[
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n"
  },
  {
    "path": ".gitignore",
    "content": "# Prerequisites\n*.d\n\n# Compiled Object files\n*.slo\n*.lo\n*.o\n*.obj\n\n# Precompiled Headers\n*.gch\n*.pch\n\n# Compiled Dynamic libraries\n*.so\n*.dylib\n*.dll\n\n# Fortran module files\n*.mod\n*.smod\n\n# Compiled Static libraries\n*.lai\n*.la\n*.a\n*.lib\n\n# Executables\n*.exe\n*.out\n*.app\n\n# Others\n.DS_STORE\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 Mixiaoxiao(谜小小)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Arduino-HomeKit-ESP32\n**[Deprecated]** Native Apple HomeKit accessory implementation for the ESP32 Arduino core.\n\nThis Arduino library is a native Apple HomeKit accessory implementation for the [ESP32 Arduino core](https://github.com/espressif/arduino-esp32), and works without any additional bridges.\n\nThis library is the ESP32 version of [Arduino-HomeKit-ESP8266](https://github.com/Mixiaoxiao/Arduino-HomeKit-ESP8266), and **will no longer be maintained**, since Espressif has published the official HomeKit library for ESP32, available on Espressif's GitHub repository [esp-apple-homekit-adk](https://github.com/espressif/esp-apple-homekit-adk).\n\n## Notes\n\n* This is a \"only-can-work\" version for ESP32, remains something to be optimized.\n\n* The `WolfSSL` used for ESP32 is based on `4.3.0-stable` version with **Hardware Acceleration Support** (enabled by default).\n\n* The HomeKit running on ESP32 has a **GREAT PERFORMANCE** which Pair-Setup can be done in ~1.2s and Pair-Verify in < 0.1s (10x faster than ESP8266).\n\n* The HomeKit storage on ESP32 is based on `nvs`.\n\n## Performance WITH Hardware Acceleration on ESP32\n\n* Preinit: ~0.53s\n* Pair Setup Step 1/3: ~0s (The heavy crypto computation is done in Preinit)\n* Pair Setup Step 2/3: ~0.53s \n* Pair Setup Step 3/3: ~0.20s \n* Pair Verify Step 1/2: ~0.05s\n* Pair Verify Step 2/2: ~0.02s\n\n## Performance WITHOUT Hardware Acceleration on ESP32\n\n* Preinit: ~2.2s\n* Pair Setup Step 1/3: ~0s (The heavy crypto computation is done in Preinit)\n* Pair Setup Step 2/3: ~2.5s \n* Pair Setup Step 3/3: ~0.1s \n* Pair Verify Step 1/2: ~0.06s\n* Pair Verify Step 2/2: ~0.03s\n\n## Setup code of the example sketch\n\n``111-11-111``\n\n## Manual Installation \n\nRefer to the official guide: [Manual installation](https://www.arduino.cc/en/guide/libraries#toc5)\nNote: this library will not publish the release version for Arduino IDE. \n\n\n#### Manual Installation for Windows\n\n1. Click on _\"Clone or Download\"_ button, then click _\"[Download ZIP](https://github.com/Mixiaoxiao/Arduino-HomeKit-ESP32/archive/master.zip)\"_ on the page.\n1. Extract the contents of the downloaded zip file.\n1. Rename the extracted folder to _\"Arduino-HomeKit-ESP32\"_.\n1. Move this folder to your libraries directory. (under windows: `C:\\Users\\<USERNAME>\\Documents\\Arduino\\libraries\\`)\n1. Restart your Arduino IDE.\n1. Check out the examples.\n\n\n"
  },
  {
    "path": "examples/ESP32_homekit_wolfssl_4_3_0/ESP32_homekit.ino",
    "content": "#include \"Arduino.h\"\n#include \"WiFi.h\"\n#include \"arduino_homekit_server.h\"\n#include \"ESPButton.h\"\n\nextern \"C\" homekit_server_config_t config;\nextern \"C\" homekit_characteristic_t name;\nextern \"C\" char ACCESSORY_NAME[32];\nextern \"C\" void led_toggle();\nextern \"C\" void accessory_init();\n\n#define PIN_BTN 0\n\nconst char *ssid = \"your-ssid\";\nconst char *password = \"your-password\";\n\nvoid setup() {\n\tSerial.begin(115200);\n\n\tWiFi.mode(WIFI_STA);\n\tWiFi.persistent(false);\n\tWiFi.disconnect(false);\n\tWiFi.setAutoReconnect(true);\n\tWiFi.begin(ssid, password);\n\n\tprintf(\"\\n\");\n\tprintf(\"SketchSize: %d B\\n\", ESP.getSketchSize());\n\tprintf(\"FreeSketchSpace: %d B\\n\", ESP.getFreeSketchSpace());\n\tprintf(\"FlashChipSize: %d B\\n\", ESP.getFlashChipSize());\n\t//printf(\"FlashChipRealSize: %d B\\n\", ESP.getFlashChipRealSize());\n\tprintf(\"FlashChipSpeed: %d\\n\", ESP.getFlashChipSpeed());\n\tprintf(\"SdkVersion: %s\\n\", ESP.getSdkVersion());\n\t//printf(\"FullVersion: %s\\n\", ESP.getFullVersion().c_str());\n\t//printf(\"CpuFreq: %dMHz\\n\", ESP.getCpuFreqMHz());\n\tprintf(\"FreeHeap: %d B\\n\", ESP.getFreeHeap());\n\t//printf(\"ResetInfo: %s\\n\", ESP.getResetInfo().c_str());\n\t//printf(\"ResetReason: %s\\n\", ESP.getResetReason().c_str());\n\tDEBUG_HEAP();\n\n\t//Init Button\n\tpinMode(PIN_BTN, INPUT_PULLUP);\n\tESPButton.add(0, PIN_BTN, LOW, false, true);\n\tESPButton.setCallback([](uint8_t id, ESPButtonEvent event) {\n\t\tprintf(\"ButtonEvent: %s\\n\", ESPButton.getButtonEventDescription(event));\n\t\tif (event == ESPBUTTONEVENT_SINGLECLICK) {\n\t\t\tled_toggle();\n\t\t} else if (event == ESPBUTTONEVENT_DOUBLECLICK) {\n\n\t\t} else if (event == ESPBUTTONEVENT_LONGCLICK) {\n\t\t\thomekit_storage_reset();\n\t\t\tesp_restart();\n\t\t}\n\t});\n\tESPButton.begin();\n\thomekit_setup();\n}\n\nvoid loop() {\n\tESPButton.loop();\n\tuint32_t time = millis();\n\tstatic uint32_t next_heap_millis = 0;\n\tif (time > next_heap_millis) {\n\t\tINFO(\"heap: %u, sockets: %d\", ESP.getFreeHeap(), arduino_homekit_connected_clients_count());\n\t\tnext_heap_millis = time + 5000;\n\t}\n\tdelay(5);\n}\n\nvoid homekit_setup() {\n\taccessory_init();\n\t// We create one FreeRTOS-task for HomeKit\n\t// No need to call arduino_homekit_loop\n\tarduino_homekit_setup(&config);\n}\n"
  },
  {
    "path": "examples/ESP32_homekit_wolfssl_4_3_0/ESPButton.h",
    "content": "/*\n * ESPButton.h\n * Ticker-scan based Button Handler with debounce.\n * Default scan interval is 16ms (60FPS).\n * All added Buttons are scanned by a global Ticker (by os timer).\n * [!!!] All events are triggered in interrupt, so you can NOT use delay() in callback!\n *\n * Usage:\n * in setup():\n * pinMode(pin, INPUT_PULLUP / INPUT /... );\n * ESPButton.add(id, pin, pin_down_digital);\n * ESPButton.setCallback(...); // handle your ButtonEvent by id\n * ESPButton.begin(); // call begin to start scan.\n * in loop():\n * ESPButton.loop(); // will notify the event in loop (not in interrupt timer)\n *\n *  Created on:  2020-03-08\n *  Last update: 2020-04-14\n *      Author:  Wang Bin\n */\n\n#ifndef ESPBUTTON_H_\n#define ESPBUTTON_H_\n\n#include <Arduino.h>\n#include <functional>\n#include <Ticker.h>\n\n#define ESPBUTTON_DEBUG(message, ...)  //printf_P(PSTR(\"[%7d] ESPButton: \" message \"\\n\"), millis(), ##__VA_ARGS__)\n\ntypedef struct _ESPButtonEntry {\n\tuint8_t id = -1;\n\tuint8_t pin = -1;\n\tuint8_t pin_down_digital = LOW; //按下状态时的digital值\n\n\tbool stable_down = false; //稳定状态的下的按键状态 (true: down, false: up)\n\tuint32_t stable_threshold = 40; //如果按键状态维持一段时间未变化就认为是stable\n\tbool is_stable = false;\t//当前是否是稳定状态，只有稳定状态下才会进一步处理\n\tbool raw_down = false; //未消抖的原始按键状态\n\tuint32_t raw_changed_time = 0; //未消抖的原始按键状态的改变的时间\n\n\t//void (*ext_digitalRead)(uint8_t pin);\n\t//如果该pin不是ESP芯片的引脚，而是从其他的扩展芯片读取的，就需要传入ext_digitalRead\n\tstd::function<uint8_t(uint8_t pin)> ext_digitalRead = nullptr;\n\t//======\n\tbool longclicked = false; //用来保证一次按下只能触发一次长按\n\tbool down_handled = false; //标志着是否已经处理了该次down按下事件（比如已经触发了长按)\n\t//down->up，在规定时间内再次down就是双击，否则超时就是单击\n\tbool wait_doubleclick = false; //标志着是否等待着双击事件\n\tuint32_t down_time = 0; //ms\n\tuint32_t up_time = 0;\n\n\tuint32_t longclick_threshold = 5000;\n\tuint32_t doubleclick_threshold = 150; //按下释放后在此时间间隔内又按下认为是双击\n\n\tbool longclick_enable = true;\n\tbool doubleclick_enable = true;\n\t//======\n\tstruct _ESPButtonEntry *next;\n} ESPButtonEntry;\n\nenum ESPButtonEvent {\n\tESPBUTTONEVENT_NONE = 0,\n\tESPBUTTONEVENT_SINGLECLICK,\n\tESPBUTTONEVENT_DOUBLECLICK,\n\tESPBUTTONEVENT_LONGCLICK\n};\nclass ESPButtonClass;\n\nstatic void _esp32_ticker_cb(ESPButtonClass *esp_button);\n\nclass ESPButtonClass {\n\npublic:\n\n\ttypedef std::function<void(uint8_t id, ESPButtonEvent event)> espbutton_callback;\n\n\tTicker ticker;\n\tESPButtonEntry *entries = nullptr;\n\tespbutton_callback callback;\n\tESPButtonEvent notify_event = ESPBUTTONEVENT_NONE;\n\tuint8_t notify_id = 0;\n\n\tESPButtonClass() {\n\t}\n\t~ESPButtonClass() {\n\t}\n\n\tvoid begin() {\n\t\tticker.detach();\n#if defined(ESP8266)\n\t\tticker.attach_ms(16, std::bind(&ESPButtonClass::tick, this));\n#elif defined(ESP32)\n\t\tticker.attach_ms(16, _esp32_ticker_cb, this);\n#endif\n\t}\n\n\tESPButtonEntry* add(uint8_t _id, uint8_t _pin, uint8_t _pin_down_digital,\n\t\t\tbool _doubleclick_enable = false, bool _longclick_enable = true) {\n\t\tESPButtonEntry *entry = new ESPButtonEntry();\n\t\tentry->id = _id;\n\t\tentry->pin = _pin;\n\t\tentry->pin_down_digital = _pin_down_digital;\n\t\tentry->doubleclick_enable = _doubleclick_enable;\n\t\tentry->longclick_enable = _longclick_enable;\n\n\t\t//初始化entry的状态？？暂时不需要，我们就是认为按键默认就是未按下的\n\t\t//entry->laststate_is_down = digitalReadEntryIsDown(entry);\n\t\t//加入链表\n\t\tentry->next = entries;\n\t\tentries = entry;\n\t\treturn entry;\n\t}\n\n\tvoid setCallback(espbutton_callback _callback) {\n\t\tcallback = _callback;\n\t}\n\n\tPGM_P getButtonEventDescription(ESPButtonEvent e) {\n\t\tswitch (e) {\n\t\tcase ESPBUTTONEVENT_SINGLECLICK:\n\t\t\treturn PSTR(\"SingleClick\");\n\t\tcase ESPBUTTONEVENT_DOUBLECLICK:\n\t\t\treturn PSTR(\"DoubleClick\");\n\t\tcase ESPBUTTONEVENT_LONGCLICK:\n\t\t\treturn PSTR(\"LongClick\");\n\t\tdefault:\n\t\t\treturn PSTR(\"<unknown event>\");\n\t\t}\n\t}\n\n\tvoid tick() {\n\t\tESPButtonEntry *entry = entries;\n\t\twhile (entry) {\n\t\t\ttickEntry(entry);\n\t\t\tentry = entry->next;\n\t\t}\n\t}\n\n\tvoid loop() {\n\t\tif (callback && (notify_event != ESPBUTTONEVENT_NONE)) {\n\t\t\tcallback(notify_id, notify_event);\n\t\t\tnotify_id = 0;\n\t\t\tnotify_event = ESPBUTTONEVENT_NONE;\n\t\t}\n\t}\n\nprivate:\n\n\tbool digitalReadEntryIsDown(ESPButtonEntry *entry) {\n\t\tif (entry->ext_digitalRead) {\n\t\t\treturn entry->ext_digitalRead(entry->pin) == entry->pin_down_digital;\n\t\t}\n\t\treturn digitalRead(entry->pin) == entry->pin_down_digital;\n\t}\n\n\tvoid tickEntry(ESPButtonEntry *entry) {\n\t\tconst uint32_t t = millis();\n\t\tconst bool down = digitalReadEntryIsDown(entry);\n\t\tif (down != entry->raw_down) {\n\t\t\tentry->raw_down = down;\n\t\t\tentry->is_stable = false;\n\t\t\tentry->raw_changed_time = t;\n\t\t\tESPBUTTON_DEBUG(\"change (%s)\", down ? PSTR(\"down\") : PSTR(\"up\"));\n\t\t} else { // down == raw_down\n\t\t\t// 在stable_threshold时间内一直没有变化，认为是stable\n\t\t\tif (!entry->is_stable) {\n\t\t\t\tif (t - entry->raw_changed_time > entry->stable_threshold) {\n\t\t\t\t\tESPBUTTON_DEBUG(\"t: %d, raw: %d\", t, entry->raw_changed_time);ESPBUTTON_DEBUG(\"stable (%s)\", down ? PSTR(\"down\") : PSTR(\"up\"));\n\t\t\t\t\tentry->is_stable = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!entry->is_stable) {\n\t\t\t//ESPBUTTON_DEBUG(\"not stable\");\n\t\t\treturn;\n\t\t}\n\t\t//以上代码能检测出超过一定时间的稳定了的状态，等稳定了之后再做处理\n\n\t\tif (entry->stable_down == down) {\n\t\t\thandleEntryUnchanged(entry);\n\t\t\treturn;\n\t\t} else {\n\t\t\tentry->stable_down = down;\n\t\t\thandleEntryChanged(entry);\n\t\t}\n\n\t}\n\n\tvoid handleEntryChanged(ESPButtonEntry *entry) {\n\t\tconst bool down = entry->stable_down;\n\t\t//仅有单击事件就在down的时候直接回调？ 暂时不这么做，类比实体开关，按下不松手的时候，就是一直开着的状态\n\t\t//逻辑如下：\n\t\t//单击：按下->释放->且释放一段时间内没有第二次按下\n\t\t//双击：按下->释放->且释放一段时间内执行第二次按下时触发\n\t\t//长按：按下一段时间内未释放\n\t\tif (down) { //down\n\t\t\tif (entry->wait_doubleclick && entry->doubleclick_enable) {\n\t\t\t\t//规定时间内第二次down了，认为是双击\n\t\t\t\t//亲测，一般情况下我的双击up->第二次down的间隔是80~100左右\n\t\t\t\tESPBUTTON_DEBUG(\"doubleclick, wait %d\", (millis() - entry->up_time));\n\t\t\t\tentry->down_handled = true;\n\t\t\t\tnotifyEvent(entry, ESPBUTTONEVENT_DOUBLECLICK);\n\t\t\t} else {\n\t\t\t\t//第一次按下\n\t\t\t\tentry->down_handled = false;\n\t\t\t}\n\t\t\tentry->down_time = millis();\n\t\t\tentry->longclicked = false;\n\t\t\tentry->wait_doubleclick = false;\n\t\t} else { //up\n\t\t\tif (!entry->down_handled) {\n\t\t\t\tif (entry->doubleclick_enable) {\n\t\t\t\t\t//在loop中延时等待第二次按下\n\t\t\t\t\tentry->up_time = millis();\n\t\t\t\t\tentry->wait_doubleclick = true;\n\t\t\t\t} else {\n\t\t\t\t\tentry->down_handled = true;\n\t\t\t\t\tnotifyEvent(entry, ESPBUTTONEVENT_SINGLECLICK);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t}\n\n\tvoid handleEntryUnchanged(ESPButtonEntry *entry) {\n\t\tbool down = entry->stable_down;\n\t\tif (down) { //down\n\t\t\tif (entry->longclick_enable) {\n\t\t\t\tif (!entry->longclicked && !entry->down_handled) {\n\t\t\t\t\tif (millis() - entry->down_time > entry->longclick_threshold) {\n\t\t\t\t\t\tentry->longclicked = true;\n\t\t\t\t\t\tentry->down_handled = true;\n\t\t\t\t\t\tnotifyEvent(entry, ESPBUTTONEVENT_LONGCLICK);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else { //up\n\t\t\tentry->longclicked = false;\n\t\t\tif (entry->wait_doubleclick && entry->doubleclick_enable) {\n\t\t\t\tif (millis() - entry->up_time > entry->doubleclick_threshold) {\n\t\t\t\t\tentry->wait_doubleclick = false;\n\t\t\t\t\tentry->down_handled = true;\n\t\t\t\t\t//key2DoClick();\n\t\t\t\t\tnotifyEvent(entry, ESPBUTTONEVENT_SINGLECLICK);\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\n\tvoid notifyEvent(ESPButtonEntry *entry, ESPButtonEvent event) {\n\t\tESPBUTTON_DEBUG(\"Button(%d): %s\", entry->id, getButtonEventDescription(event));\n\t\t// Save the Event and notify it in loop\n\t\tif (notify_event != ESPBUTTONEVENT_NONE) {\n\t\t\tESPBUTTON_DEBUG(\"Warnning! Previous Button Event is not handled in loop!\");\n\t\t}\n\t\tnotify_event = event;\n\t\tnotify_id = entry->id;\n//\t\tif (callback) {\n//\t\t\tcallback(entry->id, event);\n//\t\t}\n\t}\n\n};\n\nESPButtonClass ESPButton;\n\nstatic void _esp32_ticker_cb(ESPButtonClass *esp_button) {\n\tesp_button->tick();\n}\n\n#endif /* ESPBUTTON_H_ */\n"
  },
  {
    "path": "examples/ESP32_homekit_wolfssl_4_3_0/builtin_led_accessory.c",
    "content": "/*\n * builtin_led_accessory.c\n * Define the accessory in pure C language using the Macro in characteristics.h\n *\n *  Created on: 2020-04-13\n *      Author: Mixiaoxiao (Wang Bin)\n */\n\n#include <Arduino.h>\n#include <homekit/types.h>\n#include <homekit/homekit.h>\n#include <homekit/characteristics.h>\n#include <stdio.h>\n#include <port.h>\n#include <esp_wifi_types.h>\n#include <esp_wifi.h>\n\nstatic char ACCESSORY_NAME[32] = \"ESP32_LED\";\n#define ACCESSORY_SN  (\"SN_0123456\")  //SERIAL_NUMBER\n#define ACCESSORY_MANUFACTURER (\"Arduino HomeKit\")\n#define ACCESSORY_MODEL  (\"ESP32_DEVKIT\")\n\n#define PIN_LED  2\n\nvoid led_set_power(bool on) {\n\tdigitalWrite(PIN_LED, on ? HIGH : LOW);\n}\n\nvoid led_setter(homekit_value_t value);\n\nhomekit_characteristic_t name = HOMEKIT_CHARACTERISTIC_(NAME, ACCESSORY_NAME);\nhomekit_characteristic_t serial_number = HOMEKIT_CHARACTERISTIC_(SERIAL_NUMBER, ACCESSORY_SN);\nhomekit_characteristic_t led_on = HOMEKIT_CHARACTERISTIC_(ON, false, .setter=led_setter);\n\nvoid led_setter(homekit_value_t value) {\n\tif (value.format != homekit_format_bool) {\n\t\tprintf(\"Invalid on-value format: %d\\n\", value.format);\n\t\treturn;\n\t}\n\tconst bool power = value.bool_value;\n\tled_on.value.bool_value = power; // Sync the value, and no getter needed.\n\tled_set_power(power);\n\tprintf(\"Set Builtin-LED to %s\\n\", power ? \"ON\" : \"OFF\");\n}\n\nvoid led_toggle() {\n\tbool power = !led_on.value.bool_value;\n\tled_on.value.bool_value = power;\n\tled_set_power(power);\n\thomekit_characteristic_notify(&led_on, led_on.value);\n}\n\nvoid led_blink_task(void *_args) {\n\tfor (int i = 0; i < 3; i++) {\n\t\tled_set_power(true);\n\t\tvTaskDelay(100 / portTICK_PERIOD_MS);\n\t\tled_set_power(false);\n\t\tvTaskDelay(100 / portTICK_PERIOD_MS);\n\t}\n\tled_set_power(false);\n\tvTaskDelete(NULL);\n}\n\nvoid led_blink() {\n\txTaskCreate(led_blink_task, \"led_blink_task\", 2048, NULL, 1, NULL);\n}\n\nvoid accessory_identify(homekit_value_t _value) {\n\tprintf(\"accessory identify\\n\");\n\tled_blink();\n}\n\nhomekit_accessory_t *accessories[] = {\n\t\t\t\tHOMEKIT_ACCESSORY(\n\t\t\t\t\t\t.id = 1,\n\t\t\t\t\t\t.category = homekit_accessory_category_lightbulb,\n\t\t\t\t\t\t.services=(homekit_service_t*[]){\n\t\t\t\t\t\t  HOMEKIT_SERVICE(ACCESSORY_INFORMATION,\n\t\t\t\t\t\t  .characteristics=(homekit_characteristic_t*[]){\n\t\t\t\t\t\t    &name,\n\t\t\t\t\t\t    HOMEKIT_CHARACTERISTIC(MANUFACTURER, ACCESSORY_MANUFACTURER),\n\t\t\t\t\t\t    &serial_number,\n\t\t\t\t\t\t    HOMEKIT_CHARACTERISTIC(MODEL, ACCESSORY_MODEL),\n\t\t\t\t\t\t    HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, \"1.0.1\"),\n\t\t\t\t\t\t    HOMEKIT_CHARACTERISTIC(IDENTIFY, accessory_identify),\n\t\t\t\t\t\t    NULL\n\t\t\t\t\t\t  }),\n\t\t\t\t\t\t  HOMEKIT_SERVICE(LIGHTBULB, .primary=true,\n\t\t\t\t\t\t  .characteristics=(homekit_characteristic_t*[]){\n\t\t\t\t\t\t    HOMEKIT_CHARACTERISTIC(NAME, \"Led\"),\n\t\t\t\t\t\t    &led_on,\n\t\t\t\t\t\t    NULL\n\t\t\t\t\t\t  }),\n\t\t\t\t\t\t  NULL\n\t\t\t\t\t\t}),\n\t\t\t\tNULL\n\t\t};\n\nhomekit_server_config_t config = {\n\t\t.accessories = accessories,\n\t\t.password = \"111-11-111\",\n\t\t//.on_event = on_homekit_event,\n\t\t.setupId = \"ABCD\"\n};\n\nvoid accessory_init() {\n\tpinMode(PIN_LED, OUTPUT);\n\tled_set_power(false);\n\t//Rename ACCESSORY_NAME base on MAC address.\n\tuint8_t mac[6];\n\tesp_wifi_get_mac(WIFI_IF_STA, mac);\n\tsprintf(ACCESSORY_NAME, \"ESP32_LED_%02X%02X%02X\", mac[3], mac[4], mac[5]);\n}\n"
  },
  {
    "path": "library.json",
    "content": "{\n  \"name\":\"HomeKit-ESP32\",\n  \"description\":\"Apple HomeKit accessory server library for the ESP32 Arduino core.\",\n  \"keywords\":\"homekit,esp32,apple homekit\",\n  \"authors\":\n  {\n    \"name\": \"Mixiaoxiao (Wang Bin)\",\n    \"maintainer\": true\n  },\n  \"repository\":\n  {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/Mixiaoxiao/Arduino-HomeKit-ESP32.git\"\n  },\n  \"version\": \"1.0.0\",\n  \"license\": \"MIT\",\n  \"frameworks\": \"arduino\",\n  \"platforms\": \"espressif32\",\n  \"build\": {\n    \"libCompatMode\": 2\n  }\n}\n"
  },
  {
    "path": "library.properties",
    "content": "name=HomeKit-ESP32\nversion=1.0.0\nauthor=Mixiaoxiao\nmaintainer=Mixiaoxiao\nsentence=Native Apple HomeKit accessory implementation for the ESP32 Arduino core.\nparagraph=Native Apple HomeKit Accessory Implementation for the ESP32 Arduino core.\ncategory=Communication\nurl=https://github.com/Mixiaoxiao/Arduino-HomeKit-ESP32.git\narchitectures=esp32\n"
  },
  {
    "path": "src/accessories.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <homekit/types.h>\n\nbool homekit_value_equal(homekit_value_t *a, homekit_value_t *b) {\n    if (a->is_null != b->is_null)\n        return false;\n\n    if (a->format != b->format)\n        return false;\n\n    switch (a->format) {\n        case homekit_format_bool:\n            return a->bool_value == b->bool_value;\n        case homekit_format_uint8:\n        case homekit_format_uint16:\n        case homekit_format_uint32:\n        case homekit_format_uint64:\n        case homekit_format_int:\n            return a->int_value == b->int_value;\n        case homekit_format_float:\n            return a->float_value == b->float_value;\n        case homekit_format_string:\n            return !strcmp(a->string_value, b->string_value);\n        case homekit_format_tlv: {\n            if (!a->tlv_values && !b->tlv_values)\n                return true;\n            if (!a->tlv_values || !b->tlv_values)\n                return false;\n\n            // TODO: implement order independent comparison?\n            tlv_t *ta = a->tlv_values->head, *tb = b->tlv_values->head;\n            for (; ta && tb; ta=ta->next, tb=tb->next) {\n                if (ta->type != tb->type || ta->size != tb->size)\n                    return false;\n                if (strncmp((char *)ta->value, (char *)tb->value, ta->size))\n                    return false;\n            }\n\n            return (!ta && !tb);\n        }\n        case homekit_format_data:\n            if (!a->data_value && !b->data_value)\n                return true;\n\n            if (!a->data_value || !b->data_value)\n                return false;\n\n            if (a->data_size != b->data_size)\n                return false;\n\n            return !memcmp(a->data_value, b->data_value, a->data_size);\n    }\n\n    return false;\n}\n\nvoid homekit_value_copy(homekit_value_t *dst, homekit_value_t *src) {\n    memset(dst, 0, sizeof(*dst));\n\n    dst->format = src->format;\n    dst->is_null = src->is_null;\n\n    if (!src->is_null) {\n        switch (src->format) {\n            case homekit_format_bool:\n                dst->bool_value = src->bool_value;\n                break;\n            case homekit_format_uint8:\n            case homekit_format_uint16:\n            case homekit_format_uint32:\n            case homekit_format_uint64:\n            case homekit_format_int:\n                dst->int_value = src->int_value;\n                break;\n            case homekit_format_float:\n                dst->float_value = src->float_value;\n                break;\n            case homekit_format_string:\n                if (src->is_static) {\n                    dst->string_value = src->string_value;\n                    dst->is_static = true;\n                } else {\n                    dst->string_value = strdup(src->string_value);\n                }\n                break;\n            case homekit_format_tlv: {\n                if (src->is_static) {\n                    dst->tlv_values = src->tlv_values;\n                    dst->is_static = true;\n                } else {\n                    dst->tlv_values = tlv_new();\n                    for (tlv_t *v=src->tlv_values->head; v; v=v->next) {\n                      tlv_add_value(dst->tlv_values, v->type, v->value, v->size);\n                    }\n                }\n                break;\n            }\n            case homekit_format_data:\n                if (src->is_static) {\n                    dst->data_value = src->data_value;\n                    dst->data_size = src->data_size;\n                    dst->is_static = true;\n                } else {\n                    dst->data_size = src->data_size;\n                    dst->data_value = malloc(src->data_size);\n                    memcpy(dst->data_value, src->data_value, src->data_size);\n                }\n                break;\n            default:\n                // unknown format\n                break;\n        }\n    }\n}\n\n\nhomekit_value_t *homekit_value_clone(homekit_value_t *value) {\n    homekit_value_t *copy = malloc(sizeof(homekit_value_t));\n    homekit_value_copy(copy, value);\n    return copy;\n}\n\nvoid homekit_value_destruct(homekit_value_t *value) {\n    if (!value->is_null) {\n        switch (value->format) {\n            case homekit_format_string:\n                if (!value->is_static && value->string_value)\n                    free(value->string_value);\n                break;\n            case homekit_format_tlv:\n                if (!value->is_static && value->tlv_values)\n                    tlv_free(value->tlv_values);\n                break;\n            case homekit_format_data:\n                if (!value->is_static && value->data_value)\n                    free(value->data_value);\n                break;\n            default:\n                // unknown format\n                break;\n        }\n    }\n}\n\nvoid homekit_value_free(homekit_value_t *value) {\n    homekit_value_destruct(value);\n    free(value);\n}\n\n\nsize_t align_size(size_t size) {\n    if (size % sizeof(void*)) {\n        size += sizeof(void*) - size % sizeof(void*);\n    }\n    return size;\n}\n\nvoid *align_pointer(void *ptr) {\n    uintptr_t p = (uintptr_t) ptr;\n    if (p % sizeof(void*)) {\n        p += sizeof(void*) - p % sizeof(void*);\n    }\n    return (void*) p;\n}\n\n\nhomekit_characteristic_t* homekit_characteristic_clone(homekit_characteristic_t* ch) {\n    size_t type_len = strlen(ch->type) + 1;\n    size_t description_len = ch->description ? strlen(ch->description) + 1 : 0;\n\n    size_t size = align_size(sizeof(homekit_characteristic_t) + type_len + description_len);\n\n    if (ch->min_value)\n        size += sizeof(float);\n    if (ch->max_value)\n        size += sizeof(float);\n    if (ch->min_step)\n        size += sizeof(float);\n    if (ch->max_len)\n        size += sizeof(int);\n    if (ch->max_data_len)\n        size += sizeof(int);\n    if (ch->valid_values.count)\n        size += align_size(sizeof(uint8_t) * ch->valid_values.count);\n    if (ch->valid_values_ranges.count)\n        size += align_size(sizeof(homekit_valid_values_range_t) * ch->valid_values_ranges.count);\n    if (ch->callback) {\n        homekit_characteristic_change_callback_t *c = ch->callback;\n        while (c) {\n            size += align_size(sizeof(homekit_characteristic_change_callback_t));\n            c = c->next;\n        }\n    }\n\n    uint8_t* p = calloc(1, size);\n\n    homekit_characteristic_t* clone = (homekit_characteristic_t*) p;\n    p += sizeof(homekit_characteristic_t);\n\n    clone->service = ch->service;\n    clone->id = ch->id;\n    clone->type = (char*) p;\n    strncpy((char*) p, ch->type, type_len);\n    p[type_len - 1] = 0;\n    p += type_len;\n\n    clone->description = (char*) p;\n    strncpy((char*) p, ch->description, description_len);\n    p[description_len - 1] = 0;\n    p += description_len;\n\n    p = align_pointer(p);\n\n    clone->format = ch->format;\n    clone->unit = ch->unit;\n    clone->permissions = ch->permissions;\n    homekit_value_copy(&clone->value, &ch->value);\n\n    if (ch->min_value) {\n        clone->min_value = (float*) p;\n        *clone->min_value = *ch->min_value;\n        p += sizeof(float);\n    }\n\n    if (ch->max_value) {\n        clone->max_value = (float*) p;\n        *clone->max_value = *ch->max_value;\n        p += sizeof(float);\n    }\n\n    if (ch->min_step) {\n        clone->min_step = (float*) p;\n        *clone->min_step = *ch->min_step;\n        p += sizeof(float);\n    }\n\n    if (ch->max_len) {\n        clone->max_len = (int*) p;\n        *clone->max_len = *ch->max_len;\n        p += sizeof(int);\n    }\n\n    if (ch->max_data_len) {\n        clone->max_data_len = (int*) p;\n        *clone->max_data_len = *ch->max_data_len;\n        p += sizeof(int);\n    }\n\n    if (ch->valid_values.count) {\n        clone->valid_values.count = ch->valid_values.count;\n        clone->valid_values.values = (uint8_t*) p;\n        memcpy(clone->valid_values.values, ch->valid_values.values,\n               sizeof(uint8_t) * ch->valid_values.count);\n\n        p += align_size(sizeof(uint8_t) * ch->valid_values.count);\n    }\n\n    if (ch->valid_values_ranges.count) {\n        int c = ch->valid_values_ranges.count;\n        clone->valid_values_ranges.count = c;\n        clone->valid_values_ranges.ranges = (homekit_valid_values_range_t*) p;\n        memcpy(clone->valid_values_ranges.ranges,\n               ch->valid_values_ranges.ranges,\n               sizeof(homekit_valid_values_range_t*) * c);\n\n        p += align_size(sizeof(homekit_valid_values_range_t*) * c);\n    }\n\n    if (ch->callback) {\n        int c = 1;\n        homekit_characteristic_change_callback_t *callback_in = ch->callback;\n        clone->callback = (homekit_characteristic_change_callback_t*)p;\n\n        homekit_characteristic_change_callback_t *callback_out = clone->callback;\n        memcpy(callback_out, callback_in, sizeof(*callback_out));\n\n        while (callback_in->next) {\n            callback_in = callback_in->next;\n            callback_out->next = callback_out + 1;\n            callback_out = callback_out->next;\n            memcpy(callback_out, callback_in, sizeof(*callback_out));\n            c++;\n        }\n        callback_out->next = NULL;\n\n        p += align_size(sizeof(homekit_characteristic_change_callback_t)) * c;\n    }\n\n    clone->getter = ch->getter;\n    clone->setter = ch->setter;\n    clone->getter_ex = ch->getter_ex;\n    clone->setter_ex = ch->setter_ex;\n    clone->context = ch->context;\n\n    return clone;\n}\n\nhomekit_service_t* homekit_service_clone(homekit_service_t* service) {\n    size_t type_len = strlen(service->type) + 1;\n    size_t size = align_size(sizeof(homekit_service_t) + type_len);\n\n    if (service->linked) {\n        int i = 0;\n        while (service->linked[i])\n            i++;\n\n        size += sizeof(homekit_service_t*) * (i + 1);\n    }\n    if (service->characteristics) {\n        int i = 0;\n        while (service->characteristics[i])\n            i++;\n\n        size += sizeof(homekit_characteristic_t*) * (i + 1);\n    }\n\n    uint8_t *p = calloc(1, size);\n    homekit_service_t *clone = (homekit_service_t*) p;\n    p += sizeof(homekit_service_t);\n    clone->accessory = service->accessory;\n    clone->id = service->id;\n    clone->type = strncpy((char*) p, service->type, type_len);\n    p[type_len - 1] = 0;\n    p += align_size(type_len);\n\n    clone->hidden = service->hidden;\n    clone->primary = service->primary;\n\n    if (service->linked) {\n        clone->linked = (homekit_service_t**) p;\n        int i = 0;\n        while (service->linked[i]) {\n            clone->linked[i] = service->linked[i];\n            i++;\n        }\n        clone->linked[i] = NULL;\n        p += (i + 1) * sizeof(homekit_service_t*);\n    }\n\n    if (service->characteristics) {\n        clone->characteristics = (homekit_characteristic_t**) p;\n        int i = 0;\n        while (service->characteristics[i]) {\n            clone->characteristics[i] = service->characteristics[i];\n            i++;\n        }\n        clone->characteristics[i] = NULL;\n        p += (i + 1) * sizeof(homekit_characteristic_t*);\n    }\n\n    return clone;\n}\n\nhomekit_accessory_t* homekit_accessory_clone(homekit_accessory_t* ac) {\n    size_t size = sizeof(homekit_accessory_t);\n    if (ac->services) {\n        for (int i=0; ac->services[i]; i++) {\n            size += sizeof(homekit_service_t*);\n        }\n        size += sizeof(homekit_service_t*);\n    }\n\n    uint8_t* p = calloc(1, size);\n    homekit_accessory_t* clone = (homekit_accessory_t*) p;\n    p += align_size(sizeof(homekit_accessory_t));\n\n    clone->id = ac->id;\n    clone->category = ac->category;\n    clone->config_number = ac->config_number;\n\n    if (ac->services) {\n        clone->services = (homekit_service_t**) p;\n        int i = 0;\n        while (ac->services[i]) {\n            clone->services[i] = ac->services[i];\n            i++;\n        }\n        clone->services[i] = NULL;\n\n        p += sizeof(homekit_service_t*) * (i + 1);\n    }\n\n    return clone;\n}\n\n\nhomekit_value_t homekit_characteristic_ex_old_getter(const homekit_characteristic_t *ch) {\n    return ch->getter();\n}\n\n\nvoid homekit_characteristic_ex_old_setter(homekit_characteristic_t *ch, homekit_value_t value) {\n    ch->setter(value);\n}\n\nvoid homekit_accessories_init(homekit_accessory_t **accessories) {\n    //设置aid 和 iid (自增1)\n\tuint32_t aid = 1;\n    for (homekit_accessory_t **accessory_it = accessories; *accessory_it; accessory_it++) {\n    \thomekit_accessory_t *accessory = *accessory_it;\n        if (accessory->id) {\n            if (accessory->id >= aid)\n                aid = accessory->id+1;\n        } else {\n            accessory->id = aid++;\n        }\n        uint32_t iid = 1;\n        for (homekit_service_t **service_it = accessory->services; *service_it; service_it++) {\n        \thomekit_service_t *service = *service_it;\n            service->accessory = accessory;\n            if (service->id) {\n                if (service->id >= iid)\n                    iid = service->id+1;\n            } else {\n                service->id = iid++;\n            }\n            for (homekit_characteristic_t **ch_it = service->characteristics; *ch_it; ch_it++) {\n            \thomekit_characteristic_t *ch = *ch_it;\n                ch->service = service;\n                if (ch->id) {\n                    if (ch->id >= iid)\n                        iid = ch->id+1;\n                } else {\n                    ch->id = iid++;\n                }\n\n                if (!ch->getter_ex && ch->getter) {\n                    ch->getter_ex = homekit_characteristic_ex_old_getter;\n                }\n\n                if (!ch->setter_ex && ch->setter) {\n                    ch->setter_ex = homekit_characteristic_ex_old_setter;\n                }\n\n                ch->value.format = ch->format;\n            }\n        }\n    }\n}\n\nhomekit_accessory_t *homekit_accessory_by_id(homekit_accessory_t **accessories, uint32_t aid) {\n    for (homekit_accessory_t **accessory_it = accessories; *accessory_it; accessory_it++) {\n        homekit_accessory_t *accessory = *accessory_it;\n\n        if (accessory->id == aid)\n            return accessory;\n    }\n\n    return NULL;\n}\n\nhomekit_service_t *homekit_service_by_type(homekit_accessory_t *accessory, const char *type) {\n    for (homekit_service_t **service_it = accessory->services; *service_it; service_it++) {\n        homekit_service_t *service = *service_it;\n\n        if (!strcmp(service->type, type))\n            return service;\n    }\n\n    return NULL;\n}\n\nhomekit_characteristic_t *homekit_service_characteristic_by_type(homekit_service_t *service, const char *type) {\n    for (homekit_characteristic_t **ch_it = service->characteristics; *ch_it; ch_it++) {\n        homekit_characteristic_t *ch = *ch_it;\n\n        if (!strcmp(ch->type, type))\n            return ch;\n    }\n\n    return NULL;\n}\n\nhomekit_characteristic_t *homekit_characteristic_by_aid_and_iid(homekit_accessory_t **accessories, uint32_t aid, uint32_t iid) {\n    for (homekit_accessory_t **accessory_it = accessories; *accessory_it; accessory_it++) {\n        homekit_accessory_t *accessory = *accessory_it;\n\n        if (accessory->id != aid)\n            continue;\n\n        for (homekit_service_t **service_it = accessory->services; *service_it; service_it++) {\n            homekit_service_t *service = *service_it;\n\n            for (homekit_characteristic_t **ch_it = service->characteristics; *ch_it; ch_it++) {\n                homekit_characteristic_t *ch = *ch_it;\n\n                if (ch->id == iid)\n                    return ch;\n            }\n        }\n    }\n\n    return NULL;\n}\n\n\nhomekit_characteristic_t *homekit_characteristic_find_by_type(homekit_accessory_t **accessories, uint32_t aid, const char *type) {\n    for (homekit_accessory_t **accessory_it = accessories; *accessory_it; accessory_it++) {\n        homekit_accessory_t *accessory = *accessory_it;\n\n        if (accessory->id != aid)\n            continue;\n\n        for (homekit_service_t **service_it = accessory->services; *service_it; service_it++) {\n            homekit_service_t *service = *service_it;\n\n            for (homekit_characteristic_t **ch_it = service->characteristics; *ch_it; ch_it++) {\n                homekit_characteristic_t *ch = *ch_it;\n\n                if (!strcmp(ch->type, type))\n                    return ch;\n            }\n        }\n    }\n\n    return NULL;\n}\n\n\nvoid homekit_characteristic_notify(homekit_characteristic_t *ch, homekit_value_t value) {\n    homekit_characteristic_change_callback_t *callback = ch->callback;\n    while (callback) {\n        callback->function(ch, value, callback->context);\n        callback = callback->next;\n    }\n}\n\n\nvoid homekit_characteristic_add_notify_callback(\n    homekit_characteristic_t *ch,\n    homekit_characteristic_change_callback_fn function,\n    void *context\n) {\n    homekit_characteristic_change_callback_t *new_callback = malloc(sizeof(homekit_characteristic_change_callback_t));\n    new_callback->function = function;\n    new_callback->context = context;\n    new_callback->next = NULL;\n\n    if (!ch->callback) {\n        ch->callback = new_callback;\n    } else {\n        homekit_characteristic_change_callback_t *callback = ch->callback;\n        if (callback->function == function && callback->context == context) {\n            free(new_callback);\n            return;\n        }\n\n        while (callback->next) {\n            if (callback->next->function == function && callback->next->context == context) {\n                free(new_callback);\n                return;\n            }\n            callback = callback->next;\n        }\n\n        callback->next = new_callback;\n    }\n}\n\n\nvoid homekit_characteristic_remove_notify_callback(\n    homekit_characteristic_t *ch,\n    homekit_characteristic_change_callback_fn function,\n    void *context\n) {\n    while (ch->callback) {\n        if (ch->callback->function != function || ch->callback->context != context) {\n            break;\n        }\n\n        homekit_characteristic_change_callback_t *c = ch->callback;\n        ch->callback = ch->callback->next;\n        free(c);\n    }\n\n    if (!ch->callback)\n        return;\n\n    homekit_characteristic_change_callback_t *callback = ch->callback;\n    while (callback->next) {\n        if (callback->next->function == function && callback->next->context == context) {\n            homekit_characteristic_change_callback_t *c = callback->next;\n            callback->next = callback->next->next;\n            free(c);\n        } else {\n            callback = callback->next;\n        }\n    }\n}\n\n\n// Removes particular callback from all characteristics\nvoid homekit_accessories_clear_notify_callbacks(\n    homekit_accessory_t **accessories,\n    homekit_characteristic_change_callback_fn function,\n    void *context\n) {\n    for (homekit_accessory_t **accessory_it = accessories; *accessory_it; accessory_it++) {\n        homekit_accessory_t *accessory = *accessory_it;\n\n        for (homekit_service_t **service_it = accessory->services; *service_it; service_it++) {\n            homekit_service_t *service = *service_it;\n\n            for (homekit_characteristic_t **ch_it = service->characteristics; *ch_it; ch_it++) {\n                homekit_characteristic_t *ch = *ch_it;\n\n                homekit_characteristic_remove_notify_callback(ch, function, context);\n            }\n        }\n    }\n}\n\n\nbool homekit_characteristic_has_notify_callback(\n    const homekit_characteristic_t *ch,\n    homekit_characteristic_change_callback_fn function,\n    void *context\n) {\n    homekit_characteristic_change_callback_t *callback = ch->callback;\n    while (callback) {\n        if (callback->function == function && callback->context == context)\n            return true;\n\n        callback = callback->next;\n    }\n\n    return false;\n}\n\n"
  },
  {
    "path": "src/arduino_homekit_server.h",
    "content": "#ifndef ARDUINO_HOMEKIT_SERVER_H_\n#define ARDUINO_HOMEKIT_SERVER_H_\n\n\n#include <WiFiServer.h>\n#include <WiFiClient.h>\n#include <string.h> //size_t\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"constants.h\"\n#include \"base64.h\"\n#include \"crypto.h\"\n#include \"pairing.h\"\n#include \"storage.h\"\n#include \"query_params.h\"\n#include \"json.h\"\n#include \"homekit_debug.h\"\n#include \"port.h\"\n#include \"cQueue.h\"\n#include \"homekit/homekit.h\"\n#include \"http_parser.h\"\n\ntypedef enum {\n\tHOMEKIT_CLIENT_STEP_NONE = 0,\n\tHOMEKIT_CLIENT_STEP_PAIR_SETUP_1OF3,//1, need receive data\n\tHOMEKIT_CLIENT_STEP_PAIR_SETUP_2OF3,//2, need receive data\n\tHOMEKIT_CLIENT_STEP_PAIR_SETUP_3OF3,//3, need receive data\n\tHOMEKIT_CLIENT_STEP_PAIR_VERIFY_1OF2,//4, need receive data\n\tHOMEKIT_CLIENT_STEP_PAIR_VERIFY_2OF2,//5, secure session established\n\t//HOMEKIT_CLIENT_STEP_IDLE,//\n\t//HOMEKIT_CLIENT_STEP_PAIRINGS, // not used currently\n\tHOMEKIT_CLIENT_STEP_END // disconnected\n} homekit_client_step_t;\n\ntypedef enum {\n\tHOMEKIT_ENDPOINT_UNKNOWN = 0,\n\tHOMEKIT_ENDPOINT_PAIR_SETUP,\n\tHOMEKIT_ENDPOINT_PAIR_VERIFY,\n\tHOMEKIT_ENDPOINT_IDENTIFY,\n\tHOMEKIT_ENDPOINT_GET_ACCESSORIES,\n\tHOMEKIT_ENDPOINT_GET_CHARACTERISTICS,\n\tHOMEKIT_ENDPOINT_UPDATE_CHARACTERISTICS,\n\tHOMEKIT_ENDPOINT_PAIRINGS,\n\tHOMEKIT_ENDPOINT_RESOURCE,\n} homekit_endpoint_t;\n\nstruct _client_context_t;\ntypedef struct _client_context_t client_context_t;\n\ntypedef struct {\n\tSrp *srp;\n\tbyte *public_key;\n\tsize_t public_key_size;\n\n\tclient_context_t *client;\n} pairing_context_t;\n\ntypedef struct {\n\tbyte *secret;\n\tsize_t secret_size;\n\tbyte *session_key;\n\tsize_t session_key_size;\n\tbyte *device_public_key;\n\tsize_t device_public_key_size;\n\tbyte *accessory_public_key;\n\tsize_t accessory_public_key_size;\n} pair_verify_context_t;\n\ntypedef struct {\n\tWiFiServer *wifi_server;\n\tchar accessory_id[ACCESSORY_ID_SIZE + 1];\n\ted25519_key accessory_key;\n\n\thomekit_server_config_t *config;\n\n\tbool paired;\n\tpairing_context_t *pairing_context;\n\n\t//int listen_fd;\n\t//fd_set fds;\n\t//int max_fd;\n\tint nfds;// arduino homekit uses this to record client count\n\n\tclient_context_t *clients;\n} homekit_server_t;\n\ntypedef struct {\n\thomekit_characteristic_t *characteristic;\n\thomekit_value_t value;\n} characteristic_event_t;\n\nstruct _client_context_t {\n\thomekit_server_t *server;\n\t//int socket;\n\tWiFiClient *socket; //new and delete\n\n\thomekit_endpoint_t endpoint;\n\tquery_param_t *endpoint_params;\n\n\tbyte data[1024 + 18];\n\tsize_t data_size;\n\tsize_t data_available;\n\n\tchar *body;\n\tsize_t body_length;\n\thttp_parser parser;\n\n\tint pairing_id;\n\tbyte permissions;\n\n\tbool disconnect;\n\n\thomekit_characteristic_t *current_characteristic;\n\thomekit_value_t *current_value;\n\n\tbool encrypted;\n\tbyte read_key[32];\n\tbyte write_key[32];\n\tint count_reads;\n\tint count_writes;\n\n\t//QueueHandle_t event_queue;\n\tQueue_t *event_queue;\n\tpair_verify_context_t *verify_context;\n\n\thomekit_client_step_t step; // WangBin added\n\tbool error_write; // WangBin added\n\n\tstruct _client_context_t *next;\n};\n\n\n\ntypedef enum {\n\tTLVType_Method = 0,        // (integer) Method to use for pairing. See PairMethod\n\tTLVType_Identifier = 1,    // (UTF-8) Identifier for authentication\n\tTLVType_Salt = 2,          // (bytes) 16+ bytes of random salt\n\tTLVType_PublicKey = 3,     // (bytes) Curve25519, SRP public key or signed Ed25519 key\n\tTLVType_Proof = 4,         // (bytes) Ed25519 or SRP proof\n\tTLVType_EncryptedData = 5, // (bytes) Encrypted data with auth tag at end\n\tTLVType_State = 6,         // (integer) State of the pairing process. 1=M1, 2=M2, etc.\n\tTLVType_Error = 7,         // (integer) Error code. Must only be present if error code is\n\t\t\t\t\t\t\t   // not 0. See TLVError\n\tTLVType_RetryDelay = 8,    // (integer) Seconds to delay until retrying a setup code\n\tTLVType_Certificate = 9,   // (bytes) X.509 Certificate\n\tTLVType_Signature = 10,    // (bytes) Ed25519\n\tTLVType_Permissions = 11,  // (integer) Bit value describing permissions of the controller\n\t\t\t\t\t\t\t   // being added.\n\t\t\t\t\t\t\t   // None (0x00): Regular user\n\t\t\t\t\t\t\t   // Bit 1 (0x01): Admin that is able to add and remove\n\t\t\t\t\t\t\t   // pairings against the accessory\n\tTLVType_FragmentData = 13, // (bytes) Non-last fragment of data. If length is 0,\n\t\t\t\t\t\t\t   // it's an ACK.\n\tTLVType_FragmentLast = 14, // (bytes) Last fragment of data\n\tTLVType_Separator = 0xff,\n} TLVType;\n\ntypedef enum {\n\tTLVMethod_PairSetup = 1,\n\tTLVMethod_PairVerify = 2,\n\tTLVMethod_AddPairing = 3,\n\tTLVMethod_RemovePairing = 4,\n\tTLVMethod_ListPairings = 5,\n} TLVMethod;\n\ntypedef enum {\n\tTLVError_Unknown = 1,         // Generic error to handle unexpected errors\n\tTLVError_Authentication = 2,  // Setup code or signature verification failed\n\tTLVError_Backoff = 3,         // Client must look at the retry delay TLV item and\n\t\t\t\t\t\t\t\t  // wait that many seconds before retrying\n\tTLVError_MaxPeers = 4,        // Server cannot accept any more pairings\n\tTLVError_MaxTries = 5,        // Server reached its maximum number of\n\t\t\t\t\t\t\t\t  // authentication attempts\n\tTLVError_Unavailable = 6,     // Server pairing method is unavailable\n\tTLVError_Busy = 7,            // Server is busy and cannot accept a pairing\n\t\t\t\t\t\t\t\t   // request at this time\n} TLVError;\n\ntypedef enum {\n\t// This specifies a success for the request\n\tHAPStatus_Success = 0,\n\t// Request denied due to insufficient privileges\n\tHAPStatus_InsufficientPrivileges = -70401,\n\t// Unable to communicate with requested services,\n\t// e.g. the power to the accessory was turned off\n\tHAPStatus_NoAccessoryConnection = -70402,\n\t// Resource is busy, try again\n\tHAPStatus_ResourceBusy = -70403,\n\t// Connot write to read only characteristic\n\tHAPStatus_ReadOnly = -70404,\n\t// Cannot read from a write only characteristic\n\tHAPStatus_WriteOnly = -70405,\n\t// Notification is not supported for characteristic\n\tHAPStatus_NotificationsUnsupported = -70406,\n\t// Out of resources to process request\n\tHAPStatus_OutOfResources = -70407,\n\t// Operation timed out\n\tHAPStatus_Timeout = -70408,\n\t// Resource does not exist\n\tHAPStatus_NoResource = -70409,\n\t// Accessory received an invalid value in a write request\n\tHAPStatus_InvalidValue = -70410,\n\t// Insufficient Authorization\n\tHAPStatus_InsufficientAuthorization = -70411,\n} HAPStatus;\n\ntypedef enum {\n\tcharacteristic_format_type = (1 << 1),\n\tcharacteristic_format_meta = (1 << 2),\n\tcharacteristic_format_perms = (1 << 3),\n\tcharacteristic_format_events = (1 << 4),\n} characteristic_format_t;\n\ntypedef struct _client_event {\n\tconst homekit_characteristic_t *characteristic;\n\thomekit_value_t value;\n\n\tstruct _client_event *next;\n} client_event_t;\n\n#define ISDIGIT(x) isdigit((unsigned char)(x))\n#define ISBASE36(x) (isdigit((unsigned char)(x)) || (x >= 'A' && x <= 'Z'))\n\n\nvoid arduino_homekit_setup(homekit_server_config_t *config);\nvoid arduino_homekit_loop();\n\nhomekit_server_t * arduino_homekit_get_running_server();\nint arduino_homekit_connected_clients_count();\nvoid homekit_update_config_number();\n\n#ifdef __cplusplus\n}\n#endif\n#endif /* ARDUINO_HOMEKIT_SERVER_H_ */\n"
  },
  {
    "path": "src/arduino_homekit_server_esp32.cpp",
    "content": "#if defined(ESP32)\n#include <Arduino.h>\n#include <esp_xpgm.h>\n#include <WiFi.h>\n#include <ESPmDNS.h>\n#include <WiFiServer.h>\n#include <WiFiClient.h>\n#include <lwip/sockets.h>\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <homekit/homekit.h>\n#include <homekit/characteristics.h>\n#include <homekit/tlv.h>\n#include <homekit/types.h>\n#include <wolfssl/wolfcrypt/hash.h> //wc_sha512\n\n#include \"constants.h\"\n#include \"base64.h\"\n#include \"pairing.h\"\n#include \"storage.h\"\n#include \"query_params.h\"\n#include \"json.h\"\n#include \"homekit_debug.h\"\n#include \"port.h\"\n#include \"http_parser.h\"\n#include \"query_params.h\"\n#include \"cJSON.h\"\n#include \"cQueue.h\"\n#include \"crypto.h\"\n#include \"watchdog.h\"\n#include \"arduino_homekit_server.h\"\n\n#define HOMEKIT_SERVER_PORT      5556\n#define HOMEKIT_MAX_CLIENTS      8\n#define HOMEKIT_MDNS_SERVICE     \"_hap\"\n#define HOMEKIT_MDNS_PROTO       \"_tcp\"\n#define HOMEKIT_EVENT_QUEUE_SIZE 4 //original is 20\n#define HOMEKIT_SOCKET_TIMEOUT   500 //milliseconds\n\n//#define TCP_DEFAULT_KEEPALIVE_IDLE_SEC          7200 // 2 hours\n//#define TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC      75   // 75 sec\n//#define TCP_DEFAULT_KEEPALIVE_COUNT             9    // fault after 9 failures\n//const int idle = 180; /* 180 sec idle before start sending probes */\n#define HOMEKIT_SOCKET_KEEPALIVE_IDLE_SEC      180\n//const int interval = 30; /* 30 sec between probes */\n#define HOMEKIT_SOCKET_KEEPALIVE_INTERVAL_SEC  30\n//const int maxpkt = 4; /* Drop connection after 4 probes without response */\n#define HOMEKIT_SOCKET_KEEPALIVE_IDLE_COUNT     4\n// if 180 + 30 * 4 = 300 sec without socket response, disconected it.\n\n// WiFiClient can not write big buff once.\n// TCP_SND_BUF = (2 * TCP_MSS) = 1072. See lwipopts.h\n// max(encrypted_chunk) = 512 + 8(chunk_info) + 18(chacha_info). See client_send_encrypted\n#define HOMEKIT_JSONBUFFER_SIZE  512\n\n#ifdef HOMEKIT_DEBUG\n#define TLV_DEBUG(values) //tlv_debug(values)\n#else\n#define TLV_DEBUG(values)\n#endif\n\n#define CLIENT_DEBUG(client, message, ...) DEBUG(\"[Client %d] \" message, client->socket->fd(), ##__VA_ARGS__)\n#define CLIENT_INFO(client, message, ...) INFO(\"[Client %d] \" message, client->socket->fd(), ##__VA_ARGS__)\n#define CLIENT_ERROR(client, message, ...) ERROR(\"[Client %d] \" message, client->socket->fd(), ##__VA_ARGS__)\n\nclient_context_t *current_client_context = NULL;\nhomekit_server_t *running_server = nullptr;\n//WiFiEventHandler arduino_homekit_gotiphandler;//ESP32\n\n#define HOMEKIT_NOTIFY_EVENT(server, event) \\\n  if ((server)->config->on_event) \\\n      (server)->config->on_event(event);\n\nvoid client_context_free(client_context_t *c);\nvoid pairing_context_free(pairing_context_t *context);\nvoid homekit_server_close_client(homekit_server_t *server, client_context_t *context);\nbool arduino_homekit_preinit(homekit_server_t *server);\nvoid homekit_on_paired_status_changed();\n\nhomekit_server_t* server_new() {\n\thomekit_server_t *server = (homekit_server_t*) malloc(sizeof(homekit_server_t));\n\tserver->wifi_server = new WiFiServer(HOMEKIT_SERVER_PORT);\n\tserver->wifi_server->begin();\n\tserver->wifi_server->setNoDelay(true);\n\tDEBUG(\"WiFiServer begin at port: %d\", HOMEKIT_SERVER_PORT);\n\t//FD_ZERO(&server->fds);\n\t//server->max_fd = 0;\n\tserver->nfds = 0;\n\tserver->config = NULL;\n\tserver->paired = false;\n\tserver->pairing_context = NULL;\n\tserver->clients = NULL;\n\treturn server;\n}\n\nvoid server_free(homekit_server_t *server) {\n\tif (server->pairing_context)\n\t\tpairing_context_free(server->pairing_context);\n\n\tif (server->clients) {\n\t\tclient_context_t *client = server->clients;\n\t\twhile (client) {\n\t\t\tclient_context_t *next = client->next;\n\t\t\tclient_context_free(client);\n\t\t\tclient = next;\n\t\t}\n\t}\n\tif (server->wifi_server) {\n\t\tserver->wifi_server->stop();\n\t\tserver->wifi_server->close();\n\t\tdelete server->wifi_server;\n\t\tserver->wifi_server = nullptr;\n\t} DEBUG(\"homekit_server_t delete WiFiServer at port: %d\\n\", HOMEKIT_SERVER_PORT);\n\n\tif (server == running_server) {\n\t\trunning_server = NULL;\n\t}\n\tfree(server);\n}\n\nvoid tlv_debug(const tlv_values_t *values) {\n\tDEBUG(\"Got following TLV values:\");\n\tfor (tlv_t *t = values->head; t; t = t->next) {\n\t\tchar *escaped_payload = binary_to_string(t->value, t->size);\n\t\tDEBUG(\"Type %d value (%d bytes): %s\", t->type, t->size, escaped_payload);\n\t\tfree(escaped_payload);\n\t}\n}\n\npair_verify_context_t* pair_verify_context_new() {\n\tpair_verify_context_t *context = (pair_verify_context_t*) malloc(sizeof(pair_verify_context_t));\n\n\tcontext->secret = NULL;\n\tcontext->secret_size = 0;\n\n\tcontext->session_key = NULL;\n\tcontext->session_key_size = 0;\n\tcontext->device_public_key = NULL;\n\tcontext->device_public_key_size = 0;\n\tcontext->accessory_public_key = NULL;\n\tcontext->accessory_public_key_size = 0;\n\n\treturn context;\n}\n\nvoid pair_verify_context_free(pair_verify_context_t *context) {\n\tif (context->secret)\n\t\tfree(context->secret);\n\n\tif (context->session_key)\n\t\tfree(context->session_key);\n\n\tif (context->device_public_key)\n\t\tfree(context->device_public_key);\n\n\tif (context->accessory_public_key)\n\t\tfree(context->accessory_public_key);\n\n\tfree(context);\n}\n\n//==========================\n// client_context new and free\n//============================\nclient_context_t* client_context_new(WiFiClient *wifiClient) {\n\tclient_context_t *c = (client_context_t*) malloc(sizeof(client_context_t));\n\tc->server = NULL;\n\tc->endpoint_params = NULL;\n\n\tc->data_size = sizeof(c->data);\n\tc->data_available = 0;\n\n\tc->body = NULL;\n\tc->body_length = 0;\n\thttp_parser_init(&c->parser, HTTP_REQUEST);\n\tc->parser.data = c;\n\n\tc->pairing_id = -1;\n\tc->encrypted = false;\n\tc->count_reads = 0;\n\tc->count_writes = 0;\n\tc->disconnect = false;\n\n\t//c->event_queue = xQueueCreate(20, sizeof(characteristic_event_t*));\n\tc->event_queue = (Queue_t*) malloc(sizeof(Queue_t));\n\tq_init(c->event_queue, sizeof(characteristic_event_t*),\n\tHOMEKIT_EVENT_QUEUE_SIZE, LIFO, true);\n\n\tc->verify_context = NULL;\n\n\tc->next = NULL;\n\n\tc->socket = wifiClient;\n\n\tc->step = HOMEKIT_CLIENT_STEP_NONE;\n\tc->error_write = false;\n\n\treturn c;\n}\n\nvoid client_context_free(client_context_t *c) {\n\tif (c->verify_context)\n\t\tpair_verify_context_free(c->verify_context);\n\n\tif (c->event_queue) {\n\t\t//c->event_queue->clear();\n\t\tq_clean(c->event_queue);\n\t\tq_kill(c->event_queue);\n\t\tfree(c->event_queue);\n\t}\n\n\tif (c->endpoint_params)\n\t\tquery_params_free(c->endpoint_params);\n\n\tif (c->body)\n\t\tfree(c->body);\n\n\tif (c->socket) {\n\t\tc->socket->stop();\n\t\tdelete c->socket;\n\t\tc->socket = nullptr;\n\t}\n\n\tfree(c);\n}\n\npairing_context_t *saved_preinit_pairing_context = nullptr;\n\npairing_context_t* pairing_context_new() {\n\tpairing_context_t *context = (pairing_context_t*) malloc(sizeof(pairing_context_t));\n\tcontext->srp = crypto_srp_new();\n\tcontext->client = NULL;\n\tcontext->public_key = NULL;\n\tcontext->public_key_size = 0;\n\treturn context;\n}\n\nvoid pairing_context_free(pairing_context_t *context) {\n\tif (context == saved_preinit_pairing_context) {\n\t\tINFO(\"Free saved_preinit_pairing_context\");\n\t\tif (saved_preinit_pairing_context) {\n\t\t\tsaved_preinit_pairing_context = nullptr;\n\t\t}\n\t}\n\tif (context->srp) {\n\t\tcrypto_srp_free(context->srp);\n\t}\n\tif (context->public_key) {\n\t\tfree(context->public_key);\n\t}\n\tfree(context);\n}\n\n//=====================\n//pairing context\n//=====================\n\nvoid client_notify_characteristic(homekit_characteristic_t *ch, homekit_value_t value,\n\t\tvoid *client);\n\nvoid write_characteristic_json(json_stream *json, client_context_t *client,\n\t\tconst homekit_characteristic_t *ch, characteristic_format_t format,\n\t\tconst homekit_value_t *value) {\n\tjson_string(json, \"aid\");\n\tjson_uint32(json, ch->service->accessory->id);\n\tjson_string(json, \"iid\");\n\tjson_uint32(json, ch->id);\n\n\tif (format & characteristic_format_type) {\n\t\tjson_string(json, \"type\");\n\t\tjson_string(json, ch->type);\n\t}\n\n\tif (format & characteristic_format_perms) {\n\t\tjson_string(json, \"perms\");\n\t\tjson_array_start(json);\n\t\tif (ch->permissions & homekit_permissions_paired_read)\n\t\t\tjson_string(json, \"pr\");\n\t\tif (ch->permissions & homekit_permissions_paired_write)\n\t\t\tjson_string(json, \"pw\");\n\t\tif (ch->permissions & homekit_permissions_notify)\n\t\t\tjson_string(json, \"ev\");\n\t\tif (ch->permissions & homekit_permissions_additional_authorization)\n\t\t\tjson_string(json, \"aa\");\n\t\tif (ch->permissions & homekit_permissions_timed_write)\n\t\t\tjson_string(json, \"tw\");\n\t\tif (ch->permissions & homekit_permissions_hidden)\n\t\t\tjson_string(json, \"hd\");\n\t\tjson_array_end(json);\n\t}\n\n\tif ((format & characteristic_format_events) && (ch->permissions & homekit_permissions_notify)) {\n\t\tbool events = homekit_characteristic_has_notify_callback(ch, client_notify_characteristic,\n\t\t\t\tclient);\n\t\tjson_string(json, \"ev\");\n\t\tjson_boolean(json, events);\n\t}\n\n\tif (format & characteristic_format_meta) {\n\t\tif (ch->description) {\n\t\t\tjson_string(json, \"description\");\n\t\t\tjson_string(json, ch->description);\n\t\t}\n\n\t\tconst char *format_str = NULL;\n\t\tswitch (ch->format) {\n\t\tcase homekit_format_bool:\n\t\t\tformat_str = \"bool\";\n\t\t\tbreak;\n\t\tcase homekit_format_uint8:\n\t\t\tformat_str = \"uint8\";\n\t\t\tbreak;\n\t\tcase homekit_format_uint16:\n\t\t\tformat_str = \"uint16\";\n\t\t\tbreak;\n\t\tcase homekit_format_uint32:\n\t\t\tformat_str = \"uint32\";\n\t\t\tbreak;\n\t\tcase homekit_format_uint64:\n\t\t\tformat_str = \"uint64\";\n\t\t\tbreak;\n\t\tcase homekit_format_int:\n\t\t\tformat_str = \"int\";\n\t\t\tbreak;\n\t\tcase homekit_format_float:\n\t\t\tformat_str = \"float\";\n\t\t\tbreak;\n\t\tcase homekit_format_string:\n\t\t\tformat_str = \"string\";\n\t\t\tbreak;\n\t\tcase homekit_format_tlv:\n\t\t\tformat_str = \"tlv8\";\n\t\t\tbreak;\n\t\tcase homekit_format_data:\n\t\t\tformat_str = \"data\";\n\t\t\tbreak;\n\t\t}\n\t\tif (format_str) {\n\t\t\tjson_string(json, \"format\");\n\t\t\tjson_string(json, format_str);\n\t\t}\n\n\t\tconst char *unit_str = NULL;\n\t\tswitch (ch->unit) {\n\t\tcase homekit_unit_none:\n\t\t\tbreak;\n\t\tcase homekit_unit_celsius:\n\t\t\tunit_str = \"celsius\";\n\t\t\tbreak;\n\t\tcase homekit_unit_percentage:\n\t\t\tunit_str = \"percentage\";\n\t\t\tbreak;\n\t\tcase homekit_unit_arcdegrees:\n\t\t\tunit_str = \"arcdegrees\";\n\t\t\tbreak;\n\t\tcase homekit_unit_lux:\n\t\t\tunit_str = \"lux\";\n\t\t\tbreak;\n\t\tcase homekit_unit_seconds:\n\t\t\tunit_str = \"seconds\";\n\t\t\tbreak;\n\t\t}\n\t\tif (unit_str) {\n\t\t\tjson_string(json, \"unit\");\n\t\t\tjson_string(json, unit_str);\n\t\t}\n\n\t\tif (ch->min_value) {\n\t\t\tjson_string(json, \"minValue\");\n\t\t\tjson_float(json, *ch->min_value);\n\t\t}\n\n\t\tif (ch->max_value) {\n\t\t\tjson_string(json, \"maxValue\");\n\t\t\tjson_float(json, *ch->max_value);\n\t\t}\n\n\t\tif (ch->min_step) {\n\t\t\tjson_string(json, \"minStep\");\n\t\t\tjson_float(json, *ch->min_step);\n\t\t}\n\n\t\tif (ch->max_len) {\n\t\t\tjson_string(json, \"maxLen\");\n\t\t\tjson_uint32(json, *ch->max_len);\n\t\t}\n\n\t\tif (ch->max_data_len) {\n\t\t\tjson_string(json, \"maxDataLen\");\n\t\t\tjson_uint32(json, *ch->max_data_len);\n\t\t}\n\n\t\tif (ch->valid_values.count) {\n\t\t\tjson_string(json, \"valid-values\");\n\t\t\tjson_array_start(json);\n\n\t\t\tfor (int i = 0; i < ch->valid_values.count; i++) {\n\t\t\t\tjson_uint16(json, ch->valid_values.values[i]);\n\t\t\t}\n\n\t\t\tjson_array_end(json);\n\t\t}\n\n\t\tif (ch->valid_values_ranges.count) {\n\t\t\tjson_string(json, \"valid-values-range\");\n\t\t\tjson_array_start(json);\n\n\t\t\tfor (int i = 0; i < ch->valid_values_ranges.count; i++) {\n\t\t\t\tjson_array_start(json);\n\n\t\t\t\tjson_integer(json, ch->valid_values_ranges.ranges[i].start);\n\t\t\t\tjson_integer(json, ch->valid_values_ranges.ranges[i].end);\n\n\t\t\t\tjson_array_end(json);\n\t\t\t}\n\n\t\t\tjson_array_end(json);\n\t\t}\n\t}\n\n\tif (ch->permissions & homekit_permissions_paired_read) {\n\t\thomekit_value_t v = value ? *value : ch->getter_ex ? ch->getter_ex(ch) : ch->value;\n\n\t\tif (v.is_null) {\n\t\t\tjson_string(json, \"value\");\n\t\t\tjson_null(json);\n\t\t} else if (v.format != ch->format) {\n\t\t\tERROR(\"Characteristic value format is different from characteristic format\");\n\t\t} else {\n\t\t\tswitch (v.format) {\n\t\t\tcase homekit_format_bool: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_boolean(json, v.bool_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint8: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_uint8(json, v.uint8_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint16: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_uint16(json, v.uint16_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint32: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_uint32(json, v.uint32_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint64: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_uint64(json, v.uint64_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_int: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_integer(json, v.int_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_float: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_float(json, v.float_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_string: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_string(json, v.string_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_tlv: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tif (!v.tlv_values) {\n\t\t\t\t\tjson_string(json, \"\");\n\t\t\t\t} else {\n\t\t\t\t\tsize_t tlv_size = 0;\n\t\t\t\t\ttlv_format(v.tlv_values, NULL, &tlv_size);\n\t\t\t\t\tif (tlv_size == 0) {\n\t\t\t\t\t\tjson_string(json, \"\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbyte *tlv_data = (byte*) malloc(tlv_size);\n\t\t\t\t\t\ttlv_format(v.tlv_values, tlv_data, &tlv_size);\n\n\t\t\t\t\t\tsize_t encoded_tlv_size = base64_encoded_size(tlv_data, tlv_size);\n\t\t\t\t\t\tbyte *encoded_tlv_data = (byte*) malloc(encoded_tlv_size + 1);\n\t\t\t\t\t\tbase64_encode_(tlv_data, tlv_size, encoded_tlv_data);\n\t\t\t\t\t\tencoded_tlv_data[encoded_tlv_size] = 0;\n\n\t\t\t\t\t\tjson_string(json, (char*) encoded_tlv_data);\n\n\t\t\t\t\t\tfree(encoded_tlv_data);\n\t\t\t\t\t\tfree(tlv_data);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_data: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tif (!v.data_value || v.data_size == 0) {\n\t\t\t\t\tjson_string(json, \"\");\n\t\t\t\t} else {\n\t\t\t\t\tsize_t encoded_data_size = base64_encoded_size(v.data_value, v.data_size);\n\t\t\t\t\tbyte *encoded_data = (byte*) malloc(encoded_data_size + 1);\n\t\t\t\t\tbase64_encode_(v.data_value, v.data_size, encoded_data);\n\t\t\t\t\tencoded_data[encoded_data_size] = 0;\n\n\t\t\t\t\tjson_string(json, (char*) encoded_data);\n\n\t\t\t\t\tfree(encoded_data);\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!value && ch->getter_ex) {\n\t\t\t// called getter to get value, need to free it\n\t\t\thomekit_value_destruct(&v);\n\t\t}\n\t}\n}\n\nvoid write(client_context_t *context, byte *data, int data_size) {\n\tif ((!context) || (!context->socket) || (!context->socket->connected())) {\n\t\tCLIENT_ERROR(context, \"The socket is null! (or is closed)\");\n\t\treturn;\n\t}\n\tif (context->error_write) {\n\t\tCLIENT_ERROR(context, \"Abort write data since error_write.\");\n\t\treturn;\n\t}\n\tint write_size = context->socket->write(data, data_size);\n\tCLIENT_DEBUG(context, \"Sending data of size %d\", data_size);\n\tif (write_size != data_size) {\n\t\tCLIENT_ERROR(context, \"socket.write, data_size=%d, write_size=%d\", data_size, write_size);\n\t\tcontext->error_write = true;\n\t\t// Error write when :\n\t\t// 1. remote client is disconnected\n\t\t// 2. data_size is larger than the tcp internal send buffer\n\t\t// But We has limited the data_size to 538, and TCP_SND_BUF = 1072. (See the comments on HOMEKIT_JSONBUFFER_SIZE)\n\t\t// So we believe here is disconnected.\n\t\tcontext->disconnect = true;\n\t\thomekit_server_close_client(context->server, context);\n\t\t// We consider the socket is 'closed' when error in writing (eg. the remote client is disconnected, NO tcp ack receive).\n\t\t// Closing the socket causes memory-leak if some data has not been sent (the write_buffer did not free)\n\t\t// To fix this memory-leak, add tcp_abandon(_pcb, 0); in ClientContext.h of ESP8266WiFi-library.\n\t}\n\n}\n\nint client_send_encrypted_(client_context_t *context, byte *payload, size_t size) {\n\tCLIENT_DEBUG(context, \"Send encrypted of size %d\", size);\n\t// max(size) = HOMEKIT_JSONBUFFER_SIZE + chunk_info(8) = 512 + 8 = 520\n\tif (!context || !context->encrypted)\n\t\treturn -1;\n\n\t/*\n\t HAP doc:\n\t Each HTTP message is split into frames no larger than 1024 bytes.\n\t Each frame has the following format:\n\t <2:AAD for little endian length of encrypted data (n) in bytes>\n\t <n:encrypted data according to AEAD algorithm, up to 1024 bytes>\n\t <16:authTag according to AEAD algorithm>\n\t Note by Wang Bin. 2020-03-07\n\t */\n\n\tbyte nonce[12];\n\tmemset(nonce, 0, sizeof(nonce));\n\n\tbyte encrypted[1024 + 18];\n\tint payload_offset = 0;\n\n\twhile (payload_offset < size) {\n\t\tsize_t chunk_size = size - payload_offset;\n\t\tif (chunk_size > 1024)\n\t\t\tchunk_size = 1024;\n\n\t\tbyte aead[2] = { (byte) (chunk_size % 256), (byte) (chunk_size / 256) };\n\n\t\tmemcpy(encrypted, aead, 2);\n\n\t\tbyte i = 4;\n\t\tint x = context->count_reads++;\n\t\twhile (x) {\n\t\t\tnonce[i++] = x % 256;\n\t\t\tx /= 256;\n\t\t}\n\n\t\tsize_t available = sizeof(encrypted) - 2;\n\t\tint r = crypto_chacha20poly1305_encrypt(context->read_key, nonce, aead, 2,\n\t\t\t\tpayload + payload_offset, chunk_size, encrypted + 2, &available);\n\t\tif (r) {\n\t\t\tERROR(\"Failed to chacha encrypt payload (code %d)\", r);\n\t\t\treturn -1;\n\t\t}\n\n\t\tpayload_offset += chunk_size;\n\n\t\twrite(context, encrypted, available + 2);\n\t}\n\n\treturn 0;\n}\n\nint client_decrypt_(client_context_t *context, byte *payload, size_t payload_size, byte *decrypted,\n\t\tsize_t *decrypted_size) {\n\tif (!context || !context->encrypted)\n\t\treturn -1;\n\n\tconst size_t block_size = 1024 + 16 + 2;\n\tsize_t required_decrypted_size = payload_size / block_size * 1024;\n\tif (payload_size % block_size > 0)\n\t\trequired_decrypted_size += payload_size % block_size - 16 - 2;\n\n\tif (*decrypted_size < required_decrypted_size) {\n\t\t*decrypted_size = required_decrypted_size;\n\t\treturn -2;\n\t}\n\n\t*decrypted_size = required_decrypted_size;\n\n\tbyte nonce[12];\n\tmemset(nonce, 0, sizeof(nonce));\n\n\tint payload_offset = 0;\n\tint decrypted_offset = 0;\n\n\twhile (payload_offset < payload_size) {\n\t\tsize_t chunk_size = payload[payload_offset] + payload[payload_offset + 1] * 256;\n\t\tif (chunk_size + 18 > payload_size - payload_offset) {\n\t\t\t// Unfinished chunk\n\t\t\tbreak;\n\t\t}\n\n\t\tbyte i = 4;\n\t\tint x = context->count_writes++;\n\t\twhile (x) {\n\t\t\tnonce[i++] = x % 256;\n\t\t\tx /= 256;\n\t\t}\n\n\t\tsize_t decrypted_len = *decrypted_size - decrypted_offset;\n\t\tint r = crypto_chacha20poly1305_decrypt(context->write_key, nonce, payload + payload_offset,\n\t\t\t\t2, payload + payload_offset + 2, chunk_size + 16, decrypted, &decrypted_len);\n\t\tif (r) {\n\t\t\tERROR(\"Failed to chacha decrypt payload (code %d)\", r);\n\t\t\treturn -1;\n\t\t}\n\n\t\tdecrypted_offset += decrypted_len;\n\t\tpayload_offset += chunk_size + 18;\n\t}\n\n\treturn payload_offset;\n}\n\nvoid client_notify_characteristic(homekit_characteristic_t *ch, homekit_value_t value,\n\t\tvoid *context) {\n\tclient_context_t *client = (client_context_t*) context;\n\n\tif (client->current_characteristic == ch && client->current_value\n\t\t\t&& homekit_value_equal(client->current_value, &value)) {\n\t\t// This value is set by this client, no need to send notification\n\t\tCLIENT_DEBUG(client, \"This value is set by this client, no need to send notification\");\n\t\treturn;\n\t}\n\tCLIENT_INFO(client, \"Got characteristic %d.%d change event\", ch->service->accessory->id, ch->id);\n\t//DEBUG(\"Got characteristic %d.%d change event\", ch->service->accessory->id, ch->id);\n\n\tif (!client->event_queue) {\n\t\tERROR(\"Client has no event queue. Skipping notification\");\n\t\treturn;\n\t}\n\n\tcharacteristic_event_t *event = (characteristic_event_t*) malloc(\n\t\t\tsizeof(characteristic_event_t));\n\tevent->characteristic = ch;\n\thomekit_value_copy(&event->value, &value);\n\n\tDEBUG(\"Sending event to client %d\", client->socket);\n\n\t//xQueueSendToBack(client->event_queue, &event, 10);*/\n\t//q_push第二个参数要传指针地址\n\tq_push(client->event_queue, &event);\n}\n\nvoid client_send(client_context_t *context, byte *data, size_t data_size) {\n\n\tCLIENT_DEBUG(context, \"send data size=%d, encrypted=%s\",\n\t\t\tdata_size, context->encrypted ? \"true\" : \"false\");\n\n\tif (context->encrypted) {\n\t\tint r = client_send_encrypted_(context, data, data_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to encrypt response (code %d)\", r);\n\t\t\treturn;\n\t\t}\n\t} else {\n\t\twrite(context, data, data_size);\n\t}\n}\n\nvoid client_send_P(client_context_t *context, PGM_P pgm) {\n\tXPGM_BUFFCPY_STRING(char, buff, pgm);\n\t//client_send(context, (byte*)buff, sizeof(buff) - 1);\n\tclient_send(context, (byte*) buff, buff_size - 1);\n}\n\nvoid client_send_chunk(byte *data, size_t size, void *arg) {\n\tclient_context_t *context = (client_context_t*) arg;\n\n\tsize_t payload_size = size + 8;\n\tbyte *payload = (byte*) malloc(payload_size);\n\tif (!payload) {\n\t\tERROR(\"Error malloc payload!! payload_size->%d\", payload_size);\n\t\treturn;\n\t}\n\n\tint offset = snprintf((char*) payload, payload_size, \"%x\\r\\n\", size);\n\tmemcpy(payload + offset, data, size);\n\tpayload[offset + size] = '\\r';\n\tpayload[offset + size + 1] = '\\n';\n\tCLIENT_DEBUG(context, \"client_send_chunk, size=%d, offset=%d\", size, offset);\n\tclient_send(context, payload, offset + size + 2);\n\tfree(payload);\n}\n\nvoid send_204_response(client_context_t *context) {\n\tstatic const char PROGMEM response[] = \"HTTP/1.1 204 No Content\\r\\n\\r\\n\";\n\tclient_send_P(context, response);\n}\n\nvoid send_404_response(client_context_t *context) {\n\tstatic const char PROGMEM response[] = \"HTTP/1.1 404 Not Found\\r\\n\\r\\n\";\n\tclient_send_P(context, response);\n}\n\nvoid send_client_events(client_context_t *context, client_event_t *events) {\n\tCLIENT_DEBUG(context, \"Sending EVENT\");DEBUG_HEAP();\n\n\tstatic const char PROGMEM http_headers[] = \"EVENT/1.0 200 OK\\r\\n\"\n\t\t\t\"Content-Type: application/hap+json\\r\\n\"\n\t\t\t\"Transfer-Encoding: chunked\\r\\n\\r\\n\";\n\tclient_send_P(context, http_headers);\n\n\t// ~35 bytes per event JSON\n\t// 256 should be enough for ~7 characteristic updates\n\tjson_stream *json = json_new(HOMEKIT_JSONBUFFER_SIZE, client_send_chunk, context);\n\tjson_object_start(json);\n\tjson_string(json, \"characteristics\");\n\tjson_array_start(json);\n\n\tclient_event_t *e = events;\n\twhile (e) {\n\t\tjson_object_start(json);\n\t\twrite_characteristic_json(json, context, e->characteristic, (characteristic_format_t) 0,\n\t\t\t\t&e->value);\n\t\tjson_object_end(json);\n\n\t\te = e->next;\n\t}\n\n\tjson_array_end(json);\n\tjson_object_end(json);\n\n\tjson_flush(json);\n\tjson_free(json);\n\n\tclient_send_chunk(NULL, 0, context);\n}\n\nvoid send_tlv_response(client_context_t *context, tlv_values_t *values);\n\nvoid send_tlv_error_response(client_context_t *context, int state, TLVError error) {\n\ttlv_values_t *response = tlv_new();\n\ttlv_add_integer_value(response, TLVType_State, 1, state);\n\ttlv_add_integer_value(response, TLVType_Error, 1, error);\n\n\tsend_tlv_response(context, response);\n}\n\nvoid send_tlv_response(client_context_t *context, tlv_values_t *values) {\n\tCLIENT_DEBUG(context, \"Sending TLV response\");TLV_DEBUG(values);\n\n\tsize_t payload_size = 0;\n\ttlv_format(values, NULL, &payload_size);\n\n\tbyte *payload = (byte*) malloc(payload_size);\n\tint r = tlv_format(values, payload, &payload_size);\n\tif (r) {\n\t\tCLIENT_ERROR(context, \"Failed to format TLV payload (code %d)\", r);\n\t\tfree(payload);\n\t\treturn;\n\t}\n\n\ttlv_free(values);\n\n\tstatic const char PROGMEM http_headers_pgm[] = \"HTTP/1.1 200 OK\\r\\n\"\n\t\t\t\"Content-Type: application/pairing+tlv8\\r\\n\"\n\t\t\t\"Content-Length: %d\\r\\n\"\n\t\t\t\"Connection: keep-alive\\r\\n\\r\\n\";\n\n\tXPGM_BUFFCPY_STRING(char, http_headers, http_headers_pgm);\n\n\tint response_size = strlen(http_headers) + payload_size + 32;\n\tchar *response = (char*) malloc(response_size);\n\tint response_len = snprintf(response, response_size, http_headers, payload_size);\n\n\tif (response_size - response_len < payload_size + 1) {\n\t\tCLIENT_ERROR(context, \"Incorrect response buffer size %d: headers took %d, payload size %d\",\n\t\t\t\tresponse_size, response_len, payload_size);\n\t\tfree(response);\n\t\tfree(payload);\n\t\treturn;\n\t}\n\tmemcpy(response + response_len, payload, payload_size);\n\tresponse_len += payload_size;\n\n\tfree(payload);\n\n\tclient_send(context, (byte*) response, response_len);\n\n\tfree(response);\n}\n\nstatic const char PROGMEM json_200_response_headers_progmem[] = \"HTTP/1.1 200 OK\\r\\n\"\n\t\t\"Content-Type: application/hap+json\\r\\n\"\n\t\t\"Transfer-Encoding: chunked\\r\\n\"\n\t\t\"Connection: keep-alive\\r\\n\\r\\n\";\n\nstatic const char PROGMEM json_207_response_headers_progmem[] = \"HTTP/1.1 207 Multi-Status\\r\\n\"\n\t\t\"Content-Type: application/hap+json\\r\\n\"\n\t\t\"Transfer-Encoding: chunked\\r\\n\"\n\t\t\"Connection: keep-alive\\r\\n\\r\\n\";\n\nvoid send_json_response(client_context_t *context, int status_code, byte *payload,\n\t\tsize_t payload_size) {\n\tCLIENT_DEBUG(context, \"Sending JSON response\");DEBUG_HEAP();\n\n\tstatic const char PROGMEM http_headers_pgm[] = \"HTTP/1.1 %d %s\\r\\n\"\n\t\t\t\"Content-Type: application/hap+json\\r\\n\"\n\t\t\t\"Content-Length: %d\\r\\n\"\n\t\t\t\"Connection: keep-alive\\r\\n\\r\\n\";\n\n\tXPGM_BUFFCPY_STRING(char, http_headers, http_headers_pgm);\n\n\tCLIENT_DEBUG(context, \"Payload: %s\", payload);\n\n\t// Using PSTR and strcpy_P. Ref: ESP.getResetReason\n\t//const char *status_text = \"OK\";\n\tchar status_text[32];\n\tstrcpy_P(status_text, PSTR(\"OK\"));\n\tswitch (status_code) {\n\tcase 204:\n\t\tstrcpy_P(status_text, PSTR(\"No Content\"));\n\t\tbreak;\n\tcase 207:\n\t\tstrcpy_P(status_text, PSTR(\"Multi-Status\"));\n\t\tbreak;\n\tcase 400:\n\t\tstrcpy_P(status_text, PSTR(\"Bad Request\"));\n\t\tbreak;\n\tcase 404:\n\t\tstrcpy_P(status_text, PSTR(\"Not Found\"));\n\t\tbreak;\n\tcase 422:\n\t\tstrcpy_P(status_text, PSTR(\"Unprocessable Entity\"));\n\t\tbreak;\n\tcase 500:\n\t\tstrcpy_P(status_text, PSTR(\"Internal Server Error\"));\n\t\tbreak;\n\tcase 503:\n\t\tstrcpy_P(status_text, PSTR(\"Service Unavailable\"));\n\t\tbreak;\n\t}\n\n\tint response_size = strlen(http_headers) + payload_size + strlen(status_text) + 32;\n\tchar *response = (char*) malloc(response_size);\n\tif (!response) {\n\t\tCLIENT_ERROR(context, \"Failed to allocate response buffer of size %d\", response_size);\n\t\treturn;\n\t}\n\tint response_len = snprintf(response, response_size, http_headers, status_code, status_text,\n\t\t\tpayload_size);\n\n\tif (response_size - response_len < payload_size + 1) {\n\t\tCLIENT_ERROR(context, \"Incorrect response buffer size %d: headers took %d, payload size %d\",\n\t\t\t\tresponse_size, response_len, payload_size);\n\t\tfree(response);\n\t\treturn;\n\t}\n\tmemcpy(response + response_len, payload, payload_size);\n\tresponse_len += payload_size;\n\tresponse[response_len] = 0;  // required for debug output\n\n\tCLIENT_DEBUG(context, \"Sending HTTP response: %s\", response);\n\n\tclient_send(context, (byte*) response, response_len);\n\n\tfree(response);\n}\n\nvoid send_json_error_response(client_context_t *context, int status_code, HAPStatus status) {\n\tbyte buffer[32];\n\tint size = snprintf((char*) buffer, sizeof(buffer), \"{\\\"status\\\": %d}\", status);\n\n\tsend_json_response(context, status_code, buffer, size);\n}\n\nhomekit_client_id_t homekit_get_client_id() {\n\treturn (homekit_client_id_t) current_client_context;\n}\n\nbool homekit_client_is_admin() {\n\tif (!current_client_context)\n\t\treturn false;\n\n\treturn current_client_context->permissions & pairing_permissions_admin;\n}\n\nint homekit_client_send(unsigned char *data, size_t size) {\n\tif (!current_client_context)\n\t\treturn -1;\n\tclient_send(current_client_context, data, size);\n\treturn 0;\n}\n\nvoid homekit_server_on_identify(client_context_t *context) {\n\tCLIENT_INFO(context, \"Identify\");DEBUG_HEAP();\n\tif (context->server->paired) {\n\t\t// Already paired\n\t\tsend_json_error_response(context, 400, HAPStatus_InsufficientPrivileges);\n\t\treturn;\n\t}\n\tsend_204_response(context);\n\thomekit_accessory_t *accessory = homekit_accessory_by_id(context->server->config->accessories,\n\t\t\t1);\n\tif (!accessory) {\n\t\treturn;\n\t}\n\n\thomekit_service_t *accessory_info = homekit_service_by_type(accessory,\n\tHOMEKIT_SERVICE_ACCESSORY_INFORMATION);\n\tif (!accessory_info) {\n\t\treturn;\n\t}\n\n\thomekit_characteristic_t *ch_identify = homekit_service_characteristic_by_type(accessory_info,\n\tHOMEKIT_CHARACTERISTIC_IDENTIFY);\n\tif (!ch_identify) {\n\t\treturn;\n\t}\n\tif (ch_identify->setter_ex) {\n\t\tch_identify->setter_ex(ch_identify, HOMEKIT_BOOL_CPP(true));\n\t}\n}\n\nvoid homekit_server_on_pair_setup(client_context_t *context, const byte *data, size_t size) {\n\tDEBUG(\"Pair Setup\");DEBUG_HEAP();\n\tDEBUG_TIME_BEGIN();\n\n#ifdef HOMEKIT_OVERCLOCK_PAIR_SETUP\n    homekit_overclock_start();\n#endif\n\n\t// First set step=NONE, if pair-setup ok then set step=1or2or3\n\t// (if pair-step error, the step is NONE)\n\n\tcontext->step = HOMEKIT_CLIENT_STEP_NONE;\n\n\ttlv_values_t *message = tlv_new();\n\ttlv_parse(data, size, message);\n\tTLV_DEBUG(message);\n\tswitch (tlv_get_integer_value(message, TLVType_State, -1)) {\n\tcase 1: {\n\t\tCLIENT_INFO(context, \"Pair Setup Step 1/3\");DEBUG_HEAP();\n\t\tif (context->server->paired) {\n\t\t\tCLIENT_INFO(context, \"Refusing to pair: already paired\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unavailable);\n\t\t\tbreak;\n\t\t}\n\t\tif (context->server->pairing_context) {\n\t\t\tif (context->server->pairing_context->client != context) {\n\t\t\t\tCLIENT_INFO(context, \"Refusing to pair: another pairing in progress\");\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Busy);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\t// arduino homekit preinit (create pairing_context)\n\t\t\tif (!arduino_homekit_preinit(context->server)) {\n\t\t\t\tCLIENT_ERROR(context, \"Init pairing context error\");\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (saved_preinit_pairing_context == nullptr) {\n\t\t\t\tCLIENT_ERROR(context, \"The saved_preinit_pairing_context is NULL ?!\");\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcontext->server->pairing_context = saved_preinit_pairing_context; ///pairing_context_new();\n\t\t\tcontext->server->pairing_context->client = context;\n\t\t}\n\n\t\tint r = 0;\n\t\tsize_t salt_size = 0;\n\t\tcrypto_srp_get_salt(context->server->pairing_context->srp, NULL, &salt_size);\n\t\tbyte *salt = (byte*) malloc(salt_size);\n\t\tr = crypto_srp_get_salt(context->server->pairing_context->srp, salt, &salt_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to get salt (code %d)\", r);\n\t\t\tfree(salt);\n\t\t\tpairing_context_free(context->server->pairing_context);\n\t\t\tcontext->server->pairing_context = NULL;\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_value(response, TLVType_PublicKey, context->server->pairing_context->public_key,\n\t\t\t\tcontext->server->pairing_context->public_key_size);\n\t\ttlv_add_value(response, TLVType_Salt, salt, salt_size);\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 2);\n\t\tfree(salt);\n\t\tsend_tlv_response(context, response);\n\t\tcontext->step = HOMEKIT_CLIENT_STEP_PAIR_SETUP_1OF3;\n\t\tbreak;\n\t}\n\tcase 3: {\n\t\tCLIENT_INFO(context, \"Pair Setup Step 2/3\");DEBUG_HEAP();\n\t\ttlv_t *device_public_key = tlv_get_value(message, TLVType_PublicKey);\n\t\tif (!device_public_key) {\n\t\t\tCLIENT_ERROR(context, \"Invalid payload: no device public key\");\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *proof = tlv_get_value(message, TLVType_Proof);\n\t\tif (!proof) {\n\t\t\tCLIENT_ERROR(context, \"Invalid payload: no device proof\");\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t} CLIENT_DEBUG(context, \"Computing SRP shared secret\");DEBUG_HEAP();\n\t\twatchdog_disable_all();\n\t\twatchdog_check_begin();\n\t\tint r = crypto_srp_compute_key(context->server->pairing_context->srp,\n\t\t\t\tdevice_public_key->value, device_public_key->size,\n\t\t\t\tcontext->server->pairing_context->public_key,\n\t\t\t\tcontext->server->pairing_context->public_key_size);\n\t\twatchdog_check_end(\"crypto_srp_compute_key\"); // 13479ms\n\t\twatchdog_enable_all();\n\n\t\tdelay(10);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to compute SRP shared secret (code %d)\", r);\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tfree(context->server->pairing_context->public_key);\n\t\tcontext->server->pairing_context->public_key = NULL;\n\t\tcontext->server->pairing_context->public_key_size = 0;\n\n\t\tCLIENT_DEBUG(context, \"Verifying peer's proof\");\n\n\t\t//watchdog_check_begin();\n\t\tr = crypto_srp_verify(context->server->pairing_context->srp, proof->value, proof->size);\n\t\t//watchdog_check_end(\"crypto_srp_verify\");// 1ms\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to verify peer's proof (code %d)\", r);\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t} CLIENT_DEBUG(context, \"Generating own proof\");\n\t\tsize_t server_proof_size = 0;\n\t\tcrypto_srp_get_proof(context->server->pairing_context->srp, NULL, &server_proof_size);\n\n\t\tbyte *server_proof = (byte*) malloc(server_proof_size);\n\t\t//watchdog_check_begin();\n\t\tr = crypto_srp_get_proof(context->server->pairing_context->srp, server_proof,\n\t\t\t\t&server_proof_size);\n\t\t//watchdog_check_end(\"crypto_srp_get_proof\");// 1ms\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 4);\n\t\ttlv_add_value(response, TLVType_Proof, server_proof, server_proof_size);\n\t\tfree(server_proof);\n\t\tsend_tlv_response(context, response);\n\t\tcontext->step = HOMEKIT_CLIENT_STEP_PAIR_SETUP_2OF3;\n\t\tbreak;\n\t}\n\tcase 5: {\n\t\tCLIENT_INFO(context, \"Pair Setup Step 3/3\");DEBUG_HEAP();\n\t\tint r;\n\t\tbyte shared_secret[HKDF_HASH_SIZE];\n\t\tsize_t shared_secret_size = sizeof(shared_secret);\n\n\t\tCLIENT_DEBUG(context, \"Calculating shared secret\");\n\t\tconst char salt1[] = \"Pair-Setup-Encrypt-Salt\";\n\t\tconst char info1[] = \"Pair-Setup-Encrypt-Info\";\n\n\t\tr = crypto_srp_hkdf(context->server->pairing_context->srp, (byte*) salt1, sizeof(salt1) - 1,\n\t\t\t\t(byte*) info1, sizeof(info1) - 1, shared_secret, &shared_secret_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate shared secret (code %d)\", r);\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_encrypted_data = tlv_get_value(message, TLVType_EncryptedData);\n\t\tif (!tlv_encrypted_data) {\n\t\t\tCLIENT_ERROR(context, \"Invalid payload: no encrypted data\");\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Decrypting payload\");\n\t\tsize_t decrypted_data_size = 0;\n\t\tcrypto_chacha20poly1305_decrypt(shared_secret, (byte*) \"\\x0\\x0\\x0\\x0PS-Msg05\", NULL, 0,\n\t\t\t\ttlv_encrypted_data->value, tlv_encrypted_data->size,\n\t\t\t\tNULL, &decrypted_data_size);\n\n\t\tbyte *decrypted_data = (byte*) malloc(decrypted_data_size);\n\t\t// TODO: check malloc result\n\t\tr = crypto_chacha20poly1305_decrypt(shared_secret, (byte*) \"\\x0\\x0\\x0\\x0PS-Msg05\", NULL, 0,\n\t\t\t\ttlv_encrypted_data->value, tlv_encrypted_data->size, decrypted_data,\n\t\t\t\t&decrypted_data_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to decrypt data (code %d)\", r);\n\n\t\t\tfree(decrypted_data);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *decrypted_message = tlv_new();\n\t\tr = tlv_parse(decrypted_data, decrypted_data_size, decrypted_message);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to parse decrypted TLV (code %d)\", r);\n\n\t\t\ttlv_free(decrypted_message);\n\t\t\tfree(decrypted_data);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tfree(decrypted_data);\n\n\t\ttlv_t *tlv_device_id = tlv_get_value(decrypted_message, TLVType_Identifier);\n\t\tif (!tlv_device_id) {\n\t\t\tCLIENT_ERROR(context, \"Invalid encrypted payload: no device identifier\");\n\n\t\t\ttlv_free(decrypted_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\t// TODO: check that tlv_device_id->size == 36\n\n\t\ttlv_t *tlv_device_public_key = tlv_get_value(decrypted_message, TLVType_PublicKey);\n\t\tif (!tlv_device_public_key) {\n\t\t\tCLIENT_ERROR(context, \"Invalid encrypted payload: no device public key\");\n\n\t\t\ttlv_free(decrypted_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_device_signature = tlv_get_value(decrypted_message, TLVType_Signature);\n\t\tif (!tlv_device_signature) {\n\t\t\tCLIENT_ERROR(context, \"Invalid encrypted payload: no device signature\");\n\n\t\t\ttlv_free(decrypted_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Importing device public key\");\n\n\t\ted25519_key device_key;\n\t\tcrypto_ed25519_init(&device_key);\n\n\t\tr = crypto_ed25519_import_public_key(&device_key, tlv_device_public_key->value,\n\t\t\t\ttlv_device_public_key->size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to import device public Key (code %d)\", r);\n\n\t\t\ttlv_free(decrypted_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tbyte device_x[HKDF_HASH_SIZE];\n\t\tsize_t device_x_size = sizeof(device_x);\n\n\t\tCLIENT_DEBUG(context, \"Calculating DeviceX\");\n\t\tconst char salt2[] = \"Pair-Setup-Controller-Sign-Salt\";\n\t\tconst char info2[] = \"Pair-Setup-Controller-Sign-Info\";\n\n\t\tr = crypto_srp_hkdf(context->server->pairing_context->srp, (byte*) salt2, sizeof(salt2) - 1,\n\t\t\t\t(byte*) info2, sizeof(info2) - 1, device_x, &device_x_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate DeviceX (code %d)\", r);\n\n\t\t\ttlv_free(decrypted_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tsize_t device_info_size = device_x_size + tlv_device_id->size + tlv_device_public_key->size;\n\t\tbyte *device_info = (byte*) malloc(device_info_size);\n\t\tmemcpy(device_info, device_x, device_x_size);\n\t\tmemcpy(device_info + device_x_size, tlv_device_id->value, tlv_device_id->size);\n\t\tmemcpy(device_info + device_x_size + tlv_device_id->size, tlv_device_public_key->value,\n\t\t\t\ttlv_device_public_key->size);\n\n\t\tCLIENT_DEBUG(context, \"Verifying device signature\");\n\t\tr = crypto_ed25519_verify(&device_key, device_info, device_info_size,\n\t\t\t\ttlv_device_signature->value, tlv_device_signature->size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate DeviceX (code %d)\", r);\n\n\t\t\tfree(device_info);\n\t\t\ttlv_free(decrypted_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tfree(device_info);\n\n\t\tr = homekit_storage_add_pairing((const char*) tlv_device_id->value, &device_key,\n\t\t\t\tpairing_permissions_admin);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to store pairing (code %d)\", r);\n\n\t\t\ttlv_free(decrypted_message);\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tchar *device_id = strndup((const char*) tlv_device_id->value, tlv_device_id->size);\n\t\tINFO(\"Added pairing with %s\", device_id);\n\t\tfree(device_id);\n\n\t\ttlv_free(decrypted_message);\n\n\t\tHOMEKIT_NOTIFY_EVENT(context->server, HOMEKIT_EVENT_PAIRING_ADDED);\n\n\t\tCLIENT_DEBUG(context, \"Exporting accessory public key\");\n\t\tsize_t accessory_public_key_size = 0;\n\n\t\tcrypto_ed25519_export_public_key(&context->server->accessory_key, NULL,\n\t\t\t\t&accessory_public_key_size);\n\n\t\tbyte *accessory_public_key = (byte*) malloc(accessory_public_key_size);\n\t\tr = crypto_ed25519_export_public_key(&context->server->accessory_key, accessory_public_key,\n\t\t\t\t&accessory_public_key_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to export accessory public key (code %d)\", r);\n\n\t\t\tfree(accessory_public_key);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tsize_t accessory_id_size = sizeof(context->server->accessory_id) - 1;\n\t\tsize_t accessory_info_size = HKDF_HASH_SIZE + accessory_id_size + accessory_public_key_size;\n\t\tbyte *accessory_info = (byte*) malloc(accessory_info_size);\n\n\t\tCLIENT_DEBUG(context, \"Calculating AccessoryX\");\n\t\tsize_t accessory_x_size = accessory_info_size;\n\t\tconst char salt3[] = \"Pair-Setup-Accessory-Sign-Salt\";\n\t\tconst char info3[] = \"Pair-Setup-Accessory-Sign-Info\";\n\t\tr = crypto_srp_hkdf(context->server->pairing_context->srp, (byte*) salt3, sizeof(salt3) - 1,\n\t\t\t\t(byte*) info3, sizeof(info3) - 1, accessory_info, &accessory_x_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate AccessoryX (code %d)\", r);\n\n\t\t\tfree(accessory_info);\n\t\t\tfree(accessory_public_key);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tmemcpy(accessory_info + accessory_x_size, context->server->accessory_id, accessory_id_size);\n\t\tmemcpy(accessory_info + accessory_x_size + accessory_id_size, accessory_public_key,\n\t\t\t\taccessory_public_key_size);\n\n\t\tCLIENT_DEBUG(context, \"Generating accessory signature\");DEBUG_HEAP();\n\t\tsize_t accessory_signature_size = 0;\n\t\tcrypto_ed25519_sign(&context->server->accessory_key, accessory_info, accessory_info_size,\n\t\tNULL, &accessory_signature_size);\n\n\t\tbyte *accessory_signature = (byte*) malloc(accessory_signature_size);\n\t\tr = crypto_ed25519_sign(&context->server->accessory_key, accessory_info,\n\t\t\t\taccessory_info_size, accessory_signature, &accessory_signature_size);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate accessory signature (code %d)\", r);\n\n\t\t\tfree(accessory_signature);\n\t\t\tfree(accessory_public_key);\n\t\t\tfree(accessory_info);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tfree(accessory_info);\n\n\t\ttlv_values_t *response_message = tlv_new();\n\t\ttlv_add_value(response_message, TLVType_Identifier, (byte*) context->server->accessory_id,\n\t\t\t\taccessory_id_size);\n\t\ttlv_add_value(response_message, TLVType_PublicKey, accessory_public_key,\n\t\t\t\taccessory_public_key_size);\n\t\ttlv_add_value(response_message, TLVType_Signature, accessory_signature,\n\t\t\t\taccessory_signature_size);\n\n\t\tfree(accessory_public_key);\n\t\tfree(accessory_signature);\n\n\t\tsize_t response_data_size = 0;\n\t\tTLV_DEBUG(response_message);\n\n\t\ttlv_format(response_message, NULL, &response_data_size);\n\n\t\tbyte *response_data = (byte*) malloc(response_data_size);\n\t\tr = tlv_format(response_message, response_data, &response_data_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to format TLV response (code %d)\", r);\n\n\t\t\tfree(response_data);\n\t\t\ttlv_free(response_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_free(response_message);\n\n\t\tCLIENT_DEBUG(context, \"Encrypting response\");\n\t\tsize_t encrypted_response_data_size = 0;\n\t\tcrypto_chacha20poly1305_encrypt(shared_secret, (byte*) \"\\x0\\x0\\x0\\x0PS-Msg06\", NULL, 0,\n\t\t\t\tresponse_data, response_data_size,\n\t\t\t\tNULL, &encrypted_response_data_size);\n\n\t\tbyte *encrypted_response_data = (byte*) malloc(encrypted_response_data_size);\n\t\tr = crypto_chacha20poly1305_encrypt(shared_secret, (byte*) \"\\x0\\x0\\x0\\x0PS-Msg06\", NULL, 0,\n\t\t\t\tresponse_data, response_data_size, encrypted_response_data,\n\t\t\t\t&encrypted_response_data_size);\n\n\t\tfree(response_data);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to encrypt response data (code %d)\", r);\n\n\t\t\tfree(encrypted_response_data);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 6);\n\t\ttlv_add_value(response, TLVType_EncryptedData, encrypted_response_data,\n\t\t\t\tencrypted_response_data_size);\n\n\t\tfree(encrypted_response_data);\n\t\tsend_tlv_response(context, response);\n\n\t\tpairing_context_free(context->server->pairing_context);\n\t\tcontext->server->pairing_context = NULL;\n\t\tcontext->server->paired = true;\n\t\tCLIENT_INFO(context, \"Successfully paired\");\n\t\t//homekit_setup_mdns(context->server);\n\t\tcontext->step = HOMEKIT_CLIENT_STEP_PAIR_SETUP_3OF3;\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tCLIENT_ERROR(context, \"Unknown state: %d\",\n\t\t\t\ttlv_get_integer_value(message, TLVType_State, -1));\n\t}\n\t}\n\n\ttlv_free(message);\n\tDEBUG_TIME_END(\"pair_setup\");\n\n#ifdef HOMEKIT_OVERCLOCK_PAIR_SETUP\n    homekit_overclock_end();\n#endif\n}\n\nvoid homekit_server_on_pair_verify(client_context_t *context, const byte *data, size_t size) {\n\tDEBUG(\"HomeKit Pair Verify\");DEBUG_HEAP();\n\tDEBUG_TIME_BEGIN();\n\n\tcontext->step = HOMEKIT_CLIENT_STEP_NONE;\n\n#ifdef HOMEKIT_OVERCLOCK_PAIR_VERIFY\n    homekit_overclock_start();\n#endif\n\n\ttlv_values_t *message = tlv_new();\n\ttlv_parse(data, size, message);\n\n\tTLV_DEBUG(message);\n\tint r;\n\tswitch (tlv_get_integer_value(message, TLVType_State, -1)) {\n\tcase 1: {\n\t\tCLIENT_INFO(context, \"Pair Verify Step 1/2\"); CLIENT_DEBUG(context, \"Importing device Curve25519 public key\");\n\t\ttlv_t *tlv_device_public_key = tlv_get_value(message, TLVType_PublicKey);\n\t\tif (!tlv_device_public_key) {\n\t\t\tCLIENT_ERROR(context, \"Device Curve25519 public key not found\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\t\tcurve25519_key device_key;\n\t\tr = crypto_curve25519_init(&device_key);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to initialize device Curve25519 public key (code %d)\", r);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tr = crypto_curve25519_import_public(&device_key, tlv_device_public_key->value,\n\t\t\t\ttlv_device_public_key->size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to import device Curve25519 public key (code %d)\", r);\n\t\t\tcrypto_curve25519_done(&device_key);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t} CLIENT_DEBUG(context, \"Generating accessory Curve25519 key\");\n\t\tcurve25519_key my_key;\n\t\tr = crypto_curve25519_generate(&my_key);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate accessory Curve25519 key (code %d)\", r);\n\t\t\tcrypto_curve25519_done(&device_key);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t} CLIENT_DEBUG(context, \"Exporting accessory Curve25519 public key\");\n\t\tsize_t my_key_public_size = 0;\n\t\tcrypto_curve25519_export_public(&my_key, NULL, &my_key_public_size);\n\n\t\tbyte *my_key_public = (byte*) malloc(my_key_public_size);\n\t\tr = crypto_curve25519_export_public(&my_key, my_key_public, &my_key_public_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to export accessory Curve25519 public key (code %d)\", r);\n\t\t\tfree(my_key_public);\n\t\t\tcrypto_curve25519_done(&my_key);\n\t\t\tcrypto_curve25519_done(&device_key);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Generating Curve25519 shared secret\");\n\t\tsize_t shared_secret_size = 0;\n\t\tcrypto_curve25519_shared_secret(&my_key, &device_key, NULL, &shared_secret_size);\n\n\t\tbyte *shared_secret = (byte*) malloc(shared_secret_size);\n\t\tr = crypto_curve25519_shared_secret(&my_key, &device_key, shared_secret,\n\t\t\t\t&shared_secret_size);\n\t\tcrypto_curve25519_done(&my_key);\n\t\tcrypto_curve25519_done(&device_key);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate Curve25519 shared secret (code %d)\", r);\n\t\t\tfree(shared_secret);\n\t\t\tfree(my_key_public);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Generating signature\");\n\t\tsize_t accessory_id_size = sizeof(context->server->accessory_id) - 1;\n\t\tsize_t accessory_info_size = my_key_public_size + accessory_id_size\n\t\t\t\t+ tlv_device_public_key->size;\n\n\t\tbyte *accessory_info = (byte*) malloc(accessory_info_size);\n\t\tmemcpy(accessory_info, my_key_public, my_key_public_size);\n\t\tmemcpy(accessory_info + my_key_public_size, context->server->accessory_id,\n\t\t\t\taccessory_id_size);\n\t\tmemcpy(accessory_info + my_key_public_size + accessory_id_size,\n\t\t\t\ttlv_device_public_key->value, tlv_device_public_key->size);\n\n\t\tsize_t accessory_signature_size = 0;\n\t\tcrypto_ed25519_sign(&context->server->accessory_key, accessory_info, accessory_info_size,\n\t\tNULL, &accessory_signature_size);\n\n\t\tbyte *accessory_signature = (byte*) malloc(accessory_signature_size);\n\t\tr = crypto_ed25519_sign(&context->server->accessory_key, accessory_info,\n\t\t\t\taccessory_info_size, accessory_signature, &accessory_signature_size);\n\t\tfree(accessory_info);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate signature (code %d)\", r);\n\t\t\tfree(accessory_signature);\n\t\t\tfree(shared_secret);\n\t\t\tfree(my_key_public);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *sub_response = tlv_new();\n\t\ttlv_add_value(sub_response, TLVType_Identifier, (const byte*) context->server->accessory_id,\n\t\t\t\taccessory_id_size);\n\t\ttlv_add_value(sub_response, TLVType_Signature, accessory_signature,\n\t\t\t\taccessory_signature_size);\n\n\t\tfree(accessory_signature);\n\n\t\tsize_t sub_response_data_size = 0;\n\t\ttlv_format(sub_response, NULL, &sub_response_data_size);\n\n\t\tbyte *sub_response_data = (byte*) malloc(sub_response_data_size);\n\t\tr = tlv_format(sub_response, sub_response_data, &sub_response_data_size);\n\t\ttlv_free(sub_response);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to format sub-TLV message (code %d)\", r);\n\t\t\tfree(sub_response_data);\n\t\t\tfree(shared_secret);\n\t\t\tfree(my_key_public);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Generating proof\");\n\t\tsize_t session_key_size = 0;\n\t\tconst byte salt[] = \"Pair-Verify-Encrypt-Salt\";\n\t\tconst byte info[] = \"Pair-Verify-Encrypt-Info\";\n\t\tcrypto_hkdf(shared_secret, shared_secret_size, salt, sizeof(salt) - 1, info,\n\t\t\t\tsizeof(info) - 1,\n\t\t\t\tNULL, &session_key_size);\n\n\t\tbyte *session_key = (byte*) malloc(session_key_size);\n\t\tr = crypto_hkdf(shared_secret, shared_secret_size, salt, sizeof(salt) - 1, info,\n\t\t\t\tsizeof(info) - 1, session_key, &session_key_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to derive session key (code %d)\", r);\n\t\t\tfree(session_key);\n\t\t\tfree(sub_response_data);\n\t\t\tfree(shared_secret);\n\t\t\tfree(my_key_public);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Encrypting response\");\n\t\tsize_t encrypted_response_data_size = 0;\n\t\tcrypto_chacha20poly1305_encrypt(session_key, (byte*) \"\\x0\\x0\\x0\\x0PV-Msg02\", NULL, 0,\n\t\t\t\tsub_response_data, sub_response_data_size,\n\t\t\t\tNULL, &encrypted_response_data_size);\n\n\t\tbyte *encrypted_response_data = (byte*) malloc(encrypted_response_data_size);\n\t\tr = crypto_chacha20poly1305_encrypt(session_key, (byte*) \"\\x0\\x0\\x0\\x0PV-Msg02\", NULL, 0,\n\t\t\t\tsub_response_data, sub_response_data_size, encrypted_response_data,\n\t\t\t\t&encrypted_response_data_size);\n\t\tfree(sub_response_data);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to encrypt sub response data (code %d)\", r);\n\t\t\tfree(encrypted_response_data);\n\t\t\tfree(session_key);\n\t\t\tfree(shared_secret);\n\t\t\tfree(my_key_public);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 2);\n\t\ttlv_add_value(response, TLVType_PublicKey, my_key_public, my_key_public_size);\n\t\ttlv_add_value(response, TLVType_EncryptedData, encrypted_response_data,\n\t\t\t\tencrypted_response_data_size);\n\n\t\tfree(encrypted_response_data);\n\n\t\tsend_tlv_response(context, response);\n\n\t\tif (context->verify_context)\n\t\t\tpair_verify_context_free(context->verify_context);\n\n\t\tcontext->verify_context = pair_verify_context_new();\n\t\tcontext->verify_context->secret = shared_secret;\n\t\tcontext->verify_context->secret_size = shared_secret_size;\n\n\t\tcontext->verify_context->session_key = session_key;\n\t\tcontext->verify_context->session_key_size = session_key_size;\n\n\t\tcontext->verify_context->accessory_public_key = my_key_public;\n\t\tcontext->verify_context->accessory_public_key_size = my_key_public_size;\n\n\t\tcontext->verify_context->device_public_key = (byte*) malloc(tlv_device_public_key->size);\n\t\tmemcpy(context->verify_context->device_public_key, tlv_device_public_key->value,\n\t\t\t\ttlv_device_public_key->size);\n\t\tcontext->verify_context->device_public_key_size = tlv_device_public_key->size;\n\t\tcontext->step = HOMEKIT_CLIENT_STEP_PAIR_VERIFY_1OF2;\n\t\tbreak;\n\t}\n\tcase 3: {\n\t\tCLIENT_INFO(context, \"Pair Verify Step 2/2\");\n\n\t\tif (!context->verify_context) {\n\t\t\tCLIENT_ERROR(context, \"Failed to verify: no state 1 data\");\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_encrypted_data = tlv_get_value(message, TLVType_EncryptedData);\n\t\tif (!tlv_encrypted_data) {\n\t\t\tCLIENT_ERROR(context, \"Failed to verify: no encrypted data\");\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Decrypting payload\");\n\t\tsize_t decrypted_data_size = 0;\n\t\tcrypto_chacha20poly1305_decrypt(context->verify_context->session_key,\n\t\t\t\t(byte*) \"\\x0\\x0\\x0\\x0PV-Msg03\", NULL, 0, tlv_encrypted_data->value,\n\t\t\t\ttlv_encrypted_data->size,\n\t\t\t\tNULL, &decrypted_data_size);\n\n\t\tbyte *decrypted_data = (byte*) malloc(decrypted_data_size);\n\t\tr = crypto_chacha20poly1305_decrypt(context->verify_context->session_key,\n\t\t\t\t(byte*) \"\\x0\\x0\\x0\\x0PV-Msg03\", NULL, 0, tlv_encrypted_data->value,\n\t\t\t\ttlv_encrypted_data->size, decrypted_data, &decrypted_data_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to decrypt data (code %d)\", r);\n\t\t\tfree(decrypted_data);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *decrypted_message = tlv_new();\n\t\tr = tlv_parse(decrypted_data, decrypted_data_size, decrypted_message);\n\t\tfree(decrypted_data);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to parse decrypted TLV (code %d)\", r);\n\t\t\ttlv_free(decrypted_message);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_device_id = tlv_get_value(decrypted_message, TLVType_Identifier);\n\t\tif (!tlv_device_id) {\n\t\t\tCLIENT_ERROR(context, \"Invalid encrypted payload: no device identifier\");\n\t\t\ttlv_free(decrypted_message);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_device_signature = tlv_get_value(decrypted_message, TLVType_Signature);\n\t\tif (!tlv_device_signature) {\n\t\t\tCLIENT_ERROR(context, \"Invalid encrypted payload: no device identifier\");\n\t\t\ttlv_free(decrypted_message);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tchar *device_id = strndup((const char*) tlv_device_id->value, tlv_device_id->size);\n\t\tCLIENT_DEBUG(context, \"Searching pairing with %s\", device_id);\n\t\tpairing_t pairing;\n\t\tif (homekit_storage_find_pairing(device_id, &pairing)) {\n\t\t\tCLIENT_ERROR(context, \"No pairing for %s found\", device_id);\n\t\t\tfree(device_id);\n\t\t\ttlv_free(decrypted_message);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_INFO(context, \"Found pairing with %s\", device_id);\n\t\tfree(device_id);\n\n\t\tbyte permissions = pairing.permissions;\n\t\tint pairing_id = pairing.id;\n\n\t\tsize_t device_info_size = context->verify_context->device_public_key_size\n\t\t\t\t+ context->verify_context->accessory_public_key_size + tlv_device_id->size;\n\t\tbyte *device_info = (byte*) malloc(device_info_size);\n\t\tmemcpy(device_info, context->verify_context->device_public_key,\n\t\t\t\tcontext->verify_context->device_public_key_size);\n\t\tmemcpy(device_info + context->verify_context->device_public_key_size, tlv_device_id->value,\n\t\t\t\ttlv_device_id->size);\n\t\tmemcpy(device_info + context->verify_context->device_public_key_size + tlv_device_id->size,\n\t\t\t\tcontext->verify_context->accessory_public_key,\n\t\t\t\tcontext->verify_context->accessory_public_key_size);\n\n\t\tCLIENT_DEBUG(context, \"Verifying device signature\");\n\t\tr = crypto_ed25519_verify(&pairing.device_key, device_info, device_info_size,\n\t\t\t\ttlv_device_signature->value, tlv_device_signature->size);\n\t\tfree(device_info);\n\t\ttlv_free(decrypted_message);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to verify device signature (code %d)\", r);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tconst byte salt[] = \"Control-Salt\";\n\t\tsize_t read_key_size = sizeof(context->read_key);\n\t\tconst byte read_info[] = \"Control-Read-Encryption-Key\";\n\t\tr = crypto_hkdf(context->verify_context->secret, context->verify_context->secret_size, salt,\n\t\t\t\tsizeof(salt) - 1, read_info, sizeof(read_info) - 1, context->read_key,\n\t\t\t\t&read_key_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to derive read encryption key (code %d)\", r);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tsize_t write_key_size = sizeof(context->write_key);\n\t\tconst byte write_info[] = \"Control-Write-Encryption-Key\";\n\n\t\tr = crypto_hkdf(context->verify_context->secret, context->verify_context->secret_size, salt,\n\t\t\t\tsizeof(salt) - 1, write_info, sizeof(write_info) - 1, context->write_key,\n\t\t\t\t&write_key_size);\n\n\t\tpair_verify_context_free(context->verify_context);\n\t\tcontext->verify_context = NULL;\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to derive write encryption key (code %d)\", r);\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 4);\n\t\tsend_tlv_response(context, response);\n\n\t\tcontext->pairing_id = pairing_id;\n\t\tcontext->permissions = permissions;\n\t\tcontext->encrypted = true;\n\n\t\tHOMEKIT_NOTIFY_EVENT(context->server, HOMEKIT_EVENT_CLIENT_VERIFIED);\n\t\tCLIENT_INFO(context, \"Verification successful, secure session established\");\n\t\tcontext->step = HOMEKIT_CLIENT_STEP_PAIR_VERIFY_2OF2;\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tCLIENT_ERROR(context, \"Unknown state: %d\",\n\t\t\t\ttlv_get_integer_value(message, TLVType_State, -1));\n\t}\n\t}\n\ttlv_free(message);\n\tDEBUG_TIME_END(\"pair_verify\");\n\tINFO_HEAP();\n\n#ifdef HOMEKIT_OVERCLOCK_PAIR_VERIFY\n    homekit_overclock_end();\n#endif\n}\n\nvoid homekit_client_process(client_context_t *context);\n\nvoid homekit_server_on_get_accessories(client_context_t *context) {\n\tDEBUG_TIME_BEGIN();\n\tCLIENT_INFO(context, \"Get Accessories\");DEBUG_HEAP();\n\tclient_send_P(context, json_200_response_headers_progmem);\n\n\tCLIENT_DEBUG(context, \"Get Accessories, start send json body\");\n\n\tjson_stream *json = json_new(HOMEKIT_JSONBUFFER_SIZE, client_send_chunk, context);\n\tjson_object_start(json);\n\tjson_string(json, \"accessories\");\n\tjson_array_start(json);\n\n\tfor (homekit_accessory_t **accessory_it = context->server->config->accessories; *accessory_it;\n\t\t\taccessory_it++) {\n\n\t\thomekit_accessory_t *accessory = *accessory_it;\n\n\t\tjson_object_start(json);\n\n\t\tjson_string(json, \"aid\");\n\t\tjson_uint32(json, accessory->id);\n\t\tjson_string(json, \"services\");\n\t\tjson_array_start(json);\n\n\t\tfor (homekit_service_t **service_it = accessory->services; *service_it; service_it++) {\n\t\t\thomekit_service_t *service = *service_it;\n\n\t\t\tjson_object_start(json);\n\n\t\t\tjson_string(json, \"iid\");\n\t\t\tjson_uint32(json, service->id);\n\t\t\tjson_string(json, \"type\");\n\t\t\tjson_string(json, service->type);\n\t\t\tjson_string(json, \"hidden\");\n\t\t\tjson_boolean(json, service->hidden);\n\t\t\tjson_string(json, \"primary\");\n\t\t\tjson_boolean(json, service->primary);\n\t\t\tif (service->linked) {\n\t\t\t\tjson_string(json, \"linked\");\n\t\t\t\tjson_array_start(json);\n\t\t\t\tfor (homekit_service_t **linked = service->linked; *linked; linked++) {\n\t\t\t\t\tjson_uint32(json, (*linked)->id);\n\t\t\t\t}\n\t\t\t\tjson_array_end(json);\n\t\t\t}\n\n\t\t\tjson_string(json, \"characteristics\");\n\t\t\tjson_array_start(json);\n\n\t\t\tfor (homekit_characteristic_t **ch_it = service->characteristics; *ch_it; ch_it++) {\n\t\t\t\thomekit_characteristic_t *ch = *ch_it;\n\n\t\t\t\tjson_object_start(json);\n\t\t\t\twrite_characteristic_json(json, context, ch,\n\t\t\t\t\t\t(characteristic_format_t) (characteristic_format_type\n\t\t\t\t\t\t\t\t| characteristic_format_meta | characteristic_format_perms\n\t\t\t\t\t\t\t\t| characteristic_format_events),\n\t\t\t\t\t\tNULL);\n\t\t\t\tjson_object_end(json);\n\t\t\t}\n\n\t\t\tjson_array_end(json);\n\t\t\tjson_object_end(json); // service\n\t\t}\n\n\t\tjson_array_end(json);\n\t\tjson_object_end(json); // accessory\n\t}\n\n\tjson_array_end(json);\n\tjson_object_end(json); // response\n\n\tjson_flush(json);\n\tjson_free(json);\n\n\tclient_send_chunk(NULL, 0, context);\n\tDEBUG_TIME_END(\"get_accessories\")\n}\n\nbool bool_endpoint_param(const char *name, client_context_t *context) {\n\tquery_param_t *param = query_params_find(context->endpoint_params, name);\n\treturn param && param->value && !strcmp(param->value, \"1\");\n}\n\nvoid write_characteristic_error(json_stream *json, uint32_t aid, uint32_t iid, int status) {\n\tjson_object_start(json);\n\tjson_string(json, \"aid\");\n\tjson_uint32(json, aid);\n\tjson_string(json, \"iid\");\n\tjson_uint32(json, iid);\n\tjson_string(json, \"status\");\n\tjson_uint8(json, status);\n\tjson_object_end(json);\n}\n\nvoid homekit_server_on_get_characteristics(client_context_t *context) {\n\tCLIENT_INFO(context, \"Get Characteristics\");DEBUG_HEAP();\n\n\tquery_param_t *qp = context->endpoint_params;\n\twhile (qp) {\n\t\tCLIENT_DEBUG(context, \"Query paramter %s = %s\", qp->name, qp->value);\n\t\tqp = qp->next;\n\t}\n\n\tquery_param_t *id_param = query_params_find(context->endpoint_params, \"id\");\n\tif (!id_param) {\n\t\tCLIENT_ERROR(context, \"Invalid get characteristics request: missing ID parameter\");\n\t\tsend_json_error_response(context, 400, HAPStatus_InvalidValue);\n\t\treturn;\n\t}\n\n\tcharacteristic_format_t format = (characteristic_format_t) 0;\n\tif (bool_endpoint_param(\"meta\", context))\n\t\tformat = (characteristic_format_t) (format | characteristic_format_meta);\n\n\tif (bool_endpoint_param(\"perms\", context))\n\t\tformat = (characteristic_format_t) (format | characteristic_format_perms);\n\n\tif (bool_endpoint_param(\"type\", context))\n\t\tformat = (characteristic_format_t) (format | characteristic_format_type);\n\n\tif (bool_endpoint_param(\"ev\", context))\n\t\tformat = (characteristic_format_t) (format | characteristic_format_events);\n\n\tbool success = true;\n\n\tchar *id = strdup(id_param->value);\n\tchar *ch_id;\n\tchar *_id = id;\n\twhile ((ch_id = strsep(&_id, \",\"))) {\n\t\tchar *dot = strstr(ch_id, \".\");\n\t\tif (!dot) {\n\t\t\tsend_json_error_response(context, 400, HAPStatus_InvalidValue);\n\t\t\tfree(id);\n\t\t\treturn;\n\t\t}\n\n\t\t*dot = 0;\n\t\tuint32_t aid = atoi(ch_id);\n\t\tuint32_t iid = atoi(dot + 1);\n\n\t\tCLIENT_DEBUG(context, \"Requested characteristic info for %u.%u\", aid, iid);\n\t\thomekit_characteristic_t *ch = homekit_characteristic_by_aid_and_iid(\n\t\t\t\tcontext->server->config->accessories, aid, iid);\n\t\tif (!ch) {\n\t\t\tsuccess = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!(ch->permissions & homekit_permissions_paired_read)) {\n\t\t\tsuccess = false;\n\t\t\tcontinue;\n\t\t}\n\t}\n\n\tfree(id);\n\tid = strdup(id_param->value);\n\n\tif (success) {\n\t\tclient_send_P(context, json_200_response_headers_progmem);\n\t} else {\n\t\tclient_send_P(context, json_207_response_headers_progmem);\n\t}\n\n\tjson_stream *json = json_new(HOMEKIT_JSONBUFFER_SIZE, client_send_chunk, context);\n\tjson_object_start(json);\n\tjson_string(json, \"characteristics\");\n\tjson_array_start(json);\n\n\t_id = id;\n\twhile ((ch_id = strsep(&_id, \",\"))) {\n\t\tchar *dot = strstr(ch_id, \".\");\n\t\t*dot = 0;\n\t\tuint32_t aid = atoi(ch_id);\n\t\tuint32_t iid = atoi(dot + 1);\n\n\t\tCLIENT_DEBUG(context, \"Requested characteristic info for %d.%d\", aid, iid);\n\t\thomekit_characteristic_t *ch = homekit_characteristic_by_aid_and_iid(\n\t\t\t\tcontext->server->config->accessories, aid, iid);\n\t\tif (!ch) {\n\t\t\twrite_characteristic_error(json, aid, iid, HAPStatus_NoResource);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!(ch->permissions & homekit_permissions_paired_read)) {\n\t\t\twrite_characteristic_error(json, aid, iid, HAPStatus_WriteOnly);\n\t\t\tcontinue;\n\t\t}\n\n\t\tjson_object_start(json);\n\t\twrite_characteristic_json(json, context, ch, format, NULL);\n\t\tif (!success) {\n\t\t\tjson_string(json, \"status\");\n\t\t\tjson_uint8(json, HAPStatus_Success);\n\t\t}\n\t\tjson_object_end(json);\n\t}\n\n\tjson_array_end(json);\n\tjson_object_end(json); // response\n\n\tjson_flush(json);\n\tjson_free(json);\n\n\tclient_send_chunk(NULL, 0, context);\n\n\tfree(id);\n}\n\nHAPStatus process_characteristics_update(const cJSON *j_ch, client_context_t *context) {\n\tcJSON *j_aid = cJSON_GetObjectItem(j_ch, \"aid\");\n\tif (!j_aid) {\n\t\tCLIENT_ERROR(context, \"Failed to process request: no \\\"aid\\\" field\");\n\t\treturn HAPStatus_NoResource;\n\t}\n\tif (j_aid->type != cJSON_Number) {\n\t\tCLIENT_ERROR(context, \"Failed to process request: \\\"aid\\\" field is not a number\");\n\t\treturn HAPStatus_NoResource;\n\t}\n\n\tcJSON *j_iid = cJSON_GetObjectItem(j_ch, \"iid\");\n\tif (!j_iid) {\n\t\tCLIENT_ERROR(context, \"Failed to process request: no \\\"iid\\\" field\");\n\t\treturn HAPStatus_NoResource;\n\t}\n\tif (j_iid->type != cJSON_Number) {\n\t\tCLIENT_ERROR(context, \"Failed to process request: \\\"iid\\\" field is not a number\");\n\t\treturn HAPStatus_NoResource;\n\t}\n\n\tuint32_t aid = (uint32_t) j_aid->valuedouble; //j_aid->valueint;\n\tuint32_t iid = (uint32_t) j_iid->valuedouble; //j_iid->valueint;\n\n\thomekit_characteristic_t *ch = homekit_characteristic_by_aid_and_iid(\n\t\t\tcontext->server->config->accessories, aid, iid);\n\tif (!ch) {\n\t\tCLIENT_ERROR(context,\n\t\t\t\t\"Failed to process request to update %u.%u: \" \"no such characteristic\", aid, iid);\n\t\treturn HAPStatus_NoResource;\n\t}\n\n\tcJSON *j_value = cJSON_GetObjectItem(j_ch, \"value\");\n\tif (j_value) {\n\t\thomekit_value_t h_value = HOMEKIT_NULL_CPP();\n\n\t\tif (!(ch->permissions & homekit_permissions_paired_write)) {\n\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: no write permission\", aid, iid);\n\t\t\treturn HAPStatus_ReadOnly;\n\t\t}\n\n\t\tswitch (ch->format) {\n\t\tcase homekit_format_bool: {\n\t\t\tbool value = false;\n\t\t\tif (j_value->type == cJSON_True) {\n\t\t\t\tvalue = true;\n\t\t\t} else if (j_value->type == cJSON_False) {\n\t\t\t\tvalue = false;\n\t\t\t} else if (j_value->type == cJSON_Number\n\t\t\t\t\t&& (j_value->valueint == 0 || j_value->valueint == 1)) {\n\t\t\t\tvalue = j_value->valueint == 1;\n\t\t\t} else {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not a boolean or 0/1\", aid,\n\t\t\t\t\t\tiid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tCLIENT_DEBUG(context, \"Updating characteristic %d.%d with boolean %s\", aid, iid, value ? \"true\" : \"false\");\n\n\t\t\th_value = HOMEKIT_BOOL_CPP(value);\n\t\t\tif (ch->setter_ex) {\n\t\t\t\tch->setter_ex(ch, h_value);\n\t\t\t} else {\n\t\t\t\tch->value = h_value;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase homekit_format_uint8:\n\t\tcase homekit_format_uint16:\n\t\tcase homekit_format_uint32:\n\t\tcase homekit_format_uint64:\n\t\tcase homekit_format_int: {\n\t\t\t// We accept boolean values here in order to fix a bug in HomeKit. HomeKit sometimes sends a boolean instead of an integer of value 0 or 1.\n\t\t\tif (j_value->type != cJSON_Number && j_value->type != cJSON_False\n\t\t\t\t\t&& j_value->type != cJSON_True) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not a number\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tdouble min_value = 0;\n\t\t\tdouble max_value = 0;\n\n\t\t\tswitch (ch->format) {\n\t\t\tcase homekit_format_uint8: {\n\t\t\t\tmin_value = 0;\n\t\t\t\tmax_value = 255;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint16: {\n\t\t\t\tmin_value = 0;\n\t\t\t\tmax_value = 65535;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint32: {\n\t\t\t\tmin_value = 0;\n\t\t\t\tmax_value = 4294967295;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint64: {\n\t\t\t\tmin_value = 0;\n\t\t\t\tmax_value = 18446744073709551615ULL;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_int: {\n\t\t\t\tmin_value = -2147483648;\n\t\t\t\tmax_value = 2147483647;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// Impossible, keeping to make compiler happy\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t}\n\n\t\t\tif (ch->min_value)\n\t\t\t\tmin_value = *ch->min_value;\n\t\t\tif (ch->max_value)\n\t\t\t\tmax_value = *ch->max_value;\n\n\t\t\tdouble value = j_value->valuedouble;\n\t\t\tif (value < min_value || value > max_value) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value %g is not in range %g..%g\",\n\t\t\t\t\t\taid, iid, value, min_value, max_value);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tif (ch->valid_values.count) {\n\t\t\t\tbool matches = false;\n\t\t\t\tint v = (int) value;\n\t\t\t\tfor (int i = 0; i < ch->valid_values.count; i++) {\n\t\t\t\t\tif (v == ch->valid_values.values[i]) {\n\t\t\t\t\t\tmatches = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!matches) {\n\t\t\t\t\tCLIENT_ERROR(context,\n\t\t\t\t\t\t\t\"Failed to update %d.%d: value is not one of valid values\", aid, iid);\n\t\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (ch->valid_values_ranges.count) {\n\t\t\t\tbool matches = false;\n\t\t\t\tfor (int i = 0; i < ch->valid_values_ranges.count; i++) {\n\t\t\t\t\tif (value >= ch->valid_values_ranges.ranges[i].start\n\t\t\t\t\t\t\t&& value <= ch->valid_values_ranges.ranges[i].end) {\n\t\t\t\t\t\tmatches = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!matches) {\n\t\t\t\t\tCLIENT_ERROR(context,\n\t\t\t\t\t\t\t\"Failed to update %d.%d: value is not in valid values range\", aid, iid);\n\t\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tCLIENT_DEBUG(context, \"Updating characteristic %d.%d with integer %g\", aid, iid, value);\n\n\t\t\tswitch (ch->format) {\n\t\t\tcase homekit_format_uint8:\n\t\t\t\th_value = HOMEKIT_UINT8_CPP(value);\n\t\t\t\tbreak;\n\t\t\tcase homekit_format_uint16:\n\t\t\t\th_value = HOMEKIT_UINT16_CPP(value);\n\t\t\t\tbreak;\n\t\t\tcase homekit_format_uint32:\n\t\t\t\th_value = HOMEKIT_UINT32_CPP(value);\n\t\t\t\tbreak;\n\t\t\tcase homekit_format_uint64:\n\t\t\t\th_value = HOMEKIT_UINT64_CPP(value);\n\t\t\t\tbreak;\n\t\t\tcase homekit_format_int:\n\t\t\t\th_value = HOMEKIT_INT_CPP(value);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tCLIENT_ERROR(context, \"Unexpected format when updating numeric value: %d\",\n\t\t\t\t\t\tch->format)\n\t\t\t\t;\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tif (ch->setter_ex) {\n\t\t\t\tch->setter_ex(ch, h_value);\n\t\t\t} else {\n\t\t\t\tch->value = h_value;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase homekit_format_float: {\n\t\t\tif (j_value->type != cJSON_Number) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not a number\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tfloat value = j_value->valuedouble;\n\t\t\tif ((ch->min_value && value < *ch->min_value)\n\t\t\t\t\t|| (ch->max_value && value > *ch->max_value)) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not in range\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tCLIENT_DEBUG(context, \"Updating characteristic %d.%d with %g\", aid, iid, value);\n\n\t\t\th_value = HOMEKIT_FLOAT_CPP(value);\n\t\t\tif (ch->setter_ex) {\n\t\t\t\tch->setter_ex(ch, h_value);\n\t\t\t} else {\n\t\t\t\tch->value = h_value;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase homekit_format_string: {\n\t\t\tif (j_value->type != cJSON_String) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not a string\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tint max_len = (ch->max_len) ? *ch->max_len : 64;\n\n\t\t\tchar *value = j_value->valuestring;\n\t\t\tif (strlen(value) > max_len) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is too long\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tCLIENT_DEBUG(context, \"Updating characteristic %d.%d with \\\"%s\\\"\", aid, iid, value);\n\n\t\t\th_value = HOMEKIT_STRING_CPP(value);\n\t\t\tif (ch->setter_ex) {\n\t\t\t\tch->setter_ex(ch, h_value);\n\t\t\t} else {\n\t\t\t\thomekit_value_destruct(&ch->value);\n\t\t\t\thomekit_value_copy(&ch->value, &h_value);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase homekit_format_tlv: {\n\t\t\tif (j_value->type != cJSON_String) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not a string\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tint max_len = (ch->max_len) ? *ch->max_len : 256;\n\n\t\t\tchar *value = j_value->valuestring;\n\t\t\tsize_t value_len = strlen(value);\n\t\t\tif (value_len > max_len) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is too long\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tsize_t tlv_size = base64_decoded_size((unsigned char*) value, value_len);\n\t\t\tbyte *tlv_data = (byte*) malloc(tlv_size);\n\t\t\tif (base64_decode_((byte*) value, value_len, tlv_data) < 0) {\n\t\t\t\tfree(tlv_data);\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: error Base64 decoding\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\ttlv_values_t *tlv_values = tlv_new();\n\t\t\tint r = tlv_parse(tlv_data, tlv_size, tlv_values);\n\t\t\tfree(tlv_data);\n\n\t\t\tif (r) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: error parsing TLV\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tCLIENT_DEBUG(context, \"Updating characteristic %d.%d with TLV:\", aid, iid);\n\t\t\tfor (tlv_t *t = tlv_values->head; t; t = t->next) {\n\t\t\t\tchar *escaped_payload = binary_to_string(t->value, t->size);\n\t\t\t\tCLIENT_DEBUG(context, \"  Type %d value (%d bytes): %s\", t->type, t->size, escaped_payload);\n\t\t\t\tfree(escaped_payload);\n\t\t\t}\n\n\t\t\th_value = HOMEKIT_TLV_CPP(tlv_values);\n\t\t\tif (ch->setter_ex) {\n\t\t\t\tch->setter_ex(ch, h_value);\n\t\t\t} else {\n\t\t\t\thomekit_value_destruct(&ch->value);\n\t\t\t\thomekit_value_copy(&ch->value, &h_value);\n\t\t\t}\n\n\t\t\ttlv_free(tlv_values);\n\t\t\tbreak;\n\t\t}\n\t\tcase homekit_format_data: {\n\t\t\tif (j_value->type != cJSON_String) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not a string\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\t// Default max data len = 2,097,152 but that does not make sense\n\t\t\t// for this accessory\n\t\t\tint max_len = (ch->max_data_len) ? *ch->max_data_len : 4096;\n\n\t\t\tchar *value = j_value->valuestring;\n\t\t\tsize_t value_len = strlen(value);\n\t\t\tif (value_len > max_len) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is too long\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tsize_t data_size = base64_decoded_size((unsigned char*) value, value_len);\n\t\t\tbyte *data = (byte*) malloc(data_size);\n\t\t\tif (base64_decode_((byte*) value, value_len, data) < 0) {\n\t\t\t\tfree(data);\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: error Base64 decoding\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tCLIENT_DEBUG(context, \"Updating characteristic %d.%d with Data:\", aid, iid);\n\n\t\t\th_value = HOMEKIT_DATA_CPP(data, data_size);\n\t\t\tif (ch->setter_ex) {\n\t\t\t\tch->setter_ex(ch, h_value);\n\t\t\t} else {\n\t\t\t\thomekit_value_destruct(&ch->value);\n\t\t\t\thomekit_value_copy(&ch->value, &h_value);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\t}\n\n\t\tif (!h_value.is_null) {\n\t\t\tcontext->current_characteristic = ch;\n\t\t\tcontext->current_value = &h_value;\n\n\t\t\thomekit_characteristic_notify(ch, h_value);\n\n\t\t\tcontext->current_characteristic = NULL;\n\t\t\tcontext->current_value = NULL;\n\t\t}\n\t}\n\n\tcJSON *j_events = cJSON_GetObjectItem(j_ch, \"ev\");\n\tif (j_events) {\n\t\tif (!(ch->permissions && homekit_permissions_notify)) {\n\t\t\tCLIENT_ERROR(context,\n\t\t\t\t\t\"Failed to set notification state for %d.%d: \" \"notifications are not supported\",\n\t\t\t\t\taid, iid);\n\t\t\treturn HAPStatus_NotificationsUnsupported;\n\t\t}\n\n\t\tif ((j_events->type != cJSON_True) && (j_events->type != cJSON_False)) {\n\t\t\tCLIENT_ERROR(context,\n\t\t\t\t\t\"Failed to set notification state for %d.%d: \" \"invalid state value\", aid, iid);\n\t\t}\n\n\t\tif (j_events->type == cJSON_True) {\n\t\t\thomekit_characteristic_add_notify_callback(ch, client_notify_characteristic, context);\n\t\t} else {\n\t\t\thomekit_characteristic_remove_notify_callback(ch, client_notify_characteristic,\n\t\t\t\t\tcontext);\n\t\t}\n\t}\n\n\treturn HAPStatus_Success;\n}\n\nvoid homekit_server_on_update_characteristics(client_context_t *context, const byte *data,\n\t\tsize_t size) {\n\tDEBUG_TIME_BEGIN();\n\tCLIENT_INFO(context, \"Update Characteristics\");DEBUG_HEAP();\n\n\tchar *data1 = strndup((char*) data, size);\n\tcJSON *json = cJSON_Parse(data1);\n\tfree(data1);\n\n\tif (!json) {\n\t\tCLIENT_ERROR(context, \"Failed to parse request JSON\");\n\t\tsend_json_error_response(context, 400, HAPStatus_InvalidValue);\n\t\treturn;\n\t}\n\n\tcJSON *characteristics = cJSON_GetObjectItem(json, \"characteristics\");\n\tif (!characteristics) {\n\t\tCLIENT_ERROR(context, \"Failed to parse request: no \\\"characteristics\\\" field\");\n\t\tcJSON_Delete(json);\n\t\tsend_json_error_response(context, 400, HAPStatus_InvalidValue);\n\t\treturn;\n\t}\n\tif (characteristics->type != cJSON_Array) {\n\t\tCLIENT_ERROR(context, \"Failed to parse request: \\\"characteristics\\\" field is not an list\");\n\t\tcJSON_Delete(json);\n\t\tsend_json_error_response(context, 400, HAPStatus_InvalidValue);\n\t\treturn;\n\t}\n\n\tHAPStatus *statuses = (HAPStatus*) malloc(\n\t\t\tsizeof(HAPStatus) * cJSON_GetArraySize(characteristics));\n\tbool has_errors = false;\n\n\tfor (int i = 0; i < cJSON_GetArraySize(characteristics); i++) {\n\n\t\tcJSON *j_ch = cJSON_GetArrayItem(characteristics, i);\n\n\t\tchar *s = cJSON_Print(j_ch);\n\t\tCLIENT_DEBUG(context, \"Processing element %s\", s);\n\t\tfree(s);\n\n\t\tstatuses[i] = process_characteristics_update(j_ch, context);\n\n\t\tif (statuses[i] != HAPStatus_Success)\n\t\t\thas_errors = true;\n\t}\n\n\tif (!has_errors) {\n\t\tCLIENT_DEBUG(context, \"There were no processing errors, sending No Content response\");\n\n\t\tsend_204_response(context);\n\t} else {\n\t\tCLIENT_DEBUG(context, \"There were processing errors, sending Multi-Status response\");\n\t\tclient_send_P(context, json_207_response_headers_progmem);\n\n\t\tjson_stream *json1 = json_new(HOMEKIT_JSONBUFFER_SIZE, client_send_chunk, context);\n\t\tjson_object_start(json1);\n\t\tjson_string(json1, \"characteristics\");\n\t\tjson_array_start(json1);\n\n\t\tfor (int i = 0; i < cJSON_GetArraySize(characteristics); i++) {\n\n\t\t\tcJSON *j_ch = cJSON_GetArrayItem(characteristics, i);\n\n\t\t\tjson_object_start(json1);\n\t\t\tjson_string(json1, \"aid\");\n\t\t\tjson_uint32(json1, cJSON_GetObjectItem(j_ch, \"aid\")->valuedouble);\t\t//->valueint);\n\t\t\tjson_string(json1, \"iid\");\n\t\t\tjson_uint32(json1, cJSON_GetObjectItem(j_ch, \"iid\")->valuedouble);\t\t//->valueint);\n\t\t\tjson_string(json1, \"status\");\n\t\t\tjson_uint8(json1, statuses[i]);\n\t\t\tjson_object_end(json1);\n\t\t}\n\n\t\tjson_array_end(json1);\n\t\tjson_object_end(json1); // response\n\n\t\tjson_flush(json1);\n\t\tjson_free(json1);\n\n\t\tclient_send_chunk(NULL, 0, context);\n\t}\n\n\tfree(statuses);\n\tcJSON_Delete(json);\n\tDEBUG_TIME_END(\"update_characteristics\");\n}\n\nvoid homekit_server_on_pairings(client_context_t *context, const byte *data, size_t size) {\n\tDEBUG(\"HomeKit Pairings\");DEBUG_HEAP();\n\n\t//context->step = HOMEKIT_CLIENT_STEP_PAIRINGS;\n\ttlv_values_t *message = tlv_new();\n\ttlv_parse(data, size, message);\n\n\tTLV_DEBUG(message);\n\n\tint r;\n\n\tif (tlv_get_integer_value(message, TLVType_State, -1) != 1) {\n\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\ttlv_free(message);\n\t\treturn;\n\t}\n\n\tswitch (tlv_get_integer_value(message, TLVType_Method, -1)) {\n\tcase TLVMethod_AddPairing: {\n\t\tCLIENT_INFO(context, \"Add Pairing\");\n\n\t\tif (!(context->permissions & pairing_permissions_admin)) {\n\t\t\tCLIENT_ERROR(context, \"Refusing to add pairing to non-admin controller\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_device_identifier = tlv_get_value(message, TLVType_Identifier);\n\t\tif (!tlv_device_identifier) {\n\t\t\tCLIENT_ERROR(context, \"Invalid add pairing request: no device identifier\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\t\ttlv_t *tlv_device_public_key = tlv_get_value(message, TLVType_PublicKey);\n\t\tif (!tlv_device_public_key) {\n\t\t\tCLIENT_ERROR(context, \"Invalid add pairing request: no device public key\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\t\tint device_permissions = tlv_get_integer_value(message, TLVType_Permissions, -1);\n\t\tif (device_permissions == -1) {\n\t\t\tCLIENT_ERROR(context, \"Invalid add pairing request: no device permissions\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\ted25519_key device_key;\n\t\tcrypto_ed25519_init(&device_key);\n\t\tr = crypto_ed25519_import_public_key(&device_key, tlv_device_public_key->value,\n\t\t\t\ttlv_device_public_key->size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to import device public key\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tchar *device_identifier = strndup((const char*) tlv_device_identifier->value,\n\t\t\t\ttlv_device_identifier->size);\n\n\t\tpairing_t pairing;\n\t\tif (!homekit_storage_find_pairing(device_identifier, &pairing)) {\n\t\t\tsize_t pairing_public_key_size = 0;\n\t\t\tcrypto_ed25519_export_public_key(&pairing.device_key, NULL, &pairing_public_key_size);\n\n\t\t\tbyte *pairing_public_key = (byte*) malloc(pairing_public_key_size);\n\t\t\tr = crypto_ed25519_export_public_key(&pairing.device_key, pairing_public_key,\n\t\t\t\t\t&pairing_public_key_size);\n\t\t\tif (r) {\n\t\t\t\tCLIENT_ERROR(context,\n\t\t\t\t\t\t\"Failed to add pairing: error exporting pairing public key (code %d)\", r);\n\t\t\t\tfree(pairing_public_key);\n\t\t\t\tfree(device_identifier);\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t}\n\n\t\t\tif (pairing_public_key_size != tlv_device_public_key->size\n\t\t\t\t\t|| memcmp(tlv_device_public_key->value, pairing_public_key,\n\t\t\t\t\t\t\tpairing_public_key_size)) {\n\t\t\t\tCLIENT_ERROR(context,\n\t\t\t\t\t\t\"Failed to add pairing: pairing public key differs from given one\");\n\t\t\t\tfree(pairing_public_key);\n\t\t\t\tfree(device_identifier);\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t}\n\n\t\t\tfree(pairing_public_key);\n\n\t\t\tr = homekit_storage_update_pairing(device_identifier, device_permissions);\n\t\t\tif (r) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to add pairing: storage error (code %d)\", r);\n\t\t\t\tfree(device_identifier);\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tINFO(\"Updated pairing with %s\", device_identifier);\n\t\t} else {\n\t\t\tif (!homekit_storage_can_add_pairing()) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to add pairing: max peers\");\n\t\t\t\tfree(device_identifier);\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_MaxPeers);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tr = homekit_storage_add_pairing(device_identifier, &device_key, device_permissions);\n\t\t\tif (r) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to add pairing: storage error (code %d)\", r);\n\t\t\t\tfree(device_identifier);\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tINFO(\"Added pairing with %s\", device_identifier);\n\n\t\t\tHOMEKIT_NOTIFY_EVENT(context->server, HOMEKIT_EVENT_PAIRING_ADDED);\n\t\t}\n\n\t\tfree(device_identifier);\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 2);\n\n\t\tsend_tlv_response(context, response);\n\n\t\tbreak;\n\t}\n\tcase TLVMethod_RemovePairing: {\n\t\tCLIENT_INFO(context, \"Remove Pairing\");\n\n\t\tif (!(context->permissions & pairing_permissions_admin)) {\n\t\t\tCLIENT_ERROR(context, \"Refusing to remove pairing to non-admin controller\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_device_identifier = tlv_get_value(message, TLVType_Identifier);\n\t\tif (!tlv_device_identifier) {\n\t\t\tCLIENT_ERROR(context, \"Invalid remove pairing request: no device identifier\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tchar *device_identifier = strndup((const char*) tlv_device_identifier->value,\n\t\t\t\ttlv_device_identifier->size);\n\n\t\tpairing_t pairing;\n\t\tif (!homekit_storage_find_pairing(device_identifier, &pairing)) {\n\t\t\tbool is_admin = pairing.permissions & pairing_permissions_admin;\n\n\t\t\tr = homekit_storage_remove_pairing(device_identifier);\n\t\t\tif (r) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to remove pairing: storage error (code %d)\", r);\n\t\t\t\tfree(device_identifier);\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tINFO(\"Removed pairing with %s\", device_identifier);\n\n\t\t\tHOMEKIT_NOTIFY_EVENT(context->server, HOMEKIT_EVENT_PAIRING_REMOVED);\n\n\t\t\tclient_context_t *c = context->server->clients;\n\t\t\twhile (c) {\n\t\t\t\tif (c->pairing_id == pairing.id)\n\t\t\t\t\tc->disconnect = true;\n\t\t\t\tc = c->next;\n\t\t\t}\n\n\t\t\tif (is_admin) {\n\t\t\t\t// Removed pairing was admin,\n\t\t\t\t// check if there any other admins left.\n\t\t\t\t// If no admins left, enable pairing again\n\t\t\t\tbool admin_found = false;\n\n\t\t\t\tpairing_iterator_t pairing_it;\n\t\t\t\thomekit_storage_pairing_iterator_init(&pairing_it);\n\t\t\t\twhile ((!homekit_storage_next_pairing(&pairing_it, &pairing))) {\n\t\t\t\t\tif (pairing.permissions & pairing_permissions_admin) {\n\t\t\t\t\t\tadmin_found = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\thomekit_storage_pairing_iterator_done(&pairing_it);\n\n\t\t\t\tif (!admin_found) {\n\t\t\t\t\t// No admins left, enable pairing again\n\t\t\t\t\tINFO(\"Last admin pairing was removed, enabling pair setup\");\n\t\t\t\t\tcontext->server->paired = false;\n\t\t\t\t\thomekit_on_paired_status_changed();\n\t\t\t\t\t//homekit_setup_mdns(context->server);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfree(device_identifier);\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 2);\n\t\tsend_tlv_response(context, response);\n\n\t\tbreak;\n\t}\n\tcase TLVMethod_ListPairings: {\n\t\tCLIENT_INFO(context, \"List Pairings\");\n\n\t\tif (!(context->permissions & pairing_permissions_admin)) {\n\t\t\tCLIENT_INFO(context, \"Refusing to list pairings to non-admin controller\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 2);\n\n\t\tbool first = true;\n\n\t\tpairing_iterator_t it;\n\t\thomekit_storage_pairing_iterator_init(&it);\n\n\t\tpairing_t pairing;\n\n\t\tbyte public_key[32];\n\n\t\twhile (!homekit_storage_next_pairing(&it, &pairing)) {\n\t\t\tif (!first) {\n\t\t\t\ttlv_add_value(response, TLVType_Separator, NULL, 0);\n\t\t\t}\n\t\t\tsize_t public_key_size = sizeof(public_key);\n\t\t\tr = crypto_ed25519_export_public_key(&pairing.device_key, public_key, &public_key_size);\n\n\t\t\ttlv_add_string_value(response, TLVType_Identifier, pairing.device_id);\n\t\t\ttlv_add_value(response, TLVType_PublicKey, public_key, public_key_size);\n\t\t\ttlv_add_integer_value(response, TLVType_Permissions, 1, pairing.permissions);\n\n\t\t\tfirst = false;\n\t\t}\n\t\thomekit_storage_pairing_iterator_done(&it);\n\n\t\tsend_tlv_response(context, response);\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\tbreak;\n\t}\n\t}\n\n\ttlv_free(message);\n}\n\nvoid homekit_server_on_reset(client_context_t *context) {\n\tINFO(\"Reset\");\n\n\thomekit_server_reset();\n\tsend_204_response(context);\n\n\t//vTaskDelay(3000 / portTICK_PERIOD_MS);\n\n\thomekit_system_restart();\n}\n\nvoid homekit_server_on_resource(client_context_t *context) {\n\tCLIENT_INFO(context, \"Resource\");DEBUG_HEAP();\n\n\tif (!context->server->config->on_resource) {\n\t\tsend_404_response(context);\n\t\treturn;\n\t}\n\n\tcontext->server->config->on_resource(context->body, context->body_length);\n}\n//=============================================\n// parse data\n//=============================================\n\nint homekit_server_on_url(http_parser *parser, const char *data, size_t length) {\n\tclient_context_t *context = (client_context_t*) parser->data;\n\n\tcontext->endpoint = HOMEKIT_ENDPOINT_UNKNOWN;\n\tif (parser->method == HTTP_PARSER_METHOD_GET) {\n\t\tif (!strncmp(data, \"/accessories\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_GET_ACCESSORIES;\n\t\t} else {\n\t\t\tstatic const char url[] = \"/characteristics\";\n\t\t\tsize_t url_len = sizeof(url) - 1;\n\n\t\t\tif (length >= url_len && !strncmp(data, url, url_len)\n\t\t\t\t\t&& (data[url_len] == 0 || data[url_len] == '?')) {\n\t\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_GET_CHARACTERISTICS;\n\t\t\t\tif (data[url_len] == '?') {\n\t\t\t\t\tchar *query = strndup(data + url_len + 1, length - url_len - 1);\n\t\t\t\t\tcontext->endpoint_params = query_params_parse(query);\n\t\t\t\t\tfree(query);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (parser->method == HTTP_PARSER_METHOD_POST) {\n\t\tif (!strncmp(data, \"/identify\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_IDENTIFY;\n\t\t} else if (!strncmp(data, \"/pair-setup\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_PAIR_SETUP;\n\t\t} else if (!strncmp(data, \"/pair-verify\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_PAIR_VERIFY;\n\t\t} else if (!strncmp(data, \"/pairings\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_PAIRINGS;\n\t\t} else if (!strncmp(data, \"/resource\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_RESOURCE;\n\t\t}\n\t} else if (parser->method == HTTP_PARSER_METHOD_PUT) {\n\t\tif (!strncmp(data, \"/characteristics\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_UPDATE_CHARACTERISTICS;\n\t\t}\n\t}\n\n\tif (context->endpoint == HOMEKIT_ENDPOINT_UNKNOWN) {\n\t\tchar *url = strndup(data, length);\n\t\t//TODO fix\n\t\t//ERROR(\"Unknown endpoint: %s %s\", http_method_str(parser->method), url);\n\t\tfree(url);\n\t}\n\n\treturn 0;\n}\n\nint homekit_server_on_body(http_parser *parser, const char *data, size_t length) {\n\tDEBUG(\"http_parser lenght=%d\", length);\n\tclient_context_t *context = (client_context_t*) parser->data;\n\tcontext->body = (char*) realloc(context->body, context->body_length + length + 1);\n\tmemcpy(context->body + context->body_length, data, length);\n\tcontext->body_length += length;\n\tcontext->body[context->body_length] = 0;\n\n\treturn 0;\n}\n\nint homekit_server_on_message_complete(http_parser *parser) {\n\tDEBUG(\"http_parser message_complete\");\n\tclient_context_t *context = (client_context_t*) parser->data;\n\n\tif (!context->encrypted) {\n\t\tswitch (context->endpoint) {\n\t\tcase HOMEKIT_ENDPOINT_PAIR_SETUP: {\n\t\t\thomekit_server_on_pair_setup(context, (const byte*) context->body,\n\t\t\t\t\tcontext->body_length);\n\t\t\tbreak;\n\t\t}\n\t\tcase HOMEKIT_ENDPOINT_PAIR_VERIFY: {\n\t\t\thomekit_server_on_pair_verify(context, (const byte*) context->body,\n\t\t\t\t\tcontext->body_length);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tDEBUG(\"Unknown endpoint\");\n\t\t\tsend_404_response(context);\n\t\t\tbreak;\n\t\t}\n\t\t}\n\t} else {\n\t\tswitch (context->endpoint) {\n\t\tcase HOMEKIT_ENDPOINT_IDENTIFY: {\n\t\t\thomekit_server_on_identify(context);\n\t\t\tbreak;\n\t\t}\n\t\tcase HOMEKIT_ENDPOINT_GET_ACCESSORIES: {\n\t\t\thomekit_server_on_get_accessories(context);\n\t\t\tbreak;\n\t\t}\n\t\tcase HOMEKIT_ENDPOINT_GET_CHARACTERISTICS: {\n\t\t\thomekit_server_on_get_characteristics(context);\n\t\t\tbreak;\n\t\t}\n\t\tcase HOMEKIT_ENDPOINT_UPDATE_CHARACTERISTICS: {\n\t\t\thomekit_server_on_update_characteristics(context, (const byte*) context->body,\n\t\t\t\t\tcontext->body_length);\n\t\t\tbreak;\n\t\t}\n\t\tcase HOMEKIT_ENDPOINT_PAIRINGS: {\n\t\t\thomekit_server_on_pairings(context, (const byte*) context->body, context->body_length);\n\t\t\tbreak;\n\t\t}\n\t\tcase HOMEKIT_ENDPOINT_RESOURCE: {\n\t\t\thomekit_server_on_resource(context);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tDEBUG(\"Unknown endpoint\");\n\t\t\tsend_404_response(context);\n\t\t\tbreak;\n\t\t}\n\t\t}\n\t}\n\n\tif (context->endpoint_params) {\n\t\tquery_params_free(context->endpoint_params);\n\t\tcontext->endpoint_params = NULL;\n\t}\n\n\tif (context->body) {\n\t\tfree(context->body);\n\t\tcontext->body = NULL;\n\t\tcontext->body_length = 0;\n\t}\n\treturn 0;\n}\n\nhttp_parser_settings make_http_parser_settings() {\n\thttp_parser_settings settings;\n\tsettings.on_url = homekit_server_on_url;\n\tsettings.on_body = homekit_server_on_body;\n\tsettings.on_message_complete = homekit_server_on_message_complete;\n\treturn settings;\n}\n\n//sorry, unimplemented: non-trivial designated initializers not supported\n//static http_parser_settings homekit_http_parser_settings = {\n//    .on_url = homekit_server_on_url,\n//    .on_body = homekit_server_on_body,\n//    .on_message_complete = homekit_server_on_message_complete,\n//};\n//点号+赋值符号\n//struct A a={.b = 1,.c = 2}; //c++ compiler dose not support\n//冒号\n//struct A a={b:1,c:2}；\nstatic http_parser_settings homekit_http_parser_settings = make_http_parser_settings();\n\nvoid homekit_client_process(client_context_t *context) {\n//    int data_len = read(\n//        context->socket,\n//        context->data+context->data_available,\n//        context->data_size-context->data_available\n//    );\n\tif (context->socket == nullptr) {\n\t\tCLIENT_ERROR(context, \"The socket is null\");\n\t\treturn;\n\t}\n\tint data_len = 0;\n\tint available_len = context->socket->available();  // optimistic_yield(100);\n\tif (available_len > 0) {\n\t\tint size = context->data_size - context->data_available;\n\t\tif (size > available_len) {\n\t\t\tsize = available_len;\n\t\t}\n\t\t// read or readBytes\n\t\tdata_len = context->socket->read(context->data + context->data_available, size);\n\t}\n\tif (data_len == 0) {\n\t\tif (!context->socket->connected()) {\n\t\t\tCLIENT_INFO(context, \"Disconnected!\");\n\t\t\tcontext->disconnect = true;\n\t\t\thomekit_server_close_client(context->server, context);\n\t\t}\n\t\treturn;\n\t} CLIENT_DEBUG(context, \"Got %d incomming data, encrypted is %s\",\n\t\t\tdata_len, context->encrypted ? \"true\" : \"false\");\n\tbyte *payload = (byte*) context->data;\n\tsize_t payload_size = (size_t) data_len;\n\n\tbyte *decrypted = NULL;\n\tsize_t decrypted_size = 0;\n\n\tif (context->encrypted) {\n\t\tCLIENT_DEBUG(context, \"Decrypting data\");\n\n\t\tclient_decrypt_(context, context->data, data_len, NULL, &decrypted_size);\n\n\t\tdecrypted = (byte*) malloc(decrypted_size);\n\t\tint r = client_decrypt_(context, context->data, data_len, decrypted, &decrypted_size);\n\n\t\tif (r < 0) {\n\t\t\tCLIENT_ERROR(context, \"Invalid client data\");\n\t\t\tfree(decrypted);\n\t\t\treturn;\n\t\t}\n\t\tcontext->data_available = data_len - r;\n\t\tif (r && context->data_available) {\n\t\t\tmemmove(context->data, &context->data[r], context->data_available);\n\t\t} CLIENT_DEBUG(context, \"Decrypted %d bytes, available %d\", decrypted_size, context->data_available);\n\n\t\tpayload = decrypted;\n\t\tpayload_size = decrypted_size;\n\t\tif (payload_size)\n\t\t\tprint_binary(\"Decrypted data\", payload, payload_size);\n\t} else {\n\t\tcontext->data_available = 0;\n\t}\n\n\tcurrent_client_context = context;\n\thttp_parser_execute(&context->parser, &homekit_http_parser_settings, (char*) payload,\n\t\t\tpayload_size);\n\tcurrent_client_context = NULL;\n\n\tCLIENT_DEBUG(context, \"Finished processing\");\n\n\tif (decrypted) {\n\t\tfree(decrypted);\n\t}\n}\n\nvoid homekit_server_close_client(homekit_server_t *server, client_context_t *context) {\n\tCLIENT_INFO(context, \"Closing client connection\");\n\tcontext->step = HOMEKIT_CLIENT_STEP_END;\n\tserver->nfds--;\n\n\tif (context->socket) {\n\t\tcontext->socket->stop();\n\t\tCLIENT_DEBUG(context, \"The sockect is stopped\");\n\t\tdelete context->socket;\n\t\tcontext->socket = nullptr;\n\t}\n\tif (context->server->pairing_context && context->server->pairing_context->client == context) {\n\t\tpairing_context_free(context->server->pairing_context);\n\t\tcontext->server->pairing_context = NULL;\n\t\tCLIENT_INFO(context, \"Clear the pairing context\");\n\t}\n\n\tif (context->server->clients == context) {\n\t\tcontext->server->clients = context->next;\n\t} else {\n\t\tclient_context_t *c = context->server->clients;\n\t\twhile (c->next && c->next != context)\n\t\t\tc = c->next;\n\t\tif (c->next)\n\t\t\tc->next = c->next->next;\n\t}\n\n\thomekit_accessories_clear_notify_callbacks(context->server->config->accessories,\n\t\t\tclient_notify_characteristic, context);\n\n\tHOMEKIT_NOTIFY_EVENT(server, HOMEKIT_EVENT_CLIENT_DISCONNECTED);\n\n\tclient_context_free(context);\n}\n\nclient_context_t* homekit_server_accept_client(homekit_server_t *server) {\n\n\tif (!server->wifi_server) {\n\t\tERROR(\"The server's WiFiServer is NULL!\");\n\t\treturn NULL;\n\t}\n\tWiFiClient *wifiClient = nullptr;\n\n\tif (server->wifi_server->hasClient()) {\n\t\twifiClient = new WiFiClient(server->wifi_server->available());\n\t\tif (server->nfds >= HOMEKIT_MAX_CLIENTS) {\n\t\t\tINFO(\"No more room for client connections (max %d)\", HOMEKIT_MAX_CLIENTS);\n\t\t\twifiClient->stop();\n\t\t\tdelete wifiClient;\n\t\t\treturn NULL;\n\t\t}\n\t} else {\n\t\treturn NULL;\n\t}\n\n\tINFO(\"Got new client: local %s:%d, remote %s:%d\", wifiClient->localIP().toString().c_str(),\n\t\t\twifiClient->localPort(), wifiClient->remoteIP().toString().c_str(),\n\t\t\twifiClient->remotePort());\n\n\t//wifiClient->keepAlive(HOMEKIT_SOCKET_KEEPALIVE_IDLE_SEC,\n\t//HOMEKIT_SOCKET_KEEPALIVE_INTERVAL_SEC, HOMEKIT_SOCKET_KEEPALIVE_IDLE_COUNT);\n\tint s = wifiClient->fd();\n\tconst struct timeval rcvtimeout = { 10, 0 }; /* 10 second timeout */\n\tsetsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &rcvtimeout, sizeof(rcvtimeout));\n\n\tconst int yes = 1; /* enable sending keepalive probes for socket */\n\tsetsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes));\n\n\tconst int idle = HOMEKIT_SOCKET_KEEPALIVE_IDLE_SEC; /* 180 sec idle before start sending probes */\n\tsetsockopt(s, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle));\n\n\tconst int interval = HOMEKIT_SOCKET_KEEPALIVE_INTERVAL_SEC; /* 30 sec between probes */\n\tsetsockopt(s, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));\n\n\tconst int maxpkt = HOMEKIT_SOCKET_KEEPALIVE_IDLE_COUNT; /* Drop connection after 4 probes without response */\n\tsetsockopt(s, IPPROTO_TCP, TCP_KEEPCNT, &maxpkt, sizeof(maxpkt));\n\n\twifiClient->setNoDelay(true);\n\t//wifiClient->setSync(false);\n\twifiClient->setTimeout(HOMEKIT_SOCKET_TIMEOUT);\n\n\tclient_context_t *context = client_context_new(wifiClient);\n\tcontext->server = server;\n\tcontext->socket = wifiClient;\n\n\tcontext->next = server->clients;\n\tserver->clients = context;\n\n\tserver->nfds++;\n\n\tHOMEKIT_NOTIFY_EVENT(server, HOMEKIT_EVENT_CLIENT_CONNECTED);\n\n\treturn context;\n}\n\n//设备向iPhone传递characteristic的消息\nvoid homekit_server_process_notifications(homekit_server_t *server) {\n\tclient_context_t *context = server->clients;\n\t// 把characteristic_event_t拼接成client_event_t链表\n\t// 按照Apple的规定，Nofiy消息需合并发送\n\twhile (context) {\n\t\tif (context->step != HOMEKIT_CLIENT_STEP_PAIR_VERIFY_2OF2) {\n\t\t\t// Do not send event when the client is not verify over.\n\t\t\tcontext = context->next;\n\t\t\tcontinue;\n\t\t}\n\t\tcharacteristic_event_t *event = NULL;\n\t\tif (context->event_queue && q_pop(context->event_queue, &event)) {\n\t\t\t// Get and coalesce all client events\n\t\t\tclient_event_t *events_head = (client_event_t*) malloc(sizeof(client_event_t));\n\t\t\tevents_head->characteristic = event->characteristic;\n\t\t\thomekit_value_copy(&events_head->value, &event->value);\n\t\t\tevents_head->next = NULL;\n\n\t\t\thomekit_value_destruct(&event->value);\n\t\t\tfree(event);\n\n\t\t\tclient_event_t *events_tail = events_head;\n\n\t\t\twhile (q_pop(context->event_queue, &event)) {\n\t\t\t\t//q_pop第二个参数必须传指针的地址\n\t\t\t\t//event = context->event_queue->shift();\n\t\t\t\tclient_event_t *e = events_head;\n\t\t\t\twhile (e) {\n\t\t\t\t\tif (e->characteristic == event->characteristic) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\te = e->next;\n\t\t\t\t}\n\n\t\t\t\tif (e) {\n\t\t\t\t\thomekit_value_destruct(&e->value);\n\t\t\t\t} else {\n\t\t\t\t\te = (client_event_t*) malloc(sizeof(client_event_t));\n\t\t\t\t\te->characteristic = event->characteristic;\n\t\t\t\t\te->next = NULL;\n\n\t\t\t\t\tevents_tail->next = e;\n\t\t\t\t\tevents_tail = e;\n\t\t\t\t}\n\n\t\t\t\thomekit_value_copy(&e->value, &event->value);\n\n\t\t\t\thomekit_value_destruct(&event->value);\n\t\t\t\tfree(event);\n\t\t\t}\n\n\t\t\tsend_client_events(context, events_head);\n\n\t\t\tclient_event_t *e = events_head;\n\t\t\twhile (e) {\n\t\t\t\tclient_event_t *next = e->next;\n\n\t\t\t\thomekit_value_destruct(&e->value);\n\t\t\t\tfree(e);\n\n\t\t\t\te = next;\n\t\t\t}\n\t\t}\n\n\t\tcontext = context->next;\n\t}\n\n}\n\nbool homekit_client_need_process_data(client_context_t *context) {\n\tif (context) {\n\t\treturn (context->step >= HOMEKIT_CLIENT_STEP_PAIR_SETUP_1OF3\n\t\t\t\t&& context->step < HOMEKIT_CLIENT_STEP_PAIR_VERIFY_2OF2);\n\t}\n\treturn false;\n}\n\n//run in loop, include {accept_client, client_process, notifications}\nvoid homekit_server_process(homekit_server_t *server) {\n\n\thomekit_server_accept_client(server);\n\n\tclient_context_t *context = server->clients;\n\twhile (context) {\n\t\t//homekit_client_process includes {handle data and stop disconnected client}\n//\t\tdo{\n//\t\t\tif(homekit_client_need_process_data(context)){\n//\t\t\t\tCLIENT_INFO(context, \"Step is %d\", context->step);\n//\t\t\t}\n//\t\t\tdelay(10);\n\t\thomekit_client_process(context);\n//\t\t} while(homekit_client_need_process_data(context));\n\n\t\tcontext = context->next;\n\t}\n\thomekit_server_process_notifications(server);\n}\n\n//=====================================================\n// Arduino ESP8266 MDNS: call this funciton only once when WiFi STA is connected!\n//=====================================================\nbool homekit_mdns_started = false;\n\nvoid homekit_on_config_number_changed() {\n\tif (!running_server) {\n\t\treturn;\n\t}\n\tMDNS.addServiceTxt(HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, \"c#\",\n\t\t\tString(running_server->config->config_number).c_str());\n}\n\nvoid homekit_on_paired_status_changed() {\n\tif (!running_server) {\n\t\treturn;\n\t}\n\tMDNS.addServiceTxt(HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, \"sf\",\n\t\t\t(running_server->paired) ? \"0\" : \"1\");\n}\n\nvoid homekit_mdns_init(homekit_server_t *server) {\n\tINFO(\"Configuring MDNS\");\n\n\t//ESP32\n\t/*\n\t if (!WiFi.isConnected()) {\n\t return;\n\t }\n\n\t IPAddress staIP = WiFi.localIP();\n\t if (!staIP.isSet()) {\n\t return;\n\t }*/\n\n\thomekit_accessory_t *accessory = server->config->accessories[0];\n\thomekit_service_t *accessory_info = homekit_service_by_type(accessory,\n\tHOMEKIT_SERVICE_ACCESSORY_INFORMATION);\n\tif (!accessory_info) {\n\t\tERROR(\"Invalid accessory declaration: no Accessory Information service\");\n\t\treturn;\n\t}\n\n\thomekit_characteristic_t *name = homekit_service_characteristic_by_type(accessory_info,\n\tHOMEKIT_CHARACTERISTIC_NAME);\n\tif (!name) {\n\t\tERROR(\"Invalid accessory declaration: \" \"no Name characteristic in AccessoryInfo service\");\n\t\treturn;\n\t}\n\n\thomekit_characteristic_t *model = homekit_service_characteristic_by_type(accessory_info,\n\tHOMEKIT_CHARACTERISTIC_MODEL);\n\tif (!model) {\n\t\tERROR(\"Invalid accessory declaration: \" \"no Model characteristic in AccessoryInfo service\");\n\t\treturn;\n\t}\n\n\tif (homekit_mdns_started) {\n\t\t//MDNS.close();\n\t\t//MDNS.begin(name->value.string_value, staIP);\n\t\t//INFO(\"MDNS restart: %s, IP: %s\", name->value.string_value, staIP.toString().c_str());\n\t\t//MDNS.announce();\n\t\treturn;\n\t}\n\n\t//homekit_mdns_configure_init(name->value.string_value, PORT);\n\t//WiFi.hostname(name->value.string_value);\n\tWiFi.setHostname(name->value.string_value);\t//ESP32\n\t// Must specify the MDNS runs on the IP of STA\n\t//MDNS.begin(name->value.string_value, staIP);//ESP32\n\tMDNS.begin(name->value.string_value);\n\tmdns_instance_name_set(name->value.string_value);\n\t//INFO(\"MDNS begin: %s, IP: %s\", name->value.string_value, staIP.toString().c_str());\n\tINFO(\"MDNS begin: %s\", name->value.string_value);\n\n\tMDNS.addService(HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, HOMEKIT_SERVER_PORT);\n\n\t//MDNSResponder::hMDNSService mdns_service = MDNS.addService(name->value.string_value,\n\t//HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_SERVICE, HOMEKIT_SERVER_PORT);\n\t// Set a service specific callback for dynamic service TXT items.\n\t// The callback is called, whenever service TXT items are needed for the given service.\n//\tMDNS.setDynamicServiceTxtCallback(mdns_service,\n//\t\t\t[](const MDNSResponder::hMDNSService p_hService) {\n//\t\t\t\tDEBUG(\"MDNS call DynamicServiceTxtCallback\");\n//\t\t\t\tif (running_server) {\n//\t\t\t\t\tMDNS.addDynamicServiceTxt(p_hService, \"sf\",\n//\t\t\t\t\t\t\t(running_server->paired) ? \"0\" : \"1\");\n//\t\t\t\t\tMDNS.addDynamicServiceTxt(p_hService, \"c#\",\n//\t\t\t\t\t\t\trunning_server->config->config_number);\n//\t\t\t\t}\n//\n//\t\t\t}\n//\t);\n\t//DynamicServiceTxt for ESP32\n\tMDNS.addServiceTxt(HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, \"sf\",\n\t\t\t(server->paired) ? \"0\" : \"1\");\n\tMDNS.addServiceTxt(HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, \"c#\",\n\t\t\tString(server->config->config_number).c_str());\n\n\t//Static Service Txt\n\tMDNS.addServiceTxt(HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, \"md\",\n\t\t\t(const char*) model->value.string_value);\n\tMDNS.addServiceTxt(HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, \"pv\", \"1.0\");\n\tMDNS.addServiceTxt(HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, \"id\",\n\t\t\t(const char*) server->accessory_id);\n\t//\"c#\" is a DynamicServiceTxt\n\t//Current configuration number. Required.\n\t//Must update when an accessory, service, or characteristic is added or removed on the accessory server.\n\t//Accessories must increment the config number after a firmware update.\n\t//This must have a range of 1-65535 and wrap to 1 when it overflows.\n\t//This value must persist across reboots, power cycles, etc.\n\t//MDNS.addServiceTxt(mdns_service, \"c#\", String(server->config->config_number).c_str());\n\tMDNS.addServiceTxt(HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, \"s#\", \"1\");\n\tMDNS.addServiceTxt(HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, \"ff\", \"0\");\n\t//\"sf\" is a DynamicServiceTxt\n\t//MDNS.addServiceTxt(HAP_SERVICE, HOMEKIT_MDNS_PROTO, \"sf\", (server->paired) ? \"0\" : \"1\");\n\tMDNS.addServiceTxt(HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, \"ci\",\n\t\t\tString(server->config->category).c_str());\n\n\t/*\n\t // accessory model name (required)\n\t homekit_mdns_add_txt(\"md\", \"%s\", model->value.string_value);\n\t // protocol version (required)\n\t homekit_mdns_add_txt(\"pv\", \"1.0\");\n\t // device ID (required)\n\t // should be in format XX:XX:XX:XX:XX:XX, otherwise devices will ignore it\n\t homekit_mdns_add_txt(\"id\", \"%s\", server->accessory_id);\n\t // current configuration number (required)\n\t homekit_mdns_add_txt(\"c#\", \"%d\", server->config->config_number);\n\t // current state number (required)\n\t homekit_mdns_add_txt(\"s#\", \"1\");\n\t // feature flags (required if non-zero)\n\t //   bit 0 - supports HAP pairing. required for all HomeKit accessories\n\t //   bits 1-7 - reserved\n\t homekit_mdns_add_txt(\"ff\", \"0\");\n\t // status flags\n\t //   bit 0 - not paired\n\t //   bit 1 - not configured to join WiFi\n\t //   bit 2 - problem detected on accessory\n\t //   bits 3-7 - reserved\n\t homekit_mdns_add_txt(\"sf\", \"%d\", (server->paired) ? 0 : 1);\n\t // accessory category identifier\n\t homekit_mdns_add_txt(\"ci\", \"%d\", server->config->category);*/\n\n\tif (server->config->setupId) {\n\t\tDEBUG(\"Accessory Setup ID = %s\", server->config->setupId);\n\n\t\tsize_t data_size = strlen(server->config->setupId) + strlen(server->accessory_id) + 1;\n\t\tchar *data = (char*) malloc(data_size);\n\t\tsnprintf(data, data_size, \"%s%s\", server->config->setupId, server->accessory_id);\n\t\tdata[data_size - 1] = 0;\n\n\t\tunsigned char shaHash[SHA512_DIGEST_SIZE];\n\t\twc_Sha512Hash((const unsigned char*) data, data_size - 1, shaHash);\n\n\t\tfree(data);\n\n\t\tunsigned char encodedHash[9];\n\t\tmemset(encodedHash, 0, sizeof(encodedHash));\n\t\tword32 len = sizeof(encodedHash);\n\t\tbase64_encode_((const unsigned char*) shaHash, 4, encodedHash);\n\t\tMDNS.addServiceTxt(HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, \"sh\",\n\t\t\t\t(const char*) encodedHash);\n\t}\n\n\t//MDNS.announce();\n\t//MDNS.update();\n\thomekit_mdns_started = true;\n\t//INFO(\"MDNS ok! Open your \\\"Home\\\" app, click \\\"Add or Scan Accessory\\\"\"\n\t//\t\t\" and \\\"I Don't Have a Code\\\". \\nThis Accessory will show on your iOS device.\");\n}\n\n// Used to update the config_number (\"c#\" value of Bonjour)\n// Call this function when an accessory, service, or characteristic is added or removed on the accessory server.\n// See the official HAP specification for more information.\nvoid homekit_update_config_number() {\n\tif (!homekit_mdns_started) {\n\t\treturn;\n\t}\n\tif (!running_server) {\n\t\treturn;\n\t}\n\t// range of 1-65535\n\tuint16_t c = running_server->config->config_number;\n\tc = (c > 0 && c < 65535) ? (c + 1) : 1;\n\trunning_server->config->config_number = c;\n\t//MDNS.announce();\n\t//MDNS.update();\n\thomekit_on_config_number_changed();\n\tINFO(\"Update config_number to %u\", c);\n}\n\nint homekit_accessory_id_generate(char *accessory_id) {\n\tbyte buf[6];\n\thomekit_random_fill(buf, sizeof(buf));\n\n\tsnprintf(accessory_id, ACCESSORY_ID_SIZE + 1, \"%02X:%02X:%02X:%02X:%02X:%02X\", buf[0], buf[1],\n\t\t\tbuf[2], buf[3], buf[4], buf[5]);\n\n\tINFO(\"Generated new accessory ID: %s\", accessory_id);\n\treturn 0;\n}\n\nint homekit_accessory_key_generate(ed25519_key *key) {\n\tint r = crypto_ed25519_generate(key);\n\tif (r) {\n\t\tERROR(\"Failed to generate accessory key\");\n\t\treturn r;\n\t}\n\n\tINFO(\"Generated new accessory key\");\n\n\treturn 0;\n}\n\nvoid homekit_server_init(homekit_server_config_t *config) {\n\tif (!config->accessories) {\n\t\tERROR(\"Error initializing HomeKit accessory server: \" \"accessories are not specified\");\n\t\treturn;\n\t}\n\n\tif (!config->password && !config->password_callback) {\n\t\tERROR(\n\t\t\t\t\"Error initializing HomeKit accessory server: \" \"neither password nor password callback is specified\");\n\t\treturn;\n\t}\n\n\tif (config->password) {\n\t\tconst char *p = config->password;\n\t\tif (strlen(p) != 10\n\t\t\t\t|| !(ISDIGIT(p[0]) && ISDIGIT(p[1]) && ISDIGIT(p[2]) && p[3] == '-' && ISDIGIT(p[4])\n\t\t\t\t\t\t&& ISDIGIT(p[5]) && p[6] == '-' && ISDIGIT(p[7]) && ISDIGIT(p[8])\n\t\t\t\t\t\t&& ISDIGIT(p[9]))) {\n\t\t\tERROR(\"Error initializing HomeKit accessory server: \" \"invalid password format\");\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (config->setupId) {\n\t\tconst char *p = config->setupId;\n\t\tif (strlen(p) != 4\n\t\t\t\t|| !(ISBASE36(p[0]) && ISBASE36(p[1]) && ISBASE36(p[2]) && ISBASE36(p[3]))) {\n\t\t\tERROR(\"Error initializing HomeKit accessory server: \" \"invalid setup ID format\");\n\t\t\treturn;\n\t\t}\n\t}\n\n\thomekit_accessories_init(config->accessories);\n\tif (!config->config_number) {\n\t\tconfig->config_number = config->accessories[0]->config_number;\n\t\tif (!config->config_number) {\n\t\t\tconfig->config_number = 1;\n\t\t}\n\t}\n\tif (!config->category) {\n\t\tconfig->category = config->accessories[0]->category;\n\t}\n\thomekit_server_t *server = server_new();\n\trunning_server = server;\n\tserver->config = config;\n\n\t//homekit_server_task(server);\n\tINFO(\"Starting server\");\n\n\tint r = homekit_storage_init();\n\tif (r == 0) {\n\t\tr = homekit_storage_load_accessory_id(server->accessory_id);\n\n\t\tif (!r)\n\t\t\tr = homekit_storage_load_accessory_key(&server->accessory_key);\n\t}\n\n\tif (r) {\n\t\tif (r < 0) {\n\t\t\tINFO(\"Resetting HomeKit storage\");\n\t\t\thomekit_storage_reset();\n\t\t}\n\n\t\thomekit_accessory_id_generate(server->accessory_id);\n\t\thomekit_storage_save_accessory_id(server->accessory_id);\n\n\t\thomekit_accessory_key_generate(&server->accessory_key);\n\t\thomekit_storage_save_accessory_key(&server->accessory_key);\n\t} else {\n\t\tINFO(\"Using existing accessory ID: %s\", server->accessory_id);\n\t}\n\n\tpairing_iterator_t pairing_it;\n\thomekit_storage_pairing_iterator_init(&pairing_it);\n\n\tpairing_t pairing;\n\twhile (!homekit_storage_next_pairing(&pairing_it, &pairing)) {\n\t\tif (pairing.permissions & pairing_permissions_admin) {\n\t\t\tINFO(\"Found admin pairing with %s, disabling pair setup\", pairing.device_id);\n\t\t\tserver->paired = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\thomekit_storage_pairing_iterator_done(&pairing_it);\n\n\tif (!server->paired) {\n\t\tif (!arduino_homekit_preinit(server)) {\n\t\t\tERROR(\"Error in arduino_homekit_preinit, please check and retry\");\n\t\t\tsystem_restart();\n\t\t\treturn;\n\t\t}\n\t}\n\n\thomekit_mdns_init(server);\n\tHOMEKIT_NOTIFY_EVENT(server, HOMEKIT_EVENT_SERVER_INITIALIZED);\n\thomekit_server_process(server);\n\n\tINFO(\"Init server over\");\n}\n\nvoid homekit_server_reset() {\n\thomekit_storage_reset();\n}\n\nbool homekit_is_paired() {\n\tbool paired = false;\n\n\tpairing_iterator_t pairing_it;\n\thomekit_storage_pairing_iterator_init(&pairing_it);\n\n\tpairing_t pairing;\n\twhile (!homekit_storage_next_pairing(&pairing_it, &pairing)) {\n\t\tif (pairing.permissions & pairing_permissions_admin) {\n\t\t\tpaired = true;\n\t\t\tbreak;\n\t\t}\n\t};\n\thomekit_storage_pairing_iterator_done(&pairing_it);\n\n\treturn paired;\n}\n\nint homekit_get_accessory_id(char *buffer, size_t size) {\n\tif (size < ACCESSORY_ID_SIZE + 1)\n\t\treturn -1;\n\n\tint r = homekit_storage_load_accessory_id(buffer);\n\tif (r)\n\t\treturn r;\n\n\treturn 0;\n}\n\nint homekit_get_setup_uri(const homekit_server_config_t *config, char *buffer, size_t buffer_size) {\n\tstatic const char base36Table[] = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\n\tif (buffer_size < 20)\n\t\treturn -1;\n\n\tif (!config->password)\n\t\treturn -1;\n\t// TODO: validate password in case it is run beffore server is started\n\n\tif (!config->setupId)\n\t\treturn -1;\n\t// TODO: validate setupID in case it is run beffore server is started\n\n\thomekit_accessory_t *accessory = homekit_accessory_by_id(config->accessories, 1);\n\tif (!accessory)\n\t\treturn -1;\n\n\tuint32_t setup_code = 0;\n\tfor (const char *s = config->password; *s; s++) {\n\t\tif (ISDIGIT(*s)) {\n\t\t\tsetup_code = setup_code * 10 + *s - '0';\n\t\t}\n\t}\n\n\tuint64_t payload = 0;\n\n\tpayload <<= 4;  // reserved 4 bits\n\n\tpayload <<= 8;\n\tpayload |= accessory->category & 0xff;\n\n\tpayload <<= 4;\n\tpayload |= 2;  // flags (2=IP, 4=BLE, 8=IP_WAC)\n\n\tpayload <<= 27;\n\tpayload |= setup_code & 0x7fffffff;\n\n\tstrcpy(buffer, \"X-HM://\");\n\tbuffer += 7;\n\tfor (int i = 8; i >= 0; i--) {\n\t\tbuffer[i] = base36Table[payload % 36];\n\t\tpayload /= 36;\n\t}\n\tbuffer += 9;\n\n\tstrcpy(buffer, config->setupId);\n\tbuffer += 4;\n\n\tbuffer[0] = 0;\n\n\treturn 0;\n}\n\n// Pre-initialize the pairing_context used in Pair-Setep 1/3\n// For avoiding timeout caused sockect disconnection from iOS device.\nbool arduino_homekit_preinit(homekit_server_t *server) {\n\tif (saved_preinit_pairing_context != nullptr) {\n\t\treturn true;\n\t}\n\tINFO(\"Preiniting pairing context\");\n\tDEBUG_TIME_BEGIN();\n\tpairing_context_t *preinit_pairing_context = pairing_context_new();\n\tDEBUG_HEAP();\n\tchar password[11];\n\tif (server->config->password) {\n\t\tstrncpy(password, server->config->password, sizeof(password));\n\t\t//CLIENT_DEBUG(context, \"Using user-specified password: %s\", password);\n\t\tINFO(\"Using user-specified password: %s\", password);\n\t} else {\n\t\tfor (int i = 0; i < 10; i++) {\n\t\t\tpassword[i] = homekit_random() % 10 + '0';\n\t\t}\n\t\tpassword[3] = password[6] = '-';\n\t\tpassword[10] = 0;\n\t\t//CLIENT_DEBUG(context, \"Using random password: %s\", password);\n\t\tINFO(\"Using random password: %s\", password);\n\t}\n\n\tif (server->config->password_callback) {\n\t\tserver->config->password_callback(password);\n\t}\n\n\twatchdog_disable_all();\n\twatchdog_check_begin();\n\tcrypto_srp_init(preinit_pairing_context->srp, \"Pair-Setup\", password);\n\twatchdog_check_end(\"crypto_srp_init\");  // 6585ms\n\twatchdog_enable_all();\n\n\tdelay(10);\n\n\tif (preinit_pairing_context->public_key) {\n\t\tfree(preinit_pairing_context->public_key);\n\t\tpreinit_pairing_context->public_key = NULL;\n\t}\n\tpreinit_pairing_context->public_key_size = 0;\n\tcrypto_srp_get_public_key(preinit_pairing_context->srp, NULL,\n\t\t\t&preinit_pairing_context->public_key_size);\n\n\tpreinit_pairing_context->public_key = (byte*) malloc(preinit_pairing_context->public_key_size);\n\n\twatchdog_disable_all();\n\twatchdog_check_begin();\n\tint r = crypto_srp_get_public_key(preinit_pairing_context->srp,\n\t\t\tpreinit_pairing_context->public_key, &preinit_pairing_context->public_key_size);\n\twatchdog_check_end(\"crypto_srp_get_public_key\");  // 3310ms\n\twatchdog_enable_all();\n\n\tdelay(10);\n\n\tif (r) {\n\t\t//CLIENT_ERROR(context, \"Failed to dump SPR public key (code %d)\", r);\n\t\tERROR(\"Failed to dump SPR public key (code %d)\", r);\n\t\tpairing_context_free(preinit_pairing_context);\n\t\tpreinit_pairing_context = NULL;\n\t\t// In preinit, we should not send response\n\t\t// send_tlv_error_response(context, 2, TLVError_Unknown);\n\t\treturn false;\n\t}\n\tsaved_preinit_pairing_context = preinit_pairing_context;\n\n\tDEBUG_TIME_END(\"preinit\");\n\n\tINFO(\"Preinit pairing context success\");\n\t//MDNS.announce();\t\t// update \"paired\" state\n\n\thomekit_on_paired_status_changed();\n\treturn true;\n}\n\nvoid esp32_homekit_task(void *args) {\n\thomekit_server_config_t *config = (homekit_server_config_t*) args;\n\thomekit_server_init(config);\n\tfor (;;) {\n\t\tif (running_server != nullptr) {\n\t\t\tif (!running_server->paired) {\n\t\t\t\t//If not paired or pairing was removed, preinit paring context.\n\t\t\t\tarduino_homekit_preinit(running_server);\n\t\t\t}\n\t\t\thomekit_server_process(running_server);\n\t\t}\n\t\tvTaskDelay(10 / portTICK_PERIOD_MS);\n\t}\n}\n\nvoid arduino_homekit_setup(homekit_server_config_t *config) {\n\t//ESP32 use FreeRTOS-task\n\txTaskCreate(esp32_homekit_task, \"HomeKit Server\",\n\tSERVER_TASK_STACK, config, 1, NULL);\n\t/*\n\t if (system_get_cpu_freq() != SYS_CPU_160MHZ) {\n\t system_update_cpu_freq(SYS_CPU_160MHZ);\n\t INFO(\"Update the CPU to run at 160MHz\");\n\t }*/\n\n\t//homekit_server_init(config);\n\t// The MDNS needs to be restarted when WiFi is connected to confirm the\n\t// MDNS runs at the IPAddress of STA\n\t// otherwise the iOS will not show the Accessory\n\t/*\n\t arduino_homekit_gotiphandler = WiFi.onStationModeGotIP([](WiFiEventStationModeGotIP gotip) {\n\t INFO(\"WiFi connected, ip: %s, mask: %s, gw: %s\",\n\t gotip.ip.toString().c_str(), gotip.mask.toString().c_str(),\n\t gotip.gw.toString().c_str());\n\t if (running_server) {\n\t homekit_mdns_init(running_server);\n\t } else {\n\t ERROR(\"running_server is NULL!\");\n\t }\n\t });*/\n}\n\nvoid arduino_homekit_loop() {\n\tDEBUG(\"No need to call arduino_homekit_loop in ESP32\");\n//\tif (homekit_mdns_started) {\n//\t\tMDNS.update();\n//\t}\n//\tif (running_server != nullptr) {\n//\t\tif (!running_server->paired) {\n//\t\t\t//If not paired or pairing was removed, preinit paring context.\n//\t\t\tarduino_homekit_preinit(running_server);\n//\t\t}\n//\t\thomekit_server_process(running_server);\n//\t}\n}\n\nint arduino_homekit_connected_clients_count() {\n\tif (running_server) {\n\t\treturn running_server->nfds;\n\t}\n\treturn -1;\n}\n\nhomekit_server_t* arduino_homekit_get_running_server() {\n\treturn running_server;\n}\n\n#endif\n"
  },
  {
    "path": "src/arduino_homekit_server_esp8266.cpp",
    "content": "#if defined(ESP8266)\n#include <Arduino.h>\n#include <esp_xpgm.h>\n#include <ESP8266WiFi.h>\n#include <ESP8266mDNS.h>\n#include <LEAmDNS.h>\n\n#include <WiFiServer.h>\n#include <WiFiClient.h>\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <homekit/homekit.h>\n#include <homekit/characteristics.h>\n#include <homekit/tlv.h>\n#include <homekit/types.h>\n#include <wolfssl/wolfcrypt/hash.h> //wc_sha512\n\n#include \"constants.h\"\n#include \"base64.h\"\n#include \"pairing.h\"\n#include \"storage.h\"\n#include \"query_params.h\"\n#include \"json.h\"\n#include \"homekit_debug.h\"\n#include \"port.h\"\n#include \"http_parser.h\"\n#include \"query_params.h\"\n#include \"cJSON.h\"\n#include \"cQueue.h\"\n#include \"crypto.h\"\n#include \"watchdog.h\"\n#include \"arduino_homekit_server.h\"\n\n#define HOMEKIT_SERVER_PORT      5556\n#define HOMEKIT_MAX_CLIENTS      8\n#define HOMEKIT_MDNS_SERVICE     \"hap\"//\"_hap\"\n#define HOMEKIT_MDNS_PROTO       \"tcp\"//\"_tcp\"\n#define HOMEKIT_EVENT_QUEUE_SIZE 4 //original is 20\n#define HOMEKIT_SOCKET_TIMEOUT   500 //milliseconds\n\n//#define TCP_DEFAULT_KEEPALIVE_IDLE_SEC          7200 // 2 hours\n//#define TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC      75   // 75 sec\n//#define TCP_DEFAULT_KEEPALIVE_COUNT             9    // fault after 9 failures\n//const int idle = 180; /* 180 sec idle before start sending probes */\n#define HOMEKIT_SOCKET_KEEPALIVE_IDLE_SEC      180\n//const int interval = 30; /* 30 sec between probes */\n#define HOMEKIT_SOCKET_KEEPALIVE_INTERVAL_SEC  30\n//const int maxpkt = 4; /* Drop connection after 4 probes without response */\n#define HOMEKIT_SOCKET_KEEPALIVE_IDLE_COUNT     4\n// if 180 + 30 * 4 = 300 sec without socket response, disconected it.\n\n// WiFiClient can not write big buff once.\n// TCP_SND_BUF = (2 * TCP_MSS) = 1072. See lwipopts.h\n// max(encrypted_chunk) = 512 + 8(chunk_info) + 18(chacha_info). See client_send_encrypted\n#define HOMEKIT_JSONBUFFER_SIZE  512\n\n#ifdef HOMEKIT_DEBUG\n#define TLV_DEBUG(values) //tlv_debug(values)\n#else\n#define TLV_DEBUG(values)\n#endif\n\n#define CLIENT_DEBUG(client, message, ...) DEBUG(\"[Client %d] \" message, client->socket, ##__VA_ARGS__)\n#define CLIENT_INFO(client, message, ...) INFO(\"[Client %d] \" message, client->socket, ##__VA_ARGS__)\n#define CLIENT_ERROR(client, message, ...) ERROR(\"[Client %d] \" message, client->socket, ##__VA_ARGS__)\n\nclient_context_t *current_client_context = NULL;\nhomekit_server_t *running_server = nullptr;\nWiFiEventHandler arduino_homekit_gotiphandler;\n\n#define HOMEKIT_NOTIFY_EVENT(server, event) \\\n  if ((server)->config->on_event) \\\n      (server)->config->on_event(event);\n\nvoid client_context_free(client_context_t *c);\nvoid pairing_context_free(pairing_context_t *context);\nvoid homekit_server_close_client(homekit_server_t *server, client_context_t *context);\nbool arduino_homekit_preinit(homekit_server_t *server);\n\nhomekit_server_t* server_new() {\n\thomekit_server_t *server = (homekit_server_t*) malloc(sizeof(homekit_server_t));\n\tserver->wifi_server = new WiFiServer(HOMEKIT_SERVER_PORT);\n\tserver->wifi_server->begin();\n\tserver->wifi_server->setNoDelay(true);\n\tDEBUG(\"WiFiServer begin at port: %d\", HOMEKIT_SERVER_PORT);\n\t//FD_ZERO(&server->fds);\n\t//server->max_fd = 0;\n\tserver->nfds = 0;\n\tserver->config = NULL;\n\tserver->paired = false;\n\tserver->pairing_context = NULL;\n\tserver->clients = NULL;\n\treturn server;\n}\n\nvoid server_free(homekit_server_t *server) {\n\tif (server->pairing_context)\n\t\tpairing_context_free(server->pairing_context);\n\n\tif (server->clients) {\n\t\tclient_context_t *client = server->clients;\n\t\twhile (client) {\n\t\t\tclient_context_t *next = client->next;\n\t\t\tclient_context_free(client);\n\t\t\tclient = next;\n\t\t}\n\t}\n\tif (server->wifi_server) {\n\t\tserver->wifi_server->stop();\n\t\tserver->wifi_server->close();\n\t\tdelete server->wifi_server;\n\t\tserver->wifi_server = nullptr;\n\t}\n\tDEBUG(\"homekit_server_t delete WiFiServer at port: %d\\n\", HOMEKIT_SERVER_PORT);\n\n\tif (server == running_server) {\n\t\trunning_server = NULL;\n\t}\n\tfree(server);\n}\n\nvoid tlv_debug(const tlv_values_t *values) {\n\tDEBUG(\"Got following TLV values:\");\n\tfor (tlv_t *t = values->head; t; t = t->next) {\n\t\tchar *escaped_payload = binary_to_string(t->value, t->size);\n\t\tDEBUG(\"Type %d value (%d bytes): %s\", t->type, t->size, escaped_payload);\n\t\tfree(escaped_payload);\n\t}\n}\n\npair_verify_context_t* pair_verify_context_new() {\n\tpair_verify_context_t *context = (pair_verify_context_t*) malloc(sizeof(pair_verify_context_t));\n\n\tcontext->secret = NULL;\n\tcontext->secret_size = 0;\n\n\tcontext->session_key = NULL;\n\tcontext->session_key_size = 0;\n\tcontext->device_public_key = NULL;\n\tcontext->device_public_key_size = 0;\n\tcontext->accessory_public_key = NULL;\n\tcontext->accessory_public_key_size = 0;\n\n\treturn context;\n}\n\nvoid pair_verify_context_free(pair_verify_context_t *context) {\n\tif (context->secret)\n\t\tfree(context->secret);\n\n\tif (context->session_key)\n\t\tfree(context->session_key);\n\n\tif (context->device_public_key)\n\t\tfree(context->device_public_key);\n\n\tif (context->accessory_public_key)\n\t\tfree(context->accessory_public_key);\n\n\tfree(context);\n}\n\n//==========================\n// client_context new and free\n//============================\nclient_context_t* client_context_new(WiFiClient *wifiClient) {\n\tclient_context_t *c = (client_context_t*) malloc(sizeof(client_context_t));\n\tc->server = NULL;\n\tc->endpoint_params = NULL;\n\n\tc->data_size = sizeof(c->data);\n\tc->data_available = 0;\n\n\tc->body = NULL;\n\tc->body_length = 0;\n\thttp_parser_init(&c->parser, HTTP_REQUEST);\n\tc->parser.data = c;\n\n\tc->pairing_id = -1;\n\tc->encrypted = false;\n\tc->count_reads = 0;\n\tc->count_writes = 0;\n\tc->disconnect = false;\n\n\t//c->event_queue = xQueueCreate(20, sizeof(characteristic_event_t*));\n\tc->event_queue = (Queue_t*) malloc(sizeof(Queue_t));\n\tq_init(c->event_queue, sizeof(characteristic_event_t*),\n\tHOMEKIT_EVENT_QUEUE_SIZE, LIFO, true);\n\n\tc->verify_context = NULL;\n\n\tc->next = NULL;\n\n\tc->socket = wifiClient;\n\n\tc->step = HOMEKIT_CLIENT_STEP_NONE;\n\tc->error_write = false;\n\n\treturn c;\n}\n\nvoid client_context_free(client_context_t *c) {\n\tif (c->verify_context)\n\t\tpair_verify_context_free(c->verify_context);\n\n\tif (c->event_queue) {\n\t\t//c->event_queue->clear();\n\t\tq_clean(c->event_queue);\n\t\tq_kill(c->event_queue);\n\t\tfree(c->event_queue);\n\t}\n\n\tif (c->endpoint_params)\n\t\tquery_params_free(c->endpoint_params);\n\n\tif (c->body)\n\t\tfree(c->body);\n\n\tif (c->socket) {\n\t\tc->socket->stop();\n\t\tdelete c->socket;\n\t\tc->socket = nullptr;\n\t}\n\n\tfree(c);\n}\n\npairing_context_t *saved_preinit_pairing_context = nullptr;\n\npairing_context_t* pairing_context_new() {\n\tpairing_context_t *context = (pairing_context_t*) malloc(sizeof(pairing_context_t));\n\tcontext->srp = crypto_srp_new();\n\tcontext->client = NULL;\n\tcontext->public_key = NULL;\n\tcontext->public_key_size = 0;\n\treturn context;\n}\n\nvoid pairing_context_free(pairing_context_t *context) {\n\tif (context == saved_preinit_pairing_context) {\n\t\tINFO(\"Free saved_preinit_pairing_context\");\n\t\tif (saved_preinit_pairing_context) {\n\t\t\tsaved_preinit_pairing_context = nullptr;\n\t\t}\n\t}\n\tif (context->srp) {\n\t\tcrypto_srp_free(context->srp);\n\t}\n\tif (context->public_key) {\n\t\tfree(context->public_key);\n\t}\n\tfree(context);\n}\n\n//=====================\n//pairing context\n//=====================\n\nvoid client_notify_characteristic(homekit_characteristic_t *ch, homekit_value_t value,\n\t\tvoid *client);\n\nvoid write_characteristic_json(json_stream *json, client_context_t *client,\n\t\tconst homekit_characteristic_t *ch, characteristic_format_t format,\n\t\tconst homekit_value_t *value) {\n\tjson_string(json, \"aid\");\n\tjson_uint32(json, ch->service->accessory->id);\n\tjson_string(json, \"iid\");\n\tjson_uint32(json, ch->id);\n\n\tif (format & characteristic_format_type) {\n\t\tjson_string(json, \"type\");\n\t\tjson_string(json, ch->type);\n\t}\n\n\tif (format & characteristic_format_perms) {\n\t\tjson_string(json, \"perms\");\n\t\tjson_array_start(json);\n\t\tif (ch->permissions & homekit_permissions_paired_read)\n\t\t\tjson_string(json, \"pr\");\n\t\tif (ch->permissions & homekit_permissions_paired_write)\n\t\t\tjson_string(json, \"pw\");\n\t\tif (ch->permissions & homekit_permissions_notify)\n\t\t\tjson_string(json, \"ev\");\n\t\tif (ch->permissions & homekit_permissions_additional_authorization)\n\t\t\tjson_string(json, \"aa\");\n\t\tif (ch->permissions & homekit_permissions_timed_write)\n\t\t\tjson_string(json, \"tw\");\n\t\tif (ch->permissions & homekit_permissions_hidden)\n\t\t\tjson_string(json, \"hd\");\n\t\tjson_array_end(json);\n\t}\n\n\tif ((format & characteristic_format_events) && (ch->permissions & homekit_permissions_notify)) {\n\t\tbool events = homekit_characteristic_has_notify_callback(ch, client_notify_characteristic,\n\t\t\t\tclient);\n\t\tjson_string(json, \"ev\");\n\t\tjson_boolean(json, events);\n\t}\n\n\tif (format & characteristic_format_meta) {\n\t\tif (ch->description) {\n\t\t\tjson_string(json, \"description\");\n\t\t\tjson_string(json, ch->description);\n\t\t}\n\n\t\tconst char *format_str = NULL;\n\t\tswitch (ch->format) {\n\t\tcase homekit_format_bool:\n\t\t\tformat_str = \"bool\";\n\t\t\tbreak;\n\t\tcase homekit_format_uint8:\n\t\t\tformat_str = \"uint8\";\n\t\t\tbreak;\n\t\tcase homekit_format_uint16:\n\t\t\tformat_str = \"uint16\";\n\t\t\tbreak;\n\t\tcase homekit_format_uint32:\n\t\t\tformat_str = \"uint32\";\n\t\t\tbreak;\n\t\tcase homekit_format_uint64:\n\t\t\tformat_str = \"uint64\";\n\t\t\tbreak;\n\t\tcase homekit_format_int:\n\t\t\tformat_str = \"int\";\n\t\t\tbreak;\n\t\tcase homekit_format_float:\n\t\t\tformat_str = \"float\";\n\t\t\tbreak;\n\t\tcase homekit_format_string:\n\t\t\tformat_str = \"string\";\n\t\t\tbreak;\n\t\tcase homekit_format_tlv:\n\t\t\tformat_str = \"tlv8\";\n\t\t\tbreak;\n\t\tcase homekit_format_data:\n\t\t\tformat_str = \"data\";\n\t\t\tbreak;\n\t\t}\n\t\tif (format_str) {\n\t\t\tjson_string(json, \"format\");\n\t\t\tjson_string(json, format_str);\n\t\t}\n\n\t\tconst char *unit_str = NULL;\n\t\tswitch (ch->unit) {\n\t\tcase homekit_unit_none:\n\t\t\tbreak;\n\t\tcase homekit_unit_celsius:\n\t\t\tunit_str = \"celsius\";\n\t\t\tbreak;\n\t\tcase homekit_unit_percentage:\n\t\t\tunit_str = \"percentage\";\n\t\t\tbreak;\n\t\tcase homekit_unit_arcdegrees:\n\t\t\tunit_str = \"arcdegrees\";\n\t\t\tbreak;\n\t\tcase homekit_unit_lux:\n\t\t\tunit_str = \"lux\";\n\t\t\tbreak;\n\t\tcase homekit_unit_seconds:\n\t\t\tunit_str = \"seconds\";\n\t\t\tbreak;\n\t\t}\n\t\tif (unit_str) {\n\t\t\tjson_string(json, \"unit\");\n\t\t\tjson_string(json, unit_str);\n\t\t}\n\n\t\tif (ch->min_value) {\n\t\t\tjson_string(json, \"minValue\");\n\t\t\tjson_float(json, *ch->min_value);\n\t\t}\n\n\t\tif (ch->max_value) {\n\t\t\tjson_string(json, \"maxValue\");\n\t\t\tjson_float(json, *ch->max_value);\n\t\t}\n\n\t\tif (ch->min_step) {\n\t\t\tjson_string(json, \"minStep\");\n\t\t\tjson_float(json, *ch->min_step);\n\t\t}\n\n\t\tif (ch->max_len) {\n\t\t\tjson_string(json, \"maxLen\");\n\t\t\tjson_uint32(json, *ch->max_len);\n\t\t}\n\n\t\tif (ch->max_data_len) {\n\t\t\tjson_string(json, \"maxDataLen\");\n\t\t\tjson_uint32(json, *ch->max_data_len);\n\t\t}\n\n\t\tif (ch->valid_values.count) {\n\t\t\tjson_string(json, \"valid-values\");\n\t\t\tjson_array_start(json);\n\n\t\t\tfor (int i = 0; i < ch->valid_values.count; i++) {\n\t\t\t\tjson_uint16(json, ch->valid_values.values[i]);\n\t\t\t}\n\n\t\t\tjson_array_end(json);\n\t\t}\n\n\t\tif (ch->valid_values_ranges.count) {\n\t\t\tjson_string(json, \"valid-values-range\");\n\t\t\tjson_array_start(json);\n\n\t\t\tfor (int i = 0; i < ch->valid_values_ranges.count; i++) {\n\t\t\t\tjson_array_start(json);\n\n\t\t\t\tjson_integer(json, ch->valid_values_ranges.ranges[i].start);\n\t\t\t\tjson_integer(json, ch->valid_values_ranges.ranges[i].end);\n\n\t\t\t\tjson_array_end(json);\n\t\t\t}\n\n\t\t\tjson_array_end(json);\n\t\t}\n\t}\n\n\tif (ch->permissions & homekit_permissions_paired_read) {\n\t\thomekit_value_t v = value ? *value : ch->getter_ex ? ch->getter_ex(ch) : ch->value;\n\n\t\tif (v.is_null) {\n\t\t\t json_string(json, \"value\"); json_null(json);\n\t\t} else if (v.format != ch->format) {\n\t\t\tERROR(\"Characteristic value format is different from characteristic format\");\n\t\t} else {\n\t\t\tswitch (v.format) {\n\t\t\tcase homekit_format_bool: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_boolean(json, v.bool_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint8: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_uint8(json, v.uint8_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint16: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_uint16(json, v.uint16_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint32: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_uint32(json, v.uint32_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint64: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_uint64(json, v.uint64_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_int: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_integer(json, v.int_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_float: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_float(json, v.float_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_string: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tjson_string(json, v.string_value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_tlv: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tif (!v.tlv_values) {\n\t\t\t\t\tjson_string(json, \"\");\n\t\t\t\t} else {\n\t\t\t\t\tsize_t tlv_size = 0;\n\t\t\t\t\ttlv_format(v.tlv_values, NULL, &tlv_size);\n\t\t\t\t\tif (tlv_size == 0) {\n\t\t\t\t\t\tjson_string(json, \"\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbyte *tlv_data = (byte*) malloc(tlv_size);\n\t\t\t\t\t\ttlv_format(v.tlv_values, tlv_data, &tlv_size);\n\n\t\t\t\t\t\tsize_t encoded_tlv_size = base64_encoded_size(tlv_data, tlv_size);\n\t\t\t\t\t\tbyte *encoded_tlv_data = (byte*) malloc(encoded_tlv_size + 1);\n\t\t\t\t\t\tbase64_encode_(tlv_data, tlv_size, encoded_tlv_data);\n\t\t\t\t\t\tencoded_tlv_data[encoded_tlv_size] = 0;\n\n\t\t\t\t\t\tjson_string(json, (char*) encoded_tlv_data);\n\n\t\t\t\t\t\tfree(encoded_tlv_data);\n\t\t\t\t\t\tfree(tlv_data);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_data: {\n\t\t\t\tjson_string(json, \"value\");\n\t\t\t\tif (!v.data_value || v.data_size == 0) {\n\t\t\t\t\tjson_string(json, \"\");\n\t\t\t\t} else {\n\t\t\t\t\tsize_t encoded_data_size = base64_encoded_size(v.data_value, v.data_size);\n\t\t\t\t\tbyte *encoded_data = (byte*) malloc(encoded_data_size + 1);\n\t\t\t\t\tbase64_encode_(v.data_value, v.data_size, encoded_data);\n\t\t\t\t\tencoded_data[encoded_data_size] = 0;\n\n\t\t\t\t\tjson_string(json, (char*) encoded_data);\n\n\t\t\t\t\tfree(encoded_data);\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!value && ch->getter_ex) {\n\t\t\t// called getter to get value, need to free it\n\t\t\thomekit_value_destruct(&v);\n\t\t}\n\t}\n}\n\nvoid write(client_context_t *context, byte *data, int data_size) {\n\tif ((!context) || (!context->socket) || (!context->socket->connected())) {\n\t\tCLIENT_ERROR(context, \"The socket is null! (or is closed)\");\n\t\treturn;\n\t}\n\tif (context->error_write) {\n\t\tCLIENT_ERROR(context, \"Abort write data since error_write.\");\n\t\treturn;\n\t}\n\tint write_size = context->socket->write(data, data_size);\n\tCLIENT_DEBUG(context, \"Sending data of size %d\", data_size);\n\tif (write_size != data_size) {\n\t\tCLIENT_ERROR(context, \"socket.write, data_size=%d, write_size=%d\", data_size, write_size);\n\t\tcontext->error_write = true;\n\t\t// Error write when :\n\t\t// 1. remote client is disconnected\n\t\t// 2. data_size is larger than the tcp internal send buffer\n\t\t// But We has limited the data_size to 538, and TCP_SND_BUF = 1072. (See the comments on HOMEKIT_JSONBUFFER_SIZE)\n\t\t// So we believe here is disconnected.\n\t\tcontext->disconnect = true;\n\t\thomekit_server_close_client(context->server, context);\n\t\t// We consider the socket is 'closed' when error in writing (eg. the remote client is disconnected, NO tcp ack receive).\n\t\t// Closing the socket causes memory-leak if some data has not been sent (the write_buffer did not free)\n\t\t// To fix this memory-leak, add tcp_abandon(_pcb, 0); in ClientContext.h of ESP8266WiFi-library.\n\t}\n\n}\n\nint client_send_encrypted_(client_context_t *context,\n\t\tbyte *payload, size_t size) {\n\tCLIENT_DEBUG(context, \"Send encrypted of size %d\", size);\n\t// max(size) = HOMEKIT_JSONBUFFER_SIZE + chunk_info(8) = 512 + 8 = 520\n\tif (!context || !context->encrypted)\n\t\treturn -1;\n\n\t/*\n\t HAP doc:\n\t Each HTTP message is split into frames no larger than 1024 bytes.\n\t Each frame has the following format:\n\t <2:AAD for little endian length of encrypted data (n) in bytes>\n\t <n:encrypted data according to AEAD algorithm, up to 1024 bytes>\n\t <16:authTag according to AEAD algorithm>\n\t Note by Wang Bin. 2020-03-07\n\t */\n\n\tbyte nonce[12];\n\tmemset(nonce, 0, sizeof(nonce));\n\n\tbyte encrypted[1024 + 18];\n\tint payload_offset = 0;\n\n\twhile (payload_offset < size) {\n\t\tsize_t chunk_size = size - payload_offset;\n\t\tif (chunk_size > 1024)\n\t\t\tchunk_size = 1024;\n\n\t\tbyte aead[2] = { chunk_size % 256, chunk_size / 256 };\n\n\t\tmemcpy(encrypted, aead, 2);\n\n\t\tbyte i = 4;\n\t\tint x = context->count_reads++;\n\t\twhile (x) {\n\t\t\tnonce[i++] = x % 256;\n\t\t\tx /= 256;\n\t\t}\n\n\t\tsize_t available = sizeof(encrypted) - 2;\n\t\tint r = crypto_chacha20poly1305_encrypt(context->read_key, nonce, aead, 2,\n\t\t\t\tpayload + payload_offset, chunk_size, encrypted + 2, &available);\n\t\tif (r) {\n\t\t\tERROR(\"Failed to chacha encrypt payload (code %d)\", r);\n\t\t\treturn -1;\n\t\t}\n\n\t\tpayload_offset += chunk_size;\n\n\t\twrite(context, encrypted, available + 2);\n\t}\n\n\treturn 0;\n}\n\nint client_decrypt_(client_context_t *context,\n\t\tbyte *payload, size_t payload_size, byte *decrypted, size_t *decrypted_size) {\n\tif (!context || !context->encrypted)\n\t\treturn -1;\n\n\tconst size_t block_size = 1024 + 16 + 2;\n\tsize_t required_decrypted_size = payload_size / block_size * 1024;\n\tif (payload_size % block_size > 0)\n\t\trequired_decrypted_size += payload_size % block_size - 16 - 2;\n\n\tif (*decrypted_size < required_decrypted_size) {\n\t\t*decrypted_size = required_decrypted_size;\n\t\treturn -2;\n\t}\n\n\t*decrypted_size = required_decrypted_size;\n\n\tbyte nonce[12];\n\tmemset(nonce, 0, sizeof(nonce));\n\n\tint payload_offset = 0;\n\tint decrypted_offset = 0;\n\n\twhile (payload_offset < payload_size) {\n\t\tsize_t chunk_size = payload[payload_offset] + payload[payload_offset + 1] * 256;\n\t\tif (chunk_size + 18 > payload_size - payload_offset) {\n\t\t\t// Unfinished chunk\n\t\t\tbreak;\n\t\t}\n\n\t\tbyte i = 4;\n\t\tint x = context->count_writes++;\n\t\twhile (x) {\n\t\t\tnonce[i++] = x % 256;\n\t\t\tx /= 256;\n\t\t}\n\n\t\tsize_t decrypted_len = *decrypted_size - decrypted_offset;\n\t\tint r = crypto_chacha20poly1305_decrypt(context->write_key, nonce, payload + payload_offset,\n\t\t\t\t2, payload + payload_offset + 2, chunk_size + 16, decrypted, &decrypted_len);\n\t\tif (r) {\n\t\t\tERROR(\"Failed to chacha decrypt payload (code %d)\", r);\n\t\t\treturn -1;\n\t\t}\n\n\t\tdecrypted_offset += decrypted_len;\n\t\tpayload_offset += chunk_size + 18;\n\t}\n\n\treturn payload_offset;\n}\n\nvoid client_notify_characteristic(homekit_characteristic_t *ch, homekit_value_t value,\n\t\tvoid *context) {\n\tclient_context_t *client = (client_context_t*) context;\n\n\tif (client->current_characteristic == ch && client->current_value\n\t\t\t&& homekit_value_equal(client->current_value, &value)) {\n\t\t// This value is set by this client, no need to send notification\n\t\tCLIENT_DEBUG(client, \"This value is set by this client, no need to send notification\");\n\t\treturn;\n\t}\n\tCLIENT_INFO(client, \"Got characteristic %d.%d change event\",\n\t\t\tch->service->accessory->id, ch->id);\n\t//DEBUG(\"Got characteristic %d.%d change event\", ch->service->accessory->id, ch->id);\n\n\tif (!client->event_queue) {\n\t\tERROR(\"Client has no event queue. Skipping notification\");\n\t\treturn;\n\t}\n\n\tcharacteristic_event_t *event = (characteristic_event_t*) malloc(\n\t\t\tsizeof(characteristic_event_t));\n\tevent->characteristic = ch;\n\thomekit_value_copy(&event->value, &value);\n\n\tDEBUG(\"Sending event to client %d\", client->socket);\n\n\t//xQueueSendToBack(client->event_queue, &event, 10);*/\n\t//q_push第二个参数要传指针地址\n\tq_push(client->event_queue, &event);\n}\n\nvoid client_send(client_context_t *context, byte *data, size_t data_size) {\n\n\tCLIENT_DEBUG(context, \"send data size=%d, encrypted=%s\",\n\t\t\tdata_size, context->encrypted ? \"true\" : \"false\");\n\n\tif (context->encrypted) {\n\t\tint r = client_send_encrypted_(context, data, data_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to encrypt response (code %d)\", r);\n\t\t\treturn;\n\t\t}\n\t} else {\n\t\twrite(context, data, data_size);\n\t}\n}\n\nvoid client_send_P(client_context_t *context, PGM_P pgm) {\n\tXPGM_BUFFCPY_STRING(char, buff, pgm);\n\tclient_send(context, (byte*)buff, sizeof(buff) - 1);\n}\n\nvoid client_send_chunk(byte *data, size_t size, void *arg) {\n\tclient_context_t *context = (client_context_t*) arg;\n\n\tsize_t payload_size = size + 8;\n\tbyte *payload = (byte*) malloc(payload_size);\n\tif (!payload) {\n\t\tERROR(\"Error malloc payload!! payload_size->%d\", payload_size);\n\t\treturn;\n\t}\n\n\tint offset = snprintf((char*) payload, payload_size, \"%x\\r\\n\", size);\n\tmemcpy(payload + offset, data, size);\n\tpayload[offset + size] = '\\r';\n\tpayload[offset + size + 1] = '\\n';\n\tCLIENT_DEBUG(context, \"client_send_chunk, size=%d, offset=%d\", size, offset);\n\tclient_send(context, payload, offset + size + 2);\n\tfree(payload);\n}\n\nvoid send_204_response(client_context_t *context) {\n\tstatic const char PROGMEM response[] = \"HTTP/1.1 204 No Content\\r\\n\\r\\n\";\n\tclient_send_P(context, response);\n}\n\nvoid send_404_response(client_context_t *context) {\n\tstatic const char PROGMEM response[] = \"HTTP/1.1 404 Not Found\\r\\n\\r\\n\";\n\tclient_send_P(context, response);\n}\n\nvoid send_client_events(client_context_t *context, client_event_t *events) {\n\tCLIENT_DEBUG(context, \"Sending EVENT\");DEBUG_HEAP();\n\n\tstatic const char PROGMEM http_headers[] = \"EVENT/1.0 200 OK\\r\\n\"\n\t\t\t\"Content-Type: application/hap+json\\r\\n\"\n\t\t\t\"Transfer-Encoding: chunked\\r\\n\\r\\n\";\n\tclient_send_P(context, http_headers);\n\n\t// ~35 bytes per event JSON\n\t// 256 should be enough for ~7 characteristic updates\n\tjson_stream *json = json_new(HOMEKIT_JSONBUFFER_SIZE, client_send_chunk, context);\n\tjson_object_start(json);\n\tjson_string(json, \"characteristics\");\n\tjson_array_start(json);\n\n\tclient_event_t *e = events;\n\twhile (e) {\n\t\tjson_object_start(json);\n\t\twrite_characteristic_json(json, context, e->characteristic, (characteristic_format_t) 0,\n\t\t\t\t&e->value);\n\t\tjson_object_end(json);\n\n\t\te = e->next;\n\t}\n\n\tjson_array_end(json);\n\tjson_object_end(json);\n\n\tjson_flush(json);\n\tjson_free(json);\n\n\tclient_send_chunk(NULL, 0, context);\n}\n\nvoid send_tlv_response(client_context_t *context, tlv_values_t *values);\n\nvoid send_tlv_error_response(client_context_t *context, int state, TLVError error) {\n\ttlv_values_t *response = tlv_new();\n\ttlv_add_integer_value(response, TLVType_State, 1, state);\n\ttlv_add_integer_value(response, TLVType_Error, 1, error);\n\n\tsend_tlv_response(context, response);\n}\n\nvoid send_tlv_response(client_context_t *context, tlv_values_t *values) {\n\tCLIENT_DEBUG(context, \"Sending TLV response\");TLV_DEBUG(values);\n\n\tsize_t payload_size = 0;\n\ttlv_format(values, NULL, &payload_size);\n\n\tbyte *payload = (byte*) malloc(payload_size);\n\tint r = tlv_format(values, payload, &payload_size);\n\tif (r) {\n\t\tCLIENT_ERROR(context, \"Failed to format TLV payload (code %d)\", r);\n\t\tfree(payload);\n\t\treturn;\n\t}\n\n\ttlv_free(values);\n\n\tstatic const char PROGMEM http_headers_pgm[] = \"HTTP/1.1 200 OK\\r\\n\"\n\t\t\t\t\"Content-Type: application/pairing+tlv8\\r\\n\"\n\t\t\t\t\"Content-Length: %d\\r\\n\"\n\t\t\t\t\"Connection: keep-alive\\r\\n\\r\\n\";\n\n\tXPGM_BUFFCPY_STRING(char, http_headers, http_headers_pgm);\n\n\tint response_size = strlen(http_headers) + payload_size + 32;\n\tchar *response = (char*) malloc(response_size);\n\tint response_len = snprintf(response, response_size, http_headers, payload_size);\n\n\tif (response_size - response_len < payload_size + 1) {\n\t\tCLIENT_ERROR(context, \"Incorrect response buffer size %d: headers took %d, payload size %d\",\n\t\t\t\tresponse_size, response_len, payload_size);\n\t\tfree(response);\n\t\tfree(payload);\n\t\treturn;\n\t}\n\tmemcpy(response + response_len, payload, payload_size);\n\tresponse_len += payload_size;\n\n\tfree(payload);\n\n\tclient_send(context, (byte*) response, response_len);\n\n\tfree(response);\n}\n\nstatic const char PROGMEM json_200_response_headers_progmem[] = \"HTTP/1.1 200 OK\\r\\n\"\n\t\t\"Content-Type: application/hap+json\\r\\n\"\n\t\t\"Transfer-Encoding: chunked\\r\\n\"\n\t\t\"Connection: keep-alive\\r\\n\\r\\n\";\n\nstatic const char PROGMEM json_207_response_headers_progmem[] = \"HTTP/1.1 207 Multi-Status\\r\\n\"\n\t\t\"Content-Type: application/hap+json\\r\\n\"\n\t\t\"Transfer-Encoding: chunked\\r\\n\"\n\t\t\"Connection: keep-alive\\r\\n\\r\\n\";\n\nvoid send_json_response(client_context_t *context, int status_code, byte *payload,\n\t\tsize_t payload_size) {\n\tCLIENT_DEBUG(context, \"Sending JSON response\");DEBUG_HEAP();\n\n\tstatic const char PROGMEM http_headers_pgm[] = \"HTTP/1.1 %d %s\\r\\n\"\n\t\t\t\"Content-Type: application/hap+json\\r\\n\"\n\t\t\t\"Content-Length: %d\\r\\n\"\n\t\t\t\"Connection: keep-alive\\r\\n\\r\\n\";\n\n\tXPGM_BUFFCPY_STRING(char, http_headers, http_headers_pgm);\n\n\tCLIENT_DEBUG(context, \"Payload: %s\", payload);\n\n\t// Using PSTR and strcpy_P. Ref: ESP.getResetReason\n\t//const char *status_text = \"OK\";\n\tchar status_text[32];\n\tstrcpy_P(status_text, PSTR(\"OK\"));\n\tswitch (status_code) {\n\tcase 204:\n\t\tstrcpy_P(status_text, PSTR(\"No Content\"));\n\t\tbreak;\n\tcase 207:\n\t\tstrcpy_P(status_text, PSTR(\"Multi-Status\"));\n\t\tbreak;\n\tcase 400:\n\t\tstrcpy_P(status_text, PSTR(\"Bad Request\"));\n\t\tbreak;\n\tcase 404:\n\t\tstrcpy_P(status_text, PSTR(\"Not Found\"));\n\t\tbreak;\n\tcase 422:\n\t\tstrcpy_P(status_text, PSTR(\"Unprocessable Entity\"));\n\t\tbreak;\n\tcase 500:\n\t\tstrcpy_P(status_text, PSTR(\"Internal Server Error\"));\n\t\tbreak;\n\tcase 503:\n\t\tstrcpy_P(status_text, PSTR(\"Service Unavailable\"));\n\t\tbreak;\n\t}\n\n\tint response_size = strlen(http_headers) + payload_size + strlen(status_text) + 32;\n\tchar *response = (char*) malloc(response_size);\n\tif (!response) {\n\t\tCLIENT_ERROR(context, \"Failed to allocate response buffer of size %d\", response_size);\n\t\treturn;\n\t}\n\tint response_len = snprintf(response, response_size, http_headers, status_code, status_text,\n\t\t\tpayload_size);\n\n\tif (response_size - response_len < payload_size + 1) {\n\t\tCLIENT_ERROR(context, \"Incorrect response buffer size %d: headers took %d, payload size %d\",\n\t\t\t\tresponse_size, response_len, payload_size);\n\t\tfree(response);\n\t\treturn;\n\t}\n\tmemcpy(response + response_len, payload, payload_size);\n\tresponse_len += payload_size;\n\tresponse[response_len] = 0;  // required for debug output\n\n\tCLIENT_DEBUG(context, \"Sending HTTP response: %s\", response);\n\n\tclient_send(context, (byte*) response, response_len);\n\n\tfree(response);\n}\n\nvoid send_json_error_response(client_context_t *context, int status_code, HAPStatus status) {\n\tbyte buffer[32];\n\tint size = snprintf((char*) buffer, sizeof(buffer), \"{\\\"status\\\": %d}\", status);\n\n\tsend_json_response(context, status_code, buffer, size);\n}\n\nhomekit_client_id_t homekit_get_client_id() {\n\treturn (homekit_client_id_t) current_client_context;\n}\n\nbool homekit_client_is_admin() {\n\tif (!current_client_context)\n\t\treturn false;\n\n\treturn current_client_context->permissions & pairing_permissions_admin;\n}\n\nint homekit_client_send(unsigned char *data, size_t size) {\n\tif (!current_client_context)\n\t\treturn -1;\n\tclient_send(current_client_context, data, size);\n\treturn 0;\n}\n\nvoid homekit_server_on_identify(client_context_t *context) {\n\tCLIENT_INFO(context, \"Identify\");DEBUG_HEAP();\n\tif (context->server->paired) {\n\t\t// Already paired\n\t\tsend_json_error_response(context, 400, HAPStatus_InsufficientPrivileges);\n\t\treturn;\n\t}\n\tsend_204_response(context);\n\thomekit_accessory_t *accessory = homekit_accessory_by_id(context->server->config->accessories,\n\t\t\t1);\n\tif (!accessory) {\n\t\treturn;\n\t}\n\n\thomekit_service_t *accessory_info = homekit_service_by_type(accessory,\n\tHOMEKIT_SERVICE_ACCESSORY_INFORMATION);\n\tif (!accessory_info) {\n\t\treturn;\n\t}\n\n\thomekit_characteristic_t *ch_identify = homekit_service_characteristic_by_type(accessory_info,\n\tHOMEKIT_CHARACTERISTIC_IDENTIFY);\n\tif (!ch_identify) {\n\t\treturn;\n\t}\n\tif (ch_identify->setter_ex) {\n\t\tch_identify->setter_ex(ch_identify, HOMEKIT_BOOL_CPP(true));\n\t}\n}\n\nvoid homekit_server_on_pair_setup(client_context_t *context, const byte *data, size_t size) {\n\tDEBUG(\"Pair Setup\");DEBUG_HEAP();\n\tDEBUG_TIME_BEGIN();\n\n#ifdef HOMEKIT_OVERCLOCK_PAIR_SETUP\n    homekit_overclock_start();\n#endif\n\n\t// First set step=NONE, if pair-setup ok then set step=1or2or3\n\t// (if pair-step error, the step is NONE)\n\n\tcontext->step = HOMEKIT_CLIENT_STEP_NONE;\n\n\ttlv_values_t *message = tlv_new();\n\ttlv_parse(data, size, message);\n\tTLV_DEBUG(message);\n\tswitch (tlv_get_integer_value(message, TLVType_State, -1)) {\n\tcase 1: {\n\t\tCLIENT_INFO(context, \"Pair Setup Step 1/3\");DEBUG_HEAP();\n\t\tif (context->server->paired) {\n\t\t\tCLIENT_INFO(context, \"Refusing to pair: already paired\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unavailable);\n\t\t\tbreak;\n\t\t}\n\t\tif (context->server->pairing_context) {\n\t\t\tif (context->server->pairing_context->client != context) {\n\t\t\t\tCLIENT_INFO(context, \"Refusing to pair: another pairing in progress\");\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Busy);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\t// arduino homekit preinit (create pairing_context)\n\t\t\tif (!arduino_homekit_preinit(context->server)) {\n\t\t\t\tCLIENT_ERROR(context, \"Init pairing context error\");\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (saved_preinit_pairing_context == nullptr) {\n\t\t\t\tCLIENT_ERROR(context, \"The saved_preinit_pairing_context is NULL ?!\");\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcontext->server->pairing_context = saved_preinit_pairing_context; ///pairing_context_new();\n\t\t\tcontext->server->pairing_context->client = context;\n\t\t}\n\n\t\tint r = 0;\n\t\tsize_t salt_size = 0;\n\t\tcrypto_srp_get_salt(context->server->pairing_context->srp, NULL, &salt_size);\n\t\tbyte *salt = (byte*) malloc(salt_size);\n\t\tr = crypto_srp_get_salt(context->server->pairing_context->srp, salt, &salt_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to get salt (code %d)\", r);\n\t\t\tfree(salt);\n\t\t\tpairing_context_free(context->server->pairing_context);\n\t\t\tcontext->server->pairing_context = NULL;\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_value(response, TLVType_PublicKey, context->server->pairing_context->public_key,\n\t\t\t\tcontext->server->pairing_context->public_key_size);\n\t\ttlv_add_value(response, TLVType_Salt, salt, salt_size);\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 2);\n\t\tfree(salt);\n\t\tsend_tlv_response(context, response);\n\t\tcontext->step = HOMEKIT_CLIENT_STEP_PAIR_SETUP_1OF3;\n\t\tbreak;\n\t}\n\tcase 3: {\n\t\tCLIENT_INFO(context, \"Pair Setup Step 2/3\");DEBUG_HEAP();\n\t\ttlv_t *device_public_key = tlv_get_value(message, TLVType_PublicKey);\n\t\tif (!device_public_key) {\n\t\t\tCLIENT_ERROR(context, \"Invalid payload: no device public key\");\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *proof = tlv_get_value(message, TLVType_Proof);\n\t\tif (!proof) {\n\t\t\tCLIENT_ERROR(context, \"Invalid payload: no device proof\");\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\t\tCLIENT_DEBUG(context, \"Computing SRP shared secret\");\n\t\tDEBUG_HEAP();\n\t\twatchdog_disable_all();\n\t\twatchdog_check_begin();\n\t\tint r = crypto_srp_compute_key(context->server->pairing_context->srp,\n\t\t\t\tdevice_public_key->value, device_public_key->size,\n\t\t\t\tcontext->server->pairing_context->public_key,\n\t\t\t\tcontext->server->pairing_context->public_key_size);\n\t\twatchdog_check_end(\"crypto_srp_compute_key\"); // 13479ms\n\t\twatchdog_enable_all();\n\n\t\tdelay(10);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to compute SRP shared secret (code %d)\", r);\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tfree(context->server->pairing_context->public_key);\n\t\tcontext->server->pairing_context->public_key = NULL;\n\t\tcontext->server->pairing_context->public_key_size = 0;\n\n\t\tCLIENT_DEBUG(context, \"Verifying peer's proof\");\n\n\t\t//watchdog_check_begin();\n\t\tr = crypto_srp_verify(context->server->pairing_context->srp, proof->value, proof->size);\n\t\t//watchdog_check_end(\"crypto_srp_verify\");// 1ms\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to verify peer's proof (code %d)\", r);\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\t\tCLIENT_DEBUG(context, \"Generating own proof\");\n\t\tsize_t server_proof_size = 0;\n\t\tcrypto_srp_get_proof(context->server->pairing_context->srp, NULL, &server_proof_size);\n\n\t\tbyte *server_proof = (byte*) malloc(server_proof_size);\n\t\t//watchdog_check_begin();\n\t\tr = crypto_srp_get_proof(context->server->pairing_context->srp, server_proof,\n\t\t\t\t&server_proof_size);\n\t\t//watchdog_check_end(\"crypto_srp_get_proof\");// 1ms\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 4);\n\t\ttlv_add_value(response, TLVType_Proof, server_proof, server_proof_size);\n\t\tfree(server_proof);\n\t\tsend_tlv_response(context, response);\n\t\tcontext->step = HOMEKIT_CLIENT_STEP_PAIR_SETUP_2OF3;\n\t\tbreak;\n\t}\n\tcase 5: {\n\t\tCLIENT_INFO(context, \"Pair Setup Step 3/3\");DEBUG_HEAP();\n\t\tint r;\n\t\tbyte shared_secret[HKDF_HASH_SIZE];\n\t\tsize_t shared_secret_size = sizeof(shared_secret);\n\n\t\tCLIENT_DEBUG(context, \"Calculating shared secret\");\n\t\tconst char salt1[] = \"Pair-Setup-Encrypt-Salt\";\n\t\tconst char info1[] = \"Pair-Setup-Encrypt-Info\";\n\n\t\tr = crypto_srp_hkdf(context->server->pairing_context->srp, (byte*) salt1, sizeof(salt1) - 1,\n\t\t\t\t(byte*) info1, sizeof(info1) - 1, shared_secret, &shared_secret_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate shared secret (code %d)\", r);\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_encrypted_data = tlv_get_value(message, TLVType_EncryptedData);\n\t\tif (!tlv_encrypted_data) {\n\t\t\tCLIENT_ERROR(context, \"Invalid payload: no encrypted data\");\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Decrypting payload\");\n\t\tsize_t decrypted_data_size = 0;\n\t\tcrypto_chacha20poly1305_decrypt(shared_secret, (byte*) \"\\x0\\x0\\x0\\x0PS-Msg05\", NULL, 0,\n\t\t\t\ttlv_encrypted_data->value, tlv_encrypted_data->size,\n\t\t\t\tNULL, &decrypted_data_size);\n\n\t\tbyte *decrypted_data = (byte*) malloc(decrypted_data_size);\n\t\t// TODO: check malloc result\n\t\tr = crypto_chacha20poly1305_decrypt(shared_secret, (byte*) \"\\x0\\x0\\x0\\x0PS-Msg05\", NULL, 0,\n\t\t\t\ttlv_encrypted_data->value, tlv_encrypted_data->size, decrypted_data,\n\t\t\t\t&decrypted_data_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to decrypt data (code %d)\", r);\n\n\t\t\tfree(decrypted_data);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *decrypted_message = tlv_new();\n\t\tr = tlv_parse(decrypted_data, decrypted_data_size, decrypted_message);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to parse decrypted TLV (code %d)\", r);\n\n\t\t\ttlv_free(decrypted_message);\n\t\t\tfree(decrypted_data);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tfree(decrypted_data);\n\n\t\ttlv_t *tlv_device_id = tlv_get_value(decrypted_message, TLVType_Identifier);\n\t\tif (!tlv_device_id) {\n\t\t\tCLIENT_ERROR(context, \"Invalid encrypted payload: no device identifier\");\n\n\t\t\ttlv_free(decrypted_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\t// TODO: check that tlv_device_id->size == 36\n\n\t\ttlv_t *tlv_device_public_key = tlv_get_value(decrypted_message, TLVType_PublicKey);\n\t\tif (!tlv_device_public_key) {\n\t\t\tCLIENT_ERROR(context, \"Invalid encrypted payload: no device public key\");\n\n\t\t\ttlv_free(decrypted_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_device_signature = tlv_get_value(decrypted_message, TLVType_Signature);\n\t\tif (!tlv_device_signature) {\n\t\t\tCLIENT_ERROR(context, \"Invalid encrypted payload: no device signature\");\n\n\t\t\ttlv_free(decrypted_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Importing device public key\");\n\n\t\ted25519_key device_key;\n\t\tcrypto_ed25519_init(&device_key);\n\n\t\tr = crypto_ed25519_import_public_key(&device_key, tlv_device_public_key->value,\n\t\t\t\ttlv_device_public_key->size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to import device public Key (code %d)\", r);\n\n\t\t\ttlv_free(decrypted_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tbyte device_x[HKDF_HASH_SIZE];\n\t\tsize_t device_x_size = sizeof(device_x);\n\n\t\tCLIENT_DEBUG(context, \"Calculating DeviceX\");\n\t\tconst char salt2[] = \"Pair-Setup-Controller-Sign-Salt\";\n\t\tconst char info2[] = \"Pair-Setup-Controller-Sign-Info\";\n\n\t\tr = crypto_srp_hkdf(context->server->pairing_context->srp, (byte*) salt2, sizeof(salt2) - 1,\n\t\t\t\t(byte*) info2, sizeof(info2) - 1, device_x, &device_x_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate DeviceX (code %d)\", r);\n\n\t\t\ttlv_free(decrypted_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tsize_t device_info_size = device_x_size + tlv_device_id->size + tlv_device_public_key->size;\n\t\tbyte *device_info = (byte*) malloc(device_info_size);\n\t\tmemcpy(device_info, device_x, device_x_size);\n\t\tmemcpy(device_info + device_x_size, tlv_device_id->value, tlv_device_id->size);\n\t\tmemcpy(device_info + device_x_size + tlv_device_id->size, tlv_device_public_key->value,\n\t\t\t\ttlv_device_public_key->size);\n\n\t\tCLIENT_DEBUG(context, \"Verifying device signature\");\n\t\tr = crypto_ed25519_verify(&device_key, device_info, device_info_size,\n\t\t\t\ttlv_device_signature->value, tlv_device_signature->size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate DeviceX (code %d)\", r);\n\n\t\t\tfree(device_info);\n\t\t\ttlv_free(decrypted_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tfree(device_info);\n\n\t\tr = homekit_storage_add_pairing((const char*) tlv_device_id->value, &device_key,\n\t\t\t\tpairing_permissions_admin);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to store pairing (code %d)\", r);\n\n\t\t\ttlv_free(decrypted_message);\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tchar *device_id = strndup((const char*) tlv_device_id->value, tlv_device_id->size);\n\t\tINFO(\"Added pairing with %s\", device_id);\n\t\tfree(device_id);\n\n\t\ttlv_free(decrypted_message);\n\n\t\tHOMEKIT_NOTIFY_EVENT(context->server, HOMEKIT_EVENT_PAIRING_ADDED);\n\n\t\tCLIENT_DEBUG(context, \"Exporting accessory public key\");\n\t\tsize_t accessory_public_key_size = 0;\n\n\t\tcrypto_ed25519_export_public_key(&context->server->accessory_key, NULL,\n\t\t\t\t&accessory_public_key_size);\n\n\t\tbyte *accessory_public_key = (byte*) malloc(accessory_public_key_size);\n\t\tr = crypto_ed25519_export_public_key(&context->server->accessory_key, accessory_public_key,\n\t\t\t\t&accessory_public_key_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to export accessory public key (code %d)\", r);\n\n\t\t\tfree(accessory_public_key);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tsize_t accessory_id_size = sizeof(context->server->accessory_id) - 1;\n\t\tsize_t accessory_info_size = HKDF_HASH_SIZE + accessory_id_size + accessory_public_key_size;\n\t\tbyte *accessory_info = (byte*) malloc(accessory_info_size);\n\n\t\tCLIENT_DEBUG(context, \"Calculating AccessoryX\");\n\t\tsize_t accessory_x_size = accessory_info_size;\n\t\tconst char salt3[] = \"Pair-Setup-Accessory-Sign-Salt\";\n\t\tconst char info3[] = \"Pair-Setup-Accessory-Sign-Info\";\n\t\tr = crypto_srp_hkdf(context->server->pairing_context->srp, (byte*) salt3, sizeof(salt3) - 1,\n\t\t\t\t(byte*) info3, sizeof(info3) - 1, accessory_info, &accessory_x_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate AccessoryX (code %d)\", r);\n\n\t\t\tfree(accessory_info);\n\t\t\tfree(accessory_public_key);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tmemcpy(accessory_info + accessory_x_size, context->server->accessory_id, accessory_id_size);\n\t\tmemcpy(accessory_info + accessory_x_size + accessory_id_size, accessory_public_key,\n\t\t\t\taccessory_public_key_size);\n\n\t\tCLIENT_DEBUG(context, \"Generating accessory signature\");DEBUG_HEAP();\n\t\tsize_t accessory_signature_size = 0;\n\t\tcrypto_ed25519_sign(&context->server->accessory_key, accessory_info, accessory_info_size,\n\t\tNULL, &accessory_signature_size);\n\n\t\tbyte *accessory_signature = (byte*) malloc(accessory_signature_size);\n\t\tr = crypto_ed25519_sign(&context->server->accessory_key, accessory_info,\n\t\t\t\taccessory_info_size, accessory_signature, &accessory_signature_size);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate accessory signature (code %d)\", r);\n\n\t\t\tfree(accessory_signature);\n\t\t\tfree(accessory_public_key);\n\t\t\tfree(accessory_info);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tfree(accessory_info);\n\n\t\ttlv_values_t *response_message = tlv_new();\n\t\ttlv_add_value(response_message, TLVType_Identifier, (byte*) context->server->accessory_id,\n\t\t\t\taccessory_id_size);\n\t\ttlv_add_value(response_message, TLVType_PublicKey, accessory_public_key,\n\t\t\t\taccessory_public_key_size);\n\t\ttlv_add_value(response_message, TLVType_Signature, accessory_signature,\n\t\t\t\taccessory_signature_size);\n\n\t\tfree(accessory_public_key);\n\t\tfree(accessory_signature);\n\n\t\tsize_t response_data_size = 0;\n\t\tTLV_DEBUG(response_message);\n\n\t\ttlv_format(response_message, NULL, &response_data_size);\n\n\t\tbyte *response_data = (byte*) malloc(response_data_size);\n\t\tr = tlv_format(response_message, response_data, &response_data_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to format TLV response (code %d)\", r);\n\n\t\t\tfree(response_data);\n\t\t\ttlv_free(response_message);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_free(response_message);\n\n\t\tCLIENT_DEBUG(context, \"Encrypting response\");\n\t\tsize_t encrypted_response_data_size = 0;\n\t\tcrypto_chacha20poly1305_encrypt(shared_secret, (byte*) \"\\x0\\x0\\x0\\x0PS-Msg06\", NULL, 0,\n\t\t\t\tresponse_data, response_data_size,\n\t\t\t\tNULL, &encrypted_response_data_size);\n\n\t\tbyte *encrypted_response_data = (byte*) malloc(encrypted_response_data_size);\n\t\tr = crypto_chacha20poly1305_encrypt(shared_secret, (byte*) \"\\x0\\x0\\x0\\x0PS-Msg06\", NULL, 0,\n\t\t\t\tresponse_data, response_data_size, encrypted_response_data,\n\t\t\t\t&encrypted_response_data_size);\n\n\t\tfree(response_data);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to encrypt response data (code %d)\", r);\n\n\t\t\tfree(encrypted_response_data);\n\n\t\t\tsend_tlv_error_response(context, 6, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 6);\n\t\ttlv_add_value(response, TLVType_EncryptedData, encrypted_response_data,\n\t\t\t\tencrypted_response_data_size);\n\n\t\tfree(encrypted_response_data);\n\t\tsend_tlv_response(context, response);\n\n\t\tpairing_context_free(context->server->pairing_context);\n\t\tcontext->server->pairing_context = NULL;\n\t\tcontext->server->paired = true;\n\t\tCLIENT_INFO(context, \"Successfully paired\");\n\t\t//homekit_setup_mdns(context->server);\n\t\tcontext->step = HOMEKIT_CLIENT_STEP_PAIR_SETUP_3OF3;\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tCLIENT_ERROR(context, \"Unknown state: %d\",\n\t\t\t\ttlv_get_integer_value(message, TLVType_State, -1));\n\t}\n\t}\n\n\ttlv_free(message);\n\tDEBUG_TIME_END(\"pair_setup\");\n\n#ifdef HOMEKIT_OVERCLOCK_PAIR_SETUP\n    homekit_overclock_end();\n#endif\n}\n\nvoid homekit_server_on_pair_verify(client_context_t *context, const byte *data, size_t size) {\n\tDEBUG(\"HomeKit Pair Verify\");DEBUG_HEAP();\n\tDEBUG_TIME_BEGIN();\n\n\tcontext->step = HOMEKIT_CLIENT_STEP_NONE;\n\n#ifdef HOMEKIT_OVERCLOCK_PAIR_VERIFY\n    homekit_overclock_start();\n#endif\n\n\ttlv_values_t *message = tlv_new();\n\ttlv_parse(data, size, message);\n\n\tTLV_DEBUG(message);\n\tint r;\n\tswitch (tlv_get_integer_value(message, TLVType_State, -1)) {\n\tcase 1: {\n\t\tCLIENT_INFO(context, \"Pair Verify Step 1/2\");\n\t\tCLIENT_DEBUG(context, \"Importing device Curve25519 public key\");\n\t\ttlv_t *tlv_device_public_key = tlv_get_value(message, TLVType_PublicKey);\n\t\tif (!tlv_device_public_key) {\n\t\t\tCLIENT_ERROR(context, \"Device Curve25519 public key not found\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\t\tcurve25519_key device_key;\n\t\tr = crypto_curve25519_init(&device_key);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to initialize device Curve25519 public key (code %d)\", r);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tr = crypto_curve25519_import_public(&device_key, tlv_device_public_key->value,\n\t\t\t\ttlv_device_public_key->size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to import device Curve25519 public key (code %d)\", r);\n\t\t\tcrypto_curve25519_done(&device_key);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\t\tCLIENT_DEBUG(context, \"Generating accessory Curve25519 key\");\n\t\tcurve25519_key my_key;\n\t\tr = crypto_curve25519_generate(&my_key);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate accessory Curve25519 key (code %d)\", r);\n\t\t\tcrypto_curve25519_done(&device_key);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\t\tCLIENT_DEBUG(context, \"Exporting accessory Curve25519 public key\");\n\t\tsize_t my_key_public_size = 0;\n\t\tcrypto_curve25519_export_public(&my_key, NULL, &my_key_public_size);\n\n\t\tbyte *my_key_public = (byte*) malloc(my_key_public_size);\n\t\tr = crypto_curve25519_export_public(&my_key, my_key_public, &my_key_public_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to export accessory Curve25519 public key (code %d)\", r);\n\t\t\tfree(my_key_public);\n\t\t\tcrypto_curve25519_done(&my_key);\n\t\t\tcrypto_curve25519_done(&device_key);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Generating Curve25519 shared secret\");\n\t\tsize_t shared_secret_size = 0;\n\t\tcrypto_curve25519_shared_secret(&my_key, &device_key, NULL, &shared_secret_size);\n\n\t\tbyte *shared_secret = (byte*) malloc(shared_secret_size);\n\t\tr = crypto_curve25519_shared_secret(&my_key, &device_key, shared_secret,\n\t\t\t\t&shared_secret_size);\n\t\tcrypto_curve25519_done(&my_key);\n\t\tcrypto_curve25519_done(&device_key);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate Curve25519 shared secret (code %d)\", r);\n\t\t\tfree(shared_secret);\n\t\t\tfree(my_key_public);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Generating signature\");\n\t\tsize_t accessory_id_size = sizeof(context->server->accessory_id) - 1;\n\t\tsize_t accessory_info_size = my_key_public_size + accessory_id_size\n\t\t\t\t+ tlv_device_public_key->size;\n\n\t\tbyte *accessory_info = (byte*) malloc(accessory_info_size);\n\t\tmemcpy(accessory_info, my_key_public, my_key_public_size);\n\t\tmemcpy(accessory_info + my_key_public_size, context->server->accessory_id,\n\t\t\t\taccessory_id_size);\n\t\tmemcpy(accessory_info + my_key_public_size + accessory_id_size,\n\t\t\t\ttlv_device_public_key->value, tlv_device_public_key->size);\n\n\t\tsize_t accessory_signature_size = 0;\n\t\tcrypto_ed25519_sign(&context->server->accessory_key, accessory_info, accessory_info_size,\n\t\tNULL, &accessory_signature_size);\n\n\t\tbyte *accessory_signature = (byte*) malloc(accessory_signature_size);\n\t\tr = crypto_ed25519_sign(&context->server->accessory_key, accessory_info,\n\t\t\t\taccessory_info_size, accessory_signature, &accessory_signature_size);\n\t\tfree(accessory_info);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to generate signature (code %d)\", r);\n\t\t\tfree(accessory_signature);\n\t\t\tfree(shared_secret);\n\t\t\tfree(my_key_public);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *sub_response = tlv_new();\n\t\ttlv_add_value(sub_response, TLVType_Identifier, (const byte*) context->server->accessory_id,\n\t\t\t\taccessory_id_size);\n\t\ttlv_add_value(sub_response, TLVType_Signature, accessory_signature,\n\t\t\t\taccessory_signature_size);\n\n\t\tfree(accessory_signature);\n\n\t\tsize_t sub_response_data_size = 0;\n\t\ttlv_format(sub_response, NULL, &sub_response_data_size);\n\n\t\tbyte *sub_response_data = (byte*) malloc(sub_response_data_size);\n\t\tr = tlv_format(sub_response, sub_response_data, &sub_response_data_size);\n\t\ttlv_free(sub_response);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to format sub-TLV message (code %d)\", r);\n\t\t\tfree(sub_response_data);\n\t\t\tfree(shared_secret);\n\t\t\tfree(my_key_public);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Generating proof\");\n\t\tsize_t session_key_size = 0;\n\t\tconst byte salt[] = \"Pair-Verify-Encrypt-Salt\";\n\t\tconst byte info[] = \"Pair-Verify-Encrypt-Info\";\n\t\tcrypto_hkdf(shared_secret, shared_secret_size, salt, sizeof(salt) - 1, info,\n\t\t\t\tsizeof(info) - 1,\n\t\t\t\tNULL, &session_key_size);\n\n\t\tbyte *session_key = (byte*) malloc(session_key_size);\n\t\tr = crypto_hkdf(shared_secret, shared_secret_size, salt, sizeof(salt) - 1, info,\n\t\t\t\tsizeof(info) - 1, session_key, &session_key_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to derive session key (code %d)\", r);\n\t\t\tfree(session_key);\n\t\t\tfree(sub_response_data);\n\t\t\tfree(shared_secret);\n\t\t\tfree(my_key_public);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Encrypting response\");\n\t\tsize_t encrypted_response_data_size = 0;\n\t\tcrypto_chacha20poly1305_encrypt(session_key, (byte*) \"\\x0\\x0\\x0\\x0PV-Msg02\", NULL, 0,\n\t\t\t\tsub_response_data, sub_response_data_size,\n\t\t\t\tNULL, &encrypted_response_data_size);\n\n\t\tbyte *encrypted_response_data = (byte*) malloc(encrypted_response_data_size);\n\t\tr = crypto_chacha20poly1305_encrypt(session_key, (byte*) \"\\x0\\x0\\x0\\x0PV-Msg02\", NULL, 0,\n\t\t\t\tsub_response_data, sub_response_data_size, encrypted_response_data,\n\t\t\t\t&encrypted_response_data_size);\n\t\tfree(sub_response_data);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to encrypt sub response data (code %d)\", r);\n\t\t\tfree(encrypted_response_data);\n\t\t\tfree(session_key);\n\t\t\tfree(shared_secret);\n\t\t\tfree(my_key_public);\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 2);\n\t\ttlv_add_value(response, TLVType_PublicKey, my_key_public, my_key_public_size);\n\t\ttlv_add_value(response, TLVType_EncryptedData, encrypted_response_data,\n\t\t\t\tencrypted_response_data_size);\n\n\t\tfree(encrypted_response_data);\n\n\t\tsend_tlv_response(context, response);\n\n\t\tif (context->verify_context)\n\t\t\tpair_verify_context_free(context->verify_context);\n\n\t\tcontext->verify_context = pair_verify_context_new();\n\t\tcontext->verify_context->secret = shared_secret;\n\t\tcontext->verify_context->secret_size = shared_secret_size;\n\n\t\tcontext->verify_context->session_key = session_key;\n\t\tcontext->verify_context->session_key_size = session_key_size;\n\n\t\tcontext->verify_context->accessory_public_key = my_key_public;\n\t\tcontext->verify_context->accessory_public_key_size = my_key_public_size;\n\n\t\tcontext->verify_context->device_public_key = (byte*) malloc(tlv_device_public_key->size);\n\t\tmemcpy(context->verify_context->device_public_key, tlv_device_public_key->value,\n\t\t\t\ttlv_device_public_key->size);\n\t\tcontext->verify_context->device_public_key_size = tlv_device_public_key->size;\n\t\tcontext->step = HOMEKIT_CLIENT_STEP_PAIR_VERIFY_1OF2;\n\t\tbreak;\n\t}\n\tcase 3: {\n\t\tCLIENT_INFO(context, \"Pair Verify Step 2/2\");\n\n\t\tif (!context->verify_context) {\n\t\t\tCLIENT_ERROR(context, \"Failed to verify: no state 1 data\");\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_encrypted_data = tlv_get_value(message, TLVType_EncryptedData);\n\t\tif (!tlv_encrypted_data) {\n\t\t\tCLIENT_ERROR(context, \"Failed to verify: no encrypted data\");\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_DEBUG(context, \"Decrypting payload\");\n\t\tsize_t decrypted_data_size = 0;\n\t\tcrypto_chacha20poly1305_decrypt(context->verify_context->session_key,\n\t\t\t\t(byte*) \"\\x0\\x0\\x0\\x0PV-Msg03\", NULL, 0, tlv_encrypted_data->value,\n\t\t\t\ttlv_encrypted_data->size,\n\t\t\t\tNULL, &decrypted_data_size);\n\n\t\tbyte *decrypted_data = (byte*) malloc(decrypted_data_size);\n\t\tr = crypto_chacha20poly1305_decrypt(context->verify_context->session_key,\n\t\t\t\t(byte*) \"\\x0\\x0\\x0\\x0PV-Msg03\", NULL, 0, tlv_encrypted_data->value,\n\t\t\t\ttlv_encrypted_data->size, decrypted_data, &decrypted_data_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to decrypt data (code %d)\", r);\n\t\t\tfree(decrypted_data);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *decrypted_message = tlv_new();\n\t\tr = tlv_parse(decrypted_data, decrypted_data_size, decrypted_message);\n\t\tfree(decrypted_data);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to parse decrypted TLV (code %d)\", r);\n\t\t\ttlv_free(decrypted_message);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_device_id = tlv_get_value(decrypted_message, TLVType_Identifier);\n\t\tif (!tlv_device_id) {\n\t\t\tCLIENT_ERROR(context, \"Invalid encrypted payload: no device identifier\");\n\t\t\ttlv_free(decrypted_message);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_device_signature = tlv_get_value(decrypted_message, TLVType_Signature);\n\t\tif (!tlv_device_signature) {\n\t\t\tCLIENT_ERROR(context, \"Invalid encrypted payload: no device identifier\");\n\t\t\ttlv_free(decrypted_message);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tchar *device_id = strndup((const char*) tlv_device_id->value, tlv_device_id->size);\n\t\tCLIENT_DEBUG(context, \"Searching pairing with %s\", device_id);\n\t\tpairing_t pairing;\n\t\tif (homekit_storage_find_pairing(device_id, &pairing)) {\n\t\t\tCLIENT_ERROR(context, \"No pairing for %s found\", device_id);\n\t\t\tfree(device_id);\n\t\t\ttlv_free(decrypted_message);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tCLIENT_INFO(context, \"Found pairing with %s\", device_id);\n\t\tfree(device_id);\n\n\t\tbyte permissions = pairing.permissions;\n\t\tint pairing_id = pairing.id;\n\n\t\tsize_t device_info_size = context->verify_context->device_public_key_size\n\t\t\t\t+ context->verify_context->accessory_public_key_size + tlv_device_id->size;\n\t\tbyte *device_info = (byte*) malloc(device_info_size);\n\t\tmemcpy(device_info, context->verify_context->device_public_key,\n\t\t\t\tcontext->verify_context->device_public_key_size);\n\t\tmemcpy(device_info + context->verify_context->device_public_key_size, tlv_device_id->value,\n\t\t\t\ttlv_device_id->size);\n\t\tmemcpy(device_info + context->verify_context->device_public_key_size + tlv_device_id->size,\n\t\t\t\tcontext->verify_context->accessory_public_key,\n\t\t\t\tcontext->verify_context->accessory_public_key_size);\n\n\t\tCLIENT_DEBUG(context, \"Verifying device signature\");\n\t\tr = crypto_ed25519_verify(&pairing.device_key, device_info, device_info_size,\n\t\t\t\ttlv_device_signature->value, tlv_device_signature->size);\n\t\tfree(device_info);\n\t\ttlv_free(decrypted_message);\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to verify device signature (code %d)\", r);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\tconst byte salt[] = \"Control-Salt\";\n\t\tsize_t read_key_size = sizeof(context->read_key);\n\t\tconst byte read_info[] = \"Control-Read-Encryption-Key\";\n\t\tr = crypto_hkdf(context->verify_context->secret, context->verify_context->secret_size, salt,\n\t\t\t\tsizeof(salt) - 1, read_info, sizeof(read_info) - 1, context->read_key,\n\t\t\t\t&read_key_size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to derive read encryption key (code %d)\", r);\n\t\t\tpair_verify_context_free(context->verify_context);\n\t\t\tcontext->verify_context = NULL;\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tsize_t write_key_size = sizeof(context->write_key);\n\t\tconst byte write_info[] = \"Control-Write-Encryption-Key\";\n\n\t\tr = crypto_hkdf(context->verify_context->secret, context->verify_context->secret_size, salt,\n\t\t\t\tsizeof(salt) - 1, write_info, sizeof(write_info) - 1, context->write_key,\n\t\t\t\t&write_key_size);\n\n\t\tpair_verify_context_free(context->verify_context);\n\t\tcontext->verify_context = NULL;\n\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to derive write encryption key (code %d)\", r);\n\t\t\tsend_tlv_error_response(context, 4, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 4);\n\t\tsend_tlv_response(context, response);\n\n\t\tcontext->pairing_id = pairing_id;\n\t\tcontext->permissions = permissions;\n\t\tcontext->encrypted = true;\n\n\t\tHOMEKIT_NOTIFY_EVENT(context->server, HOMEKIT_EVENT_CLIENT_VERIFIED);\n\t\tCLIENT_INFO(context, \"Verification successful, secure session established\");\n\t\tcontext->step = HOMEKIT_CLIENT_STEP_PAIR_VERIFY_2OF2;\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tCLIENT_ERROR(context, \"Unknown state: %d\",\n\t\t\t\ttlv_get_integer_value(message, TLVType_State, -1));\n\t}\n\t}\n\ttlv_free(message);\n\tDEBUG_TIME_END(\"pair_verify\");\n\tINFO_HEAP();\n\n#ifdef HOMEKIT_OVERCLOCK_PAIR_VERIFY\n    homekit_overclock_end();\n#endif\n}\n\nvoid homekit_client_process(client_context_t *context);\n\nvoid homekit_server_on_get_accessories(client_context_t *context) {\n\tDEBUG_TIME_BEGIN();\n\tCLIENT_INFO(context, \"Get Accessories\");DEBUG_HEAP();\n\tclient_send_P(context, json_200_response_headers_progmem);\n\n\tCLIENT_DEBUG(context, \"Get Accessories, start send json body\");\n\n\tjson_stream *json = json_new(HOMEKIT_JSONBUFFER_SIZE, client_send_chunk, context);\n\tjson_object_start(json);\n\tjson_string(json, \"accessories\");\n\tjson_array_start(json);\n\n\tfor (homekit_accessory_t **accessory_it = context->server->config->accessories;\n\t\t\t*accessory_it; accessory_it++) {\n\n\t\thomekit_accessory_t *accessory = *accessory_it;\n\n\t\tjson_object_start(json);\n\n\t\tjson_string(json, \"aid\");\n\t\tjson_uint32(json, accessory->id);\n\t\tjson_string(json, \"services\");\n\t\tjson_array_start(json);\n\n\t\tfor (homekit_service_t **service_it = accessory->services; *service_it; service_it++) {\n\t\t\thomekit_service_t *service = *service_it;\n\n\t\t\tjson_object_start(json);\n\n\t\t\tjson_string(json, \"iid\");\n\t\t\tjson_uint32(json, service->id);\n\t\t\tjson_string(json, \"type\");\n\t\t\tjson_string(json, service->type);\n\t\t\tjson_string(json, \"hidden\");\n\t\t\tjson_boolean(json, service->hidden);\n\t\t\tjson_string(json, \"primary\");\n\t\t\tjson_boolean(json, service->primary);\n\t\t\tif (service->linked) {\n\t\t\t\tjson_string(json, \"linked\");\n\t\t\t\tjson_array_start(json);\n\t\t\t\tfor (homekit_service_t **linked = service->linked; *linked; linked++) {\n\t\t\t\t\tjson_uint32(json, (*linked)->id);\n\t\t\t\t}\n\t\t\t\tjson_array_end(json);\n\t\t\t}\n\n\t\t\tjson_string(json, \"characteristics\");\n\t\t\tjson_array_start(json);\n\n\t\t\tfor (homekit_characteristic_t **ch_it = service->characteristics; *ch_it; ch_it++) {\n\t\t\t\thomekit_characteristic_t *ch = *ch_it;\n\n\t\t\t\tjson_object_start(json);\n\t\t\t\twrite_characteristic_json(json, context, ch,\n\t\t\t\t\t\t(characteristic_format_t) (characteristic_format_type\n\t\t\t\t\t\t\t\t| characteristic_format_meta | characteristic_format_perms\n\t\t\t\t\t\t\t\t| characteristic_format_events),\n\t\t\t\t\t\tNULL);\n\t\t\t\tjson_object_end(json);\n\t\t\t}\n\n\t\t\tjson_array_end(json);\n\t\t\tjson_object_end(json); // service\n\t\t}\n\n\t\tjson_array_end(json);\n\t\tjson_object_end(json); // accessory\n\t}\n\n\tjson_array_end(json);\n\tjson_object_end(json); // response\n\n\tjson_flush(json);\n\tjson_free(json);\n\n\tclient_send_chunk(NULL, 0, context);\n\tDEBUG_TIME_END(\"get_accessories\")\n}\n\nbool bool_endpoint_param(const char *name, client_context_t *context) {\n\tquery_param_t *param = query_params_find(context->endpoint_params, name);\n\treturn param && param->value && !strcmp(param->value, \"1\");\n}\n\nvoid write_characteristic_error(json_stream *json, uint32_t aid, uint32_t iid, int status) {\n\tjson_object_start(json);\n\tjson_string(json, \"aid\");\n\tjson_uint32(json, aid);\n\tjson_string(json, \"iid\");\n\tjson_uint32(json, iid);\n\tjson_string(json, \"status\");\n\tjson_uint8(json, status);\n\tjson_object_end(json);\n}\n\nvoid homekit_server_on_get_characteristics(client_context_t *context) {\n\tCLIENT_INFO(context, \"Get Characteristics\");DEBUG_HEAP();\n\n\tquery_param_t *qp = context->endpoint_params;\n\twhile (qp) {\n\t\tCLIENT_DEBUG(context, \"Query paramter %s = %s\", qp->name, qp->value);\n\t\tqp = qp->next;\n\t}\n\n\tquery_param_t *id_param = query_params_find(context->endpoint_params, \"id\");\n\tif (!id_param) {\n\t\tCLIENT_ERROR(context, \"Invalid get characteristics request: missing ID parameter\");\n\t\tsend_json_error_response(context, 400, HAPStatus_InvalidValue);\n\t\treturn;\n\t}\n\n\tcharacteristic_format_t format = (characteristic_format_t) 0;\n\tif (bool_endpoint_param(\"meta\", context))\n\t\tformat = (characteristic_format_t) (format | characteristic_format_meta);\n\n\tif (bool_endpoint_param(\"perms\", context))\n\t\tformat = (characteristic_format_t) (format | characteristic_format_perms);\n\n\tif (bool_endpoint_param(\"type\", context))\n\t\tformat = (characteristic_format_t) (format | characteristic_format_type);\n\n\tif (bool_endpoint_param(\"ev\", context))\n\t\tformat = (characteristic_format_t) (format | characteristic_format_events);\n\n\tbool success = true;\n\n\tchar *id = strdup(id_param->value);\n\tchar *ch_id;\n\tchar *_id = id;\n\twhile ((ch_id = strsep(&_id, \",\"))) {\n\t\tchar *dot = strstr(ch_id, \".\");\n\t\tif (!dot) {\n\t\t\tsend_json_error_response(context, 400, HAPStatus_InvalidValue);\n\t\t\tfree(id);\n\t\t\treturn;\n\t\t}\n\n\t\t*dot = 0;\n\t\tuint32_t aid = atoi(ch_id);\n\t\tuint32_t iid = atoi(dot + 1);\n\n\t\tCLIENT_DEBUG(context, \"Requested characteristic info for %u.%u\", aid, iid);\n\t\thomekit_characteristic_t *ch = homekit_characteristic_by_aid_and_iid(\n\t\t\t\tcontext->server->config->accessories, aid, iid);\n\t\tif (!ch) {\n\t\t\tsuccess = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!(ch->permissions & homekit_permissions_paired_read)) {\n\t\t\tsuccess = false;\n\t\t\tcontinue;\n\t\t}\n\t}\n\n\tfree(id);\n\tid = strdup(id_param->value);\n\n\tif (success) {\n\t\tclient_send_P(context, json_200_response_headers_progmem);\n\t} else {\n\t\tclient_send_P(context, json_207_response_headers_progmem);\n\t}\n\n\tjson_stream *json = json_new(HOMEKIT_JSONBUFFER_SIZE, client_send_chunk, context);\n\tjson_object_start(json);\n\tjson_string(json, \"characteristics\");\n\tjson_array_start(json);\n\n\t_id = id;\n\twhile ((ch_id = strsep(&_id, \",\"))) {\n\t\tchar *dot = strstr(ch_id, \".\");\n\t\t*dot = 0;\n\t\tuint32_t aid = atoi(ch_id);\n\t\tuint32_t iid = atoi(dot + 1);\n\n\t\tCLIENT_DEBUG(context, \"Requested characteristic info for %d.%d\", aid, iid);\n\t\thomekit_characteristic_t *ch = homekit_characteristic_by_aid_and_iid(\n\t\t\t\tcontext->server->config->accessories, aid, iid);\n\t\tif (!ch) {\n\t\t\twrite_characteristic_error(json, aid, iid, HAPStatus_NoResource);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!(ch->permissions & homekit_permissions_paired_read)) {\n\t\t\twrite_characteristic_error(json, aid, iid, HAPStatus_WriteOnly);\n\t\t\tcontinue;\n\t\t}\n\n\t\tjson_object_start(json);\n\t\twrite_characteristic_json(json, context, ch, format, NULL);\n\t\tif (!success) {\n\t\t\tjson_string(json, \"status\");\n\t\t\tjson_uint8(json, HAPStatus_Success);\n\t\t}\n\t\tjson_object_end(json);\n\t}\n\n\tjson_array_end(json);\n\tjson_object_end(json); // response\n\n\tjson_flush(json);\n\tjson_free(json);\n\n\tclient_send_chunk(NULL, 0, context);\n\n\tfree(id);\n}\n\nHAPStatus process_characteristics_update(const cJSON *j_ch, client_context_t *context) {\n\tcJSON *j_aid = cJSON_GetObjectItem(j_ch, \"aid\");\n\tif (!j_aid) {\n\t\tCLIENT_ERROR(context, \"Failed to process request: no \\\"aid\\\" field\");\n\t\treturn HAPStatus_NoResource;\n\t}\n\tif (j_aid->type != cJSON_Number) {\n\t\tCLIENT_ERROR(context, \"Failed to process request: \\\"aid\\\" field is not a number\");\n\t\treturn HAPStatus_NoResource;\n\t}\n\n\tcJSON *j_iid = cJSON_GetObjectItem(j_ch, \"iid\");\n\tif (!j_iid) {\n\t\tCLIENT_ERROR(context, \"Failed to process request: no \\\"iid\\\" field\");\n\t\treturn HAPStatus_NoResource;\n\t}\n\tif (j_iid->type != cJSON_Number) {\n\t\tCLIENT_ERROR(context, \"Failed to process request: \\\"iid\\\" field is not a number\");\n\t\treturn HAPStatus_NoResource;\n\t}\n\n\tuint32_t aid = (uint32_t)j_aid->valuedouble;//j_aid->valueint;\n\tuint32_t iid = (uint32_t)j_iid->valuedouble;//j_iid->valueint;\n\n\thomekit_characteristic_t *ch = homekit_characteristic_by_aid_and_iid(\n\t\t\tcontext->server->config->accessories, aid, iid);\n\tif (!ch) {\n\t\tCLIENT_ERROR(context,\n\t\t\t\t\"Failed to process request to update %u.%u: \" \"no such characteristic\", aid, iid);\n\t\treturn HAPStatus_NoResource;\n\t}\n\n\tcJSON *j_value = cJSON_GetObjectItem(j_ch, \"value\");\n\tif (j_value) {\n\t\thomekit_value_t h_value = HOMEKIT_NULL_CPP();\n\n\t\tif (!(ch->permissions & homekit_permissions_paired_write)) {\n\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: no write permission\", aid, iid);\n\t\t\treturn HAPStatus_ReadOnly;\n\t\t}\n\n\t\tswitch (ch->format) {\n\t\tcase homekit_format_bool: {\n\t\t\tbool value = false;\n\t\t\tif (j_value->type == cJSON_True) {\n\t\t\t\tvalue = true;\n\t\t\t} else if (j_value->type == cJSON_False) {\n\t\t\t\tvalue = false;\n\t\t\t} else if (j_value->type == cJSON_Number\n\t\t\t\t\t&& (j_value->valueint == 0 || j_value->valueint == 1)) {\n\t\t\t\tvalue = j_value->valueint == 1;\n\t\t\t} else {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not a boolean or 0/1\", aid,\n\t\t\t\t\t\tiid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tCLIENT_DEBUG(context, \"Updating characteristic %d.%d with boolean %s\", aid, iid, value ? \"true\" : \"false\");\n\n\t\t\th_value = HOMEKIT_BOOL_CPP(value);\n\t\t\tif (ch->setter_ex) {\n\t\t\t\tch->setter_ex(ch, h_value);\n\t\t\t} else {\n\t\t\t\tch->value = h_value;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase homekit_format_uint8:\n\t\t\tcase homekit_format_uint16:\n\t\t\tcase homekit_format_uint32:\n\t\t\tcase homekit_format_uint64:\n\t\t\tcase homekit_format_int: {\n\t\t\t// We accept boolean values here in order to fix a bug in HomeKit. HomeKit sometimes sends a boolean instead of an integer of value 0 or 1.\n\t\t\tif (j_value->type != cJSON_Number && j_value->type != cJSON_False\n\t\t\t\t\t&& j_value->type != cJSON_True) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not a number\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tdouble min_value = 0;\n\t\t\tdouble max_value = 0;\n\n\t\t\tswitch (ch->format) {\n\t\t\tcase homekit_format_uint8: {\n\t\t\t\tmin_value = 0;\n\t\t\t\tmax_value = 255;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint16: {\n\t\t\t\tmin_value = 0;\n\t\t\t\tmax_value = 65535;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint32: {\n\t\t\t\tmin_value = 0;\n\t\t\t\tmax_value = 4294967295;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_uint64: {\n\t\t\t\tmin_value = 0;\n\t\t\t\tmax_value = 18446744073709551615ULL;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase homekit_format_int: {\n\t\t\t\tmin_value = -2147483648;\n\t\t\t\tmax_value = 2147483647;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// Impossible, keeping to make compiler happy\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t}\n\n\t\t\tif (ch->min_value)\n\t\t\t\tmin_value = *ch->min_value;\n\t\t\tif (ch->max_value)\n\t\t\t\tmax_value = *ch->max_value;\n\n\t\t\tdouble value = j_value->valuedouble;\n\t\t\tif (value < min_value || value > max_value) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value %g is not in range %g..%g\",\n\t\t\t\t\t\taid, iid, value, min_value, max_value);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tif (ch->valid_values.count) {\n\t\t\t\tbool matches = false;\n\t\t\t\tint v = (int) value;\n\t\t\t\tfor (int i = 0; i < ch->valid_values.count; i++) {\n\t\t\t\t\tif (v == ch->valid_values.values[i]) {\n\t\t\t\t\t\tmatches = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!matches) {\n\t\t\t\t\tCLIENT_ERROR(context,\n\t\t\t\t\t\t\t\"Failed to update %d.%d: value is not one of valid values\", aid, iid);\n\t\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (ch->valid_values_ranges.count) {\n\t\t\t\tbool matches = false;\n\t\t\t\tfor (int i = 0; i < ch->valid_values_ranges.count; i++) {\n\t\t\t\t\tif (value >= ch->valid_values_ranges.ranges[i].start\n\t\t\t\t\t\t\t&& value <= ch->valid_values_ranges.ranges[i].end) {\n\t\t\t\t\t\tmatches = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!matches) {\n\t\t\t\t\tCLIENT_ERROR(context,\n\t\t\t\t\t\t\t\"Failed to update %d.%d: value is not in valid values range\", aid, iid);\n\t\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tCLIENT_DEBUG(context, \"Updating characteristic %d.%d with integer %g\", aid, iid, value);\n\n\t\t\tswitch (ch->format) {\n\t\t\tcase homekit_format_uint8:\n\t\t\t\th_value = HOMEKIT_UINT8_CPP(value);\n\t\t\t\tbreak;\n\t\t\tcase homekit_format_uint16:\n\t\t\t\th_value = HOMEKIT_UINT16_CPP(value);\n\t\t\t\tbreak;\n\t\t\tcase homekit_format_uint32:\n\t\t\t\th_value = HOMEKIT_UINT32_CPP(value);\n\t\t\t\tbreak;\n\t\t\tcase homekit_format_uint64:\n\t\t\t\th_value = HOMEKIT_UINT64_CPP(value);\n\t\t\t\tbreak;\n\t\t\tcase homekit_format_int:\n\t\t\t\th_value = HOMEKIT_INT_CPP(value);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tCLIENT_ERROR(context, \"Unexpected format when updating numeric value: %d\",\n\t\t\t\t\t\tch->format);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tif (ch->setter_ex) {\n\t\t\t\tch->setter_ex(ch, h_value);\n\t\t\t} else {\n\t\t\t\tch->value = h_value;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase homekit_format_float: {\n\t\t\tif (j_value->type != cJSON_Number) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not a number\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tfloat value = j_value->valuedouble;\n\t\t\tif ((ch->min_value && value < *ch->min_value)\n\t\t\t\t\t|| (ch->max_value && value > *ch->max_value)) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not in range\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tCLIENT_DEBUG(context, \"Updating characteristic %d.%d with %g\", aid, iid, value);\n\n\t\t\th_value = HOMEKIT_FLOAT_CPP(value);\n\t\t\tif (ch->setter_ex) {\n\t\t\t\tch->setter_ex(ch, h_value);\n\t\t\t} else {\n\t\t\t\tch->value = h_value;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase homekit_format_string: {\n\t\t\tif (j_value->type != cJSON_String) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not a string\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tint max_len = (ch->max_len) ? *ch->max_len : 64;\n\n\t\t\tchar *value = j_value->valuestring;\n\t\t\tif (strlen(value) > max_len) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is too long\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tCLIENT_DEBUG(context, \"Updating characteristic %d.%d with \\\"%s\\\"\", aid, iid, value);\n\n\t\t\th_value = HOMEKIT_STRING_CPP(value);\n\t\t\tif (ch->setter_ex) {\n\t\t\t\tch->setter_ex(ch, h_value);\n\t\t\t} else {\n\t\t\t\thomekit_value_destruct(&ch->value);\n\t\t\t\thomekit_value_copy(&ch->value, &h_value);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase homekit_format_tlv: {\n\t\t\tif (j_value->type != cJSON_String) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not a string\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tint max_len = (ch->max_len) ? *ch->max_len : 256;\n\n\t\t\tchar *value = j_value->valuestring;\n\t\t\tsize_t value_len = strlen(value);\n\t\t\tif (value_len > max_len) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is too long\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tsize_t tlv_size = base64_decoded_size((unsigned char*) value, value_len);\n\t\t\tbyte *tlv_data = (byte*) malloc(tlv_size);\n\t\t\tif (base64_decode_((byte*) value, value_len, tlv_data) < 0) {\n\t\t\t\tfree(tlv_data);\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: error Base64 decoding\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\ttlv_values_t *tlv_values = tlv_new();\n\t\t\tint r = tlv_parse(tlv_data, tlv_size, tlv_values);\n\t\t\tfree(tlv_data);\n\n\t\t\tif (r) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: error parsing TLV\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tCLIENT_DEBUG(context, \"Updating characteristic %d.%d with TLV:\", aid, iid);\n\t\t\tfor (tlv_t *t = tlv_values->head; t; t = t->next) {\n\t\t\t\tchar *escaped_payload = binary_to_string(t->value, t->size);\n\t\t\t\tCLIENT_DEBUG(context, \"  Type %d value (%d bytes): %s\", t->type, t->size, escaped_payload);\n\t\t\t\tfree(escaped_payload);\n\t\t\t}\n\n\t\t\th_value = HOMEKIT_TLV_CPP(tlv_values);\n\t\t\tif (ch->setter_ex) {\n\t\t\t\tch->setter_ex(ch, h_value);\n\t\t\t} else {\n\t\t\t\thomekit_value_destruct(&ch->value);\n\t\t\t\thomekit_value_copy(&ch->value, &h_value);\n\t\t\t}\n\n\t\t\ttlv_free(tlv_values);\n\t\t\tbreak;\n\t\t}\n\t\tcase homekit_format_data: {\n\t\t\tif (j_value->type != cJSON_String) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is not a string\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\t// Default max data len = 2,097,152 but that does not make sense\n\t\t\t// for this accessory\n\t\t\tint max_len = (ch->max_data_len) ? *ch->max_data_len : 4096;\n\n\t\t\tchar *value = j_value->valuestring;\n\t\t\tsize_t value_len = strlen(value);\n\t\t\tif (value_len > max_len) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: value is too long\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tsize_t data_size = base64_decoded_size((unsigned char*) value, value_len);\n\t\t\tbyte *data = (byte*) malloc(data_size);\n\t\t\tif (base64_decode_((byte*) value, value_len, data) < 0) {\n\t\t\t\tfree(data);\n\t\t\t\tCLIENT_ERROR(context, \"Failed to update %d.%d: error Base64 decoding\", aid, iid);\n\t\t\t\treturn HAPStatus_InvalidValue;\n\t\t\t}\n\n\t\t\tCLIENT_DEBUG(context, \"Updating characteristic %d.%d with Data:\", aid, iid);\n\n\t\t\th_value = HOMEKIT_DATA_CPP(data, data_size);\n\t\t\tif (ch->setter_ex) {\n\t\t\t\tch->setter_ex(ch, h_value);\n\t\t\t} else {\n\t\t\t\thomekit_value_destruct(&ch->value);\n\t\t\t\thomekit_value_copy(&ch->value, &h_value);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\t}\n\n\t\tif (!h_value.is_null) {\n\t\t\tcontext->current_characteristic = ch;\n\t\t\tcontext->current_value = &h_value;\n\n\t\t\thomekit_characteristic_notify(ch, h_value);\n\n\t\t\tcontext->current_characteristic = NULL;\n\t\t\tcontext->current_value = NULL;\n\t\t}\n\t}\n\n\tcJSON *j_events = cJSON_GetObjectItem(j_ch, \"ev\");\n\tif (j_events) {\n\t\tif (!(ch->permissions && homekit_permissions_notify)) {\n\t\t\tCLIENT_ERROR(context,\n\t\t\t\t\t\"Failed to set notification state for %d.%d: \" \"notifications are not supported\",\n\t\t\t\t\taid, iid);\n\t\t\treturn HAPStatus_NotificationsUnsupported;\n\t\t}\n\n\t\tif ((j_events->type != cJSON_True) && (j_events->type != cJSON_False)) {\n\t\t\tCLIENT_ERROR(context,\n\t\t\t\t\t\"Failed to set notification state for %d.%d: \" \"invalid state value\", aid, iid);\n\t\t}\n\n\t\tif (j_events->type == cJSON_True) {\n\t\t\thomekit_characteristic_add_notify_callback(ch, client_notify_characteristic, context);\n\t\t} else {\n\t\t\thomekit_characteristic_remove_notify_callback(ch, client_notify_characteristic,\n\t\t\t\t\tcontext);\n\t\t}\n\t}\n\n\treturn HAPStatus_Success;\n}\n\nvoid homekit_server_on_update_characteristics(client_context_t *context, const byte *data,\n\t\tsize_t size) {\n\tDEBUG_TIME_BEGIN();\n\tCLIENT_INFO(context, \"Update Characteristics\");DEBUG_HEAP();\n\n\tchar *data1 = strndup((char*) data, size);\n\tcJSON *json = cJSON_Parse(data1);\n\tfree(data1);\n\n\tif (!json) {\n\t\tCLIENT_ERROR(context, \"Failed to parse request JSON\");\n\t\tsend_json_error_response(context, 400, HAPStatus_InvalidValue);\n\t\treturn;\n\t}\n\n\tcJSON *characteristics = cJSON_GetObjectItem(json, \"characteristics\");\n\tif (!characteristics) {\n\t\tCLIENT_ERROR(context, \"Failed to parse request: no \\\"characteristics\\\" field\");\n\t\tcJSON_Delete(json);\n\t\tsend_json_error_response(context, 400, HAPStatus_InvalidValue);\n\t\treturn;\n\t}\n\tif (characteristics->type != cJSON_Array) {\n\t\tCLIENT_ERROR(context, \"Failed to parse request: \\\"characteristics\\\" field is not an list\");\n\t\tcJSON_Delete(json);\n\t\tsend_json_error_response(context, 400, HAPStatus_InvalidValue);\n\t\treturn;\n\t}\n\n\tHAPStatus *statuses = (HAPStatus*) malloc(\n\t\t\tsizeof(HAPStatus) * cJSON_GetArraySize(characteristics));\n\tbool has_errors = false;\n\n\tfor (int i = 0; i < cJSON_GetArraySize(characteristics); i++) {\n\n\t\tcJSON *j_ch = cJSON_GetArrayItem(characteristics, i);\n\n\t\tchar *s = cJSON_Print(j_ch);\n\t\tCLIENT_DEBUG(context, \"Processing element %s\", s);\n\t\tfree(s);\n\n\t\tstatuses[i] = process_characteristics_update(j_ch, context);\n\n\t\tif (statuses[i] != HAPStatus_Success)\n\t\t\thas_errors = true;\n\t}\n\n\tif (!has_errors) {\n\t\tCLIENT_DEBUG(context, \"There were no processing errors, sending No Content response\");\n\n\t\tsend_204_response(context);\n\t} else {\n\t\tCLIENT_DEBUG(context, \"There were processing errors, sending Multi-Status response\");\n\t\tclient_send_P(context, json_207_response_headers_progmem);\n\n\t\tjson_stream *json1 = json_new(HOMEKIT_JSONBUFFER_SIZE, client_send_chunk, context);\n\t\tjson_object_start(json1);\n\t\tjson_string(json1, \"characteristics\");\n\t\tjson_array_start(json1);\n\n\t\tfor (int i = 0; i < cJSON_GetArraySize(characteristics); i++) {\n\n\t\t\tcJSON *j_ch = cJSON_GetArrayItem(characteristics, i);\n\n\t\t\tjson_object_start(json1);\n\t\t\tjson_string(json1, \"aid\");\n\t\t\tjson_uint32(json1, cJSON_GetObjectItem(j_ch, \"aid\")->valuedouble);//->valueint);\n\t\t\tjson_string(json1, \"iid\");\n\t\t\tjson_uint32(json1, cJSON_GetObjectItem(j_ch, \"iid\")->valuedouble);//->valueint);\n\t\t\tjson_string(json1, \"status\");\n\t\t\tjson_uint8(json1, statuses[i]);\n\t\t\tjson_object_end(json1);\n\t\t}\n\n\t\tjson_array_end(json1);\n\t\tjson_object_end(json1); // response\n\n\t\tjson_flush(json1);\n\t\tjson_free(json1);\n\n\t\tclient_send_chunk(NULL, 0, context);\n\t}\n\n\tfree(statuses);\n\tcJSON_Delete(json);\n\tDEBUG_TIME_END(\"update_characteristics\");\n}\n\nvoid homekit_server_on_pairings(client_context_t *context, const byte *data, size_t size) {\n\tDEBUG(\"HomeKit Pairings\");DEBUG_HEAP();\n\n\t//context->step = HOMEKIT_CLIENT_STEP_PAIRINGS;\n\ttlv_values_t *message = tlv_new();\n\ttlv_parse(data, size, message);\n\n\tTLV_DEBUG(message);\n\n\tint r;\n\n\tif (tlv_get_integer_value(message, TLVType_State, -1) != 1) {\n\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\ttlv_free(message);\n\t\treturn;\n\t}\n\n\tswitch (tlv_get_integer_value(message, TLVType_Method, -1)) {\n\tcase TLVMethod_AddPairing: {\n\t\tCLIENT_INFO(context, \"Add Pairing\");\n\n\t\tif (!(context->permissions & pairing_permissions_admin)) {\n\t\t\tCLIENT_ERROR(context, \"Refusing to add pairing to non-admin controller\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_device_identifier = tlv_get_value(message, TLVType_Identifier);\n\t\tif (!tlv_device_identifier) {\n\t\t\tCLIENT_ERROR(context, \"Invalid add pairing request: no device identifier\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\t\ttlv_t *tlv_device_public_key = tlv_get_value(message, TLVType_PublicKey);\n\t\tif (!tlv_device_public_key) {\n\t\t\tCLIENT_ERROR(context, \"Invalid add pairing request: no device public key\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\t\tint device_permissions = tlv_get_integer_value(message, TLVType_Permissions, -1);\n\t\tif (device_permissions == -1) {\n\t\t\tCLIENT_ERROR(context, \"Invalid add pairing request: no device permissions\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\ted25519_key device_key;\n\t\tcrypto_ed25519_init(&device_key);\n\t\tr = crypto_ed25519_import_public_key(&device_key, tlv_device_public_key->value,\n\t\t\t\ttlv_device_public_key->size);\n\t\tif (r) {\n\t\t\tCLIENT_ERROR(context, \"Failed to import device public key\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tchar *device_identifier = strndup((const char*) tlv_device_identifier->value,\n\t\t\t\ttlv_device_identifier->size);\n\n\t\tpairing_t pairing;\n\t\tif (!homekit_storage_find_pairing(device_identifier, &pairing)) {\n\t\t\tsize_t pairing_public_key_size = 0;\n\t\t\tcrypto_ed25519_export_public_key(&pairing.device_key, NULL, &pairing_public_key_size);\n\n\t\t\tbyte *pairing_public_key = (byte*) malloc(pairing_public_key_size);\n\t\t\tr = crypto_ed25519_export_public_key(&pairing.device_key, pairing_public_key,\n\t\t\t\t\t&pairing_public_key_size);\n\t\t\tif (r) {\n\t\t\t\tCLIENT_ERROR(context,\n\t\t\t\t\t\t\"Failed to add pairing: error exporting pairing public key (code %d)\", r);\n\t\t\t\tfree(pairing_public_key);\n\t\t\t\tfree(device_identifier);\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t}\n\n\t\t\tif (pairing_public_key_size != tlv_device_public_key->size\n\t\t\t\t\t|| memcmp(tlv_device_public_key->value, pairing_public_key,\n\t\t\t\t\t\t\tpairing_public_key_size)) {\n\t\t\t\tCLIENT_ERROR(context,\n\t\t\t\t\t\t\"Failed to add pairing: pairing public key differs from given one\");\n\t\t\t\tfree(pairing_public_key);\n\t\t\t\tfree(device_identifier);\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t}\n\n\t\t\tfree(pairing_public_key);\n\n\t\t\tr = homekit_storage_update_pairing(device_identifier, device_permissions);\n\t\t\tif (r) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to add pairing: storage error (code %d)\", r);\n\t\t\t\tfree(device_identifier);\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tINFO(\"Updated pairing with %s\", device_identifier);\n\t\t} else {\n\t\t\tif (!homekit_storage_can_add_pairing()) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to add pairing: max peers\");\n\t\t\t\tfree(device_identifier);\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_MaxPeers);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tr = homekit_storage_add_pairing(device_identifier, &device_key, device_permissions);\n\t\t\tif (r) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to add pairing: storage error (code %d)\", r);\n\t\t\t\tfree(device_identifier);\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tINFO(\"Added pairing with %s\", device_identifier);\n\n\t\t\tHOMEKIT_NOTIFY_EVENT(context->server, HOMEKIT_EVENT_PAIRING_ADDED);\n\t\t}\n\n\t\tfree(device_identifier);\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 2);\n\n\t\tsend_tlv_response(context, response);\n\n\t\tbreak;\n\t}\n\tcase TLVMethod_RemovePairing: {\n\t\tCLIENT_INFO(context, \"Remove Pairing\");\n\n\t\tif (!(context->permissions & pairing_permissions_admin)) {\n\t\t\tCLIENT_ERROR(context, \"Refusing to remove pairing to non-admin controller\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_t *tlv_device_identifier = tlv_get_value(message, TLVType_Identifier);\n\t\tif (!tlv_device_identifier) {\n\t\t\tCLIENT_ERROR(context, \"Invalid remove pairing request: no device identifier\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\tbreak;\n\t\t}\n\n\t\tchar *device_identifier = strndup((const char*) tlv_device_identifier->value,\n\t\t\t\ttlv_device_identifier->size);\n\n\t\tpairing_t pairing;\n\t\tif (!homekit_storage_find_pairing(device_identifier, &pairing)) {\n\t\t\tbool is_admin = pairing.permissions & pairing_permissions_admin;\n\n\t\t\tr = homekit_storage_remove_pairing(device_identifier);\n\t\t\tif (r) {\n\t\t\t\tCLIENT_ERROR(context, \"Failed to remove pairing: storage error (code %d)\", r);\n\t\t\t\tfree(device_identifier);\n\t\t\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tINFO(\"Removed pairing with %s\", device_identifier);\n\n\t\t\tHOMEKIT_NOTIFY_EVENT(context->server, HOMEKIT_EVENT_PAIRING_REMOVED);\n\n\t\t\tclient_context_t *c = context->server->clients;\n\t\t\twhile (c) {\n\t\t\t\tif (c->pairing_id == pairing.id)\n\t\t\t\t\tc->disconnect = true;\n\t\t\t\tc = c->next;\n\t\t\t}\n\n\t\t\tif (is_admin) {\n\t\t\t\t// Removed pairing was admin,\n\t\t\t\t// check if there any other admins left.\n\t\t\t\t// If no admins left, enable pairing again\n\t\t\t\tbool admin_found = false;\n\n\t\t\t\tpairing_iterator_t pairing_it;\n\t\t\t\thomekit_storage_pairing_iterator_init(&pairing_it);\n\t\t\t\twhile ((!homekit_storage_next_pairing(&pairing_it, &pairing))) {\n\t\t\t\t\tif (pairing.permissions & pairing_permissions_admin) {\n\t\t\t\t\t\tadmin_found = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\thomekit_storage_pairing_iterator_done(&pairing_it);\n\n\t\t\t\tif (!admin_found) {\n\t\t\t\t\t// No admins left, enable pairing again\n\t\t\t\t\tINFO(\"Last admin pairing was removed, enabling pair setup\");\n\t\t\t\t\tcontext->server->paired = false;\n\t\t\t\t\t//homekit_setup_mdns(context->server);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfree(device_identifier);\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 2);\n\t\tsend_tlv_response(context, response);\n\n\t\tbreak;\n\t}\n\tcase TLVMethod_ListPairings: {\n\t\tCLIENT_INFO(context, \"List Pairings\");\n\n\t\tif (!(context->permissions & pairing_permissions_admin)) {\n\t\t\tCLIENT_INFO(context, \"Refusing to list pairings to non-admin controller\");\n\t\t\tsend_tlv_error_response(context, 2, TLVError_Authentication);\n\t\t\tbreak;\n\t\t}\n\n\t\ttlv_values_t *response = tlv_new();\n\t\ttlv_add_integer_value(response, TLVType_State, 1, 2);\n\n\t\tbool first = true;\n\n\t\tpairing_iterator_t it;\n\t\thomekit_storage_pairing_iterator_init(&it);\n\n\t\tpairing_t pairing;\n\n\t\tbyte public_key[32];\n\n\t\twhile (!homekit_storage_next_pairing(&it, &pairing)) {\n\t\t\tif (!first) {\n\t\t\t\ttlv_add_value(response, TLVType_Separator, NULL, 0);\n\t\t\t}\n\t\t\tsize_t public_key_size = sizeof(public_key);\n\t\t\tr = crypto_ed25519_export_public_key(&pairing.device_key, public_key, &public_key_size);\n\n\t\t\ttlv_add_string_value(response, TLVType_Identifier, pairing.device_id);\n\t\t\ttlv_add_value(response, TLVType_PublicKey, public_key, public_key_size);\n\t\t\ttlv_add_integer_value(response, TLVType_Permissions, 1, pairing.permissions);\n\n\t\t\tfirst = false;\n\t\t}\n\t\thomekit_storage_pairing_iterator_done(&it);\n\n\t\tsend_tlv_response(context, response);\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tsend_tlv_error_response(context, 2, TLVError_Unknown);\n\t\tbreak;\n\t}\n\t}\n\n\ttlv_free(message);\n}\n\nvoid homekit_server_on_reset(client_context_t *context) {\n\tINFO(\"Reset\");\n\n\thomekit_server_reset();\n\tsend_204_response(context);\n\n\t//vTaskDelay(3000 / portTICK_PERIOD_MS);\n\n\thomekit_system_restart();\n}\n\nvoid homekit_server_on_resource(client_context_t *context) {\n\tCLIENT_INFO(context, \"Resource\");DEBUG_HEAP();\n\n\tif (!context->server->config->on_resource) {\n\t\tsend_404_response(context);\n\t\treturn;\n\t}\n\n\tcontext->server->config->on_resource(context->body, context->body_length);\n}\n//=============================================\n// parse data\n//=============================================\n\nint homekit_server_on_url(http_parser *parser, const char *data, size_t length) {\n\tclient_context_t *context = (client_context_t*) parser->data;\n\n\tcontext->endpoint = HOMEKIT_ENDPOINT_UNKNOWN;\n\tif (parser->method == HTTP_PARSER_METHOD_GET) {\n\t\tif (!strncmp(data, \"/accessories\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_GET_ACCESSORIES;\n\t\t} else {\n\t\t\tstatic const char url[] = \"/characteristics\";\n\t\t\tsize_t url_len = sizeof(url) - 1;\n\n\t\t\tif (length >= url_len && !strncmp(data, url, url_len)\n\t\t\t\t\t&& (data[url_len] == 0 || data[url_len] == '?')) {\n\t\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_GET_CHARACTERISTICS;\n\t\t\t\tif (data[url_len] == '?') {\n\t\t\t\t\tchar *query = strndup(data + url_len + 1, length - url_len - 1);\n\t\t\t\t\tcontext->endpoint_params = query_params_parse(query);\n\t\t\t\t\tfree(query);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (parser->method == HTTP_PARSER_METHOD_POST) {\n\t\tif (!strncmp(data, \"/identify\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_IDENTIFY;\n\t\t} else if (!strncmp(data, \"/pair-setup\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_PAIR_SETUP;\n\t\t} else if (!strncmp(data, \"/pair-verify\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_PAIR_VERIFY;\n\t\t} else if (!strncmp(data, \"/pairings\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_PAIRINGS;\n\t\t} else if (!strncmp(data, \"/resource\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_RESOURCE;\n\t\t}\n\t} else if (parser->method == HTTP_PARSER_METHOD_PUT) {\n\t\tif (!strncmp(data, \"/characteristics\", length)) {\n\t\t\tcontext->endpoint = HOMEKIT_ENDPOINT_UPDATE_CHARACTERISTICS;\n\t\t}\n\t}\n\n\tif (context->endpoint == HOMEKIT_ENDPOINT_UNKNOWN) {\n\t\tchar *url = strndup(data, length);\n\t\t//TODO fix\n\t\t//ERROR(\"Unknown endpoint: %s %s\", http_method_str(parser->method), url);\n\t\tfree(url);\n\t}\n\n\treturn 0;\n}\n\nint homekit_server_on_body(http_parser *parser, const char *data, size_t length) {\n\tDEBUG(\"http_parser lenght=%d\", length);\n\tclient_context_t *context = (client_context_t*) parser->data;\n\tcontext->body = (char*) realloc(context->body, context->body_length + length + 1);\n\tmemcpy(context->body + context->body_length, data, length);\n\tcontext->body_length += length;\n\tcontext->body[context->body_length] = 0;\n\n\treturn 0;\n}\n\nint homekit_server_on_message_complete(http_parser *parser) {\n\tDEBUG(\"http_parser message_complete\");\n\tclient_context_t *context = (client_context_t*) parser->data;\n\n\tif (!context->encrypted) {\n\t\tswitch (context->endpoint) {\n\t\tcase HOMEKIT_ENDPOINT_PAIR_SETUP: {\n\t\t\thomekit_server_on_pair_setup(context, (const byte*) context->body,\n\t\t\t\t\tcontext->body_length);\n\t\t\tbreak;\n\t\t}\n\t\tcase HOMEKIT_ENDPOINT_PAIR_VERIFY: {\n\t\t\thomekit_server_on_pair_verify(context, (const byte*) context->body,\n\t\t\t\t\tcontext->body_length);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tDEBUG(\"Unknown endpoint\");\n\t\t\tsend_404_response(context);\n\t\t\tbreak;\n\t\t}\n\t\t}\n\t} else {\n\t\tswitch (context->endpoint) {\n\t\tcase HOMEKIT_ENDPOINT_IDENTIFY: {\n\t\t\thomekit_server_on_identify(context);\n\t\t\tbreak;\n\t\t}\n\t\tcase HOMEKIT_ENDPOINT_GET_ACCESSORIES: {\n\t\t\thomekit_server_on_get_accessories(context);\n\t\t\tbreak;\n\t\t}\n\t\tcase HOMEKIT_ENDPOINT_GET_CHARACTERISTICS: {\n\t\t\thomekit_server_on_get_characteristics(context);\n\t\t\tbreak;\n\t\t}\n\t\tcase HOMEKIT_ENDPOINT_UPDATE_CHARACTERISTICS: {\n\t\t\thomekit_server_on_update_characteristics(context, (const byte*) context->body,\n\t\t\t\t\tcontext->body_length);\n\t\t\tbreak;\n\t\t}\n\t\tcase HOMEKIT_ENDPOINT_PAIRINGS: {\n\t\t\thomekit_server_on_pairings(context, (const byte*) context->body, context->body_length);\n\t\t\tbreak;\n\t\t}\n\t\tcase HOMEKIT_ENDPOINT_RESOURCE: {\n\t\t\thomekit_server_on_resource(context);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tDEBUG(\"Unknown endpoint\");\n\t\t\tsend_404_response(context);\n\t\t\tbreak;\n\t\t}\n\t\t}\n\t}\n\n\tif (context->endpoint_params) {\n\t\tquery_params_free(context->endpoint_params);\n\t\tcontext->endpoint_params = NULL;\n\t}\n\n\tif (context->body) {\n\t\tfree(context->body);\n\t\tcontext->body = NULL;\n\t\tcontext->body_length = 0;\n\t}\n\treturn 0;\n}\n\nhttp_parser_settings make_http_parser_settings() {\n\thttp_parser_settings settings;\n\tsettings.on_url = homekit_server_on_url;\n\tsettings.on_body = homekit_server_on_body;\n\tsettings.on_message_complete = homekit_server_on_message_complete;\n\treturn settings;\n}\n\n//sorry, unimplemented: non-trivial designated initializers not supported\n//static http_parser_settings homekit_http_parser_settings = {\n//    .on_url = homekit_server_on_url,\n//    .on_body = homekit_server_on_body,\n//    .on_message_complete = homekit_server_on_message_complete,\n//};\n//点号+赋值符号\n//struct A a={.b = 1,.c = 2}; //c++ compiler dose not support\n//冒号\n//struct A a={b:1,c:2}；\nstatic http_parser_settings homekit_http_parser_settings = make_http_parser_settings();\n\nvoid homekit_client_process(client_context_t *context) {\n//    int data_len = read(\n//        context->socket,\n//        context->data+context->data_available,\n//        context->data_size-context->data_available\n//    );\n\tif (context->socket == nullptr) {\n\t\tCLIENT_ERROR(context, \"The socket is null\");\n\t\treturn;\n\t}\n\tint data_len = 0;\n\tint available_len = context->socket->available();  // optimistic_yield(100);\n\tif (available_len > 0) {\n\t\tint size = context->data_size - context->data_available;\n\t\tif (size > available_len) {\n\t\t\tsize = available_len;\n\t\t}\n\t\t// read or readBytes\n\t\tdata_len = context->socket->read(context->data + context->data_available, size);\n\t}\n\tif (data_len == 0) {\n\t\tif (!context->socket->connected()) {\n\t\t\tCLIENT_INFO(context, \"Disconnected!\");\n\t\t\tcontext->disconnect = true;\n\t\t\thomekit_server_close_client(context->server, context);\n\t\t}\n\t\treturn;\n\t}\n\tCLIENT_DEBUG(context, \"Got %d incomming data, encrypted is %s\",\n\t\t\tdata_len, context->encrypted ? \"true\" : \"false\");\n\tbyte *payload = (byte*) context->data;\n\tsize_t payload_size = (size_t) data_len;\n\n\tbyte *decrypted = NULL;\n\tsize_t decrypted_size = 0;\n\n\tif (context->encrypted) {\n\t\tCLIENT_DEBUG(context, \"Decrypting data\");\n\n\t\tclient_decrypt_(context, context->data, data_len, NULL, &decrypted_size);\n\n\t\tdecrypted = (byte*) malloc(decrypted_size);\n\t\tint r = client_decrypt_(context, context->data, data_len, decrypted, &decrypted_size);\n\n\t\tif (r < 0) {\n\t\t\tCLIENT_ERROR(context, \"Invalid client data\");\n\t\t\tfree(decrypted);\n\t\t\treturn;\n\t\t}\n\t\tcontext->data_available = data_len - r;\n\t\tif (r && context->data_available) {\n\t\t\tmemmove(context->data, &context->data[r], context->data_available);\n\t\t}\n\t\tCLIENT_DEBUG(context, \"Decrypted %d bytes, available %d\", decrypted_size, context->data_available);\n\n\t\tpayload = decrypted;\n\t\tpayload_size = decrypted_size;\n\t\tif (payload_size)\n\t\t\tprint_binary(\"Decrypted data\", payload, payload_size);\n\t} else {\n\t\tcontext->data_available = 0;\n\t}\n\n\tcurrent_client_context = context;\n\thttp_parser_execute(&context->parser, &homekit_http_parser_settings,\n\t\t\t(char*) payload, payload_size);\n\tcurrent_client_context = NULL;\n\n\tCLIENT_DEBUG(context, \"Finished processing\");\n\n\tif (decrypted) {\n\t\tfree(decrypted);\n\t}\n}\n\nvoid homekit_server_close_client(homekit_server_t *server, client_context_t *context) {\n\tCLIENT_INFO(context, \"Closing client connection\");\n\tcontext->step = HOMEKIT_CLIENT_STEP_END;\n\tserver->nfds--;\n\n\tif (context->socket) {\n\t\tcontext->socket->stop();\n\t\tCLIENT_DEBUG(context, \"The sockect is stopped\");\n\t\tdelete context->socket;\n\t\tcontext->socket = nullptr;\n\t}\n\tif (context->server->pairing_context && context->server->pairing_context->client == context) {\n\t\tpairing_context_free(context->server->pairing_context);\n\t\tcontext->server->pairing_context = NULL;\n\t\tCLIENT_INFO(context, \"Clear the pairing context\");\n\t}\n\n\tif (context->server->clients == context) {\n\t\tcontext->server->clients = context->next;\n\t} else {\n\t\tclient_context_t *c = context->server->clients;\n\t\twhile (c->next && c->next != context)\n\t\t\tc = c->next;\n\t\tif (c->next)\n\t\t\tc->next = c->next->next;\n\t}\n\n\thomekit_accessories_clear_notify_callbacks(context->server->config->accessories,\n\t\t\tclient_notify_characteristic, context);\n\n\tHOMEKIT_NOTIFY_EVENT(server, HOMEKIT_EVENT_CLIENT_DISCONNECTED);\n\n\tclient_context_free(context);\n}\n\nclient_context_t* homekit_server_accept_client(homekit_server_t *server) {\n\n\tif (!server->wifi_server) {\n\t\tERROR(\"The server's WiFiServer is NULL!\");\n\t\treturn NULL;\n\t}\n\tWiFiClient *wifiClient = nullptr;\n\n\tif (server->wifi_server->hasClient()) {\n\t\twifiClient = new WiFiClient(server->wifi_server->available());\n\t\tif (server->nfds >= HOMEKIT_MAX_CLIENTS) {\n\t\t\tINFO(\"No more room for client connections (max %d)\", HOMEKIT_MAX_CLIENTS);\n\t\t\twifiClient->stop();\n\t\t\tdelete wifiClient;\n\t\t\treturn NULL;\n\t\t}\n\t} else {\n\t\treturn NULL;\n\t}\n\n\tINFO(\"Got new client: local %s:%d, remote %s:%d\",\n\t\t\twifiClient->localIP().toString().c_str(), wifiClient->localPort(),\n\t\t\twifiClient->remoteIP().toString().c_str(), wifiClient->remotePort());\n\n\twifiClient->keepAlive(HOMEKIT_SOCKET_KEEPALIVE_IDLE_SEC,\n\tHOMEKIT_SOCKET_KEEPALIVE_INTERVAL_SEC, HOMEKIT_SOCKET_KEEPALIVE_IDLE_COUNT);\n\twifiClient->setNoDelay(true);\n\twifiClient->setSync(false);\n\twifiClient->setTimeout(HOMEKIT_SOCKET_TIMEOUT);\n\n\tclient_context_t *context = client_context_new(wifiClient);\n\tcontext->server = server;\n\tcontext->socket = wifiClient;\n\n\tcontext->next = server->clients;\n\tserver->clients = context;\n\n\tserver->nfds++;\n\n\tHOMEKIT_NOTIFY_EVENT(server, HOMEKIT_EVENT_CLIENT_CONNECTED);\n\n\treturn context;\n}\n\n//设备向iPhone传递characteristic的消息\nvoid homekit_server_process_notifications(homekit_server_t *server) {\n\tclient_context_t *context = server->clients;\n\t// 把characteristic_event_t拼接成client_event_t链表\n\t// 按照Apple的规定，Nofiy消息需合并发送\n\twhile (context) {\n\t\tif (context->step != HOMEKIT_CLIENT_STEP_PAIR_VERIFY_2OF2) {\n\t\t\t// Do not send event when the client is not verify over.\n\t\t\tcontext = context->next;\n\t\t\tcontinue;\n\t\t}\n\t\tcharacteristic_event_t *event = NULL;\n\t\tif (context->event_queue && q_pop(context->event_queue, &event)) {\n\t\t\t// Get and coalesce all client events\n\t\t\tclient_event_t *events_head = (client_event_t*) malloc(sizeof(client_event_t));\n\t\t\tevents_head->characteristic = event->characteristic;\n\t\t\thomekit_value_copy(&events_head->value, &event->value);\n\t\t\tevents_head->next = NULL;\n\n\t\t\thomekit_value_destruct(&event->value);\n\t\t\tfree(event);\n\n\t\t\tclient_event_t *events_tail = events_head;\n\n\t\t\twhile (q_pop(context->event_queue, &event)) {\n\t\t\t\t//q_pop第二个参数必须传指针的地址\n\t\t\t\t//event = context->event_queue->shift();\n\t\t\t\tclient_event_t *e = events_head;\n\t\t\t\twhile (e) {\n\t\t\t\t\tif (e->characteristic == event->characteristic) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\te = e->next;\n\t\t\t\t}\n\n\t\t\t\tif (e) {\n\t\t\t\t\thomekit_value_destruct(&e->value);\n\t\t\t\t} else {\n\t\t\t\t\te = (client_event_t*) malloc(sizeof(client_event_t));\n\t\t\t\t\te->characteristic = event->characteristic;\n\t\t\t\t\te->next = NULL;\n\n\t\t\t\t\tevents_tail->next = e;\n\t\t\t\t\tevents_tail = e;\n\t\t\t\t}\n\n\t\t\t\thomekit_value_copy(&e->value, &event->value);\n\n\t\t\t\thomekit_value_destruct(&event->value);\n\t\t\t\tfree(event);\n\t\t\t}\n\n\t\t\tsend_client_events(context, events_head);\n\n\t\t\tclient_event_t *e = events_head;\n\t\t\twhile (e) {\n\t\t\t\tclient_event_t *next = e->next;\n\n\t\t\t\thomekit_value_destruct(&e->value);\n\t\t\t\tfree(e);\n\n\t\t\t\te = next;\n\t\t\t}\n\t\t}\n\n\t\tcontext = context->next;\n\t}\n\n}\n\nbool homekit_client_need_process_data(client_context_t *context) {\n\tif (context) {\n\t\treturn (context->step >= HOMEKIT_CLIENT_STEP_PAIR_SETUP_1OF3\n\t\t\t\t&& context->step < HOMEKIT_CLIENT_STEP_PAIR_VERIFY_2OF2);\n\t}\n\treturn false;\n}\n\n//run in loop, include {accept_client, client_process, notifications}\nvoid homekit_server_process(homekit_server_t *server) {\n\n\thomekit_server_accept_client(server);\n\n\tclient_context_t *context = server->clients;\n\twhile (context) {\n\t\t//homekit_client_process includes {handle data and stop disconnected client}\n//\t\tdo{\n//\t\t\tif(homekit_client_need_process_data(context)){\n//\t\t\t\tCLIENT_INFO(context, \"Step is %d\", context->step);\n//\t\t\t}\n//\t\t\tdelay(10);\n\t\thomekit_client_process(context);\n//\t\t} while(homekit_client_need_process_data(context));\n\n\t\tcontext = context->next;\n\t}\n\thomekit_server_process_notifications(server);\n}\n\n//=====================================================\n// Arduino ESP8266 MDNS: call this funciton only once when WiFi STA is connected!\n//=====================================================\nbool homekit_mdns_started = false;\n\nvoid homekit_mdns_init(homekit_server_t *server) {\n\tINFO(\"Configuring MDNS\");\n\n\tif (!WiFi.isConnected()) {\n\t\treturn;\n\t}\n\n\tIPAddress staIP = WiFi.localIP();\n\tif (!staIP.isSet()) {\n\t\treturn;\n\t}\n\n\thomekit_accessory_t *accessory = server->config->accessories[0];\n\thomekit_service_t *accessory_info = homekit_service_by_type(accessory,\n\tHOMEKIT_SERVICE_ACCESSORY_INFORMATION);\n\tif (!accessory_info) {\n\t\tERROR(\"Invalid accessory declaration: no Accessory Information service\");\n\t\treturn;\n\t}\n\n\thomekit_characteristic_t *name = homekit_service_characteristic_by_type(accessory_info,\n\tHOMEKIT_CHARACTERISTIC_NAME);\n\tif (!name) {\n\t\tERROR(\"Invalid accessory declaration: \" \"no Name characteristic in AccessoryInfo service\");\n\t\treturn;\n\t}\n\n\thomekit_characteristic_t *model = homekit_service_characteristic_by_type(accessory_info,\n\tHOMEKIT_CHARACTERISTIC_MODEL);\n\tif (!model) {\n\t\tERROR(\"Invalid accessory declaration: \" \"no Model characteristic in AccessoryInfo service\");\n\t\treturn;\n\t}\n\n\tif (homekit_mdns_started) {\n\t\tMDNS.close();\n\t\tMDNS.begin(name->value.string_value, staIP);\n\t\tINFO(\"MDNS restart: %s, IP: %s\", name->value.string_value, staIP.toString().c_str());\n\t\tMDNS.announce();\n\t\treturn;\n\t}\n\n\t//homekit_mdns_configure_init(name->value.string_value, PORT);\n\tWiFi.hostname(name->value.string_value);\n\t// Must specify the MDNS runs on the IP of STA\n\tMDNS.begin(name->value.string_value, staIP);\n\tINFO(\"MDNS begin: %s, IP: %s\", name->value.string_value, staIP.toString().c_str());\n\n\tMDNSResponder::hMDNSService mdns_service = MDNS.addService(name->value.string_value,\n\tHOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, HOMEKIT_SERVER_PORT);\n\t// Set a service specific callback for dynamic service TXT items.\n\t// The callback is called, whenever service TXT items are needed for the given service.\n\tMDNS.setDynamicServiceTxtCallback(mdns_service,\n\t\t\t[](const MDNSResponder::hMDNSService p_hService) {\n\t\t\t\tDEBUG(\"MDNS call DynamicServiceTxtCallback\");\n\t\t\t\tif (running_server) {\n\t\t\t\t\tMDNS.addDynamicServiceTxt(p_hService, \"sf\",\n\t\t\t\t\t\t\t(running_server->paired) ? \"0\" : \"1\");\n\t\t\t\t\tMDNS.addDynamicServiceTxt(p_hService, \"c#\",\n\t\t\t\t\t\t\trunning_server->config->config_number);\n\t\t\t\t}\n\n\t\t\t}\n\t);\n\tMDNS.addServiceTxt(mdns_service, \"md\", model->value.string_value);\n\tMDNS.addServiceTxt(mdns_service, \"pv\", \"1.0\");\n\tMDNS.addServiceTxt(mdns_service, \"id\", server->accessory_id);\n\t//\"c#\" is a DynamicServiceTxt\n\t//Current configuration number. Required.\n\t//Must update when an accessory, service, or characteristic is added or removed on the accessory server.\n\t//Accessories must increment the config number after a firmware update.\n\t//This must have a range of 1-65535 and wrap to 1 when it overflows.\n\t//This value must persist across reboots, power cycles, etc.\n\t//MDNS.addServiceTxt(mdns_service, \"c#\", String(server->config->config_number).c_str());\n\tMDNS.addServiceTxt(mdns_service, \"s#\", \"1\");\n\tMDNS.addServiceTxt(mdns_service, \"ff\", \"0\");\n\t//\"sf\" is a DynamicServiceTxt\n\t//MDNS.addServiceTxt(HAP_SERVICE, HOMEKIT_MDNS_PROTO, \"sf\", (server->paired) ? \"0\" : \"1\");\n\tMDNS.addServiceTxt(mdns_service, \"ci\", String(server->config->category).c_str());\n\n\t/*\n\t // accessory model name (required)\n\t homekit_mdns_add_txt(\"md\", \"%s\", model->value.string_value);\n\t // protocol version (required)\n\t homekit_mdns_add_txt(\"pv\", \"1.0\");\n\t // device ID (required)\n\t // should be in format XX:XX:XX:XX:XX:XX, otherwise devices will ignore it\n\t homekit_mdns_add_txt(\"id\", \"%s\", server->accessory_id);\n\t // current configuration number (required)\n\t homekit_mdns_add_txt(\"c#\", \"%d\", server->config->config_number);\n\t // current state number (required)\n\t homekit_mdns_add_txt(\"s#\", \"1\");\n\t // feature flags (required if non-zero)\n\t //   bit 0 - supports HAP pairing. required for all HomeKit accessories\n\t //   bits 1-7 - reserved\n\t homekit_mdns_add_txt(\"ff\", \"0\");\n\t // status flags\n\t //   bit 0 - not paired\n\t //   bit 1 - not configured to join WiFi\n\t //   bit 2 - problem detected on accessory\n\t //   bits 3-7 - reserved\n\t homekit_mdns_add_txt(\"sf\", \"%d\", (server->paired) ? 0 : 1);\n\t // accessory category identifier\n\t homekit_mdns_add_txt(\"ci\", \"%d\", server->config->category);*/\n\n\tif (server->config->setupId) {\n\t\tDEBUG(\"Accessory Setup ID = %s\", server->config->setupId);\n\n\t\tsize_t data_size = strlen(server->config->setupId) + strlen(server->accessory_id) + 1;\n\t\tchar *data = (char*) malloc(data_size);\n\t\tsnprintf(data, data_size, \"%s%s\", server->config->setupId, server->accessory_id);\n\t\tdata[data_size - 1] = 0;\n\n\t\tunsigned char shaHash[SHA512_DIGEST_SIZE];\n\t\twc_Sha512Hash((const unsigned char*) data, data_size - 1, shaHash);\n\n\t\tfree(data);\n\n\t\tunsigned char encodedHash[9];\n\t\tmemset(encodedHash, 0, sizeof(encodedHash));\n\t\tword32 len = sizeof(encodedHash);\n\t\tbase64_encode_((const unsigned char*) shaHash, 4, encodedHash);\n\t\tMDNS.addServiceTxt(mdns_service, \"sh\", (char*) encodedHash);\n\t}\n\n\tMDNS.announce();\n\tMDNS.update();\n\thomekit_mdns_started = true;\n\t//INFO(\"MDNS ok! Open your \\\"Home\\\" app, click \\\"Add or Scan Accessory\\\"\"\n\t//\t\t\" and \\\"I Don't Have a Code\\\". \\nThis Accessory will show on your iOS device.\");\n}\n\n// Used to update the config_number (\"c#\" value of Bonjour)\n// Call this function when an accessory, service, or characteristic is added or removed on the accessory server.\n// See the official HAP specification for more information.\nvoid homekit_update_config_number() {\n\tif(!homekit_mdns_started) {\n\t\treturn ;\n\t}\n\tif(!running_server){\n\t\treturn;\n\t}\n\t// range of 1-65535\n\tuint16_t c = running_server->config->config_number;\n\tc = (c > 0 && c < 65535) ? (c + 1) : 1;\n\trunning_server->config->config_number = c;\n\tMDNS.announce();\n\tMDNS.update();\n\tINFO(\"Update config_number to %u\", c);\n}\n\nint homekit_accessory_id_generate(char *accessory_id) {\n\tbyte buf[6];\n\thomekit_random_fill(buf, sizeof(buf));\n\n\tsnprintf(accessory_id, ACCESSORY_ID_SIZE + 1, \"%02X:%02X:%02X:%02X:%02X:%02X\", buf[0], buf[1],\n\t\t\tbuf[2], buf[3], buf[4], buf[5]);\n\n\tINFO(\"Generated new accessory ID: %s\", accessory_id);\n\treturn 0;\n}\n\nint homekit_accessory_key_generate(ed25519_key *key) {\n\tint r = crypto_ed25519_generate(key);\n\tif (r) {\n\t\tERROR(\"Failed to generate accessory key\");\n\t\treturn r;\n\t}\n\n\tINFO(\"Generated new accessory key\");\n\n\treturn 0;\n}\n\nvoid homekit_server_init(homekit_server_config_t *config) {\n\tif (!config->accessories) {\n\t\tERROR(\"Error initializing HomeKit accessory server: \"\n\t\t\t\t\"accessories are not specified\");\n\t\treturn;\n\t}\n\n\tif (!config->password && !config->password_callback) {\n\t\tERROR(\"Error initializing HomeKit accessory server: \"\n\t\t\t\t\"neither password nor password callback is specified\");\n\t\treturn;\n\t}\n\n\tif (config->password) {\n\t\tconst char *p = config->password;\n\t\tif (strlen(p) != 10\n\t\t\t\t|| !(ISDIGIT(p[0]) && ISDIGIT(p[1]) && ISDIGIT(p[2]) && p[3] == '-' && ISDIGIT(p[4])\n\t\t\t\t\t\t&& ISDIGIT(p[5]) && p[6] == '-' && ISDIGIT(p[7]) && ISDIGIT(p[8])\n\t\t\t\t\t\t&& ISDIGIT(p[9]))) {\n\t\t\tERROR(\"Error initializing HomeKit accessory server: \" \"invalid password format\");\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (config->setupId) {\n\t\tconst char *p = config->setupId;\n\t\tif (strlen(p) != 4\n\t\t\t\t|| !(ISBASE36(p[0]) && ISBASE36(p[1]) && ISBASE36(p[2]) && ISBASE36(p[3]))) {\n\t\t\tERROR(\"Error initializing HomeKit accessory server: \" \"invalid setup ID format\");\n\t\t\treturn;\n\t\t}\n\t}\n\n\thomekit_accessories_init(config->accessories);\n\tif (!config->config_number) {\n\t\tconfig->config_number = config->accessories[0]->config_number;\n\t\tif (!config->config_number) {\n\t\t\tconfig->config_number = 1;\n\t\t}\n\t}\n\tif (!config->category) {\n\t\tconfig->category = config->accessories[0]->category;\n\t}\n\thomekit_server_t *server = server_new();\n\trunning_server = server;\n\tserver->config = config;\n\n\t//homekit_server_task(server);\n\tINFO(\"Starting server\");\n\n\tint r = homekit_storage_init();\n\tif (r == 0) {\n\t\tr = homekit_storage_load_accessory_id(server->accessory_id);\n\n\t\tif (!r)\n\t\t\tr = homekit_storage_load_accessory_key(&server->accessory_key);\n\t}\n\n\tif (r) {\n\t\tif (r < 0) {\n\t\t\tINFO(\"Resetting HomeKit storage\");\n\t\t\thomekit_storage_reset();\n\t\t}\n\n\t\thomekit_accessory_id_generate(server->accessory_id);\n\t\thomekit_storage_save_accessory_id(server->accessory_id);\n\n\t\thomekit_accessory_key_generate(&server->accessory_key);\n\t\thomekit_storage_save_accessory_key(&server->accessory_key);\n\t} else {\n\t\tINFO(\"Using existing accessory ID: %s\", server->accessory_id);\n\t}\n\n\tpairing_iterator_t pairing_it;\n\thomekit_storage_pairing_iterator_init(&pairing_it);\n\n\tpairing_t pairing;\n\twhile (!homekit_storage_next_pairing(&pairing_it, &pairing)) {\n\t\tif (pairing.permissions & pairing_permissions_admin) {\n\t\t\tINFO(\"Found admin pairing with %s, disabling pair setup\", pairing.device_id);\n\t\t\tserver->paired = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\thomekit_storage_pairing_iterator_done(&pairing_it);\n\n\tif (!server->paired) {\n\t\tif (!arduino_homekit_preinit(server)) {\n\t\t\tERROR(\"Error in arduino_homekit_preinit, please check and retry\");\n\t\t\tsystem_restart();\n\t\t\treturn;\n\t\t}\n\t}\n\n\thomekit_mdns_init(server);\n\tHOMEKIT_NOTIFY_EVENT(server, HOMEKIT_EVENT_SERVER_INITIALIZED);\n\thomekit_server_process(server);\n\n\tINFO(\"Init server over\");\n}\n\nvoid homekit_server_reset() {\n\thomekit_storage_reset();\n}\n\nbool homekit_is_paired() {\n\tbool paired = false;\n\n\tpairing_iterator_t pairing_it;\n\thomekit_storage_pairing_iterator_init(&pairing_it);\n\n\tpairing_t pairing;\n\twhile (!homekit_storage_next_pairing(&pairing_it, &pairing)) {\n\t\tif (pairing.permissions & pairing_permissions_admin) {\n\t\t\tpaired = true;\n\t\t\tbreak;\n\t\t}\n\t};\n\thomekit_storage_pairing_iterator_done(&pairing_it);\n\n\treturn paired;\n}\n\nint homekit_get_accessory_id(char *buffer, size_t size) {\n\tif (size < ACCESSORY_ID_SIZE + 1)\n\t\treturn -1;\n\n\tint r = homekit_storage_load_accessory_id(buffer);\n\tif (r)\n\t\treturn r;\n\n\treturn 0;\n}\n\nint homekit_get_setup_uri(const homekit_server_config_t *config, char *buffer, size_t buffer_size) {\n\tstatic const char base36Table[] = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\n\tif (buffer_size < 20)\n\t\treturn -1;\n\n\tif (!config->password)\n\t\treturn -1;\n\t// TODO: validate password in case it is run beffore server is started\n\n\tif (!config->setupId)\n\t\treturn -1;\n\t// TODO: validate setupID in case it is run beffore server is started\n\n\thomekit_accessory_t *accessory = homekit_accessory_by_id(config->accessories, 1);\n\tif (!accessory)\n\t\treturn -1;\n\n\tuint32_t setup_code = 0;\n\tfor (const char *s = config->password; *s; s++) {\n\t\tif (ISDIGIT(*s)) {\n\t\t\tsetup_code = setup_code * 10 + *s - '0';\n\t\t}\n\t}\n\n\tuint64_t payload = 0;\n\n\tpayload <<= 4;  // reserved 4 bits\n\n\tpayload <<= 8;\n\tpayload |= accessory->category & 0xff;\n\n\tpayload <<= 4;\n\tpayload |= 2;  // flags (2=IP, 4=BLE, 8=IP_WAC)\n\n\tpayload <<= 27;\n\tpayload |= setup_code & 0x7fffffff;\n\n\tstrcpy(buffer, \"X-HM://\");\n\tbuffer += 7;\n\tfor (int i = 8; i >= 0; i--) {\n\t\tbuffer[i] = base36Table[payload % 36];\n\t\tpayload /= 36;\n\t}\n\tbuffer += 9;\n\n\tstrcpy(buffer, config->setupId);\n\tbuffer += 4;\n\n\tbuffer[0] = 0;\n\n\treturn 0;\n}\n\n// Pre-initialize the pairing_context used in Pair-Setep 1/3\n// For avoiding timeout caused sockect disconnection from iOS device.\nbool arduino_homekit_preinit(homekit_server_t *server) {\n\tif (saved_preinit_pairing_context != nullptr) {\n\t\treturn true;\n\t}\n\tINFO(\"Preiniting pairing context\");\n\tpairing_context_t *preinit_pairing_context = pairing_context_new();\n\tDEBUG_HEAP();\n\tchar password[11];\n\tif (server->config->password) {\n\t\tstrncpy(password, server->config->password, sizeof(password));\n\t\t//CLIENT_DEBUG(context, \"Using user-specified password: %s\", password);\n\t\tINFO(\"Using user-specified password: %s\", password);\n\t} else {\n\t\tfor (int i = 0; i < 10; i++) {\n\t\t\tpassword[i] = homekit_random() % 10 + '0';\n\t\t}\n\t\tpassword[3] = password[6] = '-';\n\t\tpassword[10] = 0;\n\t\t//CLIENT_DEBUG(context, \"Using random password: %s\", password);\n\t\tINFO(\"Using random password: %s\", password);\n\t}\n\n\tif (server->config->password_callback) {\n\t\tserver->config->password_callback(password);\n\t}\n\n\twatchdog_disable_all();\n\twatchdog_check_begin();\n\tcrypto_srp_init(preinit_pairing_context->srp, \"Pair-Setup\", password);\n\twatchdog_check_end(\"crypto_srp_init\");  // 6585ms\n\twatchdog_enable_all();\n\n\tdelay(10);\n\n\tif (preinit_pairing_context->public_key) {\n\t\tfree(preinit_pairing_context->public_key);\n\t\tpreinit_pairing_context->public_key = NULL;\n\t}\n\tpreinit_pairing_context->public_key_size = 0;\n\tcrypto_srp_get_public_key(preinit_pairing_context->srp, NULL,\n\t\t\t&preinit_pairing_context->public_key_size);\n\n\tpreinit_pairing_context->public_key = (byte*) malloc(preinit_pairing_context->public_key_size);\n\n\twatchdog_disable_all();\n\twatchdog_check_begin();\n\tint r = crypto_srp_get_public_key(preinit_pairing_context->srp,\n\t\t\tpreinit_pairing_context->public_key, &preinit_pairing_context->public_key_size);\n\twatchdog_check_end(\"crypto_srp_get_public_key\");  // 3310ms\n\twatchdog_enable_all();\n\n\tdelay(10);\n\n\tif (r) {\n\t\t//CLIENT_ERROR(context, \"Failed to dump SPR public key (code %d)\", r);\n\t\tERROR(\"Failed to dump SPR public key (code %d)\");\n\t\tpairing_context_free(preinit_pairing_context);\n\t\tpreinit_pairing_context = NULL;\n\t\t// In preinit, we should not send response\n\t\t// send_tlv_error_response(context, 2, TLVError_Unknown);\n\t\treturn false;\n\t}\n\tsaved_preinit_pairing_context = preinit_pairing_context;\n\n\tINFO(\"Preinit pairing context success\");\n\tMDNS.announce();\t\t// update \"paired\" state\n\treturn true;\n}\n\nvoid arduino_homekit_setup(homekit_server_config_t *config) {\n\tif (system_get_cpu_freq() != SYS_CPU_160MHZ) {\n\t\tsystem_update_cpu_freq(SYS_CPU_160MHZ);\n\t\tINFO(\"Update the CPU to run at 160MHz\");\n\t}\n\n\thomekit_server_init(config);\n\t// The MDNS needs to be restarted when WiFi is connected to confirm the\n\t// MDNS runs at the IPAddress of STA\n\t// otherwise the iOS will not show the Accessory\n\tarduino_homekit_gotiphandler = WiFi.onStationModeGotIP([](WiFiEventStationModeGotIP gotip) {\n\t\tINFO(\"WiFi connected, ip: %s, mask: %s, gw: %s\",\n\t\t\t\tgotip.ip.toString().c_str(), gotip.mask.toString().c_str(),\n\t\t\t\tgotip.gw.toString().c_str());\n\t\tif (running_server) {\n\t\t\thomekit_mdns_init(running_server);\n\t\t} else {\n\t\t\tERROR(\"running_server is NULL!\");\n\t\t}\n\t});\n}\n\nvoid arduino_homekit_loop() {\n\tif (homekit_mdns_started) {\n\t\tMDNS.update();\n\t}\n\tif (running_server != nullptr) {\n\t\tif (!running_server->paired) {\n\t\t\t//If not paired or pairing was removed, preinit paring context.\n\t\t\tarduino_homekit_preinit(running_server);\n\t\t}\n\t\thomekit_server_process(running_server);\n\t}\n}\n\nint arduino_homekit_connected_clients_count() {\n\tif (running_server) {\n\t\treturn running_server->nfds;\n\t}\n\treturn -1;\n}\n\nhomekit_server_t* arduino_homekit_get_running_server() {\n\treturn running_server;\n}\n#endif\n"
  },
  {
    "path": "src/base64.c",
    "content": "#include \"base64.h\"\n\nstatic unsigned char base64_chars[] = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\nunsigned char base64_encode_char(unsigned char c) {\n  return base64_chars[c];\n}\n\nunsigned char base64_decode_char(unsigned char c) {\n  if (c >= 'A' && c <= 'Z')\n    return c - 'A';\n  if (c >= 'a' && c <= 'z')\n    return c - 'a' + 26;\n  if (c >= '0' && c <= '9')\n    return c - '0' + 52;\n  if (c == '+')\n    return 62;\n  if (c == '/')\n    return 63;\n  if (c == '=')\n    return 64;\n\n  return 0;\n}\n\nsize_t base64_encoded_size(const unsigned char *data, size_t size) {\n  return (size + 2)/3*4;\n}\n\nsize_t base64_decoded_size(const unsigned char *encoded_data, size_t encoded_size) {\n  size_t size = (encoded_size + 3)/4*3;\n  if (encoded_data[encoded_size-1] == '=')\n      size--;\n  if (encoded_data[encoded_size-2] == '=')\n      size--;\n  return size;\n}\n\nint base64_encode_(const unsigned char* data, size_t size, unsigned char *encoded_data) {\n  size_t i=0, j=0, size1=size - size%3;\n  for (; i<size1; i+=3, j+=4) {\n    encoded_data[j+0] = base64_encode_char(data[i+0]>>2);\n    encoded_data[j+1] = base64_encode_char(((data[i+0]&0x3)<<4) + (data[i+1]>>4));\n    encoded_data[j+2] = base64_encode_char(((data[i+1]&0xF)<<2) + (data[i+2]>>6));\n    encoded_data[j+3] = base64_encode_char(data[i+2]&0x3F);\n  }\n\n  if (size % 3 == 1) {\n    encoded_data[j+0] = base64_encode_char(data[i+0]>>2);\n    encoded_data[j+1] = base64_encode_char((data[i+0]&0x3)<<4);\n    encoded_data[j+2] = encoded_data[j+3] = '=';\n    j += 4;\n  } else if (size % 3 == 2) {\n    encoded_data[j+0] = base64_encode_char(data[i+0]>>2);\n    encoded_data[j+1] = base64_encode_char(((data[i+0]&0x3)<<4) + (data[i+1]>>4));\n    encoded_data[j+2] = base64_encode_char(((data[i+1]&0xF)<<2));\n    encoded_data[j+3] = '=';\n    j += 4;\n  }\n\n  return j;\n}\n\nint base64_decode_(const unsigned char* encoded_data, size_t encoded_size, unsigned char *data) {\n  if (encoded_size % 4 != 0)\n    return -1;\n\n  size_t i=0, j=0;\n  for (; i<encoded_size; i+=4) {\n    unsigned char block[4];\n    for (size_t k=0; k<4; k++)\n      block[k] = base64_decode_char(encoded_data[i+k]);\n\n    data[j++] = (block[0]<<2) + (block[1]>>4);\n    if (block[2] == 64)\n      break;\n\n    data[j++] = ((block[1]&0xF)<<4) + (block[2]>>2);\n    if (block[3] == 64)\n      break;\n\n    data[j++] = ((block[2]&0x3)<<6) + block[3];\n  }\n\n  return j;\n}\n\n"
  },
  {
    "path": "src/base64.h",
    "content": "#pragma once\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stddef.h>\n\n\nsize_t base64_encoded_size(const unsigned char* data, size_t size);\nsize_t base64_decoded_size(const unsigned char* encoded_data, size_t encoded_size);\n//multiple definition of `base64_decode';\nint base64_encode_(const unsigned char* data, size_t data_size, unsigned char *encoded_data);\nint base64_decode_(const unsigned char* encoded_data, size_t encoded_size, unsigned char *data);\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "src/cJSON.c",
    "content": "/*\n  Copyright (c) 2009-2017 Dave Gamble and cJSON contributors\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files (the \"Software\"), to deal\n  in the Software without restriction, including without limitation the rights\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n  copies of the Software, and to permit persons to whom the Software is\n  furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  THE SOFTWARE.\n*/\n\n/* cJSON */\n/* JSON parser in C. */\n\n/* disable warnings about old C89 functions in MSVC */\n#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)\n#define _CRT_SECURE_NO_DEPRECATE\n#endif\n\n#ifdef __GNUC__\n#pragma GCC visibility push(default)\n#endif\n#if defined(_MSC_VER)\n#pragma warning (push)\n/* disable warning about single line comments in system headers */\n#pragma warning (disable : 4001)\n#endif\n\n#include <string.h>\n#include <stdio.h>\n#include <math.h>\n#include <stdlib.h>\n#include <limits.h>\n#include <ctype.h>\n\n#ifdef ENABLE_LOCALES\n#include <locale.h>\n#endif\n\n#if defined(_MSC_VER)\n#pragma warning (pop)\n#endif\n#ifdef __GNUC__\n#pragma GCC visibility pop\n#endif\n\n#include \"cJSON.h\"\n\n/* define our own boolean type */\n#ifdef true\n#undef true\n#endif\n#define true ((cJSON_bool)1)\n\n#ifdef false\n#undef false\n#endif\n#define false ((cJSON_bool)0)\n\ntypedef struct {\n    const unsigned char *json;\n    size_t position;\n} error;\nstatic error global_error = { NULL, 0 };\n\nCJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)\n{\n    return (const char*) (global_error.json + global_error.position);\n}\n\nCJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) {\n    if (!cJSON_IsString(item)) {\n        return NULL;\n    }\n\n    return item->valuestring;\n}\n\n/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */\n#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 12)\n    #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.\n#endif\n\nCJSON_PUBLIC(const char*) cJSON_Version(void)\n{\n    static char version[15];\n    sprintf(version, \"%i.%i.%i\", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);\n\n    return version;\n}\n\n/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */\nstatic int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)\n{\n    if ((string1 == NULL) || (string2 == NULL))\n    {\n        return 1;\n    }\n\n    if (string1 == string2)\n    {\n        return 0;\n    }\n\n    for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)\n    {\n        if (*string1 == '\\0')\n        {\n            return 0;\n        }\n    }\n\n    return tolower(*string1) - tolower(*string2);\n}\n\ntypedef struct internal_hooks\n{\n    void *(CJSON_CDECL *allocate)(size_t size);\n    void (CJSON_CDECL *deallocate)(void *pointer);\n    void *(CJSON_CDECL *reallocate)(void *pointer, size_t size);\n} internal_hooks;\n\n#if defined(_MSC_VER)\n/* work around MSVC error C2322: '...' address of dllimport '...' is not static */\nstatic void * CJSON_CDECL internal_malloc(size_t size)\n{\n    return malloc(size);\n}\nstatic void CJSON_CDECL internal_free(void *pointer)\n{\n    free(pointer);\n}\nstatic void * CJSON_CDECL internal_realloc(void *pointer, size_t size)\n{\n    return realloc(pointer, size);\n}\n#else\n#define internal_malloc malloc\n#define internal_free free\n#define internal_realloc realloc\n#endif\n\n/* strlen of character literals resolved at compile time */\n#define static_strlen(string_literal) (sizeof(string_literal) - sizeof(\"\"))\n\nstatic internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };\n\nstatic unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)\n{\n    size_t length = 0;\n    unsigned char *copy = NULL;\n\n    if (string == NULL)\n    {\n        return NULL;\n    }\n\n    length = strlen((const char*)string) + sizeof(\"\");\n    copy = (unsigned char*)hooks->allocate(length);\n    if (copy == NULL)\n    {\n        return NULL;\n    }\n    memcpy(copy, string, length);\n\n    return copy;\n}\n\nCJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)\n{\n    if (hooks == NULL)\n    {\n        /* Reset hooks */\n        global_hooks.allocate = malloc;\n        global_hooks.deallocate = free;\n        global_hooks.reallocate = realloc;\n        return;\n    }\n\n    global_hooks.allocate = malloc;\n    if (hooks->malloc_fn != NULL)\n    {\n        global_hooks.allocate = hooks->malloc_fn;\n    }\n\n    global_hooks.deallocate = free;\n    if (hooks->free_fn != NULL)\n    {\n        global_hooks.deallocate = hooks->free_fn;\n    }\n\n    /* use realloc only if both free and malloc are used */\n    global_hooks.reallocate = NULL;\n    if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))\n    {\n        global_hooks.reallocate = realloc;\n    }\n}\n\n/* Internal constructor. */\nstatic cJSON *cJSON_New_Item(const internal_hooks * const hooks)\n{\n    cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON));\n    if (node)\n    {\n        memset(node, '\\0', sizeof(cJSON));\n    }\n\n    return node;\n}\n\n/* Delete a cJSON structure. */\nCJSON_PUBLIC(void) cJSON_Delete(cJSON *item)\n{\n    cJSON *next = NULL;\n    while (item != NULL)\n    {\n        next = item->next;\n        if (!(item->type & cJSON_IsReference) && (item->child != NULL))\n        {\n            cJSON_Delete(item->child);\n        }\n        if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))\n        {\n            global_hooks.deallocate(item->valuestring);\n        }\n        if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))\n        {\n            global_hooks.deallocate(item->string);\n        }\n        global_hooks.deallocate(item);\n        item = next;\n    }\n}\n\n/* get the decimal point character of the current locale */\nstatic unsigned char get_decimal_point(void)\n{\n#ifdef ENABLE_LOCALES\n    struct lconv *lconv = localeconv();\n    return (unsigned char) lconv->decimal_point[0];\n#else\n    return '.';\n#endif\n}\n\ntypedef struct\n{\n    const unsigned char *content;\n    size_t length;\n    size_t offset;\n    size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */\n    internal_hooks hooks;\n} parse_buffer;\n\n/* check if the given size is left to read in a given parse buffer (starting with 1) */\n#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))\n/* check if the buffer can be accessed at the given index (starting with 0) */\n#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))\n#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))\n/* get a pointer to the buffer at the position */\n#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)\n\n/* Parse the input text to generate a number, and populate the result into item. */\nstatic cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)\n{\n    double number = 0;\n    unsigned char *after_end = NULL;\n    unsigned char number_c_string[64];\n    unsigned char decimal_point = get_decimal_point();\n    size_t i = 0;\n\n    if ((input_buffer == NULL) || (input_buffer->content == NULL))\n    {\n        return false;\n    }\n\n    /* copy the number into a temporary buffer and replace '.' with the decimal point\n     * of the current locale (for strtod)\n     * This also takes care of '\\0' not necessarily being available for marking the end of the input */\n    for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)\n    {\n        switch (buffer_at_offset(input_buffer)[i])\n        {\n            case '0':\n            case '1':\n            case '2':\n            case '3':\n            case '4':\n            case '5':\n            case '6':\n            case '7':\n            case '8':\n            case '9':\n            case '+':\n            case '-':\n            case 'e':\n            case 'E':\n                number_c_string[i] = buffer_at_offset(input_buffer)[i];\n                break;\n\n            case '.':\n                number_c_string[i] = decimal_point;\n                break;\n\n            default:\n                goto loop_end;\n        }\n    }\nloop_end:\n    number_c_string[i] = '\\0';\n\n    number = strtod((const char*)number_c_string, (char**)&after_end);\n    if (number_c_string == after_end)\n    {\n        return false; /* parse_error */\n    }\n\n    item->valuedouble = number;\n\n    /* use saturation in case of overflow */\n    if (number >= INT_MAX)\n    {\n        item->valueint = INT_MAX;\n    }\n    else if (number <= (double)INT_MIN)\n    {\n        item->valueint = INT_MIN;\n    }\n    else\n    {\n        item->valueint = (int)number;\n    }\n\n    item->type = cJSON_Number;\n\n    input_buffer->offset += (size_t)(after_end - number_c_string);\n    return true;\n}\n\n/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */\nCJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)\n{\n    if (number >= INT_MAX)\n    {\n        object->valueint = INT_MAX;\n    }\n    else if (number <= (double)INT_MIN)\n    {\n        object->valueint = INT_MIN;\n    }\n    else\n    {\n        object->valueint = (int)number;\n    }\n\n    return object->valuedouble = number;\n}\n\ntypedef struct\n{\n    unsigned char *buffer;\n    size_t length;\n    size_t offset;\n    size_t depth; /* current nesting depth (for formatted printing) */\n    cJSON_bool noalloc;\n    cJSON_bool format; /* is this print a formatted print */\n    internal_hooks hooks;\n} printbuffer;\n\n/* realloc printbuffer if necessary to have at least \"needed\" bytes more */\nstatic unsigned char* ensure(printbuffer * const p, size_t needed)\n{\n    unsigned char *newbuffer = NULL;\n    size_t newsize = 0;\n\n    if ((p == NULL) || (p->buffer == NULL))\n    {\n        return NULL;\n    }\n\n    if ((p->length > 0) && (p->offset >= p->length))\n    {\n        /* make sure that offset is valid */\n        return NULL;\n    }\n\n    if (needed > INT_MAX)\n    {\n        /* sizes bigger than INT_MAX are currently not supported */\n        return NULL;\n    }\n\n    needed += p->offset + 1;\n    if (needed <= p->length)\n    {\n        return p->buffer + p->offset;\n    }\n\n    if (p->noalloc) {\n        return NULL;\n    }\n\n    /* calculate new buffer size */\n    if (needed > (INT_MAX / 2))\n    {\n        /* overflow of int, use INT_MAX if possible */\n        if (needed <= INT_MAX)\n        {\n            newsize = INT_MAX;\n        }\n        else\n        {\n            return NULL;\n        }\n    }\n    else\n    {\n        newsize = needed * 2;\n    }\n\n    if (p->hooks.reallocate != NULL)\n    {\n        /* reallocate with realloc if available */\n        newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);\n        if (newbuffer == NULL)\n        {\n            p->hooks.deallocate(p->buffer);\n            p->length = 0;\n            p->buffer = NULL;\n\n            return NULL;\n        }\n    }\n    else\n    {\n        /* otherwise reallocate manually */\n        newbuffer = (unsigned char*)p->hooks.allocate(newsize);\n        if (!newbuffer)\n        {\n            p->hooks.deallocate(p->buffer);\n            p->length = 0;\n            p->buffer = NULL;\n\n            return NULL;\n        }\n        if (newbuffer)\n        {\n            memcpy(newbuffer, p->buffer, p->offset + 1);\n        }\n        p->hooks.deallocate(p->buffer);\n    }\n    p->length = newsize;\n    p->buffer = newbuffer;\n\n    return newbuffer + p->offset;\n}\n\n/* calculate the new length of the string in a printbuffer and update the offset */\nstatic void update_offset(printbuffer * const buffer)\n{\n    const unsigned char *buffer_pointer = NULL;\n    if ((buffer == NULL) || (buffer->buffer == NULL))\n    {\n        return;\n    }\n    buffer_pointer = buffer->buffer + buffer->offset;\n\n    buffer->offset += strlen((const char*)buffer_pointer);\n}\n\n/* securely comparison of floating-point variables */\nstatic cJSON_bool compare_double(double a, double b)\n{\n    return (fabs(a - b) <= CJSON_DOUBLE_PRECISION);\n}\n\n/* Render the number nicely from the given item into a string. */\nstatic cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)\n{\n    unsigned char *output_pointer = NULL;\n    double d = item->valuedouble;\n    int length = 0;\n    size_t i = 0;\n    unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */\n    unsigned char decimal_point = get_decimal_point();\n    double test = 0.0;\n\n    if (output_buffer == NULL)\n    {\n        return false;\n    }\n\n    /* This checks for NaN and Infinity */\n    if ((d * 0) != 0)\n    {\n        length = sprintf((char*)number_buffer, \"null\");\n    }\n    else\n    {\n        /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */\n        length = sprintf((char*)number_buffer, \"%1.15g\", d);\n\n        /* Check whether the original double can be recovered */\n        if ((sscanf((char*)number_buffer, \"%lg\", &test) != 1) || !compare_double((double)test, d))\n        {\n            /* If not, print with 17 decimal places of precision */\n            length = sprintf((char*)number_buffer, \"%1.17g\", d);\n        }\n    }\n\n    /* sprintf failed or buffer overrun occurred */\n    if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))\n    {\n        return false;\n    }\n\n    /* reserve appropriate space in the output */\n    output_pointer = ensure(output_buffer, (size_t)length + sizeof(\"\"));\n    if (output_pointer == NULL)\n    {\n        return false;\n    }\n\n    /* copy the printed number to the output and replace locale\n     * dependent decimal point with '.' */\n    for (i = 0; i < ((size_t)length); i++)\n    {\n        if (number_buffer[i] == decimal_point)\n        {\n            output_pointer[i] = '.';\n            continue;\n        }\n\n        output_pointer[i] = number_buffer[i];\n    }\n    output_pointer[i] = '\\0';\n\n    output_buffer->offset += (size_t)length;\n\n    return true;\n}\n\n/* parse 4 digit hexadecimal number */\nstatic unsigned parse_hex4(const unsigned char * const input)\n{\n    unsigned int h = 0;\n    size_t i = 0;\n\n    for (i = 0; i < 4; i++)\n    {\n        /* parse digit */\n        if ((input[i] >= '0') && (input[i] <= '9'))\n        {\n            h += (unsigned int) input[i] - '0';\n        }\n        else if ((input[i] >= 'A') && (input[i] <= 'F'))\n        {\n            h += (unsigned int) 10 + input[i] - 'A';\n        }\n        else if ((input[i] >= 'a') && (input[i] <= 'f'))\n        {\n            h += (unsigned int) 10 + input[i] - 'a';\n        }\n        else /* invalid */\n        {\n            return 0;\n        }\n\n        if (i < 3)\n        {\n            /* shift left to make place for the next nibble */\n            h = h << 4;\n        }\n    }\n\n    return h;\n}\n\n/* converts a UTF-16 literal to UTF-8\n * A literal can be one or two sequences of the form \\uXXXX */\nstatic unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer)\n{\n    long unsigned int codepoint = 0;\n    unsigned int first_code = 0;\n    const unsigned char *first_sequence = input_pointer;\n    unsigned char utf8_length = 0;\n    unsigned char utf8_position = 0;\n    unsigned char sequence_length = 0;\n    unsigned char first_byte_mark = 0;\n\n    if ((input_end - first_sequence) < 6)\n    {\n        /* input ends unexpectedly */\n        goto fail;\n    }\n\n    /* get the first utf16 sequence */\n    first_code = parse_hex4(first_sequence + 2);\n\n    /* check that the code is valid */\n    if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))\n    {\n        goto fail;\n    }\n\n    /* UTF16 surrogate pair */\n    if ((first_code >= 0xD800) && (first_code <= 0xDBFF))\n    {\n        const unsigned char *second_sequence = first_sequence + 6;\n        unsigned int second_code = 0;\n        sequence_length = 12; /* \\uXXXX\\uXXXX */\n\n        if ((input_end - second_sequence) < 6)\n        {\n            /* input ends unexpectedly */\n            goto fail;\n        }\n\n        if ((second_sequence[0] != '\\\\') || (second_sequence[1] != 'u'))\n        {\n            /* missing second half of the surrogate pair */\n            goto fail;\n        }\n\n        /* get the second utf16 sequence */\n        second_code = parse_hex4(second_sequence + 2);\n        /* check that the code is valid */\n        if ((second_code < 0xDC00) || (second_code > 0xDFFF))\n        {\n            /* invalid second half of the surrogate pair */\n            goto fail;\n        }\n\n\n        /* calculate the unicode codepoint from the surrogate pair */\n        codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF));\n    }\n    else\n    {\n        sequence_length = 6; /* \\uXXXX */\n        codepoint = first_code;\n    }\n\n    /* encode as UTF-8\n     * takes at maximum 4 bytes to encode:\n     * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */\n    if (codepoint < 0x80)\n    {\n        /* normal ascii, encoding 0xxxxxxx */\n        utf8_length = 1;\n    }\n    else if (codepoint < 0x800)\n    {\n        /* two bytes, encoding 110xxxxx 10xxxxxx */\n        utf8_length = 2;\n        first_byte_mark = 0xC0; /* 11000000 */\n    }\n    else if (codepoint < 0x10000)\n    {\n        /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */\n        utf8_length = 3;\n        first_byte_mark = 0xE0; /* 11100000 */\n    }\n    else if (codepoint <= 0x10FFFF)\n    {\n        /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */\n        utf8_length = 4;\n        first_byte_mark = 0xF0; /* 11110000 */\n    }\n    else\n    {\n        /* invalid unicode codepoint */\n        goto fail;\n    }\n\n    /* encode as utf8 */\n    for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--)\n    {\n        /* 10xxxxxx */\n        (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF);\n        codepoint >>= 6;\n    }\n    /* encode first byte */\n    if (utf8_length > 1)\n    {\n        (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF);\n    }\n    else\n    {\n        (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F);\n    }\n\n    *output_pointer += utf8_length;\n\n    return sequence_length;\n\nfail:\n    return 0;\n}\n\n/* Parse the input text into an unescaped cinput, and populate item. */\nstatic cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer)\n{\n    const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;\n    const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;\n    unsigned char *output_pointer = NULL;\n    unsigned char *output = NULL;\n\n    /* not a string */\n    if (buffer_at_offset(input_buffer)[0] != '\\\"')\n    {\n        goto fail;\n    }\n\n    {\n        /* calculate approximate size of the output (overestimate) */\n        size_t allocation_length = 0;\n        size_t skipped_bytes = 0;\n        while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\\\"'))\n        {\n            /* is escape sequence */\n            if (input_end[0] == '\\\\')\n            {\n                if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length)\n                {\n                    /* prevent buffer overflow when last input character is a backslash */\n                    goto fail;\n                }\n                skipped_bytes++;\n                input_end++;\n            }\n            input_end++;\n        }\n        if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\\\"'))\n        {\n            goto fail; /* string ended unexpectedly */\n        }\n\n        /* This is at most how much we need for the output */\n        allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes;\n        output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof(\"\"));\n        if (output == NULL)\n        {\n            goto fail; /* allocation failure */\n        }\n    }\n\n    output_pointer = output;\n    /* loop through the string literal */\n    while (input_pointer < input_end)\n    {\n        if (*input_pointer != '\\\\')\n        {\n            *output_pointer++ = *input_pointer++;\n        }\n        /* escape sequence */\n        else\n        {\n            unsigned char sequence_length = 2;\n            if ((input_end - input_pointer) < 1)\n            {\n                goto fail;\n            }\n\n            switch (input_pointer[1])\n            {\n                case 'b':\n                    *output_pointer++ = '\\b';\n                    break;\n                case 'f':\n                    *output_pointer++ = '\\f';\n                    break;\n                case 'n':\n                    *output_pointer++ = '\\n';\n                    break;\n                case 'r':\n                    *output_pointer++ = '\\r';\n                    break;\n                case 't':\n                    *output_pointer++ = '\\t';\n                    break;\n                case '\\\"':\n                case '\\\\':\n                case '/':\n                    *output_pointer++ = input_pointer[1];\n                    break;\n\n                /* UTF-16 literal */\n                case 'u':\n                    sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer);\n                    if (sequence_length == 0)\n                    {\n                        /* failed to convert UTF16-literal to UTF-8 */\n                        goto fail;\n                    }\n                    break;\n\n                default:\n                    goto fail;\n            }\n            input_pointer += sequence_length;\n        }\n    }\n\n    /* zero terminate the output */\n    *output_pointer = '\\0';\n\n    item->type = cJSON_String;\n    item->valuestring = (char*)output;\n\n    input_buffer->offset = (size_t) (input_end - input_buffer->content);\n    input_buffer->offset++;\n\n    return true;\n\nfail:\n    if (output != NULL)\n    {\n        input_buffer->hooks.deallocate(output);\n    }\n\n    if (input_pointer != NULL)\n    {\n        input_buffer->offset = (size_t)(input_pointer - input_buffer->content);\n    }\n\n    return false;\n}\n\n/* Render the cstring provided to an escaped version that can be printed. */\nstatic cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer)\n{\n    const unsigned char *input_pointer = NULL;\n    unsigned char *output = NULL;\n    unsigned char *output_pointer = NULL;\n    size_t output_length = 0;\n    /* numbers of additional characters needed for escaping */\n    size_t escape_characters = 0;\n\n    if (output_buffer == NULL)\n    {\n        return false;\n    }\n\n    /* empty string */\n    if (input == NULL)\n    {\n        output = ensure(output_buffer, sizeof(\"\\\"\\\"\"));\n        if (output == NULL)\n        {\n            return false;\n        }\n        strcpy((char*)output, \"\\\"\\\"\");\n\n        return true;\n    }\n\n    /* set \"flag\" to 1 if something needs to be escaped */\n    for (input_pointer = input; *input_pointer; input_pointer++)\n    {\n        switch (*input_pointer)\n        {\n            case '\\\"':\n            case '\\\\':\n            case '\\b':\n            case '\\f':\n            case '\\n':\n            case '\\r':\n            case '\\t':\n                /* one character escape sequence */\n                escape_characters++;\n                break;\n            default:\n                if (*input_pointer < 32)\n                {\n                    /* UTF-16 escape sequence uXXXX */\n                    escape_characters += 5;\n                }\n                break;\n        }\n    }\n    output_length = (size_t)(input_pointer - input) + escape_characters;\n\n    output = ensure(output_buffer, output_length + sizeof(\"\\\"\\\"\"));\n    if (output == NULL)\n    {\n        return false;\n    }\n\n    /* no characters have to be escaped */\n    if (escape_characters == 0)\n    {\n        output[0] = '\\\"';\n        memcpy(output + 1, input, output_length);\n        output[output_length + 1] = '\\\"';\n        output[output_length + 2] = '\\0';\n\n        return true;\n    }\n\n    output[0] = '\\\"';\n    output_pointer = output + 1;\n    /* copy the string */\n    for (input_pointer = input; *input_pointer != '\\0'; (void)input_pointer++, output_pointer++)\n    {\n        if ((*input_pointer > 31) && (*input_pointer != '\\\"') && (*input_pointer != '\\\\'))\n        {\n            /* normal character, copy */\n            *output_pointer = *input_pointer;\n        }\n        else\n        {\n            /* character needs to be escaped */\n            *output_pointer++ = '\\\\';\n            switch (*input_pointer)\n            {\n                case '\\\\':\n                    *output_pointer = '\\\\';\n                    break;\n                case '\\\"':\n                    *output_pointer = '\\\"';\n                    break;\n                case '\\b':\n                    *output_pointer = 'b';\n                    break;\n                case '\\f':\n                    *output_pointer = 'f';\n                    break;\n                case '\\n':\n                    *output_pointer = 'n';\n                    break;\n                case '\\r':\n                    *output_pointer = 'r';\n                    break;\n                case '\\t':\n                    *output_pointer = 't';\n                    break;\n                default:\n                    /* escape and print as unicode codepoint */\n                    sprintf((char*)output_pointer, \"u%04x\", *input_pointer);\n                    output_pointer += 4;\n                    break;\n            }\n        }\n    }\n    output[output_length + 1] = '\\\"';\n    output[output_length + 2] = '\\0';\n\n    return true;\n}\n\n/* Invoke print_string_ptr (which is useful) on an item. */\nstatic cJSON_bool print_string(const cJSON * const item, printbuffer * const p)\n{\n    return print_string_ptr((unsigned char*)item->valuestring, p);\n}\n\n/* Predeclare these prototypes. */\nstatic cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer);\nstatic cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer);\nstatic cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer);\nstatic cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer);\nstatic cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer);\nstatic cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer);\n\n/* Utility to jump whitespace and cr/lf */\nstatic parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)\n{\n    if ((buffer == NULL) || (buffer->content == NULL))\n    {\n        return NULL;\n    }\n\n    while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))\n    {\n       buffer->offset++;\n    }\n\n    if (buffer->offset == buffer->length)\n    {\n        buffer->offset--;\n    }\n\n    return buffer;\n}\n\n/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */\nstatic parse_buffer *skip_utf8_bom(parse_buffer * const buffer)\n{\n    if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0))\n    {\n        return NULL;\n    }\n\n    if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), \"\\xEF\\xBB\\xBF\", 3) == 0))\n    {\n        buffer->offset += 3;\n    }\n\n    return buffer;\n}\n\n/* Parse an object - create a new root, and populate. */\nCJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)\n{\n    parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };\n    cJSON *item = NULL;\n\n    /* reset error position */\n    global_error.json = NULL;\n    global_error.position = 0;\n\n    if (value == NULL)\n    {\n        goto fail;\n    }\n\n    buffer.content = (const unsigned char*)value;\n    buffer.length = strlen((const char*)value) + sizeof(\"\");\n    buffer.offset = 0;\n    buffer.hooks = global_hooks;\n\n    item = cJSON_New_Item(&global_hooks);\n    if (item == NULL) /* memory fail */\n    {\n        goto fail;\n    }\n\n    if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer))))\n    {\n        /* parse failure. ep is set. */\n        goto fail;\n    }\n\n    /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */\n    if (require_null_terminated)\n    {\n        buffer_skip_whitespace(&buffer);\n        if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\\0')\n        {\n            goto fail;\n        }\n    }\n    if (return_parse_end)\n    {\n        *return_parse_end = (const char*)buffer_at_offset(&buffer);\n    }\n\n    return item;\n\nfail:\n    if (item != NULL)\n    {\n        cJSON_Delete(item);\n    }\n\n    if (value != NULL)\n    {\n        error local_error;\n        local_error.json = (const unsigned char*)value;\n        local_error.position = 0;\n\n        if (buffer.offset < buffer.length)\n        {\n            local_error.position = buffer.offset;\n        }\n        else if (buffer.length > 0)\n        {\n            local_error.position = buffer.length - 1;\n        }\n\n        if (return_parse_end != NULL)\n        {\n            *return_parse_end = (const char*)local_error.json + local_error.position;\n        }\n\n        global_error = local_error;\n    }\n\n    return NULL;\n}\n\n/* Default options for cJSON_Parse */\nCJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value)\n{\n    return cJSON_ParseWithOpts(value, 0, 0);\n}\n\n#define cjson_min(a, b) ((a < b) ? a : b)\n\nstatic unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks)\n{\n    static const size_t default_buffer_size = 256;\n    printbuffer buffer[1];\n    unsigned char *printed = NULL;\n\n    memset(buffer, 0, sizeof(buffer));\n\n    /* create buffer */\n    buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size);\n    buffer->length = default_buffer_size;\n    buffer->format = format;\n    buffer->hooks = *hooks;\n    if (buffer->buffer == NULL)\n    {\n        goto fail;\n    }\n\n    /* print the value */\n    if (!print_value(item, buffer))\n    {\n        goto fail;\n    }\n    update_offset(buffer);\n\n    /* check if reallocate is available */\n    if (hooks->reallocate != NULL)\n    {\n        printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);\n        if (printed == NULL) {\n            goto fail;\n        }\n        buffer->buffer = NULL;\n    }\n    else /* otherwise copy the JSON over to a new buffer */\n    {\n        printed = (unsigned char*) hooks->allocate(buffer->offset + 1);\n        if (printed == NULL)\n        {\n            goto fail;\n        }\n        memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));\n        printed[buffer->offset] = '\\0'; /* just to be sure */\n\n        /* free the buffer */\n        hooks->deallocate(buffer->buffer);\n    }\n\n    return printed;\n\nfail:\n    if (buffer->buffer != NULL)\n    {\n        hooks->deallocate(buffer->buffer);\n    }\n\n    if (printed != NULL)\n    {\n        hooks->deallocate(printed);\n    }\n\n    return NULL;\n}\n\n/* Render a cJSON item/entity/structure to text. */\nCJSON_PUBLIC(char *) cJSON_Print(const cJSON *item)\n{\n    return (char*)print(item, true, &global_hooks);\n}\n\nCJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item)\n{\n    return (char*)print(item, false, &global_hooks);\n}\n\nCJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)\n{\n    printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };\n\n    if (prebuffer < 0)\n    {\n        return NULL;\n    }\n\n    p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer);\n    if (!p.buffer)\n    {\n        return NULL;\n    }\n\n    p.length = (size_t)prebuffer;\n    p.offset = 0;\n    p.noalloc = false;\n    p.format = fmt;\n    p.hooks = global_hooks;\n\n    if (!print_value(item, &p))\n    {\n        global_hooks.deallocate(p.buffer);\n        return NULL;\n    }\n\n    return (char*)p.buffer;\n}\n\nCJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format)\n{\n    printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };\n\n    if ((length < 0) || (buffer == NULL))\n    {\n        return false;\n    }\n\n    p.buffer = (unsigned char*)buffer;\n    p.length = (size_t)length;\n    p.offset = 0;\n    p.noalloc = true;\n    p.format = format;\n    p.hooks = global_hooks;\n\n    return print_value(item, &p);\n}\n\n/* Parser core - when encountering text, process appropriately. */\nstatic cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer)\n{\n    if ((input_buffer == NULL) || (input_buffer->content == NULL))\n    {\n        return false; /* no input */\n    }\n\n    /* parse the different types of values */\n    /* null */\n    if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), \"null\", 4) == 0))\n    {\n        item->type = cJSON_NULL;\n        input_buffer->offset += 4;\n        return true;\n    }\n    /* false */\n    if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), \"false\", 5) == 0))\n    {\n        item->type = cJSON_False;\n        input_buffer->offset += 5;\n        return true;\n    }\n    /* true */\n    if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), \"true\", 4) == 0))\n    {\n        item->type = cJSON_True;\n        item->valueint = 1;\n        input_buffer->offset += 4;\n        return true;\n    }\n    /* string */\n    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\\\"'))\n    {\n        return parse_string(item, input_buffer);\n    }\n    /* number */\n    if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9'))))\n    {\n        return parse_number(item, input_buffer);\n    }\n    /* array */\n    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '['))\n    {\n        return parse_array(item, input_buffer);\n    }\n    /* object */\n    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{'))\n    {\n        return parse_object(item, input_buffer);\n    }\n\n    return false;\n}\n\n/* Render a value to text. */\nstatic cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer)\n{\n    unsigned char *output = NULL;\n\n    if ((item == NULL) || (output_buffer == NULL))\n    {\n        return false;\n    }\n\n    switch ((item->type) & 0xFF)\n    {\n        case cJSON_NULL:\n            output = ensure(output_buffer, 5);\n            if (output == NULL)\n            {\n                return false;\n            }\n            strcpy((char*)output, \"null\");\n            return true;\n\n        case cJSON_False:\n            output = ensure(output_buffer, 6);\n            if (output == NULL)\n            {\n                return false;\n            }\n            strcpy((char*)output, \"false\");\n            return true;\n\n        case cJSON_True:\n            output = ensure(output_buffer, 5);\n            if (output == NULL)\n            {\n                return false;\n            }\n            strcpy((char*)output, \"true\");\n            return true;\n\n        case cJSON_Number:\n            return print_number(item, output_buffer);\n\n        case cJSON_Raw:\n        {\n            size_t raw_length = 0;\n            if (item->valuestring == NULL)\n            {\n                return false;\n            }\n\n            raw_length = strlen(item->valuestring) + sizeof(\"\");\n            output = ensure(output_buffer, raw_length);\n            if (output == NULL)\n            {\n                return false;\n            }\n            memcpy(output, item->valuestring, raw_length);\n            return true;\n        }\n\n        case cJSON_String:\n            return print_string(item, output_buffer);\n\n        case cJSON_Array:\n            return print_array(item, output_buffer);\n\n        case cJSON_Object:\n            return print_object(item, output_buffer);\n\n        default:\n            return false;\n    }\n}\n\n/* Build an array from input text. */\nstatic cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer)\n{\n    cJSON *head = NULL; /* head of the linked list */\n    cJSON *current_item = NULL;\n\n    if (input_buffer->depth >= CJSON_NESTING_LIMIT)\n    {\n        return false; /* to deeply nested */\n    }\n    input_buffer->depth++;\n\n    if (buffer_at_offset(input_buffer)[0] != '[')\n    {\n        /* not an array */\n        goto fail;\n    }\n\n    input_buffer->offset++;\n    buffer_skip_whitespace(input_buffer);\n    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']'))\n    {\n        /* empty array */\n        goto success;\n    }\n\n    /* check if we skipped to the end of the buffer */\n    if (cannot_access_at_index(input_buffer, 0))\n    {\n        input_buffer->offset--;\n        goto fail;\n    }\n\n    /* step back to character in front of the first element */\n    input_buffer->offset--;\n    /* loop through the comma separated array elements */\n    do\n    {\n        /* allocate next item */\n        cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));\n        if (new_item == NULL)\n        {\n            goto fail; /* allocation failure */\n        }\n\n        /* attach next item to list */\n        if (head == NULL)\n        {\n            /* start the linked list */\n            current_item = head = new_item;\n        }\n        else\n        {\n            /* add to the end and advance */\n            current_item->next = new_item;\n            new_item->prev = current_item;\n            current_item = new_item;\n        }\n\n        /* parse next value */\n        input_buffer->offset++;\n        buffer_skip_whitespace(input_buffer);\n        if (!parse_value(current_item, input_buffer))\n        {\n            goto fail; /* failed to parse value */\n        }\n        buffer_skip_whitespace(input_buffer);\n    }\n    while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));\n\n    if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']')\n    {\n        goto fail; /* expected end of array */\n    }\n\nsuccess:\n    input_buffer->depth--;\n\n    item->type = cJSON_Array;\n    item->child = head;\n\n    input_buffer->offset++;\n\n    return true;\n\nfail:\n    if (head != NULL)\n    {\n        cJSON_Delete(head);\n    }\n\n    return false;\n}\n\n/* Render an array to text */\nstatic cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer)\n{\n    unsigned char *output_pointer = NULL;\n    size_t length = 0;\n    cJSON *current_element = item->child;\n\n    if (output_buffer == NULL)\n    {\n        return false;\n    }\n\n    /* Compose the output array. */\n    /* opening square bracket */\n    output_pointer = ensure(output_buffer, 1);\n    if (output_pointer == NULL)\n    {\n        return false;\n    }\n\n    *output_pointer = '[';\n    output_buffer->offset++;\n    output_buffer->depth++;\n\n    while (current_element != NULL)\n    {\n        if (!print_value(current_element, output_buffer))\n        {\n            return false;\n        }\n        update_offset(output_buffer);\n        if (current_element->next)\n        {\n            length = (size_t) (output_buffer->format ? 2 : 1);\n            output_pointer = ensure(output_buffer, length + 1);\n            if (output_pointer == NULL)\n            {\n                return false;\n            }\n            *output_pointer++ = ',';\n            if(output_buffer->format)\n            {\n                *output_pointer++ = ' ';\n            }\n            *output_pointer = '\\0';\n            output_buffer->offset += length;\n        }\n        current_element = current_element->next;\n    }\n\n    output_pointer = ensure(output_buffer, 2);\n    if (output_pointer == NULL)\n    {\n        return false;\n    }\n    *output_pointer++ = ']';\n    *output_pointer = '\\0';\n    output_buffer->depth--;\n\n    return true;\n}\n\n/* Build an object from the text. */\nstatic cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer)\n{\n    cJSON *head = NULL; /* linked list head */\n    cJSON *current_item = NULL;\n\n    if (input_buffer->depth >= CJSON_NESTING_LIMIT)\n    {\n        return false; /* to deeply nested */\n    }\n    input_buffer->depth++;\n\n    if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{'))\n    {\n        goto fail; /* not an object */\n    }\n\n    input_buffer->offset++;\n    buffer_skip_whitespace(input_buffer);\n    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}'))\n    {\n        goto success; /* empty object */\n    }\n\n    /* check if we skipped to the end of the buffer */\n    if (cannot_access_at_index(input_buffer, 0))\n    {\n        input_buffer->offset--;\n        goto fail;\n    }\n\n    /* step back to character in front of the first element */\n    input_buffer->offset--;\n    /* loop through the comma separated array elements */\n    do\n    {\n        /* allocate next item */\n        cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));\n        if (new_item == NULL)\n        {\n            goto fail; /* allocation failure */\n        }\n\n        /* attach next item to list */\n        if (head == NULL)\n        {\n            /* start the linked list */\n            current_item = head = new_item;\n        }\n        else\n        {\n            /* add to the end and advance */\n            current_item->next = new_item;\n            new_item->prev = current_item;\n            current_item = new_item;\n        }\n\n        /* parse the name of the child */\n        input_buffer->offset++;\n        buffer_skip_whitespace(input_buffer);\n        if (!parse_string(current_item, input_buffer))\n        {\n            goto fail; /* failed to parse name */\n        }\n        buffer_skip_whitespace(input_buffer);\n\n        /* swap valuestring and string, because we parsed the name */\n        current_item->string = current_item->valuestring;\n        current_item->valuestring = NULL;\n\n        if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':'))\n        {\n            goto fail; /* invalid object */\n        }\n\n        /* parse the value */\n        input_buffer->offset++;\n        buffer_skip_whitespace(input_buffer);\n        if (!parse_value(current_item, input_buffer))\n        {\n            goto fail; /* failed to parse value */\n        }\n        buffer_skip_whitespace(input_buffer);\n    }\n    while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));\n\n    if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}'))\n    {\n        goto fail; /* expected end of object */\n    }\n\nsuccess:\n    input_buffer->depth--;\n\n    item->type = cJSON_Object;\n    item->child = head;\n\n    input_buffer->offset++;\n    return true;\n\nfail:\n    if (head != NULL)\n    {\n        cJSON_Delete(head);\n    }\n\n    return false;\n}\n\n/* Render an object to text. */\nstatic cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer)\n{\n    unsigned char *output_pointer = NULL;\n    size_t length = 0;\n    cJSON *current_item = item->child;\n\n    if (output_buffer == NULL)\n    {\n        return false;\n    }\n\n    /* Compose the output: */\n    length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\\n */\n    output_pointer = ensure(output_buffer, length + 1);\n    if (output_pointer == NULL)\n    {\n        return false;\n    }\n\n    *output_pointer++ = '{';\n    output_buffer->depth++;\n    if (output_buffer->format)\n    {\n        *output_pointer++ = '\\n';\n    }\n    output_buffer->offset += length;\n\n    while (current_item)\n    {\n        if (output_buffer->format)\n        {\n            size_t i;\n            output_pointer = ensure(output_buffer, output_buffer->depth);\n            if (output_pointer == NULL)\n            {\n                return false;\n            }\n            for (i = 0; i < output_buffer->depth; i++)\n            {\n                *output_pointer++ = '\\t';\n            }\n            output_buffer->offset += output_buffer->depth;\n        }\n\n        /* print key */\n        if (!print_string_ptr((unsigned char*)current_item->string, output_buffer))\n        {\n            return false;\n        }\n        update_offset(output_buffer);\n\n        length = (size_t) (output_buffer->format ? 2 : 1);\n        output_pointer = ensure(output_buffer, length);\n        if (output_pointer == NULL)\n        {\n            return false;\n        }\n        *output_pointer++ = ':';\n        if (output_buffer->format)\n        {\n            *output_pointer++ = '\\t';\n        }\n        output_buffer->offset += length;\n\n        /* print value */\n        if (!print_value(current_item, output_buffer))\n        {\n            return false;\n        }\n        update_offset(output_buffer);\n\n        /* print comma if not last */\n        length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0));\n        output_pointer = ensure(output_buffer, length + 1);\n        if (output_pointer == NULL)\n        {\n            return false;\n        }\n        if (current_item->next)\n        {\n            *output_pointer++ = ',';\n        }\n\n        if (output_buffer->format)\n        {\n            *output_pointer++ = '\\n';\n        }\n        *output_pointer = '\\0';\n        output_buffer->offset += length;\n\n        current_item = current_item->next;\n    }\n\n    output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2);\n    if (output_pointer == NULL)\n    {\n        return false;\n    }\n    if (output_buffer->format)\n    {\n        size_t i;\n        for (i = 0; i < (output_buffer->depth - 1); i++)\n        {\n            *output_pointer++ = '\\t';\n        }\n    }\n    *output_pointer++ = '}';\n    *output_pointer = '\\0';\n    output_buffer->depth--;\n\n    return true;\n}\n\n/* Get Array size/item / object item. */\nCJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array)\n{\n    cJSON *child = NULL;\n    size_t size = 0;\n\n    if (array == NULL)\n    {\n        return 0;\n    }\n\n    child = array->child;\n\n    while(child != NULL)\n    {\n        size++;\n        child = child->next;\n    }\n\n    /* FIXME: Can overflow here. Cannot be fixed without breaking the API */\n\n    return (int)size;\n}\n\nstatic cJSON* get_array_item(const cJSON *array, size_t index)\n{\n    cJSON *current_child = NULL;\n\n    if (array == NULL)\n    {\n        return NULL;\n    }\n\n    current_child = array->child;\n    while ((current_child != NULL) && (index > 0))\n    {\n        index--;\n        current_child = current_child->next;\n    }\n\n    return current_child;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index)\n{\n    if (index < 0)\n    {\n        return NULL;\n    }\n\n    return get_array_item(array, (size_t)index);\n}\n\nstatic cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive)\n{\n    cJSON *current_element = NULL;\n\n    if ((object == NULL) || (name == NULL))\n    {\n        return NULL;\n    }\n\n    current_element = object->child;\n    if (case_sensitive)\n    {\n        while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0))\n        {\n            current_element = current_element->next;\n        }\n    }\n    else\n    {\n        while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0))\n        {\n            current_element = current_element->next;\n        }\n    }\n\n    if ((current_element == NULL) || (current_element->string == NULL)) {\n        return NULL;\n    }\n\n    return current_element;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string)\n{\n    return get_object_item(object, string, false);\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string)\n{\n    return get_object_item(object, string, true);\n}\n\nCJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string)\n{\n    return cJSON_GetObjectItem(object, string) ? 1 : 0;\n}\n\n/* Utility for array list handling. */\nstatic void suffix_object(cJSON *prev, cJSON *item)\n{\n    prev->next = item;\n    item->prev = prev;\n}\n\n/* Utility for handling references. */\nstatic cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks)\n{\n    cJSON *reference = NULL;\n    if (item == NULL)\n    {\n        return NULL;\n    }\n\n    reference = cJSON_New_Item(hooks);\n    if (reference == NULL)\n    {\n        return NULL;\n    }\n\n    memcpy(reference, item, sizeof(cJSON));\n    reference->string = NULL;\n    reference->type |= cJSON_IsReference;\n    reference->next = reference->prev = NULL;\n    return reference;\n}\n\nstatic cJSON_bool add_item_to_array(cJSON *array, cJSON *item)\n{\n    cJSON *child = NULL;\n\n    if ((item == NULL) || (array == NULL))\n    {\n        return false;\n    }\n\n    child = array->child;\n\n    if (child == NULL)\n    {\n        /* list is empty, start new one */\n        array->child = item;\n    }\n    else\n    {\n        /* append to the end */\n        while (child->next)\n        {\n            child = child->next;\n        }\n        suffix_object(child, item);\n    }\n\n    return true;\n}\n\n/* Add item to array/object. */\nCJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item)\n{\n    add_item_to_array(array, item);\n}\n\n#if defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))\n    #pragma GCC diagnostic push\n#endif\n#ifdef __GNUC__\n#pragma GCC diagnostic ignored \"-Wcast-qual\"\n#endif\n/* helper function to cast away const */\nstatic void* cast_away_const(const void* string)\n{\n    return (void*)string;\n}\n#if defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))\n    #pragma GCC diagnostic pop\n#endif\n\n\nstatic cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key)\n{\n    char *new_key = NULL;\n    int new_type = cJSON_Invalid;\n\n    if ((object == NULL) || (string == NULL) || (item == NULL))\n    {\n        return false;\n    }\n\n    if (constant_key)\n    {\n        new_key = (char*)cast_away_const(string);\n        new_type = item->type | cJSON_StringIsConst;\n    }\n    else\n    {\n        new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);\n        if (new_key == NULL)\n        {\n            return false;\n        }\n\n        new_type = item->type & ~cJSON_StringIsConst;\n    }\n\n    if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))\n    {\n        hooks->deallocate(item->string);\n    }\n\n    item->string = new_key;\n    item->type = new_type;\n\n    return add_item_to_array(object, item);\n}\n\nCJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)\n{\n    add_item_to_object(object, string, item, &global_hooks, false);\n}\n\n/* Add an item to an object with constant string as key */\nCJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)\n{\n    add_item_to_object(object, string, item, &global_hooks, true);\n}\n\nCJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)\n{\n    if (array == NULL)\n    {\n        return;\n    }\n\n    add_item_to_array(array, create_reference(item, &global_hooks));\n}\n\nCJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)\n{\n    if ((object == NULL) || (string == NULL))\n    {\n        return;\n    }\n\n    add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);\n}\n\nCJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)\n{\n    cJSON *null = cJSON_CreateNull();\n    if (add_item_to_object(object, name, null, &global_hooks, false))\n    {\n        return null;\n    }\n\n    cJSON_Delete(null);\n    return NULL;\n}\n\nCJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name)\n{\n    cJSON *true_item = cJSON_CreateTrue();\n    if (add_item_to_object(object, name, true_item, &global_hooks, false))\n    {\n        return true_item;\n    }\n\n    cJSON_Delete(true_item);\n    return NULL;\n}\n\nCJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name)\n{\n    cJSON *false_item = cJSON_CreateFalse();\n    if (add_item_to_object(object, name, false_item, &global_hooks, false))\n    {\n        return false_item;\n    }\n\n    cJSON_Delete(false_item);\n    return NULL;\n}\n\nCJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean)\n{\n    cJSON *bool_item = cJSON_CreateBool(boolean);\n    if (add_item_to_object(object, name, bool_item, &global_hooks, false))\n    {\n        return bool_item;\n    }\n\n    cJSON_Delete(bool_item);\n    return NULL;\n}\n\nCJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number)\n{\n    cJSON *number_item = cJSON_CreateNumber(number);\n    if (add_item_to_object(object, name, number_item, &global_hooks, false))\n    {\n        return number_item;\n    }\n\n    cJSON_Delete(number_item);\n    return NULL;\n}\n\nCJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string)\n{\n    cJSON *string_item = cJSON_CreateString(string);\n    if (add_item_to_object(object, name, string_item, &global_hooks, false))\n    {\n        return string_item;\n    }\n\n    cJSON_Delete(string_item);\n    return NULL;\n}\n\nCJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw)\n{\n    cJSON *raw_item = cJSON_CreateRaw(raw);\n    if (add_item_to_object(object, name, raw_item, &global_hooks, false))\n    {\n        return raw_item;\n    }\n\n    cJSON_Delete(raw_item);\n    return NULL;\n}\n\nCJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name)\n{\n    cJSON *object_item = cJSON_CreateObject();\n    if (add_item_to_object(object, name, object_item, &global_hooks, false))\n    {\n        return object_item;\n    }\n\n    cJSON_Delete(object_item);\n    return NULL;\n}\n\nCJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name)\n{\n    cJSON *array = cJSON_CreateArray();\n    if (add_item_to_object(object, name, array, &global_hooks, false))\n    {\n        return array;\n    }\n\n    cJSON_Delete(array);\n    return NULL;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)\n{\n    if ((parent == NULL) || (item == NULL))\n    {\n        return NULL;\n    }\n\n    if (item->prev != NULL)\n    {\n        /* not the first element */\n        item->prev->next = item->next;\n    }\n    if (item->next != NULL)\n    {\n        /* not the last element */\n        item->next->prev = item->prev;\n    }\n\n    if (item == parent->child)\n    {\n        /* first element */\n        parent->child = item->next;\n    }\n    /* make sure the detached item doesn't point anywhere anymore */\n    item->prev = NULL;\n    item->next = NULL;\n\n    return item;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which)\n{\n    if (which < 0)\n    {\n        return NULL;\n    }\n\n    return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which));\n}\n\nCJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which)\n{\n    cJSON_Delete(cJSON_DetachItemFromArray(array, which));\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string)\n{\n    cJSON *to_detach = cJSON_GetObjectItem(object, string);\n\n    return cJSON_DetachItemViaPointer(object, to_detach);\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string)\n{\n    cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string);\n\n    return cJSON_DetachItemViaPointer(object, to_detach);\n}\n\nCJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)\n{\n    cJSON_Delete(cJSON_DetachItemFromObject(object, string));\n}\n\nCJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string)\n{\n    cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string));\n}\n\n/* Replace array/object items with new ones. */\nCJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)\n{\n    cJSON *after_inserted = NULL;\n\n    if (which < 0)\n    {\n        return;\n    }\n\n    after_inserted = get_array_item(array, (size_t)which);\n    if (after_inserted == NULL)\n    {\n        add_item_to_array(array, newitem);\n        return;\n    }\n\n    newitem->next = after_inserted;\n    newitem->prev = after_inserted->prev;\n    after_inserted->prev = newitem;\n    if (after_inserted == array->child)\n    {\n        array->child = newitem;\n    }\n    else\n    {\n        newitem->prev->next = newitem;\n    }\n}\n\nCJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)\n{\n    if ((parent == NULL) || (replacement == NULL) || (item == NULL))\n    {\n        return false;\n    }\n\n    if (replacement == item)\n    {\n        return true;\n    }\n\n    replacement->next = item->next;\n    replacement->prev = item->prev;\n\n    if (replacement->next != NULL)\n    {\n        replacement->next->prev = replacement;\n    }\n    if (replacement->prev != NULL)\n    {\n        replacement->prev->next = replacement;\n    }\n    if (parent->child == item)\n    {\n        parent->child = replacement;\n    }\n\n    item->next = NULL;\n    item->prev = NULL;\n    cJSON_Delete(item);\n\n    return true;\n}\n\nCJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)\n{\n    if (which < 0)\n    {\n        return;\n    }\n\n    cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);\n}\n\nstatic cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)\n{\n    if ((replacement == NULL) || (string == NULL))\n    {\n        return false;\n    }\n\n    /* replace the name in the replacement */\n    if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL))\n    {\n        cJSON_free(replacement->string);\n    }\n    replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);\n    replacement->type &= ~cJSON_StringIsConst;\n\n    cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);\n\n    return true;\n}\n\nCJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)\n{\n    replace_item_in_object(object, string, newitem, false);\n}\n\nCJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)\n{\n    replace_item_in_object(object, string, newitem, true);\n}\n\n/* Create basic types: */\nCJSON_PUBLIC(cJSON *) cJSON_CreateNull(void)\n{\n    cJSON *item = cJSON_New_Item(&global_hooks);\n    if(item)\n    {\n        item->type = cJSON_NULL;\n    }\n\n    return item;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void)\n{\n    cJSON *item = cJSON_New_Item(&global_hooks);\n    if(item)\n    {\n        item->type = cJSON_True;\n    }\n\n    return item;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void)\n{\n    cJSON *item = cJSON_New_Item(&global_hooks);\n    if(item)\n    {\n        item->type = cJSON_False;\n    }\n\n    return item;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean)\n{\n    cJSON *item = cJSON_New_Item(&global_hooks);\n    if(item)\n    {\n        item->type = boolean ? cJSON_True : cJSON_False;\n    }\n\n    return item;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)\n{\n    cJSON *item = cJSON_New_Item(&global_hooks);\n    if(item)\n    {\n        item->type = cJSON_Number;\n        item->valuedouble = num;\n\n        /* use saturation in case of overflow */\n        if (num >= INT_MAX)\n        {\n            item->valueint = INT_MAX;\n        }\n        else if (num <= (double)INT_MIN)\n        {\n            item->valueint = INT_MIN;\n        }\n        else\n        {\n            item->valueint = (int)num;\n        }\n    }\n\n    return item;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string)\n{\n    cJSON *item = cJSON_New_Item(&global_hooks);\n    if(item)\n    {\n        item->type = cJSON_String;\n        item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);\n        if(!item->valuestring)\n        {\n            cJSON_Delete(item);\n            return NULL;\n        }\n    }\n\n    return item;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string)\n{\n    cJSON *item = cJSON_New_Item(&global_hooks);\n    if (item != NULL)\n    {\n        item->type = cJSON_String | cJSON_IsReference;\n        item->valuestring = (char*)cast_away_const(string);\n    }\n\n    return item;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child)\n{\n    cJSON *item = cJSON_New_Item(&global_hooks);\n    if (item != NULL) {\n        item->type = cJSON_Object | cJSON_IsReference;\n        item->child = (cJSON*)cast_away_const(child);\n    }\n\n    return item;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) {\n    cJSON *item = cJSON_New_Item(&global_hooks);\n    if (item != NULL) {\n        item->type = cJSON_Array | cJSON_IsReference;\n        item->child = (cJSON*)cast_away_const(child);\n    }\n\n    return item;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw)\n{\n    cJSON *item = cJSON_New_Item(&global_hooks);\n    if(item)\n    {\n        item->type = cJSON_Raw;\n        item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks);\n        if(!item->valuestring)\n        {\n            cJSON_Delete(item);\n            return NULL;\n        }\n    }\n\n    return item;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateArray(void)\n{\n    cJSON *item = cJSON_New_Item(&global_hooks);\n    if(item)\n    {\n        item->type=cJSON_Array;\n    }\n\n    return item;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateObject(void)\n{\n    cJSON *item = cJSON_New_Item(&global_hooks);\n    if (item)\n    {\n        item->type = cJSON_Object;\n    }\n\n    return item;\n}\n\n/* Create Arrays: */\nCJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)\n{\n    size_t i = 0;\n    cJSON *n = NULL;\n    cJSON *p = NULL;\n    cJSON *a = NULL;\n\n    if ((count < 0) || (numbers == NULL))\n    {\n        return NULL;\n    }\n\n    a = cJSON_CreateArray();\n    for(i = 0; a && (i < (size_t)count); i++)\n    {\n        n = cJSON_CreateNumber(numbers[i]);\n        if (!n)\n        {\n            cJSON_Delete(a);\n            return NULL;\n        }\n        if(!i)\n        {\n            a->child = n;\n        }\n        else\n        {\n            suffix_object(p, n);\n        }\n        p = n;\n    }\n\n    return a;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)\n{\n    size_t i = 0;\n    cJSON *n = NULL;\n    cJSON *p = NULL;\n    cJSON *a = NULL;\n\n    if ((count < 0) || (numbers == NULL))\n    {\n        return NULL;\n    }\n\n    a = cJSON_CreateArray();\n\n    for(i = 0; a && (i < (size_t)count); i++)\n    {\n        n = cJSON_CreateNumber((double)numbers[i]);\n        if(!n)\n        {\n            cJSON_Delete(a);\n            return NULL;\n        }\n        if(!i)\n        {\n            a->child = n;\n        }\n        else\n        {\n            suffix_object(p, n);\n        }\n        p = n;\n    }\n\n    return a;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)\n{\n    size_t i = 0;\n    cJSON *n = NULL;\n    cJSON *p = NULL;\n    cJSON *a = NULL;\n\n    if ((count < 0) || (numbers == NULL))\n    {\n        return NULL;\n    }\n\n    a = cJSON_CreateArray();\n\n    for(i = 0;a && (i < (size_t)count); i++)\n    {\n        n = cJSON_CreateNumber(numbers[i]);\n        if(!n)\n        {\n            cJSON_Delete(a);\n            return NULL;\n        }\n        if(!i)\n        {\n            a->child = n;\n        }\n        else\n        {\n            suffix_object(p, n);\n        }\n        p = n;\n    }\n\n    return a;\n}\n\nCJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count)\n{\n    size_t i = 0;\n    cJSON *n = NULL;\n    cJSON *p = NULL;\n    cJSON *a = NULL;\n\n    if ((count < 0) || (strings == NULL))\n    {\n        return NULL;\n    }\n\n    a = cJSON_CreateArray();\n\n    for (i = 0; a && (i < (size_t)count); i++)\n    {\n        n = cJSON_CreateString(strings[i]);\n        if(!n)\n        {\n            cJSON_Delete(a);\n            return NULL;\n        }\n        if(!i)\n        {\n            a->child = n;\n        }\n        else\n        {\n            suffix_object(p,n);\n        }\n        p = n;\n    }\n\n    return a;\n}\n\n/* Duplication */\nCJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)\n{\n    cJSON *newitem = NULL;\n    cJSON *child = NULL;\n    cJSON *next = NULL;\n    cJSON *newchild = NULL;\n\n    /* Bail on bad ptr */\n    if (!item)\n    {\n        goto fail;\n    }\n    /* Create new item */\n    newitem = cJSON_New_Item(&global_hooks);\n    if (!newitem)\n    {\n        goto fail;\n    }\n    /* Copy over all vars */\n    newitem->type = item->type & (~cJSON_IsReference);\n    newitem->valueint = item->valueint;\n    newitem->valuedouble = item->valuedouble;\n    if (item->valuestring)\n    {\n        newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks);\n        if (!newitem->valuestring)\n        {\n            goto fail;\n        }\n    }\n    if (item->string)\n    {\n        newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks);\n        if (!newitem->string)\n        {\n            goto fail;\n        }\n    }\n    /* If non-recursive, then we're done! */\n    if (!recurse)\n    {\n        return newitem;\n    }\n    /* Walk the ->next chain for the child. */\n    child = item->child;\n    while (child != NULL)\n    {\n        newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */\n        if (!newchild)\n        {\n            goto fail;\n        }\n        if (next != NULL)\n        {\n            /* If newitem->child already set, then crosswire ->prev and ->next and move on */\n            next->next = newchild;\n            newchild->prev = next;\n            next = newchild;\n        }\n        else\n        {\n            /* Set newitem->child and move to it */\n            newitem->child = newchild;\n            next = newchild;\n        }\n        child = child->next;\n    }\n\n    return newitem;\n\nfail:\n    if (newitem != NULL)\n    {\n        cJSON_Delete(newitem);\n    }\n\n    return NULL;\n}\n\nstatic void skip_oneline_comment(char **input)\n{\n    *input += static_strlen(\"//\");\n\n    for (; (*input)[0] != '\\0'; ++(*input))\n    {\n        if ((*input)[0] == '\\n') {\n            *input += static_strlen(\"\\n\");\n            return;\n        }\n    }\n}\n\nstatic void skip_multiline_comment(char **input)\n{\n    *input += static_strlen(\"/*\");\n\n    for (; (*input)[0] != '\\0'; ++(*input))\n    {\n        if (((*input)[0] == '*') && ((*input)[1] == '/'))\n        {\n            *input += static_strlen(\"*/\");\n            return;\n        }\n    }\n}\n\nstatic void minify_string(char **input, char **output) {\n    (*output)[0] = (*input)[0];\n    *input += static_strlen(\"\\\"\");\n    *output += static_strlen(\"\\\"\");\n\n\n    for (; (*input)[0] != '\\0'; (void)++(*input), ++(*output)) {\n        (*output)[0] = (*input)[0];\n\n        if ((*input)[0] == '\\\"') {\n            (*output)[0] = '\\\"';\n            *input += static_strlen(\"\\\"\");\n            *output += static_strlen(\"\\\"\");\n            return;\n        } else if (((*input)[0] == '\\\\') && ((*input)[1] == '\\\"')) {\n            (*output)[1] = (*input)[1];\n            *input += static_strlen(\"\\\"\");\n            *output += static_strlen(\"\\\"\");\n        }\n    }\n}\n\nCJSON_PUBLIC(void) cJSON_Minify(char *json)\n{\n    char *into = json;\n\n    if (json == NULL)\n    {\n        return;\n    }\n\n    while (json[0] != '\\0')\n    {\n        switch (json[0])\n        {\n            case ' ':\n            case '\\t':\n            case '\\r':\n            case '\\n':\n                json++;\n                break;\n\n            case '/':\n                if (json[1] == '/')\n                {\n                    skip_oneline_comment(&json);\n                }\n                else if (json[1] == '*')\n                {\n                    skip_multiline_comment(&json);\n                } else {\n                    json++;\n                }\n                break;\n\n            case '\\\"':\n                minify_string(&json, (char**)&into);\n                break;\n\n            default:\n                into[0] = json[0];\n                json++;\n                into++;\n        }\n    }\n\n    /* and null-terminate. */\n    *into = '\\0';\n}\n\nCJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item)\n{\n    if (item == NULL)\n    {\n        return false;\n    }\n\n    return (item->type & 0xFF) == cJSON_Invalid;\n}\n\nCJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item)\n{\n    if (item == NULL)\n    {\n        return false;\n    }\n\n    return (item->type & 0xFF) == cJSON_False;\n}\n\nCJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item)\n{\n    if (item == NULL)\n    {\n        return false;\n    }\n\n    return (item->type & 0xff) == cJSON_True;\n}\n\n\nCJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item)\n{\n    if (item == NULL)\n    {\n        return false;\n    }\n\n    return (item->type & (cJSON_True | cJSON_False)) != 0;\n}\nCJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item)\n{\n    if (item == NULL)\n    {\n        return false;\n    }\n\n    return (item->type & 0xFF) == cJSON_NULL;\n}\n\nCJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item)\n{\n    if (item == NULL)\n    {\n        return false;\n    }\n\n    return (item->type & 0xFF) == cJSON_Number;\n}\n\nCJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item)\n{\n    if (item == NULL)\n    {\n        return false;\n    }\n\n    return (item->type & 0xFF) == cJSON_String;\n}\n\nCJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item)\n{\n    if (item == NULL)\n    {\n        return false;\n    }\n\n    return (item->type & 0xFF) == cJSON_Array;\n}\n\nCJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item)\n{\n    if (item == NULL)\n    {\n        return false;\n    }\n\n    return (item->type & 0xFF) == cJSON_Object;\n}\n\nCJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)\n{\n    if (item == NULL)\n    {\n        return false;\n    }\n\n    return (item->type & 0xFF) == cJSON_Raw;\n}\n\nCJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)\n{\n    if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))\n    {\n        return false;\n    }\n\n    /* check if type is valid */\n    switch (a->type & 0xFF)\n    {\n        case cJSON_False:\n        case cJSON_True:\n        case cJSON_NULL:\n        case cJSON_Number:\n        case cJSON_String:\n        case cJSON_Raw:\n        case cJSON_Array:\n        case cJSON_Object:\n            break;\n\n        default:\n            return false;\n    }\n\n    /* identical objects are equal */\n    if (a == b)\n    {\n        return true;\n    }\n\n    switch (a->type & 0xFF)\n    {\n        /* in these cases and equal type is enough */\n        case cJSON_False:\n        case cJSON_True:\n        case cJSON_NULL:\n            return true;\n\n        case cJSON_Number:\n            if (compare_double(a->valuedouble, b->valuedouble))\n            {\n                return true;\n            }\n            return false;\n\n        case cJSON_String:\n        case cJSON_Raw:\n            if ((a->valuestring == NULL) || (b->valuestring == NULL))\n            {\n                return false;\n            }\n            if (strcmp(a->valuestring, b->valuestring) == 0)\n            {\n                return true;\n            }\n\n            return false;\n\n        case cJSON_Array:\n        {\n            cJSON *a_element = a->child;\n            cJSON *b_element = b->child;\n\n            for (; (a_element != NULL) && (b_element != NULL);)\n            {\n                if (!cJSON_Compare(a_element, b_element, case_sensitive))\n                {\n                    return false;\n                }\n\n                a_element = a_element->next;\n                b_element = b_element->next;\n            }\n\n            /* one of the arrays is longer than the other */\n            if (a_element != b_element) {\n                return false;\n            }\n\n            return true;\n        }\n\n        case cJSON_Object:\n        {\n            cJSON *a_element = NULL;\n            cJSON *b_element = NULL;\n            cJSON_ArrayForEach(a_element, a)\n            {\n                /* TODO This has O(n^2) runtime, which is horrible! */\n                b_element = get_object_item(b, a_element->string, case_sensitive);\n                if (b_element == NULL)\n                {\n                    return false;\n                }\n\n                if (!cJSON_Compare(a_element, b_element, case_sensitive))\n                {\n                    return false;\n                }\n            }\n\n            /* doing this twice, once on a and b to prevent true comparison if a subset of b\n             * TODO: Do this the proper way, this is just a fix for now */\n            cJSON_ArrayForEach(b_element, b)\n            {\n                a_element = get_object_item(a, b_element->string, case_sensitive);\n                if (a_element == NULL)\n                {\n                    return false;\n                }\n\n                if (!cJSON_Compare(b_element, a_element, case_sensitive))\n                {\n                    return false;\n                }\n            }\n\n            return true;\n        }\n\n        default:\n            return false;\n    }\n}\n\nCJSON_PUBLIC(void *) cJSON_malloc(size_t size)\n{\n    return global_hooks.allocate(size);\n}\n\nCJSON_PUBLIC(void) cJSON_free(void *object)\n{\n    global_hooks.deallocate(object);\n}\n"
  },
  {
    "path": "src/cJSON.h",
    "content": "/*\n  Copyright (c) 2009-2017 Dave Gamble and cJSON contributors\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files (the \"Software\"), to deal\n  in the Software without restriction, including without limitation the rights\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n  copies of the Software, and to permit persons to whom the Software is\n  furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  THE SOFTWARE.\n*/\n\n#ifndef cJSON__h\n#define cJSON__h\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))\n#define __WINDOWS__\n#endif\n\n#ifdef __WINDOWS__\n\n/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention.  For windows you have 3 define options:\n\nCJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols\nCJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)\nCJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol\n\nFor *nix builds that support visibility attribute, you can define similar behavior by\n\nsetting default visibility to hidden by adding\n-fvisibility=hidden (for gcc)\nor\n-xldscope=hidden (for sun cc)\nto CFLAGS\n\nthen using the CJSON_API_VISIBILITY flag to \"export\" the same symbols the way CJSON_EXPORT_SYMBOLS does\n\n*/\n\n#define CJSON_CDECL __cdecl\n#define CJSON_STDCALL __stdcall\n\n/* export symbols by default, this is necessary for copy pasting the C and header file */\n#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)\n#define CJSON_EXPORT_SYMBOLS\n#endif\n\n#if defined(CJSON_HIDE_SYMBOLS)\n#define CJSON_PUBLIC(type)   type CJSON_STDCALL\n#elif defined(CJSON_EXPORT_SYMBOLS)\n#define CJSON_PUBLIC(type)   __declspec(dllexport) type CJSON_STDCALL\n#elif defined(CJSON_IMPORT_SYMBOLS)\n#define CJSON_PUBLIC(type)   __declspec(dllimport) type CJSON_STDCALL\n#endif\n#else /* !__WINDOWS__ */\n#define CJSON_CDECL\n#define CJSON_STDCALL\n\n#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)\n#define CJSON_PUBLIC(type)   __attribute__((visibility(\"default\"))) type\n#else\n#define CJSON_PUBLIC(type) type\n#endif\n#endif\n\n/* project version */\n#define CJSON_VERSION_MAJOR 1\n#define CJSON_VERSION_MINOR 7\n#define CJSON_VERSION_PATCH 12\n\n#include <stddef.h>\n\n/* cJSON Types: */\n#define cJSON_Invalid (0)\n#define cJSON_False  (1 << 0)\n#define cJSON_True   (1 << 1)\n#define cJSON_NULL   (1 << 2)\n#define cJSON_Number (1 << 3)\n#define cJSON_String (1 << 4)\n#define cJSON_Array  (1 << 5)\n#define cJSON_Object (1 << 6)\n#define cJSON_Raw    (1 << 7) /* raw json */\n\n#define cJSON_IsReference 256\n#define cJSON_StringIsConst 512\n\n/* The cJSON structure: */\ntypedef struct cJSON\n{\n    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */\n    struct cJSON *next;\n    struct cJSON *prev;\n    /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */\n    struct cJSON *child;\n\n    /* The type of the item, as above. */\n    int type;\n\n    /* The item's string, if type==cJSON_String  and type == cJSON_Raw */\n    char *valuestring;\n    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */\n    int valueint;\n    /* The item's number, if type==cJSON_Number */\n    double valuedouble;\n\n    /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */\n    char *string;\n} cJSON;\n\ntypedef struct cJSON_Hooks\n{\n      /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */\n      void *(CJSON_CDECL *malloc_fn)(size_t sz);\n      void (CJSON_CDECL *free_fn)(void *ptr);\n} cJSON_Hooks;\n\ntypedef int cJSON_bool;\n\n/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.\n * This is to prevent stack overflows. */\n#ifndef CJSON_NESTING_LIMIT\n#define CJSON_NESTING_LIMIT 1000\n#endif\n\n/* Precision of double variables comparison */\n#ifndef CJSON_DOUBLE_PRECISION\n#define CJSON_DOUBLE_PRECISION .0000000000000001\n#endif\n\n/* returns the version of cJSON as a string */\nCJSON_PUBLIC(const char*) cJSON_Version(void);\n\n/* Supply malloc, realloc and free functions to cJSON */\nCJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);\n\n/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */\n/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */\nCJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);\n/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */\n/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */\nCJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);\n\n/* Render a cJSON entity to text for transfer/storage. */\nCJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);\n/* Render a cJSON entity to text for transfer/storage without any formatting. */\nCJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);\n/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */\nCJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);\n/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */\n/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */\nCJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);\n/* Delete a cJSON entity and all subentities. */\nCJSON_PUBLIC(void) cJSON_Delete(cJSON *item);\n\n/* Returns the number of items in an array (or object). */\nCJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);\n/* Retrieve item number \"index\" from array \"array\". Returns NULL if unsuccessful. */\nCJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);\n/* Get item \"string\" from object. Case insensitive. */\nCJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);\nCJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);\nCJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);\n/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */\nCJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);\n\n/* Check if the item is a string and return its valuestring */\nCJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);\n\n/* These functions check the type of an item */\nCJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);\nCJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);\nCJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);\nCJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);\nCJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);\nCJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);\nCJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);\nCJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);\nCJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);\nCJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);\n\n/* These calls create a cJSON item of the appropriate type. */\nCJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);\nCJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);\nCJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);\nCJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);\nCJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);\nCJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);\n/* raw json */\nCJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);\nCJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);\nCJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);\n\n/* Create a string where valuestring references a string so\n * it will not be freed by cJSON_Delete */\nCJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);\n/* Create an object/array that only references it's elements so\n * they will not be freed by cJSON_Delete */\nCJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);\nCJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);\n\n/* These utilities create an Array of count items.\n * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/\nCJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);\nCJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);\nCJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);\nCJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);\n\n/* Append item to the specified array/object. */\nCJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);\nCJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);\n/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.\n * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before\n * writing to `item->string` */\nCJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);\n/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */\nCJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);\nCJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);\n\n/* Remove/Detach items from Arrays/Objects. */\nCJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);\nCJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);\nCJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);\nCJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);\nCJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);\nCJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);\nCJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);\n\n/* Update array items. */\nCJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */\nCJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);\nCJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);\nCJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);\nCJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);\n\n/* Duplicate a cJSON item */\nCJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);\n/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will\n * need to be released. With recurse!=0, it will duplicate any children connected to the item.\n * The item->next and ->prev pointers are always zero on return from Duplicate. */\n/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.\n * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */\nCJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);\n\n/* Minify a strings, remove blank characters(such as ' ', '\\t', '\\r', '\\n') from strings.\n * The input pointer json cannot point to a read-only address area, such as a string constant, \n * but should point to a readable and writable adress area. */\nCJSON_PUBLIC(void) cJSON_Minify(char *json);\n\n/* Helper functions for creating and adding items to an object at the same time.\n * They return the added item or NULL on failure. */\nCJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);\nCJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);\nCJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);\nCJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);\nCJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);\nCJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);\nCJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);\nCJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);\nCJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);\n\n/* When assigning an integer value, it needs to be propagated to valuedouble too. */\n#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))\n/* helper for the cJSON_SetNumberValue macro */\nCJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);\n#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))\n\n/* Macro for iterating over an array or object */\n#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)\n\n/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */\nCJSON_PUBLIC(void *) cJSON_malloc(size_t size);\nCJSON_PUBLIC(void) cJSON_free(void *object);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/cQueue.c",
    "content": "/*!\\file cQueue.c\n** \\author SMFSW\n** \\copyright BSD 3-Clause License (c) 2017-2019, SMFSW\n** \\brief Queue handling library (designed in c on STM32)\n** \\details Queue handling library (designed in c on STM32)\n**/\n/****************************************************************/\n#include <string.h>\n#include <stdlib.h>\n\n#include \"cQueue.h\"\n/****************************************************************/\n\n\n/*!\t\\brief Increment index\n**\t\\details Increment buffer index \\b pIdx rolling back to \\b start when limit \\b end is reached\n**\t\\param [in,out] pIdx - pointer to index value\n**\t\\param [in] end - counter upper limit value\n**\t\\param [in] start - counter lower limit value\n**/\nstatic inline void __attribute__((nonnull, always_inline)) inc_idx(uint16_t * const pIdx, const uint16_t end, const uint16_t start)\n{\n//\t(*pIdx)++;\n//\t*pIdx %= end;\n\tif (*pIdx < end - 1)\t{ (*pIdx)++; }\n\telse\t\t\t\t\t{ *pIdx = start; }\n}\n\n/*!\t\\brief Decrement index\n**\t\\details Decrement buffer index \\b pIdx rolling back to \\b end when limit \\b start is reached\n**\t\\param [in,out] pIdx - pointer to index value\n**\t\\param [in] end - counter upper limit value\n**\t\\param [in] start - counter lower limit value\n**/\nstatic inline void __attribute__((nonnull, always_inline)) dec_idx(uint16_t * const pIdx, const uint16_t end, const uint16_t start)\n{\n\tif (*pIdx > start)\t\t{ (*pIdx)--; }\n\telse\t\t\t\t\t{ *pIdx = end - 1; }\n}\n\n\nvoid * __attribute__((nonnull)) q_init(Queue_t * const q, const uint16_t size_rec, const uint16_t nb_recs, const QueueType type, const bool overwrite)\n{\n\tconst uint32_t size = nb_recs * size_rec;\n\n\tq->rec_nb = nb_recs;\n\tq->rec_sz = size_rec;\n\tq->impl = type;\n\tq->ovw = overwrite;\n\n\tq_kill(q);\t// Free existing data (if any)\n\tq->queue = (uint8_t *) malloc(size);\n\n\tif (q->queue == NULL)\t{ q->queue_sz = 0; return 0; }\t// Return here if Queue not allocated\n\telse\t\t\t\t\t{ q->queue_sz = size; }\n\n\tq->init = QUEUE_INITIALIZED;\n\tq_flush(q);\n\n\treturn q->queue;\t// return NULL when queue not allocated (beside), Queue address otherwise\n}\n\nvoid __attribute__((nonnull)) q_kill(Queue_t * const q)\n{\n\tif (q->init == QUEUE_INITIALIZED)\t{ free(q->queue); }\t// Free existing data (if already initialized)\n\tq->init = 0;\n}\n\n\nvoid __attribute__((nonnull)) q_flush(Queue_t * const q)\n{\n\tq->in = 0;\n\tq->out = 0;\n\tq->cnt = 0;\n}\n\n\nbool __attribute__((nonnull)) q_push(Queue_t * const q, const void * const record)\n{\n\tif ((!q->ovw) && q_isFull(q))\t{ return false; }\n\n\tuint8_t * const pStart = q->queue + (q->rec_sz * q->in);\n\tmemcpy(pStart, record, q->rec_sz);\n\n\tinc_idx(&q->in, q->rec_nb, 0);\n\n\tif (!q_isFull(q))\t{ q->cnt++; }\t// Increase records count\n\telse if (q->ovw)\t\t\t\t\t// Queue is full and overwrite is allowed\n\t{\n\t\tif (q->impl == FIFO)\t\t\t{ inc_idx(&q->out, q->rec_nb, 0); }\t// as oldest record is overwritten, increment out\n\t\t//else if (q->impl == LIFO)\t{}\t\t\t\t\t\t\t\t\t\t// Nothing to do in this case\n\t}\n\n\treturn true;\n}\n\nbool __attribute__((nonnull)) q_pop(Queue_t * const q, void * const record)\n{\n\tconst uint8_t * pStart;\n\n\tif (q_isEmpty(q))\t{ return false; }\t// No more records\n\n\tif (q->impl == FIFO)\n\t{\n\t\tpStart = q->queue + (q->rec_sz * q->out);\n\t\tinc_idx(&q->out, q->rec_nb, 0);\n\t}\n\telse if (q->impl == LIFO)\n\t{\n\t\tdec_idx(&q->in, q->rec_nb, 0);\n\t\tpStart = q->queue + (q->rec_sz * q->in);\n\t}\n\telse\t{ return false; }\n\n\tmemcpy(record, pStart, q->rec_sz);\n\tq->cnt--;\t// Decrease records count\n\treturn true;\n}\n\nbool __attribute__((nonnull)) q_peek(const Queue_t * const q, void * const record)\n{\n\tconst uint8_t * pStart;\n\n\tif (q_isEmpty(q))\t{ return false; }\t// No more records\n\n\tif (q->impl == FIFO)\n\t{\n\t\tpStart = q->queue + (q->rec_sz * q->out);\n\t\t// No change on out var as it's just a peek\n\t}\n\telse if (q->impl == LIFO)\n\t{\n\t\tuint16_t rec = q->in;\t// Temporary var for peek (no change on q->in with dec_idx)\n\t\tdec_idx(&rec, q->rec_nb, 0);\n\t\tpStart = q->queue + (q->rec_sz * rec);\n\t}\n\telse\t{ return false; }\n\n\tmemcpy(record, pStart, q->rec_sz);\n\treturn true;\n}\n\nbool __attribute__((nonnull)) q_drop(Queue_t * const q)\n{\n\tif (q_isEmpty(q))\t\t\t{ return false; }\t// No more records\n\n\tif (q->impl == FIFO)\t\t{ inc_idx(&q->out, q->rec_nb, 0); }\n\telse if (q->impl == LIFO)\t{ dec_idx(&q->in, q->rec_nb, 0); }\n\telse\t\t\t\t\t\t{ return false; }\n\n\tq->cnt--;\t// Decrease records count\n\treturn true;\n}\n\nbool __attribute__((nonnull)) q_peekIdx(const Queue_t * const q, void * const record, const uint16_t idx)\n{\n\tconst uint8_t * pStart;\n\n\tif (idx + 1 > q_getCount(q))\t{ return false; }\t// Index out of range\n\n\tif (q->impl == FIFO)\n\t{\n\t\tpStart = q->queue + (q->rec_sz * ((q->out + idx) % q->rec_nb));\n\t}\n\telse if (q->impl == LIFO)\n\t{\n\t\tpStart = q->queue + (q->rec_sz * idx);\n\t}\n\telse\t{ return false; }\n\n\tmemcpy(record, pStart, q->rec_sz);\n\treturn true;\n}\n\n"
  },
  {
    "path": "src/cQueue.h",
    "content": "/*!\\file cQueue.h\n** \\author SMFSW\n** \\copyright BSD 3-Clause License (c) 2017-2019, SMFSW\n** \\brief Queue handling library (designed in c on STM32)\n** \\details Queue handling library (designed in c on STM32)\n**/\n/****************************************************************/\n#ifndef __CQUEUE_H\n\t#define __CQUEUE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <inttypes.h>\n#include <stdbool.h>\n/****************************************************************/\n\n\n#define QUEUE_INITIALIZED\t0x5AA5\t\t\t\t\t\t\t//!< Queue initialized control value\n\n#define q_init_def(q, sz)\tq_init(q, sz, 20, FIFO, false)\t//!< Some kind of average default for queue initialization\n\n#define q_pull\t\t\t\tq_pop\t\t\t\t\t\t\t//!< \\deprecated q_pull was already used in cQueue lib, alias is made to keep compatibility with earlier versions\n#define q_nbRecs\t\t\tq_getCount\t\t\t\t\t\t//!< \\deprecated q_nbRecs was already used in cQueue lib, alias is made to keep compatibility with earlier versions\n#define q_clean\t\t\t\tq_flush\t\t\t\t\t\t\t//!< \\deprecated q_clean was already used in cQueue lib, alias is made to keep compatibility with earlier versions\n\n\n/*!\\enum enumQueueType\n** \\brief Queue behavior enumeration (FIFO, LIFO)\n**/\ntypedef enum enumQueueType {\n\tFIFO = 0,\t//!< First In First Out behavior\n\tLIFO = 1\t//!< Last In First Out behavior\n} QueueType;\n\n\n/*!\\struct Queue_t\n** \\brief Queue type structure holding all variables to handle the queue\n**/\ntypedef struct Queue_t {\n\tQueueType\timpl;\t\t//!< Queue implementation: FIFO LIFO\n\tbool\t\tovw;\t\t//!< Overwrite previous records when queue is full allowed\n\tuint16_t\trec_nb;\t\t//!< number of records in the queue\n\tuint16_t\trec_sz;\t\t//!< Size of a record\n\tuint32_t\tqueue_sz;\t//!< Size of the full queue\n\tuint8_t *\tqueue;\t\t//!< Queue start pointer (when allocated)\n\n\tuint16_t\tin;\t\t\t//!< number of records pushed into the queue\n\tuint16_t\tout;\t\t//!< number of records pulled from the queue (only for FIFO)\n\tuint16_t\tcnt;\t\t//!< number of records not retrieved from the queue\n\tuint16_t\tinit;\t\t//!< set to QUEUE_INITIALIZED after successful init of the queue and reset when killing queue\n} Queue_t;\n\n\n/*!\t\\brief Queue initialization\n**\t\\param [in,out] q - pointer of queue to handle\n**\t\\param [in] size_rec - size of a record in the queue\n**\t\\param [in] nb_recs - number of records in the queue\n**\t\\param [in] type - Queue implementation type: FIFO, LIFO\n**\t\\param [in] overwrite - Overwrite previous records when queue is full\n**\t\\return NULL when allocation not possible, Queue tab address when successful\n**/\nvoid * __attribute__((nonnull)) q_init(Queue_t * const q, const uint16_t size_rec, const uint16_t nb_recs, const QueueType type, const bool overwrite);\n\n/*!\t\\brief Queue destructor: release dynamically allocated queue\n**\t\\param [in,out] q - pointer of queue to handle\n**/\nvoid __attribute__((nonnull)) q_kill(Queue_t * const q);\n\n/*!\t\\brief Flush queue, restarting from empty queue\n**\t\\param [in,out] q - pointer of queue to handle\n**/\nvoid __attribute__((nonnull)) q_flush(Queue_t * const q);\n\n/*!\t\\brief get initialization state of the queue\n**\t\\param [in] q - pointer of queue to handle\n**\t\\return Queue initialization status\n**\t\\retval true if queue is allocated\n**\t\\retval false is queue is not allocated\n**/\ninline bool __attribute__((nonnull, always_inline)) q_isInitialized(const Queue_t * const q) {\n\treturn (q->init == QUEUE_INITIALIZED) ? true : false; }\n\n/*!\t\\brief get emptiness state of the queue\n**\t\\param [in] q - pointer of queue to handle\n**\t\\return Queue emptiness status\n**\t\\retval true if queue is empty\n**\t\\retval false is not empty\n**/\ninline bool __attribute__((nonnull, always_inline)) q_isEmpty(const Queue_t * const q) {\n\treturn (!q->cnt) ? true : false; }\n\n/*!\t\\brief get fullness state of the queue\n**\t\\param [in] q - pointer of queue to handle\n**\t\\return Queue fullness status\n**\t\\retval true if queue is full\n**\t\\retval false is not full\n**/\ninline bool __attribute__((nonnull, always_inline)) q_isFull(const Queue_t * const q) {\n\treturn (q->cnt == q->rec_nb) ? true : false; }\n\n/*!\t\\brief get size of queue\n**\t\\remark Size in bytes (like sizeof)\n**\t\\param [in] q - pointer of queue to handle\n**\t\\return Size of queue in bytes\n**/\ninline uint32_t __attribute__((nonnull, always_inline)) q_sizeof(const Queue_t * const q) {\n\treturn q->queue_sz; }\n\n/*!\t\\brief get number of records in the queue\n**\t\\param [in] q - pointer of queue to handle\n**\t\\return Number of records stored in the queue\n**/\ninline uint16_t __attribute__((nonnull, always_inline)) q_getCount(const Queue_t * const q) {\n\treturn q->cnt; }\n\n/*!\t\\brief get number of records left in the queue\n**\t\\param [in] q - pointer of queue to handle\n**\t\\return Number of records left in the queue\n**/\ninline uint16_t __attribute__((nonnull, always_inline)) q_getRemainingCount(const Queue_t * const q) {\n\treturn q->rec_nb - q->cnt; }\n\n/*!\t\\brief Push record to queue\n**\t\\warning If using q_push, q_pop, q_peek, q_drop, q_peekItem and/or q_peekPrevious in both interrupts and main application,\n**\t\t\t\tyou shall disable interrupts in main application when using these functions\n**\t\\param [in,out] q - pointer of queue to handle\n**\t\\param [in] record - pointer to record to be pushed into queue\n**\t\\return Push status\n**\t\\retval true if successfully pushed into queue\n**\t\\retval false if queue is full\n**/\nbool __attribute__((nonnull)) q_push(Queue_t * const q, const void * const record);\n\n/*!\t\\brief Pop record from queue\n**\t\\warning If using q_push, q_pop, q_peek, q_drop, q_peekItem and/or q_peekPrevious in both interrupts and main application,\n**\t\t\t\tyou shall disable interrupts in main application when using these functions\n**\t\\param [in] q - pointer of queue to handle\n**\t\\param [in,out] record - pointer to record to be popped from queue\n**\t\\return Pop status\n**\t\\retval true if successfully pulled from queue\n**\t\\retval false if queue is empty\n**/\nbool __attribute__((nonnull)) q_pop(Queue_t * const q, void * const record);\n\n/*!\t\\brief Peek record from queue\n**\t\\warning If using q_push, q_pop, q_peek, q_drop, q_peekItem and/or q_peekPrevious in both interrupts and main application,\n**\t\t\t\tyou shall disable interrupts in main application when using these functions\n**\t\\note This function is most likely to be used in conjunction with q_drop\n**\t\\param [in] q - pointer of queue to handle\n**\t\\param [in,out] record - pointer to record to be peeked from queue\n**\t\\return Peek status\n**\t\\retval true if successfully peeked from queue\n**\t\\retval false if queue is empty\n**/\nbool __attribute__((nonnull)) q_peek(const Queue_t * const q, void * const record);\n\n/*!\t\\brief Drop current record from queue\n**\t\\warning If using q_push, q_pop, q_peek, q_drop, q_peekItem and/or q_peekPrevious in both interrupts and main application,\n**\t\t\t\tyou shall disable interrupts in main application when using these functions\n**\t\\note This function is most likely to be used in conjunction with q_peek\n**\t\\param [in,out] q - pointer of queue to handle\n**\t\\return drop status\n**\t\\retval true if successfully dropped from queue\n**\t\\retval false if queue is empty\n**/\nbool __attribute__((nonnull)) q_drop(Queue_t * const q);\n\n/*!\t\\brief Peek record at index from queue\n**\t\\warning If using q_push, q_pop, q_peek, q_drop, q_peekItem and/or q_peekPrevious in both interrupts and main application,\n**\t\t\t\tyou shall disable interrupts in main application when using these functions\n**\t\\note This function is only useful if searching for a duplicate record and shouldn't be used in conjunction with q_drop\n**\t\\param [in] q - pointer of queue to handle\n**\t\\param [in,out] record - pointer to record to be peeked from queue\n**\t\\param [in] idx - index of the record to pick\n**\t\\return Peek status\n**\t\\retval true if successfully peeked from queue\n**\t\\retval false if index is out of range\n**/\nbool __attribute__((nonnull)) q_peekIdx(const Queue_t * const q, void * const record, const uint16_t idx);\n\n/*!\t\\brief Peek previous record from queue\n**\t\\warning If using q_push, q_pop, q_peek, q_drop, q_peekItem and/or q_peekPrevious in both interrupts and main application,\n**\t\t\t\tyou shall disable interrupts in main application when using these functions\n**\t\\note This inline is only useful with FIFO implementation, use q_peek instead with a LIFO (will lead to the same result)\n**\t\\param [in] q - pointer of queue to handle\n**\t\\param [in,out] record - pointer to record to be peeked from queue\n**\t\\return Peek status\n**\t\\retval true if successfully peeked from queue\n**\t\\retval false if queue is empty\n**/\ninline bool __attribute__((nonnull, always_inline)) q_peekPrevious(const Queue_t * const q, void * const record) {\n\tconst uint16_t idx = q_getCount(q) - 1;\t// No worry about count - 1 when queue is empty, test is done by q_peekIdx\n\treturn q_peekIdx(q, record, idx); }\n\n\n/****************************************************************/\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __CQUEUE_H */\n/****************************************************************/\n"
  },
  {
    "path": "src/constants.h",
    "content": "#pragma once\n\n#define DEVICE_ID_SIZE 36\n#define ACCESSORY_ID_SIZE   17\n"
  },
  {
    "path": "src/crypto.c",
    "content": "#include <string.h>\n\n#include \"user_settings.h\"\n#include <wolfssl/wolfcrypt/hmac.h>\n#include <wolfssl/wolfcrypt/ed25519.h>\n#include <wolfssl/wolfcrypt/curve25519.h>\n#include <wolfssl/wolfcrypt/sha512.h>\n#include <wolfssl/wolfcrypt/chacha20_poly1305.h>\n#include <wolfssl/wolfcrypt/srp.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n\n#include \"homekit_debug.h\"\n#include \"port.h\"\n#include <pgmspace.h>\n\n// 3072-bit group N (per RFC5054, Appendix A)\n// ~384-byte\n#define N_SIZE 384\n\nconst byte PROGMEM N[] = {\n  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, 0xda, 0xa2,\n  0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1,\n  0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6,\n  0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd,\n  0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d,\n  0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45,\n  0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, 0xf4, 0x4c, 0x42, 0xe9,\n  0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed,\n  0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, 0xae, 0x9f, 0x24, 0x11,\n  0x7c, 0x4b, 0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51, 0xec, 0xe4, 0x5b, 0x3d,\n  0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05, 0x98, 0xda, 0x48, 0x36,\n  0x1c, 0x55, 0xd3, 0x9a, 0x69, 0x16, 0x3f, 0xa8, 0xfd, 0x24, 0xcf, 0x5f,\n  0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96, 0x1c, 0x62, 0xf3, 0x56,\n  0x20, 0x85, 0x52, 0xbb, 0x9e, 0xd5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6d,\n  0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04, 0xf1, 0x74, 0x6c, 0x08,\n  0xca, 0x18, 0x21, 0x7c, 0x32, 0x90, 0x5e, 0x46, 0x2e, 0x36, 0xce, 0x3b,\n  0xe3, 0x9e, 0x77, 0x2c, 0x18, 0x0e, 0x86, 0x03, 0x9b, 0x27, 0x83, 0xa2,\n  0xec, 0x07, 0xa2, 0x8f, 0xb5, 0xc5, 0x5d, 0xf0, 0x6f, 0x4c, 0x52, 0xc9,\n  0xde, 0x2b, 0xcb, 0xf6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7c,\n  0xea, 0x95, 0x6a, 0xe5, 0x15, 0xd2, 0x26, 0x18, 0x98, 0xfa, 0x05, 0x10,\n  0x15, 0x72, 0x8e, 0x5a, 0x8a, 0xaa, 0xc4, 0x2d, 0xad, 0x33, 0x17, 0x0d,\n  0x04, 0x50, 0x7a, 0x33, 0xa8, 0x55, 0x21, 0xab, 0xdf, 0x1c, 0xba, 0x64,\n  0xec, 0xfb, 0x85, 0x04, 0x58, 0xdb, 0xef, 0x0a, 0x8a, 0xea, 0x71, 0x57,\n  0x5d, 0x06, 0x0c, 0x7d, 0xb3, 0x97, 0x0f, 0x85, 0xa6, 0xe1, 0xe4, 0xc7,\n  0xab, 0xf5, 0xae, 0x8c, 0xdb, 0x09, 0x33, 0xd7, 0x1e, 0x8c, 0x94, 0xe0,\n  0x4a, 0x25, 0x61, 0x9d, 0xce, 0xe3, 0xd2, 0x26, 0x1a, 0xd2, 0xee, 0x6b,\n  0xf1, 0x2f, 0xfa, 0x06, 0xd9, 0x8a, 0x08, 0x64, 0xd8, 0x76, 0x02, 0x73,\n  0x3e, 0xc8, 0x6a, 0x64, 0x52, 0x1f, 0x2b, 0x18, 0x17, 0x7b, 0x20, 0x0c,\n  0xbb, 0xe1, 0x17, 0x57, 0x7a, 0x61, 0x5d, 0x6c, 0x77, 0x09, 0x88, 0xc0,\n  0xba, 0xd9, 0x46, 0xe2, 0x08, 0xe2, 0x4f, 0xa0, 0x74, 0xe5, 0xab, 0x31,\n  0x43, 0xdb, 0x5b, 0xfc, 0xe0, 0xfd, 0x10, 0x8e, 0x4b, 0x82, 0xd1, 0x20,\n  0xa9, 0x3a, 0xd2, 0xca, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff\n};\n\n// 3072-bit group generator (per RFC5054, Appendix A)\nconst byte g[] = {0x05};\n\n\nint wc_SrpSetKeyH(Srp *srp, byte *secret, word32 size) {\n    SrpHash hash;\n    int r = BAD_FUNC_ARG;\n\n    srp->key = (byte*) XMALLOC(WC_SHA512_DIGEST_SIZE, NULL, DYNAMIC_TYPE_SRP);\n    if (!srp->key)\n        return MEMORY_E;\n\n    srp->keySz = WC_SHA512_DIGEST_SIZE;\n\n    r = wc_InitSha512(&hash.data.sha512);\n    if (!r) r = wc_Sha512Update(&hash.data.sha512, secret, size);\n    if (!r) r = wc_Sha512Final(&hash.data.sha512, srp->key);\n\n    // clean up hash data from stack for security\n    memset(&hash, 0, sizeof(hash));\n\n    return r;\n}\n\n\nSrp *crypto_srp_new() {\n    Srp *srp = malloc(sizeof(Srp));\n\n    DEBUG(\"Initializing SRP\");\n    int r = wc_SrpInit(srp, SRP_TYPE_SHA512, SRP_CLIENT_SIDE);\n    if (r) {\n        DEBUG(\"Failed to initialize SRP (code %d)\", r);\n        return NULL;\n    }\n    srp->keyGenFunc_cb = wc_SrpSetKeyH;\n\n    return srp;\n}\n\n\nvoid crypto_srp_free(Srp *srp) {\n    wc_SrpTerm(srp);\n    free(srp);\n}\n\n\nint crypto_srp_init(Srp *srp, const char *username, const char *password) {\n    DEBUG(\"Generating salt\");\n    byte salt[16];\n    homekit_random_fill(salt, sizeof(salt));\n\n    int r;\n    DEBUG(\"Setting SRP username\");\n    r = wc_SrpSetUsername(srp, (byte*)username, strlen(username));\n    if (r) {\n        DEBUG(\"Failed to set SRP username (code %d)\", r);\n        return r;\n    }\n\n    DEBUG(\"Setting SRP params\");\n    // Ref: https://arduino-esp8266.readthedocs.io/en/2.6.3/PROGMEM.html\n\tbyte N_ram[N_SIZE];\n\tmemcpy_P(N_ram, N, N_SIZE);\n    r = wc_SrpSetParams(srp, N_ram, N_SIZE, g, sizeof(g), salt, sizeof(salt));\n    if (r) {\n        DEBUG(\"Failed to set SRP params (code %d)\", r);\n        return r;\n    }\n\n    DEBUG(\"Setting SRP password\");\n    r = wc_SrpSetPassword(srp, (byte *)password, strlen(password));\n    if (r) {\n        DEBUG(\"Failed to set SRP password (code %d)\", r);\n        return r;\n    }\n\n    DEBUG(\"Getting SRP verifier\");\n    word32 verifierLen = 1024;\n    byte *verifier = malloc(verifierLen);\n    r = wc_SrpGetVerifier(srp, verifier, &verifierLen);\n    if (r) {\n        DEBUG(\"Failed to get SRP verifier (code %d)\", r);\n        free(verifier);\n        return r;\n    }\n\n    srp->side = SRP_SERVER_SIDE;\n    DEBUG(\"Setting SRP verifier\");\n    r = wc_SrpSetVerifier(srp, verifier, verifierLen);\n    if (r) {\n        DEBUG(\"Failed to set SRP verifier (code %d)\", r);\n        free(verifier);\n        return r;\n    }\n\n    free(verifier);\n\n    return 0;\n}\n\n\nint crypto_srp_get_salt(Srp *srp, byte *buffer, size_t *buffer_size) {\n    if (buffer_size == NULL)\n        return -1;\n\n    if (*buffer_size < srp->saltSz) {\n        *buffer_size = srp->saltSz;\n        return -2;\n    }\n\n    memcpy(buffer, srp->salt, srp->saltSz);\n    *buffer_size = srp->saltSz;\n    return 0;\n}\n\n\nint crypto_srp_get_public_key(Srp *srp, byte *buffer, size_t *buffer_size) {\n    if (buffer_size == NULL)\n        return -1;\n\n    // TODO: Fix hardcoded public key size\n    if (*buffer_size < 384) {\n        *buffer_size = 384;\n        return -2;\n    }\n\n    DEBUG(\"Calculating public key\");\n    word32 len = *buffer_size;\n    int r = wc_SrpGetPublic(srp, buffer, &len);\n    *buffer_size = len;\n    return r;\n}\n\n\nint crypto_srp_compute_key(\n    Srp *srp,\n    const byte *client_public_key, size_t client_public_key_size,\n    const byte *server_public_key, size_t server_public_key_size\n) {\n    int r = wc_SrpComputeKey(\n        srp,\n        (byte *)client_public_key, client_public_key_size,\n        (byte *)server_public_key, server_public_key_size\n    );\n    if (r) {\n        DEBUG(\"Failed to generate SRP shared secret key (code %d)\", r);\n        return r;\n    }\n\n    return 0;\n}\n\n\nint crypto_srp_verify(Srp *srp, const byte *proof, size_t proof_size) {\n    int r = wc_SrpVerifyPeersProof(srp, (byte *)proof, proof_size);\n    if (r) {\n        DEBUG(\"Failed to verify client SRP proof (code %d)\", r);\n        return r;\n    }\n\n    return 0;\n}\n\n\nint crypto_srp_get_proof(Srp *srp, byte *proof, size_t *proof_size) {\n    if (proof_size == NULL)\n        return -1;\n\n    if (*proof_size < WC_SHA512_DIGEST_SIZE) {\n        *proof_size = WC_SHA512_DIGEST_SIZE;\n        return -2;\n    }\n\n    word32 proof_len = *proof_size;\n    int r = wc_SrpGetProof(srp, proof, &proof_len);\n    *proof_size = proof_len;\n\n    return r;\n}\n\n\nint crypto_hkdf(\n    const byte *key, size_t key_size,\n    const byte *salt, size_t salt_size,\n    const byte *info, size_t info_size,\n    byte *output, size_t *output_size\n) {\n    if (output_size == NULL)\n        return -1;\n\n    if (*output_size < 32) {\n        *output_size = 32;\n        return -2;\n    }\n\n    *output_size = 32;\n\n    int r = wc_HKDF(\n        SHA512,\n        key, key_size,\n        salt, salt_size,\n        info, info_size,\n\n        output, *output_size\n    );\n\n    return r;\n}\n\n\nint crypto_srp_hkdf(\n    Srp *srp,\n    const byte *salt, size_t salt_size,\n    const byte *info, size_t info_size,\n    byte *output, size_t *output_size\n) {\n    return crypto_hkdf(\n        srp->key, srp->keySz,\n        salt, salt_size,\n        info, info_size,\n        output, output_size\n    );\n}\n\n\nint crypto_chacha20poly1305_decrypt(\n    const byte *key, const byte *nonce, const byte *aad, size_t aad_size,\n    const byte *message, size_t message_size,\n    byte *decrypted, size_t *decrypted_size\n) {\n    if (message_size <= CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE) { \n        DEBUG(\"Decrypted message is too small\");\n        return -2;\n    }\n\n    if (decrypted_size == NULL)\n        return -1;\n\n    size_t len = message_size - CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE;\n    if (*decrypted_size < len) {\n        *decrypted_size = len;\n        return -2;\n    }\n\n    *decrypted_size = len;\n\n    int r = wc_ChaCha20Poly1305_Decrypt(\n        key, nonce, aad, aad_size,\n        message, len, &message[len],\n        decrypted\n    );\n\n    return r;\n}\n\nint crypto_chacha20poly1305_encrypt(\n    const byte *key, const byte *nonce, const byte *aad, size_t aad_size,\n    const byte *message, size_t message_size,\n    byte *encrypted, size_t *encrypted_size\n) {\n    if (encrypted_size == NULL)\n        return -1;\n\n    size_t len = message_size + CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE;\n    if (*encrypted_size < len) {\n        *encrypted_size = len;\n        return -1;\n    }\n\n    *encrypted_size = len;\n\n    int r = wc_ChaCha20Poly1305_Encrypt(\n        key, nonce, aad, aad_size,\n        message, message_size,\n        encrypted, encrypted+message_size\n    );\n\n    return r;\n}\n\n\nint crypto_ed25519_init(ed25519_key *key) {\n    int r = wc_ed25519_init(key);\n    if (r) {\n        return r;\n    }\n    return 0;\n}\n\n\ned25519_key *crypto_ed25519_new() {\n    ed25519_key *key = malloc(sizeof(ed25519_key));\n    int r = crypto_ed25519_init(key);\n    if (r) {\n        free(key);\n        return NULL;\n    }\n    return key;\n}\n\n\nvoid crypto_ed25519_free(ed25519_key *key) {\n    if (key)\n        free(key);\n}\n\nint crypto_ed25519_generate(ed25519_key *key) {\n    int r;\n    r = crypto_ed25519_init(key);\n    if (r)\n        return r;\n\n    WC_RNG rng;\n    r = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, key);\n    if (r) {\n        DEBUG(\"Failed to generate key (code %d)\", r);\n        return r;\n    }\n\n    return 0;\n}\n\nint crypto_ed25519_import_key(ed25519_key *key, const byte *data, size_t size) {\n    return wc_ed25519_import_private_key(\n        data, ED25519_KEY_SIZE,\n        data + ED25519_KEY_SIZE, ED25519_PUB_KEY_SIZE,\n        key\n    );\n}\n\nint crypto_ed25519_export_key(const ed25519_key *key, byte *buffer, size_t *size) {\n    if (size == NULL)\n        return -1;\n\n    if (*size < ED25519_KEY_SIZE + ED25519_PUB_KEY_SIZE) {\n        *size = ED25519_KEY_SIZE + ED25519_PUB_KEY_SIZE;\n        return -2;\n    }\n\n    word32 key_size = *size;\n    int r = wc_ed25519_export_private((ed25519_key *)key, buffer, &key_size);\n    *size = key_size;\n    return r;\n}\n\nint crypto_ed25519_import_public_key(ed25519_key *key, const byte *data, size_t size) {\n    return wc_ed25519_import_public(data, size, key);\n}\n\nint crypto_ed25519_export_public_key(const ed25519_key *key, byte *buffer, size_t *size) {\n    if (size == NULL) {\n        return -1;\n    }\n\n    if (*size < ED25519_PUB_KEY_SIZE) {\n        *size = ED25519_PUB_KEY_SIZE;\n        return -2;\n    }\n\n    word32 len = *size;\n    int r = wc_ed25519_export_public((ed25519_key *)key, buffer, &len);\n    *size = len;\n    return r;\n}\n\n\nint crypto_ed25519_sign(\n    const ed25519_key *key,\n    const byte *message, size_t message_size,\n    byte *signature, size_t *signature_size\n) {\n    if (signature_size == NULL) {\n        return -1;\n    }\n\n    if (*signature_size < ED25519_SIG_SIZE) {\n        *signature_size = ED25519_SIG_SIZE;\n        return -2;\n    }\n\n    word32 len = *signature_size;\n\n    int r = wc_ed25519_sign_msg(\n        message, message_size,\n        signature, &len,\n        (ed25519_key *)key\n    );\n    *signature_size = len;\n    return r;\n}\n\n\nint crypto_ed25519_verify(\n    const ed25519_key *key,\n    const byte *message, size_t message_size,\n    const byte *signature, size_t signature_size\n) {\n#if defined(ARDUINO_HOMEKIT_SKIP_ED25519_VERIFY)\n\treturn 0;\n#else\n    int verified;\n    int r = wc_ed25519_verify_msg(\n        signature, signature_size,\n        message, message_size,\n        &verified, (ed25519_key *)key\n    );\n    //return (r == 0) && (verified == 1);\n    return !r && !verified;\n#endif\n}\n\n\nint crypto_curve25519_init(curve25519_key *key) {\n    int r = wc_curve25519_init(key);\n    if (r) {\n        return r;\n    }\n    return 0;\n}\n\n\nvoid crypto_curve25519_done(curve25519_key *key) {\n    if (!key)\n        return;\n\n    wc_curve25519_free(key);\n}\n\n\nint crypto_curve25519_generate(curve25519_key *key) {\n    int r;\n    r = crypto_curve25519_init(key);\n    if (r) {\n        return r;\n    }\n\n    WC_RNG rng;\n    r = wc_curve25519_make_key(&rng, 32, key);\n    if (r) {\n        crypto_curve25519_done(key);\n        return -1;\n    }\n\n    return 0;\n}\n\n\nint crypto_curve25519_import_public(curve25519_key *key, const byte *data, size_t size) {\n    return wc_curve25519_import_public_ex(data, size, key, EC25519_LITTLE_ENDIAN);\n}\n\n\nint crypto_curve25519_export_public(const curve25519_key *key, byte *buffer, size_t *size) {\n    if (*size == 0) {\n        word32 len = 0;\n        int r = wc_curve25519_export_public_ex(\n            (curve25519_key *)key,\n            (byte *)&len, &len,\n            EC25519_LITTLE_ENDIAN\n        );\n        *size = len;\n        return r;\n    }\n\n    word32 len = *size;\n    int r = wc_curve25519_export_public_ex(\n        (curve25519_key *)key,\n        buffer, &len,\n        EC25519_LITTLE_ENDIAN\n    );\n    *size = len;\n    return r;\n}\n\n\nint crypto_curve25519_shared_secret(const curve25519_key *private_key, const curve25519_key *public_key, byte *buffer, size_t *size) {\n    if (*size < CURVE25519_KEYSIZE) {\n        *size = CURVE25519_KEYSIZE;\n        return -2;\n    }\n\n    word32 len = *size;\n    int r = wc_curve25519_shared_secret_ex(\n        (curve25519_key *)private_key,\n        (curve25519_key *)public_key,\n        buffer, &len, EC25519_LITTLE_ENDIAN\n    );\n    *size = len;\n    return r;\n}\n\n"
  },
  {
    "path": "src/crypto.h",
    "content": "#ifndef __CRYPTO_H__\n#define __CRYPTO_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n//wolfssl-3.13.0-stable\n\n#include <stdlib.h>\n\n#include <wolfssl/wolfcrypt/ed25519.h>\n#include <wolfssl/wolfcrypt/curve25519.h>\n#include <wolfssl/wolfcrypt/settings.h>\n\n//#include \"wolfcrypt/hmac.h\"\n//#include \"wolfcrypt/ed25519.h\"\n//#include \"wolfcrypt/curve25519.h\"\n//#include \"wolfcrypt/sha512.h\"\n//#include \"wolfcrypt/chacha20_poly1305.h\"\n//#include \"wolfcrypt/srp.h\"\n//#include \"wolfcrypt/error-crypt.h\"\n\ntypedef unsigned char byte;\n\n#define HKDF_HASH_SIZE 32  // CHACHA20_POLY1305_AEAD_KEYSIZE\n\nint crypto_hkdf(\n    const byte *key, size_t key_size,\n    const byte *salt, size_t salt_size,\n    const byte *info, size_t info_size,\n    byte *output, size_t *output_size\n);\n\n// SRP\nstruct _Srp;\ntypedef struct _Srp Srp;\n\n\nSrp *crypto_srp_new();\nvoid crypto_srp_free(Srp *srp);\n\nint crypto_srp_init(Srp *srp, const char *username, const char *password);\n\nint crypto_srp_get_salt(Srp *srp, byte *buffer, size_t *buffer_length);\nint crypto_srp_get_public_key(Srp *srp, byte *buffer, size_t *buffer_length);\n\nint crypto_srp_compute_key(\n    Srp *srp,\n    const byte *client_public_key, size_t client_public_key_size,\n    const byte *server_public_key, size_t server_public_key_size\n);\nint crypto_srp_verify(Srp *srp, const byte *proof, size_t proof_size);\nint crypto_srp_get_proof(Srp *srp, byte *proof, size_t *proof_size);\n\nint crypto_srp_hkdf(\n    Srp *srp,\n    const byte *salt, size_t salt_size,\n    const byte *info, size_t info_size,\n    byte *output, size_t *output_size\n);\n\nint crypto_chacha20poly1305_encrypt(\n    const byte *key, const byte *nonce, const byte *aad, size_t aad_size,\n    const byte *message, size_t message_size,\n    byte *encrypted, size_t *encrypted_size\n);\nint crypto_chacha20poly1305_decrypt(\n    const byte *key, const byte *nonce, const byte *aad, size_t aad_size,\n    const byte *message, size_t message_size,\n    byte *decrypted, size_t *descrypted_size\n);\n\n// ED25519\nint crypto_ed25519_init(ed25519_key *key);\ned25519_key *crypto_ed25519_new();\nint crypto_ed25519_generate(ed25519_key *key);\nvoid crypto_ed25519_free(ed25519_key *key);\n\nint crypto_ed25519_import_key(\n    ed25519_key *key,\n    const byte *data, size_t size\n);\nint crypto_ed25519_export_key(\n    const ed25519_key *key,\n    byte *buffer, size_t *size\n);\n\nint crypto_ed25519_import_public_key(\n    ed25519_key *key,\n    const byte *data, size_t size\n);\nint crypto_ed25519_export_public_key(\n    const ed25519_key *key,\n    byte *buffer, size_t *size\n);\n\nint crypto_ed25519_sign(\n    const ed25519_key *key,\n    const byte *message, size_t message_size,\n    byte *signature, size_t *signature_size\n);\nint crypto_ed25519_verify(\n    const ed25519_key *key,\n    const byte *message, size_t message_size,\n    const byte *signature, size_t signature_size\n);\n\n\n// CURVE25519\nint crypto_curve25519_init(curve25519_key *key);\nint crypto_curve25519_done(curve25519_key *key);\nint crypto_curve25519_generate(curve25519_key *key);\nint crypto_curve25519_import_public(\n    curve25519_key *key,\n    const byte *data, size_t size\n);\nint crypto_curve25519_export_public(\n    const curve25519_key *key,\n    byte *buffer, size_t *size\n);\nint crypto_curve25519_shared_secret(\n    const curve25519_key *private_key,\n    const curve25519_key *public_key,\n    byte *buffer, size_t *size\n);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // __CRYPTO_H__\n"
  },
  {
    "path": "src/esp_xpgm.h",
    "content": "/*\n * xpgm.h\n *\n *  Created on: 2020-03-08\n *      Author: Wang Bin\n */\n\n#ifndef ESP_XPGM_H_\n#define ESP_XPGM_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <pgmspace.h>\n#include <stdint.h>\n#include <string.h>\n\n//see \"osapi.h\"\n/*\n This function works only after Serial.setDebugOutput(true); ?\n otherwise Serial prints nothing.\n #define esp_printf(fmt, ...) do {\t\\\n\tstatic const char flash_str[] ICACHE_RODATA_ATTR STORE_ATTR = fmt;\t\\\n\tos_printf_plus(flash_str, ##__VA_ARGS__);\t\\\n\t} while(0)*/\n\n#define XPGM_PRINTF(fmt, ...)   printf_P(PSTR(fmt) , ##__VA_ARGS__);\n\n#define XPGM_VAR(v0, v1) v0##v1\n\n// pgm_ptr --> ram_ptr\n#define XPGM_CPY(ram_ptr, pgm_ptr, size)  memcpy_P(ram_ptr, pgm_ptr, size)\n\n#define XPGM_BUFFCPY(buff_type, buff_name, pgm_ptr, size)  size_t XPGM_VAR(buff_name, _size) = size; \\\n\t\tbuff_type buff_name[XPGM_VAR(buff_name, _size)]; \\\n\t\tXPGM_CPY(buff_name, pgm_ptr, XPGM_VAR(buff_name, _size));\n\n#define XPGM_BUFFCPY_ARRAY(buff_type, buff_name, pgm_array)  XPGM_BUFFCPY(buff_type, buff_name, pgm_array, sizeof(pgm_array))\n\n#define XPGM_BUFFCPY_STRING(buff_type, buff_name, pgm_string) XPGM_BUFFCPY(buff_type, buff_name, pgm_string, strlen_P(pgm_string) + 1)\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* ESP_XPGM_H_ */\n"
  },
  {
    "path": "src/homekit/characteristics.h",
    "content": "#ifndef __HOMEKIT_CHARACTERISTICS__\n#define __HOMEKIT_CHARACTERISTICS__\n\n#include <homekit/types.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define HOMEKIT_SHORT_APPLE_UUIDS\n\n// MARK: - Apple UUID\n\n#ifdef HOMEKIT_SHORT_APPLE_UUIDS\n    #define HOMEKIT_APPLE_UUID8(value) (value)\n    #define HOMEKIT_APPLE_UUID7(value) (value)\n    #define HOMEKIT_APPLE_UUID6(value) (value)\n    #define HOMEKIT_APPLE_UUID5(value) (value)\n    #define HOMEKIT_APPLE_UUID4(value) (value)\n    #define HOMEKIT_APPLE_UUID3(value) (value)\n    #define HOMEKIT_APPLE_UUID2(value) (value)\n    #define HOMEKIT_APPLE_UUID1(value) (value)\n    #define HOMEKIT_APPLE_UUID0(value) (value)\n#else\n    #define HOMEKIT_APPLE_UUID8(value) (value \"-0000-1000-8000-0026BB765291\")\n    #define HOMEKIT_APPLE_UUID7(value) HOMEKIT_APPLE_UUID8(\"0\" value)\n    #define HOMEKIT_APPLE_UUID6(value) HOMEKIT_APPLE_UUID7(\"0\" value)\n    #define HOMEKIT_APPLE_UUID5(value) HOMEKIT_APPLE_UUID6(\"0\" value)\n    #define HOMEKIT_APPLE_UUID4(value) HOMEKIT_APPLE_UUID5(\"0\" value)\n    #define HOMEKIT_APPLE_UUID3(value) HOMEKIT_APPLE_UUID4(\"0\" value)\n    #define HOMEKIT_APPLE_UUID2(value) HOMEKIT_APPLE_UUID3(\"0\" value)\n    #define HOMEKIT_APPLE_UUID1(value) HOMEKIT_APPLE_UUID2(\"0\" value)\n    #define HOMEKIT_APPLE_UUID0(value) HOMEKIT_APPLE_UUID1(\"0\" value)\n#endif\n\n// MARK: - Services\n\n/**\n Defines information about a certain accessory, including a action to identify the accessory.\n \n Required Characteristics:\n - IDENTIFY\n - MANUFACTURER\n - MODEL\n - NAME\n - SERIAL_NUMBER\n - FIRMWARE_REVISION\n \n Optional Characteristics:\n - HARDWARE_REVISION\n - ACCESSORY_FLAGS\n */\n#define HOMEKIT_SERVICE_ACCESSORY_INFORMATION HOMEKIT_APPLE_UUID2(\"3E\")\n\n/**\n Defines that the accessory constains a fan. For more features see FAN2.\n \n Required Characteristics:\n - ON\n \n Optional Characteristics:\n - NAME\n - ROTATION_DIRECTION\n - ROTATION_SPEED\n */\n#define HOMEKIT_SERVICE_FAN HOMEKIT_APPLE_UUID2(\"40\")\n\n/**\n Defines that the accessory has control over the opening of a garage door.\n\n Required Characteristics:\n - CURRENT_DOOR_STATE\n - TARGET_DOOR_STATE\n - OBSTRUCTION_DETECTED\n \n Optional Characteristics:\n - NAME\n - LOCK_CURRENT_STATE\n - LOCK_TARGET_STATE\n */\n#define HOMEKIT_SERVICE_GARAGE_DOOR_OPENER HOMEKIT_APPLE_UUID2(\"41\")\n\n/**\n Defines that the accessory contains a lightbulb.\n\n Required Characteristics:\n - ON\n \n Optional Characteristics:\n - NAME\n - BRIGHTNESS\n - HUE\n - SATURATION\n - COLOR_TEMPERATURE\n */\n#define HOMEKIT_SERVICE_LIGHTBULB HOMEKIT_APPLE_UUID2(\"43\")\n\n/**\n Defines a number of additional settings, rules and information on a lock mechanism inside of a accessory.\n \n Required Characteristics:\n - LOCK_CONTROL_POINT\n - VERSION\n \n Optional Characteristics:\n - NAME\n - LOGS\n - AUDIO_FEEDBACK\n - LOCK_MANAGEMENT_AUTO_SECURITY_TIMEOUT\n - ADMINISTRATOR_ONLY_ACCESS\n - LOCK_LAST_KNOWN_ACTION\n - CURRENT_DOOR_STATE\n - MOTION_DETECTED\n */\n#define HOMEKIT_SERVICE_LOCK_MANAGEMENT HOMEKIT_APPLE_UUID2(\"44\")\n\n/**\n Defines that the accessory constains a lock mechanism. This can be combined with Lock Management.\n \n Required Characteristics:\n - LOCK_CURRENT_STATE\n - LOCK_TARGET_STATE\n \n Optional Characteristics:\n - NAME\n */\n#define HOMEKIT_SERVICE_LOCK_MECHANISM HOMEKIT_APPLE_UUID2(\"45\")\n\n/**\n Defines that the accessory contains an outlet/socket.\n \n Required Characteristics:\n - ON\n - OUTLET_IN_USE\n \n Optional Characteristics:\n - NAME\n */\n#define HOMEKIT_SERVICE_OUTLET HOMEKIT_APPLE_UUID2(\"47\")\n\n/**\n Defines that the accessory contains a switch.\n \n Required Characteristics:\n - ON\n \n Optional Characteristics:\n - NAME\n */\n#define HOMEKIT_SERVICE_SWITCH HOMEKIT_APPLE_UUID2(\"49\")\n\n/**\n Defines that the accessory contains a thermostat.\n\n Required Characteristics:\n - CURRENT_HEATING_COOLING_STATE\n - TARGET_HEATING_COOLING_STATE\n - CURRENT_TEMPERATURE\n - TARGET_TEMPERATURE\n - TEMPERATURE_DISPLAY_UNITS\n \n Optional Characteristics:\n - NAME\n - CURRENT_RELATIVE_HUMIDITY\n - TARGET_RELATIVE_HUMIDITY\n - COOLING_THRESHOLD_TEMPERATURE\n - HEATING_THRESHOLD_TEMPERATURE\n */\n#define HOMEKIT_SERVICE_THERMOSTAT HOMEKIT_APPLE_UUID2(\"4A\")\n\n/**\n Defines that the accessory contains a air quality sensor.\n\n Required Characteristics:\n - AIR_QUALITY\n \n Optional Characteristics:\n - NAME\n - STATUS_ACTIVE\n - STATUS_FAULT\n - STATUS_TAMPERED\n - STATUS_LOW_BATTERY\n - OZONE_DENSITY\n - NITROGEN_DIOXIDE_DENSITY\n - SULPHUR_DIOXIDE_DENSITY\n - PM25_DENSITY\n - PM10_DENSITY\n - VOC_DENSITY\n - CARBON_MONOXIDE_LEVEL\n - CARBON_DIOXIDE_LEVEL\n */\n#define HOMEKIT_SERVICE_AIR_QUALITY_SENSOR HOMEKIT_APPLE_UUID2(\"8D\")\n\n/**\n Defines that the accessory contains a security system.\n \n Required Characteristics:\n - SECURITY_SYSTEM_CURRENT_STATE\n - SECURITY_SYSTEM_TARGET_STATE\n \n Optional Characteristics:\n - NAME\n - STATUS_FAULT\n - STATUS_TAMPERED\n - SECURITY_SYSTEM_ALARM_TYPE\n */\n#define HOMEKIT_SERVICE_SECURITY_SYSTEM HOMEKIT_APPLE_UUID2(\"7E\")\n\n/**\n Defines that the accessory contains a monoxide dioxide (CO) sensor.\n \n Required Characteristics:\n - CARBON_MONOXIDE_DETECTED\n \n Optional Characteristics:\n - NAME\n - STATUS_ACTIVE\n - STATUS_FAULT\n - STATUS_LOW_BATTERY\n - STATUS_TAMPERED\n - CARBON_MONOXIDE_LEVEL\n - CARBON_MONOXIDE_PEAK_LEVEL\n */\n#define HOMEKIT_SERVICE_CARBON_MONOXIDE_SENSOR HOMEKIT_APPLE_UUID2(\"7F\")\n\n/**\n Defines that the accessory contains a contact sensor.\n\n Required Characteristics:\n - CONTACT_SENSOR_STATE\n \n Optional Characteristics:\n - NAME\n - STATUS_ACTIVE\n - STATUS_FAULT\n - STATUS_TAMPERED\n - STATUS_LOW_BATTERY\n */\n#define HOMEKIT_SERVICE_CONTACT_SENSOR HOMEKIT_APPLE_UUID2(\"80\")\n\n/**\n Defines that the accessory contains or controls a door.\n \n Required Characteristics:\n - CURRENT_POSITION\n - TARGET_POSITION\n - POSITION_STATE\n \n Optional Characteristics:\n - NAME\n - HOLD_POSITION\n - OBSTRUCTION_DETECTED\n */\n#define HOMEKIT_SERVICE_DOOR HOMEKIT_APPLE_UUID2(\"81\")\n\n/**\n Defines that the accessory contains a (relative) humidity sensor.\n\n Required Characteristics:\n - CURRENT_RELATIVE_HUMIDITY\n \n Optional Characteristics:\n - NAME\n - STATUS_ACTIVE\n - STATUS_FAULT\n - STATUS_TAMPERED\n - STATUS_LOW_BATTERY\n */\n#define HOMEKIT_SERVICE_HUMIDITY_SENSOR HOMEKIT_APPLE_UUID2(\"82\")\n\n/**\n Defines that the accessory contains a (water) leak sensor.\n \n Required Characteristics:\n - LEAK_DETECTED\n \n Optional Characteristics:\n - NAME\n - STATUS_ACTIVE\n - STATUS_FAULT\n - STATUS_LOW_BATTERY\n - STATUS_TAMPERED\n */\n#define HOMEKIT_SERVICE_LEAK_SENSOR HOMEKIT_APPLE_UUID2(\"83\")\n\n/**\n Defines that the accessory contains a light sensor.\n \n Required Characteristics:\n - CURRENT_AMBIENT_LIGHT_LEVEL\n \n Optional Characteristics:\n - NAME\n - STATUS_ACTIVE\n - STATUS_FAULT\n - STATUS_LOW_BATTERY\n - STATUS_TAMPERED\n */\n#define HOMEKIT_SERVICE_LIGHT_SENSOR HOMEKIT_APPLE_UUID2(\"84\")\n\n/**\n Defines that the accessory contains a motion sensor.\n \n Required Characteristics:\n - MOTION_DETECTED\n \n Optional Characteristics:\n - NAME\n - STATUS_ACTIVE\n - STATUS_FAULT\n - STATUS_LOW_BATTERY\n - STATUS_TAMPERED\n */\n#define HOMEKIT_SERVICE_MOTION_SENSOR HOMEKIT_APPLE_UUID2(\"85\")\n\n/**\n Defines that the accessory contains a occupancy sensor.\n \n Required Characteristics:\n - OCCUPANCY_DETECTED\n \n Optional Characteristics:\n - NAME\n - STATUS_ACTIVE\n - STATUS_FAULT\n - STATUS_LOW_BATTERY\n - STATUS_TAMPERED\n */\n#define HOMEKIT_SERVICE_OCCUPANCY_SENSOR HOMEKIT_APPLE_UUID2(\"86\")\n\n/**\n Defines that the accessory contains a smoke sensor.\n \n Required Characteristics:\n - SMOKE_DETECTED\n \n Optional Characteristics:\n - NAME\n - STATUS_ACTIVE\n - STATUS_FAULT\n - STATUS_LOW_BATTERY\n - STATUS_TAMPERED\n */\n#define HOMEKIT_SERVICE_SMOKE_SENSOR HOMEKIT_APPLE_UUID2(\"87\")\n\n/**\n Defines that the accessory contains a stateless programmable switch, also called a button.\n\n Required Characteristics:\n - PROGRAMMABLE_SWITCH_EVENT\n \n Optional Characteristics:\n - NAME\n - SERVICE_LABEL_INDEX\n */\n#define HOMEKIT_SERVICE_STATELESS_PROGRAMMABLE_SWITCH HOMEKIT_APPLE_UUID2(\"89\")\n\n/**\n Defines that the accessory contains a temperature sensor.\n \n Required Characteristics:\n - CURRENT_TEMPERATURE\n \n Optional Characteristics:\n - NAME\n - STATUS_ACTIVE\n - STATUS_FAULT\n - STATUS_TAMPERED\n - STATUS_LOW_BATTERY\n */\n#define HOMEKIT_SERVICE_TEMPERATURE_SENSOR HOMEKIT_APPLE_UUID2(\"8A\")\n\n/**\n Defines that the accessory contains or controls a window.\n\n Required Characteristics:\n - CURRENT_POSITION\n - TARGET_POSITION\n - POSITION_STATE\n \n Optional Characteristics:\n - NAME\n - HOLD_POSITION\n - OBSTRUCTION_DETECTED\n */\n#define HOMEKIT_SERVICE_WINDOW HOMEKIT_APPLE_UUID2(\"8B\")\n\n/**\n Defines that the accessory constains a window covering such as a blind or curtain.\n \n Required Characteristics:\n - CURRENT_POSITION\n - TARGET_POSITION\n - POSITION_STATE\n \n Optional Characteristics:\n - NAME\n - HOLD_POSITION\n - TARGET_HORIZONTAL_TILT_ANGLE\n - TARGET_VERTICAL_TILT_ANGLE\n - CURRENT_HORIZONTAL_TILT_ANGLE\n - CURRENT_VERTICAL_TILT_ANGLE\n - OBSTRUCTION_DETECTED\n */\n#define HOMEKIT_SERVICE_WINDOW_COVERING HOMEKIT_APPLE_UUID2(\"8C\")\n\n/**\n Defines that the accessory contains a battery that can be monitored.\n \n Required Characteristics:\n - BATTERY_LEVEL\n - CHARGING_STATE\n - STATUS_LOW_BATTERY\n \n Optional Characteristics:\n - NAME\n */\n#define HOMEKIT_SERVICE_BATTERY_SERVICE HOMEKIT_APPLE_UUID2(\"96\")\n\n/**\n Defines that the accessory contains a carbon dioxide (CO2) sensor.\n\n Required Characteristics:\n - CARBON_DIOXIDE_DETECTED\n \n Optional Characteristics:\n - NAME\n - STATUS_ACTIVE\n - STATUS_FAULT\n - STATUS_LOW_BATTERY\n - STATUS_TAMPERED\n - CARBON_DIOXIDE_LEVEL\n - CARBON_DIOXIDE_PEAK_LEVEL\n */\n#define HOMEKIT_SERVICE_CARBON_DIOXIDE_SENSOR HOMEKIT_APPLE_UUID2(\"97\")\n\n/**\n Defines that the accessory allows for the management of a RTP (video) stream. This is mostly used for video doorbells and cameras and may not work standalone.\n \n Required Characteristics:\n - SUPPORTED_VIDEO_STREAM_CONFIGURATION\n - SUPPORTED_AUDIO_STREAM_CONFIGURATION\n - SUPPORTED_RTP_CONFIGURATION\n - SELECTED_RTPS_CONFIGURATION\n - STREAMING_STATUS\n - SETUP_ENDPOINTS\n \n Optional Characteristics:\n - NAME\n - VOLUME\n */\n#define HOMEKIT_SERVICE_CAMERA_RTP_STREAM_MANAGEMENT HOMEKIT_APPLE_UUID3(\"110\")\n\n/**\n Defines that the accessory contains a microphone. This is mostly used for video doorbells and cameras and may not work standalone.\n \n Required Characteristics:\n - MUTE\n \n Optional Characteristics:\n - NAME\n - VOLUME\n */\n#define HOMEKIT_SERVICE_MICROPHONE HOMEKIT_APPLE_UUID3(\"112\")\n\n/**\n Defines that the accessory contains a speaker. This is mostly used for video doorbells and cameras and may not work standalone.\n\n Required Characteristics:\n - MUTE\n \n Optional Characteristics:\n - NAME\n - VOLUME\n */\n#define HOMEKIT_SERVICE_SPEAKER HOMEKIT_APPLE_UUID3(\"113\")\n\n/**\n Defines that the accessory contains a doorbell. This is mostly used for video doorbells and may not work standalone.\n\n Required Characteristics:\n - PROGRAMMABLE_SWITCH_EVENT\n \n Optional Characteristics:\n - NAME\n - BRIGHTNESS\n - VOLUME\n */\n#define HOMEKIT_SERVICE_DOORBELL HOMEKIT_APPLE_UUID3(\"121\")\n\n/**\n Defines that the accessory contains a fan that implements version 2 of the fan features.\n \n Required Characteristics:\n - ACTIVE\n \n Optional Characteristics:\n - NAME\n - CURRENT_FAN_STATE\n - TARGET_FAN_STATE\n - LOCK_PHYSICAL_CONTROLS\n - ROTATION_DIRECTION\n - ROTATION_SPEED\n - SWING_MODE\n */\n#define HOMEKIT_SERVICE_FAN2 HOMEKIT_APPLE_UUID2(\"B7\")\n\n/**\n Defines that the accessory contains slats that tilt horizontally or vertically.\n\n Required Characteristics:\n - SLAT_TYPE\n - CURRENT_SLAT_STATE\n \n Optional Characteristics:\n - NAME\n - CURRENT_TILT_ANGLE\n - TARGET_TILT_ANGLE\n - SWING_MODE\n */\n#define HOMEKIT_SERVICE_SLAT HOMEKIT_APPLE_UUID2(\"B9\")\n\n/**\n Defines that the accessory contains a filter that can notify the user of needing maintenace.\n \n Required Characteristics:\n - FILTER_CHANGE_INDICATION\n \n Optional Characteristics:\n - NAME\n - FILTER_LIFE_LEVEL\n - RESET_FILTER_INDICATION\n */\n#define HOMEKIT_SERVICE_FILTER_MAINTENANCE HOMEKIT_APPLE_UUID2(\"BA\")\n\n/**\n Defines that the accessory contains a air purifier.\n \n Required Characteristics:\n - ACTIVE\n - CURRENT_AIR_PURIFIER_STATE\n - TARGET_AIR_PURIFIER_STATE\n \n Optional Characteristics:\n - NAME\n - SWING_MODE\n - LOCK_PHYSICAL_CONTROLS\n - ROTATION_SPEED\n */\n#define HOMEKIT_SERVICE_AIR_PURIFIER HOMEKIT_APPLE_UUID2(\"BB\")\n\n/**\n Describes the service label scheme of the accessory. See the official HAP specification for more information.\n\n Required Characteristics:\n - ACTIVE\n - SERVICE_LABEL_NAMESPACE\n \n Optional Characteristics:\n - NAME\n */\n#define HOMEKIT_SERVICE_SERVICE_LABEL HOMEKIT_APPLE_UUID2(\"CC\")\n\n/**\n Defines that the accessory contains a faucet.\n \n Required Characteristics:\n - ACTIVE\n \n Optional Characteristics:\n - NAME\n - STATUS_FAULT\n */\n#define HOMEKIT_SERVICE_FAUCET HOMEKIT_APPLE_UUID2(\"D7\")\n\n/**\n Defines that the accessory supports the control of a irrigation system.\n \n Required Characteristics:\n - ACTIVE\n - PROGRAM_MODE\n - IN_USE\n \n Optional Characteristics:\n - NAME\n - REMAINING_DURATION\n - STATUS_FAULT\n */\n#define HOMEKIT_SERVICE_IRRIGATION_SYSTEM HOMEKIT_APPLE_UUID2(\"CF\")\n\n/**\n Defines that the accessory contains a (water) valve.\n \n Required Characteristics:\n - ACTIVE\n - IN_USE\n - VALVE_TYPE\n \n Optional Characteristics:\n - NAME\n - SET_DURATION\n - REMAINING_DURATION\n - IS_CONFIGURED\n - SERVICE_LABEL_INDEX\n - STATUS_FAULT\n */\n#define HOMEKIT_SERVICE_VALVE HOMEKIT_APPLE_UUID2(\"D0\")\n\n/**\n Defines that the accessory contains a heater and/or cooler.\n \n Accessory Category:\n - 20: Heaters\n - 21: Air Conditioners\n \n Required Characteristics:\n - ACTIVE\n - CURRENT_TEMPERATURE\n - CURRENT_HEATER_COOLER_STATE\n - TARGET_HEATER_COOLER_STATE\n \n Optional Characteristics:\n - NAME\n - ROTATION_SPEED\n - TEMPERATURE_DISPLAY_UNITS\n - SWING_MODE\n - COOLING_THRESHOLD_TEMPERATURE\n - HEATING_THRESHOLD_TEMPERATURE\n - LOCK_PHYSICAL_CONTROLS\n */\n#define HOMEKIT_SERVICE_HEATER_COOLER HOMEKIT_APPLE_UUID2(\"BC\")\n\n/**\n Defines that the accessory contains a humidifier and/or dehumidifier.\n \n Accessory Category:\n - 22: Humidifiers\n - 23: Dehumidifiers\n \n Required Characteristics:\n - ACTIVE\n - CURRENT_RELATIVE_HUMIDITY\n - CURRENT_HUMIDIFIER_DEHUMIDIFIER_STATE\n - TARGET_HUMIDIFIER_DEHUMIDIFIER_STATE\n \n Optional Characteristics:\n - NAME\n - RELATIVE_HUMIDITY_DEHUMIDIFIER_THRESHOLD\n - RELATIVE_HUMIDITY_HUMIDIFIER_THRESHOLD\n - ROTATION_SPEED\n - SWING_MODE\n - WATER_LEVEL\n - LOCK_PHYSICAL_CONTROLS\n */\n#define HOMEKIT_SERVICE_HUMIDIFIER_DEHUMIDIFIER HOMEKIT_APPLE_UUID2(\"BD\")\n\n/**\n Defines that the accessory has control over television\n\n Required Characteristics:\n - ACTIVE\n - ACTIVE_IDENTIFIER\n - CONFIGURED_NAME\n - SLEEP_DISCOVERY_MODE\n\n Optional Characteristics:\n - BRIGHTNESS\n - CLOSED_CAPTIONS\n - DISPLAY_ORDER\n - CURRENT_MEDIA_STATE\n - TARGET_MEDIA_STATE\n - PICTURE_MODE\n - POWER_MODE_SELECTION\n - REMOTE_KEY\n */\n#define HOMEKIT_SERVICE_TELEVISION HOMEKIT_APPLE_UUID2(\"D8\")\n\n/**\n Defines that the accessory has control over television input source\n\n Required Characteristics:\n - NAME\n - CONFIGURED_NAME\n - INPUT_SOURCE_TYPE\n - IS_CONFIGURED\n - CURRENT_VISIBILITY_STATE\n\n Optional Characteristics:\n - IDENTIFIER\n - INPUT_DEVICE_TYPE\n - TARGET_VISIBILITY_STATE\n */\n#define HOMEKIT_SERVICE_INPUT_SOURCE HOMEKIT_APPLE_UUID2(\"D9\")\n\n/**\n Defines that the accessory has control over television speaker\n\n Required Characteristics:\n - MUTE\n\n Optional Characteristics:\n - ACTIVE\n - VOLUME\n - VOLUME_CONTROL_TYPE\n - VOLUME_SELECTOR\n - NAME\n */\n#define HOMEKIT_SERVICE_TELEVISION_SPEAKER HOMEKIT_APPLE_UUID3(\"113\")\n\n// MARK: - Characteristics\n\n#define HOMEKIT_CHARACTERISTIC_ADMINISTRATOR_ONLY_ACCESS HOMEKIT_APPLE_UUID1(\"1\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_ADMINISTRATOR_ONLY_ACCESS(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_ADMINISTRATOR_ONLY_ACCESS, \\\n    .description = \"Administrator Only Access\", \\\n    .format = homekit_format_bool, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_BOOL_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_AUDIO_FEEDBACK HOMEKIT_APPLE_UUID1(\"5\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_AUDIO_FEEDBACK(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_AUDIO_FEEDBACK, \\\n    .description = \"Audio Feedback\", \\\n    .format = homekit_format_bool, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_BOOL_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_BRIGHTNESS HOMEKIT_APPLE_UUID1(\"8\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_BRIGHTNESS(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_BRIGHTNESS, \\\n    .description = \"Brightness\", \\\n    .format = homekit_format_int, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .unit = homekit_unit_percentage, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_INT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_COOLING_THRESHOLD_TEMPERATURE HOMEKIT_APPLE_UUID1(\"D\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_COOLING_THRESHOLD_TEMPERATURE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_COOLING_THRESHOLD_TEMPERATURE, \\\n    .description = \"Cooling Threshold Temperature\", \\\n    .format = homekit_format_float, \\\n    .unit = homekit_unit_celsius, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {10}, \\\n    .max_value = (float[]) {35}, \\\n    .min_step = (float[]) {0.1}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_DOOR_STATE HOMEKIT_APPLE_UUID1(\"E\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_DOOR_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_DOOR_STATE, \\\n    .description = \"Current Door State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {4}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 5, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3, 4 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CURRENT_HEATING_COOLING_STATE_OFF 0\n#define HOMEKIT_CURRENT_HEATING_COOLING_STATE_HEAT 1\n#define HOMEKIT_CURRENT_HEATING_COOLING_STATE_COOL 2\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_HEATING_COOLING_STATE HOMEKIT_APPLE_UUID1(\"F\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_HEATING_COOLING_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_HEATING_COOLING_STATE, \\\n    .description = \"Current Heating Cooling State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {2}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 3, \\\n        .values = (uint8_t[]) { 0, 1, 2 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_RELATIVE_HUMIDITY HOMEKIT_APPLE_UUID2(\"10\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_RELATIVE_HUMIDITY(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_RELATIVE_HUMIDITY, \\\n    .description = \"Current Relative Humidity\", \\\n    .format = homekit_format_float, \\\n    .unit = homekit_unit_percentage, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_TEMPERATURE HOMEKIT_APPLE_UUID2(\"11\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_TEMPERATURE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_TEMPERATURE, \\\n    .description = \"Current Temperature\", \\\n    .format = homekit_format_float, \\\n    .unit = homekit_unit_celsius, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {0.1}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_FIRMWARE_REVISION HOMEKIT_APPLE_UUID2(\"52\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_FIRMWARE_REVISION(revision, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_FIRMWARE_REVISION, \\\n    .description = \"Firmware Revision\", \\\n    .format = homekit_format_string, \\\n    .permissions = homekit_permissions_paired_read, \\\n    .value = HOMEKIT_STRING_(revision), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_HARDWARE_REVISION HOMEKIT_APPLE_UUID2(\"53\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_HARDWARE_REVISION(revision, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_HARDWARE_REVISION, \\\n    .description = \"Hardware Revision\", \\\n    .format = homekit_format_string, \\\n    .permissions = homekit_permissions_paired_read, \\\n    .value = HOMEKIT_STRING_(revision), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_HEATING_THRESHOLD_TEMPERATURE HOMEKIT_APPLE_UUID2(\"12\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_HEATING_THRESHOLD_TEMPERATURE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_HEATING_THRESHOLD_TEMPERATURE, \\\n    .description = \"Heating Threshold Temperature\", \\\n    .format = homekit_format_float, \\\n    .unit = homekit_unit_celsius, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {25}, \\\n    .min_step = (float[]) {0.1}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_HUE HOMEKIT_APPLE_UUID2(\"13\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_HUE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_HUE, \\\n    .description = \"Hue\", \\\n    .format = homekit_format_float, \\\n    .unit = homekit_unit_arcdegrees, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {360}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_IDENTIFY HOMEKIT_APPLE_UUID2(\"14\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_IDENTIFY(callback, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_IDENTIFY, \\\n    .format = homekit_format_bool, \\\n    .permissions = homekit_permissions_paired_write, \\\n    .description = \"Identify\", \\\n    .setter = callback \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_LOCK_CONTROL_POINT HOMEKIT_APPLE_UUID2(\"19\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_LOCK_CONTROL_POINT(...) \\\n    .type = HOMEKIT_CHARACTERISTIC_LOCK_CONTROL_POINT, \\\n    .description = \"Lock Control Point\", \\\n    .format = homekit_format_tlv, \\\n    .permissions = homekit_permissions_paired_write, \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_LOCK_CURRENT_STATE HOMEKIT_APPLE_UUID2(\"1D\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_LOCK_CURRENT_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_LOCK_CURRENT_STATE, \\\n    .description = \"Lock Current State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {3}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 4, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_LOCK_LAST_KNOWN_ACTION HOMEKIT_APPLE_UUID2(\"1C\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_LOCK_LAST_KNOWN_ACTION(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_LOCK_LAST_KNOWN_ACTION, \\\n    .description = \"Lock Last Known Action\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {8}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 9, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_LOCK_MANAGEMENT_AUTO_SECURITY_TIMEOUT HOMEKIT_APPLE_UUID2(\"1A\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_LOCK_MANAGEMENT_AUTO_SECURITY_TIMEOUT(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_LOCK_MANAGEMENT_AUTO_SECURITY_TIMEOUT, \\\n    .description = \"Lock Management Auto Security Timeout\", \\\n    .format = homekit_format_uint32, \\\n    .unit = homekit_unit_seconds, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_UINT32_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_LOCK_TARGET_STATE HOMEKIT_APPLE_UUID2(\"1E\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_LOCK_TARGET_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_LOCK_TARGET_STATE, \\\n    .description = \"Lock Target State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_LOGS HOMEKIT_APPLE_UUID2(\"1F\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_LOGS(...) \\\n    .type = HOMEKIT_CHARACTERISTIC_LOGS, \\\n    .description = \"Logs\", \\\n    .format = homekit_format_tlv, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_MANUFACTURER HOMEKIT_APPLE_UUID2(\"20\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_MANUFACTURER(manufacturer, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_MANUFACTURER, \\\n    .description = \"Manufacturer\", \\\n    .format = homekit_format_string, \\\n    .permissions = homekit_permissions_paired_read, \\\n    .value = HOMEKIT_STRING_(manufacturer), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_MODEL HOMEKIT_APPLE_UUID2(\"21\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_MODEL(model, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_MODEL, \\\n    .description = \"Model\", \\\n    .format = homekit_format_string, \\\n    .permissions = homekit_permissions_paired_read, \\\n    .value = HOMEKIT_STRING_(model), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_MOTION_DETECTED HOMEKIT_APPLE_UUID2(\"22\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_MOTION_DETECTED(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_MOTION_DETECTED, \\\n    .description = \"Motion Detected\", \\\n    .format = homekit_format_bool, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_BOOL_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_NAME HOMEKIT_APPLE_UUID2(\"23\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_NAME(name, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_NAME, \\\n    .description = \"Name\", \\\n    .format = homekit_format_string, \\\n    .permissions = homekit_permissions_paired_read, \\\n    .value = HOMEKIT_STRING_(name), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_OBSTRUCTION_DETECTED HOMEKIT_APPLE_UUID2(\"24\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_OBSTRUCTION_DETECTED(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_OBSTRUCTION_DETECTED, \\\n    .description = \"Obstruction Detected\", \\\n    .format = homekit_format_bool, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_BOOL_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_ON HOMEKIT_APPLE_UUID2(\"25\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_ON(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_ON, \\\n    .description = \"On\", \\\n    .format = homekit_format_bool, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_BOOL_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_OUTLET_IN_USE HOMEKIT_APPLE_UUID2(\"26\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_OUTLET_IN_USE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_OUTLET_IN_USE, \\\n    .description = \"Outlet In Use\", \\\n    .format = homekit_format_bool, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_BOOL_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_ROTATION_DIRECTION HOMEKIT_APPLE_UUID2(\"28\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_ROTATION_DIRECTION(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_ROTATION_DIRECTION, \\\n    .description = \"Rotation Direction\", \\\n    .format = homekit_format_int, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_ROTATION_SPEED HOMEKIT_APPLE_UUID2(\"29\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_ROTATION_SPEED(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_ROTATION_SPEED, \\\n    .description = \"Rotation Speed\", \\\n    .format = homekit_format_float, \\\n    .unit = homekit_unit_percentage, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {1}, \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SATURATION HOMEKIT_APPLE_UUID2(\"2F\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SATURATION(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SATURATION, \\\n    .description = \"Saturation\", \\\n    .format = homekit_format_float, \\\n    .unit = homekit_unit_percentage, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SERIAL_NUMBER HOMEKIT_APPLE_UUID2(\"30\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SERIAL_NUMBER(serial, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SERIAL_NUMBER, \\\n    .description = \"Serial Number\", \\\n    .format = homekit_format_string, \\\n    .permissions = homekit_permissions_paired_read, \\\n    .value = HOMEKIT_STRING_(serial), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_DOOR_STATE HOMEKIT_APPLE_UUID2(\"32\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_DOOR_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_DOOR_STATE, \\\n    .description = \"Target Door State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_TARGET_HEATING_COOLING_STATE_OFF 0\n#define HOMEKIT_TARGET_HEATING_COOLING_STATE_HEAT 1\n#define HOMEKIT_TARGET_HEATING_COOLING_STATE_COOL 2\n#define HOMEKIT_TARGET_HEATING_COOLING_STATE_AUTO 3\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_HEATING_COOLING_STATE HOMEKIT_APPLE_UUID2(\"33\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_HEATING_COOLING_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_HEATING_COOLING_STATE, \\\n    .description = \"Target Heating Cooling State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {3}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 4, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_RELATIVE_HUMIDITY HOMEKIT_APPLE_UUID2(\"34\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_RELATIVE_HUMIDITY(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_RELATIVE_HUMIDITY, \\\n    .description = \"Target Relative Humidity\", \\\n    .format = homekit_format_float, \\\n    .unit = homekit_unit_percentage, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_TEMPERATURE HOMEKIT_APPLE_UUID2(\"35\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_TEMPERATURE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_TEMPERATURE, \\\n    .description = \"Target Temperature\", \\\n    .format = homekit_format_float, \\\n    .unit = homekit_unit_celsius, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {10}, \\\n    .max_value = (float[]) {38}, \\\n    .min_step = (float[]) {0.1}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_TEMPERATURE_DISPLAY_UNITS HOMEKIT_APPLE_UUID2(\"36\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TEMPERATURE_DISPLAY_UNITS(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TEMPERATURE_DISPLAY_UNITS, \\\n    .description = \"Temperature Display Units\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_VERSION HOMEKIT_APPLE_UUID2(\"37\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_VERSION(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_VERSION, \\\n    .description = \"Version\", \\\n    .format = homekit_format_string, \\\n    .permissions = homekit_permissions_paired_read, \\\n    .value = HOMEKIT_STRING_(_value), \\\n    ##__VA_ARGS__\n\n\n#define HOMEKIT_CHARACTERISTIC_AIR_PARTICULATE_DENSITY HOMEKIT_APPLE_UUID2(\"64\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_AIR_PARTICULATE_DENSITY(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_AIR_PARTICULATE_DENSITY, \\\n    .description = \"Air Particulate Density\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1000}, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_AIR_PARTICULATE_SIZE HOMEKIT_APPLE_UUID2(\"65\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_AIR_PARTICULATE_SIZE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_AIR_PARTICULATE_SIZE, \\\n    .description = \"Air Particulate Size\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SECURITY_SYSTEM_CURRENT_STATE HOMEKIT_APPLE_UUID2(\"66\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SECURITY_SYSTEM_CURRENT_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SECURITY_SYSTEM_CURRENT_STATE, \\\n    .description = \"Security System Current State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {4}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 5, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3, 4 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SECURITY_SYSTEM_TARGET_STATE HOMEKIT_APPLE_UUID2(\"67\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SECURITY_SYSTEM_TARGET_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SECURITY_SYSTEM_TARGET_STATE, \\\n    .description = \"Security System Target State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {3}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 4, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_BATTERY_LEVEL HOMEKIT_APPLE_UUID2(\"68\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_BATTERY_LEVEL(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_BATTERY_LEVEL, \\\n    .description = \"Battery Level\", \\\n    .format = homekit_format_uint8, \\\n    .unit = homekit_unit_percentage, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CONTACT_SENSOR_STATE HOMEKIT_APPLE_UUID2(\"6A\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CONTACT_SENSOR_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CONTACT_SENSOR_STATE, \\\n    .description = \"Contact Sensor State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_AMBIENT_LIGHT_LEVEL HOMEKIT_APPLE_UUID2(\"6B\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_AMBIENT_LIGHT_LEVEL(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_AMBIENT_LIGHT_LEVEL, \\\n    .description = \"Current Ambient Light Level\", \\\n    .format = homekit_format_float, \\\n    .unit = homekit_unit_lux, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0.0001}, \\\n    .max_value = (float[]) {100000}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_HORIZONTAL_TILT_ANGLE HOMEKIT_APPLE_UUID2(\"6C\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_HORIZONTAL_TILT_ANGLE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_HORIZONTAL_TILT_ANGLE, \\\n    .description = \"Current Horizontal Tilt Angle\", \\\n    .format = homekit_format_int, \\\n    .unit = homekit_unit_arcdegrees, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {-90}, \\\n    .max_value = (float[]) {90}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_INT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_POSITION HOMEKIT_APPLE_UUID2(\"6D\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_POSITION(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_POSITION, \\\n    .description = \"Current Position\", \\\n    .format = homekit_format_uint8, \\\n    .unit = homekit_unit_percentage, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_VERTICAL_TILT_ANGLE HOMEKIT_APPLE_UUID2(\"6E\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_VERTICAL_TILT_ANGLE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_VERTICAL_TILT_ANGLE, \\\n    .description = \"Current Vertical Tilt Angle\", \\\n    .format = homekit_format_int, \\\n    .unit = homekit_unit_arcdegrees, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {-90}, \\\n    .max_value = (float[]) {90}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_INT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_HOLD_POSITION HOMEKIT_APPLE_UUID2(\"6F\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_HOLD_POSITION(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_HOLD_POSITION, \\\n    .description = \"Hold Position\", \\\n    .format = homekit_format_bool, \\\n    .permissions = homekit_permissions_paired_write, \\\n    .value = HOMEKIT_BOOL_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_LEAK_DETECTED HOMEKIT_APPLE_UUID2(\"70\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_LEAK_DETECTED(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_LEAK_DETECTED, \\\n    .description = \"Leak Detected\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_OCCUPANCY_DETECTED HOMEKIT_APPLE_UUID2(\"71\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_OCCUPANCY_DETECTED(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_OCCUPANCY_DETECTED, \\\n    .description = \"Occupancy Detected\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_POSITION_STATE HOMEKIT_APPLE_UUID2(\"72\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_POSITION_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_POSITION_STATE, \\\n    .description = \"Position State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {2}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 3, \\\n        .values = (uint8_t[]) { 0, 1, 2 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_PROGRAMMABLE_SWITCH_EVENT HOMEKIT_APPLE_UUID2(\"73\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_PROGRAMMABLE_SWITCH_EVENT(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_PROGRAMMABLE_SWITCH_EVENT, \\\n    .description = \"Programmable Switch Event\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {2}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 3, \\\n        .values = (uint8_t[]) { 0, 1, 2 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_STATUS_ACTIVE HOMEKIT_APPLE_UUID2(\"75\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_STATUS_ACTIVE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_STATUS_ACTIVE, \\\n    .description = \"Status Active\", \\\n    .format = homekit_format_bool, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_BOOL_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SMOKE_DETECTED HOMEKIT_APPLE_UUID2(\"76\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SMOKE_DETECTED(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SMOKE_DETECTED, \\\n    .description = \"Smoke Detected\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_STATUS_FAULT HOMEKIT_APPLE_UUID2(\"77\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_STATUS_FAULT(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_STATUS_FAULT, \\\n    .description = \"Status Fault\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_STATUS_JAMMED HOMEKIT_APPLE_UUID2(\"78\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_STATUS_JAMMED(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_STATUS_JAMMED, \\\n    .description = \"Status Jammed\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_STATUS_LOW_BATTERY HOMEKIT_APPLE_UUID2(\"79\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_STATUS_LOW_BATTERY(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_STATUS_LOW_BATTERY, \\\n    .description = \"Status Low Battery\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_STATUS_TAMPERED HOMEKIT_APPLE_UUID2(\"7A\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_STATUS_TAMPERED(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_STATUS_TAMPERED, \\\n    .description = \"Status Tampered\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_HORIZONTAL_TILT_ANGLE HOMEKIT_APPLE_UUID2(\"7B\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_HORIZONTAL_TILT_ANGLE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_HORIZONTAL_TILT_ANGLE, \\\n    .description = \"Target Horizontal Tilt Angle\", \\\n    .format = homekit_format_int, \\\n    .unit = homekit_unit_arcdegrees, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {-90}, \\\n    .max_value = (float[]) {90}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_INT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_POSITION HOMEKIT_APPLE_UUID2(\"7C\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_POSITION(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_POSITION, \\\n    .description = \"Target Position\", \\\n    .format = homekit_format_uint8, \\\n    .unit = homekit_unit_percentage, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_VERTICAL_TILT_ANGLE HOMEKIT_APPLE_UUID2(\"7D\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_VERTICAL_TILT_ANGLE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_VERTICAL_TILT_ANGLE, \\\n    .description = \"Target Vertical Tilt Angle\", \\\n    .format = homekit_format_int, \\\n    .unit = homekit_unit_arcdegrees, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {-90}, \\\n    .max_value = (float[]) {90}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SECURITY_SYSTEM_ALARM_TYPE HOMEKIT_APPLE_UUID2(\"8E\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SECURITY_SYSTEM_ALARM_TYPE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SECURITY_SYSTEM_ALARM_TYPE, \\\n    .description = \"Security System Alarm Type\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CHARGING_STATE HOMEKIT_APPLE_UUID2(\"8F\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CHARGING_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CHARGING_STATE, \\\n    .description = \"Charging State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {2}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 3, \\\n        .values = (uint8_t[]) { 0, 1, 2 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CARBON_MONOXIDE_DETECTED HOMEKIT_APPLE_UUID2(\"69\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CARBON_MONOXIDE_DETECTED(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CARBON_MONOXIDE_DETECTED, \\\n    .description = \"Carbon Monoxide Detected\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CARBON_MONOXIDE_LEVEL HOMEKIT_APPLE_UUID2(\"90\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CARBON_MONOXIDE_LEVEL(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CARBON_MONOXIDE_LEVEL, \\\n    .description = \"Carbon Monoxide Level\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CARBON_MONOXIDE_PEAK_LEVEL HOMEKIT_APPLE_UUID2(\"91\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CARBON_MONOXIDE_PEAK_LEVEL(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CARBON_MONOXIDE_PEAK_LEVEL, \\\n    .description = \"Carbon Monoxide Peak Level\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n\n#define HOMEKIT_CHARACTERISTIC_CARBON_DIOXIDE_DETECTED HOMEKIT_APPLE_UUID2(\"92\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CARBON_DIOXIDE_DETECTED(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CARBON_DIOXIDE_DETECTED, \\\n    .description = \"Carbon Dioxide Detected\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CARBON_DIOXIDE_LEVEL HOMEKIT_APPLE_UUID2(\"93\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CARBON_DIOXIDE_LEVEL(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CARBON_DIOXIDE_LEVEL, \\\n    .description = \"Carbon Dioxide Level\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100000}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CARBON_DIOXIDE_PEAK_LEVEL HOMEKIT_APPLE_UUID2(\"94\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CARBON_DIOXIDE_PEAK_LEVEL(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CARBON_DIOXIDE_PEAK_LEVEL, \\\n    .description = \"Carbon Dioxide Peak Level\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100000}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_AIR_QUALITY HOMEKIT_APPLE_UUID2(\"95\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_AIR_QUALITY(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_AIR_QUALITY, \\\n    .description = \"Air Quality\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {5}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 6, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3, 4, 5 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_STREAMING_STATUS HOMEKIT_APPLE_UUID3(\"120\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_STREAMING_STATUS(...) \\\n    .type = HOMEKIT_CHARACTERISTIC_STREAMING_STATUS, \\\n    .description = \"Streaming Status\", \\\n    .format = homekit_format_tlv, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SUPPORTED_VIDEO_STREAM_CONFIGURATION HOMEKIT_APPLE_UUID3(\"114\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SUPPORTED_VIDEO_STREAM_CONFIGURATION(...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SUPPORTED_VIDEO_STREAM_CONFIGURATION, \\\n    .description = \"Supported Video Stream Configuration\", \\\n    .format = homekit_format_tlv, \\\n    .permissions = homekit_permissions_paired_read, \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SUPPORTED_AUDIO_STREAM_CONFIGURATION HOMEKIT_APPLE_UUID3(\"115\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SUPPORTED_AUDIO_STREAM_CONFIGURATION(...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SUPPORTED_AUDIO_STREAM_CONFIGURATION, \\\n    .description = \"Supported Audio Stream Configuration\", \\\n    .format = homekit_format_tlv, \\\n    .permissions = homekit_permissions_paired_read, \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SUPPORTED_RTP_CONFIGURATION HOMEKIT_APPLE_UUID3(\"116\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SUPPORTED_RTP_CONFIGURATION(...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SUPPORTED_RTP_CONFIGURATION, \\\n    .description = \"Supported RTP Configuration\", \\\n    .format = homekit_format_tlv, \\\n    .permissions = homekit_permissions_paired_read, \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SETUP_ENDPOINTS HOMEKIT_APPLE_UUID3(\"118\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SETUP_ENDPOINTS(...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SETUP_ENDPOINTS, \\\n    .description = \"Setup Endpoints\", \\\n    .format = homekit_format_tlv, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write, \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SELECTED_RTP_STREAM_CONFIGURATION HOMEKIT_APPLE_UUID3(\"117\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SELECTED_RTP_STREAM_CONFIGURATION(...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SELECTED_RTP_STREAM_CONFIGURATION, \\\n    .description = \"Selected RTP Stream Configuration\", \\\n    .format = homekit_format_tlv, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write, \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_VOLUME HOMEKIT_APPLE_UUID3(\"119\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_VOLUME(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_VOLUME, \\\n    .description = \"Volume\", \\\n    .format = homekit_format_uint8, \\\n    .unit = homekit_unit_percentage, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_MUTE HOMEKIT_APPLE_UUID3(\"11A\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_MUTE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_MUTE, \\\n    .description = \"Mute\", \\\n    .format = homekit_format_bool, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_BOOL_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_NIGHT_VISION HOMEKIT_APPLE_UUID3(\"11B\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_NIGHT_VISION(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_NIGHT_VISION, \\\n    .description = \"Night Vision\", \\\n    .format = homekit_format_bool, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_BOOL_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_OPTICAL_ZOOM HOMEKIT_APPLE_UUID3(\"11C\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_OPTICAL_ZOOM(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_OPTICAL_ZOOM, \\\n    .description = \"Optical Zoom\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_DIGITAL_ZOOM HOMEKIT_APPLE_UUID3(\"11D\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_DIGITAL_ZOOM(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_DIGITAL_ZOOM, \\\n    .description = \"Digital Zoom\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_IMAGE_ROTATION HOMEKIT_APPLE_UUID3(\"11E\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_IMAGE_ROTATION(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_IMAGE_ROTATION, \\\n    .description = \"Image Rotation\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .valid_values = { \\\n        .count = 4, \\\n        .values = (uint8_t[]) { 0, 90, 180, 270 }, \\\n    }, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_IMAGE_MIRRORING HOMEKIT_APPLE_UUID3(\"11F\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_IMAGE_MIRRORING(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_IMAGE_MIRRORING, \\\n    .description = \"Image Mirroring\", \\\n    .format = homekit_format_bool, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_BOOL_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_ACCESSORY_FLAGS HOMEKIT_APPLE_UUID2(\"A6\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_ACCESSORY_FLAGS(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_ACCESSORY_FLAGS, \\\n    .description = \"Accessory Flags\", \\\n    .format = homekit_format_uint32, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT32_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_LOCK_PHYSICAL_CONTROLS HOMEKIT_APPLE_UUID2(\"A7\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_LOCK_PHYSICAL_CONTROLS(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_LOCK_PHYSICAL_CONTROLS, \\\n    .description = \"Lock Physical Controls\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_AIR_PURIFIER_STATE HOMEKIT_APPLE_UUID2(\"A9\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_AIR_PURIFIER_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_AIR_PURIFIER_STATE, \\\n    .description = \"Current Air Purifier State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {2}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 3, \\\n        .values = (uint8_t[]) { 0, 1, 2 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_SLAT_STATE HOMEKIT_APPLE_UUID2(\"AA\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_SLAT_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_SLAT_STATE, \\\n    .description = \"Current Slat State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {2}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 3, \\\n        .values = (uint8_t[]) { 0, 1, 2 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SLAT_TYPE HOMEKIT_APPLE_UUID2(\"C0\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SLAT_TYPE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SLAT_TYPE, \\\n    .description = \"Slat Type\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_FILTER_LIFE_LEVEL HOMEKIT_APPLE_UUID2(\"AB\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_FILTER_LIFE_LEVEL(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_FILTER_LIFE_LEVEL, \\\n    .description = \"Filter Life Level\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_FILTER_CHANGE_INDICATION HOMEKIT_APPLE_UUID2(\"AC\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_FILTER_CHANGE_INDICATION(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_FILTER_CHANGE_INDICATION, \\\n    .description = \"Filter Change Indication\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_RESET_FILTER_INDICATION HOMEKIT_APPLE_UUID2(\"AD\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_RESET_FILTER_INDICATION(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_RESET_FILTER_INDICATION, \\\n    .description = \"Reset Filter Indication\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {1}, \\\n    .max_value = (float[]) {1}, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_AIR_PURIFIER_STATE HOMEKIT_APPLE_UUID2(\"A8\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_AIR_PURIFIER_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_AIR_PURIFIER_STATE, \\\n    .description = \"Target Air Purifier State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_FAN_STATE HOMEKIT_APPLE_UUID2(\"BF\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_FAN_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_FAN_STATE, \\\n    .description = \"Target Fan State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_FAN_STATE HOMEKIT_APPLE_UUID2(\"AF\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_FAN_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_FAN_STATE, \\\n    .description = \"Current Fan State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {2}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 3, \\\n        .values = (uint8_t[]) { 0, 1, 2 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_ACTIVE HOMEKIT_APPLE_UUID2(\"B0\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_ACTIVE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_ACTIVE, \\\n    .description = \"Active\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SWING_MODE HOMEKIT_APPLE_UUID2(\"B6\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SWING_MODE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SWING_MODE, \\\n    .description = \"Swing Mode\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_TILT_ANGLE HOMEKIT_APPLE_UUID2(\"C1\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_TILT_ANGLE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_TILT_ANGLE, \\\n    .description = \"Current Tilt Angle\", \\\n    .format = homekit_format_int, \\\n    .unit = homekit_unit_arcdegrees, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {-90}, \\\n    .max_value = (float[]) {90}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_INT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_TILT_ANGLE HOMEKIT_APPLE_UUID2(\"C2\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_TILT_ANGLE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_TILT_ANGLE, \\\n    .description = \"Target Tilt Angle\", \\\n    .format = homekit_format_int, \\\n    .unit = homekit_unit_arcdegrees, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {-90}, \\\n    .max_value = (float[]) {90}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_INT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_OZONE_DENSITY HOMEKIT_APPLE_UUID2(\"C3\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_OZONE_DENSITY(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_OZONE_DENSITY, \\\n    .description = \"Ozone Density\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1000}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_NITROGEN_DIOXIDE_DENSITY HOMEKIT_APPLE_UUID2(\"C4\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_NITROGEN_DIOXIDE_DENSITY(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_NITROGEN_DIOXIDE_DENSITY, \\\n    .description = \"Nitrogen Dioxide Density\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1000}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SULPHUR_DIOXIDE_DENSITY HOMEKIT_APPLE_UUID2(\"C5\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SULPHUR_DIOXIDE_DENSITY(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SULPHUR_DIOXIDE_DENSITY, \\\n    .description = \"Sulphur Dioxide Density\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1000}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_PM25_DENSITY HOMEKIT_APPLE_UUID2(\"C6\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_PM25_DENSITY(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_PM25_DENSITY, \\\n    .description = \"PM25 Density\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1000}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_PM10_DENSITY HOMEKIT_APPLE_UUID2(\"C7\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_PM10_DENSITY(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_PM10_DENSITY, \\\n    .description = \"PM10 Density\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1000}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_VOC_DENSITY HOMEKIT_APPLE_UUID2(\"C8\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_VOC_DENSITY(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_VOC_DENSITY, \\\n    .description = \"VOC Density\", \\\n    .format = homekit_format_float, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1000}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SERVICE_LABEL_INDEX HOMEKIT_APPLE_UUID2(\"CB\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SERVICE_LABEL_INDEX(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SERVICE_LABEL_INDEX, \\\n    .description = \"Service Label Index\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read, \\\n    .min_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SERVICE_LABEL_NAMESPACE HOMEKIT_APPLE_UUID2(\"CD\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SERVICE_LABEL_NAMESPACE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SERVICE_LABEL_NAMESPACE, \\\n    .description = \"Service Label Namespace\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_COLOR_TEMPERATURE HOMEKIT_APPLE_UUID2(\"CE\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_COLOR_TEMPERATURE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_COLOR_TEMPERATURE, \\\n    .description = \"Color Temperature\", \\\n    .format = homekit_format_uint32, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {50}, \\\n    .max_value = (float[]) {400}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_UINT32_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_IN_USE HOMEKIT_APPLE_UUID2(\"D2\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_IN_USE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_IN_USE, \\\n    .description = \"In Use\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_IS_CONFIGURED HOMEKIT_APPLE_UUID2(\"D6\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_IS_CONFIGURED(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_IS_CONFIGURED, \\\n    .description = \"Is Configured\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_PROGRAM_MODE HOMEKIT_APPLE_UUID2(\"D1\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_PROGRAM_MODE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_PROGRAM_MODE, \\\n    .description = \"Program Mode\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {2}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 3, \\\n        .values = (uint8_t[]) { 0, 1, 2 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_REMAINING_DURATION HOMEKIT_APPLE_UUID2(\"D4\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_REMAINING_DURATION(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_REMAINING_DURATION, \\\n    .description = \"Remaining Duration\", \\\n    .format = homekit_format_uint32, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {3600}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_UINT32_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_SET_DURATION HOMEKIT_APPLE_UUID2(\"D3\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SET_DURATION(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SET_DURATION, \\\n    .description = \"Remaining Duration\", \\\n    .format = homekit_format_uint32, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {3600}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_UINT32_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_VALVE_TYPE HOMEKIT_APPLE_UUID2(\"D5\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_VALVE_TYPE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_VALVE_TYPE, \\\n    .description = \"Valve Type\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {3}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 4, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_HEATER_COOLER_STATE HOMEKIT_APPLE_UUID2(\"B1\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_HEATER_COOLER_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_HEATER_COOLER_STATE, \\\n    .description = \"Current Heater Cooler State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {3}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 4, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_HEATER_COOLER_STATE HOMEKIT_APPLE_UUID2(\"B2\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_HEATER_COOLER_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_HEATER_COOLER_STATE, \\\n    .description = \"Target Heater Cooler State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {2}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 3, \\\n        .values = (uint8_t[]) { 0, 1, 2 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_HUMIDIFIER_DEHUMIDIFIER_STATE HOMEKIT_APPLE_UUID2(\"B3\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_HUMIDIFIER_DEHUMIDIFIER_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_HUMIDIFIER_DEHUMIDIFIER_STATE, \\\n    .description = \"Current Humidifier Dehumidifier State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {3}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 4, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_HUMIDIFIER_DEHUMIDIFIER_STATE HOMEKIT_APPLE_UUID2(\"B4\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_HUMIDIFIER_DEHUMIDIFIER_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_HUMIDIFIER_DEHUMIDIFIER_STATE, \\\n    .description = \"Target Humidifier Dehumidifier State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {2}, \\\n    .min_step = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 3, \\\n        .values = (uint8_t[]) { 0, 1, 2 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_WATER_LEVEL HOMEKIT_APPLE_UUID2(\"B5\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_WATER_LEVEL(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_WATER_LEVEL, \\\n    .description = \"Water Level\", \\\n    .format = homekit_format_float, \\\n    .unit = homekit_unit_percentage, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_RELATIVE_HUMIDITY_DEHUMIDIFIER_THRESHOLD HOMEKIT_APPLE_UUID2(\"C9\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_RELATIVE_HUMIDITY_DEHUMIDIFIER_THRESHOLD(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_RELATIVE_HUMIDITY_DEHUMIDIFIER_THRESHOLD, \\\n    .description = \"Relative Humidity Dehumidifier Threshold\", \\\n    .format = homekit_format_float, \\\n    .unit = homekit_unit_percentage, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_RELATIVE_HUMIDITY_HUMIDIFIER_THRESHOLD HOMEKIT_APPLE_UUID2(\"CA\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_RELATIVE_HUMIDITY_HUMIDIFIER_THRESHOLD(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_RELATIVE_HUMIDITY_HUMIDIFIER_THRESHOLD, \\\n    .description = \"Relative Humidity Humidifier Threshold\", \\\n    .format = homekit_format_float, \\\n    .unit = homekit_unit_percentage, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {100}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_FLOAT_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_ACTIVE_IDENTIFIER HOMEKIT_APPLE_UUID2(\"E7\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_ACTIVE_IDENTIFIER(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_ACTIVE_IDENTIFIER, \\\n    .description = \"Active Identifier\", \\\n    .format = homekit_format_uint32, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_UINT32_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CONFIGURED_NAME HOMEKIT_APPLE_UUID2(\"E3\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CONFIGURED_NAME(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CONFIGURED_NAME, \\\n    .description = \"Configured Name\", \\\n    .format = homekit_format_string, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_STRING_(_value, .is_static=true), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_SLEEP_DISCOVERY_MODE_NOT_DISCOVERABLE 0\n#define HOMEKIT_SLEEP_DISCOVERY_MODE_ALWAYS_DISCOVERABLE 1\n\n#define HOMEKIT_CHARACTERISTIC_SLEEP_DISCOVERY_MODE HOMEKIT_APPLE_UUID2(\"E8\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_SLEEP_DISCOVERY_MODE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_SLEEP_DISCOVERY_MODE, \\\n    .description = \"Sleep Discovery Mode\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CLOSED_CAPTIONS_DISABLED 0\n#define HOMEKIT_CLOSED_CAPTIONS_ENABLED 1\n\n#define HOMEKIT_CHARACTERISTIC_CLOSED_CAPTIONS HOMEKIT_APPLE_UUID2(\"DD\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CLOSED_CAPTIONS(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CLOSED_CAPTIONS, \\\n    .description = \"Closed Captions\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_DISPLAY_ORDER HOMEKIT_APPLE_UUID3(\"136\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_DISPLAY_ORDER(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_DISPLAY_ORDER, \\\n    .description = \"Display Order\", \\\n    .format = homekit_format_tlv, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_MEDIA_STATE HOMEKIT_APPLE_UUID2(\"E0\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_MEDIA_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_MEDIA_STATE, \\\n    .description = \"Current Media State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {3}, \\\n    .valid_values = { \\\n        .count = 4, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_TARGET_MEDIA_STATE_PLAY 0\n#define HOMEKIT_TARGET_MEDIA_STATE_PAUSE 1\n#define HOMEKIT_TARGET_MEDIA_STATE_STOP 2\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_MEDIA_STATE HOMEKIT_APPLE_UUID3(\"137\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_MEDIA_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_MEDIA_STATE, \\\n    .description = \"Target Media State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {2}, \\\n    .valid_values = { \\\n        .count = 3, \\\n        .values = (uint8_t[]) { 0, 1, 2 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_PICTURE_MODE_OTHER 0\n#define HOMEKIT_PICTURE_MODE_STANDARD 1\n#define HOMEKIT_PICTURE_MODE_CALIBRATED 2\n#define HOMEKIT_PICTURE_MODE_CALIBRATED_DARK 3\n#define HOMEKIT_PICTURE_MODE_VIVID 4\n#define HOMEKIT_PICTURE_MODE_GAME 5\n#define HOMEKIT_PICTURE_MODE_COMPUTER 6\n#define HOMEKIT_PICTURE_MODE_CUSTOM 7\n\n#define HOMEKIT_CHARACTERISTIC_PICTURE_MODE HOMEKIT_APPLE_UUID2(\"E2\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_PICTURE_MODE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_PICTURE_MODE, \\\n    .description = \"Picture Mode\", \\\n    .format = homekit_format_uint16, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {13}, \\\n    .valid_values = { \\\n        .count = 14, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }, \\\n    }, \\\n    .value = HOMEKIT_UINT16_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_POWER_MODE_SELECTION_SHOW 0\n#define HOMEKIT_POWER_MODE_SELECTION_HIDE 1\n\n#define HOMEKIT_CHARACTERISTIC_POWER_MODE_SELECTION HOMEKIT_APPLE_UUID2(\"DF\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_POWER_MODE_SELECTION(...) \\\n    .type = HOMEKIT_CHARACTERISTIC_POWER_MODE_SELECTION, \\\n    .description = \"Power Mode Selection\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_write, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_REMOTE_KEY_REWIND 0\n#define HOMEKIT_REMOTE_KEY_FAST_FORWARD 1\n#define HOMEKIT_REMOTE_KEY_NEXT_TRACK 2\n#define HOMEKIT_REMOTE_KEY_PREVIOUS_TRACK 3\n#define HOMEKIT_REMOTE_KEY_ARROW_UP 4\n#define HOMEKIT_REMOTE_KEY_ARROW_DOWN 5\n#define HOMEKIT_REMOTE_KEY_ARROW_LEFT 6\n#define HOMEKIT_REMOTE_KEY_ARROW_RIGHT 7\n#define HOMEKIT_REMOTE_KEY_SELECT 8\n#define HOMEKIT_REMOTE_KEY_BACK 9\n#define HOMEKIT_REMOTE_KEY_EXIT 10\n#define HOMEKIT_REMOTE_KEY_PLAY_PAUSE 11\n#define HOMEKIT_REMOTE_KEY_INFORMATION 15\n\n#define HOMEKIT_CHARACTERISTIC_REMOTE_KEY HOMEKIT_APPLE_UUID2(\"E1\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_REMOTE_KEY(...) \\\n    .type = HOMEKIT_CHARACTERISTIC_REMOTE_KEY, \\\n    .description = \"Remote Key\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_write, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {16}, \\\n    .valid_values = { \\\n        .count = 17, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, \\\n    }, \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_INPUT_SOURCE_TYPE_OTHER 0\n#define HOMEKIT_INPUT_SOURCE_TYPE_HOME_SCREEN 1\n#define HOMEKIT_INPUT_SOURCE_TYPE_TUNER 2\n#define HOMEKIT_INPUT_SOURCE_TYPE_HDMI 3\n#define HOMEKIT_INPUT_SOURCE_TYPE_COMPOSITE_VIDEO 4\n#define HOMEKIT_INPUT_SOURCE_TYPE_S_VIDEO 5\n#define HOMEKIT_INPUT_SOURCE_TYPE_COMPONENT_VIDEO 6\n#define HOMEKIT_INPUT_SOURCE_TYPE_DVI 7\n#define HOMEKIT_INPUT_SOURCE_TYPE_AIRPLAY 8\n#define HOMEKIT_INPUT_SOURCE_TYPE_USB 9\n#define HOMEKIT_INPUT_SOURCE_TYPE_APPLICATION 10\n\n#define HOMEKIT_CHARACTERISTIC_INPUT_SOURCE_TYPE HOMEKIT_APPLE_UUID2(\"DB\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_INPUT_SOURCE_TYPE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_INPUT_SOURCE_TYPE, \\\n    .description = \"Input Source Type\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {10}, \\\n    .valid_values = { \\\n        .count = 11, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_INPUT_DEVICE_TYPE_OTHER 0\n#define HOMEKIT_INPUT_DEVICE_TYPE_TV 1\n#define HOMEKIT_INPUT_DEVICE_TYPE_RECORDING 2\n#define HOMEKIT_INPUT_DEVICE_TYPE_TUNER 3\n#define HOMEKIT_INPUT_DEVICE_TYPE_PLAYBACK 4\n#define HOMEKIT_INPUT_DEVICE_TYPE_AUDIO_SYSTEM 5\n\n#define HOMEKIT_CHARACTERISTIC_INPUT_DEVICE_TYPE HOMEKIT_APPLE_UUID2(\"DC\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_INPUT_DEVICE_TYPE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_INPUT_DEVICE_TYPE, \\\n    .description = \"Input Device Type\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {5}, \\\n    .valid_values = { \\\n        .count = 6, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3, 4, 5 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CHARACTERISTIC_IDENTIFIER HOMEKIT_APPLE_UUID2(\"E6\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_IDENTIFIER(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_IDENTIFIER, \\\n    .description = \"Identifier\", \\\n    .format = homekit_format_uint32, \\\n    .permissions = homekit_permissions_paired_read, \\\n    .min_value = (float[]) {0}, \\\n    .min_step = (float[]) {1}, \\\n    .value = HOMEKIT_UINT32_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_CURRENT_VISIBILITY_STATE_SHOWN 0\n#define HOMEKIT_CURRENT_VISIBILITY_STATE_HIDDEN 1\n\n#define HOMEKIT_CHARACTERISTIC_CURRENT_VISIBILITY_STATE HOMEKIT_APPLE_UUID3(\"135\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CURRENT_VISIBILITY_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_CURRENT_VISIBILITY_STATE, \\\n    .description = \"Current Visibility State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {3}, \\\n    .valid_values = { \\\n        .count = 4, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_TARGET_VISIBILITY_STATE_SHOWN 0\n#define HOMEKIT_TARGET_VISIBILITY_STATE_HIDDEN 1\n\n#define HOMEKIT_CHARACTERISTIC_TARGET_VISIBILITY_STATE HOMEKIT_APPLE_UUID3(\"134\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_TARGET_VISIBILITY_STATE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_TARGET_VISIBILITY_STATE, \\\n    .description = \"Target Visibility State\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_paired_write \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_VOLUME_CONTROL_TYPE_NONE 0\n#define HOMEKIT_VOLUME_CONTROL_TYPE_RELATIVE 1\n#define HOMEKIT_VOLUME_CONTROL_TYPE_RELATIVE_WITH_CURRENT 2\n#define HOMEKIT_VOLUME_CONTROL_TYPE_ABSOLUTE 3\n\n#define HOMEKIT_CHARACTERISTIC_VOLUME_CONTROL_TYPE HOMEKIT_APPLE_UUID3(\"E9\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_VOLUME_CONTROL_TYPE(_value, ...) \\\n    .type = HOMEKIT_CHARACTERISTIC_VOLUME_CONTROL_TYPE, \\\n    .description = \"Volume Control Type\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_read \\\n                 | homekit_permissions_notify, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {3}, \\\n    .valid_values = { \\\n        .count = 4, \\\n        .values = (uint8_t[]) { 0, 1, 2, 3 }, \\\n    }, \\\n    .value = HOMEKIT_UINT8_(_value), \\\n    ##__VA_ARGS__\n\n#define HOMEKIT_VOLUME_SELECTOR_INCREMENT 0\n#define HOMEKIT_VOLUME_SELECTOR_DECREMENT 1\n\n#define HOMEKIT_CHARACTERISTIC_VOLUME_SELECTOR HOMEKIT_APPLE_UUID3(\"EA\")\n#define HOMEKIT_DECLARE_CHARACTERISTIC_VOLUME_SELECTOR(...) \\\n    .type = HOMEKIT_CHARACTERISTIC_VOLUME_SELECTOR, \\\n    .description = \"Volume Selector\", \\\n    .format = homekit_format_uint8, \\\n    .permissions = homekit_permissions_paired_write, \\\n    .min_value = (float[]) {0}, \\\n    .max_value = (float[]) {1}, \\\n    .valid_values = { \\\n        .count = 2, \\\n        .values = (uint8_t[]) { 0, 1 }, \\\n    }, \\\n    ##__VA_ARGS__\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // __HOMEKIT_CHARACTERISTICS__\n"
  },
  {
    "path": "src/homekit/homekit.h",
    "content": "#ifndef __HOMEKIT_H__\n#define __HOMEKIT_H__\n\n#include <homekit/types.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef void *homekit_client_id_t;\n\n\ntypedef enum {\n    HOMEKIT_EVENT_SERVER_INITIALIZED,\n    // Just accepted client connection\n    HOMEKIT_EVENT_CLIENT_CONNECTED,\n    // Pairing verification completed and secure session is established\n    HOMEKIT_EVENT_CLIENT_VERIFIED,\n    HOMEKIT_EVENT_CLIENT_DISCONNECTED,\n    HOMEKIT_EVENT_PAIRING_ADDED,\n    HOMEKIT_EVENT_PAIRING_REMOVED,\n} homekit_event_t;\n\n\ntypedef struct {\n    // Pointer to an array of homekit_accessory_t pointers.\n    // Array should be terminated by a NULL pointer.\n    homekit_accessory_t **accessories;\n\n    homekit_accessory_category_t category;\n\n    // Used for Bonjour\n\t// Current configuration number. Required.\n\t// Must update when an accessory, service, or characteristic is added or removed on the accessory server.\n\t// Accessories must increment the config number after a firmware update.\n\t// This must have a range of 1-65535 and wrap to 1 when it overflows.\n\t// This value must persist across reboots, power cycles, etc.\n    uint16_t config_number;\n\n    // Password in format \"111-23-456\".\n    // If password is not specified, a random password\n    // will be used. In that case, a password_callback\n    // field must contain pointer to a function that should\n    // somehow communicate password to the user (e.g. display\n    // it on a screen if accessory has one).\n    char *password;\n    void (*password_callback)(const char *password);\n\n    // Setup ID in format \"XXXX\" (where X is digit or latin capital letter)\n    // Used for pairing using QR code\n    char *setupId;\n\n    // Callback for \"POST /resource\" to get snapshot image from camera\n    void (*on_resource)(const char *body, size_t body_size);\n\n    void (*on_event)(homekit_event_t event);\n} homekit_server_config_t;\n\n// Get pairing URI\nint homekit_get_setup_uri(const homekit_server_config_t *config,\n                          char *buffer, size_t buffer_size);\n\n// Initialize HomeKit accessory server\nvoid homekit_server_init(homekit_server_config_t *config);\n\n// Reset HomeKit accessory server, removing all pairings\nvoid homekit_server_reset();\n\nint  homekit_get_accessory_id(char *buffer, size_t size);\nbool homekit_is_paired();\n\n// Client related stuff\nhomekit_client_id_t homekit_get_client_id();\n\nbool homekit_client_is_admin();\nint  homekit_client_send(unsigned char *data, size_t size);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // __HOMEKIT_H__\n"
  },
  {
    "path": "src/homekit/tlv.h",
    "content": "#ifndef __TLV_H__\n#define __TLV_H__\n\n#define __need_size_t\n#include <stdlib.h>\n#include  <stdio.h>\n#include <stddef.h>\n#include <string.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef unsigned char byte;\n\ntypedef struct _tlv {\n    struct _tlv *next;\n    byte type;\n    byte *value;\n    size_t size;\n} tlv_t;\n\n\ntypedef struct {\n    tlv_t *head;\n} tlv_values_t;\n\n\ntlv_values_t *tlv_new();\n\nvoid tlv_free(tlv_values_t *values);\n\nint tlv_add_value(tlv_values_t *values, byte type, const byte *value, size_t size);\nint tlv_add_string_value(tlv_values_t *values, byte type, const char *value);\nint tlv_add_integer_value(tlv_values_t *values, byte type, size_t size, int value);\nint tlv_add_tlv_value(tlv_values_t *values, byte type, tlv_values_t *value);\n\ntlv_t *tlv_get_value(const tlv_values_t *values, byte type);\nint tlv_get_integer_value(const tlv_values_t *values, byte type, int def);\ntlv_values_t *tlv_get_tlv_value(const tlv_values_t *values, byte type);\n\nint tlv_format(const tlv_values_t *values, byte *buffer, size_t *size);\n\nint tlv_parse(const byte *buffer, size_t length, tlv_values_t *values);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // __TLV_H__\n"
  },
  {
    "path": "src/homekit/types.h",
    "content": "#ifndef __HOMEKIT_TYPES_H__\n#define __HOMEKIT_TYPES_H__\n\n#include <stdbool.h>\n#include <stdint.h>\n\n#include <homekit/tlv.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef enum {\n    homekit_format_bool,\n    homekit_format_uint8,\n    homekit_format_uint16,\n    homekit_format_uint32,\n    homekit_format_uint64,\n    homekit_format_int,\n    homekit_format_float,\n    homekit_format_string,\n    homekit_format_tlv,\n    homekit_format_data\n} homekit_format_t;\n\ntypedef enum {\n    homekit_unit_none,\n    homekit_unit_celsius,\n    homekit_unit_percentage,\n    homekit_unit_arcdegrees,\n    homekit_unit_lux,\n    homekit_unit_seconds\n} homekit_unit_t;\n\ntypedef enum {\n    homekit_permissions_paired_read = 1,\n    homekit_permissions_paired_write = 2,\n    homekit_permissions_notify = 4,\n    homekit_permissions_additional_authorization = 8,\n    homekit_permissions_timed_write = 16,\n    homekit_permissions_hidden = 32\n} homekit_permissions_t;\n\ntypedef enum {\n    homekit_accessory_category_other = 1,\n    homekit_accessory_category_bridge = 2,\n    homekit_accessory_category_fan = 3,\n    homekit_accessory_category_garage = 4,\n    homekit_accessory_category_lightbulb = 5,\n    homekit_accessory_category_door_lock = 6,\n    homekit_accessory_category_outlet = 7,\n    homekit_accessory_category_switch = 8,\n    homekit_accessory_category_thermostat = 9,\n    homekit_accessory_category_sensor = 10,\n    homekit_accessory_category_security_system = 11,\n    homekit_accessory_category_door = 12,\n    homekit_accessory_category_window = 13,\n    homekit_accessory_category_window_covering = 14,\n    homekit_accessory_category_programmable_switch = 15,\n    homekit_accessory_category_range_extender = 16,\n    homekit_accessory_category_ip_camera = 17,\n    homekit_accessory_category_video_door_bell = 18,\n    homekit_accessory_category_air_purifier = 19,\n    homekit_accessory_category_heater = 20,\n    homekit_accessory_category_air_conditioner = 21,\n    homekit_accessory_category_humidifier = 22,\n    homekit_accessory_category_dehumidifier = 23,\n    homekit_accessory_category_apple_tv = 24,\n    homekit_accessory_category_speaker = 26,\n    homekit_accessory_category_airport = 27,\n    homekit_accessory_category_sprinkler = 28,\n    homekit_accessory_category_faucet = 29,\n    homekit_accessory_category_shower_head = 30,\n    homekit_accessory_category_television = 31,\n    homekit_accessory_category_target_controller = 32,\n} homekit_accessory_category_t;\n\nstruct _homekit_accessory;\nstruct _homekit_service;\nstruct _homekit_characteristic;\ntypedef struct _homekit_accessory homekit_accessory_t;\ntypedef struct _homekit_service homekit_service_t;\ntypedef struct _homekit_characteristic homekit_characteristic_t;\n\n\ntypedef struct {\n    bool is_null : 1;\n    bool is_static : 1;\n    homekit_format_t format : 6;\n    union {\n        bool bool_value;\n        int int_value;\n        uint8_t uint8_value;\n        uint16_t uint16_value;\n        uint32_t uint32_value;\n        uint64_t uint64_value;\n        float float_value;\n        char *string_value;\n        tlv_values_t *tlv_values;\n        struct {\n            uint8_t *data_value;\n            size_t data_size;\n        };\n    };\n} homekit_value_t;\n\nbool homekit_value_equal(homekit_value_t *a, homekit_value_t *b);\nvoid homekit_value_copy(homekit_value_t *dst, homekit_value_t *src);\nhomekit_value_t *homekit_value_clone(homekit_value_t *value);\nvoid homekit_value_destruct(homekit_value_t *value);\nvoid homekit_value_free(homekit_value_t *value);\n\n\n#define HOMEKIT_NULL_(...) \\\n    {.format=homekit_format_bool, .is_null=true, ##__VA_ARGS__}\n#define HOMEKIT_NULL(...) (homekit_value_t) HOMEKIT_NULL_( __VA_ARGS__ )\n\n#define HOMEKIT_BOOL_(value, ...) \\\n    {.format=homekit_format_bool, .bool_value=(value), ##__VA_ARGS__}\n#define HOMEKIT_BOOL(value, ...) (homekit_value_t) HOMEKIT_BOOL_(value, __VA_ARGS__)\n\n#define HOMEKIT_INT_(value, ...) \\\n    {.format=homekit_format_int, .int_value=(value), ##__VA_ARGS__}\n#define HOMEKIT_INT(value, ...) (homekit_value_t) HOMEKIT_INT_(value, ##__VA_ARGS__)\n\n#define HOMEKIT_UINT8_(value, ...) \\\n    {.format=homekit_format_uint8, .uint8_value=(value), ##__VA_ARGS__}\n#define HOMEKIT_UINT8(value, ...) (homekit_value_t) HOMEKIT_UINT8_(value, ##__VA_ARGS__)\n\n#define HOMEKIT_UINT16_(value, ...) \\\n    {.format=homekit_format_uint16, .uint16_value=(value), ##__VA_ARGS__}\n#define HOMEKIT_UINT16(value, ...) (homekit_value_t) HOMEKIT_UINT16_(value, ##__VA_ARGS__)\n\n#define HOMEKIT_UINT32_(value, ...) \\\n    {.format=homekit_format_uint32, .uint32_value=(value), ##__VA_ARGS__}\n#define HOMEKIT_UINT32(value, ...) (homekit_value_t) HOMEKIT_UINT32_(value, ##__VA_ARGS__)\n\n#define HOMEKIT_UINT64_(value, ...) \\\n    {.format=homekit_format_uint64, .uint64_value=(value), ##__VA_ARGS__}\n#define HOMEKIT_UINT64(value, ...) (homekit_value_t) HOMEKIT_UINT64_(value, ##__VA_ARGS__)\n\n#define HOMEKIT_FLOAT_(value, ...) \\\n    {.format=homekit_format_float, .float_value=(value), ##__VA_ARGS__}\n#define HOMEKIT_FLOAT(value, ...) (homekit_value_t) HOMEKIT_FLOAT_(value, ##__VA_ARGS__)\n\n#define HOMEKIT_STRING_(value, ...) \\\n    {.format=homekit_format_string, .string_value=(value), ##__VA_ARGS__}\n#define HOMEKIT_STRING(value, ...) (homekit_value_t) HOMEKIT_STRING_(value, ##__VA_ARGS__)\n\n#define HOMEKIT_TLV_(value, ...) \\\n    {.format=homekit_format_tlv, .tlv_values=(value), ##__VA_ARGS__}\n#define HOMEKIT_TLV(value, ...) (homekit_value_t) HOMEKIT_TLV_(value, ##__VA_ARGS__)\n\n#define HOMEKIT_DATA_(value, size, ...) \\\n    {.format=homekit_format_data, .data_value=value, .data_size=size, ##__VA_ARGS__}\n#define HOMEKIT_DATA(value, size, ...) (homekit_value_t) HOMEKIT_DATA_(value, size, ##__VA_ARGS__)\n\n\n\ntypedef struct {\n    int count;\n    uint8_t *values;\n} homekit_valid_values_t;\n\n\ntypedef struct {\n    uint8_t start;\n    uint8_t end;\n} homekit_valid_values_range_t;\n\n\ntypedef struct {\n    int count;\n    homekit_valid_values_range_t *ranges;\n} homekit_valid_values_ranges_t;\n\n\ntypedef void (*homekit_characteristic_change_callback_fn)(homekit_characteristic_t *ch, homekit_value_t value, void *context);\n\ntypedef struct _homekit_characteristic_change_callback {\n    homekit_characteristic_change_callback_fn function;\n    void *context;\n    struct _homekit_characteristic_change_callback *next;\n} homekit_characteristic_change_callback_t;\n\n\n#define HOMEKIT_CHARACTERISTIC_CALLBACK(f, ...) &(homekit_characteristic_change_callback_t) { .function = f, ##__VA_ARGS__ }\n\n\nstruct _homekit_characteristic {\n    homekit_service_t *service;\n\n    unsigned int id;\n    const char *type;\n    const char *description;\n    homekit_format_t format;\n    homekit_unit_t unit;\n    homekit_permissions_t permissions;\n    homekit_value_t value;\n\n    float *min_value;\n    float *max_value;\n    float *min_step;\n    int *max_len;\n    int *max_data_len;\n\n    homekit_valid_values_t valid_values;\n    homekit_valid_values_ranges_t valid_values_ranges;\n\n    homekit_value_t (*getter)();\n    void (*setter)(const homekit_value_t);\n    homekit_characteristic_change_callback_t *callback;\n\n    homekit_value_t (*getter_ex)(const homekit_characteristic_t *ch);\n    void (*setter_ex)(homekit_characteristic_t *ch, const homekit_value_t value);\n\n    void *context;\n};\n\nstruct _homekit_service {\n    homekit_accessory_t *accessory;\n\n    unsigned int id;\n    const char *type;\n    bool hidden;\n    bool primary;\n\n    homekit_service_t **linked;\n    homekit_characteristic_t **characteristics;\n};\n\nstruct _homekit_accessory {\n    unsigned int id;\n\n    homekit_accessory_category_t category;\n    uint16_t config_number;\n\n    homekit_service_t **services;\n};\n\n// Macro to define accessory\n#define HOMEKIT_ACCESSORY(...) \\\n    &(homekit_accessory_t) { \\\n        .config_number=1, \\\n        .category=homekit_accessory_category_other, \\\n        ##__VA_ARGS__ \\\n    }\n\n// Macro to define service inside accessory definition.\n// Requires HOMEKIT_SERVICE_<name> define to expand to service type UUID string\n#define HOMEKIT_SERVICE(_type, ...) \\\n    &(homekit_service_t) { .type=HOMEKIT_SERVICE_ ## _type, ##__VA_ARGS__ }\n\n// Macro to define standalone service (outside of accessory definition)\n// Requires HOMEKIT_SERVICE_<name> define to expand to service type UUID string\n#define HOMEKIT_SERVICE_(_type, ...) \\\n    { .type=HOMEKIT_SERVICE_ ## _type, ##__VA_ARGS__ }\n\n// Macro to define characteristic inside service definition\n#define HOMEKIT_CHARACTERISTIC(name, ...) \\\n    &(homekit_characteristic_t) { \\\n        HOMEKIT_DECLARE_CHARACTERISTIC_ ## name( __VA_ARGS__ ) \\\n    }\n\n// Macro to define standalone characteristic (outside of service definition)\n// Requires HOMEKIT_DECLARE_CHARACTERISTIC_<name>() macro\n#define HOMEKIT_CHARACTERISTIC_(name, ...) \\\n    { \\\n        HOMEKIT_DECLARE_CHARACTERISTIC_ ## name( __VA_ARGS__ ) \\\n    }\n\n// Declaration macro to create a custom characteristic inplace without\n// having to define HOMKIT_DECLARE_CHARACTERISTIC_<name>() macro.\n//\n// Useage:\n//     homekit_characteristic_t custom_ch = HOMEKIT_CHARACTERISTIC_(\n//         CUSTOM,\n//         .type = \"00000023-0000-1000-8000-0026BB765291\",\n//         .description = \"My custom characteristic\",\n//         .format = homekit_format_string,\n//         .permissions = homekit_permissions_paired_read\n//                      | homekit_permissions_paired_write,\n//         .value = HOMEKIT_STRING_(\"my value\"),\n//     );\n#define HOMEKIT_DECLARE_CHARACTERISTIC_CUSTOM(...) \\\n    .format = homekit_format_uint8, \\\n    .unit = homekit_unit_none, \\\n    .permissions = homekit_permissions_paired_read, \\\n    ##__VA_ARGS__\n\n\n// Allocate memory and copy given accessory\n// Does not make copies of all accessory services, so make sure thay are\n// either allocated on heap or in static memory (but not on stack).\nhomekit_accessory_t *homekit_accessory_clone(homekit_accessory_t *accessory);\n// Allocate memory and copy given service.\n// Does not make copies of all service characteristics, so make sure that are\n// either allocated on heap or in static memory (but not on stack).\nhomekit_service_t *homekit_service_clone(homekit_service_t *service);\n// Allocate memory and copy given characteristic.\nhomekit_characteristic_t *homekit_characteristic_clone(homekit_characteristic_t *characteristic);\n\n\n// Macro to define an accessory in dynamic memory.\n// Used to aid creating accessories definitions in runtime.\n// Makes copy of all internal services/characteristics.\n#define NEW_HOMEKIT_ACCESSORY(...) \\\n    homekit_accessory_clone(HOMEKIT_ACCESSORY(__VA_ARGS__))\n\n// Macro to define an service in dynamic memory.\n// Used to aid creating services definitions in runtime.\n// Makes copy of all internal characteristics.\n#define NEW_HOMEKIT_SERVICE(name, ...) \\\n    homekit_service_clone(HOMEKIT_SERVICE(name, ## __VA_ARGS__))\n\n// Macro to define an characteristic in dynamic memory.\n// Used to aid creating characteristics definitions in runtime.\n#define NEW_HOMEKIT_CHARACTERISTIC(name, ...) \\\n    homekit_characteristic_clone(HOMEKIT_CHARACTERISTIC(name, ## __VA_ARGS__))\n\n\n// Init accessories by automatically assigning IDs to all\n// accessories/services/characteristics, normalizing internal data.\nvoid homekit_accessories_init(homekit_accessory_t **accessories);\n\n// Find accessory by ID. Returns NULL if not found\nhomekit_accessory_t *homekit_accessory_by_id(homekit_accessory_t **accessories, uint32_t aid);\n// Find service inside accessory by service type. Returns NULL if not found\nhomekit_service_t *homekit_service_by_type(homekit_accessory_t *accessory, const char *type);\n// Find characteristic inside service by type. Returns NULL if not found\nhomekit_characteristic_t *homekit_service_characteristic_by_type(homekit_service_t *service, const char *type);\n// Find characteristic by accessory ID and characteristic ID. Returns NULL if not found\nhomekit_characteristic_t *homekit_characteristic_by_aid_and_iid(homekit_accessory_t **accessories, uint32_t aid, uint32_t iid);\n\nvoid homekit_characteristic_notify(homekit_characteristic_t *ch, const homekit_value_t value);\nvoid homekit_characteristic_add_notify_callback(\n    homekit_characteristic_t *ch,\n    homekit_characteristic_change_callback_fn callback,\n    void *context\n);\nvoid homekit_characteristic_remove_notify_callback(\n    homekit_characteristic_t *ch,\n    homekit_characteristic_change_callback_fn callback,\n    void *context\n);\nvoid homekit_accessories_clear_notify_callbacks(\n    homekit_accessory_t **accessories,\n    homekit_characteristic_change_callback_fn callback,\n    void *context\n);\nbool homekit_characteristic_has_notify_callback(\n    const homekit_characteristic_t *ch,\n    homekit_characteristic_change_callback_fn callback,\n    void *context\n);\n\n//=========================\n// Compat for cplusplus\n//=========================\nhomekit_value_t HOMEKIT_NULL_CPP();\nhomekit_value_t HOMEKIT_BOOL_CPP(bool value) ;\nhomekit_value_t HOMEKIT_INT_CPP(uint8_t value);\nhomekit_value_t HOMEKIT_UINT8_CPP(uint8_t value);\nhomekit_value_t HOMEKIT_UINT16_CPP(uint16_t value);\nhomekit_value_t HOMEKIT_UINT32_CPP(uint32_t value);\nhomekit_value_t HOMEKIT_UINT64_CPP(uint64_t value);\nhomekit_value_t HOMEKIT_FLOAT_CPP(float value);\nhomekit_value_t HOMEKIT_STRING_CPP(char* value);\nhomekit_value_t HOMEKIT_TLV_CPP(tlv_values_t* value);\nhomekit_value_t HOMEKIT_DATA_CPP(uint8_t* value, size_t size);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // __HOMEKIT_TYPES_H__\n"
  },
  {
    "path": "src/homekit_debug.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n\n#include \"homekit_debug.h\"\n\n\nchar *binary_to_string(const byte *data, size_t size) {\n    int i;\n\n    size_t buffer_size = 1; // 1 char for eos\n    for (i=0; i<size; i++)\n        buffer_size += (data[i] == '\\\\') ? 2 : ((data[i] >= 32 && data[i] < 128) ? 1 : 4);\n\n    char *buffer = malloc(buffer_size);\n\n    int pos = 0;\n    for (i=0; i<size; i++) {\n        if (data[i] == '\\\\') {\n            buffer[pos++] = '\\\\';\n            buffer[pos++] = '\\\\';\n        } else if (data[i] < 32 || data[i] >= 128) {\n            size_t printed = snprintf(&buffer[pos], buffer_size - pos, \"\\\\x%02X\", data[i]);\n            if (printed > 0) {\n                pos += printed;\n            }\n        } else {\n            buffer[pos++] = data[i];\n        }\n    }\n    buffer[pos] = 0;\n\n    return buffer;\n}\n\n\nvoid print_binary(const char *prompt, const byte *data, size_t size) {\n#ifdef HOMEKIT_DEBUG\n    char *buffer = binary_to_string(data, size);\n    printf(\"%s (%d bytes): \\\"%s\\\"\\n\", prompt, (int)size, buffer);\n    free(buffer);\n#endif\n}\n"
  },
  {
    "path": "src/homekit_debug.h",
    "content": "#ifndef __HOMEKIT_DEBUG_H__\n#define __HOMEKIT_DEBUG_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdlib.h>\n#include <stdio.h>\n#include \"Arduino.h\"\n#include <string.h>\n#include <esp_xpgm.h>\n\ntypedef unsigned char byte;\n\n//#define HOMEKIT_DEBUG\n\n#define HOMEKIT_PRINTF XPGM_PRINTF\n#if defined(ARDUINO_ARCH_ESP8266)\n#define MILLIS_FMT \"%7u\"\n#elif defined(ARDUINO_ARCH_ESP32)\n#define MILLIS_FMT \"%7lu\"\n#endif\n\n#ifdef HOMEKIT_DEBUG\n\n#define DEBUG(message, ...)  HOMEKIT_PRINTF(\">>> %s: \" message \"\\n\", __func__, ##__VA_ARGS__)\nstatic uint32_t start_time = 0;\n#define DEBUG_TIME_BEGIN()  start_time=millis();\n#define DEBUG_TIME_END(func_name)  HOMEKIT_PRINTF(\"### [\" MILLIS_FMT \"] %s took %6dms\\n\", millis(), func_name, (millis() - start_time));\n\n#else\n\n#define DEBUG(message, ...)\n\n#endif\n\n#define INFO(message, ...) HOMEKIT_PRINTF(\">>> [\" MILLIS_FMT \"] HomeKit: \" message \"\\n\", millis(), ##__VA_ARGS__)\n#define ERROR(message, ...) HOMEKIT_PRINTF(\"!!! [\" MILLIS_FMT \"] HomeKit: \" message \"\\n\", millis(), ##__VA_ARGS__)\n#define INFO_HEAP() INFO(\"Free heap: %u\", system_get_free_heap_size());\n#define DEBUG_HEAP() DEBUG(\"Free heap: %u\", system_get_free_heap_size());\nstatic unsigned long start_time = 0;\n#define DEBUG_TIME_BEGIN()  start_time=millis();\n#define DEBUG_TIME_END(func_name)  HOMEKIT_PRINTF(\"### [\" MILLIS_FMT \"] %s took \"  MILLIS_FMT \"ms\\n\", millis(), func_name, (millis() - start_time));\n\n\nchar *binary_to_string(const byte *data, size_t size);\nvoid print_binary(const char *prompt, const byte *data, size_t size);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // __HOMEKIT_DEBUG_H__\n"
  },
  {
    "path": "src/http_parser.c",
    "content": "/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev\n *\n * Additional changes are licensed under the same terms as NGINX and\n * copyright Joyent, Inc. and other Node contributors. All rights reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n#include \"http_parser.h\"\n#include <assert.h>\n#include <stddef.h>\n#include <ctype.h>\n#include <stdlib.h>\n#include <string.h>\n#include <limits.h>\n\n#ifndef ULLONG_MAX\n# define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */\n#endif\n\n#ifndef MIN\n# define MIN(a,b) ((a) < (b) ? (a) : (b))\n#endif\n\n#ifndef ARRAY_SIZE\n# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))\n#endif\n\n#ifndef BIT_AT\n# define BIT_AT(a, i)                                                \\\n  (!!((unsigned int) (a)[(unsigned int) (i) >> 3] &                  \\\n   (1 << ((unsigned int) (i) & 7))))\n#endif\n\n#ifndef ELEM_AT\n# define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v))\n#endif\n\n#define SET_ERRNO(e)                                                 \\\ndo {                                                                 \\\n  parser->http_errno = (e);                                          \\\n} while(0)\n\n#define CURRENT_STATE() p_state\n#define UPDATE_STATE(V) p_state = (enum state) (V);\n#define RETURN(V)                                                    \\\ndo {                                                                 \\\n  parser->state = CURRENT_STATE();                                   \\\n  return (V);                                                        \\\n} while (0);\n#define REEXECUTE()                                                  \\\n  goto reexecute;                                                    \\\n\n\n#ifdef __GNUC__\n# define LIKELY(X) __builtin_expect(!!(X), 1)\n# define UNLIKELY(X) __builtin_expect(!!(X), 0)\n#else\n# define LIKELY(X) (X)\n# define UNLIKELY(X) (X)\n#endif\n\n\n/* Run the notify callback FOR, returning ER if it fails */\n#define CALLBACK_NOTIFY_(FOR, ER)                                    \\\ndo {                                                                 \\\n  assert(HTTP_PARSER_ERRNO(parser) == HPE_OK);                       \\\n                                                                     \\\n  if (LIKELY(settings->on_##FOR)) {                                  \\\n    parser->state = CURRENT_STATE();                                 \\\n    if (UNLIKELY(0 != settings->on_##FOR(parser))) {                 \\\n      SET_ERRNO(HPE_CB_##FOR);                                       \\\n    }                                                                \\\n    UPDATE_STATE(parser->state);                                     \\\n                                                                     \\\n    /* We either errored above or got paused; get out */             \\\n    if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) {             \\\n      return (ER);                                                   \\\n    }                                                                \\\n  }                                                                  \\\n} while (0)\n\n/* Run the notify callback FOR and consume the current byte */\n#define CALLBACK_NOTIFY(FOR)            CALLBACK_NOTIFY_(FOR, p - data + 1)\n\n/* Run the notify callback FOR and don't consume the current byte */\n#define CALLBACK_NOTIFY_NOADVANCE(FOR)  CALLBACK_NOTIFY_(FOR, p - data)\n\n/* Run data callback FOR with LEN bytes, returning ER if it fails */\n#define CALLBACK_DATA_(FOR, LEN, ER)                                 \\\ndo {                                                                 \\\n  assert(HTTP_PARSER_ERRNO(parser) == HPE_OK);                       \\\n                                                                     \\\n  if (FOR##_mark) {                                                  \\\n    if (LIKELY(settings->on_##FOR)) {                                \\\n      parser->state = CURRENT_STATE();                               \\\n      if (UNLIKELY(0 !=                                              \\\n                   settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \\\n        SET_ERRNO(HPE_CB_##FOR);                                     \\\n      }                                                              \\\n      UPDATE_STATE(parser->state);                                   \\\n                                                                     \\\n      /* We either errored above or got paused; get out */           \\\n      if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) {           \\\n        return (ER);                                                 \\\n      }                                                              \\\n    }                                                                \\\n    FOR##_mark = NULL;                                               \\\n  }                                                                  \\\n} while (0)\n\n/* Run the data callback FOR and consume the current byte */\n#define CALLBACK_DATA(FOR)                                           \\\n    CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1)\n\n/* Run the data callback FOR and don't consume the current byte */\n#define CALLBACK_DATA_NOADVANCE(FOR)                                 \\\n    CALLBACK_DATA_(FOR, p - FOR##_mark, p - data)\n\n/* Set the mark FOR; non-destructive if mark is already set */\n#define MARK(FOR)                                                    \\\ndo {                                                                 \\\n  if (!FOR##_mark) {                                                 \\\n    FOR##_mark = p;                                                  \\\n  }                                                                  \\\n} while (0)\n\n/* Don't allow the total size of the HTTP headers (including the status\n * line) to exceed HTTP_MAX_HEADER_SIZE.  This check is here to protect\n * embedders against denial-of-service attacks where the attacker feeds\n * us a never-ending header that the embedder keeps buffering.\n *\n * This check is arguably the responsibility of embedders but we're doing\n * it on the embedder's behalf because most won't bother and this way we\n * make the web a little safer.  HTTP_MAX_HEADER_SIZE is still far bigger\n * than any reasonable request or response so this should never affect\n * day-to-day operation.\n */\n#define COUNT_HEADER_SIZE(V)                                         \\\ndo {                                                                 \\\n  parser->nread += (V);                                              \\\n  if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) {            \\\n    SET_ERRNO(HPE_HEADER_OVERFLOW);                                  \\\n    goto error;                                                      \\\n  }                                                                  \\\n} while (0)\n\n\n#define PROXY_CONNECTION \"proxy-connection\"\n#define CONNECTION \"connection\"\n#define CONTENT_LENGTH \"content-length\"\n#define TRANSFER_ENCODING \"transfer-encoding\"\n#define UPGRADE \"upgrade\"\n#define CHUNKED \"chunked\"\n#define KEEP_ALIVE \"keep-alive\"\n#define CLOSE \"close\"\n\n\nstatic const char *method_strings[] =\n  {\n#define XX(num, name, string) #string,\n  HTTP_METHOD_MAP(XX)\n#undef XX\n  };\n\n\n/* Tokens as defined by rfc 2616. Also lowercases them.\n *        token       = 1*<any CHAR except CTLs or separators>\n *     separators     = \"(\" | \")\" | \"<\" | \">\" | \"@\"\n *                    | \",\" | \";\" | \":\" | \"\\\" | <\">\n *                    | \"/\" | \"[\" | \"]\" | \"?\" | \"=\"\n *                    | \"{\" | \"}\" | SP | HT\n */\nstatic const char tokens[256] = {\n/*   0 nul    1 soh    2 stx    3 etx    4 eot    5 enq    6 ack    7 bel  */\n        0,       0,       0,       0,       0,       0,       0,       0,\n/*   8 bs     9 ht    10 nl    11 vt    12 np    13 cr    14 so    15 si   */\n        0,       0,       0,       0,       0,       0,       0,       0,\n/*  16 dle   17 dc1   18 dc2   19 dc3   20 dc4   21 nak   22 syn   23 etb */\n        0,       0,       0,       0,       0,       0,       0,       0,\n/*  24 can   25 em    26 sub   27 esc   28 fs    29 gs    30 rs    31 us  */\n        0,       0,       0,       0,       0,       0,       0,       0,\n/*  32 sp    33  !    34  \"    35  #    36  $    37  %    38  &    39  '  */\n        0,      '!',      0,      '#',     '$',     '%',     '&',    '\\'',\n/*  40  (    41  )    42  *    43  +    44  ,    45  -    46  .    47  /  */\n        0,       0,      '*',     '+',      0,      '-',     '.',      0,\n/*  48  0    49  1    50  2    51  3    52  4    53  5    54  6    55  7  */\n       '0',     '1',     '2',     '3',     '4',     '5',     '6',     '7',\n/*  56  8    57  9    58  :    59  ;    60  <    61  =    62  >    63  ?  */\n       '8',     '9',      0,       0,       0,       0,       0,       0,\n/*  64  @    65  A    66  B    67  C    68  D    69  E    70  F    71  G  */\n        0,      'a',     'b',     'c',     'd',     'e',     'f',     'g',\n/*  72  H    73  I    74  J    75  K    76  L    77  M    78  N    79  O  */\n       'h',     'i',     'j',     'k',     'l',     'm',     'n',     'o',\n/*  80  P    81  Q    82  R    83  S    84  T    85  U    86  V    87  W  */\n       'p',     'q',     'r',     's',     't',     'u',     'v',     'w',\n/*  88  X    89  Y    90  Z    91  [    92  \\    93  ]    94  ^    95  _  */\n       'x',     'y',     'z',      0,       0,       0,      '^',     '_',\n/*  96  `    97  a    98  b    99  c   100  d   101  e   102  f   103  g  */\n       '`',     'a',     'b',     'c',     'd',     'e',     'f',     'g',\n/* 104  h   105  i   106  j   107  k   108  l   109  m   110  n   111  o  */\n       'h',     'i',     'j',     'k',     'l',     'm',     'n',     'o',\n/* 112  p   113  q   114  r   115  s   116  t   117  u   118  v   119  w  */\n       'p',     'q',     'r',     's',     't',     'u',     'v',     'w',\n/* 120  x   121  y   122  z   123  {   124  |   125  }   126  ~   127 del */\n       'x',     'y',     'z',      0,      '|',      0,      '~',       0 };\n\n\nstatic const int8_t unhex[256] =\n  {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1\n  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1\n  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1\n  , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1\n  ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1\n  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1\n  ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1\n  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1\n  };\n\n\n#if HTTP_PARSER_STRICT\n# define T(v) 0\n#else\n# define T(v) v\n#endif\n\n\nstatic const uint8_t normal_url_char[32] = {\n/*   0 nul    1 soh    2 stx    3 etx    4 eot    5 enq    6 ack    7 bel  */\n        0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,\n/*   8 bs     9 ht    10 nl    11 vt    12 np    13 cr    14 so    15 si   */\n        0    | T(2)   |   0    |   0    | T(16)  |   0    |   0    |   0,\n/*  16 dle   17 dc1   18 dc2   19 dc3   20 dc4   21 nak   22 syn   23 etb */\n        0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,\n/*  24 can   25 em    26 sub   27 esc   28 fs    29 gs    30 rs    31 us  */\n        0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,\n/*  32 sp    33  !    34  \"    35  #    36  $    37  %    38  &    39  '  */\n        0    |   2    |   4    |   0    |   16   |   32   |   64   |  128,\n/*  40  (    41  )    42  *    43  +    44  ,    45  -    46  .    47  /  */\n        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,\n/*  48  0    49  1    50  2    51  3    52  4    53  5    54  6    55  7  */\n        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,\n/*  56  8    57  9    58  :    59  ;    60  <    61  =    62  >    63  ?  */\n        1    |   2    |   4    |   8    |   16   |   32   |   64   |   0,\n/*  64  @    65  A    66  B    67  C    68  D    69  E    70  F    71  G  */\n        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,\n/*  72  H    73  I    74  J    75  K    76  L    77  M    78  N    79  O  */\n        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,\n/*  80  P    81  Q    82  R    83  S    84  T    85  U    86  V    87  W  */\n        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,\n/*  88  X    89  Y    90  Z    91  [    92  \\    93  ]    94  ^    95  _  */\n        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,\n/*  96  `    97  a    98  b    99  c   100  d   101  e   102  f   103  g  */\n        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,\n/* 104  h   105  i   106  j   107  k   108  l   109  m   110  n   111  o  */\n        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,\n/* 112  p   113  q   114  r   115  s   116  t   117  u   118  v   119  w  */\n        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,\n/* 120  x   121  y   122  z   123  {   124  |   125  }   126  ~   127 del */\n        1    |   2    |   4    |   8    |   16   |   32   |   64   |   0, };\n\n#undef T\n\nenum state\n  { s_dead = 1 /* important that this is > 0 */\n\n  , s_start_req_or_res\n  , s_res_or_resp_H\n  , s_start_res\n  , s_res_H\n  , s_res_HT\n  , s_res_HTT\n  , s_res_HTTP\n  , s_res_first_http_major\n  , s_res_http_major\n  , s_res_first_http_minor\n  , s_res_http_minor\n  , s_res_first_status_code\n  , s_res_status_code\n  , s_res_status_start\n  , s_res_status\n  , s_res_line_almost_done\n\n  , s_start_req\n\n  , s_req_method\n  , s_req_spaces_before_url\n  , s_req_schema\n  , s_req_schema_slash\n  , s_req_schema_slash_slash\n  , s_req_server_start\n  , s_req_server\n  , s_req_server_with_at\n  , s_req_path\n  , s_req_query_string_start\n  , s_req_query_string\n  , s_req_fragment_start\n  , s_req_fragment\n  , s_req_http_start\n  , s_req_http_H\n  , s_req_http_HT\n  , s_req_http_HTT\n  , s_req_http_HTTP\n  , s_req_first_http_major\n  , s_req_http_major\n  , s_req_first_http_minor\n  , s_req_http_minor\n  , s_req_line_almost_done\n\n  , s_header_field_start\n  , s_header_field\n  , s_header_value_discard_ws\n  , s_header_value_discard_ws_almost_done\n  , s_header_value_discard_lws\n  , s_header_value_start\n  , s_header_value\n  , s_header_value_lws\n\n  , s_header_almost_done\n\n  , s_chunk_size_start\n  , s_chunk_size\n  , s_chunk_parameters\n  , s_chunk_size_almost_done\n\n  , s_headers_almost_done\n  , s_headers_done\n\n  /* Important: 's_headers_done' must be the last 'header' state. All\n   * states beyond this must be 'body' states. It is used for overflow\n   * checking. See the PARSING_HEADER() macro.\n   */\n\n  , s_chunk_data\n  , s_chunk_data_almost_done\n  , s_chunk_data_done\n\n  , s_body_identity\n  , s_body_identity_eof\n\n  , s_message_done\n  };\n\n\n#define PARSING_HEADER(state) (state <= s_headers_done)\n\n\nenum header_states\n  { h_general = 0\n  , h_C\n  , h_CO\n  , h_CON\n\n  , h_matching_connection\n  , h_matching_proxy_connection\n  , h_matching_content_length\n  , h_matching_transfer_encoding\n  , h_matching_upgrade\n\n  , h_connection\n  , h_content_length\n  , h_transfer_encoding\n  , h_upgrade\n\n  , h_matching_transfer_encoding_chunked\n  , h_matching_connection_token_start\n  , h_matching_connection_keep_alive\n  , h_matching_connection_close\n  , h_matching_connection_upgrade\n  , h_matching_connection_token\n\n  , h_transfer_encoding_chunked\n  , h_connection_keep_alive\n  , h_connection_close\n  , h_connection_upgrade\n  };\n\nenum http_host_state\n  {\n    s_http_host_dead = 1\n  , s_http_userinfo_start\n  , s_http_userinfo\n  , s_http_host_start\n  , s_http_host_v6_start\n  , s_http_host\n  , s_http_host_v6\n  , s_http_host_v6_end\n  , s_http_host_v6_zone_start\n  , s_http_host_v6_zone\n  , s_http_host_port_start\n  , s_http_host_port\n};\n\n/* Macros for character classes; depends on strict-mode  */\n#define CR                  '\\r'\n#define LF                  '\\n'\n#define LOWER(c)            (unsigned char)(c | 0x20)\n#define IS_ALPHA(c)         (LOWER(c) >= 'a' && LOWER(c) <= 'z')\n#define IS_NUM(c)           ((c) >= '0' && (c) <= '9')\n#define IS_ALPHANUM(c)      (IS_ALPHA(c) || IS_NUM(c))\n#define IS_HEX(c)           (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f'))\n#define IS_MARK(c)          ((c) == '-' || (c) == '_' || (c) == '.' || \\\n  (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\\'' || (c) == '(' || \\\n  (c) == ')')\n#define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \\\n  (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \\\n  (c) == '$' || (c) == ',')\n\n#define STRICT_TOKEN(c)     (tokens[(unsigned char)c])\n\n#if HTTP_PARSER_STRICT\n#define TOKEN(c)            (tokens[(unsigned char)c])\n#define IS_URL_CHAR(c)      (BIT_AT(normal_url_char, (unsigned char)c))\n#define IS_HOST_CHAR(c)     (IS_ALPHANUM(c) || (c) == '.' || (c) == '-')\n#else\n#define TOKEN(c)            ((c == ' ') ? ' ' : tokens[(unsigned char)c])\n#define IS_URL_CHAR(c)                                                         \\\n  (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80))\n#define IS_HOST_CHAR(c)                                                        \\\n  (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_')\n#endif\n\n/**\n * Verify that a char is a valid visible (printable) US-ASCII\n * character or %x80-FF\n **/\n#define IS_HEADER_CHAR(ch)                                                     \\\n  (ch == CR || ch == LF || ch == 9 || ((unsigned char)ch > 31 && ch != 127))\n\n#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res)\n\n\n#if HTTP_PARSER_STRICT\n# define STRICT_CHECK(cond)                                          \\\ndo {                                                                 \\\n  if (cond) {                                                        \\\n    SET_ERRNO(HPE_STRICT);                                           \\\n    goto error;                                                      \\\n  }                                                                  \\\n} while (0)\n# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead)\n#else\n# define STRICT_CHECK(cond)\n# define NEW_MESSAGE() start_state\n#endif\n\n\n/* Map errno values to strings for human-readable output */\n/*\n#define HTTP_STRERROR_GEN(n, s) { \"HPE_\" #n, s },\nstatic struct {\n  const char *name;\n  const char *description;\n} http_strerror_tab[] = {\n  HTTP_ERRNO_MAP(HTTP_STRERROR_GEN)\n};\n#undef HTTP_STRERROR_GEN*/\n\nint http_message_needs_eof(const http_parser *parser);\n\n/* Our URL parser.\n *\n * This is designed to be shared by http_parser_execute() for URL validation,\n * hence it has a state transition + byte-for-byte interface. In addition, it\n * is meant to be embedded in http_parser_parse_url(), which does the dirty\n * work of turning state transitions URL components for its API.\n *\n * This function should only be invoked with non-space characters. It is\n * assumed that the caller cares about (and can detect) the transition between\n * URL and non-URL states by looking for these.\n */\nstatic enum state\nparse_url_char(enum state s, const char ch)\n{\n  if (ch == ' ' || ch == '\\r' || ch == '\\n') {\n    return s_dead;\n  }\n\n#if HTTP_PARSER_STRICT\n  if (ch == '\\t' || ch == '\\f') {\n    return s_dead;\n  }\n#endif\n\n  switch (s) {\n    case s_req_spaces_before_url:\n      /* Proxied requests are followed by scheme of an absolute URI (alpha).\n       * All methods except CONNECT are followed by '/' or '*'.\n       */\n\n      if (ch == '/' || ch == '*') {\n        return s_req_path;\n      }\n\n      if (IS_ALPHA(ch)) {\n        return s_req_schema;\n      }\n\n      break;\n\n    case s_req_schema:\n      if (IS_ALPHA(ch)) {\n        return s;\n      }\n\n      if (ch == ':') {\n        return s_req_schema_slash;\n      }\n\n      break;\n\n    case s_req_schema_slash:\n      if (ch == '/') {\n        return s_req_schema_slash_slash;\n      }\n\n      break;\n\n    case s_req_schema_slash_slash:\n      if (ch == '/') {\n        return s_req_server_start;\n      }\n\n      break;\n\n    case s_req_server_with_at:\n      if (ch == '@') {\n        return s_dead;\n      }\n\n    /* FALLTHROUGH */\n    case s_req_server_start:\n    case s_req_server:\n      if (ch == '/') {\n        return s_req_path;\n      }\n\n      if (ch == '?') {\n        return s_req_query_string_start;\n      }\n\n      if (ch == '@') {\n        return s_req_server_with_at;\n      }\n\n      if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') {\n        return s_req_server;\n      }\n\n      break;\n\n    case s_req_path:\n      if (IS_URL_CHAR(ch)) {\n        return s;\n      }\n\n      switch (ch) {\n        case '?':\n          return s_req_query_string_start;\n\n        case '#':\n          return s_req_fragment_start;\n      }\n\n      break;\n\n    case s_req_query_string_start:\n    case s_req_query_string:\n      if (IS_URL_CHAR(ch)) {\n        return s_req_query_string;\n      }\n\n      switch (ch) {\n        case '?':\n          /* allow extra '?' in query string */\n          return s_req_query_string;\n\n        case '#':\n          return s_req_fragment_start;\n      }\n\n      break;\n\n    case s_req_fragment_start:\n      if (IS_URL_CHAR(ch)) {\n        return s_req_fragment;\n      }\n\n      switch (ch) {\n        case '?':\n          return s_req_fragment;\n\n        case '#':\n          return s;\n      }\n\n      break;\n\n    case s_req_fragment:\n      if (IS_URL_CHAR(ch)) {\n        return s;\n      }\n\n      switch (ch) {\n        case '?':\n        case '#':\n          return s;\n      }\n\n      break;\n\n    default:\n      break;\n  }\n\n  /* We should never fall out of the switch above unless there's an error */\n  return s_dead;\n}\n\nsize_t http_parser_execute (http_parser *parser,\n                            const http_parser_settings *settings,\n                            const char *data,\n                            size_t len)\n{\n  char c, ch;\n  int8_t unhex_val;\n  const char *p = data;\n  const char *header_field_mark = 0;\n  const char *header_value_mark = 0;\n  const char *url_mark = 0;\n  const char *body_mark = 0;\n  const char *status_mark = 0;\n  enum state p_state = (enum state) parser->state;\n  const unsigned int lenient = parser->lenient_http_headers;\n\n  /* We're in an error state. Don't bother doing anything. */\n  if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {\n    return 0;\n  }\n\n  if (len == 0) {\n    switch (CURRENT_STATE()) {\n      case s_body_identity_eof:\n        /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if\n         * we got paused.\n         */\n        CALLBACK_NOTIFY_NOADVANCE(message_complete);\n        return 0;\n\n      case s_dead:\n      case s_start_req_or_res:\n      case s_start_res:\n      case s_start_req:\n        return 0;\n\n      default:\n        SET_ERRNO(HPE_INVALID_EOF_STATE);\n        return 1;\n    }\n  }\n\n\n  if (CURRENT_STATE() == s_header_field)\n    header_field_mark = data;\n  if (CURRENT_STATE() == s_header_value)\n    header_value_mark = data;\n  switch (CURRENT_STATE()) {\n  case s_req_path:\n  case s_req_schema:\n  case s_req_schema_slash:\n  case s_req_schema_slash_slash:\n  case s_req_server_start:\n  case s_req_server:\n  case s_req_server_with_at:\n  case s_req_query_string_start:\n  case s_req_query_string:\n  case s_req_fragment_start:\n  case s_req_fragment:\n    url_mark = data;\n    break;\n  case s_res_status:\n    status_mark = data;\n    break;\n  default:\n    break;\n  }\n\n  for (p=data; p != data + len; p++) {\n    ch = *p;\n\n    if (PARSING_HEADER(CURRENT_STATE()))\n      COUNT_HEADER_SIZE(1);\n\nreexecute:\n    switch (CURRENT_STATE()) {\n\n      case s_dead:\n        /* this state is used after a 'Connection: close' message\n         * the parser will error out if it reads another message\n         */\n        if (LIKELY(ch == CR || ch == LF))\n          break;\n\n        SET_ERRNO(HPE_CLOSED_CONNECTION);\n        goto error;\n\n      case s_start_req_or_res:\n      {\n        if (ch == CR || ch == LF)\n          break;\n        parser->flags = 0;\n        parser->content_length = ULLONG_MAX;\n\n        if (ch == 'H') {\n          UPDATE_STATE(s_res_or_resp_H);\n\n          CALLBACK_NOTIFY(message_begin);\n        } else {\n          parser->type = HTTP_REQUEST;\n          UPDATE_STATE(s_start_req);\n          REEXECUTE();\n        }\n\n        break;\n      }\n\n      case s_res_or_resp_H:\n        if (ch == 'T') {\n          parser->type = HTTP_RESPONSE;\n          UPDATE_STATE(s_res_HT);\n        } else {\n          if (UNLIKELY(ch != 'E')) {\n            SET_ERRNO(HPE_INVALID_CONSTANT);\n            goto error;\n          }\n\n          parser->type = HTTP_REQUEST;\n          parser->method = HTTP_PARSER_METHOD_HEAD;\n          parser->index = 2;\n          UPDATE_STATE(s_req_method);\n        }\n        break;\n\n      case s_start_res:\n      {\n        parser->flags = 0;\n        parser->content_length = ULLONG_MAX;\n\n        switch (ch) {\n          case 'H':\n            UPDATE_STATE(s_res_H);\n            break;\n\n          case CR:\n          case LF:\n            break;\n\n          default:\n            SET_ERRNO(HPE_INVALID_CONSTANT);\n            goto error;\n        }\n\n        CALLBACK_NOTIFY(message_begin);\n        break;\n      }\n\n      case s_res_H:\n        STRICT_CHECK(ch != 'T');\n        UPDATE_STATE(s_res_HT);\n        break;\n\n      case s_res_HT:\n        STRICT_CHECK(ch != 'T');\n        UPDATE_STATE(s_res_HTT);\n        break;\n\n      case s_res_HTT:\n        STRICT_CHECK(ch != 'P');\n        UPDATE_STATE(s_res_HTTP);\n        break;\n\n      case s_res_HTTP:\n        STRICT_CHECK(ch != '/');\n        UPDATE_STATE(s_res_first_http_major);\n        break;\n\n      case s_res_first_http_major:\n        if (UNLIKELY(ch < '0' || ch > '9')) {\n          SET_ERRNO(HPE_INVALID_VERSION);\n          goto error;\n        }\n\n        parser->http_major = ch - '0';\n        UPDATE_STATE(s_res_http_major);\n        break;\n\n      /* major HTTP version or dot */\n      case s_res_http_major:\n      {\n        if (ch == '.') {\n          UPDATE_STATE(s_res_first_http_minor);\n          break;\n        }\n\n        if (!IS_NUM(ch)) {\n          SET_ERRNO(HPE_INVALID_VERSION);\n          goto error;\n        }\n\n        parser->http_major *= 10;\n        parser->http_major += ch - '0';\n\n        if (UNLIKELY(parser->http_major > 999)) {\n          SET_ERRNO(HPE_INVALID_VERSION);\n          goto error;\n        }\n\n        break;\n      }\n\n      /* first digit of minor HTTP version */\n      case s_res_first_http_minor:\n        if (UNLIKELY(!IS_NUM(ch))) {\n          SET_ERRNO(HPE_INVALID_VERSION);\n          goto error;\n        }\n\n        parser->http_minor = ch - '0';\n        UPDATE_STATE(s_res_http_minor);\n        break;\n\n      /* minor HTTP version or end of request line */\n      case s_res_http_minor:\n      {\n        if (ch == ' ') {\n          UPDATE_STATE(s_res_first_status_code);\n          break;\n        }\n\n        if (UNLIKELY(!IS_NUM(ch))) {\n          SET_ERRNO(HPE_INVALID_VERSION);\n          goto error;\n        }\n\n        parser->http_minor *= 10;\n        parser->http_minor += ch - '0';\n\n        if (UNLIKELY(parser->http_minor > 999)) {\n          SET_ERRNO(HPE_INVALID_VERSION);\n          goto error;\n        }\n\n        break;\n      }\n\n      case s_res_first_status_code:\n      {\n        if (!IS_NUM(ch)) {\n          if (ch == ' ') {\n            break;\n          }\n\n          SET_ERRNO(HPE_INVALID_STATUS);\n          goto error;\n        }\n        parser->status_code = ch - '0';\n        UPDATE_STATE(s_res_status_code);\n        break;\n      }\n\n      case s_res_status_code:\n      {\n        if (!IS_NUM(ch)) {\n          switch (ch) {\n            case ' ':\n              UPDATE_STATE(s_res_status_start);\n              break;\n            case CR:\n              UPDATE_STATE(s_res_line_almost_done);\n              break;\n            case LF:\n              UPDATE_STATE(s_header_field_start);\n              break;\n            default:\n              SET_ERRNO(HPE_INVALID_STATUS);\n              goto error;\n          }\n          break;\n        }\n\n        parser->status_code *= 10;\n        parser->status_code += ch - '0';\n\n        if (UNLIKELY(parser->status_code > 999)) {\n          SET_ERRNO(HPE_INVALID_STATUS);\n          goto error;\n        }\n\n        break;\n      }\n\n      case s_res_status_start:\n      {\n        if (ch == CR) {\n          UPDATE_STATE(s_res_line_almost_done);\n          break;\n        }\n\n        if (ch == LF) {\n          UPDATE_STATE(s_header_field_start);\n          break;\n        }\n\n        MARK(status);\n        UPDATE_STATE(s_res_status);\n        parser->index = 0;\n        break;\n      }\n\n      case s_res_status:\n        if (ch == CR) {\n          UPDATE_STATE(s_res_line_almost_done);\n          CALLBACK_DATA(status);\n          break;\n        }\n\n        if (ch == LF) {\n          UPDATE_STATE(s_header_field_start);\n          CALLBACK_DATA(status);\n          break;\n        }\n\n        break;\n\n      case s_res_line_almost_done:\n        STRICT_CHECK(ch != LF);\n        UPDATE_STATE(s_header_field_start);\n        break;\n\n      case s_start_req:\n      {\n        if (ch == CR || ch == LF)\n          break;\n        parser->flags = 0;\n        parser->content_length = ULLONG_MAX;\n\n        if (UNLIKELY(!IS_ALPHA(ch))) {\n          SET_ERRNO(HPE_INVALID_METHOD);\n          goto error;\n        }\n\n        parser->method = (enum http_method) 0;\n        parser->index = 1;\n        switch (ch) {\n          case 'A': parser->method = HTTP_PARSER_METHOD_ACL; break;\n          case 'B': parser->method = HTTP_PARSER_METHOD_BIND; break;\n          case 'C': parser->method = HTTP_PARSER_METHOD_CONNECT; /* or COPY, CHECKOUT */ break;\n          case 'D': parser->method = HTTP_PARSER_METHOD_DELETE; break;\n          case 'G': parser->method = HTTP_PARSER_METHOD_GET; break;\n          case 'H': parser->method = HTTP_PARSER_METHOD_HEAD; break;\n          case 'L': parser->method = HTTP_PARSER_METHOD_LOCK; /* or LINK */ break;\n          case 'M': parser->method = HTTP_PARSER_METHOD_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break;\n          case 'N': parser->method = HTTP_PARSER_METHOD_NOTIFY; break;\n          case 'O': parser->method = HTTP_PARSER_METHOD_OPTIONS; break;\n          case 'P': parser->method = HTTP_PARSER_METHOD_POST;\n            /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */\n            break;\n          case 'R': parser->method = HTTP_PARSER_METHOD_REPORT; /* or REBIND */ break;\n          case 'S': parser->method = HTTP_PARSER_METHOD_SUBSCRIBE; /* or SEARCH */ break;\n          case 'T': parser->method = HTTP_PARSER_METHOD_TRACE; break;\n          case 'U': parser->method = HTTP_PARSER_METHOD_UNLOCK; /* or UNSUBSCRIBE, UNBIND, UNLINK */ break;\n          default:\n            SET_ERRNO(HPE_INVALID_METHOD);\n            goto error;\n        }\n        UPDATE_STATE(s_req_method);\n\n        CALLBACK_NOTIFY(message_begin);\n\n        break;\n      }\n\n      case s_req_method:\n      {\n        const char *matcher;\n        if (UNLIKELY(ch == '\\0')) {\n          SET_ERRNO(HPE_INVALID_METHOD);\n          goto error;\n        }\n\n        matcher = method_strings[parser->method];\n        if (ch == ' ' && matcher[parser->index] == '\\0') {\n          UPDATE_STATE(s_req_spaces_before_url);\n        } else if (ch == matcher[parser->index]) {\n          ; /* nada */\n        } else if (IS_ALPHA(ch)) {\n\n          switch (parser->method << 16 | parser->index << 8 | ch) {\n#define XX(meth, pos, ch, new_meth) \\\n            case (HTTP_PARSER_METHOD_##meth << 16 | pos << 8 | ch): \\\n              parser->method = HTTP_PARSER_METHOD_##new_meth; break;\n\n            XX(POST,      1, 'U', PUT)\n            XX(POST,      1, 'A', PATCH)\n            XX(CONNECT,   1, 'H', CHECKOUT)\n            XX(CONNECT,   2, 'P', COPY)\n            XX(MKCOL,     1, 'O', MOVE)\n            XX(MKCOL,     1, 'E', MERGE)\n            XX(MKCOL,     2, 'A', MKACTIVITY)\n            XX(MKCOL,     3, 'A', MKCALENDAR)\n            XX(SUBSCRIBE, 1, 'E', SEARCH)\n            XX(REPORT,    2, 'B', REBIND)\n            XX(POST,      1, 'R', PROPFIND)\n            XX(PROPFIND,  4, 'P', PROPPATCH)\n            XX(PUT,       2, 'R', PURGE)\n            XX(LOCK,      1, 'I', LINK)\n            XX(UNLOCK,    2, 'S', UNSUBSCRIBE)\n            XX(UNLOCK,    2, 'B', UNBIND)\n            XX(UNLOCK,    3, 'I', UNLINK)\n#undef XX\n\n            default:\n              SET_ERRNO(HPE_INVALID_METHOD);\n              goto error;\n          }\n        } else if (ch == '-' &&\n                   parser->index == 1 &&\n                   parser->method == HTTP_PARSER_METHOD_MKCOL) {\n          parser->method = HTTP_PARSER_METHOD_MSEARCH;\n        } else {\n          SET_ERRNO(HPE_INVALID_METHOD);\n          goto error;\n        }\n\n        ++parser->index;\n        break;\n      }\n\n      case s_req_spaces_before_url:\n      {\n        if (ch == ' ') break;\n\n        MARK(url);\n        if (parser->method == HTTP_PARSER_METHOD_CONNECT) {\n          UPDATE_STATE(s_req_server_start);\n        }\n\n        UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));\n        if (UNLIKELY(CURRENT_STATE() == s_dead)) {\n          SET_ERRNO(HPE_INVALID_URL);\n          goto error;\n        }\n\n        break;\n      }\n\n      case s_req_schema:\n      case s_req_schema_slash:\n      case s_req_schema_slash_slash:\n      case s_req_server_start:\n      {\n        switch (ch) {\n          /* No whitespace allowed here */\n          case ' ':\n          case CR:\n          case LF:\n            SET_ERRNO(HPE_INVALID_URL);\n            goto error;\n          default:\n            UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));\n            if (UNLIKELY(CURRENT_STATE() == s_dead)) {\n              SET_ERRNO(HPE_INVALID_URL);\n              goto error;\n            }\n        }\n\n        break;\n      }\n\n      case s_req_server:\n      case s_req_server_with_at:\n      case s_req_path:\n      case s_req_query_string_start:\n      case s_req_query_string:\n      case s_req_fragment_start:\n      case s_req_fragment:\n      {\n        switch (ch) {\n          case ' ':\n            UPDATE_STATE(s_req_http_start);\n            CALLBACK_DATA(url);\n            break;\n          case CR:\n          case LF:\n            parser->http_major = 0;\n            parser->http_minor = 9;\n            UPDATE_STATE((ch == CR) ?\n              s_req_line_almost_done :\n              s_header_field_start);\n            CALLBACK_DATA(url);\n            break;\n          default:\n            UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));\n            if (UNLIKELY(CURRENT_STATE() == s_dead)) {\n              SET_ERRNO(HPE_INVALID_URL);\n              goto error;\n            }\n        }\n        break;\n      }\n\n      case s_req_http_start:\n        switch (ch) {\n          case 'H':\n            UPDATE_STATE(s_req_http_H);\n            break;\n          case ' ':\n            break;\n          default:\n            SET_ERRNO(HPE_INVALID_CONSTANT);\n            goto error;\n        }\n        break;\n\n      case s_req_http_H:\n        STRICT_CHECK(ch != 'T');\n        UPDATE_STATE(s_req_http_HT);\n        break;\n\n      case s_req_http_HT:\n        STRICT_CHECK(ch != 'T');\n        UPDATE_STATE(s_req_http_HTT);\n        break;\n\n      case s_req_http_HTT:\n        STRICT_CHECK(ch != 'P');\n        UPDATE_STATE(s_req_http_HTTP);\n        break;\n\n      case s_req_http_HTTP:\n        STRICT_CHECK(ch != '/');\n        UPDATE_STATE(s_req_first_http_major);\n        break;\n\n      /* first digit of major HTTP version */\n      case s_req_first_http_major:\n        if (UNLIKELY(ch < '1' || ch > '9')) {\n          SET_ERRNO(HPE_INVALID_VERSION);\n          goto error;\n        }\n\n        parser->http_major = ch - '0';\n        UPDATE_STATE(s_req_http_major);\n        break;\n\n      /* major HTTP version or dot */\n      case s_req_http_major:\n      {\n        if (ch == '.') {\n          UPDATE_STATE(s_req_first_http_minor);\n          break;\n        }\n\n        if (UNLIKELY(!IS_NUM(ch))) {\n          SET_ERRNO(HPE_INVALID_VERSION);\n          goto error;\n        }\n\n        parser->http_major *= 10;\n        parser->http_major += ch - '0';\n\n        if (UNLIKELY(parser->http_major > 999)) {\n          SET_ERRNO(HPE_INVALID_VERSION);\n          goto error;\n        }\n\n        break;\n      }\n\n      /* first digit of minor HTTP version */\n      case s_req_first_http_minor:\n        if (UNLIKELY(!IS_NUM(ch))) {\n          SET_ERRNO(HPE_INVALID_VERSION);\n          goto error;\n        }\n\n        parser->http_minor = ch - '0';\n        UPDATE_STATE(s_req_http_minor);\n        break;\n\n      /* minor HTTP version or end of request line */\n      case s_req_http_minor:\n      {\n        if (ch == CR) {\n          UPDATE_STATE(s_req_line_almost_done);\n          break;\n        }\n\n        if (ch == LF) {\n          UPDATE_STATE(s_header_field_start);\n          break;\n        }\n\n        /* XXX allow spaces after digit? */\n\n        if (UNLIKELY(!IS_NUM(ch))) {\n          SET_ERRNO(HPE_INVALID_VERSION);\n          goto error;\n        }\n\n        parser->http_minor *= 10;\n        parser->http_minor += ch - '0';\n\n        if (UNLIKELY(parser->http_minor > 999)) {\n          SET_ERRNO(HPE_INVALID_VERSION);\n          goto error;\n        }\n\n        break;\n      }\n\n      /* end of request line */\n      case s_req_line_almost_done:\n      {\n        if (UNLIKELY(ch != LF)) {\n          SET_ERRNO(HPE_LF_EXPECTED);\n          goto error;\n        }\n\n        UPDATE_STATE(s_header_field_start);\n        break;\n      }\n\n      case s_header_field_start:\n      {\n        if (ch == CR) {\n          UPDATE_STATE(s_headers_almost_done);\n          break;\n        }\n\n        if (ch == LF) {\n          /* they might be just sending \\n instead of \\r\\n so this would be\n           * the second \\n to denote the end of headers*/\n          UPDATE_STATE(s_headers_almost_done);\n          REEXECUTE();\n        }\n\n        c = TOKEN(ch);\n\n        if (UNLIKELY(!c)) {\n          SET_ERRNO(HPE_INVALID_HEADER_TOKEN);\n          goto error;\n        }\n\n        MARK(header_field);\n\n        parser->index = 0;\n        UPDATE_STATE(s_header_field);\n\n        switch (c) {\n          case 'c':\n            parser->header_state = h_C;\n            break;\n\n          case 'p':\n            parser->header_state = h_matching_proxy_connection;\n            break;\n\n          case 't':\n            parser->header_state = h_matching_transfer_encoding;\n            break;\n\n          case 'u':\n            parser->header_state = h_matching_upgrade;\n            break;\n\n          default:\n            parser->header_state = h_general;\n            break;\n        }\n        break;\n      }\n\n      case s_header_field:\n      {\n        const char* start = p;\n        for (; p != data + len; p++) {\n          ch = *p;\n          c = TOKEN(ch);\n\n          if (!c)\n            break;\n\n          switch (parser->header_state) {\n            case h_general:\n              break;\n\n            case h_C:\n              parser->index++;\n              parser->header_state = (c == 'o' ? h_CO : h_general);\n              break;\n\n            case h_CO:\n              parser->index++;\n              parser->header_state = (c == 'n' ? h_CON : h_general);\n              break;\n\n            case h_CON:\n              parser->index++;\n              switch (c) {\n                case 'n':\n                  parser->header_state = h_matching_connection;\n                  break;\n                case 't':\n                  parser->header_state = h_matching_content_length;\n                  break;\n                default:\n                  parser->header_state = h_general;\n                  break;\n              }\n              break;\n\n            /* connection */\n\n            case h_matching_connection:\n              parser->index++;\n              if (parser->index > sizeof(CONNECTION)-1\n                  || c != CONNECTION[parser->index]) {\n                parser->header_state = h_general;\n              } else if (parser->index == sizeof(CONNECTION)-2) {\n                parser->header_state = h_connection;\n              }\n              break;\n\n            /* proxy-connection */\n\n            case h_matching_proxy_connection:\n              parser->index++;\n              if (parser->index > sizeof(PROXY_CONNECTION)-1\n                  || c != PROXY_CONNECTION[parser->index]) {\n                parser->header_state = h_general;\n              } else if (parser->index == sizeof(PROXY_CONNECTION)-2) {\n                parser->header_state = h_connection;\n              }\n              break;\n\n            /* content-length */\n\n            case h_matching_content_length:\n              parser->index++;\n              if (parser->index > sizeof(CONTENT_LENGTH)-1\n                  || c != CONTENT_LENGTH[parser->index]) {\n                parser->header_state = h_general;\n              } else if (parser->index == sizeof(CONTENT_LENGTH)-2) {\n                parser->header_state = h_content_length;\n              }\n              break;\n\n            /* transfer-encoding */\n\n            case h_matching_transfer_encoding:\n              parser->index++;\n              if (parser->index > sizeof(TRANSFER_ENCODING)-1\n                  || c != TRANSFER_ENCODING[parser->index]) {\n                parser->header_state = h_general;\n              } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {\n                parser->header_state = h_transfer_encoding;\n              }\n              break;\n\n            /* upgrade */\n\n            case h_matching_upgrade:\n              parser->index++;\n              if (parser->index > sizeof(UPGRADE)-1\n                  || c != UPGRADE[parser->index]) {\n                parser->header_state = h_general;\n              } else if (parser->index == sizeof(UPGRADE)-2) {\n                parser->header_state = h_upgrade;\n              }\n              break;\n\n            case h_connection:\n            case h_content_length:\n            case h_transfer_encoding:\n            case h_upgrade:\n              if (ch != ' ') parser->header_state = h_general;\n              break;\n\n            default:\n              assert(0 && \"Unknown header_state\");\n              break;\n          }\n        }\n\n        COUNT_HEADER_SIZE(p - start);\n\n        if (p == data + len) {\n          --p;\n          break;\n        }\n\n        if (ch == ':') {\n          UPDATE_STATE(s_header_value_discard_ws);\n          CALLBACK_DATA(header_field);\n          break;\n        }\n\n        SET_ERRNO(HPE_INVALID_HEADER_TOKEN);\n        goto error;\n      }\n\n      case s_header_value_discard_ws:\n        if (ch == ' ' || ch == '\\t') break;\n\n        if (ch == CR) {\n          UPDATE_STATE(s_header_value_discard_ws_almost_done);\n          break;\n        }\n\n        if (ch == LF) {\n          UPDATE_STATE(s_header_value_discard_lws);\n          break;\n        }\n\n        /* FALLTHROUGH */\n\n      case s_header_value_start:\n      {\n        MARK(header_value);\n\n        UPDATE_STATE(s_header_value);\n        parser->index = 0;\n\n        c = LOWER(ch);\n\n        switch (parser->header_state) {\n          case h_upgrade:\n            parser->flags |= F_UPGRADE;\n            parser->header_state = h_general;\n            break;\n\n          case h_transfer_encoding:\n            /* looking for 'Transfer-Encoding: chunked' */\n            if ('c' == c) {\n              parser->header_state = h_matching_transfer_encoding_chunked;\n            } else {\n              parser->header_state = h_general;\n            }\n            break;\n\n          case h_content_length:\n            if (UNLIKELY(!IS_NUM(ch))) {\n              SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);\n              goto error;\n            }\n\n            if (parser->flags & F_CONTENTLENGTH) {\n              SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH);\n              goto error;\n            }\n\n            parser->flags |= F_CONTENTLENGTH;\n            parser->content_length = ch - '0';\n            break;\n\n          case h_connection:\n            /* looking for 'Connection: keep-alive' */\n            if (c == 'k') {\n              parser->header_state = h_matching_connection_keep_alive;\n            /* looking for 'Connection: close' */\n            } else if (c == 'c') {\n              parser->header_state = h_matching_connection_close;\n            } else if (c == 'u') {\n              parser->header_state = h_matching_connection_upgrade;\n            } else {\n              parser->header_state = h_matching_connection_token;\n            }\n            break;\n\n          /* Multi-value `Connection` header */\n          case h_matching_connection_token_start:\n            break;\n\n          default:\n            parser->header_state = h_general;\n            break;\n        }\n        break;\n      }\n\n      case s_header_value:\n      {\n        const char* start = p;\n        enum header_states h_state = (enum header_states) parser->header_state;\n        for (; p != data + len; p++) {\n          ch = *p;\n          if (ch == CR) {\n            UPDATE_STATE(s_header_almost_done);\n            parser->header_state = h_state;\n            CALLBACK_DATA(header_value);\n            break;\n          }\n\n          if (ch == LF) {\n            UPDATE_STATE(s_header_almost_done);\n            COUNT_HEADER_SIZE(p - start);\n            parser->header_state = h_state;\n            CALLBACK_DATA_NOADVANCE(header_value);\n            REEXECUTE();\n          }\n\n          if (!lenient && !IS_HEADER_CHAR(ch)) {\n            SET_ERRNO(HPE_INVALID_HEADER_TOKEN);\n            goto error;\n          }\n\n          c = LOWER(ch);\n\n          switch (h_state) {\n            case h_general:\n            {\n              const char* p_cr;\n              const char* p_lf;\n              size_t limit = data + len - p;\n\n              limit = MIN(limit, HTTP_MAX_HEADER_SIZE);\n\n              p_cr = (const char*) memchr(p, CR, limit);\n              p_lf = (const char*) memchr(p, LF, limit);\n              if (p_cr != NULL) {\n                if (p_lf != NULL && p_cr >= p_lf)\n                  p = p_lf;\n                else\n                  p = p_cr;\n              } else if (UNLIKELY(p_lf != NULL)) {\n                p = p_lf;\n              } else {\n                p = data + len;\n              }\n              --p;\n\n              break;\n            }\n\n            case h_connection:\n            case h_transfer_encoding:\n              assert(0 && \"Shouldn't get here.\");\n              break;\n\n            case h_content_length:\n            {\n              uint64_t t;\n\n              if (ch == ' ') break;\n\n              if (UNLIKELY(!IS_NUM(ch))) {\n                SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);\n                parser->header_state = h_state;\n                goto error;\n              }\n\n              t = parser->content_length;\n              t *= 10;\n              t += ch - '0';\n\n              /* Overflow? Test against a conservative limit for simplicity. */\n              if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) {\n                SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);\n                parser->header_state = h_state;\n                goto error;\n              }\n\n              parser->content_length = t;\n              break;\n            }\n\n            /* Transfer-Encoding: chunked */\n            case h_matching_transfer_encoding_chunked:\n              parser->index++;\n              if (parser->index > sizeof(CHUNKED)-1\n                  || c != CHUNKED[parser->index]) {\n                h_state = h_general;\n              } else if (parser->index == sizeof(CHUNKED)-2) {\n                h_state = h_transfer_encoding_chunked;\n              }\n              break;\n\n            case h_matching_connection_token_start:\n              /* looking for 'Connection: keep-alive' */\n              if (c == 'k') {\n                h_state = h_matching_connection_keep_alive;\n              /* looking for 'Connection: close' */\n              } else if (c == 'c') {\n                h_state = h_matching_connection_close;\n              } else if (c == 'u') {\n                h_state = h_matching_connection_upgrade;\n              } else if (STRICT_TOKEN(c)) {\n                h_state = h_matching_connection_token;\n              } else if (c == ' ' || c == '\\t') {\n                /* Skip lws */\n              } else {\n                h_state = h_general;\n              }\n              break;\n\n            /* looking for 'Connection: keep-alive' */\n            case h_matching_connection_keep_alive:\n              parser->index++;\n              if (parser->index > sizeof(KEEP_ALIVE)-1\n                  || c != KEEP_ALIVE[parser->index]) {\n                h_state = h_matching_connection_token;\n              } else if (parser->index == sizeof(KEEP_ALIVE)-2) {\n                h_state = h_connection_keep_alive;\n              }\n              break;\n\n            /* looking for 'Connection: close' */\n            case h_matching_connection_close:\n              parser->index++;\n              if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) {\n                h_state = h_matching_connection_token;\n              } else if (parser->index == sizeof(CLOSE)-2) {\n                h_state = h_connection_close;\n              }\n              break;\n\n            /* looking for 'Connection: upgrade' */\n            case h_matching_connection_upgrade:\n              parser->index++;\n              if (parser->index > sizeof(UPGRADE) - 1 ||\n                  c != UPGRADE[parser->index]) {\n                h_state = h_matching_connection_token;\n              } else if (parser->index == sizeof(UPGRADE)-2) {\n                h_state = h_connection_upgrade;\n              }\n              break;\n\n            case h_matching_connection_token:\n              if (ch == ',') {\n                h_state = h_matching_connection_token_start;\n                parser->index = 0;\n              }\n              break;\n\n            case h_transfer_encoding_chunked:\n              if (ch != ' ') h_state = h_general;\n              break;\n\n            case h_connection_keep_alive:\n            case h_connection_close:\n            case h_connection_upgrade:\n              if (ch == ',') {\n                if (h_state == h_connection_keep_alive) {\n                  parser->flags |= F_CONNECTION_KEEP_ALIVE;\n                } else if (h_state == h_connection_close) {\n                  parser->flags |= F_CONNECTION_CLOSE;\n                } else if (h_state == h_connection_upgrade) {\n                  parser->flags |= F_CONNECTION_UPGRADE;\n                }\n                h_state = h_matching_connection_token_start;\n                parser->index = 0;\n              } else if (ch != ' ') {\n                h_state = h_matching_connection_token;\n              }\n              break;\n\n            default:\n              UPDATE_STATE(s_header_value);\n              h_state = h_general;\n              break;\n          }\n        }\n        parser->header_state = h_state;\n\n        COUNT_HEADER_SIZE(p - start);\n\n        if (p == data + len)\n          --p;\n        break;\n      }\n\n      case s_header_almost_done:\n      {\n        if (UNLIKELY(ch != LF)) {\n          SET_ERRNO(HPE_LF_EXPECTED);\n          goto error;\n        }\n\n        UPDATE_STATE(s_header_value_lws);\n        break;\n      }\n\n      case s_header_value_lws:\n      {\n        if (ch == ' ' || ch == '\\t') {\n          UPDATE_STATE(s_header_value_start);\n          REEXECUTE();\n        }\n\n        /* finished the header */\n        switch (parser->header_state) {\n          case h_connection_keep_alive:\n            parser->flags |= F_CONNECTION_KEEP_ALIVE;\n            break;\n          case h_connection_close:\n            parser->flags |= F_CONNECTION_CLOSE;\n            break;\n          case h_transfer_encoding_chunked:\n            parser->flags |= F_CHUNKED;\n            break;\n          case h_connection_upgrade:\n            parser->flags |= F_CONNECTION_UPGRADE;\n            break;\n          default:\n            break;\n        }\n\n        UPDATE_STATE(s_header_field_start);\n        REEXECUTE();\n      }\n\n      case s_header_value_discard_ws_almost_done:\n      {\n        STRICT_CHECK(ch != LF);\n        UPDATE_STATE(s_header_value_discard_lws);\n        break;\n      }\n\n      case s_header_value_discard_lws:\n      {\n        if (ch == ' ' || ch == '\\t') {\n          UPDATE_STATE(s_header_value_discard_ws);\n          break;\n        } else {\n          switch (parser->header_state) {\n            case h_connection_keep_alive:\n              parser->flags |= F_CONNECTION_KEEP_ALIVE;\n              break;\n            case h_connection_close:\n              parser->flags |= F_CONNECTION_CLOSE;\n              break;\n            case h_connection_upgrade:\n              parser->flags |= F_CONNECTION_UPGRADE;\n              break;\n            case h_transfer_encoding_chunked:\n              parser->flags |= F_CHUNKED;\n              break;\n            default:\n              break;\n          }\n\n          /* header value was empty */\n          MARK(header_value);\n          UPDATE_STATE(s_header_field_start);\n          CALLBACK_DATA_NOADVANCE(header_value);\n          REEXECUTE();\n        }\n      }\n\n      case s_headers_almost_done:\n      {\n        STRICT_CHECK(ch != LF);\n\n        if (parser->flags & F_TRAILING) {\n          /* End of a chunked request */\n          UPDATE_STATE(s_message_done);\n          CALLBACK_NOTIFY_NOADVANCE(chunk_complete);\n          REEXECUTE();\n        }\n\n        /* Cannot use chunked encoding and a content-length header together\n           per the HTTP specification. */\n        if ((parser->flags & F_CHUNKED) &&\n            (parser->flags & F_CONTENTLENGTH)) {\n          SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH);\n          goto error;\n        }\n\n        UPDATE_STATE(s_headers_done);\n\n        /* Set this here so that on_headers_complete() callbacks can see it */\n        parser->upgrade =\n          ((parser->flags & (F_UPGRADE | F_CONNECTION_UPGRADE)) ==\n           (F_UPGRADE | F_CONNECTION_UPGRADE) ||\n           parser->method == HTTP_PARSER_METHOD_CONNECT);\n\n        /* Here we call the headers_complete callback. This is somewhat\n         * different than other callbacks because if the user returns 1, we\n         * will interpret that as saying that this message has no body. This\n         * is needed for the annoying case of recieving a response to a HEAD\n         * request.\n         *\n         * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so\n         * we have to simulate it by handling a change in errno below.\n         */\n        if (settings->on_headers_complete) {\n          switch (settings->on_headers_complete(parser)) {\n            case 0:\n              break;\n\n            case 2:\n              parser->upgrade = 1;\n\n            case 1:\n              parser->flags |= F_SKIPBODY;\n              break;\n\n            default:\n              SET_ERRNO(HPE_CB_headers_complete);\n              RETURN(p - data); /* Error */\n          }\n        }\n\n        if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {\n          RETURN(p - data);\n        }\n\n        REEXECUTE();\n      }\n\n      case s_headers_done:\n      {\n        int hasBody;\n        STRICT_CHECK(ch != LF);\n\n        parser->nread = 0;\n\n        hasBody = parser->flags & F_CHUNKED ||\n          (parser->content_length > 0 && parser->content_length != ULLONG_MAX);\n        if (parser->upgrade && (parser->method == HTTP_PARSER_METHOD_CONNECT ||\n                                (parser->flags & F_SKIPBODY) || !hasBody)) {\n          /* Exit, the rest of the message is in a different protocol. */\n          UPDATE_STATE(NEW_MESSAGE());\n          CALLBACK_NOTIFY(message_complete);\n          RETURN((p - data) + 1);\n        }\n\n        if (parser->flags & F_SKIPBODY) {\n          UPDATE_STATE(NEW_MESSAGE());\n          CALLBACK_NOTIFY(message_complete);\n        } else if (parser->flags & F_CHUNKED) {\n          /* chunked encoding - ignore Content-Length header */\n          UPDATE_STATE(s_chunk_size_start);\n        } else {\n          if (parser->content_length == 0) {\n            /* Content-Length header given but zero: Content-Length: 0\\r\\n */\n            UPDATE_STATE(NEW_MESSAGE());\n            CALLBACK_NOTIFY(message_complete);\n          } else if (parser->content_length != ULLONG_MAX) {\n            /* Content-Length header given and non-zero */\n            UPDATE_STATE(s_body_identity);\n          } else {\n            if (!http_message_needs_eof(parser)) {\n              /* Assume content-length 0 - read the next */\n              UPDATE_STATE(NEW_MESSAGE());\n              CALLBACK_NOTIFY(message_complete);\n            } else {\n              /* Read body until EOF */\n              UPDATE_STATE(s_body_identity_eof);\n            }\n          }\n        }\n\n        break;\n      }\n\n      case s_body_identity:\n      {\n        uint64_t to_read = MIN(parser->content_length,\n                               (uint64_t) ((data + len) - p));\n\n        assert(parser->content_length != 0\n            && parser->content_length != ULLONG_MAX);\n\n        /* The difference between advancing content_length and p is because\n         * the latter will automaticaly advance on the next loop iteration.\n         * Further, if content_length ends up at 0, we want to see the last\n         * byte again for our message complete callback.\n         */\n        MARK(body);\n        parser->content_length -= to_read;\n        p += to_read - 1;\n\n        if (parser->content_length == 0) {\n          UPDATE_STATE(s_message_done);\n\n          /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte.\n           *\n           * The alternative to doing this is to wait for the next byte to\n           * trigger the data callback, just as in every other case. The\n           * problem with this is that this makes it difficult for the test\n           * harness to distinguish between complete-on-EOF and\n           * complete-on-length. It's not clear that this distinction is\n           * important for applications, but let's keep it for now.\n           */\n          CALLBACK_DATA_(body, p - body_mark + 1, p - data);\n          REEXECUTE();\n        }\n\n        break;\n      }\n\n      /* read until EOF */\n      case s_body_identity_eof:\n        MARK(body);\n        p = data + len - 1;\n\n        break;\n\n      case s_message_done:\n        UPDATE_STATE(NEW_MESSAGE());\n        CALLBACK_NOTIFY(message_complete);\n        if (parser->upgrade) {\n          /* Exit, the rest of the message is in a different protocol. */\n          RETURN((p - data) + 1);\n        }\n        break;\n\n      case s_chunk_size_start:\n      {\n        assert(parser->nread == 1);\n        assert(parser->flags & F_CHUNKED);\n\n        unhex_val = unhex[(unsigned char)ch];\n        if (UNLIKELY(unhex_val == -1)) {\n          SET_ERRNO(HPE_INVALID_CHUNK_SIZE);\n          goto error;\n        }\n\n        parser->content_length = unhex_val;\n        UPDATE_STATE(s_chunk_size);\n        break;\n      }\n\n      case s_chunk_size:\n      {\n        uint64_t t;\n\n        assert(parser->flags & F_CHUNKED);\n\n        if (ch == CR) {\n          UPDATE_STATE(s_chunk_size_almost_done);\n          break;\n        }\n\n        unhex_val = unhex[(unsigned char)ch];\n\n        if (unhex_val == -1) {\n          if (ch == ';' || ch == ' ') {\n            UPDATE_STATE(s_chunk_parameters);\n            break;\n          }\n\n          SET_ERRNO(HPE_INVALID_CHUNK_SIZE);\n          goto error;\n        }\n\n        t = parser->content_length;\n        t *= 16;\n        t += unhex_val;\n\n        /* Overflow? Test against a conservative limit for simplicity. */\n        if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) {\n          SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);\n          goto error;\n        }\n\n        parser->content_length = t;\n        break;\n      }\n\n      case s_chunk_parameters:\n      {\n        assert(parser->flags & F_CHUNKED);\n        /* just ignore this shit. TODO check for overflow */\n        if (ch == CR) {\n          UPDATE_STATE(s_chunk_size_almost_done);\n          break;\n        }\n        break;\n      }\n\n      case s_chunk_size_almost_done:\n      {\n        assert(parser->flags & F_CHUNKED);\n        STRICT_CHECK(ch != LF);\n\n        parser->nread = 0;\n\n        if (parser->content_length == 0) {\n          parser->flags |= F_TRAILING;\n          UPDATE_STATE(s_header_field_start);\n        } else {\n          UPDATE_STATE(s_chunk_data);\n        }\n        CALLBACK_NOTIFY(chunk_header);\n        break;\n      }\n\n      case s_chunk_data:\n      {\n        uint64_t to_read = MIN(parser->content_length,\n                               (uint64_t) ((data + len) - p));\n\n        assert(parser->flags & F_CHUNKED);\n        assert(parser->content_length != 0\n            && parser->content_length != ULLONG_MAX);\n\n        /* See the explanation in s_body_identity for why the content\n         * length and data pointers are managed this way.\n         */\n        MARK(body);\n        parser->content_length -= to_read;\n        p += to_read - 1;\n\n        if (parser->content_length == 0) {\n          UPDATE_STATE(s_chunk_data_almost_done);\n        }\n\n        break;\n      }\n\n      case s_chunk_data_almost_done:\n        assert(parser->flags & F_CHUNKED);\n        assert(parser->content_length == 0);\n        STRICT_CHECK(ch != CR);\n        UPDATE_STATE(s_chunk_data_done);\n        CALLBACK_DATA(body);\n        break;\n\n      case s_chunk_data_done:\n        assert(parser->flags & F_CHUNKED);\n        STRICT_CHECK(ch != LF);\n        parser->nread = 0;\n        UPDATE_STATE(s_chunk_size_start);\n        CALLBACK_NOTIFY(chunk_complete);\n        break;\n\n      default:\n        assert(0 && \"unhandled state\");\n        SET_ERRNO(HPE_INVALID_INTERNAL_STATE);\n        goto error;\n    }\n  }\n\n  /* Run callbacks for any marks that we have leftover after we ran our of\n   * bytes. There should be at most one of these set, so it's OK to invoke\n   * them in series (unset marks will not result in callbacks).\n   *\n   * We use the NOADVANCE() variety of callbacks here because 'p' has already\n   * overflowed 'data' and this allows us to correct for the off-by-one that\n   * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p'\n   * value that's in-bounds).\n   */\n\n  assert(((header_field_mark ? 1 : 0) +\n          (header_value_mark ? 1 : 0) +\n          (url_mark ? 1 : 0)  +\n          (body_mark ? 1 : 0) +\n          (status_mark ? 1 : 0)) <= 1);\n\n  CALLBACK_DATA_NOADVANCE(header_field);\n  CALLBACK_DATA_NOADVANCE(header_value);\n  CALLBACK_DATA_NOADVANCE(url);\n  CALLBACK_DATA_NOADVANCE(body);\n  CALLBACK_DATA_NOADVANCE(status);\n\n  RETURN(len);\n\nerror:\n  if (HTTP_PARSER_ERRNO(parser) == HPE_OK) {\n    SET_ERRNO(HPE_UNKNOWN);\n  }\n\n  RETURN(p - data);\n}\n\n\n/* Does the parser need to see an EOF to find the end of the message? */\nint\nhttp_message_needs_eof (const http_parser *parser)\n{\n  if (parser->type == HTTP_REQUEST) {\n    return 0;\n  }\n\n  /* See RFC 2616 section 4.4 */\n  if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */\n      parser->status_code == 204 ||     /* No Content */\n      parser->status_code == 304 ||     /* Not Modified */\n      parser->flags & F_SKIPBODY) {     /* response to a HEAD request */\n    return 0;\n  }\n\n  if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) {\n    return 0;\n  }\n\n  return 1;\n}\n\n\nint\nhttp_should_keep_alive (const http_parser *parser)\n{\n  if (parser->http_major > 0 && parser->http_minor > 0) {\n    /* HTTP/1.1 */\n    if (parser->flags & F_CONNECTION_CLOSE) {\n      return 0;\n    }\n  } else {\n    /* HTTP/1.0 or earlier */\n    if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) {\n      return 0;\n    }\n  }\n\n  return !http_message_needs_eof(parser);\n}\n\n\nconst char *\nhttp_method_str (enum http_method m)\n{\n  return ELEM_AT(method_strings, m, \"<unknown>\");\n}\n\n\nvoid\nhttp_parser_init (http_parser *parser, enum http_parser_type t)\n{\n  void *data = parser->data; /* preserve application data */\n  memset(parser, 0, sizeof(*parser));\n  parser->data = data;\n  parser->type = t;\n  parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res));\n  parser->http_errno = HPE_OK;\n}\n\nvoid\nhttp_parser_settings_init(http_parser_settings *settings)\n{\n  memset(settings, 0, sizeof(*settings));\n}\n\n/*\nconst char *\nhttp_errno_name(enum http_errno err) {\n  assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab));\n  return http_strerror_tab[err].name;\n}\n\nconst char *\nhttp_errno_description(enum http_errno err) {\n  assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab));\n  return http_strerror_tab[err].description;\n}\n*/\n\nstatic enum http_host_state\nhttp_parse_host_char(enum http_host_state s, const char ch) {\n  switch(s) {\n    case s_http_userinfo:\n    case s_http_userinfo_start:\n      if (ch == '@') {\n        return s_http_host_start;\n      }\n\n      if (IS_USERINFO_CHAR(ch)) {\n        return s_http_userinfo;\n      }\n      break;\n\n    case s_http_host_start:\n      if (ch == '[') {\n        return s_http_host_v6_start;\n      }\n\n      if (IS_HOST_CHAR(ch)) {\n        return s_http_host;\n      }\n\n      break;\n\n    case s_http_host:\n      if (IS_HOST_CHAR(ch)) {\n        return s_http_host;\n      }\n\n    /* FALLTHROUGH */\n    case s_http_host_v6_end:\n      if (ch == ':') {\n        return s_http_host_port_start;\n      }\n\n      break;\n\n    case s_http_host_v6:\n      if (ch == ']') {\n        return s_http_host_v6_end;\n      }\n\n    /* FALLTHROUGH */\n    case s_http_host_v6_start:\n      if (IS_HEX(ch) || ch == ':' || ch == '.') {\n        return s_http_host_v6;\n      }\n\n      if (s == s_http_host_v6 && ch == '%') {\n        return s_http_host_v6_zone_start;\n      }\n      break;\n\n    case s_http_host_v6_zone:\n      if (ch == ']') {\n        return s_http_host_v6_end;\n      }\n\n    /* FALLTHROUGH */\n    case s_http_host_v6_zone_start:\n      /* RFC 6874 Zone ID consists of 1*( unreserved / pct-encoded) */\n      if (IS_ALPHANUM(ch) || ch == '%' || ch == '.' || ch == '-' || ch == '_' ||\n          ch == '~') {\n        return s_http_host_v6_zone;\n      }\n      break;\n\n    case s_http_host_port:\n    case s_http_host_port_start:\n      if (IS_NUM(ch)) {\n        return s_http_host_port;\n      }\n\n      break;\n\n    default:\n      break;\n  }\n  return s_http_host_dead;\n}\n\nstatic int\nhttp_parse_host(const char * buf, struct http_parser_url *u, int found_at) {\n  enum http_host_state s;\n\n  const char *p;\n  size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len;\n\n  assert(u->field_set & (1 << UF_HOST));\n\n  u->field_data[UF_HOST].len = 0;\n\n  s = found_at ? s_http_userinfo_start : s_http_host_start;\n\n  for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) {\n    enum http_host_state new_s = http_parse_host_char(s, *p);\n\n    if (new_s == s_http_host_dead) {\n      return 1;\n    }\n\n    switch(new_s) {\n      case s_http_host:\n        if (s != s_http_host) {\n          u->field_data[UF_HOST].off = p - buf;\n        }\n        u->field_data[UF_HOST].len++;\n        break;\n\n      case s_http_host_v6:\n        if (s != s_http_host_v6) {\n          u->field_data[UF_HOST].off = p - buf;\n        }\n        u->field_data[UF_HOST].len++;\n        break;\n\n      case s_http_host_v6_zone_start:\n      case s_http_host_v6_zone:\n        u->field_data[UF_HOST].len++;\n        break;\n\n      case s_http_host_port:\n        if (s != s_http_host_port) {\n          u->field_data[UF_PORT].off = p - buf;\n          u->field_data[UF_PORT].len = 0;\n          u->field_set |= (1 << UF_PORT);\n        }\n        u->field_data[UF_PORT].len++;\n        break;\n\n      case s_http_userinfo:\n        if (s != s_http_userinfo) {\n          u->field_data[UF_USERINFO].off = p - buf ;\n          u->field_data[UF_USERINFO].len = 0;\n          u->field_set |= (1 << UF_USERINFO);\n        }\n        u->field_data[UF_USERINFO].len++;\n        break;\n\n      default:\n        break;\n    }\n    s = new_s;\n  }\n\n  /* Make sure we don't end somewhere unexpected */\n  switch (s) {\n    case s_http_host_start:\n    case s_http_host_v6_start:\n    case s_http_host_v6:\n    case s_http_host_v6_zone_start:\n    case s_http_host_v6_zone:\n    case s_http_host_port_start:\n    case s_http_userinfo:\n    case s_http_userinfo_start:\n      return 1;\n    default:\n      break;\n  }\n\n  return 0;\n}\n\nvoid\nhttp_parser_url_init(struct http_parser_url *u) {\n  memset(u, 0, sizeof(*u));\n}\n\nint\nhttp_parser_parse_url(const char *buf, size_t buflen, int is_connect,\n                      struct http_parser_url *u)\n{\n  enum state s;\n  const char *p;\n  enum http_parser_url_fields uf, old_uf;\n  int found_at = 0;\n\n  u->port = u->field_set = 0;\n  s = is_connect ? s_req_server_start : s_req_spaces_before_url;\n  old_uf = UF_MAX;\n\n  for (p = buf; p < buf + buflen; p++) {\n    s = parse_url_char(s, *p);\n\n    /* Figure out the next field that we're operating on */\n    switch (s) {\n      case s_dead:\n        return 1;\n\n      /* Skip delimeters */\n      case s_req_schema_slash:\n      case s_req_schema_slash_slash:\n      case s_req_server_start:\n      case s_req_query_string_start:\n      case s_req_fragment_start:\n        continue;\n\n      case s_req_schema:\n        uf = UF_SCHEMA;\n        break;\n\n      case s_req_server_with_at:\n        found_at = 1;\n\n      /* FALLTROUGH */\n      case s_req_server:\n        uf = UF_HOST;\n        break;\n\n      case s_req_path:\n        uf = UF_PATH;\n        break;\n\n      case s_req_query_string:\n        uf = UF_QUERY;\n        break;\n\n      case s_req_fragment:\n        uf = UF_FRAGMENT;\n        break;\n\n      default:\n        assert(!\"Unexpected state\");\n        return 1;\n    }\n\n    /* Nothing's changed; soldier on */\n    if (uf == old_uf) {\n      u->field_data[uf].len++;\n      continue;\n    }\n\n    u->field_data[uf].off = p - buf;\n    u->field_data[uf].len = 1;\n\n    u->field_set |= (1 << uf);\n    old_uf = uf;\n  }\n\n  /* host must be present if there is a schema */\n  /* parsing http:///toto will fail */\n  if ((u->field_set & (1 << UF_SCHEMA)) &&\n      (u->field_set & (1 << UF_HOST)) == 0) {\n    return 1;\n  }\n\n  if (u->field_set & (1 << UF_HOST)) {\n    if (http_parse_host(buf, u, found_at) != 0) {\n      return 1;\n    }\n  }\n\n  /* CONNECT requests can only contain \"hostname:port\" */\n  if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) {\n    return 1;\n  }\n\n  if (u->field_set & (1 << UF_PORT)) {\n    /* Don't bother with endp; we've already validated the string */\n    unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10);\n\n    /* Ports have a max value of 2^16 */\n    if (v > 0xffff) {\n      return 1;\n    }\n\n    u->port = (uint16_t) v;\n  }\n\n  return 0;\n}\n\nvoid\nhttp_parser_pause(http_parser *parser, int paused) {\n  /* Users should only be pausing/unpausing a parser that is not in an error\n   * state. In non-debug builds, there's not much that we can do about this\n   * other than ignore it.\n   */\n  if (HTTP_PARSER_ERRNO(parser) == HPE_OK ||\n      HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) {\n    SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK);\n  } else {\n    assert(0 && \"Attempting to pause parser in error state\");\n  }\n}\n\nint\nhttp_body_is_final(const struct http_parser *parser) {\n    return parser->state == s_message_done;\n}\n\nunsigned long\nhttp_parser_version(void) {\n  return HTTP_PARSER_VERSION_MAJOR * 0x10000 |\n         HTTP_PARSER_VERSION_MINOR * 0x00100 |\n         HTTP_PARSER_VERSION_PATCH * 0x00001;\n}\n"
  },
  {
    "path": "src/http_parser.h",
    "content": "/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n// Removed http_errno_name, http_errno_description to save ram\n// (constant strings are loaded in ram on ESP8266)\n// Wang Bin 2020-03-07\n\n#ifndef http_parser_h\n#define http_parser_h\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Also update SONAME in the Makefile whenever you change these. */\n#define HTTP_PARSER_VERSION_MAJOR 2\n#define HTTP_PARSER_VERSION_MINOR 7\n#define HTTP_PARSER_VERSION_PATCH 1\n\n#include <sys/types.h>\n#if defined(_WIN32) && !defined(__MINGW32__) && \\\n  (!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__)\n#include <BaseTsd.h>\n#include <stddef.h>\ntypedef __int8 int8_t;\ntypedef unsigned __int8 uint8_t;\ntypedef __int16 int16_t;\ntypedef unsigned __int16 uint16_t;\ntypedef __int32 int32_t;\ntypedef unsigned __int32 uint32_t;\ntypedef __int64 int64_t;\ntypedef unsigned __int64 uint64_t;\n#else\n#include <stdint.h>\n#endif\n\n/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run\n * faster\n */\n#ifndef HTTP_PARSER_STRICT\n# define HTTP_PARSER_STRICT 1\n#endif\n\n/* Maximium header size allowed. If the macro is not defined\n * before including this header then the default is used. To\n * change the maximum header size, define the macro in the build\n * environment (e.g. -DHTTP_MAX_HEADER_SIZE=<value>). To remove\n * the effective limit on the size of the header, define the macro\n * to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff)\n */\n#ifndef HTTP_MAX_HEADER_SIZE\n# define HTTP_MAX_HEADER_SIZE (80*1024)\n#endif\n\ntypedef struct http_parser http_parser;\ntypedef struct http_parser_settings http_parser_settings;\n\n\n/* Callbacks should return non-zero to indicate an error. The parser will\n * then halt execution.\n *\n * The one exception is on_headers_complete. In a HTTP_RESPONSE parser\n * returning '1' from on_headers_complete will tell the parser that it\n * should not expect a body. This is used when receiving a response to a\n * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:\n * chunked' headers that indicate the presence of a body.\n *\n * Returning `2` from on_headers_complete will tell parser that it should not\n * expect neither a body nor any futher responses on this connection. This is\n * useful for handling responses to a CONNECT request which may not contain\n * `Upgrade` or `Connection: upgrade` headers.\n *\n * http_data_cb does not return data chunks. It will be called arbitrarily\n * many times for each string. E.G. you might get 10 callbacks for \"on_url\"\n * each providing just a few characters more data.\n */\ntypedef int (*http_data_cb) (http_parser*, const char *at, size_t length);\ntypedef int (*http_cb) (http_parser*);\n\n\n/* Status Codes */\n#define HTTP_STATUS_MAP(XX)                                                 \\\n  XX(100, CONTINUE,                        Continue)                        \\\n  XX(101, SWITCHING_PROTOCOLS,             Switching Protocols)             \\\n  XX(102, PROCESSING,                      Processing)                      \\\n  XX(200, OK,                              OK)                              \\\n  XX(201, CREATED,                         Created)                         \\\n  XX(202, ACCEPTED,                        Accepted)                        \\\n  XX(203, NON_AUTHORITATIVE_INFORMATION,   Non-Authoritative Information)   \\\n  XX(204, NO_CONTENT,                      No Content)                      \\\n  XX(205, RESET_CONTENT,                   Reset Content)                   \\\n  XX(206, PARTIAL_CONTENT,                 Partial Content)                 \\\n  XX(207, MULTI_STATUS,                    Multi-Status)                    \\\n  XX(208, ALREADY_REPORTED,                Already Reported)                \\\n  XX(226, IM_USED,                         IM Used)                         \\\n  XX(300, MULTIPLE_CHOICES,                Multiple Choices)                \\\n  XX(301, MOVED_PERMANENTLY,               Moved Permanently)               \\\n  XX(302, FOUND,                           Found)                           \\\n  XX(303, SEE_OTHER,                       See Other)                       \\\n  XX(304, NOT_MODIFIED,                    Not Modified)                    \\\n  XX(305, USE_PROXY,                       Use Proxy)                       \\\n  XX(307, TEMPORARY_REDIRECT,              Temporary Redirect)              \\\n  XX(308, PERMANENT_REDIRECT,              Permanent Redirect)              \\\n  XX(400, BAD_REQUEST,                     Bad Request)                     \\\n  XX(401, UNAUTHORIZED,                    Unauthorized)                    \\\n  XX(402, PAYMENT_REQUIRED,                Payment Required)                \\\n  XX(403, FORBIDDEN,                       Forbidden)                       \\\n  XX(404, NOT_FOUND,                       Not Found)                       \\\n  XX(405, METHOD_NOT_ALLOWED,              Method Not Allowed)              \\\n  XX(406, NOT_ACCEPTABLE,                  Not Acceptable)                  \\\n  XX(407, PROXY_AUTHENTICATION_REQUIRED,   Proxy Authentication Required)   \\\n  XX(408, REQUEST_TIMEOUT,                 Request Timeout)                 \\\n  XX(409, CONFLICT,                        Conflict)                        \\\n  XX(410, GONE,                            Gone)                            \\\n  XX(411, LENGTH_REQUIRED,                 Length Required)                 \\\n  XX(412, PRECONDITION_FAILED,             Precondition Failed)             \\\n  XX(413, PAYLOAD_TOO_LARGE,               Payload Too Large)               \\\n  XX(414, URI_TOO_LONG,                    URI Too Long)                    \\\n  XX(415, UNSUPPORTED_MEDIA_TYPE,          Unsupported Media Type)          \\\n  XX(416, RANGE_NOT_SATISFIABLE,           Range Not Satisfiable)           \\\n  XX(417, EXPECTATION_FAILED,              Expectation Failed)              \\\n  XX(421, MISDIRECTED_REQUEST,             Misdirected Request)             \\\n  XX(422, UNPROCESSABLE_ENTITY,            Unprocessable Entity)            \\\n  XX(423, LOCKED,                          Locked)                          \\\n  XX(424, FAILED_DEPENDENCY,               Failed Dependency)               \\\n  XX(426, UPGRADE_REQUIRED,                Upgrade Required)                \\\n  XX(428, PRECONDITION_REQUIRED,           Precondition Required)           \\\n  XX(429, TOO_MANY_REQUESTS,               Too Many Requests)               \\\n  XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \\\n  XX(451, UNAVAILABLE_FOR_LEGAL_REASONS,   Unavailable For Legal Reasons)   \\\n  XX(500, INTERNAL_SERVER_ERROR,           Internal Server Error)           \\\n  XX(501, NOT_IMPLEMENTED,                 Not Implemented)                 \\\n  XX(502, BAD_GATEWAY,                     Bad Gateway)                     \\\n  XX(503, SERVICE_UNAVAILABLE,             Service Unavailable)             \\\n  XX(504, GATEWAY_TIMEOUT,                 Gateway Timeout)                 \\\n  XX(505, HTTP_VERSION_NOT_SUPPORTED,      HTTP Version Not Supported)      \\\n  XX(506, VARIANT_ALSO_NEGOTIATES,         Variant Also Negotiates)         \\\n  XX(507, INSUFFICIENT_STORAGE,            Insufficient Storage)            \\\n  XX(508, LOOP_DETECTED,                   Loop Detected)                   \\\n  XX(510, NOT_EXTENDED,                    Not Extended)                    \\\n  XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \\\n\nenum http_status\n  {\n#define XX(num, name, string) HTTP_STATUS_##name = num,\n  HTTP_STATUS_MAP(XX)\n#undef XX\n  };\n\n\n/* Request Methods */\n#define HTTP_METHOD_MAP(XX)         \\\n  XX(0,  DELETE,      DELETE)       \\\n  XX(1,  GET,         GET)          \\\n  XX(2,  HEAD,        HEAD)         \\\n  XX(3,  POST,        POST)         \\\n  XX(4,  PUT,         PUT)          \\\n  /* pathological */                \\\n  XX(5,  CONNECT,     CONNECT)      \\\n  XX(6,  OPTIONS,     OPTIONS)      \\\n  XX(7,  TRACE,       TRACE)        \\\n  /* WebDAV */                      \\\n  XX(8,  COPY,        COPY)         \\\n  XX(9,  LOCK,        LOCK)         \\\n  XX(10, MKCOL,       MKCOL)        \\\n  XX(11, MOVE,        MOVE)         \\\n  XX(12, PROPFIND,    PROPFIND)     \\\n  XX(13, PROPPATCH,   PROPPATCH)    \\\n  XX(14, SEARCH,      SEARCH)       \\\n  XX(15, UNLOCK,      UNLOCK)       \\\n  XX(16, BIND,        BIND)         \\\n  XX(17, REBIND,      REBIND)       \\\n  XX(18, UNBIND,      UNBIND)       \\\n  XX(19, ACL,         ACL)          \\\n  /* subversion */                  \\\n  XX(20, REPORT,      REPORT)       \\\n  XX(21, MKACTIVITY,  MKACTIVITY)   \\\n  XX(22, CHECKOUT,    CHECKOUT)     \\\n  XX(23, MERGE,       MERGE)        \\\n  /* upnp */                        \\\n  XX(24, MSEARCH,     M-SEARCH)     \\\n  XX(25, NOTIFY,      NOTIFY)       \\\n  XX(26, SUBSCRIBE,   SUBSCRIBE)    \\\n  XX(27, UNSUBSCRIBE, UNSUBSCRIBE)  \\\n  /* RFC-5789 */                    \\\n  XX(28, PATCH,       PATCH)        \\\n  XX(29, PURGE,       PURGE)        \\\n  /* CalDAV */                      \\\n  XX(30, MKCALENDAR,  MKCALENDAR)   \\\n  /* RFC-2068, section 19.6.1.2 */  \\\n  XX(31, LINK,        LINK)         \\\n  XX(32, UNLINK,      UNLINK)       \\\n\nenum http_method\n  {\n// For compat with ESP8266WebServer\n//(HTTP_POST / HTTP_GET is defined in ESP8266WebServer\n//#define XX(num, name, string) HTTP_##name = num,\n\t//replace \"HTTP_*\" to \"HTTP_PARSER_METHOD_*\"\n#define XX(num, name, string) HTTP_PARSER_METHOD_##name = num,\n  HTTP_METHOD_MAP(XX)\n#undef XX\n  };\n\n\nenum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };\n\n\n/* Flag values for http_parser.flags field */\nenum flags\n  { F_CHUNKED               = 1 << 0\n  , F_CONNECTION_KEEP_ALIVE = 1 << 1\n  , F_CONNECTION_CLOSE      = 1 << 2\n  , F_CONNECTION_UPGRADE    = 1 << 3\n  , F_TRAILING              = 1 << 4\n  , F_UPGRADE               = 1 << 5\n  , F_SKIPBODY              = 1 << 6\n  , F_CONTENTLENGTH         = 1 << 7\n  };\n\n\n/* Map for errno-related constants\n *\n * The provided argument should be a macro that takes 2 arguments.\n */\n#define HTTP_ERRNO_MAP(XX)                                           \\\n  /* No error */                                                     \\\n  XX(OK, \"success\")                                                  \\\n                                                                     \\\n  /* Callback-related errors */                                      \\\n  XX(CB_message_begin, \"the on_message_begin callback failed\")       \\\n  XX(CB_url, \"the on_url callback failed\")                           \\\n  XX(CB_header_field, \"the on_header_field callback failed\")         \\\n  XX(CB_header_value, \"the on_header_value callback failed\")         \\\n  XX(CB_headers_complete, \"the on_headers_complete callback failed\") \\\n  XX(CB_body, \"the on_body callback failed\")                         \\\n  XX(CB_message_complete, \"the on_message_complete callback failed\") \\\n  XX(CB_status, \"the on_status callback failed\")                     \\\n  XX(CB_chunk_header, \"the on_chunk_header callback failed\")         \\\n  XX(CB_chunk_complete, \"the on_chunk_complete callback failed\")     \\\n                                                                     \\\n  /* Parsing-related errors */                                       \\\n  XX(INVALID_EOF_STATE, \"stream ended at an unexpected time\")        \\\n  XX(HEADER_OVERFLOW,                                                \\\n     \"too many header bytes seen; overflow detected\")                \\\n  XX(CLOSED_CONNECTION,                                              \\\n     \"data received after completed connection: close message\")      \\\n  XX(INVALID_VERSION, \"invalid HTTP version\")                        \\\n  XX(INVALID_STATUS, \"invalid HTTP status code\")                     \\\n  XX(INVALID_METHOD, \"invalid HTTP method\")                          \\\n  XX(INVALID_URL, \"invalid URL\")                                     \\\n  XX(INVALID_HOST, \"invalid host\")                                   \\\n  XX(INVALID_PORT, \"invalid port\")                                   \\\n  XX(INVALID_PATH, \"invalid path\")                                   \\\n  XX(INVALID_QUERY_STRING, \"invalid query string\")                   \\\n  XX(INVALID_FRAGMENT, \"invalid fragment\")                           \\\n  XX(LF_EXPECTED, \"LF character expected\")                           \\\n  XX(INVALID_HEADER_TOKEN, \"invalid character in header\")            \\\n  XX(INVALID_CONTENT_LENGTH,                                         \\\n     \"invalid character in content-length header\")                   \\\n  XX(UNEXPECTED_CONTENT_LENGTH,                                      \\\n     \"unexpected content-length header\")                             \\\n  XX(INVALID_CHUNK_SIZE,                                             \\\n     \"invalid character in chunk size header\")                       \\\n  XX(INVALID_CONSTANT, \"invalid constant string\")                    \\\n  XX(INVALID_INTERNAL_STATE, \"encountered unexpected internal state\")\\\n  XX(STRICT, \"strict mode assertion failed\")                         \\\n  XX(PAUSED, \"parser is paused\")                                     \\\n  XX(UNKNOWN, \"an unknown error occurred\")\n\n\n/* Define HPE_* values for each errno value above */\n#define HTTP_ERRNO_GEN(n, s) HPE_##n,\nenum http_errno {\n  HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)\n};\n#undef HTTP_ERRNO_GEN\n\n\n/* Get an http_errno value from an http_parser */\n#define HTTP_PARSER_ERRNO(p)            ((enum http_errno) (p)->http_errno)\n\n\nstruct http_parser {\n  /** PRIVATE **/\n  unsigned int type : 2;         /* enum http_parser_type */\n  unsigned int flags : 8;        /* F_* values from 'flags' enum; semi-public */\n  unsigned int state : 7;        /* enum state from http_parser.c */\n  unsigned int header_state : 7; /* enum header_state from http_parser.c */\n  unsigned int index : 7;        /* index into current matcher */\n  unsigned int lenient_http_headers : 1;\n\n  uint32_t nread;          /* # bytes read in various scenarios */\n  uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */\n\n  /** READ-ONLY **/\n  unsigned short http_major;\n  unsigned short http_minor;\n  unsigned int status_code : 16; /* responses only */\n  unsigned int method : 8;       /* requests only */\n  unsigned int http_errno : 7;\n\n  /* 1 = Upgrade header was present and the parser has exited because of that.\n   * 0 = No upgrade header present.\n   * Should be checked when http_parser_execute() returns in addition to\n   * error checking.\n   */\n  unsigned int upgrade : 1;\n\n  /** PUBLIC **/\n  void *data; /* A pointer to get hook to the \"connection\" or \"socket\" object */\n};\n\n\nstruct http_parser_settings {\n  http_cb      on_message_begin;\n  http_data_cb on_url;\n  http_data_cb on_status;\n  http_data_cb on_header_field;\n  http_data_cb on_header_value;\n  http_cb      on_headers_complete;\n  http_data_cb on_body;\n  http_cb      on_message_complete;\n  /* When on_chunk_header is called, the current chunk length is stored\n   * in parser->content_length.\n   */\n  http_cb      on_chunk_header;\n  http_cb      on_chunk_complete;\n};\n\n\nenum http_parser_url_fields\n  { UF_SCHEMA           = 0\n  , UF_HOST             = 1\n  , UF_PORT             = 2\n  , UF_PATH             = 3\n  , UF_QUERY            = 4\n  , UF_FRAGMENT         = 5\n  , UF_USERINFO         = 6\n  , UF_MAX              = 7\n  };\n\n\n/* Result structure for http_parser_parse_url().\n *\n * Callers should index into field_data[] with UF_* values iff field_set\n * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and\n * because we probably have padding left over), we convert any port to\n * a uint16_t.\n */\nstruct http_parser_url {\n  uint16_t field_set;           /* Bitmask of (1 << UF_*) values */\n  uint16_t port;                /* Converted UF_PORT string */\n\n  struct {\n    uint16_t off;               /* Offset into buffer in which field starts */\n    uint16_t len;               /* Length of run in buffer */\n  } field_data[UF_MAX];\n};\n\n\n/* Returns the library version. Bits 16-23 contain the major version number,\n * bits 8-15 the minor version number and bits 0-7 the patch level.\n * Usage example:\n *\n *   unsigned long version = http_parser_version();\n *   unsigned major = (version >> 16) & 255;\n *   unsigned minor = (version >> 8) & 255;\n *   unsigned patch = version & 255;\n *   printf(\"http_parser v%u.%u.%u\\n\", major, minor, patch);\n */\nunsigned long http_parser_version(void);\n\nvoid http_parser_init(http_parser *parser, enum http_parser_type type);\n\n\n/* Initialize http_parser_settings members to 0\n */\nvoid http_parser_settings_init(http_parser_settings *settings);\n\n\n/* Executes the parser. Returns number of parsed bytes. Sets\n * `parser->http_errno` on error. */\nsize_t http_parser_execute(http_parser *parser,\n                           const http_parser_settings *settings,\n                           const char *data,\n                           size_t len);\n\n\n/* If http_should_keep_alive() in the on_headers_complete or\n * on_message_complete callback returns 0, then this should be\n * the last message on the connection.\n * If you are the server, respond with the \"Connection: close\" header.\n * If you are the client, close the connection.\n */\nint http_should_keep_alive(const http_parser *parser);\n\n/* Returns a string version of the HTTP method. */\nconst char *http_method_str(enum http_method m);\n\n/* Return a string name of the given error */\n//const char *http_errno_name(enum http_errno err);\n\n/* Return a string description of the given error */\n//const char *http_errno_description(enum http_errno err);\n\n/* Initialize all http_parser_url members to 0 */\nvoid http_parser_url_init(struct http_parser_url *u);\n\n/* Parse a URL; return nonzero on failure */\nint http_parser_parse_url(const char *buf, size_t buflen,\n                          int is_connect,\n                          struct http_parser_url *u);\n\n/* Pause or un-pause the parser; a nonzero value pauses */\nvoid http_parser_pause(http_parser *parser, int paused);\n\n/* Checks if this is the final chunk of the body. */\nint http_body_is_final(const http_parser *parser);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "src/json.c",
    "content": "#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdarg.h>\n#include \"json.h\"\n\n#include \"homekit_debug.h\"\n\n#define JSON_MAX_DEPTH 30\n#define MAX(a, b) (((a) > (b)) ? (a) : (b))\n\n#define DEBUG_STATE(json) \\\n    DEBUG(\"State = %d, last JSON output: %s\", \\\n          json->state, json->buffer + MAX(0, (long int)json->pos - 20));\n\ntypedef enum {\n    JSON_STATE_START = 1,\n    JSON_STATE_END,\n    JSON_STATE_OBJECT,\n    JSON_STATE_OBJECT_KEY,\n    JSON_STATE_OBJECT_VALUE,\n    JSON_STATE_ARRAY,\n    JSON_STATE_ARRAY_ITEM,\n    JSON_STATE_ERROR,\n} json_state;\n\ntypedef enum {\n    JSON_NESTING_OBJECT,\n    JSON_NESTING_ARRAY,\n} json_nesting;\n\nstruct json_stream {\n    uint8_t *buffer;\n    size_t size;\n    size_t pos;\n\n    json_state state;\n\n    uint8_t nesting_idx;\n    json_nesting nesting[JSON_MAX_DEPTH];\n\n    json_flush_callback on_flush;\n    void *context;\n};\n\n\njson_stream *json_new(size_t buffer_size, json_flush_callback on_flush, void *context) {\n    json_stream *json = malloc(sizeof(json_stream));\n    json->size = buffer_size;\n    json->pos = 0;\n    json->buffer = malloc(json->size);\n    json->state = JSON_STATE_START;\n    json->nesting_idx = 0;\n    json->on_flush = on_flush;\n    json->context = context;\n\n    return json;\n}\n\nvoid json_free(json_stream *json) {\n    free(json->buffer);\n    free(json);\n}\n\nvoid json_flush(json_stream *json) {\n    if (!json->pos)\n        return;\n\n    if (json->on_flush)\n        json->on_flush(json->buffer, json->pos, json->context);\n    json->pos = 0;\n}\n\nvoid json_write(json_stream *json, const char *format, ...) {\n    va_list arg_ptr;\n\n    va_start(arg_ptr, format);\n    int len = vsnprintf((char *)json->buffer + json->pos, json->size - json->pos, format, arg_ptr);\n    va_end(arg_ptr);\n\n    if (len + json->pos > json->size - 1) {\n        json_flush(json);\n\n        va_start(arg_ptr, format);\n        int len = vsnprintf((char *)json->buffer + json->pos, json->size - json->pos, format, arg_ptr);\n        va_end(arg_ptr);\n\n        if (len > json->size - 1) {\n            ERROR(\"Write value too large\");\n            DEBUG(\"Format = %s\", format);\n        } else {\n            json->pos += len;\n        }\n    } else {\n        json->pos += len;\n    }\n}\n\nvoid json_object_start(json_stream *json) {\n    if (json->state == JSON_STATE_ERROR)\n        return;\n\n    switch (json->state) {\n        case JSON_STATE_ARRAY_ITEM:\n            json_write(json, \",\");\n        case JSON_STATE_START:\n        case JSON_STATE_OBJECT_KEY:\n        case JSON_STATE_ARRAY:\n            json_write(json, \"{\");\n\n            json->state = JSON_STATE_OBJECT;\n            json->nesting[json->nesting_idx++] = JSON_NESTING_OBJECT;\n            break;\n        default:\n            ERROR(\"Unexpected object start\");\n            DEBUG_STATE(json);\n            json->state = JSON_STATE_ERROR;\n    }\n}\n\nvoid json_object_end(json_stream *json) {\n    if (json->state == JSON_STATE_ERROR)\n        return;\n\n    switch (json->state) {\n        case JSON_STATE_OBJECT:\n        case JSON_STATE_OBJECT_VALUE:\n            json_write(json, \"}\");\n\n            json->nesting_idx--;\n            if (!json->nesting_idx) {\n                json->state = JSON_STATE_END;\n            } else {\n                switch (json->nesting[json->nesting_idx-1]) {\n                    case JSON_NESTING_OBJECT:\n                        json->state = JSON_STATE_OBJECT_VALUE;\n                        break;\n                    case JSON_NESTING_ARRAY:\n                        json->state = JSON_STATE_ARRAY_ITEM;\n                        break;\n                }\n            }\n            break;\n        default:\n            ERROR(\"Unexpected object end\");\n            DEBUG_STATE(json);\n            json->state = JSON_STATE_ERROR;\n    }\n}\n\nvoid json_array_start(json_stream *json) {\n    if (json->state == JSON_STATE_ERROR)\n        return;\n\n    switch (json->state) {\n        case JSON_STATE_ARRAY_ITEM:\n            json_write(json, \",\");\n        case JSON_STATE_START:\n        case JSON_STATE_OBJECT_KEY:\n        case JSON_STATE_ARRAY:\n            json_write(json, \"[\");\n\n            json->state = JSON_STATE_ARRAY;\n            json->nesting[json->nesting_idx++] = JSON_NESTING_ARRAY;\n            break;\n        default:\n            ERROR(\"Unexpected array start\");\n            DEBUG_STATE(json);\n            json->state = JSON_STATE_ERROR;\n    }\n}\n\nvoid json_array_end(json_stream *json) {\n    if (json->state == JSON_STATE_ERROR)\n        return;\n\n    switch (json->state) {\n        case JSON_STATE_ARRAY:\n        case JSON_STATE_ARRAY_ITEM:\n            json_write(json, \"]\");\n\n            json->nesting_idx--;\n            if (!json->nesting_idx) {\n                json->state = JSON_STATE_END;\n            } else {\n                switch (json->nesting[json->nesting_idx-1]) {\n                    case JSON_NESTING_OBJECT:\n                        json->state = JSON_STATE_OBJECT_VALUE;\n                        break;\n                    case JSON_NESTING_ARRAY:\n                        json->state = JSON_STATE_ARRAY_ITEM;\n                        break;\n                }\n            }\n            break;\n        default:\n            ERROR(\"Unexpected array end\");\n            DEBUG_STATE(json);\n            json->state = JSON_STATE_ERROR;\n    }\n}\n\nvoid _json_number(json_stream *json, char *value) {\n    if (json->state == JSON_STATE_ERROR)\n        return;\n\n    void _do_write() {\n        json_write(json, value);\n    }\n\n    switch (json->state) {\n        case JSON_STATE_START:\n            _do_write();\n            json->state = JSON_STATE_END;\n            break;\n        case JSON_STATE_ARRAY_ITEM:\n            json_write(json, \",\");\n        case JSON_STATE_ARRAY:\n            _do_write();\n            json->state = JSON_STATE_ARRAY_ITEM;\n            break;\n        case JSON_STATE_OBJECT_KEY:\n            _do_write();\n            json->state = JSON_STATE_OBJECT_VALUE;\n            break;\n        default:\n            ERROR(\"Unexpected integer\");\n            DEBUG_STATE(json);\n            json->state = JSON_STATE_ERROR;\n    }\n}\n\n\nvoid json_uint8(json_stream *json, uint8_t x) {\n    char buffer[4];\n    snprintf(buffer, sizeof(buffer), \"%u\", x);\n\n    _json_number(json, buffer);\n}\n\nvoid json_uint16(json_stream *json, uint16_t x) {\n    char buffer[6];\n    snprintf(buffer, sizeof(buffer), \"%u\", x);\n\n    _json_number(json, buffer);\n}\n\nvoid json_uint32(json_stream *json, uint32_t x) {\n    char buffer[11];\n    snprintf(buffer, sizeof(buffer), \"%u\", x);\n\n    _json_number(json, buffer);\n}\n\nvoid json_uint64(json_stream *json, uint64_t x) {\n    char buffer[21];\n    buffer[20] = 0;\n\n    char *b = &buffer[20];\n    do {\n        *(--b) = '0' + (x % 10);\n    } while (x /= 10);\n\n    _json_number(json, b);\n}\n\nvoid json_integer(json_stream *json, int x) {\n    char buffer[7];\n    snprintf(buffer, sizeof(buffer), \"%d\", x);\n\n    _json_number(json, buffer);\n}\n\nvoid json_float(json_stream *json, float x) {\n    char buffer[32];\n    snprintf(buffer, sizeof(buffer), \"%1.15g\", x);\n\n    _json_number(json, buffer);\n}\n\nvoid json_string(json_stream *json, const char *x) {\n    if (json->state == JSON_STATE_ERROR)\n        return;\n\n    void _do_write() {\n        // TODO: escape string\n        json_write(json, \"\\\"%s\\\"\", x);\n    }\n\n    switch (json->state) {\n        case JSON_STATE_START:\n            _do_write();\n            json->state = JSON_STATE_END;\n            break;\n        case JSON_STATE_ARRAY_ITEM:\n            json_write(json, \",\");\n        case JSON_STATE_ARRAY:\n            _do_write();\n            json->state = JSON_STATE_ARRAY_ITEM;\n            break;\n        case JSON_STATE_OBJECT_VALUE:\n            json_write(json, \",\");\n        case JSON_STATE_OBJECT:\n            _do_write();\n            json_write(json, \":\");\n            json->state = JSON_STATE_OBJECT_KEY;\n            break;\n        case JSON_STATE_OBJECT_KEY:\n            _do_write();\n            json->state = JSON_STATE_OBJECT_VALUE;\n            break;\n        default:\n            ERROR(\"Unexpected string\");\n            DEBUG_STATE(json);\n            json->state = JSON_STATE_ERROR;\n    }\n}\n\nvoid json_boolean(json_stream *json, bool x) {\n    if (json->state == JSON_STATE_ERROR)\n        return;\n\n    void _do_write() {\n        json_write(json, (x) ? \"true\" : \"false\");\n    }\n\n    switch (json->state) {\n        case JSON_STATE_START:\n            _do_write();\n            json->state = JSON_STATE_END;\n            break;\n        case JSON_STATE_ARRAY_ITEM:\n            json_write(json, \",\");\n        case JSON_STATE_ARRAY:\n            _do_write();\n            json->state = JSON_STATE_ARRAY_ITEM;\n            break;\n        case JSON_STATE_OBJECT_KEY:\n            _do_write();\n            json->state = JSON_STATE_OBJECT_VALUE;\n            break;\n        default:\n            ERROR(\"Unexpected boolean\");\n            DEBUG_STATE(json);\n            json->state = JSON_STATE_ERROR;\n    }\n}\n\nvoid json_null(json_stream *json) {\n    if (json->state == JSON_STATE_ERROR)\n        return;\n\n    void _do_write() {\n        json_write(json, \"null\");\n    }\n\n    switch (json->state) {\n        case JSON_STATE_START:\n            _do_write();\n            json->state = JSON_STATE_END;\n            break;\n        case JSON_STATE_ARRAY_ITEM:\n            json_write(json, \",\");\n        case JSON_STATE_ARRAY:\n            _do_write();\n            json->state = JSON_STATE_ARRAY_ITEM;\n            break;\n        case JSON_STATE_OBJECT_KEY:\n            _do_write();\n            json->state = JSON_STATE_OBJECT_VALUE;\n            break;\n        default:\n            ERROR(\"Unexpected null\");\n            DEBUG_STATE(json);\n            json->state = JSON_STATE_ERROR;\n    }\n}\n\n"
  },
  {
    "path": "src/json.h",
    "content": "#pragma once\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdbool.h>\n\nstruct json_stream;\ntypedef struct json_stream json_stream;\n\ntypedef void (*json_flush_callback)(uint8_t *buffer, size_t size, void *context);\n\njson_stream *json_new(size_t buffer_size, json_flush_callback on_flush, void *context);\nvoid json_free(json_stream *json);\n\nvoid json_flush(json_stream *json);\n\nvoid json_object_start(json_stream *json);\nvoid json_object_end(json_stream *json);\n\nvoid json_array_start(json_stream *json);\nvoid json_array_end(json_stream *json);\n\nvoid json_integer(json_stream *json, int x);\nvoid json_uint8(json_stream *json, uint8_t x);\nvoid json_uint16(json_stream *json, uint16_t x);\nvoid json_uint32(json_stream *json, uint32_t x);\nvoid json_uint64(json_stream *json, uint64_t x);\nvoid json_float(json_stream *json, float x);\nvoid json_string(json_stream *json, const char *x);\nvoid json_boolean(json_stream *json, bool x);\nvoid json_null(json_stream *json);\n\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "src/pairing.h",
    "content": "#ifndef __PAIRING_H__\n#define __PAIRING_H__\n\n#include \"constants.h\"\n#include \"crypto.h\"\n\n\ntypedef enum {\n    pairing_permissions_admin = (1 << 0),\n} pairing_permissions_t;\n\ntypedef struct {\n    int id;\n    char device_id[DEVICE_ID_SIZE + 1];\n    ed25519_key device_key;\n    pairing_permissions_t permissions;\n} pairing_t;\n\n#endif // __PAIRING_H__\n"
  },
  {
    "path": "src/port.c",
    "content": "#include <stdarg.h>\n#include \"port.h\"\n\n#ifdef ESP_OPEN_RTOS\n\n#include <string.h>\n#include <esp/hwrand.h>\n#include <espressif/esp_common.h>\n#include <esplibs/libmain.h>\n#include \"mdnsresponder.h\"\n\n#ifndef MDNS_TTL\n#define MDNS_TTL 4500\n#endif\n\nuint32_t homekit_random() {\n    return hwrand();\n}\n\nvoid homekit_random_fill(uint8_t *data, size_t size) {\n    hwrand_fill(data, size);\n}\n\nvoid homekit_system_restart() {\n    sdk_system_restart();\n}\n\nvoid homekit_overclock_start() {\n    sdk_system_overclock();\n}\n\nvoid homekit_overclock_end() {\n    sdk_system_restoreclock();\n}\n\nstatic char mdns_instance_name[65] = {0};\nstatic char mdns_txt_rec[128] = {0};\nstatic int mdns_port = 80;\n\nvoid homekit_mdns_init() {\n    mdns_init();\n}\n\nvoid homekit_mdns_configure_init(const char *instance_name, int port) {\n    strncpy(mdns_instance_name, instance_name, sizeof(mdns_instance_name));\n    mdns_txt_rec[0] = 0;\n    mdns_port = port;\n}\n\nvoid homekit_mdns_add_txt(const char *key, const char *format, ...) {\n    va_list arg_ptr;\n    va_start(arg_ptr, format);\n\n    char value[128];\n    int value_len = vsnprintf(value, sizeof(value), format, arg_ptr);\n\n    va_end(arg_ptr);\n\n    if (value_len && value_len < sizeof(value)-1) {\n        char buffer[128];\n        int buffer_len = snprintf(buffer, sizeof(buffer), \"%s=%s\", key, value);\n\n        if (buffer_len < sizeof(buffer)-1)\n            mdns_TXT_append(mdns_txt_rec, sizeof(mdns_txt_rec), buffer, buffer_len);\n    }\n}\n\nvoid homekit_mdns_configure_finalize() {\n    mdns_clear();\n    mdns_add_facility(mdns_instance_name, \"_hap\", mdns_txt_rec, mdns_TCP, mdns_port, MDNS_TTL);\n\n    printf(\"mDNS announcement: Name=%s %s Port=%d TTL=%d\\n\",\n           mdns_instance_name, mdns_txt_rec, mdns_port, MDNS_TTL);\n}\n\n#endif\n\n//#ifdef ESP_IDF\n\n#ifdef ARDUINO_ARCH_ESP8266\n\n#include <string.h>\n#include <stdint.h>\n\nuint32_t homekit_random() {\n\treturn os_random();\n//    return esp_random();\n}\n\nvoid homekit_random_fill(uint8_t *data, size_t size) {\n//    uint32_t x;\n//    for (int i=0; i<size; i+=sizeof(x)) {\n//        x = rand();//esp_random();\n//        memcpy(data+i, &x, (size-i >= sizeof(x)) ? sizeof(x) : size-i);\n//    }\n\tos_get_random(data, size);\n}\n\nvoid homekit_system_restart() {\n\tsystem_restart();\n}\n\nvoid homekit_overclock_start() {\n\t//ets_update_cpu_frequency(ticks_per_us);\n}\n\nvoid homekit_overclock_end() {\n\t//ets_update_cpu_frequency(ticks_per_us);\n}\n/*\nvoid homekit_mdns_init() {\n    mdns_init();\n}\n\nvoid homekit_mdns_configure_init(const char *instance_name, int port) {\n    mdns_hostname_set(instance_name);\n    mdns_instance_name_set(instance_name);\n    mdns_service_add(instance_name, \"_hap\", \"_tcp\", port, NULL, 0);\n}\n\nvoid homekit_mdns_add_txt(const char *key, const char *format, ...) {\n    va_list arg_ptr;\n    va_start(arg_ptr, format);\n\n    char value[128];\n    int value_len = vsnprintf(value, sizeof(value), format, arg_ptr);\n\n    va_end(arg_ptr);\n\n    if (value_len && value_len < sizeof(value)-1) {\n        mdns_service_txt_item_set(\"_hap\", \"_tcp\", key, value);\n    }\n}\n\nvoid homekit_mdns_configure_finalize() {\n    printf(\"mDNS announcement: Name=%s %s Port=%d TTL=%d\\n\",\n           name->value.string_value, txt_rec, PORT, 0);\n\n//}*/\n\n#endif\n\n\n#ifdef ARDUINO_ARCH_ESP32\n\n#include <string.h>\n#include <stdint.h>\n#include <esp_system.h>\n\nuint32_t homekit_random() {\n    return esp_random();\n}\n\nvoid homekit_random_fill(uint8_t *data, size_t size) {\n//    uint32_t x;\n//    for (int i=0; i<size; i+=sizeof(x)) {\n//        x = rand();//esp_random();\n//        memcpy(data+i, &x, (size-i >= sizeof(x)) ? sizeof(x) : size-i);\n//    }\n\tesp_fill_random(data, size);\n}\n\nvoid homekit_system_restart() {\n\tesp_restart();\n}\n\nvoid homekit_overclock_start() {\n\t//ets_update_cpu_frequency(ticks_per_us);\n}\n\nvoid homekit_overclock_end() {\n\t//ets_update_cpu_frequency(ticks_per_us);\n}\n\nstatic uint8_t *_data = NULL;\nstatic nvs_handle _handle;\n\nbool spiflash_init() {\n\tif (_data) {\n\t\tERROR(\"Storage: should not call spiflash_init twice!!!\");\n\t\treturn true;\n\t}\n\t_data = (uint8_t*) malloc(HOMEKIT_STORAGE_SIZE);\n\tif (!_data) {\n\t\tERROR(\"Storage: Not enough memory for %d bytes\", HOMEKIT_STORAGE_SIZE);\n\t\treturn false;\n\t}\n\tmemset(_data, 0xFF, HOMEKIT_STORAGE_SIZE);\n\t//https://github.com/espressif/esp-idf/blob/2e14149bff63fe211d6d30ff0cd84c90b5fface9/examples/storage/nvs_rw_blob/main/nvs_blob_example_main.c\n//\tesp_err_t err = nvs_flash_init();\n//\t    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {\n//\t        // NVS partition was truncated and needs to be erased\n//\t        // Retry nvs_flash_init\n//\t        ESP_ERROR_CHECK(nvs_flash_erase());\n//\t        err = nvs_flash_init();\n//\t    }\n//\t    ESP_ERROR_CHECK( err );\n\n\tconst char *_name = HOMEKIT_STORAGE_NVS_NAME;\n\tesp_err_t res = nvs_open(_name, NVS_READWRITE, &_handle);\n\tif (res != ESP_OK) {\n\t\tERROR(\"Unable to open NVS namespace: %d\", res);\n\t\treturn false;\n\t}\n\tsize_t key_size = 0;\n\tres = nvs_get_blob(_handle, _name, NULL, &key_size);\n\tif (res != ESP_OK && res != ESP_ERR_NVS_NOT_FOUND) {\n\t\tERROR(\"Unable to read NVS key: %d\", res);\n\t\treturn false;\n\t}\n\tif (key_size == 0) {\n\t\t// New blob\n\t\tnvs_set_blob(_handle, _name, _data, HOMEKIT_STORAGE_SIZE);\n\t\tINFO(\"Storage set new blob, name: %s, size: %u\", _name, HOMEKIT_STORAGE_SIZE);\n\t} else {\n\t\tif (key_size != HOMEKIT_STORAGE_SIZE) {\n\t\t\tERROR(\"Storage error, NVS size is not equal the defined size!!\");\n\t\t\treturn false;\n\t\t} else {\n\t\t\tnvs_get_blob(_handle, _name, _data, &key_size);\n\t\t}\n\t}\n\treturn true;\n}\n\nbool spiflash_erase_sector(size_t sector) {\n\tmemset(_data, 0xFF, HOMEKIT_STORAGE_SIZE);\n\treturn true;\n}\n\nbool spiflash_write(size_t dest_addr, const void *src, size_t size) {\n\tif (dest_addr < 0 || dest_addr + size > HOMEKIT_STORAGE_SIZE) {\n\t\treturn false;\n\t}\n\tmemcpy(_data + dest_addr, (const void*) src, size);\n\treturn ESP_OK == nvs_set_blob(_handle, HOMEKIT_STORAGE_NVS_NAME, _data, HOMEKIT_STORAGE_SIZE);\n}\n\nbool spiflash_read(size_t src_addr, void *dest, size_t size) {\n\tif (src_addr < 0 || src_addr + size > HOMEKIT_STORAGE_SIZE) {\n\t\treturn false;\n\t}\n\tmemcpy(dest, _data + src_addr, size);\n\treturn true;\n}\n\n/*\nvoid homekit_mdns_init() {\n    mdns_init();\n}\n\nvoid homekit_mdns_configure_init(const char *instance_name, int port) {\n    mdns_hostname_set(instance_name);\n    mdns_instance_name_set(instance_name);\n    mdns_service_add(instance_name, \"_hap\", \"_tcp\", port, NULL, 0);\n}\n\nvoid homekit_mdns_add_txt(const char *key, const char *format, ...) {\n    va_list arg_ptr;\n    va_start(arg_ptr, format);\n\n    char value[128];\n    int value_len = vsnprintf(value, sizeof(value), format, arg_ptr);\n\n    va_end(arg_ptr);\n\n    if (value_len && value_len < sizeof(value)-1) {\n        mdns_service_txt_item_set(\"_hap\", \"_tcp\", key, value);\n    }\n}\n\nvoid homekit_mdns_configure_finalize() {\n    printf(\"mDNS announcement: Name=%s %s Port=%d TTL=%d\\n\",\n           name->value.string_value, txt_rec, PORT, 0);\n\n//}*/\n#endif\n"
  },
  {
    "path": "src/port.h",
    "content": "#ifndef __HOMEKIT_PORT_H_\n#define __HOMEKIT_PORT_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include \"homekit_debug.h\"\n\nuint32_t homekit_random();\nvoid homekit_random_fill(uint8_t *data, size_t size);\n\nvoid homekit_system_restart();\nvoid homekit_overclock_start();\nvoid homekit_overclock_end();\n\n#ifdef ESP_OPEN_RTOS\n#include <spiflash.h>\n#define ESP_OK 0\n#endif\n\n//#ifdef ESP_IDF\n//#include <esp_system.h>\n//#include <esp_spi_flash.h>\n\n#if defined(ARDUINO_ARCH_ESP8266)\n#include \"Arduino.h\"\n#include <spi_flash.h>\n#include <ets_sys.h>\n#include <osapi.h>\n#include <user_interface.h>\n#define ESP_OK SPI_FLASH_RESULT_OK //0\n\n#define SPI_FLASH_SECTOR_SIZE SPI_FLASH_SEC_SIZE\n#define spiflash_read(addr, buffer, size) (spi_flash_read((addr), (buffer), (size)) == ESP_OK)\n#define spiflash_write(addr, data, size) (spi_flash_write((addr), (data), (size)) == ESP_OK)\n#define spiflash_erase_sector(addr) (spi_flash_erase_sector((addr) / SPI_FLASH_SECTOR_SIZE) == ESP_OK)\n\n#endif\n\n//#ifdef ESP_IDF\n#ifdef ARDUINO_ARCH_ESP32\n#define SERVER_TASK_STACK 10240//12288// USE_FAST_MATH requires a lot of memory!!!\n#else\n#define SERVER_TASK_STACK 2048\n#endif\n\n#if defined(ARDUINO_ARCH_ESP32)\n#include <esp_spi_flash.h>\n#include <nvs.h>\n#define SPI_FLASH_SECTOR_SIZE SPI_FLASH_SEC_SIZE\n\n// Use nvs of ESP32, See EEPROM.cpp for example\n\n// 1536 is enough, but require 4096 in compact_data() (for compatibility)\n#define HOMEKIT_STORAGE_SIZE     SPI_FLASH_SECTOR_SIZE\n#define HOMEKIT_STORAGE_NVS_NAME \"homekit\"\n\nbool spiflash_init();\nbool spiflash_erase_sector(size_t sector);\nbool spiflash_write(size_t dest_addr, const void *src, size_t size);\nbool spiflash_read(size_t src_addr, void *dest, size_t size);\n\n#endif\n\n//void homekit_mdns_init();\n//void homekit_mdns_configure_init(const char *instance_name, int port);\n//void homekit_mdns_add_txt(const char *key, const char *format, ...);\n//void homekit_mdns_configure_finalize();\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __HOMEKIT_PORT_H_ */\n"
  },
  {
    "path": "src/query_params.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include \"query_params.h\"\n\n\nquery_param_t *query_params_parse(const char *s) {\n    query_param_t *params = NULL;\n\n    int i = 0;\n    while (1) {\n        int pos = i;\n        while (s[i] && s[i] != '=' && s[i] != '&' && s[i] != '#') i++;\n        if (i == pos) {\n            i++;\n            continue;\n        }\n\n        query_param_t *param = malloc(sizeof(query_param_t));\n        param->name = strndup(s+pos, i-pos);\n        param->value = NULL;\n        param->next = params;\n        params = param;\n\n        if (s[i] == '=') {\n            i++;\n            pos = i;\n            while (s[i] && s[i] != '&' && s[i] != '#') i++;\n            if (i != pos) {\n                param->value = strndup(s+pos, i-pos);\n            }\n        }\n\n        if (!s[i] || s[i] == '#')\n            break;\n    }\n\n    return params;\n}\n\n\nquery_param_t *query_params_find(query_param_t *params, const char *name) {\n    while (params) {\n        if (!strcmp(params->name, name))\n            return params;\n        params = params->next;\n    }\n\n    return NULL;\n}\n\n\nvoid query_params_free(query_param_t *params) {\n    while (params) {\n        query_param_t *next = params->next;\n        if (params->name)\n            free(params->name);\n        if (params->value)\n            free(params->value);\n        free(params);\n\n        params = next;\n    }\n}\n\n"
  },
  {
    "path": "src/query_params.h",
    "content": "#ifndef __HOMEKIT_QUERY_PARAMS__\n#define __HOMEKIT_QUERY_PARAMS__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef struct _query_param {\n    char *name;\n    char *value;\n\n    struct _query_param *next;\n} query_param_t;\n\nquery_param_t *query_params_parse(const char *s);\nquery_param_t *query_params_find(query_param_t *params, const char *name);\nvoid query_params_free(query_param_t *params);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif // __HOMEKIT_QUERY_PARAMS__\n"
  },
  {
    "path": "src/storage.c",
    "content": "#include <string.h>\n#include <ctype.h>\n#include \"constants.h\"\n#include \"pairing.h\"\n#include \"port.h\"\n\n#include \"storage.h\"\n\n#include \"crypto.h\"\n#include \"homekit_debug.h\"\n\n//#include \"c_types.h\"\n//#include \"ets_sys.h\"\n//#include \"os_type.h\"\n//#include \"osapi.h\"\n//#include \"spi_flash.h\"\n//#include \"spi_flash_geometry.h\"\n//#include \"FS.h\"\n//#include \"spiffs_api.h\"\n\n// ESP82666  spi_flash_geometry.h\n// FLASH_SECTOR_SIZE 0x1000 = 4096B\n// EEPROM use _sector = _EEPROM_start\n// the \"_EEPROM_start\" value is provided in tools/sdk/ld/eagle.flash.**.ld\n\n// We use the EEPROM address for this storage.c in Arduino environment\n// EEPROM = one SPI_FLASH_SEC_SIZE = 0x1000 = 4096B\n// SPI_FLASH_SEC_SIZE = 4096B\n// sizeof(pairing_data_t) = 80B\n// MAX_PAIRINGS = 16\n// PAIRINGS_OFFSET = 128(address)\n// so max use address of (128 + 80 * 16) = 1408 B\n\n// This storage use [0, 1408) of EEPROM, leave [1408, 4096) for user to use safely.\n// Leave the FS(file system) for user to use freely.\n\n/*\n\nSee https://arduino-esp8266.readthedocs.io/en/2.6.3/filesystem.html\nhttps://arduino-esp8266.readthedocs.io/en/2.6.3/libraries.html#eeprom\n\nEEPROM library uses one sector of flash located just after the SPIFFS.\n\nThe following diagram illustrates flash layout used in Arduino environment:\n\n|--------------|-------|---------------|--|--|--|--|--|\n^              ^       ^               ^     ^\nSketch    OTA update   File system   EEPROM  WiFi config (SDK)\n\n*/\n\n#pragma GCC diagnostic ignored \"-Wunused-value\"\n\n#if defined(ARDUINO_ARCH_ESP8266)\n\n// These two values are provided in tools/sdk/ld/eagle.flash.**.ld\nextern uint32_t _EEPROM_start; //See EEPROM.cpp\nextern uint32_t _SPIFFS_start; //See spiffs_api.h\n\n#define HOMEKIT_EEPROM_PHYS_ADDR ((uint32_t) (&_EEPROM_start) - 0x40200000)\n#define HOMEKIT_SPIFFS_PHYS_ADDR ((uint32_t) (&_SPIFFS_start) - 0x40200000)\n\n//#ifndef SPIFLASH_BASE_ADDR\n#define STORAGE_BASE_ADDR HOMEKIT_EEPROM_PHYS_ADDR//0x200000\n//#endif\n\n#elif defined(ARDUINO_ARCH_ESP32)\n#define STORAGE_BASE_ADDR  0\n#endif\n\n#define MAGIC_OFFSET           0\n#define ACCESSORY_ID_OFFSET    4\n#define ACCESSORY_KEY_OFFSET   32\n#define PAIRINGS_OFFSET        128\n\n#define MAGIC_ADDR           (STORAGE_BASE_ADDR + MAGIC_OFFSET)\n#define ACCESSORY_ID_ADDR    (STORAGE_BASE_ADDR + ACCESSORY_ID_OFFSET)\n#define ACCESSORY_KEY_ADDR   (STORAGE_BASE_ADDR + ACCESSORY_KEY_OFFSET)\n#define PAIRINGS_ADDR        (STORAGE_BASE_ADDR + PAIRINGS_OFFSET)\n\n#define MAX_PAIRINGS 16\n\n#define ACCESSORY_KEY_SIZE  64\n\n#define STORAGE_DEBUG(message, ...) //printf(\"*** [Storage] %s: \" message \"\\n\", __func__, ##__VA_ARGS__)\n\nconst char magic1[] = \"HAP\";\n\n// TODO: figure out alignment issues\ntypedef struct {\n    char magic[sizeof(magic1)];\n    byte permissions;\n    char device_id[DEVICE_ID_SIZE];\n    byte device_public_key[32];\n\n    byte _reserved[7]; // align record to be 80 bytes\n} pairing_data_t;\n\n\nint homekit_storage_init() {\n\n#if defined(ARDUINO_ARCH_ESP32)\n\tspiflash_init();\n#endif\n\n\tSTORAGE_DEBUG(\"EEPROM max: %d B\", SPI_FLASH_SEC_SIZE);//4096B\n\tSTORAGE_DEBUG(\"Pairing_data size: %d \", (sizeof(pairing_data_t)));//80B\n\tSTORAGE_DEBUG(\"MAX pairing count: %d \", MAX_PAIRINGS);//16\n\tSTORAGE_DEBUG(\"_EEPROM_start: 0x%x (%u)\",\n\t\t\tHOMEKIT_EEPROM_PHYS_ADDR, HOMEKIT_EEPROM_PHYS_ADDR);\n\tSTORAGE_DEBUG(\"_SPIFFS_start: 0x%x (%u)\",\n\t\t\tHOMEKIT_SPIFFS_PHYS_ADDR, HOMEKIT_SPIFFS_PHYS_ADDR);\n\n    char magic[sizeof(magic1)];\n    memset(magic, 0, sizeof(magic));\n\n    if (!spiflash_read(MAGIC_ADDR, (byte *)magic, sizeof(magic))) {\n        ERROR(\"Failed to read HomeKit storage magic\");\n    }\n\n    if (strncmp(magic, magic1, sizeof(magic1))) {\n        INFO(\"Formatting HomeKit storage at 0x%x\", STORAGE_BASE_ADDR);\n        if (!spiflash_erase_sector(STORAGE_BASE_ADDR)) {\n            ERROR(\"Failed to erase HomeKit storage\");\n            return -1;\n        }\n\n        strncpy(magic, magic1, sizeof(magic));\n        if (!spiflash_write(MAGIC_ADDR, (byte *)magic, sizeof(magic))) {\n            ERROR(\"Failed to write HomeKit storage magic\");\n            return -1;\n        }\n\n        return 1;\n    }\n\n    return 0;\n}\n\n\nint homekit_storage_reset() {\n    byte blank[sizeof(magic1)];\n    memset(blank, 0, sizeof(blank));\n\n    if (!spiflash_write(MAGIC_ADDR, blank, sizeof(blank))) {\n        ERROR(\"Failed to reset HomeKit storage\");\n        return -1;\n    }\n\n    return homekit_storage_init();\n}\n\n\nvoid homekit_storage_save_accessory_id(const char *accessory_id) {\n    if (!spiflash_write(ACCESSORY_ID_ADDR, (byte *)accessory_id, ACCESSORY_ID_SIZE)) {\n        ERROR(\"Failed to write accessory ID to HomeKit storage\");\n    }\n}\n\n\nstatic char ishex(unsigned char c) {\n    c = toupper(c);\n    return isdigit(c) || (c >= 'A' && c <= 'F');\n}\n\nint homekit_storage_load_accessory_id(char *data) {\n    if (!spiflash_read(ACCESSORY_ID_ADDR, (byte *)data, ACCESSORY_ID_SIZE)) {\n        ERROR(\"Failed to read accessory ID from HomeKit storage\");\n        return -1;\n    }\n    if (!data[0])\n        return -2;\n    data[ACCESSORY_ID_SIZE] = 0;\n\n    for (int i=0; i<ACCESSORY_ID_SIZE; i++) {\n        if (i % 3 == 2) {\n           if (data[i] != ':')\n               return -3;\n        } else if (!ishex(data[i]))\n            return -4;\n    }\n\n    return 0;\n}\n\nvoid homekit_storage_save_accessory_key(const ed25519_key *key) {\n    byte key_data[ACCESSORY_KEY_SIZE];\n    size_t key_data_size = sizeof(key_data);\n    int r = crypto_ed25519_export_key(key, key_data, &key_data_size);\n    if (r) {\n        ERROR(\"Failed to export accessory key (code %d)\", r);\n        return;\n    }\n\n    if (!spiflash_write(ACCESSORY_KEY_ADDR, key_data, key_data_size)) {\n        ERROR(\"Failed to write accessory key to HomeKit storage\");\n        return;\n    }\n}\n\nint homekit_storage_load_accessory_key(ed25519_key *key) {\n    byte key_data[ACCESSORY_KEY_SIZE];\n    if (!spiflash_read(ACCESSORY_KEY_ADDR, key_data, sizeof(key_data))) {\n        ERROR(\"Failed to read accessory key from HomeKit storage\");\n        return -1;\n    }\n\n    crypto_ed25519_init(key);\n    int r = crypto_ed25519_import_key(key, key_data, sizeof(key_data));\n    if (r) {\n        ERROR(\"Failed to import accessory key (code %d)\", r);\n        return -2;\n    }\n\n    return 0;\n}\n\nbool homekit_storage_can_add_pairing() {\n    pairing_data_t data;\n    for (int i=0; i<MAX_PAIRINGS; i++) {\n        spiflash_read(PAIRINGS_ADDR + sizeof(data)*i, (byte *)&data, sizeof(data));\n        if (strncmp(data.magic, magic1, sizeof(magic1)))\n            return true;\n    }\n    return false;\n}\n\nstatic int compact_data() {\n    byte *data = malloc(SPI_FLASH_SECTOR_SIZE);\n    if (!spiflash_read(STORAGE_BASE_ADDR, data, SPI_FLASH_SECTOR_SIZE)) {\n        free(data);\n        ERROR(\"Failed to compact HomeKit storage: sector data read error\");\n        return -1;\n    }\n\n    int next_pairing_idx = 0;\n    for (int i=0; i<MAX_PAIRINGS; i++) {\n        pairing_data_t *pairing_data = (pairing_data_t *)&data[PAIRINGS_OFFSET + sizeof(pairing_data_t)*i];\n        if (!strncmp(pairing_data->magic, magic1, sizeof(magic1))) {\n            if (i != next_pairing_idx) {\n                memcpy(&data[PAIRINGS_ADDR + sizeof(pairing_data_t)*next_pairing_idx],\n                       pairing_data, sizeof(*pairing_data));\n            }\n            next_pairing_idx++;\n        }\n    }\n\n    if (next_pairing_idx == MAX_PAIRINGS) {\n        // We are full, no compaction possible, do not waste flash erase cycle\n        free(data);\n        return 0;\n    }\n\n    if (homekit_storage_reset()) {\n        ERROR(\"Failed to compact HomeKit storage: error resetting flash\");\n        free(data);\n        return -1;\n    }\n    if (!spiflash_write(STORAGE_BASE_ADDR, data, PAIRINGS_OFFSET + sizeof(pairing_data_t)*next_pairing_idx)) {\n        ERROR(\"Failed to compact HomeKit storage: error writing compacted data\");\n        free(data);\n        return -1;\n    }\n\n    free(data);\n\n    return 0;\n}\n\nstatic int find_empty_block() {\n    byte data[sizeof(pairing_data_t)];\n\n    for (int i=0; i<MAX_PAIRINGS; i++) {\n        spiflash_read(PAIRINGS_ADDR + sizeof(data)*i, data, sizeof(data));\n\n        bool block_empty = true;\n        for (int j=0; j<sizeof(data); j++)\n            if (data[j] != 0xff) {\n                block_empty = false;\n                break;\n            }\n\n        if (block_empty)\n            return i;\n    }\n\n    return -1;\n}\n\nint homekit_storage_add_pairing(const char *device_id, const ed25519_key *device_key, byte permissions) {\n    int next_block_idx = find_empty_block();\n    if (next_block_idx == -1) {\n        compact_data();\n        next_block_idx = find_empty_block();\n    }\n\n    if (next_block_idx == -1) {\n        ERROR(\"Failed to write pairing info to HomeKit storage: max number of pairings\");\n        return -2;\n    }\n\n    pairing_data_t data;\n\n    memset(&data, 0, sizeof(data));\n    strncpy(data.magic, magic1, sizeof(data.magic));\n    data.permissions = permissions;\n    strncpy(data.device_id, device_id, sizeof(data.device_id));\n    size_t device_public_key_size = sizeof(data.device_public_key);\n    int r = crypto_ed25519_export_public_key(\n        device_key, data.device_public_key, &device_public_key_size\n    );\n    if (r) {\n        ERROR(\"Failed to export device public key (code %d)\", r);\n        return -1;\n    }\n\n    if (!spiflash_write(PAIRINGS_ADDR + sizeof(data)*next_block_idx, (byte *)&data, sizeof(data))) {\n        ERROR(\"Failed to write pairing info to HomeKit storage\");\n        return -1;\n    }\n\n    return 0;\n}\n\n\nint homekit_storage_update_pairing(const char *device_id, byte permissions) {\n    pairing_data_t data;\n    for (int i=0; i<MAX_PAIRINGS; i++) {\n        spiflash_read(PAIRINGS_ADDR + sizeof(data)*i, (byte *)&data, sizeof(data));\n        if (strncmp(data.magic, magic1, sizeof(data.magic)))\n            continue;\n\n        if (!strncmp(data.device_id, device_id, sizeof(data.device_id))) {\n            int next_block_idx = find_empty_block();\n            if (next_block_idx == -1) {\n                compact_data();\n                next_block_idx = find_empty_block();\n            }\n\n            if (next_block_idx == -1) {\n                ERROR(\"Failed to write pairing info to HomeKit storage: max number of pairings\");\n                return -2;\n            }\n\n            data.permissions = permissions;\n\n            if (!spiflash_write(PAIRINGS_ADDR + sizeof(data)*next_block_idx, (byte *)&data, sizeof(data))) {\n                ERROR(\"Failed to write pairing info to HomeKit storage\");\n                return -1;\n            }\n\n            memset(&data, 0, sizeof(data));\n            if (!spiflash_write(PAIRINGS_ADDR + sizeof(data)*i, (byte *)&data, sizeof(data))) {\n                ERROR(\"Failed to update pairing: error erasing old record from HomeKit storage\");\n                return -2;\n            }\n\n            return 0;\n        }\n    }\n    return -1;\n}\n\n\nint homekit_storage_remove_pairing(const char *device_id) {\n    pairing_data_t data;\n    for (int i=0; i<MAX_PAIRINGS; i++) {\n        spiflash_read(PAIRINGS_ADDR + sizeof(data)*i, (byte *)&data, sizeof(data));\n        if (strncmp(data.magic, magic1, sizeof(data.magic)))\n            continue;\n\n        if (!strncmp(data.device_id, device_id, sizeof(data.device_id))) {\n            memset(&data, 0, sizeof(data));\n            if (!spiflash_write(PAIRINGS_ADDR + sizeof(data)*i, (byte *)&data, sizeof(data))) {\n                ERROR(\"Failed to remove pairing from HomeKit storage\");\n                return -2;\n            }\n\n            return 0;\n        }\n    }\n    return 0;\n}\n\n\nint homekit_storage_find_pairing(const char *device_id, pairing_t *pairing) {\n    pairing_data_t data;\n    for (int i=0; i<MAX_PAIRINGS; i++) {\n        spiflash_read(PAIRINGS_ADDR + sizeof(data)*i, (byte *)&data, sizeof(data));\n        if (strncmp(data.magic, magic1, sizeof(data.magic)))\n            continue;\n\n        if (!strncmp(data.device_id, device_id, sizeof(data.device_id))) {\n            crypto_ed25519_init(&pairing->device_key);\n            int r = crypto_ed25519_import_public_key(&pairing->device_key, data.device_public_key, sizeof(data.device_public_key));\n            if (r) {\n                ERROR(\"Failed to import device public key (code %d)\", r);\n                return -2;\n            }\n\n            pairing->id = i;\n            strncpy(pairing->device_id, data.device_id, DEVICE_ID_SIZE);\n            pairing->device_id[DEVICE_ID_SIZE] = 0;\n            pairing->permissions = data.permissions;\n\n            return 0;\n        }\n    }\n\n    return -1;\n}\n\n\nvoid homekit_storage_pairing_iterator_init(pairing_iterator_t *it) {\n    it->idx = 0;\n}\n\n\nvoid homekit_storage_pairing_iterator_done(pairing_iterator_t *iterator) {\n}\n\n\nint homekit_storage_next_pairing(pairing_iterator_t *it, pairing_t *pairing) {\n    pairing_data_t data;\n    while(it->idx < MAX_PAIRINGS) {\n        int id = it->idx++;\n\n        spiflash_read(PAIRINGS_ADDR + sizeof(data)*id, (byte *)&data, sizeof(data));\n        if (!strncmp(data.magic, magic1, sizeof(data.magic))) {\n            crypto_ed25519_init(&pairing->device_key);\n            int r = crypto_ed25519_import_public_key(&pairing->device_key, data.device_public_key, sizeof(data.device_public_key));\n            if (r) {\n                ERROR(\"Failed to import device public key (code %d)\", r);\n                continue;\n            }\n\n            pairing->id = id;\n            strncpy(pairing->device_id, data.device_id, DEVICE_ID_SIZE);\n            pairing->device_id[DEVICE_ID_SIZE] = 0;\n            pairing->permissions = data.permissions;\n\n            return 0;\n        }\n    }\n\n    return -1;\n}\n\n\n#undef HOMEKIT_EEPROM_PHYS_ADDR\n#undef HOMEKIT_SPIFFS_PHYS_ADDR\n"
  },
  {
    "path": "src/storage.h",
    "content": "#ifndef __STORAGE_H__\n#define __STORAGE_H__\n\n//#include \"EEPROM.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"pairing.h\"\n\nint homekit_storage_reset();\n\nint homekit_storage_init();\n\nvoid homekit_storage_save_accessory_id(const char *accessory_id);\nint homekit_storage_load_accessory_id(char *data);\n\nvoid homekit_storage_save_accessory_key(const ed25519_key *key);\nint homekit_storage_load_accessory_key(ed25519_key *key);\n\nbool homekit_storage_can_add_pairing();\nint homekit_storage_add_pairing(const char *device_id, const ed25519_key *device_key, byte permissions);\nint homekit_storage_update_pairing(const char *device_id, byte permissions);\nint homekit_storage_remove_pairing(const char *device_id);\nint homekit_storage_find_pairing(const char *device_id, pairing_t *pairing);\n\ntypedef struct {\n    int idx;\n} pairing_iterator_t;\n\n\nvoid homekit_storage_pairing_iterator_init(pairing_iterator_t *it);\nint homekit_storage_next_pairing(pairing_iterator_t *it, pairing_t *pairing);\nvoid homekit_storage_pairing_iterator_done(pairing_iterator_t *iterator);\n\n#ifdef __cplusplus\n}\n#endif\n#endif // __STORAGE_H__\n"
  },
  {
    "path": "src/tlv.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n\n#include <homekit/tlv.h>\n\n\ntlv_values_t *tlv_new() {\n    tlv_values_t *values = malloc(sizeof(tlv_values_t));\n    values->head = NULL;\n    return values;\n}\n\n\nvoid tlv_free(tlv_values_t *values) {\n    tlv_t *t = values->head;\n    while (t) {\n        tlv_t *t2 = t;\n        t = t->next;\n        if (t2->value)\n            free(t2->value);\n        free(t2);\n    }\n    free(values);\n}\n\n\nint tlv_add_value_(tlv_values_t *values, byte type, byte *value, size_t size) {\n    tlv_t *tlv = malloc(sizeof(tlv_t));\n    tlv->type = type;\n    tlv->size = size;\n    tlv->value = value;\n    tlv->next = NULL;\n\n    if (!values->head) {\n        values->head = tlv;\n    } else {\n        tlv_t *t = values->head;\n        while (t->next) {\n            t = t->next;\n        }\n        t->next = tlv;\n    }\n\n    return 0;\n}\n\nint tlv_add_value(tlv_values_t *values, byte type, const byte *value, size_t size) {\n    byte *data = NULL;\n    if (size) {\n        data = malloc(size);\n        memcpy(data, value, size);\n    }\n    return tlv_add_value_(values, type, data, size);\n}\n\nint tlv_add_string_value(tlv_values_t *values, byte type, const char *value) {\n    return tlv_add_value(values, type, (const byte *)value, strlen(value));\n}\n\nint tlv_add_integer_value(tlv_values_t *values, byte type, size_t size, int value) {\n    byte data[8];\n\n    for (size_t i=0; i<size; i++) {\n        data[i] = value & 0xff;\n        value >>= 8;\n    }\n\n    return tlv_add_value(values, type, data, size);\n}\n\nint tlv_add_tlv_value(tlv_values_t *values, byte type, tlv_values_t *value) {\n    size_t tlv_size = 0;\n    tlv_format(value, NULL, &tlv_size);\n    byte *tlv_data = malloc(tlv_size);\n    int r = tlv_format(value, tlv_data, &tlv_size);\n    if (r) {\n        free(tlv_data);\n        return r;\n    }\n\n    r = tlv_add_value_(values, type, tlv_data, tlv_size);\n\n    return r;\n}\n\n\ntlv_t *tlv_get_value(const tlv_values_t *values, byte type) {\n    tlv_t *t = values->head;\n    while (t) {\n        if (t->type == type)\n            return t;\n        t = t->next;\n    }\n    return NULL;\n}\n\n\nint tlv_get_integer_value(const tlv_values_t *values, byte type, int def) {\n    tlv_t *t = tlv_get_value(values, type);\n    if (!t)\n        return def;\n\n    int x = 0;\n    for (int i=t->size-1; i>=0; i--) {\n        x = (x << 8) + t->value[i];\n    }\n    return x;\n}\n\n// Return a string value. Returns NULL if value does not exist.\n// Caller is responsible for freeing returned value.\nchar *tlv_get_string_value(const tlv_values_t *values, byte type) {\n    tlv_t *t = tlv_get_value(values, type);\n    if (!t)\n        return NULL;\n\n    return strndup((char*)t->value, t->size);\n}\n\n// Deserializes a TLV value and returns it. Returns NULL if value does not exist\n// or incorrect. Caller is responsible for freeing returned value.\ntlv_values_t *tlv_get_tlv_value(const tlv_values_t *values, byte type) {\n    tlv_t *t = tlv_get_value(values, type);\n    if (!t)\n        return NULL;\n\n    tlv_values_t *value = tlv_new();\n    int r = tlv_parse(t->value, t->size, value);\n\n    if (r) {\n        tlv_free(value);\n        return NULL;\n    }\n\n    return value;\n}\n\n\nint tlv_format(const tlv_values_t *values, byte *buffer, size_t *size) {\n    size_t required_size = 0;\n    tlv_t *t = values->head;\n    while (t) {\n        required_size += t->size + 2 * ((t->size + 254) / 255);\n        t = t->next;\n    }\n\n    if (*size < required_size) {\n        *size = required_size;\n        return -1;\n    }\n\n    *size = required_size;\n\n    t = values->head;\n    while (t) {\n        byte *data = t->value;\n        if (!t->size) {\n            buffer[0] = t->type;\n            buffer[1] = 0;\n            buffer += 2;\n            t = t->next;\n            continue;\n        }\n\n        size_t remaining = t->size;\n\n        while (remaining) {\n            buffer[0] = t->type;\n            size_t chunk_size = (remaining > 255) ? 255 : remaining;\n            buffer[1] = chunk_size;\n            memcpy(&buffer[2], data, chunk_size);\n            remaining -= chunk_size;\n            buffer += chunk_size + 2;\n            data += chunk_size;\n        }\n\n        t = t->next;\n    }\n\n    return 0;\n}\n\n\nint tlv_parse(const byte *buffer, size_t length, tlv_values_t *values) {\n    size_t i = 0;\n    while (i < length) {\n        byte type = buffer[i];\n        size_t size = 0;\n        byte *data = NULL;\n\n        // scan TLVs to accumulate total size of subsequent TLVs with same type (chunked data)\n        size_t j = i;\n        while (j < length && buffer[j] == type && buffer[j+1] == 255) {\n            size_t chunk_size = buffer[j+1];\n            size += chunk_size;\n            j += chunk_size + 2;\n        }\n        if (j < length && buffer[j] == type) {\n            size_t chunk_size = buffer[j+1];\n            size += chunk_size;\n        }\n\n        // allocate memory to hold all pieces of chunked data and copy data there\n        if (size != 0) {\n            data = malloc(size);\n            byte *p = data;\n\n            size_t remaining = size;\n            while (remaining) {\n                size_t chunk_size = buffer[i+1];\n                memcpy(p, &buffer[i+2], chunk_size);\n                p += chunk_size;\n                i += chunk_size + 2;\n                remaining -= chunk_size;\n            }\n        }\n\n        tlv_add_value_(values, type, data, size);\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "src/types.c",
    "content": "#include \"homekit/types.h\"\n\n//=========================\n// Compat for cplusplus\n//=========================\n\nhomekit_value_t HOMEKIT_DEFAULT_CPP() {\n\thomekit_value_t homekit_value;\n\t//homekit_value.is_null = false;//该值为默认，不用设置\n\treturn homekit_value;\n}\n\nhomekit_value_t HOMEKIT_NULL_CPP() {\n\thomekit_value_t homekit_value;\n\thomekit_value.is_null = true;\n\treturn homekit_value;\n}\n\nhomekit_value_t HOMEKIT_BOOL_CPP(bool value) {\n\thomekit_value_t homekit_value = HOMEKIT_DEFAULT_CPP();\n\thomekit_value.format = homekit_format_bool;\n\thomekit_value.bool_value = value;\n\treturn homekit_value;\n}\n\nhomekit_value_t HOMEKIT_INT_CPP(uint8_t value) {\n\thomekit_value_t homekit_value = HOMEKIT_DEFAULT_CPP();\n\thomekit_value.format = homekit_format_int;\n\thomekit_value.int_value = value;\n\treturn homekit_value;\n}\n\nhomekit_value_t HOMEKIT_UINT8_CPP(uint8_t value) {\n\thomekit_value_t homekit_value = HOMEKIT_DEFAULT_CPP();\n\thomekit_value.format = homekit_format_uint8;\n\thomekit_value.uint8_value = value;\n\treturn homekit_value;\n}\n\nhomekit_value_t HOMEKIT_UINT16_CPP(uint16_t value) {\n\thomekit_value_t homekit_value = HOMEKIT_DEFAULT_CPP();\n\thomekit_value.format = homekit_format_uint16;\n\thomekit_value.uint16_value = value;\n\treturn homekit_value;\n}\n\nhomekit_value_t HOMEKIT_UINT32_CPP(uint32_t value) {\n\thomekit_value_t homekit_value = HOMEKIT_DEFAULT_CPP();\n\thomekit_value.format = homekit_format_uint32;\n\thomekit_value.uint32_value = value;\n\treturn homekit_value;\n}\n\nhomekit_value_t HOMEKIT_UINT64_CPP(uint64_t value) {\n\thomekit_value_t homekit_value = HOMEKIT_DEFAULT_CPP();\n\thomekit_value.format = homekit_format_uint64;\n\thomekit_value.uint64_value = value;\n\treturn homekit_value;\n}\n\nhomekit_value_t HOMEKIT_FLOAT_CPP(float value) {\n\thomekit_value_t homekit_value = HOMEKIT_DEFAULT_CPP();\n\thomekit_value.format = homekit_format_float;\n\thomekit_value.float_value = value;\n\treturn homekit_value;\n}\n\nhomekit_value_t HOMEKIT_STRING_CPP(char *value) {\n\thomekit_value_t homekit_value = HOMEKIT_DEFAULT_CPP();\n\thomekit_value.format = homekit_format_string;\n\thomekit_value.string_value = value;\n\treturn homekit_value;\n}\n\nhomekit_value_t HOMEKIT_TLV_CPP(tlv_values_t *value) {\n\thomekit_value_t homekit_value = HOMEKIT_DEFAULT_CPP();\n\thomekit_value.format = homekit_format_tlv;\n\thomekit_value.tlv_values = value;\n\treturn homekit_value;\n}\n\nhomekit_value_t HOMEKIT_DATA_CPP(uint8_t *value, size_t size) {\n\thomekit_value_t homekit_value = HOMEKIT_DEFAULT_CPP();\n\thomekit_value.format = homekit_format_data;\n\thomekit_value.data_value = value;\n\thomekit_value.data_size = size;\n\treturn homekit_value;\n}\n\n"
  },
  {
    "path": "src/user_settings.h",
    "content": "#ifndef wolfcrypt_user_settings_h\n#define wolfcrypt_user_settings_h\n\n#define WOLFSSL_USER_SETTINGS\n\n//#define ARDUINO_HOMEKIT_LOWROM\n\n//skip ed25519_verify, see crypto_ed25519_verify in crypto.c\n//Pair Verify Step 2/2: skip=35ms, not-skip=794ms\n//#define ARDUINO_HOMEKIT_SKIP_ED25519_VERIFY\n\n#include \"stdint.h\"\n#include \"stddef.h\"\n#include \"stdlib.h\"\n\n#include \"homekit_debug.h\"\n\n#if !defined(ARDUINO_ARCH_ESP8266) && !defined(ARDUINO_ARCH_ESP32)\n#error HomeKit library only supports Arduino framework of ESP8266 and ESP32!\n#endif\n\n#if defined(ARDUINO_ARCH_ESP8266)\n#include \"osapi.h\"\nstatic inline int hwrand_generate_block(uint8_t *buf, size_t len) {\n\tos_get_random(buf, len);\n    return 0;\n}\n\n#elif defined(ARDUINO_ARCH_ESP32)\n#include <esp_system.h>\nstatic inline int hwrand_generate_block(uint8_t *buf, size_t len) {\n\tesp_fill_random(buf, len);\n    return 0;\n}\n#endif\n\n\n#define WC_NO_HARDEN\n#define NO_WOLFSSL_DIR\n#define SINGLE_THREADED\n#define WOLFSSL_LWIP\n#define NO_INLINE\n\n#define NO_WOLFSSL_MEMORY\n\n#define CUSTOM_RAND_GENERATE_BLOCK hwrand_generate_block\n\n//==========\n// added\n//==========\n#define WOLFCRYPT_ONLY\n\n#define NO_ASN\n#define NO_AES\n#define NO_RC4\n#define NO_RSA\n#define NO_SHA256\n#define NO_DH\n#define NO_DSA\n#define NO_CODING\n//#define NO_SHA // Use SHA512\n#define NO_MD5\n\n#define HAVE_CURVE25519\n#define HAVE_CHACHA\n#define HAVE_POLY1305\n#define HAVE_ED25519\n#define WOLFSSL_SHA512\n#define WOLFCRYPT_HAVE_SRP\n#define HAVE_HKDF\n\n#define WC_NO_HASHDRBG\n\n#define WOLFSSL_BASE64_ENCODE\n\n#if defined(ARDUINO_ARCH_ESP8266)\n\n#define MP_LOW_MEM\n//see integer.c\n//default winsize=5(MP_LOW_MEM), but ram(heap) is not sufficient!\n//winsize of {2,3,4,5} are same performance\n//lower winsize, lower ram required\n#define ESP_INTEGER_WINSIZE 2\n//winsize=3 & mp_exptmod_fast : ram(heap) is not sufficient\n//force use s_mp_exptmod (lower memory), and smiller performance with mp_exptmod_fast\n#define ESP_FORCE_S_MP_EXPTMOD\n//winsize = 5 & mp_exptmod_fast 最快，Pair Verify Step 2/2 = 10s左右\n//winsize = 6 heap不够\n\n\n#define MP_16BIT //faster than 32bit in ESP8266\n\n#endif\n\n//#define MP_16BIT //preinit took    7181ms\n//#define MP_28BIT (default)  //preinit took    2285ms\n//#define MP_31BIT   //preinit took    2283ms\n//#define MP_64BIT  //preinit took     350ms //Crypto error, ESP32 NOT support 64bit\n//#define ESP_FORCE_S_MP_EXPTMOD //preinit took    2231ms\n\n#if defined(ARDUINO_HOMEKIT_LOWROM)\n\n#define CURVE25519_SMALL\n#define ED25519_SMALL  //关联ED25519，关闭这个之后编译dram会超（stack mem太大）\n//`.bss' is not within region `dram0_0_seg'\n\n#else\n\n#if defined(ARDUINO_ARCH_ESP8266)\n// crypto.c  crypto_ed25519_verify\n// No sufficient ram to run ge_double_scalarmult_vartime in ge_operations.c\n// Run the ge_double_scalarmult_vartime in ge_low_mem\n#define ESP_GE_DOUBLE_SCALARMULT_VARTIME_LOWMEM\n#endif\n\n#if defined(ARDUINO_ARCH_ESP32)\n//#define HOMEKIT_ESP32_HW_CRYPTO  //See wolfcrypt/src/integer.c\n//#define USE_FAST_MATH\n//#define WOLFSSL_ESPWROOM32\n//#define WOLFSSL_ESPIDF\n\n// copy from WOLFSSL_ESPIDF, but NOT define FREERTOS\n\n#define NO_WRITEV\n#define SIZEOF_LONG_LONG 8\n#define NO_WOLFSSL_DIR\n#define WOLFSSL_NO_CURRDIR\n\n#define TFM_TIMING_RESISTANT\n#define ECC_TIMING_RESISTANT\n#define WC_RSA_BLINDING\n\n#define HAVE_ECC // to enable esp hw mp-functions (big integer). See esp32-crypt.h\n#undef  NO_SHA   // to enable esp hw sha-functions.\n\n//#include \"wolfssl/wolfcrypt/types.h\"\n\n//#include \"wolfssl/wolfcrypt/wc_port.h\"\n//#include \"wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h\"\n\n\n#define WOLFSSL_ESPWROOM32\n#define ESP32_USE_RSA_PRIMITIVE\n\n#if defined(WOLFSSL_ESPWROOM32) || defined(WOLFSSL_ESPWROOM32SE)\n   #ifndef NO_ESP32WROOM32_CRYPT\n        #define WOLFSSL_ESP32WROOM32_CRYPT\n        #if defined(ESP32_USE_RSA_PRIMITIVE) && \\\n            !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)\n            #define WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI\n            #define USE_FAST_MATH\n            #define WOLFSSL_SMALL_STACK\n        #endif\n   #endif\n#endif\n\n/* Define USE_FAST_MATH and SMALL_STACK                        */\n#define ESP32_USE_RSA_PRIMITIVE\n/* threshold for performance adjustment for hw primitive use   */\n/* X bits of G^X mod P greater than                            */\n#define EPS_RSA_EXPT_XBTIS           36\n/* X and Y of X * Y mod P greater than                         */\n#define ESP_RSA_MULM_BITS            2000\n\n// Fix Error: Failed to dump SPR public key (code -1)\n#define FP_MAX_BITS (4096 * 2) // HomeKit need larger integer-bits // See tfm.h and tfm.c (fp_exptmod)\n//==========================\n\n#if !defined(ICACHE_RODATA_ATTR)\n#define ICACHE_RODATA_ATTR   //Empty, compatibility with ESP8266, used in ge_operations.c\n\n#endif\n#endif\n\n#endif\n\n#endif\n"
  },
  {
    "path": "src/watchdog.c",
    "content": "// Base on esp_hw_wdt in github\n/*\n * Copyright (c) 2014-2017 Cesanta Software Limited\n * All rights reserved\n * Changed:\n * 2017 Alexander Epstine (a@epstine.com)\n */\n\n#include \"watchdog.h\"\n#include \"Arduino.h\"\n#include \"stdint.h\"\n#include \"homekit_debug.h\"\n\n#define REG_WDT_BASE 0x60000900\n\n#define WDT_CTL (REG_WDT_BASE + 0x0)\n#define WDT_CTL_ENABLE (BIT(0))\n#define WDT_RESET (REG_WDT_BASE + 0x14)\n#define WDT_RESET_VALUE 0x73\n\nvoid esp_hw_wdt_enable() {\n\tSET_PERI_REG_MASK(WDT_CTL, WDT_CTL_ENABLE);\n}\n\nvoid esp_hw_wdt_disable() {\n\tCLEAR_PERI_REG_MASK(WDT_CTL, WDT_CTL_ENABLE);\n}\n\nvoid esp_hw_wdt_feed() {\n\tWRITE_PERI_REG(WDT_RESET, WDT_RESET_VALUE);\n}\n\n#if defined(ESP8266)\n#include \"user_interface.h\"\nvoid watchdog_disable_all() {\n\tsystem_soft_wdt_stop();\n\tesp_hw_wdt_disable();\n}\n\nvoid watchdog_enable_all() {\n\tesp_hw_wdt_enable();\n\tsystem_soft_wdt_restart();\n}\n\n#else\n\n#endif\n\n#ifdef HOMEKIT_DEBUG\n\nstatic uint32_t wdt_checkpoint;\n\nvoid watchdog_check_begin() {\n\twdt_checkpoint = millis();\n}\n\nvoid watchdog_check_end(const char *message) {\n\tuint32_t d = millis() - wdt_checkpoint;\n\tprintf(\"[WatchDog] Function %s took: %dms\\n\", message, d);\n}\n\n#else\nvoid watchdog_disable_all() {\n}\n\nvoid watchdog_enable_all() {\n}\n\nvoid watchdog_check_begin() {\n}\n\nvoid watchdog_check_end(const char *message) {\n}\n\n#endif\n"
  },
  {
    "path": "src/watchdog.h",
    "content": "#ifndef WATCHDOG_H_\n#define WATCHDOG_H_\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nvoid watchdog_disable_all();\n\nvoid watchdog_enable_all();\n\nvoid watchdog_check_begin();\n\nvoid watchdog_check_end(const char* message);\n\n#ifdef __cplusplus\n}\n#endif\n\n\n#endif /* WATCHDOG_H_ */\n"
  },
  {
    "path": "src/wolfcrypt/src/aes.c",
    "content": "/* aes.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n\n#if !defined(NO_AES)\n\n/* Tip: Locate the software cipher modes by searching for \"Software AES\" */\n\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n\n    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */\n    #define FIPS_NO_WRAPPERS\n\n    #ifdef USE_WINDOWS_API\n        #pragma code_seg(\".fipsA$g\")\n        #pragma const_seg(\".fipsB$g\")\n    #endif\n#endif\n\n#include <wolfssl/wolfcrypt/aes.h>\n#include <wolfssl/wolfcrypt/cpuid.h>\n\n#ifdef WOLF_CRYPTO_CB\n    #include <wolfssl/wolfcrypt/cryptocb.h>\n#endif\n\n\n/* fips wrapper calls, user can call direct */\n#if defined(HAVE_FIPS) && \\\n    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n\n    int wc_AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv,\n                              int dir)\n    {\n        if (aes == NULL ||  !( (len == 16) || (len == 24) || (len == 32)) ) {\n            return BAD_FUNC_ARG;\n        }\n\n        return AesSetKey_fips(aes, key, len, iv, dir);\n    }\n    int wc_AesSetIV(Aes* aes, const byte* iv)\n    {\n        if (aes == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n        return AesSetIV_fips(aes, iv);\n    }\n    #ifdef HAVE_AES_CBC\n        int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n        {\n            if (aes == NULL || out == NULL || in == NULL) {\n                return BAD_FUNC_ARG;\n            }\n\n            return AesCbcEncrypt_fips(aes, out, in, sz);\n        }\n        #ifdef HAVE_AES_DECRYPT\n            int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n            {\n                if (aes == NULL || out == NULL || in == NULL\n                                            || sz % AES_BLOCK_SIZE != 0) {\n                    return BAD_FUNC_ARG;\n                }\n\n                return AesCbcDecrypt_fips(aes, out, in, sz);\n            }\n        #endif /* HAVE_AES_DECRYPT */\n    #endif /* HAVE_AES_CBC */\n\n    /* AES-CTR */\n    #ifdef WOLFSSL_AES_COUNTER\n        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n        {\n            if (aes == NULL || out == NULL || in == NULL) {\n                return BAD_FUNC_ARG;\n            }\n\n            return AesCtrEncrypt(aes, out, in, sz);\n        }\n    #endif\n\n    /* AES-DIRECT */\n    #if defined(WOLFSSL_AES_DIRECT)\n        void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)\n        {\n            AesEncryptDirect(aes, out, in);\n        }\n\n        #ifdef HAVE_AES_DECRYPT\n            void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)\n            {\n                AesDecryptDirect(aes, out, in);\n            }\n        #endif /* HAVE_AES_DECRYPT */\n\n        int wc_AesSetKeyDirect(Aes* aes, const byte* key, word32 len,\n                                        const byte* iv, int dir)\n        {\n            return AesSetKeyDirect(aes, key, len, iv, dir);\n        }\n    #endif /* WOLFSSL_AES_DIRECT */\n\n    /* AES-GCM */\n    #ifdef HAVE_AESGCM\n        int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)\n        {\n            if (aes == NULL || !( (len == 16) || (len == 24) || (len == 32)) ) {\n                return BAD_FUNC_ARG;\n            }\n\n            return AesGcmSetKey_fips(aes, key, len);\n        }\n        int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,\n                                      const byte* iv, word32 ivSz,\n                                      byte* authTag, word32 authTagSz,\n                                      const byte* authIn, word32 authInSz)\n        {\n            if (aes == NULL || authTagSz > AES_BLOCK_SIZE\n                                    || authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ ||\n                                    ivSz > AES_BLOCK_SIZE) {\n                return BAD_FUNC_ARG;\n            }\n\n            return AesGcmEncrypt_fips(aes, out, in, sz, iv, ivSz, authTag,\n                authTagSz, authIn, authInSz);\n        }\n\n        #ifdef HAVE_AES_DECRYPT\n            int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,\n                                          const byte* iv, word32 ivSz,\n                                          const byte* authTag, word32 authTagSz,\n                                          const byte* authIn, word32 authInSz)\n            {\n                if (aes == NULL || out == NULL || in == NULL || iv == NULL\n                        || authTag == NULL || authTagSz > AES_BLOCK_SIZE ||\n                        ivSz > AES_BLOCK_SIZE) {\n                    return BAD_FUNC_ARG;\n                }\n\n                return AesGcmDecrypt_fips(aes, out, in, sz, iv, ivSz, authTag,\n                    authTagSz, authIn, authInSz);\n            }\n        #endif /* HAVE_AES_DECRYPT */\n\n        int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)\n        {\n            if (gmac == NULL || key == NULL || !((len == 16) ||\n                                (len == 24) || (len == 32)) ) {\n                return BAD_FUNC_ARG;\n            }\n\n            return GmacSetKey(gmac, key, len);\n        }\n        int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,\n                                      const byte* authIn, word32 authInSz,\n                                      byte* authTag, word32 authTagSz)\n        {\n            if (gmac == NULL || authTagSz > AES_BLOCK_SIZE ||\n                               authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {\n                return BAD_FUNC_ARG;\n            }\n\n            return GmacUpdate(gmac, iv, ivSz, authIn, authInSz,\n                              authTag, authTagSz);\n        }\n    #endif /* HAVE_AESGCM */\n\n    /* AES-CCM */\n    #if defined(HAVE_AESCCM) && \\\n        defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n        int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)\n        {\n            return AesCcmSetKey(aes, key, keySz);\n        }\n        int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,\n                                      const byte* nonce, word32 nonceSz,\n                                      byte* authTag, word32 authTagSz,\n                                      const byte* authIn, word32 authInSz)\n        {\n            /* sanity check on arguments */\n            if (aes == NULL || out == NULL || in == NULL || nonce == NULL\n                    || authTag == NULL || nonceSz < 7 || nonceSz > 13)\n                return BAD_FUNC_ARG;\n\n            AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz, authTag,\n                authTagSz, authIn, authInSz);\n            return 0;\n        }\n\n        #ifdef HAVE_AES_DECRYPT\n            int  wc_AesCcmDecrypt(Aes* aes, byte* out,\n                const byte* in, word32 inSz,\n                const byte* nonce, word32 nonceSz,\n                const byte* authTag, word32 authTagSz,\n                const byte* authIn, word32 authInSz)\n            {\n\n                if (aes == NULL || out == NULL || in == NULL || nonce == NULL\n                    || authTag == NULL || nonceSz < 7 || nonceSz > 13) {\n                        return BAD_FUNC_ARG;\n                }\n\n                return AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,\n                    authTag, authTagSz, authIn, authInSz);\n            }\n        #endif /* HAVE_AES_DECRYPT */\n    #endif /* HAVE_AESCCM && HAVE_FIPS_VERSION 2 */\n\n    int wc_AesInit(Aes* aes, void* h, int i)\n    {\n        if (aes == NULL)\n            return BAD_FUNC_ARG;\n\n        (void)h;\n        (void)i;\n\n        /* FIPS doesn't support:\n            return AesInit(aes, h, i); */\n        return 0;\n    }\n    void wc_AesFree(Aes* aes)\n    {\n        (void)aes;\n        /* FIPS doesn't support:\n            AesFree(aes); */\n    }\n\n#else /* else build without fips, or for FIPS v2 */\n\n\n#if defined(WOLFSSL_TI_CRYPT)\n    #include <wolfcrypt/src/port/ti/ti-aes.c>\n#else\n\n#include <wolfssl/wolfcrypt/logging.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#if !defined(WOLFSSL_ARMASM)\n\n#ifdef WOLFSSL_IMX6_CAAM_BLOB\n    /* case of possibly not using hardware acceleration for AES but using key\n       blobs */\n    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>\n#endif\n\n#ifdef DEBUG_AESNI\n    #include <stdio.h>\n#endif\n\n#ifdef _MSC_VER\n    /* 4127 warning constant while(1)  */\n    #pragma warning(disable: 4127)\n#endif\n\n\n/* Define AES implementation includes and functions */\n#if defined(STM32_CRYPTO)\n     /* STM32F2/F4/F7/L4 hardware AES support for ECB, CBC, CTR and GCM modes */\n\n#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM)\n\n    static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n    {\n        int ret = 0;\n    #ifdef WOLFSSL_STM32_CUBEMX\n        CRYP_HandleTypeDef hcryp;\n    #else\n        CRYP_InitTypeDef cryptInit;\n        CRYP_KeyInitTypeDef keyInit;\n    #endif\n\n    #ifdef WOLFSSL_STM32_CUBEMX\n        ret = wc_Stm32_Aes_Init(aes, &hcryp);\n        if (ret != 0)\n            return ret;\n\n    #ifdef STM32_CRYPTO_AES_ONLY\n        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;\n        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;\n        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;\n    #elif defined(STM32_HAL_V2)\n        hcryp.Init.Algorithm  = CRYP_AES_ECB;\n    #endif\n        HAL_CRYP_Init(&hcryp);\n\n    #ifdef STM32_CRYPTO_AES_ONLY\n        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,\n            outBlock, STM32_HAL_TIMEOUT);\n    #elif defined(STM32_HAL_V2)\n        ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, AES_BLOCK_SIZE,\n            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);\n    #else\n        ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,\n            outBlock, STM32_HAL_TIMEOUT);\n    #endif\n        if (ret != HAL_OK) {\n            ret = WC_TIMEOUT_E;\n        }\n        HAL_CRYP_DeInit(&hcryp);\n\n    #else /* STD_PERI_LIB */\n        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);\n        if (ret != 0)\n            return ret;\n\n        /* reset registers to their default values */\n        CRYP_DeInit();\n\n        /* setup key */\n        CRYP_KeyInit(&keyInit);\n\n        /* set direction and mode */\n        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;\n        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;\n        CRYP_Init(&cryptInit);\n\n        /* enable crypto processor */\n        CRYP_Cmd(ENABLE);\n\n        /* flush IN/OUT FIFOs */\n        CRYP_FIFOFlush();\n\n        CRYP_DataIn(*(uint32_t*)&inBlock[0]);\n        CRYP_DataIn(*(uint32_t*)&inBlock[4]);\n        CRYP_DataIn(*(uint32_t*)&inBlock[8]);\n        CRYP_DataIn(*(uint32_t*)&inBlock[12]);\n\n        /* wait until the complete message has been processed */\n        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}\n\n        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();\n        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();\n        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();\n        *(uint32_t*)&outBlock[12] = CRYP_DataOut();\n\n        /* disable crypto processor */\n        CRYP_Cmd(DISABLE);\n    #endif /* WOLFSSL_STM32_CUBEMX */\n\n        return ret;\n    }\n#endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */\n\n#ifdef HAVE_AES_DECRYPT\n    #if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM)\n    static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n    {\n        int ret = 0;\n    #ifdef WOLFSSL_STM32_CUBEMX\n        CRYP_HandleTypeDef hcryp;\n    #else\n        CRYP_InitTypeDef cryptInit;\n        CRYP_KeyInitTypeDef keyInit;\n    #endif\n\n    #ifdef WOLFSSL_STM32_CUBEMX\n        ret = wc_Stm32_Aes_Init(aes, &hcryp);\n        if (ret != 0)\n            return ret;\n\n    #ifdef STM32_CRYPTO_AES_ONLY\n        hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;\n        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;\n        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;\n    #elif defined(STM32_HAL_V2)\n        hcryp.Init.Algorithm  = CRYP_AES_ECB;\n    #endif\n        HAL_CRYP_Init(&hcryp);\n\n    #ifdef STM32_CRYPTO_AES_ONLY\n        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,\n            outBlock, STM32_HAL_TIMEOUT);\n    #elif defined(STM32_HAL_V2)\n        ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, AES_BLOCK_SIZE,\n            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);\n    #else\n        ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,\n            outBlock, STM32_HAL_TIMEOUT);\n    #endif\n        if (ret != HAL_OK) {\n            ret = WC_TIMEOUT_E;\n        }\n        HAL_CRYP_DeInit(&hcryp);\n\n    #else /* STD_PERI_LIB */\n        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);\n        if (ret != 0)\n            return ret;\n\n        /* reset registers to their default values */\n        CRYP_DeInit();\n\n        /* set direction and key */\n        CRYP_KeyInit(&keyInit);\n        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;\n        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;\n        CRYP_Init(&cryptInit);\n\n        /* enable crypto processor */\n        CRYP_Cmd(ENABLE);\n\n        /* wait until decrypt key has been initialized */\n        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}\n\n        /* set direction and mode */\n        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;\n        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;\n        CRYP_Init(&cryptInit);\n\n        /* enable crypto processor */\n        CRYP_Cmd(ENABLE);\n\n        /* flush IN/OUT FIFOs */\n        CRYP_FIFOFlush();\n\n        CRYP_DataIn(*(uint32_t*)&inBlock[0]);\n        CRYP_DataIn(*(uint32_t*)&inBlock[4]);\n        CRYP_DataIn(*(uint32_t*)&inBlock[8]);\n        CRYP_DataIn(*(uint32_t*)&inBlock[12]);\n\n        /* wait until the complete message has been processed */\n        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}\n\n        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();\n        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();\n        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();\n        *(uint32_t*)&outBlock[12] = CRYP_DataOut();\n\n        /* disable crypto processor */\n        CRYP_Cmd(DISABLE);\n    #endif /* WOLFSSL_STM32_CUBEMX */\n\n        return ret;\n    }\n    #endif /* WOLFSSL_AES_DIRECT || HAVE_AESCCM */\n#endif /* HAVE_AES_DECRYPT */\n\n#elif defined(HAVE_COLDFIRE_SEC)\n    /* Freescale Coldfire SEC support for CBC mode.\n     * NOTE: no support for AES-CTR/GCM/CCM/Direct */\n    #include <wolfssl/wolfcrypt/types.h>\n    #include \"sec.h\"\n    #include \"mcf5475_sec.h\"\n    #include \"mcf5475_siu.h\"\n#elif defined(FREESCALE_LTC)\n    #include \"fsl_ltc.h\"\n    #if defined(FREESCALE_LTC_AES_GCM)\n        #undef NEED_AES_TABLES\n        #undef GCM_TABLE\n    #else\n        /* if LTC doesn't have GCM, use software with LTC AES ECB mode */\n        static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n        {\n            wc_AesEncryptDirect(aes, outBlock, inBlock);\n            return 0;\n        }\n        static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n        {\n            wc_AesDecryptDirect(aes, outBlock, inBlock);\n            return 0;\n        }\n    #endif\n#elif defined(FREESCALE_MMCAU)\n    /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes\n     * through the CAU/mmCAU library. Documentation located in\n     * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User\n     * Guide (See note in README). */\n    #ifdef FREESCALE_MMCAU_CLASSIC\n        /* MMCAU 1.4 library used with non-KSDK / classic MQX builds */\n        #include \"cau_api.h\"\n    #else\n        #include \"fsl_mmcau.h\"\n    #endif\n\n    static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n    {\n        int ret;\n\n    #ifdef FREESCALE_MMCAU_CLASSIC\n        if ((wolfssl_word)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {\n            WOLFSSL_MSG(\"Bad cau_aes_encrypt alignment\");\n            return BAD_ALIGN_E;\n        }\n    #endif\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if(ret == 0) {\n        #ifdef FREESCALE_MMCAU_CLASSIC\n            cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);\n        #else\n            MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds,\n                                 outBlock);\n        #endif\n            wolfSSL_CryptHwMutexUnLock();\n        }\n        return ret;\n    }\n    #ifdef HAVE_AES_DECRYPT\n    static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n    {\n        int ret;\n\n    #ifdef FREESCALE_MMCAU_CLASSIC\n        if ((wolfssl_word)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {\n            WOLFSSL_MSG(\"Bad cau_aes_decrypt alignment\");\n            return BAD_ALIGN_E;\n        }\n    #endif\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if(ret == 0) {\n        #ifdef FREESCALE_MMCAU_CLASSIC\n            cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);\n        #else\n            MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds,\n                                 outBlock);\n        #endif\n            wolfSSL_CryptHwMutexUnLock();\n        }\n        return ret;\n    }\n    #endif /* HAVE_AES_DECRYPT */\n\n#elif defined(WOLFSSL_PIC32MZ_CRYPT)\n\n    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>\n\n    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)\n    static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n    {\n        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,\n            outBlock, inBlock, AES_BLOCK_SIZE,\n            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);\n    }\n    #endif\n\n    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)\n    static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n    {\n        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,\n            outBlock, inBlock, AES_BLOCK_SIZE,\n            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);\n    }\n    #endif\n\n#elif defined(WOLFSSL_NRF51_AES)\n    /* Use built-in AES hardware - AES 128 ECB Encrypt Only */\n    #include \"wolfssl/wolfcrypt/port/nrf51.h\"\n\n    static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n    {\n        return nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);\n    }\n\n    #ifdef HAVE_AES_DECRYPT\n        #error nRF51 AES Hardware does not support decrypt\n    #endif /* HAVE_AES_DECRYPT */\n\n#elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)\n\n    #include \"wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h\"\n\n    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)\n    static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n    {\n        return wc_esp32AesEncrypt(aes, inBlock, outBlock);\n    }\n    #endif\n\n    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)\n    static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n    {\n       return wc_esp32AesDecrypt(aes, inBlock, outBlock);\n    }\n    #endif\n\n#elif defined(WOLFSSL_AESNI)\n\n    #define NEED_AES_TABLES\n\n    /* Each platform needs to query info type 1 from cpuid to see if aesni is\n     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts\n     */\n\n    #ifndef AESNI_ALIGN\n        #define AESNI_ALIGN 16\n    #endif\n\n    #ifdef _MSC_VER\n        #define XASM_LINK(f)\n    #elif defined(__APPLE__)\n        #define XASM_LINK(f) asm(\"_\" f)\n    #else\n        #define XASM_LINK(f) asm(f)\n    #endif /* _MSC_VER */\n\n    static int checkAESNI = 0;\n    static int haveAESNI  = 0;\n    static word32 intel_flags = 0;\n\n    static int Check_CPU_support_AES(void)\n    {\n        intel_flags = cpuid_get_flags();\n\n        return IS_INTEL_AESNI(intel_flags) != 0;\n    }\n\n\n    /* tell C compiler these are asm functions in case any mix up of ABI underscore\n       prefix between clang/gcc/llvm etc */\n    #ifdef HAVE_AES_CBC\n        void AES_CBC_encrypt(const unsigned char* in, unsigned char* out,\n                             unsigned char* ivec, unsigned long length,\n                             const unsigned char* KS, int nr)\n                             XASM_LINK(\"AES_CBC_encrypt\");\n\n        #ifdef HAVE_AES_DECRYPT\n            #if defined(WOLFSSL_AESNI_BY4)\n                void AES_CBC_decrypt_by4(const unsigned char* in, unsigned char* out,\n                                         unsigned char* ivec, unsigned long length,\n                                         const unsigned char* KS, int nr)\n                                         XASM_LINK(\"AES_CBC_decrypt_by4\");\n            #elif defined(WOLFSSL_AESNI_BY6)\n                void AES_CBC_decrypt_by6(const unsigned char* in, unsigned char* out,\n                                         unsigned char* ivec, unsigned long length,\n                                         const unsigned char* KS, int nr)\n                                         XASM_LINK(\"AES_CBC_decrypt_by6\");\n            #else /* WOLFSSL_AESNI_BYx */\n                void AES_CBC_decrypt_by8(const unsigned char* in, unsigned char* out,\n                                         unsigned char* ivec, unsigned long length,\n                                         const unsigned char* KS, int nr)\n                                         XASM_LINK(\"AES_CBC_decrypt_by8\");\n            #endif /* WOLFSSL_AESNI_BYx */\n        #endif /* HAVE_AES_DECRYPT */\n    #endif /* HAVE_AES_CBC */\n\n    void AES_ECB_encrypt(const unsigned char* in, unsigned char* out,\n                         unsigned long length, const unsigned char* KS, int nr)\n                         XASM_LINK(\"AES_ECB_encrypt\");\n\n    #ifdef HAVE_AES_DECRYPT\n        void AES_ECB_decrypt(const unsigned char* in, unsigned char* out,\n                             unsigned long length, const unsigned char* KS, int nr)\n                             XASM_LINK(\"AES_ECB_decrypt\");\n    #endif\n\n    void AES_128_Key_Expansion(const unsigned char* userkey,\n                               unsigned char* key_schedule)\n                               XASM_LINK(\"AES_128_Key_Expansion\");\n\n    void AES_192_Key_Expansion(const unsigned char* userkey,\n                               unsigned char* key_schedule)\n                               XASM_LINK(\"AES_192_Key_Expansion\");\n\n    void AES_256_Key_Expansion(const unsigned char* userkey,\n                               unsigned char* key_schedule)\n                               XASM_LINK(\"AES_256_Key_Expansion\");\n\n\n    static int AES_set_encrypt_key(const unsigned char *userKey, const int bits,\n                                   Aes* aes)\n    {\n        int ret;\n\n        if (!userKey || !aes)\n            return BAD_FUNC_ARG;\n\n        switch (bits) {\n            case 128:\n               AES_128_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 10;\n               return 0;\n            case 192:\n               AES_192_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 12;\n               return 0;\n            case 256:\n               AES_256_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 14;\n               return 0;\n            default:\n                ret = BAD_FUNC_ARG;\n        }\n\n        return ret;\n    }\n\n    #ifdef HAVE_AES_DECRYPT\n        static int AES_set_decrypt_key(const unsigned char* userKey,\n                                                    const int bits, Aes* aes)\n        {\n            int nr;\n            Aes temp_key;\n            __m128i *Key_Schedule = (__m128i*)aes->key;\n            __m128i *Temp_Key_Schedule = (__m128i*)temp_key.key;\n\n            if (!userKey || !aes)\n                return BAD_FUNC_ARG;\n\n            if (AES_set_encrypt_key(userKey,bits,&temp_key) == BAD_FUNC_ARG)\n                return BAD_FUNC_ARG;\n\n            nr = temp_key.rounds;\n            aes->rounds = nr;\n\n            Key_Schedule[nr] = Temp_Key_Schedule[0];\n            Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);\n            Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);\n            Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);\n            Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);\n            Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);\n            Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);\n            Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);\n            Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);\n            Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);\n\n            if (nr>10) {\n                Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);\n                Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);\n            }\n\n            if (nr>12) {\n                Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);\n                Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);\n            }\n\n            Key_Schedule[0] = Temp_Key_Schedule[nr];\n\n            return 0;\n        }\n    #endif /* HAVE_AES_DECRYPT */\n\n#elif (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)) || \\\n      ((defined(WOLFSSL_AFALG) || defined(WOLFSSL_DEVCRYPTO_AES)) && \\\n        defined(HAVE_AESCCM))\n        static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n        {\n            wc_AesEncryptDirect(aes, outBlock, inBlock);\n            return 0;\n        }\n\n#elif defined(WOLFSSL_AFALG)\n#elif defined(WOLFSSL_DEVCRYPTO_AES)\n#else\n\n    /* using wolfCrypt software implementation */\n    #define NEED_AES_TABLES\n#endif\n\n\n\n#ifdef NEED_AES_TABLES\n\nstatic const word32 rcon[] = {\n    0x01000000, 0x02000000, 0x04000000, 0x08000000,\n    0x10000000, 0x20000000, 0x40000000, 0x80000000,\n    0x1B000000, 0x36000000,\n    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */\n};\n\nstatic const word32 Te[4][256] = {\n{\n    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,\n    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,\n    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,\n    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,\n    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,\n    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,\n    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,\n    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,\n    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,\n    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,\n    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,\n    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,\n    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,\n    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,\n    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,\n    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,\n    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,\n    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,\n    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,\n    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,\n    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,\n    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,\n    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,\n    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,\n    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,\n    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,\n    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,\n    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,\n    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,\n    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,\n    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,\n    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,\n    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,\n    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,\n    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,\n    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,\n    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,\n    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,\n    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,\n    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,\n    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,\n    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,\n    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,\n    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,\n    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,\n    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,\n    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,\n    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,\n    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,\n    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,\n    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,\n    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,\n    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,\n    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,\n    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,\n    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,\n    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,\n    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,\n    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,\n    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,\n    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,\n    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,\n    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,\n    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,\n},\n{\n    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,\n    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,\n    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,\n    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,\n    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,\n    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,\n    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,\n    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,\n    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,\n    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,\n    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,\n    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,\n    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,\n    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,\n    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,\n    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,\n    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,\n    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,\n    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,\n    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,\n    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,\n    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,\n    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,\n    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,\n    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,\n    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,\n    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,\n    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,\n    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,\n    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,\n    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,\n    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,\n    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,\n    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,\n    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,\n    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,\n    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,\n    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,\n    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,\n    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,\n    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,\n    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,\n    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,\n    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,\n    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,\n    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,\n    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,\n    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,\n    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,\n    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,\n    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,\n    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,\n    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,\n    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,\n    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,\n    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,\n    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,\n    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,\n    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,\n    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,\n    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,\n    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,\n    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,\n    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,\n},\n{\n    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,\n    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,\n    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,\n    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,\n    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,\n    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,\n    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,\n    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,\n    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,\n    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,\n    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,\n    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,\n    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,\n    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,\n    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,\n    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,\n    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,\n    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,\n    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,\n    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,\n    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,\n    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,\n    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,\n    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,\n    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,\n    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,\n    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,\n    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,\n    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,\n    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,\n    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,\n    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,\n    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,\n    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,\n    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,\n    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,\n    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,\n    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,\n    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,\n    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,\n    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,\n    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,\n    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,\n    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,\n    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,\n    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,\n    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,\n    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,\n    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,\n    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,\n    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,\n    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,\n    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,\n    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,\n    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,\n    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,\n    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,\n    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,\n    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,\n    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,\n    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,\n    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,\n    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,\n    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,\n},\n{\n    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,\n    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,\n    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,\n    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,\n    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,\n    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,\n    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,\n    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,\n    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,\n    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,\n    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,\n    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,\n    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,\n    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,\n    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,\n    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,\n    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,\n    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,\n    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,\n    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,\n    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,\n    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,\n    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,\n    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,\n    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,\n    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,\n    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,\n    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,\n    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,\n    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,\n    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,\n    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,\n    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,\n    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,\n    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,\n    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,\n    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,\n    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,\n    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,\n    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,\n    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,\n    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,\n    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,\n    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,\n    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,\n    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,\n    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,\n    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,\n    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,\n    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,\n    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,\n    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,\n    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,\n    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,\n    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,\n    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,\n    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,\n    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,\n    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,\n    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,\n    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,\n    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,\n    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,\n    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,\n}\n};\n\n#ifdef HAVE_AES_DECRYPT\nstatic const word32 Td[4][256] = {\n{\n    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,\n    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,\n    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,\n    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,\n    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,\n    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,\n    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,\n    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,\n    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,\n    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,\n    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,\n    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,\n    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,\n    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,\n    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,\n    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,\n    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,\n    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,\n    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,\n    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,\n    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,\n    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,\n    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,\n    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,\n    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,\n    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,\n    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,\n    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,\n    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,\n    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,\n    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,\n    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,\n    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,\n    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,\n    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,\n    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,\n    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,\n    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,\n    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,\n    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,\n    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,\n    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,\n    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,\n    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,\n    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,\n    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,\n    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,\n    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,\n    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,\n    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,\n    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,\n    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,\n    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,\n    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,\n    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,\n    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,\n    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,\n    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,\n    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,\n    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,\n    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,\n    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,\n    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,\n    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,\n},\n{\n    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,\n    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,\n    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,\n    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,\n    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,\n    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,\n    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,\n    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,\n    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,\n    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,\n    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,\n    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,\n    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,\n    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,\n    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,\n    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,\n    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,\n    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,\n    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,\n    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,\n    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,\n    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,\n    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,\n    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,\n    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,\n    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,\n    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,\n    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,\n    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,\n    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,\n    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,\n    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,\n    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,\n    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,\n    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,\n    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,\n    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,\n    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,\n    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,\n    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,\n    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,\n    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,\n    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,\n    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,\n    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,\n    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,\n    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,\n    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,\n    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,\n    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,\n    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,\n    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,\n    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,\n    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,\n    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,\n    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,\n    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,\n    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,\n    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,\n    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,\n    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,\n    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,\n    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,\n    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,\n},\n{\n    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,\n    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,\n    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,\n    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,\n    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,\n    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,\n    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,\n    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,\n    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,\n    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,\n    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,\n    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,\n    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,\n    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,\n    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,\n    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,\n    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,\n    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,\n    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,\n    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,\n\n    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,\n    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,\n    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,\n    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,\n    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,\n    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,\n    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,\n    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,\n    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,\n    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,\n    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,\n    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,\n    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,\n    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,\n    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,\n    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,\n    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,\n    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,\n    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,\n    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,\n    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,\n    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,\n    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,\n    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,\n    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,\n    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,\n    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,\n    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,\n    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,\n    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,\n    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,\n    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,\n    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,\n    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,\n    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,\n    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,\n    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,\n    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,\n    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,\n    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,\n    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,\n    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,\n    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,\n    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,\n},\n{\n    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,\n    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,\n    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,\n    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,\n    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,\n    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,\n    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,\n    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,\n    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,\n    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,\n    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,\n    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,\n    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,\n    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,\n    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,\n    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,\n    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,\n    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,\n    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,\n    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,\n    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,\n    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,\n    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,\n    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,\n    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,\n    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,\n    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,\n    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,\n    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,\n    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,\n    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,\n    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,\n    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,\n    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,\n    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,\n    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,\n    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,\n    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,\n    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,\n    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,\n    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,\n    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,\n    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,\n    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,\n    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,\n    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,\n    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,\n    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,\n    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,\n    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,\n    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,\n    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,\n    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,\n    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,\n    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,\n    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,\n    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,\n    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,\n    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,\n    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,\n    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,\n    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,\n    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,\n    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,\n}\n};\n\n\n#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) \\\n\t\t\t|| defined(WOLFSSL_AES_DIRECT)\nstatic const byte Td4[256] =\n{\n    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,\n    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,\n    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,\n    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,\n    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,\n    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,\n    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,\n    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,\n    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,\n    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,\n    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,\n    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,\n    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,\n    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,\n    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,\n    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,\n    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,\n    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,\n    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,\n    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,\n    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,\n    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,\n    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,\n    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,\n    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,\n    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,\n    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,\n    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,\n    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,\n    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,\n    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,\n    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,\n};\n#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */\n#endif /* HAVE_AES_DECRYPT */\n\n#define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))\n\n\n\n#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM)\n\n#ifndef WC_CACHE_LINE_SZ\n    #if defined(__x86_64__) || defined(_M_X64) || \\\n       (defined(__ILP32__) && (__ILP32__ >= 1))\n        #define WC_CACHE_LINE_SZ 64\n    #else\n        /* default cache line size */\n        #define WC_CACHE_LINE_SZ 32\n    #endif\n#endif\n\n\n/* load 4 Te Tables into cache by cache line stride */\nstatic WC_INLINE word32 PreFetchTe(void)\n{\n    word32 x = 0;\n    int i,j;\n\n    for (i = 0; i < 4; i++) {\n        /* 256 elements, each one is 4 bytes */\n        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {\n            x &= Te[i][j];\n        }\n    }\n    return x;\n}\n\n/* Software AES - ECB Encrypt */\nstatic void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n{\n    word32 s0, s1, s2, s3;\n    word32 t0, t1, t2, t3;\n    word32 r = aes->rounds >> 1;\n    const word32* rk = aes->key;\n\n    if (r > 7 || r == 0) {\n        WOLFSSL_MSG(\"AesEncrypt encountered improper key, set it up\");\n        return;  /* stop instead of seg-faulting, set up your keys! */\n    }\n\n#ifdef WOLFSSL_AESNI\n    if (haveAESNI && aes->use_aesni) {\n        #ifdef DEBUG_AESNI\n            printf(\"about to aes encrypt\\n\");\n            printf(\"in  = %p\\n\", inBlock);\n            printf(\"out = %p\\n\", outBlock);\n            printf(\"aes->key = %p\\n\", aes->key);\n            printf(\"aes->rounds = %d\\n\", aes->rounds);\n            printf(\"sz = %d\\n\", AES_BLOCK_SIZE);\n        #endif\n\n        /* check alignment, decrypt doesn't need alignment */\n        if ((wolfssl_word)inBlock % AESNI_ALIGN) {\n        #ifndef NO_WOLFSSL_ALLOC_ALIGN\n            byte* tmp = (byte*)XMALLOC(AES_BLOCK_SIZE + AESNI_ALIGN, aes->heap,\n                                                      DYNAMIC_TYPE_TMP_BUFFER);\n            byte* tmp_align;\n            if (tmp == NULL) return;\n\n            tmp_align = tmp + (AESNI_ALIGN - ((size_t)tmp % AESNI_ALIGN));\n\n            XMEMCPY(tmp_align, inBlock, AES_BLOCK_SIZE);\n            AES_ECB_encrypt(tmp_align, tmp_align, AES_BLOCK_SIZE, (byte*)aes->key,\n                            aes->rounds);\n            XMEMCPY(outBlock, tmp_align, AES_BLOCK_SIZE);\n            XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            return;\n        #else\n            WOLFSSL_MSG(\"AES-ECB encrypt with bad alignment\");\n            return;\n        #endif\n        }\n\n        AES_ECB_encrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,\n                        aes->rounds);\n\n        return;\n    }\n    else {\n        #ifdef DEBUG_AESNI\n            printf(\"Skipping AES-NI\\n\");\n        #endif\n    }\n#endif\n\n    /*\n     * map byte array block to cipher state\n     * and add initial round key:\n     */\n    XMEMCPY(&s0, inBlock,                  sizeof(s0));\n    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));\n    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));\n    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));\n\n#ifdef LITTLE_ENDIAN_ORDER\n    s0 = ByteReverseWord32(s0);\n    s1 = ByteReverseWord32(s1);\n    s2 = ByteReverseWord32(s2);\n    s3 = ByteReverseWord32(s3);\n#endif\n\n    s0 ^= rk[0];\n    s1 ^= rk[1];\n    s2 ^= rk[2];\n    s3 ^= rk[3];\n\n    s0 |= PreFetchTe();\n\n    /*\n     * Nr - 1 full rounds:\n     */\n\n    for (;;) {\n        t0 =\n            Te[0][GETBYTE(s0, 3)]  ^\n            Te[1][GETBYTE(s1, 2)]  ^\n            Te[2][GETBYTE(s2, 1)]  ^\n            Te[3][GETBYTE(s3, 0)]  ^\n            rk[4];\n        t1 =\n            Te[0][GETBYTE(s1, 3)]  ^\n            Te[1][GETBYTE(s2, 2)]  ^\n            Te[2][GETBYTE(s3, 1)]  ^\n            Te[3][GETBYTE(s0, 0)]  ^\n            rk[5];\n        t2 =\n            Te[0][GETBYTE(s2, 3)] ^\n            Te[1][GETBYTE(s3, 2)]  ^\n            Te[2][GETBYTE(s0, 1)]  ^\n            Te[3][GETBYTE(s1, 0)]  ^\n            rk[6];\n        t3 =\n            Te[0][GETBYTE(s3, 3)] ^\n            Te[1][GETBYTE(s0, 2)]  ^\n            Te[2][GETBYTE(s1, 1)]  ^\n            Te[3][GETBYTE(s2, 0)]  ^\n            rk[7];\n\n        rk += 8;\n        if (--r == 0) {\n            break;\n        }\n\n        s0 =\n            Te[0][GETBYTE(t0, 3)] ^\n            Te[1][GETBYTE(t1, 2)] ^\n            Te[2][GETBYTE(t2, 1)] ^\n            Te[3][GETBYTE(t3, 0)] ^\n            rk[0];\n        s1 =\n            Te[0][GETBYTE(t1, 3)] ^\n            Te[1][GETBYTE(t2, 2)] ^\n            Te[2][GETBYTE(t3, 1)] ^\n            Te[3][GETBYTE(t0, 0)] ^\n            rk[1];\n        s2 =\n            Te[0][GETBYTE(t2, 3)] ^\n            Te[1][GETBYTE(t3, 2)] ^\n            Te[2][GETBYTE(t0, 1)] ^\n            Te[3][GETBYTE(t1, 0)] ^\n            rk[2];\n        s3 =\n            Te[0][GETBYTE(t3, 3)] ^\n            Te[1][GETBYTE(t0, 2)] ^\n            Te[2][GETBYTE(t1, 1)] ^\n            Te[3][GETBYTE(t2, 0)] ^\n            rk[3];\n    }\n\n    /*\n     * apply last round and\n     * map cipher state to byte array block:\n     */\n\n    s0 =\n        (Te[2][GETBYTE(t0, 3)] & 0xff000000) ^\n        (Te[3][GETBYTE(t1, 2)] & 0x00ff0000) ^\n        (Te[0][GETBYTE(t2, 1)] & 0x0000ff00) ^\n        (Te[1][GETBYTE(t3, 0)] & 0x000000ff) ^\n        rk[0];\n    s1 =\n        (Te[2][GETBYTE(t1, 3)] & 0xff000000) ^\n        (Te[3][GETBYTE(t2, 2)] & 0x00ff0000) ^\n        (Te[0][GETBYTE(t3, 1)] & 0x0000ff00) ^\n        (Te[1][GETBYTE(t0, 0)] & 0x000000ff) ^\n        rk[1];\n    s2 =\n        (Te[2][GETBYTE(t2, 3)] & 0xff000000) ^\n        (Te[3][GETBYTE(t3, 2)] & 0x00ff0000) ^\n        (Te[0][GETBYTE(t0, 1)] & 0x0000ff00) ^\n        (Te[1][GETBYTE(t1, 0)] & 0x000000ff) ^\n        rk[2];\n    s3 =\n        (Te[2][GETBYTE(t3, 3)] & 0xff000000) ^\n        (Te[3][GETBYTE(t0, 2)] & 0x00ff0000) ^\n        (Te[0][GETBYTE(t1, 1)] & 0x0000ff00) ^\n        (Te[1][GETBYTE(t2, 0)] & 0x000000ff) ^\n        rk[3];\n\n    /* write out */\n#ifdef LITTLE_ENDIAN_ORDER\n    s0 = ByteReverseWord32(s0);\n    s1 = ByteReverseWord32(s1);\n    s2 = ByteReverseWord32(s2);\n    s3 = ByteReverseWord32(s3);\n#endif\n\n    XMEMCPY(outBlock,                  &s0, sizeof(s0));\n    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));\n    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));\n    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));\n\n}\n#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */\n\n#if defined(HAVE_AES_DECRYPT)\n#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \\\n     defined(WOLFSSL_AES_DIRECT)\n\n/* load 4 Td Tables into cache by cache line stride */\nstatic WC_INLINE word32 PreFetchTd(void)\n{\n    word32 x = 0;\n    int i,j;\n\n    for (i = 0; i < 4; i++) {\n        /* 256 elements, each one is 4 bytes */\n        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {\n            x &= Td[i][j];\n        }\n    }\n    return x;\n}\n\n/* load Td Table4 into cache by cache line stride */\nstatic WC_INLINE word32 PreFetchTd4(void)\n{\n    word32 x = 0;\n    int i;\n\n    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {\n        x &= (word32)Td4[i];\n    }\n    return x;\n}\n\n/* Software AES - ECB Decrypt */\nstatic void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)\n{\n    word32 s0, s1, s2, s3;\n    word32 t0, t1, t2, t3;\n    word32 r = aes->rounds >> 1;\n\n    const word32* rk = aes->key;\n    if (r > 7 || r == 0) {\n        WOLFSSL_MSG(\"AesDecrypt encountered improper key, set it up\");\n        return;  /* stop instead of seg-faulting, set up your keys! */\n    }\n#ifdef WOLFSSL_AESNI\n    if (haveAESNI && aes->use_aesni) {\n        #ifdef DEBUG_AESNI\n            printf(\"about to aes decrypt\\n\");\n            printf(\"in  = %p\\n\", inBlock);\n            printf(\"out = %p\\n\", outBlock);\n            printf(\"aes->key = %p\\n\", aes->key);\n            printf(\"aes->rounds = %d\\n\", aes->rounds);\n            printf(\"sz = %d\\n\", AES_BLOCK_SIZE);\n        #endif\n\n        /* if input and output same will overwrite input iv */\n        if ((const byte*)aes->tmp != inBlock)\n            XMEMCPY(aes->tmp, inBlock, AES_BLOCK_SIZE);\n        AES_ECB_decrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,\n                        aes->rounds);\n        return;\n    }\n    else {\n        #ifdef DEBUG_AESNI\n            printf(\"Skipping AES-NI\\n\");\n        #endif\n    }\n#endif /* WOLFSSL_AESNI */\n\n    /*\n     * map byte array block to cipher state\n     * and add initial round key:\n     */\n    XMEMCPY(&s0, inBlock,                  sizeof(s0));\n    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));\n    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));\n    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));\n\n#ifdef LITTLE_ENDIAN_ORDER\n    s0 = ByteReverseWord32(s0);\n    s1 = ByteReverseWord32(s1);\n    s2 = ByteReverseWord32(s2);\n    s3 = ByteReverseWord32(s3);\n#endif\n\n    s0 ^= rk[0];\n    s1 ^= rk[1];\n    s2 ^= rk[2];\n    s3 ^= rk[3];\n\n    s0 |= PreFetchTd();\n\n    /*\n     * Nr - 1 full rounds:\n     */\n\n    for (;;) {\n        t0 =\n            Td[0][GETBYTE(s0, 3)] ^\n            Td[1][GETBYTE(s3, 2)] ^\n            Td[2][GETBYTE(s2, 1)] ^\n            Td[3][GETBYTE(s1, 0)] ^\n            rk[4];\n        t1 =\n            Td[0][GETBYTE(s1, 3)] ^\n            Td[1][GETBYTE(s0, 2)] ^\n            Td[2][GETBYTE(s3, 1)] ^\n            Td[3][GETBYTE(s2, 0)] ^\n            rk[5];\n        t2 =\n            Td[0][GETBYTE(s2, 3)] ^\n            Td[1][GETBYTE(s1, 2)] ^\n            Td[2][GETBYTE(s0, 1)] ^\n            Td[3][GETBYTE(s3, 0)] ^\n            rk[6];\n        t3 =\n            Td[0][GETBYTE(s3, 3)] ^\n            Td[1][GETBYTE(s2, 2)] ^\n            Td[2][GETBYTE(s1, 1)] ^\n            Td[3][GETBYTE(s0, 0)] ^\n            rk[7];\n\n        rk += 8;\n        if (--r == 0) {\n            break;\n        }\n\n        s0 =\n            Td[0][GETBYTE(t0, 3)] ^\n            Td[1][GETBYTE(t3, 2)] ^\n            Td[2][GETBYTE(t2, 1)] ^\n            Td[3][GETBYTE(t1, 0)] ^\n            rk[0];\n        s1 =\n            Td[0][GETBYTE(t1, 3)] ^\n            Td[1][GETBYTE(t0, 2)] ^\n            Td[2][GETBYTE(t3, 1)] ^\n            Td[3][GETBYTE(t2, 0)] ^\n            rk[1];\n        s2 =\n            Td[0][GETBYTE(t2, 3)] ^\n            Td[1][GETBYTE(t1, 2)] ^\n            Td[2][GETBYTE(t0, 1)] ^\n            Td[3][GETBYTE(t3, 0)] ^\n            rk[2];\n        s3 =\n            Td[0][GETBYTE(t3, 3)] ^\n            Td[1][GETBYTE(t2, 2)] ^\n            Td[2][GETBYTE(t1, 1)] ^\n            Td[3][GETBYTE(t0, 0)] ^\n            rk[3];\n    }\n    /*\n     * apply last round and\n     * map cipher state to byte array block:\n     */\n\n    t0 |= PreFetchTd4();\n\n    s0 =\n        ((word32)Td4[GETBYTE(t0, 3)] << 24) ^\n        ((word32)Td4[GETBYTE(t3, 2)] << 16) ^\n        ((word32)Td4[GETBYTE(t2, 1)] <<  8) ^\n        ((word32)Td4[GETBYTE(t1, 0)]) ^\n        rk[0];\n    s1 =\n        ((word32)Td4[GETBYTE(t1, 3)] << 24) ^\n        ((word32)Td4[GETBYTE(t0, 2)] << 16) ^\n        ((word32)Td4[GETBYTE(t3, 1)] <<  8) ^\n        ((word32)Td4[GETBYTE(t2, 0)]) ^\n        rk[1];\n    s2 =\n        ((word32)Td4[GETBYTE(t2, 3)] << 24) ^\n        ((word32)Td4[GETBYTE(t1, 2)] << 16) ^\n        ((word32)Td4[GETBYTE(t0, 1)] <<  8) ^\n        ((word32)Td4[GETBYTE(t3, 0)]) ^\n        rk[2];\n    s3 =\n        ((word32)Td4[GETBYTE(t3, 3)] << 24) ^\n        ((word32)Td4[GETBYTE(t2, 2)] << 16) ^\n        ((word32)Td4[GETBYTE(t1, 1)] <<  8) ^\n        ((word32)Td4[GETBYTE(t0, 0)]) ^\n        rk[3];\n\n    /* write out */\n#ifdef LITTLE_ENDIAN_ORDER\n    s0 = ByteReverseWord32(s0);\n    s1 = ByteReverseWord32(s1);\n    s2 = ByteReverseWord32(s2);\n    s3 = ByteReverseWord32(s3);\n#endif\n\n    XMEMCPY(outBlock,                  &s0, sizeof(s0));\n    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));\n    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));\n    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));\n}\n#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */\n#endif /* HAVE_AES_DECRYPT */\n\n#endif /* NEED_AES_TABLES */\n\n\n\n/* wc_AesSetKey */\n#if defined(STM32_CRYPTO)\n\n    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,\n            const byte* iv, int dir)\n    {\n        word32 *rk = aes->key;\n\n        (void)dir;\n\n        if (keylen != 16 &&\n        #ifdef WOLFSSL_AES_192\n            keylen != 24 &&\n        #endif\n            keylen != 32) {\n            return BAD_FUNC_ARG;\n        }\n\n        aes->keylen = keylen;\n        aes->rounds = keylen/4 + 6;\n        XMEMCPY(rk, userKey, keylen);\n    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)\n        ByteReverseWords(rk, rk, keylen);\n    #endif\n    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER)\n        aes->left = 0;\n    #endif\n\n        return wc_AesSetIV(aes, iv);\n    }\n    #if defined(WOLFSSL_AES_DIRECT)\n        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,\n                            const byte* iv, int dir)\n        {\n            return wc_AesSetKey(aes, userKey, keylen, iv, dir);\n        }\n    #endif\n\n#elif defined(HAVE_COLDFIRE_SEC)\n    #if defined (HAVE_THREADX)\n        #include \"memory_pools.h\"\n        extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */\n    #endif\n\n    #define AES_BUFFER_SIZE (AES_BLOCK_SIZE * 64)\n    static unsigned char *AESBuffIn = NULL;\n    static unsigned char *AESBuffOut = NULL;\n    static byte *secReg;\n    static byte *secKey;\n    static volatile SECdescriptorType *secDesc;\n\n    static wolfSSL_Mutex Mutex_AesSEC;\n\n    #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010\n    #define SEC_DESC_AES_CBC_DECRYPT 0x60200010\n\n    extern volatile unsigned char __MBAR[];\n\n    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,\n        const byte* iv, int dir)\n    {\n        if (AESBuffIn == NULL) {\n        #if defined (HAVE_THREADX)\n            int s1, s2, s3, s4, s5;\n            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,\n                                  sizeof(SECdescriptorType), TX_NO_WAIT);\n            s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,\n                                  AES_BUFFER_SIZE, TX_NO_WAIT);\n            s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,\n                                  AES_BUFFER_SIZE, TX_NO_WAIT);\n            s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,\n                                  AES_BLOCK_SIZE*2, TX_NO_WAIT);\n            s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,\n                                  AES_BLOCK_SIZE, TX_NO_WAIT);\n\n            if (s1 || s2 || s3 || s4 || s5)\n                return BAD_FUNC_ARG;\n        #else\n            #warning \"Allocate non-Cache buffers\"\n        #endif\n\n            wc_InitMutex(&Mutex_AesSEC);\n        }\n\n        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))\n            return BAD_FUNC_ARG;\n\n        if (aes == NULL)\n            return BAD_FUNC_ARG;\n\n        aes->keylen = keylen;\n        aes->rounds = keylen/4 + 6;\n        XMEMCPY(aes->key, userKey, keylen);\n\n        if (iv)\n            XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);\n\n    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER)\n        aes->left = 0;\n    #endif\n\n        return 0;\n    }\n#elif defined(FREESCALE_LTC)\n    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,\n                  int dir)\n    {\n        if (aes == NULL || !((keylen == 16) || (keylen == 24) || (keylen == 32)))\n            return BAD_FUNC_ARG;\n\n        aes->rounds = keylen/4 + 6;\n        XMEMCPY(aes->key, userKey, keylen);\n\n    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER)\n        aes->left = 0;\n    #endif\n\n        return wc_AesSetIV(aes, iv);\n    }\n\n    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,\n                        const byte* iv, int dir)\n    {\n        return wc_AesSetKey(aes, userKey, keylen, iv, dir);\n    }\n#elif defined(FREESCALE_MMCAU)\n    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,\n        const byte* iv, int dir)\n    {\n        int ret;\n        byte* rk = (byte*)aes->key;\n        byte* tmpKey = (byte*)userKey;\n        int tmpKeyDynamic = 0;\n        word32 alignOffset = 0;\n\n        (void)dir;\n\n        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))\n            return BAD_FUNC_ARG;\n\n        if (rk == NULL)\n            return BAD_FUNC_ARG;\n\n    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER)\n        aes->left = 0;\n    #endif\n\n        aes->rounds = keylen/4 + 6;\n\n    #ifdef FREESCALE_MMCAU_CLASSIC\n        if ((wolfssl_word)userKey % WOLFSSL_MMCAU_ALIGNMENT) {\n        #ifndef NO_WOLFSSL_ALLOC_ALIGN\n            byte* tmp = (byte*)XMALLOC(keylen + WOLFSSL_MMCAU_ALIGNMENT,\n                                       aes->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            if (tmp == NULL) {\n                return MEMORY_E;\n            }\n            alignOffset = WOLFSSL_MMCAU_ALIGNMENT -\n                          ((wolfssl_word)tmp % WOLFSSL_MMCAU_ALIGNMENT);\n            tmpKey = tmp + alignOffset;\n            XMEMCPY(tmpKey, userKey, keylen);\n            tmpKeyDynamic = 1;\n        #else\n            WOLFSSL_MSG(\"Bad cau_aes_set_key alignment\");\n            return BAD_ALIGN_E;\n        #endif\n        }\n    #endif\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if(ret == 0) {\n        #ifdef FREESCALE_MMCAU_CLASSIC\n            cau_aes_set_key(tmpKey, keylen*8, rk);\n        #else\n            MMCAU_AES_SetKey(tmpKey, keylen, rk);\n        #endif\n            wolfSSL_CryptHwMutexUnLock();\n\n            ret = wc_AesSetIV(aes, iv);\n        }\n\n        if (tmpKeyDynamic == 1) {\n            XFREE(tmpKey - alignOffset, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        }\n\n        return ret;\n    }\n\n    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,\n                        const byte* iv, int dir)\n    {\n        return wc_AesSetKey(aes, userKey, keylen, iv, dir);\n    }\n\n#elif defined(WOLFSSL_NRF51_AES)\n    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,\n        const byte* iv, int dir)\n    {\n        int ret;\n\n        (void)dir;\n        (void)iv;\n\n        if (keylen != 16)\n            return BAD_FUNC_ARG;\n\n        aes->keylen = keylen;\n        aes->rounds = keylen/4 + 6;\n        ret = nrf51_aes_set_key(userKey);\n\n    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER)\n        aes->left = 0;\n    #endif\n\n        return ret;\n    }\n\n    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,\n                        const byte* iv, int dir)\n    {\n        return wc_AesSetKey(aes, userKey, keylen, iv, dir);\n    }\n#elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)\n\n    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,\n        const byte* iv, int dir)\n    {\n        (void)dir;\n        (void)iv;\n\n        if ( aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {\n            return BAD_FUNC_ARG;\n        }\n\n        aes->keylen = keylen;\n        aes->rounds = keylen/4 + 6;\n\n        XMEMCPY(aes->key, userKey, keylen);\n\n        return wc_AesSetIV(aes, iv);\n    }\n\n    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,\n                        const byte* iv, int dir)\n    {\n        return wc_AesSetKey(aes, userKey, keylen, iv, dir);\n    }\n#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)\n\n    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,\n                    int dir)\n    {\n        SaSiError_t ret = SASI_OK;\n        SaSiAesIv_t iv_aes;\n\n        if (aes == NULL ||\n           (keylen != AES_128_KEY_SIZE &&\n            keylen != AES_192_KEY_SIZE &&\n            keylen != AES_256_KEY_SIZE)) {\n            return BAD_FUNC_ARG;\n        }\n    #if defined(AES_MAX_KEY_SIZE)\n        if (keylen > (AES_MAX_KEY_SIZE/8)) {\n            return BAD_FUNC_ARG;\n        }\n    #endif\n        if (dir != AES_ENCRYPTION &&\n            dir != AES_DECRYPTION) {\n            return BAD_FUNC_ARG;\n        }\n\n        if (dir == AES_ENCRYPTION) {\n            aes->ctx.mode = SASI_AES_ENCRYPT;\n            SaSi_AesInit(&aes->ctx.user_ctx,\n                         SASI_AES_ENCRYPT,\n                         SASI_AES_MODE_CBC,\n                         SASI_AES_PADDING_NONE);\n        }\n        else {\n            aes->ctx.mode = SASI_AES_DECRYPT;\n            SaSi_AesInit(&aes->ctx.user_ctx,\n                         SASI_AES_DECRYPT,\n                         SASI_AES_MODE_CBC,\n                         SASI_AES_PADDING_NONE);\n        }\n\n        aes->keylen = keylen;\n        aes->rounds = keylen/4 + 6;\n        XMEMCPY(aes->key, userKey, keylen);\n\n        aes->ctx.key.pKey = (uint8_t*)aes->key;\n        aes->ctx.key.keySize= keylen;\n\n        ret = SaSi_AesSetKey(&aes->ctx.user_ctx,\n                             SASI_AES_USER_KEY,\n                             &aes->ctx.key,\n                             sizeof(aes->ctx.key));\n        if (ret != SASI_OK) {\n            return BAD_FUNC_ARG;\n        }\n\n        ret = wc_AesSetIV(aes, iv);\n\n        if (iv)\n            XMEMCPY(iv_aes, iv, AES_BLOCK_SIZE);\n        else\n            XMEMSET(iv_aes,  0, AES_BLOCK_SIZE);\n\n\n        ret = SaSi_AesSetIv(&aes->ctx.user_ctx, iv_aes);\n        if (ret != SASI_OK) {\n            return ret;\n        }\n       return ret;\n    }\n    #if defined(WOLFSSL_AES_DIRECT)\n        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,\n                            const byte* iv, int dir)\n        {\n            return wc_AesSetKey(aes, userKey, keylen, iv, dir);\n        }\n    #endif\n\n#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)\n      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */\n\n#elif defined(WOLFSSL_AFALG)\n    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */\n\n#elif defined(WOLFSSL_DEVCRYPTO_AES)\n    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */\n\n#else\n\n    /* Software AES - SetKey */\n    static int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,\n                const byte* iv, int dir)\n    {\n        word32 *rk = aes->key;\n    #ifdef NEED_AES_TABLES\n        word32 temp;\n        unsigned int i = 0;\n    #endif\n\n        #ifdef WOLFSSL_AESNI\n            aes->use_aesni = 0;\n        #endif /* WOLFSSL_AESNI */\n        #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER)\n            aes->left = 0;\n        #endif\n\n        aes->keylen = keylen;\n        aes->rounds = (keylen/4) + 6;\n\n        XMEMCPY(rk, userKey, keylen);\n    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \\\n        (!defined(WOLFSSL_ESP32WROOM32_CRYPT) || \\\n          defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES))\n        ByteReverseWords(rk, rk, keylen);\n    #endif\n\n#ifdef NEED_AES_TABLES\n\n        switch (keylen) {\n    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \\\n            defined(WOLFSSL_AES_128)\n        case 16:\n            while (1)\n            {\n                temp  = rk[3];\n                rk[4] = rk[0] ^\n                    (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^\n                    (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^\n                    (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^\n                    (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^\n                    rcon[i];\n                rk[5] = rk[1] ^ rk[4];\n                rk[6] = rk[2] ^ rk[5];\n                rk[7] = rk[3] ^ rk[6];\n                if (++i == 10)\n                    break;\n                rk += 4;\n            }\n            break;\n    #endif /* 128 */\n\n    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \\\n            defined(WOLFSSL_AES_192)\n        case 24:\n            /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */\n            while (1)\n            {\n                temp = rk[ 5];\n                rk[ 6] = rk[ 0] ^\n                    (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^\n                    (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^\n                    (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^\n                    (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^\n                    rcon[i];\n                rk[ 7] = rk[ 1] ^ rk[ 6];\n                rk[ 8] = rk[ 2] ^ rk[ 7];\n                rk[ 9] = rk[ 3] ^ rk[ 8];\n                if (++i == 8)\n                    break;\n                rk[10] = rk[ 4] ^ rk[ 9];\n                rk[11] = rk[ 5] ^ rk[10];\n                rk += 6;\n            }\n            break;\n    #endif /* 192 */\n\n    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \\\n            defined(WOLFSSL_AES_256)\n        case 32:\n            while (1)\n            {\n                temp = rk[ 7];\n                rk[ 8] = rk[ 0] ^\n                    (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^\n                    (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^\n                    (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^\n                    (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^\n                    rcon[i];\n                rk[ 9] = rk[ 1] ^ rk[ 8];\n                rk[10] = rk[ 2] ^ rk[ 9];\n                rk[11] = rk[ 3] ^ rk[10];\n                if (++i == 7)\n                    break;\n                temp = rk[11];\n                rk[12] = rk[ 4] ^\n                    (Te[2][GETBYTE(temp, 3)] & 0xff000000) ^\n                    (Te[3][GETBYTE(temp, 2)] & 0x00ff0000) ^\n                    (Te[0][GETBYTE(temp, 1)] & 0x0000ff00) ^\n                    (Te[1][GETBYTE(temp, 0)] & 0x000000ff);\n                rk[13] = rk[ 5] ^ rk[12];\n                rk[14] = rk[ 6] ^ rk[13];\n                rk[15] = rk[ 7] ^ rk[14];\n\n                rk += 8;\n            }\n            break;\n    #endif /* 256 */\n\n        default:\n            return BAD_FUNC_ARG;\n        } /* switch */\n\n    #ifdef HAVE_AES_DECRYPT\n        if (dir == AES_DECRYPTION) {\n            unsigned int j;\n            rk = aes->key;\n\n            /* invert the order of the round keys: */\n            for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {\n                temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;\n                temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;\n                temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;\n                temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;\n            }\n            /* apply the inverse MixColumn transform to all round keys but the\n               first and the last: */\n            for (i = 1; i < aes->rounds; i++) {\n                rk += 4;\n                rk[0] =\n                    Td[0][Te[1][GETBYTE(rk[0], 3)] & 0xff] ^\n                    Td[1][Te[1][GETBYTE(rk[0], 2)] & 0xff] ^\n                    Td[2][Te[1][GETBYTE(rk[0], 1)] & 0xff] ^\n                    Td[3][Te[1][GETBYTE(rk[0], 0)] & 0xff];\n                rk[1] =\n                    Td[0][Te[1][GETBYTE(rk[1], 3)] & 0xff] ^\n                    Td[1][Te[1][GETBYTE(rk[1], 2)] & 0xff] ^\n                    Td[2][Te[1][GETBYTE(rk[1], 1)] & 0xff] ^\n                    Td[3][Te[1][GETBYTE(rk[1], 0)] & 0xff];\n                rk[2] =\n                    Td[0][Te[1][GETBYTE(rk[2], 3)] & 0xff] ^\n                    Td[1][Te[1][GETBYTE(rk[2], 2)] & 0xff] ^\n                    Td[2][Te[1][GETBYTE(rk[2], 1)] & 0xff] ^\n                    Td[3][Te[1][GETBYTE(rk[2], 0)] & 0xff];\n                rk[3] =\n                    Td[0][Te[1][GETBYTE(rk[3], 3)] & 0xff] ^\n                    Td[1][Te[1][GETBYTE(rk[3], 2)] & 0xff] ^\n                    Td[2][Te[1][GETBYTE(rk[3], 1)] & 0xff] ^\n                    Td[3][Te[1][GETBYTE(rk[3], 0)] & 0xff];\n            }\n        }\n    #else\n        (void)dir;\n    #endif /* HAVE_AES_DECRYPT */\n#endif /* NEED_AES_TABLES */\n\n        return wc_AesSetIV(aes, iv);\n    }\n\n    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,\n        const byte* iv, int dir)\n    {\n        int ret;\n    #if defined(AES_MAX_KEY_SIZE)\n        const word32 max_key_len = (AES_MAX_KEY_SIZE / 8);\n    #endif\n\n    #ifdef WOLFSSL_IMX6_CAAM_BLOB\n        byte   local[32];\n        word32 localSz = 32;\n\n        if (keylen == (16 + WC_CAAM_BLOB_SZ) ||\n                keylen == (24 + WC_CAAM_BLOB_SZ) ||\n                keylen == (32 + WC_CAAM_BLOB_SZ)) {\n            if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {\n                return BAD_FUNC_ARG;\n            }\n\n            /* set local values */\n            userKey = local;\n            keylen = localSz;\n        }\n    #endif\n        if (aes == NULL ||\n                !((keylen == 16) || (keylen == 24) || (keylen == 32))) {\n            return BAD_FUNC_ARG;\n        }\n\n    #if defined(AES_MAX_KEY_SIZE)\n        /* Check key length */\n        if (keylen > max_key_len) {\n            return BAD_FUNC_ARG;\n        }\n    #endif\n        aes->keylen = keylen;\n        aes->rounds = keylen/4 + 6;\n\n    #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \\\n        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \\\n        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))\n        #ifdef WOLF_CRYPTO_CB\n        if (aes->devId != INVALID_DEVID)\n        #endif\n        {\n            XMEMCPY(aes->devKey, userKey, keylen);\n        }\n    #endif\n\n    #ifdef WOLFSSL_AESNI\n        if (checkAESNI == 0) {\n            haveAESNI  = Check_CPU_support_AES();\n            checkAESNI = 1;\n        }\n        if (haveAESNI) {\n            #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB)\n                aes->left = 0;\n            #endif /* WOLFSSL_AES_COUNTER */\n            aes->use_aesni = 1;\n            if (iv)\n                XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);\n            else\n                XMEMSET(aes->reg, 0, AES_BLOCK_SIZE);\n            if (dir == AES_ENCRYPTION)\n                return AES_set_encrypt_key(userKey, keylen * 8, aes);\n        #ifdef HAVE_AES_DECRYPT\n            else\n                return AES_set_decrypt_key(userKey, keylen * 8, aes);\n        #endif\n        }\n    #endif /* WOLFSSL_AESNI */\n\n        ret = wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);\n\n    #if defined(WOLFSSL_DEVCRYPTO) && \\\n        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))\n        aes->ctx.cfd = -1;\n    #endif\n    #ifdef WOLFSSL_IMX6_CAAM_BLOB\n        ForceZero(local, sizeof(local));\n    #endif\n        return ret;\n    }\n\n    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)\n        /* AES-CTR and AES-DIRECT need to use this for key setup, no aesni yet */\n        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,\n                            const byte* iv, int dir)\n        {\n            int ret;\n\n        #ifdef WOLFSSL_IMX6_CAAM_BLOB\n            byte   local[32];\n            word32 localSz = 32;\n\n            if (keylen == (16 + WC_CAAM_BLOB_SZ) ||\n             keylen == (24 + WC_CAAM_BLOB_SZ) ||\n             keylen == (32 + WC_CAAM_BLOB_SZ)) {\n                if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz)\n                        != 0) {\n                    return BAD_FUNC_ARG;\n                }\n\n                /* set local values */\n                userKey = local;\n                keylen = localSz;\n            }\n        #endif\n            ret = wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir);\n\n        #ifdef WOLFSSL_IMX6_CAAM_BLOB\n            ForceZero(local, sizeof(local));\n        #endif\n\n            return ret;\n        }\n    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */\n#endif /* wc_AesSetKey block */\n\n\n/* wc_AesSetIV is shared between software and hardware */\nint wc_AesSetIV(Aes* aes, const byte* iv)\n{\n    if (aes == NULL)\n        return BAD_FUNC_ARG;\n\n    if (iv)\n        XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);\n    else\n        XMEMSET(aes->reg,  0, AES_BLOCK_SIZE);\n\n    return 0;\n}\n\n/* AES-DIRECT */\n#if defined(WOLFSSL_AES_DIRECT)\n    #if defined(HAVE_COLDFIRE_SEC)\n        #error \"Coldfire SEC doesn't yet support AES direct\"\n\n    #elif defined(FREESCALE_LTC)\n        /* Allow direct access to one block encrypt */\n        void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)\n        {\n            byte *key;\n            uint32_t keySize;\n\n            key = (byte*)aes->key;\n            wc_AesGetKeySize(aes, &keySize);\n\n            LTC_AES_EncryptEcb(LTC_BASE, in, out, AES_BLOCK_SIZE,\n                key, keySize);\n        }\n\n        /* Allow direct access to one block decrypt */\n        void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)\n        {\n            byte *key;\n            uint32_t keySize;\n\n            key = (byte*)aes->key;\n            wc_AesGetKeySize(aes, &keySize);\n\n            LTC_AES_DecryptEcb(LTC_BASE, in, out, AES_BLOCK_SIZE,\n                key, keySize, kLTC_EncryptKey);\n        }\n\n    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)\n        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */\n\n    #elif defined(WOLFSSL_AFALG)\n        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */\n\n    #elif defined(WOLFSSL_DEVCRYPTO_AES)\n        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */\n\n    #elif defined(STM32_CRYPTO)\n        /* Allow direct access to one block encrypt */\n        void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)\n        {\n            if (wolfSSL_CryptHwMutexLock() == 0) {\n                wc_AesEncrypt(aes, in, out);\n                wolfSSL_CryptHwMutexUnLock();\n            }\n        }\n        #ifdef HAVE_AES_DECRYPT\n        /* Allow direct access to one block decrypt */\n        void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)\n        {\n            if (wolfSSL_CryptHwMutexLock() == 0) {\n                wc_AesDecrypt(aes, in, out);\n                wolfSSL_CryptHwMutexUnLock();\n            }\n        }\n        #endif /* HAVE_AES_DECRYPT */\n\n    #else\n        /* Allow direct access to one block encrypt */\n        void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)\n        {\n            wc_AesEncrypt(aes, in, out);\n        }\n        #ifdef HAVE_AES_DECRYPT\n        /* Allow direct access to one block decrypt */\n        void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)\n        {\n            wc_AesDecrypt(aes, in, out);\n        }\n        #endif /* HAVE_AES_DECRYPT */\n    #endif /* AES direct block */\n#endif /* WOLFSSL_AES_DIRECT */\n\n\n/* AES-CBC */\n#ifdef HAVE_AES_CBC\n#if defined(STM32_CRYPTO)\n\n#ifdef WOLFSSL_STM32_CUBEMX\n    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        int ret = 0;\n        word32 blocks = (sz / AES_BLOCK_SIZE);\n        CRYP_HandleTypeDef hcryp;\n\n        ret = wc_Stm32_Aes_Init(aes, &hcryp);\n        if (ret != 0)\n            return ret;\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret != 0) {\n            return ret;\n        }\n\n    #ifdef STM32_CRYPTO_AES_ONLY\n        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;\n        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;\n        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;\n    #elif defined(STM32_HAL_V2)\n        hcryp.Init.Algorithm  = CRYP_AES_CBC;\n        ByteReverseWords(aes->reg, aes->reg, AES_BLOCK_SIZE);\n    #endif\n        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;\n        HAL_CRYP_Init(&hcryp);\n\n        while (blocks--) {\n        #ifdef STM32_CRYPTO_AES_ONLY\n            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,\n                out, STM32_HAL_TIMEOUT);\n        #elif defined(STM32_HAL_V2)\n            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, AES_BLOCK_SIZE,\n                (uint32_t*)out, STM32_HAL_TIMEOUT);\n        #else\n            ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,\n                out, STM32_HAL_TIMEOUT);\n        #endif\n            if (ret != HAL_OK) {\n                ret = WC_TIMEOUT_E;\n                break;\n            }\n\n            /* store iv for next call */\n            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n\n            sz  -= AES_BLOCK_SIZE;\n            in  += AES_BLOCK_SIZE;\n            out += AES_BLOCK_SIZE;\n        }\n\n        HAL_CRYP_DeInit(&hcryp);\n\n        wolfSSL_CryptHwMutexUnLock();\n\n        return ret;\n    }\n    #ifdef HAVE_AES_DECRYPT\n    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        int ret = 0;\n        word32 blocks = (sz / AES_BLOCK_SIZE);\n        CRYP_HandleTypeDef hcryp;\n\n        ret = wc_Stm32_Aes_Init(aes, &hcryp);\n        if (ret != 0)\n            return ret;\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret != 0) {\n            return ret;\n        }\n\n        /* if input and output same will overwrite input iv */\n        XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n\n    #ifdef STM32_CRYPTO_AES_ONLY\n        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;\n        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;\n        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;\n    #elif defined(STM32_HAL_V2)\n        hcryp.Init.Algorithm  = CRYP_AES_CBC;\n        ByteReverseWords(aes->reg, aes->reg, AES_BLOCK_SIZE);\n    #endif\n\n        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;\n        HAL_CRYP_Init(&hcryp);\n\n        while (blocks--) {\n        #ifdef STM32_CRYPTO_AES_ONLY\n            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,\n                out, STM32_HAL_TIMEOUT);\n        #elif defined(STM32_HAL_V2)\n            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, AES_BLOCK_SIZE,\n                (uint32_t*)out, STM32_HAL_TIMEOUT);\n        #else\n            ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE,\n                out, STM32_HAL_TIMEOUT);\n        #endif\n            if (ret != HAL_OK) {\n                ret = WC_TIMEOUT_E;\n                break;\n            }\n\n            /* store iv for next call */\n            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);\n\n            in  += AES_BLOCK_SIZE;\n            out += AES_BLOCK_SIZE;\n        }\n\n        HAL_CRYP_DeInit(&hcryp);\n        wolfSSL_CryptHwMutexUnLock();\n\n        return ret;\n    }\n    #endif /* HAVE_AES_DECRYPT */\n\n#else /* STD_PERI_LIB */\n    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        int ret;\n        word32 *iv;\n        word32 blocks = (sz / AES_BLOCK_SIZE);\n        CRYP_InitTypeDef cryptInit;\n        CRYP_KeyInitTypeDef keyInit;\n        CRYP_IVInitTypeDef ivInit;\n\n        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);\n        if (ret != 0)\n            return ret;\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret != 0) {\n            return ret;\n        }\n\n        /* reset registers to their default values */\n        CRYP_DeInit();\n\n        /* set key */\n        CRYP_KeyInit(&keyInit);\n\n        /* set iv */\n        iv = aes->reg;\n        CRYP_IVStructInit(&ivInit);\n        ByteReverseWords(iv, iv, AES_BLOCK_SIZE);\n        ivInit.CRYP_IV0Left  = iv[0];\n        ivInit.CRYP_IV0Right = iv[1];\n        ivInit.CRYP_IV1Left  = iv[2];\n        ivInit.CRYP_IV1Right = iv[3];\n        CRYP_IVInit(&ivInit);\n\n        /* set direction and mode */\n        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;\n        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;\n        CRYP_Init(&cryptInit);\n\n        /* enable crypto processor */\n        CRYP_Cmd(ENABLE);\n\n        while (blocks--) {\n            /* flush IN/OUT FIFOs */\n            CRYP_FIFOFlush();\n\n            CRYP_DataIn(*(uint32_t*)&in[0]);\n            CRYP_DataIn(*(uint32_t*)&in[4]);\n            CRYP_DataIn(*(uint32_t*)&in[8]);\n            CRYP_DataIn(*(uint32_t*)&in[12]);\n\n            /* wait until the complete message has been processed */\n            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}\n\n            *(uint32_t*)&out[0]  = CRYP_DataOut();\n            *(uint32_t*)&out[4]  = CRYP_DataOut();\n            *(uint32_t*)&out[8]  = CRYP_DataOut();\n            *(uint32_t*)&out[12] = CRYP_DataOut();\n\n            /* store iv for next call */\n            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n\n            sz  -= AES_BLOCK_SIZE;\n            in  += AES_BLOCK_SIZE;\n            out += AES_BLOCK_SIZE;\n        }\n\n        /* disable crypto processor */\n        CRYP_Cmd(DISABLE);\n        wolfSSL_CryptHwMutexUnLock();\n\n        return ret;\n    }\n\n    #ifdef HAVE_AES_DECRYPT\n    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        int ret;\n        word32 *iv;\n        word32 blocks = (sz / AES_BLOCK_SIZE);\n        CRYP_InitTypeDef cryptInit;\n        CRYP_KeyInitTypeDef keyInit;\n        CRYP_IVInitTypeDef ivInit;\n\n        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);\n        if (ret != 0)\n            return ret;\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret != 0) {\n            return ret;\n        }\n\n        /* if input and output same will overwrite input iv */\n        XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n\n        /* reset registers to their default values */\n        CRYP_DeInit();\n\n        /* set direction and key */\n        CRYP_KeyInit(&keyInit);\n        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;\n        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;\n        CRYP_Init(&cryptInit);\n\n        /* enable crypto processor */\n        CRYP_Cmd(ENABLE);\n\n        /* wait until key has been prepared */\n        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}\n\n        /* set direction and mode */\n        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;\n        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;\n        CRYP_Init(&cryptInit);\n\n        /* set iv */\n        iv = aes->reg;\n        CRYP_IVStructInit(&ivInit);\n        ByteReverseWords(iv, iv, AES_BLOCK_SIZE);\n        ivInit.CRYP_IV0Left  = iv[0];\n        ivInit.CRYP_IV0Right = iv[1];\n        ivInit.CRYP_IV1Left  = iv[2];\n        ivInit.CRYP_IV1Right = iv[3];\n        CRYP_IVInit(&ivInit);\n\n        /* enable crypto processor */\n        CRYP_Cmd(ENABLE);\n\n        while (blocks--) {\n            /* flush IN/OUT FIFOs */\n            CRYP_FIFOFlush();\n\n            CRYP_DataIn(*(uint32_t*)&in[0]);\n            CRYP_DataIn(*(uint32_t*)&in[4]);\n            CRYP_DataIn(*(uint32_t*)&in[8]);\n            CRYP_DataIn(*(uint32_t*)&in[12]);\n\n            /* wait until the complete message has been processed */\n            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}\n\n            *(uint32_t*)&out[0]  = CRYP_DataOut();\n            *(uint32_t*)&out[4]  = CRYP_DataOut();\n            *(uint32_t*)&out[8]  = CRYP_DataOut();\n            *(uint32_t*)&out[12] = CRYP_DataOut();\n\n            /* store iv for next call */\n            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);\n\n            in  += AES_BLOCK_SIZE;\n            out += AES_BLOCK_SIZE;\n        }\n\n        /* disable crypto processor */\n        CRYP_Cmd(DISABLE);\n        wolfSSL_CryptHwMutexUnLock();\n\n        return ret;\n    }\n    #endif /* HAVE_AES_DECRYPT */\n#endif /* WOLFSSL_STM32_CUBEMX */\n\n#elif defined(HAVE_COLDFIRE_SEC)\n    static int wc_AesCbcCrypt(Aes* aes, byte* po, const byte* pi, word32 sz,\n        word32 descHeader)\n    {\n        #ifdef DEBUG_WOLFSSL\n            int i; int stat1, stat2; int ret;\n        #endif\n\n        int size;\n        volatile int v;\n\n        if ((pi == NULL) || (po == NULL))\n            return BAD_FUNC_ARG;    /*wrong pointer*/\n\n        wc_LockMutex(&Mutex_AesSEC);\n\n        /* Set descriptor for SEC */\n        secDesc->length1 = 0x0;\n        secDesc->pointer1 = NULL;\n\n        secDesc->length2 = AES_BLOCK_SIZE;\n        secDesc->pointer2 = (byte *)secReg; /* Initial Vector */\n\n        switch(aes->rounds) {\n            case 10: secDesc->length3 = 16; break;\n            case 12: secDesc->length3 = 24; break;\n            case 14: secDesc->length3 = 32; break;\n        }\n        XMEMCPY(secKey, aes->key, secDesc->length3);\n\n        secDesc->pointer3 = (byte *)secKey;\n        secDesc->pointer4 = AESBuffIn;\n        secDesc->pointer5 = AESBuffOut;\n        secDesc->length6 = 0x0;\n        secDesc->pointer6 = NULL;\n        secDesc->length7 = 0x0;\n        secDesc->pointer7 = NULL;\n        secDesc->nextDescriptorPtr = NULL;\n\n        while (sz) {\n            secDesc->header = descHeader;\n            XMEMCPY(secReg, aes->reg, AES_BLOCK_SIZE);\n            if ((sz % AES_BUFFER_SIZE) == sz) {\n                size = sz;\n                sz = 0;\n            } else {\n                size = AES_BUFFER_SIZE;\n                sz -= AES_BUFFER_SIZE;\n            }\n            secDesc->length4 = size;\n            secDesc->length5 = size;\n\n            XMEMCPY(AESBuffIn, pi, size);\n            if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {\n                XMEMCPY((void*)aes->tmp, (void*)&(pi[size-AES_BLOCK_SIZE]),\n                        AES_BLOCK_SIZE);\n            }\n\n            /* Point SEC to the location of the descriptor */\n            MCF_SEC_FR0 = (uint32)secDesc;\n            /* Initialize SEC and wait for encryption to complete */\n            MCF_SEC_CCCR0 = 0x0000001a;\n            /* poll SISR to determine when channel is complete */\n            v=0;\n\n            while ((secDesc->header>> 24) != 0xff) v++;\n\n            #ifdef DEBUG_WOLFSSL\n                ret = MCF_SEC_SISRH;\n                stat1 = MCF_SEC_AESSR;\n                stat2 = MCF_SEC_AESISR;\n                if (ret & 0xe0000000) {\n                    db_printf(\"Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, \"\n                              \"AESISR=%08x\\n\", i, ret, stat1, stat2);\n                }\n            #endif\n\n            XMEMCPY(po, AESBuffOut, size);\n\n            if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {\n                XMEMCPY((void*)aes->reg, (void*)&(po[size-AES_BLOCK_SIZE]),\n                        AES_BLOCK_SIZE);\n            } else {\n                XMEMCPY((void*)aes->reg, (void*)aes->tmp, AES_BLOCK_SIZE);\n            }\n\n            pi += size;\n            po += size;\n        }\n\n        wc_UnLockMutex(&Mutex_AesSEC);\n        return 0;\n    }\n\n    int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)\n    {\n        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));\n    }\n\n    #ifdef HAVE_AES_DECRYPT\n    int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)\n    {\n        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));\n    }\n    #endif /* HAVE_AES_DECRYPT */\n\n#elif defined(FREESCALE_LTC)\n    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        uint32_t keySize;\n        status_t status;\n        byte *iv, *enc_key;\n        word32 blocks = (sz / AES_BLOCK_SIZE);\n\n        iv      = (byte*)aes->reg;\n        enc_key = (byte*)aes->key;\n\n        status = wc_AesGetKeySize(aes, &keySize);\n        if (status != 0) {\n            return status;\n        }\n\n        status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * AES_BLOCK_SIZE,\n            iv, enc_key, keySize);\n\n        /* store iv for next call */\n        if (status == kStatus_Success) {\n            XMEMCPY(iv, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n        }\n\n        return (status == kStatus_Success) ? 0 : -1;\n    }\n\n    #ifdef HAVE_AES_DECRYPT\n    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        uint32_t keySize;\n        status_t status;\n        byte* iv, *dec_key;\n        word32 blocks = (sz / AES_BLOCK_SIZE);\n        byte temp_block[AES_BLOCK_SIZE];\n\n        iv      = (byte*)aes->reg;\n        dec_key = (byte*)aes->key;\n\n        status = wc_AesGetKeySize(aes, &keySize);\n        if (status != 0) {\n            return status;\n        }\n\n        /* get IV for next call */\n        XMEMCPY(temp_block, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n\n        status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * AES_BLOCK_SIZE,\n            iv, dec_key, keySize, kLTC_EncryptKey);\n\n        /* store IV for next call */\n        if (status == kStatus_Success) {\n            XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);\n        }\n\n        return (status == kStatus_Success) ? 0 : -1;\n    }\n    #endif /* HAVE_AES_DECRYPT */\n\n#elif defined(FREESCALE_MMCAU)\n    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        int i;\n        int offset = 0;\n        word32 blocks = (sz / AES_BLOCK_SIZE);\n        byte *iv;\n        byte temp_block[AES_BLOCK_SIZE];\n\n        iv      = (byte*)aes->reg;\n\n        while (blocks--) {\n            XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);\n\n            /* XOR block with IV for CBC */\n            for (i = 0; i < AES_BLOCK_SIZE; i++)\n                temp_block[i] ^= iv[i];\n\n            wc_AesEncrypt(aes, temp_block, out + offset);\n\n            offset += AES_BLOCK_SIZE;\n\n            /* store IV for next block */\n            XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n        }\n\n        return 0;\n    }\n    #ifdef HAVE_AES_DECRYPT\n    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        int i;\n        int offset = 0;\n        word32 blocks = (sz / AES_BLOCK_SIZE);\n        byte* iv;\n        byte temp_block[AES_BLOCK_SIZE];\n\n        iv      = (byte*)aes->reg;\n\n        while (blocks--) {\n            XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);\n\n            wc_AesDecrypt(aes, in + offset, out + offset);\n\n            /* XOR block with IV for CBC */\n            for (i = 0; i < AES_BLOCK_SIZE; i++)\n                (out + offset)[i] ^= iv[i];\n\n            /* store IV for next block */\n            XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);\n\n            offset += AES_BLOCK_SIZE;\n        }\n\n        return 0;\n    }\n    #endif /* HAVE_AES_DECRYPT */\n\n#elif defined(WOLFSSL_PIC32MZ_CRYPT)\n\n    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        int ret;\n\n        /* hardware fails on input that is not a multiple of AES block size */\n        if (sz % AES_BLOCK_SIZE != 0) {\n            return BAD_FUNC_ARG;\n        }\n\n        ret = wc_Pic32AesCrypt(\n            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,\n            out, in, sz, PIC32_ENCRYPTION,\n            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);\n\n        /* store iv for next call */\n        if (ret == 0) {\n            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n        }\n\n        return ret;\n    }\n    #ifdef HAVE_AES_DECRYPT\n    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        int ret;\n        byte scratch[AES_BLOCK_SIZE];\n\n        /* hardware fails on input that is not a multiple of AES block size */\n        if (sz % AES_BLOCK_SIZE != 0) {\n            return BAD_FUNC_ARG;\n        }\n        XMEMCPY(scratch, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n\n        ret = wc_Pic32AesCrypt(\n            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,\n            out, in, sz, PIC32_DECRYPTION,\n            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);\n\n        /* store iv for next call */\n        if (ret == 0) {\n            XMEMCPY((byte*)aes->reg, scratch, AES_BLOCK_SIZE);\n        }\n\n        return ret;\n    }\n    #endif /* HAVE_AES_DECRYPT */\n#elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)\n\n    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        return wc_esp32AesCbcEncrypt(aes, out, in, sz);\n    }\n    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        return wc_esp32AesCbcDecrypt(aes, out, in, sz);\n    }\n#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)\n    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t* )in, sz, out);\n    }\n    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t* )in, sz, out);\n    }\n#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)\n      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */\n\n#elif defined(WOLFSSL_AFALG)\n    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */\n\n#elif defined(WOLFSSL_DEVCRYPTO_CBC)\n    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */\n\n#else\n\n    /* Software AES - CBC Encrypt */\n    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        word32 blocks = (sz / AES_BLOCK_SIZE);\n\n        if (aes == NULL || out == NULL || in == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n    #ifdef WOLF_CRYPTO_CB\n        if (aes->devId != INVALID_DEVID) {\n            int ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);\n            if (ret != CRYPTOCB_UNAVAILABLE)\n                return ret;\n            /* fall-through when unavailable */\n        }\n    #endif\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)\n        /* if async and byte count above threshold */\n        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&\n                                                sz >= WC_ASYNC_THRESH_AES_CBC) {\n        #if defined(HAVE_CAVIUM)\n            return NitroxAesCbcEncrypt(aes, out, in, sz);\n        #elif defined(HAVE_INTEL_QA)\n            return IntelQaSymAesCbcEncrypt(&aes->asyncDev, out, in, sz,\n                (const byte*)aes->devKey, aes->keylen,\n                (byte*)aes->reg, AES_BLOCK_SIZE);\n        #else /* WOLFSSL_ASYNC_CRYPT_TEST */\n            if (wc_AsyncTestInit(&aes->asyncDev, ASYNC_TEST_AES_CBC_ENCRYPT)) {\n                WC_ASYNC_TEST* testDev = &aes->asyncDev.test;\n                testDev->aes.aes = aes;\n                testDev->aes.out = out;\n                testDev->aes.in = in;\n                testDev->aes.sz = sz;\n                return WC_PENDING_E;\n            }\n        #endif\n        }\n    #endif /* WOLFSSL_ASYNC_CRYPT */\n\n    #ifdef WOLFSSL_AESNI\n        if (haveAESNI) {\n            #ifdef DEBUG_AESNI\n                printf(\"about to aes cbc encrypt\\n\");\n                printf(\"in  = %p\\n\", in);\n                printf(\"out = %p\\n\", out);\n                printf(\"aes->key = %p\\n\", aes->key);\n                printf(\"aes->reg = %p\\n\", aes->reg);\n                printf(\"aes->rounds = %d\\n\", aes->rounds);\n                printf(\"sz = %d\\n\", sz);\n            #endif\n\n            /* check alignment, decrypt doesn't need alignment */\n            if ((wolfssl_word)in % AESNI_ALIGN) {\n            #ifndef NO_WOLFSSL_ALLOC_ALIGN\n                byte* tmp = (byte*)XMALLOC(sz + AES_BLOCK_SIZE + AESNI_ALIGN,\n                                            aes->heap, DYNAMIC_TYPE_TMP_BUFFER);\n                byte* tmp_align;\n                if (tmp == NULL) return MEMORY_E;\n\n                tmp_align = tmp + (AESNI_ALIGN - ((size_t)tmp % AESNI_ALIGN));\n                XMEMCPY(tmp_align, in, sz);\n                AES_CBC_encrypt(tmp_align, tmp_align, (byte*)aes->reg, sz,\n                                                  (byte*)aes->key, aes->rounds);\n                /* store iv for next call */\n                XMEMCPY(aes->reg, tmp_align + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n\n                XMEMCPY(out, tmp_align, sz);\n                XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);\n                return 0;\n            #else\n                WOLFSSL_MSG(\"AES-CBC encrypt with bad alignment\");\n                return BAD_ALIGN_E;\n            #endif\n            }\n\n            AES_CBC_encrypt(in, out, (byte*)aes->reg, sz, (byte*)aes->key,\n                            aes->rounds);\n            /* store iv for next call */\n            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n\n            return 0;\n        }\n    #endif\n\n        while (blocks--) {\n            xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE);\n            wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg);\n            XMEMCPY(out, aes->reg, AES_BLOCK_SIZE);\n\n            out += AES_BLOCK_SIZE;\n            in  += AES_BLOCK_SIZE;\n        }\n\n        return 0;\n    }\n\n    #ifdef HAVE_AES_DECRYPT\n    /* Software AES - CBC Decrypt */\n    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n    {\n        word32 blocks;\n\n        if (aes == NULL || out == NULL || in == NULL\n                                       || sz % AES_BLOCK_SIZE != 0) {\n            return BAD_FUNC_ARG;\n        }\n\n    #ifdef WOLF_CRYPTO_CB\n        if (aes->devId != INVALID_DEVID) {\n            int ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);\n            if (ret != CRYPTOCB_UNAVAILABLE)\n                return ret;\n            /* fall-through when unavailable */\n        }\n    #endif\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)\n        /* if async and byte count above threshold */\n        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&\n                                                sz >= WC_ASYNC_THRESH_AES_CBC) {\n        #if defined(HAVE_CAVIUM)\n            return NitroxAesCbcDecrypt(aes, out, in, sz);\n        #elif defined(HAVE_INTEL_QA)\n            return IntelQaSymAesCbcDecrypt(&aes->asyncDev, out, in, sz,\n                (const byte*)aes->devKey, aes->keylen,\n                (byte*)aes->reg, AES_BLOCK_SIZE);\n        #else /* WOLFSSL_ASYNC_CRYPT_TEST */\n            if (wc_AsyncTestInit(&aes->asyncDev, ASYNC_TEST_AES_CBC_DECRYPT)) {\n                WC_ASYNC_TEST* testDev = &aes->asyncDev.test;\n                testDev->aes.aes = aes;\n                testDev->aes.out = out;\n                testDev->aes.in = in;\n                testDev->aes.sz = sz;\n                return WC_PENDING_E;\n            }\n        #endif\n        }\n    #endif\n\n    #ifdef WOLFSSL_AESNI\n        if (haveAESNI) {\n            #ifdef DEBUG_AESNI\n                printf(\"about to aes cbc decrypt\\n\");\n                printf(\"in  = %p\\n\", in);\n                printf(\"out = %p\\n\", out);\n                printf(\"aes->key = %p\\n\", aes->key);\n                printf(\"aes->reg = %p\\n\", aes->reg);\n                printf(\"aes->rounds = %d\\n\", aes->rounds);\n                printf(\"sz = %d\\n\", sz);\n            #endif\n\n            /* if input and output same will overwrite input iv */\n            XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n            #if defined(WOLFSSL_AESNI_BY4)\n            AES_CBC_decrypt_by4(in, out, (byte*)aes->reg, sz, (byte*)aes->key,\n                            aes->rounds);\n            #elif defined(WOLFSSL_AESNI_BY6)\n            AES_CBC_decrypt_by6(in, out, (byte*)aes->reg, sz, (byte*)aes->key,\n                            aes->rounds);\n            #else /* WOLFSSL_AESNI_BYx */\n            AES_CBC_decrypt_by8(in, out, (byte*)aes->reg, sz, (byte*)aes->key,\n                            aes->rounds);\n            #endif /* WOLFSSL_AESNI_BYx */\n            /* store iv for next call */\n            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);\n            return 0;\n        }\n    #endif\n\n        blocks = sz / AES_BLOCK_SIZE;\n        while (blocks--) {\n            XMEMCPY(aes->tmp, in, AES_BLOCK_SIZE);\n            wc_AesDecrypt(aes, (byte*)aes->tmp, out);\n            xorbuf(out, (byte*)aes->reg, AES_BLOCK_SIZE);\n            /* store iv for next call */\n            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);\n\n            out += AES_BLOCK_SIZE;\n            in  += AES_BLOCK_SIZE;\n        }\n\n        return 0;\n    }\n    #endif\n\n#endif /* AES-CBC block */\n#endif /* HAVE_AES_CBC */\n\n/* AES-CTR */\n#if defined(WOLFSSL_AES_COUNTER)\n\n    #ifdef STM32_CRYPTO\n        #define NEED_AES_CTR_SOFT\n        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock\n\n        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)\n        {\n            int ret = 0;\n        #ifdef WOLFSSL_STM32_CUBEMX\n            CRYP_HandleTypeDef hcryp;\n            #ifdef STM32_HAL_V2\n            word32 iv[AES_BLOCK_SIZE/sizeof(word32)];\n            #endif\n        #else\n            word32 *iv;\n            CRYP_InitTypeDef cryptInit;\n            CRYP_KeyInitTypeDef keyInit;\n            CRYP_IVInitTypeDef ivInit;\n        #endif\n\n            ret = wolfSSL_CryptHwMutexLock();\n            if (ret != 0) {\n                return ret;\n            }\n\n        #ifdef WOLFSSL_STM32_CUBEMX\n            ret = wc_Stm32_Aes_Init(aes, &hcryp);\n            if (ret != 0) {\n                wolfSSL_CryptHwMutexUnLock();\n                return ret;\n            }\n\n        #ifdef STM32_CRYPTO_AES_ONLY\n            hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;\n            hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;\n            hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;\n            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;\n        #elif defined(STM32_HAL_V2)\n            hcryp.Init.Algorithm  = CRYP_AES_CTR;\n            ByteReverseWords(iv, aes->reg, AES_BLOCK_SIZE);\n            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)iv;\n        #else\n            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;\n        #endif\n            HAL_CRYP_Init(&hcryp);\n\n        #ifdef STM32_CRYPTO_AES_ONLY\n            ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, AES_BLOCK_SIZE,\n                out, STM32_HAL_TIMEOUT);\n        #elif defined(STM32_HAL_V2)\n            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, AES_BLOCK_SIZE,\n                (uint32_t*)out, STM32_HAL_TIMEOUT);\n        #else\n            ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, AES_BLOCK_SIZE,\n                out, STM32_HAL_TIMEOUT);\n        #endif\n            if (ret != HAL_OK) {\n                ret = WC_TIMEOUT_E;\n            }\n            HAL_CRYP_DeInit(&hcryp);\n\n        #else /* STD_PERI_LIB */\n            ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);\n            if (ret != 0) {\n                wolfSSL_CryptHwMutexUnLock();\n                return ret;\n            }\n\n            /* reset registers to their default values */\n            CRYP_DeInit();\n\n            /* set key */\n            CRYP_KeyInit(&keyInit);\n\n            /* set iv */\n            iv = aes->reg;\n            CRYP_IVStructInit(&ivInit);\n            ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);\n            ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);\n            ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);\n            ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);\n            CRYP_IVInit(&ivInit);\n\n            /* set direction and mode */\n            cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;\n            cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;\n            CRYP_Init(&cryptInit);\n\n            /* enable crypto processor */\n            CRYP_Cmd(ENABLE);\n\n            /* flush IN/OUT FIFOs */\n            CRYP_FIFOFlush();\n\n            CRYP_DataIn(*(uint32_t*)&in[0]);\n            CRYP_DataIn(*(uint32_t*)&in[4]);\n            CRYP_DataIn(*(uint32_t*)&in[8]);\n            CRYP_DataIn(*(uint32_t*)&in[12]);\n\n            /* wait until the complete message has been processed */\n            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}\n\n            *(uint32_t*)&out[0]  = CRYP_DataOut();\n            *(uint32_t*)&out[4]  = CRYP_DataOut();\n            *(uint32_t*)&out[8]  = CRYP_DataOut();\n            *(uint32_t*)&out[12] = CRYP_DataOut();\n\n            /* disable crypto processor */\n            CRYP_Cmd(DISABLE);\n\n        #endif /* WOLFSSL_STM32_CUBEMX */\n\n            wolfSSL_CryptHwMutexUnLock();\n            return ret;\n        }\n\n\n    #elif defined(WOLFSSL_PIC32MZ_CRYPT)\n\n        #define NEED_AES_CTR_SOFT\n        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock\n\n        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)\n        {\n            word32 tmpIv[AES_BLOCK_SIZE / sizeof(word32)];\n            XMEMCPY(tmpIv, aes->reg, AES_BLOCK_SIZE);\n            return wc_Pic32AesCrypt(\n                aes->key, aes->keylen, tmpIv, AES_BLOCK_SIZE,\n                out, in, AES_BLOCK_SIZE,\n                PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);\n        }\n\n    #elif defined(HAVE_COLDFIRE_SEC)\n        #error \"Coldfire SEC doesn't currently support AES-CTR mode\"\n\n    #elif defined(FREESCALE_LTC)\n        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n        {\n            uint32_t keySize;\n            byte *iv, *enc_key;\n            byte* tmp;\n\n            if (aes == NULL || out == NULL || in == NULL) {\n                return BAD_FUNC_ARG;\n            }\n\n            /* consume any unused bytes left in aes->tmp */\n            tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;\n            while (aes->left && sz) {\n                *(out++) = *(in++) ^ *(tmp++);\n                aes->left--;\n                sz--;\n            }\n\n            if (sz) {\n                iv      = (byte*)aes->reg;\n                enc_key = (byte*)aes->key;\n\n                wc_AesGetKeySize(aes, &keySize);\n\n                LTC_AES_CryptCtr(LTC_BASE, in, out, sz,\n                    iv, enc_key, keySize, (byte*)aes->tmp,\n                    (uint32_t*)&aes->left);\n            }\n\n            return 0;\n        }\n\n    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)\n        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */\n\n    #elif defined(WOLFSSL_AFALG)\n        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */\n\n    #elif defined(WOLFSSL_DEVCRYPTO_AES)\n        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */\n\n    #else\n\n        /* Use software based AES counter */\n        #define NEED_AES_CTR_SOFT\n    #endif\n\n    #ifdef NEED_AES_CTR_SOFT\n        /* Increment AES counter */\n        static WC_INLINE void IncrementAesCounter(byte* inOutCtr)\n        {\n            /* in network byte order so start at end and work back */\n            int i;\n            for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {\n                if (++inOutCtr[i])  /* we're done unless we overflow */\n                    return;\n            }\n        }\n\n        /* Software AES - CTR Encrypt */\n        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n        {\n            byte* tmp;\n            byte scratch[AES_BLOCK_SIZE];\n\n            if (aes == NULL || out == NULL || in == NULL) {\n                return BAD_FUNC_ARG;\n            }\n\n            /* consume any unused bytes left in aes->tmp */\n            tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;\n            while (aes->left && sz) {\n               *(out++) = *(in++) ^ *(tmp++);\n               aes->left--;\n               sz--;\n            }\n\n            /* do as many block size ops as possible */\n            while (sz >= AES_BLOCK_SIZE) {\n            #ifdef XTRANSFORM_AESCTRBLOCK\n                XTRANSFORM_AESCTRBLOCK(aes, out, in);\n            #else\n                wc_AesEncrypt(aes, (byte*)aes->reg, scratch);\n                xorbuf(scratch, in, AES_BLOCK_SIZE);\n                XMEMCPY(out, scratch, AES_BLOCK_SIZE);\n            #endif\n                IncrementAesCounter((byte*)aes->reg);\n\n                out += AES_BLOCK_SIZE;\n                in  += AES_BLOCK_SIZE;\n                sz  -= AES_BLOCK_SIZE;\n                aes->left = 0;\n            }\n            ForceZero(scratch, AES_BLOCK_SIZE);\n\n            /* handle non block size remaining and store unused byte count in left */\n            if (sz) {\n                wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp);\n                IncrementAesCounter((byte*)aes->reg);\n\n                aes->left = AES_BLOCK_SIZE;\n                tmp = (byte*)aes->tmp;\n\n                while (sz--) {\n                    *(out++) = *(in++) ^ *(tmp++);\n                    aes->left--;\n                }\n            }\n\n            return 0;\n        }\n\n    #endif /* NEED_AES_CTR_SOFT */\n\n#endif /* WOLFSSL_AES_COUNTER */\n#endif /* !WOLFSSL_ARMASM */\n\n\n/*\n * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised\n * of two parts in order:\n *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set\n *      to the implicit IV.\n *   2. The explicit IV is generated by wolfCrypt. It needs to be managed\n *      by wolfCrypt to ensure the IV is unique for each call to encrypt.\n * The IV may be a 96-bit random value, or the 32-bit fixed value and a\n * 64-bit set of 0 or random data. The final 32-bits of reg is used as a\n * block counter during the encryption.\n */\n\n#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)\nstatic WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)\n{\n    int i;\n    for (i = ctrSz-1; i >= 0; i--) {\n        if (++ctr[i])\n            break;\n    }\n}\n#endif /* HAVE_AESGCM || HAVE_AESCCM */\n\n\n#ifdef HAVE_AESGCM\n\n#if defined(HAVE_COLDFIRE_SEC)\n    #error \"Coldfire SEC doesn't currently support AES-GCM mode\"\n\n#elif defined(WOLFSSL_NRF51_AES)\n    #error \"nRF51 doesn't currently support AES-GCM mode\"\n\n#endif\n\n#ifdef WOLFSSL_ARMASM\n    /* implementation is located in wolfcrypt/src/port/arm/armv8-aes.c */\n\n#elif defined(WOLFSSL_AFALG)\n    /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */\n\n#elif defined(WOLFSSL_DEVCRYPTO_AES)\n    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */\n\n#else /* software + AESNI implementation */\n\n#if !defined(FREESCALE_LTC_AES_GCM)\nstatic WC_INLINE void IncrementGcmCounter(byte* inOutCtr)\n{\n    int i;\n\n    /* in network byte order so start at end and work back */\n    for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) {\n        if (++inOutCtr[i])  /* we're done unless we overflow */\n            return;\n    }\n}\n#ifdef STM32_CRYPTO_AES_GCM\nstatic WC_INLINE void DecrementGcmCounter(byte* inOutCtr)\n{\n    int i;\n\n    /* in network byte order so start at end and work back */\n    for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) {\n        if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */\n            return;\n    }\n}\n#endif /* STM32_CRYPTO_AES_GCM */\n#endif /* !FREESCALE_LTC_AES_GCM */\n\n#if defined(GCM_SMALL) || defined(GCM_TABLE)\n\nstatic WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)\n{\n    /* Multiply the sz by 8 */\n    word32 szHi = (sz >> (8*sizeof(sz) - 3));\n    sz <<= 3;\n\n    /* copy over the words of the sz into the destination buffer */\n    buf[0] = (szHi >> 24) & 0xff;\n    buf[1] = (szHi >> 16) & 0xff;\n    buf[2] = (szHi >>  8) & 0xff;\n    buf[3] = szHi & 0xff;\n    buf[4] = (sz >> 24) & 0xff;\n    buf[5] = (sz >> 16) & 0xff;\n    buf[6] = (sz >>  8) & 0xff;\n    buf[7] = sz & 0xff;\n}\n\n\nstatic WC_INLINE void RIGHTSHIFTX(byte* x)\n{\n    int i;\n    int carryOut = 0;\n    int carryIn = 0;\n    int borrow = x[15] & 0x01;\n\n    for (i = 0; i < AES_BLOCK_SIZE; i++) {\n        carryOut = x[i] & 0x01;\n        x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0);\n        carryIn = carryOut;\n    }\n    if (borrow) x[0] ^= 0xE1;\n}\n\n#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) */\n\n\n#ifdef GCM_TABLE\n\nstatic void GenerateM0(Aes* aes)\n{\n    int i, j;\n    byte (*m)[AES_BLOCK_SIZE] = aes->M0;\n\n    XMEMCPY(m[128], aes->H, AES_BLOCK_SIZE);\n\n    for (i = 64; i > 0; i /= 2) {\n        XMEMCPY(m[i], m[i*2], AES_BLOCK_SIZE);\n        RIGHTSHIFTX(m[i]);\n    }\n\n    for (i = 2; i < 256; i *= 2) {\n        for (j = 1; j < i; j++) {\n            XMEMCPY(m[i+j], m[i], AES_BLOCK_SIZE);\n            xorbuf(m[i+j], m[j], AES_BLOCK_SIZE);\n        }\n    }\n\n    XMEMSET(m[0], 0, AES_BLOCK_SIZE);\n}\n\n#endif /* GCM_TABLE */\n\n/* Software AES - GCM SetKey */\nint wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)\n{\n    int  ret;\n    byte iv[AES_BLOCK_SIZE];\n\n    #ifdef WOLFSSL_IMX6_CAAM_BLOB\n        byte   local[32];\n        word32 localSz = 32;\n\n        if (len == (16 + WC_CAAM_BLOB_SZ) ||\n          len == (24 + WC_CAAM_BLOB_SZ) ||\n          len == (32 + WC_CAAM_BLOB_SZ)) {\n            if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {\n                 return BAD_FUNC_ARG;\n            }\n\n            /* set local values */\n            key = local;\n            len = localSz;\n        }\n    #endif\n\n    if (!((len == 16) || (len == 24) || (len == 32)))\n        return BAD_FUNC_ARG;\n\n#ifdef OPENSSL_EXTRA\n    if (aes != NULL) {\n        XMEMSET(aes->aadH, 0, sizeof(aes->aadH));\n        aes->aadLen = 0;\n    }\n#endif\n    XMEMSET(iv, 0, AES_BLOCK_SIZE);\n    ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);\n\n    #ifdef WOLFSSL_AESNI\n        /* AES-NI code generates its own H value. */\n        if (haveAESNI)\n            return ret;\n    #endif /* WOLFSSL_AESNI */\n\n#if !defined(FREESCALE_LTC_AES_GCM)\n    if (ret == 0) {\n        wc_AesEncrypt(aes, iv, aes->H);\n    #ifdef GCM_TABLE\n        GenerateM0(aes);\n    #endif /* GCM_TABLE */\n    }\n#endif /* FREESCALE_LTC_AES_GCM */\n\n#if defined(WOLFSSL_XILINX_CRYPT)\n    wc_AesGcmSetKey_ex(aes, key, len, XSECURE_CSU_AES_KEY_SRC_KUP);\n#elif defined(WOLFSSL_AFALG_XILINX_AES)\n    wc_AesGcmSetKey_ex(aes, key, len, 0);\n#endif\n\n#ifdef WOLF_CRYPTO_CB\n    if (aes->devId != INVALID_DEVID) {\n        XMEMCPY(aes->devKey, key, len);\n    }\n#endif\n\n#ifdef WOLFSSL_IMX6_CAAM_BLOB\n    ForceZero(local, sizeof(local));\n#endif\n\n    return ret;\n}\n\n\n#ifdef WOLFSSL_AESNI\n\n#if defined(USE_INTEL_SPEEDUP)\n    #define HAVE_INTEL_AVX1\n    #define HAVE_INTEL_AVX2\n#endif /* USE_INTEL_SPEEDUP */\n\n#ifndef _MSC_VER\n\nvoid AES_GCM_encrypt(const unsigned char *in, unsigned char *out,\n                     const unsigned char* addt, const unsigned char* ivec,\n                     unsigned char *tag, unsigned int nbytes,\n                     unsigned int abytes, unsigned int ibytes,\n                     unsigned int tbytes, const unsigned char* key, int nr)\n                     XASM_LINK(\"AES_GCM_encrypt\");\n#ifdef HAVE_INTEL_AVX1\nvoid AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,\n                          const unsigned char* addt, const unsigned char* ivec,\n                          unsigned char *tag, unsigned int nbytes,\n                          unsigned int abytes, unsigned int ibytes,\n                          unsigned int tbytes, const unsigned char* key,\n                          int nr)\n                          XASM_LINK(\"AES_GCM_encrypt_avx1\");\n#ifdef HAVE_INTEL_AVX2\nvoid AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,\n                          const unsigned char* addt, const unsigned char* ivec,\n                          unsigned char *tag, unsigned int nbytes,\n                          unsigned int abytes, unsigned int ibytes,\n                          unsigned int tbytes, const unsigned char* key,\n                          int nr)\n                          XASM_LINK(\"AES_GCM_encrypt_avx2\");\n#endif /* HAVE_INTEL_AVX2 */\n#endif /* HAVE_INTEL_AVX1 */\n\n#ifdef HAVE_AES_DECRYPT\nvoid AES_GCM_decrypt(const unsigned char *in, unsigned char *out,\n                     const unsigned char* addt, const unsigned char* ivec,\n                     const unsigned char *tag, int nbytes, int abytes,\n                     int ibytes, int tbytes, const unsigned char* key, int nr,\n                     int* res)\n                     XASM_LINK(\"AES_GCM_decrypt\");\n#ifdef HAVE_INTEL_AVX1\nvoid AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,\n                          const unsigned char* addt, const unsigned char* ivec,\n                          const unsigned char *tag, int nbytes, int abytes,\n                          int ibytes, int tbytes, const unsigned char* key,\n                          int nr, int* res)\n                          XASM_LINK(\"AES_GCM_decrypt_avx1\");\n#ifdef HAVE_INTEL_AVX2\nvoid AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,\n                          const unsigned char* addt, const unsigned char* ivec,\n                          const unsigned char *tag, int nbytes, int abytes,\n                          int ibytes, int tbytes, const unsigned char* key,\n                          int nr, int* res)\n                          XASM_LINK(\"AES_GCM_decrypt_avx2\");\n#endif /* HAVE_INTEL_AVX2 */\n#endif /* HAVE_INTEL_AVX1 */\n#endif /* HAVE_AES_DECRYPT */\n\n#else /* _MSC_VER */\n\n#define S(w,z) ((char)((unsigned long long)(w) >> (8*(7-(z))) & 0xFF))\n#define M128_INIT(x,y) { S((x),7), S((x),6), S((x),5), S((x),4), \\\n                         S((x),3), S((x),2), S((x),1), S((x),0), \\\n                         S((y),7), S((y),6), S((y),5), S((y),4), \\\n                         S((y),3), S((y),2), S((y),1), S((y),0) }\n\nstatic const __m128i MOD2_128 =\n        M128_INIT(0x1, (long long int)0xc200000000000000UL);\n\n\n/* See Intel® Carry-Less Multiplication Instruction\n * and its Usage for Computing the GCM Mode White Paper\n * by Shay Gueron, Intel Mobility Group, Israel Development Center;\n * and Michael E. Kounavis, Intel Labs, Circuits and Systems Research */\n\n\n/* Figure 9. AES-GCM – Encrypt With Single Block Ghash at a Time */\n\nstatic const __m128i ONE   = M128_INIT(0x0, 0x1);\n#ifndef AES_GCM_AESNI_NO_UNROLL\nstatic const __m128i TWO   = M128_INIT(0x0, 0x2);\nstatic const __m128i THREE = M128_INIT(0x0, 0x3);\nstatic const __m128i FOUR  = M128_INIT(0x0, 0x4);\nstatic const __m128i FIVE  = M128_INIT(0x0, 0x5);\nstatic const __m128i SIX   = M128_INIT(0x0, 0x6);\nstatic const __m128i SEVEN = M128_INIT(0x0, 0x7);\nstatic const __m128i EIGHT = M128_INIT(0x0, 0x8);\n#endif\nstatic const __m128i BSWAP_EPI64 =\n        M128_INIT(0x0001020304050607, 0x08090a0b0c0d0e0f);\nstatic const __m128i BSWAP_MASK =\n        M128_INIT(0x08090a0b0c0d0e0f, 0x0001020304050607);\n\n\n/* The following are for MSC based builds which do not allow\n * inline assembly. Intrinsic functions are used instead. */\n\n#define aes_gcm_calc_iv_12(KEY, ivec, nr, H, Y, T)         \\\ndo                                                         \\\n{                                                          \\\n    word32 iv12[4];                                        \\\n    iv12[0] = *(word32*)&ivec[0];                          \\\n    iv12[1] = *(word32*)&ivec[4];                          \\\n    iv12[2] = *(word32*)&ivec[8];                          \\\n    iv12[3] = 0x01000000;                                  \\\n    Y = _mm_loadu_si128((__m128i*)iv12);                   \\\n                                                           \\\n    /* (Compute E[ZERO, KS] and E[Y0, KS] together */      \\\n    tmp1 = _mm_load_si128(&KEY[0]);                        \\\n    tmp2 = _mm_xor_si128(Y, KEY[0]);                       \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);                 \\\n    tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);                 \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);                 \\\n    tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);                 \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);                 \\\n    tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);                 \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);                 \\\n    tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);                 \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);                 \\\n    tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);                 \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);                 \\\n    tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);                 \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);                 \\\n    tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);                 \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);                 \\\n    tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);                 \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);                 \\\n    tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);                 \\\n    lastKey = KEY[10];                                     \\\n    if (nr > 10) {                                         \\\n        tmp1 = _mm_aesenc_si128(tmp1, lastKey);            \\\n        tmp2 = _mm_aesenc_si128(tmp2, lastKey);            \\\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);            \\\n        tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);            \\\n        lastKey = KEY[12];                                 \\\n        if (nr > 12) {                                     \\\n            tmp1 = _mm_aesenc_si128(tmp1, lastKey);        \\\n            tmp2 = _mm_aesenc_si128(tmp2, lastKey);        \\\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);        \\\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);        \\\n            lastKey = KEY[14];                             \\\n        }                                                  \\\n    }                                                      \\\n    H = _mm_aesenclast_si128(tmp1, lastKey);               \\\n    T = _mm_aesenclast_si128(tmp2, lastKey);               \\\n    H = _mm_shuffle_epi8(H, BSWAP_MASK);                   \\\n}                                                          \\\nwhile (0)\n\n#define aes_gcm_calc_iv(KEY, ivec, ibytes, nr, H, Y, T)         \\\ndo                                                              \\\n{                                                               \\\n    if (ibytes % 16) {                                          \\\n        i = ibytes / 16;                                        \\\n        for (j=0; j < (int)(ibytes%16); j++)                    \\\n            ((unsigned char*)&last_block)[j] = ivec[i*16+j];    \\\n    }                                                           \\\n    tmp1 = _mm_load_si128(&KEY[0]);                             \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);                      \\\n    lastKey = KEY[10];                                          \\\n    if (nr > 10) {                                              \\\n        tmp1 = _mm_aesenc_si128(tmp1, lastKey);                 \\\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);                 \\\n        lastKey = KEY[12];                                      \\\n        if (nr > 12) {                                          \\\n            tmp1 = _mm_aesenc_si128(tmp1, lastKey);             \\\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);             \\\n            lastKey = KEY[14];                                  \\\n        }                                                       \\\n    }                                                           \\\n    H = _mm_aesenclast_si128(tmp1, lastKey);                    \\\n    H = _mm_shuffle_epi8(H, BSWAP_MASK);                        \\\n    Y = _mm_setzero_si128();                                    \\\n    for (i=0; i < (int)(ibytes/16); i++) {                      \\\n        tmp1 = _mm_loadu_si128(&((__m128i*)ivec)[i]);           \\\n        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);              \\\n        Y = _mm_xor_si128(Y, tmp1);                             \\\n        Y = gfmul_sw(Y, H);                                     \\\n    }                                                           \\\n    if (ibytes % 16) {                                          \\\n        tmp1 = last_block;                                      \\\n        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);              \\\n        Y = _mm_xor_si128(Y, tmp1);                             \\\n        Y = gfmul_sw(Y, H);                                     \\\n    }                                                           \\\n    tmp1 = _mm_insert_epi64(tmp1, ibytes*8, 0);                 \\\n    tmp1 = _mm_insert_epi64(tmp1, 0, 1);                        \\\n    Y = _mm_xor_si128(Y, tmp1);                                 \\\n    Y = gfmul_sw(Y, H);                                         \\\n    Y = _mm_shuffle_epi8(Y, BSWAP_MASK); /* Compute E(K, Y0) */ \\\n    tmp1 = _mm_xor_si128(Y, KEY[0]);                            \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);                      \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);                      \\\n    lastKey = KEY[10];                                          \\\n    if (nr > 10) {                                              \\\n        tmp1 = _mm_aesenc_si128(tmp1, lastKey);                 \\\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);                 \\\n        lastKey = KEY[12];                                      \\\n        if (nr > 12) {                                          \\\n            tmp1 = _mm_aesenc_si128(tmp1, lastKey);             \\\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);             \\\n            lastKey = KEY[14];                                  \\\n        }                                                       \\\n    }                                                           \\\n    T = _mm_aesenclast_si128(tmp1, lastKey);                    \\\n}                                                               \\\nwhile (0)\n\n#define AES_ENC_8(j)                       \\\n    tmp1 = _mm_aesenc_si128(tmp1, KEY[j]); \\\n    tmp2 = _mm_aesenc_si128(tmp2, KEY[j]); \\\n    tmp3 = _mm_aesenc_si128(tmp3, KEY[j]); \\\n    tmp4 = _mm_aesenc_si128(tmp4, KEY[j]); \\\n    tmp5 = _mm_aesenc_si128(tmp5, KEY[j]); \\\n    tmp6 = _mm_aesenc_si128(tmp6, KEY[j]); \\\n    tmp7 = _mm_aesenc_si128(tmp7, KEY[j]); \\\n    tmp8 = _mm_aesenc_si128(tmp8, KEY[j]);\n\n#define AES_ENC_LAST_8()                                                  \\\n    tmp1 =_mm_aesenclast_si128(tmp1, lastKey);                            \\\n    tmp2 =_mm_aesenclast_si128(tmp2, lastKey);                            \\\n    tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[i*8+0]));  \\\n    tmp2 = _mm_xor_si128(tmp2, _mm_loadu_si128(&((__m128i*)in)[i*8+1]));  \\\n    _mm_storeu_si128(&((__m128i*)out)[i*8+0], tmp1);                      \\\n    _mm_storeu_si128(&((__m128i*)out)[i*8+1], tmp2);                      \\\n    tmp3 =_mm_aesenclast_si128(tmp3, lastKey);                            \\\n    tmp4 =_mm_aesenclast_si128(tmp4, lastKey);                            \\\n    tmp3 = _mm_xor_si128(tmp3, _mm_loadu_si128(&((__m128i*)in)[i*8+2]));  \\\n    tmp4 = _mm_xor_si128(tmp4, _mm_loadu_si128(&((__m128i*)in)[i*8+3]));  \\\n    _mm_storeu_si128(&((__m128i*)out)[i*8+2], tmp3);                      \\\n    _mm_storeu_si128(&((__m128i*)out)[i*8+3], tmp4);                      \\\n    tmp5 =_mm_aesenclast_si128(tmp5, lastKey);                            \\\n    tmp6 =_mm_aesenclast_si128(tmp6, lastKey);                            \\\n    tmp5 = _mm_xor_si128(tmp5, _mm_loadu_si128(&((__m128i*)in)[i*8+4]));  \\\n    tmp6 = _mm_xor_si128(tmp6, _mm_loadu_si128(&((__m128i*)in)[i*8+5]));  \\\n    _mm_storeu_si128(&((__m128i*)out)[i*8+4], tmp5);                      \\\n    _mm_storeu_si128(&((__m128i*)out)[i*8+5], tmp6);                      \\\n    tmp7 =_mm_aesenclast_si128(tmp7, lastKey);                            \\\n    tmp8 =_mm_aesenclast_si128(tmp8, lastKey);                            \\\n    tmp7 = _mm_xor_si128(tmp7, _mm_loadu_si128(&((__m128i*)in)[i*8+6]));  \\\n    tmp8 = _mm_xor_si128(tmp8, _mm_loadu_si128(&((__m128i*)in)[i*8+7]));  \\\n    _mm_storeu_si128(&((__m128i*)out)[i*8+6], tmp7);                      \\\n    _mm_storeu_si128(&((__m128i*)out)[i*8+7], tmp8);\n\n\nstatic __m128i gfmul_sw(__m128i a, __m128i b)\n{\n    __m128i r, t1, t2, t3, t4, t5, t6, t7;\n    t2 = _mm_shuffle_epi32(b, 78);\n    t3 = _mm_shuffle_epi32(a, 78);\n    t2 = _mm_xor_si128(t2, b);\n    t3 = _mm_xor_si128(t3, a);\n    t4 = _mm_clmulepi64_si128(b, a, 0x11);\n    t1 = _mm_clmulepi64_si128(b, a, 0x00);\n    t2 = _mm_clmulepi64_si128(t2, t3, 0x00);\n    t2 = _mm_xor_si128(t2, t1);\n    t2 = _mm_xor_si128(t2, t4);\n    t3 = _mm_slli_si128(t2, 8);\n    t2 = _mm_srli_si128(t2, 8);\n    t1 = _mm_xor_si128(t1, t3);\n    t4 = _mm_xor_si128(t4, t2);\n\n    t5 = _mm_srli_epi32(t1, 31);\n    t6 = _mm_srli_epi32(t4, 31);\n    t1 = _mm_slli_epi32(t1, 1);\n    t4 = _mm_slli_epi32(t4, 1);\n    t7 = _mm_srli_si128(t5, 12);\n    t5 = _mm_slli_si128(t5, 4);\n    t6 = _mm_slli_si128(t6, 4);\n    t4 = _mm_or_si128(t4, t7);\n    t1 = _mm_or_si128(t1, t5);\n    t4 = _mm_or_si128(t4, t6);\n\n    t5 = _mm_slli_epi32(t1, 31);\n    t6 = _mm_slli_epi32(t1, 30);\n    t7 = _mm_slli_epi32(t1, 25);\n    t5 = _mm_xor_si128(t5, t6);\n    t5 = _mm_xor_si128(t5, t7);\n\n    t6 = _mm_srli_si128(t5, 4);\n    t5 = _mm_slli_si128(t5, 12);\n    t1 = _mm_xor_si128(t1, t5);\n    t7 = _mm_srli_epi32(t1, 1);\n    t3 = _mm_srli_epi32(t1, 2);\n    t2 = _mm_srli_epi32(t1, 7);\n\n    t7 = _mm_xor_si128(t7, t3);\n    t7 = _mm_xor_si128(t7, t2);\n    t7 = _mm_xor_si128(t7, t6);\n    t7 = _mm_xor_si128(t7, t1);\n    r = _mm_xor_si128(t4, t7);\n\n    return r;\n}\n\nstatic void gfmul_only(__m128i a, __m128i b, __m128i* r0, __m128i* r1)\n{\n    __m128i t1, t2, t3, t4;\n\n    /* 128 x 128 Carryless Multiply */\n    t2 = _mm_shuffle_epi32(b, 78);\n    t3 = _mm_shuffle_epi32(a, 78);\n    t2 = _mm_xor_si128(t2, b);\n    t3 = _mm_xor_si128(t3, a);\n    t4 = _mm_clmulepi64_si128(b, a, 0x11);\n    t1 = _mm_clmulepi64_si128(b, a, 0x00);\n    t2 = _mm_clmulepi64_si128(t2, t3, 0x00);\n    t2 = _mm_xor_si128(t2, t1);\n    t2 = _mm_xor_si128(t2, t4);\n    t3 = _mm_slli_si128(t2, 8);\n    t2 = _mm_srli_si128(t2, 8);\n    t1 = _mm_xor_si128(t1, t3);\n    t4 = _mm_xor_si128(t4, t2);\n    *r0 = _mm_xor_si128(t1, *r0);\n    *r1 = _mm_xor_si128(t4, *r1);\n}\n\nstatic __m128i gfmul_shl1(__m128i a)\n{\n    __m128i t1 = a, t2;\n    t2 = _mm_srli_epi64(t1, 63);\n    t1 = _mm_slli_epi64(t1, 1);\n    t2 = _mm_slli_si128(t2, 8);\n    t1 = _mm_or_si128(t1, t2);\n    /* if (a[1] >> 63) t1 = _mm_xor_si128(t1, MOD2_128); */\n    a = _mm_shuffle_epi32(a, 0xff);\n    a = _mm_srai_epi32(a, 31);\n    a = _mm_and_si128(a, MOD2_128);\n    t1 = _mm_xor_si128(t1, a);\n    return t1;\n}\n\nstatic __m128i ghash_red(__m128i r0, __m128i r1)\n{\n    __m128i t2, t3;\n    __m128i t5, t6, t7;\n\n    t5 = _mm_slli_epi32(r0, 31);\n    t6 = _mm_slli_epi32(r0, 30);\n    t7 = _mm_slli_epi32(r0, 25);\n    t5 = _mm_xor_si128(t5, t6);\n    t5 = _mm_xor_si128(t5, t7);\n\n    t6 = _mm_srli_si128(t5, 4);\n    t5 = _mm_slli_si128(t5, 12);\n    r0 = _mm_xor_si128(r0, t5);\n    t7 = _mm_srli_epi32(r0, 1);\n    t3 = _mm_srli_epi32(r0, 2);\n    t2 = _mm_srli_epi32(r0, 7);\n\n    t7 = _mm_xor_si128(t7, t3);\n    t7 = _mm_xor_si128(t7, t2);\n    t7 = _mm_xor_si128(t7, t6);\n    t7 = _mm_xor_si128(t7, r0);\n    return _mm_xor_si128(r1, t7);\n}\n\nstatic __m128i gfmul_shifted(__m128i a, __m128i b)\n{\n    __m128i t0 = _mm_setzero_si128(), t1 = _mm_setzero_si128();\n    gfmul_only(a, b, &t0, &t1);\n    return ghash_red(t0, t1);\n}\n\n#ifndef AES_GCM_AESNI_NO_UNROLL\nstatic __m128i gfmul8(__m128i a1, __m128i a2, __m128i a3, __m128i a4,\n                      __m128i a5, __m128i a6, __m128i a7, __m128i a8,\n                      __m128i b1, __m128i b2, __m128i b3, __m128i b4,\n                      __m128i b5, __m128i b6, __m128i b7, __m128i b8)\n{\n    __m128i t0 = _mm_setzero_si128(), t1 = _mm_setzero_si128();\n    gfmul_only(a1, b8, &t0, &t1);\n    gfmul_only(a2, b7, &t0, &t1);\n    gfmul_only(a3, b6, &t0, &t1);\n    gfmul_only(a4, b5, &t0, &t1);\n    gfmul_only(a5, b4, &t0, &t1);\n    gfmul_only(a6, b3, &t0, &t1);\n    gfmul_only(a7, b2, &t0, &t1);\n    gfmul_only(a8, b1, &t0, &t1);\n    return ghash_red(t0, t1);\n}\n#endif\n\n\nstatic void AES_GCM_encrypt(const unsigned char *in,\n                              unsigned char *out,\n                              const unsigned char* addt,\n                              const unsigned char* ivec,\n                              unsigned char *tag, unsigned int nbytes,\n                              unsigned int abytes, unsigned int ibytes,\n                              unsigned int tbytes,\n                              const unsigned char* key, int nr)\n{\n    int i, j ,k;\n    __m128i ctr1;\n    __m128i H, Y, T;\n    __m128i X = _mm_setzero_si128();\n    __m128i *KEY = (__m128i*)key, lastKey;\n    __m128i last_block = _mm_setzero_si128();\n    __m128i tmp1, tmp2;\n#ifndef AES_GCM_AESNI_NO_UNROLL\n    __m128i HT[8];\n    __m128i r0, r1;\n    __m128i XV;\n    __m128i tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;\n#endif\n\n    if (ibytes == GCM_NONCE_MID_SZ)\n        aes_gcm_calc_iv_12(KEY, ivec, nr, H, Y, T);\n    else\n        aes_gcm_calc_iv(KEY, ivec, ibytes, nr, H, Y, T);\n\n    for (i=0; i < (int)(abytes/16); i++) {\n        tmp1 = _mm_loadu_si128(&((__m128i*)addt)[i]);\n        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);\n        X = _mm_xor_si128(X, tmp1);\n        X = gfmul_sw(X, H);\n    }\n    if (abytes%16) {\n        last_block = _mm_setzero_si128();\n        for (j=0; j < (int)(abytes%16); j++)\n            ((unsigned char*)&last_block)[j] = addt[i*16+j];\n        tmp1 = last_block;\n        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);\n        X = _mm_xor_si128(X, tmp1);\n        X = gfmul_sw(X, H);\n    }\n    tmp1 = _mm_shuffle_epi8(Y, BSWAP_EPI64);\n    ctr1 = _mm_add_epi32(tmp1, ONE);\n    H = gfmul_shl1(H);\n\n#ifndef AES_GCM_AESNI_NO_UNROLL\n    i = 0;\n    if (nbytes >= 16*8) {\n        HT[0] = H;\n        HT[1] = gfmul_shifted(H, H);\n        HT[2] = gfmul_shifted(H, HT[1]);\n        HT[3] = gfmul_shifted(HT[1], HT[1]);\n        HT[4] = gfmul_shifted(HT[1], HT[2]);\n        HT[5] = gfmul_shifted(HT[2], HT[2]);\n        HT[6] = gfmul_shifted(HT[2], HT[3]);\n        HT[7] = gfmul_shifted(HT[3], HT[3]);\n\n        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);\n        tmp2 = _mm_add_epi32(ctr1, ONE);\n        tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_EPI64);\n        tmp3 = _mm_add_epi32(ctr1, TWO);\n        tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_EPI64);\n        tmp4 = _mm_add_epi32(ctr1, THREE);\n        tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_EPI64);\n        tmp5 = _mm_add_epi32(ctr1, FOUR);\n        tmp5 = _mm_shuffle_epi8(tmp5, BSWAP_EPI64);\n        tmp6 = _mm_add_epi32(ctr1, FIVE);\n        tmp6 = _mm_shuffle_epi8(tmp6, BSWAP_EPI64);\n        tmp7 = _mm_add_epi32(ctr1, SIX);\n        tmp7 = _mm_shuffle_epi8(tmp7, BSWAP_EPI64);\n        tmp8 = _mm_add_epi32(ctr1, SEVEN);\n        tmp8 = _mm_shuffle_epi8(tmp8, BSWAP_EPI64);\n        ctr1 = _mm_add_epi32(ctr1, EIGHT);\n        tmp1 =_mm_xor_si128(tmp1, KEY[0]);\n        tmp2 =_mm_xor_si128(tmp2, KEY[0]);\n        tmp3 =_mm_xor_si128(tmp3, KEY[0]);\n        tmp4 =_mm_xor_si128(tmp4, KEY[0]);\n        tmp5 =_mm_xor_si128(tmp5, KEY[0]);\n        tmp6 =_mm_xor_si128(tmp6, KEY[0]);\n        tmp7 =_mm_xor_si128(tmp7, KEY[0]);\n        tmp8 =_mm_xor_si128(tmp8, KEY[0]);\n        AES_ENC_8(1);\n        AES_ENC_8(2);\n        AES_ENC_8(3);\n        AES_ENC_8(4);\n        AES_ENC_8(5);\n        AES_ENC_8(6);\n        AES_ENC_8(7);\n        AES_ENC_8(8);\n        AES_ENC_8(9);\n        lastKey = KEY[10];\n        if (nr > 10) {\n            AES_ENC_8(10);\n            AES_ENC_8(11);\n            lastKey = KEY[12];\n            if (nr > 12) {\n                AES_ENC_8(12);\n                AES_ENC_8(13);\n                lastKey = KEY[14];\n            }\n        }\n        AES_ENC_LAST_8();\n\n        for (i=1; i < (int)(nbytes/16/8); i++) {\n                r0 = _mm_setzero_si128();\n                r1 = _mm_setzero_si128();\n            tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);\n            tmp2 = _mm_add_epi32(ctr1, ONE);\n            tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_EPI64);\n            tmp3 = _mm_add_epi32(ctr1, TWO);\n            tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_EPI64);\n            tmp4 = _mm_add_epi32(ctr1, THREE);\n            tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_EPI64);\n            tmp5 = _mm_add_epi32(ctr1, FOUR);\n            tmp5 = _mm_shuffle_epi8(tmp5, BSWAP_EPI64);\n            tmp6 = _mm_add_epi32(ctr1, FIVE);\n            tmp6 = _mm_shuffle_epi8(tmp6, BSWAP_EPI64);\n            tmp7 = _mm_add_epi32(ctr1, SIX);\n            tmp7 = _mm_shuffle_epi8(tmp7, BSWAP_EPI64);\n            tmp8 = _mm_add_epi32(ctr1, SEVEN);\n            tmp8 = _mm_shuffle_epi8(tmp8, BSWAP_EPI64);\n            ctr1 = _mm_add_epi32(ctr1, EIGHT);\n            tmp1 =_mm_xor_si128(tmp1, KEY[0]);\n            tmp2 =_mm_xor_si128(tmp2, KEY[0]);\n            tmp3 =_mm_xor_si128(tmp3, KEY[0]);\n            tmp4 =_mm_xor_si128(tmp4, KEY[0]);\n            tmp5 =_mm_xor_si128(tmp5, KEY[0]);\n            tmp6 =_mm_xor_si128(tmp6, KEY[0]);\n            tmp7 =_mm_xor_si128(tmp7, KEY[0]);\n            tmp8 =_mm_xor_si128(tmp8, KEY[0]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+0]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                XV = _mm_xor_si128(XV, X);\n                gfmul_only(XV, HT[7], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[1]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[1]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[1]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[1]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[1]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[1]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+1]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[6], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[2]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[2]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[2]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[2]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[2]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[2]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+2]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[5], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[3]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[3]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[3]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[3]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[3]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[3]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+3]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[4], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[4]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[4]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[4]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[4]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[4]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[4]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+4]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[3], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[5]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[5]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[5]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[5]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[5]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[5]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+5]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[2], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[6]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[6]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[6]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[6]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[6]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[6]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+6]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[1], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[7]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[7]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[7]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[7]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[7]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[7]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)out)[(i-1)*8+7]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[0], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[8]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[8]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[8]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[8]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[8]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[8]);\n                /* Reduction */\n                X = ghash_red(r0, r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[9]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[9]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[9]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[9]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[9]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[9]);\n            lastKey = KEY[10];\n            if (nr > 10) {\n                tmp1 = _mm_aesenc_si128(tmp1, KEY[10]);\n                tmp2 = _mm_aesenc_si128(tmp2, KEY[10]);\n                tmp3 = _mm_aesenc_si128(tmp3, KEY[10]);\n                tmp4 = _mm_aesenc_si128(tmp4, KEY[10]);\n                tmp5 = _mm_aesenc_si128(tmp5, KEY[10]);\n                tmp6 = _mm_aesenc_si128(tmp6, KEY[10]);\n                tmp7 = _mm_aesenc_si128(tmp7, KEY[10]);\n                tmp8 = _mm_aesenc_si128(tmp8, KEY[10]);\n                tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);\n                tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);\n                tmp3 = _mm_aesenc_si128(tmp3, KEY[11]);\n                tmp4 = _mm_aesenc_si128(tmp4, KEY[11]);\n                tmp5 = _mm_aesenc_si128(tmp5, KEY[11]);\n                tmp6 = _mm_aesenc_si128(tmp6, KEY[11]);\n                tmp7 = _mm_aesenc_si128(tmp7, KEY[11]);\n                tmp8 = _mm_aesenc_si128(tmp8, KEY[11]);\n                lastKey = KEY[12];\n                if (nr > 12) {\n                    tmp1 = _mm_aesenc_si128(tmp1, KEY[12]);\n                    tmp2 = _mm_aesenc_si128(tmp2, KEY[12]);\n                    tmp3 = _mm_aesenc_si128(tmp3, KEY[12]);\n                    tmp4 = _mm_aesenc_si128(tmp4, KEY[12]);\n                    tmp5 = _mm_aesenc_si128(tmp5, KEY[12]);\n                    tmp6 = _mm_aesenc_si128(tmp6, KEY[12]);\n                    tmp7 = _mm_aesenc_si128(tmp7, KEY[12]);\n                    tmp8 = _mm_aesenc_si128(tmp8, KEY[12]);\n                    tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);\n                    tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);\n                    tmp3 = _mm_aesenc_si128(tmp3, KEY[13]);\n                    tmp4 = _mm_aesenc_si128(tmp4, KEY[13]);\n                    tmp5 = _mm_aesenc_si128(tmp5, KEY[13]);\n                    tmp6 = _mm_aesenc_si128(tmp6, KEY[13]);\n                    tmp7 = _mm_aesenc_si128(tmp7, KEY[13]);\n                    tmp8 = _mm_aesenc_si128(tmp8, KEY[13]);\n                    lastKey = KEY[14];\n                }\n            }\n            AES_ENC_LAST_8();\n        }\n\n        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);\n        tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_MASK);\n        tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_MASK);\n        tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_MASK);\n        tmp5 = _mm_shuffle_epi8(tmp5, BSWAP_MASK);\n        tmp6 = _mm_shuffle_epi8(tmp6, BSWAP_MASK);\n        tmp7 = _mm_shuffle_epi8(tmp7, BSWAP_MASK);\n        tmp8 = _mm_shuffle_epi8(tmp8, BSWAP_MASK);\n        tmp1 = _mm_xor_si128(X, tmp1);\n        X = gfmul8(tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8,\n                   HT[0], HT[1], HT[2], HT[3], HT[4], HT[5], HT[6], HT[7]);\n    }\n    for (k = i*8; k < (int)(nbytes/16); k++) {\n        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);\n        ctr1 = _mm_add_epi32(ctr1, ONE);\n        tmp1 = _mm_xor_si128(tmp1, KEY[0]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);\n        lastKey = KEY[10];\n        if (nr > 10) {\n            tmp1 = _mm_aesenc_si128(tmp1, lastKey);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);\n            lastKey = KEY[12];\n            if (nr > 12) {\n                tmp1 = _mm_aesenc_si128(tmp1, lastKey);\n                tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);\n                lastKey = KEY[14];\n            }\n        }\n        tmp1 = _mm_aesenclast_si128(tmp1, lastKey);\n        tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));\n        _mm_storeu_si128(&((__m128i*)out)[k], tmp1);\n        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);\n        X =_mm_xor_si128(X, tmp1);\n        X = gfmul_shifted(X, H);\n    }\n#else /* AES_GCM_AESNI_NO_UNROLL */\n    for (k = 0; k < (int)(nbytes/16) && k < 1; k++) {\n        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);\n        ctr1 = _mm_add_epi32(ctr1, ONE);\n        tmp1 = _mm_xor_si128(tmp1, KEY[0]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);\n        lastKey = KEY[10];\n        if (nr > 10) {\n            tmp1 = _mm_aesenc_si128(tmp1, lastKey);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);\n            lastKey = KEY[12];\n            if (nr > 12) {\n                tmp1 = _mm_aesenc_si128(tmp1, lastKey);\n                tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);\n                lastKey = KEY[14];\n            }\n        }\n        tmp1 = _mm_aesenclast_si128(tmp1, lastKey);\n        tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));\n        _mm_storeu_si128(&((__m128i*)out)[k], tmp1);\n        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);\n        X =_mm_xor_si128(X, tmp1);\n    }\n    for (; k < (int)(nbytes/16); k++) {\n        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);\n        ctr1 = _mm_add_epi32(ctr1, ONE);\n        tmp1 = _mm_xor_si128(tmp1, KEY[0]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);\n        X = gfmul_shifted(X, H);\n        lastKey = KEY[10];\n        if (nr > 10) {\n            tmp1 = _mm_aesenc_si128(tmp1, lastKey);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);\n            lastKey = KEY[12];\n            if (nr > 12) {\n                tmp1 = _mm_aesenc_si128(tmp1, lastKey);\n                tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);\n                lastKey = KEY[14];\n            }\n        }\n        tmp1 = _mm_aesenclast_si128(tmp1, lastKey);\n        tmp1 = _mm_xor_si128(tmp1, _mm_loadu_si128(&((__m128i*)in)[k]));\n        _mm_storeu_si128(&((__m128i*)out)[k], tmp1);\n        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);\n        X =_mm_xor_si128(X, tmp1);\n    }\n    if (k > 0) {\n        X = gfmul_shifted(X, H);\n    }\n#endif /* AES_GCM_AESNI_NO_UNROLL */\n\n    /* If one partial block remains */\n    if (nbytes % 16) {\n        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);\n        tmp1 = _mm_xor_si128(tmp1, KEY[0]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);\n        lastKey = KEY[10];\n        if (nr > 10) {\n            tmp1 = _mm_aesenc_si128(tmp1, lastKey);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);\n            lastKey = KEY[12];\n            if (nr > 12) {\n                tmp1 = _mm_aesenc_si128(tmp1, lastKey);\n                tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);\n                lastKey = KEY[14];\n            }\n        }\n        tmp1 = _mm_aesenclast_si128(tmp1, lastKey);\n        last_block = tmp1;\n        for (j=0; j < (int)(nbytes%16); j++)\n            ((unsigned char*)&last_block)[j] = in[k*16+j];\n        tmp1 = _mm_xor_si128(tmp1, last_block);\n        last_block = tmp1;\n        for (j=0; j < (int)(nbytes%16); j++)\n            out[k*16+j] = ((unsigned char*)&last_block)[j];\n        tmp1 = last_block;\n        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);\n        X =_mm_xor_si128(X, tmp1);\n        X = gfmul_shifted(X, H);\n    }\n    tmp1 = _mm_insert_epi64(tmp1, nbytes*8, 0);\n    tmp1 = _mm_insert_epi64(tmp1, abytes*8, 1);\n    X = _mm_xor_si128(X, tmp1);\n    X = gfmul_shifted(X, H);\n    X = _mm_shuffle_epi8(X, BSWAP_MASK);\n    T = _mm_xor_si128(X, T);\n    /*_mm_storeu_si128((__m128i*)tag, T);*/\n    XMEMCPY(tag, &T, tbytes);\n}\n\n#ifdef HAVE_AES_DECRYPT\n\nstatic void AES_GCM_decrypt(const unsigned char *in,\n                           unsigned char *out,\n                           const unsigned char* addt,\n                           const unsigned char* ivec,\n                           const unsigned char *tag, int nbytes, int abytes,\n                           int ibytes, word32 tbytes, const unsigned char* key,\n                           int nr, int* res)\n{\n    int i, j ,k;\n    __m128i H, Y, T;\n    __m128i *KEY = (__m128i*)key, lastKey;\n    __m128i ctr1;\n    __m128i last_block = _mm_setzero_si128();\n    __m128i X = _mm_setzero_si128();\n    __m128i tmp1, tmp2, XV;\n#ifndef AES_GCM_AESNI_NO_UNROLL\n    __m128i HT[8];\n    __m128i r0, r1;\n    __m128i tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;\n#endif /* AES_GCM_AESNI_NO_UNROLL */\n\n    if (ibytes == GCM_NONCE_MID_SZ)\n        aes_gcm_calc_iv_12(KEY, ivec, nr, H, Y, T);\n    else\n        aes_gcm_calc_iv(KEY, ivec, ibytes, nr, H, Y, T);\n\n    for (i=0; i<abytes/16; i++) {\n        tmp1 = _mm_loadu_si128(&((__m128i*)addt)[i]);\n        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);\n        X = _mm_xor_si128(X, tmp1);\n        X = gfmul_sw(X, H);\n    }\n    if (abytes%16) {\n        last_block = _mm_setzero_si128();\n        for (j=0; j<abytes%16; j++)\n            ((unsigned char*)&last_block)[j] = addt[i*16+j];\n        tmp1 = last_block;\n        tmp1 = _mm_shuffle_epi8(tmp1, BSWAP_MASK);\n        X = _mm_xor_si128(X, tmp1);\n        X = gfmul_sw(X, H);\n    }\n\n    tmp1 = _mm_shuffle_epi8(Y, BSWAP_EPI64);\n    ctr1 = _mm_add_epi32(tmp1, ONE);\n    H = gfmul_shl1(H);\n    i = 0;\n\n#ifndef AES_GCM_AESNI_NO_UNROLL\n\n    if (0 < nbytes/16/8) {\n        HT[0] = H;\n        HT[1] = gfmul_shifted(H, H);\n        HT[2] = gfmul_shifted(H, HT[1]);\n        HT[3] = gfmul_shifted(HT[1], HT[1]);\n        HT[4] = gfmul_shifted(HT[1], HT[2]);\n        HT[5] = gfmul_shifted(HT[2], HT[2]);\n        HT[6] = gfmul_shifted(HT[2], HT[3]);\n        HT[7] = gfmul_shifted(HT[3], HT[3]);\n\n        for (; i < nbytes/16/8; i++) {\n                r0 = _mm_setzero_si128();\n                r1 = _mm_setzero_si128();\n\n            tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);\n            tmp2 = _mm_add_epi32(ctr1, ONE);\n            tmp2 = _mm_shuffle_epi8(tmp2, BSWAP_EPI64);\n            tmp3 = _mm_add_epi32(ctr1, TWO);\n            tmp3 = _mm_shuffle_epi8(tmp3, BSWAP_EPI64);\n            tmp4 = _mm_add_epi32(ctr1, THREE);\n            tmp4 = _mm_shuffle_epi8(tmp4, BSWAP_EPI64);\n            tmp5 = _mm_add_epi32(ctr1, FOUR);\n            tmp5 = _mm_shuffle_epi8(tmp5, BSWAP_EPI64);\n            tmp6 = _mm_add_epi32(ctr1, FIVE);\n            tmp6 = _mm_shuffle_epi8(tmp6, BSWAP_EPI64);\n            tmp7 = _mm_add_epi32(ctr1, SIX);\n            tmp7 = _mm_shuffle_epi8(tmp7, BSWAP_EPI64);\n            tmp8 = _mm_add_epi32(ctr1, SEVEN);\n            tmp8 = _mm_shuffle_epi8(tmp8, BSWAP_EPI64);\n            ctr1 = _mm_add_epi32(ctr1, EIGHT);\n            tmp1 =_mm_xor_si128(tmp1, KEY[0]);\n            tmp2 =_mm_xor_si128(tmp2, KEY[0]);\n            tmp3 =_mm_xor_si128(tmp3, KEY[0]);\n            tmp4 =_mm_xor_si128(tmp4, KEY[0]);\n            tmp5 =_mm_xor_si128(tmp5, KEY[0]);\n            tmp6 =_mm_xor_si128(tmp6, KEY[0]);\n            tmp7 =_mm_xor_si128(tmp7, KEY[0]);\n            tmp8 =_mm_xor_si128(tmp8, KEY[0]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+0]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                XV = _mm_xor_si128(XV, X);\n                gfmul_only(XV, HT[7], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[1]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[1]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[1]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[1]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[1]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[1]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[1]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+1]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[6], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[2]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[2]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[2]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[2]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[2]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[2]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[2]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+2]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[5], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[3]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[3]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[3]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[3]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[3]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[3]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[3]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+3]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[4], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[4]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[4]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[4]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[4]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[4]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[4]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[4]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+4]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[3], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[5]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[5]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[5]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[5]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[5]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[5]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[5]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+5]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[2], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[6]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[6]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[6]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[6]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[6]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[6]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[6]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+6]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[1], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[7]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[7]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[7]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[7]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[7]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[7]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[7]);\n                /* 128 x 128 Carryless Multiply */\n                XV = _mm_loadu_si128(&((__m128i*)in)[i*8+7]);\n                XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n                gfmul_only(XV, HT[0], &r0, &r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[8]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[8]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[8]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[8]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[8]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[8]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[8]);\n                /* Reduction */\n                X = ghash_red(r0, r1);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);\n            tmp2 = _mm_aesenc_si128(tmp2, KEY[9]);\n            tmp3 = _mm_aesenc_si128(tmp3, KEY[9]);\n            tmp4 = _mm_aesenc_si128(tmp4, KEY[9]);\n            tmp5 = _mm_aesenc_si128(tmp5, KEY[9]);\n            tmp6 = _mm_aesenc_si128(tmp6, KEY[9]);\n            tmp7 = _mm_aesenc_si128(tmp7, KEY[9]);\n            tmp8 = _mm_aesenc_si128(tmp8, KEY[9]);\n            lastKey = KEY[10];\n            if (nr > 10) {\n                tmp1 = _mm_aesenc_si128(tmp1, KEY[10]);\n                tmp2 = _mm_aesenc_si128(tmp2, KEY[10]);\n                tmp3 = _mm_aesenc_si128(tmp3, KEY[10]);\n                tmp4 = _mm_aesenc_si128(tmp4, KEY[10]);\n                tmp5 = _mm_aesenc_si128(tmp5, KEY[10]);\n                tmp6 = _mm_aesenc_si128(tmp6, KEY[10]);\n                tmp7 = _mm_aesenc_si128(tmp7, KEY[10]);\n                tmp8 = _mm_aesenc_si128(tmp8, KEY[10]);\n                tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);\n                tmp2 = _mm_aesenc_si128(tmp2, KEY[11]);\n                tmp3 = _mm_aesenc_si128(tmp3, KEY[11]);\n                tmp4 = _mm_aesenc_si128(tmp4, KEY[11]);\n                tmp5 = _mm_aesenc_si128(tmp5, KEY[11]);\n                tmp6 = _mm_aesenc_si128(tmp6, KEY[11]);\n                tmp7 = _mm_aesenc_si128(tmp7, KEY[11]);\n                tmp8 = _mm_aesenc_si128(tmp8, KEY[11]);\n                lastKey = KEY[12];\n                if (nr > 12) {\n                    tmp1 = _mm_aesenc_si128(tmp1, KEY[12]);\n                    tmp2 = _mm_aesenc_si128(tmp2, KEY[12]);\n                    tmp3 = _mm_aesenc_si128(tmp3, KEY[12]);\n                    tmp4 = _mm_aesenc_si128(tmp4, KEY[12]);\n                    tmp5 = _mm_aesenc_si128(tmp5, KEY[12]);\n                    tmp6 = _mm_aesenc_si128(tmp6, KEY[12]);\n                    tmp7 = _mm_aesenc_si128(tmp7, KEY[12]);\n                    tmp8 = _mm_aesenc_si128(tmp8, KEY[12]);\n                    tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);\n                    tmp2 = _mm_aesenc_si128(tmp2, KEY[13]);\n                    tmp3 = _mm_aesenc_si128(tmp3, KEY[13]);\n                    tmp4 = _mm_aesenc_si128(tmp4, KEY[13]);\n                    tmp5 = _mm_aesenc_si128(tmp5, KEY[13]);\n                    tmp6 = _mm_aesenc_si128(tmp6, KEY[13]);\n                    tmp7 = _mm_aesenc_si128(tmp7, KEY[13]);\n                    tmp8 = _mm_aesenc_si128(tmp8, KEY[13]);\n                    lastKey = KEY[14];\n                }\n            }\n            AES_ENC_LAST_8();\n        }\n    }\n\n#endif /* AES_GCM_AESNI_NO_UNROLL */\n\n    for (k = i*8; k < nbytes/16; k++) {\n        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);\n        ctr1 = _mm_add_epi32(ctr1, ONE);\n        tmp1 = _mm_xor_si128(tmp1, KEY[0]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);\n        /* 128 x 128 Carryless Multiply */\n        XV = _mm_loadu_si128(&((__m128i*)in)[k]);\n        XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n        XV = _mm_xor_si128(XV, X);\n        X = gfmul_shifted(XV, H);\n        lastKey = KEY[10];\n        if (nr > 10) {\n            tmp1 = _mm_aesenc_si128(tmp1, lastKey);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);\n            lastKey = KEY[12];\n            if (nr > 12) {\n                tmp1 = _mm_aesenc_si128(tmp1, lastKey);\n                tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);\n                lastKey = KEY[14];\n            }\n        }\n        tmp1 = _mm_aesenclast_si128(tmp1, lastKey);\n        tmp2 = _mm_loadu_si128(&((__m128i*)in)[k]);\n        tmp1 = _mm_xor_si128(tmp1, tmp2);\n        _mm_storeu_si128(&((__m128i*)out)[k], tmp1);\n    }\n\n    /* If one partial block remains */\n    if (nbytes % 16) {\n        tmp1 = _mm_shuffle_epi8(ctr1, BSWAP_EPI64);\n        tmp1 = _mm_xor_si128(tmp1, KEY[0]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[1]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[2]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[3]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[4]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[5]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[6]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[7]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[8]);\n        tmp1 = _mm_aesenc_si128(tmp1, KEY[9]);\n        lastKey = KEY[10];\n        if (nr > 10) {\n            tmp1 = _mm_aesenc_si128(tmp1, lastKey);\n            tmp1 = _mm_aesenc_si128(tmp1, KEY[11]);\n            lastKey = KEY[12];\n            if (nr > 12) {\n                tmp1 = _mm_aesenc_si128(tmp1, lastKey);\n                tmp1 = _mm_aesenc_si128(tmp1, KEY[13]);\n                lastKey = KEY[14];\n            }\n        }\n        tmp1 = _mm_aesenclast_si128(tmp1, lastKey);\n        last_block = _mm_setzero_si128();\n        for (j=0; j < nbytes%16; j++)\n            ((unsigned char*)&last_block)[j] = in[k*16+j];\n        XV = last_block;\n        tmp1 = _mm_xor_si128(tmp1, last_block);\n        last_block = tmp1;\n        for (j=0; j < nbytes%16; j++)\n            out[k*16+j] = ((unsigned char*)&last_block)[j];\n        XV = _mm_shuffle_epi8(XV, BSWAP_MASK);\n        XV = _mm_xor_si128(XV, X);\n        X = gfmul_shifted(XV, H);\n    }\n\n    tmp1 = _mm_insert_epi64(tmp1, nbytes*8, 0);\n    tmp1 = _mm_insert_epi64(tmp1, abytes*8, 1);\n    /* 128 x 128 Carryless Multiply */\n    X = _mm_xor_si128(X, tmp1);\n    X = gfmul_shifted(X, H);\n    X = _mm_shuffle_epi8(X, BSWAP_MASK);\n    T = _mm_xor_si128(X, T);\n\n/*    if (0xffff !=\n           _mm_movemask_epi8(_mm_cmpeq_epi8(T, _mm_loadu_si128((__m128i*)tag)))) */\n    if (XMEMCMP(tag, &T, tbytes) != 0)\n        *res = 0; /* in case the authentication failed */\n    else\n        *res = 1; /* when successful returns 1 */\n}\n\n#endif /* HAVE_AES_DECRYPT */\n#endif /* _MSC_VER */\n#endif /* WOLFSSL_AESNI */\n\n\n#if defined(GCM_SMALL)\nstatic void GMULT(byte* X, byte* Y)\n{\n    byte Z[AES_BLOCK_SIZE];\n    byte V[AES_BLOCK_SIZE];\n    int i, j;\n\n    XMEMSET(Z, 0, AES_BLOCK_SIZE);\n    XMEMCPY(V, X, AES_BLOCK_SIZE);\n    for (i = 0; i < AES_BLOCK_SIZE; i++)\n    {\n        byte y = Y[i];\n        for (j = 0; j < 8; j++)\n        {\n            if (y & 0x80) {\n                xorbuf(Z, V, AES_BLOCK_SIZE);\n            }\n\n            RIGHTSHIFTX(V);\n            y = y << 1;\n        }\n    }\n    XMEMCPY(X, Z, AES_BLOCK_SIZE);\n}\n\n\nvoid GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,\n    word32 cSz, byte* s, word32 sSz)\n{\n    byte x[AES_BLOCK_SIZE];\n    byte scratch[AES_BLOCK_SIZE];\n    word32 blocks, partial;\n    byte* h = aes->H;\n\n    XMEMSET(x, 0, AES_BLOCK_SIZE);\n\n    /* Hash in A, the Additional Authentication Data */\n    if (aSz != 0 && a != NULL) {\n        blocks = aSz / AES_BLOCK_SIZE;\n        partial = aSz % AES_BLOCK_SIZE;\n        while (blocks--) {\n            xorbuf(x, a, AES_BLOCK_SIZE);\n            GMULT(x, h);\n            a += AES_BLOCK_SIZE;\n        }\n        if (partial != 0) {\n            XMEMSET(scratch, 0, AES_BLOCK_SIZE);\n            XMEMCPY(scratch, a, partial);\n            xorbuf(x, scratch, AES_BLOCK_SIZE);\n            GMULT(x, h);\n        }\n    }\n\n    /* Hash in C, the Ciphertext */\n    if (cSz != 0 && c != NULL) {\n        blocks = cSz / AES_BLOCK_SIZE;\n        partial = cSz % AES_BLOCK_SIZE;\n        while (blocks--) {\n            xorbuf(x, c, AES_BLOCK_SIZE);\n            GMULT(x, h);\n            c += AES_BLOCK_SIZE;\n        }\n        if (partial != 0) {\n            XMEMSET(scratch, 0, AES_BLOCK_SIZE);\n            XMEMCPY(scratch, c, partial);\n            xorbuf(x, scratch, AES_BLOCK_SIZE);\n            GMULT(x, h);\n        }\n    }\n\n    /* Hash in the lengths of A and C in bits */\n    FlattenSzInBits(&scratch[0], aSz);\n    FlattenSzInBits(&scratch[8], cSz);\n    xorbuf(x, scratch, AES_BLOCK_SIZE);\n    GMULT(x, h);\n\n    /* Copy the result into s. */\n    XMEMCPY(s, x, sSz);\n}\n\n/* end GCM_SMALL */\n#elif defined(GCM_TABLE)\n\nstatic const byte R[256][2] = {\n    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},\n    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},\n    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},\n    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},\n    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},\n    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},\n    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},\n    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},\n    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},\n    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},\n    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},\n    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},\n    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},\n    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},\n    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},\n    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},\n    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},\n    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},\n    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},\n    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},\n    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},\n    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},\n    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},\n    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},\n    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},\n    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},\n    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},\n    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},\n    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},\n    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},\n    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},\n    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},\n    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},\n    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},\n    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},\n    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},\n    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},\n    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},\n    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},\n    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},\n    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},\n    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},\n    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},\n    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},\n    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},\n    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},\n    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},\n    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},\n    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},\n    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},\n    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},\n    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},\n    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},\n    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},\n    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},\n    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},\n    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},\n    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},\n    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},\n    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},\n    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},\n    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},\n    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},\n    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };\n\n\nstatic void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE])\n{\n    int i, j;\n    byte Z[AES_BLOCK_SIZE];\n    byte a;\n\n    XMEMSET(Z, 0, sizeof(Z));\n\n    for (i = 15; i > 0; i--) {\n        xorbuf(Z, m[x[i]], AES_BLOCK_SIZE);\n        a = Z[15];\n\n        for (j = 15; j > 0; j--) {\n            Z[j] = Z[j-1];\n        }\n\n        Z[0] = R[a][0];\n        Z[1] ^= R[a][1];\n    }\n    xorbuf(Z, m[x[0]], AES_BLOCK_SIZE);\n\n    XMEMCPY(x, Z, AES_BLOCK_SIZE);\n}\n\n\nvoid GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,\n    word32 cSz, byte* s, word32 sSz)\n{\n    byte x[AES_BLOCK_SIZE];\n    byte scratch[AES_BLOCK_SIZE];\n    word32 blocks, partial;\n\n    XMEMSET(x, 0, AES_BLOCK_SIZE);\n\n    /* Hash in A, the Additional Authentication Data */\n    if (aSz != 0 && a != NULL) {\n        blocks = aSz / AES_BLOCK_SIZE;\n        partial = aSz % AES_BLOCK_SIZE;\n        while (blocks--) {\n            xorbuf(x, a, AES_BLOCK_SIZE);\n            GMULT(x, aes->M0);\n            a += AES_BLOCK_SIZE;\n        }\n        if (partial != 0) {\n            XMEMSET(scratch, 0, AES_BLOCK_SIZE);\n            XMEMCPY(scratch, a, partial);\n            xorbuf(x, scratch, AES_BLOCK_SIZE);\n            GMULT(x, aes->M0);\n        }\n    }\n\n    /* Hash in C, the Ciphertext */\n    if (cSz != 0 && c != NULL) {\n        blocks = cSz / AES_BLOCK_SIZE;\n        partial = cSz % AES_BLOCK_SIZE;\n        while (blocks--) {\n            xorbuf(x, c, AES_BLOCK_SIZE);\n            GMULT(x, aes->M0);\n            c += AES_BLOCK_SIZE;\n        }\n        if (partial != 0) {\n            XMEMSET(scratch, 0, AES_BLOCK_SIZE);\n            XMEMCPY(scratch, c, partial);\n            xorbuf(x, scratch, AES_BLOCK_SIZE);\n            GMULT(x, aes->M0);\n        }\n    }\n\n    /* Hash in the lengths of A and C in bits */\n    FlattenSzInBits(&scratch[0], aSz);\n    FlattenSzInBits(&scratch[8], cSz);\n    xorbuf(x, scratch, AES_BLOCK_SIZE);\n    GMULT(x, aes->M0);\n\n    /* Copy the result into s. */\n    XMEMCPY(s, x, sSz);\n}\n\n/* end GCM_TABLE */\n#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)\n\n#if !defined(FREESCALE_LTC_AES_GCM)\nstatic void GMULT(word64* X, word64* Y)\n{\n    word64 Z[2] = {0,0};\n    word64 V[2];\n    int i, j;\n    V[0] = X[0];  V[1] = X[1];\n\n    for (i = 0; i < 2; i++)\n    {\n        word64 y = Y[i];\n        for (j = 0; j < 64; j++)\n        {\n            if (y & 0x8000000000000000ULL) {\n                Z[0] ^= V[0];\n                Z[1] ^= V[1];\n            }\n\n            if (V[1] & 0x0000000000000001) {\n                V[1] >>= 1;\n                V[1] |= ((V[0] & 0x0000000000000001) ?\n                    0x8000000000000000ULL : 0);\n                V[0] >>= 1;\n                V[0] ^= 0xE100000000000000ULL;\n            }\n            else {\n                V[1] >>= 1;\n                V[1] |= ((V[0] & 0x0000000000000001) ?\n                    0x8000000000000000ULL : 0);\n                V[0] >>= 1;\n            }\n            y <<= 1;\n        }\n    }\n    X[0] = Z[0];\n    X[1] = Z[1];\n}\n\n\nvoid GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,\n    word32 cSz, byte* s, word32 sSz)\n{\n    word64 x[2] = {0,0};\n    word32 blocks, partial;\n    word64 bigH[2];\n\n    XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);\n    #ifdef LITTLE_ENDIAN_ORDER\n        ByteReverseWords64(bigH, bigH, AES_BLOCK_SIZE);\n    #endif\n\n    /* Hash in A, the Additional Authentication Data */\n    if (aSz != 0 && a != NULL) {\n        word64 bigA[2];\n        blocks = aSz / AES_BLOCK_SIZE;\n        partial = aSz % AES_BLOCK_SIZE;\n        while (blocks--) {\n            XMEMCPY(bigA, a, AES_BLOCK_SIZE);\n            #ifdef LITTLE_ENDIAN_ORDER\n                ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);\n            #endif\n            x[0] ^= bigA[0];\n            x[1] ^= bigA[1];\n            GMULT(x, bigH);\n            a += AES_BLOCK_SIZE;\n        }\n        if (partial != 0) {\n            XMEMSET(bigA, 0, AES_BLOCK_SIZE);\n            XMEMCPY(bigA, a, partial);\n            #ifdef LITTLE_ENDIAN_ORDER\n                ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);\n            #endif\n            x[0] ^= bigA[0];\n            x[1] ^= bigA[1];\n            GMULT(x, bigH);\n        }\n#ifdef OPENSSL_EXTRA\n        /* store AAD partial tag for next call */\n        aes->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000) >> 32);\n        aes->aadH[1] = (word32)(x[0] & 0xFFFFFFFF);\n        aes->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000) >> 32);\n        aes->aadH[3] = (word32)(x[1] & 0xFFFFFFFF);\n#endif\n    }\n\n    /* Hash in C, the Ciphertext */\n    if (cSz != 0 && c != NULL) {\n        word64 bigC[2];\n        blocks = cSz / AES_BLOCK_SIZE;\n        partial = cSz % AES_BLOCK_SIZE;\n#ifdef OPENSSL_EXTRA\n        /* Start from last AAD partial tag */\n        if(aes->aadLen) {\n            x[0] = ((word64)aes->aadH[0]) << 32 | aes->aadH[1];\n            x[1] = ((word64)aes->aadH[2]) << 32 | aes->aadH[3];\n         }\n#endif\n        while (blocks--) {\n            XMEMCPY(bigC, c, AES_BLOCK_SIZE);\n            #ifdef LITTLE_ENDIAN_ORDER\n                ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);\n            #endif\n            x[0] ^= bigC[0];\n            x[1] ^= bigC[1];\n            GMULT(x, bigH);\n            c += AES_BLOCK_SIZE;\n        }\n        if (partial != 0) {\n            XMEMSET(bigC, 0, AES_BLOCK_SIZE);\n            XMEMCPY(bigC, c, partial);\n            #ifdef LITTLE_ENDIAN_ORDER\n                ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);\n            #endif\n            x[0] ^= bigC[0];\n            x[1] ^= bigC[1];\n            GMULT(x, bigH);\n        }\n    }\n\n    /* Hash in the lengths in bits of A and C */\n    {\n        word64 len[2];\n        len[0] = aSz; len[1] = cSz;\n#ifdef OPENSSL_EXTRA\n        if (aes->aadLen)\n            len[0] = (word64)aes->aadLen;\n#endif\n        /* Lengths are in bytes. Convert to bits. */\n        len[0] *= 8;\n        len[1] *= 8;\n\n        x[0] ^= len[0];\n        x[1] ^= len[1];\n        GMULT(x, bigH);\n    }\n    #ifdef LITTLE_ENDIAN_ORDER\n        ByteReverseWords64(x, x, AES_BLOCK_SIZE);\n    #endif\n    XMEMCPY(s, x, sSz);\n}\n#endif /* !FREESCALE_LTC_AES_GCM */\n\n/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */\n#else /* GCM_WORD32 */\n\nstatic void GMULT(word32* X, word32* Y)\n{\n    word32 Z[4] = {0,0,0,0};\n    word32 V[4];\n    int i, j;\n\n    V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];\n\n    for (i = 0; i < 4; i++)\n    {\n        word32 y = Y[i];\n        for (j = 0; j < 32; j++)\n        {\n            if (y & 0x80000000) {\n                Z[0] ^= V[0];\n                Z[1] ^= V[1];\n                Z[2] ^= V[2];\n                Z[3] ^= V[3];\n            }\n\n            if (V[3] & 0x00000001) {\n                V[3] >>= 1;\n                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);\n                V[2] >>= 1;\n                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);\n                V[1] >>= 1;\n                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);\n                V[0] >>= 1;\n                V[0] ^= 0xE1000000;\n            } else {\n                V[3] >>= 1;\n                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);\n                V[2] >>= 1;\n                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);\n                V[1] >>= 1;\n                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);\n                V[0] >>= 1;\n            }\n            y <<= 1;\n        }\n    }\n    X[0] = Z[0];\n    X[1] = Z[1];\n    X[2] = Z[2];\n    X[3] = Z[3];\n}\n\n\nvoid GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,\n    word32 cSz, byte* s, word32 sSz)\n{\n    word32 x[4] = {0,0,0,0};\n    word32 blocks, partial;\n    word32 bigH[4];\n\n    XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);\n    #ifdef LITTLE_ENDIAN_ORDER\n        ByteReverseWords(bigH, bigH, AES_BLOCK_SIZE);\n    #endif\n\n    /* Hash in A, the Additional Authentication Data */\n    if (aSz != 0 && a != NULL) {\n        word32 bigA[4];\n        blocks = aSz / AES_BLOCK_SIZE;\n        partial = aSz % AES_BLOCK_SIZE;\n        while (blocks--) {\n            XMEMCPY(bigA, a, AES_BLOCK_SIZE);\n            #ifdef LITTLE_ENDIAN_ORDER\n                ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);\n            #endif\n            x[0] ^= bigA[0];\n            x[1] ^= bigA[1];\n            x[2] ^= bigA[2];\n            x[3] ^= bigA[3];\n            GMULT(x, bigH);\n            a += AES_BLOCK_SIZE;\n        }\n        if (partial != 0) {\n            XMEMSET(bigA, 0, AES_BLOCK_SIZE);\n            XMEMCPY(bigA, a, partial);\n            #ifdef LITTLE_ENDIAN_ORDER\n                ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);\n            #endif\n            x[0] ^= bigA[0];\n            x[1] ^= bigA[1];\n            x[2] ^= bigA[2];\n            x[3] ^= bigA[3];\n            GMULT(x, bigH);\n        }\n    }\n\n    /* Hash in C, the Ciphertext */\n    if (cSz != 0 && c != NULL) {\n        word32 bigC[4];\n        blocks = cSz / AES_BLOCK_SIZE;\n        partial = cSz % AES_BLOCK_SIZE;\n        while (blocks--) {\n            XMEMCPY(bigC, c, AES_BLOCK_SIZE);\n            #ifdef LITTLE_ENDIAN_ORDER\n                ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);\n            #endif\n            x[0] ^= bigC[0];\n            x[1] ^= bigC[1];\n            x[2] ^= bigC[2];\n            x[3] ^= bigC[3];\n            GMULT(x, bigH);\n            c += AES_BLOCK_SIZE;\n        }\n        if (partial != 0) {\n            XMEMSET(bigC, 0, AES_BLOCK_SIZE);\n            XMEMCPY(bigC, c, partial);\n            #ifdef LITTLE_ENDIAN_ORDER\n                ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);\n            #endif\n            x[0] ^= bigC[0];\n            x[1] ^= bigC[1];\n            x[2] ^= bigC[2];\n            x[3] ^= bigC[3];\n            GMULT(x, bigH);\n        }\n    }\n\n    /* Hash in the lengths in bits of A and C */\n    {\n        word32 len[4];\n\n        /* Lengths are in bytes. Convert to bits. */\n        len[0] = (aSz >> (8*sizeof(aSz) - 3));\n        len[1] = aSz << 3;\n        len[2] = (cSz >> (8*sizeof(cSz) - 3));\n        len[3] = cSz << 3;\n\n        x[0] ^= len[0];\n        x[1] ^= len[1];\n        x[2] ^= len[2];\n        x[3] ^= len[3];\n        GMULT(x, bigH);\n    }\n    #ifdef LITTLE_ENDIAN_ORDER\n        ByteReverseWords(x, x, AES_BLOCK_SIZE);\n    #endif\n    XMEMCPY(s, x, sSz);\n}\n\n#endif /* end GCM_WORD32 */\n\n\n#if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)\n#ifdef FREESCALE_LTC_AES_GCM\nint wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,\n                   const byte* iv, word32 ivSz,\n                   byte* authTag, word32 authTagSz,\n                   const byte* authIn, word32 authInSz)\n{\n    status_t status;\n    word32 keySize;\n\n    /* argument checks */\n    if (aes == NULL || authTagSz > AES_BLOCK_SIZE) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {\n        WOLFSSL_MSG(\"GcmEncrypt authTagSz too small error\");\n        return BAD_FUNC_ARG;\n    }\n\n    status = wc_AesGetKeySize(aes, &keySize);\n    if (status)\n        return status;\n\n    status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,\n        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);\n\n    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;\n}\n\n#else\n\n#ifdef STM32_CRYPTO_AES_GCM\n\n/* this function supports inline encrypt */\nstatic int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz,\n                                  const byte* iv, word32 ivSz,\n                                  byte* authTag, word32 authTagSz,\n                                  const byte* authIn, word32 authInSz)\n{\n    int ret;\n#ifdef WOLFSSL_STM32_CUBEMX\n    CRYP_HandleTypeDef hcryp;\n#else\n    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];\n#endif\n    word32 keySize;\n    int status = HAL_OK;\n    word32 blocks = sz / AES_BLOCK_SIZE;\n    word32 partial = sz % AES_BLOCK_SIZE;\n    byte tag[AES_BLOCK_SIZE];\n    byte partialBlock[AES_BLOCK_SIZE];\n    byte ctr[AES_BLOCK_SIZE];\n    byte* authInPadded = NULL;\n    int authPadSz;\n\n    ret = wc_AesGetKeySize(aes, &keySize);\n    if (ret != 0)\n        return ret;\n\n#ifdef WOLFSSL_STM32_CUBEMX\n    ret = wc_Stm32_Aes_Init(aes, &hcryp);\n    if (ret != 0)\n        return ret;\n#endif\n\n    ret = wolfSSL_CryptHwMutexLock();\n    if (ret != 0) {\n        return ret;\n    }\n\n    XMEMSET(ctr, 0, AES_BLOCK_SIZE);\n    if (ivSz == GCM_NONCE_MID_SZ) {\n        XMEMCPY(ctr, iv, ivSz);\n        ctr[AES_BLOCK_SIZE - 1] = 1;\n    }\n    else {\n        GHASH(aes, NULL, 0, iv, ivSz, ctr, AES_BLOCK_SIZE);\n    }\n    /* Hardware requires counter + 1 */\n    IncrementGcmCounter(ctr);\n\n    if (authInSz == 0 || (authInSz % AES_BLOCK_SIZE) != 0) {\n        /* Need to pad the AAD to a full block with zeros. */\n        authPadSz = ((authInSz / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;\n        authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,\n            DYNAMIC_TYPE_TMP_BUFFER);\n        if (authInPadded == NULL) {\n            wolfSSL_CryptHwMutexUnLock();\n            return MEMORY_E;\n        }\n        XMEMSET(authInPadded, 0, authPadSz);\n        XMEMCPY(authInPadded, authIn, authInSz);\n    } else {\n        authPadSz = authInSz;\n        authInPadded = (byte*)authIn;\n    }\n\n#ifdef WOLFSSL_STM32_CUBEMX\n    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;\n    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;\n    hcryp.Init.HeaderSize = authInSz;\n\n#ifdef STM32_CRYPTO_AES_ONLY\n    /* Set the CRYP parameters */\n    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;\n    hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;\n    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;\n    HAL_CRYP_Init(&hcryp);\n\n    /* GCM init phase */\n    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);\n    if (status == HAL_OK) {\n        /* GCM header phase */\n        hcryp.Init.GCMCMACPhase  = CRYP_HEADER_PHASE;\n        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);\n    }\n    if (status == HAL_OK) {\n        /* GCM payload phase - blocks */\n        hcryp.Init.GCMCMACPhase  = CRYP_PAYLOAD_PHASE;\n        if (blocks) {\n            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,\n                (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);\n        }\n    }\n    if (status == HAL_OK && (partial != 0 || blocks == 0)) {\n        /* GCM payload phase - partial remainder */\n        XMEMSET(partialBlock, 0, sizeof(partialBlock));\n        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);\n        status = HAL_CRYPEx_AES_Auth(&hcryp, partialBlock, partial,\n            partialBlock, STM32_HAL_TIMEOUT);\n        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);\n    }\n    if (status == HAL_OK) {\n        /* GCM final phase */\n        hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;\n        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, tag, STM32_HAL_TIMEOUT);\n    }\n#elif defined(STM32_HAL_V2)\n    hcryp.Init.Algorithm  = CRYP_AES_GCM;\n    ByteReverseWords((word32*)partialBlock, (word32*)ctr, AES_BLOCK_SIZE);\n    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)partialBlock;\n    HAL_CRYP_Init(&hcryp);\n\n    /* GCM payload phase - can handle partial blocks */\n    status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,\n        (blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);\n    if (status == HAL_OK) {\n        /* Compute the authTag */\n        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,\n            STM32_HAL_TIMEOUT);\n    }\n#else\n    HAL_CRYP_Init(&hcryp);\n    if (blocks) {\n        /* GCM payload phase - blocks */\n        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in,\n            (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);\n    }\n    if (status == HAL_OK && (partial != 0 || blocks == 0)) {\n        /* GCM payload phase - partial remainder */\n        XMEMSET(partialBlock, 0, sizeof(partialBlock));\n        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);\n        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, partialBlock, partial,\n            partialBlock, STM32_HAL_TIMEOUT);\n        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);\n    }\n    if (status == HAL_OK) {\n        /* Compute the authTag */\n        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, tag, STM32_HAL_TIMEOUT);\n    }\n#endif\n\n    if (status != HAL_OK)\n        ret = AES_GCM_AUTH_E;\n    HAL_CRYP_DeInit(&hcryp);\n\n#else /* STD_PERI_LIB */\n    ByteReverseWords(keyCopy, (word32*)aes->key, keySize);\n    status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr,\n                         (uint8_t*)keyCopy,      keySize * 8,\n                         (uint8_t*)in,           sz,\n                         (uint8_t*)authInPadded, authInSz,\n                         (uint8_t*)out,          tag);\n    if (status != SUCCESS)\n        ret = AES_GCM_AUTH_E;\n#endif /* WOLFSSL_STM32_CUBEMX */\n\n    if (ret == 0) {\n        /* return authTag */\n        if (authTag) {\n            /* STM32 GCM won't compute Auth correctly for partial or\n                when IV != 12, so use software here */\n            if (sz == 0 || partial != 0 || ivSz != GCM_NONCE_MID_SZ) {\n                DecrementGcmCounter(ctr); /* hardware requires +1, so subtract it */\n                GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);\n                wc_AesEncrypt(aes, ctr, tag);\n                xorbuf(authTag, tag, authTagSz);\n            }\n            else {\n                XMEMCPY(authTag, tag, authTagSz);\n            }\n        }\n    }\n\n    /* Free memory if not a multiple of AES_BLOCK_SZ */\n    if (authInPadded != authIn) {\n        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    wolfSSL_CryptHwMutexUnLock();\n\n    return ret;\n}\n\n#endif /* STM32_CRYPTO_AES_GCM */\n\n#ifdef WOLFSSL_AESNI\nint AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,\n                      const byte* iv, word32 ivSz,\n                      byte* authTag, word32 authTagSz,\n                      const byte* authIn, word32 authInSz);\n#else\nstatic\n#endif\nint AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,\n                      const byte* iv, word32 ivSz,\n                      byte* authTag, word32 authTagSz,\n                      const byte* authIn, word32 authInSz)\n{\n    int ret = 0;\n    word32 blocks = sz / AES_BLOCK_SIZE;\n    word32 partial = sz % AES_BLOCK_SIZE;\n    const byte* p = in;\n    byte* c = out;\n    byte counter[AES_BLOCK_SIZE];\n    byte initialCounter[AES_BLOCK_SIZE];\n    byte *ctr;\n    byte scratch[AES_BLOCK_SIZE];\n#ifdef OPENSSL_EXTRA\n    word32 aadTemp;\n#endif\n    ctr = counter;\n    XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);\n    XMEMSET(scratch, 0, AES_BLOCK_SIZE);\n    if (ivSz == GCM_NONCE_MID_SZ) {\n        XMEMCPY(initialCounter, iv, ivSz);\n        initialCounter[AES_BLOCK_SIZE - 1] = 1;\n    }\n    else {\n#ifdef OPENSSL_EXTRA\n        aadTemp = aes->aadLen;\n        aes->aadLen = 0;\n#endif\n        GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);\n#ifdef OPENSSL_EXTRA\n        aes->aadLen = aadTemp;\n#endif\n    }\n    XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);\n\n#ifdef WOLFSSL_PIC32MZ_CRYPT\n    if (blocks) {\n        /* use initial IV for HW, but don't use it below */\n        XMEMCPY(aes->reg, ctr, AES_BLOCK_SIZE);\n\n        ret = wc_Pic32AesCrypt(\n            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,\n            out, in, (blocks * AES_BLOCK_SIZE),\n            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);\n        if (ret != 0)\n            return ret;\n    }\n    /* process remainder using partial handling */\n#endif\n\n#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)\n    /* some hardware acceleration can gain performance from doing AES encryption\n     * of the whole buffer at once */\n    if (c != p) { /* can not handle inline encryption */\n        while (blocks--) {\n            IncrementGcmCounter(ctr);\n            XMEMCPY(c, ctr, AES_BLOCK_SIZE);\n            c += AES_BLOCK_SIZE;\n        }\n\n        /* reset number of blocks and then do encryption */\n        blocks = sz / AES_BLOCK_SIZE;\n        wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);\n        xorbuf(out, p, AES_BLOCK_SIZE * blocks);\n        p += AES_BLOCK_SIZE * blocks;\n    }\n    else\n#endif /* HAVE_AES_ECB && !WOLFSSL_PIC32MZ_CRYPT */\n\n    while (blocks--) {\n        IncrementGcmCounter(ctr);\n    #if !defined(WOLFSSL_PIC32MZ_CRYPT)\n        wc_AesEncrypt(aes, ctr, scratch);\n        xorbuf(scratch, p, AES_BLOCK_SIZE);\n        XMEMCPY(c, scratch, AES_BLOCK_SIZE);\n    #endif\n        p += AES_BLOCK_SIZE;\n        c += AES_BLOCK_SIZE;\n    }\n\n    if (partial != 0) {\n        IncrementGcmCounter(ctr);\n        wc_AesEncrypt(aes, ctr, scratch);\n        xorbuf(scratch, p, partial);\n        XMEMCPY(c, scratch, partial);\n    }\n    if (authTag) {\n        GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);\n        wc_AesEncrypt(aes, initialCounter, scratch);\n        xorbuf(authTag, scratch, authTagSz);\n#ifdef OPENSSL_EXTRA\n        if (!in && !sz)\n            /* store AAD size for next call */\n            aes->aadLen = authInSz;\n#endif\n    }\n\n    return ret;\n}\n\n/* Software AES - GCM Encrypt */\nint wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,\n                   const byte* iv, word32 ivSz,\n                   byte* authTag, word32 authTagSz,\n                   const byte* authIn, word32 authInSz)\n{\n    /* argument checks */\n    if (aes == NULL || authTagSz > AES_BLOCK_SIZE) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {\n        WOLFSSL_MSG(\"GcmEncrypt authTagSz too small error\");\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLF_CRYPTO_CB\n    if (aes->devId != INVALID_DEVID) {\n        int ret = wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz,\n            authTag, authTagSz, authIn, authInSz);\n        if (ret != CRYPTOCB_UNAVAILABLE)\n            return ret;\n        /* fall-through when unavailable */\n    }\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)\n    /* if async and byte count above threshold */\n    /* only 12-byte IV is supported in HW */\n    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&\n                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {\n    #if defined(HAVE_CAVIUM)\n        #ifdef HAVE_CAVIUM_V\n        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */\n            return NitroxAesGcmEncrypt(aes, out, in, sz,\n                (const byte*)aes->devKey, aes->keylen, iv, ivSz,\n                authTag, authTagSz, authIn, authInSz);\n        }\n        #endif\n    #elif defined(HAVE_INTEL_QA)\n        return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,\n            (const byte*)aes->devKey, aes->keylen, iv, ivSz,\n            authTag, authTagSz, authIn, authInSz);\n    #else /* WOLFSSL_ASYNC_CRYPT_TEST */\n        if (wc_AsyncTestInit(&aes->asyncDev, ASYNC_TEST_AES_GCM_ENCRYPT)) {\n            WC_ASYNC_TEST* testDev = &aes->asyncDev.test;\n            testDev->aes.aes = aes;\n            testDev->aes.out = out;\n            testDev->aes.in = in;\n            testDev->aes.sz = sz;\n            testDev->aes.iv = iv;\n            testDev->aes.ivSz = ivSz;\n            testDev->aes.authTag = authTag;\n            testDev->aes.authTagSz = authTagSz;\n            testDev->aes.authIn = authIn;\n            testDev->aes.authInSz = authInSz;\n            return WC_PENDING_E;\n        }\n    #endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n#ifdef STM32_CRYPTO_AES_GCM\n    /* The STM standard peripheral library API's doesn't support partial blocks */\n    #ifdef STD_PERI_LIB\n    if (partial == 0)\n    #endif\n    {\n        return wc_AesGcmEncrypt_STM32(\n            aes, out, in, sz, iv, ivSz,\n            authTag, authTagSz, authIn, authInSz);\n    }\n#endif /* STM32_CRYPTO_AES_GCM */\n\n#ifdef WOLFSSL_AESNI\n    #ifdef HAVE_INTEL_AVX2\n    if (IS_INTEL_AVX2(intel_flags)) {\n        AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,\n                                 authTagSz, (const byte*)aes->key, aes->rounds);\n        return 0;\n    }\n    else\n    #endif\n    #ifdef HAVE_INTEL_AVX1\n    if (IS_INTEL_AVX1(intel_flags)) {\n        AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,\n                                 authTagSz, (const byte*)aes->key, aes->rounds);\n        return 0;\n    }\n    else\n    #endif\n    if (haveAESNI) {\n        AES_GCM_encrypt(in, out, authIn, iv, authTag, sz, authInSz, ivSz,\n                                 authTagSz, (const byte*)aes->key, aes->rounds);\n        return 0;\n    }\n    else\n#endif\n    {\n        return AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,\n                                                              authIn, authInSz);\n    }\n}\n#endif\n\n\n\n/* AES GCM Decrypt */\n#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)\n#ifdef FREESCALE_LTC_AES_GCM\nint  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,\n                   const byte* iv, word32 ivSz,\n                   const byte* authTag, word32 authTagSz,\n                   const byte* authIn, word32 authInSz)\n{\n    int ret;\n    word32 keySize;\n    status_t status;\n\n    /* argument checks */\n    /* If the sz is non-zero, both in and out must be set. If sz is 0,\n     * in and out are don't cares, as this is is the GMAC case. */\n    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||\n        authTag == NULL || authTagSz > AES_BLOCK_SIZE || authTagSz == 0) {\n\n        return BAD_FUNC_ARG;\n    }\n\n    ret = wc_AesGetKeySize(aes, &keySize);\n    if (ret != 0) {\n        return ret;\n    }\n\n    status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,\n        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);\n\n    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;\n}\n\n#else\n\n#ifdef STM32_CRYPTO_AES_GCM\n/* this function supports inline decrypt */\nstatic int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,\n                                  const byte* in, word32 sz,\n                                  const byte* iv, word32 ivSz,\n                                  const byte* authTag, word32 authTagSz,\n                                  const byte* authIn, word32 authInSz)\n{\n    int ret;\n#ifdef WOLFSSL_STM32_CUBEMX\n    CRYP_HandleTypeDef hcryp;\n#else\n    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];\n#endif\n    word32 keySize;\n    int status = HAL_OK;\n    word32 blocks = sz / AES_BLOCK_SIZE;\n    word32 partial = sz % AES_BLOCK_SIZE;\n    byte tag[AES_BLOCK_SIZE];\n    byte partialBlock[AES_BLOCK_SIZE];\n    byte ctr[AES_BLOCK_SIZE];\n    byte* authInPadded = NULL;\n    int authPadSz;\n\n    ret = wc_AesGetKeySize(aes, &keySize);\n    if (ret != 0)\n        return ret;\n\n#ifdef WOLFSSL_STM32_CUBEMX\n    ret = wc_Stm32_Aes_Init(aes, &hcryp);\n    if (ret != 0)\n        return ret;\n#endif\n\n    ret = wolfSSL_CryptHwMutexLock();\n    if (ret != 0) {\n        return ret;\n    }\n\n    XMEMSET(ctr, 0, AES_BLOCK_SIZE);\n    if (ivSz == GCM_NONCE_MID_SZ) {\n        XMEMCPY(ctr, iv, ivSz);\n        ctr[AES_BLOCK_SIZE - 1] = 1;\n    }\n    else {\n        GHASH(aes, NULL, 0, iv, ivSz, ctr, AES_BLOCK_SIZE);\n    }\n    /* Hardware requires counter + 1 */\n    IncrementGcmCounter(ctr);\n\n    if (authInSz == 0 || (authInSz % AES_BLOCK_SIZE) != 0) {\n        /* Need to pad the AAD to a full block with zeros. */\n        authPadSz = ((authInSz / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;\n        authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,\n            DYNAMIC_TYPE_TMP_BUFFER);\n        if (authInPadded == NULL) {\n            wolfSSL_CryptHwMutexUnLock();\n            return MEMORY_E;\n        }\n        XMEMSET(authInPadded, 0, authPadSz);\n        XMEMCPY(authInPadded, authIn, authInSz);\n    } else {\n        authPadSz = authInSz;\n        authInPadded = (byte*)authIn;\n    }\n\n#ifdef WOLFSSL_STM32_CUBEMX\n    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;\n    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;\n    hcryp.Init.HeaderSize = authInSz;\n\n#ifdef STM32_CRYPTO_AES_ONLY\n    /* Set the CRYP parameters */\n    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;\n    hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;\n    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;\n    HAL_CRYP_Init(&hcryp);\n\n    /* GCM init phase */\n    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);\n    if (status == HAL_OK) {\n        /* GCM header phase */\n        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;\n        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);\n    }\n    if (status == HAL_OK) {\n        /* GCM payload phase - blocks */\n        hcryp.Init.GCMCMACPhase  = CRYP_PAYLOAD_PHASE;\n        if (blocks) {\n            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,\n                (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);\n        }\n    }\n    if (status == HAL_OK && (partial != 0 || blocks == 0)) {\n        /* GCM payload phase - partial remainder */\n        XMEMSET(partialBlock, 0, sizeof(partialBlock));\n        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);\n        status = HAL_CRYPEx_AES_Auth(&hcryp, partialBlock, partial,\n            partialBlock, STM32_HAL_TIMEOUT);\n        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);\n    }\n    if (status == HAL_OK) {\n        /* GCM final phase */\n        hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;\n        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, tag, STM32_HAL_TIMEOUT);\n    }\n#elif defined(STM32_HAL_V2)\n    hcryp.Init.Algorithm = CRYP_AES_GCM;\n    ByteReverseWords((word32*)partialBlock, (word32*)ctr, AES_BLOCK_SIZE);\n    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)partialBlock;\n    HAL_CRYP_Init(&hcryp);\n\n    /* GCM payload phase - can handle partial blocks */\n    status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,\n        (blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);\n    if (status == HAL_OK) {\n        /* Compute the authTag */\n        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,\n            STM32_HAL_TIMEOUT);\n    }\n#else\n    HAL_CRYP_Init(&hcryp);\n    if (blocks) {\n        /* GCM payload phase - blocks */\n        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)in,\n            (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);\n    }\n    if (status == HAL_OK && (partial != 0 || blocks == 0)) {\n        /* GCM payload phase - partial remainder */\n        XMEMSET(partialBlock, 0, sizeof(partialBlock));\n        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);\n        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, partialBlock, partial,\n            partialBlock, STM32_HAL_TIMEOUT);\n        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);\n    }\n    if (status == HAL_OK) {\n        /* Compute the authTag */\n        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, tag, STM32_HAL_TIMEOUT);\n    }\n#endif\n\n    if (status != HAL_OK)\n        ret = AES_GCM_AUTH_E;\n\n    HAL_CRYP_DeInit(&hcryp);\n\n#else /* STD_PERI_LIB */\n    ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);\n\n    /* Input size and auth size need to be the actual sizes, even though\n     * they are not block aligned, because this length (in bits) is used\n     * in the final GHASH. */\n    status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,\n                         (uint8_t*)keyCopy,      keySize * 8,\n                         (uint8_t*)in,           sz,\n                         (uint8_t*)authInPadded, authInSz,\n                         (uint8_t*)out,          tag);\n    if (status != SUCCESS)\n        ret = AES_GCM_AUTH_E;\n#endif /* WOLFSSL_STM32_CUBEMX */\n\n    /* STM32 GCM hardware only supports IV of 12 bytes, so use software for auth */\n    if (sz == 0 || ivSz != GCM_NONCE_MID_SZ) {\n        DecrementGcmCounter(ctr); /* hardware requires +1, so subtract it */\n        GHASH(aes, authIn, authInSz, in, sz, tag, sizeof(tag));\n        wc_AesEncrypt(aes, ctr, partialBlock);\n        xorbuf(tag, partialBlock, sizeof(tag));\n    }\n\n    if (ConstantCompare(authTag, tag, authTagSz) != 0) {\n        ret = AES_GCM_AUTH_E;\n    }\n\n    /* Free memory if not a multiple of AES_BLOCK_SZ */\n    if (authInPadded != authIn) {\n        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    wolfSSL_CryptHwMutexUnLock();\n\n    return ret;\n}\n\n#endif /* STM32_CRYPTO_AES_GCM */\n\n#ifdef WOLFSSL_AESNI\nint AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,\n                      const byte* iv, word32 ivSz,\n                      const byte* authTag, word32 authTagSz,\n                      const byte* authIn, word32 authInSz);\n#else\nstatic\n#endif\nint AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,\n                      const byte* iv, word32 ivSz,\n                      const byte* authTag, word32 authTagSz,\n                      const byte* authIn, word32 authInSz)\n{\n    int ret = 0;\n    word32 blocks = sz / AES_BLOCK_SIZE;\n    word32 partial = sz % AES_BLOCK_SIZE;\n    const byte* c = in;\n    byte* p = out;\n    byte counter[AES_BLOCK_SIZE];\n    byte initialCounter[AES_BLOCK_SIZE];\n    byte *ctr;\n    byte scratch[AES_BLOCK_SIZE];\n    byte Tprime[AES_BLOCK_SIZE];\n    byte EKY0[AES_BLOCK_SIZE];\n#ifdef OPENSSL_EXTRA\n    word32 aadTemp;\n#endif\n    ctr = counter;\n    XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);\n    if (ivSz == GCM_NONCE_MID_SZ) {\n        XMEMCPY(initialCounter, iv, ivSz);\n        initialCounter[AES_BLOCK_SIZE - 1] = 1;\n    }\n    else {\n#ifdef OPENSSL_EXTRA\n        aadTemp = aes->aadLen;\n        aes->aadLen = 0;\n#endif\n        GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE);\n#ifdef OPENSSL_EXTRA\n        aes->aadLen = aadTemp;\n#endif\n    }\n    XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE);\n\n    /* Calc the authTag again using the received auth data and the cipher text */\n    GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));\n    wc_AesEncrypt(aes, ctr, EKY0);\n    xorbuf(Tprime, EKY0, sizeof(Tprime));\n\n#ifdef OPENSSL_EXTRA\n    if (!out) {\n        /* authenticated, non-confidential data */\n        /* store AAD size for next call */\n        aes->aadLen = authInSz;\n    }\n#endif\n    if (ConstantCompare(authTag, Tprime, authTagSz) != 0) {\n        return AES_GCM_AUTH_E;\n    }\n\n#if defined(WOLFSSL_PIC32MZ_CRYPT)\n    if (blocks) {\n        /* use initial IV for HW, but don't use it below */\n        XMEMCPY(aes->reg, ctr, AES_BLOCK_SIZE);\n\n        ret = wc_Pic32AesCrypt(\n            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,\n            out, in, (blocks * AES_BLOCK_SIZE),\n            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);\n        if (ret != 0)\n            return ret;\n    }\n    /* process remainder using partial handling */\n#endif\n\n#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)\n    /* some hardware acceleration can gain performance from doing AES encryption\n     * of the whole buffer at once */\n    if (c != p) { /* can not handle inline decryption */\n        while (blocks--) {\n            IncrementGcmCounter(ctr);\n            XMEMCPY(p, ctr, AES_BLOCK_SIZE);\n            p += AES_BLOCK_SIZE;\n        }\n\n        /* reset number of blocks and then do encryption */\n        blocks = sz / AES_BLOCK_SIZE;\n        wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);\n        xorbuf(out, c, AES_BLOCK_SIZE * blocks);\n        c += AES_BLOCK_SIZE * blocks;\n    }\n    else\n#endif /* HAVE_AES_ECB && !PIC32MZ */\n    while (blocks--) {\n        IncrementGcmCounter(ctr);\n    #if !defined(WOLFSSL_PIC32MZ_CRYPT)\n        wc_AesEncrypt(aes, ctr, scratch);\n        xorbuf(scratch, c, AES_BLOCK_SIZE);\n        XMEMCPY(p, scratch, AES_BLOCK_SIZE);\n    #endif\n        p += AES_BLOCK_SIZE;\n        c += AES_BLOCK_SIZE;\n    }\n\n    if (partial != 0) {\n        IncrementGcmCounter(ctr);\n        wc_AesEncrypt(aes, ctr, scratch);\n        xorbuf(scratch, c, partial);\n        XMEMCPY(p, scratch, partial);\n    }\n\n    return ret;\n}\n\n/* Software AES - GCM Decrypt */\nint wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,\n                     const byte* iv, word32 ivSz,\n                     const byte* authTag, word32 authTagSz,\n                     const byte* authIn, word32 authInSz)\n{\n#ifdef WOLFSSL_AESNI\n    int res = AES_GCM_AUTH_E;\n#endif\n\n    /* argument checks */\n    /* If the sz is non-zero, both in and out must be set. If sz is 0,\n     * in and out are don't cares, as this is is the GMAC case. */\n    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||\n        authTag == NULL || authTagSz > AES_BLOCK_SIZE || authTagSz == 0) {\n\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLF_CRYPTO_CB\n    if (aes->devId != INVALID_DEVID) {\n        int ret = wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,\n            authTag, authTagSz, authIn, authInSz);\n        if (ret != CRYPTOCB_UNAVAILABLE)\n            return ret;\n        /* fall-through when unavailable */\n    }\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)\n    /* if async and byte count above threshold */\n    /* only 12-byte IV is supported in HW */\n    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&\n                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {\n    #if defined(HAVE_CAVIUM)\n        #ifdef HAVE_CAVIUM_V\n        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */\n            return NitroxAesGcmDecrypt(aes, out, in, sz,\n                (const byte*)aes->devKey, aes->keylen, iv, ivSz,\n                authTag, authTagSz, authIn, authInSz);\n        }\n        #endif\n    #elif defined(HAVE_INTEL_QA)\n        return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,\n            (const byte*)aes->devKey, aes->keylen, iv, ivSz,\n            authTag, authTagSz, authIn, authInSz);\n    #else /* WOLFSSL_ASYNC_CRYPT_TEST */\n        if (wc_AsyncTestInit(&aes->asyncDev, ASYNC_TEST_AES_GCM_DECRYPT)) {\n            WC_ASYNC_TEST* testDev = &aes->asyncDev.test;\n            testDev->aes.aes = aes;\n            testDev->aes.out = out;\n            testDev->aes.in = in;\n            testDev->aes.sz = sz;\n            testDev->aes.iv = iv;\n            testDev->aes.ivSz = ivSz;\n            testDev->aes.authTag = (byte*)authTag;\n            testDev->aes.authTagSz = authTagSz;\n            testDev->aes.authIn = authIn;\n            testDev->aes.authInSz = authInSz;\n            return WC_PENDING_E;\n        }\n    #endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n#ifdef STM32_CRYPTO_AES_GCM\n    /* The STM standard peripheral library API's doesn't support partial blocks */\n    #ifdef STD_PERI_LIB\n    if (partial == 0)\n    #endif\n    {\n        return wc_AesGcmDecrypt_STM32(\n            aes, out, in, sz, iv, ivSz,\n            authTag, authTagSz, authIn, authInSz);\n    }\n#endif /* STM32_CRYPTO_AES_GCM */\n\n#ifdef WOLFSSL_AESNI\n    #ifdef HAVE_INTEL_AVX2\n    if (IS_INTEL_AVX2(intel_flags)) {\n        AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,\n                                 authTagSz, (byte*)aes->key, aes->rounds, &res);\n        if (res == 0)\n            return AES_GCM_AUTH_E;\n        return 0;\n    }\n    else\n    #endif\n    #ifdef HAVE_INTEL_AVX1\n    if (IS_INTEL_AVX1(intel_flags)) {\n        AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,\n                                 authTagSz, (byte*)aes->key, aes->rounds, &res);\n        if (res == 0)\n            return AES_GCM_AUTH_E;\n        return 0;\n    }\n    else\n    #endif\n    if (haveAESNI) {\n        AES_GCM_decrypt(in, out, authIn, iv, authTag, sz, authInSz, ivSz,\n                                 authTagSz, (byte*)aes->key, aes->rounds, &res);\n        if (res == 0)\n            return AES_GCM_AUTH_E;\n        return 0;\n    }\n    else\n#endif\n    {\n        return AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,\n                                                              authIn, authInSz);\n    }\n}\n#endif\n#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */\n#endif /* WOLFSSL_XILINX_CRYPT */\n#endif /* end of block for AESGCM implementation selection */\n\n\n/* Common to all, abstract functions that build off of lower level AESGCM\n * functions */\n#ifndef WC_NO_RNG\n\nint wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)\n{\n    int ret = 0;\n\n    if (aes == NULL || iv == NULL ||\n        (ivSz != GCM_NONCE_MIN_SZ && ivSz != GCM_NONCE_MID_SZ &&\n         ivSz != GCM_NONCE_MAX_SZ)) {\n\n        ret = BAD_FUNC_ARG;\n    }\n\n    if (ret == 0) {\n        XMEMCPY((byte*)aes->reg, iv, ivSz);\n\n        /* If the IV is 96, allow for a 2^64 invocation counter.\n         * For any other size for the nonce, limit the invocation\n         * counter to 32-bits. (SP 800-38D 8.3) */\n        aes->invokeCtr[0] = 0;\n        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;\n        aes->nonceSz = ivSz;\n    }\n\n    return ret;\n}\n\n\nint wc_AesGcmSetIV(Aes* aes, word32 ivSz,\n                   const byte* ivFixed, word32 ivFixedSz,\n                   WC_RNG* rng)\n{\n    int ret = 0;\n\n    if (aes == NULL || rng == NULL ||\n        (ivSz != GCM_NONCE_MIN_SZ && ivSz != GCM_NONCE_MID_SZ &&\n         ivSz != GCM_NONCE_MAX_SZ) ||\n        (ivFixed == NULL && ivFixedSz != 0) ||\n        (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {\n\n        ret = BAD_FUNC_ARG;\n    }\n\n    if (ret == 0) {\n        byte* iv = (byte*)aes->reg;\n\n        if (ivFixedSz)\n            XMEMCPY(iv, ivFixed, ivFixedSz);\n\n        ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);\n    }\n\n    if (ret == 0) {\n        /* If the IV is 96, allow for a 2^64 invocation counter.\n         * For any other size for the nonce, limit the invocation\n         * counter to 32-bits. (SP 800-38D 8.3) */\n        aes->invokeCtr[0] = 0;\n        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;\n        aes->nonceSz = ivSz;\n    }\n\n    return ret;\n}\n\n\nint wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,\n                        byte* ivOut, word32 ivOutSz,\n                        byte* authTag, word32 authTagSz,\n                        const byte* authIn, word32 authInSz)\n{\n    int ret = 0;\n\n    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||\n        ivOut == NULL || ivOutSz != aes->nonceSz ||\n        (authIn == NULL && authInSz != 0)) {\n\n        ret = BAD_FUNC_ARG;\n    }\n\n    if (ret == 0) {\n        aes->invokeCtr[0]++;\n        if (aes->invokeCtr[0] == 0) {\n            aes->invokeCtr[1]++;\n            if (aes->invokeCtr[1] == 0)\n                ret = AES_GCM_OVERFLOW_E;\n        }\n    }\n\n    if (ret == 0) {\n        XMEMCPY(ivOut, aes->reg, ivOutSz);\n        ret = wc_AesGcmEncrypt(aes, out, in, sz,\n                               (byte*)aes->reg, ivOutSz,\n                               authTag, authTagSz,\n                               authIn, authInSz);\n        if (ret == 0)\n            IncCtr((byte*)aes->reg, ivOutSz);\n    }\n\n    return ret;\n}\n\nint wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,\n            const byte* authIn, word32 authInSz,\n            byte* authTag, word32 authTagSz, WC_RNG* rng)\n{\n    Aes aes;\n    int ret;\n\n    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||\n        authTag == NULL || authTagSz == 0 || rng == NULL) {\n\n        return BAD_FUNC_ARG;\n    }\n\n    ret = wc_AesInit(&aes, NULL, INVALID_DEVID);\n    if (ret == 0) {\n        ret = wc_AesGcmSetKey(&aes, key, keySz);\n        if (ret == 0)\n            ret = wc_AesGcmSetIV(&aes, ivSz, NULL, 0, rng);\n        if (ret == 0)\n            ret = wc_AesGcmEncrypt_ex(&aes, NULL, NULL, 0, iv, ivSz,\n                                  authTag, authTagSz, authIn, authInSz);\n        wc_AesFree(&aes);\n    }\n    ForceZero(&aes, sizeof(aes));\n\n    return ret;\n}\n\nint wc_GmacVerify(const byte* key, word32 keySz,\n                  const byte* iv, word32 ivSz,\n                  const byte* authIn, word32 authInSz,\n                  const byte* authTag, word32 authTagSz)\n{\n    int ret;\n#ifndef NO_AES_DECRYPT\n    Aes aes;\n\n    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||\n        authTag == NULL || authTagSz == 0 || authTagSz > AES_BLOCK_SIZE) {\n\n        return BAD_FUNC_ARG;\n    }\n\n    ret = wc_AesInit(&aes, NULL, INVALID_DEVID);\n    if (ret == 0) {\n        ret = wc_AesGcmSetKey(&aes, key, keySz);\n        if (ret == 0)\n            ret = wc_AesGcmDecrypt(&aes, NULL, NULL, 0, iv, ivSz,\n                                  authTag, authTagSz, authIn, authInSz);\n        wc_AesFree(&aes);\n    }\n    ForceZero(&aes, sizeof(aes));\n#else\n    (void)key;\n    (void)keySz;\n    (void)iv;\n    (void)ivSz;\n    (void)authIn;\n    (void)authInSz;\n    (void)authTag;\n    (void)authTagSz;\n    ret = NOT_COMPILED_IN;\n#endif\n    return ret;\n}\n\n#endif /* WC_NO_RNG */\n\n\nWOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)\n{\n    if (gmac == NULL || key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    return wc_AesGcmSetKey(&gmac->aes, key, len);\n}\n\n\nWOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,\n                              const byte* authIn, word32 authInSz,\n                              byte* authTag, word32 authTagSz)\n{\n    return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,\n                                         authTag, authTagSz, authIn, authInSz);\n}\n\n#endif /* HAVE_AESGCM */\n\n\n#ifdef HAVE_AESCCM\n\nint wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)\n{\n    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))\n        return BAD_FUNC_ARG;\n\n    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);\n}\n\n#ifdef WOLFSSL_ARMASM\n    /* implementation located in wolfcrypt/src/port/arm/armv8-aes.c */\n\n#elif defined(HAVE_COLDFIRE_SEC)\n    #error \"Coldfire SEC doesn't currently support AES-CCM mode\"\n\n#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)\n    /* implemented in wolfcrypt/src/port/caam_aes.c */\n\n#elif defined(FREESCALE_LTC)\n\n/* return 0 on success */\nint wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,\n                   const byte* nonce, word32 nonceSz,\n                   byte* authTag, word32 authTagSz,\n                   const byte* authIn, word32 authInSz)\n{\n    byte *key;\n    uint32_t keySize;\n    status_t status;\n\n    /* sanity check on arguments */\n    if (aes == NULL || out == NULL || in == NULL || nonce == NULL\n            || authTag == NULL || nonceSz < 7 || nonceSz > 13)\n        return BAD_FUNC_ARG;\n\n    key = (byte*)aes->key;\n\n    status = wc_AesGetKeySize(aes, &keySize);\n    if (status != 0) {\n        return status;\n    }\n\n    status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,\n        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);\n\n    return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;\n}\n\n#ifdef HAVE_AES_DECRYPT\nint  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,\n                   const byte* nonce, word32 nonceSz,\n                   const byte* authTag, word32 authTagSz,\n                   const byte* authIn, word32 authInSz)\n{\n    byte *key;\n    uint32_t keySize;\n    status_t status;\n\n    /* sanity check on arguments */\n    if (aes == NULL || out == NULL || in == NULL || nonce == NULL\n            || authTag == NULL || nonceSz < 7 || nonceSz > 13)\n        return BAD_FUNC_ARG;\n\n    key = (byte*)aes->key;\n\n    status = wc_AesGetKeySize(aes, &keySize);\n    if (status != 0) {\n        return status;\n    }\n\n    status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,\n        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);\n\n    if (status == kStatus_Success) {\n        return 0;\n    }\n    else {\n        XMEMSET(out, 0, inSz);\n        return AES_CCM_AUTH_E;\n    }\n}\n#endif /* HAVE_AES_DECRYPT */\n\n#else\n\n/* Software CCM */\nstatic void roll_x(Aes* aes, const byte* in, word32 inSz, byte* out)\n{\n    /* process the bulk of the data */\n    while (inSz >= AES_BLOCK_SIZE) {\n        xorbuf(out, in, AES_BLOCK_SIZE);\n        in += AES_BLOCK_SIZE;\n        inSz -= AES_BLOCK_SIZE;\n\n        wc_AesEncrypt(aes, out, out);\n    }\n\n    /* process remainder of the data */\n    if (inSz > 0) {\n        xorbuf(out, in, inSz);\n        wc_AesEncrypt(aes, out, out);\n    }\n}\n\nstatic void roll_auth(Aes* aes, const byte* in, word32 inSz, byte* out)\n{\n    word32 authLenSz;\n    word32 remainder;\n\n    /* encode the length in */\n    if (inSz <= 0xFEFF) {\n        authLenSz = 2;\n        out[0] ^= ((inSz & 0xFF00) >> 8);\n        out[1] ^=  (inSz & 0x00FF);\n    }\n    else if (inSz <= 0xFFFFFFFF) {\n        authLenSz = 6;\n        out[0] ^= 0xFF; out[1] ^= 0xFE;\n        out[2] ^= ((inSz & 0xFF000000) >> 24);\n        out[3] ^= ((inSz & 0x00FF0000) >> 16);\n        out[4] ^= ((inSz & 0x0000FF00) >>  8);\n        out[5] ^=  (inSz & 0x000000FF);\n    }\n    /* Note, the protocol handles auth data up to 2^64, but we are\n     * using 32-bit sizes right now, so the bigger data isn't handled\n     * else if (inSz <= 0xFFFFFFFFFFFFFFFF) {} */\n    else\n        return;\n\n    /* start fill out the rest of the first block */\n    remainder = AES_BLOCK_SIZE - authLenSz;\n    if (inSz >= remainder) {\n        /* plenty of bulk data to fill the remainder of this block */\n        xorbuf(out + authLenSz, in, remainder);\n        inSz -= remainder;\n        in += remainder;\n    }\n    else {\n        /* not enough bulk data, copy what is available, and pad zero */\n        xorbuf(out + authLenSz, in, inSz);\n        inSz = 0;\n    }\n    wc_AesEncrypt(aes, out, out);\n\n    if (inSz > 0)\n        roll_x(aes, in, inSz, out);\n}\n\n\nstatic WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)\n{\n    word32 i;\n\n    for (i = 0; i < lenSz; i++) {\n        if (++B[AES_BLOCK_SIZE - 1 - i] != 0) return;\n    }\n}\n\n/* Software AES - CCM Encrypt */\n/* return 0 on success */\nint wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,\n                   const byte* nonce, word32 nonceSz,\n                   byte* authTag, word32 authTagSz,\n                   const byte* authIn, word32 authInSz)\n{\n    byte A[AES_BLOCK_SIZE];\n    byte B[AES_BLOCK_SIZE];\n    byte lenSz;\n    word32 i;\n    byte mask = 0xFF;\n    const word32 wordSz = (word32)sizeof(word32);\n\n    /* sanity check on arguments */\n    if (aes == NULL || out == NULL || in == NULL || nonce == NULL\n            || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||\n            authTagSz > AES_BLOCK_SIZE)\n        return BAD_FUNC_ARG;\n\n    XMEMSET(A, 0, sizeof(A));\n    XMEMCPY(B+1, nonce, nonceSz);\n    lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;\n    B[0] = (authInSz > 0 ? 64 : 0)\n         + (8 * (((byte)authTagSz - 2) / 2))\n         + (lenSz - 1);\n    for (i = 0; i < lenSz; i++) {\n        if (mask && i >= wordSz)\n            mask = 0x00;\n        B[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;\n    }\n\n    wc_AesEncrypt(aes, B, A);\n\n    if (authInSz > 0)\n        roll_auth(aes, authIn, authInSz, A);\n    if (inSz > 0)\n        roll_x(aes, in, inSz, A);\n    XMEMCPY(authTag, A, authTagSz);\n\n    B[0] = lenSz - 1;\n    for (i = 0; i < lenSz; i++)\n        B[AES_BLOCK_SIZE - 1 - i] = 0;\n    wc_AesEncrypt(aes, B, A);\n    xorbuf(authTag, A, authTagSz);\n\n    B[15] = 1;\n    while (inSz >= AES_BLOCK_SIZE) {\n        wc_AesEncrypt(aes, B, A);\n        xorbuf(A, in, AES_BLOCK_SIZE);\n        XMEMCPY(out, A, AES_BLOCK_SIZE);\n\n        AesCcmCtrInc(B, lenSz);\n        inSz -= AES_BLOCK_SIZE;\n        in += AES_BLOCK_SIZE;\n        out += AES_BLOCK_SIZE;\n    }\n    if (inSz > 0) {\n        wc_AesEncrypt(aes, B, A);\n        xorbuf(A, in, inSz);\n        XMEMCPY(out, A, inSz);\n    }\n\n    ForceZero(A, AES_BLOCK_SIZE);\n    ForceZero(B, AES_BLOCK_SIZE);\n\n    return 0;\n}\n\n#ifdef HAVE_AES_DECRYPT\n/* Software AES - CCM Decrypt */\nint  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,\n                   const byte* nonce, word32 nonceSz,\n                   const byte* authTag, word32 authTagSz,\n                   const byte* authIn, word32 authInSz)\n{\n    byte A[AES_BLOCK_SIZE];\n    byte B[AES_BLOCK_SIZE];\n    byte* o;\n    byte lenSz;\n    word32 i, oSz;\n    int result = 0;\n    byte mask = 0xFF;\n    const word32 wordSz = (word32)sizeof(word32);\n\n    /* sanity check on arguments */\n    if (aes == NULL || out == NULL || in == NULL || nonce == NULL\n            || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||\n            authTagSz > AES_BLOCK_SIZE)\n        return BAD_FUNC_ARG;\n\n    o = out;\n    oSz = inSz;\n    XMEMCPY(B+1, nonce, nonceSz);\n    lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;\n\n    B[0] = lenSz - 1;\n    for (i = 0; i < lenSz; i++)\n        B[AES_BLOCK_SIZE - 1 - i] = 0;\n    B[15] = 1;\n\n    while (oSz >= AES_BLOCK_SIZE) {\n        wc_AesEncrypt(aes, B, A);\n        xorbuf(A, in, AES_BLOCK_SIZE);\n        XMEMCPY(o, A, AES_BLOCK_SIZE);\n\n        AesCcmCtrInc(B, lenSz);\n        oSz -= AES_BLOCK_SIZE;\n        in += AES_BLOCK_SIZE;\n        o += AES_BLOCK_SIZE;\n    }\n    if (inSz > 0) {\n        wc_AesEncrypt(aes, B, A);\n        xorbuf(A, in, oSz);\n        XMEMCPY(o, A, oSz);\n    }\n\n    for (i = 0; i < lenSz; i++)\n        B[AES_BLOCK_SIZE - 1 - i] = 0;\n    wc_AesEncrypt(aes, B, A);\n\n    o = out;\n    oSz = inSz;\n\n    B[0] = (authInSz > 0 ? 64 : 0)\n         + (8 * (((byte)authTagSz - 2) / 2))\n         + (lenSz - 1);\n    for (i = 0; i < lenSz; i++) {\n        if (mask && i >= wordSz)\n            mask = 0x00;\n        B[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;\n    }\n\n    wc_AesEncrypt(aes, B, A);\n\n    if (authInSz > 0)\n        roll_auth(aes, authIn, authInSz, A);\n    if (inSz > 0)\n        roll_x(aes, o, oSz, A);\n\n    B[0] = lenSz - 1;\n    for (i = 0; i < lenSz; i++)\n        B[AES_BLOCK_SIZE - 1 - i] = 0;\n    wc_AesEncrypt(aes, B, B);\n    xorbuf(A, B, authTagSz);\n\n    if (ConstantCompare(A, authTag, authTagSz) != 0) {\n        /* If the authTag check fails, don't keep the decrypted data.\n         * Unfortunately, you need the decrypted data to calculate the\n         * check value. */\n        XMEMSET(out, 0, inSz);\n        result = AES_CCM_AUTH_E;\n    }\n\n    ForceZero(A, AES_BLOCK_SIZE);\n    ForceZero(B, AES_BLOCK_SIZE);\n    o = NULL;\n\n    return result;\n}\n\n#endif /* HAVE_AES_DECRYPT */\n#endif /* software CCM */\n\n/* abstract functions that call lower level AESCCM functions */\n#ifndef WC_NO_RNG\n\nint wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)\n{\n    int ret = 0;\n\n    if (aes == NULL || nonce == NULL ||\n        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {\n\n        ret = BAD_FUNC_ARG;\n    }\n\n    if (ret == 0) {\n        XMEMCPY(aes->reg, nonce, nonceSz);\n        aes->nonceSz = nonceSz;\n\n        /* Invocation counter should be 2^61 */\n        aes->invokeCtr[0] = 0;\n        aes->invokeCtr[1] = 0xE0000000;\n    }\n\n    return ret;\n}\n\n\nint wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,\n                        byte* ivOut, word32 ivOutSz,\n                        byte* authTag, word32 authTagSz,\n                        const byte* authIn, word32 authInSz)\n{\n    int ret = 0;\n\n    if (aes == NULL || out == NULL ||\n        (in == NULL && sz != 0) ||\n        ivOut == NULL ||\n        (authIn == NULL && authInSz != 0) ||\n        (ivOutSz != aes->nonceSz)) {\n\n        ret = BAD_FUNC_ARG;\n    }\n\n    if (ret == 0) {\n        aes->invokeCtr[0]++;\n        if (aes->invokeCtr[0] == 0) {\n            aes->invokeCtr[1]++;\n            if (aes->invokeCtr[1] == 0)\n                ret = AES_CCM_OVERFLOW_E;\n        }\n    }\n\n    if (ret == 0) {\n        ret = wc_AesCcmEncrypt(aes, out, in, sz,\n                               (byte*)aes->reg, aes->nonceSz,\n                               authTag, authTagSz,\n                               authIn, authInSz);\n        if (ret == 0) {\n            XMEMCPY(ivOut, aes->reg, aes->nonceSz);\n            IncCtr((byte*)aes->reg, aes->nonceSz);\n        }\n    }\n\n    return ret;\n}\n\n#endif /* WC_NO_RNG */\n\n#endif /* HAVE_AESCCM */\n\n\n/* Initialize Aes for use with async hardware */\nint wc_AesInit(Aes* aes, void* heap, int devId)\n{\n    int ret = 0;\n\n    if (aes == NULL)\n        return BAD_FUNC_ARG;\n\n    aes->heap = heap;\n\n#ifdef WOLF_CRYPTO_CB\n    aes->devId = devId;\n    aes->devCtx = NULL;\n#else\n    (void)devId;\n#endif\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)\n    ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,\n                                                        aes->heap, devId);\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n#ifdef WOLFSSL_AFALG\n    aes->alFd = -1;\n    aes->rdFd = -1;\n#endif\n#if defined(WOLFSSL_DEVCRYPTO) && \\\n   (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))\n    aes->ctx.cfd = -1;\n#endif\n#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)\n    XMEMSET(&aes->ctx, 0, sizeof(aes->ctx));\n#endif\n#ifdef HAVE_AESGCM\n#ifdef OPENSSL_EXTRA\n    XMEMSET(aes->aadH, 0, sizeof(aes->aadH));\n    aes->aadLen = 0;\n#endif\n#endif\n    return ret;\n}\n\n#ifdef HAVE_PKCS11\nint  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)\n{\n    int ret = 0;\n\n    if (aes == NULL)\n        ret = BAD_FUNC_ARG;\n    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))\n        ret = BUFFER_E;\n\n    if (ret == 0)\n        ret  = wc_AesInit(aes, heap, devId);\n    if (ret == 0) {\n        XMEMCPY(aes->id, id, len);\n        aes->idLen = len;\n    }\n\n    return ret;\n}\n#endif\n\n/* Free Aes from use with async hardware */\nvoid wc_AesFree(Aes* aes)\n{\n    if (aes == NULL)\n        return;\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)\n    wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);\n#endif /* WOLFSSL_ASYNC_CRYPT */\n#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)\n    if (aes->rdFd > 0) { /* negative is error case */\n        close(aes->rdFd);\n    }\n    if (aes->alFd > 0) {\n        close(aes->alFd);\n    }\n#endif /* WOLFSSL_AFALG */\n#if defined(WOLFSSL_DEVCRYPTO) && \\\n    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))\n    wc_DevCryptoFree(&aes->ctx);\n#endif\n#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \\\n    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \\\n    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))\n    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);\n#endif\n}\n\n\nint wc_AesGetKeySize(Aes* aes, word32* keySize)\n{\n    int ret = 0;\n\n    if (aes == NULL || keySize == NULL) {\n        return BAD_FUNC_ARG;\n    }\n#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)\n    *keySize = aes->ctx.key.keySize;\n    return ret;\n#endif\n    switch (aes->rounds) {\n#ifdef WOLFSSL_AES_128\n    case 10:\n        *keySize = 16;\n        break;\n#endif\n#ifdef WOLFSSL_AES_192\n    case 12:\n        *keySize = 24;\n        break;\n#endif\n#ifdef WOLFSSL_AES_256\n    case 14:\n        *keySize = 32;\n        break;\n#endif\n    default:\n        *keySize = 0;\n        ret = BAD_FUNC_ARG;\n    }\n\n    return ret;\n}\n\n#endif /* !WOLFSSL_TI_CRYPT */\n\n#ifdef HAVE_AES_ECB\n#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)\n    /* implemented in wolfcrypt/src/port/caam/caam_aes.c */\n\n#elif defined(WOLFSSL_AFALG)\n    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */\n\n#elif defined(WOLFSSL_DEVCRYPTO_AES)\n    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */\n\n#else\n\n/* Software AES - ECB */\nint wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n{\n    word32 blocks = sz / AES_BLOCK_SIZE;\n\n    if ((in == NULL) || (out == NULL) || (aes == NULL))\n      return BAD_FUNC_ARG;\n    while (blocks>0) {\n      wc_AesEncryptDirect(aes, out, in);\n      out += AES_BLOCK_SIZE;\n      in  += AES_BLOCK_SIZE;\n      sz  -= AES_BLOCK_SIZE;\n      blocks--;\n    }\n    return 0;\n}\n\n\nint wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n{\n    word32 blocks = sz / AES_BLOCK_SIZE;\n\n    if ((in == NULL) || (out == NULL) || (aes == NULL))\n      return BAD_FUNC_ARG;\n    while (blocks>0) {\n      wc_AesDecryptDirect(aes, out, in);\n      out += AES_BLOCK_SIZE;\n      in  += AES_BLOCK_SIZE;\n      sz  -= AES_BLOCK_SIZE;\n      blocks--;\n    }\n    return 0;\n}\n#endif\n#endif /* HAVE_AES_ECB */\n\n#ifdef WOLFSSL_AES_CFB\n/* CFB 128\n *\n * aes structure holding key to use for encryption\n * out buffer to hold result of encryption (must be at least as large as input\n *     buffer)\n * in  buffer to encrypt\n * sz  size of input buffer\n *\n * returns 0 on success and negative error values on failure\n */\n/* Software AES - CFB Encrypt */\nint wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n{\n    byte*  tmp = NULL;\n    byte*  reg = NULL;\n\n    if (aes == NULL || out == NULL || in == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (aes->left && sz) {\n        reg = (byte*)aes->reg + AES_BLOCK_SIZE - aes->left;\n    }\n\n    /* consume any unused bytes left in aes->tmp */\n    tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;\n    while (aes->left && sz) {\n        *(out++) = *(reg++) = *(in++) ^ *(tmp++);\n        aes->left--;\n        sz--;\n    }\n\n    while (sz >= AES_BLOCK_SIZE) {\n        wc_AesEncryptDirect(aes, out, (byte*)aes->reg);\n        xorbuf(out, in, AES_BLOCK_SIZE);\n        XMEMCPY(aes->reg, out, AES_BLOCK_SIZE);\n        out += AES_BLOCK_SIZE;\n        in  += AES_BLOCK_SIZE;\n        sz  -= AES_BLOCK_SIZE;\n        aes->left = 0;\n    }\n\n    /* encrypt left over data */\n    if (sz) {\n        wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);\n        aes->left = AES_BLOCK_SIZE;\n        tmp = (byte*)aes->tmp;\n        reg = (byte*)aes->reg;\n\n        while (sz--) {\n            *(out++) = *(reg++) = *(in++) ^ *(tmp++);\n            aes->left--;\n        }\n    }\n\n    return 0;\n}\n\n\n#ifdef HAVE_AES_DECRYPT\n/* CFB 128\n *\n * aes structure holding key to use for decryption\n * out buffer to hold result of decryption (must be at least as large as input\n *     buffer)\n * in  buffer to decrypt\n * sz  size of input buffer\n *\n * returns 0 on success and negative error values on failure\n */\n/* Software AES - CFB Decrypt */\nint wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n{\n    byte*  tmp;\n\n    if (aes == NULL || out == NULL || in == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* check if more input needs copied over to aes->reg */\n    if (aes->left && sz) {\n        int size = min(aes->left, sz);\n        XMEMCPY((byte*)aes->reg + AES_BLOCK_SIZE - aes->left, in, size);\n    }\n\n    /* consume any unused bytes left in aes->tmp */\n    tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;\n    while (aes->left && sz) {\n        *(out++) = *(in++) ^ *(tmp++);\n        aes->left--;\n        sz--;\n    }\n\n    while (sz > AES_BLOCK_SIZE) {\n        wc_AesEncryptDirect(aes, out, (byte*)aes->reg);\n        xorbuf(out, in, AES_BLOCK_SIZE);\n        XMEMCPY(aes->reg, in, AES_BLOCK_SIZE);\n        out += AES_BLOCK_SIZE;\n        in  += AES_BLOCK_SIZE;\n        sz  -= AES_BLOCK_SIZE;\n        aes->left = 0;\n    }\n\n    /* decrypt left over data */\n    if (sz) {\n        wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);\n        XMEMCPY(aes->reg, in, sz);\n        aes->left = AES_BLOCK_SIZE;\n        tmp = (byte*)aes->tmp;\n\n        while (sz--) {\n            *(out++) = *(in++) ^ *(tmp++);\n            aes->left--;\n        }\n    }\n\n    return 0;\n}\n#endif /* HAVE_AES_DECRYPT */\n#endif /* WOLFSSL_AES_CFB */\n\n\n#ifdef HAVE_AES_KEYWRAP\n\n/* Initialize key wrap counter with value */\nstatic WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)\n{\n    int i;\n    word32 bytes;\n\n    bytes = sizeof(word32);\n    for (i = 0; i < (int)sizeof(word32); i++) {\n        inOutCtr[i+sizeof(word32)] = (value >> ((bytes - 1) * 8)) & 0xFF;\n        bytes--;\n    }\n}\n\n/* Increment key wrap counter */\nstatic WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)\n{\n    int i;\n\n    /* in network byte order so start at end and work back */\n    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {\n        if (++inOutCtr[i])  /* we're done unless we overflow */\n            return;\n    }\n}\n\n/* Decrement key wrap counter */\nstatic WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)\n{\n    int i;\n\n    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {\n        if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */\n            return;\n    }\n}\n\n/* perform AES key wrap (RFC3394), return out sz on success, negative on err */\nint wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,\n                  byte* out, word32 outSz, const byte* iv)\n{\n    Aes aes;\n    byte* r;\n    word32 i;\n    int ret, j;\n\n    byte t[KEYWRAP_BLOCK_SIZE];\n    byte tmp[AES_BLOCK_SIZE];\n\n    /* n must be at least 2, output size is n + 8 bytes */\n    if (key == NULL || in  == NULL || inSz < 2 ||\n        out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))\n        return BAD_FUNC_ARG;\n\n    /* input must be multiple of 64-bits */\n    if (inSz % KEYWRAP_BLOCK_SIZE != 0)\n        return BAD_FUNC_ARG;\n\n    /* user IV is optional */\n    if (iv == NULL) {\n        XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);\n    } else {\n        XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);\n    }\n\n    r = out + 8;\n    XMEMCPY(r, in, inSz);\n    XMEMSET(t, 0, sizeof(t));\n\n    ret = wc_AesInit(&aes, NULL, INVALID_DEVID);\n    if (ret != 0)\n        return ret;\n\n    ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_ENCRYPTION);\n    if (ret != 0)\n        return ret;\n\n    for (j = 0; j <= 5; j++) {\n        for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {\n\n            /* load R[i] */\n            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);\n\n            wc_AesEncryptDirect(&aes, tmp, tmp);\n\n            /* calculate new A */\n            IncrementKeyWrapCounter(t);\n            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);\n\n            /* save R[i] */\n            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);\n            r += KEYWRAP_BLOCK_SIZE;\n        }\n        r = out + KEYWRAP_BLOCK_SIZE;\n    }\n\n    /* C[0] = A */\n    XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);\n\n    wc_AesFree(&aes);\n\n    return inSz + KEYWRAP_BLOCK_SIZE;\n}\n\nint wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,\n                    byte* out, word32 outSz, const byte* iv)\n{\n    Aes aes;\n    byte* r;\n    word32 i, n;\n    int ret, j;\n\n    byte t[KEYWRAP_BLOCK_SIZE];\n    byte tmp[AES_BLOCK_SIZE];\n\n    const byte* expIv;\n    const byte defaultIV[] = {\n        0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6\n    };\n\n    (void)iv;\n\n    if (key == NULL || in == NULL || inSz < 3 ||\n        out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))\n        return BAD_FUNC_ARG;\n\n    /* input must be multiple of 64-bits */\n    if (inSz % KEYWRAP_BLOCK_SIZE != 0)\n        return BAD_FUNC_ARG;\n\n    /* user IV optional */\n    if (iv != NULL) {\n        expIv = iv;\n    } else {\n        expIv = defaultIV;\n    }\n\n    /* A = C[0], R[i] = C[i] */\n    XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);\n    XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);\n    XMEMSET(t, 0, sizeof(t));\n\n    ret = wc_AesInit(&aes, NULL, INVALID_DEVID);\n    if (ret != 0)\n        return ret;\n\n    ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_DECRYPTION);\n    if (ret != 0)\n        return ret;\n\n    /* initialize counter to 6n */\n    n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;\n    InitKeyWrapCounter(t, 6 * n);\n\n    for (j = 5; j >= 0; j--) {\n        for (i = n; i >= 1; i--) {\n\n            /* calculate A */\n            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);\n            DecrementKeyWrapCounter(t);\n\n            /* load R[i], starting at end of R */\n            r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);\n            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);\n            wc_AesDecryptDirect(&aes, tmp, tmp);\n\n            /* save R[i] */\n            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);\n        }\n    }\n\n    wc_AesFree(&aes);\n\n    /* verify IV */\n    if (XMEMCMP(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)\n        return BAD_KEYWRAP_IV_E;\n\n    return inSz - KEYWRAP_BLOCK_SIZE;\n}\n\n#endif /* HAVE_AES_KEYWRAP */\n\n#ifdef WOLFSSL_AES_XTS\n\n/* Galios Field to use */\n#define GF_XTS 0x87\n\n/* This is to help with setting keys to correct encrypt or decrypt type.\n *\n * tweak AES key for tweak in XTS\n * aes   AES key for encrypt/decrypt process\n * key   buffer holding aes key | tweak key\n * len   length of key buffer in bytes. Should be twice that of key size. i.e.\n *       32 for a 16 byte key.\n * dir   direction, either AES_ENCRYPTION or AES_DECRYPTION\n * heap  heap hint to use for memory. Can be NULL\n * devId id to use with async crypto. Can be 0\n *\n * Note: is up to user to call wc_AesFree on tweak and aes key when done.\n *\n * return 0 on success\n */\nint wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir,\n        void* heap, int devId)\n{\n    word32 keySz;\n    int    ret = 0;\n\n    if (aes == NULL || key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {\n        return ret;\n    }\n    if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {\n        return ret;\n    }\n\n    keySz = len/2;\n    if (keySz != 16 && keySz != 32) {\n        WOLFSSL_MSG(\"Unsupported key size\");\n        return WC_KEY_SIZE_E;\n    }\n\n    if ((ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, dir)) == 0) {\n        ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,\n                AES_ENCRYPTION);\n        if (ret != 0) {\n            wc_AesFree(&aes->aes);\n        }\n    }\n\n    return ret;\n}\n\n\n/* This is used to free up resources used by Aes structs\n *\n * aes AES keys to free\n *\n * return 0 on success\n */\nint wc_AesXtsFree(XtsAes* aes)\n{\n    if (aes != NULL) {\n        wc_AesFree(&aes->aes);\n        wc_AesFree(&aes->tweak);\n    }\n\n    return 0;\n}\n\n\n/* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value\n * instead of a byte array. This just converts the word64 to a byte array and\n * calls wc_AesXtsEncrypt.\n *\n * aes    AES keys to use for block encrypt/decrypt\n * out    output buffer to hold cipher text\n * in     input plain text buffer to encrypt\n * sz     size of both out and in buffers\n * sector value to use for tweak\n *\n * returns 0 on success\n */\nint wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in,\n        word32 sz, word64 sector)\n{\n    byte* pt;\n    byte  i[AES_BLOCK_SIZE];\n\n    XMEMSET(i, 0, AES_BLOCK_SIZE);\n#ifdef BIG_ENDIAN_ORDER\n    sector = ByteReverseWord64(sector);\n#endif\n    pt = (byte*)&sector;\n    XMEMCPY(i, pt, sizeof(word64));\n\n    return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, AES_BLOCK_SIZE);\n}\n\n\n/* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value\n * instead of a byte array. This just converts the word64 to a byte array.\n *\n * aes    AES keys to use for block encrypt/decrypt\n * out    output buffer to hold plain text\n * in     input cipher text buffer to encrypt\n * sz     size of both out and in buffers\n * sector value to use for tweak\n *\n * returns 0 on success\n */\nint wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz,\n        word64 sector)\n{\n    byte* pt;\n    byte  i[AES_BLOCK_SIZE];\n\n    XMEMSET(i, 0, AES_BLOCK_SIZE);\n#ifdef BIG_ENDIAN_ORDER\n    sector = ByteReverseWord64(sector);\n#endif\n    pt = (byte*)&sector;\n    XMEMCPY(i, pt, sizeof(word64));\n\n    return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, AES_BLOCK_SIZE);\n}\n\n#ifdef HAVE_AES_ECB\n/* helper function for encrypting / decrypting full buffer at once */\nstatic int _AesXtsHelper(Aes* aes, byte* out, const byte* in, word32 sz, int dir)\n{\n    word32 outSz   = sz;\n    word32 totalSz = (sz / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; /* total bytes */\n    byte*  pt      = out;\n\n    outSz -= AES_BLOCK_SIZE;\n\n    while (outSz > 0) {\n        word32 j;\n        byte carry = 0;\n\n        /* multiply by shift left and propagate carry */\n        for (j = 0; j < AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {\n            byte tmpC;\n\n            tmpC   = (pt[j] >> 7) & 0x01;\n            pt[j+AES_BLOCK_SIZE] = ((pt[j] << 1) + carry) & 0xFF;\n            carry  = tmpC;\n        }\n        if (carry) {\n            pt[AES_BLOCK_SIZE] ^= GF_XTS;\n        }\n\n        pt += AES_BLOCK_SIZE;\n    }\n\n    xorbuf(out, in, totalSz);\n    if (dir == AES_ENCRYPTION) {\n        return wc_AesEcbEncrypt(aes, out, out, totalSz);\n    }\n    else {\n        return wc_AesEcbDecrypt(aes, out, out, totalSz);\n    }\n}\n#endif /* HAVE_AES_ECB */\n\n\n/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.\n *\n * xaes  AES keys to use for block encrypt/decrypt\n * out   output buffer to hold cipher text\n * in    input plain text buffer to encrypt\n * sz    size of both out and in buffers\n * i     value to use for tweak\n * iSz   size of i buffer, should always be AES_BLOCK_SIZE but having this input\n *       adds a sanity check on how the user calls the function.\n *\n * returns 0 on success\n */\n/* Software AES - XTS Encrypt  */\nint wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,\n        const byte* i, word32 iSz)\n{\n    int ret = 0;\n    word32 blocks = (sz / AES_BLOCK_SIZE);\n    Aes *aes, *tweak;\n\n    if (xaes == NULL || out == NULL || in == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    aes   = &xaes->aes;\n    tweak = &xaes->tweak;\n\n    if (iSz < AES_BLOCK_SIZE) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (blocks > 0) {\n        byte tmp[AES_BLOCK_SIZE];\n\n        XMEMSET(tmp, 0, AES_BLOCK_SIZE); /* set to 0's in case of improper AES\n                                          * key setup passed to encrypt direct*/\n\n        wc_AesEncryptDirect(tweak, tmp, i);\n\n    #ifdef HAVE_AES_ECB\n        /* encrypt all of buffer at once when possible */\n        if (in != out) { /* can not handle inline */\n            XMEMCPY(out, tmp, AES_BLOCK_SIZE);\n            if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0) {\n                return ret;\n            }\n        }\n    #endif\n\n        while (blocks > 0) {\n            word32 j;\n            byte carry = 0;\n            byte buf[AES_BLOCK_SIZE];\n\n    #ifdef HAVE_AES_ECB\n            if (in == out) { /* check for if inline */\n    #endif\n            XMEMCPY(buf, in, AES_BLOCK_SIZE);\n            xorbuf(buf, tmp, AES_BLOCK_SIZE);\n            wc_AesEncryptDirect(aes, out, buf);\n    #ifdef HAVE_AES_ECB\n            }\n    #endif\n            xorbuf(out, tmp, AES_BLOCK_SIZE);\n\n            /* multiply by shift left and propagate carry */\n            for (j = 0; j < AES_BLOCK_SIZE; j++) {\n                byte tmpC;\n\n                tmpC   = (tmp[j] >> 7) & 0x01;\n                tmp[j] = ((tmp[j] << 1) + carry) & 0xFF;\n                carry  = tmpC;\n            }\n            if (carry) {\n                tmp[0] ^= GF_XTS;\n            }\n\n            in  += AES_BLOCK_SIZE;\n            out += AES_BLOCK_SIZE;\n            sz  -= AES_BLOCK_SIZE;\n            blocks--;\n        }\n\n        /* stealing operation of XTS to handle left overs */\n        if (sz > 0) {\n            byte buf[AES_BLOCK_SIZE];\n\n            XMEMCPY(buf, out - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n            if (sz >= AES_BLOCK_SIZE) { /* extra sanity check before copy */\n                return BUFFER_E;\n            }\n            XMEMCPY(out, buf, sz);\n            XMEMCPY(buf, in, sz);\n\n            xorbuf(buf, tmp, AES_BLOCK_SIZE);\n            wc_AesEncryptDirect(aes, out - AES_BLOCK_SIZE, buf);\n            xorbuf(out - AES_BLOCK_SIZE, tmp, AES_BLOCK_SIZE);\n        }\n    }\n    else {\n        WOLFSSL_MSG(\"Plain text input too small for encryption\");\n        return BAD_FUNC_ARG;\n    }\n\n    return ret;\n}\n\n\n/* Same process as encryption but Aes key is AES_DECRYPTION type.\n *\n * xaes  AES keys to use for block encrypt/decrypt\n * out   output buffer to hold plain text\n * in    input cipher text buffer to decrypt\n * sz    size of both out and in buffers\n * i     value to use for tweak\n * iSz   size of i buffer, should always be AES_BLOCK_SIZE but having this input\n *       adds a sanity check on how the user calls the function.\n *\n * returns 0 on success\n */\n/* Software AES - XTS Decrypt */\nint wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,\n        const byte* i, word32 iSz)\n{\n    int ret = 0;\n    word32 blocks = (sz / AES_BLOCK_SIZE);\n    Aes *aes, *tweak;\n\n    if (xaes == NULL || out == NULL || in == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    aes   = &xaes->aes;\n    tweak = &xaes->tweak;\n\n    if (iSz < AES_BLOCK_SIZE) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (blocks > 0) {\n        word32 j;\n        byte carry = 0;\n        byte tmp[AES_BLOCK_SIZE];\n        byte stl = (sz % AES_BLOCK_SIZE);\n\n        XMEMSET(tmp, 0, AES_BLOCK_SIZE); /* set to 0's in case of improper AES\n                                          * key setup passed to decrypt direct*/\n\n        wc_AesEncryptDirect(tweak, tmp, i);\n\n        /* if Stealing then break out of loop one block early to handle special\n         * case */\n        if (stl > 0) {\n            blocks--;\n        }\n\n    #ifdef HAVE_AES_ECB\n        /* decrypt all of buffer at once when possible */\n        if (in != out) { /* can not handle inline */\n            XMEMCPY(out, tmp, AES_BLOCK_SIZE);\n            if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0) {\n                return ret;\n            }\n        }\n    #endif\n\n        while (blocks > 0) {\n            byte buf[AES_BLOCK_SIZE];\n\n    #ifdef HAVE_AES_ECB\n            if (in == out) { /* check for if inline */\n    #endif\n            XMEMCPY(buf, in, AES_BLOCK_SIZE);\n            xorbuf(buf, tmp, AES_BLOCK_SIZE);\n            wc_AesDecryptDirect(aes, out, buf);\n    #ifdef HAVE_AES_ECB\n            }\n    #endif\n            xorbuf(out, tmp, AES_BLOCK_SIZE);\n\n            /* multiply by shift left and propagate carry */\n            for (j = 0; j < AES_BLOCK_SIZE; j++) {\n                byte tmpC;\n\n                tmpC   = (tmp[j] >> 7) & 0x01;\n                tmp[j] = ((tmp[j] << 1) + carry) & 0xFF;\n                carry  = tmpC;\n            }\n            if (carry) {\n                tmp[0] ^= GF_XTS;\n            }\n            carry = 0;\n\n            in  += AES_BLOCK_SIZE;\n            out += AES_BLOCK_SIZE;\n            sz  -= AES_BLOCK_SIZE;\n            blocks--;\n        }\n\n        /* stealing operation of XTS to handle left overs */\n        if (sz > 0) {\n            byte buf[AES_BLOCK_SIZE];\n            byte tmp2[AES_BLOCK_SIZE];\n\n            /* multiply by shift left and propagate carry */\n            for (j = 0; j < AES_BLOCK_SIZE; j++) {\n                byte tmpC;\n\n                tmpC   = (tmp[j] >> 7) & 0x01;\n                tmp2[j] = ((tmp[j] << 1) + carry) & 0xFF;\n                carry  = tmpC;\n            }\n            if (carry) {\n                tmp2[0] ^= GF_XTS;\n            }\n\n            XMEMCPY(buf, in, AES_BLOCK_SIZE);\n            xorbuf(buf, tmp2, AES_BLOCK_SIZE);\n            wc_AesDecryptDirect(aes, out, buf);\n            xorbuf(out, tmp2, AES_BLOCK_SIZE);\n\n            /* tmp2 holds partial | last */\n            XMEMCPY(tmp2, out, AES_BLOCK_SIZE);\n            in  += AES_BLOCK_SIZE;\n            out += AES_BLOCK_SIZE;\n            sz  -= AES_BLOCK_SIZE;\n\n            /* Make buffer with end of cipher text | last */\n            XMEMCPY(buf, tmp2, AES_BLOCK_SIZE);\n            if (sz >= AES_BLOCK_SIZE) { /* extra sanity check before copy */\n                return BUFFER_E;\n            }\n            XMEMCPY(buf, in,   sz);\n            XMEMCPY(out, tmp2, sz);\n\n            xorbuf(buf, tmp, AES_BLOCK_SIZE);\n            wc_AesDecryptDirect(aes, tmp2, buf);\n            xorbuf(tmp2, tmp, AES_BLOCK_SIZE);\n            XMEMCPY(out - AES_BLOCK_SIZE, tmp2, AES_BLOCK_SIZE);\n        }\n    }\n    else {\n        WOLFSSL_MSG(\"Plain text input too small for encryption\");\n        return BAD_FUNC_ARG;\n    }\n\n    return ret;\n}\n\n#endif /* WOLFSSL_AES_XTS */\n\n#endif /* HAVE_FIPS */\n#endif /* !NO_AES */\n"
  },
  {
    "path": "src/wolfcrypt/src/arc4.c",
    "content": "/* arc4.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifndef NO_RC4\n\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/arc4.h>\n\n\nint wc_Arc4SetKey(Arc4* arc4, const byte* key, word32 length)\n{\n    int ret = 0;\n    word32 i;\n    word32 keyIndex = 0, stateIndex = 0;\n\n    if (arc4 == NULL || key == NULL || length == 0) {\n        return BAD_FUNC_ARG;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ARC4) && \\\n        defined(HAVE_CAVIUM) && !defined(HAVE_CAVIUM_V)\n    if (arc4->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ARC4) {\n        return NitroxArc4SetKey(arc4, key, length);\n    }\n#endif\n\n    arc4->x = 1;\n    arc4->y = 0;\n\n    for (i = 0; i < ARC4_STATE_SIZE; i++)\n        arc4->state[i] = (byte)i;\n\n    for (i = 0; i < ARC4_STATE_SIZE; i++) {\n        word32 a = arc4->state[i];\n        stateIndex += key[keyIndex] + a;\n        stateIndex &= 0xFF;\n        arc4->state[i] = arc4->state[stateIndex];\n        arc4->state[stateIndex] = (byte)a;\n\n        if (++keyIndex >= length)\n            keyIndex = 0;\n    }\n\n    return ret;\n}\n\n\nstatic WC_INLINE byte MakeByte(word32* x, word32* y, byte* s)\n{\n    word32 a = s[*x], b;\n    *y = (*y+a) & 0xff;\n\n    b = s[*y];\n    s[*x] = (byte)b;\n    s[*y] = (byte)a;\n    *x = (*x+1) & 0xff;\n\n    return s[(a+b) & 0xff];\n}\n\n\nint wc_Arc4Process(Arc4* arc4, byte* out, const byte* in, word32 length)\n{\n    int ret = 0;\n    word32 x;\n    word32 y;\n\n    if (arc4 == NULL || out == NULL || in == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ARC4) && \\\n        defined(HAVE_CAVIUM) && !defined(HAVE_CAVIUM_V)\n    if (arc4->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ARC4) {\n        return NitroxArc4Process(arc4, out, in, length);\n    }\n#endif\n\n    x = arc4->x;\n    y = arc4->y;\n\n    while(length--)\n        *out++ = *in++ ^ MakeByte(&x, &y, arc4->state);\n\n    arc4->x = (byte)x;\n    arc4->y = (byte)y;\n\n    return ret;\n}\n\n/* Initialize Arc4 for use with async device */\nint wc_Arc4Init(Arc4* arc4, void* heap, int devId)\n{\n    int ret = 0;\n\n    if (arc4 == NULL)\n        return BAD_FUNC_ARG;\n\n    arc4->heap = heap;\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ARC4)\n    ret = wolfAsync_DevCtxInit(&arc4->asyncDev, WOLFSSL_ASYNC_MARKER_ARC4,\n        arc4->heap, devId);\n#else\n    (void)devId;\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    return ret;\n}\n\n\n/* Free Arc4 from use with async device */\nvoid wc_Arc4Free(Arc4* arc4)\n{\n    if (arc4 == NULL)\n        return;\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ARC4)\n    wolfAsync_DevCtxFree(&arc4->asyncDev, WOLFSSL_ASYNC_MARKER_ARC4);\n#endif /* WOLFSSL_ASYNC_CRYPT */\n}\n\n#endif /* NO_RC4 */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/asm.c",
    "content": "/* asm.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n/*\n * Based on public domain TomsFastMath 0.10 by Tom St Denis, tomstdenis@iahu.ca,\n * http://math.libtomcrypt.com\n */\n\n\n/******************************************************************/\n/* fp_montgomery_reduce.c asm or generic */\n\n\n/* Each platform needs to query info type 1 from cpuid to see if aesni is\n * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts\n */\n\n#if defined(HAVE_INTEL_MULX)\n#ifndef _MSC_VER\n    #define cpuid(reg, leaf, sub)\\\n            __asm__ __volatile__ (\"cpuid\":\\\n             \"=a\" (reg[0]), \"=b\" (reg[1]), \"=c\" (reg[2]), \"=d\" (reg[3]) :\\\n             \"a\" (leaf), \"c\"(sub));\n\n    #define XASM_LINK(f) asm(f)\n#else\n\n    #include <intrin.h>\n    #define cpuid(a,b,c) __cpuidex((int*)a,b,c)\n\n    #define XASM_LINK(f)\n\n#endif /* _MSC_VER */\n\n#define EAX 0\n#define EBX 1\n#define ECX 2\n#define EDX 3\n\n#define CPUID_AVX1   0x1\n#define CPUID_AVX2   0x2\n#define CPUID_RDRAND 0x4\n#define CPUID_RDSEED 0x8\n#define CPUID_BMI2   0x10   /* MULX, RORX */\n#define CPUID_ADX    0x20   /* ADCX, ADOX */\n\n#define IS_INTEL_AVX1       (cpuid_flags&CPUID_AVX1)\n#define IS_INTEL_AVX2       (cpuid_flags&CPUID_AVX2)\n#define IS_INTEL_BMI2       (cpuid_flags&CPUID_BMI2)\n#define IS_INTEL_ADX        (cpuid_flags&CPUID_ADX)\n#define IS_INTEL_RDRAND     (cpuid_flags&CPUID_RDRAND)\n#define IS_INTEL_RDSEED     (cpuid_flags&CPUID_RDSEED)\n#define SET_FLAGS\n\nstatic word32 cpuid_check = 0 ;\nstatic word32 cpuid_flags = 0 ;\n\nstatic word32 cpuid_flag(word32 leaf, word32 sub, word32 num, word32 bit) {\n    int got_intel_cpu = 0;\n    int got_amd_cpu = 0;\n    unsigned int reg[5];\n\n    reg[4] = '\\0' ;\n    cpuid(reg, 0, 0);\n\n    /* check for intel cpu */\n    if( memcmp((char *)&(reg[EBX]), \"Genu\", 4) == 0 &&\n        memcmp((char *)&(reg[EDX]), \"ineI\", 4) == 0 &&\n        memcmp((char *)&(reg[ECX]), \"ntel\", 4) == 0) {\n        got_intel_cpu = 1;\n    }\n\n    /* check for AMD cpu */\n    if( memcmp((char *)&(reg[EBX]), \"Auth\", 4) == 0 &&\n        memcmp((char *)&(reg[EDX]), \"enti\", 4) == 0 &&\n        memcmp((char *)&(reg[ECX]), \"cAMD\", 4) == 0) {\n        got_amd_cpu = 1;\n    }\n    if (got_intel_cpu || got_amd_cpu) {\n        cpuid(reg, leaf, sub);\n        return((reg[num]>>bit)&0x1) ;\n    }\n    return 0 ;\n}\n\nWC_INLINE static int set_cpuid_flags(void) {\n    if(cpuid_check == 0) {\n        if(cpuid_flag(7, 0, EBX, 8)){  cpuid_flags |= CPUID_BMI2 ; }\n        if(cpuid_flag(7, 0, EBX,19)){  cpuid_flags |= CPUID_ADX  ; }\n\t\tcpuid_check = 1 ;\n\t\treturn 0 ;\n    }\n    return 1 ;\n}\n\n#define RETURN return\n#define IF_HAVE_INTEL_MULX(func, ret)    \\\n   if(cpuid_check==0)set_cpuid_flags() ; \\\n   if(IS_INTEL_BMI2 && IS_INTEL_ADX){  func;  ret ;  }\n\n#else\n    #define IF_HAVE_INTEL_MULX(func, ret)\n#endif\n\n#if defined(TFM_X86) && !defined(TFM_SSE2)\n/* x86-32 code */\n\n#define MONT_START\n#define MONT_FINI\n#define LOOP_END\n#define LOOP_START \\\n   mu = c[x] * mp\n\n#define INNERMUL                                          \\\n__asm__(                                                  \\\n   \"movl %5,%%eax \\n\\t\"                                   \\\n   \"mull %4       \\n\\t\"                                   \\\n   \"addl %1,%%eax \\n\\t\"                                   \\\n   \"adcl $0,%%edx \\n\\t\"                                   \\\n   \"addl %%eax,%0 \\n\\t\"                                   \\\n   \"adcl $0,%%edx \\n\\t\"                                   \\\n   \"movl %%edx,%1 \\n\\t\"                                   \\\n:\"=g\"(_c[LO]), \"=r\"(cy)                                   \\\n:\"0\"(_c[LO]), \"1\"(cy), \"r\"(mu), \"r\"(*tmpm++)              \\\n: \"%eax\", \"%edx\", \"cc\")\n\n#define PROPCARRY                           \\\n__asm__(                                    \\\n   \"addl   %1,%0    \\n\\t\"                   \\\n   \"setb   %%al     \\n\\t\"                   \\\n   \"movzbl %%al,%1 \\n\\t\"                    \\\n:\"=g\"(_c[LO]), \"=r\"(cy)                     \\\n:\"0\"(_c[LO]), \"1\"(cy)                       \\\n: \"%eax\", \"cc\")\n\n/******************************************************************/\n#elif defined(TFM_X86_64)\n/* x86-64 code */\n\n#define MONT_START\n#define MONT_FINI\n#define LOOP_END\n#define LOOP_START \\\n   mu = c[x] * mp\n\n#define INNERMUL                                          \\\n__asm__(                                                  \\\n   \"movq %5,%%rax \\n\\t\"                                   \\\n   \"mulq %4       \\n\\t\"                                   \\\n   \"addq %1,%%rax \\n\\t\"                                   \\\n   \"adcq $0,%%rdx \\n\\t\"                                   \\\n   \"addq %%rax,%0 \\n\\t\"                                   \\\n   \"adcq $0,%%rdx \\n\\t\"                                   \\\n   \"movq %%rdx,%1 \\n\\t\"                                   \\\n:\"=g\"(_c[LO]), \"=r\"(cy)                                   \\\n:\"0\"(_c[LO]), \"1\"(cy), \"r\"(mu), \"r\"(*tmpm++)              \\\n: \"%rax\", \"%rdx\", \"cc\")\n\n#if defined(HAVE_INTEL_MULX)\n#define MULX_INNERMUL8(x,y,z,cy)                                       \\\n    __asm__  volatile (                                                \\\n        \"movq\t%[yn], %%rdx\\n\\t\"                                      \\\n        \"xorq\t%%rcx, %%rcx\\n\\t\"                                      \\\n        \"movq   0(%[c]), %%r8\\n\\t\"                                     \\\n        \"movq   8(%[c]), %%r9\\n\\t\"                                     \\\n        \"movq   16(%[c]), %%r10\\n\\t\"                                   \\\n        \"movq   24(%[c]), %%r11\\n\\t\"                                   \\\n        \"movq   32(%[c]), %%r12\\n\\t\"                                   \\\n        \"movq   40(%[c]), %%r13\\n\\t\"                                   \\\n        \"movq   48(%[c]), %%r14\\n\\t\"                                   \\\n        \"movq   56(%[c]), %%r15\\n\\t\"                                   \\\n                                                                       \\\n        \"mulx\t0(%[xp]), %%rax, %%rcx\\n\\t\"                            \\\n        \"adcxq\t%[cy], %%r8\\n\\t\"                                       \\\n        \"adoxq\t%%rax, %%r8\\n\\t\"                                       \\\n        \"mulx\t8(%[xp]), %%rax, %[cy]\\n\\t\"                            \\\n        \"adcxq\t%%rcx, %%r9\\n\\t\"                                       \\\n        \"adoxq\t%%rax, %%r9\\n\\t\"                                       \\\n        \"mulx\t16(%[xp]), %%rax, %%rcx\\n\\t\"                           \\\n        \"adcxq\t%[cy], %%r10\\n\\t\"                                      \\\n        \"adoxq\t%%rax, %%r10\\n\\t\"                                      \\\n        \"mulx\t24(%[xp]), %%rax, %[cy]\\n\\t\"                           \\\n        \"adcxq\t%%rcx, %%r11\\n\\t\"                                      \\\n        \"adoxq\t%%rax, %%r11\\n\\t\"                                      \\\n        \"mulx\t32(%[xp]), %%rax, %%rcx\\n\\t\"                           \\\n        \"adcxq\t%[cy], %%r12\\n\\t\"                                      \\\n        \"adoxq\t%%rax, %%r12\\n\\t\"                                      \\\n        \"mulx\t40(%[xp]), %%rax, %[cy]\\n\\t\"                           \\\n        \"adcxq\t%%rcx, %%r13\\n\\t\"                                      \\\n        \"adoxq\t%%rax, %%r13\\n\\t\"                                      \\\n        \"mulx\t48(%[xp]), %%rax, %%rcx\\n\\t\"                           \\\n        \"adcxq\t%[cy], %%r14\\n\\t\"                                      \\\n        \"adoxq\t%%rax, %%r14\\n\\t\"                                      \\\n        \"adcxq\t%%rcx, %%r15\\n\\t\"                                      \\\n        \"mulx\t56(%[xp]), %%rax, %[cy]\\n\\t\"                           \\\n        \"movq\t$0, %%rdx\\n\\t\"                                         \\\n        \"adoxq\t%%rdx, %%rax\\n\\t\"                                      \\\n        \"adcxq\t%%rdx, %[cy]\\n\\t\"                                      \\\n        \"adoxq\t%%rdx, %[cy]\\n\\t\"                                      \\\n        \"addq   %%rax, %%r15\\n\\t\"                                      \\\n        \"adcq   $0, %[cy]\\n\\t\"                                         \\\n                                                                       \\\n        \"movq   %%r8,   0(%[c])\\n\\t\"                                   \\\n        \"movq   %%r9,   8(%[c])\\n\\t\"                                   \\\n        \"movq   %%r10, 16(%[c])\\n\\t\"                                   \\\n        \"movq   %%r11, 24(%[c])\\n\\t\"                                   \\\n        \"movq   %%r12, 32(%[c])\\n\\t\"                                   \\\n        \"movq   %%r13, 40(%[c])\\n\\t\"                                   \\\n        \"movq   %%r14, 48(%[c])\\n\\t\"                                   \\\n        \"movq   %%r15, 56(%[c])\\n\\t\"                                   \\\n        : [cy] \"+r\" (cy)                                               \\\n        : [xp] \"r\" (x), [c] \"r\" (c_mulx), [yn] \"rm\" (y)                \\\n        :\"%r8\", \"%r9\", \"%r10\", \"%r11\", \"%r12\", \"%r13\", \"%r14\", \"%r15\", \\\n         \"%rdx\", \"%rax\", \"%rcx\" \\\n    )\n\n#define INNERMUL8_MULX \\\n{\\\n    MULX_INNERMUL8(tmpm, mu, _c, cy);\\\n}\n#endif\n\n#define INNERMUL8 \\\n __asm__(                    \\\n \"movq 0(%5),%%rax    \\n\\t\"  \\\n \"movq 0(%2),%%r10    \\n\\t\"  \\\n \"movq 0x8(%5),%%r11  \\n\\t\"  \\\n \"mulq %4             \\n\\t\"  \\\n \"addq %%r10,%%rax    \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq 0x8(%2),%%r10  \\n\\t\"  \\\n \"addq %3,%%rax       \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq %%rax,0(%0)    \\n\\t\"  \\\n \"movq %%rdx,%1       \\n\\t\"  \\\n \\\n \"movq %%r11,%%rax    \\n\\t\"  \\\n \"movq 0x10(%5),%%r11 \\n\\t\"  \\\n \"mulq %4             \\n\\t\"  \\\n \"addq %%r10,%%rax    \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq 0x10(%2),%%r10 \\n\\t\"  \\\n \"addq %3,%%rax       \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq %%rax,0x8(%0)  \\n\\t\"  \\\n \"movq %%rdx,%1       \\n\\t\"  \\\n \\\n \"movq %%r11,%%rax    \\n\\t\"  \\\n \"movq 0x18(%5),%%r11 \\n\\t\"  \\\n \"mulq %4             \\n\\t\"  \\\n \"addq %%r10,%%rax    \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq 0x18(%2),%%r10 \\n\\t\"  \\\n \"addq %3,%%rax       \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq %%rax,0x10(%0) \\n\\t\"  \\\n \"movq %%rdx,%1       \\n\\t\"  \\\n \\\n \"movq %%r11,%%rax    \\n\\t\"  \\\n \"movq 0x20(%5),%%r11 \\n\\t\"  \\\n \"mulq %4             \\n\\t\"  \\\n \"addq %%r10,%%rax    \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq 0x20(%2),%%r10 \\n\\t\"  \\\n \"addq %3,%%rax       \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq %%rax,0x18(%0) \\n\\t\"  \\\n \"movq %%rdx,%1       \\n\\t\"  \\\n \\\n \"movq %%r11,%%rax    \\n\\t\"  \\\n \"movq 0x28(%5),%%r11 \\n\\t\"  \\\n \"mulq %4             \\n\\t\"  \\\n \"addq %%r10,%%rax    \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq 0x28(%2),%%r10 \\n\\t\"  \\\n \"addq %3,%%rax       \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq %%rax,0x20(%0) \\n\\t\"  \\\n \"movq %%rdx,%1       \\n\\t\"  \\\n \\\n \"movq %%r11,%%rax    \\n\\t\"  \\\n \"movq 0x30(%5),%%r11 \\n\\t\"  \\\n \"mulq %4             \\n\\t\"  \\\n \"addq %%r10,%%rax    \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq 0x30(%2),%%r10 \\n\\t\"  \\\n \"addq %3,%%rax       \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq %%rax,0x28(%0) \\n\\t\"  \\\n \"movq %%rdx,%1       \\n\\t\"  \\\n \\\n \"movq %%r11,%%rax    \\n\\t\"  \\\n \"movq 0x38(%5),%%r11 \\n\\t\"  \\\n \"mulq %4             \\n\\t\"  \\\n \"addq %%r10,%%rax    \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq 0x38(%2),%%r10 \\n\\t\"  \\\n \"addq %3,%%rax       \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq %%rax,0x30(%0) \\n\\t\"  \\\n \"movq %%rdx,%1       \\n\\t\"  \\\n \\\n \"movq %%r11,%%rax    \\n\\t\"  \\\n \"mulq %4             \\n\\t\"  \\\n \"addq %%r10,%%rax    \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"addq %3,%%rax       \\n\\t\"  \\\n \"adcq $0,%%rdx       \\n\\t\"  \\\n \"movq %%rax,0x38(%0) \\n\\t\"  \\\n \"movq %%rdx,%1       \\n\\t\"  \\\n \\\n:\"=r\"(_c), \"=r\"(cy)                    \\\n: \"0\"(_c),  \"1\"(cy), \"g\"(mu), \"r\"(tmpm)\\\n: \"%rax\", \"%rdx\", \"%r10\", \"%r11\", \"cc\")\n\n#define PROPCARRY                           \\\n__asm__(                                    \\\n   \"addq   %1,%0    \\n\\t\"                   \\\n   \"setb   %%al     \\n\\t\"                   \\\n   \"movzbq %%al,%1 \\n\\t\"                    \\\n:\"=g\"(_c[LO]), \"=r\"(cy)                     \\\n:\"0\"(_c[LO]), \"1\"(cy)                       \\\n: \"%rax\", \"cc\")\n\n/******************************************************************/\n#elif defined(TFM_SSE2)\n/* SSE2 code (assumes 32-bit fp_digits) */\n/* XMM register assignments:\n * xmm0  *tmpm++, then Mu * (*tmpm++)\n * xmm1  c[x], then Mu\n * xmm2  mp\n * xmm3  cy\n * xmm4  _c[LO]\n */\n\n#define MONT_START \\\n   __asm__(\"movd %0,%%mm2\"::\"g\"(mp))\n\n#define MONT_FINI \\\n   __asm__(\"emms\")\n\n#define LOOP_START          \\\n__asm__(                    \\\n\"movd %0,%%mm1        \\n\\t\" \\\n\"pxor %%mm3,%%mm3     \\n\\t\" \\\n\"pmuludq %%mm2,%%mm1  \\n\\t\" \\\n:: \"g\"(c[x]))\n\n/* pmuludq on mmx registers does a 32x32->64 multiply. */\n#define INNERMUL               \\\n__asm__(                       \\\n   \"movd %1,%%mm4        \\n\\t\" \\\n   \"movd %2,%%mm0        \\n\\t\" \\\n   \"paddq %%mm4,%%mm3    \\n\\t\" \\\n   \"pmuludq %%mm1,%%mm0  \\n\\t\" \\\n   \"paddq %%mm0,%%mm3    \\n\\t\" \\\n   \"movd %%mm3,%0        \\n\\t\" \\\n   \"psrlq $32, %%mm3     \\n\\t\" \\\n:\"=g\"(_c[LO]) : \"0\"(_c[LO]), \"g\"(*tmpm++) );\n\n#define INNERMUL8 \\\n__asm__(                       \\\n   \"movd 0(%1),%%mm4     \\n\\t\" \\\n   \"movd 0(%2),%%mm0     \\n\\t\" \\\n   \"paddq %%mm4,%%mm3    \\n\\t\" \\\n   \"pmuludq %%mm1,%%mm0  \\n\\t\" \\\n   \"movd 4(%2),%%mm5     \\n\\t\" \\\n   \"paddq %%mm0,%%mm3    \\n\\t\" \\\n   \"movd 4(%1),%%mm6     \\n\\t\" \\\n   \"movd %%mm3,0(%0)     \\n\\t\" \\\n   \"psrlq $32, %%mm3     \\n\\t\" \\\n\\\n   \"paddq %%mm6,%%mm3    \\n\\t\" \\\n   \"pmuludq %%mm1,%%mm5  \\n\\t\" \\\n   \"movd 8(%2),%%mm6     \\n\\t\" \\\n   \"paddq %%mm5,%%mm3    \\n\\t\" \\\n   \"movd 8(%1),%%mm7     \\n\\t\" \\\n   \"movd %%mm3,4(%0)     \\n\\t\" \\\n   \"psrlq $32, %%mm3     \\n\\t\" \\\n\\\n   \"paddq %%mm7,%%mm3    \\n\\t\" \\\n   \"pmuludq %%mm1,%%mm6  \\n\\t\" \\\n   \"movd 12(%2),%%mm7    \\n\\t\" \\\n   \"paddq %%mm6,%%mm3    \\n\\t\" \\\n   \"movd 12(%1),%%mm5     \\n\\t\" \\\n   \"movd %%mm3,8(%0)     \\n\\t\" \\\n   \"psrlq $32, %%mm3     \\n\\t\" \\\n\\\n   \"paddq %%mm5,%%mm3    \\n\\t\" \\\n   \"pmuludq %%mm1,%%mm7  \\n\\t\" \\\n   \"movd 16(%2),%%mm5    \\n\\t\" \\\n   \"paddq %%mm7,%%mm3    \\n\\t\" \\\n   \"movd 16(%1),%%mm6    \\n\\t\" \\\n   \"movd %%mm3,12(%0)    \\n\\t\" \\\n   \"psrlq $32, %%mm3     \\n\\t\" \\\n\\\n   \"paddq %%mm6,%%mm3    \\n\\t\" \\\n   \"pmuludq %%mm1,%%mm5  \\n\\t\" \\\n   \"movd 20(%2),%%mm6    \\n\\t\" \\\n   \"paddq %%mm5,%%mm3    \\n\\t\" \\\n   \"movd 20(%1),%%mm7    \\n\\t\" \\\n   \"movd %%mm3,16(%0)    \\n\\t\" \\\n   \"psrlq $32, %%mm3     \\n\\t\" \\\n\\\n   \"paddq %%mm7,%%mm3    \\n\\t\" \\\n   \"pmuludq %%mm1,%%mm6  \\n\\t\" \\\n   \"movd 24(%2),%%mm7    \\n\\t\" \\\n   \"paddq %%mm6,%%mm3    \\n\\t\" \\\n   \"movd 24(%1),%%mm5     \\n\\t\" \\\n   \"movd %%mm3,20(%0)    \\n\\t\" \\\n   \"psrlq $32, %%mm3     \\n\\t\" \\\n\\\n   \"paddq %%mm5,%%mm3    \\n\\t\" \\\n   \"pmuludq %%mm1,%%mm7  \\n\\t\" \\\n   \"movd 28(%2),%%mm5    \\n\\t\" \\\n   \"paddq %%mm7,%%mm3    \\n\\t\" \\\n   \"movd 28(%1),%%mm6    \\n\\t\" \\\n   \"movd %%mm3,24(%0)    \\n\\t\" \\\n   \"psrlq $32, %%mm3     \\n\\t\" \\\n\\\n   \"paddq %%mm6,%%mm3    \\n\\t\" \\\n   \"pmuludq %%mm1,%%mm5  \\n\\t\" \\\n   \"paddq %%mm5,%%mm3    \\n\\t\" \\\n   \"movd %%mm3,28(%0)    \\n\\t\" \\\n   \"psrlq $32, %%mm3     \\n\\t\" \\\n:\"=r\"(_c) : \"0\"(_c), \"r\"(tmpm) );\n\n/* TAO switched tmpm from \"g\" to \"r\" after gcc tried to index the indexed stack\n   pointer */\n\n#define LOOP_END \\\n__asm__( \"movd %%mm3,%0  \\n\" :\"=r\"(cy))\n\n#define PROPCARRY                           \\\n__asm__(                                    \\\n   \"addl   %1,%0    \\n\\t\"                   \\\n   \"setb   %%al     \\n\\t\"                   \\\n   \"movzbl %%al,%1 \\n\\t\"                    \\\n:\"=g\"(_c[LO]), \"=r\"(cy)                     \\\n:\"0\"(_c[LO]), \"1\"(cy)                       \\\n: \"%eax\", \"cc\")\n\n/******************************************************************/\n#elif defined(TFM_ARM)\n   /* ARMv4 code */\n\n#define MONT_START\n#define MONT_FINI\n#define LOOP_END\n#define LOOP_START \\\n   mu = c[x] * mp\n\n\n#ifdef __thumb__\n\n#define INNERMUL                    \\\n__asm__(                            \\\n    \" LDR    r0,%1            \\n\\t\" \\\n    \" ADDS   r0,r0,%0         \\n\\t\" \\\n    \" ITE    CS               \\n\\t\" \\\n    \" MOVCS  %0,#1            \\n\\t\" \\\n    \" MOVCC  %0,#0            \\n\\t\" \\\n    \" UMLAL  r0,%0,%3,%4      \\n\\t\" \\\n    \" STR    r0,%1            \\n\\t\" \\\n:\"=r\"(cy),\"=m\"(_c[0]):\"0\"(cy),\"r\"(mu),\"r\"(*tmpm++),\"m\"(_c[0]):\"r0\",\"cc\");\n\n#define PROPCARRY                  \\\n__asm__(                           \\\n    \" LDR   r0,%1            \\n\\t\" \\\n    \" ADDS  r0,r0,%0         \\n\\t\" \\\n    \" STR   r0,%1            \\n\\t\" \\\n    \" ITE   CS               \\n\\t\" \\\n    \" MOVCS %0,#1            \\n\\t\" \\\n    \" MOVCC %0,#0            \\n\\t\" \\\n:\"=r\"(cy),\"=m\"(_c[0]):\"0\"(cy),\"m\"(_c[0]):\"r0\",\"cc\");\n\n\n/* TAO thumb mode uses ite (if then else) to detect carry directly\n * fixed unmatched constraint warning by changing 1 to m  */\n\n#else  /* __thumb__ */\n\n#define INNERMUL                    \\\n__asm__(                            \\\n    \" LDR    r0,%1            \\n\\t\" \\\n    \" ADDS   r0,r0,%0         \\n\\t\" \\\n    \" MOVCS  %0,#1            \\n\\t\" \\\n    \" MOVCC  %0,#0            \\n\\t\" \\\n    \" UMLAL  r0,%0,%3,%4      \\n\\t\" \\\n    \" STR    r0,%1            \\n\\t\" \\\n:\"=r\"(cy),\"=m\"(_c[0]):\"0\"(cy),\"r\"(mu),\"r\"(*tmpm++),\"1\"(_c[0]):\"r0\",\"cc\");\n\n#define PROPCARRY                  \\\n__asm__(                           \\\n    \" LDR   r0,%1            \\n\\t\" \\\n    \" ADDS  r0,r0,%0         \\n\\t\" \\\n    \" STR   r0,%1            \\n\\t\" \\\n    \" MOVCS %0,#1            \\n\\t\" \\\n    \" MOVCC %0,#0            \\n\\t\" \\\n:\"=r\"(cy),\"=m\"(_c[0]):\"0\"(cy),\"1\"(_c[0]):\"r0\",\"cc\");\n\n#endif /* __thumb__ */\n\n#elif defined(TFM_PPC32)\n\n/* PPC32 */\n#define MONT_START\n#define MONT_FINI\n#define LOOP_END\n#define LOOP_START \\\n   mu = c[x] * mp\n\n#define INNERMUL                     \\\n__asm__(                             \\\n   \" mullw    16,%3,%4       \\n\\t\"   \\\n   \" mulhwu   17,%3,%4       \\n\\t\"   \\\n   \" addc     16,16,%2       \\n\\t\"   \\\n   \" addze    17,17          \\n\\t\"   \\\n   \" addc     %1,16,%5       \\n\\t\"   \\\n   \" addze    %0,17          \\n\\t\"   \\\n:\"=r\"(cy),\"=r\"(_c[0]):\"0\"(cy),\"r\"(mu),\"r\"(tmpm[0]),\"1\"(_c[0]):\"16\", \"17\", \"cc\"); ++tmpm;\n\n#define PROPCARRY                    \\\n__asm__(                             \\\n   \" addc     %1,%3,%2      \\n\\t\"    \\\n   \" xor      %0,%2,%2      \\n\\t\"    \\\n   \" addze    %0,%2         \\n\\t\"    \\\n:\"=r\"(cy),\"=r\"(_c[0]):\"0\"(cy),\"1\"(_c[0]):\"cc\");\n\n#elif defined(TFM_PPC64)\n\n/* PPC64 */\n#define MONT_START\n#define MONT_FINI\n#define LOOP_END\n#define LOOP_START \\\n   mu = c[x] * mp\n\n#define INNERMUL                      \\\n__asm__(                              \\\n   \" mulld    r16,%3,%4       \\n\\t\"   \\\n   \" mulhdu   r17,%3,%4       \\n\\t\"   \\\n   \" addc     r16,16,%0       \\n\\t\"   \\\n   \" addze    r17,r17         \\n\\t\"   \\\n   \" ldx      r18,0,%1        \\n\\t\"   \\\n   \" addc     r16,r16,r18     \\n\\t\"   \\\n   \" addze    %0,r17          \\n\\t\"   \\\n   \" sdx      r16,0,%1        \\n\\t\"   \\\n:\"=r\"(cy),\"=m\"(_c[0]):\"0\"(cy),\"r\"(mu),\"r\"(tmpm[0]),\"1\"(_c[0]):\"r16\", \"r17\", \"r18\",\"cc\"); ++tmpm;\n\n#define PROPCARRY                     \\\n__asm__(                              \\\n   \" ldx      r16,0,%1       \\n\\t\"    \\\n   \" addc     r16,r16,%0     \\n\\t\"    \\\n   \" sdx      r16,0,%1       \\n\\t\"    \\\n   \" xor      %0,%0,%0       \\n\\t\"    \\\n   \" addze    %0,%0          \\n\\t\"    \\\n:\"=r\"(cy),\"=m\"(_c[0]):\"0\"(cy),\"1\"(_c[0]):\"r16\",\"cc\");\n\n/******************************************************************/\n\n#elif defined(TFM_AVR32)\n\n/* AVR32 */\n#define MONT_START\n#define MONT_FINI\n#define LOOP_END\n#define LOOP_START \\\n   mu = c[x] * mp\n\n#define INNERMUL                    \\\n__asm__(                            \\\n    \" ld.w   r2,%1            \\n\\t\" \\\n    \" add    r2,%0            \\n\\t\" \\\n    \" eor    r3,r3            \\n\\t\" \\\n    \" acr    r3               \\n\\t\" \\\n    \" macu.d r2,%3,%4         \\n\\t\" \\\n    \" st.w   %1,r2            \\n\\t\" \\\n    \" mov    %0,r3            \\n\\t\" \\\n:\"=r\"(cy),\"=r\"(_c):\"0\"(cy),\"r\"(mu),\"r\"(*tmpm++),\"1\"(_c):\"r2\",\"r3\");\n\n#define PROPCARRY                    \\\n__asm__(                             \\\n   \" ld.w     r2,%1         \\n\\t\"    \\\n   \" add      r2,%0         \\n\\t\"    \\\n   \" st.w     %1,r2         \\n\\t\"    \\\n   \" eor      %0,%0         \\n\\t\"    \\\n   \" acr      %0            \\n\\t\"    \\\n:\"=r\"(cy),\"=r\"(&_c[0]):\"0\"(cy),\"1\"(&_c[0]):\"r2\",\"cc\");\n\n/******************************************************************/\n#elif defined(TFM_MIPS)\n\n/* MIPS */\n#define MONT_START\n#define MONT_FINI\n#define LOOP_END\n#define LOOP_START \\\n   mu = c[x] * mp\n\n#define INNERMUL                     \\\n__asm__(                             \\\n   \" multu    %3,%4          \\n\\t\"   \\\n   \" mflo     $12            \\n\\t\"   \\\n   \" mfhi     $13            \\n\\t\"   \\\n   \" addu     $12,$12,%0     \\n\\t\"   \\\n   \" sltu     $10,$12,%0     \\n\\t\"   \\\n   \" addu     $13,$13,$10    \\n\\t\"   \\\n   \" lw       $10,%1         \\n\\t\"   \\\n   \" addu     $12,$12,$10    \\n\\t\"   \\\n   \" sltu     $10,$12,$10    \\n\\t\"   \\\n   \" addu     %0,$13,$10     \\n\\t\"   \\\n   \" sw       $12,%1         \\n\\t\"   \\\n:\"+r\"(cy),\"+m\"(_c[0]):\"\"(cy),\"r\"(mu),\"r\"(tmpm[0]),\"\"(_c[0]):\"$10\",\"$12\",\"$13\"); ++tmpm;\n\n#define PROPCARRY                    \\\n__asm__(                             \\\n   \" lw       $10,%1        \\n\\t\"    \\\n   \" addu     $10,$10,%0    \\n\\t\"    \\\n   \" sw       $10,%1        \\n\\t\"    \\\n   \" sltu     %0,$10,%0     \\n\\t\"    \\\n:\"+r\"(cy),\"+m\"(_c[0]):\"\"(cy),\"\"(_c[0]):\"$10\");\n\n/******************************************************************/\n#else\n\n/* ISO C code */\n#define MONT_START\n#define MONT_FINI\n#define LOOP_END\n#define LOOP_START \\\n   mu = c[x] * mp\n\n#define INNERMUL                                      \\\n   do { fp_word t;                                    \\\n   t  = ((fp_word)_c[0] + (fp_word)cy) +              \\\n                (((fp_word)mu) * ((fp_word)*tmpm++)); \\\n   _c[0] = (fp_digit)t;                               \\\n   cy = (fp_digit)(t >> DIGIT_BIT);                   \\\n   } while (0)\n\n#define PROPCARRY \\\n   do { fp_digit t = _c[0] += cy; cy = (t < cy); } while (0)\n\n#endif\n/******************************************************************/\n\n\n#define LO  0\n/* end fp_montogomery_reduce.c asm */\n\n\n/* start fp_sqr_comba.c asm */\n#if defined(TFM_X86)\n\n/* x86-32 optimized */\n\n#define COMBA_START\n\n#define CLEAR_CARRY \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define CARRY_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_FINI\n\n#define SQRADD(i, j)                                      \\\n__asm__(                                                  \\\n     \"movl  %6,%%eax     \\n\\t\"                            \\\n     \"mull  %%eax        \\n\\t\"                            \\\n     \"addl  %%eax,%0     \\n\\t\"                            \\\n     \"adcl  %%edx,%1     \\n\\t\"                            \\\n     \"adcl  $0,%2        \\n\\t\"                            \\\n     :\"=r\"(c0), \"=r\"(c1), \"=r\"(c2): \"0\"(c0), \"1\"(c1), \"2\"(c2), \"m\"(i) :\"%eax\",\"%edx\",\"cc\");\n\n#define SQRADD2(i, j)                                     \\\n__asm__(                                                  \\\n     \"movl  %6,%%eax     \\n\\t\"                            \\\n     \"mull  %7           \\n\\t\"                            \\\n     \"addl  %%eax,%0     \\n\\t\"                            \\\n     \"adcl  %%edx,%1     \\n\\t\"                            \\\n     \"adcl  $0,%2        \\n\\t\"                            \\\n     \"addl  %%eax,%0     \\n\\t\"                            \\\n     \"adcl  %%edx,%1     \\n\\t\"                            \\\n     \"adcl  $0,%2        \\n\\t\"                            \\\n     :\"=r\"(c0), \"=r\"(c1), \"=r\"(c2): \"0\"(c0), \"1\"(c1), \"2\"(c2), \"m\"(i), \"m\"(j)  :\"%eax\",\"%edx\", \"cc\");\n\n#define SQRADDSC(i, j)                                    \\\n__asm__(                                                     \\\n     \"movl  %3,%%eax     \\n\\t\"                            \\\n     \"mull  %4           \\n\\t\"                            \\\n     \"movl  %%eax,%0     \\n\\t\"                            \\\n     \"movl  %%edx,%1     \\n\\t\"                            \\\n     \"xorl  %2,%2        \\n\\t\"                            \\\n     :\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2): \"g\"(i), \"g\"(j) :\"%eax\",\"%edx\",\"cc\");\n\n#define SQRADDAC(i, j)                                    \\\n__asm__(                                                  \\\n     \"movl  %6,%%eax     \\n\\t\"                            \\\n     \"mull  %7           \\n\\t\"                            \\\n     \"addl  %%eax,%0     \\n\\t\"                            \\\n     \"adcl  %%edx,%1     \\n\\t\"                            \\\n     \"adcl  $0,%2        \\n\\t\"                            \\\n     :\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2): \"0\"(sc0), \"1\"(sc1), \"2\"(sc2), \"g\"(i), \"g\"(j) :\"%eax\",\"%edx\",\"cc\");\n\n#define SQRADDDB                                          \\\n__asm__(                                                  \\\n     \"addl %6,%0         \\n\\t\"                            \\\n     \"adcl %7,%1         \\n\\t\"                            \\\n     \"adcl %8,%2         \\n\\t\"                            \\\n     \"addl %6,%0         \\n\\t\"                            \\\n     \"adcl %7,%1         \\n\\t\"                            \\\n     \"adcl %8,%2         \\n\\t\"                            \\\n     :\"=r\"(c0), \"=r\"(c1), \"=r\"(c2) : \"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(sc0), \"r\"(sc1), \"r\"(sc2) : \"cc\");\n\n#elif defined(TFM_X86_64)\n/* x86-64 optimized */\n\n#define COMBA_START\n\n#define CLEAR_CARRY \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define CARRY_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_FINI\n\n#define SQRADD(i, j)                                      \\\n__asm__(                                                  \\\n     \"movq  %6,%%rax     \\n\\t\"                            \\\n     \"mulq  %%rax        \\n\\t\"                            \\\n     \"addq  %%rax,%0     \\n\\t\"                            \\\n     \"adcq  %%rdx,%1     \\n\\t\"                            \\\n     \"adcq  $0,%2        \\n\\t\"                            \\\n     :\"=r\"(c0), \"=r\"(c1), \"=r\"(c2): \"0\"(c0), \"1\"(c1), \"2\"(c2), \"x\"(i) :\"%rax\",\"%rdx\",\"cc\");\n\n#define SQRADD2(i, j)                                     \\\n__asm__(                                                  \\\n     \"movq  %6,%%rax     \\n\\t\"                            \\\n     \"mulq  %7           \\n\\t\"                            \\\n     \"addq  %%rax,%0     \\n\\t\"                            \\\n     \"adcq  %%rdx,%1     \\n\\t\"                            \\\n     \"adcq  $0,%2        \\n\\t\"                            \\\n     \"addq  %%rax,%0     \\n\\t\"                            \\\n     \"adcq  %%rdx,%1     \\n\\t\"                            \\\n     \"adcq  $0,%2        \\n\\t\"                            \\\n     :\"=r\"(c0), \"=r\"(c1), \"=r\"(c2): \"0\"(c0), \"1\"(c1), \"2\"(c2), \"g\"(i), \"g\"(j)  :\"%rax\",\"%rdx\",\"cc\");\n\n#define SQRADDSC(i, j)                                    \\\n__asm__(                                                  \\\n     \"movq  %3,%%rax     \\n\\t\"                            \\\n     \"mulq  %4           \\n\\t\"                            \\\n     \"movq  %%rax,%0     \\n\\t\"                            \\\n     \"movq  %%rdx,%1     \\n\\t\"                            \\\n     \"xorq  %2,%2        \\n\\t\"                            \\\n     :\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2): \"g\"(i), \"g\"(j) :\"%rax\",\"%rdx\",\"cc\");\n\n#define SQRADDAC(i, j)                                                         \\\n__asm__(                                                  \\\n     \"movq  %6,%%rax     \\n\\t\"                            \\\n     \"mulq  %7           \\n\\t\"                            \\\n     \"addq  %%rax,%0     \\n\\t\"                            \\\n     \"adcq  %%rdx,%1     \\n\\t\"                            \\\n     \"adcq  $0,%2        \\n\\t\"                            \\\n     :\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2): \"0\"(sc0), \"1\"(sc1), \"2\"(sc2), \"g\"(i), \"g\"(j) :\"%rax\",\"%rdx\",\"cc\");\n\n#define SQRADDDB                                          \\\n__asm__(                                                  \\\n     \"addq %6,%0         \\n\\t\"                            \\\n     \"adcq %7,%1         \\n\\t\"                            \\\n     \"adcq %8,%2         \\n\\t\"                            \\\n     \"addq %6,%0         \\n\\t\"                            \\\n     \"adcq %7,%1         \\n\\t\"                            \\\n     \"adcq %8,%2         \\n\\t\"                            \\\n     :\"=r\"(c0), \"=r\"(c1), \"=r\"(c2) : \"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(sc0), \"r\"(sc1), \"r\"(sc2) : \"cc\");\n\n#elif defined(TFM_SSE2)\n\n/* SSE2 Optimized */\n#define COMBA_START\n\n#define CLEAR_CARRY \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define CARRY_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_FINI \\\n   __asm__(\"emms\");\n\n#define SQRADD(i, j)                                      \\\n__asm__(                                                  \\\n     \"movd  %6,%%mm0     \\n\\t\"                            \\\n     \"pmuludq %%mm0,%%mm0\\n\\t\"                            \\\n     \"movd  %%mm0,%%eax  \\n\\t\"                            \\\n     \"psrlq $32,%%mm0    \\n\\t\"                            \\\n     \"addl  %%eax,%0     \\n\\t\"                            \\\n     \"movd  %%mm0,%%eax  \\n\\t\"                            \\\n     \"adcl  %%eax,%1     \\n\\t\"                            \\\n     \"adcl  $0,%2        \\n\\t\"                            \\\n     :\"=r\"(c0), \"=r\"(c1), \"=r\"(c2): \"0\"(c0), \"1\"(c1), \"2\"(c2), \"m\"(i) :\"%eax\",\"cc\");\n\n#define SQRADD2(i, j)                                     \\\n__asm__(                                                  \\\n     \"movd  %6,%%mm0     \\n\\t\"                            \\\n     \"movd  %7,%%mm1     \\n\\t\"                            \\\n     \"pmuludq %%mm1,%%mm0\\n\\t\"                            \\\n     \"movd  %%mm0,%%eax  \\n\\t\"                            \\\n     \"psrlq $32,%%mm0    \\n\\t\"                            \\\n     \"movd  %%mm0,%%edx  \\n\\t\"                            \\\n     \"addl  %%eax,%0     \\n\\t\"                            \\\n     \"adcl  %%edx,%1     \\n\\t\"                            \\\n     \"adcl  $0,%2        \\n\\t\"                            \\\n     \"addl  %%eax,%0     \\n\\t\"                            \\\n     \"adcl  %%edx,%1     \\n\\t\"                            \\\n     \"adcl  $0,%2        \\n\\t\"                            \\\n     :\"=r\"(c0), \"=r\"(c1), \"=r\"(c2): \"0\"(c0), \"1\"(c1), \"2\"(c2), \"m\"(i), \"m\"(j)  :\"%eax\",\"%edx\",\"cc\");\n\n#define SQRADDSC(i, j)                                                         \\\n__asm__(                                                  \\\n     \"movd  %3,%%mm0     \\n\\t\"                            \\\n     \"movd  %4,%%mm1     \\n\\t\"                            \\\n     \"pmuludq %%mm1,%%mm0\\n\\t\"                            \\\n     \"movd  %%mm0,%0     \\n\\t\"                            \\\n     \"psrlq $32,%%mm0    \\n\\t\"                            \\\n     \"movd  %%mm0,%1     \\n\\t\"                            \\\n     \"xorl  %2,%2        \\n\\t\"                            \\\n     :\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2): \"m\"(i), \"m\"(j));\n\n/* TAO removed sc0,1,2 as input to remove warning so %6,%7 become %3,%4 */\n\n#define SQRADDAC(i, j)                                                         \\\n__asm__(                                                  \\\n     \"movd  %6,%%mm0     \\n\\t\"                            \\\n     \"movd  %7,%%mm1     \\n\\t\"                            \\\n     \"pmuludq %%mm1,%%mm0\\n\\t\"                            \\\n     \"movd  %%mm0,%%eax  \\n\\t\"                            \\\n     \"psrlq $32,%%mm0    \\n\\t\"                            \\\n     \"movd  %%mm0,%%edx  \\n\\t\"                            \\\n     \"addl  %%eax,%0     \\n\\t\"                            \\\n     \"adcl  %%edx,%1     \\n\\t\"                            \\\n     \"adcl  $0,%2        \\n\\t\"                            \\\n     :\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2): \"0\"(sc0), \"1\"(sc1), \"2\"(sc2), \"m\"(i), \"m\"(j)  :\"%eax\",\"%edx\",\"cc\");\n\n#define SQRADDDB                                          \\\n__asm__(                                                  \\\n     \"addl %6,%0         \\n\\t\"                            \\\n     \"adcl %7,%1         \\n\\t\"                            \\\n     \"adcl %8,%2         \\n\\t\"                            \\\n     \"addl %6,%0         \\n\\t\"                            \\\n     \"adcl %7,%1         \\n\\t\"                            \\\n     \"adcl %8,%2         \\n\\t\"                            \\\n     :\"=r\"(c0), \"=r\"(c1), \"=r\"(c2) : \"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(sc0), \"r\"(sc1), \"r\"(sc2) : \"cc\");\n\n#elif defined(TFM_ARM)\n\n/* ARM code */\n\n#define COMBA_START\n\n#define CLEAR_CARRY \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define CARRY_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_FINI\n\n/* multiplies point i and j, updates carry \"c1\" and digit c2 */\n#define SQRADD(i, j)                                             \\\n__asm__(                                                         \\\n\"  UMULL  r0,r1,%6,%6              \\n\\t\"                         \\\n\"  ADDS   %0,%0,r0                 \\n\\t\"                         \\\n\"  ADCS   %1,%1,r1                 \\n\\t\"                         \\\n\"  ADC    %2,%2,#0                 \\n\\t\"                         \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2) : \"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i) : \"r0\", \"r1\", \"cc\");\n\n/* for squaring some of the terms are doubled... */\n#define SQRADD2(i, j)                                            \\\n__asm__(                                                         \\\n\"  UMULL  r0,r1,%6,%7              \\n\\t\"                         \\\n\"  ADDS   %0,%0,r0                 \\n\\t\"                         \\\n\"  ADCS   %1,%1,r1                 \\n\\t\"                         \\\n\"  ADC    %2,%2,#0                 \\n\\t\"                         \\\n\"  ADDS   %0,%0,r0                 \\n\\t\"                         \\\n\"  ADCS   %1,%1,r1                 \\n\\t\"                         \\\n\"  ADC    %2,%2,#0                 \\n\\t\"                         \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2) : \"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i), \"r\"(j) : \"r0\", \"r1\", \"cc\");\n\n#define SQRADDSC(i, j)                                           \\\n__asm__(                                                         \\\n\"  UMULL  %0,%1,%3,%4              \\n\\t\"                         \\\n\"  SUB    %2,%2,%2                 \\n\\t\"                         \\\n:\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2) : \"r\"(i), \"r\"(j) : \"cc\");\n\n/* TAO removed sc0,1,2 as input to remove warning so %6,%7 become %3,%4 */\n\n#define SQRADDAC(i, j)                                           \\\n__asm__(                                                         \\\n\"  UMULL  r0,r1,%6,%7              \\n\\t\"                         \\\n\"  ADDS   %0,%0,r0                 \\n\\t\"                         \\\n\"  ADCS   %1,%1,r1                 \\n\\t\"                         \\\n\"  ADC    %2,%2,#0                 \\n\\t\"                         \\\n:\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2) : \"0\"(sc0), \"1\"(sc1), \"2\"(sc2), \"r\"(i), \"r\"(j) : \"r0\", \"r1\", \"cc\");\n\n#define SQRADDDB                                                 \\\n__asm__(                                                         \\\n\"  ADDS  %0,%0,%3                     \\n\\t\"                      \\\n\"  ADCS  %1,%1,%4                     \\n\\t\"                      \\\n\"  ADC   %2,%2,%5                     \\n\\t\"                      \\\n\"  ADDS  %0,%0,%3                     \\n\\t\"                      \\\n\"  ADCS  %1,%1,%4                     \\n\\t\"                      \\\n\"  ADC   %2,%2,%5                     \\n\\t\"                      \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2) : \"r\"(sc0), \"r\"(sc1), \"r\"(sc2), \"0\"(c0), \"1\"(c1), \"2\"(c2) : \"cc\");\n\n#elif defined(TFM_PPC32)\n\n/* PPC32 */\n\n#define COMBA_START\n\n#define CLEAR_CARRY \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define CARRY_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_FINI\n\n/* multiplies point i and j, updates carry \"c1\" and digit c2 */\n#define SQRADD(i, j)             \\\n__asm__(                         \\\n   \" mullw  16,%6,%6       \\n\\t\" \\\n   \" addc   %0,%0,16       \\n\\t\" \\\n   \" mulhwu 16,%6,%6       \\n\\t\" \\\n   \" adde   %1,%1,16       \\n\\t\" \\\n   \" addze  %2,%2          \\n\\t\" \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2):\"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i):\"16\",\"cc\");\n\n/* for squaring some of the terms are doubled... */\n#define SQRADD2(i, j)            \\\n__asm__(                         \\\n   \" mullw  16,%6,%7       \\n\\t\" \\\n   \" mulhwu 17,%6,%7       \\n\\t\" \\\n   \" addc   %0,%0,16       \\n\\t\" \\\n   \" adde   %1,%1,17       \\n\\t\" \\\n   \" addze  %2,%2          \\n\\t\" \\\n   \" addc   %0,%0,16       \\n\\t\" \\\n   \" adde   %1,%1,17       \\n\\t\" \\\n   \" addze  %2,%2          \\n\\t\" \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2):\"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i), \"r\"(j):\"16\", \"17\",\"cc\");\n\n#define SQRADDSC(i, j)            \\\n__asm__(                          \\\n   \" mullw  %0,%6,%7        \\n\\t\" \\\n   \" mulhwu %1,%6,%7        \\n\\t\" \\\n   \" xor    %2,%2,%2        \\n\\t\" \\\n:\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2):\"0\"(sc0), \"1\"(sc1), \"2\"(sc2), \"r\"(i),\"r\"(j) : \"cc\");\n\n#define SQRADDAC(i, j)           \\\n__asm__(                         \\\n   \" mullw  16,%6,%7       \\n\\t\" \\\n   \" addc   %0,%0,16       \\n\\t\" \\\n   \" mulhwu 16,%6,%7       \\n\\t\" \\\n   \" adde   %1,%1,16       \\n\\t\" \\\n   \" addze  %2,%2          \\n\\t\" \\\n:\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2):\"0\"(sc0), \"1\"(sc1), \"2\"(sc2), \"r\"(i), \"r\"(j):\"16\", \"cc\");\n\n#define SQRADDDB                  \\\n__asm__(                          \\\n   \" addc   %0,%0,%3        \\n\\t\" \\\n   \" adde   %1,%1,%4        \\n\\t\" \\\n   \" adde   %2,%2,%5        \\n\\t\" \\\n   \" addc   %0,%0,%3        \\n\\t\" \\\n   \" adde   %1,%1,%4        \\n\\t\" \\\n   \" adde   %2,%2,%5        \\n\\t\" \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2) : \"r\"(sc0), \"r\"(sc1), \"r\"(sc2), \"0\"(c0), \"1\"(c1), \"2\"(c2) : \"cc\");\n\n#elif defined(TFM_PPC64)\n/* PPC64 */\n\n#define COMBA_START\n\n#define CLEAR_CARRY \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define CARRY_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_FINI\n\n/* multiplies point i and j, updates carry \"c1\" and digit c2 */\n#define SQRADD(i, j)              \\\n__asm__(                          \\\n   \" mulld  r16,%6,%6       \\n\\t\" \\\n   \" addc   %0,%0,r16       \\n\\t\" \\\n   \" mulhdu r16,%6,%6       \\n\\t\" \\\n   \" adde   %1,%1,r16       \\n\\t\" \\\n   \" addze  %2,%2           \\n\\t\" \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2):\"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i):\"r16\",\"cc\");\n\n/* for squaring some of the terms are doubled... */\n#define SQRADD2(i, j)             \\\n__asm__(                          \\\n   \" mulld  r16,%6,%7       \\n\\t\" \\\n   \" mulhdu r17,%6,%7       \\n\\t\" \\\n   \" addc   %0,%0,r16       \\n\\t\" \\\n   \" adde   %1,%1,r17       \\n\\t\" \\\n   \" addze  %2,%2           \\n\\t\" \\\n   \" addc   %0,%0,r16       \\n\\t\" \\\n   \" adde   %1,%1,r17       \\n\\t\" \\\n   \" addze  %2,%2           \\n\\t\" \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2):\"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i), \"r\"(j):\"r16\", \"r17\",\"cc\");\n\n#define SQRADDSC(i, j)            \\\n__asm__(                          \\\n   \" mulld  %0,%6,%7        \\n\\t\" \\\n   \" mulhdu %1,%6,%7        \\n\\t\" \\\n   \" xor    %2,%2,%2        \\n\\t\" \\\n:\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2):\"0\"(sc0), \"1\"(sc1), \"2\"(sc2), \"r\"(i),\"r\"(j) : \"cc\");\n\n#define SQRADDAC(i, j)            \\\n__asm__(                          \\\n   \" mulld  r16,%6,%7       \\n\\t\" \\\n   \" addc   %0,%0,r16       \\n\\t\" \\\n   \" mulhdu r16,%6,%7       \\n\\t\" \\\n   \" adde   %1,%1,r16       \\n\\t\" \\\n   \" addze  %2,%2           \\n\\t\" \\\n:\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2):\"0\"(sc0), \"1\"(sc1), \"2\"(sc2), \"r\"(i), \"r\"(j):\"r16\", \"cc\");\n\n#define SQRADDDB                  \\\n__asm__(                          \\\n   \" addc   %0,%0,%3        \\n\\t\" \\\n   \" adde   %1,%1,%4        \\n\\t\" \\\n   \" adde   %2,%2,%5        \\n\\t\" \\\n   \" addc   %0,%0,%3        \\n\\t\" \\\n   \" adde   %1,%1,%4        \\n\\t\" \\\n   \" adde   %2,%2,%5        \\n\\t\" \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2) : \"r\"(sc0), \"r\"(sc1), \"r\"(sc2), \"0\"(c0), \"1\"(c1), \"2\"(c2) : \"cc\");\n\n\n#elif defined(TFM_AVR32)\n\n/* AVR32 */\n\n#define COMBA_START\n\n#define CLEAR_CARRY \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define CARRY_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_FINI\n\n/* multiplies point i and j, updates carry \"c1\" and digit c2 */\n#define SQRADD(i, j)             \\\n__asm__(                         \\\n   \" mulu.d r2,%6,%6       \\n\\t\" \\\n   \" add    %0,%0,r2       \\n\\t\" \\\n   \" adc    %1,%1,r3       \\n\\t\" \\\n   \" acr    %2             \\n\\t\" \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2):\"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i):\"r2\",\"r3\");\n\n/* for squaring some of the terms are doubled... */\n#define SQRADD2(i, j)            \\\n__asm__(                         \\\n   \" mulu.d r2,%6,%7       \\n\\t\" \\\n   \" add    %0,%0,r2       \\n\\t\" \\\n   \" adc    %1,%1,r3       \\n\\t\" \\\n   \" acr    %2,            \\n\\t\" \\\n   \" add    %0,%0,r2       \\n\\t\" \\\n   \" adc    %1,%1,r3       \\n\\t\" \\\n   \" acr    %2,            \\n\\t\" \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2):\"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i), \"r\"(j):\"r2\", \"r3\");\n\n#define SQRADDSC(i, j)            \\\n__asm__(                          \\\n   \" mulu.d r2,%6,%7        \\n\\t\" \\\n   \" mov    %0,r2           \\n\\t\" \\\n   \" mov    %1,r3           \\n\\t\" \\\n   \" eor    %2,%2           \\n\\t\" \\\n:\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2):\"0\"(sc0), \"1\"(sc1), \"2\"(sc2), \"r\"(i),\"r\"(j) : \"r2\", \"r3\");\n\n#define SQRADDAC(i, j)           \\\n__asm__(                         \\\n   \" mulu.d r2,%6,%7       \\n\\t\" \\\n   \" add    %0,%0,r2       \\n\\t\" \\\n   \" adc    %1,%1,r3       \\n\\t\" \\\n   \" acr    %2             \\n\\t\" \\\n:\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2):\"0\"(sc0), \"1\"(sc1), \"2\"(sc2), \"r\"(i), \"r\"(j):\"r2\", \"r3\");\n\n#define SQRADDDB                  \\\n__asm__(                          \\\n   \" add    %0,%0,%3        \\n\\t\" \\\n   \" adc    %1,%1,%4        \\n\\t\" \\\n   \" adc    %2,%2,%5        \\n\\t\" \\\n   \" add    %0,%0,%3        \\n\\t\" \\\n   \" adc    %1,%1,%4        \\n\\t\" \\\n   \" adc    %2,%2,%5        \\n\\t\" \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2) : \"r\"(sc0), \"r\"(sc1), \"r\"(sc2), \"0\"(c0), \"1\"(c1), \"2\"(c2) : \"cc\");\n\n#elif defined(TFM_MIPS)\n\n/* MIPS */\n#define COMBA_START\n\n#define CLEAR_CARRY \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define CARRY_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_FINI\n\n/* multiplies point i and j, updates carry \"c1\" and digit c2 */\n#define SQRADD(i, j)              \\\n__asm__(                          \\\n   \" multu  %6,%6          \\n\\t\"  \\\n   \" mflo   $12            \\n\\t\"  \\\n   \" mfhi   $13            \\n\\t\"  \\\n   \" addu    %0,%0,$12     \\n\\t\"  \\\n   \" sltu   $12,%0,$12     \\n\\t\"  \\\n   \" addu    %1,%1,$13     \\n\\t\"  \\\n   \" sltu   $13,%1,$13     \\n\\t\"  \\\n   \" addu    %1,%1,$12     \\n\\t\"  \\\n   \" sltu   $12,%1,$12     \\n\\t\"  \\\n   \" addu    %2,%2,$13     \\n\\t\"  \\\n   \" addu    %2,%2,$12     \\n\\t\"  \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2):\"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i):\"$12\",\"$13\");\n\n/* for squaring some of the terms are doubled... */\n#define SQRADD2(i, j)            \\\n__asm__(                         \\\n   \" multu  %6,%7          \\n\\t\" \\\n   \" mflo   $12            \\n\\t\" \\\n   \" mfhi   $13            \\n\\t\" \\\n                                 \\\n   \" addu    %0,%0,$12     \\n\\t\" \\\n   \" sltu   $14,%0,$12     \\n\\t\" \\\n   \" addu    %1,%1,$13     \\n\\t\" \\\n   \" sltu   $15,%1,$13     \\n\\t\" \\\n   \" addu    %1,%1,$14     \\n\\t\" \\\n   \" sltu   $14,%1,$14     \\n\\t\" \\\n   \" addu    %2,%2,$15     \\n\\t\" \\\n   \" addu    %2,%2,$14     \\n\\t\" \\\n                                 \\\n   \" addu    %0,%0,$12     \\n\\t\" \\\n   \" sltu   $14,%0,$12     \\n\\t\" \\\n   \" addu    %1,%1,$13     \\n\\t\" \\\n   \" sltu   $15,%1,$13     \\n\\t\" \\\n   \" addu    %1,%1,$14     \\n\\t\" \\\n   \" sltu   $14,%1,$14     \\n\\t\" \\\n   \" addu    %2,%2,$15     \\n\\t\" \\\n   \" addu    %2,%2,$14     \\n\\t\" \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2):\"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i), \"r\"(j):\"$12\", \"$13\", \"$14\", \"$15\");\n\n#define SQRADDSC(i, j)            \\\n__asm__(                          \\\n   \" multu  %6,%7          \\n\\t\"  \\\n   \" mflo   %0             \\n\\t\"  \\\n   \" mfhi   %1             \\n\\t\"  \\\n   \" xor    %2,%2,%2       \\n\\t\"  \\\n:\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2):\"0\"(sc0), \"1\"(sc1), \"2\"(sc2), \"r\"(i),\"r\"(j) : \"cc\");\n\n#define SQRADDAC(i, j)           \\\n__asm__(                         \\\n   \" multu  %6,%7          \\n\\t\" \\\n   \" mflo   $12            \\n\\t\" \\\n   \" mfhi   $13            \\n\\t\" \\\n   \" addu    %0,%0,$12     \\n\\t\" \\\n   \" sltu   $12,%0,$12     \\n\\t\" \\\n   \" addu    %1,%1,$13     \\n\\t\" \\\n   \" sltu   $13,%1,$13     \\n\\t\" \\\n   \" addu    %1,%1,$12     \\n\\t\" \\\n   \" sltu   $12,%1,$12     \\n\\t\" \\\n   \" addu    %2,%2,$13     \\n\\t\" \\\n   \" addu    %2,%2,$12     \\n\\t\" \\\n:\"=r\"(sc0), \"=r\"(sc1), \"=r\"(sc2):\"0\"(sc0), \"1\"(sc1), \"2\"(sc2), \"r\"(i), \"r\"(j):\"$12\", \"$13\", \"$14\");\n\n#define SQRADDDB                  \\\n__asm__(                          \\\n   \" addu    %0,%0,%3       \\n\\t\" \\\n   \" sltu   $10,%0,%3       \\n\\t\" \\\n   \" addu    %1,%1,$10      \\n\\t\" \\\n   \" sltu   $10,%1,$10      \\n\\t\" \\\n   \" addu    %1,%1,%4       \\n\\t\" \\\n   \" sltu   $11,%1,%4       \\n\\t\" \\\n   \" addu    %2,%2,$10      \\n\\t\" \\\n   \" addu    %2,%2,$11      \\n\\t\" \\\n   \" addu    %2,%2,%5       \\n\\t\" \\\n                                  \\\n   \" addu    %0,%0,%3       \\n\\t\" \\\n   \" sltu   $10,%0,%3       \\n\\t\" \\\n   \" addu    %1,%1,$10      \\n\\t\" \\\n   \" sltu   $10,%1,$10      \\n\\t\" \\\n   \" addu    %1,%1,%4       \\n\\t\" \\\n   \" sltu   $11,%1,%4       \\n\\t\" \\\n   \" addu    %2,%2,$10      \\n\\t\" \\\n   \" addu    %2,%2,$11      \\n\\t\" \\\n   \" addu    %2,%2,%5       \\n\\t\" \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2) : \"r\"(sc0), \"r\"(sc1), \"r\"(sc2), \"0\"(c0), \"1\"(c1), \"2\"(c2) : \"$10\", \"$11\");\n\n#else\n\n#define TFM_ISO\n\n/* ISO C portable code */\n\n#define COMBA_START\n\n#define CLEAR_CARRY \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define CARRY_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_FINI\n\n/* multiplies point i and j, updates carry \"c1\" and digit c2 */\n#define SQRADD(i, j)                                 \\\n   do { fp_word t;                                   \\\n   t = c0 + ((fp_word)i) * ((fp_word)j);  c0 = (fp_digit)t;    \\\n   t = c1 + (t >> DIGIT_BIT);             c1 = (fp_digit)t;    \\\n                                          c2 +=(fp_digit) (t >> DIGIT_BIT); \\\n   } while (0);\n\n\n/* for squaring some of the terms are doubled... */\n#define SQRADD2(i, j)                                                 \\\n   do { fp_word t;                                                    \\\n   t  = ((fp_word)i) * ((fp_word)j);                                  \\\n   tt = (fp_word)c0 + t;                 c0 = (fp_digit)tt;           \\\n   tt = (fp_word)c1 + (tt >> DIGIT_BIT); c1 = (fp_digit)tt;           \\\n                                         c2 +=(fp_digit)(tt >> DIGIT_BIT);     \\\n   tt = (fp_word)c0 + t;                 c0 = (fp_digit)tt;                    \\\n   tt = (fp_word)c1 + (tt >> DIGIT_BIT); c1 = (fp_digit)tt;            \\\n                                         c2 +=(fp_digit)(tt >> DIGIT_BIT);     \\\n   } while (0);\n\n#define SQRADDSC(i, j)                                                         \\\n   do { fp_word t;                                                             \\\n      t =  ((fp_word)i) * ((fp_word)j);                                        \\\n      sc0 = (fp_digit)t; sc1 = (t >> DIGIT_BIT); sc2 = 0;                      \\\n   } while (0);\n\n#define SQRADDAC(i, j)                                                         \\\n   do { fp_word t;                                                             \\\n   t = sc0 + ((fp_word)i) * ((fp_word)j);  sc0 =  (fp_digit)t;                 \\\n   t = sc1 + (t >> DIGIT_BIT);             sc1 =  (fp_digit)t;                 \\\n                                           sc2 += (fp_digit)(t >> DIGIT_BIT);  \\\n   } while (0);\n\n#define SQRADDDB                                                               \\\n   do { fp_word t;                                                             \\\n   t = ((fp_word)sc0) + ((fp_word)sc0) + c0; c0 = (fp_digit)t;                 \\\n   t = ((fp_word)sc1) + ((fp_word)sc1) + c1 + (t >> DIGIT_BIT);                \\\n                                             c1 = (fp_digit)t;                 \\\n   c2 = c2 + (fp_digit)(((fp_word)sc2) + ((fp_word)sc2) + (t >> DIGIT_BIT));   \\\n   } while (0);\n\n#endif\n\n#ifdef TFM_SMALL_SET\n    #include \"fp_sqr_comba_small_set.i\"\n#endif\n\n#if defined(TFM_SQR3) && FP_SIZE >= 6\n    #include \"fp_sqr_comba_3.i\"\n#endif\n#if defined(TFM_SQR4) && FP_SIZE >= 8\n    #include \"fp_sqr_comba_4.i\"\n#endif\n#if defined(TFM_SQR6) && FP_SIZE >= 12\n    #include \"fp_sqr_comba_6.i\"\n#endif\n#if defined(TFM_SQR7) && FP_SIZE >= 14\n    #include \"fp_sqr_comba_7.i\"\n#endif\n#if defined(TFM_SQR8) && FP_SIZE >= 16\n    #include \"fp_sqr_comba_8.i\"\n#endif\n#if defined(TFM_SQR9) && FP_SIZE >= 18\n    #include \"fp_sqr_comba_9.i\"\n#endif\n#if defined(TFM_SQR12) && FP_SIZE >= 24\n    #include \"fp_sqr_comba_12.i\"\n#endif\n#if defined(TFM_SQR17) && FP_SIZE >= 34\n    #include \"fp_sqr_comba_17.i\"\n#endif\n#if defined(TFM_SQR20) && FP_SIZE >= 40\n    #include \"fp_sqr_comba_20.i\"\n#endif\n#if defined(TFM_SQR24) && FP_SIZE >= 48\n    #include \"fp_sqr_comba_24.i\"\n#endif\n#if defined(TFM_SQR28) && FP_SIZE >= 56\n    #include \"fp_sqr_comba_28.i\"\n#endif\n#if defined(TFM_SQR32) && FP_SIZE >= 64\n    #include \"fp_sqr_comba_32.i\"\n#endif\n#if defined(TFM_SQR48) && FP_SIZE >= 96\n    #include \"fp_sqr_comba_48.i\"\n#endif\n#if defined(TFM_SQR64) && FP_SIZE >= 128\n    #include \"fp_sqr_comba_64.i\"\n#endif\n/* end fp_sqr_comba.c asm */\n\n/* start fp_mul_comba.c asm */\n/* these are the combas.  Worship them. */\n#if defined(TFM_X86)\n/* Generic x86 optimized code */\n\n/* anything you need at the start */\n#define COMBA_START\n\n/* clear the chaining variables */\n#define COMBA_CLEAR \\\n   c0 = c1 = c2 = 0;\n\n/* forward the carry to the next digit */\n#define COMBA_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n/* store the first sum */\n#define COMBA_STORE(x) \\\n   x = c0;\n\n/* store the second sum [carry] */\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n/* anything you need at the end */\n#define COMBA_FINI\n\n/* this should multiply i and j  */\n#define MULADD(i, j)                                      \\\n__asm__(                                                  \\\n     \"movl  %6,%%eax     \\n\\t\"                            \\\n     \"mull  %7           \\n\\t\"                            \\\n     \"addl  %%eax,%0     \\n\\t\"                            \\\n     \"adcl  %%edx,%1     \\n\\t\"                            \\\n     \"adcl  $0,%2        \\n\\t\"                            \\\n     :\"=r\"(c0), \"=r\"(c1), \"=r\"(c2): \"0\"(c0), \"1\"(c1), \"2\"(c2), \"m\"(i), \"m\"(j)  :\"%eax\",\"%edx\",\"cc\");\n\n#elif defined(TFM_X86_64)\n/* x86-64 optimized */\n\n/* anything you need at the start */\n#define COMBA_START\n\n/* clear the chaining variables */\n#define COMBA_CLEAR \\\n   c0 = c1 = c2 = 0;\n\n/* forward the carry to the next digit */\n#define COMBA_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n/* store the first sum */\n#define COMBA_STORE(x) \\\n   x = c0;\n\n/* store the second sum [carry] */\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n/* anything you need at the end */\n#define COMBA_FINI\n\n/* this should multiply i and j  */\n#define MULADD(i, j)                                      \\\n__asm__  (                                                \\\n     \"movq  %6,%%rax     \\n\\t\"                            \\\n     \"mulq  %7           \\n\\t\"                            \\\n     \"addq  %%rax,%0     \\n\\t\"                            \\\n     \"adcq  %%rdx,%1     \\n\\t\"                            \\\n     \"adcq  $0,%2        \\n\\t\"                            \\\n     :\"=r\"(c0), \"=r\"(c1), \"=r\"(c2): \"0\"(c0), \"1\"(c1), \"2\"(c2), \"g\"(i), \"g\"(j)  :\"%rax\",\"%rdx\",\"cc\");\n\n\n#if defined(HAVE_INTEL_MULX)\n#define MULADD_BODY(a,b,c)                              \\\n    __asm__ volatile(                                   \\\n         \"movq  %[a0],%%rdx\\n\\t\"                        \\\n         \"xorq  %%rcx, %%rcx\\n\\t\"                       \\\n         \"movq  0(%[cp]),%%r8\\n\\t\"                      \\\n         \"movq  8(%[cp]),%%r9\\n\\t\"                      \\\n         \"movq  16(%[cp]),%%r10\\n\\t\"                    \\\n         \"movq  24(%[cp]),%%r11\\n\\t\"                    \\\n         \"movq  32(%[cp]),%%r12\\n\\t\"                    \\\n         \"movq  40(%[cp]),%%r13\\n\\t\"                    \\\n                                                        \\\n         \"mulx  (%[bp]),%%rax, %%rbx\\n\\t\"               \\\n         \"adoxq  %%rax, %%r8\\n\\t\"                       \\\n         \"mulx  8(%[bp]),%%rax, %%rcx\\n\\t\"              \\\n         \"adcxq  %%rbx, %%r9\\n\\t\"                       \\\n         \"adoxq  %%rax, %%r9\\n\\t\"                       \\\n         \"mulx  16(%[bp]),%%rax, %%rbx\\n\\t\"             \\\n         \"adcxq  %%rcx, %%r10\\n\\t\"                      \\\n         \"adoxq  %%rax, %%r10\\n\\t\"                      \\\n         \"mulx  24(%[bp]),%%rax, %%rcx\\n\\t\"             \\\n         \"adcxq  %%rbx, %%r11\\n\\t\"                      \\\n         \"adoxq  %%rax, %%r11\\n\\t\"                      \\\n         \"adcxq  %%rcx, %%r12\\n\\t\"                      \\\n         \"mov $0, %%rdx\\n\\t\"                            \\\n         \"adox %%rdx, %%r12\\n\\t\"                        \\\n         \"adcx %%rdx, %%r13\\n\\t\"                        \\\n                                                        \\\n         \"movq  %%r8, 0(%[cp])\\n\\t\"                     \\\n         \"movq  %%r9, 8(%[cp])\\n\\t\"                     \\\n         \"movq  %%r10, 16(%[cp])\\n\\t\"                   \\\n         \"movq  %%r11, 24(%[cp])\\n\\t\"                   \\\n         \"movq  %%r12, 32(%[cp])\\n\\t\"                   \\\n         \"movq  %%r13, 40(%[cp])\\n\\t\"                   \\\n      :                                                 \\\n      : [a0] \"r\" (a->dp[ix]), [bp] \"r\" (&(b->dp[iy])),  \\\n        [cp] \"r\" (&(c->dp[iz]))                         \\\n      : \"%r8\", \"%r9\", \"%r10\", \"%r11\", \"%r12\", \"%r13\",   \\\n        \"%rdx\", \"%rax\", \"%rcx\", \"%rbx\"                  \\\n    )\n\n#define TFM_INTEL_MUL_COMBA(a, b, c)       \\\n    for (iz=0; iz<pa; iz++) c->dp[iz] = 0; \\\n    for (ix=0; ix<a->used; ix++) {         \\\n        for (iy=0; iy<b->used; iy+=4) {    \\\n            iz = ix + iy;                  \\\n            MULADD_BODY(a, b, c);          \\\n        }                                  \\\n    }\n#endif\n\n#elif defined(TFM_SSE2)\n/* use SSE2 optimizations */\n\n/* anything you need at the start */\n#define COMBA_START\n\n/* clear the chaining variables */\n#define COMBA_CLEAR \\\n   c0 = c1 = c2 = 0;\n\n/* forward the carry to the next digit */\n#define COMBA_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n/* store the first sum */\n#define COMBA_STORE(x) \\\n   x = c0;\n\n/* store the second sum [carry] */\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n/* anything you need at the end */\n#define COMBA_FINI \\\n   __asm__(\"emms\");\n\n/* this should multiply i and j  */\n#define MULADD(i, j)                                     \\\n__asm__(                                                 \\\n    \"movd  %6,%%mm0     \\n\\t\"                            \\\n    \"movd  %7,%%mm1     \\n\\t\"                            \\\n    \"pmuludq %%mm1,%%mm0\\n\\t\"                            \\\n    \"movd  %%mm0,%%eax  \\n\\t\"                            \\\n    \"psrlq $32,%%mm0    \\n\\t\"                            \\\n    \"addl  %%eax,%0     \\n\\t\"                            \\\n    \"movd  %%mm0,%%eax  \\n\\t\"                            \\\n    \"adcl  %%eax,%1     \\n\\t\"                            \\\n    \"adcl  $0,%2        \\n\\t\"                            \\\n    :\"=r\"(c0), \"=r\"(c1), \"=r\"(c2): \"0\"(c0), \"1\"(c1), \"2\"(c2), \"m\"(i), \"m\"(j)  :\"%eax\",\"cc\");\n\n#elif defined(TFM_ARM)\n/* ARM code */\n\n#define COMBA_START\n\n#define COMBA_CLEAR \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define COMBA_FINI\n\n#define MULADD(i, j)                                          \\\n__asm__(                                                      \\\n\"  UMULL  r0,r1,%6,%7           \\n\\t\"                         \\\n\"  ADDS   %0,%0,r0              \\n\\t\"                         \\\n\"  ADCS   %1,%1,r1              \\n\\t\"                         \\\n\"  ADC    %2,%2,#0              \\n\\t\"                         \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2) : \"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i), \"r\"(j) : \"r0\", \"r1\", \"cc\");\n\n#elif defined(TFM_PPC32)\n/* For 32-bit PPC */\n\n#define COMBA_START\n\n#define COMBA_CLEAR \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define COMBA_FINI\n\n/* untested: will mulhwu change the flags?  Docs say no */\n#define MULADD(i, j)             \\\n__asm__(                         \\\n   \" mullw  16,%6,%7       \\n\\t\" \\\n   \" addc   %0,%0,16       \\n\\t\" \\\n   \" mulhwu 16,%6,%7       \\n\\t\" \\\n   \" adde   %1,%1,16       \\n\\t\" \\\n   \" addze  %2,%2          \\n\\t\" \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2):\"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i), \"r\"(j):\"16\");\n\n#elif defined(TFM_PPC64)\n/* For 64-bit PPC */\n\n#define COMBA_START\n\n#define COMBA_CLEAR \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define COMBA_FINI\n\n/* untested: will mulhdu change the flags?  Docs say no */\n#define MULADD(i, j)              \\\n____asm__(                        \\\n   \" mulld  r16,%6,%7       \\n\\t\" \\\n   \" addc   %0,%0,16        \\n\\t\" \\\n   \" mulhdu r16,%6,%7       \\n\\t\" \\\n   \" adde   %1,%1,16        \\n\\t\" \\\n   \" addze  %2,%2           \\n\\t\" \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2):\"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i), \"r\"(j):\"r16\");\n\n#elif defined(TFM_AVR32)\n\n/* ISO C code */\n\n#define COMBA_START\n\n#define COMBA_CLEAR \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define COMBA_FINI\n\n#define MULADD(i, j)             \\\n____asm__(                       \\\n   \" mulu.d r2,%6,%7        \\n\\t\"\\\n   \" add    %0,r2           \\n\\t\"\\\n   \" adc    %1,%1,r3        \\n\\t\"\\\n   \" acr    %2              \\n\\t\"\\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2):\"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i), \"r\"(j):\"r2\",\"r3\");\n\n#elif defined(TFM_MIPS)\n\n/* MIPS */\n#define COMBA_START\n\n#define COMBA_CLEAR \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define COMBA_FINI\n\n#define MULADD(i, j)              \\\n__asm__(                          \\\n   \" multu  %6,%7          \\n\\t\"  \\\n   \" mflo   $12            \\n\\t\"  \\\n   \" mfhi   $13            \\n\\t\"  \\\n   \" addu    %0,%0,$12     \\n\\t\"  \\\n   \" sltu   $12,%0,$12     \\n\\t\"  \\\n   \" addu    %1,%1,$13     \\n\\t\"  \\\n   \" sltu   $13,%1,$13     \\n\\t\"  \\\n   \" addu    %1,%1,$12     \\n\\t\"  \\\n   \" sltu   $12,%1,$12     \\n\\t\"  \\\n   \" addu    %2,%2,$13     \\n\\t\"  \\\n   \" addu    %2,%2,$12     \\n\\t\"  \\\n:\"=r\"(c0), \"=r\"(c1), \"=r\"(c2):\"0\"(c0), \"1\"(c1), \"2\"(c2), \"r\"(i), \"r\"(j):\"$12\",\"$13\");\n\n#else\n/* ISO C code */\n\n#define COMBA_START\n\n#define COMBA_CLEAR \\\n   c0 = c1 = c2 = 0;\n\n#define COMBA_FORWARD \\\n   do { c0 = c1; c1 = c2; c2 = 0; } while (0);\n\n#define COMBA_STORE(x) \\\n   x = c0;\n\n#define COMBA_STORE2(x) \\\n   x = c1;\n\n#define COMBA_FINI\n\n#define MULADD(i, j)                                                                                                                                  \\\n   do { fp_word t;                                      \\\n   t = (fp_word)c0 + ((fp_word)i) * ((fp_word)j);       \\\n   c0 = (fp_digit)t;                                    \\\n   t = (fp_word)c1 + (t >> DIGIT_BIT);                  \\\n   c1 = (fp_digit)t;                                    \\\n   c2 += (fp_digit)(t >> DIGIT_BIT);                    \\\n   } while (0);\n\n#endif\n\n\n#ifdef TFM_SMALL_SET\n    #include \"fp_mul_comba_small_set.i\"\n#endif\n\n#if defined(TFM_MUL3) && FP_SIZE >= 6\n    #include \"fp_mul_comba_3.i\"\n#endif\n#if defined(TFM_MUL4) && FP_SIZE >= 8\n    #include \"fp_mul_comba_4.i\"\n#endif\n#if defined(TFM_MUL6) && FP_SIZE >= 12\n    #include \"fp_mul_comba_6.i\"\n#endif\n#if defined(TFM_MUL7) && FP_SIZE >= 14\n    #include \"fp_mul_comba_7.i\"\n#endif\n#if defined(TFM_MUL8) && FP_SIZE >= 16\n    #include \"fp_mul_comba_8.i\"\n#endif\n#if defined(TFM_MUL9) && FP_SIZE >= 18\n    #include \"fp_mul_comba_9.i\"\n#endif\n#if defined(TFM_MUL12) && FP_SIZE >= 24\n    #include \"fp_mul_comba_12.i\"\n#endif\n#if defined(TFM_MUL17) && FP_SIZE >= 34\n    #include \"fp_mul_comba_17.i\"\n#endif\n#if defined(TFM_MUL20) && FP_SIZE >= 40\n    #include \"fp_mul_comba_20.i\"\n#endif\n#if defined(TFM_MUL24) && FP_SIZE >= 48\n    #include \"fp_mul_comba_24.i\"\n#endif\n#if defined(TFM_MUL28) && FP_SIZE >= 56\n    #include \"fp_mul_comba_28.i\"\n#endif\n#if defined(TFM_MUL32) && FP_SIZE >= 64\n    #include \"fp_mul_comba_32.i\"\n#endif\n#if defined(TFM_MUL48) && FP_SIZE >= 96\n    #include \"fp_mul_comba_48.i\"\n#endif\n#if defined(TFM_MUL64) && FP_SIZE >= 128\n    #include \"fp_mul_comba_64.i\"\n#endif\n\n/* end fp_mul_comba.c asm */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/asn.c",
    "content": "/* asn.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n/*\nASN Options:\n * NO_ASN_TIME: Disables time parts of the ASN code for systems without an RTC\n    or wishing to save space.\n * IGNORE_NAME_CONSTRAINTS: Skip ASN name checks.\n * ASN_DUMP_OID: Allows dump of OID information for debugging.\n * RSA_DECODE_EXTRA: Decodes extra information in RSA public key.\n * WOLFSSL_CERT_GEN: Cert generation. Saves extra certificate info in GetName.\n * WOLFSSL_NO_ASN_STRICT: Disable strict RFC compliance checks to\n    restore 3.13.0 behavior.\n * WOLFSSL_NO_OCSP_OPTIONAL_CERTS: Skip optional OCSP certs (responder issuer\n    must still be trusted)\n * WOLFSSL_NO_TRUSTED_CERTS_VERIFY: Workaround for situation where entire cert\n    chain is not loaded. This only matches on subject and public key and\n    does not perform a PKI validation, so it is not a secure solution.\n    Only enabled for OCSP.\n * WOLFSSL_NO_OCSP_ISSUER_CHECK: Can be defined for backwards compatibility to\n    disable checking of OCSP subject hash with issuer hash.\n * WOLFSSL_SMALL_CERT_VERIFY: Verify the certificate signature without using\n    DecodedCert. Doubles up on some code but allows smaller dynamic memory\n    usage.\n * WOLFSSL_NO_OCSP_DATE_CHECK: Disable date checks for OCSP responses. This\n    may be required when the system's real-time clock is not very accurate.\n    It is recommended to enforce the nonce check instead if possible.\n * WOLFSSL_FORCE_OCSP_NONCE_CHECK: Require nonces to be available in OCSP\n    responses. The nonces are optional and may not be supported by all\n    responders. If it can be ensured that the used responder sends nonces this\n    option may improve security.\n*/\n\n#ifndef NO_ASN\n\n#include <wolfssl/wolfcrypt/asn.h>\n#include <wolfssl/wolfcrypt/coding.h>\n#include <wolfssl/wolfcrypt/md2.h>\n#include <wolfssl/wolfcrypt/hmac.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/pwdbased.h>\n#include <wolfssl/wolfcrypt/des3.h>\n#include <wolfssl/wolfcrypt/aes.h>\n#include <wolfssl/wolfcrypt/wc_encrypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n\n#include <wolfssl/wolfcrypt/random.h>\n#include <wolfssl/wolfcrypt/hash.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#ifndef NO_PWDBASED\n    #include <wolfssl/wolfcrypt/aes.h>\n#endif\n#ifndef NO_RC4\n    #include <wolfssl/wolfcrypt/arc4.h>\n#endif\n\n#ifdef HAVE_NTRU\n    #include \"libntruencrypt/ntru_crypto.h\"\n#endif\n\n#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)\n    #include <wolfssl/wolfcrypt/sha512.h>\n#endif\n\n#ifndef NO_SHA256\n    #include <wolfssl/wolfcrypt/sha256.h>\n#endif\n\n#ifdef HAVE_ECC\n    #include <wolfssl/wolfcrypt/ecc.h>\n#endif\n\n#ifdef HAVE_ED25519\n    #include <wolfssl/wolfcrypt/ed25519.h>\n#endif\n\n#ifndef NO_RSA\n    #include <wolfssl/wolfcrypt/rsa.h>\n#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)\nextern int wc_InitRsaHw(RsaKey* key);\n#endif\n#endif\n\n#ifdef WOLF_CRYPTO_CB\n    #include <wolfssl/wolfcrypt/cryptocb.h>\n#endif\n\n#ifdef _MSC_VER\n    /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */\n    #pragma warning(disable: 4996)\n#endif\n\n#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }\n\n#ifdef HAVE_SELFTEST\n    #ifndef WOLFSSL_AES_KEY_SIZE_ENUM\n    enum Asn_Misc {\n        AES_IV_SIZE         = 16,\n        AES_128_KEY_SIZE    = 16,\n        AES_192_KEY_SIZE    = 24,\n        AES_256_KEY_SIZE    = 32\n    };\n    #endif\n#endif\n#ifdef WOLFSSL_RENESAS_TSIP_TLS\nWOLFSSL_LOCAL void tsip_inform_key_position(const word32 key_n_start,\n                const word32 key_n_len, const word32 key_e_start,\n                const word32 key_e_len);\nWOLFSSL_LOCAL int tsip_tls_CertVerify(const byte *cert, word32 certSz,\n                        const byte *signature, word32 sigSz,\n                        word32 key_n_start, word32 key_n_len,\n                        word32 key_e_start, word32 key_e_len,\n                        byte *tsip_encRsaKeyIdx);\n#endif\nWOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,\n                           word32 maxIdx)\n{\n    return GetLength_ex(input, inOutIdx, len, maxIdx, 1);\n}\n\n\n/* give option to check length value found against index. 1 to check 0 to not */\nWOLFSSL_LOCAL int GetLength_ex(const byte* input, word32* inOutIdx, int* len,\n                           word32 maxIdx, int check)\n{\n    int     length = 0;\n    word32  idx = *inOutIdx;\n    byte    b;\n\n    *len = 0;    /* default length */\n\n    if ((idx + 1) > maxIdx) {   /* for first read */\n        WOLFSSL_MSG(\"GetLength bad index on input\");\n        return BUFFER_E;\n    }\n\n    b = input[idx++];\n    if (b >= ASN_LONG_LENGTH) {\n        word32 bytes = b & 0x7F;\n\n        if ((idx + bytes) > maxIdx) {   /* for reading bytes */\n            WOLFSSL_MSG(\"GetLength bad long length\");\n            return BUFFER_E;\n        }\n\n        if (bytes > sizeof(length)) {\n            return ASN_PARSE_E;\n        }\n        while (bytes--) {\n            b = input[idx++];\n            length = (length << 8) | b;\n        }\n        if (length < 0) {\n            return ASN_PARSE_E;\n        }\n    }\n    else\n        length = b;\n\n    if (check && (idx + length) > maxIdx) {   /* for user of length */\n        WOLFSSL_MSG(\"GetLength value exceeds buffer length\");\n        return BUFFER_E;\n    }\n\n    *inOutIdx = idx;\n    if (length > 0)\n        *len = length;\n\n    return length;\n}\n\n\n/* input : buffer to read from\n * inOutIdx : index to start reading from, gets advanced by 1 if successful\n * maxIdx : maximum index value\n * tag : ASN tag value found\n *\n * returns 0 on success\n */\nint GetASNTag(const byte* input, word32* inOutIdx, byte* tag, word32 maxIdx)\n{\n    word32 idx;\n\n    if (tag == NULL || inOutIdx == NULL || input == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    idx = *inOutIdx;\n    if (idx + ASN_TAG_SZ > maxIdx) {\n        WOLFSSL_MSG(\"Buffer too small for ASN tag\");\n        return BUFFER_E;\n    }\n\n    *tag = input[idx];\n    *inOutIdx = idx + ASN_TAG_SZ;\n    return 0;\n}\n\n\nstatic int GetASNHeader_ex(const byte* input, byte tag, word32* inOutIdx, int* len,\n                        word32 maxIdx, int check)\n{\n    word32 idx = *inOutIdx;\n    byte   tagFound;\n    int    length;\n\n    if (GetASNTag(input, &idx, &tagFound, maxIdx) != 0)\n        return ASN_PARSE_E;\n\n    if (tagFound != tag)\n        return ASN_PARSE_E;\n\n    if (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)\n        return ASN_PARSE_E;\n\n    *len      = length;\n    *inOutIdx = idx;\n    return length;\n}\n\n\n/* Get the DER/BER encoding of an ASN.1 header.\n *\n * input     Buffer holding DER/BER encoded data.\n * tag       ASN.1 tag value expected in header.\n * inOutIdx  Current index into buffer to parse.\n * len       The number of bytes in the ASN.1 data.\n * maxIdx    Length of data in buffer.\n * returns BUFFER_E when there is not enough data to parse.\n *         ASN_PARSE_E when the expected tag is not found or length is invalid.\n *         Otherwise, the number of bytes in the ASN.1 data.\n */\nstatic int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len,\n                        word32 maxIdx)\n{\n    return GetASNHeader_ex(input, tag, inOutIdx, len, maxIdx, 1);\n}\n\nstatic int GetHeader(const byte* input, byte* tag, word32* inOutIdx, int* len,\n                     word32 maxIdx, int check)\n{\n    word32 idx = *inOutIdx;\n    int    length;\n\n    if ((idx + 1) > maxIdx)\n        return BUFFER_E;\n\n    *tag = input[idx++];\n\n    if (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)\n        return ASN_PARSE_E;\n\n    *len      = length;\n    *inOutIdx = idx;\n    return length;\n}\n\nWOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,\n                           word32 maxIdx)\n{\n    return GetASNHeader(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,\n                        maxIdx);\n}\n\n\nWOLFSSL_LOCAL int GetSequence_ex(const byte* input, word32* inOutIdx, int* len,\n                           word32 maxIdx, int check)\n{\n    return GetASNHeader_ex(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,\n                        maxIdx, check);\n}\n\n\nWOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,\n                        word32 maxIdx)\n{\n    return GetASNHeader(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,\n                        maxIdx);\n}\n\n\nWOLFSSL_LOCAL int GetSet_ex(const byte* input, word32* inOutIdx, int* len,\n                        word32 maxIdx, int check)\n{\n    return GetASNHeader_ex(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,\n                        maxIdx, check);\n}\n\n/* Get the DER/BER encoded ASN.1 NULL element.\n * Ensure that the all fields are as expected and move index past the element.\n *\n * input     Buffer holding DER/BER encoded data.\n * inOutIdx  Current index into buffer to parse.\n * maxIdx    Length of data in buffer.\n * returns BUFFER_E when there is not enough data to parse.\n *         ASN_TAG_NULL_E when the NULL tag is not found.\n *         ASN_EXPECT_0_E when the length is not zero.\n *         Otherwise, 0 to indicate success.\n */\nstatic int GetASNNull(const byte* input, word32* inOutIdx, word32 maxIdx)\n{\n    word32 idx = *inOutIdx;\n    byte   b;\n\n    if ((idx + 2) > maxIdx)\n        return BUFFER_E;\n\n    b = input[idx++];\n    if (b != ASN_TAG_NULL)\n        return ASN_TAG_NULL_E;\n\n    if (input[idx++] != 0)\n        return ASN_EXPECT_0_E;\n\n    *inOutIdx = idx;\n    return 0;\n}\n\n/* Set the DER/BER encoding of the ASN.1 NULL element.\n *\n * output  Buffer to write into.\n * returns the number of bytes added to the buffer.\n */\nstatic int SetASNNull(byte* output)\n{\n    output[0] = ASN_TAG_NULL;\n    output[1] = 0;\n\n    return 2;\n}\n\n/* Get the DER/BER encoding of an ASN.1 BOOLEAN.\n *\n * input     Buffer holding DER/BER encoded data.\n * inOutIdx  Current index into buffer to parse.\n * maxIdx    Length of data in buffer.\n * returns BUFFER_E when there is not enough data to parse.\n *         ASN_PARSE_E when the BOOLEAN tag is not found or length is not 1.\n *         Otherwise, 0 to indicate the value was false and 1 to indicate true.\n */\nstatic int GetBoolean(const byte* input, word32* inOutIdx, word32 maxIdx)\n{\n    word32 idx = *inOutIdx;\n    byte   b;\n\n    if ((idx + 3) > maxIdx)\n        return BUFFER_E;\n\n    b = input[idx++];\n    if (b != ASN_BOOLEAN)\n        return ASN_PARSE_E;\n\n    if (input[idx++] != 1)\n        return ASN_PARSE_E;\n\n    b = input[idx++] != 0;\n\n    *inOutIdx = idx;\n    return b;\n}\n\n#ifdef ASN1_SET_BOOLEAN\n/* Set the DER/BER encoding of the ASN.1 NULL element.\n * Note: Function not required as yet.\n *\n * val     Boolean value to encode.\n * output  Buffer to write into.\n * returns the number of bytes added to the buffer.\n */\nstatic int SetBoolean(int val, byte* output)\n{\n    output[0] = ASN_BOOLEAN;\n    output[1] = 1;\n    output[2] = val ? -1 : 0;\n\n    return 3;\n}\n#endif\n\n/* Get the DER/BER encoding of an ASN.1 OCTET_STRING header.\n *\n * input     Buffer holding DER/BER encoded data.\n * inOutIdx  Current index into buffer to parse.\n * len       The number of bytes in the ASN.1 data.\n * maxIdx    Length of data in buffer.\n * returns BUFFER_E when there is not enough data to parse.\n *         ASN_PARSE_E when the OCTET_STRING tag is not found or length is\n *         invalid.\n *         Otherwise, the number of bytes in the ASN.1 data.\n */\nstatic int GetOctetString(const byte* input, word32* inOutIdx, int* len,\n                          word32 maxIdx)\n{\n    return GetASNHeader(input, ASN_OCTET_STRING, inOutIdx, len, maxIdx);\n}\n\n/* Get the DER/BER encoding of an ASN.1 INTEGER header.\n * Removes the leading zero byte when found.\n *\n * input     Buffer holding DER/BER encoded data.\n * inOutIdx  Current index into buffer to parse.\n * len       The number of bytes in the ASN.1 data (excluding any leading zero).\n * maxIdx    Length of data in buffer.\n * returns BUFFER_E when there is not enough data to parse.\n *         ASN_PARSE_E when the INTEGER tag is not found, length is invalid,\n *         or invalid use of or missing leading zero.\n *         Otherwise, 0 to indicate success.\n */\nstatic int GetASNInt(const byte* input, word32* inOutIdx, int* len,\n                     word32 maxIdx)\n{\n    int    ret;\n\n    ret = GetASNHeader(input, ASN_INTEGER, inOutIdx, len, maxIdx);\n    if (ret < 0)\n        return ret;\n\n    if (*len > 0) {\n        /* remove leading zero, unless there is only one 0x00 byte */\n        if ((input[*inOutIdx] == 0x00) && (*len > 1)) {\n            (*inOutIdx)++;\n            (*len)--;\n\n            if (*len > 0 && (input[*inOutIdx] & 0x80) == 0)\n                return ASN_PARSE_E;\n        }\n    }\n\n    return 0;\n}\n\n/* Get the DER/BER encoding of an ASN.1 INTEGER that has a value of no more than\n * 7 bits.\n *\n * input     Buffer holding DER/BER encoded data.\n * inOutIdx  Current index into buffer to parse.\n * maxIdx    Length of data in buffer.\n * returns BUFFER_E when there is not enough data to parse.\n *         ASN_PARSE_E when the INTEGER tag is not found or length is invalid.\n *         Otherwise, the 7-bit value.\n */\nstatic int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx)\n{\n    word32 idx = *inOutIdx;\n    byte   b;\n\n    if ((idx + 3) > maxIdx)\n        return BUFFER_E;\n\n    if (GetASNTag(input, &idx, &b, maxIdx) != 0)\n        return ASN_PARSE_E;\n    if (b != ASN_INTEGER)\n        return ASN_PARSE_E;\n    if (input[idx++] != 1)\n        return ASN_PARSE_E;\n    b = input[idx++];\n\n    *inOutIdx = idx;\n    return b;\n}\n\n\n#if !defined(NO_DSA) && !defined(NO_SHA)\nstatic char sigSha1wDsaName[] = \"SHAwDSA\";\n#endif /* NO_DSA */\n#ifndef NO_RSA\n#ifdef WOLFSSL_MD2\n    static char sigMd2wRsaName[] = \"MD2wRSA\";\n#endif\n#ifndef NO_MD5\n    static char sigMd5wRsaName[] = \"MD5wRSA\";\n#endif\n#ifndef NO_SHA\n    static char sigSha1wRsaName[] = \"SHAwRSA\";\n#endif\n#ifdef WOLFSSL_SHA224\n    static char sigSha224wRsaName[] = \"SHA224wRSA\";\n#endif\n#ifndef NO_SHA256\n    static char sigSha256wRsaName[] = \"SHA256wRSA\";\n#endif\n#ifdef WOLFSSL_SHA384\n    static char sigSha384wRsaName[] = \"SHA384wRSA\";\n#endif\n#ifdef WOLFSSL_SHA512\n    static char sigSha512wRsaName[] = \"SHA512wRSA\";\n#endif\n#endif /* NO_RSA */\n#ifdef HAVE_ECC\n#ifndef NO_SHA\n    static char sigSha1wEcdsaName[] = \"SHAwECDSA\";\n#endif\n#ifdef WOLFSSL_SHA224\n    static char sigSha224wEcdsaName[] = \"SHA224wECDSA\";\n#endif\n#ifndef NO_SHA256\n    static char sigSha256wEcdsaName[] = \"SHA256wECDSA\";\n#endif\n#ifdef WOLFSSL_SHA384\n    static char sigSha384wEcdsaName[] = \"SHA384wECDSA\";\n#endif\n#ifdef WOLFSSL_SHA512\n    static char sigSha512wEcdsaName[] = \"SHA512wECDSA\";\n#endif\n#endif /* HAVE_ECC */\nstatic char sigUnknownName[] = \"Unknown\";\n\n\n/* Get the human readable string for a signature type\n *\n * oid  Oid value for signature\n */\nchar* GetSigName(int oid) {\n    switch (oid) {\n    #if !defined(NO_DSA) && !defined(NO_SHA)\n        case CTC_SHAwDSA:\n            return sigSha1wDsaName;\n    #endif /* NO_DSA && NO_SHA */\n    #ifndef NO_RSA\n        #ifdef WOLFSSL_MD2\n        case CTC_MD2wRSA:\n            return sigMd2wRsaName;\n        #endif\n        #ifndef NO_MD5\n        case CTC_MD5wRSA:\n            return sigMd5wRsaName;\n        #endif\n        #ifndef NO_SHA\n        case CTC_SHAwRSA:\n            return sigSha1wRsaName;\n        #endif\n        #ifdef WOLFSSL_SHA224\n        case CTC_SHA224wRSA:\n            return sigSha224wRsaName;\n        #endif\n        #ifndef NO_SHA256\n        case CTC_SHA256wRSA:\n            return sigSha256wRsaName;\n        #endif\n        #ifdef WOLFSSL_SHA384\n        case CTC_SHA384wRSA:\n            return sigSha384wRsaName;\n        #endif\n        #ifdef WOLFSSL_SHA512\n        case CTC_SHA512wRSA:\n            return sigSha512wRsaName;\n        #endif\n    #endif /* NO_RSA */\n    #ifdef HAVE_ECC\n        #ifndef NO_SHA\n        case CTC_SHAwECDSA:\n            return sigSha1wEcdsaName;\n        #endif\n        #ifdef WOLFSSL_SHA224\n        case CTC_SHA224wECDSA:\n            return sigSha224wEcdsaName;\n        #endif\n        #ifndef NO_SHA256\n        case CTC_SHA256wECDSA:\n            return sigSha256wEcdsaName;\n        #endif\n        #ifdef WOLFSSL_SHA384\n        case CTC_SHA384wECDSA:\n            return sigSha384wEcdsaName;\n        #endif\n        #ifdef WOLFSSL_SHA512\n        case CTC_SHA512wECDSA:\n            return sigSha512wEcdsaName;\n        #endif\n    #endif /* HAVE_ECC */\n        default:\n            return sigUnknownName;\n    }\n}\n\n\n#if !defined(NO_DSA) || defined(HAVE_ECC) || !defined(NO_CERTS) || \\\n   (!defined(NO_RSA) && \\\n        (defined(WOLFSSL_CERT_GEN) || \\\n        ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA))))\n/* Set the DER/BER encoding of the ASN.1 INTEGER header.\n *\n * len        Length of data to encode.\n * firstByte  First byte of data, most significant byte of integer, to encode.\n * output     Buffer to write into.\n * returns the number of bytes added to the buffer.\n */\nstatic int SetASNInt(int len, byte firstByte, byte* output)\n{\n    word32 idx = 0;\n\n    if (output)\n        output[idx] = ASN_INTEGER;\n    idx++;\n    if (firstByte & 0x80)\n        len++;\n    idx += SetLength(len, output ? output + idx : NULL);\n    if (firstByte & 0x80) {\n        if (output)\n            output[idx] = 0x00;\n        idx++;\n    }\n\n    return idx;\n}\n#endif\n\n#if !defined(NO_DSA) || defined(HAVE_ECC) || defined(WOLFSSL_CERT_GEN) || \\\n    ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA))\n/* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int.\n * The number is assumed to be positive.\n *\n * n       Multi-precision integer to encode.\n * maxSz   Maximum size of the encoded integer.\n *         A negative value indicates no check of length requested.\n * output  Buffer to write into.\n * returns BUFFER_E when the data is too long for the buffer.\n *         MP_TO_E when encoding the integer fails.\n *         Otherwise, the number of bytes added to the buffer.\n */\nstatic int SetASNIntMP(mp_int* n, int maxSz, byte* output)\n{\n    int idx = 0;\n    int leadingBit;\n    int length;\n    int err;\n\n    leadingBit = mp_leading_bit(n);\n    length = mp_unsigned_bin_size(n);\n    idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);\n    if (maxSz >= 0 && (idx + length) > maxSz)\n        return BUFFER_E;\n\n    if (output) {\n        err = mp_to_unsigned_bin(n, output + idx);\n        if (err != MP_OKAY)\n            return MP_TO_E;\n    }\n    idx += length;\n\n    return idx;\n}\n#endif\n\n#if !defined(NO_RSA) && defined(HAVE_USER_RSA) && \\\n    (defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA))\n/* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int from\n * an RSA key.\n * The number is assumed to be positive.\n *\n * n       Multi-precision integer to encode.\n * output  Buffer to write into.\n * returns BUFFER_E when the data is too long for the buffer.\n *         MP_TO_E when encoding the integer fails.\n *         Otherwise, the number of bytes added to the buffer.\n */\nstatic int SetASNIntRSA(void* n, byte* output)\n{\n    int idx = 0;\n    int leadingBit;\n    int length;\n    int err;\n\n    leadingBit = wc_Rsa_leading_bit(n);\n    length = wc_Rsa_unsigned_bin_size(n);\n    idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);\n    if ((idx + length) > MAX_RSA_INT_SZ)\n        return BUFFER_E;\n\n    if (output) {\n        err = wc_Rsa_to_unsigned_bin(n, output + idx, length);\n        if (err != MP_OKAY)\n            return MP_TO_E;\n    }\n    idx += length;\n\n    return idx;\n}\n#endif /* !NO_RSA && HAVE_USER_RSA && WOLFSSL_CERT_GEN */\n\n/* Windows header clash for WinCE using GetVersion */\nWOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,\n                               int* version, word32 maxIdx)\n{\n    word32 idx = *inOutIdx;\n    byte   tag;\n\n    if ((idx + MIN_VERSION_SZ) > maxIdx)\n        return ASN_PARSE_E;\n\n    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)\n        return ASN_PARSE_E;\n\n    if (tag != ASN_INTEGER)\n        return ASN_PARSE_E;\n\n    if (input[idx++] != 0x01)\n        return ASN_VERSION_E;\n\n    *version  = input[idx++];\n    *inOutIdx = idx;\n\n    return *version;\n}\n\n\n#ifndef NO_PWDBASED\n/* Get small count integer, 32 bits or less */\nWOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx)\n{\n    word32 idx = *inOutIdx;\n    word32 len;\n    byte   tag;\n\n    *number = 0;\n\n    /* check for type and length bytes */\n    if ((idx + 2) > maxIdx)\n        return BUFFER_E;\n\n    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)\n        return ASN_PARSE_E;\n\n    if (tag != ASN_INTEGER)\n        return ASN_PARSE_E;\n\n    len = input[idx++];\n    if (len > 4)\n        return ASN_PARSE_E;\n\n    if (len + idx > maxIdx)\n        return ASN_PARSE_E;\n\n    while (len--) {\n        *number  = *number << 8 | input[idx++];\n    }\n\n    *inOutIdx = idx;\n\n    return *number;\n}\n\n\n/* Set small integer, 32 bits or less. DER encoding with no leading 0s\n * returns total amount written including ASN tag and length byte on success */\nWOLFSSL_LOCAL int SetShortInt(byte* input, word32* inOutIdx, word32 number, word32 maxIdx)\n{\n    word32 idx = *inOutIdx;\n    word32 len = 0;\n    int    i;\n    byte ar[MAX_LENGTH_SZ];\n\n    /* check for room for type and length bytes */\n    if ((idx + 2) > maxIdx)\n        return BUFFER_E;\n\n    input[idx++] = ASN_INTEGER;\n    idx++; /* place holder for length byte */\n    if (MAX_LENGTH_SZ + idx > maxIdx)\n        return ASN_PARSE_E;\n\n    /* find first non zero byte */\n    XMEMSET(ar, 0, MAX_LENGTH_SZ);\n    c32toa(number, ar);\n    for (i = 0; i < MAX_LENGTH_SZ; i++) {\n        if (ar[i] != 0) {\n            break;\n        }\n    }\n\n    /* handle case of 0 */\n    if (i == MAX_LENGTH_SZ) {\n        input[idx++] = 0; len++;\n    }\n\n    for (; i < MAX_LENGTH_SZ && idx < maxIdx; i++) {\n        input[idx++] = ar[i]; len++;\n    }\n\n    /* jump back to beginning of input buffer using unaltered inOutIdx value\n     * and set number of bytes for integer, then update the index value */\n    input[*inOutIdx + 1] = (byte)len;\n    *inOutIdx = idx;\n\n    return len + 2; /* size of integer bytes plus ASN TAG and length byte */\n}\n#endif /* !NO_PWDBASED */\n\n/* May not have one, not an error */\nstatic int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version,\n                              word32 maxIdx)\n{\n    word32 idx = *inOutIdx;\n    byte tag;\n\n    WOLFSSL_ENTER(\"GetExplicitVersion\");\n\n    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)\n        return ASN_PARSE_E;\n\n    if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {\n        *inOutIdx = ++idx;  /* skip header */\n        return GetMyVersion(input, inOutIdx, version, maxIdx);\n    }\n\n    /* go back as is */\n    *version = 0;\n\n    return 0;\n}\n\nint GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, word32 maxIdx)\n{\n    word32 idx = *inOutIdx;\n    int    ret;\n    int    length;\n\n    ret = GetASNInt(input, &idx, &length, maxIdx);\n    if (ret != 0)\n        return ret;\n\n    if (mp_init(mpi) != MP_OKAY)\n        return MP_INIT_E;\n\n    if (mp_read_unsigned_bin(mpi, (byte*)input + idx, length) != 0) {\n        mp_clear(mpi);\n        return ASN_GETINT_E;\n    }\n\n#ifdef HAVE_WOLF_BIGINT\n    if (wc_bigint_from_unsigned_bin(&mpi->raw, input + idx, length) != 0) {\n        mp_clear(mpi);\n        return ASN_GETINT_E;\n    }\n#endif /* HAVE_WOLF_BIGINT */\n\n    *inOutIdx = idx + length;\n\n    return 0;\n}\n\n#if (!defined(WOLFSSL_KEY_GEN) && !defined(OPENSSL_EXTRA) && defined(RSA_LOW_MEM)) \\\n    || defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)\nstatic int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)\n{\n    word32 idx = *inOutIdx;\n    int    ret;\n    int    length;\n\n    ret = GetASNInt(input, &idx, &length, maxIdx);\n    if (ret != 0)\n        return ret;\n\n    *inOutIdx = idx + length;\n\n    return 0;\n}\n#endif\n#endif\n\nstatic int CheckBitString(const byte* input, word32* inOutIdx, int* len,\n                          word32 maxIdx, int zeroBits, byte* unusedBits)\n{\n    word32 idx = *inOutIdx;\n    int    length;\n    byte   b;\n\n    if (GetASNTag(input, &idx, &b, maxIdx) != 0) {\n        return ASN_BITSTR_E;\n    }\n\n    if (b != ASN_BIT_STRING) {\n        return ASN_BITSTR_E;\n    }\n\n    if (GetLength(input, &idx, &length, maxIdx) < 0)\n        return ASN_PARSE_E;\n\n    /* extra sanity check that length is greater than 0 */\n    if (length <= 0) {\n        WOLFSSL_MSG(\"Error length was 0 in CheckBitString\");\n        return BUFFER_E;\n    }\n\n    if (idx + 1 > maxIdx) {\n        WOLFSSL_MSG(\"Attempted buffer read larger than input buffer\");\n        return BUFFER_E;\n    }\n\n    b = input[idx];\n    if (zeroBits && b != 0x00)\n        return ASN_EXPECT_0_E;\n    if (b >= 0x08)\n        return ASN_PARSE_E;\n    if (b != 0) {\n        if ((byte)(input[idx + length - 1] << (8 - b)) != 0)\n            return ASN_PARSE_E;\n    }\n    idx++;\n    length--; /* length has been checked for greater than 0 */\n\n    *inOutIdx = idx;\n    if (len != NULL)\n        *len = length;\n    if (unusedBits != NULL)\n        *unusedBits = b;\n\n    return 0;\n}\n\n/* RSA (with CertGen or KeyGen) OR ECC OR ED25519 (with CertGen or KeyGen) */\n#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && \\\n        (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))) || \\\n    (defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)) || \\\n    (defined(HAVE_ED25519) && \\\n        (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)))\n\n/* Set the DER/BER encoding of the ASN.1 BIT_STRING header.\n *\n * len         Length of data to encode.\n * unusedBits  The number of unused bits in the last byte of data.\n *             That is, the number of least significant zero bits before a one.\n *             The last byte is the most-significant non-zero byte of a number.\n * output      Buffer to write into.\n * returns the number of bytes added to the buffer.\n */\nstatic word32 SetBitString(word32 len, byte unusedBits, byte* output)\n{\n    word32 idx = 0;\n\n    if (output)\n        output[idx] = ASN_BIT_STRING;\n    idx++;\n\n    idx += SetLength(len + 1, output ? output + idx : NULL);\n    if (output)\n        output[idx] = unusedBits;\n    idx++;\n\n    return idx;\n}\n#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */\n\n#ifdef ASN_BER_TO_DER\n/* Pull informtation from the ASN.1 BER encoded item header */\nstatic int GetBerHeader(const byte* data, word32* idx, word32 maxIdx,\n                        byte* pTag, word32* pLen, int* indef)\n{\n    int len = 0;\n    byte tag;\n    word32 i = *idx;\n\n    *indef = 0;\n\n    /* Check there is enough data for a minimal header */\n    if (i + 2 > maxIdx) {\n        return ASN_PARSE_E;\n    }\n\n    /* Retrieve tag */\n    tag = data[i++];\n\n    /* Indefinite length handled specially */\n    if (data[i] == 0x80) {\n        /* Check valid tag for indefinite */\n        if (((tag & 0xc0) == 0) && ((tag & ASN_CONSTRUCTED) == 0x00)) {\n            return ASN_PARSE_E;\n        }\n        i++;\n        *indef = 1;\n    }\n    else if (GetLength(data, &i, &len, maxIdx) < 0) {\n        return ASN_PARSE_E;\n    }\n\n    /* Return tag, length and index after BER item header */\n    *pTag = tag;\n    *pLen = len;\n    *idx = i;\n    return 0;\n}\n\n#ifndef INDEF_ITEMS_MAX\n#define INDEF_ITEMS_MAX       20\n#endif\n\n/* Indef length item data */\ntypedef struct Indef {\n    word32 start;\n    int depth;\n    int headerLen;\n    word32 len;\n} Indef;\n\n/* Indef length items */\ntypedef struct IndefItems\n{\n    Indef len[INDEF_ITEMS_MAX];\n    int cnt;\n    int idx;\n    int depth;\n} IndefItems;\n\n\n/* Get header length of current item */\nstatic int IndefItems_HeaderLen(IndefItems* items)\n{\n    return items->len[items->idx].headerLen;\n}\n\n/* Get data length of current item */\nstatic word32 IndefItems_Len(IndefItems* items)\n{\n    return items->len[items->idx].len;\n}\n\n/* Add a indefinite length item */\nstatic int IndefItems_AddItem(IndefItems* items, word32 start)\n{\n    int ret = 0;\n    int i;\n\n    if (items->cnt == INDEF_ITEMS_MAX) {\n        ret = MEMORY_E;\n    }\n    else {\n        i = items->cnt++;\n        items->len[i].start = start;\n        items->len[i].depth = items->depth++;\n        items->len[i].headerLen = 1;\n        items->len[i].len = 0;\n        items->idx = i;\n    }\n\n    return ret;\n}\n\n/* Increase data length of current item */\nstatic void IndefItems_AddData(IndefItems* items, word32 length)\n{\n    items->len[items->idx].len += length;\n}\n\n/* Update header length of current item to reflect data length */\nstatic void IndefItems_UpdateHeaderLen(IndefItems* items)\n{\n    items->len[items->idx].headerLen +=\n                                    SetLength(items->len[items->idx].len, NULL);\n}\n\n/* Go to indefinite parent of current item */\nstatic void IndefItems_Up(IndefItems* items)\n{\n    int i;\n    int depth = items->len[items->idx].depth - 1;\n\n    for (i = items->cnt - 1; i >= 0; i--) {\n        if (items->len[i].depth == depth) {\n            break;\n        }\n    }\n    items->idx = i;\n    items->depth = depth + 1;\n}\n\n/* Calcuate final length by adding length of indefinite child items */\nstatic void IndefItems_CalcLength(IndefItems* items)\n{\n    int i;\n    int idx = items->idx;\n\n    for (i = idx + 1; i < items->cnt; i++) {\n        if (items->len[i].depth == items->depth) {\n            items->len[idx].len += items->len[i].headerLen;\n            items->len[idx].len += items->len[i].len;\n        }\n    }\n    items->len[idx].headerLen += SetLength(items->len[idx].len, NULL);\n}\n\n/* Add more data to indefinite length item */\nstatic void IndefItems_MoreData(IndefItems* items, word32 length)\n{\n    if (items->cnt > 0 && items->idx >= 0) {\n        items->len[items->idx].len += length;\n    }\n}\n\n/* Convert a BER encoding with indefinite length items to DER.\n *\n * ber    BER encoded data.\n * berSz  Length of BER encoded data.\n * der    Buffer to hold DER encoded version of data.\n *        NULL indicates only the length is required.\n * derSz  The size of the buffer to hold the DER encoded data.\n *        Will be set if der is NULL, otherwise the value is checked as der is\n *        filled.\n * returns ASN_PARSE_E if the BER data is invalid and BAD_FUNC_ARG if ber or\n * derSz are NULL.\n */\nint wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)\n{\n    int ret = 0;\n    word32 i, j;\n#ifdef WOLFSSL_SMALL_STACK\n    IndefItems* indefItems = NULL;\n#else\n    IndefItems indefItems[1];\n#endif\n    byte tag, basic;\n    word32 length;\n    int indef;\n\n    if (ber == NULL || derSz == NULL)\n        return BAD_FUNC_ARG;\n\n#ifdef WOLFSSL_SMALL_STACK\n    indefItems = XMALLOC(sizeof(IndefItems), NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (indefItems == NULL) {\n        ret = MEMORY_E;\n        goto end;\n    }\n#endif\n\n    XMEMSET(indefItems, 0, sizeof(*indefItems));\n\n    /* Calculate indefinite item lengths */\n    for (i = 0; i < berSz; ) {\n        word32 start = i;\n\n        /* Get next BER item */\n        ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);\n        if (ret != 0) {\n            goto end;\n        }\n\n        if (indef) {\n            /* Indefinite item - add to list */\n            ret = IndefItems_AddItem(indefItems, i);\n            if (ret != 0) {\n                goto end;\n            }\n\n            if ((tag & 0xC0) == 0 &&\n                tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&\n                tag != (ASN_SET      | ASN_CONSTRUCTED)) {\n                /* Constructed basic type - get repeating tag */\n                basic = tag & (~ASN_CONSTRUCTED);\n\n                /* Add up lengths of each item below */\n                for (; i < berSz; ) {\n                    /* Get next BER_item */\n                    ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);\n                    if (ret != 0) {\n                        goto end;\n                    }\n\n                    /* End of content closes item */\n                    if (tag == ASN_EOC) {\n                        /* Must be zero length */\n                        if (length != 0) {\n                            ret = ASN_PARSE_E;\n                            goto end;\n                        }\n                        break;\n                    }\n\n                    /* Must not be indefinite and tag must match parent */\n                    if (indef || tag != basic) {\n                        ret = ASN_PARSE_E;\n                        goto end;\n                    }\n\n                    /* Add to length */\n                    IndefItems_AddData(indefItems, length);\n                    /* Skip data */\n                    i += length;\n                }\n\n                /* Ensure we got an EOC and not end of data */\n                if (tag != ASN_EOC) {\n                    ret = ASN_PARSE_E;\n                    goto end;\n                }\n\n                /* Set the header length to include the length field */\n                IndefItems_UpdateHeaderLen(indefItems);\n                /* Go to indefinte parent item */\n                IndefItems_Up(indefItems);\n            }\n        }\n        else if (tag == ASN_EOC) {\n            /* End-of-content must be 0 length */\n            if (length != 0) {\n                ret = ASN_PARSE_E;\n                goto end;\n            }\n            /* Check there is an item to close - missing EOC */\n            if (indefItems->depth == 0) {\n                ret = ASN_PARSE_E;\n                goto end;\n            }\n\n            /* Finish calculation of data length for indefinite item */\n            IndefItems_CalcLength(indefItems);\n            /* Go to indefinte parent item */\n            IndefItems_Up(indefItems);\n        }\n        else {\n            /* Known length item to add in - make sure enough data for it */\n            if (i + length > berSz) {\n                ret = ASN_PARSE_E;\n                goto end;\n            }\n\n            /* Include all data - can't have indefinite inside definite */\n            i += length;\n            /* Add entire item to current indefinite item */\n            IndefItems_MoreData(indefItems, i - start);\n        }\n    }\n    /* Check we had a EOC for each indefinite item */\n    if (indefItems->depth != 0) {\n        ret = ASN_PARSE_E;\n        goto end;\n    }\n\n    /* Write out DER */\n\n    j = 0;\n    /* Reset index */\n    indefItems->idx = 0;\n    for (i = 0; i < berSz; ) {\n        word32 start = i;\n\n        /* Get item - checked above */\n        (void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);\n        if (indef) {\n            if (der != NULL) {\n                /* Check enough space for header */\n                if (j + IndefItems_HeaderLen(indefItems) > *derSz) {\n                    ret = BUFFER_E;\n                    goto end;\n                }\n\n                if ((tag & 0xC0) == 0 &&\n                    tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&\n                    tag != (ASN_SET      | ASN_CONSTRUCTED)) {\n                    /* Remove constructed tag for basic types */\n                    tag &= ~ASN_CONSTRUCTED;\n                }\n                /* Add tag and length */\n                der[j] = tag;\n                (void)SetLength(IndefItems_Len(indefItems), der + j + 1);\n            }\n            /* Add header length of indefinite item */\n            j += IndefItems_HeaderLen(indefItems);\n\n            if ((tag & 0xC0) == 0 &&\n                tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&\n                tag != (ASN_SET      | ASN_CONSTRUCTED)) {\n                /* For basic type - get each child item and add data */\n                for (; i < berSz; ) {\n                    (void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);\n                    if (tag == ASN_EOC) {\n                        break;\n                    }\n                    if (der != NULL) {\n                        if (j + length > *derSz) {\n                            ret = BUFFER_E;\n                            goto end;\n                        }\n                        XMEMCPY(der + j, ber + i, length);\n                    }\n                    j += length;\n                    i += length;\n                }\n            }\n\n            /* Move to next indef item in list */\n            indefItems->idx++;\n        }\n        else if (tag == ASN_EOC) {\n            /* End-Of-Content is not written out in DER */\n        }\n        else {\n            /* Write out definite length item as is. */\n            i += length;\n            if (der != NULL) {\n                /* Ensure space for item */\n                if (j + i - start > *derSz) {\n                    ret = BUFFER_E;\n                    goto end;\n                }\n                /* Copy item as is */\n                XMEMCPY(der + j, ber + start, i - start);\n            }\n            j += i - start;\n        }\n    }\n\n    /* Return the length of the DER encoded ASN.1 */\n    *derSz = j;\n    if (der == NULL) {\n        ret = LENGTH_ONLY_E;\n    }\nend:\n#ifdef WOLFSSL_SMALL_STACK\n    if (indefItems != NULL) {\n        XFREE(indefItems, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n    return ret;\n}\n#endif\n\n#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)\n\n#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || \\\n    defined(HAVE_ECC) || defined(HAVE_ED25519)\n\n#ifdef WOLFSSL_CERT_EXT\n/* Set the DER/BER encoding of the ASN.1 BIT_STRING with a 16-bit value.\n *\n * val         16-bit value to encode.\n * output      Buffer to write into.\n * returns the number of bytes added to the buffer.\n */\nstatic word32 SetBitString16Bit(word16 val, byte* output)\n{\n    word32 idx;\n    int    len;\n    byte   lastByte;\n    byte   unusedBits = 0;\n\n    if ((val >> 8) != 0) {\n        len = 2;\n        lastByte = (byte)(val >> 8);\n    }\n    else {\n        len = 1;\n        lastByte = (byte)val;\n    }\n\n    while (((lastByte >> unusedBits) & 0x01) == 0x00)\n        unusedBits++;\n\n    idx = SetBitString(len, unusedBits, output);\n    output[idx++] = (byte)val;\n    if (len > 1)\n        output[idx++] = (byte)(val >> 8);\n\n    return idx;\n}\n#endif /* WOLFSSL_CERT_EXT */\n#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */\n#endif /* WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN */\n\n\n\n/* hashType */\n#ifdef WOLFSSL_MD2\n    static const byte hashMd2hOid[] = {42, 134, 72, 134, 247, 13, 2, 2};\n#endif\n#ifndef NO_MD5\n    static const byte hashMd5hOid[] = {42, 134, 72, 134, 247, 13, 2, 5};\n#endif\n#ifndef NO_SHA\n    static const byte hashSha1hOid[] = {43, 14, 3, 2, 26};\n#endif\n#ifdef WOLFSSL_SHA224\n    static const byte hashSha224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 4};\n#endif\n#ifndef NO_SHA256\n    static const byte hashSha256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 1};\n#endif\n#ifdef WOLFSSL_SHA384\n    static const byte hashSha384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 2};\n#endif\n#ifdef WOLFSSL_SHA512\n    static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3};\n#endif\n\n/* hmacType */\n#ifndef NO_HMAC\n    #ifdef WOLFSSL_SHA224\n    static const byte hmacSha224Oid[] = {42, 134, 72, 134, 247, 13, 2, 8};\n    #endif\n    #ifndef NO_SHA256\n    static const byte hmacSha256Oid[] = {42, 134, 72, 134, 247, 13, 2, 9};\n    #endif\n    #ifdef WOLFSSL_SHA384\n    static const byte hmacSha384Oid[] = {42, 134, 72, 134, 247, 13, 2, 10};\n    #endif\n    #ifdef WOLFSSL_SHA512\n    static const byte hmacSha512Oid[] = {42, 134, 72, 134, 247, 13, 2, 11};\n    #endif\n#endif\n\n/* sigType */\n#if !defined(NO_DSA) && !defined(NO_SHA)\n    static const byte sigSha1wDsaOid[] = {42, 134, 72, 206, 56, 4, 3};\n#endif /* NO_DSA */\n#ifndef NO_RSA\n    #ifdef WOLFSSL_MD2\n    static const byte sigMd2wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 2};\n    #endif\n    #ifndef NO_MD5\n    static const byte sigMd5wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 4};\n    #endif\n    #ifndef NO_SHA\n    static const byte sigSha1wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 5};\n    #endif\n    #ifdef WOLFSSL_SHA224\n    static const byte sigSha224wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,14};\n    #endif\n    #ifndef NO_SHA256\n    static const byte sigSha256wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,11};\n    #endif\n    #ifdef WOLFSSL_SHA384\n    static const byte sigSha384wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,12};\n    #endif\n    #ifdef WOLFSSL_SHA512\n    static const byte sigSha512wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,13};\n    #endif\n#endif /* NO_RSA */\n#ifdef HAVE_ECC\n    #ifndef NO_SHA\n    static const byte sigSha1wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 1};\n    #endif\n    #ifdef WOLFSSL_SHA224\n    static const byte sigSha224wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 1};\n    #endif\n    #ifndef NO_SHA256\n    static const byte sigSha256wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 2};\n    #endif\n    #ifdef WOLFSSL_SHA384\n    static const byte sigSha384wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 3};\n    #endif\n    #ifdef WOLFSSL_SHA512\n    static const byte sigSha512wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 4};\n    #endif\n#endif /* HAVE_ECC */\n#ifdef HAVE_ED25519\n    static const byte sigEd25519Oid[] = {43, 101, 112};\n#endif /* HAVE_ED25519 */\n\n/* keyType */\n#ifndef NO_DSA\n    static const byte keyDsaOid[] = {42, 134, 72, 206, 56, 4, 1};\n#endif /* NO_DSA */\n#ifndef NO_RSA\n    static const byte keyRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 1};\n#endif /* NO_RSA */\n#ifdef HAVE_NTRU\n    static const byte keyNtruOid[] = {43, 6, 1, 4, 1, 193, 22, 1, 1, 1, 1};\n#endif /* HAVE_NTRU */\n#ifdef HAVE_ECC\n    static const byte keyEcdsaOid[] = {42, 134, 72, 206, 61, 2, 1};\n#endif /* HAVE_ECC */\n#ifdef HAVE_ED25519\n    static const byte keyEd25519Oid[] = {43, 101, 112};\n#endif /* HAVE_ED25519 */\n\n/* curveType */\n#ifdef HAVE_ECC\n    /* See \"ecc_sets\" table in ecc.c */\n#endif /* HAVE_ECC */\n\n#ifdef HAVE_AES_CBC\n/* blkType */\n    #ifdef WOLFSSL_AES_128\n    static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2};\n    #endif\n    #ifdef WOLFSSL_AES_192\n    static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22};\n    #endif\n    #ifdef WOLFSSL_AES_256\n    static const byte blkAes256CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 42};\n    #endif\n#endif /* HAVE_AES_CBC */\n#ifdef HAVE_AESGCM\n    #ifdef WOLFSSL_AES_128\n    static const byte blkAes128GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 6};\n    #endif\n    #ifdef WOLFSSL_AES_192\n    static const byte blkAes192GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 26};\n    #endif\n    #ifdef WOLFSSL_AES_256\n    static const byte blkAes256GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 46};\n    #endif\n#endif /* HAVE_AESGCM */\n#ifdef HAVE_AESCCM\n    #ifdef WOLFSSL_AES_128\n    static const byte blkAes128CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 7};\n    #endif\n    #ifdef WOLFSSL_AES_192\n    static const byte blkAes192CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 27};\n    #endif\n    #ifdef WOLFSSL_AES_256\n    static const byte blkAes256CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 47};\n    #endif\n#endif /* HAVE_AESCCM */\n\n#ifndef NO_DES3\n    static const byte blkDesCbcOid[]  = {43, 14, 3, 2, 7};\n    static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7};\n#endif\n\n/* keyWrapType */\n#ifdef WOLFSSL_AES_128\n    static const byte wrapAes128Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 5};\n#endif\n#ifdef WOLFSSL_AES_192\n    static const byte wrapAes192Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 25};\n#endif\n#ifdef WOLFSSL_AES_256\n    static const byte wrapAes256Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 45};\n#endif\n#ifdef HAVE_PKCS7\n/* From RFC 3211 */\nstatic const byte wrapPwriKekOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3,9};\n#endif\n\n/* cmsKeyAgreeType */\n#ifndef NO_SHA\n    static const byte dhSinglePass_stdDH_sha1kdf_Oid[]   =\n                                          {43, 129, 5, 16, 134, 72, 63, 0, 2};\n#endif\n#ifdef WOLFSSL_SHA224\n    static const byte dhSinglePass_stdDH_sha224kdf_Oid[] = {43, 129, 4, 1, 11, 0};\n#endif\n#ifndef NO_SHA256\n    static const byte dhSinglePass_stdDH_sha256kdf_Oid[] = {43, 129, 4, 1, 11, 1};\n#endif\n#ifdef WOLFSSL_SHA384\n    static const byte dhSinglePass_stdDH_sha384kdf_Oid[] = {43, 129, 4, 1, 11, 2};\n#endif\n#ifdef WOLFSSL_SHA512\n    static const byte dhSinglePass_stdDH_sha512kdf_Oid[] = {43, 129, 4, 1, 11, 3};\n#endif\n\n/* ocspType */\n#ifdef HAVE_OCSP\n    static const byte ocspBasicOid[] = {43, 6, 1, 5, 5, 7, 48, 1, 1};\n    static const byte ocspNonceOid[] = {43, 6, 1, 5, 5, 7, 48, 1, 2};\n#endif /* HAVE_OCSP */\n\n/* certExtType */\nstatic const byte extBasicCaOid[] = {85, 29, 19};\nstatic const byte extAltNamesOid[] = {85, 29, 17};\nstatic const byte extCrlDistOid[] = {85, 29, 31};\nstatic const byte extAuthInfoOid[] = {43, 6, 1, 5, 5, 7, 1, 1};\nstatic const byte extAuthKeyOid[] = {85, 29, 35};\nstatic const byte extSubjKeyOid[] = {85, 29, 14};\nstatic const byte extCertPolicyOid[] = {85, 29, 32};\nstatic const byte extKeyUsageOid[] = {85, 29, 15};\nstatic const byte extInhibitAnyOid[] = {85, 29, 54};\nstatic const byte extExtKeyUsageOid[] = {85, 29, 37};\n#ifndef IGNORE_NAME_CONSTRAINTS\n    static const byte extNameConsOid[] = {85, 29, 30};\n#endif\n\n/* certAuthInfoType */\n#ifdef HAVE_OCSP\n    static const byte extAuthInfoOcspOid[] = {43, 6, 1, 5, 5, 7, 48, 1};\n#endif\nstatic const byte extAuthInfoCaIssuerOid[] = {43, 6, 1, 5, 5, 7, 48, 2};\n\n/* certPolicyType */\nstatic const byte extCertPolicyAnyOid[] = {85, 29, 32, 0};\n\n/* certKeyUseType */\nstatic const byte extAltNamesHwNameOid[] = {43, 6, 1, 5, 5, 7, 8, 4};\n\n/* certKeyUseType */\nstatic const byte extExtKeyUsageAnyOid[] = {85, 29, 37, 0};\nstatic const byte extExtKeyUsageServerAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 1};\nstatic const byte extExtKeyUsageClientAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 2};\nstatic const byte extExtKeyUsageCodeSigningOid[]  = {43, 6, 1, 5, 5, 7, 3, 3};\nstatic const byte extExtKeyUsageEmailProtectOid[] = {43, 6, 1, 5, 5, 7, 3, 4};\nstatic const byte extExtKeyUsageTimestampOid[]    = {43, 6, 1, 5, 5, 7, 3, 8};\nstatic const byte extExtKeyUsageOcspSignOid[]     = {43, 6, 1, 5, 5, 7, 3, 9};\n\n/* kdfType */\nstatic const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12};\n\n/* PKCS5 */\n#if !defined(NO_DES3) && !defined(NO_SHA)\nstatic const byte pbeSha1Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 10};\n#endif\nstatic const byte pbes2[] = {42, 134, 72, 134, 247, 13, 1, 5, 13};\n\n/* PKCS12 */\n#if !defined(NO_RC4) && !defined(NO_SHA)\nstatic const byte pbeSha1RC4128[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 1};\n#endif\n#if !defined(NO_DES3) && !defined(NO_SHA)\nstatic const byte pbeSha1Des3[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 3};\n#endif\n\n#ifdef HAVE_LIBZ\n/* zlib compression */\nstatic const byte zlibCompress[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3, 8};\n#endif\n#ifdef WOLFSSL_APACHE_HTTPD\n/* tlsExtType */\nstatic const byte tlsFeatureOid[] = {43, 6, 1, 5, 5, 7, 1, 24};\n/* certNameType */\nstatic const byte dnsSRVOid[] = {43, 6, 1, 5, 5, 7, 8, 7};\n#endif\n\n\n/* returns a pointer to the OID string on success and NULL on fail */\nconst byte* OidFromId(word32 id, word32 type, word32* oidSz)\n{\n    const byte* oid = NULL;\n\n    *oidSz = 0;\n\n    switch (type) {\n\n        case oidHashType:\n            switch (id) {\n            #ifdef WOLFSSL_MD2\n                case MD2h:\n                    oid = hashMd2hOid;\n                    *oidSz = sizeof(hashMd2hOid);\n                    break;\n            #endif\n            #ifndef NO_MD5\n                case MD5h:\n                    oid = hashMd5hOid;\n                    *oidSz = sizeof(hashMd5hOid);\n                    break;\n            #endif\n            #ifndef NO_SHA\n                case SHAh:\n                    oid = hashSha1hOid;\n                    *oidSz = sizeof(hashSha1hOid);\n                    break;\n            #endif\n            #ifdef WOLFSSL_SHA224\n                case SHA224h:\n                    oid = hashSha224hOid;\n                    *oidSz = sizeof(hashSha224hOid);\n                    break;\n            #endif\n            #ifndef NO_SHA256\n                case SHA256h:\n                    oid = hashSha256hOid;\n                    *oidSz = sizeof(hashSha256hOid);\n                    break;\n            #endif\n            #ifdef WOLFSSL_SHA384\n                case SHA384h:\n                    oid = hashSha384hOid;\n                    *oidSz = sizeof(hashSha384hOid);\n                    break;\n            #endif\n            #ifdef WOLFSSL_SHA512\n                case SHA512h:\n                    oid = hashSha512hOid;\n                    *oidSz = sizeof(hashSha512hOid);\n                    break;\n            #endif\n            }\n            break;\n\n        case oidSigType:\n            switch (id) {\n                #if !defined(NO_DSA) && !defined(NO_SHA)\n                case CTC_SHAwDSA:\n                    oid = sigSha1wDsaOid;\n                    *oidSz = sizeof(sigSha1wDsaOid);\n                    break;\n                #endif /* NO_DSA */\n                #ifndef NO_RSA\n                #ifdef WOLFSSL_MD2\n                case CTC_MD2wRSA:\n                    oid = sigMd2wRsaOid;\n                    *oidSz = sizeof(sigMd2wRsaOid);\n                    break;\n                #endif\n                #ifndef NO_MD5\n                case CTC_MD5wRSA:\n                    oid = sigMd5wRsaOid;\n                    *oidSz = sizeof(sigMd5wRsaOid);\n                    break;\n                #endif\n                #ifndef NO_SHA\n                case CTC_SHAwRSA:\n                    oid = sigSha1wRsaOid;\n                    *oidSz = sizeof(sigSha1wRsaOid);\n                    break;\n                #endif\n                #ifdef WOLFSSL_SHA224\n                case CTC_SHA224wRSA:\n                    oid = sigSha224wRsaOid;\n                    *oidSz = sizeof(sigSha224wRsaOid);\n                    break;\n                #endif\n                #ifndef NO_SHA256\n                case CTC_SHA256wRSA:\n                    oid = sigSha256wRsaOid;\n                    *oidSz = sizeof(sigSha256wRsaOid);\n                    break;\n                #endif\n                #ifdef WOLFSSL_SHA384\n                case CTC_SHA384wRSA:\n                    oid = sigSha384wRsaOid;\n                    *oidSz = sizeof(sigSha384wRsaOid);\n                    break;\n                #endif\n                #ifdef WOLFSSL_SHA512\n                case CTC_SHA512wRSA:\n                    oid = sigSha512wRsaOid;\n                    *oidSz = sizeof(sigSha512wRsaOid);\n                    break;\n                #endif /* WOLFSSL_SHA512 */\n                #endif /* NO_RSA */\n                #ifdef HAVE_ECC\n                #ifndef NO_SHA\n                case CTC_SHAwECDSA:\n                    oid = sigSha1wEcdsaOid;\n                    *oidSz = sizeof(sigSha1wEcdsaOid);\n                    break;\n                #endif\n                #ifdef WOLFSSL_SHA224\n                case CTC_SHA224wECDSA:\n                    oid = sigSha224wEcdsaOid;\n                    *oidSz = sizeof(sigSha224wEcdsaOid);\n                    break;\n                #endif\n                #ifndef NO_SHA256\n                case CTC_SHA256wECDSA:\n                    oid = sigSha256wEcdsaOid;\n                    *oidSz = sizeof(sigSha256wEcdsaOid);\n                    break;\n                #endif\n                #ifdef WOLFSSL_SHA384\n                case CTC_SHA384wECDSA:\n                    oid = sigSha384wEcdsaOid;\n                    *oidSz = sizeof(sigSha384wEcdsaOid);\n                    break;\n                #endif\n                #ifdef WOLFSSL_SHA512\n                case CTC_SHA512wECDSA:\n                    oid = sigSha512wEcdsaOid;\n                    *oidSz = sizeof(sigSha512wEcdsaOid);\n                    break;\n                #endif\n                #endif /* HAVE_ECC */\n                #ifdef HAVE_ED25519\n                case CTC_ED25519:\n                    oid = sigEd25519Oid;\n                    *oidSz = sizeof(sigEd25519Oid);\n                    break;\n                #endif\n                default:\n                    break;\n            }\n            break;\n\n        case oidKeyType:\n            switch (id) {\n                #ifndef NO_DSA\n                case DSAk:\n                    oid = keyDsaOid;\n                    *oidSz = sizeof(keyDsaOid);\n                    break;\n                #endif /* NO_DSA */\n                #ifndef NO_RSA\n                case RSAk:\n                    oid = keyRsaOid;\n                    *oidSz = sizeof(keyRsaOid);\n                    break;\n                #endif /* NO_RSA */\n                #ifdef HAVE_NTRU\n                case NTRUk:\n                    oid = keyNtruOid;\n                    *oidSz = sizeof(keyNtruOid);\n                    break;\n                #endif /* HAVE_NTRU */\n                #ifdef HAVE_ECC\n                case ECDSAk:\n                    oid = keyEcdsaOid;\n                    *oidSz = sizeof(keyEcdsaOid);\n                    break;\n                #endif /* HAVE_ECC */\n                #ifdef HAVE_ED25519\n                case ED25519k:\n                    oid = keyEd25519Oid;\n                    *oidSz = sizeof(keyEd25519Oid);\n                    break;\n                #endif /* HAVE_ED25519 */\n                default:\n                    break;\n            }\n            break;\n\n        #ifdef HAVE_ECC\n        case oidCurveType:\n            if (wc_ecc_get_oid(id, &oid, oidSz) < 0) {\n                WOLFSSL_MSG(\"ECC OID not found\");\n            }\n            break;\n        #endif /* HAVE_ECC */\n\n        case oidBlkType:\n            switch (id) {\n    #ifdef HAVE_AES_CBC\n        #ifdef WOLFSSL_AES_128\n                case AES128CBCb:\n                    oid = blkAes128CbcOid;\n                    *oidSz = sizeof(blkAes128CbcOid);\n                    break;\n        #endif\n        #ifdef WOLFSSL_AES_192\n                case AES192CBCb:\n                    oid = blkAes192CbcOid;\n                    *oidSz = sizeof(blkAes192CbcOid);\n                    break;\n        #endif\n        #ifdef WOLFSSL_AES_256\n                case AES256CBCb:\n                    oid = blkAes256CbcOid;\n                    *oidSz = sizeof(blkAes256CbcOid);\n                    break;\n        #endif\n    #endif /* HAVE_AES_CBC */\n    #ifdef HAVE_AESGCM\n        #ifdef WOLFSSL_AES_128\n                case AES128GCMb:\n                    oid = blkAes128GcmOid;\n                    *oidSz = sizeof(blkAes128GcmOid);\n                    break;\n        #endif\n        #ifdef WOLFSSL_AES_192\n                case AES192GCMb:\n                    oid = blkAes192GcmOid;\n                    *oidSz = sizeof(blkAes192GcmOid);\n                    break;\n        #endif\n        #ifdef WOLFSSL_AES_256\n                case AES256GCMb:\n                    oid = blkAes256GcmOid;\n                    *oidSz = sizeof(blkAes256GcmOid);\n                    break;\n        #endif\n    #endif /* HAVE_AESGCM */\n    #ifdef HAVE_AESCCM\n        #ifdef WOLFSSL_AES_128\n                case AES128CCMb:\n                    oid = blkAes128CcmOid;\n                    *oidSz = sizeof(blkAes128CcmOid);\n                    break;\n        #endif\n        #ifdef WOLFSSL_AES_192\n                case AES192CCMb:\n                    oid = blkAes192CcmOid;\n                    *oidSz = sizeof(blkAes192CcmOid);\n                    break;\n        #endif\n        #ifdef WOLFSSL_AES_256\n                case AES256CCMb:\n                    oid = blkAes256CcmOid;\n                    *oidSz = sizeof(blkAes256CcmOid);\n                    break;\n        #endif\n    #endif /* HAVE_AESCCM */\n    #ifndef NO_DES3\n                case DESb:\n                    oid = blkDesCbcOid;\n                    *oidSz = sizeof(blkDesCbcOid);\n                    break;\n                case DES3b:\n                    oid = blkDes3CbcOid;\n                    *oidSz = sizeof(blkDes3CbcOid);\n                    break;\n    #endif /* !NO_DES3 */\n            }\n            break;\n\n        #ifdef HAVE_OCSP\n        case oidOcspType:\n            switch (id) {\n                case OCSP_BASIC_OID:\n                    oid = ocspBasicOid;\n                    *oidSz = sizeof(ocspBasicOid);\n                    break;\n                case OCSP_NONCE_OID:\n                    oid = ocspNonceOid;\n                    *oidSz = sizeof(ocspNonceOid);\n                    break;\n            }\n            break;\n        #endif /* HAVE_OCSP */\n\n        case oidCertExtType:\n            switch (id) {\n                case BASIC_CA_OID:\n                    oid = extBasicCaOid;\n                    *oidSz = sizeof(extBasicCaOid);\n                    break;\n                case ALT_NAMES_OID:\n                    oid = extAltNamesOid;\n                    *oidSz = sizeof(extAltNamesOid);\n                    break;\n                case CRL_DIST_OID:\n                    oid = extCrlDistOid;\n                    *oidSz = sizeof(extCrlDistOid);\n                    break;\n                case AUTH_INFO_OID:\n                    oid = extAuthInfoOid;\n                    *oidSz = sizeof(extAuthInfoOid);\n                    break;\n                case AUTH_KEY_OID:\n                    oid = extAuthKeyOid;\n                    *oidSz = sizeof(extAuthKeyOid);\n                    break;\n                case SUBJ_KEY_OID:\n                    oid = extSubjKeyOid;\n                    *oidSz = sizeof(extSubjKeyOid);\n                    break;\n                case CERT_POLICY_OID:\n                    oid = extCertPolicyOid;\n                    *oidSz = sizeof(extCertPolicyOid);\n                    break;\n                case KEY_USAGE_OID:\n                    oid = extKeyUsageOid;\n                    *oidSz = sizeof(extKeyUsageOid);\n                    break;\n                case INHIBIT_ANY_OID:\n                    oid = extInhibitAnyOid;\n                    *oidSz = sizeof(extInhibitAnyOid);\n                    break;\n                case EXT_KEY_USAGE_OID:\n                    oid = extExtKeyUsageOid;\n                    *oidSz = sizeof(extExtKeyUsageOid);\n                    break;\n            #ifndef IGNORE_NAME_CONSTRAINTS\n                case NAME_CONS_OID:\n                    oid = extNameConsOid;\n                    *oidSz = sizeof(extNameConsOid);\n                    break;\n            #endif\n            }\n            break;\n\n        case oidCrlExtType:\n            #ifdef HAVE_CRL\n            switch (id) {\n                case AUTH_KEY_OID:\n                    oid = extAuthKeyOid;\n                    *oidSz = sizeof(extAuthKeyOid);\n                    break;\n            }\n            #endif\n            break;\n\n        case oidCertAuthInfoType:\n            switch (id) {\n            #ifdef HAVE_OCSP\n                case AIA_OCSP_OID:\n                    oid = extAuthInfoOcspOid;\n                    *oidSz = sizeof(extAuthInfoOcspOid);\n                    break;\n            #endif\n                case AIA_CA_ISSUER_OID:\n                    oid = extAuthInfoCaIssuerOid;\n                    *oidSz = sizeof(extAuthInfoCaIssuerOid);\n                    break;\n            }\n            break;\n\n        case oidCertPolicyType:\n            switch (id) {\n                case CP_ANY_OID:\n                    oid = extCertPolicyAnyOid;\n                    *oidSz = sizeof(extCertPolicyAnyOid);\n                    break;\n            }\n            break;\n\n        case oidCertAltNameType:\n            switch (id) {\n                case HW_NAME_OID:\n                    oid = extAltNamesHwNameOid;\n                    *oidSz = sizeof(extAltNamesHwNameOid);\n                    break;\n            }\n            break;\n\n        case oidCertKeyUseType:\n            switch (id) {\n                case EKU_ANY_OID:\n                    oid = extExtKeyUsageAnyOid;\n                    *oidSz = sizeof(extExtKeyUsageAnyOid);\n                    break;\n                case EKU_SERVER_AUTH_OID:\n                    oid = extExtKeyUsageServerAuthOid;\n                    *oidSz = sizeof(extExtKeyUsageServerAuthOid);\n                    break;\n                case EKU_CLIENT_AUTH_OID:\n                    oid = extExtKeyUsageClientAuthOid;\n                    *oidSz = sizeof(extExtKeyUsageClientAuthOid);\n                    break;\n                case EKU_CODESIGNING_OID:\n                    oid = extExtKeyUsageCodeSigningOid;\n                    *oidSz = sizeof(extExtKeyUsageCodeSigningOid);\n                    break;\n                case EKU_EMAILPROTECT_OID:\n                    oid = extExtKeyUsageEmailProtectOid;\n                    *oidSz = sizeof(extExtKeyUsageEmailProtectOid);\n                    break;\n                case EKU_TIMESTAMP_OID:\n                    oid = extExtKeyUsageTimestampOid;\n                    *oidSz = sizeof(extExtKeyUsageTimestampOid);\n                    break;\n                case EKU_OCSP_SIGN_OID:\n                    oid = extExtKeyUsageOcspSignOid;\n                    *oidSz = sizeof(extExtKeyUsageOcspSignOid);\n                    break;\n            }\n            break;\n\n        case oidKdfType:\n            switch (id) {\n                case PBKDF2_OID:\n                    oid = pbkdf2Oid;\n                    *oidSz = sizeof(pbkdf2Oid);\n                    break;\n            }\n            break;\n\n        case oidPBEType:\n            switch (id) {\n        #if !defined(NO_SHA) && !defined(NO_RC4)\n                case PBE_SHA1_RC4_128:\n                    oid = pbeSha1RC4128;\n                    *oidSz = sizeof(pbeSha1RC4128);\n                    break;\n        #endif\n        #if !defined(NO_SHA) && !defined(NO_DES3)\n                case PBE_SHA1_DES:\n                    oid = pbeSha1Des;\n                    *oidSz = sizeof(pbeSha1Des);\n                    break;\n\n        #endif\n        #if !defined(NO_SHA) && !defined(NO_DES3)\n                case PBE_SHA1_DES3:\n                    oid = pbeSha1Des3;\n                    *oidSz = sizeof(pbeSha1Des3);\n                    break;\n        #endif\n                case PBES2:\n                    oid = pbes2;\n                    *oidSz = sizeof(pbes2);\n                    break;\n            }\n            break;\n\n        case oidKeyWrapType:\n            switch (id) {\n            #ifdef WOLFSSL_AES_128\n                case AES128_WRAP:\n                    oid = wrapAes128Oid;\n                    *oidSz = sizeof(wrapAes128Oid);\n                    break;\n            #endif\n            #ifdef WOLFSSL_AES_192\n                case AES192_WRAP:\n                    oid = wrapAes192Oid;\n                    *oidSz = sizeof(wrapAes192Oid);\n                    break;\n            #endif\n            #ifdef WOLFSSL_AES_256\n                case AES256_WRAP:\n                    oid = wrapAes256Oid;\n                    *oidSz = sizeof(wrapAes256Oid);\n                    break;\n            #endif\n            #ifdef HAVE_PKCS7\n                case PWRI_KEK_WRAP:\n                    oid = wrapPwriKekOid;\n                    *oidSz = sizeof(wrapPwriKekOid);\n                    break;\n            #endif\n            }\n            break;\n\n        case oidCmsKeyAgreeType:\n            switch (id) {\n            #ifndef NO_SHA\n                case dhSinglePass_stdDH_sha1kdf_scheme:\n                    oid = dhSinglePass_stdDH_sha1kdf_Oid;\n                    *oidSz = sizeof(dhSinglePass_stdDH_sha1kdf_Oid);\n                    break;\n            #endif\n            #ifdef WOLFSSL_SHA224\n                case dhSinglePass_stdDH_sha224kdf_scheme:\n                    oid = dhSinglePass_stdDH_sha224kdf_Oid;\n                    *oidSz = sizeof(dhSinglePass_stdDH_sha224kdf_Oid);\n                    break;\n            #endif\n            #ifndef NO_SHA256\n                case dhSinglePass_stdDH_sha256kdf_scheme:\n                    oid = dhSinglePass_stdDH_sha256kdf_Oid;\n                    *oidSz = sizeof(dhSinglePass_stdDH_sha256kdf_Oid);\n                    break;\n            #endif\n            #ifdef WOLFSSL_SHA384\n                case dhSinglePass_stdDH_sha384kdf_scheme:\n                    oid = dhSinglePass_stdDH_sha384kdf_Oid;\n                    *oidSz = sizeof(dhSinglePass_stdDH_sha384kdf_Oid);\n                    break;\n            #endif\n            #ifdef WOLFSSL_SHA512\n                case dhSinglePass_stdDH_sha512kdf_scheme:\n                    oid = dhSinglePass_stdDH_sha512kdf_Oid;\n                    *oidSz = sizeof(dhSinglePass_stdDH_sha512kdf_Oid);\n                    break;\n            #endif\n            }\n            break;\n\n#ifndef NO_HMAC\n        case oidHmacType:\n            switch (id) {\n        #ifdef WOLFSSL_SHA224\n                case HMAC_SHA224_OID:\n                    oid = hmacSha224Oid;\n                    *oidSz = sizeof(hmacSha224Oid);\n                    break;\n        #endif\n        #ifndef NO_SHA256\n                case HMAC_SHA256_OID:\n                    oid = hmacSha256Oid;\n                    *oidSz = sizeof(hmacSha256Oid);\n                    break;\n        #endif\n        #ifdef WOLFSSL_SHA384\n                case HMAC_SHA384_OID:\n                    oid = hmacSha384Oid;\n                    *oidSz = sizeof(hmacSha384Oid);\n                    break;\n        #endif\n        #ifdef WOLFSSL_SHA512\n                case HMAC_SHA512_OID:\n                    oid = hmacSha512Oid;\n                    *oidSz = sizeof(hmacSha512Oid);\n                    break;\n        #endif\n            }\n            break;\n#endif /* !NO_HMAC */\n\n#ifdef HAVE_LIBZ\n        case oidCompressType:\n            switch (id) {\n                case ZLIBc:\n                    oid = zlibCompress;\n                    *oidSz = sizeof(zlibCompress);\n                    break;\n            }\n            break;\n#endif /* HAVE_LIBZ */\n#ifdef WOLFSSL_APACHE_HTTPD\n        case oidCertNameType:\n            switch (id) {\n                 case NID_id_on_dnsSRV:\n                    oid = dnsSRVOid;\n                    *oidSz = sizeof(dnsSRVOid);\n                    break;\n            }\n            break;\n        case oidTlsExtType:\n            switch (id) {\n                case TLS_FEATURE_OID:\n                    oid = tlsFeatureOid;\n                    *oidSz = sizeof(tlsFeatureOid);\n                    break;\n            }\n            break;\n#endif /* WOLFSSL_APACHE_HTTPD */\n        case oidIgnoreType:\n        default:\n            break;\n    }\n\n    return oid;\n}\n\n#ifdef HAVE_OID_ENCODING\nint EncodeObjectId(const word16* in, word32 inSz, byte* out, word32* outSz)\n{\n    int i, x, len;\n    word32 d, t;\n\n    /* check args */\n    if (in == NULL || outSz == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* compute length of encoded OID */\n    d = (in[0] * 40) + in[1];\n    len = 0;\n    for (i = 1; i < (int)inSz; i++) {\n        x = 0;\n        t = d;\n        while (t) {\n            x++;\n            t >>= 1;\n        }\n        len += (x / 7) + ((x % 7) ? 1 : 0) + (d == 0 ? 1 : 0);\n\n        if (i < (int)inSz - 1) {\n            d = in[i + 1];\n        }\n    }\n\n    if (out) {\n        /* verify length */\n        if ((int)*outSz < len) {\n            return BUFFER_E; /* buffer provided is not large enough */\n        }\n\n        /* calc first byte */\n        d = (in[0] * 40) + in[1];\n\n        /* encode bytes */\n        x = 0;\n        for (i = 1; i < (int)inSz; i++) {\n            if (d) {\n                int y = x, z;\n                byte mask = 0;\n                while (d) {\n                    out[x++] = (byte)((d & 0x7F) | mask);\n                    d     >>= 7;\n                    mask  |= 0x80;  /* upper bit is set on all but the last byte */\n                }\n                /* now swap bytes y...x-1 */\n                z = x - 1;\n                while (y < z) {\n                    mask = out[y];\n                    out[y] = out[z];\n                    out[z] = mask;\n                    ++y;\n                    --z;\n                }\n            }\n            else {\n              out[x++] = 0x00; /* zero value */\n            }\n\n            /* next word */\n            if (i < (int)inSz - 1) {\n                d = in[i + 1];\n            }\n        }\n    }\n\n    /* return length */\n    *outSz = len;\n\n    return 0;\n}\n#endif /* HAVE_OID_ENCODING */\n\n#ifdef HAVE_OID_DECODING\nint DecodeObjectId(const byte* in, word32 inSz, word16* out, word32* outSz)\n{\n    int x = 0, y = 0;\n    word32 t = 0;\n\n    /* check args */\n    if (in == NULL || outSz == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* decode bytes */\n    while (inSz--) {\n        t = (t << 7) | (in[x] & 0x7F);\n        if (!(in[x] & 0x80)) {\n            if (y >= (int)*outSz) {\n                return BUFFER_E;\n            }\n            if (y == 0) {\n                out[0] = (t / 40);\n                out[1] = (t % 40);\n                y = 2;\n            }\n            else {\n                out[y++] = t;\n            }\n            t = 0; /* reset tmp */\n        }\n        x++;\n    }\n\n    /* return length */\n    *outSz = y;\n\n    return 0;\n}\n#endif /* HAVE_OID_DECODING */\n\n/* Get the DER/BER encoding of an ASN.1 OBJECT_ID header.\n *\n * input     Buffer holding DER/BER encoded data.\n * inOutIdx  Current index into buffer to parse.\n * len       The number of bytes in the ASN.1 data.\n * maxIdx    Length of data in buffer.\n * returns BUFFER_E when there is not enough data to parse.\n *         ASN_OBJECt_ID_E when the OBJECT_ID tag is not found.\n *         ASN_PARSE_E when length is invalid.\n *         Otherwise, 0 to indicate success.\n */\nint GetASNObjectId(const byte* input, word32* inOutIdx, int* len,\n                          word32 maxIdx)\n{\n    word32 idx = *inOutIdx;\n    int    length;\n    byte   tag;\n\n    if ((idx + 1) > maxIdx)\n        return BUFFER_E;\n\n    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)\n        return ASN_PARSE_E;\n\n    if (tag != ASN_OBJECT_ID)\n        return ASN_OBJECT_ID_E;\n\n    if (GetLength(input, &idx, &length, maxIdx) < 0)\n        return ASN_PARSE_E;\n\n    *len = length;\n    *inOutIdx = idx;\n    return 0;\n}\n\n/* Set the DER/BER encoding of the ASN.1 OBJECT_ID header.\n *\n * len         Length of the OBJECT_ID data.\n * output      Buffer to write into.\n * returns the number of bytes added to the buffer.\n */\nint SetObjectId(int len, byte* output)\n{\n    int idx = 0;\n\n    output[idx++] = ASN_OBJECT_ID;\n    idx += SetLength(len, output + idx);\n\n    return idx;\n}\n\nint GetObjectId(const byte* input, word32* inOutIdx, word32* oid,\n                                  word32 oidType, word32 maxIdx)\n{\n    int    ret = 0, length;\n    word32 idx = *inOutIdx;\n#ifndef NO_VERIFY_OID\n    word32 actualOidSz = 0;\n    const byte* actualOid;\n#endif /* NO_VERIFY_OID */\n\n    (void)oidType;\n    WOLFSSL_ENTER(\"GetObjectId()\");\n    *oid = 0;\n\n    ret = GetASNObjectId(input, &idx, &length, maxIdx);\n    if (ret != 0)\n        return ret;\n\n#ifndef NO_VERIFY_OID\n    actualOid = &input[idx];\n    if (length > 0)\n        actualOidSz = (word32)length;\n#endif /* NO_VERIFY_OID */\n\n    while (length--) {\n        /* odd HC08 compiler behavior here when input[idx++] */\n        *oid += (word32)input[idx];\n        idx++;\n    }\n    /* just sum it up for now */\n\n    *inOutIdx = idx;\n\n#ifndef NO_VERIFY_OID\n    {\n        const byte* checkOid = NULL;\n        word32 checkOidSz;\n    #ifdef ASN_DUMP_OID\n        word32 i;\n    #endif\n\n        if (oidType != oidIgnoreType) {\n            checkOid = OidFromId(*oid, oidType, &checkOidSz);\n\n        #ifdef ASN_DUMP_OID\n            /* support for dumping OID information */\n            printf(\"OID (Type %d, Sz %d, Sum %d): \", oidType, actualOidSz, *oid);\n            for (i=0; i<actualOidSz; i++) {\n                printf(\"%d, \", actualOid[i]);\n            }\n            printf(\"\\n\");\n            #ifdef HAVE_OID_DECODING\n            {\n                word16 decOid[16];\n                word32 decOidSz = sizeof(decOid);\n                ret = DecodeObjectId(actualOid, actualOidSz, decOid, &decOidSz);\n                if (ret == 0) {\n                    printf(\"  Decoded (Sz %d): \", decOidSz);\n                    for (i=0; i<decOidSz; i++) {\n                        printf(\"%d.\", decOid[i]);\n                    }\n                    printf(\"\\n\");\n                }\n                else {\n                    printf(\"DecodeObjectId failed: %d\\n\", ret);\n                }\n            }\n            #endif /* HAVE_OID_DECODING */\n        #endif /* ASN_DUMP_OID */\n\n            if (checkOid != NULL &&\n                (checkOidSz != actualOidSz ||\n                    XMEMCMP(actualOid, checkOid, checkOidSz) != 0)) {\n                WOLFSSL_MSG(\"OID Check Failed\");\n                return ASN_UNKNOWN_OID_E;\n            }\n        }\n    }\n#endif /* NO_VERIFY_OID */\n\n    return ret;\n}\n\nstatic int SkipObjectId(const byte* input, word32* inOutIdx, word32 maxIdx)\n{\n    word32 idx = *inOutIdx;\n    int    length;\n    int ret;\n\n    ret = GetASNObjectId(input, &idx, &length, maxIdx);\n    if (ret != 0)\n        return ret;\n\n    idx += length;\n    *inOutIdx = idx;\n\n    return 0;\n}\n\nWOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,\n                     word32 oidType, word32 maxIdx)\n{\n    int    length;\n    word32 idx = *inOutIdx;\n    int    ret;\n    *oid = 0;\n\n    WOLFSSL_ENTER(\"GetAlgoId\");\n\n    if (GetSequence(input, &idx, &length, maxIdx) < 0)\n        return ASN_PARSE_E;\n\n    if (GetObjectId(input, &idx, oid, oidType, maxIdx) < 0)\n        return ASN_OBJECT_ID_E;\n\n    /* could have NULL tag and 0 terminator, but may not */\n    if (idx < maxIdx) {\n        word32 localIdx = idx; /*use localIdx to not advance when checking tag*/\n        byte   tag;\n\n        if (GetASNTag(input, &localIdx, &tag, maxIdx) == 0) {\n            if (tag == ASN_TAG_NULL) {\n                ret = GetASNNull(input, &idx, maxIdx);\n                if (ret != 0)\n                    return ret;\n            }\n        }\n    }\n\n    *inOutIdx = idx;\n\n    return 0;\n}\n\n#ifndef NO_RSA\n\n#ifndef HAVE_USER_RSA\nint wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,\n                        word32 inSz)\n{\n    int version, length;\n\n    if (inOutIdx == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)\n        return ASN_PARSE_E;\n\n    key->type = RSA_PRIVATE;\n\n    if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||\n        GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n        GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||\n        GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||\n        GetInt(&key->q,  input, inOutIdx, inSz) < 0)\n#else\n        SkipInt(input, inOutIdx, inSz) < 0 ||\n        SkipInt(input, inOutIdx, inSz) < 0 ||\n        SkipInt(input, inOutIdx, inSz) < 0 )\n\n#endif\n            return ASN_RSA_KEY_E;\n#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)) \\\n    && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n    if (GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||\n        GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||\n        GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;\n#else\n    if (SkipInt(input, inOutIdx, inSz) < 0 ||\n        SkipInt(input, inOutIdx, inSz) < 0 ||\n        SkipInt(input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;\n#endif\n\n#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)\n    if (wc_InitRsaHw(key) != 0) {\n        return BAD_STATE_E;\n    }\n#endif\n\n    return 0;\n}\n#endif /* HAVE_USER_RSA */\n#endif /* NO_RSA */\n\n#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)\n\n/* Remove PKCS8 header, place inOutIdx at beginning of traditional,\n * return traditional length on success, negative on error */\nint ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,\n                           word32* algId)\n{\n    word32 idx;\n    int    version, length;\n    int    ret;\n    byte   tag;\n\n    if (input == NULL || inOutIdx == NULL)\n        return BAD_FUNC_ARG;\n\n    idx = *inOutIdx;\n\n    if (GetSequence(input, &idx, &length, sz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetMyVersion(input, &idx, &version, sz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetAlgoId(input, &idx, algId, oidKeyType, sz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetASNTag(input, &idx, &tag, sz) < 0)\n        return ASN_PARSE_E;\n    idx = idx - 1; /* reset idx after finding tag */\n\n    if (tag == ASN_OBJECT_ID) {\n        if (SkipObjectId(input, &idx, sz) < 0)\n            return ASN_PARSE_E;\n    }\n\n    ret = GetOctetString(input, &idx, &length, sz);\n    if (ret < 0)\n        return ret;\n\n    *inOutIdx = idx;\n\n    return length;\n}\n\nint ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)\n{\n    word32 oid;\n\n    return ToTraditionalInline_ex(input, inOutIdx, sz, &oid);\n}\n\n/* Remove PKCS8 header, move beginning of traditional to beginning of input */\nint ToTraditional_ex(byte* input, word32 sz, word32* algId)\n{\n    word32 inOutIdx = 0;\n    int    length;\n\n    if (input == NULL)\n        return BAD_FUNC_ARG;\n\n    length = ToTraditionalInline_ex(input, &inOutIdx, sz, algId);\n    if (length < 0)\n        return length;\n\n    XMEMMOVE(input, input + inOutIdx, length);\n\n    return length;\n}\n\nint ToTraditional(byte* input, word32 sz)\n{\n    word32 oid;\n\n    return ToTraditional_ex(input, sz, &oid);\n}\n\n#endif /* HAVE_PKCS8 || HAVE_PKCS12 */\n\n#ifdef HAVE_PKCS8\n\n/* find beginning of traditional key inside PKCS#8 unencrypted buffer\n * return traditional length on success, with inOutIdx at beginning of\n * traditional\n * return negative on failure/error */\nint wc_GetPkcs8TraditionalOffset(byte* input, word32* inOutIdx, word32 sz)\n{\n    int length;\n    word32 algId;\n\n    if (input == NULL || inOutIdx == NULL || (*inOutIdx > sz))\n        return BAD_FUNC_ARG;\n\n    length = ToTraditionalInline_ex(input, inOutIdx, sz, &algId);\n\n    return length;\n}\n\n\n/* PKCS#8 from RFC 5208\n * This function takes in a DER key and converts it to PKCS#8 format. Used\n * in creating PKCS#12 shrouded key bags.\n * Reverse of ToTraditional\n *\n * PrivateKeyInfo ::= SEQUENCE {\n *  version Version,\n *  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,\n *  privateKey          PrivateKey,\n *  attributes          optional\n *  }\n *  Version ::= INTEGER\n *  PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier\n *  PrivateKey ::= OCTET STRING\n *\n * out      buffer to place result in\n * outSz    size of out buffer\n * key      buffer with DER key\n * keySz    size of key buffer\n * algoID   algorithm ID i.e. RSAk\n * curveOID ECC curve oid if used. Should be NULL for RSA keys.\n * oidSz    size of curve oid. Is set to 0 if curveOID is NULL.\n *\n * Returns the size of PKCS#8 placed into out. In error cases returns negative\n * values.\n */\nint wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,\n        int algoID, const byte* curveOID, word32 oidSz)\n{\n        word32 keyIdx = 0;\n        word32 tmpSz  = 0;\n        word32 sz;\n\n\n        /* If out is NULL then return the max size needed\n         * + 2 for ASN_OBJECT_ID and ASN_OCTET_STRING tags */\n        if (out == NULL && outSz != NULL) {\n            *outSz = keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ\n                     + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2;\n\n            if (curveOID != NULL)\n                *outSz += oidSz + MAX_LENGTH_SZ + 1;\n\n            WOLFSSL_MSG(\"Checking size of PKCS8\");\n\n            return LENGTH_ONLY_E;\n        }\n\n        WOLFSSL_ENTER(\"wc_CreatePKCS8Key()\");\n\n        if (key == NULL || out == NULL || outSz == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n        /* check the buffer has enough room for largest possible size */\n        if (curveOID != NULL) {\n            if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ\n                   + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 3 + oidSz + MAX_LENGTH_SZ))\n                return BUFFER_E;\n        }\n        else {\n            oidSz = 0; /* with no curveOID oid size must be 0 */\n            if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ\n                      + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2))\n                return BUFFER_E;\n        }\n\n        /* PrivateKeyInfo ::= SEQUENCE */\n        keyIdx += MAX_SEQ_SZ; /* save room for sequence */\n\n        /*  version Version\n         *  no header information just INTEGER */\n        sz = SetMyVersion(PKCS8v0, out + keyIdx, 0);\n        tmpSz += sz; keyIdx += sz;\n\n        /*  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier */\n        sz = 0; /* set sz to 0 and get privateKey oid buffer size needed */\n        if (curveOID != NULL && oidSz > 0) {\n            byte buf[MAX_LENGTH_SZ];\n            sz = SetLength(oidSz, buf);\n            sz += 1; /* plus one for ASN object id */\n        }\n        sz = SetAlgoID(algoID, out + keyIdx, oidKeyType, oidSz + sz);\n        tmpSz += sz; keyIdx += sz;\n\n        /*  privateKey          PrivateKey *\n         * pkcs8 ecc uses slightly different format. Places curve oid in\n         * buffer */\n        if (curveOID != NULL && oidSz > 0) {\n            sz = SetObjectId(oidSz, out + keyIdx);\n            keyIdx += sz; tmpSz += sz;\n            XMEMCPY(out + keyIdx, curveOID, oidSz);\n            keyIdx += oidSz; tmpSz += oidSz;\n        }\n\n        sz = SetOctetString(keySz, out + keyIdx);\n        keyIdx += sz; tmpSz += sz;\n        XMEMCPY(out + keyIdx, key, keySz);\n        tmpSz += keySz;\n\n        /*  attributes          optional\n         * No attributes currently added */\n\n        /* rewind and add sequence */\n        sz = SetSequence(tmpSz, out);\n        XMEMMOVE(out + sz, out + MAX_SEQ_SZ, tmpSz);\n\n        return tmpSz + sz;\n}\n\n#endif /* HAVE_PKCS8 */\n\n#if defined(HAVE_PKCS12) || !defined(NO_CHECK_PRIVATE_KEY)\n/* check that the private key is a pair for the public key in certificate\n * return 1 (true) on match\n * return 0 or negative value on failure/error\n *\n * key   : buffer holding DER fromat key\n * keySz : size of key buffer\n * der   : a initialized and parsed DecodedCert holding a certificate */\nint wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)\n{\n    int ret;\n    (void)keySz;\n\n    if (key == NULL || der == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)\n    /* test if RSA key */\n    if (der->keyOID == RSAk) {\n    #ifdef WOLFSSL_SMALL_STACK\n        RsaKey* a = NULL;\n        RsaKey* b = NULL;\n    #else\n        RsaKey a[1], b[1];\n    #endif\n        word32 keyIdx = 0;\n\n    #ifdef WOLFSSL_SMALL_STACK\n        a = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);\n        if (a == NULL)\n            return MEMORY_E;\n        b = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);\n        if (b == NULL) {\n            XFREE(a, NULL, DYNAMIC_TYPE_RSA);\n            return MEMORY_E;\n        }\n    #endif\n\n        if ((ret = wc_InitRsaKey(a, NULL)) < 0) {\n    #ifdef WOLFSSL_SMALL_STACK\n            XFREE(b, NULL, DYNAMIC_TYPE_RSA);\n            XFREE(a, NULL, DYNAMIC_TYPE_RSA);\n    #endif\n            return ret;\n        }\n        if ((ret = wc_InitRsaKey(b, NULL)) < 0) {\n            wc_FreeRsaKey(a);\n    #ifdef WOLFSSL_SMALL_STACK\n            XFREE(b, NULL, DYNAMIC_TYPE_RSA);\n            XFREE(a, NULL, DYNAMIC_TYPE_RSA);\n    #endif\n            return ret;\n        }\n        if ((ret = wc_RsaPrivateKeyDecode(key, &keyIdx, a, keySz)) == 0) {\n            WOLFSSL_MSG(\"Checking RSA key pair\");\n            keyIdx = 0; /* reset to 0 for parsing public key */\n\n            if ((ret = wc_RsaPublicKeyDecode(der->publicKey, &keyIdx, b,\n                                                       der->pubKeySize)) == 0) {\n                /* limit for user RSA crypto because of RsaKey\n                 * dereference. */\n            #if defined(HAVE_USER_RSA)\n                WOLFSSL_MSG(\"Cannot verify RSA pair with user RSA\");\n                ret = 1; /* return first RSA cert as match */\n            #else\n                /* both keys extracted successfully now check n and e\n                 * values are the same. This is dereferencing RsaKey */\n                if (mp_cmp(&(a->n), &(b->n)) != MP_EQ ||\n                    mp_cmp(&(a->e), &(b->e)) != MP_EQ) {\n                    ret = MP_CMP_E;\n                }\n                else\n                    ret = 1;\n            #endif\n            }\n        }\n        wc_FreeRsaKey(b);\n        wc_FreeRsaKey(a);\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(b, NULL, DYNAMIC_TYPE_RSA);\n        XFREE(a, NULL, DYNAMIC_TYPE_RSA);\n    #endif\n    }\n    else\n    #endif /* !NO_RSA && !NO_ASN_CRYPT */\n\n    #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)\n    if (der->keyOID == ECDSAk) {\n    #ifdef WOLFSSL_SMALL_STACK\n        ecc_key* key_pair = NULL;\n        byte*    privDer;\n    #else\n        ecc_key  key_pair[1];\n        byte     privDer[MAX_ECC_BYTES];\n    #endif\n        word32   privSz = MAX_ECC_BYTES;\n        word32   keyIdx = 0;\n\n    #ifdef WOLFSSL_SMALL_STACK\n        key_pair = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);\n        if (key_pair == NULL)\n            return MEMORY_E;\n        privDer = (byte*)XMALLOC(MAX_ECC_BYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        if (privDer == NULL) {\n            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);\n            return MEMORY_E;\n        }\n    #endif\n\n        if ((ret = wc_ecc_init(key_pair)) < 0) {\n    #ifdef WOLFSSL_SMALL_STACK\n            XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);\n    #endif\n            return ret;\n        }\n\n        if ((ret = wc_EccPrivateKeyDecode(key, &keyIdx, key_pair,\n                                                                 keySz)) == 0) {\n            WOLFSSL_MSG(\"Checking ECC key pair\");\n\n            if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz))\n                                                                         == 0) {\n                wc_ecc_free(key_pair);\n                ret = wc_ecc_init(key_pair);\n                if (ret == 0) {\n                    ret = wc_ecc_import_private_key((const byte*)privDer,\n                                            privSz, (const byte*)der->publicKey,\n                                            der->pubKeySize, key_pair);\n                }\n\n                /* public and private extracted successfuly now check if is\n                 * a pair and also do sanity checks on key. wc_ecc_check_key\n                 * checks that private * base generator equals pubkey */\n                if (ret == 0) {\n                    if ((ret = wc_ecc_check_key(key_pair)) == 0) {\n                        ret = 1;\n                    }\n                }\n                ForceZero(privDer, privSz);\n            }\n        }\n        wc_ecc_free(key_pair);\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);\n    #endif\n    }\n    else\n    #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */\n\n    #if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT)\n    if (der->keyOID == ED25519k) {\n    #ifdef WOLFSSL_SMALL_STACK\n        ed25519_key* key_pair = NULL;\n    #else\n        ed25519_key  key_pair[1];\n    #endif\n        word32       keyIdx = 0;\n\n    #ifdef WOLFSSL_SMALL_STACK\n        key_pair = (ed25519_key*)XMALLOC(sizeof(ed25519_key), NULL,\n                                                          DYNAMIC_TYPE_ED25519);\n        if (key_pair == NULL)\n            return MEMORY_E;\n    #endif\n\n        if ((ret = wc_ed25519_init(key_pair)) < 0) {\n    #ifdef WOLFSSL_SMALL_STACK\n            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);\n    #endif\n            return ret;\n        }\n        if ((ret = wc_Ed25519PrivateKeyDecode(key, &keyIdx, key_pair,\n                                                                 keySz)) == 0) {\n            WOLFSSL_MSG(\"Checking ED25519 key pair\");\n            keyIdx = 0;\n            if ((ret = wc_ed25519_import_public(der->publicKey, der->pubKeySize,\n                                                              key_pair)) == 0) {\n                /* public and private extracted successfuly no check if is\n                 * a pair and also do sanity checks on key. wc_ecc_check_key\n                 * checks that private * base generator equals pubkey */\n                if ((ret = wc_ed25519_check_key(key_pair)) == 0)\n                    ret = 1;\n            }\n        }\n        wc_ed25519_free(key_pair);\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);\n    #endif\n    }\n    else\n    #endif /* HAVE_ED25519 && !NO_ASN_CRYPT */\n    {\n        ret = 0;\n    }\n\n    (void)keySz;\n\n    return ret;\n}\n\n#endif /* HAVE_PKCS12 || !NO_CHECK_PRIVATE_KEY */\n\n#ifndef NO_PWDBASED\n\n#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)\n/* Check To see if PKCS version algo is supported, set id if it is return 0\n   < 0 on error */\nstatic int CheckAlgo(int first, int second, int* id, int* version, int* blockSz)\n{\n    *id      = ALGO_ID_E;\n    *version = PKCS5;   /* default */\n    if (blockSz) *blockSz = 8; /* default */\n\n    if (first == 1) {\n        switch (second) {\n#if !defined(NO_SHA)\n    #ifndef NO_RC4\n        case PBE_SHA1_RC4_128:\n            *id = PBE_SHA1_RC4_128;\n            *version = PKCS12v1;\n            return 0;\n    #endif\n    #ifndef NO_DES3\n        case PBE_SHA1_DES3:\n            *id = PBE_SHA1_DES3;\n            *version = PKCS12v1;\n            if (blockSz) *blockSz = DES_BLOCK_SIZE;\n            return 0;\n    #endif\n#endif /* !NO_SHA */\n        default:\n            return ALGO_ID_E;\n        }\n    }\n\n    if (first != PKCS5)\n        return ASN_INPUT_E;  /* VERSION ERROR */\n\n    if (second == PBES2) {\n        *version = PKCS5v2;\n        return 0;\n    }\n\n    switch (second) {\n#ifndef NO_DES3\n    #ifndef NO_MD5\n    case 3:                   /* see RFC 2898 for ids */\n        *id = PBE_MD5_DES;\n        if (blockSz) *blockSz = DES_BLOCK_SIZE;\n        return 0;\n    #endif\n    #ifndef NO_SHA\n    case 10:\n        *id = PBE_SHA1_DES;\n        if (blockSz) *blockSz = DES_BLOCK_SIZE;\n        return 0;\n    #endif\n#endif /* !NO_DES3 */\n    default:\n        return ALGO_ID_E;\n\n    }\n}\n\n/* Check To see if PKCS v2 algo is supported, set id if it is return 0\n   < 0 on error */\nstatic int CheckAlgoV2(int oid, int* id, int* blockSz)\n{\n    if (blockSz) *blockSz = 8; /* default */\n    (void)id; /* not used if AES and DES3 disabled */\n    switch (oid) {\n#if !defined(NO_DES3) && !defined(NO_SHA)\n    case DESb:\n        *id = PBE_SHA1_DES;\n        if (blockSz) *blockSz = DES_BLOCK_SIZE;\n        return 0;\n    case DES3b:\n        *id = PBE_SHA1_DES3;\n        if (blockSz) *blockSz = DES_BLOCK_SIZE;\n        return 0;\n#endif\n#ifdef WOLFSSL_AES_256\n    case AES256CBCb:\n        *id = PBE_AES256_CBC;\n        if (blockSz) *blockSz = AES_BLOCK_SIZE;\n        return 0;\n#endif\n    default:\n        return ALGO_ID_E;\n\n    }\n}\n\n#endif /* HAVE_PKCS8 || HAVE_PKCS12 */\n\n#ifdef HAVE_PKCS8\n\nint wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,\n        int* algoID, void* heap)\n{\n    word32 tmpIdx = 0;\n\n    if (key == NULL || algoID == NULL)\n        return BAD_FUNC_ARG;\n\n    *algoID = 0;\n\n    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)\n    {\n        RsaKey rsa;\n\n        wc_InitRsaKey(&rsa, heap);\n        if (wc_RsaPrivateKeyDecode(key, &tmpIdx, &rsa, keySz) == 0) {\n            *algoID = RSAk;\n        }\n        else {\n            WOLFSSL_MSG(\"Not RSA DER key\");\n        }\n        wc_FreeRsaKey(&rsa);\n    }\n    #endif /* !NO_RSA && !NO_ASN_CRYPT */\n    #if defined(HAVE_ECC) && !defined(NO_ASN_CRYPT)\n    if (*algoID == 0) {\n        ecc_key ecc;\n\n        tmpIdx = 0;\n        wc_ecc_init_ex(&ecc, heap, INVALID_DEVID);\n        if (wc_EccPrivateKeyDecode(key, &tmpIdx, &ecc, keySz) == 0) {\n            *algoID = ECDSAk;\n\n            /* now find oid */\n            if (wc_ecc_get_oid(ecc.dp->oidSum, curveOID, oidSz) < 0) {\n                WOLFSSL_MSG(\"Error getting ECC curve OID\");\n                wc_ecc_free(&ecc);\n                return BAD_FUNC_ARG;\n            }\n        }\n        else {\n            WOLFSSL_MSG(\"Not ECC DER key either\");\n        }\n        wc_ecc_free(&ecc);\n    }\n#endif /* HAVE_ECC && !NO_ASN_CRYPT */\n#if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT)\n    if (*algoID != RSAk && *algoID != ECDSAk) {\n        ed25519_key ed25519;\n\n        tmpIdx = 0;\n        if (wc_ed25519_init(&ed25519) == 0) {\n            if (wc_Ed25519PrivateKeyDecode(key, &tmpIdx, &ed25519, keySz)\n                                                                         == 0) {\n                *algoID = ED25519k;\n            }\n            else {\n                WOLFSSL_MSG(\"Not ED25519 DER key\");\n            }\n            wc_ed25519_free(&ed25519);\n        }\n        else {\n            WOLFSSL_MSG(\"GetKeyOID wc_ed25519_init failed\");\n        }\n    }\n#endif /* HAVE_ED25519 && !NO_ASN_CRYPT */\n\n    /* if flag is not set then is neither RSA or ECC key that could be\n     * found */\n    if (*algoID == 0) {\n        WOLFSSL_MSG(\"Bad key DER or compile options\");\n        return BAD_FUNC_ARG;\n    }\n\n    (void)tmpIdx;\n    (void)curveOID;\n    (void)oidSz;\n    (void)keySz;\n    (void)heap;\n\n    return 1;\n}\n\n#endif /* HAVE_PKCS8 */\n\n#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)\n\n#define PKCS8_MIN_BLOCK_SIZE 8\nstatic int Pkcs8Pad(byte* buf, int sz, int blockSz)\n{\n    int i, padSz;\n\n    /* calculate pad size */\n    padSz = blockSz - (sz & (blockSz - 1));\n\n    /* pad with padSz value */\n    if (buf) {\n        for (i = 0; i < padSz; i++) {\n            buf[sz+i] = (byte)(padSz & 0xFF);\n        }\n    }\n\n    /* return adjusted length */\n    return sz + padSz;\n}\n\n#endif /* HAVE_PKCS8 || HAVE_PKCS12 */\n\n#ifdef HAVE_PKCS8\n\n/*\n * Used when creating PKCS12 shrouded key bags\n * vPKCS is the version of PKCS to use\n * vAlgo is the algorithm version to use\n *\n * if salt is NULL a random number is generated\n *\n * returns the size of encrypted data on success\n */\nint UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,\n        const char* password, int passwordSz, int vPKCS, int vAlgo,\n        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)\n{\n    int algoID = 0;\n    byte*  tmp;\n    word32 tmpSz = 0;\n    word32 sz;\n    word32 seqSz;\n    word32 inOutIdx = 0;\n    word32 totalSz = 0;\n    int    version, id;\n    int    ret;\n    int    blockSz = 0;\n\n    const byte* curveOID = NULL;\n    word32 oidSz   = 0;\n\n#ifdef WOLFSSL_SMALL_STACK\n    byte*  saltTmp = NULL;\n    byte*  cbcIv   = NULL;\n#else\n    byte   saltTmp[MAX_IV_SIZE];\n    byte   cbcIv[MAX_IV_SIZE];\n#endif\n\n    WOLFSSL_ENTER(\"UnTraditionalEnc()\");\n\n    if (saltSz > MAX_SALT_SIZE)\n        return ASN_PARSE_E;\n\n\n    inOutIdx += MAX_SEQ_SZ; /* leave room for size of finished shroud */\n    if (CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0) {\n        WOLFSSL_MSG(\"Bad/Unsupported algorithm ID\");\n        return ASN_INPUT_E;  /* Algo ID error */\n    }\n\n    if (out != NULL) {\n        if (*outSz < inOutIdx + MAX_ALGO_SZ + MAX_SALT_SIZE + MAX_SEQ_SZ + 1 +\n                MAX_LENGTH_SZ + MAX_SHORT_SZ + 1)\n                return BUFFER_E;\n\n        if (version == PKCS5v2) {\n            WOLFSSL_MSG(\"PKCS5v2 Not supported yet\\n\");\n            return ASN_VERSION_E;\n        }\n\n        if (salt == NULL || saltSz <= 0) {\n            saltSz = 8;\n        #ifdef WOLFSSL_SMALL_STACK\n            saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);\n            if (saltTmp == NULL)\n                return MEMORY_E;\n        #endif\n            salt = saltTmp;\n\n            if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {\n                WOLFSSL_MSG(\"Error generating random salt\");\n            #ifdef WOLFSSL_SMALL_STACK\n                if (saltTmp != NULL)\n                    XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n            #endif\n                return ret;\n            }\n        }\n\n\n        /* leave room for a sequence (contains salt and iterations int) */\n        inOutIdx += MAX_SEQ_SZ; sz = 0;\n        inOutIdx += MAX_ALGO_SZ;\n\n        /* place salt in buffer */\n        out[inOutIdx++] = ASN_OCTET_STRING; sz++;\n        tmpSz = SetLength(saltSz, out + inOutIdx);\n        inOutIdx += tmpSz; sz += tmpSz;\n        XMEMCPY(out + inOutIdx, salt, saltSz);\n        inOutIdx += saltSz; sz += saltSz;\n\n        /* place iteration count in buffer */\n        ret = SetShortInt(out, &inOutIdx, itt, *outSz);\n        if (ret < 0) {\n            return ret;\n        }\n        sz += (word32)ret;\n\n        /* wind back index and set sequence then clean up buffer */\n        inOutIdx -= (sz + MAX_SEQ_SZ);\n        tmpSz = SetSequence(sz, out + inOutIdx);\n        XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_SEQ_SZ, sz);\n        totalSz += tmpSz + sz; sz += tmpSz;\n\n        /* add in algo ID */\n        inOutIdx -= MAX_ALGO_SZ;\n        tmpSz =  SetAlgoID(id, out + inOutIdx, oidPBEType, sz);\n        XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_ALGO_SZ, sz);\n        totalSz += tmpSz; inOutIdx += tmpSz + sz;\n\n        /* octet string containing encrypted key */\n        out[inOutIdx++] = ASN_OCTET_STRING; totalSz++;\n    }\n\n    /* check key type and get OID if ECC */\n    if ((ret = wc_GetKeyOID(key, keySz, &curveOID, &oidSz, &algoID, heap))< 0) {\n            return ret;\n    }\n\n    /* PKCS#8 wrapping around key */\n    if (wc_CreatePKCS8Key(NULL, &tmpSz, key, keySz, algoID, curveOID, oidSz)\n            != LENGTH_ONLY_E) {\n    #ifdef WOLFSSL_SMALL_STACK\n        if (saltTmp != NULL)\n            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        return MEMORY_E;\n    }\n\n    /* check if should return max size */\n    if (out == NULL) {\n        /* account for salt size */\n        if (salt == NULL || saltSz <= 0) {\n            tmpSz += MAX_SALT_SIZE;\n        }\n        else {\n            tmpSz += saltSz;\n        }\n\n        /* plus 3 for tags */\n        *outSz = tmpSz + MAX_ALGO_SZ + MAX_LENGTH_SZ +MAX_LENGTH_SZ + MAX_SEQ_SZ\n            + MAX_LENGTH_SZ + MAX_SEQ_SZ + 3;\n        return LENGTH_ONLY_E;\n    }\n\n    /* reserve buffer for crypto and make sure it supports full blocks */\n    tmp = (byte*)XMALLOC(tmpSz + (blockSz-1), heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (tmp == NULL) {\n    #ifdef WOLFSSL_SMALL_STACK\n        if (saltTmp != NULL)\n            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        return MEMORY_E;\n    }\n\n    if ((ret = wc_CreatePKCS8Key(tmp, &tmpSz, key, keySz, algoID, curveOID,\n                    oidSz)) < 0) {\n        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        WOLFSSL_MSG(\"Error wrapping key with PKCS#8\");\n    #ifdef WOLFSSL_SMALL_STACK\n        if (saltTmp != NULL)\n            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        return ret;\n    }\n    tmpSz = ret;\n\n    /* adjust size to pad */\n    tmpSz = Pkcs8Pad(tmp, tmpSz, blockSz);\n\n#ifdef WOLFSSL_SMALL_STACK\n    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (cbcIv == NULL) {\n        if (saltTmp != NULL)\n            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(salt, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n#endif\n\n    /* encrypt PKCS#8 wrapped key */\n    if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,\n               tmp, tmpSz, version, cbcIv, 1)) < 0) {\n        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        WOLFSSL_MSG(\"Error encrypting key\");\n    #ifdef WOLFSSL_SMALL_STACK\n        if (saltTmp != NULL)\n            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (cbcIv != NULL)\n            XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        return ret;  /* encryption failure */\n    }\n    totalSz += tmpSz;\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (saltTmp != NULL)\n        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (cbcIv != NULL)\n        XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    if (*outSz < inOutIdx + tmpSz + MAX_LENGTH_SZ) {\n        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return BUFFER_E;\n    }\n\n    /* set length of key and copy over encrypted key */\n    seqSz = SetLength(tmpSz, out + inOutIdx);\n    inOutIdx += seqSz; totalSz += seqSz;\n    XMEMCPY(out + inOutIdx, tmp, tmpSz);\n    XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    /* set total size at beginning */\n    sz = SetSequence(totalSz, out);\n    XMEMMOVE(out + sz, out + MAX_SEQ_SZ, totalSz);\n\n    (void)rng;\n\n    return totalSz + sz;\n}\n\nstatic int GetAlgoV2(int encAlgId, const byte** oid, int *len, int* id,\n                     int *blkSz)\n{\n    int ret = 0;\n\n    switch (encAlgId) {\n#if !defined(NO_DES3) && !defined(NO_SHA)\n    case DESb:\n        *len = sizeof(blkDesCbcOid);\n        *oid = blkDesCbcOid;\n        *id = PBE_SHA1_DES;\n        *blkSz = 8;\n        break;\n    case DES3b:\n        *len = sizeof(blkDes3CbcOid);\n        *oid = blkDes3CbcOid;\n        *id = PBE_SHA1_DES3;\n        *blkSz = 8;\n        break;\n#endif\n#if defined(WOLFSSL_AES_256) && defined(HAVE_AES_CBC)\n    case AES256CBCb:\n        *len = sizeof(blkAes256CbcOid);\n        *oid = blkAes256CbcOid;\n        *id = PBE_AES256_CBC;\n        *blkSz = 16;\n        break;\n#endif\n    default:\n        (void)len;\n        (void)oid;\n        (void)id;\n        (void)blkSz;\n        ret = ALGO_ID_E;\n    }\n\n    return ret;\n}\n\n/* Converts Encrypted PKCS#8 to 'traditional' (i.e. PKCS#8 removed from\n * decrypted key.)\n */\nint TraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,\n        const char* password, int passwordSz, int vPKCS, int vAlgo,\n        int encAlgId, byte* salt, word32 saltSz, int itt, WC_RNG* rng,\n        void* heap)\n{\n    int ret = 0;\n    int version, blockSz, id;\n    word32 idx = 0, encIdx;\n#ifdef WOLFSSL_SMALL_STACK\n    byte* saltTmp = NULL;\n#else\n    byte saltTmp[MAX_SALT_SIZE];\n#endif\n    byte cbcIv[MAX_IV_SIZE];\n    byte *pkcs8Key = NULL;\n    word32 pkcs8KeySz = 0, padSz = 0;\n    int algId = 0;\n    const byte* curveOid = NULL;\n    word32 curveOidSz = 0;\n    const byte* pbeOid = NULL;\n    word32 pbeOidSz = 0;\n    const byte* encOid = NULL;\n    int encOidSz = 0;\n    word32 pbeLen = 0, kdfLen = 0, encLen = 0;\n    word32 innerLen = 0, outerLen;\n\n    ret = CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz);\n    /* create random salt if one not provided */\n    if (ret == 0 && (salt == NULL || saltSz <= 0)) {\n        saltSz = 8;\n    #ifdef WOLFSSL_SMALL_STACK\n        saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (saltTmp == NULL)\n            return MEMORY_E;\n    #endif\n        salt = saltTmp;\n\n        if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {\n            WOLFSSL_MSG(\"Error generating random salt\");\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n            return ret;\n        }\n    }\n\n    if (ret == 0) {\n        /* check key type and get OID if ECC */\n        ret = wc_GetKeyOID(key, keySz, &curveOid, &curveOidSz, &algId, heap);\n        if (ret == 1)\n            ret = 0;\n    }\n    if (ret == 0) {\n        ret = wc_CreatePKCS8Key(NULL, &pkcs8KeySz, key, keySz, algId, curveOid,\n                                                                    curveOidSz);\n        if (ret == LENGTH_ONLY_E)\n            ret = 0;\n    }\n    if (ret == 0) {\n        pkcs8Key = (byte*)XMALLOC(pkcs8KeySz, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        if (pkcs8Key == NULL)\n            ret = MEMORY_E;\n    }\n    if (ret == 0) {\n        ret = wc_CreatePKCS8Key(pkcs8Key, &pkcs8KeySz, key, keySz, algId,\n                                                          curveOid, curveOidSz);\n        if (ret >= 0) {\n            pkcs8KeySz = ret;\n            ret = 0;\n        }\n    }\n\n    if (ret == 0 && version == PKCS5v2)\n        ret = GetAlgoV2(encAlgId, &encOid, &encOidSz, &id, &blockSz);\n\n    if (ret == 0) {\n        padSz = (blockSz - (pkcs8KeySz & (blockSz - 1))) & (blockSz - 1);\n        /* inner = OCT salt INT itt */\n        innerLen = 2 + saltSz + 2 + (itt < 256 ? 1 : 2);\n\n        if (version != PKCS5v2) {\n            pbeOid = OidFromId(id, oidPBEType, &pbeOidSz);\n            /* pbe = OBJ pbse1 SEQ [ inner ] */\n            pbeLen = 2 + pbeOidSz + 2 + innerLen;\n        }\n        else {\n            pbeOid = pbes2;\n            pbeOidSz = sizeof(pbes2);\n            /* kdf = OBJ pbkdf2 [ SEQ innerLen ] */\n            kdfLen = 2 + sizeof(pbkdf2Oid) + 2 + innerLen;\n            /* enc = OBJ enc_alg OCT iv */\n            encLen = 2 + encOidSz + 2 + blockSz;\n            /* pbe = OBJ pbse2 SEQ [ SEQ [ kdf ] SEQ [ enc ] ] */\n            pbeLen = 2 + sizeof(pbes2) + 2 + 2 + kdfLen + 2 + encLen;\n\n            ret = wc_RNG_GenerateBlock(rng, cbcIv, blockSz);\n        }\n    }\n    if (ret == 0) {\n        /* outer = SEQ [ pbe ] OCT encrypted_PKCS#8_key */\n        outerLen = 2 + pbeLen;\n        outerLen += SetOctetString(pkcs8KeySz + padSz, out);\n        outerLen += pkcs8KeySz + padSz;\n\n        idx += SetSequence(outerLen, out + idx);\n\n        encIdx = idx + outerLen - pkcs8KeySz - padSz;\n        /* Put Encrypted content in place. */\n        XMEMCPY(out + encIdx, pkcs8Key, pkcs8KeySz);\n        if (padSz > 0) {\n            XMEMSET(out + encIdx + pkcs8KeySz, padSz, padSz);\n            pkcs8KeySz += padSz;\n        }\n        ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,\n                                   out + encIdx, pkcs8KeySz, version, cbcIv, 1);\n    }\n    if (ret == 0) {\n        if (version != PKCS5v2) {\n            /* PBE algorithm */\n            idx += SetSequence(pbeLen, out + idx);\n            idx += SetObjectId(pbeOidSz, out + idx);\n            XMEMCPY(out + idx, pbeOid, pbeOidSz);\n            idx += pbeOidSz;\n        }\n        else {\n            /* PBES2 algorithm identifier */\n            idx += SetSequence(pbeLen, out + idx);\n            idx += SetObjectId(pbeOidSz, out + idx);\n            XMEMCPY(out + idx, pbeOid, pbeOidSz);\n            idx += pbeOidSz;\n            /* PBES2 Parameters: SEQ [ kdf ] SEQ [ enc ] */\n            idx += SetSequence(2 + kdfLen + 2 + encLen, out + idx);\n            /* KDF Algorithm Identifier */\n            idx += SetSequence(kdfLen, out + idx);\n            idx += SetObjectId(sizeof(pbkdf2Oid), out + idx);\n            XMEMCPY(out + idx, pbkdf2Oid, sizeof(pbkdf2Oid));\n            idx += sizeof(pbkdf2Oid);\n        }\n        idx += SetSequence(innerLen, out + idx);\n        idx += SetOctetString(saltSz, out + idx);\n        XMEMCPY(out + idx, salt, saltSz); idx += saltSz;\n        ret = SetShortInt(out, &idx, itt, *outSz);\n        if (ret > 0)\n            ret = 0;\n    }\n    if (ret == 0) {\n        if (version == PKCS5v2) {\n            /* Encryption Algorithm Identifier */\n            idx += SetSequence(encLen, out + idx);\n            idx += SetObjectId(encOidSz, out + idx);\n            XMEMCPY(out + idx, encOid, encOidSz);\n            idx += encOidSz;\n            /* Encryption Algorithm Parameter: CBC IV */\n            idx += SetOctetString(blockSz, out + idx);\n            XMEMCPY(out + idx, cbcIv, blockSz);\n            idx += blockSz;\n        }\n        idx += SetOctetString(pkcs8KeySz, out + idx);\n        /* Default PRF - no need to write out OID */\n        idx += pkcs8KeySz;\n\n        ret = idx;\n    }\n\n    if (pkcs8Key != NULL) {\n        ForceZero(pkcs8Key, pkcs8KeySz);\n        XFREE(pkcs8Key, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#ifdef WOLFSSL_SMALL_STACK\n    if (saltTmp != NULL) {\n        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    (void)rng;\n\n    return ret;\n}\n\n#endif /* HAVE_PKCS8 */\n\n#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)\n\n/* Remove Encrypted PKCS8 header, move beginning of traditional to beginning\n   of input */\nint ToTraditionalEnc(byte* input, word32 sz,const char* password,\n                     int passwordSz, word32* algId)\n{\n    word32 inOutIdx = 0, seqEnd, oid;\n    int    ret = 0, first, second, length = 0, version, saltSz, id;\n    int    iterations = 0, keySz = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    byte*  salt = NULL;\n    byte*  cbcIv = NULL;\n#else\n    byte   salt[MAX_SALT_SIZE];\n    byte   cbcIv[MAX_IV_SIZE];\n#endif\n\n    if (passwordSz < 0) {\n        WOLFSSL_MSG(\"Bad password size\");\n        return BAD_FUNC_ARG;\n    }\n\n    if (GetSequence(input, &inOutIdx, &length, sz) < 0) {\n        ERROR_OUT(ASN_PARSE_E, exit_tte);\n    }\n\n    if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {\n        ERROR_OUT(ASN_PARSE_E, exit_tte);\n    }\n\n    first  = input[inOutIdx - 2];   /* PKCS version always 2nd to last byte */\n    second = input[inOutIdx - 1];   /* version.algo, algo id last byte */\n\n    if (CheckAlgo(first, second, &id, &version, NULL) < 0) {\n        ERROR_OUT(ASN_INPUT_E, exit_tte); /* Algo ID error */\n    }\n\n    if (version == PKCS5v2) {\n        if (GetSequence(input, &inOutIdx, &length, sz) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_tte);\n        }\n\n        if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_tte);\n        }\n\n        if (oid != PBKDF2_OID) {\n            ERROR_OUT(ASN_PARSE_E, exit_tte);\n        }\n    }\n\n    if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {\n        ERROR_OUT(ASN_PARSE_E, exit_tte);\n    }\n    /* Find the end of this SEQUENCE so we can check for the OPTIONAL and\n     * DEFAULT items. */\n    seqEnd = inOutIdx + length;\n\n    ret = GetOctetString(input, &inOutIdx, &saltSz, sz);\n    if (ret < 0)\n        goto exit_tte;\n\n    if (saltSz > MAX_SALT_SIZE) {\n        ERROR_OUT(ASN_PARSE_E, exit_tte);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (salt == NULL) {\n        ERROR_OUT(MEMORY_E, exit_tte);\n    }\n#endif\n\n    XMEMCPY(salt, &input[inOutIdx], saltSz);\n    inOutIdx += saltSz;\n\n    if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {\n        ERROR_OUT(ASN_PARSE_E, exit_tte);\n    }\n\n    /* OPTIONAL key length */\n    if (seqEnd > inOutIdx) {\n        word32 localIdx = inOutIdx;\n        byte tag;\n\n        if (GetASNTag(input, &localIdx, &tag, sz) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_tte);\n        }\n\n        if (tag == ASN_INTEGER &&\n                GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_tte);\n        }\n    }\n\n    /* DEFAULT HMAC is SHA-1 */\n    if (seqEnd > inOutIdx) {\n        if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_tte);\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (cbcIv == NULL) {\n        ERROR_OUT(MEMORY_E, exit_tte);\n    }\n#endif\n\n    if (version == PKCS5v2) {\n        /* get encryption algo */\n        if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_tte);\n        }\n\n        if (CheckAlgoV2(oid, &id, NULL) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_tte); /* PKCS v2 algo id error */\n        }\n\n        ret = GetOctetString(input, &inOutIdx, &length, sz);\n        if (ret < 0)\n            goto exit_tte;\n\n        if (length > MAX_IV_SIZE) {\n            ERROR_OUT(ASN_PARSE_E, exit_tte);\n        }\n\n        XMEMCPY(cbcIv, &input[inOutIdx], length);\n        inOutIdx += length;\n    }\n\n    ret = GetOctetString(input, &inOutIdx, &length, sz);\n    if (ret < 0)\n        goto exit_tte;\n\n    ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,\n                   input + inOutIdx, length, version, cbcIv, 0);\n\nexit_tte:\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    if (ret == 0) {\n        XMEMMOVE(input, input + inOutIdx, length);\n        ret = ToTraditional_ex(input, length, algId);\n    }\n\n    return ret;\n}\n\n#endif /* HAVE_PKCS8 || HAVE_PKCS12 */\n\n#ifdef HAVE_PKCS12\n\n/* encrypt PKCS 12 content\n *\n * NOTE: if out is NULL then outSz is set with the total buffer size needed and\n *       the error value LENGTH_ONLY_E is returned.\n *\n * input      data to encrypt\n * inputSz    size of input buffer\n * out        buffer to hold the result\n * outSz      size of out buffer\n * password   password if used. Can be NULL for no password\n * passwordSz size of password buffer\n * vPKCS      version of PKCS i.e. PKCS5v2\n * vAlgo      algorithm version\n * salt       buffer holding salt if used. If NULL then a random salt is created\n * saltSz     size of salt buffer if it is not NULL\n * itt        number of iterations used\n * rng        random number generator to use\n * heap       possible heap hint for mallocs/frees\n *\n * returns the total size of encrypted content on success.\n */\nint EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,\n        const char* password, int passwordSz, int vPKCS, int vAlgo,\n        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)\n{\n    word32 sz;\n    word32 inOutIdx = 0;\n    word32 tmpIdx   = 0;\n    word32 totalSz  = 0;\n    word32 seqSz;\n    int    ret;\n    int    version, id, blockSz = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    byte*  saltTmp = NULL;\n    byte*  cbcIv   = NULL;\n#else\n    byte   saltTmp[MAX_SALT_SIZE];\n    byte   cbcIv[MAX_IV_SIZE];\n#endif\n\n    (void)heap;\n\n    WOLFSSL_ENTER(\"EncryptContent()\");\n\n    if (CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0)\n        return ASN_INPUT_E;  /* Algo ID error */\n\n    if (version == PKCS5v2) {\n        WOLFSSL_MSG(\"PKCS#5 version 2 not supported yet\");\n        return BAD_FUNC_ARG;\n    }\n\n    if (saltSz > MAX_SALT_SIZE)\n        return ASN_PARSE_E;\n\n    if (outSz == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (out == NULL) {\n        sz = inputSz;\n        switch (id) {\n        #if !defined(NO_DES3) && (!defined(NO_MD5) || !defined(NO_SHA))\n            case PBE_MD5_DES:\n            case PBE_SHA1_DES:\n            case PBE_SHA1_DES3:\n                /* set to block size of 8 for DES operations. This rounds up\n                 * to the nearest multiple of 8 */\n                sz &= 0xfffffff8;\n                sz += 8;\n                break;\n        #endif /* !NO_DES3 && (!NO_MD5 || !NO_SHA) */\n        #if !defined(NO_RC4) && !defined(NO_SHA)\n            case PBE_SHA1_RC4_128:\n                break;\n        #endif\n            case -1:\n                break;\n\n            default:\n                return ALGO_ID_E;\n        }\n\n        if (saltSz <= 0) {\n            sz += MAX_SALT_SIZE;\n        }\n        else {\n            sz += saltSz;\n        }\n\n        /* add 2 for tags */\n        totalSz = sz + MAX_ALGO_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ +\n            MAX_LENGTH_SZ + MAX_LENGTH_SZ + MAX_SHORT_SZ + 2;\n\n        /* adjust size to pad */\n        totalSz = Pkcs8Pad(NULL, totalSz, blockSz);\n\n        /* return result */\n        *outSz = totalSz;\n\n        return LENGTH_ONLY_E;\n    }\n\n    if (inOutIdx + MAX_ALGO_SZ + MAX_SEQ_SZ + 1 > *outSz)\n        return BUFFER_E;\n\n    sz = SetAlgoID(id, out + inOutIdx, oidPBEType, 0);\n    inOutIdx += sz; totalSz += sz;\n    tmpIdx = inOutIdx;\n    tmpIdx += MAX_SEQ_SZ; /* save room for salt and itter sequence */\n    out[tmpIdx++] = ASN_OCTET_STRING;\n\n    /* create random salt if one not provided */\n    if (salt == NULL || saltSz <= 0) {\n        saltSz = 8;\n    #ifdef WOLFSSL_SMALL_STACK\n        saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (saltTmp == NULL)\n            return MEMORY_E;\n    #endif\n        salt = saltTmp;\n\n        if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {\n            WOLFSSL_MSG(\"Error generating random salt\");\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n            return ret;\n        }\n    }\n\n    if (tmpIdx + MAX_LENGTH_SZ + saltSz + MAX_SHORT_SZ > *outSz) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        return BUFFER_E;\n    }\n\n    sz = SetLength(saltSz, out + tmpIdx);\n    tmpIdx += sz;\n\n    XMEMCPY(out + tmpIdx, salt, saltSz);\n    tmpIdx += saltSz;\n\n    /* place iteration setting in buffer */\n    ret = SetShortInt(out, &tmpIdx, itt, *outSz);\n    if (ret < 0) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        return ret;\n    }\n\n    /* rewind and place sequence */\n    sz = tmpIdx - inOutIdx - MAX_SEQ_SZ;\n    seqSz = SetSequence(sz, out + inOutIdx);\n    XMEMMOVE(out + inOutIdx + seqSz, out + inOutIdx + MAX_SEQ_SZ, sz);\n    inOutIdx += seqSz; totalSz += seqSz;\n    inOutIdx += sz; totalSz += sz;\n\n#ifdef WOLFSSL_SMALL_STACK\n    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (cbcIv == NULL) {\n        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n#endif\n\n    if (inOutIdx + 1 + MAX_LENGTH_SZ + inputSz > *outSz)\n        return BUFFER_E;\n\n    out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0; totalSz++;\n    sz = SetLength(inputSz, out + inOutIdx);\n    inOutIdx += sz; totalSz += sz;\n\n    /* get pad size and verify buffer room */\n    sz = Pkcs8Pad(NULL, inputSz, blockSz);\n    if (sz + inOutIdx > *outSz)\n        return BUFFER_E;\n\n    /* copy input to output buffer and pad end */\n    XMEMCPY(out + inOutIdx, input, inputSz);\n    sz = Pkcs8Pad(out + inOutIdx, inputSz, blockSz);\n    totalSz += sz;\n\n    /* encrypt */\n    if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,\n                   out + inOutIdx, sz, version, cbcIv, 1)) < 0) {\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        return ret;  /* encrypt failure */\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    (void)rng;\n\n    return totalSz;\n}\n\n\n/* decrypt PKCS\n *\n * NOTE: input buffer is overwritten with decrypted data!\n *\n * input[in/out] data to decrypt and results are written to\n * sz            size of input buffer\n * password      password if used. Can be NULL for no password\n * passwordSz    size of password buffer\n *\n * returns the total size of decrypted content on success.\n */\nint DecryptContent(byte* input, word32 sz,const char* password, int passwordSz)\n{\n    word32 inOutIdx = 0, seqEnd, oid;\n    int    ret = 0;\n    int    first, second, length = 0, version, saltSz, id;\n    int    iterations = 0, keySz = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    byte*  salt = NULL;\n    byte*  cbcIv = NULL;\n#else\n    byte   salt[MAX_SALT_SIZE];\n    byte   cbcIv[MAX_IV_SIZE];\n#endif\n    byte   tag;\n\n    if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {\n        ERROR_OUT(ASN_PARSE_E, exit_dc);\n    }\n\n    first  = input[inOutIdx - 2];   /* PKCS version always 2nd to last byte */\n    second = input[inOutIdx - 1];   /* version.algo, algo id last byte */\n\n    if (CheckAlgo(first, second, &id, &version, NULL) < 0) {\n        ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */\n    }\n\n    if (version == PKCS5v2) {\n        if (GetSequence(input, &inOutIdx, &length, sz) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_dc);\n        }\n\n        if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_dc);\n        }\n\n        if (oid != PBKDF2_OID) {\n            ERROR_OUT(ASN_PARSE_E, exit_dc);\n        }\n    }\n\n    if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {\n        ERROR_OUT(ASN_PARSE_E, exit_dc);\n    }\n    /* Find the end of this SEQUENCE so we can check for the OPTIONAL and\n     * DEFAULT items. */\n    seqEnd = inOutIdx + length;\n\n    ret = GetOctetString(input, &inOutIdx, &saltSz, sz);\n    if (ret < 0)\n        goto exit_dc;\n\n    if (saltSz > MAX_SALT_SIZE) {\n        ERROR_OUT(ASN_PARSE_E, exit_dc);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (salt == NULL) {\n        ERROR_OUT(MEMORY_E, exit_dc);\n    }\n#endif\n\n    XMEMCPY(salt, &input[inOutIdx], saltSz);\n    inOutIdx += saltSz;\n\n    if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {\n        ERROR_OUT(ASN_PARSE_E, exit_dc);\n    }\n\n    /* OPTIONAL key length */\n    if (seqEnd > inOutIdx) {\n        word32 localIdx = inOutIdx;\n\n        if (GetASNTag(input, &localIdx, &tag, sz) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_dc);\n        }\n\n        if (tag == ASN_INTEGER &&\n                GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_dc);\n        }\n    }\n\n    /* DEFAULT HMAC is SHA-1 */\n    if (seqEnd > inOutIdx) {\n        if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_dc);\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (cbcIv == NULL) {\n        ERROR_OUT(MEMORY_E, exit_dc);\n    }\n#endif\n\n    if (version == PKCS5v2) {\n        /* get encryption algo */\n        if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_dc);\n        }\n\n        if (CheckAlgoV2(oid, &id, NULL) < 0) {\n            ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */\n        }\n\n        ret = GetOctetString(input, &inOutIdx, &length, sz);\n        if (ret < 0)\n            goto exit_dc;\n\n        if (length > MAX_IV_SIZE) {\n            ERROR_OUT(ASN_PARSE_E, exit_dc);\n        }\n\n        XMEMCPY(cbcIv, &input[inOutIdx], length);\n        inOutIdx += length;\n    }\n\n    if (GetASNTag(input, &inOutIdx, &tag, sz) < 0) {\n        ERROR_OUT(ASN_PARSE_E, exit_dc);\n    }\n\n    if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {\n        ERROR_OUT(ASN_PARSE_E, exit_dc);\n    }\n\n    if (GetLength(input, &inOutIdx, &length, sz) < 0) {\n        ERROR_OUT(ASN_PARSE_E, exit_dc);\n    }\n\n    ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,\n                   input + inOutIdx, length, version, cbcIv, 0);\n\nexit_dc:\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    if (ret == 0) {\n        XMEMMOVE(input, input + inOutIdx, length);\n        ret = length;\n    }\n\n    return ret;\n}\n#endif /* HAVE_PKCS12 */\n#endif /* NO_PWDBASED */\n\n#ifndef NO_RSA\n\n#ifndef HAVE_USER_RSA\n#ifdef WOLFSSL_RENESAS_TSIP\n/* This function is to retrieve key position information in a cert.*\n * The information will be used to call TSIP TLS-linked API for    *\n * certificate verification.                                       */\nstatic int RsaPublicKeyDecodeRawIndex(const byte* input, word32* inOutIdx,\n                                      word32 inSz, word32* key_n,\n                                      word32* key_n_len, word32* key_e,\n                                      word32* key_e_len)\n{\n\n    int ret = 0;\n    int length = 0;\n#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)\n    byte b;\n#endif\n\n    if (input == NULL || inOutIdx == NULL)\n        return BAD_FUNC_ARG;\n\n    if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n        return ASN_PARSE_E;\n\n#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)\n    if ((*inOutIdx + 1) > inSz)\n        return BUFFER_E;\n\n    b = input[*inOutIdx];\n    if (b != ASN_INTEGER) {\n        /* not from decoded cert, will have algo id, skip past */\n        if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n            return ASN_PARSE_E;\n\n        if (SkipObjectId(input, inOutIdx, inSz) < 0)\n            return ASN_PARSE_E;\n\n        /* Option NULL ASN.1 tag */\n        if (*inOutIdx  >= inSz) {\n            return BUFFER_E;\n        }\n        if (input[*inOutIdx] == ASN_TAG_NULL) {\n            ret = GetASNNull(input, inOutIdx, inSz);\n            if (ret != 0)\n                return ret;\n        }\n\n        /* should have bit tag length and seq next */\n        ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);\n        if (ret != 0)\n            return ret;\n\n        if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n            return ASN_PARSE_E;\n    }\n#endif /* OPENSSL_EXTRA */\n\n    /* Get modulus */\n    ret = GetASNInt(input, inOutIdx, &length, inSz);\n    *key_n += *inOutIdx;\n    if (ret < 0) {\n        return ASN_RSA_KEY_E;\n    }\n    if (key_n_len)\n        *key_n_len = length;\n    *inOutIdx += length;\n\n    /* Get exponent */\n    ret = GetASNInt(input, inOutIdx, &length, inSz);\n    *key_e += *inOutIdx;\n    if (ret < 0) {\n        return ASN_RSA_KEY_E;\n    }\n    if (key_e_len)\n        *key_e_len = length;\n\n    return ret;\n}\n#endif /* WOLFSSL_RENESAS_TSIP */\n\nint wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,\n    const byte** n, word32* nSz, const byte** e, word32* eSz)\n{\n    int ret = 0;\n    int length = 0;\n#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)\n    word32 localIdx;\n    byte   tag;\n#endif\n\n    if (input == NULL || inOutIdx == NULL)\n        return BAD_FUNC_ARG;\n\n    if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n        return ASN_PARSE_E;\n\n#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)\n    localIdx = *inOutIdx;\n    if (GetASNTag(input, &localIdx, &tag, inSz) < 0)\n        return BUFFER_E;\n\n    if (tag != ASN_INTEGER) {\n        /* not from decoded cert, will have algo id, skip past */\n        if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n            return ASN_PARSE_E;\n\n        if (SkipObjectId(input, inOutIdx, inSz) < 0)\n            return ASN_PARSE_E;\n\n        /* Option NULL ASN.1 tag */\n        if (*inOutIdx  >= inSz) {\n            return BUFFER_E;\n        }\n\n        localIdx = *inOutIdx;\n        if (GetASNTag(input, &localIdx, &tag, inSz) < 0)\n            return ASN_PARSE_E;\n\n        if (tag == ASN_TAG_NULL) {\n            ret = GetASNNull(input, inOutIdx, inSz);\n            if (ret != 0)\n                return ret;\n        }\n\n        /* should have bit tag length and seq next */\n        ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);\n        if (ret != 0)\n            return ret;\n\n        if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n            return ASN_PARSE_E;\n    }\n#endif /* OPENSSL_EXTRA */\n\n    /* Get modulus */\n    ret = GetASNInt(input, inOutIdx, &length, inSz);\n    if (ret < 0) {\n        return ASN_RSA_KEY_E;\n    }\n    if (nSz)\n        *nSz = length;\n    if (n)\n        *n = &input[*inOutIdx];\n    *inOutIdx += length;\n\n    /* Get exponent */\n    ret = GetASNInt(input, inOutIdx, &length, inSz);\n    if (ret < 0) {\n        return ASN_RSA_KEY_E;\n    }\n    if (eSz)\n        *eSz = length;\n    if (e)\n        *e = &input[*inOutIdx];\n    *inOutIdx += length;\n\n    return ret;\n}\n\nint wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,\n                       word32 inSz)\n{\n    int ret;\n    const byte *n = NULL, *e = NULL;\n    word32 nSz = 0, eSz = 0;\n\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    ret = wc_RsaPublicKeyDecode_ex(input, inOutIdx, inSz, &n, &nSz, &e, &eSz);\n    if (ret == 0) {\n        ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key);\n    }\n\n    return ret;\n}\n\n/* import RSA public key elements (n, e) into RsaKey structure (key) */\nint wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,\n                             word32 eSz, RsaKey* key)\n{\n    if (n == NULL || e == NULL || key == NULL)\n        return BAD_FUNC_ARG;\n\n    key->type = RSA_PUBLIC;\n\n    if (mp_init(&key->n) != MP_OKAY)\n        return MP_INIT_E;\n\n    if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) {\n        mp_clear(&key->n);\n        return ASN_GETINT_E;\n    }\n#ifdef HAVE_WOLF_BIGINT\n    if ((int)nSz > 0 && wc_bigint_from_unsigned_bin(&key->n.raw, n, nSz) != 0) {\n        mp_clear(&key->n);\n        return ASN_GETINT_E;\n    }\n#endif /* HAVE_WOLF_BIGINT */\n\n    if (mp_init(&key->e) != MP_OKAY) {\n        mp_clear(&key->n);\n        return MP_INIT_E;\n    }\n\n    if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) {\n        mp_clear(&key->n);\n        mp_clear(&key->e);\n        return ASN_GETINT_E;\n    }\n#ifdef HAVE_WOLF_BIGINT\n    if ((int)eSz > 0 && wc_bigint_from_unsigned_bin(&key->e.raw, e, eSz) != 0) {\n        mp_clear(&key->n);\n        mp_clear(&key->e);\n        return ASN_GETINT_E;\n    }\n#endif /* HAVE_WOLF_BIGINT */\n\n#ifdef WOLFSSL_XILINX_CRYPT\n    if (wc_InitRsaHw(key) != 0) {\n        return BAD_STATE_E;\n    }\n#endif\n\n    return 0;\n}\n#endif /* HAVE_USER_RSA */\n#endif /* !NO_RSA */\n\n#ifndef NO_DH\n\nint wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)\n{\n    int    length;\n\n    if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||\n        GetInt(&key->g,  input, inOutIdx, inSz) < 0) {\n        return ASN_DH_KEY_E;\n    }\n\n    return 0;\n}\n\n\nint wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,\n                 byte* g, word32* gInOutSz)\n{\n    word32 idx = 0;\n    int    ret;\n    int    length;\n\n    if (GetSequence(input, &idx, &length, inSz) <= 0)\n        return ASN_PARSE_E;\n\n    ret = GetASNInt(input, &idx, &length, inSz);\n    if (ret != 0)\n        return ret;\n\n    if (length <= (int)*pInOutSz) {\n        XMEMCPY(p, &input[idx], length);\n        *pInOutSz = length;\n    }\n    else {\n        return BUFFER_E;\n    }\n    idx += length;\n\n    ret = GetASNInt(input, &idx, &length, inSz);\n    if (ret != 0)\n        return ret;\n\n    if (length <= (int)*gInOutSz) {\n        XMEMCPY(g, &input[idx], length);\n        *gInOutSz = length;\n    }\n    else {\n        return BUFFER_E;\n    }\n\n    return 0;\n}\n#endif /* NO_DH */\n\n\n#ifndef NO_DSA\n\nint DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,\n                        word32 inSz)\n{\n    int    length;\n\n    if (input == NULL || inOutIdx == NULL || key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||\n        GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||\n        GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||\n        GetInt(&key->y,  input, inOutIdx, inSz) < 0 )\n        return ASN_DH_KEY_E;\n\n    key->type = DSA_PUBLIC;\n    return 0;\n}\n\n\nint DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,\n                        word32 inSz)\n{\n    int    length, version;\n\n    /* Sanity checks on input */\n    if (input == NULL || inOutIdx == NULL || key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||\n        GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||\n        GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||\n        GetInt(&key->y,  input, inOutIdx, inSz) < 0 ||\n        GetInt(&key->x,  input, inOutIdx, inSz) < 0 )\n        return ASN_DH_KEY_E;\n\n    key->type = DSA_PRIVATE;\n    return 0;\n}\n\nstatic mp_int* GetDsaInt(DsaKey* key, int idx)\n{\n    if (idx == 0)\n        return &key->p;\n    if (idx == 1)\n        return &key->q;\n    if (idx == 2)\n        return &key->g;\n    if (idx == 3)\n        return &key->y;\n    if (idx == 4)\n        return &key->x;\n\n    return NULL;\n}\n\n/* Release Tmp DSA resources */\nstatic WC_INLINE void FreeTmpDsas(byte** tmps, void* heap)\n{\n    int i;\n\n    for (i = 0; i < DSA_INTS; i++)\n        XFREE(tmps[i], heap, DYNAMIC_TYPE_DSA);\n\n    (void)heap;\n}\n\n/* Convert DsaKey key to DER format, write to output (inLen), return bytes\n written */\nint wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)\n{\n    word32 seqSz, verSz, rawLen, intTotalLen = 0;\n    word32 sizes[DSA_INTS];\n    int    i, j, outLen, ret = 0, mpSz;\n\n    byte  seq[MAX_SEQ_SZ];\n    byte  ver[MAX_VERSION_SZ];\n    byte* tmps[DSA_INTS];\n\n    if (!key || !output)\n        return BAD_FUNC_ARG;\n\n    if (key->type != DSA_PRIVATE)\n        return BAD_FUNC_ARG;\n\n    for (i = 0; i < DSA_INTS; i++)\n        tmps[i] = NULL;\n\n    /* write all big ints from key to DER tmps */\n    for (i = 0; i < DSA_INTS; i++) {\n        mp_int* keyInt = GetDsaInt(key, i);\n\n        rawLen = mp_unsigned_bin_size(keyInt) + 1;\n        tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,\n                                                              DYNAMIC_TYPE_DSA);\n        if (tmps[i] == NULL) {\n            ret = MEMORY_E;\n            break;\n        }\n\n        mpSz = SetASNIntMP(keyInt, -1, tmps[i]);\n        if (mpSz < 0) {\n            ret = mpSz;\n            break;\n        }\n        intTotalLen += (sizes[i] = mpSz);\n    }\n\n    if (ret != 0) {\n        FreeTmpDsas(tmps, key->heap);\n        return ret;\n    }\n\n    /* make headers */\n    verSz = SetMyVersion(0, ver, FALSE);\n    seqSz = SetSequence(verSz + intTotalLen, seq);\n\n    outLen = seqSz + verSz + intTotalLen;\n    if (outLen > (int)inLen) {\n        FreeTmpDsas(tmps, key->heap);\n        return BAD_FUNC_ARG;\n    }\n\n    /* write to output */\n    XMEMCPY(output, seq, seqSz);\n    j = seqSz;\n    XMEMCPY(output + j, ver, verSz);\n    j += verSz;\n\n    for (i = 0; i < DSA_INTS; i++) {\n        XMEMCPY(output + j, tmps[i], sizes[i]);\n        j += sizes[i];\n    }\n    FreeTmpDsas(tmps, key->heap);\n\n    return outLen;\n}\n\n#endif /* NO_DSA */\n\nvoid InitDecodedCert(DecodedCert* cert,\n                     const byte* source, word32 inSz, void* heap)\n{\n    if (cert != NULL) {\n        XMEMSET(cert, 0, sizeof(DecodedCert));\n\n        cert->subjectCNEnc    = CTC_UTF8;\n        cert->issuer[0]       = '\\0';\n        cert->subject[0]      = '\\0';\n        cert->source          = source;  /* don't own */\n        cert->maxIdx          = inSz;    /* can't go over this index */\n        cert->heap            = heap;\n        cert->maxPathLen      = WOLFSSL_MAX_PATH_LEN;\n    #ifdef WOLFSSL_CERT_GEN\n        cert->subjectSNEnc    = CTC_UTF8;\n        cert->subjectCEnc     = CTC_PRINTABLE;\n        cert->subjectLEnc     = CTC_UTF8;\n        cert->subjectSTEnc    = CTC_UTF8;\n        cert->subjectOEnc     = CTC_UTF8;\n        cert->subjectOUEnc    = CTC_UTF8;\n    #endif /* WOLFSSL_CERT_GEN */\n\n    #ifndef NO_CERTS\n        InitSignatureCtx(&cert->sigCtx, heap, INVALID_DEVID);\n    #endif\n    }\n}\n\n\nvoid FreeAltNames(DNS_entry* altNames, void* heap)\n{\n    (void)heap;\n\n    while (altNames) {\n        DNS_entry* tmp = altNames->next;\n\n        XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);\n        XFREE(altNames,       heap, DYNAMIC_TYPE_ALTNAME);\n        altNames = tmp;\n    }\n}\n\n#ifndef IGNORE_NAME_CONSTRAINTS\n\nvoid FreeNameSubtrees(Base_entry* names, void* heap)\n{\n    (void)heap;\n\n    while (names) {\n        Base_entry* tmp = names->next;\n\n        XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME);\n        XFREE(names,       heap, DYNAMIC_TYPE_ALTNAME);\n        names = tmp;\n    }\n}\n\n#endif /* IGNORE_NAME_CONSTRAINTS */\n\nvoid FreeDecodedCert(DecodedCert* cert)\n{\n    if (cert == NULL)\n        return;\n    if (cert->subjectCNStored == 1)\n        XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);\n    if (cert->pubKeyStored == 1)\n        XFREE((void*)cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);\n    if (cert->weOwnAltNames && cert->altNames)\n        FreeAltNames(cert->altNames, cert->heap);\n#ifndef IGNORE_NAME_CONSTRAINTS\n    if (cert->altEmailNames)\n        FreeAltNames(cert->altEmailNames, cert->heap);\n    if (cert->permittedNames)\n        FreeNameSubtrees(cert->permittedNames, cert->heap);\n    if (cert->excludedNames)\n        FreeNameSubtrees(cert->excludedNames, cert->heap);\n#endif /* IGNORE_NAME_CONSTRAINTS */\n#ifdef WOLFSSL_SEP\n    XFREE(cert->deviceType, cert->heap, DYNAMIC_TYPE_X509_EXT);\n    XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);\n    XFREE(cert->hwSerialNum, cert->heap, DYNAMIC_TYPE_X509_EXT);\n#endif /* WOLFSSL_SEP */\n#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n    if (cert->issuerName.fullName != NULL)\n        XFREE(cert->issuerName.fullName, cert->heap, DYNAMIC_TYPE_X509);\n    if (cert->subjectName.fullName != NULL)\n        XFREE(cert->subjectName.fullName, cert->heap, DYNAMIC_TYPE_X509);\n#endif /* OPENSSL_EXTRA */\n#ifdef WOLFSSL_RENESAS_TSIP_TLS\n    if (cert->tsip_encRsaKeyIdx != NULL)\n        XFREE(cert->tsip_encRsaKeyIdx, cert->heap, DYNAMIC_TYPE_RSA);\n#endif\n#ifndef NO_CERTS\n    FreeSignatureCtx(&cert->sigCtx);\n#endif\n}\n\nstatic int GetCertHeader(DecodedCert* cert)\n{\n    int ret = 0, len;\n\n    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)\n        return ASN_PARSE_E;\n\n    /* Reset the max index for the size indicated in the outer wrapper. */\n    cert->maxIdx = len + cert->srcIdx;\n    cert->certBegin = cert->srcIdx;\n\n    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)\n        return ASN_PARSE_E;\n\n    cert->sigIndex = len + cert->srcIdx;\n    if (cert->sigIndex > cert->maxIdx)\n        return ASN_PARSE_E;\n\n    if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version,\n                                                            cert->sigIndex) < 0)\n        return ASN_PARSE_E;\n\n    if (GetSerialNumber(cert->source, &cert->srcIdx, cert->serial,\n                                           &cert->serialSz, cert->sigIndex) < 0)\n        return ASN_PARSE_E;\n\n    return ret;\n}\n\n#if !defined(NO_RSA)\n/* Store Rsa Key, may save later, Dsa could use in future */\nstatic int StoreRsaKey(DecodedCert* cert, word32 bitStringEnd)\n{\n    int    length;\n    word32 recvd = cert->srcIdx;\n\n    if (GetSequence(cert->source, &cert->srcIdx, &length, bitStringEnd) < 0)\n        return ASN_PARSE_E;\n\n    recvd = cert->srcIdx - recvd;\n    length += recvd;\n\n    while (recvd--)\n       cert->srcIdx--;\n#if defined(WOLFSSL_RENESAS_TSIP)\n    cert->sigCtx.pubkey_n_start = cert->sigCtx.pubkey_e_start = cert->srcIdx;\n#endif\n    cert->pubKeySize = length;\n    cert->publicKey = cert->source + cert->srcIdx;\n    cert->srcIdx += length;\n\n    return 0;\n}\n#endif /* !NO_RSA */\n\n#ifdef HAVE_ECC\n\n    /* return 0 on success if the ECC curve oid sum is supported */\n    static int CheckCurve(word32 oid)\n    {\n        int ret = 0;\n        word32 oidSz = 0;\n\n        ret = wc_ecc_get_oid(oid, NULL, &oidSz);\n        if (ret < 0 || oidSz <= 0) {\n            WOLFSSL_MSG(\"CheckCurve not found\");\n            ret = ALGO_ID_E;\n        }\n\n        return ret;\n    }\n\n#endif /* HAVE_ECC */\n\nstatic int GetKey(DecodedCert* cert)\n{\n    int length;\n#if defined(HAVE_ECC) || defined(HAVE_NTRU)\n    int tmpIdx = cert->srcIdx;\n#endif\n\n    if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)\n        return ASN_PARSE_E;\n\n    if (GetAlgoId(cert->source, &cert->srcIdx,\n                  &cert->keyOID, oidKeyType, cert->maxIdx) < 0)\n        return ASN_PARSE_E;\n\n    switch (cert->keyOID) {\n   #ifndef NO_RSA\n        case RSAk:\n        {\n            int ret;\n\n            ret = CheckBitString(cert->source, &cert->srcIdx, &length,\n                                 cert->maxIdx, 1, NULL);\n            if (ret != 0)\n                return ret;\n\n            #ifdef HAVE_OCSP\n                ret = CalcHashId(cert->source + cert->srcIdx, length,\n                        cert->subjectKeyHash);\n                if (ret != 0)\n                    return ret;\n            #endif\n\n            return StoreRsaKey(cert, cert->srcIdx + length);\n        }\n\n    #endif /* NO_RSA */\n    #ifdef HAVE_NTRU\n        case NTRUk:\n        {\n            const byte* key = &cert->source[tmpIdx];\n            byte*       next = (byte*)key;\n            word16      keyLen;\n            word32      rc;\n            word32      remaining = cert->maxIdx - cert->srcIdx;\n            byte*       publicKey;\n#ifdef WOLFSSL_SMALL_STACK\n            byte*       keyBlob = NULL;\n#else\n            byte        keyBlob[MAX_NTRU_KEY_SZ];\n#endif\n            rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,\n                                &keyLen, NULL, &next, &remaining);\n            if (rc != NTRU_OK)\n                return ASN_NTRU_KEY_E;\n            if (keyLen > MAX_NTRU_KEY_SZ)\n                return ASN_NTRU_KEY_E;\n\n#ifdef WOLFSSL_SMALL_STACK\n            keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, cert->heap,\n                                     DYNAMIC_TYPE_TMP_BUFFER);\n            if (keyBlob == NULL)\n                return MEMORY_E;\n#endif\n\n            rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,\n                                &keyLen, keyBlob, &next, &remaining);\n            if (rc != NTRU_OK) {\n#ifdef WOLFSSL_SMALL_STACK\n                XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n                return ASN_NTRU_KEY_E;\n            }\n\n            if ( (next - key) < 0) {\n#ifdef WOLFSSL_SMALL_STACK\n                XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n                return ASN_NTRU_KEY_E;\n            }\n\n            cert->srcIdx = tmpIdx + (int)(next - key);\n\n            publicKey = (byte*)XMALLOC(keyLen, cert->heap,\n                                       DYNAMIC_TYPE_PUBLIC_KEY);\n            if (publicKey == NULL) {\n#ifdef WOLFSSL_SMALL_STACK\n                XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n                return MEMORY_E;\n            }\n            XMEMCPY(publicKey, keyBlob, keyLen);\n            cert->publicKey = publicKey;\n            cert->pubKeyStored = 1;\n            cert->pubKeySize   = keyLen;\n\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n            return 0;\n        }\n    #endif /* HAVE_NTRU */\n    #ifdef HAVE_ECC\n        case ECDSAk:\n        {\n            int ret;\n            byte seq[5];\n            int pubLen = length + 1 + SetLength(length, seq);\n            word32 localIdx;\n            byte* publicKey;\n            byte  tag;\n\n            localIdx = cert->srcIdx;\n            if (GetASNTag(cert->source, &localIdx, &tag, cert->maxIdx) < 0)\n                return ASN_PARSE_E;\n\n            if (tag != (ASN_SEQUENCE | ASN_CONSTRUCTED)) {\n                if (GetObjectId(cert->source, &cert->srcIdx,\n                            &cert->pkCurveOID, oidCurveType, cert->maxIdx) < 0)\n                    return ASN_PARSE_E;\n\n                if (CheckCurve(cert->pkCurveOID) < 0)\n                    return ECC_CURVE_OID_E;\n\n                /* key header */\n                ret = CheckBitString(cert->source, &cert->srcIdx, &length,\n                                                         cert->maxIdx, 1, NULL);\n                if (ret != 0)\n                    return ret;\n            #ifdef HAVE_OCSP\n                ret = CalcHashId(cert->source + cert->srcIdx, length,\n                        cert->subjectKeyHash);\n                if (ret != 0)\n                    return ret;\n            #endif\n            }\n\n            publicKey = (byte*)XMALLOC(pubLen, cert->heap,\n                                       DYNAMIC_TYPE_PUBLIC_KEY);\n            if (publicKey == NULL)\n                return MEMORY_E;\n            XMEMCPY(publicKey, &cert->source[tmpIdx], pubLen);\n            cert->publicKey = publicKey;\n            cert->pubKeyStored = 1;\n            cert->pubKeySize   = pubLen;\n\n            cert->srcIdx = tmpIdx + pubLen;\n\n            return 0;\n        }\n    #endif /* HAVE_ECC */\n    #ifdef HAVE_ED25519\n        case ED25519k:\n        {\n            byte* publicKey;\n            int ret;\n\n            cert->pkCurveOID = ED25519k;\n\n            ret = CheckBitString(cert->source, &cert->srcIdx, &length,\n                                 cert->maxIdx, 1, NULL);\n            if (ret != 0)\n                return ret;\n\n            #ifdef HAVE_OCSP\n                ret = CalcHashId(cert->source + cert->srcIdx, length,\n                        cert->subjectKeyHash);\n                if (ret != 0)\n                    return ret;\n            #endif\n\n            publicKey = (byte*) XMALLOC(length, cert->heap,\n                                        DYNAMIC_TYPE_PUBLIC_KEY);\n            if (publicKey == NULL)\n                return MEMORY_E;\n            XMEMCPY(publicKey, &cert->source[cert->srcIdx], length);\n            cert->publicKey = publicKey;\n            cert->pubKeyStored = 1;\n            cert->pubKeySize   = length;\n\n            cert->srcIdx += length;\n\n            return 0;\n        }\n    #endif /* HAVE_ED25519 */\n        default:\n            return ASN_UNKNOWN_OID_E;\n    }\n}\n\n#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\nWOLFSSL_LOCAL int wc_OBJ_sn2nid(const char *sn)\n{\n    static const struct {\n        const char *sn;\n        int  nid;\n    } sn2nid[] = {\n        {WOLFSSL_COMMON_NAME, NID_commonName},\n        {WOLFSSL_COUNTRY_NAME, NID_countryName},\n        {WOLFSSL_LOCALITY_NAME, NID_localityName},\n        {WOLFSSL_STATE_NAME, NID_stateOrProvinceName},\n        {WOLFSSL_ORG_NAME, NID_organizationName},\n        {WOLFSSL_ORGUNIT_NAME, NID_organizationalUnitName},\n        {WOLFSSL_EMAIL_ADDR, NID_emailAddress},\n        {NULL, -1}};\n\n    int i;\n    WOLFSSL_ENTER(\"OBJ_osn2nid\");\n    #ifdef HAVE_ECC\n    /* Nginx uses this OpenSSL string. */\n    if (XSTRNCMP(sn, \"prime256v1\", 10) == 0)\n        sn = \"SECP256R1\";\n    if (XSTRNCMP(sn, \"secp384r1\", 10) == 0)\n        sn = \"SECP384R1\";\n    /* find based on name and return NID */\n    for (i = 0; ecc_sets[i].size != 0 && ecc_sets[i].name != NULL; i++) {\n        if (XSTRNCMP(sn, ecc_sets[i].name, ECC_MAXNAME) == 0) {\n            return ecc_sets[i].id;\n        }\n    }\n    #endif\n\n    for(i=0; sn2nid[i].sn != NULL; i++) {\n        if(XSTRNCMP(sn, sn2nid[i].sn, XSTRLEN(sn2nid[i].sn)) == 0) {\n            return sn2nid[i].nid;\n        }\n    }\n\n    return NID_undef;\n}\n#endif\n\n/* Routine for calculating hashId */\nint CalcHashId(const byte* data, word32 len, byte* hash)\n{\n    int ret = NOT_COMPILED_IN;\n\n#ifdef WOLF_CRYPTO_CB\n    /* try to use a registered crypto callback */\n    ret = wc_CryptoCb_Sha256Hash(NULL, data, len, hash);\n    if (ret != CRYPTOCB_UNAVAILABLE)\n        return ret;\n    /* fall-through when unavailable */\n#endif\n\n#if defined(NO_SHA) && !defined(NO_SHA256)\n    ret = wc_Sha256Hash(data, len, hash);\n#elif !defined(NO_SHA)\n    ret = wc_ShaHash(data, len, hash);\n#endif\n\n    return ret;\n}\n\n/* process NAME, either issuer or subject */\nstatic int GetName(DecodedCert* cert, int nameType, int maxIdx)\n{\n    int    length;  /* length of all distinguished names */\n    int    dummy;\n    int    ret;\n    char*  full;\n    byte*  hash;\n    word32 idx, localIdx = 0;\n    byte   tag;\n    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n        DecodedName* dName =\n                  (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;\n        int dcnum = 0;\n        #ifdef OPENSSL_EXTRA\n        int count = 0;\n        #endif\n    #endif /* OPENSSL_EXTRA */\n\n    WOLFSSL_MSG(\"Getting Cert Name\");\n\n    if (nameType == ISSUER) {\n        full = cert->issuer;\n        hash = cert->issuerHash;\n    }\n    else {\n        full = cert->subject;\n        hash = cert->subjectHash;\n    }\n\n    if (cert->srcIdx >= (word32)maxIdx) {\n        return BUFFER_E;\n    }\n\n    localIdx = cert->srcIdx;\n    if (GetASNTag(cert->source, &localIdx, &tag, maxIdx) < 0) {\n        return ASN_PARSE_E;\n    }\n\n    if (tag == ASN_OBJECT_ID) {\n        WOLFSSL_MSG(\"Trying optional prefix...\");\n\n        if (SkipObjectId(cert->source, &cert->srcIdx, maxIdx) < 0)\n            return ASN_PARSE_E;\n        WOLFSSL_MSG(\"Got optional prefix\");\n    }\n\n    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be\n     * calculated over the entire DER encoding of the Name field, including\n     * the tag and length. */\n    idx = cert->srcIdx;\n    if (GetSequence(cert->source, &cert->srcIdx, &length, maxIdx) < 0)\n        return ASN_PARSE_E;\n\n    ret = CalcHashId(&cert->source[idx], length + cert->srcIdx - idx, hash);\n    if (ret != 0)\n        return ret;\n\n    length += cert->srcIdx;\n    idx = 0;\n\n#if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)\n    /* store pointer to raw issuer */\n    if (nameType == ISSUER) {\n        cert->issuerRaw = &cert->source[cert->srcIdx];\n        cert->issuerRawLen = length - cert->srcIdx;\n    }\n#endif\n#ifndef IGNORE_NAME_CONSTRAINTS\n    if (nameType == SUBJECT) {\n        cert->subjectRaw = &cert->source[cert->srcIdx];\n        cert->subjectRawLen = length - cert->srcIdx;\n    }\n#endif\n\n    while (cert->srcIdx < (word32)length) {\n        byte        b       = 0;\n        byte        joint[3];\n        byte        tooBig  = FALSE;\n        int         oidSz;\n        const char* copy    = NULL;\n        int         copyLen = 0;\n        int         strLen  = 0;\n        byte        id      = 0;\n\n        if (GetSet(cert->source, &cert->srcIdx, &dummy, maxIdx) < 0) {\n            WOLFSSL_MSG(\"Cert name lacks set header, trying sequence\");\n        }\n\n        if (GetSequence(cert->source, &cert->srcIdx, &dummy, maxIdx) <= 0)\n            return ASN_PARSE_E;\n\n        ret = GetASNObjectId(cert->source, &cert->srcIdx, &oidSz, maxIdx);\n        if (ret != 0)\n            return ret;\n\n        /* make sure there is room for joint */\n        if ((cert->srcIdx + sizeof(joint)) > (word32)maxIdx)\n            return ASN_PARSE_E;\n\n        XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));\n\n        /* v1 name types */\n        if (joint[0] == 0x55 && joint[1] == 0x04) {\n            cert->srcIdx += 3;\n            id = joint[2];\n            if (GetHeader(cert->source, &b, &cert->srcIdx, &strLen,\n                          maxIdx, 1) < 0) {\n                return ASN_PARSE_E;\n            }\n\n            if (id == ASN_COMMON_NAME) {\n                if (nameType == SUBJECT) {\n                    cert->subjectCN = (char *)&cert->source[cert->srcIdx];\n                    cert->subjectCNLen = strLen;\n                    cert->subjectCNEnc = b;\n                }\n\n                copy = WOLFSSL_COMMON_NAME;\n                copyLen = sizeof(WOLFSSL_COMMON_NAME) - 1;\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    dName->cnIdx = cert->srcIdx;\n                    dName->cnLen = strLen;\n                #endif /* OPENSSL_EXTRA */\n            }\n            else if (id == ASN_SUR_NAME) {\n                copy = WOLFSSL_SUR_NAME;\n                copyLen = sizeof(WOLFSSL_SUR_NAME) - 1;\n                #ifdef WOLFSSL_CERT_GEN\n                    if (nameType == SUBJECT) {\n                        cert->subjectSN = (char*)&cert->source[cert->srcIdx];\n                        cert->subjectSNLen = strLen;\n                        cert->subjectSNEnc = b;\n                    }\n                #endif /* WOLFSSL_CERT_GEN */\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    dName->snIdx = cert->srcIdx;\n                    dName->snLen = strLen;\n                #endif /* OPENSSL_EXTRA */\n            }\n            else if (id == ASN_COUNTRY_NAME) {\n                copy = WOLFSSL_COUNTRY_NAME;\n                copyLen = sizeof(WOLFSSL_COUNTRY_NAME) - 1;\n                #ifdef WOLFSSL_CERT_GEN\n                    if (nameType == SUBJECT) {\n                        cert->subjectC = (char*)&cert->source[cert->srcIdx];\n                        cert->subjectCLen = strLen;\n                        cert->subjectCEnc = b;\n                    }\n                #endif /* WOLFSSL_CERT_GEN */\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    dName->cIdx = cert->srcIdx;\n                    dName->cLen = strLen;\n                #endif /* OPENSSL_EXTRA */\n            }\n            else if (id == ASN_LOCALITY_NAME) {\n                copy = WOLFSSL_LOCALITY_NAME;\n                copyLen = sizeof(WOLFSSL_LOCALITY_NAME) - 1;\n                #ifdef WOLFSSL_CERT_GEN\n                    if (nameType == SUBJECT) {\n                        cert->subjectL = (char*)&cert->source[cert->srcIdx];\n                        cert->subjectLLen = strLen;\n                        cert->subjectLEnc = b;\n                    }\n                #endif /* WOLFSSL_CERT_GEN */\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    dName->lIdx = cert->srcIdx;\n                    dName->lLen = strLen;\n                #endif /* OPENSSL_EXTRA */\n            }\n            else if (id == ASN_STATE_NAME) {\n                copy = WOLFSSL_STATE_NAME;\n                copyLen = sizeof(WOLFSSL_STATE_NAME) - 1;\n                #ifdef WOLFSSL_CERT_GEN\n                    if (nameType == SUBJECT) {\n                        cert->subjectST = (char*)&cert->source[cert->srcIdx];\n                        cert->subjectSTLen = strLen;\n                        cert->subjectSTEnc = b;\n                    }\n                #endif /* WOLFSSL_CERT_GEN */\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    dName->stIdx = cert->srcIdx;\n                    dName->stLen = strLen;\n                #endif /* OPENSSL_EXTRA */\n            }\n            else if (id == ASN_ORG_NAME) {\n                copy = WOLFSSL_ORG_NAME;\n                copyLen = sizeof(WOLFSSL_ORG_NAME) - 1;\n                #ifdef WOLFSSL_CERT_GEN\n                    if (nameType == SUBJECT) {\n                        cert->subjectO = (char*)&cert->source[cert->srcIdx];\n                        cert->subjectOLen = strLen;\n                        cert->subjectOEnc = b;\n                    }\n                #endif /* WOLFSSL_CERT_GEN */\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    dName->oIdx = cert->srcIdx;\n                    dName->oLen = strLen;\n                #endif /* OPENSSL_EXTRA */\n            }\n            else if (id == ASN_ORGUNIT_NAME) {\n                copy = WOLFSSL_ORGUNIT_NAME;\n                copyLen = sizeof(WOLFSSL_ORGUNIT_NAME) - 1;\n                #ifdef WOLFSSL_CERT_GEN\n                    if (nameType == SUBJECT) {\n                        cert->subjectOU = (char*)&cert->source[cert->srcIdx];\n                        cert->subjectOULen = strLen;\n                        cert->subjectOUEnc = b;\n                    }\n                #endif /* WOLFSSL_CERT_GEN */\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    dName->ouIdx = cert->srcIdx;\n                    dName->ouLen = strLen;\n                #endif /* OPENSSL_EXTRA */\n            }\n            else if (id == ASN_SERIAL_NUMBER) {\n                copy = WOLFSSL_SERIAL_NUMBER;\n                copyLen = sizeof(WOLFSSL_SERIAL_NUMBER) - 1;\n                #ifdef WOLFSSL_CERT_GEN\n                    if (nameType == SUBJECT) {\n                        cert->subjectSND = (char*)&cert->source[cert->srcIdx];\n                        cert->subjectSNDLen = strLen;\n                        cert->subjectSNDEnc = b;\n                    }\n                #endif /* WOLFSSL_CERT_GEN */\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    dName->snIdx = cert->srcIdx;\n                    dName->snLen = strLen;\n                #endif /* OPENSSL_EXTRA */\n            }\n        #ifdef WOLFSSL_CERT_EXT\n            else if (id == ASN_BUS_CAT) {\n                copy = WOLFSSL_BUS_CAT;\n                copyLen = sizeof(WOLFSSL_BUS_CAT) - 1;\n            #ifdef WOLFSSL_CERT_GEN\n                if (nameType == SUBJECT) {\n                    cert->subjectBC = (char*)&cert->source[cert->srcIdx];\n                    cert->subjectBCLen = strLen;\n                    cert->subjectBCEnc = b;\n                }\n            #endif /* WOLFSSL_CERT_GEN */\n            #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                dName->bcIdx = cert->srcIdx;\n                dName->bcLen = strLen;\n            #endif /* OPENSSL_EXTRA */\n            }\n        #endif /* WOLFSSL_CERT_EXT */\n        }\n    #ifdef WOLFSSL_CERT_EXT\n        else if ((cert->srcIdx + ASN_JOI_PREFIX_SZ + 2 <= (word32)maxIdx) &&\n                 (0 == XMEMCMP(&cert->source[cert->srcIdx], ASN_JOI_PREFIX,\n                               ASN_JOI_PREFIX_SZ)) &&\n                 ((cert->source[cert->srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_C) ||\n                  (cert->source[cert->srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_ST)))\n        {\n            cert->srcIdx += ASN_JOI_PREFIX_SZ;\n            id = cert->source[cert->srcIdx++];\n            b = cert->source[cert->srcIdx++]; /* encoding */\n\n            if (GetLength(cert->source, &cert->srcIdx, &strLen,\n                          maxIdx) < 0)\n                return ASN_PARSE_E;\n\n            /* Check for jurisdiction of incorporation country name */\n            if (id == ASN_JOI_C) {\n                copy = WOLFSSL_JOI_C;\n                copyLen = sizeof(WOLFSSL_JOI_C) - 1;\n                #ifdef WOLFSSL_CERT_GEN\n                    if (nameType == SUBJECT) {\n                        cert->subjectJC = (char*)&cert->source[cert->srcIdx];\n                        cert->subjectJCLen = strLen;\n                        cert->subjectJCEnc = b;\n                    }\n                #endif /* WOLFSSL_CERT_GEN */\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    dName->jcIdx = cert->srcIdx;\n                    dName->jcLen = strLen;\n                #endif /* OPENSSL_EXTRA */\n            }\n\n            /* Check for jurisdiction of incorporation state name */\n            else if (id == ASN_JOI_ST) {\n                copy = WOLFSSL_JOI_ST;\n                copyLen = sizeof(WOLFSSL_JOI_ST) - 1;\n                #ifdef WOLFSSL_CERT_GEN\n                    if (nameType == SUBJECT) {\n                        cert->subjectJS = (char*)&cert->source[cert->srcIdx];\n                        cert->subjectJSLen = strLen;\n                        cert->subjectJSEnc = b;\n                    }\n                #endif /* WOLFSSL_CERT_GEN */\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    dName->jsIdx = cert->srcIdx;\n                    dName->jsLen = strLen;\n                #endif /* OPENSSL_EXTRA */\n            }\n\n            if ((strLen + copyLen) > (int)(ASN_NAME_MAX - idx)) {\n                WOLFSSL_MSG(\"ASN Name too big, skipping\");\n                tooBig = TRUE;\n            }\n        }\n    #endif /* WOLFSSL_CERT_EXT */\n        else {\n            /* skip */\n            byte email = FALSE;\n            byte pilot = FALSE;\n\n            if (joint[0] == 0x2a && joint[1] == 0x86) {  /* email id hdr */\n                id = ASN_EMAIL_NAME;\n                email = TRUE;\n            }\n\n            if (joint[0] == 0x9  && joint[1] == 0x92) { /* uid id hdr */\n                /* last value of OID is the type of pilot attribute */\n                id    = cert->source[cert->srcIdx + oidSz - 1];\n                pilot = TRUE;\n            }\n\n            cert->srcIdx += oidSz + 1;\n\n            if (GetLength(cert->source, &cert->srcIdx, &strLen, maxIdx) < 0)\n                return ASN_PARSE_E;\n\n            if (strLen > (int)(ASN_NAME_MAX - idx)) {\n                WOLFSSL_MSG(\"ASN name too big, skipping\");\n                tooBig = TRUE;\n            }\n\n            if (email) {\n                copyLen = sizeof(WOLFSSL_EMAIL_ADDR) - 1;\n                if ((copyLen + strLen) > (int)(ASN_NAME_MAX - idx)) {\n                    WOLFSSL_MSG(\"ASN name too big, skipping\");\n                    tooBig = TRUE;\n                }\n                else {\n                    copy = WOLFSSL_EMAIL_ADDR;\n                }\n\n                #ifdef WOLFSSL_CERT_GEN\n                    if (nameType == SUBJECT) {\n                        cert->subjectEmail = (char*)&cert->source[cert->srcIdx];\n                        cert->subjectEmailLen = strLen;\n                    }\n                #endif /* WOLFSSL_CERT_GEN */\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    dName->emailIdx = cert->srcIdx;\n                    dName->emailLen = strLen;\n                #endif /* OPENSSL_EXTRA */\n                #ifndef IGNORE_NAME_CONSTRAINTS\n                    {\n                        DNS_entry* emailName = NULL;\n\n                        emailName = (DNS_entry*)XMALLOC(sizeof(DNS_entry),\n                                              cert->heap, DYNAMIC_TYPE_ALTNAME);\n                        if (emailName == NULL) {\n                            WOLFSSL_MSG(\"\\tOut of Memory\");\n                            return MEMORY_E;\n                        }\n                        emailName->type = 0;\n                        emailName->name = (char*)XMALLOC(strLen + 1,\n                                              cert->heap, DYNAMIC_TYPE_ALTNAME);\n                        if (emailName->name == NULL) {\n                            WOLFSSL_MSG(\"\\tOut of Memory\");\n                            XFREE(emailName, cert->heap, DYNAMIC_TYPE_ALTNAME);\n                            return MEMORY_E;\n                        }\n                        emailName->len = strLen;\n                        XMEMCPY(emailName->name, &cert->source[cert->srcIdx],\n                                                                        strLen);\n                        emailName->name[strLen] = '\\0';\n\n                        emailName->next = cert->altEmailNames;\n                        cert->altEmailNames = emailName;\n                    }\n                #endif /* IGNORE_NAME_CONSTRAINTS */\n            }\n\n            if (pilot) {\n                switch (id) {\n                    case ASN_USER_ID:\n                        copy = WOLFSSL_USER_ID;\n                        copyLen = sizeof(WOLFSSL_USER_ID) - 1;\n                    #if defined(OPENSSL_EXTRA) || \\\n                        defined(OPENSSL_EXTRA_X509_SMALL)\n                        dName->uidIdx = cert->srcIdx;\n                        dName->uidLen = strLen;\n                    #endif /* OPENSSL_EXTRA */\n                        break;\n\n                    case ASN_DOMAIN_COMPONENT:\n                        copy = WOLFSSL_DOMAIN_COMPONENT;\n                        copyLen = sizeof(WOLFSSL_DOMAIN_COMPONENT) - 1;\n                    #if defined(OPENSSL_EXTRA) || \\\n                        defined(OPENSSL_EXTRA_X509_SMALL)\n                        dName->dcIdx[dcnum] = cert->srcIdx;\n                        dName->dcLen[dcnum] = strLen;\n                        dName->dcNum = dcnum + 1;\n                        dcnum++;\n                    #endif /* OPENSSL_EXTRA */\n                        break;\n\n                    default:\n                        WOLFSSL_MSG(\"Unknown pilot attribute type\");\n                        return ASN_PARSE_E;\n                }\n            }\n        }\n        if ((copyLen + strLen) > (int)(ASN_NAME_MAX - idx))\n        {\n            WOLFSSL_MSG(\"ASN Name too big, skipping\");\n            tooBig = TRUE;\n        }\n        if ((copy != NULL) && !tooBig) {\n            XMEMCPY(&full[idx], copy, copyLen);\n            idx += copyLen;\n            XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);\n            idx += strLen;\n\n        #ifdef OPENSSL_EXTRA\n            if (count < DOMAIN_COMPONENT_MAX) {\n                /* store order that DN was parsed */\n                dName->loc[count++] = id;\n            }\n        #endif\n        }\n        cert->srcIdx += strLen;\n    }\n    full[idx++] = 0;\n#if defined(OPENSSL_EXTRA)\n    /* store order that DN was parsed */\n    dName->locSz = count;\n#endif\n\n    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n    {\n        int totalLen = 0;\n        int i = 0;\n\n        if (dName->cnLen != 0)\n            totalLen += dName->cnLen + 4;\n        if (dName->snLen != 0)\n            totalLen += dName->snLen + 4;\n        if (dName->cLen != 0)\n            totalLen += dName->cLen + 3;\n        if (dName->lLen != 0)\n            totalLen += dName->lLen + 3;\n        if (dName->stLen != 0)\n            totalLen += dName->stLen + 4;\n        if (dName->oLen != 0)\n            totalLen += dName->oLen + 3;\n        if (dName->ouLen != 0)\n            totalLen += dName->ouLen + 4;\n        if (dName->emailLen != 0)\n            totalLen += dName->emailLen + 14;\n        if (dName->uidLen != 0)\n            totalLen += dName->uidLen + 5;\n        if (dName->serialLen != 0)\n            totalLen += dName->serialLen + 14;\n        if (dName->dcNum != 0){\n            for (i = 0;i < dName->dcNum;i++)\n                totalLen += dName->dcLen[i] + 4;\n        }\n\n        dName->fullName = (char*)XMALLOC(totalLen + 1, cert->heap,\n                                                             DYNAMIC_TYPE_X509);\n        if (dName->fullName != NULL) {\n            idx = 0;\n\n            if (dName->cnLen != 0) {\n                dName->entryCount++;\n                XMEMCPY(&dName->fullName[idx], WOLFSSL_COMMON_NAME, 4);\n                dName->cnNid = wc_OBJ_sn2nid((const char *)WOLFSSL_COMMON_NAME);\n                idx += 4;\n                XMEMCPY(&dName->fullName[idx],\n                                     &cert->source[dName->cnIdx], dName->cnLen);\n                dName->cnIdx = idx;\n                idx += dName->cnLen;\n            }\n            if (dName->snLen != 0) {\n                dName->entryCount++;\n                XMEMCPY(&dName->fullName[idx], WOLFSSL_SUR_NAME, 4);\n                dName->snNid = wc_OBJ_sn2nid((const char *)WOLFSSL_SUR_NAME);\n                idx += 4;\n                XMEMCPY(&dName->fullName[idx],\n                                     &cert->source[dName->snIdx], dName->snLen);\n                dName->snIdx = idx;\n                idx += dName->snLen;\n            }\n            if (dName->cLen != 0) {\n                dName->entryCount++;\n                XMEMCPY(&dName->fullName[idx], WOLFSSL_COUNTRY_NAME, 3);\n                dName->cNid = wc_OBJ_sn2nid((const char *)WOLFSSL_COUNTRY_NAME);\n                idx += 3;\n                XMEMCPY(&dName->fullName[idx],\n                                       &cert->source[dName->cIdx], dName->cLen);\n                dName->cIdx = idx;\n                idx += dName->cLen;\n            }\n            if (dName->lLen != 0) {\n                dName->entryCount++;\n                XMEMCPY(&dName->fullName[idx], WOLFSSL_LOCALITY_NAME, 3);\n                dName->lNid = wc_OBJ_sn2nid((const char *)WOLFSSL_LOCALITY_NAME);\n                idx += 3;\n                XMEMCPY(&dName->fullName[idx],\n                                       &cert->source[dName->lIdx], dName->lLen);\n                dName->lIdx = idx;\n                idx += dName->lLen;\n            }\n            if (dName->stLen != 0) {\n                dName->entryCount++;\n                XMEMCPY(&dName->fullName[idx], WOLFSSL_STATE_NAME, 4);\n                dName->stNid = wc_OBJ_sn2nid((const char *)WOLFSSL_STATE_NAME);\n                idx += 4;\n                XMEMCPY(&dName->fullName[idx],\n                                     &cert->source[dName->stIdx], dName->stLen);\n                dName->stIdx = idx;\n                idx += dName->stLen;\n            }\n            if (dName->oLen != 0) {\n                dName->entryCount++;\n                XMEMCPY(&dName->fullName[idx], WOLFSSL_ORG_NAME, 3);\n                dName->oNid = wc_OBJ_sn2nid((const char *)WOLFSSL_ORG_NAME);\n                idx += 3;\n                XMEMCPY(&dName->fullName[idx],\n                                       &cert->source[dName->oIdx], dName->oLen);\n                dName->oIdx = idx;\n                idx += dName->oLen;\n            }\n            if (dName->ouLen != 0) {\n                dName->entryCount++;\n                XMEMCPY(&dName->fullName[idx], WOLFSSL_ORGUNIT_NAME, 4);\n                dName->ouNid = wc_OBJ_sn2nid((const char *)WOLFSSL_ORGUNIT_NAME);\n                idx += 4;\n                XMEMCPY(&dName->fullName[idx],\n                                     &cert->source[dName->ouIdx], dName->ouLen);\n                dName->ouIdx = idx;\n                idx += dName->ouLen;\n            }\n            if (dName->emailLen != 0) {\n                dName->entryCount++;\n                XMEMCPY(&dName->fullName[idx], \"/emailAddress=\", 14);\n                dName->emailNid = wc_OBJ_sn2nid((const char *)\"/emailAddress=\");\n                idx += 14;\n                XMEMCPY(&dName->fullName[idx],\n                               &cert->source[dName->emailIdx], dName->emailLen);\n                dName->emailIdx = idx;\n                idx += dName->emailLen;\n            }\n            for (i = 0;i < dName->dcNum;i++){\n                if (dName->dcLen[i] != 0) {\n                    dName->entryCount++;\n                    XMEMCPY(&dName->fullName[idx], WOLFSSL_DOMAIN_COMPONENT, 4);\n                    idx += 4;\n                    XMEMCPY(&dName->fullName[idx],\n                                    &cert->source[dName->dcIdx[i]], dName->dcLen[i]);\n                    dName->dcIdx[i] = idx;\n                    idx += dName->dcLen[i];\n                }\n            }\n            if (dName->uidLen != 0) {\n                dName->entryCount++;\n                XMEMCPY(&dName->fullName[idx], \"/UID=\", 5);\n                dName->uidNid = wc_OBJ_sn2nid((const char *)\"/UID=\");\n                idx += 5;\n                XMEMCPY(&dName->fullName[idx],\n                                   &cert->source[dName->uidIdx], dName->uidLen);\n                dName->uidIdx = idx;\n                idx += dName->uidLen;\n            }\n            if (dName->serialLen != 0) {\n                dName->entryCount++;\n                XMEMCPY(&dName->fullName[idx], WOLFSSL_SERIAL_NUMBER, 14);\n                dName->serialNid = wc_OBJ_sn2nid((const char *)WOLFSSL_SERIAL_NUMBER);\n                idx += 14;\n                XMEMCPY(&dName->fullName[idx],\n                             &cert->source[dName->serialIdx], dName->serialLen);\n                dName->serialIdx = idx;\n                idx += dName->serialLen;\n            }\n            dName->fullName[idx] = '\\0';\n            dName->fullNameLen = totalLen;\n        }\n    }\n    #endif /* OPENSSL_EXTRA */\n\n    return 0;\n}\n\n\n#ifndef NO_ASN_TIME\n\n/* two byte date/time, add to value */\nstatic WC_INLINE int GetTime(int* value, const byte* date, int* idx)\n{\n    int i = *idx;\n\n    if (date[i] < 0x30 || date[i] > 0x39 || date[i+1] < 0x30 ||\n                                                             date[i+1] > 0x39) {\n        return ASN_PARSE_E;\n    }\n\n    *value += btoi(date[i++]) * 10;\n    *value += btoi(date[i++]);\n\n    *idx = i;\n\n    return 0;\n}\n\nint ExtractDate(const unsigned char* date, unsigned char format,\n                                                  struct tm* certTime, int* idx)\n{\n    XMEMSET(certTime, 0, sizeof(struct tm));\n\n    if (format == ASN_UTC_TIME) {\n        if (btoi(date[*idx]) >= 5)\n            certTime->tm_year = 1900;\n        else\n            certTime->tm_year = 2000;\n    }\n    else  { /* format == GENERALIZED_TIME */\n        if (GetTime(&certTime->tm_year, date, idx) != 0) return 0;\n        certTime->tm_year *= 100;\n    }\n\n    /* adjust tm_year, tm_mon */\n    if (GetTime(&certTime->tm_year, date, idx) != 0) return 0;\n    certTime->tm_year -= 1900;\n    if (GetTime(&certTime->tm_mon , date, idx) != 0) return 0;\n    certTime->tm_mon  -= 1;\n    if (GetTime(&certTime->tm_mday, date, idx) != 0) return 0;\n    if (GetTime(&certTime->tm_hour, date, idx) != 0) return 0;\n    if (GetTime(&certTime->tm_min , date, idx) != 0) return 0;\n    if (GetTime(&certTime->tm_sec , date, idx) != 0) return 0;\n\n    return 1;\n}\n\n\n#if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \\\n    defined(OPENSSL_EXTRA) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)\nint GetTimeString(byte* date, int format, char* buf, int len)\n{\n    struct tm t;\n    int idx = 0;\n\n    if (!ExtractDate(date, (unsigned char)format, &t, &idx)) {\n        return 0;\n    }\n\n    if (date[idx] != 'Z') {\n        WOLFSSL_MSG(\"UTCtime, not Zulu\") ;\n        return 0;\n    }\n\n    /* place month in buffer */\n    buf[0] = '\\0';\n    switch(t.tm_mon) {\n        case 0:  XSTRNCAT(buf, \"Jan \", 5); break;\n        case 1:  XSTRNCAT(buf, \"Feb \", 5); break;\n        case 2:  XSTRNCAT(buf, \"Mar \", 5); break;\n        case 3:  XSTRNCAT(buf, \"Apr \", 5); break;\n        case 4:  XSTRNCAT(buf, \"May \", 5); break;\n        case 5:  XSTRNCAT(buf, \"Jun \", 5); break;\n        case 6:  XSTRNCAT(buf, \"Jul \", 5); break;\n        case 7:  XSTRNCAT(buf, \"Aug \", 5); break;\n        case 8:  XSTRNCAT(buf, \"Sep \", 5); break;\n        case 9:  XSTRNCAT(buf, \"Oct \", 5); break;\n        case 10: XSTRNCAT(buf, \"Nov \", 5); break;\n        case 11: XSTRNCAT(buf, \"Dec \", 5); break;\n        default:\n            return 0;\n\n    }\n    idx = 4; /* use idx now for char buffer */\n\n    XSNPRINTF(buf + idx, len - idx, \"%2d %02d:%02d:%02d %d GMT\",\n              t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, t.tm_year + 1900);\n\n    return 1;\n}\n#endif /* OPENSSL_ALL || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY */\n\n\n#if !defined(NO_ASN_TIME) && defined(HAVE_PKCS7)\n\n/* Set current time string, either UTC or GeneralizedTime.\n * (void*) tm should be a pointer to time_t, output is placed in buf.\n *\n * Return time string length placed in buf on success, negative on error */\nint GetAsnTimeString(void* currTime, byte* buf, word32 len)\n{\n    struct tm* ts      = NULL;\n    struct tm* tmpTime = NULL;\n#if defined(NEED_TMP_TIME)\n    struct tm tmpTimeStorage;\n    tmpTime = &tmpTimeStorage;\n#else\n    (void)tmpTime;\n#endif\n    byte* data_ptr  = buf;\n    word32 data_len = 0;\n    int year, mon, day, hour, mini, sec;\n\n    WOLFSSL_ENTER(\"SetAsnTimeString\");\n\n    if (buf == NULL || len == 0)\n        return BAD_FUNC_ARG;\n\n    ts = (struct tm *)XGMTIME((time_t*)currTime, tmpTime);\n    if (ts == NULL){\n        WOLFSSL_MSG(\"failed to get time data.\");\n        return ASN_TIME_E;\n    }\n\n    /* Note ASN_UTC_TIME_SIZE and ASN_GENERALIZED_TIME_SIZE include space for\n     * the null terminator. ASN encoded values leave off the terminator. */\n\n    if (ts->tm_year >= 50 && ts->tm_year < 150) {\n        /* UTC Time */\n        char utc_str[ASN_UTC_TIME_SIZE];\n        data_len = ASN_UTC_TIME_SIZE - 1 + 2;\n\n        if (len < data_len)\n            return BUFFER_E;\n\n        if (ts->tm_year >= 50 && ts->tm_year < 100) {\n            year = ts->tm_year;\n        } else if (ts->tm_year >= 100 && ts->tm_year < 150) {\n            year = ts->tm_year - 100;\n        }\n        else {\n            WOLFSSL_MSG(\"unsupported year range\");\n            return BAD_FUNC_ARG;\n        }\n        mon  = ts->tm_mon + 1;\n        day  = ts->tm_mday;\n        hour = ts->tm_hour;\n        mini = ts->tm_min;\n        sec  = ts->tm_sec;\n        XSNPRINTF((char *)utc_str, ASN_UTC_TIME_SIZE,\n                  \"%02d%02d%02d%02d%02d%02dZ\", year, mon, day, hour, mini, sec);\n        *data_ptr = (byte) ASN_UTC_TIME; data_ptr++;\n        /* -1 below excludes null terminator */\n        *data_ptr = (byte) ASN_UTC_TIME_SIZE - 1; data_ptr++;\n        XMEMCPY(data_ptr,(byte *)utc_str, ASN_UTC_TIME_SIZE - 1);\n\n    } else {\n        /* GeneralizedTime */\n        char gt_str[ASN_GENERALIZED_TIME_SIZE];\n        data_len = ASN_GENERALIZED_TIME_SIZE - 1 + 2;\n\n        if (len < data_len)\n            return BUFFER_E;\n\n        year = ts->tm_year + 1900;\n        mon  = ts->tm_mon + 1;\n        day  = ts->tm_mday;\n        hour = ts->tm_hour;\n        mini = ts->tm_min;\n        sec  = ts->tm_sec;\n        XSNPRINTF((char *)gt_str, ASN_GENERALIZED_TIME_SIZE,\n                  \"%4d%02d%02d%02d%02d%02dZ\", year, mon, day, hour, mini, sec);\n        *data_ptr = (byte) ASN_GENERALIZED_TIME; data_ptr++;\n        /* -1 below excludes null terminator */\n        *data_ptr = (byte) ASN_GENERALIZED_TIME_SIZE - 1; data_ptr++;\n        XMEMCPY(data_ptr,(byte *)gt_str, ASN_GENERALIZED_TIME_SIZE - 1);\n    }\n\n    return data_len;\n}\n\n#endif /* !NO_ASN_TIME && HAVE_PKCS7 */\n\n\n#if defined(USE_WOLF_VALIDDATE)\n\n/* to the second */\nWOLFSSL_LOCAL int DateGreaterThan(const struct tm* a, const struct tm* b)\n{\n    if (a->tm_year > b->tm_year)\n        return 1;\n\n    if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)\n        return 1;\n\n    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&\n           a->tm_mday > b->tm_mday)\n        return 1;\n\n    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&\n        a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)\n        return 1;\n\n    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&\n        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&\n        a->tm_min > b->tm_min)\n        return 1;\n\n    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&\n        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&\n        a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)\n        return 1;\n\n    return 0; /* false */\n}\n\n\nstatic WC_INLINE int DateLessThan(const struct tm* a, const struct tm* b)\n{\n    return DateGreaterThan(b,a);\n}\n\n/* like atoi but only use first byte */\n/* Make sure before and after dates are valid */\nint ValidateDate(const byte* date, byte format, int dateType)\n{\n    time_t ltime;\n    struct tm  certTime;\n    struct tm* localTime;\n    struct tm* tmpTime = NULL;\n    int    i = 0;\n    int    timeDiff = 0 ;\n    int    diffHH = 0 ; int diffMM = 0 ;\n    int    diffSign = 0 ;\n\n#if defined(NEED_TMP_TIME)\n    struct tm tmpTimeStorage;\n    tmpTime = &tmpTimeStorage;\n#else\n    (void)tmpTime;\n#endif\n\n    ltime = XTIME(0);\n\n#ifdef WOLFSSL_BEFORE_DATE_CLOCK_SKEW\n    if (dateType == BEFORE) {\n        WOLFSSL_MSG(\"Skewing local time for before date check\");\n        ltime += WOLFSSL_BEFORE_DATE_CLOCK_SKEW;\n    }\n#endif\n\n#ifdef WOLFSSL_AFTER_DATE_CLOCK_SKEW\n    if (dateType == AFTER) {\n        WOLFSSL_MSG(\"Skewing local time for after date check\");\n        ltime -= WOLFSSL_AFTER_DATE_CLOCK_SKEW;\n    }\n#endif\n\n    if (!ExtractDate(date, format, &certTime, &i)) {\n        WOLFSSL_MSG(\"Error extracting the date\");\n        return 0;\n    }\n\n    if ((date[i] == '+') || (date[i] == '-')) {\n        WOLFSSL_MSG(\"Using time differential, not Zulu\") ;\n        diffSign = date[i++] == '+' ? 1 : -1 ;\n        if (GetTime(&diffHH, date, &i) != 0)\n            return 0;\n        if (GetTime(&diffMM, date, &i) != 0)\n            return 0;\n        timeDiff = diffSign * (diffHH*60 + diffMM) * 60 ;\n    } else if (date[i] != 'Z') {\n        WOLFSSL_MSG(\"UTCtime, neither Zulu or time differential\") ;\n        return 0;\n    }\n\n    ltime -= (time_t)timeDiff ;\n    localTime = XGMTIME(&ltime, tmpTime);\n\n    if (localTime == NULL) {\n        WOLFSSL_MSG(\"XGMTIME failed\");\n        return 0;\n    }\n\n    if (dateType == BEFORE) {\n        if (DateLessThan(localTime, &certTime)) {\n            WOLFSSL_MSG(\"Date BEFORE check failed\");\n            return 0;\n        }\n    }\n    else {  /* dateType == AFTER */\n        if (DateGreaterThan(localTime, &certTime)) {\n            WOLFSSL_MSG(\"Date AFTER check failed\");\n            return 0;\n        }\n    }\n\n    return 1;\n}\n#endif /* USE_WOLF_VALIDDATE */\n\nint wc_GetTime(void* timePtr, word32 timeSize)\n{\n    time_t* ltime = (time_t*)timePtr;\n\n    if (timePtr == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if ((word32)sizeof(time_t) > timeSize) {\n        return BUFFER_E;\n    }\n\n    *ltime = XTIME(0);\n\n    return 0;\n}\n\n#endif /* !NO_ASN_TIME */\n\n\n/* Get date buffer, format and length. Returns 0=success or error */\nstatic int GetDateInfo(const byte* source, word32* idx, const byte** pDate,\n                        byte* pFormat, int* pLength, word32 maxIdx)\n{\n    int length;\n    byte format;\n\n    if (source == NULL || idx == NULL)\n        return BAD_FUNC_ARG;\n\n    /* get ASN format header */\n    if (*idx+1 > maxIdx)\n        return BUFFER_E;\n    format = source[*idx];\n    *idx += 1;\n    if (format != ASN_UTC_TIME && format != ASN_GENERALIZED_TIME)\n        return ASN_TIME_E;\n\n    /* get length */\n    if (GetLength(source, idx, &length, maxIdx) < 0)\n        return ASN_PARSE_E;\n    if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)\n        return ASN_DATE_SZ_E;\n\n    /* return format, date and length */\n    if (pFormat)\n        *pFormat = format;\n    if (pDate)\n        *pDate = &source[*idx];\n    if (pLength)\n        *pLength = length;\n\n    *idx += length;\n\n    return 0;\n}\n\nstatic int GetDate(DecodedCert* cert, int dateType, int verify, int maxIdx)\n{\n    int    ret, length;\n    const byte *datePtr = NULL;\n    byte   date[MAX_DATE_SIZE];\n    byte   format;\n    word32 startIdx = 0;\n\n    if (dateType == BEFORE)\n        cert->beforeDate = &cert->source[cert->srcIdx];\n    else\n        cert->afterDate = &cert->source[cert->srcIdx];\n    startIdx = cert->srcIdx;\n\n    ret = GetDateInfo(cert->source, &cert->srcIdx, &datePtr, &format,\n                      &length, maxIdx);\n    if (ret < 0)\n        return ret;\n\n    XMEMSET(date, 0, MAX_DATE_SIZE);\n    XMEMCPY(date, datePtr, length);\n\n    if (dateType == BEFORE)\n        cert->beforeDateLen = cert->srcIdx - startIdx;\n    else\n        cert->afterDateLen  = cert->srcIdx - startIdx;\n\n#ifndef NO_ASN_TIME\n    if (verify != NO_VERIFY && verify != VERIFY_SKIP_DATE &&\n            !XVALIDATE_DATE(date, format, dateType)) {\n        if (dateType == BEFORE)\n            return ASN_BEFORE_DATE_E;\n        else\n            return ASN_AFTER_DATE_E;\n    }\n#else\n    (void)verify;\n#endif\n\n    return 0;\n}\n\nstatic int GetValidity(DecodedCert* cert, int verify, int maxIdx)\n{\n    int length;\n    int badDate = 0;\n\n    if (GetSequence(cert->source, &cert->srcIdx, &length, maxIdx) < 0)\n        return ASN_PARSE_E;\n\n    maxIdx = cert->srcIdx + length;\n\n    if (GetDate(cert, BEFORE, verify, maxIdx) < 0)\n        badDate = ASN_BEFORE_DATE_E; /* continue parsing */\n\n    if (GetDate(cert, AFTER, verify, maxIdx) < 0)\n        return ASN_AFTER_DATE_E;\n\n    if (badDate != 0)\n        return badDate;\n\n    return 0;\n}\n\n\nint wc_GetDateInfo(const byte* certDate, int certDateSz, const byte** date,\n    byte* format, int* length)\n{\n    int ret;\n    word32 idx = 0;\n\n    ret = GetDateInfo(certDate, &idx, date, format, length, certDateSz);\n    if (ret < 0)\n        return ret;\n\n    return 0;\n}\n\n#ifndef NO_ASN_TIME\nint wc_GetDateAsCalendarTime(const byte* date, int length, byte format,\n    struct tm* timearg)\n{\n    int idx = 0;\n    (void)length;\n    if (!ExtractDate(date, format, timearg, &idx))\n        return ASN_TIME_E;\n    return 0;\n}\n\n#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_ALT_NAMES)\nint wc_GetCertDates(Cert* cert, struct tm* before, struct tm* after)\n{\n    int ret = 0;\n    const byte* date;\n    byte format;\n    int length;\n\n    if (cert == NULL)\n        return BAD_FUNC_ARG;\n\n    if (before && cert->beforeDateSz > 0) {\n        ret = wc_GetDateInfo(cert->beforeDate, cert->beforeDateSz, &date,\n                             &format, &length);\n        if (ret == 0)\n            ret = wc_GetDateAsCalendarTime(date, length, format, before);\n    }\n    if (after && cert->afterDateSz > 0) {\n        ret = wc_GetDateInfo(cert->afterDate, cert->afterDateSz, &date,\n                             &format, &length);\n        if (ret == 0)\n            ret = wc_GetDateAsCalendarTime(date, length, format, after);\n    }\n\n    return ret;\n}\n#endif /* WOLFSSL_CERT_GEN && WOLFSSL_ALT_NAMES */\n#endif /* !NO_ASN_TIME */\n\n/* parses certificate up to point of X.509 public key\n *\n * if cert date is invalid then badDate gets set to error value, otherwise is 0\n *\n * returns a negative value on fail case\n */\nint wc_GetPubX509(DecodedCert* cert, int verify, int* badDate)\n{\n    int ret;\n\n    if (cert == NULL || badDate == NULL)\n        return BAD_FUNC_ARG;\n\n    *badDate = 0;\n    if ( (ret = GetCertHeader(cert)) < 0)\n        return ret;\n\n    WOLFSSL_MSG(\"Got Cert Header\");\n\n    /* Using the sigIndex as the upper bound because that's where the\n     * actual certificate data ends. */\n    if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,\n                          oidSigType, cert->sigIndex)) < 0)\n        return ret;\n\n    WOLFSSL_MSG(\"Got Algo ID\");\n\n    if ( (ret = GetName(cert, ISSUER, cert->sigIndex)) < 0)\n        return ret;\n\n    if ( (ret = GetValidity(cert, verify, cert->sigIndex)) < 0)\n        *badDate = ret;\n\n    if ( (ret = GetName(cert, SUBJECT, cert->sigIndex)) < 0)\n        return ret;\n\n    WOLFSSL_MSG(\"Got Subject Name\");\n    return ret;\n}\n\nint DecodeToKey(DecodedCert* cert, int verify)\n{\n    int badDate = 0;\n    int ret;\n\n    if ( (ret = wc_GetPubX509(cert, verify, &badDate)) < 0)\n        return ret;\n\n    /* Determine if self signed */\n    cert->selfSigned = XMEMCMP(cert->issuerHash,\n                               cert->subjectHash,\n                               KEYID_SIZE) == 0 ? 1 : 0;\n\n    if ( (ret = GetKey(cert)) < 0)\n        return ret;\n\n    WOLFSSL_MSG(\"Got Key\");\n\n    if (badDate != 0)\n        return badDate;\n\n    return ret;\n}\n\nstatic int GetSignature(DecodedCert* cert)\n{\n    int length;\n    int ret;\n    ret = CheckBitString(cert->source, &cert->srcIdx, &length, cert->maxIdx, 1,\n                         NULL);\n    if (ret != 0)\n        return ret;\n\n    cert->sigLength = length;\n    cert->signature = &cert->source[cert->srcIdx];\n    cert->srcIdx += cert->sigLength;\n\n    return 0;\n}\n\nstatic word32 SetOctetString8Bit(word32 len, byte* output)\n{\n    output[0] = ASN_OCTET_STRING;\n    output[1] = (byte)len;\n    return 2;\n}\n\nstatic word32 SetDigest(const byte* digest, word32 digSz, byte* output)\n{\n    word32 idx = SetOctetString8Bit(digSz, output);\n    XMEMCPY(&output[idx], digest, digSz);\n\n    return idx + digSz;\n}\n\n\nstatic word32 BytePrecision(word32 value)\n{\n    word32 i;\n    for (i = sizeof(value); i; --i)\n        if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))\n            break;\n\n    return i;\n}\n\n\nWOLFSSL_LOCAL word32 SetLength(word32 length, byte* output)\n{\n    word32 i = 0, j;\n\n    if (length < ASN_LONG_LENGTH) {\n        if (output)\n            output[i] = (byte)length;\n        i++;\n    }\n    else {\n        if (output)\n            output[i] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);\n        i++;\n\n        for (j = BytePrecision(length); j; --j) {\n            if (output)\n                output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));\n            i++;\n        }\n    }\n\n    return i;\n}\n\n\nWOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output)\n{\n    if (output)\n        output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;\n    return SetLength(len, output ? output + 1 : NULL) + 1;\n}\n\nWOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output)\n{\n    output[0] = ASN_OCTET_STRING;\n    return SetLength(len, output + 1) + 1;\n}\n\n/* Write a set header to output */\nWOLFSSL_LOCAL word32 SetSet(word32 len, byte* output)\n{\n    output[0] = ASN_SET | ASN_CONSTRUCTED;\n    return SetLength(len, output + 1) + 1;\n}\n\nWOLFSSL_LOCAL word32 SetImplicit(byte tag, byte number, word32 len, byte* output)\n{\n\n    output[0] = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0)\n                    | ASN_CONTEXT_SPECIFIC | number;\n    return SetLength(len, output + 1) + 1;\n}\n\nWOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output)\n{\n    output[0] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number;\n    return SetLength(len, output + 1) + 1;\n}\n\n\n#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)\n\nstatic int SetCurve(ecc_key* key, byte* output)\n{\n#ifdef HAVE_OID_ENCODING\n    int ret;\n#endif\n    int idx = 0;\n    word32 oidSz = 0;\n\n    /* validate key */\n    if (key == NULL || key->dp == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef HAVE_OID_ENCODING\n    ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, NULL, &oidSz);\n    if (ret != 0) {\n        return ret;\n    }\n#else\n    oidSz = key->dp->oidSz;\n#endif\n\n    idx += SetObjectId(oidSz, output);\n\n#ifdef HAVE_OID_ENCODING\n    ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, output+idx, &oidSz);\n    if (ret != 0) {\n        return ret;\n    }\n#else\n    XMEMCPY(output+idx, key->dp->oid, oidSz);\n#endif\n    idx += oidSz;\n\n    return idx;\n}\n\n#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */\n\n\n#ifdef HAVE_ECC\nstatic WC_INLINE int IsSigAlgoECDSA(int algoOID)\n{\n    /* ECDSA sigAlgo must not have ASN1 NULL parameters */\n    if (algoOID == CTC_SHAwECDSA || algoOID == CTC_SHA256wECDSA ||\n        algoOID == CTC_SHA384wECDSA || algoOID == CTC_SHA512wECDSA) {\n        return 1;\n    }\n\n    return 0;\n}\n#endif\n\nWOLFSSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)\n{\n    word32 tagSz, idSz, seqSz, algoSz = 0;\n    const  byte* algoName = 0;\n    byte   ID_Length[1 + MAX_LENGTH_SZ];\n    byte   seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */\n\n    tagSz = (type == oidHashType ||\n             (type == oidSigType\n        #ifdef HAVE_ECC\n              && !IsSigAlgoECDSA(algoOID)\n        #endif\n        #ifdef HAVE_ED25519\n              && algoOID != ED25519k\n        #endif\n              ) ||\n             (type == oidKeyType && algoOID == RSAk)) ? 2 : 0;\n\n    algoName = OidFromId(algoOID, type, &algoSz);\n\n    if (algoName == NULL) {\n        WOLFSSL_MSG(\"Unknown Algorithm\");\n        return 0;\n    }\n\n    idSz  = SetObjectId(algoSz, ID_Length);\n    seqSz = SetSequence(idSz + algoSz + tagSz + curveSz, seqArray);\n\n    if (output) {\n        XMEMCPY(output, seqArray, seqSz);\n        XMEMCPY(output + seqSz, ID_Length, idSz);\n        XMEMCPY(output + seqSz + idSz, algoName, algoSz);\n        if (tagSz == 2)\n            SetASNNull(&output[seqSz + idSz + algoSz]);\n    }\n\n    return seqSz + idSz + algoSz + tagSz;\n\n}\n\n\nword32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz,\n                          int hashOID)\n{\n    byte digArray[MAX_ENCODED_DIG_SZ];\n    byte algoArray[MAX_ALGO_SZ];\n    byte seqArray[MAX_SEQ_SZ];\n    word32 encDigSz, algoSz, seqSz;\n\n    encDigSz = SetDigest(digest, digSz, digArray);\n    algoSz   = SetAlgoID(hashOID, algoArray, oidHashType, 0);\n    seqSz    = SetSequence(encDigSz + algoSz, seqArray);\n\n    XMEMCPY(out, seqArray, seqSz);\n    XMEMCPY(out + seqSz, algoArray, algoSz);\n    XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);\n\n    return encDigSz + algoSz + seqSz;\n}\n\n\n#ifndef NO_CERTS\n\nint wc_GetCTC_HashOID(int type)\n{\n    int ret;\n    enum wc_HashType hType;\n\n    hType = wc_HashTypeConvert(type);\n    ret = wc_HashGetOID(hType);\n    if (ret < 0)\n        ret = 0; /* backwards compatibility */\n\n    return ret;\n}\n\nvoid InitSignatureCtx(SignatureCtx* sigCtx, void* heap, int devId)\n{\n    if (sigCtx) {\n        XMEMSET(sigCtx, 0, sizeof(SignatureCtx));\n        sigCtx->devId = devId;\n        sigCtx->heap = heap;\n    }\n}\n\nvoid FreeSignatureCtx(SignatureCtx* sigCtx)\n{\n    if (sigCtx == NULL)\n        return;\n\n    if (sigCtx->digest) {\n        XFREE(sigCtx->digest, sigCtx->heap, DYNAMIC_TYPE_DIGEST);\n        sigCtx->digest = NULL;\n    }\n#ifndef NO_RSA\n    if (sigCtx->plain) {\n        XFREE(sigCtx->plain, sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);\n        sigCtx->plain = NULL;\n    }\n#endif\n#ifndef NO_ASN_CRYPT\n    if (sigCtx->key.ptr) {\n        switch (sigCtx->keyOID) {\n        #ifndef NO_RSA\n            case RSAk:\n                wc_FreeRsaKey(sigCtx->key.rsa);\n                XFREE(sigCtx->key.ptr, sigCtx->heap, DYNAMIC_TYPE_RSA);\n                break;\n        #endif /* !NO_RSA */\n        #ifdef HAVE_ECC\n            case ECDSAk:\n                wc_ecc_free(sigCtx->key.ecc);\n                XFREE(sigCtx->key.ecc, sigCtx->heap, DYNAMIC_TYPE_ECC);\n                break;\n        #endif /* HAVE_ECC */\n        #ifdef HAVE_ED25519\n            case ED25519k:\n                wc_ed25519_free(sigCtx->key.ed25519);\n                XFREE(sigCtx->key.ed25519, sigCtx->heap, DYNAMIC_TYPE_ED25519);\n                break;\n        #endif /* HAVE_ED25519 */\n            default:\n                break;\n        } /* switch (keyOID) */\n        sigCtx->key.ptr = NULL;\n    }\n#endif\n\n    /* reset state, we are done */\n    sigCtx->state = SIG_STATE_BEGIN;\n}\n\n#ifndef NO_ASN_CRYPT\nstatic int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,\n                            byte* digest, int* typeH, int* digestSz, int verify)\n{\n    int ret = 0;\n\n    (void)verify;\n\n    switch (sigOID) {\n    #if defined(WOLFSSL_MD2)\n        case CTC_MD2wRSA:\n            if (!verify) {\n                ret = HASH_TYPE_E;\n                WOLFSSL_MSG(\"MD2 not supported for signing\");\n            }\n            else if ((ret = wc_Md2Hash(buf, bufSz, digest)) == 0) {\n                *typeH    = MD2h;\n                *digestSz = MD2_DIGEST_SIZE;\n            }\n        break;\n    #endif\n    #ifndef NO_MD5\n        case CTC_MD5wRSA:\n            if ((ret = wc_Md5Hash(buf, bufSz, digest)) == 0) {\n                *typeH    = MD5h;\n                *digestSz = WC_MD5_DIGEST_SIZE;\n            }\n            break;\n    #endif\n    #ifndef NO_SHA\n        case CTC_SHAwRSA:\n        case CTC_SHAwDSA:\n        case CTC_SHAwECDSA:\n            if ((ret = wc_ShaHash(buf, bufSz, digest)) == 0) {\n                *typeH    = SHAh;\n                *digestSz = WC_SHA_DIGEST_SIZE;\n            }\n            break;\n    #endif\n    #ifdef WOLFSSL_SHA224\n        case CTC_SHA224wRSA:\n        case CTC_SHA224wECDSA:\n            if ((ret = wc_Sha224Hash(buf, bufSz, digest)) == 0) {\n                *typeH    = SHA224h;\n                *digestSz = WC_SHA224_DIGEST_SIZE;\n            }\n            break;\n    #endif\n    #ifndef NO_SHA256\n        case CTC_SHA256wRSA:\n        case CTC_SHA256wECDSA:\n            if ((ret = wc_Sha256Hash(buf, bufSz, digest)) == 0) {\n                *typeH    = SHA256h;\n                *digestSz = WC_SHA256_DIGEST_SIZE;\n            }\n            break;\n    #endif\n    #ifdef WOLFSSL_SHA384\n        case CTC_SHA384wRSA:\n        case CTC_SHA384wECDSA:\n            if ((ret = wc_Sha384Hash(buf, bufSz, digest)) == 0) {\n                *typeH    = SHA384h;\n                *digestSz = WC_SHA384_DIGEST_SIZE;\n            }\n            break;\n    #endif\n    #ifdef WOLFSSL_SHA512\n        case CTC_SHA512wRSA:\n        case CTC_SHA512wECDSA:\n            if ((ret = wc_Sha512Hash(buf, bufSz, digest)) == 0) {\n                *typeH    = SHA512h;\n                *digestSz = WC_SHA512_DIGEST_SIZE;\n            }\n            break;\n    #endif\n        case CTC_ED25519:\n            /* Hashes done in signing operation.\n             * Two dependent hashes with prefixes performed.\n             */\n            break;\n        default:\n            ret = HASH_TYPE_E;\n            WOLFSSL_MSG(\"Hash for Signature has unsupported type\");\n    }\n\n    return ret;\n}\n#endif /* !NO_ASN_CRYPT */\n\n/* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */\nstatic int ConfirmSignature(SignatureCtx* sigCtx,\n    const byte* buf, word32 bufSz,\n    const byte* key, word32 keySz, word32 keyOID,\n    const byte* sig, word32 sigSz, word32 sigOID, byte* rsaKeyIdx)\n{\n    int ret = 0;\n#ifndef WOLFSSL_RENESAS_TSIP_TLS\n    (void)rsaKeyIdx;\n#endif\n    if (sigCtx == NULL || buf == NULL || bufSz == 0 || key == NULL ||\n        keySz == 0 || sig == NULL || sigSz == 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    (void)key;\n    (void)keySz;\n    (void)sig;\n    (void)sigSz;\n\n    WOLFSSL_ENTER(\"ConfirmSignature\");\n\n#ifndef NO_ASN_CRYPT\n    switch (sigCtx->state) {\n        case SIG_STATE_BEGIN:\n        {\n            sigCtx->keyOID = keyOID; /* must set early for cleanup */\n\n            sigCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, sigCtx->heap,\n                                                    DYNAMIC_TYPE_DIGEST);\n            if (sigCtx->digest == NULL) {\n                ERROR_OUT(MEMORY_E, exit_cs);\n            }\n\n            sigCtx->state = SIG_STATE_HASH;\n        } /* SIG_STATE_BEGIN */\n        FALL_THROUGH;\n\n        case SIG_STATE_HASH:\n        {\n            ret = HashForSignature(buf, bufSz, sigOID, sigCtx->digest,\n                                   &sigCtx->typeH, &sigCtx->digestSz, 1);\n            if (ret != 0) {\n                goto exit_cs;\n            }\n\n            sigCtx->state = SIG_STATE_KEY;\n        } /* SIG_STATE_HASH */\n        FALL_THROUGH;\n\n        case SIG_STATE_KEY:\n        {\n            switch (keyOID) {\n            #ifndef NO_RSA\n                case RSAk:\n                {\n                    word32 idx = 0;\n\n                    sigCtx->key.rsa = (RsaKey*)XMALLOC(sizeof(RsaKey),\n                                                sigCtx->heap, DYNAMIC_TYPE_RSA);\n                    sigCtx->plain = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,\n                                         sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);\n                    if (sigCtx->key.rsa == NULL || sigCtx->plain == NULL) {\n                        ERROR_OUT(MEMORY_E, exit_cs);\n                    }\n                    if ((ret = wc_InitRsaKey_ex(sigCtx->key.rsa, sigCtx->heap,\n                                                        sigCtx->devId)) != 0) {\n                        goto exit_cs;\n                    }\n                    if (sigSz > MAX_ENCODED_SIG_SZ) {\n                        WOLFSSL_MSG(\"Verify Signature is too big\");\n                        ERROR_OUT(BUFFER_E, exit_cs);\n                    }\n                    if ((ret = wc_RsaPublicKeyDecode(key, &idx, sigCtx->key.rsa,\n                                                                 keySz)) != 0) {\n                        WOLFSSL_MSG(\"ASN Key decode error RSA\");\n                        goto exit_cs;\n                    }\n                    XMEMCPY(sigCtx->plain, sig, sigSz);\n                    sigCtx->out = NULL;\n\n                #ifdef WOLFSSL_ASYNC_CRYPT\n                    sigCtx->asyncDev = &sigCtx->key.rsa->asyncDev;\n                #endif\n                    break;\n                }\n            #endif /* !NO_RSA */\n            #ifdef HAVE_ECC\n                case ECDSAk:\n                {\n                    word32 idx = 0;\n\n                    sigCtx->verify = 0;\n                    sigCtx->key.ecc = (ecc_key*)XMALLOC(sizeof(ecc_key),\n                                                sigCtx->heap, DYNAMIC_TYPE_ECC);\n                    if (sigCtx->key.ecc == NULL) {\n                        ERROR_OUT(MEMORY_E, exit_cs);\n                    }\n                    if ((ret = wc_ecc_init_ex(sigCtx->key.ecc, sigCtx->heap,\n                                                          sigCtx->devId)) < 0) {\n                        goto exit_cs;\n                    }\n                    ret = wc_EccPublicKeyDecode(key, &idx, sigCtx->key.ecc,\n                                                                         keySz);\n                    if (ret < 0) {\n                        WOLFSSL_MSG(\"ASN Key import error ECC\");\n                        goto exit_cs;\n                    }\n                #ifdef WOLFSSL_ASYNC_CRYPT\n                    sigCtx->asyncDev = &sigCtx->key.ecc->asyncDev;\n                #endif\n                    break;\n                }\n            #endif /* HAVE_ECC */\n            #ifdef HAVE_ED25519\n                case ED25519k:\n                {\n                    sigCtx->verify = 0;\n                    sigCtx->key.ed25519 = (ed25519_key*)XMALLOC(\n                                              sizeof(ed25519_key), sigCtx->heap,\n                                              DYNAMIC_TYPE_ED25519);\n                    if (sigCtx->key.ed25519 == NULL) {\n                        ERROR_OUT(MEMORY_E, exit_cs);\n                    }\n                    if ((ret = wc_ed25519_init(sigCtx->key.ed25519)) < 0) {\n                        goto exit_cs;\n                    }\n                    if ((ret = wc_ed25519_import_public(key, keySz,\n                                                    sigCtx->key.ed25519)) < 0) {\n                        WOLFSSL_MSG(\"ASN Key import error ED25519\");\n                        goto exit_cs;\n                    }\n                #ifdef WOLFSSL_ASYNC_CRYPT\n                    sigCtx->asyncDev = &sigCtx->key.ed25519->asyncDev;\n                #endif\n                    break;\n                }\n            #endif\n                default:\n                    WOLFSSL_MSG(\"Verify Key type unknown\");\n                    ret = ASN_UNKNOWN_OID_E;\n                    break;\n            } /* switch (keyOID) */\n\n            if (ret != 0) {\n                goto exit_cs;\n            }\n\n            sigCtx->state = SIG_STATE_DO;\n\n        #ifdef WOLFSSL_ASYNC_CRYPT\n            if (sigCtx->devId != INVALID_DEVID && sigCtx->asyncDev && sigCtx->asyncCtx) {\n                /* make sure event is initialized */\n                WOLF_EVENT* event = &sigCtx->asyncDev->event;\n                ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL,\n                    sigCtx->asyncCtx, WC_ASYNC_FLAG_CALL_AGAIN);\n            }\n        #endif\n        } /* SIG_STATE_KEY */\n        FALL_THROUGH;\n\n        case SIG_STATE_DO:\n        {\n            switch (keyOID) {\n            #ifndef NO_RSA\n                case RSAk:\n                {\n                #ifdef HAVE_PK_CALLBACKS\n                    if (sigCtx->pkCbRsa) {\n                        ret = sigCtx->pkCbRsa(\n                                sigCtx->plain, sigSz, &sigCtx->out,\n                                key, keySz,\n                                sigCtx->pkCtxRsa);\n                    }\n                    else\n                #endif /* HAVE_PK_CALLBACKS */\n                    {\n                     #ifdef WOLFSSL_RENESAS_TSIP_TLS\n                        if (rsaKeyIdx != NULL)\n                        {\n                            ret = tsip_tls_CertVerify(buf, bufSz, sigCtx->plain,\n                                sigSz,\n                                sigCtx->pubkey_n_start - sigCtx->certBegin,\n                                sigCtx->pubkey_n_len - 1,\n                                sigCtx->pubkey_e_start - sigCtx->certBegin,\n                                sigCtx->pubkey_e_len - 1,\n                                rsaKeyIdx);\n\n                            if (ret == 0){\n                                sigCtx->verifyByTSIP = 1;\n                                ret = 0;\n                            } else {\n                                WOLFSSL_MSG(\"RSA Verify by tsip didn't match\");\n                                ret = ASN_SIG_CONFIRM_E;\n                            }\n                        } else\n                    #endif\n                        ret = wc_RsaSSL_VerifyInline(sigCtx->plain, sigSz,\n                                                 &sigCtx->out, sigCtx->key.rsa);\n                    }\n                    break;\n                }\n            #endif /* !NO_RSA */\n            #ifdef HAVE_ECC\n                case ECDSAk:\n                {\n                #ifdef HAVE_PK_CALLBACKS\n                    if (sigCtx->pkCbEcc) {\n                        ret = sigCtx->pkCbEcc(\n                                sig, sigSz,\n                                sigCtx->digest, sigCtx->digestSz,\n                                key, keySz, &sigCtx->verify,\n                                sigCtx->pkCtxEcc);\n                    }\n                    else\n                #endif /* HAVE_PK_CALLBACKS */\n                    {\n                        ret = wc_ecc_verify_hash(sig, sigSz, sigCtx->digest,\n                                            sigCtx->digestSz, &sigCtx->verify,\n                                            sigCtx->key.ecc);\n                    }\n                    break;\n                }\n            #endif /* HAVE_ECC */\n            #ifdef HAVE_ED25519\n                case ED25519k:\n                {\n                    ret = wc_ed25519_verify_msg(sig, sigSz, buf, bufSz,\n                                          &sigCtx->verify, sigCtx->key.ed25519);\n                    break;\n                }\n            #endif\n                default:\n                    break;\n            }  /* switch (keyOID) */\n\n        #ifdef WOLFSSL_ASYNC_CRYPT\n            if (ret == WC_PENDING_E) {\n                goto exit_cs;\n            }\n        #endif\n\n            if (ret < 0) {\n                /* treat all RSA errors as ASN_SIG_CONFIRM_E */\n                ret = ASN_SIG_CONFIRM_E;\n                goto exit_cs;\n            }\n\n            sigCtx->state = SIG_STATE_CHECK;\n        } /* SIG_STATE_DO */\n        FALL_THROUGH;\n\n        case SIG_STATE_CHECK:\n        {\n            switch (keyOID) {\n            #ifndef NO_RSA\n                case RSAk:\n                {\n                    int encodedSigSz, verifySz;\n                #ifdef WOLFSSL_RENESAS_TSIP\n                    if (sigCtx->verifyByTSIP == 1) break;\n                #endif\n                #ifdef WOLFSSL_SMALL_STACK\n                    byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,\n                                        sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);\n                    if (encodedSig == NULL) {\n                        ERROR_OUT(MEMORY_E, exit_cs);\n                    }\n                #else\n                    byte encodedSig[MAX_ENCODED_SIG_SZ];\n                #endif\n\n                    verifySz = ret;\n\n                    /* make sure we're right justified */\n                    encodedSigSz = wc_EncodeSignature(encodedSig,\n                            sigCtx->digest, sigCtx->digestSz, sigCtx->typeH);\n                    if (encodedSigSz == verifySz && sigCtx->out != NULL &&\n                        XMEMCMP(sigCtx->out, encodedSig, encodedSigSz) == 0) {\n                        ret = 0;\n                    }\n                    else {\n                        WOLFSSL_MSG(\"RSA SSL verify match encode error\");\n                        ret = ASN_SIG_CONFIRM_E;\n                    }\n\n                #ifdef WOLFSSL_SMALL_STACK\n                    XFREE(encodedSig, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);\n                #endif\n                    break;\n                }\n            #endif /* NO_RSA */\n            #ifdef HAVE_ECC\n                case ECDSAk:\n                {\n                    if (sigCtx->verify == 1) {\n                        ret = 0;\n                    }\n                    else {\n                        WOLFSSL_MSG(\"ECC Verify didn't match\");\n                        ret = ASN_SIG_CONFIRM_E;\n                    }\n                    break;\n                }\n            #endif /* HAVE_ECC */\n            #ifdef HAVE_ED25519\n                case ED25519k:\n                {\n                    if (sigCtx->verify == 1) {\n                        ret = 0;\n                    }\n                    else {\n                        WOLFSSL_MSG(\"ED25519 Verify didn't match\");\n                        ret = ASN_SIG_CONFIRM_E;\n                    }\n                    break;\n                }\n            #endif /* HAVE_ED25519 */\n                default:\n                    break;\n            }  /* switch (keyOID) */\n\n            break;\n        } /* SIG_STATE_CHECK */\n    } /* switch (sigCtx->state) */\n\nexit_cs:\n\n#endif /* !NO_ASN_CRYPT */\n\n    (void)keyOID;\n    (void)sigOID;\n\n    WOLFSSL_LEAVE(\"ConfirmSignature\", ret);\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    if (ret == WC_PENDING_E)\n        return ret;\n#endif\n\n    FreeSignatureCtx(sigCtx);\n\n    return ret;\n}\n\n\n#ifndef IGNORE_NAME_CONSTRAINTS\n\nstatic int MatchBaseName(int type, const char* name, int nameSz,\n                         const char* base, int baseSz)\n{\n    if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||\n            name[0] == '.' || nameSz < baseSz ||\n            (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE))\n        return 0;\n\n    /* If an email type, handle special cases where the base is only\n     * a domain, or is an email address itself. */\n    if (type == ASN_RFC822_TYPE) {\n        const char* p = NULL;\n        int count = 0;\n\n        if (base[0] != '.') {\n            p = base;\n            count = 0;\n\n            /* find the '@' in the base */\n            while (*p != '@' && count < baseSz) {\n                count++;\n                p++;\n            }\n\n            /* No '@' in base, reset p to NULL */\n            if (count >= baseSz)\n                p = NULL;\n        }\n\n        if (p == NULL) {\n            /* Base isn't an email address, it is a domain name,\n             * wind the name forward one character past its '@'. */\n            p = name;\n            count = 0;\n            while (*p != '@' && count < baseSz) {\n                count++;\n                p++;\n            }\n\n            if (count < baseSz && *p == '@') {\n                name = p + 1;\n                nameSz -= count + 1;\n            }\n        }\n    }\n\n    if ((type == ASN_DNS_TYPE || type == ASN_RFC822_TYPE) && base[0] == '.') {\n        int szAdjust = nameSz - baseSz;\n        name += szAdjust;\n        nameSz -= szAdjust;\n    }\n\n    while (nameSz > 0) {\n        if (XTOLOWER((unsigned char)*name++) !=\n                                               XTOLOWER((unsigned char)*base++))\n            return 0;\n        nameSz--;\n    }\n\n    return 1;\n}\n\n\nstatic int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)\n{\n    if (signer == NULL || cert == NULL)\n        return 0;\n\n    /* Check against the excluded list */\n    if (signer->excludedNames) {\n        Base_entry* base = signer->excludedNames;\n\n        while (base != NULL) {\n            switch (base->type) {\n                case ASN_DNS_TYPE:\n                {\n                    DNS_entry* name = cert->altNames;\n                    while (name != NULL) {\n                        if (MatchBaseName(ASN_DNS_TYPE,\n                                          name->name, name->len,\n                                          base->name, base->nameSz)) {\n                            return 0;\n                        }\n                        name = name->next;\n                    }\n                    break;\n                }\n                case ASN_RFC822_TYPE:\n                {\n                    DNS_entry* name = cert->altEmailNames;\n                    while (name != NULL) {\n                        if (MatchBaseName(ASN_RFC822_TYPE,\n                                          name->name, name->len,\n                                          base->name, base->nameSz)) {\n                            return 0;\n                        }\n                        name = name->next;\n                    }\n                    break;\n                }\n                case ASN_DIR_TYPE:\n                {\n                    /* allow permitted dirName smaller than actual subject */\n                    if (cert->subjectRawLen >= base->nameSz &&\n                        XMEMCMP(cert->subjectRaw, base->name,\n                                                        base->nameSz) == 0) {\n                        return 0;\n                    }\n                    break;\n                }\n            }; /* switch */\n            base = base->next;\n        }\n    }\n\n    /* Check against the permitted list */\n    if (signer->permittedNames != NULL) {\n        int needDns = 0;\n        int matchDns = 0;\n        int needEmail = 0;\n        int matchEmail = 0;\n        int needDir = 0;\n        int matchDir = 0;\n        Base_entry* base = signer->permittedNames;\n\n        while (base != NULL) {\n            switch (base->type) {\n                case ASN_DNS_TYPE:\n                {\n                    DNS_entry* name = cert->altNames;\n\n                    if (name != NULL)\n                        needDns = 1;\n\n                    while (name != NULL) {\n                        matchDns = MatchBaseName(ASN_DNS_TYPE,\n                                          name->name, name->len,\n                                          base->name, base->nameSz);\n                        name = name->next;\n                    }\n                    break;\n                }\n                case ASN_RFC822_TYPE:\n                {\n                    DNS_entry* name = cert->altEmailNames;\n\n                    if (name != NULL)\n                        needEmail = 1;\n\n                    while (name != NULL) {\n                        matchEmail = MatchBaseName(ASN_DNS_TYPE,\n                                          name->name, name->len,\n                                          base->name, base->nameSz);\n                        name = name->next;\n                    }\n                    break;\n                }\n                case ASN_DIR_TYPE:\n                {\n                    /* allow permitted dirName smaller than actual subject */\n                    needDir = 1;\n                    if (cert->subjectRaw != NULL &&\n                        cert->subjectRawLen >= base->nameSz &&\n                        XMEMCMP(cert->subjectRaw, base->name,\n                                                        base->nameSz) == 0) {\n                        matchDir = 1;\n                    }\n                    break;\n                }\n            } /* switch */\n            base = base->next;\n        }\n\n        if ((needDns   && !matchDns) ||\n            (needEmail && !matchEmail) ||\n            (needDir   && !matchDir)) {\n            return 0;\n        }\n    }\n\n    return 1;\n}\n\n#endif /* IGNORE_NAME_CONSTRAINTS */\n\nstatic int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)\n{\n    word32 idx = 0;\n    int length = 0;\n\n    WOLFSSL_ENTER(\"DecodeAltNames\");\n\n    if (GetSequence(input, &idx, &length, sz) < 0) {\n        WOLFSSL_MSG(\"\\tBad Sequence\");\n        return ASN_PARSE_E;\n    }\n\n    cert->weOwnAltNames = 1;\n\n    while (length > 0) {\n        byte b = input[idx++];\n\n        length--;\n\n        /* Save DNS Type names in the altNames list. */\n        /* Save Other Type names in the cert's OidMap */\n        if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {\n            DNS_entry* dnsEntry;\n            int strLen;\n            word32 lenStartIdx = idx;\n\n            if (GetLength(input, &idx, &strLen, sz) < 0) {\n                WOLFSSL_MSG(\"\\tfail: str length\");\n                return ASN_PARSE_E;\n            }\n            length -= (idx - lenStartIdx);\n\n            dnsEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,\n                                        DYNAMIC_TYPE_ALTNAME);\n            if (dnsEntry == NULL) {\n                WOLFSSL_MSG(\"\\tOut of Memory\");\n                return MEMORY_E;\n            }\n\n            dnsEntry->type = ASN_DNS_TYPE;\n            dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,\n                                         DYNAMIC_TYPE_ALTNAME);\n            if (dnsEntry->name == NULL) {\n                WOLFSSL_MSG(\"\\tOut of Memory\");\n                XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);\n                return MEMORY_E;\n            }\n            dnsEntry->len = strLen;\n            XMEMCPY(dnsEntry->name, &input[idx], strLen);\n            dnsEntry->name[strLen] = '\\0';\n\n            dnsEntry->next = cert->altNames;\n            cert->altNames = dnsEntry;\n\n            length -= strLen;\n            idx    += strLen;\n        }\n    #ifndef IGNORE_NAME_CONSTRAINTS\n        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {\n            DNS_entry* emailEntry;\n            int strLen;\n            word32 lenStartIdx = idx;\n\n            if (GetLength(input, &idx, &strLen, sz) < 0) {\n                WOLFSSL_MSG(\"\\tfail: str length\");\n                return ASN_PARSE_E;\n            }\n            length -= (idx - lenStartIdx);\n\n            emailEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,\n                                        DYNAMIC_TYPE_ALTNAME);\n            if (emailEntry == NULL) {\n                WOLFSSL_MSG(\"\\tOut of Memory\");\n                return MEMORY_E;\n            }\n\n            emailEntry->type = ASN_RFC822_TYPE;\n            emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,\n                                         DYNAMIC_TYPE_ALTNAME);\n            if (emailEntry->name == NULL) {\n                WOLFSSL_MSG(\"\\tOut of Memory\");\n                XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);\n                return MEMORY_E;\n            }\n            emailEntry->len = strLen;\n            XMEMCPY(emailEntry->name, &input[idx], strLen);\n            emailEntry->name[strLen] = '\\0';\n\n            emailEntry->next = cert->altEmailNames;\n            cert->altEmailNames = emailEntry;\n\n            length -= strLen;\n            idx    += strLen;\n        }\n        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {\n            DNS_entry* uriEntry;\n            int strLen;\n            word32 lenStartIdx = idx;\n\n            WOLFSSL_MSG(\"\\tPutting URI into list but not using\");\n            if (GetLength(input, &idx, &strLen, sz) < 0) {\n                WOLFSSL_MSG(\"\\tfail: str length\");\n                return ASN_PARSE_E;\n            }\n            length -= (idx - lenStartIdx);\n\n            /* check that strLen at index is not past input buffer */\n            if (strLen + (int)idx > sz) {\n                return BUFFER_E;\n            }\n\n        #ifndef WOLFSSL_NO_ASN_STRICT\n            /* Verify RFC 5280 Sec 4.2.1.6 rule:\n                \"The name MUST NOT be a relative URI\" */\n\n            {\n                int i;\n\n                /* skip past scheme (i.e http,ftp,...) finding first ':' char */\n                for (i = 0; i < strLen; i++) {\n                    if (input[idx + i] == ':') {\n                        break;\n                    }\n                    if (input[idx + i] == '/') {\n                        i = strLen; /* error, found relative path since '/' was\n                                     * encountered before ':'. Returning error\n                                     * value in next if statement. */\n                    }\n                }\n\n                /* test if no ':' char was found and test that the next two\n                 * chars are // to match the pattern \"://\" */\n                if (i >= strLen - 2 || (input[idx + i + 1] != '/' ||\n                                        input[idx + i + 2] != '/')) {\n                    WOLFSSL_MSG(\"\\tAlt Name must be absolute URI\");\n                    return ASN_ALT_NAME_E;\n                }\n            }\n        #endif\n\n            uriEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,\n                                        DYNAMIC_TYPE_ALTNAME);\n            if (uriEntry == NULL) {\n                WOLFSSL_MSG(\"\\tOut of Memory\");\n                return MEMORY_E;\n            }\n\n            uriEntry->type = ASN_URI_TYPE;\n            uriEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,\n                                         DYNAMIC_TYPE_ALTNAME);\n            if (uriEntry->name == NULL) {\n                WOLFSSL_MSG(\"\\tOut of Memory\");\n                XFREE(uriEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);\n                return MEMORY_E;\n            }\n            uriEntry->len = strLen;\n            XMEMCPY(uriEntry->name, &input[idx], strLen);\n            uriEntry->name[strLen] = '\\0';\n\n            uriEntry->next = cert->altNames;\n            cert->altNames = uriEntry;\n\n            length -= strLen;\n            idx    += strLen;\n        }\n#endif /* IGNORE_NAME_CONSTRAINTS */\n#ifdef WOLFSSL_SEP\n        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))\n        {\n            int strLen;\n            word32 lenStartIdx = idx;\n            word32 oid = 0;\n            int    ret;\n            byte   tag;\n\n            if (GetLength(input, &idx, &strLen, sz) < 0) {\n                WOLFSSL_MSG(\"\\tfail: other name length\");\n                return ASN_PARSE_E;\n            }\n            /* Consume the rest of this sequence. */\n            length -= (strLen + idx - lenStartIdx);\n\n            if (GetObjectId(input, &idx, &oid, oidCertAltNameType, sz) < 0) {\n                WOLFSSL_MSG(\"\\tbad OID\");\n                return ASN_PARSE_E;\n            }\n\n            if (oid != HW_NAME_OID) {\n                WOLFSSL_MSG(\"\\tincorrect OID\");\n                return ASN_PARSE_E;\n            }\n\n            if (GetASNTag(input, &idx, &tag, sz) < 0) {\n                return ASN_PARSE_E;\n            }\n\n            if (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {\n                WOLFSSL_MSG(\"\\twrong type\");\n                return ASN_PARSE_E;\n            }\n\n            if (GetLength(input, &idx, &strLen, sz) < 0) {\n                WOLFSSL_MSG(\"\\tfail: str len\");\n                return ASN_PARSE_E;\n            }\n\n            if (GetSequence(input, &idx, &strLen, sz) < 0) {\n                WOLFSSL_MSG(\"\\tBad Sequence\");\n                return ASN_PARSE_E;\n            }\n\n            ret = GetASNObjectId(input, &idx, &strLen, sz);\n            if (ret != 0) {\n                WOLFSSL_MSG(\"\\tbad OID\");\n                return ret;\n            }\n\n            cert->hwType = (byte*)XMALLOC(strLen, cert->heap,\n                                          DYNAMIC_TYPE_X509_EXT);\n            if (cert->hwType == NULL) {\n                WOLFSSL_MSG(\"\\tOut of Memory\");\n                return MEMORY_E;\n            }\n\n            XMEMCPY(cert->hwType, &input[idx], strLen);\n            cert->hwTypeSz = strLen;\n            idx += strLen;\n\n            ret = GetOctetString(input, &idx, &strLen, sz);\n            if (ret < 0)\n                return ret;\n\n            cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap,\n                                               DYNAMIC_TYPE_X509_EXT);\n            if (cert->hwSerialNum == NULL) {\n                WOLFSSL_MSG(\"\\tOut of Memory\");\n                return MEMORY_E;\n            }\n\n            XMEMCPY(cert->hwSerialNum, &input[idx], strLen);\n            cert->hwSerialNum[strLen] = '\\0';\n            cert->hwSerialNumSz = strLen;\n            idx += strLen;\n        }\n    #endif /* WOLFSSL_SEP */\n        else {\n            int strLen;\n            word32 lenStartIdx = idx;\n\n            WOLFSSL_MSG(\"\\tUnsupported name type, skipping\");\n\n            if (GetLength(input, &idx, &strLen, sz) < 0) {\n                WOLFSSL_MSG(\"\\tfail: unsupported name length\");\n                return ASN_PARSE_E;\n            }\n            length -= (strLen + idx - lenStartIdx);\n            idx += strLen;\n        }\n    }\n    return 0;\n}\n\nstatic int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)\n{\n    word32 idx = 0;\n    int length = 0;\n    int ret;\n\n    WOLFSSL_ENTER(\"DecodeBasicCaConstraint\");\n\n    if (GetSequence(input, &idx, &length, sz) < 0) {\n        WOLFSSL_MSG(\"\\tfail: bad SEQUENCE\");\n        return ASN_PARSE_E;\n    }\n\n    if (length == 0)\n        return 0;\n\n    /* If the basic ca constraint is false, this extension may be named, but\n     * left empty. So, if the length is 0, just return. */\n\n    ret = GetBoolean(input, &idx, sz);\n\n#ifndef WOLFSSL_X509_BASICCONS_INT\n    if (ret < 0) {\n        WOLFSSL_MSG(\"\\tfail: constraint not valid BOOLEAN\");\n        return ret;\n    }\n\n    cert->isCA = (byte)ret;\n#else\n    if (ret < 0) {\n        if(input[idx] == ASN_INTEGER) {\n            /* For OpenSSL compatibility, if ASN_INTEGER it is valid format */\n            cert->isCA = FALSE;\n        } else return ret;\n    } else\n        cert->isCA = (byte)ret;\n#endif\n\n    /* If there isn't any more data, return. */\n    if (idx >= (word32)sz) {\n        return 0;\n    }\n\n    ret = GetInteger7Bit(input, &idx, sz);\n    if (ret < 0)\n        return ret;\n    cert->pathLength = (byte)ret;\n    cert->pathLengthSet = 1;\n\n    return 0;\n}\n\n\n#define CRLDP_FULL_NAME 0\n    /* From RFC3280 SS4.2.1.14, Distribution Point Name*/\n#define GENERALNAME_URI 6\n    /* From RFC3280 SS4.2.1.7, GeneralName */\n\nstatic int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert)\n{\n    word32 idx = 0, localIdx;\n    int length = 0;\n    byte tag   = 0;\n\n    WOLFSSL_ENTER(\"DecodeCrlDist\");\n\n    /* Unwrap the list of Distribution Points*/\n    if (GetSequence(input, &idx, &length, sz) < 0)\n        return ASN_PARSE_E;\n\n    /* Unwrap a single Distribution Point */\n    if (GetSequence(input, &idx, &length, sz) < 0)\n        return ASN_PARSE_E;\n\n    /* The Distribution Point has three explicit optional members\n     *  First check for a DistributionPointName\n     */\n    localIdx = idx;\n    if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&\n            tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))\n    {\n        idx++;\n        if (GetLength(input, &idx, &length, sz) < 0)\n            return ASN_PARSE_E;\n\n        localIdx = idx;\n        if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&\n                tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED |\n                    CRLDP_FULL_NAME))\n        {\n            idx++;\n            if (GetLength(input, &idx, &length, sz) < 0)\n                return ASN_PARSE_E;\n\n            localIdx = idx;\n            if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&\n                    tag == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))\n            {\n                idx++;\n                if (GetLength(input, &idx, &length, sz) < 0)\n                    return ASN_PARSE_E;\n\n                cert->extCrlInfoSz = length;\n                cert->extCrlInfo = input + idx;\n                idx += length;\n            }\n            else\n                /* This isn't a URI, skip it. */\n                idx += length;\n        }\n        else {\n            /* This isn't a FULLNAME, skip it. */\n            idx += length;\n        }\n    }\n\n    /* Check for reasonFlags */\n    localIdx = idx;\n    if (idx < (word32)sz &&\n        GetASNTag(input, &localIdx, &tag, sz) == 0 &&\n        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))\n    {\n        idx++;\n        if (GetLength(input, &idx, &length, sz) < 0)\n            return ASN_PARSE_E;\n        idx += length;\n    }\n\n    /* Check for cRLIssuer */\n    localIdx = idx;\n    if (idx < (word32)sz &&\n        GetASNTag(input, &localIdx, &tag, sz) == 0 &&\n        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))\n    {\n        idx++;\n        if (GetLength(input, &idx, &length, sz) < 0)\n            return ASN_PARSE_E;\n        idx += length;\n    }\n\n    if (idx < (word32)sz)\n    {\n        WOLFSSL_MSG(\"\\tThere are more CRL Distribution Point records, \"\n                   \"but we only use the first one.\");\n    }\n\n    return 0;\n}\n\n\nstatic int DecodeAuthInfo(const byte* input, int sz, DecodedCert* cert)\n/*\n *  Read the first of the Authority Information Access records. If there are\n *  any issues, return without saving the record.\n */\n{\n    word32 idx = 0;\n    int length = 0;\n    byte b = 0;\n    word32 oid;\n\n    WOLFSSL_ENTER(\"DecodeAuthInfo\");\n\n    /* Unwrap the list of AIAs */\n    if (GetSequence(input, &idx, &length, sz) < 0)\n        return ASN_PARSE_E;\n\n    while (idx < (word32)sz) {\n        /* Unwrap a single AIA */\n        if (GetSequence(input, &idx, &length, sz) < 0)\n            return ASN_PARSE_E;\n\n        oid = 0;\n        if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0)\n            return ASN_PARSE_E;\n\n\n        /* Only supporting URIs right now. */\n        if (GetASNTag(input, &idx, &b, sz) < 0)\n            return ASN_PARSE_E;\n\n        if (GetLength(input, &idx, &length, sz) < 0)\n            return ASN_PARSE_E;\n\n        if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) &&\n            oid == AIA_OCSP_OID)\n        {\n            cert->extAuthInfoSz = length;\n            cert->extAuthInfo = input + idx;\n            break;\n        }\n        idx += length;\n    }\n\n    return 0;\n}\n\n\nstatic int DecodeAuthKeyId(const byte* input, int sz, DecodedCert* cert)\n{\n    word32 idx = 0;\n    int length = 0, ret = 0;\n    byte tag;\n\n    WOLFSSL_ENTER(\"DecodeAuthKeyId\");\n\n    if (GetSequence(input, &idx, &length, sz) < 0) {\n        WOLFSSL_MSG(\"\\tfail: should be a SEQUENCE\\n\");\n        return ASN_PARSE_E;\n    }\n\n    if (GetASNTag(input, &idx, &tag, sz) < 0) {\n        return ASN_PARSE_E;\n    }\n\n    if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {\n        WOLFSSL_MSG(\"\\tinfo: OPTIONAL item 0, not available\\n\");\n        return 0;\n    }\n\n    if (GetLength(input, &idx, &length, sz) <= 0) {\n        WOLFSSL_MSG(\"\\tfail: extension data length\");\n        return ASN_PARSE_E;\n    }\n\n#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n    cert->extAuthKeyIdSrc = &input[idx];\n    cert->extAuthKeyIdSz = length;\n#endif /* OPENSSL_EXTRA */\n\n    if (length == KEYID_SIZE) {\n        XMEMCPY(cert->extAuthKeyId, input + idx, length);\n    }\n    else\n        ret = CalcHashId(input + idx, length, cert->extAuthKeyId);\n\n    return ret;\n}\n\n\nstatic int DecodeSubjKeyId(const byte* input, int sz, DecodedCert* cert)\n{\n    word32 idx = 0;\n    int length = 0, ret = 0;\n\n    WOLFSSL_ENTER(\"DecodeSubjKeyId\");\n\n    if (sz <= 0)\n        return ASN_PARSE_E;\n\n    ret = GetOctetString(input, &idx, &length, sz);\n    if (ret < 0)\n        return ret;\n\n    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n        cert->extSubjKeyIdSrc = &input[idx];\n        cert->extSubjKeyIdSz = length;\n    #endif /* OPENSSL_EXTRA */\n\n    if (length == KEYID_SIZE) {\n        XMEMCPY(cert->extSubjKeyId, input + idx, length);\n    }\n    else\n        ret = CalcHashId(input + idx, length, cert->extSubjKeyId);\n\n    return ret;\n}\n\n\nstatic int DecodeKeyUsage(const byte* input, int sz, DecodedCert* cert)\n{\n    word32 idx = 0;\n    int length;\n    int ret;\n    WOLFSSL_ENTER(\"DecodeKeyUsage\");\n\n    ret = CheckBitString(input, &idx, &length, sz, 0, NULL);\n    if (ret != 0)\n        return ret;\n\n    cert->extKeyUsage = (word16)(input[idx]);\n    if (length == 2)\n        cert->extKeyUsage |= (word16)(input[idx+1] << 8);\n\n    return 0;\n}\n\n\nstatic int DecodeExtKeyUsage(const byte* input, int sz, DecodedCert* cert)\n{\n    word32 idx = 0, oid;\n    int length, ret;\n\n    WOLFSSL_MSG(\"DecodeExtKeyUsage\");\n\n    if (GetSequence(input, &idx, &length, sz) < 0) {\n        WOLFSSL_MSG(\"\\tfail: should be a SEQUENCE\");\n        return ASN_PARSE_E;\n    }\n\n#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n    cert->extExtKeyUsageSrc = input + idx;\n    cert->extExtKeyUsageSz = length;\n#endif\n\n    while (idx < (word32)sz) {\n        ret = GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz);\n        if (ret == ASN_UNKNOWN_OID_E)\n            continue;\n        else if (ret < 0)\n            return ret;\n\n        switch (oid) {\n            case EKU_ANY_OID:\n                cert->extExtKeyUsage |= EXTKEYUSE_ANY;\n                break;\n            case EKU_SERVER_AUTH_OID:\n                cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;\n                break;\n            case EKU_CLIENT_AUTH_OID:\n                cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;\n                break;\n            case EKU_CODESIGNING_OID:\n                cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;\n                break;\n            case EKU_EMAILPROTECT_OID:\n                cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;\n                break;\n            case EKU_TIMESTAMP_OID:\n                cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;\n                break;\n            case EKU_OCSP_SIGN_OID:\n                cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;\n                break;\n        }\n\n    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n        cert->extExtKeyUsageCount++;\n    #endif\n    }\n\n    return 0;\n}\n\n\n#ifndef IGNORE_NAME_CONSTRAINTS\n#define ASN_TYPE_MASK 0xF\nstatic int DecodeSubtree(const byte* input, int sz,\n                         Base_entry** head, void* heap)\n{\n    word32 idx = 0;\n\n    (void)heap;\n\n    while (idx < (word32)sz) {\n        int seqLength, strLength;\n        word32 nameIdx;\n        byte b, bType;\n\n        if (GetSequence(input, &idx, &seqLength, sz) < 0) {\n            WOLFSSL_MSG(\"\\tfail: should be a SEQUENCE\");\n            return ASN_PARSE_E;\n        }\n        nameIdx = idx;\n        b = input[nameIdx++];\n\n        if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {\n            WOLFSSL_MSG(\"\\tinvalid length\");\n            return ASN_PARSE_E;\n        }\n\n        /* Get type, LSB 4-bits */\n        bType = (b & ASN_TYPE_MASK);\n\n        if (bType == ASN_DNS_TYPE || bType == ASN_RFC822_TYPE ||\n                                                        bType == ASN_DIR_TYPE) {\n            Base_entry* entry;\n\n            /* if constructed has leading sequence */\n            if (b & ASN_CONSTRUCTED) {\n                if (GetSequence(input, &nameIdx, &strLength, sz) < 0) {\n                    WOLFSSL_MSG(\"\\tfail: constructed be a SEQUENCE\");\n                    return ASN_PARSE_E;\n                }\n            }\n\n            entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap,\n                                                          DYNAMIC_TYPE_ALTNAME);\n            if (entry == NULL) {\n                WOLFSSL_MSG(\"allocate error\");\n                return MEMORY_E;\n            }\n\n            entry->name = (char*)XMALLOC(strLength, heap, DYNAMIC_TYPE_ALTNAME);\n            if (entry->name == NULL) {\n                WOLFSSL_MSG(\"allocate error\");\n                XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);\n                return MEMORY_E;\n            }\n\n            XMEMCPY(entry->name, &input[nameIdx], strLength);\n            entry->nameSz = strLength;\n            entry->type = bType;\n\n            entry->next = *head;\n            *head = entry;\n        }\n\n        idx += seqLength;\n    }\n\n    return 0;\n}\n\n\nstatic int DecodeNameConstraints(const byte* input, int sz, DecodedCert* cert)\n{\n    word32 idx = 0;\n    int length = 0;\n\n    WOLFSSL_ENTER(\"DecodeNameConstraints\");\n\n    if (GetSequence(input, &idx, &length, sz) < 0) {\n        WOLFSSL_MSG(\"\\tfail: should be a SEQUENCE\");\n        return ASN_PARSE_E;\n    }\n\n    while (idx < (word32)sz) {\n        byte b = input[idx++];\n        Base_entry** subtree = NULL;\n\n        if (GetLength(input, &idx, &length, sz) <= 0) {\n            WOLFSSL_MSG(\"\\tinvalid length\");\n            return ASN_PARSE_E;\n        }\n\n        if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))\n            subtree = &cert->permittedNames;\n        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))\n            subtree = &cert->excludedNames;\n        else {\n            WOLFSSL_MSG(\"\\tinvalid subtree\");\n            return ASN_PARSE_E;\n        }\n\n        DecodeSubtree(input + idx, length, subtree, cert->heap);\n\n        idx += length;\n    }\n\n    return 0;\n}\n#endif /* IGNORE_NAME_CONSTRAINTS */\n\n#if (defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)) || defined(OPENSSL_EXTRA)\n\n/* Decode ITU-T X.690 OID format to a string representation\n * return string length */\nint DecodePolicyOID(char *out, word32 outSz, const byte *in, word32 inSz)\n{\n    word32 val, inIdx = 0, outIdx = 0;\n    int w = 0;\n\n    if (out == NULL || in == NULL || outSz < 4 || inSz < 2)\n        return BAD_FUNC_ARG;\n\n    /* The first byte expands into b/40 dot b%40. */\n    val = in[inIdx++];\n\n    w = XSNPRINTF(out, outSz, \"%u.%u\", val / 40, val % 40);\n    if (w < 0)\n        goto exit;\n    outIdx += w;\n    val = 0;\n\n    while (inIdx < inSz && outIdx < outSz) {\n        /* extract the next OID digit from in to val */\n        /* first bit is used to set if value is coded on 1 or multiple bytes */\n        if (in[inIdx] & 0x80) {\n            val += in[inIdx] & 0x7F;\n            val *= 128;\n        }\n        else {\n            /* write val as text into out */\n            val += in[inIdx];\n            w = XSNPRINTF(out + outIdx, outSz - outIdx, \".%u\", val);\n            if (w < 0)\n                goto exit;\n            outIdx += w;\n            val = 0;\n        }\n        inIdx++;\n    }\n    if (outIdx == outSz)\n        outIdx--;\n    out[outIdx] = 0;\n\n    w = (int)outIdx;\n\nexit:\n    return w;\n}\n#endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */\n\n#if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)\n    /* Reference: https://tools.ietf.org/html/rfc5280#section-4.2.1.4 */\n    static int DecodeCertPolicy(const byte* input, int sz, DecodedCert* cert)\n    {\n        word32 idx = 0;\n        word32 oldIdx;\n        int ret;\n        int total_length = 0, policy_length = 0, length = 0;\n    #if !defined(WOLFSSL_SEP) && defined(WOLFSSL_CERT_EXT) && \\\n        !defined(WOLFSSL_DUP_CERTPOL)\n        int i;\n    #endif\n\n        WOLFSSL_ENTER(\"DecodeCertPolicy\");\n\n    #if defined(WOLFSSL_CERT_EXT)\n         cert->extCertPoliciesNb = 0;\n    #endif\n\n        if (GetSequence(input, &idx, &total_length, sz) < 0) {\n            WOLFSSL_MSG(\"\\tGet CertPolicy total seq failed\");\n            return ASN_PARSE_E;\n        }\n\n        /* Validate total length */\n        if (total_length > (sz - (int)idx)) {\n            WOLFSSL_MSG(\"\\tCertPolicy length mismatch\");\n            return ASN_PARSE_E;\n        }\n\n        /* Unwrap certificatePolicies */\n        do {\n            if (GetSequence(input, &idx, &policy_length, sz) < 0) {\n                WOLFSSL_MSG(\"\\tGet CertPolicy seq failed\");\n                return ASN_PARSE_E;\n            }\n\n            oldIdx = idx;\n            ret = GetASNObjectId(input, &idx, &length, sz);\n            if (ret != 0)\n                return ret;\n            policy_length -= idx - oldIdx;\n\n            if (length > 0) {\n                /* Verify length won't overrun buffer */\n                if (length > (sz - (int)idx)) {\n                    WOLFSSL_MSG(\"\\tCertPolicy length exceeds input buffer\");\n                    return ASN_PARSE_E;\n                }\n\n        #if defined(WOLFSSL_SEP)\n                cert->deviceType = (byte*)XMALLOC(length, cert->heap,\n                                                         DYNAMIC_TYPE_X509_EXT);\n                if (cert->deviceType == NULL) {\n                    WOLFSSL_MSG(\"\\tCouldn't alloc memory for deviceType\");\n                    return MEMORY_E;\n                }\n                cert->deviceTypeSz = length;\n                XMEMCPY(cert->deviceType, input + idx, length);\n                break;\n        #elif defined(WOLFSSL_CERT_EXT)\n                /* decode cert policy */\n                if (DecodePolicyOID(cert->extCertPolicies[\n                                       cert->extCertPoliciesNb], MAX_CERTPOL_SZ,\n                                       input + idx, length) <= 0) {\n                    WOLFSSL_MSG(\"\\tCouldn't decode CertPolicy\");\n                    return ASN_PARSE_E;\n                }\n            #ifndef WOLFSSL_DUP_CERTPOL\n                /* From RFC 5280 section 4.2.1.3 \"A certificate policy OID MUST\n                 * NOT appear more than once in a certificate policies\n                 * extension\". This is a sanity check for duplicates.\n                 * extCertPolicies should only have OID values, additional\n                 * qualifiers need to be stored in a seperate array. */\n                for (i = 0; i < cert->extCertPoliciesNb; i++) {\n                    if (XMEMCMP(cert->extCertPolicies[i],\n                            cert->extCertPolicies[cert->extCertPoliciesNb],\n                            MAX_CERTPOL_SZ) == 0) {\n                            WOLFSSL_MSG(\"Duplicate policy OIDs not allowed\");\n                            WOLFSSL_MSG(\"Use WOLFSSL_DUP_CERTPOL if wanted\");\n                            return CERTPOLICIES_E;\n                    }\n                }\n            #endif /* !WOLFSSL_DUP_CERTPOL */\n                cert->extCertPoliciesNb++;\n        #else\n                WOLFSSL_LEAVE(\"DecodeCertPolicy : unsupported mode\", 0);\n                return 0;\n        #endif\n            }\n            idx += policy_length;\n        } while((int)idx < total_length\n    #if defined(WOLFSSL_CERT_EXT)\n            && cert->extCertPoliciesNb < MAX_CERTPOL_NB\n    #endif\n        );\n\n        WOLFSSL_LEAVE(\"DecodeCertPolicy\", 0);\n        return 0;\n    }\n#endif /* WOLFSSL_SEP */\n\n/* Macro to check if bit is set, if not sets and return success.\n    Otherwise returns failure */\n/* Macro required here because bit-field operation */\n#ifndef WOLFSSL_NO_ASN_STRICT\n    #define VERIFY_AND_SET_OID(bit) \\\n        if (bit == 0) \\\n            bit = 1; \\\n        else \\\n            return ASN_OBJECT_ID_E;\n#else\n    /* With no strict defined, the verify is skipped */\n#define VERIFY_AND_SET_OID(bit) bit = 1;\n#endif\n\nstatic int DecodeCertExtensions(DecodedCert* cert)\n/*\n *  Processing the Certificate Extensions. This does not modify the current\n *  index. It is works starting with the recorded extensions pointer.\n */\n{\n    int ret = 0;\n    word32 idx = 0;\n    int sz = cert->extensionsSz;\n    const byte* input = cert->extensions;\n    int length;\n    word32 oid;\n    byte critical = 0;\n    byte criticalFail = 0;\n    byte tag = 0;\n\n    WOLFSSL_ENTER(\"DecodeCertExtensions\");\n\n    if (input == NULL || sz == 0)\n        return BAD_FUNC_ARG;\n\n    if (GetASNTag(input, &idx, &tag, sz) < 0) {\n        return ASN_PARSE_E;\n    }\n\n    if (tag != ASN_EXTENSIONS) {\n        WOLFSSL_MSG(\"\\tfail: should be an EXTENSIONS\");\n        return ASN_PARSE_E;\n    }\n\n    if (GetLength(input, &idx, &length, sz) < 0) {\n        WOLFSSL_MSG(\"\\tfail: invalid length\");\n        return ASN_PARSE_E;\n    }\n\n    if (GetSequence(input, &idx, &length, sz) < 0) {\n        WOLFSSL_MSG(\"\\tfail: should be a SEQUENCE (1)\");\n        return ASN_PARSE_E;\n    }\n\n    while (idx < (word32)sz) {\n        word32 localIdx;\n\n        if (GetSequence(input, &idx, &length, sz) < 0) {\n            WOLFSSL_MSG(\"\\tfail: should be a SEQUENCE\");\n            return ASN_PARSE_E;\n        }\n\n        oid = 0;\n        if ((ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz)) < 0) {\n            WOLFSSL_MSG(\"\\tfail: OBJECT ID\");\n            return ret;\n        }\n\n        /* check for critical flag */\n        critical = 0;\n        if ((idx + 1) > (word32)sz) {\n            WOLFSSL_MSG(\"\\tfail: malformed buffer\");\n            return BUFFER_E;\n        }\n\n        localIdx = idx;\n        if (GetASNTag(input, &localIdx, &tag, sz) == 0) {\n            if (tag == ASN_BOOLEAN) {\n                ret = GetBoolean(input, &idx, sz);\n                if (ret < 0) {\n                    WOLFSSL_MSG(\"\\tfail: critical boolean\");\n                    return ret;\n                }\n\n                critical = (byte)ret;\n            }\n        }\n\n        /* process the extension based on the OID */\n        ret = GetOctetString(input, &idx, &length, sz);\n        if (ret < 0) {\n            WOLFSSL_MSG(\"\\tfail: bad OCTET STRING\");\n            return ret;\n        }\n\n        switch (oid) {\n            case BASIC_CA_OID:\n                VERIFY_AND_SET_OID(cert->extBasicConstSet);\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    cert->extBasicConstCrit = critical;\n                #endif\n                if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0)\n                    return ASN_PARSE_E;\n                break;\n\n            case CRL_DIST_OID:\n                VERIFY_AND_SET_OID(cert->extCRLdistSet);\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    cert->extCRLdistCrit = critical;\n                #endif\n                if (DecodeCrlDist(&input[idx], length, cert) < 0)\n                    return ASN_PARSE_E;\n                break;\n\n            case AUTH_INFO_OID:\n                VERIFY_AND_SET_OID(cert->extAuthInfoSet);\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    cert->extAuthInfoCrit = critical;\n                #endif\n                if (DecodeAuthInfo(&input[idx], length, cert) < 0)\n                    return ASN_PARSE_E;\n                break;\n\n            case ALT_NAMES_OID:\n                VERIFY_AND_SET_OID(cert->extSubjAltNameSet);\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    cert->extSubjAltNameCrit = critical;\n                #endif\n                ret = DecodeAltNames(&input[idx], length, cert);\n                if (ret < 0)\n                    return ret;\n                break;\n\n            case AUTH_KEY_OID:\n                VERIFY_AND_SET_OID(cert->extAuthKeyIdSet);\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    cert->extAuthKeyIdCrit = critical;\n                #endif\n                #ifndef WOLFSSL_ALLOW_CRIT_SKID\n                    /* This check is added due to RFC 5280 section 4.2.1.1\n                     * stating that conforming CA's must mark this extension\n                     * as non-critical. When parsing extensions check that\n                     * certificate was made in compliance with this. */\n                    if (critical) {\n                        WOLFSSL_MSG(\"Critical Auth Key ID is not allowed\");\n                        WOLFSSL_MSG(\"Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted\");\n                        return ASN_CRIT_EXT_E;\n                    }\n                #endif\n                if (DecodeAuthKeyId(&input[idx], length, cert) < 0)\n                    return ASN_PARSE_E;\n                break;\n\n            case SUBJ_KEY_OID:\n                VERIFY_AND_SET_OID(cert->extSubjKeyIdSet);\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    cert->extSubjKeyIdCrit = critical;\n                #endif\n                #ifndef WOLFSSL_ALLOW_CRIT_SKID\n                    /* This check is added due to RFC 5280 section 4.2.1.2\n                     * stating that conforming CA's must mark this extension\n                     * as non-critical. When parsing extensions check that\n                     * certificate was made in compliance with this. */\n                    if (critical) {\n                        WOLFSSL_MSG(\"Critical Subject Key ID is not allowed\");\n                        WOLFSSL_MSG(\"Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted\");\n                        return ASN_CRIT_EXT_E;\n                    }\n                #endif\n\n                if (DecodeSubjKeyId(&input[idx], length, cert) < 0)\n                    return ASN_PARSE_E;\n                break;\n\n            case CERT_POLICY_OID:\n                #ifdef WOLFSSL_SEP\n                    VERIFY_AND_SET_OID(cert->extCertPolicySet);\n                    #if defined(OPENSSL_EXTRA) || \\\n                        defined(OPENSSL_EXTRA_X509_SMALL)\n                        cert->extCertPolicyCrit = critical;\n                    #endif\n                #endif\n                #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)\n                    if (DecodeCertPolicy(&input[idx], length, cert) < 0) {\n                        return ASN_PARSE_E;\n                    }\n                #else\n                    WOLFSSL_MSG(\"Certificate Policy extension not supported yet.\");\n                #endif\n                break;\n\n            case KEY_USAGE_OID:\n                VERIFY_AND_SET_OID(cert->extKeyUsageSet);\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    cert->extKeyUsageCrit = critical;\n                #endif\n                if (DecodeKeyUsage(&input[idx], length, cert) < 0)\n                    return ASN_PARSE_E;\n                break;\n\n            case EXT_KEY_USAGE_OID:\n                VERIFY_AND_SET_OID(cert->extExtKeyUsageSet);\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    cert->extExtKeyUsageCrit = critical;\n                #endif\n                if (DecodeExtKeyUsage(&input[idx], length, cert) < 0)\n                    return ASN_PARSE_E;\n                break;\n\n            #ifndef IGNORE_NAME_CONSTRAINTS\n            case NAME_CONS_OID:\n            #ifndef WOLFSSL_NO_ASN_STRICT\n                /* Verify RFC 5280 Sec 4.2.1.10 rule:\n                    \"The name constraints extension,\n                    which MUST be used only in a CA certificate\" */\n                if (!cert->isCA) {\n                    WOLFSSL_MSG(\"Name constraints allowed only for CA certs\");\n                    return ASN_NAME_INVALID_E;\n                }\n            #endif\n                VERIFY_AND_SET_OID(cert->extNameConstraintSet);\n                #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n                    cert->extNameConstraintCrit = critical;\n                #endif\n                if (DecodeNameConstraints(&input[idx], length, cert) < 0)\n                    return ASN_PARSE_E;\n                break;\n            #endif /* IGNORE_NAME_CONSTRAINTS */\n\n            case INHIBIT_ANY_OID:\n                VERIFY_AND_SET_OID(cert->inhibitAnyOidSet);\n                WOLFSSL_MSG(\"Inhibit anyPolicy extension not supported yet.\");\n                break;\n\n            default:\n            #ifndef WOLFSSL_NO_ASN_STRICT\n                /* While it is a failure to not support critical extensions,\n                 * still parse the certificate ignoring the unsupported\n                 * extension to allow caller to accept it with the verify\n                 * callback. */\n                if (critical)\n                    criticalFail = 1;\n            #endif\n            break;\n        }\n        idx += length;\n    }\n\n    return criticalFail ? ASN_CRIT_EXT_E : 0;\n}\n\nint ParseCert(DecodedCert* cert, int type, int verify, void* cm)\n{\n    int   ret;\n    char* ptr;\n\n    ret = ParseCertRelative(cert, type, verify, cm);\n    if (ret < 0)\n        return ret;\n\n    if (cert->subjectCNLen > 0) {\n        ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,\n                              DYNAMIC_TYPE_SUBJECT_CN);\n        if (ptr == NULL)\n            return MEMORY_E;\n        XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);\n        ptr[cert->subjectCNLen] = '\\0';\n        cert->subjectCN = ptr;\n        cert->subjectCNStored = 1;\n    }\n\n    if (cert->keyOID == RSAk &&\n                          cert->publicKey != NULL  && cert->pubKeySize > 0) {\n        ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,\n                              DYNAMIC_TYPE_PUBLIC_KEY);\n        if (ptr == NULL)\n            return MEMORY_E;\n        XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);\n        cert->publicKey = (byte *)ptr;\n        cert->pubKeyStored = 1;\n    }\n\n    return ret;\n}\n\n\n/* from SSL proper, for locking can't do find here anymore */\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n    WOLFSSL_LOCAL Signer* GetCA(void* signers, byte* hash);\n    #ifndef NO_SKID\n        WOLFSSL_LOCAL Signer* GetCAByName(void* signers, byte* hash);\n    #endif\n#ifdef __cplusplus\n    }\n#endif\n\n\n#if defined(WOLFCRYPT_ONLY) || defined(NO_CERTS)\n\n/* dummy functions, not using wolfSSL so don't need actual ones */\nSigner* GetCA(void* signers, byte* hash)\n{\n    (void)hash;\n\n    return (Signer*)signers;\n}\n\n#ifndef NO_SKID\nSigner* GetCAByName(void* signers, byte* hash)\n{\n    (void)hash;\n\n    return (Signer*)signers;\n}\n#endif /* NO_SKID */\n\n#endif /* WOLFCRYPT_ONLY || NO_CERTS */\n\n#if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)\nstatic Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm)\n{\n    Signer* ca = NULL;\n    if (cert->extSubjKeyIdSet)\n        ca = GetCA(cm, cert->extSubjKeyId);\n    if (ca == NULL)\n        ca = GetCAByName(cm, cert->subjectHash);\n    if (ca) {\n        if ((ca->pubKeySize == cert->pubKeySize) &&\n               (XMEMCMP(ca->publicKey, cert->publicKey, ca->pubKeySize) == 0)) {\n            return ca;\n        }\n    }\n    return NULL;\n}\n#endif\n\n#if defined(WOLFSSL_SMALL_CERT_VERIFY) || defined(OPENSSL_EXTRA)\n/* Only quick step through the certificate to find fields that are then used\n * in certificate signature verification.\n * Must use the signature OID from the signed part of the certificate.\n *\n * This is only for minimizing dynamic memory usage during TLS certificate\n * chain processing.\n * Doesn't support:\n *   OCSP Only: alt lookup using subject and pub key w/o sig check\n */\nstatic int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,\n        void* cm, const byte* pubKey, word32 pubKeySz, int pubKeyOID)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    SignatureCtx  sigCtx[1];\n#else\n    SignatureCtx* sigCtx;\n#endif\n    byte          hash[KEYID_SIZE];\n    Signer*       ca = NULL;\n    word32        idx = 0;\n    int           len;\n    word32        tbsCertIdx = 0;\n    word32        sigIndex   = 0;\n    word32        signatureOID = 0;\n    word32        oid = 0;\n    word32        issuerIdx = 0;\n    word32        issuerSz  = 0;\n#ifndef NO_SKID\n    int           extLen = 0;\n    word32        extIdx = 0;\n    word32        extEndIdx = 0;\n    int           extAuthKeyIdSet = 0;\n#endif\n    int           ret = 0;\n    word32        localIdx;\n    byte          tag;\n\n\n    if (cert == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    sigCtx = (SignatureCtx*)XMALLOC(sizeof(*sigCtx), heap, DYNAMIC_TYPE_SIGNATURE);\n    if (sigCtx == NULL)\n        return MEMORY_E;\n#endif\n    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);\n\n    /* Certificate SEQUENCE */\n    if (GetSequence(cert, &idx, &len, certSz) < 0)\n        ret = ASN_PARSE_E;\n    if (ret == 0) {\n        tbsCertIdx = idx;\n\n        /* TBSCertificate SEQUENCE */\n        if (GetSequence(cert, &idx, &len, certSz) < 0)\n            ret = ASN_PARSE_E;\n    }\n    if (ret == 0) {\n        sigIndex = len + idx;\n\n        if ((idx + 1) > certSz)\n            ret = BUFFER_E;\n    }\n    if (ret == 0) {\n        /* version - optional */\n        localIdx = idx;\n        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {\n            if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {\n                idx++;\n                if (GetLength(cert, &idx, &len, certSz) < 0)\n                    ret = ASN_PARSE_E;\n                idx += len;\n            }\n        }\n    }\n\n    if (ret == 0) {\n        /* serialNumber */\n        if (GetASNHeader(cert, ASN_INTEGER, &idx, &len, certSz) < 0)\n            ret = ASN_PARSE_E;\n    }\n    if (ret == 0) {\n        idx += len;\n\n        /* signature */\n        if (GetAlgoId(cert, &idx, &signatureOID, oidSigType, certSz) < 0)\n            ret = ASN_PARSE_E;\n    }\n\n    if (ret == 0) {\n        issuerIdx = idx;\n        /* issuer */\n        if (GetSequence(cert, &idx, &len, certSz) < 0)\n            ret = ASN_PARSE_E;\n    }\n    if (ret == 0) {\n        issuerSz = len + idx - issuerIdx;\n    }\n#ifndef NO_SKID\n    if (ret == 0) {\n        idx += len;\n\n        /* validity */\n        if (GetSequence(cert, &idx, &len, certSz) < 0)\n            ret = ASN_PARSE_E;\n    }\n    if (ret == 0) {\n        idx += len;\n\n        /* subject */\n        if (GetSequence(cert, &idx, &len, certSz) < 0)\n            ret = ASN_PARSE_E;\n    }\n    if (ret == 0) {\n        idx += len;\n\n        /* subjectPublicKeyInfo */\n        if (GetSequence(cert, &idx, &len, certSz) < 0)\n            ret = ASN_PARSE_E;\n    }\n    if (ret == 0) {\n        idx += len;\n\n        if ((idx + 1) > certSz)\n            ret = BUFFER_E;\n    }\n    if (ret == 0) {\n        /* issuerUniqueID - optional */\n        localIdx = idx;\n        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {\n            if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {\n                idx++;\n                if (GetLength(cert, &idx, &len, certSz) < 0)\n                    ret = ASN_PARSE_E;\n                idx += len;\n            }\n        }\n    }\n    if (ret == 0) {\n        if ((idx + 1) > certSz)\n            ret = BUFFER_E;\n    }\n    if (ret == 0) {\n        /* subjectUniqueID - optional */\n        localIdx = idx;\n        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {\n            if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {\n                idx++;\n                if (GetLength(cert, &idx, &len, certSz) < 0)\n                    ret = ASN_PARSE_E;\n                idx += len;\n            }\n        }\n    }\n\n    if (ret == 0) {\n        if ((idx + 1) > certSz)\n            ret = BUFFER_E;\n    }\n    /* extensions - optional */\n    localIdx = idx;\n    if (ret == 0 && GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&\n            tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) {\n        idx++;\n        if (GetLength(cert, &idx, &extLen, certSz) < 0)\n            ret = ASN_PARSE_E;\n        if (ret == 0) {\n            if (GetSequence(cert, &idx, &extLen, certSz) < 0)\n                ret = ASN_PARSE_E;\n        }\n        if (ret == 0) {\n            extEndIdx = idx + extLen;\n\n            /* Check each extension for the ones we want. */\n            while (ret == 0 && idx < extEndIdx) {\n                if (GetSequence(cert, &idx, &len, certSz) < 0)\n                    ret = ASN_PARSE_E;\n                if (ret == 0) {\n                    extIdx = idx;\n                    if (GetObjectId(cert, &extIdx, &oid, oidCertExtType,\n                                                                  certSz) < 0) {\n                        ret = ASN_PARSE_E;\n                    }\n\n                    if (ret == 0) {\n                        if ((extIdx + 1) > certSz)\n                            ret = BUFFER_E;\n                    }\n                }\n\n                if (ret == 0) {\n                    localIdx = extIdx;\n                    if (GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&\n                            tag == ASN_BOOLEAN) {\n                        if (GetBoolean(cert, &extIdx, certSz) < 0)\n                            ret = ASN_PARSE_E;\n                    }\n                }\n                if (ret == 0) {\n                    if (GetOctetString(cert, &extIdx, &extLen, certSz) < 0)\n                        ret = ASN_PARSE_E;\n                }\n\n                if (ret == 0) {\n                    switch (oid) {\n                    case AUTH_KEY_OID:\n                        extAuthKeyIdSet = 1;\n                        if (GetSequence(cert, &extIdx, &extLen, certSz) < 0)\n                            ret = ASN_PARSE_E;\n\n                        if (ret == 0 && (extIdx + 1) >= certSz)\n                            ret = BUFFER_E;\n\n                        if (ret == 0 &&\n                                GetASNTag(cert, &extIdx, &tag, certSz) == 0 &&\n                                tag == (ASN_CONTEXT_SPECIFIC | 0)) {\n                            if (GetLength(cert, &extIdx, &extLen, certSz) <= 0)\n                                ret = ASN_PARSE_E;\n                            if (ret == 0) {\n                                if (extLen == KEYID_SIZE)\n                                    XMEMCPY(hash, cert + extIdx, extLen);\n                                else {\n                                    ret = CalcHashId(cert + extIdx, extLen,\n                                                                          hash);\n                                }\n                            }\n                        }\n                        break;\n\n                    default:\n                        break;\n                    }\n                }\n                idx += len;\n            }\n        }\n    }\n\n    if (ret == 0 && pubKey == NULL) {\n        if (extAuthKeyIdSet)\n            ca = GetCA(cm, hash);\n        if (ca == NULL) {\n            ret = CalcHashId(cert + issuerIdx, issuerSz, hash);\n            if (ret == 0)\n                ca = GetCAByName(cm, hash);\n        }\n    }\n#else\n    if (ret == 0 && pubKey == NULL) {\n        ret = CalcHashId(cert + issuerIdx, issuerSz, hash);\n        if (ret == 0)\n            ca = GetCA(cm, hash);\n    }\n#endif /* !NO_SKID */\n    if (ca == NULL && pubKey == NULL)\n        ret = ASN_NO_SIGNER_E;\n\n    if (ret == 0) {\n        idx = sigIndex;\n        /* signatureAlgorithm */\n        if (GetAlgoId(cert, &idx, &oid, oidSigType, certSz) < 0)\n            ret = ASN_PARSE_E;\n    }\n    if (ret == 0) {\n        if (oid != signatureOID)\n            ret = ASN_SIG_OID_E;\n    }\n    if (ret == 0) {\n        /* signatureValue */\n        if (CheckBitString(cert, &idx, &len, certSz, 1, NULL) < 0)\n            ret = ASN_PARSE_E;\n    }\n\n    if (ret == 0) {\n        if (pubKey != NULL) {\n            ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,\n                               sigIndex - tbsCertIdx,\n                               pubKey, pubKeySz, pubKeyOID,\n                               cert + idx, len, signatureOID, NULL);\n        }\n        else {\n            ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,\n                               sigIndex - tbsCertIdx,\n                               ca->publicKey, ca->pubKeySize, ca->keyOID,\n                               cert + idx, len, signatureOID, NULL);\n        }\n        if (ret != 0) {\n            WOLFSSL_MSG(\"Confirm signature failed\");\n        }\n    }\n\n    FreeSignatureCtx(sigCtx);\n#ifdef WOLFSSL_SMALL_STACK\n    if (sigCtx != NULL)\n        XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);\n#endif\n    return ret;\n}\n\n#ifdef OPENSSL_EXTRA\n/* Call CheckCertSignature_ex using a public key buffer for verification\n */\nint CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap,\n        const byte* pubKey, word32 pubKeySz, int pubKeyOID)\n{\n    return CheckCertSignature_ex(cert, certSz, heap, NULL,\n            pubKey, pubKeySz, pubKeyOID);\n}\n#endif /* OPENSSL_EXTRA */\n#ifdef WOLFSSL_SMALL_CERT_VERIFY\n/* Call CheckCertSignature_ex using a certificate manager (cm)\n */\nint CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)\n{\n    return CheckCertSignature_ex(cert, certSz, heap, cm, NULL, 0, 0);\n}\n#endif /* WOLFSSL_SMALL_CERT_VERIFY */\n#endif /* WOLFSSL_SMALL_CERT_VERIFY || OPENSSL_EXTRA */\n\nint ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)\n{\n    int    ret = 0;\n    int    checkPathLen = 0;\n    int    decrementMaxPathLen = 0;\n    word32 confirmOID;\n#if defined(WOLFSSL_RENESAS_TSIP)\n    int    idx = 0;\n#endif\n    byte*  tsip_encRsaKeyIdx;\n\n    if (cert == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (cert->sigCtx.state == SIG_STATE_BEGIN) {\n        cert->badDate = 0;\n        cert->criticalExt = 0;\n        if ((ret = DecodeToKey(cert, verify)) < 0) {\n            if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)\n                cert->badDate = ret;\n            else\n                return ret;\n        }\n\n        WOLFSSL_MSG(\"Parsed Past Key\");\n\n        if (cert->srcIdx < cert->sigIndex) {\n        #ifndef ALLOW_V1_EXTENSIONS\n            if (cert->version < 2) {\n                WOLFSSL_MSG(\"\\tv1 and v2 certs not allowed extensions\");\n                return ASN_VERSION_E;\n            }\n        #endif\n\n            /* save extensions */\n            cert->extensions    = &cert->source[cert->srcIdx];\n            cert->extensionsSz  = cert->sigIndex - cert->srcIdx;\n            cert->extensionsIdx = cert->srcIdx;   /* for potential later use */\n\n            if ((ret = DecodeCertExtensions(cert)) < 0) {\n                if (ret == ASN_CRIT_EXT_E)\n                    cert->criticalExt = ret;\n                else\n                    return ret;\n            }\n\n            /* advance past extensions */\n            cert->srcIdx = cert->sigIndex;\n        }\n\n        if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID,\n                             oidSigType, cert->maxIdx)) < 0)\n            return ret;\n\n        if ((ret = GetSignature(cert)) < 0)\n            return ret;\n\n        if (confirmOID != cert->signatureOID)\n            return ASN_SIG_OID_E;\n\n    #ifndef NO_SKID\n        if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&\n                                                         cert->pubKeySize > 0) {\n            ret = CalcHashId(cert->publicKey, cert->pubKeySize,\n                                                            cert->extSubjKeyId);\n            if (ret != 0)\n                return ret;\n        }\n    #endif /* !NO_SKID */\n\n        if (!cert->selfSigned || (verify != NO_VERIFY && type != CA_TYPE &&\n                                                   type != TRUSTED_PEER_TYPE)) {\n            cert->ca = NULL;\n    #ifndef NO_SKID\n            if (cert->extAuthKeyIdSet) {\n                cert->ca = GetCA(cm, cert->extAuthKeyId);\n            }\n            if (cert->ca == NULL && cert->extSubjKeyIdSet\n                                 && verify != VERIFY_OCSP) {\n                cert->ca = GetCA(cm, cert->extSubjKeyId);\n            }\n            if (cert->ca != NULL && XMEMCMP(cert->issuerHash,\n                                  cert->ca->subjectNameHash, KEYID_SIZE) != 0) {\n                cert->ca = NULL;\n            }\n            if (cert->ca == NULL) {\n                cert->ca = GetCAByName(cm, cert->issuerHash);\n                /* If AKID is availale then this CA doesn't have the public\n                 * key required */\n                if (cert->ca && cert->extAuthKeyIdSet) {\n                    WOLFSSL_MSG(\"CA SKID doesn't match AKID\");\n                    cert->ca = NULL;\n                }\n            }\n\n            /* OCSP Only: alt lookup using subject and pub key w/o sig check */\n        #ifdef WOLFSSL_NO_TRUSTED_CERTS_VERIFY\n            if (cert->ca == NULL && verify == VERIFY_OCSP) {\n                cert->ca = GetCABySubjectAndPubKey(cert, cm);\n                if (cert->ca) {\n                    ret = 0; /* success */\n                    goto exit_pcr;\n                }\n            }\n        #endif /* WOLFSSL_NO_TRUSTED_CERTS_VERIFY */\n    #else\n            cert->ca = GetCA(cm, cert->issuerHash);\n    #endif /* !NO_SKID */\n        }\n\n        if (cert->selfSigned) {\n            cert->maxPathLen = WOLFSSL_MAX_PATH_LEN;\n        } else {\n            /* RFC 5280 Section 4.2.1.9:\n             *\n             * load/receive check\n             *\n             * 1) Is CA boolean set?\n             *      No  - SKIP CHECK\n             *      Yes - Check key usage\n             * 2) Is Key usage extension present?\n             *      No  - goto 3\n             *      Yes - check keyCertSign assertion\n             *     2.a) Is keyCertSign asserted?\n             *          No  - goto 4\n             *          Yes - goto 3\n             * 3) Is pathLen set?\n             *      No  - goto 4\n             *      Yes - check pathLen against maxPathLen.\n             *      3.a) Is pathLen less than maxPathLen?\n             *           No - goto 4\n             *           Yes - set maxPathLen to pathLen and EXIT\n             * 4) Is maxPathLen > 0?\n             *      Yes - Reduce by 1\n             *      No  - ERROR\n             */\n\n            if (cert->ca && cert->pathLengthSet) {\n                cert->maxPathLen = cert->pathLength;\n                if (cert->isCA) {\n                    WOLFSSL_MSG(\"\\tCA boolean set\");\n                    if (cert->extKeyUsageSet) {\n                         WOLFSSL_MSG(\"\\tExtension Key Usage Set\");\n                         if ((cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) != 0) {\n                            checkPathLen = 1;\n                         } else {\n                            decrementMaxPathLen = 1;\n                         }\n                    } else {\n                        checkPathLen = 1;\n                    } /* !cert->ca check */\n                } /* cert is not a CA (assuming entity cert) */\n\n                if (checkPathLen && cert->pathLengthSet) {\n                    if (cert->pathLength < cert->ca->maxPathLen) {\n                        WOLFSSL_MSG(\"\\tmaxPathLen status: set to pathLength\");\n                        cert->maxPathLen = cert->pathLength;\n                    } else {\n                        decrementMaxPathLen = 1;\n                    }\n                }\n\n                if (decrementMaxPathLen && cert->ca->maxPathLen > 0) {\n                    WOLFSSL_MSG(\"\\tmaxPathLen status: reduce by 1\");\n                    cert->maxPathLen = cert->ca->maxPathLen - 1;\n                    if (verify != NO_VERIFY && type != CA_TYPE &&\n                                                    type != TRUSTED_PEER_TYPE) {\n                        WOLFSSL_MSG(\"\\tmaxPathLen status: OK\");\n                    }\n                } else if (decrementMaxPathLen && cert->ca->maxPathLen <= 0) {\n                    cert->maxPathLen = 0;\n                    if (verify != NO_VERIFY && type != CA_TYPE &&\n                                                    type != TRUSTED_PEER_TYPE) {\n                        WOLFSSL_MSG(\"\\tNon-entity cert, maxPathLen is 0\");\n                        WOLFSSL_MSG(\"\\tmaxPathLen status: ERROR\");\n                        return ASN_PATHLEN_INV_E;\n                    }\n                }\n            } else if (cert->ca && cert->isCA) {\n                /* case where cert->pathLength extension is not set */\n                if (cert->ca->maxPathLen > 0) {\n                    cert->maxPathLen = cert->ca->maxPathLen - 1;\n                } else {\n                    cert->maxPathLen = 0;\n                    if (verify != NO_VERIFY && type != CA_TYPE &&\n                                                    type != TRUSTED_PEER_TYPE) {\n                        WOLFSSL_MSG(\"\\tNon-entity cert, maxPathLen is 0\");\n                        WOLFSSL_MSG(\"\\tmaxPathLen status: ERROR\");\n                        return ASN_PATHLEN_INV_E;\n                    }\n                }\n            }\n            #ifdef HAVE_OCSP\n            if (verify != NO_VERIFY && type != CA_TYPE &&\n                                                    type != TRUSTED_PEER_TYPE) {\n                if (cert->ca) {\n                    /* Need the CA's public key hash for OCSP */\n                    XMEMCPY(cert->issuerKeyHash, cert->ca->subjectKeyHash,\n                                                                    KEYID_SIZE);\n                }\n\n            }\n            #endif /* HAVE_OCSP */\n        }\n    }\n#if defined(WOLFSSL_RENESAS_TSIP)\n    /* prepare for TSIP TLS cert verification API use */\n    if (cert->keyOID == RSAk) {\n        /* to call TSIP API, it needs keys position info in bytes */\n        if (ret = RsaPublicKeyDecodeRawIndex(cert->publicKey, (word32*)&idx,\n                                   cert->pubKeySize,\n                                   &cert->sigCtx.pubkey_n_start,\n                                   &cert->sigCtx.pubkey_n_len,\n                                   &cert->sigCtx.pubkey_e_start,\n                                   &cert->sigCtx.pubkey_e_len) != 0) {\n            WOLFSSL_MSG(\"Decoding index from cert failed.\");\n            return ret;\n        }\n        cert->sigCtx.certBegin = cert->certBegin;\n    }\n    /* check if we can use TSIP for cert verification */\n    /* if the ca is verified as tsip root ca.         */\n    /* TSIP can only handle 2048 bits(256 byte) key.  */\n    if (cert->ca && tsip_checkCA(cert->ca->cm_idx) != 0 &&\n        cert->sigCtx.pubkey_n_len == 256) {\n\n        /* assign memory to encrypted tsip Rsa key index */\n        if (!cert->tsip_encRsaKeyIdx)\n            cert->tsip_encRsaKeyIdx =\n                            (byte*)XMALLOC(TSIP_TLS_ENCPUBKEY_SZ_BY_CERTVRFY,\n                             cert->heap, DYNAMIC_TYPE_RSA);\n        if (cert->tsip_encRsaKeyIdx == NULL)\n                return MEMORY_E;\n    } else {\n        if (cert->ca) {\n            /* TSIP isn't usable */\n            if (tsip_checkCA(cert->ca->cm_idx) == 0)\n                WOLFSSL_MSG(\"TSIP isn't usable because the ca isn't verified \"\n                            \"by TSIP.\");\n            else if (cert->sigCtx.pubkey_n_len != 256)\n                WOLFSSL_MSG(\"TSIP isn't usable because the ca isn't signed by \"\n                            \"RSA 2048.\");\n            else\n                WOLFSSL_MSG(\"TSIP isn't usable\");\n        }\n        cert->tsip_encRsaKeyIdx = NULL;\n    }\n\n    tsip_encRsaKeyIdx = cert->tsip_encRsaKeyIdx;\n#else\n    tsip_encRsaKeyIdx = NULL;\n#endif\n\n    if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) {\n        if (cert->ca) {\n            if (verify == VERIFY || verify == VERIFY_OCSP ||\n                                                 verify == VERIFY_SKIP_DATE) {\n                /* try to confirm/verify signature */\n                if ((ret = ConfirmSignature(&cert->sigCtx,\n                        cert->source + cert->certBegin,\n                        cert->sigIndex - cert->certBegin,\n                        cert->ca->publicKey, cert->ca->pubKeySize,\n                        cert->ca->keyOID, cert->signature,\n                        cert->sigLength, cert->signatureOID,\n                        tsip_encRsaKeyIdx)) != 0) {\n                    if (ret != 0 && ret != WC_PENDING_E) {\n                        WOLFSSL_MSG(\"Confirm signature failed\");\n                    }\n                    return ret;\n                }\n            }\n        #ifndef IGNORE_NAME_CONSTRAINTS\n            if (verify == VERIFY || verify == VERIFY_OCSP ||\n                        verify == VERIFY_NAME || verify == VERIFY_SKIP_DATE) {\n                /* check that this cert's name is permitted by the signer's\n                 * name constraints */\n                if (!ConfirmNameConstraints(cert->ca, cert)) {\n                    WOLFSSL_MSG(\"Confirm name constraint failed\");\n                    return ASN_NAME_INVALID_E;\n                }\n            }\n        #endif /* IGNORE_NAME_CONSTRAINTS */\n        }\n        else {\n            /* no signer */\n            WOLFSSL_MSG(\"No CA signer to verify with\");\n            return ASN_NO_SIGNER_E;\n        }\n    }\n\n#if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)\nexit_pcr:\n#endif\n\n    if (cert->badDate != 0) {\n        if (verify != VERIFY_SKIP_DATE) {\n            return cert->badDate;\n        }\n        WOLFSSL_MSG(\"Date error: Verify option is skipping\");\n    }\n\n    if (cert->criticalExt != 0)\n        return cert->criticalExt;\n\n    return ret;\n}\n\n/* Create and init an new signer */\nSigner* MakeSigner(void* heap)\n{\n    Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,\n                                       DYNAMIC_TYPE_SIGNER);\n    if (signer) {\n        XMEMSET(signer, 0, sizeof(Signer));\n    }\n    (void)heap;\n\n    return signer;\n}\n\n\n/* Free an individual signer */\nvoid FreeSigner(Signer* signer, void* heap)\n{\n    XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);\n    XFREE((void*)signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);\n#ifndef IGNORE_NAME_CONSTRAINTS\n    if (signer->permittedNames)\n        FreeNameSubtrees(signer->permittedNames, heap);\n    if (signer->excludedNames)\n        FreeNameSubtrees(signer->excludedNames, heap);\n#endif\n#ifdef WOLFSSL_SIGNER_DER_CERT\n    FreeDer(&signer->derCert);\n#endif\n    XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);\n\n    (void)heap;\n}\n\n\n/* Free the whole singer table with number of rows */\nvoid FreeSignerTable(Signer** table, int rows, void* heap)\n{\n    int i;\n\n    for (i = 0; i < rows; i++) {\n        Signer* signer = table[i];\n        while (signer) {\n            Signer* next = signer->next;\n            FreeSigner(signer, heap);\n            signer = next;\n        }\n        table[i] = NULL;\n    }\n}\n\n#ifdef WOLFSSL_TRUST_PEER_CERT\n/* Free an individual trusted peer cert */\nvoid FreeTrustedPeer(TrustedPeerCert* tp, void* heap)\n{\n    if (tp == NULL) {\n        return;\n    }\n\n    if (tp->name) {\n        XFREE(tp->name, heap, DYNAMIC_TYPE_SUBJECT_CN);\n    }\n\n    if (tp->sig) {\n        XFREE(tp->sig, heap, DYNAMIC_TYPE_SIGNATURE);\n    }\n#ifndef IGNORE_NAME_CONSTRAINTS\n    if (tp->permittedNames)\n        FreeNameSubtrees(tp->permittedNames, heap);\n    if (tp->excludedNames)\n        FreeNameSubtrees(tp->excludedNames, heap);\n#endif\n    XFREE(tp, heap, DYNAMIC_TYPE_CERT);\n\n    (void)heap;\n}\n\n/* Free the whole Trusted Peer linked list */\nvoid FreeTrustedPeerTable(TrustedPeerCert** table, int rows, void* heap)\n{\n    int i;\n\n    for (i = 0; i < rows; i++) {\n        TrustedPeerCert* tp = table[i];\n        while (tp) {\n            TrustedPeerCert* next = tp->next;\n            FreeTrustedPeer(tp, heap);\n            tp = next;\n        }\n        table[i] = NULL;\n    }\n}\n#endif /* WOLFSSL_TRUST_PEER_CERT */\n\nWOLFSSL_LOCAL int SetMyVersion(word32 version, byte* output, int header)\n{\n    int i = 0;\n\n    if (output == NULL)\n        return BAD_FUNC_ARG;\n\n    if (header) {\n        output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;\n        output[i++] = 3;\n    }\n    output[i++] = ASN_INTEGER;\n    output[i++] = 0x01;\n    output[i++] = (byte)version;\n\n    return i;\n}\n\n\nWOLFSSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output,\n    word32 outputSz, int maxSnSz)\n{\n    int i;\n    int snSzInt = (int)snSz;\n\n    if (sn == NULL || output == NULL || snSzInt < 0)\n        return BAD_FUNC_ARG;\n\n    /* remove leading zeros */\n    while (snSzInt > 0 && sn[0] == 0) {\n        snSzInt--;\n        sn++;\n    }\n    /* RFC 5280 - 4.1.2.2:\n     *   Serial numbers must be a postive value (and not zero) */\n    if (snSzInt == 0)\n        return BAD_FUNC_ARG;\n\n    if (sn[0] & 0x80)\n        maxSnSz--;\n    /* truncate if input is too long */\n    if (snSzInt > maxSnSz)\n        snSzInt = maxSnSz;\n\n    i = SetASNInt(snSzInt, sn[0], NULL);\n    /* truncate if input is too long */\n    if (snSzInt > (int)outputSz - i)\n        snSzInt = (int)outputSz - i;\n    /* sanity check number of bytes to copy */\n    if (snSzInt <= 0) {\n        return BUFFER_E;\n    }\n\n    /* write out ASN.1 Integer */\n    (void)SetASNInt(snSzInt, sn[0], output);\n    XMEMCPY(output + i, sn, snSzInt);\n\n    /* compute final length */\n    i += snSzInt;\n\n    return i;\n}\n\n#endif /* !NO_CERTS */\n\nWOLFSSL_LOCAL int GetSerialNumber(const byte* input, word32* inOutIdx,\n    byte* serial, int* serialSz, word32 maxIdx)\n{\n    int result = 0;\n    int ret;\n\n    WOLFSSL_ENTER(\"GetSerialNumber\");\n\n    if (serial == NULL || input == NULL || serialSz == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* First byte is ASN type */\n    if ((*inOutIdx+1) > maxIdx) {\n        WOLFSSL_MSG(\"Bad idx first\");\n        return BUFFER_E;\n    }\n\n    ret = GetASNInt(input, inOutIdx, serialSz, maxIdx);\n    if (ret != 0)\n        return ret;\n\n    if (*serialSz > EXTERNAL_SERIAL_SIZE) {\n        WOLFSSL_MSG(\"Serial size bad\");\n        return ASN_PARSE_E;\n    }\n\n    /* return serial */\n    XMEMCPY(serial, &input[*inOutIdx], *serialSz);\n    *inOutIdx += *serialSz;\n\n    return result;\n}\n\n#ifndef NO_CERTS\n\nint AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)\n{\n    int ret = BAD_FUNC_ARG;\n    if (pDer) {\n        int dynType = 0;\n        DerBuffer* der;\n\n        /* Determine dynamic type */\n        switch (type) {\n            case CA_TYPE:   dynType = DYNAMIC_TYPE_CA;   break;\n            case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;\n            case CRL_TYPE:  dynType = DYNAMIC_TYPE_CRL;  break;\n            case DSA_TYPE:  dynType = DYNAMIC_TYPE_DSA;  break;\n            case ECC_TYPE:  dynType = DYNAMIC_TYPE_ECC;  break;\n            case RSA_TYPE:  dynType = DYNAMIC_TYPE_RSA;  break;\n            default:        dynType = DYNAMIC_TYPE_KEY;  break;\n        }\n\n        /* Setup new buffer */\n        *pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);\n        if (*pDer == NULL) {\n            return MEMORY_E;\n        }\n        XMEMSET(*pDer, 0, sizeof(DerBuffer) + length);\n\n        der = *pDer;\n        der->type = type;\n        der->dynType = dynType; /* Cache this for FreeDer */\n        der->heap = heap;\n        der->buffer = (byte*)der + sizeof(DerBuffer);\n        der->length = length;\n        ret = 0; /* Success */\n    }\n    return ret;\n}\n\nvoid FreeDer(DerBuffer** pDer)\n{\n    if (pDer && *pDer)\n    {\n        DerBuffer* der = (DerBuffer*)*pDer;\n\n        /* ForceZero private keys */\n        if (der->type == PRIVATEKEY_TYPE) {\n            ForceZero(der->buffer, der->length);\n        }\n        der->buffer = NULL;\n        der->length = 0;\n        XFREE(der, der->heap, der->dynType);\n\n        *pDer = NULL;\n    }\n}\n\nint wc_AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)\n{\n    return AllocDer(pDer, length, type, heap);\n}\nvoid wc_FreeDer(DerBuffer** pDer)\n{\n    FreeDer(pDer);\n}\n\n\n#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)\n\n/* Max X509 header length indicates the max length + 2 ('\\n', '\\0') */\n#define MAX_X509_HEADER_SZ  (37 + 2)\n\nconst char* const BEGIN_CERT           = \"-----BEGIN CERTIFICATE-----\";\nconst char* const END_CERT             = \"-----END CERTIFICATE-----\";\n#ifdef WOLFSSL_CERT_REQ\n    const char* const BEGIN_CERT_REQ   = \"-----BEGIN CERTIFICATE REQUEST-----\";\n    const char* const END_CERT_REQ     = \"-----END CERTIFICATE REQUEST-----\";\n#endif\n#ifndef NO_DH\n    const char* const BEGIN_DH_PARAM   = \"-----BEGIN DH PARAMETERS-----\";\n    const char* const END_DH_PARAM     = \"-----END DH PARAMETERS-----\";\n#endif\n#ifndef NO_DSA\n    const char* const BEGIN_DSA_PARAM  = \"-----BEGIN DSA PARAMETERS-----\";\n    const char* const END_DSA_PARAM    = \"-----END DSA PARAMETERS-----\";\n#endif\nconst char* const BEGIN_X509_CRL       = \"-----BEGIN X509 CRL-----\";\nconst char* const END_X509_CRL         = \"-----END X509 CRL-----\";\nconst char* const BEGIN_RSA_PRIV       = \"-----BEGIN RSA PRIVATE KEY-----\";\nconst char* const END_RSA_PRIV         = \"-----END RSA PRIVATE KEY-----\";\nconst char* const BEGIN_PRIV_KEY       = \"-----BEGIN PRIVATE KEY-----\";\nconst char* const END_PRIV_KEY         = \"-----END PRIVATE KEY-----\";\nconst char* const BEGIN_ENC_PRIV_KEY   = \"-----BEGIN ENCRYPTED PRIVATE KEY-----\";\nconst char* const END_ENC_PRIV_KEY     = \"-----END ENCRYPTED PRIVATE KEY-----\";\n#ifdef HAVE_ECC\n    const char* const BEGIN_EC_PRIV    = \"-----BEGIN EC PRIVATE KEY-----\";\n    const char* const END_EC_PRIV      = \"-----END EC PRIVATE KEY-----\";\n#endif\n#if defined(HAVE_ECC) || defined(HAVE_ED25519) || !defined(NO_DSA)\n    const char* const BEGIN_DSA_PRIV   = \"-----BEGIN DSA PRIVATE KEY-----\";\n    const char* const END_DSA_PRIV     = \"-----END DSA PRIVATE KEY-----\";\n#endif\nconst char* const BEGIN_PUB_KEY        = \"-----BEGIN PUBLIC KEY-----\";\nconst char* const END_PUB_KEY          = \"-----END PUBLIC KEY-----\";\n#ifdef HAVE_ED25519\n    const char* const BEGIN_EDDSA_PRIV = \"-----BEGIN EDDSA PRIVATE KEY-----\";\n    const char* const END_EDDSA_PRIV   = \"-----END EDDSA PRIVATE KEY-----\";\n#endif\n#ifdef HAVE_CRL\n    const char *const BEGIN_CRL = \"-----BEGIN X509 CRL-----\";\n    const char* const END_CRL   = \"-----END X509 CRL-----\";\n#endif\n\n\nstatic WC_INLINE char* SkipEndOfLineChars(char* line, const char* endOfLine)\n{\n    /* eat end of line characters */\n    while (line < endOfLine &&\n              (line[0] == '\\r' || line[0] == '\\n')) {\n        line++;\n    }\n    return line;\n}\n\nint wc_PemGetHeaderFooter(int type, const char** header, const char** footer)\n{\n    int ret = BAD_FUNC_ARG;\n\n    switch (type) {\n        case CA_TYPE:       /* same as below */\n        case TRUSTED_PEER_TYPE:\n        case CERT_TYPE:\n            if (header) *header = BEGIN_CERT;\n            if (footer) *footer = END_CERT;\n            ret = 0;\n            break;\n\n        case CRL_TYPE:\n            if (header) *header = BEGIN_X509_CRL;\n            if (footer) *footer = END_X509_CRL;\n            ret = 0;\n            break;\n    #ifndef NO_DH\n        case DH_PARAM_TYPE:\n            if (header) *header = BEGIN_DH_PARAM;\n            if (footer) *footer = END_DH_PARAM;\n            ret = 0;\n            break;\n    #endif\n    #ifndef NO_DSA\n        case DSA_PARAM_TYPE:\n            if (header) *header = BEGIN_DSA_PARAM;\n            if (footer) *footer = END_DSA_PARAM;\n            ret = 0;\n            break;\n    #endif\n    #ifdef WOLFSSL_CERT_REQ\n        case CERTREQ_TYPE:\n            if (header) *header = BEGIN_CERT_REQ;\n            if (footer) *footer = END_CERT_REQ;\n            ret = 0;\n            break;\n    #endif\n    #ifndef NO_DSA\n        case DSA_TYPE:\n        case DSA_PRIVATEKEY_TYPE:\n            if (header) *header = BEGIN_DSA_PRIV;\n            if (footer) *footer = END_DSA_PRIV;\n            ret = 0;\n            break;\n    #endif\n    #ifdef HAVE_ECC\n        case ECC_TYPE:\n        case ECC_PRIVATEKEY_TYPE:\n            if (header) *header = BEGIN_EC_PRIV;\n            if (footer) *footer = END_EC_PRIV;\n            ret = 0;\n            break;\n    #endif\n        case RSA_TYPE:\n        case PRIVATEKEY_TYPE:\n            if (header) *header = BEGIN_RSA_PRIV;\n            if (footer) *footer = END_RSA_PRIV;\n            ret = 0;\n            break;\n    #ifdef HAVE_ED25519\n        case ED25519_TYPE:\n        case EDDSA_PRIVATEKEY_TYPE:\n            if (header) *header = BEGIN_EDDSA_PRIV;\n            if (footer) *footer = END_EDDSA_PRIV;\n            ret = 0;\n            break;\n    #endif\n        case PUBLICKEY_TYPE:\n        case ECC_PUBLICKEY_TYPE:\n            if (header) *header = BEGIN_PUB_KEY;\n            if (footer) *footer = END_PUB_KEY;\n            ret = 0;\n            break;\n        case PKCS8_PRIVATEKEY_TYPE:\n            if (header) *header = BEGIN_PRIV_KEY;\n            if (footer) *footer = END_PRIV_KEY;\n            ret = 0;\n            break;\n        case PKCS8_ENC_PRIVATEKEY_TYPE:\n            if (header) *header = BEGIN_ENC_PRIV_KEY;\n            if (footer) *footer = END_ENC_PRIV_KEY;\n            ret = 0;\n            break;\n        default:\n            break;\n    }\n    return ret;\n}\n\n#ifdef WOLFSSL_ENCRYPTED_KEYS\n\nstatic const char* const kProcTypeHeader = \"Proc-Type\";\nstatic const char* const kDecInfoHeader = \"DEK-Info\";\n\n#ifdef WOLFSSL_PEM_TO_DER\n#ifndef NO_DES3\n    static const char* const kEncTypeDes = \"DES-CBC\";\n    static const char* const kEncTypeDes3 = \"DES-EDE3-CBC\";\n#endif\n#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)\n    static const char* const kEncTypeAesCbc128 = \"AES-128-CBC\";\n#endif\n#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)\n    static const char* const kEncTypeAesCbc192 = \"AES-192-CBC\";\n#endif\n#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)\n    static const char* const kEncTypeAesCbc256 = \"AES-256-CBC\";\n#endif\n\nint wc_EncryptedInfoGet(EncryptedInfo* info, const char* cipherInfo)\n{\n    int ret = 0;\n\n    if (info == NULL || cipherInfo == NULL)\n        return BAD_FUNC_ARG;\n\n    /* determine cipher information */\n#ifndef NO_DES3\n    if (XSTRNCMP(cipherInfo, kEncTypeDes, XSTRLEN(kEncTypeDes)) == 0) {\n        info->cipherType = WC_CIPHER_DES;\n        info->keySz = DES_KEY_SIZE;\n        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;\n    }\n    else if (XSTRNCMP(cipherInfo, kEncTypeDes3, XSTRLEN(kEncTypeDes3)) == 0) {\n        info->cipherType = WC_CIPHER_DES3;\n        info->keySz = DES3_KEY_SIZE;\n        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;\n    }\n    else\n#endif /* !NO_DES3 */\n#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)\n    if (XSTRNCMP(cipherInfo, kEncTypeAesCbc128, XSTRLEN(kEncTypeAesCbc128)) == 0) {\n        info->cipherType = WC_CIPHER_AES_CBC;\n        info->keySz = AES_128_KEY_SIZE;\n        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;\n    }\n    else\n#endif\n#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)\n    if (XSTRNCMP(cipherInfo, kEncTypeAesCbc192, XSTRLEN(kEncTypeAesCbc192)) == 0) {\n        info->cipherType = WC_CIPHER_AES_CBC;\n        info->keySz = AES_192_KEY_SIZE;\n        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;\n    }\n    else\n#endif\n#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)\n    if (XSTRNCMP(cipherInfo, kEncTypeAesCbc256, XSTRLEN(kEncTypeAesCbc256)) == 0) {\n        info->cipherType = WC_CIPHER_AES_CBC;\n        info->keySz = AES_256_KEY_SIZE;\n        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;\n    }\n    else\n#endif\n    {\n        ret = NOT_COMPILED_IN;\n    }\n    return ret;\n}\n\nint wc_EncryptedInfoParse(EncryptedInfo* info, char** pBuffer, size_t bufSz)\n{\n    int err = 0;\n    char*  bufferStart;\n    char*  bufferEnd;\n    char*  line;\n    word32 lineSz;\n    char*  finish;\n    word32 finishSz;\n    char*  start = NULL;\n    word32 startSz;\n    char*  newline = NULL;\n\n    if (info == NULL || pBuffer == NULL || bufSz == 0)\n        return BAD_FUNC_ARG;\n\n    bufferStart = *pBuffer;\n    bufferEnd = bufferStart + bufSz;\n\n    /* find encrypted info marker */\n    line = XSTRNSTR(bufferStart, kProcTypeHeader,\n                    min((word32)bufSz, PEM_LINE_LEN));\n    if (line != NULL) {\n        if (line >= bufferEnd) {\n            return BUFFER_E;\n        }\n\n        lineSz = (word32)(bufferEnd - line);\n\n        /* find DEC-Info marker */\n        start = XSTRNSTR(line, kDecInfoHeader, min(lineSz, PEM_LINE_LEN));\n\n        if (start == NULL)\n            return BUFFER_E;\n\n        /* skip dec-info and \": \" */\n        start += XSTRLEN(kDecInfoHeader);\n        if (start >= bufferEnd)\n            return BUFFER_E;\n\n        if (start[0] == ':') {\n            start++;\n            if (start >= bufferEnd)\n                return BUFFER_E;\n        }\n        if (start[0] == ' ')\n            start++;\n\n        startSz = (word32)(bufferEnd - start);\n        finish = XSTRNSTR(start, \",\", min(startSz, PEM_LINE_LEN));\n\n        if ((start != NULL) && (finish != NULL) && (start < finish)) {\n            if (finish >= bufferEnd) {\n                return BUFFER_E;\n            }\n\n            finishSz = (word32)(bufferEnd - finish);\n            newline = XSTRNSTR(finish, \"\\r\", min(finishSz, PEM_LINE_LEN));\n\n            /* get cipher name */\n            if (NAME_SZ < (finish - start)) /* buffer size of info->name */\n                return BUFFER_E;\n            if (XMEMCPY(info->name, start, finish - start) == NULL)\n                return BUFFER_E;\n            info->name[finish - start] = '\\0'; /* null term */\n\n            /* populate info */\n            err = wc_EncryptedInfoGet(info, info->name);\n            if (err != 0)\n                return err;\n\n            /* get IV */\n            if (finishSz < info->ivSz + 1)\n                return BUFFER_E;\n\n            if (newline == NULL) {\n                newline = XSTRNSTR(finish, \"\\n\", min(finishSz,\n                                                     PEM_LINE_LEN));\n            }\n            if ((newline != NULL) && (newline > finish)) {\n                info->ivSz = (word32)(newline - (finish + 1));\n                if (XMEMCPY(info->iv, finish + 1, info->ivSz) == NULL)\n                    return BUFFER_E;\n                info->set = 1;\n            }\n            else\n                return BUFFER_E;\n        }\n        else\n            return BUFFER_E;\n\n        /* eat end of line characters */\n        newline = SkipEndOfLineChars(newline, bufferEnd);\n\n        /* return new headerEnd */\n        if (pBuffer)\n            *pBuffer = newline;\n    }\n\n    return err;\n}\n#endif /* WOLFSSL_PEM_TO_DER */\n\n#ifdef WOLFSSL_DER_TO_PEM\nstatic int wc_EncryptedInfoAppend(char* dest, int destSz, char* cipherInfo)\n{\n    if (cipherInfo != NULL) {\n        int cipherInfoStrLen = (int)XSTRLEN((char*)cipherInfo);\n\n        if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3))\n            cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3);\n\n        if (destSz - (int)XSTRLEN(dest) >= cipherInfoStrLen + (9+14+8+2+2+1)) {\n            /* strncat's src length needs to include the NULL */\n            XSTRNCAT(dest, kProcTypeHeader, 10);\n            XSTRNCAT(dest, \": 4,ENCRYPTED\\n\", 15);\n            XSTRNCAT(dest, kDecInfoHeader, 9);\n            XSTRNCAT(dest, \": \", 3);\n            XSTRNCAT(dest, cipherInfo, destSz - (int)XSTRLEN(dest) - 1);\n            XSTRNCAT(dest, \"\\n\\n\", 4);\n        }\n    }\n    return 0;\n}\n#endif /* WOLFSSL_DER_TO_PEM */\n#endif /* WOLFSSL_ENCRYPTED_KEYS */\n\n#ifdef WOLFSSL_DER_TO_PEM\n\n/* Used for compatibility API */\nint wc_DerToPem(const byte* der, word32 derSz,\n                byte* output, word32 outSz, int type)\n{\n    return wc_DerToPemEx(der, derSz, output, outSz, NULL, type);\n}\n\n/* convert der buffer to pem into output, can't do inplace, der and output\n   need to be different */\nint wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,\n             byte *cipher_info, int type)\n{\n    const char* headerStr = NULL;\n    const char* footerStr = NULL;\n#ifdef WOLFSSL_SMALL_STACK\n    char* header = NULL;\n    char* footer = NULL;\n#else\n    char header[MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE];\n    char footer[MAX_X509_HEADER_SZ];\n#endif\n    int headerLen = MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE;\n    int footerLen = MAX_X509_HEADER_SZ;\n    int i;\n    int err;\n    int outLen;   /* return length or error */\n\n    (void)cipher_info;\n\n    if (der == output)      /* no in place conversion */\n        return BAD_FUNC_ARG;\n\n    err = wc_PemGetHeaderFooter(type, &headerStr, &footerStr);\n    if (err != 0)\n        return err;\n\n#ifdef WOLFSSL_SMALL_STACK\n    header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (header == NULL)\n        return MEMORY_E;\n\n    footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (footer == NULL) {\n        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n#endif\n\n    /* build header and footer based on type */\n    XSTRNCPY(header, headerStr, headerLen - 1);\n    header[headerLen - 2] = 0;\n    XSTRNCPY(footer, footerStr, footerLen - 1);\n    footer[footerLen - 2] = 0;\n\n    /* add new line to end */\n    XSTRNCAT(header, \"\\n\", 2);\n    XSTRNCAT(footer, \"\\n\", 2);\n\n#ifdef WOLFSSL_ENCRYPTED_KEYS\n    err = wc_EncryptedInfoAppend(header, headerLen, (char*)cipher_info);\n    if (err != 0) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        return err;\n    }\n#endif\n\n    headerLen = (int)XSTRLEN(header);\n    footerLen = (int)XSTRLEN(footer);\n\n    /* if null output and 0 size passed in then return size needed */\n    if (!output && outSz == 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        outLen = 0;\n        if ((err = Base64_Encode(der, derSz, NULL, (word32*)&outLen))\n                != LENGTH_ONLY_E) {\n            return err;\n        }\n        return headerLen + footerLen + outLen;\n    }\n\n    if (!der || !output) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return BAD_FUNC_ARG;\n    }\n\n    /* don't even try if outSz too short */\n    if (outSz < headerLen + footerLen + derSz) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return BAD_FUNC_ARG;\n    }\n\n    /* header */\n    XMEMCPY(output, header, headerLen);\n    i = headerLen;\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    /* body */\n    outLen = outSz - (headerLen + footerLen);  /* input to Base64_Encode */\n    if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return err;\n    }\n    i += outLen;\n\n    /* footer */\n    if ( (i + footerLen) > (int)outSz) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return BAD_FUNC_ARG;\n    }\n    XMEMCPY(output + i, footer, footerLen);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return outLen + headerLen + footerLen;\n}\n\n#endif /* WOLFSSL_DER_TO_PEM */\n\n#ifdef WOLFSSL_PEM_TO_DER\n\n/* Remove PEM header/footer, convert to ASN1, store any encrypted data\n   info->consumed tracks of PEM bytes consumed in case multiple parts */\nint PemToDer(const unsigned char* buff, long longSz, int type,\n              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)\n{\n    const char* header      = NULL;\n    const char* footer      = NULL;\n    char*       headerEnd;\n    char*       footerEnd;\n    char*       consumedEnd;\n    char*       bufferEnd   = (char*)(buff + longSz);\n    long        neededSz;\n    int         ret         = 0;\n    int         sz          = (int)longSz;\n    int         encrypted_key = 0;\n    DerBuffer*  der;\n#if defined(HAVE_PKCS8) || defined(WOLFSSL_ENCRYPTED_KEYS)\n    word32      algId = 0;\n#endif\n\n    WOLFSSL_ENTER(\"PemToDer\");\n\n    /* get PEM header and footer based on type */\n    ret = wc_PemGetHeaderFooter(type, &header, &footer);\n    if (ret != 0)\n        return ret;\n\n    /* map header if not found for type */\n    for (;;) {\n        headerEnd = XSTRNSTR((char*)buff, header, sz);\n\n        if (headerEnd) {\n            break;\n        } else\n        if (type == PRIVATEKEY_TYPE) {\n            if (header == BEGIN_RSA_PRIV) {\n                header =  BEGIN_PRIV_KEY;       footer = END_PRIV_KEY;\n            } else\n            if (header == BEGIN_PRIV_KEY) {\n                header =  BEGIN_ENC_PRIV_KEY;   footer = END_ENC_PRIV_KEY;\n            } else\n    #ifdef HAVE_ECC\n            if (header == BEGIN_ENC_PRIV_KEY) {\n                header =  BEGIN_EC_PRIV;        footer = END_EC_PRIV;\n            } else\n            if (header == BEGIN_EC_PRIV) {\n                header =  BEGIN_DSA_PRIV;       footer = END_DSA_PRIV;\n            } else\n    #endif\n    #ifdef HAVE_ED25519\n        #ifdef HAVE_ECC\n            if (header == BEGIN_DSA_PRIV)\n        #else\n            if (header == BEGIN_ENC_PRIV_KEY)\n        #endif\n            {\n                header =  BEGIN_EDDSA_PRIV;     footer = END_EDDSA_PRIV;\n            } else\n    #endif\n            {\n                break;\n            }\n        } else\n#ifdef HAVE_CRL\n        if ((type == CRL_TYPE) && (header != BEGIN_CRL)) {\n            header =  BEGIN_CRL;                footer = END_CRL;\n        } else\n#endif\n        {\n            break;\n        }\n    }\n\n    if (!headerEnd) {\n        WOLFSSL_MSG(\"Couldn't find PEM header\");\n        return ASN_NO_PEM_HEADER;\n    }\n\n    headerEnd += XSTRLEN(header);\n\n    /* eat end of line characters */\n    headerEnd = SkipEndOfLineChars(headerEnd, bufferEnd);\n\n    if (type == PRIVATEKEY_TYPE) {\n        if (eccKey) {\n        #ifdef HAVE_ECC\n            *eccKey = (header == BEGIN_EC_PRIV) ? 1 : 0;\n        #else\n            *eccKey = 0;\n        #endif\n        }\n    }\n\n#ifdef WOLFSSL_ENCRYPTED_KEYS\n    if (info) {\n        ret = wc_EncryptedInfoParse(info, &headerEnd, bufferEnd - headerEnd);\n        if (ret < 0)\n            return ret;\n        if (info->set)\n            encrypted_key = 1;\n    }\n#endif /* WOLFSSL_ENCRYPTED_KEYS */\n\n    /* find footer */\n    footerEnd = XSTRNSTR((char*)buff, footer, sz);\n    if (!footerEnd) {\n        if (info)\n            info->consumed = longSz; /* No more certs if no footer */\n        return BUFFER_E;\n    }\n\n    consumedEnd = footerEnd + XSTRLEN(footer);\n\n    if (consumedEnd < bufferEnd) { /* handle no end of line on last line */\n        /* eat end of line characters */\n        consumedEnd = SkipEndOfLineChars(consumedEnd, bufferEnd);\n        /* skip possible null term */\n        if (consumedEnd < bufferEnd && consumedEnd[0] == '\\0')\n            consumedEnd++;\n    }\n\n    if (info)\n        info->consumed = (long)(consumedEnd - (char*)buff);\n\n    /* set up der buffer */\n    neededSz = (long)(footerEnd - headerEnd);\n    if (neededSz > sz || neededSz <= 0)\n        return BUFFER_E;\n\n    ret = AllocDer(pDer, (word32)neededSz, type, heap);\n    if (ret < 0) {\n        return ret;\n    }\n    der = *pDer;\n\n    if (Base64_Decode((byte*)headerEnd, (word32)neededSz,\n                      der->buffer, &der->length) < 0)\n        return BUFFER_E;\n\n    if ((header == BEGIN_PRIV_KEY\n#ifdef HAVE_ECC\n         || header == BEGIN_EC_PRIV\n#endif\n        ) && !encrypted_key)\n    {\n    #ifdef HAVE_PKCS8\n        /* pkcs8 key, convert and adjust length */\n        if ((ret = ToTraditional_ex(der->buffer, der->length, &algId)) > 0) {\n            der->length = ret;\n        }\n        else {\n            /* ignore failure here and assume key is not pkcs8 wrapped */\n        }\n    #endif\n\n        return 0;\n    }\n\n#ifdef WOLFSSL_ENCRYPTED_KEYS\n    if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {\n        int   passwordSz = NAME_SZ;\n    #ifdef WOLFSSL_SMALL_STACK\n        char* password = NULL;\n    #else\n        char  password[NAME_SZ];\n    #endif\n\n        if (!info || !info->passwd_cb) {\n            WOLFSSL_MSG(\"No password callback set\");\n            return NO_PASSWORD;\n        }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);\n        if (password == NULL)\n            return MEMORY_E;\n    #endif\n\n        /* get password */\n        ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,\n            info->passwd_userdata);\n        if (ret >= 0) {\n            passwordSz = ret;\n\n            /* convert and adjust length */\n            if (header == BEGIN_ENC_PRIV_KEY) {\n            #ifndef NO_PWDBASED\n                ret = ToTraditionalEnc(der->buffer, der->length,\n                                       password, passwordSz, &algId);\n\n                if (ret >= 0) {\n                    der->length = ret;\n                    if ((algId == ECDSAk) && (eccKey != NULL)) {\n                        *eccKey = 1;\n                    }\n                    ret = 0;\n                }\n            #else\n                ret = NOT_COMPILED_IN;\n            #endif\n            }\n            /* decrypt the key */\n            else {\n                ret = wc_BufferKeyDecrypt(info, der->buffer, der->length,\n                    (byte*)password, passwordSz, WC_MD5);\n            }\n            ForceZero(password, passwordSz);\n        }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(password, heap, DYNAMIC_TYPE_STRING);\n    #endif\n    }\n#endif /* WOLFSSL_ENCRYPTED_KEYS */\n\n    return ret;\n}\n\nint wc_PemToDer(const unsigned char* buff, long longSz, int type,\n              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)\n{\n    return PemToDer(buff, longSz, type, pDer, heap, info, eccKey);\n}\n\n\n/* our KeyPemToDer password callback, password in userData */\nstatic WC_INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)\n{\n    (void)rw;\n\n    if (userdata == NULL)\n        return 0;\n\n    XSTRNCPY(passwd, (char*)userdata, sz);\n    return min((word32)sz, (word32)XSTRLEN((char*)userdata));\n}\n\n/* Return bytes written to buff or < 0 for error */\nint wc_KeyPemToDer(const unsigned char* pem, int pemSz,\n                        unsigned char* buff, int buffSz, const char* pass)\n{\n    int            eccKey = 0;\n    int            ret;\n    DerBuffer*     der = NULL;\n#ifdef WOLFSSL_SMALL_STACK\n    EncryptedInfo* info = NULL;\n#else\n    EncryptedInfo  info[1];\n#endif\n\n    WOLFSSL_ENTER(\"wc_KeyPemToDer\");\n\n    if (pem == NULL || buff == NULL || buffSz <= 0) {\n        WOLFSSL_MSG(\"Bad pem der args\");\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,\n                                   DYNAMIC_TYPE_ENCRYPTEDINFO);\n    if (info == NULL)\n        return MEMORY_E;\n#endif\n\n    XMEMSET(info, 0, sizeof(EncryptedInfo));\n    info->passwd_cb = OurPasswordCb;\n    info->passwd_userdata = (void*)pass;\n\n    ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);\n#endif\n\n    if (ret < 0 || der == NULL) {\n        WOLFSSL_MSG(\"Bad Pem To Der\");\n    }\n    else {\n        if (der->length <= (word32)buffSz) {\n            XMEMCPY(buff, der->buffer, der->length);\n            ret = der->length;\n        }\n        else {\n            WOLFSSL_MSG(\"Bad der length\");\n            ret = BAD_FUNC_ARG;\n        }\n    }\n\n    FreeDer(&der);\n    return ret;\n}\n\n\n/* Return bytes written to buff or < 0 for error */\nint wc_CertPemToDer(const unsigned char* pem, int pemSz,\n                        unsigned char* buff, int buffSz, int type)\n{\n    int            eccKey = 0;\n    int            ret;\n    DerBuffer*     der = NULL;\n\n    WOLFSSL_ENTER(\"wc_CertPemToDer\");\n\n    if (pem == NULL || buff == NULL || buffSz <= 0) {\n        WOLFSSL_MSG(\"Bad pem der args\");\n        return BAD_FUNC_ARG;\n    }\n\n    if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {\n        WOLFSSL_MSG(\"Bad cert type\");\n        return BAD_FUNC_ARG;\n    }\n\n\n    ret = PemToDer(pem, pemSz, type, &der, NULL, NULL, &eccKey);\n    if (ret < 0 || der == NULL) {\n        WOLFSSL_MSG(\"Bad Pem To Der\");\n    }\n    else {\n        if (der->length <= (word32)buffSz) {\n            XMEMCPY(buff, der->buffer, der->length);\n            ret = der->length;\n        }\n        else {\n            WOLFSSL_MSG(\"Bad der length\");\n            ret = BAD_FUNC_ARG;\n        }\n    }\n\n    FreeDer(&der);\n    return ret;\n}\n\n#endif /* WOLFSSL_PEM_TO_DER */\n#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */\n\n\n#ifdef WOLFSSL_PEM_TO_DER\n#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)\n/* Return bytes written to buff or < 0 for error */\nint wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,\n                           unsigned char* buff, int buffSz)\n{\n    int ret;\n    DerBuffer* der = NULL;\n\n    WOLFSSL_ENTER(\"wc_PubKeyPemToDer\");\n\n    if (pem == NULL || buff == NULL || buffSz <= 0) {\n        WOLFSSL_MSG(\"Bad pem der args\");\n        return BAD_FUNC_ARG;\n    }\n\n    ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);\n    if (ret < 0 || der == NULL) {\n        WOLFSSL_MSG(\"Bad Pem To Der\");\n    }\n    else {\n        if (der->length <= (word32)buffSz) {\n            XMEMCPY(buff, der->buffer, der->length);\n            ret = der->length;\n        }\n        else {\n            WOLFSSL_MSG(\"Bad der length\");\n            ret = BAD_FUNC_ARG;\n        }\n    }\n\n    FreeDer(&der);\n    return ret;\n}\n#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */\n#endif /* WOLFSSL_PEM_TO_DER */\n\n#ifndef NO_FILESYSTEM\n\n#ifdef WOLFSSL_CERT_GEN\n/* load pem cert from file into der buffer, return der size or error */\nint wc_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)\n{\n#ifdef WOLFSSL_SMALL_STACK\n    byte   staticBuffer[1]; /* force XMALLOC */\n#else\n    byte   staticBuffer[FILE_BUFFER_SIZE];\n#endif\n    byte*  fileBuf = staticBuffer;\n    int    dynamic = 0;\n    int    ret     = 0;\n    long   sz      = 0;\n    XFILE  file;\n    DerBuffer* converted = NULL;\n\n    WOLFSSL_ENTER(\"wc_PemCertToDer\");\n\n    if (fileName == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n    else {\n        file = XFOPEN(fileName, \"rb\");\n        if (file == XBADFILE) {\n            ret = BUFFER_E;\n        }\n    }\n\n    if (ret == 0) {\n        if(XFSEEK(file, 0, XSEEK_END) != 0)\n            ret = BUFFER_E;\n        sz = XFTELL(file);\n        XREWIND(file);\n\n        if (sz <= 0) {\n            ret = BUFFER_E;\n        }\n        else if (sz > (long)sizeof(staticBuffer)) {\n        #ifdef WOLFSSL_STATIC_MEMORY\n            WOLFSSL_MSG(\"File was larger then static buffer\");\n            return MEMORY_E;\n        #endif\n            fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);\n            if (fileBuf == NULL)\n                ret = MEMORY_E;\n            else\n                dynamic = 1;\n        }\n\n        if (ret == 0) {\n            if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {\n                ret = BUFFER_E;\n            }\n        #ifdef WOLFSSL_PEM_TO_DER\n            else {\n                ret = PemToDer(fileBuf, sz, CA_TYPE, &converted,  0, NULL,NULL);\n            }\n        #endif\n\n            if (ret == 0) {\n                if (converted->length < (word32)derSz) {\n                    XMEMCPY(derBuf, converted->buffer, converted->length);\n                    ret = converted->length;\n                }\n                else\n                    ret = BUFFER_E;\n            }\n\n            FreeDer(&converted);\n        }\n\n        XFCLOSE(file);\n        if (dynamic)\n            XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);\n    }\n\n    return ret;\n}\n#endif /* WOLFSSL_CERT_GEN */\n\n#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)\n/* load pem public key from file into der buffer, return der size or error */\nint wc_PemPubKeyToDer(const char* fileName,\n                           unsigned char* derBuf, int derSz)\n{\n#ifdef WOLFSSL_SMALL_STACK\n    byte   staticBuffer[1]; /* force XMALLOC */\n#else\n    byte   staticBuffer[FILE_BUFFER_SIZE];\n#endif\n    byte*  fileBuf = staticBuffer;\n    int    dynamic = 0;\n    int    ret     = 0;\n    long   sz      = 0;\n    XFILE  file;\n    DerBuffer* converted = NULL;\n\n    WOLFSSL_ENTER(\"wc_PemPubKeyToDer\");\n\n    if (fileName == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n    else {\n        file = XFOPEN(fileName, \"rb\");\n        if (file == XBADFILE) {\n            ret = BUFFER_E;\n        }\n    }\n\n    if (ret == 0) {\n        if(XFSEEK(file, 0, XSEEK_END) != 0)\n            ret = BUFFER_E;\n        sz = XFTELL(file);\n        XREWIND(file);\n\n        if (sz <= 0) {\n            ret = BUFFER_E;\n        }\n        else if (sz > (long)sizeof(staticBuffer)) {\n        #ifdef WOLFSSL_STATIC_MEMORY\n            WOLFSSL_MSG(\"File was larger then static buffer\");\n            return MEMORY_E;\n        #endif\n            fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);\n            if (fileBuf == NULL)\n                ret = MEMORY_E;\n            else\n                dynamic = 1;\n        }\n        if (ret == 0) {\n            if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {\n                ret = BUFFER_E;\n            }\n        #ifdef WOLFSSL_PEM_TO_DER\n            else {\n                ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, &converted,\n                               0, NULL, NULL);\n            }\n        #endif\n\n            if (ret == 0) {\n                if (converted->length < (word32)derSz) {\n                    XMEMCPY(derBuf, converted->buffer, converted->length);\n                    ret = converted->length;\n                }\n                else\n                    ret = BUFFER_E;\n            }\n\n            FreeDer(&converted);\n        }\n\n        XFCLOSE(file);\n        if (dynamic)\n            XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);\n    }\n\n    return ret;\n}\n#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */\n\n#endif /* !NO_FILESYSTEM */\n\n\n#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \\\n    ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)))\n/* USER RSA ifdef portions used instead of refactor in consideration for\n   possible fips build */\n/* Write a public RSA key to output */\nstatic int SetRsaPublicKey(byte* output, RsaKey* key,\n                           int outLen, int with_header)\n{\n#ifdef WOLFSSL_SMALL_STACK\n    byte* n = NULL;\n    byte* e = NULL;\n#else\n    byte n[MAX_RSA_INT_SZ];\n    byte e[MAX_RSA_E_SZ];\n#endif\n    byte seq[MAX_SEQ_SZ];\n    byte bitString[1 + MAX_LENGTH_SZ + 1];\n    int  nSz;\n    int  eSz;\n    int  seqSz;\n    int  bitStringSz;\n    int  idx;\n\n    if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ)\n        return BAD_FUNC_ARG;\n\n    /* n */\n#ifdef WOLFSSL_SMALL_STACK\n    n = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (n == NULL)\n        return MEMORY_E;\n#endif\n\n#ifdef HAVE_USER_RSA\n    nSz = SetASNIntRSA(key->n, n);\n#else\n    nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, n);\n#endif\n    if (nSz < 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return nSz;\n    }\n\n    /* e */\n#ifdef WOLFSSL_SMALL_STACK\n    e = (byte*)XMALLOC(MAX_RSA_E_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (e == NULL) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return MEMORY_E;\n    }\n#endif\n\n#ifdef HAVE_USER_RSA\n    eSz = SetASNIntRSA(key->e, e);\n#else\n    eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, e);\n#endif\n    if (eSz < 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return eSz;\n    }\n\n    seqSz  = SetSequence(nSz + eSz, seq);\n\n    /* check output size */\n    if ( (seqSz + nSz + eSz) > outLen) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return BUFFER_E;\n    }\n\n    /* headers */\n    if (with_header) {\n        int  algoSz;\n#ifdef WOLFSSL_SMALL_STACK\n        byte* algo = NULL;\n\n        algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (algo == NULL) {\n            XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            return MEMORY_E;\n        }\n#else\n        byte algo[MAX_ALGO_SZ];\n#endif\n        algoSz = SetAlgoID(RSAk, algo, oidKeyType, 0);\n        bitStringSz  = SetBitString(seqSz + nSz + eSz, 0, bitString);\n\n        idx = SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, output);\n\n        /* check output size */\n        if ( (idx + algoSz + bitStringSz + seqSz + nSz + eSz) > outLen) {\n            #ifdef WOLFSSL_SMALL_STACK\n                XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n                XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n                XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            #endif\n\n            return BUFFER_E;\n        }\n\n        /* algo */\n        XMEMCPY(output + idx, algo, algoSz);\n        idx += algoSz;\n        /* bit string */\n        XMEMCPY(output + idx, bitString, bitStringSz);\n        idx += bitStringSz;\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n    }\n    else\n        idx = 0;\n\n    /* seq */\n    XMEMCPY(output + idx, seq, seqSz);\n    idx += seqSz;\n    /* n */\n    XMEMCPY(output + idx, n, nSz);\n    idx += nSz;\n    /* e */\n    XMEMCPY(output + idx, e, eSz);\n    idx += eSz;\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(n,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(e,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return idx;\n}\n\n#endif /* !NO_RSA && (WOLFSSL_CERT_GEN || (WOLFSSL_KEY_GEN &&\n                                           !HAVE_USER_RSA))) */\n\n#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA))\nint wc_RsaPublicKeyDerSize(RsaKey* key, int with_header)\n{\n    int  idx = 0;\n    int  nSz, eSz, seqSz, bitStringSz, algoSz;\n\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    /* n */\n#ifdef HAVE_USER_RSA\n    nSz = SetASNIntRSA(key->n, NULL);\n#else\n    nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, NULL);\n#endif\n    if (nSz < 0) {\n        return nSz;\n    }\n\n    /* e */\n#ifdef HAVE_USER_RSA\n    eSz = SetASNIntRSA(key->e, NULL);\n#else\n    eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, NULL);\n#endif\n    if (eSz < 0) {\n        return eSz;\n    }\n\n    seqSz  = SetSequence(nSz + eSz, NULL);\n\n    /* headers */\n    if (with_header) {\n        algoSz = SetAlgoID(RSAk, NULL, oidKeyType, 0);\n        bitStringSz = SetBitString(seqSz + nSz + eSz, 0, NULL);\n\n        idx += SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, NULL);\n\n        /* algo */\n        idx += algoSz;\n        /* bit string */\n        idx += bitStringSz;\n    }\n\n    /* seq */\n    idx += seqSz;\n    /* n */\n    idx += nSz;\n    /* e */\n    idx += eSz;\n\n    return idx;\n}\n\n#endif /* !NO_RSA && WOLFSSL_CERT_GEN */\n\n\n#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)\n\nstatic mp_int* GetRsaInt(RsaKey* key, int idx)\n{\n    if (idx == 0)\n        return &key->n;\n    if (idx == 1)\n        return &key->e;\n    if (idx == 2)\n        return &key->d;\n    if (idx == 3)\n        return &key->p;\n    if (idx == 4)\n        return &key->q;\n    if (idx == 5)\n        return &key->dP;\n    if (idx == 6)\n        return &key->dQ;\n    if (idx == 7)\n        return &key->u;\n\n    return NULL;\n}\n\n\n/* Release Tmp RSA resources */\nstatic WC_INLINE void FreeTmpRsas(byte** tmps, void* heap)\n{\n    int i;\n\n    (void)heap;\n\n    for (i = 0; i < RSA_INTS; i++)\n        XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA);\n}\n\n\n/* Convert RsaKey key to DER format, write to output (inLen), return bytes\n   written */\nint wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)\n{\n    word32 seqSz, verSz, rawLen, intTotalLen = 0;\n    word32 sizes[RSA_INTS];\n    int    i, j, outLen, ret = 0, mpSz;\n\n    byte  seq[MAX_SEQ_SZ];\n    byte  ver[MAX_VERSION_SZ];\n    byte* tmps[RSA_INTS];\n\n    if (!key || !output)\n        return BAD_FUNC_ARG;\n\n    if (key->type != RSA_PRIVATE)\n        return BAD_FUNC_ARG;\n\n    for (i = 0; i < RSA_INTS; i++)\n        tmps[i] = NULL;\n\n    /* write all big ints from key to DER tmps */\n    for (i = 0; i < RSA_INTS; i++) {\n        mp_int* keyInt = GetRsaInt(key, i);\n\n        rawLen = mp_unsigned_bin_size(keyInt) + 1;\n        tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,\n                                 DYNAMIC_TYPE_RSA);\n        if (tmps[i] == NULL) {\n            ret = MEMORY_E;\n            break;\n        }\n\n        mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]);\n        if (mpSz < 0) {\n            ret = mpSz;\n            break;\n        }\n        intTotalLen += (sizes[i] = mpSz);\n    }\n\n    if (ret != 0) {\n        FreeTmpRsas(tmps, key->heap);\n        return ret;\n    }\n\n    /* make headers */\n    verSz = SetMyVersion(0, ver, FALSE);\n    seqSz = SetSequence(verSz + intTotalLen, seq);\n\n    outLen = seqSz + verSz + intTotalLen;\n    if (outLen > (int)inLen) {\n        FreeTmpRsas(tmps, key->heap);\n        return BAD_FUNC_ARG;\n    }\n\n    /* write to output */\n    XMEMCPY(output, seq, seqSz);\n    j = seqSz;\n    XMEMCPY(output + j, ver, verSz);\n    j += verSz;\n\n    for (i = 0; i < RSA_INTS; i++) {\n        XMEMCPY(output + j, tmps[i], sizes[i]);\n        j += sizes[i];\n    }\n    FreeTmpRsas(tmps, key->heap);\n\n    return outLen;\n}\n#endif\n\n#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)\n/* Convert Rsa Public key to DER format, write to output (inLen), return bytes\n   written */\nint wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)\n{\n    return SetRsaPublicKey(output, key, inLen, 1);\n}\n\n#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA && !HAVE_USER_RSA */\n\n\n#ifdef WOLFSSL_CERT_GEN\n\n/* Initialize and Set Certificate defaults:\n   version    = 3 (0x2)\n   serial     = 0\n   sigType    = SHA_WITH_RSA\n   issuer     = blank\n   daysValid  = 500\n   selfSigned = 1 (true) use subject as issuer\n   subject    = blank\n*/\nint wc_InitCert(Cert* cert)\n{\n#ifdef WOLFSSL_MULTI_ATTRIB\n    int i = 0;\n#endif\n    if (cert == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    XMEMSET(cert, 0, sizeof(Cert));\n\n    cert->version    = 2;   /* version 3 is hex 2 */\n#ifndef NO_SHA\n    cert->sigType    = CTC_SHAwRSA;\n#elif !defined(NO_SHA256)\n    cert->sigType    = CTC_SHA256wRSA;\n#else\n    cert->sigType    = 0;\n#endif\n    cert->daysValid  = 500;\n    cert->selfSigned = 1;\n    cert->keyType    = RSA_KEY;\n\n    cert->issuer.countryEnc = CTC_PRINTABLE;\n    cert->issuer.stateEnc = CTC_UTF8;\n    cert->issuer.localityEnc = CTC_UTF8;\n    cert->issuer.surEnc = CTC_UTF8;\n    cert->issuer.orgEnc = CTC_UTF8;\n    cert->issuer.unitEnc = CTC_UTF8;\n    cert->issuer.commonNameEnc = CTC_UTF8;\n\n    cert->subject.countryEnc = CTC_PRINTABLE;\n    cert->subject.stateEnc = CTC_UTF8;\n    cert->subject.localityEnc = CTC_UTF8;\n    cert->subject.surEnc = CTC_UTF8;\n    cert->subject.orgEnc = CTC_UTF8;\n    cert->subject.unitEnc = CTC_UTF8;\n    cert->subject.commonNameEnc = CTC_UTF8;\n\n#ifdef WOLFSSL_MULTI_ATTRIB\n    for (i = 0; i < CTC_MAX_ATTRIB; i++) {\n        cert->issuer.name[i].type   = CTC_UTF8;\n        cert->subject.name[i].type  = CTC_UTF8;\n    }\n#endif /* WOLFSSL_MULTI_ATTRIB */\n\n#ifdef WOLFSSL_HEAP_TEST\n    cert->heap = (void*)WOLFSSL_HEAP_TEST;\n#endif\n\n    return 0;\n}\n\n\n/* DER encoded x509 Certificate */\ntypedef struct DerCert {\n    byte size[MAX_LENGTH_SZ];          /* length encoded */\n    byte version[MAX_VERSION_SZ];      /* version encoded */\n    byte serial[(int)CTC_SERIAL_SIZE + (int)MAX_LENGTH_SZ]; /* serial number encoded */\n    byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */\n    byte issuer[ASN_NAME_MAX];         /* issuer  encoded */\n    byte subject[ASN_NAME_MAX];        /* subject encoded */\n    byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */\n    byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */\n    byte ca[MAX_CA_SZ];                /* basic constraint CA true size */\n    byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */\n#ifdef WOLFSSL_CERT_EXT\n    byte skid[MAX_KID_SZ];             /* Subject Key Identifier extension */\n    byte akid[MAX_KID_SZ];             /* Authority Key Identifier extension */\n    byte keyUsage[MAX_KEYUSAGE_SZ];    /* Key Usage extension */\n    byte extKeyUsage[MAX_EXTKEYUSAGE_SZ]; /* Extended Key Usage extension */\n    byte certPolicies[MAX_CERTPOL_NB*MAX_CERTPOL_SZ]; /* Certificate Policies */\n#endif\n#ifdef WOLFSSL_CERT_REQ\n    byte attrib[MAX_ATTRIB_SZ];        /* Cert req attributes encoded */\n#endif\n#ifdef WOLFSSL_ALT_NAMES\n    byte altNames[CTC_MAX_ALT_SIZE];   /* Alternative Names encoded */\n#endif\n    int  sizeSz;                       /* encoded size length */\n    int  versionSz;                    /* encoded version length */\n    int  serialSz;                     /* encoded serial length */\n    int  sigAlgoSz;                    /* encoded sig alog length */\n    int  issuerSz;                     /* encoded issuer length */\n    int  subjectSz;                    /* encoded subject length */\n    int  validitySz;                   /* encoded validity length */\n    int  publicKeySz;                  /* encoded public key length */\n    int  caSz;                         /* encoded CA extension length */\n#ifdef WOLFSSL_CERT_EXT\n    int  skidSz;                       /* encoded SKID extension length */\n    int  akidSz;                       /* encoded SKID extension length */\n    int  keyUsageSz;                   /* encoded KeyUsage extension length */\n    int  extKeyUsageSz;                /* encoded ExtendedKeyUsage extension length */\n    int  certPoliciesSz;               /* encoded CertPolicies extension length*/\n#endif\n#ifdef WOLFSSL_ALT_NAMES\n    int  altNamesSz;                   /* encoded AltNames extension length */\n#endif\n    int  extensionsSz;                 /* encoded extensions total length */\n    int  total;                        /* total encoded lengths */\n#ifdef WOLFSSL_CERT_REQ\n    int  attribSz;\n#endif\n} DerCert;\n\n\n#ifdef WOLFSSL_CERT_REQ\n\n/* Write a set header to output */\nstatic word32 SetPrintableString(word32 len, byte* output)\n{\n    output[0] = ASN_PRINTABLE_STRING;\n    return SetLength(len, output + 1) + 1;\n}\n\nstatic word32 SetUTF8String(word32 len, byte* output)\n{\n    output[0] = ASN_UTF8STRING;\n    return SetLength(len, output + 1) + 1;\n}\n\n#endif /* WOLFSSL_CERT_REQ */\n\n\n#ifndef WOLFSSL_CERT_GEN_CACHE\n/* wc_SetCert_Free is only public when WOLFSSL_CERT_GEN_CACHE is not defined */\nstatic\n#endif\nvoid wc_SetCert_Free(Cert* cert)\n{\n    if (cert != NULL) {\n\n        if (cert->der != NULL) {\n            cert->der = NULL;\n        }\n\n        if (cert->decodedCert) {\n            FreeDecodedCert((DecodedCert*)cert->decodedCert);\n\n            XFREE(cert->decodedCert, cert->heap, DYNAMIC_TYPE_DCERT);\n            cert->decodedCert = NULL;\n        }\n    }\n}\n\nstatic int wc_SetCert_LoadDer(Cert* cert, const byte* der, word32 derSz)\n{\n    int ret;\n\n    if (cert == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n    else {\n        /* Allocate DecodedCert struct and Zero */\n        cert->decodedCert = (void*)XMALLOC(sizeof(DecodedCert), cert->heap,\n            DYNAMIC_TYPE_DCERT);\n\n        if (cert->decodedCert == NULL) {\n            ret = MEMORY_E;\n        }\n        else {\n            XMEMSET(cert->decodedCert, 0, sizeof(DecodedCert));\n\n            InitDecodedCert((DecodedCert*)cert->decodedCert, der, derSz,\n                    cert->heap);\n            ret = ParseCertRelative((DecodedCert*)cert->decodedCert,\n                    CERT_TYPE, 0, NULL);\n            if (ret >= 0) {\n                cert->der = (byte*)der;\n            }\n            else {\n                wc_SetCert_Free(cert);\n            }\n        }\n    }\n\n    return ret;\n}\n\n#endif /* WOLFSSL_CERT_GEN */\n\n\n#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)\n\n/* Write a public ECC key to output */\nstatic int SetEccPublicKey(byte* output, ecc_key* key, int with_header)\n{\n    byte bitString[1 + MAX_LENGTH_SZ + 1];\n    int  algoSz;\n    int  curveSz;\n    int  bitStringSz;\n    int  idx;\n    word32 pubSz = ECC_BUFSIZE;\n#ifdef WOLFSSL_SMALL_STACK\n    byte* algo = NULL;\n    byte* curve = NULL;\n    byte* pub = NULL;\n#else\n    byte algo[MAX_ALGO_SZ];\n    byte curve[MAX_ALGO_SZ];\n    byte pub[ECC_BUFSIZE];\n#endif\n    int ret;\n\n#ifdef WOLFSSL_SMALL_STACK\n    pub = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (pub == NULL)\n        return MEMORY_E;\n#endif\n\n#ifdef HAVE_SELFTEST\n    /* older version of ecc.c can not handle dp being NULL */\n    if (key != NULL && key->dp == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n    else {\n        ret = wc_ecc_export_x963(key, pub, &pubSz);\n    }\n#else\n    ret = wc_ecc_export_x963(key, pub, &pubSz);\n#endif\n    if (ret != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return ret;\n    }\n\n    /* headers */\n    if (with_header) {\n#ifdef WOLFSSL_SMALL_STACK\n        curve = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (curve == NULL) {\n            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            return MEMORY_E;\n        }\n#endif\n        curveSz = SetCurve(key, curve);\n        if (curveSz <= 0) {\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n            return curveSz;\n        }\n\n#ifdef WOLFSSL_SMALL_STACK\n        algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (algo == NULL) {\n            XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            return MEMORY_E;\n        }\n#endif\n        algoSz  = SetAlgoID(ECDSAk, algo, oidKeyType, curveSz);\n\n        bitStringSz = SetBitString(pubSz, 0, bitString);\n\n        idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, output);\n        /* algo */\n        if (output)\n            XMEMCPY(output + idx, algo, algoSz);\n        idx += algoSz;\n        /* curve */\n        if (output)\n            XMEMCPY(output + idx, curve, curveSz);\n        idx += curveSz;\n        /* bit string */\n        if (output)\n            XMEMCPY(output + idx, bitString, bitStringSz);\n        idx += bitStringSz;\n    }\n    else\n        idx = 0;\n\n    /* pub */\n    if (output)\n        XMEMCPY(output + idx, pub, pubSz);\n    idx += pubSz;\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (with_header) {\n        XFREE(algo,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n    XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return idx;\n}\n\n\n/* returns the size of buffer used, the public ECC key in DER format is stored\n   in output buffer\n   with_AlgCurve is a flag for when to include a header that has the Algorithm\n   and Curve information */\nint wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen,\n                                                              int with_AlgCurve)\n{\n    word32 infoSz = 0;\n    word32 keySz  = 0;\n    int ret;\n\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (with_AlgCurve) {\n        /* buffer space for algorithm/curve */\n        infoSz += MAX_SEQ_SZ;\n        infoSz += 2 * MAX_ALGO_SZ;\n\n        /* buffer space for public key sequence */\n        infoSz += MAX_SEQ_SZ;\n        infoSz += TRAILING_ZERO;\n    }\n\n#ifdef HAVE_SELFTEST\n    /* older version of ecc.c can not handle dp being NULL */\n    if (key != NULL && key->dp == NULL) {\n        keySz = 1 + 2 * MAX_ECC_BYTES;\n        ret = LENGTH_ONLY_E;\n    }\n    else {\n        ret = wc_ecc_export_x963(key, NULL, &keySz);\n    }\n#else\n    ret = wc_ecc_export_x963(key, NULL, &keySz);\n#endif\n    if (ret != LENGTH_ONLY_E) {\n        WOLFSSL_MSG(\"Error in getting ECC public key size\");\n        return ret;\n    }\n\n    /* if output null then just return size */\n    if (output == NULL) {\n        return keySz + infoSz;\n    }\n\n    if (output == NULL || inLen < keySz + infoSz) {\n        return BUFFER_E;\n    }\n\n    return SetEccPublicKey(output, key, with_AlgCurve);\n}\n\nint wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve)\n{\n    return wc_EccPublicKeyToDer(key, NULL, 0, with_AlgCurve);\n}\n\n#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */\n\n#if defined(HAVE_ED25519) && (defined(WOLFSSL_CERT_GEN) || \\\n                              defined(WOLFSSL_KEY_GEN))\n\n/* Write a public ECC key to output */\nstatic int SetEd25519PublicKey(byte* output, ed25519_key* key, int with_header)\n{\n    byte bitString[1 + MAX_LENGTH_SZ + 1];\n    int  algoSz;\n    int  bitStringSz;\n    int  idx;\n    word32 pubSz = ED25519_PUB_KEY_SIZE;\n#ifdef WOLFSSL_SMALL_STACK\n    byte* algo = NULL;\n    byte* pub = NULL;\n#else\n    byte algo[MAX_ALGO_SZ];\n    byte pub[ED25519_PUB_KEY_SIZE];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (pub == NULL)\n        return MEMORY_E;\n#endif\n\n    idx = wc_ed25519_export_public(key, pub, &pubSz);\n    if (idx != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return idx;\n    }\n\n    /* headers */\n    if (with_header) {\n#ifdef WOLFSSL_SMALL_STACK\n        algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        if (algo == NULL) {\n            XFREE(pub,   key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            return MEMORY_E;\n        }\n#endif\n        algoSz  = SetAlgoID(ED25519k, algo, oidKeyType, 0);\n\n        bitStringSz = SetBitString(pubSz, 0, bitString);\n\n        idx = SetSequence(pubSz + bitStringSz + algoSz, output);\n        /* algo */\n        XMEMCPY(output + idx, algo, algoSz);\n        idx += algoSz;\n        /* bit string */\n        XMEMCPY(output + idx, bitString, bitStringSz);\n        idx += bitStringSz;\n    }\n    else\n        idx = 0;\n\n    /* pub */\n    XMEMCPY(output + idx, pub, pubSz);\n    idx += pubSz;\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (with_header) {\n        XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n    XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return idx;\n}\n\nint wc_Ed25519PublicKeyToDer(ed25519_key* key, byte* output, word32 inLen,\n                                                                    int withAlg)\n{\n    word32 infoSz = 0;\n    word32 keySz  = 0;\n    int ret;\n\n    if (output == NULL || key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (withAlg) {\n        /* buffer space for algorithm */\n        infoSz += MAX_SEQ_SZ;\n        infoSz += MAX_ALGO_SZ;\n\n        /* buffer space for public key sequence */\n        infoSz += MAX_SEQ_SZ;\n        infoSz += TRAILING_ZERO;\n    }\n\n    if ((ret = wc_ed25519_export_public(key, output, &keySz)) != BUFFER_E) {\n        WOLFSSL_MSG(\"Error in getting ECC public key size\");\n        return ret;\n    }\n\n    if (inLen < keySz + infoSz) {\n        return BUFFER_E;\n    }\n\n    return SetEd25519PublicKey(output, key, withAlg);\n}\n#endif /* HAVE_ED25519 && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */\n\n\n#ifdef WOLFSSL_CERT_GEN\n\nstatic WC_INLINE byte itob(int number)\n{\n    return (byte)number + 0x30;\n}\n\n\n/* write time to output, format */\nstatic void SetTime(struct tm* date, byte* output)\n{\n    int i = 0;\n\n    output[i++] = itob((date->tm_year % 10000) / 1000);\n    output[i++] = itob((date->tm_year % 1000)  /  100);\n    output[i++] = itob((date->tm_year % 100)   /   10);\n    output[i++] = itob( date->tm_year % 10);\n\n    output[i++] = itob(date->tm_mon / 10);\n    output[i++] = itob(date->tm_mon % 10);\n\n    output[i++] = itob(date->tm_mday / 10);\n    output[i++] = itob(date->tm_mday % 10);\n\n    output[i++] = itob(date->tm_hour / 10);\n    output[i++] = itob(date->tm_hour % 10);\n\n    output[i++] = itob(date->tm_min / 10);\n    output[i++] = itob(date->tm_min % 10);\n\n    output[i++] = itob(date->tm_sec / 10);\n    output[i++] = itob(date->tm_sec % 10);\n\n    output[i] = 'Z';  /* Zulu profile */\n}\n\n\n#ifdef WOLFSSL_ALT_NAMES\n\n/* Copy Dates from cert, return bytes written */\nstatic int CopyValidity(byte* output, Cert* cert)\n{\n    int seqSz;\n\n    WOLFSSL_ENTER(\"CopyValidity\");\n\n    /* headers and output */\n    seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output);\n    if (output) {\n        XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz);\n        XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,\n                                                     cert->afterDateSz);\n    }\n    return seqSz + cert->beforeDateSz + cert->afterDateSz;\n}\n\n#endif\n\n\n/* Set Date validity from now until now + daysValid\n * return size in bytes written to output, 0 on error */\nstatic int SetValidity(byte* output, int daysValid)\n{\n    byte before[MAX_DATE_SIZE];\n    byte  after[MAX_DATE_SIZE];\n\n    int beforeSz;\n    int afterSz;\n    int seqSz;\n\n    time_t now;\n    time_t then;\n    struct tm* tmpTime = NULL;\n    struct tm* expandedTime;\n    struct tm localTime;\n\n#if defined(NEED_TMP_TIME)\n    /* for use with gmtime_r */\n    struct tm tmpTimeStorage;\n    tmpTime = &tmpTimeStorage;\n#else\n    (void)tmpTime;\n#endif\n\n    now = XTIME(0);\n\n    /* before now */\n    before[0] = ASN_GENERALIZED_TIME;\n    beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */\n\n    /* subtract 1 day of seconds for more compliance */\n    then = now - 86400;\n    expandedTime = XGMTIME(&then, tmpTime);\n    if (expandedTime == NULL) {\n        WOLFSSL_MSG(\"XGMTIME failed\");\n        return 0;   /* error */\n    }\n    localTime = *expandedTime;\n\n    /* adjust */\n    localTime.tm_year += 1900;\n    localTime.tm_mon +=    1;\n\n    SetTime(&localTime, before + beforeSz);\n    beforeSz += ASN_GEN_TIME_SZ;\n\n    after[0] = ASN_GENERALIZED_TIME;\n    afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */\n\n    /* add daysValid of seconds */\n    then = now + (daysValid * (time_t)86400);\n    expandedTime = XGMTIME(&then, tmpTime);\n    if (expandedTime == NULL) {\n        WOLFSSL_MSG(\"XGMTIME failed\");\n        return 0;   /* error */\n    }\n    localTime = *expandedTime;\n\n    /* adjust */\n    localTime.tm_year += 1900;\n    localTime.tm_mon  +=    1;\n\n    SetTime(&localTime, after + afterSz);\n    afterSz += ASN_GEN_TIME_SZ;\n\n    /* headers and output */\n    seqSz = SetSequence(beforeSz + afterSz, output);\n    XMEMCPY(output + seqSz, before, beforeSz);\n    XMEMCPY(output + seqSz + beforeSz, after, afterSz);\n\n    return seqSz + beforeSz + afterSz;\n}\n\n\n/* ASN Encoded Name field */\ntypedef struct EncodedName {\n    int  nameLen;                /* actual string value length */\n    int  totalLen;               /* total encoded length */\n    int  type;                   /* type of name */\n    int  used;                   /* are we actually using this one */\n    byte encoded[CTC_NAME_SIZE * 2]; /* encoding */\n} EncodedName;\n\n\n/* Get Which Name from index */\nstatic const char* GetOneName(CertName* name, int idx)\n{\n    switch (idx) {\n    case 0:\n       return name->country;\n\n    case 1:\n       return name->state;\n\n    case 2:\n       return name->locality;\n\n    case 3:\n       return name->sur;\n\n    case 4:\n       return name->org;\n\n    case 5:\n       return name->unit;\n\n    case 6:\n       return name->commonName;\n\n    case 7:\n       return name->serialDev;\n\n#ifdef WOLFSSL_CERT_EXT\n    case 8:\n       return name->busCat;\n\n    case 9:\n#else\n    case 8:\n#endif\n       return name->email;\n\n    default:\n       return 0;\n    }\n}\n\n\n/* Get Which Name Encoding from index */\nstatic char GetNameType(CertName* name, int idx)\n{\n    switch (idx) {\n    case 0:\n       return name->countryEnc;\n\n    case 1:\n       return name->stateEnc;\n\n    case 2:\n       return name->localityEnc;\n\n    case 3:\n       return name->surEnc;\n\n    case 4:\n       return name->orgEnc;\n\n    case 5:\n       return name->unitEnc;\n\n    case 6:\n       return name->commonNameEnc;\n\n    case 7:\n       return name->serialDevEnc;\n\n#ifdef WOLFSSL_CERT_EXT\n    case 8:\n       return name->busCatEnc;\n\n    case 9:\n#else\n    case 8:\n#endif\n        /* FALL THROUGH */\n        /* The last index, email name, does not have encoding type.\n           The empty case here is to keep track of it for future reference. */\n    default:\n       return 0;\n    }\n}\n\n\n/* Get ASN Name from index */\nstatic byte GetNameId(int idx)\n{\n    switch (idx) {\n    case 0:\n       return ASN_COUNTRY_NAME;\n\n    case 1:\n       return ASN_STATE_NAME;\n\n    case 2:\n       return ASN_LOCALITY_NAME;\n\n    case 3:\n       return ASN_SUR_NAME;\n\n    case 4:\n       return ASN_ORG_NAME;\n\n    case 5:\n       return ASN_ORGUNIT_NAME;\n\n    case 6:\n       return ASN_COMMON_NAME;\n\n    case 7:\n       return ASN_SERIAL_NUMBER;\n\n#ifdef WOLFSSL_CERT_EXT\n    case 8:\n        return ASN_BUS_CAT;\n\n    case 9:\n#else\n    case 8:\n#endif\n        return ASN_EMAIL_NAME;\n\n    default:\n       return 0;\n    }\n}\n\n/*\n Extensions ::= SEQUENCE OF Extension\n\n Extension ::= SEQUENCE {\n extnId     OBJECT IDENTIFIER,\n critical   BOOLEAN DEFAULT FALSE,\n extnValue  OCTET STRING }\n */\n\n/* encode all extensions, return total bytes written */\nstatic int SetExtensions(byte* out, word32 outSz, int *IdxInOut,\n                         const byte* ext, int extSz)\n{\n    if (out == NULL || IdxInOut == NULL || ext == NULL)\n        return BAD_FUNC_ARG;\n\n    if (outSz < (word32)(*IdxInOut+extSz))\n        return BUFFER_E;\n\n    XMEMCPY(&out[*IdxInOut], ext, extSz);  /* extensions */\n    *IdxInOut += extSz;\n\n    return *IdxInOut;\n}\n\n/* encode extensions header, return total bytes written */\nstatic int SetExtensionsHeader(byte* out, word32 outSz, int extSz)\n{\n    byte sequence[MAX_SEQ_SZ];\n    byte len[MAX_LENGTH_SZ];\n    int seqSz, lenSz, idx = 0;\n\n    if (out == NULL)\n        return BAD_FUNC_ARG;\n\n    if (outSz < 3)\n        return BUFFER_E;\n\n    seqSz = SetSequence(extSz, sequence);\n\n    /* encode extensions length provided */\n    lenSz = SetLength(extSz+seqSz, len);\n\n    if (outSz < (word32)(lenSz+seqSz+1))\n        return BUFFER_E;\n\n    out[idx++] = ASN_EXTENSIONS; /* extensions id */\n    XMEMCPY(&out[idx], len, lenSz);  /* length */\n    idx += lenSz;\n\n    XMEMCPY(&out[idx], sequence, seqSz);  /* sequence */\n    idx += seqSz;\n\n    return idx;\n}\n\n\n/* encode CA basic constraint true, return total bytes written */\nstatic int SetCa(byte* out, word32 outSz)\n{\n    static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,\n                               0x05, 0x30, 0x03, 0x01, 0x01, 0xff };\n\n    if (out == NULL)\n        return BAD_FUNC_ARG;\n\n    if (outSz < sizeof(ca))\n        return BUFFER_E;\n\n    XMEMCPY(out, ca, sizeof(ca));\n\n    return (int)sizeof(ca);\n}\n\n\n#ifdef WOLFSSL_CERT_EXT\n/* encode OID and associated value, return total bytes written */\nstatic int SetOidValue(byte* out, word32 outSz, const byte *oid, word32 oidSz,\n                       byte *in, word32 inSz)\n{\n    int idx = 0;\n\n    if (out == NULL || oid == NULL || in == NULL)\n        return BAD_FUNC_ARG;\n\n    if (outSz < 3)\n        return BUFFER_E;\n\n    /* sequence,  + 1 => byte to put value size */\n    idx = SetSequence(inSz + oidSz + 1, out);\n\n    if ((idx + inSz + oidSz + 1) > outSz)\n        return BUFFER_E;\n\n    XMEMCPY(out+idx, oid, oidSz);\n    idx += oidSz;\n    out[idx++] = (byte)inSz;\n    XMEMCPY(out+idx, in, inSz);\n\n    return (idx+inSz);\n}\n\n/* encode Subject Key Identifier, return total bytes written\n * RFC5280 : non-critical */\nstatic int SetSKID(byte* output, word32 outSz, const byte *input, word32 length)\n{\n    byte skid_len[1 + MAX_LENGTH_SZ];\n    byte skid_enc_len[MAX_LENGTH_SZ];\n    int idx = 0, skid_lenSz, skid_enc_lenSz;\n    static const byte skid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04 };\n\n    if (output == NULL || input == NULL)\n        return BAD_FUNC_ARG;\n\n    /* Octet String header */\n    skid_lenSz = SetOctetString(length, skid_len);\n\n    /* length of encoded value */\n    skid_enc_lenSz = SetLength(length + skid_lenSz, skid_enc_len);\n\n    if (outSz < 3)\n        return BUFFER_E;\n\n    idx = SetSequence(length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz,\n                      output);\n\n    if ((length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz) > outSz)\n        return BUFFER_E;\n\n    /* put oid */\n    XMEMCPY(output+idx, skid_oid, sizeof(skid_oid));\n    idx += sizeof(skid_oid);\n\n    /* put encoded len */\n    XMEMCPY(output+idx, skid_enc_len, skid_enc_lenSz);\n    idx += skid_enc_lenSz;\n\n    /* put octet header */\n    XMEMCPY(output+idx, skid_len, skid_lenSz);\n    idx += skid_lenSz;\n\n    /* put value */\n    XMEMCPY(output+idx, input, length);\n    idx += length;\n\n    return idx;\n}\n\n/* encode Authority Key Identifier, return total bytes written\n * RFC5280 : non-critical */\nstatic int SetAKID(byte* output, word32 outSz,\n                                         byte *input, word32 length, void* heap)\n{\n    byte    *enc_val;\n    int     ret, enc_valSz;\n    static const byte akid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04 };\n    static const byte akid_cs[] = { 0x80 };\n\n    (void)heap;\n\n    if (output == NULL || input == NULL)\n        return BAD_FUNC_ARG;\n\n    enc_valSz = length + 3 + sizeof(akid_cs);\n    enc_val = (byte *)XMALLOC(enc_valSz, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (enc_val == NULL)\n        return MEMORY_E;\n\n    /* sequence for ContentSpec & value */\n    ret = SetOidValue(enc_val, enc_valSz, akid_cs, sizeof(akid_cs),\n                      input, length);\n    if (ret > 0) {\n        enc_valSz = ret;\n\n        ret = SetOidValue(output, outSz, akid_oid, sizeof(akid_oid),\n                          enc_val, enc_valSz);\n    }\n\n    XFREE(enc_val, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    return ret;\n}\n\n/* encode Key Usage, return total bytes written\n * RFC5280 : critical */\nstatic int SetKeyUsage(byte* output, word32 outSz, word16 input)\n{\n    byte ku[5];\n    int  idx;\n    static const byte keyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0f,\n                                         0x01, 0x01, 0xff, 0x04};\n    if (output == NULL)\n        return BAD_FUNC_ARG;\n\n    idx = SetBitString16Bit(input, ku);\n    return SetOidValue(output, outSz, keyusage_oid, sizeof(keyusage_oid),\n                       ku, idx);\n}\n\nstatic int SetOjectIdValue(byte* output, word32 outSz, int* idx,\n    const byte* oid, word32 oidSz)\n{\n    /* verify room */\n    if (*idx + 2 + oidSz >= outSz)\n        return ASN_PARSE_E;\n\n    *idx += SetObjectId(oidSz, &output[*idx]);\n    XMEMCPY(&output[*idx], oid, oidSz);\n    *idx += oidSz;\n\n    return 0;\n}\n\n/* encode Extended Key Usage (RFC 5280 4.2.1.12), return total bytes written */\nstatic int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)\n{\n    int idx = 0, oidListSz = 0, totalSz, ret = 0;\n    static const byte extkeyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x25 };\n\n    if (output == NULL)\n        return BAD_FUNC_ARG;\n\n    /* Skip to OID List */\n    totalSz = 2 + sizeof(extkeyusage_oid) + 4;\n    idx = totalSz;\n\n    /* Build OID List */\n    /* If any set, then just use it */\n    if (input & EXTKEYUSE_ANY) {\n        ret |= SetOjectIdValue(output, outSz, &idx,\n            extExtKeyUsageAnyOid, sizeof(extExtKeyUsageAnyOid));\n    }\n    else {\n        if (input & EXTKEYUSE_SERVER_AUTH)\n            ret |= SetOjectIdValue(output, outSz, &idx,\n                extExtKeyUsageServerAuthOid, sizeof(extExtKeyUsageServerAuthOid));\n        if (input & EXTKEYUSE_CLIENT_AUTH)\n            ret |= SetOjectIdValue(output, outSz, &idx,\n                extExtKeyUsageClientAuthOid, sizeof(extExtKeyUsageClientAuthOid));\n        if (input & EXTKEYUSE_CODESIGN)\n            ret |= SetOjectIdValue(output, outSz, &idx,\n                extExtKeyUsageCodeSigningOid, sizeof(extExtKeyUsageCodeSigningOid));\n        if (input & EXTKEYUSE_EMAILPROT)\n            ret |= SetOjectIdValue(output, outSz, &idx,\n                extExtKeyUsageEmailProtectOid, sizeof(extExtKeyUsageEmailProtectOid));\n        if (input & EXTKEYUSE_TIMESTAMP)\n            ret |= SetOjectIdValue(output, outSz, &idx,\n                extExtKeyUsageTimestampOid, sizeof(extExtKeyUsageTimestampOid));\n        if (input & EXTKEYUSE_OCSP_SIGN)\n            ret |= SetOjectIdValue(output, outSz, &idx,\n                extExtKeyUsageOcspSignOid, sizeof(extExtKeyUsageOcspSignOid));\n    #ifdef WOLFSSL_EKU_OID\n        /* iterate through OID values */\n        if (input & EXTKEYUSE_USER) {\n            int i, sz;\n            for (i = 0; i < CTC_MAX_EKU_NB; i++) {\n                sz = cert->extKeyUsageOIDSz[i];\n                if (sz > 0) {\n                    ret |= SetOjectIdValue(output, outSz, &idx,\n                        cert->extKeyUsageOID[i], sz);\n                }\n            }\n        }\n    #endif /* WOLFSSL_EKU_OID */\n    }\n    if (ret != 0)\n        return ASN_PARSE_E;\n\n    /* Calculate Sizes */\n    oidListSz = idx - totalSz;\n    totalSz = idx - 2; /* exclude first seq/len (2) */\n\n    /* 1. Seq + Total Len (2) */\n    idx = SetSequence(totalSz, output);\n\n    /* 2. Object ID (2) */\n    XMEMCPY(&output[idx], extkeyusage_oid, sizeof(extkeyusage_oid));\n    idx += sizeof(extkeyusage_oid);\n\n    /* 3. Octect String (2) */\n    idx += SetOctetString(totalSz - idx, &output[idx]);\n\n    /* 4. Seq + OidListLen (2) */\n    idx += SetSequence(oidListSz, &output[idx]);\n\n    /* 5. Oid List (already set in-place above) */\n    idx += oidListSz;\n\n    (void)cert;\n    return idx;\n}\n\n/* encode Certificate Policies, return total bytes written\n * each input value must be ITU-T X.690 formatted : a.b.c...\n * input must be an array of values with a NULL terminated for the latest\n * RFC5280 : non-critical */\nstatic int SetCertificatePolicies(byte *output,\n                                  word32 outputSz,\n                                  char input[MAX_CERTPOL_NB][MAX_CERTPOL_SZ],\n                                  word16 nb_certpol,\n                                  void* heap)\n{\n    byte    oid[MAX_OID_SZ],\n            der_oid[MAX_CERTPOL_NB][MAX_OID_SZ],\n            out[MAX_CERTPOL_SZ];\n    word32  oidSz;\n    word32  outSz, i = 0, der_oidSz[MAX_CERTPOL_NB];\n    int     ret;\n\n    static const byte certpol_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04 };\n    static const byte oid_oid[] = { 0x06 };\n\n    if (output == NULL || input == NULL || nb_certpol > MAX_CERTPOL_NB)\n        return BAD_FUNC_ARG;\n\n    for (i = 0; i < nb_certpol; i++) {\n        oidSz = sizeof(oid);\n        XMEMSET(oid, 0, oidSz);\n\n        ret = EncodePolicyOID(oid, &oidSz, input[i], heap);\n        if (ret != 0)\n            return ret;\n\n        /* compute sequence value for the oid */\n        ret = SetOidValue(der_oid[i], MAX_OID_SZ, oid_oid,\n                          sizeof(oid_oid), oid, oidSz);\n        if (ret <= 0)\n            return ret;\n        else\n            der_oidSz[i] = (word32)ret;\n    }\n\n    /* concatenate oid, keep two byte for sequence/size of the created value */\n    for (i = 0, outSz = 2; i < nb_certpol; i++) {\n        XMEMCPY(out+outSz, der_oid[i], der_oidSz[i]);\n        outSz += der_oidSz[i];\n    }\n\n    /* add sequence */\n    ret = SetSequence(outSz-2, out);\n    if (ret <= 0)\n        return ret;\n\n    /* add Policy OID to compute final value */\n    return SetOidValue(output, outputSz, certpol_oid, sizeof(certpol_oid),\n                      out, outSz);\n}\n#endif /* WOLFSSL_CERT_EXT */\n\n#ifdef WOLFSSL_ALT_NAMES\n/* encode Alternative Names, return total bytes written */\nstatic int SetAltNames(byte *out, word32 outSz, byte *input, word32 length)\n{\n    if (out == NULL || input == NULL)\n        return BAD_FUNC_ARG;\n\n    if (outSz < length)\n        return BUFFER_E;\n\n    /* Alternative Names come from certificate or computed by\n     * external function, so already encoded. Just copy value */\n    XMEMCPY(out, input, length);\n    return length;\n}\n#endif /* WOLFSL_ALT_NAMES */\n\n/* Encodes one attribute of the name (issuer/subject)\n *\n * name     structure to hold result of encoding\n * nameStr  value to be encoded\n * nameType type of encoding i.e CTC_UTF8\n * type     id of attribute i.e ASN_COMMON_NAME\n *\n * returns length on success\n */\nstatic int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType,\n        byte type)\n{\n    word32 idx = 0;\n\n    if (nameStr) {\n        /* bottom up */\n        byte firstLen[1 + MAX_LENGTH_SZ];\n        byte secondLen[MAX_LENGTH_SZ];\n        byte sequence[MAX_SEQ_SZ];\n        byte set[MAX_SET_SZ];\n\n        int strLen  = (int)XSTRLEN(nameStr);\n        int thisLen = strLen;\n        int firstSz, secondSz, seqSz, setSz;\n\n        if (strLen == 0) { /* no user data for this item */\n            name->used = 0;\n            return 0;\n        }\n\n        /* Restrict country code size */\n        if (ASN_COUNTRY_NAME == type && strLen != CTC_COUNTRY_SIZE) {\n            return ASN_COUNTRY_SIZE_E;\n        }\n\n        secondSz = SetLength(strLen, secondLen);\n        thisLen += secondSz;\n        switch (type) {\n            case ASN_EMAIL_NAME: /* email */\n                thisLen += EMAIL_JOINT_LEN;\n                firstSz  = EMAIL_JOINT_LEN;\n                break;\n\n            case ASN_DOMAIN_COMPONENT:\n                thisLen += PILOT_JOINT_LEN;\n                firstSz  = PILOT_JOINT_LEN;\n                break;\n\n            default:\n                thisLen++;                                 /* str type */\n                thisLen += JOINT_LEN;\n                firstSz  = JOINT_LEN + 1;\n        }\n        thisLen++; /* id  type */\n        firstSz  = SetObjectId(firstSz, firstLen);\n        thisLen += firstSz;\n\n        seqSz = SetSequence(thisLen, sequence);\n        thisLen += seqSz;\n        setSz = SetSet(thisLen, set);\n        thisLen += setSz;\n\n        if (thisLen > (int)sizeof(name->encoded)) {\n            return BUFFER_E;\n        }\n\n        /* store it */\n        idx = 0;\n        /* set */\n        XMEMCPY(name->encoded, set, setSz);\n        idx += setSz;\n        /* seq */\n        XMEMCPY(name->encoded + idx, sequence, seqSz);\n        idx += seqSz;\n        /* asn object id */\n        XMEMCPY(name->encoded + idx, firstLen, firstSz);\n        idx += firstSz;\n        switch (type) {\n            case ASN_EMAIL_NAME:\n                {\n                    const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,\n                                       0x01, 0x09, 0x01, 0x16 };\n                    /* email joint id */\n                    XMEMCPY(name->encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));\n                    idx += (int)sizeof(EMAIL_OID);\n                }\n                break;\n\n            case ASN_DOMAIN_COMPONENT:\n                {\n                    const byte PILOT_OID[] = { 0x09, 0x92, 0x26, 0x89,\n                                    0x93, 0xF2, 0x2C, 0x64, 0x01\n                    };\n\n                    XMEMCPY(name->encoded + idx, PILOT_OID,\n                                                     sizeof(PILOT_OID));\n                    idx += (int)sizeof(PILOT_OID);\n                    /* id type */\n                    name->encoded[idx++] = type;\n                    /* str type */\n                    name->encoded[idx++] = nameType;\n                }\n                break;\n\n            default:\n                name->encoded[idx++] = 0x55;\n                name->encoded[idx++] = 0x04;\n                /* id type */\n                name->encoded[idx++] = type;\n                /* str type */\n                name->encoded[idx++] = nameType;\n        }\n        /* second length */\n        XMEMCPY(name->encoded + idx, secondLen, secondSz);\n        idx += secondSz;\n        /* str value */\n        XMEMCPY(name->encoded + idx, nameStr, strLen);\n        idx += strLen;\n\n        name->type = type;\n        name->totalLen = idx;\n        name->used = 1;\n    }\n    else\n        name->used = 0;\n\n    return idx;\n}\n\n/* encode CertName into output, return total bytes written */\nint SetName(byte* output, word32 outputSz, CertName* name)\n{\n    int          totalBytes = 0, i, idx;\n#ifdef WOLFSSL_SMALL_STACK\n    EncodedName* names = NULL;\n#else\n    EncodedName  names[NAME_ENTRIES];\n#endif\n#ifdef WOLFSSL_MULTI_ATTRIB\n    EncodedName addNames[CTC_MAX_ATTRIB];\n    int j, type;\n#endif\n\n    if (output == NULL || name == NULL)\n        return BAD_FUNC_ARG;\n\n    if (outputSz < 3)\n        return BUFFER_E;\n\n#ifdef WOLFSSL_SMALL_STACK\n    names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (names == NULL)\n        return MEMORY_E;\n#endif\n\n    for (i = 0; i < NAME_ENTRIES; i++) {\n        int ret;\n        const char* nameStr = GetOneName(name, i);\n\n        ret = wc_EncodeName(&names[i], nameStr, GetNameType(name, i),\n                          GetNameId(i));\n        if (ret < 0) {\n        #ifdef WOLFSSL_SMALL_STACK\n                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n                return BUFFER_E;\n        }\n        totalBytes += ret;\n    }\n#ifdef WOLFSSL_MULTI_ATTRIB\n    for (i = 0; i < CTC_MAX_ATTRIB; i++) {\n        if (name->name[i].sz > 0) {\n            int ret;\n            ret = wc_EncodeName(&addNames[i], name->name[i].value,\n                        name->name[i].type, name->name[i].id);\n            if (ret < 0) {\n            #ifdef WOLFSSL_SMALL_STACK\n                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n            #endif\n                return BUFFER_E;\n            }\n            totalBytes += ret;\n        }\n        else {\n            addNames[i].used = 0;\n        }\n    }\n#endif /* WOLFSSL_MULTI_ATTRIB */\n\n    /* header */\n    idx = SetSequence(totalBytes, output);\n    totalBytes += idx;\n    if (totalBytes > ASN_NAME_MAX) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return BUFFER_E;\n    }\n\n    for (i = 0; i < NAME_ENTRIES; i++) {\n    #ifdef WOLFSSL_MULTI_ATTRIB\n        type = GetNameId(i);\n\n        /* list all DC values before OUs */\n        if (type == ASN_ORGUNIT_NAME) {\n            type = ASN_DOMAIN_COMPONENT;\n            for (j = 0; j < CTC_MAX_ATTRIB; j++) {\n                if (name->name[j].sz > 0 && type == name->name[j].id) {\n                    if (outputSz < (word32)(idx+addNames[j].totalLen)) {\n                    #ifdef WOLFSSL_SMALL_STACK\n                        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n                    #endif\n                        return BUFFER_E;\n                    }\n\n                    XMEMCPY(output + idx, addNames[j].encoded,\n                            addNames[j].totalLen);\n                    idx += addNames[j].totalLen;\n                }\n            }\n            type = ASN_ORGUNIT_NAME;\n        }\n\n        /* write all similar types to the buffer */\n        for (j = 0; j < CTC_MAX_ATTRIB; j++) {\n            if (name->name[j].sz > 0 && type == name->name[j].id) {\n                if (outputSz < (word32)(idx+addNames[j].totalLen)) {\n                #ifdef WOLFSSL_SMALL_STACK\n                    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n                #endif\n                    return BUFFER_E;\n                }\n\n                XMEMCPY(output + idx, addNames[j].encoded,\n                        addNames[j].totalLen);\n                idx += addNames[j].totalLen;\n            }\n        }\n    #endif /* WOLFSSL_MULTI_ATTRIB */\n\n        if (names[i].used) {\n            if (outputSz < (word32)(idx+names[i].totalLen)) {\n#ifdef WOLFSSL_SMALL_STACK\n                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n                return BUFFER_E;\n            }\n\n            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);\n            idx += names[i].totalLen;\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return totalBytes;\n}\n\n/* encode info from cert into DER encoded format */\nstatic int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,\n                      WC_RNG* rng, const byte* ntruKey, word16 ntruSz,\n                      ed25519_key* ed25519Key)\n{\n    int ret;\n\n    if (cert == NULL || der == NULL || rng == NULL)\n        return BAD_FUNC_ARG;\n\n    /* make sure at least one key type is provided */\n    if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL && ntruKey == NULL)\n        return PUBLIC_KEY_E;\n\n    /* init */\n    XMEMSET(der, 0, sizeof(DerCert));\n\n    /* version */\n    der->versionSz = SetMyVersion(cert->version, der->version, TRUE);\n\n    /* serial number (must be positive) */\n    if (cert->serialSz == 0) {\n        /* generate random serial */\n        cert->serialSz = CTC_GEN_SERIAL_SZ;\n        ret = wc_RNG_GenerateBlock(rng, cert->serial, cert->serialSz);\n        if (ret != 0)\n            return ret;\n        /* Clear the top bit to avoid a negative value */\n        cert->serial[0] &= 0x7f;\n    }\n    der->serialSz = SetSerialNumber(cert->serial, cert->serialSz, der->serial,\n        sizeof(der->serial), CTC_SERIAL_SIZE);\n    if (der->serialSz < 0)\n        return der->serialSz;\n\n    /* signature algo */\n    der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, oidSigType, 0);\n    if (der->sigAlgoSz <= 0)\n        return ALGO_ID_E;\n\n    /* public key */\n#ifndef NO_RSA\n    if (cert->keyType == RSA_KEY) {\n        if (rsaKey == NULL)\n            return PUBLIC_KEY_E;\n        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,\n                                           sizeof(der->publicKey), 1);\n    }\n#endif\n\n#ifdef HAVE_ECC\n    if (cert->keyType == ECC_KEY) {\n        if (eccKey == NULL)\n            return PUBLIC_KEY_E;\n        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, 1);\n    }\n#endif\n\n#ifdef HAVE_ED25519\n    if (cert->keyType == ED25519_KEY) {\n        if (ed25519Key == NULL)\n            return PUBLIC_KEY_E;\n        der->publicKeySz = SetEd25519PublicKey(der->publicKey, ed25519Key, 1);\n    }\n#endif\n\n#ifdef HAVE_NTRU\n    if (cert->keyType == NTRU_KEY) {\n        word32 rc;\n        word16 encodedSz;\n\n        if (ntruKey == NULL)\n            return PUBLIC_KEY_E;\n\n        rc  = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(ntruSz,\n                                                   ntruKey, &encodedSz, NULL);\n        if (rc != NTRU_OK)\n            return PUBLIC_KEY_E;\n        if (encodedSz > MAX_PUBLIC_KEY_SZ)\n            return PUBLIC_KEY_E;\n\n        rc  = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(ntruSz,\n                                         ntruKey, &encodedSz, der->publicKey);\n        if (rc != NTRU_OK)\n            return PUBLIC_KEY_E;\n\n        der->publicKeySz = encodedSz;\n    }\n#else\n    (void)ntruSz;\n#endif /* HAVE_NTRU */\n\n    if (der->publicKeySz <= 0)\n        return PUBLIC_KEY_E;\n\n    der->validitySz = 0;\n#ifdef WOLFSSL_ALT_NAMES\n    /* date validity copy ? */\n    if (cert->beforeDateSz && cert->afterDateSz) {\n        der->validitySz = CopyValidity(der->validity, cert);\n        if (der->validitySz <= 0)\n            return DATE_E;\n    }\n#endif\n\n    /* date validity */\n    if (der->validitySz == 0) {\n        der->validitySz = SetValidity(der->validity, cert->daysValid);\n        if (der->validitySz <= 0)\n            return DATE_E;\n    }\n\n    /* subject name */\n#ifdef WOLFSSL_CERT_EXT\n    if (XSTRLEN((const char*)cert->sbjRaw) > 0) {\n        /* Use the raw subject */\n        int idx;\n\n        der->subjectSz = min(sizeof(der->subject),\n                (word32)XSTRLEN((const char*)cert->sbjRaw));\n        /* header */\n        idx = SetSequence(der->subjectSz, der->subject);\n        if (der->subjectSz + idx > (int)sizeof(der->subject)) {\n            return SUBJECT_E;\n        }\n\n        XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,\n                der->subjectSz);\n        der->subjectSz += idx;\n    }\n    else\n#endif\n    {\n        /* Use the name structure */\n        der->subjectSz = SetName(der->subject, sizeof(der->subject),\n                &cert->subject);\n    }\n    if (der->subjectSz <= 0)\n        return SUBJECT_E;\n\n    /* issuer name */\n#ifdef WOLFSSL_CERT_EXT\n    if (XSTRLEN((const char*)cert->issRaw) > 0) {\n        /* Use the raw issuer */\n        int idx;\n\n        der->issuerSz = min(sizeof(der->issuer),\n                (word32)XSTRLEN((const char*)cert->issRaw));\n        /* header */\n        idx = SetSequence(der->issuerSz, der->issuer);\n        if (der->issuerSz + idx > (int)sizeof(der->issuer)) {\n            return ISSUER_E;\n        }\n\n        XMEMCPY((char*)der->issuer + idx, (const char*)cert->issRaw,\n                der->issuerSz);\n        der->issuerSz += idx;\n    }\n    else\n#endif\n    {\n        /* Use the name structure */\n        der->issuerSz = SetName(der->issuer, sizeof(der->issuer),\n                cert->selfSigned ? &cert->subject : &cert->issuer);\n    }\n    if (der->issuerSz <= 0)\n        return ISSUER_E;\n\n    /* set the extensions */\n    der->extensionsSz = 0;\n\n    /* CA */\n    if (cert->isCA) {\n        der->caSz = SetCa(der->ca, sizeof(der->ca));\n        if (der->caSz <= 0)\n            return CA_TRUE_E;\n\n        der->extensionsSz += der->caSz;\n    }\n    else\n        der->caSz = 0;\n\n#ifdef WOLFSSL_ALT_NAMES\n    /* Alternative Name */\n    if (cert->altNamesSz) {\n        der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),\n                                      cert->altNames, cert->altNamesSz);\n        if (der->altNamesSz <= 0)\n            return ALT_NAME_E;\n\n        der->extensionsSz += der->altNamesSz;\n    }\n    else\n        der->altNamesSz = 0;\n#endif\n\n#ifdef WOLFSSL_CERT_EXT\n    /* SKID */\n    if (cert->skidSz) {\n        /* check the provided SKID size */\n        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))\n            return SKID_E;\n\n        /* Note: different skid buffers sizes for der (MAX_KID_SZ) and\n            cert (CTC_MAX_SKID_SIZE). */\n        der->skidSz = SetSKID(der->skid, sizeof(der->skid),\n                              cert->skid, cert->skidSz);\n        if (der->skidSz <= 0)\n            return SKID_E;\n\n        der->extensionsSz += der->skidSz;\n    }\n    else\n        der->skidSz = 0;\n\n    /* AKID */\n    if (cert->akidSz) {\n        /* check the provided AKID size */\n        if (cert->akidSz > (int)min(CTC_MAX_AKID_SIZE, sizeof(der->akid)))\n            return AKID_E;\n\n        der->akidSz = SetAKID(der->akid, sizeof(der->akid),\n                              cert->akid, cert->akidSz, cert->heap);\n        if (der->akidSz <= 0)\n            return AKID_E;\n\n        der->extensionsSz += der->akidSz;\n    }\n    else\n        der->akidSz = 0;\n\n    /* Key Usage */\n    if (cert->keyUsage != 0){\n        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),\n                                      cert->keyUsage);\n        if (der->keyUsageSz <= 0)\n            return KEYUSAGE_E;\n\n        der->extensionsSz += der->keyUsageSz;\n    }\n    else\n        der->keyUsageSz = 0;\n\n    /* Extended Key Usage */\n    if (cert->extKeyUsage != 0){\n        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,\n                                sizeof(der->extKeyUsage), cert->extKeyUsage);\n        if (der->extKeyUsageSz <= 0)\n            return EXTKEYUSAGE_E;\n\n        der->extensionsSz += der->extKeyUsageSz;\n    }\n    else\n        der->extKeyUsageSz = 0;\n\n    /* Certificate Policies */\n    if (cert->certPoliciesNb != 0) {\n        der->certPoliciesSz = SetCertificatePolicies(der->certPolicies,\n                                                     sizeof(der->certPolicies),\n                                                     cert->certPolicies,\n                                                     cert->certPoliciesNb,\n                                                     cert->heap);\n        if (der->certPoliciesSz <= 0)\n            return CERTPOLICIES_E;\n\n        der->extensionsSz += der->certPoliciesSz;\n    }\n    else\n        der->certPoliciesSz = 0;\n#endif /* WOLFSSL_CERT_EXT */\n\n    /* put extensions */\n    if (der->extensionsSz > 0) {\n\n        /* put the start of extensions sequence (ID, Size) */\n        der->extensionsSz = SetExtensionsHeader(der->extensions,\n                                                sizeof(der->extensions),\n                                                der->extensionsSz);\n        if (der->extensionsSz <= 0)\n            return EXTENSIONS_E;\n\n        /* put CA */\n        if (der->caSz) {\n            ret = SetExtensions(der->extensions, sizeof(der->extensions),\n                                &der->extensionsSz,\n                                der->ca, der->caSz);\n            if (ret == 0)\n                return EXTENSIONS_E;\n        }\n\n#ifdef WOLFSSL_ALT_NAMES\n        /* put Alternative Names */\n        if (der->altNamesSz) {\n            ret = SetExtensions(der->extensions, sizeof(der->extensions),\n                                &der->extensionsSz,\n                                der->altNames, der->altNamesSz);\n            if (ret <= 0)\n                return EXTENSIONS_E;\n        }\n#endif\n\n#ifdef WOLFSSL_CERT_EXT\n        /* put SKID */\n        if (der->skidSz) {\n            ret = SetExtensions(der->extensions, sizeof(der->extensions),\n                                &der->extensionsSz,\n                                der->skid, der->skidSz);\n            if (ret <= 0)\n                return EXTENSIONS_E;\n        }\n\n        /* put AKID */\n        if (der->akidSz) {\n            ret = SetExtensions(der->extensions, sizeof(der->extensions),\n                                &der->extensionsSz,\n                                der->akid, der->akidSz);\n            if (ret <= 0)\n                return EXTENSIONS_E;\n        }\n\n        /* put KeyUsage */\n        if (der->keyUsageSz) {\n            ret = SetExtensions(der->extensions, sizeof(der->extensions),\n                                &der->extensionsSz,\n                                der->keyUsage, der->keyUsageSz);\n            if (ret <= 0)\n                return EXTENSIONS_E;\n        }\n\n        /* put ExtendedKeyUsage */\n        if (der->extKeyUsageSz) {\n            ret = SetExtensions(der->extensions, sizeof(der->extensions),\n                                &der->extensionsSz,\n                                der->extKeyUsage, der->extKeyUsageSz);\n            if (ret <= 0)\n                return EXTENSIONS_E;\n        }\n\n        /* put Certificate Policies */\n        if (der->certPoliciesSz) {\n            ret = SetExtensions(der->extensions, sizeof(der->extensions),\n                                &der->extensionsSz,\n                                der->certPolicies, der->certPoliciesSz);\n            if (ret <= 0)\n                return EXTENSIONS_E;\n        }\n#endif /* WOLFSSL_CERT_EXT */\n    }\n\n    der->total = der->versionSz + der->serialSz + der->sigAlgoSz +\n        der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +\n        der->extensionsSz;\n\n    return 0;\n}\n\n\n/* write DER encoded cert to buffer, size already checked */\nstatic int WriteCertBody(DerCert* der, byte* buffer)\n{\n    int idx;\n\n    /* signed part header */\n    idx = SetSequence(der->total, buffer);\n    /* version */\n    XMEMCPY(buffer + idx, der->version, der->versionSz);\n    idx += der->versionSz;\n    /* serial */\n    XMEMCPY(buffer + idx, der->serial, der->serialSz);\n    idx += der->serialSz;\n    /* sig algo */\n    XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz);\n    idx += der->sigAlgoSz;\n    /* issuer */\n    XMEMCPY(buffer + idx, der->issuer, der->issuerSz);\n    idx += der->issuerSz;\n    /* validity */\n    XMEMCPY(buffer + idx, der->validity, der->validitySz);\n    idx += der->validitySz;\n    /* subject */\n    XMEMCPY(buffer + idx, der->subject, der->subjectSz);\n    idx += der->subjectSz;\n    /* public key */\n    XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);\n    idx += der->publicKeySz;\n    if (der->extensionsSz) {\n        /* extensions */\n        XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,\n                                                   (int)sizeof(der->extensions)));\n        idx += der->extensionsSz;\n    }\n\n    return idx;\n}\n\n\n/* Make RSA signature from buffer (sz), write to sig (sigSz) */\nstatic int MakeSignature(CertSignCtx* certSignCtx, const byte* buffer, int sz,\n    byte* sig, int sigSz, RsaKey* rsaKey, ecc_key* eccKey,\n    ed25519_key* ed25519Key, WC_RNG* rng, int sigAlgoType, void* heap)\n{\n    int digestSz = 0, typeH = 0, ret = 0;\n\n    (void)digestSz;\n    (void)typeH;\n    (void)buffer;\n    (void)sz;\n    (void)sig;\n    (void)sigSz;\n    (void)rsaKey;\n    (void)eccKey;\n    (void)ed25519Key;\n    (void)rng;\n    (void)heap;\n\n    switch (certSignCtx->state) {\n    case CERTSIGN_STATE_BEGIN:\n    case CERTSIGN_STATE_DIGEST:\n\n        certSignCtx->state = CERTSIGN_STATE_DIGEST;\n        certSignCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap,\n            DYNAMIC_TYPE_TMP_BUFFER);\n        if (certSignCtx->digest == NULL) {\n            ret = MEMORY_E; goto exit_ms;\n        }\n\n        ret = HashForSignature(buffer, sz, sigAlgoType, certSignCtx->digest,\n                               &typeH, &digestSz, 0);\n        /* set next state, since WC_PENDING_E rentry for these are not \"call again\" */\n        certSignCtx->state = CERTSIGN_STATE_ENCODE;\n        if (ret != 0) {\n            goto exit_ms;\n        }\n        FALL_THROUGH;\n\n    case CERTSIGN_STATE_ENCODE:\n    #ifndef NO_RSA\n        if (rsaKey) {\n            certSignCtx->encSig = (byte*)XMALLOC(MAX_DER_DIGEST_SZ, heap,\n                DYNAMIC_TYPE_TMP_BUFFER);\n            if (certSignCtx->encSig == NULL) {\n                ret = MEMORY_E; goto exit_ms;\n            }\n\n            /* signature */\n            certSignCtx->encSigSz = wc_EncodeSignature(certSignCtx->encSig,\n                                          certSignCtx->digest, digestSz, typeH);\n        }\n    #endif /* !NO_RSA */\n        FALL_THROUGH;\n\n    case CERTSIGN_STATE_DO:\n        certSignCtx->state = CERTSIGN_STATE_DO;\n        ret = ALGO_ID_E; /* default to error */\n\n    #ifndef NO_RSA\n        if (rsaKey) {\n            /* signature */\n            ret = wc_RsaSSL_Sign(certSignCtx->encSig, certSignCtx->encSigSz,\n                                 sig, sigSz, rsaKey, rng);\n        }\n    #endif /* !NO_RSA */\n\n    #ifdef HAVE_ECC\n        if (!rsaKey && eccKey) {\n            word32 outSz = sigSz;\n\n            ret = wc_ecc_sign_hash(certSignCtx->digest, digestSz,\n                                   sig, &outSz, rng, eccKey);\n            if (ret == 0)\n                ret = outSz;\n        }\n    #endif /* HAVE_ECC */\n\n    #ifdef HAVE_ED25519\n        if (!rsaKey && !eccKey && ed25519Key) {\n            word32 outSz = sigSz;\n\n            ret = wc_ed25519_sign_msg(buffer, sz, sig, &outSz, ed25519Key);\n            if (ret == 0)\n                ret = outSz;\n        }\n    #endif /* HAVE_ECC */\n        break;\n    }\n\nexit_ms:\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    if (ret == WC_PENDING_E) {\n        return ret;\n    }\n#endif\n\n#ifndef NO_RSA\n    if (rsaKey) {\n        XFREE(certSignCtx->encSig, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif /* !NO_RSA */\n\n    XFREE(certSignCtx->digest, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    certSignCtx->digest = NULL;\n\n    /* reset state */\n    certSignCtx->state = CERTSIGN_STATE_BEGIN;\n\n    return ret;\n}\n\n\n/* add signature to end of buffer, size of buffer assumed checked, return\n   new length */\nstatic int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz,\n                        int sigAlgoType)\n{\n    byte seq[MAX_SEQ_SZ];\n    int  idx = bodySz, seqSz;\n\n    /* algo */\n    idx += SetAlgoID(sigAlgoType, buffer ? buffer + idx : NULL, oidSigType, 0);\n    /* bit string */\n    idx += SetBitString(sigSz, 0, buffer ? buffer + idx : NULL);\n    /* signature */\n    if (buffer)\n        XMEMCPY(buffer + idx, sig, sigSz);\n    idx += sigSz;\n\n    /* make room for overall header */\n    seqSz = SetSequence(idx, seq);\n    if (buffer) {\n        XMEMMOVE(buffer + seqSz, buffer, idx);\n        XMEMCPY(buffer, seq, seqSz);\n    }\n\n    return idx + seqSz;\n}\n\n\n/* Make an x509 Certificate v3 any key type from cert input, write to buffer */\nstatic int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,\n                       RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,\n                       const byte* ntruKey, word16 ntruSz,\n                       ed25519_key* ed25519Key)\n{\n    int ret;\n#ifdef WOLFSSL_SMALL_STACK\n    DerCert* der;\n#else\n    DerCert der[1];\n#endif\n\n    if (derBuffer == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    cert->keyType = eccKey ? ECC_KEY : (rsaKey ? RSA_KEY :\n                                         (ed25519Key ? ED25519_KEY : NTRU_KEY));\n\n#ifdef WOLFSSL_SMALL_STACK\n    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (der == NULL)\n        return MEMORY_E;\n#endif\n\n    ret = EncodeCert(cert, der, rsaKey, eccKey, rng, ntruKey, ntruSz,\n                     ed25519Key);\n    if (ret == 0) {\n        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)\n            ret = BUFFER_E;\n        else\n            ret = cert->bodySz = WriteCertBody(der, derBuffer);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n\n/* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */\nint wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,\n                   void* key, WC_RNG* rng)\n{\n    RsaKey* rsaKey = NULL;\n    ecc_key* eccKey = NULL;\n    ed25519_key* ed25519Key = NULL;\n\n    if (keyType == RSA_TYPE)\n        rsaKey = (RsaKey*)key;\n    else if (keyType == ECC_TYPE)\n        eccKey = (ecc_key*)key;\n    else if (keyType == ED25519_TYPE)\n        ed25519Key = (ed25519_key*)key;\n\n    return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0,\n                       ed25519Key);\n}\n/* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */\nint wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,\n             ecc_key* eccKey, WC_RNG* rng)\n{\n    return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0,\n                       NULL);\n}\n\n\n#ifdef HAVE_NTRU\n\nint wc_MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,\n                  const byte* ntruKey, word16 keySz, WC_RNG* rng)\n{\n    return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz, NULL);\n}\n\n#endif /* HAVE_NTRU */\n\n\n#ifdef WOLFSSL_CERT_REQ\n\nstatic int SetReqAttrib(byte* output, char* pw, int pwPrintableString,\n                        int extSz)\n{\n    static const byte cpOid[] =\n        { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,\n                         0x09, 0x07 };\n    static const byte erOid[] =\n        { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,\n                         0x09, 0x0e };\n\n    int sz      = 0; /* overall size */\n    int cpSz    = 0; /* Challenge Password section size */\n    int cpSeqSz = 0;\n    int cpSetSz = 0;\n    int cpStrSz = 0;\n    int pwSz    = 0;\n    int erSz    = 0; /* Extension Request section size */\n    int erSeqSz = 0;\n    int erSetSz = 0;\n    byte cpSeq[MAX_SEQ_SZ];\n    byte cpSet[MAX_SET_SZ];\n    byte cpStr[MAX_PRSTR_SZ];\n    byte erSeq[MAX_SEQ_SZ];\n    byte erSet[MAX_SET_SZ];\n\n    output[0] = 0xa0;\n    sz++;\n\n    if (pw && pw[0]) {\n        pwSz = (int)XSTRLEN(pw);\n        if (pwPrintableString) {\n            cpStrSz = SetPrintableString(pwSz, cpStr);\n        } else {\n            cpStrSz = SetUTF8String(pwSz, cpStr);\n        }\n        cpSetSz = SetSet(cpStrSz + pwSz, cpSet);\n        cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq);\n        cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz;\n    }\n\n    if (extSz) {\n        erSetSz = SetSet(extSz, erSet);\n        erSeqSz = SetSequence(erSetSz + sizeof(erOid) + extSz, erSeq);\n        erSz = extSz + erSetSz + erSeqSz + sizeof(erOid);\n    }\n\n    /* Put the pieces together. */\n    sz += SetLength(cpSz + erSz, &output[sz]);\n\n    if (cpSz) {\n        XMEMCPY(&output[sz], cpSeq, cpSeqSz);\n        sz += cpSeqSz;\n        XMEMCPY(&output[sz], cpOid, sizeof(cpOid));\n        sz += sizeof(cpOid);\n        XMEMCPY(&output[sz], cpSet, cpSetSz);\n        sz += cpSetSz;\n        XMEMCPY(&output[sz], cpStr, cpStrSz);\n        sz += cpStrSz;\n        XMEMCPY(&output[sz], pw, pwSz);\n        sz += pwSz;\n    }\n\n    if (erSz) {\n        XMEMCPY(&output[sz], erSeq, erSeqSz);\n        sz += erSeqSz;\n        XMEMCPY(&output[sz], erOid, sizeof(erOid));\n        sz += sizeof(erOid);\n        XMEMCPY(&output[sz], erSet, erSetSz);\n        sz += erSetSz;\n        /* The actual extension data will be tacked onto the output later. */\n    }\n\n    return sz;\n}\n\n\n/* encode info from cert into DER encoded format */\nstatic int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,\n                         ecc_key* eccKey, ed25519_key* ed25519Key)\n{\n    (void)eccKey;\n    (void)ed25519Key;\n\n    if (cert == NULL || der == NULL)\n        return BAD_FUNC_ARG;\n\n    if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL)\n            return PUBLIC_KEY_E;\n\n    /* init */\n    XMEMSET(der, 0, sizeof(DerCert));\n\n    /* version */\n    der->versionSz = SetMyVersion(cert->version, der->version, FALSE);\n\n    /* subject name */\n    der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);\n    if (der->subjectSz <= 0)\n        return SUBJECT_E;\n\n    /* public key */\n#ifndef NO_RSA\n    if (cert->keyType == RSA_KEY) {\n        if (rsaKey == NULL)\n            return PUBLIC_KEY_E;\n        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,\n                                           sizeof(der->publicKey), 1);\n    }\n#endif\n\n#ifdef HAVE_ECC\n    if (cert->keyType == ECC_KEY) {\n        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, 1);\n    }\n#endif\n\n#ifdef HAVE_ED25519\n    if (cert->keyType == ED25519_KEY) {\n        if (ed25519Key == NULL)\n            return PUBLIC_KEY_E;\n        der->publicKeySz = SetEd25519PublicKey(der->publicKey, ed25519Key, 1);\n    }\n#endif\n\n    if (der->publicKeySz <= 0)\n        return PUBLIC_KEY_E;\n\n    /* set the extensions */\n    der->extensionsSz = 0;\n\n    /* CA */\n    if (cert->isCA) {\n        der->caSz = SetCa(der->ca, sizeof(der->ca));\n        if (der->caSz <= 0)\n            return CA_TRUE_E;\n\n        der->extensionsSz += der->caSz;\n    }\n    else\n        der->caSz = 0;\n\n#ifdef WOLFSSL_CERT_EXT\n    /* SKID */\n    if (cert->skidSz) {\n        /* check the provided SKID size */\n        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))\n            return SKID_E;\n\n        der->skidSz = SetSKID(der->skid, sizeof(der->skid),\n                              cert->skid, cert->skidSz);\n        if (der->skidSz <= 0)\n            return SKID_E;\n\n        der->extensionsSz += der->skidSz;\n    }\n    else\n        der->skidSz = 0;\n\n    /* Key Usage */\n    if (cert->keyUsage != 0){\n        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),\n                                      cert->keyUsage);\n        if (der->keyUsageSz <= 0)\n            return KEYUSAGE_E;\n\n        der->extensionsSz += der->keyUsageSz;\n    }\n    else\n        der->keyUsageSz = 0;\n\n    /* Extended Key Usage */\n    if (cert->extKeyUsage != 0){\n        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,\n                                sizeof(der->extKeyUsage), cert->extKeyUsage);\n        if (der->extKeyUsageSz <= 0)\n            return EXTKEYUSAGE_E;\n\n        der->extensionsSz += der->extKeyUsageSz;\n    }\n    else\n        der->extKeyUsageSz = 0;\n\n#endif /* WOLFSSL_CERT_EXT */\n\n    /* put extensions */\n    if (der->extensionsSz > 0) {\n        int ret;\n\n        /* put the start of sequence (ID, Size) */\n        der->extensionsSz = SetSequence(der->extensionsSz, der->extensions);\n        if (der->extensionsSz <= 0)\n            return EXTENSIONS_E;\n\n        /* put CA */\n        if (der->caSz) {\n            ret = SetExtensions(der->extensions, sizeof(der->extensions),\n                                &der->extensionsSz,\n                                der->ca, der->caSz);\n            if (ret <= 0)\n                return EXTENSIONS_E;\n        }\n\n#ifdef WOLFSSL_CERT_EXT\n        /* put SKID */\n        if (der->skidSz) {\n            ret = SetExtensions(der->extensions, sizeof(der->extensions),\n                                &der->extensionsSz,\n                                der->skid, der->skidSz);\n            if (ret <= 0)\n                return EXTENSIONS_E;\n        }\n\n        /* put AKID */\n        if (der->akidSz) {\n            ret = SetExtensions(der->extensions, sizeof(der->extensions),\n                                &der->extensionsSz,\n                                der->akid, der->akidSz);\n            if (ret <= 0)\n                return EXTENSIONS_E;\n        }\n\n        /* put KeyUsage */\n        if (der->keyUsageSz) {\n            ret = SetExtensions(der->extensions, sizeof(der->extensions),\n                                &der->extensionsSz,\n                                der->keyUsage, der->keyUsageSz);\n            if (ret <= 0)\n                return EXTENSIONS_E;\n        }\n\n        /* put ExtendedKeyUsage */\n        if (der->extKeyUsageSz) {\n            ret = SetExtensions(der->extensions, sizeof(der->extensions),\n                                &der->extensionsSz,\n                                der->extKeyUsage, der->extKeyUsageSz);\n            if (ret <= 0)\n                return EXTENSIONS_E;\n        }\n\n#endif /* WOLFSSL_CERT_EXT */\n    }\n\n    der->attribSz = SetReqAttrib(der->attrib, cert->challengePw,\n                                 cert->challengePwPrintableString,\n                                 der->extensionsSz);\n    if (der->attribSz <= 0)\n        return REQ_ATTRIBUTE_E;\n\n    der->total = der->versionSz + der->subjectSz + der->publicKeySz +\n        der->extensionsSz + der->attribSz;\n\n    return 0;\n}\n\n\n/* write DER encoded cert req to buffer, size already checked */\nstatic int WriteCertReqBody(DerCert* der, byte* buffer)\n{\n    int idx;\n\n    /* signed part header */\n    idx = SetSequence(der->total, buffer);\n    /* version */\n    if (buffer)\n        XMEMCPY(buffer + idx, der->version, der->versionSz);\n    idx += der->versionSz;\n    /* subject */\n    if (buffer)\n        XMEMCPY(buffer + idx, der->subject, der->subjectSz);\n    idx += der->subjectSz;\n    /* public key */\n    if (buffer)\n        XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);\n    idx += der->publicKeySz;\n    /* attributes */\n    if (buffer)\n        XMEMCPY(buffer + idx, der->attrib, der->attribSz);\n    idx += der->attribSz;\n    /* extensions */\n    if (der->extensionsSz) {\n        if (buffer)\n            XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,\n                                               (int)sizeof(der->extensions)));\n        idx += der->extensionsSz;\n    }\n\n    return idx;\n}\n\n\nstatic int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,\n                   RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key)\n{\n    int ret;\n#ifdef WOLFSSL_SMALL_STACK\n    DerCert* der;\n#else\n    DerCert der[1];\n#endif\n\n    cert->keyType = eccKey ? ECC_KEY : (ed25519Key ? ED25519_KEY : RSA_KEY);\n\n#ifdef WOLFSSL_SMALL_STACK\n    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap,\n                                                    DYNAMIC_TYPE_TMP_BUFFER);\n    if (der == NULL)\n        return MEMORY_E;\n#endif\n\n    ret = EncodeCertReq(cert, der, rsaKey, eccKey, ed25519Key);\n\n    if (ret == 0) {\n        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)\n            ret = BUFFER_E;\n        else\n            ret = cert->bodySz = WriteCertReqBody(der, derBuffer);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\nint wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,\n                      void* key)\n{\n    RsaKey* rsaKey = NULL;\n    ecc_key* eccKey = NULL;\n    ed25519_key* ed25519Key = NULL;\n\n    if (keyType == RSA_TYPE)\n        rsaKey = (RsaKey*)key;\n    else if (keyType == ECC_TYPE)\n        eccKey = (ecc_key*)key;\n    else if (keyType == ED25519_TYPE)\n        ed25519Key = (ed25519_key*)key;\n\n    return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, ed25519Key);\n}\n\nint wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,\n                   RsaKey* rsaKey, ecc_key* eccKey)\n{\n    return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, NULL);\n}\n#endif /* WOLFSSL_CERT_REQ */\n\n\nstatic int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz,\n                    RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key,\n                    WC_RNG* rng)\n{\n    int sigSz = 0;\n    void* heap = NULL;\n    CertSignCtx* certSignCtx = NULL;\n#ifndef WOLFSSL_ASYNC_CRYPT\n    CertSignCtx  certSignCtx_lcl;\n    certSignCtx = &certSignCtx_lcl;\n    XMEMSET(certSignCtx, 0, sizeof(CertSignCtx));\n#endif\n\n    if (requestSz < 0)\n        return requestSz;\n\n    /* locate ctx */\n    if (rsaKey) {\n    #ifndef NO_RSA\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        certSignCtx = &rsaKey->certSignCtx;\n    #endif\n        heap = rsaKey->heap;\n    #else\n        return NOT_COMPILED_IN;\n    #endif /* NO_RSA */\n    }\n    else if (eccKey) {\n    #ifdef HAVE_ECC\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        certSignCtx = &eccKey->certSignCtx;\n    #endif\n        heap = eccKey->heap;\n    #else\n        return NOT_COMPILED_IN;\n    #endif /* HAVE_ECC */\n    }\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    if (certSignCtx == NULL) {\n        return BAD_FUNC_ARG;\n    }\n#endif\n\n    if (certSignCtx->sig == NULL) {\n        certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, heap,\n            DYNAMIC_TYPE_TMP_BUFFER);\n        if (certSignCtx->sig == NULL)\n            return MEMORY_E;\n    }\n\n    sigSz = MakeSignature(certSignCtx, buffer, requestSz, certSignCtx->sig,\n        MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, rng, sType, heap);\n#ifdef WOLFSSL_ASYNC_CRYPT\n    if (sigSz == WC_PENDING_E) {\n        /* Not free'ing certSignCtx->sig here because it could still be in use\n         * with async operations. */\n        return sigSz;\n    }\n#endif\n\n    if (sigSz >= 0) {\n        if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)\n            sigSz = BUFFER_E;\n        else\n            sigSz = AddSignature(buffer, requestSz, certSignCtx->sig, sigSz,\n                                 sType);\n    }\n\n    XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    certSignCtx->sig = NULL;\n\n    return sigSz;\n}\n\nint wc_SignCert_ex(int requestSz, int sType, byte* buffer, word32 buffSz,\n                   int keyType, void* key, WC_RNG* rng)\n{\n    RsaKey* rsaKey = NULL;\n    ecc_key* eccKey = NULL;\n    ed25519_key* ed25519Key = NULL;\n\n    if (keyType == RSA_TYPE)\n        rsaKey = (RsaKey*)key;\n    else if (keyType == ECC_TYPE)\n        eccKey = (ecc_key*)key;\n    else if (keyType == ED25519_TYPE)\n        ed25519Key = (ed25519_key*)key;\n\n    return SignCert(requestSz, sType, buffer, buffSz, rsaKey, eccKey,\n                    ed25519Key, rng);\n}\n\nint wc_SignCert(int requestSz, int sType, byte* buffer, word32 buffSz,\n                RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)\n{\n    return SignCert(requestSz, sType, buffer, buffSz, rsaKey, eccKey, NULL,\n                    rng);\n}\n\nint wc_MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz,\n                    RsaKey* key, WC_RNG* rng)\n{\n    int ret;\n\n    ret = wc_MakeCert(cert, buffer, buffSz, key, NULL, rng);\n    if (ret < 0)\n        return ret;\n\n    return wc_SignCert(cert->bodySz, cert->sigType,\n                       buffer, buffSz, key, NULL, rng);\n}\n\n\n#ifdef WOLFSSL_CERT_EXT\n\n/* Get raw subject from cert, which may contain OIDs not parsed by Decode.\n   The raw subject pointer will only be valid while \"cert\" is valid. */\nint wc_GetSubjectRaw(byte **subjectRaw, Cert *cert)\n{\n    int rc = BAD_FUNC_ARG;\n    if ((subjectRaw != NULL) && (cert != NULL)) {\n        *subjectRaw = cert->sbjRaw;\n        rc = 0;\n    }\n    return rc;\n}\n\n/* Set KID from public key */\nstatic int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,\n                                 byte *ntruKey, word16 ntruKeySz,\n                                 ed25519_key* ed25519Key, int kid_type)\n{\n    byte *buffer;\n    int   bufferSz, ret;\n\n    if (cert == NULL ||\n        (rsakey == NULL && eckey == NULL && ntruKey == NULL &&\n                                            ed25519Key == NULL) ||\n        (kid_type != SKID_TYPE && kid_type != AKID_TYPE))\n        return BAD_FUNC_ARG;\n\n    buffer = (byte *)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (buffer == NULL)\n        return MEMORY_E;\n\n    /* Public Key */\n    bufferSz = -1;\n#ifndef NO_RSA\n    /* RSA public key */\n    if (rsakey != NULL)\n        bufferSz = SetRsaPublicKey(buffer, rsakey, MAX_PUBLIC_KEY_SZ, 0);\n#endif\n#ifdef HAVE_ECC\n    /* ECC public key */\n    if (eckey != NULL)\n        bufferSz = SetEccPublicKey(buffer, eckey, 0);\n#endif\n#ifdef HAVE_NTRU\n    /* NTRU public key */\n    if (ntruKey != NULL) {\n        bufferSz = MAX_PUBLIC_KEY_SZ;\n        ret = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(\n                        ntruKeySz, ntruKey, (word16 *)(&bufferSz), buffer);\n        if (ret != NTRU_OK)\n            bufferSz = -1;\n    }\n#else\n    (void)ntruKeySz;\n#endif\n#ifdef HAVE_ED25519\n    /* ED25519 public key */\n    if (ed25519Key != NULL)\n        bufferSz = SetEd25519PublicKey(buffer, ed25519Key, 0);\n#endif\n\n    if (bufferSz <= 0) {\n        XFREE(buffer, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return PUBLIC_KEY_E;\n    }\n\n    /* Compute SKID by hashing public key */\n    if (kid_type == SKID_TYPE) {\n        ret = CalcHashId(buffer, bufferSz, cert->skid);\n        cert->skidSz = KEYID_SIZE;\n    }\n    else if (kid_type == AKID_TYPE) {\n        ret = CalcHashId(buffer, bufferSz, cert->akid);\n        cert->akidSz = KEYID_SIZE;\n    }\n    else\n        ret = BAD_FUNC_ARG;\n\n    XFREE(buffer, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    return ret;\n}\n\nint wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)\n{\n    RsaKey* rsaKey = NULL;\n    ecc_key* eccKey = NULL;\n    ed25519_key* ed25519Key = NULL;\n\n    if (keyType == RSA_TYPE)\n        rsaKey = (RsaKey*)key;\n    else if (keyType == ECC_TYPE)\n        eccKey = (ecc_key*)key;\n    else if (keyType == ED25519_TYPE)\n        ed25519Key = (ed25519_key*)key;\n\n    return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, NULL, 0, ed25519Key,\n                                 SKID_TYPE);\n}\n\n/* Set SKID from RSA or ECC public key */\nint wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)\n{\n    return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, NULL, SKID_TYPE);\n}\n\n#ifdef HAVE_NTRU\n/* Set SKID from NTRU public key */\nint wc_SetSubjectKeyIdFromNtruPublicKey(Cert *cert,\n                                        byte *ntruKey, word16 ntruKeySz)\n{\n    return SetKeyIdFromPublicKey(cert, NULL,NULL,ntruKey, ntruKeySz, NULL,\n                                 SKID_TYPE);\n}\n#endif\n\nint wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)\n{\n    RsaKey* rsaKey = NULL;\n    ecc_key* eccKey = NULL;\n    ed25519_key* ed25519Key = NULL;\n\n    if (keyType == RSA_TYPE)\n        rsaKey = (RsaKey*)key;\n    else if (keyType == ECC_TYPE)\n        eccKey = (ecc_key*)key;\n    else if (keyType == ED25519_TYPE)\n        ed25519Key = (ed25519_key*)key;\n\n    return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, NULL, 0, ed25519Key,\n                                 AKID_TYPE);\n}\n\n/* Set SKID from RSA or ECC public key */\nint wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)\n{\n    return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, NULL, AKID_TYPE);\n}\n\n\n#if !defined(NO_FILESYSTEM) && !defined(NO_ASN_CRYPT)\n\n/* Set SKID from public key file in PEM */\nint wc_SetSubjectKeyId(Cert *cert, const char* file)\n{\n    int     ret, derSz;\n    byte*   der;\n    word32  idx;\n    RsaKey  *rsakey = NULL;\n    ecc_key *eckey = NULL;\n\n    if (cert == NULL || file == NULL)\n        return BAD_FUNC_ARG;\n\n    der = (byte*)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap, DYNAMIC_TYPE_CERT);\n    if (der == NULL) {\n        WOLFSSL_MSG(\"wc_SetSubjectKeyId memory Problem\");\n        return MEMORY_E;\n    }\n    derSz = MAX_PUBLIC_KEY_SZ;\n\n    XMEMSET(der, 0, derSz);\n    derSz = wc_PemPubKeyToDer(file, der, derSz);\n    if (derSz <= 0) {\n        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);\n        return derSz;\n    }\n\n    /* Load PubKey in internal structure */\n#ifndef NO_RSA\n    rsakey = (RsaKey*) XMALLOC(sizeof(RsaKey), cert->heap, DYNAMIC_TYPE_RSA);\n    if (rsakey == NULL) {\n        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);\n        return MEMORY_E;\n    }\n\n    if (wc_InitRsaKey(rsakey, cert->heap) != 0) {\n        WOLFSSL_MSG(\"wc_InitRsaKey failure\");\n        XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);\n        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);\n        return MEMORY_E;\n    }\n\n    idx = 0;\n    ret = wc_RsaPublicKeyDecode(der, &idx, rsakey, derSz);\n    if (ret != 0)\n#endif\n    {\n#ifndef NO_RSA\n        WOLFSSL_MSG(\"wc_RsaPublicKeyDecode failed\");\n        wc_FreeRsaKey(rsakey);\n        XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);\n        rsakey = NULL;\n#endif\n#ifdef HAVE_ECC\n        /* Check to load ecc public key */\n        eckey = (ecc_key*) XMALLOC(sizeof(ecc_key), cert->heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (eckey == NULL) {\n            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);\n            return MEMORY_E;\n        }\n\n        if (wc_ecc_init(eckey) != 0) {\n            WOLFSSL_MSG(\"wc_ecc_init failure\");\n            wc_ecc_free(eckey);\n            XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);\n            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);\n            return MEMORY_E;\n        }\n\n        idx = 0;\n        ret = wc_EccPublicKeyDecode(der, &idx, eckey, derSz);\n        if (ret != 0) {\n            WOLFSSL_MSG(\"wc_EccPublicKeyDecode failed\");\n            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);\n            wc_ecc_free(eckey);\n            XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);\n            return PUBLIC_KEY_E;\n        }\n#else\n        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);\n        return PUBLIC_KEY_E;\n#endif /* HAVE_ECC */\n    }\n\n    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);\n\n    ret = wc_SetSubjectKeyIdFromPublicKey(cert, rsakey, eckey);\n\n#ifndef NO_RSA\n    wc_FreeRsaKey(rsakey);\n    XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);\n#endif\n#ifdef HAVE_ECC\n    wc_ecc_free(eckey);\n    XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);\n#endif\n    return ret;\n}\n\n#endif /* !NO_FILESYSTEM && !NO_ASN_CRYPT */\n\nstatic int SetAuthKeyIdFromDcert(Cert* cert, DecodedCert* decoded)\n{\n    int ret = 0;\n\n    /* Subject Key Id not found !! */\n    if (decoded->extSubjKeyIdSet == 0) {\n        ret = ASN_NO_SKID;\n    }\n\n    /* SKID invalid size */\n    else if (sizeof(cert->akid) < sizeof(decoded->extSubjKeyId)) {\n        ret = MEMORY_E;\n    }\n\n    else {\n        /* Put the SKID of CA to AKID of certificate */\n        XMEMCPY(cert->akid, decoded->extSubjKeyId, KEYID_SIZE);\n        cert->akidSz = KEYID_SIZE;\n    }\n\n    return ret;\n}\n\n/* Set AKID from certificate contains in buffer (DER encoded) */\nint wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz)\n{\n    int ret = 0;\n\n    if (cert == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n    else {\n        /* Check if decodedCert is cached */\n        if (cert->der != der) {\n            /* Allocate cache for the decoded cert */\n            ret = wc_SetCert_LoadDer(cert, der, derSz);\n        }\n\n        if (ret >= 0) {\n            ret = SetAuthKeyIdFromDcert(cert, (DecodedCert*)cert->decodedCert);\n#ifndef WOLFSSL_CERT_GEN_CACHE\n            wc_SetCert_Free(cert);\n#endif\n        }\n    }\n\n    return ret;\n}\n\n\n#ifndef NO_FILESYSTEM\n\n/* Set AKID from certificate file in PEM */\nint wc_SetAuthKeyId(Cert *cert, const char* file)\n{\n    int         ret;\n    int         derSz;\n    byte*       der;\n\n    if (cert == NULL || file == NULL)\n        return BAD_FUNC_ARG;\n\n    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);\n    if (der == NULL) {\n        WOLFSSL_MSG(\"wc_SetAuthKeyId OOF Problem\");\n        return MEMORY_E;\n    }\n\n    derSz = wc_PemCertToDer(file, der, EIGHTK_BUF);\n    if (derSz <= 0)\n    {\n        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);\n        return derSz;\n    }\n\n    ret = wc_SetAuthKeyIdFromCert(cert, der, derSz);\n    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);\n\n    return ret;\n}\n\n#endif /* !NO_FILESYSTEM */\n\n/* Set KeyUsage from human readable string */\nint wc_SetKeyUsage(Cert *cert, const char *value)\n{\n    int ret = 0;\n    char *token, *str, *ptr;\n    word32 len;\n\n    if (cert == NULL || value == NULL)\n        return BAD_FUNC_ARG;\n\n    cert->keyUsage = 0;\n\n    /* duplicate string (including terminator) */\n    len = (word32)XSTRLEN(value);\n    str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (str == NULL)\n        return MEMORY_E;\n    XMEMCPY(str, value, len+1);\n\n    /* parse value, and set corresponding Key Usage value */\n    if ((token = XSTRTOK(str, \",\", &ptr)) == NULL) {\n        XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return KEYUSAGE_E;\n    }\n    while (token != NULL)\n    {\n        len = (word32)XSTRLEN(token);\n\n        if (!XSTRNCASECMP(token, \"digitalSignature\", len))\n            cert->keyUsage |= KEYUSE_DIGITAL_SIG;\n        else if (!XSTRNCASECMP(token, \"nonRepudiation\", len) ||\n                 !XSTRNCASECMP(token, \"contentCommitment\", len))\n            cert->keyUsage |= KEYUSE_CONTENT_COMMIT;\n        else if (!XSTRNCASECMP(token, \"keyEncipherment\", len))\n            cert->keyUsage |= KEYUSE_KEY_ENCIPHER;\n        else if (!XSTRNCASECMP(token, \"dataEncipherment\", len))\n            cert->keyUsage |= KEYUSE_DATA_ENCIPHER;\n        else if (!XSTRNCASECMP(token, \"keyAgreement\", len))\n            cert->keyUsage |= KEYUSE_KEY_AGREE;\n        else if (!XSTRNCASECMP(token, \"keyCertSign\", len))\n            cert->keyUsage |= KEYUSE_KEY_CERT_SIGN;\n        else if (!XSTRNCASECMP(token, \"cRLSign\", len))\n            cert->keyUsage |= KEYUSE_CRL_SIGN;\n        else if (!XSTRNCASECMP(token, \"encipherOnly\", len))\n            cert->keyUsage |= KEYUSE_ENCIPHER_ONLY;\n        else if (!XSTRNCASECMP(token, \"decipherOnly\", len))\n            cert->keyUsage |= KEYUSE_DECIPHER_ONLY;\n        else {\n            ret = KEYUSAGE_E;\n            break;\n        }\n\n        token = XSTRTOK(NULL, \",\", &ptr);\n    }\n\n    XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    return ret;\n}\n\n/* Set ExtendedKeyUsage from human readable string */\nint wc_SetExtKeyUsage(Cert *cert, const char *value)\n{\n    int ret = 0;\n    char *token, *str, *ptr;\n    word32 len;\n\n    if (cert == NULL || value == NULL)\n        return BAD_FUNC_ARG;\n\n    cert->extKeyUsage = 0;\n\n    /* duplicate string (including terminator) */\n    len = (word32)XSTRLEN(value);\n    str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (str == NULL)\n        return MEMORY_E;\n    XMEMCPY(str, value, len+1);\n\n    /* parse value, and set corresponding Key Usage value */\n    if ((token = XSTRTOK(str, \",\", &ptr)) == NULL) {\n        XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return EXTKEYUSAGE_E;\n    }\n\n    while (token != NULL)\n    {\n        len = (word32)XSTRLEN(token);\n\n        if (!XSTRNCASECMP(token, \"any\", len))\n            cert->extKeyUsage |= EXTKEYUSE_ANY;\n        else if (!XSTRNCASECMP(token, \"serverAuth\", len))\n            cert->extKeyUsage |= EXTKEYUSE_SERVER_AUTH;\n        else if (!XSTRNCASECMP(token, \"clientAuth\", len))\n            cert->extKeyUsage |= EXTKEYUSE_CLIENT_AUTH;\n        else if (!XSTRNCASECMP(token, \"codeSigning\", len))\n            cert->extKeyUsage |= EXTKEYUSE_CODESIGN;\n        else if (!XSTRNCASECMP(token, \"emailProtection\", len))\n            cert->extKeyUsage |= EXTKEYUSE_EMAILPROT;\n        else if (!XSTRNCASECMP(token, \"timeStamping\", len))\n            cert->extKeyUsage |= EXTKEYUSE_TIMESTAMP;\n        else if (!XSTRNCASECMP(token, \"OCSPSigning\", len))\n            cert->extKeyUsage |= EXTKEYUSE_OCSP_SIGN;\n        else {\n            ret = EXTKEYUSAGE_E;\n            break;\n        }\n\n        token = XSTRTOK(NULL, \",\", &ptr);\n    }\n\n    XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    return ret;\n}\n\n#ifdef WOLFSSL_EKU_OID\n/*\n * cert structure to set EKU oid in\n * oid  the oid in byte representation\n * sz   size of oid buffer\n * idx  index of array to place oid\n *\n * returns 0 on success\n */\nint wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,\n        void* heap)\n{\n    byte oid[MAX_OID_SZ];\n    word32 oidSz = MAX_OID_SZ;\n\n    if (idx >= CTC_MAX_EKU_NB || sz >= CTC_MAX_EKU_OID_SZ) {\n        WOLFSSL_MSG(\"Either idx or sz was too large\");\n        return BAD_FUNC_ARG;\n    }\n\n    if (EncodePolicyOID(oid, &oidSz, in, heap) != 0) {\n        return BUFFER_E;\n    }\n\n    XMEMCPY(cert->extKeyUsageOID[idx], oid, oidSz);\n    cert->extKeyUsageOIDSz[idx] = oidSz;\n    cert->extKeyUsage |= EXTKEYUSE_USER;\n\n    return 0;\n}\n#endif /* WOLFSSL_EKU_OID */\n#endif /* WOLFSSL_CERT_EXT */\n\n\n#ifdef WOLFSSL_ALT_NAMES\n\nstatic int SetAltNamesFromDcert(Cert* cert, DecodedCert* decoded)\n{\n    int ret = 0;\n    byte tag;\n\n    if (decoded->extensions) {\n        int    length;\n        word32 maxExtensionsIdx;\n\n        decoded->srcIdx = decoded->extensionsIdx;\n        if (GetASNTag(decoded->source, &decoded->srcIdx, &tag, decoded->maxIdx)\n                != 0) {\n            return ASN_PARSE_E;\n        }\n\n        if (tag != ASN_EXTENSIONS) {\n            ret = ASN_PARSE_E;\n        }\n        else if (GetLength(decoded->source, &decoded->srcIdx, &length,\n                                                         decoded->maxIdx) < 0) {\n            ret = ASN_PARSE_E;\n        }\n        else if (GetSequence(decoded->source, &decoded->srcIdx, &length,\n                                                         decoded->maxIdx) < 0) {\n            ret = ASN_PARSE_E;\n        }\n        else {\n            maxExtensionsIdx = decoded->srcIdx + length;\n\n            while (decoded->srcIdx < maxExtensionsIdx) {\n                word32 oid;\n                word32 startIdx = decoded->srcIdx;\n                word32 tmpIdx;\n\n                if (GetSequence(decoded->source, &decoded->srcIdx, &length,\n                            decoded->maxIdx) < 0) {\n                    ret = ASN_PARSE_E;\n                    break;\n                }\n\n                tmpIdx = decoded->srcIdx;\n                decoded->srcIdx = startIdx;\n\n                if (GetAlgoId(decoded->source, &decoded->srcIdx, &oid,\n                              oidCertExtType, decoded->maxIdx) < 0) {\n                    ret = ASN_PARSE_E;\n                    break;\n                }\n\n                if (oid == ALT_NAMES_OID) {\n                    cert->altNamesSz = length + (tmpIdx - startIdx);\n\n                    if (cert->altNamesSz < (int)sizeof(cert->altNames))\n                        XMEMCPY(cert->altNames, &decoded->source[startIdx],\n                                cert->altNamesSz);\n                    else {\n                        cert->altNamesSz = 0;\n                        WOLFSSL_MSG(\"AltNames extensions too big\");\n                        ret = ALT_NAME_E;\n                        break;\n                    }\n                }\n                decoded->srcIdx = tmpIdx + length;\n            }\n        }\n    }\n\n    return ret;\n}\n\n#ifndef NO_FILESYSTEM\n\n/* Set Alt Names from der cert, return 0 on success */\nstatic int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)\n{\n    int ret;\n#ifdef WOLFSSL_SMALL_STACK\n    DecodedCert* decoded;\n#else\n    DecodedCert decoded[1];\n#endif\n\n    if (derSz < 0)\n        return derSz;\n\n#ifdef WOLFSSL_SMALL_STACK\n    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (decoded == NULL)\n        return MEMORY_E;\n#endif\n\n    InitDecodedCert(decoded, der, derSz, NULL);\n    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);\n\n    if (ret < 0) {\n        WOLFSSL_MSG(\"ParseCertRelative error\");\n    }\n    else {\n        ret = SetAltNamesFromDcert(cert, decoded);\n    }\n\n    FreeDecodedCert(decoded);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret < 0 ? ret : 0;\n}\n\n#endif\n\nstatic int SetDatesFromDcert(Cert* cert, DecodedCert* decoded)\n{\n    int ret = 0;\n\n    if (decoded->beforeDate == NULL || decoded->afterDate == NULL) {\n        WOLFSSL_MSG(\"Couldn't extract dates\");\n        ret = -1;\n    }\n    else if (decoded->beforeDateLen > MAX_DATE_SIZE ||\n                                        decoded->afterDateLen > MAX_DATE_SIZE) {\n        WOLFSSL_MSG(\"Bad date size\");\n        ret = -1;\n    }\n    else {\n        XMEMCPY(cert->beforeDate, decoded->beforeDate, decoded->beforeDateLen);\n        XMEMCPY(cert->afterDate,  decoded->afterDate,  decoded->afterDateLen);\n\n        cert->beforeDateSz = decoded->beforeDateLen;\n        cert->afterDateSz  = decoded->afterDateLen;\n    }\n\n    return ret;\n}\n\n#endif /* WOLFSSL_ALT_NAMES */\n\nstatic void SetNameFromDcert(CertName* cn, DecodedCert* decoded)\n{\n    int sz;\n\n    if (decoded->subjectCN) {\n        sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen\n                                                     : CTC_NAME_SIZE - 1;\n        XSTRNCPY(cn->commonName, decoded->subjectCN, sz);\n        cn->commonName[sz] = '\\0';\n        cn->commonNameEnc = decoded->subjectCNEnc;\n    }\n    if (decoded->subjectC) {\n        sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen\n                                                    : CTC_NAME_SIZE - 1;\n        XSTRNCPY(cn->country, decoded->subjectC, sz);\n        cn->country[sz] = '\\0';\n        cn->countryEnc = decoded->subjectCEnc;\n    }\n    if (decoded->subjectST) {\n        sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen\n                                                     : CTC_NAME_SIZE - 1;\n        XSTRNCPY(cn->state, decoded->subjectST, sz);\n        cn->state[sz] = '\\0';\n        cn->stateEnc = decoded->subjectSTEnc;\n    }\n    if (decoded->subjectL) {\n        sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen\n                                                    : CTC_NAME_SIZE - 1;\n        XSTRNCPY(cn->locality, decoded->subjectL, sz);\n        cn->locality[sz] = '\\0';\n        cn->localityEnc = decoded->subjectLEnc;\n    }\n    if (decoded->subjectO) {\n        sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen\n                                                    : CTC_NAME_SIZE - 1;\n        XSTRNCPY(cn->org, decoded->subjectO, sz);\n        cn->org[sz] = '\\0';\n        cn->orgEnc = decoded->subjectOEnc;\n    }\n    if (decoded->subjectOU) {\n        sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen\n                                                     : CTC_NAME_SIZE - 1;\n        XSTRNCPY(cn->unit, decoded->subjectOU, sz);\n        cn->unit[sz] = '\\0';\n        cn->unitEnc = decoded->subjectOUEnc;\n    }\n    if (decoded->subjectSN) {\n        sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen\n                                                     : CTC_NAME_SIZE - 1;\n        XSTRNCPY(cn->sur, decoded->subjectSN, sz);\n        cn->sur[sz] = '\\0';\n        cn->surEnc = decoded->subjectSNEnc;\n    }\n    if (decoded->subjectSND) {\n        sz = (decoded->subjectSNDLen < CTC_NAME_SIZE) ? decoded->subjectSNDLen\n                                                     : CTC_NAME_SIZE - 1;\n        XSTRNCPY(cn->serialDev, decoded->subjectSND, sz);\n        cn->serialDev[sz] = '\\0';\n        cn->serialDevEnc = decoded->subjectSNDEnc;\n    }\n#ifdef WOLFSSL_CERT_EXT\n    if (decoded->subjectBC) {\n        sz = (decoded->subjectBCLen < CTC_NAME_SIZE) ? decoded->subjectBCLen\n                                                     : CTC_NAME_SIZE - 1;\n        XSTRNCPY(cn->busCat, decoded->subjectBC, sz);\n        cn->busCat[sz] = '\\0';\n        cn->busCatEnc = decoded->subjectBCEnc;\n    }\n    if (decoded->subjectJC) {\n        sz = (decoded->subjectJCLen < CTC_NAME_SIZE) ? decoded->subjectJCLen\n                                                     : CTC_NAME_SIZE - 1;\n        XSTRNCPY(cn->joiC, decoded->subjectJC, sz);\n        cn->joiC[sz] = '\\0';\n        cn->joiCEnc = decoded->subjectJCEnc;\n    }\n    if (decoded->subjectJS) {\n        sz = (decoded->subjectJSLen < CTC_NAME_SIZE) ? decoded->subjectJSLen\n                                                     : CTC_NAME_SIZE - 1;\n        XSTRNCPY(cn->joiSt, decoded->subjectJS, sz);\n        cn->joiSt[sz] = '\\0';\n        cn->joiStEnc = decoded->subjectJSEnc;\n    }\n#endif\n    if (decoded->subjectEmail) {\n        sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)\n           ?  decoded->subjectEmailLen : CTC_NAME_SIZE - 1;\n        XSTRNCPY(cn->email, decoded->subjectEmail, sz);\n        cn->email[sz] = '\\0';\n    }\n}\n\n#ifndef NO_FILESYSTEM\n\n/* Set cn name from der buffer, return 0 on success */\nstatic int SetNameFromCert(CertName* cn, const byte* der, int derSz)\n{\n    int ret;\n#ifdef WOLFSSL_SMALL_STACK\n    DecodedCert* decoded;\n#else\n    DecodedCert decoded[1];\n#endif\n\n    if (derSz < 0)\n        return derSz;\n\n#ifdef WOLFSSL_SMALL_STACK\n    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (decoded == NULL)\n        return MEMORY_E;\n#endif\n\n    InitDecodedCert(decoded, der, derSz, NULL);\n    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);\n\n    if (ret < 0) {\n        WOLFSSL_MSG(\"ParseCertRelative error\");\n    }\n    else {\n        SetNameFromDcert(cn, decoded);\n    }\n\n    FreeDecodedCert(decoded);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret < 0 ? ret : 0;\n}\n\n/* Set cert issuer from issuerFile in PEM */\nint wc_SetIssuer(Cert* cert, const char* issuerFile)\n{\n    int         ret;\n    int         derSz;\n    byte*       der;\n\n    if (cert == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);\n    if (der == NULL) {\n        WOLFSSL_MSG(\"wc_SetIssuer OOF Problem\");\n        return MEMORY_E;\n    }\n    derSz = wc_PemCertToDer(issuerFile, der, EIGHTK_BUF);\n    cert->selfSigned = 0;\n    ret = SetNameFromCert(&cert->issuer, der, derSz);\n    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);\n\n    return ret;\n}\n\n\n/* Set cert subject from subjectFile in PEM */\nint wc_SetSubject(Cert* cert, const char* subjectFile)\n{\n    int         ret;\n    int         derSz;\n    byte*       der;\n\n    if (cert == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);\n    if (der == NULL) {\n        WOLFSSL_MSG(\"wc_SetSubject OOF Problem\");\n        return MEMORY_E;\n    }\n\n    derSz = wc_PemCertToDer(subjectFile, der, EIGHTK_BUF);\n    ret = SetNameFromCert(&cert->subject, der, derSz);\n    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);\n\n    return ret;\n}\n\n#ifdef WOLFSSL_ALT_NAMES\n\n/* Set alt names from file in PEM */\nint wc_SetAltNames(Cert* cert, const char* file)\n{\n    int         ret;\n    int         derSz;\n    byte*       der;\n\n    if (cert == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);\n    if (der == NULL) {\n        WOLFSSL_MSG(\"wc_SetAltNames OOF Problem\");\n        return MEMORY_E;\n    }\n    derSz = wc_PemCertToDer(file, der, EIGHTK_BUF);\n    ret = SetAltNamesFromCert(cert, der, derSz);\n    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);\n\n    return ret;\n}\n\n#endif /* WOLFSSL_ALT_NAMES */\n\n#endif /* !NO_FILESYSTEM */\n\n/* Set cert issuer from DER buffer */\nint wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)\n{\n    int ret = 0;\n\n    if (cert == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n    else {\n        cert->selfSigned = 0;\n\n        /* Check if decodedCert is cached */\n        if (cert->der != der) {\n            /* Allocate cache for the decoded cert */\n            ret = wc_SetCert_LoadDer(cert, der, derSz);\n        }\n\n        if (ret >= 0) {\n            SetNameFromDcert(&cert->issuer, (DecodedCert*)cert->decodedCert);\n#ifndef WOLFSSL_CERT_GEN_CACHE\n            wc_SetCert_Free(cert);\n#endif\n        }\n    }\n\n    return ret;\n}\n\n/* Set cert subject from DER buffer */\nint wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)\n{\n    int ret = 0;\n\n    if (cert == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n    else {\n        /* Check if decodedCert is cached */\n        if (cert->der != der) {\n            /* Allocate cache for the decoded cert */\n            ret = wc_SetCert_LoadDer(cert, der, derSz);\n        }\n\n        if (ret >= 0) {\n            SetNameFromDcert(&cert->subject, (DecodedCert*)cert->decodedCert);\n#ifndef WOLFSSL_CERT_GEN_CACHE\n            wc_SetCert_Free(cert);\n#endif\n        }\n    }\n\n    return ret;\n}\n#ifdef WOLFSSL_CERT_EXT\n/* Set cert raw subject from DER buffer */\nint wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz)\n{\n    int ret = 0;\n\n    if (cert == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n    else {\n        /* Check if decodedCert is cached */\n        if (cert->der != der) {\n            /* Allocate cache for the decoded cert */\n            ret = wc_SetCert_LoadDer(cert, der, derSz);\n        }\n\n        if (ret >= 0) {\n            if ((((DecodedCert*)cert->decodedCert)->subjectRaw) &&\n                (((DecodedCert*)cert->decodedCert)->subjectRawLen <=\n                        (int)sizeof(CertName))) {\n                XMEMCPY(cert->sbjRaw,\n                        ((DecodedCert*)cert->decodedCert)->subjectRaw,\n                        ((DecodedCert*)cert->decodedCert)->subjectRawLen);\n            }\n#ifndef WOLFSSL_CERT_GEN_CACHE\n            wc_SetCert_Free(cert);\n#endif\n        }\n    }\n\n    return ret;\n}\n\n/* Set cert raw issuer from DER buffer */\nint wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz)\n{\n    int ret = 0;\n\n    if (cert == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n    else {\n        /* Check if decodedCert is cached */\n        if (cert->der != der) {\n            /* Allocate cache for the decoded cert */\n            ret = wc_SetCert_LoadDer(cert, der, derSz);\n        }\n\n        if (ret >= 0) {\n            if ((((DecodedCert*)cert->decodedCert)->issuerRaw) &&\n                (((DecodedCert*)cert->decodedCert)->issuerRawLen <=\n                        (int)sizeof(CertName))) {\n                XMEMCPY(cert->issRaw,\n                        ((DecodedCert*)cert->decodedCert)->issuerRaw,\n                        ((DecodedCert*)cert->decodedCert)->issuerRawLen);\n            }\n#ifndef WOLFSSL_CERT_GEN_CACHE\n            wc_SetCert_Free(cert);\n#endif\n        }\n    }\n    return ret;\n}\n#endif\n\n#ifdef WOLFSSL_ALT_NAMES\n\n/* Set cert alt names from DER buffer */\nint wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)\n{\n    int ret = 0;\n\n    if (cert == NULL) {\n     ret = BAD_FUNC_ARG;\n    }\n    else {\n        /* Check if decodedCert is cached */\n        if (cert->der != der) {\n            /* Allocate cache for the decoded cert */\n            ret = wc_SetCert_LoadDer(cert, der, derSz);\n        }\n\n        if (ret >= 0) {\n            ret = SetAltNamesFromDcert(cert, (DecodedCert*)cert->decodedCert);\n#ifndef WOLFSSL_CERT_GEN_CACHE\n            wc_SetCert_Free(cert);\n#endif\n       }\n    }\n\n    return(ret);\n}\n\n/* Set cert dates from DER buffer */\nint wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz)\n{\n    int ret = 0;\n\n    if (cert == NULL) {\n     ret = BAD_FUNC_ARG;\n    }\n    else {\n        /* Check if decodedCert is cached */\n        if (cert->der != der) {\n            /* Allocate cache for the decoded cert */\n            ret = wc_SetCert_LoadDer(cert, der, derSz);\n        }\n\n        if (ret >= 0) {\n            ret = SetDatesFromDcert(cert, (DecodedCert*)cert->decodedCert);\n#ifndef WOLFSSL_CERT_GEN_CACHE\n            wc_SetCert_Free(cert);\n#endif\n        }\n    }\n\n    return(ret);\n}\n\n#endif /* WOLFSSL_ALT_NAMES */\n\n#endif /* WOLFSSL_CERT_GEN */\n\n#if (defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT)) \\\n        || defined(OPENSSL_EXTRA)\n/* Encode OID string representation to ITU-T X.690 format */\nint EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)\n{\n    word32 val, idx = 0, nb_val;\n    char *token, *str, *ptr;\n    word32 len;\n\n    (void)heap;\n\n    if (out == NULL || outSz == NULL || *outSz < 2 || in == NULL)\n        return BAD_FUNC_ARG;\n\n    /* duplicate string (including terminator) */\n    len = (word32)XSTRLEN(in);\n    str = (char *)XMALLOC(len+1, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (str == NULL)\n        return MEMORY_E;\n    XMEMCPY(str, in, len+1);\n\n    nb_val = 0;\n\n    /* parse value, and set corresponding Policy OID value */\n    token = XSTRTOK(str, \".\", &ptr);\n    while (token != NULL)\n    {\n        val = (word32)XATOI(token);\n\n        if (nb_val == 0) {\n            if (val > 2) {\n                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);\n                return ASN_OBJECT_ID_E;\n            }\n\n            out[idx] = (byte)(40 * val);\n        }\n        else if (nb_val == 1) {\n            if (val > 127) {\n                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);\n                return ASN_OBJECT_ID_E;\n            }\n\n            if (idx > *outSz) {\n                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);\n                return BUFFER_E;\n            }\n\n            out[idx++] += (byte)val;\n        }\n        else {\n            word32  tb = 0, x;\n            int     i = 0;\n            byte    oid[MAX_OID_SZ];\n\n            while (val >= 128) {\n                x = val % 128;\n                val /= 128;\n                oid[i++] = (byte) (((tb++) ? 0x80 : 0) | x);\n            }\n\n            if ((idx+(word32)i) > *outSz) {\n                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);\n                return BUFFER_E;\n            }\n\n            oid[i] = (byte) (((tb++) ? 0x80 : 0) | val);\n\n            /* push value in the right order */\n            while (i >= 0)\n                out[idx++] = oid[i--];\n        }\n\n        token = XSTRTOK(NULL, \".\", &ptr);\n        nb_val++;\n    }\n\n    *outSz = idx;\n\n    XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    return 0;\n}\n#endif /* WOLFSSL_CERT_EXT || OPENSSL_EXTRA */\n\n#endif /* !NO_CERTS */\n\n#ifdef HAVE_ECC\n\n/* Der Encode r & s ints into out, outLen is (in/out) size */\nint StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)\n{\n    word32 idx = 0;\n    int    rSz;                           /* encoding size */\n    int    sSz;\n    word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */\n\n    /* If the leading bit on the INTEGER is a 1, add a leading zero */\n    int rLeadingZero = mp_leading_bit(r);\n    int sLeadingZero = mp_leading_bit(s);\n    int rLen = mp_unsigned_bin_size(r);   /* big int size */\n    int sLen = mp_unsigned_bin_size(s);\n\n    if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero +\n                   headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */\n        return BUFFER_E;\n\n    idx = SetSequence(rLen + rLeadingZero + sLen+sLeadingZero + headerSz, out);\n\n    /* store r */\n    rSz = SetASNIntMP(r, -1, &out[idx]);\n    if (rSz < 0)\n        return rSz;\n    idx += rSz;\n\n    /* store s */\n    sSz = SetASNIntMP(s, -1, &out[idx]);\n    if (sSz < 0)\n        return sSz;\n    idx += sSz;\n\n    *outLen = idx;\n\n    return 0;\n}\n\n\n/* Der Decode ECC-DSA Signature, r & s stored as big ints */\nint DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)\n{\n    word32 idx = 0;\n    int    len = 0;\n\n    if (GetSequence(sig, &idx, &len, sigLen) < 0) {\n        return ASN_ECC_KEY_E;\n    }\n\n#ifndef NO_STRICT_ECDSA_LEN\n    /* enable strict length checking for signature */\n    if (sigLen != idx + (word32)len) {\n        return ASN_ECC_KEY_E;\n    }\n#else\n    /* allow extra signature bytes at end */\n    if ((word32)len > (sigLen - idx)) {\n        return ASN_ECC_KEY_E;\n    }\n#endif\n\n    if (GetInt(r, sig, &idx, sigLen) < 0) {\n        return ASN_ECC_KEY_E;\n    }\n\n    if (GetInt(s, sig, &idx, sigLen) < 0) {\n        return ASN_ECC_KEY_E;\n    }\n\n    return 0;\n}\n\n\nint wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,\n                        word32 inSz)\n{\n    word32 oidSum;\n    int    version, length;\n    int    privSz, pubSz = 0;\n    byte   b;\n    int    ret = 0;\n    int    curve_id = ECC_CURVE_DEF;\n#ifdef WOLFSSL_SMALL_STACK\n    byte* priv;\n    byte* pub;\n#else\n    byte priv[ECC_MAXSIZE+1];\n    byte pub[2*(ECC_MAXSIZE+1)]; /* public key has two parts plus header */\n#endif\n    byte* pubData = NULL;\n\n    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)\n        return BAD_FUNC_ARG;\n\n    if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)\n        return ASN_PARSE_E;\n\n    if (*inOutIdx >= inSz)\n        return ASN_PARSE_E;\n\n    b = input[*inOutIdx];\n    *inOutIdx += 1;\n\n    /* priv type */\n    if (b != 4 && b != 6 && b != 7)\n        return ASN_PARSE_E;\n\n    if (GetLength(input, inOutIdx, &length, inSz) < 0)\n        return ASN_PARSE_E;\n\n    if (length > ECC_MAXSIZE)\n        return BUFFER_E;\n\n#ifdef WOLFSSL_SMALL_STACK\n    priv = (byte*)XMALLOC(ECC_MAXSIZE+1, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (priv == NULL)\n        return MEMORY_E;\n\n    pub = (byte*)XMALLOC(2*(ECC_MAXSIZE+1), key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (pub == NULL) {\n        XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n#endif\n\n    /* priv key */\n    privSz = length;\n    XMEMCPY(priv, &input[*inOutIdx], privSz);\n    *inOutIdx += length;\n\n    if (ret == 0 && (*inOutIdx + 1) < inSz) {\n        /* prefix 0, may have */\n        b = input[*inOutIdx];\n        if (b == ECC_PREFIX_0) {\n            *inOutIdx += 1;\n\n            if (GetLength(input, inOutIdx, &length, inSz) <= 0)\n                ret = ASN_PARSE_E;\n            else {\n                ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType,\n                                  inSz);\n                if (ret == 0) {\n                    if ((ret = CheckCurve(oidSum)) < 0)\n                        ret = ECC_CURVE_OID_E;\n                    else {\n                        curve_id = ret;\n                        ret = 0;\n                    }\n                }\n            }\n        }\n    }\n\n    if (ret == 0 && (*inOutIdx + 1) < inSz) {\n        /* prefix 1 */\n        b = input[*inOutIdx];\n        *inOutIdx += 1;\n\n        if (b != ECC_PREFIX_1) {\n            ret = ASN_ECC_KEY_E;\n        }\n        else if (GetLength(input, inOutIdx, &length, inSz) <= 0) {\n            ret = ASN_PARSE_E;\n        }\n        else {\n            /* key header */\n            ret = CheckBitString(input, inOutIdx, &length, inSz, 0, NULL);\n            if (ret == 0) {\n                /* pub key */\n                pubSz = length;\n                if (pubSz < 2*(ECC_MAXSIZE+1)) {\n                    XMEMCPY(pub, &input[*inOutIdx], pubSz);\n                    *inOutIdx += length;\n                    pubData = pub;\n                }\n                else\n                    ret = BUFFER_E;\n            }\n        }\n    }\n\n    if (ret == 0) {\n        ret = wc_ecc_import_private_key_ex(priv, privSz, pubData, pubSz, key,\n                                                                      curve_id);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(pub,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n\n#ifdef WOLFSSL_CUSTOM_CURVES\nstatic void ByteToHex(byte n, char* str)\n{\n    static const char hexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7',\n                                    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };\n\n    str[0] = hexChar[n >> 4];\n    str[1] = hexChar[n & 0xf];\n}\n\n/* returns 0 on success */\nstatic int ASNToHexString(const byte* input, word32* inOutIdx, char** out,\n                          word32 inSz, void* heap, int heapType)\n{\n    int len;\n    int i;\n    char* str;\n    word32 localIdx;\n    byte   tag;\n\n    if (*inOutIdx >= inSz) {\n        return BUFFER_E;\n    }\n\n    localIdx = *inOutIdx;\n    if (GetASNTag(input, &localIdx, &tag, inSz) == 0 && tag == ASN_INTEGER) {\n        if (GetASNInt(input, inOutIdx, &len, inSz) < 0)\n            return ASN_PARSE_E;\n    }\n    else {\n        if (GetOctetString(input, inOutIdx, &len, inSz) < 0)\n            return ASN_PARSE_E;\n    }\n\n    str = (char*)XMALLOC(len * 2 + 1, heap, heapType);\n    for (i=0; i<len; i++)\n        ByteToHex(input[*inOutIdx + i], str + i*2);\n    str[len*2] = '\\0';\n\n    *inOutIdx += len;\n    *out = str;\n\n    (void)heap;\n    (void)heapType;\n\n    return 0;\n}\n#endif /* WOLFSSL_CUSTOM_CURVES */\n\nint wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,\n                          ecc_key* key, word32 inSz)\n{\n    int    length;\n    int    ret;\n    int    curve_id = ECC_CURVE_DEF;\n    word32 oidSum, localIdx;\n    byte   tag;\n\n    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)\n        return BAD_FUNC_ARG;\n\n    if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n        return ASN_PARSE_E;\n\n    ret = SkipObjectId(input, inOutIdx, inSz);\n    if (ret != 0)\n        return ret;\n\n    if (*inOutIdx >= inSz) {\n        return BUFFER_E;\n    }\n\n    localIdx = *inOutIdx;\n    if (GetASNTag(input, &localIdx, &tag, inSz) == 0 &&\n            tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {\n#ifdef WOLFSSL_CUSTOM_CURVES\n        ecc_set_type* curve;\n        int len;\n        char* point = NULL;\n\n        ret = 0;\n\n        curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,\n                                                       DYNAMIC_TYPE_ECC_BUFFER);\n        if (curve == NULL)\n            ret = MEMORY_E;\n\n        if (ret == 0) {\n            static char customName[] = \"Custom\";\n            XMEMSET(curve, 0, sizeof(*curve));\n        #ifndef USE_WINDOWS_API\n            curve->name = customName;\n        #else\n            XMEMCPY((void*)curve->name, customName, sizeof(customName));\n        #endif\n            curve->id = ECC_CURVE_CUSTOM;\n\n            if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n                ret = ASN_PARSE_E;\n        }\n\n        if (ret == 0) {\n            GetInteger7Bit(input, inOutIdx, inSz);\n            if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n                ret = ASN_PARSE_E;\n        }\n        if (ret == 0) {\n            SkipObjectId(input, inOutIdx, inSz);\n            ret = ASNToHexString(input, inOutIdx, (char**)&curve->prime, inSz,\n                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);\n        }\n        if (ret == 0) {\n            curve->size = (int)XSTRLEN(curve->prime) / 2;\n\n            if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n                ret = ASN_PARSE_E;\n        }\n        if (ret == 0) {\n            ret = ASNToHexString(input, inOutIdx, (char**)&curve->Af, inSz,\n                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);\n        }\n        if (ret == 0) {\n            ret = ASNToHexString(input, inOutIdx, (char**)&curve->Bf, inSz,\n                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);\n        }\n        if (ret == 0) {\n            localIdx = *inOutIdx;\n            if (*inOutIdx < inSz && GetASNTag(input, &localIdx, &tag, inSz)\n                    == 0 && tag == ASN_BIT_STRING) {\n                len = 0;\n                ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz);\n                *inOutIdx += len;\n            }\n        }\n        if (ret == 0) {\n            ret = ASNToHexString(input, inOutIdx, (char**)&point, inSz,\n                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);\n\n            /* sanity check that point buffer is not smaller than the expected\n             * size to hold ( 0 4 || Gx || Gy )\n             * where Gx and Gy are each the size of curve->size * 2 */\n            if (ret == 0 && (int)XSTRLEN(point) < (curve->size * 4) + 2) {\n                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);\n                ret = BUFFER_E;\n            }\n        }\n        if (ret == 0) {\n        #ifndef USE_WINDOWS_API\n            curve->Gx = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,\n                                                       DYNAMIC_TYPE_ECC_BUFFER);\n            curve->Gy = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,\n                                                       DYNAMIC_TYPE_ECC_BUFFER);\n            if (curve->Gx == NULL || curve->Gy == NULL) {\n                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);\n                ret = MEMORY_E;\n            }\n        #else\n            if (curve->size * 2 + 2 > MAX_ECC_STRING) {\n                WOLFSSL_MSG(\"curve size is too large to fit in buffer\");\n                ret = BUFFER_E;\n            }\n        #endif\n        }\n        if (ret == 0) {\n            XMEMCPY((char*)curve->Gx, point + 2, curve->size * 2);\n            XMEMCPY((char*)curve->Gy, point + curve->size * 2 + 2,\n                                                               curve->size * 2);\n            ((char*)curve->Gx)[curve->size * 2] = '\\0';\n            ((char*)curve->Gy)[curve->size * 2] = '\\0';\n            XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);\n            ret = ASNToHexString(input, inOutIdx, (char**)&curve->order, inSz,\n                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);\n        }\n        if (ret == 0) {\n            curve->cofactor = GetInteger7Bit(input, inOutIdx, inSz);\n\n        #ifndef USE_WINDOWS_API\n            curve->oid = NULL;\n        #else\n            XMEMSET((void*)curve->oid, 0, sizeof(curve->oid));\n        #endif\n            curve->oidSz = 0;\n            curve->oidSum = 0;\n\n            if (wc_ecc_set_custom_curve(key, curve) < 0) {\n                ret = ASN_PARSE_E;\n            }\n        #ifndef USE_WINDOWS_API\n            key->deallocSet = 1;\n        #endif\n            curve = NULL;\n        }\n        if (curve != NULL)\n            wc_ecc_free_curve(curve, key->heap);\n\n        if (ret < 0)\n            return ret;\n#else\n        return ASN_PARSE_E;\n#endif /* WOLFSSL_CUSTOM_CURVES */\n    }\n    else {\n        /* ecc params information */\n        ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);\n        if (ret != 0)\n            return ret;\n\n        /* get curve id */\n        curve_id = wc_ecc_get_oid(oidSum, NULL, 0);\n        if (curve_id < 0)\n            return ECC_CURVE_OID_E;\n    }\n\n    /* key header */\n    ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);\n    if (ret != 0)\n        return ret;\n\n    /* This is the raw point data compressed or uncompressed. */\n    if (wc_ecc_import_x963_ex(input + *inOutIdx, inSz - *inOutIdx, key,\n                                                            curve_id) != 0) {\n        return ASN_ECC_KEY_E;\n    }\n\n    *inOutIdx += length;\n\n    return 0;\n}\n\n#if defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)\n/* build DER formatted ECC key, include optional public key if requested,\n * return length on success, negative on error */\nstatic int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen,\n                             int pubIn)\n{\n    byte   curve[MAX_ALGO_SZ+2];\n    byte   ver[MAX_VERSION_SZ];\n    byte   seq[MAX_SEQ_SZ];\n    byte   *prv = NULL, *pub = NULL;\n    int    ret, totalSz, curveSz, verSz;\n    int    privHdrSz  = ASN_ECC_HEADER_SZ;\n    int    pubHdrSz   = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;\n\n    word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0;\n    word32 seqSz, privSz, pubSz = ECC_BUFSIZE;\n\n    if (key == NULL || output == NULL || inLen == 0)\n        return BAD_FUNC_ARG;\n\n    /* curve */\n    curve[curveidx++] = ECC_PREFIX_0;\n    curveidx++ /* to put the size after computation */;\n    curveSz = SetCurve(key, curve+curveidx);\n    if (curveSz < 0)\n        return curveSz;\n    /* set computed size */\n    curve[1] = (byte)curveSz;\n    curveidx += curveSz;\n\n    /* private */\n    privSz = key->dp->size;\n    prv = (byte*)XMALLOC(privSz + privHdrSz + MAX_SEQ_SZ,\n                         key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (prv == NULL) {\n        return MEMORY_E;\n    }\n    prvidx += SetOctetString8Bit(key->dp->size, &prv[prvidx]);\n    ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz);\n    if (ret < 0) {\n        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return ret;\n    }\n    prvidx += privSz;\n\n    /* pubIn */\n    if (pubIn) {\n        ret = wc_ecc_export_x963(key, NULL, &pubSz);\n        if (ret != LENGTH_ONLY_E) {\n            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            return ret;\n        }\n\n        pub = (byte*)XMALLOC(pubSz + pubHdrSz + MAX_SEQ_SZ,\n                             key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (pub == NULL) {\n            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            return MEMORY_E;\n        }\n\n        pub[pubidx++] = ECC_PREFIX_1;\n        if (pubSz > 128) /* leading zero + extra size byte */\n            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx);\n        else /* leading zero */\n            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx);\n\n        /* SetBitString adds leading zero */\n        pubidx += SetBitString(pubSz, 0, pub + pubidx);\n        ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz);\n        if (ret != 0) {\n            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            return ret;\n        }\n        pubidx += pubSz;\n    }\n\n    /* make headers */\n    verSz = SetMyVersion(1, ver, FALSE);\n    seqSz = SetSequence(verSz + prvidx + pubidx + curveidx, seq);\n\n    totalSz = prvidx + pubidx + curveidx + verSz + seqSz;\n    if (totalSz > (int)inLen) {\n        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (pubIn) {\n            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        }\n        return BAD_FUNC_ARG;\n    }\n\n    /* write out */\n    /* seq */\n    XMEMCPY(output + idx, seq, seqSz);\n    idx = seqSz;\n\n    /* ver */\n    XMEMCPY(output + idx, ver, verSz);\n    idx += verSz;\n\n    /* private */\n    XMEMCPY(output + idx, prv, prvidx);\n    idx += prvidx;\n    XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    /* curve */\n    XMEMCPY(output + idx, curve, curveidx);\n    idx += curveidx;\n\n    /* pubIn */\n    if (pubIn) {\n        XMEMCPY(output + idx, pub, pubidx);\n        /* idx += pubidx;  not used after write, if more data remove comment */\n        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    return totalSz;\n}\n\n/* Write a Private ecc key, including public to DER format,\n * length on success else < 0 */\nint wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)\n{\n    return wc_BuildEccKeyDer(key, output, inLen, 1);\n}\n\n\n/* Write only private ecc key to DER format,\n * length on success else < 0 */\nint wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)\n{\n    return wc_BuildEccKeyDer(key, output, inLen, 0);\n}\n\n#ifdef HAVE_PKCS8\n/* Write only private ecc key to unencrypted PKCS#8 format.\n *\n * If output is NULL, places required PKCS#8 buffer size in outLen and\n * returns LENGTH_ONLY_E.\n *\n * return length on success else < 0 */\nint wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)\n{\n    int ret, tmpDerSz;\n    int algoID = 0;\n    word32 oidSz = 0;\n    word32 pkcs8Sz = 0;\n    const byte* curveOID = NULL;\n    byte* tmpDer = NULL;\n\n    if (key == NULL || outLen == NULL)\n        return BAD_FUNC_ARG;\n\n    /* set algoID, get curve OID */\n    algoID = ECDSAk;\n    ret = wc_ecc_get_oid(key->dp->oidSum, &curveOID, &oidSz);\n    if (ret < 0)\n        return ret;\n\n    /* temp buffer for plain DER key */\n    tmpDer = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (tmpDer == NULL)\n        return MEMORY_E;\n\n    XMEMSET(tmpDer, 0, ECC_BUFSIZE);\n\n    tmpDerSz = wc_BuildEccKeyDer(key, tmpDer, ECC_BUFSIZE, 0);\n    if (tmpDerSz < 0) {\n        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return tmpDerSz;\n    }\n\n    /* get pkcs8 expected output size */\n    ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID,\n                            curveOID, oidSz);\n    if (ret != LENGTH_ONLY_E) {\n        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return ret;\n    }\n\n    if (output == NULL) {\n        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        *outLen = pkcs8Sz;\n        return LENGTH_ONLY_E;\n\n    } else if (*outLen < pkcs8Sz) {\n        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        WOLFSSL_MSG(\"Input buffer too small for ECC PKCS#8 key\");\n        return BUFFER_E;\n    }\n\n    ret = wc_CreatePKCS8Key(output, &pkcs8Sz, tmpDer, tmpDerSz,\n                            algoID, curveOID, oidSz);\n    if (ret < 0) {\n        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return ret;\n    }\n\n    XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    *outLen = ret;\n    return ret;\n}\n#endif /* HAVE_PKCS8 */\n#endif /* HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */\n#endif /* HAVE_ECC */\n\n\n#ifdef HAVE_ED25519\n\nint wc_Ed25519PrivateKeyDecode(const byte* input, word32* inOutIdx,\n                               ed25519_key* key, word32 inSz)\n{\n    word32      oid;\n    int         ret, version, length, endKeyIdx, privSz, pubSz;\n    const byte* priv;\n    const byte* pub;\n\n    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)\n        return BAD_FUNC_ARG;\n\n    if (GetSequence(input, inOutIdx, &length, inSz) >= 0) {\n        endKeyIdx = *inOutIdx + length;\n\n        if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)\n            return ASN_PARSE_E;\n        if (version != 0) {\n            WOLFSSL_MSG(\"Unrecognized version of ED25519 private key\");\n            return ASN_PARSE_E;\n        }\n\n        if (GetAlgoId(input, inOutIdx, &oid, oidKeyType, inSz) < 0)\n            return ASN_PARSE_E;\n        if (oid != ED25519k)\n            return ASN_PARSE_E;\n\n        if (GetOctetString(input, inOutIdx, &length, inSz) < 0)\n            return ASN_PARSE_E;\n\n        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)\n            return ASN_PARSE_E;\n\n        priv = input + *inOutIdx;\n        *inOutIdx += privSz;\n    }\n    else {\n        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)\n            return ASN_PARSE_E;\n\n        priv = input + *inOutIdx;\n        *inOutIdx += privSz;\n        endKeyIdx = *inOutIdx;\n    }\n\n    if (endKeyIdx == (int)*inOutIdx) {\n        ret = wc_ed25519_import_private_only(priv, privSz, key);\n    }\n    else {\n        if (GetASNHeader(input, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1,\n                         inOutIdx, &length, inSz) < 0) {\n            return ASN_PARSE_E;\n        }\n        if (GetOctetString(input, inOutIdx, &pubSz, inSz) < 0)\n            return ASN_PARSE_E;\n        pub = input + *inOutIdx;\n        *inOutIdx += pubSz;\n\n        ret = wc_ed25519_import_private_key(priv, privSz, pub, pubSz, key);\n    }\n    if (ret == 0 && endKeyIdx != (int)*inOutIdx)\n        return ASN_PARSE_E;\n\n    return ret;\n}\n\n\nint wc_Ed25519PublicKeyDecode(const byte* input, word32* inOutIdx,\n                              ed25519_key* key, word32 inSz)\n{\n    int    length;\n    int    ret;\n\n    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)\n        return BAD_FUNC_ARG;\n\n    if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetSequence(input, inOutIdx, &length, inSz) < 0)\n        return ASN_PARSE_E;\n\n    ret = SkipObjectId(input, inOutIdx, inSz);\n    if (ret != 0)\n        return ret;\n\n    /* key header */\n    ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);\n    if (ret != 0)\n        return ret;\n\n    /* This is the raw point data compressed or uncompressed. */\n    if (wc_ed25519_import_public(input + *inOutIdx, inSz - *inOutIdx, key) != 0)\n        return ASN_ECC_KEY_E;\n\n    return 0;\n}\n\n\n#ifdef WOLFSSL_KEY_GEN\n\n/* build DER formatted ED25519 key,\n * return length on success, negative on error */\nstatic int wc_BuildEd25519KeyDer(ed25519_key* key, byte* output, word32 inLen,\n                                 int pubOut)\n{\n    byte   algoArray[MAX_ALGO_SZ];\n    byte   ver[MAX_VERSION_SZ];\n    byte   seq[MAX_SEQ_SZ];\n    int    ret;\n    word32 idx = 0, seqSz, verSz, algoSz, privSz, pubSz = 0;\n\n    if (key == NULL || output == NULL || inLen == 0)\n        return BAD_FUNC_ARG;\n\n    if (pubOut)\n        pubSz = 2 + 2 + ED25519_PUB_KEY_SIZE;\n    privSz = 2 + 2 + ED25519_KEY_SIZE;\n    algoSz = SetAlgoID(ED25519k, algoArray, oidKeyType, 0);\n    verSz  = SetMyVersion(0, ver, FALSE);\n    seqSz  = SetSequence(verSz + algoSz + privSz + pubSz, seq);\n\n    if (seqSz + verSz + algoSz + privSz + pubSz > inLen)\n        return BAD_FUNC_ARG;\n\n    /* write out */\n    /* seq */\n    XMEMCPY(output + idx, seq, seqSz);\n    idx = seqSz;\n    /* ver */\n    XMEMCPY(output + idx, ver, verSz);\n    idx += verSz;\n    /* algo */\n    XMEMCPY(output + idx, algoArray, algoSz);\n    idx += algoSz;\n    /* privKey */\n    idx += SetOctetString(2 + ED25519_KEY_SIZE, output + idx);\n    idx += SetOctetString(ED25519_KEY_SIZE, output + idx);\n    ret = wc_ed25519_export_private_only(key, output + idx, &privSz);\n    if (ret != 0)\n        return ret;\n    idx += privSz;\n    /* pubKey */\n    if (pubOut) {\n        idx += SetExplicit(1, 2 + ED25519_PUB_KEY_SIZE, output + idx);\n        idx += SetOctetString(ED25519_KEY_SIZE, output + idx);\n        ret = wc_ed25519_export_public(key, output + idx, &pubSz);\n        if (ret != 0)\n            return ret;\n        idx += pubSz;\n    }\n\n    return idx;\n}\n\n/* Write a Private ecc key, including public to DER format,\n * length on success else < 0 */\nint wc_Ed25519KeyToDer(ed25519_key* key, byte* output, word32 inLen)\n{\n    return wc_BuildEd25519KeyDer(key, output, inLen, 1);\n}\n\n\n\n/* Write only private ecc key to DER format,\n * length on success else < 0 */\nint wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen)\n{\n    return wc_BuildEd25519KeyDer(key, output, inLen, 0);\n}\n\n#endif /* WOLFSSL_KEY_GEN */\n\n#endif /* HAVE_ED25519 */\n\n\n#if defined(HAVE_OCSP) || defined(HAVE_CRL)\n\n/* Get raw Date only, no processing, 0 on success */\nstatic int GetBasicDate(const byte* source, word32* idx, byte* date,\n                        byte* format, int maxIdx)\n{\n    int    ret, length;\n    const byte *datePtr = NULL;\n\n    WOLFSSL_ENTER(\"GetBasicDate\");\n\n    ret = GetDateInfo(source, idx, &datePtr, format, &length, maxIdx);\n    if (ret < 0)\n        return ret;\n\n    XMEMCPY(date, datePtr, length);\n\n    return 0;\n}\n\n#endif /* HAVE_OCSP || HAVE_CRL */\n\n\n#ifdef HAVE_OCSP\n\nstatic int GetEnumerated(const byte* input, word32* inOutIdx, int *value,\n        int sz)\n{\n    word32 idx = *inOutIdx;\n    word32 len;\n    byte   tag;\n\n    WOLFSSL_ENTER(\"GetEnumerated\");\n\n    *value = 0;\n\n    if (GetASNTag(input, &idx, &tag, sz) < 0)\n        return ASN_PARSE_E;\n\n    if (tag != ASN_ENUMERATED)\n        return ASN_PARSE_E;\n\n    if ((int)idx >= sz)\n        return BUFFER_E;\n\n    len = input[idx++];\n    if (len > 4 || (int)(len + idx) > sz)\n        return ASN_PARSE_E;\n\n    while (len--) {\n        *value  = *value << 8 | input[idx++];\n    }\n\n    *inOutIdx = idx;\n\n    return *value;\n}\n\n\nstatic int DecodeSingleResponse(byte* source,\n                            word32* ioIndex, OcspResponse* resp, word32 size)\n{\n    word32 idx = *ioIndex, prevIndex, oid, localIdx;\n    int length, wrapperSz;\n    CertStatus* cs = resp->status;\n    int ret;\n    byte tag;\n\n    WOLFSSL_ENTER(\"DecodeSingleResponse\");\n\n    /* Outer wrapper of the SEQUENCE OF Single Responses. */\n    if (GetSequence(source, &idx, &wrapperSz, size) < 0)\n        return ASN_PARSE_E;\n\n    prevIndex = idx;\n\n    /* When making a request, we only request one status on one certificate\n     * at a time. There should only be one SingleResponse */\n\n    /* Wrapper around the Single Response */\n    if (GetSequence(source, &idx, &length, size) < 0)\n        return ASN_PARSE_E;\n\n    /* Wrapper around the CertID */\n    if (GetSequence(source, &idx, &length, size) < 0)\n        return ASN_PARSE_E;\n    /* Skip the hash algorithm */\n    if (GetAlgoId(source, &idx, &oid, oidIgnoreType, size) < 0)\n        return ASN_PARSE_E;\n    /* Save reference to the hash of CN */\n    ret = GetOctetString(source, &idx, &length, size);\n    if (ret < 0)\n        return ret;\n    resp->issuerHash = source + idx;\n    idx += length;\n    /* Save reference to the hash of the issuer public key */\n    ret = GetOctetString(source, &idx, &length, size);\n    if (ret < 0)\n        return ret;\n    resp->issuerKeyHash = source + idx;\n    idx += length;\n\n    /* Get serial number */\n    if (GetSerialNumber(source, &idx, cs->serial, &cs->serialSz, size) < 0)\n        return ASN_PARSE_E;\n\n    if ( idx >= size )\n        return BUFFER_E;\n\n    /* CertStatus */\n    switch (source[idx++])\n    {\n        case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):\n            cs->status = CERT_GOOD;\n            idx++;\n            break;\n        case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):\n            cs->status = CERT_REVOKED;\n            if (GetLength(source, &idx, &length, size) < 0)\n                return ASN_PARSE_E;\n            idx += length;\n            break;\n        case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):\n            cs->status = CERT_UNKNOWN;\n            idx++;\n            break;\n        default:\n            return ASN_PARSE_E;\n    }\n\n#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)\n    cs->thisDateAsn = source + idx;\n    localIdx = 0;\n    if (GetDateInfo(cs->thisDateAsn, &localIdx, NULL,\n                    (byte*)&cs->thisDateParsed.type,\n                    &cs->thisDateParsed.length, size) < 0)\n        return ASN_PARSE_E;\n    XMEMCPY(cs->thisDateParsed.data,\n            cs->thisDateAsn + localIdx - cs->thisDateParsed.length,\n            cs->thisDateParsed.length);\n#endif\n    if (GetBasicDate(source, &idx, cs->thisDate,\n                                                &cs->thisDateFormat, size) < 0)\n        return ASN_PARSE_E;\n\n#ifndef NO_ASN_TIME\n#ifndef WOLFSSL_NO_OCSP_DATE_CHECK\n    if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE))\n        return ASN_BEFORE_DATE_E;\n#endif\n#endif\n\n    /* The following items are optional. Only check for them if there is more\n     * unprocessed data in the singleResponse wrapper. */\n\n    localIdx = idx;\n    if (((int)(idx - prevIndex) < wrapperSz) &&\n        GetASNTag(source, &localIdx, &tag, size) == 0 &&\n        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))\n    {\n        idx++;\n        if (GetLength(source, &idx, &length, size) < 0)\n            return ASN_PARSE_E;\n#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)\n        cs->nextDateAsn = source + idx;\n        localIdx = 0;\n        if (GetDateInfo(cs->nextDateAsn, &localIdx, NULL,\n                        (byte*)&cs->nextDateParsed.type,\n                        &cs->nextDateParsed.length, size) < 0)\n            return ASN_PARSE_E;\n        XMEMCPY(cs->nextDateParsed.data,\n                cs->nextDateAsn + localIdx - cs->nextDateParsed.length,\n                cs->nextDateParsed.length);\n#endif\n        if (GetBasicDate(source, &idx, cs->nextDate,\n                                                &cs->nextDateFormat, size) < 0)\n            return ASN_PARSE_E;\n\n#ifndef NO_ASN_TIME\n#ifndef WOLFSSL_NO_OCSP_DATE_CHECK\n        if (!XVALIDATE_DATE(cs->nextDate, cs->nextDateFormat, AFTER))\n            return ASN_AFTER_DATE_E;\n#endif\n#endif\n    }\n\n    localIdx = idx;\n    if (((int)(idx - prevIndex) < wrapperSz) &&\n        GetASNTag(source, &localIdx, &tag, size) == 0 &&\n        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))\n    {\n        idx++;\n        if (GetLength(source, &idx, &length, size) < 0)\n            return ASN_PARSE_E;\n        idx += length;\n    }\n\n    *ioIndex = idx;\n\n    return 0;\n}\n\nstatic int DecodeOcspRespExtensions(byte* source,\n                            word32* ioIndex, OcspResponse* resp, word32 sz)\n{\n    word32 idx = *ioIndex;\n    int length;\n    int ext_bound; /* boundary index for the sequence of extensions */\n    word32 oid;\n    int ret;\n    byte tag;\n\n    WOLFSSL_ENTER(\"DecodeOcspRespExtensions\");\n\n    if ((idx + 1) > sz)\n        return BUFFER_E;\n\n    if (GetASNTag(source, &idx, &tag, sz) < 0)\n        return ASN_PARSE_E;\n\n    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))\n        return ASN_PARSE_E;\n\n    if (GetLength(source, &idx, &length, sz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetSequence(source, &idx, &length, sz) < 0)\n        return ASN_PARSE_E;\n\n    ext_bound = idx + length;\n\n    while (idx < (word32)ext_bound) {\n        word32 localIdx;\n\n        if (GetSequence(source, &idx, &length, sz) < 0) {\n            WOLFSSL_MSG(\"\\tfail: should be a SEQUENCE\");\n            return ASN_PARSE_E;\n        }\n\n        oid = 0;\n        if (GetObjectId(source, &idx, &oid, oidOcspType, sz) < 0) {\n            WOLFSSL_MSG(\"\\tfail: OBJECT ID\");\n            return ASN_PARSE_E;\n        }\n\n        /* check for critical flag */\n        if ((idx + 1) > (word32)sz) {\n            WOLFSSL_MSG(\"\\tfail: malformed buffer\");\n            return BUFFER_E;\n        }\n\n        localIdx = idx;\n        if (GetASNTag(source, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {\n            WOLFSSL_MSG(\"\\tfound optional critical flag, moving past\");\n            ret = GetBoolean(source, &idx, sz);\n            if (ret < 0)\n                return ret;\n        }\n\n        ret = GetOctetString(source, &idx, &length, sz);\n        if (ret < 0)\n            return ret;\n\n        if (oid == OCSP_NONCE_OID) {\n            /* get data inside extra OCTET_STRING */\n            ret = GetOctetString(source, &idx, &length, sz);\n            if (ret < 0)\n                return ret;\n\n            resp->nonce = source + idx;\n            resp->nonceSz = length;\n        }\n\n        idx += length;\n    }\n\n    *ioIndex = idx;\n    return 0;\n}\n\n\nstatic int DecodeResponseData(byte* source,\n                            word32* ioIndex, OcspResponse* resp, word32 size)\n{\n    word32 idx = *ioIndex, prev_idx, localIdx;\n    int length;\n    int version;\n    int ret;\n    byte tag;\n\n    WOLFSSL_ENTER(\"DecodeResponseData\");\n\n    resp->response = source + idx;\n    prev_idx = idx;\n    if (GetSequence(source, &idx, &length, size) < 0)\n        return ASN_PARSE_E;\n    resp->responseSz = length + idx - prev_idx;\n\n    /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this\n     * item isn't an EXPLICIT[0], then set version to zero and move\n     * onto the next item.\n     */\n    localIdx = idx;\n    if (GetASNTag(source, &localIdx, &tag, size) == 0 &&\n            tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))\n    {\n        idx += 2; /* Eat the value and length */\n        if (GetMyVersion(source, &idx, &version, size) < 0)\n            return ASN_PARSE_E;\n    } else\n        version = 0;\n\n    localIdx = idx;\n    if (GetASNTag(source, &localIdx, &tag, size) == 0 &&\n        ( tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1) ||\n          tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2) ))\n    {\n        idx++; /* advance past ASN tag */\n        if (GetLength(source, &idx, &length, size) < 0)\n            return ASN_PARSE_E;\n        idx += length;\n    }\n    else\n        return ASN_PARSE_E;\n\n    /* save pointer to the producedAt time */\n    if (GetBasicDate(source, &idx, resp->producedDate,\n                                        &resp->producedDateFormat, size) < 0)\n        return ASN_PARSE_E;\n\n    if ((ret = DecodeSingleResponse(source, &idx, resp, size)) < 0)\n        return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */\n\n    /*\n     * Check the length of the ResponseData against the current index to\n     * see if there are extensions, they are optional.\n     */\n    if (idx - prev_idx < resp->responseSz)\n        if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)\n            return ASN_PARSE_E;\n\n    *ioIndex = idx;\n    return 0;\n}\n\n\n#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS\n\nstatic int DecodeCerts(byte* source,\n                            word32* ioIndex, OcspResponse* resp, word32 size)\n{\n    word32 idx = *ioIndex;\n    byte tag;\n\n    WOLFSSL_ENTER(\"DecodeCerts\");\n\n    if (GetASNTag(source, &idx, &tag, size) < 0)\n        return ASN_PARSE_E;\n\n    if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))\n    {\n        int length;\n\n        if (GetLength(source, &idx, &length, size) < 0)\n            return ASN_PARSE_E;\n\n        if (GetSequence(source, &idx, &length, size) < 0)\n            return ASN_PARSE_E;\n\n        resp->cert = source + idx;\n        resp->certSz = length;\n\n        idx += length;\n    }\n    *ioIndex = idx;\n    return 0;\n}\n\n#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */\n\n\nstatic int DecodeBasicOcspResponse(byte* source, word32* ioIndex,\n            OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify)\n{\n    int    length;\n    word32 idx = *ioIndex;\n    word32 end_index;\n    int    ret;\n    int    sigLength;\n\n    WOLFSSL_ENTER(\"DecodeBasicOcspResponse\");\n    (void)heap;\n\n    if (GetSequence(source, &idx, &length, size) < 0)\n        return ASN_PARSE_E;\n\n    if (idx + length > size)\n        return ASN_INPUT_E;\n    end_index = idx + length;\n\n    if ((ret = DecodeResponseData(source, &idx, resp, size)) < 0)\n        return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */\n\n    /* Get the signature algorithm */\n    if (GetAlgoId(source, &idx, &resp->sigOID, oidSigType, size) < 0)\n        return ASN_PARSE_E;\n\n    ret = CheckBitString(source, &idx, &sigLength, size, 1, NULL);\n    if (ret != 0)\n        return ret;\n\n    resp->sigSz = sigLength;\n    resp->sig = source + idx;\n    idx += sigLength;\n\n    /*\n     * Check the length of the BasicOcspResponse against the current index to\n     * see if there are certificates, they are optional.\n     */\n#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS\n    if (idx < end_index)\n    {\n        DecodedCert cert;\n\n        if (DecodeCerts(source, &idx, resp, size) < 0)\n            return ASN_PARSE_E;\n\n        InitDecodedCert(&cert, resp->cert, resp->certSz, heap);\n\n        /* Don't verify if we don't have access to Cert Manager. */\n        ret = ParseCertRelative(&cert, CERT_TYPE,\n                                noVerify ? NO_VERIFY : VERIFY_OCSP, cm);\n        if (ret < 0) {\n            WOLFSSL_MSG(\"\\tOCSP Responder certificate parsing failed\");\n            FreeDecodedCert(&cert);\n            return ret;\n        }\n\n#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK\n        if ((cert.extExtKeyUsage & EXTKEYUSE_OCSP_SIGN) == 0) {\n            if (XMEMCMP(cert.subjectHash,\n                        resp->issuerHash, KEYID_SIZE) == 0) {\n                WOLFSSL_MSG(\"\\tOCSP Response signed by issuer\");\n            }\n            else {\n                WOLFSSL_MSG(\"\\tOCSP Responder key usage check failed\");\n    #ifdef OPENSSL_EXTRA\n                resp->verifyError = OCSP_BAD_ISSUER;\n    #else\n                FreeDecodedCert(&cert);\n                return BAD_OCSP_RESPONDER;\n    #endif\n            }\n        }\n#endif\n\n        /* ConfirmSignature is blocking here */\n        ret = ConfirmSignature(&cert.sigCtx,\n            resp->response, resp->responseSz,\n            cert.publicKey, cert.pubKeySize, cert.keyOID,\n            resp->sig, resp->sigSz, resp->sigOID, NULL);\n\n        FreeDecodedCert(&cert);\n\n        if (ret != 0) {\n            WOLFSSL_MSG(\"\\tOCSP Confirm signature failed\");\n            return ASN_OCSP_CONFIRM_E;\n        }\n    }\n    else\n#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */\n    {\n        Signer* ca = NULL;\n        int sigValid = -1;\n\n        #ifndef NO_SKID\n            ca = GetCA(cm, resp->issuerKeyHash);\n        #else\n            ca = GetCA(cm, resp->issuerHash);\n        #endif\n\n        if (ca) {\n            SignatureCtx sigCtx;\n            InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);\n\n            /* ConfirmSignature is blocking here */\n            sigValid = ConfirmSignature(&sigCtx, resp->response,\n                resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,\n                                resp->sig, resp->sigSz, resp->sigOID, NULL);\n        }\n        if (ca == NULL || sigValid != 0) {\n            WOLFSSL_MSG(\"\\tOCSP Confirm signature failed\");\n            return ASN_OCSP_CONFIRM_E;\n        }\n\n        (void)noVerify;\n    }\n\n    *ioIndex = idx;\n    return 0;\n}\n\n\nvoid InitOcspResponse(OcspResponse* resp, CertStatus* status,\n                                                    byte* source, word32 inSz)\n{\n    WOLFSSL_ENTER(\"InitOcspResponse\");\n\n    XMEMSET(status, 0, sizeof(CertStatus));\n    XMEMSET(resp,   0, sizeof(OcspResponse));\n\n    resp->responseStatus = -1;\n    resp->status         = status;\n    resp->source         = source;\n    resp->maxIdx         = inSz;\n}\n\n\nint OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)\n{\n    int ret;\n    int length = 0;\n    word32 idx = 0;\n    byte* source = resp->source;\n    word32 size = resp->maxIdx;\n    word32 oid;\n    byte   tag;\n\n    WOLFSSL_ENTER(\"OcspResponseDecode\");\n\n    /* peel the outer SEQUENCE wrapper */\n    if (GetSequence(source, &idx, &length, size) < 0)\n        return ASN_PARSE_E;\n\n    /* First get the responseStatus, an ENUMERATED */\n    if (GetEnumerated(source, &idx, &resp->responseStatus, size) < 0)\n        return ASN_PARSE_E;\n\n    if (resp->responseStatus != OCSP_SUCCESSFUL)\n        return 0;\n\n    /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */\n    if (idx >= size)\n        return ASN_INPUT_E;\n    if (GetASNTag(source, &idx, &tag, size) < 0)\n        return ASN_PARSE_E;\n    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))\n        return ASN_PARSE_E;\n    if (GetLength(source, &idx, &length, size) < 0)\n        return ASN_PARSE_E;\n\n    /* Get the responseBytes SEQUENCE */\n    if (GetSequence(source, &idx, &length, size) < 0)\n        return ASN_PARSE_E;\n\n    /* Check ObjectID for the resposeBytes */\n    if (GetObjectId(source, &idx, &oid, oidOcspType, size) < 0)\n        return ASN_PARSE_E;\n    if (oid != OCSP_BASIC_OID)\n        return ASN_PARSE_E;\n    ret = GetOctetString(source, &idx, &length, size);\n    if (ret < 0)\n        return ret;\n\n    ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify);\n    if (ret < 0)\n        return ret;\n\n    return 0;\n}\n\n\nword32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)\n{\n    static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,\n                                       0x30, 0x01, 0x02 };\n    byte seqArray[5][MAX_SEQ_SZ];\n    word32 seqSz[5], totalSz = (word32)sizeof(NonceObjId);\n\n    WOLFSSL_ENTER(\"SetOcspReqExtensions\");\n\n    if (!req || !output || !req->nonceSz)\n        return 0;\n\n    totalSz += req->nonceSz;\n    totalSz += seqSz[0] = SetOctetString(req->nonceSz, seqArray[0]);\n    totalSz += seqSz[1] = SetOctetString(req->nonceSz + seqSz[0], seqArray[1]);\n    totalSz += seqSz[2] = SetObjectId(sizeof(NonceObjId), seqArray[2]);\n    totalSz += seqSz[3] = SetSequence(totalSz, seqArray[3]);\n    totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);\n\n    if (totalSz > size)\n        return 0;\n\n    totalSz = 0;\n\n    XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);\n    totalSz += seqSz[4];\n\n    XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);\n    totalSz += seqSz[3];\n\n    XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);\n    totalSz += seqSz[2];\n\n    XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));\n    totalSz += (word32)sizeof(NonceObjId);\n\n    XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);\n    totalSz += seqSz[1];\n\n    XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);\n    totalSz += seqSz[0];\n\n    XMEMCPY(output + totalSz, req->nonce, req->nonceSz);\n    totalSz += req->nonceSz;\n\n    return totalSz;\n}\n\n\nint EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)\n{\n    byte seqArray[5][MAX_SEQ_SZ];\n    /* The ASN.1 of the OCSP Request is an onion of sequences */\n    byte algoArray[MAX_ALGO_SZ];\n    byte issuerArray[MAX_ENCODED_DIG_SZ];\n    byte issuerKeyArray[MAX_ENCODED_DIG_SZ];\n    byte snArray[MAX_SN_SZ];\n    byte extArray[MAX_OCSP_EXT_SZ];\n    word32 seqSz[5], algoSz, issuerSz, issuerKeySz, extSz, totalSz;\n    int i, snSz;\n\n    WOLFSSL_ENTER(\"EncodeOcspRequest\");\n\n#ifdef NO_SHA\n    algoSz = SetAlgoID(SHA256h, algoArray, oidHashType, 0);\n#else\n    algoSz = SetAlgoID(SHAh, algoArray, oidHashType, 0);\n#endif\n\n    issuerSz    = SetDigest(req->issuerHash,    KEYID_SIZE,    issuerArray);\n    issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE,    issuerKeyArray);\n    snSz        = SetSerialNumber(req->serial,  req->serialSz, snArray,\n                                                          MAX_SN_SZ, MAX_SN_SZ);\n    extSz       = 0;\n\n    if (snSz < 0)\n        return snSz;\n\n    if (req->nonceSz) {\n        /* TLS Extensions use this function too - put extensions after\n         * ASN.1: Context Specific [2].\n         */\n        extSz = EncodeOcspRequestExtensions(req, extArray + 2,\n                                            OCSP_NONCE_EXT_SZ);\n        extSz += SetExplicit(2, extSz, extArray);\n    }\n\n    totalSz = algoSz + issuerSz + issuerKeySz + snSz;\n    for (i = 4; i >= 0; i--) {\n        seqSz[i] = SetSequence(totalSz, seqArray[i]);\n        totalSz += seqSz[i];\n        if (i == 2) totalSz += extSz;\n    }\n\n    if (output == NULL)\n        return totalSz;\n    if (totalSz > size)\n        return BUFFER_E;\n\n    totalSz = 0;\n    for (i = 0; i < 5; i++) {\n        XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);\n        totalSz += seqSz[i];\n    }\n\n    XMEMCPY(output + totalSz, algoArray, algoSz);\n    totalSz += algoSz;\n\n    XMEMCPY(output + totalSz, issuerArray, issuerSz);\n    totalSz += issuerSz;\n\n    XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);\n    totalSz += issuerKeySz;\n\n    XMEMCPY(output + totalSz, snArray, snSz);\n    totalSz += snSz;\n\n    if (extSz != 0) {\n        XMEMCPY(output + totalSz, extArray, extSz);\n        totalSz += extSz;\n    }\n\n    return totalSz;\n}\n\n\nint InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,\n                                                                     void* heap)\n{\n    int ret;\n\n    WOLFSSL_ENTER(\"InitOcspRequest\");\n\n    if (req == NULL)\n        return BAD_FUNC_ARG;\n\n    ForceZero(req, sizeof(OcspRequest));\n    req->heap = heap;\n\n    if (cert) {\n        XMEMCPY(req->issuerHash,    cert->issuerHash,    KEYID_SIZE);\n        XMEMCPY(req->issuerKeyHash, cert->issuerKeyHash, KEYID_SIZE);\n\n        req->serial = (byte*)XMALLOC(cert->serialSz, req->heap,\n                                                     DYNAMIC_TYPE_OCSP_REQUEST);\n        if (req->serial == NULL)\n            return MEMORY_E;\n\n        XMEMCPY(req->serial, cert->serial, cert->serialSz);\n        req->serialSz = cert->serialSz;\n\n        if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {\n            req->url = (byte*)XMALLOC(cert->extAuthInfoSz + 1, req->heap,\n                                                     DYNAMIC_TYPE_OCSP_REQUEST);\n            if (req->url == NULL) {\n                XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP);\n                return MEMORY_E;\n            }\n\n            XMEMCPY(req->url, cert->extAuthInfo, cert->extAuthInfoSz);\n            req->urlSz = cert->extAuthInfoSz;\n            req->url[req->urlSz] = 0;\n        }\n    }\n\n    if (useNonce) {\n        WC_RNG rng;\n\n    #ifndef HAVE_FIPS\n        ret = wc_InitRng_ex(&rng, req->heap, INVALID_DEVID);\n    #else\n        ret = wc_InitRng(&rng);\n    #endif\n        if (ret != 0) {\n            WOLFSSL_MSG(\"\\tCannot initialize RNG. Skipping the OSCP Nonce.\");\n        } else {\n            if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)\n                WOLFSSL_MSG(\"\\tCannot run RNG. Skipping the OSCP Nonce.\");\n            else\n                req->nonceSz = MAX_OCSP_NONCE_SZ;\n\n            wc_FreeRng(&rng);\n        }\n    }\n\n    return 0;\n}\n\nvoid FreeOcspRequest(OcspRequest* req)\n{\n    WOLFSSL_ENTER(\"FreeOcspRequest\");\n\n    if (req) {\n        if (req->serial)\n            XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);\n        req->serial = NULL;\n\n#ifdef OPENSSL_EXTRA\n        if (req->serialInt) {\n            if (req->serialInt->isDynamic) {\n                XFREE(req->serialInt->data, NULL, DYNAMIC_TYPE_OPENSSL);\n            }\n            XFREE(req->serialInt, NULL, DYNAMIC_TYPE_OPENSSL);\n        }\n        req->serialInt = NULL;\n#endif\n\n        if (req->url)\n            XFREE(req->url, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);\n        req->url = NULL;\n    }\n}\n\n\nint CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)\n{\n    int cmp;\n\n    WOLFSSL_ENTER(\"CompareOcspReqResp\");\n\n    if (req == NULL)\n    {\n        WOLFSSL_MSG(\"\\tReq missing\");\n        return -1;\n    }\n\n    if (resp == NULL)\n    {\n        WOLFSSL_MSG(\"\\tResp missing\");\n        return 1;\n    }\n\n    /* Nonces are not critical. The responder may not necessarily add\n     * the nonce to the response. */\n    if (req->nonceSz\n#ifndef WOLFSSL_FORCE_OCSP_NONCE_CHECK\n            && resp->nonceSz != 0\n#endif\n    ) {\n        cmp = req->nonceSz - resp->nonceSz;\n        if (cmp != 0)\n        {\n            WOLFSSL_MSG(\"\\tnonceSz mismatch\");\n            return cmp;\n        }\n\n        cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);\n        if (cmp != 0)\n        {\n            WOLFSSL_MSG(\"\\tnonce mismatch\");\n            return cmp;\n        }\n    }\n\n    cmp = XMEMCMP(req->issuerHash, resp->issuerHash, KEYID_SIZE);\n    if (cmp != 0)\n    {\n        WOLFSSL_MSG(\"\\tissuerHash mismatch\");\n        return cmp;\n    }\n\n    cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, KEYID_SIZE);\n    if (cmp != 0)\n    {\n        WOLFSSL_MSG(\"\\tissuerKeyHash mismatch\");\n        return cmp;\n    }\n\n    cmp = req->serialSz - resp->status->serialSz;\n    if (cmp != 0)\n    {\n        WOLFSSL_MSG(\"\\tserialSz mismatch\");\n        return cmp;\n    }\n\n    cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz);\n    if (cmp != 0)\n    {\n        WOLFSSL_MSG(\"\\tserial mismatch\");\n        return cmp;\n    }\n\n    return 0;\n}\n\n#endif /* HAVE_OCSP */\n\n\n/* store WC_SHA hash of NAME */\nWOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,\n                             int maxIdx)\n{\n    int    length;  /* length of all distinguished names */\n    int    ret;\n    word32 dummy;\n    byte   tag;\n\n    WOLFSSL_ENTER(\"GetNameHash\");\n\n    dummy = *idx;\n    if (GetASNTag(source, &dummy, &tag, maxIdx) == 0 && tag == ASN_OBJECT_ID) {\n        WOLFSSL_MSG(\"Trying optional prefix...\");\n\n        if (GetLength(source, idx, &length, maxIdx) < 0)\n            return ASN_PARSE_E;\n\n        *idx += length;\n        WOLFSSL_MSG(\"Got optional prefix\");\n    }\n\n    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be\n     * calculated over the entire DER encoding of the Name field, including\n     * the tag and length. */\n    dummy = *idx;\n    if (GetSequence(source, idx, &length, maxIdx) < 0)\n        return ASN_PARSE_E;\n\n    ret = CalcHashId(source + dummy, length + *idx - dummy, hash);\n\n    *idx += length;\n\n    return ret;\n}\n\n\n#ifdef HAVE_CRL\n\n/* initialize decoded CRL */\nvoid InitDecodedCRL(DecodedCRL* dcrl, void* heap)\n{\n    WOLFSSL_MSG(\"InitDecodedCRL\");\n\n    XMEMSET(dcrl, 0, sizeof(DecodedCRL));\n    dcrl->heap = heap;\n    #ifdef WOLFSSL_HEAP_TEST\n        dcrl->heap = (void*)WOLFSSL_HEAP_TEST;\n    #endif\n}\n\n\n/* free decoded CRL resources */\nvoid FreeDecodedCRL(DecodedCRL* dcrl)\n{\n    RevokedCert* tmp = dcrl->certs;\n\n    WOLFSSL_MSG(\"FreeDecodedCRL\");\n\n    while(tmp) {\n        RevokedCert* next = tmp->next;\n        XFREE(tmp, dcrl->heap, DYNAMIC_TYPE_REVOKED);\n        tmp = next;\n    }\n}\n\n\n/* Get Revoked Cert list, 0 on success */\nstatic int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,\n                      int maxIdx)\n{\n    int    ret, len;\n    word32 end;\n    byte   b;\n    RevokedCert* rc;\n\n    WOLFSSL_ENTER(\"GetRevoked\");\n\n    if (GetSequence(buff, idx, &len, maxIdx) < 0)\n        return ASN_PARSE_E;\n\n    end = *idx + len;\n\n    rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,\n                                                          DYNAMIC_TYPE_REVOKED);\n    if (rc == NULL) {\n        WOLFSSL_MSG(\"Alloc Revoked Cert failed\");\n        return MEMORY_E;\n    }\n\n    if (GetSerialNumber(buff, idx, rc->serialNumber, &rc->serialSz,\n                                                                maxIdx) < 0) {\n        XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED);\n        return ASN_PARSE_E;\n    }\n\n    /* add to list */\n    rc->next = dcrl->certs;\n    dcrl->certs = rc;\n    dcrl->totalCerts++;\n\n    /* get date */\n    ret = GetDateInfo(buff, idx, NULL, &b, NULL, maxIdx);\n    if (ret < 0) {\n        WOLFSSL_MSG(\"Expecting Date\");\n        return ret;\n    }\n\n    if (*idx != end)  /* skip extensions */\n        *idx = end;\n\n    return 0;\n}\n\n\n/* Get CRL Signature, 0 on success */\nstatic int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,\n                            int maxIdx)\n{\n    int    length;\n    int    ret;\n\n    WOLFSSL_ENTER(\"GetCRL_Signature\");\n\n    ret = CheckBitString(source, idx, &length, maxIdx, 1, NULL);\n    if (ret != 0)\n        return ret;\n    dcrl->sigLength = length;\n\n    dcrl->signature = (byte*)&source[*idx];\n    *idx += dcrl->sigLength;\n\n    return 0;\n}\n\nint VerifyCRL_Signature(SignatureCtx* sigCtx, const byte* toBeSigned,\n                        word32 tbsSz, const byte* signature, word32 sigSz,\n                        word32 signatureOID, Signer *ca, void* heap)\n{\n    /* try to confirm/verify signature */\n#ifndef IGNORE_KEY_EXTENSIONS\n    if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {\n        WOLFSSL_MSG(\"CA cannot sign CRLs\");\n        return ASN_CRL_NO_SIGNER_E;\n    }\n#endif /* IGNORE_KEY_EXTENSIONS */\n\n    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);\n    if (ConfirmSignature(sigCtx, toBeSigned, tbsSz, ca->publicKey,\n                         ca->pubKeySize, ca->keyOID, signature, sigSz,\n                         signatureOID, NULL) != 0) {\n        WOLFSSL_MSG(\"CRL Confirm signature failed\");\n        return ASN_CRL_CONFIRM_E;\n    }\n\n    return 0;\n}\n\n\nstatic int ParseCRL_CertList(DecodedCRL* dcrl, const byte* buf,\n        word32* inOutIdx, int sz)\n{\n    word32 oid, dateIdx, idx, checkIdx;\n    int version, doNextDate = 1;\n    byte tag;\n\n    if (dcrl == NULL || inOutIdx == NULL || buf == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* may have version */\n    idx = *inOutIdx;\n\n    checkIdx = idx;\n    if (GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag == ASN_INTEGER) {\n        if (GetMyVersion(buf, &idx, &version, sz) < 0)\n            return ASN_PARSE_E;\n    }\n\n    if (GetAlgoId(buf, &idx, &oid, oidIgnoreType, sz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetNameHash(buf, &idx, dcrl->issuerHash, sz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetBasicDate(buf, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)\n        return ASN_PARSE_E;\n\n    dateIdx = idx;\n\n    if (GetBasicDate(buf, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)\n    {\n#ifndef WOLFSSL_NO_CRL_NEXT_DATE\n        (void)dateIdx;\n        return ASN_PARSE_E;\n#else\n        dcrl->nextDateFormat = ASN_OTHER_TYPE;  /* skip flag */\n        doNextDate = 0;\n        idx = dateIdx;\n#endif\n    }\n\n    if (doNextDate) {\n#ifndef NO_ASN_TIME\n        if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {\n            WOLFSSL_MSG(\"CRL after date is no longer valid\");\n            return ASN_AFTER_DATE_E;\n        }\n#endif\n    }\n\n    checkIdx = idx;\n    if (idx != dcrl->sigIndex &&\n           GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag != CRL_EXTENSIONS) {\n\n        int len;\n\n        if (GetSequence(buf, &idx, &len, sz) < 0)\n            return ASN_PARSE_E;\n        len += idx;\n\n        while (idx < (word32)len) {\n            if (GetRevoked(buf, &idx, dcrl, len) < 0)\n                return ASN_PARSE_E;\n        }\n    }\n\n    *inOutIdx = idx;\n\n    return 0;\n}\n\n\n#ifndef NO_SKID\nstatic int ParseCRL_AuthKeyIdExt(const byte* input, int sz, DecodedCRL* dcrl)\n{\n    word32 idx = 0;\n    int length = 0, ret = 0;\n    byte tag;\n\n    WOLFSSL_ENTER(\"ParseCRL_AuthKeyIdExt\");\n\n    if (GetSequence(input, &idx, &length, sz) < 0) {\n        WOLFSSL_MSG(\"\\tfail: should be a SEQUENCE\\n\");\n        return ASN_PARSE_E;\n    }\n\n    if (GetASNTag(input, &idx, &tag, sz) < 0) {\n        return ASN_PARSE_E;\n    }\n\n    if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {\n        WOLFSSL_MSG(\"\\tinfo: OPTIONAL item 0, not available\\n\");\n        return 0;\n    }\n\n    if (GetLength(input, &idx, &length, sz) <= 0) {\n        WOLFSSL_MSG(\"\\tfail: extension data length\");\n        return ASN_PARSE_E;\n    }\n\n    dcrl->extAuthKeyIdSet = 1;\n    if (length == KEYID_SIZE) {\n        XMEMCPY(dcrl->extAuthKeyId, input + idx, length);\n    }\n    else {\n        ret = CalcHashId(input + idx, length, dcrl->extAuthKeyId);\n    }\n\n    return ret;\n}\n#endif\n\n\nstatic int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf,\n        word32* inOutIdx, word32 sz)\n{\n    int length;\n    word32 idx;\n    word32 ext_bound; /* boundary index for the sequence of extensions */\n    word32 oid;\n    byte tag;\n\n    WOLFSSL_ENTER(\"ParseCRL_Extensions\");\n    (void)dcrl;\n\n    if (inOutIdx == NULL)\n        return BAD_FUNC_ARG;\n\n    idx = *inOutIdx;\n\n    if ((idx + 1) > sz)\n        return BUFFER_E;\n\n    if (GetASNTag(buf, &idx, &tag, sz) < 0)\n        return ASN_PARSE_E;\n\n    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))\n        return ASN_PARSE_E;\n\n    if (GetLength(buf, &idx, &length, sz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetSequence(buf, &idx, &length, sz) < 0)\n        return ASN_PARSE_E;\n\n    ext_bound = idx + length;\n\n    while (idx < (word32)ext_bound) {\n        word32 localIdx;\n        int ret;\n\n        if (GetSequence(buf, &idx, &length, sz) < 0) {\n            WOLFSSL_MSG(\"\\tfail: should be a SEQUENCE\");\n            return ASN_PARSE_E;\n        }\n\n        oid = 0;\n        if (GetObjectId(buf, &idx, &oid, oidCrlExtType, sz) < 0) {\n            WOLFSSL_MSG(\"\\tfail: OBJECT ID\");\n            return ASN_PARSE_E;\n        }\n\n        /* check for critical flag */\n        if ((idx + 1) > (word32)sz) {\n            WOLFSSL_MSG(\"\\tfail: malformed buffer\");\n            return BUFFER_E;\n        }\n\n        localIdx = idx;\n        if (GetASNTag(buf, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {\n            WOLFSSL_MSG(\"\\tfound optional critical flag, moving past\");\n            ret = GetBoolean(buf, &idx, sz);\n            if (ret < 0)\n                return ret;\n        }\n\n        ret = GetOctetString(buf, &idx, &length, sz);\n        if (ret < 0)\n            return ret;\n\n        if (oid == AUTH_KEY_OID) {\n        #ifndef NO_SKID\n            ret = ParseCRL_AuthKeyIdExt(buf + idx, length, dcrl);\n            if (ret < 0) {\n                WOLFSSL_MSG(\"\\tcouldn't parse AuthKeyId extension\");\n                return ret;\n            }\n        #endif\n        }\n\n        idx += length;\n    }\n\n    *inOutIdx = idx;\n\n    return 0;\n}\n\n\n/* prase crl buffer into decoded state, 0 on success */\nint ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)\n{\n    int          len;\n    word32       idx = 0;\n    Signer*      ca = NULL;\n    SignatureCtx sigCtx;\n\n    WOLFSSL_MSG(\"ParseCRL\");\n\n    /* raw crl hash */\n    /* hash here if needed for optimized comparisons\n     * wc_Sha sha;\n     * wc_InitSha(&sha);\n     * wc_ShaUpdate(&sha, buff, sz);\n     * wc_ShaFinal(&sha, dcrl->crlHash); */\n\n    if (GetSequence(buff, &idx, &len, sz) < 0)\n        return ASN_PARSE_E;\n\n    dcrl->certBegin = idx;\n    /* Normalize sz for the length inside the outer sequence. */\n    sz = len + idx;\n\n    if (GetSequence(buff, &idx, &len, sz) < 0)\n        return ASN_PARSE_E;\n    dcrl->sigIndex = len + idx;\n\n    if (ParseCRL_CertList(dcrl, buff, &idx, idx + len) < 0)\n        return ASN_PARSE_E;\n\n    if (ParseCRL_Extensions(dcrl, buff, &idx, idx + len) < 0)\n        return ASN_PARSE_E;\n\n    idx = dcrl->sigIndex;\n\n    if (GetAlgoId(buff, &idx, &dcrl->signatureOID, oidSigType, sz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)\n        return ASN_PARSE_E;\n\n    /* openssl doesn't add skid by default for CRLs cause firefox chokes\n       if experiencing issues uncomment NO_SKID define in CRL section of\n       wolfssl/wolfcrypt/settings.h */\n#ifndef NO_SKID\n    if (dcrl->extAuthKeyIdSet) {\n        ca = GetCA(cm, dcrl->extAuthKeyId); /* more unique than issuerHash */\n    }\n    if (ca != NULL && XMEMCMP(dcrl->issuerHash, ca->subjectNameHash,\n                KEYID_SIZE) != 0) {\n        ca = NULL;\n    }\n    if (ca == NULL) {\n        ca = GetCAByName(cm, dcrl->issuerHash); /* last resort */\n        /* If AKID is availale then this CA doesn't have the public\n         * key required */\n        if (ca && dcrl->extAuthKeyIdSet) {\n            WOLFSSL_MSG(\"CA SKID doesn't match AKID\");\n            ca = NULL;\n        }\n    }\n#else\n    ca = GetCA(cm, dcrl->issuerHash);\n#endif /* !NO_SKID */\n    WOLFSSL_MSG(\"About to verify CRL signature\");\n\n    if (ca == NULL) {\n        WOLFSSL_MSG(\"Did NOT find CRL issuer CA\");\n        return ASN_CRL_NO_SIGNER_E;\n    }\n\n    WOLFSSL_MSG(\"Found CRL issuer CA\");\n    return VerifyCRL_Signature(&sigCtx, buff + dcrl->certBegin,\n           dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,\n           dcrl->signatureOID, ca, dcrl->heap);\n}\n\n#endif /* HAVE_CRL */\n\n\n\n#ifdef WOLFSSL_CERT_PIV\n\nint wc_ParseCertPIV(wc_CertPIV* piv, const byte* buf, word32 totalSz)\n{\n    int length = 0;\n    word32 idx = 0;\n\n    WOLFSSL_ENTER(\"wc_ParseCertPIV\");\n\n    if (piv == NULL || buf == NULL || totalSz == 0)\n        return BAD_FUNC_ARG;\n\n    XMEMSET(piv, 0, sizeof(wc_CertPIV));\n\n    /* Detect Identiv PIV (with 0x0A, 0x0B and 0x0C sections) */\n    /* Certificate (0A 82 05FA) */\n    if (GetASNHeader(buf, ASN_PIV_CERT, &idx, &length, totalSz) >= 0) {\n        /* Identiv Type PIV card */\n        piv->isIdentiv = 1;\n\n        piv->cert =   &buf[idx];\n        piv->certSz = length;\n        idx += length;\n\n        /* Nonce (0B 14) */\n        if (GetASNHeader(buf, ASN_PIV_NONCE, &idx, &length, totalSz) >= 0) {\n            piv->nonce =   &buf[idx];\n            piv->nonceSz = length;\n            idx += length;\n        }\n\n        /* Signed Nonce (0C 82 0100) */\n        if (GetASNHeader(buf, ASN_PIV_SIGNED_NONCE, &idx, &length, totalSz) >= 0) {\n            piv->signedNonce =   &buf[idx];\n            piv->signedNonceSz = length;\n            idx += length;\n        }\n\n        idx = 0;\n        buf = piv->cert;\n        totalSz = piv->certSz;\n    }\n\n    /* Certificate Buffer Total Size (53 82 05F6) */\n    if (GetASNHeader(buf, ASN_APPLICATION | ASN_PRINTABLE_STRING, &idx,\n                                                   &length, totalSz) < 0) {\n        return ASN_PARSE_E;\n    }\n    /* PIV Certificate (70 82 05ED) */\n    if (GetASNHeader(buf, ASN_PIV_TAG_CERT, &idx, &length,\n                                                         totalSz) < 0) {\n        return ASN_PARSE_E;\n    }\n\n    /* Capture certificate buffer pointer and length */\n    piv->cert =   &buf[idx];\n    piv->certSz = length;\n    idx += length;\n\n    /* PIV Certificate Info (71 01 00) */\n    if (GetASNHeader(buf, ASN_PIV_TAG_CERT_INFO, &idx, &length,\n                                                        totalSz) >= 0) {\n        if (length >= 1) {\n            piv->compression = (buf[idx] & ASN_PIV_CERT_INFO_COMPRESSED);\n            piv->isX509 =      (buf[idx] & ASN_PIV_CERT_INFO_ISX509);\n        }\n        idx += length;\n    }\n\n    /* PIV Error Detection (FE 00) */\n    if (GetASNHeader(buf, ASN_PIV_TAG_ERR_DET, &idx, &length,\n                                                        totalSz) >= 0) {\n        piv->certErrDet =   &buf[idx];\n        piv->certErrDetSz = length;\n        idx += length;\n    }\n\n    return 0;\n}\n\n#endif /* WOLFSSL_CERT_PIV */\n\n\n#undef ERROR_OUT\n\n#endif /* !NO_ASN */\n\n#ifdef WOLFSSL_SEP\n\n\n#endif /* WOLFSSL_SEP */\n"
  },
  {
    "path": "src/wolfcrypt/src/blake2b.c",
    "content": "/*\n   BLAKE2 reference source code package - reference C implementations\n\n   Written in 2012 by Samuel Neves <sneves@dei.uc.pt>\n\n   To the extent possible under law, the author(s) have dedicated all copyright\n   and related and neighboring rights to this software to the public domain\n   worldwide. This software is distributed without any warranty.\n\n   You should have received a copy of the CC0 Public Domain Dedication along with\n   this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.\n*/\n/* blake2b.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_BLAKE2\n\n#include <wolfssl/wolfcrypt/blake2.h>\n#include <wolfssl/wolfcrypt/blake2-impl.h>\n\n\nstatic const word64 blake2b_IV[8] =\n{\n  0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,\n  0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,\n  0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,\n  0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL\n};\n\nstatic const byte blake2b_sigma[12][16] =\n{\n  {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,\n  { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,\n  { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,\n  {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,\n  {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,\n  {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,\n  { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,\n  { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,\n  {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,\n  { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,\n  {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,\n  { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 }\n};\n\n\nstatic WC_INLINE int blake2b_set_lastnode( blake2b_state *S )\n{\n  S->f[1] = ~0ULL;\n  return 0;\n}\n\n/* Some helper functions, not necessarily useful */\nstatic WC_INLINE int blake2b_set_lastblock( blake2b_state *S )\n{\n  if( S->last_node ) blake2b_set_lastnode( S );\n\n  S->f[0] = ~0ULL;\n  return 0;\n}\n\nstatic WC_INLINE int blake2b_increment_counter( blake2b_state *S, const word64\n                                             inc )\n{\n  S->t[0] += inc;\n  S->t[1] += ( S->t[0] < inc );\n  return 0;\n}\n\nstatic WC_INLINE int blake2b_init0( blake2b_state *S )\n{\n  int i;\n  XMEMSET( S, 0, sizeof( blake2b_state ) );\n\n  for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];\n\n  return 0;\n}\n\n/* init xors IV with input parameter block */\nint blake2b_init_param( blake2b_state *S, const blake2b_param *P )\n{\n  word32 i;\n  byte *p ;\n  blake2b_init0( S );\n  p =  ( byte * )( P );\n\n  /* IV XOR ParamBlock */\n  for( i = 0; i < 8; ++i )\n    S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );\n\n  return 0;\n}\n\n\n\nint blake2b_init( blake2b_state *S, const byte outlen )\n{\n  blake2b_param P[1];\n\n  if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;\n\n#ifdef WOLFSSL_BLAKE2B_INIT_EACH_FIELD\n  P->digest_length = outlen;\n  P->key_length    = 0;\n  P->fanout        = 1;\n  P->depth         = 1;\n  store32( &P->leaf_length, 0 );\n  store64( &P->node_offset, 0 );\n  P->node_depth    = 0;\n  P->inner_length  = 0;\n  XMEMSET( P->reserved, 0, sizeof( P->reserved ) );\n  XMEMSET( P->salt,     0, sizeof( P->salt ) );\n  XMEMSET( P->personal, 0, sizeof( P->personal ) );\n#else\n  XMEMSET( P, 0, sizeof( *P ) );\n  P->digest_length = outlen;\n  P->fanout        = 1;\n  P->depth         = 1;\n#endif\n  return blake2b_init_param( S, P );\n}\n\n\nint blake2b_init_key( blake2b_state *S, const byte outlen, const void *key,\n                      const byte keylen )\n{\n  blake2b_param P[1];\n\n  if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;\n\n  if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;\n\n#ifdef WOLFSSL_BLAKE2B_INIT_EACH_FIELD\n  P->digest_length = outlen;\n  P->key_length    = keylen;\n  P->fanout        = 1;\n  P->depth         = 1;\n  store32( &P->leaf_length, 0 );\n  store64( &P->node_offset, 0 );\n  P->node_depth    = 0;\n  P->inner_length  = 0;\n  XMEMSET( P->reserved, 0, sizeof( P->reserved ) );\n  XMEMSET( P->salt,     0, sizeof( P->salt ) );\n  XMEMSET( P->personal, 0, sizeof( P->personal ) );\n#else\n  XMEMSET( P, 0, sizeof( *P ) );\n  P->digest_length = outlen;\n  P->key_length    = keylen;\n  P->fanout        = 1;\n  P->depth         = 1;\n#endif\n\n  if( blake2b_init_param( S, P ) < 0 ) return -1;\n\n  {\n#ifdef WOLFSSL_SMALL_STACK\n    byte* block;\n\n    block = (byte*)XMALLOC(BLAKE2B_BLOCKBYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n\n    if ( block == NULL ) return -1;\n#else\n    byte block[BLAKE2B_BLOCKBYTES];\n#endif\n\n    XMEMSET( block, 0, BLAKE2B_BLOCKBYTES );\n    XMEMCPY( block, key, keylen );\n    blake2b_update( S, block, BLAKE2B_BLOCKBYTES );\n    secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from */\n                                                     /* memory */\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(block, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n  }\n  return 0;\n}\n\nstatic int blake2b_compress( blake2b_state *S,\n                             const byte block[BLAKE2B_BLOCKBYTES] )\n{\n  int i;\n\n#ifdef WOLFSSL_SMALL_STACK\n  word64* m;\n  word64* v;\n\n  m = (word64*)XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n\n  if ( m == NULL ) return -1;\n\n  v = (word64*)XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n\n  if ( v == NULL )\n  {\n    XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    return -1;\n  }\n#else\n  word64 m[16];\n  word64 v[16];\n#endif\n\n  for( i = 0; i < 16; ++i )\n    m[i] = load64( block + i * sizeof( m[i] ) );\n\n  for( i = 0; i < 8; ++i )\n    v[i] = S->h[i];\n\n  v[ 8] = blake2b_IV[0];\n  v[ 9] = blake2b_IV[1];\n  v[10] = blake2b_IV[2];\n  v[11] = blake2b_IV[3];\n  v[12] = S->t[0] ^ blake2b_IV[4];\n  v[13] = S->t[1] ^ blake2b_IV[5];\n  v[14] = S->f[0] ^ blake2b_IV[6];\n  v[15] = S->f[1] ^ blake2b_IV[7];\n#define G(r,i,a,b,c,d) \\\n  do { \\\n    a = a + b + m[blake2b_sigma[r][2*i+0]]; \\\n    d = rotr64(d ^ a, 32); \\\n    c = c + d; \\\n    b = rotr64(b ^ c, 24); \\\n    a = a + b + m[blake2b_sigma[r][2*i+1]]; \\\n    d = rotr64(d ^ a, 16); \\\n    c = c + d; \\\n    b = rotr64(b ^ c, 63); \\\n  } while(0)\n#define ROUND(r)  \\\n  do { \\\n    G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \\\n    G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \\\n    G(r,2,v[ 2],v[ 6],v[10],v[14]); \\\n    G(r,3,v[ 3],v[ 7],v[11],v[15]); \\\n    G(r,4,v[ 0],v[ 5],v[10],v[15]); \\\n    G(r,5,v[ 1],v[ 6],v[11],v[12]); \\\n    G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \\\n    G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \\\n  } while(0)\n  ROUND( 0 );\n  ROUND( 1 );\n  ROUND( 2 );\n  ROUND( 3 );\n  ROUND( 4 );\n  ROUND( 5 );\n  ROUND( 6 );\n  ROUND( 7 );\n  ROUND( 8 );\n  ROUND( 9 );\n  ROUND( 10 );\n  ROUND( 11 );\n\n  for( i = 0; i < 8; ++i )\n    S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];\n\n#undef G\n#undef ROUND\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n  XFREE(v, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n  return 0;\n}\n\n/* inlen now in bytes */\nint blake2b_update( blake2b_state *S, const byte *in, word64 inlen )\n{\n  while( inlen > 0 )\n  {\n    word64 left = S->buflen;\n    word64 fill = 2 * BLAKE2B_BLOCKBYTES - left;\n\n    if( inlen > fill )\n    {\n      XMEMCPY( S->buf + left, in, (wolfssl_word)fill ); /* Fill buffer */\n      S->buflen += fill;\n      blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );\n\n      if ( blake2b_compress( S, S->buf ) < 0 ) return -1; /* Compress */\n\n      XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES );\n              /* Shift buffer left */\n      S->buflen -= BLAKE2B_BLOCKBYTES;\n      in += fill;\n      inlen -= fill;\n    }\n    else /* inlen <= fill */\n    {\n      XMEMCPY( S->buf + left, in, (wolfssl_word)inlen );\n      S->buflen += inlen; /* Be lazy, do not compress */\n      in += inlen;\n      inlen -= inlen;\n    }\n  }\n\n  return 0;\n}\n\n/* Is this correct? */\nint blake2b_final( blake2b_state *S, byte *out, byte outlen )\n{\n  byte buffer[BLAKE2B_OUTBYTES];\n  int     i;\n\n  if( S->buflen > BLAKE2B_BLOCKBYTES )\n  {\n    blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );\n\n    if ( blake2b_compress( S, S->buf ) < 0 ) return -1;\n\n    S->buflen -= BLAKE2B_BLOCKBYTES;\n    XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, (wolfssl_word)S->buflen );\n  }\n\n  blake2b_increment_counter( S, S->buflen );\n  blake2b_set_lastblock( S );\n  XMEMSET( S->buf + S->buflen, 0, (wolfssl_word)(2 * BLAKE2B_BLOCKBYTES - S->buflen) );\n         /* Padding */\n  if ( blake2b_compress( S, S->buf ) < 0 ) return -1;\n\n  for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */\n    store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );\n\n  XMEMCPY( out, buffer, outlen );\n  return 0;\n}\n\n/* inlen, at least, should be word64. Others can be size_t. */\nint blake2b( byte *out, const void *in, const void *key, const byte outlen,\n             const word64 inlen, byte keylen )\n{\n  blake2b_state S[1];\n\n  /* Verify parameters */\n  if ( NULL == in ) return -1;\n\n  if ( NULL == out ) return -1;\n\n  if( NULL == key ) keylen = 0;\n\n  if( keylen > 0 )\n  {\n    if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;\n  }\n  else\n  {\n    if( blake2b_init( S, outlen ) < 0 ) return -1;\n  }\n\n  if ( blake2b_update( S, ( byte * )in, inlen ) < 0) return -1;\n\n  return blake2b_final( S, out, outlen );\n}\n\n#if defined(BLAKE2B_SELFTEST)\n#include <string.h>\n#include \"blake2-kat.h\"\nint main( int argc, char **argv )\n{\n  byte key[BLAKE2B_KEYBYTES];\n  byte buf[KAT_LENGTH];\n\n  for( word32 i = 0; i < BLAKE2B_KEYBYTES; ++i )\n    key[i] = ( byte )i;\n\n  for( word32 i = 0; i < KAT_LENGTH; ++i )\n    buf[i] = ( byte )i;\n\n  for( word32 i = 0; i < KAT_LENGTH; ++i )\n  {\n    byte hash[BLAKE2B_OUTBYTES];\n    if ( blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 )\n    {\n      puts( \"error\" );\n      return -1;\n    }\n\n    if( 0 != XMEMCMP( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )\n    {\n      puts( \"error\" );\n      return -1;\n    }\n  }\n\n  puts( \"ok\" );\n  return 0;\n}\n#endif\n\n\n/* wolfCrypt API */\n\n/* Init Blake2b digest, track size in case final doesn't want to \"remember\" */\nint wc_InitBlake2b(Blake2b* b2b, word32 digestSz)\n{\n    if (b2b == NULL){\n        return -1;\n    }\n    b2b->digestSz = digestSz;\n\n    return blake2b_init(b2b->S, (byte)digestSz);\n}\n\n\n/* Blake2b Update */\nint wc_Blake2bUpdate(Blake2b* b2b, const byte* data, word32 sz)\n{\n    return blake2b_update(b2b->S, data, sz);\n}\n\n\n/* Blake2b Final, if pass in zero size we use init digestSz */\nint wc_Blake2bFinal(Blake2b* b2b, byte* final, word32 requestSz)\n{\n    word32 sz = requestSz ? requestSz : b2b->digestSz;\n\n    return blake2b_final(b2b->S, final, (byte)sz);\n}\n\n\n/* end CTaoCrypt API */\n\n#endif  /* HAVE_BLAKE2 */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/blake2s.c",
    "content": "/*\n   BLAKE2 reference source code package - reference C implementations\n\n   Written in 2012 by Samuel Neves <sneves@dei.uc.pt>\n\n   To the extent possible under law, the author(s) have dedicated all copyright\n   and related and neighboring rights to this software to the public domain\n   worldwide. This software is distributed without any warranty.\n\n   You should have received a copy of the CC0 Public Domain Dedication along with\n   this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.\n*/\n/* blake2s.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_BLAKE2S\n\n#include <wolfssl/wolfcrypt/blake2.h>\n#include <wolfssl/wolfcrypt/blake2-impl.h>\n\n\nstatic const word32 blake2s_IV[8] =\n{\n  0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,\n  0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19\n};\n\nstatic const byte blake2s_sigma[10][16] =\n{\n  {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,\n  { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,\n  { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,\n  {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,\n  {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,\n  {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,\n  { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,\n  { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,\n  {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,\n  { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 }\n};\n\n\nstatic WC_INLINE int blake2s_set_lastnode( blake2s_state *S )\n{\n  S->f[1] = ~0;\n  return 0;\n}\n\n/* Some helper functions, not necessarily useful */\nstatic WC_INLINE int blake2s_set_lastblock( blake2s_state *S )\n{\n  if( S->last_node ) blake2s_set_lastnode( S );\n\n  S->f[0] = ~0;\n  return 0;\n}\n\nstatic WC_INLINE int blake2s_increment_counter( blake2s_state *S, const word32\n                                             inc )\n{\n  S->t[0] += inc;\n  S->t[1] += ( S->t[0] < inc );\n  return 0;\n}\n\nstatic WC_INLINE int blake2s_init0( blake2s_state *S )\n{\n  int i;\n  XMEMSET( S, 0, sizeof( blake2s_state ) );\n\n  for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];\n\n  return 0;\n}\n\n/* init xors IV with input parameter block */\nint blake2s_init_param( blake2s_state *S, const blake2s_param *P )\n{\n  word32 i;\n  byte *p ;\n  blake2s_init0( S );\n  p =  ( byte * )( P );\n\n  /* IV XOR ParamBlock */\n  for( i = 0; i < 8; ++i )\n    S->h[i] ^= load32( p + sizeof( S->h[i] ) * i );\n\n  return 0;\n}\n\n\n\nint blake2s_init( blake2s_state *S, const byte outlen )\n{\n  blake2s_param P[1];\n\n  if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;\n\n#ifdef WOLFSSL_BLAKE2S_INIT_EACH_FIELD\n  P->digest_length = outlen;\n  P->key_length    = 0;\n  P->fanout        = 1;\n  P->depth         = 1;\n  store32( &P->leaf_length, 0 );\n  store32( &P->node_offset, 0 );\n  P->node_depth    = 0;\n  P->inner_length  = 0;\n  XMEMSET( P->reserved, 0, sizeof( P->reserved ) );\n  XMEMSET( P->salt,     0, sizeof( P->salt ) );\n  XMEMSET( P->personal, 0, sizeof( P->personal ) );\n#else\n  XMEMSET( P, 0, sizeof( *P ) );\n  P->digest_length = outlen;\n  P->fanout        = 1;\n  P->depth         = 1;\n#endif\n  return blake2s_init_param( S, P );\n}\n\n\nint blake2s_init_key( blake2s_state *S, const byte outlen, const void *key,\n                      const byte keylen )\n{\n  blake2s_param P[1];\n\n  if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;\n\n  if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;\n\n#ifdef WOLFSSL_BLAKE2S_INIT_EACH_FIELD\n  P->digest_length = outlen;\n  P->key_length    = keylen;\n  P->fanout        = 1;\n  P->depth         = 1;\n  store32( &P->leaf_length, 0 );\n  store64( &P->node_offset, 0 );\n  P->node_depth    = 0;\n  P->inner_length  = 0;\n  XMEMSET( P->reserved, 0, sizeof( P->reserved ) );\n  XMEMSET( P->salt,     0, sizeof( P->salt ) );\n  XMEMSET( P->personal, 0, sizeof( P->personal ) );\n#else\n  XMEMSET( P, 0, sizeof( *P ) );\n  P->digest_length = outlen;\n  P->key_length    = keylen;\n  P->fanout        = 1;\n  P->depth         = 1;\n#endif\n\n  if( blake2s_init_param( S, P ) < 0 ) return -1;\n\n  {\n#ifdef WOLFSSL_SMALL_STACK\n    byte* block;\n\n    block = (byte*)XMALLOC(BLAKE2S_BLOCKBYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n\n    if ( block == NULL ) return -1;\n#else\n    byte block[BLAKE2S_BLOCKBYTES];\n#endif\n\n    XMEMSET( block, 0, BLAKE2S_BLOCKBYTES );\n    XMEMCPY( block, key, keylen );\n    blake2s_update( S, block, BLAKE2S_BLOCKBYTES );\n    secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from */\n                                                     /* memory */\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(block, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n  }\n  return 0;\n}\n\nstatic int blake2s_compress( blake2s_state *S,\n                             const byte block[BLAKE2S_BLOCKBYTES] )\n{\n  int i;\n\n#ifdef WOLFSSL_SMALL_STACK\n  word32* m;\n  word32* v;\n\n  m = (word32*)XMALLOC(sizeof(word32) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n\n  if ( m == NULL ) return -1;\n\n  v = (word32*)XMALLOC(sizeof(word32) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n\n  if ( v == NULL )\n  {\n    XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    return -1;\n  }\n#else\n  word32 m[16];\n  word32 v[16];\n#endif\n\n  for( i = 0; i < 16; ++i )\n    m[i] = load32( block + i * sizeof( m[i] ) );\n\n  for( i = 0; i < 8; ++i )\n    v[i] = S->h[i];\n\n  v[ 8] = blake2s_IV[0];\n  v[ 9] = blake2s_IV[1];\n  v[10] = blake2s_IV[2];\n  v[11] = blake2s_IV[3];\n  v[12] = S->t[0] ^ blake2s_IV[4];\n  v[13] = S->t[1] ^ blake2s_IV[5];\n  v[14] = S->f[0] ^ blake2s_IV[6];\n  v[15] = S->f[1] ^ blake2s_IV[7];\n#define G(r,i,a,b,c,d) \\\n  do { \\\n    a = a + b + m[blake2s_sigma[r][2*i+0]]; \\\n    d = rotr32(d ^ a, 16); \\\n    c = c + d; \\\n    b = rotr32(b ^ c, 12); \\\n    a = a + b + m[blake2s_sigma[r][2*i+1]]; \\\n    d = rotr32(d ^ a, 8); \\\n    c = c + d; \\\n    b = rotr32(b ^ c, 7); \\\n  } while(0)\n#define ROUND(r)  \\\n  do { \\\n    G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \\\n    G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \\\n    G(r,2,v[ 2],v[ 6],v[10],v[14]); \\\n    G(r,3,v[ 3],v[ 7],v[11],v[15]); \\\n    G(r,4,v[ 0],v[ 5],v[10],v[15]); \\\n    G(r,5,v[ 1],v[ 6],v[11],v[12]); \\\n    G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \\\n    G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \\\n  } while(0)\n  ROUND( 0 );\n  ROUND( 1 );\n  ROUND( 2 );\n  ROUND( 3 );\n  ROUND( 4 );\n  ROUND( 5 );\n  ROUND( 6 );\n  ROUND( 7 );\n  ROUND( 8 );\n  ROUND( 9 );\n\n  for( i = 0; i < 8; ++i )\n    S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];\n\n#undef G\n#undef ROUND\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n  XFREE(v, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n  return 0;\n}\n\n/* inlen now in bytes */\nint blake2s_update( blake2s_state *S, const byte *in, word32 inlen )\n{\n  while( inlen > 0 )\n  {\n    word32 left = S->buflen;\n    word32 fill = 2 * BLAKE2S_BLOCKBYTES - left;\n\n    if( inlen > fill )\n    {\n      XMEMCPY( S->buf + left, in, (wolfssl_word)fill ); /* Fill buffer */\n      S->buflen += fill;\n      blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );\n\n      if ( blake2s_compress( S, S->buf ) < 0 ) return -1; /* Compress */\n\n      XMEMCPY( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );\n              /* Shift buffer left */\n      S->buflen -= BLAKE2S_BLOCKBYTES;\n      in += fill;\n      inlen -= fill;\n    }\n    else /* inlen <= fill */\n    {\n      XMEMCPY( S->buf + left, in, (wolfssl_word)inlen );\n      S->buflen += inlen; /* Be lazy, do not compress */\n      in += inlen;\n      inlen -= inlen;\n    }\n  }\n\n  return 0;\n}\n\n/* Is this correct? */\nint blake2s_final( blake2s_state *S, byte *out, byte outlen )\n{\n  int     i;\n  byte buffer[BLAKE2S_BLOCKBYTES];\n\n  if( S->buflen > BLAKE2S_BLOCKBYTES )\n  {\n    blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );\n\n    if ( blake2s_compress( S, S->buf ) < 0 ) return -1;\n\n    S->buflen -= BLAKE2S_BLOCKBYTES;\n    XMEMCPY( S->buf, S->buf + BLAKE2S_BLOCKBYTES, (wolfssl_word)S->buflen );\n  }\n\n  blake2s_increment_counter( S, S->buflen );\n  blake2s_set_lastblock( S );\n  XMEMSET( S->buf + S->buflen, 0, (wolfssl_word)(2 * BLAKE2S_BLOCKBYTES - S->buflen) );\n         /* Padding */\n  if ( blake2s_compress( S, S->buf ) < 0 ) return -1;\n\n  for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */\n    store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );\n\n  XMEMCPY( out, buffer, outlen );\n  return 0;\n}\n\n/* inlen, at least, should be word32. Others can be size_t. */\nint blake2s( byte *out, const void *in, const void *key, const byte outlen,\n             const word32 inlen, byte keylen )\n{\n  blake2s_state S[1];\n\n  /* Verify parameters */\n  if ( NULL == in ) return -1;\n\n  if ( NULL == out ) return -1;\n\n  if( NULL == key ) keylen = 0;\n\n  if( keylen > 0 )\n  {\n    if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;\n  }\n  else\n  {\n    if( blake2s_init( S, outlen ) < 0 ) return -1;\n  }\n\n  if ( blake2s_update( S, ( byte * )in, inlen ) < 0) return -1;\n\n  return blake2s_final( S, out, outlen );\n}\n\n#if defined(BLAKE2S_SELFTEST)\n#include <string.h>\n#include \"blake2-kat.h\"\nint main( int argc, char **argv )\n{\n  byte key[BLAKE2S_KEYBYTES];\n  byte buf[KAT_LENGTH];\n\n  for( word32 i = 0; i < BLAKE2S_KEYBYTES; ++i )\n    key[i] = ( byte )i;\n\n  for( word32 i = 0; i < KAT_LENGTH; ++i )\n    buf[i] = ( byte )i;\n\n  for( word32 i = 0; i < KAT_LENGTH; ++i )\n  {\n    byte hash[BLAKE2S_OUTBYTES];\n    if ( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 )\n    {\n      puts( \"error\" );\n      return -1;\n    }\n\n    if( 0 != XMEMCMP( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )\n    {\n      puts( \"error\" );\n      return -1;\n    }\n  }\n\n  puts( \"ok\" );\n  return 0;\n}\n#endif\n\n\n/* wolfCrypt API */\n\n/* Init Blake2s digest, track size in case final doesn't want to \"remember\" */\nint wc_InitBlake2s(Blake2s* b2s, word32 digestSz)\n{\n    if (b2s == NULL){\n        return -1;\n    }\n    b2s->digestSz = digestSz;\n\n    return blake2s_init(b2s->S, (byte)digestSz);\n}\n\n\n/* Blake2s Update */\nint wc_Blake2sUpdate(Blake2s* b2s, const byte* data, word32 sz)\n{\n    return blake2s_update(b2s->S, data, sz);\n}\n\n\n/* Blake2s Final, if pass in zero size we use init digestSz */\nint wc_Blake2sFinal(Blake2s* b2s, byte* final, word32 requestSz)\n{\n    word32 sz = requestSz ? requestSz : b2s->digestSz;\n\n    return blake2s_final(b2s->S, final, (byte)sz);\n}\n\n\n/* end CTaoCrypt API */\n\n#endif  /* HAVE_BLAKE2S */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/camellia.c",
    "content": "/* camellia.c ver 1.2.0\n *\n * Copyright (c) 2006,2007\n * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer as\n *   the first lines of this file unmodified.\n * 2. Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* camellia.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n/*\n * Algorithm Specification\n *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_CAMELLIA\n\n#include <wolfssl/wolfcrypt/camellia.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n/* u32 must be 32bit word */\ntypedef unsigned int u32;\ntypedef unsigned char u8;\n\n/* key constants */\n\n#define CAMELLIA_SIGMA1L ((u32)0xA09E667FL)\n#define CAMELLIA_SIGMA1R ((u32)0x3BCC908BL)\n#define CAMELLIA_SIGMA2L ((u32)0xB67AE858L)\n#define CAMELLIA_SIGMA2R ((u32)0x4CAA73B2L)\n#define CAMELLIA_SIGMA3L ((u32)0xC6EF372FL)\n#define CAMELLIA_SIGMA3R ((u32)0xE94F82BEL)\n#define CAMELLIA_SIGMA4L ((u32)0x54FF53A5L)\n#define CAMELLIA_SIGMA4R ((u32)0xF1D36F1CL)\n#define CAMELLIA_SIGMA5L ((u32)0x10E527FAL)\n#define CAMELLIA_SIGMA5R ((u32)0xDE682D1DL)\n#define CAMELLIA_SIGMA6L ((u32)0xB05688C2L)\n#define CAMELLIA_SIGMA6R ((u32)0xB3E6C1FDL)\n\n/*\n *  macros\n */\n\n\n#if defined(_MSC_VER)\n\n# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)\n# define GETU32(p) SWAP(*((u32 *)(p)))\n# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));}\n\n#else /* not MS-VC */\n\n# define GETU32(pt)\t\t\t\t\\\n    (((u32)(pt)[0] << 24)\t\t\t\\\n     ^ ((u32)(pt)[1] << 16)\t\t\t\\\n     ^ ((u32)(pt)[2] <<  8)\t\t\t\\\n     ^ ((u32)(pt)[3]))\n\n# define PUTU32(ct, st)  {\t\t\t\\\n\t(ct)[0] = (u8)((st) >> 24);\t\t\\\n\t(ct)[1] = (u8)((st) >> 16);\t\t\\\n\t(ct)[2] = (u8)((st) >>  8);\t\t\\\n\t(ct)[3] = (u8)(st); }\n\n#endif\n\n#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])\n#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])\n\n/* rotation right shift 1byte */\n#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))\n/* rotation left shift 1bit */\n#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))\n/* rotation left shift 1byte */\n#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))\n\n#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits)\t\\\n    do {\t\t\t\t\t\t\\\n\tw0 = ll;\t\t\t\t\t\\\n\tll = (ll << bits) + (lr >> (32 - bits));\t\\\n\tlr = (lr << bits) + (rl >> (32 - bits));\t\\\n\trl = (rl << bits) + (rr >> (32 - bits));\t\\\n\trr = (rr << bits) + (w0 >> (32 - bits));\t\\\n    } while(0)\n\n#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits)\t\\\n    do {\t\t\t\t\t\t\\\n\tw0 = ll;\t\t\t\t\t\\\n\tw1 = lr;\t\t\t\t\t\\\n\tll = (lr << (bits - 32)) + (rl >> (64 - bits));\t\\\n\tlr = (rl << (bits - 32)) + (rr >> (64 - bits));\t\\\n\trl = (rr << (bits - 32)) + (w0 >> (64 - bits));\t\\\n\trr = (w0 << (bits - 32)) + (w1 >> (64 - bits));\t\\\n    } while(0)\n\n#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])\n#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])\n#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])\n#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])\n\n#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)\t\\\n    do {\t\t\t\t\t\t\t\\\n\til = xl ^ kl;\t\t\t\t\t\t\\\n\tir = xr ^ kr;\t\t\t\t\t\t\\\n\tt0 = il >> 16;\t\t\t\t\t\t\\\n\tt1 = ir >> 16;\t\t\t\t\t\t\\\n\tyl = CAMELLIA_SP1110(ir & 0xff)\t\t\t\t\\\n\t    ^ CAMELLIA_SP0222((t1 >> 8) & 0xff)\t\t\t\\\n\t    ^ CAMELLIA_SP3033(t1 & 0xff)\t\t\t\\\n\t    ^ CAMELLIA_SP4404((ir >> 8) & 0xff);\t\t\\\n\tyr = CAMELLIA_SP1110((t0 >> 8) & 0xff)\t\t\t\\\n\t    ^ CAMELLIA_SP0222(t0 & 0xff)\t\t\t\\\n\t    ^ CAMELLIA_SP3033((il >> 8) & 0xff)\t\t\t\\\n\t    ^ CAMELLIA_SP4404(il & 0xff);\t\t\t\\\n\tyl ^= yr;\t\t\t\t\t\t\\\n\tyr = CAMELLIA_RR8(yr);\t\t\t\t\t\\\n\tyr ^= yl;\t\t\t\t\t\t\\\n    } while(0)\n\n\n/*\n * for speed up\n *\n */\n#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \\\n    do {\t\t\t\t\t\t\t\t\\\n\tt0 = kll;\t\t\t\t\t\t\t\\\n\tt0 &= ll;\t\t\t\t\t\t\t\\\n\tlr ^= CAMELLIA_RL1(t0);\t\t\t\t\t\t\\\n\tt1 = klr;\t\t\t\t\t\t\t\\\n\tt1 |= lr;\t\t\t\t\t\t\t\\\n\tll ^= t1;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tt2 = krr;\t\t\t\t\t\t\t\\\n\tt2 |= rr;\t\t\t\t\t\t\t\\\n\trl ^= t2;\t\t\t\t\t\t\t\\\n\tt3 = krl;\t\t\t\t\t\t\t\\\n\tt3 &= rl;\t\t\t\t\t\t\t\\\n\trr ^= CAMELLIA_RL1(t3);\t\t\t\t\t\t\\\n    } while(0)\n\n#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)\t\\\n    do {\t\t\t\t\t\t\t\t\\\n\tir = CAMELLIA_SP1110(xr & 0xff)\t\t\t\t\t\\\n\t    ^ CAMELLIA_SP0222((xr >> 24) & 0xff)\t\t\t\\\n\t    ^ CAMELLIA_SP3033((xr >> 16) & 0xff)\t\t\t\\\n\t    ^ CAMELLIA_SP4404((xr >> 8) & 0xff);\t\t\t\\\n\til = CAMELLIA_SP1110((xl >> 24) & 0xff)\t\t\t\t\\\n\t    ^ CAMELLIA_SP0222((xl >> 16) & 0xff)\t\t\t\\\n\t    ^ CAMELLIA_SP3033((xl >> 8) & 0xff)\t\t\t\t\\\n\t    ^ CAMELLIA_SP4404(xl & 0xff);\t\t\t\t\\\n\til ^= kl;\t\t\t\t\t\t\t\\\n\tir ^= kr;\t\t\t\t\t\t\t\\\n\tir ^= il;\t\t\t\t\t\t\t\\\n\til = CAMELLIA_RR8(il);\t\t\t\t\t\t\\\n\til ^= ir;\t\t\t\t\t\t\t\\\n\tyl ^= ir;\t\t\t\t\t\t\t\\\n\tyr ^= il;\t\t\t\t\t\t\t\\\n    } while(0)\n\n\nstatic const u32 camellia_sp1110[256] = {\n    0x70707000,0x82828200,0x2c2c2c00,0xececec00,\n    0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,\n    0xe4e4e400,0x85858500,0x57575700,0x35353500,\n    0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,\n    0x23232300,0xefefef00,0x6b6b6b00,0x93939300,\n    0x45454500,0x19191900,0xa5a5a500,0x21212100,\n    0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,\n    0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,\n    0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,\n    0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,\n    0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,\n    0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,\n    0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,\n    0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,\n    0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,\n    0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,\n    0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,\n    0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,\n    0x74747400,0x12121200,0x2b2b2b00,0x20202000,\n    0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,\n    0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,\n    0x34343400,0x7e7e7e00,0x76767600,0x05050500,\n    0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,\n    0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,\n    0x14141400,0x58585800,0x3a3a3a00,0x61616100,\n    0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,\n    0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,\n    0x53535300,0x18181800,0xf2f2f200,0x22222200,\n    0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,\n    0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,\n    0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,\n    0x60606000,0xfcfcfc00,0x69696900,0x50505000,\n    0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,\n    0xa1a1a100,0x89898900,0x62626200,0x97979700,\n    0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,\n    0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,\n    0x10101000,0xc4c4c400,0x00000000,0x48484800,\n    0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,\n    0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,\n    0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,\n    0x87878700,0x5c5c5c00,0x83838300,0x02020200,\n    0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,\n    0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,\n    0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,\n    0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,\n    0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,\n    0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,\n    0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,\n    0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,\n    0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,\n    0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,\n    0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,\n    0x78787800,0x98989800,0x06060600,0x6a6a6a00,\n    0xe7e7e700,0x46464600,0x71717100,0xbababa00,\n    0xd4d4d400,0x25252500,0xababab00,0x42424200,\n    0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,\n    0x72727200,0x07070700,0xb9b9b900,0x55555500,\n    0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,\n    0x36363600,0x49494900,0x2a2a2a00,0x68686800,\n    0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,\n    0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,\n    0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,\n    0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,\n    0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,\n};\n\nstatic const u32 camellia_sp0222[256] = {\n    0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,\n    0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,\n    0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,\n    0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,\n    0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,\n    0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,\n    0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,\n    0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,\n    0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,\n    0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,\n    0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,\n    0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,\n    0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,\n    0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,\n    0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,\n    0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,\n    0x00171717,0x001a1a1a,0x00353535,0x00cccccc,\n    0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,\n    0x00e8e8e8,0x00242424,0x00565656,0x00404040,\n    0x00e1e1e1,0x00636363,0x00090909,0x00333333,\n    0x00bfbfbf,0x00989898,0x00979797,0x00858585,\n    0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,\n    0x00dadada,0x006f6f6f,0x00535353,0x00626262,\n    0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,\n    0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,\n    0x00bdbdbd,0x00363636,0x00222222,0x00383838,\n    0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,\n    0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,\n    0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,\n    0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,\n    0x00484848,0x00101010,0x00d1d1d1,0x00515151,\n    0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,\n    0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,\n    0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,\n    0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,\n    0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,\n    0x00202020,0x00898989,0x00000000,0x00909090,\n    0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,\n    0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,\n    0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,\n    0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,\n    0x009b9b9b,0x00949494,0x00212121,0x00666666,\n    0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,\n    0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,\n    0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,\n    0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,\n    0x00030303,0x002d2d2d,0x00dedede,0x00969696,\n    0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,\n    0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,\n    0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,\n    0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,\n    0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,\n    0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,\n    0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,\n    0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,\n    0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,\n    0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,\n    0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,\n    0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,\n    0x00787878,0x00707070,0x00e3e3e3,0x00494949,\n    0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,\n    0x00777777,0x00939393,0x00868686,0x00838383,\n    0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,\n    0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,\n};\n\nstatic const u32 camellia_sp3033[256] = {\n    0x38003838,0x41004141,0x16001616,0x76007676,\n    0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,\n    0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,\n    0x75007575,0x06000606,0x57005757,0xa000a0a0,\n    0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,\n    0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,\n    0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,\n    0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,\n    0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,\n    0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,\n    0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,\n    0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,\n    0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,\n    0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,\n    0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,\n    0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,\n    0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,\n    0xfd00fdfd,0x66006666,0x58005858,0x96009696,\n    0x3a003a3a,0x09000909,0x95009595,0x10001010,\n    0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,\n    0xef00efef,0x26002626,0xe500e5e5,0x61006161,\n    0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,\n    0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,\n    0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,\n    0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,\n    0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,\n    0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,\n    0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,\n    0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,\n    0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,\n    0x12001212,0x04000404,0x74007474,0x54005454,\n    0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,\n    0x55005555,0x68006868,0x50005050,0xbe00bebe,\n    0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,\n    0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,\n    0x70007070,0xff00ffff,0x32003232,0x69006969,\n    0x08000808,0x62006262,0x00000000,0x24002424,\n    0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,\n    0x45004545,0x81008181,0x73007373,0x6d006d6d,\n    0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,\n    0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,\n    0xe600e6e6,0x25002525,0x48004848,0x99009999,\n    0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,\n    0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,\n    0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,\n    0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,\n    0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,\n    0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,\n    0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,\n    0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,\n    0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,\n    0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,\n    0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,\n    0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,\n    0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,\n    0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,\n    0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,\n    0x7c007c7c,0x77007777,0x56005656,0x05000505,\n    0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,\n    0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,\n    0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,\n    0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,\n    0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,\n    0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,\n};\n\nstatic const u32 camellia_sp4404[256] = {\n    0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,\n    0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,\n    0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,\n    0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,\n    0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,\n    0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,\n    0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,\n    0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,\n    0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,\n    0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,\n    0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,\n    0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,\n    0x14140014,0x3a3a003a,0xdede00de,0x11110011,\n    0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,\n    0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,\n    0x24240024,0xe8e800e8,0x60600060,0x69690069,\n    0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,\n    0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,\n    0x10100010,0x00000000,0xa3a300a3,0x75750075,\n    0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,\n    0x87870087,0x83830083,0xcdcd00cd,0x90900090,\n    0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,\n    0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,\n    0x81810081,0x6f6f006f,0x13130013,0x63630063,\n    0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,\n    0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,\n    0x78780078,0x06060006,0xe7e700e7,0x71710071,\n    0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,\n    0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,\n    0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,\n    0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,\n    0x15150015,0xadad00ad,0x77770077,0x80800080,\n    0x82820082,0xecec00ec,0x27270027,0xe5e500e5,\n    0x85850085,0x35350035,0x0c0c000c,0x41410041,\n    0xefef00ef,0x93930093,0x19190019,0x21210021,\n    0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,\n    0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,\n    0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,\n    0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,\n    0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,\n    0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,\n    0x12120012,0x20200020,0xb1b100b1,0x99990099,\n    0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,\n    0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,\n    0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,\n    0x0f0f000f,0x16160016,0x18180018,0x22220022,\n    0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,\n    0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,\n    0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,\n    0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,\n    0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,\n    0x03030003,0xdada00da,0x3f3f003f,0x94940094,\n    0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,\n    0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,\n    0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,\n    0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,\n    0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,\n    0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,\n    0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,\n    0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,\n    0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,\n    0x49490049,0x68680068,0x38380038,0xa4a400a4,\n    0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,\n    0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,\n};\n\n\n/**\n * Stuff related to the Camellia key schedule\n */\n#define subl(x) subL[(x)]\n#define subr(x) subR[(x)]\n\nstatic int camellia_setup128(const unsigned char *key, u32 *subkey)\n{\n    u32 kll, klr, krl, krr;\n    u32 il, ir, t0, t1, w0, w1;\n    u32 kw4l, kw4r, dw, tl, tr;\n\n#ifdef WOLFSSL_SMALL_STACK\n    u32* subL;\n    u32* subR;\n\n    subL = (u32*) XMALLOC(sizeof(u32) * 26, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (subL == NULL)\n        return MEMORY_E;\n\n    subR = (u32*) XMALLOC(sizeof(u32) * 26, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (subR == NULL) {\n        XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n#else\n    u32 subL[26];\n    u32 subR[26];\n#endif\n\n    /**\n     *  k == kll || klr || krl || krr (|| is concatenation)\n     */\n    kll = GETU32(key     );\n    klr = GETU32(key +  4);\n    krl = GETU32(key +  8);\n    krr = GETU32(key + 12);\n    /**\n     * generate KL dependent subkeys\n     */\n    subl(0) = kll; subr(0) = klr;\n    subl(1) = krl; subr(1) = krr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);\n    subl(4) = kll; subr(4) = klr;\n    subl(5) = krl; subr(5) = krr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);\n    subl(10) = kll; subr(10) = klr;\n    subl(11) = krl; subr(11) = krr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);\n    subl(13) = krl; subr(13) = krr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);\n    subl(16) = kll; subr(16) = klr;\n    subl(17) = krl; subr(17) = krr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);\n    subl(18) = kll; subr(18) = klr;\n    subl(19) = krl; subr(19) = krr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);\n    subl(22) = kll; subr(22) = klr;\n    subl(23) = krl; subr(23) = krr;\n\n    /* generate KA */\n    kll = subl(0); klr = subr(0);\n    krl = subl(1); krr = subr(1);\n    CAMELLIA_F(kll, klr,\n\t       CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,\n\t       w0, w1, il, ir, t0, t1);\n    krl ^= w0; krr ^= w1;\n    CAMELLIA_F(krl, krr,\n\t       CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,\n\t       kll, klr, il, ir, t0, t1);\n    CAMELLIA_F(kll, klr,\n\t       CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,\n\t       krl, krr, il, ir, t0, t1);\n    krl ^= w0; krr ^= w1;\n    CAMELLIA_F(krl, krr,\n\t       CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,\n\t       w0, w1, il, ir, t0, t1);\n    kll ^= w0; klr ^= w1;\n\n    /* generate KA dependent subkeys */\n    subl(2) = kll; subr(2) = klr;\n    subl(3) = krl; subr(3) = krr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);\n    subl(6) = kll; subr(6) = klr;\n    subl(7) = krl; subr(7) = krr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);\n    subl(8) = kll; subr(8) = klr;\n    subl(9) = krl; subr(9) = krr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);\n    subl(12) = kll; subr(12) = klr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);\n    subl(14) = kll; subr(14) = klr;\n    subl(15) = krl; subr(15) = krr;\n    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);\n    subl(20) = kll; subr(20) = klr;\n    subl(21) = krl; subr(21) = krr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);\n    subl(24) = kll; subr(24) = klr;\n    subl(25) = krl; subr(25) = krr;\n\n\n    /* absorb kw2 to other subkeys */\n    subl(3) ^= subl(1); subr(3) ^= subr(1);\n    subl(5) ^= subl(1); subr(5) ^= subr(1);\n    subl(7) ^= subl(1); subr(7) ^= subr(1);\n    subl(1) ^= subr(1) & ~subr(9);\n    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);\n    subl(11) ^= subl(1); subr(11) ^= subr(1);\n    subl(13) ^= subl(1); subr(13) ^= subr(1);\n    subl(15) ^= subl(1); subr(15) ^= subr(1);\n    subl(1) ^= subr(1) & ~subr(17);\n    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);\n    subl(19) ^= subl(1); subr(19) ^= subr(1);\n    subl(21) ^= subl(1); subr(21) ^= subr(1);\n    subl(23) ^= subl(1); subr(23) ^= subr(1);\n    subl(24) ^= subl(1); subr(24) ^= subr(1);\n\n    /* absorb kw4 to other subkeys */\n    kw4l = subl(25); kw4r = subr(25);\n    subl(22) ^= kw4l; subr(22) ^= kw4r;\n    subl(20) ^= kw4l; subr(20) ^= kw4r;\n    subl(18) ^= kw4l; subr(18) ^= kw4r;\n    kw4l ^= kw4r & ~subr(16);\n    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);\n    subl(14) ^= kw4l; subr(14) ^= kw4r;\n    subl(12) ^= kw4l; subr(12) ^= kw4r;\n    subl(10) ^= kw4l; subr(10) ^= kw4r;\n    kw4l ^= kw4r & ~subr(8);\n    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);\n    subl(6) ^= kw4l; subr(6) ^= kw4r;\n    subl(4) ^= kw4l; subr(4) ^= kw4r;\n    subl(2) ^= kw4l; subr(2) ^= kw4r;\n    subl(0) ^= kw4l; subr(0) ^= kw4r;\n\n    /* key XOR is end of F-function */\n    CamelliaSubkeyL(0) = subl(0) ^ subl(2);\n    CamelliaSubkeyR(0) = subr(0) ^ subr(2);\n    CamelliaSubkeyL(2) = subl(3);\n    CamelliaSubkeyR(2) = subr(3);\n    CamelliaSubkeyL(3) = subl(2) ^ subl(4);\n    CamelliaSubkeyR(3) = subr(2) ^ subr(4);\n    CamelliaSubkeyL(4) = subl(3) ^ subl(5);\n    CamelliaSubkeyR(4) = subr(3) ^ subr(5);\n    CamelliaSubkeyL(5) = subl(4) ^ subl(6);\n    CamelliaSubkeyR(5) = subr(4) ^ subr(6);\n    CamelliaSubkeyL(6) = subl(5) ^ subl(7);\n    CamelliaSubkeyR(6) = subr(5) ^ subr(7);\n    tl = subl(10) ^ (subr(10) & ~subr(8));\n    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);\n    CamelliaSubkeyL(7) = subl(6) ^ tl;\n    CamelliaSubkeyR(7) = subr(6) ^ tr;\n    CamelliaSubkeyL(8) = subl(8);\n    CamelliaSubkeyR(8) = subr(8);\n    CamelliaSubkeyL(9) = subl(9);\n    CamelliaSubkeyR(9) = subr(9);\n    tl = subl(7) ^ (subr(7) & ~subr(9));\n    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);\n    CamelliaSubkeyL(10) = tl ^ subl(11);\n    CamelliaSubkeyR(10) = tr ^ subr(11);\n    CamelliaSubkeyL(11) = subl(10) ^ subl(12);\n    CamelliaSubkeyR(11) = subr(10) ^ subr(12);\n    CamelliaSubkeyL(12) = subl(11) ^ subl(13);\n    CamelliaSubkeyR(12) = subr(11) ^ subr(13);\n    CamelliaSubkeyL(13) = subl(12) ^ subl(14);\n    CamelliaSubkeyR(13) = subr(12) ^ subr(14);\n    CamelliaSubkeyL(14) = subl(13) ^ subl(15);\n    CamelliaSubkeyR(14) = subr(13) ^ subr(15);\n    tl = subl(18) ^ (subr(18) & ~subr(16));\n    dw = tl & subl(16),\ttr = subr(18) ^ CAMELLIA_RL1(dw);\n    CamelliaSubkeyL(15) = subl(14) ^ tl;\n    CamelliaSubkeyR(15) = subr(14) ^ tr;\n    CamelliaSubkeyL(16) = subl(16);\n    CamelliaSubkeyR(16) = subr(16);\n    CamelliaSubkeyL(17) = subl(17);\n    CamelliaSubkeyR(17) = subr(17);\n    tl = subl(15) ^ (subr(15) & ~subr(17));\n    dw = tl & subl(17),\ttr = subr(15) ^ CAMELLIA_RL1(dw);\n    CamelliaSubkeyL(18) = tl ^ subl(19);\n    CamelliaSubkeyR(18) = tr ^ subr(19);\n    CamelliaSubkeyL(19) = subl(18) ^ subl(20);\n    CamelliaSubkeyR(19) = subr(18) ^ subr(20);\n    CamelliaSubkeyL(20) = subl(19) ^ subl(21);\n    CamelliaSubkeyR(20) = subr(19) ^ subr(21);\n    CamelliaSubkeyL(21) = subl(20) ^ subl(22);\n    CamelliaSubkeyR(21) = subr(20) ^ subr(22);\n    CamelliaSubkeyL(22) = subl(21) ^ subl(23);\n    CamelliaSubkeyR(22) = subr(21) ^ subr(23);\n    CamelliaSubkeyL(23) = subl(22);\n    CamelliaSubkeyR(23) = subr(22);\n    CamelliaSubkeyL(24) = subl(24) ^ subl(23);\n    CamelliaSubkeyR(24) = subr(24) ^ subr(23);\n\n    /* apply the inverse of the last half of P-function */\n    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;\n    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;\n    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;\n    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;\n    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;\n    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;\n    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;\n    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;\n    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;\n    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;\n    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;\n    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;\n    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;\n    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;\n    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;\n    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;\n    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;\n    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(subR, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return 0;\n}\n\nstatic int camellia_setup256(const unsigned char *key, u32 *subkey)\n{\n    u32 kll,klr,krl,krr;           /* left half of key */\n    u32 krll,krlr,krrl,krrr;       /* right half of key */\n    u32 il, ir, t0, t1, w0, w1;    /* temporary variables */\n    u32 kw4l, kw4r, dw, tl, tr;\n\n#ifdef WOLFSSL_SMALL_STACK\n    u32* subL;\n    u32* subR;\n\n    subL = (u32*) XMALLOC(sizeof(u32) * 34, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (subL == NULL)\n        return MEMORY_E;\n\n    subR = (u32*) XMALLOC(sizeof(u32) * 34, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (subR == NULL) {\n        XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n#else\n    u32 subL[34];\n    u32 subR[34];\n#endif\n\n    /**\n     *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)\n     *  (|| is concatenation)\n     */\n\n    kll  = GETU32(key     );\n    klr  = GETU32(key +  4);\n    krl  = GETU32(key +  8);\n    krr  = GETU32(key + 12);\n    krll = GETU32(key + 16);\n    krlr = GETU32(key + 20);\n    krrl = GETU32(key + 24);\n    krrr = GETU32(key + 28);\n\n    /* generate KL dependent subkeys */\n    subl(0) = kll; subr(0) = klr;\n    subl(1) = krl; subr(1) = krr;\n    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);\n    subl(12) = kll; subr(12) = klr;\n    subl(13) = krl; subr(13) = krr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);\n    subl(16) = kll; subr(16) = klr;\n    subl(17) = krl; subr(17) = krr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);\n    subl(22) = kll; subr(22) = klr;\n    subl(23) = krl; subr(23) = krr;\n    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);\n    subl(30) = kll; subr(30) = klr;\n    subl(31) = krl; subr(31) = krr;\n\n    /* generate KR dependent subkeys */\n    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);\n    subl(4) = krll; subr(4) = krlr;\n    subl(5) = krrl; subr(5) = krrr;\n    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);\n    subl(8) = krll; subr(8) = krlr;\n    subl(9) = krrl; subr(9) = krrr;\n    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);\n    subl(18) = krll; subr(18) = krlr;\n    subl(19) = krrl; subr(19) = krrr;\n    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);\n    subl(26) = krll; subr(26) = krlr;\n    subl(27) = krrl; subr(27) = krrr;\n    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);\n\n    /* generate KA */\n    kll = subl(0) ^ krll; klr = subr(0) ^ krlr;\n    krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;\n    CAMELLIA_F(kll, klr,\n\t       CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,\n\t       w0, w1, il, ir, t0, t1);\n    krl ^= w0; krr ^= w1;\n    CAMELLIA_F(krl, krr,\n\t       CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,\n\t       kll, klr, il, ir, t0, t1);\n    kll ^= krll; klr ^= krlr;\n    CAMELLIA_F(kll, klr,\n\t       CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,\n\t       krl, krr, il, ir, t0, t1);\n    krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;\n    CAMELLIA_F(krl, krr,\n\t       CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,\n\t       w0, w1, il, ir, t0, t1);\n    kll ^= w0; klr ^= w1;\n\n    /* generate KB */\n    krll ^= kll; krlr ^= klr;\n    krrl ^= krl; krrr ^= krr;\n    CAMELLIA_F(krll, krlr,\n\t       CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,\n\t       w0, w1, il, ir, t0, t1);\n    krrl ^= w0; krrr ^= w1;\n    CAMELLIA_F(krrl, krrr,\n\t       CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,\n\t       w0, w1, il, ir, t0, t1);\n    krll ^= w0; krlr ^= w1;\n\n    /* generate KA dependent subkeys */\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);\n    subl(6) = kll; subr(6) = klr;\n    subl(7) = krl; subr(7) = krr;\n    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);\n    subl(14) = kll; subr(14) = klr;\n    subl(15) = krl; subr(15) = krr;\n    subl(24) = klr; subr(24) = krl;\n    subl(25) = krr; subr(25) = kll;\n    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);\n    subl(28) = kll; subr(28) = klr;\n    subl(29) = krl; subr(29) = krr;\n\n    /* generate KB dependent subkeys */\n    subl(2) = krll; subr(2) = krlr;\n    subl(3) = krrl; subr(3) = krrr;\n    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);\n    subl(10) = krll; subr(10) = krlr;\n    subl(11) = krrl; subr(11) = krrr;\n    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);\n    subl(20) = krll; subr(20) = krlr;\n    subl(21) = krrl; subr(21) = krrr;\n    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);\n    subl(32) = krll; subr(32) = krlr;\n    subl(33) = krrl; subr(33) = krrr;\n\n    /* absorb kw2 to other subkeys */\n    subl(3) ^= subl(1); subr(3) ^= subr(1);\n    subl(5) ^= subl(1); subr(5) ^= subr(1);\n    subl(7) ^= subl(1); subr(7) ^= subr(1);\n    subl(1) ^= subr(1) & ~subr(9);\n    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);\n    subl(11) ^= subl(1); subr(11) ^= subr(1);\n    subl(13) ^= subl(1); subr(13) ^= subr(1);\n    subl(15) ^= subl(1); subr(15) ^= subr(1);\n    subl(1) ^= subr(1) & ~subr(17);\n    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);\n    subl(19) ^= subl(1); subr(19) ^= subr(1);\n    subl(21) ^= subl(1); subr(21) ^= subr(1);\n    subl(23) ^= subl(1); subr(23) ^= subr(1);\n    subl(1) ^= subr(1) & ~subr(25);\n    dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);\n    subl(27) ^= subl(1); subr(27) ^= subr(1);\n    subl(29) ^= subl(1); subr(29) ^= subr(1);\n    subl(31) ^= subl(1); subr(31) ^= subr(1);\n    subl(32) ^= subl(1); subr(32) ^= subr(1);\n\n    /* absorb kw4 to other subkeys */\n    kw4l = subl(33); kw4r = subr(33);\n    subl(30) ^= kw4l; subr(30) ^= kw4r;\n    subl(28) ^= kw4l; subr(28) ^= kw4r;\n    subl(26) ^= kw4l; subr(26) ^= kw4r;\n    kw4l ^= kw4r & ~subr(24);\n    dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);\n    subl(22) ^= kw4l; subr(22) ^= kw4r;\n    subl(20) ^= kw4l; subr(20) ^= kw4r;\n    subl(18) ^= kw4l; subr(18) ^= kw4r;\n    kw4l ^= kw4r & ~subr(16);\n    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);\n    subl(14) ^= kw4l; subr(14) ^= kw4r;\n    subl(12) ^= kw4l; subr(12) ^= kw4r;\n    subl(10) ^= kw4l; subr(10) ^= kw4r;\n    kw4l ^= kw4r & ~subr(8);\n    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);\n    subl(6) ^= kw4l; subr(6) ^= kw4r;\n    subl(4) ^= kw4l; subr(4) ^= kw4r;\n    subl(2) ^= kw4l; subr(2) ^= kw4r;\n    subl(0) ^= kw4l; subr(0) ^= kw4r;\n\n    /* key XOR is end of F-function */\n    CamelliaSubkeyL(0) = subl(0) ^ subl(2);\n    CamelliaSubkeyR(0) = subr(0) ^ subr(2);\n    CamelliaSubkeyL(2) = subl(3);\n    CamelliaSubkeyR(2) = subr(3);\n    CamelliaSubkeyL(3) = subl(2) ^ subl(4);\n    CamelliaSubkeyR(3) = subr(2) ^ subr(4);\n    CamelliaSubkeyL(4) = subl(3) ^ subl(5);\n    CamelliaSubkeyR(4) = subr(3) ^ subr(5);\n    CamelliaSubkeyL(5) = subl(4) ^ subl(6);\n    CamelliaSubkeyR(5) = subr(4) ^ subr(6);\n    CamelliaSubkeyL(6) = subl(5) ^ subl(7);\n    CamelliaSubkeyR(6) = subr(5) ^ subr(7);\n    tl = subl(10) ^ (subr(10) & ~subr(8));\n    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);\n    CamelliaSubkeyL(7) = subl(6) ^ tl;\n    CamelliaSubkeyR(7) = subr(6) ^ tr;\n    CamelliaSubkeyL(8) = subl(8);\n    CamelliaSubkeyR(8) = subr(8);\n    CamelliaSubkeyL(9) = subl(9);\n    CamelliaSubkeyR(9) = subr(9);\n    tl = subl(7) ^ (subr(7) & ~subr(9));\n    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);\n    CamelliaSubkeyL(10) = tl ^ subl(11);\n    CamelliaSubkeyR(10) = tr ^ subr(11);\n    CamelliaSubkeyL(11) = subl(10) ^ subl(12);\n    CamelliaSubkeyR(11) = subr(10) ^ subr(12);\n    CamelliaSubkeyL(12) = subl(11) ^ subl(13);\n    CamelliaSubkeyR(12) = subr(11) ^ subr(13);\n    CamelliaSubkeyL(13) = subl(12) ^ subl(14);\n    CamelliaSubkeyR(13) = subr(12) ^ subr(14);\n    CamelliaSubkeyL(14) = subl(13) ^ subl(15);\n    CamelliaSubkeyR(14) = subr(13) ^ subr(15);\n    tl = subl(18) ^ (subr(18) & ~subr(16));\n    dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);\n    CamelliaSubkeyL(15) = subl(14) ^ tl;\n    CamelliaSubkeyR(15) = subr(14) ^ tr;\n    CamelliaSubkeyL(16) = subl(16);\n    CamelliaSubkeyR(16) = subr(16);\n    CamelliaSubkeyL(17) = subl(17);\n    CamelliaSubkeyR(17) = subr(17);\n    tl = subl(15) ^ (subr(15) & ~subr(17));\n    dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);\n    CamelliaSubkeyL(18) = tl ^ subl(19);\n    CamelliaSubkeyR(18) = tr ^ subr(19);\n    CamelliaSubkeyL(19) = subl(18) ^ subl(20);\n    CamelliaSubkeyR(19) = subr(18) ^ subr(20);\n    CamelliaSubkeyL(20) = subl(19) ^ subl(21);\n    CamelliaSubkeyR(20) = subr(19) ^ subr(21);\n    CamelliaSubkeyL(21) = subl(20) ^ subl(22);\n    CamelliaSubkeyR(21) = subr(20) ^ subr(22);\n    CamelliaSubkeyL(22) = subl(21) ^ subl(23);\n    CamelliaSubkeyR(22) = subr(21) ^ subr(23);\n    tl = subl(26) ^ (subr(26) & ~subr(24));\n    dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);\n    CamelliaSubkeyL(23) = subl(22) ^ tl;\n    CamelliaSubkeyR(23) = subr(22) ^ tr;\n    CamelliaSubkeyL(24) = subl(24);\n    CamelliaSubkeyR(24) = subr(24);\n    CamelliaSubkeyL(25) = subl(25);\n    CamelliaSubkeyR(25) = subr(25);\n    tl = subl(23) ^ (subr(23) &  ~subr(25));\n    dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);\n    CamelliaSubkeyL(26) = tl ^ subl(27);\n    CamelliaSubkeyR(26) = tr ^ subr(27);\n    CamelliaSubkeyL(27) = subl(26) ^ subl(28);\n    CamelliaSubkeyR(27) = subr(26) ^ subr(28);\n    CamelliaSubkeyL(28) = subl(27) ^ subl(29);\n    CamelliaSubkeyR(28) = subr(27) ^ subr(29);\n    CamelliaSubkeyL(29) = subl(28) ^ subl(30);\n    CamelliaSubkeyR(29) = subr(28) ^ subr(30);\n    CamelliaSubkeyL(30) = subl(29) ^ subl(31);\n    CamelliaSubkeyR(30) = subr(29) ^ subr(31);\n    CamelliaSubkeyL(31) = subl(30);\n    CamelliaSubkeyR(31) = subr(30);\n    CamelliaSubkeyL(32) = subl(32) ^ subl(31);\n    CamelliaSubkeyR(32) = subr(32) ^ subr(31);\n\n    /* apply the inverse of the last half of P-function */\n    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;\n    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;\n    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;\n    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;\n    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;\n    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;\n    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;\n    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;\n    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;\n    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;\n    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;\n    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;\n    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;\n    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;\n    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;\n    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;\n    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;\n    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;\n    dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw;\n    dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw;\n    dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw;\n    dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw;\n    dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;\n    dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);\n    CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw;\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(subR, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return 0;\n}\n\nstatic int camellia_setup192(const unsigned char *key, u32 *subkey)\n{\n    unsigned char kk[32];\n    u32 krll, krlr, krrl,krrr;\n\n    XMEMCPY(kk, key, 24);\n    XMEMCPY((unsigned char *)&krll, key+16,4);\n    XMEMCPY((unsigned char *)&krlr, key+20,4);\n    krrl = ~krll;\n    krrr = ~krlr;\n    XMEMCPY(kk+24, (unsigned char *)&krrl, 4);\n    XMEMCPY(kk+28, (unsigned char *)&krrr, 4);\n\n    return camellia_setup256(kk, subkey);\n}\n\n\n/**\n * Stuff related to camellia encryption/decryption\n *\n * \"io\" must be 4byte aligned and big-endian data.\n */\nstatic void camellia_encrypt128(const u32 *subkey, u32 *io)\n{\n    u32 il, ir, t0, t1;\n\n    /* pre whitening but absorb kw2*/\n    io[0] ^= CamelliaSubkeyL(0);\n    io[1] ^= CamelliaSubkeyR(0);\n    /* main iteration */\n\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(2),CamelliaSubkeyR(2),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(3),CamelliaSubkeyR(3),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(4),CamelliaSubkeyR(4),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(5),CamelliaSubkeyR(5),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(6),CamelliaSubkeyR(6),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(7),CamelliaSubkeyR(7),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    CAMELLIA_FLS(io[0],io[1],io[2],io[3],\n\t\t CamelliaSubkeyL(8),CamelliaSubkeyR(8),\n\t\t CamelliaSubkeyL(9),CamelliaSubkeyR(9),\n\t\t t0,t1,il,ir);\n\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(10),CamelliaSubkeyR(10),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(11),CamelliaSubkeyR(11),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(12),CamelliaSubkeyR(12),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(13),CamelliaSubkeyR(13),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(14),CamelliaSubkeyR(14),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(15),CamelliaSubkeyR(15),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    CAMELLIA_FLS(io[0],io[1],io[2],io[3],\n\t\t CamelliaSubkeyL(16),CamelliaSubkeyR(16),\n\t\t CamelliaSubkeyL(17),CamelliaSubkeyR(17),\n\t\t t0,t1,il,ir);\n\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(18),CamelliaSubkeyR(18),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(19),CamelliaSubkeyR(19),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(20),CamelliaSubkeyR(20),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(21),CamelliaSubkeyR(21),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(22),CamelliaSubkeyR(22),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(23),CamelliaSubkeyR(23),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    /* post whitening but kw4 */\n    io[2] ^= CamelliaSubkeyL(24);\n    io[3] ^= CamelliaSubkeyR(24);\n\n    t0 = io[0];\n    t1 = io[1];\n    io[0] = io[2];\n    io[1] = io[3];\n    io[2] = t0;\n    io[3] = t1;\n\n    return;\n}\n\nstatic void camellia_decrypt128(const u32 *subkey, u32 *io)\n{\n    u32 il,ir,t0,t1;               /* temporary variables */\n\n    /* pre whitening but absorb kw2*/\n    io[0] ^= CamelliaSubkeyL(24);\n    io[1] ^= CamelliaSubkeyR(24);\n\n    /* main iteration */\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(23),CamelliaSubkeyR(23),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(22),CamelliaSubkeyR(22),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(21),CamelliaSubkeyR(21),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(20),CamelliaSubkeyR(20),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(19),CamelliaSubkeyR(19),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(18),CamelliaSubkeyR(18),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    CAMELLIA_FLS(io[0],io[1],io[2],io[3],\n\t\t CamelliaSubkeyL(17),CamelliaSubkeyR(17),\n\t\t CamelliaSubkeyL(16),CamelliaSubkeyR(16),\n\t\t t0,t1,il,ir);\n\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(15),CamelliaSubkeyR(15),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(14),CamelliaSubkeyR(14),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(13),CamelliaSubkeyR(13),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(12),CamelliaSubkeyR(12),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(11),CamelliaSubkeyR(11),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(10),CamelliaSubkeyR(10),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    CAMELLIA_FLS(io[0],io[1],io[2],io[3],\n\t\t CamelliaSubkeyL(9),CamelliaSubkeyR(9),\n\t\t CamelliaSubkeyL(8),CamelliaSubkeyR(8),\n\t\t t0,t1,il,ir);\n\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(7),CamelliaSubkeyR(7),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(6),CamelliaSubkeyR(6),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(5),CamelliaSubkeyR(5),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(4),CamelliaSubkeyR(4),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(3),CamelliaSubkeyR(3),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(2),CamelliaSubkeyR(2),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    /* post whitening but kw4 */\n    io[2] ^= CamelliaSubkeyL(0);\n    io[3] ^= CamelliaSubkeyR(0);\n\n    t0 = io[0];\n    t1 = io[1];\n    io[0] = io[2];\n    io[1] = io[3];\n    io[2] = t0;\n    io[3] = t1;\n\n    return;\n}\n\n/**\n * stuff for 192 and 256bit encryption/decryption\n */\nstatic void camellia_encrypt256(const u32 *subkey, u32 *io)\n{\n    u32 il,ir,t0,t1;           /* temporary variables */\n\n    /* pre whitening but absorb kw2*/\n    io[0] ^= CamelliaSubkeyL(0);\n    io[1] ^= CamelliaSubkeyR(0);\n\n    /* main iteration */\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(2),CamelliaSubkeyR(2),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(3),CamelliaSubkeyR(3),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(4),CamelliaSubkeyR(4),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(5),CamelliaSubkeyR(5),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(6),CamelliaSubkeyR(6),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(7),CamelliaSubkeyR(7),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    CAMELLIA_FLS(io[0],io[1],io[2],io[3],\n\t\t CamelliaSubkeyL(8),CamelliaSubkeyR(8),\n\t\t CamelliaSubkeyL(9),CamelliaSubkeyR(9),\n\t\t t0,t1,il,ir);\n\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(10),CamelliaSubkeyR(10),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(11),CamelliaSubkeyR(11),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(12),CamelliaSubkeyR(12),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(13),CamelliaSubkeyR(13),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(14),CamelliaSubkeyR(14),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(15),CamelliaSubkeyR(15),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    CAMELLIA_FLS(io[0],io[1],io[2],io[3],\n\t\t CamelliaSubkeyL(16),CamelliaSubkeyR(16),\n\t\t CamelliaSubkeyL(17),CamelliaSubkeyR(17),\n\t\t t0,t1,il,ir);\n\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(18),CamelliaSubkeyR(18),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(19),CamelliaSubkeyR(19),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(20),CamelliaSubkeyR(20),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(21),CamelliaSubkeyR(21),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(22),CamelliaSubkeyR(22),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(23),CamelliaSubkeyR(23),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    CAMELLIA_FLS(io[0],io[1],io[2],io[3],\n\t\t CamelliaSubkeyL(24),CamelliaSubkeyR(24),\n\t\t CamelliaSubkeyL(25),CamelliaSubkeyR(25),\n\t\t t0,t1,il,ir);\n\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(26),CamelliaSubkeyR(26),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(27),CamelliaSubkeyR(27),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(28),CamelliaSubkeyR(28),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(29),CamelliaSubkeyR(29),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(30),CamelliaSubkeyR(30),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(31),CamelliaSubkeyR(31),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    /* post whitening but kw4 */\n    io[2] ^= CamelliaSubkeyL(32);\n    io[3] ^= CamelliaSubkeyR(32);\n\n    t0 = io[0];\n    t1 = io[1];\n    io[0] = io[2];\n    io[1] = io[3];\n    io[2] = t0;\n    io[3] = t1;\n\n    return;\n}\n\nstatic void camellia_decrypt256(const u32 *subkey, u32 *io)\n{\n    u32 il,ir,t0,t1;           /* temporary variables */\n\n    /* pre whitening but absorb kw2*/\n    io[0] ^= CamelliaSubkeyL(32);\n    io[1] ^= CamelliaSubkeyR(32);\n\n    /* main iteration */\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(31),CamelliaSubkeyR(31),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(30),CamelliaSubkeyR(30),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(29),CamelliaSubkeyR(29),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(28),CamelliaSubkeyR(28),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(27),CamelliaSubkeyR(27),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(26),CamelliaSubkeyR(26),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    CAMELLIA_FLS(io[0],io[1],io[2],io[3],\n\t\t CamelliaSubkeyL(25),CamelliaSubkeyR(25),\n\t\t CamelliaSubkeyL(24),CamelliaSubkeyR(24),\n\t\t t0,t1,il,ir);\n\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(23),CamelliaSubkeyR(23),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(22),CamelliaSubkeyR(22),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(21),CamelliaSubkeyR(21),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(20),CamelliaSubkeyR(20),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(19),CamelliaSubkeyR(19),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(18),CamelliaSubkeyR(18),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    CAMELLIA_FLS(io[0],io[1],io[2],io[3],\n\t\t CamelliaSubkeyL(17),CamelliaSubkeyR(17),\n\t\t CamelliaSubkeyL(16),CamelliaSubkeyR(16),\n\t\t t0,t1,il,ir);\n\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(15),CamelliaSubkeyR(15),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(14),CamelliaSubkeyR(14),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(13),CamelliaSubkeyR(13),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(12),CamelliaSubkeyR(12),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(11),CamelliaSubkeyR(11),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(10),CamelliaSubkeyR(10),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    CAMELLIA_FLS(io[0],io[1],io[2],io[3],\n\t\t CamelliaSubkeyL(9),CamelliaSubkeyR(9),\n\t\t CamelliaSubkeyL(8),CamelliaSubkeyR(8),\n\t\t t0,t1,il,ir);\n\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(7),CamelliaSubkeyR(7),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(6),CamelliaSubkeyR(6),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(5),CamelliaSubkeyR(5),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(4),CamelliaSubkeyR(4),\n\t\t     io[0],io[1],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[0],io[1],\n\t\t     CamelliaSubkeyL(3),CamelliaSubkeyR(3),\n\t\t     io[2],io[3],il,ir,t0,t1);\n    CAMELLIA_ROUNDSM(io[2],io[3],\n\t\t     CamelliaSubkeyL(2),CamelliaSubkeyR(2),\n\t\t     io[0],io[1],il,ir,t0,t1);\n\n    /* post whitening but kw4 */\n    io[2] ^= CamelliaSubkeyL(0);\n    io[3] ^= CamelliaSubkeyR(0);\n\n    t0 = io[0];\n    t1 = io[1];\n    io[0] = io[2];\n    io[1] = io[3];\n    io[2] = t0;\n    io[3] = t1;\n\n    return;\n}\n\n/***\n *\n * API for compatibility\n */\n\nstatic void Camellia_EncryptBlock(const int keyBitLength,\n\t\t\t   const unsigned char *plaintext,\n\t\t\t   const KEY_TABLE_TYPE keyTable,\n\t\t\t   unsigned char *ciphertext)\n{\n    u32 tmp[4];\n\n    tmp[0] = GETU32(plaintext);\n    tmp[1] = GETU32(plaintext + 4);\n    tmp[2] = GETU32(plaintext + 8);\n    tmp[3] = GETU32(plaintext + 12);\n\n    switch (keyBitLength) {\n    case 128:\n\tcamellia_encrypt128(keyTable, tmp);\n\tbreak;\n    case 192:\n\t/* fall through */\n    case 256:\n\tcamellia_encrypt256(keyTable, tmp);\n\tbreak;\n    default:\n\tbreak;\n    }\n\n    PUTU32(ciphertext, tmp[0]);\n    PUTU32(ciphertext + 4, tmp[1]);\n    PUTU32(ciphertext + 8, tmp[2]);\n    PUTU32(ciphertext + 12, tmp[3]);\n}\n\nstatic void Camellia_DecryptBlock(const int keyBitLength,\n\t\t\t   const unsigned char *ciphertext,\n\t\t\t   const KEY_TABLE_TYPE keyTable,\n\t\t\t   unsigned char *plaintext)\n{\n    u32 tmp[4];\n\n    tmp[0] = GETU32(ciphertext);\n    tmp[1] = GETU32(ciphertext + 4);\n    tmp[2] = GETU32(ciphertext + 8);\n    tmp[3] = GETU32(ciphertext + 12);\n\n    switch (keyBitLength) {\n    case 128:\n\tcamellia_decrypt128(keyTable, tmp);\n\tbreak;\n    case 192:\n\t/* fall through */\n    case 256:\n\tcamellia_decrypt256(keyTable, tmp);\n\tbreak;\n    default:\n\tbreak;\n    }\n    PUTU32(plaintext, tmp[0]);\n    PUTU32(plaintext + 4, tmp[1]);\n    PUTU32(plaintext + 8, tmp[2]);\n    PUTU32(plaintext + 12, tmp[3]);\n}\n\n\n\n/* wolfCrypt wrappers to the Camellia code */\n\nint wc_CamelliaSetKey(Camellia* cam, const byte* key, word32 len, const byte* iv)\n{\n    int ret = 0;\n\n    if (cam == NULL) return BAD_FUNC_ARG;\n\n    XMEMSET(cam->key, 0, sizeof(KEY_TABLE_TYPE));\n\n    switch (len) {\n        case 16:\n        \tret = camellia_setup128(key, cam->key);\n            break;\n        case 24:\n        \tret = camellia_setup192(key, cam->key);\n            break;\n        case 32:\n            ret = camellia_setup256(key, cam->key);\n            break;\n        default:\n            return BAD_FUNC_ARG;\n    }\n\n    if (ret != 0)\n        return ret;\n\n    cam->keySz = len * 8;\n\n    return wc_CamelliaSetIV(cam, iv);\n}\n\n\nint wc_CamelliaSetIV(Camellia* cam, const byte* iv)\n{\n    if (cam == NULL)\n        return BAD_FUNC_ARG;\n\n    if (iv)\n        XMEMCPY(cam->reg, iv, CAMELLIA_BLOCK_SIZE);\n    else\n        XMEMSET(cam->reg,  0, CAMELLIA_BLOCK_SIZE);\n\n    return 0;\n}\n\n\nint wc_CamelliaEncryptDirect(Camellia* cam, byte* out, const byte* in)\n{\n    if (cam == NULL || out == NULL || in == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    Camellia_EncryptBlock(cam->keySz, in, cam->key, out);\n\n    return 0;\n}\n\n\nint wc_CamelliaDecryptDirect(Camellia* cam, byte* out, const byte* in)\n{\n    if (cam == NULL || out == NULL || in == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    Camellia_DecryptBlock(cam->keySz, in, cam->key, out);\n\n    return 0;\n}\n\n\nint wc_CamelliaCbcEncrypt(Camellia* cam, byte* out, const byte* in, word32 sz)\n{\n    word32 blocks;\n    if (cam == NULL || out == NULL || in == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    blocks = sz / CAMELLIA_BLOCK_SIZE;\n\n    while (blocks--) {\n        xorbuf((byte*)cam->reg, in, CAMELLIA_BLOCK_SIZE);\n        Camellia_EncryptBlock(cam->keySz, (byte*)cam->reg,\n                                                     cam->key, (byte*)cam->reg);\n        XMEMCPY(out, cam->reg, CAMELLIA_BLOCK_SIZE);\n\n        out += CAMELLIA_BLOCK_SIZE;\n        in  += CAMELLIA_BLOCK_SIZE;\n    }\n\n    return 0;\n}\n\n\nint wc_CamelliaCbcDecrypt(Camellia* cam, byte* out, const byte* in, word32 sz)\n{\n    word32 blocks;\n    if (cam == NULL || out == NULL || in == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    blocks = sz / CAMELLIA_BLOCK_SIZE;\n\n    while (blocks--) {\n        XMEMCPY(cam->tmp, in, CAMELLIA_BLOCK_SIZE);\n        Camellia_DecryptBlock(cam->keySz, (byte*)cam->tmp, cam->key, out);\n        xorbuf(out, (byte*)cam->reg, CAMELLIA_BLOCK_SIZE);\n        XMEMCPY(cam->reg, cam->tmp, CAMELLIA_BLOCK_SIZE);\n\n        out += CAMELLIA_BLOCK_SIZE;\n        in  += CAMELLIA_BLOCK_SIZE;\n    }\n\n    return 0;\n}\n\n\n#endif /* HAVE_CAMELLIA */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/chacha.c",
    "content": "/* chacha.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*\n *  based from\n *  chacha-ref.c version 20080118\n *  D. J. Bernstein\n *  Public domain.\n */\n\n\n#ifdef WOLFSSL_ARMASM\n    /* implementation is located in wolfcrypt/src/port/arm/armv8-chacha.c */\n\n#else\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_CHACHA\n\n#include <wolfssl/wolfcrypt/chacha.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#include <wolfssl/wolfcrypt/cpuid.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#ifdef CHACHA_AEAD_TEST\n    #include <stdio.h>\n#endif\n\n#ifdef USE_INTEL_CHACHA_SPEEDUP\n    #include <emmintrin.h>\n    #include <immintrin.h>\n\n    #if defined(__GNUC__) && ((__GNUC__ < 4) || \\\n                              (__GNUC__ == 4 && __GNUC_MINOR__ <= 8))\n        #undef  NO_AVX2_SUPPORT\n        #define NO_AVX2_SUPPORT\n    #endif\n    #if defined(__clang__) && ((__clang_major__ < 3) || \\\n                               (__clang_major__ == 3 && __clang_minor__ <= 5))\n        #undef  NO_AVX2_SUPPORT\n        #define NO_AVX2_SUPPORT\n    #elif defined(__clang__) && defined(NO_AVX2_SUPPORT)\n        #undef NO_AVX2_SUPPORT\n    #endif\n\n    #ifndef NO_AVX2_SUPPORT\n        #define HAVE_INTEL_AVX2\n    #endif\n\n    static int cpuidFlagsSet = 0;\n    static int cpuidFlags = 0;\n#endif\n\n#ifdef BIG_ENDIAN_ORDER\n    #define LITTLE32(x) ByteReverseWord32(x)\n#else\n    #define LITTLE32(x) (x)\n#endif\n\n/* Number of rounds */\n#define ROUNDS  20\n\n#define U32C(v) (v##U)\n#define U32V(v) ((word32)(v) & U32C(0xFFFFFFFF))\n#define U8TO32_LITTLE(p) LITTLE32(((word32*)(p))[0])\n\n#define ROTATE(v,c) rotlFixed(v, c)\n#define XOR(v,w)    ((v) ^ (w))\n#define PLUS(v,w)   (U32V((v) + (w)))\n#define PLUSONE(v)  (PLUS((v),1))\n\n#define QUARTERROUND(a,b,c,d) \\\n  x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \\\n  x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]),12); \\\n  x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \\\n  x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7);\n\n\n/**\n  * Set up iv(nonce). Earlier versions used 64 bits instead of 96, this version\n  * uses the typical AEAD 96 bit nonce and can do record sizes of 256 GB.\n  */\nint wc_Chacha_SetIV(ChaCha* ctx, const byte* inIv, word32 counter)\n{\n    word32 temp[CHACHA_IV_WORDS];/* used for alignment of memory */\n\n#ifdef CHACHA_AEAD_TEST\n    word32 i;\n    printf(\"NONCE : \");\n    for (i = 0; i < CHACHA_IV_BYTES; i++) {\n        printf(\"%02x\", inIv[i]);\n    }\n    printf(\"\\n\\n\");\n#endif\n\n    if (ctx == NULL)\n        return BAD_FUNC_ARG;\n\n    XMEMCPY(temp, inIv, CHACHA_IV_BYTES);\n\n    ctx->X[CHACHA_IV_BYTES+0] = counter;           /* block counter */\n    ctx->X[CHACHA_IV_BYTES+1] = LITTLE32(temp[0]); /* fixed variable from nonce */\n    ctx->X[CHACHA_IV_BYTES+2] = LITTLE32(temp[1]); /* counter from nonce */\n    ctx->X[CHACHA_IV_BYTES+3] = LITTLE32(temp[2]); /* counter from nonce */\n\n    return 0;\n}\n\n/* \"expand 32-byte k\" as unsigned 32 byte */\nstatic const word32 sigma[4] = {0x61707865, 0x3320646e, 0x79622d32, 0x6b206574};\n/* \"expand 16-byte k\" as unsigned 16 byte */\nstatic const word32 tau[4] = {0x61707865, 0x3120646e, 0x79622d36, 0x6b206574};\n\n/**\n  * Key setup. 8 word iv (nonce)\n  */\nint wc_Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz)\n{\n    const word32* constants;\n    const byte*   k;\n\n#ifdef XSTREAM_ALIGN\n    word32 alignKey[8];\n#endif\n\n    if (ctx == NULL)\n        return BAD_FUNC_ARG;\n\n    if (keySz != (CHACHA_MAX_KEY_SZ/2) && keySz != CHACHA_MAX_KEY_SZ)\n        return BAD_FUNC_ARG;\n\n#ifdef XSTREAM_ALIGN\n    if ((wolfssl_word)key % 4) {\n        WOLFSSL_MSG(\"wc_ChachaSetKey unaligned key\");\n        XMEMCPY(alignKey, key, keySz);\n        k = (byte*)alignKey;\n    }\n    else {\n        k = key;\n    }\n#else\n    k = key;\n#endif /* XSTREAM_ALIGN */\n\n#ifdef CHACHA_AEAD_TEST\n    word32 i;\n    printf(\"ChaCha key used :\\n\");\n    for (i = 0; i < keySz; i++) {\n        printf(\"%02x\", key[i]);\n        if ((i + 1) % 8 == 0)\n           printf(\"\\n\");\n    }\n    printf(\"\\n\\n\");\n#endif\n\n    ctx->X[4] = U8TO32_LITTLE(k +  0);\n    ctx->X[5] = U8TO32_LITTLE(k +  4);\n    ctx->X[6] = U8TO32_LITTLE(k +  8);\n    ctx->X[7] = U8TO32_LITTLE(k + 12);\n    if (keySz == CHACHA_MAX_KEY_SZ) {\n        k += 16;\n        constants = sigma;\n    }\n    else {\n        constants = tau;\n    }\n    ctx->X[ 8] = U8TO32_LITTLE(k +  0);\n    ctx->X[ 9] = U8TO32_LITTLE(k +  4);\n    ctx->X[10] = U8TO32_LITTLE(k +  8);\n    ctx->X[11] = U8TO32_LITTLE(k + 12);\n    ctx->X[ 0] = constants[0];\n    ctx->X[ 1] = constants[1];\n    ctx->X[ 2] = constants[2];\n    ctx->X[ 3] = constants[3];\n\n    return 0;\n}\n\n/**\n  * Converts word into bytes with rotations having been done.\n  */\nstatic WC_INLINE void wc_Chacha_wordtobyte(word32 output[CHACHA_CHUNK_WORDS],\n    const word32 input[CHACHA_CHUNK_WORDS])\n{\n    word32 x[CHACHA_CHUNK_WORDS];\n    word32 i;\n\n    for (i = 0; i < CHACHA_CHUNK_WORDS; i++) {\n        x[i] = input[i];\n    }\n\n    for (i = (ROUNDS); i > 0; i -= 2) {\n        QUARTERROUND(0, 4,  8, 12)\n        QUARTERROUND(1, 5,  9, 13)\n        QUARTERROUND(2, 6, 10, 14)\n        QUARTERROUND(3, 7, 11, 15)\n        QUARTERROUND(0, 5, 10, 15)\n        QUARTERROUND(1, 6, 11, 12)\n        QUARTERROUND(2, 7,  8, 13)\n        QUARTERROUND(3, 4,  9, 14)\n    }\n\n    for (i = 0; i < CHACHA_CHUNK_WORDS; i++) {\n        x[i] = PLUS(x[i], input[i]);\n    }\n\n    for (i = 0; i < CHACHA_CHUNK_WORDS; i++) {\n        output[i] = LITTLE32(x[i]);\n    }\n}\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\nextern void chacha_encrypt_x64(ChaCha* ctx, const byte* m, byte* c,\n                               word32 bytes);\nextern void chacha_encrypt_avx1(ChaCha* ctx, const byte* m, byte* c,\n                                word32 bytes);\nextern void chacha_encrypt_avx2(ChaCha* ctx, const byte* m, byte* c,\n                                word32 bytes);\n\n#ifdef __cplusplus\n    }  /* extern \"C\" */\n#endif\n\n\n/**\n  * Encrypt a stream of bytes\n  */\nstatic void wc_Chacha_encrypt_bytes(ChaCha* ctx, const byte* m, byte* c,\n                                    word32 bytes)\n{\n    byte*  output;\n    word32 temp[CHACHA_CHUNK_WORDS]; /* used to make sure aligned */\n    word32 i;\n\n    output = (byte*)temp;\n\n    for (; bytes > 0;) {\n        wc_Chacha_wordtobyte(temp, ctx->X);\n        ctx->X[CHACHA_IV_BYTES] = PLUSONE(ctx->X[CHACHA_IV_BYTES]);\n        if (bytes <= CHACHA_CHUNK_BYTES) {\n            for (i = 0; i < bytes; ++i) {\n                c[i] = m[i] ^ output[i];\n            }\n            return;\n        }\n        for (i = 0; i < CHACHA_CHUNK_BYTES; ++i) {\n            c[i] = m[i] ^ output[i];\n        }\n        bytes -= CHACHA_CHUNK_BYTES;\n        c += CHACHA_CHUNK_BYTES;\n        m += CHACHA_CHUNK_BYTES;\n    }\n}\n\n/**\n  * API to encrypt/decrypt a message of any size.\n  */\nint wc_Chacha_Process(ChaCha* ctx, byte* output, const byte* input,\n                      word32 msglen)\n{\n    if (ctx == NULL)\n        return BAD_FUNC_ARG;\n\n#ifdef USE_INTEL_CHACHA_SPEEDUP\n    if (!cpuidFlagsSet) {\n        cpuidFlags = cpuid_get_flags();\n        cpuidFlagsSet = 1;\n    }\n\n    #ifdef HAVE_INTEL_AVX2\n    if (IS_INTEL_AVX2(cpuidFlags)) {\n        chacha_encrypt_avx2(ctx, input, output, msglen);\n        return 0;\n    }\n    #endif\n    if (IS_INTEL_AVX1(cpuidFlags)) {\n        chacha_encrypt_avx1(ctx, input, output, msglen);\n        return 0;\n    }\n    else {\n        chacha_encrypt_x64(ctx, input, output, msglen);\n        return 0;\n    }\n#endif\n    wc_Chacha_encrypt_bytes(ctx, input, output, msglen);\n\n    return 0;\n}\n\n#endif /* HAVE_CHACHA*/\n\n#endif /* WOLFSSL_ARMASM */\n"
  },
  {
    "path": "src/wolfcrypt/src/chacha20_poly1305.c",
    "content": "/* chacha.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)\n\n#include <wolfssl/wolfcrypt/chacha20_poly1305.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#include <wolfssl/wolfcrypt/chacha.h>\n#include <wolfssl/wolfcrypt/poly1305.h>\n\n#ifdef NO_INLINE\n#include <wolfssl/wolfcrypt/misc.h>\n#else\n#define WOLFSSL_MISC_INCLUDED\n#include <wolfcrypt/src/misc.c>\n#endif\n\n#ifdef CHACHA_AEAD_TEST\n#include <stdio.h>\n#endif\n\n#define CHACHA20_POLY1305_AEAD_INITIAL_COUNTER  0\n#define CHACHA20_POLY1305_MAC_PADDING_ALIGNMENT 16\n\nstatic void word32ToLittle64(const word32 inLittle32, byte outLittle64[8]);\nstatic int calculateAuthTag(\n                  const byte inAuthKey[CHACHA20_POLY1305_AEAD_KEYSIZE],\n                  const byte* inAAD, const word32 inAADLen,\n                  const byte *inCiphertext, const word32 inCiphertextLen,\n                  byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]);\n\nint wc_ChaCha20Poly1305_Encrypt(\n                const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE],\n                const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE],\n                const byte* inAAD, const word32 inAADLen,\n                const byte* inPlaintext, const word32 inPlaintextLen,\n                byte* outCiphertext,\n                byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE])\n{\n    int err;\n    byte poly1305Key[CHACHA20_POLY1305_AEAD_KEYSIZE];\n    ChaCha chaChaCtx;\n\n    /* Validate function arguments */\n\n    if (!inKey || !inIV ||\n        !inPlaintext || !inPlaintextLen ||\n        !outCiphertext ||\n        !outAuthTag)\n    {\n        return BAD_FUNC_ARG;\n    }\n\n    XMEMSET(poly1305Key, 0, sizeof(poly1305Key));\n\n    /* Create the Poly1305 key */\n    err = wc_Chacha_SetKey(&chaChaCtx, inKey, CHACHA20_POLY1305_AEAD_KEYSIZE);\n    if (err != 0) return err;\n\n    err = wc_Chacha_SetIV(&chaChaCtx, inIV,\n                           CHACHA20_POLY1305_AEAD_INITIAL_COUNTER);\n    if (err != 0) return err;\n\n    err = wc_Chacha_Process(&chaChaCtx, poly1305Key, poly1305Key,\n                             CHACHA20_POLY1305_AEAD_KEYSIZE);\n    if (err != 0) return err;\n\n    /* Encrypt the plaintext using ChaCha20 */\n    err = wc_Chacha_Process(&chaChaCtx, outCiphertext, inPlaintext,\n                            inPlaintextLen);\n    /* Calculate the Poly1305 auth tag */\n    if (err == 0)\n        err = calculateAuthTag(poly1305Key,\n                               inAAD, inAADLen,\n                               outCiphertext, inPlaintextLen,\n                               outAuthTag);\n    ForceZero(poly1305Key, sizeof(poly1305Key));\n\n    return err;\n}\n\n\nint wc_ChaCha20Poly1305_Decrypt(\n                const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE],\n                const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE],\n                const byte* inAAD, const word32 inAADLen,\n                const byte* inCiphertext, const word32 inCiphertextLen,\n                const byte inAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE],\n                byte* outPlaintext)\n{\n    int err;\n    byte poly1305Key[CHACHA20_POLY1305_AEAD_KEYSIZE];\n    ChaCha chaChaCtx;\n    byte calculatedAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE];\n\n    /* Validate function arguments */\n\n    if (!inKey || !inIV ||\n        !inCiphertext || !inCiphertextLen ||\n        !inAuthTag ||\n        !outPlaintext)\n    {\n        return BAD_FUNC_ARG;\n    }\n\n    XMEMSET(calculatedAuthTag, 0, sizeof(calculatedAuthTag));\n    XMEMSET(poly1305Key, 0, sizeof(poly1305Key));\n\n    /* Create the Poly1305 key */\n    err = wc_Chacha_SetKey(&chaChaCtx, inKey, CHACHA20_POLY1305_AEAD_KEYSIZE);\n    if (err != 0) return err;\n\n    err = wc_Chacha_SetIV(&chaChaCtx, inIV,\n                           CHACHA20_POLY1305_AEAD_INITIAL_COUNTER);\n    if (err != 0) return err;\n\n    err = wc_Chacha_Process(&chaChaCtx, poly1305Key, poly1305Key,\n                             CHACHA20_POLY1305_AEAD_KEYSIZE);\n    if (err != 0) return err;\n\n    /* Calculate the Poly1305 auth tag */\n    err = calculateAuthTag(poly1305Key,\n                           inAAD, inAADLen,\n                           inCiphertext, inCiphertextLen,\n                           calculatedAuthTag);\n\n    /* Compare the calculated auth tag with the received one */\n    if (err == 0 && ConstantCompare(inAuthTag, calculatedAuthTag,\n                                    CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE) != 0)\n    {\n        err = MAC_CMP_FAILED_E;\n    }\n\n    /* Decrypt the received ciphertext */\n    if (err == 0)\n        err = wc_Chacha_Process(&chaChaCtx, outPlaintext, inCiphertext,\n                                inCiphertextLen);\n    ForceZero(poly1305Key, sizeof(poly1305Key));\n\n    return err;\n}\n\n\nstatic int calculateAuthTag(\n                const byte inAuthKey[CHACHA20_POLY1305_AEAD_KEYSIZE],\n                const byte *inAAD, const word32 inAADLen,\n                const byte *inCiphertext, const word32 inCiphertextLen,\n                 byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE])\n{\n    int err;\n    Poly1305 poly1305Ctx;\n    byte padding[CHACHA20_POLY1305_MAC_PADDING_ALIGNMENT - 1];\n    word32 paddingLen;\n    byte little64[16];\n\n    XMEMSET(padding, 0, sizeof(padding));\n\n    /* Initialize Poly1305 */\n    err = wc_Poly1305SetKey(&poly1305Ctx, inAuthKey,\n                            CHACHA20_POLY1305_AEAD_KEYSIZE);\n    if (err)\n        return err;\n\n    /* Create the authTag by MAC'ing the following items: */\n    /* -- AAD */\n    if (inAAD && inAADLen)\n    {\n        err = wc_Poly1305Update(&poly1305Ctx, inAAD, inAADLen);\n        /* -- padding1: pad the AAD to 16 bytes */\n        paddingLen = -(int)inAADLen &\n                                  (CHACHA20_POLY1305_MAC_PADDING_ALIGNMENT - 1);\n        if (paddingLen)\n            err += wc_Poly1305Update(&poly1305Ctx, padding, paddingLen);\n\n        if (err)\n            return err;\n    }\n\n    /* -- Ciphertext */\n    err = wc_Poly1305Update(&poly1305Ctx, inCiphertext, inCiphertextLen);\n    if (err)\n        return err;\n\n    /* -- padding2: pad the ciphertext to 16 bytes */\n    paddingLen = -(int)inCiphertextLen &\n                                  (CHACHA20_POLY1305_MAC_PADDING_ALIGNMENT - 1);\n    if (paddingLen)\n    {\n        err = wc_Poly1305Update(&poly1305Ctx, padding, paddingLen);\n        if (err)\n            return err;\n    }\n\n    /* -- AAD length as a 64-bit little endian integer */\n    word32ToLittle64(inAADLen, little64);\n    /* -- Ciphertext length as a 64-bit little endian integer */\n    word32ToLittle64(inCiphertextLen, little64 + 8);\n    err = wc_Poly1305Update(&poly1305Ctx, little64, sizeof(little64));\n    if (err)\n        return err;\n\n    /* Finalize the auth tag */\n    err = wc_Poly1305Final(&poly1305Ctx, outAuthTag);\n\n    return err;\n}\n\n\nstatic void word32ToLittle64(const word32 inLittle32, byte outLittle64[8])\n{\n#ifndef WOLFSSL_X86_64_BUILD\n    XMEMSET(outLittle64 + 4, 0, 4);\n\n    outLittle64[0] = (byte)(inLittle32 & 0x000000FF);\n    outLittle64[1] = (byte)((inLittle32 & 0x0000FF00) >> 8);\n    outLittle64[2] = (byte)((inLittle32 & 0x00FF0000) >> 16);\n    outLittle64[3] = (byte)((inLittle32 & 0xFF000000) >> 24);\n#else\n    *(word64*)outLittle64 = inLittle32;\n#endif\n}\n\n\n#endif /* HAVE_CHACHA && HAVE_POLY1305 */\n"
  },
  {
    "path": "src/wolfcrypt/src/cmac.c",
    "content": "/* cmac.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)\n\n#if defined(HAVE_FIPS) && \\\n\tdefined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n\n    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */\n    #define FIPS_NO_WRAPPERS\n\n    #ifdef USE_WINDOWS_API\n        #pragma code_seg(\".fipsA$n\")\n        #pragma const_seg(\".fipsB$n\")\n    #endif\n#endif\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/aes.h>\n#include <wolfssl/wolfcrypt/cmac.h>\n\n\nstatic void ShiftAndXorRb(byte* out, byte* in)\n{\n    int i, j, xorRb;\n    int mask = 0, last = 0;\n    byte Rb = 0x87;\n\n    xorRb = (in[0] & 0x80) != 0;\n\n    for (i = 1, j = AES_BLOCK_SIZE - 1; i <= AES_BLOCK_SIZE; i++, j--) {\n        last = (in[j] & 0x80) ? 1 : 0;\n        out[j] = (byte)((in[j] << 1) | mask);\n        mask = last;\n        if (xorRb) {\n            out[j] ^= Rb;\n            Rb = 0;\n        }\n    }\n}\n\n\nint wc_InitCmac(Cmac* cmac, const byte* key, word32 keySz,\n                int type, void* unused)\n{\n    int ret;\n\n    (void)unused;\n\n    if (cmac == NULL || key == NULL || keySz == 0 || type != WC_CMAC_AES)\n        return BAD_FUNC_ARG;\n\n    XMEMSET(cmac, 0, sizeof(Cmac));\n    ret = wc_AesSetKey(&cmac->aes, key, keySz, NULL, AES_ENCRYPTION);\n    if (ret == 0) {\n        byte l[AES_BLOCK_SIZE];\n\n        XMEMSET(l, 0, AES_BLOCK_SIZE);\n        wc_AesEncryptDirect(&cmac->aes, l, l);\n        ShiftAndXorRb(cmac->k1, l);\n        ShiftAndXorRb(cmac->k2, cmac->k1);\n        ForceZero(l, AES_BLOCK_SIZE);\n    }\n    return ret;\n}\n\n\nint wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz)\n{\n    if ((cmac == NULL) || (in == NULL && inSz != 0))\n        return BAD_FUNC_ARG;\n\n    while (inSz != 0) {\n        word32 add = min(inSz, AES_BLOCK_SIZE - cmac->bufferSz);\n        XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);\n\n        cmac->bufferSz += add;\n        in += add;\n        inSz -= add;\n\n        if (cmac->bufferSz == AES_BLOCK_SIZE && inSz != 0) {\n            if (cmac->totalSz != 0)\n                xorbuf(cmac->buffer, cmac->digest, AES_BLOCK_SIZE);\n            wc_AesEncryptDirect(&cmac->aes,\n                                cmac->digest,\n                                cmac->buffer);\n            cmac->totalSz += AES_BLOCK_SIZE;\n            cmac->bufferSz = 0;\n        }\n    }\n\n    return 0;\n}\n\n\nint wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz)\n{\n    const byte* subKey;\n\n    if (cmac == NULL || out == NULL || outSz == NULL)\n        return BAD_FUNC_ARG;\n\n    if (*outSz < WC_CMAC_TAG_MIN_SZ || *outSz > WC_CMAC_TAG_MAX_SZ)\n        return BUFFER_E;\n\n    if (cmac->bufferSz == AES_BLOCK_SIZE) {\n        subKey = cmac->k1;\n    }\n    else {\n        word32 remainder = AES_BLOCK_SIZE - cmac->bufferSz;\n\n        if (remainder == 0)\n            remainder = AES_BLOCK_SIZE;\n\n        if (remainder > 1)\n            XMEMSET(cmac->buffer + AES_BLOCK_SIZE - remainder, 0, remainder);\n        cmac->buffer[AES_BLOCK_SIZE - remainder] = 0x80;\n        subKey = cmac->k2;\n    }\n    xorbuf(cmac->buffer, cmac->digest, AES_BLOCK_SIZE);\n    xorbuf(cmac->buffer, subKey, AES_BLOCK_SIZE);\n    wc_AesEncryptDirect(&cmac->aes, cmac->digest, cmac->buffer);\n\n    XMEMCPY(out, cmac->digest, *outSz);\n\n    ForceZero(cmac, sizeof(Cmac));\n\n    return 0;\n}\n\n\nint wc_AesCmacGenerate(byte* out, word32* outSz,\n                       const byte* in, word32 inSz,\n                       const byte* key, word32 keySz)\n{\n    Cmac cmac;\n    int ret;\n\n    if (out == NULL || (in == NULL && inSz > 0) || key == NULL || keySz == 0)\n        return BAD_FUNC_ARG;\n\n    ret = wc_InitCmac(&cmac, key, keySz, WC_CMAC_AES, NULL);\n    if (ret != 0)\n        return ret;\n\n    ret = wc_CmacUpdate(&cmac, in, inSz);\n    if (ret != 0)\n        return ret;\n\n    ret = wc_CmacFinal(&cmac, out, outSz);\n    if (ret != 0)\n        return ret;\n\n    return 0;\n}\n\n\nint wc_AesCmacVerify(const byte* check, word32 checkSz,\n                     const byte* in, word32 inSz,\n                     const byte* key, word32 keySz)\n{\n    byte a[AES_BLOCK_SIZE];\n    word32 aSz = sizeof(a);\n    int result;\n    int compareRet;\n\n    if (check == NULL || checkSz == 0 || (in == NULL && inSz != 0) ||\n        key == NULL || keySz == 0)\n\n        return BAD_FUNC_ARG;\n\n    XMEMSET(a, 0, aSz);\n    result = wc_AesCmacGenerate(a, &aSz, in, inSz, key, keySz);\n    compareRet = ConstantCompare(check, a, min(checkSz, aSz));\n\n    if (result == 0)\n        result = compareRet ? 1 : 0;\n\n    return result;\n}\n\n\n#endif /* WOLFSSL_CMAC && NO_AES && WOLFSSL_AES_DIRECT */\n"
  },
  {
    "path": "src/wolfcrypt/src/coding.c",
    "content": "/* coding.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifndef NO_CODING\n\n#include <wolfssl/wolfcrypt/coding.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n\n\nenum {\n    BAD         = 0xFF,  /* invalid encoding */\n    PAD         = '=',\n    PEM_LINE_SZ = 64,\n    BASE64_MIN  = 0x2B,\n    BASE16_MIN  = 0x30,\n};\n\n\nstatic\nconst byte base64Decode[] = { 62, BAD, BAD, BAD, 63,   /* + starts at 0x2B */\n                              52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n                              BAD, BAD, BAD, BAD, BAD, BAD, BAD,\n                              0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\n                              10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n                              20, 21, 22, 23, 24, 25,\n                              BAD, BAD, BAD, BAD, BAD, BAD,\n                              26, 27, 28, 29, 30, 31, 32, 33, 34, 35,\n                              36, 37, 38, 39, 40, 41, 42, 43, 44, 45,\n                              46, 47, 48, 49, 50, 51\n                            };\n\n\nint Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)\n{\n    word32 i = 0;\n    word32 j = 0;\n    word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ );\n    const byte maxIdx = (byte)sizeof(base64Decode) + BASE64_MIN - 1;\n\n    plainSz = (plainSz * 3 + 3) / 4;\n    if (plainSz > *outLen) return BAD_FUNC_ARG;\n\n    while (inLen > 3) {\n        byte b1, b2, b3;\n        byte e1 = in[j++];\n        byte e2 = in[j++];\n        byte e3 = in[j++];\n        byte e4 = in[j++];\n\n        int pad3 = 0;\n        int pad4 = 0;\n\n        if (e1 == 0)            /* end file 0's */\n            break;\n        if (e3 == PAD)\n            pad3 = 1;\n        if (e4 == PAD)\n            pad4 = 1;\n\n        if (e1 < BASE64_MIN || e2 < BASE64_MIN || e3 < BASE64_MIN || e4 < BASE64_MIN) {\n            WOLFSSL_MSG(\"Bad Base64 Decode data, too small\");\n            return ASN_INPUT_E;\n        }\n\n        if (e1 > maxIdx || e2 > maxIdx || e3 > maxIdx || e4 > maxIdx) {\n            WOLFSSL_MSG(\"Bad Base64 Decode data, too big\");\n            return ASN_INPUT_E;\n        }\n\n        if (i + 1 + !pad3 + !pad4 > *outLen) {\n            WOLFSSL_MSG(\"Bad Base64 Decode out buffer, too small\");\n            return BAD_FUNC_ARG;\n        }\n\n        e1 = base64Decode[e1 - BASE64_MIN];\n        e2 = base64Decode[e2 - BASE64_MIN];\n        e3 = (e3 == PAD) ? 0 : base64Decode[e3 - BASE64_MIN];\n        e4 = (e4 == PAD) ? 0 : base64Decode[e4 - BASE64_MIN];\n\n        b1 = (byte)((e1 << 2) | (e2 >> 4));\n        b2 = (byte)(((e2 & 0xF) << 4) | (e3 >> 2));\n        b3 = (byte)(((e3 & 0x3) << 6) | e4);\n\n        out[i++] = b1;\n        if (!pad3)\n            out[i++] = b2;\n        if (!pad4)\n            out[i++] = b3;\n        else\n            break;\n\n        inLen -= 4;\n        if (inLen && (in[j] == ' ' || in[j] == '\\r' || in[j] == '\\n')) {\n            byte endLine = in[j++];\n            inLen--;\n            while (inLen && endLine == ' ') {   /* allow trailing whitespace */\n                endLine = in[j++];\n                inLen--;\n            }\n            if (endLine == '\\r') {\n                if (inLen) {\n                    endLine = in[j++];\n                    inLen--;\n                }\n            }\n            if (endLine != '\\n') {\n                WOLFSSL_MSG(\"Bad end of line in Base64 Decode\");\n                return ASN_INPUT_E;\n            }\n        }\n    }\n/* If the output buffer has a room for an extra byte, add a null terminator */\n    if (out && *outLen > i)\n        out[i]= '\\0';\n\n    *outLen = i;\n\n    return 0;\n}\n\n\n#if defined(WOLFSSL_BASE64_ENCODE)\n\nstatic\nconst byte base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',\n                              'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',\n                              'U', 'V', 'W', 'X', 'Y', 'Z',\n                              'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',\n                              'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',\n                              'u', 'v', 'w', 'x', 'y', 'z',\n                              '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n                              '+', '/'\n                            };\n\n\n/* make sure *i (idx) won't exceed max, store and possibly escape to out,\n * raw means use e w/o decode,  0 on success */\nstatic int CEscape(int escaped, byte e, byte* out, word32* i, word32 max,\n                  int raw, int getSzOnly)\n{\n    int    doEscape = 0;\n    word32 needed = 1;\n    word32 idx = *i;\n\n    byte basic;\n    byte plus    = 0;\n    byte equals  = 0;\n    byte newline = 0;\n\n    if (raw)\n        basic = e;\n    else\n        basic = base64Encode[e];\n\n    /* check whether to escape. Only escape for EncodeEsc */\n    if (escaped == WC_ESC_NL_ENC) {\n        switch ((char)basic) {\n            case '+' :\n                plus     = 1;\n                doEscape = 1;\n                needed  += 2;\n                break;\n            case '=' :\n                equals   = 1;\n                doEscape = 1;\n                needed  += 2;\n                break;\n            case '\\n' :\n                newline  = 1;\n                doEscape = 1;\n                needed  += 2;\n                break;\n            default:\n                /* do nothing */\n                break;\n        }\n    }\n\n    /* check size */\n    if ( (idx+needed) > max && !getSzOnly) {\n        WOLFSSL_MSG(\"Escape buffer max too small\");\n        return BUFFER_E;\n    }\n\n    /* store it */\n    if (doEscape == 0) {\n        if(getSzOnly)\n            idx++;\n        else\n            out[idx++] = basic;\n    }\n    else {\n        if(getSzOnly)\n            idx+=3;\n        else {\n            out[idx++] = '%';  /* start escape */\n\n            if (plus) {\n                out[idx++] = '2';\n                out[idx++] = 'B';\n            }\n            else if (equals) {\n                out[idx++] = '3';\n                out[idx++] = 'D';\n            }\n            else if (newline) {\n                out[idx++] = '0';\n                out[idx++] = 'A';\n            }\n        }\n    }\n    *i = idx;\n\n    return 0;\n}\n\n\n/* internal worker, handles both escaped and normal line endings.\n   If out buffer is NULL, will return sz needed in outLen */\nstatic int DoBase64_Encode(const byte* in, word32 inLen, byte* out,\n                           word32* outLen, int escaped)\n{\n    int    ret = 0;\n    word32 i = 0,\n           j = 0,\n           n = 0;   /* new line counter */\n\n    int    getSzOnly = (out == NULL);\n\n    word32 outSz = (inLen + 3 - 1) / 3 * 4;\n    word32 addSz = (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ;  /* new lines */\n\n    if (escaped == WC_ESC_NL_ENC)\n        addSz *= 3;   /* instead of just \\n, we're doing %0A triplet */\n    else if (escaped == WC_NO_NL_ENC)\n        addSz = 0;    /* encode without \\n */\n\n    outSz += addSz;\n\n    /* if escaped we can't predetermine size for one pass encoding, but\n     * make sure we have enough if no escapes are in input\n     * Also need to ensure outLen valid before dereference */\n    if (!outLen || (outSz > *outLen && !getSzOnly)) return BAD_FUNC_ARG;\n\n    while (inLen > 2) {\n        byte b1 = in[j++];\n        byte b2 = in[j++];\n        byte b3 = in[j++];\n\n        /* encoded idx */\n        byte e1 = b1 >> 2;\n        byte e2 = (byte)(((b1 & 0x3) << 4) | (b2 >> 4));\n        byte e3 = (byte)(((b2 & 0xF) << 2) | (b3 >> 6));\n        byte e4 = b3 & 0x3F;\n\n        /* store */\n        ret = CEscape(escaped, e1, out, &i, *outLen, 0, getSzOnly);\n        if (ret != 0) break;\n        ret = CEscape(escaped, e2, out, &i, *outLen, 0, getSzOnly);\n        if (ret != 0) break;\n        ret = CEscape(escaped, e3, out, &i, *outLen, 0, getSzOnly);\n        if (ret != 0) break;\n        ret = CEscape(escaped, e4, out, &i, *outLen, 0, getSzOnly);\n        if (ret != 0) break;\n\n        inLen -= 3;\n\n        /* Insert newline after PEM_LINE_SZ, unless no \\n requested */\n        if (escaped != WC_NO_NL_ENC && (++n % (PEM_LINE_SZ/4)) == 0 && inLen) {\n            ret = CEscape(escaped, '\\n', out, &i, *outLen, 1, getSzOnly);\n            if (ret != 0) break;\n        }\n    }\n\n    /* last integral */\n    if (inLen && ret == 0) {\n        int twoBytes = (inLen == 2);\n\n        byte b1 = in[j++];\n        byte b2 = (twoBytes) ? in[j++] : 0;\n\n        byte e1 = b1 >> 2;\n        byte e2 = (byte)(((b1 & 0x3) << 4) | (b2 >> 4));\n        byte e3 = (byte)((b2 & 0xF) << 2);\n\n        ret = CEscape(escaped, e1, out, &i, *outLen, 0, getSzOnly);\n        if (ret == 0)\n            ret = CEscape(escaped, e2, out, &i, *outLen, 0, getSzOnly);\n        if (ret == 0) {\n            /* third */\n            if (twoBytes)\n                ret = CEscape(escaped, e3, out, &i, *outLen, 0, getSzOnly);\n            else\n                ret = CEscape(escaped, '=', out, &i, *outLen, 1, getSzOnly);\n        }\n        /* fourth always pad */\n        if (ret == 0)\n            ret = CEscape(escaped, '=', out, &i, *outLen, 1, getSzOnly);\n    }\n\n    if (ret == 0 && escaped != WC_NO_NL_ENC)\n        ret = CEscape(escaped, '\\n', out, &i, *outLen, 1, getSzOnly);\n\n    if (i != outSz && escaped != 1 && ret == 0)\n        return ASN_INPUT_E;\n/* If the output buffer has a room for an extra byte, add a null terminator */\n    if (out && *outLen > i)\n        out[i]= '\\0';\n\n    *outLen = i;\n\n    if (ret == 0)\n        return getSzOnly ? LENGTH_ONLY_E : 0;\n\n    return ret;\n}\n\n\n/* Base64 Encode, PEM style, with \\n line endings */\nint Base64_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)\n{\n    return DoBase64_Encode(in, inLen, out, outLen, WC_STD_ENC);\n}\n\n\n/* Base64 Encode, with %0A escaped line endings instead of \\n */\nint Base64_EncodeEsc(const byte* in, word32 inLen, byte* out, word32* outLen)\n{\n    return DoBase64_Encode(in, inLen, out, outLen, WC_ESC_NL_ENC);\n}\n\nint Base64_Encode_NoNl(const byte* in, word32 inLen, byte* out, word32* outLen)\n{\n    return DoBase64_Encode(in, inLen, out, outLen, WC_NO_NL_ENC);\n}\n\n#endif /* WOLFSSL_BASE64_ENCODE */\n\n\n#ifdef WOLFSSL_BASE16\n\nstatic\nconst byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\n                           BAD, BAD, BAD, BAD, BAD, BAD, BAD,\n                           10, 11, 12, 13, 14, 15,  /* upper case A-F */\n                           BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,\n                           BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,\n                           BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,\n                           BAD, BAD,  /* G - ` */\n                           10, 11, 12, 13, 14, 15   /* lower case a-f */\n                         };  /* A starts at 0x41 not 0x3A */\n\nint Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)\n{\n    word32 inIdx  = 0;\n    word32 outIdx = 0;\n\n    if (in == NULL || out == NULL || outLen == NULL)\n        return BAD_FUNC_ARG;\n\n    if (inLen == 1 && *outLen && in) {\n        byte b = in[inIdx++] - BASE16_MIN;  /* 0 starts at 0x30 */\n\n        /* sanity check */\n        if (b >=  sizeof(hexDecode)/sizeof(hexDecode[0]))\n            return ASN_INPUT_E;\n\n        b  = hexDecode[b];\n\n        if (b == BAD)\n            return ASN_INPUT_E;\n\n        out[outIdx++] = b;\n\n        *outLen = outIdx;\n        return 0;\n    }\n\n    if (inLen % 2)\n        return BAD_FUNC_ARG;\n\n    if (*outLen < (inLen / 2))\n        return BAD_FUNC_ARG;\n\n    while (inLen) {\n        byte b  = in[inIdx++] - BASE16_MIN;  /* 0 starts at 0x30 */\n        byte b2 = in[inIdx++] - BASE16_MIN;\n\n        /* sanity checks */\n        if (b >=  sizeof(hexDecode)/sizeof(hexDecode[0]))\n            return ASN_INPUT_E;\n        if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0]))\n            return ASN_INPUT_E;\n\n        b  = hexDecode[b];\n        b2 = hexDecode[b2];\n\n        if (b == BAD || b2 == BAD)\n            return ASN_INPUT_E;\n\n        out[outIdx++] = (byte)((b << 4) | b2);\n        inLen -= 2;\n    }\n\n    *outLen = outIdx;\n    return 0;\n}\n\nint Base16_Encode(const byte* in, word32 inLen, byte* out, word32* outLen)\n{\n    word32 outIdx = 0;\n    word32 i;\n    byte   hb, lb;\n\n    if (in == NULL || out == NULL || outLen == NULL)\n        return BAD_FUNC_ARG;\n\n    if (*outLen < (2 * inLen + 1))\n        return BAD_FUNC_ARG;\n\n    for (i = 0; i < inLen; i++) {\n        hb = in[i] >> 4;\n        lb = in[i] & 0x0f;\n\n        /* ASCII value */\n        hb += '0';\n        if (hb > '9')\n            hb += 7;\n\n        /* ASCII value */\n        lb += '0';\n        if (lb>'9')\n            lb += 7;\n\n        out[outIdx++] = hb;\n        out[outIdx++] = lb;\n    }\n\n    /* force 0 at this end */\n    out[outIdx++] = 0;\n\n    *outLen = outIdx;\n    return 0;\n}\n\n#endif /* WOLFSSL_BASE16 */\n\n#endif /* !NO_CODING */\n"
  },
  {
    "path": "src/wolfcrypt/src/compress.c",
    "content": "/* compress.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_LIBZ\n\n\n#include <wolfssl/wolfcrypt/compress.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#include <zlib.h>\n\n\n/* alloc user allocs to work with zlib */\nstatic void* myAlloc(void* opaque, unsigned int item, unsigned int size)\n{\n    (void)opaque;\n    return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);\n}\n\n\nstatic void myFree(void* opaque, void* memory)\n{\n    (void)opaque;\n    XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);\n}\n\n\n#ifdef HAVE_MCAPI\n    #define DEFLATE_DEFAULT_WINDOWBITS  11\n    #define DEFLATE_DEFAULT_MEMLEVEL     1\n#else\n    #define DEFLATE_DEFAULT_WINDOWBITS 15\n    #define DEFLATE_DEFAULT_MEMLEVEL    8\n#endif\n\n\n/*\n * out - pointer to destination buffer\n * outSz - size of destination buffer\n * in - pointer to source buffer to compress\n * inSz - size of source to compress\n * flags - flags to control how compress operates\n *\n * return:\n *    negative - error code\n *    positive - bytes stored in out buffer\n *\n * Note, the output buffer still needs to be larger than the input buffer.\n * The right chunk of data won't compress at all, and the lookup table will\n * add to the size of the output. The libz code says the compressed\n * buffer should be srcSz + 0.1% + 12.\n */\nint wc_Compress_ex(byte* out, word32 outSz, const byte* in, word32 inSz,\n    word32 flags, word32 windowBits)\n{\n    z_stream stream;\n    int result = 0;\n\n    stream.next_in = (Bytef*)in;\n    stream.avail_in = (uInt)inSz;\n#ifdef MAXSEG_64K\n    /* Check for source > 64K on 16-bit machine: */\n    if ((uLong)stream.avail_in != inSz) return COMPRESS_INIT_E;\n#endif\n    stream.next_out = out;\n    stream.avail_out = (uInt)outSz;\n    if ((uLong)stream.avail_out != outSz) return COMPRESS_INIT_E;\n\n    stream.zalloc = (alloc_func)myAlloc;\n    stream.zfree = (free_func)myFree;\n    stream.opaque = (voidpf)0;\n\n    if (deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,\n                     DEFLATE_DEFAULT_WINDOWBITS | windowBits,\n                     DEFLATE_DEFAULT_MEMLEVEL,\n                     flags ? Z_FIXED : Z_DEFAULT_STRATEGY) != Z_OK)\n        return COMPRESS_INIT_E;\n\n    if (deflate(&stream, Z_FINISH) != Z_STREAM_END) {\n        deflateEnd(&stream);\n        return COMPRESS_E;\n    }\n\n    result = (int)stream.total_out;\n\n    if (deflateEnd(&stream) != Z_OK)\n        result = COMPRESS_E;\n\n    return result;\n}\n\nint wc_Compress(byte* out, word32 outSz, const byte* in, word32 inSz, word32 flags)\n{\n    return wc_Compress_ex(out, outSz, in, inSz, flags, 0);\n}\n\n\n/* windowBits:\n* deflateInit() and inflateInit(), as well as deflateInit2() and inflateInit2()\n    with windowBits in 0..15 all process zlib-wrapped deflate data.\n    (See RFC 1950 and RFC 1951.)\n* deflateInit2() and inflateInit2() with negative windowBits in -1..-15 process\n    raw deflate data with no header or trailer.\n* deflateInit2() and inflateInit2() with windowBits in 16..31, i.e. 16\n    added to 0..15, process gzip-wrapped deflate data (RFC 1952).\n* inflateInit2() with windowBits in 32..47 (32 added to 0..15) will\n    automatically detect either a gzip or zlib header (but not raw deflate\n    data), and decompress accordingly.\n*/\nint wc_DeCompress_ex(byte* out, word32 outSz, const byte* in, word32 inSz,\n    int windowBits)\n/*\n * out - pointer to destination buffer\n * outSz - size of destination buffer\n * in - pointer to source buffer to compress\n * inSz - size of source to compress\n * windowBits - flags to control how decompress operates\n *\n * return:\n *    negative - error code\n *    positive - bytes stored in out buffer\n */\n{\n    z_stream stream;\n    int result = 0;\n\n    stream.next_in = (Bytef*)in;\n    stream.avail_in = (uInt)inSz;\n    /* Check for source > 64K on 16-bit machine: */\n    if ((uLong)stream.avail_in != inSz) return DECOMPRESS_INIT_E;\n\n    stream.next_out = out;\n    stream.avail_out = (uInt)outSz;\n    if ((uLong)stream.avail_out != outSz) return DECOMPRESS_INIT_E;\n\n    stream.zalloc = (alloc_func)myAlloc;\n    stream.zfree = (free_func)myFree;\n    stream.opaque = (voidpf)0;\n\n    if (inflateInit2(&stream, DEFLATE_DEFAULT_WINDOWBITS | windowBits) != Z_OK)\n        return DECOMPRESS_INIT_E;\n\n    result = inflate(&stream, Z_FINISH);\n    if (result != Z_STREAM_END) {\n        inflateEnd(&stream);\n        return DECOMPRESS_E;\n    }\n\n    result = (int)stream.total_out;\n\n    if (inflateEnd(&stream) != Z_OK)\n        result = DECOMPRESS_E;\n\n    return result;\n}\n\n\nint wc_DeCompress(byte* out, word32 outSz, const byte* in, word32 inSz)\n{\n    return wc_DeCompress_ex(out, outSz, in, inSz, 0);\n}\n\n\n#endif /* HAVE_LIBZ */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/cpuid.c",
    "content": "/* cpuid.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#include <wolfssl/wolfcrypt/cpuid.h>\n\n#if (defined(WOLFSSL_X86_64_BUILD) || defined(USE_INTEL_SPEEDUP) || \\\n     defined(WOLFSSL_AESNI)) && !defined(WOLFSSL_NO_ASM)\n    /* Each platform needs to query info type 1 from cpuid to see if aesni is\n     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts\n     */\n\n    #ifndef _MSC_VER\n        #define cpuid(reg, leaf, sub)\\\n            __asm__ __volatile__ (\"cpuid\":\\\n                \"=a\" (reg[0]), \"=b\" (reg[1]), \"=c\" (reg[2]), \"=d\" (reg[3]) :\\\n                \"a\" (leaf), \"c\"(sub));\n\n        #define XASM_LINK(f) asm(f)\n    #else\n        #include <intrin.h>\n\n        #define cpuid(a,b,c) __cpuidex((int*)a,b,c)\n\n        #define XASM_LINK(f)\n    #endif /* _MSC_VER */\n\n    #define EAX 0\n    #define EBX 1\n    #define ECX 2\n    #define EDX 3\n\n    static word32 cpuid_check = 0;\n    static word32 cpuid_flags = 0;\n\n    static word32 cpuid_flag(word32 leaf, word32 sub, word32 num, word32 bit)\n    {\n        int got_intel_cpu = 0;\n        int got_amd_cpu = 0;\n        unsigned int reg[5];\n        reg[4] = '\\0';\n        cpuid(reg, 0, 0);\n\n        /* check for Intel cpu */\n        if (XMEMCMP((char *)&(reg[EBX]), \"Genu\", 4) == 0 &&\n            XMEMCMP((char *)&(reg[EDX]), \"ineI\", 4) == 0 &&\n            XMEMCMP((char *)&(reg[ECX]), \"ntel\", 4) == 0) {\n            got_intel_cpu = 1;\n        }\n\n        /* check for AMD cpu */\n        if (XMEMCMP((char *)&(reg[EBX]), \"Auth\", 4) == 0 &&\n            XMEMCMP((char *)&(reg[EDX]), \"enti\", 4) == 0 &&\n            XMEMCMP((char *)&(reg[ECX]), \"cAMD\", 4) == 0) {\n            got_amd_cpu = 1;\n        }\n\n        if (got_intel_cpu || got_amd_cpu) {\n            cpuid(reg, leaf, sub);\n            return ((reg[num] >> bit) & 0x1);\n        }\n        return 0;\n    }\n\n\n    void cpuid_set_flags(void)\n    {\n        if (!cpuid_check) {\n            if (cpuid_flag(1, 0, ECX, 28)) { cpuid_flags |= CPUID_AVX1  ; }\n            if (cpuid_flag(7, 0, EBX,  5)) { cpuid_flags |= CPUID_AVX2  ; }\n            if (cpuid_flag(7, 0, EBX,  8)) { cpuid_flags |= CPUID_BMI2  ; }\n            if (cpuid_flag(1, 0, ECX, 30)) { cpuid_flags |= CPUID_RDRAND; }\n            if (cpuid_flag(7, 0, EBX, 18)) { cpuid_flags |= CPUID_RDSEED; }\n            if (cpuid_flag(1, 0, ECX, 25)) { cpuid_flags |= CPUID_AESNI ; }\n            if (cpuid_flag(7, 0, EBX, 19)) { cpuid_flags |= CPUID_ADX   ; }\n            cpuid_check = 1;\n        }\n    }\n\n    word32 cpuid_get_flags(void)\n    {\n        if (!cpuid_check)\n            cpuid_set_flags();\n        return cpuid_flags;\n    }\n#endif\n"
  },
  {
    "path": "src/wolfcrypt/src/cryptocb.c",
    "content": "/* cryptocb.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n/* This framework provides a central place for crypto hardware integration\n   using the devId scheme. If not supported return `CRYPTOCB_UNAVAILABLE`. */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef WOLF_CRYPTO_CB\n\n#include <wolfssl/wolfcrypt/cryptocb.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n\n\n/* TODO: Consider linked list with mutex */\n#ifndef MAX_CRYPTO_DEVID_CALLBACKS\n#define MAX_CRYPTO_DEVID_CALLBACKS 8\n#endif\n\ntypedef struct CryptoCb {\n    int devId;\n    CryptoDevCallbackFunc cb;\n    void* ctx;\n} CryptoCb;\nstatic WOLFSSL_GLOBAL CryptoCb gCryptoDev[MAX_CRYPTO_DEVID_CALLBACKS];\n\nstatic CryptoCb* wc_CryptoCb_FindDevice(int devId)\n{\n    int i;\n    for (i=0; i<MAX_CRYPTO_DEVID_CALLBACKS; i++) {\n        if (gCryptoDev[i].devId == devId)\n            return &gCryptoDev[i];\n    }\n    return NULL;\n}\nstatic CryptoCb* wc_CryptoCb_FindDeviceByIndex(int startIdx)\n{\n    int i;\n    for (i=startIdx; i<MAX_CRYPTO_DEVID_CALLBACKS; i++) {\n        if (gCryptoDev[i].devId != INVALID_DEVID)\n            return &gCryptoDev[i];\n    }\n    return NULL;\n}\n\nstatic WC_INLINE int wc_CryptoCb_TranslateErrorCode(int ret)\n{\n    if (ret == NOT_COMPILED_IN) {\n        /* backwards compatibility for older NOT_COMPILED_IN syntax */\n        ret = CRYPTOCB_UNAVAILABLE;\n    }\n    return ret;\n}\n\nvoid wc_CryptoCb_Init(void)\n{\n    int i;\n    for (i=0; i<MAX_CRYPTO_DEVID_CALLBACKS; i++) {\n        gCryptoDev[i].devId = INVALID_DEVID;\n    }\n}\n\nint wc_CryptoCb_RegisterDevice(int devId, CryptoDevCallbackFunc cb, void* ctx)\n{\n    /* find existing or new */\n    CryptoCb* dev = wc_CryptoCb_FindDevice(devId);\n    if (dev == NULL)\n        dev = wc_CryptoCb_FindDevice(INVALID_DEVID);\n\n    if (dev == NULL)\n        return BUFFER_E; /* out of devices */\n\n    dev->devId = devId;\n    dev->cb = cb;\n    dev->ctx = ctx;\n\n    return 0;\n}\n\nvoid wc_CryptoCb_UnRegisterDevice(int devId)\n{\n    CryptoCb* dev = wc_CryptoCb_FindDevice(devId);\n    if (dev) {\n        XMEMSET(dev, 0, sizeof(*dev));\n        dev->devId = INVALID_DEVID;\n    }\n}\n\n#ifndef NO_RSA\nint wc_CryptoCb_Rsa(const byte* in, word32 inLen, byte* out,\n    word32* outLen, int type, RsaKey* key, WC_RNG* rng)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    if (key == NULL)\n        return ret;\n\n    /* locate registered callback */\n    dev = wc_CryptoCb_FindDevice(key->devId);\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_PK;\n        cryptoInfo.pk.type = WC_PK_TYPE_RSA;\n        cryptoInfo.pk.rsa.in = in;\n        cryptoInfo.pk.rsa.inLen = inLen;\n        cryptoInfo.pk.rsa.out = out;\n        cryptoInfo.pk.rsa.outLen = outLen;\n        cryptoInfo.pk.rsa.type = type;\n        cryptoInfo.pk.rsa.key = key;\n        cryptoInfo.pk.rsa.rng = rng;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n\n#ifdef WOLFSSL_KEY_GEN\nint wc_CryptoCb_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    if (key == NULL)\n        return ret;\n\n    /* locate registered callback */\n    dev = wc_CryptoCb_FindDevice(key->devId);\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_PK;\n        cryptoInfo.pk.type = WC_PK_TYPE_RSA_KEYGEN;\n        cryptoInfo.pk.rsakg.key = key;\n        cryptoInfo.pk.rsakg.size = size;\n        cryptoInfo.pk.rsakg.e = e;\n        cryptoInfo.pk.rsakg.rng = rng;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n#endif\n#endif /* !NO_RSA */\n\n#ifdef HAVE_ECC\nint wc_CryptoCb_MakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, int curveId)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    if (key == NULL)\n        return ret;\n\n    /* locate registered callback */\n    dev = wc_CryptoCb_FindDevice(key->devId);\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_PK;\n        cryptoInfo.pk.type = WC_PK_TYPE_EC_KEYGEN;\n        cryptoInfo.pk.eckg.rng = rng;\n        cryptoInfo.pk.eckg.size = keySize;\n        cryptoInfo.pk.eckg.key = key;\n        cryptoInfo.pk.eckg.curveId = curveId;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n\nint wc_CryptoCb_Ecdh(ecc_key* private_key, ecc_key* public_key,\n    byte* out, word32* outlen)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    if (private_key == NULL)\n        return ret;\n\n    /* locate registered callback */\n    dev = wc_CryptoCb_FindDevice(private_key->devId);\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_PK;\n        cryptoInfo.pk.type = WC_PK_TYPE_ECDH;\n        cryptoInfo.pk.ecdh.private_key = private_key;\n        cryptoInfo.pk.ecdh.public_key = public_key;\n        cryptoInfo.pk.ecdh.out = out;\n        cryptoInfo.pk.ecdh.outlen = outlen;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n\nint wc_CryptoCb_EccSign(const byte* in, word32 inlen, byte* out,\n    word32 *outlen, WC_RNG* rng, ecc_key* key)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    if (key == NULL)\n        return ret;\n\n    /* locate registered callback */\n    dev = wc_CryptoCb_FindDevice(key->devId);\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_PK;\n        cryptoInfo.pk.type = WC_PK_TYPE_ECDSA_SIGN;\n        cryptoInfo.pk.eccsign.in = in;\n        cryptoInfo.pk.eccsign.inlen = inlen;\n        cryptoInfo.pk.eccsign.out = out;\n        cryptoInfo.pk.eccsign.outlen = outlen;\n        cryptoInfo.pk.eccsign.rng = rng;\n        cryptoInfo.pk.eccsign.key = key;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n\nint wc_CryptoCb_EccVerify(const byte* sig, word32 siglen,\n    const byte* hash, word32 hashlen, int* res, ecc_key* key)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    if (key == NULL)\n        return ret;\n\n    /* locate registered callback */\n    dev = wc_CryptoCb_FindDevice(key->devId);\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_PK;\n        cryptoInfo.pk.type = WC_PK_TYPE_ECDSA_VERIFY;\n        cryptoInfo.pk.eccverify.sig = sig;\n        cryptoInfo.pk.eccverify.siglen = siglen;\n        cryptoInfo.pk.eccverify.hash = hash;\n        cryptoInfo.pk.eccverify.hashlen = hashlen;\n        cryptoInfo.pk.eccverify.res = res;\n        cryptoInfo.pk.eccverify.key = key;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n#endif /* HAVE_ECC */\n\n#ifndef NO_AES\n#ifdef HAVE_AESGCM\nint wc_CryptoCb_AesGcmEncrypt(Aes* aes, byte* out,\n                               const byte* in, word32 sz,\n                               const byte* iv, word32 ivSz,\n                               byte* authTag, word32 authTagSz,\n                               const byte* authIn, word32 authInSz)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    /* locate registered callback */\n    if (aes) {\n        dev = wc_CryptoCb_FindDevice(aes->devId);\n    }\n    else {\n        /* locate first callback and try using it */\n        dev = wc_CryptoCb_FindDeviceByIndex(0);\n    }\n\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_CIPHER;\n        cryptoInfo.cipher.type = WC_CIPHER_AES_GCM;\n        cryptoInfo.cipher.enc = 1;\n        cryptoInfo.cipher.aesgcm_enc.aes       = aes;\n        cryptoInfo.cipher.aesgcm_enc.out       = out;\n        cryptoInfo.cipher.aesgcm_enc.in        = in;\n        cryptoInfo.cipher.aesgcm_enc.sz        = sz;\n        cryptoInfo.cipher.aesgcm_enc.iv        = iv;\n        cryptoInfo.cipher.aesgcm_enc.ivSz      = ivSz;\n        cryptoInfo.cipher.aesgcm_enc.authTag   = authTag;\n        cryptoInfo.cipher.aesgcm_enc.authTagSz = authTagSz;\n        cryptoInfo.cipher.aesgcm_enc.authIn    = authIn;\n        cryptoInfo.cipher.aesgcm_enc.authInSz  = authInSz;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n\nint wc_CryptoCb_AesGcmDecrypt(Aes* aes, byte* out,\n                               const byte* in, word32 sz,\n                               const byte* iv, word32 ivSz,\n                               const byte* authTag, word32 authTagSz,\n                               const byte* authIn, word32 authInSz)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    /* locate registered callback */\n    if (aes) {\n        dev = wc_CryptoCb_FindDevice(aes->devId);\n    }\n    else {\n        /* locate first callback and try using it */\n        dev = wc_CryptoCb_FindDeviceByIndex(0);\n    }\n\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_CIPHER;\n        cryptoInfo.cipher.type = WC_CIPHER_AES_GCM;\n        cryptoInfo.cipher.enc = 0;\n        cryptoInfo.cipher.aesgcm_dec.aes       = aes;\n        cryptoInfo.cipher.aesgcm_dec.out       = out;\n        cryptoInfo.cipher.aesgcm_dec.in        = in;\n        cryptoInfo.cipher.aesgcm_dec.sz        = sz;\n        cryptoInfo.cipher.aesgcm_dec.iv        = iv;\n        cryptoInfo.cipher.aesgcm_dec.ivSz      = ivSz;\n        cryptoInfo.cipher.aesgcm_dec.authTag   = authTag;\n        cryptoInfo.cipher.aesgcm_dec.authTagSz = authTagSz;\n        cryptoInfo.cipher.aesgcm_dec.authIn    = authIn;\n        cryptoInfo.cipher.aesgcm_dec.authInSz  = authInSz;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n#endif /* HAVE_AESGCM */\n\n#ifdef HAVE_AES_CBC\nint wc_CryptoCb_AesCbcEncrypt(Aes* aes, byte* out,\n                               const byte* in, word32 sz)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    /* locate registered callback */\n    if (aes) {\n        dev = wc_CryptoCb_FindDevice(aes->devId);\n    }\n    else {\n        /* locate first callback and try using it */\n        dev = wc_CryptoCb_FindDeviceByIndex(0);\n    }\n\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_CIPHER;\n        cryptoInfo.cipher.type = WC_CIPHER_AES_CBC;\n        cryptoInfo.cipher.enc = 1;\n        cryptoInfo.cipher.aescbc.aes = aes;\n        cryptoInfo.cipher.aescbc.out = out;\n        cryptoInfo.cipher.aescbc.in = in;\n        cryptoInfo.cipher.aescbc.sz = sz;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n\nint wc_CryptoCb_AesCbcDecrypt(Aes* aes, byte* out,\n                               const byte* in, word32 sz)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    /* locate registered callback */\n    if (aes) {\n        dev = wc_CryptoCb_FindDevice(aes->devId);\n    }\n    else {\n        /* locate first callback and try using it */\n        dev = wc_CryptoCb_FindDeviceByIndex(0);\n    }\n\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_CIPHER;\n        cryptoInfo.cipher.type = WC_CIPHER_AES_CBC;\n        cryptoInfo.cipher.enc = 0;\n        cryptoInfo.cipher.aescbc.aes = aes;\n        cryptoInfo.cipher.aescbc.out = out;\n        cryptoInfo.cipher.aescbc.in = in;\n        cryptoInfo.cipher.aescbc.sz = sz;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n#endif /* HAVE_AES_CBC */\n#endif /* !NO_AES */\n\n#ifndef NO_DES3\nint wc_CryptoCb_Des3Encrypt(Des3* des3, byte* out,\n                               const byte* in, word32 sz)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    /* locate registered callback */\n    if (des3) {\n        dev = wc_CryptoCb_FindDevice(des3->devId);\n    }\n    else {\n        /* locate first callback and try using it */\n        dev = wc_CryptoCb_FindDeviceByIndex(0);\n    }\n\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_CIPHER;\n        cryptoInfo.cipher.type = WC_CIPHER_DES3;\n        cryptoInfo.cipher.enc = 1;\n        cryptoInfo.cipher.des3.des = des3;\n        cryptoInfo.cipher.des3.out = out;\n        cryptoInfo.cipher.des3.in = in;\n        cryptoInfo.cipher.des3.sz = sz;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n\nint wc_CryptoCb_Des3Decrypt(Des3* des3, byte* out,\n                               const byte* in, word32 sz)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    /* locate registered callback */\n    if (des3) {\n        dev = wc_CryptoCb_FindDevice(des3->devId);\n    }\n    else {\n        /* locate first callback and try using it */\n        dev = wc_CryptoCb_FindDeviceByIndex(0);\n    }\n\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_CIPHER;\n        cryptoInfo.cipher.type = WC_CIPHER_DES3;\n        cryptoInfo.cipher.enc = 0;\n        cryptoInfo.cipher.des3.des = des3;\n        cryptoInfo.cipher.des3.out = out;\n        cryptoInfo.cipher.des3.in = in;\n        cryptoInfo.cipher.des3.sz = sz;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n#endif /* !NO_DES3 */\n\n#ifndef NO_SHA\nint wc_CryptoCb_ShaHash(wc_Sha* sha, const byte* in,\n    word32 inSz, byte* digest)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    /* locate registered callback */\n    if (sha) {\n        dev = wc_CryptoCb_FindDevice(sha->devId);\n    }\n    else {\n        /* locate first callback and try using it */\n        dev = wc_CryptoCb_FindDeviceByIndex(0);\n    }\n\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_HASH;\n        cryptoInfo.hash.type = WC_HASH_TYPE_SHA;\n        cryptoInfo.hash.sha1 = sha;\n        cryptoInfo.hash.in = in;\n        cryptoInfo.hash.inSz = inSz;\n        cryptoInfo.hash.digest = digest;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n#endif /* !NO_SHA */\n\n#ifndef NO_SHA256\nint wc_CryptoCb_Sha256Hash(wc_Sha256* sha256, const byte* in,\n    word32 inSz, byte* digest)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    /* locate registered callback */\n    if (sha256) {\n        dev = wc_CryptoCb_FindDevice(sha256->devId);\n    }\n    else {\n        /* locate first callback and try using it */\n        dev = wc_CryptoCb_FindDeviceByIndex(0);\n    }\n\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_HASH;\n        cryptoInfo.hash.type = WC_HASH_TYPE_SHA256;\n        cryptoInfo.hash.sha256 = sha256;\n        cryptoInfo.hash.in = in;\n        cryptoInfo.hash.inSz = inSz;\n        cryptoInfo.hash.digest = digest;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n#endif /* !NO_SHA256 */\n\n#ifndef NO_HMAC\nint wc_CryptoCb_Hmac(Hmac* hmac, int macType, const byte* in, word32 inSz,\n    byte* digest)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    if (hmac == NULL)\n        return ret;\n\n    /* locate registered callback */\n    dev = wc_CryptoCb_FindDevice(hmac->devId);\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_HMAC;\n        cryptoInfo.hmac.macType = macType;\n        cryptoInfo.hmac.in = in;\n        cryptoInfo.hmac.inSz = inSz;\n        cryptoInfo.hmac.digest = digest;\n        cryptoInfo.hmac.hmac = hmac;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n#endif /* !NO_HMAC */\n\n#ifndef WC_NO_RNG\nint wc_CryptoCb_RandomBlock(WC_RNG* rng, byte* out, word32 sz)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    /* locate registered callback */\n    if (rng) {\n        dev = wc_CryptoCb_FindDevice(rng->devId);\n    }\n    else {\n        /* locate first callback and try using it */\n        dev = wc_CryptoCb_FindDeviceByIndex(0);\n    }\n\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_RNG;\n        cryptoInfo.rng.rng = rng;\n        cryptoInfo.rng.out = out;\n        cryptoInfo.rng.sz = sz;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n\nint wc_CryptoCb_RandomSeed(OS_Seed* os, byte* seed, word32 sz)\n{\n    int ret = CRYPTOCB_UNAVAILABLE;\n    CryptoCb* dev;\n\n    /* locate registered callback */\n    dev = wc_CryptoCb_FindDevice(os->devId);\n    if (dev && dev->cb) {\n        wc_CryptoInfo cryptoInfo;\n        XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));\n        cryptoInfo.algo_type = WC_ALGO_TYPE_SEED;\n        cryptoInfo.seed.os = os;\n        cryptoInfo.seed.seed = seed;\n        cryptoInfo.seed.sz = sz;\n\n        ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);\n    }\n\n    return wc_CryptoCb_TranslateErrorCode(ret);\n}\n#endif /* !WC_NO_RNG */\n\n#endif /* WOLF_CRYPTO_CB */\n"
  },
  {
    "path": "src/wolfcrypt/src/curve25519.c",
    "content": "/* curve25519.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n /* Based On Daniel J Bernstein's curve25519 Public Domain ref10 work. */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_CURVE25519\n\n#include <wolfssl/wolfcrypt/curve25519.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#if defined(FREESCALE_LTC_ECC)\n    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>\n#endif\n\nconst curve25519_set_type curve25519_sets[] = {\n    {\n        CURVE25519_KEYSIZE,\n        \"CURVE25519\",\n    }\n};\n\nint wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)\n{\n#ifdef FREESCALE_LTC_ECC\n    const ECPoint* basepoint = wc_curve25519_GetBasePoint();\n#else\n    unsigned char basepoint[CURVE25519_KEYSIZE] = {9};\n#endif\n    int  ret;\n\n    if (key == NULL || rng == NULL)\n        return BAD_FUNC_ARG;\n\n    /* currently only a key size of 32 bytes is used */\n    if (keysize != CURVE25519_KEYSIZE)\n        return ECC_BAD_ARG_E;\n\n#ifndef FREESCALE_LTC_ECC\n    fe_init();\n#endif\n\n    /* random number for private key */\n    ret = wc_RNG_GenerateBlock(rng, key->k.point, keysize);\n    if (ret != 0)\n        return ret;\n\n    /* Clamp the private key */\n    key->k.point[0] &= 248;\n    key->k.point[CURVE25519_KEYSIZE-1] &= 63; /* same &=127 because |=64 after */\n    key->k.point[CURVE25519_KEYSIZE-1] |= 64;\n\n    /* compute public key */\n    #ifdef FREESCALE_LTC_ECC\n        ret = wc_curve25519(&key->p, key->k.point, basepoint, kLTC_Weierstrass); /* input basepoint on Weierstrass curve */\n    #else\n        ret = curve25519(key->p.point, key->k.point, basepoint);\n    #endif\n    if (ret != 0) {\n        ForceZero(key->k.point, keysize);\n        ForceZero(key->p.point, keysize);\n        return ret;\n    }\n\n    return ret;\n}\n\n#ifdef HAVE_CURVE25519_SHARED_SECRET\n\nint wc_curve25519_shared_secret(curve25519_key* private_key,\n                                curve25519_key* public_key,\n                                byte* out, word32* outlen)\n{\n    return wc_curve25519_shared_secret_ex(private_key, public_key,\n                                          out, outlen, EC25519_BIG_ENDIAN);\n}\n\nint wc_curve25519_shared_secret_ex(curve25519_key* private_key,\n                                   curve25519_key* public_key,\n                                   byte* out, word32* outlen, int endian)\n{\n    #ifdef FREESCALE_LTC_ECC\n        ECPoint o = {{0}};\n    #else\n        unsigned char o[CURVE25519_KEYSIZE];\n    #endif\n    int ret = 0;\n\n    /* sanity check */\n    if (private_key == NULL || public_key == NULL ||\n        out == NULL || outlen == NULL || *outlen < CURVE25519_KEYSIZE)\n        return BAD_FUNC_ARG;\n\n    /* avoid implementation fingerprinting */\n    if (public_key->p.point[CURVE25519_KEYSIZE-1] > 0x7F)\n        return ECC_BAD_ARG_E;\n\n    #ifdef FREESCALE_LTC_ECC\n        ret = wc_curve25519(&o, private_key->k.point, &public_key->p, kLTC_Curve25519 /* input point P on Curve25519 */);\n    #else\n        ret = curve25519(o, private_key->k.point, public_key->p.point);\n    #endif\n    if (ret != 0) {\n        #ifdef FREESCALE_LTC_ECC\n            ForceZero(o.point, CURVE25519_KEYSIZE);\n            ForceZero(o.pointY, CURVE25519_KEYSIZE);\n        #else\n            ForceZero(o, CURVE25519_KEYSIZE);\n        #endif\n        return ret;\n    }\n\n    if (endian == EC25519_BIG_ENDIAN) {\n        int i;\n        /* put shared secret key in Big Endian format */\n        for (i = 0; i < CURVE25519_KEYSIZE; i++)\n            #ifdef FREESCALE_LTC_ECC\n                out[i] = o.point[CURVE25519_KEYSIZE - i -1];\n            #else\n                out[i] = o[CURVE25519_KEYSIZE - i -1];\n            #endif\n    }\n    else /* put shared secret key in Little Endian format */\n        #ifdef FREESCALE_LTC_ECC\n            XMEMCPY(out, o.point, CURVE25519_KEYSIZE);\n        #else\n            XMEMCPY(out, o, CURVE25519_KEYSIZE);\n        #endif\n\n    *outlen = CURVE25519_KEYSIZE;\n\n    #ifdef FREESCALE_LTC_ECC\n        ForceZero(o.point, CURVE25519_KEYSIZE);\n        ForceZero(o.pointY, CURVE25519_KEYSIZE);\n    #else\n        ForceZero(o, CURVE25519_KEYSIZE);\n    #endif\n\n    return ret;\n}\n\n#endif /* HAVE_CURVE25519_SHARED_SECRET */\n\n#ifdef HAVE_CURVE25519_KEY_EXPORT\n\n/* export curve25519 public key (Big endian)\n * return 0 on success */\nint wc_curve25519_export_public(curve25519_key* key, byte* out, word32* outLen)\n{\n    return wc_curve25519_export_public_ex(key, out, outLen, EC25519_BIG_ENDIAN);\n}\n\n/* export curve25519 public key (Big or Little endian)\n * return 0 on success */\nint wc_curve25519_export_public_ex(curve25519_key* key, byte* out,\n                                   word32* outLen, int endian)\n{\n    if (key == NULL || out == NULL || outLen == NULL)\n        return BAD_FUNC_ARG;\n\n    /* check and set outgoing key size */\n    if (*outLen < CURVE25519_KEYSIZE) {\n        *outLen = CURVE25519_KEYSIZE;\n        return ECC_BAD_ARG_E;\n    }\n    *outLen = CURVE25519_KEYSIZE;\n\n    if (endian == EC25519_BIG_ENDIAN) {\n        int i;\n\n        /* read keys in Big Endian format */\n        for (i = 0; i < CURVE25519_KEYSIZE; i++)\n            out[i] = key->p.point[CURVE25519_KEYSIZE - i - 1];\n    }\n    else\n        XMEMCPY(out, key->p.point, CURVE25519_KEYSIZE);\n\n    return 0;\n}\n\n#endif /* HAVE_CURVE25519_KEY_EXPORT */\n\n#ifdef HAVE_CURVE25519_KEY_IMPORT\n\n/* import curve25519 public key (Big endian)\n *  return 0 on success */\nint wc_curve25519_import_public(const byte* in, word32 inLen,\n                                curve25519_key* key)\n{\n    return wc_curve25519_import_public_ex(in, inLen, key, EC25519_BIG_ENDIAN);\n}\n\n/* import curve25519 public key (Big or Little endian)\n * return 0 on success */\nint wc_curve25519_import_public_ex(const byte* in, word32 inLen,\n                                curve25519_key* key, int endian)\n{\n    /* sanity check */\n    if (key == NULL || in == NULL)\n        return BAD_FUNC_ARG;\n\n    /* check size of incoming keys */\n    if (inLen != CURVE25519_KEYSIZE)\n       return ECC_BAD_ARG_E;\n\n    if (endian == EC25519_BIG_ENDIAN) {\n        int i;\n\n        /* read keys in Big Endian format */\n        for (i = 0; i < CURVE25519_KEYSIZE; i++)\n            key->p.point[i] = in[CURVE25519_KEYSIZE - i - 1];\n    }\n    else\n        XMEMCPY(key->p.point, in, inLen);\n\n    key->dp = &curve25519_sets[0];\n\n    /* LTC needs also Y coordinate - let's compute it */\n    #ifdef FREESCALE_LTC_ECC\n        ltc_pkha_ecc_point_t ltcPoint;\n        ltcPoint.X = &key->p.point[0];\n        ltcPoint.Y = &key->p.pointY[0];\n        LTC_PKHA_Curve25519ComputeY(&ltcPoint);\n    #endif\n\n    return 0;\n}\n\n/* Check the public key value (big or little endian)\n *\n * pub     Public key bytes.\n * pubSz   Size of public key in bytes.\n * endian  Public key bytes passed in as big-endian or little-endian.\n * returns BAD_FUNC_ARGS when pub is NULL,\n *         BUFFER_E when size of public key is zero;\n *         ECC_OUT_OF_RANGE_E if the high bit is set;\n *         ECC_BAD_ARG_E if key length is not 32 bytes, public key value is\n *         zero or one; and\n *         0 otherwise.\n */\nint wc_curve25519_check_public(const byte* pub, word32 pubSz, int endian)\n{\n    word32 i;\n\n    if (pub == NULL)\n        return BAD_FUNC_ARG;\n\n    /* Check for empty key data */\n    if (pubSz == 0)\n        return BUFFER_E;\n\n    /* Check key length */\n    if (pubSz != CURVE25519_KEYSIZE)\n        return ECC_BAD_ARG_E;\n\n\n    if (endian == EC25519_LITTLE_ENDIAN) {\n        /* Check for value of zero or one */\n        for (i = pubSz - 1; i > 0; i--) {\n            if (pub[i] != 0)\n                break;\n        }\n        if (i == 0 && (pub[0] == 0 || pub[0] == 1))\n            return ECC_BAD_ARG_E;\n\n        /* Check high bit set */\n        if (pub[CURVE25519_KEYSIZE-1] & 0x80)\n            return ECC_OUT_OF_RANGE_E;\n    }\n    else {\n        /* Check for value of zero or one */\n        for (i = 0; i < pubSz-1; i++) {\n            if (pub[i] != 0)\n                break;\n        }\n        if (i == pubSz - 1 && (pub[i] == 0 || pub[i] == 1))\n            return ECC_BAD_ARG_E;\n\n        /* Check high bit set */\n        if (pub[0] & 0x80)\n            return ECC_OUT_OF_RANGE_E;\n    }\n\n    return 0;\n}\n\n#endif /* HAVE_CURVE25519_KEY_IMPORT */\n\n\n#ifdef HAVE_CURVE25519_KEY_EXPORT\n\n/* export curve25519 private key only raw (Big endian)\n * outLen is in/out size\n * return 0 on success */\nint wc_curve25519_export_private_raw(curve25519_key* key, byte* out,\n                                     word32* outLen)\n{\n    return wc_curve25519_export_private_raw_ex(key, out, outLen,\n                                               EC25519_BIG_ENDIAN);\n}\n\n/* export curve25519 private key only raw (Big or Little endian)\n * outLen is in/out size\n * return 0 on success */\nint wc_curve25519_export_private_raw_ex(curve25519_key* key, byte* out,\n                                        word32* outLen, int endian)\n{\n    /* sanity check */\n    if (key == NULL || out == NULL || outLen == NULL)\n        return BAD_FUNC_ARG;\n\n    /* check size of outgoing buffer */\n    if (*outLen < CURVE25519_KEYSIZE) {\n        *outLen = CURVE25519_KEYSIZE;\n        return ECC_BAD_ARG_E;\n    }\n    *outLen = CURVE25519_KEYSIZE;\n\n    if (endian == EC25519_BIG_ENDIAN) {\n        int i;\n\n        /* put the key in Big Endian format */\n        for (i = 0; i < CURVE25519_KEYSIZE; i++)\n            out[i] = key->k.point[CURVE25519_KEYSIZE - i - 1];\n    }\n    else\n        XMEMCPY(out, key->k.point, CURVE25519_KEYSIZE);\n\n    return 0;\n}\n\n/* curve25519 key pair export (Big or Little endian)\n * return 0 on success */\nint wc_curve25519_export_key_raw(curve25519_key* key,\n                                 byte* priv, word32 *privSz,\n                                 byte* pub, word32 *pubSz)\n{\n    return wc_curve25519_export_key_raw_ex(key, priv, privSz,\n                                           pub, pubSz, EC25519_BIG_ENDIAN);\n}\n\n/* curve25519 key pair export (Big or Little endian)\n * return 0 on success */\nint wc_curve25519_export_key_raw_ex(curve25519_key* key,\n                                    byte* priv, word32 *privSz,\n                                    byte* pub, word32 *pubSz,\n                                    int endian)\n{\n    int ret;\n\n    /* export private part */\n    ret = wc_curve25519_export_private_raw_ex(key, priv, privSz, endian);\n    if (ret != 0)\n        return ret;\n\n    /* export public part */\n    return wc_curve25519_export_public_ex(key, pub, pubSz, endian);\n}\n\n#endif /* HAVE_CURVE25519_KEY_EXPORT */\n\n#ifdef HAVE_CURVE25519_KEY_IMPORT\n\n/* curve25519 private key import (Big endian)\n * Public key to match private key needs to be imported too\n * return 0 on success */\nint wc_curve25519_import_private_raw(const byte* priv, word32 privSz,\n                                     const byte* pub, word32 pubSz,\n                                     curve25519_key* key)\n{\n    return wc_curve25519_import_private_raw_ex(priv, privSz, pub, pubSz,\n                                               key, EC25519_BIG_ENDIAN);\n}\n\n/* curve25519 private key import (Big or Little endian)\n * Public key to match private key needs to be imported too\n * return 0 on success */\nint wc_curve25519_import_private_raw_ex(const byte* priv, word32 privSz,\n                                        const byte* pub, word32 pubSz,\n                                        curve25519_key* key, int endian)\n{\n    int ret;\n\n    /* import private part */\n    ret = wc_curve25519_import_private_ex(priv, privSz, key, endian);\n    if (ret != 0)\n        return ret;\n\n    /* import public part */\n    return wc_curve25519_import_public_ex(pub, pubSz, key, endian);\n}\n\n/* curve25519 private key import only. (Big endian)\n * return 0 on success */\nint wc_curve25519_import_private(const byte* priv, word32 privSz,\n                                 curve25519_key* key)\n{\n    return wc_curve25519_import_private_ex(priv, privSz,\n                                           key, EC25519_BIG_ENDIAN);\n}\n\n/* curve25519 private key import only. (Big or Little endian)\n * return 0 on success */\nint wc_curve25519_import_private_ex(const byte* priv, word32 privSz,\n                                    curve25519_key* key, int endian)\n{\n    /* sanity check */\n    if (key == NULL || priv == NULL)\n        return BAD_FUNC_ARG;\n\n    /* check size of incoming keys */\n    if ((int)privSz != CURVE25519_KEYSIZE)\n        return ECC_BAD_ARG_E;\n\n    if (endian == EC25519_BIG_ENDIAN) {\n        int i;\n\n        /* read the key in Big Endian format */\n        for (i = 0; i < CURVE25519_KEYSIZE; i++)\n            key->k.point[i] = priv[CURVE25519_KEYSIZE - i - 1];\n    }\n    else\n        XMEMCPY(key->k.point, priv, CURVE25519_KEYSIZE);\n\n    key->dp = &curve25519_sets[0];\n\n    /* Clamp the key */\n    key->k.point[0] &= 248;\n    key->k.point[privSz-1] &= 63; /* same &=127 because |=64 after */\n    key->k.point[privSz-1] |= 64;\n\n    return 0;\n}\n\n#endif /* HAVE_CURVE25519_KEY_IMPORT */\n\n\nint wc_curve25519_init(curve25519_key* key)\n{\n    if (key == NULL)\n       return BAD_FUNC_ARG;\n\n    XMEMSET(key, 0, sizeof(*key));\n\n    /* currently the format for curve25519 */\n    key->dp = &curve25519_sets[0];\n\n#ifndef FREESCALE_LTC_ECC\n    fe_init();\n#endif\n\n    return 0;\n}\n\n\n/* Clean the memory of a key */\nvoid wc_curve25519_free(curve25519_key* key)\n{\n   if (key == NULL)\n       return;\n\n   key->dp = NULL;\n   ForceZero(key->p.point, sizeof(key->p.point));\n   ForceZero(key->k.point, sizeof(key->k.point));\n   #ifdef FREESCALE_LTC_ECC\n       ForceZero(key->p.point, sizeof(key->p.pointY));\n       ForceZero(key->k.point, sizeof(key->k.pointY));\n   #endif\n}\n\n\n/* get key size */\nint wc_curve25519_size(curve25519_key* key)\n{\n    if (key == NULL)\n        return 0;\n\n    return key->dp->size;\n}\n\n#endif /*HAVE_CURVE25519*/\n\n"
  },
  {
    "path": "src/wolfcrypt/src/des3.c",
    "content": "/* des3.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n\n\n#ifndef NO_DES3\n\n#if defined(HAVE_FIPS) && \\\n\tdefined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n\n    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */\n    #define FIPS_NO_WRAPPERS\n\n    #ifdef USE_WINDOWS_API\n        #pragma code_seg(\".fipsA$i\")\n        #pragma const_seg(\".fipsB$i\")\n    #endif\n#endif\n\n#include <wolfssl/wolfcrypt/des3.h>\n\n#ifdef WOLF_CRYPTO_CB\n    #include <wolfssl/wolfcrypt/cryptocb.h>\n#endif\n\n/* fips wrapper calls, user can call direct */\n#if defined(HAVE_FIPS) && \\\n    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n\n    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)\n    {\n        return Des_SetKey(des, key, iv, dir);\n    }\n    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)\n    {\n        if (des == NULL || key == NULL || dir < 0) {\n            return BAD_FUNC_ARG;\n        }\n\n        return Des3_SetKey_fips(des, key, iv, dir);\n    }\n    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        return Des_CbcEncrypt(des, out, in, sz);\n    }\n    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        return Des_CbcDecrypt(des, out, in, sz);\n    }\n    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)\n    {\n        if (des == NULL || out == NULL || in == NULL) {\n            return BAD_FUNC_ARG;\n        }\n        return Des3_CbcEncrypt_fips(des, out, in, sz);\n    }\n    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)\n    {\n        if (des == NULL || out == NULL || in == NULL) {\n            return BAD_FUNC_ARG;\n        }\n        return Des3_CbcDecrypt_fips(des, out, in, sz);\n    }\n\n    #ifdef WOLFSSL_DES_ECB\n        /* One block, compatibility only */\n        int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)\n        {\n            return Des_EcbEncrypt(des, out, in, sz);\n        }\n        int wc_Des3_EcbEncrypt(Des3* des, byte* out, const byte* in, word32 sz)\n        {\n            return Des3_EcbEncrypt(des, out, in, sz);\n        }\n    #endif /* WOLFSSL_DES_ECB */\n\n    void wc_Des_SetIV(Des* des, const byte* iv)\n    {\n        Des_SetIV(des, iv);\n    }\n    int wc_Des3_SetIV(Des3* des, const byte* iv)\n    {\n        return Des3_SetIV_fips(des, iv);\n    }\n\n    int wc_Des3Init(Des3* des3, void* heap, int devId)\n    {\n        (void)des3;\n        (void)heap;\n        (void)devId;\n        /* FIPS doesn't support:\n            return Des3Init(des3, heap, devId); */\n        return 0;\n    }\n    void wc_Des3Free(Des3* des3)\n    {\n        (void)des3;\n        /* FIPS doesn't support:\n            Des3Free(des3); */\n    }\n\n#else /* else build without fips, or for FIPS v2 */\n\n\n#if defined(WOLFSSL_TI_CRYPT)\n    #include <wolfcrypt/src/port/ti/ti-des3.c>\n#else\n\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\n/* Hardware Acceleration */\n#if defined(STM32_CRYPTO)\n\n    /*\n     * STM32F2/F4 hardware DES/3DES support through the standard\n     * peripheral library. (See note in README).\n     */\n\n    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)\n    {\n        word32 *dkey = des->key;\n\n        (void)dir;\n\n        XMEMCPY(dkey, key, 8);\n    #ifndef WOLFSSL_STM32_CUBEMX\n        ByteReverseWords(dkey, dkey, 8);\n    #endif\n\n        wc_Des_SetIV(des, iv);\n\n        return 0;\n    }\n\n    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)\n    {\n    #ifndef WOLFSSL_STM32_CUBEMX\n        word32 *dkey1 = des->key[0];\n        word32 *dkey2 = des->key[1];\n        word32 *dkey3 = des->key[2];\n\n        (void)dir;\n\n        XMEMCPY(dkey1, key, 8);         /* set key 1 */\n        XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */\n        XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */\n\n        ByteReverseWords(dkey1, dkey1, 8);\n        ByteReverseWords(dkey2, dkey2, 8);\n        ByteReverseWords(dkey3, dkey3, 8);\n    #else\n        (void)dir;\n        XMEMCPY(des->key[0], key, DES3_KEYLEN); /* CUBEMX wants keys in sequential memory */\n    #endif\n\n        return wc_Des3_SetIV(des, iv);\n    }\n\n    static void DesCrypt(Des* des, byte* out, const byte* in, word32 sz,\n                  int dir, int mode)\n    {\n        int ret;\n    #ifdef WOLFSSL_STM32_CUBEMX\n        CRYP_HandleTypeDef hcryp;\n    #else\n        word32 *dkey, *iv;\n        CRYP_InitTypeDef DES_CRYP_InitStructure;\n        CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure;\n        CRYP_IVInitTypeDef DES_CRYP_IVInitStructure;\n    #endif\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret != 0) {\n            return;\n        }\n\n    #ifdef WOLFSSL_STM32_CUBEMX\n        XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));\n        hcryp.Instance = CRYP;\n        hcryp.Init.KeySize  = CRYP_KEYSIZE_128B;\n        hcryp.Init.DataType = CRYP_DATATYPE_8B;\n        hcryp.Init.pKey = (uint8_t*)des->key;\n        hcryp.Init.pInitVect = (uint8_t*)des->reg;\n\n        HAL_CRYP_Init(&hcryp);\n\n        while (sz > 0) {\n            /* if input and output same will overwrite input iv */\n            XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);\n\n            if (mode == DES_CBC) {\n                if (dir == DES_ENCRYPTION) {\n                    HAL_CRYP_DESCBC_Encrypt(&hcryp, (uint8_t*)in,\n                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);\n                }\n                else {\n                    HAL_CRYP_DESCBC_Decrypt(&hcryp, (uint8_t*)in,\n                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);\n                }\n            }\n            else {\n                if (dir == DES_ENCRYPTION) {\n                    HAL_CRYP_DESECB_Encrypt(&hcryp, (uint8_t*)in,\n                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);\n                }\n                else {\n                    HAL_CRYP_DESECB_Decrypt(&hcryp, (uint8_t*)in,\n                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);\n                }\n            }\n\n            /* store iv for next call */\n            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);\n\n            sz  -= DES_BLOCK_SIZE;\n            in  += DES_BLOCK_SIZE;\n            out += DES_BLOCK_SIZE;\n        }\n\n        HAL_CRYP_DeInit(&hcryp);\n    #else\n        dkey = des->key;\n        iv = des->reg;\n\n        /* crypto structure initialization */\n        CRYP_KeyStructInit(&DES_CRYP_KeyInitStructure);\n        CRYP_StructInit(&DES_CRYP_InitStructure);\n        CRYP_IVStructInit(&DES_CRYP_IVInitStructure);\n\n        /* reset registers to their default values */\n        CRYP_DeInit();\n\n        /* set direction, mode, and datatype */\n        if (dir == DES_ENCRYPTION) {\n            DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;\n        } else { /* DES_DECRYPTION */\n            DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;\n        }\n\n        if (mode == DES_CBC) {\n            DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_CBC;\n        } else { /* DES_ECB */\n            DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_ECB;\n        }\n\n        DES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;\n        CRYP_Init(&DES_CRYP_InitStructure);\n\n        /* load key into correct registers */\n        DES_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey[0];\n        DES_CRYP_KeyInitStructure.CRYP_Key1Right = dkey[1];\n        CRYP_KeyInit(&DES_CRYP_KeyInitStructure);\n\n        /* set iv */\n        ByteReverseWords(iv, iv, DES_BLOCK_SIZE);\n        DES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];\n        DES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];\n        CRYP_IVInit(&DES_CRYP_IVInitStructure);\n\n        /* enable crypto processor */\n        CRYP_Cmd(ENABLE);\n\n        while (sz > 0) {\n            /* flush IN/OUT FIFOs */\n            CRYP_FIFOFlush();\n\n            /* if input and output same will overwrite input iv */\n            XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);\n\n            CRYP_DataIn(*(uint32_t*)&in[0]);\n            CRYP_DataIn(*(uint32_t*)&in[4]);\n\n            /* wait until the complete message has been processed */\n            while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}\n\n            *(uint32_t*)&out[0]  = CRYP_DataOut();\n            *(uint32_t*)&out[4]  = CRYP_DataOut();\n\n            /* store iv for next call */\n            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);\n\n            sz  -= DES_BLOCK_SIZE;\n            in  += DES_BLOCK_SIZE;\n            out += DES_BLOCK_SIZE;\n        }\n\n        /* disable crypto processor */\n        CRYP_Cmd(DISABLE);\n    #endif /* WOLFSSL_STM32_CUBEMX */\n        wolfSSL_CryptHwMutexUnLock();\n    }\n\n    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_CBC);\n        return 0;\n    }\n\n    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        DesCrypt(des, out, in, sz, DES_DECRYPTION, DES_CBC);\n        return 0;\n    }\n\n    int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_ECB);\n        return 0;\n    }\n\n    static void Des3Crypt(Des3* des, byte* out, const byte* in, word32 sz,\n                   int dir)\n    {\n    #ifdef WOLFSSL_STM32_CUBEMX\n        CRYP_HandleTypeDef hcryp;\n\n        XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));\n        hcryp.Instance = CRYP;\n        hcryp.Init.KeySize  = CRYP_KEYSIZE_128B;\n        hcryp.Init.DataType = CRYP_DATATYPE_8B;\n        hcryp.Init.pKey = (uint8_t*)des->key;\n        hcryp.Init.pInitVect = (uint8_t*)des->reg;\n\n        HAL_CRYP_Init(&hcryp);\n\n        while (sz > 0)\n        {\n            if (dir == DES_ENCRYPTION) {\n                HAL_CRYP_TDESCBC_Encrypt(&hcryp, (byte*)in,\n                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);\n            }\n            else {\n                HAL_CRYP_TDESCBC_Decrypt(&hcryp, (byte*)in,\n                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);\n            }\n\n            /* store iv for next call */\n            XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);\n\n            sz  -= DES_BLOCK_SIZE;\n            in  += DES_BLOCK_SIZE;\n            out += DES_BLOCK_SIZE;\n        }\n\n        HAL_CRYP_DeInit(&hcryp);\n    #else\n        word32 *dkey1, *dkey2, *dkey3, *iv;\n        CRYP_InitTypeDef DES3_CRYP_InitStructure;\n        CRYP_KeyInitTypeDef DES3_CRYP_KeyInitStructure;\n        CRYP_IVInitTypeDef DES3_CRYP_IVInitStructure;\n\n        dkey1 = des->key[0];\n        dkey2 = des->key[1];\n        dkey3 = des->key[2];\n        iv = des->reg;\n\n        /* crypto structure initialization */\n        CRYP_KeyStructInit(&DES3_CRYP_KeyInitStructure);\n        CRYP_StructInit(&DES3_CRYP_InitStructure);\n        CRYP_IVStructInit(&DES3_CRYP_IVInitStructure);\n\n        /* reset registers to their default values */\n        CRYP_DeInit();\n\n        /* set direction, mode, and datatype */\n        if (dir == DES_ENCRYPTION) {\n            DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;\n        } else {\n            DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;\n        }\n\n        DES3_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_TDES_CBC;\n        DES3_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;\n        CRYP_Init(&DES3_CRYP_InitStructure);\n\n        /* load key into correct registers */\n        DES3_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey1[0];\n        DES3_CRYP_KeyInitStructure.CRYP_Key1Right = dkey1[1];\n        DES3_CRYP_KeyInitStructure.CRYP_Key2Left  = dkey2[0];\n        DES3_CRYP_KeyInitStructure.CRYP_Key2Right = dkey2[1];\n        DES3_CRYP_KeyInitStructure.CRYP_Key3Left  = dkey3[0];\n        DES3_CRYP_KeyInitStructure.CRYP_Key3Right = dkey3[1];\n        CRYP_KeyInit(&DES3_CRYP_KeyInitStructure);\n\n        /* set iv */\n        ByteReverseWords(iv, iv, DES_BLOCK_SIZE);\n        DES3_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];\n        DES3_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];\n        CRYP_IVInit(&DES3_CRYP_IVInitStructure);\n\n        /* enable crypto processor */\n        CRYP_Cmd(ENABLE);\n\n        while (sz > 0)\n        {\n            /* flush IN/OUT FIFOs */\n            CRYP_FIFOFlush();\n\n            CRYP_DataIn(*(uint32_t*)&in[0]);\n            CRYP_DataIn(*(uint32_t*)&in[4]);\n\n            /* wait until the complete message has been processed */\n            while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}\n\n            *(uint32_t*)&out[0]  = CRYP_DataOut();\n            *(uint32_t*)&out[4]  = CRYP_DataOut();\n\n            /* store iv for next call */\n            XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);\n\n            sz  -= DES_BLOCK_SIZE;\n            in  += DES_BLOCK_SIZE;\n            out += DES_BLOCK_SIZE;\n        }\n\n        /* disable crypto processor */\n        CRYP_Cmd(DISABLE);\n    #endif /* WOLFSSL_STM32_CUBEMX */\n    }\n\n    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)\n    {\n        Des3Crypt(des, out, in, sz, DES_ENCRYPTION);\n        return 0;\n    }\n\n    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)\n    {\n        Des3Crypt(des, out, in, sz, DES_DECRYPTION);\n        return 0;\n    }\n\n#elif defined(HAVE_COLDFIRE_SEC)\n\n    #include <wolfssl/ctaocrypt/types.h>\n\n    #include \"sec.h\"\n    #include \"mcf5475_sec.h\"\n    #include \"mcf5475_siu.h\"\n\n    #if defined (HAVE_THREADX)\n    #include \"memory_pools.h\"\n    extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */\n    #endif\n\n    #define DES_BUFFER_SIZE (DES_BLOCK_SIZE * 64)\n    static unsigned char *desBuffIn = NULL;\n    static unsigned char *desBuffOut = NULL;\n    static byte *secIV;\n    static byte *secKey;\n    static volatile SECdescriptorType *secDesc;\n\n    static wolfSSL_Mutex Mutex_DesSEC;\n\n    #define SEC_DESC_DES_CBC_ENCRYPT  0x20500010\n    #define SEC_DESC_DES_CBC_DECRYPT  0x20400010\n    #define SEC_DESC_DES3_CBC_ENCRYPT 0x20700010\n    #define SEC_DESC_DES3_CBC_DECRYPT 0x20600010\n\n    #define DES_IVLEN 8\n    #define DES_KEYLEN 8\n    #define DES3_IVLEN 8\n    #define DES3_KEYLEN 24\n\n    extern volatile unsigned char __MBAR[];\n\n    static void wc_Des_Cbc(byte* out, const byte* in, word32 sz,\n                        byte *key, byte *iv, word32 desc)\n    {\n        #ifdef DEBUG_WOLFSSL\n        int ret;  int stat1,stat2;\n    \t  #endif\n        int size;\n        volatile int v;\n\n        wc_LockMutex(&Mutex_DesSEC) ;\n\n        secDesc->length1 = 0x0;\n        secDesc->pointer1 = NULL;\n        if((desc==SEC_DESC_DES_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_DECRYPT)){\n            secDesc->length2 = DES_IVLEN;\n            secDesc->length3 = DES_KEYLEN;\n        } else {\n            secDesc->length2 = DES3_IVLEN;\n            secDesc->length3 = DES3_KEYLEN;\n        }\n        secDesc->pointer2 = secIV;\n        secDesc->pointer3 = secKey;\n        secDesc->pointer4 = desBuffIn;\n        secDesc->pointer5 = desBuffOut;\n        secDesc->length6 = 0;\n        secDesc->pointer6 = NULL;\n        secDesc->length7 = 0x0;\n        secDesc->pointer7 = NULL;\n        secDesc->nextDescriptorPtr = NULL;\n\n        while(sz) {\n            XMEMCPY(secIV, iv, secDesc->length2);\n            if((sz%DES_BUFFER_SIZE) == sz) {\n                size = sz;\n                sz = 0;\n            } else {\n                size = DES_BUFFER_SIZE;\n                sz -= DES_BUFFER_SIZE;\n            }\n\n            XMEMCPY(desBuffIn, in, size);\n            XMEMCPY(secKey, key, secDesc->length3);\n\n            secDesc->header = desc;\n            secDesc->length4 = size;\n            secDesc->length5 = size;\n            /* Point SEC to the location of the descriptor */\n            MCF_SEC_FR0 = (uint32)secDesc;\n            /* Initialize SEC and wait for encryption to complete */\n            MCF_SEC_CCCR0 = 0x0000001a;\n            /* poll SISR to determine when channel is complete */\n            v=0;\n            while((secDesc->header>> 24) != 0xff) {\n                if(v++ > 1000)break;\n            }\n\n        #ifdef DEBUG_WOLFSSL\n            ret = MCF_SEC_SISRH;\n            stat1 = MCF_SEC_DSR;\n            stat2 = MCF_SEC_DISR;\n            if(ret & 0xe0000000) {\n                /* db_printf(\"Des_Cbc(%x):ISRH=%08x, DSR=%08x, DISR=%08x\\n\", desc, ret, stat1, stat2); */\n            }\n        #endif\n\n            XMEMCPY(out, desBuffOut, size);\n\n            if ((desc==SEC_DESC_DES3_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_ENCRYPT)) {\n                XMEMCPY((void*)iv, (void*)&(out[size-secDesc->length2]), secDesc->length2);\n            } else {\n                XMEMCPY((void*)iv, (void*)&(in[size-secDesc->length2]), secDesc->length2);\n            }\n\n            in  += size;\n            out += size;\n\n        }\n        wc_UnLockMutex(&Mutex_DesSEC) ;\n\n    }\n\n\n    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        wc_Des_Cbc(out, in, sz,  (byte *)des->key,  (byte *)des->reg, SEC_DESC_DES_CBC_ENCRYPT);\n        return 0;\n    }\n\n    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        wc_Des_Cbc(out, in, sz,   (byte *)des->key,  (byte *)des->reg, SEC_DESC_DES_CBC_DECRYPT);\n        return 0;\n    }\n\n    int wc_Des3_CbcEncrypt(Des3* des3, byte* out, const byte* in, word32 sz)\n    {\n        wc_Des_Cbc(out, in, sz,  (byte *)des3->key,  (byte *)des3->reg, SEC_DESC_DES3_CBC_ENCRYPT);\n    \t  return 0;\n    }\n\n\n    int wc_Des3_CbcDecrypt(Des3* des3, byte* out, const byte* in, word32 sz)\n    {\n        wc_Des_Cbc(out, in, sz,   (byte *)des3->key,  (byte *)des3->reg, SEC_DESC_DES3_CBC_DECRYPT);\n    \t  return 0;\n    }\n\n    static void setParity(byte *buf, int len)\n    {\n        int i, j;\n        byte v;\n        int bits;\n\n        for (i=0; i<len; i++) {\n            v = buf[i] >> 1;\n            buf[i] = v << 1;\n            bits = 0;\n            for (j=0; j<7; j++) {\n                bits += (v&0x1);\n                v = v >> 1;\n            }\n            buf[i] |= (1 - (bits&0x1));\n        }\n\n    }\n\n    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)\n    {\n        if(desBuffIn == NULL) {\n        #if defined (HAVE_THREADX)\n    \t\t\t  int s1, s2, s3, s4, s5;\n            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,\n                                                         sizeof(SECdescriptorType), TX_NO_WAIT);\n            s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn,  DES_BUFFER_SIZE, TX_NO_WAIT);\n            s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT);\n            /* Don't know des or des3 to be used. Allocate larger buffers */\n            s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey,     DES3_KEYLEN,TX_NO_WAIT);\n            s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV,      DES3_IVLEN,  TX_NO_WAIT);\n        #else\n            #warning \"Allocate non-Cache buffers\"\n        #endif\n\n            InitMutex(&Mutex_DesSEC);\n        }\n\n        XMEMCPY(des->key, key, DES_KEYLEN);\n        setParity((byte *)des->key, DES_KEYLEN);\n\n        if (iv) {\n            XMEMCPY(des->reg, iv, DES_IVLEN);\n        }   else {\n            XMEMSET(des->reg, 0x0, DES_IVLEN);\n        }\n    \t\treturn 0;\n    }\n\n    int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)\n    {\n\n        if(desBuffIn == NULL) {\n        #if defined (HAVE_THREADX)\n    \t\t\t  int s1, s2, s3, s4, s5;\n            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,\n                                                         sizeof(SECdescriptorType), TX_NO_WAIT);\n            s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn,  DES_BUFFER_SIZE, TX_NO_WAIT);\n            s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT);\n            s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey,     DES3_KEYLEN,TX_NO_WAIT);\n            s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV,      DES3_IVLEN,  TX_NO_WAIT);\n        #else\n            #warning \"Allocate non-Cache buffers\"\n        #endif\n\n            InitMutex(&Mutex_DesSEC);\n        }\n\n        XMEMCPY(des3->key[0], key, DES3_KEYLEN);\n        setParity((byte *)des3->key[0], DES3_KEYLEN);\n\n        if (iv) {\n            XMEMCPY(des3->reg, iv, DES3_IVLEN);\n        }   else {\n            XMEMSET(des3->reg, 0x0, DES3_IVLEN);\n        }\n        return 0;\n\n    }\n#elif defined(FREESCALE_LTC_DES)\n\n    #include \"fsl_ltc.h\"\n    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)\n    {\n        byte* dkey = (byte*)des->key;\n\n        XMEMCPY(dkey, key, 8);\n\n        wc_Des_SetIV(des, iv);\n\n        return 0;\n    }\n\n    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)\n    {\n        int ret = 0;\n        byte* dkey1 = (byte*)des->key[0];\n        byte* dkey2 = (byte*)des->key[1];\n        byte* dkey3 = (byte*)des->key[2];\n\n        XMEMCPY(dkey1, key, 8);         /* set key 1 */\n        XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */\n        XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */\n\n        ret = wc_Des3_SetIV(des, iv);\n        if (ret != 0)\n            return ret;\n\n        return ret;\n    }\n\n    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        status_t status;\n        status = LTC_DES_EncryptCbc(LTC_BASE, in, out, sz, (byte*)des->reg, (byte*)des->key);\n        if (status == kStatus_Success)\n            return 0;\n        else\n            return -1;\n    }\n\n    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        status_t status;\n        status = LTC_DES_DecryptCbc(LTC_BASE, in, out, sz, (byte*)des->reg, (byte*)des->key);\n        if (status == kStatus_Success)\n            return 0;\n        else\n            return -1;\n    }\n\n    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)\n    {\n        status_t status;\n        status = LTC_DES3_EncryptCbc(LTC_BASE,\n                                 in,\n                                 out,\n                                 sz,\n                                 (byte*)des->reg,\n                                 (byte*)des->key[0],\n                                 (byte*)des->key[1],\n                                 (byte*)des->key[2]);\n        if (status == kStatus_Success)\n            return 0;\n        else\n            return -1;\n    }\n\n    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)\n    {\n        status_t status;\n        status = LTC_DES3_DecryptCbc(LTC_BASE,\n                                 in,\n                                 out,\n                                 sz,\n                                 (byte*)des->reg,\n                                 (byte*)des->key[0],\n                                 (byte*)des->key[1],\n                                 (byte*)des->key[2]);\n        if (status == kStatus_Success)\n            return 0;\n        else\n            return -1;\n\n    }\n\n#elif defined(FREESCALE_MMCAU)\n    /*\n     * Freescale mmCAU hardware DES/3DES support through the CAU/mmCAU library.\n     * Documentation located in ColdFire/ColdFire+ CAU and Kinetis mmCAU\n     * Software Library User Guide (See note in README).\n     */\n    #ifdef FREESCALE_MMCAU_CLASSIC\n        #include \"cau_api.h\"\n    #else\n        #include \"fsl_mmcau.h\"\n    #endif\n\n    const unsigned char parityLookup[128] = {\n        1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,\n        0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,\n        0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,\n        1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0\n     };\n\n    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)\n    {\n        int i = 0;\n        byte* dkey = (byte*)des->key;\n\n        XMEMCPY(dkey, key, 8);\n\n        wc_Des_SetIV(des, iv);\n\n        /* fix key parity, if needed */\n        for (i = 0; i < 8; i++) {\n            dkey[i] = ((dkey[i] & 0xFE) | parityLookup[dkey[i] >> 1]);\n        }\n\n        return 0;\n    }\n\n    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)\n    {\n        int i = 0, ret = 0;\n        byte* dkey1 = (byte*)des->key[0];\n        byte* dkey2 = (byte*)des->key[1];\n        byte* dkey3 = (byte*)des->key[2];\n\n        XMEMCPY(dkey1, key, 8);         /* set key 1 */\n        XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */\n        XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */\n\n        ret = wc_Des3_SetIV(des, iv);\n        if (ret != 0)\n            return ret;\n\n        /* fix key parity if needed */\n        for (i = 0; i < 8; i++)\n           dkey1[i] = ((dkey1[i] & 0xFE) | parityLookup[dkey1[i] >> 1]);\n\n        for (i = 0; i < 8; i++)\n           dkey2[i] = ((dkey2[i] & 0xFE) | parityLookup[dkey2[i] >> 1]);\n\n        for (i = 0; i < 8; i++)\n           dkey3[i] = ((dkey3[i] & 0xFE) | parityLookup[dkey3[i] >> 1]);\n\n        return ret;\n    }\n\n    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        int i;\n        int offset = 0;\n        int len = sz;\n        int ret = 0;\n        byte *iv;\n        byte temp_block[DES_BLOCK_SIZE];\n\n        iv = (byte*)des->reg;\n\n    #ifdef FREESCALE_MMCAU_CLASSIC\n        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {\n            WOLFSSL_MSG(\"Bad cau_des_encrypt alignment\");\n            return BAD_ALIGN_E;\n        }\n    #endif\n\n        while (len > 0)\n        {\n            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);\n\n            /* XOR block with IV for CBC */\n            for (i = 0; i < DES_BLOCK_SIZE; i++)\n                temp_block[i] ^= iv[i];\n\n            ret = wolfSSL_CryptHwMutexLock();\n            if(ret != 0) {\n                return ret;\n            }\n        #ifdef FREESCALE_MMCAU_CLASSIC\n            cau_des_encrypt(temp_block, (byte*)des->key, out + offset);\n        #else\n            MMCAU_DES_EncryptEcb(temp_block, (byte*)des->key, out + offset);\n        #endif\n            wolfSSL_CryptHwMutexUnLock();\n\n            len    -= DES_BLOCK_SIZE;\n            offset += DES_BLOCK_SIZE;\n\n            /* store IV for next block */\n            XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);\n        }\n\n        return ret;\n    }\n\n    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        int i;\n        int offset = 0;\n        int len = sz;\n        int ret = 0;\n        byte* iv;\n        byte temp_block[DES_BLOCK_SIZE];\n\n        iv = (byte*)des->reg;\n\n    #ifdef FREESCALE_MMCAU_CLASSIC\n        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {\n            WOLFSSL_MSG(\"Bad cau_des_decrypt alignment\");\n            return BAD_ALIGN_E;\n        }\n    #endif\n\n        while (len > 0)\n        {\n            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);\n\n            ret = wolfSSL_CryptHwMutexLock();\n            if(ret != 0) {\n                return ret;\n            }\n\n        #ifdef FREESCALE_MMCAU_CLASSIC\n            cau_des_decrypt(in + offset, (byte*)des->key, out + offset);\n        #else\n            MMCAU_DES_DecryptEcb(in + offset, (byte*)des->key, out + offset);\n        #endif\n            wolfSSL_CryptHwMutexUnLock();\n\n            /* XOR block with IV for CBC */\n            for (i = 0; i < DES_BLOCK_SIZE; i++)\n                (out + offset)[i] ^= iv[i];\n\n            /* store IV for next block */\n            XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);\n\n            len     -= DES_BLOCK_SIZE;\n            offset += DES_BLOCK_SIZE;\n        }\n\n        return ret;\n    }\n\n    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)\n    {\n        int i;\n        int offset = 0;\n        int len = sz;\n        int ret = 0;\n\n        byte *iv;\n        byte temp_block[DES_BLOCK_SIZE];\n\n        iv = (byte*)des->reg;\n\n    #ifdef FREESCALE_MMCAU_CLASSIC\n        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {\n            WOLFSSL_MSG(\"Bad 3ede cau_des_encrypt alignment\");\n            return BAD_ALIGN_E;\n        }\n    #endif\n\n        while (len > 0)\n        {\n            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);\n\n            /* XOR block with IV for CBC */\n            for (i = 0; i < DES_BLOCK_SIZE; i++)\n                temp_block[i] ^= iv[i];\n\n            ret = wolfSSL_CryptHwMutexLock();\n            if(ret != 0) {\n                return ret;\n            }\n    #ifdef FREESCALE_MMCAU_CLASSIC\n            cau_des_encrypt(temp_block,   (byte*)des->key[0], out + offset);\n            cau_des_decrypt(out + offset, (byte*)des->key[1], out + offset);\n            cau_des_encrypt(out + offset, (byte*)des->key[2], out + offset);\n    #else\n            MMCAU_DES_EncryptEcb(temp_block  , (byte*)des->key[0], out + offset);\n            MMCAU_DES_DecryptEcb(out + offset, (byte*)des->key[1], out + offset);\n            MMCAU_DES_EncryptEcb(out + offset, (byte*)des->key[2], out + offset);\n    #endif\n            wolfSSL_CryptHwMutexUnLock();\n\n            len    -= DES_BLOCK_SIZE;\n            offset += DES_BLOCK_SIZE;\n\n            /* store IV for next block */\n            XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);\n        }\n\n        return ret;\n    }\n\n    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)\n    {\n        int i;\n        int offset = 0;\n        int len = sz;\n        int ret = 0;\n\n        byte* iv;\n        byte temp_block[DES_BLOCK_SIZE];\n\n        iv = (byte*)des->reg;\n\n    #ifdef FREESCALE_MMCAU_CLASSIC\n        if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) {\n            WOLFSSL_MSG(\"Bad 3ede cau_des_decrypt alignment\");\n            return BAD_ALIGN_E;\n        }\n    #endif\n\n        while (len > 0)\n        {\n            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);\n\n            ret = wolfSSL_CryptHwMutexLock();\n            if(ret != 0) {\n                return ret;\n            }\n        #ifdef FREESCALE_MMCAU_CLASSIC\n            cau_des_decrypt(in + offset,  (byte*)des->key[2], out + offset);\n            cau_des_encrypt(out + offset, (byte*)des->key[1], out + offset);\n            cau_des_decrypt(out + offset, (byte*)des->key[0], out + offset);\n        #else\n            MMCAU_DES_DecryptEcb(in + offset , (byte*)des->key[2], out + offset);\n            MMCAU_DES_EncryptEcb(out + offset, (byte*)des->key[1], out + offset);\n            MMCAU_DES_DecryptEcb(out + offset, (byte*)des->key[0], out + offset);\n        #endif\n            wolfSSL_CryptHwMutexUnLock();\n\n            /* XOR block with IV for CBC */\n            for (i = 0; i < DES_BLOCK_SIZE; i++)\n                (out + offset)[i] ^= iv[i];\n\n            /* store IV for next block */\n            XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);\n\n            len    -= DES_BLOCK_SIZE;\n            offset += DES_BLOCK_SIZE;\n        }\n\n        return ret;\n    }\n\n\n#elif defined(WOLFSSL_PIC32MZ_CRYPT)\n\n    /* PIC32MZ DES hardware requires size multiple of block size */\n    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>\n\n    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)\n    {\n        if (des == NULL || key == NULL || iv == NULL)\n            return BAD_FUNC_ARG;\n\n        XMEMCPY(des->key, key, DES_KEYLEN);\n        XMEMCPY(des->reg, iv, DES_IVLEN);\n\n        return 0;\n    }\n\n    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)\n    {\n        if (des == NULL || key == NULL || iv == NULL)\n            return BAD_FUNC_ARG;\n\n        XMEMCPY(des->key[0], key, DES3_KEYLEN);\n        XMEMCPY(des->reg, iv, DES3_IVLEN);\n\n        return 0;\n    }\n\n    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        word32 blocks = sz / DES_BLOCK_SIZE;\n\n        if (des == NULL || out == NULL || in == NULL)\n            return BAD_FUNC_ARG;\n\n        return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN,\n            out, in, (blocks * DES_BLOCK_SIZE),\n            PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC);\n    }\n\n    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        word32 blocks = sz / DES_BLOCK_SIZE;\n\n        if (des == NULL || out == NULL || in == NULL)\n            return BAD_FUNC_ARG;\n\n        return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN,\n            out, in, (blocks * DES_BLOCK_SIZE),\n            PIC32_DECRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC);\n    }\n\n    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)\n    {\n        word32 blocks = sz / DES_BLOCK_SIZE;\n\n        if (des == NULL || out == NULL || in == NULL)\n            return BAD_FUNC_ARG;\n\n        return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN,\n            out, in, (blocks * DES_BLOCK_SIZE),\n            PIC32_ENCRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC);\n    }\n\n    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)\n    {\n        word32 blocks = sz / DES_BLOCK_SIZE;\n\n        if (des == NULL || out == NULL || in == NULL)\n            return BAD_FUNC_ARG;\n\n        return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN,\n            out, in, (blocks * DES_BLOCK_SIZE),\n            PIC32_DECRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC);\n    }\n\n    #ifdef WOLFSSL_DES_ECB\n        int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)\n        {\n            word32 blocks = sz / DES_BLOCK_SIZE;\n\n            if (des == NULL || out == NULL || in == NULL)\n                return BAD_FUNC_ARG;\n\n            return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN,\n                out, in, (blocks * DES_BLOCK_SIZE),\n                    PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_ECB);\n        }\n\n        int wc_Des3_EcbEncrypt(Des3* des, byte* out, const byte* in, word32 sz)\n        {\n            word32 blocks = sz / DES_BLOCK_SIZE;\n\n            if (des == NULL || out == NULL || in == NULL)\n                return BAD_FUNC_ARG;\n\n            return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN,\n                out, in, (blocks * DES_BLOCK_SIZE),\n                PIC32_ENCRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TECB);\n        }\n    #endif /* WOLFSSL_DES_ECB */\n\n#else\n    #define NEED_SOFT_DES\n\n#endif\n\n\n#ifdef NEED_SOFT_DES\n\n    /* permuted choice table (key) */\n    static const byte pc1[] = {\n           57, 49, 41, 33, 25, 17,  9,\n            1, 58, 50, 42, 34, 26, 18,\n           10,  2, 59, 51, 43, 35, 27,\n           19, 11,  3, 60, 52, 44, 36,\n\n           63, 55, 47, 39, 31, 23, 15,\n            7, 62, 54, 46, 38, 30, 22,\n           14,  6, 61, 53, 45, 37, 29,\n           21, 13,  5, 28, 20, 12,  4\n    };\n\n    /* number left rotations of pc1 */\n    static const byte totrot[] = {\n           1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28\n    };\n\n    /* permuted choice key (table) */\n    static const byte pc2[] = {\n           14, 17, 11, 24,  1,  5,\n            3, 28, 15,  6, 21, 10,\n           23, 19, 12,  4, 26,  8,\n           16,  7, 27, 20, 13,  2,\n           41, 52, 31, 37, 47, 55,\n           30, 40, 51, 45, 33, 48,\n           44, 49, 39, 56, 34, 53,\n           46, 42, 50, 36, 29, 32\n    };\n\n    /* End of DES-defined tables */\n\n    /* bit 0 is left-most in byte */\n    static const int bytebit[] = {\n        0200,0100,040,020,010,04,02,01\n    };\n\n    static const word32 Spbox[8][64] = {\n    {   0x01010400,0x00000000,0x00010000,0x01010404,\n        0x01010004,0x00010404,0x00000004,0x00010000,\n        0x00000400,0x01010400,0x01010404,0x00000400,\n        0x01000404,0x01010004,0x01000000,0x00000004,\n        0x00000404,0x01000400,0x01000400,0x00010400,\n        0x00010400,0x01010000,0x01010000,0x01000404,\n        0x00010004,0x01000004,0x01000004,0x00010004,\n        0x00000000,0x00000404,0x00010404,0x01000000,\n        0x00010000,0x01010404,0x00000004,0x01010000,\n        0x01010400,0x01000000,0x01000000,0x00000400,\n        0x01010004,0x00010000,0x00010400,0x01000004,\n        0x00000400,0x00000004,0x01000404,0x00010404,\n        0x01010404,0x00010004,0x01010000,0x01000404,\n        0x01000004,0x00000404,0x00010404,0x01010400,\n        0x00000404,0x01000400,0x01000400,0x00000000,\n        0x00010004,0x00010400,0x00000000,0x01010004},\n    {   0x80108020,0x80008000,0x00008000,0x00108020,\n        0x00100000,0x00000020,0x80100020,0x80008020,\n        0x80000020,0x80108020,0x80108000,0x80000000,\n        0x80008000,0x00100000,0x00000020,0x80100020,\n        0x00108000,0x00100020,0x80008020,0x00000000,\n        0x80000000,0x00008000,0x00108020,0x80100000,\n        0x00100020,0x80000020,0x00000000,0x00108000,\n        0x00008020,0x80108000,0x80100000,0x00008020,\n        0x00000000,0x00108020,0x80100020,0x00100000,\n        0x80008020,0x80100000,0x80108000,0x00008000,\n        0x80100000,0x80008000,0x00000020,0x80108020,\n        0x00108020,0x00000020,0x00008000,0x80000000,\n        0x00008020,0x80108000,0x00100000,0x80000020,\n        0x00100020,0x80008020,0x80000020,0x00100020,\n        0x00108000,0x00000000,0x80008000,0x00008020,\n        0x80000000,0x80100020,0x80108020,0x00108000},\n    {   0x00000208,0x08020200,0x00000000,0x08020008,\n        0x08000200,0x00000000,0x00020208,0x08000200,\n        0x00020008,0x08000008,0x08000008,0x00020000,\n        0x08020208,0x00020008,0x08020000,0x00000208,\n        0x08000000,0x00000008,0x08020200,0x00000200,\n        0x00020200,0x08020000,0x08020008,0x00020208,\n        0x08000208,0x00020200,0x00020000,0x08000208,\n        0x00000008,0x08020208,0x00000200,0x08000000,\n        0x08020200,0x08000000,0x00020008,0x00000208,\n        0x00020000,0x08020200,0x08000200,0x00000000,\n        0x00000200,0x00020008,0x08020208,0x08000200,\n        0x08000008,0x00000200,0x00000000,0x08020008,\n        0x08000208,0x00020000,0x08000000,0x08020208,\n        0x00000008,0x00020208,0x00020200,0x08000008,\n        0x08020000,0x08000208,0x00000208,0x08020000,\n        0x00020208,0x00000008,0x08020008,0x00020200},\n    {   0x00802001,0x00002081,0x00002081,0x00000080,\n        0x00802080,0x00800081,0x00800001,0x00002001,\n        0x00000000,0x00802000,0x00802000,0x00802081,\n        0x00000081,0x00000000,0x00800080,0x00800001,\n        0x00000001,0x00002000,0x00800000,0x00802001,\n        0x00000080,0x00800000,0x00002001,0x00002080,\n        0x00800081,0x00000001,0x00002080,0x00800080,\n        0x00002000,0x00802080,0x00802081,0x00000081,\n        0x00800080,0x00800001,0x00802000,0x00802081,\n        0x00000081,0x00000000,0x00000000,0x00802000,\n        0x00002080,0x00800080,0x00800081,0x00000001,\n        0x00802001,0x00002081,0x00002081,0x00000080,\n        0x00802081,0x00000081,0x00000001,0x00002000,\n        0x00800001,0x00002001,0x00802080,0x00800081,\n        0x00002001,0x00002080,0x00800000,0x00802001,\n        0x00000080,0x00800000,0x00002000,0x00802080},\n    {   0x00000100,0x02080100,0x02080000,0x42000100,\n        0x00080000,0x00000100,0x40000000,0x02080000,\n        0x40080100,0x00080000,0x02000100,0x40080100,\n        0x42000100,0x42080000,0x00080100,0x40000000,\n        0x02000000,0x40080000,0x40080000,0x00000000,\n        0x40000100,0x42080100,0x42080100,0x02000100,\n        0x42080000,0x40000100,0x00000000,0x42000000,\n        0x02080100,0x02000000,0x42000000,0x00080100,\n        0x00080000,0x42000100,0x00000100,0x02000000,\n        0x40000000,0x02080000,0x42000100,0x40080100,\n        0x02000100,0x40000000,0x42080000,0x02080100,\n        0x40080100,0x00000100,0x02000000,0x42080000,\n        0x42080100,0x00080100,0x42000000,0x42080100,\n        0x02080000,0x00000000,0x40080000,0x42000000,\n        0x00080100,0x02000100,0x40000100,0x00080000,\n        0x00000000,0x40080000,0x02080100,0x40000100},\n    {   0x20000010,0x20400000,0x00004000,0x20404010,\n        0x20400000,0x00000010,0x20404010,0x00400000,\n        0x20004000,0x00404010,0x00400000,0x20000010,\n        0x00400010,0x20004000,0x20000000,0x00004010,\n        0x00000000,0x00400010,0x20004010,0x00004000,\n        0x00404000,0x20004010,0x00000010,0x20400010,\n        0x20400010,0x00000000,0x00404010,0x20404000,\n        0x00004010,0x00404000,0x20404000,0x20000000,\n        0x20004000,0x00000010,0x20400010,0x00404000,\n        0x20404010,0x00400000,0x00004010,0x20000010,\n        0x00400000,0x20004000,0x20000000,0x00004010,\n        0x20000010,0x20404010,0x00404000,0x20400000,\n        0x00404010,0x20404000,0x00000000,0x20400010,\n        0x00000010,0x00004000,0x20400000,0x00404010,\n        0x00004000,0x00400010,0x20004010,0x00000000,\n        0x20404000,0x20000000,0x00400010,0x20004010},\n    {   0x00200000,0x04200002,0x04000802,0x00000000,\n        0x00000800,0x04000802,0x00200802,0x04200800,\n        0x04200802,0x00200000,0x00000000,0x04000002,\n        0x00000002,0x04000000,0x04200002,0x00000802,\n        0x04000800,0x00200802,0x00200002,0x04000800,\n        0x04000002,0x04200000,0x04200800,0x00200002,\n        0x04200000,0x00000800,0x00000802,0x04200802,\n        0x00200800,0x00000002,0x04000000,0x00200800,\n        0x04000000,0x00200800,0x00200000,0x04000802,\n        0x04000802,0x04200002,0x04200002,0x00000002,\n        0x00200002,0x04000000,0x04000800,0x00200000,\n        0x04200800,0x00000802,0x00200802,0x04200800,\n        0x00000802,0x04000002,0x04200802,0x04200000,\n        0x00200800,0x00000000,0x00000002,0x04200802,\n        0x00000000,0x00200802,0x04200000,0x00000800,\n        0x04000002,0x04000800,0x00000800,0x00200002},\n    {   0x10001040,0x00001000,0x00040000,0x10041040,\n        0x10000000,0x10001040,0x00000040,0x10000000,\n        0x00040040,0x10040000,0x10041040,0x00041000,\n        0x10041000,0x00041040,0x00001000,0x00000040,\n        0x10040000,0x10000040,0x10001000,0x00001040,\n        0x00041000,0x00040040,0x10040040,0x10041000,\n        0x00001040,0x00000000,0x00000000,0x10040040,\n        0x10000040,0x10001000,0x00041040,0x00040000,\n        0x00041040,0x00040000,0x10041000,0x00001000,\n        0x00000040,0x10040040,0x00001000,0x00041040,\n        0x10001000,0x00000040,0x10000040,0x10040000,\n        0x10040040,0x10000000,0x00040000,0x10001040,\n        0x00000000,0x10041040,0x00040040,0x10000040,\n        0x10040000,0x10001000,0x10001040,0x00000000,\n        0x10041040,0x00041000,0x00041000,0x00001040,\n        0x00001040,0x00040040,0x10000000,0x10041000}\n    };\n\n    static WC_INLINE void IPERM(word32* left, word32* right)\n    {\n        word32 work;\n\n        *right = rotlFixed(*right, 4U);\n        work = (*left ^ *right) & 0xf0f0f0f0;\n        *left ^= work;\n\n        *right = rotrFixed(*right^work, 20U);\n        work = (*left ^ *right) & 0xffff0000;\n        *left ^= work;\n\n        *right = rotrFixed(*right^work, 18U);\n        work = (*left ^ *right) & 0x33333333;\n        *left ^= work;\n\n        *right = rotrFixed(*right^work, 6U);\n        work = (*left ^ *right) & 0x00ff00ff;\n        *left ^= work;\n\n        *right = rotlFixed(*right^work, 9U);\n        work = (*left ^ *right) & 0xaaaaaaaa;\n        *left = rotlFixed(*left^work, 1U);\n        *right ^= work;\n    }\n\n    static WC_INLINE void FPERM(word32* left, word32* right)\n    {\n        word32 work;\n\n        *right = rotrFixed(*right, 1U);\n        work = (*left ^ *right) & 0xaaaaaaaa;\n        *right ^= work;\n\n        *left = rotrFixed(*left^work, 9U);\n        work = (*left ^ *right) & 0x00ff00ff;\n        *right ^= work;\n\n        *left = rotlFixed(*left^work, 6U);\n        work = (*left ^ *right) & 0x33333333;\n        *right ^= work;\n\n        *left = rotlFixed(*left^work, 18U);\n        work = (*left ^ *right) & 0xffff0000;\n        *right ^= work;\n\n        *left = rotlFixed(*left^work, 20U);\n        work = (*left ^ *right) & 0xf0f0f0f0;\n        *right ^= work;\n\n        *left = rotrFixed(*left^work, 4U);\n    }\n\n    static int DesSetKey(const byte* key, int dir, word32* out)\n    {\n        #define DES_KEY_BUFFER_SIZE (56+56+8)\n    #ifdef WOLFSSL_SMALL_STACK\n        byte* buffer = (byte*)XMALLOC(DES_KEY_BUFFER_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n\n        if (buffer == NULL)\n            return MEMORY_E;\n    #else\n        byte buffer[DES_KEY_BUFFER_SIZE];\n    #endif\n\n        {\n            byte* const  pc1m = buffer;            /* place to modify pc1 into */\n            byte* const  pcr  = pc1m + 56;         /* place to rotate pc1 into */\n            byte* const  ks   = pcr  + 56;\n            register int i, j, l;\n            int          m;\n\n            for (j = 0; j < 56; j++) {             /* convert pc1 to bits of key  */\n                l = pc1[j] - 1;                    /* integer bit location        */\n                m = l & 07;                        /* find bit                    */\n                pc1m[j] = (key[l >> 3] &           /* find which key byte l is in */\n                    bytebit[m])                    /* and which bit of that byte  */\n                    ? 1 : 0;                       /* and store 1-bit result      */\n            }\n\n            for (i = 0; i < 16; i++) {            /* key chunk for each iteration */\n                XMEMSET(ks, 0, 8);                /* Clear key schedule */\n\n                for (j = 0; j < 56; j++)          /* rotate pc1 the right amount  */\n                    pcr[j] =\n                          pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l-28];\n\n                /* rotate left and right halves independently */\n                for (j = 0; j < 48; j++) {        /* select bits individually     */\n                    if (pcr[pc2[j] - 1]) {        /* check bit that goes to ks[j] */\n                        l= j % 6;                 /* mask it in if it's there     */\n                        ks[j/6] |= bytebit[l] >> 2;\n                    }\n                }\n\n                /* Now convert to odd/even interleaved form for use in F */\n                out[2*i] = ((word32) ks[0] << 24)\n                         | ((word32) ks[2] << 16)\n                         | ((word32) ks[4] << 8)\n                         | ((word32) ks[6]);\n\n                out[2*i + 1] = ((word32) ks[1] << 24)\n                             | ((word32) ks[3] << 16)\n                             | ((word32) ks[5] << 8)\n                             | ((word32) ks[7]);\n            }\n\n            /* reverse key schedule order */\n            if (dir == DES_DECRYPTION) {\n                for (i = 0; i < 16; i += 2) {\n                    word32 swap = out[i];\n                    out[i] = out[DES_KS_SIZE - 2 - i];\n                    out[DES_KS_SIZE - 2 - i] = swap;\n\n                    swap = out[i + 1];\n                    out[i + 1] = out[DES_KS_SIZE - 1 - i];\n                    out[DES_KS_SIZE - 1 - i] = swap;\n                }\n            }\n\n    #ifdef WOLFSSL_SMALL_STACK\n            XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        }\n\n        return 0;\n    }\n\n    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)\n    {\n        wc_Des_SetIV(des, iv);\n\n        return DesSetKey(key, dir, des->key);\n    }\n\n    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)\n    {\n        int ret;\n\n        if (des == NULL || key == NULL || dir < 0) {\n            return BAD_FUNC_ARG;\n        }\n\n    #if defined(WOLF_CRYPTO_CB) || \\\n        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES))\n        #ifdef WOLF_CRYPTO_CB\n        if (des->devId != INVALID_DEVID)\n        #endif\n        {\n            XMEMCPY(des->devKey, key, DES3_KEYLEN);\n        }\n    #endif\n\n        ret = DesSetKey(key + (dir == DES_ENCRYPTION ? 0:16), dir, des->key[0]);\n        if (ret != 0)\n            return ret;\n\n        ret = DesSetKey(key + 8, !dir, des->key[1]);\n        if (ret != 0)\n            return ret;\n\n        ret = DesSetKey(key + (dir == DES_DECRYPTION ? 0:16), dir, des->key[2]);\n        if (ret != 0)\n            return ret;\n\n        return wc_Des3_SetIV(des, iv);\n    }\n\n    static void DesRawProcessBlock(word32* lIn, word32* rIn, const word32* kptr)\n    {\n        word32 l = *lIn, r = *rIn, i;\n\n        for (i=0; i<8; i++)\n        {\n            word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];\n            l ^= Spbox[6][(work) & 0x3f]\n              ^  Spbox[4][(work >> 8) & 0x3f]\n              ^  Spbox[2][(work >> 16) & 0x3f]\n              ^  Spbox[0][(work >> 24) & 0x3f];\n            work = r ^ kptr[4*i+1];\n            l ^= Spbox[7][(work) & 0x3f]\n              ^  Spbox[5][(work >> 8) & 0x3f]\n              ^  Spbox[3][(work >> 16) & 0x3f]\n              ^  Spbox[1][(work >> 24) & 0x3f];\n\n            work = rotrFixed(l, 4U) ^ kptr[4*i+2];\n            r ^= Spbox[6][(work) & 0x3f]\n              ^  Spbox[4][(work >> 8) & 0x3f]\n              ^  Spbox[2][(work >> 16) & 0x3f]\n              ^  Spbox[0][(work >> 24) & 0x3f];\n            work = l ^ kptr[4*i+3];\n            r ^= Spbox[7][(work) & 0x3f]\n              ^  Spbox[5][(work >> 8) & 0x3f]\n              ^  Spbox[3][(work >> 16) & 0x3f]\n              ^  Spbox[1][(work >> 24) & 0x3f];\n        }\n\n        *lIn = l; *rIn = r;\n    }\n\n    static void DesProcessBlock(Des* des, const byte* in, byte* out)\n    {\n        word32 l, r;\n\n        XMEMCPY(&l, in, sizeof(l));\n        XMEMCPY(&r, in + sizeof(l), sizeof(r));\n        #ifdef LITTLE_ENDIAN_ORDER\n            l = ByteReverseWord32(l);\n            r = ByteReverseWord32(r);\n        #endif\n        IPERM(&l,&r);\n\n        DesRawProcessBlock(&l, &r, des->key);\n\n        FPERM(&l,&r);\n        #ifdef LITTLE_ENDIAN_ORDER\n            l = ByteReverseWord32(l);\n            r = ByteReverseWord32(r);\n        #endif\n        XMEMCPY(out, &r, sizeof(r));\n        XMEMCPY(out + sizeof(r), &l, sizeof(l));\n    }\n\n    static void Des3ProcessBlock(Des3* des, const byte* in, byte* out)\n    {\n        word32 l, r;\n\n        XMEMCPY(&l, in, sizeof(l));\n        XMEMCPY(&r, in + sizeof(l), sizeof(r));\n        #ifdef LITTLE_ENDIAN_ORDER\n            l = ByteReverseWord32(l);\n            r = ByteReverseWord32(r);\n        #endif\n        IPERM(&l,&r);\n\n        DesRawProcessBlock(&l, &r, des->key[0]);\n        DesRawProcessBlock(&r, &l, des->key[1]);\n        DesRawProcessBlock(&l, &r, des->key[2]);\n\n        FPERM(&l,&r);\n        #ifdef LITTLE_ENDIAN_ORDER\n            l = ByteReverseWord32(l);\n            r = ByteReverseWord32(r);\n        #endif\n        XMEMCPY(out, &r, sizeof(r));\n        XMEMCPY(out + sizeof(r), &l, sizeof(l));\n    }\n\n    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        word32 blocks = sz / DES_BLOCK_SIZE;\n\n        while (blocks--) {\n            xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);\n            DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg);\n            XMEMCPY(out, des->reg, DES_BLOCK_SIZE);\n\n            out += DES_BLOCK_SIZE;\n            in  += DES_BLOCK_SIZE;\n        }\n        return 0;\n    }\n\n    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)\n    {\n        word32 blocks = sz / DES_BLOCK_SIZE;\n\n        while (blocks--) {\n            XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);\n            DesProcessBlock(des, (byte*)des->tmp, out);\n            xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);\n            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);\n\n            out += DES_BLOCK_SIZE;\n            in  += DES_BLOCK_SIZE;\n        }\n        return 0;\n    }\n\n    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)\n    {\n        word32 blocks;\n\n        if (des == NULL || out == NULL || in == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n    #ifdef WOLF_CRYPTO_CB\n        if (des->devId != INVALID_DEVID) {\n            int ret = wc_CryptoCb_Des3Encrypt(des, out, in, sz);\n            if (ret != CRYPTOCB_UNAVAILABLE)\n                return ret;\n            /* fall-through when unavailable */\n        }\n    #endif\n\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)\n        if (des->asyncDev.marker == WOLFSSL_ASYNC_MARKER_3DES &&\n                                            sz >= WC_ASYNC_THRESH_DES3_CBC) {\n        #if defined(HAVE_CAVIUM)\n            return NitroxDes3CbcEncrypt(des, out, in, sz);\n        #elif defined(HAVE_INTEL_QA)\n            return IntelQaSymDes3CbcEncrypt(&des->asyncDev, out, in, sz,\n                (const byte*)des->devKey, DES3_KEYLEN, (byte*)des->reg, DES3_IVLEN);\n        #else /* WOLFSSL_ASYNC_CRYPT_TEST */\n            if (wc_AsyncTestInit(&des->asyncDev, ASYNC_TEST_DES3_CBC_ENCRYPT)) {\n                WC_ASYNC_TEST* testDev = &des->asyncDev.test;\n                testDev->des.des = des;\n                testDev->des.out = out;\n                testDev->des.in = in;\n                testDev->des.sz = sz;\n                return WC_PENDING_E;\n            }\n        #endif\n        }\n    #endif /* WOLFSSL_ASYNC_CRYPT */\n\n        blocks = sz / DES_BLOCK_SIZE;\n        while (blocks--) {\n            xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);\n            Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg);\n            XMEMCPY(out, des->reg, DES_BLOCK_SIZE);\n\n            out += DES_BLOCK_SIZE;\n            in  += DES_BLOCK_SIZE;\n        }\n        return 0;\n    }\n\n\n    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)\n    {\n        word32 blocks;\n\n        if (des == NULL || out == NULL || in == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n    #ifdef WOLF_CRYPTO_CB\n        if (des->devId != INVALID_DEVID) {\n            int ret = wc_CryptoCb_Des3Decrypt(des, out, in, sz);\n            if (ret != CRYPTOCB_UNAVAILABLE)\n                return ret;\n            /* fall-through when unavailable */\n        }\n    #endif\n\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)\n        if (des->asyncDev.marker == WOLFSSL_ASYNC_MARKER_3DES &&\n                                            sz >= WC_ASYNC_THRESH_DES3_CBC) {\n        #if defined(HAVE_CAVIUM)\n            return NitroxDes3CbcDecrypt(des, out, in, sz);\n        #elif defined(HAVE_INTEL_QA)\n            return IntelQaSymDes3CbcDecrypt(&des->asyncDev, out, in, sz,\n                (const byte*)des->devKey, DES3_KEYLEN, (byte*)des->reg, DES3_IVLEN);\n        #else /* WOLFSSL_ASYNC_CRYPT_TEST */\n            if (wc_AsyncTestInit(&des->asyncDev, ASYNC_TEST_DES3_CBC_DECRYPT)) {\n                WC_ASYNC_TEST* testDev = &des->asyncDev.test;\n                testDev->des.des = des;\n                testDev->des.out = out;\n                testDev->des.in = in;\n                testDev->des.sz = sz;\n                return WC_PENDING_E;\n            }\n        #endif\n        }\n    #endif /* WOLFSSL_ASYNC_CRYPT */\n\n        blocks = sz / DES_BLOCK_SIZE;\n        while (blocks--) {\n            XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);\n            Des3ProcessBlock(des, (byte*)des->tmp, out);\n            xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);\n            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);\n\n            out += DES_BLOCK_SIZE;\n            in  += DES_BLOCK_SIZE;\n        }\n        return 0;\n    }\n\n    #ifdef WOLFSSL_DES_ECB\n        /* One block, compatibility only */\n        int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)\n        {\n            word32 blocks = sz / DES_BLOCK_SIZE;\n\n            if (des == NULL || out == NULL || in == NULL) {\n                return BAD_FUNC_ARG;\n            }\n\n            while (blocks--) {\n                DesProcessBlock(des, in, out);\n\n                out += DES_BLOCK_SIZE;\n                in  += DES_BLOCK_SIZE;\n            }\n            return 0;\n        }\n\n        int wc_Des3_EcbEncrypt(Des3* des, byte* out, const byte* in, word32 sz)\n        {\n            word32 blocks = sz / DES_BLOCK_SIZE;\n\n            if (des == NULL || out == NULL || in == NULL) {\n                return BAD_FUNC_ARG;\n            }\n\n            while (blocks--) {\n                Des3ProcessBlock(des, in, out);\n\n                out += DES_BLOCK_SIZE;\n                in  += DES_BLOCK_SIZE;\n            }\n            return 0;\n        }\n    #endif /* WOLFSSL_DES_ECB */\n\n#endif /* NEED_SOFT_DES */\n\n\nvoid wc_Des_SetIV(Des* des, const byte* iv)\n{\n    if (des && iv)\n        XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);\n    else if (des)\n        XMEMSET(des->reg,  0, DES_BLOCK_SIZE);\n}\n\nint wc_Des3_SetIV(Des3* des, const byte* iv)\n{\n    if (des == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    if (des && iv)\n        XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);\n    else if (des)\n        XMEMSET(des->reg,  0, DES_BLOCK_SIZE);\n\n    return 0;\n}\n\n\n/* Initialize Des3 for use with async device */\nint wc_Des3Init(Des3* des3, void* heap, int devId)\n{\n    int ret = 0;\n    if (des3 == NULL)\n        return BAD_FUNC_ARG;\n\n    des3->heap = heap;\n\n#ifdef WOLF_CRYPTO_CB\n    des3->devId = devId;\n    des3->devCtx = NULL;\n#else\n    (void)devId;\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)\n    ret = wolfAsync_DevCtxInit(&des3->asyncDev, WOLFSSL_ASYNC_MARKER_3DES,\n                                                        des3->heap, devId);\n#endif\n\n    return ret;\n}\n\n/* Free Des3 from use with async device */\nvoid wc_Des3Free(Des3* des3)\n{\n    if (des3 == NULL)\n        return;\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)\n    wolfAsync_DevCtxFree(&des3->asyncDev, WOLFSSL_ASYNC_MARKER_3DES);\n#endif /* WOLFSSL_ASYNC_CRYPT */\n#if defined(WOLF_CRYPTO_CB) || \\\n        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES))\n    ForceZero(des3->devKey, sizeof(des3->devKey));\n#endif\n}\n\n#endif /* WOLFSSL_TI_CRYPT */\n#endif /* HAVE_FIPS */\n#endif /* NO_DES3 */\n"
  },
  {
    "path": "src/wolfcrypt/src/dh.c",
    "content": "/* dh.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifndef NO_DH\n\n#if defined(HAVE_FIPS) && \\\n\tdefined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n\n    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */\n    #define FIPS_NO_WRAPPERS\n\n    #ifdef USE_WINDOWS_API\n        #pragma code_seg(\".fipsA$m\")\n        #pragma const_seg(\".fipsB$m\")\n    #endif\n#endif\n\n#include <wolfssl/wolfcrypt/dh.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n\n#ifdef WOLFSSL_HAVE_SP_DH\n#include <wolfssl/wolfcrypt/sp.h>\n#endif\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\n/*\nPossible DH enable options:\n * NO_RSA:              Overall control of DH                 default: on (not defined)\n * WOLFSSL_OLD_PRIME_CHECK: Disables the new prime number check. It does not\n                        directly effect this file, but it does speed up DH\n                        removing the testing. It is not recommended to\n                        disable the prime checking.           default: off\n\n*/\n\n\n#if !defined(USER_MATH_LIB) && !defined(WOLFSSL_DH_CONST)\n    #include <math.h>\n    #define XPOW(x,y) pow((x),(y))\n    #define XLOG(x)   log((x))\n#else\n    /* user's own math lib */\n#endif\n\n#ifdef HAVE_FFDHE_2048\nstatic const byte dh_ffdhe2048_p[] = {\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,\n    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,\n    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,\n    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,\n    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,\n    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,\n    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,\n    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,\n    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,\n    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,\n    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,\n    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,\n    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,\n    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,\n    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,\n    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,\n    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,\n    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,\n    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,\n    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,\n    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,\n    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,\n    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,\n    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,\n    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,\n    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,\n    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,\n    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,\n    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,\n    0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97,\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\nstatic const byte dh_ffdhe2048_g[] = { 0x02 };\n#ifdef HAVE_FFDHE_Q\nstatic const byte dh_ffdhe2048_q[] = {\n    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,\n    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,\n    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,\n    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,\n    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,\n    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,\n    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,\n    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,\n    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,\n    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,\n    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,\n    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,\n    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,\n    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,\n    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,\n    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,\n    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,\n    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,\n    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,\n    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,\n    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,\n    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,\n    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,\n    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,\n    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,\n    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,\n    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,\n    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,\n    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,\n    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x94, 0x2E, 0x4B,\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\n#endif /* HAVE_FFDHE_Q */\n\nconst DhParams* wc_Dh_ffdhe2048_Get(void)\n{\n    static const DhParams ffdhe2048 = {\n        #ifdef HAVE_FFDHE_Q\n            dh_ffdhe2048_q, sizeof(dh_ffdhe2048_q),\n        #endif /* HAVE_FFDHE_Q */\n        dh_ffdhe2048_p, sizeof(dh_ffdhe2048_p),\n        dh_ffdhe2048_g, sizeof(dh_ffdhe2048_g)\n    };\n    return &ffdhe2048;\n}\n#endif\n\n#ifdef HAVE_FFDHE_3072\nstatic const byte dh_ffdhe3072_p[] = {\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,\n    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,\n    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,\n    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,\n    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,\n    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,\n    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,\n    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,\n    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,\n    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,\n    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,\n    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,\n    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,\n    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,\n    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,\n    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,\n    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,\n    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,\n    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,\n    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,\n    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,\n    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,\n    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,\n    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,\n    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,\n    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,\n    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,\n    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,\n    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,\n    0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,\n    0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,\n    0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,\n    0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,\n    0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,\n    0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,\n    0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,\n    0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,\n    0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,\n    0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,\n    0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,\n    0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,\n    0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,\n    0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,\n    0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,\n    0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,\n    0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37,\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\nstatic const byte dh_ffdhe3072_g[] = { 0x02 };\n#ifdef HAVE_FFDHE_Q\nstatic const byte dh_ffdhe3072_q[] = {\n    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,\n    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,\n    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,\n    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,\n    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,\n    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,\n    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,\n    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,\n    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,\n    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,\n    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,\n    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,\n    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,\n    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,\n    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,\n    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,\n    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,\n    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,\n    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,\n    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,\n    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,\n    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,\n    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,\n    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,\n    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,\n    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,\n    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,\n    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,\n    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,\n    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,\n    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,\n    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,\n    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,\n    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,\n    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,\n    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,\n    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,\n    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,\n    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,\n    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,\n    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,\n    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,\n    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,\n    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,\n    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,\n    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x63, 0x17, 0x1B,\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\n#endif /* HAVE_FFDHE_Q */\n\nconst DhParams* wc_Dh_ffdhe3072_Get(void)\n{\n    static const DhParams ffdhe3072 = {\n        #ifdef HAVE_FFDHE_Q\n            dh_ffdhe3072_q, sizeof(dh_ffdhe3072_q),\n        #endif /* HAVE_FFDHE_Q */\n        dh_ffdhe3072_p, sizeof(dh_ffdhe3072_p),\n        dh_ffdhe3072_g, sizeof(dh_ffdhe3072_g)\n    };\n    return &ffdhe3072;\n}\n#endif\n\n#ifdef HAVE_FFDHE_4096\nstatic const byte dh_ffdhe4096_p[] = {\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,\n    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,\n    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,\n    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,\n    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,\n    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,\n    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,\n    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,\n    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,\n    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,\n    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,\n    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,\n    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,\n    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,\n    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,\n    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,\n    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,\n    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,\n    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,\n    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,\n    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,\n    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,\n    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,\n    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,\n    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,\n    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,\n    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,\n    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,\n    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,\n    0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,\n    0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,\n    0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,\n    0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,\n    0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,\n    0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,\n    0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,\n    0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,\n    0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,\n    0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,\n    0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,\n    0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,\n    0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,\n    0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,\n    0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,\n    0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,\n    0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,\n    0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,\n    0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,\n    0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,\n    0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,\n    0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,\n    0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,\n    0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,\n    0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,\n    0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,\n    0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,\n    0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,\n    0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,\n    0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,\n    0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,\n    0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,\n    0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A,\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\nstatic const byte dh_ffdhe4096_g[] = { 0x02 };\n#ifdef HAVE_FFDHE_Q\nstatic const byte dh_ffdhe4096_q[] = {\n    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,\n    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,\n    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,\n    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,\n    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,\n    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,\n    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,\n    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,\n    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,\n    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,\n    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,\n    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,\n    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,\n    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,\n    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,\n    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,\n    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,\n    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,\n    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,\n    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,\n    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,\n    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,\n    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,\n    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,\n    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,\n    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,\n    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,\n    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,\n    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,\n    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,\n    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,\n    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,\n    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,\n    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,\n    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,\n    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,\n    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,\n    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,\n    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,\n    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,\n    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,\n    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,\n    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,\n    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,\n    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,\n    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,\n    0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,\n    0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,\n    0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,\n    0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,\n    0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,\n    0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,\n    0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,\n    0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,\n    0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,\n    0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,\n    0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,\n    0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,\n    0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,\n    0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,\n    0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,\n    0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x32, 0xAF, 0xB5,\n    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\n#endif /* HAVE_FFDHE_Q */\n\nconst DhParams* wc_Dh_ffdhe4096_Get(void)\n{\n    static const DhParams ffdhe4096 = {\n        #ifdef HAVE_FFDHE_Q\n            dh_ffdhe4096_q, sizeof(dh_ffdhe4096_q),\n        #endif /* HAVE_FFDHE_Q */\n        dh_ffdhe4096_p, sizeof(dh_ffdhe4096_p),\n        dh_ffdhe4096_g, sizeof(dh_ffdhe4096_g)\n    };\n    return &ffdhe4096;\n}\n#endif\n\n#ifdef HAVE_FFDHE_6144\nstatic const byte dh_ffdhe6144_p[] = {\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,\n    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,\n    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,\n    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,\n    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,\n    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,\n    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,\n    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,\n    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,\n    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,\n    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,\n    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,\n    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,\n    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,\n    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,\n    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,\n    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,\n    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,\n    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,\n    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,\n    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,\n    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,\n    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,\n    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,\n    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,\n    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,\n    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,\n    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,\n    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,\n    0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,\n    0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,\n    0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,\n    0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,\n    0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,\n    0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,\n    0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,\n    0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,\n    0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,\n    0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,\n    0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,\n    0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,\n    0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,\n    0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,\n    0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,\n    0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,\n    0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,\n    0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,\n    0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,\n    0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,\n    0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,\n    0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,\n    0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,\n    0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,\n    0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,\n    0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,\n    0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,\n    0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,\n    0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,\n    0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,\n    0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,\n    0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,\n    0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02,\n    0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A,\n    0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A,\n    0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6,\n    0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8,\n    0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C,\n    0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A,\n    0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71,\n    0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F,\n    0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77,\n    0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10,\n    0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8,\n    0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3,\n    0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E,\n    0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3,\n    0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4,\n    0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1,\n    0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92,\n    0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6,\n    0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82,\n    0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE,\n    0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C,\n    0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E,\n    0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46,\n    0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A,\n    0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17,\n    0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03,\n    0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04,\n    0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6,\n    0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69,\n    0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1,\n    0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4,\n    0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65,\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\nstatic const byte dh_ffdhe6144_g[] = { 0x02 };\n#ifdef HAVE_FFDHE_Q\nstatic const byte dh_ffdhe6144_q[] = {\n    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,\n    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,\n    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,\n    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,\n    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,\n    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,\n    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,\n    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,\n    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,\n    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,\n    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,\n    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,\n    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,\n    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,\n    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,\n    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,\n    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,\n    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,\n    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,\n    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,\n    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,\n    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,\n    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,\n    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,\n    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,\n    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,\n    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,\n    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,\n    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,\n    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,\n    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,\n    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,\n    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,\n    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,\n    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,\n    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,\n    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,\n    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,\n    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,\n    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,\n    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,\n    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,\n    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,\n    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,\n    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,\n    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,\n    0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,\n    0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,\n    0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,\n    0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,\n    0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,\n    0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,\n    0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,\n    0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,\n    0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,\n    0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,\n    0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,\n    0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,\n    0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,\n    0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,\n    0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,\n    0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81,\n    0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D,\n    0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D,\n    0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53,\n    0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64,\n    0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6,\n    0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D,\n    0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38,\n    0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F,\n    0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B,\n    0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88,\n    0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C,\n    0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1,\n    0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37,\n    0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1,\n    0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA,\n    0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0,\n    0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9,\n    0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB,\n    0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41,\n    0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F,\n    0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6,\n    0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF,\n    0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23,\n    0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5,\n    0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B,\n    0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01,\n    0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82,\n    0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B,\n    0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34,\n    0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0,\n    0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A,\n    0x52, 0x07, 0x19, 0x4E, 0x68, 0x72, 0x07, 0x32,\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\n#endif /* HAVE_FFDHE_Q */\n\nconst DhParams* wc_Dh_ffdhe6144_Get(void)\n{\n    static const DhParams ffdhe6144 = {\n        #ifdef HAVE_FFDHE_Q\n            dh_ffdhe6144_q, sizeof(dh_ffdhe6144_q),\n        #endif /* HAVE_FFDHE_Q */\n        dh_ffdhe6144_p, sizeof(dh_ffdhe6144_p),\n        dh_ffdhe6144_g, sizeof(dh_ffdhe6144_g)\n    };\n    return &ffdhe6144;\n}\n#endif\n\n#ifdef HAVE_FFDHE_8192\nstatic const byte dh_ffdhe8192_p[] = {\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,\n    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,\n    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,\n    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,\n    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,\n    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,\n    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,\n    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,\n    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,\n    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,\n    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,\n    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,\n    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,\n    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,\n    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,\n    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,\n    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,\n    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,\n    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,\n    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,\n    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,\n    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,\n    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,\n    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,\n    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,\n    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,\n    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,\n    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,\n    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,\n    0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,\n    0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,\n    0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,\n    0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,\n    0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,\n    0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,\n    0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,\n    0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,\n    0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,\n    0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,\n    0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,\n    0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,\n    0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,\n    0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,\n    0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,\n    0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,\n    0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,\n    0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,\n    0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,\n    0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,\n    0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,\n    0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,\n    0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,\n    0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,\n    0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,\n    0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,\n    0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,\n    0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,\n    0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,\n    0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,\n    0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,\n    0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,\n    0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02,\n    0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A,\n    0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A,\n    0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6,\n    0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8,\n    0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C,\n    0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A,\n    0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71,\n    0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F,\n    0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77,\n    0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10,\n    0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8,\n    0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3,\n    0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E,\n    0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3,\n    0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4,\n    0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1,\n    0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92,\n    0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6,\n    0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82,\n    0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE,\n    0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C,\n    0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E,\n    0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46,\n    0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A,\n    0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17,\n    0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03,\n    0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04,\n    0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6,\n    0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69,\n    0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1,\n    0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4,\n    0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA,\n    0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38,\n    0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64,\n    0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43,\n    0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E,\n    0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF,\n    0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29,\n    0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65,\n    0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02,\n    0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4,\n    0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82,\n    0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C,\n    0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51,\n    0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22,\n    0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74,\n    0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE,\n    0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C,\n    0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC,\n    0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B,\n    0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9,\n    0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0,\n    0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31,\n    0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57,\n    0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8,\n    0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E,\n    0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30,\n    0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E,\n    0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE,\n    0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D,\n    0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D,\n    0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E,\n    0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C,\n    0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C,\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\nstatic const byte dh_ffdhe8192_g[] = { 0x02 };\n#ifdef HAVE_FFDHE_Q\nstatic const byte dh_ffdhe8192_q[] = {\n    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,\n    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,\n    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,\n    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,\n    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,\n    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,\n    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,\n    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,\n    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,\n    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,\n    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,\n    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,\n    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,\n    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,\n    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,\n    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,\n    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,\n    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,\n    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,\n    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,\n    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,\n    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,\n    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,\n    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,\n    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,\n    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,\n    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,\n    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,\n    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,\n    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,\n    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,\n    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,\n    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,\n    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,\n    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,\n    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,\n    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,\n    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,\n    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,\n    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,\n    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,\n    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,\n    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,\n    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,\n    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,\n    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,\n    0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,\n    0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,\n    0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,\n    0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,\n    0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,\n    0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,\n    0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,\n    0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,\n    0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,\n    0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,\n    0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,\n    0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,\n    0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,\n    0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,\n    0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,\n    0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81,\n    0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D,\n    0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D,\n    0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53,\n    0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64,\n    0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6,\n    0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D,\n    0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38,\n    0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F,\n    0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B,\n    0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88,\n    0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C,\n    0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1,\n    0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37,\n    0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1,\n    0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA,\n    0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0,\n    0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9,\n    0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB,\n    0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41,\n    0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F,\n    0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6,\n    0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF,\n    0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23,\n    0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5,\n    0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B,\n    0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01,\n    0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82,\n    0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B,\n    0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34,\n    0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0,\n    0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A,\n    0x52, 0x07, 0x19, 0x4E, 0x67, 0xFA, 0x35, 0x55,\n    0x1B, 0x56, 0x80, 0x26, 0x7B, 0x00, 0x64, 0x1C,\n    0x0F, 0x21, 0x2D, 0x18, 0xEC, 0xA8, 0xD7, 0x32,\n    0x7E, 0xD9, 0x1F, 0xE7, 0x64, 0xA8, 0x4E, 0xA1,\n    0xB4, 0x3F, 0xF5, 0xB4, 0xF6, 0xE8, 0xE6, 0x2F,\n    0x05, 0xC6, 0x61, 0xDE, 0xFB, 0x25, 0x88, 0x77,\n    0xC3, 0x5B, 0x18, 0xA1, 0x51, 0xD5, 0xC4, 0x14,\n    0xAA, 0xAD, 0x97, 0xBA, 0x3E, 0x49, 0x93, 0x32,\n    0xE5, 0x96, 0x07, 0x8E, 0x60, 0x0D, 0xEB, 0x81,\n    0x14, 0x9C, 0x44, 0x1C, 0xE9, 0x57, 0x82, 0xF2,\n    0x2A, 0x28, 0x25, 0x63, 0xC5, 0xBA, 0xC1, 0x41,\n    0x14, 0x23, 0x60, 0x5D, 0x1A, 0xE1, 0xAF, 0xAE,\n    0x2C, 0x8B, 0x06, 0x60, 0x23, 0x7E, 0xC1, 0x28,\n    0xAA, 0x0F, 0xE3, 0x46, 0x4E, 0x43, 0x58, 0x11,\n    0x5D, 0xB8, 0x4C, 0xC3, 0xB5, 0x23, 0x07, 0x3A,\n    0x28, 0xD4, 0x54, 0x98, 0x84, 0xB8, 0x1F, 0xF7,\n    0x0E, 0x10, 0xBF, 0x36, 0x1C, 0x13, 0x72, 0x96,\n    0x28, 0xD5, 0x34, 0x8F, 0x07, 0x21, 0x1E, 0x7E,\n    0x4C, 0xF4, 0xF1, 0x8B, 0x28, 0x60, 0x90, 0xBD,\n    0xB1, 0x24, 0x0B, 0x66, 0xD6, 0xCD, 0x4A, 0xFC,\n    0xEA, 0xDC, 0x00, 0xCA, 0x44, 0x6C, 0xE0, 0x50,\n    0x50, 0xFF, 0x18, 0x3A, 0xD2, 0xBB, 0xF1, 0x18,\n    0xC1, 0xFC, 0x0E, 0xA5, 0x1F, 0x97, 0xD2, 0x2B,\n    0x8F, 0x7E, 0x46, 0x70, 0x5D, 0x45, 0x27, 0xF4,\n    0x5B, 0x42, 0xAE, 0xFF, 0x39, 0x58, 0x53, 0x37,\n    0x6F, 0x69, 0x7D, 0xD5, 0xFD, 0xF2, 0xC5, 0x18,\n    0x7D, 0x7D, 0x5F, 0x0E, 0x2E, 0xB8, 0xD4, 0x3F,\n    0x17, 0xBA, 0x0F, 0x7C, 0x60, 0xFF, 0x43, 0x7F,\n    0x53, 0x5D, 0xFE, 0xF2, 0x98, 0x33, 0xBF, 0x86,\n    0xCB, 0xE8, 0x8E, 0xA4, 0xFB, 0xD4, 0x22, 0x1E,\n    0x84, 0x11, 0x72, 0x83, 0x54, 0xFA, 0x30, 0xA7,\n    0x00, 0x8F, 0x15, 0x4A, 0x41, 0xC7, 0xFC, 0x46,\n    0x6B, 0x46, 0x45, 0xDB, 0xE2, 0xE3, 0x21, 0x26,\n    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n};\n#endif /* HAVE_FFDHE_Q */\n\nconst DhParams* wc_Dh_ffdhe8192_Get(void)\n{\n    static const DhParams ffdhe8192 = {\n        #ifdef HAVE_FFDHE_Q\n            dh_ffdhe8192_q, sizeof(dh_ffdhe8192_q),\n        #endif /* HAVE_FFDHE_Q */\n        dh_ffdhe8192_p, sizeof(dh_ffdhe8192_p),\n        dh_ffdhe8192_g, sizeof(dh_ffdhe8192_g)\n    };\n    return &ffdhe8192;\n}\n#endif\n\nint wc_InitDhKey_ex(DhKey* key, void* heap, int devId)\n{\n    int ret = 0;\n\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    key->heap = heap; /* for XMALLOC/XFREE in future */\n\n    if (mp_init_multi(&key->p, &key->g, &key->q, NULL, NULL, NULL) != MP_OKAY)\n        return MEMORY_E;\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)\n    /* handle as async */\n    ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_DH,\n        key->heap, devId);\n#else\n    (void)devId;\n#endif\n\n    return ret;\n}\n\nint wc_InitDhKey(DhKey* key)\n{\n    return wc_InitDhKey_ex(key, NULL, INVALID_DEVID);\n}\n\n\nint wc_FreeDhKey(DhKey* key)\n{\n    if (key) {\n        mp_clear(&key->p);\n        mp_clear(&key->g);\n        mp_clear(&key->q);\n\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)\n        wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_DH);\n    #endif\n    }\n    return 0;\n}\n\n\n#ifndef WC_NO_RNG\n/* if defined to not use floating point values do not compile in */\n#ifndef WOLFSSL_DH_CONST\n    static word32 DiscreteLogWorkFactor(word32 n)\n    {\n        /* assuming discrete log takes about the same time as factoring */\n        if (n < 5)\n            return 0;\n        else\n            return (word32)(2.4 * XPOW((double)n, 1.0/3.0) *\n                    XPOW(XLOG((double)n), 2.0/3.0) - 5);\n    }\n#endif /* WOLFSSL_DH_CONST*/\n\n\n/* if not using fixed points use DiscreteLogWorkFactor function for unsual size\n   otherwise round up on size needed */\n#ifndef WOLFSSL_DH_CONST\n    #define WOLFSSL_DH_ROUND(x)\n#else\n    #define WOLFSSL_DH_ROUND(x) \\\n        do {                    \\\n            if (x % 128) {      \\\n                x &= 0xffffff80;\\\n                x += 128;       \\\n            }                   \\\n        }                       \\\n        while (0)\n#endif\n\n\n#ifndef WOLFSSL_NO_DH186\n/* validate that (L,N) match allowed sizes from SP 800-56A, Section 5.5.1.1.\n * modLen - represents L, the size of p in bits\n * divLen - represents N, the size of q in bits\n * return 0 on success, -1 on error */\nstatic int CheckDhLN(int modLen, int divLen)\n{\n    int ret = -1;\n\n    switch (modLen) {\n        /* FA */\n        case 1024:\n            if (divLen == 160)\n                ret = 0;\n            break;\n        /* FB, FC */\n        case 2048:\n            if (divLen == 224 || divLen == 256)\n                ret = 0;\n            break;\n        default:\n            break;\n    }\n\n    return ret;\n}\n\n\n/* Create DH private key\n *\n * Based on NIST FIPS 186-4,\n * \"B.1.1 Key Pair Generation Using Extra Random Bits\"\n *\n * dh     - pointer to initialized DhKey structure, needs to have dh->q\n * rng    - pointer to initialized WC_RNG structure\n * priv   - output location for generated private key\n * privSz - IN/OUT, size of priv buffer, size of generated private key\n *\n * return 0 on success, negative on error */\nstatic int GeneratePrivateDh186(DhKey* key, WC_RNG* rng, byte* priv,\n                                word32* privSz)\n{\n    byte* cBuf;\n    int qSz, pSz, cSz, err;\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int* tmpQ = NULL;\n    mp_int* tmpX = NULL;\n#else\n    mp_int tmpQ[1], tmpX[1];\n#endif\n\n    /* Parameters validated in calling functions. */\n\n    if (mp_iszero(&key->q) == MP_YES) {\n        WOLFSSL_MSG(\"DH q parameter needed for FIPS 186-4 key generation\");\n        return BAD_FUNC_ARG;\n    }\n\n    qSz = mp_unsigned_bin_size(&key->q);\n    pSz = mp_unsigned_bin_size(&key->p);\n\n    /* verify (L,N) pair bit lengths */\n    if (CheckDhLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) {\n        WOLFSSL_MSG(\"DH param sizes do not match SP 800-56A requirements\");\n        return BAD_FUNC_ARG;\n    }\n\n    /* generate extra 64 bits so that bias from mod function is negligible */\n    cSz = qSz + (64 / WOLFSSL_BIT_SIZE);\n    cBuf = (byte*)XMALLOC(cSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (cBuf == NULL) {\n        return MEMORY_E;\n    }\n#ifdef WOLFSSL_SMALL_STACK\n    tmpQ = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (tmpQ == NULL) {\n        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n    tmpX = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (tmpX == NULL) {\n        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);\n        return MEMORY_E;\n    }\n#endif\n\n\n    if ((err = mp_init_multi(tmpX, tmpQ, NULL, NULL, NULL, NULL))\n                   != MP_OKAY) {\n        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);\n#endif\n        return err;\n    }\n\n    do {\n        /* generate N+64 bits (c) from RBG into tmpX, making sure positive.\n         * Hash_DRBG uses SHA-256 which matches maximum\n         * requested_security_strength of (L,N) */\n        err = wc_RNG_GenerateBlock(rng, cBuf, cSz);\n        if (err == MP_OKAY)\n            err = mp_read_unsigned_bin(tmpX, cBuf, cSz);\n        if (err != MP_OKAY) {\n            mp_clear(tmpX);\n            mp_clear(tmpQ);\n            XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);\n            XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);\n#endif\n            return err;\n        }\n    } while (mp_cmp_d(tmpX, 1) != MP_GT);\n\n    ForceZero(cBuf, cSz);\n    XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    /* tmpQ = q - 1 */\n    if (err == MP_OKAY)\n        err = mp_copy(&key->q, tmpQ);\n\n    if (err == MP_OKAY)\n        err = mp_sub_d(tmpQ, 1, tmpQ);\n\n    /* x = c mod (q-1), tmpX holds c */\n    if (err == MP_OKAY)\n        err = mp_mod(tmpX, tmpQ, tmpX);\n\n    /* x = c mod (q-1) + 1 */\n    if (err == MP_OKAY)\n        err = mp_add_d(tmpX, 1, tmpX);\n\n    /* copy tmpX into priv */\n    if (err == MP_OKAY) {\n        pSz = mp_unsigned_bin_size(tmpX);\n        if (pSz > (int)*privSz) {\n            WOLFSSL_MSG(\"DH private key output buffer too small\");\n            err = BAD_FUNC_ARG;\n        } else {\n            *privSz = pSz;\n            err = mp_to_unsigned_bin(tmpX, priv);\n        }\n    }\n\n    mp_forcezero(tmpX);\n    mp_clear(tmpX);\n    mp_clear(tmpQ);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);\n    XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_NO_DH186 */\n#endif /* !WC_NO_RNG */\n\nstatic int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv,\n                             word32* privSz)\n{\n#ifndef WC_NO_RNG\n    int ret = 0;\n    word32 sz = 0;\n\n#ifndef WOLFSSL_NO_DH186\n    if (mp_iszero(&key->q) == MP_NO) {\n\n        /* q param available, use NIST FIPS 186-4, \"B.1.1 Key Pair\n         * Generation Using Extra Random Bits\" */\n        ret = GeneratePrivateDh186(key, rng, priv, privSz);\n\n    } else\n#endif\n    {\n\n        sz = mp_unsigned_bin_size(&key->p);\n\n        /* Table of predetermined values from the operation\n           2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /\n           WOLFSSL_BIT_SIZE + 1\n           Sizes in table checked against RFC 3526\n         */\n        WOLFSSL_DH_ROUND(sz); /* if using fixed points only, then round up */\n        switch (sz) {\n            case 128:  sz = 21; break;\n            case 256:  sz = 29; break;\n            case 384:  sz = 34; break;\n            case 512:  sz = 39; break;\n            case 640:  sz = 42; break;\n            case 768:  sz = 46; break;\n            case 896:  sz = 49; break;\n            case 1024: sz = 52; break;\n            default:\n            #ifndef WOLFSSL_DH_CONST\n                /* if using floating points and size of p is not in table */\n                sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /\n                                           WOLFSSL_BIT_SIZE + 1);\n                break;\n            #else\n                return BAD_FUNC_ARG;\n            #endif\n        }\n\n        ret = wc_RNG_GenerateBlock(rng, priv, sz);\n\n        if (ret == 0) {\n            priv[0] |= 0x0C;\n            *privSz = sz;\n        }\n    }\n\n    return ret;\n#else\n    (void)key;\n    (void)rng;\n    (void)priv;\n    (void)privSz;\n    return NOT_COMPILED_IN;\n#endif /* WC_NO_RNG */\n}\n\n\nstatic int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz,\n    byte* pub, word32* pubSz)\n{\n    int ret = 0;\n#ifndef WOLFSSL_SP_MATH\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int* x = NULL;\n    mp_int* y = NULL;\n#else\n    mp_int x[1];\n    mp_int y[1];\n#endif\n#endif\n\n#ifdef WOLFSSL_HAVE_SP_DH\n#ifndef WOLFSSL_SP_NO_2048\n    if (mp_count_bits(&key->p) == 2048)\n        return sp_DhExp_2048(&key->g, priv, privSz, &key->p, pub, pubSz);\n#endif\n#ifndef WOLFSSL_SP_NO_3072\n    if (mp_count_bits(&key->p) == 3072)\n        return sp_DhExp_3072(&key->g, priv, privSz, &key->p, pub, pubSz);\n#endif\n#ifdef WOLFSSL_SP_4096\n    if (mp_count_bits(&key->p) == 4096)\n        return sp_DhExp_4096(&key->g, priv, privSz, &key->p, pub, pubSz);\n#endif\n#endif\n\n#ifndef WOLFSSL_SP_MATH\n#ifdef WOLFSSL_SMALL_STACK\n    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (x == NULL)\n        return MEMORY_E;\n    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (y == NULL) {\n        XFREE(x, key->heap, DYNAMIC_TYPE_DH);\n        return MEMORY_E;\n    }\n#endif\n    if (mp_init_multi(x, y, 0, 0, 0, 0) != MP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(y, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(x, key->heap, DYNAMIC_TYPE_DH);\n    #endif\n        return MP_INIT_E;\n    }\n\n    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)\n        ret = MP_READ_E;\n\n    if (ret == 0 && mp_exptmod(&key->g, x, &key->p, y) != MP_OKAY)\n        ret = MP_EXPTMOD_E;\n\n    if (ret == 0 && mp_to_unsigned_bin(y, pub) != MP_OKAY)\n        ret = MP_TO_E;\n\n    if (ret == 0)\n        *pubSz = mp_unsigned_bin_size(y);\n\n    mp_clear(y);\n    mp_clear(x);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(y, key->heap, DYNAMIC_TYPE_DH);\n    XFREE(x, key->heap, DYNAMIC_TYPE_DH);\n#endif\n#else\n    ret = WC_KEY_SIZE_E;\n#endif\n\n    return ret;\n}\n\nstatic int wc_DhGenerateKeyPair_Sync(DhKey* key, WC_RNG* rng,\n    byte* priv, word32* privSz, byte* pub, word32* pubSz)\n{\n    int ret;\n\n    if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||\n        pub == NULL || pubSz == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    ret = GeneratePrivateDh(key, rng, priv, privSz);\n\n    return (ret != 0) ? ret : GeneratePublicDh(key, priv, *privSz, pub, pubSz);\n}\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)\nstatic int wc_DhGenerateKeyPair_Async(DhKey* key, WC_RNG* rng,\n    byte* priv, word32* privSz, byte* pub, word32* pubSz)\n{\n    int ret;\n\n#if defined(HAVE_INTEL_QA)\n    word32 pBits;\n\n    /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */\n    pBits = mp_unsigned_bin_size(&key->p) * 8;\n    if (pBits == 768 ||  pBits == 1024 || pBits == 1536 ||\n        pBits == 2048 || pBits == 3072 || pBits == 4096) {\n        mp_int x;\n\n        ret = mp_init(&x);\n        if (ret != MP_OKAY)\n            return ret;\n\n        ret = GeneratePrivateDh(key, rng, priv, privSz);\n        if (ret == 0)\n            ret = mp_read_unsigned_bin(&x, priv, *privSz);\n        if (ret == MP_OKAY)\n            ret = wc_mp_to_bigint(&x, &x.raw);\n        if (ret == MP_OKAY)\n            ret = wc_mp_to_bigint(&key->p, &key->p.raw);\n        if (ret == MP_OKAY)\n            ret = wc_mp_to_bigint(&key->g, &key->g.raw);\n        if (ret == MP_OKAY)\n            ret = IntelQaDhKeyGen(&key->asyncDev, &key->p.raw, &key->g.raw,\n                &x.raw, pub, pubSz);\n        mp_clear(&x);\n\n        return ret;\n    }\n\n#elif defined(HAVE_CAVIUM)\n    /* TODO: Not implemented - use software for now */\n\n#else /* WOLFSSL_ASYNC_CRYPT_TEST */\n    if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_DH_GEN)) {\n        WC_ASYNC_TEST* testDev = &key->asyncDev.test;\n        testDev->dhGen.key = key;\n        testDev->dhGen.rng = rng;\n        testDev->dhGen.priv = priv;\n        testDev->dhGen.privSz = privSz;\n        testDev->dhGen.pub = pub;\n        testDev->dhGen.pubSz = pubSz;\n        return WC_PENDING_E;\n    }\n#endif\n\n    /* otherwise use software DH */\n    ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);\n\n    return ret;\n}\n#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_DH */\n\n\n/* Check DH Public Key for invalid numbers, optionally allowing\n * the public key to be checked against the large prime (q).\n * Check per process in SP 800-56Ar3, section 5.6.2.3.1.\n *\n * key     DH key group parameters.\n * pub     Public Key.\n * pubSz   Public Key size.\n * prime   Large prime (q), optionally NULL to skip check\n * primeSz Size of large prime\n *\n *  returns 0 on success or error code\n */\nint wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,\n                        const byte* prime, word32 primeSz)\n{\n    int ret = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int* y = NULL;\n    mp_int* p = NULL;\n    mp_int* q = NULL;\n#else\n    mp_int y[1];\n    mp_int p[1];\n    mp_int q[1];\n#endif\n\n    if (key == NULL || pub == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (y == NULL)\n        return MEMORY_E;\n    p = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (p == NULL) {\n        XFREE(y, key->heap, DYNAMIC_TYPE_DH);\n        return MEMORY_E;\n    }\n    q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (q == NULL) {\n        XFREE(p, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(y, key->heap, DYNAMIC_TYPE_DH);\n        return MEMORY_E;\n    }\n#endif\n\n    if (mp_init_multi(y, p, q, NULL, NULL, NULL) != MP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(q, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(p, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(y, key->heap, DYNAMIC_TYPE_DH);\n    #endif\n        return MP_INIT_E;\n    }\n\n    if (mp_read_unsigned_bin(y, pub, pubSz) != MP_OKAY) {\n        ret = MP_READ_E;\n    }\n\n    if (ret == 0 && prime != NULL) {\n        if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)\n            ret = MP_READ_E;\n\n    } else if (mp_iszero(&key->q) == MP_NO) {\n        /* use q available in DhKey */\n        if (mp_copy(&key->q, q) != MP_OKAY)\n            ret = MP_INIT_E;\n    }\n\n    /* SP 800-56Ar3, section 5.6.2.3.1, process step 1 */\n    /* pub (y) should not be 0 or 1 */\n    if (ret == 0 && mp_cmp_d(y, 2) == MP_LT) {\n        ret = MP_CMP_E;\n    }\n\n    /* pub (y) shouldn't be greater than or equal to p - 1 */\n    if (ret == 0 && mp_copy(&key->p, p) != MP_OKAY) {\n        ret = MP_INIT_E;\n    }\n    if (ret == 0 && mp_sub_d(p, 2, p) != MP_OKAY) {\n        ret = MP_SUB_E;\n    }\n    if (ret == 0 && mp_cmp(y, p) == MP_GT) {\n        ret = MP_CMP_E;\n    }\n\n    if (ret == 0 && (prime != NULL || (mp_iszero(&key->q) == MP_NO) )) {\n\n        /* restore key->p into p */\n        if (mp_copy(&key->p, p) != MP_OKAY)\n            ret = MP_INIT_E;\n    }\n\n    if (ret == 0 && prime != NULL) {\n#ifdef WOLFSSL_HAVE_SP_DH\n#ifndef WOLFSSL_SP_NO_2048\n        if (mp_count_bits(&key->p) == 2048) {\n            ret = sp_ModExp_2048(y, q, p, y);\n            if (ret != 0)\n                ret = MP_EXPTMOD_E;\n        }\n        else\n#endif\n#ifndef WOLFSSL_SP_NO_3072\n        if (mp_count_bits(&key->p) == 3072) {\n            ret = sp_ModExp_3072(y, q, p, y);\n            if (ret != 0)\n                ret = MP_EXPTMOD_E;\n        }\n        else\n#endif\n#ifdef WOLFSSL_SP_NO_4096\n        if (mp_count_bits(&key->p) == 4096) {\n            ret = sp_ModExp_4096(y, q, p, y);\n            if (ret != 0)\n                ret = MP_EXPTMOD_E;\n        }\n        else\n#endif\n#endif\n\n        {\n    /* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */\n#ifndef WOLFSSL_SP_MATH\n            /* calculate (y^q) mod(p), store back into y */\n            if (ret == 0 && mp_exptmod(y, q, p, y) != MP_OKAY)\n                ret = MP_EXPTMOD_E;\n#else\n            ret = WC_KEY_SIZE_E;\n#endif\n        }\n\n        /* verify above == 1 */\n        if (ret == 0 && mp_cmp_d(y, 1) != MP_EQ)\n            ret = MP_CMP_E;\n    }\n\n    mp_clear(y);\n    mp_clear(p);\n    mp_clear(q);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(q, key->heap, DYNAMIC_TYPE_DH);\n    XFREE(p, key->heap, DYNAMIC_TYPE_DH);\n    XFREE(y, key->heap, DYNAMIC_TYPE_DH);\n#endif\n\n    return ret;\n}\n\n\n/* Check DH Public Key for invalid numbers\n *\n * key   DH key group parameters.\n * pub   Public Key.\n * pubSz Public Key size.\n *\n *  returns 0 on success or error code\n */\nint wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz)\n{\n    return wc_DhCheckPubKey_ex(key, pub, pubSz, NULL, 0);\n}\n\n\n/**\n * Quick validity check of public key value agaist prime.\n * Checks are:\n *   - Public key not 0 or 1\n *   - Public key not equal to prime or prime - 1\n *   - Public key not bigger than prime.\n *\n * prime    Big-endian encoding of prime in bytes.\n * primeSz  Size of prime in bytes.\n * pub      Big-endian encoding of public key in bytes.\n * pubSz    Size of public key in bytes.\n */\nint wc_DhCheckPubValue(const byte* prime, word32 primeSz, const byte* pub,\n                       word32 pubSz)\n{\n    int ret = 0;\n    word32 i;\n\n    for (i = 0; i < pubSz && pub[i] == 0; i++) {\n    }\n    pubSz -= i;\n    pub += i;\n\n    if (pubSz == 0 || (pubSz == 1 && pub[0] == 1))\n        ret = MP_VAL;\n    else if (pubSz == primeSz) {\n        for (i = 0; i < pubSz-1 && pub[i] == prime[i]; i++) {\n        }\n        if (i == pubSz-1 && (pub[i] == prime[i] || pub[i] == prime[i] - 1))\n            ret = MP_VAL;\n        else if (pub[i] > prime[i])\n            ret = MP_VAL;\n    }\n    else if (pubSz > primeSz)\n        ret = MP_VAL;\n\n    return ret;\n}\n\n\n/* Check DH Private Key for invalid numbers, optionally allowing\n * the private key to be checked against the large prime (q).\n * Check per process in SP 800-56Ar3, section 5.6.2.1.2.\n *\n * key     DH key group parameters.\n * priv    Private Key.\n * privSz  Private Key size.\n * prime   Large prime (q), optionally NULL to skip check\n * primeSz Size of large prime\n *\n *  returns 0 on success or error code\n */\nint wc_DhCheckPrivKey_ex(DhKey* key, const byte* priv, word32 privSz,\n                         const byte* prime, word32 primeSz)\n{\n    int ret = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int* x = NULL;\n    mp_int* q = NULL;\n#else\n    mp_int x[1];\n    mp_int q[1];\n#endif\n\n    if (key == NULL || priv == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (x == NULL)\n        return MEMORY_E;\n    q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (q == NULL) {\n        XFREE(x, key->heap, DYNAMIC_TYPE_DH);\n        return MEMORY_E;\n    }\n#endif\n\n    if (mp_init_multi(x, q, NULL, NULL, NULL, NULL) != MP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(q, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(x, key->heap, DYNAMIC_TYPE_DH);\n    #endif\n        return MP_INIT_E;\n    }\n\n    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY) {\n        ret = MP_READ_E;\n    }\n\n    if (ret == 0) {\n        if (prime != NULL) {\n            if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)\n                ret = MP_READ_E;\n        }\n        else if (mp_iszero(&key->q) == MP_NO) {\n            /* use q available in DhKey */\n            if (mp_copy(&key->q, q) != MP_OKAY)\n                ret = MP_INIT_E;\n        }\n    }\n\n    /* priv (x) should not be 0 */\n    if (ret == 0) {\n        if (mp_cmp_d(x, 0) == MP_EQ)\n            ret = MP_CMP_E;\n    }\n\n    if (ret == 0) {\n        if (mp_iszero(q) == MP_NO) {\n            /* priv (x) shouldn't be greater than q - 1 */\n            if (ret == 0) {\n                if (mp_copy(&key->q, q) != MP_OKAY)\n                    ret = MP_INIT_E;\n            }\n            if (ret == 0) {\n                if (mp_sub_d(q, 1, q) != MP_OKAY)\n                    ret = MP_SUB_E;\n            }\n            if (ret == 0) {\n                if (mp_cmp(x, q) == MP_GT)\n                    ret = DH_CHECK_PRIV_E;\n            }\n        }\n    }\n\n    mp_clear(x);\n    mp_clear(q);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(q, key->heap, DYNAMIC_TYPE_DH);\n    XFREE(x, key->heap, DYNAMIC_TYPE_DH);\n#endif\n\n    return ret;\n}\n\n\n/* Check DH Private Key for invalid numbers\n *\n * key    DH key group parameters.\n * priv   Private Key.\n * privSz Private Key size.\n *\n *  returns 0 on success or error code\n */\nint wc_DhCheckPrivKey(DhKey* key, const byte* priv, word32 privSz)\n{\n    return wc_DhCheckPrivKey_ex(key, priv, privSz, NULL, 0);\n}\n\n\n/* Check DH Keys for pair-wise consistency per process in\n * SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC.\n *\n * key    DH key group parameters.\n * pub    Public Key.\n * pubSz  Public Key size.\n * priv   Private Key.\n * privSz Private Key size.\n *\n *  returns 0 on success or error code\n */\nint wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz,\n                      const byte* priv, word32 privSz)\n{\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int* publicKey = NULL;\n    mp_int* privateKey = NULL;\n    mp_int* checkKey = NULL;\n#else\n    mp_int publicKey[1];\n    mp_int privateKey[1];\n    mp_int checkKey[1];\n#endif\n    int ret = 0;\n\n    if (key == NULL || pub == NULL || priv == NULL)\n        return BAD_FUNC_ARG;\n\n#ifdef WOLFSSL_SMALL_STACK\n    publicKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (publicKey == NULL)\n        return MEMORY_E;\n    privateKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (privateKey == NULL) {\n        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);\n        return MEMORY_E;\n    }\n    checkKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (checkKey == NULL) {\n        XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);\n        return MEMORY_E;\n    }\n#endif\n\n    if (mp_init_multi(publicKey, privateKey, checkKey,\n                      NULL, NULL, NULL) != MP_OKAY) {\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);\n    #endif\n        return MP_INIT_E;\n    }\n\n    /* Load the private and public keys into big integers. */\n    if (mp_read_unsigned_bin(publicKey, pub, pubSz) != MP_OKAY ||\n        mp_read_unsigned_bin(privateKey, priv, privSz) != MP_OKAY) {\n\n        ret = MP_READ_E;\n    }\n\n    /* Calculate checkKey = g^privateKey mod p */\n    if (ret == 0) {\n#ifdef WOLFSSL_HAVE_SP_DH\n#ifndef WOLFSSL_SP_NO_2048\n        if (mp_count_bits(&key->p) == 2048) {\n            ret = sp_ModExp_2048(&key->g, privateKey, &key->p, checkKey);\n            if (ret != 0)\n                ret = MP_EXPTMOD_E;\n        }\n        else\n#endif\n#ifndef WOLFSSL_SP_NO_3072\n        if (mp_count_bits(&key->p) == 3072) {\n            ret = sp_ModExp_3072(&key->g, privateKey, &key->p, checkKey);\n            if (ret != 0)\n                ret = MP_EXPTMOD_E;\n        }\n        else\n#endif\n#ifdef WOLFSSL_SP_4096\n        if (mp_count_bits(&key->p) == 4096) {\n            ret = sp_ModExp_4096(&key->g, privateKey, &key->p, checkKey);\n            if (ret != 0)\n                ret = MP_EXPTMOD_E;\n        }\n        else\n#endif\n#endif\n        {\n#ifndef WOLFSSL_SP_MATH\n            if (mp_exptmod(&key->g, privateKey, &key->p, checkKey) != MP_OKAY)\n                ret = MP_EXPTMOD_E;\n#else\n            ret = WC_KEY_SIZE_E;\n#endif\n        }\n    }\n\n    /* Compare the calculated public key to the supplied check value. */\n    if (ret == 0) {\n        if (mp_cmp(checkKey, publicKey) != MP_EQ)\n            ret = MP_CMP_E;\n    }\n\n    mp_forcezero(privateKey);\n    mp_clear(privateKey);\n    mp_clear(publicKey);\n    mp_clear(checkKey);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);\n    XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);\n    XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);\n#endif\n\n    return ret;\n}\n\n\nint wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng,\n    byte* priv, word32* privSz, byte* pub, word32* pubSz)\n{\n    int ret;\n\n    if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||\n                                                pub == NULL || pubSz == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)\n    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {\n        ret = wc_DhGenerateKeyPair_Async(key, rng, priv, privSz, pub, pubSz);\n    }\n    else\n#endif\n    {\n        ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);\n    }\n\n    return ret;\n}\n\n\nstatic int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,\n    const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz)\n{\n    int ret = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int* y = NULL;\n#ifndef WOLFSSL_SP_MATH\n    mp_int* x = NULL;\n    mp_int* z = NULL;\n#endif\n#else\n    mp_int y[1];\n#ifndef WOLFSSL_SP_MATH\n    mp_int x[1];\n    mp_int z[1];\n#endif\n#endif\n\n#ifdef WOLFSSL_VALIDATE_FFC_IMPORT\n    if (wc_DhCheckPrivKey(key, priv, privSz) != 0) {\n        WOLFSSL_MSG(\"wc_DhAgree wc_DhCheckPrivKey failed\");\n        return DH_CHECK_PRIV_E;\n    }\n\n    if (wc_DhCheckPubKey(key, otherPub, pubSz) != 0) {\n        WOLFSSL_MSG(\"wc_DhAgree wc_DhCheckPubKey failed\");\n        return DH_CHECK_PUB_E;\n    }\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (y == NULL)\n        return MEMORY_E;\n#ifndef WOLFSSL_SP_MATH\n    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (x == NULL) {\n        XFREE(y, key->heap, DYNAMIC_TYPE_DH);\n        return MEMORY_E;\n    }\n    z = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);\n    if (z == NULL) {\n        XFREE(x, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(y, key->heap, DYNAMIC_TYPE_DH);\n        return MEMORY_E;\n    }\n#endif\n#endif\n\n#ifdef WOLFSSL_HAVE_SP_DH\n#ifndef WOLFSSL_SP_NO_2048\n    if (mp_count_bits(&key->p) == 2048) {\n        if (mp_init(y) != MP_OKAY)\n            return MP_INIT_E;\n\n        if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)\n            ret = MP_READ_E;\n\n        if (ret == 0)\n            ret = sp_DhExp_2048(y, priv, privSz, &key->p, agree, agreeSz);\n\n        mp_clear(y);\n    #ifdef WOLFSSL_SMALL_STACK\n    #ifndef WOLFSSL_SP_MATH\n        XFREE(z, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(x, key->heap, DYNAMIC_TYPE_DH);\n    #endif\n        XFREE(y, key->heap, DYNAMIC_TYPE_DH);\n    #endif\n        return ret;\n    }\n#endif\n#ifndef WOLFSSL_SP_NO_3072\n    if (mp_count_bits(&key->p) == 3072) {\n        if (mp_init(y) != MP_OKAY)\n            return MP_INIT_E;\n\n        if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)\n            ret = MP_READ_E;\n\n        if (ret == 0)\n            ret = sp_DhExp_3072(y, priv, privSz, &key->p, agree, agreeSz);\n\n        mp_clear(y);\n    #ifdef WOLFSSL_SMALL_STACK\n    #ifndef WOLFSSL_SP_MATH\n        XFREE(z, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(x, key->heap, DYNAMIC_TYPE_DH);\n    #endif\n        XFREE(y, key->heap, DYNAMIC_TYPE_DH);\n    #endif\n        return ret;\n    }\n#endif\n#ifdef WOLFSSL_SP_4096\n    if (mp_count_bits(&key->p) == 4096) {\n        if (mp_init(y) != MP_OKAY)\n            return MP_INIT_E;\n\n        if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)\n            ret = MP_READ_E;\n\n        if (ret == 0)\n            ret = sp_DhExp_4096(y, priv, privSz, &key->p, agree, agreeSz);\n\n        mp_clear(y);\n    #ifdef WOLFSSL_SMALL_STACK\n    #ifndef WOLFSSL_SP_MATH\n        XFREE(z, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(x, key->heap, DYNAMIC_TYPE_DH);\n    #endif\n        XFREE(y, key->heap, DYNAMIC_TYPE_DH);\n    #endif\n        return ret;\n    }\n#endif\n#endif\n\n#ifndef WOLFSSL_SP_MATH\n    if (mp_init_multi(x, y, z, 0, 0, 0) != MP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(z, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(x, key->heap, DYNAMIC_TYPE_DH);\n        XFREE(y, key->heap, DYNAMIC_TYPE_DH);\n    #endif\n        return MP_INIT_E;\n    }\n\n    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)\n        ret = MP_READ_E;\n\n    if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)\n        ret = MP_READ_E;\n\n    if (ret == 0 && mp_exptmod(y, x, &key->p, z) != MP_OKAY)\n        ret = MP_EXPTMOD_E;\n\n    /* make sure z is not one (SP800-56A, 5.7.1.1) */\n    if (ret == 0 && (mp_cmp_d(z, 1) == MP_EQ))\n        ret = MP_VAL;\n\n    if (ret == 0 && mp_to_unsigned_bin(z, agree) != MP_OKAY)\n        ret = MP_TO_E;\n\n    if (ret == 0)\n        *agreeSz = mp_unsigned_bin_size(z);\n\n    mp_clear(z);\n    mp_clear(y);\n    mp_forcezero(x);\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n#ifndef WOLFSSL_SP_MATH\n    XFREE(z, key->heap, DYNAMIC_TYPE_DH);\n    XFREE(x, key->heap, DYNAMIC_TYPE_DH);\n#endif\n    XFREE(y, key->heap, DYNAMIC_TYPE_DH);\n#endif\n\n    return ret;\n}\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)\nstatic int wc_DhAgree_Async(DhKey* key, byte* agree, word32* agreeSz,\n    const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz)\n{\n    int ret;\n\n#if defined(HAVE_INTEL_QA)\n    word32 pBits;\n\n    /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */\n    pBits = mp_unsigned_bin_size(&key->p) * 8;\n    if (pBits == 768 ||  pBits == 1024 || pBits == 1536 ||\n        pBits == 2048 || pBits == 3072 || pBits == 4096) {\n        ret = wc_mp_to_bigint(&key->p, &key->p.raw);\n        if (ret == MP_OKAY)\n            ret = IntelQaDhAgree(&key->asyncDev, &key->p.raw,\n                agree, agreeSz, priv, privSz, otherPub, pubSz);\n        return ret;\n    }\n\n#elif defined(HAVE_CAVIUM)\n    /* TODO: Not implemented - use software for now */\n\n#else /* WOLFSSL_ASYNC_CRYPT_TEST */\n    if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_DH_AGREE)) {\n        WC_ASYNC_TEST* testDev = &key->asyncDev.test;\n        testDev->dhAgree.key = key;\n        testDev->dhAgree.agree = agree;\n        testDev->dhAgree.agreeSz = agreeSz;\n        testDev->dhAgree.priv = priv;\n        testDev->dhAgree.privSz = privSz;\n        testDev->dhAgree.otherPub = otherPub;\n        testDev->dhAgree.pubSz = pubSz;\n        return WC_PENDING_E;\n    }\n#endif\n\n    /* otherwise use software DH */\n    ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz);\n\n    return ret;\n}\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\nint wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,\n            word32 privSz, const byte* otherPub, word32 pubSz)\n{\n    int ret = 0;\n\n    if (key == NULL || agree == NULL || agreeSz == NULL || priv == NULL ||\n                                                            otherPub == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)\n    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {\n        ret = wc_DhAgree_Async(key, agree, agreeSz, priv, privSz, otherPub, pubSz);\n    }\n    else\n#endif\n    {\n        ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz);\n    }\n\n    return ret;\n}\n\n\nstatic int _DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,\n                   word32 gSz, const byte* q, word32 qSz, int trusted,\n                   WC_RNG* rng)\n{\n    int ret = 0;\n    mp_int* keyP = NULL;\n    mp_int* keyG = NULL;\n    mp_int* keyQ = NULL;\n\n    if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) {\n        ret = BAD_FUNC_ARG;\n    }\n\n    if (ret == 0) {\n        /* may have leading 0 */\n        if (p[0] == 0) {\n            pSz--; p++;\n        }\n\n        if (g[0] == 0) {\n            gSz--; g++;\n        }\n\n        if (q != NULL) {\n            if (q[0] == 0) {\n                qSz--; q++;\n            }\n        }\n\n        if (mp_init(&key->p) != MP_OKAY)\n            ret = MP_INIT_E;\n    }\n\n    if (ret == 0) {\n        if (mp_read_unsigned_bin(&key->p, p, pSz) != MP_OKAY)\n            ret = ASN_DH_KEY_E;\n        else\n            keyP = &key->p;\n    }\n\n    if (ret == 0 && !trusted) {\n        int isPrime = 0;\n        if (rng != NULL)\n            ret = mp_prime_is_prime_ex(keyP, 8, &isPrime, rng);\n        else\n            ret = mp_prime_is_prime(keyP, 8, &isPrime);\n\n        if (ret == 0 && isPrime == 0)\n            ret = DH_CHECK_PUB_E;\n    }\n\n    if (ret == 0 && mp_init(&key->g) != MP_OKAY)\n        ret = MP_INIT_E;\n    if (ret == 0) {\n        if (mp_read_unsigned_bin(&key->g, g, gSz) != MP_OKAY)\n            ret = ASN_DH_KEY_E;\n        else\n            keyG = &key->g;\n    }\n\n    if (ret == 0 && q != NULL) {\n        if (mp_init(&key->q) != MP_OKAY)\n            ret = MP_INIT_E;\n    }\n    if (ret == 0 && q != NULL) {\n        if (mp_read_unsigned_bin(&key->q, q, qSz) != MP_OKAY)\n            ret = MP_INIT_E;\n        else\n            keyQ = &key->q;\n    }\n\n    if (ret != 0 && key != NULL) {\n        if (keyQ)\n            mp_clear(keyQ);\n        if (keyG)\n            mp_clear(keyG);\n        if (keyP)\n            mp_clear(keyP);\n    }\n\n    return ret;\n}\n\n\nint wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, const byte* g,\n                   word32 gSz, const byte* q, word32 qSz, int trusted,\n                   WC_RNG* rng)\n{\n    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, trusted, rng);\n}\n\n\nint wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g,\n                   word32 gSz, const byte* q, word32 qSz)\n{\n    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 1, NULL);\n}\n\n\n/* not in asn anymore since no actual asn types used */\nint wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,\n                word32 gSz)\n{\n    return _DhSetKey(key, p, pSz, g, gSz, NULL, 0, 1, NULL);\n}\n\n\n#ifdef WOLFSSL_KEY_GEN\n\n/* modulus_size in bits */\nint wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh)\n{\n    mp_int  tmp, tmp2;\n    int     groupSz = 0, bufSz = 0,\n            primeCheckCount = 0,\n            primeCheck = MP_NO,\n            ret = 0;\n    unsigned char *buf = NULL;\n\n    if (rng == NULL || dh == NULL)\n        ret = BAD_FUNC_ARG;\n\n    /* set group size in bytes from modulus size\n     * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256)\n     */\n    if (ret == 0) {\n        switch (modSz) {\n            case 1024:\n                groupSz = 20;\n                break;\n            case 2048:\n            case 3072:\n                groupSz = 32;\n                break;\n            default:\n                ret = BAD_FUNC_ARG;\n                break;\n        }\n    }\n\n    if (ret == 0) {\n        /* modulus size in bytes */\n        modSz /= WOLFSSL_BIT_SIZE;\n        bufSz = modSz - groupSz;\n\n        /* allocate ram */\n        buf = (unsigned char *)XMALLOC(bufSz,\n                                       dh->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (buf == NULL)\n            ret = MEMORY_E;\n    }\n\n    /* make a random string that will be multplied against q */\n    if (ret == 0)\n        ret = wc_RNG_GenerateBlock(rng, buf, bufSz);\n\n    if (ret == 0) {\n        /* force magnitude */\n        buf[0] |= 0xC0;\n        /* force even */\n        buf[bufSz - 1] &= ~1;\n\n        if (mp_init_multi(&tmp, &tmp2, &dh->p, &dh->q, &dh->g, 0)\n                != MP_OKAY) {\n            ret = MP_INIT_E;\n        }\n    }\n\n    if (ret == 0) {\n        if (mp_read_unsigned_bin(&tmp2, buf, bufSz) != MP_OKAY)\n            ret = MP_READ_E;\n    }\n\n    /* make our prime q */\n    if (ret == 0) {\n        if (mp_rand_prime(&dh->q, groupSz, rng, NULL) != MP_OKAY)\n            ret = PRIME_GEN_E;\n    }\n\n    /* p = random * q */\n    if (ret == 0) {\n        if (mp_mul(&dh->q, &tmp2, &dh->p) != MP_OKAY)\n            ret = MP_MUL_E;\n    }\n\n    /* p = random * q + 1, so q is a prime divisor of p-1 */\n    if (ret == 0) {\n        if (mp_add_d(&dh->p, 1, &dh->p) != MP_OKAY)\n            ret = MP_ADD_E;\n    }\n\n    /* tmp = 2q  */\n    if (ret == 0) {\n        if (mp_add(&dh->q, &dh->q, &tmp) != MP_OKAY)\n            ret = MP_ADD_E;\n    }\n\n    /* loop until p is prime */\n    if (ret == 0) {\n        do {\n            if (mp_prime_is_prime_ex(&dh->p, 8, &primeCheck, rng) != MP_OKAY)\n                ret = PRIME_GEN_E;\n\n            if (primeCheck != MP_YES) {\n                /* p += 2q */\n                if (mp_add(&tmp, &dh->p, &dh->p) != MP_OKAY)\n                    ret = MP_ADD_E;\n                else\n                    primeCheckCount++;\n            }\n        } while (ret == 0 && primeCheck == MP_NO);\n    }\n\n    /* tmp2 += (2*loop_check_prime)\n     * to have p = (q * tmp2) + 1 prime\n     */\n    if ((ret == 0) && (primeCheckCount)) {\n        if (mp_add_d(&tmp2, 2 * primeCheckCount, &tmp2) != MP_OKAY)\n            ret = MP_ADD_E;\n    }\n\n    /* find a value g for which g^tmp2 != 1 */\n    if ((ret == 0) && (mp_set(&dh->g, 1) != MP_OKAY))\n        ret = MP_ZERO_E;\n\n    if (ret == 0) {\n        do {\n            if (mp_add_d(&dh->g, 1, &dh->g) != MP_OKAY)\n                ret = MP_ADD_E;\n            else if (mp_exptmod(&dh->g, &tmp2, &dh->p, &tmp) != MP_OKAY)\n                ret = MP_EXPTMOD_E;\n        } while (ret == 0 && mp_cmp_d(&tmp, 1) == MP_EQ);\n    }\n\n    if (ret == 0) {\n        /* at this point tmp generates a group of order q mod p */\n        mp_exch(&tmp, &dh->g);\n    }\n\n    /* clear the parameters if there was an error */\n    if ((ret != 0) && (dh != NULL)) {\n        mp_clear(&dh->q);\n        mp_clear(&dh->p);\n        mp_clear(&dh->g);\n    }\n\n    if (buf != NULL) {\n        ForceZero(buf, bufSz);\n        if (dh != NULL) {\n            XFREE(buf, dh->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        }\n    }\n    mp_clear(&tmp);\n    mp_clear(&tmp2);\n\n    return ret;\n}\n\n\n/* Export raw DH parameters from DhKey structure\n *\n * dh   - pointer to initialized DhKey structure\n * p    - output location for DH (p) parameter\n * pSz  - [IN/OUT] size of output buffer for p, size of p\n * q    - output location for DH (q) parameter\n * qSz  - [IN/OUT] size of output buffer for q, size of q\n * g    - output location for DH (g) parameter\n * gSz  - [IN/OUT] size of output buffer for g, size of g\n *\n * If p, q, and g pointers are all passed in as NULL, the function\n * will set pSz, qSz, and gSz to the required output buffer sizes for p,\n * q, and g. In this case, the function will return LENGTH_ONLY_E.\n *\n * returns 0 on success, negative upon failure\n */\nint wc_DhExportParamsRaw(DhKey* dh, byte* p, word32* pSz,\n                         byte* q, word32* qSz, byte* g, word32* gSz)\n{\n    int ret = 0;\n    word32 pLen = 0, qLen = 0, gLen = 0;\n\n    if (dh == NULL || pSz == NULL || qSz == NULL || gSz == NULL)\n        ret = BAD_FUNC_ARG;\n\n    /* get required output buffer sizes */\n    if (ret == 0) {\n        pLen = mp_unsigned_bin_size(&dh->p);\n        qLen = mp_unsigned_bin_size(&dh->q);\n        gLen = mp_unsigned_bin_size(&dh->g);\n\n        /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */\n        if (p == NULL && q == NULL && g == NULL) {\n            *pSz = pLen;\n            *qSz = qLen;\n            *gSz = gLen;\n            ret = LENGTH_ONLY_E;\n        }\n    }\n\n    if (ret == 0) {\n        if (p == NULL || q == NULL || g == NULL)\n            ret = BAD_FUNC_ARG;\n    }\n\n    /* export p */\n    if (ret == 0) {\n        if (*pSz < pLen) {\n            WOLFSSL_MSG(\"Output buffer for DH p parameter too small, \"\n                        \"required size placed into pSz\");\n            *pSz = pLen;\n            ret = BUFFER_E;\n        }\n    }\n\n    if (ret == 0) {\n        *pSz = pLen;\n        if (mp_to_unsigned_bin(&dh->p, p) != MP_OKAY)\n            ret = MP_TO_E;\n    }\n\n    /* export q */\n    if (ret == 0) {\n        if (*qSz < qLen) {\n            WOLFSSL_MSG(\"Output buffer for DH q parameter too small, \"\n                        \"required size placed into qSz\");\n            *qSz = qLen;\n            ret = BUFFER_E;\n        }\n    }\n\n    if (ret == 0) {\n        *qSz = qLen;\n        if (mp_to_unsigned_bin(&dh->q, q) != MP_OKAY)\n            ret = MP_TO_E;\n    }\n\n    /* export g */\n    if (ret == 0) {\n        if (*gSz < gLen) {\n            WOLFSSL_MSG(\"Output buffer for DH g parameter too small, \"\n                        \"required size placed into gSz\");\n            *gSz = gLen;\n            ret = BUFFER_E;\n        }\n    }\n\n    if (ret == 0) {\n        *gSz = gLen;\n        if (mp_to_unsigned_bin(&dh->g, g) != MP_OKAY)\n            ret = MP_TO_E;\n    }\n\n    return ret;\n}\n\n#endif /* WOLFSSL_KEY_GEN */\n\n#endif /* NO_DH */\n"
  },
  {
    "path": "src/wolfcrypt/src/dsa.c",
    "content": "/* dsa.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifndef NO_DSA\n\n#include <wolfssl/wolfcrypt/random.h>\n#include <wolfssl/wolfcrypt/integer.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#include <wolfssl/wolfcrypt/sha.h>\n#include <wolfssl/wolfcrypt/dsa.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\nenum {\n    DSA_HALF_SIZE = 20,   /* r and s size  */\n    DSA_SIG_SIZE  = 40    /* signature size */\n};\n\n\n\nint wc_InitDsaKey(DsaKey* key)\n{\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    key->type = -1;  /* haven't decided yet */\n    key->heap = NULL;\n\n    return mp_init_multi(\n        /* public  alloc parts */\n        &key->p,\n        &key->q,\n        &key->g,\n        &key->y,\n\n        /* private alloc parts */\n        &key->x,\n        NULL\n    );\n}\n\n\nint wc_InitDsaKey_h(DsaKey* key, void* h)\n{\n    int ret = wc_InitDsaKey(key);\n    if (ret == 0)\n        key->heap = h;\n\n    return ret;\n}\n\n\nvoid wc_FreeDsaKey(DsaKey* key)\n{\n    if (key == NULL)\n        return;\n\n    if (key->type == DSA_PRIVATE)\n        mp_forcezero(&key->x);\n\n    mp_clear(&key->x);\n    mp_clear(&key->y);\n    mp_clear(&key->g);\n    mp_clear(&key->q);\n    mp_clear(&key->p);\n}\n\n\n/* validate that (L,N) match allowed sizes from FIPS 186-4, Section 4.2.\n * modLen - represents L, the size of p (prime modulus) in bits\n * divLen - represents N, the size of q (prime divisor) in bits\n * return 0 on success, -1 on error */\nstatic int CheckDsaLN(int modLen, int divLen)\n{\n    int ret = -1;\n\n    switch (modLen) {\n        case 1024:\n            if (divLen == 160)\n                ret = 0;\n            break;\n        case 2048:\n            if (divLen == 224 || divLen == 256)\n                ret = 0;\n            break;\n        case 3072:\n            if (divLen == 256)\n                ret = 0;\n            break;\n        default:\n            break;\n    }\n\n    return ret;\n}\n\n\n#ifdef WOLFSSL_KEY_GEN\n\n/* Create DSA key pair (&dsa->x, &dsa->y)\n *\n * Based on NIST FIPS 186-4,\n * \"B.1.1 Key Pair Generation Using Extra Random Bits\"\n *\n * rng - pointer to initialized WC_RNG structure\n * dsa - pointer to initialized DsaKey structure, will hold generated key\n *\n * return 0 on success, negative on error */\nint wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa)\n{\n    byte* cBuf;\n    int qSz, pSz, cSz, err;\n    mp_int tmpQ;\n\n    if (rng == NULL || dsa == NULL)\n        return BAD_FUNC_ARG;\n\n    qSz = mp_unsigned_bin_size(&dsa->q);\n    pSz = mp_unsigned_bin_size(&dsa->p);\n\n    /* verify (L,N) pair bit lengths */\n    if (CheckDsaLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0)\n        return BAD_FUNC_ARG;\n\n    /* generate extra 64 bits so that bias from mod function is negligible */\n    cSz = qSz + (64 / WOLFSSL_BIT_SIZE);\n    cBuf = (byte*)XMALLOC(cSz, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (cBuf == NULL) {\n        return MEMORY_E;\n    }\n\n    if ((err = mp_init_multi(&dsa->x, &dsa->y, &tmpQ, NULL, NULL, NULL))\n                   != MP_OKAY) {\n        XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return err;\n    }\n\n    do {\n        /* generate N+64 bits (c) from RBG into &dsa->x, making sure positive.\n         * Hash_DRBG uses SHA-256 which matches maximum\n         * requested_security_strength of (L,N) */\n        err = wc_RNG_GenerateBlock(rng, cBuf, cSz);\n        if (err != MP_OKAY) {\n            mp_clear(&dsa->x);\n            mp_clear(&dsa->y);\n            mp_clear(&tmpQ);\n            XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            return err;\n        }\n\n        err = mp_read_unsigned_bin(&dsa->x, cBuf, cSz);\n        if (err != MP_OKAY) {\n            mp_clear(&dsa->x);\n            mp_clear(&dsa->y);\n            mp_clear(&tmpQ);\n            XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            return err;\n        }\n    } while (mp_cmp_d(&dsa->x, 1) != MP_GT);\n\n    XFREE(cBuf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    /* tmpQ = q - 1 */\n    if (err == MP_OKAY)\n        err = mp_copy(&dsa->q, &tmpQ);\n\n    if (err == MP_OKAY)\n        err = mp_sub_d(&tmpQ, 1, &tmpQ);\n\n    /* x = c mod (q-1), &dsa->x holds c */\n    if (err == MP_OKAY)\n        err = mp_mod(&dsa->x, &tmpQ, &dsa->x);\n\n    /* x = c mod (q-1) + 1 */\n    if (err == MP_OKAY)\n        err = mp_add_d(&dsa->x, 1, &dsa->x);\n\n    /* public key : y = g^x mod p */\n    if (err == MP_OKAY)\n        err = mp_exptmod_ex(&dsa->g, &dsa->x, dsa->q.used, &dsa->p, &dsa->y);\n\n    if (err == MP_OKAY)\n        dsa->type = DSA_PRIVATE;\n\n    if (err != MP_OKAY) {\n        mp_clear(&dsa->x);\n        mp_clear(&dsa->y);\n    }\n    mp_clear(&tmpQ);\n\n    return err;\n}\n\n\n/* modulus_size in bits */\nint wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa)\n{\n    mp_int  tmp, tmp2;\n    int     err, msize, qsize,\n            loop_check_prime = 0,\n            check_prime = MP_NO;\n    unsigned char   *buf;\n\n    if (rng == NULL || dsa == NULL)\n        return BAD_FUNC_ARG;\n\n    /* set group size in bytes from modulus size\n     * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256)\n     */\n    switch (modulus_size) {\n        case 1024:\n            qsize = 20;\n            break;\n        case 2048:\n        case 3072:\n            qsize = 32;\n            break;\n        default:\n            return BAD_FUNC_ARG;\n    }\n\n    /* modulus size in bytes */\n    msize = modulus_size / WOLFSSL_BIT_SIZE;\n\n    /* allocate ram */\n    buf = (unsigned char *)XMALLOC(msize - qsize,\n                                   dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (buf == NULL) {\n        return MEMORY_E;\n    }\n\n    /* make a random string that will be multplied against q */\n    err = wc_RNG_GenerateBlock(rng, buf, msize - qsize);\n    if (err != MP_OKAY) {\n        XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return err;\n    }\n\n    /* force magnitude */\n    buf[0] |= 0xC0;\n\n    /* force even */\n    buf[msize - qsize - 1] &= ~1;\n\n    if (mp_init_multi(&tmp2, &dsa->p, &dsa->q, 0, 0, 0) != MP_OKAY) {\n        mp_clear(&dsa->q);\n        XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return MP_INIT_E;\n    }\n\n    err = mp_read_unsigned_bin(&tmp2, buf, msize - qsize);\n    if (err != MP_OKAY) {\n        mp_clear(&dsa->q);\n        mp_clear(&dsa->p);\n        mp_clear(&tmp2);\n        XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return err;\n    }\n    XFREE(buf, dsa->heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    /* make our prime q */\n    err = mp_rand_prime(&dsa->q, qsize, rng, NULL);\n    if (err != MP_OKAY) {\n        mp_clear(&dsa->q);\n        mp_clear(&dsa->p);\n        mp_clear(&tmp2);\n        return err;\n    }\n\n    /* p = random * q */\n    err = mp_mul(&dsa->q, &tmp2, &dsa->p);\n    if (err != MP_OKAY) {\n        mp_clear(&dsa->q);\n        mp_clear(&dsa->p);\n        mp_clear(&tmp2);\n        return err;\n    }\n\n    /* p = random * q + 1, so q is a prime divisor of p-1 */\n    err = mp_add_d(&dsa->p, 1, &dsa->p);\n    if (err != MP_OKAY) {\n        mp_clear(&dsa->q);\n        mp_clear(&dsa->p);\n        mp_clear(&tmp2);\n        return err;\n    }\n\n    if (mp_init(&tmp) != MP_OKAY) {\n        mp_clear(&dsa->q);\n        mp_clear(&dsa->p);\n        mp_clear(&tmp2);\n        return MP_INIT_E;\n    }\n\n    /* tmp = 2q  */\n    err = mp_add(&dsa->q, &dsa->q, &tmp);\n    if (err != MP_OKAY) {\n        mp_clear(&dsa->q);\n        mp_clear(&dsa->p);\n        mp_clear(&tmp);\n        mp_clear(&tmp2);\n        return err;\n    }\n\n    /* loop until p is prime */\n    while (check_prime == MP_NO) {\n        err = mp_prime_is_prime_ex(&dsa->p, 8, &check_prime, rng);\n        if (err != MP_OKAY) {\n            mp_clear(&dsa->q);\n            mp_clear(&dsa->p);\n            mp_clear(&tmp);\n            mp_clear(&tmp2);\n            return err;\n        }\n\n        if (check_prime != MP_YES) {\n            /* p += 2q */\n            err = mp_add(&tmp, &dsa->p, &dsa->p);\n            if (err != MP_OKAY) {\n                mp_clear(&dsa->q);\n                mp_clear(&dsa->p);\n                mp_clear(&tmp);\n                mp_clear(&tmp2);\n                return err;\n            }\n\n            loop_check_prime++;\n        }\n    }\n\n    /* tmp2 += (2*loop_check_prime)\n     * to have p = (q * tmp2) + 1 prime\n     */\n    if (loop_check_prime) {\n        err = mp_add_d(&tmp2, 2*loop_check_prime, &tmp2);\n        if (err != MP_OKAY) {\n            mp_clear(&dsa->q);\n            mp_clear(&dsa->p);\n            mp_clear(&tmp);\n            mp_clear(&tmp2);\n            return err;\n        }\n    }\n\n    if (mp_init(&dsa->g) != MP_OKAY) {\n        mp_clear(&dsa->q);\n        mp_clear(&dsa->p);\n        mp_clear(&tmp);\n        mp_clear(&tmp2);\n        return MP_INIT_E;\n    }\n\n    /* find a value g for which g^tmp2 != 1 */\n    if (mp_set(&dsa->g, 1) != MP_OKAY) {\n        mp_clear(&dsa->q);\n        mp_clear(&dsa->p);\n        mp_clear(&tmp);\n        mp_clear(&tmp2);\n        return MP_INIT_E;\n    }\n\n    do {\n        err = mp_add_d(&dsa->g, 1, &dsa->g);\n        if (err != MP_OKAY) {\n            mp_clear(&dsa->q);\n            mp_clear(&dsa->p);\n            mp_clear(&dsa->g);\n            mp_clear(&tmp);\n            mp_clear(&tmp2);\n            return err;\n        }\n\n        err = mp_exptmod(&dsa->g, &tmp2, &dsa->p, &tmp);\n        if (err != MP_OKAY) {\n            mp_clear(&dsa->q);\n            mp_clear(&dsa->p);\n            mp_clear(&dsa->g);\n            mp_clear(&tmp);\n            mp_clear(&tmp2);\n            return err;\n        }\n\n    } while (mp_cmp_d(&tmp, 1) == MP_EQ);\n\n    /* at this point tmp generates a group of order q mod p */\n    mp_exch(&tmp, &dsa->g);\n\n    mp_clear(&tmp);\n    mp_clear(&tmp2);\n\n    return MP_OKAY;\n}\n#endif /* WOLFSSL_KEY_GEN */\n\n\nstatic int _DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q,\n                          const char* g, int trusted, WC_RNG* rng)\n{\n    int err;\n    word32 pSz, qSz;\n\n    if (dsa == NULL || p == NULL || q == NULL || g == NULL)\n        return BAD_FUNC_ARG;\n\n    /* read p */\n    err = mp_read_radix(&dsa->p, p, MP_RADIX_HEX);\n    if (err == MP_OKAY && !trusted) {\n        int isPrime = 1;\n        if (rng == NULL)\n            err = mp_prime_is_prime(&dsa->p, 8, &isPrime);\n        else\n            err = mp_prime_is_prime_ex(&dsa->p, 8, &isPrime, rng);\n\n        if (err == MP_OKAY) {\n            if (!isPrime)\n                err = DH_CHECK_PUB_E;\n        }\n    }\n\n    /* read q */\n    if (err == MP_OKAY)\n        err = mp_read_radix(&dsa->q, q, MP_RADIX_HEX);\n\n    /* read g */\n    if (err == MP_OKAY)\n        err = mp_read_radix(&dsa->g, g, MP_RADIX_HEX);\n\n    /* verify (L,N) pair bit lengths */\n    pSz = mp_unsigned_bin_size(&dsa->p);\n    qSz = mp_unsigned_bin_size(&dsa->q);\n\n    if (CheckDsaLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) {\n        WOLFSSL_MSG(\"Invalid DSA p or q parameter size\");\n        err = BAD_FUNC_ARG;\n    }\n\n    if (err != MP_OKAY) {\n        mp_clear(&dsa->p);\n        mp_clear(&dsa->q);\n        mp_clear(&dsa->g);\n    }\n\n    return err;\n}\n\n\n/* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(),\n * input parameters (p,q,g) should be represented as ASCII hex values.\n *\n * dsa  - pointer to initialized DsaKey structure\n * p    - DSA (p) parameter, ASCII hex string\n * pSz  - length of p\n * q    - DSA (q) parameter, ASCII hex string\n * qSz  - length of q\n * g    - DSA (g) parameter, ASCII hex string\n * gSz  - length of g\n *\n * returns 0 on success, negative upon failure\n */\nint wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q,\n                          const char* g)\n{\n    return _DsaImportParamsRaw(dsa, p, q, g, 1, NULL);\n}\n\n\n/* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(),\n * input parameters (p,q,g) should be represented as ASCII hex values. Check\n * that the p value is probably prime.\n *\n * dsa  - pointer to initialized DsaKey structure\n * p    - DSA (p) parameter, ASCII hex string\n * pSz  - length of p\n * q    - DSA (q) parameter, ASCII hex string\n * qSz  - length of q\n * g    - DSA (g) parameter, ASCII hex string\n * gSz  - length of g\n * trusted - trust that p is OK\n * rng  - random number generator for the prime test\n *\n * returns 0 on success, negative upon failure\n */\nint wc_DsaImportParamsRawCheck(DsaKey* dsa, const char* p, const char* q,\n                          const char* g, int trusted, WC_RNG* rng)\n{\n    return _DsaImportParamsRaw(dsa, p, q, g, trusted, rng);\n}\n\n\n/* Export raw DSA parameters from DsaKey structure\n *\n * dsa  - pointer to initialized DsaKey structure\n * p    - output location for DSA (p) parameter\n * pSz  - [IN/OUT] size of output buffer for p, size of p\n * q    - output location for DSA (q) parameter\n * qSz  - [IN/OUT] size of output buffer for q, size of q\n * g    - output location for DSA (g) parameter\n * gSz  - [IN/OUT] size of output buffer for g, size of g\n *\n * If p, q, and g pointers are all passed in as NULL, the function\n * will set pSz, qSz, and gSz to the required output buffer sizes for p,\n * q, and g. In this case, the function will return LENGTH_ONLY_E.\n *\n * returns 0 on success, negative upon failure\n */\nint wc_DsaExportParamsRaw(DsaKey* dsa, byte* p, word32* pSz,\n                          byte* q, word32* qSz, byte* g, word32* gSz)\n{\n    int err;\n    word32 pLen, qLen, gLen;\n\n    if (dsa == NULL || pSz == NULL || qSz == NULL || gSz == NULL)\n        return BAD_FUNC_ARG;\n\n    /* get required output buffer sizes */\n    pLen = mp_unsigned_bin_size(&dsa->p);\n    qLen = mp_unsigned_bin_size(&dsa->q);\n    gLen = mp_unsigned_bin_size(&dsa->g);\n\n    /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */\n    if (p == NULL && q == NULL && g == NULL) {\n        *pSz = pLen;\n        *qSz = qLen;\n        *gSz = gLen;\n        return LENGTH_ONLY_E;\n    }\n\n    if (p == NULL || q == NULL || g == NULL)\n        return BAD_FUNC_ARG;\n\n    /* export p */\n    if (*pSz < pLen) {\n        WOLFSSL_MSG(\"Output buffer for DSA p parameter too small, \"\n                    \"required size placed into pSz\");\n        *pSz = pLen;\n        return BUFFER_E;\n    }\n    *pSz = pLen;\n    err = mp_to_unsigned_bin(&dsa->p, p);\n\n    /* export q */\n    if (err == MP_OKAY) {\n        if (*qSz < qLen) {\n            WOLFSSL_MSG(\"Output buffer for DSA q parameter too small, \"\n                        \"required size placed into qSz\");\n            *qSz = qLen;\n            return BUFFER_E;\n        }\n        *qSz = qLen;\n        err = mp_to_unsigned_bin(&dsa->q, q);\n    }\n\n    /* export g */\n    if (err == MP_OKAY) {\n        if (*gSz < gLen) {\n            WOLFSSL_MSG(\"Output buffer for DSA g parameter too small, \"\n                        \"required size placed into gSz\");\n            *gSz = gLen;\n            return BUFFER_E;\n        }\n        *gSz = gLen;\n        err = mp_to_unsigned_bin(&dsa->g, g);\n    }\n\n    return err;\n}\n\n\n/* Export raw DSA key (x, y) from DsaKey structure\n *\n * dsa  - pointer to initialized DsaKey structure\n * x    - output location for private key\n * xSz  - [IN/OUT] size of output buffer for x, size of x\n * y    - output location for public key\n * ySz  - [IN/OUT] size of output buffer for y, size of y\n *\n * If x and y pointers are all passed in as NULL, the function\n * will set xSz and ySz to the required output buffer sizes for x\n * and y. In this case, the function will return LENGTH_ONLY_E.\n *\n * returns 0 on success, negative upon failure\n */\nint wc_DsaExportKeyRaw(DsaKey* dsa, byte* x, word32* xSz, byte* y, word32* ySz)\n{\n    int err;\n    word32 xLen, yLen;\n\n    if (dsa == NULL || xSz == NULL || ySz == NULL)\n        return BAD_FUNC_ARG;\n\n    /* get required output buffer sizes */\n    xLen = mp_unsigned_bin_size(&dsa->x);\n    yLen = mp_unsigned_bin_size(&dsa->y);\n\n    /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */\n    if (x == NULL && y == NULL) {\n        *xSz = xLen;\n        *ySz = yLen;\n        return LENGTH_ONLY_E;\n    }\n\n    if (x == NULL || y == NULL)\n        return BAD_FUNC_ARG;\n\n    /* export x */\n    if (*xSz < xLen) {\n        WOLFSSL_MSG(\"Output buffer for DSA private key (x) too small, \"\n                    \"required size placed into xSz\");\n        *xSz = xLen;\n        return BUFFER_E;\n    }\n    *xSz = xLen;\n    err = mp_to_unsigned_bin(&dsa->x, x);\n\n    /* export y */\n    if (err == MP_OKAY) {\n        if (*ySz < yLen) {\n            WOLFSSL_MSG(\"Output buffer to DSA public key (y) too small, \"\n                        \"required size placed into ySz\");\n            *ySz = yLen;\n            return BUFFER_E;\n        }\n        *ySz = yLen;\n        err = mp_to_unsigned_bin(&dsa->y, y);\n    }\n\n    return err;\n}\n\n\nint wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)\n{\n    mp_int  k, kInv, r, s, H;\n#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME\n    mp_int  b;\n#endif\n    mp_int* qMinus1;\n    int     ret = 0, sz;\n    byte    buffer[DSA_HALF_SIZE];\n    byte*   tmp;  /* initial output pointer */\n\n    if (digest == NULL || out == NULL || key == NULL || rng == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    tmp = out;\n\n    sz = min((int)sizeof(buffer), mp_unsigned_bin_size(&key->q));\n\n#ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME\n    if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY)\n#else\n    if (mp_init_multi(&k, &kInv, &r, &s, &H, &b) != MP_OKAY)\n#endif\n    {\n        return MP_INIT_E;\n    }\n    qMinus1 = &kInv;\n\n    /* NIST FIPS 186-4: B.2.2\n     * Per-Message Secret Number Generation by Testing Candidates\n     * Generate k in range [1, q-1].\n     *   Check that k is less than q-1: range [0, q-2].\n     *   Add 1 to k: range [1, q-1].\n     */\n    if (mp_sub_d(&key->q, 1, qMinus1))\n        ret = MP_SUB_E;\n\n    if (ret == 0) {\n        do {\n            /* Step 4: generate k */\n            ret = wc_RNG_GenerateBlock(rng, buffer, sz);\n\n            /* Step 5 */\n            if (ret == 0 && mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY)\n                ret = MP_READ_E;\n\n            /* k is a random numnber and it should be less than q-1\n             * if k greater than repeat\n             */\n        /* Step 6 */\n        } while (ret == 0 && mp_cmp(&k, qMinus1) != MP_LT);\n    }\n    /* Step 7 */\n    if (ret == 0 && mp_add_d(&k, 1, &k) != MP_OKAY)\n        ret = MP_MOD_E;\n\n#ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME\n    /* inverse k mod q */\n    if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY)\n        ret = MP_INVMOD_E;\n\n    /* generate r, r = (g exp k mod p) mod q */\n    if (ret == 0 && mp_exptmod_ex(&key->g, &k, key->q.used, &key->p,\n                                                               &r) != MP_OKAY) {\n        ret = MP_EXPTMOD_E;\n    }\n\n    if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY)\n        ret = MP_MOD_E;\n\n    /* generate H from sha digest */\n    if (ret == 0 && mp_read_unsigned_bin(&H, digest,WC_SHA_DIGEST_SIZE) != MP_OKAY)\n        ret = MP_READ_E;\n\n    /* generate s, s = (kInv * (H + x*r)) % q */\n    if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY)\n        ret = MP_MUL_E;\n\n    if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY)\n        ret = MP_ADD_E;\n\n    if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY)\n        ret = MP_MULMOD_E;\n#else\n    /* Blinding value\n     * Generate b in range [1, q-1].\n     */\n    if (ret == 0) {\n        do {\n            ret = wc_RNG_GenerateBlock(rng, buffer, sz);\n            if (ret == 0 && mp_read_unsigned_bin(&b, buffer, sz) != MP_OKAY)\n                ret = MP_READ_E;\n        } while (ret == 0 && mp_cmp(&b, qMinus1) != MP_LT);\n    }\n    if (ret == 0 && mp_add_d(&b, 1, &b) != MP_OKAY)\n        ret = MP_MOD_E;\n\n    /* set H from sha digest */\n    if (ret == 0 && mp_read_unsigned_bin(&H, digest,\n                                               WC_SHA_DIGEST_SIZE) != MP_OKAY) {\n        ret = MP_READ_E;\n    }\n\n    /* generate r, r = (g exp k mod p) mod q */\n    if (ret == 0 && mp_exptmod_ex(&key->g, &k, key->q.used, &key->p,\n                                                               &r) != MP_OKAY) {\n        ret = MP_EXPTMOD_E;\n    }\n\n    /* calculate s = (H + xr)/k\n                   = b.(H/k.b + x.r/k.b) */\n\n    /* k = k.b */\n    if (ret == 0 && mp_mulmod(&k, &b, &key->q, &k) != MP_OKAY)\n        ret = MP_MULMOD_E;\n\n    /* kInv = 1/k.b mod q */\n    if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY)\n        ret = MP_INVMOD_E;\n\n    if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY)\n        ret = MP_MOD_E;\n\n    /* s = x.r */\n    if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY)\n        ret = MP_MUL_E;\n\n    /* s = x.r/k.b */\n    if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY)\n        ret = MP_MULMOD_E;\n\n    /* H = H/k.b */\n    if (ret == 0 && mp_mulmod(&H, &kInv, &key->q, &H) != MP_OKAY)\n        ret = MP_MULMOD_E;\n\n    /* s = H/k.b + x.r/k.b\n         = (H + x.r)/k.b */\n    if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY)\n        ret = MP_ADD_E;\n\n    /* s = b.(e + x.r)/k.b\n         = (e + x.r)/k */\n    if (ret == 0 && mp_mulmod(&s, &b, &key->q, &s) != MP_OKAY)\n        ret = MP_MULMOD_E;\n\n    /* s = (e + x.r)/k */\n    if (ret == 0 && mp_mod(&s, &key->q, &s) != MP_OKAY)\n        ret = MP_MOD_E;\n#endif\n\n    /* detect zero r or s */\n    if (ret == 0 && (mp_iszero(&r) == MP_YES || mp_iszero(&s) == MP_YES))\n        ret = MP_ZERO_E;\n\n    /* write out */\n    if (ret == 0)  {\n        int rSz = mp_unsigned_bin_size(&r);\n        int sSz = mp_unsigned_bin_size(&s);\n\n        while (rSz++ < DSA_HALF_SIZE) {\n            *out++ = 0x00;  /* pad front with zeros */\n        }\n\n        if (mp_to_unsigned_bin(&r, out) != MP_OKAY)\n            ret = MP_TO_E;\n        else {\n            out = tmp + DSA_HALF_SIZE;  /* advance to s in output */\n            while (sSz++ < DSA_HALF_SIZE) {\n                *out++ = 0x00;  /* pad front with zeros */\n            }\n            ret = mp_to_unsigned_bin(&s, out);\n        }\n    }\n\n    ForceZero(buffer, sz);\n    mp_forcezero(&kInv);\n    mp_forcezero(&k);\n#ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME\n    mp_forcezero(&b);\n\n    mp_clear(&b);\n#endif\n    mp_clear(&H);\n    mp_clear(&s);\n    mp_clear(&r);\n    mp_clear(&kInv);\n    mp_clear(&k);\n\n    return ret;\n}\n\n\nint wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer)\n{\n    mp_int w, u1, u2, v, r, s;\n    int    ret = 0;\n\n    if (digest == NULL || sig == NULL || key == NULL || answer == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (mp_init_multi(&w, &u1, &u2, &v, &r, &s) != MP_OKAY)\n        return MP_INIT_E;\n\n    /* set r and s from signature */\n    if (mp_read_unsigned_bin(&r, sig, DSA_HALF_SIZE) != MP_OKAY ||\n        mp_read_unsigned_bin(&s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY)\n        ret = MP_READ_E;\n\n    /* sanity checks */\n    if (ret == 0) {\n        if (mp_iszero(&r) == MP_YES || mp_iszero(&s) == MP_YES ||\n                mp_cmp(&r, &key->q) != MP_LT || mp_cmp(&s, &key->q) != MP_LT) {\n            ret = MP_ZERO_E;\n        }\n    }\n\n    /* put H into u1 from sha digest */\n    if (ret == 0 && mp_read_unsigned_bin(&u1,digest,WC_SHA_DIGEST_SIZE) != MP_OKAY)\n        ret = MP_READ_E;\n\n    /* w = s invmod q */\n    if (ret == 0 && mp_invmod(&s, &key->q, &w) != MP_OKAY)\n        ret = MP_INVMOD_E;\n\n    /* u1 = (H * w) % q */\n    if (ret == 0 && mp_mulmod(&u1, &w, &key->q, &u1) != MP_OKAY)\n        ret = MP_MULMOD_E;\n\n    /* u2 = (r * w) % q */\n    if (ret == 0 && mp_mulmod(&r, &w, &key->q, &u2) != MP_OKAY)\n        ret = MP_MULMOD_E;\n\n    /* verify v = ((g^u1 * y^u2) mod p) mod q */\n    if (ret == 0 && mp_exptmod(&key->g, &u1, &key->p, &u1) != MP_OKAY)\n        ret = MP_EXPTMOD_E;\n\n    if (ret == 0 && mp_exptmod(&key->y, &u2, &key->p, &u2) != MP_OKAY)\n        ret = MP_EXPTMOD_E;\n\n    if (ret == 0 && mp_mulmod(&u1, &u2, &key->p, &v) != MP_OKAY)\n        ret = MP_MULMOD_E;\n\n    if (ret == 0 && mp_mod(&v, &key->q, &v) != MP_OKAY)\n        ret = MP_MULMOD_E;\n\n    /* do they match */\n    if (ret == 0 && mp_cmp(&r, &v) == MP_EQ)\n        *answer = 1;\n    else\n        *answer = 0;\n\n    mp_clear(&s);\n    mp_clear(&r);\n    mp_clear(&u1);\n    mp_clear(&u2);\n    mp_clear(&w);\n    mp_clear(&v);\n\n    return ret;\n}\n\n\n#endif /* NO_DSA */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/ecc.c",
    "content": "/* ecc.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n/* in case user set HAVE_ECC there */\n#include <wolfssl/wolfcrypt/settings.h>\n\n/* public ASN interface */\n#include <wolfssl/wolfcrypt/asn_public.h>\n\n/*\nPossible ECC enable options:\n * HAVE_ECC:            Overall control of ECC                  default: on\n * HAVE_ECC_ENCRYPT:    ECC encrypt/decrypt w/AES and HKDF      default: off\n * HAVE_ECC_SIGN:       ECC sign                                default: on\n * HAVE_ECC_VERIFY:     ECC verify                              default: on\n * HAVE_ECC_DHE:        ECC build shared secret                 default: on\n * HAVE_ECC_CDH:        ECC cofactor DH shared secret           default: off\n * HAVE_ECC_KEY_IMPORT: ECC Key import                          default: on\n * HAVE_ECC_KEY_EXPORT: ECC Key export                          default: on\n * ECC_SHAMIR:          Enables Shamir calc method              default: on\n * HAVE_COMP_KEY:       Enables compressed key                  default: off\n * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import      default: off\n * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen            default: off\n * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves.            default: off\n *                        Includes the curve \"a\" variable in calculation\n * ECC_DUMP_OID:        Enables dump of OID encoding and sum    default: off\n * ECC_CACHE_CURVE:     Enables cache of curve info to improve perofrmance\n                                                                default: off\n * FP_ECC:              ECC Fixed Point Cache                   default: off\n * USE_ECC_B_PARAM:     Enable ECC curve B param                default: off\n                         (on for HAVE_COMP_KEY)\n */\n\n/*\nECC Curve Types:\n * NO_ECC_SECP          Disables SECP curves                    default: off (not defined)\n * HAVE_ECC_SECPR2      Enables SECP R2 curves                  default: off\n * HAVE_ECC_SECPR3      Enables SECP R3 curves                  default: off\n * HAVE_ECC_BRAINPOOL   Enables Brainpool curves                default: off\n * HAVE_ECC_KOBLITZ     Enables Koblitz curves                  default: off\n */\n\n/*\nECC Curve Sizes:\n * ECC_USER_CURVES: Allows custom combination of key sizes below\n * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)\n * HAVE_ECC112: 112 bit key\n * HAVE_ECC128: 128 bit key\n * HAVE_ECC160: 160 bit key\n * HAVE_ECC192: 192 bit key\n * HAVE_ECC224: 224 bit key\n * HAVE_ECC239: 239 bit key\n * NO_ECC256: Disables 256 bit key (on by default)\n * HAVE_ECC320: 320 bit key\n * HAVE_ECC384: 384 bit key\n * HAVE_ECC512: 512 bit key\n * HAVE_ECC521: 521 bit key\n */\n\n\n#ifdef HAVE_ECC\n\n/* Make sure custom curves is enabled for Brainpool or Koblitz curve types */\n#if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\\\n    !defined(WOLFSSL_CUSTOM_CURVES)\n    #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES\n#endif\n\n#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */\n    #define FIPS_NO_WRAPPERS\n\n\t#ifdef USE_WINDOWS_API\n\t\t#pragma code_seg(\".fipsA$f\")\n\t\t#pragma const_seg(\".fipsB$f\")\n\t#endif\n#endif\n\n#include <wolfssl/wolfcrypt/ecc.h>\n#include <wolfssl/wolfcrypt/asn.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef WOLFSSL_HAVE_SP_ECC\n#include <wolfssl/wolfcrypt/sp.h>\n#endif\n\n#ifdef HAVE_ECC_ENCRYPT\n    #include <wolfssl/wolfcrypt/hmac.h>\n    #include <wolfssl/wolfcrypt/aes.h>\n#endif\n\n#ifdef HAVE_X963_KDF\n    #include <wolfssl/wolfcrypt/hash.h>\n#endif\n\n#ifdef WOLF_CRYPTO_CB\n    #include <wolfssl/wolfcrypt/cryptocb.h>\n#endif\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#if defined(FREESCALE_LTC_ECC)\n    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>\n#endif\n\n#if defined(WOLFSSL_STM32_PKA)\n    #include <wolfssl/wolfcrypt/port/st/stm32.h>\n#endif\n\n#ifdef WOLFSSL_SP_MATH\n    #define GEN_MEM_ERR MP_MEM\n#elif defined(USE_FAST_MATH)\n    #define GEN_MEM_ERR FP_MEM\n#else\n    #define GEN_MEM_ERR MP_MEM\n#endif\n\n\n/* internal ECC states */\nenum {\n    ECC_STATE_NONE = 0,\n\n    ECC_STATE_SHARED_SEC_GEN,\n    ECC_STATE_SHARED_SEC_RES,\n\n    ECC_STATE_SIGN_DO,\n    ECC_STATE_SIGN_ENCODE,\n\n    ECC_STATE_VERIFY_DECODE,\n    ECC_STATE_VERIFY_DO,\n    ECC_STATE_VERIFY_RES,\n};\n\n\n/* map\n   ptmul -> mulmod\n*/\n\n/* 256-bit curve on by default whether user curves or not */\n#if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)\n    #define ECC112\n#endif\n#if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)\n    #define ECC128\n#endif\n#if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)\n    #define ECC160\n#endif\n#if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)\n    #define ECC192\n#endif\n#if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)\n    #define ECC224\n#endif\n#if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)\n    #define ECC239\n#endif\n#if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)\n    #define ECC256\n#endif\n#if defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)\n    #define ECC320\n#endif\n#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)\n    #define ECC384\n#endif\n#if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)\n    #define ECC512\n#endif\n#if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)\n    #define ECC521\n#endif\n\n/* The encoded OID's for ECC curves */\n#ifdef ECC112\n    #ifndef NO_ECC_SECP\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP112R1    {1,3,132,0,6}\n            #define CODED_SECP112R1_SZ 5\n        #else\n            #define CODED_SECP112R1    {0x2B,0x81,0x04,0x00,0x06}\n            #define CODED_SECP112R1_SZ 5\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;\n        #else\n            #define ecc_oid_secp112r1 CODED_SECP112R1\n        #endif\n        #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_SECPR2\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP112R2    {1,3,132,0,7}\n            #define CODED_SECP112R2_SZ 5\n        #else\n            #define CODED_SECP112R2    {0x2B,0x81,0x04,0x00,0x07}\n            #define CODED_SECP112R2_SZ 5\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;\n        #else\n            #define ecc_oid_secp112r2 CODED_SECP112R2\n        #endif\n        #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ\n    #endif /* HAVE_ECC_SECPR2 */\n#endif /* ECC112 */\n#ifdef ECC128\n    #ifndef NO_ECC_SECP\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP128R1    {1,3,132,0,28}\n            #define CODED_SECP128R1_SZ 5\n        #else\n            #define CODED_SECP128R1    {0x2B,0x81,0x04,0x00,0x1C}\n            #define CODED_SECP128R1_SZ 5\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;\n        #else\n            #define ecc_oid_secp128r1 CODED_SECP128R1\n        #endif\n        #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_SECPR2\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP128R2    {1,3,132,0,29}\n            #define CODED_SECP128R2_SZ 5\n        #else\n            #define CODED_SECP128R2    {0x2B,0x81,0x04,0x00,0x1D}\n            #define CODED_SECP128R2_SZ 5\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;\n        #else\n            #define ecc_oid_secp128r2 CODED_SECP128R2\n        #endif\n        #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ\n    #endif /* HAVE_ECC_SECPR2 */\n#endif /* ECC128 */\n#ifdef ECC160\n    #ifndef NO_ECC_SECP\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP160R1    {1,3,132,0,8}\n            #define CODED_SECP160R1_SZ 5\n        #else\n            #define CODED_SECP160R1    {0x2B,0x81,0x04,0x00,0x08}\n            #define CODED_SECP160R1_SZ 5\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;\n        #else\n            #define ecc_oid_secp160r1 CODED_SECP160R1\n        #endif\n        #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_SECPR2\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP160R2    {1,3,132,0,30}\n            #define CODED_SECP160R1_SZ 5\n        #else\n            #define CODED_SECP160R2    {0x2B,0x81,0x04,0x00,0x1E}\n            #define CODED_SECP160R2_SZ 5\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;\n        #else\n            #define ecc_oid_secp160r2 CODED_SECP160R2\n        #endif\n        #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ\n    #endif /* HAVE_ECC_SECPR2 */\n    #ifdef HAVE_ECC_KOBLITZ\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP160K1    {1,3,132,0,9}\n            #define CODED_SECP160K1_SZ 5\n        #else\n            #define CODED_SECP160K1    {0x2B,0x81,0x04,0x00,0x09}\n            #define CODED_SECP160K1_SZ 5\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;\n        #else\n            #define ecc_oid_secp160k1 CODED_SECP160K1\n        #endif\n        #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ\n    #endif /* HAVE_ECC_KOBLITZ */\n    #ifdef HAVE_ECC_BRAINPOOL\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_BRAINPOOLP160R1    {1,3,36,3,3,2,8,1,1,1}\n            #define CODED_BRAINPOOLP160R1_SZ 10\n        #else\n            #define CODED_BRAINPOOLP160R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}\n            #define CODED_BRAINPOOLP160R1_SZ 9\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;\n        #else\n            #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1\n        #endif\n        #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC160 */\n#ifdef ECC192\n    #ifndef NO_ECC_SECP\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP192R1    {1,2,840,10045,3,1,1}\n            #define CODED_SECP192R1_SZ 7\n        #else\n            #define CODED_SECP192R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}\n            #define CODED_SECP192R1_SZ 8\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;\n        #else\n            #define ecc_oid_secp192r1 CODED_SECP192R1\n        #endif\n        #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_SECPR2\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_PRIME192V2    {1,2,840,10045,3,1,2}\n            #define CODED_PRIME192V2_SZ 7\n        #else\n            #define CODED_PRIME192V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}\n            #define CODED_PRIME192V2_SZ 8\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;\n        #else\n            #define ecc_oid_prime192v2 CODED_PRIME192V2\n        #endif\n        #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ\n    #endif /* HAVE_ECC_SECPR2 */\n    #ifdef HAVE_ECC_SECPR3\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_PRIME192V3    {1,2,840,10045,3,1,3}\n            #define CODED_PRIME192V3_SZ 7\n        #else\n            #define CODED_PRIME192V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}\n            #define CODED_PRIME192V3_SZ 8\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;\n        #else\n            #define ecc_oid_prime192v3 CODED_PRIME192V3\n        #endif\n        #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ\n    #endif /* HAVE_ECC_SECPR3 */\n    #ifdef HAVE_ECC_KOBLITZ\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP192K1    {1,3,132,0,31}\n            #define CODED_SECP192K1_SZ 5\n        #else\n            #define CODED_SECP192K1    {0x2B,0x81,0x04,0x00,0x1F}\n            #define CODED_SECP192K1_SZ 5\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;\n        #else\n            #define ecc_oid_secp192k1 CODED_SECP192K1\n        #endif\n        #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ\n    #endif /* HAVE_ECC_KOBLITZ */\n    #ifdef HAVE_ECC_BRAINPOOL\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_BRAINPOOLP192R1    {1,3,36,3,3,2,8,1,1,3}\n            #define CODED_BRAINPOOLP192R1_SZ 10\n        #else\n            #define CODED_BRAINPOOLP192R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}\n            #define CODED_BRAINPOOLP192R1_SZ 9\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;\n        #else\n            #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1\n        #endif\n        #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC192 */\n#ifdef ECC224\n    #ifndef NO_ECC_SECP\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP224R1    {1,3,132,0,33}\n            #define CODED_SECP224R1_SZ 5\n        #else\n            #define CODED_SECP224R1    {0x2B,0x81,0x04,0x00,0x21}\n            #define CODED_SECP224R1_SZ 5\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;\n        #else\n            #define ecc_oid_secp224r1 CODED_SECP224R1\n        #endif\n        #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_KOBLITZ\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP224K1    {1,3,132,0,32}\n            #define CODED_SECP224K1_SZ 5\n        #else\n            #define CODED_SECP224K1    {0x2B,0x81,0x04,0x00,0x20}\n            #define CODED_SECP224K1_SZ 5\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;\n        #else\n            #define ecc_oid_secp224k1 CODED_SECP224K1\n        #endif\n        #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ\n    #endif /* HAVE_ECC_KOBLITZ */\n    #ifdef HAVE_ECC_BRAINPOOL\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_BRAINPOOLP224R1    {1,3,36,3,3,2,8,1,1,5}\n            #define CODED_BRAINPOOLP224R1_SZ 10\n        #else\n            #define CODED_BRAINPOOLP224R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}\n            #define CODED_BRAINPOOLP224R1_SZ 9\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;\n        #else\n            #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1\n        #endif\n        #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC224 */\n#ifdef ECC239\n    #ifndef NO_ECC_SECP\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_PRIME239V1    {1,2,840,10045,3,1,4}\n            #define CODED_PRIME239V1_SZ 7\n        #else\n            #define CODED_PRIME239V1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}\n            #define CODED_PRIME239V1_SZ 8\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;\n        #else\n            #define ecc_oid_prime239v1 CODED_PRIME239V1\n        #endif\n        #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_SECPR2\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_PRIME239V2    {1,2,840,10045,3,1,5}\n            #define CODED_PRIME239V2_SZ 7\n        #else\n            #define CODED_PRIME239V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}\n            #define CODED_PRIME239V2_SZ 8\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;\n        #else\n            #define ecc_oid_prime239v2 CODED_PRIME239V2\n        #endif\n        #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ\n    #endif /* HAVE_ECC_SECPR2 */\n    #ifdef HAVE_ECC_SECPR3\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_PRIME239V3    {1,2,840,10045,3,1,6}\n            #define CODED_PRIME239V3_SZ 7\n        #else\n            #define CODED_PRIME239V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}\n            #define CODED_PRIME239V3_SZ 8\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;\n        #else\n            #define ecc_oid_prime239v3 CODED_PRIME239V3\n        #endif\n        #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ\n    #endif /* HAVE_ECC_SECPR3 */\n#endif /* ECC239 */\n#ifdef ECC256\n    #ifndef NO_ECC_SECP\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP256R1    {1,2,840,10045,3,1,7}\n            #define CODED_SECP256R1_SZ 7\n        #else\n            #define CODED_SECP256R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}\n            #define CODED_SECP256R1_SZ 8\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;\n        #else\n            #define ecc_oid_secp256r1 CODED_SECP256R1\n        #endif\n        #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_KOBLITZ\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP256K1    {1,3,132,0,10}\n            #define CODED_SECP256K1_SZ 5\n        #else\n            #define CODED_SECP256K1    {0x2B,0x81,0x04,0x00,0x0A}\n            #define CODED_SECP256K1_SZ 5\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;\n        #else\n            #define ecc_oid_secp256k1 CODED_SECP256K1\n        #endif\n        #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ\n    #endif /* HAVE_ECC_KOBLITZ */\n    #ifdef HAVE_ECC_BRAINPOOL\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_BRAINPOOLP256R1    {1,3,36,3,3,2,8,1,1,7}\n            #define CODED_BRAINPOOLP256R1_SZ 10\n        #else\n            #define CODED_BRAINPOOLP256R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}\n            #define CODED_BRAINPOOLP256R1_SZ 9\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;\n        #else\n            #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1\n        #endif\n        #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC256 */\n#ifdef ECC320\n    #ifdef HAVE_ECC_BRAINPOOL\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_BRAINPOOLP320R1    {1,3,36,3,3,2,8,1,1,9}\n            #define CODED_BRAINPOOLP320R1_SZ 10\n        #else\n            #define CODED_BRAINPOOLP320R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}\n            #define CODED_BRAINPOOLP320R1_SZ 9\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;\n        #else\n            #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1\n        #endif\n        #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC320 */\n#ifdef ECC384\n    #ifndef NO_ECC_SECP\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP384R1    {1,3,132,0,34}\n            #define CODED_SECP384R1_SZ 5\n        #else\n            #define CODED_SECP384R1    {0x2B,0x81,0x04,0x00,0x22}\n            #define CODED_SECP384R1_SZ 5\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;\n            #define CODED_SECP384R1_OID ecc_oid_secp384r1\n        #else\n\t\t\t#define ecc_oid_secp384r1 CODED_SECP384R1\n        #endif\n        #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_BRAINPOOL\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_BRAINPOOLP384R1    {1,3,36,3,3,2,8,1,1,11}\n            #define CODED_BRAINPOOLP384R1_SZ 10\n        #else\n            #define CODED_BRAINPOOLP384R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}\n            #define CODED_BRAINPOOLP384R1_SZ 9\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;\n        #else\n            #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1\n        #endif\n        #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC384 */\n#ifdef ECC512\n    #ifdef HAVE_ECC_BRAINPOOL\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_BRAINPOOLP512R1    {1,3,36,3,3,2,8,1,1,13}\n            #define CODED_BRAINPOOLP512R1_SZ 10\n        #else\n            #define CODED_BRAINPOOLP512R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}\n            #define CODED_BRAINPOOLP512R1_SZ 9\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;\n        #else\n            #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1\n        #endif\n        #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC512 */\n#ifdef ECC521\n    #ifndef NO_ECC_SECP\n        #ifdef HAVE_OID_ENCODING\n            #define CODED_SECP521R1     {1,3,132,0,35}\n            #define CODED_SECP521R1_SZ 5\n        #else\n            #define CODED_SECP521R1     {0x2B,0x81,0x04,0x00,0x23}\n            #define CODED_SECP521R1_SZ 5\n        #endif\n        #ifndef USE_WINDOWS_API\n            static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;\n        #else\n            #define ecc_oid_secp521r1 CODED_SECP521R1\n        #endif\n        #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ\n    #endif /* !NO_ECC_SECP */\n#endif /* ECC521 */\n\n\n/* This holds the key settings.\n   ***MUST*** be organized by size from smallest to largest. */\n\nconst ecc_set_type ecc_sets[] = {\n#ifdef ECC112\n    #ifndef NO_ECC_SECP\n    {\n        14,                             /* size/bytes */\n        ECC_SECP112R1,                  /* ID         */\n        \"SECP112R1\",                    /* curve name */\n        \"DB7C2ABF62E35E668076BEAD208B\", /* prime      */\n        \"DB7C2ABF62E35E668076BEAD2088\", /* A          */\n        \"659EF8BA043916EEDE8911702B22\", /* B          */\n        \"DB7C2ABF62E35E7628DFAC6561C5\", /* order      */\n        \"9487239995A5EE76B55F9C2F098\",  /* Gx         */\n        \"A89CE5AF8724C0A23E0E0FF77500\", /* Gy         */\n        ecc_oid_secp112r1,              /* oid/oidSz  */\n        ecc_oid_secp112r1_sz,\n        ECC_SECP112R1_OID,              /* oid sum    */\n        1,                              /* cofactor   */\n    },\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_SECPR2\n    {\n        14,                             /* size/bytes */\n        ECC_SECP112R2,                  /* ID         */\n        \"SECP112R2\",                    /* curve name */\n        \"DB7C2ABF62E35E668076BEAD208B\", /* prime      */\n        \"6127C24C05F38A0AAAF65C0EF02C\", /* A          */\n        \"51DEF1815DB5ED74FCC34C85D709\", /* B          */\n        \"36DF0AAFD8B8D7597CA10520D04B\", /* order      */\n        \"4BA30AB5E892B4E1649DD0928643\", /* Gx         */\n        \"ADCD46F5882E3747DEF36E956E97\", /* Gy         */\n        ecc_oid_secp112r2,              /* oid/oidSz  */\n        ecc_oid_secp112r2_sz,\n        ECC_SECP112R2_OID,              /* oid sum    */\n        4,                              /* cofactor   */\n    },\n    #endif /* HAVE_ECC_SECPR2 */\n#endif /* ECC112 */\n#ifdef ECC128\n    #ifndef NO_ECC_SECP\n    {\n        16,                                 /* size/bytes */\n        ECC_SECP128R1,                      /* ID         */\n        \"SECP128R1\",                        /* curve name */\n        \"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF\", /* prime      */\n        \"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC\", /* A          */\n        \"E87579C11079F43DD824993C2CEE5ED3\", /* B          */\n        \"FFFFFFFE0000000075A30D1B9038A115\", /* order      */\n        \"161FF7528B899B2D0C28607CA52C5B86\", /* Gx         */\n        \"CF5AC8395BAFEB13C02DA292DDED7A83\", /* Gy         */\n        ecc_oid_secp128r1,                  /* oid/oidSz  */\n        ecc_oid_secp128r1_sz,\n        ECC_SECP128R1_OID,                  /* oid sum    */\n        1,                                  /* cofactor   */\n    },\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_SECPR2\n    {\n        16,                                 /* size/bytes */\n        ECC_SECP128R2,                      /* ID         */\n        \"SECP128R2\",                        /* curve name */\n        \"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF\", /* prime      */\n        \"D6031998D1B3BBFEBF59CC9BBFF9AEE1\", /* A          */\n        \"5EEEFCA380D02919DC2C6558BB6D8A5D\", /* B          */\n        \"3FFFFFFF7FFFFFFFBE0024720613B5A3\", /* order      */\n        \"7B6AA5D85E572983E6FB32A7CDEBC140\", /* Gx         */\n        \"27B6916A894D3AEE7106FE805FC34B44\", /* Gy         */\n        ecc_oid_secp128r2,                  /* oid/oidSz  */\n        ecc_oid_secp128r2_sz,\n        ECC_SECP128R2_OID,                  /* oid sum    */\n        4,                                  /* cofactor   */\n    },\n    #endif /* HAVE_ECC_SECPR2 */\n#endif /* ECC128 */\n#ifdef ECC160\n    #ifndef NO_ECC_SECP\n    {\n        20,                                         /* size/bytes */\n        ECC_SECP160R1,                              /* ID         */\n        \"SECP160R1\",                                /* curve name */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF\", /* prime      */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC\", /* A          */\n        \"1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45\", /* B          */\n        \"100000000000000000001F4C8F927AED3CA752257\",/* order      */\n        \"4A96B5688EF573284664698968C38BB913CBFC82\", /* Gx         */\n        \"23A628553168947D59DCC912042351377AC5FB32\", /* Gy         */\n        ecc_oid_secp160r1,                          /* oid/oidSz  */\n        ecc_oid_secp160r1_sz,\n        ECC_SECP160R1_OID,                          /* oid sum    */\n        1,                                          /* cofactor   */\n    },\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_SECPR2\n    {\n        20,                                         /* size/bytes */\n        ECC_SECP160R2,                              /* ID         */\n        \"SECP160R2\",                                /* curve name */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73\", /* prime      */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70\", /* A          */\n        \"B4E134D3FB59EB8BAB57274904664D5AF50388BA\", /* B          */\n        \"100000000000000000000351EE786A818F3A1A16B\",/* order      */\n        \"52DCB034293A117E1F4FF11B30F7199D3144CE6D\", /* Gx         */\n        \"FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E\", /* Gy         */\n        ecc_oid_secp160r2,                          /* oid/oidSz  */\n        ecc_oid_secp160r2_sz,\n        ECC_SECP160R2_OID,                          /* oid sum    */\n        1,                                          /* cofactor   */\n    },\n    #endif /* HAVE_ECC_SECPR2 */\n    #ifdef HAVE_ECC_KOBLITZ\n    {\n        20,                                         /* size/bytes */\n        ECC_SECP160K1,                              /* ID         */\n        \"SECP160K1\",                                /* curve name */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73\", /* prime      */\n        \"0000000000000000000000000000000000000000\", /* A          */\n        \"0000000000000000000000000000000000000007\", /* B          */\n        \"100000000000000000001B8FA16DFAB9ACA16B6B3\",/* order      */\n        \"3B4C382CE37AA192A4019E763036F4F5DD4D7EBB\", /* Gx         */\n        \"938CF935318FDCED6BC28286531733C3F03C4FEE\", /* Gy         */\n        ecc_oid_secp160k1,                          /* oid/oidSz  */\n        ecc_oid_secp160k1_sz,\n        ECC_SECP160K1_OID,                          /* oid sum    */\n        1,                                          /* cofactor   */\n    },\n    #endif /* HAVE_ECC_KOBLITZ */\n    #ifdef HAVE_ECC_BRAINPOOL\n    {\n        20,                                         /* size/bytes */\n        ECC_BRAINPOOLP160R1,                        /* ID         */\n        \"BRAINPOOLP160R1\",                          /* curve name */\n        \"E95E4A5F737059DC60DFC7AD95B3D8139515620F\", /* prime      */\n        \"340E7BE2A280EB74E2BE61BADA745D97E8F7C300\", /* A          */\n        \"1E589A8595423412134FAA2DBDEC95C8D8675E58\", /* B          */\n        \"E95E4A5F737059DC60DF5991D45029409E60FC09\", /* order      */\n        \"BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3\", /* Gx         */\n        \"1667CB477A1A8EC338F94741669C976316DA6321\", /* Gy         */\n        ecc_oid_brainpoolp160r1,                    /* oid/oidSz  */\n        ecc_oid_brainpoolp160r1_sz,\n        ECC_BRAINPOOLP160R1_OID,                    /* oid sum    */\n        1,                                          /* cofactor   */\n    },\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC160 */\n#ifdef ECC192\n    #ifndef NO_ECC_SECP\n    {\n        24,                                                 /* size/bytes */\n        ECC_SECP192R1,                                      /* ID         */\n        \"SECP192R1\",                                        /* curve name */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF\", /* prime      */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC\", /* A          */\n        \"64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1\", /* B          */\n        \"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831\", /* order      */\n        \"188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012\", /* Gx         */\n        \"7192B95FFC8DA78631011ED6B24CDD573F977A11E794811\",  /* Gy         */\n        ecc_oid_secp192r1,                                  /* oid/oidSz  */\n        ecc_oid_secp192r1_sz,\n        ECC_SECP192R1_OID,                                  /* oid sum    */\n        1,                                                  /* cofactor   */\n    },\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_SECPR2\n    {\n        24,                                                 /* size/bytes */\n        ECC_PRIME192V2,                                     /* ID         */\n        \"PRIME192V2\",                                       /* curve name */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF\", /* prime      */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC\", /* A          */\n        \"CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953\", /* B          */\n        \"FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31\", /* order      */\n        \"EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A\", /* Gx         */\n        \"6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15\", /* Gy         */\n        ecc_oid_prime192v2,                                 /* oid/oidSz  */\n        ecc_oid_prime192v2_sz,\n        ECC_PRIME192V2_OID,                                 /* oid sum    */\n        1,                                                  /* cofactor   */\n    },\n    #endif /* HAVE_ECC_SECPR2 */\n    #ifdef HAVE_ECC_SECPR3\n    {\n        24,                                                 /* size/bytes */\n        ECC_PRIME192V3,                                     /* ID         */\n        \"PRIME192V3\",                                       /* curve name */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF\", /* prime      */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC\", /* A          */\n        \"22123DC2395A05CAA7423DAECCC94760A7D462256BD56916\", /* B          */\n        \"FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13\", /* order      */\n        \"7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896\", /* Gx         */\n        \"38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0\", /* Gy         */\n        ecc_oid_prime192v3,                                 /* oid/oidSz  */\n        ecc_oid_prime192v3_sz,\n        ECC_PRIME192V3_OID,                                 /* oid sum    */\n        1,                                                  /* cofactor   */\n    },\n    #endif /* HAVE_ECC_SECPR3 */\n    #ifdef HAVE_ECC_KOBLITZ\n    {\n        24,                                                 /* size/bytes */\n        ECC_SECP192K1,                                      /* ID         */\n        \"SECP192K1\",                                        /* curve name */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37\", /* prime      */\n        \"000000000000000000000000000000000000000000000000\", /* A          */\n        \"000000000000000000000000000000000000000000000003\", /* B          */\n        \"FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D\", /* order      */\n        \"DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D\", /* Gx         */\n        \"9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D\", /* Gy         */\n        ecc_oid_secp192k1,                                  /* oid/oidSz  */\n        ecc_oid_secp192k1_sz,\n        ECC_SECP192K1_OID,                                  /* oid sum    */\n        1,                                                  /* cofactor   */\n    },\n    #endif /* HAVE_ECC_KOBLITZ */\n    #ifdef HAVE_ECC_BRAINPOOL\n    {\n        24,                                                 /* size/bytes */\n        ECC_BRAINPOOLP192R1,                                /* ID         */\n        \"BRAINPOOLP192R1\",                                  /* curve name */\n        \"C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297\", /* prime      */\n        \"6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF\", /* A          */\n        \"469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9\", /* B          */\n        \"C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1\", /* order      */\n        \"C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6\", /* Gx         */\n        \"14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F\", /* Gy         */\n        ecc_oid_brainpoolp192r1,                            /* oid/oidSz  */\n        ecc_oid_brainpoolp192r1_sz,\n        ECC_BRAINPOOLP192R1_OID,                            /* oid sum    */\n        1,                                                  /* cofactor   */\n    },\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC192 */\n#ifdef ECC224\n    #ifndef NO_ECC_SECP\n    {\n        28,                                                         /* size/bytes */\n        ECC_SECP224R1,                                              /* ID         */\n        \"SECP224R1\",                                                /* curve name */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001\", /* prime      */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE\", /* A          */\n        \"B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4\", /* B          */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D\", /* order      */\n        \"B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21\", /* Gx         */\n        \"BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34\", /* Gy         */\n        ecc_oid_secp224r1,                                          /* oid/oidSz  */\n        ecc_oid_secp224r1_sz,\n        ECC_SECP224R1_OID,                                          /* oid sum    */\n        1,                                                          /* cofactor   */\n    },\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_KOBLITZ\n    {\n        28,                                                         /* size/bytes */\n        ECC_SECP224K1,                                              /* ID         */\n        \"SECP224K1\",                                                /* curve name */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D\", /* prime      */\n        \"00000000000000000000000000000000000000000000000000000000\", /* A          */\n        \"00000000000000000000000000000000000000000000000000000005\", /* B          */\n        \"10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7\",/* order      */\n        \"A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C\", /* Gx         */\n        \"7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5\", /* Gy         */\n        ecc_oid_secp224k1,                                          /* oid/oidSz  */\n        ecc_oid_secp224k1_sz,\n        ECC_SECP224K1_OID,                                          /* oid sum    */\n        1,                                                          /* cofactor   */\n    },\n    #endif /* HAVE_ECC_KOBLITZ */\n    #ifdef HAVE_ECC_BRAINPOOL\n    {\n        28,                                                         /* size/bytes */\n        ECC_BRAINPOOLP224R1,                                        /* ID         */\n        \"BRAINPOOLP224R1\",                                          /* curve name */\n        \"D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF\", /* prime      */\n        \"68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43\", /* A          */\n        \"2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B\", /* B          */\n        \"D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F\", /* order      */\n        \"0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D\", /* Gx         */\n        \"58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD\", /* Gy         */\n        ecc_oid_brainpoolp224r1,                                    /* oid/oidSz  */\n        ecc_oid_brainpoolp224r1_sz,\n        ECC_BRAINPOOLP224R1_OID,                                    /* oid sum    */\n        1,                                                          /* cofactor   */\n    },\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC224 */\n#ifdef ECC239\n    #ifndef NO_ECC_SECP\n    {\n        30,                                                             /* size/bytes */\n        ECC_PRIME239V1,                                                 /* ID         */\n        \"PRIME239V1\",                                                   /* curve name */\n        \"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF\", /* prime      */\n        \"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC\", /* A          */\n        \"6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A\", /* B          */\n        \"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B\", /* order      */\n        \"0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF\", /* Gx         */\n        \"7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE\", /* Gy         */\n        ecc_oid_prime239v1,                                             /* oid/oidSz  */\n        ecc_oid_prime239v1_sz,\n        ECC_PRIME239V1_OID,                                             /* oid sum    */\n        1,                                                              /* cofactor   */\n    },\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_SECPR2\n    {\n        30,                                                             /* size/bytes */\n        ECC_PRIME239V2,                                                 /* ID         */\n        \"PRIME239V2\",                                                   /* curve name */\n        \"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF\", /* prime      */\n        \"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC\", /* A          */\n        \"617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C\", /* B          */\n        \"7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063\", /* order      */\n        \"38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7\", /* Gx         */\n        \"5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA\", /* Gy         */\n        ecc_oid_prime239v2,                                             /* oid/oidSz  */\n        ecc_oid_prime239v2_sz,\n        ECC_PRIME239V2_OID,                                             /* oid sum    */\n        1,                                                              /* cofactor   */\n    },\n    #endif /* HAVE_ECC_SECPR2 */\n    #ifdef HAVE_ECC_SECPR3\n    {\n        30,                                                             /* size/bytes */\n        ECC_PRIME239V3,                                                 /* ID         */\n        \"PRIME239V3\",                                                   /* curve name */\n        \"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF\", /* prime      */\n        \"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC\", /* A          */\n        \"255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E\", /* B          */\n        \"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551\", /* order      */\n        \"6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A\", /* Gx         */\n        \"1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3\", /* Gy         */\n        ecc_oid_prime239v3,                                             /* oid/oidSz  */\n        ecc_oid_prime239v3_sz,\n        ECC_PRIME239V3_OID,                                             /* oid sum    */\n        1,                                                              /* cofactor   */\n    },\n    #endif /* HAVE_ECC_SECPR3 */\n#endif /* ECC239 */\n#ifdef ECC256\n    #ifndef NO_ECC_SECP\n    {\n        32,                                                                 /* size/bytes */\n        ECC_SECP256R1,                                                      /* ID         */\n        \"SECP256R1\",                                                        /* curve name */\n        \"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\", /* prime      */\n        \"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC\", /* A          */\n        \"5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B\", /* B          */\n        \"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551\", /* order      */\n        \"6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296\", /* Gx         */\n        \"4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5\", /* Gy         */\n\t\tecc_oid_secp256r1,                                                  /* oid/oidSz  */\n        ecc_oid_secp256r1_sz,\n        ECC_SECP256R1_OID,                                                  /* oid sum    */\n        1,                                                                  /* cofactor   */\n    },\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_KOBLITZ\n    {\n        32,                                                                 /* size/bytes */\n        ECC_SECP256K1,                                                      /* ID         */\n        \"SECP256K1\",                                                        /* curve name */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F\", /* prime      */\n        \"0000000000000000000000000000000000000000000000000000000000000000\", /* A          */\n        \"0000000000000000000000000000000000000000000000000000000000000007\", /* B          */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\", /* order      */\n        \"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798\", /* Gx         */\n        \"483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8\", /* Gy         */\n        ecc_oid_secp256k1,                                                  /* oid/oidSz  */\n        ecc_oid_secp256k1_sz,\n        ECC_SECP256K1_OID,                                                  /* oid sum    */\n        1,                                                                  /* cofactor   */\n    },\n    #endif /* HAVE_ECC_KOBLITZ */\n    #ifdef HAVE_ECC_BRAINPOOL\n    {\n        32,                                                                 /* size/bytes */\n        ECC_BRAINPOOLP256R1,                                                /* ID         */\n        \"BRAINPOOLP256R1\",                                                  /* curve name */\n        \"A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377\", /* prime      */\n        \"7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9\", /* A          */\n        \"26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6\", /* B          */\n        \"A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7\", /* order      */\n        \"8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262\", /* Gx         */\n        \"547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997\", /* Gy         */\n        ecc_oid_brainpoolp256r1,                                            /* oid/oidSz  */\n        ecc_oid_brainpoolp256r1_sz,\n        ECC_BRAINPOOLP256R1_OID,                                            /* oid sum    */\n        1,                                                                  /* cofactor   */\n    },\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC256 */\n#ifdef ECC320\n    #ifdef HAVE_ECC_BRAINPOOL\n    {\n        40,                                                                                 /* size/bytes */\n        ECC_BRAINPOOLP320R1,                                                                /* ID         */\n        \"BRAINPOOLP320R1\",                                                                  /* curve name */\n        \"D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27\", /* prime      */\n        \"3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4\", /* A          */\n        \"520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6\", /* B          */\n        \"D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311\", /* order      */\n        \"43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611\", /* Gx         */\n        \"14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1\", /* Gy         */\n        ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz,                                /* oid/oidSz  */\n        ECC_BRAINPOOLP320R1_OID,                                                            /* oid sum    */\n        1,                                                                                  /* cofactor   */\n    },\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC320 */\n#ifdef ECC384\n    #ifndef NO_ECC_SECP\n    {\n        48,                                                                                                 /* size/bytes */\n        ECC_SECP384R1,                                                                                      /* ID         */\n        \"SECP384R1\",                                                                                        /* curve name */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF\", /* prime      */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC\", /* A          */\n        \"B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF\", /* B          */\n        \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973\", /* order      */\n        \"AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7\", /* Gx         */\n        \"3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F\", /* Gy         */\n        ecc_oid_secp384r1, ecc_oid_secp384r1_sz,                                                            /* oid/oidSz  */\n        ECC_SECP384R1_OID,                                                                                  /* oid sum    */\n        1,                                                                                                  /* cofactor   */\n    },\n    #endif /* !NO_ECC_SECP */\n    #ifdef HAVE_ECC_BRAINPOOL\n    {\n        48,                                                                                                 /* size/bytes */\n        ECC_BRAINPOOLP384R1,                                                                                /* ID         */\n        \"BRAINPOOLP384R1\",                                                                                  /* curve name */\n        \"8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53\", /* prime      */\n        \"7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826\", /* A          */\n        \"04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11\", /* B          */\n        \"8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565\", /* order      */\n        \"1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E\", /* Gx         */\n        \"8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315\", /* Gy         */\n        ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz,                                                /* oid/oidSz  */\n        ECC_BRAINPOOLP384R1_OID,                                                                            /* oid sum    */\n        1,                                                                                                  /* cofactor   */\n    },\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC384 */\n#ifdef ECC512\n    #ifdef HAVE_ECC_BRAINPOOL\n    {\n        64,                                                                                                                                 /* size/bytes */\n        ECC_BRAINPOOLP512R1,                                                                                                                /* ID         */\n        \"BRAINPOOLP512R1\",                                                                                                                  /* curve name */\n        \"AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3\", /* prime      */\n        \"7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA\", /* A          */\n        \"3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723\", /* B          */\n        \"AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069\", /* order      */\n        \"81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822\", /* Gx         */\n        \"7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892\", /* Gy         */\n        ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz,                                                                                /* oid/oidSz  */\n        ECC_BRAINPOOLP512R1_OID,                                                                                                            /* oid sum    */\n        1,                                                                                                                                  /* cofactor   */\n    },\n    #endif /* HAVE_ECC_BRAINPOOL */\n#endif /* ECC512 */\n#ifdef ECC521\n    #ifndef NO_ECC_SECP\n    {\n        66,                                                                                                                                    /* size/bytes */\n        ECC_SECP521R1,                                                                                                                         /* ID         */\n        \"SECP521R1\",                                                                                                                           /* curve name */\n        \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\", /* prime      */\n        \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC\", /* A          */\n        \"51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00\",  /* B          */\n        \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409\", /* order      */\n        \"C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66\",  /* Gx         */\n        \"11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650\", /* Gy         */\n        ecc_oid_secp521r1, ecc_oid_secp521r1_sz,                                                                                               /* oid/oidSz  */\n        ECC_SECP521R1_OID,                                                                                                                     /* oid sum    */\n        1,                                                                                                                                     /* cofactor   */\n    },\n    #endif /* !NO_ECC_SECP */\n#endif /* ECC521 */\n#if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)\n    /* place holder for custom curve index for cache */\n    {\n        1, /* non-zero */\n        ECC_CURVE_CUSTOM,\n        #ifndef USE_WINDOWS_API\n            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,\n        #else\n            {0},{0},{0},{0},{0},{0},{0},{0},\n        #endif\n        0, 0, 0\n    },\n#endif\n    {\n        0,\n        ECC_CURVE_INVALID,\n        #ifndef USE_WINDOWS_API\n            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,\n        #else\n            {0},{0},{0},{0},{0},{0},{0},{0},\n        #endif\n        0, 0, 0\n    }\n};\n#define ECC_SET_COUNT   (sizeof(ecc_sets)/sizeof(ecc_set_type))\n\n\n#ifdef HAVE_OID_ENCODING\n    /* encoded OID cache */\n    typedef struct {\n        word32 oidSz;\n        byte oid[ECC_MAX_OID_LEN];\n    } oid_cache_t;\n    static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];\n#endif\n\n\n#ifdef HAVE_COMP_KEY\nstatic int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen);\n#endif\n\n\n#if (defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)) && \\\n    !defined(WOLFSSL_ATECC508A)\nstatic int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,\n        mp_int* prime, mp_int* order);\n#endif\n\nint mp_jacobi(mp_int* a, mp_int* n, int* c);\nint mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);\n\n\n/* Curve Specs */\ntypedef struct ecc_curve_spec {\n    const ecc_set_type* dp;\n\n    mp_int* prime;\n    mp_int* Af;\n    #ifdef USE_ECC_B_PARAM\n        mp_int* Bf;\n    #endif\n    mp_int* order;\n    mp_int* Gx;\n    mp_int* Gy;\n\n#ifdef ECC_CACHE_CURVE\n    mp_int prime_lcl;\n    mp_int Af_lcl;\n    #ifdef USE_ECC_B_PARAM\n        mp_int Bf_lcl;\n    #endif\n    mp_int order_lcl;\n    mp_int Gx_lcl;\n    mp_int Gy_lcl;\n#else\n    mp_int* spec_ints;\n    word32 spec_count;\n    word32 spec_use;\n#endif\n\n    byte load_mask;\n} ecc_curve_spec;\n\nenum ecc_curve_load_mask {\n    ECC_CURVE_FIELD_NONE    = 0x00,\n    ECC_CURVE_FIELD_PRIME   = 0x01,\n    ECC_CURVE_FIELD_AF      = 0x02,\n#ifdef USE_ECC_B_PARAM\n    ECC_CURVE_FIELD_BF      = 0x04,\n#endif\n    ECC_CURVE_FIELD_ORDER   = 0x08,\n    ECC_CURVE_FIELD_GX      = 0x10,\n    ECC_CURVE_FIELD_GY      = 0x20,\n#ifdef USE_ECC_B_PARAM\n    ECC_CURVE_FIELD_ALL     = 0x3F,\n    ECC_CURVE_FIELD_COUNT   = 6,\n#else\n    ECC_CURVE_FIELD_ALL     = 0x3B,\n    ECC_CURVE_FIELD_COUNT   = 5,\n#endif\n};\n\n#ifdef ECC_CACHE_CURVE\n    /* cache (mp_int) of the curve parameters */\n    static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT];\n    #ifndef SINGLE_THREADED\n        static wolfSSL_Mutex ecc_curve_cache_mutex;\n    #endif\n\n    #define DECLARE_CURVE_SPECS(curve, intcount) ecc_curve_spec* curve = NULL\n    #define ALLOC_CURVE_SPECS(intcount)\n    #define FREE_CURVE_SPECS()\n#elif defined(WOLFSSL_SMALL_STACK)\n    #define DECLARE_CURVE_SPECS(curve, intcount)                        \\\n        mp_int* spec_ints = NULL;                                       \\\n        ecc_curve_spec curve_lcl;                                       \\\n        ecc_curve_spec* curve = &curve_lcl;                             \\\n        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \\\n        curve->spec_count = intcount\n\n    #define ALLOC_CURVE_SPECS(intcount)                                 \\\n        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \\\n                            DYNAMIC_TYPE_ECC);                          \\\n        if (spec_ints == NULL)                                          \\\n            return MEMORY_E;                                            \\\n        curve->spec_ints = spec_ints\n    #define FREE_CURVE_SPECS()                                          \\\n        XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)\n#else\n    #define DECLARE_CURVE_SPECS(curve, intcount) \\\n        mp_int spec_ints[(intcount)]; \\\n        ecc_curve_spec curve_lcl; \\\n        ecc_curve_spec* curve = &curve_lcl; \\\n        XMEMSET(curve, 0, sizeof(ecc_curve_spec)); \\\n        curve->spec_ints = spec_ints; \\\n        curve->spec_count = intcount\n    #define ALLOC_CURVE_SPECS(intcount)\n    #define FREE_CURVE_SPECS()\n#endif /* ECC_CACHE_CURVE */\n\nstatic void _wc_ecc_curve_free(ecc_curve_spec* curve)\n{\n    if (curve == NULL) {\n        return;\n    }\n\n    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)\n        mp_clear(curve->prime);\n    if (curve->load_mask & ECC_CURVE_FIELD_AF)\n        mp_clear(curve->Af);\n#ifdef USE_ECC_B_PARAM\n    if (curve->load_mask & ECC_CURVE_FIELD_BF)\n        mp_clear(curve->Bf);\n#endif\n    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)\n        mp_clear(curve->order);\n    if (curve->load_mask & ECC_CURVE_FIELD_GX)\n        mp_clear(curve->Gx);\n    if (curve->load_mask & ECC_CURVE_FIELD_GY)\n        mp_clear(curve->Gy);\n\n    curve->load_mask = 0;\n}\n\nstatic void wc_ecc_curve_free(ecc_curve_spec* curve)\n{\n    /* don't free cached curves */\n#ifndef ECC_CACHE_CURVE\n    _wc_ecc_curve_free(curve);\n#endif\n    (void)curve;\n}\n\nstatic int wc_ecc_curve_load_item(const char* src, mp_int** dst,\n    ecc_curve_spec* curve, byte mask)\n{\n    int err;\n\n#ifndef ECC_CACHE_CURVE\n    /* get mp_int from temp */\n    if (curve->spec_use >= curve->spec_count) {\n        WOLFSSL_MSG(\"Invalid DECLARE_CURVE_SPECS count\");\n        return ECC_BAD_ARG_E;\n    }\n    *dst = &curve->spec_ints[curve->spec_use++];\n#endif\n\n    err = mp_init(*dst);\n    if (err == MP_OKAY) {\n        curve->load_mask |= mask;\n\n        err = mp_read_radix(*dst, src, MP_RADIX_HEX);\n\n    #ifdef HAVE_WOLF_BIGINT\n        if (err == MP_OKAY)\n            err = wc_mp_to_bigint(*dst, &(*dst)->raw);\n    #endif\n    }\n    return err;\n}\n\nstatic int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,\n    byte load_mask)\n{\n    int ret = 0, x;\n    ecc_curve_spec* curve;\n    byte load_items = 0; /* mask of items to load */\n\n    if (dp == NULL || pCurve == NULL)\n        return BAD_FUNC_ARG;\n\n#ifdef ECC_CACHE_CURVE\n    x = wc_ecc_get_curve_idx(dp->id);\n    if (x == ECC_CURVE_INVALID)\n        return ECC_BAD_ARG_E;\n\n#if !defined(SINGLE_THREADED)\n    ret = wc_LockMutex(&ecc_curve_cache_mutex);\n    if (ret != 0) {\n        return ret;\n    }\n#endif\n\n    /* make sure cache has been allocated */\n    if (ecc_curve_spec_cache[x] == NULL) {\n        ecc_curve_spec_cache[x] = (ecc_curve_spec*)XMALLOC(\n            sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);\n        if (ecc_curve_spec_cache[x] == NULL) {\n        #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)\n            wc_UnLockMutex(&ecc_curve_cache_mutex);\n        #endif\n            return MEMORY_E;\n        }\n        XMEMSET(ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec));\n    }\n\n    /* set curve pointer to cache */\n    *pCurve = ecc_curve_spec_cache[x];\n\n#endif /* ECC_CACHE_CURVE */\n    curve = *pCurve;\n\n    /* make sure the curve is initialized */\n    if (curve->dp != dp) {\n        curve->load_mask = 0;\n\n    #ifdef ECC_CACHE_CURVE\n        curve->prime = &curve->prime_lcl;\n        curve->Af = &curve->Af_lcl;\n        #ifdef USE_ECC_B_PARAM\n            curve->Bf = &curve->Bf_lcl;\n        #endif\n        curve->order = &curve->order_lcl;\n        curve->Gx = &curve->Gx_lcl;\n        curve->Gy = &curve->Gy_lcl;\n    #endif\n    }\n    curve->dp = dp; /* set dp info */\n\n    /* determine items to load */\n    load_items = (((byte)~(word32)curve->load_mask) & load_mask);\n    curve->load_mask |= load_items;\n\n    /* load items */\n    x = 0;\n    if (load_items & ECC_CURVE_FIELD_PRIME)\n        x += wc_ecc_curve_load_item(dp->prime, &curve->prime, curve,\n            ECC_CURVE_FIELD_PRIME);\n    if (load_items & ECC_CURVE_FIELD_AF)\n        x += wc_ecc_curve_load_item(dp->Af, &curve->Af, curve,\n            ECC_CURVE_FIELD_AF);\n#ifdef USE_ECC_B_PARAM\n    if (load_items & ECC_CURVE_FIELD_BF)\n        x += wc_ecc_curve_load_item(dp->Bf, &curve->Bf, curve,\n            ECC_CURVE_FIELD_BF);\n#endif\n    if (load_items & ECC_CURVE_FIELD_ORDER)\n        x += wc_ecc_curve_load_item(dp->order, &curve->order, curve,\n            ECC_CURVE_FIELD_ORDER);\n    if (load_items & ECC_CURVE_FIELD_GX)\n        x += wc_ecc_curve_load_item(dp->Gx, &curve->Gx, curve,\n            ECC_CURVE_FIELD_GX);\n    if (load_items & ECC_CURVE_FIELD_GY)\n        x += wc_ecc_curve_load_item(dp->Gy, &curve->Gy, curve,\n            ECC_CURVE_FIELD_GY);\n\n    /* check for error */\n    if (x != 0) {\n        wc_ecc_curve_free(curve);\n        ret = MP_READ_E;\n    }\n\n#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)\n    wc_UnLockMutex(&ecc_curve_cache_mutex);\n#endif\n\n    return ret;\n}\n\n#ifdef ECC_CACHE_CURVE\nint wc_ecc_curve_cache_init(void)\n{\n    int ret = 0;\n#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)\n    ret = wc_InitMutex(&ecc_curve_cache_mutex);\n#endif\n    return ret;\n}\n\nvoid wc_ecc_curve_cache_free(void)\n{\n    int x;\n\n    /* free all ECC curve caches */\n    for (x = 0; x < (int)ECC_SET_COUNT; x++) {\n        if (ecc_curve_spec_cache[x]) {\n            _wc_ecc_curve_free(ecc_curve_spec_cache[x]);\n            XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);\n            ecc_curve_spec_cache[x] = NULL;\n        }\n    }\n\n#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)\n    wc_FreeMutex(&ecc_curve_cache_mutex);\n#endif\n}\n#endif /* ECC_CACHE_CURVE */\n\n\n/* Retrieve the curve name for the ECC curve id.\n *\n * curve_id  The id of the curve.\n * returns the name stored from the curve if available, otherwise NULL.\n */\nconst char* wc_ecc_get_name(int curve_id)\n{\n    int curve_idx = wc_ecc_get_curve_idx(curve_id);\n    if (curve_idx == ECC_CURVE_INVALID)\n        return NULL;\n    return ecc_sets[curve_idx].name;\n}\n\nint wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)\n{\n    if (keysize <= 0 && curve_id < 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (keysize > ECC_MAXSIZE) {\n        return ECC_BAD_ARG_E;\n    }\n\n    /* handle custom case */\n    if (key->idx != ECC_CUSTOM_IDX) {\n        int x;\n\n        /* default values */\n        key->idx = 0;\n        key->dp = NULL;\n\n        /* find ecc_set based on curve_id or key size */\n        for (x = 0; ecc_sets[x].size != 0; x++) {\n            if (curve_id > ECC_CURVE_DEF) {\n                if (curve_id == ecc_sets[x].id)\n                  break;\n            }\n            else if (keysize <= ecc_sets[x].size) {\n                break;\n            }\n        }\n        if (ecc_sets[x].size == 0) {\n            WOLFSSL_MSG(\"ECC Curve not found\");\n            return ECC_CURVE_OID_E;\n        }\n\n        key->idx = x;\n        key->dp  = &ecc_sets[x];\n    }\n\n    return 0;\n}\n\n\n#ifdef ALT_ECC_SIZE\nstatic void alt_fp_init(mp_int* a)\n{\n    a->size = FP_SIZE_ECC;\n    mp_zero(a);\n}\n#endif /* ALT_ECC_SIZE */\n\n\n#ifndef WOLFSSL_ATECC508A\n\n#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)\n\n/**\n   Add two ECC points\n   P        The point to add\n   Q        The point to add\n   R        [out] The destination of the double\n   a        ECC curve parameter a\n   modulus  The modulus of the field the ECC curve is in\n   mp       The \"b\" value from montgomery_setup()\n   return   MP_OKAY on success\n*/\nint ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,\n                             mp_int* a, mp_int* modulus, mp_digit mp)\n{\n#ifndef WOLFSSL_SP_MATH\n#ifdef WOLFSSL_SMALL_STACK\n   mp_int* t1 = NULL;\n   mp_int* t2 = NULL;\n#ifdef ALT_ECC_SIZE\n   mp_int* rx = NULL;\n   mp_int* ry = NULL;\n   mp_int* rz = NULL;\n#endif\n#else\n   mp_int  t1[1], t2[1];\n#ifdef ALT_ECC_SIZE\n   mp_int  rx[1], ry[1], rz[1];\n#endif\n#endif\n   mp_int  *x, *y, *z;\n   int     err;\n\n   if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {\n       return ECC_BAD_ARG_E;\n   }\n\n   /* if Q == R then swap P and Q, so we don't require a local x,y,z */\n   if (Q == R) {\n      ecc_point* tPt  = P;\n      P = Q;\n      Q = tPt;\n   }\n\n#ifdef WOLFSSL_SMALL_STACK\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n   if (R->key != NULL) {\n       t1 = R->key->t1;\n       t2 = R->key->t2;\n#ifdef ALT_ECC_SIZE\n       rx = R->key->x;\n       ry = R->key->y;\n       rz = R->key->z;\n#endif\n   }\n   else\n#endif /* WOLFSSL_SMALL_STACK_CACHE */\n   {\n       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       if (t1 == NULL || t2 == NULL) {\n           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n           return MEMORY_E;\n       }\n#ifdef ALT_ECC_SIZE\n       rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       if (rx == NULL || ry == NULL || rz == NULL) {\n           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n           return MEMORY_E;\n       }\n#endif\n   }\n#endif /* WOLFSSL_SMALL_STACK */\n\n   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n   #ifdef WOLFSSL_SMALL_STACK_CACHE\n       if (R->key == NULL)\n   #endif\n       {\n       #ifdef ALT_ECC_SIZE\n          XFREE(rz, NULL, DYNAMIC_TYPE_ECC);\n          XFREE(ry, NULL, DYNAMIC_TYPE_ECC);\n          XFREE(rx, NULL, DYNAMIC_TYPE_ECC);\n       #endif\n          XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n          XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n       }\n#endif\n      return err;\n   }\n\n   /* should we dbl instead? */\n   if (err == MP_OKAY)\n       err = mp_sub(modulus, Q->y, t1);\n   if (err == MP_OKAY) {\n       if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&\n            (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&\n            (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {\n           mp_clear(t1);\n           mp_clear(t2);\n    #ifdef WOLFSSL_SMALL_STACK\n       #ifdef WOLFSSL_SMALL_STACK_CACHE\n           if (R->key == NULL)\n       #endif\n           {\n            #ifdef ALT_ECC_SIZE\n               XFREE(rz, NULL, DYNAMIC_TYPE_ECC);\n               XFREE(ry, NULL, DYNAMIC_TYPE_ECC);\n               XFREE(rx, NULL, DYNAMIC_TYPE_ECC);\n            #endif\n               XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n               XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n           }\n        #endif\n          return ecc_projective_dbl_point(P, R, a, modulus, mp);\n       }\n   }\n\n   if (err != MP_OKAY) {\n      goto done;\n   }\n\n/* If use ALT_ECC_SIZE we need to use local stack variable since\n   ecc_point x,y,z is reduced size */\n#ifdef ALT_ECC_SIZE\n   /* Use local stack variable */\n   x = rx;\n   y = ry;\n   z = rz;\n\n   if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {\n      goto done;\n   }\n#else\n   /* Use destination directly */\n   x = R->x;\n   y = R->y;\n   z = R->z;\n#endif\n\n   if (err == MP_OKAY)\n       err = mp_copy(P->x, x);\n   if (err == MP_OKAY)\n       err = mp_copy(P->y, y);\n   if (err == MP_OKAY)\n       err = mp_copy(P->z, z);\n\n   /* if Z is one then these are no-operations */\n   if (err == MP_OKAY) {\n       if (!mp_iszero(Q->z)) {\n           /* T1 = Z' * Z' */\n           err = mp_sqr(Q->z, t1);\n           if (err == MP_OKAY)\n               err = mp_montgomery_reduce(t1, modulus, mp);\n\n           /* X = X * T1 */\n           if (err == MP_OKAY)\n               err = mp_mul(t1, x, x);\n           if (err == MP_OKAY)\n               err = mp_montgomery_reduce(x, modulus, mp);\n\n           /* T1 = Z' * T1 */\n           if (err == MP_OKAY)\n               err = mp_mul(Q->z, t1, t1);\n           if (err == MP_OKAY)\n               err = mp_montgomery_reduce(t1, modulus, mp);\n\n           /* Y = Y * T1 */\n           if (err == MP_OKAY)\n               err = mp_mul(t1, y, y);\n           if (err == MP_OKAY)\n               err = mp_montgomery_reduce(y, modulus, mp);\n       }\n   }\n\n   /* T1 = Z*Z */\n   if (err == MP_OKAY)\n       err = mp_sqr(z, t1);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(t1, modulus, mp);\n\n   /* T2 = X' * T1 */\n   if (err == MP_OKAY)\n       err = mp_mul(Q->x, t1, t2);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(t2, modulus, mp);\n\n   /* T1 = Z * T1 */\n   if (err == MP_OKAY)\n       err = mp_mul(z, t1, t1);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(t1, modulus, mp);\n\n   /* T1 = Y' * T1 */\n   if (err == MP_OKAY)\n       err = mp_mul(Q->y, t1, t1);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(t1, modulus, mp);\n\n   /* Y = Y - T1 */\n   if (err == MP_OKAY)\n       err = mp_sub(y, t1, y);\n   if (err == MP_OKAY) {\n       if (mp_isneg(y))\n           err = mp_add(y, modulus, y);\n   }\n   /* T1 = 2T1 */\n   if (err == MP_OKAY)\n       err = mp_add(t1, t1, t1);\n   if (err == MP_OKAY) {\n       if (mp_cmp(t1, modulus) != MP_LT)\n           err = mp_sub(t1, modulus, t1);\n   }\n   /* T1 = Y + T1 */\n   if (err == MP_OKAY)\n       err = mp_add(t1, y, t1);\n   if (err == MP_OKAY) {\n       if (mp_cmp(t1, modulus) != MP_LT)\n           err = mp_sub(t1, modulus, t1);\n   }\n   /* X = X - T2 */\n   if (err == MP_OKAY)\n       err = mp_sub(x, t2, x);\n   if (err == MP_OKAY) {\n       if (mp_isneg(x))\n           err = mp_add(x, modulus, x);\n   }\n   /* T2 = 2T2 */\n   if (err == MP_OKAY)\n       err = mp_add(t2, t2, t2);\n   if (err == MP_OKAY) {\n       if (mp_cmp(t2, modulus) != MP_LT)\n           err = mp_sub(t2, modulus, t2);\n   }\n   /* T2 = X + T2 */\n   if (err == MP_OKAY)\n       err = mp_add(t2, x, t2);\n   if (err == MP_OKAY) {\n       if (mp_cmp(t2, modulus) != MP_LT)\n           err = mp_sub(t2, modulus, t2);\n   }\n\n   if (err == MP_OKAY) {\n       if (!mp_iszero(Q->z)) {\n           /* Z = Z * Z' */\n           err = mp_mul(z, Q->z, z);\n           if (err == MP_OKAY)\n               err = mp_montgomery_reduce(z, modulus, mp);\n       }\n   }\n\n   /* Z = Z * X */\n   if (err == MP_OKAY)\n       err = mp_mul(z, x, z);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(z, modulus, mp);\n\n   /* T1 = T1 * X  */\n   if (err == MP_OKAY)\n       err = mp_mul(t1, x, t1);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(t1, modulus, mp);\n\n   /* X = X * X */\n   if (err == MP_OKAY)\n       err = mp_sqr(x, x);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(x, modulus, mp);\n\n   /* T2 = T2 * x */\n   if (err == MP_OKAY)\n       err = mp_mul(t2, x, t2);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(t2, modulus, mp);\n\n   /* T1 = T1 * X  */\n   if (err == MP_OKAY)\n       err = mp_mul(t1, x, t1);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(t1, modulus, mp);\n\n   /* X = Y*Y */\n   if (err == MP_OKAY)\n       err = mp_sqr(y, x);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(x, modulus, mp);\n\n   /* X = X - T2 */\n   if (err == MP_OKAY)\n       err = mp_sub(x, t2, x);\n   if (err == MP_OKAY) {\n       if (mp_isneg(x))\n           err = mp_add(x, modulus, x);\n   }\n   /* T2 = T2 - X */\n   if (err == MP_OKAY)\n       err = mp_sub(t2, x, t2);\n   if (err == MP_OKAY) {\n       if (mp_isneg(t2))\n           err = mp_add(t2, modulus, t2);\n   }\n   /* T2 = T2 - X */\n   if (err == MP_OKAY)\n       err = mp_sub(t2, x, t2);\n   if (err == MP_OKAY) {\n       if (mp_isneg(t2))\n           err = mp_add(t2, modulus, t2);\n   }\n   /* T2 = T2 * Y */\n   if (err == MP_OKAY)\n       err = mp_mul(t2, y, t2);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(t2, modulus, mp);\n\n   /* Y = T2 - T1 */\n   if (err == MP_OKAY)\n       err = mp_sub(t2, t1, y);\n   if (err == MP_OKAY) {\n       if (mp_isneg(y))\n           err = mp_add(y, modulus, y);\n   }\n   /* Y = Y/2 */\n   if (err == MP_OKAY) {\n       if (mp_isodd(y) == MP_YES)\n           err = mp_add(y, modulus, y);\n   }\n   if (err == MP_OKAY)\n       err = mp_div_2(y, y);\n\n#ifdef ALT_ECC_SIZE\n   if (err == MP_OKAY)\n       err = mp_copy(x, R->x);\n   if (err == MP_OKAY)\n       err = mp_copy(y, R->y);\n   if (err == MP_OKAY)\n       err = mp_copy(z, R->z);\n#endif\n\ndone:\n\n   /* clean up */\n   mp_clear(t1);\n   mp_clear(t2);\n#ifdef WOLFSSL_SMALL_STACK\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n   if (R->key == NULL)\n#endif\n   {\n   #ifdef ALT_ECC_SIZE\n      XFREE(rz, NULL, DYNAMIC_TYPE_ECC);\n      XFREE(ry, NULL, DYNAMIC_TYPE_ECC);\n      XFREE(rx, NULL, DYNAMIC_TYPE_ECC);\n   #endif\n      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n   }\n#endif\n\n   return err;\n#else\n    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {\n        return ECC_BAD_ARG_E;\n    }\n\n    (void)a;\n    (void)mp;\n\n    return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,\n                                     R->x, R->y, R->z);\n#endif\n}\n\n/* ### Point doubling in Jacobian coordinate system ###\n *\n * let us have a curve:                 y^2 = x^3 + a*x + b\n * in Jacobian coordinates it becomes:  y^2 = x^3 + a*x*z^4 + b*z^6\n *\n * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:\n * Xr = M^2 - 2*S\n * Yr = M * (S - Xr) - 8*T\n * Zr = 2 * Yp * Zp\n *\n * M = 3 * Xp^2 + a*Zp^4\n * T = Yp^4\n * S = 4 * Xp * Yp^2\n *\n * SPECIAL CASE: when a == 3 we can compute M as\n * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)\n */\n\n/**\n   Double an ECC point\n   P   The point to double\n   R   [out] The destination of the double\n   a   ECC curve parameter a\n   modulus  The modulus of the field the ECC curve is in\n   mp       The \"b\" value from montgomery_setup()\n   return   MP_OKAY on success\n*/\nint ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,\n                                       mp_int* modulus, mp_digit mp)\n{\n#ifndef WOLFSSL_SP_MATH\n#ifdef WOLFSSL_SMALL_STACK\n   mp_int* t1 = NULL;\n   mp_int* t2 = NULL;\n#ifdef ALT_ECC_SIZE\n   mp_int* rx = NULL;\n   mp_int* ry = NULL;\n   mp_int* rz = NULL;\n#endif\n#else\n   mp_int  t1[1], t2[1];\n#ifdef ALT_ECC_SIZE\n   mp_int  rx[1], ry[1], rz[1];\n#endif\n#endif\n   mp_int *x, *y, *z;\n   int    err;\n\n   if (P == NULL || R == NULL || modulus == NULL)\n       return ECC_BAD_ARG_E;\n\n#ifdef WOLFSSL_SMALL_STACK\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n   if (R->key != NULL) {\n       t1 = R->key->t1;\n       t2 = R->key->t2;\n   #ifdef ALT_ECC_SIZE\n       rx = R->key->x;\n       ry = R->key->y;\n       rz = R->key->z;\n   #endif\n   }\n   else\n#endif /* WOLFSSL_SMALL_STACK_CACHE */\n   {\n       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       if (t1 == NULL || t2 == NULL) {\n           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n           return MEMORY_E;\n       }\n    #ifdef ALT_ECC_SIZE\n       rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       if (rx == NULL || ry == NULL || rz == NULL) {\n           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n           return MEMORY_E;\n       }\n    #endif\n    }\n#endif\n\n   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    if (R->key == NULL)\n#endif\n    {\n    #ifdef ALT_ECC_SIZE\n       XFREE(rz, NULL, DYNAMIC_TYPE_ECC);\n       XFREE(ry, NULL, DYNAMIC_TYPE_ECC);\n       XFREE(rx, NULL, DYNAMIC_TYPE_ECC);\n    #endif\n       XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n     }\n#endif\n      return err;\n   }\n\n/* If use ALT_ECC_SIZE we need to use local stack variable since\n   ecc_point x,y,z is reduced size */\n#ifdef ALT_ECC_SIZE\n   /* Use local stack variable */\n   x = rx;\n   y = ry;\n   z = rz;\n\n   if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {\n       mp_clear(t1);\n       mp_clear(t2);\n    #ifdef WOLFSSL_SMALL_STACK\n    #ifdef WOLFSSL_SMALL_STACK_CACHE\n       if (R->key == NULL)\n    #endif\n       {\n       #ifdef ALT_ECC_SIZE\n          XFREE(rz, NULL, DYNAMIC_TYPE_ECC);\n          XFREE(ry, NULL, DYNAMIC_TYPE_ECC);\n          XFREE(rx, NULL, DYNAMIC_TYPE_ECC);\n       #endif\n          XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n          XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n       }\n    #endif\n       return err;\n   }\n#else\n   /* Use destination directly */\n   x = R->x;\n   y = R->y;\n   z = R->z;\n#endif\n\n   if (err == MP_OKAY)\n       err = mp_copy(P->x, x);\n   if (err == MP_OKAY)\n       err = mp_copy(P->y, y);\n   if (err == MP_OKAY)\n       err = mp_copy(P->z, z);\n\n   /* T1 = Z * Z */\n   if (err == MP_OKAY)\n       err = mp_sqr(z, t1);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(t1, modulus, mp);\n\n   /* Z = Y * Z */\n   if (err == MP_OKAY)\n       err = mp_mul(z, y, z);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(z, modulus, mp);\n\n   /* Z = 2Z */\n   if (err == MP_OKAY)\n       err = mp_add(z, z, z);\n   if (err == MP_OKAY) {\n       if (mp_cmp(z, modulus) != MP_LT)\n           err = mp_sub(z, modulus, z);\n   }\n\n   /* Determine if curve \"a\" should be used in calc */\n#ifdef WOLFSSL_CUSTOM_CURVES\n   if (err == MP_OKAY) {\n      /* Use a and prime to determine if a == 3 */\n      err = mp_submod(modulus, a, modulus, t2);\n   }\n   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {\n      /* use \"a\" in calc */\n\n      /* T2 = T1 * T1 */\n      if (err == MP_OKAY)\n          err = mp_sqr(t1, t2);\n      if (err == MP_OKAY)\n          err = mp_montgomery_reduce(t2, modulus, mp);\n      /* T1 = T2 * a */\n      if (err == MP_OKAY)\n          err = mp_mulmod(t2, a, modulus, t1);\n      /* T2 = X * X */\n      if (err == MP_OKAY)\n          err = mp_sqr(x, t2);\n      if (err == MP_OKAY)\n          err = mp_montgomery_reduce(t2, modulus, mp);\n      /* T1 = T2 + T1 */\n      if (err == MP_OKAY)\n          err = mp_add(t1, t2, t1);\n      if (err == MP_OKAY) {\n         if (mp_cmp(t1, modulus) != MP_LT)\n            err = mp_sub(t1, modulus, t1);\n      }\n      /* T1 = T2 + T1 */\n      if (err == MP_OKAY)\n          err = mp_add(t1, t2, t1);\n      if (err == MP_OKAY) {\n          if (mp_cmp(t1, modulus) != MP_LT)\n              err = mp_sub(t1, modulus, t1);\n      }\n      /* T1 = T2 + T1 */\n      if (err == MP_OKAY)\n          err = mp_add(t1, t2, t1);\n      if (err == MP_OKAY) {\n         if (mp_cmp(t1, modulus) != MP_LT)\n            err = mp_sub(t1, modulus, t1);\n      }\n   }\n   else\n#endif /* WOLFSSL_CUSTOM_CURVES */\n   {\n      /* assumes \"a\" == 3 */\n      (void)a;\n\n      /* T2 = X - T1 */\n      if (err == MP_OKAY)\n          err = mp_sub(x, t1, t2);\n      if (err == MP_OKAY) {\n          if (mp_isneg(t2))\n              err = mp_add(t2, modulus, t2);\n      }\n      /* T1 = X + T1 */\n      if (err == MP_OKAY)\n          err = mp_add(t1, x, t1);\n      if (err == MP_OKAY) {\n          if (mp_cmp(t1, modulus) != MP_LT)\n              err = mp_sub(t1, modulus, t1);\n      }\n      /* T2 = T1 * T2 */\n      if (err == MP_OKAY)\n          err = mp_mul(t1, t2, t2);\n      if (err == MP_OKAY)\n          err = mp_montgomery_reduce(t2, modulus, mp);\n\n      /* T1 = 2T2 */\n      if (err == MP_OKAY)\n          err = mp_add(t2, t2, t1);\n      if (err == MP_OKAY) {\n          if (mp_cmp(t1, modulus) != MP_LT)\n              err = mp_sub(t1, modulus, t1);\n      }\n      /* T1 = T1 + T2 */\n      if (err == MP_OKAY)\n          err = mp_add(t1, t2, t1);\n      if (err == MP_OKAY) {\n          if (mp_cmp(t1, modulus) != MP_LT)\n              err = mp_sub(t1, modulus, t1);\n      }\n   }\n\n   /* Y = 2Y */\n   if (err == MP_OKAY)\n       err = mp_add(y, y, y);\n   if (err == MP_OKAY) {\n       if (mp_cmp(y, modulus) != MP_LT)\n           err = mp_sub(y, modulus, y);\n   }\n   /* Y = Y * Y */\n   if (err == MP_OKAY)\n       err = mp_sqr(y, y);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(y, modulus, mp);\n\n   /* T2 = Y * Y */\n   if (err == MP_OKAY)\n       err = mp_sqr(y, t2);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(t2, modulus, mp);\n\n   /* T2 = T2/2 */\n   if (err == MP_OKAY) {\n       if (mp_isodd(t2) == MP_YES)\n           err = mp_add(t2, modulus, t2);\n   }\n   if (err == MP_OKAY)\n       err = mp_div_2(t2, t2);\n\n   /* Y = Y * X */\n   if (err == MP_OKAY)\n       err = mp_mul(y, x, y);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(y, modulus, mp);\n\n   /* X = T1 * T1 */\n   if (err == MP_OKAY)\n       err = mp_sqr(t1, x);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(x, modulus, mp);\n\n   /* X = X - Y */\n   if (err == MP_OKAY)\n       err = mp_sub(x, y, x);\n   if (err == MP_OKAY) {\n       if (mp_isneg(x))\n           err = mp_add(x, modulus, x);\n   }\n   /* X = X - Y */\n   if (err == MP_OKAY)\n       err = mp_sub(x, y, x);\n   if (err == MP_OKAY) {\n       if (mp_isneg(x))\n           err = mp_add(x, modulus, x);\n   }\n\n   /* Y = Y - X */\n   if (err == MP_OKAY)\n       err = mp_sub(y, x, y);\n   if (err == MP_OKAY) {\n       if (mp_isneg(y))\n           err = mp_add(y, modulus, y);\n   }\n   /* Y = Y * T1 */\n   if (err == MP_OKAY)\n       err = mp_mul(y, t1, y);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(y, modulus, mp);\n\n   /* Y = Y - T2 */\n   if (err == MP_OKAY)\n       err = mp_sub(y, t2, y);\n   if (err == MP_OKAY) {\n       if (mp_isneg(y))\n           err = mp_add(y, modulus, y);\n   }\n\n#ifdef ALT_ECC_SIZE\n   if (err == MP_OKAY)\n       err = mp_copy(x, R->x);\n   if (err == MP_OKAY)\n       err = mp_copy(y, R->y);\n   if (err == MP_OKAY)\n       err = mp_copy(z, R->z);\n#endif\n\n   /* clean up */\n   mp_clear(t1);\n   mp_clear(t2);\n\n#ifdef WOLFSSL_SMALL_STACK\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n   if (R->key == NULL)\n#endif\n   {\n    #ifdef ALT_ECC_SIZE\n       XFREE(rz, NULL, DYNAMIC_TYPE_ECC);\n       XFREE(ry, NULL, DYNAMIC_TYPE_ECC);\n       XFREE(rx, NULL, DYNAMIC_TYPE_ECC);\n    #endif\n       XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n   return err;\n#else\n    if (P == NULL || R == NULL || modulus == NULL)\n        return ECC_BAD_ARG_E;\n\n    (void)a;\n    (void)mp;\n\n    return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);\n#endif\n}\n\n\n/**\n  Map a projective jacbobian point back to affine space\n  P        [in/out] The point to map\n  modulus  The modulus of the field the ECC curve is in\n  mp       The \"b\" value from montgomery_setup()\n  return   MP_OKAY on success\n*/\nint ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)\n{\n#ifndef WOLFSSL_SP_MATH\n#ifdef WOLFSSL_SMALL_STACK\n   mp_int* t1 = NULL;\n   mp_int* t2 = NULL;\n#ifdef ALT_ECC_SIZE\n   mp_int* rx = NULL;\n   mp_int* ry = NULL;\n   mp_int* rz = NULL;\n#endif\n#else\n   mp_int  t1[1], t2[1];\n#ifdef ALT_ECC_SIZE\n   mp_int  rx[1], ry[1], rz[1];\n#endif\n#endif /* WOLFSSL_SMALL_STACK */\n   mp_int *x, *y, *z;\n   int    err;\n\n   if (P == NULL || modulus == NULL)\n       return ECC_BAD_ARG_E;\n\n   /* special case for point at infinity */\n   if (mp_cmp_d(P->z, 0) == MP_EQ) {\n       err = mp_set(P->x, 0);\n       if (err == MP_OKAY)\n           err = mp_set(P->y, 0);\n       if (err == MP_OKAY)\n           err = mp_set(P->z, 1);\n       return err;\n   }\n\n#ifdef WOLFSSL_SMALL_STACK\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n   if (P->key != NULL) {\n       t1 = P->key->t1;\n       t2 = P->key->t2;\n   #ifdef ALT_ECC_SIZE\n       rx = P->key->x;\n       ry = P->key->y;\n       rz = P->key->z;\n   #endif\n   }\n   else\n#endif /* WOLFSSL_SMALL_STACK_CACHE */\n   {\n       t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       if (t1 == NULL || t2 == NULL) {\n           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n           return MEMORY_E;\n       }\n#ifdef ALT_ECC_SIZE\n       rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n       if (rx == NULL || ry == NULL || rz == NULL) {\n           XFREE(rz, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(ry, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(rx, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n           XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n           return MEMORY_E;\n       }\n#endif\n   }\n#endif /* WOLFSSL_SMALL_STACK */\n\n   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n      if (P->key == NULL)\n#endif\n      {\n      #ifdef ALT_ECC_SIZE\n         XFREE(rz, NULL, DYNAMIC_TYPE_ECC);\n         XFREE(ry, NULL, DYNAMIC_TYPE_ECC);\n         XFREE(rx, NULL, DYNAMIC_TYPE_ECC);\n      #endif\n         XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n         XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n      }\n#endif\n      return MEMORY_E;\n   }\n\n#ifdef ALT_ECC_SIZE\n   /* Use local stack variable */\n   x = rx;\n   y = ry;\n   z = rz;\n\n   if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {\n       goto done;\n   }\n\n   if (err == MP_OKAY)\n       err = mp_copy(P->x, x);\n   if (err == MP_OKAY)\n       err = mp_copy(P->y, y);\n   if (err == MP_OKAY)\n       err = mp_copy(P->z, z);\n\n   if (err != MP_OKAY) {\n      goto done;\n   }\n#else\n   /* Use destination directly */\n   x = P->x;\n   y = P->y;\n   z = P->z;\n#endif\n\n   /* first map z back to normal */\n   err = mp_montgomery_reduce(z, modulus, mp);\n\n   /* get 1/z */\n   if (err == MP_OKAY)\n       err = mp_invmod(z, modulus, t1);\n\n   /* get 1/z^2 and 1/z^3 */\n   if (err == MP_OKAY)\n       err = mp_sqr(t1, t2);\n   if (err == MP_OKAY)\n       err = mp_mod(t2, modulus, t2);\n   if (err == MP_OKAY)\n       err = mp_mul(t1, t2, t1);\n   if (err == MP_OKAY)\n       err = mp_mod(t1, modulus, t1);\n\n   /* multiply against x/y */\n   if (err == MP_OKAY)\n       err = mp_mul(x, t2, x);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(x, modulus, mp);\n   if (err == MP_OKAY)\n       err = mp_mul(y, t1, y);\n   if (err == MP_OKAY)\n       err = mp_montgomery_reduce(y, modulus, mp);\n\n   if (err == MP_OKAY)\n       err = mp_set(z, 1);\n\n#ifdef ALT_ECC_SIZE\n   /* return result */\n   if (err == MP_OKAY)\n      err = mp_copy(x, P->x);\n   if (err == MP_OKAY)\n      err = mp_copy(y, P->y);\n   if (err == MP_OKAY)\n      err = mp_copy(z, P->z);\n\ndone:\n#endif\n\n   /* clean up */\n   mp_clear(t1);\n   mp_clear(t2);\n\n#ifdef WOLFSSL_SMALL_STACK\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n   if (P->key == NULL)\n#endif\n   {\n   #ifdef ALT_ECC_SIZE\n      XFREE(rz, NULL, DYNAMIC_TYPE_ECC);\n      XFREE(ry, NULL, DYNAMIC_TYPE_ECC);\n      XFREE(rx, NULL, DYNAMIC_TYPE_ECC);\n   #endif\n      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n   }\n#endif\n\n   return err;\n#else\n    if (P == NULL || modulus == NULL)\n        return ECC_BAD_ARG_E;\n\n    (void)mp;\n\n    return sp_ecc_map_256(P->x, P->y, P->z);\n#endif\n}\n\n#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */\n\n#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA)\n\n#if !defined(FP_ECC) || !defined(WOLFSSL_SP_MATH)\n/**\n   Perform a point multiplication\n   k    The scalar to multiply by\n   G    The base point\n   R    [out] Destination for kG\n   a    ECC curve parameter a\n   modulus  The modulus of the field the ECC curve is in\n   map      Boolean whether to map back to affine or not\n                (1==map, 0 == leave in projective)\n   return MP_OKAY on success\n*/\n#ifdef FP_ECC\nstatic int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R,\n                  mp_int* a, mp_int* modulus, int map,\n                  void* heap)\n#else\nint wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,\n                  mp_int* a, mp_int* modulus, int map,\n                  void* heap)\n#endif\n{\n#ifndef WOLFSSL_SP_MATH\n#ifndef ECC_TIMING_RESISTANT\n   /* size of sliding window, don't change this! */\n   #define WINSIZE  4\n   #define M_POINTS 8\n   int           first = 1, bitbuf = 0, bitcpy = 0, j;\n#else\n   #define M_POINTS 4\n#endif\n\n   ecc_point     *tG, *M[M_POINTS];\n   int           i, err;\n#ifdef WOLFSSL_SMALL_STACK\n   mp_int*       mu = NULL;\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n   ecc_key       key;\n#endif\n#else\n   mp_int        mu[1];\n#endif\n   mp_digit      mp;\n   mp_digit      buf;\n   int           bitcnt = 0, mode = 0, digidx = 0;\n\n   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {\n       return ECC_BAD_ARG_E;\n   }\n\n   /* init variables */\n   tG = NULL;\n   XMEMSET(M, 0, sizeof(M));\n#ifdef WOLFSSL_SMALL_STACK\n   mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);\n   if (mu == NULL)\n       return MEMORY_E;\n#endif\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n   key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);\n   key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);\n#ifdef ALT_ECC_SIZE\n   key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);\n   key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);\n   key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);\n#endif\n   if (key.t1 == NULL || key.t2 == NULL\n#ifdef ALT_ECC_SIZE\n      || key.x == NULL || key.y == NULL || key.z == NULL\n#endif\n   ) {\n#ifdef ALT_ECC_SIZE\n       XFREE(key.z, heap, DYNAMIC_TYPE_ECC);\n       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);\n       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);\n#endif\n       XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);\n       XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);\n       XFREE(mu, heap, DYNAMIC_TYPE_ECC);\n       return MEMORY_E;\n   }\n#endif /* WOLFSSL_SMALL_STACK_CACHE */\n\n   /* init montgomery reduction */\n   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n#ifdef ALT_ECC_SIZE\n       XFREE(key.z, heap, DYNAMIC_TYPE_ECC);\n       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);\n       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);\n#endif\n       XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);\n       XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);\n#endif /* WOLFSSL_SMALL_STACK_CACHE */\n#ifdef WOLFSSL_SMALL_STACK\n       XFREE(mu, heap, DYNAMIC_TYPE_ECC);\n#endif\n       return err;\n   }\n\n   if ((err = mp_init(mu)) != MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n#ifdef ALT_ECC_SIZE\n       XFREE(key.z, heap, DYNAMIC_TYPE_ECC);\n       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);\n       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);\n#endif\n       XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);\n       XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);\n#endif /* WOLFSSL_SMALL_STACK_CACHE */\n#ifdef WOLFSSL_SMALL_STACK\n       XFREE(mu, heap, DYNAMIC_TYPE_ECC);\n#endif\n       return err;\n   }\n   if ((err = mp_montgomery_calc_normalization(mu, modulus)) != MP_OKAY) {\n       mp_clear(mu);\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n#ifdef ALT_ECC_SIZE\n       XFREE(key.z, heap, DYNAMIC_TYPE_ECC);\n       XFREE(key.y, heap, DYNAMIC_TYPE_ECC);\n       XFREE(key.x, heap, DYNAMIC_TYPE_ECC);\n#endif\n       XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);\n       XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);\n#endif /* WOLFSSL_SMALL_STACK_CACHE */\n#ifdef WOLFSSL_SMALL_STACK\n       XFREE(mu, heap, DYNAMIC_TYPE_ECC);\n#endif\n       return err;\n   }\n\n  /* alloc ram for window temps */\n  for (i = 0; i < M_POINTS; i++) {\n      M[i] = wc_ecc_new_point_h(heap);\n      if (M[i] == NULL) {\n         mp_clear(mu);\n         err = MEMORY_E; goto exit;\n      }\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n      M[i]->key = &key;\n#endif\n  }\n\n   /* make a copy of G in case R==G */\n   tG = wc_ecc_new_point_h(heap);\n   if (tG == NULL)\n       err = MEMORY_E;\n\n   /* tG = G  and convert to montgomery */\n   if (err == MP_OKAY) {\n       if (mp_cmp_d(mu, 1) == MP_EQ) {\n           err = mp_copy(G->x, tG->x);\n           if (err == MP_OKAY)\n               err = mp_copy(G->y, tG->y);\n           if (err == MP_OKAY)\n               err = mp_copy(G->z, tG->z);\n       } else {\n           err = mp_mulmod(G->x, mu, modulus, tG->x);\n           if (err == MP_OKAY)\n               err = mp_mulmod(G->y, mu, modulus, tG->y);\n           if (err == MP_OKAY)\n               err = mp_mulmod(G->z, mu, modulus, tG->z);\n       }\n   }\n\n   /* done with mu */\n   mp_clear(mu);\n\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n   R->key = &key;\n#endif\n#ifndef ECC_TIMING_RESISTANT\n\n   /* calc the M tab, which holds kG for k==8..15 */\n   /* M[0] == 8G */\n   if (err == MP_OKAY)\n       err = ecc_projective_dbl_point(tG, M[0], a, modulus, mp);\n   if (err == MP_OKAY)\n       err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp);\n   if (err == MP_OKAY)\n       err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp);\n\n   /* now find (8+k)G for k=1..7 */\n   if (err == MP_OKAY)\n       for (j = 9; j < 16; j++) {\n           err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a, modulus,\n                                                                            mp);\n           if (err != MP_OKAY) break;\n       }\n\n   /* setup sliding window */\n   if (err == MP_OKAY) {\n       mode   = 0;\n       bitcnt = 1;\n       buf    = 0;\n       digidx = get_digit_count(k) - 1;\n       bitcpy = bitbuf = 0;\n       first  = 1;\n\n       /* perform ops */\n       for (;;) {\n           /* grab next digit as required */\n           if (--bitcnt == 0) {\n               if (digidx == -1) {\n                   break;\n               }\n               buf    = get_digit(k, digidx);\n               bitcnt = (int) DIGIT_BIT;\n               --digidx;\n           }\n\n           /* grab the next msb from the ltiplicand */\n           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;\n           buf <<= 1;\n\n           /* skip leading zero bits */\n           if (mode == 0 && i == 0)\n               continue;\n\n           /* if the bit is zero and mode == 1 then we double */\n           if (mode == 1 && i == 0) {\n               err = ecc_projective_dbl_point(R, R, a, modulus, mp);\n               if (err != MP_OKAY) break;\n               continue;\n           }\n\n           /* else we add it to the window */\n           bitbuf |= (i << (WINSIZE - ++bitcpy));\n           mode = 2;\n\n           if (bitcpy == WINSIZE) {\n               /* if this is the first window we do a simple copy */\n               if (first == 1) {\n                   /* R = kG [k = first window] */\n                   err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);\n                   if (err != MP_OKAY) break;\n\n                   err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);\n                   if (err != MP_OKAY) break;\n\n                   err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);\n                   first = 0;\n               } else {\n                   /* normal window */\n                   /* ok window is filled so double as required and add  */\n                   /* double first */\n                   for (j = 0; j < WINSIZE; j++) {\n                       err = ecc_projective_dbl_point(R, R, a, modulus, mp);\n                       if (err != MP_OKAY) break;\n                   }\n                   if (err != MP_OKAY) break;  /* out of first for(;;) */\n\n                   /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */\n                   err = ecc_projective_add_point(R, M[bitbuf-M_POINTS], R, a,\n                                                                   modulus, mp);\n               }\n               if (err != MP_OKAY) break;\n               /* empty window and reset */\n               bitcpy = bitbuf = 0;\n               mode = 1;\n           }\n       }\n   }\n\n   /* if bits remain then double/add */\n   if (err == MP_OKAY) {\n       if (mode == 2 && bitcpy > 0) {\n           /* double then add */\n           for (j = 0; j < bitcpy; j++) {\n               /* only double if we have had at least one add first */\n               if (first == 0) {\n                   err = ecc_projective_dbl_point(R, R, a, modulus, mp);\n                   if (err != MP_OKAY) break;\n               }\n\n               bitbuf <<= 1;\n               if ((bitbuf & (1 << WINSIZE)) != 0) {\n                   if (first == 1) {\n                       /* first add, so copy */\n                       err = mp_copy(tG->x, R->x);\n                       if (err != MP_OKAY) break;\n\n                       err = mp_copy(tG->y, R->y);\n                       if (err != MP_OKAY) break;\n\n                       err = mp_copy(tG->z, R->z);\n                       if (err != MP_OKAY) break;\n                       first = 0;\n                   } else {\n                       /* then add */\n                       err = ecc_projective_add_point(R, tG, R, a, modulus, mp);\n                       if (err != MP_OKAY) break;\n                   }\n               }\n           }\n       }\n   }\n\n   #undef WINSIZE\n\n#else /* ECC_TIMING_RESISTANT */\n\n   /* calc the M tab */\n   /* M[0] == G */\n   if (err == MP_OKAY)\n       err = mp_copy(tG->x, M[0]->x);\n   if (err == MP_OKAY)\n       err = mp_copy(tG->y, M[0]->y);\n   if (err == MP_OKAY)\n       err = mp_copy(tG->z, M[0]->z);\n\n   /* M[1] == 2G */\n   if (err == MP_OKAY)\n       err = ecc_projective_dbl_point(tG, M[1], a, modulus, mp);\n\n   /* setup sliding window */\n   mode   = 0;\n   bitcnt = 1;\n   buf    = 0;\n   digidx = get_digit_count(modulus) - 1;\n   /* The order MAY be 1 bit longer than the modulus. */\n   digidx += (modulus->dp[digidx] >> (DIGIT_BIT-1));\n\n   /* perform ops */\n   if (err == MP_OKAY) {\n       for (;;) {\n           /* grab next digit as required */\n           if (--bitcnt == 0) {\n               if (digidx == -1) {\n                   break;\n               }\n               buf = get_digit(k, digidx);\n               bitcnt = (int)DIGIT_BIT;\n               --digidx;\n           }\n\n           /* grab the next msb from the multiplicand */\n           i = (buf >> (DIGIT_BIT - 1)) & 1;\n           buf <<= 1;\n\n#ifdef WC_NO_CACHE_RESISTANT\n           if (mode == 0) {\n               /* timing resistant - dummy operations */\n               if (err == MP_OKAY)\n                   err = ecc_projective_add_point(M[1], M[2], M[2], a, modulus,\n                                                  mp);\n               if (err == MP_OKAY)\n                   err = ecc_projective_dbl_point(M[2], M[3], a, modulus, mp);\n           }\n           else {\n               if (err == MP_OKAY)\n                   err = ecc_projective_add_point(M[0], M[1], M[i^1], a,\n                                                  modulus, mp);\n               if (err == MP_OKAY)\n                   err = ecc_projective_dbl_point(M[i], M[i], a, modulus, mp);\n           }\n\n           mode |= i;\n#else\n           if (err == MP_OKAY)\n               err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus,\n                                              mp);\n           if (err == MP_OKAY)\n               err = mp_copy(M[2]->x,\n                             (mp_int*)\n                             ( ((size_t)M[0]->x & wc_off_on_addr[mode&(i  )]) +\n                               ((size_t)M[1]->x & wc_off_on_addr[mode&(i^1)]) +\n                               ((size_t)M[2]->x & wc_off_on_addr[mode^1])) );\n           if (err == MP_OKAY)\n               err = mp_copy(M[2]->y,\n                             (mp_int*)\n                             ( ((size_t)M[0]->y & wc_off_on_addr[mode&(i  )]) +\n                               ((size_t)M[1]->y & wc_off_on_addr[mode&(i^1)]) +\n                               ((size_t)M[2]->y & wc_off_on_addr[mode^1])) );\n           if (err == MP_OKAY)\n               err = mp_copy(M[2]->z,\n                             (mp_int*)\n                             ( ((size_t)M[0]->z & wc_off_on_addr[mode&(i  )]) +\n                               ((size_t)M[1]->z & wc_off_on_addr[mode&(i^1)]) +\n                               ((size_t)M[2]->z & wc_off_on_addr[mode^1])) );\n\n            /* instead of using M[i] for double, which leaks key bit to cache\n             * monitor, use M[2] as temp, make sure address calc is constant,\n             * keep M[0] and M[1] in cache */\n           if (err == MP_OKAY)\n               err = mp_copy((mp_int*)\n                             ( ((size_t)M[0]->x & wc_off_on_addr[i^1]) +\n                               ((size_t)M[1]->x & wc_off_on_addr[i])),\n                             M[2]->x);\n           if (err == MP_OKAY)\n               err = mp_copy((mp_int*)\n                             ( ((size_t)M[0]->y & wc_off_on_addr[i^1]) +\n                               ((size_t)M[1]->y & wc_off_on_addr[i])),\n                             M[2]->y);\n           if (err == MP_OKAY)\n               err = mp_copy((mp_int*)\n                             ( ((size_t)M[0]->z & wc_off_on_addr[i^1]) +\n                               ((size_t)M[1]->z & wc_off_on_addr[i])),\n                             M[2]->z);\n           if (err == MP_OKAY)\n               err = ecc_projective_dbl_point(M[2], M[3], a, modulus, mp);\n           /* copy M[2] back to M[i] */\n           if (err == MP_OKAY)\n               err = mp_copy((mp_int*)\n                             (((size_t)M[2]->x & wc_off_on_addr[mode^1]) +\n                              ((size_t)M[3]->x & wc_off_on_addr[mode])),\n                             (mp_int*)\n                             ( ((size_t)M[0]->x & wc_off_on_addr[i^1]) +\n                               ((size_t)M[1]->x & wc_off_on_addr[i])) );\n           if (err == MP_OKAY)\n               err = mp_copy((mp_int*)\n                             (((size_t)M[2]->y & wc_off_on_addr[mode^1]) +\n                              ((size_t)M[3]->y & wc_off_on_addr[mode])),\n                             (mp_int*)\n                             ( ((size_t)M[0]->y & wc_off_on_addr[i^1]) +\n                               ((size_t)M[1]->y & wc_off_on_addr[i])) );\n           if (err == MP_OKAY)\n               err = mp_copy((mp_int*)\n                             (((size_t)M[2]->z & wc_off_on_addr[mode^1]) +\n                              ((size_t)M[3]->z & wc_off_on_addr[mode])),\n                             (mp_int*)\n                             ( ((size_t)M[0]->z & wc_off_on_addr[i^1]) +\n                               ((size_t)M[1]->z & wc_off_on_addr[i])) );\n           if (err != MP_OKAY)\n               break;\n\n           mode |= i;\n#endif /* WC_NO_CACHE_RESISTANT */\n       } /* end for */\n   }\n\n   /* copy result out */\n   if (err == MP_OKAY)\n       err = mp_copy(M[0]->x, R->x);\n   if (err == MP_OKAY)\n       err = mp_copy(M[0]->y, R->y);\n   if (err == MP_OKAY)\n       err = mp_copy(M[0]->z, R->z);\n\n#endif /* ECC_TIMING_RESISTANT */\n\n   /* map R back from projective space */\n   if (err == MP_OKAY && map)\n       err = ecc_map(R, modulus, mp);\n\nexit:\n\n   /* done */\n   wc_ecc_del_point_h(tG, heap);\n   for (i = 0; i < M_POINTS; i++) {\n       wc_ecc_del_point_h(M[i], heap);\n   }\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n   R->key = NULL;\n#ifdef ALT_ECC_SIZE\n   XFREE(key.z, heap, DYNAMIC_TYPE_ECC);\n   XFREE(key.y, heap, DYNAMIC_TYPE_ECC);\n   XFREE(key.x, heap, DYNAMIC_TYPE_ECC);\n#endif\n   XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);\n   XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);\n#endif /* WOLFSSL_SMALL_STACK_CACHE */\n#ifdef WOLFSSL_SMALL_STACK\n   XFREE(mu, heap, DYNAMIC_TYPE_ECC);\n#endif\n\n   return err;\n#else\n   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {\n       return ECC_BAD_ARG_E;\n   }\n\n   (void)a;\n\n   return sp_ecc_mulmod_256(k, G, R, map, heap);\n#endif\n}\n\n#endif /* !FP_ECC || !WOLFSSL_SP_MATH */\n\n#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */\n\n/** ECC Fixed Point mulmod global\n    k        The multiplicand\n    G        Base point to multiply\n    R        [out] Destination of product\n    a        ECC curve parameter a\n    modulus  The modulus for the curve\n    map      [boolean] If non-zero maps the point back to affine co-ordinates,\n             otherwise it's left in jacobian-montgomery form\n    return MP_OKAY if successful\n*/\nint wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,\n                  mp_int* modulus, int map)\n{\n    return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);\n}\n\n#endif /* !WOLFSSL_ATECC508A */\n\n/**\n * use a heap hint when creating new ecc_point\n * return an allocated point on success or NULL on failure\n */\necc_point* wc_ecc_new_point_h(void* heap)\n{\n   ecc_point* p;\n\n   (void)heap;\n\n   p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);\n   if (p == NULL) {\n      return NULL;\n   }\n   XMEMSET(p, 0, sizeof(ecc_point));\n\n#ifndef ALT_ECC_SIZE\n   if (mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL) != MP_OKAY) {\n      XFREE(p, heap, DYNAMIC_TYPE_ECC);\n      return NULL;\n   }\n#else\n   p->x = (mp_int*)&p->xyz[0];\n   p->y = (mp_int*)&p->xyz[1];\n   p->z = (mp_int*)&p->xyz[2];\n   alt_fp_init(p->x);\n   alt_fp_init(p->y);\n   alt_fp_init(p->z);\n#endif\n\n   return p;\n}\n\n\n/**\n   Allocate a new ECC point\n   return A newly allocated point or NULL on error\n*/\necc_point* wc_ecc_new_point(void)\n{\n  return wc_ecc_new_point_h(NULL);\n}\n\n\nvoid wc_ecc_del_point_h(ecc_point* p, void* heap)\n{\n   /* prevents free'ing null arguments */\n   if (p != NULL) {\n      mp_clear(p->x);\n      mp_clear(p->y);\n      mp_clear(p->z);\n      XFREE(p, heap, DYNAMIC_TYPE_ECC);\n   }\n   (void)heap;\n}\n\n\n/** Free an ECC point from memory\n  p   The point to free\n*/\nvoid wc_ecc_del_point(ecc_point* p)\n{\n    wc_ecc_del_point_h(p, NULL);\n}\n\n\n/** Copy the value of a point to an other one\n  p    The point to copy\n  r    The created point\n*/\nint wc_ecc_copy_point(ecc_point* p, ecc_point *r)\n{\n    int ret;\n\n    /* prevents null arguments */\n    if (p == NULL || r == NULL)\n        return ECC_BAD_ARG_E;\n\n    ret = mp_copy(p->x, r->x);\n    if (ret != MP_OKAY)\n        return ret;\n    ret = mp_copy(p->y, r->y);\n    if (ret != MP_OKAY)\n        return ret;\n    ret = mp_copy(p->z, r->z);\n    if (ret != MP_OKAY)\n        return ret;\n\n    return MP_OKAY;\n}\n\n/** Compare the value of a point with an other one\n a    The point to compare\n b    The other point to compare\n\n return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error\n */\nint wc_ecc_cmp_point(ecc_point* a, ecc_point *b)\n{\n    int ret;\n\n    /* prevents null arguments */\n    if (a == NULL || b == NULL)\n        return BAD_FUNC_ARG;\n\n    ret = mp_cmp(a->x, b->x);\n    if (ret != MP_EQ)\n        return ret;\n    ret = mp_cmp(a->y, b->y);\n    if (ret != MP_EQ)\n        return ret;\n    ret = mp_cmp(a->z, b->z);\n    if (ret != MP_EQ)\n        return ret;\n\n    return MP_EQ;\n}\n\n\n/** Returns whether an ECC idx is valid or not\n  n      The idx number to check\n  return 1 if valid, 0 if not\n*/\nint wc_ecc_is_valid_idx(int n)\n{\n   int x;\n\n   for (x = 0; ecc_sets[x].size != 0; x++)\n       ;\n   /* -1 is a valid index --- indicating that the domain params\n      were supplied by the user */\n   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {\n      return 1;\n   }\n\n   return 0;\n}\n\nint wc_ecc_get_curve_idx(int curve_id)\n{\n    int curve_idx;\n    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {\n        if (curve_id == ecc_sets[curve_idx].id)\n            break;\n    }\n    if (ecc_sets[curve_idx].size == 0) {\n        return ECC_CURVE_INVALID;\n    }\n    return curve_idx;\n}\n\nint wc_ecc_get_curve_id(int curve_idx)\n{\n    if (wc_ecc_is_valid_idx(curve_idx)) {\n        return ecc_sets[curve_idx].id;\n    }\n    return ECC_CURVE_INVALID;\n}\n\n/* Returns the curve size that corresponds to a given ecc_curve_id identifier\n *\n * id      curve id, from ecc_curve_id enum in ecc.h\n * return  curve size, from ecc_sets[] on success, negative on error\n */\nint wc_ecc_get_curve_size_from_id(int curve_id)\n{\n    int curve_idx = wc_ecc_get_curve_idx(curve_id);\n    if (curve_idx == ECC_CURVE_INVALID)\n        return ECC_BAD_ARG_E;\n    return ecc_sets[curve_idx].size;\n}\n\n/* Returns the curve index that corresponds to a given curve name in\n * ecc_sets[] of ecc.c\n *\n * name    curve name, from ecc_sets[].name in ecc.c\n * return  curve index in ecc_sets[] on success, negative on error\n */\nint wc_ecc_get_curve_idx_from_name(const char* curveName)\n{\n    int curve_idx;\n    word32 len;\n\n    if (curveName == NULL)\n        return BAD_FUNC_ARG;\n\n    len = (word32)XSTRLEN(curveName);\n\n    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {\n        if (ecc_sets[curve_idx].name &&\n                XSTRNCASECMP(ecc_sets[curve_idx].name, curveName, len) == 0) {\n            break;\n        }\n    }\n    if (ecc_sets[curve_idx].size == 0) {\n        WOLFSSL_MSG(\"ecc_set curve name not found\");\n        return ECC_CURVE_INVALID;\n    }\n    return curve_idx;\n}\n\n/* Returns the curve size that corresponds to a given curve name,\n * as listed in ecc_sets[] of ecc.c.\n *\n * name    curve name, from ecc_sets[].name in ecc.c\n * return  curve size, from ecc_sets[] on success, negative on error\n */\nint wc_ecc_get_curve_size_from_name(const char* curveName)\n{\n    int curve_idx;\n\n    if (curveName == NULL)\n        return BAD_FUNC_ARG;\n\n    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);\n    if (curve_idx < 0)\n        return curve_idx;\n\n    return ecc_sets[curve_idx].size;\n}\n\n/* Returns the curve id that corresponds to a given curve name,\n * as listed in ecc_sets[] of ecc.c.\n *\n * name   curve name, from ecc_sets[].name in ecc.c\n * return curve id, from ecc_sets[] on success, negative on error\n */\nint wc_ecc_get_curve_id_from_name(const char* curveName)\n{\n    int curve_idx;\n\n    if (curveName == NULL)\n        return BAD_FUNC_ARG;\n\n    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);\n    if (curve_idx < 0)\n        return curve_idx;\n\n    return ecc_sets[curve_idx].id;\n}\n\n/* Compares a curve parameter (hex, from ecc_sets[]) to given input\n * parameter for equality.\n * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR\n * Returns MP_EQ on success, negative on error */\nstatic int wc_ecc_cmp_param(const char* curveParam,\n                            const byte* param, word32 paramSz, int encType)\n{\n    int err = MP_OKAY;\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int* a = NULL;\n    mp_int* b = NULL;\n#else\n    mp_int  a[1], b[1];\n#endif\n\n    if (param == NULL || curveParam == NULL)\n        return BAD_FUNC_ARG;\n\n    if (encType == WC_TYPE_HEX_STR)\n        return XSTRNCMP(curveParam, (char*) param, paramSz);\n\n#ifdef WOLFSSL_SMALL_STACK\n    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n    if (a == NULL)\n        return MEMORY_E;\n    b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n    if (b == NULL) {\n        XFREE(a, NULL, DYNAMIC_TYPE_ECC);\n        return MEMORY_E;\n    }\n#endif\n\n    if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(a, NULL, DYNAMIC_TYPE_ECC);\n        XFREE(b, NULL, DYNAMIC_TYPE_ECC);\n    #endif\n        return err;\n    }\n\n    if (err == MP_OKAY) {\n        err = mp_read_unsigned_bin(a, param, paramSz);\n    }\n    if (err == MP_OKAY)\n        err = mp_read_radix(b, curveParam, MP_RADIX_HEX);\n\n    if (err == MP_OKAY) {\n        if (mp_cmp(a, b) != MP_EQ) {\n            err = -1;\n        } else {\n            err = MP_EQ;\n        }\n    }\n\n    mp_clear(a);\n    mp_clear(b);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(b, NULL, DYNAMIC_TYPE_ECC);\n    XFREE(a, NULL, DYNAMIC_TYPE_ECC);\n#endif\n\n    return err;\n}\n\n/* Returns the curve id in ecc_sets[] that corresponds to a given set of\n * curve parameters.\n *\n * fieldSize  the field size in bits\n * prime      prime of the finite field\n * primeSz    size of prime in octets\n * Af         first coefficient a of the curve\n * AfSz       size of Af in octets\n * Bf         second coefficient b of the curve\n * BfSz       size of Bf in octets\n * order      curve order\n * orderSz    size of curve in octets\n * Gx         affine x coordinate of base point\n * GxSz       size of Gx in octets\n * Gy         affine y coordinate of base point\n * GySz       size of Gy in octets\n * cofactor   curve cofactor\n *\n * return curve id, from ecc_sets[] on success, negative on error\n */\nint wc_ecc_get_curve_id_from_params(int fieldSize,\n        const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,\n        const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,\n        const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)\n{\n    int idx;\n    int curveSz;\n\n    if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||\n        Gx == NULL || Gy == NULL)\n        return BAD_FUNC_ARG;\n\n    curveSz = (fieldSize + 1) / 8;    /* round up */\n\n    for (idx = 0; ecc_sets[idx].size != 0; idx++) {\n        if (curveSz == ecc_sets[idx].size) {\n            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,\n                            primeSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&\n                (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz,\n                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&\n                (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz,\n                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&\n                (wc_ecc_cmp_param(ecc_sets[idx].order, order,\n                                  orderSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&\n                (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz,\n                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&\n                (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz,\n                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&\n                (cofactor == ecc_sets[idx].cofactor)) {\n                    break;\n            }\n        }\n    }\n\n    if (ecc_sets[idx].size == 0)\n        return ECC_CURVE_INVALID;\n\n    return ecc_sets[idx].id;\n}\n\n/* Returns the curve id in ecc_sets[] that corresponds\n * to a given domain parameters pointer.\n *\n * dp   domain parameters pointer\n *\n * return curve id, from ecc_sets[] on success, negative on error\n */\nint wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp)\n{\n    int idx;\n\n    if (dp == NULL || dp->prime == NULL ||  dp->Af == NULL ||\n        dp->Bf == NULL || dp->order == NULL || dp->Gx == NULL || dp->Gy == NULL)\n        return BAD_FUNC_ARG;\n\n    for (idx = 0; ecc_sets[idx].size != 0; idx++) {\n        if (dp->size == ecc_sets[idx].size) {\n            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, (const byte*)dp->prime,\n                    (word32)XSTRLEN(dp->prime), WC_TYPE_HEX_STR) == MP_EQ) &&\n                (wc_ecc_cmp_param(ecc_sets[idx].Af, (const byte*)dp->Af,\n                    (word32)XSTRLEN(dp->Af),WC_TYPE_HEX_STR) == MP_EQ) &&\n                (wc_ecc_cmp_param(ecc_sets[idx].Bf, (const byte*)dp->Bf,\n                    (word32)XSTRLEN(dp->Bf),WC_TYPE_HEX_STR) == MP_EQ) &&\n                (wc_ecc_cmp_param(ecc_sets[idx].order, (const byte*)dp->order,\n                    (word32)XSTRLEN(dp->order),WC_TYPE_HEX_STR) == MP_EQ) &&\n                (wc_ecc_cmp_param(ecc_sets[idx].Gx, (const byte*)dp->Gx,\n                    (word32)XSTRLEN(dp->Gx),WC_TYPE_HEX_STR) == MP_EQ) &&\n                (wc_ecc_cmp_param(ecc_sets[idx].Gy, (const byte*)dp->Gy,\n                    (word32)XSTRLEN(dp->Gy),WC_TYPE_HEX_STR) == MP_EQ) &&\n                (dp->cofactor == ecc_sets[idx].cofactor)) {\n                    break;\n            }\n        }\n    }\n\n    if (ecc_sets[idx].size == 0)\n        return ECC_CURVE_INVALID;\n\n    return ecc_sets[idx].id;\n}\n\n/* Returns the curve id that corresponds to a given OID,\n * as listed in ecc_sets[] of ecc.c.\n *\n * oid   OID, from ecc_sets[].name in ecc.c\n * len   OID len, from ecc_sets[].name in ecc.c\n * return curve id, from ecc_sets[] on success, negative on error\n */\nint wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)\n{\n    int curve_idx;\n\n    if (oid == NULL)\n        return BAD_FUNC_ARG;\n\n    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {\n        if (ecc_sets[curve_idx].oid && ecc_sets[curve_idx].oidSz == len &&\n                              XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0) {\n            break;\n        }\n    }\n    if (ecc_sets[curve_idx].size == 0) {\n        WOLFSSL_MSG(\"ecc_set curve name not found\");\n        return ECC_CURVE_INVALID;\n    }\n\n    return ecc_sets[curve_idx].id;\n}\n\n/* Get curve parameters using curve index */\nconst ecc_set_type* wc_ecc_get_curve_params(int curve_idx)\n{\n    const ecc_set_type* ecc_set = NULL;\n\n    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {\n        ecc_set = &ecc_sets[curve_idx];\n    }\n    return ecc_set;\n}\n\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\nstatic WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)\n{\n   if (key == NULL || mp == NULL)\n      return BAD_FUNC_ARG;\n   if (*mp == NULL) {\n      *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);\n      if (*mp == NULL) {\n         return MEMORY_E;\n      }\n      XMEMSET(*mp, 0, sizeof(mp_int));\n   }\n   return 0;\n}\nstatic WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)\n{\n   if (key && mp && *mp) {\n      mp_clear(*mp);\n      XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);\n      *mp = NULL;\n   }\n}\n\nstatic int wc_ecc_alloc_async(ecc_key* key)\n{\n    int err = wc_ecc_alloc_mpint(key, &key->r);\n    if (err == 0)\n        err = wc_ecc_alloc_mpint(key, &key->s);\n    return err;\n}\n\nstatic void wc_ecc_free_async(ecc_key* key)\n{\n    wc_ecc_free_mpint(key, &key->r);\n    wc_ecc_free_mpint(key, &key->s);\n#ifdef HAVE_CAVIUM_V\n    wc_ecc_free_mpint(key, &key->e);\n    wc_ecc_free_mpint(key, &key->signK);\n#endif /* HAVE_CAVIUM_V */\n}\n#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */\n\n\n#ifdef HAVE_ECC_DHE\n/**\n  Create an ECC shared secret between two keys\n  private_key      The private ECC key (heap hint based off of private key)\n  public_key       The public key\n  out              [out] Destination of the shared secret\n                         Conforms to EC-DH from ANSI X9.63\n  outlen           [in/out] The max size and resulting size of the shared secret\n  return           MP_OKAY if successful\n*/\nint wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,\n                      word32* outlen)\n{\n   int err;\n#if defined(WOLFSSL_CRYPTOCELL)\n   CRYS_ECDH_TempData_t tempBuff;\n#endif\n   if (private_key == NULL || public_key == NULL || out == NULL ||\n                                                            outlen == NULL) {\n       return BAD_FUNC_ARG;\n   }\n\n#ifdef WOLF_CRYPTO_CB\n    if (private_key->devId != INVALID_DEVID) {\n        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);\n        if (err != CRYPTOCB_UNAVAILABLE)\n            return err;\n        /* fall-through when unavailable */\n    }\n#endif\n\n   /* type valid? */\n   if (private_key->type != ECC_PRIVATEKEY &&\n           private_key->type != ECC_PRIVATEKEY_ONLY) {\n      return ECC_BAD_ARG_E;\n   }\n\n   /* Verify domain params supplied */\n   if (wc_ecc_is_valid_idx(private_key->idx) == 0 ||\n       wc_ecc_is_valid_idx(public_key->idx)  == 0) {\n      return ECC_BAD_ARG_E;\n   }\n\n   /* Verify curve id matches */\n   if (private_key->dp->id != public_key->dp->id) {\n      return ECC_BAD_ARG_E;\n   }\n\n#ifdef WOLFSSL_ATECC508A\n   /* For SECP256R1 use hardware */\n   if (private_key->dp->id == ECC_SECP256R1) {\n       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);\n       *outlen = private_key->dp->size;\n   }\n   else {\n      err = NOT_COMPILED_IN;\n   }\n#elif defined(WOLFSSL_CRYPTOCELL)\n\n    /* generate a secret*/\n    err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,\n                            &private_key->ctx.privKey,\n                            out,\n                            outlen,\n                            &tempBuff);\n\n    if (err != SA_SILIB_RET_OK){\n        WOLFSSL_MSG(\"CRYS_ECDH_SVDP_DH for secret failed\");\n        return err;\n    }\n\n#else\n   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);\n#endif /* WOLFSSL_ATECC508A */\n\n   return err;\n}\n\n\n#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)\n\nstatic int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,\n                               byte* out, word32* outlen, ecc_curve_spec* curve)\n{\n    int err;\n#ifndef WOLFSSL_SP_MATH\n    ecc_point* result = NULL;\n    word32 x = 0;\n#endif\n    mp_int* k = &private_key->k;\n#ifdef HAVE_ECC_CDH\n    mp_int k_lcl;\n\n    /* if cofactor flag has been set */\n    if (private_key->flags & WC_ECC_FLAG_COFACTOR) {\n        mp_digit cofactor = (mp_digit)private_key->dp->cofactor;\n        /* only perform cofactor calc if not equal to 1 */\n        if (cofactor != 1) {\n            k = &k_lcl;\n            if (mp_init(k) != MP_OKAY)\n                return MEMORY_E;\n            /* multiply cofactor times private key \"k\" */\n            err = mp_mul_d(&private_key->k, cofactor, k);\n            if (err != MP_OKAY) {\n                mp_clear(k);\n                return err;\n            }\n        }\n    }\n#endif\n\n#ifdef WOLFSSL_HAVE_SP_ECC\n#ifndef WOLFSSL_SP_NO_256\n    if (private_key->idx != ECC_CUSTOM_IDX &&\n                               ecc_sets[private_key->idx].id == ECC_SECP256R1) {\n        err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);\n    }\n    else\n#endif\n#endif\n#ifdef WOLFSSL_SP_MATH\n    {\n        err = WC_KEY_SIZE_E;\n\n        (void)curve;\n    }\n#else\n    {\n        /* make new point */\n        result = wc_ecc_new_point_h(private_key->heap);\n        if (result == NULL) {\n#ifdef HAVE_ECC_CDH\n            if (k == &k_lcl)\n                mp_clear(k);\n#endif\n            return MEMORY_E;\n        }\n\n        err = wc_ecc_mulmod_ex(k, point, result, curve->Af, curve->prime, 1,\n                                                             private_key->heap);\n        if (err == MP_OKAY) {\n            x = mp_unsigned_bin_size(curve->prime);\n            if (*outlen < x || (int)x < mp_unsigned_bin_size(result->x)) {\n                err = BUFFER_E;\n            }\n        }\n\n        if (err == MP_OKAY) {\n            XMEMSET(out, 0, x);\n            err = mp_to_unsigned_bin(result->x,out +\n                                     (x - mp_unsigned_bin_size(result->x)));\n        }\n        *outlen = x;\n\n        wc_ecc_del_point_h(result, private_key->heap);\n    }\n#endif\n#ifdef HAVE_ECC_CDH\n    if (k == &k_lcl)\n        mp_clear(k);\n#endif\n\n    return err;\n}\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\nstatic int wc_ecc_shared_secret_gen_async(ecc_key* private_key,\n            ecc_point* point, byte* out, word32 *outlen,\n            ecc_curve_spec* curve)\n{\n    int err;\n\n#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)\n#ifdef HAVE_CAVIUM_V\n    /* verify the curve is supported by hardware */\n    if (NitroxEccIsCurveSupported(private_key))\n#endif\n    {\n        word32 keySz = private_key->dp->size;\n\n        /* sync public key x/y */\n        err = wc_mp_to_bigint_sz(&private_key->k, &private_key->k.raw, keySz);\n        if (err == MP_OKAY)\n            err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);\n        if (err == MP_OKAY)\n            err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);\n    #ifdef HAVE_CAVIUM_V\n        /* allocate buffer for output */\n        if (err == MP_OKAY)\n            err = wc_ecc_alloc_mpint(private_key, &private_key->e);\n        if (err == MP_OKAY)\n            err = wc_bigint_alloc(&private_key->e->raw,\n                NitroxEccGetSize(private_key)*2);\n        if (err == MP_OKAY)\n            err = NitroxEcdh(private_key,\n                &private_key->k.raw, &point->x->raw, &point->y->raw,\n                private_key->e->raw.buf, &private_key->e->raw.len,\n                &curve->prime->raw);\n    #else\n        if (err == MP_OKAY)\n            err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);\n        if (err == MP_OKAY)\n            err = IntelQaEcdh(&private_key->asyncDev,\n                &private_key->k.raw, &point->x->raw, &point->y->raw,\n                out, outlen,\n                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,\n                private_key->dp->cofactor);\n    #endif\n        return err;\n    }\n#elif defined(WOLFSSL_ASYNC_CRYPT_TEST)\n    if (wc_AsyncTestInit(&private_key->asyncDev, ASYNC_TEST_ECC_SHARED_SEC)) {\n        WC_ASYNC_TEST* testDev = &private_key->asyncDev.test;\n        testDev->eccSharedSec.private_key = private_key;\n        testDev->eccSharedSec.public_point = point;\n        testDev->eccSharedSec.out = out;\n        testDev->eccSharedSec.outLen = outlen;\n        return WC_PENDING_E;\n    }\n#endif\n\n    /* use sync in other cases */\n    err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen, curve);\n\n    return err;\n}\n#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */\n\nint wc_ecc_shared_secret_gen(ecc_key* private_key, ecc_point* point,\n                                                    byte* out, word32 *outlen)\n{\n    int err;\n    DECLARE_CURVE_SPECS(curve, 2);\n\n    if (private_key == NULL || point == NULL || out == NULL ||\n                                                            outlen == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    ALLOC_CURVE_SPECS(2);\n\n    /* load curve info */\n    err = wc_ecc_curve_load(private_key->dp, &curve,\n        (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));\n    if (err != MP_OKAY) {\n        FREE_CURVE_SPECS();\n        return err;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n    if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {\n        err = wc_ecc_shared_secret_gen_async(private_key, point,\n            out, outlen, curve);\n    }\n    else\n#endif\n    {\n        err = wc_ecc_shared_secret_gen_sync(private_key, point,\n            out, outlen, curve);\n    }\n\n    wc_ecc_curve_free(curve);\n    FREE_CURVE_SPECS();\n\n    return err;\n}\n\n/**\n Create an ECC shared secret between private key and public point\n private_key      The private ECC key (heap hint based on private key)\n point            The point to use (public key)\n out              [out] Destination of the shared secret\n                        Conforms to EC-DH from ANSI X9.63\n outlen           [in/out] The max size and resulting size of the shared secret\n return           MP_OKAY if successful\n*/\nint wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,\n                            byte* out, word32 *outlen)\n{\n    int err;\n\n    if (private_key == NULL || point == NULL || out == NULL ||\n                                                            outlen == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* type valid? */\n    if (private_key->type != ECC_PRIVATEKEY &&\n            private_key->type != ECC_PRIVATEKEY_ONLY) {\n        return ECC_BAD_ARG_E;\n    }\n\n    /* Verify domain params supplied */\n    if (wc_ecc_is_valid_idx(private_key->idx) == 0)\n        return ECC_BAD_ARG_E;\n\n    switch(private_key->state) {\n        case ECC_STATE_NONE:\n        case ECC_STATE_SHARED_SEC_GEN:\n            private_key->state = ECC_STATE_SHARED_SEC_GEN;\n\n            err = wc_ecc_shared_secret_gen(private_key, point, out, outlen);\n            if (err < 0) {\n                break;\n            }\n            FALL_THROUGH;\n\n        case ECC_STATE_SHARED_SEC_RES:\n            private_key->state = ECC_STATE_SHARED_SEC_RES;\n        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {\n            #ifdef HAVE_CAVIUM_V\n                /* verify the curve is supported by hardware */\n                if (NitroxEccIsCurveSupported(private_key)) {\n                    /* copy output */\n                    *outlen = private_key->dp->size;\n                    XMEMCPY(out, private_key->e->raw.buf, *outlen);\n                }\n            #endif /* HAVE_CAVIUM_V */\n            }\n        #endif /* WOLFSSL_ASYNC_CRYPT */\n            err = 0;\n            break;\n\n        default:\n            err = BAD_STATE_E;\n    } /* switch */\n\n    /* if async pending then return and skip done cleanup below */\n    if (err == WC_PENDING_E) {\n        private_key->state++;\n        return err;\n    }\n\n    /* cleanup */\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n    wc_ecc_free_async(private_key);\n#endif\n    private_key->state = ECC_STATE_NONE;\n\n    return err;\n}\n#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */\n#endif /* HAVE_ECC_DHE */\n\n\n#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)\n/* return 1 if point is at infinity, 0 if not, < 0 on error */\nint wc_ecc_point_is_at_infinity(ecc_point* p)\n{\n    if (p == NULL)\n        return BAD_FUNC_ARG;\n\n    if (get_digit_count(p->x) == 0 && get_digit_count(p->y) == 0)\n        return 1;\n\n    return 0;\n}\n\n/* generate random and ensure its greater than 0 and less than order */\nint wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)\n{\n#ifndef WC_NO_RNG\n    int err;\n    byte buf[ECC_MAXSIZE_GEN];\n\n    /*generate 8 extra bytes to mitigate bias from the modulo operation below*/\n    /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/\n    size += 8;\n\n    /* make up random string */\n    err = wc_RNG_GenerateBlock(rng, buf, size);\n\n    /* load random buffer data into k */\n    if (err == 0)\n        err = mp_read_unsigned_bin(k, (byte*)buf, size);\n\n    /* the key should be smaller than the order of base point */\n    if (err == MP_OKAY) {\n        if (mp_cmp(k, order) != MP_LT) {\n            err = mp_mod(k, order, k);\n        }\n    }\n\n    /* quick sanity check to make sure we're not dealing with a 0 key */\n    if (err == MP_OKAY) {\n        if (mp_iszero(k) == MP_YES)\n          err = MP_ZERO_E;\n    }\n\n    ForceZero(buf, ECC_MAXSIZE);\n\n    return err;\n#else\n    (void)rng;\n    (void)size;\n    (void)k;\n    (void)order;\n    return NOT_COMPILED_IN;\n#endif /* !WC_NO_RNG */\n}\n#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */\n\nstatic WC_INLINE void wc_ecc_reset(ecc_key* key)\n{\n    /* make sure required key variables are reset */\n    key->state = ECC_STATE_NONE;\n}\n\n\n/* create the public ECC key from a private key\n *\n * key     an initialized private key to generate public part from\n * curveIn [in]curve for key, can be NULL\n * pubOut  [out]ecc_point holding the public key, if NULL then public key part\n *         is cached in key instead.\n *\n * Note this function is local to the file because of the argument type\n *      ecc_curve_spec. Having this argument allows for not having to load the\n *      curve type multiple times when generating a key with wc_ecc_make_key().\n *\n * returns MP_OKAY on success\n */\nstatic int wc_ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn,\n        ecc_point* pubOut)\n{\n    int err = MP_OKAY;\n#ifndef WOLFSSL_ATECC508A\n#ifndef WOLFSSL_SP_MATH\n    ecc_point* base = NULL;\n#endif\n    ecc_point* pub;\n    DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);\n#endif /* !WOLFSSL_ATECC508A */\n\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifndef WOLFSSL_ATECC508A\n\n    /* if ecc_point passed in then use it as output for public key point */\n    if (pubOut != NULL) {\n        pub = pubOut;\n    }\n    else {\n        /* caching public key making it a ECC_PRIVATEKEY instead of\n           ECC_PRIVATEKEY_ONLY */\n        pub = &key->pubkey;\n        key->type = ECC_PRIVATEKEY_ONLY;\n    }\n\n    /* avoid loading the curve unless it is not passed in */\n    if (curveIn != NULL) {\n        curve = curveIn;\n    }\n    else {\n        ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);\n\n        /* load curve info */\n        if (err == MP_OKAY)\n            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);\n    }\n\n    if (err == MP_OKAY) {\n    #ifndef ALT_ECC_SIZE\n        err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL);\n    #else\n        pub->x = (mp_int*)&pub->xyz[0];\n        pub->y = (mp_int*)&pub->xyz[1];\n        pub->z = (mp_int*)&pub->xyz[2];\n        alt_fp_init(pub->x);\n        alt_fp_init(pub->y);\n        alt_fp_init(pub->z);\n    #endif\n    }\n\n\n#ifdef WOLFSSL_HAVE_SP_ECC\n#ifndef WOLFSSL_SP_NO_256\n    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {\n        if (err == MP_OKAY)\n            err = sp_ecc_mulmod_base_256(&key->k, pub, 1, key->heap);\n    }\n    else\n#endif\n#endif\n#ifdef WOLFSSL_SP_MATH\n        err = WC_KEY_SIZE_E;\n#else\n    {\n        if (err == MP_OKAY) {\n            base = wc_ecc_new_point_h(key->heap);\n            if (base == NULL)\n                err = MEMORY_E;\n        }\n        /* read in the x/y for this key */\n        if (err == MP_OKAY)\n            err = mp_copy(curve->Gx, base->x);\n        if (err == MP_OKAY)\n            err = mp_copy(curve->Gy, base->y);\n        if (err == MP_OKAY)\n            err = mp_set(base->z, 1);\n\n        /* make the public key */\n        if (err == MP_OKAY) {\n            err = wc_ecc_mulmod_ex(&key->k, base, pub, curve->Af, curve->prime,\n                                                                  1, key->heap);\n            if (err == MP_MEM) {\n               err = MEMORY_E;\n            }\n        }\n\n        wc_ecc_del_point_h(base, key->heap);\n    }\n#endif\n\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    /* validate the public key, order * pubkey = point at infinity */\n    if (err == MP_OKAY)\n        err = ecc_check_pubkey_order(key, pub, curve->Af, curve->prime,\n                curve->order);\n#endif /* WOLFSSL_VALIDATE_KEYGEN */\n\n    if (err != MP_OKAY) {\n        /* clean up if failed */\n    #ifndef ALT_ECC_SIZE\n        mp_clear(pub->x);\n        mp_clear(pub->y);\n        mp_clear(pub->z);\n    #endif\n    }\n\n    /* free up local curve */\n    if (curveIn == NULL) {\n        wc_ecc_curve_free(curve);\n        FREE_CURVE_SPECS();\n    }\n\n#else\n    (void)curveIn;\n    err = NOT_COMPILED_IN;\n#endif /* WOLFSSL_ATECC508A */\n\n    /* change key state if public part is cached */\n    if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {\n        key->type = ECC_PRIVATEKEY;\n    }\n\n    return err;\n}\n\n\n/* create the public ECC key from a private key\n *\n * key     an initialized private key to generate public part from\n * pubOut  [out]ecc_point holding the public key, if NULL then public key part\n *         is cached in key instead.\n *\n *\n * returns MP_OKAY on success\n */\nint wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)\n{\n    WOLFSSL_ENTER(\"wc_ecc_make_pub\");\n\n    return wc_ecc_make_pub_ex(key, NULL, pubOut);\n}\n\n\nWOLFSSL_ABI\nint wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)\n{\n    int err;\n#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)\n#ifndef WOLFSSL_SP_MATH\n    DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);\n#endif\n#endif /* !WOLFSSL_ATECC508A */\n#if defined(WOLFSSL_CRYPTOCELL)\n    const CRYS_ECPKI_Domain_t*  pDomain;\n    CRYS_ECPKI_KG_TempData_t    tempBuff;\n    CRYS_ECPKI_KG_FipsContext_t fipsCtx;\n    byte ucompressed_key[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];\n    word32 raw_size = 0;\n#endif\n    if (key == NULL || rng == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* make sure required variables are reset */\n    wc_ecc_reset(key);\n\n    err = wc_ecc_set_curve(key, keysize, curve_id);\n    if (err != 0) {\n        return err;\n    }\n\n#ifdef WOLF_CRYPTO_CB\n    if (key->devId != INVALID_DEVID) {\n        err = wc_CryptoCb_MakeEccKey(rng, keysize, key, curve_id);\n        if (err != CRYPTOCB_UNAVAILABLE)\n            return err;\n        /* fall-through when unavailable */\n    }\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {\n    #ifdef HAVE_CAVIUM\n        /* TODO: Not implemented */\n    #elif defined(HAVE_INTEL_QA)\n        /* TODO: Not implemented */\n    #else\n        if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_MAKE)) {\n            WC_ASYNC_TEST* testDev = &key->asyncDev.test;\n            testDev->eccMake.rng = rng;\n            testDev->eccMake.key = key;\n            testDev->eccMake.size = keysize;\n            testDev->eccMake.curve_id = curve_id;\n            return WC_PENDING_E;\n        }\n    #endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */\n\n#ifdef WOLFSSL_ATECC508A\n   if (key->dp->id == ECC_SECP256R1) {\n       key->type = ECC_PRIVATEKEY;\n       key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);\n       err = atmel_ecc_create_key(key->slot, key->pubkey_raw);\n\n       /* populate key->pubkey */\n       if (err == 0\n       #ifdef ALT_ECC_SIZE\n          && key->pubkey.x\n       #endif\n       ) {\n           err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,\n                                      ECC_MAX_CRYPTO_HW_SIZE);\n       }\n       if (err == 0\n       #ifdef ALT_ECC_SIZE\n          && key->pubkey.y\n       #endif\n       ) {\n           err = mp_read_unsigned_bin(key->pubkey.y,\n                                      key->pubkey_raw + ECC_MAX_CRYPTO_HW_SIZE,\n                                      ECC_MAX_CRYPTO_HW_SIZE);\n       }\n   }\n   else {\n      err = NOT_COMPILED_IN;\n   }\n#elif defined(WOLFSSL_CRYPTOCELL)\n\n    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(curve_id));\n    raw_size = (word32)(key->dp->size)*2 + 1;\n\n    /* generate first key pair */\n    err = CRYS_ECPKI_GenKeyPair(&wc_rndState,\n                                wc_rndGenVectFunc,\n                                pDomain,\n                                &key->ctx.privKey,\n                                &key->ctx.pubKey,\n                                &tempBuff,\n                                &fipsCtx);\n\n    if (err != SA_SILIB_RET_OK){\n        WOLFSSL_MSG(\"CRYS_ECPKI_GenKeyPair for key pair failed\");\n        return err;\n    }\n    key->type = ECC_PRIVATEKEY;\n\n    err = CRYS_ECPKI_ExportPublKey(&key->ctx.pubKey,\n                                   CRYS_EC_PointUncompressed,\n                                   &ucompressed_key[0],\n                                   &raw_size);\n\n    if (err == SA_SILIB_RET_OK && key->pubkey.x && key->pubkey.y) {\n        err = mp_read_unsigned_bin(key->pubkey.x,\n                                   &ucompressed_key[1], key->dp->size);\n        if (err == MP_OKAY) {\n            err = mp_read_unsigned_bin(key->pubkey.y,\n                            &ucompressed_key[1+key->dp->size],key->dp->size);\n        }\n    }\n    raw_size = key->dp->size;\n    if (err == MP_OKAY) {\n        err = CRYS_ECPKI_ExportPrivKey(&key->ctx.privKey,\n                                       ucompressed_key,\n                                       &raw_size);\n    }\n\n    if (err == SA_SILIB_RET_OK) {\n        err = mp_read_unsigned_bin(&key->k, ucompressed_key, raw_size);\n    }\n\n#else\n\n#ifdef WOLFSSL_HAVE_SP_ECC\n#ifndef WOLFSSL_SP_NO_256\n    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {\n        err = sp_ecc_make_key_256(rng, &key->k, &key->pubkey, key->heap);\n        if (err == MP_OKAY)\n            key->type = ECC_PRIVATEKEY;\n    }\n    else\n#endif\n#endif /* WOLFSSL_HAVE_SP_ECC */\n\n   { /* software key gen */\n#ifdef WOLFSSL_SP_MATH\n        err = WC_KEY_SIZE_E;\n#else\n        ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);\n\n        /* setup the key variables */\n        err = mp_init(&key->k);\n\n        /* load curve info */\n        if (err == MP_OKAY)\n            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);\n\n        /* generate k */\n        if (err == MP_OKAY)\n            err = wc_ecc_gen_k(rng, key->dp->size, &key->k, curve->order);\n\n        /* generate public key from k */\n        if (err == MP_OKAY)\n            err = wc_ecc_make_pub_ex(key, curve, NULL);\n\n        if (err == MP_OKAY)\n            key->type = ECC_PRIVATEKEY;\n\n        /* cleanup these on failure case only */\n        if (err != MP_OKAY) {\n            /* clean up */\n            mp_forcezero(&key->k);\n        }\n\n        /* cleanup allocations */\n        wc_ecc_curve_free(curve);\n        FREE_CURVE_SPECS();\n#endif /* WOLFSSL_SP_MATH */\n    }\n\n#ifdef HAVE_WOLF_BIGINT\n    if (err == MP_OKAY)\n         err = wc_mp_to_bigint(&key->k, &key->k.raw);\n    if (err == MP_OKAY)\n         err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw);\n    if (err == MP_OKAY)\n         err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw);\n    if (err == MP_OKAY)\n         err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw);\n#endif\n\n#endif /* WOLFSSL_ATECC508A */\n\n    return err;\n}\n\n#ifdef ECC_DUMP_OID\n/* Optional dump of encoded OID for adding new curves */\nstatic int mOidDumpDone;\nstatic void wc_ecc_dump_oids(void)\n{\n    int x;\n\n    if (mOidDumpDone) {\n        return;\n    }\n\n    /* find matching OID sum (based on encoded value) */\n    for (x = 0; ecc_sets[x].size != 0; x++) {\n        int i;\n        byte* oid;\n        word32 oidSz, sum = 0;\n\n        printf(\"ECC %s (%d):\\n\", ecc_sets[x].name, x);\n\n    #ifdef HAVE_OID_ENCODING\n        byte oidEnc[ECC_MAX_OID_LEN];\n\n        oid = oidEnc;\n        oidSz = ECC_MAX_OID_LEN;\n\n        printf(\"OID: \");\n        for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {\n            printf(\"%d.\", ecc_sets[x].oid[i]);\n        }\n        printf(\"\\n\");\n\n        EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);\n    #else\n        oid = (byte*)ecc_sets[x].oid;\n        oidSz = ecc_sets[x].oidSz;\n    #endif\n\n        printf(\"OID Encoded: \");\n        for (i = 0; i < (int)oidSz; i++) {\n            printf(\"0x%02X,\", oid[i]);\n        }\n        printf(\"\\n\");\n\n        for (i = 0; i < (int)oidSz; i++) {\n            sum += oid[i];\n        }\n        printf(\"Sum: %d\\n\", sum);\n\n        /* validate sum */\n        if (ecc_sets[x].oidSum != sum) {\n            printf(\"  Sum %d Not Valid!\\n\", ecc_sets[x].oidSum);\n        }\n    }\n    mOidDumpDone = 1;\n}\n#endif /* ECC_DUMP_OID */\n\n\nWOLFSSL_ABI\necc_key* wc_ecc_key_new(void* heap)\n{\n    ecc_key* key;\n\n    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);\n    if (key) {\n        if (wc_ecc_init_ex(key, heap, INVALID_DEVID) != 0) {\n            XFREE(key, heap, DYNAMIC_TYPE_ECC);\n            key = NULL;\n        }\n    }\n\n    return key;\n}\n\n\nWOLFSSL_ABI\nvoid wc_ecc_key_free(ecc_key* key)\n{\n    if (key) {\n        void* heap = key->heap;\n\n        wc_ecc_free(key);\n        ForceZero(key, sizeof(ecc_key));\n        XFREE(key, heap, DYNAMIC_TYPE_ECC);\n        (void)heap;\n    }\n}\n\n\n/**\n Make a new ECC key\n rng          An active RNG state\n keysize      The keysize for the new key (in octets from 20 to 65 bytes)\n key          [out] Destination of the newly created key\n return       MP_OKAY if successful,\n upon error all allocated memory will be freed\n */\nint wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)\n{\n    return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);\n}\n\n/* Setup dynamic pointers if using normal math for proper freeing */\nWOLFSSL_ABI\nint wc_ecc_init_ex(ecc_key* key, void* heap, int devId)\n{\n    int ret = 0;\n\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef ECC_DUMP_OID\n    wc_ecc_dump_oids();\n#endif\n\n    XMEMSET(key, 0, sizeof(ecc_key));\n    key->state = ECC_STATE_NONE;\n\n#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)\n    key->devId = devId;\n#else\n    (void)devId;\n#endif\n\n#ifdef WOLFSSL_ATECC508A\n    key->slot = ATECC_INVALID_SLOT;\n#else\n#ifdef ALT_ECC_SIZE\n    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];\n    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];\n    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];\n    alt_fp_init(key->pubkey.x);\n    alt_fp_init(key->pubkey.y);\n    alt_fp_init(key->pubkey.z);\n    ret = mp_init(&key->k);\n    if (ret != MP_OKAY) {\n        return MEMORY_E;\n    }\n#else\n    ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,\n                                                                    NULL, NULL);\n    if (ret != MP_OKAY) {\n        return MEMORY_E;\n    }\n#endif /* ALT_ECC_SIZE */\n#endif /* WOLFSSL_ATECC508A */\n\n#ifdef WOLFSSL_HEAP_TEST\n    key->heap = (void*)WOLFSSL_HEAP_TEST;\n#else\n    key->heap = heap;\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n    /* handle as async */\n    ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,\n                                                            key->heap, devId);\n#endif\n\n    return ret;\n}\n\nint wc_ecc_init(ecc_key* key)\n{\n    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);\n}\n\n#ifdef HAVE_PKCS11\nint wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,\n                   int devId)\n{\n    int ret = 0;\n\n    if (key == NULL)\n        ret = BAD_FUNC_ARG;\n    if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN))\n        ret = BUFFER_E;\n\n    if (ret == 0)\n        ret = wc_ecc_init_ex(key, heap, devId);\n\n    if (ret == 0 && id != NULL && len != 0) {\n        XMEMCPY(key->id, id, len);\n        key->idLen = len;\n    }\n\n    return ret;\n}\n#endif\n\nint wc_ecc_set_flags(ecc_key* key, word32 flags)\n{\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    key->flags |= flags;\n    return 0;\n}\n\n\nstatic int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp)\n{\n    int err;\n    word32 orderBits;\n    DECLARE_CURVE_SPECS(curve, 1);\n\n    ALLOC_CURVE_SPECS(1);\n    err = wc_ecc_curve_load(dp, &curve, ECC_CURVE_FIELD_ORDER);\n    if (err != 0) {\n       FREE_CURVE_SPECS();\n       return err;\n    }\n    orderBits = mp_count_bits(curve->order);\n\n    wc_ecc_curve_free(curve);\n    FREE_CURVE_SPECS();\n    return (int)orderBits;\n}\n\n#ifdef HAVE_ECC_SIGN\n\n#ifndef NO_ASN\n\n#if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) || \\\n    defined(WOLFSSL_CRYPTOCELL)\nstatic int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,\n    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,\n    ecc_key* key)\n{\n    int err;\n#ifdef PLUTON_CRYPTO_ECC\n    if (key->devId != INVALID_DEVID) /* use hardware */\n#endif\n#if defined(WOLFSSL_CRYPTOCELL)\n    CRYS_ECDSA_SignUserContext_t sigCtxTemp;\n    word32 raw_sig_size = *outlen;\n    word32 msgLenInBytes = inlen;\n    CRYS_ECPKI_HASH_OpMode_t hash_mode;\n#endif\n    {\n        word32 keysize = (word32)key->dp->size;\n        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);\n\n        /* Check args */\n        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {\n            return ECC_BAD_ARG_E;\n        }\n\n        /* if the input is larger than curve order, we must truncate */\n        if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {\n           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;\n        }\n\n    #if defined(WOLFSSL_ATECC508A)\n        key->slot = atmel_ecc_alloc(ATMEL_SLOT_DEVICE);\n        if (key->slot == ATECC_INVALID_SLOT) {\n            return ECC_BAD_ARG_E;\n        }\n\n        /* Sign: Result is 32-bytes of R then 32-bytes of S */\n        err = atmel_ecc_sign(key->slot, in, out);\n        if (err != 0) {\n           return err;\n        }\n    #elif defined(PLUTON_CRYPTO_ECC)\n        {\n            /* perform ECC sign */\n            word32 raw_sig_size = *outlen;\n            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);\n            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){\n               return BAD_COND_E;\n            }\n        }\n    #elif defined(WOLFSSL_CRYPTOCELL)\n\n        hash_mode = cc310_hashModeECC(msgLenInBytes);\n        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {\n            hash_mode = cc310_hashModeECC(keysize);\n            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;\n        }\n\n        /* truncate if hash is longer than key size */\n        if (msgLenInBytes > keysize) {\n            msgLenInBytes = keysize;\n        }\n\n        /* create signature from an input buffer using a private key*/\n        err = CRYS_ECDSA_Sign(&wc_rndState,\n                               wc_rndGenVectFunc,\n                               &sigCtxTemp,\n                               &key->ctx.privKey,\n                               hash_mode,\n                               (byte*)in,\n                               msgLenInBytes,\n                               out,\n                               &raw_sig_size);\n\n        if (err != SA_SILIB_RET_OK){\n            WOLFSSL_MSG(\"CRYS_ECDSA_Sign failed\");\n            return err;\n        }\n    #endif\n\n        /* Load R and S */\n        err = mp_read_unsigned_bin(r, &out[0], keysize);\n        if (err != MP_OKAY) {\n            return err;\n        }\n        err = mp_read_unsigned_bin(s, &out[keysize], keysize);\n        if (err != MP_OKAY) {\n            return err;\n        }\n\n        /* Check for zeros */\n        if (mp_iszero(r) || mp_iszero(s)) {\n            return MP_ZERO_E;\n        }\n    }\n#ifdef PLUTON_CRYPTO_ECC\n    else {\n        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);\n    }\n#endif\n    (void)rng;\n\n    return err;\n}\n#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC || WOLFSSL_CRYPTOCELL */\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\nstatic int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,\n    word32 *outlen, WC_RNG* rng, ecc_key* key)\n{\n    int err;\n    mp_int *r = NULL, *s = NULL;\n\n    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||\n                                                                rng == NULL) {\n        return ECC_BAD_ARG_E;\n    }\n\n    err = wc_ecc_alloc_async(key);\n    if (err != 0) {\n        return err;\n    }\n    r = key->r;\n    s = key->s;\n\n    switch(key->state) {\n        case ECC_STATE_NONE:\n        case ECC_STATE_SIGN_DO:\n            key->state = ECC_STATE_SIGN_DO;\n\n            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){\n                break;\n            }\n\n            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);\n            if (err < 0) {\n                break;\n            }\n\n            FALL_THROUGH;\n\n        case ECC_STATE_SIGN_ENCODE:\n            key->state = ECC_STATE_SIGN_ENCODE;\n\n            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {\n                #ifdef HAVE_CAVIUM_V\n                    /* Nitrox requires r and s in sep buffer, so split it */\n                    NitroxEccRsSplit(key, &r->raw, &s->raw);\n                #endif\n                #ifndef WOLFSSL_ASYNC_CRYPT_TEST\n                    /* only do this if not simulator, since it overwrites result */\n                    wc_bigint_to_mp(&r->raw, r);\n                    wc_bigint_to_mp(&s->raw, s);\n                #endif\n            }\n\n            /* encoded with DSA header */\n            err = StoreECC_DSA_Sig(out, outlen, r, s);\n\n            /* done with R/S */\n            mp_clear(r);\n            mp_clear(s);\n            break;\n\n        default:\n            err = BAD_STATE_E;\n            break;\n    }\n\n    /* if async pending then return and skip done cleanup below */\n    if (err == WC_PENDING_E) {\n        key->state++;\n        return err;\n    }\n\n    /* cleanup */\n    wc_ecc_free_async(key);\n    key->state = ECC_STATE_NONE;\n\n    return err;\n}\n#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */\n\n/**\n Sign a message digest\n in        The message digest to sign\n inlen     The length of the digest\n out       [out] The destination for the signature\n outlen    [in/out] The max size and resulting size of the signature\n key       A private ECC key\n return    MP_OKAY if successful\n */\nWOLFSSL_ABI\nint wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,\n                     WC_RNG* rng, ecc_key* key)\n{\n    int err;\n#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int *r = NULL, *s = NULL;\n#else\n    mp_int r[1], s[1];\n#endif\n#endif\n\n    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||\n                                                                rng == NULL) {\n        return ECC_BAD_ARG_E;\n    }\n\n#ifdef WOLF_CRYPTO_CB\n    if (key->devId != INVALID_DEVID) {\n        err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key);\n        if (err != CRYPTOCB_UNAVAILABLE)\n            return err;\n        /* fall-through when unavailable */\n    }\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n    /* handle async cases */\n    err = wc_ecc_sign_hash_async(in, inlen, out, outlen, rng, key);\n#else\n\n#ifdef WOLFSSL_SMALL_STACK\n    r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);\n    if (r == NULL)\n        return MEMORY_E;\n    s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);\n    if (s == NULL) {\n        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);\n        return MEMORY_E;\n    }\n#endif\n    XMEMSET(r, 0, sizeof(mp_int));\n    XMEMSET(s, 0, sizeof(mp_int));\n\n    if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(s, key->heap, DYNAMIC_TYPE_ECC);\n        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);\n    #endif\n        return err;\n    }\n\n/* hardware crypto */\n#if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL)\n    err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);\n#else\n    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);\n#endif\n    if (err < 0) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(s, key->heap, DYNAMIC_TYPE_ECC);\n        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);\n    #endif\n        return err;\n    }\n\n    /* encoded with DSA header */\n    err = StoreECC_DSA_Sig(out, outlen, r, s);\n\n    /* cleanup */\n    mp_clear(r);\n    mp_clear(s);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(s, key->heap, DYNAMIC_TYPE_ECC);\n    XFREE(r, key->heap, DYNAMIC_TYPE_ECC);\n#endif\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    return err;\n}\n#endif /* !NO_ASN */\n\n#if defined(WOLFSSL_STM32_PKA)\nint wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,\n                     ecc_key* key, mp_int *r, mp_int *s)\n{\n    return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);\n}\n#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)\n/**\n  Sign a message digest\n  in        The message digest to sign\n  inlen     The length of the digest\n  key       A private ECC key\n  r         [out] The destination for r component of the signature\n  s         [out] The destination for s component of the signature\n  return    MP_OKAY if successful\n*/\nint wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,\n                     ecc_key* key, mp_int *r, mp_int *s)\n{\n   int    err = 0;\n#ifndef WOLFSSL_SP_MATH\n   mp_int* e;\n#if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)) && \\\n                                                   !defined(WOLFSSL_SMALL_STACK)\n   mp_int  e_lcl;\n#endif\n#ifndef WOLFSSL_ECDSA_SET_K\n   DECLARE_CURVE_SPECS(curve, 1);\n#else\n   DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);\n#endif\n#endif /* !WOLFSSL_SP_MATH */\n\n   if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {\n       return ECC_BAD_ARG_E;\n   }\n\n   /* is this a private key? */\n   if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {\n      return ECC_BAD_ARG_E;\n   }\n\n   /* is the IDX valid ?  */\n   if (wc_ecc_is_valid_idx(key->idx) != 1) {\n      return ECC_BAD_ARG_E;\n   }\n\n#ifdef WOLFSSL_SP_MATH\n    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {\n    #ifndef WOLFSSL_ECDSA_SET_K\n        return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL, key->heap);\n    #else\n        return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->sign_k,\n                                                                     key->heap);\n    #endif\n    }\n    else {\n        return WC_KEY_SIZE_E;\n    }\n#else\n#ifdef WOLFSSL_HAVE_SP_ECC\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n    if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC)\n    #endif\n    {\n    #ifndef WOLFSSL_SP_NO_256\n        if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1)\n        #ifndef WOLFSSL_ECDSA_SET_K\n            return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL,\n                                                                     key->heap);\n        #else\n            return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->sign_k,\n                                                                     key->heap);\n        #endif\n    #endif\n    }\n#endif /* WOLFSSL_HAVE_SP_ECC */\n\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \\\n       defined(WOLFSSL_ASYNC_CRYPT_TEST)\n    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {\n        if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_SIGN)) {\n            WC_ASYNC_TEST* testDev = &key->asyncDev.test;\n            testDev->eccSign.in = in;\n            testDev->eccSign.inSz = inlen;\n            testDev->eccSign.rng = rng;\n            testDev->eccSign.key = key;\n            testDev->eccSign.r = r;\n            testDev->eccSign.s = s;\n            return WC_PENDING_E;\n        }\n    }\n#endif\n\n   ALLOC_CURVE_SPECS(1);\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)\n   err = wc_ecc_alloc_mpint(key, &key->e);\n   if (err != 0) {\n      FREE_CURVE_SPECS();\n      return err;\n   }\n   e = key->e;\n#elif !defined(WOLFSSL_SMALL_STACK)\n   e = &e_lcl;\n#else\n   e = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);\n   if (e == NULL) {\n      FREE_CURVE_SPECS();\n      return MEMORY_E;\n   }\n#endif\n\n   /* get the hash and load it as a bignum into 'e' */\n   /* init the bignums */\n   if ((err = mp_init(e)) != MP_OKAY) {\n   #ifdef WOLFSSL_SMALL_STACK\n      XFREE(e, key->heap, DYNAMIC_TYPE_ECC);\n   #endif\n      FREE_CURVE_SPECS();\n      return err;\n   }\n\n   /* load curve info */\n#ifndef WOLFSSL_ECDSA_SET_K\n   err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);\n#else\n   err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);\n#endif\n\n   /* load digest into e */\n   if (err == MP_OKAY) {\n       /* we may need to truncate if hash is longer than key size */\n       word32 orderBits = mp_count_bits(curve->order);\n\n       /* truncate down to byte size, may be all that's needed */\n       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)\n           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;\n       err = mp_read_unsigned_bin(e, (byte*)in, inlen);\n\n       /* may still need bit truncation too */\n       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)\n           mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));\n   }\n\n   /* make up a key and export the public copy */\n   if (err == MP_OKAY) {\n       int      loop_check = 0;\n   #ifdef WOLFSSL_SMALL_STACK\n       ecc_key* pubkey = NULL;\n   #else\n       ecc_key  pubkey[1];\n   #endif\n\n   #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n        if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {\n        #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)\n        #ifdef HAVE_CAVIUM_V\n            if (NitroxEccIsCurveSupported(key))\n        #endif\n            {\n               word32 keySz = key->dp->size;\n               mp_int* k;\n            #ifdef HAVE_CAVIUM_V\n               err = wc_ecc_alloc_mpint(key, &key->signK);\n               if (err != 0)\n                  return err;\n               k = key->signK;\n            #else\n               mp_int k_lcl;\n               k = &k_lcl;\n            #endif\n\n               err = mp_init(k);\n\n                /* make sure r and s are allocated */\n           #ifdef HAVE_CAVIUM_V\n               /* Nitrox V needs single buffer for R and S */\n               if (err == MP_OKAY)\n                   err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);\n               /* Nitrox V only needs Prime and Order */\n               if (err == MP_OKAY)\n                   err = wc_ecc_curve_load(key->dp, &curve,\n                        (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));\n           #else\n               if (err == MP_OKAY)\n                   err = wc_bigint_alloc(&key->r->raw, key->dp->size);\n               if (err == MP_OKAY)\n                   err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);\n           #endif\n               if (err == MP_OKAY)\n                   err = wc_bigint_alloc(&key->s->raw, key->dp->size);\n\n               /* load e and k */\n               if (err == MP_OKAY)\n                   err = wc_mp_to_bigint_sz(e, &e->raw, keySz);\n               if (err == MP_OKAY)\n                   err = wc_mp_to_bigint_sz(&key->k, &key->k.raw, keySz);\n               if (err == MP_OKAY)\n                   err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);\n               if (err == MP_OKAY)\n                   err = wc_mp_to_bigint_sz(k, &k->raw, keySz);\n\n           #ifdef HAVE_CAVIUM_V\n               if (err == MP_OKAY)\n                   err = NitroxEcdsaSign(key, &e->raw, &key->k.raw, &k->raw,\n                    &r->raw, &s->raw, &curve->prime->raw, &curve->order->raw);\n           #else\n               if (err == MP_OKAY)\n                   err = IntelQaEcdsaSign(&key->asyncDev, &e->raw, &key->k.raw,\n                      &k->raw, &r->raw, &s->raw, &curve->Af->raw, &curve->Bf->raw,\n                      &curve->prime->raw, &curve->order->raw, &curve->Gx->raw,\n                      &curve->Gy->raw);\n           #endif\n\n           #ifndef HAVE_CAVIUM_V\n               mp_clear(e);\n               mp_clear(k);\n           #endif\n               wc_ecc_curve_free(curve);\n               FREE_CURVE_SPECS();\n\n               return err;\n           }\n       #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */\n       }\n   #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */\n\n   #ifdef WOLFSSL_SMALL_STACK\n       pubkey = (ecc_key*)XMALLOC(sizeof(ecc_key), key->heap, DYNAMIC_TYPE_ECC);\n       if (pubkey == NULL)\n           err = MEMORY_E;\n   #endif\n\n       /* don't use async for key, since we don't support async return here */\n       if (err == MP_OKAY && (err = wc_ecc_init_ex(pubkey, key->heap,\n                                                   INVALID_DEVID)) == MP_OKAY) {\n       #ifdef WOLFSSL_SMALL_STACK\n           mp_int* b = NULL;\n       #else\n           mp_int  b[1];\n       #endif\n\n       #ifdef WOLFSSL_SMALL_STACK\n           if (err == MP_OKAY) {\n               b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,\n                                                              DYNAMIC_TYPE_ECC);\n               if (b == NULL)\n                   err = MEMORY_E;\n           }\n       #endif\n\n           if (err == MP_OKAY) {\n               err = mp_init(b);\n           }\n\n       #ifdef WOLFSSL_CUSTOM_CURVES\n           /* if custom curve, apply params to pubkey */\n           if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {\n               err = wc_ecc_set_custom_curve(pubkey, key->dp);\n           }\n       #endif\n\n           if (err == MP_OKAY) {\n               /* Generate blinding value - non-zero value. */\n               do {\n                   if (++loop_check > 64) {\n                        err = RNG_FAILURE_E;\n                        break;\n                   }\n\n                   err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);\n               }\n               while (err == MP_ZERO_E);\n               loop_check = 0;\n           }\n\n           for (; err == MP_OKAY;) {\n               if (++loop_check > 64) {\n                    err = RNG_FAILURE_E;\n                    break;\n               }\n       #ifdef WOLFSSL_ECDSA_SET_K\n               if (key->sign_k != NULL) {\n                   if (loop_check > 1) {\n                      err = RNG_FAILURE_E;\n                      break;\n                   }\n\n                   err = mp_copy(key->sign_k, &pubkey->k);\n                   if (err != MP_OKAY) break;\n\n                   mp_forcezero(key->sign_k);\n                   mp_free(key->sign_k);\n                   XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);\n                   key->sign_k = NULL;\n                   err = wc_ecc_make_pub_ex(pubkey, curve, NULL);\n               }\n               else\n       #endif\n               {\n                   err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey,\n                                                                   key->dp->id);\n               }\n               if (err != MP_OKAY) break;\n\n               /* find r = x1 mod n */\n               err = mp_mod(pubkey->pubkey.x, curve->order, r);\n               if (err != MP_OKAY) break;\n\n               if (mp_iszero(r) == MP_YES) {\n                #ifndef ALT_ECC_SIZE\n                   mp_clear(pubkey->pubkey.x);\n                   mp_clear(pubkey->pubkey.y);\n                   mp_clear(pubkey->pubkey.z);\n                #endif\n                   mp_forcezero(&pubkey->k);\n               }\n               else {\n                   /* find s = (e + xr)/k\n                             = b.(e/k.b + x.r/k.b) */\n\n                   /* k = k.b */\n                   err = mp_mulmod(&pubkey->k, b, curve->order, &pubkey->k);\n                   if (err != MP_OKAY) break;\n\n                   /* k = 1/k.b */\n                   err = mp_invmod(&pubkey->k, curve->order, &pubkey->k);\n                   if (err != MP_OKAY) break;\n\n                   /* s = x.r */\n                   err = mp_mulmod(&key->k, r, curve->order, s);\n                   if (err != MP_OKAY) break;\n\n                   /* s = x.r/k.b */\n                   err = mp_mulmod(&pubkey->k, s, curve->order, s);\n                   if (err != MP_OKAY) break;\n\n                   /* e = e/k.b */\n                   err = mp_mulmod(&pubkey->k, e, curve->order, e);\n                   if (err != MP_OKAY) break;\n\n                   /* s = e/k.b + x.r/k.b\n                        = (e + x.r)/k.b */\n                   err = mp_add(e, s, s);\n                   if (err != MP_OKAY) break;\n\n                   /* s = b.(e + x.r)/k.b\n                        = (e + x.r)/k */\n                   err = mp_mulmod(s, b, curve->order, s);\n                   if (err != MP_OKAY) break;\n\n                   /* s = (e + xr)/k */\n                   err = mp_mod(s, curve->order, s);\n                   if (err != MP_OKAY) break;\n\n                   if (mp_iszero(s) == MP_NO)\n                       break;\n                }\n           }\n           mp_clear(b);\n           mp_free(b);\n       #ifdef WOLFSSL_SMALL_STACK\n           XFREE(b, key->heap, DYNAMIC_TYPE_ECC);\n       #endif\n           wc_ecc_free(pubkey);\n       #ifdef WOLFSSL_SMALL_STACK\n           XFREE(pubkey, key->heap, DYNAMIC_TYPE_ECC);\n       #endif\n       }\n   }\n\n   mp_clear(e);\n   wc_ecc_curve_free(curve);\n#ifdef WOLFSSL_SMALL_STACK\n   XFREE(e, key->heap, DYNAMIC_TYPE_ECC);\n#endif\n   FREE_CURVE_SPECS();\n#endif /* WOLFSSL_SP_MATH */\n\n   return err;\n}\n\n#ifdef WOLFSSL_ECDSA_SET_K\nint wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)\n{\n    int ret = 0;\n\n    if (k == NULL || klen <= 0 || key == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n\n    if (ret == 0) {\n        if (key->sign_k == NULL) {\n            key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,\n                                                              DYNAMIC_TYPE_ECC);\n            if (key->sign_k == NULL) {\n                ret = MEMORY_E;\n            }\n        }\n    }\n\n    if (ret == 0) {\n        ret = mp_read_unsigned_bin(key->sign_k, k, klen);\n    }\n\n    return ret;\n}\n#endif /* WOLFSSL_ECDSA_SET_K */\n#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL*/\n\n#endif /* HAVE_ECC_SIGN */\n\n#ifdef WOLFSSL_CUSTOM_CURVES\nvoid wc_ecc_free_curve(const ecc_set_type* curve, void* heap)\n{\n    if (curve->prime != NULL)\n        XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);\n    if (curve->Af != NULL)\n        XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);\n    if (curve->Bf != NULL)\n        XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);\n    if (curve->order != NULL)\n        XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);\n    if (curve->Gx != NULL)\n        XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);\n    if (curve->Gy != NULL)\n        XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);\n\n    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);\n\n    (void)heap;\n}\n#endif /* WOLFSSL_CUSTOM_CURVES */\n\n/**\n  Free an ECC key from memory\n  key   The key you wish to free\n*/\nWOLFSSL_ABI\nint wc_ecc_free(ecc_key* key)\n{\n    if (key == NULL) {\n        return 0;\n    }\n\n#ifdef WOLFSSL_ECDSA_SET_K\n    if (key->sign_k != NULL) {\n        mp_forcezero(key->sign_k);\n        mp_free(key->sign_k);\n        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n    #ifdef WC_ASYNC_ENABLE_ECC\n    wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);\n    #endif\n    wc_ecc_free_async(key);\n#endif\n\n#ifdef WOLFSSL_ATECC508A\n    atmel_ecc_free(key->slot);\n    key->slot = ATECC_INVALID_SLOT;\n#else\n\n    mp_clear(key->pubkey.x);\n    mp_clear(key->pubkey.y);\n    mp_clear(key->pubkey.z);\n\n    mp_forcezero(&key->k);\n#endif /* WOLFSSL_ATECC508A */\n\n#ifdef WOLFSSL_CUSTOM_CURVES\n    if (key->deallocSet && key->dp != NULL)\n        wc_ecc_free_curve(key->dp, key->heap);\n#endif\n\n    return 0;\n}\n\n#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)\n#ifdef ECC_SHAMIR\n\n/** Computes kA*A + kB*B = C using Shamir's Trick\n  A        First point to multiply\n  kA       What to multiple A by\n  B        Second point to multiply\n  kB       What to multiple B by\n  C        [out] Destination point (can overlap with A or B)\n  a        ECC curve parameter a\n  modulus  Modulus for curve\n  return MP_OKAY on success\n*/\n#ifdef FP_ECC\nstatic int normal_ecc_mul2add(ecc_point* A, mp_int* kA,\n                             ecc_point* B, mp_int* kB,\n                             ecc_point* C, mp_int* a, mp_int* modulus,\n                             void* heap)\n#else\nint ecc_mul2add(ecc_point* A, mp_int* kA,\n                    ecc_point* B, mp_int* kB,\n                    ecc_point* C, mp_int* a, mp_int* modulus,\n                    void* heap)\n#endif\n{\n#ifdef WOLFSSL_SMALL_STACK\n  ecc_point**    precomp = NULL;\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n  ecc_key        key;\n#endif\n#else\n  ecc_point*     precomp[SHAMIR_PRECOMP_SZ];\n#endif\n  unsigned       bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;\n  unsigned char* tA;\n  unsigned char* tB;\n  int            err = MP_OKAY, first, x, y;\n  mp_digit       mp = 0;\n\n  /* argchks */\n  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||\n                                                         modulus == NULL) {\n     return ECC_BAD_ARG_E;\n  }\n\n  /* allocate memory */\n  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);\n  if (tA == NULL) {\n     return GEN_MEM_ERR;\n  }\n  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);\n  if (tB == NULL) {\n     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);\n     return GEN_MEM_ERR;\n  }\n#ifdef WOLFSSL_SMALL_STACK\n  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,\n                                                       DYNAMIC_TYPE_ECC_BUFFER);\n  if (precomp == NULL) {\n     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);\n     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);\n     return GEN_MEM_ERR;\n  }\n#endif\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n  key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);\n  key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);\n#ifdef ALT_ECC_SIZE\n  key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);\n  key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);\n  key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);\n#endif\n  if (key.t1 == NULL || key.t2 == NULL\n#ifdef ALT_ECC_SIZE\n     || key.x == NULL || key.y == NULL || key.z == NULL\n#endif\n  ) {\n#ifdef ALT_ECC_SIZE\n      XFREE(key.z, heap, DYNAMIC_TYPE_ECC);\n      XFREE(key.y, heap, DYNAMIC_TYPE_ECC);\n      XFREE(key.x, heap, DYNAMIC_TYPE_ECC);\n#endif\n      XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);\n      XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);\n      XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);\n      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);\n      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);\n      return MEMORY_E;\n  }\n  C->key = &key;\n#endif /* WOLFSSL_SMALL_STACK_CACHE */\n\n  /* init variables */\n  XMEMSET(tA, 0, ECC_BUFSIZE);\n  XMEMSET(tB, 0, ECC_BUFSIZE);\n#ifndef WOLFSSL_SMALL_STACK\n  XMEMSET(precomp, 0, sizeof(precomp));\n#else\n  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);\n#endif\n\n  /* get sizes */\n  lenA = mp_unsigned_bin_size(kA);\n  lenB = mp_unsigned_bin_size(kB);\n  len  = MAX(lenA, lenB);\n\n  /* sanity check */\n  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {\n    err = BAD_FUNC_ARG;\n  }\n\n  if (err == MP_OKAY) {\n    /* extract and justify kA */\n    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);\n\n    /* extract and justify kB */\n    if (err == MP_OKAY)\n        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);\n\n    /* allocate the table */\n    if (err == MP_OKAY) {\n        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {\n            precomp[x] = wc_ecc_new_point_h(heap);\n            if (precomp[x] == NULL) {\n                err = GEN_MEM_ERR;\n                break;\n            }\n        #ifdef WOLFSSL_SMALL_STACK_CACHE\n            precomp[x]->key = &key;\n        #endif\n        }\n    }\n  }\n\n  if (err == MP_OKAY)\n    /* init montgomery reduction */\n    err = mp_montgomery_setup(modulus, &mp);\n\n  if (err == MP_OKAY) {\n  #ifdef WOLFSSL_SMALL_STACK\n    mp_int* mu = NULL;\n  #else\n    mp_int  mu[1];\n  #endif\n  #ifdef WOLFSSL_SMALL_STACK\n    mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);\n    if (mu == NULL)\n        err = MEMORY_E;\n  #endif\n    if (err == MP_OKAY) {\n        err = mp_init(mu);\n    }\n    if (err == MP_OKAY) {\n      err = mp_montgomery_calc_normalization(mu, modulus);\n\n      if (err == MP_OKAY)\n        /* copy ones ... */\n        err = mp_mulmod(A->x, mu, modulus, precomp[1]->x);\n\n      if (err == MP_OKAY)\n        err = mp_mulmod(A->y, mu, modulus, precomp[1]->y);\n      if (err == MP_OKAY)\n        err = mp_mulmod(A->z, mu, modulus, precomp[1]->z);\n\n      if (err == MP_OKAY)\n        err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x);\n      if (err == MP_OKAY)\n        err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y);\n      if (err == MP_OKAY)\n        err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z);\n\n      /* done with mu */\n      mp_clear(mu);\n    }\n  #ifdef WOLFSSL_SMALL_STACK\n    if (mu != NULL) {\n      XFREE(mu, heap, DYNAMIC_TYPE_ECC);\n    }\n  #endif\n  }\n\n  if (err == MP_OKAY)\n    /* precomp [i,0](A + B) table */\n    err = ecc_projective_dbl_point(precomp[1], precomp[2], a, modulus, mp);\n\n  if (err == MP_OKAY)\n    err = ecc_projective_add_point(precomp[1], precomp[2], precomp[3],\n                                   a, modulus, mp);\n  if (err == MP_OKAY)\n    /* precomp [0,i](A + B) table */\n    err = ecc_projective_dbl_point(precomp[1<<2], precomp[2<<2], a, modulus, mp);\n\n  if (err == MP_OKAY)\n    err = ecc_projective_add_point(precomp[1<<2], precomp[2<<2], precomp[3<<2],\n                                   a, modulus, mp);\n\n  if (err == MP_OKAY) {\n    /* precomp [i,j](A + B) table (i != 0, j != 0) */\n    for (x = 1; x < 4; x++) {\n      for (y = 1; y < 4; y++) {\n        if (err == MP_OKAY) {\n          err = ecc_projective_add_point(precomp[x], precomp[(y<<2)],\n                                             precomp[x+(y<<2)], a, modulus, mp);\n        }\n      }\n    }\n  }\n\n  if (err == MP_OKAY) {\n    nibble  = 3;\n    first   = 1;\n    bitbufA = tA[0];\n    bitbufB = tB[0];\n\n    /* for every byte of the multiplicands */\n    for (x = 0;; ) {\n        /* grab a nibble */\n        if (++nibble == 4) {\n            if (x == (int)len) break;\n            bitbufA = tA[x];\n            bitbufB = tB[x];\n            nibble  = 0;\n            x++;\n        }\n\n        /* extract two bits from both, shift/update */\n        nA = (bitbufA >> 6) & 0x03;\n        nB = (bitbufB >> 6) & 0x03;\n        bitbufA = (bitbufA << 2) & 0xFF;\n        bitbufB = (bitbufB << 2) & 0xFF;\n\n        /* if both zero, if first, continue */\n        if ((nA == 0) && (nB == 0) && (first == 1)) {\n            continue;\n        }\n\n        /* double twice, only if this isn't the first */\n        if (first == 0) {\n            /* double twice */\n            if (err == MP_OKAY)\n                err = ecc_projective_dbl_point(C, C, a, modulus, mp);\n            if (err == MP_OKAY)\n                err = ecc_projective_dbl_point(C, C, a, modulus, mp);\n            else\n                break;\n        }\n\n        /* if not both zero */\n        if ((nA != 0) || (nB != 0)) {\n            if (first == 1) {\n                /* if first, copy from table */\n                first = 0;\n                if (err == MP_OKAY)\n                    err = mp_copy(precomp[nA + (nB<<2)]->x, C->x);\n\n                if (err == MP_OKAY)\n                    err = mp_copy(precomp[nA + (nB<<2)]->y, C->y);\n\n                if (err == MP_OKAY)\n                    err = mp_copy(precomp[nA + (nB<<2)]->z, C->z);\n                else\n                    break;\n            } else {\n                /* if not first, add from table */\n                if (err == MP_OKAY)\n                    err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C,\n                                                   a, modulus, mp);\n                if (err != MP_OKAY)\n                    break;\n                if (mp_iszero(C->z)) {\n                    /* When all zero then should have done an add */\n                    if (mp_iszero(C->x) && mp_iszero(C->y)) {\n                        err = ecc_projective_dbl_point(precomp[nA + (nB<<2)], C,\n                                                       a, modulus, mp);\n                        if (err != MP_OKAY)\n                            break;\n                    }\n                    /* When only Z zero then result is infinity */\n                    else {\n                        err = mp_set(C->x, 0);\n                        if (err != MP_OKAY)\n                            break;\n                        err = mp_set(C->y, 0);\n                        if (err != MP_OKAY)\n                            break;\n                        err = mp_set(C->z, 1);\n                        if (err != MP_OKAY)\n                            break;\n                        first = 1;\n                    }\n                }\n            }\n        }\n    }\n  }\n\n  /* reduce to affine */\n  if (err == MP_OKAY)\n    err = ecc_map(C, modulus, mp);\n\n  /* clean up */\n  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {\n     wc_ecc_del_point_h(precomp[x], heap);\n  }\n\n  ForceZero(tA, ECC_BUFSIZE);\n  ForceZero(tB, ECC_BUFSIZE);\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n#ifdef ALT_ECC_SIZE\n  XFREE(key.z, heap, DYNAMIC_TYPE_ECC);\n  XFREE(key.y, heap, DYNAMIC_TYPE_ECC);\n  XFREE(key.x, heap, DYNAMIC_TYPE_ECC);\n#endif\n  XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);\n  XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);\n  C->key = NULL;\n#endif\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);\n#endif\n  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);\n  XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);\n\n  return err;\n}\n\n#endif /* ECC_SHAMIR */\n#endif /* !WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCEL*/\n\n\n#ifdef HAVE_ECC_VERIFY\n#ifndef NO_ASN\n/* verify\n *\n * w  = s^-1 mod n\n * u1 = xw\n * u2 = rw\n * X = u1*G + u2*Q\n * v = X_x1 mod n\n * accept if v == r\n */\n\n/**\n Verify an ECC signature\n sig         The signature to verify\n siglen      The length of the signature (octets)\n hash        The hash (message digest) that was signed\n hashlen     The length of the hash (octets)\n res         Result of signature, 1==valid, 0==invalid\n key         The corresponding public ECC key\n return      MP_OKAY if successful (even if the signature is not valid)\n */\nint wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,\n                       word32 hashlen, int* res, ecc_key* key)\n{\n    int err;\n    mp_int *r = NULL, *s = NULL;\n#if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)) && \\\n    !defined(WOLFSSL_SMALL_STACK)\n    mp_int r_lcl, s_lcl;\n#endif\n\n    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {\n        return ECC_BAD_ARG_E;\n    }\n\n#ifdef WOLF_CRYPTO_CB\n    if (key->devId != INVALID_DEVID) {\n        err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key);\n        if (err != CRYPTOCB_UNAVAILABLE)\n            return err;\n        /* fall-through when unavailable */\n    }\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n    err = wc_ecc_alloc_async(key);\n    if (err != 0)\n        return err;\n    r = key->r;\n    s = key->s;\n#else\n    #ifndef WOLFSSL_SMALL_STACK\n    r = &r_lcl;\n    s = &s_lcl;\n    #else\n    r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);\n    if (r == NULL)\n        return MEMORY_E;\n    s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);\n    if (s == NULL) {\n        XFREE(r, key->heap, DYNAMIC_TYPE_ECC);\n        return MEMORY_E;\n    }\n    #endif\n    XMEMSET(r, 0, sizeof(mp_int));\n    XMEMSET(s, 0, sizeof(mp_int));\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    switch (key->state) {\n        case ECC_STATE_NONE:\n        case ECC_STATE_VERIFY_DECODE:\n            key->state = ECC_STATE_VERIFY_DECODE;\n\n            /* default to invalid signature */\n            *res = 0;\n\n            /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.\n             * If either of those don't allocate correctly, none of\n             * the rest of this function will execute, and everything\n             * gets cleaned up at the end. */\n            /* decode DSA header */\n            err = DecodeECC_DSA_Sig(sig, siglen, r, s);\n            if (err < 0) {\n                break;\n            }\n            FALL_THROUGH;\n\n        case ECC_STATE_VERIFY_DO:\n            key->state = ECC_STATE_VERIFY_DO;\n\n            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);\n\n        #ifndef WOLFSSL_ASYNC_CRYPT\n            /* done with R/S */\n            mp_clear(r);\n            mp_clear(s);\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(s, key->heap, DYNAMIC_TYPE_ECC);\n            XFREE(r, key->heap, DYNAMIC_TYPE_ECC);\n            r = NULL;\n            s = NULL;\n        #endif\n        #endif\n\n            if (err < 0) {\n                break;\n            }\n            FALL_THROUGH;\n\n        case ECC_STATE_VERIFY_RES:\n            key->state = ECC_STATE_VERIFY_RES;\n            err = 0;\n            break;\n\n        default:\n            err = BAD_STATE_E;\n    }\n\n    /* if async pending then return and skip done cleanup below */\n    if (err == WC_PENDING_E) {\n        key->state++;\n        return err;\n    }\n\n    /* cleanup */\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n    wc_ecc_free_async(key);\n#elif defined(WOLFSSL_SMALL_STACK)\n    XFREE(s, key->heap, DYNAMIC_TYPE_ECC);\n    XFREE(r, key->heap, DYNAMIC_TYPE_ECC);\n    r = NULL;\n    s = NULL;\n#endif\n\n    key->state = ECC_STATE_NONE;\n\n    return err;\n}\n#endif /* !NO_ASN */\n\n\n/**\n   Verify an ECC signature\n   r           The signature R component to verify\n   s           The signature S component to verify\n   hash        The hash (message digest) that was signed\n   hashlen     The length of the hash (octets)\n   res         Result of signature, 1==valid, 0==invalid\n   key         The corresponding public ECC key\n   return      MP_OKAY if successful (even if the signature is not valid)\n*/\n\nint wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,\n                    word32 hashlen, int* res, ecc_key* key)\n#if defined(WOLFSSL_STM32_PKA)\n{\n    return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);\n}\n#else\n{\n   int           err;\n   word32        keySz;\n#ifdef WOLFSSL_ATECC508A\n   byte sigRS[ATECC_KEY_SIZE*2];\n#elif defined(WOLFSSL_CRYPTOCELL)\n   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];\n   CRYS_ECDSA_VerifyUserContext_t sigCtxTemp;\n   word32 msgLenInBytes = hashlen;\n   CRYS_ECPKI_HASH_OpMode_t hash_mode;\n#elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)\n   int          did_init = 0;\n   ecc_point    *mG = NULL, *mQ = NULL;\n   #ifdef WOLFSSL_SMALL_STACK\n   mp_int*       v = NULL;\n   mp_int*       w = NULL;\n   mp_int*       u1 = NULL;\n   mp_int*       u2 = NULL;\n      #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)\n   mp_int*       e_lcl = NULL;\n      #endif\n   #else /* WOLFSSL_SMALL_STACK */\n   mp_int        v[1];\n   mp_int        w[1];\n   mp_int        u1[1];\n   mp_int        u2[1];\n      #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)\n   mp_int        e_lcl[1];\n      #endif\n   #endif /* WOLFSSL_SMALL_STACK */\n   mp_int*       e;\n   DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);\n#endif\n\n   if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)\n       return ECC_BAD_ARG_E;\n\n   /* default to invalid signature */\n   *res = 0;\n\n   /* is the IDX valid ?  */\n   if (wc_ecc_is_valid_idx(key->idx) != 1) {\n      return ECC_BAD_ARG_E;\n   }\n\n   keySz = key->dp->size;\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \\\n       defined(WOLFSSL_ASYNC_CRYPT_TEST)\n    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {\n        if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_VERIFY)) {\n            WC_ASYNC_TEST* testDev = &key->asyncDev.test;\n            testDev->eccVerify.r = r;\n            testDev->eccVerify.s = s;\n            testDev->eccVerify.hash = hash;\n            testDev->eccVerify.hashlen = hashlen;\n            testDev->eccVerify.stat = res;\n            testDev->eccVerify.key = key;\n            return WC_PENDING_E;\n        }\n    }\n#endif\n\n#ifdef WOLFSSL_ATECC508A\n    /* Extract R and S */\n    err = mp_to_unsigned_bin(r, &sigRS[0]);\n    if (err != MP_OKAY) {\n        return err;\n    }\n    err = mp_to_unsigned_bin(s, &sigRS[keySz]);\n    if (err != MP_OKAY) {\n        return err;\n    }\n\n    err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);\n    if (err != 0) {\n       return err;\n    }\n    (void)hashlen;\n#elif defined(WOLFSSL_CRYPTOCELL)\n\n   /* Extract R and S */\n\n   err = mp_to_unsigned_bin(r, &sigRS[0]);\n   if (err != MP_OKAY) {\n       return err;\n   }\n   err = mp_to_unsigned_bin(s, &sigRS[keySz]);\n   if (err != MP_OKAY) {\n       return err;\n   }\n\n   hash_mode = cc310_hashModeECC(msgLenInBytes);\n   if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {\n       hash_mode = cc310_hashModeECC(keySz);\n       hash_mode = CRYS_ECPKI_HASH_SHA256_mode;\n   }\n   /* truncate if hash is longer than key size */\n   if (msgLenInBytes > keySz) {\n       msgLenInBytes = keySz;\n   }\n\n   /* verify the signature using the public key */\n   err = CRYS_ECDSA_Verify(&sigCtxTemp,\n                           &key->ctx.pubKey,\n                           hash_mode,\n                           &sigRS[0],\n                           keySz*2,\n                           (byte*)hash,\n                           msgLenInBytes);\n\n   if (err != SA_SILIB_RET_OK) {\n       WOLFSSL_MSG(\"CRYS_ECDSA_Verify failed\");\n       return err;\n   }\n   /* valid signature if we get to this point */\n   *res = 1;\n#else\n  /* checking if private key with no public part */\n  if (key->type == ECC_PRIVATEKEY_ONLY) {\n      WOLFSSL_MSG(\"Verify called with private key, generating public part\");\n      err = wc_ecc_make_pub_ex(key, NULL, NULL);\n      if (err != MP_OKAY) {\n           WOLFSSL_MSG(\"Unable to extract public key\");\n           return err;\n      }\n  }\n\n#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)\n  if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {\n      return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y,\n                                           key->pubkey.z, r, s, res, key->heap);\n  }\n  else\n      return WC_KEY_SIZE_E;\n#else\n#if defined WOLFSSL_HAVE_SP_ECC && !defined(FREESCALE_LTC_ECC)\n#ifndef WOLFSSL_SP_NO_256\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n    if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC)\n    #endif\n    {\n        if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1)\n            return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y,\n                                     key->pubkey.z,r, s, res, key->heap);\n    }\n#endif /* WOLFSSL_SP_NO_256 */\n#endif /* WOLFSSL_HAVE_SP_ECC */\n\n   ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)\n   err = wc_ecc_alloc_mpint(key, &key->e);\n   if (err != 0) {\n      FREE_CURVE_SPECS();\n      return err;\n   }\n   e = key->e;\n#else\n#ifdef WOLFSSL_SMALL_STACK\n   e_lcl = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);\n   if (e_lcl == NULL) {\n       FREE_CURVE_SPECS();\n       return MEMORY_E;\n   }\n#endif\n   e = e_lcl;\n#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */\n\n   err = mp_init(e);\n   if (err != MP_OKAY)\n      return MEMORY_E;\n\n   /* read in the specs for this curve */\n   err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);\n\n   /* check for zero */\n   if (err == MP_OKAY) {\n       if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES ||\n           mp_cmp(r, curve->order) != MP_LT ||\n           mp_cmp(s, curve->order) != MP_LT) {\n           err = MP_ZERO_E;\n       }\n   }\n\n   /* read hash */\n   if (err == MP_OKAY) {\n       /* we may need to truncate if hash is longer than key size */\n       unsigned int orderBits = mp_count_bits(curve->order);\n\n       /* truncate down to byte size, may be all that's needed */\n       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)\n           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;\n       err = mp_read_unsigned_bin(e, hash, hashlen);\n\n       /* may still need bit truncation too */\n       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)\n           mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));\n   }\n\n   /* check for async hardware acceleration */\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n   if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {\n   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)\n   #ifdef HAVE_CAVIUM_V\n      if (NitroxEccIsCurveSupported(key))\n   #endif\n      {\n          err = wc_mp_to_bigint_sz(e, &e->raw, keySz);\n          if (err == MP_OKAY)\n              err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);\n          if (err == MP_OKAY)\n              err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);\n          if (err == MP_OKAY)\n          #ifdef HAVE_CAVIUM_V\n              err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,\n                    &key->pubkey.y->raw, &r->raw, &s->raw,\n                    &curve->prime->raw, &curve->order->raw, res);\n          #else\n              err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,\n                    &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,\n                    &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,\n                    &curve->Gx->raw, &curve->Gy->raw, res);\n          #endif\n\n      #ifndef HAVE_CAVIUM_V\n          mp_clear(e);\n      #endif\n          wc_ecc_curve_free(curve);\n          FREE_CURVE_SPECS();\n\n          return err;\n      }\n   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */\n   }\n#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */\n\n#ifdef WOLFSSL_SMALL_STACK\n   if (err == MP_OKAY) {\n       v = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);\n       if (v == NULL)\n           err = MEMORY_E;\n   }\n   if (err == MP_OKAY) {\n       w = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);\n       if (w == NULL)\n           err = MEMORY_E;\n   }\n   if (err == MP_OKAY) {\n       u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);\n       if (u1 == NULL)\n           err = MEMORY_E;\n   }\n   if (err == MP_OKAY) {\n       u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);\n       if (u2 == NULL)\n           err = MEMORY_E;\n   }\n#endif\n\n   /* allocate ints */\n   if (err == MP_OKAY) {\n       if ((err = mp_init_multi(v, w, u1, u2, NULL, NULL)) != MP_OKAY) {\n          err = MEMORY_E;\n       }\n       did_init = 1;\n   }\n\n   /* allocate points */\n   if (err == MP_OKAY) {\n       mG = wc_ecc_new_point_h(key->heap);\n       mQ = wc_ecc_new_point_h(key->heap);\n       if (mQ  == NULL || mG == NULL)\n          err = MEMORY_E;\n   }\n\n   /*  w  = s^-1 mod n */\n   if (err == MP_OKAY)\n       err = mp_invmod(s, curve->order, w);\n\n   /* u1 = ew */\n   if (err == MP_OKAY)\n       err = mp_mulmod(e, w, curve->order, u1);\n\n   /* u2 = rw */\n   if (err == MP_OKAY)\n       err = mp_mulmod(r, w, curve->order, u2);\n\n   /* find mG and mQ */\n   if (err == MP_OKAY)\n       err = mp_copy(curve->Gx, mG->x);\n   if (err == MP_OKAY)\n       err = mp_copy(curve->Gy, mG->y);\n   if (err == MP_OKAY)\n       err = mp_set(mG->z, 1);\n\n   if (err == MP_OKAY)\n       err = mp_copy(key->pubkey.x, mQ->x);\n   if (err == MP_OKAY)\n       err = mp_copy(key->pubkey.y, mQ->y);\n   if (err == MP_OKAY)\n       err = mp_copy(key->pubkey.z, mQ->z);\n\n#if defined(FREESCALE_LTC_ECC)\n   /* use PKHA to compute u1*mG + u2*mQ */\n   if (err == MP_OKAY)\n       err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);\n   if (err == MP_OKAY)\n       err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);\n   if (err == MP_OKAY)\n       err = wc_ecc_point_add(mG, mQ, mG, curve->prime);\n#else\n#ifndef ECC_SHAMIR\n    if (err == MP_OKAY)\n    {\n        mp_digit mp = 0;\n\n        if (!mp_iszero(u1)) {\n            /* compute u1*mG + u2*mQ = mG */\n            err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,\n                                                                     key->heap);\n            if (err == MP_OKAY) {\n                err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,\n                                                                     key->heap);\n            }\n\n            /* find the montgomery mp */\n            if (err == MP_OKAY)\n                err = mp_montgomery_setup(curve->prime, &mp);\n\n            /* add them */\n            if (err == MP_OKAY)\n                err = ecc_projective_add_point(mQ, mG, mG, curve->Af,\n                                                              curve->prime, mp);\n            if (err == MP_OKAY && mp_iszero(mG->z)) {\n                /* When all zero then should have done an add */\n                if (mp_iszero(mG->x) && mp_iszero(mG->y)) {\n                    err = ecc_projective_dbl_point(mQ, mG, curve->Af,\n                                                              curve->prime, mp);\n                }\n                /* When only Z zero then result is infinity */\n                else {\n                    err = mp_set(mG->x, 0);\n                    if (err == MP_OKAY)\n                        err = mp_set(mG->y, 0);\n                    if (err == MP_OKAY)\n                        err = mp_set(mG->z, 1);\n                }\n            }\n        }\n        else {\n            /* compute 0*mG + u2*mQ = mG */\n            err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0,\n                                                                     key->heap);\n            /* find the montgomery mp */\n            if (err == MP_OKAY)\n                err = mp_montgomery_setup(curve->prime, &mp);\n        }\n\n        /* reduce */\n        if (err == MP_OKAY)\n            err = ecc_map(mG, curve->prime, mp);\n    }\n#else\n    /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */\n    if (err == MP_OKAY) {\n        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,\n                                                                     key->heap);\n    }\n#endif /* ECC_SHAMIR */\n#endif /* FREESCALE_LTC_ECC */\n   /* v = X_x1 mod n */\n   if (err == MP_OKAY)\n       err = mp_mod(mG->x, curve->order, v);\n\n   /* does v == r */\n   if (err == MP_OKAY) {\n       if (mp_cmp(v, r) == MP_EQ)\n           *res = 1;\n   }\n\n   /* cleanup */\n   wc_ecc_del_point_h(mG, key->heap);\n   wc_ecc_del_point_h(mQ, key->heap);\n\n   mp_clear(e);\n   if (did_init) {\n       mp_clear(v);\n       mp_clear(w);\n       mp_clear(u1);\n       mp_clear(u2);\n   }\n#ifdef WOLFSSL_SMALL_STACK\n   XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);\n   XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);\n   XFREE(w, key->heap, DYNAMIC_TYPE_ECC);\n   XFREE(v, key->heap, DYNAMIC_TYPE_ECC);\n#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)\n   XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);\n#endif\n#endif\n\n   wc_ecc_curve_free(curve);\n   FREE_CURVE_SPECS();\n\n#endif /* WOLFSSL_SP_MATH */\n#endif /* WOLFSSL_ATECC508A */\n\n   (void)keySz;\n   (void)hashlen;\n\n   return err;\n}\n#endif /* WOLFSSL_STM32_PKA */\n#endif /* HAVE_ECC_VERIFY */\n\n#ifdef HAVE_ECC_KEY_IMPORT\n/* import point from der */\nint wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,\n                            ecc_point* point)\n{\n    int err = 0;\n    int compressed = 0;\n    int keysize;\n    byte pointType;\n\n    if (in == NULL || point == NULL || (curve_idx < 0) ||\n        (wc_ecc_is_valid_idx(curve_idx) == 0))\n        return ECC_BAD_ARG_E;\n\n    /* must be odd */\n    if ((inLen & 1) == 0) {\n        return ECC_BAD_ARG_E;\n    }\n\n    /* init point */\n#ifdef ALT_ECC_SIZE\n    point->x = (mp_int*)&point->xyz[0];\n    point->y = (mp_int*)&point->xyz[1];\n    point->z = (mp_int*)&point->xyz[2];\n    alt_fp_init(point->x);\n    alt_fp_init(point->y);\n    alt_fp_init(point->z);\n#else\n    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);\n#endif\n    if (err != MP_OKAY)\n        return MEMORY_E;\n\n    /* check for point type (4, 2, or 3) */\n    pointType = in[0];\n    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&\n                                         pointType != ECC_POINT_COMP_ODD) {\n        err = ASN_PARSE_E;\n    }\n\n    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {\n#ifdef HAVE_COMP_KEY\n        compressed = 1;\n#else\n        err = NOT_COMPILED_IN;\n#endif\n    }\n\n    /* adjust to skip first byte */\n    inLen -= 1;\n    in += 1;\n\n    /* calculate key size based on inLen / 2 */\n    keysize = inLen>>1;\n\n    /* read data */\n    if (err == MP_OKAY)\n        err = mp_read_unsigned_bin(point->x, (byte*)in, keysize);\n\n#ifdef HAVE_COMP_KEY\n    if (err == MP_OKAY && compressed == 1) {   /* build y */\n#ifndef WOLFSSL_SP_MATH\n        int did_init = 0;\n        mp_int t1, t2;\n        DECLARE_CURVE_SPECS(curve, 3);\n\n        ALLOC_CURVE_SPECS(3);\n\n        if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)\n            err = MEMORY_E;\n        else\n            did_init = 1;\n\n        /* load curve info */\n        if (err == MP_OKAY)\n            err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,\n                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |\n                    ECC_CURVE_FIELD_BF));\n\n        /* compute x^3 */\n        if (err == MP_OKAY)\n            err = mp_sqr(point->x, &t1);\n        if (err == MP_OKAY)\n            err = mp_mulmod(&t1, point->x, curve->prime, &t1);\n\n        /* compute x^3 + a*x */\n        if (err == MP_OKAY)\n            err = mp_mulmod(curve->Af, point->x, curve->prime, &t2);\n        if (err == MP_OKAY)\n            err = mp_add(&t1, &t2, &t1);\n\n        /* compute x^3 + a*x + b */\n        if (err == MP_OKAY)\n            err = mp_add(&t1, curve->Bf, &t1);\n\n        /* compute sqrt(x^3 + a*x + b) */\n        if (err == MP_OKAY)\n            err = mp_sqrtmod_prime(&t1, curve->prime, &t2);\n\n        /* adjust y */\n        if (err == MP_OKAY) {\n            if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||\n                (mp_isodd(&t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {\n                err = mp_mod(&t2, curve->prime, point->y);\n            }\n            else {\n                err = mp_submod(curve->prime, &t2, curve->prime, point->y);\n            }\n        }\n\n        if (did_init) {\n            mp_clear(&t2);\n            mp_clear(&t1);\n        }\n\n        wc_ecc_curve_free(curve);\n        FREE_CURVE_SPECS();\n#else\n        sp_ecc_uncompress_256(point->x, pointType, point->y);\n#endif\n    }\n#endif\n\n    if (err == MP_OKAY && compressed == 0)\n        err = mp_read_unsigned_bin(point->y, (byte*)in + keysize, keysize);\n    if (err == MP_OKAY)\n        err = mp_set(point->z, 1);\n\n    if (err != MP_OKAY) {\n        mp_clear(point->x);\n        mp_clear(point->y);\n        mp_clear(point->z);\n    }\n\n    return err;\n}\n#endif /* HAVE_ECC_KEY_IMPORT */\n\n#ifdef HAVE_ECC_KEY_EXPORT\n/* export point to der */\nint wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,\n                            word32* outLen)\n{\n    int    ret = MP_OKAY;\n    word32 numlen;\n#ifdef WOLFSSL_SMALL_STACK\n    byte*  buf;\n#else\n    byte   buf[ECC_BUFSIZE];\n#endif\n\n    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))\n        return ECC_BAD_ARG_E;\n\n    /* return length needed only */\n    if (point != NULL && out == NULL && outLen != NULL) {\n        numlen = ecc_sets[curve_idx].size;\n        *outLen = 1 + 2*numlen;\n        return LENGTH_ONLY_E;\n    }\n\n    if (point == NULL || out == NULL || outLen == NULL)\n        return ECC_BAD_ARG_E;\n\n    numlen = ecc_sets[curve_idx].size;\n\n    if (*outLen < (1 + 2*numlen)) {\n        *outLen = 1 + 2*numlen;\n        return BUFFER_E;\n    }\n\n    /* store byte point type */\n    out[0] = ECC_POINT_UNCOMP;\n\n#ifdef WOLFSSL_SMALL_STACK\n    buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n    if (buf == NULL)\n        return MEMORY_E;\n#endif\n\n    /* pad and store x */\n    XMEMSET(buf, 0, ECC_BUFSIZE);\n    ret = mp_to_unsigned_bin(point->x, buf +\n                                 (numlen - mp_unsigned_bin_size(point->x)));\n    if (ret != MP_OKAY)\n        goto done;\n    XMEMCPY(out+1, buf, numlen);\n\n    /* pad and store y */\n    XMEMSET(buf, 0, ECC_BUFSIZE);\n    ret = mp_to_unsigned_bin(point->y, buf +\n                                 (numlen - mp_unsigned_bin_size(point->y)));\n    if (ret != MP_OKAY)\n        goto done;\n    XMEMCPY(out+1+numlen, buf, numlen);\n\n    *outLen = 1 + 2*numlen;\n\ndone:\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n#endif\n\n    return ret;\n}\n\n\n/* export public ECC key in ANSI X9.63 format */\nint wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)\n{\n   int    ret = MP_OKAY;\n   word32 numlen;\n#ifdef WOLFSSL_SMALL_STACK\n   byte*  buf;\n#else\n   byte   buf[ECC_BUFSIZE];\n#endif\n   word32 pubxlen, pubylen;\n\n   /* return length needed only */\n   if (key != NULL && out == NULL && outLen != NULL) {\n      /* if key hasn't been setup assume max bytes for size estimation */\n      numlen = key->dp ? key->dp->size : MAX_ECC_BYTES;\n      *outLen = 1 + 2*numlen;\n      return LENGTH_ONLY_E;\n   }\n\n   if (key == NULL || out == NULL || outLen == NULL)\n      return ECC_BAD_ARG_E;\n\n   if (key->type == ECC_PRIVATEKEY_ONLY)\n       return ECC_PRIVATEONLY_E;\n\n   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {\n      return ECC_BAD_ARG_E;\n   }\n   numlen = key->dp->size;\n\n    /* verify room in out buffer */\n   if (*outLen < (1 + 2*numlen)) {\n      *outLen = 1 + 2*numlen;\n      return BUFFER_E;\n   }\n\n   /* verify public key length is less than key size */\n   pubxlen = mp_unsigned_bin_size(key->pubkey.x);\n   pubylen = mp_unsigned_bin_size(key->pubkey.y);\n   if ((pubxlen > numlen) || (pubylen > numlen)) {\n      WOLFSSL_MSG(\"Public key x/y invalid!\");\n      return BUFFER_E;\n   }\n\n   /* store byte point type */\n   out[0] = ECC_POINT_UNCOMP;\n\n#ifdef WOLFSSL_SMALL_STACK\n   buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n   if (buf == NULL)\n      return MEMORY_E;\n#endif\n\n   /* pad and store x */\n   XMEMSET(buf, 0, ECC_BUFSIZE);\n   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));\n   if (ret != MP_OKAY)\n      goto done;\n   XMEMCPY(out+1, buf, numlen);\n\n   /* pad and store y */\n   XMEMSET(buf, 0, ECC_BUFSIZE);\n   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));\n   if (ret != MP_OKAY)\n      goto done;\n   XMEMCPY(out+1+numlen, buf, numlen);\n\n   *outLen = 1 + 2*numlen;\n\ndone:\n#ifdef WOLFSSL_SMALL_STACK\n   XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n#endif\n\n   return ret;\n}\n\n\n/* export public ECC key in ANSI X9.63 format, extended with\n * compression option */\nint wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,\n                          int compressed)\n{\n    if (compressed == 0)\n        return wc_ecc_export_x963(key, out, outLen);\n#ifdef HAVE_COMP_KEY\n    else\n        return wc_ecc_export_x963_compressed(key, out, outLen);\n#else\n    return NOT_COMPILED_IN;\n#endif\n}\n#endif /* HAVE_ECC_KEY_EXPORT */\n\n\n#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)\n\n/* is ecc point on curve described by dp ? */\nint wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)\n{\n#ifndef WOLFSSL_SP_MATH\n   int err;\n#ifdef WOLFSSL_SMALL_STACK\n   mp_int* t1 = NULL;\n   mp_int* t2 = NULL;\n#else\n   mp_int  t1[1], t2[1];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n   if (t1 == NULL)\n       return MEMORY_E;\n   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n   if (t2 == NULL) {\n       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n       return MEMORY_E;\n   }\n#endif\n\n   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {\n   #ifdef WOLFSSL_SMALL_STACK\n      XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n      XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n   #endif\n      return err;\n   }\n\n   /* compute y^2 */\n   if (err == MP_OKAY)\n       err = mp_sqr(ecp->y, t1);\n\n   /* compute x^3 */\n   if (err == MP_OKAY)\n       err = mp_sqr(ecp->x, t2);\n   if (err == MP_OKAY)\n       err = mp_mod(t2, prime, t2);\n   if (err == MP_OKAY)\n       err = mp_mul(ecp->x, t2, t2);\n\n   /* compute y^2 - x^3 */\n   if (err == MP_OKAY)\n       err = mp_sub(t1, t2, t1);\n\n   /* Determine if curve \"a\" should be used in calc */\n#ifdef WOLFSSL_CUSTOM_CURVES\n   if (err == MP_OKAY) {\n      /* Use a and prime to determine if a == 3 */\n      err = mp_set(t2, 0);\n      if (err == MP_OKAY)\n          err = mp_submod(prime, a, prime, t2);\n   }\n   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {\n      /* compute y^2 - x^3 + a*x */\n      if (err == MP_OKAY)\n          err = mp_mulmod(t2, ecp->x, prime, t2);\n      if (err == MP_OKAY)\n          err = mp_addmod(t1, t2, prime, t1);\n   }\n   else\n#endif /* WOLFSSL_CUSTOM_CURVES */\n   {\n      /* assumes \"a\" == 3 */\n      (void)a;\n\n      /* compute y^2 - x^3 + 3x */\n      if (err == MP_OKAY)\n          err = mp_add(t1, ecp->x, t1);\n      if (err == MP_OKAY)\n          err = mp_add(t1, ecp->x, t1);\n      if (err == MP_OKAY)\n          err = mp_add(t1, ecp->x, t1);\n      if (err == MP_OKAY)\n          err = mp_mod(t1, prime, t1);\n  }\n\n   /* adjust range (0, prime) */\n   while (err == MP_OKAY && mp_isneg(t1)) {\n      err = mp_add(t1, prime, t1);\n   }\n   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {\n      err = mp_sub(t1, prime, t1);\n   }\n\n   /* compare to b */\n   if (err == MP_OKAY) {\n       if (mp_cmp(t1, b) != MP_EQ) {\n          err = MP_VAL;\n       } else {\n          err = MP_OKAY;\n       }\n   }\n\n   mp_clear(t1);\n   mp_clear(t2);\n#ifdef WOLFSSL_SMALL_STACK\n   XFREE(t2, NULL, DYNAMIC_TYPE_ECC);\n   XFREE(t1, NULL, DYNAMIC_TYPE_ECC);\n#endif\n\n   return err;\n#else\n   (void)a;\n   (void)b;\n   (void)prime;\n\n   return sp_ecc_is_point_256(ecp->x, ecp->y);\n#endif\n}\n\n#ifndef WOLFSSL_SP_MATH\n/* validate privkey * generator == pubkey, 0 on success */\nstatic int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)\n{\n    int        err = MP_OKAY;\n    ecc_point* base = NULL;\n    ecc_point* res  = NULL;\n    DECLARE_CURVE_SPECS(curve, 2);\n\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    ALLOC_CURVE_SPECS(2);\n\n    res = wc_ecc_new_point_h(key->heap);\n    if (res == NULL)\n        err = MEMORY_E;\n\n#ifdef WOLFSSL_HAVE_SP_ECC\n#ifndef WOLFSSL_SP_NO_256\n    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {\n        if (err == MP_OKAY)\n            err = sp_ecc_mulmod_base_256(&key->k, res, 1, key->heap);\n    }\n    else\n#endif\n#endif\n    {\n        base = wc_ecc_new_point_h(key->heap);\n        if (base == NULL)\n            err = MEMORY_E;\n\n        if (err == MP_OKAY) {\n            /* load curve info */\n            err = wc_ecc_curve_load(key->dp, &curve,\n                                      (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));\n        }\n\n        /* set up base generator */\n        if (err == MP_OKAY)\n            err = mp_copy(curve->Gx, base->x);\n        if (err == MP_OKAY)\n            err = mp_copy(curve->Gy, base->y);\n        if (err == MP_OKAY)\n            err = mp_set(base->z, 1);\n\n        if (err == MP_OKAY)\n            err = wc_ecc_mulmod_ex(&key->k, base, res, a, prime, 1, key->heap);\n    }\n\n    if (err == MP_OKAY) {\n        /* compare result to public key */\n        if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||\n            mp_cmp(res->y, key->pubkey.y) != MP_EQ ||\n            mp_cmp(res->z, key->pubkey.z) != MP_EQ) {\n            /* didn't match */\n            err = ECC_PRIV_KEY_E;\n        }\n    }\n\n    wc_ecc_curve_free(curve);\n    wc_ecc_del_point_h(res, key->heap);\n    wc_ecc_del_point_h(base, key->heap);\n    FREE_CURVE_SPECS();\n\n    return err;\n}\n#endif\n\n#ifdef WOLFSSL_VALIDATE_ECC_IMPORT\n\n/* check privkey generator helper, creates prime needed */\nstatic int ecc_check_privkey_gen_helper(ecc_key* key)\n{\n    int    err;\n#ifndef WOLFSSL_ATECC508A\n    DECLARE_CURVE_SPECS(curve, 2);\n#endif\n\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n#ifdef WOLFSSL_ATECC508A\n    /* Hardware based private key, so this operation is not supported */\n    err = MP_OKAY; /* just report success */\n\n#else\n    ALLOC_CURVE_SPECS(2);\n\n    /* load curve info */\n    err = wc_ecc_curve_load(key->dp, &curve,\n        (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));\n\n    if (err == MP_OKAY)\n        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);\n\n    wc_ecc_curve_free(curve);\n    FREE_CURVE_SPECS();\n\n#endif /* WOLFSSL_ATECC508A */\n\n    return err;\n}\n\n#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */\n\n\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)\n/* validate order * pubkey = point at infinity, 0 on success */\nstatic int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,\n        mp_int* prime, mp_int* order)\n{\n    ecc_point* inf = NULL;\n    int        err;\n\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    inf = wc_ecc_new_point_h(key->heap);\n    if (inf == NULL)\n        err = MEMORY_E;\n    else {\n#ifdef WOLFSSL_HAVE_SP_ECC\n#ifndef WOLFSSL_SP_NO_256\n        if (key->idx != ECC_CUSTOM_IDX &&\n                                       ecc_sets[key->idx].id == ECC_SECP256R1) {\n            err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap);\n        }\n        else\n#endif\n#endif\n#ifndef WOLFSSL_SP_MATH\n            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);\n        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))\n            err = ECC_INF_E;\n#else\n            (void)a;\n            (void)prime;\n\n            err = WC_KEY_SIZE_E;\n#endif\n    }\n\n    wc_ecc_del_point_h(inf, key->heap);\n\n    return err;\n}\n#endif\n#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL*/\n\n\n/* perform sanity checks on ecc key validity, 0 on success */\nint wc_ecc_check_key(ecc_key* key)\n{\n    int    err;\n#ifndef WOLFSSL_SP_MATH\n#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)\n    mp_int* b = NULL;\n#ifdef USE_ECC_B_PARAM\n    DECLARE_CURVE_SPECS(curve, 4);\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    mp_int b_lcl;\n#endif\n    DECLARE_CURVE_SPECS(curve, 3);\n#endif /* USE_ECC_B_PARAM */\n#endif /* WOLFSSL_ATECC508A */\n\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_CRYPTOCELL)\n\n    err = 0; /* consider key check success on ATECC508A */\n\n#else\n    #ifdef USE_ECC_B_PARAM\n        ALLOC_CURVE_SPECS(4);\n    #else\n        ALLOC_CURVE_SPECS(3);\n        #ifndef WOLFSSL_SMALL_STACK\n            b = &b_lcl;\n        #else\n            b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);\n            if (b == NULL) {\n                FREE_CURVE_SPECS();\n                return MEMORY_E;\n            }\n        #endif\n        XMEMSET(b, 0, sizeof(mp_int));\n    #endif\n\n    /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */\n    /* pubkey point cannot be at infinity */\n    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(b, key->heap, DYNAMIC_TYPE_ECC);\n    #endif\n        FREE_CURVE_SPECS();\n        return ECC_INF_E;\n    }\n\n    /* load curve info */\n    err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |\n            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER\n#ifdef USE_ECC_B_PARAM\n            | ECC_CURVE_FIELD_BF\n#endif\n    ));\n\n#ifndef USE_ECC_B_PARAM\n    /* load curve b parameter */\n    if (err == MP_OKAY)\n        err = mp_init(b);\n    if (err == MP_OKAY)\n        err = mp_read_radix(b, key->dp->Bf, MP_RADIX_HEX);\n#else\n    if (err == MP_OKAY)\n        b = curve->Bf;\n#endif\n\n    /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */\n    /* Qx must be in the range [0, p-1] */\n    if (err == MP_OKAY) {\n        if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT)\n            err = ECC_OUT_OF_RANGE_E;\n    }\n\n    /* Qy must be in the range [0, p-1] */\n    if (err == MP_OKAY) {\n        if (mp_cmp(key->pubkey.y, curve->prime) != MP_LT)\n            err = ECC_OUT_OF_RANGE_E;\n    }\n\n    /* SP 800-56Ar3, section 5.6.2.3.3, process steps 3 */\n    /* make sure point is actually on curve */\n    if (err == MP_OKAY)\n        err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);\n\n    /* SP 800-56Ar3, section 5.6.2.3.3, process steps 4 */\n    /* pubkey * order must be at infinity */\n    if (err == MP_OKAY)\n        err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af, curve->prime,\n                curve->order);\n\n    /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */\n    /* private * base generator must equal pubkey */\n    if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)\n        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);\n\n    wc_ecc_curve_free(curve);\n\n#ifndef USE_ECC_B_PARAM\n    mp_clear(b);\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(b, key->heap, DYNAMIC_TYPE_ECC);\n    #endif\n#endif\n\n    FREE_CURVE_SPECS();\n\n#endif /* WOLFSSL_ATECC508A */\n#else\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    /* pubkey point cannot be at infinity */\n    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {\n        err = sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y, &key->k,\n                                                                     key->heap);\n    }\n    else\n        err = WC_KEY_SIZE_E;\n#endif\n\n    return err;\n}\n\n#ifdef HAVE_ECC_KEY_IMPORT\n/* import public ECC key in ANSI X9.63 format */\nint wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,\n                          int curve_id)\n{\n    int err = MP_OKAY;\n    int compressed = 0;\n    int keysize = 0;\n    byte pointType;\n\n    if (in == NULL || key == NULL)\n        return BAD_FUNC_ARG;\n\n    /* must be odd */\n    if ((inLen & 1) == 0) {\n        return ECC_BAD_ARG_E;\n    }\n\n    /* make sure required variables are reset */\n    wc_ecc_reset(key);\n\n    /* init key */\n    #ifdef ALT_ECC_SIZE\n        key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];\n        key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];\n        key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];\n        alt_fp_init(key->pubkey.x);\n        alt_fp_init(key->pubkey.y);\n        alt_fp_init(key->pubkey.z);\n        err = mp_init(&key->k);\n    #else\n        err = mp_init_multi(&key->k,\n                    key->pubkey.x, key->pubkey.y, key->pubkey.z, NULL, NULL);\n    #endif\n    if (err != MP_OKAY)\n        return MEMORY_E;\n\n    /* check for point type (4, 2, or 3) */\n    pointType = in[0];\n    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&\n                                         pointType != ECC_POINT_COMP_ODD) {\n        err = ASN_PARSE_E;\n    }\n\n    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {\n    #ifdef HAVE_COMP_KEY\n        compressed = 1;\n    #else\n        err = NOT_COMPILED_IN;\n    #endif\n    }\n\n    /* adjust to skip first byte */\n    inLen -= 1;\n    in += 1;\n\n#ifdef WOLFSSL_ATECC508A\n    /* For SECP256R1 only save raw public key for hardware */\n    if (curve_id == ECC_SECP256R1 && !compressed &&\n                                            inLen <= sizeof(key->pubkey_raw)) {\n        XMEMCPY(key->pubkey_raw, (byte*)in, inLen);\n    }\n#endif\n\n    if (err == MP_OKAY) {\n    #ifdef HAVE_COMP_KEY\n        /* adjust inLen if compressed */\n        if (compressed)\n            inLen = inLen*2 + 1;  /* used uncompressed len */\n    #endif\n\n        /* determine key size */\n        keysize = (inLen>>1);\n        err = wc_ecc_set_curve(key, keysize, curve_id);\n        key->type = ECC_PUBLICKEY;\n    }\n\n    /* read data */\n    if (err == MP_OKAY)\n        err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in, keysize);\n\n#ifdef HAVE_COMP_KEY\n    if (err == MP_OKAY && compressed == 1) {   /* build y */\n#ifndef WOLFSSL_SP_MATH\n        mp_int t1, t2;\n        int did_init = 0;\n\n        DECLARE_CURVE_SPECS(curve, 3);\n        ALLOC_CURVE_SPECS(3);\n\n        if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)\n            err = MEMORY_E;\n        else\n            did_init = 1;\n\n        /* load curve info */\n        if (err == MP_OKAY)\n            err = wc_ecc_curve_load(key->dp, &curve,\n                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |\n                 ECC_CURVE_FIELD_BF));\n\n        /* compute x^3 */\n        if (err == MP_OKAY)\n            err = mp_sqr(key->pubkey.x, &t1);\n        if (err == MP_OKAY)\n            err = mp_mulmod(&t1, key->pubkey.x, curve->prime, &t1);\n\n        /* compute x^3 + a*x */\n        if (err == MP_OKAY)\n            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, &t2);\n        if (err == MP_OKAY)\n            err = mp_add(&t1, &t2, &t1);\n\n        /* compute x^3 + a*x + b */\n        if (err == MP_OKAY)\n            err = mp_add(&t1, curve->Bf, &t1);\n\n        /* compute sqrt(x^3 + a*x + b) */\n        if (err == MP_OKAY)\n            err = mp_sqrtmod_prime(&t1, curve->prime, &t2);\n\n        /* adjust y */\n        if (err == MP_OKAY) {\n            if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||\n                (mp_isodd(&t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {\n                err = mp_mod(&t2, curve->prime, &t2);\n            }\n            else {\n                err = mp_submod(curve->prime, &t2, curve->prime, &t2);\n            }\n            if (err == MP_OKAY)\n                err = mp_copy(&t2, key->pubkey.y);\n        }\n\n        if (did_init) {\n            mp_clear(&t2);\n            mp_clear(&t1);\n        }\n\n        wc_ecc_curve_free(curve);\n        FREE_CURVE_SPECS();\n#else\n        sp_ecc_uncompress_256(key->pubkey.x, pointType, key->pubkey.y);\n#endif\n    }\n#endif /* HAVE_COMP_KEY */\n\n    if (err == MP_OKAY && compressed == 0)\n        err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in + keysize, keysize);\n    if (err == MP_OKAY)\n        err = mp_set(key->pubkey.z, 1);\n\n#ifdef WOLFSSL_VALIDATE_ECC_IMPORT\n    if (err == MP_OKAY)\n        err = wc_ecc_check_key(key);\n#endif\n\n    if (err != MP_OKAY) {\n        mp_clear(key->pubkey.x);\n        mp_clear(key->pubkey.y);\n        mp_clear(key->pubkey.z);\n        mp_clear(&key->k);\n    }\n\n    return err;\n}\n\nint wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)\n{\n    return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);\n}\n#endif /* HAVE_ECC_KEY_IMPORT */\n\n#ifdef HAVE_ECC_KEY_EXPORT\n\n/* export ecc key to component form, d is optional if only exporting public\n * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR\n * return MP_OKAY on success */\nint wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,\n                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)\n{\n    int err = 0;\n    word32 keySz;\n\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (wc_ecc_is_valid_idx(key->idx) == 0) {\n        return ECC_BAD_ARG_E;\n    }\n    keySz = key->dp->size;\n\n    /* private key, d */\n    if (d != NULL) {\n        if (dLen == NULL ||\n            (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY))\n            return BAD_FUNC_ARG;\n\n    #ifdef WOLFSSL_ATECC508A\n        /* Hardware cannot export private portion */\n        return NOT_COMPILED_IN;\n    #else\n        err = wc_export_int(&key->k, d, dLen, keySz, encType);\n        if (err != MP_OKAY)\n            return err;\n    #endif\n    }\n\n    /* public x component */\n    if (qx != NULL) {\n        if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)\n            return BAD_FUNC_ARG;\n\n        err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);\n        if (err != MP_OKAY)\n            return err;\n    }\n\n    /* public y component */\n    if (qy != NULL) {\n        if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)\n            return BAD_FUNC_ARG;\n\n        err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);\n        if (err != MP_OKAY)\n            return err;\n    }\n\n    return err;\n}\n\n\n/* export ecc private key only raw, outLen is in/out size as unsigned bin\n   return MP_OKAY on success */\nint wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)\n{\n    if (out == NULL || outLen == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,\n        WC_TYPE_UNSIGNED_BIN);\n}\n\n/* export public key to raw elements including public (Qx,Qy) as unsigned bin\n * return MP_OKAY on success, negative on error */\nint wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,\n                             byte* qy, word32* qyLen)\n{\n    if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,\n        WC_TYPE_UNSIGNED_BIN);\n}\n\n/* export ecc key to raw elements including public (Qx,Qy) and\n *   private (d) as unsigned bin\n * return MP_OKAY on success, negative on error */\nint wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,\n                              byte* qy, word32* qyLen, byte* d, word32* dLen)\n{\n    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,\n        WC_TYPE_UNSIGNED_BIN);\n}\n\n#endif /* HAVE_ECC_KEY_EXPORT */\n\n#ifndef NO_ASN\n#ifdef HAVE_ECC_KEY_IMPORT\n/* import private key, public part optional if (pub) passed as NULL */\nint wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,\n                                 const byte* pub, word32 pubSz, ecc_key* key,\n                                 int curve_id)\n{\n    int ret;\n    word32 idx = 0;\n#if defined(WOLFSSL_CRYPTOCELL)\n    const CRYS_ECPKI_Domain_t* pDomain;\n    CRYS_ECPKI_BUILD_TempData_t tempBuff;\n#endif\n    if (key == NULL || priv == NULL)\n        return BAD_FUNC_ARG;\n\n    /* public optional, NULL if only importing private */\n    if (pub != NULL) {\n        ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);\n        if (ret < 0)\n            ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);\n        key->type = ECC_PRIVATEKEY;\n    }\n    else {\n        /* make sure required variables are reset */\n        wc_ecc_reset(key);\n\n        /* set key size */\n        ret = wc_ecc_set_curve(key, privSz, curve_id);\n        key->type = ECC_PRIVATEKEY_ONLY;\n    }\n\n    if (ret != 0)\n        return ret;\n\n#ifdef WOLFSSL_ATECC508A\n    /* Hardware does not support loading private keys */\n    return NOT_COMPILED_IN;\n#elif defined(WOLFSSL_CRYPTOCELL)\n    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(curve_id));\n\n    if (pub != NULL && pub[0] != '\\0') {\n        /* create public key from external key buffer */\n        ret = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,\n                                               (byte*)pub,\n                                               pubSz,\n                                               &key->ctx.pubKey,\n                                               &tempBuff);\n\n        if (ret != SA_SILIB_RET_OK){\n            WOLFSSL_MSG(\"CRYS_ECPKI_BuildPublKeyFullCheck failed\");\n            return ret;\n        }\n    }\n    /* import private key */\n    if (priv != NULL && priv[0] != '\\0') {\n\n        /* Create private key from external key buffer*/\n        ret = CRYS_ECPKI_BuildPrivKey(pDomain,\n                                      priv,\n                                      privSz,\n                                      &key->ctx.privKey);\n\n        if (ret != SA_SILIB_RET_OK) {\n            WOLFSSL_MSG(\"CRYS_ECPKI_BuildPrivKey failed\");\n            return ret;\n        }\n\n        ret = mp_read_unsigned_bin(&key->k, priv, privSz);\n    }\n\n#else\n\n    ret = mp_read_unsigned_bin(&key->k, priv, privSz);\n#ifdef HAVE_WOLF_BIGINT\n    if (ret == 0 &&\n                  wc_bigint_from_unsigned_bin(&key->k.raw, priv, privSz) != 0) {\n        mp_clear(&key->k);\n        ret = ASN_GETINT_E;\n    }\n#endif /* HAVE_WOLF_BIGINT */\n\n\n#endif /* WOLFSSL_ATECC508A */\n\n#ifdef WOLFSSL_VALIDATE_ECC_IMPORT\n    if ((pub != NULL) && (ret == MP_OKAY))\n        /* public key needed to perform key validation */\n        ret = ecc_check_privkey_gen_helper(key);\n#endif\n\n    return ret;\n}\n\n/* ecc private key import, public key in ANSI X9.63 format, private raw */\nint wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,\n                           word32 pubSz, ecc_key* key)\n{\n    return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,\n                                                                ECC_CURVE_DEF);\n}\n#endif /* HAVE_ECC_KEY_IMPORT */\n\n/**\n   Convert ECC R,S to signature\n   r       R component of signature\n   s       S component of signature\n   out     DER-encoded ECDSA signature\n   outlen  [in/out] output buffer size, output signature size\n   return  MP_OKAY on success\n*/\nint wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)\n{\n    int err;\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int* rtmp = NULL;\n    mp_int* stmp = NULL;\n#else\n    mp_int  rtmp[1];\n    mp_int  stmp[1];\n#endif\n\n    if (r == NULL || s == NULL || out == NULL || outlen == NULL)\n        return ECC_BAD_ARG_E;\n\n#ifdef WOLFSSL_SMALL_STACK\n    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n    if (rtmp == NULL)\n        return MEMORY_E;\n    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n    if (stmp == NULL) {\n        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);\n        return MEMORY_E;\n    }\n#endif\n\n    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);\n    if (err != MP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);\n        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);\n    #endif\n        return err;\n    }\n\n    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);\n    if (err == MP_OKAY)\n        err = mp_read_radix(stmp, s, MP_RADIX_HEX);\n\n    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */\n    if (err == MP_OKAY)\n        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);\n\n    if (err == MP_OKAY) {\n        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)\n            err = MP_ZERO_E;\n    }\n\n    mp_clear(rtmp);\n    mp_clear(stmp);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);\n    XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);\n#endif\n\n    return err;\n}\n\n/**\n   Convert ECC R,S raw unsigned bin to signature\n   r       R component of signature\n   rSz     R size\n   s       S component of signature\n   sSz     S size\n   out     DER-encoded ECDSA signature\n   outlen  [in/out] output buffer size, output signature size\n   return  MP_OKAY on success\n*/\nint wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,\n    byte* out, word32* outlen)\n{\n    int err;\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int* rtmp = NULL;\n    mp_int* stmp = NULL;\n#else\n    mp_int  rtmp[1];\n    mp_int  stmp[1];\n#endif\n\n    if (r == NULL || s == NULL || out == NULL || outlen == NULL)\n        return ECC_BAD_ARG_E;\n\n#ifdef WOLFSSL_SMALL_STACK\n    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n    if (rtmp == NULL)\n        return MEMORY_E;\n    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n    if (stmp == NULL) {\n        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);\n        return MEMORY_E;\n    }\n#endif\n\n    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);\n    if (err != MP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);\n        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);\n    #endif\n        return err;\n    }\n\n    err = mp_read_unsigned_bin(rtmp, r, rSz);\n    if (err == MP_OKAY)\n        err = mp_read_unsigned_bin(stmp, s, sSz);\n\n    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */\n    if (err == MP_OKAY)\n        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);\n\n    if (err == MP_OKAY) {\n        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)\n            err = MP_ZERO_E;\n    }\n\n    mp_clear(rtmp);\n    mp_clear(stmp);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);\n    XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);\n#endif\n\n    return err;\n}\n\n/**\n   Convert ECC signature to R,S\n   sig     DER-encoded ECDSA signature\n   sigLen  length of signature in octets\n   r       R component of signature\n   rLen    [in/out] output \"r\" buffer size, output \"r\" size\n   s       S component of signature\n   sLen    [in/out] output \"s\" buffer size, output \"s\" size\n   return  MP_OKAY on success, negative on error\n*/\nint wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,\n                     byte* s, word32* sLen)\n{\n    int err;\n    int tmp_valid = 0;\n    word32 x = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int* rtmp = NULL;\n    mp_int* stmp = NULL;\n#else\n    mp_int  rtmp[1];\n    mp_int  stmp[1];\n#endif\n\n    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)\n        return ECC_BAD_ARG_E;\n\n#ifdef WOLFSSL_SMALL_STACK\n    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n    if (rtmp == NULL)\n        return MEMORY_E;\n    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);\n    if (stmp == NULL) {\n        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);\n        return MEMORY_E;\n    }\n#endif\n\n    err = DecodeECC_DSA_Sig(sig, sigLen, rtmp, stmp);\n\n    /* rtmp and stmp are initialized */\n    if (err == MP_OKAY) {\n        tmp_valid = 1;\n    }\n\n    /* extract r */\n    if (err == MP_OKAY) {\n        x = mp_unsigned_bin_size(rtmp);\n        if (*rLen < x)\n            err = BUFFER_E;\n\n        if (err == MP_OKAY) {\n            *rLen = x;\n            err = mp_to_unsigned_bin(rtmp, r);\n        }\n    }\n\n    /* extract s */\n    if (err == MP_OKAY) {\n        x = mp_unsigned_bin_size(stmp);\n        if (*sLen < x)\n            err = BUFFER_E;\n\n        if (err == MP_OKAY) {\n            *sLen = x;\n            err = mp_to_unsigned_bin(stmp, s);\n        }\n    }\n\n    if (tmp_valid) {\n        mp_clear(rtmp);\n        mp_clear(stmp);\n    }\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);\n    XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);\n#endif\n\n    return err;\n}\n#endif /* !NO_ASN */\n\n#ifdef HAVE_ECC_KEY_IMPORT\nstatic int wc_ecc_import_raw_private(ecc_key* key, const char* qx,\n          const char* qy, const char* d, int curve_id, int encType)\n{\n    int err = MP_OKAY;\n#if defined(WOLFSSL_CRYPTOCELL)\n    const CRYS_ECPKI_Domain_t* pDomain;\n    CRYS_ECPKI_BUILD_TempData_t tempBuff;\n    byte key_raw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];\n    word32 keySz = 0;\n#endif\n    /* if d is NULL, only import as public key using Qx,Qy */\n    if (key == NULL || qx == NULL || qy == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* make sure required variables are reset */\n    wc_ecc_reset(key);\n\n    /* set curve type and index */\n    err = wc_ecc_set_curve(key, 0, curve_id);\n    if (err != 0) {\n        return err;\n    }\n\n    /* init key */\n#ifdef ALT_ECC_SIZE\n    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];\n    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];\n    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];\n    alt_fp_init(key->pubkey.x);\n    alt_fp_init(key->pubkey.y);\n    alt_fp_init(key->pubkey.z);\n    err = mp_init(&key->k);\n#else\n    err = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,\n                                                                  NULL, NULL);\n#endif\n    if (err != MP_OKAY)\n        return MEMORY_E;\n\n    /* read Qx */\n    if (err == MP_OKAY) {\n        if (encType == WC_TYPE_HEX_STR)\n            err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);\n        else\n            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,\n                key->dp->size);\n    }\n\n    /* read Qy */\n    if (err == MP_OKAY) {\n        if (encType == WC_TYPE_HEX_STR)\n            err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);\n        else\n            err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,\n                key->dp->size);\n\n    }\n\n    if (err == MP_OKAY)\n        err = mp_set(key->pubkey.z, 1);\n\n#ifdef WOLFSSL_ATECC508A\n    /* For SECP256R1 only save raw public key for hardware */\n    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {\n        word32 keySz = key->dp->size;\n        err = wc_export_int(key->pubkey.x, key->pubkey_raw,\n            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);\n        if (err == MP_OKAY)\n            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],\n                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);\n    }\n#elif defined(WOLFSSL_CRYPTOCELL)\n    if (err == MP_OKAY) {\n        key_raw[0] = ECC_POINT_UNCOMP;\n        keySz = (word32)key->dp->size;\n        err = wc_export_int(key->pubkey.x, &key_raw[1], &keySz, keySz,\n            WC_TYPE_UNSIGNED_BIN);\n        if (err == MP_OKAY)\n            err = wc_export_int(key->pubkey.y, &key_raw[1+keySz],\n                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);\n\n\n        pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(curve_id));\n\n        /* create public key from external key buffer */\n        err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,\n                                               key_raw,\n                                               keySz*2 + 1,\n                                               &key->ctx.pubKey,\n                                               &tempBuff);\n\n        if (err != SA_SILIB_RET_OK){\n            WOLFSSL_MSG(\"CRYS_ECPKI_BuildPublKeyFullCheck failed\");\n            return err;\n        }\n    }\n\n#endif\n\n    /* import private key */\n    if (err == MP_OKAY) {\n        if (d != NULL && d[0] != '\\0') {\n        #ifdef WOLFSSL_ATECC508A\n            /* Hardware doesn't support loading private key */\n            err = NOT_COMPILED_IN;\n\n        #elif defined(WOLFSSL_CRYPTOCELL)\n\n            key->type = ECC_PRIVATEKEY;\n\n            if (encType == WC_TYPE_HEX_STR)\n                err = mp_read_radix(&key->k, d, MP_RADIX_HEX);\n            else\n                err = mp_read_unsigned_bin(&key->k, (const byte*)d,\n                    key->dp->size);\n\n            err = wc_export_int(&key->k, &key_raw[0], &keySz, keySz,\n                WC_TYPE_UNSIGNED_BIN);\n\n            /* Create private key from external key buffer*/\n            err = CRYS_ECPKI_BuildPrivKey(pDomain,\n                                          key_raw,\n                                          keySz,\n                                          &key->ctx.privKey);\n\n            if (err != SA_SILIB_RET_OK){\n                WOLFSSL_MSG(\"CRYS_ECPKI_BuildPrivKey failed\");\n                return err;\n            }\n\n        #else\n            key->type = ECC_PRIVATEKEY;\n\n            if (encType == WC_TYPE_HEX_STR)\n                err = mp_read_radix(&key->k, d, MP_RADIX_HEX);\n            else\n                err = mp_read_unsigned_bin(&key->k, (const byte*)d,\n                    key->dp->size);\n        #endif /* WOLFSSL_ATECC508A */\n        } else {\n            key->type = ECC_PUBLICKEY;\n        }\n    }\n\n#ifdef WOLFSSL_VALIDATE_ECC_IMPORT\n    if (err == MP_OKAY)\n        err = wc_ecc_check_key(key);\n#endif\n\n    if (err != MP_OKAY) {\n        mp_clear(key->pubkey.x);\n        mp_clear(key->pubkey.y);\n        mp_clear(key->pubkey.z);\n        mp_clear(&key->k);\n    }\n\n    return err;\n}\n\n/**\n   Import raw ECC key\n   key       The destination ecc_key structure\n   qx        x component of the public key, as ASCII hex string\n   qy        y component of the public key, as ASCII hex string\n   d         private key, as ASCII hex string, optional if importing public\n             key only\n   dp        Custom ecc_set_type\n   return    MP_OKAY on success\n*/\nint wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,\n                   const char* d, int curve_id)\n{\n    return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,\n        WC_TYPE_HEX_STR);\n\n}\n\n/* Import x, y and optional private (d) as unsigned binary */\nint wc_ecc_import_unsigned(ecc_key* key, byte* qx, byte* qy,\n                   byte* d, int curve_id)\n{\n    return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,\n        (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);\n}\n\n/**\n   Import raw ECC key\n   key       The destination ecc_key structure\n   qx        x component of the public key, as ASCII hex string\n   qy        y component of the public key, as ASCII hex string\n   d         private key, as ASCII hex string, optional if importing public\n             key only\n   curveName ECC curve name, from ecc_sets[]\n   return    MP_OKAY on success\n*/\nint wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,\n                   const char* d, const char* curveName)\n{\n    int err, x;\n\n    /* if d is NULL, only import as public key using Qx,Qy */\n    if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* set curve type and index */\n    for (x = 0; ecc_sets[x].size != 0; x++) {\n        if (XSTRNCMP(ecc_sets[x].name, curveName,\n                     XSTRLEN(curveName)) == 0) {\n            break;\n        }\n    }\n\n    if (ecc_sets[x].size == 0) {\n        WOLFSSL_MSG(\"ecc_set curve name not found\");\n        err = ASN_PARSE_E;\n    } else {\n        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,\n            WC_TYPE_HEX_STR);\n    }\n\n    return err;\n}\n#endif /* HAVE_ECC_KEY_IMPORT */\n\n/* key size in octets */\nint wc_ecc_size(ecc_key* key)\n{\n    if (key == NULL)\n        return 0;\n\n    return key->dp->size;\n}\n\n/* maximum signature size based on key size */\nint wc_ecc_sig_size_calc(int sz)\n{\n    int maxSigSz = 0;\n\n    /* calculate based on key bits */\n    /* maximum possible signature header size is 7 bytes plus 2 bytes padding */\n    maxSigSz = (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;\n\n    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */\n    if (maxSigSz < (128 + 2)) {\n        maxSigSz -= 1;\n    }\n\n    return maxSigSz;\n}\n\n/* maximum signature size based on actual key curve */\nint wc_ecc_sig_size(ecc_key* key)\n{\n    int maxSigSz;\n    int orderBits, keySz;\n\n    if (key == NULL || key->dp == NULL)\n        return 0;\n\n    /* the signature r and s will always be less than order */\n    /* if the order MSB (top bit of byte) is set then ASN encoding needs\n        extra byte for r and s, so add 2 */\n    keySz = key->dp->size;\n    orderBits = wc_ecc_get_curve_order_bit_count(key->dp);\n    if (orderBits > keySz * 8) {\n        keySz = (orderBits + 7) / 8;\n    }\n    /* maximum possible signature header size is 7 bytes */\n    maxSigSz = (keySz * 2) + SIG_HEADER_SZ;\n    if ((orderBits % 8) == 0) {\n        /* MSB can be set, so add 2 */\n        maxSigSz += ECC_MAX_PAD_SZ;\n    }\n    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */\n    if (maxSigSz < (128 + 2)) {\n        maxSigSz -= 1;\n    }\n\n    return maxSigSz;\n}\n\n\n#ifdef FP_ECC\n\n/* fixed point ECC cache */\n/* number of entries in the cache */\n#ifndef FP_ENTRIES\n    #define FP_ENTRIES 15\n#endif\n\n/* number of bits in LUT */\n#ifndef FP_LUT\n    #define FP_LUT     8U\n#endif\n\n#ifdef ECC_SHAMIR\n    /* Sharmir requires a bigger LUT, TAO */\n    #if (FP_LUT > 12) || (FP_LUT < 4)\n        #error FP_LUT must be between 4 and 12 inclusively\n    #endif\n#else\n    #if (FP_LUT > 12) || (FP_LUT < 2)\n        #error FP_LUT must be between 2 and 12 inclusively\n    #endif\n#endif\n\n\n#ifndef WOLFSSL_SP_MATH\n\n/** Our FP cache */\ntypedef struct {\n   ecc_point* g;               /* cached COPY of base point */\n   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */\n   mp_int     mu;              /* copy of the montgomery constant */\n   int        lru_count;       /* amount of times this entry has been used */\n   int        lock;            /* flag to indicate cache eviction */\n                               /* permitted (0) or not (1) */\n} fp_cache_t;\n\n/* if HAVE_THREAD_LS this cache is per thread, no locking needed */\nstatic THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];\n\n#ifndef HAVE_THREAD_LS\n    static volatile int initMutex = 0;  /* prevent multiple mutex inits */\n    static wolfSSL_Mutex ecc_fp_lock;\n#endif /* HAVE_THREAD_LS */\n\n/* simple table to help direct the generation of the LUT */\nstatic const struct {\n   int ham, terma, termb;\n} lut_orders[] = {\n   { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },\n   { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },\n   { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },\n   { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },\n   { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },\n   { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },\n   { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },\n   { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },\n#if FP_LUT > 6\n   { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },\n   { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },\n   { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },\n   { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },\n   { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },\n   { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },\n   { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },\n   { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },\n#if FP_LUT > 7\n   { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },\n   { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },\n   { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },\n   { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },\n   { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },\n   { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },\n   { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },\n   { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },\n   { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },\n   { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },\n   { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },\n   { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },\n   { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },\n   { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },\n   { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },\n   { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },\n#if FP_LUT > 8\n   { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },\n   { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },\n   { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },\n   { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },\n   { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },\n   { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },\n   { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },\n   { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },\n   { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },\n   { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },\n   { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },\n   { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },\n   { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },\n   { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },\n   { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },\n   { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },\n   { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },\n   { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },\n   { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },\n   { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },\n   { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },\n   { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },\n   { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },\n   { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },\n   { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },\n   { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },\n   { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },\n   { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },\n   { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },\n   { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },\n   { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },\n   { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },\n#if FP_LUT > 9\n   { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },\n   { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },\n   { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },\n   { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },\n   { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },\n   { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },\n   { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },\n   { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },\n   { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },\n   { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },\n   { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },\n   { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },\n   { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },\n   { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },\n   { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },\n   { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },\n   { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },\n   { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },\n   { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },\n   { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },\n   { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },\n   { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },\n   { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },\n   { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },\n   { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },\n   { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },\n   { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },\n   { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },\n   { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },\n   { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },\n   { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },\n   { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },\n   { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },\n   { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },\n   { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },\n   { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },\n   { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },\n   { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },\n   { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },\n   { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },\n   { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },\n   { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },\n   { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },\n   { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },\n   { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },\n   { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },\n   { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },\n   { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },\n   { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },\n   { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },\n   { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },\n   { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },\n   { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },\n   { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },\n   { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },\n   { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },\n   { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },\n   { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },\n   { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },\n   { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },\n   { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },\n   { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },\n   { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },\n   { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },\n#if FP_LUT > 10\n   { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },\n   { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },\n   { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },\n   { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },\n   { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },\n   { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },\n   { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },\n   { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },\n   { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },\n   { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },\n   { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },\n   { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },\n   { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },\n   { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },\n   { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },\n   { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },\n   { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },\n   { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },\n   { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },\n   { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },\n   { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },\n   { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },\n   { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },\n   { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },\n   { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },\n   { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },\n   { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },\n   { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },\n   { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },\n   { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },\n   { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },\n   { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },\n   { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },\n   { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },\n   { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },\n   { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },\n   { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },\n   { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },\n   { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },\n   { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },\n   { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },\n   { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },\n   { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },\n   { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },\n   { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },\n   { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },\n   { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },\n   { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },\n   { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },\n   { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },\n   { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },\n   { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },\n   { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },\n   { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },\n   { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },\n   { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },\n   { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },\n   { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },\n   { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },\n   { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },\n   { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },\n   { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },\n   { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },\n   { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },\n   { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },\n   { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },\n   { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },\n   { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },\n   { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },\n   { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },\n   { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },\n   { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },\n   { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },\n   { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },\n   { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },\n   { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },\n   { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },\n   { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },\n   { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },\n   { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },\n   { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },\n   { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },\n   { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },\n   { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },\n   { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },\n   { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },\n   { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },\n   { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },\n   { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },\n   { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },\n   { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },\n   { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },\n   { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },\n   { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },\n   { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },\n   { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },\n   { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },\n   { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },\n   { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },\n   { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },\n   { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },\n   { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },\n   { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },\n   { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },\n   { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },\n   { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },\n   { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },\n   { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },\n   { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },\n   { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },\n   { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },\n   { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },\n   { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },\n   { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },\n   { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },\n   { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },\n   { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },\n   { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },\n   { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },\n   { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },\n   { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },\n   { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },\n   { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },\n   { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },\n   { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },\n   { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },\n   { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },\n   { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },\n#if FP_LUT > 11\n   { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },\n   { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },\n   { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },\n   { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },\n   { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },\n   { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },\n   { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },\n   { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },\n   { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },\n   { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },\n   { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },\n   { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },\n   { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },\n   { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },\n   { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },\n   { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },\n   { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },\n   { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },\n   { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },\n   { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },\n   { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },\n   { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },\n   { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },\n   { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },\n   { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },\n   { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },\n   { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },\n   { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },\n   { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },\n   { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },\n   { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },\n   { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },\n   { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },\n   { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },\n   { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },\n   { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },\n   { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },\n   { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },\n   { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },\n   { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },\n   { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },\n   { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },\n   { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },\n   { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },\n   { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },\n   { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },\n   { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },\n   { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },\n   { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },\n   { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },\n   { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },\n   { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },\n   { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },\n   { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },\n   { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },\n   { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },\n   { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },\n   { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },\n   { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },\n   { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },\n   { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },\n   { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },\n   { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },\n   { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },\n   { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },\n   { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },\n   { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },\n   { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },\n   { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },\n   { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },\n   { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },\n   { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },\n   { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },\n   { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },\n   { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },\n   { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },\n   { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },\n   { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },\n   { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },\n   { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },\n   { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },\n   { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },\n   { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },\n   { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },\n   { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },\n   { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },\n   { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },\n   { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },\n   { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },\n   { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },\n   { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },\n   { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },\n   { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },\n   { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },\n   { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },\n   { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },\n   { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },\n   { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },\n   { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },\n   { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },\n   { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },\n   { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },\n   { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },\n   { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },\n   { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },\n   { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },\n   { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },\n   { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },\n   { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },\n   { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },\n   { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },\n   { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },\n   { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },\n   { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },\n   { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },\n   { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },\n   { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },\n   { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },\n   { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },\n   { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },\n   { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },\n   { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },\n   { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },\n   { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },\n   { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },\n   { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },\n   { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },\n   { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },\n   { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },\n   { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },\n   { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },\n   { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },\n   { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },\n   { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },\n   { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },\n   { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },\n   { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },\n   { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },\n   { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },\n   { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },\n   { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },\n   { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },\n   { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },\n   { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },\n   { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },\n   { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },\n   { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },\n   { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },\n   { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },\n   { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },\n   { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },\n   { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },\n   { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },\n   { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },\n   { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },\n   { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },\n   { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },\n   { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },\n   { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },\n   { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },\n   { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },\n   { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },\n   { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },\n   { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },\n   { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },\n   { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },\n   { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },\n   { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },\n   { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },\n   { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },\n   { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },\n   { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },\n   { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },\n   { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },\n   { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },\n   { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },\n   { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },\n   { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },\n   { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },\n   { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },\n   { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },\n   { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },\n   { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },\n   { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },\n   { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },\n   { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },\n   { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },\n   { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },\n   { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },\n   { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },\n   { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },\n   { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },\n   { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },\n   { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },\n   { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },\n   { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },\n   { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },\n   { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },\n   { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },\n   { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },\n   { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },\n   { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },\n   { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },\n   { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },\n   { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },\n   { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },\n   { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },\n   { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },\n   { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },\n   { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },\n   { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },\n   { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },\n   { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },\n   { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },\n   { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },\n   { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },\n   { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },\n   { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },\n   { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },\n   { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },\n   { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },\n   { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },\n   { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },\n   { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },\n   { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },\n   { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },\n   { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },\n   { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },\n   { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },\n   { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },\n   { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },\n   { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },\n   { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },\n   { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },\n   { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },\n   { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },\n   { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },\n   { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },\n   { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },\n   { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },\n   { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },\n   { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },\n   { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },\n   { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },\n   { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },\n   { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },\n   { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },\n   { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },\n   { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },\n   { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },\n   { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },\n   { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },\n   { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },\n   { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },\n   { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },\n   { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },\n#endif\n#endif\n#endif\n#endif\n#endif\n#endif\n};\n\n\n/* find a hole and free as required, return -1 if no hole found */\nstatic int find_hole(void)\n{\n   unsigned x;\n   int      y, z;\n   for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {\n       if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {\n          z = x;\n          y = fp_cache[x].lru_count;\n       }\n   }\n\n   /* decrease all */\n   for (x = 0; x < FP_ENTRIES; x++) {\n      if (fp_cache[x].lru_count > 3) {\n         --(fp_cache[x].lru_count);\n      }\n   }\n\n   /* free entry z */\n   if (z >= 0 && fp_cache[z].g) {\n      mp_clear(&fp_cache[z].mu);\n      wc_ecc_del_point(fp_cache[z].g);\n      fp_cache[z].g  = NULL;\n      for (x = 0; x < (1U<<FP_LUT); x++) {\n         wc_ecc_del_point(fp_cache[z].LUT[x]);\n         fp_cache[z].LUT[x] = NULL;\n      }\n      fp_cache[z].lru_count = 0;\n   }\n   return z;\n}\n\n/* determine if a base is already in the cache and if so, where */\nstatic int find_base(ecc_point* g)\n{\n   int x;\n   for (x = 0; x < FP_ENTRIES; x++) {\n      if (fp_cache[x].g != NULL &&\n          mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&\n          mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&\n          mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {\n         break;\n      }\n   }\n   if (x == FP_ENTRIES) {\n      x = -1;\n   }\n   return x;\n}\n\n/* add a new base to the cache */\nstatic int add_entry(int idx, ecc_point *g)\n{\n   unsigned x, y;\n\n   /* allocate base and LUT */\n   fp_cache[idx].g = wc_ecc_new_point();\n   if (fp_cache[idx].g == NULL) {\n      return GEN_MEM_ERR;\n   }\n\n   /* copy x and y */\n   if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||\n       (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||\n       (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {\n      wc_ecc_del_point(fp_cache[idx].g);\n      fp_cache[idx].g = NULL;\n      return GEN_MEM_ERR;\n   }\n\n   for (x = 0; x < (1U<<FP_LUT); x++) {\n      fp_cache[idx].LUT[x] = wc_ecc_new_point();\n      if (fp_cache[idx].LUT[x] == NULL) {\n         for (y = 0; y < x; y++) {\n            wc_ecc_del_point(fp_cache[idx].LUT[y]);\n            fp_cache[idx].LUT[y] = NULL;\n         }\n         wc_ecc_del_point(fp_cache[idx].g);\n         fp_cache[idx].g         = NULL;\n         fp_cache[idx].lru_count = 0;\n         return GEN_MEM_ERR;\n      }\n   }\n\n   fp_cache[idx].lru_count = 0;\n\n   return MP_OKAY;\n}\n#endif\n\n#ifndef WOLFSSL_SP_MATH\n/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart\n *\n * The algorithm builds patterns in increasing bit order by first making all\n * single bit input patterns, then all two bit input patterns and so on\n */\nstatic int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,\n    mp_int* mu)\n{\n   int err;\n   unsigned x, y, bitlen, lut_gap;\n   mp_int tmp;\n\n   if (mp_init(&tmp) != MP_OKAY)\n       return GEN_MEM_ERR;\n\n   /* sanity check to make sure lut_order table is of correct size,\n      should compile out to a NOP if true */\n   if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {\n       err = BAD_FUNC_ARG;\n   }\n   else {\n    /* get bitlen and round up to next multiple of FP_LUT */\n    bitlen  = mp_unsigned_bin_size(modulus) << 3;\n    x       = bitlen % FP_LUT;\n    if (x) {\n      bitlen += FP_LUT - x;\n    }\n    lut_gap = bitlen / FP_LUT;\n\n    /* init the mu */\n    err = mp_init_copy(&fp_cache[idx].mu, mu);\n   }\n\n   /* copy base */\n   if (err == MP_OKAY) {\n     if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,\n                  fp_cache[idx].LUT[1]->x) != MP_OKAY) ||\n         (mp_mulmod(fp_cache[idx].g->y, mu, modulus,\n                  fp_cache[idx].LUT[1]->y) != MP_OKAY) ||\n         (mp_mulmod(fp_cache[idx].g->z, mu, modulus,\n                  fp_cache[idx].LUT[1]->z) != MP_OKAY)) {\n       err = MP_MULMOD_E;\n     }\n   }\n\n   /* make all single bit entries */\n   for (x = 1; x < FP_LUT; x++) {\n      if (err != MP_OKAY)\n          break;\n      if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x,\n                   fp_cache[idx].LUT[1<<x]->x) != MP_OKAY) ||\n          (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y,\n                   fp_cache[idx].LUT[1<<x]->y) != MP_OKAY) ||\n          (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z,\n                   fp_cache[idx].LUT[1<<x]->z) != MP_OKAY)){\n          err = MP_INIT_E;\n          break;\n      } else {\n\n         /* now double it bitlen/FP_LUT times */\n         for (y = 0; y < lut_gap; y++) {\n             if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[1<<x],\n                            fp_cache[idx].LUT[1<<x], a, modulus, mp)) != MP_OKAY) {\n                 break;\n             }\n         }\n     }\n  }\n\n   /* now make all entries in increase order of hamming weight */\n   for (x = 2; x <= FP_LUT; x++) {\n       if (err != MP_OKAY)\n           break;\n       for (y = 0; y < (1UL<<FP_LUT); y++) {\n           if (lut_orders[y].ham != (int)x) continue;\n\n           /* perform the add */\n           if ((err = ecc_projective_add_point(\n                           fp_cache[idx].LUT[lut_orders[y].terma],\n                           fp_cache[idx].LUT[lut_orders[y].termb],\n                           fp_cache[idx].LUT[y], a, modulus, mp)) != MP_OKAY) {\n              break;\n           }\n       }\n   }\n\n   /* now map all entries back to affine space to make point addition faster */\n   for (x = 1; x < (1UL<<FP_LUT); x++) {\n       if (err != MP_OKAY)\n           break;\n\n       /* convert z to normal from montgomery */\n       err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);\n\n       /* invert it */\n       if (err == MP_OKAY)\n         err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,\n                         fp_cache[idx].LUT[x]->z);\n\n       if (err == MP_OKAY)\n         /* now square it */\n         err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, &tmp);\n\n       if (err == MP_OKAY)\n         /* fix x */\n         err = mp_mulmod(fp_cache[idx].LUT[x]->x, &tmp, modulus,\n                         fp_cache[idx].LUT[x]->x);\n\n       if (err == MP_OKAY)\n         /* get 1/z^3 */\n         err = mp_mulmod(&tmp, fp_cache[idx].LUT[x]->z, modulus, &tmp);\n\n       if (err == MP_OKAY)\n         /* fix y */\n         err = mp_mulmod(fp_cache[idx].LUT[x]->y, &tmp, modulus,\n                         fp_cache[idx].LUT[x]->y);\n\n       if (err == MP_OKAY)\n         /* free z */\n         mp_clear(fp_cache[idx].LUT[x]->z);\n   }\n\n   mp_clear(&tmp);\n\n   if (err == MP_OKAY)\n     return MP_OKAY;\n\n   /* err cleanup */\n   for (y = 0; y < (1U<<FP_LUT); y++) {\n      wc_ecc_del_point(fp_cache[idx].LUT[y]);\n      fp_cache[idx].LUT[y] = NULL;\n   }\n   wc_ecc_del_point(fp_cache[idx].g);\n   fp_cache[idx].g         = NULL;\n   fp_cache[idx].lru_count = 0;\n   mp_clear(&fp_cache[idx].mu);\n\n   return err;\n}\n\n/* perform a fixed point ECC mulmod */\nstatic int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a,\n                        mp_int* modulus, mp_digit mp, int map)\n{\n#define KB_SIZE 128\n\n#ifdef WOLFSSL_SMALL_STACK\n   unsigned char* kb = NULL;\n#else\n   unsigned char kb[KB_SIZE];\n#endif\n   int      x, err;\n   unsigned y, z = 0, bitlen, bitpos, lut_gap, first;\n   mp_int   tk, order;\n\n   if (mp_init_multi(&tk, &order, NULL, NULL, NULL, NULL) != MP_OKAY)\n       return MP_INIT_E;\n\n   /* if it's smaller than modulus we fine */\n   if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {\n      /* find order */\n      y = mp_unsigned_bin_size(modulus);\n      for (x = 0; ecc_sets[x].size; x++) {\n         if (y <= (unsigned)ecc_sets[x].size) break;\n      }\n\n      /* back off if we are on the 521 bit curve */\n      if (y == 66) --x;\n\n      if ((err = mp_read_radix(&order, ecc_sets[x].order,\n                                                MP_RADIX_HEX)) != MP_OKAY) {\n         goto done;\n      }\n\n      /* k must be less than modulus */\n      if (mp_cmp(k, &order) != MP_LT) {\n         if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) {\n            goto done;\n         }\n      } else {\n         if ((err = mp_copy(k, &tk)) != MP_OKAY) {\n            goto done;\n         }\n      }\n   } else {\n      if ((err = mp_copy(k, &tk)) != MP_OKAY) {\n         goto done;\n      }\n   }\n\n   /* get bitlen and round up to next multiple of FP_LUT */\n   bitlen  = mp_unsigned_bin_size(modulus) << 3;\n   x       = bitlen % FP_LUT;\n   if (x) {\n      bitlen += FP_LUT - x;\n   }\n   lut_gap = bitlen / FP_LUT;\n\n   /* get the k value */\n   if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) {\n      err = BUFFER_E; goto done;\n   }\n\n   /* store k */\n#ifdef WOLFSSL_SMALL_STACK\n   kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n   if (kb == NULL) {\n      err = MEMORY_E; goto done;\n   }\n#endif\n\n   XMEMSET(kb, 0, KB_SIZE);\n   if ((err = mp_to_unsigned_bin(&tk, kb)) == MP_OKAY) {\n      /* let's reverse kb so it's little endian */\n      x = 0;\n      y = mp_unsigned_bin_size(&tk);\n      if (y > 0) {\n          y -= 1;\n      }\n\n      while ((unsigned)x < y) {\n         z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;\n         ++x; --y;\n      }\n\n      /* at this point we can start, yipee */\n      first = 1;\n      for (x = lut_gap-1; x >= 0; x--) {\n          /* extract FP_LUT bits from kb spread out by lut_gap bits and offset\n             by x bits from the start */\n          bitpos = x;\n          for (y = z = 0; y < FP_LUT; y++) {\n             z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y;\n             bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid\n                                    the mult in each loop */\n          }\n\n          /* double if not first */\n          if (!first) {\n             if ((err = ecc_projective_dbl_point(R, R, a, modulus,\n                                                              mp)) != MP_OKAY) {\n                break;\n             }\n          }\n\n          /* add if not first, otherwise copy */\n          if (!first && z) {\n             if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R, a,\n                                                     modulus, mp)) != MP_OKAY) {\n                break;\n             }\n             if (mp_iszero(R->z)) {\n                 /* When all zero then should have done an add */\n                 if (mp_iszero(R->x) && mp_iszero(R->y)) {\n                     if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[z],\n                                               R, a, modulus, mp)) != MP_OKAY) {\n                         break;\n                     }\n                 }\n                 /* When only Z zero then result is infinity */\n                 else {\n                    err = mp_set(R->x, 0);\n                    if (err != MP_OKAY) {\n                       break;\n                    }\n                    err = mp_set(R->y, 0);\n                    if (err != MP_OKAY) {\n                       break;\n                    }\n                    err = mp_copy(&fp_cache[idx].mu, R->z);\n                    if (err != MP_OKAY) {\n                       break;\n                    }\n                    first = 1;\n                 }\n             }\n          } else if (z) {\n             if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||\n                 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||\n                 (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {\n                 err = GEN_MEM_ERR;\n                 break;\n             }\n             first = 0;\n          }\n      }\n   }\n\n   if (err == MP_OKAY) {\n      (void) z; /* Acknowledge the unused assignment */\n      ForceZero(kb, KB_SIZE);\n\n      /* map R back from projective space */\n      if (map) {\n         err = ecc_map(R, modulus, mp);\n      } else {\n         err = MP_OKAY;\n      }\n   }\n\ndone:\n   /* cleanup */\n   mp_clear(&order);\n   mp_clear(&tk);\n\n#ifdef WOLFSSL_SMALL_STACK\n   XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n#endif\n\n#undef KB_SIZE\n\n   return err;\n}\n#endif\n\n#ifdef ECC_SHAMIR\n#ifndef WOLFSSL_SP_MATH\n/* perform a fixed point ECC mulmod */\nstatic int accel_fp_mul2add(int idx1, int idx2,\n                            mp_int* kA, mp_int* kB,\n                            ecc_point *R, mp_int* a,\n                            mp_int* modulus, mp_digit mp)\n{\n#define KB_SIZE 128\n\n#ifdef WOLFSSL_SMALL_STACK\n   unsigned char* kb[2] = {NULL, NULL};\n#else\n   unsigned char kb[2][KB_SIZE];\n#endif\n   int      x, err;\n   unsigned y, z, bitlen, bitpos, lut_gap, first, zA, zB;\n   mp_int tka, tkb, order;\n\n   if (mp_init_multi(&tka, &tkb, &order, NULL, NULL, NULL) != MP_OKAY)\n       return MP_INIT_E;\n\n   /* if it's smaller than modulus we fine */\n   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {\n      /* find order */\n      y = mp_unsigned_bin_size(modulus);\n      for (x = 0; ecc_sets[x].size; x++) {\n         if (y <= (unsigned)ecc_sets[x].size) break;\n      }\n\n      /* back off if we are on the 521 bit curve */\n      if (y == 66) --x;\n\n      if ((err = mp_read_radix(&order, ecc_sets[x].order,\n                                                MP_RADIX_HEX)) != MP_OKAY) {\n         goto done;\n      }\n\n      /* kA must be less than modulus */\n      if (mp_cmp(kA, &order) != MP_LT) {\n         if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) {\n            goto done;\n         }\n      } else {\n         if ((err = mp_copy(kA, &tka)) != MP_OKAY) {\n            goto done;\n         }\n      }\n   } else {\n      if ((err = mp_copy(kA, &tka)) != MP_OKAY) {\n         goto done;\n      }\n   }\n\n   /* if it's smaller than modulus we fine */\n   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {\n      /* find order */\n      y = mp_unsigned_bin_size(modulus);\n      for (x = 0; ecc_sets[x].size; x++) {\n         if (y <= (unsigned)ecc_sets[x].size) break;\n      }\n\n      /* back off if we are on the 521 bit curve */\n      if (y == 66) --x;\n\n      if ((err = mp_read_radix(&order, ecc_sets[x].order,\n                                                MP_RADIX_HEX)) != MP_OKAY) {\n         goto done;\n      }\n\n      /* kB must be less than modulus */\n      if (mp_cmp(kB, &order) != MP_LT) {\n         if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) {\n            goto done;\n         }\n      } else {\n         if ((err = mp_copy(kB, &tkb)) != MP_OKAY) {\n            goto done;\n         }\n      }\n   } else {\n      if ((err = mp_copy(kB, &tkb)) != MP_OKAY) {\n         goto done;\n      }\n   }\n\n   /* get bitlen and round up to next multiple of FP_LUT */\n   bitlen  = mp_unsigned_bin_size(modulus) << 3;\n   x       = bitlen % FP_LUT;\n   if (x) {\n      bitlen += FP_LUT - x;\n   }\n   lut_gap = bitlen / FP_LUT;\n\n   /* get the k value */\n   if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) ||\n       (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2))  ) {\n      err = BUFFER_E; goto done;\n   }\n\n   /* store k */\n#ifdef WOLFSSL_SMALL_STACK\n   kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n   if (kb[0] == NULL) {\n      err = MEMORY_E; goto done;\n   }\n#endif\n\n   XMEMSET(kb[0], 0, KB_SIZE);\n   if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) {\n      goto done;\n   }\n\n   /* let's reverse kb so it's little endian */\n   x = 0;\n   y = mp_unsigned_bin_size(&tka);\n   if (y > 0) {\n       y -= 1;\n   }\n   mp_clear(&tka);\n   while ((unsigned)x < y) {\n      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;\n      ++x; --y;\n   }\n\n   /* store b */\n#ifdef WOLFSSL_SMALL_STACK\n   kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n   if (kb[1] == NULL) {\n      err = MEMORY_E; goto done;\n   }\n#endif\n\n   XMEMSET(kb[1], 0, KB_SIZE);\n   if ((err = mp_to_unsigned_bin(&tkb, kb[1])) == MP_OKAY) {\n      x = 0;\n      y = mp_unsigned_bin_size(&tkb);\n      if (y > 0) {\n          y -= 1;\n      }\n\n      while ((unsigned)x < y) {\n         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;\n         ++x; --y;\n      }\n\n      /* at this point we can start, yipee */\n      first = 1;\n      for (x = lut_gap-1; x >= 0; x--) {\n          /* extract FP_LUT bits from kb spread out by lut_gap bits and\n             offset by x bits from the start */\n          bitpos = x;\n          for (y = zA = zB = 0; y < FP_LUT; y++) {\n             zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y;\n             zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y;\n             bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid\n                                      the mult in each loop */\n          }\n\n          /* double if not first */\n          if (!first) {\n             if ((err = ecc_projective_dbl_point(R, R, a, modulus,\n                                                              mp)) != MP_OKAY) {\n                break;\n             }\n          }\n\n          /* add if not first, otherwise copy */\n          if (!first) {\n             if (zA) {\n                if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA],\n                                               R, a, modulus, mp)) != MP_OKAY) {\n                   break;\n                }\n                if (mp_iszero(R->z)) {\n                    /* When all zero then should have done an add */\n                    if (mp_iszero(R->x) && mp_iszero(R->y)) {\n                        if ((err = ecc_projective_dbl_point(\n                                                  fp_cache[idx1].LUT[zA], R,\n                                                  a, modulus, mp)) != MP_OKAY) {\n                            break;\n                        }\n                    }\n                    /* When only Z zero then result is infinity */\n                    else {\n                       err = mp_set(R->x, 0);\n                       if (err != MP_OKAY) {\n                          break;\n                       }\n                       err = mp_set(R->y, 0);\n                       if (err != MP_OKAY) {\n                          break;\n                       }\n                       err = mp_copy(&fp_cache[idx1].mu, R->z);\n                       if (err != MP_OKAY) {\n                          break;\n                       }\n                       first = 1;\n                    }\n                }\n             }\n\n             if (zB) {\n                if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB],\n                                               R, a, modulus, mp)) != MP_OKAY) {\n                   break;\n                }\n                if (mp_iszero(R->z)) {\n                    /* When all zero then should have done an add */\n                    if (mp_iszero(R->x) && mp_iszero(R->y)) {\n                        if ((err = ecc_projective_dbl_point(\n                                                  fp_cache[idx2].LUT[zB], R,\n                                                  a, modulus, mp)) != MP_OKAY) {\n                            break;\n                        }\n                    }\n                    /* When only Z zero then result is infinity */\n                    else {\n                       err = mp_set(R->x, 0);\n                       if (err != MP_OKAY) {\n                          break;\n                       }\n                       err = mp_set(R->y, 0);\n                       if (err != MP_OKAY) {\n                          break;\n                       }\n                       err = mp_copy(&fp_cache[idx2].mu, R->z);\n                       if (err != MP_OKAY) {\n                          break;\n                       }\n                       first = 1;\n                    }\n                }\n             }\n          } else {\n             if (zA) {\n                 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||\n                     (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||\n                     (mp_copy(&fp_cache[idx1].mu,        R->z) != MP_OKAY)) {\n                     err = GEN_MEM_ERR;\n                     break;\n                 }\n                    first = 0;\n             }\n             if (zB && first == 0) {\n                if (zB) {\n                   if ((err = ecc_projective_add_point(R,\n                        fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != MP_OKAY){\n                      break;\n                   }\n                   if (mp_iszero(R->z)) {\n                       /* When all zero then should have done an add */\n                       if (mp_iszero(R->x) && mp_iszero(R->y)) {\n                           if ((err = ecc_projective_dbl_point(\n                                                  fp_cache[idx2].LUT[zB], R,\n                                                  a, modulus, mp)) != MP_OKAY) {\n                               break;\n                           }\n                       }\n                       /* When only Z zero then result is infinity */\n                       else {\n                          err = mp_set(R->x, 0);\n                          if (err != MP_OKAY) {\n                             break;\n                          }\n                          err = mp_set(R->y, 0);\n                          if (err != MP_OKAY) {\n                             break;\n                          }\n                          err = mp_copy(&fp_cache[idx2].mu, R->z);\n                          if (err != MP_OKAY) {\n                             break;\n                          }\n                          first = 1;\n                       }\n                   }\n                }\n             } else if (zB && first == 1) {\n                 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||\n                     (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||\n                     (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {\n                     err = GEN_MEM_ERR;\n                     break;\n                 }\n                    first = 0;\n             }\n          }\n      }\n   }\n\ndone:\n   /* cleanup */\n   mp_clear(&tkb);\n   mp_clear(&tka);\n   mp_clear(&order);\n\n#ifdef WOLFSSL_SMALL_STACK\n   if (kb[0])\n#endif\n      ForceZero(kb[0], KB_SIZE);\n#ifdef WOLFSSL_SMALL_STACK\n   if (kb[1])\n#endif\n      ForceZero(kb[1], KB_SIZE);\n\n#ifdef WOLFSSL_SMALL_STACK\n   XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);\n   XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);\n#endif\n\n#undef KB_SIZE\n\n    if (err != MP_OKAY)\n        return err;\n\n   return ecc_map(R, modulus, mp);\n}\n\n\n/** ECC Fixed Point mulmod global with heap hint used\n  Computes kA*A + kB*B = C using Shamir's Trick\n  A        First point to multiply\n  kA       What to multiple A by\n  B        Second point to multiply\n  kB       What to multiple B by\n  C        [out] Destination point (can overlap with A or B)\n  a        ECC curve parameter a\n  modulus  Modulus for curve\n  return MP_OKAY on success\n*/\nint ecc_mul2add(ecc_point* A, mp_int* kA,\n                ecc_point* B, mp_int* kB,\n                ecc_point* C, mp_int* a, mp_int* modulus, void* heap)\n{\n   int  idx1 = -1, idx2 = -1, err = MP_OKAY, mpInit = 0;\n   mp_digit mp;\n   mp_int   mu;\n\n   err = mp_init(&mu);\n   if (err != MP_OKAY)\n       return err;\n\n#ifndef HAVE_THREAD_LS\n   if (initMutex == 0) {\n        wc_InitMutex(&ecc_fp_lock);\n        initMutex = 1;\n   }\n   if (wc_LockMutex(&ecc_fp_lock) != 0)\n      return BAD_MUTEX_E;\n#endif /* HAVE_THREAD_LS */\n\n      /* find point */\n      idx1 = find_base(A);\n\n      /* no entry? */\n      if (idx1 == -1) {\n         /* find hole and add it */\n         if ((idx1 = find_hole()) >= 0) {\n            err = add_entry(idx1, A);\n         }\n      }\n      if (err == MP_OKAY && idx1 != -1) {\n         /* increment LRU */\n         ++(fp_cache[idx1].lru_count);\n      }\n\n      if (err == MP_OKAY)\n        /* find point */\n        idx2 = find_base(B);\n\n      if (err == MP_OKAY) {\n        /* no entry? */\n        if (idx2 == -1) {\n           /* find hole and add it */\n           if ((idx2 = find_hole()) >= 0)\n              err = add_entry(idx2, B);\n         }\n      }\n\n      if (err == MP_OKAY && idx2 != -1) {\n         /* increment LRU */\n         ++(fp_cache[idx2].lru_count);\n      }\n\n      if (err == MP_OKAY) {\n        /* if it's 2 build the LUT, if it's higher just use the LUT */\n        if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) {\n           /* compute mp */\n           err = mp_montgomery_setup(modulus, &mp);\n\n           if (err == MP_OKAY) {\n             mpInit = 1;\n             err = mp_montgomery_calc_normalization(&mu, modulus);\n           }\n\n           if (err == MP_OKAY)\n             /* build the LUT */\n               err = build_lut(idx1, a, modulus, mp, &mu);\n        }\n      }\n\n      if (err == MP_OKAY) {\n        /* if it's 2 build the LUT, if it's higher just use the LUT */\n        if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) {\n           if (mpInit == 0) {\n                /* compute mp */\n                err = mp_montgomery_setup(modulus, &mp);\n                if (err == MP_OKAY) {\n                    mpInit = 1;\n                    err = mp_montgomery_calc_normalization(&mu, modulus);\n                }\n            }\n\n            if (err == MP_OKAY)\n            /* build the LUT */\n              err = build_lut(idx2, a, modulus, mp, &mu);\n        }\n      }\n\n\n      if (err == MP_OKAY) {\n        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 &&\n                                     fp_cache[idx2].lru_count >= 2) {\n           if (mpInit == 0) {\n              /* compute mp */\n              err = mp_montgomery_setup(modulus, &mp);\n           }\n           if (err == MP_OKAY)\n             err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);\n        } else {\n           err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);\n        }\n    }\n\n#ifndef HAVE_THREAD_LS\n    wc_UnLockMutex(&ecc_fp_lock);\n#endif /* HAVE_THREAD_LS */\n    mp_clear(&mu);\n\n    return err;\n}\n#endif\n#endif /* ECC_SHAMIR */\n\n/** ECC Fixed Point mulmod global\n    k        The multiplicand\n    G        Base point to multiply\n    R        [out] Destination of product\n    a        ECC curve parameter a\n    modulus  The modulus for the curve\n    map      [boolean] If non-zero maps the point back to affine co-ordinates,\n             otherwise it's left in jacobian-montgomery form\n    return MP_OKAY if successful\n*/\nint wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,\n    mp_int* modulus, int map, void* heap)\n{\n#ifndef WOLFSSL_SP_MATH\n   int   idx, err = MP_OKAY;\n   mp_digit mp;\n   mp_int   mu;\n   int      mpSetup = 0;\n\n   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {\n       return ECC_BAD_ARG_E;\n   }\n\n   if (mp_init(&mu) != MP_OKAY)\n       return MP_INIT_E;\n\n#ifndef HAVE_THREAD_LS\n   if (initMutex == 0) {\n        wc_InitMutex(&ecc_fp_lock);\n        initMutex = 1;\n   }\n\n   if (wc_LockMutex(&ecc_fp_lock) != 0)\n      return BAD_MUTEX_E;\n#endif /* HAVE_THREAD_LS */\n\n      /* find point */\n      idx = find_base(G);\n\n      /* no entry? */\n      if (idx == -1) {\n         /* find hole and add it */\n         idx = find_hole();\n\n         if (idx >= 0)\n            err = add_entry(idx, G);\n      }\n      if (err == MP_OKAY && idx >= 0) {\n         /* increment LRU */\n         ++(fp_cache[idx].lru_count);\n      }\n\n\n      if (err == MP_OKAY) {\n        /* if it's 2 build the LUT, if it's higher just use the LUT */\n        if (idx >= 0 && fp_cache[idx].lru_count == 2) {\n           /* compute mp */\n           err = mp_montgomery_setup(modulus, &mp);\n\n           if (err == MP_OKAY) {\n             /* compute mu */\n             mpSetup = 1;\n             err = mp_montgomery_calc_normalization(&mu, modulus);\n           }\n\n           if (err == MP_OKAY)\n             /* build the LUT */\n             err = build_lut(idx, a, modulus, mp, &mu);\n        }\n      }\n\n      if (err == MP_OKAY) {\n        if (idx >= 0 && fp_cache[idx].lru_count >= 2) {\n           if (mpSetup == 0) {\n              /* compute mp */\n              err = mp_montgomery_setup(modulus, &mp);\n           }\n           if (err == MP_OKAY)\n             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);\n        } else {\n           err = normal_ecc_mulmod(k, G, R, a, modulus, map, heap);\n        }\n     }\n\n#ifndef HAVE_THREAD_LS\n    wc_UnLockMutex(&ecc_fp_lock);\n#endif /* HAVE_THREAD_LS */\n    mp_clear(&mu);\n\n    return err;\n#else\n    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {\n        return ECC_BAD_ARG_E;\n    }\n\n    return sp_ecc_mulmod_256(k, G, R, map, heap);\n#endif\n}\n\n#ifndef WOLFSSL_SP_MATH\n/* helper function for freeing the cache ...\n   must be called with the cache mutex locked */\nstatic void wc_ecc_fp_free_cache(void)\n{\n   unsigned x, y;\n   for (x = 0; x < FP_ENTRIES; x++) {\n      if (fp_cache[x].g != NULL) {\n         for (y = 0; y < (1U<<FP_LUT); y++) {\n            wc_ecc_del_point(fp_cache[x].LUT[y]);\n            fp_cache[x].LUT[y] = NULL;\n         }\n         wc_ecc_del_point(fp_cache[x].g);\n         fp_cache[x].g         = NULL;\n         mp_clear(&fp_cache[x].mu);\n         fp_cache[x].lru_count = 0;\n         fp_cache[x].lock = 0;\n      }\n   }\n}\n#endif\n\n/** Free the Fixed Point cache */\nvoid wc_ecc_fp_free(void)\n{\n#ifndef WOLFSSL_SP_MATH\n#ifndef HAVE_THREAD_LS\n   if (initMutex == 0) {\n        wc_InitMutex(&ecc_fp_lock);\n        initMutex = 1;\n   }\n\n   if (wc_LockMutex(&ecc_fp_lock) == 0) {\n#endif /* HAVE_THREAD_LS */\n\n       wc_ecc_fp_free_cache();\n\n#ifndef HAVE_THREAD_LS\n       wc_UnLockMutex(&ecc_fp_lock);\n       wc_FreeMutex(&ecc_fp_lock);\n       initMutex = 0;\n   }\n#endif /* HAVE_THREAD_LS */\n#endif\n}\n\n\n#endif /* FP_ECC */\n\n#ifdef HAVE_ECC_ENCRYPT\n\n\nenum ecCliState {\n    ecCLI_INIT      = 1,\n    ecCLI_SALT_GET  = 2,\n    ecCLI_SALT_SET  = 3,\n    ecCLI_SENT_REQ  = 4,\n    ecCLI_RECV_RESP = 5,\n    ecCLI_BAD_STATE = 99\n};\n\nenum ecSrvState {\n    ecSRV_INIT      = 1,\n    ecSRV_SALT_GET  = 2,\n    ecSRV_SALT_SET  = 3,\n    ecSRV_RECV_REQ  = 4,\n    ecSRV_SENT_RESP = 5,\n    ecSRV_BAD_STATE = 99\n};\n\n\nstruct ecEncCtx {\n    const byte* kdfSalt;   /* optional salt for kdf */\n    const byte* kdfInfo;   /* optional info for kdf */\n    const byte* macSalt;   /* optional salt for mac */\n    word32    kdfSaltSz;   /* size of kdfSalt */\n    word32    kdfInfoSz;   /* size of kdfInfo */\n    word32    macSaltSz;   /* size of macSalt */\n    void*     heap;        /* heap hint for memory used */\n    byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */\n    byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */\n    byte      encAlgo;     /* which encryption type */\n    byte      kdfAlgo;     /* which key derivation function type */\n    byte      macAlgo;     /* which mac function type */\n    byte      protocol;    /* are we REQ_RESP client or server ? */\n    byte      cliSt;       /* protocol state, for sanity checks */\n    byte      srvSt;       /* protocol state, for sanity checks */\n};\n\n\nconst byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)\n{\n    if (ctx == NULL || ctx->protocol == 0)\n        return NULL;\n\n    if (ctx->protocol == REQ_RESP_CLIENT) {\n        if (ctx->cliSt == ecCLI_INIT) {\n            ctx->cliSt =  ecCLI_SALT_GET;\n            return ctx->clientSalt;\n        }\n        else {\n            ctx->cliSt = ecCLI_BAD_STATE;\n            return NULL;\n        }\n    }\n    else if (ctx->protocol == REQ_RESP_SERVER) {\n        if (ctx->srvSt == ecSRV_INIT) {\n            ctx->srvSt =  ecSRV_SALT_GET;\n            return ctx->serverSalt;\n        }\n        else {\n            ctx->srvSt = ecSRV_BAD_STATE;\n            return NULL;\n        }\n    }\n\n    return NULL;\n}\n\n\n/* optional set info, can be called before or after set_peer_salt */\nint wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)\n{\n    if (ctx == NULL || info == 0 || sz < 0)\n        return BAD_FUNC_ARG;\n\n    ctx->kdfInfo   = info;\n    ctx->kdfInfoSz = sz;\n\n    return 0;\n}\n\n\nstatic const char* exchange_info = \"Secure Message Exchange\";\n\nint wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)\n{\n    byte tmp[EXCHANGE_SALT_SZ/2];\n    int  halfSz = EXCHANGE_SALT_SZ/2;\n\n    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)\n        return BAD_FUNC_ARG;\n\n    if (ctx->protocol == REQ_RESP_CLIENT) {\n        XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);\n        if (ctx->cliSt == ecCLI_SALT_GET)\n            ctx->cliSt =  ecCLI_SALT_SET;\n        else {\n            ctx->cliSt =  ecCLI_BAD_STATE;\n            return BAD_STATE_E;\n        }\n    }\n    else {\n        XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);\n        if (ctx->srvSt == ecSRV_SALT_GET)\n            ctx->srvSt =  ecSRV_SALT_SET;\n        else {\n            ctx->srvSt =  ecSRV_BAD_STATE;\n            return BAD_STATE_E;\n        }\n    }\n\n    /* mix half and half */\n    /* tmp stores 2nd half of client before overwrite */\n    XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz);\n    XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz);\n    XMEMCPY(ctx->serverSalt, tmp, halfSz);\n\n    ctx->kdfSalt   = ctx->clientSalt;\n    ctx->kdfSaltSz = EXCHANGE_SALT_SZ;\n\n    ctx->macSalt   = ctx->serverSalt;\n    ctx->macSaltSz = EXCHANGE_SALT_SZ;\n\n    if (ctx->kdfInfo == NULL) {\n        /* default info */\n        ctx->kdfInfo   = (const byte*)exchange_info;\n        ctx->kdfInfoSz = EXCHANGE_INFO_SZ;\n    }\n\n    return 0;\n}\n\n\nstatic int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, WC_RNG* rng)\n{\n    byte* saltBuffer = NULL;\n\n    if (ctx == NULL || rng == NULL || flags == 0)\n        return BAD_FUNC_ARG;\n\n    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;\n\n    return wc_RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ);\n}\n\n\nstatic void ecc_ctx_init(ecEncCtx* ctx, int flags)\n{\n    if (ctx) {\n        XMEMSET(ctx, 0, sizeof(ecEncCtx));\n\n        ctx->encAlgo  = ecAES_128_CBC;\n        ctx->kdfAlgo  = ecHKDF_SHA256;\n        ctx->macAlgo  = ecHMAC_SHA256;\n        ctx->protocol = (byte)flags;\n\n        if (flags == REQ_RESP_CLIENT)\n            ctx->cliSt = ecCLI_INIT;\n        if (flags == REQ_RESP_SERVER)\n            ctx->srvSt = ecSRV_INIT;\n    }\n}\n\n\n/* allow ecc context reset so user doesn't have to init/free for reuse */\nint wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)\n{\n    if (ctx == NULL || rng == NULL)\n        return BAD_FUNC_ARG;\n\n    ecc_ctx_init(ctx, ctx->protocol);\n    return ecc_ctx_set_salt(ctx, ctx->protocol, rng);\n}\n\n\necEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)\n{\n    int       ret = 0;\n    ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,\n                                                              DYNAMIC_TYPE_ECC);\n\n    if (ctx) {\n        ctx->protocol = (byte)flags;\n        ctx->heap     = heap;\n    }\n\n    ret = wc_ecc_ctx_reset(ctx, rng);\n    if (ret != 0) {\n        wc_ecc_ctx_free(ctx);\n        ctx = NULL;\n    }\n\n    return ctx;\n}\n\n\n/* alloc/init and set defaults, return new Context  */\necEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)\n{\n    return wc_ecc_ctx_new_ex(flags, rng, NULL);\n}\n\n\n/* free any resources, clear any keys */\nvoid wc_ecc_ctx_free(ecEncCtx* ctx)\n{\n    if (ctx) {\n        ForceZero(ctx, sizeof(ecEncCtx));\n        XFREE(ctx, ctx->heap, DYNAMIC_TYPE_ECC);\n    }\n}\n\n\nstatic int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,\n                             int* keysLen, word32* digestSz, word32* blockSz)\n{\n    if (ctx) {\n        switch (ctx->encAlgo) {\n            case ecAES_128_CBC:\n                *encKeySz = KEY_SIZE_128;\n                *ivSz     = IV_SIZE_128;\n                *blockSz  = AES_BLOCK_SIZE;\n                break;\n            default:\n                return BAD_FUNC_ARG;\n        }\n\n        switch (ctx->macAlgo) {\n            case ecHMAC_SHA256:\n                *digestSz = WC_SHA256_DIGEST_SIZE;\n                break;\n            default:\n                return BAD_FUNC_ARG;\n        }\n    } else\n        return BAD_FUNC_ARG;\n\n    *keysLen  = *encKeySz + *ivSz + *digestSz;\n\n    return 0;\n}\n\n\n/* ecc encrypt with shared secret run through kdf\n   ctx holds non default algos and inputs\n   msgSz should be the right size for encAlgo, i.e., already padded\n   return 0 on success */\nint wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,\n                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)\n{\n    int          ret = 0;\n    word32       blockSz;\n    word32       digestSz;\n    ecEncCtx     localCtx;\n#ifdef WOLFSSL_SMALL_STACK\n    byte*        sharedSecret;\n    byte*        keys;\n#else\n    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */\n    byte         keys[ECC_BUFSIZE];         /* max size */\n#endif\n    word32       sharedSz = ECC_MAXSIZE;\n    int          keysLen;\n    int          encKeySz;\n    int          ivSz;\n    int          offset = 0;         /* keys offset if doing msg exchange */\n    byte*        encKey;\n    byte*        encIv;\n    byte*        macKey;\n\n    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||\n                           outSz  == NULL)\n        return BAD_FUNC_ARG;\n\n    if (ctx == NULL) {  /* use defaults */\n        ecc_ctx_init(&localCtx, 0);\n        ctx = &localCtx;\n    }\n\n    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,\n                            &blockSz);\n    if (ret != 0)\n        return ret;\n\n    if (ctx->protocol == REQ_RESP_SERVER) {\n        offset = keysLen;\n        keysLen *= 2;\n\n        if (ctx->srvSt != ecSRV_RECV_REQ)\n            return BAD_STATE_E;\n\n        ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */\n    }\n    else if (ctx->protocol == REQ_RESP_CLIENT) {\n        if (ctx->cliSt != ecCLI_SALT_SET)\n            return BAD_STATE_E;\n\n        ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */\n    }\n\n    if (keysLen > ECC_BUFSIZE) /* keys size */\n        return BUFFER_E;\n\n    if ( (msgSz%blockSz) != 0)\n        return BAD_PADDING_E;\n\n    if (*outSz < (msgSz + digestSz))\n        return BUFFER_E;\n\n#ifdef WOLFSSL_SMALL_STACK\n    sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n    if (sharedSecret == NULL)\n        return MEMORY_E;\n\n    keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n    if (keys == NULL) {\n        XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n        return MEMORY_E;\n    }\n#endif\n\n    do {\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);\n        if (ret != 0)\n            break;\n    #endif\n        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);\n    } while (ret == WC_PENDING_E);\n    if (ret == 0) {\n       switch (ctx->kdfAlgo) {\n           case ecHKDF_SHA256 :\n               ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,\n                          ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,\n                          keys, keysLen);\n               break;\n\n           default:\n               ret = BAD_FUNC_ARG;\n               break;\n       }\n    }\n\n    if (ret == 0) {\n       encKey = keys + offset;\n       encIv  = encKey + encKeySz;\n       macKey = encKey + encKeySz + ivSz;\n\n       switch (ctx->encAlgo) {\n           case ecAES_128_CBC:\n               {\n                   Aes aes;\n                   ret = wc_AesInit(&aes, NULL, INVALID_DEVID);\n                   if (ret == 0) {\n                       ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,\n                                                                AES_ENCRYPTION);\n                       if (ret == 0) {\n                           ret = wc_AesCbcEncrypt(&aes, out, msg, msgSz);\n                       #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)\n                           ret = wc_AsyncWait(ret, &aes.asyncDev,\n                                              WC_ASYNC_FLAG_NONE);\n                       #endif\n                       }\n                       wc_AesFree(&aes);\n                   }\n                   if (ret != 0)\n                      break;\n               }\n               break;\n\n           default:\n               ret = BAD_FUNC_ARG;\n               break;\n       }\n    }\n\n    if (ret == 0) {\n       switch (ctx->macAlgo) {\n           case ecHMAC_SHA256:\n               {\n                   Hmac hmac;\n                   ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);\n                   if (ret == 0) {\n                       ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);\n                       if (ret == 0)\n                           ret = wc_HmacUpdate(&hmac, out, msgSz);\n                       if (ret == 0)\n                           ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);\n                       if (ret == 0)\n                           ret = wc_HmacFinal(&hmac, out+msgSz);\n                       wc_HmacFree(&hmac);\n                   }\n               }\n               break;\n\n           default:\n               ret = BAD_FUNC_ARG;\n               break;\n       }\n    }\n\n    if (ret == 0)\n       *outSz = msgSz + digestSz;\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n    XFREE(keys, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n#endif\n\n    return ret;\n}\n\n\n/* ecc decrypt with shared secret run through kdf\n   ctx holds non default algos and inputs\n   return 0 on success */\nint wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,\n                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)\n{\n    int          ret = 0;\n    word32       blockSz;\n    word32       digestSz;\n    ecEncCtx     localCtx;\n#ifdef WOLFSSL_SMALL_STACK\n    byte*        sharedSecret;\n    byte*        keys;\n#else\n    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */\n    byte         keys[ECC_BUFSIZE];         /* max size */\n#endif\n    word32       sharedSz = ECC_MAXSIZE;\n    int          keysLen;\n    int          encKeySz;\n    int          ivSz;\n    int          offset = 0;       /* in case using msg exchange */\n    byte*        encKey;\n    byte*        encIv;\n    byte*        macKey;\n\n    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||\n                           outSz  == NULL)\n        return BAD_FUNC_ARG;\n\n    if (ctx == NULL) {  /* use defaults */\n        ecc_ctx_init(&localCtx, 0);\n        ctx = &localCtx;\n    }\n\n    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,\n                            &blockSz);\n    if (ret != 0)\n        return ret;\n\n    if (ctx->protocol == REQ_RESP_CLIENT) {\n        offset = keysLen;\n        keysLen *= 2;\n\n        if (ctx->cliSt != ecCLI_SENT_REQ)\n            return BAD_STATE_E;\n\n        ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */\n    }\n    else if (ctx->protocol == REQ_RESP_SERVER) {\n        if (ctx->srvSt != ecSRV_SALT_SET)\n            return BAD_STATE_E;\n\n        ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */\n    }\n\n    if (keysLen > ECC_BUFSIZE) /* keys size */\n        return BUFFER_E;\n\n    if ( ((msgSz-digestSz) % blockSz) != 0)\n        return BAD_PADDING_E;\n\n    if (*outSz < (msgSz - digestSz))\n        return BUFFER_E;\n\n#ifdef WOLFSSL_SMALL_STACK\n    sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n    if (sharedSecret == NULL)\n        return MEMORY_E;\n\n    keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n    if (keys == NULL) {\n        XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n        return MEMORY_E;\n    }\n#endif\n\n    do {\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)\n        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);\n        if (ret != 0)\n            break;\n    #endif\n        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);\n    } while (ret == WC_PENDING_E);\n    if (ret == 0) {\n       switch (ctx->kdfAlgo) {\n           case ecHKDF_SHA256 :\n               ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,\n                          ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,\n                          keys, keysLen);\n               break;\n\n           default:\n               ret = BAD_FUNC_ARG;\n               break;\n       }\n    }\n\n    if (ret == 0) {\n       encKey = keys + offset;\n       encIv  = encKey + encKeySz;\n       macKey = encKey + encKeySz + ivSz;\n\n       switch (ctx->macAlgo) {\n           case ecHMAC_SHA256:\n           {\n               byte verify[WC_SHA256_DIGEST_SIZE];\n               Hmac hmac;\n\n               ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);\n               if (ret == 0) {\n                   ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);\n                   if (ret == 0)\n                       ret = wc_HmacUpdate(&hmac, msg, msgSz-digestSz);\n                   if (ret == 0)\n                       ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);\n                   if (ret == 0)\n                       ret = wc_HmacFinal(&hmac, verify);\n                   if (ret == 0) {\n                      if (XMEMCMP(verify, msg + msgSz - digestSz, digestSz) != 0)\n                          ret = -1;\n                   }\n\n                   wc_HmacFree(&hmac);\n               }\n               break;\n           }\n\n           default:\n               ret = BAD_FUNC_ARG;\n               break;\n       }\n    }\n\n    if (ret == 0) {\n       switch (ctx->encAlgo) {\n    #ifdef HAVE_AES_CBC\n           case ecAES_128_CBC:\n               {\n                   Aes aes;\n                   ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,\n                                                                AES_DECRYPTION);\n                   if (ret != 0)\n                       break;\n                   ret = wc_AesCbcDecrypt(&aes, out, msg, msgSz-digestSz);\n                #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)\n                   ret = wc_AsyncWait(ret, &aes.asyncDev, WC_ASYNC_FLAG_NONE);\n                #endif\n               }\n               break;\n    #endif\n           default:\n               ret = BAD_FUNC_ARG;\n               break;\n       }\n    }\n\n    if (ret == 0)\n       *outSz = msgSz - digestSz;\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n    XFREE(keys, NULL, DYNAMIC_TYPE_ECC_BUFFER);\n#endif\n\n    return ret;\n}\n\n\n#endif /* HAVE_ECC_ENCRYPT */\n\n\n#ifdef HAVE_COMP_KEY\n#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)\n\n#ifndef WOLFSSL_SP_MATH\nint do_mp_jacobi(mp_int* a, mp_int* n, int* c);\n\nint do_mp_jacobi(mp_int* a, mp_int* n, int* c)\n{\n  int      k, s, res;\n  int      r = 0; /* initialize to help static analysis out */\n  mp_digit residue;\n\n  /* if a < 0 return MP_VAL */\n  if (mp_isneg(a) == MP_YES) {\n     return MP_VAL;\n  }\n\n  /* if n <= 0 return MP_VAL */\n  if (mp_cmp_d(n, 0) != MP_GT) {\n     return MP_VAL;\n  }\n\n  /* step 1. handle case of a == 0 */\n  if (mp_iszero (a) == MP_YES) {\n     /* special case of a == 0 and n == 1 */\n     if (mp_cmp_d (n, 1) == MP_EQ) {\n       *c = 1;\n     } else {\n       *c = 0;\n     }\n     return MP_OKAY;\n  }\n\n  /* step 2.  if a == 1, return 1 */\n  if (mp_cmp_d (a, 1) == MP_EQ) {\n    *c = 1;\n    return MP_OKAY;\n  }\n\n  /* default */\n  s = 0;\n\n  /* divide out larger power of two */\n  k = mp_cnt_lsb(a);\n  res = mp_div_2d(a, k, a, NULL);\n\n  if (res == MP_OKAY) {\n    /* step 4.  if e is even set s=1 */\n    if ((k & 1) == 0) {\n      s = 1;\n    } else {\n      /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */\n      residue = n->dp[0] & 7;\n\n      if (residue == 1 || residue == 7) {\n        s = 1;\n      } else if (residue == 3 || residue == 5) {\n        s = -1;\n      }\n    }\n\n    /* step 5.  if p == 3 (mod 4) *and* a == 3 (mod 4) then s = -s */\n    if ( ((n->dp[0] & 3) == 3) && ((a->dp[0] & 3) == 3)) {\n      s = -s;\n    }\n  }\n\n  if (res == MP_OKAY) {\n    /* if a == 1 we're done */\n    if (mp_cmp_d(a, 1) == MP_EQ) {\n      *c = s;\n    } else {\n      /* n1 = n mod a */\n      res = mp_mod (n, a, n);\n      if (res == MP_OKAY)\n        res = do_mp_jacobi(n, a, &r);\n\n      if (res == MP_OKAY)\n        *c = s * r;\n    }\n  }\n\n  return res;\n}\n\n\n/* computes the jacobi c = (a | n) (or Legendre if n is prime)\n * HAC pp. 73 Algorithm 2.149\n * HAC is wrong here, as the special case of (0 | 1) is not\n * handled correctly.\n */\nint mp_jacobi(mp_int* a, mp_int* n, int* c)\n{\n    mp_int   a1, n1;\n    int      res;\n\n    /* step 3.  write a = a1 * 2**k  */\n    if ((res = mp_init_multi(&a1, &n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {\n        return res;\n    }\n\n    if ((res = mp_copy(a, &a1)) != MP_OKAY) {\n        goto done;\n    }\n\n    if ((res = mp_copy(n, &n1)) != MP_OKAY) {\n        goto done;\n    }\n\n    res = do_mp_jacobi(&a1, &n1, c);\n\ndone:\n  /* cleanup */\n  mp_clear(&n1);\n  mp_clear(&a1);\n\n  return res;\n}\n\n\n/* Solves the modular equation x^2 = n (mod p)\n * where prime number is greater than 2 (odd prime).\n * The result is returned in the third argument x\n * the function returns MP_OKAY on success, MP_VAL or another error on failure\n */\nint mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)\n{\n#ifdef SQRTMOD_USE_MOD_EXP\n  int res;\n\n  mp_int e;\n\n  res = mp_init(&e);\n  if (res == MP_OKAY)\n      res = mp_add_d(prime, 1, &e);\n  if (res == MP_OKAY)\n      res = mp_div_2d(&e, 2, &e, NULL);\n  if (res == MP_OKAY)\n      res = mp_exptmod(n, &e, prime, ret);\n\n  mp_clear(&e);\n\n  return res;\n#else\n  int res, legendre, done = 0;\n  mp_int t1, C, Q, S, Z, M, T, R, two;\n  mp_digit i;\n\n  /* first handle the simple cases n = 0 or n = 1 */\n  if (mp_cmp_d(n, 0) == MP_EQ) {\n    mp_zero(ret);\n    return MP_OKAY;\n  }\n  if (mp_cmp_d(n, 1) == MP_EQ) {\n    return mp_set(ret, 1);\n  }\n\n  /* prime must be odd */\n  if (mp_cmp_d(prime, 2) == MP_EQ) {\n    return MP_VAL;\n  }\n\n  /* is quadratic non-residue mod prime */\n  if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) {\n    return res;\n  }\n  if (legendre == -1) {\n    return MP_VAL;\n  }\n\n  if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY)\n    return res;\n\n  if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL))\n                          != MP_OKAY) {\n    mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z);\n    mp_clear(&M);\n    return res;\n  }\n\n  /* SPECIAL CASE: if prime mod 4 == 3\n   * compute directly: res = n^(prime+1)/4 mod prime\n   * Handbook of Applied Cryptography algorithm 3.36\n   */\n  res = mp_mod_d(prime, 4, &i);\n  if (res == MP_OKAY && i == 3) {\n    res = mp_add_d(prime, 1, &t1);\n\n    if (res == MP_OKAY)\n      res = mp_div_2(&t1, &t1);\n    if (res == MP_OKAY)\n      res = mp_div_2(&t1, &t1);\n    if (res == MP_OKAY)\n      res = mp_exptmod(n, &t1, prime, ret);\n\n    done = 1;\n  }\n\n  /* NOW: TonelliShanks algorithm */\n  if (res == MP_OKAY && done == 0) {\n\n    /* factor out powers of 2 from prime-1, defining Q and S\n    *                                      as: prime-1 = Q*2^S */\n    /* Q = prime - 1 */\n    res = mp_copy(prime, &Q);\n    if (res == MP_OKAY)\n      res = mp_sub_d(&Q, 1, &Q);\n\n    /* S = 0 */\n    if (res == MP_OKAY)\n      mp_zero(&S);\n\n    while (res == MP_OKAY && mp_iseven(&Q) == MP_YES) {\n      /* Q = Q / 2 */\n      res = mp_div_2(&Q, &Q);\n\n      /* S = S + 1 */\n      if (res == MP_OKAY)\n        res = mp_add_d(&S, 1, &S);\n    }\n\n    /* find a Z such that the Legendre symbol (Z|prime) == -1 */\n    /* Z = 2 */\n    if (res == MP_OKAY)\n      res = mp_set_int(&Z, 2);\n\n    while (res == MP_OKAY) {\n      res = mp_jacobi(&Z, prime, &legendre);\n      if (res == MP_OKAY && legendre == -1)\n        break;\n\n      /* Z = Z + 1 */\n      if (res == MP_OKAY)\n        res = mp_add_d(&Z, 1, &Z);\n    }\n\n    /* C = Z ^ Q mod prime */\n    if (res == MP_OKAY)\n      res = mp_exptmod(&Z, &Q, prime, &C);\n\n    /* t1 = (Q + 1) / 2 */\n    if (res == MP_OKAY)\n      res = mp_add_d(&Q, 1, &t1);\n    if (res == MP_OKAY)\n      res = mp_div_2(&t1, &t1);\n\n    /* R = n ^ ((Q + 1) / 2) mod prime */\n    if (res == MP_OKAY)\n      res = mp_exptmod(n, &t1, prime, &R);\n\n    /* T = n ^ Q mod prime */\n    if (res == MP_OKAY)\n      res = mp_exptmod(n, &Q, prime, &T);\n\n    /* M = S */\n    if (res == MP_OKAY)\n      res = mp_copy(&S, &M);\n\n    if (res == MP_OKAY)\n      res = mp_set_int(&two, 2);\n\n    while (res == MP_OKAY && done == 0) {\n      res = mp_copy(&T, &t1);\n\n      /* reduce to 1 and count */\n      i = 0;\n      while (res == MP_OKAY) {\n        if (mp_cmp_d(&t1, 1) == MP_EQ)\n            break;\n        res = mp_exptmod(&t1, &two, prime, &t1);\n        if (res == MP_OKAY)\n          i++;\n      }\n      if (res == MP_OKAY && i == 0) {\n        res = mp_copy(&R, ret);\n        done = 1;\n      }\n\n      if (done == 0) {\n        /* t1 = 2 ^ (M - i - 1) */\n        if (res == MP_OKAY)\n          res = mp_sub_d(&M, i, &t1);\n        if (res == MP_OKAY)\n          res = mp_sub_d(&t1, 1, &t1);\n        if (res == MP_OKAY)\n          res = mp_exptmod(&two, &t1, prime, &t1);\n\n        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */\n        if (res == MP_OKAY)\n          res = mp_exptmod(&C, &t1, prime, &t1);\n\n        /* C = (t1 * t1) mod prime */\n        if (res == MP_OKAY)\n          res = mp_sqrmod(&t1, prime, &C);\n\n        /* R = (R * t1) mod prime */\n        if (res == MP_OKAY)\n          res = mp_mulmod(&R, &t1, prime, &R);\n\n        /* T = (T * C) mod prime */\n        if (res == MP_OKAY)\n          res = mp_mulmod(&T, &C, prime, &T);\n\n        /* M = i */\n        if (res == MP_OKAY)\n          res = mp_set(&M, i);\n      }\n    }\n  }\n\n  /* done */\n  mp_clear(&t1);\n  mp_clear(&C);\n  mp_clear(&Q);\n  mp_clear(&S);\n  mp_clear(&Z);\n  mp_clear(&M);\n  mp_clear(&T);\n  mp_clear(&R);\n  mp_clear(&two);\n\n  return res;\n#endif\n}\n#endif\n#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */\n\n\n/* export public ECC key in ANSI X9.63 format compressed */\nstatic int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)\n{\n   word32 numlen;\n   int    ret = MP_OKAY;\n\n   if (key == NULL || out == NULL || outLen == NULL)\n       return BAD_FUNC_ARG;\n\n   if (wc_ecc_is_valid_idx(key->idx) == 0) {\n      return ECC_BAD_ARG_E;\n   }\n   numlen = key->dp->size;\n\n   if (*outLen < (1 + numlen)) {\n      *outLen = 1 + numlen;\n      return BUFFER_E;\n   }\n\n   /* store first byte */\n   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;\n\n   /* pad and store x */\n   XMEMSET(out+1, 0, numlen);\n   ret = mp_to_unsigned_bin(key->pubkey.x,\n                       out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x)));\n   *outLen = 1 + numlen;\n\n   return ret;\n}\n\n#endif /* HAVE_COMP_KEY */\n\n\nint wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)\n{\n    int x;\n\n    if (oidSum == 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* find matching OID sum (based on encoded value) */\n    for (x = 0; ecc_sets[x].size != 0; x++) {\n        if (ecc_sets[x].oidSum == oidSum) {\n            int ret = 0;\n        #ifdef HAVE_OID_ENCODING\n            /* check cache */\n            oid_cache_t* o = &ecc_oid_cache[x];\n            if (o->oidSz == 0) {\n                o->oidSz = sizeof(o->oid);\n                ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,\n                                                            o->oid, &o->oidSz);\n            }\n            if (oidSz) {\n                *oidSz = o->oidSz;\n            }\n            if (oid) {\n                *oid = o->oid;\n            }\n        #else\n            if (oidSz) {\n                *oidSz = ecc_sets[x].oidSz;\n            }\n            if (oid) {\n                *oid = ecc_sets[x].oid;\n            }\n        #endif\n            /* on success return curve id */\n            if (ret == 0) {\n                ret = ecc_sets[x].id;\n            }\n            return ret;\n        }\n    }\n\n    return NOT_COMPILED_IN;\n}\n\n#ifdef WOLFSSL_CUSTOM_CURVES\nint wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)\n{\n    if (key == NULL || dp == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    key->idx = ECC_CUSTOM_IDX;\n    key->dp = dp;\n\n    return 0;\n}\n#endif /* WOLFSSL_CUSTOM_CURVES */\n\n#ifdef HAVE_X963_KDF\n\nstatic WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)\n{\n    int i;\n\n    /* in network byte order so start at end and work back */\n    for (i = 3; i >= 0; i--) {\n        if (++inOutCtr[i])  /* we're done unless we overflow */\n            return;\n    }\n}\n\n/* ASN X9.63 Key Derivation Function (SEC1) */\nint wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,\n                const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)\n{\n    int ret, i;\n    int digestSz, copySz;\n    int remaining = outSz;\n    byte* outIdx;\n    byte  counter[4];\n    byte  tmp[WC_MAX_DIGEST_SIZE];\n\n#ifdef WOLFSSL_SMALL_STACK\n    wc_HashAlg* hash;\n#else\n    wc_HashAlg hash[1];\n#endif\n\n    if (secret == NULL || secretSz == 0 || out == NULL)\n        return BAD_FUNC_ARG;\n\n    /* X9.63 allowed algos only */\n    if (type != WC_HASH_TYPE_SHA    && type != WC_HASH_TYPE_SHA224 &&\n        type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&\n        type != WC_HASH_TYPE_SHA512)\n        return BAD_FUNC_ARG;\n\n    digestSz = wc_HashGetDigestSize(type);\n    if (digestSz < 0)\n        return digestSz;\n\n#ifdef WOLFSSL_SMALL_STACK\n    hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL,\n                                DYNAMIC_TYPE_HASHES);\n    if (hash == NULL)\n        return MEMORY_E;\n#endif\n\n    ret = wc_HashInit(hash, type);\n    if (ret != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);\n#endif\n        return ret;\n    }\n\n    outIdx = out;\n    XMEMSET(counter, 0, sizeof(counter));\n\n    for (i = 1; remaining > 0; i++) {\n\n        IncrementX963KdfCounter(counter);\n\n        ret = wc_HashUpdate(hash, type, secret, secretSz);\n        if (ret != 0) {\n            break;\n        }\n\n        ret = wc_HashUpdate(hash, type, counter, sizeof(counter));\n        if (ret != 0) {\n            break;\n        }\n\n        if (sinfo) {\n            ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);\n            if (ret != 0) {\n                break;\n            }\n        }\n\n        ret = wc_HashFinal(hash, type, tmp);\n        if (ret != 0) {\n            break;\n        }\n\n        copySz = min(remaining, digestSz);\n        XMEMCPY(outIdx, tmp, copySz);\n\n        remaining -= copySz;\n        outIdx += copySz;\n    }\n\n    wc_HashFree(hash, type);\n\n#ifdef WOLFSSL_SMALL_STACK\n     XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);\n#endif\n\n    return ret;\n}\n#endif /* HAVE_X963_KDF */\n\n#endif /* HAVE_ECC */\n"
  },
  {
    "path": "src/wolfcrypt/src/ecc_fp.c",
    "content": "/* dummy ecc_fp.c for dist */\n"
  },
  {
    "path": "src/wolfcrypt/src/ed25519.c",
    "content": "/* ed25519.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n /* Based On Daniel J Bernstein's ed25519 Public Domain ref10 work. */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n/* in case user set HAVE_ED25519 there */\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_ED25519\n\n#include <wolfssl/wolfcrypt/ed25519.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/hash.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#ifdef FREESCALE_LTC_ECC\n    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>\n#endif\n\n#if defined(HAVE_ED25519_SIGN) || defined(HAVE_ED25519_VERIFY)\n#define ED25519CTX_SIZE    32\n\nstatic const byte ed25519Ctx[ED25519CTX_SIZE+1] =\n                                             \"SigEd25519 no Ed25519 collisions\";\n#endif\n\nint wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey,\n                           word32 pubKeySz)\n{\n    int   ret = 0;\n    byte  az[ED25519_PRV_KEY_SIZE];\n#if !defined(FREESCALE_LTC_ECC)\n    ge_p3 A;\n#endif\n\n    if (key == NULL || pubKeySz != ED25519_PUB_KEY_SIZE)\n        ret = BAD_FUNC_ARG;\n\n    if (ret == 0)\n        ret = wc_Sha512Hash(key->k, ED25519_KEY_SIZE, az);\n    if (ret == 0) {\n        /* apply clamp */\n        az[0]  &= 248;\n        az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */\n        az[31] |= 64;\n\n    #ifdef FREESCALE_LTC_ECC\n        ltc_pkha_ecc_point_t publicKey = {0};\n        publicKey.X = key->pointX;\n        publicKey.Y = key->pointY;\n        LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), az,\n            ED25519_KEY_SIZE, &publicKey, kLTC_Ed25519 /* result on Ed25519 */);\n        LTC_PKHA_Ed25519_Compress(&publicKey, pubKey);\n    #else\n        ge_scalarmult_base(&A, az);\n        ge_p3_tobytes(pubKey, &A);\n    #endif\n    }\n\n    return ret;\n}\n\n/* generate an ed25519 key pair.\n * returns 0 on success\n */\nint wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key)\n{\n    int ret;\n\n    if (rng == NULL || key == NULL)\n        return BAD_FUNC_ARG;\n\n    /* ed25519 has 32 byte key sizes */\n    if (keySz != ED25519_KEY_SIZE)\n        return BAD_FUNC_ARG;\n\n    ret  = wc_RNG_GenerateBlock(rng, key->k, ED25519_KEY_SIZE);\n    if (ret != 0)\n        return ret;\n\n    ret = wc_ed25519_make_public(key, key->p, ED25519_PUB_KEY_SIZE);\n    if (ret != 0) {\n        ForceZero(key->k, ED25519_KEY_SIZE);\n        return ret;\n    }\n\n    /* put public key after private key, on the same buffer */\n    XMEMMOVE(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE);\n\n    key->pubKeySet = 1;\n\n    return ret;\n}\n\n\n#ifdef HAVE_ED25519_SIGN\n/*\n    in          contains the message to sign\n    inLen       is the length of the message to sign\n    out         is the buffer to write the signature\n    outLen      [in/out] input size of out buf\n                          output gets set as the final length of out\n    key         is the ed25519 key to use when signing\n    type        one of Ed25519, Ed25519ctx or Ed25519ph\n    context     extra signing data\n    contextLen  length of extra signing data\n    return 0 on success\n */\nstatic int ed25519_sign_msg(const byte* in, word32 inLen, byte* out,\n                            word32 *outLen, ed25519_key* key, byte type,\n                            const byte* context, byte contextLen)\n{\n#ifdef FREESCALE_LTC_ECC\n    byte   tempBuf[ED25519_PRV_KEY_SIZE];\n#else\n    ge_p3  R;\n#endif\n    byte   nonce[WC_SHA512_DIGEST_SIZE];\n    byte   hram[WC_SHA512_DIGEST_SIZE];\n    byte   az[ED25519_PRV_KEY_SIZE];\n    wc_Sha512 sha;\n    int    ret;\n\n    /* sanity check on arguments */\n    if (in == NULL || out == NULL || outLen == NULL || key == NULL ||\n                                         (context == NULL && contextLen != 0)) {\n        return BAD_FUNC_ARG;\n    }\n    if (!key->pubKeySet)\n        return BAD_FUNC_ARG;\n\n    /* check and set up out length */\n    if (*outLen < ED25519_SIG_SIZE) {\n        *outLen = ED25519_SIG_SIZE;\n        return BUFFER_E;\n    }\n    *outLen = ED25519_SIG_SIZE;\n\n    /* step 1: create nonce to use where nonce is r in\n       r = H(h_b, ... ,h_2b-1,M) */\n    ret = wc_Sha512Hash(key->k, ED25519_KEY_SIZE, az);\n    if (ret != 0)\n        return ret;\n\n    /* apply clamp */\n    az[0]  &= 248;\n    az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */\n    az[31] |= 64;\n\n    ret = wc_InitSha512(&sha);\n    if (ret != 0)\n        return ret;\n    if (type == Ed25519ctx || type == Ed25519ph) {\n        ret = wc_Sha512Update(&sha, ed25519Ctx, ED25519CTX_SIZE);\n        if (ret == 0)\n            ret = wc_Sha512Update(&sha, &type, sizeof(type));\n        if (ret == 0)\n            ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen));\n        if (ret == 0 && context != NULL)\n            ret = wc_Sha512Update(&sha, context, contextLen);\n    }\n    if (ret == 0)\n        ret = wc_Sha512Update(&sha, az + ED25519_KEY_SIZE, ED25519_KEY_SIZE);\n    if (ret == 0)\n        ret = wc_Sha512Update(&sha, in, inLen);\n    if (ret == 0)\n        ret = wc_Sha512Final(&sha, nonce);\n    wc_Sha512Free(&sha);\n    if (ret != 0)\n        return ret;\n\n#ifdef FREESCALE_LTC_ECC\n    ltc_pkha_ecc_point_t ltcPoint = {0};\n    ltcPoint.X = &tempBuf[0];\n    ltcPoint.Y = &tempBuf[32];\n    LTC_PKHA_sc_reduce(nonce);\n    LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), nonce,\n           ED25519_KEY_SIZE, &ltcPoint, kLTC_Ed25519 /* result on Ed25519 */);\n    LTC_PKHA_Ed25519_Compress(&ltcPoint, out);\n#else\n    sc_reduce(nonce);\n\n    /* step 2: computing R = rB where rB is the scalar multiplication of\n       r and B */\n    ge_scalarmult_base(&R,nonce);\n    ge_p3_tobytes(out,&R);\n#endif\n\n    /* step 3: hash R + public key + message getting H(R,A,M) then\n       creating S = (r + H(R,A,M)a) mod l */\n    ret = wc_InitSha512(&sha);\n    if (ret != 0)\n        return ret;\n    if (type == Ed25519ctx || type == Ed25519ph) {\n        ret = wc_Sha512Update(&sha, ed25519Ctx, ED25519CTX_SIZE);\n        if (ret == 0)\n            ret = wc_Sha512Update(&sha, &type, sizeof(type));\n        if (ret == 0)\n            ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen));\n        if (ret == 0 && context != NULL)\n            ret = wc_Sha512Update(&sha, context, contextLen);\n    }\n    if (ret == 0)\n        ret = wc_Sha512Update(&sha, out, ED25519_SIG_SIZE/2);\n    if (ret == 0)\n        ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);\n    if (ret == 0)\n        ret = wc_Sha512Update(&sha, in, inLen);\n    if (ret == 0)\n        ret = wc_Sha512Final(&sha, hram);\n    wc_Sha512Free(&sha);\n    if (ret != 0)\n        return ret;\n\n#ifdef FREESCALE_LTC_ECC\n    LTC_PKHA_sc_reduce(hram);\n    LTC_PKHA_sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce);\n#else\n    sc_reduce(hram);\n    sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce);\n#endif\n\n    return ret;\n}\n\n/*\n    in     contains the message to sign\n    inLen  is the length of the message to sign\n    out    is the buffer to write the signature\n    outLen [in/out] input size of out buf\n                     output gets set as the final length of out\n    key    is the ed25519 key to use when signing\n    return 0 on success\n */\nint wc_ed25519_sign_msg(const byte* in, word32 inLen, byte* out,\n                        word32 *outLen, ed25519_key* key)\n{\n    return ed25519_sign_msg(in, inLen, out, outLen, key, (byte)Ed25519, NULL, 0);\n}\n\n/*\n    in          contains the message to sign\n    inLen       is the length of the message to sign\n    out         is the buffer to write the signature\n    outLen      [in/out] input size of out buf\n                          output gets set as the final length of out\n    key         is the ed25519 key to use when signing\n    context     extra signing data\n    contextLen  length of extra signing data\n    return 0 on success\n */\nint wc_ed25519ctx_sign_msg(const byte* in, word32 inLen, byte* out,\n                           word32 *outLen, ed25519_key* key,\n                           const byte* context, byte contextLen)\n{\n    return ed25519_sign_msg(in, inLen, out, outLen, key, Ed25519ctx, context,\n                                                                    contextLen);\n}\n\n/*\n    hash        contains the SHA-512 hash of the message to sign\n    hashLen     is the length of the SHA-512 hash of the message to sign\n    out         is the buffer to write the signature\n    outLen      [in/out] input size of out buf\n                          output gets set as the final length of out\n    key         is the ed25519 key to use when signing\n    context     extra signing data\n    contextLen  length of extra signing data\n    return 0 on success\n */\nint wc_ed25519ph_sign_hash(const byte* hash, word32 hashLen, byte* out,\n                           word32 *outLen, ed25519_key* key,\n                           const byte* context, byte contextLen)\n{\n    return ed25519_sign_msg(hash, hashLen, out, outLen, key, Ed25519ph, context,\n                                                                    contextLen);\n}\n\n/*\n    in          contains the message to sign\n    inLen       is the length of the message to sign\n    out         is the buffer to write the signature\n    outLen      [in/out] input size of out buf\n                          output gets set as the final length of out\n    key         is the ed25519 key to use when signing\n    context     extra signing data\n    contextLen  length of extra signing data\n    return 0 on success\n */\nint wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out,\n                          word32 *outLen, ed25519_key* key,\n                          const byte* context, byte contextLen)\n{\n    int  ret;\n    byte hash[WC_SHA512_DIGEST_SIZE];\n\n    ret = wc_Sha512Hash(in, inLen, hash);\n    if (ret != 0)\n        return ret;\n\n    return wc_ed25519ph_sign_hash(hash, sizeof(hash), out, outLen, key, context,\n                                                                    contextLen);\n}\n#endif /* HAVE_ED25519_SIGN */\n\n#ifdef HAVE_ED25519_VERIFY\n\n/*\n   sig     is array of bytes containing the signature\n   sigLen  is the length of sig byte array\n   msg     the array of bytes containing the message\n   msgLen  length of msg array\n   res     will be 1 on successful verify and 0 on unsuccessful\n   key     Ed25519 public key\n   return  0 and res of 1 on success\n*/\nstatic int ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg,\n                              word32 msgLen, int* res, ed25519_key* key,\n                              byte type, const byte* context, byte contextLen)\n{\n    byte   rcheck[ED25519_KEY_SIZE];\n    byte   h[WC_SHA512_DIGEST_SIZE];\n#ifndef FREESCALE_LTC_ECC\n    ge_p3  A;\n    ge_p2  R;\n#endif\n    int    ret;\n    wc_Sha512 sha;\n\n    /* sanity check on arguments */\n    if (sig == NULL || msg == NULL || res == NULL || key == NULL ||\n                                         (context == NULL && contextLen != 0)) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* set verification failed by default */\n    *res = 0;\n\n    /* check on basics needed to verify signature */\n    if (sigLen < ED25519_SIG_SIZE || (sig[ED25519_SIG_SIZE-1] & 224))\n        return BAD_FUNC_ARG;\n\n    /* uncompress A (public key), test if valid, and negate it */\n#ifndef FREESCALE_LTC_ECC\n    if (ge_frombytes_negate_vartime(&A, key->p) != 0)\n        return BAD_FUNC_ARG;\n#endif\n\n    /* find H(R,A,M) and store it as h */\n    ret  = wc_InitSha512(&sha);\n    if (ret != 0)\n        return ret;\n    if (type == Ed25519ctx || type == Ed25519ph) {\n        ret = wc_Sha512Update(&sha, ed25519Ctx, ED25519CTX_SIZE);\n        if (ret == 0)\n            ret = wc_Sha512Update(&sha, &type, sizeof(type));\n        if (ret == 0)\n            ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen));\n        if (ret == 0 && context != NULL)\n            ret = wc_Sha512Update(&sha, context, contextLen);\n    }\n    if (ret == 0)\n        ret = wc_Sha512Update(&sha, sig, ED25519_SIG_SIZE/2);\n    if (ret == 0)\n        ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);\n    if (ret == 0)\n        ret = wc_Sha512Update(&sha, msg, msgLen);\n    if (ret == 0)\n        ret = wc_Sha512Final(&sha,  h);\n    wc_Sha512Free(&sha);\n    if (ret != 0)\n        return ret;\n\n#ifdef FREESCALE_LTC_ECC\n    LTC_PKHA_sc_reduce(h);\n    LTC_PKHA_SignatureForVerify(rcheck, h, sig + (ED25519_SIG_SIZE/2), key);\n#else\n    sc_reduce(h);\n\n    /*\n       Uses a fast single-signature verification SB = R + H(R,A,M)A becomes\n       SB - H(R,A,M)A saving decompression of R\n    */\n    ret = ge_double_scalarmult_vartime(&R, h, &A, sig + (ED25519_SIG_SIZE/2));\n    if (ret != 0)\n        return ret;\n\n    ge_tobytes(rcheck, &R);\n#endif /* FREESCALE_LTC_ECC */\n\n    /* comparison of R created to R in sig */\n    ret = ConstantCompare(rcheck, sig, ED25519_SIG_SIZE/2);\n    if (ret != 0)\n        return SIG_VERIFY_E;\n\n    /* set the verification status */\n    *res = 1;\n\n    return ret;\n}\n\n/*\n   sig     is array of bytes containing the signature\n   sigLen  is the length of sig byte array\n   msg     the array of bytes containing the message\n   msgLen  length of msg array\n   res     will be 1 on successful verify and 0 on unsuccessful\n   key     Ed25519 public key\n   return  0 and res of 1 on success\n*/\nint wc_ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg,\n                          word32 msgLen, int* res, ed25519_key* key)\n{\n    return ed25519_verify_msg(sig, sigLen, msg, msgLen, res, key, (byte)Ed25519,\n                                                                       NULL, 0);\n}\n\n/*\n   sig         is array of bytes containing the signature\n   sigLen      is the length of sig byte array\n   msg         the array of bytes containing the message\n   msgLen      length of msg array\n   res         will be 1 on successful verify and 0 on unsuccessful\n   key         Ed25519 public key\n   context     extra sigining data\n   contextLen  length of extra sigining data\n   return  0 and res of 1 on success\n*/\nint wc_ed25519ctx_verify_msg(const byte* sig, word32 sigLen, const byte* msg,\n                             word32 msgLen, int* res, ed25519_key* key,\n                             const byte* context, byte contextLen)\n{\n    return ed25519_verify_msg(sig, sigLen, msg, msgLen, res, key, Ed25519ctx,\n                                                           context, contextLen);\n}\n\n/*\n   sig         is array of bytes containing the signature\n   sigLen      is the length of sig byte array\n   hash        the array of bytes containing the SHA-512 hash of the message\n   hashLen     length of hash array\n   res         will be 1 on successful verify and 0 on unsuccessful\n   key         Ed25519 public key\n   context     extra sigining data\n   contextLen  length of extra sigining data\n   return  0 and res of 1 on success\n*/\nint wc_ed25519ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash,\n                             word32 hashLen, int* res, ed25519_key* key,\n                             const byte* context, byte contextLen)\n{\n    return ed25519_verify_msg(sig, sigLen, hash, hashLen, res, key, Ed25519ph,\n                                                           context, contextLen);\n}\n\n/*\n   sig         is array of bytes containing the signature\n   sigLen      is the length of sig byte array\n   msg         the array of bytes containing the message\n   msgLen      length of msg array\n   res         will be 1 on successful verify and 0 on unsuccessful\n   key         Ed25519 public key\n   context     extra sigining data\n   contextLen  length of extra sigining data\n   return  0 and res of 1 on success\n*/\nint wc_ed25519ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,\n                            word32 msgLen, int* res, ed25519_key* key,\n                            const byte* context, byte contextLen)\n{\n    int  ret;\n    byte hash[WC_SHA512_DIGEST_SIZE];\n\n    ret = wc_Sha512Hash(msg, msgLen, hash);\n    if (ret != 0)\n        return ret;\n\n    return wc_ed25519ph_verify_hash(sig, sigLen, hash, sizeof(hash), res, key,\n                                                           context, contextLen);\n}\n#endif /* HAVE_ED25519_VERIFY */\n\n\n/* initialize information and memory for key */\nint wc_ed25519_init(ed25519_key* key)\n{\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    XMEMSET(key, 0, sizeof(ed25519_key));\n\n#ifndef FREESCALE_LTC_ECC\n    fe_init();\n#endif\n\n    return 0;\n}\n\n\n/* clear memory of key */\nvoid wc_ed25519_free(ed25519_key* key)\n{\n    if (key == NULL)\n        return;\n\n    ForceZero(key, sizeof(ed25519_key));\n}\n\n\n#ifdef HAVE_ED25519_KEY_EXPORT\n\n/*\n    outLen should contain the size of out buffer when input. outLen is than set\n    to the final output length.\n    returns 0 on success\n */\nint wc_ed25519_export_public(ed25519_key* key, byte* out, word32* outLen)\n{\n    /* sanity check on arguments */\n    if (key == NULL || out == NULL || outLen == NULL)\n        return BAD_FUNC_ARG;\n\n    if (*outLen < ED25519_PUB_KEY_SIZE) {\n        *outLen = ED25519_PUB_KEY_SIZE;\n        return BUFFER_E;\n    }\n\n    *outLen = ED25519_PUB_KEY_SIZE;\n    XMEMCPY(out, key->p, ED25519_PUB_KEY_SIZE);\n\n    return 0;\n}\n\n#endif /* HAVE_ED25519_KEY_EXPORT */\n\n\n#ifdef HAVE_ED25519_KEY_IMPORT\n/*\n    Imports a compressed/uncompressed public key.\n    in    the byte array containing the public key\n    inLen the length of the byte array being passed in\n    key   ed25519 key struct to put the public key in\n */\nint wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)\n{\n    int    ret;\n\n    /* sanity check on arguments */\n    if (in == NULL || key == NULL)\n        return BAD_FUNC_ARG;\n\n    if (inLen < ED25519_PUB_KEY_SIZE)\n        return BAD_FUNC_ARG;\n\n    /* compressed prefix according to draft\n       http://www.ietf.org/id/draft-koch-eddsa-for-openpgp-02.txt */\n    if (in[0] == 0x40 && inLen > ED25519_PUB_KEY_SIZE) {\n        /* key is stored in compressed format so just copy in */\n        XMEMCPY(key->p, (in + 1), ED25519_PUB_KEY_SIZE);\n#ifdef FREESCALE_LTC_ECC\n        /* recover X coordinate */\n        ltc_pkha_ecc_point_t pubKey;\n        pubKey.X = key->pointX;\n        pubKey.Y = key->pointY;\n        LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);\n#endif\n        key->pubKeySet = 1;\n        return 0;\n    }\n\n    /* importing uncompressed public key */\n    if (in[0] == 0x04 && inLen > 2*ED25519_PUB_KEY_SIZE) {\n#ifdef FREESCALE_LTC_ECC\n        /* reverse bytes for little endian byte order */\n        for (int i = 0; i < ED25519_KEY_SIZE; i++)\n        {\n            key->pointX[i] = *(in + ED25519_KEY_SIZE - i);\n            key->pointY[i] = *(in + 2*ED25519_KEY_SIZE - i);\n        }\n        XMEMCPY(key->p, key->pointY, ED25519_KEY_SIZE);\n        ret = 0;\n#else\n        /* pass in (x,y) and store compressed key */\n        ret = ge_compress_key(key->p, in+1,\n                              in+1+ED25519_PUB_KEY_SIZE, ED25519_PUB_KEY_SIZE);\n#endif /* FREESCALE_LTC_ECC */\n        if (ret == 0)\n            key->pubKeySet = 1;\n        return ret;\n    }\n\n    /* if not specified compressed or uncompressed check key size\n       if key size is equal to compressed key size copy in key */\n    if (inLen == ED25519_PUB_KEY_SIZE) {\n        XMEMCPY(key->p, in, ED25519_PUB_KEY_SIZE);\n#ifdef FREESCALE_LTC_ECC\n        /* recover X coordinate */\n        ltc_pkha_ecc_point_t pubKey;\n        pubKey.X = key->pointX;\n        pubKey.Y = key->pointY;\n        LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);\n#endif\n        key->pubKeySet = 1;\n        return 0;\n    }\n\n    /* bad public key format */\n    return BAD_FUNC_ARG;\n}\n\n\n/*\n    For importing a private key.\n */\nint wc_ed25519_import_private_only(const byte* priv, word32 privSz,\n                                                               ed25519_key* key)\n{\n    /* sanity check on arguments */\n    if (priv == NULL || key == NULL)\n        return BAD_FUNC_ARG;\n\n    /* key size check */\n    if (privSz < ED25519_KEY_SIZE)\n        return BAD_FUNC_ARG;\n\n    XMEMCPY(key->k, priv, ED25519_KEY_SIZE);\n\n    return 0;\n}\n\n/*\n    For importing a private key and its associated public key.\n */\nint wc_ed25519_import_private_key(const byte* priv, word32 privSz,\n                                const byte* pub, word32 pubSz, ed25519_key* key)\n{\n    int    ret;\n\n    /* sanity check on arguments */\n    if (priv == NULL || pub == NULL || key == NULL)\n        return BAD_FUNC_ARG;\n\n    /* key size check */\n    if (privSz < ED25519_KEY_SIZE || pubSz < ED25519_PUB_KEY_SIZE)\n        return BAD_FUNC_ARG;\n\n    /* import public key */\n    ret = wc_ed25519_import_public(pub, pubSz, key);\n    if (ret != 0)\n        return ret;\n\n    /* make the private key (priv + pub) */\n    XMEMCPY(key->k, priv, ED25519_KEY_SIZE);\n    XMEMCPY(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE);\n\n    return ret;\n}\n\n#endif /* HAVE_ED25519_KEY_IMPORT */\n\n\n#ifdef HAVE_ED25519_KEY_EXPORT\n\n/*\n export private key only (secret part so 32 bytes)\n outLen should contain the size of out buffer when input. outLen is than set\n to the final output length.\n returns 0 on success\n */\nint wc_ed25519_export_private_only(ed25519_key* key, byte* out, word32* outLen)\n{\n    /* sanity checks on arguments */\n    if (key == NULL || out == NULL || outLen == NULL)\n        return BAD_FUNC_ARG;\n\n    if (*outLen < ED25519_KEY_SIZE) {\n        *outLen = ED25519_KEY_SIZE;\n        return BUFFER_E;\n    }\n\n    *outLen = ED25519_KEY_SIZE;\n    XMEMCPY(out, key->k, ED25519_KEY_SIZE);\n\n    return 0;\n}\n\n/*\n export private key, including public part\n outLen should contain the size of out buffer when input. outLen is than set\n to the final output length.\n returns 0 on success\n */\nint wc_ed25519_export_private(ed25519_key* key, byte* out, word32* outLen)\n{\n    /* sanity checks on arguments */\n    if (key == NULL || out == NULL || outLen == NULL)\n        return BAD_FUNC_ARG;\n\n    if (*outLen < ED25519_PRV_KEY_SIZE) {\n        *outLen = ED25519_PRV_KEY_SIZE;\n        return BUFFER_E;\n    }\n\n    *outLen = ED25519_PRV_KEY_SIZE;\n    XMEMCPY(out, key->k, ED25519_PRV_KEY_SIZE);\n\n    return 0;\n}\n\n/* export full private key and public key\n   return 0 on success\n */\nint wc_ed25519_export_key(ed25519_key* key,\n                          byte* priv, word32 *privSz,\n                          byte* pub, word32 *pubSz)\n{\n    int ret;\n\n    /* export 'full' private part */\n    ret = wc_ed25519_export_private(key, priv, privSz);\n    if (ret != 0)\n        return ret;\n\n    /* export public part */\n    ret = wc_ed25519_export_public(key, pub, pubSz);\n\n    return ret;\n}\n\n#endif /* HAVE_ED25519_KEY_EXPORT */\n\n/* check the private and public keys match */\nint wc_ed25519_check_key(ed25519_key* key)\n{\n    int ret = 0;\n    unsigned char pubKey[ED25519_PUB_KEY_SIZE];\n\n    if (!key->pubKeySet)\n        ret = PUBLIC_KEY_E;\n    if (ret == 0)\n        ret = wc_ed25519_make_public(key, pubKey, sizeof(pubKey));\n    if (ret == 0 && XMEMCMP(pubKey, key->p, ED25519_PUB_KEY_SIZE) != 0)\n        ret = PUBLIC_KEY_E;\n\n    return ret;\n}\n\n/* returns the private key size (secret only) in bytes */\nint wc_ed25519_size(ed25519_key* key)\n{\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    return ED25519_KEY_SIZE;\n}\n\n/* returns the private key size (secret + public) in bytes */\nint wc_ed25519_priv_size(ed25519_key* key)\n{\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    return ED25519_PRV_KEY_SIZE;\n}\n\n/* returns the compressed key size in bytes (public key) */\nint wc_ed25519_pub_size(ed25519_key* key)\n{\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    return ED25519_PUB_KEY_SIZE;\n}\n\n/* returns the size of signature in bytes */\nint wc_ed25519_sig_size(ed25519_key* key)\n{\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    return ED25519_SIG_SIZE;\n}\n\n#endif /* HAVE_ED25519 */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/error.c",
    "content": "/* error.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#include <wolfssl/wolfcrypt/error-crypt.h>\n\n#ifdef _MSC_VER\n    /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */\n    #pragma warning(disable: 4996)\n#endif\n\n#ifndef NO_ERROR_STRINGS\nconst char* wc_GetErrorString(int error)\n{\n    switch (error) {\n\n    case OPEN_RAN_E :\n        return \"opening random device error\";\n\n    case READ_RAN_E :\n        return \"reading random device error\";\n\n    case WINCRYPT_E :\n        return \"windows crypt init error\";\n\n    case CRYPTGEN_E :\n        return \"windows crypt generation error\";\n\n    case RAN_BLOCK_E :\n        return \"random device read would block error\";\n\n    case BAD_MUTEX_E :\n        return \"Bad mutex, operation failed\";\n\n    case WC_TIMEOUT_E:\n        return \"Timeout error\";\n\n    case WC_PENDING_E:\n        return \"wolfCrypt Operation Pending (would block / eagain) error\";\n\n    case WC_NOT_PENDING_E:\n        return \"wolfCrypt operation not pending error\";\n\n    case MP_INIT_E :\n        return \"mp_init error state\";\n\n    case MP_READ_E :\n        return \"mp_read error state\";\n\n    case MP_EXPTMOD_E :\n        return \"mp_exptmod error state\";\n\n    case MP_TO_E :\n        return \"mp_to_xxx error state, can't convert\";\n\n    case MP_SUB_E :\n        return \"mp_sub error state, can't subtract\";\n\n    case MP_ADD_E :\n        return \"mp_add error state, can't add\";\n\n    case MP_MUL_E :\n        return \"mp_mul error state, can't multiply\";\n\n    case MP_MULMOD_E :\n        return \"mp_mulmod error state, can't multiply mod\";\n\n    case MP_MOD_E :\n        return \"mp_mod error state, can't mod\";\n\n    case MP_INVMOD_E :\n        return \"mp_invmod error state, can't inv mod\";\n\n    case MP_CMP_E :\n        return \"mp_cmp error state\";\n\n    case MP_ZERO_E :\n        return \"mp zero result, not expected\";\n\n    case MEMORY_E :\n        return \"out of memory error\";\n\n    case VAR_STATE_CHANGE_E :\n        return \"Variable state modified by different thread\";\n\n    case RSA_WRONG_TYPE_E :\n        return \"RSA wrong block type for RSA function\";\n\n    case RSA_BUFFER_E :\n        return \"RSA buffer error, output too small or input too big\";\n\n    case BUFFER_E :\n        return \"Buffer error, output too small or input too big\";\n\n    case ALGO_ID_E :\n        return \"Setting Cert AlgoID error\";\n\n    case PUBLIC_KEY_E :\n        return \"Setting Cert Public Key error\";\n\n    case DATE_E :\n        return \"Setting Cert Date validity error\";\n\n    case SUBJECT_E :\n        return \"Setting Cert Subject name error\";\n\n    case ISSUER_E :\n        return \"Setting Cert Issuer name error\";\n\n    case CA_TRUE_E :\n        return \"Setting basic constraint CA true error\";\n\n    case EXTENSIONS_E :\n        return \"Setting extensions error\";\n\n    case ASN_PARSE_E :\n        return \"ASN parsing error, invalid input\";\n\n    case ASN_VERSION_E :\n        return \"ASN version error, invalid number\";\n\n    case ASN_GETINT_E :\n        return \"ASN get big int error, invalid data\";\n\n    case ASN_RSA_KEY_E :\n        return \"ASN key init error, invalid input\";\n\n    case ASN_OBJECT_ID_E :\n        return \"ASN object id error, invalid id\";\n\n    case ASN_TAG_NULL_E :\n        return \"ASN tag error, not null\";\n\n    case ASN_EXPECT_0_E :\n        return \"ASN expect error, not zero\";\n\n    case ASN_BITSTR_E :\n        return \"ASN bit string error, wrong id\";\n\n    case ASN_UNKNOWN_OID_E :\n        return \"ASN oid error, unknown sum id\";\n\n    case ASN_DATE_SZ_E :\n        return \"ASN date error, bad size\";\n\n    case ASN_BEFORE_DATE_E :\n        return \"ASN date error, current date before\";\n\n    case ASN_AFTER_DATE_E :\n        return \"ASN date error, current date after\";\n\n    case ASN_SIG_OID_E :\n        return \"ASN signature error, mismatched oid\";\n\n    case ASN_TIME_E :\n        return \"ASN time error, unknown time type\";\n\n    case ASN_INPUT_E :\n        return \"ASN input error, not enough data\";\n\n    case ASN_SIG_CONFIRM_E :\n        return \"ASN sig error, confirm failure\";\n\n    case ASN_SIG_HASH_E :\n        return \"ASN sig error, unsupported hash type\";\n\n    case ASN_SIG_KEY_E :\n        return \"ASN sig error, unsupported key type\";\n\n    case ASN_DH_KEY_E :\n        return \"ASN key init error, invalid input\";\n\n    case ASN_NTRU_KEY_E :\n        return \"ASN NTRU key decode error, invalid input\";\n\n    case ASN_CRIT_EXT_E:\n        return \"X.509 Critical extension ignored or invalid\";\n\n    case ASN_ALT_NAME_E:\n        return \"ASN alternate name error\";\n\n    case ECC_BAD_ARG_E :\n        return \"ECC input argument wrong type, invalid input\";\n\n    case ASN_ECC_KEY_E :\n        return \"ECC ASN1 bad key data, invalid input\";\n\n    case ECC_CURVE_OID_E :\n        return \"ECC curve sum OID unsupported, invalid input\";\n\n    case BAD_FUNC_ARG :\n        return \"Bad function argument\";\n\n    case NOT_COMPILED_IN :\n        return \"Feature not compiled in\";\n\n    case UNICODE_SIZE_E :\n        return \"Unicode password too big\";\n\n    case NO_PASSWORD :\n        return \"No password provided by user\";\n\n    case ALT_NAME_E :\n        return \"Alt Name problem, too big\";\n\n    case AES_GCM_AUTH_E:\n        return \"AES-GCM Authentication check fail\";\n\n    case AES_CCM_AUTH_E:\n        return \"AES-CCM Authentication check fail\";\n\n    case ASYNC_INIT_E:\n        return \"Async Init error\";\n\n    case COMPRESS_INIT_E:\n        return \"Compress Init error\";\n\n    case COMPRESS_E:\n        return \"Compress error\";\n\n    case DECOMPRESS_INIT_E:\n        return \"DeCompress Init error\";\n\n    case DECOMPRESS_E:\n        return \"DeCompress error\";\n\n    case BAD_ALIGN_E:\n        return \"Bad alignment error, no alloc help\";\n\n    case ASN_NO_SIGNER_E :\n        return \"ASN no signer error to confirm failure\";\n\n    case ASN_CRL_CONFIRM_E :\n        return \"ASN CRL sig error, confirm failure\";\n\n    case ASN_CRL_NO_SIGNER_E :\n        return \"ASN CRL no signer error to confirm failure\";\n\n    case ASN_OCSP_CONFIRM_E :\n        return \"ASN OCSP sig error, confirm failure\";\n\n    case ASN_NO_PEM_HEADER:\n        return \"ASN no PEM Header Error\";\n\n    case BAD_STATE_E:\n        return \"Bad state operation\";\n\n    case BAD_PADDING_E:\n        return \"Bad padding, message wrong length\";\n\n    case REQ_ATTRIBUTE_E:\n        return \"Setting cert request attributes error\";\n\n    case PKCS7_OID_E:\n        return \"PKCS#7 error: mismatched OID value\";\n\n    case PKCS7_RECIP_E:\n        return \"PKCS#7 error: no matching recipient found\";\n\n    case WC_PKCS7_WANT_READ_E:\n        return \"PKCS#7 operations wants more input, call again\";\n\n    case FIPS_NOT_ALLOWED_E:\n        return \"FIPS mode not allowed error\";\n\n    case ASN_NAME_INVALID_E:\n        return \"Name Constraint error\";\n\n    case RNG_FAILURE_E:\n        return \"Random Number Generator failed\";\n\n    case HMAC_MIN_KEYLEN_E:\n        return \"FIPS Mode HMAC Minimum Key Length error\";\n\n    case RSA_PAD_E:\n        return \"Rsa Padding error\";\n\n    case LENGTH_ONLY_E:\n        return \"Output length only set, not for other use error\";\n\n    case IN_CORE_FIPS_E:\n        return \"In Core Integrity check FIPS error\";\n\n    case AES_KAT_FIPS_E:\n        return \"AES Known Answer Test check FIPS error\";\n\n    case DES3_KAT_FIPS_E:\n        return \"DES3 Known Answer Test check FIPS error\";\n\n    case HMAC_KAT_FIPS_E:\n        return \"HMAC Known Answer Test check FIPS error\";\n\n    case RSA_KAT_FIPS_E:\n        return \"RSA Known Answer Test check FIPS error\";\n\n    case DRBG_KAT_FIPS_E:\n        return \"DRBG Known Answer Test check FIPS error\";\n\n    case DRBG_CONT_FIPS_E:\n        return \"DRBG Continuous Test FIPS error\";\n\n    case AESGCM_KAT_FIPS_E:\n        return \"AESGCM Known Answer Test check FIPS error\";\n\n    case THREAD_STORE_KEY_E:\n        return \"Thread Storage Key Create error\";\n\n    case THREAD_STORE_SET_E:\n        return \"Thread Storage Set error\";\n\n    case MAC_CMP_FAILED_E:\n        return \"MAC comparison failed\";\n\n    case IS_POINT_E:\n        return \"ECC is point on curve failed\";\n\n    case ECC_INF_E:\n        return \" ECC point at infinity error\";\n\n    case ECC_OUT_OF_RANGE_E:\n        return \" ECC Qx or Qy out of range error\";\n\n    case ECC_PRIV_KEY_E:\n        return \" ECC private key is not valid error\";\n\n    case SRP_CALL_ORDER_E:\n        return \"SRP function called in the wrong order error\";\n\n    case SRP_VERIFY_E:\n        return \"SRP proof verification error\";\n\n    case SRP_BAD_KEY_E:\n        return \"SRP bad key values error\";\n\n    case ASN_NO_SKID:\n        return \"ASN no Subject Key Identifier found error\";\n\n    case ASN_NO_AKID:\n        return \"ASN no Authority Key Identifier found error\";\n\n    case ASN_NO_KEYUSAGE:\n        return \"ASN no Key Usage found error\";\n\n    case SKID_E:\n        return \"Setting Subject Key Identifier error\";\n\n    case AKID_E:\n        return \"Setting Authority Key Identifier error\";\n\n    case KEYUSAGE_E:\n        return \"Key Usage value error\";\n\n    case EXTKEYUSAGE_E:\n        return \"Extended Key Usage value error\";\n\n    case CERTPOLICIES_E:\n        return \"Setting Certificate Policies error\";\n\n    case WC_INIT_E:\n        return \"wolfCrypt Initialize Failure error\";\n\n    case SIG_VERIFY_E:\n        return \"Signature verify error\";\n\n    case BAD_COND_E:\n        return \"Bad condition variable operation error\";\n\n    case SIG_TYPE_E:\n        return \"Signature type not enabled/available\";\n\n    case HASH_TYPE_E:\n        return \"Hash type not enabled/available\";\n\n    case WC_KEY_SIZE_E:\n        return \"Key size error, either too small or large\";\n\n    case ASN_COUNTRY_SIZE_E:\n        return \"Country code size error, either too small or large\";\n\n    case MISSING_RNG_E:\n        return \"RNG required but not provided\";\n\n    case ASN_PATHLEN_SIZE_E:\n        return \"ASN CA path length value too large error\";\n\n    case ASN_PATHLEN_INV_E:\n        return \"ASN CA path length larger than signer error\";\n\n    case BAD_KEYWRAP_ALG_E:\n        return \"Unsupported key wrap algorithm error\";\n\n    case BAD_KEYWRAP_IV_E:\n        return \"Decrypted AES key wrap IV does not match expected\";\n\n    case WC_CLEANUP_E:\n        return \"wolfcrypt cleanup failed\";\n\n    case ECC_CDH_KAT_FIPS_E:\n        return \"wolfcrypt FIPS ECC CDH Known Answer Test Failure\";\n\n    case DH_CHECK_PUB_E:\n        return \"DH Check Public Key failure\";\n\n    case BAD_PATH_ERROR:\n        return \"Bad path for opendir error\";\n\n    case ASYNC_OP_E:\n        return \"Async operation error\";\n\n    case BAD_OCSP_RESPONDER:\n        return \"Invalid OCSP Responder, missing specific key usage extensions\";\n\n    case ECC_PRIVATEONLY_E:\n        return \"Invalid use of private only ECC key\";\n\n    case WC_HW_E:\n        return \"Error with hardware crypto use\";\n\n    case WC_HW_WAIT_E:\n        return \"Hardware waiting on resource\";\n\n    case PSS_SALTLEN_E:\n        return \"PSS - Length of salt is too big for hash algorithm\";\n\n    case PRIME_GEN_E:\n        return \"Unable to find a prime for RSA key\";\n\n    case BER_INDEF_E:\n        return \"Unable to decode an indefinite length encoded message\";\n\n    case RSA_OUT_OF_RANGE_E:\n        return \"Ciphertext to decrypt is out of range\";\n\n    case RSAPSS_PAT_FIPS_E:\n        return \"wolfcrypt FIPS RSA-PSS Pairwise Agreement Test Failure\";\n\n    case ECDSA_PAT_FIPS_E:\n        return \"wolfcrypt FIPS ECDSA Pairwise Agreement Test Failure\";\n\n    case DH_KAT_FIPS_E:\n        return \"wolfcrypt FIPS DH Known Answer Test Failure\";\n\n    case AESCCM_KAT_FIPS_E:\n        return \"AESCCM Known Answer Test check FIPS error\";\n\n    case SHA3_KAT_FIPS_E:\n        return \"SHA-3 Known Answer Test check FIPS error\";\n\n    case ECDHE_KAT_FIPS_E:\n        return \"wolfcrypt FIPS ECDHE Known Answer Test Failure\";\n\n    case AES_GCM_OVERFLOW_E:\n        return \"AES-GCM invocation counter overflow\";\n\n    case AES_CCM_OVERFLOW_E:\n        return \"AES-CCM invocation counter overflow\";\n\n    case RSA_KEY_PAIR_E:\n        return \"RSA Key Pair-Wise Consistency check fail\";\n\n    case DH_CHECK_PRIV_E:\n        return \"DH Check Private Key failure\";\n\n    case WC_AFALG_SOCK_E:\n        return \"AF_ALG socket error\";\n\n    case WC_DEVCRYPTO_E:\n        return \"Error with /dev/crypto\";\n\n    case ZLIB_INIT_ERROR:\n        return \"zlib init error\";\n\n    case ZLIB_COMPRESS_ERROR:\n        return \"zlib compress error\";\n\n    case ZLIB_DECOMPRESS_ERROR:\n        return \"zlib decompress error\";\n\n    case PKCS7_NO_SIGNER_E:\n        return \"No signer in PKCS#7 signed data\";\n\n    case CRYPTOCB_UNAVAILABLE:\n        return \"Crypto callback unavailable\";\n\n    case PKCS7_SIGNEEDS_CHECK:\n        return \"Signature found but no certificate to verify\";\n\n    case PSS_SALTLEN_RECOVER_E:\n        return \"PSS - Salt length unable to be recovered\";\n\n    default:\n        return \"unknown error number\";\n\n    }\n}\n\nvoid wc_ErrorString(int error, char* buffer)\n{\n    XSTRNCPY(buffer, wc_GetErrorString(error), WOLFSSL_MAX_ERROR_SZ);\n    buffer[WOLFSSL_MAX_ERROR_SZ-1] = 0;\n}\n#endif /* !NO_ERROR_STRINGS */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/evp.c",
    "content": "/* evp.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if !defined(WOLFSSL_EVP_INCLUDED)\n    #ifndef WOLFSSL_IGNORE_FILE_WARN\n        #warning evp.c does not need to be compiled separately from ssl.c\n    #endif\n#else\n\nstatic unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher);\n\n\n/* Getter function for cipher key length\n *\n * c  WOLFSSL_EVP_CIPHER structure to get key length from\n *\n * NOTE: OpenSSL_add_all_ciphers() should be called first before using this\n *       function\n *\n * Returns size of key in bytes\n */\nint wolfSSL_EVP_Cipher_key_length(const WOLFSSL_EVP_CIPHER* c)\n{\n    WOLFSSL_ENTER(\"wolfSSL_EVP_Cipher_key_length\");\n\n    if (c == NULL) {\n        return 0;\n    }\n\n    switch (cipherType(c)) {\n#if !defined(NO_AES)\n  #if defined(HAVE_AES_CBC)\n      case AES_128_CBC_TYPE: return 16;\n      case AES_192_CBC_TYPE: return 24;\n      case AES_256_CBC_TYPE: return 32;\n  #endif\n  #if defined(HAVE_AESGCM)\n      case AES_128_GCM_TYPE: return 16;\n      case AES_192_GCM_TYPE: return 24;\n      case AES_256_GCM_TYPE: return 32;\n  #endif\n  #if defined(WOLFSSL_AES_COUNTER)\n      case AES_128_CTR_TYPE: return 16;\n      case AES_192_CTR_TYPE: return 24;\n      case AES_256_CTR_TYPE: return 32;\n  #endif\n  #if defined(HAVE_AES_ECB)\n      case AES_128_ECB_TYPE: return 16;\n      case AES_192_ECB_TYPE: return 24;\n      case AES_256_ECB_TYPE: return 32;\n  #endif\n#endif /* !NO_AES */\n  #ifndef NO_DES3\n      case DES_CBC_TYPE:      return 8;\n      case DES_EDE3_CBC_TYPE: return 24;\n      case DES_ECB_TYPE:      return 8;\n      case DES_EDE3_ECB_TYPE: return 24;\n  #endif\n      default:\n          return 0;\n      }\n}\n\n\nint  wolfSSL_EVP_EncryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx,\n                                        const WOLFSSL_EVP_CIPHER* type,\n                                        const unsigned char* key,\n                                        const unsigned char* iv)\n{\n    return wolfSSL_EVP_CipherInit(ctx, type, (byte*)key, (byte*)iv, 1);\n}\n\nint  wolfSSL_EVP_EncryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,\n                                        const WOLFSSL_EVP_CIPHER* type,\n                                        WOLFSSL_ENGINE *impl,\n                                        const unsigned char* key,\n                                        const unsigned char* iv)\n{\n    (void) impl;\n    return wolfSSL_EVP_CipherInit(ctx, type, (byte*)key, (byte*)iv, 1);\n}\n\nint  wolfSSL_EVP_DecryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx,\n                                        const WOLFSSL_EVP_CIPHER* type,\n                                        const unsigned char* key,\n                                        const unsigned char* iv)\n{\n    WOLFSSL_ENTER(\"wolfSSL_EVP_CipherInit\");\n    return wolfSSL_EVP_CipherInit(ctx, type, (byte*)key, (byte*)iv, 0);\n}\n\nint  wolfSSL_EVP_DecryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,\n                                        const WOLFSSL_EVP_CIPHER* type,\n                                        WOLFSSL_ENGINE *impl,\n                                        const unsigned char* key,\n                                        const unsigned char* iv)\n{\n    (void) impl;\n    WOLFSSL_ENTER(\"wolfSSL_EVP_DecryptInit\");\n    return wolfSSL_EVP_CipherInit(ctx, type, (byte*)key, (byte*)iv, 0);\n}\n\n\nWOLFSSL_EVP_CIPHER_CTX *wolfSSL_EVP_CIPHER_CTX_new(void)\n{\n\tWOLFSSL_EVP_CIPHER_CTX *ctx = (WOLFSSL_EVP_CIPHER_CTX*)XMALLOC(sizeof *ctx,\n                                                 NULL, DYNAMIC_TYPE_TMP_BUFFER);\n\tif (ctx) {\n      WOLFSSL_ENTER(\"wolfSSL_EVP_CIPHER_CTX_new\");\n\t\t  wolfSSL_EVP_CIPHER_CTX_init(ctx);\n  }\n\treturn ctx;\n}\n\nvoid wolfSSL_EVP_CIPHER_CTX_free(WOLFSSL_EVP_CIPHER_CTX *ctx)\n{\n    if (ctx) {\n        WOLFSSL_ENTER(\"wolfSSL_EVP_CIPHER_CTX_free\");\n\t\t    wolfSSL_EVP_CIPHER_CTX_cleanup(ctx);\n\t\t    XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n\t\t}\n}\n\nunsigned long wolfSSL_EVP_CIPHER_CTX_mode(const WOLFSSL_EVP_CIPHER_CTX *ctx)\n{\n  if (ctx == NULL) return 0;\n  return ctx->flags & WOLFSSL_EVP_CIPH_MODE;\n}\n\nint  wolfSSL_EVP_EncryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,\n                                   unsigned char *out, int *outl)\n{\n    if (ctx && ctx->enc) {\n        WOLFSSL_ENTER(\"wolfSSL_EVP_EncryptFinal\");\n        return wolfSSL_EVP_CipherFinal(ctx, out, outl);\n    }\n    else\n        return WOLFSSL_FAILURE;\n}\n\n\nint  wolfSSL_EVP_CipherInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,\n                                    const WOLFSSL_EVP_CIPHER* type,\n                                    WOLFSSL_ENGINE *impl,\n                                    const unsigned char* key,\n                                    const unsigned char* iv,\n                                    int enc)\n{\n    (void)impl;\n    return wolfSSL_EVP_CipherInit(ctx, type, key, iv, enc);\n}\n\nint  wolfSSL_EVP_EncryptFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx,\n                                   unsigned char *out, int *outl)\n{\n    if (ctx && ctx->enc) {\n        WOLFSSL_ENTER(\"wolfSSL_EVP_EncryptFinal_ex\");\n        return wolfSSL_EVP_CipherFinal(ctx, out, outl);\n    }\n    else\n        return WOLFSSL_FAILURE;\n}\n\nint  wolfSSL_EVP_DecryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,\n                                   unsigned char *out, int *outl)\n{\n    if (ctx && !ctx->enc) {\n        WOLFSSL_ENTER(\"wolfSSL_EVP_DecryptFinal\");\n        return wolfSSL_EVP_CipherFinal(ctx, out, outl);\n    }\n    else {\n        return WOLFSSL_FAILURE;\n    }\n}\n\nint  wolfSSL_EVP_DecryptFinal_ex(WOLFSSL_EVP_CIPHER_CTX *ctx,\n                                   unsigned char *out, int *outl)\n{\n    if (ctx && !ctx->enc) {\n        WOLFSSL_ENTER(\"wolfSSL_EVP_DecryptFinal_ex\");\n        return wolfSSL_EVP_CipherFinal(ctx, out, outl);\n    }\n    else {\n        return WOLFSSL_FAILURE;\n    }\n}\n\n\nint wolfSSL_EVP_DigestInit_ex(WOLFSSL_EVP_MD_CTX* ctx,\n                                     const WOLFSSL_EVP_MD* type,\n                                     WOLFSSL_ENGINE *impl)\n{\n    (void) impl;\n    WOLFSSL_ENTER(\"wolfSSL_EVP_DigestInit_ex\");\n    return wolfSSL_EVP_DigestInit(ctx, type);\n}\n\n#ifdef DEBUG_WOLFSSL_EVP\n#define PRINT_BUF(b, sz) { int _i; for(_i=0; _i<(sz); _i++) { \\\n  printf(\"%02x(%c),\", (b)[_i], (b)[_i]); if ((_i+1)%8==0)printf(\"\\n\");}}\n#else\n#define PRINT_BUF(b, sz)\n#endif\n\nstatic int fillBuff(WOLFSSL_EVP_CIPHER_CTX *ctx, const unsigned char *in, int sz)\n{\n    int fill;\n\n    if (sz > 0) {\n        if ((sz+ctx->bufUsed) > ctx->block_size) {\n            fill = ctx->block_size - ctx->bufUsed;\n        } else {\n            fill = sz;\n        }\n        XMEMCPY(&(ctx->buf[ctx->bufUsed]), in, fill);\n        ctx->bufUsed += fill;\n        return fill;\n    } else return 0;\n}\n\nstatic int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx,\n                                   unsigned char *out,\n                                   const unsigned char *in, int inl)\n{\n    int ret = 0;\n\n    switch (ctx->cipherType) {\n#if !defined(NO_AES)\n    #if defined(HAVE_AES_CBC)\n        case AES_128_CBC_TYPE:\n        case AES_192_CBC_TYPE:\n        case AES_256_CBC_TYPE:\n            if (ctx->enc)\n                ret = wc_AesCbcEncrypt(&ctx->cipher.aes, out, in, inl);\n            else\n                ret = wc_AesCbcDecrypt(&ctx->cipher.aes, out, in, inl);\n            break;\n    #endif\n    #if defined(HAVE_AESGCM)\n        case AES_128_GCM_TYPE:\n        case AES_192_GCM_TYPE:\n        case AES_256_GCM_TYPE:\n            if (ctx->enc) {\n                if (out){\n                    /* encrypt confidential data*/\n                    ret = wc_AesGcmEncrypt(&ctx->cipher.aes, out, in, inl,\n                              ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,\n                              NULL, 0);\n                }\n                else {\n                    /* authenticated, non-confidential data */\n                    ret = wc_AesGcmEncrypt(&ctx->cipher.aes, NULL, NULL, 0,\n                              ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,\n                              in, inl);\n                    /* Reset partial authTag error for AAD*/\n                    if (ret == AES_GCM_AUTH_E)\n                        ret = 0;\n                }\n            }\n            else {\n                if (out){\n                    /* decrypt confidential data*/\n                    ret = wc_AesGcmDecrypt(&ctx->cipher.aes, out, in, inl,\n                              ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,\n                              NULL, 0);\n                }\n                else {\n                    /* authenticated, non-confidential data*/\n                    ret = wc_AesGcmDecrypt(&ctx->cipher.aes, NULL, NULL, 0,\n                              ctx->iv, ctx->ivSz,\n                              ctx->authTag, ctx->authTagSz,\n                              in, inl);\n                    /* Reset partial authTag error for AAD*/\n                    if (ret == AES_GCM_AUTH_E)\n                        ret = 0;\n                }\n            }\n            break;\n    #endif\n    #if defined(WOLFSSL_AES_COUNTER)\n        case AES_128_CTR_TYPE:\n        case AES_192_CTR_TYPE:\n        case AES_256_CTR_TYPE:\n            ret = wc_AesCtrEncrypt(&ctx->cipher.aes, out, in, inl);\n            break;\n    #endif\n    #if defined(HAVE_AES_ECB)\n        case AES_128_ECB_TYPE:\n        case AES_192_ECB_TYPE:\n        case AES_256_ECB_TYPE:\n            if (ctx->enc)\n                ret = wc_AesEcbEncrypt(&ctx->cipher.aes, out, in, inl);\n            else\n                ret = wc_AesEcbDecrypt(&ctx->cipher.aes, out, in, inl);\n            break;\n    #endif\n#endif /* !NO_AES */\n    #ifndef NO_DES3\n        case DES_CBC_TYPE:\n            if (ctx->enc)\n                ret = wc_Des_CbcEncrypt(&ctx->cipher.des, out, in, inl);\n            else\n                ret = wc_Des_CbcDecrypt(&ctx->cipher.des, out, in, inl);\n            break;\n        case DES_EDE3_CBC_TYPE:\n            if (ctx->enc)\n                ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, out, in, inl);\n            else\n                ret = wc_Des3_CbcDecrypt(&ctx->cipher.des3, out, in, inl);\n            break;\n        #if defined(WOLFSSL_DES_ECB)\n        case DES_ECB_TYPE:\n            ret = wc_Des_EcbEncrypt(&ctx->cipher.des, out, in, inl);\n            break;\n        case DES_EDE3_ECB_TYPE:\n            ret = wc_Des3_EcbEncrypt(&ctx->cipher.des3, out, in, inl);\n            break;\n        #endif\n    #endif\n    #ifndef NO_RC4\n        case ARC4_TYPE:\n            wc_Arc4Process(&ctx->cipher.arc4, out, in, inl);\n        break;\n    #endif\n        default:\n            return WOLFSSL_FAILURE;\n    }\n\n    if (ret != 0)\n        return WOLFSSL_FAILURE; /* failure */\n\n    (void)in;\n    (void)inl;\n    (void)out;\n\n    return WOLFSSL_SUCCESS; /* success */\n}\n\n#if defined(HAVE_AESGCM)\nstatic int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx,\n                                   unsigned char *out, int *outl,\n                                   const unsigned char *in, int inl)\n{\n    /* process blocks */\n    if (evpCipherBlock(ctx, out, in, inl) == 0)\n        return WOLFSSL_FAILURE;\n    *outl = inl;\n    return WOLFSSL_SUCCESS;\n}\n#endif\n\n/* returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */\nWOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,\n                                   unsigned char *out, int *outl,\n                                   const unsigned char *in, int inl)\n{\n    int blocks;\n    int fill;\n\n    WOLFSSL_ENTER(\"wolfSSL_EVP_CipherUpdate\");\n    if ((ctx == NULL) || (inl < 0) || (outl == NULL)|| (in == NULL)) {\n        WOLFSSL_MSG(\"Bad argument\");\n        return WOLFSSL_FAILURE;\n    }\n\n    *outl = 0;\n    if (inl == 0) {\n        return WOLFSSL_SUCCESS;\n    }\n\n#if !defined(NO_AES) && defined(HAVE_AESGCM)\n        switch (ctx->cipherType) {\n            case AES_128_GCM_TYPE:\n            case AES_192_GCM_TYPE:\n            case AES_256_GCM_TYPE:\n/* if out == NULL, in/inl contains the additional authenticated data for GCM */\n                return wolfSSL_EVP_CipherUpdate_GCM(ctx, out, outl, in, inl);\n            default:\n                /* fall-through */\n                break;\n        }\n#endif /* !defined(NO_AES) && defined(HAVE_AESGCM) */\n\n    if (out == NULL) {\n        return WOLFSSL_FAILURE;\n    }\n\n\n    if (ctx->bufUsed > 0) { /* concatenate them if there is anything */\n        fill = fillBuff(ctx, in, inl);\n        inl -= fill;\n        in  += fill;\n    }\n\n    /* check if the buff is full, and if so flash it out */\n    if (ctx->bufUsed == ctx->block_size) {\n        byte* output = out;\n\n        /* During decryption we save the last block to check padding on Final.\n         * Update the last block stored if one has already been stored */\n        if (ctx->enc == 0) {\n            if (ctx->lastUsed == 1) {\n                XMEMCPY(out, ctx->lastBlock, ctx->block_size);\n                *outl+= ctx->block_size;\n                out  += ctx->block_size;\n            }\n            output = ctx->lastBlock; /* redirect output to last block buffer */\n            ctx->lastUsed = 1;\n        }\n\n        PRINT_BUF(ctx->buf, ctx->block_size);\n        if (evpCipherBlock(ctx, output, ctx->buf, ctx->block_size) == 0) {\n            return WOLFSSL_FAILURE;\n        }\n        PRINT_BUF(out, ctx->block_size);\n        ctx->bufUsed = 0;\n\n        /* if doing encryption update the new output block, decryption will\n         * always have the last block saved for when Final is called */\n        if ((ctx->enc != 0)) {\n            *outl+= ctx->block_size;\n            out  += ctx->block_size;\n        }\n    }\n\n    blocks = inl / ctx->block_size;\n    if (blocks > 0) {\n        /* During decryption we save the last block to check padding on Final.\n         * Update the last block stored if one has already been stored */\n        if ((ctx->enc == 0) && (ctx->lastUsed == 1)) {\n            PRINT_BUF(ctx->lastBlock, ctx->block_size);\n            XMEMCPY(out, ctx->lastBlock, ctx->block_size);\n            *outl += ctx->block_size;\n            out += ctx->block_size;\n            ctx->lastUsed = 0;\n        }\n\n        /* process blocks */\n        if (evpCipherBlock(ctx, out, in, blocks * ctx->block_size) == 0) {\n            return WOLFSSL_FAILURE;\n        }\n        PRINT_BUF(in, ctx->block_size*blocks);\n        PRINT_BUF(out,ctx->block_size*blocks);\n        inl  -= ctx->block_size * blocks;\n        in   += ctx->block_size * blocks;\n        if (ctx->enc == 0) {\n            if ((ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING) ||\n                    (ctx->block_size == 1)) {\n                ctx->lastUsed = 0;\n                *outl += ctx->block_size * blocks;\n            } else {\n                /* in the case of decryption and padding, store the last block\n                 * here in order to verify the padding when Final is called */\n                if (inl == 0) { /* if not 0 then we know leftovers are checked*/\n                    ctx->lastUsed = 1;\n                    blocks = blocks - 1; /* save last block to check padding in\n                                          * EVP_CipherFinal call */\n                    XMEMCPY(ctx->lastBlock, &out[ctx->block_size * blocks],\n                            ctx->block_size);\n                }\n                *outl += ctx->block_size * blocks;\n            }\n        } else {\n            *outl += ctx->block_size * blocks;\n        }\n    }\n\n\n    if (inl > 0) {\n        /* put fraction into buff */\n        fillBuff(ctx, in, inl);\n        /* no increase of outl */\n    }\n    (void)out; /* silence warning in case not read */\n\n    return WOLFSSL_SUCCESS;\n}\n\nstatic void padBlock(WOLFSSL_EVP_CIPHER_CTX *ctx)\n{\n    int i;\n    for (i = ctx->bufUsed; i < ctx->block_size; i++)\n        ctx->buf[i] = (byte)(ctx->block_size - ctx->bufUsed);\n}\n\nstatic int checkPad(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *buff)\n{\n    int i;\n    int n;\n    n = buff[ctx->block_size-1];\n    if (n > ctx->block_size) return -1;\n    for (i = 0; i < n; i++) {\n        if (buff[ctx->block_size-i-1] != n)\n            return -1;\n    }\n    return ctx->block_size - n;\n}\n\nint  wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,\n                                   unsigned char *out, int *outl)\n{\n    int fl;\n    int ret = WOLFSSL_SUCCESS;\n    if (ctx == NULL || out == NULL || outl == NULL)\n        return BAD_FUNC_ARG;\n\n    WOLFSSL_ENTER(\"wolfSSL_EVP_CipherFinal\");\n\n#if !defined(NO_AES) && defined(HAVE_AESGCM)\n        switch (ctx->cipherType) {\n            case AES_128_GCM_TYPE:\n            case AES_192_GCM_TYPE:\n            case AES_256_GCM_TYPE:\n                *outl = 0;\n                /* Clear IV, since IV reuse is not recommended for AES GCM. */\n                XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE);\n                return WOLFSSL_SUCCESS;\n            default:\n                /* fall-through */\n                break;\n        }\n#endif /* !NO_AES && HAVE_AESGCM */\n\n    if (ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING) {\n        if (ctx->bufUsed != 0) return WOLFSSL_FAILURE;\n        *outl = 0;\n    }\n    else if (ctx->enc) {\n        if (ctx->block_size == 1) {\n            *outl = 0;\n        }\n        else if ((ctx->bufUsed >= 0) && (ctx->block_size != 1)) {\n            padBlock(ctx);\n            PRINT_BUF(ctx->buf, ctx->block_size);\n            if (evpCipherBlock(ctx, out, ctx->buf, ctx->block_size) == 0) {\n                ret = WOLFSSL_FAILURE;\n            }\n            else {\n                PRINT_BUF(out, ctx->block_size);\n                *outl = ctx->block_size;\n            }\n        }\n    }\n    else {\n        if (ctx->block_size == 1) {\n            *outl = 0;\n        }\n        else if ((ctx->bufUsed % ctx->block_size) != 0) {\n            *outl = 0;\n            /* not enough padding for decrypt */\n            ret = WOLFSSL_FAILURE;\n        }\n        else if (ctx->lastUsed) {\n            PRINT_BUF(ctx->lastBlock, ctx->block_size);\n            if ((fl = checkPad(ctx, ctx->lastBlock)) >= 0) {\n                XMEMCPY(out, ctx->lastBlock, fl);\n                *outl = fl;\n                if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {\n                    /* return error in cases where the block length is incorrect */\n                    ret = WOLFSSL_FAILURE;\n                }\n            }\n            else {\n                ret = WOLFSSL_FAILURE;\n            }\n        }\n        else if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {\n            /* return error in cases where the block length is incorrect */\n            ret = WOLFSSL_FAILURE;\n        }\n    }\n    if (ret == WOLFSSL_SUCCESS) {\n        /* reset cipher state after final */\n        wolfSSL_EVP_CipherInit(ctx, NULL, NULL, NULL, -1);\n    }\n    return ret;\n}\n\n\n#ifdef WOLFSSL_EVP_DECRYPT_LEGACY\n/* This is a version of DecryptFinal to work with data encrypted with\n * wolfSSL_EVP_EncryptFinal() with the broken padding. (pre-v3.12.0)\n * Only call this after wolfSSL_EVP_CipherFinal() fails on a decrypt.\n * Note, you don't know if the padding is good or bad with the old\n * encrypt, but it is likely to be or bad. It will update the output\n * length with the block_size so the last block is still captured. */\nWOLFSSL_API int  wolfSSL_EVP_DecryptFinal_legacy(WOLFSSL_EVP_CIPHER_CTX *ctx,\n        unsigned char *out, int *outl)\n{\n    int fl;\n    if (ctx == NULL || out == NULL || outl == NULL)\n        return BAD_FUNC_ARG;\n\n    WOLFSSL_ENTER(\"wolfSSL_EVP_DecryptFinal_legacy\");\n    if (ctx->block_size == 1) {\n        *outl = 0;\n        return WOLFSSL_SUCCESS;\n    }\n    if ((ctx->bufUsed % ctx->block_size) != 0) {\n        *outl = 0;\n        /* not enough padding for decrypt */\n        return WOLFSSL_FAILURE;\n    }\n    /* The original behavior of CipherFinal() was like it is now,\n     * but checkPad would return 0 in case of a bad pad. It would\n     * treat the pad as 0, and leave the data in the output buffer,\n     * and not try to copy anything. This converts checkPad's -1 error\n     * code to block_size.\n     */\n    if (ctx->lastUsed) {\n        PRINT_BUF(ctx->lastBlock, ctx->block_size);\n        if ((fl = checkPad(ctx, ctx->lastBlock)) < 0) {\n            fl = ctx->block_size;\n        }\n        else {\n            XMEMCPY(out, ctx->lastBlock, fl);\n        }\n        *outl = fl;\n    }\n    /* return error in cases where the block length is incorrect */\n    if (ctx->lastUsed == 0 && ctx->bufUsed == 0) {\n        return WOLFSSL_FAILURE;\n    }\n\n    return WOLFSSL_SUCCESS;\n}\n#endif\n\n\nint wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx)\n{\n    if (ctx == NULL) return BAD_FUNC_ARG;\n    switch (ctx->cipherType) {\n#if !defined(NO_AES) || !defined(NO_DES3)\n#if !defined(NO_AES)\n#if defined(HAVE_AES_CBC)\n    case AES_128_CBC_TYPE:\n    case AES_192_CBC_TYPE:\n    case AES_256_CBC_TYPE:\n#endif\n#if defined(HAVE_AESGCM)\n    case AES_128_GCM_TYPE:\n    case AES_192_GCM_TYPE:\n    case AES_256_GCM_TYPE:\n#endif\n#if defined(WOLFSSL_AES_COUNTER)\n    case AES_128_CTR_TYPE:\n    case AES_192_CTR_TYPE:\n    case AES_256_CTR_TYPE:\n#endif\n\n    case AES_128_ECB_TYPE:\n    case AES_192_ECB_TYPE:\n    case AES_256_ECB_TYPE:\n#endif /* !NO_AES */\n#ifndef NO_DES3\n    case DES_CBC_TYPE:\n    case DES_ECB_TYPE:\n    case DES_EDE3_CBC_TYPE:\n    case DES_EDE3_ECB_TYPE:\n#endif\n        return ctx->block_size;\n#endif /* !NO_AES || !NO_DES3 */\n    default:\n        return 0;\n    }\n}\n\nstatic unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher)\n{\n    if (cipher == NULL) return 0; /* dummy for #ifdef */\n  #ifndef NO_DES3\n      else if (XSTRNCMP(cipher, EVP_DES_CBC, EVP_DES_SIZE) == 0)\n          return DES_CBC_TYPE;\n      else if (XSTRNCMP(cipher, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)\n          return DES_EDE3_CBC_TYPE;\n  #if !defined(NO_DES3)\n      else if (XSTRNCMP(cipher, EVP_DES_ECB, EVP_DES_SIZE) == 0)\n          return DES_ECB_TYPE;\n      else if (XSTRNCMP(cipher, EVP_DES_EDE3_ECB, EVP_DES_EDE3_SIZE) == 0)\n          return DES_EDE3_ECB_TYPE;\n  #endif /* NO_DES3 && HAVE_AES_ECB */\n  #endif\n  #if !defined(NO_AES)\n  #if defined(HAVE_AES_CBC)\n      #ifdef WOLFSSL_AES_128\n      else if (XSTRNCMP(cipher, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)\n          return AES_128_CBC_TYPE;\n      #endif\n      #ifdef WOLFSSL_AES_192\n      else if (XSTRNCMP(cipher, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)\n          return AES_192_CBC_TYPE;\n      #endif\n      #ifdef WOLFSSL_AES_256\n      else if (XSTRNCMP(cipher, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)\n          return AES_256_CBC_TYPE;\n      #endif\n  #endif /* HAVE_AES_CBC */\n  #if defined(HAVE_AESGCM)\n      #ifdef WOLFSSL_AES_128\n      else if (XSTRNCMP(cipher, EVP_AES_128_GCM, EVP_AES_SIZE) == 0)\n          return AES_128_GCM_TYPE;\n      #endif\n      #ifdef WOLFSSL_AES_192\n      else if (XSTRNCMP(cipher, EVP_AES_192_GCM, EVP_AES_SIZE) == 0)\n          return AES_192_GCM_TYPE;\n      #endif\n      #ifdef WOLFSSL_AES_256\n      else if (XSTRNCMP(cipher, EVP_AES_256_GCM, EVP_AES_SIZE) == 0)\n          return AES_256_GCM_TYPE;\n      #endif\n  #endif /* HAVE_AESGCM */\n  #if defined(WOLFSSL_AES_COUNTER)\n      #ifdef WOLFSSL_AES_128\n      else if (XSTRNCMP(cipher, EVP_AES_128_CTR, EVP_AES_SIZE) == 0)\n          return AES_128_CTR_TYPE;\n      #endif\n      #ifdef WOLFSSL_AES_192\n      else if (XSTRNCMP(cipher, EVP_AES_192_CTR, EVP_AES_SIZE) == 0)\n          return AES_192_CTR_TYPE;\n      #endif\n      #ifdef WOLFSSL_AES_256\n      else if (XSTRNCMP(cipher, EVP_AES_256_CTR, EVP_AES_SIZE) == 0)\n          return AES_256_CTR_TYPE;\n      #endif\n  #endif /* HAVE_AES_CBC */\n  #if defined(HAVE_AES_ECB)\n      #ifdef WOLFSSL_AES_128\n      else if (XSTRNCMP(cipher, EVP_AES_128_ECB, EVP_AES_SIZE) == 0)\n          return AES_128_ECB_TYPE;\n      #endif\n      #ifdef WOLFSSL_AES_192\n      else if (XSTRNCMP(cipher, EVP_AES_192_ECB, EVP_AES_SIZE) == 0)\n          return AES_192_ECB_TYPE;\n      #endif\n      #ifdef WOLFSSL_AES_256\n      else if (XSTRNCMP(cipher, EVP_AES_256_ECB, EVP_AES_SIZE) == 0)\n          return AES_256_ECB_TYPE;\n      #endif\n  #endif /*HAVE_AES_CBC */\n#endif /* !NO_AES */\n      else return 0;\n}\n\nint wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher)\n{\n  if (cipher == NULL) return BAD_FUNC_ARG;\n  switch (cipherType(cipher)) {\n#if !defined(NO_AES)\n  #if defined(HAVE_AES_CBC)\n      case AES_128_CBC_TYPE:\n      case AES_192_CBC_TYPE:\n      case AES_256_CBC_TYPE:\n          return AES_BLOCK_SIZE;\n  #endif\n  #if defined(HAVE_AESGCM)\n      case AES_128_GCM_TYPE:\n      case AES_192_GCM_TYPE:\n      case AES_256_GCM_TYPE:\n          return AES_BLOCK_SIZE;\n  #endif\n  #if defined(WOLFSSL_AES_COUNTER)\n      case AES_128_CTR_TYPE:\n      case AES_192_CTR_TYPE:\n      case AES_256_CTR_TYPE:\n          return AES_BLOCK_SIZE;\n  #endif\n  #if defined(HAVE_AES_ECB)\n      case AES_128_ECB_TYPE:\n      case AES_192_ECB_TYPE:\n      case AES_256_ECB_TYPE:\n          return AES_BLOCK_SIZE;\n  #endif\n#endif /* NO_AES */\n  #ifndef NO_DES3\n      case DES_CBC_TYPE: return 8;\n      case DES_EDE3_CBC_TYPE: return 8;\n      case DES_ECB_TYPE: return 8;\n      case DES_EDE3_ECB_TYPE: return 8;\n  #endif\n      default:\n          return 0;\n      }\n}\n\nunsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher)\n{\n    switch (cipherType(cipher)) {\n#if !defined(NO_AES)\n    #if defined(HAVE_AES_CBC)\n        case AES_128_CBC_TYPE:\n        case AES_192_CBC_TYPE:\n        case AES_256_CBC_TYPE:\n            return WOLFSSL_EVP_CIPH_CBC_MODE;\n    #endif\n    #if defined(HAVE_AESGCM)\n        case AES_128_GCM_TYPE:\n        case AES_192_GCM_TYPE:\n        case AES_256_GCM_TYPE:\n            return WOLFSSL_EVP_CIPH_GCM_MODE;\n    #endif\n    #if defined(WOLFSSL_AES_COUNTER)\n        case AES_128_CTR_TYPE:\n        case AES_192_CTR_TYPE:\n        case AES_256_CTR_TYPE:\n            return WOLFSSL_EVP_CIPH_CTR_MODE;\n    #endif\n        case AES_128_ECB_TYPE:\n        case AES_192_ECB_TYPE:\n        case AES_256_ECB_TYPE:\n            return WOLFSSL_EVP_CIPH_ECB_MODE;\n#endif /* NO_ASE */\n    #ifndef NO_DES3\n        case DES_CBC_TYPE:\n        case DES_EDE3_CBC_TYPE:\n            return WOLFSSL_EVP_CIPH_CBC_MODE;\n        case DES_ECB_TYPE:\n        case DES_EDE3_ECB_TYPE:\n            return WOLFSSL_EVP_CIPH_ECB_MODE;\n    #endif\n    #ifndef NO_RC4\n        case ARC4_TYPE:\n            return EVP_CIPH_STREAM_CIPHER;\n    #endif\n        default:\n            return 0;\n        }\n}\n\nunsigned long WOLFSSL_EVP_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher)\n{\n  if (cipher == NULL) return 0;\n  return WOLFSSL_CIPHER_mode(cipher);\n}\n\nvoid wolfSSL_EVP_CIPHER_CTX_set_flags(WOLFSSL_EVP_CIPHER_CTX *ctx, int flags)\n{\n    if (ctx != NULL) {\n        ctx->flags |= flags;\n    }\n}\n\nvoid wolfSSL_EVP_CIPHER_CTX_clear_flags(WOLFSSL_EVP_CIPHER_CTX *ctx, int flags)\n{\n    if (ctx != NULL) {\n        ctx->flags &= ~flags;\n    }\n}\n\nunsigned long wolfSSL_EVP_CIPHER_flags(const WOLFSSL_EVP_CIPHER *cipher)\n{\n  if (cipher == NULL) return 0;\n  return WOLFSSL_CIPHER_mode(cipher);\n}\n\nint  wolfSSL_EVP_CIPHER_CTX_set_padding(WOLFSSL_EVP_CIPHER_CTX *ctx, int padding)\n{\n  if (ctx == NULL) return BAD_FUNC_ARG;\n  if (padding) {\n      ctx->flags &= ~WOLFSSL_EVP_CIPH_NO_PADDING;\n  }\n  else {\n      ctx->flags |=  WOLFSSL_EVP_CIPH_NO_PADDING;\n  }\n  return 1;\n}\n\nint wolfSSL_EVP_add_digest(const WOLFSSL_EVP_MD *digest)\n{\n    (void)digest;\n    /* nothing to do */\n    return 0;\n}\n\n\n/* Frees the WOLFSSL_EVP_PKEY_CTX passed in.\n *\n * return WOLFSSL_SUCCESS on success\n */\nint wolfSSL_EVP_PKEY_CTX_free(WOLFSSL_EVP_PKEY_CTX *ctx)\n{\n    if (ctx == NULL) return 0;\n    WOLFSSL_ENTER(\"EVP_PKEY_CTX_free\");\n    XFREE(ctx, NULL, DYNAMIC_TYPE_PUBLIC_KEY);\n    return WOLFSSL_SUCCESS;\n}\n\n\n/* Creates a new WOLFSSL_EVP_PKEY_CTX structure.\n *\n * pkey  key structure to use with new WOLFSSL_EVP_PEKY_CTX\n * e     engine to use. It should be NULL at this time.\n *\n * return the new structure on success and NULL if failed.\n */\nWOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_ENGINE *e)\n{\n    WOLFSSL_EVP_PKEY_CTX* ctx;\n\n    if (pkey == NULL) return 0;\n    if (e != NULL) return 0;\n    WOLFSSL_ENTER(\"EVP_PKEY_CTX_new\");\n\n    ctx = (WOLFSSL_EVP_PKEY_CTX*)XMALLOC(sizeof(WOLFSSL_EVP_PKEY_CTX), NULL,\n            DYNAMIC_TYPE_PUBLIC_KEY);\n    if (ctx == NULL) return NULL;\n    XMEMSET(ctx, 0, sizeof(WOLFSSL_EVP_PKEY_CTX));\n    ctx->pkey = pkey;\n#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)\n    ctx->padding = RSA_PKCS1_PADDING;\n#endif\n\n    return ctx;\n}\n\n\n/* Sets the type of RSA padding to use.\n *\n * ctx     structure to set padding in.\n * padding RSA padding type\n *\n * returns WOLFSSL_SUCCESS on success.\n */\nint wolfSSL_EVP_PKEY_CTX_set_rsa_padding(WOLFSSL_EVP_PKEY_CTX *ctx, int padding)\n{\n    if (ctx == NULL) return 0;\n    WOLFSSL_ENTER(\"EVP_PKEY_CTX_set_rsa_padding\");\n    ctx->padding = padding;\n    return WOLFSSL_SUCCESS;\n}\n\n/* create a PKEY contxt and return it */\nWOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new_id(int id, WOLFSSL_ENGINE *e)\n{\n    WOLFSSL_EVP_PKEY* pkey;\n    WOLFSSL_EVP_PKEY_CTX* ctx = NULL;\n\n    WOLFSSL_ENTER(\"wolfSSL_EVP_PKEY_CTX_new_id\");\n\n    pkey = wolfSSL_PKEY_new_ex(NULL);\n    if (pkey) {\n        pkey->type = id;\n        ctx = wolfSSL_EVP_PKEY_CTX_new(pkey, e);\n        if (ctx == NULL) {\n            wolfSSL_EVP_PKEY_free(pkey);\n        }\n    }\n    return ctx;\n}\n\n/* Returns WOLFSSL_SUCCESS or error */\nint wolfSSL_EVP_PKEY_CTX_set_rsa_keygen_bits(WOLFSSL_EVP_PKEY_CTX *ctx, int bits)\n{\n    if (ctx) {\n        ctx->nbits = bits;\n    }\n    return WOLFSSL_SUCCESS;\n}\n\n/* Uses the WOLFSSL_EVP_PKEY_CTX to decrypt a buffer.\n *\n * ctx    structure to decrypt with\n * out    buffer to hold the results\n * outlen initially holds size of out buffer and gets set to decrypt result size\n * in     buffer decrypt\n * inlen  length of in buffer\n *\n * returns WOLFSSL_SUCCESS on success.\n */\nint wolfSSL_EVP_PKEY_decrypt(WOLFSSL_EVP_PKEY_CTX *ctx,\n                     unsigned char *out, size_t *outlen,\n                     const unsigned char *in, size_t inlen)\n{\n    int len = 0;\n\n    if (ctx == NULL) return 0;\n    WOLFSSL_ENTER(\"EVP_PKEY_decrypt\");\n\n    (void)out;\n    (void)outlen;\n    (void)in;\n    (void)inlen;\n    (void)len;\n\n    switch (ctx->pkey->type) {\n#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)\n    case EVP_PKEY_RSA:\n        len = wolfSSL_RSA_private_decrypt((int)inlen, (unsigned char*)in, out,\n              ctx->pkey->rsa, ctx->padding);\n        if (len < 0) break;\n        else {\n            *outlen = len;\n            return WOLFSSL_SUCCESS;\n        }\n#endif /* NO_RSA */\n\n    case EVP_PKEY_EC:\n        WOLFSSL_MSG(\"not implemented\");\n        FALL_THROUGH;\n    default:\n        break;\n    }\n    return WOLFSSL_FAILURE;\n}\n\n\n/* Initialize a WOLFSSL_EVP_PKEY_CTX structure for decryption\n *\n * ctx    WOLFSSL_EVP_PKEY_CTX structure to use with decryption\n *\n * Returns WOLFSSL_FAILURE on failure and WOLFSSL_SUCCESS on success\n */\nint wolfSSL_EVP_PKEY_decrypt_init(WOLFSSL_EVP_PKEY_CTX *ctx)\n{\n    if (ctx == NULL) return WOLFSSL_FAILURE;\n    WOLFSSL_ENTER(\"EVP_PKEY_decrypt_init\");\n    switch (ctx->pkey->type) {\n    case EVP_PKEY_RSA:\n        ctx->op = EVP_PKEY_OP_DECRYPT;\n        return WOLFSSL_SUCCESS;\n    case EVP_PKEY_EC:\n        WOLFSSL_MSG(\"not implemented\");\n        FALL_THROUGH;\n    default:\n        break;\n    }\n    return WOLFSSL_FAILURE;\n}\n\n\n/* Use a WOLFSSL_EVP_PKEY_CTX structure to encrypt data\n *\n * ctx    WOLFSSL_EVP_PKEY_CTX structure to use with encryption\n * out    buffer to hold encrypted data\n * outlen length of out buffer\n * in     data to be encrypted\n * inlen  length of in buffer\n *\n * Returns WOLFSSL_FAILURE on failure and WOLFSSL_SUCCESS on success\n */\nint wolfSSL_EVP_PKEY_encrypt(WOLFSSL_EVP_PKEY_CTX *ctx,\n                     unsigned char *out, size_t *outlen,\n                     const unsigned char *in, size_t inlen)\n{\n    int len = 0;\n    if (ctx == NULL) return WOLFSSL_FAILURE;\n    WOLFSSL_ENTER(\"EVP_PKEY_encrypt\");\n    if (ctx->op != EVP_PKEY_OP_ENCRYPT) return WOLFSSL_FAILURE;\n\n    (void)out;\n    (void)outlen;\n    (void)in;\n    (void)inlen;\n    (void)len;\n    switch (ctx->pkey->type) {\n#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)\n    case EVP_PKEY_RSA:\n        len = wolfSSL_RSA_public_encrypt((int)inlen, (unsigned char *)in, out,\n                  ctx->pkey->rsa, ctx->padding);\n        if (len < 0)\n            break;\n        else {\n            *outlen = len;\n            return WOLFSSL_SUCCESS;\n        }\n#endif /* NO_RSA */\n\n    case EVP_PKEY_EC:\n        WOLFSSL_MSG(\"not implemented\");\n        FALL_THROUGH;\n    default:\n        break;\n    }\n    return WOLFSSL_FAILURE;\n}\n\n\n/* Initialize a WOLFSSL_EVP_PKEY_CTX structure to encrypt data\n *\n * ctx    WOLFSSL_EVP_PKEY_CTX structure to use with encryption\n *\n * Returns WOLFSSL_FAILURE on failure and WOLFSSL_SUCCESS on success\n */\nint wolfSSL_EVP_PKEY_encrypt_init(WOLFSSL_EVP_PKEY_CTX *ctx)\n{\n    if (ctx == NULL) return WOLFSSL_FAILURE;\n    WOLFSSL_ENTER(\"EVP_PKEY_encrypt_init\");\n\n    switch (ctx->pkey->type) {\n    case EVP_PKEY_RSA:\n        ctx->op = EVP_PKEY_OP_ENCRYPT;\n        return WOLFSSL_SUCCESS;\n    case EVP_PKEY_EC:\n        WOLFSSL_MSG(\"not implemented\");\n        FALL_THROUGH;\n    default:\n        break;\n    }\n    return WOLFSSL_FAILURE;\n}\n/******************************************************************************\n* wolfSSL_EVP_PKEY_sign_init -  initializes a public key algorithm context for\n* a signing operation.\n*\n* RETURNS:\n* returns WOLFSSL_SUCCESS on success, otherwise returns -2\n*/\nWOLFSSL_API int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx)\n{\n    int ret = -2;\n\n    WOLFSSL_MSG(\"wolfSSL_EVP_PKEY_sign_init\");\n    if (!ctx  || !ctx->pkey)\n        return ret;\n\n    switch (ctx->pkey->type) {\n        case EVP_PKEY_RSA:\n            ctx->op = EVP_PKEY_OP_SIGN;\n            ret = WOLFSSL_SUCCESS;\n            break;\n        case EVP_PKEY_EC:\n            WOLFSSL_MSG(\"not implemented\");\n            FALL_THROUGH;\n        default:\n            ret = -2;\n    }\n    return ret;\n}\n/******************************************************************************\n* wolfSSL_EVP_PKEY_sign - performs a public key signing operation using ctx\n* The data to be signed should be hashed since the function does not hash the data.\n*\n* RETURNS:\n* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE\n*/\n\nWOLFSSL_API int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *sig,\n                        size_t *siglen, const unsigned char *tbs, size_t tbslen)\n{\n    int len = 0;\n\n    WOLFSSL_MSG(\"wolfSSL_EVP_PKEY_sign\");\n\n    if (!ctx || ctx->op != EVP_PKEY_OP_SIGN || !ctx->pkey)\n        return WOLFSSL_FAILURE;\n\n    (void)sig;\n    (void)siglen;\n    (void)tbs;\n    (void)tbslen;\n    (void)len;\n\n    switch (ctx->pkey->type) {\n#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)\n    case EVP_PKEY_RSA:\n        len = wolfSSL_RSA_private_encrypt((int)tbslen, (unsigned char*)tbs, sig,\n              ctx->pkey->rsa, ctx->padding);\n        if (len < 0)\n            break;\n        else {\n            *siglen = len;\n            return WOLFSSL_SUCCESS;\n        }\n#endif /* NO_RSA */\n\n    case EVP_PKEY_EC:\n        WOLFSSL_MSG(\"not implemented\");\n        FALL_THROUGH;\n    default:\n        break;\n    }\n    return WOLFSSL_FAILURE;\n}\n\n/* Get the size in bits for WOLFSSL_EVP_PKEY key\n *\n * pkey WOLFSSL_EVP_PKEY structure to get key size of\n *\n * returns the size in bits of key on success\n */\nint wolfSSL_EVP_PKEY_bits(const WOLFSSL_EVP_PKEY *pkey)\n{\n    int bytes;\n\n    if (pkey == NULL) return 0;\n    WOLFSSL_ENTER(\"EVP_PKEY_bits\");\n    if ((bytes = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey)) ==0) return 0;\n    return bytes*8;\n}\n\n\nint wolfSSL_EVP_PKEY_keygen_init(WOLFSSL_EVP_PKEY_CTX *ctx)\n{\n    (void)ctx;\n    return WOLFSSL_SUCCESS;\n}\n\nint wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx,\n  WOLFSSL_EVP_PKEY **ppkey)\n{\n    int ret = WOLFSSL_FAILURE;\n    int ownPkey = 0;\n    WOLFSSL_EVP_PKEY* pkey;\n\n    if (ctx == NULL || ppkey == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    pkey = *ppkey;\n    if (pkey == NULL) {\n        ownPkey = 1;\n        pkey = wolfSSL_PKEY_new();\n    }\n\n    switch (pkey->type) {\n#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)\n        case EVP_PKEY_RSA:\n            pkey->rsa = wolfSSL_RSA_generate_key(ctx->nbits, WC_RSA_EXPONENT,\n                NULL, NULL);\n            if (pkey->rsa) {\n                pkey->ownRsa = 1;\n                pkey->pkey_sz = wolfSSL_i2d_RSAPrivateKey(pkey->rsa,\n                        (unsigned char**)&pkey->pkey.ptr);\n                ret = WOLFSSL_SUCCESS;\n            }\n            break;\n#endif\n#ifdef HAVE_ECC\n        case EVP_PKEY_EC:\n            pkey->ecc = wolfSSL_EC_KEY_new();\n            if (pkey->ecc) {\n                ret = wolfSSL_EC_KEY_generate_key(pkey->ecc);\n                if (ret == WOLFSSL_SUCCESS) {\n                    pkey->ownEcc = 1;\n                }\n            }\n#endif\n        default:\n            break;\n    }\n\n    if (ret != WOLFSSL_SUCCESS && ownPkey) {\n        wolfSSL_EVP_PKEY_free(pkey);\n        pkey = NULL;\n    }\n\n    *ppkey = pkey;\n\n    return ret;\n}\n\n/* Get the size in bytes for WOLFSSL_EVP_PKEY key\n *\n * pkey WOLFSSL_EVP_PKEY structure to get key size of\n *\n * returns the size of a key on success which is the maximum size of a\n *         signature\n */\nint wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey)\n{\n    if (pkey == NULL) return 0;\n    WOLFSSL_ENTER(\"EVP_PKEY_size\");\n\n    switch (pkey->type) {\n#ifndef NO_RSA\n    case EVP_PKEY_RSA:\n        return (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(pkey->rsa));\n#endif /* !NO_RSA */\n\n#ifdef HAVE_ECC\n    case EVP_PKEY_EC:\n        if (pkey->ecc == NULL || pkey->ecc->internal == NULL) {\n            WOLFSSL_MSG(\"No ECC key has been set\");\n            break;\n        }\n        return wc_ecc_size((ecc_key*)(pkey->ecc->internal));\n#endif /* HAVE_ECC */\n\n    default:\n        break;\n    }\n    return 0;\n}\n\n#ifndef NO_WOLFSSL_STUB\nWOLFSSL_API int wolfSSL_EVP_PKEY_missing_parameters(WOLFSSL_EVP_PKEY *pkey)\n{\n    (void)pkey;\n    /* not using missing params callback and returning zero to indicate success */\n    return 0;\n}\n#endif\n\nWOLFSSL_API int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b)\n{\n    int ret = -1; /* failure */\n    int a_sz = 0, b_sz = 0;\n\n    if (a == NULL || b == NULL)\n        return ret;\n\n    /* check its the same type of key */\n    if (a->type != b->type)\n        return ret;\n\n    /* get size based on key type */\n    switch (a->type) {\n#ifndef NO_RSA\n    case EVP_PKEY_RSA:\n        a_sz = (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(a->rsa));\n        b_sz = (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(b->rsa));\n        break;\n#endif /* !NO_RSA */\n#ifdef HAVE_ECC\n    case EVP_PKEY_EC:\n        if (a->ecc == NULL || a->ecc->internal == NULL ||\n            b->ecc == NULL || b->ecc->internal == NULL) {\n            return ret;\n        }\n        a_sz = wc_ecc_size((ecc_key*)(a->ecc->internal));\n        b_sz = wc_ecc_size((ecc_key*)(b->ecc->internal));\n        break;\n#endif /* HAVE_ECC */\n    default:\n        break;\n    } /* switch (a->type) */\n\n    /* check size */\n    if (a_sz <= 0 || b_sz <= 0 || a_sz != b_sz) {\n        return ret;\n    }\n\n    /* check public key size */\n    if (a->pkey_sz > 0 && b->pkey_sz > 0 && a->pkey_sz != b->pkey_sz) {\n        return ret;\n    }\n\n    /* check public key */\n    if (a->pkey.ptr && b->pkey.ptr) {\n        if (XMEMCMP(a->pkey.ptr, b->pkey.ptr, a->pkey_sz) != 0) {\n            return ret;\n        }\n    }\n    ret = 0; /* success */\n\n    return ret;\n}\n\n\n/* Initialize structure for signing\n *\n * ctx  WOLFSSL_EVP_MD_CTX structure to initialize\n * type is the type of message digest to use\n *\n * returns WOLFSSL_SUCCESS on success\n */\nint wolfSSL_EVP_SignInit(WOLFSSL_EVP_MD_CTX *ctx, const WOLFSSL_EVP_MD *type)\n{\n    if (ctx == NULL) return WOLFSSL_FAILURE;\n    WOLFSSL_ENTER(\"EVP_SignInit\");\n    return wolfSSL_EVP_DigestInit(ctx,type);\n}\n\nWOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx,\n                                     const WOLFSSL_EVP_MD* type,\n                                     WOLFSSL_ENGINE *impl)\n{\n    if (ctx == NULL) return WOLFSSL_FAILURE;\n    WOLFSSL_ENTER(\"EVP_SignInit\");\n    return wolfSSL_EVP_DigestInit_ex(ctx,type,impl);\n}\n\n\n/* Update structure with data for signing\n *\n * ctx  WOLFSSL_EVP_MD_CTX structure to update\n * data buffer holding data to update with for sign\n * len  length of data buffer\n *\n * returns WOLFSSL_SUCCESS on success\n */\nint wolfSSL_EVP_SignUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *data, size_t len)\n{\n    if (ctx == NULL) return 0;\n    WOLFSSL_ENTER(\"EVP_SignUpdate(\");\n    return wolfSSL_EVP_DigestUpdate(ctx, data, len);\n}\n\n/* macro gaurd because currently only used with RSA */\n#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)\n/* Helper function for getting the NID value from md\n *\n * returns the NID value associated with md on success */\nstatic int md2nid(const unsigned char md)\n{\n    const char * d;\n    d = (const char *)wolfSSL_EVP_get_md(md);\n    if (XSTRNCMP(d, \"SHA\", 3) == 0) {\n        if (XSTRLEN(d) > 3) {\n            if (XSTRNCMP(d, \"SHA256\", 6) == 0) {\n                return NID_sha256;\n            }\n            if (XSTRNCMP(d, \"SHA384\", 6) == 0) {\n                return NID_sha384;\n            }\n            if (XSTRNCMP(d, \"SHA512\", 6) == 0) {\n                return NID_sha512;\n            }\n            WOLFSSL_MSG(\"Unknown SHA type\");\n            return 0;\n        }\n        else {\n            return NID_sha1;\n        }\n    }\n    if (XSTRNCMP(d, \"MD5\", 3) == 0)\n        return NID_md5;\n    return 0;\n}\n#endif /* NO_RSA */\n\n/* Finalize structure for signing\n *\n * ctx    WOLFSSL_EVP_MD_CTX structure to finalize\n * sigret buffer to hold resulting signature\n * siglen length of sigret buffer\n * pkey   key to sign with\n *\n * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure\n */\nint wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret,\n                  unsigned int *siglen, WOLFSSL_EVP_PKEY *pkey)\n{\n    unsigned int mdsize;\n    unsigned char md[WC_MAX_DIGEST_SIZE];\n    int ret;\n    if (ctx == NULL) return WOLFSSL_FAILURE;\n    WOLFSSL_ENTER(\"EVP_SignFinal\");\n\n    ret = wolfSSL_EVP_DigestFinal(ctx, md, &mdsize);\n    if (ret <= 0) return ret;\n\n    (void)sigret;\n    (void)siglen;\n\n    switch (pkey->type) {\n#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)\n    case EVP_PKEY_RSA: {\n        int nid = md2nid(ctx->macType);\n        if (nid < 0) break;\n        return wolfSSL_RSA_sign(nid, md, mdsize, sigret,\n                                siglen, pkey->rsa);\n    }\n#endif /* NO_RSA */\n\n    case EVP_PKEY_DSA:\n    case EVP_PKEY_EC:\n        WOLFSSL_MSG(\"not implemented\");\n        FALL_THROUGH;\n    default:\n        break;\n    }\n    return WOLFSSL_FAILURE;\n}\n\n\n/* Initialize structure for verifying signature\n *\n * ctx  WOLFSSL_EVP_MD_CTX structure to initialize\n * type is the type of message digest to use\n *\n * returns WOLFSSL_SUCCESS on success\n */\nint wolfSSL_EVP_VerifyInit(WOLFSSL_EVP_MD_CTX *ctx, const WOLFSSL_EVP_MD *type)\n{\n    if (ctx == NULL) return WOLFSSL_FAILURE;\n    WOLFSSL_ENTER(\"EVP_VerifyInit\");\n    return wolfSSL_EVP_DigestInit(ctx,type);\n}\n\n\n/* Update structure for verifying signature\n *\n * ctx  WOLFSSL_EVP_MD_CTX structure to update\n * data buffer holding data to update with for verify\n * len  length of data buffer\n *\n * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure\n */\nint wolfSSL_EVP_VerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *data, size_t len)\n{\n    if (ctx == NULL) return WOLFSSL_FAILURE;\n    WOLFSSL_ENTER(\"EVP_VerifyUpdate\");\n    return wolfSSL_EVP_DigestUpdate(ctx, data, len);\n}\n\n\n/* Finalize structure for verifying signature\n *\n * ctx    WOLFSSL_EVP_MD_CTX structure to finalize\n * sig    buffer holding signature\n * siglen length of sig buffer\n * pkey   key to verify with\n *\n * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure\n */\nint wolfSSL_EVP_VerifyFinal(WOLFSSL_EVP_MD_CTX *ctx,\n        unsigned char*sig, unsigned int siglen, WOLFSSL_EVP_PKEY *pkey)\n{\n    int ret;\n    unsigned char md[WC_MAX_DIGEST_SIZE];\n    unsigned int mdsize;\n\n    if (ctx == NULL) return WOLFSSL_FAILURE;\n    WOLFSSL_ENTER(\"EVP_VerifyFinal\");\n    ret = wolfSSL_EVP_DigestFinal(ctx, md, &mdsize);\n    if (ret <= 0) return ret;\n\n    (void)sig;\n    (void)siglen;\n\n    switch (pkey->type) {\n#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)\n    case EVP_PKEY_RSA: {\n        int nid = md2nid(ctx->macType);\n        if (nid < 0) break;\n        return wolfSSL_RSA_verify(nid, md, mdsize, sig,\n                (unsigned int)siglen, pkey->rsa);\n    }\n#endif /* NO_RSA */\n\n    case EVP_PKEY_DSA:\n    case EVP_PKEY_EC:\n        WOLFSSL_MSG(\"not implemented\");\n        FALL_THROUGH;\n    default:\n        break;\n    }\n    return WOLFSSL_FAILURE;\n}\n\nint wolfSSL_EVP_add_cipher(const WOLFSSL_EVP_CIPHER *cipher)\n{\n    (void)cipher;\n    /* nothing to do */\n    return 0;\n}\n\n\nWOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_mac_key(int type, ENGINE* e,\n                                          const unsigned char* key, int keylen)\n{\n    WOLFSSL_EVP_PKEY* pkey;\n\n    (void)e;\n\n    if (type != EVP_PKEY_HMAC || (key == NULL && keylen != 0))\n        return NULL;\n\n    pkey = wolfSSL_PKEY_new();\n    if (pkey != NULL) {\n        pkey->pkey.ptr = (char*)XMALLOC(keylen, NULL, DYNAMIC_TYPE_PUBLIC_KEY);\n        if (pkey->pkey.ptr == NULL && keylen > 0) {\n            wolfSSL_EVP_PKEY_free(pkey);\n            pkey = NULL;\n        }\n        else {\n            XMEMCPY(pkey->pkey.ptr, key, keylen);\n            pkey->pkey_sz = keylen;\n            pkey->type = pkey->save_type = type;\n        }\n    }\n\n    return pkey;\n}\n\n\nconst unsigned char* wolfSSL_EVP_PKEY_get0_hmac(const WOLFSSL_EVP_PKEY* pkey,\n                                                size_t* len)\n{\n    if (pkey == NULL || len == NULL)\n        return NULL;\n\n    *len = (size_t)pkey->pkey_sz;\n\n    return (const unsigned char*)pkey->pkey.ptr;\n}\n\n\n/* Initialize an EVP_DigestSign/Verify operation.\n * Initialize a digest for RSA and ECC keys, or HMAC for HMAC key.\n */\nstatic int wolfSSL_evp_digest_pk_init(WOLFSSL_EVP_MD_CTX *ctx,\n                                      WOLFSSL_EVP_PKEY_CTX **pctx,\n                                      const WOLFSSL_EVP_MD *type,\n                                      WOLFSSL_ENGINE *e,\n                                      WOLFSSL_EVP_PKEY *pkey)\n{\n    if (pkey->type == EVP_PKEY_HMAC) {\n        int                  hashType;\n        const unsigned char* key;\n        size_t               keySz;\n\n        if (XSTRNCMP(type, \"SHA256\", 6) == 0) {\n            hashType = WC_SHA256;\n        }\n    #ifdef WOLFSSL_SHA224\n        else if (XSTRNCMP(type, \"SHA224\", 6) == 0) {\n            hashType = WC_SHA224;\n        }\n    #endif\n    #ifdef WOLFSSL_SHA384\n        else if (XSTRNCMP(type, \"SHA384\", 6) == 0) {\n            hashType = WC_SHA384;\n        }\n    #endif\n    #ifdef WOLFSSL_SHA512\n        else if (XSTRNCMP(type, \"SHA512\", 6) == 0) {\n            hashType = WC_SHA512;\n        }\n    #endif\n    #ifndef NO_MD5\n        else if (XSTRNCMP(type, \"MD5\", 3) == 0) {\n            hashType = WC_MD5;\n        }\n    #endif\n    #ifndef NO_SHA\n        /* has to be last since would pick or 224, 256, 384, or 512 too */\n        else if (XSTRNCMP(type, \"SHA\", 3) == 0) {\n             hashType = WC_SHA;\n        }\n    #endif /* NO_SHA */\n        else\n             return BAD_FUNC_ARG;\n\n        key = wolfSSL_EVP_PKEY_get0_hmac(pkey, &keySz);\n\n        if (wc_HmacInit(&ctx->hash.hmac, NULL, INVALID_DEVID) != 0)\n            return WOLFSSL_FAILURE;\n\n        if (wc_HmacSetKey(&ctx->hash.hmac, hashType, key, (word32)keySz) != 0)\n            return WOLFSSL_FAILURE;\n\n        ctx->macType = NID_hmac & 0xFF;\n    }\n    else {\n        int ret;\n\n        if (ctx->pctx == NULL)\n            ctx->pctx = wolfSSL_EVP_PKEY_CTX_new(pkey, e);\n        if (ctx->pctx == NULL)\n            return WOLFSSL_FAILURE;\n\n        ret = wolfSSL_EVP_DigestInit(ctx, type);\n        if (ret == WOLFSSL_SUCCESS && pctx != NULL)\n            *pctx = ctx->pctx;\n        return ret;\n    }\n\n    return WOLFSSL_SUCCESS;\n}\n\n/* Update an EVP_DigestSign/Verify operation.\n * Update a digest for RSA and ECC keys, or HMAC for HMAC key.\n */\nstatic int wolfssl_evp_digest_pk_update(WOLFSSL_EVP_MD_CTX *ctx,\n                                        const void *d, unsigned int cnt)\n{\n    if (ctx->pctx == NULL) {\n        if (ctx->macType != (NID_hmac & 0xFF))\n            return WOLFSSL_FAILURE;\n\n        if (wc_HmacUpdate(&ctx->hash.hmac, (const byte *)d, cnt) != 0)\n            return WOLFSSL_FAILURE;\n\n        return WOLFSSL_SUCCESS;\n    }\n    else\n        return wolfSSL_EVP_DigestUpdate(ctx, d, cnt);\n}\n\n/* Finalize an EVP_DigestSign/Verify operation - common part only.\n * Finalize a digest for RSA and ECC keys, or HMAC for HMAC key.\n * Copies the digest so that you can keep updating.\n */\nstatic int wolfssl_evp_digest_pk_final(WOLFSSL_EVP_MD_CTX *ctx,\n                                       unsigned char *md, unsigned int* mdlen)\n{\n    int  ret;\n\n    if (ctx->pctx == NULL) {\n        Hmac hmacCopy;\n\n        if (ctx->macType != (NID_hmac & 0xFF))\n            return WOLFSSL_FAILURE;\n\n        if (wolfSSL_HmacCopy(&hmacCopy, &ctx->hash.hmac) != WOLFSSL_SUCCESS)\n            return WOLFSSL_FAILURE;\n        ret = wc_HmacFinal(&hmacCopy, md) == 0;\n        wc_HmacFree(&hmacCopy);\n        return ret;\n    }\n    else {\n        WOLFSSL_EVP_MD_CTX ctxCopy;\n\n        if (wolfSSL_EVP_MD_CTX_copy_ex(&ctxCopy, ctx) != WOLFSSL_SUCCESS)\n            return WOLFSSL_FAILURE;\n\n        ret = wolfSSL_EVP_DigestFinal(&ctxCopy, md, mdlen);\n        wolfSSL_EVP_MD_CTX_cleanup(&ctxCopy);\n        return ret;\n    }\n}\n\n/* Get the length of the mac based on the digest algorithm. */\nstatic int wolfssl_mac_len(unsigned char macType)\n{\n    int hashLen;\n\n    switch (macType) {\n    #ifndef NO_MD5\n        case WC_MD5:\n            hashLen = WC_MD5_DIGEST_SIZE;\n            break;\n    #endif /* !NO_MD5 */\n\n    #ifndef NO_SHA\n        case WC_SHA:\n            hashLen = WC_SHA_DIGEST_SIZE;\n            break;\n    #endif /* !NO_SHA */\n\n    #ifdef WOLFSSL_SHA224\n        case WC_SHA224:\n            hashLen = WC_SHA224_DIGEST_SIZE;\n            break;\n    #endif /* WOLFSSL_SHA224 */\n\n    #ifndef NO_SHA256\n        case WC_SHA256:\n            hashLen = WC_SHA256_DIGEST_SIZE;\n            break;\n    #endif /* !NO_SHA256 */\n\n    #ifdef WOLFSSL_SHA384\n        case WC_SHA384:\n            hashLen = WC_SHA384_DIGEST_SIZE;\n            break;\n    #endif /* WOLFSSL_SHA384 */\n    #ifdef WOLFSSL_SHA512\n        case WC_SHA512:\n            hashLen = WC_SHA512_DIGEST_SIZE;\n            break;\n    #endif /* WOLFSSL_SHA512 */\n\n    #ifdef HAVE_BLAKE2\n        case BLAKE2B_ID:\n            hashLen = BLAKE2B_OUTBYTES;\n            break;\n    #endif /* HAVE_BLAKE2 */\n\n        default:\n            hashLen = 0;\n    }\n\n    return hashLen;\n}\n\nint wolfSSL_EVP_DigestSignInit(WOLFSSL_EVP_MD_CTX *ctx,\n                               WOLFSSL_EVP_PKEY_CTX **pctx,\n                               const WOLFSSL_EVP_MD *type,\n                               WOLFSSL_ENGINE *e,\n                               WOLFSSL_EVP_PKEY *pkey)\n{\n    WOLFSSL_ENTER(\"EVP_DigestSignInit\");\n\n    if (ctx == NULL || type == NULL || pkey == NULL)\n        return BAD_FUNC_ARG;\n\n    return wolfSSL_evp_digest_pk_init(ctx, pctx, type, e, pkey);\n}\n\n\nint wolfSSL_EVP_DigestSignUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *d,\n                                 unsigned int cnt)\n{\n    WOLFSSL_ENTER(\"EVP_DigestSignUpdate\");\n\n    if (ctx == NULL || d == NULL)\n        return BAD_FUNC_ARG;\n\n    return wolfssl_evp_digest_pk_update(ctx, d, cnt);\n}\n\nint wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig,\n                                size_t *siglen)\n{\n    unsigned char digest[WC_MAX_DIGEST_SIZE];\n    unsigned int  hashLen;\n    int           ret = WOLFSSL_FAILURE;\n\n    WOLFSSL_ENTER(\"EVP_DigestSignFinal\");\n\n    if (ctx == NULL || siglen == NULL)\n        return WOLFSSL_FAILURE;\n\n    /* Return the maximum size of the signaure when sig is NULL. */\n    if (ctx->pctx == NULL) {\n        if (ctx->macType != (NID_hmac & 0xFF))\n            return WOLFSSL_FAILURE;\n\n        hashLen = wolfssl_mac_len(ctx->hash.hmac.macType);\n\n        if (sig == NULL) {\n            *siglen = hashLen;\n            return WOLFSSL_SUCCESS;\n        }\n    }\n#ifndef NO_RSA\n    else if (ctx->pctx->pkey->type == EVP_PKEY_RSA) {\n        if (sig == NULL) {\n            *siglen = wolfSSL_RSA_size(ctx->pctx->pkey->rsa);\n            return WOLFSSL_SUCCESS;\n        }\n    }\n#endif /* !NO_RSA */\n#ifdef HAVE_ECC\n    else if (ctx->pctx->pkey->type == EVP_PKEY_EC) {\n        if (sig == NULL) {\n            /* SEQ + INT + INT */\n            *siglen = ecc_sets[ctx->pctx->pkey->ecc->group->curve_idx].size * 2\n                    + 8;\n            return WOLFSSL_SUCCESS;\n        }\n    }\n#endif\n\n    if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0)\n        return WOLFSSL_FAILURE;\n\n    if (ctx->pctx == NULL) {\n        /* Copy the HMAC result as signature. */\n        if ((unsigned int)(*siglen) > hashLen)\n            *siglen = hashLen;\n        /* May be a truncated signature. */\n\n        XMEMCPY(sig, digest, *siglen);\n        ret = WOLFSSL_SUCCESS;\n    }\n    else {\n        /* Sign the digest. */\n        switch (ctx->pctx->pkey->type) {\n    #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)\n        case EVP_PKEY_RSA: {\n            unsigned int sigSz;\n            int          nid = md2nid(ctx->macType);\n            if (nid < 0)\n                break;\n            ret = wolfSSL_RSA_sign(nid, digest, hashLen, sig, &sigSz,\n                                   ctx->pctx->pkey->rsa);\n            if (ret >= 0)\n                *siglen = sigSz;\n            break;\n        }\n    #endif /* NO_RSA */\n\n    #ifdef HAVE_ECC\n        case EVP_PKEY_EC: {\n            WOLFSSL_ECDSA_SIG *ecdsaSig;\n            ecdsaSig = wolfSSL_ECDSA_do_sign(digest, hashLen,\n                                             ctx->pctx->pkey->ecc);\n            if (ecdsaSig == NULL)\n                break;\n            *siglen = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig);\n            wolfSSL_ECDSA_SIG_free(ecdsaSig);\n            ret = WOLFSSL_SUCCESS;\n            break;\n        }\n    #endif\n        default:\n            break;\n        }\n    }\n\n    ForceZero(digest, sizeof(digest));\n    return ret;\n}\n\nint wolfSSL_EVP_DigestVerifyInit(WOLFSSL_EVP_MD_CTX *ctx,\n                                 WOLFSSL_EVP_PKEY_CTX **pctx,\n                                 const WOLFSSL_EVP_MD *type,\n                                 WOLFSSL_ENGINE *e,\n                                 WOLFSSL_EVP_PKEY *pkey)\n{\n    WOLFSSL_ENTER(\"EVP_DigestVerifyInit\");\n\n    if (ctx == NULL || type == NULL || pkey == NULL)\n        return BAD_FUNC_ARG;\n\n    return wolfSSL_evp_digest_pk_init(ctx, pctx, type, e, pkey);\n}\n\n\nint wolfSSL_EVP_DigestVerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *d,\n                                   size_t cnt)\n{\n    WOLFSSL_ENTER(\"EVP_DigestVerifyUpdate\");\n\n    if (ctx == NULL || d == NULL)\n        return BAD_FUNC_ARG;\n\n    return wolfssl_evp_digest_pk_update(ctx, d, (unsigned int)cnt);\n}\n\n\nint wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx,\n                                  const unsigned char *sig, size_t siglen)\n{\n    unsigned char digest[WC_MAX_DIGEST_SIZE];\n    unsigned int  hashLen;\n\n    WOLFSSL_ENTER(\"EVP_DigestVerifyFinal\");\n\n    if (ctx == NULL || sig == NULL)\n        return WOLFSSL_FAILURE;\n\n    if (ctx->pctx == NULL) {\n        if (ctx->macType != (NID_hmac & 0xFF))\n            return WOLFSSL_FAILURE;\n\n        hashLen = wolfssl_mac_len(ctx->hash.hmac.macType);\n\n        if (siglen > hashLen)\n            return WOLFSSL_FAILURE;\n        /* May be a truncated signature. */\n    }\n\n    if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0)\n        return WOLFSSL_FAILURE;\n\n    if (ctx->pctx == NULL) {\n        /* Check HMAC result matches the signature. */\n        if (XMEMCMP(sig, digest, siglen) == 0)\n            return WOLFSSL_SUCCESS;\n        return WOLFSSL_FAILURE;\n    }\n    else {\n        /* Verify the signature with the digest. */\n        switch (ctx->pctx->pkey->type) {\n    #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)\n        case EVP_PKEY_RSA: {\n            int nid = md2nid(ctx->macType);\n            if (nid < 0)\n                return WOLFSSL_FAILURE;\n            return wolfSSL_RSA_verify(nid, digest, hashLen, sig,\n                                      (unsigned int)siglen,\n                                      ctx->pctx->pkey->rsa);\n        }\n    #endif /* NO_RSA */\n\n    #ifdef HAVE_ECC\n        case EVP_PKEY_EC: {\n            int ret;\n            WOLFSSL_ECDSA_SIG *ecdsaSig;\n            ecdsaSig = wolfSSL_d2i_ECDSA_SIG(NULL, &sig, (long)siglen);\n            if (ecdsaSig == NULL)\n                return WOLFSSL_FAILURE;\n            ret = wolfSSL_ECDSA_do_verify(digest, hashLen, ecdsaSig,\n                                          ctx->pctx->pkey->ecc);\n            wolfSSL_ECDSA_SIG_free(ecdsaSig);\n            return ret;\n        }\n    #endif\n        default:\n            break;\n        }\n    }\n\n    return WOLFSSL_FAILURE;\n}\n\n#ifdef WOLFSSL_APACHE_HTTPD\n#if !defined(USE_WINDOWS_API) && !defined(MICROCHIP_PIC32)\n    #include <termios.h>\n#endif\n\n#ifndef XGETPASSWD\n    static int XGETPASSWD(char* buf, int bufSz) {\n        int ret = WOLFSSL_SUCCESS;\n\n        /* turn off echo for passwords */\n    #ifdef USE_WINDOWS_API\n        DWORD originalTerm;\n        DWORD newTerm;\n        CONSOLE_SCREEN_BUFFER_INFO screenOrig;\n        HANDLE stdinHandle = GetStdHandle(STD_INPUT_HANDLE);\n        if (GetConsoleMode(stdinHandle, &originalTerm) == 0) {\n            WOLFSSL_MSG(\"Couldn't get the original terminal settings\");\n            return WOLFSSL_FAILURE;\n        }\n        newTerm = originalTerm;\n        newTerm &= ~ENABLE_ECHO_INPUT;\n        if (SetConsoleMode(stdinHandle, newTerm) == 0) {\n            WOLFSSL_MSG(\"Couldn't turn off echo\");\n            return WOLFSSL_FAILURE;\n        }\n    #else\n        struct termios originalTerm;\n        struct termios newTerm;\n        if (tcgetattr(STDIN_FILENO, &originalTerm) != 0) {\n            WOLFSSL_MSG(\"Couldn't get the original terminal settings\");\n            return WOLFSSL_FAILURE;\n        }\n        XMEMCPY(&newTerm, &originalTerm, sizeof(struct termios));\n\n        newTerm.c_lflag &= ~ECHO;\n        newTerm.c_lflag |= (ICANON | ECHONL);\n        if (tcsetattr(STDIN_FILENO, TCSANOW, &newTerm) != 0) {\n            WOLFSSL_MSG(\"Couldn't turn off echo\");\n            return WOLFSSL_FAILURE;\n        }\n    #endif\n\n        if (XFGETS(buf, bufSz, stdin) == NULL) {\n            ret = WOLFSSL_FAILURE;\n        }\n\n        /* restore default echo */\n    #ifdef USE_WINDOWS_API\n        if (SetConsoleMode(stdinHandle, originalTerm) == 0) {\n            WOLFSSL_MSG(\"Couldn't restore the terminal settings\");\n            return WOLFSSL_FAILURE;\n        }\n    #else\n        if (tcsetattr(STDIN_FILENO, TCSANOW, &originalTerm) != 0) {\n            WOLFSSL_MSG(\"Couldn't restore the terminal settings\");\n            return WOLFSSL_FAILURE;\n        }\n    #endif\n        return ret;\n    }\n#endif\n\n/* returns 0 on success and -2 or -1 on failure */\nint wolfSSL_EVP_read_pw_string(char* buf, int bufSz, const char* banner, int v)\n{\n    printf(\"%s\", banner);\n    if (XGETPASSWD(buf, bufSz) == WOLFSSL_FAILURE) {\n        return -1;\n    }\n    (void)v; /* fgets always sanity checks size of input vs buffer */\n    return 0;\n}\n#endif /* WOLFSSL_APACHE_HTTPD */\n#endif /* WOLFSSL_EVP_INCLUDED */\n\n#if defined(OPENSSL_EXTRA) && !defined(NO_PWDBASED) && !defined(NO_SHA)\nint wolfSSL_PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,\n                                               const unsigned char *salt,\n                                               int saltlen, int iter,\n                                               int keylen, unsigned char *out)\n{\n    const char *nostring = \"\";\n    int ret = 0;\n\n    if (pass == NULL) {\n        passlen = 0;\n        pass = nostring;\n    }\n    else if (passlen == -1) {\n        passlen = (int)XSTRLEN(pass);\n    }\n\n    ret = wc_PBKDF2((byte*)out, (byte*)pass, passlen, (byte*)salt, saltlen,\n                    iter, keylen, WC_SHA);\n    if (ret == 0)\n        return WOLFSSL_SUCCESS;\n    else\n        return WOLFSSL_FAILURE;\n}\n#endif /* OPENSSL_EXTRA && !NO_PWDBASED !NO_SHA*/\n\n#if defined(OPENSSL_EXTRA) && !defined(NO_PWDBASED)\nWOLFSSL_API int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen,\n                                           const unsigned char *salt,\n                                           int saltlen, int iter,\n                                           const WOLFSSL_EVP_MD *digest,\n                                           int keylen, unsigned char *out)\n{\n    const char *nostring = \"\";\n    int ret = 0;\n\n    if (pass == NULL) {\n        passlen = 0;\n        pass = nostring;\n    } else if (passlen == -1) {\n        passlen = (int)XSTRLEN(pass);\n    }\n\n    ret = wc_PBKDF2((byte*)out, (byte*)pass, passlen, (byte*)salt, saltlen,\n                    iter, keylen, wolfSSL_EVP_MD_type(digest));\n    if (ret == 0)\n        return WOLFSSL_SUCCESS;\n    else\n        return WOLFSSL_FAILURE;\n}\n#endif /* OPENSSL_EXTRA && !NO_PWDBASED */\n"
  },
  {
    "path": "src/wolfcrypt/src/fe_low_mem.c",
    "content": "/* fe_low_mem.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n/* Based from Daniel Beer's public domain work. */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if defined(HAVE_CURVE25519) || defined(HAVE_ED25519)\n#if defined(CURVE25519_SMALL) || defined(ED25519_SMALL) /* use slower code that takes less memory */\n\n#include <wolfssl/wolfcrypt/fe_operations.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\nvoid fprime_copy(byte *x, const byte *a)\n{\n    int i;\n    for (i = 0; i < F25519_SIZE; i++)\n        x[i] = a[i];\n}\n\n\nvoid lm_copy(byte* x, const byte* a)\n{\n    int i;\n    for (i = 0; i < F25519_SIZE; i++)\n        x[i] = a[i];\n}\n\n#if ((defined(HAVE_CURVE25519) && !defined(CURVE25519_SMALL)) || \\\n    (defined(HAVE_ED25519) && !defined(ED25519_SMALL))) &&      \\\n    !defined(FREESCALE_LTC_ECC)\n    /* to be Complementary to fe_low_mem.c */\n#else\nvoid fe_init(void)\n{\n}\n#endif\n\n#ifdef CURVE25519_SMALL\n\n/* Double an X-coordinate */\nstatic void xc_double(byte *x3, byte *z3,\n\t\t      const byte *x1, const byte *z1)\n{\n\t/* Explicit formulas database: dbl-1987-m\n\t *\n\t * source 1987 Montgomery \"Speeding the Pollard and elliptic\n\t *   curve methods of factorization\", page 261, fourth display\n\t * compute X3 = (X1^2-Z1^2)^2\n\t * compute Z3 = 4 X1 Z1 (X1^2 + a X1 Z1 + Z1^2)\n\t */\n\tbyte x1sq[F25519_SIZE];\n\tbyte z1sq[F25519_SIZE];\n\tbyte x1z1[F25519_SIZE];\n\tbyte a[F25519_SIZE];\n\n\tfe_mul__distinct(x1sq, x1, x1);\n\tfe_mul__distinct(z1sq, z1, z1);\n\tfe_mul__distinct(x1z1, x1, z1);\n\n\tlm_sub(a, x1sq, z1sq);\n\tfe_mul__distinct(x3, a, a);\n\n\tfe_mul_c(a, x1z1, 486662);\n\tlm_add(a, x1sq, a);\n\tlm_add(a, z1sq, a);\n\tfe_mul__distinct(x1sq, x1z1, a);\n\tfe_mul_c(z3, x1sq, 4);\n}\n\n\n/* Differential addition */\nstatic void xc_diffadd(byte *x5, byte *z5,\n\t\t       const byte *x1, const byte *z1,\n\t\t       const byte *x2, const byte *z2,\n\t\t       const byte *x3, const byte *z3)\n{\n\t/* Explicit formulas database: dbl-1987-m3\n\t *\n\t * source 1987 Montgomery \"Speeding the Pollard and elliptic curve\n\t *   methods of factorization\", page 261, fifth display, plus\n\t *   common-subexpression elimination\n\t * compute A = X2+Z2\n\t * compute B = X2-Z2\n\t * compute C = X3+Z3\n\t * compute D = X3-Z3\n\t * compute DA = D A\n\t * compute CB = C B\n\t * compute X5 = Z1(DA+CB)^2\n\t * compute Z5 = X1(DA-CB)^2\n\t */\n\tbyte da[F25519_SIZE];\n\tbyte cb[F25519_SIZE];\n\tbyte a[F25519_SIZE];\n\tbyte b[F25519_SIZE];\n\n\tlm_add(a, x2, z2);\n\tlm_sub(b, x3, z3); /* D */\n\tfe_mul__distinct(da, a, b);\n\n\tlm_sub(b, x2, z2);\n\tlm_add(a, x3, z3); /* C */\n\tfe_mul__distinct(cb, a, b);\n\n\tlm_add(a, da, cb);\n\tfe_mul__distinct(b, a, a);\n\tfe_mul__distinct(x5, z1, b);\n\n\tlm_sub(a, da, cb);\n\tfe_mul__distinct(b, a, a);\n\tfe_mul__distinct(z5, x1, b);\n}\n\n#ifndef FREESCALE_LTC_ECC\nint curve25519(byte *result, byte *e, byte *q)\n{\n\t/* Current point: P_m */\n\tbyte xm[F25519_SIZE];\n\tbyte zm[F25519_SIZE] = {1};\n\n\t/* Predecessor: P_(m-1) */\n\tbyte xm1[F25519_SIZE] = {1};\n\tbyte zm1[F25519_SIZE] = {0};\n\n\tint i;\n\n\t/* Note: bit 254 is assumed to be 1 */\n\tlm_copy(xm, q);\n\n\tfor (i = 253; i >= 0; i--) {\n\t\tconst int bit = (e[i >> 3] >> (i & 7)) & 1;\n\t\tbyte xms[F25519_SIZE];\n\t\tbyte zms[F25519_SIZE];\n\n\t\t/* From P_m and P_(m-1), compute P_(2m) and P_(2m-1) */\n\t\txc_diffadd(xm1, zm1, q, f25519_one, xm, zm, xm1, zm1);\n\t\txc_double(xm, zm, xm, zm);\n\n\t\t/* Compute P_(2m+1) */\n\t\txc_diffadd(xms, zms, xm1, zm1, xm, zm, q, f25519_one);\n\n\t\t/* Select:\n\t\t *   bit = 1 --> (P_(2m+1), P_(2m))\n\t\t *   bit = 0 --> (P_(2m), P_(2m-1))\n\t\t */\n\t\tfe_select(xm1, xm1, xm, bit);\n\t\tfe_select(zm1, zm1, zm, bit);\n\t\tfe_select(xm, xm, xms, bit);\n\t\tfe_select(zm, zm, zms, bit);\n\t}\n\n\t/* Freeze out of projective coordinates */\n\tfe_inv__distinct(zm1, zm);\n\tfe_mul__distinct(result, zm1, xm);\n\tfe_normalize(result);\n    return 0;\n}\n#endif /* !FREESCALE_LTC_ECC */\n#endif /* CURVE25519_SMALL */\n\n\nstatic void raw_add(byte *x, const byte *p)\n{\n\tword16 c = 0;\n\tint i;\n\n\tfor (i = 0; i < F25519_SIZE; i++) {\n\t\tc += ((word16)x[i]) + ((word16)p[i]);\n\t\tx[i] = (byte)c;\n\t\tc >>= 8;\n\t}\n}\n\n\nstatic void raw_try_sub(byte *x, const byte *p)\n{\n\tbyte minusp[F25519_SIZE];\n\tword16 c = 0;\n\tint i;\n\n\tfor (i = 0; i < F25519_SIZE; i++) {\n\t\tc = ((word16)x[i]) - ((word16)p[i]) - c;\n\t\tminusp[i] = (byte)c;\n\t\tc = (c >> 8) & 1;\n\t}\n\n\tfprime_select(x, minusp, x, (byte)c);\n}\n\n\nstatic int prime_msb(const byte *p)\n{\n    int i;\n    byte x;\n    int shift = 1;\n    int z     = F25519_SIZE - 1;\n\n   /*\n       Test for any hot bits.\n       As soon as one instance is encountered set shift to 0.\n    */\n\tfor (i = F25519_SIZE - 1; i >= 0; i--) {\n        shift &= ((shift ^ ((-p[i] | p[i]) >> 7)) & 1);\n        z -= shift;\n    }\n\tx = p[z];\n\tz <<= 3;\n    shift = 1;\n    for (i = 0; i < 8; i++) {\n        shift &= ((-(x >> i) | (x >> i)) >> (7 - i) & 1);\n        z += shift;\n    }\n\n\treturn z - 1;\n}\n\n\nvoid fprime_select(byte *dst, const byte *zero, const byte *one, byte condition)\n{\n\tconst byte mask = -condition;\n\tint i;\n\n\tfor (i = 0; i < F25519_SIZE; i++)\n\t\tdst[i] = zero[i] ^ (mask & (one[i] ^ zero[i]));\n}\n\n\nvoid fprime_add(byte *r, const byte *a, const byte *modulus)\n{\n\traw_add(r, a);\n\traw_try_sub(r, modulus);\n}\n\n\nvoid fprime_sub(byte *r, const byte *a, const byte *modulus)\n{\n\traw_add(r, modulus);\n\traw_try_sub(r, a);\n\traw_try_sub(r, modulus);\n}\n\n\nvoid fprime_mul(byte *r, const byte *a, const byte *b,\n\t\tconst byte *modulus)\n{\n\tword16 c = 0;\n\tint i,j;\n\n\tXMEMSET(r, 0, F25519_SIZE);\n\n\tfor (i = prime_msb(modulus); i >= 0; i--) {\n\t\tconst byte bit = (b[i >> 3] >> (i & 7)) & 1;\n\t\tbyte plusa[F25519_SIZE];\n\n\t    for (j = 0; j < F25519_SIZE; j++) {\n\t\t    c |= ((word16)r[j]) << 1;\n\t\t    r[j] = (byte)c;\n\t\t    c >>= 8;\n\t    }\n\t\traw_try_sub(r, modulus);\n\n\t\tfprime_copy(plusa, r);\n\t\tfprime_add(plusa, a, modulus);\n\n\t\tfprime_select(r, r, plusa, bit);\n\t}\n}\n\n\nvoid fe_load(byte *x, word32 c)\n{\n\tword32 i;\n\n\tfor (i = 0; i < sizeof(c); i++) {\n\t\tx[i] = c;\n\t\tc >>= 8;\n\t}\n\n\tfor (; i < F25519_SIZE; i++)\n\t\tx[i] = 0;\n}\n\n\nvoid fe_normalize(byte *x)\n{\n\tbyte minusp[F25519_SIZE];\n\tword16 c;\n\tint i;\n\n\t/* Reduce using 2^255 = 19 mod p */\n\tc = (x[31] >> 7) * 19;\n\tx[31] &= 127;\n\n\tfor (i = 0; i < F25519_SIZE; i++) {\n\t\tc += x[i];\n\t\tx[i] = (byte)c;\n\t\tc >>= 8;\n\t}\n\n\t/* The number is now less than 2^255 + 18, and therefore less than\n\t * 2p. Try subtracting p, and conditionally load the subtracted\n\t * value if underflow did not occur.\n\t */\n\tc = 19;\n\n\tfor (i = 0; i + 1 < F25519_SIZE; i++) {\n\t\tc += x[i];\n\t\tminusp[i] = (byte)c;\n\t\tc >>= 8;\n\t}\n\n\tc += ((word16)x[i]) - 128;\n\tminusp[31] = (byte)c;\n\n\t/* Load x-p if no underflow */\n\tfe_select(x, minusp, x, (c >> 15) & 1);\n}\n\n\nvoid fe_select(byte *dst,\n\t\t   const byte *zero, const byte *one,\n\t\t   byte condition)\n{\n\tconst byte mask = -condition;\n\tint i;\n\n\tfor (i = 0; i < F25519_SIZE; i++)\n\t\tdst[i] = zero[i] ^ (mask & (one[i] ^ zero[i]));\n}\n\n\nvoid lm_add(byte* r, const byte* a, const byte* b)\n{\n\tword16 c = 0;\n\tint i;\n\n\t/* Add */\n\tfor (i = 0; i < F25519_SIZE; i++) {\n\t\tc >>= 8;\n\t\tc += ((word16)a[i]) + ((word16)b[i]);\n\t\tr[i] = (byte)c;\n\t}\n\n\t/* Reduce with 2^255 = 19 mod p */\n\tr[31] &= 127;\n\tc = (c >> 7) * 19;\n\n\tfor (i = 0; i < F25519_SIZE; i++) {\n\t\tc += r[i];\n\t\tr[i] = (byte)c;\n\t\tc >>= 8;\n\t}\n}\n\n\nvoid lm_sub(byte* r, const byte* a, const byte* b)\n{\n\tword32 c = 0;\n\tint i;\n\n\t/* Calculate a + 2p - b, to avoid underflow */\n\tc = 218;\n\tfor (i = 0; i + 1 < F25519_SIZE; i++) {\n\t\tc += 65280 + ((word32)a[i]) - ((word32)b[i]);\n\t\tr[i] = c;\n\t\tc >>= 8;\n\t}\n\n\tc += ((word32)a[31]) - ((word32)b[31]);\n\tr[31] = c & 127;\n\tc = (c >> 7) * 19;\n\n\tfor (i = 0; i < F25519_SIZE; i++) {\n\t\tc += r[i];\n\t\tr[i] = c;\n\t\tc >>= 8;\n\t}\n}\n\n\nvoid lm_neg(byte* r, const byte* a)\n{\n\tword32 c = 0;\n\tint i;\n\n\t/* Calculate 2p - a, to avoid underflow */\n\tc = 218;\n\tfor (i = 0; i + 1 < F25519_SIZE; i++) {\n\t\tc += 65280 - ((word32)a[i]);\n\t\tr[i] = c;\n\t\tc >>= 8;\n\t}\n\n\tc -= ((word32)a[31]);\n\tr[31] = c & 127;\n\tc = (c >> 7) * 19;\n\n\tfor (i = 0; i < F25519_SIZE; i++) {\n\t\tc += r[i];\n\t\tr[i] = c;\n\t\tc >>= 8;\n\t}\n}\n\n\nvoid fe_mul__distinct(byte *r, const byte *a, const byte *b)\n{\n\tword32 c = 0;\n\tint i;\n\n\tfor (i = 0; i < F25519_SIZE; i++) {\n\t\tint j;\n\n\t\tc >>= 8;\n\t\tfor (j = 0; j <= i; j++)\n\t\t\tc += ((word32)a[j]) * ((word32)b[i - j]);\n\n\t\tfor (; j < F25519_SIZE; j++)\n\t\t\tc += ((word32)a[j]) *\n\t\t\t     ((word32)b[i + F25519_SIZE - j]) * 38;\n\n\t\tr[i] = c;\n\t}\n\n\tr[31] &= 127;\n\tc = (c >> 7) * 19;\n\n\tfor (i = 0; i < F25519_SIZE; i++) {\n\t\tc += r[i];\n\t\tr[i] = c;\n\t\tc >>= 8;\n\t}\n}\n\n\nvoid lm_mul(byte *r, const byte* a, const byte *b)\n{\n\tbyte tmp[F25519_SIZE];\n\n\tfe_mul__distinct(tmp, a, b);\n\tlm_copy(r, tmp);\n}\n\n\nvoid fe_mul_c(byte *r, const byte *a, word32 b)\n{\n\tword32 c = 0;\n\tint i;\n\n\tfor (i = 0; i < F25519_SIZE; i++) {\n\t\tc >>= 8;\n\t\tc += b * ((word32)a[i]);\n\t\tr[i] = c;\n\t}\n\n\tr[31] &= 127;\n\tc >>= 7;\n\tc *= 19;\n\n\tfor (i = 0; i < F25519_SIZE; i++) {\n\t\tc += r[i];\n\t\tr[i] = c;\n\t\tc >>= 8;\n\t}\n}\n\n\nvoid fe_inv__distinct(byte *r, const byte *x)\n{\n\tbyte s[F25519_SIZE];\n\tint i;\n\n\t/* This is a prime field, so by Fermat's little theorem:\n\t *\n\t *     x^(p-1) = 1 mod p\n\t *\n\t * Therefore, raise to (p-2) = 2^255-21 to get a multiplicative\n\t * inverse.\n\t *\n\t * This is a 255-bit binary number with the digits:\n\t *\n\t *     11111111... 01011\n\t *\n\t * We compute the result by the usual binary chain, but\n\t * alternate between keeping the accumulator in r and s, so as\n\t * to avoid copying temporaries.\n\t */\n\n\t/* 1 1 */\n\tfe_mul__distinct(s, x, x);\n\tfe_mul__distinct(r, s, x);\n\n\t/* 1 x 248 */\n\tfor (i = 0; i < 248; i++) {\n\t\tfe_mul__distinct(s, r, r);\n\t\tfe_mul__distinct(r, s, x);\n\t}\n\n\t/* 0 */\n\tfe_mul__distinct(s, r, r);\n\n\t/* 1 */\n\tfe_mul__distinct(r, s, s);\n\tfe_mul__distinct(s, r, x);\n\n\t/* 0 */\n\tfe_mul__distinct(r, s, s);\n\n\t/* 1 */\n\tfe_mul__distinct(s, r, r);\n\tfe_mul__distinct(r, s, x);\n\n\t/* 1 */\n\tfe_mul__distinct(s, r, r);\n\tfe_mul__distinct(r, s, x);\n}\n\n\nvoid lm_invert(byte *r, const byte *x)\n{\n\tbyte tmp[F25519_SIZE];\n\n\tfe_inv__distinct(tmp, x);\n\tlm_copy(r, tmp);\n}\n\n\n/* Raise x to the power of (p-5)/8 = 2^252-3, using s for temporary\n * storage.\n */\nstatic void exp2523(byte *r, const byte *x, byte *s)\n{\n\tint i;\n\n\t/* This number is a 252-bit number with the binary expansion:\n\t *\n\t *     111111... 01\n\t */\n\n\t/* 1 1 */\n\tfe_mul__distinct(r, x, x);\n\tfe_mul__distinct(s, r, x);\n\n\t/* 1 x 248 */\n\tfor (i = 0; i < 248; i++) {\n\t\tfe_mul__distinct(r, s, s);\n\t\tfe_mul__distinct(s, r, x);\n\t}\n\n\t/* 0 */\n\tfe_mul__distinct(r, s, s);\n\n\t/* 1 */\n\tfe_mul__distinct(s, r, r);\n\tfe_mul__distinct(r, s, x);\n}\n\n\nvoid fe_sqrt(byte *r, const byte *a)\n{\n\tbyte v[F25519_SIZE];\n\tbyte i[F25519_SIZE];\n\tbyte x[F25519_SIZE];\n\tbyte y[F25519_SIZE];\n\n\t/* v = (2a)^((p-5)/8) [x = 2a] */\n\tfe_mul_c(x, a, 2);\n\texp2523(v, x, y);\n\n\t/* i = 2av^2 - 1 */\n\tfe_mul__distinct(y, v, v);\n\tfe_mul__distinct(i, x, y);\n\tfe_load(y, 1);\n\tlm_sub(i, i, y);\n\n\t/* r = avi */\n\tfe_mul__distinct(x, v, a);\n\tfe_mul__distinct(r, x, i);\n}\n\n#endif /* CURVE25519_SMALL || ED25519_SMALL */\n#endif /* HAVE_CURVE25519 || HAVE_ED25519 */\n"
  },
  {
    "path": "src/wolfcrypt/src/fe_operations.c",
    "content": "/* fe_operations.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n /* Based On Daniel J Bernstein's curve25519 Public Domain ref10 work. */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if defined(HAVE_CURVE25519) || defined(HAVE_ED25519)\n#if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL) /* run when not defined to use small memory math */\n\n#include <wolfssl/wolfcrypt/fe_operations.h>\n#include <stdint.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#ifdef CURVED25519_X64\n/* Assembly code in fe_x25519_asm.* */\n#elif defined(WOLFSSL_ARMASM)\n/* Assembly code in fe_armv[78]_x25519.* */\n#elif defined(CURVED25519_128BIT)\n#include \"fe_x25519_128.i\"\n#else\n\n#if defined(HAVE_CURVE25519) || \\\n    (defined(HAVE_ED25519) && !defined(ED25519_SMALL))\n/*\nfe means field element.\nHere the field is \\Z/(2^255-19).\nAn element t, entries t[0]...t[9], represents the integer\nt[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].\nBounds on each t[i] vary depending on context.\n*/\n\nuint64_t load_3(const unsigned char *in)\n{\n  uint64_t result;\n  result = (uint64_t) in[0];\n  result |= ((uint64_t) in[1]) << 8;\n  result |= ((uint64_t) in[2]) << 16;\n  return result;\n}\n\n\nuint64_t load_4(const unsigned char *in)\n{\n  uint64_t result;\n  result = (uint64_t) in[0];\n  result |= ((uint64_t) in[1]) << 8;\n  result |= ((uint64_t) in[2]) << 16;\n  result |= ((uint64_t) in[3]) << 24;\n  return result;\n}\n#endif\n\n/*\nh = 1\n*/\n\nvoid fe_1(fe h)\n{\n  h[0] = 1;\n  h[1] = 0;\n  h[2] = 0;\n  h[3] = 0;\n  h[4] = 0;\n  h[5] = 0;\n  h[6] = 0;\n  h[7] = 0;\n  h[8] = 0;\n  h[9] = 0;\n}\n\n\n/*\nh = 0\n*/\n\nvoid fe_0(fe h)\n{\n  h[0] = 0;\n  h[1] = 0;\n  h[2] = 0;\n  h[3] = 0;\n  h[4] = 0;\n  h[5] = 0;\n  h[6] = 0;\n  h[7] = 0;\n  h[8] = 0;\n  h[9] = 0;\n}\n\n\n#if ((defined(HAVE_CURVE25519) && !defined(CURVE25519_SMALL)) || \\\n     (defined(HAVE_ED25519) && !defined(ED25519_SMALL))) && \\\n    !defined(FREESCALE_LTC_ECC)\n/* to be Complementary to fe_low_mem.c */\nvoid fe_init(void)\n{\n}\n#endif\n\n#if defined(HAVE_CURVE25519) && !defined(CURVE25519_SMALL) && \\\n    !defined(FREESCALE_LTC_ECC)\nint curve25519(byte* q, byte* n, byte* p)\n{\n#if 0\n  unsigned char e[32];\n#endif\n  fe x1;\n  fe x2;\n  fe z2;\n  fe x3;\n  fe z3;\n  fe tmp0;\n  fe tmp1;\n  int pos;\n  unsigned int swap;\n  unsigned int b;\n\n  /* Clamp already done during key generation and import */\n#if 0\n  {\n    unsigned int i;\n    for (i = 0;i < 32;++i) e[i] = n[i];\n    e[0] &= 248;\n    e[31] &= 127;\n    e[31] |= 64;\n  }\n#endif\n\n  fe_frombytes(x1,p);\n  fe_1(x2);\n  fe_0(z2);\n  fe_copy(x3,x1);\n  fe_1(z3);\n\n  swap = 0;\n  for (pos = 254;pos >= 0;--pos) {\n#if 0\n    b = e[pos / 8] >> (pos & 7);\n#else\n    b = n[pos / 8] >> (pos & 7);\n#endif\n    b &= 1;\n    swap ^= b;\n    fe_cswap(x2,x3,swap);\n    fe_cswap(z2,z3,swap);\n    swap = b;\n\n    /* montgomery */\n\tfe_sub(tmp0,x3,z3);\n\tfe_sub(tmp1,x2,z2);\n\tfe_add(x2,x2,z2);\n\tfe_add(z2,x3,z3);\n\tfe_mul(z3,tmp0,x2);\n\tfe_mul(z2,z2,tmp1);\n\tfe_sq(tmp0,tmp1);\n\tfe_sq(tmp1,x2);\n\tfe_add(x3,z3,z2);\n\tfe_sub(z2,z3,z2);\n\tfe_mul(x2,tmp1,tmp0);\n\tfe_sub(tmp1,tmp1,tmp0);\n\tfe_sq(z2,z2);\n\tfe_mul121666(z3,tmp1);\n\tfe_sq(x3,x3);\n\tfe_add(tmp0,tmp0,z3);\n\tfe_mul(z3,x1,z2);\n\tfe_mul(z2,tmp1,tmp0);\n  }\n  fe_cswap(x2,x3,swap);\n  fe_cswap(z2,z3,swap);\n\n  fe_invert(z2,z2);\n  fe_mul(x2,x2,z2);\n  fe_tobytes(q,x2);\n\n  return 0;\n}\n#endif /* HAVE_CURVE25519 && !CURVE25519_SMALL && !FREESCALE_LTC_ECC */\n\n\n/*\nh = f * f\nCan overlap h with f.\n\nPreconditions:\n   |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.\n\nPostconditions:\n   |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.\n*/\n\n/*\nSee fe_mul.c for discussion of implementation strategy.\n*/\n\nvoid fe_sq(fe h,const fe f)\n{\n  int32_t f0 = f[0];\n  int32_t f1 = f[1];\n  int32_t f2 = f[2];\n  int32_t f3 = f[3];\n  int32_t f4 = f[4];\n  int32_t f5 = f[5];\n  int32_t f6 = f[6];\n  int32_t f7 = f[7];\n  int32_t f8 = f[8];\n  int32_t f9 = f[9];\n  int32_t f0_2 = 2 * f0;\n  int32_t f1_2 = 2 * f1;\n  int32_t f2_2 = 2 * f2;\n  int32_t f3_2 = 2 * f3;\n  int32_t f4_2 = 2 * f4;\n  int32_t f5_2 = 2 * f5;\n  int32_t f6_2 = 2 * f6;\n  int32_t f7_2 = 2 * f7;\n  int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */\n  int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */\n  int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */\n  int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */\n  int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */\n  int64_t f0f0    = f0   * (int64_t) f0;\n  int64_t f0f1_2  = f0_2 * (int64_t) f1;\n  int64_t f0f2_2  = f0_2 * (int64_t) f2;\n  int64_t f0f3_2  = f0_2 * (int64_t) f3;\n  int64_t f0f4_2  = f0_2 * (int64_t) f4;\n  int64_t f0f5_2  = f0_2 * (int64_t) f5;\n  int64_t f0f6_2  = f0_2 * (int64_t) f6;\n  int64_t f0f7_2  = f0_2 * (int64_t) f7;\n  int64_t f0f8_2  = f0_2 * (int64_t) f8;\n  int64_t f0f9_2  = f0_2 * (int64_t) f9;\n  int64_t f1f1_2  = f1_2 * (int64_t) f1;\n  int64_t f1f2_2  = f1_2 * (int64_t) f2;\n  int64_t f1f3_4  = f1_2 * (int64_t) f3_2;\n  int64_t f1f4_2  = f1_2 * (int64_t) f4;\n  int64_t f1f5_4  = f1_2 * (int64_t) f5_2;\n  int64_t f1f6_2  = f1_2 * (int64_t) f6;\n  int64_t f1f7_4  = f1_2 * (int64_t) f7_2;\n  int64_t f1f8_2  = f1_2 * (int64_t) f8;\n  int64_t f1f9_76 = f1_2 * (int64_t) f9_38;\n  int64_t f2f2    = f2   * (int64_t) f2;\n  int64_t f2f3_2  = f2_2 * (int64_t) f3;\n  int64_t f2f4_2  = f2_2 * (int64_t) f4;\n  int64_t f2f5_2  = f2_2 * (int64_t) f5;\n  int64_t f2f6_2  = f2_2 * (int64_t) f6;\n  int64_t f2f7_2  = f2_2 * (int64_t) f7;\n  int64_t f2f8_38 = f2_2 * (int64_t) f8_19;\n  int64_t f2f9_38 = f2   * (int64_t) f9_38;\n  int64_t f3f3_2  = f3_2 * (int64_t) f3;\n  int64_t f3f4_2  = f3_2 * (int64_t) f4;\n  int64_t f3f5_4  = f3_2 * (int64_t) f5_2;\n  int64_t f3f6_2  = f3_2 * (int64_t) f6;\n  int64_t f3f7_76 = f3_2 * (int64_t) f7_38;\n  int64_t f3f8_38 = f3_2 * (int64_t) f8_19;\n  int64_t f3f9_76 = f3_2 * (int64_t) f9_38;\n  int64_t f4f4    = f4   * (int64_t) f4;\n  int64_t f4f5_2  = f4_2 * (int64_t) f5;\n  int64_t f4f6_38 = f4_2 * (int64_t) f6_19;\n  int64_t f4f7_38 = f4   * (int64_t) f7_38;\n  int64_t f4f8_38 = f4_2 * (int64_t) f8_19;\n  int64_t f4f9_38 = f4   * (int64_t) f9_38;\n  int64_t f5f5_38 = f5   * (int64_t) f5_38;\n  int64_t f5f6_38 = f5_2 * (int64_t) f6_19;\n  int64_t f5f7_76 = f5_2 * (int64_t) f7_38;\n  int64_t f5f8_38 = f5_2 * (int64_t) f8_19;\n  int64_t f5f9_76 = f5_2 * (int64_t) f9_38;\n  int64_t f6f6_19 = f6   * (int64_t) f6_19;\n  int64_t f6f7_38 = f6   * (int64_t) f7_38;\n  int64_t f6f8_38 = f6_2 * (int64_t) f8_19;\n  int64_t f6f9_38 = f6   * (int64_t) f9_38;\n  int64_t f7f7_38 = f7   * (int64_t) f7_38;\n  int64_t f7f8_38 = f7_2 * (int64_t) f8_19;\n  int64_t f7f9_76 = f7_2 * (int64_t) f9_38;\n  int64_t f8f8_19 = f8   * (int64_t) f8_19;\n  int64_t f8f9_38 = f8   * (int64_t) f9_38;\n  int64_t f9f9_38 = f9   * (int64_t) f9_38;\n  int64_t h0 = f0f0  +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;\n  int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;\n  int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;\n  int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;\n  int64_t h4 = f0f4_2+f1f3_4 +f2f2   +f5f9_76+f6f8_38+f7f7_38;\n  int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;\n  int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;\n  int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;\n  int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4   +f9f9_38;\n  int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;\n  int64_t carry0;\n  int64_t carry1;\n  int64_t carry2;\n  int64_t carry3;\n  int64_t carry4;\n  int64_t carry5;\n  int64_t carry6;\n  int64_t carry7;\n  int64_t carry8;\n  int64_t carry9;\n\n  carry0 = (h0 + (int64_t) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;\n  carry4 = (h4 + (int64_t) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;\n\n  carry1 = (h1 + (int64_t) (1UL<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;\n  carry5 = (h5 + (int64_t) (1UL<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;\n\n  carry2 = (h2 + (int64_t) (1UL<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;\n  carry6 = (h6 + (int64_t) (1UL<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;\n\n  carry3 = (h3 + (int64_t) (1UL<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;\n  carry7 = (h7 + (int64_t) (1UL<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;\n\n  carry4 = (h4 + (int64_t) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;\n  carry8 = (h8 + (int64_t) (1UL<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;\n\n  carry9 = (h9 + (int64_t) (1UL<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;\n\n  carry0 = (h0 + (int64_t) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;\n\n  h[0] = (int32_t)h0;\n  h[1] = (int32_t)h1;\n  h[2] = (int32_t)h2;\n  h[3] = (int32_t)h3;\n  h[4] = (int32_t)h4;\n  h[5] = (int32_t)h5;\n  h[6] = (int32_t)h6;\n  h[7] = (int32_t)h7;\n  h[8] = (int32_t)h8;\n  h[9] = (int32_t)h9;\n}\n\n\n/*\nh = f + g\nCan overlap h with f or g.\n\nPreconditions:\n   |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.\n   |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.\n\nPostconditions:\n   |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.\n*/\n\nvoid fe_add(fe h,const fe f,const fe g)\n{\n  int32_t f0 = f[0];\n  int32_t f1 = f[1];\n  int32_t f2 = f[2];\n  int32_t f3 = f[3];\n  int32_t f4 = f[4];\n  int32_t f5 = f[5];\n  int32_t f6 = f[6];\n  int32_t f7 = f[7];\n  int32_t f8 = f[8];\n  int32_t f9 = f[9];\n  int32_t g0 = g[0];\n  int32_t g1 = g[1];\n  int32_t g2 = g[2];\n  int32_t g3 = g[3];\n  int32_t g4 = g[4];\n  int32_t g5 = g[5];\n  int32_t g6 = g[6];\n  int32_t g7 = g[7];\n  int32_t g8 = g[8];\n  int32_t g9 = g[9];\n  int32_t h0 = f0 + g0;\n  int32_t h1 = f1 + g1;\n  int32_t h2 = f2 + g2;\n  int32_t h3 = f3 + g3;\n  int32_t h4 = f4 + g4;\n  int32_t h5 = f5 + g5;\n  int32_t h6 = f6 + g6;\n  int32_t h7 = f7 + g7;\n  int32_t h8 = f8 + g8;\n  int32_t h9 = f9 + g9;\n  h[0] = h0;\n  h[1] = h1;\n  h[2] = h2;\n  h[3] = h3;\n  h[4] = h4;\n  h[5] = h5;\n  h[6] = h6;\n  h[7] = h7;\n  h[8] = h8;\n  h[9] = h9;\n}\n\n\n/*\nPreconditions:\n  |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.\n\nWrite p=2^255-19; q=floor(h/p).\nBasic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).\n\nProof:\n  Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.\n  Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.\n\n  Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).\n  Then 0<y<1.\n\n  Write r=h-pq.\n  Have 0<=r<=p-1=2^255-20.\n  Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.\n\n  Write x=r+19(2^-255)r+y.\n  Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.\n\n  Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))\n  so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.\n*/\n\nvoid fe_tobytes(unsigned char *s,const fe h)\n{\n  int32_t h0 = h[0];\n  int32_t h1 = h[1];\n  int32_t h2 = h[2];\n  int32_t h3 = h[3];\n  int32_t h4 = h[4];\n  int32_t h5 = h[5];\n  int32_t h6 = h[6];\n  int32_t h7 = h[7];\n  int32_t h8 = h[8];\n  int32_t h9 = h[9];\n  int32_t q;\n  int32_t carry0;\n  int32_t carry1;\n  int32_t carry2;\n  int32_t carry3;\n  int32_t carry4;\n  int32_t carry5;\n  int32_t carry6;\n  int32_t carry7;\n  int32_t carry8;\n  int32_t carry9;\n\n  q = (19 * h9 + (((int32_t) 1) << 24)) >> 25;\n  q = (h0 + q) >> 26;\n  q = (h1 + q) >> 25;\n  q = (h2 + q) >> 26;\n  q = (h3 + q) >> 25;\n  q = (h4 + q) >> 26;\n  q = (h5 + q) >> 25;\n  q = (h6 + q) >> 26;\n  q = (h7 + q) >> 25;\n  q = (h8 + q) >> 26;\n  q = (h9 + q) >> 25;\n\n  /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */\n  h0 += 19 * q;\n  /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */\n\n  carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26;\n  carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25;\n  carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26;\n  carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25;\n  carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26;\n  carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25;\n  carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26;\n  carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25;\n  carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26;\n  carry9 = h9 >> 25;               h9 -= carry9 << 25;\n                  /* h10 = carry9 */\n\n  /*\n  Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.\n  Have h0+...+2^230 h9 between 0 and 2^255-1;\n  evidently 2^255 h10-2^255 q = 0.\n  Goal: Output h0+...+2^230 h9.\n  */\n\n  s[0] = (byte)(h0 >> 0);\n  s[1] = (byte)(h0 >> 8);\n  s[2] = (byte)(h0 >> 16);\n  s[3] = (byte)((h0 >> 24) | (h1 << 2));\n  s[4] = (byte)(h1 >> 6);\n  s[5] = (byte)(h1 >> 14);\n  s[6] = (byte)((h1 >> 22) | (h2 << 3));\n  s[7] = (byte)(h2 >> 5);\n  s[8] = (byte)(h2 >> 13);\n  s[9] = (byte)((h2 >> 21) | (h3 << 5));\n  s[10] = (byte)(h3 >> 3);\n  s[11] = (byte)(h3 >> 11);\n  s[12] = (byte)((h3 >> 19) | (h4 << 6));\n  s[13] = (byte)(h4 >> 2);\n  s[14] = (byte)(h4 >> 10);\n  s[15] = (byte)(h4 >> 18);\n  s[16] = (byte)(h5 >> 0);\n  s[17] = (byte)(h5 >> 8);\n  s[18] = (byte)(h5 >> 16);\n  s[19] = (byte)((h5 >> 24) | (h6 << 1));\n  s[20] = (byte)(h6 >> 7);\n  s[21] = (byte)(h6 >> 15);\n  s[22] = (byte)((h6 >> 23) | (h7 << 3));\n  s[23] = (byte)(h7 >> 5);\n  s[24] = (byte)(h7 >> 13);\n  s[25] = (byte)((h7 >> 21) | (h8 << 4));\n  s[26] = (byte)(h8 >> 4);\n  s[27] = (byte)(h8 >> 12);\n  s[28] = (byte)((h8 >> 20) | (h9 << 6));\n  s[29] = (byte)(h9 >> 2);\n  s[30] = (byte)(h9 >> 10);\n  s[31] = (byte)(h9 >> 18);\n}\n\n\n/*\nh = f - g\nCan overlap h with f or g.\n\nPreconditions:\n   |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.\n   |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.\n\nPostconditions:\n   |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.\n*/\n\nvoid fe_sub(fe h,const fe f,const fe g)\n{\n  int32_t f0 = f[0];\n  int32_t f1 = f[1];\n  int32_t f2 = f[2];\n  int32_t f3 = f[3];\n  int32_t f4 = f[4];\n  int32_t f5 = f[5];\n  int32_t f6 = f[6];\n  int32_t f7 = f[7];\n  int32_t f8 = f[8];\n  int32_t f9 = f[9];\n  int32_t g0 = g[0];\n  int32_t g1 = g[1];\n  int32_t g2 = g[2];\n  int32_t g3 = g[3];\n  int32_t g4 = g[4];\n  int32_t g5 = g[5];\n  int32_t g6 = g[6];\n  int32_t g7 = g[7];\n  int32_t g8 = g[8];\n  int32_t g9 = g[9];\n  int32_t h0 = f0 - g0;\n  int32_t h1 = f1 - g1;\n  int32_t h2 = f2 - g2;\n  int32_t h3 = f3 - g3;\n  int32_t h4 = f4 - g4;\n  int32_t h5 = f5 - g5;\n  int32_t h6 = f6 - g6;\n  int32_t h7 = f7 - g7;\n  int32_t h8 = f8 - g8;\n  int32_t h9 = f9 - g9;\n  h[0] = h0;\n  h[1] = h1;\n  h[2] = h2;\n  h[3] = h3;\n  h[4] = h4;\n  h[5] = h5;\n  h[6] = h6;\n  h[7] = h7;\n  h[8] = h8;\n  h[9] = h9;\n}\n\n\n#if defined(HAVE_CURVE25519) || \\\n    (defined(HAVE_ED25519) && !defined(ED25519_SMALL))\n/*\nIgnores top bit of h.\n*/\n\nvoid fe_frombytes(fe h,const unsigned char *s)\n{\n  int64_t h0 = load_4(s);\n  int64_t h1 = load_3(s + 4) << 6;\n  int64_t h2 = load_3(s + 7) << 5;\n  int64_t h3 = load_3(s + 10) << 3;\n  int64_t h4 = load_3(s + 13) << 2;\n  int64_t h5 = load_4(s + 16);\n  int64_t h6 = load_3(s + 20) << 7;\n  int64_t h7 = load_3(s + 23) << 5;\n  int64_t h8 = load_3(s + 26) << 4;\n  int64_t h9 = (load_3(s + 29) & 8388607) << 2;\n  int64_t carry0;\n  int64_t carry1;\n  int64_t carry2;\n  int64_t carry3;\n  int64_t carry4;\n  int64_t carry5;\n  int64_t carry6;\n  int64_t carry7;\n  int64_t carry8;\n  int64_t carry9;\n\n  carry9 = (h9 + (int64_t) (1UL<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;\n  carry1 = (h1 + (int64_t) (1UL<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;\n  carry3 = (h3 + (int64_t) (1UL<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;\n  carry5 = (h5 + (int64_t) (1UL<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;\n  carry7 = (h7 + (int64_t) (1UL<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;\n\n  carry0 = (h0 + (int64_t) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;\n  carry2 = (h2 + (int64_t) (1UL<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;\n  carry4 = (h4 + (int64_t) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;\n  carry6 = (h6 + (int64_t) (1UL<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;\n  carry8 = (h8 + (int64_t) (1UL<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;\n\n  h[0] = (int32_t)h0;\n  h[1] = (int32_t)h1;\n  h[2] = (int32_t)h2;\n  h[3] = (int32_t)h3;\n  h[4] = (int32_t)h4;\n  h[5] = (int32_t)h5;\n  h[6] = (int32_t)h6;\n  h[7] = (int32_t)h7;\n  h[8] = (int32_t)h8;\n  h[9] = (int32_t)h9;\n}\n#endif\n\n\nvoid fe_invert(fe out,const fe z)\n{\n  fe t0;\n  fe t1;\n  fe t2;\n  fe t3;\n  int i;\n\n  /* pow225521 */\n  fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0);\n  fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1);\n  fe_mul(t1,z,t1);\n  fe_mul(t0,t0,t1);\n  fe_sq(t2,t0); for (i = 1;i < 1;++i) fe_sq(t2,t2);\n  fe_mul(t1,t1,t2);\n  fe_sq(t2,t1); for (i = 1;i < 5;++i) fe_sq(t2,t2);\n  fe_mul(t1,t2,t1);\n  fe_sq(t2,t1); for (i = 1;i < 10;++i) fe_sq(t2,t2);\n  fe_mul(t2,t2,t1);\n  fe_sq(t3,t2); for (i = 1;i < 20;++i) fe_sq(t3,t3);\n  fe_mul(t2,t3,t2);\n  fe_sq(t2,t2); for (i = 1;i < 10;++i) fe_sq(t2,t2);\n  fe_mul(t1,t2,t1);\n  fe_sq(t2,t1); for (i = 1;i < 50;++i) fe_sq(t2,t2);\n  fe_mul(t2,t2,t1);\n  fe_sq(t3,t2); for (i = 1;i < 100;++i) fe_sq(t3,t3);\n  fe_mul(t2,t3,t2);\n  fe_sq(t2,t2); for (i = 1;i < 50;++i) fe_sq(t2,t2);\n  fe_mul(t1,t2,t1);\n  fe_sq(t1,t1); for (i = 1;i < 5;++i) fe_sq(t1,t1);\n  fe_mul(out,t1,t0);\n\n  return;\n}\n\n\n/*\nh = f\n*/\n\nvoid fe_copy(fe h,const fe f)\n{\n  int32_t f0 = f[0];\n  int32_t f1 = f[1];\n  int32_t f2 = f[2];\n  int32_t f3 = f[3];\n  int32_t f4 = f[4];\n  int32_t f5 = f[5];\n  int32_t f6 = f[6];\n  int32_t f7 = f[7];\n  int32_t f8 = f[8];\n  int32_t f9 = f[9];\n  h[0] = f0;\n  h[1] = f1;\n  h[2] = f2;\n  h[3] = f3;\n  h[4] = f4;\n  h[5] = f5;\n  h[6] = f6;\n  h[7] = f7;\n  h[8] = f8;\n  h[9] = f9;\n}\n\n\n/*\nh = f * g\nCan overlap h with f or g.\n\nPreconditions:\n   |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.\n   |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.\n\nPostconditions:\n   |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.\n*/\n\n/*\nNotes on implementation strategy:\n\nUsing schoolbook multiplication.\nKaratsuba would save a little in some cost models.\n\nMost multiplications by 2 and 19 are 32-bit precomputations;\ncheaper than 64-bit postcomputations.\n\nThere is one remaining multiplication by 19 in the carry chain;\none *19 precomputation can be merged into this,\nbut the resulting data flow is considerably less clean.\n\nThere are 12 carries below.\n10 of them are 2-way parallelizable and vectorizable.\nCan get away with 11 carries, but then data flow is much deeper.\n\nWith tighter constraints on inputs can squeeze carries into int32.\n*/\n\nvoid fe_mul(fe h,const fe f,const fe g)\n{\n  int32_t f0 = f[0];\n  int32_t f1 = f[1];\n  int32_t f2 = f[2];\n  int32_t f3 = f[3];\n  int32_t f4 = f[4];\n  int32_t f5 = f[5];\n  int32_t f6 = f[6];\n  int32_t f7 = f[7];\n  int32_t f8 = f[8];\n  int32_t f9 = f[9];\n  int32_t g0 = g[0];\n  int32_t g1 = g[1];\n  int32_t g2 = g[2];\n  int32_t g3 = g[3];\n  int32_t g4 = g[4];\n  int32_t g5 = g[5];\n  int32_t g6 = g[6];\n  int32_t g7 = g[7];\n  int32_t g8 = g[8];\n  int32_t g9 = g[9];\n  int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */\n  int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */\n  int32_t g3_19 = 19 * g3;\n  int32_t g4_19 = 19 * g4;\n  int32_t g5_19 = 19 * g5;\n  int32_t g6_19 = 19 * g6;\n  int32_t g7_19 = 19 * g7;\n  int32_t g8_19 = 19 * g8;\n  int32_t g9_19 = 19 * g9;\n  int32_t f1_2 = 2 * f1;\n  int32_t f3_2 = 2 * f3;\n  int32_t f5_2 = 2 * f5;\n  int32_t f7_2 = 2 * f7;\n  int32_t f9_2 = 2 * f9;\n  int64_t f0g0    = f0   * (int64_t) g0;\n  int64_t f0g1    = f0   * (int64_t) g1;\n  int64_t f0g2    = f0   * (int64_t) g2;\n  int64_t f0g3    = f0   * (int64_t) g3;\n  int64_t f0g4    = f0   * (int64_t) g4;\n  int64_t f0g5    = f0   * (int64_t) g5;\n  int64_t f0g6    = f0   * (int64_t) g6;\n  int64_t f0g7    = f0   * (int64_t) g7;\n  int64_t f0g8    = f0   * (int64_t) g8;\n  int64_t f0g9    = f0   * (int64_t) g9;\n  int64_t f1g0    = f1   * (int64_t) g0;\n  int64_t f1g1_2  = f1_2 * (int64_t) g1;\n  int64_t f1g2    = f1   * (int64_t) g2;\n  int64_t f1g3_2  = f1_2 * (int64_t) g3;\n  int64_t f1g4    = f1   * (int64_t) g4;\n  int64_t f1g5_2  = f1_2 * (int64_t) g5;\n  int64_t f1g6    = f1   * (int64_t) g6;\n  int64_t f1g7_2  = f1_2 * (int64_t) g7;\n  int64_t f1g8    = f1   * (int64_t) g8;\n  int64_t f1g9_38 = f1_2 * (int64_t) g9_19;\n  int64_t f2g0    = f2   * (int64_t) g0;\n  int64_t f2g1    = f2   * (int64_t) g1;\n  int64_t f2g2    = f2   * (int64_t) g2;\n  int64_t f2g3    = f2   * (int64_t) g3;\n  int64_t f2g4    = f2   * (int64_t) g4;\n  int64_t f2g5    = f2   * (int64_t) g5;\n  int64_t f2g6    = f2   * (int64_t) g6;\n  int64_t f2g7    = f2   * (int64_t) g7;\n  int64_t f2g8_19 = f2   * (int64_t) g8_19;\n  int64_t f2g9_19 = f2   * (int64_t) g9_19;\n  int64_t f3g0    = f3   * (int64_t) g0;\n  int64_t f3g1_2  = f3_2 * (int64_t) g1;\n  int64_t f3g2    = f3   * (int64_t) g2;\n  int64_t f3g3_2  = f3_2 * (int64_t) g3;\n  int64_t f3g4    = f3   * (int64_t) g4;\n  int64_t f3g5_2  = f3_2 * (int64_t) g5;\n  int64_t f3g6    = f3   * (int64_t) g6;\n  int64_t f3g7_38 = f3_2 * (int64_t) g7_19;\n  int64_t f3g8_19 = f3   * (int64_t) g8_19;\n  int64_t f3g9_38 = f3_2 * (int64_t) g9_19;\n  int64_t f4g0    = f4   * (int64_t) g0;\n  int64_t f4g1    = f4   * (int64_t) g1;\n  int64_t f4g2    = f4   * (int64_t) g2;\n  int64_t f4g3    = f4   * (int64_t) g3;\n  int64_t f4g4    = f4   * (int64_t) g4;\n  int64_t f4g5    = f4   * (int64_t) g5;\n  int64_t f4g6_19 = f4   * (int64_t) g6_19;\n  int64_t f4g7_19 = f4   * (int64_t) g7_19;\n  int64_t f4g8_19 = f4   * (int64_t) g8_19;\n  int64_t f4g9_19 = f4   * (int64_t) g9_19;\n  int64_t f5g0    = f5   * (int64_t) g0;\n  int64_t f5g1_2  = f5_2 * (int64_t) g1;\n  int64_t f5g2    = f5   * (int64_t) g2;\n  int64_t f5g3_2  = f5_2 * (int64_t) g3;\n  int64_t f5g4    = f5   * (int64_t) g4;\n  int64_t f5g5_38 = f5_2 * (int64_t) g5_19;\n  int64_t f5g6_19 = f5   * (int64_t) g6_19;\n  int64_t f5g7_38 = f5_2 * (int64_t) g7_19;\n  int64_t f5g8_19 = f5   * (int64_t) g8_19;\n  int64_t f5g9_38 = f5_2 * (int64_t) g9_19;\n  int64_t f6g0    = f6   * (int64_t) g0;\n  int64_t f6g1    = f6   * (int64_t) g1;\n  int64_t f6g2    = f6   * (int64_t) g2;\n  int64_t f6g3    = f6   * (int64_t) g3;\n  int64_t f6g4_19 = f6   * (int64_t) g4_19;\n  int64_t f6g5_19 = f6   * (int64_t) g5_19;\n  int64_t f6g6_19 = f6   * (int64_t) g6_19;\n  int64_t f6g7_19 = f6   * (int64_t) g7_19;\n  int64_t f6g8_19 = f6   * (int64_t) g8_19;\n  int64_t f6g9_19 = f6   * (int64_t) g9_19;\n  int64_t f7g0    = f7   * (int64_t) g0;\n  int64_t f7g1_2  = f7_2 * (int64_t) g1;\n  int64_t f7g2    = f7   * (int64_t) g2;\n  int64_t f7g3_38 = f7_2 * (int64_t) g3_19;\n  int64_t f7g4_19 = f7   * (int64_t) g4_19;\n  int64_t f7g5_38 = f7_2 * (int64_t) g5_19;\n  int64_t f7g6_19 = f7   * (int64_t) g6_19;\n  int64_t f7g7_38 = f7_2 * (int64_t) g7_19;\n  int64_t f7g8_19 = f7   * (int64_t) g8_19;\n  int64_t f7g9_38 = f7_2 * (int64_t) g9_19;\n  int64_t f8g0    = f8   * (int64_t) g0;\n  int64_t f8g1    = f8   * (int64_t) g1;\n  int64_t f8g2_19 = f8   * (int64_t) g2_19;\n  int64_t f8g3_19 = f8   * (int64_t) g3_19;\n  int64_t f8g4_19 = f8   * (int64_t) g4_19;\n  int64_t f8g5_19 = f8   * (int64_t) g5_19;\n  int64_t f8g6_19 = f8   * (int64_t) g6_19;\n  int64_t f8g7_19 = f8   * (int64_t) g7_19;\n  int64_t f8g8_19 = f8   * (int64_t) g8_19;\n  int64_t f8g9_19 = f8   * (int64_t) g9_19;\n  int64_t f9g0    = f9   * (int64_t) g0;\n  int64_t f9g1_38 = f9_2 * (int64_t) g1_19;\n  int64_t f9g2_19 = f9   * (int64_t) g2_19;\n  int64_t f9g3_38 = f9_2 * (int64_t) g3_19;\n  int64_t f9g4_19 = f9   * (int64_t) g4_19;\n  int64_t f9g5_38 = f9_2 * (int64_t) g5_19;\n  int64_t f9g6_19 = f9   * (int64_t) g6_19;\n  int64_t f9g7_38 = f9_2 * (int64_t) g7_19;\n  int64_t f9g8_19 = f9   * (int64_t) g8_19;\n  int64_t f9g9_38 = f9_2 * (int64_t) g9_19;\n  int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38;\n  int64_t h1 = f0g1+f1g0   +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19;\n  int64_t h2 = f0g2+f1g1_2 +f2g0   +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38;\n  int64_t h3 = f0g3+f1g2   +f2g1   +f3g0   +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19;\n  int64_t h4 = f0g4+f1g3_2 +f2g2   +f3g1_2 +f4g0   +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38;\n  int64_t h5 = f0g5+f1g4   +f2g3   +f3g2   +f4g1   +f5g0   +f6g9_19+f7g8_19+f8g7_19+f9g6_19;\n  int64_t h6 = f0g6+f1g5_2 +f2g4   +f3g3_2 +f4g2   +f5g1_2 +f6g0   +f7g9_38+f8g8_19+f9g7_38;\n  int64_t h7 = f0g7+f1g6   +f2g5   +f3g4   +f4g3   +f5g2   +f6g1   +f7g0   +f8g9_19+f9g8_19;\n  int64_t h8 = f0g8+f1g7_2 +f2g6   +f3g5_2 +f4g4   +f5g3_2 +f6g2   +f7g1_2 +f8g0   +f9g9_38;\n  int64_t h9 = f0g9+f1g8   +f2g7   +f3g6   +f4g5   +f5g4   +f6g3   +f7g2   +f8g1   +f9g0   ;\n  int64_t carry0;\n  int64_t carry1;\n  int64_t carry2;\n  int64_t carry3;\n  int64_t carry4;\n  int64_t carry5;\n  int64_t carry6;\n  int64_t carry7;\n  int64_t carry8;\n  int64_t carry9;\n\n  /*\n  |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))\n    i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8\n  |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))\n    i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9\n  */\n\n  carry0 = (h0 + (int64_t) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;\n  carry4 = (h4 + (int64_t) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;\n  /* |h0| <= 2^25 */\n  /* |h4| <= 2^25 */\n  /* |h1| <= 1.71*2^59 */\n  /* |h5| <= 1.71*2^59 */\n\n  carry1 = (h1 + (int64_t) (1UL<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;\n  carry5 = (h5 + (int64_t) (1UL<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;\n  /* |h1| <= 2^24; from now on fits into int32 */\n  /* |h5| <= 2^24; from now on fits into int32 */\n  /* |h2| <= 1.41*2^60 */\n  /* |h6| <= 1.41*2^60 */\n\n  carry2 = (h2 + (int64_t) (1UL<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;\n  carry6 = (h6 + (int64_t) (1UL<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;\n  /* |h2| <= 2^25; from now on fits into int32 unchanged */\n  /* |h6| <= 2^25; from now on fits into int32 unchanged */\n  /* |h3| <= 1.71*2^59 */\n  /* |h7| <= 1.71*2^59 */\n\n  carry3 = (h3 + (int64_t) (1UL<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;\n  carry7 = (h7 + (int64_t) (1UL<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;\n  /* |h3| <= 2^24; from now on fits into int32 unchanged */\n  /* |h7| <= 2^24; from now on fits into int32 unchanged */\n  /* |h4| <= 1.72*2^34 */\n  /* |h8| <= 1.41*2^60 */\n\n  carry4 = (h4 + (int64_t) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;\n  carry8 = (h8 + (int64_t) (1UL<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;\n  /* |h4| <= 2^25; from now on fits into int32 unchanged */\n  /* |h8| <= 2^25; from now on fits into int32 unchanged */\n  /* |h5| <= 1.01*2^24 */\n  /* |h9| <= 1.71*2^59 */\n\n  carry9 = (h9 + (int64_t) (1UL<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;\n  /* |h9| <= 2^24; from now on fits into int32 unchanged */\n  /* |h0| <= 1.1*2^39 */\n\n  carry0 = (h0 + (int64_t) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;\n  /* |h0| <= 2^25; from now on fits into int32 unchanged */\n  /* |h1| <= 1.01*2^24 */\n\n  h[0] = (int32_t)h0;\n  h[1] = (int32_t)h1;\n  h[2] = (int32_t)h2;\n  h[3] = (int32_t)h3;\n  h[4] = (int32_t)h4;\n  h[5] = (int32_t)h5;\n  h[6] = (int32_t)h6;\n  h[7] = (int32_t)h7;\n  h[8] = (int32_t)h8;\n  h[9] = (int32_t)h9;\n}\n\n\n/*\nReplace (f,g) with (g,f) if b == 1;\nreplace (f,g) with (f,g) if b == 0.\n\nPreconditions: b in {0,1}.\n*/\n\nvoid fe_cswap(fe f, fe g, int b)\n{\n  int32_t f0 = f[0];\n  int32_t f1 = f[1];\n  int32_t f2 = f[2];\n  int32_t f3 = f[3];\n  int32_t f4 = f[4];\n  int32_t f5 = f[5];\n  int32_t f6 = f[6];\n  int32_t f7 = f[7];\n  int32_t f8 = f[8];\n  int32_t f9 = f[9];\n  int32_t g0 = g[0];\n  int32_t g1 = g[1];\n  int32_t g2 = g[2];\n  int32_t g3 = g[3];\n  int32_t g4 = g[4];\n  int32_t g5 = g[5];\n  int32_t g6 = g[6];\n  int32_t g7 = g[7];\n  int32_t g8 = g[8];\n  int32_t g9 = g[9];\n  int32_t x0 = f0 ^ g0;\n  int32_t x1 = f1 ^ g1;\n  int32_t x2 = f2 ^ g2;\n  int32_t x3 = f3 ^ g3;\n  int32_t x4 = f4 ^ g4;\n  int32_t x5 = f5 ^ g5;\n  int32_t x6 = f6 ^ g6;\n  int32_t x7 = f7 ^ g7;\n  int32_t x8 = f8 ^ g8;\n  int32_t x9 = f9 ^ g9;\n  b = -b;\n  x0 &= b;\n  x1 &= b;\n  x2 &= b;\n  x3 &= b;\n  x4 &= b;\n  x5 &= b;\n  x6 &= b;\n  x7 &= b;\n  x8 &= b;\n  x9 &= b;\n  f[0] = f0 ^ x0;\n  f[1] = f1 ^ x1;\n  f[2] = f2 ^ x2;\n  f[3] = f3 ^ x3;\n  f[4] = f4 ^ x4;\n  f[5] = f5 ^ x5;\n  f[6] = f6 ^ x6;\n  f[7] = f7 ^ x7;\n  f[8] = f8 ^ x8;\n  f[9] = f9 ^ x9;\n  g[0] = g0 ^ x0;\n  g[1] = g1 ^ x1;\n  g[2] = g2 ^ x2;\n  g[3] = g3 ^ x3;\n  g[4] = g4 ^ x4;\n  g[5] = g5 ^ x5;\n  g[6] = g6 ^ x6;\n  g[7] = g7 ^ x7;\n  g[8] = g8 ^ x8;\n  g[9] = g9 ^ x9;\n}\n\n\n/*\nh = f * 121666\nCan overlap h with f.\n\nPreconditions:\n   |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.\n\nPostconditions:\n   |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.\n*/\n\nvoid fe_mul121666(fe h,fe f)\n{\n  int32_t f0 = f[0];\n  int32_t f1 = f[1];\n  int32_t f2 = f[2];\n  int32_t f3 = f[3];\n  int32_t f4 = f[4];\n  int32_t f5 = f[5];\n  int32_t f6 = f[6];\n  int32_t f7 = f[7];\n  int32_t f8 = f[8];\n  int32_t f9 = f[9];\n  int64_t h0 = f0 * (int64_t) 121666;\n  int64_t h1 = f1 * (int64_t) 121666;\n  int64_t h2 = f2 * (int64_t) 121666;\n  int64_t h3 = f3 * (int64_t) 121666;\n  int64_t h4 = f4 * (int64_t) 121666;\n  int64_t h5 = f5 * (int64_t) 121666;\n  int64_t h6 = f6 * (int64_t) 121666;\n  int64_t h7 = f7 * (int64_t) 121666;\n  int64_t h8 = f8 * (int64_t) 121666;\n  int64_t h9 = f9 * (int64_t) 121666;\n  int64_t carry0;\n  int64_t carry1;\n  int64_t carry2;\n  int64_t carry3;\n  int64_t carry4;\n  int64_t carry5;\n  int64_t carry6;\n  int64_t carry7;\n  int64_t carry8;\n  int64_t carry9;\n\n  carry9 = (h9 + (int64_t) (1UL<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;\n  carry1 = (h1 + (int64_t) (1UL<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;\n  carry3 = (h3 + (int64_t) (1UL<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;\n  carry5 = (h5 + (int64_t) (1UL<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;\n  carry7 = (h7 + (int64_t) (1UL<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;\n\n  carry0 = (h0 + (int64_t) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;\n  carry2 = (h2 + (int64_t) (1UL<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;\n  carry4 = (h4 + (int64_t) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;\n  carry6 = (h6 + (int64_t) (1UL<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;\n  carry8 = (h8 + (int64_t) (1UL<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;\n\n  h[0] = (int32_t)h0;\n  h[1] = (int32_t)h1;\n  h[2] = (int32_t)h2;\n  h[3] = (int32_t)h3;\n  h[4] = (int32_t)h4;\n  h[5] = (int32_t)h5;\n  h[6] = (int32_t)h6;\n  h[7] = (int32_t)h7;\n  h[8] = (int32_t)h8;\n  h[9] = (int32_t)h9;\n}\n\n\n/*\nh = 2 * f * f\nCan overlap h with f.\n\nPreconditions:\n   |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.\n\nPostconditions:\n   |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.\n*/\n\n/*\nSee fe_mul.c for discussion of implementation strategy.\n*/\n\nvoid fe_sq2(fe h,const fe f)\n{\n  int32_t f0 = f[0];\n  int32_t f1 = f[1];\n  int32_t f2 = f[2];\n  int32_t f3 = f[3];\n  int32_t f4 = f[4];\n  int32_t f5 = f[5];\n  int32_t f6 = f[6];\n  int32_t f7 = f[7];\n  int32_t f8 = f[8];\n  int32_t f9 = f[9];\n  int32_t f0_2 = 2 * f0;\n  int32_t f1_2 = 2 * f1;\n  int32_t f2_2 = 2 * f2;\n  int32_t f3_2 = 2 * f3;\n  int32_t f4_2 = 2 * f4;\n  int32_t f5_2 = 2 * f5;\n  int32_t f6_2 = 2 * f6;\n  int32_t f7_2 = 2 * f7;\n  int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */\n  int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */\n  int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */\n  int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */\n  int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */\n  int64_t f0f0    = f0   * (int64_t) f0;\n  int64_t f0f1_2  = f0_2 * (int64_t) f1;\n  int64_t f0f2_2  = f0_2 * (int64_t) f2;\n  int64_t f0f3_2  = f0_2 * (int64_t) f3;\n  int64_t f0f4_2  = f0_2 * (int64_t) f4;\n  int64_t f0f5_2  = f0_2 * (int64_t) f5;\n  int64_t f0f6_2  = f0_2 * (int64_t) f6;\n  int64_t f0f7_2  = f0_2 * (int64_t) f7;\n  int64_t f0f8_2  = f0_2 * (int64_t) f8;\n  int64_t f0f9_2  = f0_2 * (int64_t) f9;\n  int64_t f1f1_2  = f1_2 * (int64_t) f1;\n  int64_t f1f2_2  = f1_2 * (int64_t) f2;\n  int64_t f1f3_4  = f1_2 * (int64_t) f3_2;\n  int64_t f1f4_2  = f1_2 * (int64_t) f4;\n  int64_t f1f5_4  = f1_2 * (int64_t) f5_2;\n  int64_t f1f6_2  = f1_2 * (int64_t) f6;\n  int64_t f1f7_4  = f1_2 * (int64_t) f7_2;\n  int64_t f1f8_2  = f1_2 * (int64_t) f8;\n  int64_t f1f9_76 = f1_2 * (int64_t) f9_38;\n  int64_t f2f2    = f2   * (int64_t) f2;\n  int64_t f2f3_2  = f2_2 * (int64_t) f3;\n  int64_t f2f4_2  = f2_2 * (int64_t) f4;\n  int64_t f2f5_2  = f2_2 * (int64_t) f5;\n  int64_t f2f6_2  = f2_2 * (int64_t) f6;\n  int64_t f2f7_2  = f2_2 * (int64_t) f7;\n  int64_t f2f8_38 = f2_2 * (int64_t) f8_19;\n  int64_t f2f9_38 = f2   * (int64_t) f9_38;\n  int64_t f3f3_2  = f3_2 * (int64_t) f3;\n  int64_t f3f4_2  = f3_2 * (int64_t) f4;\n  int64_t f3f5_4  = f3_2 * (int64_t) f5_2;\n  int64_t f3f6_2  = f3_2 * (int64_t) f6;\n  int64_t f3f7_76 = f3_2 * (int64_t) f7_38;\n  int64_t f3f8_38 = f3_2 * (int64_t) f8_19;\n  int64_t f3f9_76 = f3_2 * (int64_t) f9_38;\n  int64_t f4f4    = f4   * (int64_t) f4;\n  int64_t f4f5_2  = f4_2 * (int64_t) f5;\n  int64_t f4f6_38 = f4_2 * (int64_t) f6_19;\n  int64_t f4f7_38 = f4   * (int64_t) f7_38;\n  int64_t f4f8_38 = f4_2 * (int64_t) f8_19;\n  int64_t f4f9_38 = f4   * (int64_t) f9_38;\n  int64_t f5f5_38 = f5   * (int64_t) f5_38;\n  int64_t f5f6_38 = f5_2 * (int64_t) f6_19;\n  int64_t f5f7_76 = f5_2 * (int64_t) f7_38;\n  int64_t f5f8_38 = f5_2 * (int64_t) f8_19;\n  int64_t f5f9_76 = f5_2 * (int64_t) f9_38;\n  int64_t f6f6_19 = f6   * (int64_t) f6_19;\n  int64_t f6f7_38 = f6   * (int64_t) f7_38;\n  int64_t f6f8_38 = f6_2 * (int64_t) f8_19;\n  int64_t f6f9_38 = f6   * (int64_t) f9_38;\n  int64_t f7f7_38 = f7   * (int64_t) f7_38;\n  int64_t f7f8_38 = f7_2 * (int64_t) f8_19;\n  int64_t f7f9_76 = f7_2 * (int64_t) f9_38;\n  int64_t f8f8_19 = f8   * (int64_t) f8_19;\n  int64_t f8f9_38 = f8   * (int64_t) f9_38;\n  int64_t f9f9_38 = f9   * (int64_t) f9_38;\n  int64_t h0 = f0f0  +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;\n  int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;\n  int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;\n  int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;\n  int64_t h4 = f0f4_2+f1f3_4 +f2f2   +f5f9_76+f6f8_38+f7f7_38;\n  int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;\n  int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;\n  int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;\n  int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4   +f9f9_38;\n  int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;\n  int64_t carry0;\n  int64_t carry1;\n  int64_t carry2;\n  int64_t carry3;\n  int64_t carry4;\n  int64_t carry5;\n  int64_t carry6;\n  int64_t carry7;\n  int64_t carry8;\n  int64_t carry9;\n\n  h0 += h0;\n  h1 += h1;\n  h2 += h2;\n  h3 += h3;\n  h4 += h4;\n  h5 += h5;\n  h6 += h6;\n  h7 += h7;\n  h8 += h8;\n  h9 += h9;\n\n  carry0 = (h0 + (int64_t) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;\n  carry4 = (h4 + (int64_t) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;\n\n  carry1 = (h1 + (int64_t) (1UL<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;\n  carry5 = (h5 + (int64_t) (1UL<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;\n\n  carry2 = (h2 + (int64_t) (1UL<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;\n  carry6 = (h6 + (int64_t) (1UL<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;\n\n  carry3 = (h3 + (int64_t) (1UL<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;\n  carry7 = (h7 + (int64_t) (1UL<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;\n\n  carry4 = (h4 + (int64_t) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;\n  carry8 = (h8 + (int64_t) (1UL<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;\n\n  carry9 = (h9 + (int64_t) (1UL<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;\n\n  carry0 = (h0 + (int64_t) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;\n\n  h[0] = (int32_t)h0;\n  h[1] = (int32_t)h1;\n  h[2] = (int32_t)h2;\n  h[3] = (int32_t)h3;\n  h[4] = (int32_t)h4;\n  h[5] = (int32_t)h5;\n  h[6] = (int32_t)h6;\n  h[7] = (int32_t)h7;\n  h[8] = (int32_t)h8;\n  h[9] = (int32_t)h9;\n}\n\n\nvoid fe_pow22523(fe out,const fe z)\n{\n  fe t0;\n  fe t1;\n  fe t2;\n  int i;\n\n  fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0);\n  fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1);\n  fe_mul(t1,z,t1);\n  fe_mul(t0,t0,t1);\n  fe_sq(t0,t0); for (i = 1;i < 1;++i) fe_sq(t0,t0);\n  fe_mul(t0,t1,t0);\n  fe_sq(t1,t0); for (i = 1;i < 5;++i) fe_sq(t1,t1);\n  fe_mul(t0,t1,t0);\n  fe_sq(t1,t0); for (i = 1;i < 10;++i) fe_sq(t1,t1);\n  fe_mul(t1,t1,t0);\n  fe_sq(t2,t1); for (i = 1;i < 20;++i) fe_sq(t2,t2);\n  fe_mul(t1,t2,t1);\n  fe_sq(t1,t1); for (i = 1;i < 10;++i) fe_sq(t1,t1);\n  fe_mul(t0,t1,t0);\n  fe_sq(t1,t0); for (i = 1;i < 50;++i) fe_sq(t1,t1);\n  fe_mul(t1,t1,t0);\n  fe_sq(t2,t1); for (i = 1;i < 100;++i) fe_sq(t2,t2);\n  fe_mul(t1,t2,t1);\n  fe_sq(t1,t1); for (i = 1;i < 50;++i) fe_sq(t1,t1);\n  fe_mul(t0,t1,t0);\n  fe_sq(t0,t0); for (i = 1;i < 2;++i) fe_sq(t0,t0);\n  fe_mul(out,t0,z);\n\n  return;\n}\n\n\n/*\nh = -f\n\nPreconditions:\n   |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.\n\nPostconditions:\n   |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.\n*/\n\nvoid fe_neg(fe h,const fe f)\n{\n  int32_t f0 = f[0];\n  int32_t f1 = f[1];\n  int32_t f2 = f[2];\n  int32_t f3 = f[3];\n  int32_t f4 = f[4];\n  int32_t f5 = f[5];\n  int32_t f6 = f[6];\n  int32_t f7 = f[7];\n  int32_t f8 = f[8];\n  int32_t f9 = f[9];\n  int32_t h0 = -f0;\n  int32_t h1 = -f1;\n  int32_t h2 = -f2;\n  int32_t h3 = -f3;\n  int32_t h4 = -f4;\n  int32_t h5 = -f5;\n  int32_t h6 = -f6;\n  int32_t h7 = -f7;\n  int32_t h8 = -f8;\n  int32_t h9 = -f9;\n  h[0] = h0;\n  h[1] = h1;\n  h[2] = h2;\n  h[3] = h3;\n  h[4] = h4;\n  h[5] = h5;\n  h[6] = h6;\n  h[7] = h7;\n  h[8] = h8;\n  h[9] = h9;\n}\n\n\n/*\nPreconditions:\n   |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.\n*/\n\nstatic const unsigned char zero[32] = {0};\n\nint fe_isnonzero(const fe f)\n{\n  unsigned char s[32];\n  fe_tobytes(s,f);\n  return ConstantCompare(s,zero,32);\n}\n\n\n/*\nreturn 1 if f is in {1,3,5,...,q-2}\nreturn 0 if f is in {0,2,4,...,q-1}\n\nPreconditions:\n   |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.\n*/\n\nint fe_isnegative(const fe f)\n{\n  unsigned char s[32];\n  fe_tobytes(s,f);\n  return s[0] & 1;\n}\n\n\n/*\nReplace (f,g) with (g,g) if b == 1;\nreplace (f,g) with (f,g) if b == 0.\n\nPreconditions: b in {0,1}.\n*/\n\nvoid fe_cmov(fe f, const fe g, int b)\n{\n  int32_t f0 = f[0];\n  int32_t f1 = f[1];\n  int32_t f2 = f[2];\n  int32_t f3 = f[3];\n  int32_t f4 = f[4];\n  int32_t f5 = f[5];\n  int32_t f6 = f[6];\n  int32_t f7 = f[7];\n  int32_t f8 = f[8];\n  int32_t f9 = f[9];\n  int32_t g0 = g[0];\n  int32_t g1 = g[1];\n  int32_t g2 = g[2];\n  int32_t g3 = g[3];\n  int32_t g4 = g[4];\n  int32_t g5 = g[5];\n  int32_t g6 = g[6];\n  int32_t g7 = g[7];\n  int32_t g8 = g[8];\n  int32_t g9 = g[9];\n  int32_t x0 = f0 ^ g0;\n  int32_t x1 = f1 ^ g1;\n  int32_t x2 = f2 ^ g2;\n  int32_t x3 = f3 ^ g3;\n  int32_t x4 = f4 ^ g4;\n  int32_t x5 = f5 ^ g5;\n  int32_t x6 = f6 ^ g6;\n  int32_t x7 = f7 ^ g7;\n  int32_t x8 = f8 ^ g8;\n  int32_t x9 = f9 ^ g9;\n  b = -b;\n  x0 &= b;\n  x1 &= b;\n  x2 &= b;\n  x3 &= b;\n  x4 &= b;\n  x5 &= b;\n  x6 &= b;\n  x7 &= b;\n  x8 &= b;\n  x9 &= b;\n  f[0] = f0 ^ x0;\n  f[1] = f1 ^ x1;\n  f[2] = f2 ^ x2;\n  f[3] = f3 ^ x3;\n  f[4] = f4 ^ x4;\n  f[5] = f5 ^ x5;\n  f[6] = f6 ^ x6;\n  f[7] = f7 ^ x7;\n  f[8] = f8 ^ x8;\n  f[9] = f9 ^ x9;\n}\n#endif\n\n#endif /* !CURVE25519_SMALL || !ED25519_SMALL */\n#endif /* HAVE_CURVE25519 || HAVE_ED25519 */\n"
  },
  {
    "path": "src/wolfcrypt/src/ge_low_mem.c",
    "content": "/* ge_low_mem.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n /* Based from Daniel Beer's public domain work. */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_ED25519\n#ifdef ED25519_SMALL /* use slower code that takes less memory */\n\n#include <wolfssl/wolfcrypt/ge_operations.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\nvoid ed25519_smult(ge_p3 *r, const ge_p3 *a, const byte *e);\nvoid ed25519_add(ge_p3 *r, const ge_p3 *a, const ge_p3 *b);\nvoid ed25519_double(ge_p3 *r, const ge_p3 *a);\n\n\nstatic const byte ed25519_order[F25519_SIZE] = {\n    0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,\n    0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10\n};\n\n/*Arithmetic modulo the group order m = 2^252 +\n 27742317777372353535851937790883648493 =\n 7237005577332262213973186563042994240857116359379907606001950938285454250989 */\n\nstatic const word32 m[32] = {\n    0xED,0xD3,0xF5,0x5C,0x1A,0x63,0x12,0x58,0xD6,0x9C,0xF7,0xA2,0xDE,0xF9,\n    0xDE,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x10\n};\n\nstatic const word32 mu[33] = {\n    0x1B,0x13,0x2C,0x0A,0xA3,0xE5,0x9C,0xED,0xA7,0x29,0x63,0x08,0x5D,0x21,\n    0x06,0x21,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,\n    0xFF,0xFF,0xFF,0xFF,0x0F\n};\n\n\nint ge_compress_key(byte* out, const byte* xIn, const byte* yIn,\n                        word32 keySz)\n{\n    byte tmp[F25519_SIZE];\n    byte parity;\n    byte pt[32];\n    int     i;\n\n    lm_copy(tmp, xIn);\n    parity = (tmp[0] & 1) << 7;\n\n    lm_copy(pt, yIn);\n    pt[31] |= parity;\n\n    for(i = 0; i < 32; i++) {\n        out[32-i-1] = pt[i];\n    }\n    (void)keySz;\n    return 0;\n}\n\n\nstatic word32 lt(word32 a,word32 b) /* 16-bit inputs */\n{\n  word32 x = a;\n  x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */\n  x >>= 31; /* 0: no; 1: yes */\n  return x;\n}\n\n\n/* Reduce coefficients of r before calling reduce_add_sub */\nstatic void reduce_add_sub(word32 *r)\n{\n  word32 pb = 0;\n  word32 b;\n  word32 mask;\n  int i;\n  unsigned char t[32];\n\n  for(i=0;i<32;i++)\n  {\n    pb += m[i];\n    b = lt(r[i],pb);\n    t[i] = r[i]-pb+(b<<8);\n    pb = b;\n  }\n  mask = b - 1;\n  for(i=0;i<32;i++)\n    r[i] ^= mask & (r[i] ^ t[i]);\n}\n\n\n/* Reduce coefficients of x before calling barrett_reduce */\nstatic void barrett_reduce(word32* r, word32 x[64])\n{\n  /* See HAC, Alg. 14.42 */\n  int i,j;\n  word32 q2[66];\n  word32 *q3 = q2 + 33;\n  word32 r1[33];\n  word32 r2[33];\n  word32 carry;\n  word32 pb = 0;\n  word32 b;\n\n  for (i = 0;i < 66;++i) q2[i] = 0;\n  for (i = 0;i < 33;++i) r2[i] = 0;\n\n  for(i=0;i<33;i++)\n    for(j=0;j<33;j++)\n      if(i+j >= 31) q2[i+j] += mu[i]*x[j+31];\n  carry = q2[31] >> 8;\n  q2[32] += carry;\n  carry = q2[32] >> 8;\n  q2[33] += carry;\n\n  for(i=0;i<33;i++)r1[i] = x[i];\n  for(i=0;i<32;i++)\n    for(j=0;j<33;j++)\n      if(i+j < 33) r2[i+j] += m[i]*q3[j];\n\n  for(i=0;i<32;i++)\n  {\n    carry = r2[i] >> 8;\n    r2[i+1] += carry;\n    r2[i] &= 0xff;\n  }\n\n  for(i=0;i<32;i++)\n  {\n    pb += r2[i];\n    b = lt(r1[i],pb);\n    r[i] = r1[i]-pb+(b<<8);\n    pb = b;\n  }\n\n  /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3\n   * r is an unsigned type.\n   * If so: Handle  it here!\n   */\n\n  reduce_add_sub(r);\n  reduce_add_sub(r);\n}\n\n\nvoid sc_reduce(unsigned char x[64])\n{\n  int i;\n  word32 t[64];\n  word32 r[32];\n  for(i=0;i<64;i++) t[i] = x[i];\n  barrett_reduce(r, t);\n  for(i=0;i<32;i++) x[i] = (r[i] & 0xFF);\n}\n\n\nvoid sc_muladd(byte* out, const byte* a, const byte* b, const byte* c)\n{\n\n    byte s[32];\n    byte e[64];\n\n    XMEMSET(e, 0, sizeof(e));\n    XMEMCPY(e, b, 32);\n\n    /* Obtain e */\n    sc_reduce(e);\n\n    /* Compute s = ze + k */\n    fprime_mul(s, a, e, ed25519_order);\n    fprime_add(s, c, ed25519_order);\n\n    XMEMCPY(out, s, 32);\n}\n\n\n/* Base point is (numbers wrapped):\n *\n *     x = 151122213495354007725011514095885315114\n *         54012693041857206046113283949847762202\n *     y = 463168356949264781694283940034751631413\n *         07993866256225615783033603165251855960\n *\n * y is derived by transforming the original Montgomery base (u=9). x\n * is the corresponding positive coordinate for the new curve equation.\n * t is x*y.\n */\nconst ge_p3 ed25519_base = {\n    {\n        0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9,\n        0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69,\n        0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,\n        0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21\n    },\n    {\n        0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,\n        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,\n        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,\n        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66\n    },\n    {1, 0},\n    {\n        0xa3, 0xdd, 0xb7, 0xa5, 0xb3, 0x8a, 0xde, 0x6d,\n        0xf5, 0x52, 0x51, 0x77, 0x80, 0x9f, 0xf0, 0x20,\n        0x7d, 0xe3, 0xab, 0x64, 0x8e, 0x4e, 0xea, 0x66,\n        0x65, 0x76, 0x8b, 0xd7, 0x0f, 0x5f, 0x87, 0x67\n    },\n\n};\n\n\nconst ge_p3 ed25519_neutral = {\n    {0},\n    {1, 0},\n    {1, 0},\n    {0},\n\n};\n\n\nstatic const byte ed25519_d[F25519_SIZE] = {\n    0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,\n    0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,\n    0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,\n    0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52\n};\n\n\n/* k = 2d */\nstatic const byte ed25519_k[F25519_SIZE] = {\n    0x59, 0xf1, 0xb2, 0x26, 0x94, 0x9b, 0xd6, 0xeb,\n    0x56, 0xb1, 0x83, 0x82, 0x9a, 0x14, 0xe0, 0x00,\n    0x30, 0xd1, 0xf3, 0xee, 0xf2, 0x80, 0x8e, 0x19,\n    0xe7, 0xfc, 0xdf, 0x56, 0xdc, 0xd9, 0x06, 0x24\n};\n\n\nvoid ed25519_add(ge_p3 *r,\n         const ge_p3 *p1, const ge_p3 *p2)\n{\n    /* Explicit formulas database: add-2008-hwcd-3\n     *\n     * source 2008 Hisil--Wong--Carter--Dawson,\n     *     http://eprint.iacr.org/2008/522, Section 3.1\n     * appliesto extended-1\n     * parameter k\n     * assume k = 2 d\n     * compute A = (Y1-X1)(Y2-X2)\n     * compute B = (Y1+X1)(Y2+X2)\n     * compute C = T1 k T2\n     * compute D = Z1 2 Z2\n     * compute E = B - A\n     * compute F = D - C\n     * compute G = D + C\n     * compute H = B + A\n     * compute X3 = E F\n     * compute Y3 = G H\n     * compute T3 = E H\n     * compute Z3 = F G\n     */\n    byte a[F25519_SIZE];\n    byte b[F25519_SIZE];\n    byte c[F25519_SIZE];\n    byte d[F25519_SIZE];\n    byte e[F25519_SIZE];\n    byte f[F25519_SIZE];\n    byte g[F25519_SIZE];\n    byte h[F25519_SIZE];\n\n    /* A = (Y1-X1)(Y2-X2) */\n    lm_sub(c, p1->Y, p1->X);\n    lm_sub(d, p2->Y, p2->X);\n    fe_mul__distinct(a, c, d);\n\n    /* B = (Y1+X1)(Y2+X2) */\n    lm_add(c, p1->Y, p1->X);\n    lm_add(d, p2->Y, p2->X);\n    fe_mul__distinct(b, c, d);\n\n    /* C = T1 k T2 */\n    fe_mul__distinct(d, p1->T, p2->T);\n    fe_mul__distinct(c, d, ed25519_k);\n\n    /* D = Z1 2 Z2 */\n    fe_mul__distinct(d, p1->Z, p2->Z);\n    lm_add(d, d, d);\n\n    /* E = B - A */\n    lm_sub(e, b, a);\n\n    /* F = D - C */\n    lm_sub(f, d, c);\n\n    /* G = D + C */\n    lm_add(g, d, c);\n\n    /* H = B + A */\n    lm_add(h, b, a);\n\n    /* X3 = E F */\n    fe_mul__distinct(r->X, e, f);\n\n    /* Y3 = G H */\n    fe_mul__distinct(r->Y, g, h);\n\n    /* T3 = E H */\n    fe_mul__distinct(r->T, e, h);\n\n    /* Z3 = F G */\n    fe_mul__distinct(r->Z, f, g);\n}\n\n\nvoid ed25519_double(ge_p3 *r, const ge_p3 *p)\n{\n    /* Explicit formulas database: dbl-2008-hwcd\n     *\n     * source 2008 Hisil--Wong--Carter--Dawson,\n     *     http://eprint.iacr.org/2008/522, Section 3.3\n     * compute A = X1^2\n     * compute B = Y1^2\n     * compute C = 2 Z1^2\n     * compute D = a A\n     * compute E = (X1+Y1)^2-A-B\n     * compute G = D + B\n     * compute F = G - C\n     * compute H = D - B\n     * compute X3 = E F\n     * compute Y3 = G H\n     * compute T3 = E H\n     * compute Z3 = F G\n     */\n    byte a[F25519_SIZE];\n    byte b[F25519_SIZE];\n    byte c[F25519_SIZE];\n    byte e[F25519_SIZE];\n    byte f[F25519_SIZE];\n    byte g[F25519_SIZE];\n    byte h[F25519_SIZE];\n\n    /* A = X1^2 */\n    fe_mul__distinct(a, p->X, p->X);\n\n    /* B = Y1^2 */\n    fe_mul__distinct(b, p->Y, p->Y);\n\n    /* C = 2 Z1^2 */\n    fe_mul__distinct(c, p->Z, p->Z);\n    lm_add(c, c, c);\n\n    /* D = a A (alter sign) */\n    /* E = (X1+Y1)^2-A-B */\n    lm_add(f, p->X, p->Y);\n    fe_mul__distinct(e, f, f);\n    lm_sub(e, e, a);\n    lm_sub(e, e, b);\n\n    /* G = D + B */\n    lm_sub(g, b, a);\n\n    /* F = G - C */\n    lm_sub(f, g, c);\n\n    /* H = D - B */\n    lm_neg(h, b);\n    lm_sub(h, h, a);\n\n    /* X3 = E F */\n    fe_mul__distinct(r->X, e, f);\n\n    /* Y3 = G H */\n    fe_mul__distinct(r->Y, g, h);\n\n    /* T3 = E H */\n    fe_mul__distinct(r->T, e, h);\n\n    /* Z3 = F G */\n    fe_mul__distinct(r->Z, f, g);\n}\n\n\nvoid ed25519_smult(ge_p3 *r_out, const ge_p3 *p, const byte *e)\n{\n    ge_p3 r;\n    int   i;\n\n    XMEMCPY(&r, &ed25519_neutral, sizeof(r));\n\n    for (i = 255; i >= 0; i--) {\n        const byte bit = (e[i >> 3] >> (i & 7)) & 1;\n        ge_p3 s;\n\n        ed25519_double(&r, &r);\n        ed25519_add(&s, &r, p);\n\n        fe_select(r.X, r.X, s.X, bit);\n        fe_select(r.Y, r.Y, s.Y, bit);\n        fe_select(r.Z, r.Z, s.Z, bit);\n        fe_select(r.T, r.T, s.T, bit);\n    }\n    XMEMCPY(r_out, &r, sizeof(r));\n}\n\n\nvoid ge_scalarmult_base(ge_p3 *R,const unsigned char *nonce)\n{\n    ed25519_smult(R, &ed25519_base, nonce);\n}\n\n\n/* pack the point h into array s */\nvoid ge_p3_tobytes(unsigned char *s,const ge_p3 *h)\n{\n    byte x[F25519_SIZE];\n    byte y[F25519_SIZE];\n    byte z1[F25519_SIZE];\n    byte parity;\n\n    fe_inv__distinct(z1, h->Z);\n    fe_mul__distinct(x, h->X, z1);\n    fe_mul__distinct(y, h->Y, z1);\n\n    fe_normalize(x);\n    fe_normalize(y);\n\n    parity = (x[0] & 1) << 7;\n    lm_copy(s, y);\n    fe_normalize(s);\n    s[31] |= parity;\n}\n\n\n/* pack the point h into array s */\nvoid ge_tobytes(unsigned char *s,const ge_p2 *h)\n{\n    byte x[F25519_SIZE];\n    byte y[F25519_SIZE];\n    byte z1[F25519_SIZE];\n    byte parity;\n\n    fe_inv__distinct(z1, h->Z);\n    fe_mul__distinct(x, h->X, z1);\n    fe_mul__distinct(y, h->Y, z1);\n\n    fe_normalize(x);\n    fe_normalize(y);\n\n    parity = (x[0] & 1) << 7;\n    lm_copy(s, y);\n    fe_normalize(s);\n    s[31] |= parity;\n}\n\n\n/*\n   Test if the public key can be uncompressed and negate it (-X,Y,Z,-T)\n   return 0 on success\n */\nint ge_frombytes_negate_vartime(ge_p3 *p,const unsigned char *s)\n{\n\n    byte parity;\n    byte x[F25519_SIZE];\n    byte y[F25519_SIZE];\n    byte a[F25519_SIZE];\n    byte b[F25519_SIZE];\n    byte c[F25519_SIZE];\n    int ret = 0;\n\n    /* unpack the key s */\n    parity = s[31] >> 7;\n    lm_copy(y, s);\n    y[31] &= 127;\n\n    fe_mul__distinct(c, y, y);\n    fe_mul__distinct(b, c, ed25519_d);\n    lm_add(a, b, f25519_one);\n    fe_inv__distinct(b, a);\n    lm_sub(a, c, f25519_one);\n    fe_mul__distinct(c, a, b);\n    fe_sqrt(a, c);\n    lm_neg(b, a);\n    fe_select(x, a, b, (a[0] ^ parity) & 1);\n\n    /* test that x^2 is equal to c */\n    fe_mul__distinct(a, x, x);\n    fe_normalize(a);\n    fe_normalize(c);\n    ret |= ConstantCompare(a, c, F25519_SIZE);\n\n    /* project the key s onto p */\n    lm_copy(p->X, x);\n    lm_copy(p->Y, y);\n    fe_load(p->Z, 1);\n    fe_mul__distinct(p->T, x, y);\n\n    /* negate, the point becomes (-X,Y,Z,-T) */\n    lm_neg(p->X,p->X);\n    lm_neg(p->T,p->T);\n\n    return ret;\n}\n\n\nint ge_double_scalarmult_vartime(ge_p2* R, const unsigned char *h,\n                                 const ge_p3 *inA,const unsigned char *sig)\n{\n    ge_p3 p, A;\n    int ret = 0;\n\n    XMEMCPY(&A, inA, sizeof(ge_p3));\n\n    /* find SB */\n    ed25519_smult(&p, &ed25519_base, sig);\n\n    /* find H(R,A,M) * -A */\n    ed25519_smult(&A, &A, h);\n\n    /* SB + -H(R,A,M)A */\n    ed25519_add(&A, &p, &A);\n\n    lm_copy(R->X, A.X);\n    lm_copy(R->Y, A.Y);\n    lm_copy(R->Z, A.Z);\n\n    return ret;\n}\n\n#endif /* ED25519_SMALL */\n#endif /* HAVE_ED25519 */\n"
  },
  {
    "path": "src/wolfcrypt/src/ge_operations.c",
    "content": "/* ge_operations.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n /* Based On Daniel J Bernstein's ed25519 Public Domain ref10 work. */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_ED25519\n#ifndef ED25519_SMALL /* run when not defined to use small memory math */\n\n#include <wolfssl/wolfcrypt/ge_operations.h>\n#include <wolfssl/wolfcrypt/ed25519.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#if defined(CURVED25519_X64)\n    #define CURVED25519_ASM_64BIT\n    #define CURVED25519_ASM\n#endif\n#if defined(WOLFSSL_ARMASM)\n    #if defined(__aarch64__)\n        #define CURVED25519_ASM_64BIT\n    #else\n        #define CURVED25519_ASM_32BIT\n    #endif\n    #define CURVED25519_ASM\n#endif\n\n\nstatic void ge_p2_0(ge_p2 *);\n#ifndef CURVED25519_ASM\nstatic void ge_precomp_0(ge_precomp *);\n#endif\nstatic void ge_p3_to_p2(ge_p2 *,const ge_p3 *);\nstatic void ge_p3_to_cached(ge_cached *,const ge_p3 *);\nstatic void ge_p1p1_to_p2(ge_p2 *,const ge_p1p1 *);\nstatic void ge_p1p1_to_p3(ge_p3 *,const ge_p1p1 *);\nstatic void ge_p2_dbl(ge_p1p1 *,const ge_p2 *);\nstatic void ge_p3_dbl(ge_p1p1 *,const ge_p3 *);\n\nstatic void ge_madd(ge_p1p1 *,const ge_p3 *,const ge_precomp *);\nstatic void ge_msub(ge_p1p1 *,const ge_p3 *,const ge_precomp *);\nstatic void ge_add(ge_p1p1 *,const ge_p3 *,const ge_cached *);\nstatic void ge_sub(ge_p1p1 *,const ge_p3 *,const ge_cached *);\n\n/*\nge means group element.\n\nHere the group is the set of pairs (x,y) of field elements (see ge_operations.h)\nsatisfying -x^2 + y^2 = 1 + d x^2y^2\nwhere d = -121665/121666.\n\nRepresentations:\n  ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z\n  ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT\n  ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T\n  ge_precomp (Duif): (y+x,y-x,2dxy)\n*/\n\n#if !defined(HAVE___UINT128_T) || defined(NO_CURVED25519_128BIT)\n#define MASK_21     0x1fffff\n#define ORDER_0     0x15d3ed\n#define ORDER_1     0x18d2e7\n#define ORDER_2     0x160498\n#define ORDER_3     0xf39ac\n#define ORDER_4     0x1dea2f\n#define ORDER_5     0xa6f7c\n\n#ifdef CURVED25519_ASM_32BIT\nuint64_t load_3(const unsigned char *in)\n{\n  uint64_t result;\n  result = (uint64_t) in[0];\n  result |= ((uint64_t) in[1]) << 8;\n  result |= ((uint64_t) in[2]) << 16;\n  return result;\n}\n\n\nuint64_t load_4(const unsigned char *in)\n{\n  uint64_t result;\n  result = (uint64_t) in[0];\n  result |= ((uint64_t) in[1]) << 8;\n  result |= ((uint64_t) in[2]) << 16;\n  result |= ((uint64_t) in[3]) << 24;\n  return result;\n}\n#endif\n\n/*\nInput:\n  s[0]+256*s[1]+...+256^63*s[63] = s\n\nOutput:\n  s[0]+256*s[1]+...+256^31*s[31] = s mod l\n  where l = 2^252 + 27742317777372353535851937790883648493.\n  Overwrites s in place.\n*/\nvoid sc_reduce(byte* s)\n{\n    int64_t t[24];\n    int64_t carry;\n\n    t[ 0] = MASK_21 & (load_3(s +  0) >> 0);\n    t[ 1] = MASK_21 & (load_4(s +  2) >> 5);\n    t[ 2] = MASK_21 & (load_3(s +  5) >> 2);\n    t[ 3] = MASK_21 & (load_4(s +  7) >> 7);\n    t[ 4] = MASK_21 & (load_4(s + 10) >> 4);\n    t[ 5] = MASK_21 & (load_3(s + 13) >> 1);\n    t[ 6] = MASK_21 & (load_4(s + 15) >> 6);\n    t[ 7] = MASK_21 & (load_3(s + 18) >> 3);\n    t[ 8] = MASK_21 & (load_3(s + 21) >> 0);\n    t[ 9] = MASK_21 & (load_4(s + 23) >> 5);\n    t[10] = MASK_21 & (load_3(s + 26) >> 2);\n    t[11] = MASK_21 & (load_4(s + 28) >> 7);\n    t[12] = MASK_21 & (load_4(s + 31) >> 4);\n    t[13] = MASK_21 & (load_3(s + 34) >> 1);\n    t[14] = MASK_21 & (load_4(s + 36) >> 6);\n    t[15] = MASK_21 & (load_3(s + 39) >> 3);\n    t[16] = MASK_21 & (load_3(s + 42) >> 0);\n    t[17] = MASK_21 & (load_4(s + 44) >> 5);\n    t[18] = MASK_21 & (load_3(s + 47) >> 2);\n    t[19] = MASK_21 & (load_4(s + 49) >> 7);\n    t[20] = MASK_21 & (load_4(s + 52) >> 4);\n    t[21] = MASK_21 & (load_3(s + 55) >> 1);\n    t[22] = MASK_21 & (load_4(s + 57) >> 6);\n    t[23] =           (load_4(s + 60) >> 3);\n\n    t[11] -= t[23] * ORDER_0;\n    t[12] -= t[23] * ORDER_1;\n    t[13] -= t[23] * ORDER_2;\n    t[14] -= t[23] * ORDER_3;\n    t[15] -= t[23] * ORDER_4;\n    t[16] -= t[23] * ORDER_5;\n\n    t[10] -= t[22] * ORDER_0;\n    t[11] -= t[22] * ORDER_1;\n    t[12] -= t[22] * ORDER_2;\n    t[13] -= t[22] * ORDER_3;\n    t[14] -= t[22] * ORDER_4;\n    t[15] -= t[22] * ORDER_5;\n\n    t[ 9] -= t[21] * ORDER_0;\n    t[10] -= t[21] * ORDER_1;\n    t[11] -= t[21] * ORDER_2;\n    t[12] -= t[21] * ORDER_3;\n    t[13] -= t[21] * ORDER_4;\n    t[14] -= t[21] * ORDER_5;\n\n    t[ 8] -= t[20] * ORDER_0;\n    t[ 9] -= t[20] * ORDER_1;\n    t[10] -= t[20] * ORDER_2;\n    t[11] -= t[20] * ORDER_3;\n    t[12] -= t[20] * ORDER_4;\n    t[13] -= t[20] * ORDER_5;\n\n    t[ 7] -= t[19] * ORDER_0;\n    t[ 8] -= t[19] * ORDER_1;\n    t[ 9] -= t[19] * ORDER_2;\n    t[10] -= t[19] * ORDER_3;\n    t[11] -= t[19] * ORDER_4;\n    t[12] -= t[19] * ORDER_5;\n\n    t[ 6] -= t[18] * ORDER_0;\n    t[ 7] -= t[18] * ORDER_1;\n    t[ 8] -= t[18] * ORDER_2;\n    t[ 9] -= t[18] * ORDER_3;\n    t[10] -= t[18] * ORDER_4;\n    t[11] -= t[18] * ORDER_5;\n\n    carry = t[ 6] >> 21; t[ 7] += carry; t[ 6] &= MASK_21;\n    carry = t[ 8] >> 21; t[ 9] += carry; t[ 8] &= MASK_21;\n    carry = t[10] >> 21; t[11] += carry; t[10] &= MASK_21;\n    carry = t[12] >> 21; t[13] += carry; t[12] &= MASK_21;\n    carry = t[14] >> 21; t[15] += carry; t[14] &= MASK_21;\n    carry = t[16] >> 21; t[17] += carry; t[16] &= MASK_21;\n    carry = t[ 7] >> 21; t[ 8] += carry; t[ 7] &= MASK_21;\n    carry = t[ 9] >> 21; t[10] += carry; t[ 9] &= MASK_21;\n    carry = t[11] >> 21; t[12] += carry; t[11] &= MASK_21;\n    carry = t[13] >> 21; t[14] += carry; t[13] &= MASK_21;\n    carry = t[15] >> 21; t[16] += carry; t[15] &= MASK_21;\n\n    t[ 5] -= t[17] * ORDER_0;\n    t[ 6] -= t[17] * ORDER_1;\n    t[ 7] -= t[17] * ORDER_2;\n    t[ 8] -= t[17] * ORDER_3;\n    t[ 9] -= t[17] * ORDER_4;\n    t[10] -= t[17] * ORDER_5;\n\n    t[ 4] -= t[16] * ORDER_0;\n    t[ 5] -= t[16] * ORDER_1;\n    t[ 6] -= t[16] * ORDER_2;\n    t[ 7] -= t[16] * ORDER_3;\n    t[ 8] -= t[16] * ORDER_4;\n    t[ 9] -= t[16] * ORDER_5;\n\n    t[ 3] -= t[15] * ORDER_0;\n    t[ 4] -= t[15] * ORDER_1;\n    t[ 5] -= t[15] * ORDER_2;\n    t[ 6] -= t[15] * ORDER_3;\n    t[ 7] -= t[15] * ORDER_4;\n    t[ 8] -= t[15] * ORDER_5;\n\n    t[ 2] -= t[14] * ORDER_0;\n    t[ 3] -= t[14] * ORDER_1;\n    t[ 4] -= t[14] * ORDER_2;\n    t[ 5] -= t[14] * ORDER_3;\n    t[ 6] -= t[14] * ORDER_4;\n    t[ 7] -= t[14] * ORDER_5;\n\n    t[ 1] -= t[13] * ORDER_0;\n    t[ 2] -= t[13] * ORDER_1;\n    t[ 3] -= t[13] * ORDER_2;\n    t[ 4] -= t[13] * ORDER_3;\n    t[ 5] -= t[13] * ORDER_4;\n    t[ 6] -= t[13] * ORDER_5;\n\n    t[ 0] -= t[12] * ORDER_0;\n    t[ 1] -= t[12] * ORDER_1;\n    t[ 2] -= t[12] * ORDER_2;\n    t[ 3] -= t[12] * ORDER_3;\n    t[ 4] -= t[12] * ORDER_4;\n    t[ 5] -= t[12] * ORDER_5;\n    t[12]  = 0;\n\n    carry = t[ 0] >> 21; t[ 1] += carry; t[ 0] &= MASK_21;\n    carry = t[ 1] >> 21; t[ 2] += carry; t[ 1] &= MASK_21;\n    carry = t[ 2] >> 21; t[ 3] += carry; t[ 2] &= MASK_21;\n    carry = t[ 3] >> 21; t[ 4] += carry; t[ 3] &= MASK_21;\n    carry = t[ 4] >> 21; t[ 5] += carry; t[ 4] &= MASK_21;\n    carry = t[ 5] >> 21; t[ 6] += carry; t[ 5] &= MASK_21;\n    carry = t[ 6] >> 21; t[ 7] += carry; t[ 6] &= MASK_21;\n    carry = t[ 7] >> 21; t[ 8] += carry; t[ 7] &= MASK_21;\n    carry = t[ 8] >> 21; t[ 9] += carry; t[ 8] &= MASK_21;\n    carry = t[ 9] >> 21; t[10] += carry; t[ 9] &= MASK_21;\n    carry = t[10] >> 21; t[11] += carry; t[10] &= MASK_21;\n    carry = t[11] >> 21; t[12] += carry; t[11] &= MASK_21;\n\n    t[ 0] -= t[12] * ORDER_0;\n    t[ 1] -= t[12] * ORDER_1;\n    t[ 2] -= t[12] * ORDER_2;\n    t[ 3] -= t[12] * ORDER_3;\n    t[ 4] -= t[12] * ORDER_4;\n    t[ 5] -= t[12] * ORDER_5;\n\n    carry = t[ 0] >> 21; t[ 1] += carry; t[ 0] &= MASK_21;\n    carry = t[ 1] >> 21; t[ 2] += carry; t[ 1] &= MASK_21;\n    carry = t[ 2] >> 21; t[ 3] += carry; t[ 2] &= MASK_21;\n    carry = t[ 3] >> 21; t[ 4] += carry; t[ 3] &= MASK_21;\n    carry = t[ 4] >> 21; t[ 5] += carry; t[ 4] &= MASK_21;\n    carry = t[ 5] >> 21; t[ 6] += carry; t[ 5] &= MASK_21;\n    carry = t[ 6] >> 21; t[ 7] += carry; t[ 6] &= MASK_21;\n    carry = t[ 7] >> 21; t[ 8] += carry; t[ 7] &= MASK_21;\n    carry = t[ 8] >> 21; t[ 9] += carry; t[ 8] &= MASK_21;\n    carry = t[ 9] >> 21; t[10] += carry; t[ 9] &= MASK_21;\n    carry = t[10] >> 21; t[11] += carry; t[10] &= MASK_21;\n\n    s[ 0] = (byte)(t[ 0] >>  0);\n    s[ 1] = (byte)(t[ 0] >>  8);\n    s[ 2] = (byte)((t[ 0] >> 16) | (t[ 1] <<  5));\n    s[ 3] = (byte)(t[ 1] >>  3);\n    s[ 4] = (byte)(t[ 1] >> 11);\n    s[ 5] = (byte)((t[ 1] >> 19) | (t[ 2] <<  2));\n    s[ 6] = (byte)(t[ 2] >>  6);\n    s[ 7] = (byte)((t[ 2] >> 14) | (t[ 3] <<  7));\n    s[ 8] = (byte)(t[ 3] >>  1);\n    s[ 9] = (byte)(t[ 3] >>  9);\n    s[10] = (byte)((t[ 3] >> 17) | (t[ 4] <<  4));\n    s[11] = (byte)(t[ 4] >>  4);\n    s[12] = (byte)(t[ 4] >> 12);\n    s[13] = (byte)((t[ 4] >> 20) | (t[ 5] <<  1));\n    s[14] = (byte)(t[ 5] >>  7);\n    s[15] = (byte)((t[ 5] >> 15) | (t[ 6] <<  6));\n    s[16] = (byte)(t[ 6] >>  2);\n    s[17] = (byte)(t[ 6] >> 10);\n    s[18] = (byte)((t[ 6] >> 18) | (t[ 7] <<  3));\n    s[19] = (byte)(t[ 7] >>  5);\n    s[20] = (byte)(t[ 7] >> 13);\n    s[21] = (byte)(t[ 8] >>  0);\n    s[22] = (byte)(t[ 8] >>  8);\n    s[23] = (byte)((t[ 8] >> 16) | (t[ 9] <<  5));\n    s[24] = (byte)(t[ 9] >>  3);\n    s[25] = (byte)(t[ 9] >> 11);\n    s[26] = (byte)((t[ 9] >> 19) | (t[10] <<  2));\n    s[27] = (byte)(t[10] >>  6);\n    s[28] = (byte)((t[10] >> 14) | (t[11] <<  7));\n    s[29] = (byte)(t[11] >>  1);\n    s[30] = (byte)(t[11] >>  9);\n    s[31] = (byte)(t[11] >> 17);\n}\n\n/*\nInput:\n  a[0]+256*a[1]+...+256^31*a[31] = a\n  b[0]+256*b[1]+...+256^31*b[31] = b\n  c[0]+256*c[1]+...+256^31*c[31] = c\n\nOutput:\n  s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l\n  where l = 2^252 + 27742317777372353535851937790883648493.\n*/\nvoid sc_muladd(byte* s, const byte* a, const byte* b, const byte* c)\n{\n    uint32_t ad[12], bd[12], cd[12];\n    int64_t t[24];\n    int64_t carry;\n\n    ad[ 0] = MASK_21 & (load_3(a +  0) >> 0);\n    ad[ 1] = MASK_21 & (load_4(a +  2) >> 5);\n    ad[ 2] = MASK_21 & (load_3(a +  5) >> 2);\n    ad[ 3] = MASK_21 & (load_4(a +  7) >> 7);\n    ad[ 4] = MASK_21 & (load_4(a + 10) >> 4);\n    ad[ 5] = MASK_21 & (load_3(a + 13) >> 1);\n    ad[ 6] = MASK_21 & (load_4(a + 15) >> 6);\n    ad[ 7] = MASK_21 & (load_3(a + 18) >> 3);\n    ad[ 8] = MASK_21 & (load_3(a + 21) >> 0);\n    ad[ 9] = MASK_21 & (load_4(a + 23) >> 5);\n    ad[10] = MASK_21 & (load_3(a + 26) >> 2);\n    ad[11] = (uint32_t)(load_4(a + 28) >> 7);\n    bd[ 0] = MASK_21 & (load_3(b +  0) >> 0);\n    bd[ 1] = MASK_21 & (load_4(b +  2) >> 5);\n    bd[ 2] = MASK_21 & (load_3(b +  5) >> 2);\n    bd[ 3] = MASK_21 & (load_4(b +  7) >> 7);\n    bd[ 4] = MASK_21 & (load_4(b + 10) >> 4);\n    bd[ 5] = MASK_21 & (load_3(b + 13) >> 1);\n    bd[ 6] = MASK_21 & (load_4(b + 15) >> 6);\n    bd[ 7] = MASK_21 & (load_3(b + 18) >> 3);\n    bd[ 8] = MASK_21 & (load_3(b + 21) >> 0);\n    bd[ 9] = MASK_21 & (load_4(b + 23) >> 5);\n    bd[10] = MASK_21 & (load_3(b + 26) >> 2);\n    bd[11] = (uint32_t)(load_4(b + 28) >> 7);\n    cd[ 0] = MASK_21 & (load_3(c +  0) >> 0);\n    cd[ 1] = MASK_21 & (load_4(c +  2) >> 5);\n    cd[ 2] = MASK_21 & (load_3(c +  5) >> 2);\n    cd[ 3] = MASK_21 & (load_4(c +  7) >> 7);\n    cd[ 4] = MASK_21 & (load_4(c + 10) >> 4);\n    cd[ 5] = MASK_21 & (load_3(c + 13) >> 1);\n    cd[ 6] = MASK_21 & (load_4(c + 15) >> 6);\n    cd[ 7] = MASK_21 & (load_3(c + 18) >> 3);\n    cd[ 8] = MASK_21 & (load_3(c + 21) >> 0);\n    cd[ 9] = MASK_21 & (load_4(c + 23) >> 5);\n    cd[10] = MASK_21 & (load_3(c + 26) >> 2);\n    cd[11] = (uint32_t)(load_4(c + 28) >> 7);\n\n    t[ 0] = cd[ 0] + (int64_t)ad[ 0] * bd[ 0];\n    t[ 1] = cd[ 1] + (int64_t)ad[ 0] * bd[ 1] + (int64_t)ad[ 1] * bd[ 0];\n    t[ 2] = cd[ 2] + (int64_t)ad[ 0] * bd[ 2] + (int64_t)ad[ 1] * bd[ 1] +\n                     (int64_t)ad[ 2] * bd[ 0];\n    t[ 3] = cd[ 3] + (int64_t)ad[ 0] * bd[ 3] + (int64_t)ad[ 1] * bd[ 2] +\n                     (int64_t)ad[ 2] * bd[ 1] + (int64_t)ad[ 3] * bd[ 0];\n    t[ 4] = cd[ 4] + (int64_t)ad[ 0] * bd[ 4] + (int64_t)ad[ 1] * bd[ 3] +\n                     (int64_t)ad[ 2] * bd[ 2] + (int64_t)ad[ 3] * bd[ 1] +\n                     (int64_t)ad[ 4] * bd[ 0];\n    t[ 5] = cd[ 5] + (int64_t)ad[ 0] * bd[ 5] + (int64_t)ad[ 1] * bd[ 4] +\n                     (int64_t)ad[ 2] * bd[ 3] + (int64_t)ad[ 3] * bd[ 2] +\n                     (int64_t)ad[ 4] * bd[ 1] + (int64_t)ad[ 5] * bd[ 0];\n    t[ 6] = cd[ 6] + (int64_t)ad[ 0] * bd[ 6] + (int64_t)ad[ 1] * bd[ 5] +\n                     (int64_t)ad[ 2] * bd[ 4] + (int64_t)ad[ 3] * bd[ 3] +\n                     (int64_t)ad[ 4] * bd[ 2] + (int64_t)ad[ 5] * bd[ 1] +\n                     (int64_t)ad[ 6] * bd[ 0];\n    t[ 7] = cd[ 7] + (int64_t)ad[ 0] * bd[ 7] + (int64_t)ad[ 1] * bd[ 6] +\n                     (int64_t)ad[ 2] * bd[ 5] + (int64_t)ad[ 3] * bd[ 4] +\n                     (int64_t)ad[ 4] * bd[ 3] + (int64_t)ad[ 5] * bd[ 2] +\n                     (int64_t)ad[ 6] * bd[ 1] + (int64_t)ad[ 7] * bd[ 0];\n    t[ 8] = cd[ 8] + (int64_t)ad[ 0] * bd[ 8] + (int64_t)ad[ 1] * bd[ 7] +\n                     (int64_t)ad[ 2] * bd[ 6] + (int64_t)ad[ 3] * bd[ 5] +\n                     (int64_t)ad[ 4] * bd[ 4] + (int64_t)ad[ 5] * bd[ 3] +\n                     (int64_t)ad[ 6] * bd[ 2] + (int64_t)ad[ 7] * bd[ 1] +\n                     (int64_t)ad[ 8] * bd[ 0];\n    t[ 9] = cd[ 9] + (int64_t)ad[ 0] * bd[ 9] + (int64_t)ad[ 1] * bd[ 8] +\n                     (int64_t)ad[ 2] * bd[ 7] + (int64_t)ad[ 3] * bd[ 6] +\n                     (int64_t)ad[ 4] * bd[ 5] + (int64_t)ad[ 5] * bd[ 4] +\n                     (int64_t)ad[ 6] * bd[ 3] + (int64_t)ad[ 7] * bd[ 2] +\n                     (int64_t)ad[ 8] * bd[ 1] + (int64_t)ad[ 9] * bd[ 0];\n    t[10] = cd[10] + (int64_t)ad[ 0] * bd[10] + (int64_t)ad[ 1] * bd[ 9] +\n                     (int64_t)ad[ 2] * bd[ 8] + (int64_t)ad[ 3] * bd[ 7] +\n                     (int64_t)ad[ 4] * bd[ 6] + (int64_t)ad[ 5] * bd[ 5] +\n                     (int64_t)ad[ 6] * bd[ 4] + (int64_t)ad[ 7] * bd[ 3] +\n                     (int64_t)ad[ 8] * bd[ 2] + (int64_t)ad[ 9] * bd[ 1] +\n                     (int64_t)ad[10] * bd[ 0];\n    t[11] = cd[11] + (int64_t)ad[ 0] * bd[11] + (int64_t)ad[ 1] * bd[10] +\n                     (int64_t)ad[ 2] * bd[ 9] + (int64_t)ad[ 3] * bd[ 8] +\n                     (int64_t)ad[ 4] * bd[ 7] + (int64_t)ad[ 5] * bd[ 6] +\n                     (int64_t)ad[ 6] * bd[ 5] + (int64_t)ad[ 7] * bd[ 4] +\n                     (int64_t)ad[ 8] * bd[ 3] + (int64_t)ad[ 9] * bd[ 2] +\n                     (int64_t)ad[10] * bd[ 1] + (int64_t)ad[11] * bd[ 0];\n    t[12] =          (int64_t)ad[ 1] * bd[11] + (int64_t)ad[ 2] * bd[10] +\n                     (int64_t)ad[ 3] * bd[ 9] + (int64_t)ad[ 4] * bd[ 8] +\n                     (int64_t)ad[ 5] * bd[ 7] + (int64_t)ad[ 6] * bd[ 6] +\n                     (int64_t)ad[ 7] * bd[ 5] + (int64_t)ad[ 8] * bd[ 4] +\n                     (int64_t)ad[ 9] * bd[ 3] + (int64_t)ad[10] * bd[ 2] +\n                     (int64_t)ad[11] * bd[ 1];\n    t[13] =          (int64_t)ad[ 2] * bd[11] + (int64_t)ad[ 3] * bd[10] +\n                     (int64_t)ad[ 4] * bd[ 9] + (int64_t)ad[ 5] * bd[ 8] +\n                     (int64_t)ad[ 6] * bd[ 7] + (int64_t)ad[ 7] * bd[ 6] +\n                     (int64_t)ad[ 8] * bd[ 5] + (int64_t)ad[ 9] * bd[ 4] +\n                     (int64_t)ad[10] * bd[ 3] + (int64_t)ad[11] * bd[ 2];\n    t[14] =          (int64_t)ad[ 3] * bd[11] + (int64_t)ad[ 4] * bd[10] +\n                     (int64_t)ad[ 5] * bd[ 9] + (int64_t)ad[ 6] * bd[ 8] +\n                     (int64_t)ad[ 7] * bd[ 7] + (int64_t)ad[ 8] * bd[ 6] +\n                     (int64_t)ad[ 9] * bd[ 5] + (int64_t)ad[10] * bd[ 4] +\n                     (int64_t)ad[11] * bd[ 3];\n    t[15] =          (int64_t)ad[ 4] * bd[11] + (int64_t)ad[ 5] * bd[10] +\n                     (int64_t)ad[ 6] * bd[ 9] + (int64_t)ad[ 7] * bd[ 8] +\n                     (int64_t)ad[ 8] * bd[ 7] + (int64_t)ad[ 9] * bd[ 6] +\n                     (int64_t)ad[10] * bd[ 5] + (int64_t)ad[11] * bd[ 4];\n    t[16] =          (int64_t)ad[ 5] * bd[11] + (int64_t)ad[ 6] * bd[10] +\n                     (int64_t)ad[ 7] * bd[ 9] + (int64_t)ad[ 8] * bd[ 8] +\n                     (int64_t)ad[ 9] * bd[ 7] + (int64_t)ad[10] * bd[ 6] +\n                     (int64_t)ad[11] * bd[ 5];\n    t[17] =          (int64_t)ad[ 6] * bd[11] + (int64_t)ad[ 7] * bd[10] +\n                     (int64_t)ad[ 8] * bd[ 9] + (int64_t)ad[ 9] * bd[ 8] +\n                     (int64_t)ad[10] * bd[ 7] + (int64_t)ad[11] * bd[ 6];\n    t[18] =          (int64_t)ad[ 7] * bd[11] + (int64_t)ad[ 8] * bd[10] +\n                     (int64_t)ad[ 9] * bd[ 9] + (int64_t)ad[10] * bd[ 8] +\n                     (int64_t)ad[11] * bd[ 7];\n    t[19] =          (int64_t)ad[ 8] * bd[11] + (int64_t)ad[ 9] * bd[10] +\n                     (int64_t)ad[10] * bd[ 9] + (int64_t)ad[11] * bd[ 8];\n    t[20] =          (int64_t)ad[ 9] * bd[11] + (int64_t)ad[10] * bd[10] +\n                     (int64_t)ad[11] * bd[ 9];\n    t[21] =          (int64_t)ad[10] * bd[11] + (int64_t)ad[11] * bd[10];\n    t[22] =          (int64_t)ad[11] * bd[11];\n    t[23] = 0;\n\n    carry = t[ 0] >> 21; t[ 1] += carry; t[ 0] &= MASK_21;\n    carry = t[ 2] >> 21; t[ 3] += carry; t[ 2] &= MASK_21;\n    carry = t[ 4] >> 21; t[ 5] += carry; t[ 4] &= MASK_21;\n    carry = t[ 6] >> 21; t[ 7] += carry; t[ 6] &= MASK_21;\n    carry = t[ 8] >> 21; t[ 9] += carry; t[ 8] &= MASK_21;\n    carry = t[10] >> 21; t[11] += carry; t[10] &= MASK_21;\n    carry = t[12] >> 21; t[13] += carry; t[12] &= MASK_21;\n    carry = t[14] >> 21; t[15] += carry; t[14] &= MASK_21;\n    carry = t[16] >> 21; t[17] += carry; t[16] &= MASK_21;\n    carry = t[18] >> 21; t[19] += carry; t[18] &= MASK_21;\n    carry = t[20] >> 21; t[21] += carry; t[20] &= MASK_21;\n    carry = t[22] >> 21; t[23] += carry; t[22] &= MASK_21;\n    carry = t[ 1] >> 21; t[ 2] += carry; t[ 1] &= MASK_21;\n    carry = t[ 3] >> 21; t[ 4] += carry; t[ 3] &= MASK_21;\n    carry = t[ 5] >> 21; t[ 6] += carry; t[ 5] &= MASK_21;\n    carry = t[ 7] >> 21; t[ 8] += carry; t[ 7] &= MASK_21;\n    carry = t[ 9] >> 21; t[10] += carry; t[ 9] &= MASK_21;\n    carry = t[11] >> 21; t[12] += carry; t[11] &= MASK_21;\n    carry = t[13] >> 21; t[14] += carry; t[13] &= MASK_21;\n    carry = t[15] >> 21; t[16] += carry; t[15] &= MASK_21;\n    carry = t[17] >> 21; t[18] += carry; t[17] &= MASK_21;\n    carry = t[19] >> 21; t[20] += carry; t[19] &= MASK_21;\n    carry = t[21] >> 21; t[22] += carry; t[21] &= MASK_21;\n\n    t[11] -= t[23] * ORDER_0;\n    t[12] -= t[23] * ORDER_1;\n    t[13] -= t[23] * ORDER_2;\n    t[14] -= t[23] * ORDER_3;\n    t[15] -= t[23] * ORDER_4;\n    t[16] -= t[23] * ORDER_5;\n\n    t[10] -= t[22] * ORDER_0;\n    t[11] -= t[22] * ORDER_1;\n    t[12] -= t[22] * ORDER_2;\n    t[13] -= t[22] * ORDER_3;\n    t[14] -= t[22] * ORDER_4;\n    t[15] -= t[22] * ORDER_5;\n\n    t[ 9] -= t[21] * ORDER_0;\n    t[10] -= t[21] * ORDER_1;\n    t[11] -= t[21] * ORDER_2;\n    t[12] -= t[21] * ORDER_3;\n    t[13] -= t[21] * ORDER_4;\n    t[14] -= t[21] * ORDER_5;\n\n    t[ 8] -= t[20] * ORDER_0;\n    t[ 9] -= t[20] * ORDER_1;\n    t[10] -= t[20] * ORDER_2;\n    t[11] -= t[20] * ORDER_3;\n    t[12] -= t[20] * ORDER_4;\n    t[13] -= t[20] * ORDER_5;\n\n    t[ 7] -= t[19] * ORDER_0;\n    t[ 8] -= t[19] * ORDER_1;\n    t[ 9] -= t[19] * ORDER_2;\n    t[10] -= t[19] * ORDER_3;\n    t[11] -= t[19] * ORDER_4;\n    t[12] -= t[19] * ORDER_5;\n\n    t[ 6] -= t[18] * ORDER_0;\n    t[ 7] -= t[18] * ORDER_1;\n    t[ 8] -= t[18] * ORDER_2;\n    t[ 9] -= t[18] * ORDER_3;\n    t[10] -= t[18] * ORDER_4;\n    t[11] -= t[18] * ORDER_5;\n\n    carry = t[ 6] >> 21; t[ 7] += carry; t[ 6] &= MASK_21;\n    carry = t[ 8] >> 21; t[ 9] += carry; t[ 8] &= MASK_21;\n    carry = t[10] >> 21; t[11] += carry; t[10] &= MASK_21;\n    carry = t[12] >> 21; t[13] += carry; t[12] &= MASK_21;\n    carry = t[14] >> 21; t[15] += carry; t[14] &= MASK_21;\n    carry = t[16] >> 21; t[17] += carry; t[16] &= MASK_21;\n    carry = t[ 7] >> 21; t[ 8] += carry; t[ 7] &= MASK_21;\n    carry = t[ 9] >> 21; t[10] += carry; t[ 9] &= MASK_21;\n    carry = t[11] >> 21; t[12] += carry; t[11] &= MASK_21;\n    carry = t[13] >> 21; t[14] += carry; t[13] &= MASK_21;\n    carry = t[15] >> 21; t[16] += carry; t[15] &= MASK_21;\n\n    t[ 5] -= t[17] * ORDER_0;\n    t[ 6] -= t[17] * ORDER_1;\n    t[ 7] -= t[17] * ORDER_2;\n    t[ 8] -= t[17] * ORDER_3;\n    t[ 9] -= t[17] * ORDER_4;\n    t[10] -= t[17] * ORDER_5;\n\n    t[ 4] -= t[16] * ORDER_0;\n    t[ 5] -= t[16] * ORDER_1;\n    t[ 6] -= t[16] * ORDER_2;\n    t[ 7] -= t[16] * ORDER_3;\n    t[ 8] -= t[16] * ORDER_4;\n    t[ 9] -= t[16] * ORDER_5;\n\n    t[ 3] -= t[15] * ORDER_0;\n    t[ 4] -= t[15] * ORDER_1;\n    t[ 5] -= t[15] * ORDER_2;\n    t[ 6] -= t[15] * ORDER_3;\n    t[ 7] -= t[15] * ORDER_4;\n    t[ 8] -= t[15] * ORDER_5;\n\n    t[ 2] -= t[14] * ORDER_0;\n    t[ 3] -= t[14] * ORDER_1;\n    t[ 4] -= t[14] * ORDER_2;\n    t[ 5] -= t[14] * ORDER_3;\n    t[ 6] -= t[14] * ORDER_4;\n    t[ 7] -= t[14] * ORDER_5;\n\n    t[ 1] -= t[13] * ORDER_0;\n    t[ 2] -= t[13] * ORDER_1;\n    t[ 3] -= t[13] * ORDER_2;\n    t[ 4] -= t[13] * ORDER_3;\n    t[ 5] -= t[13] * ORDER_4;\n    t[ 6] -= t[13] * ORDER_5;\n\n    t[ 0] -= t[12] * ORDER_0;\n    t[ 1] -= t[12] * ORDER_1;\n    t[ 2] -= t[12] * ORDER_2;\n    t[ 3] -= t[12] * ORDER_3;\n    t[ 4] -= t[12] * ORDER_4;\n    t[ 5] -= t[12] * ORDER_5;\n    t[12]  = 0;\n\n    carry = t[ 0] >> 21; t[ 1] += carry; t[ 0] &= MASK_21;\n    carry = t[ 1] >> 21; t[ 2] += carry; t[ 1] &= MASK_21;\n    carry = t[ 2] >> 21; t[ 3] += carry; t[ 2] &= MASK_21;\n    carry = t[ 3] >> 21; t[ 4] += carry; t[ 3] &= MASK_21;\n    carry = t[ 4] >> 21; t[ 5] += carry; t[ 4] &= MASK_21;\n    carry = t[ 5] >> 21; t[ 6] += carry; t[ 5] &= MASK_21;\n    carry = t[ 6] >> 21; t[ 7] += carry; t[ 6] &= MASK_21;\n    carry = t[ 7] >> 21; t[ 8] += carry; t[ 7] &= MASK_21;\n    carry = t[ 8] >> 21; t[ 9] += carry; t[ 8] &= MASK_21;\n    carry = t[ 9] >> 21; t[10] += carry; t[ 9] &= MASK_21;\n    carry = t[10] >> 21; t[11] += carry; t[10] &= MASK_21;\n    carry = t[11] >> 21; t[12] += carry; t[11] &= MASK_21;\n\n    t[ 0] -= t[12] * ORDER_0;\n    t[ 1] -= t[12] * ORDER_1;\n    t[ 2] -= t[12] * ORDER_2;\n    t[ 3] -= t[12] * ORDER_3;\n    t[ 4] -= t[12] * ORDER_4;\n    t[ 5] -= t[12] * ORDER_5;\n\n    carry = t[ 0] >> 21; t[ 1] += carry; t[ 0] &= MASK_21;\n    carry = t[ 1] >> 21; t[ 2] += carry; t[ 1] &= MASK_21;\n    carry = t[ 2] >> 21; t[ 3] += carry; t[ 2] &= MASK_21;\n    carry = t[ 3] >> 21; t[ 4] += carry; t[ 3] &= MASK_21;\n    carry = t[ 4] >> 21; t[ 5] += carry; t[ 4] &= MASK_21;\n    carry = t[ 5] >> 21; t[ 6] += carry; t[ 5] &= MASK_21;\n    carry = t[ 6] >> 21; t[ 7] += carry; t[ 6] &= MASK_21;\n    carry = t[ 7] >> 21; t[ 8] += carry; t[ 7] &= MASK_21;\n    carry = t[ 8] >> 21; t[ 9] += carry; t[ 8] &= MASK_21;\n    carry = t[ 9] >> 21; t[10] += carry; t[ 9] &= MASK_21;\n    carry = t[10] >> 21; t[11] += carry; t[10] &= MASK_21;\n\n    s[ 0] = (byte)(t[ 0] >>  0);\n    s[ 1] = (byte)(t[ 0] >>  8);\n    s[ 2] = (byte)((t[ 0] >> 16) | (t[ 1] <<  5));\n    s[ 3] = (byte)(t[ 1] >>  3);\n    s[ 4] = (byte)(t[ 1] >> 11);\n    s[ 5] = (byte)((t[ 1] >> 19) | (t[ 2] <<  2));\n    s[ 6] = (byte)(t[ 2] >>  6);\n    s[ 7] = (byte)((t[ 2] >> 14) | (t[ 3] <<  7));\n    s[ 8] = (byte)(t[ 3] >>  1);\n    s[ 9] = (byte)(t[ 3] >>  9);\n    s[10] = (byte)((t[ 3] >> 17) | (t[ 4] <<  4));\n    s[11] = (byte)(t[ 4] >>  4);\n    s[12] = (byte)(t[ 4] >> 12);\n    s[13] = (byte)((t[ 4] >> 20) | (t[ 5] <<  1));\n    s[14] = (byte)(t[ 5] >>  7);\n    s[15] = (byte)((t[ 5] >> 15) | (t[ 6] <<  6));\n    s[16] = (byte)(t[ 6] >>  2);\n    s[17] = (byte)(t[ 6] >> 10);\n    s[18] = (byte)((t[ 6] >> 18) | (t[ 7] <<  3));\n    s[19] = (byte)(t[ 7] >>  5);\n    s[20] = (byte)(t[ 7] >> 13);\n    s[21] = (byte)(t[ 8] >>  0);\n    s[22] = (byte)(t[ 8] >>  8);\n    s[23] = (byte)((t[ 8] >> 16) | (t[ 9] <<  5));\n    s[24] = (byte)(t[ 9] >>  3);\n    s[25] = (byte)(t[ 9] >> 11);\n    s[26] = (byte)((t[ 9] >> 19) | (t[10] <<  2));\n    s[27] = (byte)(t[10] >>  6);\n    s[28] = (byte)((t[10] >> 14) | (t[11] <<  7));\n    s[29] = (byte)(t[11] >>  1);\n    s[30] = (byte)(t[11] >>  9);\n    s[31] = (byte)(t[11] >> 17);\n}\n#else\nstatic uint64_t load_6(const byte* a)\n{\n    uint64_t n;\n    n = ((uint64_t)a[0] <<  0) |\n        ((uint64_t)a[1] <<  8) |\n        ((uint64_t)a[2] << 16) |\n        ((uint64_t)a[3] << 24) |\n        ((uint64_t)a[4] << 32) |\n        ((uint64_t)a[5] << 40);\n    return n;\n}\n\nstatic uint64_t load_7(const byte* a)\n{\n    uint64_t n;\n    n = ((uint64_t)a[0] <<  0) |\n        ((uint64_t)a[1] <<  8) |\n        ((uint64_t)a[2] << 16) |\n        ((uint64_t)a[3] << 24) |\n        ((uint64_t)a[4] << 32) |\n        ((uint64_t)a[5] << 40) |\n        ((uint64_t)a[6] << 48);\n    return n;\n}\n\n#define MASK_42     0x3ffffffffffl\n#define ORDER_0     0x31a5cf5d3edl\n#define ORDER_1     0x1e735960498l\n#define ORDER_2     0x14def9dea2fl\n\n/*\nInput:\n  s[0]+256*s[1]+...+256^63*s[63] = s\n\nOutput:\n  s[0]+256*s[1]+...+256^31*s[31] = s mod l\n  where l = 2^252 + 27742317777372353535851937790883648493.\n  Overwrites s in place.\n*/\nvoid sc_reduce(byte* s)\n{\n    __int128_t t[12];\n    __int128_t carry;\n\n    t[ 0] = MASK_42 & (load_6(s +  0) >> 0);\n    t[ 1] = MASK_42 & (load_6(s +  5) >> 2);\n    t[ 2] = MASK_42 & (load_6(s + 10) >> 4);\n    t[ 3] = MASK_42 & (load_6(s + 15) >> 6);\n    t[ 4] = MASK_42 & (load_6(s + 21) >> 0);\n    t[ 5] = MASK_42 & (load_6(s + 26) >> 2);\n    t[ 6] = MASK_42 & (load_6(s + 31) >> 4);\n    t[ 7] = MASK_42 & (load_6(s + 36) >> 6);\n    t[ 8] = MASK_42 & (load_6(s + 42) >> 0);\n    t[ 9] = MASK_42 & (load_6(s + 47) >> 2);\n    t[10] = MASK_42 & (load_6(s + 52) >> 4);\n    t[11] =           (load_7(s + 57) >> 6);\n\n    t[ 5] -= t[11] * ORDER_0;\n    t[ 6] -= t[11] * ORDER_1;\n    t[ 7] -= t[11] * ORDER_2;\n\n    t[ 4] -= t[10] * ORDER_0;\n    t[ 5] -= t[10] * ORDER_1;\n    t[ 6] -= t[10] * ORDER_2;\n\n    t[ 3] -= t[ 9] * ORDER_0;\n    t[ 4] -= t[ 9] * ORDER_1;\n    t[ 5] -= t[ 9] * ORDER_2;\n\n    carry = t[ 3] >> 42; t[ 4] += carry; t[ 3] &= MASK_42;\n    carry = t[ 5] >> 42; t[ 6] += carry; t[ 5] &= MASK_42;\n    carry = t[ 7] >> 42; t[ 8] += carry; t[ 7] &= MASK_42;\n    carry = t[ 4] >> 42; t[ 5] += carry; t[ 4] &= MASK_42;\n    carry = t[ 6] >> 42; t[ 7] += carry; t[ 6] &= MASK_42;\n\n    t[ 2] -= t[ 8] * ORDER_0;\n    t[ 3] -= t[ 8] * ORDER_1;\n    t[ 4] -= t[ 8] * ORDER_2;\n\n    t[ 1] -= t[ 7] * ORDER_0;\n    t[ 2] -= t[ 7] * ORDER_1;\n    t[ 3] -= t[ 7] * ORDER_2;\n\n    t[ 0] -= t[ 6] * ORDER_0;\n    t[ 1] -= t[ 6] * ORDER_1;\n    t[ 2] -= t[ 6] * ORDER_2;\n    t[ 6]  = 0;\n\n    carry = t[ 0] >> 42; t[ 1] += carry; t[ 0] &= MASK_42;\n    carry = t[ 1] >> 42; t[ 2] += carry; t[ 1] &= MASK_42;\n    carry = t[ 2] >> 42; t[ 3] += carry; t[ 2] &= MASK_42;\n    carry = t[ 3] >> 42; t[ 4] += carry; t[ 3] &= MASK_42;\n    carry = t[ 4] >> 42; t[ 5] += carry; t[ 4] &= MASK_42;\n    carry = t[ 5] >> 42; t[ 6] += carry; t[ 5] &= MASK_42;\n\n    t[ 0] -= t[ 6] * ORDER_0;\n    t[ 1] -= t[ 6] * ORDER_1;\n    t[ 2] -= t[ 6] * ORDER_2;\n\n    carry = t[ 0] >> 42; t[ 1] += carry; t[ 0] &= MASK_42;\n    carry = t[ 1] >> 42; t[ 2] += carry; t[ 1] &= MASK_42;\n    carry = t[ 2] >> 42; t[ 3] += carry; t[ 2] &= MASK_42;\n    carry = t[ 3] >> 42; t[ 4] += carry; t[ 3] &= MASK_42;\n    carry = t[ 4] >> 42; t[ 5] += carry; t[ 4] &= MASK_42;\n\n    s[ 0] = (t[ 0] >>  0);\n    s[ 1] = (t[ 0] >>  8);\n    s[ 2] = (t[ 0] >> 16);\n    s[ 3] = (t[ 0] >> 24);\n    s[ 4] = (t[ 0] >> 32);\n    s[ 5] = (t[ 0] >> 40) | (t[ 1] <<  2);\n    s[ 6] = (t[ 1] >>  6);\n    s[ 7] = (t[ 1] >> 14);\n    s[ 8] = (t[ 1] >> 22);\n    s[ 9] = (t[ 1] >> 30);\n    s[10] = (t[ 1] >> 38) | (t[ 2] <<  4);\n    s[11] = (t[ 2] >>  4);\n    s[12] = (t[ 2] >> 12);\n    s[13] = (t[ 2] >> 20);\n    s[14] = (t[ 2] >> 28);\n    s[15] = (t[ 2] >> 36) | (t[ 3] <<  6);\n    s[16] = (t[ 3] >>  2);\n    s[17] = (t[ 3] >> 10);\n    s[18] = (t[ 3] >> 18);\n    s[19] = (t[ 3] >> 26);\n    s[20] = (t[ 3] >> 34);\n    s[21] = (t[ 4] >>  0);\n    s[22] = (t[ 4] >>  8);\n    s[23] = (t[ 4] >> 16);\n    s[24] = (t[ 4] >> 24);\n    s[25] = (t[ 4] >> 32);\n    s[26] = (t[ 4] >> 40) | (t[ 5] <<  2);\n    s[27] = (t[ 5] >>  6);\n    s[28] = (t[ 5] >> 14);\n    s[29] = (t[ 5] >> 22);\n    s[30] = (t[ 5] >> 30);\n    s[31] = (t[ 5] >> 38);\n}\n\n/*\nInput:\n  a[0]+256*a[1]+...+256^31*a[31] = a\n  b[0]+256*b[1]+...+256^31*b[31] = b\n  c[0]+256*c[1]+...+256^31*c[31] = c\n\nOutput:\n  s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l\n  where l = 2^252 + 27742317777372353535851937790883648493.\n*/\nvoid sc_muladd(byte* s, const byte* a, const byte* b, const byte* c)\n{\n    uint64_t ad[6], bd[6], cd[6];\n    __int128_t t[12];\n    __int128_t carry;\n\n    ad[ 0] = MASK_42 & (load_6(a +  0) >> 0);\n    ad[ 1] = MASK_42 & (load_6(a +  5) >> 2);\n    ad[ 2] = MASK_42 & (load_6(a + 10) >> 4);\n    ad[ 3] = MASK_42 & (load_6(a + 15) >> 6);\n    ad[ 4] = MASK_42 & (load_6(a + 21) >> 0);\n    ad[ 5] =           (load_6(a + 26) >> 2);\n    bd[ 0] = MASK_42 & (load_6(b +  0) >> 0);\n    bd[ 1] = MASK_42 & (load_6(b +  5) >> 2);\n    bd[ 2] = MASK_42 & (load_6(b + 10) >> 4);\n    bd[ 3] = MASK_42 & (load_6(b + 15) >> 6);\n    bd[ 4] = MASK_42 & (load_6(b + 21) >> 0);\n    bd[ 5] =           (load_6(b + 26) >> 2);\n    cd[ 0] = MASK_42 & (load_6(c +  0) >> 0);\n    cd[ 1] = MASK_42 & (load_6(c +  5) >> 2);\n    cd[ 2] = MASK_42 & (load_6(c + 10) >> 4);\n    cd[ 3] = MASK_42 & (load_6(c + 15) >> 6);\n    cd[ 4] = MASK_42 & (load_6(c + 21) >> 0);\n    cd[ 5] =           (load_6(c + 26) >> 2);\n\n    t[ 0] = cd[ 0] + (__int128_t)ad[ 0] * bd[ 0];\n    t[ 1] = cd[ 1] + (__int128_t)ad[ 0] * bd[ 1] + (__int128_t)ad[ 1] * bd[ 0];\n    t[ 2] = cd[ 2] + (__int128_t)ad[ 0] * bd[ 2] + (__int128_t)ad[ 1] * bd[ 1] +\n                     (__int128_t)ad[ 2] * bd[ 0];\n    t[ 3] = cd[ 3] + (__int128_t)ad[ 0] * bd[ 3] + (__int128_t)ad[ 1] * bd[ 2] +\n                     (__int128_t)ad[ 2] * bd[ 1] + (__int128_t)ad[ 3] * bd[ 0];\n    t[ 4] = cd[ 4] + (__int128_t)ad[ 0] * bd[ 4] + (__int128_t)ad[ 1] * bd[ 3] +\n                     (__int128_t)ad[ 2] * bd[ 2] + (__int128_t)ad[ 3] * bd[ 1] +\n                     (__int128_t)ad[ 4] * bd[ 0];\n    t[ 5] = cd[ 5] + (__int128_t)ad[ 0] * bd[ 5] + (__int128_t)ad[ 1] * bd[ 4] +\n                     (__int128_t)ad[ 2] * bd[ 3] + (__int128_t)ad[ 3] * bd[ 2] +\n                     (__int128_t)ad[ 4] * bd[ 1] + (__int128_t)ad[ 5] * bd[ 0];\n    t[ 6] =          (__int128_t)ad[ 1] * bd[ 5] + (__int128_t)ad[ 2] * bd[ 4] +\n                     (__int128_t)ad[ 3] * bd[ 3] + (__int128_t)ad[ 4] * bd[ 2] +\n                     (__int128_t)ad[ 5] * bd[ 1];\n    t[ 7] =          (__int128_t)ad[ 2] * bd[ 5] + (__int128_t)ad[ 3] * bd[ 4] +\n                     (__int128_t)ad[ 4] * bd[ 3] + (__int128_t)ad[ 5] * bd[ 2];\n    t[ 8] =          (__int128_t)ad[ 3] * bd[ 5] + (__int128_t)ad[ 4] * bd[ 4] +\n                     (__int128_t)ad[ 5] * bd[ 3];\n    t[ 9] =          (__int128_t)ad[ 4] * bd[ 5] + (__int128_t)ad[ 5] * bd[ 4];\n    t[10] =          (__int128_t)ad[ 5] * bd[ 5];\n    t[11] = 0;\n\n    carry = t[ 0] >> 42; t[ 1] += carry; t[ 0] &= MASK_42;\n    carry = t[ 2] >> 42; t[ 3] += carry; t[ 2] &= MASK_42;\n    carry = t[ 4] >> 42; t[ 5] += carry; t[ 4] &= MASK_42;\n    carry = t[ 6] >> 42; t[ 7] += carry; t[ 6] &= MASK_42;\n    carry = t[ 8] >> 42; t[ 9] += carry; t[ 8] &= MASK_42;\n    carry = t[10] >> 42; t[11] += carry; t[10] &= MASK_42;\n    carry = t[ 1] >> 42; t[ 2] += carry; t[ 1] &= MASK_42;\n    carry = t[ 3] >> 42; t[ 4] += carry; t[ 3] &= MASK_42;\n    carry = t[ 5] >> 42; t[ 6] += carry; t[ 5] &= MASK_42;\n    carry = t[ 7] >> 42; t[ 8] += carry; t[ 7] &= MASK_42;\n    carry = t[ 9] >> 42; t[10] += carry; t[ 9] &= MASK_42;\n\n    t[ 5] -= t[11] * ORDER_0;\n    t[ 6] -= t[11] * ORDER_1;\n    t[ 7] -= t[11] * ORDER_2;\n\n    t[ 4] -= t[10] * ORDER_0;\n    t[ 5] -= t[10] * ORDER_1;\n    t[ 6] -= t[10] * ORDER_2;\n\n    t[ 3] -= t[ 9] * ORDER_0;\n    t[ 4] -= t[ 9] * ORDER_1;\n    t[ 5] -= t[ 9] * ORDER_2;\n\n    carry = t[ 3] >> 42; t[ 4] += carry; t[ 3] &= MASK_42;\n    carry = t[ 5] >> 42; t[ 6] += carry; t[ 5] &= MASK_42;\n    carry = t[ 7] >> 42; t[ 8] += carry; t[ 7] &= MASK_42;\n    carry = t[ 4] >> 42; t[ 5] += carry; t[ 4] &= MASK_42;\n    carry = t[ 6] >> 42; t[ 7] += carry; t[ 6] &= MASK_42;\n\n    t[ 2] -= t[ 8] * ORDER_0;\n    t[ 3] -= t[ 8] * ORDER_1;\n    t[ 4] -= t[ 8] * ORDER_2;\n\n    t[ 1] -= t[ 7] * ORDER_0;\n    t[ 2] -= t[ 7] * ORDER_1;\n    t[ 3] -= t[ 7] * ORDER_2;\n\n    t[ 0] -= t[ 6] * ORDER_0;\n    t[ 1] -= t[ 6] * ORDER_1;\n    t[ 2] -= t[ 6] * ORDER_2;\n    t[ 6]  = 0;\n\n    carry = t[ 0] >> 42; t[ 1] += carry; t[ 0] &= MASK_42;\n    carry = t[ 1] >> 42; t[ 2] += carry; t[ 1] &= MASK_42;\n    carry = t[ 2] >> 42; t[ 3] += carry; t[ 2] &= MASK_42;\n    carry = t[ 3] >> 42; t[ 4] += carry; t[ 3] &= MASK_42;\n    carry = t[ 4] >> 42; t[ 5] += carry; t[ 4] &= MASK_42;\n    carry = t[ 5] >> 42; t[ 6] += carry; t[ 5] &= MASK_42;\n\n    t[ 0] -= t[ 6] * ORDER_0;\n    t[ 1] -= t[ 6] * ORDER_1;\n    t[ 2] -= t[ 6] * ORDER_2;\n\n    carry = t[ 0] >> 42; t[ 1] += carry; t[ 0] &= MASK_42;\n    carry = t[ 1] >> 42; t[ 2] += carry; t[ 1] &= MASK_42;\n    carry = t[ 2] >> 42; t[ 3] += carry; t[ 2] &= MASK_42;\n    carry = t[ 3] >> 42; t[ 4] += carry; t[ 3] &= MASK_42;\n    carry = t[ 4] >> 42; t[ 5] += carry; t[ 4] &= MASK_42;\n\n    s[ 0] = (t[ 0] >>  0);\n    s[ 1] = (t[ 0] >>  8);\n    s[ 2] = (t[ 0] >> 16);\n    s[ 3] = (t[ 0] >> 24);\n    s[ 4] = (t[ 0] >> 32);\n    s[ 5] = (t[ 0] >> 40) | (t[ 1] <<  2);\n    s[ 6] = (t[ 1] >>  6);\n    s[ 7] = (t[ 1] >> 14);\n    s[ 8] = (t[ 1] >> 22);\n    s[ 9] = (t[ 1] >> 30);\n    s[10] = (t[ 1] >> 38) | (t[ 2] <<  4);\n    s[11] = (t[ 2] >>  4);\n    s[12] = (t[ 2] >> 12);\n    s[13] = (t[ 2] >> 20);\n    s[14] = (t[ 2] >> 28);\n    s[15] = (t[ 2] >> 36) | (t[ 3] <<  6);\n    s[16] = (t[ 3] >>  2);\n    s[17] = (t[ 3] >> 10);\n    s[18] = (t[ 3] >> 18);\n    s[19] = (t[ 3] >> 26);\n    s[20] = (t[ 3] >> 34);\n    s[21] = (t[ 4] >>  0);\n    s[22] = (t[ 4] >>  8);\n    s[23] = (t[ 4] >> 16);\n    s[24] = (t[ 4] >> 24);\n    s[25] = (t[ 4] >> 32);\n    s[26] = (t[ 4] >> 40) | (t[ 5] <<  2);\n    s[27] = (t[ 5] >>  6);\n    s[28] = (t[ 5] >> 14);\n    s[29] = (t[ 5] >> 22);\n    s[30] = (t[ 5] >> 30);\n    s[31] = (t[ 5] >> 38);\n}\n#endif /* !HAVE___UINT128_T || NO_CURVED25519_128BIT */\n\nint ge_compress_key(byte* out, const byte* xIn, const byte* yIn, word32 keySz)\n{\n    ge     x,y,z;\n    ge_p3  g;\n    byte   bArray[ED25519_KEY_SIZE];\n    word32 i;\n\n    fe_0(x);\n    fe_0(y);\n    fe_1(z);\n    fe_frombytes(x, xIn);\n    fe_frombytes(y, yIn);\n\n    fe_copy(g.X, x);\n    fe_copy(g.Y, y);\n    fe_copy(g.Z, z);\n\n    ge_p3_tobytes(bArray, &g);\n\n    for (i = 0; i < keySz; i++) {\n        out[keySz - 1 - i] = bArray[i];\n    }\n\n    return 0;\n}\n\n\n/*\nr = p + q\n*/\nstatic WC_INLINE void ge_add(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q)\n{\n#ifndef CURVED25519_ASM\n    ge t0;\n    fe_add(r->X,p->Y,p->X);\n    fe_sub(r->Y,p->Y,p->X);\n    fe_mul(r->Z,r->X,q->YplusX);\n    fe_mul(r->Y,r->Y,q->YminusX);\n    fe_mul(r->T,q->T2d,p->T);\n    fe_mul(r->X,p->Z,q->Z);\n    fe_add(t0,r->X,r->X);\n    fe_sub(r->X,r->Z,r->Y);\n    fe_add(r->Y,r->Z,r->Y);\n    fe_add(r->Z,t0,r->T);\n    fe_sub(r->T,t0,r->T);\n#else\n    fe_ge_add(r->X, r->Y, r->Z, r->T, p->X, p->Y, p->Z, p->T, q->Z, q->T2d,\n              q->YplusX, q->YminusX);\n#endif\n}\n\n\n#ifndef CURVED25519_ASM\n/* ge_scalar mult base */\nstatic unsigned char equal(signed char b,signed char c)\n{\n  unsigned char ub = b;\n  unsigned char uc = c;\n  unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */\n  uint32_t y = x; /* 0: yes; 1..255: no */\n  y -= 1; /* 4294967295: yes; 0..254: no */\n  y >>= 31; /* 1: yes; 0: no */\n  return (unsigned char)y;\n}\n\n\nstatic unsigned char negative(signed char b)\n{\n  return ((unsigned char)b) >> 7;\n}\n\n\nstatic WC_INLINE void cmov(ge_precomp *t,const ge_precomp *u,unsigned char b,\n                        unsigned char n)\n{\n  b = equal(b,n);\n  fe_cmov(t->yplusx,u->yplusx,b);\n  fe_cmov(t->yminusx,u->yminusx,b);\n  fe_cmov(t->xy2d,u->xy2d,b);\n}\n#endif\n\n#ifdef CURVED25519_ASM_64BIT\nstatic const ge_precomp base[64][8] = {\n{\n    {\n        { 0x2fbc93c6f58c3b85, -0x306cd2390473f1e7, 0x270b4898643d42c2, 0x07cf9d3a33d4ba65 },\n        { -0x62efc6fa28bf6ec2, -0x02c660fa2ebf414d, -0x5a3e7bcb977075f7, 0x44fd2f9298f81267 },\n        { -0x2442ea98b49044a7, 0x41e13f00eea2a5ea, -0x322b62e336a83906, 0x4f0ebe1faf16ecca }\n    },\n    {\n        { -0x6ddb18036cc38e29, -0x60b9626985f00a4b, 0x5aa69a65e1d60702, 0x590c063fa87d2e2e },\n        { -0x75665a9fbd4b2a58, -0x70d47ef3b19f530a, -0x1f61dc944e91c856, 0x6bb595a669c92555 },\n        { 0x6e347eaadad36802, -0x450ca66c7c11b7fb, 0x3bcabe10e6076826, 0x49314f0a165ed1b8 }\n    },\n    {\n        { -0x50da4f57b31168d0, 0x025a8430e8864b8a, -0x3ee4affd60fe98ce, 0x7a164e1b9a80f8f4 },\n        { 0x56611fe8a4fcd265, 0x3bd353fde5c1ba7d, -0x7ece0ce5deb42943, 0x2ab91587555bda62 },\n        { -0x640dee0b0e98b7cc, -0x47b194e809d2076b, -0x282190f8a48dd5b2, 0x549a04b963bb2a21 }\n    },\n    {\n        { 0x287351b98efc099f, 0x6765c6f47dfd2538, -0x35cb72c204f56d9b, 0x680e910321e58727 },\n        { -0x6a01faf5fa97e741, 0x327e89715660faa9, -0x3c171c32f95faf8d, 0x27933f4c7445a49a },\n        { -0x40e1ba131aebd950, -0x1cd439c29245f06c, -0x1bd68b2a7307ad40, 0x44f079b1b0e64c18 }\n    },\n    {\n        { -0x5ded43bbf75a44cd, -0x72afb73c38a112fe, -0x22e414f3a54013bc, 0x2945ccf146e206eb },\n        { 0x7f9182c3a447d6ba, -0x2affeb2eb4d8d649, -0x1cc30ee3479b5f79, 0x154a7e73eb1b55f3 },\n        { -0x37cd5e86182ffc4d, 0x5f729d0a00124d7e, 0x62c1d4a10e6d8ff3, 0x68b8ac5938b27a98 }\n    },\n    {\n        { 0x3a0ceeeb77157131, -0x64d8ea76ff375078, -0x7f9a499725a658ca, 0x51e57bb6a2cc38bd },\n        { 0x499806b67b7d8ca4, 0x575be28427d22739, -0x44f7a318dfbaac47, 0x38b64c41ae417884 },\n        { -0x7062526e97621c5c, 0x175f2428f8fb9137, 0x050ab5329fcfb988, 0x7865dfa21354c09f }\n    },\n    {\n        { 0x6b1a5cd0944ea3bf, 0x7470353ab39dc0d2, 0x71b2528228542e49, 0x461bea69283c927e },\n        { -0x4590d36555cdde4f, 0x6ca021533bba23a7, -0x621589b06de6d3c6, 0x1d6edd5d2e5317e0 },\n        { 0x217a8aacab0fda36, -0x5ad739abc2cab638, 0x37d05b8b13ab7568, 0x233cef623a2cbc37 }\n    },\n    {\n        { 0x59b7596604dd3e8f, 0x6cb30377e288702c, -0x4ecc6399a1263cdd, 0x0915e76061bce52f },\n        { -0x1d58a2120c6dcb27, -0x69c2897f1e4aa707, 0x2c2741ac6e3c23fb, 0x3a9024a1320e01c3 },\n        { -0x208217ca57cb5c82, -0x741e63259767a816, 0x2c1185367167b326, 0x589eb3d9dbefd5c2 }\n    },\n},\n{\n    {\n        { 0x322d04a52d9021f6, -0x463e60cc8a394064, 0x587a3a4342d20b09, 0x143b1cf8aa64fe61 },\n        { 0x7ec851ca553e2df3, -0x58ed7b3459b7874d, -0x194a1be6cd772e19, 0x4cf210ec5a9a8883 },\n        { -0x6079838269753555, 0x5f54258e27092729, -0x2f582cb415e7f68b, 0x21b546a3374126e1 }\n    },\n    {\n        { 0x490a7a45d185218f, -0x65eac887b9fb6ccb, 0x0060ea09cc31e1f6, 0x7e041577f86ee965 },\n        { -0x56b007a75d777cbd, -0x31f12ba9acec12c4, -0x0aa3c2304a40cb06, 0x0a653ca5c9eab371 },\n        { 0x66b2a496ce5b67f3, -0x00ab6d2742a9686a, 0x503cec294a592cd0, 0x566943650813acb2 }\n    },\n    {\n        { 0x5672f9eb1dabb69d, -0x458f4aca5017ac04, 0x47ac0f752796d66d, 0x32a5351794117275 },\n        { -0x47e724f3d99df868, 0x5d5c31d9606e354a, 0x0982fa4f00a8cdc7, 0x17e12bcd4653e2d4 },\n        { -0x2c59bb59209b7bc9, 0x703b6559880fbfdd, -0x347adabf52c5e55b, 0x0900b3f78e4c6468 }\n    },\n    {\n        { -0x12d7f04137e952cf, 0x52d9595bd8e6efe3, 0x0fe71772f6c623f5, 0x4314030b051e293c },\n        { 0x0a851b9f679d651b, -0x1ef7349efcccbd0e, -0x29fe0a801774cf5d, 0x371f3acaed2dd714 },\n        { -0x2a9fffa1040f4353, -0x7148f0d12e78f3a2, 0x201f9033d084e6a0, 0x4c3a5ae1ce7b6670 }\n    },\n    {\n        { -0x45078a1b36c25f23, -0x46cd7d588e46d6b3, -0x7f29c0480b393ba0, 0x6de9c73dea66c181 },\n        { 0x4138a434dcb8fa95, -0x78f3098293697bf5, -0x21c77a8bd68417d4, 0x7c814db27262a55a },\n        { 0x478904d5a04df8f2, -0x050451b54efebd2d, -0x0937539caaa2f668, 0x5aac4a412f90b104 }\n    },\n    {\n        { 0x603a0d0abd7f5134, -0x7f7636cd1e2c51ba, -0x20da6ec67867429d, 0x1c145cd274ba0235 },\n        { -0x39b0cd94c536d6f8, 0x5551b282e663e1e0, 0x476b35f54a1a4b83, 0x1b9da3fe189f68c2 },\n        { 0x32e8386475f3d743, 0x365b8baf6ae5d9ef, -0x7dadc749c7a497e2, 0x234929c1167d65e1 }\n    },\n    {\n        { 0x48145cc21d099fcf, 0x4535c192cc28d7e5, -0x7f183e1ab7db81ff, 0x4a5f28743b2973ee },\n        { -0x67b213545f885218, 0x383f77ad19eb389d, -0x38139481d6ab286c, 0x59c77b3aeb7c3a7a },\n        { -0x2c5228dadda3309e, -0x6ee5cc7e4dead3a3, -0x274c6052a4f70783, 0x6f05606b4799fe3b }\n    },\n    {\n        { 0x5b433149f91b6483, -0x524a239aa5d3409e, -0x78057bed9cd7d84d, 0x60895e91ab49f8d8 },\n        { -0x6001616de884569e, -0x675118e2f21a351f, 0x3ff4ae942d831044, 0x714de12e58533ac8 },\n        { -0x16130d12f30793e8, -0x4b92f9edf8ca202c, -0x43625f67fb469419, 0x73e2e62fd96dc26b }\n    },\n},\n{\n    {\n        { 0x2eccdd0e632f9c1d, 0x51d0b69676893115, 0x52dfb76ba8637a58, 0x6dd37d49a00eef39 },\n        { -0x12a49cabb655aea2, -0x579a3b60f4397dc6, -0x7af3e016a4bd2e3c, 0x30d76d6f03d315b9 },\n        { 0x6c4444172106e4c7, -0x04ac297f6d728097, -0x4b8c615b96b2c0da, 0x10c697112e864bb0 }\n    },\n    {\n        { 0x0ca62aa08358c805, 0x6a3d4ae37a204247, 0x7464d3a63b11eddc, 0x03bf9baf550806ef },\n        { 0x6493c4277dbe5fde, 0x265d4fad19ad7ea2, 0x0e00dfc846304590, 0x25e61cabed66fe09 },\n        { 0x3f13e128cc586604, 0x6f5873ecb459747e, -0x5f49c21233ed970b, 0x566d78634586e22c }\n    },\n    {\n        { -0x5efabd7a39a5d030, 0x6c64112af31667c3, 0x680ae240731aee58, 0x14fba5f34793b22a },\n        { 0x1637a49f9cc10834, -0x4371a92a57643baf, 0x1cb5ec0f7f7fd2db, 0x33975bca5ecc35d9 },\n        { 0x3cd746166985f7d4, 0x593e5e84c9c80057, 0x2fc3f2b67b61131e, 0x14829cea83fc526c }\n    },\n    {\n        { 0x21e70b2f4e71ecb8, -0x19a92246bf5b881d, -0x409aa93131e2b080, 0x05fc3bc4535d7b7e },\n        { -0x00bc847b68226a3e, 0x6c744e30aa4eb5a7, -0x61f3a29ec37a1775, 0x2fd9c71e5f758173 },\n        { 0x24b8b3ae52afdedd, 0x3495638ced3b30cf, 0x33a4bc83a9be8195, 0x373767475c651f04 }\n    },\n    {\n        { 0x634095cb14246590, -0x10edebbfe93eaacb, -0x61c7ebf376ef43a0, 0x6bf5905730907c8c },\n        { 0x2fba99fd40d1add9, -0x4cf8e990690b2fd9, 0x4363f05215f03bae, 0x1fbea56c3b18f999 },\n        { 0x0fa778f1e1415b8a, 0x06409ff7bac3a77e, 0x6f52d7b89aa29a50, 0x02521cf67a635a56 }\n    },\n    {\n        { -0x4eeb98df88d0a11c, -0x17076b4e69f86532, 0x4af8224d00ac824a, 0x001753d9f7cd6cc4 },\n        { 0x513fee0b0a9d5294, -0x706718a3f020a59a, -0x2b9e7977401ef832, 0x3fa00a7e71382ced },\n        { 0x3c69232d963ddb34, 0x1dde87dab4973858, -0x55282e065f6e0d7b, 0x12b5fe2fa048edb6 }\n    },\n    {\n        { -0x20d483d95290e16e, 0x4b66d323504b8913, -0x73bf623f8ae3743d, 0x6f7e93c20796c7b8 },\n        { 0x71f0fbc496fce34d, 0x73b9826badf35bed, -0x2dfb8d9e00d73a9f, 0x749b76f96fb1206f },\n        { 0x1f5af604aea6ae05, -0x3edcae0e411b6367, 0x61a808b5eeff6b66, 0x0fcec10f01e02151 }\n    },\n    {\n        { 0x3df2d29dc4244e45, 0x2b020e7493d8de0a, 0x6cc8067e820c214d, 0x413779166feab90a },\n        { 0x644d58a649fe1e44, 0x21fcaea231ad777e, 0x02441c5a887fd0d2, 0x4901aa7183c511f3 },\n        { 0x08b1b7548c1af8f0, -0x31f08583db9d664c, -0x089f4f06e1f926c7, 0x41bb887b726d1213 }\n    },\n},\n{\n    {\n        { -0x68267f1f55c6082e, 0x35d0384252c6b51c, 0x7d43f49307cd55aa, 0x56bd36cfb78ac362 },\n        { -0x6d987f93a983b628, 0x066d04ccca791e6a, -0x5960a9ba1c33c6b5, 0x5c95b686a0788cd2 },\n        { 0x2ac519c10d14a954, -0x150b8b4b6b4a0570, -0x19507c7d560785a6, 0x0dea6db1879be094 }\n    },\n    {\n        { 0x15baeb74d6a8797a, 0x7ef55cf1fac41732, 0x29001f5a3c8b05c5, 0x0ad7cc8752eaccfb },\n        { -0x559940ab8cbb1a55, -0x25eda77770e4bcf7, 0x5e87d2b3fd564b2f, 0x5b2c78885483b1dd },\n        { 0x52151362793408cf, -0x14f0e8fce669c26c, -0x57cc4d0577c26b9a, 0x093a7fa775003c78 }\n    },\n    {\n        { -0x47169fbb9f56ed7a, 0x7f3fd8047778d3de, 0x67d01e31bf8a5e2d, 0x7b038a06c27b653e },\n        { -0x1aef8219c5e92842, -0x5c880023650ccd31, 0x70d5bf18440b677f, 0x6a252b19a4a31403 },\n        { -0x6126e62a2c966f0d, 0x5213aebbdb4eb9f2, -0x38f715fab3466ecb, 0x58ded57f72260e56 }\n    },\n    {\n        { -0x2592acd9a4f02b75, -0x769f7dce6c405678, -0x287536cd9e2a81d8, 0x79f2942d3a5c8143 },\n        { 0x78e79dade9413d77, -0x0da8062a68d61983, 0x59db910ee37aa7e6, 0x6aa11b5bbb9e039c },\n        { -0x6825d0da49377217, 0x251ba7eaacf20169, 0x09b44f87ef4eb4e4, 0x7d90ab1bbc6a7da5 }\n    },\n    {\n        { 0x1a07a3f496b3c397, 0x11ceaa188f4e2532, 0x7d9498d5a7751bf0, 0x19ed161f508dd8a0 },\n        { -0x6533597c58fe9402, -0x6fafa0b20d3af493, 0x6b610d5fcce435aa, 0x19a10d446198ff96 },\n        { 0x560a2cd687dce6ca, 0x7f3568c48664cf4d, -0x78be16addd7fc5c8, 0x483bdab1595653fc }\n    },\n    {\n        { -0x2930b2f54b257f0a, -0x7db7c1ba07cf8020, 0x05005269ae6f9da4, 0x1c7052909cf7877a },\n        { -0x0587f0eb78cb05b7, 0x106f0b70360534e0, 0x2210776fe3e307bd, 0x3286c109dde6a0fe },\n        { 0x32ee7de2874e98d4, 0x14c362e9b97e0c60, 0x5781dcde6a60a38a, 0x217dd5eaaa7aa840 }\n    },\n    {\n        { -0x7420e0464173f138, 0x00bae7f8e30a0282, 0x4963991dad6c4f6c, 0x07058a6e5df6f60a },\n        { -0x62483b2fdb71e150, -0x1f89681eb28b40ae, 0x1e6a9b173c562354, 0x7fa7c21f795a4965 },\n        { -0x1614fd3b24ce0981, -0x12da0276ef4304d5, 0x46c8131f5c5cddb4, 0x33b21c13a0cb9bce }\n    },\n    {\n        { -0x6550464fa11c73a5, -0x4062d2b1f8e5ec39, -0x7111919216ccd6f6, 0x1c3bab17ae109717 },\n        { 0x360692f8087d8e31, -0x0b2339c82d8e9c09, 0x25a4e62065ea5963, 0x659bf72e5ac160d9 },\n        { 0x1c9ab216c7cab7b0, 0x7d65d37407bbc3cc, 0x52744750504a58d5, 0x09f2606b131a2990 }\n    },\n},\n{\n    {\n        { 0x7e234c597c6691ae, 0x64889d3d0a85b4c8, -0x251d36f3cab50519, 0x0a871e070c6a9e1d },\n        { 0x40e87d44744346be, 0x1d48dad415b52b25, 0x7c3a8a18a13b603e, 0x4eb728c12fcdbdf7 },\n        { 0x3301b5994bbc8989, 0x736bae3a5bdd4260, 0x0d61ade219d59e3c, 0x3ee7300f2685d464 }\n    },\n    {\n        { 0x43fa7947841e7518, -0x1a3905a69c63b929, -0x5ef9a1e21cfad48c, 0x7d47c6a2cfb89030 },\n        { -0x0a2daa1b61822949, -0x7fe9eea39ef4e154, 0x3c99975d92e187ca, 0x13815762979125c2 },\n        { 0x3fdad0148ef0d6e0, -0x62c18b656eab90c4, 0x71ec621026bb8157, 0x148cf58d34c9ec80 }\n    },\n    {\n        { -0x1da8d082651b8a93, 0x56c345bb88f3487f, -0x602ef492969f5773, 0x278febad4eaea1b9 },\n        { 0x46a492f67934f027, 0x469984bef6840aa9, 0x5ca1bc2a89611854, 0x3ff2fa1ebd5dbbd4 },\n        { -0x4e5597e0736cc69a, -0x73de6b63dfd6f368, 0x39115291219d3c52, 0x4104dd02fe9c677b }\n    },\n    {\n        { -0x7edeb1f924f69548, 0x21a8b6c90ce44f35, 0x6524c12a409e2af5, 0x0165b5a48efca481 },\n        { 0x72b2bf5e1124422a, -0x5e05f3cc675cc54b, -0x6b349efe05ad499a, 0x2c863b00afaf53d5 },\n        { -0x0e6f5b8b5f7b958a, 0x12eff984cd2f7cc0, 0x695e290658aa2b8f, 0x591b67d9bffec8b8 }\n    },\n    {\n        { -0x66464c8e60e74aa3, -0x1b9a1a055e739be2, 0x61081136c29f05ed, 0x489b4f867030128b },\n        { 0x312f0d1c80b49bfa, 0x5979515eabf3ec8a, 0x727033c09ef01c88, 0x3de02ec7ca8f7bcb },\n        { -0x2dcdefd2c5146d11, -0x1e9dac4b9ee9579f, 0x3d7eabe7190baa24, 0x49f5fbba496cbebf }\n    },\n    {\n        { 0x155d628c1e9c572e, -0x75b279533a77b8bf, -0x6e5cad09aea89c15, 0x06a1a6c28867515b },\n        { 0x30949a108a5bcfd4, -0x23bf228f439b8c15, -0x6d3d6b3ecf83f2e4, 0x5604a86dcbfa6e74 },\n        { 0x7288d1d47c1764b6, 0x72541140e0418b51, -0x60fce59fe753092f, 0x20989e89fe2742c6 }\n    },\n    {\n        { 0x1674278b85eaec2e, 0x5621dc077acb2bdf, 0x640a4c1661cbf45a, 0x730b9950f70595d3 },\n        { 0x499777fd3a2dcc7f, 0x32857c2ca54fd892, -0x5d86279b2df81c60, 0x0403ed1d0ca67e29 },\n        { -0x36b4d2ca78b13aae, -0x3a19373067db9073, -0x0834b905e93fca32, 0x5bd7454308303dcc }\n    },\n    {\n        { -0x7a3b6cdeea1886d6, -0x39b3765d42322237, -0x62e1c257525c289e, 0x5bb7db123067f82c },\n        { 0x7f9ad19528b24cc2, 0x7f6b54656335c181, 0x66b8b66e4fc07236, 0x133a78007380ad83 },\n        { 0x0961f467c6ca62be, 0x04ec21d6211952ee, 0x182360779bd54770, 0x740dca6d58f0e0d2 }\n    },\n},\n{\n    {\n        { 0x3906c72aed261ae5, -0x65497026771eff09, -0x0a16fa650cc9fe69, 0x0e53dc78bf2b6d47 },\n        { 0x50b70bf5d3f0af0b, 0x4feaf48ae32e71f7, 0x60e84ed3a55bbd34, 0x00ed489b3f50d1ed },\n        { -0x46f7d640868e7886, 0x5e4444636d17e631, 0x4d05c52e18276893, 0x27632d9a5a4a4af5 }\n    },\n    {\n        { -0x567d7a2e78150025, -0x5a4b0444272f579c, -0x49a70d80fdd99c09, 0x3bbc2b22d99ce282 },\n        { -0x2ee00faeab4d9f32, -0x27923c718d06ad90, 0x601fcd0d267cc138, 0x2b67916429e90ccd },\n        { -0x46e836ada7c3f5a8, 0x653ff9b80fe4c6f3, -0x64f258284320c3f4, 0x43a0eeb6ab54d60e }\n    },\n    {\n        { 0x3ac6322357875fe8, -0x262b0b130a043471, -0x72117b6cc7d449e0, 0x50c5eaa14c799fdc },\n        { 0x396966a46d4a5487, -0x07ee5e7553d44c46, 0x66e4685b5628b26b, 0x70a477029d929b92 },\n        { -0x22f12374290d04c4, 0x54c63aa79cc7b7a0, -0x51f4fcd4d37260e6, 0x6f9ce107602967fb }\n    },\n    {\n        { 0x139693063520e0b5, 0x437fcf7c88ea03fe, -0x082b3bf42c36a644, 0x699154d1f893ded9 },\n        { -0x52efab4e321e3dd6, -0x3b5716fdb714cd21, 0x5f3e7b33accdc0ea, 0x72364713fc79963e },\n        { 0x315d5c75b4b27526, -0x33347bd2fdc9255b, 0x22f0c8a3345fee8e, 0x73975a617d39dbed }\n    },\n    {\n        { 0x6f37f392f4433e46, 0x0e19b9a11f566b18, 0x220fb78a1fd1d662, 0x362a4258a381c94d },\n        { -0x1bfdb2069c8a25f0, 0x78d3251a1830c870, -0x6fd4e6b79a7326e4, 0x7e18b10b29b7438a },\n        { -0x6f8e26ecd49414d1, 0x0f26e9ad28418247, -0x1546e13642136da3, 0x4be65bc8f48af2de }\n    },\n    {\n        { 0x1d50fba257c26234, 0x7bd4823adeb0678b, -0x3d4f239159ac750b, 0x5665eec6351da73e },\n        { 0x78487feba36e7028, 0x5f3f13001dd8ce34, -0x6cb04ed2b4cf3b77, 0x056c244d397f0a2b },\n        { -0x24c11ff6bc404df0, 0x4972018720800ac2, 0x26ab5d6173bd8667, 0x20b209c2ab204938 }\n    },\n    {\n        { 0x1fcca94516bd3289, 0x448d65aa41420428, 0x59c3b7b216a55d62, 0x49992cc64e612cd8 },\n        { 0x549e342ac07fb34b, 0x02d8220821373d93, -0x43d9d28f532e0a99, 0x7a92c9fdfbcac784 },\n        { 0x65bd1bea70f801de, 0x1befb7c0fe49e28a, -0x579cf9324e4d51b6, 0x3b7ac0cd265c2a09 }\n    },\n    {\n        { -0x0f2ab1b0dd12c659, -0x5d5516e1a9f7eaf6, -0x0bde4d161225178b, 0x31bc531d6b7de992 },\n        { -0x7dd411bc73fe4314, 0x530cb525c0fbc73b, 0x48519034c1953fe9, 0x265cc261e09a0f5b },\n        { -0x20c2ecb2567f068f, 0x7a4fb8d1221a22a7, 0x3df7d42035aad6d8, 0x2a14edcc6a1a125e }\n    },\n},\n{\n    {\n        { 0x231a8c570478433c, -0x484ad8f13d7ebc63, -0x245566151c26f861, 0x2c03f5256c2b03d9 },\n        { -0x20b711f8ad3031b2, -0x3c00050cf913f749, 0x05710b2ab95459c4, 0x161d25fa963ea38d },\n        { 0x790f18757b53a47d, 0x307b0130cf0c5879, 0x31903d77257ef7f9, 0x699468bdbd96bbaf }\n    },\n    {\n        { -0x2722c2199556e6b8, 0x485064c22fc0d2cc, -0x64b7db99cb0215d1, 0x293e1c4e6c4a2e3a },\n        { -0x42e0d0b90b250131, 0x7cef0114a47fd6f7, -0x2ce00225b5b84c81, 0x525219a473905785 },\n        { 0x376e134b925112e1, 0x703778b5dca15da0, -0x4fba7650b9e3ceef, 0x5b605c447f032823 }\n    },\n    {\n        { 0x3be9fec6f0e7f04c, -0x7995a8618a1cb69e, 0x5542ef161e1de61a, 0x2f12fef4cc5abdd5 },\n        { -0x469a7fa6df3b8377, -0x180feff36dc47034, 0x0001256502e2ef77, 0x24a76dcea8aeb3ee },\n        { 0x0a4522b2dfc0c740, 0x10d06e7f40c9a407, -0x3930ebbe87300998, 0x5e607b2518a43790 }\n    },\n    {\n        { -0x5fd3bce35a6930ec, -0x1c3bd2bf512c1c00, -0x2dbad97fd1f0d925, 0x201f33139e457068 },\n        { 0x58b31d8f6cdf1818, 0x35cfa74fc36258a2, -0x1e4c00b09919e292, 0x5067acab6ccdd5f7 },\n        { -0x02ad8094f7fc62af, 0x18b14964017c0006, -0x2addf14fd1da5b58, 0x397cba8862460375 }\n    },\n    {\n        { 0x7815c3fbc81379e7, -0x599e6bdf221ed50f, -0x00563f077a57022b, 0x771b4022c1e1c252 },\n        { 0x30c13093f05959b2, -0x1dc55e721656868a, 0x222fd491721d5e26, 0x2339d320766e6c3a },\n        { -0x27822679aec5d059, -0x0a53648e062b30f8, -0x2f943ce4e15d7c4d, 0x331a189219971a76 }\n    },\n    {\n        { 0x26512f3a9d7572af, 0x5bcbe28868074a9e, -0x7b123e3eee7f083c, 0x1ac9619ff649a67b },\n        { -0x0ae990ba04b07f3a, -0x63c938219e388a31, -0x1c2b17e46fbe26e4, 0x31167c6b83bdfe21 },\n        { -0x0dd4c7bdadb4ef98, 0x5068343bee9ce987, -0x03628e7bb59daf38, 0x612436341f08b111 }\n    },\n    {\n        { -0x749cb61ce5d2d9c8, -0x622048ff642c02cb, 0x7f8bf1b8a3a06ba4, 0x1522aa3178d90445 },\n        { -0x2662be2478b17673, 0x09fea5f16c07dc20, 0x793d2c67d00f9bbc, 0x46ebe2309e5eff40 },\n        { 0x2c382f5369614938, -0x2501bf6548d292f0, -0x1737cc6e49b90dd9, 0x45fe70f50524306c }\n    },\n    {\n        { 0x62f24920c8951491, 0x05f007c83f630ca2, 0x6fbb45d2f5c9d4b8, 0x16619f6db57a2245 },\n        { -0x25b78a5969f3f474, 0x5b68d076ef0e2f20, 0x07fb51cf3d0b8fd4, 0x428d1623a0e392d4 },\n        { 0x084f4a4401a308fd, -0x57dde63c895a3554, -0x214721b9bc2e4383, 0x1d81592d60bd38c6 }\n    },\n},\n{\n    {\n        { 0x3a4a369a2f89c8a1, 0x63137a1d7c8de80d, -0x4353ff7587125feb, 0x2cb8b3a5b483b03f },\n        { -0x27cc284113d5b3c8, 0x2c9162830acc20ed, -0x16c5b8556d208a7f, 0x702d67a3333c4a81 },\n        { 0x36e417cbcb1b90a1, 0x33b3ddaa7f11794e, 0x3f510808885bc607, 0x24141dc0e6a8020d }\n    },\n    {\n        { -0x6e6da233427cea83, 0x3ca1205322cc8094, 0x28e57f183f90d6e4, 0x1a4714cede2e767b },\n        { 0x59f73c773fefee9d, -0x4c0e10763e306763, -0x1ca204bd1fd1aba1, 0x5766120b47a1b47c },\n        { -0x24df45f047494801, -0x48cd3c4988aee05f, -0x56d4ae3f660fd277, 0x4f3875ad489ca5f1 }\n    },\n    {\n        { 0x79ed13f6ee73eec0, -0x5a39ad9296eef44f, -0x1b76d73c79fc79f4, 0x722a1446fd7059f5 },\n        { -0x380389d0b6cd54de, 0x7ac0edf72f4c3c1b, 0x5f6b55aa9aa895e8, 0x3680274dad0a0081 },\n        { -0x2f6a6016573077e7, -0x2f566aaf7b8a5664, 0x6eac173320b09cc5, 0x628ecf04331b1095 }\n    },\n    {\n        { -0x64be5307a38b330f, -0x498cce7ef7d9adaf, -0x6636d512ee524eb9, 0x7a47d70d34ecb40f },\n        { -0x67434ee7562f2244, -0x11bb61cbf74b7fd5, -0x78f76dd947594efc, 0x685f349a45c7915d },\n        { 0x60a0c4cbcc43a4f5, 0x775c66ca3677bea9, -0x5e855e8ad0070a13, 0x11ded9020e01fdc0 }\n    },\n    {\n        { 0x471f95b03bea93b7, 0x0552d7d43313abd3, -0x426c8f1d1e81c085, 0x7b120f1db20e5bec },\n        { -0x76f187f6351018fc, -0x78d7d6921cf17394, 0x4c5cd2a392aeb1c9, 0x194263d15771531f },\n        { 0x17d2fb3d86502d7a, -0x4a9b27bbaf596cae, 0x7da962c8a60ed75d, 0x00d0f85b318736aa }\n    },\n    {\n        { -0x598ac3e10289de3f, 0x69c0b4a7445671f5, -0x68e0ad8bfa4dc3ef, 0x387bc74851a8c7cd },\n        { -0x6874ebd188837b03, -0x0bfd9bb8fa573f9e, -0x59852ae41819ed39, 0x2f7b459698dd6a33 },\n        { -0x7e76b4b2b5ad5658, -0x5226c1ed09477cd1, 0x184d8548b61bd638, 0x3f1c62dbd6c9f6cd }\n    },\n    {\n        { 0x3fad3e40148f693d, 0x052656e194eb9a72, 0x2f4dcbfd184f4e2f, 0x406f8db1c482e18b },\n        { 0x2e8f1f0091910c1f, -0x5b20b01f400d1ed4, 0x60c6560aee927438, 0x6338283facefc8fa },\n        { -0x619cf2d380e6e11c, 0x4fbf8301bc3ff670, 0x787d8e4e7afb73c4, 0x50d83d5be8f58fa5 }\n    },\n    {\n        { -0x3f53306f4b2c4993, -0x58fa621a9e8cd1a0, 0x033d1f7870c6b0ba, 0x584161cd26d946e4 },\n        { -0x7a97c6e93ee5e769, 0x2d69a4efe506d008, 0x39af1378f664bd01, 0x65942131361517c6 },\n        { -0x440d4e5f8d2d835e, -0x40c6c3a6042138fc, -0x167244311d9d47e2, 0x02eebd0b3029b589 }\n    },\n},\n{\n    {\n        { -0x789a4960847a3a18, 0x6ff0678bd168bab2, 0x3a70e77c1d330f9b, 0x3a5f6d51b0af8e7c },\n        { 0x61368756a60dac5f, 0x17e02f6aebabdc57, 0x7f193f2d4cce0f7d, 0x20234a7789ecdcf0 },\n        { 0x76d20db67178b252, 0x071c34f9d51ed160, -0x09d5b5df4c1bee90, 0x7cd682353cffe366 }\n    },\n    {\n        { -0x599a329f97530b0d, 0x42d92d183cd7e3d3, 0x5759389d336025d9, 0x3ef0253b2b2cd8ff },\n        { 0x0be1a45bd887fab6, 0x2a846a32ba403b6e, -0x266defed1691a000, 0x2838c8863bdc0943 },\n        { -0x2e944f30b5b9afd0, -0x05b694beea3a8855, -0x7d3051750b54be63, 0x21dcb8a606a82812 }\n    },\n    {\n        { -0x6572ff054188ce46, -0x7dfc9f819d61e777, -0x4d33fdc8bc0c2681, 0x5d840dbf6c6f678b },\n        { 0x5c6004468c9d9fc8, 0x2540096ed42aa3cb, 0x125b4d4c12ee2f9c, 0x0bc3d08194a31dab },\n        { 0x706e380d309fe18b, 0x6eb02da6b9e165c7, 0x57bbba997dae20ab, 0x3a4276232ac196dd }\n    },\n    {\n        { 0x3bf8c172db447ecb, 0x5fcfc41fc6282dbd, -0x7f53003f8a55ea02, 0x0770c9e824e1a9f9 },\n        { 0x4b42432c8a7084fa, -0x7675e61c20461abb, -0x4160ffde63a71ba3, 0x1ff177cea16debd1 },\n        { -0x309e2665ba4a4a03, -0x79f67b16e4c586dc, -0x18cff6e6cfc1c177, 0x39f264fd41500b1e }\n    },\n    {\n        { -0x2e64b55401f6841f, -0x5b92031e201fe6d7, -0x3c36f76bd3590e01, 0x65c621272c35f14e },\n        { -0x5852cbe824181d64, -0x426bc895d463ec64, -0x5f16e4716ca68457, 0x1712d73468889840 },\n        { -0x18d4760731ce6c23, 0x4d103356a125c0bb, 0x0419a93d2e1cfe83, 0x22f9800ab19ce272 }\n    },\n    {\n        { 0x42029fdd9a6efdac, -0x46ed3141cb5ab6bf, 0x640f64b987bdf37b, 0x4171a4d38598cab4 },\n        { 0x605a368a3e9ef8cb, -0x1c163fdd5aafb8eb, 0x553d48b05f24248f, 0x13f416cd647626e5 },\n        { -0x05d8a7556636b374, 0x23006f6fb000b807, -0x042d6e225225ac6e, 0x508214fa574bd1ab }\n    },\n    {\n        { 0x461a15bb53d003d6, -0x4defd777430c369b, 0x27c576756c683a5a, 0x3a7758a4c86cb447 },\n        { -0x3dfd96eac12901b5, -0x59a598c6aee2883c, -0x3421d9b9d3eb506c, 0x22f960ec6faba74b },\n        { 0x548111f693ae5076, 0x1dae21df1dfd54a6, 0x12248c90f3115e65, 0x5d9fd15f8de7f494 }\n    },\n    {\n        { 0x3f244d2aeed7521e, -0x71c56fd7bcd169eb, -0x1e9b4588d163e92c, 0x3bc187fa47eb98d8 },\n        { 0x031408d36d63727f, 0x6a379aefd7c7b533, -0x561e703a33511db5, 0x332f35914f8fbed3 },\n        { 0x6d470115ea86c20c, -0x6675483493b92edb, -0x2887cd4ac599fe78, 0x450d81ce906fba03 }\n    },\n},\n{\n    {\n        { 0x23264d66b2cae0b5, 0x7dbaed33ebca6576, 0x030ebed6f0d24ac8, 0x2a887f78f7635510 },\n        { -0x0751b2d527bac6fe, 0x7018058ee8db2d1d, -0x554c66a0382d3ee2, 0x53b16d2324ccca79 },\n        { 0x2a23b9e75c012d4f, 0x0c974651cae1f2ea, 0x2fb63273675d70ca, 0x0ba7250b864403f5 }\n    },\n    {\n        { -0x229ca76c79079264, 0x61699176e13a85a4, 0x2e5111954eaa7d57, 0x32c21b57fb60bdfb },\n        { -0x44f2e702fd639bdf, -0x43d2ebde76d670fe, -0x7cb8071974daf16a, 0x7b9f2fe8032d71c9 },\n        { -0x2787dc32ce61f880, -0x103b303e76888a3b, 0x4854fb129a0ab3f7, 0x12c49d417238c371 }\n    },\n    {\n        { 0x09b3a01783799542, 0x626dd08faad5ee3f, -0x45ff4311148feb61, 0x1421b246a0a444c9 },\n        { 0x0950b533ffe83769, 0x21861c1d8e1d6bd1, -0x0fdd27c7ecfd1af0, 0x2509200c6391cab4 },\n        { 0x4aa43a8e8c24a7c7, 0x04c1f540d8f05ef5, -0x5245a1f3f4c14624, 0x2ab5504448a49ce3 }\n    },\n    {\n        { -0x23f8539ce3a2c506, 0x58615171f9df8c6c, 0x72a079d89d73e2b0, 0x7301f4ceb4eae15d },\n        { 0x2ed227266f0f5dec, -0x67db11bea12af7dc, -0x7f8413836b972beb, 0x7093bae1b521e23f },\n        { 0x6409e759d6722c41, -0x598b1e308d408d65, -0x43f5db14c3de1a97, 0x390167d24ebacb23 }\n    },\n    {\n        { -0x2844fab45d0dedf5, -0x1d4631514efa7649, 0x3fe8bac8f3c0edbe, 0x4cbd40767112cb69 },\n        { 0x27f58e3bba353f1c, 0x4c47764dbf6a4361, -0x50443b1a91a9d9b0, 0x07db2ee6aae1a45d },\n        { 0x0b603cc029c58176, 0x5988e3825cb15d61, 0x2bb61413dcf0ad8d, 0x7b8eec6c74183287 }\n    },\n    {\n        { 0x32fee570fc386b73, -0x2574febe25c57339, -0x68a002f537697ca7, 0x6ee809a1b132a855 },\n        { -0x1b35bf87d32d8350, -0x25063cdc04169843, -0x4d642cb5752be162, 0x72810497626ede4d },\n        { -0x6bbb44ce030279c6, 0x2fe3690a3e4e48c5, -0x23d637982f7705db, 0x13bd1e38d173292e }\n    },\n    {\n        { 0x223fb5cf1dfac521, 0x325c25316f554450, 0x030b98d7659177ac, 0x1ed018b64f88a4bd },\n        { -0x2cd4b327969eb64b, -0x1aa6c8287e275549, 0x0bcb2127ae122b94, 0x41e86fcfb14099b0 },\n        { 0x3630dfa1b802a6b0, -0x77f078b8bd52c42b, 0x0af90d6ceec5a4d4, 0x746a247a37cdc5d9 }\n    },\n    {\n        { 0x6eccd85278d941ed, 0x2254ae83d22f7843, -0x3add2fd184403249, 0x681e3351bff0e4e2 },\n        { -0x2ace4742d484650a, 0x5005093537fc5b51, 0x232fcf25c593546d, 0x20a365142bb40f49 },\n        { -0x749b4a627cfcb0bb, 0x2f8b71f21fa20efb, 0x69249495ba6550e4, 0x539ef98e45d5472b }\n    },\n},\n{\n    {\n        { -0x2f8b2769e3518bc1, -0x0792e70a11e39c13, -0x68423aa4180b12d7, 0x4cbad279663ab108 },\n        { 0x6e7bb6a1a6205275, -0x55b0de28bec3717d, 0x6f56d155e88f5cb2, 0x2de25d4ba6345be1 },\n        { -0x7f2e6fdb5f28e033, -0x3ada3df504d77508, -0x4e5c68b4a0c59be7, 0x7d7fbcefe2007233 }\n    },\n    {\n        { -0x3283a23a0c3d6f6c, -0x387e5d65d56efa55, -0x7f39e2c9bde3cfa8, 0x4f9cd196dcd8d4d7 },\n        { -0x0510e195d994d7ff, -0x7993973b2a8c60ea, -0x0975d043e4fc89d4, 0x5975435e87b75a8d },\n        { 0x199297d86a7b3768, -0x2f2fa7dbe52e859d, -0x45fd6352a3e3f3e9, 0x7ccdd084387a0307 }\n    },\n    {\n        { -0x64f37be7989f336d, -0x3251ff85e54cd567, -0x577213799df425e8, 0x3593ca848190ca44 },\n        { -0x2359bdd392d9fbe9, -0x51eac2af6b7dbf43, -0x563f3e4b04973989, 0x428bd0ed61d0cf53 },\n        { -0x6dece765a17b6559, -0x2b273cca9a270533, -0x73adaba4ac02442f, 0x27398308da2d63e6 }\n    },\n    {\n        { -0x465ef1b3f58fdbad, 0x0fa25866d57d1bde, -0x0046264a32d82509, 0x572c2945492c33fd },\n        { 0x42c38d28435ed413, -0x42af0c9fcd873337, -0x44f854e58625fc11, 0x269597aebe8c3355 },\n        { -0x388038ba2932cf42, -0x1b20172c1c455105, -0x5dd377cf55a225f4, 0x7f985498c05bca80 }\n    },\n    {\n        { -0x2ca9eaadf0409c9d, 0x08045a45cf4dfba6, -0x113db04378c05f3e, 0x30f2653cd69b12e7 },\n        { 0x3849ce889f0be117, -0x7ffa52e484ab5d78, 0x3da3c39f23fc921c, 0x76c2ec470a31f304 },\n        { -0x75f736c7553ef37b, 0x46179b60db276bcb, -0x56df3fe1f1905390, 0x2f1273f1596473da }\n    },\n    {\n        { 0x30488bd755a70bc0, 0x06d6b5a4f1d442e7, -0x152e596143a69e9e, 0x38ac1997edc5f784 },\n        { 0x4739fc7c8ae01e11, -0x02ad8b6fb5955461, 0x41d98a8287728f2e, 0x5d9e572ad85b69f2 },\n        { 0x0666b517a751b13b, 0x747d06867e9b858c, -0x53533feebab221b7, 0x22dfcd9cbfe9e69c }\n    },\n    {\n        { 0x56ec59b4103be0a1, 0x2ee3baecd259f969, 0x797cb29413f5cd32, 0x0fe9877824cde472 },\n        { -0x72242d1f3cf2f327, -0x527199a05344bccd, -0x7094da73cdd569e1, 0x6b2916c05448c1c7 },\n        { 0x7edb34d10aba913b, 0x4ea3cd822e6dac0e, 0x66083dff6578f815, 0x4c303f307ff00a17 }\n    },\n    {\n        { 0x29fc03580dd94500, -0x132d855b9044136d, 0x130a155fc2e2a7f8, 0x416b151ab706a1d5 },\n        { -0x2cf5c429e84d737b, -0x3a2c8848c688c416, -0x39391873e195a341, 0x0d61b8f78b2ab7c4 },\n        { 0x56a8d7efe9c136b0, -0x42f81a32a71bb4e0, -0x5019d025e4a81f55, 0x191a2af74277e8d2 }\n    },\n},\n{\n    {\n        { 0x09d4b60b2fe09a14, -0x3c7b0f50244e8b82, 0x58e2ea8978b5fd6e, 0x519ef577b5e09b0a },\n        { -0x2aaff6a45490b67b, 0x04f4cd5b4fbfaf1a, -0x6271d12ed5f38ac0, 0x2bc24e04b2212286 },\n        { 0x1863d7d91124cca9, 0x7ac08145b88a708e, 0x2bcd7309857031f5, 0x62337a6e8ab8fae5 }\n    },\n    {\n        { -0x2e54cdb1e4c5ed8d, 0x18947cf181055340, 0x3b5d9567a98c196e, 0x7fa00425802e1e68 },\n        { 0x4bcef17f06ffca16, -0x21f91e2496d51e96, 0x0753702d614f42b0, 0x5f6041b45b9212d0 },\n        { 0x7d531574028c2705, -0x7fce829624f28a02, 0x30fface8ef8c8ddd, 0x7e9de97bb6c3e998 }\n    },\n    {\n        { -0x0ffb419d5db2bf23, -0x45f9a66efbad2be1, -0x7e3ba11e9d5bbdcc, 0x4cb829d8a22266ef },\n        { 0x1558967b9e6585a3, -0x6836631f6716746e, 0x10af149b6eb3adad, 0x42181fe8f4d38cfa },\n        { 0x1dbcaa8407b86681, 0x081f001e8b26753b, 0x3cd7ce6a84048e81, 0x78af11633f25f22c }\n    },\n    {\n        { 0x3241c00e7d65318c, -0x19411a232f179219, 0x118b2dc2fbc08c26, 0x680d04a7fc603dc3 },\n        { -0x7be9142bf4af4544, 0x1508722628208bee, -0x5ceb7050463e3c93, 0x0d07daacd32d7d5d },\n        { -0x063dbeb596a55c15, -0x255bd3b3fa5970df, 0x7c6c23987f93963e, 0x210e8cd30c3954e3 }\n    },\n    {\n        { 0x2b50f16137fe6c26, -0x1efd4327a91bfb28, 0x12b0f1414c561f6b, 0x51b17bc8d028ec91 },\n        { -0x53bdfe0def58e3fa, 0x6a65e0aef3bfb021, -0x43bd3ca3c6c9cd09, 0x56ea8db1865f0742 },\n        { -0x000a04b430acaee7, -0x0b67628620eef760, -0x4203159a65c45cdb, 0x18a11f1174d1a6f2 }\n    },\n    {\n        { -0x0429c3252d85a0d4, -0x0ff03b43755ef929, 0x53fb5c1a8e64a430, 0x04eaabe50c1a2e85 },\n        { 0x407375ab3f6bba29, -0x613c492766e1b7d2, -0x6637f17d1aa06d17, 0x307c13b6fb0c0ae1 },\n        { 0x24751021cb8ab5e7, -0x03dcbbb6a3afef15, 0x5f1e717b4e5610a1, 0x44da5f18c2710cd5 }\n    },\n    {\n        { -0x6ea9019476271534, -0x19486bae1dced95f, -0x428b9c26c6bb14b2, 0x726373f6767203ae },\n        { 0x033cc55ff1b82eb5, -0x4ea51c92bee351ae, -0x45bf49e67004532d, 0x768edce1532e861f },\n        { -0x1cfa358d14810976, 0x662cf31f70eadb23, 0x18f026fdb4c45b68, 0x513b5384b5d2ecbd }\n    },\n    {\n        { 0x5e2702878af34ceb, -0x6ff4fbf646b92952, 0x6512ebf7dabd8512, 0x61d9b76988258f81 },\n        { 0x46d46280c729989e, 0x4b93fbd05368a5dd, 0x63df3f81d1765a89, 0x34cebd64b9a0a223 },\n        { -0x593a58ecb64826b5, -0x5c0c2ea7dc146bba, 0x0416fbd277484834, 0x69d45e6f2c70812f }\n    },\n},\n{\n    {\n        { -0x6019d4bcb0b9f105, -0x212cfc2b59c9f82a, -0x0faddef1485f25dc, 0x237e7dbe00545b93 },\n        { -0x31e908b43ac3ebcf, 0x2b9725ce2072edde, -0x47463c904a4dc119, 0x7e2e0e450b5cc908 },\n        { 0x013575ed6701b430, 0x231094e69f0bfd10, 0x75320f1583e47f22, 0x71afa699b11155e3 }\n    },\n    {\n        { -0x15bdc3e3b8c4af2a, 0x51e87a1f3b38ef10, -0x647b40a04d36416b, 0x00731fbc78f89a1c },\n        { 0x65ce6f9b3953b61d, -0x39a7c615505ebe1a, 0x0f435ffda9f759fe, 0x021142e9c2b1c28e },\n        { -0x1bcf38e7b707e780, -0x4069f3dda1313ee7, -0x49251f7c9445ea1d, 0x4c4d6f3347e15808 }\n    },\n    {\n        { 0x2f0cddfc988f1970, 0x6b916227b0b9f51b, 0x6ec7b6c4779176be, 0x38bf9500a88f9fa8 },\n        { 0x18f7eccfc17d1fc9, 0x6c75f5a651403c14, -0x24218ed40811f321, 0x193fddaaa7e47a22 },\n        { 0x1fd2c93c37e8876f, -0x5d09e1a5e72eb9d4, 0x5080f58239241276, 0x6a6fb99ebf0d4969 }\n    },\n    {\n        { -0x114edd4a491bdc3a, -0x6c628fef0d790072, -0x6f56d57ce230a274, 0x136fda9f42c5eb10 },\n        { 0x6a46c1bb560855eb, 0x2416bb38f893f09d, -0x28e2eec8708e533f, 0x75f76914a31896ea },\n        { -0x06b3204e5cfa422f, 0x0f364b9d9ff82c08, 0x2a87d8a5c3bb588a, 0x022183510be8dcba }\n    },\n    {\n        { -0x62a58efebccf8581, -0x4f9c21613b825ba1, 0x22bbfe52be927ad3, 0x1387c441fd40426c },\n        { 0x4af766385ead2d14, -0x5f71277f3583a7d0, 0x0d13a6e610211e3d, 0x6a071ce17b806c03 },\n        { -0x4a2c3c2e78687508, 0x722b5a3d7f0e4413, 0x0d7b4848bb477ca0, 0x3171b26aaf1edc92 }\n    },\n    {\n        { -0x59f248274d75b82f, -0x5940eb29e88f5b0f, -0x2b5e076cac2242a8, 0x6c514a63344243e9 },\n        { -0x56d0ce6f68a9b358, -0x008447b3dd8a1ee7, 0x4f55fe37a4875150, 0x221fd4873cf0835a },\n        { 0x2322204f3a156341, -0x048c1f1645f5fcd3, -0x031f22b3bef0fcf2, 0x48daa596fb924aaa }\n    },\n    {\n        { 0x14f61d5dc84c9793, -0x66be061c10be7dfa, -0x320a4770cb9d8854, 0x58c837fa0e8a79a9 },\n        { 0x6eca8e665ca59cc7, -0x57b8dab4d1c75360, 0x31afc708d21e17ce, 0x676dd6fccad84af7 },\n        { 0x0cf9688596fc9058, 0x1ddcbbf37b56a01b, -0x233d1882b6ca2996, 0x1c4f73f2c6a57f0a }\n    },\n    {\n        { -0x4c918f910383cb7c, 0x73dfc9b4c3c1cf61, -0x14e2863687e3381b, 0x70459adb7daf675c },\n        { 0x0e7a4fbd305fa0bb, -0x7d62b31fab399c53, -0x0bde3c7cd01cc7b8, 0x795ac80d1bf64c42 },\n        { 0x1b91db4991b42bb3, 0x572696234b02dcca, -0x6020611ae0738724, 0x5fe162848ce21fd3 }\n    },\n},\n{\n    {\n        { 0x315c29c795115389, -0x281f1af879d08b32, 0x0c4a762185927432, 0x72de6c984a25a1e4 },\n        { -0x1d86f551b2f883bf, -0x746c7d8f248b965d, 0x6eb632dc8abd16a2, 0x720814ecaa064b72 },\n        { -0x51654aac40955cf0, 0x050a50a9806d6e1b, -0x6d448bfc5200aec7, 0x0394d27645be618b }\n    },\n    {\n        { -0x0ac69bda4dcaba5c, 0x15a7a27e98fbb296, -0x5493ad439c90227a, 0x79d995a8419334ee },\n        { 0x4d572251857eedf4, -0x1c8db1221e616c3b, -0x758ebdf1f4868fcb, 0x3b3c833687abe743 },\n        { -0x32757159ee6a228b, -0x5afb2757e22657d1, 0x540dca81a35879b6, 0x60dd16a379c86a8a }\n    },\n    {\n        { 0x3501d6f8153e47b8, -0x485698abeb5d09f4, 0x112ee8b6455d9523, 0x4e62a3c18112ea8a },\n        { 0x35a2c8487381e559, 0x596ffea6d78082cb, -0x34688e14245849ad, 0x5a08b5019b4da685 },\n        { -0x372b53fbae95487a, 0x595af3215295b23d, -0x29122dcb24fdcf3f, 0x0929efe8825b41cc }\n    },\n    {\n        { -0x74ce8d4852a99ae3, 0x01581b7a3fabd717, 0x2dc94df6424df6e4, 0x30376e5d2c29284f },\n        { 0x5f0601d1cbd0f2d3, 0x736e412f6132bb7f, -0x7c9fbbcddc722179, 0x1e3a5272f5c0753c },\n        { -0x2d6e72587ea65a64, 0x6bdc1cd93f0713f3, 0x565f7a934acd6590, 0x53daacec4cb4c128 }\n    },\n    {\n        { -0x667ad43c7ad30250, 0x2cc12e9559d6ed0b, 0x70f9e2bf9b5ac27b, 0x4f3b8c117959ae99 },\n        { 0x4ca73bd79cc8a7d6, 0x4d4a738f47e9a9b2, -0x0b340ed6bd0a0200, 0x01a13ff9bdbf0752 },\n        { 0x55b6c9c82ff26412, 0x1ac4a8c91fb667a8, -0x2ad840301488740e, 0x303337da7012a3be }\n    },\n    {\n        { -0x6892c334052d022f, -0x34777c68c859bf58, 0x2ff00c1d6734cb25, 0x269ff4dc789c2d2b },\n        { -0x6aabdddd73e36284, 0x01fac1371a9b340f, 0x7e8d9177925b48d7, 0x53f8ad5661b3e31b },\n        { 0x0c003fbdc08d678d, 0x4d982fa37ead2b17, -0x3f8194324d1a7d0f, 0x296c7291df412a44 }\n    },\n    {\n        { -0x204dcdfa25474a62, 0x465aeaa0c8092250, -0x2ecc3ee7658da2e8, 0x2327370261f117d1 },\n        { 0x7903de2b33daf397, -0x2f00f9e63659db4d, -0x75e2dad4aaa4c1e8, 0x2b6d581c52e0b7c0 },\n        { 0x3d0543d3623e7986, 0x679414c2c278a354, -0x51bc0f338d9e690a, 0x7836c41f8245eaba }\n    },\n    {\n        { -0x359ae17b7fee6c84, -0x394f3b91910be5d8, -0x48fde458a0c072ae, 0x119dff99ead7b9fd },\n        { -0x185dab24b616a57f, 0x5192d5d008b0ad73, 0x4d20e5b1d00afc07, 0x5d55f8012cf25f38 },\n        { 0x43eadfcbf4b31d4d, -0x39afc08beeeb776e, -0x0111973af9f2c4e9, 0x329293b3dd4a0ac8 }\n    },\n},\n{\n    {\n        { 0x2879852d5d7cb208, -0x4721228f97820d19, -0x23f40054de97876f, 0x2b44c043677daa35 },\n        { 0x4e59214fe194961a, 0x49be7dc70d71cd4f, -0x6cff302dc4af0dd3, 0x4789d446fc917232 },\n        { 0x1a1c87ab074eb78e, -0x05392e7166250b99, 0x3eacbbcd484f9067, 0x60c52eef2bb9a4e4 }\n    },\n    {\n        { 0x702bc5c27cae6d11, 0x44c7699b54a48cab, -0x1043bfa945b6d14e, 0x70d77248d9b6676d },\n        { 0x0b5d89bc3bfd8bf1, -0x4f946dc8360caae6, 0x0e4c16b0d53028f5, 0x10bc9c312ccfcaab },\n        { -0x557517b4c13d5fa5, -0x6796610b12e87e20, 0x794513e4708e85d1, 0x63755bd3a976f413 }\n    },\n    {\n        { 0x3dc7101897f1acb7, 0x5dda7d5ec165bbd8, 0x508e5b9c0fa1020f, 0x2763751737c52a56 },\n        { -0x4aa05fc1d52ef7ad, 0x356f75909ee63569, -0x60060e0241964770, 0x0d8cc1c48bc16f84 },\n        { 0x029402d36eb419a9, -0x0f4bb181884b9f5b, -0x30579dcf2bc3b6aa, 0x70c2dd8a7ad166e7 }\n    },\n    {\n        { -0x6e2b6982471281ed, 0x74252f0ad776817a, -0x1bf67d1ff27ada9c, 0x32b8613816a53ce5 },\n        { 0x656194509f6fec0e, -0x11d18156b939ae73, -0x68cc3e0c981f64a4, 0x2e0fac6363948495 },\n        { 0x79e7f7bee448cd64, 0x6ac83a67087886d0, -0x07602b265f1b24d2, 0x4179215c735a4f41 }\n    },\n    {\n        { -0x1b51cc46d79432cc, -0x48108149aa622924, 0x278b141fb3d38e1f, 0x31fa85662241c286 },\n        { -0x738f6b18282312d6, -0x6804753cb82c6390, -0x1ec41fcc56f926fe, 0x700344a30cd99d76 },\n        { -0x507d93bdd1c9dd0c, -0x3edfd67867ccafd3, -0x643e481ed4c76edd, 0x24bb2312a9952489 }\n    },\n    {\n        { 0x41f80c2af5f85c6b, 0x687284c304fa6794, -0x76ba20665c45e453, 0x0d1d2af9ffeb5d16 },\n        { -0x4e5712e8cd21983d, 0x3cb49418461b4948, -0x7142bcbc8930432e, 0x0fee3e871e188008 },\n        { -0x5625755ecd9de121, 0x30b822a159226579, 0x4004197ba79ac193, 0x16acd79718531d76 }\n    },\n    {\n        { -0x36a6393a87784953, -0x6b1e6152a06f0146, 0x16e24e62a342f504, 0x164ed34b18161700 },\n        { 0x72df72af2d9b1d3d, 0x63462a36a432245a, 0x3ecea07916b39637, 0x123e0ef6b9302309 },\n        { 0x487ed94c192fe69a, 0x61ae2cea3a911513, -0x7884092c465b21d9, 0x78da0fc61073f3eb }\n    },\n    {\n        { -0x5d607f0e97f3c56c, 0x71f77e151ae9e7e6, 0x1100f15848017973, 0x054aa4b316b38ddd },\n        { 0x5bf15d28e52bc66a, 0x2c47e31870f01a8e, 0x2419afbc06c28bdd, 0x2d25deeb256b173a },\n        { -0x2037b972e6d98348, 0x0b28789c66e54daf, 0x2aeb1d2a666eec17, 0x134610a6ab7da760 }\n    },\n},\n{\n    {\n        { -0x26ebcf1f23fd73c4, 0x0eb955a85217c771, 0x4b09e1ed2c99a1fa, 0x42881af2bd6a743c },\n        { -0x350aa13d83a64dc1, -0x665112c1eab2fb0e, 0x68441d72e14141f4, 0x140345133932a0a2 },\n        { 0x7bfec69aab5cad3d, -0x3dc1732cb34d3053, 0x685dd14bfb37d6a2, 0x0ad6d64415677a18 }\n    },\n    {\n        { 0x7914892847927e9f, 0x33dad6ef370aa877, 0x1f8f24fa11122703, 0x5265ac2f2adf9592 },\n        { 0x781a439e417becb5, 0x4ac5938cd10e0266, 0x5da385110692ac24, 0x11b065a2ade31233 },\n        { 0x405fdd309afcb346, -0x268dc2bbd719c0ac, -0x6b3fe20fa09a5552, 0x43e4dc3ae14c0809 }\n    },\n    {\n        { -0x1590853c523d395d, -0x2f16d709168e836c, -0x1d2c861529ba150b, 0x46dd8785c51ffbbe },\n        { -0x43ed380e56c75ae9, 0x473028ab3180b2e1, 0x3f78571efbcd254a, 0x74e534426ff6f90f },\n        { 0x709801be375c8898, 0x4b06dab5e3fd8348, 0x75880ced27230714, 0x2b09468fdd2f4c42 }\n    },\n    {\n        { 0x5b97946582ffa02a, -0x25f695ae01570ab7, -0x5f9caec8a0885065, 0x1bcfde61201d1e76 },\n        { -0x6838b61148fe346a, -0x7c0bc72b495c963d, 0x62962b8b9a402cd9, 0x6976c7509888df7b },\n        { 0x4a4a5490246a59a2, -0x29c1422117802270, -0x26bc8398f2dc8e06, 0x69e87308d30f8ed6 }\n    },\n    {\n        { 0x0f80bf028bc80303, 0x6aae16b37a18cefb, -0x22b815b828d3295d, 0x61943588f4ed39aa },\n        { 0x435a8bb15656beb0, -0x07053645b0b2a436, -0x464d873beab73f8b, 0x3eb0ef76e892b622 },\n        { -0x2d91a3c16efc607b, -0x3f161882090cc557, -0x176973aa8ff9956d, 0x3c34d1881faaaddd }\n    },\n    {\n        { -0x42a4f470d0001f27, 0x6aa254103ed24fb9, 0x2ac7d7bcb26821c4, 0x605b394b60dca36a },\n        { 0x3f9d2b5ea09f9ec0, 0x1dab3b6fb623a890, -0x5f645c158d26d93c, 0x374193513fd8b36d },\n        { -0x4b17a91ba562e12e, -0x1017b7899368565e, -0x4efb309be1a11183, 0x2f50b81c88a71c8f }\n    },\n    {\n        { 0x2b552ca0a7da522a, 0x3230b336449b0250, -0x0d3b3a435b466047, 0x7b2c674958074a22 },\n        { 0x31723c61fc6811bb, -0x634bafb79dee7ff1, 0x768933d347995753, 0x3491a53502752fcd },\n        { -0x2aae9a77c12d7321, 0x12d84fd2d362de39, 0x0a874ad3e3378e4f, 0x000d2b1f7c763e74 }\n    },\n    {\n        { -0x69db8873c16b5755, 0x0ad6f3cee9a78bec, -0x6b75387ef28bc3b1, 0x76627935aaecfccc },\n        { 0x3d420811d06d4a67, -0x4103fb7a6f1f001d, -0x078f394842b78422, 0x6e2a7316319afa28 },\n        { 0x56a8ac24d6d59a9f, -0x37248ac1cf690ffa, 0x477f41e68f4c5299, 0x588d851cf6c86114 }\n    },\n},\n{\n    {\n        { -0x32d59a18882e0aeb, 0x548991878faa60f1, -0x4e48c4432543f91b, 0x654878cba97cc9fb },\n        { 0x51138ec78df6b0fe, 0x5397da89e575f51b, 0x09207a1d717af1b9, 0x2102fdba2b20d650 },\n        { -0x69611bfafaa3195f, 0x36bca7681251ad29, 0x3a1af517aa7da415, 0x0ad725db29ecb2ba }\n    },\n    {\n        { -0x013843f364fa907b, 0x537d5268e7f5ffd7, 0x77afc6624312aefa, 0x4f675f5302399fd9 },\n        { -0x23bd984e7cb1dba9, -0x498abb4a8f31e43b, 0x1af07a0bf7d15ed7, 0x4aefcffb71a03650 },\n        { -0x3cd2c9c9fbeae8e2, -0x32d410ee7667b7c5, -0x78f591522f6baef0, 0x0bccbb72a2a86561 }\n    },\n    {\n        { 0x186d5e4c50fe1296, -0x1fc6847d01176082, 0x3bc7f6c5507031b0, 0x6678fd69108f37c2 },\n        { 0x185e962feab1a9c8, -0x791819ca9aeb8233, -0x4f6d1fce44a4920e, 0x4024f0ab59d6b73e },\n        { 0x1586fa31636863c2, 0x07f68c48572d33f2, 0x4f73cc9f789eaefc, 0x2d42e2108ead4701 }\n    },\n    {\n        { 0x21717b0d0f537593, -0x6eb196f4ece1f9b4, 0x1bb687ae752ae09f, 0x420bf3a79b423c6e },\n        { -0x680aecea6b202d65, 0x6155985d313f4c6a, -0x145ec0f8f7baaff0, 0x676b2608b8d2d322 },\n        { -0x7ec7459ae3a4d4b9, -0x798e4913cee4e480, 0x7bff0cb1bc3135b0, 0x745d2ffa9c0cf1e0 }\n    },\n    {\n        { 0x6036df5721d34e6a, -0x4e2477d866844c30, -0x2c3df63c378a9506, 0x06e15be54c1dc839 },\n        { -0x40ada5e1d4363743, -0x15a4d9f7d9b8627f, -0x2aee38f120feaa25, 0x1ae23ceb960cf5d0 },\n        { 0x5b725d871932994a, 0x32351cb5ceb1dab0, 0x7dc41549dab7ca05, 0x58ded861278ec1f7 }\n    },\n    {\n        { 0x2dfb5ba8b6c2c9a8, 0x48eeef8ef52c598c, 0x33809107f12d1573, 0x08ba696b531d5bd8 },\n        { -0x27e8c86c0d993aa4, -0x3736893a33bab1b7, 0x5ce382f8bc26c3a8, 0x2ff39de85485f6f9 },\n        { 0x77ed3eeec3efc57a, 0x04e05517d4ff4811, -0x15c285c00e598e35, 0x120633b4947cfe54 }\n    },\n    {\n        { -0x7d42ceb8b6edeff6, -0x21dc8492819041fa, -0x1ee189e6ee15863a, 0x07433be3cb393bde },\n        { 0x0b94987891610042, 0x4ee7b13cecebfae8, 0x70be739594f0a4c0, 0x35d30a99b4d59185 },\n        { -0x0086bb3fa316680c, 0x575d3de4b05c51a3, 0x583381fd5a76847c, 0x2d873ede7af6da9f }\n    },\n    {\n        { -0x559dfd1eb1a2067f, -0x5df2a6e8afea1e0b, 0x18a275d3bae21d6c, 0x0543618a01600253 },\n        { 0x157a316443373409, -0x054748110b557e27, -0x4f6c01190a59b7fa, 0x2e773654707fa7b6 },\n        { 0x0deabdf4974c23c1, -0x5590f5da6231b96d, 0x04202cb8a29aba2c, 0x4b1443362d07960d }\n    },\n},\n{\n    {\n        { 0x299b1c3f57c5715e, -0x69346d6194979270, 0x3004806447235ab3, 0x2c435c24a44d9fe1 },\n        { 0x47b837f753242cec, 0x256dc48cc04212f2, -0x1ddd04041e26d73b, 0x48ea295bad8a2c07 },\n        { 0x0607c97c80f8833f, 0x0e851578ca25ec5b, 0x54f7450b161ebb6f, 0x7bcb4792a0def80e }\n    },\n    {\n        { 0x1cecd0a0045224c2, 0x757f1b1b69e53952, 0x775b7a925289f681, 0x1b6cc62016736148 },\n        { -0x7b781c2fd438c9a7, 0x4baf8445059979df, -0x2e8368a523529041, 0x57369f0bdefc96b6 },\n        { -0x0e5666fe8a9c7968, 0x353dd1beeeaa60d3, -0x7b6b8eccb3645b78, 0x63fa6e6843ade311 }\n    },\n    {\n        { 0x2195becdd24b5eb7, 0x5e41f18cc0cd44f9, -0x20d7f8bbbe356122, 0x07073b98f35b7d67 },\n        { -0x2ea3dfac9a683e98, -0x608c8bff672d7877, 0x18aee7f13257ba1f, 0x3418bfda07346f14 },\n        { -0x2fc39893b31acf2c, 0x0b64c0473b5df9f4, 0x065cef8b19b3a31e, 0x3084d661533102c9 }\n    },\n    {\n        { -0x6593178989fcde03, 0x7fe2b5109eb63ad8, 0x00e7d4ae8ac80592, 0x73d86b7abb6f723a },\n        { -0x1e094861407b9653, 0x15801004e2663135, -0x65b67ccf508be7e5, 0x3ba2504f049b673c },\n        { 0x0b52b5606dba5ab6, -0x56ecb0f0444e1255, 0x30a9520d9b04a635, 0x6813b8f37973e5db }\n    },\n    {\n        { -0x0e6b35a90cea81d7, 0x136d35705ef528a5, -0x22b3108874fa6644, 0x7d5472af24f833ed },\n        { -0x67ab4fabccbed83f, 0x105d047882fbff25, -0x24b60806bbe790b1, 0x1768e838bed0b900 },\n        { -0x2f1078b250cc25b9, 0x00d3be5db6e339f9, 0x3f2a8a2f9c9ceece, 0x5d1aeb792352435a }\n    },\n    {\n        { 0x12c7bfaeb61ba775, -0x47b19de01d9c4003, 0x0b47a5c35c840dcf, 0x7e83be0bccaf8634 },\n        { -0x0a61944ce6329c36, 0x670c159221d06839, -0x4f92a9a4deaf354a, 0x20fb199d104f12a3 },\n        { 0x61943dee6d99c120, -0x79efe0d1b9f46020, 0x6bb2f1518ee8598d, 0x76b76289fcc475cc }\n    },\n    {\n        { 0x4245f1a1522ec0b3, 0x558785b22a75656d, 0x1d485a2548a1b3c0, 0x60959eccd58fe09f },\n        { 0x791b4cc1756286fa, -0x24312ce828b5ea84, 0x7e732421ea72bde6, 0x01fe18491131c8e9 },\n        { 0x3ebfeb7ba8ed7a09, 0x49fdc2bbe502789c, 0x44ebce5d3c119428, 0x35e1eb55be947f4a }\n    },\n    {\n        { 0x14fd6dfa726ccc74, 0x3b084cfe2f53b965, -0x0cc51b0aad5d374c, 0x59aab07a0d40166a },\n        { -0x242518fe3a8c722d, -0x063909ca4d90e412, 0x61e96a8042f15ef4, 0x3aa1d11faf60a4d8 },\n        { 0x77bcec4c925eac25, 0x1848718460137738, 0x5b374337fea9f451, 0x1865e78ec8e6aa46 }\n    },\n},\n{\n    {\n        { -0x6983ab16e3ad6335, 0x30f6269264c635fb, 0x2747aff478121965, 0x17038418eaf66f5c },\n        { -0x333b48384991e086, 0x44157e25f50c2f7e, 0x3ef06dfc713eaf1c, 0x582f446752da63f7 },\n        { -0x39ce842cdfcdb31c, -0x57efbd175bb7743c, -0x4de10e74b1a5ec9c, 0x0c2a1c4bcda28dc9 }\n    },\n    {\n        { -0x123b7eb7964296bb, 0x0d6d907dbe1c8d22, -0x39c42ded2aa33a55, 0x5a6a9b30a314dc83 },\n        { -0x2db2382f90e0fbb9, -0x4dd961c124783fa7, -0x2ea4fd8d044d2d71, 0x7c558bd1c6f64877 },\n        { -0x2f13eadb2c69b9c3, 0x12bb628ac35a24f0, -0x5af3c586e343a05c, 0x0404a5ca0afbafc3 }\n    },\n    {\n        { 0x62bc9e1b2a416fd1, -0x4a3908d71cafa675, 0x04343fd83d5d6967, 0x39527516e7f8ee98 },\n        { -0x73e0bff8f558bc2a, -0x33452f34a4d9a118, 0x574b046b668fd2de, 0x46395bfdcadd9633 },\n        { 0x117fdb2d1a5d9a9c, -0x6388ba432effa3d6, -0x102b410eab2a9016, 0x76579a29e822d016 }\n    },\n    {\n        { 0x333cb51352b434f2, -0x27cdd7b66c217f1f, -0x4aaed7788af2ca32, 0x02c514bb2a2777c1 },\n        { 0x45b68e7e49c02a17, 0x23cd51a2bca9a37f, 0x3ed65f11ec224c1b, 0x43a384dc9e05bdb1 },\n        { 0x684bd5da8bf1b645, -0x04742c81094ab4ad, 0x313916d7a9b0d253, 0x1160920961548059 }\n    },\n    {\n        { 0x7a385616369b4dcd, 0x75c02ca7655c3563, 0x7dc21bf9d4f18021, 0x2f637d7491e6e042 },\n        { -0x4bb2e996d6253056, -0x25ad60b37beca671, -0x16109c35bac2aaa7, 0x351e125bc5698e0b },\n        { -0x2b4b64b9e5098442, -0x29fcfc853754769f, 0x71dee19ff9a699fb, 0x7f182d06e7ce2a9a }\n    },\n    {\n        { 0x09454b728e217522, -0x55a7170b2b7b4728, -0x2ca7dab280b96fc4, 0x44acc043241c5217 },\n        { 0x7a7c8e64ab0168ec, -0x34a5b5aaea123abd, 0x095519d347cd0eda, 0x67d4ac8c343e93b0 },\n        { 0x1c7d6bbb4f7a5777, -0x74ca012b6e7cec1f, 0x4adca1c6c96b4684, 0x556d1c8312ad71bd }\n    },\n    {\n        { -0x7e0f98a94ee417df, 0x0faff82310a3f3dd, -0x074d2faa9566b9a3, 0x097abe38cc8c7f05 },\n        { 0x17ef40e30c8d3982, 0x31f7073e15a3fa34, 0x4f21f3cb0773646e, 0x746c6c6d1d824eff },\n        { 0x0c49c9877ea52da4, 0x4c4369559bdc1d43, 0x022c3809f7ccebd2, 0x577e14a34bee84bd }\n    },\n    {\n        { -0x6b01314142b228d5, -0x0b95b025f9f0ddef, 0x124a5977c0c8d1ff, 0x705304b8fb009295 },\n        { -0x0f1d97539e58c4f6, -0x0d0505efc86e5a0b, -0x3e1ec17d9492ff17, 0x60fa7ee96fd78f42 },\n        { -0x49c2e2cab2d6913a, -0x0c3cfac1a052ce28, 0x670b958cb4bd42ec, 0x21398e0ca16353fd }\n    },\n},\n{\n    {\n        { -0x793a03e979e48166, -0x095ccfb895d83baf, 0x01667267a1e93597, 0x05ffb9cd6082dfeb },\n        { 0x216ab2ca8da7d2ef, 0x366ad9dd99f42827, -0x519b46ffb022c38b, 0x403a395b53909e62 },\n        { -0x59e805600ac09ec7, 0x60f2b5e513e66cb6, -0x285741104cbb755c, 0x7a2932856f5ea192 }\n    },\n    {\n        { -0x4763bbb7869c6cfe, 0x4ae4f19350c67f2c, -0x0f4ca25737e5063a, 0x39d0003546871017 },\n        { 0x0b39d761b02de888, 0x5f550e7ed2414e1f, -0x59405ba7dd1e56c0, 0x050a2f7dfd447b99 },\n        { 0x437c3b33a650db77, 0x6bafe81dbac52bb2, -0x0166bfd2d2482ce8, 0x2b5b7eec372ba6ce }\n    },\n    {\n        { -0x596bbfb29ec5370c, 0x500c3c2bfa97e72c, -0x78befb2de0313df0, 0x1b205fb38604a8ee },\n        { -0x4c43b4427c0af111, 0x508f0c998c927866, 0x43e76587c8b7e66e, 0x0f7655a3a47f98d9 },\n        { 0x55ecad37d24b133c, 0x441e147d6038c90b, 0x656683a1d62c6fee, 0x0157d5dc87e0ecae }\n    },\n    {\n        { -0x6ad9aaeb28e14adc, -0x19fc277ea20eba6d, 0x147cdf410d4de6b7, 0x5293b1730437c850 },\n        { -0x0d5850aefcab3ec3, -0x285f4eba55c8d4a0, 0x2869b96a05a3d470, 0x6528e42d82460173 },\n        { 0x23d0e0814bccf226, -0x6d38ba327e69046d, -0x749e8693a6abe1a5, 0x40a44df0c021f978 }\n    },\n    {\n        { -0x793691aeb43a2f6b, -0x0df2bf6703597fb6, 0x27363d89c826ea5d, 0x39ca36565719cacf },\n        { -0x25579676b0df1596, -0x15eb5c2eb39df9e8, 0x6001fccb090bf8be, 0x35f4e822947e9cf0 },\n        { -0x68af90d0907848a4, -0x39db515ffcb51f90, 0x1ec856e3aad34dd6, 0x055b0be0e440e58f }\n    },\n    {\n        { 0x4d12a04b6ea33da2, 0x57cf4c15e36126dd, -0x6f13698a11bb2699, 0x64ca348d2a985aac },\n        { 0x6469a17d89735d12, -0x2490d82a199d460f, -0x60345cd795c6a97f, 0x363b8004d269af25 },\n        { -0x66a771e61b3b6ed3, -0x1033c4b1e35a3195, 0x4522ea60fa5b98d5, 0x7064bbab1de4a819 }\n    },\n    {\n        { -0x5d6f3f9ebdabded7, -0x0d1d3d514172a470, -0x30dba724895401e5, 0x02157ade83d626bf },\n        { -0x46e61eaea588f9bf, -0x565d1d38b1807fc7, 0x7527250b3df23109, 0x756a7330ac27b78b },\n        { 0x3e46972a1b9a038b, 0x2e4ee66a7ee03fb4, -0x7e5db78891244b36, 0x1a944ee88ecd0563 }\n    },\n    {\n        { -0x44bf57a6e7dc9d2a, -0x4660aa8875b2e545, -0x72e74bd88a7aa60a, 0x26c20fe74d26235a },\n        { -0x2a56e2eeaefc6c8e, 0x2ed377b799ca26de, -0x5e8dfd5302c99495, 0x0730291bd6901995 },\n        { 0x648d1d9fe9cc22f5, 0x66bc561928dd577c, 0x47d3ed21652439d1, 0x49d271acedaf8b49 }\n    },\n},\n{\n    {\n        { 0x2798aaf9b4b75601, 0x5eac72135c8dad72, -0x2d31559e9e485fdd, 0x1bbfb284e98f7d4e },\n        { -0x760afa75c7d4cc0d, 0x5ae2ba0bad48c0b4, -0x706c4afc5ac24c92, 0x5aa3ed9d95a232e6 },\n        { 0x656777e9c7d96561, -0x34d4edab8d387fca, 0x65053299d9506eee, 0x4a07e14e5e8957cc }\n    },\n    {\n        { 0x240b58cdc477a49b, -0x02c725219bb80fe9, 0x19928d32a7c86aad, 0x50af7aed84afa081 },\n        { 0x4ee412cb980df999, -0x5cea2890c391388f, -0x445a12216da38803, 0x3f0bac391d313402 },\n        { 0x6e4fde0115f65be5, 0x29982621216109b2, 0x780205810badd6d9, 0x1921a316baebd006 }\n    },\n    {\n        { -0x28a55265260c3e75, 0x566a0eef60b1c19c, 0x3e9a0bac255c0ed9, 0x7b049deca062c7f5 },\n        { -0x76bdd08120478f04, 0x2c296beb4f76b3bd, 0x0738f1d436c24df7, 0x6458df41e273aeb0 },\n        { -0x23341c85cabbbb7d, 0x758879330fedbe93, 0x786004c312c5dd87, 0x6093dccbc2950e64 }\n    },\n    {\n        { 0x6bdeeebe6084034b, 0x3199c2b6780fb854, -0x68cc895449d2f96b, 0x6e3180c98b647d90 },\n        { 0x1ff39a8585e0706d, 0x36d0a5d8b3e73933, 0x43b9f2e1718f453b, 0x57d1ea084827a97c },\n        { -0x118549185ed74f8f, -0x5b3ea6926c577456, -0x084b217d4dde9ed0, 0x363e999ddd97bd18 }\n    },\n    {\n        { 0x2f1848dce24baec6, 0x769b7255babcaf60, -0x6f34c391c31016cf, 0x231f979bc6f9b355 },\n        { -0x6957bc3eca11e03c, -0x68914caaf71b3731, -0x4bd097fe4a732cd0, 0x48ee9b78693a052b },\n        { 0x5c31de4bcc2af3c6, -0x4fb44fcf01df72e1, -0x48728ff63eb04b9a, 0x079bfa9b08792413 }\n    },\n    {\n        { -0x0c36127f5d2abdbb, 0x0aa08b7877f63952, -0x2892539c2ef7ab8b, 0x1ef4fb159470636b },\n        { -0x1c6fc5ae25cff20c, -0x7bc69bdcc256a550, -0x12c30ed2f4ca9b80, 0x038c77f684817194 },\n        { -0x7ab1a119a4e98414, 0x59590a4296d0cdc2, 0x72b2df3498102199, 0x575ee92a4a0bff56 }\n    },\n    {\n        { 0x5d46bc450aa4d801, -0x3c50edd85acc4628, 0x389e3b262b8906c2, 0x200a1e7e382f581b },\n        { -0x2b3f7f6f75e7d031, 0x30e170c299489dbd, 0x05babd5752f733de, 0x43d4e7112cd3fd00 },\n        { 0x518db967eaf93ac5, 0x71bc989b056652c0, -0x01d47a26a98e680b, 0x050eca52651e4e38 }\n    },\n    {\n        { -0x6853c6899f199716, -0x64e64401eac54b69, 0x4cb179b534eca79f, 0x6151c09fa131ae57 },\n        { -0x3cbce521bac0f364, -0x160afba1008fc465, -0x03268536127b84c3, 0x4b0ee6c21c58f4c6 },\n        { 0x3af55c0dfdf05d96, -0x22d9d11fd54b1186, 0x11b2bb8712171709, 0x1fef24fa800f030b }\n    },\n},\n{\n    {\n        { -0x006e59956fe99de0, -0x0ddaad51a40e1ff7, 0x7dff85d87f90df7c, 0x4f620ffe0c736fb9 },\n        { -0x4b69edc5949399f7, -0x58af017a7f54a6c8, -0x0b8e40c6483d85a1, 0x507903ce77ac193c },\n        { 0x62f90d65dfde3e34, -0x30d73a6d4605a053, -0x6637910639e9baf0, 0x25d448044a256c84 }\n    },\n    {\n        { 0x2c7c4415c9022b55, 0x56a0d241812eb1fe, -0x0fd15e362849a1f3, 0x4180512fd5323b26 },\n        { -0x4297dcf138164e91, 0x0eb1b9c1c1c5795d, 0x7943c8c495b6b1ff, 0x2f9faf620bbacf5e },\n        { -0x5b00c19675b75a25, -0x4595c7f9426abfc5, -0x60831e50b82a49a3, 0x15e087e55939d2fb }\n    },\n    {\n        { -0x776be7910469c0c8, 0x48a00e80dc639bd5, -0x5b17f6d41693e367, 0x5a097d54ca573661 },\n        { 0x12207543745c1496, -0x2500c30225c79ef4, -0x1b1868d8d38e3cb1, 0x39c07b1934bdede9 },\n        { 0x2d45892b17c9e755, -0x2fcc028d76cf7208, 0x6c2fe9d9525b8bd9, 0x2edbecf1c11cc079 }\n    },\n    {\n        { -0x11f0f0222f785da1, -0x638aceaaa3c1cb12, 0x660c572e8fab3ab5, 0x0854fc44544cd3b2 },\n        { 0x1616a4e3c715a0d2, 0x53623cb0f8341d4d, -0x6910acd638176635, 0x3d4e8dbba668baa6 },\n        { 0x61eba0c555edad19, 0x24b533fef0a83de6, 0x3b77042883baa5f8, 0x678f82b898a47e8d }\n    },\n    {\n        { 0x1e09d94057775696, -0x112ed9a3c326ae25, -0x056253d4df431e91, 0x0f7f76e0e8d089f4 },\n        { -0x4eb6e2f4296ff3ac, 0x3539722c9d132636, 0x4db928920b362bc9, 0x4d7cd1fea68b69df },\n        { 0x36d9ebc5d485b00c, -0x5da69b6d1b524c9b, -0x3e9a6b7f3dee6333, 0x45306349186e0d5f }\n    },\n    {\n        { -0x695beb13d4f8db6f, 0x1bb2218127a7b65b, 0x6d2849596e8a4af0, 0x65f3b08ccd27765f },\n        { -0x6b222f3e593200e3, 0x55f6f115e84213ae, 0x6c935f85992fcf6a, 0x067ee0f54a37f16f },\n        { -0x134d6000e667fe09, -0x62c9e2e05d5f08d1, 0x25f11d2375fd2f49, 0x124cefe80fe10fe2 }\n    },\n    {\n        { 0x1518e85b31b16489, -0x70552348248ef405, 0x39b0bdf4a14ae239, 0x05f4cbea503d20c1 },\n        { 0x4c126cf9d18df255, -0x3e2b8e16eb859c4a, 0x2c6d3c73f3c93b5f, 0x6be3a6a2e3ff86a2 },\n        { -0x31fbf1613fbeba44, -0x38e00b1df7097cb4, -0x42ab91725477b85d, 0x64666aa0a4d2aba5 }\n    },\n    {\n        { -0x4f3ac408ccc816b4, 0x7cb5697e11e14f15, 0x4b84abac1930c750, 0x28dd4abfe0640468 },\n        { 0x6841435a7c06d912, -0x35edc3de44c07cf5, -0x2b4c84d84e341d88, 0x1d753b84c76f5046 },\n        { 0x7dc0b64c44cb9f44, 0x18a3e1ace3925dbf, 0x7a3034862d0457c4, 0x4c498bf78a0c892e }\n    },\n},\n{\n    {\n        { 0x22d2aff530976b86, -0x726f47f93d2db9fc, -0x235e7693b21a451b, 0x28005fe6c8340c17 },\n        { 0x37d653fb1aa73196, 0x0f9495303fd76418, -0x52dff4f604c5e84e, 0x544d49292fc8613e },\n        { 0x6aefba9f34528688, 0x5c1bff9425107da1, -0x08a444329926b4ca, 0x72e472930f316dfa }\n    },\n    {\n        { 0x07f3f635d32a7627, 0x7aaa4d865f6566f0, 0x3c85e79728d04450, 0x1fee7f000fe06438 },\n        { 0x2695208c9781084f, -0x4eafd5f4dcbaf11f, -0x02625159fc1021fe, 0x5a9d2e8c2733a34c },\n        { 0x765305da03dbf7e5, -0x5b250db6ebcb3243, 0x7b4ad5cdd24a88ec, 0x00f94051ee040543 }\n    },\n    {\n        { -0x28106c44f85068ad, 0x583ed0cf3db766a7, -0x3196674091f4e13b, 0x47b7ffd25dd40452 },\n        { -0x72ca94dc3c2ccf4e, -0x0de374644fb8e4fa, -0x4c93ce9391bd47c4, 0x07d79c7e8beab10d },\n        { -0x7804046343f722ee, -0x75f994c51e113d65, 0x0d57242bdb1fc1bf, 0x1c3520a35ea64bb6 }\n    },\n    {\n        { -0x325790bfde943fa7, 0x1fbb231d12bcd87e, -0x4b6a9561e838f670, 0x38750c3b66d12e55 },\n        { -0x7f2dac5943345cb6, 0x3e61c3a13838219b, -0x6f3c49fe677d1c6a, 0x1c3d05775d0ee66f },\n        { 0x692ef1409422e51a, -0x343f38c3d4a2098f, 0x21014fe7744ce029, 0x0621e2c7d330487c }\n    },\n    {\n        { -0x4851e8694f240f0d, 0x54dfafb9e17ce196, 0x25923071e9aaa3b4, 0x5d8e589ca1002e9d },\n        { -0x50679f337da67c73, -0x6f15b73e39606524, 0x6526483765581e30, 0x0007d6097bd3a5bc },\n        { -0x3f40e26af7bd56b5, -0x4d2c3c9ca770d1c2, 0x0a961438bb51e2ef, 0x1583d7783c1cbf86 }\n    },\n    {\n        { -0x6ffcb8fb3362d739, 0x1d1b679ef72cc58f, 0x16e12b5fbe5b8726, 0x4958064e83c5580a },\n        { -0x13115d10a25d851f, 0x597c3a1455670174, -0x3659d5ed99f6e986, 0x252a5f2e81ed8f70 },\n        { 0x0d2894265066e80d, -0x033c087acf837395, 0x1b53da780c1112fd, 0x079c170bd843b388 }\n    },\n    {\n        { -0x322932af3f2a2faa, -0x6508979244fca8c5, 0x3ca6723ff3c3ef48, 0x6768c0d7317b8acc },\n        { 0x0506ece464fa6fff, -0x411cbce19dfa1add, 0x3579422451b8ea42, 0x6dec05e34ac9fb00 },\n        { -0x6b49da1a0eaa3e4d, 0x417bf3a7997b7b91, -0x3dd342239294da00, 0x51445e14ddcd52f4 }\n    },\n    {\n        { -0x76ceb854d4415bab, -0x73ac5db06df86ed7, 0x4b49f948be30f7a7, 0x12e990086e4fd43d },\n        { 0x57502b4b3b144951, -0x71980094bbb4434d, -0x474296d8e99c7a25, 0x13186f31e39295c8 },\n        { -0x0ef3694c802044d2, -0x60656ca1ede31507, -0x20eec93bc5a467c1, 0x77b2e3f05d3e99af }\n    },\n},\n{\n    {\n        { -0x6acd0b7033a32d65, 0x2ba851bea3ce3671, 0x32dacaa051122941, 0x478d99d9350004f2 },\n        { -0x02f28a78630ed9a9, -0x17d0106b1ac5f1d7, -0x33cb580fa444b419, 0x0b251172a50c38a2 },\n        { 0x1d5ad94890bb02c0, 0x50e208b10ec25115, -0x5d95dd76b10de8fe, 0x4dc923343b524805 }\n    },\n    {\n        { 0x3ad3e3ebf36c4975, -0x28a2da5ac879dedb, -0x178c6bc25fda5aea, 0x6bbc7cb4c411c847 },\n        { -0x1c7d73bff07f794a, 0x3f77e6f7979f0dc8, 0x7ef6de304df42cb4, 0x5265797cb6abd784 },\n        { 0x3c6f9cd1d4a50d56, -0x49dbbf8839015482, 0x6ff9bf483580972e, 0x00375883b332acfb }\n    },\n    {\n        { -0x3674137a938a3664, -0x1bbe7b3fff1cc30c, 0x0a676b9bba907634, 0x669e2cb571f379d7 },\n        { 0x0001b2cd28cb0940, 0x63fb51a06f1c24c9, -0x4a52796e232a35cf, 0x67238dbd8c450660 },\n        { -0x34ee948c5b642cf8, 0x025aad6b2392729e, -0x4b86c105c0aa264f, 0x72a1056140678bb9 }\n    },\n    {\n        { 0x0d8d2909e2e505b6, -0x673587543fd6edd0, 0x77ef5569a9b12327, 0x7c77897b81439b47 },\n        { -0x5d497ed4e336db63, 0x62866eee21211f58, 0x2cb5c5b85df10ece, 0x03a6b259e263ae00 },\n        { -0x0e3e4a1d21cce34b, 0x5a9f5d8e15fca420, -0x605bc70e8426cd4f, 0x2a381bf01c6146e7 }\n    },\n    {\n        { -0x083f41cd4acbe991, 0x27e6ca6419cf70d4, -0x6cb2082856a858a7, 0x5701461dabdec2aa },\n        { -0x536467863037ee3f, -0x7482d67ec8a91a99, 0x50da4e607c70edfc, 0x5dbca62f884400b6 },\n        { 0x2c6747402c915c25, 0x1bdcd1a80b0d340a, 0x5e5601bd07b43f5f, 0x2555b4e05539a242 }\n    },\n    {\n        { 0x78409b1d87e463d4, -0x52b256a532049c63, -0x13d788c8aada6464, 0x69c806e9c31230ab },\n        { 0x6fc09f5266ddd216, -0x231a9f58371c8fb8, -0x139a6c625d209d03, 0x7a869ae7e52ed192 },\n        { 0x7b48f57414bb3f22, 0x68c7cee4aedccc88, -0x12d06c9e86127f42, 0x25d70b885f77bc4b }\n    },\n    {\n        { -0x67ba62d644e51b2c, 0x56b9c4c739f954ec, -0x7cd8bc093d64b4c2, 0x21ea8e2798b6878a },\n        { 0x4151c3d9762bf4de, 0x083f435f2745d82b, 0x29775a2e0d23ddd5, 0x138e3a6269a5db24 },\n        { -0x78410b4b95a58464, -0x2dd662e4a03e2f9e, -0x7dbf67e722cde9b8, 0x5c5abeb1e5a2e03d }\n    },\n    {\n        { 0x02cde6de1306a233, 0x7b5a52a2116f8ec7, -0x1e397e0b3ee9c4a5, 0x241d350660d32643 },\n        { 0x14722af4b73c2ddb, -0x43b8f3a0a5faf9f3, 0x00943eac2581b02e, 0x0e434b3b1f499c8f },\n        { 0x6be4404d0ebc52c7, -0x51b9dcc44e586e0b, 0x2aec170ed25db42b, 0x1d8dfd966645d694 }\n    },\n},\n{\n    {\n        { -0x2a679c63ed224f5c, -0x5a2e60cf3fdb7995, -0x2e83d0fca7031ba0, 0x07a195152e095e8a },\n        { 0x296fa9c59c2ec4de, -0x43749e40b07b0c35, 0x1c7706d917a8f908, 0x63b795fc7ad3255d },\n        { -0x57c970fdc761a038, -0x6fbcc4fd30721bc5, -0x505e02a23abed9bd, 0x3e8fe83d032f0137 }\n    },\n    {\n        { 0x08704c8de8efd13c, -0x203ae571cc1fc8cf, -0x5a62a25aed9f321d, 0x22d60899a6258c86 },\n        { 0x2f8b15b90570a294, -0x6b0dbd8f98f7bab7, -0x21e3a51e9e44027c, 0x75ba3b797fac4007 },\n        { 0x6239dbc070cdd196, 0x60fe8a8b6c7d8a9a, -0x4c77b84314bfeda0, 0x0904d07b87779e5e }\n    },\n    {\n        { -0x0bcdd299b706bf47, 0x06952f0cbd2d0c39, 0x167697ada081f931, 0x6240aacebaf72a6c },\n        { -0x4b31e02b22456e64, -0x30ce24c138b37256, 0x2c63cc63ad86cc51, 0x43e2143fbc1dde07 },\n        { -0x07cb8b63a45d6a60, -0x296b83a435c82da6, 0x66f13ba7e7c9316a, 0x56bdaf238db40cac }\n    },\n    {\n        { 0x1310d36cc19d3bb2, 0x062a6bb7622386b9, 0x7c9b8591d7a14f5c, 0x03aa31507e1e5754 },\n        { 0x362ab9e3f53533eb, 0x338568d56eb93d40, -0x61f1ebade2a5aa8e, 0x1d24a86d83741318 },\n        { -0x0b1389b7002b31e1, -0x1fba150fab5373e4, -0x772dda7de2f6ca84, 0x43b261dc9aeb4859 }\n    },\n    {\n        { 0x19513d8b6c951364, -0x6b018ed9fff40b85, 0x028d10ddd54f9567, 0x02b4d5e242940964 },\n        { -0x1aa4e1e677448645, -0x5f612f823e85ca63, -0x4fd3d11d9fc215cd, 0x326055cf5b276bc2 },\n        { -0x4b5eaa34d72e720e, -0x1533b9b9e7931af8, -0x3b630b6c937dbc77, 0x27a6c809ae5d3410 }\n    },\n    {\n        { -0x32d3d8f53bc296ac, -0x22b5c1a89599354e, 0x79fa592469d7036c, 0x221503603d8c2599 },\n        { -0x74591432e0f24e78, 0x37d3d73a675a5be8, -0x0dd1205cea0aa7a6, 0x2cb67174ff60a17e },\n        { 0x59eecdf9390be1d0, -0x56bddfbb8d731c0f, -0x7d76e399856b0f0c, 0x7b1df4b73890f436 }\n    },\n    {\n        { 0x5f2e221807f8f58c, -0x1caaa3602b6bf62c, -0x4d555772e04959d0, 0x68698245d352e03d },\n        { -0x1b6d0d1f4c4d5ddc, 0x7c6c9e062b551160, 0x15eb8fe20d7f7b0e, 0x61fcef2658fc5992 },\n        { -0x244ea27ad5e7e786, -0x0c1b552c79225329, 0x44bae2810ff6c482, 0x46cf4c473daf01cf }\n    },\n    {\n        { 0x213c6ea7f1498140, 0x7c1e7ef8392b4854, 0x2488c38c5629ceba, 0x1065aae50d8cc5bb },\n        { 0x426525ed9ec4e5f9, 0x0e5eda0116903303, 0x72b1a7f2cbe5cadc, 0x29387bcd14eb5f40 },\n        { 0x1c2c4525df200d57, 0x5c3b2dd6bfca674a, 0x0a07e7b1e1834030, 0x69a198e64f1ce716 }\n    },\n},\n{\n    {\n        { 0x7b26e56b9e2d4734, -0x3b38ecd47e39e98b, -0x10a36ada13632181, 0x39c80b16e71743ad },\n        { 0x7afcd613efa9d697, 0x0cc45aa41c067959, -0x5a901efb3e05256a, 0x3a73b70472e40365 },\n        { 0x0f196e0d1b826c68, -0x08e00f1db69f1c25, 0x6113167023b7436c, 0x0cf0ea5877da7282 }\n    },\n    {\n        { -0x1ccd312bc4596ba6, -0x21f4ec9e177e3fa3, 0x1ad40f095e67ed3b, 0x5da8acdab8c63d5d },\n        { 0x196c80a4ddd4ccbd, 0x22e6f55d95f2dd9d, -0x38a1cc38bf2938e5, 0x7bb51279cb3c042f },\n        { -0x3b4999b5c58fea61, 0x76194f0f0a904e14, -0x5a9eb3c65bf693ed, 0x6cd0ff50979feced }\n    },\n    {\n        { 0x7fecfabdb04ba18e, -0x2f038403c4224309, -0x5be2b791fa85ece4, 0x641a4391f2223a61 },\n        { -0x3f1f981870bbd754, 0x14835ab0a61135e3, -0x0de2eb0cc7f9d6cb, 0x6390a4c8df04849c },\n        { -0x3a3946a559f95725, -0x6eb480614f97da0f, 0x2a731f6b44fc9eff, 0x30ddf38562705cfc }\n    },\n    {\n        { 0x33bef2bd68bcd52c, -0x39b6244f96b7d10e, -0x4a4911f3be34e512, 0x5c294d270212a7e5 },\n        { 0x4e3dcbdad1bff7f9, -0x36ee717ddf9ba8e9, -0x45333143f0e762aa, 0x1b4822e9d4467668 },\n        { -0x54c9f580daa9c87f, 0x2512228a480f7958, -0x38a2fad89eeb4b1d, 0x222d9625d976fe2a }\n    },\n    {\n        { 0x0f94be7e0a344f85, -0x14d05573780dd3c8, -0x631e18a1b11e90f1, 0x43e64e5418a08dea },\n        { 0x1c717f85b372ace1, -0x7e6cf196b9c740e8, 0x239cad056bc08b58, 0x0b34271c87f8fff4 },\n        { -0x7eaa1dade5ca319d, -0x41eff2b206edfd72, -0x4007f4075a822314, 0x57342dc96d6bc6e4 }\n    },\n    {\n        { -0x0c3c4348e18f840a, 0x351d9b8c7291a762, 0x00502e6edad69a33, 0x522f521f1ec8807f },\n        { -0x10110f9a3731a668, -0x40fd6aef4a34155e, -0x739b5ef9df483ba8, 0x35134fb231c24855 },\n        { 0x272c1f46f9a3902b, -0x36e45c48669a8434, -0x519eb4cfb075e3f2, 0x7afcaad70b99017b }\n    },\n    {\n        { -0x577ebe13107bd495, 0x55e7b14797abe6c5, -0x738b7068fc87b002, 0x5b50a1f7afcd00b7 },\n        { -0x3da212ab5b4741bf, -0x6fd2ec1ee44f1d23, 0x41f43233cde82ab2, 0x1085faa5c3aae7cb },\n        { -0x647bf0990ec9eceb, 0x18462242701003e9, 0x65ed45fae4a25080, 0x0a2862393fda7320 }\n    },\n    {\n        { -0x69f18c84913462e9, -0x050db6b72983151f, 0x37e7a9b4d55e1b89, 0x5cb7173cb46c59eb },\n        { 0x46ab13c8347cbc9d, 0x3849e8d499c12383, 0x4cea314087d64ac9, 0x1f354134b1a29ee7 },\n        { 0x4a89e68b82b7abf0, -0x0be326d864594847, 0x16e6c210e18d876f, 0x7cacdb0f7f1b09c6 }\n    },\n},\n{\n    {\n        { -0x1efebbcb233a3513, 0x47ed5d963c84fb33, 0x70019576ed86a0e7, 0x25b2697bd267f9e4 },\n        { -0x6f9d4d1f26e58744, 0x47c9889cc8509667, -0x620ab599bfaf8f48, 0x7369e6a92493a1bf },\n        { -0x6298c004ec67979c, 0x3ca5fbd9415dc7b8, -0x1fb133c420d8c4a2, 0x1420683db54e4cd2 }\n    },\n    {\n        { 0x34eebb6fc1cc5ad0, 0x6a1b0ce99646ac8b, -0x2c4f25b6599421ad, 0x31e83b4161d081c1 },\n        { -0x4b8742e1db622e69, 0x620c35005e58c102, -0x04fd2cd0334553a4, 0x60b63bebf508a72d },\n        { -0x681738ed61f9d4b1, 0x49e48f4f29320ad8, 0x5bece14b6f18683f, 0x55cf1eb62d550317 }\n    },\n    {\n        { 0x3076b5e37df58c52, -0x28c54622186633ca, -0x427ce31cb6ec11e0, 0x1a56fbaa62ba0133 },\n        { 0x5879101065c23d58, -0x7462f792af6b7e64, -0x1dbfd056ed3aa059, 0x669a6564570891d4 },\n        { -0x6bc194afa3623614, 0x302557bba77c371a, -0x678c51a9becb89af, 0x13c4836799c58a5c }\n    },\n    {\n        { -0x3b230495a2742f80, -0x21143b13a8e5b7be, -0x2b4d177c471aac9b, 0x50bdc87dc8e5b827 },\n        { 0x423a5d465ab3e1b9, -0x03ec3e78380ec09f, 0x19f83664ecb5b9b6, 0x66f80c93a637b607 },\n        { 0x606d37836edfe111, 0x32353e15f011abd9, 0x64b03ac325b73b96, 0x1dd56444725fd5ae }\n    },\n    {\n        { -0x3d6819fff7453766, 0x7d4cea11eae1c3e0, -0x0c1c741e60186884, 0x3a3a450f63a305cd },\n        { -0x705b8007cc9ded83, -0x4360953b8e3283eb, 0x6e71454349220c8b, 0x0e645912219f732e },\n        { 0x078f2f31d8394627, 0x389d3183de94a510, -0x2e1c9392e8669080, 0x318c8d9393a9a87b }\n    },\n    {\n        { 0x5d669e29ab1dd398, -0x036de9a7cbd261c5, 0x55851dfdf35973cd, 0x509a41c325950af6 },\n        { -0x0d8ba2fcd50001e7, 0x0c9f3c497f24db66, -0x43672c1c457a6711, 0x224c7c679a1d5314 },\n        { -0x423f91235906da17, 0x793ef3f4641b1f33, -0x7d13ed7f627cc177, 0x05bff02328a11389 }\n    },\n    {\n        { 0x6881a0dd0dc512e4, 0x4fe70dc844a5fafe, 0x1f748e6b8f4a5240, 0x576277cdee01a3ea },\n        { 0x3632137023cae00b, 0x544acf0ad1accf59, -0x698befb62de5e378, 0x780b8cc3fa2a44a7 },\n        { 0x1ef38abc234f305f, -0x65a88042ebfa21f8, 0x5e82a51434e62a0d, 0x5ff418726271b7a1 }\n    },\n    {\n        { -0x1a24b817ec496ac0, -0x0ca2d5c4bcd9ef1f, -0x53e0d916c787ed8a, 0x29d4db8ca0a0cb69 },\n        { 0x398e080c1789db9d, -0x589fdfda0c18870b, -0x056776b3f942fca3, 0x106a03dc25a966be },\n        { -0x2652f550ccccac30, 0x38669da5acd309e5, 0x3c57658ac888f7f0, 0x4ab38a51052cbefa }\n    },\n},\n{\n    {\n        { -0x09701d177f621fac, -0x1c43f695637d452f, 0x076353d40aadbf45, 0x7b9b1fb5dea1959e },\n        { -0x20253411bcdb3f17, 0x054442883f955bb7, -0x2108555715ce9f61, 0x68aee70642287cff },\n        { -0x0fe3370e8b8e33f4, -0x6adbd1c8a86f7d45, 0x27776093d3e46b5f, 0x2d13d55a28bd85fb }\n    },\n    {\n        { -0x40fe6331851185ae, -0x57212d491bab152d, 0x3c619f0b87a8bb19, 0x3619b5d7560916d8 },\n        { -0x053a2df9a4ca4726, -0x572575657a9db449, -0x332d356ec2de32f1, 0x6b8341ee8bf90d58 },\n        { 0x3579f26b0282c4b2, 0x64d592f24fafefae, -0x48321284d7373840, 0x6a927b6b7173a8d7 }\n    },\n    {\n        { -0x728fbf79c1317715, -0x0f1cf8567f113f74, -0x53ddaf9ef2877026, 0x056d92a43a0d478d },\n        { 0x1f6db24f986e4656, 0x1021c02ed1e9105b, -0x0700c000d33f5c8b, 0x1d2a6bf8c6c82592 },\n        { 0x1b05a196fc3da5a1, 0x77d7a8c243b59ed0, 0x06da3d6297d17918, 0x66fbb494f12353f7 }\n    },\n    {\n        { -0x2928f6690edcf62a, -0x2404dc7a163c2ac7, 0x46d602b0f7552411, 0x270a0b0557843e0c },\n        { 0x751a50b9d85c0fb8, -0x2e5023da7430f685, 0x2f16a6a38309a969, 0x14ddff9ee5b00659 },\n        { 0x61ff0640a7862bcc, -0x7e353f65a0ee5402, -0x6fb87cfbaa2ed545, 0x19a4bde1945ae873 }\n    },\n    {\n        { 0x40c709dec076c49f, 0x657bfaf27f3e53f6, 0x40662331eca042c4, 0x14b375487eb4df04 },\n        { -0x6460d90adf59dff6, 0x64804443cf13eaf8, -0x759c98c079ce122d, 0x72bbbce11ed39dc1 },\n        { -0x517ac36b549923b9, -0x149dcbc12089d292, -0x0f71f1e7904d082f, 0x4f0b1c02700ab37a }\n    },\n    {\n        { 0x79fd21ccc1b2e23f, 0x4ae7c281453df52a, -0x37e8d1362eaeb795, 0x68abe9443e0a7534 },\n        { -0x1e8f987827e6ae06, -0x5ef5d3714d6f3885, -0x18c7d05fc129988d, 0x0a4d84710bcc4b54 },\n        { -0x25ed393bf87ce235, 0x0da230d74d5c510d, 0x4ab1531e6bd404e1, 0x4106b166bcf440ef }\n    },\n    {\n        { -0x5b7a332ac61b130e, 0x5aa3f3ad0555bab5, 0x145e3439937df82d, 0x1238b51e1214283f },\n        { 0x02e57a421cd23668, 0x4ad9fb5d0eaef6fd, -0x6ab198d84edbbb80, 0x7f792f9d2699f331 },\n        { 0x0b886b925fd4d924, 0x60906f7a3626a80d, -0x132c984b467542ee, 0x2876beb1def344cf }\n    },\n    {\n        { -0x2a6b4cccc5757a08, 0x4ea37689e78d7d58, 0x73bf9f455e8e351f, 0x5507d7d2bc41ebb4 },\n        { -0x237b16ca9cebb96f, 0x632fe8a0d61f23f4, 0x4caa800612a9a8d5, 0x48f9dbfa0e9918d3 },\n        { 0x1ceb2903299572fc, 0x7c8ccaa29502d0ee, -0x6e405bcbee331985, 0x5784481964a831e7 }\n    },\n},\n{\n    {\n        { -0x29302e10a0223f64, -0x17d4c10208a8a232, 0x25d56b5d201634c2, 0x3041c6bb04ed2b9b },\n        { -0x2583d4da98972a6d, -0x673e3fa8bbdd35ed, -0x0e57f42a35f531e3, 0x29cdd1adc088a690 },\n        { 0x0ff2f2f9d956e148, -0x5218688a60ca94d2, 0x1a4698bb5f6c025c, 0x104bbd6814049a7b }\n    },\n    {\n        { -0x56a265a029800e9d, -0x16d41962b338a97f, -0x4807fdb321df0da9, 0x204f2a20fb072df5 },\n        { 0x51f0fd3168f1ed67, 0x2c811dcdd86f3bc2, 0x44dc5c4304d2f2de, 0x5be8cc57092a7149 },\n        { -0x37ebc4c2cf144f87, 0x7589155abd652e30, 0x653c3c318f6d5c31, 0x2570fb17c279161f }\n    },\n    {\n        { 0x192ea9550bb8245a, -0x37190457706faf2f, 0x7986ea2d88a4c935, 0x241c5f91de018668 },\n        { 0x3efa367f2cb61575, -0x0a069089e329fd94, -0x1738ebd59a4ada9e, 0x3dcb65ea53030acd },\n        { 0x28d8172940de6caa, -0x7040d30fdd268cc6, 0x16d7fcdd235b01d1, 0x08420edd5fcdf0e5 }\n    },\n    {\n        { 0x0358c34e04f410ce, -0x49eca4a5d891f97b, 0x5d9670c7ebb91521, 0x04d654f321db889c },\n        { -0x3200df547c9d05b6, 0x57e118d4e21a3e6e, -0x1ce869e803c619d5, 0x0d9a53efbc1769fd },\n        { 0x5e7dc116ddbdb5d5, 0x2954deb68da5dd2d, 0x1cb608173334a292, 0x4a7a4f2618991ad7 }\n    },\n    {\n        { 0x24c3b291af372a4b, -0x6c257d8f8e7eb80e, -0x227b7a9b7976610e, 0x4a96314223e0ee33 },\n        { -0x0b58e7fda04ea06b, 0x3df65f346b5c1b8f, -0x32030f7aff1feeee, 0x11b50c4cddd31848 },\n        { -0x5917d8bbf75b002a, 0x738e177e9c1576d9, 0x773348b63d02b3f2, 0x4f4bce4dce6bcc51 }\n    },\n    {\n        { 0x30e2616ec49d0b6f, -0x1ba98e703513dce9, 0x48eb409bf26b4fa6, 0x3042cee561595f37 },\n        { -0x58e031a51ddbda7c, 0x26ea725692f58a9e, -0x2de5f628e315c30c, 0x73fcdd14b71c01e6 },\n        { 0x427e7079449bac41, -0x7aa51c92431dcef6, 0x4cae76215f841a7c, 0x389e740c9a9ce1d6 }\n    },\n    {\n        { -0x36428709a8f153d8, -0x1aa4f4cdd86e631f, 0x65fc3eaba19b91ed, 0x25c425e5d6263690 },\n        { 0x64fcb3ae34dcb9ce, -0x68affcdc1cb72f53, 0x45b3f07d62c6381b, 0x61545379465a6788 },\n        { 0x3f3e06a6f1d7de6e, 0x3ef976278e062308, -0x73eb09d9b1759389, 0x6539a08915484759 }\n    },\n    {\n        { -0x223b242beb44b5e7, 0x19b2bc3c98424f8e, 0x48a89fd736ca7169, 0x0f65320ef019bd90 },\n        { -0x162de08b3c2d088d, -0x3eafabbeda3b97bb, 0x624e5ce8f9b99e33, 0x11c5e4aac5cd186c },\n        { -0x2b792e4e35021f3a, 0x4f3fe6e3163b5181, 0x59a8af0dfaf2939a, 0x4cabc7bdec33072a }\n    },\n},\n{\n    {\n        { -0x083f5e63e5ab5fbc, 0x4a1c5e2477bd9fbb, -0x591c35eea50dd68e, 0x1819bb953f2e9e0d },\n        { 0x16faa8fb532f7428, -0x242bd15fb95b1d8e, 0x5337653b8b9ea480, 0x4065947223973f03 },\n        { 0x498fbb795e042e84, 0x7d0dd89a7698b714, -0x7404f45bd8019d6b, 0x36ba82e721200524 }\n    },\n    {\n        { -0x372962f5a8d8b12b, 0x45ba803260804b17, -0x20c325efddaa2054, 0x77d221232709b339 },\n        { -0x29f13448bdba13bf, -0x02641761cbcb78ea, -0x36dbf5011bdd7b22, 0x4472f648d0531db4 },\n        { 0x498a6d7064ad94d8, -0x5a4a37026509dd9d, -0x735712faba3ebe0c, 0x2c63bec3662d358c }\n    },\n    {\n        { -0x65ae74c57a790741, -0x6118e509344e6910, -0x55f9da195dc7a30e, 0x1deb2176ddd7c8d1 },\n        { 0x7fe60d8bea787955, -0x4623ee814a0bfe49, -0x6e383f65e6caa332, 0x22692ef59442bedf },\n        { -0x7a9c2e65df993094, 0x401bfd8c4dcc7cd7, -0x2689594132f2709e, 0x67cfd773a278b05e }\n    },\n    {\n        { 0x2d5fa9855a4e586a, 0x65f8f7a449beab7e, -0x55f8b2220de2cc2d, 0x185cba721bcb9dee },\n        { -0x7213ce0510c11b8b, -0x6624007561dd026e, 0x512d11594e26cab1, 0x0cde561eec4310b9 },\n        { -0x6c79625c0b1c34bf, -0x40fc6d0abf086882, 0x026204fcd0463b83, 0x3ec91a769eec6eed }\n    },\n    {\n        { 0x0fad2fb7b0a3402f, 0x46615ecbfb69f4a8, -0x08ba43373a07155a, 0x7a5fa8794a94e896 },\n        { 0x1e9df75bf78166ad, 0x4dfda838eb0cd7af, -0x45ffd1273e150678, 0x13fedb3e11f33cfc },\n        { 0x52958faa13cd67a1, -0x69a11f7e74244ae9, 0x16e58daa2e8845b3, 0x357d397d5499da8f }\n    },\n    {\n        { 0x481dacb4194bfbf8, 0x4d77e3f1bae58299, 0x1ef4612e7d1372a0, 0x3a8d867e70ff69e1 },\n        { 0x1ebfa05fb0bace6c, -0x36cb9df3e35065e2, -0x3388e33be27d49e6, 0x2d94a16aa5f74fec },\n        { 0x6f58cd5d55aff958, -0x45c155a38aa988df, 0x75c123999165227d, 0x69be1343c2f2b35e }\n    },\n    {\n        { -0x7d44425397b4721d, -0x5d0b382fc035f8e8, 0x337f92fbe096aaa8, 0x200d4d8c63587376 },\n        { 0x0e091d5ee197c92a, 0x4f51019f2945119f, 0x143679b9f034e99c, 0x7d88112e4d24c696 },\n        { 0x208aed4b4893b32b, 0x3efbf23ebe59b964, -0x289d214f245a1af9, 0x69607bd681bd9d94 }\n    },\n    {\n        { 0x3b7f3bd49323a902, 0x7c21b5566b2c6e53, -0x1a45700ac587ad59, 0x28bc77a5838ece00 },\n        { -0x0941fdef9721e31f, -0x172ae718f12343e1, -0x1c10022fe4aafa5b, 0x35f63353d3ec3fd0 },\n        { 0x63ba78a8e25d8036, 0x63651e0094333490, 0x48d82f20288ce532, 0x3a31abfa36b57524 }\n    },\n},\n{\n    {\n        { -0x3f708770c0872d77, -0x01cf58d35ebfb261, -0x0d887403309a3363, 0x7ee498165acb2021 },\n        { 0x239e9624089c0a2e, -0x38b73b3fc501b8c8, 0x17dbed2a764fa12a, 0x639b93f0321c8582 },\n        { 0x7bd508e39111a1c3, 0x2b2b90d480907489, -0x182d513d518d02e7, 0x0edf493c85b602a6 }\n    },\n    {\n        { 0x6767c4d284764113, -0x5f6fbfc0080a07cb, 0x1c8fcffacae6bede, 0x04c00c54d1dfa369 },\n        { -0x51337ea7a664a598, -0x15a8b0f014521df2, 0x4fe41d7422b67f07, 0x403b92e3019d4fb4 },\n        { 0x4dc22f818b465cf8, 0x71a0f35a1480eff8, -0x51174052fb3829a9, 0x355bb12ab26176f4 }\n    },\n    {\n        { -0x5cfe2538a5738ce8, -0x126ffc624c3155ef, 0x6f077cbf3bae3f2d, 0x7518eaf8e052ad8e },\n        { -0x58e19b338b6c440c, -0x1a427b26135c4f3d, 0x0a6bc50cfa05e785, 0x0f9b8132182ec312 },\n        { -0x5b77a63be48093ce, 0x0f2d60bcf4383298, 0x1815a929c9b1d1d9, 0x47c3871bbb1755c4 }\n    },\n    {\n        { -0x0419a2af37af9950, 0x62ecc4b0b3a299b0, -0x1ac8ab15bbe51720, 0x08fea02ce8d48d5f },\n        { 0x5144539771ec4f48, -0x07fa4e823673a292, -0x089d3ee5b83c3995, 0x00b89b85764699dc },\n        { -0x7db2228997211530, -0x379bbadfb497a2dd, -0x4aeb3032a276299b, 0x473829a74f75d537 }\n    },\n    {\n        { 0x23d9533aad3902c9, 0x64c2ddceef03588f, 0x15257390cfe12fb4, 0x6c668b4d44e4d390 },\n        { -0x7d2d258ab9863be8, -0x19c428274d9e7210, 0x355eef24ac47eb0a, 0x2078684c4833c6b4 },\n        { 0x3b48cf217a78820c, -0x0895f54d7ed8c169, -0x56939a5873711285, 0x7411a6054f8a433f }\n    },\n    {\n        { 0x579ae53d18b175b4, 0x68713159f392a102, -0x7baa1345e110ca0b, 0x1ec9a872458c398f },\n        { 0x4d659d32b99dc86d, 0x044cdc75603af115, -0x4cb38ed3233d1b78, 0x7c136574fb8134ff },\n        { -0x47195b2bff5daf65, -0x647e28fdf4377d4c, 0x57e7cc9bf1957561, 0x3add88a5c7cd6460 }\n    },\n    {\n        { -0x7a3d672ba6c6cfba, -0x7081ca67a009a614, 0x1d2ca22af2f66e3a, 0x61ba1131a406a720 },\n        { -0x5476a88f49ca230e, 0x02dfef6cf66c1fbc, -0x7aacfd9741492e79, 0x249929fccc879e74 },\n        { -0x5c2f5f0ee96a6fd7, 0x023b6b6cba7ebd89, 0x7bf15a3e26783307, 0x5620310cbbd8ece7 }\n    },\n    {\n        { 0x6646b5f477e285d6, 0x40e8ff676c8f6193, -0x59138cee544a6b23, 0x7ec846f3658cec4d },\n        { 0x528993434934d643, -0x462407f95aeddd0b, -0x709278703c0be3de, 0x37676a2a4d9d9730 },\n        { -0x64a170c0e25dd139, 0x130f1d776c01cd13, 0x214c8fcfa2989fb8, 0x6daaf723399b9dd5 }\n    },\n},\n{\n    {\n        { -0x7e514422d32ecf90, -0x69d1bcda07a5f162, -0x216c6e5535200135, 0x53177fda52c230e6 },\n        { 0x591e4a5610628564, 0x2a4bb87ca8b4df34, -0x21d5da8d185c71bd, 0x3cbdabd9fee5046e },\n        { -0x584368f9af462187, 0x3d12a7fbc301b59b, 0x02652e68d36ae38c, 0x79d739835a6199dc }\n    },\n    {\n        { 0x21c9d9920d591737, -0x6415be2d164b932a, -0x1df17bdff2764036, 0x79d99f946eae5ff8 },\n        { -0x26cab209bece3e43, 0x758094a186ec5822, 0x4464ee12e459f3c2, 0x6c11fce4cb133282 },\n        { -0x0e84b7ca9798cdfb, 0x387deae83caad96c, 0x61b471fd56ffe386, 0x31741195b745a599 }\n    },\n    {\n        { 0x17f8ba683b02a047, 0x50212096feefb6c8, 0x70139be21556cbe2, 0x203e44a11d98915b },\n        { -0x172efe6f4885c9f5, -0x66467cdf666a18fe, -0x42b0200705fdb856, 0x2772e344e0d36a87 },\n        { -0x2979c145c8461c61, 0x105bc169723b5a23, 0x104f6459a65c0762, 0x567951295b4d38d4 }\n    },\n    {\n        { 0x07242eb30d4b497f, 0x1ef96306b9bccc87, 0x37950934d8116f45, 0x05468d6201405b04 },\n        { 0x535fd60613037524, -0x1def52094f043d96, -0x5372f564dc166f52, 0x47204d08d72fdbf9 },\n        { 0x00f565a9f93267de, -0x313028723f2a7176, -0x5dea1d230ce71d72, 0x4599ee919b633352 }\n    },\n    {\n        { -0x538b929479e51a87, 0x31ab0650f6aea9dc, 0x241d661140256d4c, 0x2f485e853d21a5de },\n        { -0x2c3ddf358f1f1895, -0x4ed415a71560cf6c, 0x294ddec8c3271282, 0x0c3539e1a1d1d028 },\n        { 0x329744839c0833f3, 0x6fe6257fd2abc484, 0x5327d1814b358817, 0x65712585893fe9bc }\n    },\n    {\n        { -0x7e3d60e428f711c1, -0x2234a5fa519bf830, -0x68513e282d5c1459, 0x1590521a91d50831 },\n        { -0x63efd048cd59ee9f, -0x1b71ef22cb2adf58, 0x365c63546f9a9176, 0x32f6fe4c046f6006 },\n        { 0x40a3a11ec7910acc, -0x6fec20070e92d852, 0x1a9720d8abb195d4, 0x1bb9fe452ea98463 }\n    },\n    {\n        { -0x30a1936a33c98b84, 0x294201536b0bc30d, 0x453ac67cee797af0, 0x5eae6ab32a8bb3c9 },\n        { -0x162e26af4c2ab062, 0x2d5f9cbee00d33c1, 0x51c2c656a04fc6ac, 0x65c091ee3c1cbcc9 },\n        { 0x7083661114f118ea, 0x2b37b87b94349cad, 0x7273f51cb4e99f40, 0x78a2a95823d75698 }\n    },\n    {\n        { -0x4b0dc3bda107cdf9, -0x54076b2c3656cb4b, -0x2f8f73ecc6027809, 0x1876789117166130 },\n        { -0x5d4f8d16a373d532, 0x69cffc96651e9c4b, 0x44328ef842e7b42b, 0x5dd996c122aadeb3 },\n        { -0x6da4a10f98f3af84, -0x7e6437bd46c3cc41, 0x10792e9a70dd003f, 0x59ad4b7a6e28dc74 }\n    },\n},\n{\n    {\n        { 0x583b04bfacad8ea2, 0x29b743e8148be884, 0x2b1e583b0810c5db, 0x2b5449e58eb3bbaa },\n        { 0x5f3a7562eb3dbe47, -0x0815c7ab71425f48, 0x00c3e53145747299, 0x1304e9e71627d551 },\n        { 0x789814d26adc9cfe, 0x3c1bab3f8b48dd0b, -0x25f01e00068639f6, 0x4468de2d7c2dd693 }\n    },\n    {\n        { 0x4b9ad8c6f86307ce, 0x21113531435d0c28, -0x2b57993a9a8588d4, 0x5da6427e63247352 },\n        { 0x51bb355e9419469e, 0x33e6dc4c23ddc754, -0x6c5a4929bb80669e, 0x6cce7c6ffb44bd63 },\n        { 0x1a94c688deac22ca, -0x46f991084451e008, -0x775273c772a6a7f1, 0x58f29abfe79f2ca8 }\n    },\n    {\n        { 0x4b5a64bf710ecdf6, -0x4eb31ac7b9d3d6c4, 0x3643d056d50b3ab9, 0x6af93724185b4870 },\n        { -0x16f130547218c198, 0x54036f9f377e76a5, -0x0fb6a4f441fea67e, 0x577629c4a7f41e36 },\n        { 0x3220024509c6a888, -0x2d1fc9ecb4aa768d, -0x7c1dc9dcc3ccd761, 0x701f25bb0caec18f }\n    },\n    {\n        { -0x62e7092683413eed, -0x7bb5f9198b40241c, 0x20f5b522ac4e60d6, 0x720a5bc050955e51 },\n        { -0x3c574f071b9e9313, -0x08ff99f161da5783, 0x61e3061ff4bca59c, 0x2e0c92bfbdc40be9 },\n        { 0x0c3f09439b805a35, -0x17b174c89dbd5404, 0x691417f35c229346, 0x0e9b9cbb144ef0ec }\n    },\n    {\n        { -0x7211642aa24e4112, -0x363c54c8f58dc047, 0x44a8f1bf1c68d791, 0x366d44191cfd3cde },\n        { -0x04452b7004a8df53, -0x117e6e942406f2f2, -0x2b7ecead9caabc41, 0x221104eb3f337bd8 },\n        { -0x61c3e8bc0d4373ec, 0x2eda26fcb5856c3b, -0x3347d0f197580469, 0x4167a4e6bc593244 }\n    },\n    {\n        { -0x3d41d99a07317012, -0x169800eb177f29d4, -0x0ed19181d0c9b112, 0x34b33370cb7ed2f6 },\n        { 0x643b9d2876f62700, 0x5d1d9d400e7668eb, 0x1b4b430321fc0684, 0x7938bb7e2255246a },\n        { -0x323a6e11797e2934, -0x31fdef63127a58ad, -0x128b7a3ea77f777d, 0x1176fc6e2dfe65e4 }\n    },\n    {\n        { -0x246f1d76b688f148, -0x670433d5530bbf5d, 0x21354ffeded7879b, 0x1f6a3e54f26906b6 },\n        { -0x4b50932fa4639e65, 0x2ddfc9f4b2a58480, 0x3d4fa502ebe94dc4, 0x08fc3a4c677d5f34 },\n        { 0x60a4c199d30734ea, 0x40c085b631165cd6, -0x1dccc1dc08a67d6b, 0x4f2fad0116b900d1 }\n    },\n    {\n        { -0x69d326e248c449c8, -0x19fa885503ed63f8, 0x6f619b39f3b61689, 0x3451995f2944ee81 },\n        { 0x44beb24194ae4e54, 0x5f541c511857ef6c, -0x59e194d2c972fb68, 0x445484a4972ef7ab },\n        { -0x6ead032f60158284, 0x4a816c94b0935cf6, 0x258e9aaa47285c40, 0x10b89ca6042893b7 }\n    },\n},\n{\n    {\n        { -0x29832129862cb560, -0x33f4613f33b24c61, -0x5aca5ba91ca2e6f1, 0x2e05d9eaf61f6fef },\n        { -0x64d5bd91c49b9fdb, 0x32127190385ce4cf, -0x5da3003d229215bb, 0x06409010bea8de75 },\n        { -0x3bb86fe529e414a7, 0x661f19bce5dc880a, 0x24685482b7ca6827, 0x293c778cefe07f26 }\n    },\n    {\n        { 0x16c795d6a11ff200, -0x348f2f1d4ea7ea37, -0x760d6cdf64ac6a4b, 0x50b8c2d031e47b4f },\n        { -0x797f618ff8f96f6a, -0x5528a4ea1b1afe77, 0x07f35715a21a0147, 0x0487f3f112815d5e },\n        { 0x48350c08068a4962, 0x6ffdd05351092c9a, 0x17af4f4aaf6fc8dd, 0x4b0553b53cdba58b }\n    },\n    {\n        { -0x40fadee4d83ead2c, 0x5ec26849bd1af639, 0x5e0b2caa8e6fab98, 0x054c8bdd50bd0840 },\n        { -0x639a0341e4cd0087, -0x148a1560fc4af065, -0x0312d59393f819fa, 0x35106cd551717908 },\n        { 0x38a0b12f1dcf073d, 0x4b60a8a3b7f6a276, -0x012a53da2cbfb066, 0x72e82d5e5505c229 }\n    },\n    {\n        { 0x00d9cdfd69771d02, 0x410276cd6cfbf17e, 0x4c45306c1cb12ec7, 0x2857bf1627500861 },\n        { 0x6b0b697ff0d844c8, -0x44ed07a3268634b7, -0x2d5abe393e25f0e1, 0x7b7c242958ce7211 },\n        { -0x60de6fc0fefe9762, -0x2886202c4079effb, -0x5edd11a0c214f0e5, 0x510df84b485a00d4 }\n    },\n    {\n        { 0x24b3c887c70ac15e, -0x4f0c5aa8047e48ce, -0x64d321d01a8733e5, 0x4cf7ed0703b54f8e },\n        { -0x5abecc446d885e06, 0x74ec3b6263991237, 0x1a3c54dc35d2f15a, 0x2d347144e482ba3a },\n        { 0x6bd47c6598fbee0f, -0x61b8cc1d54aa41d3, 0x1093f624127610c5, 0x4e05e26ad0a1eaa4 }\n    },\n    {\n        { 0x1833c773e18fe6c0, -0x1c3b8ee52c378d9b, 0x3bfd3c4f0116b283, 0x1955875eb4cd4db8 },\n        { -0x2564949db4ace0e0, 0x429a760e77509abb, -0x24160add17dc3480, 0x618f1856880c8f82 },\n        { 0x6da6de8f0e399799, 0x7ad61aa440fda178, -0x4cd327efa1ca9c23, 0x15f6beae2ae340ae }\n    },\n    {\n        { -0x4565f0846dba1deb, -0x0c979ed22673f245, 0x2e84e4cbf220b020, 0x6ba92fe962d90eda },\n        { -0x79d434f3ce13c59e, -0x7ef1d4baeec70c3e, 0x788ec4b839dac2a4, 0x28f76867ae2a9281 },\n        { 0x3e4df9655884e2aa, -0x429d0424242b9a5b, -0x28a69355f2161adc, 0x6e8042ccb2b1b3d7 }\n    },\n    {\n        { 0x1530653616521f7e, 0x660d06b896203dba, 0x2d3989bc545f0879, 0x4b5303af78ebd7b0 },\n        { -0x0ef2c3d631d73592, -0x452cbabf0349f6c3, -0x18bd91285d15d2c1, 0x08af9d4e4ff298b9 },\n        { 0x72f8a6c3bebcbde8, 0x4f0fca4adc3a8e89, 0x6fa9d4e8c7bfdf7a, 0x0dcf2d679b624eb7 }\n    },\n},\n{\n    {\n        { 0x753941be5a45f06e, -0x2f8351129263a09b, 0x11776b9c72ff51b6, 0x17d2d1d9ef0d4da9 },\n        { 0x3d5947499718289c, 0x12ebf8c524533f26, 0x0262bfcb14c3ef15, 0x20b878d577b7518e },\n        { 0x27f2af18073f3e6a, -0x02c01ae628adef97, 0x22e3b72c3ca60022, 0x72214f63cc65c6a7 }\n    },\n    {\n        { 0x1d9db7b9f43b29c9, -0x29fa7db5b0ae708b, -0x0d3f8d42ced0623c, 0x1f24ac855a1545b0 },\n        { -0x4b1c80bfacf8596d, -0x5458eb28d0cc986b, -0x29042f588c89ef67, 0x5fdf48c58171cbc9 },\n        { 0x24d608328e9505aa, 0x4748c1d10c1420ee, -0x38001ba3f904da5e, 0x00ba739e2ae395e6 }\n    },\n    {\n        { -0x51bbd90a157744da, 0x360679d984973bfb, 0x5c9f030c26694e50, 0x72297de7d518d226 },\n        { 0x592e98de5c8790d6, -0x1a40482cba3d5d21, 0x115a3b60f9b49922, 0x03283a3e67ad78f3 },\n        { 0x48241dc7be0cb939, 0x32f19b4d8b633080, -0x2c2036f2fdd76cf8, 0x05e1296846271945 }\n    },\n    {\n        { -0x52404437dbd3bab0, -0x4337f3132fcf7e27, -0x7bca99590a37206e, 0x78cf25d38258ce4c },\n        { -0x457d114cd263b6a6, -0x311037030ed44684, -0x4fd254516c4a2e20, 0x39c00c9c13698d9b },\n        { 0x15ae6b8e31489d68, -0x557ae35463d40f79, -0x3658a5680fb105fb, 0x006b52076b3ff832 }\n    },\n    {\n        { -0x0a3481e94631f7d3, 0x3407f14c417abc29, -0x2b4c9431d40b5855, 0x7de2e9561a9f75ce },\n        { 0x29e0cfe19d95781c, -0x497e20e7699cef1e, 0x57df39d370516b39, 0x4d57e3443bc76122 },\n        { -0x218f2b0b495aa135, 0x4801527f5d85db99, -0x24363bbf2c11657f, 0x6b2a90af1a6029ed }\n    },\n    {\n        { 0x77ebf3245bb2d80a, -0x27cfe4b8d046f865, -0x39b8190db3118ccd, 0x465812c8276c2109 },\n        { 0x6923f4fc9ae61e97, 0x5735281de03f5fd1, -0x589b51bc19122ed3, 0x5fd8f4e9d12d3e4a },\n        { 0x4d43beb22a1062d9, 0x7065fb753831dc16, 0x180d4a7bde2968d7, 0x05b32c2b1cb16790 }\n    },\n    {\n        { -0x08035bd3852a7e6b, 0x3214286e4333f3cc, -0x493d62f2cbf46863, 0x31771a48567307e1 },\n        { -0x373fa1332db25703, -0x5e30e553fa20107d, -0x2441100d8206329f, 0x3b5556a37b471e99 },\n        { 0x32b0c524e14dd482, -0x124caeabe5d45b4a, -0x5c2e9fb7d7d4a50d, 0x4fc079d27a7336eb }\n    },\n    {\n        { -0x23cb74bbf3793af3, 0x1337cbc9cc94e651, 0x6422f74d643e3cb9, 0x241170c2bae3cd08 },\n        { 0x51c938b089bf2f7f, 0x2497bd6502dfe9a7, -0x00003f63877f1bad, 0x124567cecaf98e92 },\n        { 0x3ff9ab860ac473b4, -0x0f6ee211feec1bcb, 0x4ae75060ebc6c4af, 0x3f8612966c87000d }\n    },\n},\n{\n    {\n        { 0x529fdffe638c7bf3, -0x20d4619fc774b66b, -0x1fd84cb0e452fdb7, 0x7bc92fc9b9fa74ed },\n        { 0x0c9c5303f7957be4, -0x5c3ce5df1f7a3ebb, -0x4f8de28e2f7affb0, 0x0aba390eab0bf2da },\n        { -0x606810d17fe52607, -0x7c9682ab865025c6, -0x16f94c0042a694b0, 0x02672b37dd3fb8e0 }\n    },\n    {\n        { -0x116458d6c673580b, -0x146359da85b7b625, 0x29eb29ce7ec544e1, 0x232ca21ef736e2c8 },\n        { 0x48b2ca8b260885e4, -0x5bd794137d4cb3e4, -0x6c81e5d9e80a708c, 0x741d1fcbab2ca2a5 },\n        { -0x409ebdc2dac034e9, 0x08803ceafa39eb14, -0x0e79fd2067ae3851, 0x0400f3a049e3414b }\n    },\n    {\n        { 0x2efba412a06e7b06, 0x146785452c8d2560, -0x2068ec1429856e39, 0x32830ac7157eadf3 },\n        { -0x5431fb89459e3aa5, 0x36a3d6d7c4d39716, 0x6eb259d5e8d82d09, 0x0c9176e984d756fb },\n        { 0x0e782a7ab73769e8, 0x04a05d7875b18e2c, 0x29525226ebcceae1, 0x0d794f8383eba820 }\n    },\n    {\n        { 0x7be44ce7a7a2e1ac, 0x411fd93efad1b8b7, 0x1734a1d70d5f7c9b, 0x0d6592233127db16 },\n        { -0x00ca0a3461eae90c, -0x117fa4309b7551bb, -0x0f28c3d446c5610d, 0x097b0bf22092a6c2 },\n        { -0x3b7454eade5628cd, -0x593d151529e544db, 0x625c6c1cc6cb4305, 0x7fc90fea93eb3a67 }\n    },\n    {\n        { -0x3ad8214a63834dc3, -0x6aac6e96acd7bfb2, -0x29bc6d7e8330d386, 0x6ce97dabf7d8fa11 },\n        { 0x0408f1fe1f5c5926, 0x1a8f2f5e3b258bf4, 0x40a951a2fdc71669, 0x6598ee93c98b577e },\n        { 0x25b5a8e50ef7c48f, -0x149fcbee90d31ace, -0x3a18ae8c1ac21ac9, 0x73119fa08c12bb03 }\n    },\n    {\n        { 0x7845b94d21f4774d, -0x409d0e93876848d9, 0x671857c03c56522b, 0x3cd6a85295621212 },\n        { -0x12cfed6bac0e5b35, -0x4319de36370ac879, -0x0534d4ecc7411847, 0x3025798a9ea8428c },\n        { 0x3fecde923aeca999, -0x4255a4ff9d173ed1, 0x67b99dfc96988ade, 0x3f52c02852661036 }\n    },\n    {\n        { -0x6da74066113be93a, -0x5375afe8562d098f, 0x629549ab16dea4ab, 0x05d0e85c99091569 },\n        { -0x00155b71d5ecae3a, 0x28624754fa7f53d7, 0x0b5ba9e57582ddf1, 0x60c0104ba696ac59 },\n        { 0x051de020de9cbe97, -0x05f803a94af4308c, 0x378cec9f0f11df65, 0x36853c69ab96de4d }\n    },\n    {\n        { 0x4433c0b0fac5e7be, 0x724bae854c08dcbe, -0x0e0db33bb9687065, 0x4a0aff6d62825fc8 },\n        { 0x36d9b8de78f39b2d, 0x7f42ed71a847b9ec, 0x241cd1d679bd3fde, 0x6a704fec92fbce6b },\n        { -0x16e804619ef6acff, -0x3efd206bfd5f6d08, -0x40f61d0a0599e6f5, 0x681109bee0dcfe37 }\n    },\n},\n{\n    {\n        { -0x63e70305c9fb72ed, 0x29159db373899ddd, -0x2360caf4606d2f56, 0x26f57eee878a19d4 },\n        { 0x559a0cc9782a0dde, 0x551dcdb2ea718385, 0x7f62865b31ef238c, 0x504aa7767973613d },\n        { 0x0cab2cd55687efb1, 0x5180d162247af17b, -0x7a3ea5cbb0a5db99, 0x4041943d9dba3069 }\n    },\n    {\n        { 0x4b217743a26caadd, 0x47a6b424648ab7ce, -0x34e2b085fc04361d, 0x12d931429800d019 },\n        { -0x3c3f1145bc14336a, -0x728b6363d9156351, -0x26056a11e388333a, 0x1420a1d97684340f },\n        { 0x00c67799d337594f, 0x5e3c5140b23aa47b, 0x44182854e35ff395, 0x1b4f92314359a012 }\n    },\n    {\n        { 0x33cf3030a49866b1, 0x251f73d2215f4859, -0x547d55bfae210b0a, 0x5ff191d56f9a23f6 },\n        { 0x3e5c109d89150951, 0x39cefa912de9696a, 0x20eae43f975f3020, 0x239b572a7f132dae },\n        { -0x7e612bcc53d26f98, 0x2883ab795fc98523, -0x10ba8d7faa6c14c3, 0x020c526a758f36cb }\n    },\n    {\n        { -0x16ce10a60fbd3377, 0x2c589c9d8e124bb6, -0x52371e755138a669, 0x452cfe0a5602c50c },\n        { 0x779834f89ed8dbbc, -0x370d550623835b94, -0x56adb3235c1e4f8c, 0x02aacc4615313877 },\n        { -0x795f085f9b878821, -0x443b9bd8f19f8361, -0x54e815da0e04ee37, 0x4cfb7d7b304b877b }\n    },\n    {\n        { -0x1d79663d687610ee, 0x2b6ecd71df57190d, -0x3cbc37a813368f30, 0x5b1d4cbc434d3ac5 },\n        { 0x72b43d6cb89b75fe, 0x54c694d99c6adc80, -0x473c55c8c11cb361, 0x14b4622b39075364 },\n        { -0x4904d9ea33f560da, 0x3a4f0e2bb88dcce5, 0x1301498b3369a705, 0x2f98f71258592dd1 }\n    },\n    {\n        { 0x2e12ae444f54a701, -0x0301c10f56342822, -0x314076f28a7ca220, 0x1d8062e9e7614554 },\n        { 0x0c94a74cb50f9e56, 0x5b1ff4a98e8e1320, -0x65d533de7dcff099, 0x3a6ae249d806aaf9 },\n        { 0x657ada85a9907c5a, 0x1a0ea8b591b90f62, -0x72f1e20420cb4b17, 0x298b8ce8aef25ff3 }\n    },\n    {\n        { -0x7c858d15f5de9a22, 0x3fab07b40bcf79f6, 0x521636c77738ae70, 0x6ba6271803a7d7dc },\n        { 0x2a927953eff70cb2, 0x4b89c92a79157076, -0x6be7ba85cf583096, 0x34b8a8404d5ce485 },\n        { -0x3d91134a7c96cccb, -0x2a57ec209c4a0103, -0x5d6c55655b4dda8d, 0x71d62bdd465e1c6a }\n    },\n    {\n        { -0x32d24a254e08a10b, -0x28806a30e94f9a0b, 0x14571fea3f49f085, 0x1c333621262b2b3d },\n        { 0x6533cc28d378df80, -0x0924bc86f5f05b4c, -0x1c9ba00608fe25a6, 0x74d5f317f3172ba4 },\n        { -0x57901aab9826357f, 0x398b7c752b298c37, -0x2592f76d1c539dc5, 0x4aebcc4547e9d98c }\n    },\n},\n{\n    {\n        { 0x0de9b204a059a445, -0x1ea34b55b4e852f1, -0x1e4413ade0863aa9, 0x2633f1b9d071081b },\n        { 0x53175a7205d21a77, -0x4f3fbbdd2c46cb2c, -0x52260db422a21524, 0x074f46e69f10ff8c },\n        { -0x3e04be88fe7466f0, -0x5915df2393f01ec0, -0x299e0c18bcab3901, 0x5ecb72e6f1a3407a }\n    },\n    {\n        { -0x01151ef917179669, -0x679ccc80672f6c7d, -0x6b8fb7f155f91411, 0x038b6898d4c5c2d0 },\n        { -0x5aea5ce4dda604b2, 0x0960f3972bcac52f, -0x124ad01372cbab35, 0x382e2720c476c019 },\n        { -0x0c6e3ae27531af5a, 0x3142d0b9ae2d2948, -0x24b2a5e580db3580, 0x21aeba8b59250ea8 }\n    },\n    {\n        { 0x53853600f0087f23, 0x4c461879da7d5784, 0x6af303deb41f6860, 0x0a3c16c5c27c18ed },\n        { 0x24f13b34cf405530, 0x3c44ea4a43088af7, 0x5dd5c5170006a482, 0x118eb8f8890b086d },\n        { 0x17e49c17cc947f3d, -0x33391259553e2d85, -0x209f6d314f0f71aa, 0x4909b3e22c67c36b }\n    },\n    {\n        { 0x59a16676706ff64e, 0x10b953dd0d86a53d, 0x5848e1e6ce5c0b96, 0x2d8b78e712780c68 },\n        { -0x63637a159c01d177, -0x41e4506ef16bed14, -0x7084557579040185, 0x0fb17f9fef968b6c },\n        { 0x79d5c62eafc3902b, 0x773a215289e80728, -0x3c7519bf1efedf47, 0x09ae23717b2b1a6d }\n    },\n    {\n        { 0x10ab8fa1ad32b1d0, -0x165312e41d8874dc, -0x577a943fc8c216f1, 0x66f35ddddda53996 },\n        { -0x4495e6d5b1b2f7c4, 0x34ace0630029e192, -0x67dba5a655054515, 0x6d9c8a9ada97faac },\n        { -0x2d826504db668cdd, 0x1bb7e07ef6f01d2e, 0x2ba7472df52ecc7f, 0x03019b4f646f9dc8 }\n    },\n    {\n        { -0x50f64deb194c2395, 0x3f7573b5ad7d2f65, -0x2fe62677eff5dc50, 0x392b63a58b5c35f7 },\n        { 0x04a186b5565345cd, -0x111899ef433bee96, 0x689c73b478fb2a45, 0x387dcbff65697512 },\n        { 0x4093addc9c07c205, -0x3a9a41ea0acd3c82, 0x63dbecfd1583402a, 0x61722b4aef2e032e }\n    },\n    {\n        { -0x294f85aa7e34f1c4, 0x290ff006d9444969, 0x08680b6a16dcda1f, 0x5568d2b75a06de59 },\n        { 0x0012aafeecbd47af, 0x55a266fb1cd46309, -0x0dfc1497f69838d4, 0x39633944ca3c1429 },\n        { -0x72f34773e4c8301f, 0x05b6a5a3053818f3, -0x0d1643fb487826a7, 0x6beba1249add7f64 }\n    },\n    {\n        { 0x5c3cecb943f5a53b, -0x633659e2f93f720e, -0x30459c657a76abb9, 0x5a845ae80df09fd5 },\n        { 0x1d06005ca5b1b143, 0x6d4c6bb87fd1cda2, 0x6ef5967653fcffe7, 0x097c29e8c1ce1ea5 },\n        { 0x4ce97dbe5deb94ca, 0x38d0a4388c709c48, -0x3bc1312b5e962f69, 0x0a1249fff7e587c3 }\n    },\n},\n{\n    {\n        { 0x0b408d9e7354b610, -0x7f94cdaca457a492, -0x2419c5fcb5a75df9, 0x173bd9ddc9a1df2c },\n        { 0x12f0071b276d01c9, -0x1847453a793b7390, 0x5308129b71d6fba9, 0x5d88fbf95a3db792 },\n        { 0x2b500f1efe5872df, 0x58d6582ed43918c1, -0x1912d8713698c520, 0x06e1cd13b19ea319 }\n    },\n    {\n        { 0x472baf629e5b0353, 0x3baa0b90278d0447, 0x0c785f469643bf27, 0x7f3a6a1a8d837b13 },\n        { 0x40d0ad516f166f23, 0x118e32931fab6abe, 0x3fe35e14a04d088e, 0x3080603526e16266 },\n        { -0x0819bbc6a2c27ff5, -0x6a572aaa36fe120a, 0x68cd7830592c6339, 0x30d0fded2e51307e }\n    },\n    {\n        { -0x634b68e19747b8b0, -0x5f6a8dd6999b4431, 0x5c8de72672fa412b, 0x4615084351c589d9 },\n        { -0x1fa6b2e50dedcc4d, 0x1bdbe78ef0cc4d9c, 0x6965187f8f499a77, 0x0a9214202c099868 },\n        { -0x436fe63f51465fd2, 0x55c7110d16034cae, 0x0e6df501659932ec, 0x3bca0d2895ca5dfe }\n    },\n    {\n        { -0x639771496133fe41, -0x0f437c5259bb7691, -0x35d26aa0a085601e, 0x4ea8b4038df28241 },\n        { 0x40f031bc3c5d62a4, 0x19fc8b3ecff07a60, -0x67e7c25decf04abb, 0x5631deddae8f13cd },\n        { 0x2aed460af1cad202, 0x46305305a48cee83, -0x6ede88bab60ee5a1, 0x24ce0930542ca463 }\n    },\n    {\n        { 0x3fcfa155fdf30b85, -0x2d08e971c9c8d15c, -0x4d1f9b219b6d07bc, 0x549928a7324f4280 },\n        { 0x1fe890f5fd06c106, -0x4a3b97caa277ef0e, -0x7d87f701917350c2, 0x41d4e3c28a06d74b },\n        { -0x0d91cd589c11e5d2, -0x516e1b482da00216, -0x43c42cc42e80b297, 0x491b66dec0dcff6a }\n    },\n    {\n        { 0x75f04a8ed0da64a1, -0x12ddd350981dd7b5, -0x7dcb5c86e084845c, 0x4cf6b8b0b7018b67 },\n        { -0x670a4ec23815cd59, -0x1c2a073381e92468, -0x53f540ad340726b9, 0x08f338d0c85ee4ac },\n        { -0x3c7c57de66e58c43, -0x54d843fe20cdf386, -0x3ec2cce47b888f9d, 0x530d4a82eb078a99 }\n    },\n    {\n        { 0x6d6973456c9abf9e, 0x257fb2fc4900a880, 0x2bacf412c8cfb850, 0x0db3e7e00cbfbd5b },\n        { 0x004c3630e1f94825, 0x7e2d78268cab535a, -0x38b7dcdc337b0075, 0x65ea753f101770b9 },\n        { 0x3d66fc3ee2096363, -0x7e29d3809e4a3495, 0x0fbe044213443b1a, 0x02a4ec1921e1a1db }\n    },\n    {\n        { -0x0a379e9d0e3086a1, 0x118c861926ee57f2, 0x172124851c063578, 0x36d12b5dec067fcf },\n        { 0x5ce6259a3b24b8a2, -0x47a88533ba505f48, -0x33341917745f8fc9, 0x3d143c51127809bf },\n        { 0x126d279179154557, -0x2a1b70a30387c5f6, 0x36bdb6e8df179bac, 0x2ef517885ba82859 }\n    },\n},\n{\n    {\n        { 0x1ea436837c6da1e9, -0x063e7650e0464242, 0x303001fcce5dd155, 0x28a7c99ebc57be52 },\n        { -0x7742bc732ee1f2b6, 0x30cb610d43ccf308, -0x1f65f1c86e6c8434, 0x4559135b25b1720c },\n        { -0x47026c66172e6163, -0x6f7e6e3469dbdc01, -0x4d46b728b838bd5d, 0x37f33226d7fb44c4 }\n    },\n    {\n        { 0x33912553c821b11d, 0x66ed42c241e301df, 0x066fcc11104222fd, 0x307a3b41c192168f },\n        { 0x0dae8767b55f6e08, 0x4a43b3b35b203a02, -0x1c8da5917f507387, 0x0f7a7fd1705fa7a3 },\n        { -0x7114a2f8914aa320, 0x2fc536bfaa0d925a, -0x417e7cf023493918, 0x556c7045827baf52 }\n    },\n    {\n        { -0x46b46ffdd40bbbfa, -0x542bdc81006f4acc, 0x7600a960faf86d3a, 0x2f45abdac2322ee3 },\n        { -0x71d4ae8cfd162749, -0x1c1add96db78eb18, -0x42b04288b3569f4b, 0x6f4b4199c5ecada9 },\n        { 0x61af4912c8ef8a6a, -0x1a705b01bc0491a2, -0x4a5033a2902bd831, 0x6a5393281e1e11eb }\n    },\n    {\n        { 0x0fff04fe149443cf, 0x53cac6d9865cddd7, 0x31385b03531ed1b7, 0x5846a27cacd1039d },\n        { -0x0c25aec65a2e1177, -0x7ebaba83006c9678, 0x3f622fed00e188c4, 0x0f513815db8b5a3d },\n        { 0x4ff5cdac1eb08717, 0x67e8b29590f2e9bc, 0x44093b5e237afa99, 0x0d414bed8708b8b2 }\n    },\n    {\n        { -0x7e77956dd6b53618, 0x23162b45d55547be, -0x6b3043bbfc8ea67d, 0x50eb8fdb134bc401 },\n        { -0x30497d9a02f18a0a, -0x1ba4c1d7446f18f9, 0x7242a8de9ff92c7a, 0x685b3201933202dd },\n        { -0x3f48c139294ccf33, -0x7b1bb7f8ecd0500f, 0x732b7352c4a5dee1, 0x5d7c7cf1aa7cd2d2 }\n    },\n    {\n        { 0x33d1013e9b73a562, -0x6da310a8b713d91f, -0x580319eb22b97fa8, 0x78b0fad41e9aa438 },\n        { -0x50c4b94085b5505e, -0x4878fa13b2bf2bef, 0x114f0c6aca7c15e3, 0x3f364faaa9489d4d },\n        { -0x40a95bce12fa4b78, -0x5acc199363b6a382, -0x179ad450780c9ae6, 0x0241800059d66c33 }\n    },\n    {\n        { 0x28350c7dcf38ea01, 0x7c6cdbc0b2917ab6, -0x531830417a8f7d09, 0x4d2845aba2d9a1e0 },\n        { -0x314f88015c85a41c, -0x249bd0fd1a5a1149, -0x3d192f3ab8ed8f48, 0x4771b65538e4529c },\n        { -0x44ac801fbb8f8f22, -0x3458bbbc922aa821, -0x2c4a5cb8c9ff2435, 0x4aeabbe6f9ffd7f8 }\n    },\n    {\n        { 0x6a2134bcc4a9c8f2, -0x040702e37531d1c9, 0x000ae3049911a0ba, 0x046e3a616bc89b9e },\n        { 0x4630119e40d8f78c, -0x5fe5643ac38ef1ef, 0x486d2b258910dd79, 0x1e6c47b3db0324e5 },\n        { 0x14e65442f03906be, 0x4a019d54e362be2a, 0x68ccdfec8dc230c7, 0x7cfb7e3faf6b861c }\n    },\n},\n{\n    {\n        { -0x69114004cfa4d0af, -0x2c06c752776a6948, -0x0f0ad238b92a22db, 0x57968290bb3a0095 },\n        { 0x4637974e8c58aedc, -0x4610dd04540fbe5c, -0x1e7a26a9167f8e76, 0x2f1b78fab143a8a6 },\n        { -0x08e547bcf5df1eff, -0x0c6c9a72db0f13b9, -0x308af657911d112f, 0x7dc43e35dc2aa3e1 }\n    },\n    {\n        { 0x5a782a5c273e9718, 0x3576c6995e4efd94, 0x0f2ed8051f237d3e, 0x044fb81d82d50a99 },\n        { -0x7a69999a7782263d, -0x36f064ceb44facab, -0x391f720710df864f, 0x7ef72016758cc12f },\n        { -0x3e20e73a56f81c27, 0x57b3371dce4c6359, -0x358fbacb4dfe44b7, 0x7f79823f9c30dd2e }\n    },\n    {\n        { 0x6a9c1ff068f587ba, 0x0827894e0050c8de, 0x3cbf99557ded5be7, 0x64a9b0431c06d6f0 },\n        { -0x7ccb2dc65c4aec18, -0x3ec98f2b46e05728, 0x12b54136f590bd33, 0x0a4e0373d784d9b4 },\n        { 0x2eb3d6a15b7d2919, -0x4f4b095f2ac57dcb, 0x7156ce4389a45d47, 0x071a7d0ace18346c }\n    },\n    {\n        { -0x33f3caaddf1ebbcf, 0x0d65950709b15141, -0x650a9de4df62a0ca, 0x7c69bcf7617755d3 },\n        { -0x2cf8d255377845f5, 0x01262905bfa562ee, -0x30abcffd3f108975, 0x2c3bcc7146ea7e9c },\n        { 0x07f0d7eb04e8295f, 0x10db18252f50f37d, -0x16ae565ce8e86729, 0x6f5a9a7322aca51d }\n    },\n    {\n        { -0x18d62b145c26bb42, -0x7261f6bf7f875062, 0x4525567a47869c03, 0x02ab9680ee8d3b24 },\n        { -0x745efff3d0be393b, -0x3b60863ef3010465, 0x4efa47703cc51c9f, 0x494e21a2e147afca },\n        { -0x105b757a221af266, 0x219a224e0fb9a249, -0x05f6e0e226e10927, 0x6b5d76cbea46bb34 }\n    },\n    {\n        { -0x1f06bee8e187dade, -0x0e19518bfc96c92d, 0x408b3ea2d0fcc746, 0x16fb869c03dd313e },\n        { -0x77a8aa9313f3266c, 0x6472dc6f5cd01dba, -0x50fe96eb70bd4b89, 0x0ae333f685277354 },\n        { 0x288e199733b60962, 0x24fc72b4d8abe133, 0x4811f7ed0991d03e, 0x3f81e38b8f70d075 }\n    },\n    {\n        { 0x0adb7f355f17c824, 0x74b923c3d74299a4, -0x2a83c17434071509, 0x0ad3e2d34cdedc3d },\n        { 0x7f910fcc7ed9affe, 0x545cb8a12465874b, -0x57c6812db4f3b8fc, 0x50510fc104f50993 },\n        { 0x6f0c0fc5336e249d, 0x745ede19c331cfd9, -0x0d2902fff61101e4, 0x127c158bf0fa1ebe }\n    },\n    {\n        { -0x215d703b51ae468c, 0x1d9973d3744dfe96, 0x6240680b873848a8, 0x4ed82479d167df95 },\n        { -0x09e683bdd167865e, -0x5bb5222bad35c9b9, -0x64bec03eb4b15335, 0x354ef87d07ef4f68 },\n        { -0x011c4add9f3a268b, 0x50352efceb41b0b8, -0x77f753cf56099ac4, 0x302d92d20539236d }\n    },\n},\n{\n    {\n        { -0x6a847474f20ac3d0, 0x2a1c770a8e60f098, -0x4438598fcba86922, 0x22a48f9a90c99bc9 },\n        { 0x4c59023fcb3efb7c, 0x6c2fcb99c63c2a94, -0x45be6f1d3c381f7c, 0x0e545daea51874d9 },\n        { 0x6b7dc0dc8d3fac58, 0x5497cd6ce6e42bfd, 0x542f7d1bf400d305, 0x4159f47f048d9136 }\n    },\n    {\n        { 0x748515a8bbd24839, 0x77128347afb02b55, 0x50ba2ac649a2a17f, 0x060525513ad730f1 },\n        { 0x20ad660839e31e32, -0x07e1e42a7bfa41b0, -0x07f9bfa90b254397, 0x14d23dd4ce71b975 },\n        { -0x0dc671f6755d807e, 0x6d7982bb89a1b024, -0x0596bf7bdeb22db4, 0x71ab966fa32301c3 }\n    },\n    {\n        { -0x4ef775f8fd7f66ab, 0x43b273ea0b43c391, -0x3564985101f97913, 0x605eecbf8335f4ed },\n        { 0x2dcbd8e34ded02fc, 0x1151f3ec596f22aa, -0x435daabcb1fcd726, 0x35768fbe92411b22 },\n        { -0x7cdff59a93cbfbcf, -0x60328e98711a63d1, 0x75d4613f71300f8a, 0x7a912faf60f542f9 }\n    },\n    {\n        { 0x253f4f8dfa2d5597, 0x25e49c405477130c, 0x00c052e5996b1102, 0x33cb966e33bb6c4a },\n        { -0x4dfba7a1a123e5bd, -0x60f1e911a76838c4, 0x5b82c0ae4e70483c, 0x624a170e2bddf9be },\n        { 0x597028047f116909, -0x7d753be3e1a9bb99, 0x70417dbde6217387, 0x721627aefbac4384 }\n    },\n    {\n        { -0x02cf6843bef4d0de, -0x0e5fa2584a3057bc, 0x61289a1def57ca74, 0x245ea199bb821902 },\n        { -0x682fc43c78c9522b, 0x2f1422afc532b130, 0x3aa68a057101bbc4, 0x4c946cf7e74f9fa7 },\n        { -0x51235996872b8808, 0x1898ba3c29117fe1, -0x308c067c8df342a8, 0x67da12e6b8b56351 }\n    },\n    {\n        { 0x2b7ef3d38ec8308c, -0x7d7028138e146b55, -0x7f83c4c93af9d543, 0x0cb64cb831a94141 },\n        { 0x7067e187b4bd6e07, 0x6e8f0203c7d1fe74, -0x6c3955d0c737a5d0, 0x76297d1f3d75a78a },\n        { 0x3030fc33534c6378, -0x469ca3a31abe179f, 0x15d9a9bed9b2c728, 0x49233ea3f3775dcb }\n    },\n    {\n        { 0x7b3985fe1c9f249b, 0x4fd6b2d5a1233293, -0x314cba6be520b29e, 0x6987ff6f542de50c },\n        { 0x629398fa8dbffc3a, -0x1ed01ad22ab24bab, -0x0c41ee20250dad6b, 0x628b140dce5e7b51 },\n        { 0x47e241428f83753c, 0x6317bebc866af997, -0x2544a4bcc2e567d7, 0x074d8d245287fb2d }\n    },\n    {\n        { 0x481875c6c0e31488, 0x219429b2e22034b4, 0x7223c98a31283b65, 0x3420d60b342277f9 },\n        { -0x7cc82632bbf403cf, 0x729d2ca1af318fd7, -0x5fbf5b5b88d3df90, 0x46002ef03a7349be },\n        { -0x055dc52150019a09, 0x78261ed45be0764c, 0x441c0a1e2f164403, 0x5aea8e567a87d395 }\n    },\n},\n{\n    {\n        { 0x2dbc6fb6e4e0f177, 0x04e1bf29a4bd6a93, 0x5e1966d4787af6e8, 0x0edc5f5eb426d060 },\n        { 0x7813c1a2bca4283d, -0x129d0f6e5e79c227, -0x513843473d97057a, 0x10e5d3b76f1cae4c },\n        { 0x5453bfd653da8e67, -0x1623e113db5609bf, -0x4078d9c4fca875dd, 0x45b46c51361cba72 }\n    },\n    {\n        { -0x3162b22275801c1c, -0x54ec9ba9899df1d0, 0x4b594f7bb30e9958, 0x5c1c0aef321229df },\n        { -0x56bfd540ceb0805f, -0x1da80e2371730bb0, 0x1dbbd54b23a8be84, 0x2177bfa36dcb713b },\n        { 0x37081bbcfa79db8f, 0x6048811ec25f59b3, 0x087a76659c832487, 0x4ae619387d8ab5bb }\n    },\n    {\n        { 0x61117e44985bfb83, -0x031fb9d58e69ceca, -0x7c53cbb72bda6fb5, 0x75685abe5ba43d64 },\n        { -0x72240955acbb5cd2, 0x7d88eab4b41b4078, 0x5eb0eb974a130d60, 0x1a00d91b17bf3e03 },\n        { 0x6e960933eb61f2b2, 0x543d0fa8c9ff4952, -0x208d8aef85099a97, 0x135529b623b0e6aa }\n    },\n    {\n        { -0x0a38e9431dd17c02, -0x4bd414e617f67a3f, -0x136259c8ebdab552, 0x5972ea051590a613 },\n        { 0x18f0dbd7add1d518, -0x68608777303ee0ef, -0x78cd1e0f8eeb8a65, 0x79b5b81a65ca3a01 },\n        { 0x0fd4ac20dc8f7811, -0x65652d6b53b2b058, -0x3fe4d29b4cc9fbcc, 0x4f7e9c95905f3bdb }\n    },\n    {\n        { 0x71c8443d355299fe, -0x7432c4e324141529, -0x7f6db6610e5b6b9a, 0x1942eec4a144adc8 },\n        { 0x62674bbc5781302e, -0x27adf0c6765223f1, -0x73d66651ac04263a, 0x31993ad92e638e4c },\n        { 0x7dac5319ae234992, 0x2c1b3d910cea3e92, 0x553ce494253c1122, 0x2a0a65314ef9ca75 }\n    },\n    {\n        { -0x30c9e532c3e386c6, 0x2f9ebcac5a35bc3b, 0x60e860e9a8cda6ab, 0x055dc39b6dea1a13 },\n        { 0x2db7937ff7f927c2, -0x248be0f9e82f59cb, 0x5982f3a21155af76, 0x4cf6e218647c2ded },\n        { -0x4ee6dd833d72a44a, 0x07e24ebc774dffab, -0x57c387311b5cd377, 0x121a307710aa24b6 }\n    },\n    {\n        { -0x29a68ec1388b7c37, -0x77401f8847d46951, 0x289e28231097bcd3, 0x527bb94a6ced3a9b },\n        { -0x1b24a2a160fcb569, -0x1eac03f6cfcb43d3, 0x460546919551d3b1, 0x333fc76c7a40e52d },\n        { 0x563d992a995b482e, 0x3405d07c6e383801, 0x485035de2f64d8e5, 0x6b89069b20a7a9f7 }\n    },\n    {\n        { 0x4082fa8cb5c7db77, 0x068686f8c734c155, 0x29e6c8d9f6e7a57e, 0x0473d308a7639bcf },\n        { -0x7ed55fbe9d8fddf3, -0x66a5760506dba4b2, -0x00523b31af8d10fb, 0x23bc2103aa73eb73 },\n        { -0x351186d9fca761fb, 0x2b4b421246dcc492, 0x02a1ef74e601a94f, 0x102f73bfde04341a }\n    },\n},\n{\n    {\n        { 0x358ecba293a36247, -0x5070679d4d97029b, 0x412f7e9968a01c89, 0x5786f312cd754524 },\n        { -0x4a5d2af3813df2c2, -0x39b422915f368d9d, 0x56e89052c1ff734d, 0x4929c6f72b2ffaba },\n        { 0x337788ffca14032c, -0x0c6defd7bb80e11d, -0x74ebf8e0dce43353, 0x4c817b4bf2344783 }\n    },\n    {\n        { 0x413ba057a40b4484, -0x45b3d1e5b0a095bd, 0x614ba0a5aee1d61c, 0x78a1531a8b05dc53 },\n        { 0x0ff853852871b96e, -0x1ec160549f3c0e45, -0x1102a6acdacbbbfe, 0x0a37c37075b7744b },\n        { 0x6cbdf1703ad0562b, -0x7130b7cf36dade5d, -0x25142cfc027bdb19, 0x72ad82a42e5ec56f }\n    },\n    {\n        { -0x3c976c6e98fdb43d, -0x71962e92b6afd026, -0x030d13c31ba0b4d7, 0x065f669ea3b4cbc4 },\n        { 0x3f9e8e35bafb65f6, 0x39d69ec8f27293a1, 0x6cb8cd958cf6a3d0, 0x1734778173adae6d },\n        { -0x75ff5138aacd24b3, -0x47965b1bbc1ce44f, 0x4a0f8552d3a7f515, 0x19adeb7c303d7c08 }\n    },\n    {\n        { -0x62fa4582bc3ce86c, 0x2470c8ff93322526, -0x7cdc2137e9e68bc8, 0x2852709881569b53 },\n        { -0x38df349eac15265d, 0x55b2c97f512b636e, -0x4e1ca4a02bfd6f4f, 0x2fd9ccf13b530ee2 },\n        { 0x07bd475b47f796b8, -0x2d384fecabd370ac, 0x2dbd23f43b24f87e, 0x6551afd77b0901d6 }\n    },\n    {\n        { 0x68a24ce3a1d5c9ac, -0x44885cc2ef009b9f, 0x0f86ce4425d3166e, 0x56507c0950b9623b },\n        { 0x4546baaf54aac27f, -0x090990134d5ba5d8, 0x582d1b5b562bcfe8, 0x44b123f3920f785f },\n        { 0x1206f0b7d1713e63, 0x353fe3d915bafc74, 0x194ceb970ad9d94d, 0x62fadd7cf9d03ad3 }\n    },\n    {\n        { 0x3cd7bc61e7ce4594, -0x3294ca564822d982, -0x5f7f5437bc9910d9, 0x6ec7c46f59c79711 },\n        { -0x394a6984aa675f8c, 0x5efe91ce8e493e25, -0x2b48d3bab6d7f778, 0x20ef1149a26740c2 },\n        { 0x2f07ad636f09a8a2, -0x79681931dbdfa183, -0x3f5103fa11ca5ec7, 0x15e80958b5f9d897 }\n    },\n    {\n        { 0x4dd1ed355bb061c4, 0x42dc0cef941c0700, 0x61305dc1fd86340e, 0x56b2cc930e55a443 },\n        { 0x25a5ef7d0c3e235b, 0x6c39c17fbe134ee7, -0x388b1ecbd23a3cd9, 0x021354b892021f39 },\n        { 0x1df79da6a6bfc5a2, 0x02f3a2749fde4369, -0x4cdc260d325c6f59, 0x7be0847b8774d363 }\n    },\n    {\n        { 0x1466f5af5307fa11, -0x7e8033821293f50e, 0x0a6de44ec3a4a3fb, 0x74071475bc927d0b },\n        { -0x736633a574c0aa3d, 0x0611d7253fded2a0, -0x12d66a00c948f5ca, 0x1f699a54d78a2619 },\n        { -0x188d6d0c8c181576, 0x296537d2cb045a31, 0x1bd0653ed3274fde, 0x2f9a2c4476bd2966 }\n    },\n},\n{\n    {\n        { -0x5d4b251f4aaee366, 0x7ac860292bffff06, -0x67e0c8a20aafbdcc, 0x3f6bd725da4ea12d },\n        { -0x14e7465480a8ba3a, 0x023a8aee5787c690, -0x48d8ed25d2085057, 0x36597d25ea5c013d },\n        { 0x734d8d7b106058ac, -0x26bfa86190396fa1, 0x6466f8f99202932d, 0x7b7ecc19da60d6d0 }\n    },\n    {\n        { 0x6dae4a51a77cfa9b, -0x7dd9c9ab185c79b0, 0x09bbffcd8f2d82db, 0x03bedc661bf5caba },\n        { 0x78c2373c695c690d, -0x22dad199f9bd6f92, -0x6ae2bbbbb51ed42e, 0x4235ad7601743956 },\n        { 0x6258cb0d078975f5, 0x492942549189f298, -0x5f354bdc1d1c911c, 0x0e7ce2b0cdf066a1 }\n    },\n    {\n        { -0x0159012026b48f07, -0x0ecf3fae3e0345d3, 0x4882d47e7f2fab89, 0x615256138aeceeb5 },\n        { -0x3b6b9bc53b737a5d, -0x02c9e20bc39ec653, 0x09db17dd3ae94d48, 0x666e0a5d8fb4674a },\n        { 0x2abbf64e4870cb0d, -0x329a430f55ba7495, -0x6541b1458a1767a3, 0x7f0bc810d514dee4 }\n    },\n    {\n        { -0x7c5362528c8dec60, -0x60090745d108d168, 0x311e2edd43ec6957, 0x1d3a907ddec5ab75 },\n        { -0x46ff945bd90bec91, -0x7298c961a81fcfcb, -0x34372026b0b9c3d8, 0x0d1f8dbcf8eedbf5 },\n        { -0x45e96ccec12f7e24, 0x29329fad851b3480, 0x0128013c030321cb, 0x00011b44a31bfde3 }\n    },\n    {\n        { 0x16561f696a0aa75c, -0x3e408da3a7ad4296, 0x11a8dd7f9a7966ad, 0x63d988a2d2851026 },\n        { 0x3fdfa06c3fc66c0c, 0x5d40e38e4dd60dd2, 0x7ae38b38268e4d71, 0x3ac48d916e8357e1 },\n        { 0x00120753afbd232e, -0x16d431470227097d, -0x07e9964c7b18d46f, 0x33fad52b2368a066 }\n    },\n    {\n        { -0x72d3372f3bdd3018, 0x072b4f7b05a13acb, -0x5c01491913095a91, 0x3cc355ccb90a71e2 },\n        { 0x540649c6c5e41e16, 0x0af86430333f7735, -0x4d53032d0cfa18ba, 0x16c0f429a256dca7 },\n        { -0x16496bbc6fc16ecf, -0x475b6b3485a9c832, -0x37832e5b45456dbc, 0x631eaf426bae7568 }\n    },\n    {\n        { 0x47d975b9a3700de8, 0x7280c5fbe2f80552, 0x53658f2732e45de1, 0x431f2c7f665f80b5 },\n        { -0x4c16fbef25990161, -0x7a22b4ad93e91a5a, -0x43c2689ee106407d, 0x5599648b1ea919b5 },\n        { -0x29fd9cbb7a7084e7, 0x14ab352fa1ea514a, -0x76ffbbe5df6f5629, 0x7b04715f91253b26 }\n    },\n    {\n        { -0x4c893d7f3b19453a, -0x68f12c2292e264f5, -0x4f656aa7baf406bc, 0x48d0acfa57cde223 },\n        { -0x7c1242d7530951bd, -0x79ca837482a3854c, -0x3fbfb8964814d3bc, 0x59b37bf5c2f6583f },\n        { -0x49f0d91b8254198f, -0x0e2e5e689dd0c5c9, 0x4208ce7ee9960394, 0x16234191336d3bdb }\n    },\n},\n{\n    {\n        { -0x7ad22e02c2a87442, 0x2b65ce72c3286108, 0x658c07f4eace2273, 0x0933f804ec38ab40 },\n        { -0x0e651538cc59c511, 0x2c7fba5d4442454e, 0x5da87aa04795e441, 0x413051e1a4e0b0f5 },\n        { -0x5854968672b69b8a, -0x7ede5521034a5438, -0x5a23ed1084ac6b8e, 0x07fd47065e45351a }\n    },\n    {\n        { 0x304211559ae8e7c3, -0x0d7e4dd66bb77d5b, -0x75ec53d1c87daf1c, 0x014afa0954ba48f4 },\n        { -0x37a7c3c2da72d433, 0x17029a4daf60b73f, -0x05f03629be95c87f, 0x1c1e5fba38b3fb23 },\n        { -0x34ce68ffe44c9994, 0x330060524bffecb9, 0x293711991a88233c, 0x291884363d4ed364 }\n    },\n    {\n        { -0x0462c83c43e54915, 0x02be14534d57a240, -0x0b28cbea075a1e0a, 0x5964f4300ccc8188 },\n        { 0x033c6805dc4babfa, 0x2c15bf5e5596ecc1, 0x1bc70624b59b1d3b, 0x3ede9850a19f0ec5 },\n        { -0x1bb5dcead2f69800, 0x5c08c55970866996, -0x20d249f5b9500492, 0x579155c1f856fd89 }\n    },\n    {\n        { -0x4a0e949cf7e8185a, -0x7f7396dcc3caefda, 0x324a983b54cef201, 0x53c092084a485345 },\n        { -0x69cdb122ed1f3611, 0x468b878df2420297, 0x199a3776a4f573be, 0x1e7fbcf18e91e92a },\n        { -0x2d2beb7e0e345041, 0x231d2db6716174e5, 0x0b7d7656e2a55c98, 0x3e955cd82aa495f6 }\n    },\n    {\n        { -0x54c60c109e44c5c1, -0x714bff9ad146e6c2, -0x4a219133c73ee08c, 0x654d7e9626f3c49f },\n        { -0x1b70aca1c12eabcd, -0x2f8a96d5f28d8f5d, 0x40fbd21daade6387, 0x14264887cf4495f5 },\n        { -0x1a9b3022a382d315, -0x7d11502128c83347, 0x6107db62d1f9b0ab, 0x0b6baac3b4358dbb }\n    },\n    {\n        { 0x204abad63700a93b, -0x41ffdc2c25886c8d, -0x27a0fcb99cc548f7, 0x00496dc490820412 },\n        { 0x7ae62bcb8622fe98, 0x47762256ceb891af, 0x1a5a92bcf2e406b4, 0x7d29401784e41501 },\n        { 0x1c74b88dc27e6360, 0x074854268d14850c, -0x5eba0484c1f234d0, 0x10843f1b43803b23 }\n    },\n    {\n        { -0x2a9098d21cdb9765, -0x2e2575124c6b567f, -0x2284a7016e973013, 0x7ce246cd4d56c1e8 },\n        { -0x3a06fbaac89d8923, -0x31a6ea72289ba327, -0x6d09a2aee2c994c7, 0x11574b6e526996c4 },\n        { -0x470bcf71807f41ad, 0x5f3cb8cb34a9d397, 0x18a961bd33cc2b2c, 0x710045fb3a9af671 }\n    },\n    {\n        { -0x5fc0379dfa629662, 0x2370cfa19a619e69, -0x3b01c4edd07dc215, 0x1d1b056fa7f0844e },\n        { 0x73f93d36101b95eb, -0x0510cc86b090bb7a, 0x5651735f8f15e562, 0x7fa3f19058b40da1 },\n        { 0x1bc64631e56bf61f, -0x2c8654ef91ac7d5d, 0x4d58c57e0540168d, 0x566256628442d8e4 }\n    },\n},\n{\n    {\n        { -0x22b66329e00c79c0, 0x29cd9bc3063625a0, 0x51e2d8023dd73dc3, 0x4a25707a203b9231 },\n        { -0x461b662109d9800a, 0x7772ca7b742c0843, 0x23a0153fe9a4f2b1, 0x2cdfdfecd5d05006 },\n        { 0x2ab7668a53f6ed6a, 0x304242581dd170a1, 0x4000144c3ae20161, 0x5721896d248e49fc }\n    },\n    {\n        { 0x285d5091a1d0da4e, 0x4baa6fa7b5fe3e08, 0x63e5177ce19393b3, 0x03c935afc4b030fd },\n        { 0x0b6e5517fd181bae, -0x6fdd9d60d4469c4c, 0x5509bce932064625, 0x578edd74f63c13da },\n        { -0x668d8939b6d4f3c3, 0x47ccc2c4dfe205fc, -0x232d647b229dc5c4, 0x3ec2ab590288c7a2 }\n    },\n    {\n        { -0x58dec5f651cd2e35, 0x0f2b87df40f5c2d5, 0x0baea4c6e81eab29, 0x0e1bf66c6adbac5e },\n        { -0x5e5f2d841b278447, -0x5674b2149ec6e513, -0x665f222f8c34647d, 0x2dd5c25a200fcace },\n        { -0x1d542a1686d37782, 0x1a020018cb926d5d, -0x404596324551a0e2, 0x730548b35ae88f5f }\n    },\n    {\n        { -0x7fa4f6b45e291ccc, -0x40c10e88f6cac0e7, 0x423f06cb0622702b, 0x585a2277d87845dd },\n        { -0x3bcaae5c34574712, 0x65a26f1db2115f16, 0x760f4f52ab8c3850, 0x3043443b411db8ca },\n        { -0x5e75a07dcc2b769e, 0x6698c4b5ec78257f, -0x5871905ac8c1be01, 0x7656278950ef981f }\n    },\n    {\n        { -0x1e8f8c5c15793063, 0x3a8cfbb707155fdc, 0x4853e7fc31838a8e, 0x28bbf484b613f616 },\n        { 0x38c3cf59d51fc8c0, -0x64122d02faf9490e, 0x26bf109fab570e8f, 0x3f4160a8c1b846a6 },\n        { -0x0d9ed0a390ec9384, -0x50152ef80922ee42, 0x527e9ad213de6f33, 0x1e79cb358188f75d }\n    },\n    {\n        { 0x77e953d8f5e08181, -0x7b5af3bbd6622127, -0x2393d2f379bada1b, 0x478ab52d39d1f2f4 },\n        { 0x013436c3eef7e3f1, -0x7d7495800161ef08, 0x7ff908e5bcf9defc, 0x65d7951b3a3b3831 },\n        { 0x66a6a4d39252d159, -0x1a221e4378e537f9, -0x47d394bf593e3691, 0x16d87a411a212214 }\n    },\n    {\n        { -0x045b2a1d2ab1fa7d, -0x1de05028d1426606, 0x497ac2736ee9778f, 0x1f990b577a5a6dde },\n        { -0x4c4281a5bdf99deb, -0x78641c32f3a5db3f, 0x57c05db1d6f994b7, 0x28f87c8165f38ca6 },\n        { -0x5ccbb152e417082a, 0x7d1e50ebacea798f, 0x77c6569e520de052, 0x45882fe1534d6d3e }\n    },\n    {\n        { -0x275366d66bc3901c, -0x4a060e9e5c7c6d5e, 0x2699db13bec89af3, 0x7dcf843ce405f074 },\n        { 0x6669345d757983d6, 0x62b6ed1117aa11a6, 0x7ddd1857985e128f, 0x688fe5b8f626f6dd },\n        { 0x6c90d6484a4732c0, -0x2adebc0235a9cd67, -0x4c41d73c6ea2391f, 0x6739687e7327191b }\n    },\n},\n{\n    {\n        { -0x731a552f363468e1, 0x1156aaa99fd54a29, 0x41f7247015af9b78, 0x1fe8cca8420f49aa },\n        { -0x609a3a15dff7eb31, -0x7bfac91e965ce8c0, -0x74f12ec6da374b53, 0x0080dbafe936361d },\n        { 0x72a1848f3c0cc82a, 0x38c560c2877c9e54, 0x5004e228ce554140, 0x042418a103429d71 }\n    },\n    {\n        { 0x58e84c6f20816247, -0x724d4d491c90286d, -0x688e7da9e2b7b27b, 0x0822024f8632abd7 },\n        { -0x766215ae540c00a1, -0x646c5798d03d2746, 0x2c38cb97be6ebd5c, 0x114d578497263b5d },\n        { -0x4cfe448394e4135d, 0x55393f6dc6eb1375, -0x6ef2d7ef68491b15, 0x1ad4548d9d479ea3 }\n    },\n    {\n        { -0x5f901992f016012d, -0x578cc5bfe3a786f7, 0x30d14d800df98953, 0x41ce5876c7b30258 },\n        { -0x32a5825fc765b703, -0x4c705b556587c8e2, -0x392689e4d3247194, 0x35cf51dbc97e1443 },\n        { 0x59ac3bc5d670c022, -0x151983ef64ee6bfa, -0x6867420f4c87d026, 0x651e3201fd074092 }\n    },\n    {\n        { -0x5a845b5fe1035162, 0x769f4beedc308a94, -0x2e0ef114c9fc34d2, 0x4099ce5e7e441278 },\n        { -0x29c27b7c10cf3a31, 0x4cd4b4962361cc0c, -0x116f1aff5b7bd954, 0x0af51d7d18c14eeb },\n        { 0x1ac98e4f8a5121e9, 0x7dae9544dbfa2fe0, -0x7cdf55f229bcf207, 0x667282652c4a2fb5 }\n    },\n    {\n        { -0x5257491fd6b924dd, 0x1c0ce51a7b253ab7, -0x7bb737a59922b7a5, 0x7f1fc025d0675adf },\n        { -0x78b9de0b27943655, -0x4ab38441a9019016, 0x077a24257fadc22c, 0x1ab53be419b90d39 },\n        { -0x2711e4e7ce615956, 0x004d88083a21f0da, 0x3bd6aa1d883a4f4b, 0x4db9a3a6dfd9fd14 }\n    },\n    {\n        { -0x26a4ff4434488398, -0x22437b956e0e87b7, 0x7cf700aebe28d9b3, 0x5ce1285c85d31f3e },\n        { -0x73184dc44663f8ab, 0x35c5d6edc4f50f7a, 0x7e1e2ed2ed9b50c3, 0x36305f16e8934da1 },\n        { 0x31b6972d98b0bde8, 0x7d920706aca6de5b, -0x198cef076f759a61, 0x50fac2a6efdf0235 }\n    },\n    {\n        { 0x295b1c86f6f449bc, 0x51b2e84a1f0ab4dd, -0x3ffe34cf5571aae3, 0x6a28d35944f43662 },\n        { -0x0c2c560ca477f0a6, -0x1213faf324fc183e, -0x576967e0060f4e5e, 0x49a4ae2bac5e34a4 },\n        { 0x28bb12ee04a740e0, 0x14313bbd9bce8174, 0x72f5b5e4e8c10c40, 0x7cbfb19936adcd5b }\n    },\n    {\n        { -0x7186c58533c91920, -0x0605485c82a79113, 0x3a4f9692bae1f4e4, 0x1c14b03eff5f447e },\n        { -0x5cee223d947686d3, 0x1b30b4c6da512664, 0x0ca77b4ccf150859, 0x1de443df1b009408 },\n        { 0x19647bd114a85291, 0x57b76cb21034d3af, 0x6329db440f9d6dfa, 0x5ef43e586a571493 }\n    },\n},\n{\n    {\n        { -0x5992336237f3e540, -0x685fa30be4c75bca, -0x58140c416a24283a, 0x7da0b8f68d7e7dab },\n        { -0x1087dfebc7a98a5a, -0x5d9b60cf55025618, 0x4cd1eb505cdfa8cb, 0x46115aba1d4dc0b3 },\n        { -0x2bf0e6ac3c4a258a, 0x1dac6f7321119e9b, 0x03cc6021feb25960, 0x5a5f887e83674b4b }\n    },\n    {\n        { -0x6169d72c5f59bc47, -0x4a3c34ff193cdf9c, -0x64acfd7683d213ce, 0x43e37ae2d5d1c70c },\n        { -0x709cfe308f5ec2ef, -0x303147eacaf22f3c, -0x08fd682b5b435b82, 0x3669b656e44d1434 },\n        { 0x387e3f06eda6e133, 0x67301d5199a13ac0, -0x42a52707c9d9c7ef, 0x6a21e6cd4fd5e9be }\n    },\n    {\n        { -0x10bed6ed99664d1d, 0x71d30847708d1301, 0x325432d01182b0bd, 0x45371b07001e8b36 },\n        { -0x0e39e8f5cfb919a1, 0x58712a2a00d23524, 0x69dbbd3c8c82b755, 0x586bf9f1a195ff57 },\n        { -0x5924f772a10786f5, 0x5278f0dc610937e5, -0x53fcb62d9e5e9148, 0x0eafb03790e52179 }\n    },\n    {\n        { 0x5140805e0f75ae1d, -0x13fd041cd99d33d0, 0x2cebdf1eea92396d, 0x44ae3344c5435bb3 },\n        { -0x69faaa3ec8b7fbd1, 0x219a41e6820baa11, 0x1c81f73873486d0c, 0x309acc675a02c661 },\n        { -0x630d7646445abc12, -0x0c89f162a5368ebe, 0x1d82e5c64f9360aa, 0x62d5221b7f94678f }\n    },\n    {\n        { 0x7585d4263af77a3c, -0x205184ee0116ebb3, -0x5af98f7fa608e6c3, 0x14f29a5383922037 },\n        { 0x524c299c18d0936d, -0x37944a9375f3e5f4, -0x5c8afad124b579cf, 0x5c0efde4bc754562 },\n        { -0x208e8123da4d280b, 0x21f970db99b53040, -0x256dcb483c12b39e, 0x5e72365c7bee093e }\n    },\n    {\n        { 0x7d9339062f08b33e, 0x5b9659e5df9f32be, -0x5300c252e0614203, 0x70b20555cb7349b7 },\n        { 0x575bfc074571217f, 0x3779675d0694d95b, -0x65f5c8440be6e1cd, 0x77f1104c47b4eabc },\n        { -0x41aeec3aaaeed3b4, 0x6688423a9a881fcd, 0x446677855e503b47, 0x0e34398f4a06404a }\n    },\n    {\n        { 0x18930b093e4b1928, 0x7de3e10e73f3f640, -0x0bcde8258cc6a291, 0x6f8aded6ca379c3e },\n        { -0x4982dd26c1314218, 0x09b3e84127822f07, 0x743fa61fb05b6d8d, 0x5e5405368a362372 },\n        { -0x1cbfedc202484d66, 0x487b97e1a21ab291, -0x066982fd02196b62, 0x780de72ec8d3de97 }\n    },\n    {\n        { 0x671feaf300f42772, -0x708d14d5d573be56, 0x29a17fd797373292, 0x1defc6ad32b587a6 },\n        { 0x0ae28545089ae7bc, 0x388ddecf1c7f4d06, 0x38ac15510a4811b8, 0x0eb28bf671928ce4 },\n        { -0x50a441e510ae6a59, 0x148c1277917b15ed, 0x2991f7fb7ae5da2e, 0x467d201bf8dd2867 }\n    },\n},\n{\n    {\n        { 0x745f9d56296bc318, -0x66ca7f2b27ead19b, -0x4f1a4ec0a7c61632, 0x51fc2b28d43921c0 },\n        { 0x7906ee72f7bd2e6b, 0x05d270d6109abf4e, -0x72a301ba46be575c, 0x44c218671c974287 },\n        { 0x1b8fd11795e2a98c, 0x1c4e5ee12b6b6291, 0x5b30e7107424b572, 0x6e6b9de84c4f4ac6 }\n    },\n    {\n        { 0x6b7c5f10f80cb088, 0x736b54dc56e42151, -0x3d49df5a3910663c, 0x5f4c802cc3a06f42 },\n        { -0x200da031b4e21eaf, -0x27be3f381ee3bfdb, 0x2554b3c854749c87, 0x2d292459908e0df9 },\n        { -0x649a370e82f8ad26, -0x77e31cc738811800, -0x3c4aeb0fa49d061d, 0x66ed5dd5bec10d48 }\n    },\n    {\n        { -0x0f520c363435fb83, -0x7e3c4d340baad095, -0x3025eed2bb8ca06d, 0x1f23a0c77e20048c },\n        { 0x7d38a1c20bb2089d, -0x7f7ccb1e69332bee, -0x3b58f47393682ced, 0x2eacf8bc03007f20 },\n        { -0x0dcab9841a43ea90, 0x03d2d9020dbab38c, 0x27529aa2fcf9e09e, 0x0840bef29d34bc50 }\n    },\n    {\n        { -0x32ab1f9480c81b15, -0x733ea0780a169336, -0x47db744f2ca68232, 0x246affa06074400c },\n        { 0x796dfb35dc10b287, 0x27176bcd5c7ff29d, 0x7f3d43e8c7b24905, 0x0304f5a191c54276 },\n        { 0x37d88e68fbe45321, -0x79f68ab73f28afce, 0x4e9b13ef894a0d35, 0x25a83cac5753d325 }\n    },\n    {\n        { -0x60f099d6c6ad491e, 0x33db5e0e0934267b, -0x00badad429f60124, 0x06be10f5c506e0c9 },\n        { 0x10222f48eed8165e, 0x623fc1234b8bcf3a, 0x1e145c09c221e8f0, 0x7ccfa59fca782630 },\n        { 0x1a9615a9b62a345f, 0x22050c564a52fecc, -0x585d877ad743f202, 0x5e82770a1a1ee71d }\n    },\n    {\n        { -0x17fd17f5bdcc638c, 0x34175166a7fffae5, 0x34865d1f1c408cae, 0x2cca982c605bc5ee },\n        { 0x35425183ad896a5c, -0x1798c5041872ad0a, 0x2c66f25f92a35f64, 0x09d04f3b3b86b102 },\n        { -0x02d2a2cae6824192, 0x207c2eea8be4ffa3, 0x2613d8db325ae918, 0x7a325d1727741d3e }\n    },\n    {\n        { -0x132d82fe81d5f896, -0x28779760e9c9b6a2, 0x52a61af0919233e5, 0x2a479df17bb1ae64 },\n        { -0x2fc946442e92021e, -0x5dfaa8a83b6857d7, -0x71933699580ed999, 0x4d3b1a791239c180 },\n        { -0x61a11171cc24d8f0, 0x189854ded6c43ca5, -0x5be3dd3a6d8e7ec8, 0x27ad5538a43a5e9b }\n    },\n    {\n        { -0x34a5829c71b8f884, -0x7248ac9edf5e3fa7, 0x549e1e4d8bedfdcc, 0x080153b7503b179d },\n        { 0x2746dd4b15350d61, -0x2fc03437116ade49, -0x1791c9a5ec798d36, 0x510e987f7e7d89e2 },\n        { -0x2259626cf5c12c1d, 0x3d386ef1cd60a722, -0x37e852a74255b11a, 0x23be8d554fe7372a }\n    },\n},\n{\n    {\n        { -0x43e10b42a9851857, 0x3f624cb2d64498bd, -0x1bef9b2dd3e0b138, 0x2ef9c5a5ba384001 },\n        { -0x6a016e658b10b053, 0x3a827becf6a308a2, -0x69b1fe2cf65b84ff, 0x71c43c4f5ba3c797 },\n        { -0x4902920905618b33, -0x0e7d87431b50d986, -0x7daa4c2f0e1066f2, 0x5a758ca390c5f293 }\n    },\n    {\n        { -0x731f6e74e29e236c, -0x7212c9b9657ecf9a, -0x2b1957d65017552d, 0x0a738027f639d43f },\n        { -0x5d48d8ef26b9db6b, 0x3aa8c6d2d57d5003, -0x1c2bff405f4b7836, 0x2dbae244b3eb72ec },\n        { -0x67f0b5d0a8001e34, 0x00670d0de1839843, 0x105c3f4a49fb15fd, 0x2698ca635126a69c }\n    },\n    {\n        { 0x2e3d702f5e3dd90e, -0x61c0f6e71b2dac7a, 0x5e773ef6024da96a, 0x3c004b0c4afa3332 },\n        { -0x189ace77cd4f4588, 0x381831f7925cff8b, 0x08a81b91a0291fcc, 0x1fb43dcc49caeb07 },\n        { -0x6556b953f90b47d5, 0x1ca284a5a806c4f3, 0x3ed3265fc6cd4787, 0x6b43fd01cd1fd217 }\n    },\n    {\n        { -0x4a38bda7c189f10d, 0x75dc52b9ee0ab990, -0x40ebd83df8d46dc1, 0x73420b2d6ff0d9f0 },\n        { -0x3858a2b4b9683abc, 0x15fdf848df0fffbf, 0x2868b9ebaa46785a, 0x5a68d7105b52f714 },\n        { -0x50d30934617ae1fa, -0x70a6c6ec39ddc73c, -0x2575476966040c8d, 0x3db5632fea34bc9e }\n    },\n    {\n        { 0x2e4990b1829825d5, -0x12151478c165766f, -0x110fc2c6b38fb508, 0x59197ea495df2b0e },\n        { -0x0b9111d408a22628, 0x0d17b1f6396759a5, 0x1bf2d131499e7273, 0x04321adf49d75f13 },\n        { 0x04e16019e4e55aae, -0x1884bc8581d06d17, -0x3831d23e90ea655c, 0x45eafdc1f4d70cc0 }\n    },\n    {\n        { -0x49f1b9db30334e13, 0x59dbc292bd5c0395, 0x31a09d1ddc0481c9, 0x3f73ceea5d56d940 },\n        { 0x698401858045d72b, 0x4c22faa2cf2f0651, -0x6be5c99a94ddd23a, 0x5a5eebc80362dade },\n        { -0x4858402ef5b1723a, -0x41a8ff81bb364cc7, 0x60c1207f1557aefa, 0x26058891266218db }\n    },\n    {\n        { 0x4c818e3cc676e542, 0x5e422c9303ceccad, -0x13f833354bed60f8, 0x0dedfa10b24443b8 },\n        { 0x59f704a68360ff04, -0x3c26c021899e190c, -0x7ce4d58ced78caaf, 0x54ad0c2e4e615d57 },\n        { -0x11c4982a47d4add6, 0x36f163469fa5c1eb, -0x5a4b2d0d913e602d, 0x62ecb2baa77a9408 }\n    },\n    {\n        { -0x6df8d7c95049d78c, 0x5fcd5e8579e104a5, 0x5aad01adc630a14a, 0x61913d5075663f98 },\n        { -0x1a1286ad9eead4c3, 0x4962357d0eddd7d1, 0x7482c8d0b96b4c71, 0x2e59f919a966d8be },\n        { 0x0dc62d361a3231da, -0x05b8a7cd6bdffd90, 0x02d801513f9594ce, 0x3ddbc2a131c05d5c }\n    },\n},\n{\n    {\n        { -0x048ca53dffb5ca2f, 0x31de0f433a6607c3, 0x7b8591bfc528d599, 0x55be9a25f5bb050c },\n        { 0x3f50a50a4ffb81ef, -0x4e1fcaf6c40bdf41, -0x645571e33955d330, 0x32239861fa237a40 },\n        { 0x0d005acd33db3dbf, 0x0111b37c80ac35e2, 0x4892d66c6f88ebeb, 0x770eadb16508fbcd }\n    },\n    {\n        { -0x0e2c497e5faf8e47, 0x2207659a3592ff3a, 0x5f0169297881e40e, 0x16bedd0e86ba374e },\n        { -0x7bae061fa1b17623, -0x3f9cfd004386c6c9, 0x5d22749556a6495c, 0x09a6755ca05603fb },\n        { 0x5ecccc4f2c2737b5, 0x43b79e0c2dccb703, 0x33e008bc4ec43df3, 0x06c1b840f07566c0 }\n    },\n    {\n        { 0x69ee9e7f9b02805c, -0x34007d75ab82e9c0, 0x3d93a869b2430968, 0x46b7b8cd3fe26972 },\n        { 0x7688a5c6a388f877, 0x02a96c14deb2b6ac, 0x64c9f3431b8c2af8, 0x3628435554a1eed6 },\n        { -0x167edf7901811420, 0x4cba6be72f515437, 0x1d04168b516efae9, 0x5ea1391043982cb9 }\n    },\n    {\n        { 0x6f2b3be4d5d3b002, -0x5013cc2695f63780, 0x035f73a4a8bcc4cc, 0x22c5b9284662198b },\n        { 0x49125c9cf4702ee1, 0x4520b71f8b25b32d, 0x33193026501fef7e, 0x656d8997c8d2eb2b },\n        { -0x34a73701bcc276c7, -0x765f34d1957281b0, 0x79ca955309fbbe5a, 0x0c626616cd7fc106 }\n    },\n    {\n        { -0x70203c86040bab4f, 0x45a5a970f1a4b771, -0x536de108452ca6eb, 0x42d088dca81c2192 },\n        { 0x1ffeb80a4879b61f, 0x6396726e4ada21ed, 0x33c7b093368025ba, 0x471aa0c6f3c31788 },\n        { -0x7025f0c85fe9ae67, 0x0adadb77c8a0e343, 0x20fbfdfcc875e820, 0x1cf2bea80c2206e7 }\n    },\n    {\n        { -0x67d291e5fd3fbed1, -0x6f05b37c24a71702, 0x01c2f5bcdcb18bc0, 0x686e0c90216abc66 },\n        { -0x3d220e214c9dfd54, -0x6d5a01f62d1d855b, 0x7d1648f6fc09f1d3, 0x74c2cc0513bc4959 },\n        { 0x1fadbadba54395a7, -0x4be5fd5f51f25996, -0x40e60a67445c83f9, 0x6a12b8acde48430d }\n    },\n    {\n        { 0x793bdd801aaeeb5f, 0x00a2a0aac1518871, -0x175c8c5ce0dec94c, 0x48aab888fc91ef19 },\n        { -0x072515e0c62b6a27, 0x592c190e525f1dfc, -0x247342fb3666e2e5, 0x11f7fda3d88f0cb7 },\n        { 0x041f7e925830f40e, 0x002d6ca979661c06, -0x79236006d4fb95d2, 0x760360928b0493d1 }\n    },\n    {\n        { -0x4bcef71a96a5f4fb, 0x6cb00ee8ad37a38b, 0x5edad6eea3537381, 0x3f2602d4b6dc3224 },\n        { 0x21bb41c6120cf9c6, -0x154d55ed21325a65, -0x3e58d2fdf55b74cc, 0x215d4d27e87d3b68 },\n        { -0x374db849a4350e64, 0x49779dc3b1b2c652, -0x765e7f442a131d1e, 0x13f098a3cec8e039 }\n    },\n},\n{\n    {\n        { -0x0c55a85dd86944ec, -0x77c5454864f825df, -0x1ab41de7ce5fc6e4, 0x5ee7fb38d83205f9 },\n        { -0x6523f00631a13ab5, 0x039c2a6b8c2f130d, 0x028007c7f0f89515, 0x78968314ac04b36b },\n        { 0x538dfdcb41446a8e, -0x5a530256bcb6c807, 0x46af908d263c8c78, 0x61d0633c9bca0d09 }\n    },\n    {\n        { -0x525cd74307038c21, -0x117b96a2590fc804, 0x637fb4db38c2a909, 0x5b23ac2df8067bdc },\n        { 0x63744935ffdb2566, -0x3a42947687f49745, 0x6f1b3280553eec03, 0x6e965fd847aed7f5 },\n        { -0x652d46ac117fad85, -0x1770e65505219273, 0x0e711704150e82cf, 0x79b9bbb9dd95dedc }\n    },\n    {\n        { -0x2e66825171608c8c, -0x5fcd5d073044f7ea, -0x329345ed92bba0f6, 0x1ba811460accb834 },\n        { -0x144caabf95ced93e, -0x2d9c7c5797373c6d, 0x6c0c6429e5b97a82, 0x5065f158c9fd2147 },\n        { 0x708169fb0c429954, -0x1eb9ff5328913099, 0x2eaab98a70e645ba, 0x3981f39e58a4faf2 }\n    },\n    {\n        { -0x37ba205a92199022, -0x1ead5affd3bfb7c6, -0x162d1e9c384b09ce, 0x30f4452edcbc1b65 },\n        { 0x18fb8a7559230a93, 0x1d168f6960e6f45d, 0x3a85a94514a93cb5, 0x38dc083705acd0fd },\n        { -0x7a92d87d3a8a68c0, -0x05ecba9606634134, -0x77bb038c3f15b18f, 0x632d9a1a593f2469 }\n    },\n    {\n        { -0x40f602ee12f37b59, 0x63f071810d9f693a, 0x21908c2d57cf8779, 0x3a5a7df28af64ba2 },\n        { -0x094494ea47f8345a, 0x1823c7dfbc54f0d7, -0x44e268fc91d698f5, 0x0b24f48847ed4a57 },\n        { -0x23252b41aee41539, -0x5bac7f8a12d9330e, -0x1e630060ffa0659b, 0x34fcf74475481f63 }\n    },\n    {\n        { -0x5a44e25487305568, 0x5ceda267190b72f2, -0x6cf636eef56d9f72, 0x0119a3042fb374b0 },\n        { -0x3e681fb387689836, -0x478eb234c726b983, 0x55de888283f95fa8, 0x3d3bdc164dfa63f7 },\n        { 0x67a2d89ce8c2177d, 0x669da5f66895d0c1, -0x0a9a671a4d7d5d50, 0x56c088f1ede20a73 }\n    },\n    {\n        { 0x581b5fac24f38f02, -0x56f41601451cf343, -0x65de96fd75306d10, 0x038b7ea48359038f },\n        { 0x336d3d1110a86e17, -0x280c77cdf48a4d06, -0x06eacc89daf8d678, 0x09674c6b99108b87 },\n        { -0x60b107de66ce9008, 0x2f49d282eaa78d4f, 0x0971a5ab5aef3174, 0x6e5e31025969eb65 }\n    },\n    {\n        { 0x3304fb0e63066222, -0x04caf976785345c1, -0x42e6db8873ef9e5d, 0x3058ad43d1838620 },\n        { -0x4e939d0a781a6c05, 0x4999eddeca5d3e71, -0x4b6e3e1feb33c193, 0x08f5114789a8dba8 },\n        { 0x323c0ffde57663d0, 0x05c3df38a22ea610, -0x423875425366b066, 0x26549fa4efe3dc99 }\n    },\n},\n{\n    {\n        { 0x04dbbc17f75396b9, 0x69e6a2d7d2f86746, -0x39bf62660ac1543a, 0x606175f6332e25d2 },\n        { 0x738b38d787ce8f89, -0x49d9a71dbe865773, 0x30738c9cf151316d, 0x49128c7f727275c9 },\n        { 0x4021370ef540e7dd, 0x0910d6f5a1f1d0a5, 0x4634aacd5b06b807, 0x6a39e6356944f235 }\n    },\n    {\n        { 0x1da1965774049e9d, -0x0432915e6701cad5, -0x4e3432af33adc95a, 0x1f5ec83d3f9846e2 },\n        { -0x6932a9bf206f0c19, 0x6c3a760edbfa25ea, 0x24f3ef0959e33cc4, 0x42889e7e530d2e58 },\n        { -0x7104dc3ccd73348b, -0x50bd5df822789117, 0x20fbdadc5dfae796, 0x241e246b06bf9f51 }\n    },\n    {\n        { 0x7eaafc9a6280bbb8, 0x22a70f12f403d809, 0x31ce40bb1bfc8d20, 0x2bc65635e8bd53ee },\n        { 0x29e68e57ad6e98f6, 0x4c9260c80b462065, 0x3f00862ea51ebb4b, 0x5bc2c77fb38d9097 },\n        { -0x172a23605694526d, -0x1a704e8221e6b824, 0x681532ea65185fa3, 0x1fdd6c3b034a7830 }\n    },\n    {\n        { -0x63ec595ad2270857, 0x2dbb1f8c3efdcabf, -0x69e1cdbfa1f7084b, 0x48c8a121bbe6c9e5 },\n        { 0x0a64e28c55dc18fe, -0x1c206166cc661423, 0x79ac432370e2e652, 0x35ff7fc33ae4cc0e },\n        { -0x03bea583a69b9bbb, -0x2ddb4d283ed749eb, 0x6035c9c905fbb912, 0x42d7a91274429fab }\n    },\n    {\n        { -0x565b76b86cc25a44, 0x4a58920ec2e979ec, -0x69277fffec1a53b4, 0x453692d74b48b147 },\n        { 0x4e6213e3eaf72ed3, 0x6794981a43acd4e7, -0x00ab8321914af735, 0x6fed19dd10fcb532 },\n        { -0x2288a26657aa6391, -0x0bd5debf20ffc1dc, 0x5223e229da928a66, 0x063f46ba6d38f22c }\n    },\n    {\n        { 0x39843cb737346921, -0x58b804f8c7376bb9, -0x34727fce5dbacf82, 0x67810f8e6d82f068 },\n        { -0x2d2dbd76a0ac996c, -0x35cc5d3abd6c64d4, -0x67905259382246a4, 0x5a152c042f712d5d },\n        { 0x3eeb8fbcd2287db4, 0x72c7d3a301a03e93, 0x5473e88cbd98265a, 0x7324aa515921b403 }\n    },\n    {\n        { -0x52dc092517dcab35, 0x6962502ab6571a6d, -0x649ae9c91c71c82f, 0x5cac5005d1a3312f },\n        { -0x7a86bd0b93c34172, -0x5e2c9b4eb8cf3fba, 0x1c8ed914d23c41bf, 0x0838e161eef6d5d2 },\n        { -0x733eab33161c66fc, 0x5b3a040b84de6846, -0x3b2759e34e41a292, 0x40fb897bd8861f02 }\n    },\n    {\n        { -0x1a8127b8a54ef89f, 0x71435e206fd13746, 0x342f824ecd025632, 0x4b16281ea8791e7b },\n        { -0x7b3a556f9d21c85f, 0x421da5000d1d96e1, 0x788286306a9242d9, 0x3c5e464a690d10da },\n        { -0x2e3efe2af47ecc7f, -0x2119f0ee891197d8, 0x0cb68893383f6409, 0x6183c565f6ff484a }\n    },\n},\n{\n    {\n        { -0x24b97ab650c09992, -0x288030fb0eb5f15b, 0x3df23ff7a4ba0c47, 0x3a10dfe132ce3c85 },\n        { 0x741d5a461e6bf9d6, 0x2305b3fc7777a581, -0x2baa8b5d9b8b2c27, 0x1926e1dc6401e0ff },\n        { -0x1f80b17515e83160, 0x2fd515463a1fc1fd, 0x175322fd31f2c0f1, 0x1fa1d01d861e5d15 }\n    },\n    {\n        { 0x38dcac00d1df94ab, 0x2e712bddd1080de9, 0x7f13e93efdd5e262, 0x73fced18ee9a01e5 },\n        { -0x337faa6b82a667ce, 0x1e4656da37f15520, -0x6609088bb1fa6ce0, 0x773563bc6a75cf33 },\n        { 0x06b1e90863139cb3, -0x5b6c25983a5fc133, -0x72883137529c76ce, 0x1f426b701b864f44 }\n    },\n    {\n        { -0x0e81ca376e5edaae, -0x48947eaca8a1638a, -0x057cbf90f2648dc2, 0x0b76bb1b3fa7e438 },\n        { -0x1036d9b3be6ee3ff, -0x0e5c4847e85dd3db, 0x5875da6bf30f1447, 0x4e1af5271d31b090 },\n        { 0x08b8c1f97f92939b, -0x41988e342bbb5492, 0x22e5646399bb8017, 0x7b6dd61eb772a955 }\n    },\n    {\n        { 0x5730abf9ab01d2c7, 0x16fb76dc40143b18, -0x7993419a5f344d7f, 0x53fa9b659bff6afe },\n        { -0x48523e17af0cc26e, 0x7998fa4f608cd5cf, -0x5269d2427203a425, 0x703e9bceaf1d2f4f },\n        { 0x6c14c8e994885455, -0x7bc5a2999a512b1b, 0x181bb73ebcd65af1, 0x398d93e5c4c61f50 }\n    },\n    {\n        { -0x3c78839f2d181c0e, 0x3b34aaa030828bb1, 0x283e26e7739ef138, 0x699c9c9002c30577 },\n        { 0x1c4bd16733e248f3, -0x4261ed78ea40f5a1, -0x2bc0730f5ef4fc8a, 0x53b09b5ddf191b13 },\n        { -0x0cf958dca6b90e34, -0x6de8e74a331a2683, 0x28cdd24781b4e975, 0x51caf30c6fcdd907 }\n    },\n    {\n        { 0x737af99a18ac54c7, -0x6fcc87233ae34cf1, 0x2b89bc334ce10cc7, 0x12ae29c189f8e99a },\n        { -0x59f458bd898b1ff6, 0x630e8570a17a7bf3, 0x3758563dcf3324cc, 0x5504aa292383fdaa },\n        { -0x56613f34e0f2fe31, 0x0dd1efcc3a34f7ae, 0x55ca7521d09c4e22, 0x5fd14fe958eba5ea }\n    },\n    {\n        { 0x3c42fe5ebf93cb8e, -0x412057aec92ba9a1, -0x1f0f7a6177bddf18, 0x7dd73f960725d128 },\n        { -0x4a23d220d7ba54d4, 0x069491b10a7fe993, 0x4daaf3d64002e346, 0x093ff26e586474d1 },\n        { -0x4ef2db0197fa67d7, 0x75730672dbaf23e5, 0x1367253ab457ac29, 0x2f59bcbc86b470a4 }\n    },\n    {\n        { 0x7041d560b691c301, -0x7adfe4c0522818e2, 0x16c2e16311335585, 0x2aa55e3d010828b1 },\n        { -0x7c7b82bd66e8eca1, -0x52e46ee0a982fc29, 0x7e7748d9be77aad1, 0x5458b42e2e51af4a },\n        { -0x12ae6d19f3f8bbb1, 0x42c54e2d74421d10, 0x352b4c82fdb5c864, 0x13e9004a8a768664 }\n    },\n},\n{\n    {\n        { 0x1e6284c5806b467c, -0x3a09668418a29f85, -0x749826a74c872d9e, 0x3d88d66a81cd8b70 },\n        { -0x344a4aaa93fcd401, -0x208e6e48d6d685c6, -0x3e008cd952127e45, 0x71ade8bb68be03f5 },\n        { -0x7489856cdfb12877, 0x762fcacb9fa0ae2a, 0x771febcc6dce4887, 0x343062158ff05fb3 }\n    },\n    {\n        { -0x031de6f8d584ce4c, 0x4d7adc75aa578016, 0x0ec276a687479324, 0x6d6d9d5d1fda4beb },\n        { -0x1fa25e581e0a40b7, 0x26457d6dd4736092, 0x77dcb07773cc32f6, 0x0a5d94969cdd5fcd },\n        { 0x22b1a58ae9b08183, -0x026a2f8e3ea3c775, -0x567edc897af5fae9, 0x33384cbabb7f335e }\n    },\n    {\n        { 0x33bc627a26218b8d, -0x157f4de03857f39f, -0x6ba74ed4e8c1611a, 0x076247be0e2f3059 },\n        { 0x3c6fa2680ca2c7b5, 0x1b5082046fb64fda, -0x14accb63abce2922, 0x5278b38f6b879c89 },\n        { 0x52e105f61416375a, -0x136850c97a54145c, 0x26e6b50623a67c36, 0x5cf0e856f3d4fb01 }\n    },\n    {\n        { -0x415131cec24cbd58, -0x345c9ca47bd24812, -0x177399df7e80ec11, 0x1b9438aa4e76d5c6 },\n        { -0x0936978ce517354c, 0x5e20741ecb4f92c5, 0x2da53be58ccdbc3e, 0x2dddfea269970df7 },\n        { -0x75af8881e990fce6, 0x067b39f10fb7a328, 0x1925c9a6010fbd76, 0x6df9b575cc740905 }\n    },\n    {\n        { -0x13203ca4b73521bf, 0x6a88471fb2328270, 0x740a4a2440a01b6a, 0x471e5796003b5f29 },\n        { 0x42c1192927f6bdcf, -0x706e6e85bfc29e36, -0x23e3a5997461e09f, 0x1596047804ec0f8d },\n        { -0x2569444c5312c854, 0x7a2423b5e9208cea, 0x24cc5c3038aebae2, 0x50c356afdc5dae2f }\n    },\n    {\n        { -0x30126320e4ce469c, -0x0b79567a735ae50d, 0x14897265ea8c1f84, 0x784a53dd932acc00 },\n        { 0x09dcbf4341c30318, -0x1145f9ee7ce7e232, -0x3e863f3123e1d65f, 0x1dbf7b89073f35b0 },\n        { 0x2d99f9df14fc4920, 0x76ccb60cc4499fe5, -0x5becd3441a30fffd, 0x3f93d82354f000ea }\n    },\n    {\n        { -0x1553ed2e861eb688, -0x006dc00c441400a2, 0x4af663e40663ce27, 0x0fd381a811a5f5ff },\n        { -0x7e7c189761fb317b, 0x678fb71e04465341, -0x526dfa7099771254, 0x5da350d3532b099a },\n        { -0x0da953135bc920ac, 0x108b6168ae69d6e8, 0x20d986cb6b5d036c, 0x655957b9fee2af50 }\n    },\n    {\n        { -0x423ebf642ffd2f54, 0x66660245b5ccd9a6, -0x7dce823b05217a14, 0x02fe934b6ad7df0d },\n        { -0x51574f8056fdfcf1, -0x077389950b9c2ebd, 0x15b083663c787a60, 0x08eab1148267a4a8 },\n        { -0x10a30eff3048158c, 0x22897633a1cb42ac, -0x2b31f3ab310d7a1e, 0x30408c048a146a55 }\n    },\n},\n{\n    {\n        { -0x44d1ff36e6c47881, -0x131c576f1f23af95, -0x130c483fc9219b61, 0x5f46040898de9e1a },\n        { 0x739d8845832fcedb, -0x05c729365194079d, 0x32bc0dcab74ffef7, 0x73937e8814bce45e },\n        { -0x46fc8ee9d6840b73, -0x562ec4dd2b0f97cc, -0x1e68eaa8b969423a, 0x2cf8a4e891d5e835 }\n    },\n    {\n        { 0x2cb5487e17d06ba2, 0x24d2381c3950196b, -0x289a637e7a6875d0, 0x7a6f7f2891d6a4f6 },\n        { 0x6d93fd8707110f67, -0x22b3f62c83c74ab7, 0x7cb16a4cc2736a86, 0x2049bd6e58252a09 },\n        { 0x7d09fd8d6a9aef49, -0x0f119f41a4c246f5, 0x4c21b52c519ebfd4, 0x6011aadfc545941d }\n    },\n    {\n        { 0x63ded0c802cbf890, -0x042f6735f2009556, 0x624d0afdb9b6ed99, 0x69ce18b779340b1e },\n        { 0x5f67926dcf95f83c, 0x7c7e856171289071, -0x295e180c667085a5, 0x6fc5cc1b0b62f9e0 },\n        { -0x2e10aad74d678635, -0x22e551c32b816f6e, 0x127e0442189f2352, 0x15596b3ae57101f1 }\n    },\n    {\n        { 0x09ff31167e5124ca, 0x0be4158bd9c745df, 0x292b7d227ef556e5, 0x3aa4e241afb6d138 },\n        { 0x462739d23f9179a2, -0x007cedce68292231, 0x1307deb553f2148a, 0x0d2237687b5f4dda },\n        { 0x2cc138bf2a3305f5, 0x48583f8fa2e926c3, 0x083ab1a25549d2eb, 0x32fcaa6e4687a36c }\n    },\n    {\n        { 0x3207a4732787ccdf, 0x17e31908f213e3f8, -0x2a4d132809f269b2, 0x746f6336c2600be9 },\n        { 0x7bc56e8dc57d9af5, 0x3e0bd2ed9df0bdf2, -0x553feb21dd101b5d, 0x4627e9cefebd6a5c },\n        { 0x3f4af345ab6c971c, -0x1d77148d66bc8ce1, 0x33596a8a0344186d, 0x7b4917007ed66293 }\n    },\n    {\n        { 0x54341b28dd53a2dd, -0x55e86fa420bd03c1, 0x0ff592d94dd2f8f4, 0x1d03620fe08cd37d },\n        { 0x2d85fb5cab84b064, 0x497810d289f3bc14, 0x476adc447b15ce0c, 0x122ba376f844fd7b },\n        { -0x3dfdcd325d4b1aac, -0x612f02bdeea2e781, 0x2eabb4be7dd479d9, 0x02c70bf52b68ec4c }\n    },\n    {\n        { -0x531acd40ba728d1f, 0x5be768e07cb73cb5, 0x56cf7d94ee8bbde7, 0x6b0697e3feb43a03 },\n        { -0x5d7813b4a2f4d045, 0x415c5790074882ca, -0x1fbb59e13e2f7ea4, 0x26334f0a409ef5e0 },\n        { -0x49370fb5209d5c40, 0x3ef000ef076da45d, -0x636346a7b60f2d57, 0x1cc37f43441b2fae }\n    },\n    {\n        { -0x2899a90e36315147, 0x1c5b15f818e5656a, 0x26e72832844c2334, 0x3a346f772f196838 },\n        { 0x508f565a5cc7324f, -0x2f9e3b3f1af956de, -0x04e75424a3ba53e7, 0x6c6809c10380314a },\n        { -0x2d2aaeed1d259538, -0x1642fcce4e17ae13, -0x69f8b92271398d9e, 0x05911b9f6ef7c5d0 }\n    },\n},\n{\n    {\n        { 0x01c18980c5fe9f94, -0x329a98968e902a38, -0x7e9fba3c2e6a5f7a, 0x6e2b7f3266cc7982 },\n        { -0x162328a949c800d3, -0x13b3cb7036780f3c, -0x312a6d7a0c043849, 0x3305354793e1ea87 },\n        { -0x337fdb97083ca971, -0x6216457de668b34d, -0x5448dd634a47eca0, 0x44e2017a6fbeba62 }\n    },\n    {\n        { -0x7807d30c49359133, 0x580f893e18f4a0c2, 0x058930072604e557, 0x6cab6ac256d19c1d },\n        { -0x3b3d58bcab25488c, -0x71a2b3c3b150fce6, -0x4893dc2dbd7c70e9, 0x749a098f68dce4ea },\n        { -0x23201f5fd33e21a0, 0x032665ff51c5575b, 0x2c0c32f1073abeeb, 0x6a882014cd7b8606 }\n    },\n    {\n        { -0x2eee2e8350b01492, 0x050bba42b33aa4a3, 0x17514c3ceeb46c30, 0x54bedb8b1bc27d75 },\n        { -0x5ad56d015b8b804b, -0x23ed5bb6e05a5477, -0x27d256b447b85b32, 0x4d77edce9512cc4e },\n        { 0x77c8e14577e2189c, -0x5c1b909500663bbb, 0x3144dfc86d335343, 0x3a96559e7c4216a9 }\n    },\n    {\n        { 0x4493896880baaa52, 0x4c98afc4f285940e, -0x10b558645babb74a, 0x5278c510a57aae7f },\n        { 0x12550d37f42ad2ee, -0x74871ffb675e040b, 0x5d53078233894cb2, 0x02c84e4e3e498d0c },\n        { -0x5ab22f8bd6b3f46c, -0x0aa2b94720e7004a, -0x0f90133a72517c9a, 0x588657668190d165 }\n    },\n    {\n        { -0x40a7cb0fc21da33d, -0x47783751297eab6a, 0x5105221a9481e892, 0x6760ed19f7723f93 },\n        { -0x2b88edcee5108ee9, 0x50343101229e92c7, 0x7a95e1849d159b97, 0x2449959b8b5d29c9 },\n        { 0x669ba3b7ac35e160, 0x2eccf73fba842056, 0x1aec1f17c0804f07, 0x0d96bc031856f4e7 }\n    },\n    {\n        { -0x4e2acb4f338afa1f, 0x32cd003416c35288, -0x34c95a7ff89d3d63, 0x5bfe69b9237a0bf8 },\n        { 0x3318be7775c52d82, 0x4cb764b554d0aab9, -0x5430c2d83388c26f, 0x3bf4d1848123288a },\n        { 0x183eab7e78a151ab, -0x44166f3666f6c89d, -0x008e8291b5381ccb, 0x4c5cddb325f39f88 }\n    },\n    {\n        { 0x57750967e7a9f902, 0x2c37fdfc4f5b467e, -0x4d9e99c5ce8845ba, 0x3a375e78dc2d532b },\n        { -0x3f0948b29e6f5915, 0x20ea81a42db8f4e4, -0x5742908268cea8a0, 0x33b1d60262ac7c21 },\n        { -0x7ebe18d0d2b22216, -0x191501679d39f838, 0x23c28458573cafd0, 0x46b9476f4ff97346 }\n    },\n    {\n        { 0x1215505c0d58359f, 0x2a2013c7fc28c46b, 0x24a0a1af89ea664e, 0x4400b638a1130e1f },\n        { 0x0c1ffea44f901e5c, 0x2b0b6fb72184b782, -0x1a78006efeeb2478, 0x37130f364785a142 },\n        { 0x3a01b76496ed19c3, 0x31e00ab0ed327230, 0x520a885783ca15b1, 0x06aab9875accbec7 }\n    },\n},\n{\n    {\n        { 0x5349acf3512eeaef, 0x20c141d31cc1cb49, 0x24180c07a99a688d, 0x555ef9d1c64b2d17 },\n        { -0x3ecc667c0a20f145, -0x3f0c8a70aed3b354, 0x2cf1130a0bb398e1, 0x6b3cecf9aa270c62 },\n        { 0x36a770ba3b73bd08, 0x624aef08a3afbf0c, 0x5737ff98b40946f2, 0x675f4de13381749d }\n    },\n    {\n        { -0x5ed00926c4254ce3, 0x0725d80f9d652dfe, 0x019c4ff39abe9487, 0x60f450b882cd3c43 },\n        { 0x0e2c52036b1782fc, 0x64816c816cad83b4, -0x2f234226969bf8c2, 0x13d99df70164c520 },\n        { 0x014b5ec321e5c0ca, 0x4fcb69c9d719bfa2, 0x4e5f1c18750023a0, 0x1c06de9e55edac80 }\n    },\n    {\n        { -0x002ad4bf00929656, 0x34530b18dc4049bb, 0x5e4a5c2fa34d9897, 0x78096f8e7d32ba2d },\n        { -0x66f085295cc13b1e, 0x6608f938be2ee08e, -0x635ebc3a9cd7baeb, 0x4cf38a1fec2db60d },\n        { -0x5f55559af205a319, -0x063b61d5b74ab874, 0x4f09cc7d7003725b, 0x373cad3a26091abe }\n    },\n    {\n        { -0x0e41570476224453, 0x3bcb2cbc61aeaecb, -0x70a75844e0647263, 0x21547eda5112a686 },\n        { -0x4d6b9cb27d360a84, 0x1fcbfde124934536, -0x6163b24cbe7324a6, 0x0040f3d9454419fc },\n        { -0x210216c602a6792d, -0x0bd8d376aef5c7f4, -0x48d45bf844cee647, 0x63550a334a254df4 }\n    },\n    {\n        { -0x6445a7ba8dab84b7, -0x0cfa39051d3bf720, 0x60e8fa69c734f18d, 0x39a92bafaa7d767a },\n        { 0x6507d6edb569cf37, 0x178429b00ca52ee1, -0x1583ff6f149429a3, 0x3eea62c7daf78f51 },\n        { -0x62db38ec196cd8b2, 0x5f63857768dbd375, 0x70525560eb8ab39a, 0x68436a0665c9c4cd }\n    },\n    {\n        { 0x1e56d317e820107c, -0x3ad997bb7bf5169b, -0x3e1f5e39cdf00386, 0x5373669c91611472 },\n        { -0x43fdca17dfd0c0d9, -0x38a3ff1d9b068a50, -0x6e5b162a5c73dbea, 0x17b6e7f68ab789f9 },\n        { 0x5d2814ab9a0e5257, -0x6f70df7b36354c04, -0x50350a77a4d2e136, 0x1cb4b5a678f87d11 }\n    },\n    {\n        { 0x6b74aa62a2a007e7, -0x0cee1f4f0f8e384f, 0x5707e438000be223, 0x2dc0fd2d82ef6eac },\n        { -0x499b3f94c6b50394, 0x0c88de2498da5fb1, 0x4f8d03164bcad834, 0x330bca78de7434a2 },\n        { -0x67d1007beee68bb2, -0x0696a169d4f8b8dc, -0x3a753eb04036ac05, 0x3c31be1b369f1cf5 }\n    },\n    {\n        { -0x3e97436c0634bd8e, -0x51478ee038312468, 0x7f0e52aa34ac8d7a, 0x41cec1097e7d55bb },\n        { -0x4f0b79b2f76b7512, 0x07dc19ee91ba1c6f, 0x7975cdaea6aca158, 0x330b61134262d4bb },\n        { -0x0869e6285d927f76, -0x44e02b61e261ea93, 0x73d7c36cdba1df27, 0x26b44cd91f28777d }\n    },\n},\n{\n    {\n        { -0x50bb7bd24fd7a0c9, -0x78ace76fb8103721, -0x6a8b1f6e07df6866, 0x0e378d6069615579 },\n        { 0x300a9035393aa6d8, 0x2b501131a12bb1cd, 0x7b1ff677f093c222, 0x4309c1f8cab82bad },\n        { -0x26056e8e7cf8a5ab, 0x4bdb5ad26b009fdc, 0x7829ad2cd63def0e, 0x078fc54975fd3877 }\n    },\n    {\n        { -0x1dffb4a447cc5676, 0x44775dec2d4c3330, 0x3aa244067eace913, 0x272630e3d58e00a9 },\n        { -0x782042ebd77870d3, 0x134636dd1e9421a1, 0x4f17c951257341a3, 0x5df98d4bad296cb8 },\n        { -0x0c98702f1336f4ac, -0x0ffeba64edfbca67, 0x26725fbc3758b89b, 0x4325e4aa73a719ae }\n    },\n    {\n        { -0x12db9d6530960a63, 0x2a4a1ccedd5abbf4, 0x3535ca1f56b2d67b, 0x5d8c68d043b1b42d },\n        { 0x657dc6ef433c3493, 0x65375e9f80dbf8c3, 0x47fd2d465b372dae, 0x4966ab79796e7947 },\n        { -0x11ccd2b21c4bd4f6, -0x27b1a5d4e95b9fe4, 0x78243877078ba3e4, 0x77ed1eb4184ee437 }\n    },\n    {\n        { 0x185d43f89e92ed1a, -0x4fb5e11501b8e63a, 0x499fbe88a6f03f4f, 0x5d8b0d2f3c859bdd },\n        { -0x402b1ec0dfe7c660, -0x5110001dc1c20e9f, -0x49a4fb0f94a2e01d, 0x52e085fb2b62fbc0 },\n        { 0x124079eaa54cf2ba, -0x28db9a14ffe4d919, 0x6843bcfdc97af7fd, 0x0524b42b55eacd02 }\n    },\n    {\n        { -0x43e72352647d6154, 0x23ae7d28b5f579d0, -0x3cb9edd596c7bdcd, 0x1a6110b2e7d4ac89 },\n        { -0x02f2a2411babb850, 0x6cec351a092005ee, -0x665b87bba98a8635, 0x59d242a216e7fa45 },\n        { 0x4f833f6ae66997ac, 0x6849762a361839a4, 0x6985dec1970ab525, 0x53045e89dcb1f546 }\n    },\n    {\n        { -0x7b25c32172ba01ee, -0x42bd3de71bbb1d2e, -0x57ae6987e081ca68, 0x7642c93f5616e2b2 },\n        { -0x34744cb928acac25, -0x03034db451aee1de, -0x345b72bf2af51911, 0x26e3bae5f4f7cb5d },\n        { 0x2323daa74595f8e4, -0x219773747a85414c, 0x3fc48e961c59326e, 0x0b2e73ca15c9b8ba }\n    },\n    {\n        { 0x0e3fbfaf79c03a55, 0x3077af054cbb5acf, -0x2a3aadba24c21c61, 0x015e68c1476a4af7 },\n        { -0x2944bbd73e80afda, -0x614d8ddc04a56359, -0x1c845afce6e639bc, 0x21ce380db59a6602 },\n        { -0x3e2ad7addff995c8, -0x6a9fc1adca8f510d, -0x7cd9a658dd9475b3, 0x5dd689091f8eedc9 }\n    },\n    {\n        { 0x1d022591a5313084, -0x35d2b55129d8f78e, -0x795ed47ad0f402e0, 0x56e6c439ad7da748 },\n        { -0x34537b21402c37aa, 0x1624c348b35ff244, -0x48077235a26352f9, 0x3b0e574da2c2ebe8 },\n        { -0x38fb00b6bd42451a, 0x5e21ade2b2de1f79, -0x16a24c0ca9ad0528, 0x0822b5378f08ebc1 }\n    },\n},\n{\n    {\n        { -0x1e480d6c9d8cfc7d, 0x4b5279ffebca8a2c, -0x25038875402becec, 0x7deb10149c72610f },\n        { 0x51f048478f387475, -0x4da2430b634134c4, -0x6554edbb2660dfab, 0x2c709e6c1c10a5d6 },\n        { -0x349d509578991186, 0x66cbec045553cd0e, 0x588001380f0be4b5, 0x08e68e9ff62ce2ea }\n    },\n    {\n        { 0x2f2d09d50ab8f2f9, -0x5346de723aa6dc21, 0x4a8f342673766cb9, 0x4cb13bd738f719f5 },\n        { 0x34ad500a4bc130ad, -0x72c724b6c2f42b64, -0x5da3c267aff57642, 0x2f1f3f87eeba3b09 },\n        { -0x087b738a1aea49b6, -0x5a6afe4524b56fc8, -0x3df2cec0c08ae4b0, 0x19a1e353c0ae2ee8 }\n    },\n    {\n        { -0x4bde8d322a694243, -0x6c1fbabc671103c0, -0x604eacb84bbef64b, 0x736bd3990266ae34 },\n        { 0x7d1c7560bafa05c3, -0x4c1e5f5f391aa19f, -0x1cad68e73f299b8d, 0x41546b11c20c3486 },\n        { -0x7aacd2af6ccb4c4c, 0x46fd114b60816573, -0x33a0a0cfbda37c8b, 0x412295a2b87fab5c }\n    },\n    {\n        { 0x2e655261e293eac6, -0x7ba56dfcdecc5325, 0x460975cb7900996b, 0x0760bb8d195add80 },\n        { 0x19c99b88f57ed6e9, 0x5393cb266df8c825, 0x5cee3213b30ad273, 0x14e153ebb52d2e34 },\n        { 0x413e1a17cde6818a, 0x57156da9ed69a084, 0x2cbf268f46caccb1, 0x6b34be9bc33ac5f2 }\n    },\n    {\n        { 0x11fc69656571f2d3, -0x393617baacf18c86, -0x1cc5185d2b01afcb, 0x01b9c7b62e6dd30b },\n        { -0x0c20d09bc5873f4e, 0x4c3e971ef22e027c, -0x1382e3a1b63e4a5d, 0x2012c18f0922dd2d },\n        { -0x77f4aa1aa53762d7, 0x1483241f45a0a763, 0x3d36efdfc2e76c1f, 0x08af5b784e4bade8 }\n    },\n    {\n        { -0x1d8ceb2d7633d3b5, 0x4be4bd11a287178d, 0x18d528d6fa3364ce, 0x6423c1d5afd9826e },\n        { 0x283499dc881f2533, -0x62fada25886cdc4a, -0x7685220498cbbe0c, 0x32b79d71163a168d },\n        { -0x337a072612034c96, 0x22bcc28f3746e5f9, -0x1b621cc7061a2c33, 0x480a5efbc13e2dcc }\n    },\n    {\n        { -0x499eb31bbd31dde1, 0x6e199dcc4c053928, 0x663fb4a4dc1cbe03, 0x24b31d47691c8e06 },\n        { 0x0b51e70b01622071, 0x06b505cf8b1dafc5, 0x2c6bb061ef5aabcd, 0x47aa27600cb7bf31 },\n        { 0x2a541eedc015f8c3, 0x11a4fe7e7c693f7c, -0x0f5099ecb15d872a, 0x545b585d14dda094 }\n    },\n    {\n        { 0x6204e4d0e3b321e1, 0x3baa637a28ff1e95, 0x0b0ccffd5b99bd9e, 0x4d22dc3e64c8d071 },\n        { 0x67bf275ea0d43a0f, -0x521971cbf7641142, 0x4289134cd479e72e, 0x0f62f9c332ba5454 },\n        { -0x034b9a7629c4a0c7, 0x5cae6a3f57cbcf61, -0x01453d2d6ac505fb, 0x1c0fa01a36371436 }\n    },\n},\n{\n    {\n        { -0x3ee11a17ab3ac052, 0x6a0b06c12b4f3ff4, 0x33540f80e0b67a72, 0x15f18fc3cd07e3ef },\n        { -0x18ab8bb64383296e, 0x0f9abeaae6f73ddf, 0x4af01ca700837e29, 0x63ab1b5d3f1bc183 },\n        { 0x32750763b028f48c, 0x06020740556a065f, -0x2ac427ed3cb6a4a8, 0x08706c9b865f508d }\n    },\n    {\n        { -0x3366e4bec74bedba, 0x243b9c526f9ac26b, -0x4610b6b248345443, 0x5fba433dd082ed00 },\n        { -0x0c835d54c2cbc201, 0x1a8c6a2d80abc617, -0x71b61fca2b330036, 0x48b46beebaa1d1b9 },\n        { -0x63b61caa366be530, -0x468cb5218bb6707c, 0x41c3fed066663e5c, 0x0ecfedf8e8e710b3 }\n    },\n    {\n        { 0x744f7463e9403762, -0x0865721172033637, 0x163a649655e4cde3, 0x3b61788db284f435 },\n        { 0x76430f9f9cd470d9, -0x49d533645bd09ff8, 0x1898297c59adad5e, 0x7789dd2db78c5080 },\n        { -0x4dddd7e6f291094e, -0x56b5994db931b406, 0x46c1a77a4f0b6cc7, 0x4236ccffeb7338cf }\n    },\n    {\n        { 0x3bd82dbfda777df6, 0x71b177cc0b98369e, 0x1d0e8463850c3699, 0x5a71945b48e2d1f1 },\n        { -0x7b68bfb2f2aa1d8c, 0x6c6663d9c4ad2b53, -0x13d04f265256a8cc, 0x2617e120cdb8f73c },\n        { 0x6f203dd5405b4b42, 0x327ec60410b24509, -0x63cb8dcf53d577ba, 0x77de29fc11ffeb6a }\n    },\n    {\n        { -0x7ca1ec7013312d36, -0x736150ec1569c466, -0x36a0403f4de9f15a, 0x575e66f3ad877892 },\n        { -0x4f53a8367c488758, 0x53cdcca9d7fe912c, 0x61c2b854ff1f59dc, 0x3a1a2cf0f0de7dac },\n        { -0x667fc5d8377034c6, 0x345a6789275ec0b0, 0x459789d0ff6c2be5, 0x62f882651e70a8b2 }\n    },\n    {\n        { 0x6d822986698a19e0, -0x2367de1e8b28758f, 0x41a85f31f6cb1f47, 0x352721c2bcda9c51 },\n        { 0x085ae2c759ff1be4, 0x149145c93b0e40b7, -0x3b981805800d8c87, 0x4eeecf0ad5c73a95 },\n        { 0x48329952213fc985, 0x1087cf0d368a1746, -0x71ad9e4e993ea55b, 0x2d5b2d842ed24c21 }\n    },\n    {\n        { 0x5eb7d13d196ac533, 0x377234ecdb80be2b, -0x1ebb3003830a51dc, 0x5226bcf9c441acec },\n        { 0x02cfebd9ebd3ded1, -0x2ba4de88c6fde68c, 0x7576f813fe30a1b7, 0x5691b6f9a34ef6c2 },\n        { 0x79ee6c7223e5b547, 0x6f5f50768330d679, -0x128c1e1692752317, 0x27c3da1e1d8ccc03 }\n    },\n    {\n        { 0x28302e71630ef9f6, -0x3d2b5dfcd49b3120, 0x090820304b6292be, 0x5fca747aa82adf18 },\n        { 0x7eb9efb23fe24c74, 0x3e50f49f1651be01, 0x3ea732dc21858dea, 0x17377bd75bb810f9 },\n        { 0x232a03c35c258ea5, -0x790dc5d39434f30f, 0x3dad8d0d2e442166, 0x04a8933cab76862b }\n    },\n},\n{\n    {\n        { 0x69082b0e8c936a50, -0x06365fca3e253a4a, 0x6fb73e54c4dfb634, 0x4005419b1d2bc140 },\n        { -0x2d39fb49dd6bc201, -0x43734131bb304c60, 0x5d254ff397808678, 0x0fa3614f3b1ca6bf },\n        { -0x5ffc014246417d10, 0x2089c1af3a44ac90, -0x07b6606ee6ab0572, 0x1fba218aef40ab42 }\n    },\n    {\n        { 0x4f3e57043e7b0194, -0x57e2c111f7255081, -0x37c639546623210f, 0x6c535d13ff7761d5 },\n        { -0x54ab6bb705370ac2, -0x7e0917658459c8bf, 0x74fd6c7d6c2b5e01, 0x392e3acaa8c86e42 },\n        { 0x4cbd34e93e8a35af, 0x2e0781445887e816, 0x19319c76f29ab0ab, 0x25e17fe4d50ac13b }\n    },\n    {\n        { -0x6ea0800a890ede59, -0x3cb5cdd8d032781d, -0x3345d021b2e41ada, 0x6bba828f8969899b },\n        { 0x0a289bd71e04f676, 0x208e1c52d6420f95, 0x5186d8b034691fab, 0x255751442a9fb351 },\n        { -0x1d2e43996f01c6ff, 0x4cb54a18a0997ad5, -0x68e296eb507b9f2c, 0x559d504f7f6b7be4 }\n    },\n    {\n        { -0x63b76e18092d9903, 0x0744a19b0307781b, -0x77c770e29f9e1dc5, 0x123ea6a3354bd50e },\n        { -0x588c7c874c14ab2b, 0x1d69d366a5553c7c, 0x0a26cf62f92800ba, 0x01ab12d5807e3217 },\n        { 0x118d189041e32d96, -0x46121c3d27cea7b8, 0x1eab4271d83245d9, 0x4a3961e2c918a154 }\n    },\n    {\n        { 0x0327d644f3233f1e, 0x499a260e34fcf016, -0x7c4a58e90d254687, 0x68aceead9bd4111f },\n        { 0x71dc3be0f8e6bba0, -0x293107cb81001cf6, -0x566dbda01ec5b896, 0x2cd6bce3fb1db763 },\n        { 0x38b4c90ef3d7c210, 0x308e6e24b7ad040c, 0x3860d9f1b7e73e23, 0x595760d5b508f597 }\n    },\n    {\n        { -0x77d5341402fdd870, -0x7650ccfa3beea8a0, 0x65f492e37d3473f4, 0x2cb2c5df54515a2b },\n        { 0x6129bfe104aa6397, -0x7069fff75b580335, 0x3f8bc0897d909458, 0x709fa43edcb291a9 },\n        { -0x14f5a2739c02d536, -0x2dd43e99d196b101, 0x2723f36ef8cbb03a, 0x70f029ecf0c8131f }\n    },\n    {\n        { 0x2a6aafaa5e10b0b9, 0x78f0a370ef041aa9, 0x773efb77aa3ad61f, 0x44eca5a2a74bd9e1 },\n        { 0x461307b32eed3e33, -0x51fbd0cc5baa7e19, -0x36bbb62ce6a0fc9a, 0x0b7d5d8a6c314858 },\n        { 0x25d448327b95d543, 0x70d38300a3340f1d, -0x21e3ace39f1e3ad5, 0x272224512c7de9e4 }\n    },\n    {\n        { -0x40844475bd568a04, -0x73a3c68869525ca8, -0x1d803890321255b8, 0x19735fd7f6bc20a6 },\n        { 0x1abc92af49c5342e, -0x001127ee4d190530, -0x105d73720337b1d7, 0x11b5df18a44cc543 },\n        { -0x1c546f2fbd37bd9a, -0x147b71f080e6ab82, 0x2503a1d065a497b9, 0x0fef911191df895f }\n    },\n},\n{\n    {\n        { 0x6ab5dcb85b1c16b7, -0x6b3f0317c384d85b, -0x5b4ee3e58caae842, 0x499238d0ba0eafaa },\n        { -0x4eaf835e54e39147, -0x42bb70c1e949784d, 0x3455fb7f2c7a91ab, 0x7579229e2f2adec1 },\n        { -0x130b91ad854574a9, 0x15a08c478bd1647b, 0x7af1c6a65f706fef, 0x6345fa78f03a30d5 }\n    },\n    {\n        { -0x6c2c341642270f5c, -0x24ead3e402e88cfe, 0x7dbddc6d7f17a875, 0x3e1a71cc8f426efe },\n        { -0x20fd06a0efea185f, 0x790ec41da9b40263, 0x4d3a0ea133ea1107, 0x54f70be7e33af8c9 },\n        { -0x37c35c1c6f45429e, -0x7f121c98fd6e37cd, -0x377fc7332c86ff3c, 0x2c5fc0231ec31fa1 }\n    },\n    {\n        { -0x3bdd1b2efdba919b, -0x78beb53e352b846f, 0x1592e2bba2b6ffdd, 0x75d9d2bff5c2100f },\n        { -0x01456ee8e8fc74b1, -0x1aedc8de3621107f, 0x1c97e4e75d0d8834, 0x68afae7a23dc3bc6 },\n        { 0x5bd9b4763626e81c, -0x766996c9435fd123, 0x0a41193d61f077b3, 0x3097a24200ce5471 }\n    },\n    {\n        { -0x5e9d18db996a3b7a, 0x131d633435a89607, 0x30521561a0d12a37, 0x56704bada6afb363 },\n        { 0x57427734c7f8b84c, -0x0ebe5ec1fe4d8f17, 0x02d1adfeb4e564a6, 0x4bb23d92ce83bd48 },\n        { -0x5093b558ad06ed47, 0x5e665f6cd86770c8, 0x4c35ac83a3c8cd58, 0x2b7a29c010a58a7e }\n    },\n    {\n        { 0x33810a23bf00086e, -0x50316da118c90084, 0x3d60e670e24922d4, 0x11ce9e714f96061b },\n        { -0x3bff80882f3e313d, -0x72efdf49453b6d08, 0x32ec29d57e69daaf, 0x599408759d95fce0 },\n        { 0x219ef713d815bac1, -0x0ebeb9a2b7a41da4, 0x6d5447cc4e513c51, 0x174926be5ef44393 }\n    },\n    {\n        { 0x3ef5d41593ea022e, 0x5cbcc1a20ed0eed6, -0x702db130f8c7d374, 0x6fa42ead06d8e1ad },\n        { -0x4a214d0603a42a45, -0x6d2558d51e27ef1f, -0x503b302348d5e3a7, 0x497d78813fc22a24 },\n        { -0x1d897db5e08cc8e1, 0x7f7cf01c4f5b6736, 0x7e201fe304fa46e7, 0x785a36a357808c96 }\n    },\n    {\n        { 0x070442985d517bc3, 0x6acd56c7ae653678, 0x00a27983985a7763, 0x5167effae512662b },\n        { -0x7da042029cfeb2d5, -0x37adc9639358a875, 0x5b2fcd285c0b5df0, 0x12ab214c58048c8f },\n        { -0x42b1561ef0ac3b4a, 0x1673dc5f8ac91a14, -0x5707e5b1d533e546, 0x33a92a7924332a25 }\n    },\n    {\n        { 0x7ba95ba0218f2ada, -0x300bdd78ccf04636, -0x2525b692a93926f9, 0x5380c296f4beee54 },\n        { -0x622e0b66d86693fe, 0x0cb3b058e04d1752, 0x1f7e88967fd02c3e, 0x2f964268cb8b3eb1 },\n        { -0x62b0d8fb997672f6, 0x3d0987990aff3f7a, -0x2f610c9d982545bb, 0x7761455e7b1c669c }\n    },\n},\n};\n#elif defined(CURVED25519_ASM_32BIT)\nstatic const ge_precomp base[64][8] = {\n{\n    {\n        { -0x0a73c47b, 0x2fbc93c6, -0x0473f1e7, -0x306cd23a, 0x643d42c2, 0x270b4898, 0x33d4ba65, 0x07cf9d3a },\n        { -0x28bf6ec2, -0x62efc6fb, -0x2ebf414d, -0x02c660fb, 0x688f8a09, -0x5a3e7bcc, -0x6707ed99, 0x44fd2f92 },\n        { 0x4b6fbb59, -0x2442ea99, -0x115d5a16, 0x41e13f00, -0x36a83906, -0x322b62e4, -0x50e91336, 0x4f0ebe1f }\n    },\n    {\n        { -0x6cc38e29, -0x6ddb1804, 0x7a0ff5b5, -0x60b9626a, -0x1e29f8fe, 0x5aa69a65, -0x5782d1d2, 0x590c063f },\n        { 0x42b4d5a8, -0x75665aa0, 0x4e60acf6, -0x70d47ef4, -0x4e91c856, -0x1f61dc95, 0x69c92555, 0x6bb595a6 },\n        { -0x252c97fe, 0x6e347eaa, -0x7c11b7fb, -0x450ca66d, -0x19f897da, 0x3bcabe10, 0x165ed1b8, 0x49314f0a }\n    },\n    {\n        { 0x4cee9730, -0x50da4f58, -0x1779b476, 0x025a8430, -0x60fe98ce, -0x3ee4affe, -0x657f070c, 0x7a164e1b },\n        { -0x5b032d9b, 0x56611fe8, -0x1a3e4583, 0x3bd353fd, 0x214bd6bd, -0x7ece0ce6, 0x555bda62, 0x2ab91587 },\n        { -0x0e98b7cc, -0x640dee0c, -0x09d2076b, -0x47b194e9, 0x5b722a4e, -0x282190f9, 0x63bb2a21, 0x549a04b9 }\n    },\n    {\n        { -0x7103f661, 0x287351b9, 0x7dfd2538, 0x6765c6f4, -0x04f56d9b, -0x35cb72c3, 0x21e58727, 0x680e9103 },\n        { 0x056818bf, -0x6a01faf6, 0x5660faa9, 0x327e8971, 0x06a05073, -0x3c171c33, 0x7445a49a, 0x27933f4c },\n        { -0x1aebd950, -0x40e1ba14, 0x6dba0f94, -0x1cd439c3, -0x7307ad40, -0x1bd68b2b, -0x4f19b3e8, 0x44f079b1 }\n    },\n    {\n        { 0x08a5bb33, -0x5ded43bc, -0x38a112fe, -0x72afb73d, 0x5abfec44, -0x22e414f4, 0x46e206eb, 0x2945ccf1 },\n        { -0x5bb82946, 0x7f9182c3, 0x4b2729b7, -0x2affeb2f, -0x479b5f79, -0x1cc30ee4, -0x14e4aa0d, 0x154a7e73 },\n        { -0x182ffc4d, -0x37cd5e87, 0x00124d7e, 0x5f729d0a, 0x0e6d8ff3, 0x62c1d4a1, 0x38b27a98, 0x68b8ac59 }\n    },\n    {\n        { 0x77157131, 0x3a0ceeeb, 0x00c8af88, -0x64d8ea77, -0x25a658ca, -0x7f9a4998, -0x5d33c743, 0x51e57bb6 },\n        { 0x7b7d8ca4, 0x499806b6, 0x27d22739, 0x575be284, 0x204553b9, -0x44f7a319, -0x51be877c, 0x38b64c41 },\n        { 0x689de3a4, -0x7062526f, -0x07046ec9, 0x175f2428, -0x60304678, 0x050ab532, 0x1354c09f, 0x7865dfa2 }\n    },\n    {\n        { -0x6bb15c41, 0x6b1a5cd0, -0x4c623f2e, 0x7470353a, 0x28542e49, 0x71b25282, 0x283c927e, 0x461bea69 },\n        { -0x55cdde4f, -0x4590d366, 0x3bba23a7, 0x6ca02153, -0x6de6d3c6, -0x621589b1, 0x2e5317e0, 0x1d6edd5d },\n        { -0x54f025ca, 0x217a8aac, 0x3d3549c8, -0x5ad739ac, 0x13ab7568, 0x37d05b8b, 0x3a2cbc37, 0x233cef62 }\n    },\n    {\n        { 0x04dd3e8f, 0x59b75966, -0x1d778fd4, 0x6cb30377, 0x5ed9c323, -0x4ecc639a, 0x61bce52f, 0x0915e760 },\n        { -0x0c6dcb27, -0x1d58a213, -0x1e4aa707, -0x69c28980, 0x6e3c23fb, 0x2c2741ac, 0x320e01c3, 0x3a9024a1 },\n        { -0x57cb5c82, -0x208217cb, 0x689857ea, -0x741e6326, 0x7167b326, 0x2c118536, -0x24102a3e, 0x589eb3d9 }\n    },\n},\n{\n    {\n        { 0x2d9021f6, 0x322d04a5, 0x75c6bf9c, -0x463e60cd, 0x42d20b09, 0x587a3a43, -0x559b019f, 0x143b1cf8 },\n        { 0x553e2df3, 0x7ec851ca, -0x59b7874d, -0x58ed7b35, 0x3288d1e7, -0x194a1be7, 0x5a9a8883, 0x4cf210ec },\n        { -0x69753555, -0x60798383, 0x27092729, 0x5f54258e, -0x15e7f68b, -0x2f582cb5, 0x374126e1, 0x21b546a3 }\n    },\n    {\n        { -0x2e7ade71, 0x490a7a45, 0x46049335, -0x65eac888, -0x33ce1e0a, 0x0060ea09, -0x0791169b, 0x7e041577 },\n        { -0x5d777cbd, -0x56b007a8, 0x5313ed3c, -0x31f12baa, -0x4a40cb06, -0x0aa3c231, -0x36154c8f, 0x0a653ca5 },\n        { -0x31a4980d, 0x66b2a496, -0x42a9686a, -0x00ab6d28, 0x4a592cd0, 0x503cec29, 0x0813acb2, 0x56694365 }\n    },\n    {\n        { 0x1dabb69d, 0x5672f9eb, -0x5017ac04, -0x458f4acb, 0x2796d66d, 0x47ac0f75, -0x6bee8d8b, 0x32a53517 },\n        { 0x26620798, -0x47e724f4, 0x606e354a, 0x5d5c31d9, 0x00a8cdc7, 0x0982fa4f, 0x4653e2d4, 0x17e12bcd },\n        { -0x209b7bc9, -0x2c59bb5a, -0x77f04023, 0x703b6559, -0x52c5e55b, -0x347adac0, -0x71b39b98, 0x0900b3f7 }\n    },\n    {\n        { -0x37e952cf, -0x12d7f042, -0x2719101d, 0x52d9595b, -0x0939dc0b, 0x0fe71772, 0x051e293c, 0x4314030b },\n        { 0x679d651b, 0x0a851b9f, 0x033342f2, -0x1ef7349f, -0x1774cf5d, -0x29fe0a81, -0x12d228ec, 0x371f3aca },\n        { -0x040f4353, -0x2a9fffa2, -0x2e78f3a2, -0x7148f0d2, -0x2f7b1960, 0x201f9033, -0x31849990, 0x4c3a5ae1 }\n    },\n    {\n        { -0x36c25f23, -0x45078a1c, 0x71b9294d, -0x46cd7d59, -0x0b393ba0, -0x7f29c049, -0x15993e7f, 0x6de9c73d },\n        { -0x2347056b, 0x4138a434, 0x6c96840b, -0x78f30983, 0x297be82c, -0x21c77a8c, 0x7262a55a, 0x7c814db2 },\n        { -0x5fb2070e, 0x478904d5, -0x4efebd2d, -0x050451b6, 0x555d0998, -0x0937539d, 0x2f90b104, 0x5aac4a41 }\n    },\n    {\n        { -0x4280aecc, 0x603a0d0a, -0x1e2c51ba, -0x7f7636ce, -0x7867429d, -0x20da6ec7, 0x74ba0235, 0x1c145cd2 },\n        { 0x3ac92908, -0x39b0cd95, -0x199c1e20, 0x5551b282, 0x4a1a4b83, 0x476b35f5, 0x189f68c2, 0x1b9da3fe },\n        { 0x75f3d743, 0x32e83864, 0x6ae5d9ef, 0x365b8baf, 0x385b681e, -0x7dadc74a, 0x167d65e1, 0x234929c1 }\n    },\n    {\n        { 0x1d099fcf, 0x48145cc2, -0x33d7281b, 0x4535c192, 0x48247e01, -0x7f183e1b, 0x3b2973ee, 0x4a5f2874 },\n        { -0x5f885218, -0x67b21355, 0x19eb389d, 0x383f77ad, 0x2954d794, -0x38139482, -0x1483c586, 0x59c77b3a },\n        { 0x225ccf62, -0x2c5228db, -0x4dead3a3, -0x6ee5cc7f, 0x5b08f87d, -0x274c6053, 0x4799fe3b, 0x6f05606b }\n    },\n    {\n        { -0x06e49b7d, 0x5b433149, 0x5a2cbf62, -0x524a239b, 0x632827b3, -0x78057bee, -0x54b60728, 0x60895e91 },\n        { 0x177ba962, -0x6001616e, 0x0de5cae1, -0x675118e3, 0x2d831044, 0x3ff4ae94, 0x58533ac8, 0x714de12e },\n        { 0x0cf86c18, -0x16130d13, 0x0735dfd4, -0x4b92f9ee, 0x04b96be7, -0x43625f68, -0x26923d95, 0x73e2e62f }\n    },\n},\n{\n    {\n        { 0x632f9c1d, 0x2eccdd0e, 0x76893115, 0x51d0b696, -0x579c85a8, 0x52dfb76b, -0x5ff110c7, 0x6dd37d49 },\n        { 0x49aa515e, -0x12a49cac, 0x0bc6823a, -0x579a3b61, 0x5b42d1c4, -0x7af3e017, 0x03d315b9, 0x30d76d6f },\n        { 0x2106e4c7, 0x6c444417, -0x6d728097, -0x04ac2980, 0x694d3f26, -0x4b8c615c, 0x2e864bb0, 0x10c69711 }\n    },\n    {\n        { -0x7ca737fb, 0x0ca62aa0, 0x7a204247, 0x6a3d4ae3, 0x3b11eddc, 0x7464d3a6, 0x550806ef, 0x03bf9baf },\n        { 0x7dbe5fde, 0x6493c427, 0x19ad7ea2, 0x265d4fad, 0x46304590, 0x0e00dfc8, -0x129901f7, 0x25e61cab },\n        { -0x33a799fc, 0x3f13e128, -0x4ba68b82, 0x6f5873ec, -0x33ed970b, -0x5f49c213, 0x4586e22c, 0x566d7863 }\n    },\n    {\n        { -0x39a5d030, -0x5efabd7b, -0x0ce9983d, 0x6c64112a, 0x731aee58, 0x680ae240, 0x4793b22a, 0x14fba5f3 },\n        { -0x633ef7cc, 0x1637a49f, -0x57643baf, -0x4371a92b, 0x7f7fd2db, 0x1cb5ec0f, 0x5ecc35d9, 0x33975bca },\n        { 0x6985f7d4, 0x3cd74616, -0x3637ffa9, 0x593e5e84, 0x7b61131e, 0x2fc3f2b6, -0x7c03ad94, 0x14829cea }\n    },\n    {\n        { 0x4e71ecb8, 0x21e70b2f, 0x40a477e3, -0x19a92247, -0x31e2b080, -0x409aa932, 0x535d7b7e, 0x05fc3bc4 },\n        { -0x68226a3e, -0x00bc847c, -0x55b14a59, 0x6c744e30, 0x3c85e88b, -0x61f3a29f, 0x5f758173, 0x2fd9c71e },\n        { 0x52afdedd, 0x24b8b3ae, -0x12c4cf31, 0x3495638c, -0x56417e6b, 0x33a4bc83, 0x5c651f04, 0x37376747 }\n    },\n    {\n        { 0x14246590, 0x634095cb, 0x16c15535, -0x10edebc0, -0x76ef43a0, -0x61c7ebf4, 0x30907c8c, 0x6bf59057 },\n        { 0x40d1add9, 0x2fba99fd, -0x690b2fd9, -0x4cf8e991, 0x15f03bae, 0x4363f052, 0x3b18f999, 0x1fbea56c },\n        { -0x1ebea476, 0x0fa778f1, -0x453c5882, 0x06409ff7, -0x655d65b0, 0x6f52d7b8, 0x7a635a56, 0x02521cf6 }\n    },\n    {\n        { 0x772f5ee4, -0x4eeb98e0, -0x69f86532, -0x17076b4f, 0x00ac824a, 0x4af8224d, -0x0832933c, 0x001753d9 },\n        { 0x0a9d5294, 0x513fee0b, 0x0fdf5a66, -0x706718a4, -0x401ef832, -0x2b9e7978, 0x71382ced, 0x3fa00a7e },\n        { -0x69c224cc, 0x3c69232d, -0x4b68c7a8, 0x1dde87da, -0x5f6e0d7b, -0x55282e07, -0x5fb7124a, 0x12b5fe2f }\n    },\n    {\n        { -0x5290e16e, -0x20d483da, 0x504b8913, 0x4b66d323, 0x751c8bc3, -0x73bf6240, 0x0796c7b8, 0x6f7e93c2 },\n        { -0x69031cb3, 0x71f0fbc4, -0x520ca413, 0x73b9826b, -0x00d73a9f, -0x2dfb8d9f, 0x6fb1206f, 0x749b76f9 },\n        { -0x515951fb, 0x1f5af604, -0x411b6367, -0x3edcae0f, -0x1100949a, 0x61a808b5, 0x01e02151, 0x0fcec10f }\n    },\n    {\n        { -0x3bdbb1bb, 0x3df2d29d, -0x6c2721f6, 0x2b020e74, -0x7df3deb3, 0x6cc8067e, 0x6feab90a, 0x41377916 },\n        { 0x49fe1e44, 0x644d58a6, 0x31ad777e, 0x21fcaea2, -0x77802f2e, 0x02441c5a, -0x7c3aee0d, 0x4901aa71 },\n        { -0x73e50710, 0x08b1b754, 0x246299b4, -0x31f08584, 0x1e06d939, -0x089f4f07, 0x726d1213, 0x41bb887b }\n    },\n},\n{\n    {\n        { -0x55c6082e, -0x68267f20, 0x52c6b51c, 0x35d03842, 0x07cd55aa, 0x7d43f493, -0x48753c9e, 0x56bd36cf },\n        { 0x567c49d8, -0x6d987f94, -0x3586e196, 0x066d04cc, -0x1c33c6b5, -0x5960a9bb, -0x5f87732e, 0x5c95b686 },\n        { 0x0d14a954, 0x2ac519c1, -0x6b4a0570, -0x150b8b4c, -0x560785a6, -0x19507c7e, -0x78641f6c, 0x0dea6db1 }\n    },\n    {\n        { -0x29578686, 0x15baeb74, -0x053be8ce, 0x7ef55cf1, 0x3c8b05c5, 0x29001f5a, 0x52eaccfb, 0x0ad7cc87 },\n        { 0x7344e5ab, -0x559940ac, -0x70e4bcf7, -0x25eda778, -0x02a9b4d1, 0x5e87d2b3, 0x5483b1dd, 0x5b2c7888 },\n        { 0x793408cf, 0x52151362, 0x19963d94, -0x14f0e8fd, -0x77c26b9a, -0x57cc4d06, 0x75003c78, 0x093a7fa7 }\n    },\n    {\n        { 0x60a91286, -0x47169fbc, 0x7778d3de, 0x7f3fd804, -0x4075a1d3, 0x67d01e31, -0x3d849ac2, 0x7b038a06 },\n        { 0x3a16d7be, -0x1aef821a, -0x650ccd31, -0x5c880024, 0x440b677f, 0x70d5bf18, -0x5b5cebfd, 0x6a252b19 },\n        { -0x2c966f0d, -0x6126e62b, -0x24b1460e, 0x5213aebb, 0x4cb99135, -0x38f715fb, 0x72260e56, 0x58ded57f }\n    },\n    {\n        { 0x5b0fd48b, -0x2592acda, -0x6c405678, -0x769f7dcf, 0x61d57e28, -0x287536ce, 0x3a5c8143, 0x79f2942d },\n        { -0x16bec289, 0x78e79dad, -0x68d61983, -0x0da8062b, -0x1c85581a, 0x59db910e, -0x4461fc64, 0x6aa11b5b },\n        { -0x49377217, -0x6825d0db, -0x530dfe97, 0x251ba7ea, -0x10b14b1c, 0x09b44f87, -0x4395825b, 0x7d90ab1b }\n    },\n    {\n        { -0x694c3c69, 0x1a07a3f4, -0x70b1dace, 0x11ceaa18, -0x588ae410, 0x7d9498d5, 0x508dd8a0, 0x19ed161f },\n        { -0x58fe9402, -0x6533597d, -0x0d3af493, -0x6fafa0b3, -0x331bca56, 0x6b610d5f, 0x6198ff96, 0x19a10d44 },\n        { -0x78231936, 0x560a2cd6, -0x799b30b3, 0x7f3568c4, 0x22803a38, -0x78be16ae, 0x595653fc, 0x483bdab1 }\n    },\n    {\n        { -0x4b257f0a, -0x2930b2f6, -0x07cf8020, -0x7db7c1bb, -0x5190625c, 0x05005269, -0x63087886, 0x1c705290 },\n        { -0x78cb05b7, -0x0587f0ec, 0x360534e0, 0x106f0b70, -0x1c1cf843, 0x2210776f, -0x22195f02, 0x3286c109 },\n        { -0x78b1672c, 0x32ee7de2, -0x4681f3a0, 0x14c362e9, 0x6a60a38a, 0x5781dcde, -0x558557c0, 0x217dd5ea }\n    },\n    {\n        { -0x4173f138, -0x7420e047, -0x1cf5fd7e, 0x00bae7f8, -0x5293b094, 0x4963991d, 0x5df6f60a, 0x07058a6e },\n        { 0x248e1eb0, -0x62483b30, 0x4d74bf52, -0x1f89681f, 0x3c562354, 0x1e6a9b17, 0x795a4965, 0x7fa7c21f },\n        { -0x24ce0981, -0x1614fd3c, 0x10bcfb2b, -0x12da0277, 0x5c5cddb4, 0x46c8131f, -0x5f346432, 0x33b21c13 }\n    },\n    {\n        { 0x5ee38c5b, -0x65504650, 0x071a13c7, -0x4062d2b2, -0x16ccd6f6, -0x71119193, -0x51ef68e9, 0x1c3bab17 },\n        { 0x087d8e31, 0x360692f8, -0x2d8e9c09, -0x0b2339c9, 0x65ea5963, 0x25a4e620, 0x5ac160d9, 0x659bf72e },\n        { -0x38354850, 0x1c9ab216, 0x07bbc3cc, 0x7d65d374, 0x504a58d5, 0x52744750, 0x131a2990, 0x09f2606b }\n    },\n},\n{\n    {\n        { 0x7c6691ae, 0x7e234c59, 0x0a85b4c8, 0x64889d3d, 0x354afae7, -0x251d36f4, 0x0c6a9e1d, 0x0a871e07 },\n        { 0x744346be, 0x40e87d44, 0x15b52b25, 0x1d48dad4, -0x5ec49fc2, 0x7c3a8a18, 0x2fcdbdf7, 0x4eb728c1 },\n        { 0x4bbc8989, 0x3301b599, 0x5bdd4260, 0x736bae3a, 0x19d59e3c, 0x0d61ade2, 0x2685d464, 0x3ee7300f }\n    },\n    {\n        { -0x7be18ae8, 0x43fa7947, 0x639c46d7, -0x1a3905a7, -0x1cfad48c, -0x5ef9a1e3, -0x30476fd0, 0x7d47c6a2 },\n        { -0x61822949, -0x0a2daa1c, 0x610b1eac, -0x7fe9eea4, -0x6d1e7836, 0x3c99975d, -0x686eda3e, 0x13815762 },\n        { -0x710f2920, 0x3fdad014, -0x6eab90c4, -0x62c18b66, 0x26bb8157, 0x71ec6210, 0x34c9ec80, 0x148cf58d }\n    },\n    {\n        { -0x651b8a93, -0x1da8d083, -0x770cb781, 0x56c345bb, 0x6960a88d, -0x602ef493, 0x4eaea1b9, 0x278febad },\n        { 0x7934f027, 0x46a492f6, -0x097bf557, 0x469984be, -0x769ee7ac, 0x5ca1bc2a, -0x42a2442c, 0x3ff2fa1e },\n        { -0x736cc69a, -0x4e5597e1, 0x20290c98, -0x73de6b64, 0x219d3c52, 0x39115291, -0x01639885, 0x4104dd02 }\n    },\n    {\n        { -0x24f69548, -0x7edeb1fa, 0x0ce44f35, 0x21a8b6c9, 0x409e2af5, 0x6524c12a, -0x71035b7f, 0x0165b5a4 },\n        { 0x1124422a, 0x72b2bf5e, -0x675cc54b, -0x5e05f3cd, -0x05ad499a, -0x6b349eff, -0x5050ac2b, 0x2c863b00 },\n        { -0x5f7b958a, -0x0e6f5b8c, -0x32d08340, 0x12eff984, 0x58aa2b8f, 0x695e2906, -0x40013748, 0x591b67d9 }\n    },\n    {\n        { -0x60e74aa3, -0x66464c8f, -0x5e739be2, -0x1b9a1a06, -0x3d60fa13, 0x61081136, 0x7030128b, 0x489b4f86 },\n        { -0x7f4b6406, 0x312f0d1c, -0x540c1376, 0x5979515e, -0x610fe378, 0x727033c0, -0x35708435, 0x3de02ec7 },\n        { 0x3aeb92ef, -0x2dcdefd3, 0x6116a861, -0x1e9dac4c, 0x190baa24, 0x3d7eabe7, 0x496cbebf, 0x49f5fbba }\n    },\n    {\n        { 0x1e9c572e, 0x155d628c, -0x3a77b8bf, -0x75b27954, 0x515763eb, -0x6e5cad0a, -0x7798aea5, 0x06a1a6c2 },\n        { -0x75a4302c, 0x30949a10, -0x439b8c15, -0x23bf2290, 0x307c0d1c, -0x6d3d6b3f, -0x3405918c, 0x5604a86d },\n        { 0x7c1764b6, 0x7288d1d4, -0x1fbe74af, 0x72541140, 0x18acf6d1, -0x60fce5a0, -0x01d8bd3a, 0x20989e89 }\n    },\n    {\n        { -0x7a1513d2, 0x1674278b, 0x7acb2bdf, 0x5621dc07, 0x61cbf45a, 0x640a4c16, -0x08fa6a2d, 0x730b9950 },\n        { 0x3a2dcc7f, 0x499777fd, -0x5ab0276e, 0x32857c2c, -0x2df81c60, -0x5d86279c, 0x0ca67e29, 0x0403ed1d },\n        { -0x78b13aae, -0x36b4d2cb, -0x67db9073, -0x3a193731, 0x16c035ce, -0x0834b906, 0x08303dcc, 0x5bd74543 }\n    },\n    {\n        { 0x15e7792a, -0x7a3b6cdf, -0x42322237, -0x39b3765e, -0x525c289e, -0x62e1c258, 0x3067f82c, 0x5bb7db12 },\n        { 0x28b24cc2, 0x7f9ad195, 0x6335c181, 0x7f6b5465, 0x4fc07236, 0x66b8b66e, 0x7380ad83, 0x133a7800 },\n        { -0x39359d42, 0x0961f467, 0x211952ee, 0x04ec21d6, -0x642ab890, 0x18236077, 0x58f0e0d2, 0x740dca6d }\n    },\n},\n{\n    {\n        { -0x12d9e51b, 0x3906c72a, -0x771eff09, -0x65497027, -0x0cc9fe69, -0x0a16fa66, -0x40d492b9, 0x0e53dc78 },\n        { -0x2c0f50f5, 0x50b70bf5, -0x1cd18e09, 0x4feaf48a, -0x5aa442cc, 0x60e84ed3, 0x3f50d1ed, 0x00ed489b },\n        { 0x7971877a, -0x46f7d641, 0x6d17e631, 0x5e444463, 0x18276893, 0x4d05c52e, 0x5a4a4af5, 0x27632d9a }\n    },\n    {\n        { -0x78150025, -0x567d7a2f, -0x272f579c, -0x5a4b0445, 0x022663f7, -0x49a70d81, -0x26631d7e, 0x3bbc2b22 },\n        { 0x54b260ce, -0x2ee00faf, 0x72f95270, -0x27923c72, 0x267cc138, 0x601fcd0d, 0x29e90ccd, 0x2b679164 },\n        { 0x583c0a58, -0x46e836ae, 0x0fe4c6f3, 0x653ff9b8, -0x4320c3f4, -0x64f25829, -0x54ab29f2, 0x43a0eeb6 }\n    },\n    {\n        { 0x57875fe8, 0x3ac63223, -0x0a043471, -0x262b0b14, 0x382bb620, -0x72117b6d, 0x4c799fdc, 0x50c5eaa1 },\n        { 0x6d4a5487, 0x396966a4, -0x53d44c46, -0x07ee5e76, 0x5628b26b, 0x66e4685b, -0x626d646e, 0x70a47702 },\n        { -0x290d04c4, -0x22f12375, -0x63384860, 0x54c63aa7, 0x2c8d9f1a, -0x51f4fcd5, 0x602967fb, 0x6f9ce107 }\n    },\n    {\n        { 0x3520e0b5, 0x13969306, -0x7715fc02, 0x437fcf7c, -0x2c36a644, -0x082b3bf5, -0x076c2127, 0x699154d1 },\n        { -0x321e3dd6, -0x52efab4f, 0x48eb32df, -0x3b5716fe, -0x53323f16, 0x5f3e7b33, -0x038669c2, 0x72364713 },\n        { -0x4b4d8ada, 0x315d5c75, 0x0236daa5, -0x33347bd3, 0x345fee8e, 0x22f0c8a3, 0x7d39dbed, 0x73975a61 }\n    },\n    {\n        { -0x0bbcc1ba, 0x6f37f392, 0x1f566b18, 0x0e19b9a1, 0x1fd1d662, 0x220fb78a, -0x5c7e36b3, 0x362a4258 },\n        { 0x6375da10, -0x1bfdb207, 0x1830c870, 0x78d3251a, 0x658cd91c, -0x6fd4e6b8, 0x29b7438a, 0x7e18b10b },\n        { 0x2b6beb2f, -0x6f8e26ed, 0x28418247, 0x0f26e9ad, -0x42136da3, -0x1546e137, -0x0b750d22, 0x4be65bc8 }\n    },\n    {\n        { 0x57c26234, 0x1d50fba2, -0x214f9875, 0x7bd4823a, -0x59ac750b, -0x3d4f2392, 0x351da73e, 0x5665eec6 },\n        { -0x5c918fd8, 0x78487feb, 0x1dd8ce34, 0x5f3f1300, 0x4b30c489, -0x6cb04ed3, 0x397f0a2b, 0x056c244d },\n        { 0x43bfb210, -0x24c11ff7, 0x20800ac2, 0x49720187, 0x73bd8667, 0x26ab5d61, -0x54dfb6c8, 0x20b209c2 }\n    },\n    {\n        { 0x16bd3289, 0x1fcca945, 0x41420428, 0x448d65aa, 0x16a55d62, 0x59c3b7b2, 0x4e612cd8, 0x49992cc6 },\n        { -0x3f804cb5, 0x549e342a, 0x21373d93, 0x02d82208, -0x532e0a99, -0x43d9d290, -0x0435387c, 0x7a92c9fd },\n        { 0x70f801de, 0x65bd1bea, -0x01b61d76, 0x1befb7c0, -0x4e4d51b6, -0x579cf933, 0x265c2a09, 0x3b7ac0cd }\n    },\n    {\n        { 0x22ed39a7, -0x0f2ab1b1, 0x5608150a, -0x5d5516e2, -0x1225178b, -0x0bde4d17, 0x6b7de992, 0x31bc531d },\n        { -0x73fe4314, -0x7dd411bd, -0x3f0438c5, 0x530cb525, -0x3e6ac017, 0x48519034, -0x1f65f0a5, 0x265cc261 },\n        { -0x567f068f, -0x20c2ecb3, 0x221a22a7, 0x7a4fb8d1, 0x35aad6d8, 0x3df7d420, 0x6a1a125e, 0x2a14edcc }\n    },\n},\n{\n    {\n        { 0x0478433c, 0x231a8c57, -0x3d7ebc63, -0x484ad8f2, -0x1c26f861, -0x24556616, 0x6c2b03d9, 0x2c03f525 },\n        { 0x52cfce4e, -0x20b711f9, 0x06ec08b7, -0x3c00050d, -0x46aba63c, 0x05710b2a, -0x69c15c73, 0x161d25fa },\n        { 0x7b53a47d, 0x790f1875, -0x30f3a787, 0x307b0130, 0x257ef7f9, 0x31903d77, -0x42694451, 0x699468bd }\n    },\n    {\n        { 0x6aa91948, -0x2722c21a, 0x2fc0d2cc, 0x485064c2, 0x34fdea2f, -0x64b7db9a, 0x6c4a2e3a, 0x293e1c4e },\n        { -0x0b250131, -0x42e0d0ba, -0x5b802909, 0x7cef0114, 0x4a47b37f, -0x2ce00226, 0x73905785, 0x525219a4 },\n        { -0x6daeed1f, 0x376e134b, -0x235ea260, 0x703778b5, 0x461c3111, -0x4fba7651, 0x7f032823, 0x5b605c44 }\n    },\n    {\n        { -0x0f180fb4, 0x3be9fec6, 0x75e34962, -0x7995a862, 0x1e1de61a, 0x5542ef16, -0x33a5422b, 0x2f12fef4 },\n        { 0x20c47c89, -0x469a7fa7, -0x6dc47034, -0x180feff4, 0x02e2ef77, 0x00012565, -0x57514c12, 0x24a76dce },\n        { -0x203f38c0, 0x0a4522b2, 0x40c9a407, 0x10d06e7f, 0x78cff668, -0x3930ebbf, 0x18a43790, 0x5e607b25 }\n    },\n    {\n        { -0x5a6930ec, -0x5fd3bce4, -0x512c1c00, -0x1c3bd2c0, 0x2e0f26db, -0x2dbad980, -0x61ba8f98, 0x201f3313 },\n        { 0x6cdf1818, 0x58b31d8f, -0x3c9da75e, 0x35cfa74f, 0x66e61d6e, -0x1e4c00b1, 0x6ccdd5f7, 0x5067acab },\n        { 0x08039d51, -0x02ad8095, 0x017c0006, 0x18b14964, 0x2e25a4a8, -0x2addf150, 0x62460375, 0x397cba88 }\n    },\n    {\n        { -0x37ec8619, 0x7815c3fb, -0x221ed50f, -0x599e6be0, -0x7a57022b, -0x00563f08, -0x3e1e3dae, 0x771b4022 },\n        { -0x0fa6a64e, 0x30c13093, -0x1656868a, -0x1dc55e73, 0x721d5e26, 0x222fd491, 0x766e6c3a, 0x2339d320 },\n        { 0x513a2fa7, -0x2782267a, -0x062b30f8, -0x0a53648f, 0x1ea283b3, -0x2f943ce5, 0x19971a76, 0x331a1892 }\n    },\n    {\n        { -0x628a8d51, 0x26512f3a, 0x68074a9e, 0x5bcbe288, 0x1180f7c4, -0x7b123e3f, -0x09b65985, 0x1ac9619f },\n        { -0x04b07f3a, -0x0ae990bb, 0x61c775cf, -0x63c93822, -0x6fbe26e4, -0x1c2b17e5, -0x7c4201df, 0x31167c6b },\n        { 0x524b1068, -0x0dd4c7be, -0x11631679, 0x5068343b, 0x4a6250c8, -0x03628e7c, 0x1f08b111, 0x61243634 }\n    },\n    {\n        { 0x1a2d2638, -0x749cb61d, -0x642c02cb, -0x62204900, -0x5c5f945c, 0x7f8bf1b8, 0x78d90445, 0x1522aa31 },\n        { -0x78b17673, -0x2662be25, 0x6c07dc20, 0x09fea5f1, -0x2ff06444, 0x793d2c67, -0x61a100c0, 0x46ebe230 },\n        { 0x69614938, 0x2c382f53, -0x48d292f0, -0x2501bf66, -0x49b90dd9, -0x1737cc6f, 0x0524306c, 0x45fe70f5 }\n    },\n    {\n        { -0x376aeb6f, 0x62f24920, 0x3f630ca2, 0x05f007c8, -0x0a362b48, 0x6fbb45d2, -0x4a85ddbb, 0x16619f6d },\n        { -0x69f3f474, -0x25b78a5a, -0x10f1d0e0, 0x5b68d076, 0x3d0b8fd4, 0x07fb51cf, -0x5f1c6d2c, 0x428d1623 },\n        { 0x01a308fd, 0x084f4a44, 0x76a5caac, -0x57dde63d, 0x43d1bc7d, -0x214721ba, 0x60bd38c6, 0x1d81592d }\n    },\n},\n{\n    {\n        { 0x2f89c8a1, 0x3a4a369a, 0x7c8de80d, 0x63137a1d, 0x78eda015, -0x4353ff76, -0x4b7c4fc1, 0x2cb8b3a5 },\n        { -0x13d5b3c8, -0x27cc2842, 0x0acc20ed, 0x2c916283, -0x6d208a7f, -0x16c5b856, 0x333c4a81, 0x702d67a3 },\n        { -0x34e46f5f, 0x36e417cb, 0x7f11794e, 0x33b3ddaa, -0x77a439f9, 0x3f510808, -0x1957fdf3, 0x24141dc0 }\n    },\n    {\n        { -0x427cea83, -0x6e6da234, 0x22cc8094, 0x3ca12053, 0x3f90d6e4, 0x28e57f18, -0x21d18985, 0x1a4714ce },\n        { 0x3fefee9d, 0x59f73c77, -0x3e306763, -0x4c0e1077, -0x1fd1aba1, -0x1ca204be, 0x47a1b47c, 0x5766120b },\n        { -0x47494801, -0x24df45f1, 0x77511fa1, -0x48cd3c4a, -0x660fd277, -0x56d4ae40, 0x489ca5f1, 0x4f3875ad }\n    },\n    {\n        { -0x118c1140, 0x79ed13f6, 0x69110bb1, -0x5a39ad93, -0x79fc79f4, -0x1b76d73d, -0x028fa60b, 0x722a1446 },\n        { 0x4932ab22, -0x380389d1, 0x2f4c3c1b, 0x7ac0edf7, -0x65576a18, 0x5f6b55aa, -0x52f5ff7f, 0x3680274d },\n        { -0x573077e7, -0x2f6a6017, -0x7b8a5664, -0x2f566ab0, 0x20b09cc5, 0x6eac1733, 0x331b1095, 0x628ecf04 }\n    },\n    {\n        { 0x5c74ccf1, -0x64be5308, 0x08265251, -0x498cce7f, 0x11adb147, -0x6636d513, 0x34ecb40f, 0x7a47d70d },\n        { -0x562f2244, -0x67434ee8, 0x08b4802b, -0x11bb61cc, -0x47594efc, -0x78f76dda, 0x45c7915d, 0x685f349a },\n        { -0x33bc5b0b, 0x60a0c4cb, 0x3677bea9, 0x775c66ca, 0x2ff8f5ed, -0x5e855e8b, 0x0e01fdc0, 0x11ded902 }\n    },\n    {\n        { 0x3bea93b7, 0x471f95b0, 0x3313abd3, 0x0552d7d4, -0x1e81c085, -0x426c8f1e, -0x4df1a414, 0x7b120f1d },\n        { -0x351018fc, -0x76f187f7, -0x1cf17394, -0x78d7d693, -0x6d514e37, 0x4c5cd2a3, 0x5771531f, 0x194263d1 },\n        { -0x79afd286, 0x17d2fb3d, 0x50a69352, -0x4a9b27bc, -0x59f128a3, 0x7da962c8, 0x318736aa, 0x00d0f85b }\n    },\n    {\n        { -0x0289de3f, -0x598ac3e2, 0x445671f5, 0x69c0b4a7, 0x05b23c11, -0x68e0ad8c, 0x51a8c7cd, 0x387bc748 },\n        { 0x777c84fd, -0x6874ebd2, 0x05a8c062, -0x0bfd9bb9, -0x1819ed39, -0x59852ae5, -0x672295cd, 0x2f7b4596 },\n        { 0x4a52a9a8, -0x7e76b4b3, -0x09477cd1, -0x5226c1ee, -0x49e429c8, 0x184d8548, -0x29360933, 0x3f1c62db }\n    },\n    {\n        { 0x148f693d, 0x3fad3e40, -0x6b14658e, 0x052656e1, 0x184f4e2f, 0x2f4dcbfd, -0x3b7d1e75, 0x406f8db1 },\n        { -0x6e6ef3e1, 0x2e8f1f00, -0x400d1ed4, -0x5b20b020, -0x116d8bc8, 0x60c6560a, -0x53103706, 0x6338283f },\n        { 0x7f191ee4, -0x619cf2d4, -0x43c00990, 0x4fbf8301, 0x7afb73c4, 0x787d8e4e, -0x170a705b, 0x50d83d5b }\n    },\n    {\n        { -0x4b2c4993, -0x3f533070, 0x61732e60, -0x58fa621b, 0x70c6b0ba, 0x033d1f78, 0x26d946e4, 0x584161cd },\n        { -0x3ee5e769, -0x7a97c6ea, -0x1af92ff8, 0x2d69a4ef, -0x099b42ff, 0x39af1378, 0x361517c6, 0x65942131 },\n        { 0x72d27ca2, -0x440d4e60, -0x042138fc, -0x40c6c3a7, -0x1d9d47e2, -0x16724432, 0x3029b589, 0x02eebd0b }\n    },\n},\n{\n    {\n        { 0x7b85c5e8, -0x789a4961, -0x2e97454e, 0x6ff0678b, 0x1d330f9b, 0x3a70e77c, -0x4f507184, 0x3a5f6d51 },\n        { -0x59f253a1, 0x61368756, -0x145423a9, 0x17e02f6a, 0x4cce0f7d, 0x7f193f2d, -0x76132310, 0x20234a77 },\n        { 0x7178b252, 0x76d20db6, -0x2ae12ea0, 0x071c34f9, -0x4c1bee90, -0x09d5b5e0, 0x3cffe366, 0x7cd68235 }\n    },\n    {\n        { 0x68acf4f3, -0x599a32a0, 0x3cd7e3d3, 0x42d92d18, 0x336025d9, 0x5759389d, 0x2b2cd8ff, 0x3ef0253b },\n        { -0x2778054a, 0x0be1a45b, -0x45bfc492, 0x2a846a32, -0x1691a000, -0x266defee, 0x3bdc0943, 0x2838c886 },\n        { 0x4a465030, -0x2e944f31, 0x15c577ab, -0x05b694bf, -0x0b54be63, -0x7d305176, 0x06a82812, 0x21dcb8a6 }\n    },\n    {\n        { -0x4188ce46, -0x6572ff06, 0x629e1889, -0x7dfc9f82, 0x43f3d97f, -0x4d33fdc9, 0x6c6f678b, 0x5d840dbf },\n        { -0x73626038, 0x5c600446, -0x2bd55c35, 0x2540096e, 0x12ee2f9c, 0x125b4d4c, -0x6b5ce255, 0x0bc3d081 },\n        { 0x309fe18b, 0x706e380d, -0x461e9a39, 0x6eb02da6, 0x7dae20ab, 0x57bbba99, 0x2ac196dd, 0x3a427623 }\n    },\n    {\n        { -0x24bb8135, 0x3bf8c172, -0x39d7d243, 0x5fcfc41f, 0x75aa15fe, -0x7f530040, 0x24e1a9f9, 0x0770c9e8 },\n        { -0x758f7b06, 0x4b42432c, -0x20461abb, -0x7675e61d, -0x63a71ba3, -0x4160ffdf, -0x5e92142f, 0x1ff177ce },\n        { 0x45b5b5fd, -0x309e2666, 0x1b3a7924, -0x79f67b17, 0x303e3e89, -0x18cff6e7, 0x41500b1e, 0x39f264fd }\n    },\n    {\n        { -0x01f6841f, -0x2e64b555, -0x201fe6d7, -0x5b92031f, 0x2ca6f1ff, -0x3c36f76c, 0x2c35f14e, 0x65c62127 },\n        { -0x24181d64, -0x5852cbe9, 0x2b9c139c, -0x426bc896, -0x6ca68457, -0x5f16e472, 0x68889840, 0x1712d734 },\n        { -0x31ce6c23, -0x18d47608, -0x5eda3f45, 0x4d103356, 0x2e1cfe83, 0x0419a93d, -0x4e631d8e, 0x22f9800a }\n    },\n    {\n        { -0x65910254, 0x42029fdd, 0x34a54941, -0x46ed3142, -0x78420c85, 0x640f64b9, -0x7a67354c, 0x4171a4d3 },\n        { 0x3e9ef8cb, 0x605a368a, -0x5aafb8eb, -0x1c163fde, 0x5f24248f, 0x553d48b0, 0x647626e5, 0x13f416cd },\n        { -0x6636b374, -0x05d8a756, -0x4fff47f9, 0x23006f6f, -0x5225ac6e, -0x042d6e23, 0x574bd1ab, 0x508214fa }\n    },\n    {\n        { 0x53d003d6, 0x461a15bb, -0x430c369b, -0x4defd778, 0x6c683a5a, 0x27c57675, -0x37934bb9, 0x3a7758a4 },\n        { 0x3ed6fe4b, -0x3dfd96eb, 0x511d77c4, -0x59a598c7, 0x2c14af94, -0x3421d9ba, 0x6faba74b, 0x22f960ec },\n        { -0x6c51af8a, 0x548111f6, 0x1dfd54a6, 0x1dae21df, -0x0ceea19b, 0x12248c90, -0x72180b6c, 0x5d9fd15f }\n    },\n    {\n        { -0x1128ade2, 0x3f244d2a, 0x432e9615, -0x71c56fd8, 0x2e9c16d4, -0x1e9b4589, 0x47eb98d8, 0x3bc187fa },\n        { 0x6d63727f, 0x031408d3, -0x28384acd, 0x6a379aef, -0x33511db5, -0x561e703b, 0x4f8fbed3, 0x332f3591 },\n        { -0x15793df4, 0x6d470115, 0x6c46d125, -0x66754835, 0x3a660188, -0x2887cd4b, -0x6f9045fd, 0x450d81ce }\n    },\n},\n{\n    {\n        { -0x4d351f4b, 0x23264d66, -0x14359a8a, 0x7dbaed33, -0x0f2db538, 0x030ebed6, -0x089caaf0, 0x2a887f78 },\n        { -0x27bac6fe, -0x0751b2d6, -0x1724d2e3, 0x7018058e, -0x382d3ee2, -0x554c66a1, 0x24ccca79, 0x53b16d23 },\n        { 0x5c012d4f, 0x2a23b9e7, -0x351e0d16, 0x0c974651, 0x675d70ca, 0x2fb63273, -0x79bbfc0b, 0x0ba7250b }\n    },\n    {\n        { -0x79079264, -0x229ca76d, -0x1ec57a5c, 0x61699176, 0x4eaa7d57, 0x2e511195, -0x049f4205, 0x32c21b57 },\n        { 0x029c6421, -0x44f2e703, -0x76d670fe, -0x43d2ebdf, -0x74daf16a, -0x7cb8071a, 0x032d71c9, 0x7b9f2fe8 },\n        { 0x319e0780, -0x2787dc33, -0x76888a3b, -0x103b303f, -0x65f54c09, 0x4854fb12, 0x7238c371, 0x12c49d41 }\n    },\n    {\n        { -0x7c866abe, 0x09b3a017, -0x552a11c1, 0x626dd08f, -0x148feb61, -0x45ff4312, -0x5f5bbb37, 0x1421b246 },\n        { -0x0017c897, 0x0950b533, -0x71e2942f, 0x21861c1d, 0x1302e510, -0x0fdd27c8, 0x6391cab4, 0x2509200c },\n        { -0x73db5839, 0x4aa43a8e, -0x270fa10b, 0x04c1f540, 0x0b3eb9dc, -0x5245a1f4, 0x48a49ce3, 0x2ab55044 }\n    },\n    {\n        { 0x1c5d3afa, -0x23f8539d, -0x06207394, 0x58615171, -0x628c1d50, 0x72a079d8, -0x4b151ea3, 0x7301f4ce },\n        { 0x6f0f5dec, 0x2ed22726, 0x5ed50824, -0x67db11bf, -0x6b972beb, -0x7f841384, -0x4ade1dc1, 0x7093bae1 },\n        { -0x298dd3bf, 0x6409e759, 0x72bf729b, -0x598b1e31, 0x3c21e569, -0x43f5db15, 0x4ebacb23, 0x390167d2 }\n    },\n    {\n        { -0x5d0dedf5, -0x2844fab5, -0x4efa7649, -0x1d463152, -0x0c3f1242, 0x3fe8bac8, 0x7112cb69, 0x4cbd4076 },\n        { -0x45cac0e4, 0x27f58e3b, -0x4095bc9f, 0x4c47764d, 0x6e562650, -0x50443b1b, -0x551e5ba3, 0x07db2ee6 },\n        { 0x29c58176, 0x0b603cc0, 0x5cb15d61, 0x5988e382, -0x230f5273, 0x2bb61413, 0x74183287, 0x7b8eec6c }\n    },\n    {\n        { -0x03c7948d, 0x32fee570, -0x25c57339, -0x2574febf, -0x37697ca7, -0x68a002f6, -0x4ecd57ab, 0x6ee809a1 },\n        { 0x2cd27cb0, -0x1b35bf88, -0x04169843, -0x25063cdd, -0x752be162, -0x4d642cb6, 0x626ede4d, 0x72810497 },\n        { -0x030279c6, -0x6bbb44cf, 0x3e4e48c5, 0x2fe3690a, -0x2f7705db, -0x23d63799, -0x2e8cd6d2, 0x13bd1e38 }\n    },\n    {\n        { 0x1dfac521, 0x223fb5cf, 0x6f554450, 0x325c2531, 0x659177ac, 0x030b98d7, 0x4f88a4bd, 0x1ed018b6 },\n        { 0x696149b5, -0x2cd4b328, -0x7e275549, -0x1aa6c829, -0x51edd46c, 0x0bcb2127, -0x4ebf6650, 0x41e86fcf },\n        { -0x47fd5950, 0x3630dfa1, 0x42ad3bd5, -0x77f078b9, -0x113a5b2c, 0x0af90d6c, 0x37cdc5d9, 0x746a247a }\n    },\n    {\n        { 0x78d941ed, 0x6eccd852, -0x2dd087bd, 0x2254ae83, 0x7bbfcdb7, -0x3add2fd2, -0x400f1b1e, 0x681e3351 },\n        { 0x2b7b9af6, -0x2ace4743, 0x37fc5b51, 0x50050935, -0x3a6cab93, 0x232fcf25, 0x2bb40f49, 0x20a36514 },\n        { -0x7cfcb0bb, -0x749b4a63, 0x1fa20efb, 0x2f8b71f2, -0x459aaf1c, 0x69249495, 0x45d5472b, 0x539ef98e }\n    },\n},\n{\n    {\n        { 0x1cae743f, -0x2f8b276a, -0x11e39c13, -0x0792e70b, -0x180b12d7, -0x68423aa5, 0x663ab108, 0x4cbad279 },\n        { -0x59dfad8b, 0x6e7bb6a1, 0x413c8e83, -0x55b0de29, -0x1770a34e, 0x6f56d155, -0x59cba41f, 0x2de25d4b },\n        { -0x5f28e033, -0x7f2e6fdc, -0x04d77508, -0x3ada3df6, 0x5f3a6419, -0x4e5c68b5, -0x1dff8dcd, 0x7d7fbcef }\n    },\n    {\n        { -0x0c3d6f6c, -0x3283a23b, 0x2a9105ab, -0x387e5d66, 0x421c3058, -0x7f39e2ca, -0x23272b29, 0x4f9cd196 },\n        { 0x266b2801, -0x0510e196, -0x2a8c60ea, -0x7993973c, 0x1b03762c, -0x0975d044, -0x7848a573, 0x5975435e },\n        { 0x6a7b3768, 0x199297d8, 0x1ad17a63, -0x2f2fa7dc, 0x5c1c0c17, -0x45fd6353, 0x387a0307, 0x7ccdd084 }\n    },\n    {\n        { 0x6760cc93, -0x64f37be8, 0x1ab32a99, -0x3251ff86, 0x620bda18, -0x5772137a, -0x7e6f35bc, 0x3593ca84 },\n        { 0x6d260417, -0x2359bdd4, -0x6b7dbf43, -0x51eac2b0, -0x04973989, -0x563f3e4c, 0x61d0cf53, 0x428bd0ed },\n        { 0x5e849aa7, -0x6dece766, 0x65d8facd, -0x2b273ccb, 0x53fdbbd1, -0x73adaba5, -0x25d29c1a, 0x27398308 }\n    },\n    {\n        { 0x0a702453, -0x465ef1b4, -0x2a82e422, 0x0fa25866, -0x32d82509, -0x0046264b, 0x492c33fd, 0x572c2945 },\n        { 0x435ed413, 0x42c38d28, 0x3278ccc9, -0x42af0ca0, 0x79da03ef, -0x44f854e6, -0x4173ccab, 0x269597ae },\n        { -0x2932cf42, -0x388038bb, -0x1c455105, -0x1b20172d, -0x55a225f4, -0x5dd377d0, -0x3fa43580, 0x7f985498 }\n    },\n    {\n        { 0x0fbf6363, -0x2ca9eaae, -0x30b2045a, 0x08045a45, -0x78c05f3e, -0x113db044, -0x2964ed19, 0x30f2653c },\n        { -0x60f41ee9, 0x3849ce88, 0x7b54a288, -0x7ffa52e5, 0x23fc921c, 0x3da3c39f, 0x0a31f304, 0x76c2ec47 },\n        { -0x553ef37b, -0x75f736c8, -0x24d89435, 0x46179b60, 0x0e6fac70, -0x56df3fe2, 0x596473da, 0x2f1273f1 }\n    },\n    {\n        { 0x55a70bc0, 0x30488bd7, -0x0e2bbd19, 0x06d6b5a4, -0x43a69e9e, -0x152e5962, -0x123a087c, 0x38ac1997 },\n        { -0x751fe1ef, 0x4739fc7c, 0x4a6aab9f, -0x02ad8b70, -0x788d70d2, 0x41d98a82, -0x27a4960e, 0x5d9e572a },\n        { -0x58ae4ec5, 0x0666b517, 0x7e9b858c, 0x747d0686, 0x454dde49, -0x53533fef, -0x40161964, 0x22dfcd9c }\n    },\n    {\n        { 0x103be0a1, 0x56ec59b4, -0x2da60697, 0x2ee3baec, 0x13f5cd32, 0x797cb294, 0x24cde472, 0x0fe98778 },\n        { -0x3cf2f327, -0x72242d20, -0x5344bccd, -0x527199a1, 0x322a961f, -0x7094da74, 0x5448c1c7, 0x6b2916c0 },\n        { 0x0aba913b, 0x7edb34d1, 0x2e6dac0e, 0x4ea3cd82, 0x6578f815, 0x66083dff, 0x7ff00a17, 0x4c303f30 }\n    },\n    {\n        { 0x0dd94500, 0x29fc0358, 0x6fbbec93, -0x132d855c, -0x3d1d5808, 0x130a155f, -0x48f95e2b, 0x416b151a },\n        { 0x17b28c85, -0x2cf5c42a, 0x39773bea, -0x3a2c8849, 0x1e6a5cbf, -0x39391874, -0x74d5483c, 0x0d61b8f7 },\n        { -0x163ec950, 0x56a8d7ef, 0x58e44b20, -0x42f81a33, 0x1b57e0ab, -0x5019d026, 0x4277e8d2, 0x191a2af7 }\n    },\n},\n{\n    {\n        { 0x2fe09a14, 0x09d4b60b, -0x244e8b82, -0x3c7b0f51, 0x78b5fd6e, 0x58e2ea89, -0x4a1f64f6, 0x519ef577 },\n        { -0x5490b67b, -0x2aaff6a5, 0x4fbfaf1a, 0x04f4cd5b, 0x2a0c7540, -0x6271d12f, -0x4ddedd7a, 0x2bc24e04 },\n        { 0x1124cca9, 0x1863d7d9, -0x47758f72, 0x7ac08145, -0x7a8fce0b, 0x2bcd7309, -0x7547051b, 0x62337a6e }\n    },\n    {\n        { 0x1b3a1273, -0x2e54cdb2, -0x7efaacc0, 0x18947cf1, -0x5673e692, 0x3b5d9567, -0x7fd1e198, 0x7fa00425 },\n        { 0x06ffca16, 0x4bcef17f, 0x692ae16a, -0x21f91e25, 0x614f42b0, 0x0753702d, 0x5b9212d0, 0x5f6041b4 },\n        { 0x028c2705, 0x7d531574, -0x24f28a02, -0x7fce8297, -0x10737223, 0x30fface8, -0x493c1668, 0x7e9de97b }\n    },\n    {\n        { -0x5db2bf23, -0x0ffb419e, 0x0452d41f, -0x45f9a66f, 0x62a44234, -0x7e3ba11f, -0x5ddd9911, 0x4cb829d8 },\n        { -0x619a7a5d, 0x1558967b, -0x6716746e, -0x68366320, 0x6eb3adad, 0x10af149b, -0x0b2c7306, 0x42181fe8 },\n        { 0x07b86681, 0x1dbcaa84, -0x74d98ac5, 0x081f001e, -0x7bfb717f, 0x3cd7ce6a, 0x3f25f22c, 0x78af1163 }\n    },\n    {\n        { 0x7d65318c, 0x3241c00e, -0x2f179219, -0x19411a24, -0x043f73da, 0x118b2dc2, -0x039fc23d, 0x680d04a7 },\n        { 0x0b50babc, -0x7be9142c, 0x28208bee, 0x15087226, -0x463e3c93, -0x5ceb7051, -0x2cd282a3, 0x0d07daac },\n        { 0x695aa3eb, -0x063dbeb6, 0x05a68f21, -0x255bd3b4, 0x7f93963e, 0x7c6c2398, 0x0c3954e3, 0x210e8cd3 }\n    },\n    {\n        { 0x37fe6c26, 0x2b50f161, 0x56e404d8, -0x1efd4328, 0x4c561f6b, 0x12b0f141, -0x2fd7136f, 0x51b17bc8 },\n        { 0x10a71c06, -0x53bdfe0e, -0x0c404fdf, 0x6a65e0ae, 0x393632f7, -0x43bd3ca4, -0x79a0f8be, 0x56ea8db1 },\n        { -0x30acaee7, -0x000a04b5, -0x20eef760, -0x0b676287, -0x65c45cdb, -0x4203159b, 0x74d1a6f2, 0x18a11f11 }\n    },\n    {\n        { -0x2d85a0d4, -0x0429c326, -0x755ef929, -0x0ff03b44, -0x719b5bd0, 0x53fb5c1a, 0x0c1a2e85, 0x04eaabe5 },\n        { 0x3f6bba29, 0x407375ab, -0x66e1b7d2, -0x613c4928, -0x1aa06d17, -0x6637f17e, -0x04f3f51f, 0x307c13b6 },\n        { -0x34754a19, 0x24751021, 0x5c5010eb, -0x03dcbbb7, 0x4e5610a1, 0x5f1e717b, -0x3d8ef32b, 0x44da5f18 }\n    },\n    {\n        { -0x76271534, -0x6ea90195, -0x1dced95f, -0x19486baf, 0x3944eb4e, -0x428b9c27, 0x767203ae, 0x726373f6 },\n        { -0x0e47d14b, 0x033cc55f, 0x411cae52, -0x4ea51c93, -0x7004532d, -0x45bf49e7, 0x532e861f, 0x768edce1 },\n        { -0x14810976, -0x1cfa358e, 0x70eadb23, 0x662cf31f, -0x4b3ba498, 0x18f026fd, -0x4a2d1343, 0x513b5384 }\n    },\n    {\n        { -0x750cb315, 0x5e270287, -0x46b92952, -0x6ff4fbf7, -0x25427aee, 0x6512ebf7, -0x77da707f, 0x61d9b769 },\n        { -0x38d66762, 0x46d46280, 0x5368a5dd, 0x4b93fbd0, -0x2e89a577, 0x63df3f81, -0x465f5ddd, 0x34cebd64 },\n        { 0x49b7d94b, -0x593a58ed, 0x23eb9446, -0x5c0c2ea8, 0x77484834, 0x0416fbd2, 0x2c70812f, 0x69d45e6f }\n    },\n},\n{\n    {\n        { 0x4f460efb, -0x6019d4bd, -0x59c9f82a, -0x212cfc2c, -0x485f25dc, -0x0faddef2, 0x00545b93, 0x237e7dbe },\n        { -0x3ac3ebcf, -0x31e908b5, 0x2072edde, 0x2b9725ce, -0x4a4dc119, -0x47463c91, 0x0b5cc908, 0x7e2e0e45 },\n        { 0x6701b430, 0x013575ed, -0x60f402f0, 0x231094e6, -0x7c1b80de, 0x75320f15, -0x4eeeaa1d, 0x71afa699 }\n    },\n    {\n        { 0x473b50d6, -0x15bdc3e4, 0x3b38ef10, 0x51e87a1f, -0x4d36416b, -0x647b40a1, 0x78f89a1c, 0x00731fbc },\n        { 0x3953b61d, 0x65ce6f9b, -0x505ebe1a, -0x39a7c616, -0x5608a602, 0x0f435ffd, -0x3d4e3d72, 0x021142e9 },\n        { 0x48f81880, -0x1bcf38e8, 0x5ecec119, -0x4069f3de, 0x6bba15e3, -0x49251f7d, 0x47e15808, 0x4c4d6f33 }\n    },\n    {\n        { -0x6770e690, 0x2f0cddfc, -0x4f460ae5, 0x6b916227, 0x779176be, 0x6ec7b6c4, -0x57706058, 0x38bf9500 },\n        { -0x3e82e037, 0x18f7eccf, 0x51403c14, 0x6c75f5a6, -0x0811f321, -0x24218ed5, -0x581b85de, 0x193fddaa },\n        { 0x37e8876f, 0x1fd2c93c, 0x18d1462c, -0x5d09e1a6, 0x39241276, 0x5080f582, -0x40f2b697, 0x6a6fb99e }\n    },\n    {\n        { -0x491bdc3a, -0x114edd4b, -0x0d790072, -0x6c628ff0, 0x1dcf5d8c, -0x6f56d57d, 0x42c5eb10, 0x136fda9f },\n        { 0x560855eb, 0x6a46c1bb, -0x076c0f63, 0x2416bb38, -0x708e533f, -0x28e2eec9, -0x5ce76916, 0x75f76914 },\n        { -0x5cfa422f, -0x06b3204f, -0x6007d3f8, 0x0f364b9d, -0x3c44a776, 0x2a87d8a5, 0x0be8dcba, 0x02218351 }\n    },\n    {\n        { 0x43307a7f, -0x62a58eff, -0x3b825ba1, -0x4f9c2162, -0x416d852d, 0x22bbfe52, -0x02bfbd94, 0x1387c441 },\n        { 0x5ead2d14, 0x4af76638, -0x3583a7d0, -0x5f712780, 0x10211e3d, 0x0d13a6e6, 0x7b806c03, 0x6a071ce1 },\n        { -0x78687508, -0x4a2c3c2f, 0x7f0e4413, 0x722b5a3d, -0x44b88360, 0x0d7b4848, -0x50e1236e, 0x3171b26a }\n    },\n    {\n        { -0x4d75b82f, -0x59f24828, 0x1770a4f1, -0x5940eb2a, 0x53ddbd58, -0x2b5e076d, 0x344243e9, 0x6c514a63 },\n        { -0x68a9b358, -0x56d0ce70, 0x2275e119, -0x008447b4, -0x5b78aeb0, 0x4f55fe37, 0x3cf0835a, 0x221fd487 },\n        { 0x3a156341, 0x2322204f, -0x45f5fcd3, -0x048c1f17, 0x410f030e, -0x031f22b4, -0x046db556, 0x48daa596 }\n    },\n    {\n        { -0x37b3686d, 0x14f61d5d, -0x10be7dfa, -0x66be061d, 0x346277ac, -0x320a4771, 0x0e8a79a9, 0x58c837fa },\n        { 0x5ca59cc7, 0x6eca8e66, 0x2e38aca0, -0x57b8dab5, -0x2de1e832, 0x31afc708, -0x3527b509, 0x676dd6fc },\n        { -0x69036fa8, 0x0cf96885, 0x7b56a01b, 0x1ddcbbf3, 0x4935d66a, -0x233d1883, -0x395a80f6, 0x1c4f73f2 }\n    },\n    {\n        { -0x0383cb7c, -0x4c918f92, -0x3c3e309f, 0x73dfc9b4, 0x781cc7e5, -0x14e28637, 0x7daf675c, 0x70459adb },\n        { 0x305fa0bb, 0x0e7a4fbd, 0x54c663ad, -0x7d62b320, 0x2fe33848, -0x0bde3c7d, 0x1bf64c42, 0x795ac80d },\n        { -0x6e4bd44d, 0x1b91db49, 0x4b02dcca, 0x57269623, 0x1f8c78dc, -0x6020611b, -0x731de02d, 0x5fe16284 }\n    },\n},\n{\n    {\n        { -0x6aeeac77, 0x315c29c7, -0x79d08b32, -0x281f1af9, -0x7a6d8bce, 0x0c4a7621, 0x4a25a1e4, 0x72de6c98 },\n        { 0x4d077c41, -0x1d86f552, -0x248b965d, -0x746c7d90, -0x7542e95e, 0x6eb632dc, -0x55f9b48e, 0x720814ec },\n        { -0x40955cf0, -0x51654aad, -0x7f9291e5, 0x050a50a9, -0x5200aec7, -0x6d448bfd, 0x45be618b, 0x0394d276 }\n    },\n    {\n        { -0x4dcaba5c, -0x0ac69bdb, -0x67044d6a, 0x15a7a27e, 0x636fdd86, -0x5493ad44, 0x419334ee, 0x79d995a8 },\n        { -0x7a81120c, 0x4d572251, -0x1e616c3b, -0x1c8db123, 0x0b797035, -0x758ebdf2, -0x785418bd, 0x3b3c8336 },\n        { 0x1195dd75, -0x3275715a, 0x1dd9a82f, -0x5afb2758, -0x5ca7864a, 0x540dca81, 0x79c86a8a, 0x60dd16a3 }\n    },\n    {\n        { 0x153e47b8, 0x3501d6f8, 0x14a2f60c, -0x485698ac, 0x455d9523, 0x112ee8b6, -0x7eed1576, 0x4e62a3c1 },\n        { 0x7381e559, 0x35a2c848, -0x287f7d35, 0x596ffea6, -0x245849ad, -0x34688e15, -0x64b2597b, 0x5a08b501 },\n        { 0x516ab786, -0x372b53fc, 0x5295b23d, 0x595af321, -0x24fdcf3f, -0x29122dcc, -0x7da4be34, 0x0929efe8 }\n    },\n    {\n        { -0x52a99ae3, -0x74ce8d49, 0x3fabd717, 0x01581b7a, 0x424df6e4, 0x2dc94df6, 0x2c29284f, 0x30376e5d },\n        { -0x342f0d2d, 0x5f0601d1, 0x6132bb7f, 0x736e412f, 0x238dde87, -0x7c9fbbce, -0x0a3f8ac4, 0x1e3a5272 },\n        { -0x7ea65a64, -0x2d6e7259, 0x3f0713f3, 0x6bdc1cd9, 0x4acd6590, 0x565f7a93, 0x4cb4c128, 0x53daacec }\n    },\n    {\n        { -0x7ad30250, -0x667ad43d, 0x59d6ed0b, 0x2cc12e95, -0x64a53d85, 0x70f9e2bf, 0x7959ae99, 0x4f3b8c11 },\n        { -0x6337582a, 0x4ca73bd7, 0x47e9a9b2, 0x4d4a738f, 0x42f5fe00, -0x0b340ed7, -0x4240f8ae, 0x01a13ff9 },\n        { 0x2ff26412, 0x55b6c9c8, 0x1fb667a8, 0x1ac4a8c9, -0x1488740e, -0x2ad84031, 0x7012a3be, 0x303337da }\n    },\n    {\n        { -0x052d022f, -0x6892c335, 0x37a640a8, -0x34777c69, 0x6734cb25, 0x2ff00c1d, 0x789c2d2b, 0x269ff4dc },\n        { -0x73e36284, -0x6aabddde, 0x1a9b340f, 0x01fac137, -0x6da4b729, 0x7e8d9177, 0x61b3e31b, 0x53f8ad56 },\n        { -0x3f729873, 0x0c003fbd, 0x7ead2b17, 0x4d982fa3, -0x4d1a7d0f, -0x3f819433, -0x20bed5bc, 0x296c7291 }\n    },\n    {\n        { -0x25474a62, -0x204dcdfb, -0x37f6ddb0, 0x465aeaa0, -0x658da2e8, -0x2ecc3ee8, 0x61f117d1, 0x23273702 },\n        { 0x33daf397, 0x7903de2b, -0x3659db4d, -0x2f00f9e7, 0x555b3e18, -0x75e2dad5, 0x52e0b7c0, 0x2b6d581c },\n        { 0x623e7986, 0x3d0543d3, -0x3d875cac, 0x679414c2, 0x726196f6, -0x51bc0f34, -0x7dba1546, 0x7836c41f }\n    },\n    {\n        { -0x7fee6c84, -0x359ae17c, 0x6ef41a28, -0x394f3b92, 0x5f3f8d52, -0x48fde459, -0x15284603, 0x119dff99 },\n        { 0x49e95a81, -0x185dab25, 0x08b0ad73, 0x5192d5d0, -0x2ff503f9, 0x4d20e5b1, 0x2cf25f38, 0x5d55f801 },\n        { -0x0b4ce2b3, 0x43eadfcb, 0x11148892, -0x39afc08c, 0x060d3b17, -0x0111973b, -0x22b5f538, 0x329293b3 }\n    },\n},\n{\n    {\n        { 0x5d7cb208, 0x2879852d, 0x687df2e7, -0x47212290, 0x21687891, -0x23f40055, 0x677daa35, 0x2b44c043 },\n        { -0x1e6b69e6, 0x4e59214f, 0x0d71cd4f, 0x49be7dc7, 0x3b50f22d, -0x6cff302e, -0x036e8dce, 0x4789d446 },\n        { 0x074eb78e, 0x1a1c87ab, -0x66250b99, -0x05392e72, 0x484f9067, 0x3eacbbcd, 0x2bb9a4e4, 0x60c52eef }\n    },\n    {\n        { 0x7cae6d11, 0x702bc5c2, 0x54a48cab, 0x44c7699b, -0x45b6d14e, -0x1043bfaa, -0x26499893, 0x70d77248 },\n        { 0x3bfd8bf1, 0x0b5d89bc, -0x360caae6, -0x4f946dc9, -0x2acfd70b, 0x0e4c16b0, 0x2ccfcaab, 0x10bc9c31 },\n        { 0x3ec2a05b, -0x557517b5, -0x12e87e20, -0x6796610c, 0x708e85d1, 0x794513e4, -0x56890bed, 0x63755bd3 }\n    },\n    {\n        { -0x680e5349, 0x3dc71018, -0x3e9a4428, 0x5dda7d5e, 0x0fa1020f, 0x508e5b9c, 0x37c52a56, 0x27637517 },\n        { 0x2ad10853, -0x4aa05fc2, -0x6119ca97, 0x356f7590, -0x41964770, -0x60060e03, -0x743e907c, 0x0d8cc1c4 },\n        { 0x6eb419a9, 0x029402d3, 0x77b460a5, -0x0f4bb182, -0x2bc3b6aa, -0x30579dd0, 0x7ad166e7, 0x70c2dd8a }\n    },\n    {\n        { -0x471281ed, -0x6e2b6983, -0x28897e86, 0x74252f0a, 0x0d852564, -0x1bf67d20, 0x16a53ce5, 0x32b86138 },\n        { -0x609013f2, 0x65619450, 0x46c6518d, -0x11d18157, 0x67e09b5c, -0x68cc3e0d, 0x63948495, 0x2e0fac63 },\n        { -0x1bb7329c, 0x79e7f7be, 0x087886d0, 0x6ac83a67, -0x5f1b24d2, -0x07602b27, 0x735a4f41, 0x4179215c }\n    },\n    {\n        { 0x286bcd34, -0x1b51cc47, 0x559dd6dc, -0x4810814a, -0x4c2c71e1, 0x278b141f, 0x2241c286, 0x31fa8566 },\n        { -0x282312d6, -0x738f6b19, 0x47d39c70, -0x6804753d, -0x56f926fe, -0x1ec41fcd, 0x0cd99d76, 0x700344a3 },\n        { 0x2e3622f4, -0x507d93be, -0x67ccafd3, -0x3edfd679, 0x2b389123, -0x643e481f, -0x566adb77, 0x24bb2312 }\n    },\n    {\n        { -0x0a07a395, 0x41f80c2a, 0x04fa6794, 0x687284c3, -0x5c45e453, -0x76ba2067, -0x0014a2ea, 0x0d1d2af9 },\n        { 0x32de67c3, -0x4e5712e9, 0x461b4948, 0x3cb49418, 0x76cfbcd2, -0x7142bcbd, 0x1e188008, 0x0fee3e87 },\n        { 0x32621edf, -0x5625755f, 0x59226579, 0x30b822a1, -0x58653e6d, 0x4004197b, 0x18531d76, 0x16acd797 }\n    },\n    {\n        { 0x7887b6ad, -0x36a6393b, 0x5f90feba, -0x6b1e6153, -0x5cbd0afc, 0x16e24e62, 0x18161700, 0x164ed34b },\n        { 0x2d9b1d3d, 0x72df72af, -0x5bcddba6, 0x63462a36, 0x16b39637, 0x3ecea079, -0x46cfdcf7, 0x123e0ef6 },\n        { 0x192fe69a, 0x487ed94c, 0x3a911513, 0x61ae2cea, -0x465b21d9, -0x7884092d, 0x1073f3eb, 0x78da0fc6 }\n    },\n    {\n        { 0x680c3a94, -0x5d607f0f, 0x1ae9e7e6, 0x71f77e15, 0x48017973, 0x1100f158, 0x16b38ddd, 0x054aa4b3 },\n        { -0x1ad43996, 0x5bf15d28, 0x70f01a8e, 0x2c47e318, 0x06c28bdd, 0x2419afbc, 0x256b173a, 0x2d25deeb },\n        { 0x19267cb8, -0x2037b973, 0x66e54daf, 0x0b28789c, 0x666eec17, 0x2aeb1d2a, -0x548258a0, 0x134610a6 }\n    },\n},\n{\n    {\n        { -0x23fd73c4, -0x26ebcf20, 0x5217c771, 0x0eb955a8, 0x2c99a1fa, 0x4b09e1ed, -0x42958bc4, 0x42881af2 },\n        { 0x7c59b23f, -0x350aa13e, 0x154d04f2, -0x665112c2, -0x1ebebe0c, 0x68441d72, 0x3932a0a2, 0x14034513 },\n        { -0x54a352c3, 0x7bfec69a, 0x4cb2cfad, -0x3dc1732d, -0x04c8295e, 0x685dd14b, 0x15677a18, 0x0ad6d644 }\n    },\n    {\n        { 0x47927e9f, 0x79148928, 0x370aa877, 0x33dad6ef, 0x11122703, 0x1f8f24fa, 0x2adf9592, 0x5265ac2f },\n        { 0x417becb5, 0x781a439e, -0x2ef1fd9a, 0x4ac5938c, 0x0692ac24, 0x5da38511, -0x521cedcd, 0x11b065a2 },\n        { -0x65034cba, 0x405fdd30, 0x28e63f54, -0x268dc2bc, 0x5f65aaae, -0x6b3fe210, -0x1eb3f7f7, 0x43e4dc3a }\n    },\n    {\n        { -0x523d395d, -0x1590853d, -0x168e836c, -0x2f16d70a, -0x29ba150b, -0x1d2c8616, -0x3ae00442, 0x46dd8785 },\n        { -0x56c75ae9, -0x43ed380f, 0x3180b2e1, 0x473028ab, -0x0432dab6, 0x3f78571e, 0x6ff6f90f, 0x74e53442 },\n        { 0x375c8898, 0x709801be, -0x1c027cb8, 0x4b06dab5, 0x27230714, 0x75880ced, -0x22d0b3be, 0x2b09468f }\n    },\n    {\n        { -0x7d005fd6, 0x5b979465, -0x01570ab7, -0x25f695af, 0x5f77af9b, -0x5f9caec9, 0x201d1e76, 0x1bcfde61 },\n        { -0x48fe346a, -0x6838b612, -0x495c963d, -0x7c0bc72c, -0x65bfd327, 0x62962b8b, -0x67772085, 0x6976c750 },\n        { 0x246a59a2, 0x4a4a5490, -0x17802270, -0x29c14222, 0x0d2371fa, -0x26bc8399, -0x2cf0712a, 0x69e87308 }\n    },\n    {\n        { -0x7437fcfd, 0x0f80bf02, 0x7a18cefb, 0x6aae16b3, -0x28d3295d, -0x22b815b9, -0x0b12c656, 0x61943588 },\n        { 0x5656beb0, 0x435a8bb1, 0x4f4d5bca, -0x07053646, 0x1548c075, -0x464d873c, -0x176d49de, 0x3eb0ef76 },\n        { -0x6efc607b, -0x2d91a3c2, -0x090cc557, -0x3f161883, 0x70066a93, -0x176973ab, 0x1faaaddd, 0x3c34d188 }\n    },\n    {\n        { 0x2fffe0d9, -0x42a4f471, 0x3ed24fb9, 0x6aa25410, -0x4d97de3c, 0x2ac7d7bc, 0x60dca36a, 0x605b394b },\n        { -0x5f606140, 0x3f9d2b5e, -0x49dc5770, 0x1dab3b6f, 0x72d926c4, -0x5f645c16, 0x3fd8b36d, 0x37419351 },\n        { 0x5a9d1ed2, -0x4b17a91c, 0x6c97a9a2, -0x1017b78a, 0x1e5eee7d, -0x4efb309c, -0x7758e371, 0x2f50b81c }\n    },\n    {\n        { -0x5825add6, 0x2b552ca0, 0x449b0250, 0x3230b336, -0x5b466047, -0x0d3b3a44, 0x58074a22, 0x7b2c6749 },\n        { -0x0397ee45, 0x31723c61, 0x6211800f, -0x634bafb8, 0x47995753, 0x768933d3, 0x02752fcd, 0x3491a535 },\n        { 0x3ed28cdf, -0x2aae9a78, -0x2c9d21c7, 0x12d84fd2, -0x1cc871b1, 0x0a874ad3, 0x7c763e74, 0x000d2b1f }\n    },\n    {\n        { 0x3e94a8ab, -0x69db8874, -0x16587414, 0x0ad6f3ce, 0x0d743c4f, -0x6b75387f, -0x55130334, 0x76627935 },\n        { -0x2f92b599, 0x3d420811, -0x6f1f001d, -0x4103fb7b, -0x42b78422, -0x078f3949, 0x319afa28, 0x6e2a7316 },\n        { -0x292a6561, 0x56a8ac24, 0x3096f006, -0x37248ac2, -0x70b3ad67, 0x477f41e6, -0x09379eec, 0x588d851c }\n    },\n},\n{\n    {\n        { 0x77d1f515, -0x32d59a19, -0x70559f0f, 0x54899187, -0x2543f91b, -0x4e48c444, -0x56833605, 0x654878cb },\n        { -0x72094f02, 0x51138ec7, -0x1a8a0ae5, 0x5397da89, 0x717af1b9, 0x09207a1d, 0x2b20d650, 0x2102fdba },\n        { 0x055ce6a1, -0x69611bfb, 0x1251ad29, 0x36bca768, -0x55825beb, 0x3a1af517, 0x29ecb2ba, 0x0ad725db }\n    },\n    {\n        { -0x64fa907b, -0x013843f4, -0x180a0029, 0x537d5268, 0x4312aefa, 0x77afc662, 0x02399fd9, 0x4f675f53 },\n        { -0x7cb1dba9, -0x23bd984f, 0x70ce1bc5, -0x498abb4b, -0x082ea129, 0x1af07a0b, 0x71a03650, 0x4aefcffb },\n        { 0x0415171e, -0x3cd2c9ca, -0x7667b7c5, -0x32d410ef, -0x2f6baef0, -0x78f59153, -0x5d579a9f, 0x0bccbb72 }\n    },\n    {\n        { 0x50fe1296, 0x186d5e4c, -0x01176082, -0x1fc6847e, 0x507031b0, 0x3bc7f6c5, 0x108f37c2, 0x6678fd69 },\n        { -0x154e5638, 0x185e962f, 0x65147dcd, -0x791819cb, -0x44a4920e, -0x4f6d1fcf, 0x59d6b73e, 0x4024f0ab },\n        { 0x636863c2, 0x1586fa31, 0x572d33f2, 0x07f68c48, 0x789eaefc, 0x4f73cc9f, -0x7152b8ff, 0x2d42e210 }\n    },\n    {\n        { 0x0f537593, 0x21717b0d, 0x131e064c, -0x6eb196f5, 0x752ae09f, 0x1bb687ae, -0x64bdc392, 0x420bf3a7 },\n        { -0x6b202d65, -0x680aeceb, 0x313f4c6a, 0x6155985d, 0x08455010, -0x145ec0f9, -0x472d2cde, 0x676b2608 },\n        { 0x1c5b2b47, -0x7ec7459b, 0x311b1b80, -0x798e4914, -0x43ceca50, 0x7bff0cb1, -0x63f30e20, 0x745d2ffa }\n    },\n    {\n        { 0x21d34e6a, 0x6036df57, -0x66844c30, -0x4e2477d9, -0x378a9506, -0x2c3df63d, 0x4c1dc839, 0x06e15be5 },\n        { 0x2bc9c8bd, -0x40ada5e2, 0x26479d81, -0x15a4d9f8, -0x20feaa25, -0x2aee38f2, -0x69f30a30, 0x1ae23ceb },\n        { 0x1932994a, 0x5b725d87, -0x314e2550, 0x32351cb5, -0x254835fb, 0x7dc41549, 0x278ec1f7, 0x58ded861 }\n    },\n    {\n        { -0x493d3658, 0x2dfb5ba8, -0x0ad3a674, 0x48eeef8e, -0x0ed2ea8d, 0x33809107, 0x531d5bd8, 0x08ba696b },\n        { -0x0d993aa4, -0x27e8c86d, -0x33bab1b7, -0x3736893b, -0x43d93c58, 0x5ce382f8, 0x5485f6f9, 0x2ff39de8 },\n        { -0x3c103a86, 0x77ed3eee, -0x2b00b7ef, 0x04e05517, -0x0e598e35, -0x15c285c1, -0x6b8301ac, 0x120633b4 }\n    },\n    {\n        { 0x4912100a, -0x7d42ceb9, 0x7e6fbe06, -0x21dc8493, 0x11ea79c6, -0x1ee189e7, -0x34c6c422, 0x07433be3 },\n        { -0x6e9effbe, 0x0b949878, -0x13140518, 0x4ee7b13c, -0x6b0f5b40, 0x70be7395, -0x4b2a6e7b, 0x35d30a99 },\n        { 0x5ce997f4, -0x0086bb40, -0x4fa3ae5d, 0x575d3de4, 0x5a76847c, 0x583381fd, 0x7af6da9f, 0x2d873ede }\n    },\n    {\n        { 0x4e5df981, -0x559dfd1f, 0x5015e1f5, -0x5df2a6e9, -0x451de294, 0x18a275d3, 0x01600253, 0x0543618a },\n        { 0x43373409, 0x157a3164, -0x0b557e27, -0x05474812, -0x0a59b7fa, -0x4f6c011a, 0x707fa7b6, 0x2e773654 },\n        { -0x68b3dc3f, 0x0deabdf4, -0x6231b96d, -0x5590f5db, -0x5d6545d4, 0x04202cb8, 0x2d07960d, 0x4b144336 }\n    },\n},\n{\n    {\n        { 0x57c5715e, 0x299b1c3f, 0x6b686d90, -0x69346d62, 0x47235ab3, 0x30048064, -0x5bb2601f, 0x2c435c24 },\n        { 0x53242cec, 0x47b837f7, -0x3fbded0e, 0x256dc48c, -0x1e26d73b, -0x1ddd0405, -0x5275d3f9, 0x48ea295b },\n        { -0x7f077cc1, 0x0607c97c, -0x35da13a5, 0x0e851578, 0x161ebb6f, 0x54f7450b, -0x5f2107f2, 0x7bcb4792 }\n    },\n    {\n        { 0x045224c2, 0x1cecd0a0, 0x69e53952, 0x757f1b1b, 0x5289f681, 0x775b7a92, 0x16736148, 0x1b6cc620 },\n        { 0x2bc73659, -0x7b781c30, 0x059979df, 0x4baf8445, -0x23529041, -0x2e8368a6, -0x2103694a, 0x57369f0b },\n        { 0x75638698, -0x0e5666ff, -0x11559f2d, 0x353dd1be, 0x4c9ba488, -0x7b6b8ecd, 0x43ade311, 0x63fa6e68 }\n    },\n    {\n        { -0x2db4a149, 0x2195becd, -0x3f32bb07, 0x5e41f18c, 0x41ca9ede, -0x20d7f8bc, -0x0ca48299, 0x07073b98 },\n        { 0x6597c168, -0x2ea3dfad, -0x672d7877, -0x608c8c00, 0x3257ba1f, 0x18aee7f1, 0x07346f14, 0x3418bfda },\n        { 0x4ce530d4, -0x2fc39894, 0x3b5df9f4, 0x0b64c047, 0x19b3a31e, 0x065cef8b, 0x533102c9, 0x3084d661 }\n    },\n    {\n        { 0x760321fd, -0x6593178a, -0x6149c528, 0x7fe2b510, -0x7537fa6e, 0x00e7d4ae, -0x44908dc6, 0x73d86b7a },\n        { -0x407b9653, -0x1e094862, -0x1d99cecb, 0x15801004, -0x508be7e5, -0x65b67cd0, 0x049b673c, 0x3ba2504f },\n        { 0x6dba5ab6, 0x0b52b560, -0x444e1255, -0x56ecb0f1, -0x64fb59cb, 0x30a9520d, 0x7973e5db, 0x6813b8f3 }\n    },\n    {\n        { -0x0cea81d7, -0x0e6b35aa, 0x5ef528a5, 0x136d3570, -0x74fa6644, -0x22b31089, 0x24f833ed, 0x7d5472af },\n        { 0x334127c1, -0x67ab4fac, -0x7d0400db, 0x105d0478, 0x44186f4f, -0x24b60807, -0x412f4700, 0x1768e838 },\n        { -0x50cc25b9, -0x2f1078b3, -0x491cc607, 0x00d3be5d, -0x63631132, 0x3f2a8a2f, 0x2352435a, 0x5d1aeb79 }\n    },\n    {\n        { -0x49e4588b, 0x12c7bfae, -0x1d9c4003, -0x47b19de1, 0x5c840dcf, 0x0b47a5c3, -0x335079cc, 0x7e83be0b },\n        { 0x19cd63ca, -0x0a61944d, 0x21d06839, 0x670c1592, 0x2150cab6, -0x4f92a9a5, 0x104f12a3, 0x20fb199d },\n        { 0x6d99c120, 0x61943dee, 0x460b9fe0, -0x79efe0d2, -0x7117a673, 0x6bb2f151, -0x033b8a34, 0x76b76289 }\n    },\n    {\n        { 0x522ec0b3, 0x4245f1a1, 0x2a75656d, 0x558785b2, 0x48a1b3c0, 0x1d485a25, -0x2a701f61, 0x60959ecc },\n        { 0x756286fa, 0x791b4cc1, -0x28b5ea84, -0x24312ce9, -0x158d421a, 0x7e732421, 0x1131c8e9, 0x01fe1849 },\n        { -0x571285f7, 0x3ebfeb7b, -0x1afd8764, 0x49fdc2bb, 0x3c119428, 0x44ebce5d, -0x416b80b6, 0x35e1eb55 }\n    },\n    {\n        { 0x726ccc74, 0x14fd6dfa, 0x2f53b965, 0x3b084cfe, 0x52a2c8b4, -0x0cc51b0b, 0x0d40166a, 0x59aab07a },\n        { -0x3a8c722d, -0x242518ff, -0x4d90e412, -0x063909cb, 0x42f15ef4, 0x61e96a80, -0x509f5b28, 0x3aa1d11f },\n        { -0x6da153db, 0x77bcec4c, 0x60137738, 0x18487184, -0x01560baf, 0x5b374337, -0x371955ba, 0x1865e78e }\n    },\n},\n{\n    {\n        { 0x1c529ccb, -0x6983ab17, 0x64c635fb, 0x30f62692, 0x78121965, 0x2747aff4, -0x150990a4, 0x17038418 },\n        { -0x4991e086, -0x333b4839, -0x0af3d082, 0x44157e25, 0x713eaf1c, 0x3ef06dfc, 0x52da63f7, 0x582f4467 },\n        { 0x20324ce4, -0x39ce842d, -0x5bb7743c, -0x57efbd18, 0x4e5a1364, -0x4de10e75, -0x325d7237, 0x0c2a1c4b }\n    },\n    {\n        { 0x69bd6945, -0x123b7eb8, -0x41e372de, 0x0d6d907d, -0x2aa33a55, -0x39c42dee, -0x5ceb237d, 0x5a6a9b30 },\n        { 0x6f1f0447, -0x2db23830, -0x24783fa7, -0x4dd961c2, -0x044d2d71, -0x2ea4fd8e, -0x3909b789, 0x7c558bd1 },\n        { -0x2c69b9c3, -0x2f13eadc, -0x3ca5db10, 0x12bb628a, 0x1cbc5fa4, -0x5af3c587, 0x0afbafc3, 0x0404a5ca }\n    },\n    {\n        { 0x2a416fd1, 0x62bc9e1b, -0x1cafa675, -0x4a3908d8, 0x3d5d6967, 0x04343fd8, -0x18071168, 0x39527516 },\n        { 0x0aa743d6, -0x73e0bff9, 0x5b265ee8, -0x33452f35, 0x668fd2de, 0x574b046b, -0x352269cd, 0x46395bfd },\n        { 0x1a5d9a9c, 0x117fdb2d, -0x2effa3d6, -0x6388ba44, 0x54d56fea, -0x102b410f, -0x17dd2fea, 0x76579a29 }\n    },\n    {\n        { 0x52b434f2, 0x333cb513, -0x6c217f1f, -0x27cdd7b7, 0x750d35ce, -0x4aaed779, 0x2a2777c1, 0x02c514bb },\n        { 0x49c02a17, 0x45b68e7e, -0x43565c81, 0x23cd51a2, -0x13ddb3e5, 0x3ed65f11, -0x61fa424f, 0x43a384dc },\n        { -0x740e49bb, 0x684bd5da, -0x094ab4ad, -0x04742c82, -0x564f2dad, 0x313916d7, 0x61548059, 0x11609209 }\n    },\n    {\n        { 0x369b4dcd, 0x7a385616, 0x655c3563, 0x75c02ca7, -0x2b0e7fdf, 0x7dc21bf9, -0x6e191fbe, 0x2f637d74 },\n        { 0x29dacfaa, -0x4bb2e997, -0x7beca671, -0x25ad60b4, 0x453d5559, -0x16109c36, -0x3a9671f5, 0x351e125b },\n        { 0x1af67bbe, -0x2b4b64ba, -0x3754769f, -0x29fcfc86, -0x06596605, 0x71dee19f, -0x1831d566, 0x7f182d06 }\n    },\n    {\n        { -0x71de8ade, 0x09454b72, -0x2b7b4728, -0x55a7170c, 0x7f46903c, -0x2ca7dab3, 0x241c5217, 0x44acc043 },\n        { -0x54fe9714, 0x7a7c8e64, 0x15edc543, -0x34a5b5ab, 0x47cd0eda, 0x095519d3, 0x343e93b0, 0x67d4ac8c },\n        { 0x4f7a5777, 0x1c7d6bbb, -0x6e7cec1f, -0x74ca012c, -0x3694b97c, 0x4adca1c6, 0x12ad71bd, 0x556d1c83 }\n    },\n    {\n        { -0x4ee417df, -0x7e0f98aa, 0x10a3f3dd, 0x0faff823, 0x6a99465d, -0x074d2fab, -0x337380fb, 0x097abe38 },\n        { 0x0c8d3982, 0x17ef40e3, 0x15a3fa34, 0x31f7073e, 0x0773646e, 0x4f21f3cb, 0x1d824eff, 0x746c6c6d },\n        { 0x7ea52da4, 0x0c49c987, -0x6423e2bd, 0x4c436955, -0x0833142e, 0x022c3809, 0x4bee84bd, 0x577e14a3 }\n    },\n    {\n        { -0x42b228d5, -0x6b013142, 0x060f2211, -0x0b95b026, -0x3f372e01, 0x124a5977, -0x04ff6d6b, 0x705304b8 },\n        { 0x61a73b0a, -0x0f1d9754, 0x3791a5f5, -0x0d0505f0, 0x6b6d00e9, -0x3e1ec17e, 0x6fd78f42, 0x60fa7ee9 },\n        { 0x4d296ec6, -0x49c2e2cb, 0x5fad31d8, -0x0c3cfac2, -0x4b42bd14, 0x670b958c, -0x5e9cac03, 0x21398e0c }\n    },\n},\n{\n    {\n        { -0x79e48166, -0x793a03ea, 0x6a27c451, -0x095ccfb9, -0x5e16ca69, 0x01667267, 0x6082dfeb, 0x05ffb9cd },\n        { -0x72582d11, 0x216ab2ca, -0x660bd7d9, 0x366ad9dd, 0x4fdd3c75, -0x519b4700, 0x53909e62, 0x403a395b },\n        { -0x0ac09ec7, -0x59e80561, 0x13e66cb6, 0x60f2b5e5, -0x4cbb755c, -0x28574111, 0x6f5ea192, 0x7a293285 }\n    },\n    {\n        { 0x79639302, -0x4763bbb8, 0x50c67f2c, 0x4ae4f193, -0x37e5063a, -0x0f4ca258, 0x46871017, 0x39d00035 },\n        { -0x4fd21778, 0x0b39d761, -0x2dbeb1e1, 0x5f550e7e, 0x22e1a940, -0x59405ba8, -0x02bb8467, 0x050a2f7d },\n        { -0x59af2489, 0x437c3b33, -0x453ad44e, 0x6bafe81d, 0x2db7d318, -0x0166bfd3, 0x372ba6ce, 0x2b5b7eec }\n    },\n    {\n        { 0x613ac8f4, -0x596bbfb3, -0x056818d4, 0x500c3c2b, 0x1fcec210, -0x78befb2e, -0x79fb5712, 0x1b205fb3 },\n        { -0x7c0af111, -0x4c43b443, -0x736d879a, 0x508f0c99, -0x37481992, 0x43e76587, -0x5b806727, 0x0f7655a3 },\n        { -0x2db4ecc4, 0x55ecad37, 0x6038c90b, 0x441e147d, -0x29d39012, 0x656683a1, -0x781f1352, 0x0157d5dc }\n    },\n    {\n        { -0x28e14adc, -0x6ad9aaec, 0x5df14593, -0x19fc277f, 0x0d4de6b7, 0x147cdf41, 0x0437c850, 0x5293b173 },\n        { 0x0354c13d, -0x0d5850af, -0x55c8d4a0, -0x285f4ebb, 0x05a3d470, 0x2869b96a, -0x7db9fe8d, 0x6528e42d },\n        { 0x4bccf226, 0x23d0e081, -0x7e69046d, -0x6d38ba33, 0x59541e5b, -0x749e8694, -0x3fde0688, 0x40a44df0 }\n    },\n    {\n        { 0x4bc5d095, -0x793691af, -0x03597fb6, -0x0df2bf68, -0x37d915a3, 0x27363d89, 0x5719cacf, 0x39ca3656 },\n        { 0x4f20ea6a, -0x25579677, 0x4c620618, -0x15eb5c2f, 0x090bf8be, 0x6001fccb, -0x6b816310, 0x35f4e822 },\n        { 0x6f87b75c, -0x68af90d1, 0x034ae070, -0x39db5160, -0x552cb22a, 0x1ec856e3, -0x1bbf1a71, 0x055b0be0 }\n    },\n    {\n        { 0x6ea33da2, 0x4d12a04b, -0x1c9ed923, 0x57cf4c15, -0x11bb2699, -0x6f13698b, 0x2a985aac, 0x64ca348d },\n        { -0x768ca2ee, 0x6469a17d, -0x199d460f, -0x2490d82b, 0x6a395681, -0x60345cd8, -0x2d9650db, 0x363b8004 },\n        { -0x1b3b6ed3, -0x66a771e7, 0x1ca5ce6b, -0x1033c4b2, -0x05a4672b, 0x4522ea60, 0x1de4a819, 0x7064bbab }\n    },\n    {\n        { 0x42542129, -0x5d6f3f9f, -0x4172a470, -0x0d1d3d52, 0x76abfe1b, -0x30dba725, -0x7c29d941, 0x02157ade },\n        { 0x5a770641, -0x46e61eaf, 0x4e7f8039, -0x565d1d39, 0x3df23109, 0x7527250b, -0x53d84875, 0x756a7330 },\n        { 0x1b9a038b, 0x3e46972a, 0x7ee03fb4, 0x2e4ee66a, 0x6edbb4ca, -0x7e5db789, -0x7132fa9d, 0x1a944ee8 }\n    },\n    {\n        { 0x182362d6, -0x44bf57a7, -0x75b2e545, -0x4660aa89, 0x758559f6, -0x72e74bd9, 0x4d26235a, 0x26c20fe7 },\n        { 0x51039372, -0x2a56e2ef, -0x6635d922, 0x2ed377b7, -0x02c99495, -0x5e8dfd54, -0x296fe66b, 0x0730291b },\n        { -0x1633dd0b, 0x648d1d9f, 0x28dd577c, 0x66bc5619, 0x652439d1, 0x47d3ed21, -0x125074b7, 0x49d271ac }\n    },\n},\n{\n    {\n        { -0x4b48a9ff, 0x2798aaf9, 0x5c8dad72, 0x5eac7213, 0x61b7a023, -0x2d31559f, -0x167082b2, 0x1bbfb284 },\n        { 0x382b33f3, -0x760afa76, -0x52b73f4c, 0x5ae2ba0b, -0x5ac24c92, -0x706c4afd, -0x6a5dcd1a, 0x5aa3ed9d },\n        { -0x38269a9f, 0x656777e9, 0x72c78036, -0x34d4edac, -0x26af9112, 0x65053299, 0x5e8957cc, 0x4a07e14e }\n    },\n    {\n        { -0x3b885b65, 0x240b58cd, 0x6447f017, -0x02c72522, -0x58379553, 0x19928d32, -0x7b505f7f, 0x50af7aed },\n        { -0x67f20667, 0x4ee412cb, 0x3c6ec771, -0x5cea2891, -0x6da38803, -0x445a1222, 0x1d313402, 0x3f0bac39 },\n        { 0x15f65be5, 0x6e4fde01, 0x216109b2, 0x29982621, 0x0badd6d9, 0x78020581, -0x45142ffa, 0x1921a316 }\n    },\n    {\n        { -0x260c3e75, -0x28a55266, 0x60b1c19c, 0x566a0eef, 0x255c0ed9, 0x3e9a0bac, -0x5f9d380b, 0x7b049dec },\n        { -0x20478f04, -0x76bdd082, 0x4f76b3bd, 0x2c296beb, 0x36c24df7, 0x0738f1d4, -0x1d8c5150, 0x6458df41 },\n        { 0x35444483, -0x23341c86, 0x0fedbe93, 0x75887933, 0x12c5dd87, 0x786004c3, -0x3d6af19c, 0x6093dccb }\n    },\n    {\n        { 0x6084034b, 0x6bdeeebe, 0x780fb854, 0x3199c2b6, -0x49d2f96b, -0x68cc8955, -0x749b8270, 0x6e3180c9 },\n        { -0x7a1f8f93, 0x1ff39a85, -0x4c18c6cd, 0x36d0a5d8, 0x718f453b, 0x43b9f2e1, 0x4827a97c, 0x57d1ea08 },\n        { -0x5ed74f8f, -0x11854919, -0x6c577456, -0x5b3ea693, -0x4dde9ed0, -0x084b217e, -0x226842e8, 0x363e999d }\n    },\n    {\n        { -0x1db4513a, 0x2f1848dc, -0x454350a0, 0x769b7255, 0x3cefe931, -0x6f34c392, -0x39064cab, 0x231f979b },\n        { 0x35ee1fc4, -0x6957bc3f, 0x08e4c8cf, -0x68914cab, -0x4a732cd0, -0x4bd097ff, 0x693a052b, 0x48ee9b78 },\n        { -0x33d50c3a, 0x5c31de4b, -0x01df72e1, -0x4fb44fd0, -0x3eb04b9a, -0x48728ff7, 0x08792413, 0x079bfa9b }\n    },\n    {\n        { -0x5d2abdbb, -0x0c361280, 0x77f63952, 0x0aa08b78, -0x2ef7ab8b, -0x2892539d, -0x6b8f9c95, 0x1ef4fb15 },\n        { -0x25cff20c, -0x1c6fc5af, 0x3da95ab0, -0x7bc69bdd, 0x0b356480, -0x12c30ed3, -0x7b7e8e6c, 0x038c77f6 },\n        { 0x5b167bec, -0x7ab1a11a, -0x692f323e, 0x59590a42, -0x67efde67, 0x72b2df34, 0x4a0bff56, 0x575ee92a }\n    },\n    {\n        { 0x0aa4d801, 0x5d46bc45, -0x5acc4628, -0x3c50edd9, 0x2b8906c2, 0x389e3b26, 0x382f581b, 0x200a1e7e },\n        { -0x75e7d031, -0x2b3f7f70, -0x66b76243, 0x30e170c2, 0x52f733de, 0x05babd57, 0x2cd3fd00, 0x43d4e711 },\n        { -0x1506c53b, 0x518db967, 0x056652c0, 0x71bc989b, 0x567197f5, -0x01d47a27, 0x651e4e38, 0x050eca52 }\n    },\n    {\n        { 0x60e668ea, -0x6853c68a, 0x153ab497, -0x64e64402, 0x34eca79f, 0x4cb179b5, -0x5ece51a9, 0x6151c09f },\n        { 0x453f0c9c, -0x3cbce522, -0x008fc465, -0x160afba2, -0x127b84c3, -0x03268537, 0x1c58f4c6, 0x4b0ee6c2 },\n        { -0x020fa26a, 0x3af55c0d, 0x2ab4ee7a, -0x22d9d120, 0x12171709, 0x11b2bb87, -0x7ff0fcf5, 0x1fef24fa }\n    },\n},\n{\n    {\n        { -0x6fe99de0, -0x006e5996, 0x5bf1e009, -0x0ddaad52, 0x7f90df7c, 0x7dff85d8, 0x0c736fb9, 0x4f620ffe },\n        { 0x6b6c6609, -0x4b69edc6, -0x7f54a6c8, -0x58af017b, -0x483d85a1, -0x0b8e40c7, 0x77ac193c, 0x507903ce },\n        { -0x2021c1cc, 0x62f90d65, -0x4605a053, -0x30d73a6e, -0x39e9baf0, -0x66379107, 0x4a256c84, 0x25d44804 }\n    },\n    {\n        { -0x36fdd4ab, 0x2c7c4415, -0x7ed14e02, 0x56a0d241, -0x2849a1f3, -0x0fd15e37, -0x2acdc4da, 0x4180512f },\n        { -0x38164e91, -0x4297dcf2, -0x3e3a86a3, 0x0eb1b9c1, -0x6a494e01, 0x7943c8c4, 0x0bbacf5e, 0x2f9faf62 },\n        { -0x75b75a25, -0x5b00c197, -0x426abfc5, -0x4595c7fa, 0x47d5b65d, -0x60831e51, 0x5939d2fb, 0x15e087e5 }\n    },\n    {\n        { -0x0469c0c8, -0x776be792, -0x239c642b, 0x48a00e80, -0x1693e367, -0x5b17f6d5, -0x35a8c99f, 0x5a097d54 },\n        { 0x745c1496, 0x12207543, -0x25c79ef4, -0x2500c303, 0x2c71c34f, -0x1b1868d9, 0x34bdede9, 0x39c07b19 },\n        { 0x17c9e755, 0x2d45892b, -0x76cf7208, -0x2fcc028e, 0x525b8bd9, 0x6c2fe9d9, -0x3ee33f87, 0x2edbecf1 }\n    },\n    {\n        { -0x2f785da1, -0x11f0f023, 0x5c3e34ee, -0x638aceab, -0x7054c54b, 0x660c572e, 0x544cd3b2, 0x0854fc44 },\n        { -0x38ea5f2e, 0x1616a4e3, -0x07cbe2b3, 0x53623cb0, -0x38176635, -0x6910acd7, -0x5997455a, 0x3d4e8dbb },\n        { 0x55edad19, 0x61eba0c5, -0x0f57c21a, 0x24b533fe, -0x7c455a08, 0x3b770428, -0x675b8173, 0x678f82b8 }\n    },\n    {\n        { 0x57775696, 0x1e09d940, 0x3cd951db, -0x112ed9a4, 0x20bce16f, -0x056253d5, -0x172f760c, 0x0f7f76e0 },\n        { -0x296ff3ac, -0x4eb6e2f5, -0x62ecd9ca, 0x3539722c, 0x0b362bc9, 0x4db92892, -0x59749621, 0x4d7cd1fe },\n        { -0x2b7a4ff4, 0x36d9ebc5, -0x1b524c9b, -0x5da69b6e, -0x3dee6333, -0x3e9a6b80, 0x186e0d5f, 0x45306349 }\n    },\n    {\n        { 0x2b072491, -0x695beb14, 0x27a7b65b, 0x1bb22181, 0x6e8a4af0, 0x6d284959, -0x32d889a1, 0x65f3b08c },\n        { -0x593200e3, -0x6b222f3f, -0x17bdec52, 0x55f6f115, -0x66d03096, 0x6c935f85, 0x4a37f16f, 0x067ee0f5 },\n        { 0x199801f7, -0x134d6001, -0x5d5f08d1, -0x62c9e2e1, 0x75fd2f49, 0x25f11d23, 0x0fe10fe2, 0x124cefe8 }\n    },\n    {\n        { 0x31b16489, 0x1518e85b, -0x248ef405, -0x70552349, -0x5eb51dc7, 0x39b0bdf4, 0x503d20c1, 0x05f4cbea },\n        { -0x2e720dab, 0x4c126cf9, 0x147a63b6, -0x3e2b8e17, -0x0c36c4a1, 0x2c6d3c73, -0x1c00795e, 0x6be3a6a2 },\n        { -0x3fbeba44, -0x31fbf162, 0x08f6834c, -0x38e00b1e, -0x5477b85d, -0x42ab9173, -0x5b2d545b, 0x64666aa0 }\n    },\n    {\n        { 0x3337e94c, -0x4f3ac409, 0x11e14f15, 0x7cb5697e, 0x1930c750, 0x4b84abac, -0x1f9bfb98, 0x28dd4abf },\n        { 0x7c06d912, 0x6841435a, -0x44c07cf5, -0x35edc3df, -0x4e341d88, -0x2b4c84d9, -0x3890afba, 0x1d753b84 },\n        { 0x44cb9f44, 0x7dc0b64c, -0x1c6da241, 0x18a3e1ac, 0x2d0457c4, 0x7a303486, -0x75f376d2, 0x4c498bf7 }\n    },\n},\n{\n    {\n        { 0x30976b86, 0x22d2aff5, -0x3d2db9fc, -0x726f47fa, 0x4de5bae5, -0x235e7694, -0x37cbf3e9, 0x28005fe6 },\n        { 0x1aa73196, 0x37d653fb, 0x3fd76418, 0x0f949530, -0x04c5e84e, -0x52dff4f7, 0x2fc8613e, 0x544d4929 },\n        { 0x34528688, 0x6aefba9f, 0x25107da1, 0x5c1bff94, 0x66d94b36, -0x08a44433, 0x0f316dfa, 0x72e47293 }\n    },\n    {\n        { -0x2cd589d9, 0x07f3f635, 0x5f6566f0, 0x7aaa4d86, 0x28d04450, 0x3c85e797, 0x0fe06438, 0x1fee7f00 },\n        { -0x687ef7b1, 0x2695208c, 0x23450ee1, -0x4eafd5f5, 0x03efde02, -0x0262515a, 0x2733a34c, 0x5a9d2e8c },\n        { 0x03dbf7e5, 0x765305da, 0x1434cdbd, -0x5b250db7, -0x2db57714, 0x7b4ad5cd, -0x11fbfabd, 0x00f94051 }\n    },\n    {\n        { 0x07af9753, -0x28106c45, 0x3db766a7, 0x583ed0cf, 0x6e0b1ec5, -0x31966741, 0x5dd40452, 0x47b7ffd2 },\n        { -0x3c2ccf4e, -0x72ca94dd, -0x4fb8e4fa, -0x0de37465, 0x6e42b83c, -0x4c93ce94, -0x74154ef3, 0x07d79c7e },\n        { -0x43f722ee, -0x78040464, -0x1e113d65, -0x75f994c6, -0x24e03e41, 0x0d57242b, 0x5ea64bb6, 0x1c3520a3 }\n    },\n    {\n        { 0x216bc059, -0x325790c0, 0x12bcd87e, 0x1fbb231d, 0x17c70990, -0x4b6a9562, 0x66d12e55, 0x38750c3b },\n        { -0x43345cb6, -0x7f2dac5a, 0x3838219b, 0x3e61c3a1, -0x677d1c6a, -0x6f3c49ff, 0x5d0ee66f, 0x1c3d0577 },\n        { -0x6bdd1ae6, 0x692ef140, 0x2b5df671, -0x343f38c4, 0x744ce029, 0x21014fe7, -0x2ccfb784, 0x0621e2c7 }\n    },\n    {\n        { -0x4f240f0d, -0x4851e86a, -0x1e831e6a, 0x54dfafb9, -0x16555c4c, 0x25923071, -0x5effd163, 0x5d8e589c },\n        { -0x7da67c73, -0x50679f34, -0x39606524, -0x6f15b73f, 0x65581e30, 0x65264837, 0x7bd3a5bc, 0x0007d609 },\n        { 0x0842a94b, -0x3f40e26b, 0x588f2e3e, -0x4d2c3c9d, -0x44ae1d11, 0x0a961438, 0x3c1cbf86, 0x1583d778 }\n    },\n    {\n        { -0x3362d739, -0x6ffcb8fc, -0x08d33a71, 0x1d1b679e, -0x41a478da, 0x16e12b5f, -0x7c3aa7f6, 0x4958064e },\n        { 0x5da27ae1, -0x13115d11, 0x55670174, 0x597c3a14, 0x6609167a, -0x3659d5ee, -0x7e127090, 0x252a5f2e },\n        { 0x5066e80d, 0x0d289426, 0x307c8c6b, -0x033c087b, 0x0c1112fd, 0x1b53da78, -0x27bc4c78, 0x079c170b }\n    },\n    {\n        { -0x3f2a2faa, -0x322932b0, -0x44fca8c5, -0x65089793, -0x0c3c10b8, 0x3ca6723f, 0x317b8acc, 0x6768c0d7 },\n        { 0x64fa6fff, 0x0506ece4, 0x6205e523, -0x411cbce2, 0x51b8ea42, 0x35794224, 0x4ac9fb00, 0x6dec05e3 },\n        { -0x0eaa3e4d, -0x6b49da1b, -0x6684846f, 0x417bf3a7, 0x6d6b2600, -0x3dd34224, -0x2232ad0c, 0x51445e14 }\n    },\n    {\n        { 0x2bbea455, -0x76ceb855, -0x6df86ed7, -0x73ac5db1, -0x41cf0859, 0x4b49f948, 0x6e4fd43d, 0x12e99008 },\n        { 0x3b144951, 0x57502b4b, 0x444bbcb3, -0x71980095, 0x166385db, -0x474296d9, -0x1c6d6a38, 0x13186f31 },\n        { 0x7fdfbb2e, -0x0ef3694d, 0x121ceaf9, -0x60656ca2, 0x3a5b983f, -0x20eec93c, 0x5d3e99af, 0x77b2e3f0 }\n    },\n},\n{\n    {\n        { -0x33a32d65, -0x6acd0b71, -0x5c31c98f, 0x2ba851be, 0x51122941, 0x32dacaa0, 0x350004f2, 0x478d99d9 },\n        { -0x630ed9a9, -0x02f28a79, -0x1ac5f1d7, -0x17d0106c, 0x5bbb4be7, -0x33cb5810, -0x5af3c75e, 0x0b251172 },\n        { -0x6f44fd40, 0x1d5ad948, 0x0ec25115, 0x50e208b1, 0x4ef21702, -0x5d95dd77, 0x3b524805, 0x4dc92334 }\n    },\n    {\n        { -0x0c93b68b, 0x3ad3e3eb, 0x37862125, -0x28a2da5b, -0x5fda5aea, -0x178c6bc3, -0x3bee37b9, 0x6bbc7cb4 },\n        { 0x0f8086b6, -0x1c7d73c0, -0x6860f238, 0x3f77e6f7, 0x4df42cb4, 0x7ef6de30, -0x4954287c, 0x5265797c },\n        { -0x2b5af2aa, 0x3c6f9cd1, -0x39015482, -0x49dbbf89, 0x3580972e, 0x6ff9bf48, -0x4ccd5305, 0x00375883 }\n    },\n    {\n        { 0x6c75c99c, -0x3674137b, 0x00e33cf4, -0x1bbe7b40, -0x456f89cc, 0x0a676b9b, 0x71f379d7, 0x669e2cb5 },\n        { 0x28cb0940, 0x0001b2cd, 0x6f1c24c9, 0x63fb51a0, -0x232a35cf, -0x4a52796f, -0x73baf9a0, 0x67238dbd },\n        { -0x5b642cf8, -0x34ee948d, 0x2392729e, 0x025aad6b, 0x3f55d9b1, -0x4b86c106, 0x40678bb9, 0x72a10561 }\n    },\n    {\n        { -0x1d1afa4a, 0x0d8d2909, -0x3fd6edd0, -0x67358755, -0x564edcd9, 0x77ef5569, -0x7ebc64b9, 0x7c77897b },\n        { 0x1cc9249d, -0x5d497ed5, 0x21211f58, 0x62866eee, 0x5df10ece, 0x2cb5c5b8, -0x1d9c5200, 0x03a6b259 },\n        { -0x21cce34b, -0x0e3e4a1e, 0x15fca420, 0x5a9f5d8e, 0x7bd932b1, -0x605bc70f, 0x1c6146e7, 0x2a381bf0 }\n    },\n    {\n        { -0x4acbe991, -0x083f41ce, 0x19cf70d4, 0x27e6ca64, -0x56a858a7, -0x6cb20829, -0x54213d56, 0x5701461d },\n        { -0x3037ee3f, -0x53646787, 0x3756e567, -0x7482d67f, 0x7c70edfc, 0x50da4e60, -0x77bbff4a, 0x5dbca62f },\n        { 0x2c915c25, 0x2c674740, 0x0b0d340a, 0x1bdcd1a8, 0x07b43f5f, 0x5e5601bd, 0x5539a242, 0x2555b4e0 }\n    },\n    {\n        { -0x781b9c2c, 0x78409b1d, -0x32049c63, -0x52b256a6, 0x55259b9c, -0x13d788c9, -0x3cedcf55, 0x69c806e9 },\n        { 0x66ddd216, 0x6fc09f52, -0x371c8fb8, -0x231a9f59, -0x5d209d03, -0x139a6c63, -0x1ad12e6e, 0x7a869ae7 },\n        { 0x14bb3f22, 0x7b48f574, -0x51233378, 0x68c7cee4, 0x79ed80be, -0x12d06c9f, 0x5f77bc4b, 0x25d70b88 }\n    },\n    {\n        { -0x44e51b2c, -0x67ba62d7, 0x39f954ec, 0x56b9c4c7, -0x3d64b4c2, -0x7cd8bc0a, -0x67497876, 0x21ea8e27 },\n        { 0x762bf4de, 0x4151c3d9, 0x2745d82b, 0x083f435f, 0x0d23ddd5, 0x29775a2e, 0x69a5db24, 0x138e3a62 },\n        { 0x6a5a7b9c, -0x78410b4c, 0x5fc1d062, -0x2dd662e5, -0x22cde9b8, -0x7dbf67e8, -0x1a5d1fc3, 0x5c5abeb1 }\n    },\n    {\n        { 0x1306a233, 0x02cde6de, 0x116f8ec7, 0x7b5a52a2, -0x3ee9c4a5, -0x1e397e0c, 0x60d32643, 0x241d3506 },\n        { -0x48c3d225, 0x14722af4, 0x5a05060d, -0x43b8f3a1, 0x2581b02e, 0x00943eac, 0x1f499c8f, 0x0e434b3b },\n        { 0x0ebc52c7, 0x6be4404d, -0x4e586e0b, -0x51b9dcc5, -0x2da24bd5, 0x2aec170e, 0x6645d694, 0x1d8dfd96 }\n    },\n},\n{\n    {\n        { 0x12ddb0a4, -0x2a679c64, -0x3fdb7995, -0x5a2e60d0, 0x58fce460, -0x2e83d0fd, 0x2e095e8a, 0x07a19515 },\n        { -0x63d13b22, 0x296fa9c5, 0x4f84f3cb, -0x43749e41, 0x17a8f908, 0x1c7706d9, 0x7ad3255d, 0x63b795fc },\n        { 0x389e5fc8, -0x57c970fe, -0x30721bc5, -0x6fbcc4fe, -0x3abed9bd, -0x505e02a3, 0x032f0137, 0x3e8fe83d }\n    },\n    {\n        { -0x17102ec4, 0x08704c8d, 0x33e03731, -0x203ae572, 0x1260cde3, -0x5a62a25b, -0x59da737a, 0x22d60899 },\n        { 0x0570a294, 0x2f8b15b9, 0x67084549, -0x6b0dbd90, 0x61bbfd84, -0x21e3a51f, 0x7fac4007, 0x75ba3b79 },\n        { 0x70cdd196, 0x6239dbc0, 0x6c7d8a9a, 0x60fe8a8b, -0x14bfeda0, -0x4c77b844, -0x788861a2, 0x0904d07b }\n    },\n    {\n        { 0x48f940b9, -0x0bcdd29a, -0x42d2f3c7, 0x06952f0c, -0x5f7e06cf, 0x167697ad, -0x4508d594, 0x6240aace },\n        { -0x22456e64, -0x4b31e02c, -0x38b37256, -0x30ce24c2, -0x527933af, 0x2c63cc63, -0x43e221f9, 0x43e2143f },\n        { 0x5ba295a0, -0x07cb8b64, -0x35c82da6, -0x296b83a5, -0x1836ce96, 0x66f13ba7, -0x724bf354, 0x56bdaf23 }\n    },\n    {\n        { -0x3e62c44e, 0x1310d36c, 0x622386b9, 0x062a6bb7, -0x285eb0a4, 0x7c9b8591, 0x7e1e5754, 0x03aa3150 },\n        { -0x0acacc15, 0x362ab9e3, 0x6eb93d40, 0x338568d5, 0x1d5a5572, -0x61f1ebae, -0x7c8bece8, 0x1d24a86d },\n        { -0x002b31e1, -0x0b1389b8, 0x54ac8c1c, -0x1fba1510, 0x1d09357c, -0x772dda7e, -0x6514b7a7, 0x43b261dc }\n    },\n    {\n        { 0x6c951364, 0x19513d8b, 0x000bf47b, -0x6b018eda, -0x2ab06a99, 0x028d10dd, 0x42940964, 0x02b4d5e2 },\n        { -0x77448645, -0x1aa4e1e7, -0x3e85ca63, -0x5f612f83, 0x603dea33, -0x4fd3d11e, 0x5b276bc2, 0x326055cf },\n        { 0x28d18df2, -0x4b5eaa35, 0x186ce508, -0x1533b9ba, 0x6c824389, -0x3b630b6d, -0x51a2cbf0, 0x27a6c809 }\n    },\n    {\n        { -0x3bc296ac, -0x32d3d8f6, 0x6a66cab2, -0x22b5c1a9, 0x69d7036c, 0x79fa5924, 0x3d8c2599, 0x22150360 },\n        { 0x1f0db188, -0x74591433, 0x675a5be8, 0x37d3d73a, 0x15f5585a, -0x0dd1205d, -0x009f5e82, 0x2cb67174 },\n        { 0x390be1d0, 0x59eecdf9, 0x728ce3f1, -0x56bddfbc, 0x7a94f0f4, -0x7d76e39a, 0x3890f436, 0x7b1df4b7 }\n    },\n    {\n        { 0x07f8f58c, 0x5f2e2218, -0x2b6bf62c, -0x1caaa361, 0x1fb6a630, -0x4d555773, -0x2cad1fc3, 0x68698245 },\n        { -0x4c4d5ddc, -0x1b6d0d20, 0x2b551160, 0x7c6c9e06, 0x0d7f7b0e, 0x15eb8fe2, 0x58fc5992, 0x61fcef26 },\n        { 0x2a18187a, -0x244ea27b, -0x79225329, -0x0c1b552d, 0x0ff6c482, 0x44bae281, 0x3daf01cf, 0x46cf4c47 }\n    },\n    {\n        { -0x0eb67ec0, 0x213c6ea7, 0x392b4854, 0x7c1e7ef8, 0x5629ceba, 0x2488c38c, 0x0d8cc5bb, 0x1065aae5 },\n        { -0x613b1a07, 0x426525ed, 0x16903303, 0x0e5eda01, -0x341a3524, 0x72b1a7f2, 0x14eb5f40, 0x29387bcd },\n        { -0x20dff2a9, 0x1c2c4525, -0x403598b6, 0x5c3b2dd6, -0x1e7cbfd0, 0x0a07e7b1, 0x4f1ce716, 0x69a198e6 }\n    },\n},\n{\n    {\n        { -0x61d2b8cc, 0x7b26e56b, -0x7e39e98b, -0x3b38ecd5, -0x13632181, -0x10a36adb, -0x18e8bc53, 0x39c80b16 },\n        { -0x10562969, 0x7afcd613, 0x1c067959, 0x0cc45aa4, -0x3e05256a, -0x5a901efc, 0x72e40365, 0x3a73b704 },\n        { 0x1b826c68, 0x0f196e0d, 0x4960e3db, -0x08e00f1e, 0x23b7436c, 0x61131670, 0x77da7282, 0x0cf0ea58 }\n    },\n    {\n        { 0x3ba6945a, -0x1ccd312c, -0x177e3fa3, -0x21f4ec9f, 0x5e67ed3b, 0x1ad40f09, -0x4739c2a3, 0x5da8acda },\n        { -0x222b3343, 0x196c80a4, -0x6a0d2263, 0x22e6f55d, 0x40d6c71b, -0x38a1cc39, -0x34c3fbd1, 0x7bb51279 },\n        { 0x3a70159f, -0x3b4999b6, 0x0a904e14, 0x76194f0f, -0x5bf693ed, -0x5a9eb3c7, -0x68601313, 0x6cd0ff50 }\n    },\n    {\n        { -0x4fb45e72, 0x7fecfabd, 0x3bddbcf7, -0x2f038404, 0x057a131c, -0x5be2b792, -0x0dddc59f, 0x641a4391 },\n        { -0x70bbd754, -0x3f1f9819, -0x59eeca1d, 0x14835ab0, 0x38062935, -0x0de2eb0d, -0x20fb7b64, 0x6390a4c8 },\n        { -0x59f95725, -0x3a3946a6, -0x4f97da0f, -0x6eb48062, 0x44fc9eff, 0x2a731f6b, 0x62705cfc, 0x30ddf385 }\n    },\n    {\n        { 0x68bcd52c, 0x33bef2bd, 0x69482ef2, -0x39b62450, 0x41cb1aee, -0x4a4911f4, 0x0212a7e5, 0x5c294d27 },\n        { -0x2e400807, 0x4e3dcbda, 0x20645717, -0x36ee717e, 0x0f189d56, -0x45333144, -0x2bb98998, 0x1b4822e9 },\n        { 0x25563781, -0x54c9f581, 0x480f7958, 0x2512228a, 0x6114b4e3, -0x38a2fad9, -0x268901d6, 0x222d9625 }\n    },\n    {\n        { 0x0a344f85, 0x0f94be7e, -0x780dd3c8, -0x14d05574, 0x4ee16f0f, -0x631e18a2, 0x18a08dea, 0x43e64e54 },\n        { -0x4c8d531f, 0x1c717f85, 0x4638bf18, -0x7e6cf197, 0x6bc08b58, 0x239cad05, -0x7807000c, 0x0b34271c },\n        { 0x1a35ce63, -0x7eaa1dae, -0x06edfd72, -0x41eff2b3, -0x5a822314, -0x4007f408, 0x6d6bc6e4, 0x57342dc9 }\n    },\n    {\n        { 0x1e707bf6, -0x0c3c4349, 0x7291a762, 0x351d9b8c, -0x252965cd, 0x00502e6e, 0x1ec8807f, 0x522f521f },\n        { -0x3731a668, -0x10110f9b, -0x4a34155e, -0x40fd6af0, 0x20b7c458, -0x739b5efa, 0x31c24855, 0x35134fb2 },\n        { -0x065c6fd5, 0x272c1f46, -0x669a8434, -0x36e45c49, 0x4f8a1c0e, -0x519eb4d0, 0x0b99017b, 0x7afcaad7 }\n    },\n    {\n        { -0x107bd495, -0x577ebe14, -0x6854193b, 0x55e7b147, 0x03784ffe, -0x738b7069, -0x5032ff49, 0x5b50a1f7 },\n        { -0x5b4741bf, -0x3da212ac, 0x1bb0e2dd, -0x6fd2ec1f, -0x3217d54e, 0x41f43233, -0x3c551835, 0x1085faa5 },\n        { -0x0ec9eceb, -0x647bf09a, 0x701003e9, 0x18462242, -0x1b5daf80, 0x65ed45fa, 0x3fda7320, 0x0a286239 }\n    },\n    {\n        { 0x6ecb9d17, -0x69f18c85, -0x2983151f, -0x050db6b8, -0x2aa1e477, 0x37e7a9b4, -0x4b93a615, 0x5cb7173c },\n        { 0x347cbc9d, 0x46ab13c8, -0x663edc7d, 0x3849e8d4, -0x7829b537, 0x4cea3140, -0x4e5d6119, 0x1f354134 },\n        { -0x7d485410, 0x4a89e68b, -0x64594847, -0x0be326d9, -0x1e727891, 0x16e6c210, 0x7f1b09c6, 0x7cacdb0f }\n    },\n},\n{\n    {\n        { -0x233a3513, -0x1efebbcc, 0x3c84fb33, 0x47ed5d96, -0x12795f19, 0x70019576, -0x2d98061c, 0x25b2697b },\n        { -0x26e58744, -0x6f9d4d20, -0x37af6999, 0x47c9889c, 0x405070b8, -0x620ab59a, 0x2493a1bf, 0x7369e6a9 },\n        { 0x13986864, -0x6298c005, 0x415dc7b8, 0x3ca5fbd9, -0x20d8c4a2, -0x1fb133c5, -0x4ab1b32e, 0x1420683d }\n    },\n    {\n        { -0x3e33a530, 0x34eebb6f, -0x69b95375, 0x6a1b0ce9, -0x599421ad, -0x2c4f25b7, 0x61d081c1, 0x31e83b41 },\n        { 0x249dd197, -0x4b8742e2, 0x5e58c102, 0x620c3500, -0x334553a4, -0x04fd2cd1, -0x0af758d3, 0x60b63beb },\n        { -0x61f9d4b1, -0x681738ee, 0x29320ad8, 0x49e48f4f, 0x6f18683f, 0x5bece14b, 0x2d550317, 0x55cf1eb6 }\n    },\n    {\n        { 0x7df58c52, 0x3076b5e3, -0x186633ca, -0x28c54623, 0x4913ee20, -0x427ce31d, 0x62ba0133, 0x1a56fbaa },\n        { 0x65c23d58, 0x58791010, 0x5094819c, -0x7462f793, 0x12c55fa7, -0x1dbfd057, 0x570891d4, 0x669a6564 },\n        { 0x5c9dc9ec, -0x6bc194b0, -0x5883c8e6, 0x302557bb, 0x41347651, -0x678c51aa, -0x663a75a4, 0x13c48367 }\n    },\n    {\n        { 0x5d8bd080, -0x3b230496, 0x571a4842, -0x21143b14, -0x471aac9b, -0x2b4d177d, -0x371a47d9, 0x50bdc87d },\n        { 0x5ab3e1b9, 0x423a5d46, -0x380ec09f, -0x03ec3e79, -0x134a464a, 0x19f83664, -0x59c849f9, 0x66f80c93 },\n        { 0x6edfe111, 0x606d3783, -0x0fee5427, 0x32353e15, 0x25b73b96, 0x64b03ac3, 0x725fd5ae, 0x1dd56444 }\n    },\n    {\n        { 0x08bac89a, -0x3d681a00, -0x151e3c20, 0x7d4cea11, -0x60186884, -0x0c1c741f, 0x63a305cd, 0x3a3a450f },\n        { 0x3362127d, -0x705b8008, 0x71cd7c15, -0x4360953c, 0x49220c8b, 0x6e714543, 0x219f732e, 0x0e645912 },\n        { -0x27c6b9d9, 0x078f2f31, -0x216b5af0, 0x389d3183, 0x17996f80, -0x2e1c9393, -0x6c565785, 0x318c8d93 }\n    },\n    {\n        { -0x54e22c68, 0x5d669e29, 0x342d9e3b, -0x036de9a8, -0x0ca68c33, 0x55851dfd, 0x25950af6, 0x509a41c3 },\n        { 0x2afffe19, -0x0d8ba2fd, 0x7f24db66, 0x0c9f3c49, -0x457a6711, -0x43672c1d, -0x65e2acec, 0x224c7c67 },\n        { -0x5906da17, -0x423f9124, 0x641b1f33, 0x793ef3f4, -0x627cc177, -0x7d13ed80, 0x28a11389, 0x05bff023 }\n    },\n    {\n        { 0x0dc512e4, 0x6881a0dd, 0x44a5fafe, 0x4fe70dc8, -0x70b5adc0, 0x1f748e6b, -0x11fe5c16, 0x576277cd },\n        { 0x23cae00b, 0x36321370, -0x2e5330a7, 0x544acf0a, -0x2de5e378, -0x698befb7, -0x05d5bb59, 0x780b8cc3 },\n        { 0x234f305f, 0x1ef38abc, 0x1405de08, -0x65a88043, 0x34e62a0d, 0x5e82a514, 0x6271b7a1, 0x5ff41872 }\n    },\n    {\n        { 0x13b69540, -0x1a24b818, 0x432610e1, -0x0ca2d5c5, 0x38781276, -0x53e0d917, -0x5f5f3497, 0x29d4db8c },\n        { 0x1789db9d, 0x398e080c, -0x0c18870b, -0x589fdfdb, 0x06bd035d, -0x056776b4, 0x25a966be, 0x106a03dc },\n        { 0x333353d0, -0x2652f551, -0x532cf61b, 0x38669da5, -0x37770810, 0x3c57658a, 0x052cbefa, 0x4ab38a51 }\n    },\n},\n{\n    {\n        { -0x7f621fac, -0x09701d18, -0x637d452f, -0x1c43f696, 0x0aadbf45, 0x076353d4, -0x215e6a62, 0x7b9b1fb5 },\n        { 0x4324c0e9, -0x20253412, 0x3f955bb7, 0x05444288, -0x15ce9f61, -0x21085558, 0x42287cff, 0x68aee706 },\n        { 0x7471cc0c, -0x0fe3370f, 0x579082bb, -0x6adbd1c9, -0x2c1b94a1, 0x27776093, 0x28bd85fb, 0x2d13d55a }\n    },\n    {\n        { 0x7aee7a52, -0x40fe6332, -0x1bab152d, -0x57212d4a, -0x785744e7, 0x3c619f0b, 0x560916d8, 0x3619b5d7 },\n        { 0x5b35b8da, -0x053a2dfa, -0x7a9db449, -0x57257566, 0x3d21cd0f, -0x332d356f, -0x7406f2a8, 0x6b8341ee },\n        { 0x0282c4b2, 0x3579f26b, 0x4fafefae, 0x64d592f2, 0x28c8c7c0, -0x48321285, 0x7173a8d7, 0x6a927b6b }\n    },\n    {\n        { 0x3ece88eb, -0x728fbf7a, -0x7f113f74, -0x0f1cf857, 0x0d788fda, -0x53ddaf9f, 0x3a0d478d, 0x056d92a4 },\n        { -0x6791b9aa, 0x1f6db24f, -0x2e16efa5, 0x1021c02e, 0x2cc0a375, -0x0700c001, -0x3937da6e, 0x1d2a6bf8 },\n        { -0x03c25a5f, 0x1b05a196, 0x43b59ed0, 0x77d7a8c2, -0x682e86e8, 0x06da3d62, -0x0edcac09, 0x66fbb494 }\n    },\n    {\n        { -0x0edcf62a, -0x2928f66a, -0x163c2ac7, -0x2404dc7b, -0x08aadbef, 0x46d602b0, 0x57843e0c, 0x270a0b05 },\n        { -0x27a3f048, 0x751a50b9, -0x7430f685, -0x2e5023db, -0x7cf65697, 0x2f16a6a3, -0x1a4ff9a7, 0x14ddff9e },\n        { -0x5879d434, 0x61ff0640, 0x5f11abfe, -0x7e353f66, 0x55d12abb, -0x6fb87cfc, -0x6ba5178d, 0x19a4bde1 }\n    },\n    {\n        { -0x3f893b61, 0x40c709de, 0x7f3e53f6, 0x657bfaf2, -0x135fbd3c, 0x40662331, 0x7eb4df04, 0x14b37548 },\n        { 0x20a6200a, -0x6460d90b, -0x30ec1508, 0x64804443, -0x79ce122d, -0x759c98c1, 0x1ed39dc1, 0x72bbbce1 },\n        { -0x549923b9, -0x517ac36c, -0x2089d292, -0x149dcbc2, 0x6fb2f7d1, -0x0f71f1e8, 0x700ab37a, 0x4f0b1c02 }\n    },\n    {\n        { -0x3e4d1dc1, 0x79fd21cc, 0x453df52a, 0x4ae7c281, -0x2eaeb795, -0x37e8d137, 0x3e0a7534, 0x68abe944 },\n        { -0x27e6ae06, -0x1e8f9879, -0x4d6f3885, -0x5ef5d372, 0x3ed66773, -0x18c7d060, 0x0bcc4b54, 0x0a4d8471 },\n        { 0x07831dcb, -0x25ed393c, 0x4d5c510d, 0x0da230d7, 0x6bd404e1, 0x4ab1531e, -0x430bbf11, 0x4106b166 }\n    },\n    {\n        { 0x39e4ecf2, -0x5b7a332b, 0x0555bab5, 0x5aa3f3ad, -0x6c8207d3, 0x145e3439, 0x1214283f, 0x1238b51e },\n        { 0x1cd23668, 0x02e57a42, 0x0eaef6fd, 0x4ad9fb5d, -0x4edbbb80, -0x6ab198d9, 0x2699f331, 0x7f792f9d },\n        { 0x5fd4d924, 0x0b886b92, 0x3626a80d, 0x60906f7a, -0x467542ee, -0x132c984c, -0x210cbb31, 0x2876beb1 }\n    },\n    {\n        { 0x3a8a85f8, -0x2a6b4ccd, -0x187282a8, 0x4ea37689, 0x5e8e351f, 0x73bf9f45, -0x43be144c, 0x5507d7d2 },\n        { 0x63144691, -0x237b16cb, -0x29e0dc0c, 0x632fe8a0, 0x12a9a8d5, 0x4caa8006, 0x0e9918d3, 0x48f9dbfa },\n        { 0x299572fc, 0x1ceb2903, -0x6afd2f12, 0x7c8ccaa2, 0x11cce67b, -0x6e405bcc, 0x64a831e7, 0x57844819 }\n    },\n},\n{\n    {\n        { 0x5fddc09c, -0x29302e11, -0x08a8a232, -0x17d4c103, 0x201634c2, 0x25d56b5d, 0x04ed2b9b, 0x3041c6bb },\n        { 0x6768d593, -0x2583d4db, 0x4422ca13, -0x673e3fa9, -0x35f531e3, -0x0e57f42b, -0x3f775970, 0x29cdd1ad },\n        { -0x26a91eb8, 0x0ff2f2f9, -0x60ca94d2, -0x5218688b, 0x5f6c025c, 0x1a4698bb, 0x14049a7b, 0x104bbd68 }\n    },\n    {\n        { -0x29800e9d, -0x56a265a1, 0x4cc75681, -0x16d41963, -0x21df0da9, -0x4807fdb4, -0x04f8d20b, 0x204f2a20 },\n        { 0x68f1ed67, 0x51f0fd31, -0x2790c43e, 0x2c811dcd, 0x04d2f2de, 0x44dc5c43, 0x092a7149, 0x5be8cc57 },\n        { 0x30ebb079, -0x37ebc4c3, -0x429ad1d0, 0x7589155a, -0x7092a3cf, 0x653c3c31, -0x3d86e9e1, 0x2570fb17 }\n    },\n    {\n        { 0x0bb8245a, 0x192ea955, -0x706faf2f, -0x37190458, -0x775b36cb, 0x7986ea2d, -0x21fe7998, 0x241c5f91 },\n        { 0x2cb61575, 0x3efa367f, 0x1cd6026c, -0x0a06908a, 0x65b52562, -0x1738ebd6, 0x53030acd, 0x3dcb65ea },\n        { 0x40de6caa, 0x28d81729, 0x22d9733a, -0x7040d310, 0x235b01d1, 0x16d7fcdd, 0x5fcdf0e5, 0x08420edd }\n    },\n    {\n        { 0x04f410ce, 0x0358c34e, 0x276e0685, -0x49eca4a6, -0x1446eadf, 0x5d9670c7, 0x21db889c, 0x04d654f3 },\n        { -0x7c9d05b6, -0x3200df55, -0x1de5c192, 0x57e118d4, -0x03c619d5, -0x1ce869e9, -0x43e89603, 0x0d9a53ef },\n        { -0x22424a2b, 0x5e7dc116, -0x725a22d3, 0x2954deb6, 0x3334a292, 0x1cb60817, 0x18991ad7, 0x4a7a4f26 }\n    },\n    {\n        { -0x50c8d5b5, 0x24c3b291, 0x718147f2, -0x6c257d90, -0x7976610e, -0x227b7a9c, 0x23e0ee33, 0x4a963142 },\n        { 0x5fb15f95, -0x0b58e7fe, 0x6b5c1b8f, 0x3df65f34, 0x00e01112, -0x32030f7b, -0x222ce7b8, 0x11b50c4c },\n        { 0x08a4ffd6, -0x5917d8bc, -0x63ea8927, 0x738e177e, 0x3d02b3f2, 0x773348b6, -0x319433af, 0x4f4bce4d }\n    },\n    {\n        { -0x3b62f491, 0x30e2616e, -0x3513dce9, -0x1ba98e71, -0x0d94b05a, 0x48eb409b, 0x61595f37, 0x3042cee5 },\n        { -0x1ddbda7c, -0x58e031a6, -0x6d0a7562, 0x26ea7256, 0x1cea3cf4, -0x2de5f629, -0x48e3fe1a, 0x73fcdd14 },\n        { 0x449bac41, 0x427e7079, -0x431dcef6, -0x7aa51c93, 0x5f841a7c, 0x4cae7621, -0x65631e2a, 0x389e740c }\n    },\n    {\n        { 0x570eac28, -0x3642870a, 0x27919ce1, -0x1aa4f4ce, -0x5e646e13, 0x65fc3eab, -0x29d9c970, 0x25c425e5 },\n        { 0x34dcb9ce, 0x64fcb3ae, -0x1cb72f53, -0x68affcdd, 0x62c6381b, 0x45b3f07d, 0x465a6788, 0x61545379 },\n        { -0x0e282192, 0x3f3e06a6, -0x71f9dcf8, 0x3ef97627, 0x4e8a6c77, -0x73eb09da, 0x15484759, 0x6539a089 }\n    },\n    {\n        { 0x14bb4a19, -0x223b242c, -0x67bdb072, 0x19b2bc3c, 0x36ca7169, 0x48a89fd7, -0x0fe64270, 0x0f65320e },\n        { -0x3c2d088d, -0x162de08c, 0x25c46845, -0x3eafabbf, -0x064661cd, 0x624e5ce8, -0x3a32e794, 0x11c5e4aa },\n        { -0x35021f3a, -0x2b792e4f, 0x163b5181, 0x4f3fe6e3, -0x050d6c66, 0x59a8af0d, -0x13ccf8d6, 0x4cabc7bd }\n    },\n},\n{\n    {\n        { 0x1a54a044, -0x083f5e64, 0x77bd9fbb, 0x4a1c5e24, 0x5af22972, -0x591c35ef, 0x3f2e9e0d, 0x1819bb95 },\n        { 0x532f7428, 0x16faa8fb, 0x46a4e272, -0x242bd160, -0x74615b80, 0x5337653b, 0x23973f03, 0x40659472 },\n        { 0x5e042e84, 0x498fbb79, 0x7698b714, 0x7d0dd89a, 0x27fe6295, -0x7404f45c, 0x21200524, 0x36ba82e7 }\n    },\n    {\n        { 0x57274ed5, -0x372962f6, 0x60804b17, 0x45ba8032, 0x2255dfac, -0x20c325f0, 0x2709b339, 0x77d22123 },\n        { 0x4245ec41, -0x29f13449, 0x34348716, -0x02641762, -0x1bdd7b22, -0x36dbf502, -0x2face24c, 0x4472f648 },\n        { 0x64ad94d8, 0x498a6d70, -0x6509dd9d, -0x5a4a3703, 0x45c141f4, -0x735712fb, 0x662d358c, 0x2c63bec3 }\n    },\n    {\n        { -0x7a790741, -0x65ae74c6, -0x344e6910, -0x6118e50a, -0x5dc7a30e, -0x55f9da1a, -0x2228372f, 0x1deb2176 },\n        { -0x158786ab, 0x7fe60d8b, -0x4a0bfe49, -0x4623ee82, 0x19355cce, -0x6e383f66, -0x6bbd4121, 0x22692ef5 },\n        { 0x2066cf6c, -0x7a9c2e66, 0x4dcc7cd7, 0x401bfd8c, -0x32f2709e, -0x26895942, -0x5d874fa2, 0x67cfd773 }\n    },\n    {\n        { 0x5a4e586a, 0x2d5fa985, 0x49beab7e, 0x65f8f7a4, -0x0de2cc2d, -0x55f8b223, 0x1bcb9dee, 0x185cba72 },\n        { -0x10c11b8b, -0x7213ce06, -0x61dd026e, -0x66240076, 0x4e26cab1, 0x512d1159, -0x13bcef47, 0x0cde561e },\n        { -0x0b1c34bf, -0x6c79625d, 0x40f7977e, -0x40fc6d0b, -0x2fb9c47d, 0x026204fc, -0x61139113, 0x3ec91a76 }\n    },\n    {\n        { -0x4f5cbfd1, 0x0fad2fb7, -0x04960b58, 0x46615ecb, -0x3a07155a, -0x08ba4338, 0x4a94e896, 0x7a5fa879 },\n        { -0x087e9953, 0x1e9df75b, -0x14f32851, 0x4dfda838, -0x3e150678, -0x45ffd128, 0x11f33cfc, 0x13fedb3e },\n        { 0x13cd67a1, 0x52958faa, -0x74244ae9, -0x69a11f7f, 0x2e8845b3, 0x16e58daa, 0x5499da8f, 0x357d397d }\n    },\n    {\n        { 0x194bfbf8, 0x481dacb4, -0x451a7d67, 0x4d77e3f1, 0x7d1372a0, 0x1ef4612e, 0x70ff69e1, 0x3a8d867e },\n        { -0x4f453194, 0x1ebfa05f, 0x1caf9a1e, -0x36cb9df4, 0x1d82b61a, -0x3388e33c, -0x5a08b014, 0x2d94a16a },\n        { 0x55aff958, 0x6f58cd5d, 0x75567721, -0x45c155a4, -0x6e9add83, 0x75c12399, -0x3d0d4ca2, 0x69be1343 }\n    },\n    {\n        { 0x684b8de3, -0x7d444254, 0x3fca0718, -0x5d0b3830, -0x1f695558, 0x337f92fb, 0x63587376, 0x200d4d8c },\n        { -0x1e6836d6, 0x0e091d5e, 0x2945119f, 0x4f51019f, -0x0fcb1664, 0x143679b9, 0x4d24c696, 0x7d88112e },\n        { 0x4893b32b, 0x208aed4b, -0x41a6469c, 0x3efbf23e, -0x245a1af9, -0x289d2150, -0x7e42626c, 0x69607bd6 }\n    },\n    {\n        { -0x6cdc56fe, 0x3b7f3bd4, 0x6b2c6e53, 0x7c21b556, 0x3a7852a7, -0x1a45700b, -0x7c713200, 0x28bc77a5 },\n        { 0x68de1ce1, -0x0941fdf0, 0x0edcbc1f, -0x172ae719, 0x1b5505a5, -0x1c100230, -0x2c13c030, 0x35f63353 },\n        { -0x1da27fca, 0x63ba78a8, -0x6bcccb70, 0x63651e00, 0x288ce532, 0x48d82f20, 0x36b57524, 0x3a31abfa }\n    },\n},\n{\n    {\n        { 0x3f78d289, -0x3f708771, -0x5ebfb261, -0x01cf58d4, -0x309a3363, -0x0d887404, 0x5acb2021, 0x7ee49816 },\n        { 0x089c0a2e, 0x239e9624, 0x3afe4738, -0x38b73b40, 0x764fa12a, 0x17dbed2a, 0x321c8582, 0x639b93f0 },\n        { -0x6eee5e3d, 0x7bd508e3, -0x7f6f8b77, 0x2b2b90d4, -0x518d02e7, -0x182d513e, -0x7a49fd5a, 0x0edf493c }\n    },\n    {\n        { -0x7b89beed, 0x6767c4d2, -0x080a07cb, -0x5f6fbfc1, -0x35194122, 0x1c8fcffa, -0x2e205c97, 0x04c00c54 },\n        { 0x599b5a68, -0x51337ea8, -0x14521df2, -0x15a8b0f1, 0x22b67f07, 0x4fe41d74, 0x019d4fb4, 0x403b92e3 },\n        { -0x74b9a308, 0x4dc22f81, 0x1480eff8, 0x71a0f35a, 0x04c7d657, -0x51174053, -0x4d9e890c, 0x355bb12a }\n    },\n    {\n        { 0x5a8c7318, -0x5cfe2539, -0x4c3155ef, -0x126ffc63, 0x3bae3f2d, 0x6f077cbf, -0x1fad5272, 0x7518eaf8 },\n        { 0x7493bbf4, -0x58e19b34, -0x135c4f3d, -0x1a427b27, -0x05fa187b, 0x0a6bc50c, 0x182ec312, 0x0f9b8132 },\n        { 0x1b7f6c32, -0x5b77a63c, -0x0bc7cd68, 0x0f2d60bc, -0x364e2e27, 0x1815a929, -0x44e8aa3c, 0x47c3871b }\n    },\n    {\n        { -0x37af9950, -0x0419a2b0, -0x4c5d6650, 0x62ecc4b0, 0x441ae8e0, -0x1ac8ab16, -0x172b72a1, 0x08fea02c },\n        { 0x71ec4f48, 0x51445397, -0x3673a292, -0x07fa4e83, 0x47c3c66b, -0x089d3ee6, 0x764699dc, 0x00b89b85 },\n        { 0x68deead0, -0x7db2228a, 0x4b685d23, -0x379bbae0, 0x5d89d665, -0x4aeb3033, 0x4f75d537, 0x473829a7 }\n    },\n    {\n        { -0x52c6fd37, 0x23d9533a, -0x10fca771, 0x64c2ddce, -0x301ed04c, 0x15257390, 0x44e4d390, 0x6c668b4d },\n        { 0x4679c418, -0x7d2d258b, -0x4d9e7210, -0x19c42828, -0x53b814f6, 0x355eef24, 0x4833c6b4, 0x2078684c },\n        { 0x7a78820c, 0x3b48cf21, -0x7ed8c169, -0x0895f54e, -0x73711285, -0x56939a59, 0x4f8a433f, 0x7411a605 }\n    },\n    {\n        { 0x18b175b4, 0x579ae53d, -0x0c6d5efe, 0x68713159, 0x1eef35f5, -0x7baa1346, 0x458c398f, 0x1ec9a872 },\n        { -0x46623793, 0x4d659d32, 0x603af115, 0x044cdc75, -0x233d1b78, -0x4cb38ed4, -0x047ecb01, 0x7c136574 },\n        { 0x00a2509b, -0x47195b2c, 0x0bc882b4, -0x647e28fe, -0x0e6a8a9f, 0x57e7cc9b, -0x38329ba0, 0x3add88a5 }\n    },\n    {\n        { 0x59393046, -0x7a3d672c, 0x5ff659ec, -0x7081ca68, -0x0d0991c6, 0x1d2ca22a, -0x5bf958e0, 0x61ba1131 },\n        { -0x49ca230e, -0x5476a890, -0x0993e044, 0x02dfef6c, -0x41492e79, -0x7aacfd98, -0x3378618c, 0x249929fc },\n        { 0x16959029, -0x5c2f5f0f, -0x45814277, 0x023b6b6c, 0x26783307, 0x7bf15a3e, -0x44271319, 0x5620310c }\n    },\n    {\n        { 0x77e285d6, 0x6646b5f4, 0x6c8f6193, 0x40e8ff67, -0x544a6b23, -0x59138cef, 0x658cec4d, 0x7ec846f3 },\n        { 0x4934d643, 0x52899343, -0x5aeddd0b, -0x462407fa, -0x3c0be3de, -0x70927871, 0x4d9d9730, 0x37676a2a },\n        { 0x1da22ec7, -0x64a170c1, 0x6c01cd13, 0x130f1d77, -0x5d676048, 0x214c8fcf, 0x399b9dd5, 0x6daaf723 }\n    },\n},\n{\n    {\n        { 0x2cd13070, -0x7e514423, -0x07a5f162, -0x69d1bcdb, -0x35200135, -0x216c6e56, 0x52c230e6, 0x53177fda },\n        { 0x10628564, 0x591e4a56, -0x574b20cc, 0x2a4bb87c, -0x185c71bd, -0x21d5da8e, -0x011afb92, 0x3cbdabd9 },\n        { 0x50b9de79, -0x584368fa, -0x3cfe4a65, 0x3d12a7fb, -0x2c951c74, 0x02652e68, 0x5a6199dc, 0x79d73983 }\n    },\n    {\n        { 0x0d591737, 0x21c9d992, -0x164b932a, -0x6415be2e, 0x0d89bfca, -0x1df17be0, 0x6eae5ff8, 0x79d99f94 },\n        { 0x4131c1bd, -0x26cab20a, -0x7913a7de, 0x758094a1, -0x1ba60c3e, 0x4464ee12, -0x34eccd7e, 0x6c11fce4 },\n        { 0x68673205, -0x0e84b7cb, 0x3caad96c, 0x387deae8, 0x56ffe386, 0x61b471fd, -0x48ba5a67, 0x31741195 }\n    },\n    {\n        { 0x3b02a047, 0x17f8ba68, -0x01104938, 0x50212096, 0x1556cbe2, 0x70139be2, 0x1d98915b, 0x203e44a1 },\n        { -0x4885c9f5, -0x172efe70, -0x666a18fe, -0x66467ce0, -0x05fdb856, -0x42b02008, -0x1f2c9579, 0x2772e344 },\n        { 0x37b9e39f, -0x2979c146, 0x723b5a23, 0x105bc169, -0x59a3f89e, 0x104f6459, 0x5b4d38d4, 0x56795129 }\n    },\n    {\n        { 0x0d4b497f, 0x07242eb3, -0x46433379, 0x1ef96306, -0x27ee90bb, 0x37950934, 0x01405b04, 0x05468d62 },\n        { 0x13037524, 0x535fd606, -0x4f043d96, -0x1def520a, 0x23e990ae, -0x5372f565, -0x28d02407, 0x47204d08 },\n        { -0x06cd9822, 0x00f565a9, -0x3f2a7176, -0x31302873, -0x0ce71d72, -0x5dea1d24, -0x649cccae, 0x4599ee91 }\n    },\n    {\n        { -0x79e51a87, -0x538b9295, -0x09515624, 0x31ab0650, 0x40256d4c, 0x241d6611, 0x3d21a5de, 0x2f485e85 },\n        { 0x70e0e76b, -0x2c3ddf36, -0x1560cf6c, -0x4ed415a8, -0x3cd8ed7e, 0x294ddec8, -0x5e2e2fd8, 0x0c3539e1 },\n        { -0x63f7cc0d, 0x32974483, -0x2d543b7c, 0x6fe6257f, 0x4b358817, 0x5327d181, -0x76c01644, 0x65712585 }\n    },\n    {\n        { -0x28f711c1, -0x7e3d60e5, -0x519bf830, -0x2234a5fb, -0x2d5c1459, -0x68513e29, -0x6e2af7cf, 0x1590521a },\n        { 0x32a61161, -0x63efd049, 0x34d520a8, -0x1b71ef23, 0x6f9a9176, 0x365c6354, 0x046f6006, 0x32f6fe4c },\n        { -0x386ef534, 0x40a3a11e, -0x0e92d852, -0x6fec2008, -0x544e6a2c, 0x1a9720d8, 0x2ea98463, 0x1bb9fe45 }\n    },\n    {\n        { -0x33c98b84, -0x30a1936b, 0x6b0bc30d, 0x29420153, -0x11868510, 0x453ac67c, 0x2a8bb3c9, 0x5eae6ab3 },\n        { -0x4c2ab062, -0x162e26b0, -0x1ff2cc3f, 0x2d5f9cbe, -0x5fb03954, 0x51c2c656, 0x3c1cbcc9, 0x65c091ee },\n        { 0x14f118ea, 0x70836611, -0x6bcb6353, 0x2b37b87b, -0x4b1660c0, 0x7273f51c, 0x23d75698, 0x78a2a958 }\n    },\n    {\n        { 0x5ef83207, -0x4b0dc3be, -0x3656cb4b, -0x54076b2d, 0x39fd87f7, -0x2f8f73ed, 0x17166130, 0x18767891 },\n        { 0x5c8c2ace, -0x5d4f8d17, 0x651e9c4b, 0x69cffc96, 0x42e7b42b, 0x44328ef8, 0x22aadeb3, 0x5dd996c1 },\n        { 0x670c507c, -0x6da4a110, -0x46c3cc41, -0x7e6437be, 0x70dd003f, 0x10792e9a, 0x6e28dc74, 0x59ad4b7a }\n    },\n},\n{\n    {\n        { -0x5352715e, 0x583b04bf, 0x148be884, 0x29b743e8, 0x0810c5db, 0x2b1e583b, -0x714c4456, 0x2b5449e5 },\n        { -0x14c241b9, 0x5f3a7562, -0x71425f48, -0x0815c7ac, 0x45747299, 0x00c3e531, 0x1627d551, 0x1304e9e7 },\n        { 0x6adc9cfe, 0x789814d2, -0x74b722f5, 0x3c1bab3f, -0x068639f6, -0x25f01e01, 0x7c2dd693, 0x4468de2d }\n    },\n    {\n        { -0x079cf832, 0x4b9ad8c6, 0x435d0c28, 0x21113531, 0x657a772c, -0x2b57993b, 0x63247352, 0x5da6427e },\n        { -0x6be6b962, 0x51bb355e, 0x23ddc754, 0x33e6dc4c, 0x447f9962, -0x6c5a492a, -0x04bb429d, 0x6cce7c6f },\n        { -0x2153dd36, 0x1a94c688, -0x4451e008, -0x46f99109, -0x72a6a7f1, -0x775273c8, -0x1860d358, 0x58f29abf }\n    },\n    {\n        { 0x710ecdf6, 0x4b5a64bf, 0x462c293c, -0x4eb31ac8, -0x2af4c547, 0x3643d056, 0x185b4870, 0x6af93724 },\n        { -0x7218c198, -0x16f13055, 0x377e76a5, 0x54036f9f, -0x41fea67e, -0x0fb6a4f5, -0x580be1ca, 0x577629c4 },\n        { 0x09c6a888, 0x32200245, 0x4b558973, -0x2d1fc9ed, 0x3c33289f, -0x7c1dc9dd, 0x0caec18f, 0x701f25bb }\n    },\n    {\n        { 0x7cbec113, -0x62e70927, 0x74bfdbe4, -0x7bb5f91a, -0x53b19f2a, 0x20f5b522, 0x50955e51, 0x720a5bc0 },\n        { -0x1b9e9313, -0x3c574f08, -0x61da5783, -0x08ff99f2, -0x0b435a64, 0x61e3061f, -0x423bf417, 0x2e0c92bf },\n        { -0x647fa5cb, 0x0c3f0943, 0x6242abfc, -0x17b174c9, 0x5c229346, 0x691417f3, 0x144ef0ec, 0x0e9b9cbb }\n    },\n    {\n        { 0x5db1beee, -0x7211642b, 0x0a723fb9, -0x363c54c9, 0x1c68d791, 0x44a8f1bf, 0x1cfd3cde, 0x366d4419 },\n        { -0x04a8df53, -0x04452b71, -0x2406f2f2, -0x117e6e95, 0x635543bf, -0x2b7eceae, 0x3f337bd8, 0x221104eb },\n        { -0x0d4373ec, -0x61c3e8bd, -0x4a7a93c5, 0x2eda26fc, 0x68a7fb97, -0x3347d0f2, -0x43a6cdbc, 0x4167a4e6 }\n    },\n    {\n        { -0x07317012, -0x3d41d99b, -0x177f29d4, -0x169800ec, 0x2f364eee, -0x0ed19182, -0x34812d0a, 0x34b33370 },\n        { 0x76f62700, 0x643b9d28, 0x0e7668eb, 0x5d1d9d40, 0x21fc0684, 0x1b4b4303, 0x2255246a, 0x7938bb7e },\n        { -0x797e2934, -0x323a6e12, -0x127a58ad, -0x31fdef64, 0x58808883, -0x128b7a3f, 0x2dfe65e4, 0x1176fc6e }\n    },\n    {\n        { 0x49770eb8, -0x246f1d77, -0x530bbf5d, -0x670433d6, -0x21287865, 0x21354ffe, -0x0d96f94a, 0x1f6a3e54 },\n        { 0x5b9c619b, -0x4b509330, -0x4d5a7b80, 0x2ddfc9f4, -0x1416b23c, 0x3d4fa502, 0x677d5f34, 0x08fc3a4c },\n        { -0x2cf8cb16, 0x60a4c199, 0x31165cd6, 0x40c085b6, -0x08a67d6b, -0x1dccc1dd, 0x16b900d1, 0x4f2fad01 }\n    },\n    {\n        { -0x48c449c8, -0x69d326e3, -0x03ed63f8, -0x19fa8856, -0x0c49e977, 0x6f619b39, 0x2944ee81, 0x3451995f },\n        { -0x6b51b1ac, 0x44beb241, 0x1857ef6c, 0x5f541c51, 0x368d0498, -0x59e194d3, -0x68d10855, 0x445484a4 },\n        { -0x60158284, -0x6ead0330, -0x4f6ca30a, 0x4a816c94, 0x47285c40, 0x258e9aaa, 0x042893b7, 0x10b89ca6 }\n    },\n},\n{\n    {\n        { 0x79d34aa0, -0x2983212a, -0x33b24c61, -0x33f46140, -0x1ca2e6f1, -0x5aca5baa, -0x09e09011, 0x2e05d9ea },\n        { 0x3b646025, -0x64d5bd92, 0x385ce4cf, 0x32127190, -0x229215bb, -0x5da3003e, -0x4157218b, 0x06409010 },\n        { -0x29e414a7, -0x3bb86fe6, -0x1a2377f6, 0x661f19bc, -0x483597d9, 0x24685482, -0x101f80da, 0x293c778c }\n    },\n    {\n        { -0x5ee00e00, 0x16c795d6, -0x4ea7ea37, -0x348f2f1e, -0x64ac6a4b, -0x760d6ce0, 0x31e47b4f, 0x50b8c2d0 },\n        { 0x07069096, -0x797f6190, -0x1b1afe77, -0x5528a4eb, -0x5de5feb9, 0x07f35715, 0x12815d5e, 0x0487f3f1 },\n        { 0x068a4962, 0x48350c08, 0x51092c9a, 0x6ffdd053, -0x50903723, 0x17af4f4a, 0x3cdba58b, 0x4b0553b5 }\n    },\n    {\n        { 0x27c152d4, -0x40fadee5, -0x42e509c7, 0x5ec26849, -0x71905468, 0x5e0b2caa, 0x50bd0840, 0x054c8bdd },\n        { 0x1b32ff79, -0x639a0342, 0x03b50f9b, -0x148a1561, 0x6c07e606, -0x0312d594, 0x51717908, 0x35106cd5 },\n        { 0x1dcf073d, 0x38a0b12f, -0x48095d8a, 0x4b60a8a3, -0x2cbfb066, -0x012a53db, 0x5505c229, 0x72e82d5e }\n    },\n    {\n        { 0x69771d02, 0x00d9cdfd, 0x6cfbf17e, 0x410276cd, 0x1cb12ec7, 0x4c45306c, 0x27500861, 0x2857bf16 },\n        { -0x0f27bb38, 0x6b0b697f, -0x268634b7, -0x44ed07a4, -0x3e25f0e1, -0x2d5abe3a, 0x58ce7211, 0x7b7c2429 },\n        { 0x0101689e, -0x60de6fc1, -0x4079effb, -0x2886202d, 0x3deb0f1b, -0x5edd11a1, 0x485a00d4, 0x510df84b }\n    },\n    {\n        { -0x38f53ea2, 0x24b3c887, -0x047e48ce, -0x4f0c5aa9, -0x1a8733e5, -0x64d321d1, 0x03b54f8e, 0x4cf7ed07 },\n        { -0x6d885e06, -0x5abecc45, 0x63991237, 0x74ec3b62, 0x35d2f15a, 0x1a3c54dc, -0x1b7d45c6, 0x2d347144 },\n        { -0x670411f1, 0x6bd47c65, -0x54aa41d3, -0x61b8cc1e, 0x127610c5, 0x1093f624, -0x2f5e155c, 0x4e05e26a }\n    },\n    {\n        { -0x1e701940, 0x1833c773, -0x2c378d9b, -0x1c3b8ee6, 0x0116b283, 0x3bfd3c4f, -0x4b32b248, 0x1955875e },\n        { 0x4b531f20, -0x2564949e, 0x77509abb, 0x429a760e, -0x17dc3480, -0x24160ade, -0x77f3707e, 0x618f1856 },\n        { 0x0e399799, 0x6da6de8f, 0x40fda178, 0x7ad61aa4, 0x5e3563dd, -0x4cd327f0, 0x2ae340ae, 0x15f6beae }\n    },\n    {\n        { -0x6dba1deb, -0x4565f085, -0x2673f245, -0x0c979ed3, -0x0ddf4fe0, 0x2e84e4cb, 0x62d90eda, 0x6ba92fe9 },\n        { 0x31ec3a62, -0x79d434f4, 0x1138f3c2, -0x7ef1d4bb, 0x39dac2a4, 0x788ec4b8, -0x51d56d7f, 0x28f76867 },\n        { 0x5884e2aa, 0x3e4df965, -0x242b9a5b, -0x429d0425, 0x0de9e524, -0x28a69356, -0x4d4e4c29, 0x6e8042cc }\n    },\n    {\n        { 0x16521f7e, 0x15306536, -0x69dfc246, 0x660d06b8, 0x545f0879, 0x2d3989bc, 0x78ebd7b0, 0x4b5303af },\n        { -0x31d73592, -0x0ef2c3d7, -0x0349f6c3, -0x452cbac0, -0x5d15d2c1, -0x18bd9129, 0x4ff298b9, 0x08af9d4e },\n        { -0x41434218, 0x72f8a6c3, -0x23c57177, 0x4f0fca4a, -0x38402086, 0x6fa9d4e8, -0x649db149, 0x0dcf2d67 }\n    },\n},\n{\n    {\n        { 0x5a45f06e, 0x753941be, 0x6d9c5f65, -0x2f835113, 0x72ff51b6, 0x11776b9c, -0x10f2b257, 0x17d2d1d9 },\n        { -0x68e7d764, 0x3d594749, 0x24533f26, 0x12ebf8c5, 0x14c3ef15, 0x0262bfcb, 0x77b7518e, 0x20b878d5 },\n        { 0x073f3e6a, 0x27f2af18, -0x28adef97, -0x02c01ae7, 0x3ca60022, 0x22e3b72c, -0x339a3959, 0x72214f63 }\n    },\n    {\n        { -0x0bc4d637, 0x1d9db7b9, 0x4f518f75, -0x29fa7db6, 0x312f9dc4, -0x0d3f8d43, 0x5a1545b0, 0x1f24ac85 },\n        { 0x5307a693, -0x4b1c80c0, 0x2f336795, -0x5458eb29, 0x73761099, -0x29042f59, -0x7e8e3437, 0x5fdf48c5 },\n        { -0x716afa56, 0x24d60832, 0x0c1420ee, 0x4748c1d1, 0x06fb25a2, -0x38001ba4, 0x2ae395e6, 0x00ba739e }\n    },\n    {\n        { -0x157744da, -0x51bbd90b, -0x7b68c405, 0x360679d9, 0x26694e50, 0x5c9f030c, -0x2ae72dda, 0x72297de7 },\n        { 0x5c8790d6, 0x592e98de, 0x45c2a2df, -0x1a40482d, -0x064b66de, 0x115a3b60, 0x67ad78f3, 0x03283a3e },\n        { -0x41f346c7, 0x48241dc7, -0x749ccf80, 0x32f19b4d, 0x02289308, -0x2c2036f3, 0x46271945, 0x05e12968 }\n    },\n    {\n        { 0x242c4550, -0x52404438, -0x2fcf7e27, -0x4337f314, -0x0a37206e, -0x7bca995a, -0x7da731b4, 0x78cf25d3 },\n        { 0x2d9c495a, -0x457d114d, -0x0ed44684, -0x31103704, -0x6c4a2e20, -0x4fd25452, 0x13698d9b, 0x39c00c9c },\n        { 0x31489d68, 0x15ae6b8e, -0x63d40f79, -0x557ae355, -0x0fb105fb, -0x3658a569, 0x6b3ff832, 0x006b5207 }\n    },\n    {\n        { -0x4631f7d3, -0x0a3481ea, 0x417abc29, 0x3407f14c, 0x2bf4a7ab, -0x2b4c9432, 0x1a9f75ce, 0x7de2e956 },\n        { -0x626a87e4, 0x29e0cfe1, -0x699cef1e, -0x497e20e8, 0x70516b39, 0x57df39d3, 0x3bc76122, 0x4d57e344 },\n        { -0x495aa135, -0x218f2b0c, 0x5d85db99, 0x4801527f, -0x2c11657f, -0x24363bc0, 0x1a6029ed, 0x6b2a90af }\n    },\n    {\n        { 0x5bb2d80a, 0x77ebf324, 0x2fb9079b, -0x27cfe4b9, 0x4cee7333, -0x39b8190e, 0x276c2109, 0x465812c8 },\n        { -0x6519e169, 0x6923f4fc, -0x1fc0a02f, 0x5735281d, -0x19122ed3, -0x589b51bd, -0x2ed2c1b6, 0x5fd8f4e9 },\n        { 0x2a1062d9, 0x4d43beb2, 0x3831dc16, 0x7065fb75, -0x21d69729, 0x180d4a7b, 0x1cb16790, 0x05b32c2b }\n    },\n    {\n        { 0x7ad58195, -0x08035bd4, 0x4333f3cc, 0x3214286e, 0x340b979d, -0x493d62f3, 0x567307e1, 0x31771a48 },\n        { -0x2db25703, -0x373fa134, 0x05dfef83, -0x5e30e554, 0x7df9cd61, -0x2441100e, 0x7b471e99, 0x3b5556a3 },\n        { -0x1eb22b7e, 0x32b0c524, 0x1a2ba4b6, -0x124caeac, 0x282b5af3, -0x5c2e9fb8, 0x7a7336eb, 0x4fc079d2 }\n    },\n    {\n        { 0x0c86c50d, -0x23cb74bc, -0x336b19af, 0x1337cbc9, 0x643e3cb9, 0x6422f74d, -0x451c32f8, 0x241170c2 },\n        { -0x7640d081, 0x51c938b0, 0x02dfe9a7, 0x2497bd65, 0x7880e453, -0x00003f64, -0x3506716e, 0x124567ce },\n        { 0x0ac473b4, 0x3ff9ab86, 0x0113e435, -0x0f6ee212, -0x14393b51, 0x4ae75060, 0x6c87000d, 0x3f861296 }\n    },\n},\n{\n    {\n        { 0x638c7bf3, 0x529fdffe, 0x388b4995, -0x20d461a0, 0x1bad0249, -0x1fd84cb1, -0x46058b13, 0x7bc92fc9 },\n        { -0x086a841c, 0x0c9c5303, -0x1f7a3ebb, -0x5c3ce5e0, -0x2f7affb0, -0x4f8de28f, -0x54f40d26, 0x0aba390e },\n        { -0x7fe52607, -0x606810d2, 0x79afda3a, -0x7c9682ac, -0x42a694b0, -0x16f94c01, -0x22c04720, 0x02672b37 }\n    },\n    {\n        { 0x398ca7f5, -0x116458d7, 0x7a4849db, -0x146359db, 0x7ec544e1, 0x29eb29ce, -0x08c91d38, 0x232ca21e },\n        { 0x260885e4, 0x48b2ca8b, -0x7d4cb3e4, -0x5bd79414, 0x17f58f74, -0x6c81e5da, -0x54d35d5b, 0x741d1fcb },\n        { 0x253fcb17, -0x409ebdc3, -0x05c614ec, 0x08803cea, -0x67ae3851, -0x0e79fd21, 0x49e3414b, 0x0400f3a0 }\n    },\n    {\n        { -0x5f9184fa, 0x2efba412, 0x2c8d2560, 0x14678545, -0x29856e39, -0x2068ec15, 0x157eadf3, 0x32830ac7 },\n        { -0x459e3aa5, -0x5431fb8a, -0x3b2c68ea, 0x36a3d6d7, -0x1727d2f7, 0x6eb259d5, -0x7b28a905, 0x0c9176e9 },\n        { -0x48c89618, 0x0e782a7a, 0x75b18e2c, 0x04a05d78, -0x1433151f, 0x29525226, -0x7c1457e0, 0x0d794f83 }\n    },\n    {\n        { -0x585d1e54, 0x7be44ce7, -0x052e4749, 0x411fd93e, 0x0d5f7c9b, 0x1734a1d7, 0x3127db16, 0x0d659223 },\n        { -0x61eae90c, -0x00ca0a35, 0x648aae45, -0x117fa431, -0x46c5610d, -0x0f28c3d5, 0x2092a6c2, 0x097b0bf2 },\n        { 0x21a9d733, -0x3b7454eb, -0x29e544db, -0x593d1516, -0x3934bcfb, 0x625c6c1c, -0x6c14c599, 0x7fc90fea }\n    },\n    {\n        { -0x63834dc3, -0x3ad8214b, 0x5328404e, -0x6aac6e97, 0x7ccf2c7a, -0x29bc6d7f, -0x082705ef, 0x6ce97dab },\n        { 0x1f5c5926, 0x0408f1fe, 0x3b258bf4, 0x1a8f2f5e, -0x0238e997, 0x40a951a2, -0x3674a882, 0x6598ee93 },\n        { 0x0ef7c48f, 0x25b5a8e5, 0x6f2ce532, -0x149fcbef, -0x1ac21ac9, -0x3a18ae8d, -0x73ed44fd, 0x73119fa0 }\n    },\n    {\n        { 0x21f4774d, 0x7845b94d, 0x7897b727, -0x409d0e94, 0x3c56522b, 0x671857c0, -0x6a9dedee, 0x3cd6a852 },\n        { 0x53f1a4cb, -0x12cfed6c, -0x370ac879, -0x4319de37, 0x38bee7b9, -0x0534d4ed, -0x6157bd74, 0x3025798a },\n        { 0x3aeca999, 0x3fecde92, 0x62e8c12f, -0x4255a500, -0x69677522, 0x67b99dfc, 0x52661036, 0x3f52c028 }\n    },\n    {\n        { -0x113be93a, -0x6da74067, -0x562d098f, -0x5375afe9, 0x16dea4ab, 0x629549ab, -0x66f6ea97, 0x05d0e85c },\n        { 0x2a1351c6, -0x00155b72, -0x0580ac29, 0x28624754, 0x7582ddf1, 0x0b5ba9e5, -0x596953a7, 0x60c0104b },\n        { -0x21634169, 0x051de020, -0x4af4308c, -0x05f803aa, 0x0f11df65, 0x378cec9f, -0x546921b3, 0x36853c69 }\n    },\n    {\n        { -0x053a1842, 0x4433c0b0, 0x4c08dcbe, 0x724bae85, 0x46978f9b, -0x0e0db33c, 0x62825fc8, 0x4a0aff6d },\n        { 0x78f39b2d, 0x36d9b8de, -0x57b84614, 0x7f42ed71, 0x79bd3fde, 0x241cd1d6, -0x6d043195, 0x6a704fec },\n        { 0x61095301, -0x16e80462, 0x02a092f8, -0x3efd206c, -0x0599e6f5, -0x40f61d0b, -0x1f2301c9, 0x681109be }\n    },\n},\n{\n    {\n        { 0x36048d13, -0x63e70306, 0x73899ddd, 0x29159db3, -0x606d2f56, -0x2360caf5, -0x7875e62c, 0x26f57eee },\n        { 0x782a0dde, 0x559a0cc9, -0x158e7c7b, 0x551dcdb2, 0x31ef238c, 0x7f62865b, 0x7973613d, 0x504aa776 },\n        { 0x5687efb1, 0x0cab2cd5, 0x247af17b, 0x5180d162, 0x4f5a2467, -0x7a3ea5cc, -0x6245cf97, 0x4041943d }\n    },\n    {\n        { -0x5d935523, 0x4b217743, 0x648ab7ce, 0x47a6b424, 0x03fbc9e3, -0x34e2b086, -0x67ff2fe7, 0x12d93142 },\n        { 0x43ebcc96, -0x3c3f1146, 0x26ea9caf, -0x728b6364, 0x1c77ccc6, -0x26056a12, 0x7684340f, 0x1420a1d9 },\n        { -0x2cc8a6b1, 0x00c67799, -0x4dc55b85, 0x5e3c5140, -0x1ca00c6b, 0x44182854, 0x4359a012, 0x1b4f9231 }\n    },\n    {\n        { -0x5b67994f, 0x33cf3030, 0x215f4859, 0x251f73d2, 0x51def4f6, -0x547d55c0, 0x6f9a23f6, 0x5ff191d5 },\n        { -0x76eaf6af, 0x3e5c109d, 0x2de9696a, 0x39cefa91, -0x68a0cfe0, 0x20eae43f, 0x7f132dae, 0x239b572a },\n        { -0x53d26f98, -0x7e612bcd, 0x5fc98523, 0x2883ab79, 0x5593eb3d, -0x10ba8d80, 0x758f36cb, 0x020c526a }\n    },\n    {\n        { -0x0fbd3377, -0x16ce10a7, -0x71edb44a, 0x2c589c9d, -0x5138a669, -0x52371e76, 0x5602c50c, 0x452cfe0a },\n        { -0x61272444, 0x779834f8, -0x23835b94, -0x370d5507, -0x5c1e4f8c, -0x56adb324, 0x15313877, 0x02aacc46 },\n        { 0x647877df, -0x795f0860, 0x0e607c9f, -0x443b9bd9, -0x0e04ee37, -0x54e815db, 0x304b877b, 0x4cfb7d7b }\n    },\n    {\n        { -0x687610ee, -0x1d79663e, -0x20a8e6f3, 0x2b6ecd71, -0x13368f30, -0x3cbc37a9, 0x434d3ac5, 0x5b1d4cbc },\n        { -0x47648a02, 0x72b43d6c, -0x63952380, 0x54c694d9, 0x3ee34c9f, -0x473c55c9, 0x39075364, 0x14b4622b },\n        { -0x33f560da, -0x4904d9eb, -0x4772331b, 0x3a4f0e2b, 0x3369a705, 0x1301498b, 0x58592dd1, 0x2f98f712 }\n    },\n    {\n        { 0x4f54a701, 0x2e12ae44, -0x56342822, -0x0301c110, 0x75835de0, -0x314076f3, -0x189ebaac, 0x1d8062e9 },\n        { -0x4af061aa, 0x0c94a74c, -0x7171ece0, 0x5b1ff4a9, -0x7dcff099, -0x65d533df, -0x27f95507, 0x3a6ae249 },\n        { -0x566f83a6, 0x657ada85, -0x6e46f09e, 0x1a0ea8b5, -0x20cb4b17, -0x72f1e205, -0x510da00d, 0x298b8ce8 }\n    },\n    {\n        { 0x0a2165de, -0x7c858d16, 0x0bcf79f6, 0x3fab07b4, 0x7738ae70, 0x521636c7, 0x03a7d7dc, 0x6ba62718 },\n        { -0x1008f34e, 0x2a927953, 0x79157076, 0x4b89c92a, 0x30a7cf6a, -0x6be7ba86, 0x4d5ce485, 0x34b8a840 },\n        { -0x7c96cccb, -0x3d91134b, 0x63b5fefd, -0x2a57ec21, -0x5b4dda8d, -0x5d6c5566, 0x465e1c6a, 0x71d62bdd }\n    },\n    {\n        { -0x4e08a10b, -0x32d24a26, 0x16b065f5, -0x28806a31, 0x3f49f085, 0x14571fea, 0x262b2b3d, 0x1c333621 },\n        { -0x2c872080, 0x6533cc28, 0x0a0fa4b4, -0x0924bc87, -0x08fe25a6, -0x1c9ba007, -0x0ce8d45c, 0x74d5f317 },\n        { 0x67d9ca81, -0x57901aac, 0x2b298c37, 0x398b7c75, -0x1c539dc5, -0x2592f76e, 0x47e9d98c, 0x4aebcc45 }\n    },\n},\n{\n    {\n        { -0x5fa65bbb, 0x0de9b204, 0x4b17ad0f, -0x1ea34b56, 0x1f79c557, -0x1e4413ae, -0x2f8ef7e5, 0x2633f1b9 },\n        { 0x05d21a77, 0x53175a72, -0x2c46cb2c, -0x4f3fbbde, -0x22a21524, -0x52260db5, -0x60ef0074, 0x074f46e6 },\n        { 0x018b9910, -0x3e04be89, 0x6c0fe140, -0x5915df24, 0x4354c6ff, -0x299e0c19, -0x0e5cbf86, 0x5ecb72e6 }\n    },\n    {\n        { -0x17179669, -0x01151efa, -0x672f6c7d, -0x679ccc81, -0x55f91411, -0x6b8fb7f2, -0x2b3a3d30, 0x038b6898 },\n        { 0x2259fb4e, -0x5aea5ce5, 0x2bcac52f, 0x0960f397, -0x72cbab35, -0x124ad014, -0x3b893fe7, 0x382e2720 },\n        { -0x7531af5a, -0x0c6e3ae3, -0x51d2d6b8, 0x3142d0b9, 0x7f24ca80, -0x24b2a5e6, 0x59250ea8, 0x21aeba8b }\n    },\n    {\n        { -0x0ff780dd, 0x53853600, -0x2582a87c, 0x4c461879, -0x4be097a0, 0x6af303de, -0x3d83e713, 0x0a3c16c5 },\n        { -0x30bfaad0, 0x24f13b34, 0x43088af7, 0x3c44ea4a, 0x0006a482, 0x5dd5c517, -0x76f4f793, 0x118eb8f8 },\n        { -0x336b80c3, 0x17e49c17, -0x553e2d85, -0x3339125a, -0x4f0f71aa, -0x209f6d32, 0x2c67c36b, 0x4909b3e2 }\n    },\n    {\n        { 0x706ff64e, 0x59a16676, 0x0d86a53d, 0x10b953dd, -0x31a3f46a, 0x5848e1e6, 0x12780c68, 0x2d8b78e7 },\n        { 0x63fe2e89, -0x63637a16, 0x0e9412ec, -0x41e4506f, -0x79040185, -0x70845576, -0x10697494, 0x0fb17f9f },\n        { -0x503c6fd5, 0x79d5c62e, -0x7617f8d8, 0x773a2152, -0x1efedf47, -0x3c7519c0, 0x7b2b1a6d, 0x09ae2371 }\n    },\n    {\n        { -0x52cd4e30, 0x10ab8fa1, -0x1d8874dc, -0x165312e5, 0x373de90f, -0x577a9440, -0x225ac66a, 0x66f35ddd },\n        { 0x4e4d083c, -0x4495e6d6, 0x0029e192, 0x34ace063, -0x55054515, -0x67dba5a7, -0x25680554, 0x6d9c8a9a },\n        { 0x24997323, -0x2d826505, -0x090fe2d2, 0x1bb7e07e, -0x0ad13381, 0x2ba7472d, 0x646f9dc8, 0x03019b4f }\n    },\n    {\n        { -0x194c2395, -0x50f64dec, -0x5282d09b, 0x3f7573b5, 0x100a23b0, -0x2fe62678, -0x74a3ca09, 0x392b63a5 },\n        { 0x565345cd, 0x04a186b5, -0x433bee96, -0x111899f0, 0x78fb2a45, 0x689c73b4, 0x65697512, 0x387dcbff },\n        { -0x63f83dfb, 0x4093addc, -0x0acd3c82, -0x3a9a41eb, 0x1583402a, 0x63dbecfd, -0x10d1fcd2, 0x61722b4a }\n    },\n    {\n        { -0x7e34f1c4, -0x294f85ab, -0x26bbb697, 0x290ff006, 0x16dcda1f, 0x08680b6a, 0x5a06de59, 0x5568d2b7 },\n        { -0x1342b851, 0x0012aafe, 0x1cd46309, 0x55a266fb, 0x0967c72c, -0x0dfc1498, -0x35c3ebd7, 0x39633944 },\n        { 0x1b37cfe1, -0x72f34774, 0x053818f3, 0x05b6a5a3, -0x487826a7, -0x0d1643fc, -0x6522809c, 0x6beba124 }\n    },\n    {\n        { 0x43f5a53b, 0x5c3cecb9, 0x06c08df2, -0x633659e3, -0x7a76abb9, -0x30459c66, 0x0df09fd5, 0x5a845ae8 },\n        { -0x5a4e4ebd, 0x1d06005c, 0x7fd1cda2, 0x6d4c6bb8, 0x53fcffe7, 0x6ef59676, -0x3e31e15b, 0x097c29e8 },\n        { 0x5deb94ca, 0x4ce97dbe, -0x738f63b8, 0x38d0a438, -0x5e962f69, -0x3bc1312c, -0x081a783d, 0x0a1249ff }\n    },\n},\n{\n    {\n        { 0x7354b610, 0x0b408d9e, 0x5ba85b6e, -0x7f94cdad, 0x4a58a207, -0x2419c5fd, -0x365e20d4, 0x173bd9dd },\n        { 0x276d01c9, 0x12f0071b, -0x793b7390, -0x1847453b, 0x71d6fba9, 0x5308129b, 0x5a3db792, 0x5d88fbf9 },\n        { -0x01a78d21, 0x2b500f1e, -0x2bc6e73f, 0x58d6582e, -0x3698c520, -0x1912d872, -0x4e615ce7, 0x06e1cd13 }\n    },\n    {\n        { -0x61a4fcad, 0x472baf62, 0x278d0447, 0x3baa0b90, -0x69bc40d9, 0x0c785f46, -0x727c84ed, 0x7f3a6a1a },\n        { 0x6f166f23, 0x40d0ad51, 0x1fab6abe, 0x118e3293, -0x5fb2f772, 0x3fe35e14, 0x26e16266, 0x30806035 },\n        { 0x5d3d800b, -0x0819bbc7, -0x36fe120a, -0x6a572aab, 0x592c6339, 0x68cd7830, 0x2e51307e, 0x30d0fded }\n    },\n    {\n        { 0x68b84750, -0x634b68e2, 0x6664bbcf, -0x5f6a8dd7, 0x72fa412b, 0x5c8de726, 0x51c589d9, 0x46150843 },\n        { -0x0dedcc4d, -0x1fa6b2e6, -0x0f33b264, 0x1bdbe78e, -0x70b66589, 0x6965187f, 0x2c099868, 0x0a921420 },\n        { -0x51465fd2, -0x436fe640, 0x16034cae, 0x55c7110d, 0x659932ec, 0x0e6df501, -0x6a35a202, 0x3bca0d28 }\n    },\n    {\n        { -0x6133fe41, -0x6397714a, -0x59bb7691, -0x0f437c53, 0x5f7a9fe2, -0x35d26aa1, -0x720d7dbf, 0x4ea8b403 },\n        { 0x3c5d62a4, 0x40f031bc, -0x300f85a0, 0x19fc8b3e, 0x130fb545, -0x67e7c25e, -0x5170ec33, 0x5631dedd },\n        { -0x0e352dfe, 0x2aed460a, -0x5b73117d, 0x46305305, 0x49f11a5f, -0x6ede88bb, 0x542ca463, 0x24ce0930 }\n    },\n    {\n        { -0x020cf47b, 0x3fcfa155, 0x36372ea4, -0x2d08e972, 0x6492f844, -0x4d1f9b22, 0x324f4280, 0x549928a7 },\n        { -0x02f93efa, 0x1fe890f5, 0x5d8810f2, -0x4a3b97cb, 0x6e8caf3e, -0x7d87f702, -0x75f928b5, 0x41d4e3c2 },\n        { 0x63ee1a2e, -0x0d91cd59, -0x2da00216, -0x516e1b49, -0x2e80b297, -0x43c42cc5, -0x3f230096, 0x491b66de }\n    },\n    {\n        { -0x2f259b5f, 0x75f04a8e, 0x67e2284b, -0x12ddd351, 0x1f7b7ba4, -0x7dcb5c87, -0x48fe7499, 0x4cf6b8b0 },\n        { -0x3815cd59, -0x670a4ec3, 0x7e16db98, -0x1c2a0734, -0x340726b9, -0x53f540ae, -0x37a11b54, 0x08f338d0 },\n        { -0x66e58c43, -0x3c7c57df, -0x20cdf386, -0x54d843ff, -0x7b888f9d, -0x3ec2cce5, -0x14f87567, 0x530d4a82 }\n    },\n    {\n        { 0x6c9abf9e, 0x6d697345, 0x4900a880, 0x257fb2fc, -0x373047b0, 0x2bacf412, 0x0cbfbd5b, 0x0db3e7e0 },\n        { -0x1e06b7db, 0x004c3630, -0x7354aca6, 0x7e2d7826, -0x337b0075, -0x38b7dcdd, 0x101770b9, 0x65ea753f },\n        { -0x1df69c9d, 0x3d66fc3e, 0x61b5cb6b, -0x7e29d381, 0x13443b1a, 0x0fbe0442, 0x21e1a1db, 0x02a4ec19 }\n    },\n    {\n        { -0x0e3086a1, -0x0a379e9e, 0x26ee57f2, 0x118c8619, 0x1c063578, 0x17212485, -0x13f98031, 0x36d12b5d },\n        { 0x3b24b8a2, 0x5ce6259a, 0x45afa0b8, -0x47a88534, -0x745f8fc9, -0x33341918, 0x127809bf, 0x3d143c51 },\n        { 0x79154557, 0x126d2791, -0x0387c5f6, -0x2a1b70a4, -0x20e86454, 0x36bdb6e8, 0x5ba82859, 0x2ef51788 }\n    },\n},\n{\n    {\n        { 0x7c6da1e9, 0x1ea43683, 0x1fb9bdbe, -0x063e7651, -0x31a22eab, 0x303001fc, -0x43a841ae, 0x28a7c99e },\n        { -0x2ee1f2b6, -0x7742bc74, 0x43ccf308, 0x30cb610d, -0x6e6c8434, -0x1f65f1c9, 0x25b1720c, 0x4559135b },\n        { -0x172e6163, -0x47026c67, -0x69dbdc01, -0x6f7e6e35, 0x47c742a3, -0x4d46b729, -0x2804bb3c, 0x37f33226 }\n    },\n    {\n        { -0x37de4ee3, 0x33912553, 0x41e301df, 0x66ed42c2, 0x104222fd, 0x066fcc11, -0x3e6de971, 0x307a3b41 },\n        { -0x4aa091f8, 0x0dae8767, 0x5b203a02, 0x4a43b3b3, -0x7f507387, -0x1c8da592, 0x705fa7a3, 0x0f7a7fd1 },\n        { 0x6eb55ce0, -0x7114a2f9, -0x55f26da6, 0x2fc536bf, -0x23493918, -0x417e7cf1, -0x7d8450ae, 0x556c7045 }\n    },\n    {\n        { 0x2bf44406, -0x46b46ffe, -0x006f4acc, -0x542bdc82, -0x050792c6, 0x7600a960, -0x3dcdd11d, 0x2f45abda },\n        { 0x02e9d8b7, -0x71d4ae8d, 0x248714e8, -0x1c1add97, 0x4ca960b5, -0x42b04289, -0x3a135257, 0x6f4b4199 },\n        { -0x37107596, 0x61af4912, 0x43fb6e5e, -0x1a705b02, 0x6fd427cf, -0x4a5033a3, 0x1e1e11eb, 0x6a539328 }\n    },\n    {\n        { 0x149443cf, 0x0fff04fe, -0x79a32229, 0x53cac6d9, 0x531ed1b7, 0x31385b03, -0x532efc63, 0x5846a27c },\n        { -0x5a2e1177, -0x0c25aec7, -0x006c9678, -0x7ebaba84, 0x00e188c4, 0x3f622fed, -0x2474a5c3, 0x0f513815 },\n        { 0x1eb08717, 0x4ff5cdac, -0x6f0d1644, 0x67e8b295, 0x237afa99, 0x44093b5e, -0x78f7474e, 0x0d414bed }\n    },\n    {\n        { 0x294ac9e8, -0x7e77956e, -0x2aaab842, 0x23162b45, 0x03715983, -0x6b3043bc, 0x134bc401, 0x50eb8fdb },\n        { -0x02f18a0a, -0x30497d9b, -0x446f18f9, -0x1ba4c1d8, -0x6006d386, 0x7242a8de, -0x6ccdfd23, 0x685b3201 },\n        { -0x294ccf33, -0x3f48c13a, 0x132faff1, -0x7b1bb7f9, -0x3b5a211f, 0x732b7352, -0x55832d2e, 0x5d7c7cf1 }\n    },\n    {\n        { -0x648c5a9e, 0x33d1013e, 0x48ec26e1, -0x6da310a9, -0x22b97fa8, -0x580319ec, 0x1e9aa438, 0x78b0fad4 },\n        { 0x7a4aafa2, -0x50c4b941, 0x4d40d411, -0x4878fa14, -0x3583ea1d, 0x114f0c6a, -0x56b762b3, 0x3f364faa },\n        { -0x12fa4b78, -0x40a95bcf, -0x63b6a382, -0x5acc1994, -0x780c9ae6, -0x179ad451, 0x59d66c33, 0x02418000 }\n    },\n    {\n        { -0x30c715ff, 0x28350c7d, -0x4d6e854a, 0x7c6cdbc0, -0x7a8f7d09, -0x53183042, -0x5d265e20, 0x4d2845ab },\n        { -0x5c85a41c, -0x314f8802, -0x1a5a1149, -0x249bd0fe, 0x471270b8, -0x3d192f3b, 0x38e4529c, 0x4771b655 },\n        { 0x447070de, -0x44ac8020, 0x6dd557df, -0x3458bbbd, 0x3600dbcb, -0x2c4a5cb9, -0x06002808, 0x4aeabbe6 }\n    },\n    {\n        { -0x3b56370e, 0x6a2134bc, -0x7531d1c9, -0x040702e4, -0x66ee5f46, 0x000ae304, 0x6bc89b9e, 0x046e3a61 },\n        { 0x40d8f78c, 0x4630119e, 0x3c710e11, -0x5fe5643b, -0x76ef2287, 0x486d2b25, -0x24fcdb1b, 0x1e6c47b3 },\n        { -0x0fc6f942, 0x14e65442, -0x1c9d41d6, 0x4a019d54, -0x723dcf39, 0x68ccdfec, -0x509479e4, 0x7cfb7e3f }\n    },\n},\n{\n    {\n        { 0x305b2f51, -0x69114005, -0x776a6948, -0x2c06c753, 0x46d5dd25, -0x0f0ad239, -0x44c5ff6b, 0x57968290 },\n        { -0x73a75124, 0x4637974e, -0x540fbe5c, -0x4610dd05, -0x167f8e76, -0x1e7a26aa, -0x4ebc575a, 0x2f1b78fa },\n        { 0x0a20e101, -0x08e547bd, 0x24f0ec47, -0x0c6c9a73, 0x6ee2eed1, -0x308af658, -0x23d55c1f, 0x7dc43e35 }\n    },\n    {\n        { 0x273e9718, 0x5a782a5c, 0x5e4efd94, 0x3576c699, 0x1f237d3e, 0x0f2ed805, -0x7d2af567, 0x044fb81d },\n        { -0x7782263d, -0x7a69999b, 0x4bb05355, -0x36f064cf, -0x10df864f, -0x391f7208, 0x758cc12f, 0x7ef72016 },\n        { -0x56f81c27, -0x3e20e73b, -0x31b39ca7, 0x57b3371d, -0x4dfe44b7, -0x358fbacc, -0x63cf22d2, 0x7f79823f }\n    },\n    {\n        { 0x68f587ba, 0x6a9c1ff0, 0x0050c8de, 0x0827894e, 0x7ded5be7, 0x3cbf9955, 0x1c06d6f0, 0x64a9b043 },\n        { -0x5c4aec18, -0x7ccb2dc7, -0x46e05728, -0x3ec98f2c, -0x0a6f42cd, 0x12b54136, -0x287b264c, 0x0a4e0373 },\n        { 0x5b7d2919, 0x2eb3d6a1, -0x2ac57dcb, -0x4f4b0960, -0x765ba2b9, 0x7156ce43, -0x31e7cb94, 0x071a7d0a }\n    },\n    {\n        { 0x20e14431, -0x33f3caae, 0x09b15141, 0x0d659507, 0x209d5f36, -0x650a9de5, 0x617755d3, 0x7c69bcf7 },\n        { -0x377845f5, -0x2cf8d256, -0x405a9d12, 0x01262905, -0x3f108975, -0x30abcffe, 0x46ea7e9c, 0x2c3bcc71 },\n        { 0x04e8295f, 0x07f0d7eb, 0x2f50f37d, 0x10db1825, 0x171798d7, -0x16ae565d, 0x22aca51d, 0x6f5a9a73 }\n    },\n    {\n        { -0x5c26bb42, -0x18d62b15, -0x7f875062, -0x7261f6c0, 0x47869c03, 0x4525567a, -0x1172c4dc, 0x02ab9680 },\n        { 0x2f41c6c5, -0x745efff4, 0x0cfefb9b, -0x3b60863f, 0x3cc51c9f, 0x4efa4770, -0x1eb85036, 0x494e21a2 },\n        { -0x221af266, -0x105b757b, 0x0fb9a249, 0x219a224e, -0x26e10927, -0x05f6e0e3, -0x15b944cc, 0x6b5d76cb }\n    },\n    {\n        { 0x1e782522, -0x1f06bee9, 0x036936d3, -0x0e19518c, -0x2f0338ba, 0x408b3ea2, 0x03dd313e, 0x16fb869c },\n        { -0x13f3266c, -0x77a8aa94, 0x5cd01dba, 0x6472dc6f, -0x70bd4b89, -0x50fe96ec, -0x7ad88cac, 0x0ae333f6 },\n        { 0x33b60962, 0x288e1997, -0x27541ecd, 0x24fc72b4, 0x0991d03e, 0x4811f7ed, -0x708f2f8b, 0x3f81e38b }\n    },\n    {\n        { 0x5f17c824, 0x0adb7f35, -0x28bd665c, 0x74b923c3, -0x34071509, -0x2a83c175, 0x4cdedc3d, 0x0ad3e2d3 },\n        { 0x7ed9affe, 0x7f910fcc, 0x2465874b, 0x545cb8a1, 0x4b0c4704, -0x57c6812e, 0x04f50993, 0x50510fc1 },\n        { 0x336e249d, 0x6f0c0fc5, -0x3cce3027, 0x745ede19, 0x09eefe1c, -0x0d290300, -0x0f05e142, 0x127c158b }\n    },\n    {\n        { -0x51ae468c, -0x215d703c, 0x744dfe96, 0x1d9973d3, -0x78c7b758, 0x6240680b, -0x2e98206b, 0x4ed82479 },\n        { 0x2e9879a2, -0x09e683be, 0x52ca3647, -0x5bb5222c, 0x4b4eaccb, -0x64bec03f, 0x07ef4f68, 0x354ef87d },\n        { 0x60c5d975, -0x011c4ade, -0x14be4f48, 0x50352efc, -0x56099ac4, -0x77f753d0, 0x0539236d, 0x302d92d2 }\n    },\n},\n{\n    {\n        { 0x0df53c30, -0x6a847475, -0x719f0f68, 0x2a1c770a, 0x345796de, -0x44385990, -0x6f366437, 0x22a48f9a },\n        { -0x34c10484, 0x4c59023f, -0x39c3d56c, 0x6c2fcb99, -0x3c381f7c, -0x45be6f1e, -0x5ae78b27, 0x0e545dae },\n        { -0x72c053a8, 0x6b7dc0dc, -0x191bd403, 0x5497cd6c, -0x0bff2cfb, 0x542f7d1b, 0x048d9136, 0x4159f47f }\n    },\n    {\n        { -0x442db7c7, 0x748515a8, -0x504fd4ab, 0x77128347, 0x49a2a17f, 0x50ba2ac6, 0x3ad730f1, 0x06052551 },\n        { 0x39e31e32, 0x20ad6608, -0x7bfa41b0, -0x07e1e42b, -0x0b254397, -0x07f9bfaa, -0x318e468b, 0x14d23dd4 },\n        { -0x755d807e, -0x0dc671f7, -0x765e4fdc, 0x6d7982bb, 0x214dd24c, -0x0596bf7c, -0x5cdcfe3d, 0x71ab966f }\n    },\n    {\n        { 0x02809955, -0x4ef775f9, 0x0b43c391, 0x43b273ea, -0x01f97913, -0x35649852, -0x7cca0b13, 0x605eecbf },\n        { 0x4ded02fc, 0x2dcbd8e3, 0x596f22aa, 0x1151f3ec, 0x4e0328da, -0x435daabd, -0x6dbee4de, 0x35768fbe },\n        { 0x6c340431, -0x7cdff59b, -0x711a63d1, -0x60328e99, 0x71300f8a, 0x75d4613f, 0x60f542f9, 0x7a912faf }\n    },\n    {\n        { -0x05d2aa69, 0x253f4f8d, 0x5477130c, 0x25e49c40, -0x6694eefe, 0x00c052e5, 0x33bb6c4a, 0x33cb966e },\n        { 0x5edc1a43, -0x4dfba7a2, 0x5897c73c, -0x60f1e912, 0x4e70483c, 0x5b82c0ae, 0x2bddf9be, 0x624a170e },\n        { 0x7f116909, 0x59702804, 0x1e564467, -0x7d753be4, -0x19de8c79, 0x70417dbd, -0x0453bc7c, 0x721627ae }\n    },\n    {\n        { 0x410b2f22, -0x02cf6844, -0x4a3057bc, -0x0e5fa259, -0x10a8358c, 0x61289a1d, -0x447de6fe, 0x245ea199 },\n        { -0x78c9522b, -0x682fc43d, -0x3acd4ed0, 0x2f1422af, 0x7101bbc4, 0x3aa68a05, -0x18b06059, 0x4c946cf7 },\n        { 0x78d477f8, -0x51235997, 0x29117fe1, 0x1898ba3c, 0x720cbd58, -0x308c067d, -0x474a9caf, 0x67da12e6 }\n    },\n    {\n        { -0x7137cf74, 0x2b7ef3d3, 0x71eb94ab, -0x7d702814, -0x3af9d543, -0x7f83c4ca, 0x31a94141, 0x0cb64cb8 },\n        { -0x4b4291f9, 0x7067e187, -0x382e018c, 0x6e8f0203, 0x38c85a30, -0x6c3955d1, 0x3d75a78a, 0x76297d1f },\n        { 0x534c6378, 0x3030fc33, -0x1abe179f, -0x469ca3a4, -0x264d38d8, 0x15d9a9be, -0x0c88a235, 0x49233ea3 }\n    },\n    {\n        { 0x1c9f249b, 0x7b3985fe, -0x5edccd6d, 0x4fd6b2d5, 0x1adf4d62, -0x314cba6c, 0x542de50c, 0x6987ff6f },\n        { -0x724003c6, 0x629398fa, -0x2ab24bab, -0x1ed01ad3, -0x250dad6b, -0x0c41ee21, -0x31a184af, 0x628b140d },\n        { -0x707c8ac4, 0x47e24142, -0x79950669, 0x6317bebc, 0x3d1a9829, -0x2544a4bd, 0x5287fb2d, 0x074d8d24 }\n    },\n    {\n        { -0x3f1ceb78, 0x481875c6, -0x1ddfcb4c, 0x219429b2, 0x31283b65, 0x7223c98a, 0x342277f9, 0x3420d60b },\n        { 0x440bfc31, -0x7cc82633, -0x50ce7029, 0x729d2ca1, 0x772c2070, -0x5fbf5b5c, 0x3a7349be, 0x46002ef0 },\n        { -0x50019a09, -0x055dc522, 0x5be0764c, 0x78261ed4, 0x2f164403, 0x441c0a1e, 0x7a87d395, 0x5aea8e56 }\n    },\n},\n{\n    {\n        { -0x1b1f0e89, 0x2dbc6fb6, -0x5b42956d, 0x04e1bf29, 0x787af6e8, 0x5e1966d4, -0x4bd92fa0, 0x0edc5f5e },\n        { -0x435bd7c3, 0x7813c1a2, -0x5e79c227, -0x129d0f6f, -0x3d97057a, -0x51384348, 0x6f1cae4c, 0x10e5d3b7 },\n        { 0x53da8e67, 0x5453bfd6, 0x24a9f641, -0x1623e114, 0x03578a23, -0x4078d9c5, 0x361cba72, 0x45b46c51 }\n    },\n    {\n        { -0x75801c1c, -0x3162b223, 0x76620e30, -0x54ec9baa, -0x4cf166a8, 0x4b594f7b, 0x321229df, 0x5c1c0aef },\n        { 0x314f7fa1, -0x56bfd541, -0x71730bb0, -0x1da80e24, 0x23a8be84, 0x1dbbd54b, 0x6dcb713b, 0x2177bfa3 },\n        { -0x05862471, 0x37081bbc, -0x3da0a64d, 0x6048811e, -0x637cdb79, 0x087a7665, 0x7d8ab5bb, 0x4ae61938 }\n    },\n    {\n        { -0x67a4047d, 0x61117e44, 0x71963136, -0x031fb9d6, -0x2bda6fb5, -0x7c53cbb8, 0x5ba43d64, 0x75685abe },\n        { 0x5344a32e, -0x72240956, -0x4be4bf88, 0x7d88eab4, 0x4a130d60, 0x5eb0eb97, 0x17bf3e03, 0x1a00d91b },\n        { -0x149e0d4e, 0x6e960933, -0x3600b6ae, 0x543d0fa8, 0x7af66569, -0x208d8af0, 0x23b0e6aa, 0x135529b6 }\n    },\n    {\n        { -0x1dd17c02, -0x0a38e944, -0x17f67a3f, -0x4bd414e7, 0x14254aae, -0x136259c9, 0x1590a613, 0x5972ea05 },\n        { -0x522e2ae8, 0x18f0dbd7, -0x303ee0ef, -0x68608778, 0x7114759b, -0x78cd1e10, 0x65ca3a01, 0x79b5b81a },\n        { -0x237087ef, 0x0fd4ac20, -0x53b2b058, -0x65652d6c, -0x4cc9fbcc, -0x3fe4d29c, -0x6fa0c425, 0x4f7e9c95 }\n    },\n    {\n        { 0x355299fe, 0x71c8443d, -0x24141529, -0x7432c4e4, -0x0e5b6b9a, -0x7f6db662, -0x5ebb5238, 0x1942eec4 },\n        { 0x5781302e, 0x62674bbc, -0x765223f1, -0x27adf0c7, 0x53fbd9c6, -0x73d66652, 0x2e638e4c, 0x31993ad9 },\n        { -0x51dcb66e, 0x7dac5319, 0x0cea3e92, 0x2c1b3d91, 0x253c1122, 0x553ce494, 0x4ef9ca75, 0x2a0a6531 }\n    },\n    {\n        { 0x3c1c793a, -0x30c9e533, 0x5a35bc3b, 0x2f9ebcac, -0x57325955, 0x60e860e9, 0x6dea1a13, 0x055dc39b },\n        { -0x0806d83e, 0x2db7937f, 0x17d0a635, -0x248be0fa, 0x1155af76, 0x5982f3a2, 0x647c2ded, 0x4cf6e218 },\n        { -0x3d72a44a, -0x4ee6dd84, 0x774dffab, 0x07e24ebc, -0x1b5cd377, -0x57c38732, 0x10aa24b6, 0x121a3077 }\n    },\n    {\n        { -0x388b7c37, -0x29a68ec2, -0x47d46951, -0x77401f89, 0x1097bcd3, 0x289e2823, 0x6ced3a9b, 0x527bb94a },\n        { -0x60fcb569, -0x1b24a2a2, 0x3034bc2d, -0x1eac03f7, -0x6aae2c4f, 0x46054691, 0x7a40e52d, 0x333fc76c },\n        { -0x66a4b7d2, 0x563d992a, 0x6e383801, 0x3405d07c, 0x2f64d8e5, 0x485035de, 0x20a7a9f7, 0x6b89069b }\n    },\n    {\n        { -0x4a382489, 0x4082fa8c, -0x38cb3eab, 0x068686f8, -0x09185a82, 0x29e6c8d9, -0x589c6431, 0x0473d308 },\n        { 0x6270220d, -0x7ed55fbf, -0x06dba4b2, -0x66a57606, 0x5072ef05, -0x00523b32, -0x558c148d, 0x23bc2103 },\n        { 0x03589e05, -0x351186da, 0x46dcc492, 0x2b4b4212, -0x19fe56b1, 0x02a1ef74, -0x21fbcbe6, 0x102f73bf }\n    },\n},\n{\n    {\n        { -0x6c5c9db9, 0x358ecba2, -0x4d97029b, -0x5070679e, 0x68a01c89, 0x412f7e99, -0x328abadc, 0x5786f312 },\n        { 0x7ec20d3e, -0x4a5d2af4, -0x5f368d9d, -0x39b42292, -0x3e008cb3, 0x56e89052, 0x2b2ffaba, 0x4929c6f7 },\n        { -0x35ebfcd4, 0x337788ff, 0x447f1ee3, -0x0c6defd8, 0x231bccad, -0x74ebf8e1, -0x0dcbb87d, 0x4c817b4b }\n    },\n    {\n        { -0x5bf4bb7c, 0x413ba057, 0x4f5f6a43, -0x45b3d1e6, -0x511e29e4, 0x614ba0a5, -0x74fa23ad, 0x78a1531a },\n        { 0x2871b96e, 0x0ff85385, 0x60c3f1bb, -0x1ec16055, 0x25344402, -0x1102a6ad, 0x75b7744b, 0x0a37c370 },\n        { 0x3ad0562b, 0x6cbdf170, -0x36dade5d, -0x7130b7d0, -0x027bdb19, -0x25142cfd, 0x2e5ec56f, 0x72ad82a4 }\n    },\n    {\n        { 0x67024bc3, -0x3c976c6f, 0x49502fda, -0x71962e93, -0x1ba0b4d7, -0x030d13c4, -0x5c4b343c, 0x065f669e },\n        { -0x45049a0a, 0x3f9e8e35, -0x0d8d6c5f, 0x39d69ec8, -0x73095c30, 0x6cb8cd95, 0x73adae6d, 0x17347781 },\n        { 0x5532db4d, -0x75ff5139, 0x43e31bb1, -0x47965b1c, -0x2c580aeb, 0x4a0f8552, 0x303d7c08, 0x19adeb7c }\n    },\n    {\n        { 0x43c31794, -0x62fa4583, -0x6ccddada, 0x2470c8ff, 0x16197438, -0x7cdc2138, -0x7ea964ad, 0x28527098 },\n        { 0x53ead9a3, -0x38df349f, 0x512b636e, 0x55b2c97f, -0x2bfd6f4f, -0x4e1ca4a1, 0x3b530ee2, 0x2fd9ccf1 },\n        { 0x47f796b8, 0x07bd475b, 0x542c8f54, -0x2d384fed, 0x3b24f87e, 0x2dbd23f4, 0x7b0901d6, 0x6551afd7 }\n    },\n    {\n        { -0x5e2a3654, 0x68a24ce3, 0x10ff6461, -0x44885cc3, 0x25d3166e, 0x0f86ce44, 0x50b9623b, 0x56507c09 },\n        { 0x54aac27f, 0x4546baaf, -0x4d5ba5d8, -0x09099014, 0x562bcfe8, 0x582d1b5b, -0x6df087a1, 0x44b123f3 },\n        { -0x2e8ec19d, 0x1206f0b7, 0x15bafc74, 0x353fe3d9, 0x0ad9d94d, 0x194ceb97, -0x062fc52d, 0x62fadd7c }\n    },\n    {\n        { -0x1831ba6c, 0x3cd7bc61, -0x4822d982, -0x3294ca57, 0x4366ef27, -0x5f7f5438, 0x59c79711, 0x6ec7c46f },\n        { 0x5598a074, -0x394a6985, -0x71b6c1db, 0x5efe91ce, 0x49280888, -0x2b48d3bb, -0x5d98bf3e, 0x20ef1149 },\n        { 0x6f09a8a2, 0x2f07ad63, 0x24205e7d, -0x79681932, -0x11ca5ec7, -0x3f5103fb, -0x4a062769, 0x15e80958 }\n    },\n    {\n        { 0x5bb061c4, 0x4dd1ed35, -0x6be3f900, 0x42dc0cef, -0x0279cbf2, 0x61305dc1, 0x0e55a443, 0x56b2cc93 },\n        { 0x0c3e235b, 0x25a5ef7d, -0x41ecb119, 0x6c39c17f, 0x2dc5c327, -0x388b1ecc, -0x6dfde0c7, 0x021354b8 },\n        { -0x59403a5e, 0x1df79da6, -0x6021bc97, 0x02f3a274, -0x325c6f59, -0x4cdc260e, -0x788b2c9d, 0x7be0847b }\n    },\n    {\n        { 0x5307fa11, 0x1466f5af, -0x1293f50e, -0x7e803383, -0x3c5b5c05, 0x0a6de44e, -0x436d82f5, 0x74071475 },\n        { -0x74c0aa3d, -0x736633a6, 0x3fded2a0, 0x0611d725, 0x36b70a36, -0x12d66a01, -0x2875d9e7, 0x1f699a54 },\n        { 0x73e7ea8a, -0x188d6d0d, -0x34fba5cf, 0x296537d2, -0x2cd8b022, 0x1bd0653e, 0x76bd2966, 0x2f9a2c44 }\n    },\n},\n{\n    {\n        { -0x4aaee366, -0x5d4b2520, 0x2bffff06, 0x7ac86029, -0x0aafbdcc, -0x67e0c8a3, -0x25b15ed3, 0x3f6bd725 },\n        { 0x7f5745c6, -0x14e74655, 0x5787c690, 0x023a8aee, 0x2df7afa9, -0x48d8ed26, -0x15a3fec3, 0x36597d25 },\n        { 0x106058ac, 0x734d8d7b, 0x6fc6905f, -0x26bfa862, -0x6dfd6cd3, 0x6466f8f9, -0x259f2930, 0x7b7ecc19 }\n    },\n    {\n        { -0x58830565, 0x6dae4a51, -0x185c79b0, -0x7dd9c9ac, -0x70d27d25, 0x09bbffcd, 0x1bf5caba, 0x03bedc66 },\n        { 0x695c690d, 0x78c2373c, 0x0642906e, -0x22dad19a, 0x4ae12bd2, -0x6ae2bbbc, 0x01743956, 0x4235ad76 },\n        { 0x078975f5, 0x6258cb0d, -0x6e760d68, 0x49294254, -0x1d1c911c, -0x5f354bdd, -0x320f995f, 0x0e7ce2b0 }\n    },\n    {\n        { -0x26b48f07, -0x01590121, -0x3e0345d3, -0x0ecf3faf, 0x7f2fab89, 0x4882d47e, -0x7513114b, 0x61525613 },\n        { -0x3b737a5d, -0x3b6b9bc6, 0x3c6139ad, -0x02c9e20c, 0x3ae94d48, 0x09db17dd, -0x704b98b6, 0x666e0a5d },\n        { 0x4870cb0d, 0x2abbf64e, -0x55ba7495, -0x329a4310, 0x75e8985d, -0x6541b146, -0x2aeb211c, 0x7f0bc810 }\n    },\n    {\n        { 0x737213a0, -0x7c536253, 0x2ef72e98, -0x60090746, 0x43ec6957, 0x311e2edd, -0x213a548b, 0x1d3a907d },\n        { 0x26f4136f, -0x46ff945c, 0x57e03035, -0x7298c962, 0x4f463c28, -0x34372027, -0x0711240b, 0x0d1f8dbc },\n        { 0x3ed081dc, -0x45e96ccf, -0x7ae4cb80, 0x29329fad, 0x030321cb, 0x0128013c, -0x5ce4021d, 0x00011b44 }\n    },\n    {\n        { 0x6a0aa75c, 0x16561f69, 0x5852bd6a, -0x3e408da4, -0x65869953, 0x11a8dd7f, -0x2d7aefda, 0x63d988a2 },\n        { 0x3fc66c0c, 0x3fdfa06c, 0x4dd60dd2, 0x5d40e38e, 0x268e4d71, 0x7ae38b38, 0x6e8357e1, 0x3ac48d91 },\n        { -0x5042dcd2, 0x00120753, -0x0227097d, -0x16d43148, -0x7b18d46f, -0x07e9964d, 0x2368a066, 0x33fad52b }\n    },\n    {\n        { -0x3bdd3018, -0x72d33730, 0x05a13acb, 0x072b4f7b, -0x13095a91, -0x5c01491a, -0x46f58e1e, 0x3cc355cc },\n        { -0x3a1be1ea, 0x540649c6, 0x333f7735, 0x0af86430, -0x0cfa18ba, -0x4d53032e, -0x5da92359, 0x16c0f429 },\n        { -0x6fc16ecf, -0x16496bbd, 0x7a5637ce, -0x475b6b35, -0x45456dbc, -0x37832e5c, 0x6bae7568, 0x631eaf42 }\n    },\n    {\n        { -0x5c8ff218, 0x47d975b9, -0x1d07faae, 0x7280c5fb, 0x32e45de1, 0x53658f27, 0x665f80b5, 0x431f2c7f },\n        { -0x25990161, -0x4c16fbf0, 0x6c16e5a6, -0x7a22b4ae, 0x1ef9bf83, -0x43c2689f, 0x1ea919b5, 0x5599648b },\n        { -0x7a7084e7, -0x29fd9cbc, -0x5e15aeb6, 0x14ab352f, 0x2090a9d7, -0x76ffbbe6, -0x6edac4da, 0x7b04715f }\n    },\n    {\n        { -0x3b19453a, -0x4c893d80, 0x6d1d9b0b, -0x68f12c23, 0x450bf944, -0x4f656aa8, 0x57cde223, 0x48d0acfa },\n        { -0x530951bd, -0x7c1242d8, 0x7d5c7ab4, -0x79ca8375, -0x4814d3bc, -0x3fbfb897, -0x3d09a7c1, 0x59b37bf5 },\n        { 0x7dabe671, -0x49f0d91c, 0x622f3a37, -0x0e2e5e69, -0x1669fc6c, 0x4208ce7e, 0x336d3bdb, 0x16234191 }\n    },\n},\n{\n    {\n        { 0x3d578bbe, -0x7ad22e03, -0x3cd79ef8, 0x2b65ce72, -0x1531dd8d, 0x658c07f4, -0x13c754c0, 0x0933f804 },\n        { 0x33a63aef, -0x0e651539, 0x4442454e, 0x2c7fba5d, 0x4795e441, 0x5da87aa0, -0x5b1f4f0b, 0x413051e1 },\n        { -0x72b69b8a, -0x58549687, -0x034a5438, -0x7ede5522, 0x7b539472, -0x5a23ed11, 0x5e45351a, 0x07fd4706 }\n    },\n    {\n        { -0x6517183d, 0x30421155, -0x6bb77d5b, -0x0d7e4dd7, 0x378250e4, -0x75ec53d2, 0x54ba48f4, 0x014afa09 },\n        { 0x258d2bcd, -0x37a7c3c3, -0x509f48c1, 0x17029a4d, 0x416a3781, -0x05f0362a, 0x38b3fb23, 0x1c1e5fba },\n        { 0x1bb3666c, -0x34ce6900, 0x4bffecb9, 0x33006052, 0x1a88233c, 0x29371199, 0x3d4ed364, 0x29188436 }\n    },\n    {\n        { -0x43e54915, -0x0462c83d, 0x4d57a240, 0x02be1453, -0x075a1e0a, -0x0b28cbeb, 0x0ccc8188, 0x5964f430 },\n        { -0x23b45406, 0x033c6805, 0x5596ecc1, 0x2c15bf5e, -0x4a64e2c5, 0x1bc70624, -0x5e60f13b, 0x3ede9850 },\n        { 0x2d096800, -0x1bb5dceb, 0x70866996, 0x5c08c559, 0x46affb6e, -0x20d249f6, -0x07a90277, 0x579155c1 }\n    },\n    {\n        { 0x0817e7a6, -0x4a0e949d, 0x3c351026, -0x7f7396dd, 0x54cef201, 0x324a983b, 0x4a485345, 0x53c09208 },\n        { 0x12e0c9ef, -0x69cdb123, -0x0dbdfd69, 0x468b878d, -0x5b0a8c42, 0x199a3776, -0x716e16d6, 0x1e7fbcf1 },\n        { -0x0e345041, -0x2d2beb7f, 0x716174e5, 0x231d2db6, -0x1d5aa368, 0x0b7d7656, 0x2aa495f6, 0x3e955cd8 }\n    },\n    {\n        { 0x61bb3a3f, -0x54c60c11, 0x2eb9193e, -0x714bff9b, 0x38c11f74, -0x4a219134, 0x26f3c49f, 0x654d7e96 },\n        { 0x3ed15433, -0x1b70aca2, 0x0d7270a3, -0x2f8a96d6, -0x55219c79, 0x40fbd21d, -0x30bb6a0b, 0x14264887 },\n        { 0x5c7d2ceb, -0x1a9b3023, -0x28c83347, -0x7d115022, -0x2e064f55, 0x6107db62, -0x4bca7245, 0x0b6baac3 }\n    },\n    {\n        { 0x3700a93b, 0x204abad6, -0x25886c8d, -0x41ffdc2d, 0x633ab709, -0x27a0fcba, -0x6f7dfbee, 0x00496dc4 },\n        { -0x79dd0168, 0x7ae62bcb, -0x31476e51, 0x47762256, -0x0d1bf94c, 0x1a5a92bc, -0x7b1beaff, 0x7d294017 },\n        { -0x3d819ca0, 0x1c74b88d, -0x72eb7af4, 0x07485426, 0x3e0dcb30, -0x5eba0485, 0x43803b23, 0x10843f1b }\n    },\n    {\n        { -0x1cdb9765, -0x2a9098d3, -0x4c6b567f, -0x2e257513, -0x6e973013, -0x2284a702, 0x4d56c1e8, 0x7ce246cd },\n        { 0x376276dd, -0x3a06fbab, -0x289ba327, -0x31a6ea73, 0x1d366b39, -0x6d09a2af, 0x526996c4, 0x11574b6e },\n        { 0x7f80be53, -0x470bcf72, 0x34a9d397, 0x5f3cb8cb, 0x33cc2b2c, 0x18a961bd, 0x3a9af671, 0x710045fb }\n    },\n    {\n        { 0x059d699e, -0x5fc0379e, -0x659e6197, 0x2370cfa1, 0x2f823deb, -0x3b01c4ee, -0x580f7bb2, 0x1d1b056f },\n        { 0x101b95eb, 0x73f93d36, 0x4f6f4486, -0x0510cc87, -0x70ea1a9e, 0x5651735f, 0x58b40da1, 0x7fa3f190 },\n        { -0x1a9409e1, 0x1bc64631, 0x6e5382a3, -0x2c8654f0, 0x0540168d, 0x4d58c57e, -0x7bbd271c, 0x56625662 }\n    },\n},\n{\n    {\n        { 0x1ff38640, -0x22b6632a, 0x063625a0, 0x29cd9bc3, 0x3dd73dc3, 0x51e2d802, 0x203b9231, 0x4a25707a },\n        { -0x09d9800a, -0x461b6622, 0x742c0843, 0x7772ca7b, -0x165b0d4f, 0x23a0153f, -0x2a2faffa, 0x2cdfdfec },\n        { 0x53f6ed6a, 0x2ab7668a, 0x1dd170a1, 0x30424258, 0x3ae20161, 0x4000144c, 0x248e49fc, 0x5721896d }\n    },\n    {\n        { -0x5e2f25b2, 0x285d5091, -0x4a01c1f8, 0x4baa6fa7, -0x1e6c6c4d, 0x63e5177c, -0x3b4fcf03, 0x03c935af },\n        { -0x02e7e452, 0x0b6e5517, 0x2bb963b4, -0x6fdd9d61, 0x32064625, 0x5509bce9, -0x09c3ec26, 0x578edd74 },\n        { 0x492b0c3d, -0x668d893a, -0x201dfa04, 0x47ccc2c4, -0x229dc5c4, -0x232d647c, 0x0288c7a2, 0x3ec2ab59 }\n    },\n    {\n        { -0x51cd2e35, -0x58dec5f7, 0x40f5c2d5, 0x0f2b87df, -0x17e154d7, 0x0baea4c6, 0x6adbac5e, 0x0e1bf66c },\n        { -0x1b278447, -0x5e5f2d85, 0x61391aed, -0x5674b215, 0x73cb9b83, -0x665f2230, 0x200fcace, 0x2dd5c25a },\n        { 0x792c887e, -0x1d542a17, -0x346d92a3, 0x1a020018, -0x4551a0e2, -0x40459633, 0x5ae88f5f, 0x730548b3 }\n    },\n    {\n        { -0x5e291ccc, -0x7fa4f6b5, 0x09353f19, -0x40c10e89, 0x0622702b, 0x423f06cb, -0x2787ba23, 0x585a2277 },\n        { -0x34574712, -0x3bcaae5d, -0x4deea0ea, 0x65a26f1d, -0x5473c7b0, 0x760f4f52, 0x411db8ca, 0x3043443b },\n        { 0x33d48962, -0x5e75a07e, -0x1387da81, 0x6698c4b5, 0x373e41ff, -0x5871905b, 0x50ef981f, 0x76562789 }\n    },\n    {\n        { -0x15793063, -0x1e8f8c5d, 0x07155fdc, 0x3a8cfbb7, 0x31838a8e, 0x4853e7fc, -0x49ec09ea, 0x28bbf484 },\n        { -0x2ae03740, 0x38c3cf59, 0x0506b6f2, -0x64122d03, -0x54a8f171, 0x26bf109f, -0x3e47b95a, 0x3f4160a8 },\n        { 0x6f136c7c, -0x0d9ed0a4, -0x0922ee42, -0x50152ef9, 0x13de6f33, 0x527e9ad2, -0x7e7708a3, 0x1e79cb35 }\n    },\n    {\n        { -0x0a1f7e7f, 0x77e953d8, 0x299dded9, -0x7b5af3bc, -0x79bada1b, -0x2393d2f4, 0x39d1f2f4, 0x478ab52d },\n        { -0x11081c0f, 0x013436c3, -0x0161ef08, -0x7d749581, -0x43062104, 0x7ff908e5, 0x3a3b3831, 0x65d7951b },\n        { -0x6dad2ea7, 0x66a6a4d3, -0x78e537f9, -0x1a221e44, -0x593e3691, -0x47d394c0, 0x1a212214, 0x16d87a41 }\n    },\n    {\n        { -0x2ab1fa7d, -0x045b2a1e, 0x2ebd99fa, -0x1de05029, 0x6ee9778f, 0x497ac273, 0x7a5a6dde, 0x1f990b57 },\n        { 0x42066215, -0x4c4281a6, 0x0c5a24c1, -0x78641c33, -0x29066b49, 0x57c05db1, 0x65f38ca6, 0x28f87c81 },\n        { 0x1be8f7d6, -0x5ccbb153, -0x53158671, 0x7d1e50eb, 0x520de052, 0x77c6569e, 0x534d6d3e, 0x45882fe1 }\n    },\n    {\n        { -0x6bc3901c, -0x275366d7, -0x5c7c6d5e, -0x4a060e9f, -0x4137650d, 0x2699db13, -0x1bfa0f8c, 0x7dcf843c },\n        { 0x757983d6, 0x6669345d, 0x17aa11a6, 0x62b6ed11, -0x67a1ed71, 0x7ddd1857, -0x09d90923, 0x688fe5b8 },\n        { 0x4a4732c0, 0x6c90d648, -0x35a9cd67, -0x2adebc03, -0x6ea2391f, -0x4c41d73d, 0x7327191b, 0x6739687e }\n    },\n},\n{\n    {\n        { -0x363468e1, -0x731a5530, -0x602ab5d7, 0x1156aaa9, 0x15af9b78, 0x41f72470, 0x420f49aa, 0x1fe8cca8 },\n        { 0x200814cf, -0x609a3a16, 0x69a31740, -0x7bfac91f, 0x25c8b4ad, -0x74f12ec7, -0x16c9c9e3, 0x0080dbaf },\n        { 0x3c0cc82a, 0x72a1848f, -0x788361ac, 0x38c560c2, -0x31aabec0, 0x5004e228, 0x03429d71, 0x042418a1 }\n    },\n    {\n        { 0x20816247, 0x58e84c6f, -0x1c90286d, -0x724d4d4a, 0x1d484d85, -0x688e7daa, -0x79cd5429, 0x0822024f },\n        { -0x540c00a1, -0x766215af, 0x2fc2d8ba, -0x646c5799, -0x419142a4, 0x2c38cb97, -0x68d9c4a3, 0x114d5784 },\n        { 0x6b1beca3, -0x4cfe4484, -0x3914ec8b, 0x55393f6d, -0x68491b15, -0x6ef2d7f0, -0x62b8615d, 0x1ad4548d }\n    },\n    {\n        { 0x0fe9fed3, -0x5f901993, 0x1c587909, -0x578cc5c0, 0x0df98953, 0x30d14d80, -0x384cfda8, 0x41ce5876 },\n        { 0x389a48fd, -0x32a58260, -0x6587c8e2, -0x4c705b56, 0x2cdb8e6c, -0x392689e5, -0x3681ebbd, 0x35cf51db },\n        { -0x298f3fde, 0x59ac3bc5, -0x64ee6bfa, -0x151983f0, -0x4c87d026, -0x68674210, -0x02f8bf6e, 0x651e3201 }\n    },\n    {\n        { 0x1efcae9e, -0x5a845b60, -0x23cf756c, 0x769f4bee, 0x3603cb2e, -0x2e0ef115, 0x7e441278, 0x4099ce5e },\n        { -0x10cf3a31, -0x29c27b7d, 0x2361cc0c, 0x4cd4b496, -0x5b7bd954, -0x116f1b00, 0x18c14eeb, 0x0af51d7d },\n        { -0x75aede17, 0x1ac98e4f, -0x2405d020, 0x7dae9544, -0x29bcf207, -0x7cdf55f3, 0x2c4a2fb5, 0x66728265 }\n    },\n    {\n        { 0x2946db23, -0x52574920, 0x7b253ab7, 0x1c0ce51a, 0x66dd485b, -0x7bb737a6, -0x2f98a521, 0x7f1fc025 },\n        { -0x27943655, -0x78b9de0c, 0x56fe6fea, -0x4ab38442, 0x7fadc22c, 0x077a2425, 0x19b90d39, 0x1ab53be4 },\n        { 0x319ea6aa, -0x2711e4e8, 0x3a21f0da, 0x004d8808, -0x77c5b0b5, 0x3bd6aa1d, -0x202602ec, 0x4db9a3a6 }\n    },\n    {\n        { -0x34488398, -0x26a4ff45, -0x6e0e87b7, -0x22437b96, -0x41d7264d, 0x7cf700ae, -0x7a2ce0c2, 0x5ce1285c },\n        { -0x4663f8ab, -0x73184dc5, -0x3b0af086, 0x35c5d6ed, -0x1264af3d, 0x7e1e2ed2, -0x176cb25f, 0x36305f16 },\n        { -0x674f4218, 0x31b6972d, -0x535921a5, 0x7d920706, -0x6f759a61, -0x198cef08, -0x1020fdcb, 0x50fac2a6 }\n    },\n    {\n        { -0x090bb644, 0x295b1c86, 0x1f0ab4dd, 0x51b2e84a, -0x5571aae3, -0x3ffe34d0, 0x44f43662, 0x6a28d359 },\n        { 0x5b880f5a, -0x0c2c560d, -0x24fc183e, -0x1213faf4, -0x060f4e5e, -0x576967e1, -0x53a1cb5c, 0x49a4ae2b },\n        { 0x04a740e0, 0x28bb12ee, -0x64317e8c, 0x14313bbd, -0x173ef3c0, 0x72f5b5e4, 0x36adcd5b, 0x7cbfb199 }\n    },\n    {\n        { -0x33c91920, -0x7186c586, 0x7d586eed, -0x0605485d, -0x451e0b1c, 0x3a4f9692, -0x00a0bb82, 0x1c14b03e },\n        { 0x6b89792d, -0x5cee223e, -0x25aed99c, 0x1b30b4c6, -0x30eaf7a7, 0x0ca77b4c, 0x1b009408, 0x1de443df },\n        { 0x14a85291, 0x19647bd1, 0x1034d3af, 0x57b76cb2, 0x0f9d6dfa, 0x6329db44, 0x6a571493, 0x5ef43e58 }\n    },\n},\n{\n    {\n        { -0x37f3e540, -0x59923363, 0x1b38a436, -0x685fa30c, -0x6a24283a, -0x58140c42, -0x72818255, 0x7da0b8f6 },\n        { 0x385675a6, -0x1087dfec, -0x55025618, -0x5d9b60d0, 0x5cdfa8cb, 0x4cd1eb50, 0x1d4dc0b3, 0x46115aba },\n        { -0x3c4a258a, -0x2bf0e6ad, 0x21119e9b, 0x1dac6f73, -0x014da6a0, 0x03cc6021, -0x7c98b4b5, 0x5a5f887e }\n    },\n    {\n        { -0x5f59bc47, -0x6169d72d, -0x193cdf9c, -0x4a3c3500, 0x7c2dec32, -0x64acfd77, -0x2a2e38f4, 0x43e37ae2 },\n        { 0x70a13d11, -0x709cfe31, 0x350dd0c4, -0x303147eb, -0x5b435b82, -0x08fd682c, -0x1bb2ebcc, 0x3669b656 },\n        { -0x12591ecd, 0x387e3f06, -0x665ec540, 0x67301d51, 0x36263811, -0x42a52708, 0x4fd5e9be, 0x6a21e6cd }\n    },\n    {\n        { 0x6699b2e3, -0x10bed6ee, 0x708d1301, 0x71d30847, 0x1182b0bd, 0x325432d0, 0x001e8b36, 0x45371b07 },\n        { 0x3046e65f, -0x0e39e8f6, 0x00d23524, 0x58712a2a, -0x737d48ab, 0x69dbbd3c, -0x5e6a00a9, 0x586bf9f1 },\n        { 0x5ef8790b, -0x5924f773, 0x610937e5, 0x5278f0dc, 0x61a16eb8, -0x53fcb62e, -0x6f1ade87, 0x0eafb037 }\n    },\n    {\n        { 0x0f75ae1d, 0x5140805e, 0x2662cc30, -0x13fd041d, -0x156dc693, 0x2cebdf1e, -0x3abca44d, 0x44ae3344 },\n        { 0x3748042f, -0x69faaa3f, -0x7df455ef, 0x219a41e6, 0x73486d0c, 0x1c81f738, 0x5a02c661, 0x309acc67 },\n        { -0x445abc12, -0x630d7647, 0x5ac97142, -0x0c89f163, 0x4f9360aa, 0x1d82e5c6, 0x7f94678f, 0x62d5221b }\n    },\n    {\n        { 0x3af77a3c, 0x7585d426, -0x0116ebb3, -0x205184ef, 0x59f7193d, -0x5af98f80, -0x7c6ddfc9, 0x14f29a53 },\n        { 0x18d0936d, 0x524c299c, -0x75f3e5f4, -0x37944a94, -0x24b579cf, -0x5c8afad2, -0x438aba9e, 0x5c0efde4 },\n        { 0x25b2d7f5, -0x208e8124, -0x664acfc0, 0x21f970db, -0x3c12b39e, -0x256dcb49, 0x7bee093e, 0x5e72365c }\n    },\n    {\n        { 0x2f08b33e, 0x7d933906, -0x2060cd42, 0x5b9659e5, 0x1f9ebdfd, -0x5300c253, -0x348cb649, 0x70b20555 },\n        { 0x4571217f, 0x575bfc07, 0x0694d95b, 0x3779675d, -0x0be6e1cd, -0x65f5c845, 0x47b4eabc, 0x77f1104c },\n        { 0x55112c4c, -0x41aeec3b, -0x6577e033, 0x6688423a, 0x5e503b47, 0x44667785, 0x4a06404a, 0x0e34398f }\n    },\n    {\n        { 0x3e4b1928, 0x18930b09, 0x73f3f640, 0x7de3e10e, 0x73395d6f, -0x0bcde826, -0x35c863c2, 0x6f8aded6 },\n        { 0x3ecebde8, -0x4982dd27, 0x27822f07, 0x09b3e841, -0x4fa49273, 0x743fa61f, -0x75c9dc8e, 0x5e540536 },\n        { -0x02484d66, -0x1cbfedc3, -0x5de54d6f, 0x487b97e1, -0x02196b62, -0x066982fe, -0x372c2169, 0x780de72e }\n    },\n    {\n        { 0x00f42772, 0x671feaf3, 0x2a8c41aa, -0x708d14d6, -0x68c8cd6e, 0x29a17fd7, 0x32b587a6, 0x1defc6ad },\n        { 0x089ae7bc, 0x0ae28545, 0x1c7f4d06, 0x388ddecf, 0x0a4811b8, 0x38ac1551, 0x71928ce4, 0x0eb28bf6 },\n        { -0x10ae6a59, -0x50a441e6, -0x6e84ea13, 0x148c1277, 0x7ae5da2e, 0x2991f7fb, -0x0722d799, 0x467d201b }\n    },\n},\n{\n    {\n        { 0x296bc318, 0x745f9d56, -0x27ead19b, -0x66ca7f2c, 0x5839e9ce, -0x4f1a4ec1, -0x2bc6de40, 0x51fc2b28 },\n        { -0x0842d195, 0x7906ee72, 0x109abf4e, 0x05d270d6, -0x46be575c, -0x72a301bb, 0x1c974287, 0x44c21867 },\n        { -0x6a1d5674, 0x1b8fd117, 0x2b6b6291, 0x1c4e5ee1, 0x7424b572, 0x5b30e710, 0x4c4f4ac6, 0x6e6b9de8 }\n    },\n    {\n        { -0x07f34f78, 0x6b7c5f10, 0x56e42151, 0x736b54dc, -0x3910663c, -0x3d49df5b, -0x3c5f90be, 0x5f4c802c },\n        { 0x4b1de151, -0x200da032, -0x1ee3bfdb, -0x27be3f39, 0x54749c87, 0x2554b3c8, -0x6f71f207, 0x2d292459 },\n        { 0x7d0752da, -0x649a370f, -0x38811800, -0x77e31cc8, 0x5b62f9e3, -0x3c4aeb10, -0x413ef2b8, 0x66ed5dd5 }\n    },\n    {\n        { -0x3435fb83, -0x0f520c37, -0x0baad095, -0x7e3c4d35, 0x44735f93, -0x3025eed3, 0x7e20048c, 0x1f23a0c7 },\n        { 0x0bb2089d, 0x7d38a1c2, -0x69332bee, -0x7f7ccb1f, 0x6c97d313, -0x3b58f474, 0x03007f20, 0x2eacf8bc },\n        { -0x1a43ea90, -0x0dcab985, 0x0dbab38c, 0x03d2d902, -0x03061f62, 0x27529aa2, -0x62cb43b0, 0x0840bef2 }\n    },\n    {\n        { 0x7f37e4eb, -0x32ab1f95, -0x0a169336, -0x733ea079, -0x2ca68232, -0x47db7450, 0x6074400c, 0x246affa0 },\n        { -0x23ef4d79, 0x796dfb35, 0x5c7ff29d, 0x27176bcd, -0x384db6fb, 0x7f3d43e8, -0x6e3abd8a, 0x0304f5a1 },\n        { -0x041bacdf, 0x37d88e68, -0x3f28afce, -0x79f68ab8, -0x76b5f2cb, 0x4e9b13ef, 0x5753d325, 0x25a83cac }\n    },\n    {\n        { 0x3952b6e2, -0x60f099d7, 0x0934267b, 0x33db5e0e, -0x29f60124, -0x00badad5, -0x3af91f37, 0x06be10f5 },\n        { -0x1127e9a2, 0x10222f48, 0x4b8bcf3a, 0x623fc123, -0x3dde1710, 0x1e145c09, -0x3587d9d0, 0x7ccfa59f },\n        { -0x49d5cba1, 0x1a9615a9, 0x4a52fecc, 0x22050c56, 0x28bc0dfe, -0x585d877b, 0x1a1ee71d, 0x5e82770a }\n    },\n    {\n        { 0x42339c74, -0x17fd17f6, -0x5800051b, 0x34175166, 0x1c408cae, 0x34865d1f, 0x605bc5ee, 0x2cca982c },\n        { -0x527695a4, 0x35425183, -0x1872ad0a, -0x1798c505, -0x6d5ca09c, 0x2c66f25f, 0x3b86b102, 0x09d04f3b },\n        { 0x197dbe6e, -0x02d2a2cb, -0x741b005d, 0x207c2eea, 0x325ae918, 0x2613d8db, 0x27741d3e, 0x7a325d17 }\n    },\n    {\n        { 0x7e2a076a, -0x132d82ff, 0x1636495e, -0x28779761, -0x6e6dcc1b, 0x52a61af0, 0x7bb1ae64, 0x2a479df1 },\n        { -0x2e92021e, -0x2fc94645, -0x3b6857d7, -0x5dfaa8a9, -0x580ed999, -0x7193369a, 0x1239c180, 0x4d3b1a79 },\n        { 0x33db2710, -0x61a11172, -0x293bc35b, 0x189854de, -0x6d8e7ec8, -0x5be3dd3b, -0x5bc5a165, 0x27ad5538 }\n    },\n    {\n        { -0x71b8f884, -0x34a5829d, 0x20a1c059, -0x7248ac9f, -0x74120234, 0x549e1e4d, 0x503b179d, 0x080153b7 },\n        { 0x15350d61, 0x2746dd4b, -0x116ade49, -0x2fc03438, 0x138672ca, -0x1791c9a6, 0x7e7d89e2, 0x510e987f },\n        { 0x0a3ed3e3, -0x2259626d, -0x329f58de, 0x3d386ef1, -0x4255b11a, -0x37e852a8, 0x4fe7372a, 0x23be8d55 }\n    },\n},\n{\n    {\n        { 0x567ae7a9, -0x43e10b43, -0x29bb6743, 0x3f624cb2, 0x2c1f4ec8, -0x1bef9b2e, -0x45c7bfff, 0x2ef9c5a5 },\n        { 0x74ef4fad, -0x6a016e66, -0x095cf75e, 0x3a827bec, 0x09a47b01, -0x69b1fe2d, 0x5ba3c797, 0x71c43c4f },\n        { -0x05618b33, -0x4902920a, -0x1b50d986, -0x0e7d8744, -0x0e1066f2, -0x7daa4c30, -0x6f3a0d6d, 0x5a758ca3 }\n    },\n    {\n        { 0x1d61dc94, -0x731f6e75, -0x657ecf9a, -0x7212c9ba, -0x5017552d, -0x2b1957d7, -0x09c62bc1, 0x0a738027 },\n        { -0x26b9db6b, -0x5d48d8f0, -0x2a82affd, 0x3aa8c6d2, -0x5f4b7836, -0x1c2bff41, -0x4c148d14, 0x2dbae244 },\n        { 0x57ffe1cc, -0x67f0b5d1, -0x1e7c67bd, 0x00670d0d, 0x49fb15fd, 0x105c3f4a, 0x5126a69c, 0x2698ca63 }\n    },\n    {\n        { 0x5e3dd90e, 0x2e3d702f, -0x1b2dac7a, -0x61c0f6e8, 0x024da96a, 0x5e773ef6, 0x4afa3332, 0x3c004b0c },\n        { 0x32b0ba78, -0x189ace78, -0x6da30075, 0x381831f7, -0x5fd6e034, 0x08a81b91, 0x49caeb07, 0x1fb43dcc },\n        { 0x06f4b82b, -0x6556b954, -0x57f93b0d, 0x1ca284a5, -0x3932b879, 0x3ed3265f, -0x32e02de9, 0x6b43fd01 }\n    },\n    {\n        { 0x3e760ef3, -0x4a38bda8, -0x11f54670, 0x75dc52b9, 0x072b923f, -0x40ebd83e, 0x6ff0d9f0, 0x73420b2d },\n        { 0x4697c544, -0x3858a2b5, -0x20f00041, 0x15fdf848, -0x55b987a6, 0x2868b9eb, 0x5b52f714, 0x5a68d710 },\n        { -0x617ae1fa, -0x50d30935, -0x39ddc73c, -0x70a6c6ed, -0x66040c8d, -0x2575476a, -0x15cb4362, 0x3db5632f }\n    },\n    {\n        { -0x7d67da2b, 0x2e4990b1, 0x3e9a8991, -0x12151479, 0x4c704af8, -0x110fc2c7, -0x6a20d4f2, 0x59197ea4 },\n        { -0x08a22628, -0x0b9111d5, 0x396759a5, 0x0d17b1f6, 0x499e7273, 0x1bf2d131, 0x49d75f13, 0x04321adf },\n        { -0x1b1aa552, 0x04e16019, 0x7e2f92e9, -0x1884bc86, 0x6f159aa4, -0x3831d23f, -0x0b28f340, 0x45eafdc1 }\n    },\n    {\n        { -0x30334e13, -0x49f1b9dc, -0x42a3fc6b, 0x59dbc292, -0x23fb7e37, 0x31a09d1d, 0x5d56d940, 0x3f73ceea },\n        { -0x7fba28d5, 0x69840185, -0x30d0f9af, 0x4c22faa2, 0x6b222dc6, -0x6be5c99b, 0x0362dade, 0x5a5eebc8 },\n        { 0x0a4e8dc6, -0x4858402f, 0x44c9b339, -0x41a8ff82, 0x1557aefa, 0x60c1207f, 0x266218db, 0x26058891 }\n    },\n    {\n        { -0x39891abe, 0x4c818e3c, 0x03ceccad, 0x5e422c93, -0x4bed60f8, -0x13f83336, -0x4dbbbc48, 0x0dedfa10 },\n        { -0x7c9f00fc, 0x59f704a6, 0x7661e6f4, -0x3c26c022, 0x12873551, -0x7ce4d58d, 0x4e615d57, 0x54ad0c2e },\n        { -0x47d4add6, -0x11c4982b, -0x605a3e15, 0x36f16346, 0x6ec19fd3, -0x5a4b2d0e, -0x58856bf8, 0x62ecb2ba }\n    },\n    {\n        { -0x5049d78c, -0x6df8d7ca, 0x79e104a5, 0x5fcd5e85, -0x39cf5eb6, 0x5aad01ad, 0x75663f98, 0x61913d50 },\n        { 0x61152b3d, -0x1a1286ae, 0x0eddd7d1, 0x4962357d, -0x4694b38f, 0x7482c8d0, -0x56992742, 0x2e59f919 },\n        { 0x1a3231da, 0x0dc62d36, -0x6bdffd90, -0x05b8a7ce, 0x3f9594ce, 0x02d80151, 0x31c05d5c, 0x3ddbc2a1 }\n    },\n},\n{\n    {\n        { 0x004a35d1, -0x048ca53e, 0x3a6607c3, 0x31de0f43, -0x3ad72a67, 0x7b8591bf, -0x0a44faf4, 0x55be9a25 },\n        { 0x4ffb81ef, 0x3f50a50a, 0x3bf420bf, -0x4e1fcaf7, -0x3955d330, -0x645571e4, -0x05dc85c0, 0x32239861 },\n        { 0x33db3dbf, 0x0d005acd, -0x7f53ca1e, 0x0111b37c, 0x6f88ebeb, 0x4892d66c, 0x6508fbcd, 0x770eadb1 }\n    },\n    {\n        { -0x5faf8e47, -0x0e2c497f, 0x3592ff3a, 0x2207659a, 0x7881e40e, 0x5f016929, -0x7945c8b2, 0x16bedd0e },\n        { 0x5e4e89dd, -0x7bae0620, -0x4386c6c9, -0x3f9cfd01, 0x56a6495c, 0x5d227495, -0x5fa9fc05, 0x09a6755c },\n        { 0x2c2737b5, 0x5ecccc4f, 0x2dccb703, 0x43b79e0c, 0x4ec43df3, 0x33e008bc, -0x0f8a9940, 0x06c1b840 }\n    },\n    {\n        { -0x64fd7fa4, 0x69ee9e7f, 0x547d1640, -0x34007d76, -0x4dbcf698, 0x3d93a869, 0x3fe26972, 0x46b7b8cd },\n        { -0x5c770789, 0x7688a5c6, -0x214d4954, 0x02a96c14, 0x1b8c2af8, 0x64c9f343, 0x54a1eed6, 0x36284355 },\n        { -0x01811420, -0x167edf7a, 0x2f515437, 0x4cba6be7, 0x516efae9, 0x1d04168b, 0x43982cb9, 0x5ea13910 }\n    },\n    {\n        { -0x2a2c4ffe, 0x6f2b3be4, 0x6a09c880, -0x5013cc27, -0x57433b34, 0x035f73a4, 0x4662198b, 0x22c5b928 },\n        { -0x0b8fd11f, 0x49125c9c, -0x74da4cd3, 0x4520b71f, 0x501fef7e, 0x33193026, -0x372d14d5, 0x656d8997 },\n        { 0x433d8939, -0x34a73702, 0x6a8d7e50, -0x765f34d2, 0x09fbbe5a, 0x79ca9553, -0x32803efa, 0x0c626616 }\n    },\n    {\n        { -0x040bab4f, -0x70203c87, -0x0e5b488f, 0x45a5a970, -0x452ca6eb, -0x536de109, -0x57e3de6e, 0x42d088dc },\n        { 0x4879b61f, 0x1ffeb80a, 0x4ada21ed, 0x6396726e, 0x368025ba, 0x33c7b093, -0x0c3ce878, 0x471aa0c6 },\n        { -0x5fe9ae67, -0x7025f0c9, -0x375f1cbd, 0x0adadb77, -0x378a17e0, 0x20fbfdfc, 0x0c2206e7, 0x1cf2bea8 }\n    },\n    {\n        { 0x02c0412f, -0x67d291e6, -0x24a71702, -0x6f05b37d, -0x234e7440, 0x01c2f5bc, 0x216abc66, 0x686e0c90 },\n        { -0x4c9dfd54, -0x3d220e22, -0x2d1d855b, -0x6d5a01f7, -0x03f60e2d, 0x7d1648f6, 0x13bc4959, 0x74c2cc05 },\n        { -0x5abc6a59, 0x1fadbadb, -0x51f25996, -0x4be5fd60, -0x445c83f9, -0x40e60a68, -0x21b7bcf3, 0x6a12b8ac }\n    },\n    {\n        { 0x1aaeeb5f, 0x793bdd80, -0x3eae778f, 0x00a2a0aa, 0x1f2136b4, -0x175c8c5d, -0x036e10e7, 0x48aab888 },\n        { 0x39d495d9, -0x072515e1, 0x525f1dfc, 0x592c190e, -0x3666e2e5, -0x247342fc, -0x2770f349, 0x11f7fda3 },\n        { 0x5830f40e, 0x041f7e92, 0x79661c06, 0x002d6ca9, 0x2b046a2e, -0x79236007, -0x74fb6c2f, 0x76036092 }\n    },\n    {\n        { 0x695a0b05, -0x4bcef71b, -0x52c85c75, 0x6cb00ee8, -0x5cac8c7f, 0x5edad6ee, -0x4923cddc, 0x3f2602d4 },\n        { 0x120cf9c6, 0x21bb41c6, -0x21325a65, -0x154d55ee, 0x0aa48b34, -0x3e58d2fe, -0x1782c498, 0x215d4d27 },\n        { 0x5bcaf19c, -0x374db84a, -0x4e4d39ae, 0x49779dc3, -0x2a131d1e, -0x765e7f45, -0x31371fc7, 0x13f098a3 }\n    },\n},\n{\n    {\n        { 0x2796bb14, -0x0c55a85e, -0x64f825df, -0x77c54549, 0x31a0391c, -0x1ab41de8, -0x27cdfa07, 0x5ee7fb38 },\n        { -0x31a13ab5, -0x6523f007, -0x73d0ecf3, 0x039c2a6b, -0x0f076aeb, 0x028007c7, -0x53fb4c95, 0x78968314 },\n        { 0x41446a8e, 0x538dfdcb, 0x434937f9, -0x5a530257, 0x263c8c78, 0x46af908d, -0x6435f2f7, 0x61d0633c }\n    },\n    {\n        { -0x07038c21, -0x525cd744, -0x590fc804, -0x117b96a3, 0x38c2a909, 0x637fb4db, -0x07f98424, 0x5b23ac2d },\n        { -0x0024da9a, 0x63744935, 0x780b68bb, -0x3a429477, 0x553eec03, 0x6f1b3280, 0x47aed7f5, 0x6e965fd8 },\n        { -0x117fad85, -0x652d46ad, -0x05219273, -0x1770e656, 0x150e82cf, 0x0e711704, -0x226a2124, 0x79b9bbb9 }\n    },\n    {\n        { -0x71608c8c, -0x2e668252, -0x3044f7ea, -0x5fcd5d08, 0x6d445f0a, -0x329345ee, 0x0accb834, 0x1ba81146 },\n        { 0x6a3126c2, -0x144caac0, 0x68c8c393, -0x2d9c7c58, -0x1a46857e, 0x6c0c6429, -0x3602deb9, 0x5065f158 },\n        { 0x0c429954, 0x708169fb, -0x28913099, -0x1eb9ff54, 0x70e645ba, 0x2eaab98a, 0x58a4faf2, 0x3981f39e }\n    },\n    {\n        { 0x6de66fde, -0x37ba205b, 0x2c40483a, -0x1ead5b00, -0x384b09ce, -0x162d1e9d, -0x2343e49b, 0x30f4452e },\n        { 0x59230a93, 0x18fb8a75, 0x60e6f45d, 0x1d168f69, 0x14a93cb5, 0x3a85a945, 0x05acd0fd, 0x38dc0837 },\n        { -0x3a8a68c0, -0x7a92d87e, -0x06634134, -0x05ecba97, -0x3f15b18f, -0x77bb038d, 0x593f2469, 0x632d9a1a }\n    },\n    {\n        { -0x12f37b59, -0x40f602ef, 0x0d9f693a, 0x63f07181, 0x57cf8779, 0x21908c2d, -0x7509b45e, 0x3a5a7df2 },\n        { -0x47f8345a, -0x094494eb, -0x43ab0f29, 0x1823c7df, 0x6e29670b, -0x44e268fd, 0x47ed4a57, 0x0b24f488 },\n        { 0x511beac7, -0x23252b42, -0x12d9330e, -0x5bac7f8b, 0x005f9a65, -0x1e630061, 0x75481f63, 0x34fcf744 }\n    },\n    {\n        { 0x78cfaa98, -0x5a44e255, 0x190b72f2, 0x5ceda267, 0x0a92608e, -0x6cf636ef, 0x2fb374b0, 0x0119a304 },\n        { 0x789767ca, -0x3e681fb4, 0x38d9467d, -0x478eb235, -0x7c06a058, 0x55de8882, 0x4dfa63f7, 0x3d3bdc16 },\n        { -0x173de883, 0x67a2d89c, 0x6895d0c1, 0x669da5f6, -0x4d7d5d50, -0x0a9a671b, -0x121df58d, 0x56c088f1 }\n    },\n    {\n        { 0x24f38f02, 0x581b5fac, -0x451cf343, -0x56f41602, -0x75306d10, -0x65de96fe, -0x7ca6fc71, 0x038b7ea4 },\n        { 0x10a86e17, 0x336d3d11, 0x0b75b2fa, -0x280c77ce, 0x25072988, -0x06eacc8a, -0x66ef7479, 0x09674c6b },\n        { -0x66ce9008, -0x60b107df, -0x155872b1, 0x2f49d282, 0x5aef3174, 0x0971a5ab, 0x5969eb65, 0x6e5e3102 }\n    },\n    {\n        { 0x63066222, 0x3304fb0e, -0x785345c1, -0x04caf977, -0x73ef9e5d, -0x42e6db89, -0x2e7c79e0, 0x3058ad43 },\n        { -0x781a6c05, -0x4e939d0b, -0x35a2c18f, 0x4999edde, 0x14cc3e6d, -0x4b6e3e20, -0x76572458, 0x08f51147 },\n        { -0x1a899c30, 0x323c0ffd, -0x5dd159f0, 0x05c3df38, -0x5366b066, -0x42387543, -0x101c2367, 0x26549fa4 }\n    },\n},\n{\n    {\n        { -0x08ac6947, 0x04dbbc17, -0x2d0798ba, 0x69e6a2d7, -0x0ac1543a, -0x39bf6267, 0x332e25d2, 0x606175f6 },\n        { -0x78317077, 0x738b38d7, 0x4179a88d, -0x49d9a71e, -0x0eaece93, 0x30738c9c, 0x727275c9, 0x49128c7f },\n        { -0x0abf1823, 0x4021370e, -0x5e0e2f5b, 0x0910d6f5, 0x5b06b807, 0x4634aacd, 0x6944f235, 0x6a39e635 }\n    },\n    {\n        { 0x74049e9d, 0x1da19657, -0x6701cad5, -0x0432915f, -0x33adc95a, -0x4e3432b0, 0x3f9846e2, 0x1f5ec83d },\n        { -0x206f0c19, -0x6932a9c0, -0x2405da16, 0x6c3a760e, 0x59e33cc4, 0x24f3ef09, 0x530d2e58, 0x42889e7e },\n        { 0x328ccb75, -0x7104dc3d, -0x22789117, -0x50bd5df9, 0x5dfae796, 0x20fbdadc, 0x06bf9f51, 0x241e246b }\n    },\n    {\n        { 0x6280bbb8, 0x7eaafc9a, -0x0bfc27f7, 0x22a70f12, 0x1bfc8d20, 0x31ce40bb, -0x1742ac12, 0x2bc65635 },\n        { -0x5291670a, 0x29e68e57, 0x0b462065, 0x4c9260c8, -0x5ae144b5, 0x3f00862e, -0x4c726f69, 0x5bc2c77f },\n        { -0x5694526d, -0x172a2361, -0x21e6b824, -0x1a704e83, 0x65185fa3, 0x681532ea, 0x034a7830, 0x1fdd6c3b }\n    },\n    {\n        { 0x2dd8f7a9, -0x63ec595b, 0x3efdcabf, 0x2dbb1f8c, 0x5e08f7b5, -0x69e1cdc0, -0x4419361b, 0x48c8a121 },\n        { 0x55dc18fe, 0x0a64e28c, 0x3399ebdd, -0x1c206167, 0x70e2e652, 0x79ac4323, 0x3ae4cc0e, 0x35ff7fc3 },\n        { 0x59646445, -0x03bea584, -0x3ed749eb, -0x2ddb4d29, 0x05fbb912, 0x6035c9c9, 0x74429fab, 0x42d7a912 }\n    },\n    {\n        { -0x6cc25a44, -0x565b76b9, -0x3d168614, 0x4a58920e, 0x13e5ac4c, -0x69278000, 0x4b48b147, 0x453692d7 },\n        { -0x1508d12d, 0x4e6213e3, 0x43acd4e7, 0x6794981a, 0x6eb508cb, -0x00ab8322, 0x10fcb532, 0x6fed19dd },\n        { -0x57aa6391, -0x2288a267, -0x20ffc1dc, -0x0bd5dec0, -0x256d759a, 0x5223e229, 0x6d38f22c, 0x063f46ba }\n    },\n    {\n        { 0x37346921, 0x39843cb7, 0x38c89447, -0x58b804f9, -0x5dbacf82, -0x34727fcf, 0x6d82f068, 0x67810f8e },\n        { 0x5f536694, -0x2d2dbd77, 0x42939b2c, -0x35cc5d3b, -0x382246a4, -0x6790525a, 0x2f712d5d, 0x5a152c04 },\n        { -0x2dd7824c, 0x3eeb8fbc, 0x01a03e93, 0x72c7d3a3, -0x4267d9a6, 0x5473e88c, 0x5921b403, 0x7324aa51 }\n    },\n    {\n        { -0x17dcab35, -0x52dc0926, -0x49a8e593, 0x6962502a, -0x1c71c82f, -0x649ae9ca, -0x2e5cced1, 0x5cac5005 },\n        { 0x6c3cbe8e, -0x7a86bd0c, 0x4730c046, -0x5e2c9b4f, -0x2dc3be41, 0x1c8ed914, -0x11092a2e, 0x0838e161 },\n        { -0x161c66fc, -0x733eab34, -0x7b2197ba, 0x5b3a040b, -0x4e41a292, -0x3b2759e4, -0x2779e0fe, 0x40fb897b }\n    },\n    {\n        { 0x5ab10761, -0x1a8127b9, 0x6fd13746, 0x71435e20, -0x32fda9ce, 0x342f824e, -0x5786e185, 0x4b16281e },\n        { 0x62de37a1, -0x7b3a5570, 0x0d1d96e1, 0x421da500, 0x6a9242d9, 0x78828630, 0x690d10da, 0x3c5e464a },\n        { 0x0b813381, -0x2e3efe2b, 0x76ee6828, -0x2119f0ef, 0x383f6409, 0x0cb68893, -0x0900b7b6, 0x6183c565 }\n    },\n},\n{\n    {\n        { -0x50c09992, -0x24b97ab7, -0x0eb5f15b, -0x288030fc, -0x5b45f3b9, 0x3df23ff7, 0x32ce3c85, 0x3a10dfe1 },\n        { 0x1e6bf9d6, 0x741d5a46, 0x7777a581, 0x2305b3fc, 0x6474d3d9, -0x2baa8b5e, 0x6401e0ff, 0x1926e1dc },\n        { -0x15e83160, -0x1f80b176, 0x3a1fc1fd, 0x2fd51546, 0x31f2c0f1, 0x175322fd, -0x79e1a2eb, 0x1fa1d01d }\n    },\n    {\n        { -0x2e206b55, 0x38dcac00, -0x2ef7f217, 0x2e712bdd, -0x022a1d9e, 0x7f13e93e, -0x1165fe1b, 0x73fced18 },\n        { 0x7d599832, -0x337faa6c, 0x37f15520, 0x1e4656da, 0x4e059320, -0x6609088c, 0x6a75cf33, 0x773563bc },\n        { 0x63139cb3, 0x06b1e908, -0x3a5fc133, -0x5b6c2599, -0x529c76ce, -0x72883138, 0x1b864f44, 0x1f426b70 }\n    },\n    {\n        { -0x6e5edaae, -0x0e81ca38, 0x575e9c76, -0x48947ead, 0x0d9b723e, -0x057cbf91, 0x3fa7e438, 0x0b76bb1b },\n        { 0x41911c01, -0x1036d9b4, 0x17a22c25, -0x0e5c4848, -0x0cf0ebb9, 0x5875da6b, 0x1d31b090, 0x4e1af527 },\n        { 0x7f92939b, 0x08b8c1f9, -0x2bbb5492, -0x41988e35, -0x66447fe9, 0x22e56463, -0x488d56ab, 0x7b6dd61e }\n    },\n    {\n        { -0x54fe2d39, 0x5730abf9, 0x40143b18, 0x16fb76dc, -0x5f344d7f, -0x7993419b, -0x64009502, 0x53fa9b65 },\n        { 0x50f33d92, -0x48523e18, 0x608cd5cf, 0x7998fa4f, -0x7203a425, -0x5269d243, -0x50e2d0b1, 0x703e9bce },\n        { -0x6b77abab, 0x6c14c8e9, 0x65aed4e5, -0x7bc5a29a, -0x4329a50f, 0x181bb73e, -0x3b39e0b0, 0x398d93e5 }\n    },\n    {\n        { -0x2d181c0e, -0x3c7883a0, 0x30828bb1, 0x3b34aaa0, 0x739ef138, 0x283e26e7, 0x02c30577, 0x699c9c90 },\n        { 0x33e248f3, 0x1c4bd167, 0x15bf0a5f, -0x4261ed79, -0x5ef4fc8a, -0x2bc07310, -0x20e6e4ed, 0x53b09b5d },\n        { 0x5946f1cc, -0x0cf958dd, -0x331a2683, -0x6de8e74b, -0x7e4b168b, 0x28cdd247, 0x6fcdd907, 0x51caf30c }\n    },\n    {\n        { 0x18ac54c7, 0x737af99a, -0x3ae34cf1, -0x6fcc8724, 0x4ce10cc7, 0x2b89bc33, -0x76071666, 0x12ae29c1 },\n        { 0x7674e00a, -0x59f458be, -0x5e85840d, 0x630e8570, -0x30ccdb34, 0x3758563d, 0x2383fdaa, 0x5504aa29 },\n        { 0x1f0d01cf, -0x56613f35, 0x3a34f7ae, 0x0dd1efcc, -0x2f63b1de, 0x55ca7521, 0x58eba5ea, 0x5fd14fe9 }\n    },\n    {\n        { -0x406c3472, 0x3c42fe5e, 0x36d4565f, -0x412057af, -0x77bddf18, -0x1f0f7a62, 0x0725d128, 0x7dd73f96 },\n        { 0x2845ab2c, -0x4a23d221, 0x0a7fe993, 0x069491b1, 0x4002e346, 0x4daaf3d6, 0x586474d1, 0x093ff26e },\n        { 0x68059829, -0x4ef2db02, -0x2450dc1b, 0x75730672, -0x4ba853d7, 0x1367253a, -0x794b8f5c, 0x2f59bcbc }\n    },\n    {\n        { -0x496e3cff, 0x7041d560, -0x522818e2, -0x7adfe4c1, 0x11335585, 0x16c2e163, 0x010828b1, 0x2aa55e3d },\n        { -0x66e8eca1, -0x7c7b82be, 0x567d03d7, -0x52e46ee1, -0x4188552f, 0x7e7748d9, 0x2e51af4a, 0x5458b42e },\n        { 0x0c07444f, -0x12ae6d1a, 0x74421d10, 0x42c54e2d, -0x024a379c, 0x352b4c82, -0x7589799c, 0x13e9004a }\n    },\n},\n{\n    {\n        { -0x7f94b984, 0x1e6284c5, -0x18a29f85, -0x3a096685, -0x4c872d9e, -0x749826a8, -0x7e327490, 0x3d88d66a },\n        { 0x6c032bff, -0x344a4aab, 0x29297a3a, -0x208e6e49, -0x52127e45, -0x3e008cda, 0x68be03f5, 0x71ade8bb },\n        { 0x204ed789, -0x7489856d, -0x605f51d6, 0x762fcacb, 0x6dce4887, 0x771febcc, -0x700fa04d, 0x34306215 }\n    },\n    {\n        { 0x2a7b31b4, -0x031de6f9, -0x55a87fea, 0x4d7adc75, -0x78b86cdc, 0x0ec276a6, 0x1fda4beb, 0x6d6d9d5d },\n        { -0x1e0a40b7, -0x1fa25e59, -0x2b8c9f6e, 0x26457d6d, 0x73cc32f6, 0x77dcb077, -0x6322a033, 0x0a5d9496 },\n        { -0x164f7e7d, 0x22b1a58a, -0x3ea3c775, -0x026a2f8f, -0x7af5fae9, -0x567edc8a, -0x4480cca2, 0x33384cba }\n    },\n    {\n        { 0x26218b8d, 0x33bc627a, -0x3857f39f, -0x157f4de1, 0x173e9ee6, -0x6ba74ed5, 0x0e2f3059, 0x076247be },\n        { 0x0ca2c7b5, 0x3c6fa268, 0x6fb64fda, 0x1b508204, 0x5431d6de, -0x14accb64, 0x6b879c89, 0x5278b38f },\n        { 0x1416375a, 0x52e105f6, -0x7a54145c, -0x136850ca, 0x23a67c36, 0x26e6b506, -0x0c2b04ff, 0x5cf0e856 }\n    },\n    {\n        { 0x3db342a8, -0x415131cf, -0x7bd24812, -0x345c9ca5, -0x7e80ec11, -0x177399e0, 0x4e76d5c6, 0x1b9438aa },\n        { 0x1ae8cab4, -0x0936978d, -0x34b06d3b, 0x5e20741e, -0x733243c2, 0x2da53be5, 0x69970df7, 0x2dddfea2 },\n        { 0x166f031a, -0x75af8882, 0x0fb7a328, 0x067b39f1, 0x010fbd76, 0x1925c9a6, -0x338bf6fb, 0x6df9b575 }\n    },\n    {\n        { 0x48cade41, -0x13203ca5, -0x4dcd7d90, 0x6a88471f, 0x40a01b6a, 0x740a4a24, 0x003b5f29, 0x471e5796 },\n        { 0x27f6bdcf, 0x42c11929, 0x403d61ca, -0x706e6e86, -0x7461e09f, -0x23e3a59a, 0x04ec0f8d, 0x15960478 },\n        { -0x5312c854, -0x2569444d, -0x16df7316, 0x7a2423b5, 0x38aebae2, 0x24cc5c30, -0x23a251d1, 0x50c356af }\n    },\n    {\n        { 0x1b31b964, -0x30126321, -0x735ae50d, -0x0b79567b, -0x1573e07c, 0x14897265, -0x6cd53400, 0x784a53dd },\n        { 0x41c30318, 0x09dcbf43, -0x7ce7e232, -0x1145f9ef, -0x23e1d65f, -0x3e863f32, 0x073f35b0, 0x1dbf7b89 },\n        { 0x14fc4920, 0x2d99f9df, -0x3bb6601b, 0x76ccb60c, -0x1a30fffd, -0x5becd345, 0x54f000ea, 0x3f93d823 }\n    },\n    {\n        { 0x79e14978, -0x1553ed2f, -0x441400a2, -0x006dc00d, 0x0663ce27, 0x4af663e4, 0x11a5f5ff, 0x0fd381a8 },\n        { -0x61fb317b, -0x7e7c1898, 0x04465341, 0x678fb71e, 0x6688edac, -0x526dfa71, 0x532b099a, 0x5da350d3 },\n        { -0x5bc920ac, -0x0da95314, -0x51962918, 0x108b6168, 0x6b5d036c, 0x20d986cb, -0x011d50b0, 0x655957b9 }\n    },\n    {\n        { -0x2ffd2f54, -0x423ebf65, -0x4a33265a, 0x66660245, -0x05217a14, -0x7dce823c, 0x6ad7df0d, 0x02fe934b },\n        { -0x56fdfcf1, -0x51574f81, -0x0b9c2ebd, -0x07738996, 0x3c787a60, 0x15b08366, -0x7d985b58, 0x08eab114 },\n        { -0x3048158c, -0x10a30f00, -0x5e34bd54, 0x22897633, -0x310d7a1e, -0x2b31f3ac, -0x75eb95ab, 0x30408c04 }\n    },\n},\n{\n    {\n        { 0x193b877f, -0x44d1ff37, -0x1f23af95, -0x131c5770, 0x36de649f, -0x130c4840, -0x672161e6, 0x5f460408 },\n        { -0x7cd03125, 0x739d8845, -0x5194079d, -0x05c72937, -0x48b00109, 0x32bc0dca, 0x14bce45e, 0x73937e88 },\n        { 0x297bf48d, -0x46fc8eea, -0x2b0f97cc, -0x562ec4de, 0x4696bdc6, -0x1e68eaa9, -0x6e2a17cb, 0x2cf8a4e8 }\n    },\n    {\n        { 0x17d06ba2, 0x2cb5487e, 0x3950196b, 0x24d2381c, -0x7a6875d0, -0x289a637f, -0x6e295b0a, 0x7a6f7f28 },\n        { 0x07110f67, 0x6d93fd87, 0x7c38b549, -0x22b3f62d, -0x3d8c957a, 0x7cb16a4c, 0x58252a09, 0x2049bd6e },\n        { 0x6a9aef49, 0x7d09fd8d, 0x5b3db90b, -0x0f119f42, 0x519ebfd4, 0x4c21b52c, -0x3aba6be3, 0x6011aadf }\n    },\n    {\n        { 0x02cbf890, 0x63ded0c8, 0x0dff6aaa, -0x042f6736, -0x46491267, 0x624d0afd, 0x79340b1e, 0x69ce18b7 },\n        { -0x306a07c4, 0x5f67926d, 0x71289071, 0x7c7e8561, -0x667085a5, -0x295e180d, 0x0b62f9e0, 0x6fc5cc1b },\n        { -0x4d678635, -0x2e10aad8, -0x2b816f6e, -0x22e551c4, 0x189f2352, 0x127e0442, -0x1a8efe0f, 0x15596b3a }\n    },\n    {\n        { 0x7e5124ca, 0x09ff3116, -0x2638ba21, 0x0be4158b, 0x7ef556e5, 0x292b7d22, -0x50492ec8, 0x3aa4e241 },\n        { 0x3f9179a2, 0x462739d2, -0x68292231, -0x007cedcf, 0x53f2148a, 0x1307deb5, 0x7b5f4dda, 0x0d223768 },\n        { 0x2a3305f5, 0x2cc138bf, -0x5d16d93d, 0x48583f8f, 0x5549d2eb, 0x083ab1a2, 0x4687a36c, 0x32fcaa6e }\n    },\n    {\n        { 0x2787ccdf, 0x3207a473, -0x0dec1c08, 0x17e31908, -0x09f269b2, -0x2a4d1329, -0x3d9ff417, 0x746f6336 },\n        { -0x3a82650b, 0x7bc56e8d, -0x620f420e, 0x3e0bd2ed, 0x22efe4a3, -0x553feb22, -0x014295a4, 0x4627e9ce },\n        { -0x549368e4, 0x3f4af345, -0x66bc8ce1, -0x1d77148e, 0x0344186d, 0x33596a8a, 0x7ed66293, 0x7b491700 }\n    },\n    {\n        { -0x22ac5d23, 0x54341b28, -0x20bd03c1, -0x55e86fa5, 0x4dd2f8f4, 0x0ff592d9, -0x1f732c83, 0x1d03620f },\n        { -0x547b4f9c, 0x2d85fb5c, -0x760c43ec, 0x497810d2, 0x7b15ce0c, 0x476adc44, -0x07bb0285, 0x122ba376 },\n        { -0x5d4b1aac, -0x3dfdcd33, 0x115d187f, -0x612f02be, 0x7dd479d9, 0x2eabb4be, 0x2b68ec4c, 0x02c70bf5 }\n    },\n    {\n        { 0x458d72e1, -0x531acd41, 0x7cb73cb5, 0x5be768e0, -0x11744219, 0x56cf7d94, -0x014bc5fd, 0x6b0697e3 },\n        { 0x5d0b2fbb, -0x5d7813b5, 0x074882ca, 0x415c5790, -0x3e2f7ea4, -0x1fbb59e2, 0x409ef5e0, 0x26334f0a },\n        { -0x209d5c40, -0x49370fb6, 0x076da45d, 0x3ef000ef, 0x49f0d2a9, -0x636346a8, 0x441b2fae, 0x1cc37f43 }\n    },\n    {\n        { -0x36315147, -0x2899a90f, 0x18e5656a, 0x1c5b15f8, -0x7bb3dccc, 0x26e72832, 0x2f196838, 0x3a346f77 },\n        { 0x5cc7324f, 0x508f565a, -0x1af956de, -0x2f9e3b40, 0x5c45ac19, -0x04e75425, 0x0380314a, 0x6c6809c1 },\n        { -0x1d259538, -0x2d2aaeee, -0x4e17ae13, -0x1642fccf, -0x71398d9e, -0x69f8b923, 0x6ef7c5d0, 0x05911b9f }\n    },\n},\n{\n    {\n        { -0x3a01606c, 0x01c18980, 0x716fd5c8, -0x329a9897, -0x2e6a5f7a, -0x7e9fba3d, 0x66cc7982, 0x6e2b7f32 },\n        { -0x49c800d3, -0x162328aa, -0x36780f3c, -0x13b3cb71, -0x0c043849, -0x312a6d7b, -0x6c1e1579, 0x33053547 },\n        { -0x083ca971, -0x337fdb98, 0x19974cb3, -0x6216457e, -0x4a47eca0, -0x5448dd64, 0x6fbeba62, 0x44e2017a }\n    },\n    {\n        { -0x49359133, -0x7807d30d, 0x18f4a0c2, 0x580f893e, 0x2604e557, 0x05893007, 0x56d19c1d, 0x6cab6ac2 },\n        { 0x54dab774, -0x3b3d58bd, 0x4eaf031a, -0x71a2b3c4, 0x42838f17, -0x4893dc2e, 0x68dce4ea, 0x749a098f },\n        { 0x2cc1de60, -0x23201f60, 0x51c5575b, 0x032665ff, 0x073abeeb, 0x2c0c32f1, -0x328479fa, 0x6a882014 }\n    },\n    {\n        { -0x50b01492, -0x2eee2e84, -0x4cc55b5d, 0x050bba42, -0x114b93d0, 0x17514c3c, 0x1bc27d75, 0x54bedb8b },\n        { -0x5b8b804b, -0x5ad56d02, 0x1fa5ab89, -0x23ed5bb7, -0x47b85b32, -0x27d256b5, -0x6aed33b2, 0x4d77edce },\n        { 0x77e2189c, 0x77c8e145, -0x00663bbb, -0x5c1b9096, 0x6d335343, 0x3144dfc8, 0x7c4216a9, 0x3a96559e }\n    },\n    {\n        { -0x7f4555ae, 0x44938968, -0x0d7a6bf2, 0x4c98afc4, -0x5babb74a, -0x10b55865, -0x5a855181, 0x5278c510 },\n        { -0x0bd52d12, 0x12550d37, -0x675e040b, -0x74871ffc, 0x33894cb2, 0x5d530782, 0x3e498d0c, 0x02c84e4e },\n        { 0x294c0b94, -0x5ab22f8c, -0x20e7004a, -0x0aa2b948, -0x72517c9a, -0x0f90133b, -0x7e6f2e9b, 0x58865766 }\n    },\n    {\n        { 0x3de25cc3, -0x40a7cb10, -0x297eab6a, -0x47783752, -0x6b7e176e, 0x5105221a, -0x088dc06d, 0x6760ed19 },\n        { 0x1aef7117, -0x2b88edcf, 0x229e92c7, 0x50343101, -0x62ea6469, 0x7a95e184, -0x74a2d637, 0x2449959b },\n        { -0x53ca1ea0, 0x669ba3b7, -0x457bdfaa, 0x2eccf73f, -0x3f7fb0f9, 0x1aec1f17, 0x1856f4e7, 0x0d96bc03 }\n    },\n    {\n        { -0x338afa1f, -0x4e2acb50, 0x16c35288, 0x32cd0034, 0x0762c29d, -0x34c95a80, 0x237a0bf8, 0x5bfe69b9 },\n        { 0x75c52d82, 0x3318be77, 0x54d0aab9, 0x4cb764b5, -0x3388c26f, -0x5430c2d9, -0x7edcd776, 0x3bf4d184 },\n        { 0x78a151ab, 0x183eab7e, -0x66f6c89d, -0x44166f37, 0x4ac7e335, -0x008e8292, 0x25f39f88, 0x4c5cddb3 }\n    },\n    {\n        { -0x185606fe, 0x57750967, 0x4f5b467e, 0x2c37fdfc, 0x3177ba46, -0x4d9e99c6, -0x23d2acd5, 0x3a375e78 },\n        { 0x6190a6eb, -0x3f0948b3, 0x2db8f4e4, 0x20ea81a4, -0x68cea8a0, -0x57429083, 0x62ac7c21, 0x33b1d602 },\n        { 0x2d4dddea, -0x7ebe18d1, 0x62c607c8, -0x19150168, 0x573cafd0, 0x23c28458, 0x4ff97346, 0x46b9476f }\n    },\n    {\n        { 0x0d58359f, 0x1215505c, -0x03d73b95, 0x2a2013c7, -0x761599b2, 0x24a0a1af, -0x5eecf1e1, 0x4400b638 },\n        { 0x4f901e5c, 0x0c1ffea4, 0x2184b782, 0x2b0b6fb7, 0x0114db88, -0x1a78006f, 0x4785a142, 0x37130f36 },\n        { -0x6912e63d, 0x3a01b764, -0x12cd8dd0, 0x31e00ab0, -0x7c35ea4f, 0x520a8857, 0x5accbec7, 0x06aab987 }\n    },\n},\n{\n    {\n        { 0x512eeaef, 0x5349acf3, 0x1cc1cb49, 0x20c141d3, -0x56659773, 0x24180c07, -0x39b4d2e9, 0x555ef9d1 },\n        { -0x0a20f145, -0x3ecc667d, 0x512c4cac, -0x3f0c8a71, 0x0bb398e1, 0x2cf1130a, -0x55d8f39e, 0x6b3cecf9 },\n        { 0x3b73bd08, 0x36a770ba, -0x5c5040f4, 0x624aef08, -0x4bf6b90e, 0x5737ff98, 0x3381749d, 0x675f4de1 }\n    },\n    {\n        { 0x3bdab31d, -0x5ed00927, -0x629ad202, 0x0725d80f, -0x65416b79, 0x019c4ff3, -0x7d32c3bd, 0x60f450b8 },\n        { 0x6b1782fc, 0x0e2c5203, 0x6cad83b4, 0x64816c81, 0x6964073e, -0x2f234227, 0x0164c520, 0x13d99df7 },\n        { 0x21e5c0ca, 0x014b5ec3, -0x28e6405e, 0x4fcb69c9, 0x750023a0, 0x4e5f1c18, 0x55edac80, 0x1c06de9e }\n    },\n    {\n        { -0x00929656, -0x002ad4c0, -0x23bfb645, 0x34530b18, -0x5cb26769, 0x5e4a5c2f, 0x7d32ba2d, 0x78096f8e },\n        { -0x5cc13b1e, -0x66f0852a, -0x41d11f72, 0x6608f938, 0x63284515, -0x635ebc3b, -0x13d249f3, 0x4cf38a1f },\n        { 0x0dfa5ce7, -0x5f55559b, 0x48b5478c, -0x063b61d6, 0x7003725b, 0x4f09cc7d, 0x26091abe, 0x373cad3a }\n    },\n    {\n        { -0x76224453, -0x0e415705, 0x61aeaecb, 0x3bcb2cbc, 0x1f9b8d9d, -0x70a75845, 0x5112a686, 0x21547eda },\n        { -0x7d360a84, -0x4d6b9cb3, 0x24934536, 0x1fcbfde1, 0x418cdb5a, -0x6163b24d, 0x454419fc, 0x0040f3d9 },\n        { -0x02a6792d, -0x210216c7, 0x510a380c, -0x0bd8d377, -0x44cee647, -0x48d45bf9, 0x4a254df4, 0x63550a33 }\n    },\n    {\n        { 0x72547b49, -0x6445a7bb, -0x1d3bf720, -0x0cfa3906, -0x38cb0e73, 0x60e8fa69, -0x55828986, 0x39a92baf },\n        { -0x4a9630c9, 0x6507d6ed, 0x0ca52ee1, 0x178429b0, -0x149429a3, -0x1583ff70, -0x250870af, 0x3eea62c7 },\n        { -0x196cd8b2, -0x62db38ed, 0x68dbd375, 0x5f638577, -0x14754c66, 0x70525560, 0x65c9c4cd, 0x68436a06 }\n    },\n    {\n        { -0x17dfef84, 0x1e56d317, -0x7bf5169b, -0x3ad997bc, 0x320ffc7a, -0x3e1f5e3a, -0x6e9eeb8e, 0x5373669c },\n        { 0x202f3f27, -0x43fdca18, 0x64f975b0, -0x38a3ff1e, -0x5c73dbea, -0x6e5b162b, -0x75487607, 0x17b6e7f6 },\n        { -0x65f1ada9, 0x5d2814ab, -0x36354c04, -0x6f70df7c, 0x5b2d1eca, -0x50350a78, 0x78f87d11, 0x1cb4b5a6 }\n    },\n    {\n        { -0x5d5ff819, 0x6b74aa62, -0x0f8e384f, -0x0cee1f50, 0x000be223, 0x5707e438, -0x7d109154, 0x2dc0fd2d },\n        { 0x394afc6c, -0x499b3f95, -0x6725a04f, 0x0c88de24, 0x4bcad834, 0x4f8d0316, -0x218bcb5e, 0x330bca78 },\n        { 0x1119744e, -0x67d1007c, 0x2b074724, -0x0696a16a, -0x4036ac05, -0x3a753eb1, 0x369f1cf5, 0x3c31be1b }\n    },\n    {\n        { -0x0634bd8e, -0x3e97436d, -0x38312468, -0x51478ee1, 0x34ac8d7a, 0x7f0e52aa, 0x7e7d55bb, 0x41cec109 },\n        { 0x08948aee, -0x4f0b79b3, -0x6e45e391, 0x07dc19ee, -0x59535ea8, 0x7975cdae, 0x4262d4bb, 0x330b6113 },\n        { -0x5d927f76, -0x0869e629, 0x1d9e156d, -0x44e02b62, -0x245e20d9, 0x73d7c36c, 0x1f28777d, 0x26b44cd9 }\n    },\n},\n{\n    {\n        { -0x4fd7a0c9, -0x50bb7bd3, 0x47efc8df, -0x78ace770, -0x07df6866, -0x6a8b1f6f, 0x69615579, 0x0e378d60 },\n        { 0x393aa6d8, 0x300a9035, -0x5ed44e33, 0x2b501131, -0x0f6c3dde, 0x7b1ff677, -0x3547d453, 0x4309c1f8 },\n        { -0x7cf8a5ab, -0x26056e8f, 0x6b009fdc, 0x4bdb5ad2, -0x29c210f2, 0x7829ad2c, 0x75fd3877, 0x078fc549 }\n    },\n    {\n        { -0x47cc5676, -0x1dffb4a5, 0x2d4c3330, 0x44775dec, 0x7eace913, 0x3aa24406, -0x2a71ff57, 0x272630e3 },\n        { 0x28878f2d, -0x782042ec, 0x1e9421a1, 0x134636dd, 0x257341a3, 0x4f17c951, -0x52d69348, 0x5df98d4b },\n        { -0x1336f4ac, -0x0c987030, 0x12043599, -0x0ffeba65, 0x3758b89b, 0x26725fbc, 0x73a719ae, 0x4325e4aa }\n    },\n    {\n        { -0x30960a63, -0x12db9d66, -0x22a5440c, 0x2a4a1cce, 0x56b2d67b, 0x3535ca1f, 0x43b1b42d, 0x5d8c68d0 },\n        { 0x433c3493, 0x657dc6ef, -0x7f24073d, 0x65375e9f, 0x5b372dae, 0x47fd2d46, 0x796e7947, 0x4966ab79 },\n        { -0x1c4bd4f6, -0x11ccd2b3, 0x16a4601c, -0x27b1a5d5, 0x078ba3e4, 0x78243877, 0x184ee437, 0x77ed1eb4 }\n    },\n    {\n        { -0x616d12e6, 0x185d43f8, -0x01b8e63a, -0x4fb5e116, -0x590fc0b1, 0x499fbe88, 0x3c859bdd, 0x5d8b0d2f },\n        { 0x201839a0, -0x402b1ec1, 0x3e3df161, -0x5110001e, 0x6b5d1fe3, -0x49a4fb10, 0x2b62fbc0, 0x52e085fb },\n        { -0x5ab30d46, 0x124079ea, 0x001b26e7, -0x28db9a15, -0x36850803, 0x6843bcfd, 0x55eacd02, 0x0524b42b }\n    },\n    {\n        { -0x647d6154, -0x43e72353, -0x4a0a8630, 0x23ae7d28, 0x69384233, -0x3cb9edd6, -0x182b5377, 0x1a6110b2 },\n        { -0x1babb850, -0x02f2a242, 0x092005ee, 0x6cec351a, 0x567579cb, -0x665b87bc, 0x16e7fa45, 0x59d242a2 },\n        { -0x19966854, 0x4f833f6a, 0x361839a4, 0x6849762a, -0x68f54adb, 0x6985dec1, -0x234e0aba, 0x53045e89 }\n    },\n    {\n        { -0x72ba01ee, -0x7b25c322, -0x1bbb1d2e, -0x42bd3de8, 0x1f7e3598, -0x57ae6988, 0x5616e2b2, 0x7642c93f },\n        { -0x28acac25, -0x34744cba, -0x51aee1de, -0x03034db5, -0x2af51911, -0x345b72c0, -0x0b0834a3, 0x26e3bae5 },\n        { 0x4595f8e4, 0x2323daa7, -0x7a85414c, -0x21977375, 0x1c59326e, 0x3fc48e96, 0x15c9b8ba, 0x0b2e73ca }\n    },\n    {\n        { 0x79c03a55, 0x0e3fbfaf, 0x4cbb5acf, 0x3077af05, -0x24c21c61, -0x2a3aadbb, 0x476a4af7, 0x015e68c1 },\n        { -0x3e80afda, -0x2944bbd8, -0x04a56359, -0x614d8ddd, 0x1919c644, -0x1c845afd, -0x4a6599fe, 0x21ce380d },\n        { 0x20066a38, -0x3e2ad7ae, 0x3570aef3, -0x6a9fc1ae, 0x226b8a4d, -0x7cd9a659, 0x1f8eedc9, 0x5dd68909 }\n    },\n    {\n        { -0x5acecf7c, 0x1d022591, -0x29d8f78e, -0x35d2b552, 0x2f0bfd20, -0x795ed47b, -0x528258b8, 0x56e6c439 },\n        { -0x402c37aa, -0x34537b22, -0x4ca00dbc, 0x1624c348, 0x5d9cad07, -0x48077236, -0x5d3d1418, 0x3b0e574d },\n        { 0x42bdbae6, -0x38fb00b7, -0x4d21e087, 0x5e21ade2, 0x5652fad8, -0x16a24c0d, -0x70f7143f, 0x0822b537 }\n    },\n},\n{\n    {\n        { 0x62730383, -0x1e480d6d, -0x143575d4, 0x4b5279ff, -0x402becec, -0x25038876, -0x638d9ef1, 0x7deb1014 },\n        { -0x70c78b8b, 0x51f04847, -0x634134c4, -0x4da2430c, -0x2660dfab, -0x6554edbc, 0x1c10a5d6, 0x2c709e6c },\n        { -0x78991186, -0x349d5096, 0x5553cd0e, 0x66cbec04, 0x0f0be4b5, 0x58800138, -0x09d31d16, 0x08e68e9f }\n    },\n    {\n        { 0x0ab8f2f9, 0x2f2d09d5, -0x3aa6dc21, -0x5346de73, 0x73766cb9, 0x4a8f3426, 0x38f719f5, 0x4cb13bd7 },\n        { 0x4bc130ad, 0x34ad500a, 0x3d0bd49c, -0x72c724b7, 0x500a89be, -0x5da3c268, -0x1145c4f7, 0x2f1f3f87 },\n        { -0x1aea49b6, -0x087b738b, -0x24b56fc8, -0x5a6afe46, 0x3f751b50, -0x3df2cec1, -0x3f51d118, 0x19a1e353 }\n    },\n    {\n        { -0x2a694243, -0x4bde8d33, -0x671103c0, -0x6c1fbabd, -0x4bbef64b, -0x604eacb9, 0x0266ae34, 0x736bd399 },\n        { -0x4505fa3d, 0x7d1c7560, -0x391aa19f, -0x4c1e5f60, -0x3f299b8d, -0x1cad68e8, -0x3df3cb7a, 0x41546b11 },\n        { -0x6ccb4c4c, -0x7aacd2b0, 0x60816573, 0x46fd114b, 0x425c8375, -0x33a0a0d0, -0x478054a4, 0x412295a2 }\n    },\n    {\n        { -0x1d6c153a, 0x2e655261, 0x2133acdb, -0x7ba56dfd, 0x7900996b, 0x460975cb, 0x195add80, 0x0760bb8d },\n        { -0x0a812917, 0x19c99b88, 0x6df8c825, 0x5393cb26, -0x4cf52d8d, 0x5cee3213, -0x4ad2d1cc, 0x14e153eb },\n        { -0x32197e76, 0x413e1a17, -0x12965f7c, 0x57156da9, 0x46caccb1, 0x2cbf268f, -0x3cc53a0e, 0x6b34be9b }\n    },\n    {\n        { 0x6571f2d3, 0x11fc6965, 0x530e737a, -0x393617bb, -0x2b01afcb, -0x1cc5185e, 0x2e6dd30b, 0x01b9c7b6 },\n        { 0x3a78c0b2, -0x0c20d09c, -0x0dd1fd84, 0x4c3e971e, 0x49c1b5a3, -0x1382e3a2, 0x0922dd2d, 0x2012c18f },\n        { 0x5ac89d29, -0x77f4aa1b, 0x45a0a763, 0x1483241f, -0x3d1893e1, 0x3d36efdf, 0x4e4bade8, 0x08af5b78 }\n    },\n    {\n        { -0x7633d3b5, -0x1d8ceb2e, -0x5d78e873, 0x4be4bd11, -0x05cc9b32, 0x18d528d6, -0x50267d92, 0x6423c1d5 },\n        { -0x77e0dacd, 0x283499dc, 0x779323b6, -0x62fada26, 0x673441f4, -0x76852205, 0x163a168d, 0x32b79d71 },\n        { -0x12034c96, -0x337a0727, 0x3746e5f9, 0x22bcc28f, -0x061a2c33, -0x1b621cc8, -0x3ec1d234, 0x480a5efb }\n    },\n    {\n        { 0x42ce221f, -0x499eb31c, 0x4c053928, 0x6e199dcc, -0x23e341fd, 0x663fb4a4, 0x691c8e06, 0x24b31d47 },\n        { 0x01622071, 0x0b51e70b, -0x74e2503b, 0x06b505cf, -0x10a55433, 0x2c6bb061, 0x0cb7bf31, 0x47aa2760 },\n        { -0x3fea073d, 0x2a541eed, 0x7c693f7c, 0x11a4fe7e, 0x4ea278d6, -0x0f5099ed, 0x14dda094, 0x545b585d }\n    },\n    {\n        { -0x1c4cde1f, 0x6204e4d0, 0x28ff1e95, 0x3baa637a, 0x5b99bd9e, 0x0b0ccffd, 0x64c8d071, 0x4d22dc3e },\n        { -0x5f2bc5f1, 0x67bf275e, 0x089beebe, -0x521971cc, -0x2b8618d2, 0x4289134c, 0x32ba5454, 0x0f62f9c3 },\n        { -0x29c4a0c7, -0x034b9a77, 0x57cbcf61, 0x5cae6a3f, -0x6ac505fb, -0x01453d2e, 0x36371436, 0x1c0fa01a }\n    },\n},\n{\n    {\n        { 0x54c53fae, -0x3ee11a18, 0x2b4f3ff4, 0x6a0b06c1, -0x1f49858e, 0x33540f80, -0x32f81c11, 0x15f18fc3 },\n        { -0x4383296e, -0x18ab8bb7, -0x1908c221, 0x0f9abeaa, 0x00837e29, 0x4af01ca7, 0x3f1bc183, 0x63ab1b5d },\n        { -0x4fd70b74, 0x32750763, 0x556a065f, 0x06020740, -0x3cb6a4a8, -0x2ac427ee, -0x79a0af73, 0x08706c9b }\n    },\n    {\n        { 0x38b41246, -0x3366e4bf, 0x6f9ac26b, 0x243b9c52, -0x48345443, -0x4610b6b3, -0x2f7d1300, 0x5fba433d },\n        { 0x3d343dff, -0x0c835d55, -0x7f5439e9, 0x1a8c6a2d, -0x2b330036, -0x71b61fcb, -0x455e2e47, 0x48b46bee },\n        { -0x366be530, -0x63b61cab, 0x74498f84, -0x468cb522, 0x66663e5c, 0x41c3fed0, -0x1718ef4d, 0x0ecfedf8 }\n    },\n    {\n        { -0x16bfc89e, 0x744f7463, -0x72033637, -0x08657212, 0x55e4cde3, 0x163a6496, -0x4d7b0bcb, 0x3b61788d },\n        { -0x632b8f27, 0x76430f9f, -0x5bd09ff8, -0x49d53365, 0x59adad5e, 0x1898297c, -0x4873af80, 0x7789dd2d },\n        { 0x0d6ef6b2, -0x4dddd7e7, 0x46ce4bfa, -0x56b5994e, 0x4f0b6cc7, 0x46c1a77a, -0x148cc731, 0x4236ccff }\n    },\n    {\n        { -0x2588820a, 0x3bd82dbf, 0x0b98369e, 0x71b177cc, -0x7af3c967, 0x1d0e8463, 0x48e2d1f1, 0x5a71945b },\n        { 0x0d55e274, -0x7b68bfb3, -0x3b52d4ad, 0x6c6663d9, -0x5256a8cc, -0x13d04f27, -0x324708c4, 0x2617e120 },\n        { 0x405b4b42, 0x6f203dd5, 0x10b24509, 0x327ec604, -0x53d577ba, -0x63cb8dd0, 0x11ffeb6a, 0x77de29fc }\n    },\n    {\n        { -0x13312d36, -0x7ca1ec71, -0x1569c466, -0x736150ed, -0x4de9f15a, -0x36a04040, -0x5278876e, 0x575e66f3 },\n        { -0x7c488758, -0x4f53a837, -0x28016ed4, 0x53cdcca9, -0x00e0a624, 0x61c2b854, -0x0f218254, 0x3a1a2cf0 },\n        { -0x377034c6, -0x667fc5d9, 0x275ec0b0, 0x345a6789, -0x0093d41b, 0x459789d0, 0x1e70a8b2, 0x62f88265 }\n    },\n    {\n        { 0x698a19e0, 0x6d822986, 0x74d78a71, -0x2367de1f, -0x0934e0b9, 0x41a85f31, -0x432563af, 0x352721c2 },\n        { 0x59ff1be4, 0x085ae2c7, 0x3b0e40b7, 0x149145c9, 0x7ff27379, -0x3b981806, -0x2a38c56b, 0x4eeecf0a },\n        { 0x213fc985, 0x48329952, 0x368a1746, 0x1087cf0d, 0x66c15aa5, -0x71ad9e4f, 0x2ed24c21, 0x2d5b2d84 }\n    },\n    {\n        { 0x196ac533, 0x5eb7d13d, -0x247f41d5, 0x377234ec, 0x7cf5ae24, -0x1ebb3004, -0x3bbe5314, 0x5226bcf9 },\n        { -0x142c212f, 0x02cfebd9, 0x39021974, -0x2ba4de89, -0x01cf5e49, 0x7576f813, -0x5cb1093e, 0x5691b6f9 },\n        { 0x23e5b547, 0x79ee6c72, -0x7ccf2987, 0x6f5f5076, 0x6d8adce9, -0x128c1e17, 0x1d8ccc03, 0x27c3da1e }\n    },\n    {\n        { 0x630ef9f6, 0x28302e71, 0x2b64cee0, -0x3d2b5dfd, 0x4b6292be, 0x09082030, -0x57d520e8, 0x5fca747a },\n        { 0x3fe24c74, 0x7eb9efb2, 0x1651be01, 0x3e50f49f, 0x21858dea, 0x3ea732dc, 0x5bb810f9, 0x17377bd7 },\n        { 0x5c258ea5, 0x232a03c3, 0x6bcb0cf1, -0x790dc5d4, 0x2e442166, 0x3dad8d0d, -0x548979d5, 0x04a8933c }\n    },\n},\n{\n    {\n        { -0x736c95b0, 0x69082b0e, -0x3e253a4a, -0x06365fcb, -0x3b2049cc, 0x6fb73e54, 0x1d2bc140, 0x4005419b },\n        { 0x22943dff, -0x2d39fb4a, 0x44cfb3a0, -0x43734132, -0x687f7988, 0x5d254ff3, 0x3b1ca6bf, 0x0fa3614f },\n        { -0x46417d10, -0x5ffc0143, 0x3a44ac90, 0x2089c1af, 0x1954fa8e, -0x07b6606f, -0x10bf54be, 0x1fba218a }\n    },\n    {\n        { 0x3e7b0194, 0x4f3e5704, 0x08daaf7f, -0x57e2c112, -0x6623210f, -0x37c63955, -0x00889e2b, 0x6c535d13 },\n        { -0x05370ac2, -0x54ab6bb8, 0x7ba63741, -0x7e091766, 0x6c2b5e01, 0x74fd6c7d, -0x573791be, 0x392e3aca },\n        { 0x3e8a35af, 0x4cbd34e9, 0x5887e816, 0x2e078144, -0x0d654f55, 0x19319c76, -0x2af53ec5, 0x25e17fe4 }\n    },\n    {\n        { 0x76f121a7, -0x6ea0800b, 0x2fcd87e3, -0x3cb5cdd9, 0x4d1be526, -0x3345d022, -0x76967665, 0x6bba828f },\n        { 0x1e04f676, 0x0a289bd7, -0x29bdf06b, 0x208e1c52, 0x34691fab, 0x5186d8b0, 0x2a9fb351, 0x25575144 },\n        { -0x6f01c6ff, -0x1d2e439a, -0x5f66852b, 0x4cb54a18, -0x507b9f2c, -0x68e296ec, 0x7f6b7be4, 0x559d504f }\n    },\n    {\n        { -0x092d9903, -0x63b76e19, 0x0307781b, 0x0744a19b, 0x6061e23b, -0x77c770e3, 0x354bd50e, 0x123ea6a3 },\n        { -0x4c14ab2b, -0x588c7c88, -0x5aaac384, 0x1d69d366, -0x06d7ff46, 0x0a26cf62, -0x7f81cde9, 0x01ab12d5 },\n        { 0x41e32d96, 0x118d1890, -0x27cea7b8, -0x46121c3e, -0x27cdba27, 0x1eab4271, -0x36e75eac, 0x4a3961e2 }\n    },\n    {\n        { -0x0cdcc0e2, 0x0327d644, 0x34fcf016, 0x499a260e, -0x0d254687, -0x7c4a58ea, -0x642beee1, 0x68aceead },\n        { -0x07194460, 0x71dc3be0, 0x7effe30a, -0x293107cc, -0x1ec5b896, -0x566dbda1, -0x04e2489d, 0x2cd6bce3 },\n        { -0x0c283df0, 0x38b4c90e, -0x4852fbf4, 0x308e6e24, -0x4818c1dd, 0x3860d9f1, -0x4af70a69, 0x595760d5 }\n    },\n    {\n        { -0x02fdd870, -0x77d53415, -0x3beea8a0, -0x7650ccfb, 0x7d3473f4, 0x65f492e3, 0x54515a2b, 0x2cb2c5df },\n        { 0x04aa6397, 0x6129bfe1, -0x5b580335, -0x7069fff8, 0x7d909458, 0x3f8bc089, -0x234d6e57, 0x709fa43e },\n        { 0x63fd2aca, -0x14f5a274, 0x2e694eff, -0x2dd43e9a, -0x07344fc6, 0x2723f36e, -0x0f37ece1, 0x70f029ec }\n    },\n    {\n        { 0x5e10b0b9, 0x2a6aafaa, -0x10fbe557, 0x78f0a370, -0x55c529e1, 0x773efb77, -0x58b4261f, 0x44eca5a2 },\n        { 0x2eed3e33, 0x461307b3, -0x5baa7e19, -0x51fbd0cd, 0x195f0366, -0x36bbb62d, 0x6c314858, 0x0b7d5d8a },\n        { 0x7b95d543, 0x25d44832, -0x5ccbf0e3, 0x70d38300, 0x60e1c52b, -0x21e3ace4, 0x2c7de9e4, 0x27222451 }\n    },\n    {\n        { 0x42a975fc, -0x40844476, -0x69525ca8, -0x73a3c689, -0x321255b8, -0x1d803891, -0x0943df5a, 0x19735fd7 },\n        { 0x49c5342e, 0x1abc92af, -0x4d190530, -0x001127ef, -0x0337b1d7, -0x105d7373, -0x5bb33abd, 0x11b5df18 },\n        { 0x42c84266, -0x1c546f30, 0x7f19547e, -0x147b71f1, 0x65a497b9, 0x2503a1d0, -0x6e2076a1, 0x0fef9111 }\n    },\n},\n{\n    {\n        { 0x5b1c16b7, 0x6ab5dcb8, 0x3c7b27a5, -0x6b3f0318, 0x735517be, -0x5b4ee3e6, -0x45f15056, 0x499238d0 },\n        { -0x54e39147, -0x4eaf835f, 0x16b687b3, -0x42bb70c2, 0x2c7a91ab, 0x3455fb7f, 0x2f2adec1, 0x7579229e },\n        { 0x7aba8b57, -0x130b91ae, -0x742e9b85, 0x15a08c47, 0x5f706fef, 0x7af1c6a6, -0x0fc5cf2b, 0x6345fa78 }\n    },\n    {\n        { -0x42270f5c, -0x6c2c3417, -0x02e88cfe, -0x24ead3e5, 0x7f17a875, 0x7dbddc6d, -0x70bd9102, 0x3e1a71cc },\n        { 0x1015e7a1, -0x20fd06a1, -0x564bfd9d, 0x790ec41d, 0x33ea1107, 0x4d3a0ea1, -0x1cc50737, 0x54f70be7 },\n        { -0x6f45429e, -0x37c35c1d, 0x0291c833, -0x7f121c99, -0x2c86ff3c, -0x377fc734, 0x1ec31fa1, 0x2c5fc023 }\n    },\n    {\n        { 0x02456e65, -0x3bdd1b2f, -0x352b846f, -0x78beb53f, -0x5d490023, 0x1592e2bb, -0x0a3deff1, 0x75d9d2bf },\n        { 0x17038b4f, -0x01456ee9, -0x3621107f, -0x1aedc8df, 0x5d0d8834, 0x1c97e4e7, 0x23dc3bc6, 0x68afae7a },\n        { 0x3626e81c, 0x5bd9b476, -0x435fd123, -0x766996ca, 0x61f077b3, 0x0a41193d, 0x00ce5471, 0x3097a242 }\n    },\n    {\n        { 0x6695c486, -0x5e9d18dc, 0x35a89607, 0x131d6334, -0x5f2ed5c9, 0x30521561, -0x59504c9d, 0x56704bad },\n        { -0x380747b4, 0x57427734, 0x01b270e9, -0x0ebe5ec2, -0x4b1a9b5a, 0x02d1adfe, -0x317c42b8, 0x4bb23d92 },\n        { 0x52f912b9, -0x5093b559, -0x27988f38, 0x5e665f6c, -0x5c3732a8, 0x4c35ac83, 0x10a58a7e, 0x2b7a29c0 }\n    },\n    {\n        { -0x40fff792, 0x33810a23, -0x18c90084, -0x50316da2, -0x1db6dd2c, 0x3d60e670, 0x4f96061b, 0x11ce9e71 },\n        { -0x2f3e313d, -0x3bff8089, -0x453b6d08, -0x72efdf4a, 0x7e69daaf, 0x32ec29d5, -0x626a0320, 0x59940875 },\n        { -0x27ea453f, 0x219ef713, 0x485be25c, -0x0ebeb9a3, 0x4e513c51, 0x6d5447cc, 0x5ef44393, 0x174926be }\n    },\n    {\n        { -0x6c15fdd2, 0x3ef5d415, 0x0ed0eed6, 0x5cbcc1a2, 0x07382c8c, -0x702db131, 0x06d8e1ad, 0x6fa42ead },\n        { -0x03a42a45, -0x4a214d07, -0x1e27ef1f, -0x6d2558d6, -0x48d5e3a7, -0x503b3024, 0x3fc22a24, 0x497d7881 },\n        { 0x1f73371f, -0x1d897db6, 0x4f5b6736, 0x7f7cf01c, 0x04fa46e7, 0x7e201fe3, 0x57808c96, 0x785a36a3 }\n    },\n    {\n        { 0x5d517bc3, 0x07044298, -0x519ac988, 0x6acd56c7, -0x67a5889d, 0x00a27983, -0x1aed99d5, 0x5167effa },\n        { 0x63014d2b, -0x7da04203, 0x6ca7578b, -0x37adc964, 0x5c0b5df0, 0x5b2fcd28, 0x58048c8f, 0x12ab214c },\n        { 0x0f53c4b6, -0x42b1561f, -0x7536e5ec, 0x1673dc5f, 0x2acc1aba, -0x5707e5b2, 0x24332a25, 0x33a92a79 }\n    },\n    {\n        { 0x218f2ada, 0x7ba95ba0, 0x330fb9ca, -0x300bdd79, 0x56c6d907, -0x2525b693, -0x0b4111ac, 0x5380c296 },\n        { 0x27996c02, -0x622e0b67, -0x1fb2e8ae, 0x0cb3b058, 0x7fd02c3e, 0x1f7e8896, -0x3474c14f, 0x2f964268 },\n        { 0x66898d0a, -0x62b0d8fc, 0x0aff3f7a, 0x3d098799, 0x67daba45, -0x2f610c9e, 0x7b1c669c, 0x7761455e }\n    },\n},\n};\n#elif defined(CURVED25519_128BIT)\nstatic const ge_precomp base[32][8] = {\n{\n    {\n        { 0x493c6f58c3b85, 0x0df7181c325f7, 0x0f50b0b3e4cb7, 0x5329385a44c32, 0x07cf9d3a33d4b },\n        { 0x03905d740913e, 0x0ba2817d673a2, 0x23e2827f4e67c, 0x133d2e0c21a34, 0x44fd2f9298f81 },\n        { 0x11205877aaa68, 0x479955893d579, 0x50d66309b67a0, 0x2d42d0dbee5ee, 0x6f117b689f0c6 },\n    },\n    {\n        { 0x4e7fc933c71d7, 0x2cf41feb6b244, 0x7581c0a7d1a76, 0x7172d534d32f0, 0x590c063fa87d2 },\n        { 0x1a56042b4d5a8, 0x189cc159ed153, 0x5b8deaa3cae04, 0x2aaf04f11b5d8, 0x6bb595a669c92 },\n        { 0x2a8b3a59b7a5f, 0x3abb359ef087f, 0x4f5a8c4db05af, 0x5b9a807d04205, 0x701af5b13ea50 },\n    },\n    {\n        { 0x5b0a84cee9730, 0x61d10c97155e4, 0x4059cc8096a10, 0x47a608da8014f, 0x7a164e1b9a80f },\n        { 0x11fe8a4fcd265, 0x7bcb8374faacc, 0x52f5af4ef4d4f, 0x5314098f98d10, 0x2ab91587555bd },\n        { 0x6933f0dd0d889, 0x44386bb4c4295, 0x3cb6d3162508c, 0x26368b872a2c6, 0x5a2826af12b9b },\n    },\n    {\n        { 0x351b98efc099f, 0x68fbfa4a7050e, 0x42a49959d971b, 0x393e51a469efd, 0x680e910321e58 },\n        { 0x6050a056818bf, 0x62acc1f5532bf, 0x28141ccc9fa25, 0x24d61f471e683, 0x27933f4c7445a },\n        { 0x3fbe9c476ff09, 0x0af6b982e4b42, 0x0ad1251ba78e5, 0x715aeedee7c88, 0x7f9d0cbf63553 },\n    },\n    {\n        { 0x2bc4408a5bb33, 0x078ebdda05442, 0x2ffb112354123, 0x375ee8df5862d, 0x2945ccf146e20 },\n        { 0x182c3a447d6ba, 0x22964e536eff2, 0x192821f540053, 0x2f9f19e788e5c, 0x154a7e73eb1b5 },\n        { 0x3dbf1812a8285, 0x0fa17ba3f9797, 0x6f69cb49c3820, 0x34d5a0db3858d, 0x43aabe696b3bb },\n    },\n    {\n        { 0x4eeeb77157131, 0x1201915f10741, 0x1669cda6c9c56, 0x45ec032db346d, 0x51e57bb6a2cc3 },\n        { 0x006b67b7d8ca4, 0x084fa44e72933, 0x1154ee55d6f8a, 0x4425d842e7390, 0x38b64c41ae417 },\n        { 0x4326702ea4b71, 0x06834376030b5, 0x0ef0512f9c380, 0x0f1a9f2512584, 0x10b8e91a9f0d6 },\n    },\n    {\n        { 0x25cd0944ea3bf, 0x75673b81a4d63, 0x150b925d1c0d4, 0x13f38d9294114, 0x461bea69283c9 },\n        { 0x72c9aaa3221b1, 0x267774474f74d, 0x064b0e9b28085, 0x3f04ef53b27c9, 0x1d6edd5d2e531 },\n        { 0x36dc801b8b3a2, 0x0e0a7d4935e30, 0x1deb7cecc0d7d, 0x053a94e20dd2c, 0x7a9fbb1c6a0f9 },\n    },\n    {\n        { 0x7596604dd3e8f, 0x6fc510e058b36, 0x3670c8db2cc0d, 0x297d899ce332f, 0x0915e76061bce },\n        { 0x75dedf39234d9, 0x01c36ab1f3c54, 0x0f08fee58f5da, 0x0e19613a0d637, 0x3a9024a1320e0 },\n        { 0x1f5d9c9a2911a, 0x7117994fafcf8, 0x2d8a8cae28dc5, 0x74ab1b2090c87, 0x26907c5c2ecc4 },\n    },\n},\n{\n    {\n        { 0x4dd0e632f9c1d, 0x2ced12622a5d9, 0x18de9614742da, 0x79ca96fdbb5d4, 0x6dd37d49a00ee },\n        { 0x3635449aa515e, 0x3e178d0475dab, 0x50b4712a19712, 0x2dcc2860ff4ad, 0x30d76d6f03d31 },\n        { 0x444172106e4c7, 0x01251afed2d88, 0x534fc9bed4f5a, 0x5d85a39cf5234, 0x10c697112e864 },\n    },\n    {\n        { 0x62aa08358c805, 0x46f440848e194, 0x447b771a8f52b, 0x377ba3269d31d, 0x03bf9baf55080 },\n        { 0x3c4277dbe5fde, 0x5a335afd44c92, 0x0c1164099753e, 0x70487006fe423, 0x25e61cabed66f },\n        { 0x3e128cc586604, 0x5968b2e8fc7e2, 0x049a3d5bd61cf, 0x116505b1ef6e6, 0x566d78634586e },\n    },\n    {\n        { 0x54285c65a2fd0, 0x55e62ccf87420, 0x46bb961b19044, 0x1153405712039, 0x14fba5f34793b },\n        { 0x7a49f9cc10834, 0x2b513788a22c6, 0x5ff4b6ef2395b, 0x2ec8e5af607bf, 0x33975bca5ecc3 },\n        { 0x746166985f7d4, 0x09939000ae79a, 0x5844c7964f97a, 0x13617e1f95b3d, 0x14829cea83fc5 },\n    },\n    {\n        { 0x70b2f4e71ecb8, 0x728148efc643c, 0x0753e03995b76, 0x5bf5fb2ab6767, 0x05fc3bc4535d7 },\n        { 0x37b8497dd95c2, 0x61549d6b4ffe8, 0x217a22db1d138, 0x0b9cf062eb09e, 0x2fd9c71e5f758 },\n        { 0x0b3ae52afdedd, 0x19da76619e497, 0x6fa0654d2558e, 0x78219d25e41d4, 0x373767475c651 },\n    },\n    {\n        { 0x095cb14246590, 0x002d82aa6ac68, 0x442f183bc4851, 0x6464f1c0a0644, 0x6bf5905730907 },\n        { 0x299fd40d1add9, 0x5f2de9a04e5f7, 0x7c0eebacc1c59, 0x4cca1b1f8290a, 0x1fbea56c3b18f },\n        { 0x778f1e1415b8a, 0x6f75874efc1f4, 0x28a694019027f, 0x52b37a96bdc4d, 0x02521cf67a635 },\n    },\n    {\n        { 0x46720772f5ee4, 0x632c0f359d622, 0x2b2092ba3e252, 0x662257c112680, 0x001753d9f7cd6 },\n        { 0x7ee0b0a9d5294, 0x381fbeb4cca27, 0x7841f3a3e639d, 0x676ea30c3445f, 0x3fa00a7e71382 },\n        { 0x1232d963ddb34, 0x35692e70b078d, 0x247ca14777a1f, 0x6db556be8fcd0, 0x12b5fe2fa048e },\n    },\n    {\n        { 0x37c26ad6f1e92, 0x46a0971227be5, 0x4722f0d2d9b4c, 0x3dc46204ee03a, 0x6f7e93c20796c },\n        { 0x0fbc496fce34d, 0x575be6b7dae3e, 0x4a31585cee609, 0x037e9023930ff, 0x749b76f96fb12 },\n        { 0x2f604aea6ae05, 0x637dc939323eb, 0x3fdad9b048d47, 0x0a8b0d4045af7, 0x0fcec10f01e02 },\n    },\n    {\n        { 0x2d29dc4244e45, 0x6927b1bc147be, 0x0308534ac0839, 0x4853664033f41, 0x413779166feab },\n        { 0x558a649fe1e44, 0x44635aeefcc89, 0x1ff434887f2ba, 0x0f981220e2d44, 0x4901aa7183c51 },\n        { 0x1b7548c1af8f0, 0x7848c53368116, 0x01b64e7383de9, 0x109fbb0587c8f, 0x41bb887b726d1 },\n    },\n},\n{\n    {\n        { 0x34c597c6691ae, 0x7a150b6990fc4, 0x52beb9d922274, 0x70eed7164861a, 0x0a871e070c6a9 },\n        { 0x07d44744346be, 0x282b6a564a81d, 0x4ed80f875236b, 0x6fbbe1d450c50, 0x4eb728c12fcdb },\n        { 0x1b5994bbc8989, 0x74b7ba84c0660, 0x75678f1cdaeb8, 0x23206b0d6f10c, 0x3ee7300f2685d },\n    },\n    {\n        { 0x27947841e7518, 0x32c7388dae87f, 0x414add3971be9, 0x01850832f0ef1, 0x7d47c6a2cfb89 },\n        { 0x255e49e7dd6b7, 0x38c2163d59eba, 0x3861f2a005845, 0x2e11e4ccbaec9, 0x1381576297912 },\n        { 0x2d0148ef0d6e0, 0x3522a8de787fb, 0x2ee055e74f9d2, 0x64038f6310813, 0x148cf58d34c9e },\n    },\n    {\n        { 0x72f7d9ae4756d, 0x7711e690ffc4a, 0x582a2355b0d16, 0x0dccfe885b6b4, 0x278febad4eaea },\n        { 0x492f67934f027, 0x7ded0815528d4, 0x58461511a6612, 0x5ea2e50de1544, 0x3ff2fa1ebd5db },\n        { 0x2681f8c933966, 0x3840521931635, 0x674f14a308652, 0x3bd9c88a94890, 0x4104dd02fe9c6 },\n    },\n    {\n        { 0x14e06db096ab8, 0x1219c89e6b024, 0x278abd486a2db, 0x240b292609520, 0x0165b5a48efca },\n        { 0x2bf5e1124422a, 0x673146756ae56, 0x14ad99a87e830, 0x1eaca65b080fd, 0x2c863b00afaf5 },\n        { 0x0a474a0846a76, 0x099a5ef981e32, 0x2a8ae3c4bbfe6, 0x45c34af14832c, 0x591b67d9bffec },\n    },\n    {\n        { 0x1b3719f18b55d, 0x754318c83d337, 0x27c17b7919797, 0x145b084089b61, 0x489b4f8670301 },\n        { 0x70d1c80b49bfa, 0x3d57e7d914625, 0x3c0722165e545, 0x5e5b93819e04f, 0x3de02ec7ca8f7 },\n        { 0x2102d3aeb92ef, 0x68c22d50c3a46, 0x42ea89385894e, 0x75f9ebf55f38c, 0x49f5fbba496cb },\n    },\n    {\n        { 0x5628c1e9c572e, 0x598b108e822ab, 0x55d8fae29361a, 0x0adc8d1a97b28, 0x06a1a6c288675 },\n        { 0x49a108a5bcfd4, 0x6178c8e7d6612, 0x1f03473710375, 0x73a49614a6098, 0x5604a86dcbfa6 },\n        { 0x0d1d47c1764b6, 0x01c08316a2e51, 0x2b3db45c95045, 0x1634f818d300c, 0x20989e89fe274 },\n    },\n    {\n        { 0x4278b85eaec2e, 0x0ef59657be2ce, 0x72fd169588770, 0x2e9b205260b30, 0x730b9950f7059 },\n        { 0x777fd3a2dcc7f, 0x594a9fb124932, 0x01f8e80ca15f0, 0x714d13cec3269, 0x0403ed1d0ca67 },\n        { 0x32d35874ec552, 0x1f3048df1b929, 0x300d73b179b23, 0x6e67be5a37d0b, 0x5bd7454308303 },\n    },\n    {\n        { 0x4932115e7792a, 0x457b9bbb930b8, 0x68f5d8b193226, 0x4164e8f1ed456, 0x5bb7db123067f },\n        { 0x2d19528b24cc2, 0x4ac66b8302ff3, 0x701c8d9fdad51, 0x6c1b35c5b3727, 0x133a78007380a },\n        { 0x1f467c6ca62be, 0x2c4232a5dc12c, 0x7551dc013b087, 0x0690c11b03bcd, 0x740dca6d58f0e },\n    },\n},\n{\n    {\n        { 0x28c570478433c, 0x1d8502873a463, 0x7641e7eded49c, 0x1ecedd54cf571, 0x2c03f5256c2b0 },\n        { 0x0ee0752cfce4e, 0x660dd8116fbe9, 0x55167130fffeb, 0x1c682b885955c, 0x161d25fa963ea },\n        { 0x718757b53a47d, 0x619e18b0f2f21, 0x5fbdfe4c1ec04, 0x5d798c81ebb92, 0x699468bdbd96b },\n    },\n    {\n        { 0x53de66aa91948, 0x045f81a599b1b, 0x3f7a8bd214193, 0x71d4da412331a, 0x293e1c4e6c4a2 },\n        { 0x72f46f4dafecf, 0x2948ffadef7a3, 0x11ecdfdf3bc04, 0x3c2e98ffeed25, 0x525219a473905 },\n        { 0x6134b925112e1, 0x6bb942bb406ed, 0x070c445c0dde2, 0x411d822c4d7a3, 0x5b605c447f032 },\n    },\n    {\n        { 0x1fec6f0e7f04c, 0x3cebc692c477d, 0x077986a19a95e, 0x6eaaaa1778b0f, 0x2f12fef4cc5ab },\n        { 0x5805920c47c89, 0x1924771f9972c, 0x38bbddf9fc040, 0x1f7000092b281, 0x24a76dcea8aeb },\n        { 0x522b2dfc0c740, 0x7e8193480e148, 0x33fd9a04341b9, 0x3c863678a20bc, 0x5e607b2518a43 },\n    },\n    {\n        { 0x4431ca596cf14, 0x015da7c801405, 0x03c9b6f8f10b5, 0x0346922934017, 0x201f33139e457 },\n        { 0x31d8f6cdf1818, 0x1f86c4b144b16, 0x39875b8d73e9d, 0x2fbf0d9ffa7b3, 0x5067acab6ccdd },\n        { 0x27f6b08039d51, 0x4802f8000dfaa, 0x09692a062c525, 0x1baea91075817, 0x397cba8862460 },\n    },\n    {\n        { 0x5c3fbc81379e7, 0x41bbc255e2f02, 0x6a3f756998650, 0x1297fd4e07c42, 0x771b4022c1e1c },\n        { 0x13093f05959b2, 0x1bd352f2ec618, 0x075789b88ea86, 0x61d1117ea48b9, 0x2339d320766e6 },\n        { 0x5d986513a2fa7, 0x63f3a99e11b0f, 0x28a0ecfd6b26d, 0x53b6835e18d8f, 0x331a189219971 },\n    },\n    {\n        { 0x12f3a9d7572af, 0x10d00e953c4ca, 0x603df116f2f8a, 0x33dc276e0e088, 0x1ac9619ff649a },\n        { 0x66f45fb4f80c6, 0x3cc38eeb9fea2, 0x107647270db1f, 0x710f1ea740dc8, 0x31167c6b83bdf },\n        { 0x33842524b1068, 0x77dd39d30fe45, 0x189432141a0d0, 0x088fe4eb8c225, 0x612436341f08b },\n    },\n    {\n        { 0x349e31a2d2638, 0x0137a7fa6b16c, 0x681ae92777edc, 0x222bfc5f8dc51, 0x1522aa3178d90 },\n        { 0x541db874e898d, 0x62d80fb841b33, 0x03e6ef027fa97, 0x7a03c9e9633e8, 0x46ebe2309e5ef },\n        { 0x02f5369614938, 0x356e5ada20587, 0x11bc89f6bf902, 0x036746419c8db, 0x45fe70f505243 },\n    },\n    {\n        { 0x24920c8951491, 0x107ec61944c5e, 0x72752e017c01f, 0x122b7dda2e97a, 0x16619f6db57a2 },\n        { 0x075a6960c0b8c, 0x6dde1c5e41b49, 0x42e3f516da341, 0x16a03fda8e79e, 0x428d1623a0e39 },\n        { 0x74a4401a308fd, 0x06ed4b9558109, 0x746f1f6a08867, 0x4636f5c6f2321, 0x1d81592d60bd3 },\n    },\n},\n{\n    {\n        { 0x5b69f7b85c5e8, 0x17a2d175650ec, 0x4cc3e6dbfc19e, 0x73e1d3873be0e, 0x3a5f6d51b0af8 },\n        { 0x68756a60dac5f, 0x55d757b8aec26, 0x3383df45f80bd, 0x6783f8c9f96a6, 0x20234a7789ecd },\n        { 0x20db67178b252, 0x73aa3da2c0eda, 0x79045c01c70d3, 0x1b37b15251059, 0x7cd682353cffe },\n    },\n    {\n        { 0x5cd6068acf4f3, 0x3079afc7a74cc, 0x58097650b64b4, 0x47fabac9c4e99, 0x3ef0253b2b2cd },\n        { 0x1a45bd887fab6, 0x65748076dc17c, 0x5b98000aa11a8, 0x4a1ecc9080974, 0x2838c8863bdc0 },\n        { 0x3b0cf4a465030, 0x022b8aef57a2d, 0x2ad0677e925ad, 0x4094167d7457a, 0x21dcb8a606a82 },\n    },\n    {\n        { 0x500fabe7731ba, 0x7cc53c3113351, 0x7cf65fe080d81, 0x3c5d966011ba1, 0x5d840dbf6c6f6 },\n        { 0x004468c9d9fc8, 0x5da8554796b8c, 0x3b8be70950025, 0x6d5892da6a609, 0x0bc3d08194a31 },\n        { 0x6380d309fe18b, 0x4d73c2cb8ee0d, 0x6b882adbac0b6, 0x36eabdddd4cbe, 0x3a4276232ac19 },\n    },\n    {\n        { 0x0c172db447ecb, 0x3f8c505b7a77f, 0x6a857f97f3f10, 0x4fcc0567fe03a, 0x0770c9e824e1a },\n        { 0x2432c8a7084fa, 0x47bf73ca8a968, 0x1639176262867, 0x5e8df4f8010ce, 0x1ff177cea16de },\n        { 0x1d99a45b5b5fd, 0x523674f2499ec, 0x0f8fa26182613, 0x58f7398048c98, 0x39f264fd41500 },\n    },\n    {\n        { 0x34aabfe097be1, 0x43bfc03253a33, 0x29bc7fe91b7f3, 0x0a761e4844a16, 0x65c621272c35f },\n        { 0x53417dbe7e29c, 0x54573827394f5, 0x565eea6f650dd, 0x42050748dc749, 0x1712d73468889 },\n        { 0x389f8ce3193dd, 0x2d424b8177ce5, 0x073fa0d3440cd, 0x139020cd49e97, 0x22f9800ab19ce },\n    },\n    {\n        { 0x29fdd9a6efdac, 0x7c694a9282840, 0x6f7cdeee44b3a, 0x55a3207b25cc3, 0x4171a4d38598c },\n        { 0x2368a3e9ef8cb, 0x454aa08e2ac0b, 0x490923f8fa700, 0x372aa9ea4582f, 0x13f416cd64762 },\n        { 0x758aa99c94c8c, 0x5f6001700ff44, 0x7694e488c01bd, 0x0d5fde948eed6, 0x508214fa574bd },\n    },\n    {\n        { 0x215bb53d003d6, 0x1179e792ca8c3, 0x1a0e96ac840a2, 0x22393e2bb3ab6, 0x3a7758a4c86cb },\n        { 0x269153ed6fe4b, 0x72a23aef89840, 0x052be5299699c, 0x3a5e5ef132316, 0x22f960ec6faba },\n        { 0x111f693ae5076, 0x3e3bfaa94ca90, 0x445799476b887, 0x24a0912464879, 0x5d9fd15f8de7f },\n    },\n    {\n        { 0x44d2aeed7521e, 0x50865d2c2a7e4, 0x2705b5238ea40, 0x46c70b25d3b97, 0x3bc187fa47eb9 },\n        { 0x408d36d63727f, 0x5faf8f6a66062, 0x2bb892da8de6b, 0x769d4f0c7e2e6, 0x332f35914f8fb },\n        { 0x70115ea86c20c, 0x16d88da24ada8, 0x1980622662adf, 0x501ebbc195a9d, 0x450d81ce906fb },\n    },\n},\n{\n    {\n        { 0x4d8961cae743f, 0x6bdc38c7dba0e, 0x7d3b4a7e1b463, 0x0844bdee2adf3, 0x4cbad279663ab },\n        { 0x3b6a1a6205275, 0x2e82791d06dcf, 0x23d72caa93c87, 0x5f0b7ab68aaf4, 0x2de25d4ba6345 },\n        { 0x19024a0d71fcd, 0x15f65115f101a, 0x4e99067149708, 0x119d8d1cba5af, 0x7d7fbcefe2007 },\n    },\n    {\n        { 0x45dc5f3c29094, 0x3455220b579af, 0x070c1631e068a, 0x26bc0630e9b21, 0x4f9cd196dcd8d },\n        { 0x71e6a266b2801, 0x09aae73e2df5d, 0x40dd8b219b1a3, 0x546fb4517de0d, 0x5975435e87b75 },\n        { 0x297d86a7b3768, 0x4835a2f4c6332, 0x070305f434160, 0x183dd014e56ae, 0x7ccdd084387a0 },\n    },\n    {\n        { 0x484186760cc93, 0x7435665533361, 0x02f686336b801, 0x5225446f64331, 0x3593ca848190c },\n        { 0x6422c6d260417, 0x212904817bb94, 0x5a319deb854f5, 0x7a9d4e060da7d, 0x428bd0ed61d0c },\n        { 0x3189a5e849aa7, 0x6acbb1f59b242, 0x7f6ef4753630c, 0x1f346292a2da9, 0x27398308da2d6 },\n    },\n    {\n        { 0x10e4c0a702453, 0x4daafa37bd734, 0x49f6bdc3e8961, 0x1feffdcecdae6, 0x572c2945492c3 },\n        { 0x38d28435ed413, 0x4064f19992858, 0x7680fbef543cd, 0x1aadd83d58d3c, 0x269597aebe8c3 },\n        { 0x7c745d6cd30be, 0x27c7755df78ef, 0x1776833937fa3, 0x5405116441855, 0x7f985498c05bc },\n    },\n    {\n        { 0x615520fbf6363, 0x0b9e9bf74da6a, 0x4fe8308201169, 0x173f76127de43, 0x30f2653cd69b1 },\n        { 0x1ce889f0be117, 0x36f6a94510709, 0x7f248720016b4, 0x1821ed1e1cf91, 0x76c2ec470a31f },\n        { 0x0c938aac10c85, 0x41b64ed797141, 0x1beb1c1185e6d, 0x1ed5490600f07, 0x2f1273f159647 },\n    },\n    {\n        { 0x08bd755a70bc0, 0x49e3a885ce609, 0x16585881b5ad6, 0x3c27568d34f5e, 0x38ac1997edc5f },\n        { 0x1fc7c8ae01e11, 0x2094d5573e8e7, 0x5ca3cbbf549d2, 0x4f920ecc54143, 0x5d9e572ad85b6 },\n        { 0x6b517a751b13b, 0x0cfd370b180cc, 0x5377925d1f41a, 0x34e56566008a2, 0x22dfcd9cbfe9e },\n    },\n    {\n        { 0x459b4103be0a1, 0x59a4b3f2d2add, 0x7d734c8bb8eeb, 0x2393cbe594a09, 0x0fe9877824cde },\n        { 0x3d2e0c30d0cd9, 0x3f597686671bb, 0x0aa587eb63999, 0x0e3c7b592c619, 0x6b2916c05448c },\n        { 0x334d10aba913b, 0x045cdb581cfdb, 0x5e3e0553a8f36, 0x50bb3041effb2, 0x4c303f307ff00 },\n    },\n    {\n        { 0x403580dd94500, 0x48df77d92653f, 0x38a9fe3b349ea, 0x0ea89850aafe1, 0x416b151ab706a },\n        { 0x23bd617b28c85, 0x6e72ee77d5a61, 0x1a972ff174dde, 0x3e2636373c60f, 0x0d61b8f78b2ab },\n        { 0x0d7efe9c136b0, 0x1ab1c89640ad5, 0x55f82aef41f97, 0x46957f317ed0d, 0x191a2af74277e },\n    },\n},\n{\n    {\n        { 0x62b434f460efb, 0x294c6c0fad3fc, 0x68368937b4c0f, 0x5c9f82910875b, 0x237e7dbe00545 },\n        { 0x6f74bc53c1431, 0x1c40e5dbbd9c2, 0x6c8fb9cae5c97, 0x4845c5ce1b7da, 0x7e2e0e450b5cc },\n        { 0x575ed6701b430, 0x4d3e17fa20026, 0x791fc888c4253, 0x2f1ba99078ac1, 0x71afa699b1115 },\n    },\n    {\n        { 0x23c1c473b50d6, 0x3e7671de21d48, 0x326fa5547a1e8, 0x50e4dc25fafd9, 0x00731fbc78f89 },\n        { 0x66f9b3953b61d, 0x555f4283cccb9, 0x7dd67fb1960e7, 0x14707a1affed4, 0x021142e9c2b1c },\n        { 0x0c71848f81880, 0x44bd9d8233c86, 0x6e8578efe5830, 0x4045b6d7041b5, 0x4c4d6f3347e15 },\n    },\n    {\n        { 0x4ddfc988f1970, 0x4f6173ea365e1, 0x645daf9ae4588, 0x7d43763db623b, 0x38bf9500a88f9 },\n        { 0x7eccfc17d1fc9, 0x4ca280782831e, 0x7b8337db1d7d6, 0x5116def3895fb, 0x193fddaaa7e47 },\n        { 0x2c93c37e8876f, 0x3431a28c583fa, 0x49049da8bd879, 0x4b4a8407ac11c, 0x6a6fb99ebf0d4 },\n    },\n    {\n        { 0x122b5b6e423c6, 0x21e50dff1ddd6, 0x73d76324e75c0, 0x588485495418e, 0x136fda9f42c5e },\n        { 0x6c1bb560855eb, 0x71f127e13ad48, 0x5c6b304905aec, 0x3756b8e889bc7, 0x75f76914a3189 },\n        { 0x4dfb1a305bdd1, 0x3b3ff05811f29, 0x6ed62283cd92e, 0x65d1543ec52e1, 0x022183510be8d },\n    },\n    {\n        { 0x2710143307a7f, 0x3d88fb48bf3ab, 0x249eb4ec18f7a, 0x136115dff295f, 0x1387c441fd404 },\n        { 0x766385ead2d14, 0x0194f8b06095e, 0x08478f6823b62, 0x6018689d37308, 0x6a071ce17b806 },\n        { 0x3c3d187978af8, 0x7afe1c88276ba, 0x51df281c8ad68, 0x64906bda4245d, 0x3171b26aaf1ed },\n    },\n    {\n        { 0x5b7d8b28a47d1, 0x2c2ee149e34c1, 0x776f5629afc53, 0x1f4ea50fc49a9, 0x6c514a6334424 },\n        { 0x7319097564ca8, 0x1844ebc233525, 0x21d4543fdeee1, 0x1ad27aaff1bd2, 0x221fd4873cf08 },\n        { 0x2204f3a156341, 0x537414065a464, 0x43c0c3bedcf83, 0x5557e706ea620, 0x48daa596fb924 },\n    },\n    {\n        { 0x61d5dc84c9793, 0x47de83040c29e, 0x189deb26507e7, 0x4d4e6fadc479a, 0x58c837fa0e8a7 },\n        { 0x28e665ca59cc7, 0x165c715940dd9, 0x0785f3aa11c95, 0x57b98d7e38469, 0x676dd6fccad84 },\n        { 0x1688596fc9058, 0x66f6ad403619f, 0x4d759a87772ef, 0x7856e6173bea4, 0x1c4f73f2c6a57 },\n    },\n    {\n        { 0x6706efc7c3484, 0x6987839ec366d, 0x0731f95cf7f26, 0x3ae758ebce4bc, 0x70459adb7daf6 },\n        { 0x24fbd305fa0bb, 0x40a98cc75a1cf, 0x78ce1220a7533, 0x6217a10e1c197, 0x795ac80d1bf64 },\n        { 0x1db4991b42bb3, 0x469605b994372, 0x631e3715c9a58, 0x7e9cfefcf728f, 0x5fe162848ce21 },\n    },\n},\n{\n    {\n        { 0x1852d5d7cb208, 0x60d0fbe5ce50f, 0x5a1e246e37b75, 0x51aee05ffd590, 0x2b44c043677da },\n        { 0x1214fe194961a, 0x0e1ae39a9e9cb, 0x543c8b526f9f7, 0x119498067e91d, 0x4789d446fc917 },\n        { 0x487ab074eb78e, 0x1d33b5e8ce343, 0x13e419feb1b46, 0x2721f565de6a4, 0x60c52eef2bb9a },\n    },\n    {\n        { 0x3c5c27cae6d11, 0x36a9491956e05, 0x124bac9131da6, 0x3b6f7de202b5d, 0x70d77248d9b66 },\n        { 0x589bc3bfd8bf1, 0x6f93e6aa3416b, 0x4c0a3d6c1ae48, 0x55587260b586a, 0x10bc9c312ccfc },\n        { 0x2e84b3ec2a05b, 0x69da2f03c1551, 0x23a174661a67b, 0x209bca289f238, 0x63755bd3a976f },\n    },\n    {\n        { 0x7101897f1acb7, 0x3d82cb77b07b8, 0x684083d7769f5, 0x52b28472dce07, 0x2763751737c52 },\n        { 0x7a03e2ad10853, 0x213dcc6ad36ab, 0x1a6e240d5bdd6, 0x7c24ffcf8fedf, 0x0d8cc1c48bc16 },\n        { 0x402d36eb419a9, 0x7cef68c14a052, 0x0f1255bc2d139, 0x373e7d431186a, 0x70c2dd8a7ad16 },\n    },\n    {\n        { 0x4967db8ed7e13, 0x15aeed02f523a, 0x6149591d094bc, 0x672f204c17006, 0x32b8613816a53 },\n        { 0x194509f6fec0e, 0x528d8ca31acac, 0x7826d73b8b9fa, 0x24acb99e0f9b3, 0x2e0fac6363948 },\n        { 0x7f7bee448cd64, 0x4e10f10da0f3c, 0x3936cb9ab20e9, 0x7a0fc4fea6cd0, 0x4179215c735a4 },\n    },\n    {\n        { 0x633b9286bcd34, 0x6cab3badb9c95, 0x74e387edfbdfa, 0x14313c58a0fd9, 0x31fa85662241c },\n        { 0x094e7d7dced2a, 0x068fa738e118e, 0x41b640a5fee2b, 0x6bb709df019d4, 0x700344a30cd99 },\n        { 0x26c422e3622f4, 0x0f3066a05b5f0, 0x4e2448f0480a6, 0x244cde0dbf095, 0x24bb2312a9952 },\n    },\n    {\n        { 0x00c2af5f85c6b, 0x0609f4cf2883f, 0x6e86eb5a1ca13, 0x68b44a2efccd1, 0x0d1d2af9ffeb5 },\n        { 0x0ed1732de67c3, 0x308c369291635, 0x33ef348f2d250, 0x004475ea1a1bb, 0x0fee3e871e188 },\n        { 0x28aa132621edf, 0x42b244caf353b, 0x66b064cc2e08a, 0x6bb20020cbdd3, 0x16acd79718531 },\n    },\n    {\n        { 0x1c6c57887b6ad, 0x5abf21fd7592b, 0x50bd41253867a, 0x3800b71273151, 0x164ed34b18161 },\n        { 0x772af2d9b1d3d, 0x6d486448b4e5b, 0x2ce58dd8d18a8, 0x1849f67503c8b, 0x123e0ef6b9302 },\n        { 0x6d94c192fe69a, 0x5475222a2690f, 0x693789d86b8b3, 0x1f5c3bdfb69dc, 0x78da0fc61073f },\n    },\n    {\n        { 0x780f1680c3a94, 0x2a35d3cfcd453, 0x005e5cdc7ddf8, 0x6ee888078ac24, 0x054aa4b316b38 },\n        { 0x15d28e52bc66a, 0x30e1e0351cb7e, 0x30a2f74b11f8c, 0x39d120cd7de03, 0x2d25deeb256b1 },\n        { 0x0468d19267cb8, 0x38cdca9b5fbf9, 0x1bbb05c2ca1e2, 0x3b015758e9533, 0x134610a6ab7da },\n    },\n},\n{\n    {\n        { 0x265e777d1f515, 0x0f1f54c1e39a5, 0x2f01b95522646, 0x4fdd8db9dde6d, 0x654878cba97cc },\n        { 0x38ec78df6b0fe, 0x13caebea36a22, 0x5ebc6e54e5f6a, 0x32804903d0eb8, 0x2102fdba2b20d },\n        { 0x6e405055ce6a1, 0x5024a35a532d3, 0x1f69054daf29d, 0x15d1d0d7a8bd5, 0x0ad725db29ecb },\n    },\n    {\n        { 0x7bc0c9b056f85, 0x51cfebffaffd8, 0x44abbe94df549, 0x7ecbbd7e33121, 0x4f675f5302399 },\n        { 0x267b1834e2457, 0x6ae19c378bb88, 0x7457b5ed9d512, 0x3280d783d05fb, 0x4aefcffb71a03 },\n        { 0x536360415171e, 0x2313309077865, 0x251444334afbc, 0x2b0c3853756e8, 0x0bccbb72a2a86 },\n    },\n    {\n        { 0x55e4c50fe1296, 0x05fdd13efc30d, 0x1c0c6c380e5ee, 0x3e11de3fb62a8, 0x6678fd69108f3 },\n        { 0x6962feab1a9c8, 0x6aca28fb9a30b, 0x56db7ca1b9f98, 0x39f58497018dd, 0x4024f0ab59d6b },\n        { 0x6fa31636863c2, 0x10ae5a67e42b0, 0x27abbf01fda31, 0x380a7b9e64fbc, 0x2d42e2108ead4 },\n    },\n    {\n        { 0x17b0d0f537593, 0x16263c0c9842e, 0x4ab827e4539a4, 0x6370ddb43d73a, 0x420bf3a79b423 },\n        { 0x5131594dfd29b, 0x3a627e98d52fe, 0x1154041855661, 0x19175d09f8384, 0x676b2608b8d2d },\n        { 0x0ba651c5b2b47, 0x5862363701027, 0x0c4d6c219c6db, 0x0f03dff8658de, 0x745d2ffa9c0cf },\n    },\n    {\n        { 0x6df5721d34e6a, 0x4f32f767a0c06, 0x1d5abeac76e20, 0x41ce9e104e1e4, 0x06e15be54c1dc },\n        { 0x25a1e2bc9c8bd, 0x104c8f3b037ea, 0x405576fa96c98, 0x2e86a88e3876f, 0x1ae23ceb960cf },\n        { 0x25d871932994a, 0x6b9d63b560b6e, 0x2df2814c8d472, 0x0fbbee20aa4ed, 0x58ded861278ec },\n    },\n    {\n        { 0x35ba8b6c2c9a8, 0x1dea58b3185bf, 0x4b455cd23bbbe, 0x5ec19c04883f8, 0x08ba696b531d5 },\n        { 0x73793f266c55c, 0x0b988a9c93b02, 0x09b0ea32325db, 0x37cae71c17c5e, 0x2ff39de85485f },\n        { 0x53eeec3efc57a, 0x2fa9fe9022efd, 0x699c72c138154, 0x72a751ebd1ff8, 0x120633b4947cf },\n    },\n    {\n        { 0x531474912100a, 0x5afcdf7c0d057, 0x7a9e71b788ded, 0x5ef708f3b0c88, 0x07433be3cb393 },\n        { 0x4987891610042, 0x79d9d7f5d0172, 0x3c293013b9ec4, 0x0c2b85f39caca, 0x35d30a99b4d59 },\n        { 0x144c05ce997f4, 0x4960b8a347fef, 0x1da11f15d74f7, 0x54fac19c0fead, 0x2d873ede7af6d },\n    },\n    {\n        { 0x202e14e5df981, 0x2ea02bc3eb54c, 0x38875b2883564, 0x1298c513ae9dd, 0x0543618a01600 },\n        { 0x2316443373409, 0x5de95503b22af, 0x699201beae2df, 0x3db5849ff737a, 0x2e773654707fa },\n        { 0x2bdf4974c23c1, 0x4b3b9c8d261bd, 0x26ae8b2a9bc28, 0x3068210165c51, 0x4b1443362d079 },\n    },\n},\n{\n    {\n        { 0x454e91c529ccb, 0x24c98c6bf72cf, 0x0486594c3d89a, 0x7ae13a3d7fa3c, 0x17038418eaf66 },\n        { 0x4b7c7b66e1f7a, 0x4bea185efd998, 0x4fabc711055f8, 0x1fb9f7836fe38, 0x582f446752da6 },\n        { 0x17bd320324ce4, 0x51489117898c6, 0x1684d92a0410b, 0x6e4d90f78c5a7, 0x0c2a1c4bcda28 },\n    },\n    {\n        { 0x4814869bd6945, 0x7b7c391a45db8, 0x57316ac35b641, 0x641e31de9096a, 0x5a6a9b30a314d },\n        { 0x5c7d06f1f0447, 0x7db70f80b3a49, 0x6cb4a3ec89a78, 0x43be8ad81397d, 0x7c558bd1c6f64 },\n        { 0x41524d396463d, 0x1586b449e1a1d, 0x2f17e904aed8a, 0x7e1d2861d3c8e, 0x0404a5ca0afba },\n    },\n    {\n        { 0x49e1b2a416fd1, 0x51c6a0b316c57, 0x575a59ed71bdc, 0x74c021a1fec1e, 0x39527516e7f8e },\n        { 0x740070aa743d6, 0x16b64cbdd1183, 0x23f4b7b32eb43, 0x319aba58235b3, 0x46395bfdcadd9 },\n        { 0x7db2d1a5d9a9c, 0x79a200b85422f, 0x355bfaa71dd16, 0x00b77ea5f78aa, 0x76579a29e822d },\n    },\n    {\n        { 0x4b51352b434f2, 0x1327bd01c2667, 0x434d73b60c8a1, 0x3e0daa89443ba, 0x02c514bb2a277 },\n        { 0x68e7e49c02a17, 0x45795346fe8b6, 0x089306c8f3546, 0x6d89f6b2f88f6, 0x43a384dc9e05b },\n        { 0x3d5da8bf1b645, 0x7ded6a96a6d09, 0x6c3494fee2f4d, 0x02c989c8b6bd4, 0x1160920961548 },\n    },\n    {\n        { 0x05616369b4dcd, 0x4ecab86ac6f47, 0x3c60085d700b2, 0x0213ee10dfcea, 0x2f637d7491e6e },\n        { 0x5166929dacfaa, 0x190826b31f689, 0x4f55567694a7d, 0x705f4f7b1e522, 0x351e125bc5698 },\n        { 0x49b461af67bbe, 0x75915712c3a96, 0x69a67ef580c0d, 0x54d38ef70cffc, 0x7f182d06e7ce2 },\n    },\n    {\n        { 0x54b728e217522, 0x69a90971b0128, 0x51a40f2a963a3, 0x10be9ac12a6bf, 0x44acc043241c5 },\n        { 0x48e64ab0168ec, 0x2a2bdb8a86f4f, 0x7343b6b2d6929, 0x1d804aa8ce9a3, 0x67d4ac8c343e9 },\n        { 0x56bbb4f7a5777, 0x29230627c238f, 0x5ad1a122cd7fb, 0x0dea56e50e364, 0x556d1c8312ad7 },\n    },\n    {\n        { 0x06756b11be821, 0x462147e7bb03e, 0x26519743ebfe0, 0x782fc59682ab5, 0x097abe38cc8c7 },\n        { 0x740e30c8d3982, 0x7c2b47f4682fd, 0x5cd91b8c7dc1c, 0x77fa790f9e583, 0x746c6c6d1d824 },\n        { 0x1c9877ea52da4, 0x2b37b83a86189, 0x733af49310da5, 0x25e81161c04fb, 0x577e14a34bee8 },\n    },\n    {\n        { 0x6cebebd4dd72b, 0x340c1e442329f, 0x32347ffd1a93f, 0x14a89252cbbe0, 0x705304b8fb009 },\n        { 0x268ac61a73b0a, 0x206f234bebe1c, 0x5b403a7cbebe8, 0x7a160f09f4135, 0x60fa7ee96fd78 },\n        { 0x51d354d296ec6, 0x7cbf5a63b16c7, 0x2f50bb3cf0c14, 0x1feb385cac65a, 0x21398e0ca1635 },\n    },\n},\n{\n    {\n        { 0x0aaf9b4b75601, 0x26b91b5ae44f3, 0x6de808d7ab1c8, 0x6a769675530b0, 0x1bbfb284e98f7 },\n        { 0x5058a382b33f3, 0x175a91816913e, 0x4f6cdb96b8ae8, 0x17347c9da81d2, 0x5aa3ed9d95a23 },\n        { 0x777e9c7d96561, 0x28e58f006ccac, 0x541bbbb2cac49, 0x3e63282994cec, 0x4a07e14e5e895 },\n    },\n    {\n        { 0x358cdc477a49b, 0x3cc88fe02e481, 0x721aab7f4e36b, 0x0408cc9469953, 0x50af7aed84afa },\n        { 0x412cb980df999, 0x5e78dd8ee29dc, 0x171dff68c575d, 0x2015dd2f6ef49, 0x3f0bac391d313 },\n        { 0x7de0115f65be5, 0x4242c21364dc9, 0x6b75b64a66098, 0x0033c0102c085, 0x1921a316baebd },\n    },\n    {\n        { 0x2ad9ad9f3c18b, 0x5ec1638339aeb, 0x5703b6559a83b, 0x3fa9f4d05d612, 0x7b049deca062c },\n        { 0x22f7edfb870fc, 0x569eed677b128, 0x30937dcb0a5af, 0x758039c78ea1b, 0x6458df41e273a },\n        { 0x3e37a35444483, 0x661fdb7d27b99, 0x317761dd621e4, 0x7323c30026189, 0x6093dccbc2950 },\n    },\n    {\n        { 0x6eebe6084034b, 0x6cf01f70a8d7b, 0x0b41a54c6670a, 0x6c84b99bb55db, 0x6e3180c98b647 },\n        { 0x39a8585e0706d, 0x3167ce72663fe, 0x63d14ecdb4297, 0x4be21dcf970b8, 0x57d1ea084827a },\n        { 0x2b6e7a128b071, 0x5b27511755dcf, 0x08584c2930565, 0x68c7bda6f4159, 0x363e999ddd97b },\n    },\n    {\n        { 0x048dce24baec6, 0x2b75795ec05e3, 0x3bfa4c5da6dc9, 0x1aac8659e371e, 0x231f979bc6f9b },\n        { 0x043c135ee1fc4, 0x2a11c9919f2d5, 0x6334cc25dbacd, 0x295da17b400da, 0x48ee9b78693a0 },\n        { 0x1de4bcc2af3c6, 0x61fc411a3eb86, 0x53ed19ac12ec0, 0x209dbc6b804e0, 0x079bfa9b08792 },\n    },\n    {\n        { 0x1ed80a2d54245, 0x70efec72a5e79, 0x42151d42a822d, 0x1b5ebb6d631e8, 0x1ef4fb1594706 },\n        { 0x03a51da300df4, 0x467b52b561c72, 0x4d5920210e590, 0x0ca769e789685, 0x038c77f684817 },\n        { 0x65ee65b167bec, 0x052da19b850a9, 0x0408665656429, 0x7ab39596f9a4c, 0x575ee92a4a0bf },\n    },\n    {\n        { 0x6bc450aa4d801, 0x4f4a6773b0ba8, 0x6241b0b0ebc48, 0x40d9c4f1d9315, 0x200a1e7e382f5 },\n        { 0x080908a182fcf, 0x0532913b7ba98, 0x3dccf78c385c3, 0x68002dd5eaba9, 0x43d4e7112cd3f },\n        { 0x5b967eaf93ac5, 0x360acca580a31, 0x1c65fd5c6f262, 0x71c7f15c2ecab, 0x050eca52651e4 },\n    },\n    {\n        { 0x4397660e668ea, 0x7c2a75692f2f5, 0x3b29e7e6c66ef, 0x72ba658bcda9a, 0x6151c09fa131a },\n        { 0x31ade453f0c9c, 0x3dfee07737868, 0x611ecf7a7d411, 0x2637e6cbd64f6, 0x4b0ee6c21c58f },\n        { 0x55c0dfdf05d96, 0x405569dcf475e, 0x05c5c277498bb, 0x18588d95dc389, 0x1fef24fa800f0 },\n    },\n},\n{\n    {\n        { 0x2aff530976b86, 0x0d85a48c0845a, 0x796eb963642e0, 0x60bee50c4b626, 0x28005fe6c8340 },\n        { 0x653fb1aa73196, 0x607faec8306fa, 0x4e85ec83e5254, 0x09f56900584fd, 0x544d49292fc86 },\n        { 0x7ba9f34528688, 0x284a20fb42d5d, 0x3652cd9706ffe, 0x6fd7baddde6b3, 0x72e472930f316 },\n    },\n    {\n        { 0x3f635d32a7627, 0x0cbecacde00fe, 0x3411141eaa936, 0x21c1e42f3cb94, 0x1fee7f000fe06 },\n        { 0x5208c9781084f, 0x16468a1dc24d2, 0x7bf780ac540a8, 0x1a67eced75301, 0x5a9d2e8c2733a },\n        { 0x305da03dbf7e5, 0x1228699b7aeca, 0x12a23b2936bc9, 0x2a1bda56ae6e9, 0x00f94051ee040 },\n    },\n    {\n        { 0x793bb07af9753, 0x1e7b6ecd4fafd, 0x02c7b1560fb43, 0x2296734cc5fb7, 0x47b7ffd25dd40 },\n        { 0x56b23c3d330b2, 0x37608e360d1a6, 0x10ae0f3c8722e, 0x086d9b618b637, 0x07d79c7e8beab },\n        { 0x3fb9cbc08dd12, 0x75c3dd85370ff, 0x47f06fe2819ac, 0x5db06ab9215ed, 0x1c3520a35ea64 },\n    },\n    {\n        { 0x06f40216bc059, 0x3a2579b0fd9b5, 0x71c26407eec8c, 0x72ada4ab54f0b, 0x38750c3b66d12 },\n        { 0x253a6bccba34a, 0x427070433701a, 0x20b8e58f9870e, 0x337c861db00cc, 0x1c3d05775d0ee },\n        { 0x6f1409422e51a, 0x7856bbece2d25, 0x13380a72f031c, 0x43e1080a7f3ba, 0x0621e2c7d3304 },\n    },\n    {\n        { 0x61796b0dbf0f3, 0x73c2f9c32d6f5, 0x6aa8ed1537ebe, 0x74e92c91838f4, 0x5d8e589ca1002 },\n        { 0x060cc8259838d, 0x038d3f35b95f3, 0x56078c243a923, 0x2de3293241bb2, 0x0007d6097bd3a },\n        { 0x71d950842a94b, 0x46b11e5c7d817, 0x5478bbecb4f0d, 0x7c3054b0a1c5d, 0x1583d7783c1cb },\n    },\n    {\n        { 0x34704cc9d28c7, 0x3dee598b1f200, 0x16e1c98746d9e, 0x4050b7095afdf, 0x4958064e83c55 },\n        { 0x6a2ef5da27ae1, 0x28aace02e9d9d, 0x02459e965f0e8, 0x7b864d3150933, 0x252a5f2e81ed8 },\n        { 0x094265066e80d, 0x0a60f918d61a5, 0x0444bf7f30fde, 0x1c40da9ed3c06, 0x079c170bd843b },\n    },\n    {\n        { 0x6cd50c0d5d056, 0x5b7606ae779ba, 0x70fbd226bdda1, 0x5661e53391ff9, 0x6768c0d7317b8 },\n        { 0x6ece464fa6fff, 0x3cc40bca460a0, 0x6e3a90afb8d0c, 0x5801abca11228, 0x6dec05e34ac9f },\n        { 0x625e5f155c1b3, 0x4f32f6f723296, 0x5ac980105efce, 0x17a61165eee36, 0x51445e14ddcd5 },\n    },\n    {\n        { 0x147ab2bbea455, 0x1f240f2253126, 0x0c3de9e314e89, 0x21ea5a4fca45f, 0x12e990086e4fd },\n        { 0x02b4b3b144951, 0x5688977966aea, 0x18e176e399ffd, 0x2e45c5eb4938b, 0x13186f31e3929 },\n        { 0x496b37fdfbb2e, 0x3c2439d5f3e21, 0x16e60fe7e6a4d, 0x4d7ef889b621d, 0x77b2e3f05d3e9 },\n    },\n},\n{\n    {\n        { 0x0639c12ddb0a4, 0x6180490cd7ab3, 0x3f3918297467c, 0x74568be1781ac, 0x07a195152e095 },\n        { 0x7a9c59c2ec4de, 0x7e9f09e79652d, 0x6a3e422f22d86, 0x2ae8e3b836c8b, 0x63b795fc7ad32 },\n        { 0x68f02389e5fc8, 0x059f1bc877506, 0x504990e410cec, 0x09bd7d0feaee2, 0x3e8fe83d032f0 },\n    },\n    {\n        { 0x04c8de8efd13c, 0x1c67c06e6210e, 0x183378f7f146a, 0x64352ceaed289, 0x22d60899a6258 },\n        { 0x315b90570a294, 0x60ce108a925f1, 0x6eff61253c909, 0x003ef0e2d70b0, 0x75ba3b797fac4 },\n        { 0x1dbc070cdd196, 0x16d8fb1534c47, 0x500498183fa2a, 0x72f59c423de75, 0x0904d07b87779 },\n    },\n    {\n        { 0x22d6648f940b9, 0x197a5a1873e86, 0x207e4c41a54bc, 0x5360b3b4bd6d0, 0x6240aacebaf72 },\n        { 0x61fd4ddba919c, 0x7d8e991b55699, 0x61b31473cc76c, 0x7039631e631d6, 0x43e2143fbc1dd },\n        { 0x4749c5ba295a0, 0x37946fa4b5f06, 0x724c5ab5a51f1, 0x65633789dd3f3, 0x56bdaf238db40 },\n    },\n    {\n        { 0x0d36cc19d3bb2, 0x6ec4470d72262, 0x6853d7018a9ae, 0x3aa3e4dc2c8eb, 0x03aa31507e1e5 },\n        { 0x2b9e3f53533eb, 0x2add727a806c5, 0x56955c8ce15a3, 0x18c4f070a290e, 0x1d24a86d83741 },\n        { 0x47648ffd4ce1f, 0x60a9591839e9d, 0x424d5f38117ab, 0x42cc46912c10e, 0x43b261dc9aeb4 },\n    },\n    {\n        { 0x13d8b6c951364, 0x4c0017e8f632a, 0x53e559e53f9c4, 0x4b20146886eea, 0x02b4d5e242940 },\n        { 0x31e1988bb79bb, 0x7b82f46b3bcab, 0x0f7a8ce827b41, 0x5e15816177130, 0x326055cf5b276 },\n        { 0x155cb28d18df2, 0x0c30d9ca11694, 0x2090e27ab3119, 0x208624e7a49b6, 0x27a6c809ae5d3 },\n    },\n    {\n        { 0x4270ac43d6954, 0x2ed4cd95659a5, 0x75c0db37528f9, 0x2ccbcfd2c9234, 0x221503603d8c2 },\n        { 0x6ebcd1f0db188, 0x74ceb4b7d1174, 0x7d56168df4f5c, 0x0bf79176fd18a, 0x2cb67174ff60a },\n        { 0x6cdf9390be1d0, 0x08e519c7e2b3d, 0x253c3d2a50881, 0x21b41448e333d, 0x7b1df4b73890f },\n    },\n    {\n        { 0x6221807f8f58c, 0x3fa92813a8be5, 0x6da98c38d5572, 0x01ed95554468f, 0x68698245d352e },\n        { 0x2f2e0b3b2a224, 0x0c56aa22c1c92, 0x5fdec39f1b278, 0x4c90af5c7f106, 0x61fcef2658fc5 },\n        { 0x15d852a18187a, 0x270dbb59afb76, 0x7db120bcf92ab, 0x0e7a25d714087, 0x46cf4c473daf0 },\n    },\n    {\n        { 0x46ea7f1498140, 0x70725690a8427, 0x0a73ae9f079fb, 0x2dd924461c62b, 0x1065aae50d8cc },\n        { 0x525ed9ec4e5f9, 0x022d20660684c, 0x7972b70397b68, 0x7a03958d3f965, 0x29387bcd14eb5 },\n        { 0x44525df200d57, 0x2d7f94ce94385, 0x60d00c170ecb7, 0x38b0503f3d8f0, 0x69a198e64f1ce },\n    },\n},\n{\n    {\n        { 0x14434dcc5caed, 0x2c7909f667c20, 0x61a839d1fb576, 0x4f23800cabb76, 0x25b2697bd267f },\n        { 0x2b2e0d91a78bc, 0x3990a12ccf20c, 0x141c2e11f2622, 0x0dfcefaa53320, 0x7369e6a92493a },\n        { 0x73ffb13986864, 0x3282bb8f713ac, 0x49ced78f297ef, 0x6697027661def, 0x1420683db54e4 },\n    },\n    {\n        { 0x6bb6fc1cc5ad0, 0x532c8d591669d, 0x1af794da86c33, 0x0e0e9d86d24d3, 0x31e83b4161d08 },\n        { 0x0bd1e249dd197, 0x00bcb1820568f, 0x2eab1718830d4, 0x396fd816997e6, 0x60b63bebf508a },\n        { 0x0c7129e062b4f, 0x1e526415b12fd, 0x461a0fd27923d, 0x18badf670a5b7, 0x55cf1eb62d550 },\n    },\n    {\n        { 0x6b5e37df58c52, 0x3bcf33986c60e, 0x44fb8835ceae7, 0x099dec18e71a4, 0x1a56fbaa62ba0 },\n        { 0x1101065c23d58, 0x5aa1290338b0f, 0x3157e9e2e7421, 0x0ea712017d489, 0x669a656457089 },\n        { 0x66b505c9dc9ec, 0x774ef86e35287, 0x4d1d944c0955e, 0x52e4c39d72b20, 0x13c4836799c58 },\n    },\n    {\n        { 0x4fb6a5d8bd080, 0x58ae34908589b, 0x3954d977baf13, 0x413ea597441dc, 0x50bdc87dc8e5b },\n        { 0x25d465ab3e1b9, 0x0f8fe27ec2847, 0x2d6e6dbf04f06, 0x3038cfc1b3276, 0x66f80c93a637b },\n        { 0x537836edfe111, 0x2be02357b2c0d, 0x6dcee58c8d4f8, 0x2d732581d6192, 0x1dd56444725fd },\n    },\n    {\n        { 0x7e60008bac89a, 0x23d5c387c1852, 0x79e5df1f533a8, 0x2e6f9f1c5f0cf, 0x3a3a450f63a30 },\n        { 0x47ff83362127d, 0x08e39af82b1f4, 0x488322ef27dab, 0x1973738a2a1a4, 0x0e645912219f7 },\n        { 0x72f31d8394627, 0x07bd294a200f1, 0x665be00e274c6, 0x43de8f1b6368b, 0x318c8d9393a9a },\n    },\n    {\n        { 0x69e29ab1dd398, 0x30685b3c76bac, 0x565cf37f24859, 0x57b2ac28efef9, 0x509a41c325950 },\n        { 0x45d032afffe19, 0x12fe49b6cde4e, 0x21663bc327cf1, 0x18a5e4c69f1dd, 0x224c7c679a1d5 },\n        { 0x06edca6f925e9, 0x68c8363e677b8, 0x60cfa25e4fbcf, 0x1c4c17609404e, 0x05bff02328a11 },\n    },\n    {\n        { 0x1a0dd0dc512e4, 0x10894bf5fcd10, 0x52949013f9c37, 0x1f50fba4735c7, 0x576277cdee01a },\n        { 0x2137023cae00b, 0x15a3599eb26c6, 0x0687221512b3c, 0x253cb3a0824e9, 0x780b8cc3fa2a4 },\n        { 0x38abc234f305f, 0x7a280bbc103de, 0x398a836695dfe, 0x3d0af41528a1a, 0x5ff418726271b },\n    },\n    {\n        { 0x347e813b69540, 0x76864c21c3cbb, 0x1e049dbcd74a8, 0x5b4d60f93749c, 0x29d4db8ca0a0c },\n        { 0x6080c1789db9d, 0x4be7cef1ea731, 0x2f40d769d8080, 0x35f7d4c44a603, 0x106a03dc25a96 },\n        { 0x50aaf333353d0, 0x4b59a613cbb35, 0x223dfc0e19a76, 0x77d1e2bb2c564, 0x4ab38a51052cb },\n    },\n},\n{\n    {\n        { 0x7d1ef5fddc09c, 0x7beeaebb9dad9, 0x058d30ba0acfb, 0x5cd92eab5ae90, 0x3041c6bb04ed2 },\n        { 0x42b256768d593, 0x2e88459427b4f, 0x02b3876630701, 0x34878d405eae5, 0x29cdd1adc088a },\n        { 0x2f2f9d956e148, 0x6b3e6ad65c1fe, 0x5b00972b79e5d, 0x53d8d234c5daf, 0x104bbd6814049 },\n    },\n    {\n        { 0x59a5fd67ff163, 0x3a998ead0352b, 0x083c95fa4af9a, 0x6fadbfc01266f, 0x204f2a20fb072 },\n        { 0x0fd3168f1ed67, 0x1bb0de7784a3e, 0x34bcb78b20477, 0x0a4a26e2e2182, 0x5be8cc57092a7 },\n        { 0x43b3d30ebb079, 0x357aca5c61902, 0x5b570c5d62455, 0x30fb29e1e18c7, 0x2570fb17c2791 },\n    },\n    {\n        { 0x6a9550bb8245a, 0x511f20a1a2325, 0x29324d7239bee, 0x3343cc37516c4, 0x241c5f91de018 },\n        { 0x2367f2cb61575, 0x6c39ac04d87df, 0x6d4958bd7e5bd, 0x566f4638a1532, 0x3dcb65ea53030 },\n        { 0x0172940de6caa, 0x6045b2e67451b, 0x56c07463efcb3, 0x0728b6bfe6e91, 0x08420edd5fcdf },\n    },\n    {\n        { 0x0c34e04f410ce, 0x344edc0d0a06b, 0x6e45486d84d6d, 0x44e2ecb3863f5, 0x04d654f321db8 },\n        { 0x720ab8362fa4a, 0x29c4347cdd9bf, 0x0e798ad5f8463, 0x4fef18bcb0bfe, 0x0d9a53efbc176 },\n        { 0x5c116ddbdb5d5, 0x6d1b4bba5abcf, 0x4d28a48a5537a, 0x56b8e5b040b99, 0x4a7a4f2618991 },\n    },\n    {\n        { 0x3b291af372a4b, 0x60e3028fe4498, 0x2267bca4f6a09, 0x719eec242b243, 0x4a96314223e0e },\n        { 0x718025fb15f95, 0x68d6b8371fe94, 0x3804448f7d97c, 0x42466fe784280, 0x11b50c4cddd31 },\n        { 0x0274408a4ffd6, 0x7d382aedb34dd, 0x40acfc9ce385d, 0x628bb99a45b1e, 0x4f4bce4dce6bc },\n    },\n    {\n        { 0x2616ec49d0b6f, 0x1f95d8462e61c, 0x1ad3e9b9159c6, 0x79ba475a04df9, 0x3042cee561595 },\n        { 0x7ce5ae2242584, 0x2d25eb153d4e3, 0x3a8f3d09ba9c9, 0x0f3690d04eb8e, 0x73fcdd14b71c0 },\n        { 0x67079449bac41, 0x5b79c4621484f, 0x61069f2156b8d, 0x0eb26573b10af, 0x389e740c9a9ce },\n    },\n    {\n        { 0x578f6570eac28, 0x644f2339c3937, 0x66e47b7956c2c, 0x34832fe1f55d0, 0x25c425e5d6263 },\n        { 0x4b3ae34dcb9ce, 0x47c691a15ac9f, 0x318e06e5d400c, 0x3c422d9f83eb1, 0x61545379465a6 },\n        { 0x606a6f1d7de6e, 0x4f1c0c46107e7, 0x229b1dcfbe5d8, 0x3acc60a7b1327, 0x6539a08915484 },\n    },\n    {\n        { 0x4dbd414bb4a19, 0x7930849f1dbb8, 0x329c5a466caf0, 0x6c824544feb9b, 0x0f65320ef019b },\n        { 0x21f74c3d2f773, 0x024b88d08bd3a, 0x6e678cf054151, 0x43631272e747c, 0x11c5e4aac5cd1 },\n        { 0x6d1b1cafde0c6, 0x462c76a303a90, 0x3ca4e693cff9b, 0x3952cd45786fd, 0x4cabc7bdec330 },\n    },\n},\n{\n    {\n        { 0x7788f3f78d289, 0x5942809b3f811, 0x5973277f8c29c, 0x010f93bc5fe67, 0x7ee498165acb2 },\n        { 0x69624089c0a2e, 0x0075fc8e70473, 0x13e84ab1d2313, 0x2c10bedf6953b, 0x639b93f0321c8 },\n        { 0x508e39111a1c3, 0x290120e912f7a, 0x1cbf464acae43, 0x15373e9576157, 0x0edf493c85b60 },\n    },\n    {\n        { 0x7c4d284764113, 0x7fefebf06acec, 0x39afb7a824100, 0x1b48e47e7fd65, 0x04c00c54d1dfa },\n        { 0x48158599b5a68, 0x1fd75bc41d5d9, 0x2d9fc1fa95d3c, 0x7da27f20eba11, 0x403b92e3019d4 },\n        { 0x22f818b465cf8, 0x342901dff09b8, 0x31f595dc683cd, 0x37a57745fd682, 0x355bb12ab2617 },\n    },\n    {\n        { 0x1dac75a8c7318, 0x3b679d5423460, 0x6b8fcb7b6400e, 0x6c73783be5f9d, 0x7518eaf8e052a },\n        { 0x664cc7493bbf4, 0x33d94761874e3, 0x0179e1796f613, 0x1890535e2867d, 0x0f9b8132182ec },\n        { 0x059c41b7f6c32, 0x79e8706531491, 0x6c747643cb582, 0x2e20c0ad494e4, 0x47c3871bbb175 },\n    },\n    {\n        { 0x65d50c85066b0, 0x6167453361f7c, 0x06ba3818bb312, 0x6aff29baa7522, 0x08fea02ce8d48 },\n        { 0x4539771ec4f48, 0x7b9318badca28, 0x70f19afe016c5, 0x4ee7bb1608d23, 0x00b89b8576469 },\n        { 0x5dd7668deead0, 0x4096d0ba47049, 0x6275997219114, 0x29bda8a67e6ae, 0x473829a74f75d },\n    },\n    {\n        { 0x1533aad3902c9, 0x1dde06b11e47b, 0x784bed1930b77, 0x1c80a92b9c867, 0x6c668b4d44e4d },\n        { 0x2da754679c418, 0x3164c31be105a, 0x11fac2b98ef5f, 0x35a1aaf779256, 0x2078684c4833c },\n        { 0x0cf217a78820c, 0x65024e7d2e769, 0x23bb5efdda82a, 0x19fd4b632d3c6, 0x7411a6054f8a4 },\n    },\n    {\n        { 0x2e53d18b175b4, 0x33e7254204af3, 0x3bcd7d5a1c4c5, 0x4c7c22af65d0f, 0x1ec9a872458c3 },\n        { 0x59d32b99dc86d, 0x6ac075e22a9ac, 0x30b9220113371, 0x27fd9a638966e, 0x7c136574fb813 },\n        { 0x6a4d400a2509b, 0x041791056971c, 0x655d5866e075c, 0x2302bf3e64df8, 0x3add88a5c7cd6 },\n    },\n    {\n        { 0x298d459393046, 0x30bfecb3d90b8, 0x3d9b8ea3df8d6, 0x3900e96511579, 0x61ba1131a406a },\n        { 0x15770b635dcf2, 0x59ecd83f79571, 0x2db461c0b7fbd, 0x73a42a981345f, 0x249929fccc879 },\n        { 0x0a0f116959029, 0x5974fd7b1347a, 0x1e0cc1c08edad, 0x673bdf8ad1f13, 0x5620310cbbd8e },\n    },\n    {\n        { 0x6b5f477e285d6, 0x4ed91ec326cc8, 0x6d6537503a3fd, 0x626d3763988d5, 0x7ec846f3658ce },\n        { 0x193434934d643, 0x0d4a2445eaa51, 0x7d0708ae76fe0, 0x39847b6c3c7e1, 0x37676a2a4d9d9 },\n        { 0x68f3f1da22ec7, 0x6ed8039a2736b, 0x2627ee04c3c75, 0x6ea90a647e7d1, 0x6daaf723399b9 },\n    },\n},\n{\n    {\n        { 0x304bfacad8ea2, 0x502917d108b07, 0x043176ca6dd0f, 0x5d5158f2c1d84, 0x2b5449e58eb3b },\n        { 0x27562eb3dbe47, 0x291d7b4170be7, 0x5d1ca67dfa8e1, 0x2a88061f298a2, 0x1304e9e71627d },\n        { 0x014d26adc9cfe, 0x7f1691ba16f13, 0x5e71828f06eac, 0x349ed07f0fffc, 0x4468de2d7c2dd },\n    },\n    {\n        { 0x2d8c6f86307ce, 0x6286ba1850973, 0x5e9dcb08444d4, 0x1a96a543362b2, 0x5da6427e63247 },\n        { 0x3355e9419469e, 0x1847bb8ea8a37, 0x1fe6588cf9b71, 0x6b1c9d2db6b22, 0x6cce7c6ffb44b },\n        { 0x4c688deac22ca, 0x6f775c3ff0352, 0x565603ee419bb, 0x6544456c61c46, 0x58f29abfe79f2 },\n    },\n    {\n        { 0x264bf710ecdf6, 0x708c58527896b, 0x42ceae6c53394, 0x4381b21e82b6a, 0x6af93724185b4 },\n        { 0x6cfab8de73e68, 0x3e6efced4bd21, 0x0056609500dbe, 0x71b7824ad85df, 0x577629c4a7f41 },\n        { 0x0024509c6a888, 0x2696ab12e6644, 0x0cca27f4b80d8, 0x0c7c1f11b119e, 0x701f25bb0caec },\n    },\n    {\n        { 0x0f6d97cbec113, 0x4ce97fb7c93a3, 0x139835a11281b, 0x728907ada9156, 0x720a5bc050955 },\n        { 0x0b0f8e4616ced, 0x1d3c4b50fb875, 0x2f29673dc0198, 0x5f4b0f1830ffa, 0x2e0c92bfbdc40 },\n        { 0x709439b805a35, 0x6ec48557f8187, 0x08a4d1ba13a2c, 0x076348a0bf9ae, 0x0e9b9cbb144ef },\n    },\n    {\n        { 0x69bd55db1beee, 0x6e14e47f731bd, 0x1a35e47270eac, 0x66f225478df8e, 0x366d44191cfd3 },\n        { 0x2d48ffb5720ad, 0x57b7f21a1df77, 0x5550effba0645, 0x5ec6a4098a931, 0x221104eb3f337 },\n        { 0x41743f2bc8c14, 0x796b0ad8773c7, 0x29fee5cbb689b, 0x122665c178734, 0x4167a4e6bc593 },\n    },\n    {\n        { 0x62665f8ce8fee, 0x29d101ac59857, 0x4d93bbba59ffc, 0x17b7897373f17, 0x34b33370cb7ed },\n        { 0x39d2876f62700, 0x001cecd1d6c87, 0x7f01a11747675, 0x2350da5a18190, 0x7938bb7e22552 },\n        { 0x591ee8681d6cc, 0x39db0b4ea79b8, 0x202220f380842, 0x2f276ba42e0ac, 0x1176fc6e2dfe6 },\n    },\n    {\n        { 0x0e28949770eb8, 0x5559e88147b72, 0x35e1e6e63ef30, 0x35b109aa7ff6f, 0x1f6a3e54f2690 },\n        { 0x76cd05b9c619b, 0x69654b0901695, 0x7a53710b77f27, 0x79a1ea7d28175, 0x08fc3a4c677d5 },\n        { 0x4c199d30734ea, 0x6c622cb9acc14, 0x5660a55030216, 0x068f1199f11fb, 0x4f2fad0116b90 },\n    },\n    {\n        { 0x4d91db73bb638, 0x55f82538112c5, 0x6d85a279815de, 0x740b7b0cd9cf9, 0x3451995f2944e },\n        { 0x6b24194ae4e54, 0x2230afded8897, 0x23412617d5071, 0x3d5d30f35969b, 0x445484a4972ef },\n        { 0x2fcd09fea7d7c, 0x296126b9ed22a, 0x4a171012a05b2, 0x1db92c74d5523, 0x10b89ca604289 },\n    },\n},\n{\n    {\n        { 0x141be5a45f06e, 0x5adb38becaea7, 0x3fd46db41f2bb, 0x6d488bbb5ce39, 0x17d2d1d9ef0d4 },\n        { 0x147499718289c, 0x0a48a67e4c7ab, 0x30fbc544bafe3, 0x0c701315fe58a, 0x20b878d577b75 },\n        { 0x2af18073f3e6a, 0x33aea420d24fe, 0x298008bf4ff94, 0x3539171db961e, 0x72214f63cc65c },\n    },\n    {\n        { 0x5b7b9f43b29c9, 0x149ea31eea3b3, 0x4be7713581609, 0x2d87960395e98, 0x1f24ac855a154 },\n        { 0x37f405307a693, 0x2e5e66cf2b69c, 0x5d84266ae9c53, 0x5e4eb7de853b9, 0x5fdf48c58171c },\n        { 0x608328e9505aa, 0x22182841dc49a, 0x3ec96891d2307, 0x2f363fff22e03, 0x00ba739e2ae39 },\n    },\n    {\n        { 0x426f5ea88bb26, 0x33092e77f75c8, 0x1a53940d819e7, 0x1132e4f818613, 0x72297de7d518d },\n        { 0x698de5c8790d6, 0x268b8545beb25, 0x6d2648b96fedf, 0x47988ad1db07c, 0x03283a3e67ad7 },\n        { 0x41dc7be0cb939, 0x1b16c66100904, 0x0a24c20cbc66d, 0x4a2e9efe48681, 0x05e1296846271 },\n    },\n    {\n        { 0x7bbc8242c4550, 0x59a06103b35b7, 0x7237e4af32033, 0x726421ab3537a, 0x78cf25d38258c },\n        { 0x2eeb32d9c495a, 0x79e25772f9750, 0x6d747833bbf23, 0x6cdd816d5d749, 0x39c00c9c13698 },\n        { 0x66b8e31489d68, 0x573857e10e2b5, 0x13be816aa1472, 0x41964d3ad4bf8, 0x006b52076b3ff },\n    },\n    {\n        { 0x37e16b9ce082d, 0x1882f57853eb9, 0x7d29eacd01fc5, 0x2e76a59b5e715, 0x7de2e9561a9f7 },\n        { 0x0cfe19d95781c, 0x312cc621c453c, 0x145ace6da077c, 0x0912bef9ce9b8, 0x4d57e3443bc76 },\n        { 0x0d4f4b6a55ecb, 0x7ebb0bb733bce, 0x7ba6a05200549, 0x4f6ede4e22069, 0x6b2a90af1a602 },\n    },\n    {\n        { 0x3f3245bb2d80a, 0x0e5f720f36efd, 0x3b9cccf60c06d, 0x084e323f37926, 0x465812c8276c2 },\n        { 0x3f4fc9ae61e97, 0x3bc07ebfa2d24, 0x3b744b55cd4a0, 0x72553b25721f3, 0x5fd8f4e9d12d3 },\n        { 0x3beb22a1062d9, 0x6a7063b82c9a8, 0x0a5a35dc197ed, 0x3c80c06a53def, 0x05b32c2b1cb16 },\n    },\n    {\n        { 0x4a42c7ad58195, 0x5c8667e799eff, 0x02e5e74c850a1, 0x3f0db614e869a, 0x31771a4856730 },\n        { 0x05eccd24da8fd, 0x580bbfdf07918, 0x7e73586873c6a, 0x74ceddf77f93e, 0x3b5556a37b471 },\n        { 0x0c524e14dd482, 0x283457496c656, 0x0ad6bcfb6cd45, 0x375d1e8b02414, 0x4fc079d27a733 },\n    },\n    {\n        { 0x48b440c86c50d, 0x139929cca3b86, 0x0f8f2e44cdf2f, 0x68432117ba6b2, 0x241170c2bae3c },\n        { 0x138b089bf2f7f, 0x4a05bfd34ea39, 0x203914c925ef5, 0x7497fffe04e3c, 0x124567cecaf98 },\n        { 0x1ab860ac473b4, 0x5c0227c86a7ff, 0x71b12bfc24477, 0x006a573a83075, 0x3f8612966c870 },\n    },\n},\n{\n    {\n        { 0x0fcfa36048d13, 0x66e7133bbb383, 0x64b42a8a45676, 0x4ea6e4f9a85cf, 0x26f57eee878a1 },\n        { 0x20cc9782a0dde, 0x65d4e3070aab3, 0x7bc8e31547736, 0x09ebfb1432d98, 0x504aa77679736 },\n        { 0x32cd55687efb1, 0x4448f5e2f6195, 0x568919d460345, 0x034c2e0ad1a27, 0x4041943d9dba3 },\n    },\n    {\n        { 0x17743a26caadd, 0x48c9156f9c964, 0x7ef278d1e9ad0, 0x00ce58ea7bd01, 0x12d931429800d },\n        { 0x0eeba43ebcc96, 0x384dd5395f878, 0x1df331a35d272, 0x207ecfd4af70e, 0x1420a1d976843 },\n        { 0x67799d337594f, 0x01647548f6018, 0x57fce5578f145, 0x009220c142a71, 0x1b4f92314359a },\n    },\n    {\n        { 0x73030a49866b1, 0x2442be90b2679, 0x77bd3d8947dcf, 0x1fb55c1552028, 0x5ff191d56f9a2 },\n        { 0x4109d89150951, 0x225bd2d2d47cb, 0x57cc080e73bea, 0x6d71075721fcb, 0x239b572a7f132 },\n        { 0x6d433ac2d9068, 0x72bf930a47033, 0x64facf4a20ead, 0x365f7a2b9402a, 0x020c526a758f3 },\n    },\n    {\n        { 0x1ef59f042cc89, 0x3b1c24976dd26, 0x31d665cb16272, 0x28656e470c557, 0x452cfe0a5602c },\n        { 0x034f89ed8dbbc, 0x73b8f948d8ef3, 0x786c1d323caab, 0x43bd4a9266e51, 0x02aacc4615313 },\n        { 0x0f7a0647877df, 0x4e1cc0f93f0d4, 0x7ec4726ef1190, 0x3bdd58bf512f8, 0x4cfb7d7b304b8 },\n    },\n    {\n        { 0x699c29789ef12, 0x63beae321bc50, 0x325c340adbb35, 0x562e1a1e42bf6, 0x5b1d4cbc434d3 },\n        { 0x43d6cb89b75fe, 0x3338d5b900e56, 0x38d327d531a53, 0x1b25c61d51b9f, 0x14b4622b39075 },\n        { 0x32615cc0a9f26, 0x57711b99cb6df, 0x5a69c14e93c38, 0x6e88980a4c599, 0x2f98f71258592 },\n    },\n    {\n        { 0x2ae444f54a701, 0x615397afbc5c2, 0x60d7783f3f8fb, 0x2aa675fc486ba, 0x1d8062e9e7614 },\n        { 0x4a74cb50f9e56, 0x531d1c2640192, 0x0c03d9d6c7fd2, 0x57ccd156610c1, 0x3a6ae249d806a },\n        { 0x2da85a9907c5a, 0x6b23721ec4caf, 0x4d2d3a4683aa2, 0x7f9c6870efdef, 0x298b8ce8aef25 },\n    },\n    {\n        { 0x272ea0a2165de, 0x68179ef3ed06f, 0x4e2b9c0feac1e, 0x3ee290b1b63bb, 0x6ba6271803a7d },\n        { 0x27953eff70cb2, 0x54f22ae0ec552, 0x29f3da92e2724, 0x242ca0c22bd18, 0x34b8a8404d5ce },\n        { 0x6ecb583693335, 0x3ec76bfdfb84d, 0x2c895cf56a04f, 0x6355149d54d52, 0x71d62bdd465e1 },\n    },\n    {\n        { 0x5b5dab1f75ef5, 0x1e2d60cbeb9a5, 0x527c2175dfe57, 0x59e8a2b8ff51f, 0x1c333621262b2 },\n        { 0x3cc28d378df80, 0x72141f4968ca6, 0x407696bdb6d0d, 0x5d271b22ffcfb, 0x74d5f317f3172 },\n        { 0x7e55467d9ca81, 0x6a5653186f50d, 0x6b188ece62df1, 0x4c66d36844971, 0x4aebcc4547e9d },\n    },\n},\n{\n    {\n        { 0x08d9e7354b610, 0x26b750b6dc168, 0x162881e01acc9, 0x7966df31d01a5, 0x173bd9ddc9a1d },\n        { 0x0071b276d01c9, 0x0b0d8918e025e, 0x75beea79ee2eb, 0x3c92984094db8, 0x5d88fbf95a3db },\n        { 0x00f1efe5872df, 0x5da872318256a, 0x59ceb81635960, 0x18cf37693c764, 0x06e1cd13b19ea },\n    },\n    {\n        { 0x3af629e5b0353, 0x204f1a088e8e5, 0x10efc9ceea82e, 0x589863c2fa34b, 0x7f3a6a1a8d837 },\n        { 0x0ad516f166f23, 0x263f56d57c81a, 0x13422384638ca, 0x1331ff1af0a50, 0x3080603526e16 },\n        { 0x644395d3d800b, 0x2b9203dbedefc, 0x4b18ce656a355, 0x03f3466bc182c, 0x30d0fded2e513 },\n    },\n    {\n        { 0x4971e68b84750, 0x52ccc9779f396, 0x3e904ae8255c8, 0x4ecae46f39339, 0x4615084351c58 },\n        { 0x14d1af21233b3, 0x1de1989b39c0b, 0x52669dc6f6f9e, 0x43434b28c3fc7, 0x0a9214202c099 },\n        { 0x019c0aeb9a02e, 0x1a2c06995d792, 0x664cbb1571c44, 0x6ff0736fa80b2, 0x3bca0d2895ca5 },\n    },\n    {\n        { 0x08eb69ecc01bf, 0x5b4c8912df38d, 0x5ea7f8bc2f20e, 0x120e516caafaf, 0x4ea8b4038df28 },\n        { 0x031bc3c5d62a4, 0x7d9fe0f4c081e, 0x43ed51467f22c, 0x1e6cc0c1ed109, 0x5631deddae8f1 },\n        { 0x5460af1cad202, 0x0b4919dd0655d, 0x7c4697d18c14c, 0x231c890bba2a4, 0x24ce0930542ca },\n    },\n    {\n        { 0x7a155fdf30b85, 0x1c6c6e5d487f9, 0x24be1134bdc5a, 0x1405970326f32, 0x549928a7324f4 },\n        { 0x090f5fd06c106, 0x6abb1021e43fd, 0x232bcfad711a0, 0x3a5c13c047f37, 0x41d4e3c28a06d },\n        { 0x632a763ee1a2e, 0x6fa4bffbd5e4d, 0x5fd35a6ba4792, 0x7b55e1de99de8, 0x491b66dec0dcf },\n    },\n    {\n        { 0x04a8ed0da64a1, 0x5ecfc45096ebe, 0x5edee93b488b2, 0x5b3c11a51bc8f, 0x4cf6b8b0b7018 },\n        { 0x5b13dc7ea32a7, 0x18fc2db73131e, 0x7e3651f8f57e3, 0x25656055fa965, 0x08f338d0c85ee },\n        { 0x3a821991a73bd, 0x03be6418f5870, 0x1ddc18eac9ef0, 0x54ce09e998dc2, 0x530d4a82eb078 },\n    },\n    {\n        { 0x173456c9abf9e, 0x7892015100dad, 0x33ee14095fecb, 0x6ad95d67a0964, 0x0db3e7e00cbfb },\n        { 0x43630e1f94825, 0x4d1956a6b4009, 0x213fe2df8b5e0, 0x05ce3a41191e6, 0x65ea753f10177 },\n        { 0x6fc3ee2096363, 0x7ec36b96d67ac, 0x510ec6a0758b1, 0x0ed87df022109, 0x02a4ec1921e1a },\n    },\n    {\n        { 0x06162f1cf795f, 0x324ddcafe5eb9, 0x018d5e0463218, 0x7e78b9092428e, 0x36d12b5dec067 },\n        { 0x6259a3b24b8a2, 0x188b5f4170b9c, 0x681c0dee15deb, 0x4dfe665f37445, 0x3d143c5112780 },\n        { 0x5279179154557, 0x39f8f0741424d, 0x45e6eb357923d, 0x42c9b5edb746f, 0x2ef517885ba82 },\n    },\n},\n{\n    {\n        { 0x6bffb305b2f51, 0x5b112b2d712dd, 0x35774974fe4e2, 0x04af87a96e3a3, 0x57968290bb3a0 },\n        { 0x7974e8c58aedc, 0x7757e083488c6, 0x601c62ae7bc8b, 0x45370c2ecab74, 0x2f1b78fab143a },\n        { 0x2b8430a20e101, 0x1a49e1d88fee3, 0x38bbb47ce4d96, 0x1f0e7ba84d437, 0x7dc43e35dc2aa },\n    },\n    {\n        { 0x02a5c273e9718, 0x32bc9dfb28b4f, 0x48df4f8d5db1a, 0x54c87976c028f, 0x044fb81d82d50 },\n        { 0x66665887dd9c3, 0x629760a6ab0b2, 0x481e6c7243e6c, 0x097e37046fc77, 0x7ef72016758cc },\n        { 0x718c5a907e3d9, 0x3b9c98c6b383b, 0x006ed255eccdc, 0x6976538229a59, 0x7f79823f9c30d },\n    },\n    {\n        { 0x41ff068f587ba, 0x1c00a191bcd53, 0x7b56f9c209e25, 0x3781e5fccaabe, 0x64a9b0431c06d },\n        { 0x4d239a3b513e8, 0x29723f51b1066, 0x642f4cf04d9c3, 0x4da095aa09b7a, 0x0a4e0373d784d },\n        { 0x3d6a15b7d2919, 0x41aa75046a5d6, 0x691751ec2d3da, 0x23638ab6721c4, 0x071a7d0ace183 },\n    },\n    {\n        { 0x4355220e14431, 0x0e1362a283981, 0x2757cd8359654, 0x2e9cd7ab10d90, 0x7c69bcf761775 },\n        { 0x72daac887ba0b, 0x0b7f4ac5dda60, 0x3bdda2c0498a4, 0x74e67aa180160, 0x2c3bcc7146ea7 },\n        { 0x0d7eb04e8295f, 0x4a5ea1e6fa0fe, 0x45e635c436c60, 0x28ef4a8d4d18b, 0x6f5a9a7322aca },\n    },\n    {\n        { 0x1d4eba3d944be, 0x0100f15f3dce5, 0x61a700e367825, 0x5922292ab3d23, 0x02ab9680ee8d3 },\n        { 0x1000c2f41c6c5, 0x0219fdf737174, 0x314727f127de7, 0x7e5277d23b81e, 0x494e21a2e147a },\n        { 0x48a85dde50d9a, 0x1c1f734493df4, 0x47bdb64866889, 0x59a7d048f8eec, 0x6b5d76cbea46b },\n    },\n    {\n        { 0x141171e782522, 0x6806d26da7c1f, 0x3f31d1bc79ab9, 0x09f20459f5168, 0x16fb869c03dd3 },\n        { 0x7556cec0cd994, 0x5eb9a03b7510a, 0x50ad1dd91cb71, 0x1aa5780b48a47, 0x0ae333f685277 },\n        { 0x6199733b60962, 0x69b157c266511, 0x64740f893f1ca, 0x03aa408fbf684, 0x3f81e38b8f70d },\n    },\n    {\n        { 0x37f355f17c824, 0x07ae85334815b, 0x7e3abddd2e48f, 0x61eeabe1f45e5, 0x0ad3e2d34cded },\n        { 0x10fcc7ed9affe, 0x4248cb0e96ff2, 0x4311c115172e2, 0x4c9d41cbf6925, 0x50510fc104f50 },\n        { 0x40fc5336e249d, 0x3386639fb2de1, 0x7bbf871d17b78, 0x75f796b7e8004, 0x127c158bf0fa1 },\n    },\n    {\n        { 0x28fc4ae51b974, 0x26e89bfd2dbd4, 0x4e122a07665cf, 0x7cab1203405c3, 0x4ed82479d167d },\n        { 0x17c422e9879a2, 0x28a5946c8fec3, 0x53ab32e912b77, 0x7b44da09fe0a5, 0x354ef87d07ef4 },\n        { 0x3b52260c5d975, 0x79d6836171fdc, 0x7d994f140d4bb, 0x1b6c404561854, 0x302d92d205392 },\n    },\n},\n{\n    {\n        { 0x46fb6e4e0f177, 0x53497ad5265b7, 0x1ebdba01386fc, 0x0302f0cb36a3c, 0x0edc5f5eb426d },\n        { 0x3c1a2bca4283d, 0x23430c7bb2f02, 0x1a3ea1bb58bc2, 0x7265763de5c61, 0x10e5d3b76f1ca },\n        { 0x3bfd653da8e67, 0x584953ec82a8a, 0x55e288fa7707b, 0x5395fc3931d81, 0x45b46c51361cb },\n    },\n    {\n        { 0x54ddd8a7fe3e4, 0x2cecc41c619d3, 0x43a6562ac4d91, 0x4efa5aca7bdd9, 0x5c1c0aef32122 },\n        { 0x02abf314f7fa1, 0x391d19e8a1528, 0x6a2fa13895fc7, 0x09d8eddeaa591, 0x2177bfa36dcb7 },\n        { 0x01bbcfa79db8f, 0x3d84beb3666e1, 0x20c921d812204, 0x2dd843d3b32ce, 0x4ae619387d8ab },\n    },\n    {\n        { 0x17e44985bfb83, 0x54e32c626cc22, 0x096412ff38118, 0x6b241d61a246a, 0x75685abe5ba43 },\n        { 0x3f6aa5344a32e, 0x69683680f11bb, 0x04c3581f623aa, 0x701af5875cba5, 0x1a00d91b17bf3 },\n        { 0x60933eb61f2b2, 0x5193fe92a4dd2, 0x3d995a550f43e, 0x3556fb93a883d, 0x135529b623b0e },\n    },\n    {\n        { 0x716bce22e83fe, 0x33d0130b83eb8, 0x0952abad0afac, 0x309f64ed31b8a, 0x5972ea051590a },\n        { 0x0dbd7add1d518, 0x119f823e2231e, 0x451d66e5e7de2, 0x500c39970f838, 0x79b5b81a65ca3 },\n        { 0x4ac20dc8f7811, 0x29589a9f501fa, 0x4d810d26a6b4a, 0x5ede00d96b259, 0x4f7e9c95905f3 },\n    },\n    {\n        { 0x0443d355299fe, 0x39b7d7d5aee39, 0x692519a2f34ec, 0x6e4404924cf78, 0x1942eec4a144a },\n        { 0x74bbc5781302e, 0x73135bb81ec4c, 0x7ef671b61483c, 0x7264614ccd729, 0x31993ad92e638 },\n        { 0x45319ae234992, 0x2219d47d24fb5, 0x4f04488b06cf6, 0x53aaa9e724a12, 0x2a0a65314ef9c },\n    },\n    {\n        { 0x61acd3c1c793a, 0x58b46b78779e6, 0x3369aacbe7af2, 0x509b0743074d4, 0x055dc39b6dea1 },\n        { 0x7937ff7f927c2, 0x0c2fa14c6a5b6, 0x556bddb6dd07c, 0x6f6acc179d108, 0x4cf6e218647c2 },\n        { 0x1227cc28d5bb6, 0x78ee9bff57623, 0x28cb2241f893a, 0x25b541e3c6772, 0x121a307710aa2 },\n    },\n    {\n        { 0x1713ec77483c9, 0x6f70572d5facb, 0x25ef34e22ff81, 0x54d944f141188, 0x527bb94a6ced3 },\n        { 0x35d5e9f034a97, 0x126069785bc9b, 0x5474ec7854ff0, 0x296a302a348ca, 0x333fc76c7a40e },\n        { 0x5992a995b482e, 0x78dc707002ac7, 0x5936394d01741, 0x4fba4281aef17, 0x6b89069b20a7a },\n    },\n    {\n        { 0x2fa8cb5c7db77, 0x718e6982aa810, 0x39e95f81a1a1b, 0x5e794f3646cfb, 0x0473d308a7639 },\n        { 0x2a0416270220d, 0x75f248b69d025, 0x1cbbc16656a27, 0x5b9ffd6e26728, 0x23bc2103aa73e },\n        { 0x6792603589e05, 0x248db9892595d, 0x006a53cad2d08, 0x20d0150f7ba73, 0x102f73bfde043 },\n    },\n},\n{\n    {\n        { 0x4dae0b5511c9a, 0x5257fffe0d456, 0x54108d1eb2180, 0x096cc0f9baefa, 0x3f6bd725da4ea },\n        { 0x0b9ab7f5745c6, 0x5caf0f8d21d63, 0x7debea408ea2b, 0x09edb93896d16, 0x36597d25ea5c0 },\n        { 0x58d7b106058ac, 0x3cdf8d20bee69, 0x00a4cb765015e, 0x36832337c7cc9, 0x7b7ecc19da60d },\n    },\n    {\n        { 0x64a51a77cfa9b, 0x29cf470ca0db5, 0x4b60b6e0898d9, 0x55d04ddffe6c7, 0x03bedc661bf5c },\n        { 0x2373c695c690d, 0x4c0c8520dcf18, 0x384af4b7494b9, 0x4ab4a8ea22225, 0x4235ad7601743 },\n        { 0x0cb0d078975f5, 0x292313e530c4b, 0x38dbb9124a509, 0x350d0655a11f1, 0x0e7ce2b0cdf06 },\n    },\n    {\n        { 0x6fedfd94b70f9, 0x2383f9745bfd4, 0x4beae27c4c301, 0x75aa4416a3f3f, 0x615256138aece },\n        { 0x4643ac48c85a3, 0x6878c2735b892, 0x3a53523f4d877, 0x3a504ed8bee9d, 0x666e0a5d8fb46 },\n        { 0x3f64e4870cb0d, 0x61548b16d6557, 0x7a261773596f3, 0x7724d5f275d3a, 0x7f0bc810d514d },\n    },\n    {\n        { 0x49dad737213a0, 0x745dee5d31075, 0x7b1a55e7fdbe2, 0x5ba988f176ea1, 0x1d3a907ddec5a },\n        { 0x06ba426f4136f, 0x3cafc0606b720, 0x518f0a2359cda, 0x5fae5e46feca7, 0x0d1f8dbcf8eed },\n        { 0x693313ed081dc, 0x5b0a366901742, 0x40c872ca4ca7e, 0x6f18094009e01, 0x00011b44a31bf },\n    },\n    {\n        { 0x61f696a0aa75c, 0x38b0a57ad42ca, 0x1e59ab706fdc9, 0x01308d46ebfcd, 0x63d988a2d2851 },\n        { 0x7a06c3fc66c0c, 0x1c9bac1ba47fb, 0x23935c575038e, 0x3f0bd71c59c13, 0x3ac48d916e835 },\n        { 0x20753afbd232e, 0x71fbb1ed06002, 0x39cae47a4af3a, 0x0337c0b34d9c2, 0x33fad52b2368a },\n    },\n    {\n        { 0x4c8d0c422cfe8, 0x760b4275971a5, 0x3da95bc1cad3d, 0x0f151ff5b7376, 0x3cc355ccb90a7 },\n        { 0x649c6c5e41e16, 0x60667eee6aa80, 0x4179d182be190, 0x653d9567e6979, 0x16c0f429a256d },\n        { 0x69443903e9131, 0x16f4ac6f9dd36, 0x2ea4912e29253, 0x2b4643e68d25d, 0x631eaf426bae7 },\n    },\n    {\n        { 0x175b9a3700de8, 0x77c5f00aa48fb, 0x3917785ca0317, 0x05aa9b2c79399, 0x431f2c7f665f8 },\n        { 0x10410da66fe9f, 0x24d82dcb4d67d, 0x3e6fe0e17752d, 0x4dade1ecbb08f, 0x5599648b1ea91 },\n        { 0x26344858f7b19, 0x5f43d4a295ac0, 0x242a75c52acd4, 0x5934480220d10, 0x7b04715f91253 },\n    },\n    {\n        { 0x6c280c4e6bac6, 0x3ada3b361766e, 0x42fe5125c3b4f, 0x111d84d4aac22, 0x48d0acfa57cde },\n        { 0x5bd28acf6ae43, 0x16fab8f56907d, 0x7acb11218d5f2, 0x41fe02023b4db, 0x59b37bf5c2f65 },\n        { 0x726e47dabe671, 0x2ec45e746f6c1, 0x6580e53c74686, 0x5eda104673f74, 0x16234191336d3 },\n    },\n},\n{\n    {\n        { 0x19cd61ff38640, 0x060c6c4b41ba9, 0x75cf70ca7366f, 0x118a8f16c011e, 0x4a25707a203b9 },\n        { 0x499def6267ff6, 0x76e858108773c, 0x693cac5ddcb29, 0x00311d00a9ff4, 0x2cdfdfecd5d05 },\n        { 0x7668a53f6ed6a, 0x303ba2e142556, 0x3880584c10909, 0x4fe20000a261d, 0x5721896d248e4 },\n    },\n    {\n        { 0x55091a1d0da4e, 0x4f6bfc7c1050b, 0x64e4ecd2ea9be, 0x07eb1f28bbe70, 0x03c935afc4b03 },\n        { 0x65517fd181bae, 0x3e5772c76816d, 0x019189640898a, 0x1ed2a84de7499, 0x578edd74f63c1 },\n        { 0x276c6492b0c3d, 0x09bfc40bf932e, 0x588e8f11f330b, 0x3d16e694dc26e, 0x3ec2ab590288c },\n    },\n    {\n        { 0x13a09ae32d1cb, 0x3e81eb85ab4e4, 0x07aaca43cae1f, 0x62f05d7526374, 0x0e1bf66c6adba },\n        { 0x0d27be4d87bb9, 0x56c27235db434, 0x72e6e0ea62d37, 0x5674cd06ee839, 0x2dd5c25a200fc },\n        { 0x3d5e9792c887e, 0x319724dabbc55, 0x2b97c78680800, 0x7afdfdd34e6dd, 0x730548b35ae88 },\n    },\n    {\n        { 0x3094ba1d6e334, 0x6e126a7e3300b, 0x089c0aefcfbc5, 0x2eea11f836583, 0x585a2277d8784 },\n        { 0x551a3cba8b8ee, 0x3b6422be2d886, 0x630e1419689bc, 0x4653b07a7a955, 0x3043443b411db },\n        { 0x25f8233d48962, 0x6bd8f04aff431, 0x4f907fd9a6312, 0x40fd3c737d29b, 0x7656278950ef9 },\n    },\n    {\n        { 0x073a3ea86cf9d, 0x6e0e2abfb9c2e, 0x60e2a38ea33ee, 0x30b2429f3fe18, 0x28bbf484b613f },\n        { 0x3cf59d51fc8c0, 0x7a0a0d6de4718, 0x55c3a3e6fb74b, 0x353135f884fd5, 0x3f4160a8c1b84 },\n        { 0x12f5c6f136c7c, 0x0fedba237de4c, 0x779bccebfab44, 0x3aea93f4d6909, 0x1e79cb358188f },\n    },\n    {\n        { 0x153d8f5e08181, 0x08533bbdb2efd, 0x1149796129431, 0x17a6e36168643, 0x478ab52d39d1f },\n        { 0x436c3eef7e3f1, 0x7ffd3c21f0026, 0x3e77bf20a2da9, 0x418bffc8472de, 0x65d7951b3a3b3 },\n        { 0x6a4d39252d159, 0x790e35900ecd4, 0x30725bf977786, 0x10a5c1635a053, 0x16d87a411a212 },\n    },\n    {\n        { 0x4d5e2d54e0583, 0x2e5d7b33f5f74, 0x3a5de3f887ebf, 0x6ef24bd6139b7, 0x1f990b577a5a6 },\n        { 0x57e5a42066215, 0x1a18b44983677, 0x3e652de1e6f8f, 0x6532be02ed8eb, 0x28f87c8165f38 },\n        { 0x44ead1be8f7d6, 0x5759d4f31f466, 0x0378149f47943, 0x69f3be32b4f29, 0x45882fe1534d6 },\n    },\n    {\n        { 0x49929943c6fe4, 0x4347072545b15, 0x3226bced7e7c5, 0x03a134ced89df, 0x7dcf843ce405f },\n        { 0x1345d757983d6, 0x222f54234cccd, 0x1784a3d8adbb4, 0x36ebeee8c2bcc, 0x688fe5b8f626f },\n        { 0x0d6484a4732c0, 0x7b94ac6532d92, 0x5771b8754850f, 0x48dd9df1461c8, 0x6739687e73271 },\n    },\n},\n{\n    {\n        { 0x5cc9dc80c1ac0, 0x683671486d4cd, 0x76f5f1a5e8173, 0x6d5d3f5f9df4a, 0x7da0b8f68d7e7 },\n        { 0x02014385675a6, 0x6155fb53d1def, 0x37ea32e89927c, 0x059a668f5a82e, 0x46115aba1d4dc },\n        { 0x71953c3b5da76, 0x6642233d37a81, 0x2c9658076b1bd, 0x5a581e63010ff, 0x5a5f887e83674 },\n    },\n    {\n        { 0x628d3a0a643b9, 0x01cd8640c93d2, 0x0b7b0cad70f2c, 0x3864da98144be, 0x43e37ae2d5d1c },\n        { 0x301cf70a13d11, 0x2a6a1ba1891ec, 0x2f291fb3f3ae0, 0x21a7b814bea52, 0x3669b656e44d1 },\n        { 0x63f06eda6e133, 0x233342758070f, 0x098e0459cc075, 0x4df5ead6c7c1b, 0x6a21e6cd4fd5e },\n    },\n    {\n        { 0x129126699b2e3, 0x0ee11a2603de8, 0x60ac2f5c74c21, 0x59b192a196808, 0x45371b07001e8 },\n        { 0x6170a3046e65f, 0x5401a46a49e38, 0x20add5561c4a8, 0x7abb4edde9e46, 0x586bf9f1a195f },\n        { 0x3088d5ef8790b, 0x38c2126fcb4db, 0x685bae149e3c3, 0x0bcd601a4e930, 0x0eafb03790e52 },\n    },\n    {\n        { 0x0805e0f75ae1d, 0x464cc59860a28, 0x248e5b7b00bef, 0x5d99675ef8f75, 0x44ae3344c5435 },\n        { 0x555c13748042f, 0x4d041754232c0, 0x521b430866907, 0x3308e40fb9c39, 0x309acc675a02c },\n        { 0x289b9bba543ee, 0x3ab592e28539e, 0x64d82abcdd83a, 0x3c78ec172e327, 0x62d5221b7f946 },\n    },\n    {\n        { 0x5d4263af77a3c, 0x23fdd2289aeb0, 0x7dc64f77eb9ec, 0x01bd28338402c, 0x14f29a5383922 },\n        { 0x4299c18d0936d, 0x5914183418a49, 0x52a18c721aed5, 0x2b151ba82976d, 0x5c0efde4bc754 },\n        { 0x17edc25b2d7f5, 0x37336a6081bee, 0x7b5318887e5c3, 0x49f6d491a5be1, 0x5e72365c7bee0 },\n    },\n    {\n        { 0x339062f08b33e, 0x4bbf3e657cfb2, 0x67af7f56e5967, 0x4dbd67f9ed68f, 0x70b20555cb734 },\n        { 0x3fc074571217f, 0x3a0d29b2b6aeb, 0x06478ccdde59d, 0x55e4d051bddfa, 0x77f1104c47b4e },\n        { 0x113c555112c4c, 0x7535103f9b7ca, 0x140ed1d9a2108, 0x02522333bc2af, 0x0e34398f4a064 },\n    },\n    {\n        { 0x30b093e4b1928, 0x1ce7e7ec80312, 0x4e575bdf78f84, 0x61f7a190bed39, 0x6f8aded6ca379 },\n        { 0x522d93ecebde8, 0x024f045e0f6cf, 0x16db63426cfa1, 0x1b93a1fd30fd8, 0x5e5405368a362 },\n        { 0x0123dfdb7b29a, 0x4344356523c68, 0x79a527921ee5f, 0x74bfccb3e817e, 0x780de72ec8d3d },\n    },\n    {\n        { 0x7eaf300f42772, 0x5455188354ce3, 0x4dcca4a3dcbac, 0x3d314d0bfebcb, 0x1defc6ad32b58 },\n        { 0x28545089ae7bc, 0x1e38fe9a0c15c, 0x12046e0e2377b, 0x6721c560aa885, 0x0eb28bf671928 },\n        { 0x3be1aef5195a7, 0x6f22f62bdb5eb, 0x39768b8523049, 0x43394c8fbfdbd, 0x467d201bf8dd2 },\n    },\n},\n{\n    {\n        { 0x6f4bd567ae7a9, 0x65ac89317b783, 0x07d3b20fd8932, 0x000f208326916, 0x2ef9c5a5ba384 },\n        { 0x6919a74ef4fad, 0x59ed4611452bf, 0x691ec04ea09ef, 0x3cbcb2700e984, 0x71c43c4f5ba3c },\n        { 0x56df6fa9e74cd, 0x79c95e4cf56df, 0x7be643bc609e2, 0x149c12ad9e878, 0x5a758ca390c5f },\n    },\n    {\n        { 0x0918b1d61dc94, 0x0d350260cd19c, 0x7a2ab4e37b4d9, 0x21fea735414d7, 0x0a738027f639d },\n        { 0x72710d9462495, 0x25aafaa007456, 0x2d21f28eaa31b, 0x17671ea005fd0, 0x2dbae244b3eb7 },\n        { 0x74a2f57ffe1cc, 0x1bc3073087301, 0x7ec57f4019c34, 0x34e082e1fa524, 0x2698ca635126a },\n    },\n    {\n        { 0x5702f5e3dd90e, 0x31c9a4a70c5c7, 0x136a5aa78fc24, 0x1992f3b9f7b01, 0x3c004b0c4afa3 },\n        { 0x5318832b0ba78, 0x6f24b9ff17cec, 0x0a47f30e060c7, 0x58384540dc8d0, 0x1fb43dcc49cae },\n        { 0x146ac06f4b82b, 0x4b500d89e7355, 0x3351e1c728a12, 0x10b9f69932fe3, 0x6b43fd01cd1fd },\n    },\n    {\n        { 0x742583e760ef3, 0x73dc1573216b8, 0x4ae48fdd7714a, 0x4f85f8a13e103, 0x73420b2d6ff0d },\n        { 0x75d4b4697c544, 0x11be1fff7f8f4, 0x119e16857f7e1, 0x38a14345cf5d5, 0x5a68d7105b52f },\n        { 0x4f6cb9e851e06, 0x278c4471895e5, 0x7efcdce3d64e4, 0x64f6d455c4b4c, 0x3db5632fea34b },\n    },\n    {\n        { 0x190b1829825d5, 0x0e7d3513225c9, 0x1c12be3b7abae, 0x58777781e9ca6, 0x59197ea495df2 },\n        { 0x6ee2bf75dd9d8, 0x6c72ceb34be8d, 0x679c9cc345ec7, 0x7898df96898a4, 0x04321adf49d75 },\n        { 0x16019e4e55aae, 0x74fc5f25d209c, 0x4566a939ded0d, 0x66063e716e0b7, 0x45eafdc1f4d70 },\n    },\n    {\n        { 0x64624cfccb1ed, 0x257ab8072b6c1, 0x0120725676f0a, 0x4a018d04e8eee, 0x3f73ceea5d56d },\n        { 0x401858045d72b, 0x459e5e0ca2d30, 0x488b719308bea, 0x56f4a0d1b32b5, 0x5a5eebc80362d },\n        { 0x7bfd10a4e8dc6, 0x7c899366736f4, 0x55ebbeaf95c01, 0x46db060903f8a, 0x2605889126621 },\n    },\n    {\n        { 0x18e3cc676e542, 0x26079d995a990, 0x04a7c217908b2, 0x1dc7603e6655a, 0x0dedfa10b2444 },\n        { 0x704a68360ff04, 0x3cecc3cde8b3e, 0x21cd5470f64ff, 0x6abc18d953989, 0x54ad0c2e4e615 },\n        { 0x367d5b82b522a, 0x0d3f4b83d7dc7, 0x3067f4cdbc58d, 0x20452da697937, 0x62ecb2baa77a9 },\n    },\n    {\n        { 0x72836afb62874, 0x0af3c2094b240, 0x0c285297f357a, 0x7cc2d5680d6e3, 0x61913d5075663 },\n        { 0x5795261152b3d, 0x7a1dbbafa3cbd, 0x5ad31c52588d5, 0x45f3a4164685c, 0x2e59f919a966d },\n        { 0x62d361a3231da, 0x65284004e01b8, 0x656533be91d60, 0x6ae016c00a89f, 0x3ddbc2a131c05 },\n    },\n},\n{\n    {\n        { 0x257a22796bb14, 0x6f360fb443e75, 0x680e47220eaea, 0x2fcf2a5f10c18, 0x5ee7fb38d8320 },\n        { 0x40ff9ce5ec54b, 0x57185e261b35b, 0x3e254540e70a9, 0x1b5814003e3f8, 0x78968314ac04b },\n        { 0x5fdcb41446a8e, 0x5286926ff2a71, 0x0f231e296b3f6, 0x684a357c84693, 0x61d0633c9bca0 },\n    },\n    {\n        { 0x328bcf8fc73df, 0x3b4de06ff95b4, 0x30aa427ba11a5, 0x5ee31bfda6d9c, 0x5b23ac2df8067 },\n        { 0x44935ffdb2566, 0x12f016d176c6e, 0x4fbb00f16f5ae, 0x3fab78d99402a, 0x6e965fd847aed },\n        { 0x2b953ee80527b, 0x55f5bcdb1b35a, 0x43a0b3fa23c66, 0x76e07388b820a, 0x79b9bbb9dd95d },\n    },\n    {\n        { 0x17dae8e9f7374, 0x719f76102da33, 0x5117c2a80ca8b, 0x41a66b65d0936, 0x1ba811460accb },\n        { 0x355406a3126c2, 0x50d1918727d76, 0x6e5ea0b498e0e, 0x0a3b6063214f2, 0x5065f158c9fd2 },\n        { 0x169fb0c429954, 0x59aedd9ecee10, 0x39916eb851802, 0x57917555cc538, 0x3981f39e58a4f },\n    },\n    {\n        { 0x5dfa56de66fde, 0x0058809075908, 0x6d3d8cb854a94, 0x5b2f4e970b1e3, 0x30f4452edcbc1 },\n        { 0x38a7559230a93, 0x52c1cde8ba31f, 0x2a4f2d4745a3d, 0x07e9d42d4a28a, 0x38dc083705acd },\n        { 0x52782c5759740, 0x53f3397d990ad, 0x3a939c7e84d15, 0x234c4227e39e0, 0x632d9a1a593f2 },\n    },\n    {\n        { 0x1fd11ed0c84a7, 0x021b3ed2757e1, 0x73e1de58fc1c6, 0x5d110c84616ab, 0x3a5a7df28af64 },\n        { 0x36b15b807cba6, 0x3f78a9e1afed7, 0x0a59c2c608f1f, 0x52bdd8ecb81b7, 0x0b24f48847ed4 },\n        { 0x2d4be511beac7, 0x6bda4d99e5b9b, 0x17e6996914e01, 0x7b1f0ce7fcf80, 0x34fcf74475481 },\n    },\n    {\n        { 0x31dab78cfaa98, 0x4e3216e5e54b7, 0x249823973b689, 0x2584984e48885, 0x0119a3042fb37 },\n        { 0x7e04c789767ca, 0x1671b28cfb832, 0x7e57ea2e1c537, 0x1fbaaef444141, 0x3d3bdc164dfa6 },\n        { 0x2d89ce8c2177d, 0x6cd12ba182cf4, 0x20a8ac19a7697, 0x539fab2cc72d9, 0x56c088f1ede20 },\n    },\n    {\n        { 0x35fac24f38f02, 0x7d75c6197ab03, 0x33e4bc2a42fa7, 0x1c7cd10b48145, 0x038b7ea483590 },\n        { 0x53d1110a86e17, 0x6416eb65f466d, 0x41ca6235fce20, 0x5c3fc8a99bb12, 0x09674c6b99108 },\n        { 0x6f82199316ff8, 0x05d54f1a9f3e9, 0x3bcc5d0bd274a, 0x5b284b8d2d5ad, 0x6e5e31025969e },\n    },\n    {\n        { 0x4fb0e63066222, 0x130f59747e660, 0x041868fecd41a, 0x3105e8c923bc6, 0x3058ad43d1838 },\n        { 0x462f587e593fb, 0x3d94ba7ce362d, 0x330f9b52667b7, 0x5d45a48e0f00a, 0x08f5114789a8d },\n        { 0x40ffde57663d0, 0x71445d4c20647, 0x2653e68170f7c, 0x64cdee3c55ed6, 0x26549fa4efe3d },\n    },\n},\n{\n    {\n        { 0x68549af3f666e, 0x09e2941d4bb68, 0x2e8311f5dff3c, 0x6429ef91ffbd2, 0x3a10dfe132ce3 },\n        { 0x55a461e6bf9d6, 0x78eeef4b02e83, 0x1d34f648c16cf, 0x07fea2aba5132, 0x1926e1dc6401e },\n        { 0x74e8aea17cea0, 0x0c743f83fbc0f, 0x7cb03c4bf5455, 0x68a8ba9917e98, 0x1fa1d01d861e5 },\n    },\n    {\n        { 0x4ac00d1df94ab, 0x3ba2101bd271b, 0x7578988b9c4af, 0x0f2bf89f49f7e, 0x73fced18ee9a0 },\n        { 0x055947d599832, 0x346fe2aa41990, 0x0164c8079195b, 0x799ccfb7bba27, 0x773563bc6a75c },\n        { 0x1e90863139cb3, 0x4f8b407d9a0d6, 0x58e24ca924f69, 0x7a246bbe76456, 0x1f426b701b864 },\n    },\n    {\n        { 0x635c891a12552, 0x26aebd38ede2f, 0x66dc8faddae05, 0x21c7d41a03786, 0x0b76bb1b3fa7e },\n        { 0x1264c41911c01, 0x702f44584bdf9, 0x43c511fc68ede, 0x0482c3aed35f9, 0x4e1af5271d31b },\n        { 0x0c1f97f92939b, 0x17a88956dc117, 0x6ee005ef99dc7, 0x4aa9172b231cc, 0x7b6dd61eb772a },\n    },\n    {\n        { 0x0abf9ab01d2c7, 0x3880287630ae6, 0x32eca045beddb, 0x57f43365f32d0, 0x53fa9b659bff6 },\n        { 0x5c1e850f33d92, 0x1ec119ab9f6f5, 0x7f16f6de663e9, 0x7a7d6cb16dec6, 0x703e9bceaf1d2 },\n        { 0x4c8e994885455, 0x4ccb5da9cad82, 0x3596bc610e975, 0x7a80c0ddb9f5e, 0x398d93e5c4c61 },\n    },\n    {\n        { 0x77c60d2e7e3f2, 0x4061051763870, 0x67bc4e0ecd2aa, 0x2bb941f1373b9, 0x699c9c9002c30 },\n        { 0x3d16733e248f3, 0x0e2b7e14be389, 0x42c0ddaf6784a, 0x589ea1fc67850, 0x53b09b5ddf191 },\n        { 0x6a7235946f1cc, 0x6b99cbb2fbe60, 0x6d3a5d6485c62, 0x4839466e923c0, 0x51caf30c6fcdd },\n    },\n    {\n        { 0x2f99a18ac54c7, 0x398a39661ee6f, 0x384331e40cde3, 0x4cd15c4de19a6, 0x12ae29c189f8e },\n        { 0x3a7427674e00a, 0x6142f4f7e74c1, 0x4cc93318c3a15, 0x6d51bac2b1ee7, 0x5504aa292383f },\n        { 0x6c0cb1f0d01cf, 0x187469ef5d533, 0x27138883747bf, 0x2f52ae53a90e8, 0x5fd14fe958eba },\n    },\n    {\n        { 0x2fe5ebf93cb8e, 0x226da8acbe788, 0x10883a2fb7ea1, 0x094707842cf44, 0x7dd73f960725d },\n        { 0x42ddf2845ab2c, 0x6214ffd3276bb, 0x00b8d181a5246, 0x268a6d579eb20, 0x093ff26e58647 },\n        { 0x524fe68059829, 0x65b75e47cb621, 0x15eb0a5d5cc19, 0x05209b3929d5a, 0x2f59bcbc86b47 },\n    },\n    {\n        { 0x1d560b691c301, 0x7f5bafce3ce08, 0x4cd561614806c, 0x4588b6170b188, 0x2aa55e3d01082 },\n        { 0x47d429917135f, 0x3eacfa07af070, 0x1deab46b46e44, 0x7a53f3ba46cdf, 0x5458b42e2e51a },\n        { 0x192e60c07444f, 0x5ae8843a21daa, 0x6d721910b1538, 0x3321a95a6417e, 0x13e9004a8a768 },\n    },\n},\n{\n    {\n        { 0x600c9193b877f, 0x21c1b8a0d7765, 0x379927fb38ea2, 0x70d7679dbe01b, 0x5f46040898de9 },\n        { 0x58845832fcedb, 0x135cd7f0c6e73, 0x53ffbdfe8e35b, 0x22f195e06e55b, 0x73937e8814bce },\n        { 0x37116297bf48d, 0x45a9e0d069720, 0x25af71aa744ec, 0x41af0cb8aaba3, 0x2cf8a4e891d5e },\n    },\n    {\n        { 0x5487e17d06ba2, 0x3872a032d6596, 0x65e28c09348e0, 0x27b6bb2ce40c2, 0x7a6f7f2891d6a },\n        { 0x3fd8707110f67, 0x26f8716a92db2, 0x1cdaa1b753027, 0x504be58b52661, 0x2049bd6e58252 },\n        { 0x1fd8d6a9aef49, 0x7cb67b7216fa1, 0x67aff53c3b982, 0x20ea610da9628, 0x6011aadfc5459 },\n    },\n    {\n        { 0x6d0c802cbf890, 0x141bfed554c7b, 0x6dbb667ef4263, 0x58f3126857edc, 0x69ce18b779340 },\n        { 0x7926dcf95f83c, 0x42e25120e2bec, 0x63de96df1fa15, 0x4f06b50f3f9cc, 0x6fc5cc1b0b62f },\n        { 0x75528b29879cb, 0x79a8fd2125a3d, 0x27c8d4b746ab8, 0x0f8893f02210c, 0x15596b3ae5710 },\n    },\n    {\n        { 0x731167e5124ca, 0x17b38e8bbe13f, 0x3d55b942f9056, 0x09c1495be913f, 0x3aa4e241afb6d },\n        { 0x739d23f9179a2, 0x632fadbb9e8c4, 0x7c8522bfe0c48, 0x6ed0983ef5aa9, 0x0d2237687b5f4 },\n        { 0x138bf2a3305f5, 0x1f45d24d86598, 0x5274bad2160fe, 0x1b6041d58d12a, 0x32fcaa6e4687a },\n    },\n    {\n        { 0x7a4732787ccdf, 0x11e427c7f0640, 0x03659385f8c64, 0x5f4ead9766bfb, 0x746f6336c2600 },\n        { 0x56e8dc57d9af5, 0x5b3be17be4f78, 0x3bf928cf82f4b, 0x52e55600a6f11, 0x4627e9cefebd6 },\n        { 0x2f345ab6c971c, 0x653286e63e7e9, 0x51061b78a23ad, 0x14999acb54501, 0x7b4917007ed66 },\n    },\n    {\n        { 0x41b28dd53a2dd, 0x37be85f87ea86, 0x74be3d2a85e41, 0x1be87fac96ca6, 0x1d03620fe08cd },\n        { 0x5fb5cab84b064, 0x2513e778285b0, 0x457383125e043, 0x6bda3b56e223d, 0x122ba376f844f },\n        { 0x232cda2b4e554, 0x0422ba30ff840, 0x751e7667b43f5, 0x6261755da5f3e, 0x02c70bf52b68e },\n    },\n    {\n        { 0x532bf458d72e1, 0x40f96e796b59c, 0x22ef79d6f9da3, 0x501ab67beca77, 0x6b0697e3feb43 },\n        { 0x7ec4b5d0b2fbb, 0x200e910595450, 0x742057105715e, 0x2f07022530f60, 0x26334f0a409ef },\n        { 0x0f04adf62a3c0, 0x5e0edb48bb6d9, 0x7c34aa4fbc003, 0x7d74e4e5cac24, 0x1cc37f43441b2 },\n    },\n    {\n        { 0x656f1c9ceaeb9, 0x7031cacad5aec, 0x1308cd0716c57, 0x41c1373941942, 0x3a346f772f196 },\n        { 0x7565a5cc7324f, 0x01ca0d5244a11, 0x116b067418713, 0x0a57d8c55edae, 0x6c6809c103803 },\n        { 0x55112e2da6ac8, 0x6363d0a3dba5a, 0x319c98ba6f40c, 0x2e84b03a36ec7, 0x05911b9f6ef7c },\n    },\n},\n{\n    {\n        { 0x1acf3512eeaef, 0x2639839692a69, 0x669a234830507, 0x68b920c0603d4, 0x555ef9d1c64b2 },\n        { 0x39983f5df0ebb, 0x1ea2589959826, 0x6ce638703cdd6, 0x6311678898505, 0x6b3cecf9aa270 },\n        { 0x770ba3b73bd08, 0x11475f7e186d4, 0x0251bc9892bbc, 0x24eab9bffcc5a, 0x675f4de133817 },\n    },\n    {\n        { 0x7f6d93bdab31d, 0x1f3aca5bfd425, 0x2fa521c1c9760, 0x62180ce27f9cd, 0x60f450b882cd3 },\n        { 0x452036b1782fc, 0x02d95b07681c5, 0x5901cf99205b2, 0x290686e5eecb4, 0x13d99df70164c },\n        { 0x35ec321e5c0ca, 0x13ae337f44029, 0x4008e813f2da7, 0x640272f8e0c3a, 0x1c06de9e55eda },\n    },\n    {\n        { 0x52b40ff6d69aa, 0x31b8809377ffa, 0x536625cd14c2c, 0x516af252e17d1, 0x78096f8e7d32b },\n        { 0x77ad6a33ec4e2, 0x717c5dc11d321, 0x4a114559823e4, 0x306ce50a1e2b1, 0x4cf38a1fec2db },\n        { 0x2aa650dfa5ce7, 0x54916a8f19415, 0x00dc96fe71278, 0x55f2784e63eb8, 0x373cad3a26091 },\n    },\n    {\n        { 0x6a8fb89ddbbad, 0x78c35d5d97e37, 0x66e3674ef2cb2, 0x34347ac53dd8f, 0x21547eda5112a },\n        { 0x4634d82c9f57c, 0x4249268a6d652, 0x6336d687f2ff7, 0x4fe4f4e26d9a0, 0x0040f3d945441 },\n        { 0x5e939fd5986d3, 0x12a2147019bdf, 0x4c466e7d09cb2, 0x6fa5b95d203dd, 0x63550a334a254 },\n    },\n    {\n        { 0x2584572547b49, 0x75c58811c1377, 0x4d3c637cc171b, 0x33d30747d34e3, 0x39a92bafaa7d7 },\n        { 0x7d6edb569cf37, 0x60194a5dc2ca0, 0x5af59745e10a6, 0x7a8f53e004875, 0x3eea62c7daf78 },\n        { 0x4c713e693274e, 0x6ed1b7a6eb3a4, 0x62ace697d8e15, 0x266b8292ab075, 0x68436a0665c9c },\n    },\n    {\n        { 0x6d317e820107c, 0x090815d2ca3ca, 0x03ff1eb1499a1, 0x23960f050e319, 0x5373669c91611 },\n        { 0x235e8202f3f27, 0x44c9f2eb61780, 0x630905b1d7003, 0x4fcc8d274ead1, 0x17b6e7f68ab78 },\n        { 0x014ab9a0e5257, 0x09939567f8ba5, 0x4b47b2a423c82, 0x688d7e57ac42d, 0x1cb4b5a678f87 },\n    },\n    {\n        { 0x4aa62a2a007e7, 0x61e0e38f62d6e, 0x02f888fcc4782, 0x7562b83f21c00, 0x2dc0fd2d82ef6 },\n        { 0x4c06b394afc6c, 0x4931b4bf636cc, 0x72b60d0322378, 0x25127c6818b25, 0x330bca78de743 },\n        { 0x6ff841119744e, 0x2c560e8e49305, 0x7254fefe5a57a, 0x67ae2c560a7df, 0x3c31be1b369f1 },\n    },\n    {\n        { 0x0bc93f9cb4272, 0x3f8f9db73182d, 0x2b235eabae1c4, 0x2ddbf8729551a, 0x41cec1097e7d5 },\n        { 0x4864d08948aee, 0x5d237438df61e, 0x2b285601f7067, 0x25dbcbae6d753, 0x330b61134262d },\n        { 0x619d7a26d808a, 0x3c3b3c2adbef2, 0x6877c9eec7f52, 0x3beb9ebe1b66d, 0x26b44cd91f287 },\n    },\n},\n{\n    {\n        { 0x7f29362730383, 0x7fd7951459c36, 0x7504c512d49e7, 0x087ed7e3bc55f, 0x7deb10149c726 },\n        { 0x048478f387475, 0x69397d9678a3e, 0x67c8156c976f3, 0x2eb4d5589226c, 0x2c709e6c1c10a },\n        { 0x2af6a8766ee7a, 0x08aaa79a1d96c, 0x42f92d59b2fb0, 0x1752c40009c07, 0x08e68e9ff62ce },\n    },\n    {\n        { 0x509d50ab8f2f9, 0x1b8ab247be5e5, 0x5d9b2e6b2e486, 0x4faa5479a1339, 0x4cb13bd738f71 },\n        { 0x5500a4bc130ad, 0x127a17a938695, 0x02a26fa34e36d, 0x584d12e1ecc28, 0x2f1f3f87eeba3 },\n        { 0x48c75e515b64a, 0x75b6952071ef0, 0x5d46d42965406, 0x7746106989f9f, 0x19a1e353c0ae2 },\n    },\n    {\n        { 0x172cdd596bdbd, 0x0731ddf881684, 0x10426d64f8115, 0x71a4fd8a9a3da, 0x736bd3990266a },\n        { 0x47560bafa05c3, 0x418dcabcc2fa3, 0x35991cecf8682, 0x24371a94b8c60, 0x41546b11c20c3 },\n        { 0x32d509334b3b4, 0x16c102cae70aa, 0x1720dd51bf445, 0x5ae662faf9821, 0x412295a2b87fa },\n    },\n    {\n        { 0x55261e293eac6, 0x06426759b65cc, 0x40265ae116a48, 0x6c02304bae5bc, 0x0760bb8d195ad },\n        { 0x19b88f57ed6e9, 0x4cdbf1904a339, 0x42b49cd4e4f2c, 0x71a2e771909d9, 0x14e153ebb52d2 },\n        { 0x61a17cde6818a, 0x53dad34108827, 0x32b32c55c55b6, 0x2f9165f9347a3, 0x6b34be9bc33ac },\n    },\n    {\n        { 0x469656571f2d3, 0x0aa61ce6f423f, 0x3f940d71b27a1, 0x185f19d73d16a, 0x01b9c7b62e6dd },\n        { 0x72f643a78c0b2, 0x3de45c04f9e7b, 0x706d68d30fa5c, 0x696f63e8e2f24, 0x2012c18f0922d },\n        { 0x355e55ac89d29, 0x3e8b414ec7101, 0x39db07c520c90, 0x6f41e9b77efe1, 0x08af5b784e4ba },\n    },\n    {\n        { 0x314d289cc2c4b, 0x23450e2f1bc4e, 0x0cd93392f92f4, 0x1370c6a946b7d, 0x6423c1d5afd98 },\n        { 0x499dc881f2533, 0x34ef26476c506, 0x4d107d2741497, 0x346c4bd6efdb3, 0x32b79d71163a1 },\n        { 0x5f8d9edfcb36a, 0x1e6e8dcbf3990, 0x7974f348af30a, 0x6e6724ef19c7c, 0x480a5efbc13e2 },\n    },\n    {\n        { 0x14ce442ce221f, 0x18980a72516cc, 0x072f80db86677, 0x703331fda526e, 0x24b31d47691c8 },\n        { 0x1e70b01622071, 0x1f163b5f8a16a, 0x56aaf341ad417, 0x7989635d830f7, 0x47aa27600cb7b },\n        { 0x41eedc015f8c3, 0x7cf8d27ef854a, 0x289e3584693f9, 0x04a7857b309a7, 0x545b585d14dda },\n    },\n    {\n        { 0x4e4d0e3b321e1, 0x7451fe3d2ac40, 0x666f678eea98d, 0x038858667fead, 0x4d22dc3e64c8d },\n        { 0x7275ea0d43a0f, 0x681137dd7ccf7, 0x1e79cbab79a38, 0x22a214489a66a, 0x0f62f9c332ba5 },\n        { 0x46589d63b5f39, 0x7eaf979ec3f96, 0x4ebe81572b9a8, 0x21b7f5d61694a, 0x1c0fa01a36371 },\n    },\n},\n{\n    {\n        { 0x02b0e8c936a50, 0x6b83b58b6cd21, 0x37ed8d3e72680, 0x0a037db9f2a62, 0x4005419b1d2bc },\n        { 0x604b622943dff, 0x1c899f6741a58, 0x60219e2f232fb, 0x35fae92a7f9cb, 0x0fa3614f3b1ca },\n        { 0x3febdb9be82f0, 0x5e74895921400, 0x553ea38822706, 0x5a17c24cfc88c, 0x1fba218aef40a },\n    },\n    {\n        { 0x657043e7b0194, 0x5c11b55efe9e7, 0x7737bc6a074fb, 0x0eae41ce355cc, 0x6c535d13ff776 },\n        { 0x49448fac8f53e, 0x34f74c6e8356a, 0x0ad780607dba2, 0x7213a7eb63eb6, 0x392e3acaa8c86 },\n        { 0x534e93e8a35af, 0x08b10fd02c997, 0x26ac2acb81e05, 0x09d8c98ce3b79, 0x25e17fe4d50ac },\n    },\n    {\n        { 0x77ff576f121a7, 0x4e5f9b0fc722b, 0x46f949b0d28c8, 0x4cde65d17ef26, 0x6bba828f89698 },\n        { 0x09bd71e04f676, 0x25ac841f2a145, 0x1a47eac823871, 0x1a8a8c36c581a, 0x255751442a9fb },\n        { 0x1bc6690fe3901, 0x314132f5abc5a, 0x611835132d528, 0x5f24b8eb48a57, 0x559d504f7f6b7 },\n    },\n    {\n        { 0x091e7f6d266fd, 0x36060ef037389, 0x18788ec1d1286, 0x287441c478eb0, 0x123ea6a3354bd },\n        { 0x38378b3eb54d5, 0x4d4aaa78f94ee, 0x4a002e875a74d, 0x10b851367b17c, 0x01ab12d5807e3 },\n        { 0x5189041e32d96, 0x05b062b090231, 0x0c91766e7b78f, 0x0aa0f55a138ec, 0x4a3961e2c918a },\n    },\n    {\n        { 0x7d644f3233f1e, 0x1c69f9e02c064, 0x36ae5e5266898, 0x08fc1dad38b79, 0x68aceead9bd41 },\n        { 0x43be0f8e6bba0, 0x68fdffc614e3b, 0x4e91dab5b3be0, 0x3b1d4c9212ff0, 0x2cd6bce3fb1db },\n        { 0x4c90ef3d7c210, 0x496f5a0818716, 0x79cf88cc239b8, 0x2cb9c306cf8db, 0x595760d5b508f },\n    },\n    {\n        { 0x2cbebfd022790, 0x0b8822aec1105, 0x4d1cfd226bccc, 0x515b2fa4971be, 0x2cb2c5df54515 },\n        { 0x1bfe104aa6397, 0x11494ff996c25, 0x64251623e5800, 0x0d49fc5e044be, 0x709fa43edcb29 },\n        { 0x25d8c63fd2aca, 0x4c5cd29dffd61, 0x32ec0eb48af05, 0x18f9391f9b77c, 0x70f029ecf0c81 },\n    },\n    {\n        { 0x2afaa5e10b0b9, 0x61de08355254d, 0x0eb587de3c28d, 0x4f0bb9f7dbbd5, 0x44eca5a2a74bd },\n        { 0x307b32eed3e33, 0x6748ab03ce8c2, 0x57c0d9ab810bc, 0x42c64a224e98c, 0x0b7d5d8a6c314 },\n        { 0x448327b95d543, 0x0146681e3a4ba, 0x38714adc34e0c, 0x4f26f0e298e30, 0x272224512c7de },\n    },\n    {\n        { 0x3bb8a42a975fc, 0x6f2d5b46b17ef, 0x7b6a9223170e5, 0x053713fe3b7e6, 0x19735fd7f6bc2 },\n        { 0x492af49c5342e, 0x2365cdf5a0357, 0x32138a7ffbb60, 0x2a1f7d14646fe, 0x11b5df18a44cc },\n        { 0x390d042c84266, 0x1efe32a8fdc75, 0x6925ee7ae1238, 0x4af9281d0e832, 0x0fef911191df8 },\n    },\n},\n};\n#else\n/* base[i][j] = (j+1)*256^i*B */\nstatic const ge_precomp base[32][8] = {\n{\n {\n  { 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 },\n  { -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 },\n  { -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 },\n },\n {\n  { -12815894,-12976347,-21581243,11784320,-25355658,-2750717,-11717903,-3814571,-358445,-10211303 },\n  { -21703237,6903825,27185491,6451973,-29577724,-9554005,-15616551,11189268,-26829678,-5319081 },\n  { 26966642,11152617,32442495,15396054,14353839,-12752335,-3128826,-9541118,-15472047,-4166697 },\n },\n {\n  { 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 },\n  { 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 },\n  { 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 },\n },\n {\n  { -17036878,13921892,10945806,-6033431,27105052,-16084379,-28926210,15006023,3284568,-6276540 },\n  { 23599295,-8306047,-11193664,-7687416,13236774,10506355,7464579,9656445,13059162,10374397 },\n  { 7798556,16710257,3033922,2874086,28997861,2835604,32406664,-3839045,-641708,-101325 },\n },\n {\n  { 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 },\n  { 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 },\n  { 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 },\n },\n {\n  { -15371964,-12862754,32573250,4720197,-26436522,5875511,-19188627,-15224819,-9818940,-12085777 },\n  { -8549212,109983,15149363,2178705,22900618,4543417,3044240,-15689887,1762328,14866737 },\n  { -18199695,-15951423,-10473290,1707278,-17185920,3916101,-28236412,3959421,27914454,4383652 },\n },\n {\n  { 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 },\n  { -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 },\n  { 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 },\n },\n {\n  { 14499471,-2729599,-33191113,-4254652,28494862,14271267,30290735,10876454,-33154098,2381726 },\n  { -7195431,-2655363,-14730155,462251,-27724326,3941372,-6236617,3696005,-32300832,15351955 },\n  { 27431194,8222322,16448760,-3907995,-18707002,11938355,-32961401,-2970515,29551813,10109425 },\n },\n},\n{\n {\n  { -13657040,-13155431,-31283750,11777098,21447386,6519384,-2378284,-1627556,10092783,-4764171 },\n  { 27939166,14210322,4677035,16277044,-22964462,-12398139,-32508754,12005538,-17810127,12803510 },\n  { 17228999,-15661624,-1233527,300140,-1224870,-11714777,30364213,-9038194,18016357,4397660 },\n },\n {\n  { -10958843,-7690207,4776341,-14954238,27850028,-15602212,-26619106,14544525,-17477504,982639 },\n  { 29253598,15796703,-2863982,-9908884,10057023,3163536,7332899,-4120128,-21047696,9934963 },\n  { 5793303,16271923,-24131614,-10116404,29188560,1206517,-14747930,4559895,-30123922,-10897950 },\n },\n {\n  { -27643952,-11493006,16282657,-11036493,28414021,-15012264,24191034,4541697,-13338309,5500568 },\n  { 12650548,-1497113,9052871,11355358,-17680037,-8400164,-17430592,12264343,10874051,13524335 },\n  { 25556948,-3045990,714651,2510400,23394682,-10415330,33119038,5080568,-22528059,5376628 },\n },\n {\n  { -26088264,-4011052,-17013699,-3537628,-6726793,1920897,-22321305,-9447443,4535768,1569007 },\n  { -2255422,14606630,-21692440,-8039818,28430649,8775819,-30494562,3044290,31848280,12543772 },\n  { -22028579,2943893,-31857513,6777306,13784462,-4292203,-27377195,-2062731,7718482,14474653 },\n },\n {\n  { 2385315,2454213,-22631320,46603,-4437935,-15680415,656965,-7236665,24316168,-5253567 },\n  { 13741529,10911568,-33233417,-8603737,-20177830,-1033297,33040651,-13424532,-20729456,8321686 },\n  { 21060490,-2212744,15712757,-4336099,1639040,10656336,23845965,-11874838,-9984458,608372 },\n },\n {\n  { -13672732,-15087586,-10889693,-7557059,-6036909,11305547,1123968,-6780577,27229399,23887 },\n  { -23244140,-294205,-11744728,14712571,-29465699,-2029617,12797024,-6440308,-1633405,16678954 },\n  { -29500620,4770662,-16054387,14001338,7830047,9564805,-1508144,-4795045,-17169265,4904953 },\n },\n {\n  { 24059557,14617003,19037157,-15039908,19766093,-14906429,5169211,16191880,2128236,-4326833 },\n  { -16981152,4124966,-8540610,-10653797,30336522,-14105247,-29806336,916033,-6882542,-2986532 },\n  { -22630907,12419372,-7134229,-7473371,-16478904,16739175,285431,2763829,15736322,4143876 },\n },\n {\n  { 2379352,11839345,-4110402,-5988665,11274298,794957,212801,-14594663,23527084,-16458268 },\n  { 33431127,-11130478,-17838966,-15626900,8909499,8376530,-32625340,4087881,-15188911,-14416214 },\n  { 1767683,7197987,-13205226,-2022635,-13091350,448826,5799055,4357868,-4774191,-16323038 },\n },\n},\n{\n {\n  { 6721966,13833823,-23523388,-1551314,26354293,-11863321,23365147,-3949732,7390890,2759800 },\n  { 4409041,2052381,23373853,10530217,7676779,-12885954,21302353,-4264057,1244380,-12919645 },\n  { -4421239,7169619,4982368,-2957590,30256825,-2777540,14086413,9208236,15886429,16489664 },\n },\n {\n  { 1996075,10375649,14346367,13311202,-6874135,-16438411,-13693198,398369,-30606455,-712933 },\n  { -25307465,9795880,-2777414,14878809,-33531835,14780363,13348553,12076947,-30836462,5113182 },\n  { -17770784,11797796,31950843,13929123,-25888302,12288344,-30341101,-7336386,13847711,5387222 },\n },\n {\n  { -18582163,-3416217,17824843,-2340966,22744343,-10442611,8763061,3617786,-19600662,10370991 },\n  { 20246567,-14369378,22358229,-543712,18507283,-10413996,14554437,-8746092,32232924,16763880 },\n  { 9648505,10094563,26416693,14745928,-30374318,-6472621,11094161,15689506,3140038,-16510092 },\n },\n {\n  { -16160072,5472695,31895588,4744994,8823515,10365685,-27224800,9448613,-28774454,366295 },\n  { 19153450,11523972,-11096490,-6503142,-24647631,5420647,28344573,8041113,719605,11671788 },\n  { 8678025,2694440,-6808014,2517372,4964326,11152271,-15432916,-15266516,27000813,-10195553 },\n },\n {\n  { -15157904,7134312,8639287,-2814877,-7235688,10421742,564065,5336097,6750977,-14521026 },\n  { 11836410,-3979488,26297894,16080799,23455045,15735944,1695823,-8819122,8169720,16220347 },\n  { -18115838,8653647,17578566,-6092619,-8025777,-16012763,-11144307,-2627664,-5990708,-14166033 },\n },\n {\n  { -23308498,-10968312,15213228,-10081214,-30853605,-11050004,27884329,2847284,2655861,1738395 },\n  { -27537433,-14253021,-25336301,-8002780,-9370762,8129821,21651608,-3239336,-19087449,-11005278 },\n  { 1533110,3437855,23735889,459276,29970501,11335377,26030092,5821408,10478196,8544890 },\n },\n {\n  { 32173121,-16129311,24896207,3921497,22579056,-3410854,19270449,12217473,17789017,-3395995 },\n  { -30552961,-2228401,-15578829,-10147201,13243889,517024,15479401,-3853233,30460520,1052596 },\n  { -11614875,13323618,32618793,8175907,-15230173,12596687,27491595,-4612359,3179268,-9478891 },\n },\n {\n  { 31947069,-14366651,-4640583,-15339921,-15125977,-6039709,-14756777,-16411740,19072640,-9511060 },\n  { 11685058,11822410,3158003,-13952594,33402194,-4165066,5977896,-5215017,473099,5040608 },\n  { -20290863,8198642,-27410132,11602123,1290375,-2799760,28326862,1721092,-19558642,-3131606 },\n },\n},\n{\n {\n  { 7881532,10687937,7578723,7738378,-18951012,-2553952,21820786,8076149,-27868496,11538389 },\n  { -19935666,3899861,18283497,-6801568,-15728660,-11249211,8754525,7446702,-5676054,5797016 },\n  { -11295600,-3793569,-15782110,-7964573,12708869,-8456199,2014099,-9050574,-2369172,-5877341 },\n },\n {\n  { -22472376,-11568741,-27682020,1146375,18956691,16640559,1192730,-3714199,15123619,10811505 },\n  { 14352098,-3419715,-18942044,10822655,32750596,4699007,-70363,15776356,-28886779,-11974553 },\n  { -28241164,-8072475,-4978962,-5315317,29416931,1847569,-20654173,-16484855,4714547,-9600655 },\n },\n {\n  { 15200332,8368572,19679101,15970074,-31872674,1959451,24611599,-4543832,-11745876,12340220 },\n  { 12876937,-10480056,33134381,6590940,-6307776,14872440,9613953,8241152,15370987,9608631 },\n  { -4143277,-12014408,8446281,-391603,4407738,13629032,-7724868,15866074,-28210621,-8814099 },\n },\n {\n  { 26660628,-15677655,8393734,358047,-7401291,992988,-23904233,858697,20571223,8420556 },\n  { 14620715,13067227,-15447274,8264467,14106269,15080814,33531827,12516406,-21574435,-12476749 },\n  { 236881,10476226,57258,-14677024,6472998,2466984,17258519,7256740,8791136,15069930 },\n },\n {\n  { 1276410,-9371918,22949635,-16322807,-23493039,-5702186,14711875,4874229,-30663140,-2331391 },\n  { 5855666,4990204,-13711848,7294284,-7804282,1924647,-1423175,-7912378,-33069337,9234253 },\n  { 20590503,-9018988,31529744,-7352666,-2706834,10650548,31559055,-11609587,18979186,13396066 },\n },\n {\n  { 24474287,4968103,22267082,4407354,24063882,-8325180,-18816887,13594782,33514650,7021958 },\n  { -11566906,-6565505,-21365085,15928892,-26158305,4315421,-25948728,-3916677,-21480480,12868082 },\n  { -28635013,13504661,19988037,-2132761,21078225,6443208,-21446107,2244500,-12455797,-8089383 },\n },\n {\n  { -30595528,13793479,-5852820,319136,-25723172,-6263899,33086546,8957937,-15233648,5540521 },\n  { -11630176,-11503902,-8119500,-7643073,2620056,1022908,-23710744,-1568984,-16128528,-14962807 },\n  { 23152971,775386,27395463,14006635,-9701118,4649512,1689819,892185,-11513277,-15205948 },\n },\n {\n  { 9770129,9586738,26496094,4324120,1556511,-3550024,27453819,4763127,-19179614,5867134 },\n  { -32765025,1927590,31726409,-4753295,23962434,-16019500,27846559,5931263,-29749703,-16108455 },\n  { 27461885,-2977536,22380810,1815854,-23033753,-3031938,7283490,-15148073,-19526700,7734629 },\n },\n},\n{\n {\n  { -8010264,-9590817,-11120403,6196038,29344158,-13430885,7585295,-3176626,18549497,15302069 },\n  { -32658337,-6171222,-7672793,-11051681,6258878,13504381,10458790,-6418461,-8872242,8424746 },\n  { 24687205,8613276,-30667046,-3233545,1863892,-1830544,19206234,7134917,-11284482,-828919 },\n },\n {\n  { 11334899,-9218022,8025293,12707519,17523892,-10476071,10243738,-14685461,-5066034,16498837 },\n  { 8911542,6887158,-9584260,-6958590,11145641,-9543680,17303925,-14124238,6536641,10543906 },\n  { -28946384,15479763,-17466835,568876,-1497683,11223454,-2669190,-16625574,-27235709,8876771 },\n },\n {\n  { -25742899,-12566864,-15649966,-846607,-33026686,-796288,-33481822,15824474,-604426,-9039817 },\n  { 10330056,70051,7957388,-9002667,9764902,15609756,27698697,-4890037,1657394,3084098 },\n  { 10477963,-7470260,12119566,-13250805,29016247,-5365589,31280319,14396151,-30233575,15272409 },\n },\n {\n  { -12288309,3169463,28813183,16658753,25116432,-5630466,-25173957,-12636138,-25014757,1950504 },\n  { -26180358,9489187,11053416,-14746161,-31053720,5825630,-8384306,-8767532,15341279,8373727 },\n  { 28685821,7759505,-14378516,-12002860,-31971820,4079242,298136,-10232602,-2878207,15190420 },\n },\n {\n  { -32932876,13806336,-14337485,-15794431,-24004620,10940928,8669718,2742393,-26033313,-6875003 },\n  { -1580388,-11729417,-25979658,-11445023,-17411874,-10912854,9291594,-16247779,-12154742,6048605 },\n  { -30305315,14843444,1539301,11864366,20201677,1900163,13934231,5128323,11213262,9168384 },\n },\n {\n  { -26280513,11007847,19408960,-940758,-18592965,-4328580,-5088060,-11105150,20470157,-16398701 },\n  { -23136053,9282192,14855179,-15390078,-7362815,-14408560,-22783952,14461608,14042978,5230683 },\n  { 29969567,-2741594,-16711867,-8552442,9175486,-2468974,21556951,3506042,-5933891,-12449708 },\n },\n {\n  { -3144746,8744661,19704003,4581278,-20430686,6830683,-21284170,8971513,-28539189,15326563 },\n  { -19464629,10110288,-17262528,-3503892,-23500387,1355669,-15523050,15300988,-20514118,9168260 },\n  { -5353335,4488613,-23803248,16314347,7780487,-15638939,-28948358,9601605,33087103,-9011387 },\n },\n {\n  { -19443170,-15512900,-20797467,-12445323,-29824447,10229461,-27444329,-15000531,-5996870,15664672 },\n  { 23294591,-16632613,-22650781,-8470978,27844204,11461195,13099750,-2460356,18151676,13417686 },\n  { -24722913,-4176517,-31150679,5988919,-26858785,6685065,1661597,-12551441,15271676,-15452665 },\n },\n},\n{\n {\n  { 11433042,-13228665,8239631,-5279517,-1985436,-725718,-18698764,2167544,-6921301,-13440182 },\n  { -31436171,15575146,30436815,12192228,-22463353,9395379,-9917708,-8638997,12215110,12028277 },\n  { 14098400,6555944,23007258,5757252,-15427832,-12950502,30123440,4617780,-16900089,-655628 },\n },\n {\n  { -4026201,-15240835,11893168,13718664,-14809462,1847385,-15819999,10154009,23973261,-12684474 },\n  { -26531820,-3695990,-1908898,2534301,-31870557,-16550355,18341390,-11419951,32013174,-10103539 },\n  { -25479301,10876443,-11771086,-14625140,-12369567,1838104,21911214,6354752,4425632,-837822 },\n },\n {\n  { -10433389,-14612966,22229858,-3091047,-13191166,776729,-17415375,-12020462,4725005,14044970 },\n  { 19268650,-7304421,1555349,8692754,-21474059,-9910664,6347390,-1411784,-19522291,-16109756 },\n  { -24864089,12986008,-10898878,-5558584,-11312371,-148526,19541418,8180106,9282262,10282508 },\n },\n {\n  { -26205082,4428547,-8661196,-13194263,4098402,-14165257,15522535,8372215,5542595,-10702683 },\n  { -10562541,14895633,26814552,-16673850,-17480754,-2489360,-2781891,6993761,-18093885,10114655 },\n  { -20107055,-929418,31422704,10427861,-7110749,6150669,-29091755,-11529146,25953725,-106158 },\n },\n {\n  { -4234397,-8039292,-9119125,3046000,2101609,-12607294,19390020,6094296,-3315279,12831125 },\n  { -15998678,7578152,5310217,14408357,-33548620,-224739,31575954,6326196,7381791,-2421839 },\n  { -20902779,3296811,24736065,-16328389,18374254,7318640,6295303,8082724,-15362489,12339664 },\n },\n {\n  { 27724736,2291157,6088201,-14184798,1792727,5857634,13848414,15768922,25091167,14856294 },\n  { -18866652,8331043,24373479,8541013,-701998,-9269457,12927300,-12695493,-22182473,-9012899 },\n  { -11423429,-5421590,11632845,3405020,30536730,-11674039,-27260765,13866390,30146206,9142070 },\n },\n {\n  { 3924129,-15307516,-13817122,-10054960,12291820,-668366,-27702774,9326384,-8237858,4171294 },\n  { -15921940,16037937,6713787,16606682,-21612135,2790944,26396185,3731949,345228,-5462949 },\n  { -21327538,13448259,25284571,1143661,20614966,-8849387,2031539,-12391231,-16253183,-13582083 },\n },\n {\n  { 31016211,-16722429,26371392,-14451233,-5027349,14854137,17477601,3842657,28012650,-16405420 },\n  { -5075835,9368966,-8562079,-4600902,-15249953,6970560,-9189873,16292057,-8867157,3507940 },\n  { 29439664,3537914,23333589,6997794,-17555561,-11018068,-15209202,-15051267,-9164929,6580396 },\n },\n},\n{\n {\n  { -12185861,-7679788,16438269,10826160,-8696817,-6235611,17860444,-9273846,-2095802,9304567 },\n  { 20714564,-4336911,29088195,7406487,11426967,-5095705,14792667,-14608617,5289421,-477127 },\n  { -16665533,-10650790,-6160345,-13305760,9192020,-1802462,17271490,12349094,26939669,-3752294 },\n },\n {\n  { -12889898,9373458,31595848,16374215,21471720,13221525,-27283495,-12348559,-3698806,117887 },\n  { 22263325,-6560050,3984570,-11174646,-15114008,-566785,28311253,5358056,-23319780,541964 },\n  { 16259219,3261970,2309254,-15534474,-16885711,-4581916,24134070,-16705829,-13337066,-13552195 },\n },\n {\n  { 9378160,-13140186,-22845982,-12745264,28198281,-7244098,-2399684,-717351,690426,14876244 },\n  { 24977353,-314384,-8223969,-13465086,28432343,-1176353,-13068804,-12297348,-22380984,6618999 },\n  { -1538174,11685646,12944378,13682314,-24389511,-14413193,8044829,-13817328,32239829,-5652762 },\n },\n {\n  { -18603066,4762990,-926250,8885304,-28412480,-3187315,9781647,-10350059,32779359,5095274 },\n  { -33008130,-5214506,-32264887,-3685216,9460461,-9327423,-24601656,14506724,21639561,-2630236 },\n  { -16400943,-13112215,25239338,15531969,3987758,-4499318,-1289502,-6863535,17874574,558605 },\n },\n {\n  { -13600129,10240081,9171883,16131053,-20869254,9599700,33499487,5080151,2085892,5119761 },\n  { -22205145,-2519528,-16381601,414691,-25019550,2170430,30634760,-8363614,-31999993,-5759884 },\n  { -6845704,15791202,8550074,-1312654,29928809,-12092256,27534430,-7192145,-22351378,12961482 },\n },\n {\n  { -24492060,-9570771,10368194,11582341,-23397293,-2245287,16533930,8206996,-30194652,-5159638 },\n  { -11121496,-3382234,2307366,6362031,-135455,8868177,-16835630,7031275,7589640,8945490 },\n  { -32152748,8917967,6661220,-11677616,-1192060,-15793393,7251489,-11182180,24099109,-14456170 },\n },\n {\n  { 5019558,-7907470,4244127,-14714356,-26933272,6453165,-19118182,-13289025,-6231896,-10280736 },\n  { 10853594,10721687,26480089,5861829,-22995819,1972175,-1866647,-10557898,-3363451,-6441124 },\n  { -17002408,5906790,221599,-6563147,7828208,-13248918,24362661,-2008168,-13866408,7421392 },\n },\n {\n  { 8139927,-6546497,32257646,-5890546,30375719,1886181,-21175108,15441252,28826358,-4123029 },\n  { 6267086,9695052,7709135,-16603597,-32869068,-1886135,14795160,-7840124,13746021,-1742048 },\n  { 28584902,7787108,-6732942,-15050729,22846041,-7571236,-3181936,-363524,4771362,-8419958 },\n },\n},\n{\n {\n  { 24949256,6376279,-27466481,-8174608,-18646154,-9930606,33543569,-12141695,3569627,11342593 },\n  { 26514989,4740088,27912651,3697550,19331575,-11472339,6809886,4608608,7325975,-14801071 },\n  { -11618399,-14554430,-24321212,7655128,-1369274,5214312,-27400540,10258390,-17646694,-8186692 },\n },\n {\n  { 11431204,15823007,26570245,14329124,18029990,4796082,-31446179,15580664,9280358,-3973687 },\n  { -160783,-10326257,-22855316,-4304997,-20861367,-13621002,-32810901,-11181622,-15545091,4387441 },\n  { -20799378,12194512,3937617,-5805892,-27154820,9340370,-24513992,8548137,20617071,-7482001 },\n },\n {\n  { -938825,-3930586,-8714311,16124718,24603125,-6225393,-13775352,-11875822,24345683,10325460 },\n  { -19855277,-1568885,-22202708,8714034,14007766,6928528,16318175,-1010689,4766743,3552007 },\n  { -21751364,-16730916,1351763,-803421,-4009670,3950935,3217514,14481909,10988822,-3994762 },\n },\n {\n  { 15564307,-14311570,3101243,5684148,30446780,-8051356,12677127,-6505343,-8295852,13296005 },\n  { -9442290,6624296,-30298964,-11913677,-4670981,-2057379,31521204,9614054,-30000824,12074674 },\n  { 4771191,-135239,14290749,-13089852,27992298,14998318,-1413936,-1556716,29832613,-16391035 },\n },\n {\n  { 7064884,-7541174,-19161962,-5067537,-18891269,-2912736,25825242,5293297,-27122660,13101590 },\n  { -2298563,2439670,-7466610,1719965,-27267541,-16328445,32512469,-5317593,-30356070,-4190957 },\n  { -30006540,10162316,-33180176,3981723,-16482138,-13070044,14413974,9515896,19568978,9628812 },\n },\n {\n  { 33053803,199357,15894591,1583059,27380243,-4580435,-17838894,-6106839,-6291786,3437740 },\n  { -18978877,3884493,19469877,12726490,15913552,13614290,-22961733,70104,7463304,4176122 },\n  { -27124001,10659917,11482427,-16070381,12771467,-6635117,-32719404,-5322751,24216882,5944158 },\n },\n {\n  { 8894125,7450974,-2664149,-9765752,-28080517,-12389115,19345746,14680796,11632993,5847885 },\n  { 26942781,-2315317,9129564,-4906607,26024105,11769399,-11518837,6367194,-9727230,4782140 },\n  { 19916461,-4828410,-22910704,-11414391,25606324,-5972441,33253853,8220911,6358847,-1873857 },\n },\n {\n  { 801428,-2081702,16569428,11065167,29875704,96627,7908388,-4480480,-13538503,1387155 },\n  { 19646058,5720633,-11416706,12814209,11607948,12749789,14147075,15156355,-21866831,11835260 },\n  { 19299512,1155910,28703737,14890794,2925026,7269399,26121523,15467869,-26560550,5052483 },\n },\n},\n{\n {\n  { -3017432,10058206,1980837,3964243,22160966,12322533,-6431123,-12618185,12228557,-7003677 },\n  { 32944382,14922211,-22844894,5188528,21913450,-8719943,4001465,13238564,-6114803,8653815 },\n  { 22865569,-4652735,27603668,-12545395,14348958,8234005,24808405,5719875,28483275,2841751 },\n },\n {\n  { -16420968,-1113305,-327719,-12107856,21886282,-15552774,-1887966,-315658,19932058,-12739203 },\n  { -11656086,10087521,-8864888,-5536143,-19278573,-3055912,3999228,13239134,-4777469,-13910208 },\n  { 1382174,-11694719,17266790,9194690,-13324356,9720081,20403944,11284705,-14013818,3093230 },\n },\n {\n  { 16650921,-11037932,-1064178,1570629,-8329746,7352753,-302424,16271225,-24049421,-6691850 },\n  { -21911077,-5927941,-4611316,-5560156,-31744103,-10785293,24123614,15193618,-21652117,-16739389 },\n  { -9935934,-4289447,-25279823,4372842,2087473,10399484,31870908,14690798,17361620,11864968 },\n },\n {\n  { -11307610,6210372,13206574,5806320,-29017692,-13967200,-12331205,-7486601,-25578460,-16240689 },\n  { 14668462,-12270235,26039039,15305210,25515617,4542480,10453892,6577524,9145645,-6443880 },\n  { 5974874,3053895,-9433049,-10385191,-31865124,3225009,-7972642,3936128,-5652273,-3050304 },\n },\n {\n  { 30625386,-4729400,-25555961,-12792866,-20484575,7695099,17097188,-16303496,-27999779,1803632 },\n  { -3553091,9865099,-5228566,4272701,-5673832,-16689700,14911344,12196514,-21405489,7047412 },\n  { 20093277,9920966,-11138194,-5343857,13161587,12044805,-32856851,4124601,-32343828,-10257566 },\n },\n {\n  { -20788824,14084654,-13531713,7842147,19119038,-13822605,4752377,-8714640,-21679658,2288038 },\n  { -26819236,-3283715,29965059,3039786,-14473765,2540457,29457502,14625692,-24819617,12570232 },\n  { -1063558,-11551823,16920318,12494842,1278292,-5869109,-21159943,-3498680,-11974704,4724943 },\n },\n {\n  { 17960970,-11775534,-4140968,-9702530,-8876562,-1410617,-12907383,-8659932,-29576300,1903856 },\n  { 23134274,-14279132,-10681997,-1611936,20684485,15770816,-12989750,3190296,26955097,14109738 },\n  { 15308788,5320727,-30113809,-14318877,22902008,7767164,29425325,-11277562,31960942,11934971 },\n },\n {\n  { -27395711,8435796,4109644,12222639,-24627868,14818669,20638173,4875028,10491392,1379718 },\n  { -13159415,9197841,3875503,-8936108,-1383712,-5879801,33518459,16176658,21432314,12180697 },\n  { -11787308,11500838,13787581,-13832590,-22430679,10140205,1465425,12689540,-10301319,-13872883 },\n },\n},\n{\n {\n  { 5414091,-15386041,-21007664,9643570,12834970,1186149,-2622916,-1342231,26128231,6032912 },\n  { -26337395,-13766162,32496025,-13653919,17847801,-12669156,3604025,8316894,-25875034,-10437358 },\n  { 3296484,6223048,24680646,-12246460,-23052020,5903205,-8862297,-4639164,12376617,3188849 },\n },\n {\n  { 29190488,-14659046,27549113,-1183516,3520066,-10697301,32049515,-7309113,-16109234,-9852307 },\n  { -14744486,-9309156,735818,-598978,-20407687,-5057904,25246078,-15795669,18640741,-960977 },\n  { -6928835,-16430795,10361374,5642961,4910474,12345252,-31638386,-494430,10530747,1053335 },\n },\n {\n  { -29265967,-14186805,-13538216,-12117373,-19457059,-10655384,-31462369,-2948985,24018831,15026644 },\n  { -22592535,-3145277,-2289276,5953843,-13440189,9425631,25310643,13003497,-2314791,-15145616 },\n  { -27419985,-603321,-8043984,-1669117,-26092265,13987819,-27297622,187899,-23166419,-2531735 },\n },\n {\n  { -21744398,-13810475,1844840,5021428,-10434399,-15911473,9716667,16266922,-5070217,726099 },\n  { 29370922,-6053998,7334071,-15342259,9385287,2247707,-13661962,-4839461,30007388,-15823341 },\n  { -936379,16086691,23751945,-543318,-1167538,-5189036,9137109,730663,9835848,4555336 },\n },\n {\n  { -23376435,1410446,-22253753,-12899614,30867635,15826977,17693930,544696,-11985298,12422646 },\n  { 31117226,-12215734,-13502838,6561947,-9876867,-12757670,-5118685,-4096706,29120153,13924425 },\n  { -17400879,-14233209,19675799,-2734756,-11006962,-5858820,-9383939,-11317700,7240931,-237388 },\n },\n {\n  { -31361739,-11346780,-15007447,-5856218,-22453340,-12152771,1222336,4389483,3293637,-15551743 },\n  { -16684801,-14444245,11038544,11054958,-13801175,-3338533,-24319580,7733547,12796905,-6335822 },\n  { -8759414,-10817836,-25418864,10783769,-30615557,-9746811,-28253339,3647836,3222231,-11160462 },\n },\n {\n  { 18606113,1693100,-25448386,-15170272,4112353,10045021,23603893,-2048234,-7550776,2484985 },\n  { 9255317,-3131197,-12156162,-1004256,13098013,-9214866,16377220,-2102812,-19802075,-3034702 },\n  { -22729289,7496160,-5742199,11329249,19991973,-3347502,-31718148,9936966,-30097688,-10618797 },\n },\n {\n  { 21878590,-5001297,4338336,13643897,-3036865,13160960,19708896,5415497,-7360503,-4109293 },\n  { 27736861,10103576,12500508,8502413,-3413016,-9633558,10436918,-1550276,-23659143,-8132100 },\n  { 19492550,-12104365,-29681976,-852630,-3208171,12403437,30066266,8367329,13243957,8709688 },\n },\n},\n{\n {\n  { 12015105,2801261,28198131,10151021,24818120,-4743133,-11194191,-5645734,5150968,7274186 },\n  { 2831366,-12492146,1478975,6122054,23825128,-12733586,31097299,6083058,31021603,-9793610 },\n  { -2529932,-2229646,445613,10720828,-13849527,-11505937,-23507731,16354465,15067285,-14147707 },\n },\n {\n  { 7840942,14037873,-33364863,15934016,-728213,-3642706,21403988,1057586,-19379462,-12403220 },\n  { 915865,-16469274,15608285,-8789130,-24357026,6060030,-17371319,8410997,-7220461,16527025 },\n  { 32922597,-556987,20336074,-16184568,10903705,-5384487,16957574,52992,23834301,6588044 },\n },\n {\n  { 32752030,11232950,3381995,-8714866,22652988,-10744103,17159699,16689107,-20314580,-1305992 },\n  { -4689649,9166776,-25710296,-10847306,11576752,12733943,7924251,-2752281,1976123,-7249027 },\n  { 21251222,16309901,-2983015,-6783122,30810597,12967303,156041,-3371252,12331345,-8237197 },\n },\n {\n  { 8651614,-4477032,-16085636,-4996994,13002507,2950805,29054427,-5106970,10008136,-4667901 },\n  { 31486080,15114593,-14261250,12951354,14369431,-7387845,16347321,-13662089,8684155,-10532952 },\n  { 19443825,11385320,24468943,-9659068,-23919258,2187569,-26263207,-6086921,31316348,14219878 },\n },\n {\n  { -28594490,1193785,32245219,11392485,31092169,15722801,27146014,6992409,29126555,9207390 },\n  { 32382935,1110093,18477781,11028262,-27411763,-7548111,-4980517,10843782,-7957600,-14435730 },\n  { 2814918,7836403,27519878,-7868156,-20894015,-11553689,-21494559,8550130,28346258,1994730 },\n },\n {\n  { -19578299,8085545,-14000519,-3948622,2785838,-16231307,-19516951,7174894,22628102,8115180 },\n  { -30405132,955511,-11133838,-15078069,-32447087,-13278079,-25651578,3317160,-9943017,930272 },\n  { -15303681,-6833769,28856490,1357446,23421993,1057177,24091212,-1388970,-22765376,-10650715 },\n },\n {\n  { -22751231,-5303997,-12907607,-12768866,-15811511,-7797053,-14839018,-16554220,-1867018,8398970 },\n  { -31969310,2106403,-4736360,1362501,12813763,16200670,22981545,-6291273,18009408,-15772772 },\n  { -17220923,-9545221,-27784654,14166835,29815394,7444469,29551787,-3727419,19288549,1325865 },\n },\n {\n  { 15100157,-15835752,-23923978,-1005098,-26450192,15509408,12376730,-3479146,33166107,-8042750 },\n  { 20909231,13023121,-9209752,16251778,-5778415,-8094914,12412151,10018715,2213263,-13878373 },\n  { 32529814,-11074689,30361439,-16689753,-9135940,1513226,22922121,6382134,-5766928,8371348 },\n },\n},\n{\n {\n  { 9923462,11271500,12616794,3544722,-29998368,-1721626,12891687,-8193132,-26442943,10486144 },\n  { -22597207,-7012665,8587003,-8257861,4084309,-12970062,361726,2610596,-23921530,-11455195 },\n  { 5408411,-1136691,-4969122,10561668,24145918,14240566,31319731,-4235541,19985175,-3436086 },\n },\n {\n  { -13994457,16616821,14549246,3341099,32155958,13648976,-17577068,8849297,65030,8370684 },\n  { -8320926,-12049626,31204563,5839400,-20627288,-1057277,-19442942,6922164,12743482,-9800518 },\n  { -2361371,12678785,28815050,4759974,-23893047,4884717,23783145,11038569,18800704,255233 },\n },\n {\n  { -5269658,-1773886,13957886,7990715,23132995,728773,13393847,9066957,19258688,-14753793 },\n  { -2936654,-10827535,-10432089,14516793,-3640786,4372541,-31934921,2209390,-1524053,2055794 },\n  { 580882,16705327,5468415,-2683018,-30926419,-14696000,-7203346,-8994389,-30021019,7394435 },\n },\n {\n  { 23838809,1822728,-15738443,15242727,8318092,-3733104,-21672180,-3492205,-4821741,14799921 },\n  { 13345610,9759151,3371034,-16137791,16353039,8577942,31129804,13496856,-9056018,7402518 },\n  { 2286874,-4435931,-20042458,-2008336,-13696227,5038122,11006906,-15760352,8205061,1607563 },\n },\n {\n  { 14414086,-8002132,3331830,-3208217,22249151,-5594188,18364661,-2906958,30019587,-9029278 },\n  { -27688051,1585953,-10775053,931069,-29120221,-11002319,-14410829,12029093,9944378,8024 },\n  { 4368715,-3709630,29874200,-15022983,-20230386,-11410704,-16114594,-999085,-8142388,5640030 },\n },\n {\n  { 10299610,13746483,11661824,16234854,7630238,5998374,9809887,-16694564,15219798,-14327783 },\n  { 27425505,-5719081,3055006,10660664,23458024,595578,-15398605,-1173195,-18342183,9742717 },\n  { 6744077,2427284,26042789,2720740,-847906,1118974,32324614,7406442,12420155,1994844 },\n },\n {\n  { 14012521,-5024720,-18384453,-9578469,-26485342,-3936439,-13033478,-10909803,24319929,-6446333 },\n  { 16412690,-4507367,10772641,15929391,-17068788,-4658621,10555945,-10484049,-30102368,-4739048 },\n  { 22397382,-7767684,-9293161,-12792868,17166287,-9755136,-27333065,6199366,21880021,-12250760 },\n },\n {\n  { -4283307,5368523,-31117018,8163389,-30323063,3209128,16557151,8890729,8840445,4957760 },\n  { -15447727,709327,-6919446,-10870178,-29777922,6522332,-21720181,12130072,-14796503,5005757 },\n  { -2114751,-14308128,23019042,15765735,-25269683,6002752,10183197,-13239326,-16395286,-2176112 },\n },\n},\n{\n {\n  { -19025756,1632005,13466291,-7995100,-23640451,16573537,-32013908,-3057104,22208662,2000468 },\n  { 3065073,-1412761,-25598674,-361432,-17683065,-5703415,-8164212,11248527,-3691214,-7414184 },\n  { 10379208,-6045554,8877319,1473647,-29291284,-12507580,16690915,2553332,-3132688,16400289 },\n },\n {\n  { 15716668,1254266,-18472690,7446274,-8448918,6344164,-22097271,-7285580,26894937,9132066 },\n  { 24158887,12938817,11085297,-8177598,-28063478,-4457083,-30576463,64452,-6817084,-2692882 },\n  { 13488534,7794716,22236231,5989356,25426474,-12578208,2350710,-3418511,-4688006,2364226 },\n },\n {\n  { 16335052,9132434,25640582,6678888,1725628,8517937,-11807024,-11697457,15445875,-7798101 },\n  { 29004207,-7867081,28661402,-640412,-12794003,-7943086,31863255,-4135540,-278050,-15759279 },\n  { -6122061,-14866665,-28614905,14569919,-10857999,-3591829,10343412,-6976290,-29828287,-10815811 },\n },\n {\n  { 27081650,3463984,14099042,-4517604,1616303,-6205604,29542636,15372179,17293797,960709 },\n  { 20263915,11434237,-5765435,11236810,13505955,-10857102,-16111345,6493122,-19384511,7639714 },\n  { -2830798,-14839232,25403038,-8215196,-8317012,-16173699,18006287,-16043750,29994677,-15808121 },\n },\n {\n  { 9769828,5202651,-24157398,-13631392,-28051003,-11561624,-24613141,-13860782,-31184575,709464 },\n  { 12286395,13076066,-21775189,-1176622,-25003198,4057652,-32018128,-8890874,16102007,13205847 },\n  { 13733362,5599946,10557076,3195751,-5557991,8536970,-25540170,8525972,10151379,10394400 },\n },\n {\n  { 4024660,-16137551,22436262,12276534,-9099015,-2686099,19698229,11743039,-33302334,8934414 },\n  { -15879800,-4525240,-8580747,-2934061,14634845,-698278,-9449077,3137094,-11536886,11721158 },\n  { 17555939,-5013938,8268606,2331751,-22738815,9761013,9319229,8835153,-9205489,-1280045 },\n },\n {\n  { -461409,-7830014,20614118,16688288,-7514766,-4807119,22300304,505429,6108462,-6183415 },\n  { -5070281,12367917,-30663534,3234473,32617080,-8422642,29880583,-13483331,-26898490,-7867459 },\n  { -31975283,5726539,26934134,10237677,-3173717,-605053,24199304,3795095,7592688,-14992079 },\n },\n {\n  { 21594432,-14964228,17466408,-4077222,32537084,2739898,6407723,12018833,-28256052,4298412 },\n  { -20650503,-11961496,-27236275,570498,3767144,-1717540,13891942,-1569194,13717174,10805743 },\n  { -14676630,-15644296,15287174,11927123,24177847,-8175568,-796431,14860609,-26938930,-5863836 },\n },\n},\n{\n {\n  { 12962541,5311799,-10060768,11658280,18855286,-7954201,13286263,-12808704,-4381056,9882022 },\n  { 18512079,11319350,-20123124,15090309,18818594,5271736,-22727904,3666879,-23967430,-3299429 },\n  { -6789020,-3146043,16192429,13241070,15898607,-14206114,-10084880,-6661110,-2403099,5276065 },\n },\n {\n  { 30169808,-5317648,26306206,-11750859,27814964,7069267,7152851,3684982,1449224,13082861 },\n  { 10342826,3098505,2119311,193222,25702612,12233820,23697382,15056736,-21016438,-8202000 },\n  { -33150110,3261608,22745853,7948688,19370557,-15177665,-26171976,6482814,-10300080,-11060101 },\n },\n {\n  { 32869458,-5408545,25609743,15678670,-10687769,-15471071,26112421,2521008,-22664288,6904815 },\n  { 29506923,4457497,3377935,-9796444,-30510046,12935080,1561737,3841096,-29003639,-6657642 },\n  { 10340844,-6630377,-18656632,-2278430,12621151,-13339055,30878497,-11824370,-25584551,5181966 },\n },\n {\n  { 25940115,-12658025,17324188,-10307374,-8671468,15029094,24396252,-16450922,-2322852,-12388574 },\n  { -21765684,9916823,-1300409,4079498,-1028346,11909559,1782390,12641087,20603771,-6561742 },\n  { -18882287,-11673380,24849422,11501709,13161720,-4768874,1925523,11914390,4662781,7820689 },\n },\n {\n  { 12241050,-425982,8132691,9393934,32846760,-1599620,29749456,12172924,16136752,15264020 },\n  { -10349955,-14680563,-8211979,2330220,-17662549,-14545780,10658213,6671822,19012087,3772772 },\n  { 3753511,-3421066,10617074,2028709,14841030,-6721664,28718732,-15762884,20527771,12988982 },\n },\n {\n  { -14822485,-5797269,-3707987,12689773,-898983,-10914866,-24183046,-10564943,3299665,-12424953 },\n  { -16777703,-15253301,-9642417,4978983,3308785,8755439,6943197,6461331,-25583147,8991218 },\n  { -17226263,1816362,-1673288,-6086439,31783888,-8175991,-32948145,7417950,-30242287,1507265 },\n },\n {\n  { 29692663,6829891,-10498800,4334896,20945975,-11906496,-28887608,8209391,14606362,-10647073 },\n  { -3481570,8707081,32188102,5672294,22096700,1711240,-33020695,9761487,4170404,-2085325 },\n  { -11587470,14855945,-4127778,-1531857,-26649089,15084046,22186522,16002000,-14276837,-8400798 },\n },\n {\n  { -4811456,13761029,-31703877,-2483919,-3312471,7869047,-7113572,-9620092,13240845,10965870 },\n  { -7742563,-8256762,-14768334,-13656260,-23232383,12387166,4498947,14147411,29514390,4302863 },\n  { -13413405,-12407859,20757302,-13801832,14785143,8976368,-5061276,-2144373,17846988,-13971927 },\n },\n},\n{\n {\n  { -2244452,-754728,-4597030,-1066309,-6247172,1455299,-21647728,-9214789,-5222701,12650267 },\n  { -9906797,-16070310,21134160,12198166,-27064575,708126,387813,13770293,-19134326,10958663 },\n  { 22470984,12369526,23446014,-5441109,-21520802,-9698723,-11772496,-11574455,-25083830,4271862 },\n },\n {\n  { -25169565,-10053642,-19909332,15361595,-5984358,2159192,75375,-4278529,-32526221,8469673 },\n  { 15854970,4148314,-8893890,7259002,11666551,13824734,-30531198,2697372,24154791,-9460943 },\n  { 15446137,-15806644,29759747,14019369,30811221,-9610191,-31582008,12840104,24913809,9815020 },\n },\n {\n  { -4709286,-5614269,-31841498,-12288893,-14443537,10799414,-9103676,13438769,18735128,9466238 },\n  { 11933045,9281483,5081055,-5183824,-2628162,-4905629,-7727821,-10896103,-22728655,16199064 },\n  { 14576810,379472,-26786533,-8317236,-29426508,-10812974,-102766,1876699,30801119,2164795 },\n },\n {\n  { 15995086,3199873,13672555,13712240,-19378835,-4647646,-13081610,-15496269,-13492807,1268052 },\n  { -10290614,-3659039,-3286592,10948818,23037027,3794475,-3470338,-12600221,-17055369,3565904 },\n  { 29210088,-9419337,-5919792,-4952785,10834811,-13327726,-16512102,-10820713,-27162222,-14030531 },\n },\n {\n  { -13161890,15508588,16663704,-8156150,-28349942,9019123,-29183421,-3769423,2244111,-14001979 },\n  { -5152875,-3800936,-9306475,-6071583,16243069,14684434,-25673088,-16180800,13491506,4641841 },\n  { 10813417,643330,-19188515,-728916,30292062,-16600078,27548447,-7721242,14476989,-12767431 },\n },\n {\n  { 10292079,9984945,6481436,8279905,-7251514,7032743,27282937,-1644259,-27912810,12651324 },\n  { -31185513,-813383,22271204,11835308,10201545,15351028,17099662,3988035,21721536,-3148940 },\n  { 10202177,-6545839,-31373232,-9574638,-32150642,-8119683,-12906320,3852694,13216206,14842320 },\n },\n {\n  { -15815640,-10601066,-6538952,-7258995,-6984659,-6581778,-31500847,13765824,-27434397,9900184 },\n  { 14465505,-13833331,-32133984,-14738873,-27443187,12990492,33046193,15796406,-7051866,-8040114 },\n  { 30924417,-8279620,6359016,-12816335,16508377,9071735,-25488601,15413635,9524356,-7018878 },\n },\n {\n  { 12274201,-13175547,32627641,-1785326,6736625,13267305,5237659,-5109483,15663516,4035784 },\n  { -2951309,8903985,17349946,601635,-16432815,-4612556,-13732739,-15889334,-22258478,4659091 },\n  { -16916263,-4952973,-30393711,-15158821,20774812,15897498,5736189,15026997,-2178256,-13455585 },\n },\n},\n{\n {\n  { -8858980,-2219056,28571666,-10155518,-474467,-10105698,-3801496,278095,23440562,-290208 },\n  { 10226241,-5928702,15139956,120818,-14867693,5218603,32937275,11551483,-16571960,-7442864 },\n  { 17932739,-12437276,-24039557,10749060,11316803,7535897,22503767,5561594,-3646624,3898661 },\n },\n {\n  { 7749907,-969567,-16339731,-16464,-25018111,15122143,-1573531,7152530,21831162,1245233 },\n  { 26958459,-14658026,4314586,8346991,-5677764,11960072,-32589295,-620035,-30402091,-16716212 },\n  { -12165896,9166947,33491384,13673479,29787085,13096535,6280834,14587357,-22338025,13987525 },\n },\n {\n  { -24349909,7778775,21116000,15572597,-4833266,-5357778,-4300898,-5124639,-7469781,-2858068 },\n  { 9681908,-6737123,-31951644,13591838,-6883821,386950,31622781,6439245,-14581012,4091397 },\n  { -8426427,1470727,-28109679,-1596990,3978627,-5123623,-19622683,12092163,29077877,-14741988 },\n },\n {\n  { 5269168,-6859726,-13230211,-8020715,25932563,1763552,-5606110,-5505881,-20017847,2357889 },\n  { 32264008,-15407652,-5387735,-1160093,-2091322,-3946900,23104804,-12869908,5727338,189038 },\n  { 14609123,-8954470,-6000566,-16622781,-14577387,-7743898,-26745169,10942115,-25888931,-14884697 },\n },\n {\n  { 20513500,5557931,-15604613,7829531,26413943,-2019404,-21378968,7471781,13913677,-5137875 },\n  { -25574376,11967826,29233242,12948236,-6754465,4713227,-8940970,14059180,12878652,8511905 },\n  { -25656801,3393631,-2955415,-7075526,-2250709,9366908,-30223418,6812974,5568676,-3127656 },\n },\n {\n  { 11630004,12144454,2116339,13606037,27378885,15676917,-17408753,-13504373,-14395196,8070818 },\n  { 27117696,-10007378,-31282771,-5570088,1127282,12772488,-29845906,10483306,-11552749,-1028714 },\n  { 10637467,-5688064,5674781,1072708,-26343588,-6982302,-1683975,9177853,-27493162,15431203 },\n },\n {\n  { 20525145,10892566,-12742472,12779443,-29493034,16150075,-28240519,14943142,-15056790,-7935931 },\n  { -30024462,5626926,-551567,-9981087,753598,11981191,25244767,-3239766,-3356550,9594024 },\n  { -23752644,2636870,-5163910,-10103818,585134,7877383,11345683,-6492290,13352335,-10977084 },\n },\n {\n  { -1931799,-5407458,3304649,-12884869,17015806,-4877091,-29783850,-7752482,-13215537,-319204 },\n  { 20239939,6607058,6203985,3483793,-18386976,-779229,-20723742,15077870,-22750759,14523817 },\n  { 27406042,-6041657,27423596,-4497394,4996214,10002360,-28842031,-4545494,-30172742,-4805667 },\n },\n},\n{\n {\n  { 11374242,12660715,17861383,-12540833,10935568,1099227,-13886076,-9091740,-27727044,11358504 },\n  { -12730809,10311867,1510375,10778093,-2119455,-9145702,32676003,11149336,-26123651,4985768 },\n  { -19096303,341147,-6197485,-239033,15756973,-8796662,-983043,13794114,-19414307,-15621255 },\n },\n {\n  { 6490081,11940286,25495923,-7726360,8668373,-8751316,3367603,6970005,-1691065,-9004790 },\n  { 1656497,13457317,15370807,6364910,13605745,8362338,-19174622,-5475723,-16796596,-5031438 },\n  { -22273315,-13524424,-64685,-4334223,-18605636,-10921968,-20571065,-7007978,-99853,-10237333 },\n },\n {\n  { 17747465,10039260,19368299,-4050591,-20630635,-16041286,31992683,-15857976,-29260363,-5511971 },\n  { 31932027,-4986141,-19612382,16366580,22023614,88450,11371999,-3744247,4882242,-10626905 },\n  { 29796507,37186,19818052,10115756,-11829032,3352736,18551198,3272828,-5190932,-4162409 },\n },\n {\n  { 12501286,4044383,-8612957,-13392385,-32430052,5136599,-19230378,-3529697,330070,-3659409 },\n  { 6384877,2899513,17807477,7663917,-2358888,12363165,25366522,-8573892,-271295,12071499 },\n  { -8365515,-4042521,25133448,-4517355,-6211027,2265927,-32769618,1936675,-5159697,3829363 },\n },\n {\n  { 28425966,-5835433,-577090,-4697198,-14217555,6870930,7921550,-6567787,26333140,14267664 },\n  { -11067219,11871231,27385719,-10559544,-4585914,-11189312,10004786,-8709488,-21761224,8930324 },\n  { -21197785,-16396035,25654216,-1725397,12282012,11008919,1541940,4757911,-26491501,-16408940 },\n },\n {\n  { 13537262,-7759490,-20604840,10961927,-5922820,-13218065,-13156584,6217254,-15943699,13814990 },\n  { -17422573,15157790,18705543,29619,24409717,-260476,27361681,9257833,-1956526,-1776914 },\n  { -25045300,-10191966,15366585,15166509,-13105086,8423556,-29171540,12361135,-18685978,4578290 },\n },\n {\n  { 24579768,3711570,1342322,-11180126,-27005135,14124956,-22544529,14074919,21964432,8235257 },\n  { -6528613,-2411497,9442966,-5925588,12025640,-1487420,-2981514,-1669206,13006806,2355433 },\n  { -16304899,-13605259,-6632427,-5142349,16974359,-10911083,27202044,1719366,1141648,-12796236 },\n },\n {\n  { -12863944,-13219986,-8318266,-11018091,-6810145,-4843894,13475066,-3133972,32674895,13715045 },\n  { 11423335,-5468059,32344216,8962751,24989809,9241752,-13265253,16086212,-28740881,-15642093 },\n  { -1409668,12530728,-6368726,10847387,19531186,-14132160,-11709148,7791794,-27245943,4383347 },\n },\n},\n{\n {\n  { -28970898,5271447,-1266009,-9736989,-12455236,16732599,-4862407,-4906449,27193557,6245191 },\n  { -15193956,5362278,-1783893,2695834,4960227,12840725,23061898,3260492,22510453,8577507 },\n  { -12632451,11257346,-32692994,13548177,-721004,10879011,31168030,13952092,-29571492,-3635906 },\n },\n {\n  { 3877321,-9572739,32416692,5405324,-11004407,-13656635,3759769,11935320,5611860,8164018 },\n  { -16275802,14667797,15906460,12155291,-22111149,-9039718,32003002,-8832289,5773085,-8422109 },\n  { -23788118,-8254300,1950875,8937633,18686727,16459170,-905725,12376320,31632953,190926 },\n },\n {\n  { -24593607,-16138885,-8423991,13378746,14162407,6901328,-8288749,4508564,-25341555,-3627528 },\n  { 8884438,-5884009,6023974,10104341,-6881569,-4941533,18722941,-14786005,-1672488,827625 },\n  { -32720583,-16289296,-32503547,7101210,13354605,2659080,-1800575,-14108036,-24878478,1541286 },\n },\n {\n  { 2901347,-1117687,3880376,-10059388,-17620940,-3612781,-21802117,-3567481,20456845,-1885033 },\n  { 27019610,12299467,-13658288,-1603234,-12861660,-4861471,-19540150,-5016058,29439641,15138866 },\n  { 21536104,-6626420,-32447818,-10690208,-22408077,5175814,-5420040,-16361163,7779328,109896 },\n },\n {\n  { 30279744,14648750,-8044871,6425558,13639621,-743509,28698390,12180118,23177719,-554075 },\n  { 26572847,3405927,-31701700,12890905,-19265668,5335866,-6493768,2378492,4439158,-13279347 },\n  { -22716706,3489070,-9225266,-332753,18875722,-1140095,14819434,-12731527,-17717757,-5461437 },\n },\n {\n  { -5056483,16566551,15953661,3767752,-10436499,15627060,-820954,2177225,8550082,-15114165 },\n  { -18473302,16596775,-381660,15663611,22860960,15585581,-27844109,-3582739,-23260460,-8428588 },\n  { -32480551,15707275,-8205912,-5652081,29464558,2713815,-22725137,15860482,-21902570,1494193 },\n },\n {\n  { -19562091,-14087393,-25583872,-9299552,13127842,759709,21923482,16529112,8742704,12967017 },\n  { -28464899,1553205,32536856,-10473729,-24691605,-406174,-8914625,-2933896,-29903758,15553883 },\n  { 21877909,3230008,9881174,10539357,-4797115,2841332,11543572,14513274,19375923,-12647961 },\n },\n {\n  { 8832269,-14495485,13253511,5137575,5037871,4078777,24880818,-6222716,2862653,9455043 },\n  { 29306751,5123106,20245049,-14149889,9592566,8447059,-2077124,-2990080,15511449,4789663 },\n  { -20679756,7004547,8824831,-9434977,-4045704,-3750736,-5754762,108893,23513200,16652362 },\n },\n},\n{\n {\n  { -33256173,4144782,-4476029,-6579123,10770039,-7155542,-6650416,-12936300,-18319198,10212860 },\n  { 2756081,8598110,7383731,-6859892,22312759,-1105012,21179801,2600940,-9988298,-12506466 },\n  { -24645692,13317462,-30449259,-15653928,21365574,-10869657,11344424,864440,-2499677,-16710063 },\n },\n {\n  { -26432803,6148329,-17184412,-14474154,18782929,-275997,-22561534,211300,2719757,4940997 },\n  { -1323882,3911313,-6948744,14759765,-30027150,7851207,21690126,8518463,26699843,5276295 },\n  { -13149873,-6429067,9396249,365013,24703301,-10488939,1321586,149635,-15452774,7159369 },\n },\n {\n  { 9987780,-3404759,17507962,9505530,9731535,-2165514,22356009,8312176,22477218,-8403385 },\n  { 18155857,-16504990,19744716,9006923,15154154,-10538976,24256460,-4864995,-22548173,9334109 },\n  { 2986088,-4911893,10776628,-3473844,10620590,-7083203,-21413845,14253545,-22587149,536906 },\n },\n {\n  { 4377756,8115836,24567078,15495314,11625074,13064599,7390551,10589625,10838060,-15420424 },\n  { -19342404,867880,9277171,-3218459,-14431572,-1986443,19295826,-15796950,6378260,699185 },\n  { 7895026,4057113,-7081772,-13077756,-17886831,-323126,-716039,15693155,-5045064,-13373962 },\n },\n {\n  { -7737563,-5869402,-14566319,-7406919,11385654,13201616,31730678,-10962840,-3918636,-9669325 },\n  { 10188286,-15770834,-7336361,13427543,22223443,14896287,30743455,7116568,-21786507,5427593 },\n  { 696102,13206899,27047647,-10632082,15285305,-9853179,10798490,-4578720,19236243,12477404 },\n },\n {\n  { -11229439,11243796,-17054270,-8040865,-788228,-8167967,-3897669,11180504,-23169516,7733644 },\n  { 17800790,-14036179,-27000429,-11766671,23887827,3149671,23466177,-10538171,10322027,15313801 },\n  { 26246234,11968874,32263343,-5468728,6830755,-13323031,-15794704,-101982,-24449242,10890804 },\n },\n {\n  { -31365647,10271363,-12660625,-6267268,16690207,-13062544,-14982212,16484931,25180797,-5334884 },\n  { -586574,10376444,-32586414,-11286356,19801893,10997610,2276632,9482883,316878,13820577 },\n  { -9882808,-4510367,-2115506,16457136,-11100081,11674996,30756178,-7515054,30696930,-3712849 },\n },\n {\n  { 32988917,-9603412,12499366,7910787,-10617257,-11931514,-7342816,-9985397,-32349517,7392473 },\n  { -8855661,15927861,9866406,-3649411,-2396914,-16655781,-30409476,-9134995,25112947,-2926644 },\n  { -2504044,-436966,25621774,-5678772,15085042,-5479877,-24884878,-13526194,5537438,-13914319 },\n },\n},\n{\n {\n  { -11225584,2320285,-9584280,10149187,-33444663,5808648,-14876251,-1729667,31234590,6090599 },\n  { -9633316,116426,26083934,2897444,-6364437,-2688086,609721,15878753,-6970405,-9034768 },\n  { -27757857,247744,-15194774,-9002551,23288161,-10011936,-23869595,6503646,20650474,1804084 },\n },\n {\n  { -27589786,15456424,8972517,8469608,15640622,4439847,3121995,-10329713,27842616,-202328 },\n  { -15306973,2839644,22530074,10026331,4602058,5048462,28248656,5031932,-11375082,12714369 },\n  { 20807691,-7270825,29286141,11421711,-27876523,-13868230,-21227475,1035546,-19733229,12796920 },\n },\n {\n  { 12076899,-14301286,-8785001,-11848922,-25012791,16400684,-17591495,-12899438,3480665,-15182815 },\n  { -32361549,5457597,28548107,7833186,7303070,-11953545,-24363064,-15921875,-33374054,2771025 },\n  { -21389266,421932,26597266,6860826,22486084,-6737172,-17137485,-4210226,-24552282,15673397 },\n },\n {\n  { -20184622,2338216,19788685,-9620956,-4001265,-8740893,-20271184,4733254,3727144,-12934448 },\n  { 6120119,814863,-11794402,-622716,6812205,-15747771,2019594,7975683,31123697,-10958981 },\n  { 30069250,-11435332,30434654,2958439,18399564,-976289,12296869,9204260,-16432438,9648165 },\n },\n {\n  { 32705432,-1550977,30705658,7451065,-11805606,9631813,3305266,5248604,-26008332,-11377501 },\n  { 17219865,2375039,-31570947,-5575615,-19459679,9219903,294711,15298639,2662509,-16297073 },\n  { -1172927,-7558695,-4366770,-4287744,-21346413,-8434326,32087529,-1222777,32247248,-14389861 },\n },\n {\n  { 14312628,1221556,17395390,-8700143,-4945741,-8684635,-28197744,-9637817,-16027623,-13378845 },\n  { -1428825,-9678990,-9235681,6549687,-7383069,-468664,23046502,9803137,17597934,2346211 },\n  { 18510800,15337574,26171504,981392,-22241552,7827556,-23491134,-11323352,3059833,-11782870 },\n },\n {\n  { 10141598,6082907,17829293,-1947643,9830092,13613136,-25556636,-5544586,-33502212,3592096 },\n  { 33114168,-15889352,-26525686,-13343397,33076705,8716171,1151462,1521897,-982665,-6837803 },\n  { -32939165,-4255815,23947181,-324178,-33072974,-12305637,-16637686,3891704,26353178,693168 },\n },\n {\n  { 30374239,1595580,-16884039,13186931,4600344,406904,9585294,-400668,31375464,14369965 },\n  { -14370654,-7772529,1510301,6434173,-18784789,-6262728,32732230,-13108839,17901441,16011505 },\n  { 18171223,-11934626,-12500402,15197122,-11038147,-15230035,-19172240,-16046376,8764035,12309598 },\n },\n},\n{\n {\n  { 5975908,-5243188,-19459362,-9681747,-11541277,14015782,-23665757,1228319,17544096,-10593782 },\n  { 5811932,-1715293,3442887,-2269310,-18367348,-8359541,-18044043,-15410127,-5565381,12348900 },\n  { -31399660,11407555,25755363,6891399,-3256938,14872274,-24849353,8141295,-10632534,-585479 },\n },\n {\n  { -12675304,694026,-5076145,13300344,14015258,-14451394,-9698672,-11329050,30944593,1130208 },\n  { 8247766,-6710942,-26562381,-7709309,-14401939,-14648910,4652152,2488540,23550156,-271232 },\n  { 17294316,-3788438,7026748,15626851,22990044,113481,2267737,-5908146,-408818,-137719 },\n },\n {\n  { 16091085,-16253926,18599252,7340678,2137637,-1221657,-3364161,14550936,3260525,-7166271 },\n  { -4910104,-13332887,18550887,10864893,-16459325,-7291596,-23028869,-13204905,-12748722,2701326 },\n  { -8574695,16099415,4629974,-16340524,-20786213,-6005432,-10018363,9276971,11329923,1862132 },\n },\n {\n  { 14763076,-15903608,-30918270,3689867,3511892,10313526,-21951088,12219231,-9037963,-940300 },\n  { 8894987,-3446094,6150753,3013931,301220,15693451,-31981216,-2909717,-15438168,11595570 },\n  { 15214962,3537601,-26238722,-14058872,4418657,-15230761,13947276,10730794,-13489462,-4363670 },\n },\n {\n  { -2538306,7682793,32759013,263109,-29984731,-7955452,-22332124,-10188635,977108,699994 },\n  { -12466472,4195084,-9211532,550904,-15565337,12917920,19118110,-439841,-30534533,-14337913 },\n  { 31788461,-14507657,4799989,7372237,8808585,-14747943,9408237,-10051775,12493932,-5409317 },\n },\n {\n  { -25680606,5260744,-19235809,-6284470,-3695942,16566087,27218280,2607121,29375955,6024730 },\n  { 842132,-2794693,-4763381,-8722815,26332018,-12405641,11831880,6985184,-9940361,2854096 },\n  { -4847262,-7969331,2516242,-5847713,9695691,-7221186,16512645,960770,12121869,16648078 },\n },\n {\n  { -15218652,14667096,-13336229,2013717,30598287,-464137,-31504922,-7882064,20237806,2838411 },\n  { -19288047,4453152,15298546,-16178388,22115043,-15972604,12544294,-13470457,1068881,-12499905 },\n  { -9558883,-16518835,33238498,13506958,30505848,-1114596,-8486907,-2630053,12521378,4845654 },\n },\n {\n  { -28198521,10744108,-2958380,10199664,7759311,-13088600,3409348,-873400,-6482306,-12885870 },\n  { -23561822,6230156,-20382013,10655314,-24040585,-11621172,10477734,-1240216,-3113227,13974498 },\n  { 12966261,15550616,-32038948,-1615346,21025980,-629444,5642325,7188737,18895762,12629579 },\n },\n},\n{\n {\n  { 14741879,-14946887,22177208,-11721237,1279741,8058600,11758140,789443,32195181,3895677 },\n  { 10758205,15755439,-4509950,9243698,-4879422,6879879,-2204575,-3566119,-8982069,4429647 },\n  { -2453894,15725973,-20436342,-10410672,-5803908,-11040220,-7135870,-11642895,18047436,-15281743 },\n },\n {\n  { -25173001,-11307165,29759956,11776784,-22262383,-15820455,10993114,-12850837,-17620701,-9408468 },\n  { 21987233,700364,-24505048,14972008,-7774265,-5718395,32155026,2581431,-29958985,8773375 },\n  { -25568350,454463,-13211935,16126715,25240068,8594567,20656846,12017935,-7874389,-13920155 },\n },\n {\n  { 6028182,6263078,-31011806,-11301710,-818919,2461772,-31841174,-5468042,-1721788,-2776725 },\n  { -12278994,16624277,987579,-5922598,32908203,1248608,7719845,-4166698,28408820,6816612 },\n  { -10358094,-8237829,19549651,-12169222,22082623,16147817,20613181,13982702,-10339570,5067943 },\n },\n {\n  { -30505967,-3821767,12074681,13582412,-19877972,2443951,-19719286,12746132,5331210,-10105944 },\n  { 30528811,3601899,-1957090,4619785,-27361822,-15436388,24180793,-12570394,27679908,-1648928 },\n  { 9402404,-13957065,32834043,10838634,-26580150,-13237195,26653274,-8685565,22611444,-12715406 },\n },\n {\n  { 22190590,1118029,22736441,15130463,-30460692,-5991321,19189625,-4648942,4854859,6622139 },\n  { -8310738,-2953450,-8262579,-3388049,-10401731,-271929,13424426,-3567227,26404409,13001963 },\n  { -31241838,-15415700,-2994250,8939346,11562230,-12840670,-26064365,-11621720,-15405155,11020693 },\n },\n {\n  { 1866042,-7949489,-7898649,-10301010,12483315,13477547,3175636,-12424163,28761762,1406734 },\n  { -448555,-1777666,13018551,3194501,-9580420,-11161737,24760585,-4347088,25577411,-13378680 },\n  { -24290378,4759345,-690653,-1852816,2066747,10693769,-29595790,9884936,-9368926,4745410 },\n },\n {\n  { -9141284,6049714,-19531061,-4341411,-31260798,9944276,-15462008,-11311852,10931924,-11931931 },\n  { -16561513,14112680,-8012645,4817318,-8040464,-11414606,-22853429,10856641,-20470770,13434654 },\n  { 22759489,-10073434,-16766264,-1871422,13637442,-10168091,1765144,-12654326,28445307,-5364710 },\n },\n {\n  { 29875063,12493613,2795536,-3786330,1710620,15181182,-10195717,-8788675,9074234,1167180 },\n  { -26205683,11014233,-9842651,-2635485,-26908120,7532294,-18716888,-9535498,3843903,9367684 },\n  { -10969595,-6403711,9591134,9582310,11349256,108879,16235123,8601684,-139197,4242895 },\n },\n},\n{\n {\n  { 22092954,-13191123,-2042793,-11968512,32186753,-11517388,-6574341,2470660,-27417366,16625501 },\n  { -11057722,3042016,13770083,-9257922,584236,-544855,-7770857,2602725,-27351616,14247413 },\n  { 6314175,-10264892,-32772502,15957557,-10157730,168750,-8618807,14290061,27108877,-1180880 },\n },\n {\n  { -8586597,-7170966,13241782,10960156,-32991015,-13794596,33547976,-11058889,-27148451,981874 },\n  { 22833440,9293594,-32649448,-13618667,-9136966,14756819,-22928859,-13970780,-10479804,-16197962 },\n  { -7768587,3326786,-28111797,10783824,19178761,14905060,22680049,13906969,-15933690,3797899 },\n },\n {\n  { 21721356,-4212746,-12206123,9310182,-3882239,-13653110,23740224,-2709232,20491983,-8042152 },\n  { 9209270,-15135055,-13256557,-6167798,-731016,15289673,25947805,15286587,30997318,-6703063 },\n  { 7392032,16618386,23946583,-8039892,-13265164,-1533858,-14197445,-2321576,17649998,-250080 },\n },\n {\n  { -9301088,-14193827,30609526,-3049543,-25175069,-1283752,-15241566,-9525724,-2233253,7662146 },\n  { -17558673,1763594,-33114336,15908610,-30040870,-12174295,7335080,-8472199,-3174674,3440183 },\n  { -19889700,-5977008,-24111293,-9688870,10799743,-16571957,40450,-4431835,4862400,1133 },\n },\n {\n  { -32856209,-7873957,-5422389,14860950,-16319031,7956142,7258061,311861,-30594991,-7379421 },\n  { -3773428,-1565936,28985340,7499440,24445838,9325937,29727763,16527196,18278453,15405622 },\n  { -4381906,8508652,-19898366,-3674424,-5984453,15149970,-13313598,843523,-21875062,13626197 },\n },\n {\n  { 2281448,-13487055,-10915418,-2609910,1879358,16164207,-10783882,3953792,13340839,15928663 },\n  { 31727126,-7179855,-18437503,-8283652,2875793,-16390330,-25269894,-7014826,-23452306,5964753 },\n  { 4100420,-5959452,-17179337,6017714,-18705837,12227141,-26684835,11344144,2538215,-7570755 },\n },\n {\n  { -9433605,6123113,11159803,-2156608,30016280,14966241,-20474983,1485421,-629256,-15958862 },\n  { -26804558,4260919,11851389,9658551,-32017107,16367492,-20205425,-13191288,11659922,-11115118 },\n  { 26180396,10015009,-30844224,-8581293,5418197,9480663,2231568,-10170080,33100372,-1306171 },\n },\n {\n  { 15121113,-5201871,-10389905,15427821,-27509937,-15992507,21670947,4486675,-5931810,-14466380 },\n  { 16166486,-9483733,-11104130,6023908,-31926798,-1364923,2340060,-16254968,-10735770,-10039824 },\n  { 28042865,-3557089,-12126526,12259706,-3717498,-6945899,6766453,-8689599,18036436,5803270 },\n },\n},\n{\n {\n  { -817581,6763912,11803561,1585585,10958447,-2671165,23855391,4598332,-6159431,-14117438 },\n  { -31031306,-14256194,17332029,-2383520,31312682,-5967183,696309,50292,-20095739,11763584 },\n  { -594563,-2514283,-32234153,12643980,12650761,14811489,665117,-12613632,-19773211,-10713562 },\n },\n {\n  { 30464590,-11262872,-4127476,-12734478,19835327,-7105613,-24396175,2075773,-17020157,992471 },\n  { 18357185,-6994433,7766382,16342475,-29324918,411174,14578841,8080033,-11574335,-10601610 },\n  { 19598397,10334610,12555054,2555664,18821899,-10339780,21873263,16014234,26224780,16452269 },\n },\n {\n  { -30223925,5145196,5944548,16385966,3976735,2009897,-11377804,-7618186,-20533829,3698650 },\n  { 14187449,3448569,-10636236,-10810935,-22663880,-3433596,7268410,-10890444,27394301,12015369 },\n  { 19695761,16087646,28032085,12999827,6817792,11427614,20244189,-1312777,-13259127,-3402461 },\n },\n {\n  { 30860103,12735208,-1888245,-4699734,-16974906,2256940,-8166013,12298312,-8550524,-10393462 },\n  { -5719826,-11245325,-1910649,15569035,26642876,-7587760,-5789354,-15118654,-4976164,12651793 },\n  { -2848395,9953421,11531313,-5282879,26895123,-12697089,-13118820,-16517902,9768698,-2533218 },\n },\n {\n  { -24719459,1894651,-287698,-4704085,15348719,-8156530,32767513,12765450,4940095,10678226 },\n  { 18860224,15980149,-18987240,-1562570,-26233012,-11071856,-7843882,13944024,-24372348,16582019 },\n  { -15504260,4970268,-29893044,4175593,-20993212,-2199756,-11704054,15444560,-11003761,7989037 },\n },\n {\n  { 31490452,5568061,-2412803,2182383,-32336847,4531686,-32078269,6200206,-19686113,-14800171 },\n  { -17308668,-15879940,-31522777,-2831,-32887382,16375549,8680158,-16371713,28550068,-6857132 },\n  { -28126887,-5688091,16837845,-1820458,-6850681,12700016,-30039981,4364038,1155602,5988841 },\n },\n {\n  { 21890435,-13272907,-12624011,12154349,-7831873,15300496,23148983,-4470481,24618407,8283181 },\n  { -33136107,-10512751,9975416,6841041,-31559793,16356536,3070187,-7025928,1466169,10740210 },\n  { -1509399,-15488185,-13503385,-10655916,32799044,909394,-13938903,-5779719,-32164649,-15327040 },\n },\n {\n  { 3960823,-14267803,-28026090,-15918051,-19404858,13146868,15567327,951507,-3260321,-573935 },\n  { 24740841,5052253,-30094131,8961361,25877428,6165135,-24368180,14397372,-7380369,-6144105 },\n  { -28888365,3510803,-28103278,-1158478,-11238128,-10631454,-15441463,-14453128,-1625486,-6494814 },\n },\n},\n{\n {\n  { 793299,-9230478,8836302,-6235707,-27360908,-2369593,33152843,-4885251,-9906200,-621852 },\n  { 5666233,525582,20782575,-8038419,-24538499,14657740,16099374,1468826,-6171428,-15186581 },\n  { -4859255,-3779343,-2917758,-6748019,7778750,11688288,-30404353,-9871238,-1558923,-9863646 },\n },\n {\n  { 10896332,-7719704,824275,472601,-19460308,3009587,25248958,14783338,-30581476,-15757844 },\n  { 10566929,12612572,-31944212,11118703,-12633376,12362879,21752402,8822496,24003793,14264025 },\n  { 27713862,-7355973,-11008240,9227530,27050101,2504721,23886875,-13117525,13958495,-5732453 },\n },\n {\n  { -23481610,4867226,-27247128,3900521,29838369,-8212291,-31889399,-10041781,7340521,-15410068 },\n  { 4646514,-8011124,-22766023,-11532654,23184553,8566613,31366726,-1381061,-15066784,-10375192 },\n  { -17270517,12723032,-16993061,14878794,21619651,-6197576,27584817,3093888,-8843694,3849921 },\n },\n {\n  { -9064912,2103172,25561640,-15125738,-5239824,9582958,32477045,-9017955,5002294,-15550259 },\n  { -12057553,-11177906,21115585,-13365155,8808712,-12030708,16489530,13378448,-25845716,12741426 },\n  { -5946367,10645103,-30911586,15390284,-3286982,-7118677,24306472,15852464,28834118,-7646072 },\n },\n {\n  { -17335748,-9107057,-24531279,9434953,-8472084,-583362,-13090771,455841,20461858,5491305 },\n  { 13669248,-16095482,-12481974,-10203039,-14569770,-11893198,-24995986,11293807,-28588204,-9421832 },\n  { 28497928,6272777,-33022994,14470570,8906179,-1225630,18504674,-14165166,29867745,-8795943 },\n },\n {\n  { -16207023,13517196,-27799630,-13697798,24009064,-6373891,-6367600,-13175392,22853429,-4012011 },\n  { 24191378,16712145,-13931797,15217831,14542237,1646131,18603514,-11037887,12876623,-2112447 },\n  { 17902668,4518229,-411702,-2829247,26878217,5258055,-12860753,608397,16031844,3723494 },\n },\n {\n  { -28632773,12763728,-20446446,7577504,33001348,-13017745,17558842,-7872890,23896954,-4314245 },\n  { -20005381,-12011952,31520464,605201,2543521,5991821,-2945064,7229064,-9919646,-8826859 },\n  { 28816045,298879,-28165016,-15920938,19000928,-1665890,-12680833,-2949325,-18051778,-2082915 },\n },\n {\n  { 16000882,-344896,3493092,-11447198,-29504595,-13159789,12577740,16041268,-19715240,7847707 },\n  { 10151868,10572098,27312476,7922682,14825339,4723128,-32855931,-6519018,-10020567,3852848 },\n  { -11430470,15697596,-21121557,-4420647,5386314,15063598,16514493,-15932110,29330899,-15076224 },\n },\n},\n{\n {\n  { -25499735,-4378794,-15222908,-6901211,16615731,2051784,3303702,15490,-27548796,12314391 },\n  { 15683520,-6003043,18109120,-9980648,15337968,-5997823,-16717435,15921866,16103996,-3731215 },\n  { -23169824,-10781249,13588192,-1628807,-3798557,-1074929,-19273607,5402699,-29815713,-9841101 },\n },\n {\n  { 23190676,2384583,-32714340,3462154,-29903655,-1529132,-11266856,8911517,-25205859,2739713 },\n  { 21374101,-3554250,-33524649,9874411,15377179,11831242,-33529904,6134907,4931255,11987849 },\n  { -7732,-2978858,-16223486,7277597,105524,-322051,-31480539,13861388,-30076310,10117930 },\n },\n {\n  { -29501170,-10744872,-26163768,13051539,-25625564,5089643,-6325503,6704079,12890019,15728940 },\n  { -21972360,-11771379,-951059,-4418840,14704840,2695116,903376,-10428139,12885167,8311031 },\n  { -17516482,5352194,10384213,-13811658,7506451,13453191,26423267,4384730,1888765,-5435404 },\n },\n {\n  { -25817338,-3107312,-13494599,-3182506,30896459,-13921729,-32251644,-12707869,-19464434,-3340243 },\n  { -23607977,-2665774,-526091,4651136,5765089,4618330,6092245,14845197,17151279,-9854116 },\n  { -24830458,-12733720,-15165978,10367250,-29530908,-265356,22825805,-7087279,-16866484,16176525 },\n },\n {\n  { -23583256,6564961,20063689,3798228,-4740178,7359225,2006182,-10363426,-28746253,-10197509 },\n  { -10626600,-4486402,-13320562,-5125317,3432136,-6393229,23632037,-1940610,32808310,1099883 },\n  { 15030977,5768825,-27451236,-2887299,-6427378,-15361371,-15277896,-6809350,2051441,-15225865 },\n },\n {\n  { -3362323,-7239372,7517890,9824992,23555850,295369,5148398,-14154188,-22686354,16633660 },\n  { 4577086,-16752288,13249841,-15304328,19958763,-14537274,18559670,-10759549,8402478,-9864273 },\n  { -28406330,-1051581,-26790155,-907698,-17212414,-11030789,9453451,-14980072,17983010,9967138 },\n },\n {\n  { -25762494,6524722,26585488,9969270,24709298,1220360,-1677990,7806337,17507396,3651560 },\n  { -10420457,-4118111,14584639,15971087,-15768321,8861010,26556809,-5574557,-18553322,-11357135 },\n  { 2839101,14284142,4029895,3472686,14402957,12689363,-26642121,8459447,-5605463,-7621941 },\n },\n {\n  { -4839289,-3535444,9744961,2871048,25113978,3187018,-25110813,-849066,17258084,-7977739 },\n  { 18164541,-10595176,-17154882,-1542417,19237078,-9745295,23357533,-15217008,26908270,12150756 },\n  { -30264870,-7647865,5112249,-7036672,-1499807,-6974257,43168,-5537701,-32302074,16215819 },\n },\n},\n{\n {\n  { -6898905,9824394,-12304779,-4401089,-31397141,-6276835,32574489,12532905,-7503072,-8675347 },\n  { -27343522,-16515468,-27151524,-10722951,946346,16291093,254968,7168080,21676107,-1943028 },\n  { 21260961,-8424752,-16831886,-11920822,-23677961,3968121,-3651949,-6215466,-3556191,-7913075 },\n },\n {\n  { 16544754,13250366,-16804428,15546242,-4583003,12757258,-2462308,-8680336,-18907032,-9662799 },\n  { -2415239,-15577728,18312303,4964443,-15272530,-12653564,26820651,16690659,25459437,-4564609 },\n  { -25144690,11425020,28423002,-11020557,-6144921,-15826224,9142795,-2391602,-6432418,-1644817 },\n },\n {\n  { -23104652,6253476,16964147,-3768872,-25113972,-12296437,-27457225,-16344658,6335692,7249989 },\n  { -30333227,13979675,7503222,-12368314,-11956721,-4621693,-30272269,2682242,25993170,-12478523 },\n  { 4364628,5930691,32304656,-10044554,-8054781,15091131,22857016,-10598955,31820368,15075278 },\n },\n {\n  { 31879134,-8918693,17258761,90626,-8041836,-4917709,24162788,-9650886,-17970238,12833045 },\n  { 19073683,14851414,-24403169,-11860168,7625278,11091125,-19619190,2074449,-9413939,14905377 },\n  { 24483667,-11935567,-2518866,-11547418,-1553130,15355506,-25282080,9253129,27628530,-7555480 },\n },\n {\n  { 17597607,8340603,19355617,552187,26198470,-3176583,4593324,-9157582,-14110875,15297016 },\n  { 510886,14337390,-31785257,16638632,6328095,2713355,-20217417,-11864220,8683221,2921426 },\n  { 18606791,11874196,27155355,-5281482,-24031742,6265446,-25178240,-1278924,4674690,13890525 },\n },\n {\n  { 13609624,13069022,-27372361,-13055908,24360586,9592974,14977157,9835105,4389687,288396 },\n  { 9922506,-519394,13613107,5883594,-18758345,-434263,-12304062,8317628,23388070,16052080 },\n  { 12720016,11937594,-31970060,-5028689,26900120,8561328,-20155687,-11632979,-14754271,-10812892 },\n },\n {\n  { 15961858,14150409,26716931,-665832,-22794328,13603569,11829573,7467844,-28822128,929275 },\n  { 11038231,-11582396,-27310482,-7316562,-10498527,-16307831,-23479533,-9371869,-21393143,2465074 },\n  { 20017163,-4323226,27915242,1529148,12396362,15675764,13817261,-9658066,2463391,-4622140 },\n },\n {\n  { -16358878,-12663911,-12065183,4996454,-1256422,1073572,9583558,12851107,4003896,12673717 },\n  { -1731589,-15155870,-3262930,16143082,19294135,13385325,14741514,-9103726,7903886,2348101 },\n  { 24536016,-16515207,12715592,-3862155,1511293,10047386,-3842346,-7129159,-28377538,10048127 },\n },\n},\n{\n {\n  { -12622226,-6204820,30718825,2591312,-10617028,12192840,18873298,-7297090,-32297756,15221632 },\n  { -26478122,-11103864,11546244,-1852483,9180880,7656409,-21343950,2095755,29769758,6593415 },\n  { -31994208,-2907461,4176912,3264766,12538965,-868111,26312345,-6118678,30958054,8292160 },\n },\n {\n  { 31429822,-13959116,29173532,15632448,12174511,-2760094,32808831,3977186,26143136,-3148876 },\n  { 22648901,1402143,-22799984,13746059,7936347,365344,-8668633,-1674433,-3758243,-2304625 },\n  { -15491917,8012313,-2514730,-12702462,-23965846,-10254029,-1612713,-1535569,-16664475,8194478 },\n },\n {\n  { 27338066,-7507420,-7414224,10140405,-19026427,-6589889,27277191,8855376,28572286,3005164 },\n  { 26287124,4821776,25476601,-4145903,-3764513,-15788984,-18008582,1182479,-26094821,-13079595 },\n  { -7171154,3178080,23970071,6201893,-17195577,-4489192,-21876275,-13982627,32208683,-1198248 },\n },\n {\n  { -16657702,2817643,-10286362,14811298,6024667,13349505,-27315504,-10497842,-27672585,-11539858 },\n  { 15941029,-9405932,-21367050,8062055,31876073,-238629,-15278393,-1444429,15397331,-4130193 },\n  { 8934485,-13485467,-23286397,-13423241,-32446090,14047986,31170398,-1441021,-27505566,15087184 },\n },\n {\n  { -18357243,-2156491,24524913,-16677868,15520427,-6360776,-15502406,11461896,16788528,-5868942 },\n  { -1947386,16013773,21750665,3714552,-17401782,-16055433,-3770287,-10323320,31322514,-11615635 },\n  { 21426655,-5650218,-13648287,-5347537,-28812189,-4920970,-18275391,-14621414,13040862,-12112948 },\n },\n {\n  { 11293895,12478086,-27136401,15083750,-29307421,14748872,14555558,-13417103,1613711,4896935 },\n  { -25894883,15323294,-8489791,-8057900,25967126,-13425460,2825960,-4897045,-23971776,-11267415 },\n  { -15924766,-5229880,-17443532,6410664,3622847,10243618,20615400,12405433,-23753030,-8436416 },\n },\n {\n  { -7091295,12556208,-20191352,9025187,-17072479,4333801,4378436,2432030,23097949,-566018 },\n  { 4565804,-16025654,20084412,-7842817,1724999,189254,24767264,10103221,-18512313,2424778 },\n  { 366633,-11976806,8173090,-6890119,30788634,5745705,-7168678,1344109,-3642553,12412659 },\n },\n {\n  { -24001791,7690286,14929416,-168257,-32210835,-13412986,24162697,-15326504,-3141501,11179385 },\n  { 18289522,-14724954,8056945,16430056,-21729724,7842514,-6001441,-1486897,-18684645,-11443503 },\n  { 476239,6601091,-6152790,-9723375,17503545,-4863900,27672959,13403813,11052904,5219329 },\n },\n},\n{\n {\n  { 20678546,-8375738,-32671898,8849123,-5009758,14574752,31186971,-3973730,9014762,-8579056 },\n  { -13644050,-10350239,-15962508,5075808,-1514661,-11534600,-33102500,9160280,8473550,-3256838 },\n  { 24900749,14435722,17209120,-15292541,-22592275,9878983,-7689309,-16335821,-24568481,11788948 },\n },\n {\n  { -3118155,-11395194,-13802089,14797441,9652448,-6845904,-20037437,10410733,-24568470,-1458691 },\n  { -15659161,16736706,-22467150,10215878,-9097177,7563911,11871841,-12505194,-18513325,8464118 },\n  { -23400612,8348507,-14585951,-861714,-3950205,-6373419,14325289,8628612,33313881,-8370517 },\n },\n {\n  { -20186973,-4967935,22367356,5271547,-1097117,-4788838,-24805667,-10236854,-8940735,-5818269 },\n  { -6948785,-1795212,-32625683,-16021179,32635414,-7374245,15989197,-12838188,28358192,-4253904 },\n  { -23561781,-2799059,-32351682,-1661963,-9147719,10429267,-16637684,4072016,-5351664,5596589 },\n },\n {\n  { -28236598,-3390048,12312896,6213178,3117142,16078565,29266239,2557221,1768301,15373193 },\n  { -7243358,-3246960,-4593467,-7553353,-127927,-912245,-1090902,-4504991,-24660491,3442910 },\n  { -30210571,5124043,14181784,8197961,18964734,-11939093,22597931,7176455,-18585478,13365930 },\n },\n {\n  { -7877390,-1499958,8324673,4690079,6261860,890446,24538107,-8570186,-9689599,-3031667 },\n  { 25008904,-10771599,-4305031,-9638010,16265036,15721635,683793,-11823784,15723479,-15163481 },\n  { -9660625,12374379,-27006999,-7026148,-7724114,-12314514,11879682,5400171,519526,-1235876 },\n },\n {\n  { 22258397,-16332233,-7869817,14613016,-22520255,-2950923,-20353881,7315967,16648397,7605640 },\n  { -8081308,-8464597,-8223311,9719710,19259459,-15348212,23994942,-5281555,-9468848,4763278 },\n  { -21699244,9220969,-15730624,1084137,-25476107,-2852390,31088447,-7764523,-11356529,728112 },\n },\n {\n  { 26047220,-11751471,-6900323,-16521798,24092068,9158119,-4273545,-12555558,-29365436,-5498272 },\n  { 17510331,-322857,5854289,8403524,17133918,-3112612,-28111007,12327945,10750447,10014012 },\n  { -10312768,3936952,9156313,-8897683,16498692,-994647,-27481051,-666732,3424691,7540221 },\n },\n {\n  { 30322361,-6964110,11361005,-4143317,7433304,4989748,-7071422,-16317219,-9244265,15258046 },\n  { 13054562,-2779497,19155474,469045,-12482797,4566042,5631406,2711395,1062915,-5136345 },\n  { -19240248,-11254599,-29509029,-7499965,-5835763,13005411,-6066489,12194497,32960380,1459310 },\n },\n},\n{\n {\n  { 19852034,7027924,23669353,10020366,8586503,-6657907,394197,-6101885,18638003,-11174937 },\n  { 31395534,15098109,26581030,8030562,-16527914,-5007134,9012486,-7584354,-6643087,-5442636 },\n  { -9192165,-2347377,-1997099,4529534,25766844,607986,-13222,9677543,-32294889,-6456008 },\n },\n {\n  { -2444496,-149937,29348902,8186665,1873760,12489863,-30934579,-7839692,-7852844,-8138429 },\n  { -15236356,-15433509,7766470,746860,26346930,-10221762,-27333451,10754588,-9431476,5203576 },\n  { 31834314,14135496,-770007,5159118,20917671,-16768096,-7467973,-7337524,31809243,7347066 },\n },\n {\n  { -9606723,-11874240,20414459,13033986,13716524,-11691881,19797970,-12211255,15192876,-2087490 },\n  { -12663563,-2181719,1168162,-3804809,26747877,-14138091,10609330,12694420,33473243,-13382104 },\n  { 33184999,11180355,15832085,-11385430,-1633671,225884,15089336,-11023903,-6135662,14480053 },\n },\n {\n  { 31308717,-5619998,31030840,-1897099,15674547,-6582883,5496208,13685227,27595050,8737275 },\n  { -20318852,-15150239,10933843,-16178022,8335352,-7546022,-31008351,-12610604,26498114,66511 },\n  { 22644454,-8761729,-16671776,4884562,-3105614,-13559366,30540766,-4286747,-13327787,-7515095 },\n },\n {\n  { -28017847,9834845,18617207,-2681312,-3401956,-13307506,8205540,13585437,-17127465,15115439 },\n  { 23711543,-672915,31206561,-8362711,6164647,-9709987,-33535882,-1426096,8236921,16492939 },\n  { -23910559,-13515526,-26299483,-4503841,25005590,-7687270,19574902,10071562,6708380,-6222424 },\n },\n {\n  { 2101391,-4930054,19702731,2367575,-15427167,1047675,5301017,9328700,29955601,-11678310 },\n  { 3096359,9271816,-21620864,-15521844,-14847996,-7592937,-25892142,-12635595,-9917575,6216608 },\n  { -32615849,338663,-25195611,2510422,-29213566,-13820213,24822830,-6146567,-26767480,7525079 },\n },\n {\n  { -23066649,-13985623,16133487,-7896178,-3389565,778788,-910336,-2782495,-19386633,11994101 },\n  { 21691500,-13624626,-641331,-14367021,3285881,-3483596,-25064666,9718258,-7477437,13381418 },\n  { 18445390,-4202236,14979846,11622458,-1727110,-3582980,23111648,-6375247,28535282,15779576 },\n },\n {\n  { 30098053,3089662,-9234387,16662135,-21306940,11308411,-14068454,12021730,9955285,-16303356 },\n  { 9734894,-14576830,-7473633,-9138735,2060392,11313496,-18426029,9924399,20194861,13380996 },\n  { -26378102,-7965207,-22167821,15789297,-18055342,-6168792,-1984914,15707771,26342023,10146099 },\n },\n},\n{\n {\n  { -26016874,-219943,21339191,-41388,19745256,-2878700,-29637280,2227040,21612326,-545728 },\n  { -13077387,1184228,23562814,-5970442,-20351244,-6348714,25764461,12243797,-20856566,11649658 },\n  { -10031494,11262626,27384172,2271902,26947504,-15997771,39944,6114064,33514190,2333242 },\n },\n {\n  { -21433588,-12421821,8119782,7219913,-21830522,-9016134,-6679750,-12670638,24350578,-13450001 },\n  { -4116307,-11271533,-23886186,4843615,-30088339,690623,-31536088,-10406836,8317860,12352766 },\n  { 18200138,-14475911,-33087759,-2696619,-23702521,-9102511,-23552096,-2287550,20712163,6719373 },\n },\n {\n  { 26656208,6075253,-7858556,1886072,-28344043,4262326,11117530,-3763210,26224235,-3297458 },\n  { -17168938,-14854097,-3395676,-16369877,-19954045,14050420,21728352,9493610,18620611,-16428628 },\n  { -13323321,13325349,11432106,5964811,18609221,6062965,-5269471,-9725556,-30701573,-16479657 },\n },\n {\n  { -23860538,-11233159,26961357,1640861,-32413112,-16737940,12248509,-5240639,13735342,1934062 },\n  { 25089769,6742589,17081145,-13406266,21909293,-16067981,-15136294,-3765346,-21277997,5473616 },\n  { 31883677,-7961101,1083432,-11572403,22828471,13290673,-7125085,12469656,29111212,-5451014 },\n },\n {\n  { 24244947,-15050407,-26262976,2791540,-14997599,16666678,24367466,6388839,-10295587,452383 },\n  { -25640782,-3417841,5217916,16224624,19987036,-4082269,-24236251,-5915248,15766062,8407814 },\n  { -20406999,13990231,15495425,16395525,5377168,15166495,-8917023,-4388953,-8067909,2276718 },\n },\n {\n  { 30157918,12924066,-17712050,9245753,19895028,3368142,-23827587,5096219,22740376,-7303417 },\n  { 2041139,-14256350,7783687,13876377,-25946985,-13352459,24051124,13742383,-15637599,13295222 },\n  { 33338237,-8505733,12532113,7977527,9106186,-1715251,-17720195,-4612972,-4451357,-14669444 },\n },\n {\n  { -20045281,5454097,-14346548,6447146,28862071,1883651,-2469266,-4141880,7770569,9620597 },\n  { 23208068,7979712,33071466,8149229,1758231,-10834995,30945528,-1694323,-33502340,-14767970 },\n  { 1439958,-16270480,-1079989,-793782,4625402,10647766,-5043801,1220118,30494170,-11440799 },\n },\n {\n  { -5037580,-13028295,-2970559,-3061767,15640974,-6701666,-26739026,926050,-1684339,-13333647 },\n  { 13908495,-3549272,30919928,-6273825,-21521863,7989039,9021034,9078865,3353509,4033511 },\n  { -29663431,-15113610,32259991,-344482,24295849,-12912123,23161163,8839127,27485041,7356032 },\n },\n},\n{\n {\n  { 9661027,705443,11980065,-5370154,-1628543,14661173,-6346142,2625015,28431036,-16771834 },\n  { -23839233,-8311415,-25945511,7480958,-17681669,-8354183,-22545972,14150565,15970762,4099461 },\n  { 29262576,16756590,26350592,-8793563,8529671,-11208050,13617293,-9937143,11465739,8317062 },\n },\n {\n  { -25493081,-6962928,32500200,-9419051,-23038724,-2302222,14898637,3848455,20969334,-5157516 },\n  { -20384450,-14347713,-18336405,13884722,-33039454,2842114,-21610826,-3649888,11177095,14989547 },\n  { -24496721,-11716016,16959896,2278463,12066309,10137771,13515641,2581286,-28487508,9930240 },\n },\n {\n  { -17751622,-2097826,16544300,-13009300,-15914807,-14949081,18345767,-13403753,16291481,-5314038 },\n  { -33229194,2553288,32678213,9875984,8534129,6889387,-9676774,6957617,4368891,9788741 },\n  { 16660756,7281060,-10830758,12911820,20108584,-8101676,-21722536,-8613148,16250552,-11111103 },\n },\n {\n  { -19765507,2390526,-16551031,14161980,1905286,6414907,4689584,10604807,-30190403,4782747 },\n  { -1354539,14736941,-7367442,-13292886,7710542,-14155590,-9981571,4383045,22546403,437323 },\n  { 31665577,-12180464,-16186830,1491339,-18368625,3294682,27343084,2786261,-30633590,-14097016 },\n },\n {\n  { -14467279,-683715,-33374107,7448552,19294360,14334329,-19690631,2355319,-19284671,-6114373 },\n  { 15121312,-15796162,6377020,-6031361,-10798111,-12957845,18952177,15496498,-29380133,11754228 },\n  { -2637277,-13483075,8488727,-14303896,12728761,-1622493,7141596,11724556,22761615,-10134141 },\n },\n {\n  { 16918416,11729663,-18083579,3022987,-31015732,-13339659,-28741185,-12227393,32851222,11717399 },\n  { 11166634,7338049,-6722523,4531520,-29468672,-7302055,31474879,3483633,-1193175,-4030831 },\n  { -185635,9921305,31456609,-13536438,-12013818,13348923,33142652,6546660,-19985279,-3948376 },\n },\n {\n  { -32460596,11266712,-11197107,-7899103,31703694,3855903,-8537131,-12833048,-30772034,-15486313 },\n  { -18006477,12709068,3991746,-6479188,-21491523,-10550425,-31135347,-16049879,10928917,3011958 },\n  { -6957757,-15594337,31696059,334240,29576716,14796075,-30831056,-12805180,18008031,10258577 },\n },\n {\n  { -22448644,15655569,7018479,-4410003,-30314266,-1201591,-1853465,1367120,25127874,6671743 },\n  { 29701166,-14373934,-10878120,9279288,-17568,13127210,21382910,11042292,25838796,4642684 },\n  { -20430234,14955537,-24126347,8124619,-5369288,-5990470,30468147,-13900640,18423289,4177476 },\n },\n},\n} ;\n#endif\n\n\nstatic void ge_select(ge_precomp *t,int pos,signed char b)\n{\n#ifndef CURVED25519_ASM\n  ge_precomp minust;\n  unsigned char bnegative = negative(b);\n  unsigned char babs = b - (((-bnegative) & b) << 1);\n\n  ge_precomp_0(t);\n  cmov(t,&base[pos][0],babs,1);\n  cmov(t,&base[pos][1],babs,2);\n  cmov(t,&base[pos][2],babs,3);\n  cmov(t,&base[pos][3],babs,4);\n  cmov(t,&base[pos][4],babs,5);\n  cmov(t,&base[pos][5],babs,6);\n  cmov(t,&base[pos][6],babs,7);\n  cmov(t,&base[pos][7],babs,8);\n  fe_cswap(t->yminusx, t->yplusx, bnegative);\n  fe_neg(minust.xy2d,t->xy2d);\n  fe_cmov(t->xy2d,minust.xy2d,bnegative);\n#else\n  fe_cmov_table((fe*)t, (fe*)base[pos], b);\n#endif\n}\n\n/*\nh = a * B\nwhere a = a[0]+256*a[1]+...+256^31 a[31]\nB is the Ed25519 base point (x,4/5) with x positive.\n\nPreconditions:\n  a[31] <= 127\n*/\nvoid ge_scalarmult_base(ge_p3 *h,const unsigned char *a)\n{\n  signed char e[64];\n  signed char carry;\n  ge_p1p1 r;\n#ifndef CURVED25519_ASM\n  ge_p2 s;\n#endif\n  ge_precomp t;\n  int i;\n\n  for (i = 0;i < 32;++i) {\n    e[2 * i + 0] = (a[i] >> 0) & 15;\n    e[2 * i + 1] = (a[i] >> 4) & 15;\n  }\n  /* each e[i] is between 0 and 15 */\n  /* e[63] is between 0 and 7 */\n\n  carry = 0;\n  for (i = 0;i < 63;++i) {\n    e[i] += carry;\n    carry = e[i] + 8;\n    carry >>= 4;\n    e[i] -= carry << 4;\n  }\n  e[63] += carry;\n  /* each e[i] is between -8 and 8 */\n\n#ifndef CURVED25519_ASM\n  ge_select(&t,0,e[1]);\n  fe_sub(h->X, t.yplusx, t.yminusx);\n  fe_add(h->Y, t.yplusx, t.yminusx);\n  fe_0(h->Z);\n  h->Z[0] = 4;\n  fe_mul(h->T,h->X,h->Y);\n  fe_add(h->X, h->X, h->X);\n  fe_add(h->Y, h->Y, h->Y);\n\n  for (i = 3;i < 64;i += 2) {\n    ge_select(&t,i / 2,e[i]);\n    ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r);\n  }\n\n  ge_p3_dbl(&r,h);  ge_p1p1_to_p2(&s,&r);\n  ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r);\n  ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r);\n  ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r);\n\n  for (i = 0;i < 64;i += 2) {\n    ge_select(&t,i / 2,e[i]);\n    ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r);\n  }\n#else\n  ge_select(&t, 0, e[0]);\n  fe_sub(h->X, t.yplusx, t.yminusx);\n  fe_add(h->Y, t.yplusx, t.yminusx);\n  fe_0(h->Z);\n  h->Z[0] = 2;\n  fe_copy(h->T, t.xy2d);\n  for (i = 1; i < 64; i++) {\n    ge_select(&t, i, e[i]);\n    ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r);\n  }\n#endif\n}\n\n\n/* ge double scalar mult */\nstatic void slide(signed char *r,const unsigned char *a)\n{\n  int i;\n  int b;\n  int k;\n\n  for (i = 0;i < 256;++i)\n    r[i] = 1 & (a[i >> 3] >> (i & 7));\n\n  for (i = 0;i < 256;++i)\n    if (r[i]) {\n      for (b = 1;b <= 6 && i + b < 256;++b) {\n        if (r[i + b]) {\n          if (r[i] + (r[i + b] << b) <= 15) {\n            r[i] += r[i + b] << b; r[i + b] = 0;\n          } else if (r[i] - (r[i + b] << b) >= -15) {\n            r[i] -= r[i + b] << b;\n            for (k = i + b;k < 256;++k) {\n              if (!r[k]) {\n                r[k] = 1;\n                break;\n              }\n              r[k] = 0;\n            }\n          } else\n            break;\n        }\n      }\n    }\n}\n\n#ifdef CURVED25519_ASM_64BIT\nstatic const ge_precomp Bi[8] = {\n    {\n        { 0x2fbc93c6f58c3b85, -0x306cd2390473f1e7, 0x270b4898643d42c2, 0x07cf9d3a33d4ba65,  },\n        { -0x62efc6fa28bf6ec2, -0x02c660fa2ebf414d, -0x5a3e7bcb977075f7, 0x44fd2f9298f81267,  },\n        { -0x5436edfa78855598, 0x26d9e823ccaac49e, 0x5a1b7dcbdd43598c, 0x6f117b689f0c65a8,  },\n    },\n    {\n        { -0x50da4f57b31168d0, 0x025a8430e8864b8a, -0x3ee4affd60fe98ce, 0x7a164e1b9a80f8f4,  },\n        { 0x56611fe8a4fcd265, 0x3bd353fde5c1ba7d, -0x7ece0ce5deb42943, 0x2ab91587555bda62,  },\n        { 0x14ae933f0dd0d889, 0x589423221c35da62, -0x2e8f1aba730d24b4, 0x5a2826af12b9b4c6,  },\n    },\n    {\n        { -0x5ded43bbf75a44cd, -0x72afb73c38a112fe, -0x22e414f3a54013bc, 0x2945ccf146e206eb,  },\n        { 0x7f9182c3a447d6ba, -0x2affeb2eb4d8d649, -0x1cc30ee3479b5f79, 0x154a7e73eb1b55f3,  },\n        { -0x4344240e7ed57d7b, 0x270e0807d0bdd1fc, -0x4be498f4e44258d3, 0x43aabe696b3bb69a,  },\n    },\n    {\n        { 0x6b1a5cd0944ea3bf, 0x7470353ab39dc0d2, 0x71b2528228542e49, 0x461bea69283c927e,  },\n        { -0x4590d36555cdde4f, 0x6ca021533bba23a7, -0x621589b06de6d3c6, 0x1d6edd5d2e5317e0,  },\n        { -0x0e7c9237fe474c5e, -0x4cfca0b8fac15b66, 0x529c41ba5877adf3, 0x7a9fbb1c6a0f90a7,  },\n    },\n    {\n        { -0x64d1987559579cd1, -0x59af6190ae43b93b, -0x314dcc3639790a4b, 0x34b9ed338add7f59,  },\n        { -0x0c91de81fc627f9c, -0x675f7e490adfbe65, -0x693439f718a14fbc, 0x49c05a51fadc9c8f,  },\n        { 0x06b4e8bf9045af1b, -0x1d007c1758e62dd1, -0x550903d66c2b30ea, 0x73c172021b008b06,  },\n    },\n    {\n        { 0x2fbf00848a802ade, -0x1a260130fdcfd1d9, 0x113e847117703406, 0x4275aae2546d8faf,  },\n        { 0x315f5b0249864348, 0x3ed6b36977088381, -0x5c5f8aaa9572146b, 0x18ab598029d5c77f,  },\n        { -0x27d4d33a029f7617, 0x031eb4a13282e4a4, 0x44311199b51a8622, 0x3dc65522b53df948,  },\n    },\n    {\n        { -0x408f3ddd5dff8093, -0x407b4c654a432125, 0x537a0e12fb07ba07, 0x234fd7eec346f241,  },\n        { 0x506f013b327fbf93, -0x5103143664889095, -0x62ed4dcd5552a698, 0x0267882d176024a7,  },\n        { 0x5360a119732ea378, 0x2437e6b1df8dd471, -0x5d10c8076e581acd, 0x497ba6fdaa097863,  },\n    },\n    {\n        { 0x24cecc0313cfeaa0, -0x79b73d72e763db93, 0x2dbdbdfac1f2d4d0, 0x61e22917f12de72b,  },\n        { 0x040bcd86468ccf0b, -0x2c7d645bd566ef2a, 0x7508300807b25192, 0x43b5cd4218d05ebf,  },\n        { 0x5d9a762f9bd0b516, -0x14c750b1c8c02112, 0x032e5a7d93d64270, 0x511d61210ae4d842,  },\n    },\n};\n#elif defined(CURVED25519_ASM_32BIT)\nstatic const ge_precomp Bi[8] = {\n    {\n        { -0x0a73c47b, 0x2fbc93c6, -0x0473f1e7, -0x306cd23a, 0x643d42c2, 0x270b4898, 0x33d4ba65, 0x07cf9d3a,  },\n        { -0x28bf6ec2, -0x62efc6fb, -0x2ebf414d, -0x02c660fb, 0x688f8a09, -0x5a3e7bcc, -0x6707ed99, 0x44fd2f92,  },\n        { -0x78855598, -0x5436edfb, -0x33553b62, 0x26d9e823, -0x22bca674, 0x5a1b7dcb, -0x60f39a58, 0x6f117b68,  },\n    },\n    {\n        { 0x4cee9730, -0x50da4f58, -0x1779b476, 0x025a8430, -0x60fe98ce, -0x3ee4affe, -0x657f070c, 0x7a164e1b,  },\n        { -0x5b032d9b, 0x56611fe8, -0x1a3e4583, 0x3bd353fd, 0x214bd6bd, -0x7ece0ce6, 0x555bda62, 0x2ab91587,  },\n        { 0x0dd0d889, 0x14ae933f, 0x1c35da62, 0x58942322, -0x730d24b4, -0x2e8f1abb, 0x12b9b4c6, 0x5a2826af,  },\n    },\n    {\n        { 0x08a5bb33, -0x5ded43bc, -0x38a112fe, -0x72afb73d, 0x5abfec44, -0x22e414f4, 0x46e206eb, 0x2945ccf1,  },\n        { -0x5bb82946, 0x7f9182c3, 0x4b2729b7, -0x2affeb2f, -0x479b5f79, -0x1cc30ee4, -0x14e4aa0d, 0x154a7e73,  },\n        { -0x7ed57d7b, -0x4344240f, -0x2f422e04, 0x270e0807, 0x1bbda72d, -0x4be498f5, 0x6b3bb69a, 0x43aabe69,  },\n    },\n    {\n        { -0x6bb15c41, 0x6b1a5cd0, -0x4c623f2e, 0x7470353a, 0x28542e49, 0x71b25282, 0x283c927e, 0x461bea69,  },\n        { -0x55cdde4f, -0x4590d366, 0x3bba23a7, 0x6ca02153, -0x6de6d3c6, -0x621589b1, 0x2e5317e0, 0x1d6edd5d,  },\n        { 0x01b8b3a2, -0x0e7c9238, 0x053ea49a, -0x4cfca0b9, 0x5877adf3, 0x529c41ba, 0x6a0f90a7, 0x7a9fbb1c,  },\n    },\n    {\n        { -0x59579cd1, -0x64d19876, 0x51bc46c5, -0x59af6191, -0x39790a4b, -0x314dcc37, -0x752280a7, 0x34b9ed33,  },\n        { 0x039d8064, -0x0c91de82, -0x0adfbe65, -0x675f7e4a, -0x18a14fbc, -0x693439f8, -0x05236371, 0x49c05a51,  },\n        { -0x6fba50e5, 0x06b4e8bf, -0x58e62dd1, -0x1d007c18, -0x6c2b30ea, -0x550903d7, 0x1b008b06, 0x73c17202,  },\n    },\n    {\n        { -0x757fd522, 0x2fbf0084, 0x02302e27, -0x1a260131, 0x17703406, 0x113e8471, 0x546d8faf, 0x4275aae2,  },\n        { 0x49864348, 0x315f5b02, 0x77088381, 0x3ed6b369, 0x6a8deb95, -0x5c5f8aab, 0x29d5c77f, 0x18ab5980,  },\n        { -0x029f7617, -0x27d4d33b, 0x3282e4a4, 0x031eb4a1, -0x4ae579de, 0x44311199, -0x4ac206b8, 0x3dc65522,  },\n    },\n    {\n        { -0x5dff8093, -0x408f3dde, -0x4a432125, -0x407b4c66, -0x04f845f9, 0x537a0e12, -0x3cb90dbf, 0x234fd7ee,  },\n        { 0x327fbf93, 0x506f013b, -0x64889095, -0x51031437, -0x5552a698, -0x62ed4dce, 0x176024a7, 0x0267882d,  },\n        { 0x732ea378, 0x5360a119, -0x20722b8f, 0x2437e6b1, -0x6e581acd, -0x5d10c808, -0x55f6879d, 0x497ba6fd,  },\n    },\n    {\n        { 0x13cfeaa0, 0x24cecc03, 0x189c246d, -0x79b73d73, -0x3e0d2b30, 0x2dbdbdfa, -0x0ed218d5, 0x61e22917,  },\n        { 0x468ccf0b, 0x040bcd86, 0x2a9910d6, -0x2c7d645c, 0x07b25192, 0x75083008, 0x18d05ebf, 0x43b5cd42,  },\n        { -0x642f4aea, 0x5d9a762f, 0x373fdeee, -0x14c750b2, -0x6c29bd90, 0x032e5a7d, 0x0ae4d842, 0x511d6121,  },\n    },\n};\n#elif defined(CURVED25519_128BIT)\nstatic const ge_precomp Bi[8] = {\n    {\n        { 0x493c6f58c3b85, 0x0df7181c325f7, 0x0f50b0b3e4cb7, 0x5329385a44c32, 0x07cf9d3a33d4b },\n        { 0x03905d740913e, 0x0ba2817d673a2, 0x23e2827f4e67c, 0x133d2e0c21a34, 0x44fd2f9298f81 },\n        { 0x11205877aaa68, 0x479955893d579, 0x50d66309b67a0, 0x2d42d0dbee5ee, 0x6f117b689f0c6 },\n    },\n    {\n        { 0x5b0a84cee9730, 0x61d10c97155e4, 0x4059cc8096a10, 0x47a608da8014f, 0x7a164e1b9a80f },\n        { 0x11fe8a4fcd265, 0x7bcb8374faacc, 0x52f5af4ef4d4f, 0x5314098f98d10, 0x2ab91587555bd },\n        { 0x6933f0dd0d889, 0x44386bb4c4295, 0x3cb6d3162508c, 0x26368b872a2c6, 0x5a2826af12b9b },\n    },\n    {\n        { 0x2bc4408a5bb33, 0x078ebdda05442, 0x2ffb112354123, 0x375ee8df5862d, 0x2945ccf146e20 },\n        { 0x182c3a447d6ba, 0x22964e536eff2, 0x192821f540053, 0x2f9f19e788e5c, 0x154a7e73eb1b5 },\n        { 0x3dbf1812a8285, 0x0fa17ba3f9797, 0x6f69cb49c3820, 0x34d5a0db3858d, 0x43aabe696b3bb },\n    },\n    {\n        { 0x25cd0944ea3bf, 0x75673b81a4d63, 0x150b925d1c0d4, 0x13f38d9294114, 0x461bea69283c9 },\n        { 0x72c9aaa3221b1, 0x267774474f74d, 0x064b0e9b28085, 0x3f04ef53b27c9, 0x1d6edd5d2e531 },\n        { 0x36dc801b8b3a2, 0x0e0a7d4935e30, 0x1deb7cecc0d7d, 0x053a94e20dd2c, 0x7a9fbb1c6a0f9 },\n    },\n    {\n        { 0x6678aa6a8632f, 0x5ea3788d8b365, 0x21bd6d6994279, 0x7ace75919e4e3, 0x34b9ed338add7 },\n        { 0x6217e039d8064, 0x6dea408337e6d, 0x57ac112628206, 0x647cb65e30473, 0x49c05a51fadc9 },\n        { 0x4e8bf9045af1b, 0x514e33a45e0d6, 0x7533c5b8bfe0f, 0x583557b7e14c9, 0x73c172021b008 },\n    },\n    {\n        { 0x700848a802ade, 0x1e04605c4e5f7, 0x5c0d01b9767fb, 0x7d7889f42388b, 0x4275aae2546d8 },\n        { 0x75b0249864348, 0x52ee11070262b, 0x237ae54fb5acd, 0x3bfd1d03aaab5, 0x18ab598029d5c },\n        { 0x32cc5fd6089e9, 0x426505c949b05, 0x46a18880c7ad2, 0x4a4221888ccda, 0x3dc65522b53df },\n    },\n    {\n        { 0x0c222a2007f6d, 0x356b79bdb77ee, 0x41ee81efe12ce, 0x120a9bd07097d, 0x234fd7eec346f },\n        { 0x7013b327fbf93, 0x1336eeded6a0d, 0x2b565a2bbf3af, 0x253ce89591955, 0x0267882d17602 },\n        { 0x0a119732ea378, 0x63bf1ba8e2a6c, 0x69f94cc90df9a, 0x431d1779bfc48, 0x497ba6fdaa097 },\n    },\n    {\n        { 0x6cc0313cfeaa0, 0x1a313848da499, 0x7cb534219230a, 0x39596dedefd60, 0x61e22917f12de },\n        { 0x3cd86468ccf0b, 0x48553221ac081, 0x6c9464b4e0a6e, 0x75fba84180403, 0x43b5cd4218d05 },\n        { 0x2762f9bd0b516, 0x1c6e7fbddcbb3, 0x75909c3ace2bd, 0x42101972d3ec9, 0x511d61210ae4d },\n    },\n};\n#else\nstatic const ge_precomp Bi[8] = {\n {\n  { 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 },\n  { -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 },\n  { -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 },\n },\n {\n  { 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 },\n  { 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 },\n  { 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 },\n },\n {\n  { 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 },\n  { 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 },\n  { 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 },\n },\n {\n  { 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 },\n  { -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 },\n  { 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 },\n },\n {\n  { -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 },\n  { -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 },\n  { 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 },\n },\n {\n  { -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 },\n  { 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 },\n  { 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 },\n },\n {\n  { -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 },\n  { -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 },\n  { -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 },\n },\n {\n  { -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 },\n  { -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 },\n  { -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 },\n },\n} ;\n#endif\n\n\n/*\nr = a * A + b * B\nwhere a = a[0]+256*a[1]+...+256^31 a[31].\nand b = b[0]+256*b[1]+...+256^31 b[31].\nB is the Ed25519 base point (x,4/5) with x positive.\n*/\nint ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a,\n                                 const ge_p3 *A, const unsigned char *b)\n{\n  signed char aslide[256];\n  signed char bslide[256];\n  ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */\n  ge_p1p1 t;\n  ge_p3 u;\n  ge_p3 A2;\n  int i;\n\n  slide(aslide,a);\n  slide(bslide,b);\n\n  ge_p3_to_cached(&Ai[0],A);\n  ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t);\n  ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u);\n  ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u);\n  ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u);\n  ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u);\n  ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u);\n  ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u);\n  ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u);\n\n  ge_p2_0(r);\n\n  for (i = 255;i >= 0;--i) {\n    if (aslide[i] || bslide[i]) break;\n  }\n\n  for (;i >= 0;--i) {\n    ge_p2_dbl(&t,r);\n\n    if (aslide[i] > 0) {\n      ge_p1p1_to_p3(&u,&t);\n      ge_add(&t,&u,&Ai[aslide[i]/2]);\n    } else if (aslide[i] < 0) {\n      ge_p1p1_to_p3(&u,&t);\n      ge_sub(&t,&u,&Ai[(-aslide[i])/2]);\n    }\n\n    if (bslide[i] > 0) {\n      ge_p1p1_to_p3(&u,&t);\n      ge_madd(&t,&u,&Bi[bslide[i]/2]);\n    } else if (bslide[i] < 0) {\n      ge_p1p1_to_p3(&u,&t);\n      ge_msub(&t,&u,&Bi[(-bslide[i])/2]);\n    }\n\n    ge_p1p1_to_p2(r,&t);\n  }\n\n  return 0;\n}\n\n#ifdef CURVED25519_ASM_64BIT\nstatic const ge d = {\n    0x75eb4dca135978a3, 0x00700a4d4141d8ab, -0x7338bf8688861768, 0x52036cee2b6ffe73,\n};\n#elif defined(CURVED25519_ASM_32BIT)\nstatic const ge d = {\n    0x135978a3, 0x75eb4dca, 0x4141d8ab, 0x00700a4d, 0x7779e898, -0x7338bf87, 0x2b6ffe73, 0x52036cee,\n};\n#elif defined(CURVED25519_128BIT)\nstatic const ge d = {\n    0x34dca135978a3, 0x1a8283b156ebd, 0x5e7a26001c029, 0x739c663a03cbb,\n    0x52036cee2b6ff\n};\n#else\nstatic const ge d = {\n-10913610,13857413,-15372611,6949391,114729,\n-8787816,-6275908,-3247719,-18696448,-12055116\n};\n#endif\n\n\n#ifdef CURVED25519_ASM_64BIT\nstatic const ge sqrtm1 = {\n    -0x3b11e4d8b5f15f50, 0x2f431806ad2fe478, 0x2b4d00993dfbd7a7, 0x2b8324804fc1df0b,\n};\n#elif defined(CURVED25519_ASM_32BIT)\nstatic const ge sqrtm1 = {\n    0x4a0ea0b0, -0x3b11e4d9, -0x52d01b88, 0x2f431806, 0x3dfbd7a7, 0x2b4d0099, 0x4fc1df0b, 0x2b832480,\n};\n#elif defined(CURVED25519_128BIT)\nstatic const ge sqrtm1 = {\n    0x61b274a0ea0b0, 0x0d5a5fc8f189d, 0x7ef5e9cbd0c60, 0x78595a6804c9e,\n    0x2b8324804fc1d\n};\n#else\nstatic const ge sqrtm1 = {\n-32595792,-7943725,9377950,3500415,12389472,\n-272473,-25146209,-2005654,326686,11406482\n};\n#endif\n\n\nint ge_frombytes_negate_vartime(ge_p3 *h,const unsigned char *s)\n{\n  ge u;\n  ge v;\n  ge v3;\n  ge vxx;\n  ge check;\n\n  fe_frombytes(h->Y,s);\n  fe_1(h->Z);\n  fe_sq(u,h->Y);\n  fe_mul(v,u,d);\n  fe_sub(u,u,h->Z);       /* u = y^2-1 */\n  fe_add(v,v,h->Z);       /* v = dy^2+1 */\n\n\n  fe_sq(v3,v);\n  fe_mul(v3,v3,v);        /* v3 = v^3 */\n  fe_sq(h->X,v3);\n  fe_mul(h->X,h->X,v);\n  fe_mul(h->X,h->X,u);    /* x = uv^7 */\n\n  fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */\n  fe_mul(h->X,h->X,v3);\n  fe_mul(h->X,h->X,u);    /* x = uv^3(uv^7)^((q-5)/8) */\n\n  fe_sq(vxx,h->X);\n  fe_mul(vxx,vxx,v);\n  fe_sub(check,vxx,u);    /* vx^2-u */\n  if (fe_isnonzero(check)) {\n    fe_add(check,vxx,u);  /* vx^2+u */\n    if (fe_isnonzero(check)) return -1;\n    fe_mul(h->X,h->X,sqrtm1);\n  }\n\n  if (fe_isnegative(h->X) == (s[31] >> 7))\n    fe_neg(h->X,h->X);\n\n  fe_mul(h->T,h->X,h->Y);\n  return 0;\n}\n\n\n/* ge madd */\n/*\nr = p + q\n*/\n\nstatic WC_INLINE void ge_madd(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q)\n{\n#ifndef CURVED25519_ASM\n    ge t0;\n    fe_add(r->X,p->Y,p->X);\n    fe_sub(r->Y,p->Y,p->X);\n    fe_mul(r->Z,r->X,q->yplusx);\n    fe_mul(r->Y,r->Y,q->yminusx);\n    fe_mul(r->T,q->xy2d,p->T);\n    fe_add(t0,p->Z,p->Z);\n    fe_sub(r->X,r->Z,r->Y);\n    fe_add(r->Y,r->Z,r->Y);\n    fe_add(r->Z,t0,r->T);\n    fe_sub(r->T,t0,r->T);\n#else\n    fe_ge_madd(r->X, r->Y, r->Z, r->T, p->X, p->Y, p->Z, p->T, q->xy2d,\n              q->yplusx, q->yminusx);\n#endif\n}\n\n\n/* ge msub */\n\n/*\nr = p - q\n*/\n\nstatic WC_INLINE void ge_msub(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q)\n{\n#ifndef CURVED25519_ASM\n    ge t0;\n    fe_add(r->X,p->Y,p->X);\n    fe_sub(r->Y,p->Y,p->X);\n    fe_mul(r->Z,r->X,q->yminusx);\n    fe_mul(r->Y,r->Y,q->yplusx);\n    fe_mul(r->T,q->xy2d,p->T);\n    fe_add(t0,p->Z,p->Z);\n    fe_sub(r->X,r->Z,r->Y);\n    fe_add(r->Y,r->Z,r->Y);\n    fe_sub(r->Z,t0,r->T);\n    fe_add(r->T,t0,r->T);\n#else\n    fe_ge_msub(r->X, r->Y, r->Z, r->T, p->X, p->Y, p->Z, p->T, q->xy2d,\n              q->yplusx, q->yminusx);\n#endif\n}\n\n\n/* ge p1p1 to p2 */\n/*\nr = p\n*/\n\nstatic void ge_p1p1_to_p2(ge_p2 *r,const ge_p1p1 *p)\n{\n#ifndef CURVED25519_ASM\n  fe_mul(r->X,p->X,p->T);\n  fe_mul(r->Y,p->Y,p->Z);\n  fe_mul(r->Z,p->Z,p->T);\n#else\n  fe_ge_to_p2(r->X, r->Y, r->Z, p->X, p->Y, p->Z, p->T);\n#endif\n}\n\n\n/* ge p1p1 to p3 */\n\n/*\nr = p\n*/\n\nstatic WC_INLINE void ge_p1p1_to_p3(ge_p3 *r,const ge_p1p1 *p)\n{\n#ifndef CURVED25519_ASM\n  fe_mul(r->X,p->X,p->T);\n  fe_mul(r->Y,p->Y,p->Z);\n  fe_mul(r->Z,p->Z,p->T);\n  fe_mul(r->T,p->X,p->Y);\n#else\n  fe_ge_to_p3(r->X, r->Y, r->Z, r->T, p->X, p->Y, p->Z, p->T);\n#endif\n}\n\n\n/* ge p2 0 */\n\nstatic void ge_p2_0(ge_p2 *h)\n{\n  fe_0(h->X);\n  fe_1(h->Y);\n  fe_1(h->Z);\n}\n\n\n/* ge p2 dbl */\n\n/*\nr = 2 * p\n*/\n\nstatic WC_INLINE void ge_p2_dbl(ge_p1p1 *r,const ge_p2 *p)\n{\n#ifndef CURVED25519_ASM\n    ge t0;\n    fe_sq(r->X,p->X);\n    fe_sq(r->Z,p->Y);\n    fe_sq2(r->T,p->Z);\n    fe_add(r->Y,p->X,p->Y);\n    fe_sq(t0,r->Y);\n    fe_add(r->Y,r->Z,r->X);\n    fe_sub(r->Z,r->Z,r->X);\n    fe_sub(r->X,t0,r->Y);\n    fe_sub(r->T,r->T,r->Z);\n#else\n    fe_ge_dbl(r->X, r->Y, r->Z, r->T, p->X, p->Y, p->Z);\n#endif\n}\n\n\n/* ge p3 dble */\n\n/*\nr = 2 * p\n*/\n\nstatic void ge_p3_dbl(ge_p1p1 *r,const ge_p3 *p)\n{\n  ge_p2 q;\n  ge_p3_to_p2(&q,p);\n  ge_p2_dbl(r,&q);\n}\n\n\n/* ge p3 to cached */\n\n/*\nr = p\n*/\n\n#ifdef CURVED25519_ASM_64BIT\nstatic const ge d2 = {\n    -0x1429646bd94d0ea7, 0x00e0149a8283b156, 0x198e80f2eef3d130, 0x2406d9dc56dffce7,\n};\n#elif defined(CURVED25519_ASM_32BIT)\nstatic const ge d2 = {\n    0x26b2f159, -0x1429646c, -0x7d7c4eaa, 0x00e0149a, -0x110c2ed0, 0x198e80f2, 0x56dffce7, 0x2406d9dc,\n};\n#elif defined(CURVED25519_128BIT)\nstatic const ge d2 = {\n    0x69b9426b2f159, 0x35050762add7a, 0x3cf44c0038052, 0x6738cc7407977,\n    0x2406d9dc56dff\n};\n#else\nstatic const ge d2 = {\n-21827239,-5839606,-30745221,13898782,229458,\n15978800,-12551817,-6495438,29715968,9444199\n} ;\n#endif\n\n\nstatic WC_INLINE void ge_p3_to_cached(ge_cached *r,const ge_p3 *p)\n{\n  fe_add(r->YplusX,p->Y,p->X);\n  fe_sub(r->YminusX,p->Y,p->X);\n  fe_copy(r->Z,p->Z);\n  fe_mul(r->T2d,p->T,d2);\n}\n\n\n/* ge p3 to p2 */\n/*\nr = p\n*/\n\nstatic void ge_p3_to_p2(ge_p2 *r,const ge_p3 *p)\n{\n  fe_copy(r->X,p->X);\n  fe_copy(r->Y,p->Y);\n  fe_copy(r->Z,p->Z);\n}\n\n\n/* ge p3 tobytes */\nvoid ge_p3_tobytes(unsigned char *s,const ge_p3 *h)\n{\n  ge recip;\n  ge x;\n  ge y;\n\n  fe_invert(recip,h->Z);\n  fe_mul(x,h->X,recip);\n  fe_mul(y,h->Y,recip);\n  fe_tobytes(s,y);\n  s[31] ^= fe_isnegative(x) << 7;\n}\n\n\n#ifndef CURVED25519_ASM\n/* ge_precomp_0 */\nstatic void ge_precomp_0(ge_precomp *h)\n{\n  fe_1(h->yplusx);\n  fe_1(h->yminusx);\n  fe_0(h->xy2d);\n}\n#endif\n\n\n/* ge_sub */\n/*\nr = p - q\n*/\n\nstatic WC_INLINE void ge_sub(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q)\n{\n#ifndef CURVED25519_ASM\n    ge t0;\n    fe_add(r->X,p->Y,p->X);\n    fe_sub(r->Y,p->Y,p->X);\n    fe_mul(r->Z,r->X,q->YminusX);\n    fe_mul(r->Y,r->Y,q->YplusX);\n    fe_mul(r->T,q->T2d,p->T);\n    fe_mul(r->X,p->Z,q->Z);\n    fe_add(t0,r->X,r->X);\n    fe_sub(r->X,r->Z,r->Y);\n    fe_add(r->Y,r->Z,r->Y);\n    fe_sub(r->Z,t0,r->T);\n    fe_add(r->T,t0,r->T);\n#else\n    fe_ge_sub(r->X, r->Y, r->Z, r->T, p->X, p->Y, p->Z, p->T, q->Z, q->T2d,\n              q->YplusX, q->YminusX);\n#endif\n}\n\n\n/* ge tobytes */\nvoid ge_tobytes(unsigned char *s,const ge_p2 *h)\n{\n  ge recip;\n  ge x;\n  ge y;\n\n  fe_invert(recip,h->Z);\n  fe_mul(x,h->X,recip);\n  fe_mul(y,h->Y,recip);\n  fe_tobytes(s,y);\n  s[31] ^= fe_isnegative(x) << 7;\n}\n\n#endif /* !ED25519_SMALL */\n#endif /* HAVE_ED25519 */\n"
  },
  {
    "path": "src/wolfcrypt/src/hash.c",
    "content": "/* hash.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#ifndef NO_ASN\n#include <wolfssl/wolfcrypt/asn.h>\n#endif\n\n#include <wolfssl/wolfcrypt/hash.h>\n#include <wolfssl/wolfcrypt/hmac.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\n#ifdef NO_ASN\nenum Hash_Sum  {\n    MD2h      = 646,\n    MD5h      = 649,\n    SHAh      =  88,\n    SHA224h   = 417,\n    SHA256h   = 414,\n    SHA384h   = 415,\n    SHA512h   = 416,\n    SHA3_224h = 420,\n    SHA3_256h = 421,\n    SHA3_384h = 422,\n    SHA3_512h = 423\n};\n#endif /* !NO_ASN */\n\n/* function converts int hash type to enum */\nenum wc_HashType wc_HashTypeConvert(int hashType)\n{\n    /* Default to hash type none as error */\n    enum wc_HashType eHashType = WC_HASH_TYPE_NONE;\n#if defined(HAVE_FIPS) || defined(HAVE_SELFTEST)\n    /* original FIPSv1  and CAVP selftest require a mapping for unique hash\n       type to wc_HashType */\n    switch (hashType) {\n    #ifndef NO_MD5\n        case WC_MD5:\n            eHashType = WC_HASH_TYPE_MD5;\n            break;\n    #endif /* !NO_MD5 */\n    #ifndef NO_SHA\n        case WC_SHA:\n            eHashType = WC_HASH_TYPE_SHA;\n            break;\n    #endif /* !NO_SHA */\n\n    #ifdef WOLFSSL_SHA224\n        case WC_SHA224:\n            eHashType = WC_HASH_TYPE_SHA224;\n            break;\n    #endif /* WOLFSSL_SHA224 */\n\n    #ifndef NO_SHA256\n        case WC_SHA256:\n            eHashType = WC_HASH_TYPE_SHA256;\n            break;\n    #endif /* !NO_SHA256 */\n\n    #ifdef WOLFSSL_SHA384\n        case WC_SHA384:\n            eHashType = WC_HASH_TYPE_SHA384;\n            break;\n    #endif /* WOLFSSL_SHA384 */\n    #ifdef WOLFSSL_SHA512\n        case WC_SHA512:\n            eHashType = WC_HASH_TYPE_SHA512;\n            break;\n    #endif /* WOLFSSL_SHA512 */\n    #ifdef WOLFSSL_SHA3\n        case WC_SHA3_224:\n            eHashType = WC_HASH_TYPE_SHA3_224;\n            break;\n        case WC_SHA3_256:\n            eHashType = WC_HASH_TYPE_SHA3_256;\n            break;\n        case WC_SHA3_384:\n            eHashType = WC_HASH_TYPE_SHA3_384;\n            break;\n        case WC_SHA3_512:\n            eHashType = WC_HASH_TYPE_SHA3_512;\n            break;\n    #endif /* WOLFSSL_SHA3 */\n        default:\n            eHashType = WC_HASH_TYPE_NONE;\n            break;\n    }\n#else\n    /* current master uses same unique types as wc_HashType */\n    if (hashType > 0 && hashType <= WC_HASH_TYPE_MAX) {\n        eHashType = (enum wc_HashType)hashType;\n    }\n#endif\n    return eHashType;\n}\n\n#if !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC)\n\nint wc_HashGetOID(enum wc_HashType hash_type)\n{\n    int oid = HASH_TYPE_E; /* Default to hash type error */\n    switch(hash_type)\n    {\n        case WC_HASH_TYPE_MD2:\n        #ifdef WOLFSSL_MD2\n            oid = MD2h;\n        #endif\n            break;\n        case WC_HASH_TYPE_MD5_SHA:\n        case WC_HASH_TYPE_MD5:\n        #ifndef NO_MD5\n            oid = MD5h;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA:\n        #ifndef NO_SHA\n            oid = SHAh;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA224:\n        #ifdef WOLFSSL_SHA224\n            oid = SHA224h;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA256:\n        #ifndef NO_SHA256\n            oid = SHA256h;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA384:\n        #ifdef WOLFSSL_SHA384\n            oid = SHA384h;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA512:\n        #ifdef WOLFSSL_SHA512\n            oid = SHA512h;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA3_224:\n        #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)\n            oid = SHA3_224h;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA3_256:\n        #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)\n            oid = SHA3_256h;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA3_384:\n        #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)\n            oid = SHA3_384h;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA3_512:\n        #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)\n            oid = SHA3_512h;\n        #endif\n            break;\n\n        /* Not Supported */\n        case WC_HASH_TYPE_MD4:\n        case WC_HASH_TYPE_BLAKE2B:\n        case WC_HASH_TYPE_BLAKE2S:\n        case WC_HASH_TYPE_NONE:\n        default:\n            oid = BAD_FUNC_ARG;\n            break;\n    }\n    return oid;\n}\n\nenum wc_HashType wc_OidGetHash(int oid)\n{\n    enum wc_HashType hash_type = WC_HASH_TYPE_NONE;\n    switch (oid)\n    {\n    #ifdef WOLFSSL_MD2\n        case MD2h:\n            hash_type = WC_HASH_TYPE_MD2;\n            break;\n    #endif\n        case MD5h:\n        #ifndef NO_MD5\n            hash_type = WC_HASH_TYPE_MD5;\n        #endif\n            break;\n        case SHAh:\n        #ifndef NO_SHA\n            hash_type = WC_HASH_TYPE_SHA;\n        #endif\n            break;\n        case SHA224h:\n        #ifdef WOLFSSL_SHA224\n            hash_type = WC_HASH_TYPE_SHA224;\n        #endif\n            break;\n        case SHA256h:\n        #ifndef NO_SHA256\n            hash_type = WC_HASH_TYPE_SHA256;\n        #endif\n            break;\n        case SHA384h:\n        #ifdef WOLFSSL_SHA384\n            hash_type = WC_HASH_TYPE_SHA384;\n        #endif\n            break;\n        case SHA512h:\n        #ifdef WOLFSSL_SHA512\n            hash_type = WC_HASH_TYPE_SHA512;\n        #endif\n            break;\n    #ifdef WOLFSSL_SHA3\n        case SHA3_224h:\n            hash_type = WC_HASH_TYPE_SHA3_224;\n            break;\n        case SHA3_256h:\n            hash_type = WC_HASH_TYPE_SHA3_256;\n            break;\n        case SHA3_384h:\n            hash_type = WC_HASH_TYPE_SHA3_384;\n            break;\n        case SHA3_512h:\n            hash_type = WC_HASH_TYPE_SHA3_512;\n            break;\n    #endif /* WOLFSSL_SHA3 */\n        default:\n            break;\n    }\n    return hash_type;\n}\n#endif /* !NO_ASN || !NO_DH || HAVE_ECC */\n\n\n\n/* Get Hash digest size */\nint wc_HashGetDigestSize(enum wc_HashType hash_type)\n{\n    int dig_size = HASH_TYPE_E; /* Default to hash type error */\n    switch(hash_type)\n    {\n        case WC_HASH_TYPE_MD2:\n        #ifdef WOLFSSL_MD2\n            dig_size = MD2_DIGEST_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_MD4:\n        #ifndef NO_MD4\n            dig_size = MD4_DIGEST_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_MD5:\n        #ifndef NO_MD5\n            dig_size = WC_MD5_DIGEST_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA:\n        #ifndef NO_SHA\n            dig_size = WC_SHA_DIGEST_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA224:\n        #ifdef WOLFSSL_SHA224\n            dig_size = WC_SHA224_DIGEST_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA256:\n        #ifndef NO_SHA256\n            dig_size = WC_SHA256_DIGEST_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA384:\n        #ifdef WOLFSSL_SHA384\n            dig_size = WC_SHA384_DIGEST_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA512:\n        #ifdef WOLFSSL_SHA512\n            dig_size = WC_SHA512_DIGEST_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_MD5_SHA: /* Old TLS Specific */\n        #if !defined(NO_MD5) && !defined(NO_SHA)\n            dig_size = (int)WC_MD5_DIGEST_SIZE + (int)WC_SHA_DIGEST_SIZE;\n        #endif\n            break;\n\n        case WC_HASH_TYPE_SHA3_224:\n        #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)\n            dig_size = WC_SHA3_224_DIGEST_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA3_256:\n        #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)\n            dig_size = WC_SHA3_256_DIGEST_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA3_384:\n        #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)\n            dig_size = WC_SHA3_384_DIGEST_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA3_512:\n        #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)\n            dig_size = WC_SHA3_512_DIGEST_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_BLAKE2B:\n        case WC_HASH_TYPE_BLAKE2S:\n        #if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S)\n            dig_size = BLAKE2S_OUTBYTES;\n        #endif\n            break;\n\n        /* Not Supported */\n        case WC_HASH_TYPE_NONE:\n        default:\n            dig_size = BAD_FUNC_ARG;\n            break;\n    }\n    return dig_size;\n}\n\n\n/* Get Hash block size */\nint wc_HashGetBlockSize(enum wc_HashType hash_type)\n{\n    int block_size = HASH_TYPE_E; /* Default to hash type error */\n    switch (hash_type)\n    {\n        case WC_HASH_TYPE_MD2:\n        #ifdef WOLFSSL_MD2\n            block_size = MD2_BLOCK_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_MD4:\n        #ifndef NO_MD4\n            block_size = MD4_BLOCK_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_MD5:\n        #ifndef NO_MD5\n            block_size = WC_MD5_BLOCK_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA:\n        #ifndef NO_SHA\n            block_size = WC_SHA_BLOCK_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA224:\n        #ifdef WOLFSSL_SHA224\n            block_size = WC_SHA224_BLOCK_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA256:\n        #ifndef NO_SHA256\n            block_size = WC_SHA256_BLOCK_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA384:\n        #ifdef WOLFSSL_SHA384\n            block_size = WC_SHA384_BLOCK_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA512:\n        #ifdef WOLFSSL_SHA512\n            block_size = WC_SHA512_BLOCK_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_MD5_SHA: /* Old TLS Specific */\n        #if !defined(NO_MD5) && !defined(NO_SHA)\n            block_size = (int)WC_MD5_BLOCK_SIZE + (int)WC_SHA_BLOCK_SIZE;\n        #endif\n            break;\n\n        case WC_HASH_TYPE_SHA3_224:\n        #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)\n            block_size = WC_SHA3_224_BLOCK_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA3_256:\n        #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)\n            block_size = WC_SHA3_256_BLOCK_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA3_384:\n        #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)\n            block_size = WC_SHA3_384_BLOCK_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_SHA3_512:\n        #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)\n            block_size = WC_SHA3_512_BLOCK_SIZE;\n        #endif\n            break;\n        case WC_HASH_TYPE_BLAKE2B:\n        case WC_HASH_TYPE_BLAKE2S:\n        #if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S)\n            block_size = BLAKE2S_BLOCKBYTES;\n        #endif\n            break;\n\n        /* Not Supported */\n        case WC_HASH_TYPE_NONE:\n        default:\n            block_size = BAD_FUNC_ARG;\n            break;\n    }\n    return block_size;\n}\n\n/* Generic Hashing Wrapper */\nint wc_Hash(enum wc_HashType hash_type, const byte* data,\n    word32 data_len, byte* hash, word32 hash_len)\n{\n    int ret = HASH_TYPE_E; /* Default to hash type error */\n    word32 dig_size;\n\n    /* Validate hash buffer size */\n    dig_size = wc_HashGetDigestSize(hash_type);\n    if (hash_len < dig_size) {\n        return BUFFER_E;\n    }\n\n    /* Suppress possible unused arg if all hashing is disabled */\n    (void)data;\n    (void)data_len;\n    (void)hash;\n    (void)hash_len;\n\n    switch(hash_type)\n    {\n        case WC_HASH_TYPE_MD5:\n#ifndef NO_MD5\n            ret = wc_Md5Hash(data, data_len, hash);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA:\n#ifndef NO_SHA\n            ret = wc_ShaHash(data, data_len, hash);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA224:\n#ifdef WOLFSSL_SHA224\n            ret = wc_Sha224Hash(data, data_len, hash);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA256:\n#ifndef NO_SHA256\n            ret = wc_Sha256Hash(data, data_len, hash);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA384:\n#ifdef WOLFSSL_SHA384\n            ret = wc_Sha384Hash(data, data_len, hash);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA512:\n#ifdef WOLFSSL_SHA512\n            ret = wc_Sha512Hash(data, data_len, hash);\n#endif\n            break;\n        case WC_HASH_TYPE_MD5_SHA:\n#if !defined(NO_MD5) && !defined(NO_SHA)\n            ret = wc_Md5Hash(data, data_len, hash);\n            if (ret == 0) {\n                ret = wc_ShaHash(data, data_len, &hash[WC_MD5_DIGEST_SIZE]);\n            }\n#endif\n            break;\n\n        case WC_HASH_TYPE_SHA3_224:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)\n            ret = wc_Sha3_224Hash(data, data_len, hash);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_256:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)\n            ret = wc_Sha3_256Hash(data, data_len, hash);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_384:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)\n            ret = wc_Sha3_384Hash(data, data_len, hash);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_512:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)\n            ret = wc_Sha3_512Hash(data, data_len, hash);\n#endif\n            break;\n\n        /* Not Supported */\n        case WC_HASH_TYPE_MD2:\n        case WC_HASH_TYPE_MD4:\n        case WC_HASH_TYPE_BLAKE2B:\n        case WC_HASH_TYPE_BLAKE2S:\n        case WC_HASH_TYPE_NONE:\n        default:\n            ret = BAD_FUNC_ARG;\n            break;\n    }\n    return ret;\n}\n\nint wc_HashInit_ex(wc_HashAlg* hash, enum wc_HashType type, void* heap,\n    int devId)\n{\n    int ret = HASH_TYPE_E; /* Default to hash type error */\n\n    if (hash == NULL)\n        return BAD_FUNC_ARG;\n\n    switch (type) {\n        case WC_HASH_TYPE_MD5:\n#ifndef NO_MD5\n            ret = wc_InitMd5_ex(&hash->md5, heap, devId);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA:\n#ifndef NO_SHA\n            ret = wc_InitSha_ex(&hash->sha, heap, devId);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA224:\n#ifdef WOLFSSL_SHA224\n            ret = wc_InitSha224_ex(&hash->sha224, heap, devId);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA256:\n#ifndef NO_SHA256\n            ret = wc_InitSha256_ex(&hash->sha256, heap, devId);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA384:\n#ifdef WOLFSSL_SHA384\n            ret = wc_InitSha384_ex(&hash->sha384, heap, devId);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA512:\n#ifdef WOLFSSL_SHA512\n            ret = wc_InitSha512_ex(&hash->sha512, heap, devId);\n#endif\n            break;\n\n        case WC_HASH_TYPE_SHA3_224:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)\n            ret = wc_InitSha3_224(&hash->sha3, heap, devId);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_256:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)\n            ret = wc_InitSha3_256(&hash->sha3, heap, devId);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_384:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)\n            ret = wc_InitSha3_384(&hash->sha3, heap, devId);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_512:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)\n            ret = wc_InitSha3_512(&hash->sha3, heap, devId);\n#endif\n            break;\n\n        /* not supported */\n        case WC_HASH_TYPE_MD5_SHA:\n        case WC_HASH_TYPE_MD2:\n        case WC_HASH_TYPE_MD4:\n        case WC_HASH_TYPE_BLAKE2B:\n        case WC_HASH_TYPE_BLAKE2S:\n        case WC_HASH_TYPE_NONE:\n        default:\n            ret = BAD_FUNC_ARG;\n    };\n\n    return ret;\n}\n\nint wc_HashInit(wc_HashAlg* hash, enum wc_HashType type)\n{\n    return wc_HashInit_ex(hash, type, NULL, INVALID_DEVID);\n}\n\nint wc_HashUpdate(wc_HashAlg* hash, enum wc_HashType type, const byte* data,\n                  word32 dataSz)\n{\n    int ret = HASH_TYPE_E; /* Default to hash type error */\n\n    if (hash == NULL || data == NULL)\n        return BAD_FUNC_ARG;\n\n    switch (type) {\n        case WC_HASH_TYPE_MD5:\n#ifndef NO_MD5\n            ret = wc_Md5Update(&hash->md5, data, dataSz);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA:\n#ifndef NO_SHA\n            ret = wc_ShaUpdate(&hash->sha, data, dataSz);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA224:\n#ifdef WOLFSSL_SHA224\n            ret = wc_Sha224Update(&hash->sha224, data, dataSz);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA256:\n#ifndef NO_SHA256\n            ret = wc_Sha256Update(&hash->sha256, data, dataSz);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA384:\n#ifdef WOLFSSL_SHA384\n            ret = wc_Sha384Update(&hash->sha384, data, dataSz);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA512:\n#ifdef WOLFSSL_SHA512\n            ret = wc_Sha512Update(&hash->sha512, data, dataSz);\n#endif\n            break;\n\n        case WC_HASH_TYPE_SHA3_224:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)\n            ret = wc_Sha3_224_Update(&hash->sha3, data, dataSz);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_256:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)\n            ret = wc_Sha3_256_Update(&hash->sha3, data, dataSz);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_384:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)\n            ret = wc_Sha3_384_Update(&hash->sha3, data, dataSz);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_512:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)\n            ret = wc_Sha3_512_Update(&hash->sha3, data, dataSz);\n#endif\n            break;\n\n        /* not supported */\n        case WC_HASH_TYPE_MD5_SHA:\n        case WC_HASH_TYPE_MD2:\n        case WC_HASH_TYPE_MD4:\n        case WC_HASH_TYPE_BLAKE2B:\n        case WC_HASH_TYPE_BLAKE2S:\n        case WC_HASH_TYPE_NONE:\n        default:\n            ret = BAD_FUNC_ARG;\n    };\n\n    return ret;\n}\n\nint wc_HashFinal(wc_HashAlg* hash, enum wc_HashType type, byte* out)\n{\n    int ret = HASH_TYPE_E; /* Default to hash type error */\n\n    if (hash == NULL || out == NULL)\n        return BAD_FUNC_ARG;\n\n    switch (type) {\n        case WC_HASH_TYPE_MD5:\n#ifndef NO_MD5\n            ret = wc_Md5Final(&hash->md5, out);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA:\n#ifndef NO_SHA\n            ret = wc_ShaFinal(&hash->sha, out);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA224:\n#ifdef WOLFSSL_SHA224\n            ret = wc_Sha224Final(&hash->sha224, out);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA256:\n#ifndef NO_SHA256\n            ret = wc_Sha256Final(&hash->sha256, out);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA384:\n#ifdef WOLFSSL_SHA384\n            ret = wc_Sha384Final(&hash->sha384, out);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA512:\n#ifdef WOLFSSL_SHA512\n            ret = wc_Sha512Final(&hash->sha512, out);\n#endif\n            break;\n\n        case WC_HASH_TYPE_SHA3_224:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)\n            ret = wc_Sha3_224_Final(&hash->sha3, out);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_256:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)\n            ret = wc_Sha3_256_Final(&hash->sha3, out);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_384:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)\n            ret = wc_Sha3_384_Final(&hash->sha3, out);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_512:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)\n            ret = wc_Sha3_512_Final(&hash->sha3, out);\n#endif\n            break;\n\n        /* not supported */\n        case WC_HASH_TYPE_MD5_SHA:\n        case WC_HASH_TYPE_MD2:\n        case WC_HASH_TYPE_MD4:\n        case WC_HASH_TYPE_BLAKE2B:\n        case WC_HASH_TYPE_BLAKE2S:\n        case WC_HASH_TYPE_NONE:\n        default:\n            ret = BAD_FUNC_ARG;\n    };\n\n    return ret;\n}\n\nint wc_HashFree(wc_HashAlg* hash, enum wc_HashType type)\n{\n    int ret = HASH_TYPE_E; /* Default to hash type error */\n\n    if (hash == NULL)\n        return BAD_FUNC_ARG;\n\n    switch (type) {\n        case WC_HASH_TYPE_MD5:\n#ifndef NO_MD5\n            wc_Md5Free(&hash->md5);\n            ret = 0;\n#endif\n            break;\n        case WC_HASH_TYPE_SHA:\n#ifndef NO_SHA\n            wc_ShaFree(&hash->sha);\n            ret = 0;\n#endif\n            break;\n        case WC_HASH_TYPE_SHA224:\n#ifdef WOLFSSL_SHA224\n            wc_Sha224Free(&hash->sha224);\n            ret = 0;\n#endif\n            break;\n        case WC_HASH_TYPE_SHA256:\n#ifndef NO_SHA256\n            wc_Sha256Free(&hash->sha256);\n            ret = 0;\n#endif\n            break;\n        case WC_HASH_TYPE_SHA384:\n#ifdef WOLFSSL_SHA384\n            wc_Sha384Free(&hash->sha384);\n            ret = 0;\n#endif\n            break;\n        case WC_HASH_TYPE_SHA512:\n#ifdef WOLFSSL_SHA512\n            wc_Sha512Free(&hash->sha512);\n            ret = 0;\n#endif\n            break;\n\n        case WC_HASH_TYPE_SHA3_224:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)\n            wc_Sha3_224_Free(&hash->sha3);\n            ret = 0;\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_256:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)\n            wc_Sha3_256_Free(&hash->sha3);\n            ret = 0;\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_384:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)\n            wc_Sha3_384_Free(&hash->sha3);\n            ret = 0;\n#endif\n            break;\n        case WC_HASH_TYPE_SHA3_512:\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)\n            wc_Sha3_512_Free(&hash->sha3);\n            ret = 0;\n#endif\n            break;\n\n        /* not supported */\n        case WC_HASH_TYPE_MD5_SHA:\n        case WC_HASH_TYPE_MD2:\n        case WC_HASH_TYPE_MD4:\n        case WC_HASH_TYPE_BLAKE2B:\n        case WC_HASH_TYPE_BLAKE2S:\n        case WC_HASH_TYPE_NONE:\n        default:\n            ret = BAD_FUNC_ARG;\n    };\n\n    return ret;\n}\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\nint wc_HashSetFlags(wc_HashAlg* hash, enum wc_HashType type, word32 flags)\n{\n    int ret = HASH_TYPE_E; /* Default to hash type error */\n\n    if (hash == NULL)\n        return BAD_FUNC_ARG;\n\n    switch (type) {\n        case WC_HASH_TYPE_MD5:\n#ifndef NO_MD5\n            ret = wc_Md5SetFlags(&hash->md5, flags);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA:\n#ifndef NO_SHA\n            ret = wc_ShaSetFlags(&hash->sha, flags);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA224:\n#ifdef WOLFSSL_SHA224\n            ret = wc_Sha224SetFlags(&hash->sha224, flags);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA256:\n#ifndef NO_SHA256\n            ret = wc_Sha256SetFlags(&hash->sha256, flags);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA384:\n#ifdef WOLFSSL_SHA384\n            ret = wc_Sha384SetFlags(&hash->sha384, flags);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA512:\n#ifdef WOLFSSL_SHA512\n            ret = wc_Sha512SetFlags(&hash->sha512, flags);\n#endif\n            break;\n\n        case WC_HASH_TYPE_SHA3_224:\n        case WC_HASH_TYPE_SHA3_256:\n        case WC_HASH_TYPE_SHA3_384:\n        case WC_HASH_TYPE_SHA3_512:\n#ifdef WOLFSSL_SHA3\n            ret = wc_Sha3_SetFlags(&hash->sha3, flags);\n#endif\n            break;\n\n        /* not supported */\n        case WC_HASH_TYPE_MD5_SHA:\n        case WC_HASH_TYPE_MD2:\n        case WC_HASH_TYPE_MD4:\n        case WC_HASH_TYPE_BLAKE2B:\n        case WC_HASH_TYPE_BLAKE2S:\n        case WC_HASH_TYPE_NONE:\n        default:\n            ret = BAD_FUNC_ARG;\n    };\n\n    return ret;\n}\nint wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags)\n{\n    int ret = HASH_TYPE_E; /* Default to hash type error */\n\n    if (hash == NULL)\n        return BAD_FUNC_ARG;\n\n    switch (type) {\n        case WC_HASH_TYPE_MD5:\n#ifndef NO_MD5\n            ret = wc_Md5GetFlags(&hash->md5, flags);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA:\n#ifndef NO_SHA\n            ret = wc_ShaGetFlags(&hash->sha, flags);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA224:\n#ifdef WOLFSSL_SHA224\n            ret = wc_Sha224GetFlags(&hash->sha224, flags);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA256:\n#ifndef NO_SHA256\n            ret = wc_Sha256GetFlags(&hash->sha256, flags);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA384:\n#ifdef WOLFSSL_SHA384\n            ret = wc_Sha384GetFlags(&hash->sha384, flags);\n#endif\n            break;\n        case WC_HASH_TYPE_SHA512:\n#ifdef WOLFSSL_SHA512\n            ret = wc_Sha512GetFlags(&hash->sha512, flags);\n#endif\n            break;\n\n        case WC_HASH_TYPE_SHA3_224:\n        case WC_HASH_TYPE_SHA3_256:\n        case WC_HASH_TYPE_SHA3_384:\n        case WC_HASH_TYPE_SHA3_512:\n#ifdef WOLFSSL_SHA3\n            ret = wc_Sha3_GetFlags(&hash->sha3, flags);\n#endif\n            break;\n\n        /* not supported */\n        case WC_HASH_TYPE_MD5_SHA:\n        case WC_HASH_TYPE_MD2:\n        case WC_HASH_TYPE_MD4:\n        case WC_HASH_TYPE_BLAKE2B:\n        case WC_HASH_TYPE_BLAKE2S:\n        case WC_HASH_TYPE_NONE:\n        default:\n            ret = BAD_FUNC_ARG;\n    };\n\n    return ret;\n}\n#endif\n\n\n#if !defined(WOLFSSL_TI_HASH)\n\n#if !defined(NO_MD5)\n    int wc_Md5Hash(const byte* data, word32 len, byte* hash)\n    {\n        int ret;\n    #ifdef WOLFSSL_SMALL_STACK\n        wc_Md5* md5;\n    #else\n        wc_Md5  md5[1];\n    #endif\n\n    #ifdef WOLFSSL_SMALL_STACK\n        md5 = (wc_Md5*)XMALLOC(sizeof(wc_Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        if (md5 == NULL)\n            return MEMORY_E;\n    #endif\n\n        if ((ret = wc_InitMd5(md5)) != 0) {\n            WOLFSSL_MSG(\"InitMd5 failed\");\n        }\n        else {\n            if ((ret = wc_Md5Update(md5, data, len)) != 0) {\n                WOLFSSL_MSG(\"Md5Update failed\");\n            }\n            else if ((ret = wc_Md5Final(md5, hash)) != 0) {\n                WOLFSSL_MSG(\"Md5Final failed\");\n            }\n            wc_Md5Free(md5);\n        }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n\n        return ret;\n    }\n#endif /* !NO_MD5 */\n\n#if !defined(NO_SHA)\n    int wc_ShaHash(const byte* data, word32 len, byte* hash)\n    {\n        int ret = 0;\n    #ifdef WOLFSSL_SMALL_STACK\n        wc_Sha* sha;\n    #else\n        wc_Sha sha[1];\n    #endif\n\n    #ifdef WOLFSSL_SMALL_STACK\n        sha = (wc_Sha*)XMALLOC(sizeof(wc_Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        if (sha == NULL)\n            return MEMORY_E;\n    #endif\n\n        if ((ret = wc_InitSha(sha)) != 0) {\n            WOLFSSL_MSG(\"InitSha failed\");\n        }\n        else {\n            if ((ret = wc_ShaUpdate(sha, data, len)) != 0) {\n                WOLFSSL_MSG(\"ShaUpdate failed\");\n            }\n            else if ((ret = wc_ShaFinal(sha, hash)) != 0) {\n                WOLFSSL_MSG(\"ShaFinal failed\");\n            }\n            wc_ShaFree(sha);\n        }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n\n        return ret;\n    }\n#endif /* !NO_SHA */\n\n#if defined(WOLFSSL_SHA224)\n    int wc_Sha224Hash(const byte* data, word32 len, byte* hash)\n    {\n        int ret = 0;\n    #ifdef WOLFSSL_SMALL_STACK\n        wc_Sha224* sha224;\n    #else\n        wc_Sha224 sha224[1];\n    #endif\n\n    #ifdef WOLFSSL_SMALL_STACK\n        sha224 = (wc_Sha224*)XMALLOC(sizeof(wc_Sha224), NULL,\n            DYNAMIC_TYPE_TMP_BUFFER);\n        if (sha224 == NULL)\n            return MEMORY_E;\n    #endif\n\n        if ((ret = wc_InitSha224(sha224)) != 0) {\n            WOLFSSL_MSG(\"InitSha224 failed\");\n        }\n        else {\n            if ((ret = wc_Sha224Update(sha224, data, len)) != 0) {\n                WOLFSSL_MSG(\"Sha224Update failed\");\n            }\n            else if ((ret = wc_Sha224Final(sha224, hash)) != 0) {\n                WOLFSSL_MSG(\"Sha224Final failed\");\n            }\n            wc_Sha224Free(sha224);\n        }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(sha224, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n\n    return ret;\n}\n#endif /* WOLFSSL_SHA224 */\n\n#if !defined(NO_SHA256)\n    int wc_Sha256Hash(const byte* data, word32 len, byte* hash)\n    {\n        int ret = 0;\n    #ifdef WOLFSSL_SMALL_STACK\n        wc_Sha256* sha256;\n    #else\n        wc_Sha256 sha256[1];\n    #endif\n\n    #ifdef WOLFSSL_SMALL_STACK\n        sha256 = (wc_Sha256*)XMALLOC(sizeof(wc_Sha256), NULL,\n            DYNAMIC_TYPE_TMP_BUFFER);\n        if (sha256 == NULL)\n            return MEMORY_E;\n    #endif\n\n        if ((ret = wc_InitSha256(sha256)) != 0) {\n            WOLFSSL_MSG(\"InitSha256 failed\");\n        }\n        else {\n            if ((ret = wc_Sha256Update(sha256, data, len)) != 0) {\n                WOLFSSL_MSG(\"Sha256Update failed\");\n            }\n            else if ((ret = wc_Sha256Final(sha256, hash)) != 0) {\n                WOLFSSL_MSG(\"Sha256Final failed\");\n            }\n            wc_Sha256Free(sha256);\n        }\n\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n\n        return ret;\n    }\n#endif /* !NO_SHA256 */\n\n#endif /* !defined(WOLFSSL_TI_HASH) */\n\n\n#if defined(WOLFSSL_SHA512)\n    int wc_Sha512Hash(const byte* data, word32 len, byte* hash)\n    {\n        int ret = 0;\n    #ifdef WOLFSSL_SMALL_STACK\n        wc_Sha512* sha512;\n    #else\n        wc_Sha512 sha512[1];\n    #endif\n\n    #ifdef WOLFSSL_SMALL_STACK\n        sha512 = (wc_Sha512*)XMALLOC(sizeof(wc_Sha512), NULL,\n            DYNAMIC_TYPE_TMP_BUFFER);\n        if (sha512 == NULL)\n            return MEMORY_E;\n    #endif\n\n        if ((ret = wc_InitSha512(sha512)) != 0) {\n            WOLFSSL_MSG(\"InitSha512 failed\");\n        }\n        else {\n            if ((ret = wc_Sha512Update(sha512, data, len)) != 0) {\n                WOLFSSL_MSG(\"Sha512Update failed\");\n            }\n            else if ((ret = wc_Sha512Final(sha512, hash)) != 0) {\n                WOLFSSL_MSG(\"Sha512Final failed\");\n            }\n            wc_Sha512Free(sha512);\n        }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(sha512, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n\n        return ret;\n    }\n#endif /* WOLFSSL_SHA512 */\n\n#if defined(WOLFSSL_SHA384)\n    int wc_Sha384Hash(const byte* data, word32 len, byte* hash)\n    {\n        int ret = 0;\n    #ifdef WOLFSSL_SMALL_STACK\n        wc_Sha384* sha384;\n    #else\n        wc_Sha384 sha384[1];\n    #endif\n\n    #ifdef WOLFSSL_SMALL_STACK\n        sha384 = (wc_Sha384*)XMALLOC(sizeof(wc_Sha384), NULL,\n            DYNAMIC_TYPE_TMP_BUFFER);\n        if (sha384 == NULL)\n            return MEMORY_E;\n    #endif\n\n        if ((ret = wc_InitSha384(sha384)) != 0) {\n            WOLFSSL_MSG(\"InitSha384 failed\");\n        }\n        else {\n            if ((ret = wc_Sha384Update(sha384, data, len)) != 0) {\n                WOLFSSL_MSG(\"Sha384Update failed\");\n            }\n            else if ((ret = wc_Sha384Final(sha384, hash)) != 0) {\n                WOLFSSL_MSG(\"Sha384Final failed\");\n            }\n            wc_Sha384Free(sha384);\n        }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n\n        return ret;\n    }\n#endif /* WOLFSSL_SHA384 */\n\n#if defined(WOLFSSL_SHA3)\n#if !defined(WOLFSSL_NOSHA3_224)\n    int wc_Sha3_224Hash(const byte* data, word32 len, byte* hash)\n    {\n        int ret = 0;\n    #ifdef WOLFSSL_SMALL_STACK\n        wc_Sha3* sha3;\n    #else\n        wc_Sha3 sha3[1];\n    #endif\n\n    #ifdef WOLFSSL_SMALL_STACK\n        sha3 = (wc_Sha3*)XMALLOC(sizeof(wc_Sha3), NULL,\n            DYNAMIC_TYPE_TMP_BUFFER);\n        if (sha3 == NULL)\n            return MEMORY_E;\n    #endif\n\n        if ((ret = wc_InitSha3_224(sha3, NULL, INVALID_DEVID)) != 0) {\n            WOLFSSL_MSG(\"InitSha3_224 failed\");\n        }\n        else {\n            if ((ret = wc_Sha3_224_Update(sha3, data, len)) != 0) {\n                WOLFSSL_MSG(\"Sha3_224_Update failed\");\n            }\n            else if ((ret = wc_Sha3_224_Final(sha3, hash)) != 0) {\n                WOLFSSL_MSG(\"Sha3_224_Final failed\");\n            }\n            wc_Sha3_224_Free(sha3);\n        }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(sha3, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n\n        return ret;\n    }\n#endif /* !WOLFSSL_NOSHA3_224 */\n\n#if !defined(WOLFSSL_NOSHA3_256)\n    int wc_Sha3_256Hash(const byte* data, word32 len, byte* hash)\n    {\n        int ret = 0;\n    #ifdef WOLFSSL_SMALL_STACK\n        wc_Sha3* sha3;\n    #else\n        wc_Sha3 sha3[1];\n    #endif\n\n    #ifdef WOLFSSL_SMALL_STACK\n        sha3 = (wc_Sha3*)XMALLOC(sizeof(wc_Sha3), NULL,\n            DYNAMIC_TYPE_TMP_BUFFER);\n        if (sha3 == NULL)\n            return MEMORY_E;\n    #endif\n\n        if ((ret = wc_InitSha3_256(sha3, NULL, INVALID_DEVID)) != 0) {\n            WOLFSSL_MSG(\"InitSha3_256 failed\");\n        }\n        else {\n            if ((ret = wc_Sha3_256_Update(sha3, data, len)) != 0) {\n                WOLFSSL_MSG(\"Sha3_256_Update failed\");\n            }\n            else if ((ret = wc_Sha3_256_Final(sha3, hash)) != 0) {\n                WOLFSSL_MSG(\"Sha3_256_Final failed\");\n            }\n            wc_Sha3_256_Free(sha3);\n        }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(sha3, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n\n        return ret;\n    }\n#endif /* !WOLFSSL_NOSHA3_256 */\n\n#if !defined(WOLFSSL_NOSHA3_384)\n    int wc_Sha3_384Hash(const byte* data, word32 len, byte* hash)\n    {\n        int ret = 0;\n    #ifdef WOLFSSL_SMALL_STACK\n        wc_Sha3* sha3;\n    #else\n        wc_Sha3 sha3[1];\n    #endif\n\n    #ifdef WOLFSSL_SMALL_STACK\n        sha3 = (wc_Sha3*)XMALLOC(sizeof(wc_Sha3), NULL,\n            DYNAMIC_TYPE_TMP_BUFFER);\n        if (sha3 == NULL)\n            return MEMORY_E;\n    #endif\n\n        if ((ret = wc_InitSha3_384(sha3, NULL, INVALID_DEVID)) != 0) {\n            WOLFSSL_MSG(\"InitSha3_384 failed\");\n        }\n        else {\n            if ((ret = wc_Sha3_384_Update(sha3, data, len)) != 0) {\n                WOLFSSL_MSG(\"Sha3_384_Update failed\");\n            }\n            else if ((ret = wc_Sha3_384_Final(sha3, hash)) != 0) {\n                WOLFSSL_MSG(\"Sha3_384_Final failed\");\n            }\n            wc_Sha3_384_Free(sha3);\n        }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(sha3, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n\n        return ret;\n    }\n#endif /* !WOLFSSL_NOSHA3_384 */\n\n#if !defined(WOLFSSL_NOSHA3_512)\n    int wc_Sha3_512Hash(const byte* data, word32 len, byte* hash)\n    {\n        int ret = 0;\n    #ifdef WOLFSSL_SMALL_STACK\n        wc_Sha3* sha3;\n    #else\n        wc_Sha3 sha3[1];\n    #endif\n\n    #ifdef WOLFSSL_SMALL_STACK\n        sha3 = (wc_Sha3*)XMALLOC(sizeof(wc_Sha3), NULL,\n            DYNAMIC_TYPE_TMP_BUFFER);\n        if (sha3 == NULL)\n            return MEMORY_E;\n    #endif\n\n        if ((ret = wc_InitSha3_512(sha3, NULL, INVALID_DEVID)) != 0) {\n            WOLFSSL_MSG(\"InitSha3_512 failed\");\n        }\n        else {\n            if ((ret = wc_Sha3_512_Update(sha3, data, len)) != 0) {\n                WOLFSSL_MSG(\"Sha3_512_Update failed\");\n            }\n            else if ((ret = wc_Sha3_512_Final(sha3, hash)) != 0) {\n                WOLFSSL_MSG(\"Sha3_512_Final failed\");\n            }\n            wc_Sha3_512_Free(sha3);\n        }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(sha3, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n\n        return ret;\n    }\n#endif /* !WOLFSSL_NOSHA3_512 */\n#endif /* WOLFSSL_SHA3 */\n\n#ifdef WOLFSSL_HAVE_PRF\n\n#ifdef WOLFSSL_SHA384\n    #define P_HASH_MAX_SIZE WC_SHA384_DIGEST_SIZE\n#else\n    #define P_HASH_MAX_SIZE WC_SHA256_DIGEST_SIZE\n#endif\n\n/* Pseudo Random Function for MD5, SHA-1, SHA-256, or SHA-384 */\nint wc_PRF(byte* result, word32 resLen, const byte* secret,\n                  word32 secLen, const byte* seed, word32 seedLen, int hash,\n                  void* heap, int devId)\n{\n    word32 len = P_HASH_MAX_SIZE;\n    word32 times;\n    word32 lastLen;\n    word32 lastTime;\n    word32 i;\n    word32 idx = 0;\n    int    ret = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    byte*  previous;\n    byte*  current;\n    Hmac*  hmac;\n#else\n    byte   previous[P_HASH_MAX_SIZE];  /* max size */\n    byte   current[P_HASH_MAX_SIZE];   /* max size */\n    Hmac   hmac[1];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    previous = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);\n    current  = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);\n    hmac     = (Hmac*)XMALLOC(sizeof(Hmac),    heap, DYNAMIC_TYPE_HMAC);\n\n    if (previous == NULL || current == NULL || hmac == NULL) {\n        if (previous) XFREE(previous, heap, DYNAMIC_TYPE_DIGEST);\n        if (current)  XFREE(current,  heap, DYNAMIC_TYPE_DIGEST);\n        if (hmac)     XFREE(hmac,     heap, DYNAMIC_TYPE_HMAC);\n\n        return MEMORY_E;\n    }\n#endif\n\n    switch (hash) {\n    #ifndef NO_MD5\n        case md5_mac:\n            hash = WC_MD5;\n            len  = WC_MD5_DIGEST_SIZE;\n        break;\n    #endif\n\n    #ifndef NO_SHA256\n        case sha256_mac:\n            hash = WC_SHA256;\n            len  = WC_SHA256_DIGEST_SIZE;\n        break;\n    #endif\n\n    #ifdef WOLFSSL_SHA384\n        case sha384_mac:\n            hash = WC_SHA384;\n            len  = WC_SHA384_DIGEST_SIZE;\n        break;\n    #endif\n\n    #ifndef NO_SHA\n        case sha_mac:\n        default:\n            hash = WC_SHA;\n            len  = WC_SHA_DIGEST_SIZE;\n        break;\n    #endif\n    }\n\n    times   = resLen / len;\n    lastLen = resLen % len;\n\n    if (lastLen)\n        times += 1;\n\n    lastTime = times - 1;\n\n    ret = wc_HmacInit(hmac, heap, devId);\n    if (ret == 0) {\n        ret = wc_HmacSetKey(hmac, hash, secret, secLen);\n        if (ret == 0)\n            ret = wc_HmacUpdate(hmac, seed, seedLen); /* A0 = seed */\n        if (ret == 0)\n            ret = wc_HmacFinal(hmac, previous);       /* A1 */\n        if (ret == 0) {\n            for (i = 0; i < times; i++) {\n                ret = wc_HmacUpdate(hmac, previous, len);\n                if (ret != 0)\n                    break;\n                ret = wc_HmacUpdate(hmac, seed, seedLen);\n                if (ret != 0)\n                    break;\n                ret = wc_HmacFinal(hmac, current);\n                if (ret != 0)\n                    break;\n\n                if ((i == lastTime) && lastLen)\n                    XMEMCPY(&result[idx], current,\n                                             min(lastLen, P_HASH_MAX_SIZE));\n                else {\n                    XMEMCPY(&result[idx], current, len);\n                    idx += len;\n                    ret = wc_HmacUpdate(hmac, previous, len);\n                    if (ret != 0)\n                        break;\n                    ret = wc_HmacFinal(hmac, previous);\n                    if (ret != 0)\n                        break;\n                }\n            }\n        }\n        wc_HmacFree(hmac);\n    }\n\n    ForceZero(previous,  P_HASH_MAX_SIZE);\n    ForceZero(current,   P_HASH_MAX_SIZE);\n    ForceZero(hmac,      sizeof(Hmac));\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(previous, heap, DYNAMIC_TYPE_DIGEST);\n    XFREE(current,  heap, DYNAMIC_TYPE_DIGEST);\n    XFREE(hmac,     heap, DYNAMIC_TYPE_HMAC);\n#endif\n\n    return ret;\n}\n#undef P_HASH_MAX_SIZE\n\n/* compute PRF (pseudo random function) using SHA1 and MD5 for TLSv1 */\nint wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret,\n           word32 secLen, const byte* label, word32 labLen,\n           const byte* seed, word32 seedLen, void* heap, int devId)\n{\n    int    ret  = 0;\n    word32 half = (secLen + 1) / 2;\n\n#ifdef WOLFSSL_SMALL_STACK\n    byte* md5_half;\n    byte* sha_half;\n    byte* md5_result;\n    byte* sha_result;\n#else\n    byte  md5_half[MAX_PRF_HALF];     /* half is real size */\n    byte  sha_half[MAX_PRF_HALF];     /* half is real size */\n    byte  md5_result[MAX_PRF_DIG];    /* digLen is real size */\n    byte  sha_result[MAX_PRF_DIG];    /* digLen is real size */\n#endif\n#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)\n    DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, heap);\n    if (labelSeed == NULL)\n        return MEMORY_E;\n#else\n    byte labelSeed[MAX_PRF_LABSEED];\n#endif\n\n    if (half > MAX_PRF_HALF ||\n        labLen + seedLen > MAX_PRF_LABSEED ||\n        digLen > MAX_PRF_DIG)\n    {\n    #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)\n        FREE_VAR(labelSeed, heap);\n    #endif\n        return BUFFER_E;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    md5_half   = (byte*)XMALLOC(MAX_PRF_HALF,    heap, DYNAMIC_TYPE_DIGEST);\n    sha_half   = (byte*)XMALLOC(MAX_PRF_HALF,    heap, DYNAMIC_TYPE_DIGEST);\n    md5_result = (byte*)XMALLOC(MAX_PRF_DIG,     heap, DYNAMIC_TYPE_DIGEST);\n    sha_result = (byte*)XMALLOC(MAX_PRF_DIG,     heap, DYNAMIC_TYPE_DIGEST);\n\n    if (md5_half == NULL || sha_half == NULL || md5_result == NULL ||\n                                                           sha_result == NULL) {\n        if (md5_half)   XFREE(md5_half,   heap, DYNAMIC_TYPE_DIGEST);\n        if (sha_half)   XFREE(sha_half,   heap, DYNAMIC_TYPE_DIGEST);\n        if (md5_result) XFREE(md5_result, heap, DYNAMIC_TYPE_DIGEST);\n        if (sha_result) XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);\n    #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)\n        FREE_VAR(labelSeed, heap);\n    #endif\n\n        return MEMORY_E;\n    }\n#endif\n\n    XMEMSET(md5_result, 0, digLen);\n    XMEMSET(sha_result, 0, digLen);\n\n    XMEMCPY(md5_half, secret, half);\n    XMEMCPY(sha_half, secret + half - secLen % 2, half);\n\n    XMEMCPY(labelSeed, label, labLen);\n    XMEMCPY(labelSeed + labLen, seed, seedLen);\n\n    if ((ret = wc_PRF(md5_result, digLen, md5_half, half, labelSeed,\n                                labLen + seedLen, md5_mac, heap, devId)) == 0) {\n        if ((ret = wc_PRF(sha_result, digLen, sha_half, half, labelSeed,\n                                labLen + seedLen, sha_mac, heap, devId)) == 0) {\n            /* calculate XOR for TLSv1 PRF */\n            XMEMCPY(digest, md5_result, digLen);\n            xorbuf(digest, sha_result, digLen);\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(md5_half,   heap, DYNAMIC_TYPE_DIGEST);\n    XFREE(sha_half,   heap, DYNAMIC_TYPE_DIGEST);\n    XFREE(md5_result, heap, DYNAMIC_TYPE_DIGEST);\n    XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)\n    FREE_VAR(labelSeed, heap);\n#endif\n\n    return ret;\n}\n\n/* Wrapper for TLS 1.2 and TLSv1 cases to calculate PRF */\n/* In TLS 1.2 case call straight thru to wc_PRF */\nint wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen,\n            const byte* label, word32 labLen, const byte* seed, word32 seedLen,\n            int useAtLeastSha256, int hash_type, void* heap, int devId)\n{\n    int ret = 0;\n\n    if (useAtLeastSha256) {\n    #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)\n        DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, heap);\n        if (labelSeed == NULL)\n            return MEMORY_E;\n    #else\n        byte labelSeed[MAX_PRF_LABSEED];\n    #endif\n\n        if (labLen + seedLen > MAX_PRF_LABSEED)\n            return BUFFER_E;\n\n        XMEMCPY(labelSeed, label, labLen);\n        XMEMCPY(labelSeed + labLen, seed, seedLen);\n\n        /* If a cipher suite wants an algorithm better than sha256, it\n         * should use better. */\n        if (hash_type < sha256_mac || hash_type == blake2b_mac)\n            hash_type = sha256_mac;\n        /* compute PRF for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1.2 PRF */\n        ret = wc_PRF(digest, digLen, secret, secLen, labelSeed,\n                     labLen + seedLen, hash_type, heap, devId);\n\n    #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)\n        FREE_VAR(labelSeed, heap);\n    #endif\n    }\n#ifndef NO_OLD_TLS\n    else {\n        /* compute TLSv1 PRF (pseudo random function using HMAC) */\n        ret = wc_PRF_TLSv1(digest, digLen, secret, secLen, label, labLen, seed,\n                          seedLen, heap, devId);\n    }\n#endif\n\n    return ret;\n}\n#endif /* WOLFSSL_HAVE_PRF */\n"
  },
  {
    "path": "src/wolfcrypt/src/hc128.c",
    "content": "/* hc128.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_HC128\n\n#include <wolfssl/wolfcrypt/hc128.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/hc128.h>\n\t\t#include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\n#ifdef BIG_ENDIAN_ORDER\n    #define LITTLE32(x) ByteReverseWord32(x)\n#else\n    #define LITTLE32(x) (x)\n#endif\n\n\n/*h1 function*/\n#define h1(ctx, x, y) {                         \\\n     byte a,c;                                  \\\n     a = (byte) (x);                            \\\n     c = (byte) ((x) >> 16);                    \\\n     y = (ctx->T[512+a])+(ctx->T[512+256+c]);   \\\n}\n\n/*h2 function*/\n#define h2(ctx, x, y) {                         \\\n     byte a,c;                                  \\\n     a = (byte) (x);                            \\\n     c = (byte) ((x) >> 16);                    \\\n     y = (ctx->T[a])+(ctx->T[256+c]);           \\\n}\n\n/*one step of HC-128, update P and generate 32 bits keystream*/\n#define step_P(ctx,u,v,a,b,c,d,n){              \\\n     word32 tem0,tem1,tem2,tem3;                \\\n     h1((ctx),(ctx->X[(d)]),tem3);              \\\n     tem0 = rotrFixed((ctx->T[(v)]),23);        \\\n     tem1 = rotrFixed((ctx->X[(c)]),10);        \\\n     tem2 = rotrFixed((ctx->X[(b)]),8);         \\\n     (ctx->T[(u)]) += tem2+(tem0 ^ tem1);       \\\n     (ctx->X[(a)]) = (ctx->T[(u)]);             \\\n     (n) = tem3 ^ (ctx->T[(u)]) ;               \\\n}\n\n/*one step of HC-128, update Q and generate 32 bits keystream*/\n#define step_Q(ctx,u,v,a,b,c,d,n){              \\\n     word32 tem0,tem1,tem2,tem3;                \\\n     h2((ctx),(ctx->Y[(d)]),tem3);              \\\n     tem0 = rotrFixed((ctx->T[(v)]),(32-23));   \\\n     tem1 = rotrFixed((ctx->Y[(c)]),(32-10));   \\\n     tem2 = rotrFixed((ctx->Y[(b)]),(32-8));    \\\n     (ctx->T[(u)]) += tem2 + (tem0 ^ tem1);     \\\n     (ctx->Y[(a)]) = (ctx->T[(u)]);             \\\n     (n) = tem3 ^ (ctx->T[(u)]) ;               \\\n}\n\n/*16 steps of HC-128, generate 512 bits keystream*/\nstatic void generate_keystream(HC128* ctx, word32* keystream)\n{\n   word32 cc,dd;\n   cc = ctx->counter1024 & 0x1ff;\n   dd = (cc+16)&0x1ff;\n\n   if (ctx->counter1024 < 512)\n   {\n      ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;\n      step_P(ctx, cc+0, cc+1, 0, 6, 13,4, keystream[0]);\n      step_P(ctx, cc+1, cc+2, 1, 7, 14,5, keystream[1]);\n      step_P(ctx, cc+2, cc+3, 2, 8, 15,6, keystream[2]);\n      step_P(ctx, cc+3, cc+4, 3, 9, 0, 7, keystream[3]);\n      step_P(ctx, cc+4, cc+5, 4, 10,1, 8, keystream[4]);\n      step_P(ctx, cc+5, cc+6, 5, 11,2, 9, keystream[5]);\n      step_P(ctx, cc+6, cc+7, 6, 12,3, 10,keystream[6]);\n      step_P(ctx, cc+7, cc+8, 7, 13,4, 11,keystream[7]);\n      step_P(ctx, cc+8, cc+9, 8, 14,5, 12,keystream[8]);\n      step_P(ctx, cc+9, cc+10,9, 15,6, 13,keystream[9]);\n      step_P(ctx, cc+10,cc+11,10,0, 7, 14,keystream[10]);\n      step_P(ctx, cc+11,cc+12,11,1, 8, 15,keystream[11]);\n      step_P(ctx, cc+12,cc+13,12,2, 9, 0, keystream[12]);\n      step_P(ctx, cc+13,cc+14,13,3, 10,1, keystream[13]);\n      step_P(ctx, cc+14,cc+15,14,4, 11,2, keystream[14]);\n      step_P(ctx, cc+15,dd+0, 15,5, 12,3, keystream[15]);\n   }\n   else\n   {\n\t  ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;\n      step_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13,4, keystream[0]);\n      step_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14,5, keystream[1]);\n      step_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15,6, keystream[2]);\n      step_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0, 7, keystream[3]);\n      step_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1, 8, keystream[4]);\n      step_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2, 9, keystream[5]);\n      step_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3, 10,keystream[6]);\n      step_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4, 11,keystream[7]);\n      step_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5, 12,keystream[8]);\n      step_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6, 13,keystream[9]);\n      step_Q(ctx, 512+cc+10,512+cc+11,10,0, 7, 14,keystream[10]);\n      step_Q(ctx, 512+cc+11,512+cc+12,11,1, 8, 15,keystream[11]);\n      step_Q(ctx, 512+cc+12,512+cc+13,12,2, 9, 0, keystream[12]);\n      step_Q(ctx, 512+cc+13,512+cc+14,13,3, 10,1, keystream[13]);\n      step_Q(ctx, 512+cc+14,512+cc+15,14,4, 11,2, keystream[14]);\n      step_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12,3, keystream[15]);\n   }\n}\n\n\n/* The following defines the initialization functions */\n#define f1(x)  (rotrFixed((x),7)  ^ rotrFixed((x),18) ^ ((x) >> 3))\n#define f2(x)  (rotrFixed((x),17) ^ rotrFixed((x),19) ^ ((x) >> 10))\n\n/*update table P*/\n#define update_P(ctx,u,v,a,b,c,d){                  \\\n     word32 tem0,tem1,tem2,tem3;                    \\\n     tem0 = rotrFixed((ctx->T[(v)]),23);            \\\n     tem1 = rotrFixed((ctx->X[(c)]),10);            \\\n     tem2 = rotrFixed((ctx->X[(b)]),8);             \\\n     h1((ctx),(ctx->X[(d)]),tem3);                  \\\n     (ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3;     \\\n     (ctx->X[(a)]) = (ctx->T[(u)]);                 \\\n}\n\n/*update table Q*/\n#define update_Q(ctx,u,v,a,b,c,d){                  \\\n     word32 tem0,tem1,tem2,tem3;                    \\\n     tem0 = rotrFixed((ctx->T[(v)]),(32-23));       \\\n     tem1 = rotrFixed((ctx->Y[(c)]),(32-10));       \\\n     tem2 = rotrFixed((ctx->Y[(b)]),(32-8));        \\\n     h2((ctx),(ctx->Y[(d)]),tem3);                  \\\n     (ctx->T[(u)]) = ((ctx->T[(u)]) + tem2+(tem0^tem1)) ^ tem3;     \\\n     (ctx->Y[(a)]) = (ctx->T[(u)]);                 \\\n}\n\n/*16 steps of HC-128, without generating keystream, */\n/*but use the outputs to update P and Q*/\nstatic void setup_update(HC128* ctx)  /*each time 16 steps*/\n{\n   word32 cc,dd;\n   cc = ctx->counter1024 & 0x1ff;\n   dd = (cc+16)&0x1ff;\n\n   if (ctx->counter1024 < 512)\n   {\n      ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;\n      update_P(ctx, cc+0, cc+1, 0, 6, 13, 4);\n      update_P(ctx, cc+1, cc+2, 1, 7, 14, 5);\n      update_P(ctx, cc+2, cc+3, 2, 8, 15, 6);\n      update_P(ctx, cc+3, cc+4, 3, 9, 0,  7);\n      update_P(ctx, cc+4, cc+5, 4, 10,1,  8);\n      update_P(ctx, cc+5, cc+6, 5, 11,2,  9);\n      update_P(ctx, cc+6, cc+7, 6, 12,3,  10);\n      update_P(ctx, cc+7, cc+8, 7, 13,4,  11);\n      update_P(ctx, cc+8, cc+9, 8, 14,5,  12);\n      update_P(ctx, cc+9, cc+10,9, 15,6,  13);\n      update_P(ctx, cc+10,cc+11,10,0, 7,  14);\n      update_P(ctx, cc+11,cc+12,11,1, 8,  15);\n      update_P(ctx, cc+12,cc+13,12,2, 9,  0);\n      update_P(ctx, cc+13,cc+14,13,3, 10, 1);\n      update_P(ctx, cc+14,cc+15,14,4, 11, 2);\n      update_P(ctx, cc+15,dd+0, 15,5, 12, 3);\n   }\n   else\n   {\n      ctx->counter1024 = (ctx->counter1024 + 16) & 0x3ff;\n      update_Q(ctx, 512+cc+0, 512+cc+1, 0, 6, 13, 4);\n      update_Q(ctx, 512+cc+1, 512+cc+2, 1, 7, 14, 5);\n      update_Q(ctx, 512+cc+2, 512+cc+3, 2, 8, 15, 6);\n      update_Q(ctx, 512+cc+3, 512+cc+4, 3, 9, 0,  7);\n      update_Q(ctx, 512+cc+4, 512+cc+5, 4, 10,1,  8);\n      update_Q(ctx, 512+cc+5, 512+cc+6, 5, 11,2,  9);\n      update_Q(ctx, 512+cc+6, 512+cc+7, 6, 12,3,  10);\n      update_Q(ctx, 512+cc+7, 512+cc+8, 7, 13,4,  11);\n      update_Q(ctx, 512+cc+8, 512+cc+9, 8, 14,5,  12);\n      update_Q(ctx, 512+cc+9, 512+cc+10,9, 15,6,  13);\n      update_Q(ctx, 512+cc+10,512+cc+11,10,0, 7,  14);\n      update_Q(ctx, 512+cc+11,512+cc+12,11,1, 8,  15);\n      update_Q(ctx, 512+cc+12,512+cc+13,12,2, 9,  0);\n      update_Q(ctx, 512+cc+13,512+cc+14,13,3, 10, 1);\n      update_Q(ctx, 512+cc+14,512+cc+15,14,4, 11, 2);\n      update_Q(ctx, 512+cc+15,512+dd+0, 15,5, 12, 3);\n   }\n}\n\n\n/* for the 128-bit key:  key[0]...key[15]\n*  key[0] is the least significant byte of ctx->key[0] (K_0);\n*  key[3] is the most significant byte of ctx->key[0]  (K_0);\n*  ...\n*  key[12] is the least significant byte of ctx->key[3] (K_3)\n*  key[15] is the most significant byte of ctx->key[3]  (K_3)\n*\n*  for the 128-bit iv:  iv[0]...iv[15]\n*  iv[0] is the least significant byte of ctx->iv[0] (IV_0);\n*  iv[3] is the most significant byte of ctx->iv[0]  (IV_0);\n*  ...\n*  iv[12] is the least significant byte of ctx->iv[3] (IV_3)\n*  iv[15] is the most significant byte of ctx->iv[3]  (IV_3)\n*/\n\n\n\nstatic void Hc128_SetIV(HC128* ctx, const byte* inIv)\n{\n    word32 i;\n    word32 iv[4];\n\n    if (inIv)\n        XMEMCPY(iv, inIv, sizeof(iv));\n    else\n        XMEMSET(iv,    0, sizeof(iv));\n\n\tfor (i = 0; i < (128 >> 5); i++)\n        ctx->iv[i] = LITTLE32(iv[i]);\n\n    for (; i < 8; i++) ctx->iv[i] = ctx->iv[i-4];\n\n    /* expand the key and IV into the table T */\n    /* (expand the key and IV into the table P and Q) */\n\n\tfor (i = 0; i < 8;  i++)   ctx->T[i] = ctx->key[i];\n\tfor (i = 8; i < 16; i++)   ctx->T[i] = ctx->iv[i-8];\n\n    for (i = 16; i < (256+16); i++)\n\t\tctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) +\n                                                       ctx->T[i-16]+i;\n\n\tfor (i = 0; i < 16;  i++)  ctx->T[i] = ctx->T[256+i];\n\n\tfor (i = 16; i < 1024; i++)\n\t\tctx->T[i] = f2(ctx->T[i-2]) + ctx->T[i-7] + f1(ctx->T[i-15]) +\n                                                       ctx->T[i-16]+256+i;\n\n    /* initialize counter1024, X and Y */\n\tctx->counter1024 = 0;\n\tfor (i = 0; i < 16; i++) ctx->X[i] = ctx->T[512-16+i];\n    for (i = 0; i < 16; i++) ctx->Y[i] = ctx->T[512+512-16+i];\n\n    /* run the cipher 1024 steps before generating the output */\n\tfor (i = 0; i < 64; i++)  setup_update(ctx);\n}\n\n\nstatic WC_INLINE int DoKey(HC128* ctx, const byte* key, const byte* iv)\n{\n  word32 i;\n\n  /* Key size in bits 128 */\n  for (i = 0; i < (128 >> 5); i++)\n      ctx->key[i] = LITTLE32(((word32*)key)[i]);\n\n  for ( ; i < 8 ; i++) ctx->key[i] = ctx->key[i-4];\n\n  Hc128_SetIV(ctx, iv);\n\n  return 0;\n}\n\n\nint wc_Hc128_SetHeap(HC128* ctx, void* heap)\n{\n    if (ctx == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef XSTREAM_ALIGN\n    ctx->heap = heap;\n#endif\n\n    (void)heap;\n    return 0;\n}\n\n/* Key setup */\nint wc_Hc128_SetKey(HC128* ctx, const byte* key, const byte* iv)\n{\n    if (ctx == NULL || key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef XSTREAM_ALIGN\n    /* default heap to NULL or heap test value */\n    #ifdef WOLFSSL_HEAP_TEST\n        ctx->heap = (void*)WOLFSSL_HEAP_TEST;\n    #else\n        ctx->heap = NULL;\n    #endif /* WOLFSSL_HEAP_TEST */\n\n    if ((wolfssl_word)key % 4) {\n        int alignKey[4];\n\n        /* iv gets aligned in SetIV */\n        WOLFSSL_MSG(\"Hc128SetKey unaligned key\");\n\n        XMEMCPY(alignKey, key, sizeof(alignKey));\n\n        return DoKey(ctx, (const byte*)alignKey, iv);\n    }\n#endif /* XSTREAM_ALIGN */\n\n    return DoKey(ctx, key, iv);\n}\n\n\n\n/* The following defines the encryption of data stream */\nstatic WC_INLINE int DoProcess(HC128* ctx, byte* output, const byte* input,\n                            word32 msglen)\n{\n  word32 i, keystream[16];\n\n  for ( ; msglen >= 64; msglen -= 64, input += 64, output += 64)\n  {\n\t  generate_keystream(ctx, keystream);\n\n      /* unroll loop */\n\t  ((word32*)output)[0]  = ((word32*)input)[0]  ^ LITTLE32(keystream[0]);\n\t  ((word32*)output)[1]  = ((word32*)input)[1]  ^ LITTLE32(keystream[1]);\n\t  ((word32*)output)[2]  = ((word32*)input)[2]  ^ LITTLE32(keystream[2]);\n\t  ((word32*)output)[3]  = ((word32*)input)[3]  ^ LITTLE32(keystream[3]);\n\t  ((word32*)output)[4]  = ((word32*)input)[4]  ^ LITTLE32(keystream[4]);\n\t  ((word32*)output)[5]  = ((word32*)input)[5]  ^ LITTLE32(keystream[5]);\n\t  ((word32*)output)[6]  = ((word32*)input)[6]  ^ LITTLE32(keystream[6]);\n\t  ((word32*)output)[7]  = ((word32*)input)[7]  ^ LITTLE32(keystream[7]);\n\t  ((word32*)output)[8]  = ((word32*)input)[8]  ^ LITTLE32(keystream[8]);\n\t  ((word32*)output)[9]  = ((word32*)input)[9]  ^ LITTLE32(keystream[9]);\n\t  ((word32*)output)[10] = ((word32*)input)[10] ^ LITTLE32(keystream[10]);\n\t  ((word32*)output)[11] = ((word32*)input)[11] ^ LITTLE32(keystream[11]);\n\t  ((word32*)output)[12] = ((word32*)input)[12] ^ LITTLE32(keystream[12]);\n\t  ((word32*)output)[13] = ((word32*)input)[13] ^ LITTLE32(keystream[13]);\n\t  ((word32*)output)[14] = ((word32*)input)[14] ^ LITTLE32(keystream[14]);\n\t  ((word32*)output)[15] = ((word32*)input)[15] ^ LITTLE32(keystream[15]);\n  }\n\n  if (msglen > 0)\n  {\n      XMEMSET(keystream, 0, sizeof(keystream)); /* hush the static analysis */\n      generate_keystream(ctx, keystream);\n\n#ifdef BIG_ENDIAN_ORDER\n      {\n          word32 wordsLeft = msglen / sizeof(word32);\n          if (msglen % sizeof(word32)) wordsLeft++;\n\n          ByteReverseWords(keystream, keystream, wordsLeft * sizeof(word32));\n      }\n#endif\n\n      for (i = 0; i < msglen; i++)\n\t      output[i] = input[i] ^ ((byte*)keystream)[i];\n  }\n\n  return 0;\n}\n\n\n/* Encrypt/decrypt a message of any size */\nint wc_Hc128_Process(HC128* ctx, byte* output, const byte* input, word32 msglen)\n{\n    if (ctx == NULL || output == NULL || input == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef XSTREAM_ALIGN\n    if ((wolfssl_word)input % 4 || (wolfssl_word)output % 4) {\n        #ifndef NO_WOLFSSL_ALLOC_ALIGN\n            byte* tmp;\n            WOLFSSL_MSG(\"Hc128Process unaligned\");\n\n            tmp = (byte*)XMALLOC(msglen, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            if (tmp == NULL) return MEMORY_E;\n\n            XMEMCPY(tmp, input, msglen);\n            DoProcess(ctx, tmp, tmp, msglen);\n            XMEMCPY(output, tmp, msglen);\n\n            XFREE(tmp, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n            return 0;\n        #else\n            return BAD_ALIGN_E;\n        #endif\n    }\n#endif /* XSTREAM_ALIGN */\n\n    return DoProcess(ctx, output, input, msglen);\n}\n\n\n#else  /* HAVE_HC128 */\n\n\n#ifdef _MSC_VER\n    /* 4206 warning for blank file */\n    #pragma warning(disable: 4206)\n#endif\n\n\n#endif /* HAVE_HC128 */\n"
  },
  {
    "path": "src/wolfcrypt/src/hmac.c",
    "content": "/* hmac.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n\n#ifndef NO_HMAC\n\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n\n    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */\n    #define FIPS_NO_WRAPPERS\n\n    #ifdef USE_WINDOWS_API\n        #pragma code_seg(\".fipsA$b\")\n        #pragma const_seg(\".fipsB$b\")\n    #endif\n#endif\n\n#include <wolfssl/wolfcrypt/hmac.h>\n\n#ifdef WOLF_CRYPTO_CB\n    #include <wolfssl/wolfcrypt/cryptocb.h>\n#endif\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\n/* fips wrapper calls, user can call direct */\n/* If building for old FIPS. */\n#if defined(HAVE_FIPS) && \\\n    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n\n    /* does init */\n    int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz)\n    {\n        if (hmac == NULL || (key == NULL && keySz != 0) ||\n           !(type == WC_MD5 || type == WC_SHA || type == WC_SHA256 ||\n                type == WC_SHA384 || type == WC_SHA512)) {\n            return BAD_FUNC_ARG;\n        }\n\n        return HmacSetKey_fips(hmac, type, key, keySz);\n    }\n    int wc_HmacUpdate(Hmac* hmac, const byte* in, word32 sz)\n    {\n        if (hmac == NULL || (in == NULL && sz > 0)) {\n            return BAD_FUNC_ARG;\n        }\n\n        return HmacUpdate_fips(hmac, in, sz);\n    }\n    int wc_HmacFinal(Hmac* hmac, byte* out)\n    {\n        if (hmac == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n        return HmacFinal_fips(hmac, out);\n    }\n    int wolfSSL_GetHmacMaxSize(void)\n    {\n        return CyaSSL_GetHmacMaxSize();\n    }\n\n    int wc_HmacInit(Hmac* hmac, void* heap, int devId)\n    {\n        (void)hmac;\n        (void)heap;\n        (void)devId;\n        /* FIPS doesn't support:\n            return HmacInit(hmac, heap, devId); */\n        return 0;\n    }\n    void wc_HmacFree(Hmac* hmac)\n    {\n        (void)hmac;\n        /* FIPS doesn't support:\n            HmacFree(hmac); */\n    }\n\n    #ifdef HAVE_HKDF\n        int wc_HKDF(int type, const byte* inKey, word32 inKeySz,\n                    const byte* salt, word32 saltSz,\n                    const byte* info, word32 infoSz,\n                    byte* out, word32 outSz)\n        {\n            return HKDF(type, inKey, inKeySz, salt, saltSz,\n                info, infoSz, out, outSz);\n        }\n    #endif /* HAVE_HKDF */\n\n#else /* else build without fips, or for new fips */\n\n\nint wc_HmacSizeByType(int type)\n{\n    int ret;\n\n    if (!(type == WC_MD5 || type == WC_SHA ||\n            type == WC_SHA224 || type == WC_SHA256 ||\n            type == WC_SHA384 || type == WC_SHA512 ||\n            type == WC_SHA3_224 || type == WC_SHA3_256 ||\n            type == WC_SHA3_384 || type == WC_SHA3_512)) {\n        return BAD_FUNC_ARG;\n    }\n\n    switch (type) {\n    #ifndef NO_MD5\n        case WC_MD5:\n            ret = WC_MD5_DIGEST_SIZE;\n            break;\n    #endif /* !NO_MD5 */\n\n    #ifndef NO_SHA\n        case WC_SHA:\n            ret = WC_SHA_DIGEST_SIZE;\n            break;\n    #endif /* !NO_SHA */\n\n    #ifdef WOLFSSL_SHA224\n        case WC_SHA224:\n            ret = WC_SHA224_DIGEST_SIZE;\n            break;\n    #endif /* WOLFSSL_SHA224 */\n\n    #ifndef NO_SHA256\n        case WC_SHA256:\n            ret = WC_SHA256_DIGEST_SIZE;\n            break;\n    #endif /* !NO_SHA256 */\n\n    #ifdef WOLFSSL_SHA384\n        case WC_SHA384:\n            ret = WC_SHA384_DIGEST_SIZE;\n            break;\n    #endif /* WOLFSSL_SHA384 */\n    #ifdef WOLFSSL_SHA512\n        case WC_SHA512:\n            ret = WC_SHA512_DIGEST_SIZE;\n            break;\n    #endif /* WOLFSSL_SHA512 */\n\n    #ifdef WOLFSSL_SHA3\n        case WC_SHA3_224:\n            ret = WC_SHA3_224_DIGEST_SIZE;\n            break;\n\n        case WC_SHA3_256:\n            ret = WC_SHA3_256_DIGEST_SIZE;\n            break;\n\n        case WC_SHA3_384:\n            ret = WC_SHA3_384_DIGEST_SIZE;\n            break;\n\n        case WC_SHA3_512:\n            ret = WC_SHA3_512_DIGEST_SIZE;\n            break;\n\n    #endif\n\n        default:\n            ret = BAD_FUNC_ARG;\n            break;\n    }\n\n    return ret;\n}\n\nint _InitHmac(Hmac* hmac, int type, void* heap)\n{\n    int ret = 0;\n\n    switch (type) {\n    #ifndef NO_MD5\n        case WC_MD5:\n            ret = wc_InitMd5(&hmac->hash.md5);\n            break;\n    #endif /* !NO_MD5 */\n\n    #ifndef NO_SHA\n        case WC_SHA:\n            ret = wc_InitSha(&hmac->hash.sha);\n            break;\n    #endif /* !NO_SHA */\n\n    #ifdef WOLFSSL_SHA224\n        case WC_SHA224:\n            ret = wc_InitSha224(&hmac->hash.sha224);\n            break;\n    #endif /* WOLFSSL_SHA224 */\n\n    #ifndef NO_SHA256\n        case WC_SHA256:\n            ret = wc_InitSha256(&hmac->hash.sha256);\n            break;\n    #endif /* !NO_SHA256 */\n\n    #ifdef WOLFSSL_SHA384\n        case WC_SHA384:\n            ret = wc_InitSha384(&hmac->hash.sha384);\n            break;\n    #endif /* WOLFSSL_SHA384 */\n    #ifdef WOLFSSL_SHA512\n        case WC_SHA512:\n            ret = wc_InitSha512(&hmac->hash.sha512);\n            break;\n    #endif /* WOLFSSL_SHA512 */\n\n    #ifdef WOLFSSL_SHA3\n    #ifndef WOLFSSL_NOSHA3_224\n        case WC_SHA3_224:\n            ret = wc_InitSha3_224(&hmac->hash.sha3, heap, INVALID_DEVID);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_256\n        case WC_SHA3_256:\n            ret = wc_InitSha3_256(&hmac->hash.sha3, heap, INVALID_DEVID);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_384\n        case WC_SHA3_384:\n            ret = wc_InitSha3_384(&hmac->hash.sha3, heap, INVALID_DEVID);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_512\n        case WC_SHA3_512:\n            ret = wc_InitSha3_512(&hmac->hash.sha3, heap, INVALID_DEVID);\n            break;\n    #endif\n    #endif\n\n        default:\n            ret = BAD_FUNC_ARG;\n            break;\n    }\n\n    /* default to NULL heap hint or test value */\n#ifdef WOLFSSL_HEAP_TEST\n    hmac->heap = (void)WOLFSSL_HEAP_TEST;\n#else\n    hmac->heap = heap;\n#endif /* WOLFSSL_HEAP_TEST */\n\n    return ret;\n}\n\n\nint wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)\n{\n    byte*  ip;\n    byte*  op;\n    word32 i, hmac_block_size = 0;\n    int    ret = 0;\n    void*  heap = NULL;\n\n    if (hmac == NULL || (key == NULL && length != 0) ||\n       !(type == WC_MD5 || type == WC_SHA ||\n            type == WC_SHA224 || type == WC_SHA256 ||\n            type == WC_SHA384 || type == WC_SHA512 ||\n            type == WC_SHA3_224 || type == WC_SHA3_256 ||\n            type == WC_SHA3_384 || type == WC_SHA3_512)) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* if set key has already been run then make sure and free existing */\n    if (hmac->macType != 0) {\n        wc_HmacFree(hmac);\n    }\n\n    hmac->innerHashKeyed = 0;\n    hmac->macType = (byte)type;\n\n    ret = _InitHmac(hmac, type, heap);\n    if (ret != 0)\n        return ret;\n\n#ifdef HAVE_FIPS\n    if (length < HMAC_FIPS_MIN_KEY)\n        return HMAC_MIN_KEYLEN_E;\n#endif\n\n#ifdef WOLF_CRYPTO_CB\n    hmac->keyRaw = key; /* use buffer directly */\n    hmac->keyLen = length;\n#endif\n\n    ip = (byte*)hmac->ipad;\n    op = (byte*)hmac->opad;\n\n    switch (hmac->macType) {\n    #ifndef NO_MD5\n        case WC_MD5:\n            hmac_block_size = WC_MD5_BLOCK_SIZE;\n            if (length <= WC_MD5_BLOCK_SIZE) {\n                if (key != NULL) {\n                    XMEMCPY(ip, key, length);\n                }\n            }\n            else {\n                ret = wc_Md5Update(&hmac->hash.md5, key, length);\n                if (ret != 0)\n                    break;\n                ret = wc_Md5Final(&hmac->hash.md5, ip);\n                if (ret != 0)\n                    break;\n                length = WC_MD5_DIGEST_SIZE;\n            }\n            break;\n    #endif /* !NO_MD5 */\n\n    #ifndef NO_SHA\n        case WC_SHA:\n            hmac_block_size = WC_SHA_BLOCK_SIZE;\n            if (length <= WC_SHA_BLOCK_SIZE) {\n                if (key != NULL) {\n                    XMEMCPY(ip, key, length);\n                }\n            }\n            else {\n                ret = wc_ShaUpdate(&hmac->hash.sha, key, length);\n                if (ret != 0)\n                    break;\n                ret = wc_ShaFinal(&hmac->hash.sha, ip);\n                if (ret != 0)\n                    break;\n\n                length = WC_SHA_DIGEST_SIZE;\n            }\n            break;\n    #endif /* !NO_SHA */\n\n    #ifdef WOLFSSL_SHA224\n        case WC_SHA224:\n            hmac_block_size = WC_SHA224_BLOCK_SIZE;\n            if (length <= WC_SHA224_BLOCK_SIZE) {\n                if (key != NULL) {\n                    XMEMCPY(ip, key, length);\n                }\n            }\n            else {\n                ret = wc_Sha224Update(&hmac->hash.sha224, key, length);\n                if (ret != 0)\n                    break;\n                ret = wc_Sha224Final(&hmac->hash.sha224, ip);\n                if (ret != 0)\n                    break;\n\n                length = WC_SHA224_DIGEST_SIZE;\n            }\n            break;\n    #endif /* WOLFSSL_SHA224 */\n    #ifndef NO_SHA256\n        case WC_SHA256:\n            hmac_block_size = WC_SHA256_BLOCK_SIZE;\n            if (length <= WC_SHA256_BLOCK_SIZE) {\n                if (key != NULL) {\n                    XMEMCPY(ip, key, length);\n                }\n            }\n            else {\n                ret = wc_Sha256Update(&hmac->hash.sha256, key, length);\n                if (ret != 0)\n                    break;\n                ret = wc_Sha256Final(&hmac->hash.sha256, ip);\n                if (ret != 0)\n                    break;\n\n                length = WC_SHA256_DIGEST_SIZE;\n            }\n            break;\n    #endif /* !NO_SHA256 */\n\n    #ifdef WOLFSSL_SHA384\n        case WC_SHA384:\n            hmac_block_size = WC_SHA384_BLOCK_SIZE;\n            if (length <= WC_SHA384_BLOCK_SIZE) {\n                if (key != NULL) {\n                    XMEMCPY(ip, key, length);\n                }\n            }\n            else {\n                ret = wc_Sha384Update(&hmac->hash.sha384, key, length);\n                if (ret != 0)\n                    break;\n                ret = wc_Sha384Final(&hmac->hash.sha384, ip);\n                if (ret != 0)\n                    break;\n\n                length = WC_SHA384_DIGEST_SIZE;\n            }\n            break;\n    #endif /* WOLFSSL_SHA384 */\n    #ifdef WOLFSSL_SHA512\n        case WC_SHA512:\n            hmac_block_size = WC_SHA512_BLOCK_SIZE;\n            if (length <= WC_SHA512_BLOCK_SIZE) {\n                if (key != NULL) {\n                    XMEMCPY(ip, key, length);\n                }\n            }\n            else {\n                ret = wc_Sha512Update(&hmac->hash.sha512, key, length);\n                if (ret != 0)\n                    break;\n                ret = wc_Sha512Final(&hmac->hash.sha512, ip);\n                if (ret != 0)\n                    break;\n\n                length = WC_SHA512_DIGEST_SIZE;\n            }\n            break;\n    #endif /* WOLFSSL_SHA512 */\n\n    #ifdef WOLFSSL_SHA3\n    #ifndef WOLFSSL_NOSHA3_224\n        case WC_SHA3_224:\n            hmac_block_size = WC_SHA3_224_BLOCK_SIZE;\n            if (length <= WC_SHA3_224_BLOCK_SIZE) {\n                if (key != NULL) {\n                    XMEMCPY(ip, key, length);\n                }\n            }\n            else {\n                ret = wc_Sha3_224_Update(&hmac->hash.sha3, key, length);\n                if (ret != 0)\n                    break;\n                ret = wc_Sha3_224_Final(&hmac->hash.sha3, ip);\n                if (ret != 0)\n                    break;\n\n                length = WC_SHA3_224_DIGEST_SIZE;\n            }\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_256\n        case WC_SHA3_256:\n            hmac_block_size = WC_SHA3_256_BLOCK_SIZE;\n            if (length <= WC_SHA3_256_BLOCK_SIZE) {\n                if (key != NULL) {\n                    XMEMCPY(ip, key, length);\n                }\n            }\n            else {\n                ret = wc_Sha3_256_Update(&hmac->hash.sha3, key, length);\n                if (ret != 0)\n                    break;\n                ret = wc_Sha3_256_Final(&hmac->hash.sha3, ip);\n                if (ret != 0)\n                    break;\n\n                length = WC_SHA3_256_DIGEST_SIZE;\n            }\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_384\n        case WC_SHA3_384:\n            hmac_block_size = WC_SHA3_384_BLOCK_SIZE;\n            if (length <= WC_SHA3_384_BLOCK_SIZE) {\n                if (key != NULL) {\n                    XMEMCPY(ip, key, length);\n                }\n            }\n            else {\n                ret = wc_Sha3_384_Update(&hmac->hash.sha3, key, length);\n                if (ret != 0)\n                    break;\n                ret = wc_Sha3_384_Final(&hmac->hash.sha3, ip);\n                if (ret != 0)\n                    break;\n\n                length = WC_SHA3_384_DIGEST_SIZE;\n            }\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_512\n        case WC_SHA3_512:\n            hmac_block_size = WC_SHA3_512_BLOCK_SIZE;\n            if (length <= WC_SHA3_512_BLOCK_SIZE) {\n                if (key != NULL) {\n                    XMEMCPY(ip, key, length);\n                }\n            }\n            else {\n                ret = wc_Sha3_512_Update(&hmac->hash.sha3, key, length);\n                if (ret != 0)\n                    break;\n                ret = wc_Sha3_512_Final(&hmac->hash.sha3, ip);\n                if (ret != 0)\n                    break;\n\n                length = WC_SHA3_512_DIGEST_SIZE;\n            }\n            break;\n    #endif\n    #endif /* WOLFSSL_SHA3 */\n\n        default:\n            return BAD_FUNC_ARG;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)\n    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {\n    #if defined(HAVE_INTEL_QA) || defined(HAVE_CAVIUM)\n        #ifdef HAVE_INTEL_QA\n        if (IntelQaHmacGetType(hmac->macType, NULL) == 0)\n        #endif\n        {\n            if (length > hmac_block_size)\n                length = hmac_block_size;\n            /* update key length */\n            hmac->keyLen = (word16)length;\n\n            return ret;\n        }\n        /* no need to pad below */\n    #endif\n    }\n#endif\n\n    if (ret == 0) {\n        if (length < hmac_block_size)\n            XMEMSET(ip + length, 0, hmac_block_size - length);\n\n        for(i = 0; i < hmac_block_size; i++) {\n            op[i] = ip[i] ^ OPAD;\n            ip[i] ^= IPAD;\n        }\n    }\n\n    return ret;\n}\n\n\nstatic int HmacKeyInnerHash(Hmac* hmac)\n{\n    int ret = 0;\n\n    switch (hmac->macType) {\n    #ifndef NO_MD5\n        case WC_MD5:\n            ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->ipad,\n                                                             WC_MD5_BLOCK_SIZE);\n            break;\n    #endif /* !NO_MD5 */\n\n    #ifndef NO_SHA\n        case WC_SHA:\n            ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->ipad,\n                                                             WC_SHA_BLOCK_SIZE);\n            break;\n    #endif /* !NO_SHA */\n\n    #ifdef WOLFSSL_SHA224\n        case WC_SHA224:\n            ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->ipad,\n                                                          WC_SHA224_BLOCK_SIZE);\n            break;\n    #endif /* WOLFSSL_SHA224 */\n    #ifndef NO_SHA256\n        case WC_SHA256:\n            ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->ipad,\n                                                          WC_SHA256_BLOCK_SIZE);\n            break;\n    #endif /* !NO_SHA256 */\n\n    #ifdef WOLFSSL_SHA384\n        case WC_SHA384:\n            ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->ipad,\n                                                          WC_SHA384_BLOCK_SIZE);\n            break;\n    #endif /* WOLFSSL_SHA384 */\n    #ifdef WOLFSSL_SHA512\n        case WC_SHA512:\n            ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->ipad,\n                                                          WC_SHA512_BLOCK_SIZE);\n            break;\n    #endif /* WOLFSSL_SHA512 */\n\n    #ifdef WOLFSSL_SHA3\n    #ifndef WOLFSSL_NOSHA3_224\n        case WC_SHA3_224:\n            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->ipad,\n                                                        WC_SHA3_224_BLOCK_SIZE);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_256\n        case WC_SHA3_256:\n            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->ipad,\n                                                        WC_SHA3_256_BLOCK_SIZE);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_384\n        case WC_SHA3_384:\n            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->ipad,\n                                                        WC_SHA3_384_BLOCK_SIZE);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_512\n        case WC_SHA3_512:\n            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->ipad,\n                                                        WC_SHA3_512_BLOCK_SIZE);\n            break;\n    #endif\n    #endif /* WOLFSSL_SHA3 */\n\n        default:\n            break;\n    }\n\n    if (ret == 0)\n        hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_SW;\n\n    return ret;\n}\n\n\nint wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length)\n{\n    int ret = 0;\n\n    if (hmac == NULL || (msg == NULL && length > 0)) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLF_CRYPTO_CB\n    if (hmac->devId != INVALID_DEVID) {\n        ret = wc_CryptoCb_Hmac(hmac, hmac->macType, msg, length, NULL);\n        if (ret != CRYPTOCB_UNAVAILABLE)\n            return ret;\n        /* fall-through when unavailable */\n        ret = 0; /* reset error code */\n    }\n#endif\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)\n    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {\n    #if defined(HAVE_CAVIUM)\n        return NitroxHmacUpdate(hmac, msg, length);\n    #elif defined(HAVE_INTEL_QA)\n        if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {\n            return IntelQaHmac(&hmac->asyncDev, hmac->macType,\n                (byte*)hmac->ipad, hmac->keyLen, NULL, msg, length);\n        }\n    #endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    if (!hmac->innerHashKeyed) {\n        ret = HmacKeyInnerHash(hmac);\n        if (ret != 0)\n            return ret;\n    }\n\n    switch (hmac->macType) {\n    #ifndef NO_MD5\n        case WC_MD5:\n            ret = wc_Md5Update(&hmac->hash.md5, msg, length);\n            break;\n    #endif /* !NO_MD5 */\n\n    #ifndef NO_SHA\n        case WC_SHA:\n            ret = wc_ShaUpdate(&hmac->hash.sha, msg, length);\n            break;\n    #endif /* !NO_SHA */\n\n    #ifdef WOLFSSL_SHA224\n        case WC_SHA224:\n            ret = wc_Sha224Update(&hmac->hash.sha224, msg, length);\n            break;\n    #endif /* WOLFSSL_SHA224 */\n\n    #ifndef NO_SHA256\n        case WC_SHA256:\n            ret = wc_Sha256Update(&hmac->hash.sha256, msg, length);\n            break;\n    #endif /* !NO_SHA256 */\n\n    #ifdef WOLFSSL_SHA384\n        case WC_SHA384:\n            ret = wc_Sha384Update(&hmac->hash.sha384, msg, length);\n            break;\n    #endif /* WOLFSSL_SHA384 */\n    #ifdef WOLFSSL_SHA512\n        case WC_SHA512:\n            ret = wc_Sha512Update(&hmac->hash.sha512, msg, length);\n            break;\n    #endif /* WOLFSSL_SHA512 */\n\n    #ifdef WOLFSSL_SHA3\n    #ifndef WOLFSSL_NOSHA3_224\n        case WC_SHA3_224:\n            ret = wc_Sha3_224_Update(&hmac->hash.sha3, msg, length);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_256\n        case WC_SHA3_256:\n            ret = wc_Sha3_256_Update(&hmac->hash.sha3, msg, length);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_384\n        case WC_SHA3_384:\n            ret = wc_Sha3_384_Update(&hmac->hash.sha3, msg, length);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_512\n        case WC_SHA3_512:\n            ret = wc_Sha3_512_Update(&hmac->hash.sha3, msg, length);\n            break;\n    #endif\n    #endif /* WOLFSSL_SHA3 */\n\n        default:\n            break;\n    }\n\n    return ret;\n}\n\n\nint wc_HmacFinal(Hmac* hmac, byte* hash)\n{\n    int ret;\n\n    if (hmac == NULL || hash == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLF_CRYPTO_CB\n    if (hmac->devId != INVALID_DEVID) {\n        ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, hash);\n        if (ret != CRYPTOCB_UNAVAILABLE)\n            return ret;\n        /* fall-through when unavailable */\n    }\n#endif\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)\n    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {\n        int hashLen = wc_HmacSizeByType(hmac->macType);\n        if (hashLen <= 0)\n            return hashLen;\n\n    #if defined(HAVE_CAVIUM)\n        return NitroxHmacFinal(hmac, hash, hashLen);\n    #elif defined(HAVE_INTEL_QA)\n        if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {\n            return IntelQaHmac(&hmac->asyncDev, hmac->macType,\n                (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen);\n        }\n    #endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    if (!hmac->innerHashKeyed) {\n        ret = HmacKeyInnerHash(hmac);\n        if (ret != 0)\n            return ret;\n    }\n\n    switch (hmac->macType) {\n    #ifndef NO_MD5\n        case WC_MD5:\n            ret = wc_Md5Final(&hmac->hash.md5, (byte*)hmac->innerHash);\n            if (ret != 0)\n                break;\n            ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->opad,\n                                                             WC_MD5_BLOCK_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->innerHash,\n                                                            WC_MD5_DIGEST_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Md5Final(&hmac->hash.md5, hash);\n            break;\n    #endif /* !NO_MD5 */\n\n    #ifndef NO_SHA\n        case WC_SHA:\n            ret = wc_ShaFinal(&hmac->hash.sha, (byte*)hmac->innerHash);\n            if (ret != 0)\n                break;\n            ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad,\n                                                             WC_SHA_BLOCK_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash,\n                                                            WC_SHA_DIGEST_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_ShaFinal(&hmac->hash.sha, hash);\n            break;\n    #endif /* !NO_SHA */\n\n    #ifdef WOLFSSL_SHA224\n        case WC_SHA224:\n            ret = wc_Sha224Final(&hmac->hash.sha224, (byte*)hmac->innerHash);\n            if (ret != 0)\n                break;\n            ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->opad,\n                                                          WC_SHA224_BLOCK_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->innerHash,\n                                                         WC_SHA224_DIGEST_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha224Final(&hmac->hash.sha224, hash);\n            if (ret != 0)\n                break;\n            break;\n    #endif /* WOLFSSL_SHA224 */\n    #ifndef NO_SHA256\n        case WC_SHA256:\n            ret = wc_Sha256Final(&hmac->hash.sha256, (byte*)hmac->innerHash);\n            if (ret != 0)\n                break;\n            ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad,\n                                                          WC_SHA256_BLOCK_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->innerHash,\n                                                         WC_SHA256_DIGEST_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha256Final(&hmac->hash.sha256, hash);\n            break;\n    #endif /* !NO_SHA256 */\n\n    #ifdef WOLFSSL_SHA384\n        case WC_SHA384:\n            ret = wc_Sha384Final(&hmac->hash.sha384, (byte*)hmac->innerHash);\n            if (ret != 0)\n                break;\n            ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad,\n                                                          WC_SHA384_BLOCK_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->innerHash,\n                                                         WC_SHA384_DIGEST_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha384Final(&hmac->hash.sha384, hash);\n            break;\n    #endif /* WOLFSSL_SHA384 */\n    #ifdef WOLFSSL_SHA512\n        case WC_SHA512:\n            ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash);\n            if (ret != 0)\n                break;\n            ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->opad,\n                                                          WC_SHA512_BLOCK_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->innerHash,\n                                                         WC_SHA512_DIGEST_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha512Final(&hmac->hash.sha512, hash);\n            break;\n    #endif /* WOLFSSL_SHA512 */\n\n    #ifdef WOLFSSL_SHA3\n    #ifndef WOLFSSL_NOSHA3_224\n        case WC_SHA3_224:\n            ret = wc_Sha3_224_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);\n            if (ret != 0)\n                break;\n            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->opad,\n                                                        WC_SHA3_224_BLOCK_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,\n                                                       WC_SHA3_224_DIGEST_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha3_224_Final(&hmac->hash.sha3, hash);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_256\n        case WC_SHA3_256:\n            ret = wc_Sha3_256_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);\n            if (ret != 0)\n                break;\n            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->opad,\n                                                        WC_SHA3_256_BLOCK_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,\n                                                       WC_SHA3_256_DIGEST_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha3_256_Final(&hmac->hash.sha3, hash);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_384\n        case WC_SHA3_384:\n            ret = wc_Sha3_384_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);\n            if (ret != 0)\n                break;\n            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->opad,\n                                                        WC_SHA3_384_BLOCK_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,\n                                                       WC_SHA3_384_DIGEST_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha3_384_Final(&hmac->hash.sha3, hash);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_512\n        case WC_SHA3_512:\n            ret = wc_Sha3_512_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);\n            if (ret != 0)\n                break;\n            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->opad,\n                                                        WC_SHA3_512_BLOCK_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,\n                                                       WC_SHA3_512_DIGEST_SIZE);\n            if (ret != 0)\n                break;\n            ret = wc_Sha3_512_Final(&hmac->hash.sha3, hash);\n            break;\n    #endif\n    #endif /* WOLFSSL_SHA3 */\n\n        default:\n            ret = BAD_FUNC_ARG;\n            break;\n    }\n\n    if (ret == 0) {\n        hmac->innerHashKeyed = 0;\n    }\n\n    return ret;\n}\n\n\n/* Initialize Hmac for use with async device */\nint wc_HmacInit(Hmac* hmac, void* heap, int devId)\n{\n    int ret = 0;\n\n    if (hmac == NULL)\n        return BAD_FUNC_ARG;\n\n    XMEMSET(hmac, 0, sizeof(Hmac));\n    hmac->heap = heap;\n#ifdef WOLF_CRYPTO_CB\n    hmac->devId = devId;\n    hmac->devCtx = NULL;\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)\n    ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC,\n                                                         hmac->heap, devId);\n#else\n    (void)devId;\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    return ret;\n}\n\n#ifdef HAVE_PKCS11\nint  wc_HmacInit_Id(Hmac* hmac, unsigned char* id, int len, void* heap,\n                    int devId)\n{\n    int ret = 0;\n\n    if (hmac == NULL)\n        ret = BAD_FUNC_ARG;\n    if (ret == 0 && (len < 0 || len > HMAC_MAX_ID_LEN))\n        ret = BUFFER_E;\n\n    if (ret == 0)\n        ret  = wc_HmacInit(hmac, heap, devId);\n    if (ret == 0) {\n        XMEMCPY(hmac->id, id, len);\n        hmac->idLen = len;\n    }\n\n    return ret;\n}\n#endif\n\n/* Free Hmac from use with async device */\nvoid wc_HmacFree(Hmac* hmac)\n{\n    if (hmac == NULL)\n        return;\n\n#ifdef WOLF_CRYPTO_CB\n    /* handle cleanup case where final is not called */\n    if (hmac->devId != INVALID_DEVID && hmac->devCtx != NULL) {\n        int  ret;\n        byte finalHash[WC_HMAC_BLOCK_SIZE];\n        ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, finalHash);\n        (void)ret; /* must ignore return code here */\n        (void)finalHash;\n    }\n#endif\n\n    switch (hmac->macType) {\n    #ifndef NO_MD5\n        case WC_MD5:\n            wc_Md5Free(&hmac->hash.md5);\n            break;\n    #endif /* !NO_MD5 */\n\n    #ifndef NO_SHA\n        case WC_SHA:\n            wc_ShaFree(&hmac->hash.sha);\n            break;\n    #endif /* !NO_SHA */\n\n    #ifdef WOLFSSL_SHA224\n        case WC_SHA224:\n            wc_Sha224Free(&hmac->hash.sha224);\n            break;\n    #endif /* WOLFSSL_SHA224 */\n    #ifndef NO_SHA256\n        case WC_SHA256:\n            wc_Sha256Free(&hmac->hash.sha256);\n            break;\n    #endif /* !NO_SHA256 */\n\n    #ifdef WOLFSSL_SHA384\n        case WC_SHA384:\n            wc_Sha384Free(&hmac->hash.sha384);\n            break;\n    #endif /* WOLFSSL_SHA384 */\n    #ifdef WOLFSSL_SHA512\n        case WC_SHA512:\n            wc_Sha512Free(&hmac->hash.sha512);\n            break;\n    #endif /* WOLFSSL_SHA512 */\n\n    #ifdef WOLFSSL_SHA3\n    #ifndef WOLFSSL_NOSHA3_224\n        case WC_SHA3_224:\n            wc_Sha3_224_Free(&hmac->hash.sha3);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_256\n        case WC_SHA3_256:\n            wc_Sha3_256_Free(&hmac->hash.sha3);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_384\n        case WC_SHA3_384:\n            wc_Sha3_384_Free(&hmac->hash.sha3);\n            break;\n    #endif\n    #ifndef WOLFSSL_NOSHA3_512\n        case WC_SHA3_512:\n            wc_Sha3_512_Free(&hmac->hash.sha3);\n            break;\n    #endif\n    #endif /* WOLFSSL_SHA3 */\n\n        default:\n            break;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)\n    wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC);\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    switch (hmac->macType) {\n    #ifndef NO_MD5\n        case WC_MD5:\n            wc_Md5Free(&hmac->hash.md5);\n            break;\n    #endif /* !NO_MD5 */\n\n    #ifndef NO_SHA\n        case WC_SHA:\n            wc_ShaFree(&hmac->hash.sha);\n            break;\n    #endif /* !NO_SHA */\n\n    #ifdef WOLFSSL_SHA224\n        case WC_SHA224:\n            wc_Sha224Free(&hmac->hash.sha224);\n            break;\n    #endif /* WOLFSSL_SHA224 */\n    #ifndef NO_SHA256\n        case WC_SHA256:\n            wc_Sha256Free(&hmac->hash.sha256);\n            break;\n    #endif /* !NO_SHA256 */\n\n    #ifdef WOLFSSL_SHA512\n    #ifdef WOLFSSL_SHA384\n        case WC_SHA384:\n            wc_Sha384Free(&hmac->hash.sha384);\n            break;\n    #endif /* WOLFSSL_SHA384 */\n        case WC_SHA512:\n            wc_Sha512Free(&hmac->hash.sha512);\n            break;\n    #endif /* WOLFSSL_SHA512 */\n    }\n}\n\nint wolfSSL_GetHmacMaxSize(void)\n{\n    return WC_MAX_DIGEST_SIZE;\n}\n\n#ifdef HAVE_HKDF\n    /* HMAC-KDF-Extract.\n     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).\n     *\n     * type     The hash algorithm type.\n     * salt     The optional salt value.\n     * saltSz   The size of the salt.\n     * inKey    The input keying material.\n     * inKeySz  The size of the input keying material.\n     * out      The pseudorandom key with the length that of the hash.\n     * returns 0 on success, otherwise failure.\n     */\n    int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz,\n                        const byte* inKey, word32 inKeySz, byte* out)\n    {\n        byte   tmp[WC_MAX_DIGEST_SIZE]; /* localSalt helper */\n        Hmac   myHmac;\n        int    ret;\n        const  byte* localSalt;  /* either points to user input or tmp */\n        int    hashSz;\n\n        ret = wc_HmacSizeByType(type);\n        if (ret < 0)\n            return ret;\n\n        hashSz = ret;\n        localSalt = salt;\n        if (localSalt == NULL) {\n            XMEMSET(tmp, 0, hashSz);\n            localSalt = tmp;\n            saltSz    = hashSz;\n        }\n\n        ret = wc_HmacInit(&myHmac, NULL, INVALID_DEVID);\n        if (ret == 0) {\n            ret = wc_HmacSetKey(&myHmac, type, localSalt, saltSz);\n            if (ret == 0)\n                ret = wc_HmacUpdate(&myHmac, inKey, inKeySz);\n            if (ret == 0)\n                ret = wc_HmacFinal(&myHmac,  out);\n            wc_HmacFree(&myHmac);\n        }\n\n        return ret;\n    }\n\n    /* HMAC-KDF-Expand.\n     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).\n     *\n     * type     The hash algorithm type.\n     * inKey    The input key.\n     * inKeySz  The size of the input key.\n     * info     The application specific information.\n     * infoSz   The size of the application specific information.\n     * out      The output keying material.\n     * returns 0 on success, otherwise failure.\n     */\n    int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz,\n                       const byte* info, word32 infoSz, byte* out, word32 outSz)\n    {\n        byte   tmp[WC_MAX_DIGEST_SIZE];\n        Hmac   myHmac;\n        int    ret = 0;\n        word32 outIdx = 0;\n        word32 hashSz = wc_HmacSizeByType(type);\n        byte   n = 0x1;\n\n        ret = wc_HmacInit(&myHmac, NULL, INVALID_DEVID);\n        if (ret != 0)\n            return ret;\n\n        while (outIdx < outSz) {\n            int    tmpSz = (n == 1) ? 0 : hashSz;\n            word32 left = outSz - outIdx;\n\n            ret = wc_HmacSetKey(&myHmac, type, inKey, inKeySz);\n            if (ret != 0)\n                break;\n            ret = wc_HmacUpdate(&myHmac, tmp, tmpSz);\n            if (ret != 0)\n                break;\n            ret = wc_HmacUpdate(&myHmac, info, infoSz);\n            if (ret != 0)\n                break;\n            ret = wc_HmacUpdate(&myHmac, &n, 1);\n            if (ret != 0)\n                break;\n            ret = wc_HmacFinal(&myHmac, tmp);\n            if (ret != 0)\n                break;\n\n            left = min(left, hashSz);\n            XMEMCPY(out+outIdx, tmp, left);\n\n            outIdx += hashSz;\n            n++;\n        }\n\n        wc_HmacFree(&myHmac);\n\n        return ret;\n    }\n\n    /* HMAC-KDF.\n     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).\n     *\n     * type     The hash algorithm type.\n     * inKey    The input keying material.\n     * inKeySz  The size of the input keying material.\n     * salt     The optional salt value.\n     * saltSz   The size of the salt.\n     * info     The application specific information.\n     * infoSz   The size of the application specific information.\n     * out      The output keying material.\n     * returns 0 on success, otherwise failure.\n     */\n    int wc_HKDF(int type, const byte* inKey, word32 inKeySz,\n                       const byte* salt,  word32 saltSz,\n                       const byte* info,  word32 infoSz,\n                       byte* out,         word32 outSz)\n    {\n        byte   prk[WC_MAX_DIGEST_SIZE];\n        int    hashSz = wc_HmacSizeByType(type);\n        int    ret;\n\n        if (hashSz < 0)\n            return BAD_FUNC_ARG;\n\n        ret = wc_HKDF_Extract(type, salt, saltSz, inKey, inKeySz, prk);\n        if (ret != 0)\n            return ret;\n\n        return wc_HKDF_Expand(type, prk, hashSz, info, infoSz, out, outSz);\n    }\n\n#endif /* HAVE_HKDF */\n\n#endif /* HAVE_FIPS */\n#endif /* NO_HMAC */\n"
  },
  {
    "path": "src/wolfcrypt/src/idea.c",
    "content": "/* idea.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_IDEA\n\n#include <wolfssl/wolfcrypt/idea.h>\n\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n/* multiplication of x and y modulo 2^16+1\n * IDEA specify a special case when an entry value is 0 ( x or y)\n * then it must be replaced by 2^16\n */\nstatic WC_INLINE word16 idea_mult(word16 x, word16 y)\n{\n    long mul, res;\n\n    mul = (long)x * (long)y;\n    if (mul) {\n        res = (mul & IDEA_MASK) - ((word32)mul >> 16);\n        if (res <= 0)\n            res += IDEA_MODULO;\n\n        return (word16) (res & IDEA_MASK);\n    }\n\n    if (!x)\n        return ((IDEA_MODULO - y) & IDEA_MASK);\n\n    /* !y */\n    return ((IDEA_MODULO - x) & IDEA_MASK);\n}\n\n/* compute 1/a modulo 2^16+1 using Extended euclidean algorithm\n * adapted from fp_invmod */\nstatic WC_INLINE word16 idea_invmod(word16 x)\n{\n    int   u, v, b, d;\n\n    if (x <= 1)\n        return x;\n\n    u = IDEA_MODULO;\n    v = x;\n    d = 1;\n    b = 0;\n\n    do {\n        while (!(u & 1)) {\n            u >>= 1;\n            if (b & 1)\n                b -= IDEA_MODULO;\n            b >>= 1;\n        }\n\n        while (!(v & 1)) {\n            v >>= 1;\n            if (d & 1) {\n                d -= IDEA_MODULO;\n            }\n            d >>= 1;\n        }\n\n        if (u >= v) {\n            u -= v;\n            b -= d;\n        } else {\n            v -= u;\n            d -= b;\n        }\n    } while (u != 0);\n\n    /* d is now the inverse, put positive value if required */\n    while (d < 0)\n        d += IDEA_MODULO;\n\n    /* d must be < IDEA_MODULO */\n    while (d >= (int)IDEA_MODULO)\n        d -= IDEA_MODULO;\n\n    return (word16)(d & IDEA_MASK);\n}\n\n/* generate the 52 16-bits key sub-blocks from the 128 key */\nint wc_IdeaSetKey(Idea *idea, const byte* key, word16 keySz,\n                  const byte *iv, int dir)\n{\n    word16  idx = 0;\n    word32  t;\n    short   i;\n\n    if (idea == NULL || key == NULL || keySz != IDEA_KEY_SIZE ||\n        (dir != IDEA_ENCRYPTION && dir != IDEA_DECRYPTION))\n        return BAD_FUNC_ARG;\n\n    /* initial key schedule for 0 -> 7 */\n    for (i = 0; i < IDEA_ROUNDS; i++) {\n        idea->skey[i]  = (word16)key[idx++] << 8;\n        idea->skey[i] |= (word16)key[idx++];\n    }\n\n    /* shift phase key schedule for 8 -> 51 */\n    for (i = IDEA_ROUNDS; i < IDEA_SK_NUM; i++) {\n        t  = (word32)idea->skey[((i+1) & 7) ? i-7 : i-15] << 9;\n        t |= (word32)idea->skey[((i+2) & 7) < 2 ? i-14 : i-6] >> 7;\n        idea->skey[i] = (word16)(t & IDEA_MASK);\n    }\n\n    /* compute decryption key from encryption key */\n    if (dir == IDEA_DECRYPTION) {\n        word16  enckey[IDEA_SK_NUM];\n\n        /* put encryption key in tmp buffer */\n        XMEMCPY(enckey, idea->skey, sizeof(idea->skey));\n\n        idx = 0;\n\n        idea->skey[6*IDEA_ROUNDS]   = idea_invmod(enckey[idx++]);\n        idea->skey[6*IDEA_ROUNDS+1] = (IDEA_2EXP16 - enckey[idx++]) & IDEA_MASK;\n        idea->skey[6*IDEA_ROUNDS+2] = (IDEA_2EXP16 - enckey[idx++]) & IDEA_MASK;\n        idea->skey[6*IDEA_ROUNDS+3] = idea_invmod(enckey[idx++]);\n\n        for (i = 6*(IDEA_ROUNDS-1); i >= 0; i -= 6) {\n            idea->skey[i+4] = enckey[idx++];\n            idea->skey[i+5] = enckey[idx++];\n\n            idea->skey[i] = idea_invmod(enckey[idx++]);\n            if (i) {\n                idea->skey[i+2] = (IDEA_2EXP16 - enckey[idx++]) & IDEA_MASK;\n                idea->skey[i+1] = (IDEA_2EXP16 - enckey[idx++]) & IDEA_MASK;\n            }\n            else {\n                idea->skey[1] = (IDEA_2EXP16 - enckey[idx++]) & IDEA_MASK;\n                idea->skey[2] = (IDEA_2EXP16 - enckey[idx++]) & IDEA_MASK;\n            }\n\n            idea->skey[i+3] = idea_invmod(enckey[idx++]);\n        }\n\n        /* erase temporary buffer */\n        ForceZero(enckey, sizeof(enckey));\n    }\n\n    /* set the iv */\n    return wc_IdeaSetIV(idea, iv);\n}\n\n/* set the IV in the Idea key structure */\nint wc_IdeaSetIV(Idea *idea, const byte* iv)\n{\n    if (idea == NULL)\n        return BAD_FUNC_ARG;\n\n    if (iv != NULL)\n        XMEMCPY(idea->reg, iv, IDEA_BLOCK_SIZE);\n    else\n        XMEMSET(idea->reg, 0, IDEA_BLOCK_SIZE);\n\n    return 0;\n}\n\n/* encryption/decryption for a block (64 bits)\n */\nint wc_IdeaCipher(Idea *idea, byte* out, const byte* in)\n{\n    word32 t1, t2;\n    word16 i, skey_idx = 0, idx = 0;\n    word16 x[4];\n\n    if (idea == NULL || out == NULL || in == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* put input byte block in word16 */\n    for (i = 0; i < IDEA_BLOCK_SIZE/2; i++) {\n        x[i]  = (word16)in[idx++] << 8;\n        x[i] |= (word16)in[idx++];\n    }\n\n    for (i = 0; i < IDEA_ROUNDS; i++) {\n        x[0] = idea_mult(x[0], idea->skey[skey_idx++]);\n        x[1] = ((word32)x[1] + (word32)idea->skey[skey_idx++]) & IDEA_MASK;\n        x[2] = ((word32)x[2] + (word32)idea->skey[skey_idx++]) & IDEA_MASK;\n        x[3] = idea_mult(x[3], idea->skey[skey_idx++]);\n\n        t2 = x[0] ^ x[2];\n        t2 = idea_mult((word16)t2, idea->skey[skey_idx++]);\n        t1 = (t2 + (x[1] ^ x[3])) & IDEA_MASK;\n        t1 = idea_mult((word16)t1, idea->skey[skey_idx++]);\n        t2 = (t1 + t2) & IDEA_MASK;\n\n        x[0] ^= t1;\n        x[3] ^= t2;\n\n        t2 ^= x[1];\n        x[1] = x[2] ^ (word16)t1;\n        x[2] = (word16)t2;\n    }\n\n    x[0] = idea_mult(x[0], idea->skey[skey_idx++]);\n    out[0] = (x[0] >> 8) & 0xFF;\n    out[1] = x[0] & 0xFF;\n\n    x[2] = ((word32)x[2] + (word32)idea->skey[skey_idx++]) & IDEA_MASK;\n    out[2] = (x[2] >> 8) & 0xFF;\n    out[3] = x[2] & 0xFF;\n\n    x[1] = ((word32)x[1] + (word32)idea->skey[skey_idx++]) & IDEA_MASK;\n    out[4] = (x[1] >> 8) & 0xFF;\n    out[5] = x[1] & 0xFF;\n\n    x[3] = idea_mult(x[3], idea->skey[skey_idx++]);\n    out[6] = (x[3] >> 8) & 0xFF;\n    out[7] = x[3] & 0xFF;\n\n    return 0;\n}\n\nint wc_IdeaCbcEncrypt(Idea *idea, byte* out, const byte* in, word32 len)\n{\n    int  blocks;\n    int  ret;\n\n    if (idea == NULL || out == NULL || in == NULL)\n        return BAD_FUNC_ARG;\n\n    blocks = len / IDEA_BLOCK_SIZE;\n    while (blocks--) {\n        xorbuf((byte*)idea->reg, in, IDEA_BLOCK_SIZE);\n        ret = wc_IdeaCipher(idea, (byte*)idea->reg, (byte*)idea->reg);\n        if (ret != 0) {\n            return ret;\n        }\n\n        XMEMCPY(out, idea->reg, IDEA_BLOCK_SIZE);\n\n        out += IDEA_BLOCK_SIZE;\n        in  += IDEA_BLOCK_SIZE;\n    }\n\n    return 0;\n}\n\nint wc_IdeaCbcDecrypt(Idea *idea, byte* out, const byte* in, word32 len)\n{\n    int  blocks;\n    int  ret;\n\n    if (idea == NULL || out == NULL || in == NULL)\n        return BAD_FUNC_ARG;\n\n    blocks = len / IDEA_BLOCK_SIZE;\n    while (blocks--) {\n        XMEMCPY((byte*)idea->tmp, in, IDEA_BLOCK_SIZE);\n        ret = wc_IdeaCipher(idea, out, (byte*)idea->tmp);\n        if (ret != 0) {\n            return ret;\n        }\n\n        xorbuf(out, (byte*)idea->reg, IDEA_BLOCK_SIZE);\n        XMEMCPY(idea->reg, idea->tmp, IDEA_BLOCK_SIZE);\n\n        out += IDEA_BLOCK_SIZE;\n        in  += IDEA_BLOCK_SIZE;\n    }\n\n    return 0;\n}\n\n#endif /* HAVE_IDEA */\n"
  },
  {
    "path": "src/wolfcrypt/src/integer.c",
    "content": "/* integer.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n/*\n * Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca,\n * http://math.libtomcrypt.com\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n/* in case user set USE_FAST_MATH there */\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#ifndef NO_BIG_INT\n\n#ifndef USE_FAST_MATH\n\n#ifndef WOLFSSL_SP_MATH\n\n#include <wolfssl/wolfcrypt/integer.h>\n\n#if defined(FREESCALE_LTC_TFM)\n    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>\n#endif\n#ifdef WOLFSSL_DEBUG_MATH\n    #include <stdio.h>\n#endif\n\n#ifndef NO_WOLFSSL_SMALL_STACK\n    #ifndef WOLFSSL_SMALL_STACK\n        #define WOLFSSL_SMALL_STACK\n    #endif\n#endif\n\n#ifdef SHOW_GEN\n    #ifndef NO_STDIO_FILESYSTEM\n        #include <stdio.h>\n    #endif\n#endif\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\nWOLFSSL_LOCAL int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n#endif\n\n/* reverse an array, used for radix code */\nstatic void\nbn_reverse (unsigned char *s, int len)\n{\n    int     ix, iy;\n    unsigned char t;\n\n    ix = 0;\n    iy = len - 1;\n    while (ix < iy) {\n        t     = s[ix];\n        s[ix] = s[iy];\n        s[iy] = t;\n        ++ix;\n        --iy;\n    }\n}\n\n/* math settings check */\nword32 CheckRunTimeSettings(void)\n{\n    return CTC_SETTINGS;\n}\n\n\n/* handle up to 6 inits */\nint mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,\n                  mp_int* f)\n{\n    int res = MP_OKAY;\n\n    if (a) XMEMSET(a, 0, sizeof(mp_int));\n    if (b) XMEMSET(b, 0, sizeof(mp_int));\n    if (c) XMEMSET(c, 0, sizeof(mp_int));\n    if (d) XMEMSET(d, 0, sizeof(mp_int));\n    if (e) XMEMSET(e, 0, sizeof(mp_int));\n    if (f) XMEMSET(f, 0, sizeof(mp_int));\n\n    if (a && ((res = mp_init(a)) != MP_OKAY))\n        return res;\n\n    if (b && ((res = mp_init(b)) != MP_OKAY)) {\n        mp_clear(a);\n        return res;\n    }\n\n    if (c && ((res = mp_init(c)) != MP_OKAY)) {\n        mp_clear(a); mp_clear(b);\n        return res;\n    }\n\n    if (d && ((res = mp_init(d)) != MP_OKAY)) {\n        mp_clear(a); mp_clear(b); mp_clear(c);\n        return res;\n    }\n\n    if (e && ((res = mp_init(e)) != MP_OKAY)) {\n        mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d);\n        return res;\n    }\n\n    if (f && ((res = mp_init(f)) != MP_OKAY)) {\n        mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d); mp_clear(e);\n        return res;\n    }\n\n    return res;\n}\n\n\n/* init a new mp_int */\nint mp_init (mp_int * a)\n{\n  /* Safeguard against passing in a null pointer */\n  if (a == NULL)\n    return MP_VAL;\n\n  /* defer allocation until mp_grow */\n  a->dp = NULL;\n\n  /* set the used to zero, allocated digits to the default precision\n   * and sign to positive */\n  a->used  = 0;\n  a->alloc = 0;\n  a->sign  = MP_ZPOS;\n#ifdef HAVE_WOLF_BIGINT\n  wc_bigint_init(&a->raw);\n#endif\n\n  return MP_OKAY;\n}\n\n\n/* clear one (frees)  */\nvoid mp_clear (mp_int * a)\n{\n  int i;\n\n  if (a == NULL)\n      return;\n\n  /* only do anything if a hasn't been freed previously */\n  if (a->dp != NULL) {\n    /* first zero the digits */\n    for (i = 0; i < a->used; i++) {\n        a->dp[i] = 0;\n    }\n\n    /* free ram */\n    mp_free(a);\n\n    /* reset members to make debugging easier */\n    a->alloc = a->used = 0;\n    a->sign  = MP_ZPOS;\n  }\n}\n\nvoid mp_free (mp_int * a)\n{\n  /* only do anything if a hasn't been freed previously */\n  if (a->dp != NULL) {\n    /* free ram */\n    XFREE(a->dp, 0, DYNAMIC_TYPE_BIGINT);\n    a->dp    = NULL;\n  }\n\n#ifdef HAVE_WOLF_BIGINT\n  wc_bigint_free(&a->raw);\n#endif\n}\n\nvoid mp_forcezero(mp_int * a)\n{\n    if (a == NULL)\n        return;\n\n    /* only do anything if a hasn't been freed previously */\n    if (a->dp != NULL) {\n      /* force zero the used digits */\n      ForceZero(a->dp, a->used * sizeof(mp_digit));\n#ifdef HAVE_WOLF_BIGINT\n      wc_bigint_zero(&a->raw);\n#endif\n      /* free ram */\n      mp_free(a);\n\n      /* reset members to make debugging easier */\n      a->alloc = a->used = 0;\n      a->sign  = MP_ZPOS;\n    }\n\n    a->sign = MP_ZPOS;\n    a->used = 0;\n}\n\n\n/* get the size for an unsigned equivalent */\nint mp_unsigned_bin_size (mp_int * a)\n{\n  int     size = mp_count_bits (a);\n  return (size / 8 + ((size & 7) != 0 ? 1 : 0));\n}\n\n\n/* returns the number of bits in an int */\nint mp_count_bits (mp_int * a)\n{\n  int     r;\n  mp_digit q;\n\n  /* shortcut */\n  if (a->used == 0) {\n    return 0;\n  }\n\n  /* get number of digits and add that */\n  r = (a->used - 1) * DIGIT_BIT;\n\n  /* take the last digit and count the bits in it */\n  q = a->dp[a->used - 1];\n  while (q > ((mp_digit) 0)) {\n    ++r;\n    q >>= ((mp_digit) 1);\n  }\n  return r;\n}\n\n\nint mp_leading_bit (mp_int * a)\n{\n    int bit = 0;\n    mp_int t;\n\n    if (mp_init_copy(&t, a) != MP_OKAY)\n        return 0;\n\n    while (mp_iszero(&t) == MP_NO) {\n#ifndef MP_8BIT\n        bit = (t.dp[0] & 0x80) != 0;\n#else\n        bit = (t.dp[0] | ((t.dp[1] & 0x01) << 7)) & 0x80 != 0;\n#endif\n        if (mp_div_2d (&t, 8, &t, NULL) != MP_OKAY)\n            break;\n    }\n    mp_clear(&t);\n    return bit;\n}\n\nint mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b)\n{\n  int res = 0;\n  while (mp_iszero(t) == MP_NO) {\n#ifndef MP_8BIT\n      b[x++] = (unsigned char) (t->dp[0] & 255);\n#else\n      b[x++] = (unsigned char) (t->dp[0] | ((t->dp[1] & 0x01) << 7));\n#endif\n    if ((res = mp_div_2d (t, 8, t, NULL)) != MP_OKAY) {\n      return res;\n    }\n    res = x;\n  }\n  return res;\n}\n\n/* store in unsigned [big endian] format */\nint mp_to_unsigned_bin (mp_int * a, unsigned char *b)\n{\n  int     x, res;\n  mp_int  t;\n\n  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {\n    return res;\n  }\n\n  x = mp_to_unsigned_bin_at_pos(0, &t, b);\n  if (x < 0) {\n    mp_clear(&t);\n    return x;\n  }\n\n  bn_reverse (b, x);\n  mp_clear (&t);\n  return res;\n}\n\nint mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c)\n{\n    int i, len;\n\n    len = mp_unsigned_bin_size(a);\n\n    /* pad front w/ zeros to match length */\n    for (i = 0; i < c - len; i++)\n        b[i] = 0x00;\n    return mp_to_unsigned_bin(a, b + i);\n}\n\n/* creates \"a\" then copies b into it */\nint mp_init_copy (mp_int * a, mp_int * b)\n{\n  int     res;\n\n  if ((res = mp_init_size (a, b->used)) != MP_OKAY) {\n    return res;\n  }\n\n  if((res = mp_copy (b, a)) != MP_OKAY) {\n    mp_clear(a);\n  }\n\n  return res;\n}\n\n\n/* copy, b = a */\nint mp_copy (mp_int * a, mp_int * b)\n{\n  int     res, n;\n\n  /* Safeguard against passing in a null pointer */\n  if (a == NULL || b == NULL)\n    return MP_VAL;\n\n  /* if dst == src do nothing */\n  if (a == b) {\n    return MP_OKAY;\n  }\n\n  /* grow dest */\n  if (b->alloc < a->used || b->alloc == 0) {\n     if ((res = mp_grow (b, a->used)) != MP_OKAY) {\n        return res;\n     }\n  }\n\n  /* zero b and copy the parameters over */\n  {\n    mp_digit *tmpa, *tmpb;\n\n    /* pointer aliases */\n\n    /* source */\n    tmpa = a->dp;\n\n    /* destination */\n    tmpb = b->dp;\n\n    /* copy all the digits */\n    for (n = 0; n < a->used; n++) {\n      *tmpb++ = *tmpa++;\n    }\n\n    /* clear high digits */\n    for (; n < b->used && b->dp; n++) {\n      *tmpb++ = 0;\n    }\n  }\n\n  /* copy used count and sign */\n  b->used = a->used;\n  b->sign = a->sign;\n  return MP_OKAY;\n}\n\n\n/* grow as required */\nint mp_grow (mp_int * a, int size)\n{\n  int     i;\n  mp_digit *tmp;\n\n  /* if the alloc size is smaller alloc more ram */\n  if (a->alloc < size || size == 0) {\n    /* ensure there are always at least MP_PREC digits extra on top */\n    size += (MP_PREC * 2) - (size % MP_PREC);\n\n    /* reallocate the array a->dp\n     *\n     * We store the return in a temporary variable\n     * in case the operation failed we don't want\n     * to overwrite the dp member of a.\n     */\n    tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size, NULL,\n                                                           DYNAMIC_TYPE_BIGINT);\n    if (tmp == NULL) {\n      /* reallocation failed but \"a\" is still valid [can be freed] */\n      return MP_MEM;\n    }\n\n    /* reallocation succeeded so set a->dp */\n    a->dp = tmp;\n\n    /* zero excess digits */\n    i        = a->alloc;\n    a->alloc = size;\n    for (; i < a->alloc; i++) {\n      a->dp[i] = 0;\n    }\n  }\n  return MP_OKAY;\n}\n\n\n/* shift right by a certain bit count (store quotient in c, optional\n   remainder in d) */\nint mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)\n{\n  int     D, res;\n  mp_int  t;\n\n\n  /* if the shift count is <= 0 then we do no work */\n  if (b <= 0) {\n    res = mp_copy (a, c);\n    if (d != NULL) {\n      mp_zero (d);\n    }\n    return res;\n  }\n\n  if ((res = mp_init (&t)) != MP_OKAY) {\n    return res;\n  }\n\n  /* get the remainder */\n  if (d != NULL) {\n    if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {\n      mp_clear (&t);\n      return res;\n    }\n  }\n\n  /* copy */\n  if ((res = mp_copy (a, c)) != MP_OKAY) {\n    mp_clear (&t);\n    return res;\n  }\n\n  /* shift by as many digits in the bit count */\n  if (b >= (int)DIGIT_BIT) {\n    mp_rshd (c, b / DIGIT_BIT);\n  }\n\n  /* shift any bit count < DIGIT_BIT */\n  D = (b % DIGIT_BIT);\n  if (D != 0) {\n    mp_rshb(c, D);\n  }\n  mp_clamp (c);\n  if (d != NULL) {\n    mp_exch (&t, d);\n  }\n  mp_clear (&t);\n  return MP_OKAY;\n}\n\n\n/* set to zero */\nvoid mp_zero (mp_int * a)\n{\n  int       n;\n  mp_digit *tmp;\n\n  if (a == NULL)\n      return;\n\n  a->sign = MP_ZPOS;\n  a->used = 0;\n\n  tmp = a->dp;\n  for (n = 0; n < a->alloc; n++) {\n     *tmp++ = 0;\n  }\n}\n\n\n/* trim unused digits\n *\n * This is used to ensure that leading zero digits are\n * trimmed and the leading \"used\" digit will be non-zero\n * Typically very fast.  Also fixes the sign if there\n * are no more leading digits\n */\nvoid mp_clamp (mp_int * a)\n{\n  /* decrease used while the most significant digit is\n   * zero.\n   */\n  while (a->used > 0 && a->dp[a->used - 1] == 0) {\n    --(a->used);\n  }\n\n  /* reset the sign flag if used == 0 */\n  if (a->used == 0) {\n    a->sign = MP_ZPOS;\n  }\n}\n\n\n/* swap the elements of two integers, for cases where you can't simply swap the\n * mp_int pointers around\n */\nvoid mp_exch (mp_int * a, mp_int * b)\n{\n  mp_int  t;\n\n  t  = *a;\n  *a = *b;\n  *b = t;\n}\n\n\n/* shift right a certain number of bits */\nvoid mp_rshb (mp_int *c, int x)\n{\n    mp_digit *tmpc, mask, shift;\n    mp_digit r, rr;\n    mp_digit D = x;\n\n    if (mp_iszero(c)) return;\n\n    /* mask */\n    mask = (((mp_digit)1) << D) - 1;\n\n    /* shift for lsb */\n    shift = DIGIT_BIT - D;\n\n    /* alias */\n    tmpc = c->dp + (c->used - 1);\n\n    /* carry */\n    r = 0;\n    for (x = c->used - 1; x >= 0; x--) {\n      /* get the lower  bits of this word in a temp */\n      rr = *tmpc & mask;\n\n      /* shift the current word and mix in the carry bits from previous word */\n      *tmpc = (*tmpc >> D) | (r << shift);\n      --tmpc;\n\n      /* set the carry to the carry bits of the current word found above */\n      r = rr;\n    }\n    mp_clamp(c);\n}\n\n\n/* shift right a certain amount of digits */\nvoid mp_rshd (mp_int * a, int b)\n{\n  int     x;\n\n  /* if b <= 0 then ignore it */\n  if (b <= 0) {\n    return;\n  }\n\n  /* if b > used then simply zero it and return */\n  if (a->used <= b) {\n    mp_zero (a);\n    return;\n  }\n\n  {\n    mp_digit *bottom, *top;\n\n    /* shift the digits down */\n\n    /* bottom */\n    bottom = a->dp;\n\n    /* top [offset into digits] */\n    top = a->dp + b;\n\n    /* this is implemented as a sliding window where\n     * the window is b-digits long and digits from\n     * the top of the window are copied to the bottom\n     *\n     * e.g.\n\n     b-2 | b-1 | b0 | b1 | b2 | ... | bb |   ---->\n                 /\\                   |      ---->\n                  \\-------------------/      ---->\n     */\n    for (x = 0; x < (a->used - b); x++) {\n      *bottom++ = *top++;\n    }\n\n    /* zero the top digits */\n    for (; x < a->used; x++) {\n      *bottom++ = 0;\n    }\n  }\n\n  /* remove excess digits */\n  a->used -= b;\n}\n\n\n/* calc a value mod 2**b */\nint mp_mod_2d (mp_int * a, int b, mp_int * c)\n{\n  int     x, res;\n\n  /* if b is <= 0 then zero the int */\n  if (b <= 0) {\n    mp_zero (c);\n    return MP_OKAY;\n  }\n\n  /* if the modulus is larger than the value than return */\n  if (b >= (int) (a->used * DIGIT_BIT)) {\n    res = mp_copy (a, c);\n    return res;\n  }\n\n  /* copy */\n  if ((res = mp_copy (a, c)) != MP_OKAY) {\n    return res;\n  }\n\n  /* zero digits above the last digit of the modulus */\n  for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {\n    c->dp[x] = 0;\n  }\n  /* clear the digit that is not completely outside/inside the modulus */\n  c->dp[b / DIGIT_BIT] &= (mp_digit) ((((mp_digit) 1) <<\n              (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));\n  mp_clamp (c);\n  return MP_OKAY;\n}\n\n\n/* reads a unsigned char array, assumes the msb is stored first [big endian] */\nint mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)\n{\n  int     res;\n\n  /* make sure there are at least two digits */\n  if (a->alloc < 2) {\n     if ((res = mp_grow(a, 2)) != MP_OKAY) {\n        return res;\n     }\n  }\n\n  /* zero the int */\n  mp_zero (a);\n\n  /* read the bytes in */\n  while (c-- > 0) {\n    if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {\n      return res;\n    }\n\n#ifndef MP_8BIT\n      a->dp[0] |= *b++;\n      a->used += 1;\n#else\n      a->dp[0] = (*b & MP_MASK);\n      a->dp[1] |= ((*b++ >> 7U) & 1);\n      a->used += 2;\n#endif\n  }\n  mp_clamp (a);\n  return MP_OKAY;\n}\n\n\n/* shift left by a certain bit count */\nint mp_mul_2d (mp_int * a, int b, mp_int * c)\n{\n  mp_digit d;\n  int      res;\n\n  /* copy */\n  if (a != c) {\n     if ((res = mp_copy (a, c)) != MP_OKAY) {\n       return res;\n     }\n  }\n\n  if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {\n     if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {\n       return res;\n     }\n  }\n\n  /* shift by as many digits in the bit count */\n  if (b >= (int)DIGIT_BIT) {\n    if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {\n      return res;\n    }\n  }\n\n  /* shift any bit count < DIGIT_BIT */\n  d = (mp_digit) (b % DIGIT_BIT);\n  if (d != 0) {\n    mp_digit *tmpc, shift, mask, r, rr;\n    int x;\n\n    /* bitmask for carries */\n    mask = (((mp_digit)1) << d) - 1;\n\n    /* shift for msbs */\n    shift = DIGIT_BIT - d;\n\n    /* alias */\n    tmpc = c->dp;\n\n    /* carry */\n    r    = 0;\n    for (x = 0; x < c->used; x++) {\n      /* get the higher bits of the current word */\n      rr = (*tmpc >> shift) & mask;\n\n      /* shift the current word and OR in the carry */\n      *tmpc = (mp_digit)(((*tmpc << d) | r) & MP_MASK);\n      ++tmpc;\n\n      /* set the carry to the carry bits of the current word */\n      r = rr;\n    }\n\n    /* set final carry */\n    if (r != 0) {\n       c->dp[(c->used)++] = r;\n    }\n  }\n  mp_clamp (c);\n  return MP_OKAY;\n}\n\n\n/* shift left a certain amount of digits */\nint mp_lshd (mp_int * a, int b)\n{\n  int     x, res;\n\n  /* if its less than zero return */\n  if (b <= 0) {\n    return MP_OKAY;\n  }\n\n  /* grow to fit the new digits */\n  if (a->alloc < a->used + b) {\n     if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {\n       return res;\n     }\n  }\n\n  {\n    mp_digit *top, *bottom;\n\n    /* increment the used by the shift amount then copy upwards */\n    a->used += b;\n\n    /* top */\n    top = a->dp + a->used - 1;\n\n    /* base */\n    bottom = a->dp + a->used - 1 - b;\n\n    /* much like mp_rshd this is implemented using a sliding window\n     * except the window goes the other way around.  Copying from\n     * the bottom to the top.  see bn_mp_rshd.c for more info.\n     */\n    for (x = a->used - 1; x >= b; x--) {\n      *top-- = *bottom--;\n    }\n\n    /* zero the lower digits */\n    top = a->dp;\n    for (x = 0; x < b; x++) {\n      *top++ = 0;\n    }\n  }\n  return MP_OKAY;\n}\n\n\n/* this is a shell function that calls either the normal or Montgomery\n * exptmod functions.  Originally the call to the montgomery code was\n * embedded in the normal function but that wasted a lot of stack space\n * for nothing (since 99% of the time the Montgomery code would be called)\n */\n#if defined(FREESCALE_LTC_TFM)\nint wolfcrypt_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)\n#else\nint mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)\n#endif\n{\n  int dr;\n\n  /* modulus P must be positive */\n  if (mp_iszero(P) || P->sign == MP_NEG) {\n     return MP_VAL;\n  }\n  if (mp_isone(P)) {\n     mp_set(Y, 0);\n     return MP_OKAY;\n  }\n  if (mp_iszero(X)) {\n     mp_set(Y, 1);\n     return MP_OKAY;\n  }\n  if (mp_iszero(G)) {\n     mp_set(Y, 0);\n     return MP_OKAY;\n  }\n\n  /* if exponent X is negative we have to recurse */\n  if (X->sign == MP_NEG) {\n#ifdef BN_MP_INVMOD_C\n     mp_int tmpG, tmpX;\n     int err;\n\n     /* first compute 1/G mod P */\n     if ((err = mp_init(&tmpG)) != MP_OKAY) {\n        return err;\n     }\n     if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {\n        mp_clear(&tmpG);\n        return err;\n     }\n\n     /* now get |X| */\n     if ((err = mp_init(&tmpX)) != MP_OKAY) {\n        mp_clear(&tmpG);\n        return err;\n     }\n     if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {\n        mp_clear(&tmpG);\n        mp_clear(&tmpX);\n        return err;\n     }\n\n     /* and now compute (1/G)**|X| instead of G**X [X < 0] */\n     err = mp_exptmod(&tmpG, &tmpX, P, Y);\n     mp_clear(&tmpG);\n     mp_clear(&tmpX);\n     return err;\n#else\n     /* no invmod */\n     return MP_VAL;\n#endif\n  }\n\n#ifdef BN_MP_EXPTMOD_BASE_2\n  if (G->used == 1 && G->dp[0] == 2) {\n    return mp_exptmod_base_2(X, P, Y);\n  }\n#endif\n\n/* modified diminished radix reduction */\n#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && \\\n  defined(BN_S_MP_EXPTMOD_C)\n  if (mp_reduce_is_2k_l(P) == MP_YES) {\n     return s_mp_exptmod(G, X, P, Y, 1);\n  }\n#endif\n\n#ifdef BN_MP_DR_IS_MODULUS_C\n  /* is it a DR modulus? */\n  dr = mp_dr_is_modulus(P);\n#else\n  /* default to no */\n  dr = 0;\n#endif\n\n#ifdef BN_MP_REDUCE_IS_2K_C\n  /* if not, is it a unrestricted DR modulus? */\n  if (dr == 0) {\n     dr = mp_reduce_is_2k(P) << 1;\n  }\n#endif\n\n  /* if the modulus is odd or dr != 0 use the montgomery method */\n#ifdef BN_MP_EXPTMOD_FAST_C\n  if (mp_isodd (P) == MP_YES || dr !=  0) {\n    return mp_exptmod_fast (G, X, P, Y, dr);\n  } else {\n#endif\n#ifdef BN_S_MP_EXPTMOD_C\n    /* otherwise use the generic Barrett reduction technique */\n    return s_mp_exptmod (G, X, P, Y, 0);\n#else\n    /* no exptmod for evens */\n    return MP_VAL;\n#endif\n#ifdef BN_MP_EXPTMOD_FAST_C\n  }\n#endif\n}\n\nint mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P, mp_int * Y)\n{\n    (void)digits;\n    return mp_exptmod(G, X, P, Y);\n}\n\n/* b = |a|\n *\n * Simple function copies the input and fixes the sign to positive\n */\nint mp_abs (mp_int * a, mp_int * b)\n{\n  int     res;\n\n  /* copy a to b */\n  if (a != b) {\n     if ((res = mp_copy (a, b)) != MP_OKAY) {\n       return res;\n     }\n  }\n\n  /* force the sign of b to positive */\n  b->sign = MP_ZPOS;\n\n  return MP_OKAY;\n}\n\n\n/* hac 14.61, pp608 */\n#if defined(FREESCALE_LTC_TFM)\nint wolfcrypt_mp_invmod(mp_int * a, mp_int * b, mp_int * c)\n#else\nint mp_invmod (mp_int * a, mp_int * b, mp_int * c)\n#endif\n{\n  /* b cannot be negative or zero, and can not divide by 0 (1/a mod b) */\n  if (b->sign == MP_NEG || mp_iszero(b) == MP_YES || mp_iszero(a) == MP_YES) {\n    return MP_VAL;\n  }\n\n#ifdef BN_FAST_MP_INVMOD_C\n  /* if the modulus is odd we can use a faster routine instead */\n  if ((mp_isodd(b) == MP_YES) && (mp_cmp_d(b, 1) != MP_EQ)) {\n    return fast_mp_invmod (a, b, c);\n  }\n#endif\n\n#ifdef BN_MP_INVMOD_SLOW_C\n  return mp_invmod_slow(a, b, c);\n#else\n  return MP_VAL;\n#endif\n}\n\n\n/* computes the modular inverse via binary extended euclidean algorithm,\n * that is c = 1/a mod b\n *\n * Based on slow invmod except this is optimized for the case where b is\n * odd as per HAC Note 14.64 on pp. 610\n */\nint fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)\n{\n  mp_int  x, y, u, v, B, D;\n  int     res, neg, loop_check = 0;\n\n  /* 2. [modified] b must be odd   */\n  if (mp_iseven (b) == MP_YES) {\n    return MP_VAL;\n  }\n\n  /* init all our temps */\n  if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D)) != MP_OKAY) {\n     return res;\n  }\n\n  /* x == modulus, y == value to invert */\n  if ((res = mp_copy (b, &x)) != MP_OKAY) {\n    goto LBL_ERR;\n  }\n\n  /* we need y = |a| */\n  if ((res = mp_mod (a, b, &y)) != MP_OKAY) {\n    goto LBL_ERR;\n  }\n\n  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */\n  if ((res = mp_copy (&x, &u)) != MP_OKAY) {\n    goto LBL_ERR;\n  }\n  if ((res = mp_copy (&y, &v)) != MP_OKAY) {\n    goto LBL_ERR;\n  }\n  if ((res = mp_set (&D, 1)) != MP_OKAY) {\n    goto LBL_ERR;\n  }\n\ntop:\n  /* 4.  while u is even do */\n  while (mp_iseven (&u) == MP_YES) {\n    /* 4.1 u = u/2 */\n    if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n    /* 4.2 if B is odd then */\n    if (mp_isodd (&B) == MP_YES) {\n      if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {\n        goto LBL_ERR;\n      }\n    }\n    /* B = B/2 */\n    if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n  }\n\n  /* 5.  while v is even do */\n  while (mp_iseven (&v) == MP_YES) {\n    /* 5.1 v = v/2 */\n    if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n    /* 5.2 if D is odd then */\n    if (mp_isodd (&D) == MP_YES) {\n      /* D = (D-x)/2 */\n      if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {\n        goto LBL_ERR;\n      }\n    }\n    /* D = D/2 */\n    if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n  }\n\n  /* 6.  if u >= v then */\n  if (mp_cmp (&u, &v) != MP_LT) {\n    /* u = u - v, B = B - D */\n    if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n\n    if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n  } else {\n    /* v - v - u, D = D - B */\n    if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n\n    if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n  }\n\n  /* if not zero goto step 4 */\n  if (mp_iszero (&u) == MP_NO) {\n    if (++loop_check > MAX_INVMOD_SZ) {\n        res = MP_VAL;\n        goto LBL_ERR;\n    }\n    goto top;\n  }\n\n  /* now a = C, b = D, gcd == g*v */\n\n  /* if v != 1 then there is no inverse */\n  if (mp_cmp_d (&v, 1) != MP_EQ) {\n    res = MP_VAL;\n    goto LBL_ERR;\n  }\n\n  /* b is now the inverse */\n  neg = a->sign;\n  while (D.sign == MP_NEG) {\n    if ((res = mp_add (&D, b, &D)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n  }\n  /* too big */\n  while (mp_cmp_mag(&D, b) != MP_LT) {\n      if ((res = mp_sub(&D, b, &D)) != MP_OKAY) {\n         goto LBL_ERR;\n      }\n  }\n  mp_exch (&D, c);\n  c->sign = neg;\n  res = MP_OKAY;\n\nLBL_ERR:mp_clear(&x);\n        mp_clear(&y);\n        mp_clear(&u);\n        mp_clear(&v);\n        mp_clear(&B);\n        mp_clear(&D);\n  return res;\n}\n\n\n/* hac 14.61, pp608 */\nint mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)\n{\n  mp_int  x, y, u, v, A, B, C, D;\n  int     res;\n\n  /* b cannot be negative */\n  if (b->sign == MP_NEG || mp_iszero(b) == MP_YES) {\n    return MP_VAL;\n  }\n\n  /* init temps */\n  if ((res = mp_init_multi(&x, &y, &u, &v,\n                           &A, &B)) != MP_OKAY) {\n    return res;\n  }\n\n  /* init rest of tmps temps */\n  if ((res = mp_init_multi(&C, &D, 0, 0, 0, 0)) != MP_OKAY) {\n    mp_clear(&x);\n    mp_clear(&y);\n    mp_clear(&u);\n    mp_clear(&v);\n    mp_clear(&A);\n    mp_clear(&B);\n    return res;\n  }\n\n  /* x = a, y = b */\n  if ((res = mp_mod(a, b, &x)) != MP_OKAY) {\n    goto LBL_ERR;\n  }\n  if (mp_isone(&x)) {\n    mp_set(c, 1);\n    res = MP_OKAY;\n    goto LBL_ERR;\n  }\n  if ((res = mp_copy (b, &y)) != MP_OKAY) {\n    goto LBL_ERR;\n  }\n\n  /* 2. [modified] if x,y are both even then return an error! */\n  if (mp_iseven (&x) == MP_YES && mp_iseven (&y) == MP_YES) {\n    res = MP_VAL;\n    goto LBL_ERR;\n  }\n\n  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */\n  if ((res = mp_copy (&x, &u)) != MP_OKAY) {\n    goto LBL_ERR;\n  }\n  if ((res = mp_copy (&y, &v)) != MP_OKAY) {\n    goto LBL_ERR;\n  }\n  if ((res = mp_set (&A, 1)) != MP_OKAY) {\n    goto LBL_ERR;\n  }\n  if ((res = mp_set (&D, 1)) != MP_OKAY) {\n    goto LBL_ERR;\n  }\n\ntop:\n  /* 4.  while u is even do */\n  while (mp_iseven (&u) == MP_YES) {\n    /* 4.1 u = u/2 */\n    if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n    /* 4.2 if A or B is odd then */\n    if (mp_isodd (&A) == MP_YES || mp_isodd (&B) == MP_YES) {\n      /* A = (A+y)/2, B = (B-x)/2 */\n      if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {\n        goto LBL_ERR;\n      }\n      if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {\n        goto LBL_ERR;\n      }\n    }\n    /* A = A/2, B = B/2 */\n    if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n    if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n  }\n\n  /* 5.  while v is even do */\n  while (mp_iseven (&v) == MP_YES) {\n    /* 5.1 v = v/2 */\n    if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n    /* 5.2 if C or D is odd then */\n    if (mp_isodd (&C) == MP_YES || mp_isodd (&D) == MP_YES) {\n      /* C = (C+y)/2, D = (D-x)/2 */\n      if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {\n        goto LBL_ERR;\n      }\n      if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {\n        goto LBL_ERR;\n      }\n    }\n    /* C = C/2, D = D/2 */\n    if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n    if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n  }\n\n  /* 6.  if u >= v then */\n  if (mp_cmp (&u, &v) != MP_LT) {\n    /* u = u - v, A = A - C, B = B - D */\n    if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n\n    if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n\n    if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n  } else {\n    /* v - v - u, C = C - A, D = D - B */\n    if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n\n    if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n\n    if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {\n      goto LBL_ERR;\n    }\n  }\n\n  /* if not zero goto step 4 */\n  if (mp_iszero (&u) == MP_NO)\n    goto top;\n\n  /* now a = C, b = D, gcd == g*v */\n\n  /* if v != 1 then there is no inverse */\n  if (mp_cmp_d (&v, 1) != MP_EQ) {\n    res = MP_VAL;\n    goto LBL_ERR;\n  }\n\n  /* if its too low */\n  while (mp_cmp_d(&C, 0) == MP_LT) {\n      if ((res = mp_add(&C, b, &C)) != MP_OKAY) {\n         goto LBL_ERR;\n      }\n  }\n\n  /* too big */\n  while (mp_cmp_mag(&C, b) != MP_LT) {\n      if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {\n         goto LBL_ERR;\n      }\n  }\n\n  /* C is now the inverse */\n  mp_exch (&C, c);\n  res = MP_OKAY;\nLBL_ERR:mp_clear(&x);\n        mp_clear(&y);\n        mp_clear(&u);\n        mp_clear(&v);\n        mp_clear(&A);\n        mp_clear(&B);\n        mp_clear(&C);\n        mp_clear(&D);\n  return res;\n}\n\n\n/* compare magnitude of two ints (unsigned) */\nint mp_cmp_mag (mp_int * a, mp_int * b)\n{\n  int     n;\n  mp_digit *tmpa, *tmpb;\n\n  /* compare based on # of non-zero digits */\n  if (a->used > b->used) {\n    return MP_GT;\n  }\n\n  if (a->used < b->used) {\n    return MP_LT;\n  }\n\n  /* alias for a */\n  tmpa = a->dp + (a->used - 1);\n\n  /* alias for b */\n  tmpb = b->dp + (a->used - 1);\n\n  /* compare based on digits  */\n  for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {\n    if (*tmpa > *tmpb) {\n      return MP_GT;\n    }\n\n    if (*tmpa < *tmpb) {\n      return MP_LT;\n    }\n  }\n  return MP_EQ;\n}\n\n\n/* compare two ints (signed)*/\nint mp_cmp (mp_int * a, mp_int * b)\n{\n  /* compare based on sign */\n  if (a->sign != b->sign) {\n     if (a->sign == MP_NEG) {\n        return MP_LT;\n     } else {\n        return MP_GT;\n     }\n  }\n\n  /* compare digits */\n  if (a->sign == MP_NEG) {\n     /* if negative compare opposite direction */\n     return mp_cmp_mag(b, a);\n  } else {\n     return mp_cmp_mag(a, b);\n  }\n}\n\n\n/* compare a digit */\nint mp_cmp_d(mp_int * a, mp_digit b)\n{\n  /* special case for zero*/\n  if (a->used == 0 && b == 0)\n    return MP_EQ;\n\n  /* compare based on sign */\n  if ((b && a->used == 0) || a->sign == MP_NEG) {\n    return MP_LT;\n  }\n\n  /* compare based on magnitude */\n  if (a->used > 1) {\n    return MP_GT;\n  }\n\n  /* compare the only digit of a to b */\n  if (a->dp[0] > b) {\n    return MP_GT;\n  } else if (a->dp[0] < b) {\n    return MP_LT;\n  } else {\n    return MP_EQ;\n  }\n}\n\n\n/* set to a digit */\nint mp_set (mp_int * a, mp_digit b)\n{\n  int res;\n  mp_zero (a);\n  res = mp_grow (a, 1);\n  if (res == MP_OKAY) {\n    a->dp[0] = (mp_digit)(b & MP_MASK);\n    a->used  = (a->dp[0] != 0) ? 1 : 0;\n  }\n  return res;\n}\n\n/* chek if a bit is set */\nint mp_is_bit_set (mp_int *a, mp_digit b)\n{\n    if ((mp_digit)a->used < b/DIGIT_BIT)\n        return 0;\n\n    return (int)((a->dp[b/DIGIT_BIT] >> b%DIGIT_BIT) & (mp_digit)1);\n}\n\n/* c = a mod b, 0 <= c < b */\n#if defined(FREESCALE_LTC_TFM)\nint wolfcrypt_mp_mod(mp_int * a, mp_int * b, mp_int * c)\n#else\nint mp_mod (mp_int * a, mp_int * b, mp_int * c)\n#endif\n{\n  mp_int  t;\n  int     res;\n\n  if ((res = mp_init_size (&t, b->used)) != MP_OKAY) {\n    return res;\n  }\n\n  if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {\n    mp_clear (&t);\n    return res;\n  }\n\n  if ((mp_iszero(&t) != MP_NO) || (t.sign == b->sign)) {\n    res = MP_OKAY;\n    mp_exch (&t, c);\n  } else {\n    res = mp_add (b, &t, c);\n  }\n\n  mp_clear (&t);\n  return res;\n}\n\n\n/* slower bit-bang division... also smaller */\nint mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)\n{\n   mp_int ta, tb, tq, q;\n   int    res, n, n2;\n\n  /* is divisor zero ? */\n  if (mp_iszero (b) == MP_YES) {\n    return MP_VAL;\n  }\n\n  /* if a < b then q=0, r = a */\n  if (mp_cmp_mag (a, b) == MP_LT) {\n    if (d != NULL) {\n      res = mp_copy (a, d);\n    } else {\n      res = MP_OKAY;\n    }\n    if (c != NULL) {\n      mp_zero (c);\n    }\n    return res;\n  }\n\n  /* init our temps */\n  if ((res = mp_init_multi(&ta, &tb, &tq, &q, 0, 0)) != MP_OKAY) {\n     return res;\n  }\n\n  if ((res = mp_set(&tq, 1)) != MP_OKAY) {\n     return res;\n  }\n  n = mp_count_bits(a) - mp_count_bits(b);\n  if (((res = mp_abs(a, &ta)) != MP_OKAY) ||\n      ((res = mp_abs(b, &tb)) != MP_OKAY) ||\n      ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||\n      ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {\n      goto LBL_ERR;\n  }\n\n  while (n-- >= 0) {\n     if (mp_cmp(&tb, &ta) != MP_GT) {\n        if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||\n            ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {\n           goto LBL_ERR;\n        }\n     }\n     if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||\n         ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {\n           goto LBL_ERR;\n     }\n  }\n\n  /* now q == quotient and ta == remainder */\n  n  = a->sign;\n  n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);\n  if (c != NULL) {\n     mp_exch(c, &q);\n     c->sign  = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;\n  }\n  if (d != NULL) {\n     mp_exch(d, &ta);\n     d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;\n  }\nLBL_ERR:\n   mp_clear(&ta);\n   mp_clear(&tb);\n   mp_clear(&tq);\n   mp_clear(&q);\n   return res;\n}\n\n\n/* b = a/2 */\nint mp_div_2(mp_int * a, mp_int * b)\n{\n  int     x, res, oldused;\n\n  /* copy */\n  if (b->alloc < a->used) {\n    if ((res = mp_grow (b, a->used)) != MP_OKAY) {\n      return res;\n    }\n  }\n\n  oldused = b->used;\n  b->used = a->used;\n  {\n    mp_digit r, rr, *tmpa, *tmpb;\n\n    /* source alias */\n    tmpa = a->dp + b->used - 1;\n\n    /* dest alias */\n    tmpb = b->dp + b->used - 1;\n\n    /* carry */\n    r = 0;\n    for (x = b->used - 1; x >= 0; x--) {\n      /* get the carry for the next iteration */\n      rr = *tmpa & 1;\n\n      /* shift the current digit, add in carry and store */\n      *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));\n\n      /* forward carry to next iteration */\n      r = rr;\n    }\n\n    /* zero excess digits */\n    tmpb = b->dp + b->used;\n    for (x = b->used; x < oldused; x++) {\n      *tmpb++ = 0;\n    }\n  }\n  b->sign = a->sign;\n  mp_clamp (b);\n  return MP_OKAY;\n}\n\n\n/* high level addition (handles signs) */\nint mp_add (mp_int * a, mp_int * b, mp_int * c)\n{\n  int sa, sb, res;\n\n  /* get sign of both inputs */\n  sa = a->sign;\n  sb = b->sign;\n\n  /* handle two cases, not four */\n  if (sa == sb) {\n    /* both positive or both negative */\n    /* add their magnitudes, copy the sign */\n    c->sign = sa;\n    res = s_mp_add (a, b, c);\n  } else {\n    /* one positive, the other negative */\n    /* subtract the one with the greater magnitude from */\n    /* the one of the lesser magnitude.  The result gets */\n    /* the sign of the one with the greater magnitude. */\n    if (mp_cmp_mag (a, b) == MP_LT) {\n      c->sign = sb;\n      res = s_mp_sub (b, a, c);\n    } else {\n      c->sign = sa;\n      res = s_mp_sub (a, b, c);\n    }\n  }\n  return res;\n}\n\n\n/* low level addition, based on HAC pp.594, Algorithm 14.7 */\nint s_mp_add (mp_int * a, mp_int * b, mp_int * c)\n{\n  mp_int *x;\n  int     olduse, res, min_ab, max_ab;\n\n  /* find sizes, we let |a| <= |b| which means we have to sort\n   * them.  \"x\" will point to the input with the most digits\n   */\n  if (a->used > b->used) {\n    min_ab = b->used;\n    max_ab = a->used;\n    x = a;\n  } else {\n    min_ab = a->used;\n    max_ab = b->used;\n    x = b;\n  }\n\n  /* init result */\n  if (c->alloc < max_ab + 1) {\n    if ((res = mp_grow (c, max_ab + 1)) != MP_OKAY) {\n      return res;\n    }\n  }\n\n  /* get old used digit count and set new one */\n  olduse = c->used;\n  c->used = max_ab + 1;\n\n  {\n    mp_digit u, *tmpa, *tmpb, *tmpc;\n    int i;\n\n    /* alias for digit pointers */\n\n    /* first input */\n    tmpa = a->dp;\n\n    /* second input */\n    tmpb = b->dp;\n\n    /* destination */\n    tmpc = c->dp;\n\n    /* zero the carry */\n    u = 0;\n    for (i = 0; i < min_ab; i++) {\n      /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */\n      *tmpc = *tmpa++ + *tmpb++ + u;\n\n      /* U = carry bit of T[i] */\n      u = *tmpc >> ((mp_digit)DIGIT_BIT);\n\n      /* take away carry bit from T[i] */\n      *tmpc++ &= MP_MASK;\n    }\n\n    /* now copy higher words if any, that is in A+B\n     * if A or B has more digits add those in\n     */\n    if (min_ab != max_ab) {\n      for (; i < max_ab; i++) {\n        /* T[i] = X[i] + U */\n        *tmpc = x->dp[i] + u;\n\n        /* U = carry bit of T[i] */\n        u = *tmpc >> ((mp_digit)DIGIT_BIT);\n\n        /* take away carry bit from T[i] */\n        *tmpc++ &= MP_MASK;\n      }\n    }\n\n    /* add carry */\n    *tmpc++ = u;\n\n    /* clear digits above olduse */\n    for (i = c->used; i < olduse; i++) {\n      *tmpc++ = 0;\n    }\n  }\n\n  mp_clamp (c);\n  return MP_OKAY;\n}\n\n\n/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */\nint s_mp_sub (mp_int * a, mp_int * b, mp_int * c)\n{\n  int     olduse, res, min_b, max_a;\n\n  /* find sizes */\n  min_b = b->used;\n  max_a = a->used;\n\n  /* init result */\n  if (c->alloc < max_a) {\n    if ((res = mp_grow (c, max_a)) != MP_OKAY) {\n      return res;\n    }\n  }\n\n  /* sanity check on destination */\n  if (c->dp == NULL)\n     return MP_VAL;\n\n  olduse = c->used;\n  c->used = max_a;\n\n  {\n    mp_digit u, *tmpa, *tmpb, *tmpc;\n    int i;\n\n    /* alias for digit pointers */\n    tmpa = a->dp;\n    tmpb = b->dp;\n    tmpc = c->dp;\n\n    /* set carry to zero */\n    u = 0;\n    for (i = 0; i < min_b; i++) {\n      /* T[i] = A[i] - B[i] - U */\n      *tmpc = *tmpa++ - *tmpb++ - u;\n\n      /* U = carry bit of T[i]\n       * Note this saves performing an AND operation since\n       * if a carry does occur it will propagate all the way to the\n       * MSB.  As a result a single shift is enough to get the carry\n       */\n      u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));\n\n      /* Clear carry from T[i] */\n      *tmpc++ &= MP_MASK;\n    }\n\n    /* now copy higher words if any, e.g. if A has more digits than B  */\n    for (; i < max_a; i++) {\n      /* T[i] = A[i] - U */\n      *tmpc = *tmpa++ - u;\n\n      /* U = carry bit of T[i] */\n      u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));\n\n      /* Clear carry from T[i] */\n      *tmpc++ &= MP_MASK;\n    }\n\n    /* clear digits above used (since we may not have grown result above) */\n    for (i = c->used; i < olduse; i++) {\n      *tmpc++ = 0;\n    }\n  }\n\n  mp_clamp (c);\n  return MP_OKAY;\n}\n\n\n/* high level subtraction (handles signs) */\nint mp_sub (mp_int * a, mp_int * b, mp_int * c)\n{\n  int     sa, sb, res;\n\n  sa = a->sign;\n  sb = b->sign;\n\n  if (sa != sb) {\n    /* subtract a negative from a positive, OR */\n    /* subtract a positive from a negative. */\n    /* In either case, ADD their magnitudes, */\n    /* and use the sign of the first number. */\n    c->sign = sa;\n    res = s_mp_add (a, b, c);\n  } else {\n    /* subtract a positive from a positive, OR */\n    /* subtract a negative from a negative. */\n    /* First, take the difference between their */\n    /* magnitudes, then... */\n    if (mp_cmp_mag (a, b) != MP_LT) {\n      /* Copy the sign from the first */\n      c->sign = sa;\n      /* The first has a larger or equal magnitude */\n      res = s_mp_sub (a, b, c);\n    } else {\n      /* The result has the *opposite* sign from */\n      /* the first number. */\n      c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;\n      /* The second has a larger magnitude */\n      res = s_mp_sub (b, a, c);\n    }\n  }\n  return res;\n}\n\n\n/* determines if reduce_2k_l can be used */\nint mp_reduce_is_2k_l(mp_int *a)\n{\n   int ix, iy;\n\n   if (a->used == 0) {\n      return MP_NO;\n   } else if (a->used == 1) {\n      return MP_YES;\n   } else if (a->used > 1) {\n      /* if more than half of the digits are -1 we're sold */\n      for (iy = ix = 0; ix < a->used; ix++) {\n          if (a->dp[ix] == MP_MASK) {\n              ++iy;\n          }\n      }\n      return (iy >= (a->used/2)) ? MP_YES : MP_NO;\n\n   }\n   return MP_NO;\n}\n\n\n/* determines if mp_reduce_2k can be used */\nint mp_reduce_is_2k(mp_int *a)\n{\n   int ix, iy, iw;\n   mp_digit iz;\n\n   if (a->used == 0) {\n      return MP_NO;\n   } else if (a->used == 1) {\n      return MP_YES;\n   } else if (a->used > 1) {\n      iy = mp_count_bits(a);\n      iz = 1;\n      iw = 1;\n\n      /* Test every bit from the second digit up, must be 1 */\n      for (ix = DIGIT_BIT; ix < iy; ix++) {\n          if ((a->dp[iw] & iz) == 0) {\n             return MP_NO;\n          }\n          iz <<= 1;\n          if (iz > (mp_digit)MP_MASK) {\n             ++iw;\n             iz = 1;\n          }\n      }\n   }\n   return MP_YES;\n}\n\n\n/* determines if a number is a valid DR modulus */\nint mp_dr_is_modulus(mp_int *a)\n{\n   int ix;\n\n   /* must be at least two digits */\n   if (a->used < 2) {\n      return 0;\n   }\n\n   /* must be of the form b**k - a [a <= b] so all\n    * but the first digit must be equal to -1 (mod b).\n    */\n   for (ix = 1; ix < a->used; ix++) {\n       if (a->dp[ix] != MP_MASK) {\n          return 0;\n       }\n   }\n   return 1;\n}\n\n\n/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85\n *\n * Uses a left-to-right k-ary sliding window to compute the modular\n * exponentiation.\n * The value of k changes based on the size of the exponent.\n *\n * Uses Montgomery or Diminished Radix reduction [whichever appropriate]\n */\n\n#ifdef MP_LOW_MEM\n   #define TAB_SIZE 32\n#else\n   #define TAB_SIZE 256\n#endif\n\nint mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,\n                     int redmode)\n{\n  mp_int res;\n  mp_digit buf, mp;\n  int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;\n#ifdef WOLFSSL_SMALL_STACK\n  mp_int* M = NULL;\n#else\n  mp_int M[TAB_SIZE];\n#endif\n  /* use a pointer to the reduction algorithm.  This allows us to use\n   * one of many reduction algorithms without modding the guts of\n   * the code with if statements everywhere.\n   */\n  int     (*redux)(mp_int*,mp_int*,mp_digit);\n\n#ifdef WOLFSSL_SMALL_STACK\n  M = (mp_int*) XMALLOC(sizeof(mp_int) * TAB_SIZE, NULL,\n                                                       DYNAMIC_TYPE_BIGINT);\n  if (M == NULL)\n    return MP_MEM;\n#endif\n\n  /* find window size */\n  x = mp_count_bits (X);\n  if (x <= 7) {\n    winsize = 2;\n  } else if (x <= 36) {\n    winsize = 3;\n  } else if (x <= 140) {\n    winsize = 4;\n  } else if (x <= 450) {\n    winsize = 5;\n  } else if (x <= 1303) {\n    winsize = 6;\n  } else if (x <= 3529) {\n    winsize = 7;\n  } else {\n    winsize = 8;\n  }\n\n#ifdef MP_LOW_MEM\n  if (winsize > 5) {\n     winsize = 5;\n  }\n#endif\n\n  /* init M array */\n  /* init first cell */\n  if ((err = mp_init_size(&M[1], P->alloc)) != MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n     XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n     return err;\n  }\n\n  /* now init the second half of the array */\n  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {\n    if ((err = mp_init_size(&M[x], P->alloc)) != MP_OKAY) {\n      for (y = 1<<(winsize-1); y < x; y++) {\n        mp_clear (&M[y]);\n      }\n      mp_clear(&M[1]);\n\n#ifdef WOLFSSL_SMALL_STACK\n      XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n      return err;\n    }\n  }\n\n  /* determine and setup reduction code */\n  if (redmode == 0) {\n#ifdef BN_MP_MONTGOMERY_SETUP_C\n     /* now setup montgomery  */\n     if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {\n        goto LBL_M;\n     }\n#else\n     err = MP_VAL;\n     goto LBL_M;\n#endif\n\n     /* automatically pick the comba one if available (saves quite a few\n        calls/ifs) */\n#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C\n     if (((P->used * 2 + 1) < (int)MP_WARRAY) &&\n          P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {\n        redux = fast_mp_montgomery_reduce;\n     } else\n#endif\n     {\n#ifdef BN_MP_MONTGOMERY_REDUCE_C\n        /* use slower baseline Montgomery method */\n        redux = mp_montgomery_reduce;\n#else\n        err = MP_VAL;\n        goto LBL_M;\n#endif\n     }\n  } else if (redmode == 1) {\n#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)\n     /* setup DR reduction for moduli of the form B**k - b */\n     mp_dr_setup(P, &mp);\n     redux = mp_dr_reduce;\n#else\n     err = MP_VAL;\n     goto LBL_M;\n#endif\n  } else {\n#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)\n     /* setup DR reduction for moduli of the form 2**k - b */\n     if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {\n        goto LBL_M;\n     }\n     redux = mp_reduce_2k;\n#else\n     err = MP_VAL;\n     goto LBL_M;\n#endif\n  }\n\n  /* setup result */\n  if ((err = mp_init_size (&res, P->alloc)) != MP_OKAY) {\n    goto LBL_M;\n  }\n\n  /* create M table\n   *\n\n   *\n   * The first half of the table is not computed though accept for M[0] and M[1]\n   */\n\n  if (redmode == 0) {\n#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C\n     /* now we need R mod m */\n     if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {\n       goto LBL_RES;\n     }\n\n     /* now set M[1] to G * R mod m */\n     if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {\n       goto LBL_RES;\n     }\n#else\n     err = MP_VAL;\n     goto LBL_RES;\n#endif\n  } else {\n     if ((err = mp_set(&res, 1)) != MP_OKAY) {\n        goto LBL_RES;\n     }\n     if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {\n        goto LBL_RES;\n     }\n  }\n\n  /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times*/\n  if ((err = mp_copy (&M[1], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {\n    goto LBL_RES;\n  }\n\n  for (x = 0; x < (winsize - 1); x++) {\n    if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))],\n                       &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {\n      goto LBL_RES;\n    }\n    if ((err = redux (&M[(mp_digit)(1 << (winsize - 1))], P, mp)) != MP_OKAY) {\n      goto LBL_RES;\n    }\n  }\n\n  /* create upper table */\n  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {\n    if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {\n      goto LBL_RES;\n    }\n    if ((err = redux (&M[x], P, mp)) != MP_OKAY) {\n      goto LBL_RES;\n    }\n  }\n\n  /* set initial mode and bit cnt */\n  mode   = 0;\n  bitcnt = 1;\n  buf    = 0;\n  digidx = X->used - 1;\n  bitcpy = 0;\n  bitbuf = 0;\n\n  for (;;) {\n    /* grab next digit as required */\n    if (--bitcnt == 0) {\n      /* if digidx == -1 we are out of digits so break */\n      if (digidx == -1) {\n        break;\n      }\n      /* read next digit and reset bitcnt */\n      buf    = X->dp[digidx--];\n      bitcnt = (int)DIGIT_BIT;\n    }\n\n    /* grab the next msb from the exponent */\n    y     = (int)(buf >> (DIGIT_BIT - 1)) & 1;\n    buf <<= (mp_digit)1;\n\n    /* if the bit is zero and mode == 0 then we ignore it\n     * These represent the leading zero bits before the first 1 bit\n     * in the exponent.  Technically this opt is not required but it\n     * does lower the # of trivial squaring/reductions used\n     */\n    if (mode == 0 && y == 0) {\n      continue;\n    }\n\n    /* if the bit is zero and mode == 1 then we square */\n    if (mode == 1 && y == 0) {\n      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {\n        goto LBL_RES;\n      }\n      if ((err = redux (&res, P, mp)) != MP_OKAY) {\n        goto LBL_RES;\n      }\n      continue;\n    }\n\n    /* else we add it to the window */\n    bitbuf |= (y << (winsize - ++bitcpy));\n    mode    = 2;\n\n    if (bitcpy == winsize) {\n      /* ok window is filled so square as required and multiply  */\n      /* square first */\n      for (x = 0; x < winsize; x++) {\n        if ((err = mp_sqr (&res, &res)) != MP_OKAY) {\n          goto LBL_RES;\n        }\n        if ((err = redux (&res, P, mp)) != MP_OKAY) {\n          goto LBL_RES;\n        }\n      }\n\n      /* then multiply */\n      if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {\n        goto LBL_RES;\n      }\n      if ((err = redux (&res, P, mp)) != MP_OKAY) {\n        goto LBL_RES;\n      }\n\n      /* empty window and reset */\n      bitcpy = 0;\n      bitbuf = 0;\n      mode   = 1;\n    }\n  }\n\n  /* if bits remain then square/multiply */\n  if (mode == 2 && bitcpy > 0) {\n    /* square then multiply if the bit is set */\n    for (x = 0; x < bitcpy; x++) {\n      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {\n        goto LBL_RES;\n      }\n      if ((err = redux (&res, P, mp)) != MP_OKAY) {\n        goto LBL_RES;\n      }\n\n      /* get next bit of the window */\n      bitbuf <<= 1;\n      if ((bitbuf & (1 << winsize)) != 0) {\n        /* then multiply */\n        if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {\n          goto LBL_RES;\n        }\n        if ((err = redux (&res, P, mp)) != MP_OKAY) {\n          goto LBL_RES;\n        }\n      }\n    }\n  }\n\n  if (redmode == 0) {\n     /* fixup result if Montgomery reduction is used\n      * recall that any value in a Montgomery system is\n      * actually multiplied by R mod n.  So we have\n      * to reduce one more time to cancel out the factor\n      * of R.\n      */\n     if ((err = redux(&res, P, mp)) != MP_OKAY) {\n       goto LBL_RES;\n     }\n  }\n\n  /* swap res with Y */\n  mp_exch (&res, Y);\n  err = MP_OKAY;\nLBL_RES:mp_clear (&res);\nLBL_M:\n  mp_clear(&M[1]);\n  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {\n    mp_clear (&M[x]);\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n  return err;\n}\n\n#ifdef BN_MP_EXPTMOD_BASE_2\n#if DIGIT_BIT < 16\n    #define WINSIZE    3\n#elif DIGIT_BIT < 32\n    #define WINSIZE    4\n#elif DIGIT_BIT < 64\n    #define WINSIZE    5\n#elif DIGIT_BIT < 128\n    #define WINSIZE    6\n#endif\nint mp_exptmod_base_2(mp_int * X, mp_int * P, mp_int * Y)\n{\n  mp_digit buf, mp;\n  int      err = MP_OKAY, bitbuf, bitcpy, bitcnt, digidx, x, y;\n#ifdef WOLFSSL_SMALL_STACK\n  mp_int  *res = NULL;\n#else\n  mp_int   res[1];\n#endif\n  int     (*redux)(mp_int*,mp_int*,mp_digit);\n\n  /* automatically pick the comba one if available (saves quite a few\n     calls/ifs) */\n#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C\n  if (((P->used * 2 + 1) < (int)MP_WARRAY) &&\n       P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {\n     redux = fast_mp_montgomery_reduce;\n  } else\n#endif\n  {\n#ifdef BN_MP_MONTGOMERY_REDUCE_C\n     /* use slower baseline Montgomery method */\n     redux = mp_montgomery_reduce;\n#else\n     return MP_VAL;\n#endif\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  res = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER);\n  if (res == NULL) {\n     return MP_MEM;\n  }\n#endif\n\n  /* now setup montgomery  */\n  if ((err = mp_montgomery_setup(P, &mp)) != MP_OKAY) {\n     goto LBL_M;\n  }\n\n  /* setup result */\n  if ((err = mp_init(res)) != MP_OKAY) {\n     goto LBL_M;\n  }\n\n  /* now we need R mod m */\n  if ((err = mp_montgomery_calc_normalization(res, P)) != MP_OKAY) {\n     goto LBL_RES;\n  }\n\n  /* Get the top bits left over after taking WINSIZE bits starting at the\n   * least-significant.\n   */\n  digidx = X->used - 1;\n  bitcpy = (X->used * DIGIT_BIT) % WINSIZE;\n  if (bitcpy > 0) {\n     bitcnt = (int)DIGIT_BIT - bitcpy;\n     buf    = X->dp[digidx--];\n     bitbuf = (int)(buf >> bitcnt);\n     /* Multiply montgomery representation of 1 by 2 ^ top */\n     err = mp_mul_2d(res, bitbuf, res);\n     if (err != MP_OKAY) {\n        goto LBL_RES;\n     }\n     err = mp_mod(res, P, res);\n     if (err != MP_OKAY) {\n        goto LBL_RES;\n     }\n     /* Move out bits used */\n     buf  <<= bitcpy;\n     bitcnt++;\n  }\n  else {\n     bitcnt = 1;\n     buf    = 0;\n  }\n\n  /* empty window and reset  */\n  bitbuf = 0;\n  bitcpy = 0;\n\n  for (;;) {\n    /* grab next digit as required */\n    if (--bitcnt == 0) {\n      /* if digidx == -1 we are out of digits so break */\n      if (digidx == -1) {\n        break;\n      }\n      /* read next digit and reset bitcnt */\n      buf    = X->dp[digidx--];\n      bitcnt = (int)DIGIT_BIT;\n    }\n\n    /* grab the next msb from the exponent */\n    y       = (int)(buf >> (DIGIT_BIT - 1)) & 1;\n    buf   <<= (mp_digit)1;\n    /* add bit to the window */\n    bitbuf |= (y << (WINSIZE - ++bitcpy));\n\n    if (bitcpy == WINSIZE) {\n      /* ok window is filled so square as required and multiply  */\n      /* square first */\n      for (x = 0; x < WINSIZE; x++) {\n        err = mp_sqr(res, res);\n        if (err != MP_OKAY) {\n          goto LBL_RES;\n        }\n        err = (*redux)(res, P, mp);\n        if (err != MP_OKAY) {\n          goto LBL_RES;\n        }\n      }\n\n      /* then multiply by 2^bitbuf */\n      err = mp_mul_2d(res, bitbuf, res);\n      if (err != MP_OKAY) {\n         goto LBL_RES;\n      }\n      err = mp_mod(res, P, res);\n      if (err != MP_OKAY) {\n         goto LBL_RES;\n      }\n\n      /* empty window and reset */\n      bitcpy = 0;\n      bitbuf = 0;\n    }\n  }\n\n  /* fixup result if Montgomery reduction is used\n   * recall that any value in a Montgomery system is\n   * actually multiplied by R mod n.  So we have\n   * to reduce one more time to cancel out the factor\n   * of R.\n   */\n  err = (*redux)(res, P, mp);\n  if (err != MP_OKAY) {\n     goto LBL_RES;\n  }\n\n  /* swap res with Y */\n  mp_copy(res, Y);\n\nLBL_RES:mp_clear (res);\nLBL_M:\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n  return err;\n}\n\n#undef WINSIZE\n#endif /* BN_MP_EXPTMOD_BASE_2 */\n\n\n/* setups the montgomery reduction stuff */\nint mp_montgomery_setup (mp_int * n, mp_digit * rho)\n{\n  mp_digit x, b;\n\n/* fast inversion mod 2**k\n *\n * Based on the fact that\n *\n * XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)\n *                    =>  2*X*A - X*X*A*A = 1\n *                    =>  2*(1) - (1)     = 1\n */\n  b = n->dp[0];\n\n  if ((b & 1) == 0) {\n    return MP_VAL;\n  }\n\n  x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n  x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n#if !defined(MP_8BIT)\n  x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n#endif\n#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))\n  x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n#endif\n#ifdef MP_64BIT\n  x *= 2 - b * x;               /* here x*a==1 mod 2**64 */\n#endif\n\n  /* rho = -1/m mod b */\n  /* TAO, switched mp_word casts to mp_digit to shut up compiler */\n  *rho = (mp_digit)((((mp_digit)1 << ((mp_digit) DIGIT_BIT)) - x) & MP_MASK);\n\n  return MP_OKAY;\n}\n\n\n/* computes xR**-1 == x (mod N) via Montgomery Reduction\n *\n * This is an optimized implementation of montgomery_reduce\n * which uses the comba method to quickly calculate the columns of the\n * reduction.\n *\n * Based on Algorithm 14.32 on pp.601 of HAC.\n*/\nint fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)\n{\n  int     ix, res, olduse;\n#ifdef WOLFSSL_SMALL_STACK\n  mp_word* W;    /* uses dynamic memory and slower */\n#else\n  mp_word W[MP_WARRAY];\n#endif\n\n  /* get old used count */\n  olduse = x->used;\n\n  /* grow a as required */\n  if (x->alloc < n->used + 1) {\n    if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {\n      return res;\n    }\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  W = (mp_word*)XMALLOC(sizeof(mp_word) * MP_WARRAY, NULL, DYNAMIC_TYPE_BIGINT);\n  if (W == NULL)\n    return MP_MEM;\n#endif\n\n  /* first we have to get the digits of the input into\n   * an array of double precision words W[...]\n   */\n  {\n    mp_word *_W;\n    mp_digit *tmpx;\n\n    /* alias for the W[] array */\n    _W   = W;\n\n    /* alias for the digits of  x*/\n    tmpx = x->dp;\n\n    /* copy the digits of a into W[0..a->used-1] */\n    for (ix = 0; ix < x->used; ix++) {\n      *_W++ = *tmpx++;\n    }\n\n    /* zero the high words of W[a->used..m->used*2] */\n    for (; ix < n->used * 2 + 1; ix++) {\n      *_W++ = 0;\n    }\n  }\n\n  /* now we proceed to zero successive digits\n   * from the least significant upwards\n   */\n  for (ix = 0; ix < n->used; ix++) {\n    /* mu = ai * m' mod b\n     *\n     * We avoid a double precision multiplication (which isn't required)\n     * by casting the value down to a mp_digit.  Note this requires\n     * that W[ix-1] have  the carry cleared (see after the inner loop)\n     */\n    mp_digit mu;\n    mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);\n\n    /* a = a + mu * m * b**i\n     *\n     * This is computed in place and on the fly.  The multiplication\n     * by b**i is handled by offseting which columns the results\n     * are added to.\n     *\n     * Note the comba method normally doesn't handle carries in the\n     * inner loop In this case we fix the carry from the previous\n     * column since the Montgomery reduction requires digits of the\n     * result (so far) [see above] to work.  This is\n     * handled by fixing up one carry after the inner loop.  The\n     * carry fixups are done in order so after these loops the\n     * first m->used words of W[] have the carries fixed\n     */\n    {\n      int iy;\n      mp_digit *tmpn;\n      mp_word *_W;\n\n      /* alias for the digits of the modulus */\n      tmpn = n->dp;\n\n      /* Alias for the columns set by an offset of ix */\n      _W = W + ix;\n\n      /* inner loop */\n      for (iy = 0; iy < n->used; iy++) {\n          *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);\n      }\n    }\n\n    /* now fix carry for next digit, W[ix+1] */\n    W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);\n  }\n\n  /* now we have to propagate the carries and\n   * shift the words downward [all those least\n   * significant digits we zeroed].\n   */\n  {\n    mp_digit *tmpx;\n    mp_word *_W, *_W1;\n\n    /* nox fix rest of carries */\n\n    /* alias for current word */\n    _W1 = W + ix;\n\n    /* alias for next word, where the carry goes */\n    _W = W + ++ix;\n\n    for (; ix <= n->used * 2 + 1; ix++) {\n      *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);\n    }\n\n    /* copy out, A = A/b**n\n     *\n     * The result is A/b**n but instead of converting from an\n     * array of mp_word to mp_digit than calling mp_rshd\n     * we just copy them in the right order\n     */\n\n    /* alias for destination word */\n    tmpx = x->dp;\n\n    /* alias for shifted double precision result */\n    _W = W + n->used;\n\n    for (ix = 0; ix < n->used + 1; ix++) {\n      *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));\n    }\n\n    /* zero olduse digits, if the input a was larger than\n     * m->used+1 we'll have to clear the digits\n     */\n    for (; ix < olduse; ix++) {\n      *tmpx++ = 0;\n    }\n  }\n\n  /* set the max used and clamp */\n  x->used = n->used + 1;\n  mp_clamp (x);\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(W, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n  /* if A >= m then A = A - m */\n  if (mp_cmp_mag (x, n) != MP_LT) {\n    return s_mp_sub (x, n, x);\n  }\n  return MP_OKAY;\n}\n\n\n/* computes xR**-1 == x (mod N) via Montgomery Reduction */\nint mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)\n{\n  int     ix, res, digs;\n  mp_digit mu;\n\n  /* can the fast reduction [comba] method be used?\n   *\n   * Note that unlike in mul you're safely allowed *less*\n   * than the available columns [255 per default] since carries\n   * are fixed up in the inner loop.\n   */\n  digs = n->used * 2 + 1;\n  if ((digs < (int)MP_WARRAY) &&\n      n->used <\n      (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {\n    return fast_mp_montgomery_reduce (x, n, rho);\n  }\n\n  /* grow the input as required */\n  if (x->alloc < digs) {\n    if ((res = mp_grow (x, digs)) != MP_OKAY) {\n      return res;\n    }\n  }\n  x->used = digs;\n\n  for (ix = 0; ix < n->used; ix++) {\n    /* mu = ai * rho mod b\n     *\n     * The value of rho must be precalculated via\n     * montgomery_setup() such that\n     * it equals -1/n0 mod b this allows the\n     * following inner loop to reduce the\n     * input one digit at a time\n     */\n    mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);\n\n    /* a = a + mu * m * b**i */\n    {\n      int iy;\n      mp_digit *tmpn, *tmpx, u;\n      mp_word r;\n\n      /* alias for digits of the modulus */\n      tmpn = n->dp;\n\n      /* alias for the digits of x [the input] */\n      tmpx = x->dp + ix;\n\n      /* set the carry to zero */\n      u = 0;\n\n      /* Multiply and add in place */\n      for (iy = 0; iy < n->used; iy++) {\n        /* compute product and sum */\n        r       = ((mp_word)mu) * ((mp_word)*tmpn++) +\n                  ((mp_word) u) + ((mp_word) * tmpx);\n\n        /* get carry */\n        u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));\n\n        /* fix digit */\n        *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));\n      }\n      /* At this point the ix'th digit of x should be zero */\n\n\n      /* propagate carries upwards as required*/\n      while (u) {\n        *tmpx   += u;\n        u        = *tmpx >> DIGIT_BIT;\n        *tmpx++ &= MP_MASK;\n      }\n    }\n  }\n\n  /* at this point the n.used'th least\n   * significant digits of x are all zero\n   * which means we can shift x to the\n   * right by n.used digits and the\n   * residue is unchanged.\n   */\n\n  /* x = x/b**n.used */\n  mp_clamp(x);\n  mp_rshd (x, n->used);\n\n  /* if x >= n then x = x - n */\n  if (mp_cmp_mag (x, n) != MP_LT) {\n    return s_mp_sub (x, n, x);\n  }\n\n  return MP_OKAY;\n}\n\n\n/* determines the setup value */\nvoid mp_dr_setup(mp_int *a, mp_digit *d)\n{\n   /* the casts are required if DIGIT_BIT is one less than\n    * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]\n    */\n   *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) -\n        ((mp_word)a->dp[0]));\n}\n\n\n/* reduce \"x\" in place modulo \"n\" using the Diminished Radix algorithm.\n *\n * Based on algorithm from the paper\n *\n * \"Generating Efficient Primes for Discrete Log Cryptosystems\"\n *                 Chae Hoon Lim, Pil Joong Lee,\n *          POSTECH Information Research Laboratories\n *\n * The modulus must be of a special format [see manual]\n *\n * Has been modified to use algorithm 7.10 from the LTM book instead\n *\n * Input x must be in the range 0 <= x <= (n-1)**2\n */\nint mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)\n{\n  int      err, i, m;\n  mp_word  r;\n  mp_digit mu, *tmpx1, *tmpx2;\n\n  /* m = digits in modulus */\n  m = n->used;\n\n  /* ensure that \"x\" has at least 2m digits */\n  if (x->alloc < m + m) {\n    if ((err = mp_grow (x, m + m)) != MP_OKAY) {\n      return err;\n    }\n  }\n\n/* top of loop, this is where the code resumes if\n * another reduction pass is required.\n */\ntop:\n  /* aliases for digits */\n  /* alias for lower half of x */\n  tmpx1 = x->dp;\n\n  /* alias for upper half of x, or x/B**m */\n  tmpx2 = x->dp + m;\n\n  /* set carry to zero */\n  mu = 0;\n\n  /* compute (x mod B**m) + k * [x/B**m] inline and inplace */\n  for (i = 0; i < m; i++) {\n      r         = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;\n      *tmpx1++  = (mp_digit)(r & MP_MASK);\n      mu        = (mp_digit)(r >> ((mp_word)DIGIT_BIT));\n  }\n\n  /* set final carry */\n  *tmpx1++ = mu;\n\n  /* zero words above m */\n  for (i = m + 1; i < x->used; i++) {\n      *tmpx1++ = 0;\n  }\n\n  /* clamp, sub and return */\n  mp_clamp (x);\n\n  /* if x >= n then subtract and reduce again\n   * Each successive \"recursion\" makes the input smaller and smaller.\n   */\n  if (mp_cmp_mag (x, n) != MP_LT) {\n    if ((err = s_mp_sub(x, n, x)) != MP_OKAY) {\n        return err;\n    }\n    goto top;\n  }\n  return MP_OKAY;\n}\n\n\n/* reduces a modulo n where n is of the form 2**p - d */\nint mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)\n{\n   mp_int q;\n   int    p, res;\n\n   if ((res = mp_init(&q)) != MP_OKAY) {\n      return res;\n   }\n\n   p = mp_count_bits(n);\ntop:\n   /* q = a/2**p, a = a mod 2**p */\n   if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {\n      goto ERR;\n   }\n\n   if (d != 1) {\n      /* q = q * d */\n      if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) {\n         goto ERR;\n      }\n   }\n\n   /* a = a + q */\n   if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {\n      goto ERR;\n   }\n\n   if (mp_cmp_mag(a, n) != MP_LT) {\n      if ((res = s_mp_sub(a, n, a)) != MP_OKAY) {\n         goto ERR;\n      }\n      goto top;\n   }\n\nERR:\n   mp_clear(&q);\n   return res;\n}\n\n\n/* determines the setup value */\nint mp_reduce_2k_setup(mp_int *a, mp_digit *d)\n{\n   int res, p;\n   mp_int tmp;\n\n   if ((res = mp_init(&tmp)) != MP_OKAY) {\n      return res;\n   }\n\n   p = mp_count_bits(a);\n   if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {\n      mp_clear(&tmp);\n      return res;\n   }\n\n   if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {\n      mp_clear(&tmp);\n      return res;\n   }\n\n   *d = tmp.dp[0];\n   mp_clear(&tmp);\n   return MP_OKAY;\n}\n\n\n/* set the b bit of a */\nint mp_set_bit (mp_int * a, int b)\n{\n    int i = b / DIGIT_BIT, res;\n\n    if (a->dp == NULL || a->used < (int)(i + 1)) {\n        /* grow a to accommodate the single bit */\n        if ((res = mp_grow (a, i + 1)) != MP_OKAY) {\n            return res;\n        }\n\n        /* set the used count of where the bit will go */\n        a->used = (int)(i + 1);\n    }\n\n    /* put the single bit in its place */\n    a->dp[i] |= ((mp_digit)1) << (b % DIGIT_BIT);\n\n    return MP_OKAY;\n}\n\n/* computes a = 2**b\n *\n * Simple algorithm which zeros the int, set the required bit\n */\nint mp_2expt (mp_int * a, int b)\n{\n    /* zero a as per default */\n    mp_zero (a);\n\n    return mp_set_bit(a, b);\n}\n\n/* multiply by a digit */\nint mp_mul_d (mp_int * a, mp_digit b, mp_int * c)\n{\n  mp_digit u, *tmpa, *tmpc;\n  mp_word  r;\n  int      ix, res, olduse;\n\n  /* make sure c is big enough to hold a*b */\n  if (c->alloc < a->used + 1) {\n    if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {\n      return res;\n    }\n  }\n\n  /* get the original destinations used count */\n  olduse = c->used;\n\n  /* set the sign */\n  c->sign = a->sign;\n\n  /* alias for a->dp [source] */\n  tmpa = a->dp;\n\n  /* alias for c->dp [dest] */\n  tmpc = c->dp;\n\n  /* zero carry */\n  u = 0;\n\n  /* compute columns */\n  for (ix = 0; ix < a->used; ix++) {\n    /* compute product and carry sum for this term */\n    r       = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);\n\n    /* mask off higher bits to get a single digit */\n    *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));\n\n    /* send carry into next iteration */\n    u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));\n  }\n\n  /* store final carry [if any] and increment ix offset  */\n  *tmpc++ = u;\n  ++ix;\n\n  /* now zero digits above the top */\n  while (ix++ < olduse) {\n     *tmpc++ = 0;\n  }\n\n  /* set used count */\n  c->used = a->used + 1;\n  mp_clamp(c);\n\n  return MP_OKAY;\n}\n\n\n/* d = a * b (mod c) */\n#if defined(FREESCALE_LTC_TFM)\nint wolfcrypt_mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d)\n#else\nint mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)\n#endif\n{\n  int     res;\n  mp_int  t;\n\n  if ((res = mp_init_size (&t, c->used)) != MP_OKAY) {\n    return res;\n  }\n\n  res = mp_mul (a, b, &t);\n  if (res == MP_OKAY) {\n      res = mp_mod (&t, c, d);\n  }\n\n  mp_clear (&t);\n  return res;\n}\n\n\n/* d = a - b (mod c) */\nint mp_submod(mp_int* a, mp_int* b, mp_int* c, mp_int* d)\n{\n  int     res;\n  mp_int  t;\n\n  if ((res = mp_init (&t)) != MP_OKAY) {\n    return res;\n  }\n\n  res = mp_sub (a, b, &t);\n  if (res == MP_OKAY) {\n      res = mp_mod (&t, c, d);\n  }\n\n  mp_clear (&t);\n\n  return res;\n}\n\n/* d = a + b (mod c) */\nint mp_addmod(mp_int* a, mp_int* b, mp_int* c, mp_int* d)\n{\n   int     res;\n   mp_int  t;\n\n   if ((res = mp_init (&t)) != MP_OKAY) {\n     return res;\n   }\n\n   res = mp_add (a, b, &t);\n   if (res == MP_OKAY) {\n       res = mp_mod (&t, c, d);\n   }\n\n   mp_clear (&t);\n\n   return res;\n}\n\n/* computes b = a*a */\nint mp_sqr (mp_int * a, mp_int * b)\n{\n  int     res;\n\n  {\n#ifdef BN_FAST_S_MP_SQR_C\n    /* can we use the fast comba multiplier? */\n    if ((a->used * 2 + 1) < (int)MP_WARRAY &&\n         a->used <\n         (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {\n      res = fast_s_mp_sqr (a, b);\n    } else\n#endif\n#ifdef BN_S_MP_SQR_C\n      res = s_mp_sqr (a, b);\n#else\n      res = MP_VAL;\n#endif\n  }\n  b->sign = MP_ZPOS;\n  return res;\n}\n\n\n/* high level multiplication (handles sign) */\n#if defined(FREESCALE_LTC_TFM)\nint wolfcrypt_mp_mul(mp_int *a, mp_int *b, mp_int *c)\n#else\nint mp_mul (mp_int * a, mp_int * b, mp_int * c)\n#endif\n{\n  int     res, neg;\n  neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;\n\n  {\n    /* can we use the fast multiplier?\n     *\n     * The fast multiplier can be used if the output will\n     * have less than MP_WARRAY digits and the number of\n     * digits won't affect carry propagation\n     */\n    int     digs = a->used + b->used + 1;\n\n#ifdef BN_FAST_S_MP_MUL_DIGS_C\n    if ((digs < (int)MP_WARRAY) &&\n        MIN(a->used, b->used) <=\n        (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {\n      res = fast_s_mp_mul_digs (a, b, c, digs);\n    } else\n#endif\n#ifdef BN_S_MP_MUL_DIGS_C\n      res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */\n#else\n      res = MP_VAL;\n#endif\n\n  }\n  c->sign = (c->used > 0) ? neg : MP_ZPOS;\n  return res;\n}\n\n\n/* b = a*2 */\nint mp_mul_2(mp_int * a, mp_int * b)\n{\n  int     x, res, oldused;\n\n  /* grow to accommodate result */\n  if (b->alloc < a->used + 1) {\n    if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {\n      return res;\n    }\n  }\n\n  oldused = b->used;\n  b->used = a->used;\n\n  {\n    mp_digit r, rr, *tmpa, *tmpb;\n\n    /* alias for source */\n    tmpa = a->dp;\n\n    /* alias for dest */\n    tmpb = b->dp;\n\n    /* carry */\n    r = 0;\n    for (x = 0; x < a->used; x++) {\n\n      /* get what will be the *next* carry bit from the\n       * MSB of the current digit\n       */\n      rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));\n\n      /* now shift up this digit, add in the carry [from the previous] */\n      *tmpb++ = (mp_digit)(((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK);\n\n      /* copy the carry that would be from the source\n       * digit into the next iteration\n       */\n      r = rr;\n    }\n\n    /* new leading digit? */\n    if (r != 0) {\n      /* add a MSB which is always 1 at this point */\n      *tmpb = 1;\n      ++(b->used);\n    }\n\n    /* now zero any excess digits on the destination\n     * that we didn't write to\n     */\n    tmpb = b->dp + b->used;\n    for (x = b->used; x < oldused; x++) {\n      *tmpb++ = 0;\n    }\n  }\n  b->sign = a->sign;\n  return MP_OKAY;\n}\n\n\n/* divide by three (based on routine from MPI and the GMP manual) */\nint mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)\n{\n  mp_int   q;\n  mp_word  w, t;\n  mp_digit b;\n  int      res, ix;\n\n  /* b = 2**DIGIT_BIT / 3 */\n  b = (mp_digit) ( (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3) );\n\n  if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {\n     return res;\n  }\n\n  q.used = a->used;\n  q.sign = a->sign;\n  w = 0;\n  for (ix = a->used - 1; ix >= 0; ix--) {\n     w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);\n\n     if (w >= 3) {\n        /* multiply w by [1/3] */\n        t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);\n\n        /* now subtract 3 * [w/3] from w, to get the remainder */\n        w -= t+t+t;\n\n        /* fixup the remainder as required since\n         * the optimization is not exact.\n         */\n        while (w >= 3) {\n           t += 1;\n           w -= 3;\n        }\n      } else {\n        t = 0;\n      }\n      q.dp[ix] = (mp_digit)t;\n  }\n\n  /* [optional] store the remainder */\n  if (d != NULL) {\n     *d = (mp_digit)w;\n  }\n\n  /* [optional] store the quotient */\n  if (c != NULL) {\n     mp_clamp(&q);\n     mp_exch(&q, c);\n  }\n  mp_clear(&q);\n\n  return res;\n}\n\n\n/* init an mp_init for a given size */\nint mp_init_size (mp_int * a, int size)\n{\n  int x;\n\n  /* pad size so there are always extra digits */\n  size += (MP_PREC * 2) - (size % MP_PREC);\n\n  /* alloc mem */\n  a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size, NULL,\n                                      DYNAMIC_TYPE_BIGINT);\n  if (a->dp == NULL) {\n    return MP_MEM;\n  }\n\n  /* set the members */\n  a->used  = 0;\n  a->alloc = size;\n  a->sign  = MP_ZPOS;\n#ifdef HAVE_WOLF_BIGINT\n  wc_bigint_init(&a->raw);\n#endif\n\n  /* zero the digits */\n  for (x = 0; x < size; x++) {\n      a->dp[x] = 0;\n  }\n\n  return MP_OKAY;\n}\n\n\n/* the jist of squaring...\n * you do like mult except the offset of the tmpx [one that\n * starts closer to zero] can't equal the offset of tmpy.\n * So basically you set up iy like before then you min it with\n * (ty-tx) so that it never happens.  You double all those\n * you add in the inner loop\n\nAfter that loop you do the squares and add them in.\n*/\n\nint fast_s_mp_sqr (mp_int * a, mp_int * b)\n{\n  int       olduse, res, pa, ix, iz;\n#ifdef WOLFSSL_SMALL_STACK\n  mp_digit* W;    /* uses dynamic memory and slower */\n#else\n  mp_digit W[MP_WARRAY];\n#endif\n  mp_digit  *tmpx;\n  mp_word   W1;\n\n  /* grow the destination as required */\n  pa = a->used + a->used;\n  if (b->alloc < pa) {\n    if ((res = mp_grow (b, pa)) != MP_OKAY) {\n      return res;\n    }\n  }\n\n  if (pa > (int)MP_WARRAY)\n    return MP_RANGE;  /* TAO range check */\n\n#ifdef WOLFSSL_SMALL_STACK\n  W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, NULL, DYNAMIC_TYPE_BIGINT);\n  if (W == NULL)\n    return MP_MEM;\n#endif\n\n  /* number of output digits to produce */\n  W1 = 0;\n  for (ix = 0; ix < pa; ix++) {\n      int      tx, ty, iy;\n      mp_word  _W;\n      mp_digit *tmpy;\n\n      /* clear counter */\n      _W = 0;\n\n      /* get offsets into the two bignums */\n      ty = MIN(a->used-1, ix);\n      tx = ix - ty;\n\n      /* setup temp aliases */\n      tmpx = a->dp + tx;\n      tmpy = a->dp + ty;\n\n      /* this is the number of times the loop will iterate, essentially\n         while (tx++ < a->used && ty-- >= 0) { ... }\n       */\n      iy = MIN(a->used-tx, ty+1);\n\n      /* now for squaring tx can never equal ty\n       * we halve the distance since they approach at a rate of 2x\n       * and we have to round because odd cases need to be executed\n       */\n      iy = MIN(iy, (ty-tx+1)>>1);\n\n      /* execute loop */\n      for (iz = 0; iz < iy; iz++) {\n         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);\n      }\n\n      /* double the inner product and add carry */\n      _W = _W + _W + W1;\n\n      /* even columns have the square term in them */\n      if ((ix&1) == 0) {\n         _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);\n      }\n\n      /* store it */\n      W[ix] = (mp_digit)(_W & MP_MASK);\n\n      /* make next carry */\n      W1 = _W >> ((mp_word)DIGIT_BIT);\n  }\n\n  /* setup dest */\n  olduse  = b->used;\n  b->used = a->used+a->used;\n\n  {\n    mp_digit *tmpb;\n    tmpb = b->dp;\n    for (ix = 0; ix < pa; ix++) {\n      *tmpb++ = (mp_digit)(W[ix] & MP_MASK);\n    }\n\n    /* clear unused digits [that existed in the old copy of c] */\n    for (; ix < olduse; ix++) {\n      *tmpb++ = 0;\n    }\n  }\n  mp_clamp (b);\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(W, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n  return MP_OKAY;\n}\n\n\n/* Fast (comba) multiplier\n *\n * This is the fast column-array [comba] multiplier.  It is\n * designed to compute the columns of the product first\n * then handle the carries afterwards.  This has the effect\n * of making the nested loops that compute the columns very\n * simple and schedulable on super-scalar processors.\n *\n * This has been modified to produce a variable number of\n * digits of output so if say only a half-product is required\n * you don't have to compute the upper half (a feature\n * required for fast Barrett reduction).\n *\n * Based on Algorithm 14.12 on pp.595 of HAC.\n *\n */\nint fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)\n{\n  int     olduse, res, pa, ix, iz;\n#ifdef WOLFSSL_SMALL_STACK\n  mp_digit* W;    /* uses dynamic memory and slower */\n#else\n  mp_digit W[MP_WARRAY];\n#endif\n  mp_word  _W;\n\n  /* grow the destination as required */\n  if (c->alloc < digs) {\n    if ((res = mp_grow (c, digs)) != MP_OKAY) {\n      return res;\n    }\n  }\n\n  /* number of output digits to produce */\n  pa = MIN(digs, a->used + b->used);\n  if (pa > (int)MP_WARRAY)\n    return MP_RANGE;  /* TAO range check */\n\n#ifdef WOLFSSL_SMALL_STACK\n  W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, NULL, DYNAMIC_TYPE_BIGINT);\n  if (W == NULL)\n    return MP_MEM;\n#endif\n\n  /* clear the carry */\n  _W = 0;\n  for (ix = 0; ix < pa; ix++) {\n      int      tx, ty;\n      int      iy;\n      mp_digit *tmpx, *tmpy;\n\n      /* get offsets into the two bignums */\n      ty = MIN(b->used-1, ix);\n      tx = ix - ty;\n\n      /* setup temp aliases */\n      tmpx = a->dp + tx;\n      tmpy = b->dp + ty;\n\n      /* this is the number of times the loop will iterate, essentially\n         while (tx++ < a->used && ty-- >= 0) { ... }\n       */\n      iy = MIN(a->used-tx, ty+1);\n\n      /* execute loop */\n      for (iz = 0; iz < iy; ++iz) {\n         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);\n\n      }\n\n      /* store term */\n      W[ix] = (mp_digit)(((mp_digit)_W) & MP_MASK);\n\n      /* make next carry */\n      _W = _W >> ((mp_word)DIGIT_BIT);\n }\n\n  /* setup dest */\n  olduse  = c->used;\n  c->used = pa;\n\n  {\n    mp_digit *tmpc;\n    tmpc = c->dp;\n    for (ix = 0; ix < pa; ix++) { /* JRB, +1 could read uninitialized data */\n      /* now extract the previous digit [below the carry] */\n      *tmpc++ = W[ix];\n    }\n\n    /* clear unused digits [that existed in the old copy of c] */\n    for (; ix < olduse; ix++) {\n      *tmpc++ = 0;\n    }\n  }\n  mp_clamp (c);\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(W, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n  return MP_OKAY;\n}\n\n\n/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */\nint s_mp_sqr (mp_int * a, mp_int * b)\n{\n  mp_int  t;\n  int     res, ix, iy, pa;\n  mp_word r;\n  mp_digit u, tmpx, *tmpt;\n\n  pa = a->used;\n  if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {\n    return res;\n  }\n\n  /* default used is maximum possible size */\n  t.used = 2*pa + 1;\n\n  for (ix = 0; ix < pa; ix++) {\n    /* first calculate the digit at 2*ix */\n    /* calculate double precision result */\n    r = ((mp_word) t.dp[2*ix]) +\n        ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);\n\n    /* store lower part in result */\n    t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));\n\n    /* get the carry */\n    u           = (mp_digit)(r >> ((mp_word) DIGIT_BIT));\n\n    /* left hand side of A[ix] * A[iy] */\n    tmpx        = a->dp[ix];\n\n    /* alias for where to store the results */\n    tmpt        = t.dp + (2*ix + 1);\n\n    for (iy = ix + 1; iy < pa; iy++) {\n      /* first calculate the product */\n      r       = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);\n\n      /* now calculate the double precision result, note we use\n       * addition instead of *2 since it's easier to optimize\n       */\n      r       = ((mp_word) *tmpt) + r + r + ((mp_word) u);\n\n      /* store lower part */\n      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));\n\n      /* get carry */\n      u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));\n    }\n    /* propagate upwards */\n    while (u != ((mp_digit) 0)) {\n      r       = ((mp_word) *tmpt) + ((mp_word) u);\n      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));\n      u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));\n    }\n  }\n\n  mp_clamp (&t);\n  mp_exch (&t, b);\n  mp_clear (&t);\n  return MP_OKAY;\n}\n\n\n/* multiplies |a| * |b| and only computes up to digs digits of result\n * HAC pp. 595, Algorithm 14.12  Modified so you can control how\n * many digits of output are created.\n */\nint s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)\n{\n  mp_int  t;\n  int     res, pa, pb, ix, iy;\n  mp_digit u;\n  mp_word r;\n  mp_digit tmpx, *tmpt, *tmpy;\n\n  /* can we use the fast multiplier? */\n  if ((digs < (int)MP_WARRAY) &&\n      MIN (a->used, b->used) <\n          (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {\n    return fast_s_mp_mul_digs (a, b, c, digs);\n  }\n\n  if ((res = mp_init_size (&t, digs)) != MP_OKAY) {\n    return res;\n  }\n  t.used = digs;\n\n  /* compute the digits of the product directly */\n  pa = a->used;\n  for (ix = 0; ix < pa; ix++) {\n    /* set the carry to zero */\n    u = 0;\n\n    /* limit ourselves to making digs digits of output */\n    pb = MIN (b->used, digs - ix);\n\n    /* setup some aliases */\n    /* copy of the digit from a used within the nested loop */\n    tmpx = a->dp[ix];\n\n    /* an alias for the destination shifted ix places */\n    tmpt = t.dp + ix;\n\n    /* an alias for the digits of b */\n    tmpy = b->dp;\n\n    /* compute the columns of the output and propagate the carry */\n    for (iy = 0; iy < pb; iy++) {\n      /* compute the column as a mp_word */\n      r       = ((mp_word)*tmpt) +\n                ((mp_word)tmpx) * ((mp_word)*tmpy++) +\n                ((mp_word) u);\n\n      /* the new column is the lower part of the result */\n      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));\n\n      /* get the carry word from the result */\n      u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));\n    }\n    /* set carry if it is placed below digs */\n    if (ix + iy < digs) {\n      *tmpt = u;\n    }\n  }\n\n  mp_clamp (&t);\n  mp_exch (&t, c);\n\n  mp_clear (&t);\n  return MP_OKAY;\n}\n\n\n/*\n * shifts with subtractions when the result is greater than b.\n *\n * The method is slightly modified to shift B unconditionally up to just under\n * the leading bit of b.  This saves a lot of multiple precision shifting.\n */\nint mp_montgomery_calc_normalization (mp_int * a, mp_int * b)\n{\n  int     x, bits, res;\n\n  /* how many bits of last digit does b use */\n  bits = mp_count_bits (b) % DIGIT_BIT;\n\n  if (b->used > 1) {\n     if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1))\n         != MP_OKAY) {\n        return res;\n     }\n  } else {\n     if ((res = mp_set(a, 1)) != MP_OKAY) {\n        return res;\n     }\n     bits = 1;\n  }\n\n  /* now compute C = A * B mod b */\n  for (x = bits - 1; x < (int)DIGIT_BIT; x++) {\n    if ((res = mp_mul_2 (a, a)) != MP_OKAY) {\n      return res;\n    }\n    if (mp_cmp_mag (a, b) != MP_LT) {\n      if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {\n        return res;\n      }\n    }\n  }\n\n  return MP_OKAY;\n}\n\n\n#ifdef MP_LOW_MEM\n   #define TAB_SIZE 32\n#else\n   #define TAB_SIZE 256\n#endif\n\nint s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)\n{\n  mp_int  M[TAB_SIZE], res, mu;\n  mp_digit buf;\n  int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;\n  int (*redux)(mp_int*,mp_int*,mp_int*);\n\n  /* find window size */\n  x = mp_count_bits (X);\n  if (x <= 7) {\n    winsize = 2;\n  } else if (x <= 36) {\n    winsize = 3;\n  } else if (x <= 140) {\n    winsize = 4;\n  } else if (x <= 450) {\n    winsize = 5;\n  } else if (x <= 1303) {\n    winsize = 6;\n  } else if (x <= 3529) {\n    winsize = 7;\n  } else {\n    winsize = 8;\n  }\n\n#ifdef MP_LOW_MEM\n    if (winsize > 5) {\n       winsize = 5;\n    }\n#endif\n\n  /* init M array */\n  /* init first cell */\n  if ((err = mp_init(&M[1])) != MP_OKAY) {\n     return err;\n  }\n\n  /* now init the second half of the array */\n  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {\n    if ((err = mp_init(&M[x])) != MP_OKAY) {\n      for (y = 1<<(winsize-1); y < x; y++) {\n        mp_clear (&M[y]);\n      }\n      mp_clear(&M[1]);\n      return err;\n    }\n  }\n\n  /* create mu, used for Barrett reduction */\n  if ((err = mp_init (&mu)) != MP_OKAY) {\n    goto LBL_M;\n  }\n\n  if (redmode == 0) {\n     if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {\n        goto LBL_MU;\n     }\n     redux = mp_reduce;\n  } else {\n     if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {\n        goto LBL_MU;\n     }\n     redux = mp_reduce_2k_l;\n  }\n\n  /* create M table\n   *\n   * The M table contains powers of the base,\n   * e.g. M[x] = G**x mod P\n   *\n   * The first half of the table is not\n   * computed though accept for M[0] and M[1]\n   */\n  if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {\n    goto LBL_MU;\n  }\n\n  /* compute the value at M[1<<(winsize-1)] by squaring\n   * M[1] (winsize-1) times\n   */\n  if ((err = mp_copy (&M[1], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {\n    goto LBL_MU;\n  }\n\n  for (x = 0; x < (winsize - 1); x++) {\n    /* square it */\n    if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))],\n                       &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {\n      goto LBL_MU;\n    }\n\n    /* reduce modulo P */\n    if ((err = redux (&M[(mp_digit)(1 << (winsize - 1))], P, &mu)) != MP_OKAY) {\n      goto LBL_MU;\n    }\n  }\n\n  /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)\n   * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)\n   */\n  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {\n    if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {\n      goto LBL_MU;\n    }\n    if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {\n      goto LBL_MU;\n    }\n  }\n\n  /* setup result */\n  if ((err = mp_init (&res)) != MP_OKAY) {\n    goto LBL_MU;\n  }\n  if ((err = mp_set (&res, 1)) != MP_OKAY) {\n    goto LBL_MU;\n  }\n\n  /* set initial mode and bit cnt */\n  mode   = 0;\n  bitcnt = 1;\n  buf    = 0;\n  digidx = X->used - 1;\n  bitcpy = 0;\n  bitbuf = 0;\n\n  for (;;) {\n    /* grab next digit as required */\n    if (--bitcnt == 0) {\n      /* if digidx == -1 we are out of digits */\n      if (digidx == -1) {\n        break;\n      }\n      /* read next digit and reset the bitcnt */\n      buf    = X->dp[digidx--];\n      bitcnt = (int) DIGIT_BIT;\n    }\n\n    /* grab the next msb from the exponent */\n    y     = (int)(buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;\n    buf <<= (mp_digit)1;\n\n    /* if the bit is zero and mode == 0 then we ignore it\n     * These represent the leading zero bits before the first 1 bit\n     * in the exponent.  Technically this opt is not required but it\n     * does lower the # of trivial squaring/reductions used\n     */\n    if (mode == 0 && y == 0) {\n      continue;\n    }\n\n    /* if the bit is zero and mode == 1 then we square */\n    if (mode == 1 && y == 0) {\n      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {\n        goto LBL_RES;\n      }\n      if ((err = redux (&res, P, &mu)) != MP_OKAY) {\n        goto LBL_RES;\n      }\n      continue;\n    }\n\n    /* else we add it to the window */\n    bitbuf |= (y << (winsize - ++bitcpy));\n    mode    = 2;\n\n    if (bitcpy == winsize) {\n      /* ok window is filled so square as required and multiply  */\n      /* square first */\n      for (x = 0; x < winsize; x++) {\n        if ((err = mp_sqr (&res, &res)) != MP_OKAY) {\n          goto LBL_RES;\n        }\n        if ((err = redux (&res, P, &mu)) != MP_OKAY) {\n          goto LBL_RES;\n        }\n      }\n\n      /* then multiply */\n      if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {\n        goto LBL_RES;\n      }\n      if ((err = redux (&res, P, &mu)) != MP_OKAY) {\n        goto LBL_RES;\n      }\n\n      /* empty window and reset */\n      bitcpy = 0;\n      bitbuf = 0;\n      mode   = 1;\n    }\n  }\n\n  /* if bits remain then square/multiply */\n  if (mode == 2 && bitcpy > 0) {\n    /* square then multiply if the bit is set */\n    for (x = 0; x < bitcpy; x++) {\n      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {\n        goto LBL_RES;\n      }\n      if ((err = redux (&res, P, &mu)) != MP_OKAY) {\n        goto LBL_RES;\n      }\n\n      bitbuf <<= 1;\n      if ((bitbuf & (1 << winsize)) != 0) {\n        /* then multiply */\n        if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {\n          goto LBL_RES;\n        }\n        if ((err = redux (&res, P, &mu)) != MP_OKAY) {\n          goto LBL_RES;\n        }\n      }\n    }\n  }\n\n  mp_exch (&res, Y);\n  err = MP_OKAY;\nLBL_RES:mp_clear (&res);\nLBL_MU:mp_clear (&mu);\nLBL_M:\n  mp_clear(&M[1]);\n  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {\n    mp_clear (&M[x]);\n  }\n  return err;\n}\n\n\n/* pre-calculate the value required for Barrett reduction\n * For a given modulus \"b\" it calculates the value required in \"a\"\n */\nint mp_reduce_setup (mp_int * a, mp_int * b)\n{\n  int     res;\n\n  if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {\n    return res;\n  }\n  return mp_div (a, b, a, NULL);\n}\n\n\n/* reduces x mod m, assumes 0 < x < m**2, mu is\n * precomputed via mp_reduce_setup.\n * From HAC pp.604 Algorithm 14.42\n */\nint mp_reduce (mp_int * x, mp_int * m, mp_int * mu)\n{\n  mp_int  q;\n  int     res, um = m->used;\n\n  /* q = x */\n  if ((res = mp_init_copy (&q, x)) != MP_OKAY) {\n    return res;\n  }\n\n  /* q1 = x / b**(k-1)  */\n  mp_rshd (&q, um - 1);\n\n  /* according to HAC this optimization is ok */\n  if (((mp_word) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {\n    if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {\n      goto CLEANUP;\n    }\n  } else {\n#ifdef BN_S_MP_MUL_HIGH_DIGS_C\n    if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {\n      goto CLEANUP;\n    }\n#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)\n    if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {\n      goto CLEANUP;\n    }\n#else\n    {\n      res = MP_VAL;\n      goto CLEANUP;\n    }\n#endif\n  }\n\n  /* q3 = q2 / b**(k+1) */\n  mp_rshd (&q, um + 1);\n\n  /* x = x mod b**(k+1), quick (no division) */\n  if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {\n    goto CLEANUP;\n  }\n\n  /* q = q * m mod b**(k+1), quick (no division) */\n  if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {\n    goto CLEANUP;\n  }\n\n  /* x = x - q */\n  if ((res = mp_sub (x, &q, x)) != MP_OKAY) {\n    goto CLEANUP;\n  }\n\n  /* If x < 0, add b**(k+1) to it */\n  if (mp_cmp_d (x, 0) == MP_LT) {\n    if ((res = mp_set (&q, 1)) != MP_OKAY)\n        goto CLEANUP;\n    if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)\n      goto CLEANUP;\n    if ((res = mp_add (x, &q, x)) != MP_OKAY)\n      goto CLEANUP;\n  }\n\n  /* Back off if it's too big */\n  while (mp_cmp (x, m) != MP_LT) {\n    if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {\n      goto CLEANUP;\n    }\n  }\n\nCLEANUP:\n  mp_clear (&q);\n\n  return res;\n}\n\n\n/* reduces a modulo n where n is of the form 2**p - d\n   This differs from reduce_2k since \"d\" can be larger\n   than a single digit.\n*/\nint mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d)\n{\n   mp_int q;\n   int    p, res;\n\n   if ((res = mp_init(&q)) != MP_OKAY) {\n      return res;\n   }\n\n   p = mp_count_bits(n);\ntop:\n   /* q = a/2**p, a = a mod 2**p */\n   if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {\n      goto ERR;\n   }\n\n   /* q = q * d */\n   if ((res = mp_mul(&q, d, &q)) != MP_OKAY) {\n      goto ERR;\n   }\n\n   /* a = a + q */\n   if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {\n      goto ERR;\n   }\n\n   if (mp_cmp_mag(a, n) != MP_LT) {\n      if ((res = s_mp_sub(a, n, a)) != MP_OKAY) {\n         goto ERR;\n      }\n      goto top;\n   }\n\nERR:\n   mp_clear(&q);\n   return res;\n}\n\n\n/* determines the setup value */\nint mp_reduce_2k_setup_l(mp_int *a, mp_int *d)\n{\n   int    res;\n   mp_int tmp;\n\n   if ((res = mp_init(&tmp)) != MP_OKAY) {\n      return res;\n   }\n\n   if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) {\n      goto ERR;\n   }\n\n   if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) {\n      goto ERR;\n   }\n\nERR:\n   mp_clear(&tmp);\n   return res;\n}\n\n\n/* multiplies |a| * |b| and does not compute the lower digs digits\n * [meant to get the higher part of the product]\n */\nint s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)\n{\n  mp_int  t;\n  int     res, pa, pb, ix, iy;\n  mp_digit u;\n  mp_word r;\n  mp_digit tmpx, *tmpt, *tmpy;\n\n  /* can we use the fast multiplier? */\n#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C\n  if (((a->used + b->used + 1) < (int)MP_WARRAY)\n      && MIN (a->used, b->used) <\n      (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {\n    return fast_s_mp_mul_high_digs (a, b, c, digs);\n  }\n#endif\n\n  if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) {\n    return res;\n  }\n  t.used = a->used + b->used + 1;\n\n  pa = a->used;\n  pb = b->used;\n  for (ix = 0; ix < pa && a->dp; ix++) {\n    /* clear the carry */\n    u = 0;\n\n    /* left hand side of A[ix] * B[iy] */\n    tmpx = a->dp[ix];\n\n    /* alias to the address of where the digits will be stored */\n    tmpt = &(t.dp[digs]);\n\n    /* alias for where to read the right hand side from */\n    tmpy = b->dp + (digs - ix);\n\n    for (iy = digs - ix; iy < pb; iy++) {\n      /* calculate the double precision result */\n      r       = ((mp_word)*tmpt) +\n                ((mp_word)tmpx) * ((mp_word)*tmpy++) +\n                ((mp_word) u);\n\n      /* get the lower part */\n      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));\n\n      /* carry the carry */\n      u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));\n    }\n    *tmpt = u;\n  }\n  mp_clamp (&t);\n  mp_exch (&t, c);\n  mp_clear (&t);\n  return MP_OKAY;\n}\n\n\n/* this is a modified version of fast_s_mul_digs that only produces\n * output digits *above* digs.  See the comments for fast_s_mul_digs\n * to see how it works.\n *\n * This is used in the Barrett reduction since for one of the multiplications\n * only the higher digits were needed.  This essentially halves the work.\n *\n * Based on Algorithm 14.12 on pp.595 of HAC.\n */\nint fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)\n{\n  int     olduse, res, pa, ix, iz;\n#ifdef WOLFSSL_SMALL_STACK\n  mp_digit* W;    /* uses dynamic memory and slower */\n#else\n  mp_digit W[MP_WARRAY];\n#endif\n  mp_word  _W;\n\n  if (a->dp == NULL) { /* JRB, avoid reading uninitialized values */\n      return MP_VAL;\n  }\n\n  /* grow the destination as required */\n  pa = a->used + b->used;\n  if (c->alloc < pa) {\n    if ((res = mp_grow (c, pa)) != MP_OKAY) {\n      return res;\n    }\n  }\n\n  if (pa > (int)MP_WARRAY)\n    return MP_RANGE;  /* TAO range check */\n\n#ifdef WOLFSSL_SMALL_STACK\n  W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, NULL, DYNAMIC_TYPE_BIGINT);\n  if (W == NULL)\n    return MP_MEM;\n#endif\n\n  /* number of output digits to produce */\n  pa = a->used + b->used;\n  _W = 0;\n  for (ix = digs; ix < pa; ix++) { /* JRB, have a->dp check at top of function*/\n      int      tx, ty, iy;\n      mp_digit *tmpx, *tmpy;\n\n      /* get offsets into the two bignums */\n      ty = MIN(b->used-1, ix);\n      tx = ix - ty;\n\n      /* setup temp aliases */\n      tmpx = a->dp + tx;\n      tmpy = b->dp + ty;\n\n      /* this is the number of times the loop will iterate, essentially its\n         while (tx++ < a->used && ty-- >= 0) { ... }\n       */\n      iy = MIN(a->used-tx, ty+1);\n\n      /* execute loop */\n      for (iz = 0; iz < iy; iz++) {\n         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);\n      }\n\n      /* store term */\n      W[ix] = (mp_digit)(((mp_digit)_W) & MP_MASK);\n\n      /* make next carry */\n      _W = _W >> ((mp_word)DIGIT_BIT);\n  }\n\n  /* setup dest */\n  olduse  = c->used;\n  c->used = pa;\n\n  {\n    mp_digit *tmpc;\n\n    tmpc = c->dp + digs;\n    for (ix = digs; ix < pa; ix++) {   /* TAO, <= could potentially overwrite */\n      /* now extract the previous digit [below the carry] */\n      *tmpc++ = W[ix];\n    }\n\n    /* clear unused digits [that existed in the old copy of c] */\n    for (; ix < olduse; ix++) {\n      *tmpc++ = 0;\n    }\n  }\n  mp_clamp (c);\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(W, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n  return MP_OKAY;\n}\n\n\n#ifndef MP_SET_CHUNK_BITS\n    #define MP_SET_CHUNK_BITS 4\n#endif\nint mp_set_int (mp_int * a, unsigned long b)\n{\n  int x, res;\n\n  /* use direct mp_set if b is less than mp_digit max */\n  if (b < MP_DIGIT_MAX) {\n    return mp_set (a, (mp_digit)b);\n  }\n\n  mp_zero (a);\n\n  /* set chunk bits at a time */\n  for (x = 0; x < (int)(sizeof(b) * 8) / MP_SET_CHUNK_BITS; x++) {\n    /* shift the number up chunk bits */\n    if ((res = mp_mul_2d (a, MP_SET_CHUNK_BITS, a)) != MP_OKAY) {\n      return res;\n    }\n\n    /* OR in the top bits of the source */\n    a->dp[0] |= (b >> ((sizeof(b) * 8) - MP_SET_CHUNK_BITS)) &\n                                  ((1 << MP_SET_CHUNK_BITS) - 1);\n\n    /* shift the source up to the next chunk bits */\n    b <<= MP_SET_CHUNK_BITS;\n\n    /* ensure that digits are not clamped off */\n    a->used += 1;\n  }\n  mp_clamp (a);\n  return MP_OKAY;\n}\n\n\n#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_ECC) || !defined(NO_RSA) || \\\n    !defined(NO_DSA) | !defined(NO_DH)\n\n/* c = a * a (mod b) */\nint mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)\n{\n  int     res;\n  mp_int  t;\n\n  if ((res = mp_init (&t)) != MP_OKAY) {\n    return res;\n  }\n\n  if ((res = mp_sqr (a, &t)) != MP_OKAY) {\n    mp_clear (&t);\n    return res;\n  }\n  res = mp_mod (&t, b, c);\n  mp_clear (&t);\n  return res;\n}\n\n#endif\n\n\n#if defined(HAVE_ECC) || !defined(NO_PWDBASED) || defined(WOLFSSL_SNIFFER) || \\\n    defined(WOLFSSL_HAVE_WOLFSCEP) || defined(WOLFSSL_KEY_GEN) || \\\n    defined(OPENSSL_EXTRA) || defined(WC_RSA_BLINDING) || \\\n    (!defined(NO_RSA) && !defined(NO_RSA_BOUNDS_CHECK))\n\n/* single digit addition */\nint mp_add_d (mp_int* a, mp_digit b, mp_int* c)\n{\n  int     res, ix, oldused;\n  mp_digit *tmpa, *tmpc, mu;\n\n  /* grow c as required */\n  if (c->alloc < a->used + 1) {\n     if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {\n        return res;\n     }\n  }\n\n  /* if a is negative and |a| >= b, call c = |a| - b */\n  if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {\n     /* temporarily fix sign of a */\n     a->sign = MP_ZPOS;\n\n     /* c = |a| - b */\n     res = mp_sub_d(a, b, c);\n\n     /* fix sign  */\n     a->sign = c->sign = MP_NEG;\n\n     /* clamp */\n     mp_clamp(c);\n\n     return res;\n  }\n\n  /* old number of used digits in c */\n  oldused = c->used;\n\n  /* sign always positive */\n  c->sign = MP_ZPOS;\n\n  /* source alias */\n  tmpa    = a->dp;\n\n  /* destination alias */\n  tmpc    = c->dp;\n\n  /* if a is positive */\n  if (a->sign == MP_ZPOS) {\n     /* add digit, after this we're propagating\n      * the carry.\n      */\n     *tmpc   = *tmpa++ + b;\n     mu      = *tmpc >> DIGIT_BIT;\n     *tmpc++ &= MP_MASK;\n\n     /* now handle rest of the digits */\n     for (ix = 1; ix < a->used; ix++) {\n        *tmpc   = *tmpa++ + mu;\n        mu      = *tmpc >> DIGIT_BIT;\n        *tmpc++ &= MP_MASK;\n     }\n     /* set final carry */\n     if (ix < c->alloc) {\n        ix++;\n        *tmpc++  = mu;\n     }\n\n     /* setup size */\n     c->used = a->used + 1;\n  } else {\n     /* a was negative and |a| < b */\n     c->used  = 1;\n\n     /* the result is a single digit */\n     if (a->used == 1) {\n        *tmpc++  =  b - a->dp[0];\n     } else {\n        *tmpc++  =  b;\n     }\n\n     /* setup count so the clearing of oldused\n      * can fall through correctly\n      */\n     ix       = 1;\n  }\n\n  /* now zero to oldused */\n  while (ix++ < oldused) {\n     *tmpc++ = 0;\n  }\n  mp_clamp(c);\n\n  return MP_OKAY;\n}\n\n\n/* single digit subtraction */\nint mp_sub_d (mp_int * a, mp_digit b, mp_int * c)\n{\n  mp_digit *tmpa, *tmpc, mu;\n  int       res, ix, oldused;\n\n  /* grow c as required */\n  if (c->alloc < a->used + 1) {\n     if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {\n        return res;\n     }\n  }\n\n  /* if a is negative just do an unsigned\n   * addition [with fudged signs]\n   */\n  if (a->sign == MP_NEG) {\n     a->sign = MP_ZPOS;\n     res     = mp_add_d(a, b, c);\n     a->sign = c->sign = MP_NEG;\n\n     /* clamp */\n     mp_clamp(c);\n\n     return res;\n  }\n\n  /* setup regs */\n  oldused = c->used;\n  tmpa    = a->dp;\n  tmpc    = c->dp;\n\n  /* if a <= b simply fix the single digit */\n  if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {\n     if (a->used == 1) {\n        *tmpc++ = b - *tmpa;\n     } else {\n        *tmpc++ = b;\n     }\n     ix      = 1;\n\n     /* negative/1digit */\n     c->sign = MP_NEG;\n     c->used = 1;\n  } else {\n     /* positive/size */\n     c->sign = MP_ZPOS;\n     c->used = a->used;\n\n     /* subtract first digit */\n     *tmpc    = *tmpa++ - b;\n     mu       = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);\n     *tmpc++ &= MP_MASK;\n\n     /* handle rest of the digits */\n     for (ix = 1; ix < a->used; ix++) {\n        *tmpc    = *tmpa++ - mu;\n        mu       = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);\n        *tmpc++ &= MP_MASK;\n     }\n  }\n\n  /* zero excess digits */\n  while (ix++ < oldused) {\n     *tmpc++ = 0;\n  }\n  mp_clamp(c);\n  return MP_OKAY;\n}\n\n#endif /* defined(HAVE_ECC) || !defined(NO_PWDBASED) */\n\n\n#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(HAVE_ECC) || \\\n    defined(DEBUG_WOLFSSL) || !defined(NO_RSA) || !defined(NO_DSA) || \\\n    !defined(NO_DH)\n\nstatic const int lnz[16] = {\n   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0\n};\n\n/* Counts the number of lsbs which are zero before the first zero bit */\nint mp_cnt_lsb(mp_int *a)\n{\n    int x;\n    mp_digit q = 0, qq;\n\n    /* easy out */\n    if (mp_iszero(a) == MP_YES) {\n        return 0;\n    }\n\n    /* scan lower digits until non-zero */\n    for (x = 0; x < a->used && a->dp[x] == 0; x++) {}\n    if (a->dp)\n        q = a->dp[x];\n    x *= DIGIT_BIT;\n\n    /* now scan this digit until a 1 is found */\n    if ((q & 1) == 0) {\n        do {\n            qq  = q & 15;\n            x  += lnz[qq];\n            q >>= 4;\n        } while (qq == 0);\n    }\n    return x;\n}\n\n\n\n\nstatic int s_is_power_of_two(mp_digit b, int *p)\n{\n   int x;\n\n   /* fast return if no power of two */\n   if ((b==0) || (b & (b-1))) {\n      return 0;\n   }\n\n   for (x = 0; x < DIGIT_BIT; x++) {\n      if (b == (((mp_digit)1)<<x)) {\n         *p = x;\n         return 1;\n      }\n   }\n   return 0;\n}\n\n/* single digit division (based on routine from MPI) */\nstatic int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)\n{\n  mp_int  q;\n  mp_word w;\n  mp_digit t;\n  int     res = MP_OKAY, ix;\n\n  /* cannot divide by zero */\n  if (b == 0) {\n     return MP_VAL;\n  }\n\n  /* quick outs */\n  if (b == 1 || mp_iszero(a) == MP_YES) {\n     if (d != NULL) {\n        *d = 0;\n     }\n     if (c != NULL) {\n        return mp_copy(a, c);\n     }\n     return MP_OKAY;\n  }\n\n  /* power of two ? */\n  if (s_is_power_of_two(b, &ix) == 1) {\n     if (d != NULL) {\n        *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);\n     }\n     if (c != NULL) {\n        return mp_div_2d(a, ix, c, NULL);\n     }\n     return MP_OKAY;\n  }\n\n#ifdef BN_MP_DIV_3_C\n  /* three? */\n  if (b == 3) {\n     return mp_div_3(a, c, d);\n  }\n#endif\n\n  /* no easy answer [c'est la vie].  Just division */\n  if (c != NULL) {\n      if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {\n         return res;\n      }\n\n      q.used = a->used;\n      q.sign = a->sign;\n  }\n  else {\n      if ((res = mp_init(&q)) != MP_OKAY) {\n         return res;\n      }\n  }\n\n\n  w = 0;\n  for (ix = a->used - 1; ix >= 0; ix--) {\n     w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);\n\n     if (w >= b) {\n        t = (mp_digit)(w / b);\n        w -= ((mp_word)t) * ((mp_word)b);\n      } else {\n        t = 0;\n      }\n      if (c != NULL)\n        q.dp[ix] = (mp_digit)t;\n  }\n\n  if (d != NULL) {\n     *d = (mp_digit)w;\n  }\n\n  if (c != NULL) {\n     mp_clamp(&q);\n     mp_exch(&q, c);\n  }\n  mp_clear(&q);\n\n  return res;\n}\n\n\nint mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)\n{\n  return mp_div_d(a, b, NULL, c);\n}\n\n#endif /* WOLFSSL_KEY_GEN || HAVE_COMP_KEY || HAVE_ECC || DEBUG_WOLFSSL */\n\n#if defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA)\n\nconst mp_digit ltm_prime_tab[PRIME_SIZE] = {\n  0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,\n  0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,\n  0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,\n  0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,\n#ifndef MP_8BIT\n  0x0083,\n  0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,\n  0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,\n  0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,\n  0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,\n\n  0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,\n  0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,\n  0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,\n  0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,\n  0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,\n  0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,\n  0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,\n  0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,\n\n  0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,\n  0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,\n  0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,\n  0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,\n  0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,\n  0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,\n  0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,\n  0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,\n\n  0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,\n  0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,\n  0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,\n  0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,\n  0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,\n  0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,\n  0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,\n  0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653\n#endif\n};\n\n\n/* Miller-Rabin test of \"a\" to the base of \"b\" as described in\n * HAC pp. 139 Algorithm 4.24\n *\n * Sets result to 0 if definitely composite or 1 if probably prime.\n * Randomly the chance of error is no more than 1/4 and often\n * very much lower.\n */\nstatic int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)\n{\n  mp_int  n1, y, r;\n  int     s, j, err;\n\n  /* default */\n  *result = MP_NO;\n\n  /* ensure b > 1 */\n  if (mp_cmp_d(b, 1) != MP_GT) {\n     return MP_VAL;\n  }\n\n  /* get n1 = a - 1 */\n  if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {\n    return err;\n  }\n  if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) {\n    goto LBL_N1;\n  }\n\n  /* set 2**s * r = n1 */\n  if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {\n    goto LBL_N1;\n  }\n\n  /* count the number of least significant bits\n   * which are zero\n   */\n  s = mp_cnt_lsb(&r);\n\n  /* now divide n - 1 by 2**s */\n  if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {\n    goto LBL_R;\n  }\n\n  /* compute y = b**r mod a */\n  if ((err = mp_init (&y)) != MP_OKAY) {\n    goto LBL_R;\n  }\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n#ifndef WOLFSSL_SP_NO_2048\n  if (mp_count_bits(a) == 1024)\n      err = sp_ModExp_1024(b, &r, a, &y);\n  else if (mp_count_bits(a) == 2048)\n      err = sp_ModExp_2048(b, &r, a, &y);\n  else\n#endif\n#ifndef WOLFSSL_SP_NO_3072\n  if (mp_count_bits(a) == 1536)\n      err = sp_ModExp_1536(b, &r, a, &y);\n  else if (mp_count_bits(a) == 3072)\n      err = sp_ModExp_3072(b, &r, a, &y);\n  else\n#endif\n#ifdef WOLFSSL_SP_4096\n  if (mp_count_bits(a) == 4096)\n      err = sp_ModExp_4096(b, &r, a, &y);\n  else\n#endif\n#endif\n      err = mp_exptmod (b, &r, a, &y);\n  if (err != MP_OKAY)\n      goto LBL_Y;\n\n  /* if y != 1 and y != n1 do */\n  if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) {\n    j = 1;\n    /* while j <= s-1 and y != n1 */\n    while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) {\n      if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) {\n         goto LBL_Y;\n      }\n\n      /* if y == 1 then composite */\n      if (mp_cmp_d (&y, 1) == MP_EQ) {\n         goto LBL_Y;\n      }\n\n      ++j;\n    }\n\n    /* if y != n1 then composite */\n    if (mp_cmp (&y, &n1) != MP_EQ) {\n      goto LBL_Y;\n    }\n  }\n\n  /* probably prime now */\n  *result = MP_YES;\nLBL_Y:mp_clear (&y);\nLBL_R:mp_clear (&r);\nLBL_N1:mp_clear (&n1);\n  return err;\n}\n\n\n/* determines if an integers is divisible by one\n * of the first PRIME_SIZE primes or not\n *\n * sets result to 0 if not, 1 if yes\n */\nstatic int mp_prime_is_divisible (mp_int * a, int *result)\n{\n  int     err, ix;\n  mp_digit res;\n\n  /* default to not */\n  *result = MP_NO;\n\n  for (ix = 0; ix < PRIME_SIZE; ix++) {\n    /* what is a mod LBL_prime_tab[ix] */\n    if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) {\n      return err;\n    }\n\n    /* is the residue zero? */\n    if (res == 0) {\n      *result = MP_YES;\n      return MP_OKAY;\n    }\n  }\n\n  return MP_OKAY;\n}\n\n/*\n * Sets result to 1 if probably prime, 0 otherwise\n */\nint mp_prime_is_prime (mp_int * a, int t, int *result)\n{\n  mp_int  b;\n  int     ix, err, res;\n\n  /* default to no */\n  *result = MP_NO;\n\n  /* valid value of t? */\n  if (t <= 0 || t > PRIME_SIZE) {\n    return MP_VAL;\n  }\n\n  if (mp_isone(a)) {\n      *result = MP_NO;\n      return MP_OKAY;\n  }\n\n  /* is the input equal to one of the primes in the table? */\n  for (ix = 0; ix < PRIME_SIZE; ix++) {\n      if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {\n         *result = MP_YES;\n         return MP_OKAY;\n      }\n  }\n\n  /* first perform trial division */\n  if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {\n    return err;\n  }\n\n  /* return if it was trivially divisible */\n  if (res == MP_YES) {\n    return MP_OKAY;\n  }\n\n  /* now perform the miller-rabin rounds */\n  if ((err = mp_init (&b)) != MP_OKAY) {\n    return err;\n  }\n\n  for (ix = 0; ix < t; ix++) {\n    /* set the prime */\n    if ((err = mp_set (&b, ltm_prime_tab[ix])) != MP_OKAY) {\n        goto LBL_B;\n    }\n\n    if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {\n      goto LBL_B;\n    }\n\n    if (res == MP_NO) {\n      goto LBL_B;\n    }\n  }\n\n  /* passed the test */\n  *result = MP_YES;\nLBL_B:mp_clear (&b);\n  return err;\n}\n\n\n/*\n * Sets result to 1 if probably prime, 0 otherwise\n */\nint mp_prime_is_prime_ex (mp_int * a, int t, int *result, WC_RNG *rng)\n{\n  mp_int  b, c;\n  int     ix, err, res;\n  byte*   base = NULL;\n  word32  baseSz = 0;\n\n  /* default to no */\n  *result = MP_NO;\n\n  /* valid value of t? */\n  if (t <= 0 || t > PRIME_SIZE) {\n    return MP_VAL;\n  }\n\n  if (mp_isone(a)) {\n    *result = MP_NO;\n    return MP_OKAY;\n  }\n\n  /* is the input equal to one of the primes in the table? */\n  for (ix = 0; ix < PRIME_SIZE; ix++) {\n      if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {\n         *result = MP_YES;\n         return MP_OKAY;\n      }\n  }\n\n  /* first perform trial division */\n  if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {\n    return err;\n  }\n\n  /* return if it was trivially divisible */\n  if (res == MP_YES) {\n    return MP_OKAY;\n  }\n\n  /* now perform the miller-rabin rounds */\n  if ((err = mp_init (&b)) != MP_OKAY) {\n    return err;\n  }\n  if ((err = mp_init (&c)) != MP_OKAY) {\n      mp_clear(&b);\n    return err;\n  }\n\n  baseSz = mp_count_bits(a);\n  baseSz = (baseSz / 8) + ((baseSz % 8) ? 1 : 0);\n\n  base = (byte*)XMALLOC(baseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n  if (base == NULL) {\n      err = MP_MEM;\n      goto LBL_B;\n  }\n\n  if ((err = mp_sub_d(a, 2, &c)) != MP_OKAY) {\n      goto LBL_B;\n  }\n\n /* now do a miller rabin with up to t random numbers, this should\n  * give a (1/4)^t chance of a false prime. */\n  for (ix = 0; ix < t; ix++) {\n    /* Set a test candidate. */\n    if ((err = wc_RNG_GenerateBlock(rng, base, baseSz)) != 0) {\n        goto LBL_B;\n    }\n\n    if ((err = mp_read_unsigned_bin(&b, base, baseSz)) != MP_OKAY) {\n        goto LBL_B;\n    }\n\n    if (mp_cmp_d(&b, 2) != MP_GT || mp_cmp(&b, &c) != MP_LT) {\n        ix--;\n        continue;\n    }\n\n    if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {\n      goto LBL_B;\n    }\n\n    if (res == MP_NO) {\n      goto LBL_B;\n    }\n  }\n\n  /* passed the test */\n  *result = MP_YES;\nLBL_B:mp_clear (&b);\n      mp_clear (&c);\n      XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n  return err;\n}\n\n#endif /* WOLFSSL_KEY_GEN NO_DH NO_DSA NO_RSA */\n\n#ifdef WOLFSSL_KEY_GEN\n\nstatic const int USE_BBS = 1;\n\nint mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap)\n{\n    int   err, res, type;\n    byte* buf;\n\n    if (N == NULL || rng == NULL)\n        return MP_VAL;\n\n    /* get type */\n    if (len < 0) {\n        type = USE_BBS;\n        len = -len;\n    } else {\n        type = 0;\n    }\n\n    /* allow sizes between 2 and 512 bytes for a prime size */\n    if (len < 2 || len > 512) {\n        return MP_VAL;\n    }\n\n    /* allocate buffer to work with */\n    buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_RSA);\n    if (buf == NULL) {\n        return MP_MEM;\n    }\n    XMEMSET(buf, 0, len);\n\n    do {\n#ifdef SHOW_GEN\n        printf(\".\");\n        fflush(stdout);\n#endif\n        /* generate value */\n        err = wc_RNG_GenerateBlock(rng, buf, len);\n        if (err != 0) {\n            XFREE(buf, heap, DYNAMIC_TYPE_RSA);\n            return err;\n        }\n\n        /* munge bits */\n        buf[0]     |= 0x80 | 0x40;\n        buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);\n\n        /* load value */\n        if ((err = mp_read_unsigned_bin(N, buf, len)) != MP_OKAY) {\n            XFREE(buf, heap, DYNAMIC_TYPE_RSA);\n            return err;\n        }\n\n        /* test */\n        /* Running Miller-Rabin up to 3 times gives us a 2^{-80} chance\n         * of a 1024-bit candidate being a false positive, when it is our\n         * prime candidate. (Note 4.49 of Handbook of Applied Cryptography.)\n         * Using 8 because we've always used 8. */\n        if ((err = mp_prime_is_prime_ex(N, 8, &res, rng)) != MP_OKAY) {\n            XFREE(buf, heap, DYNAMIC_TYPE_RSA);\n            return err;\n        }\n    } while (res == MP_NO);\n\n    XMEMSET(buf, 0, len);\n    XFREE(buf, heap, DYNAMIC_TYPE_RSA);\n\n    return MP_OKAY;\n}\n\n\n/* computes least common multiple as |a*b|/(a, b) */\nint mp_lcm (mp_int * a, mp_int * b, mp_int * c)\n{\n  int     res;\n  mp_int  t1, t2;\n\n\n  if ((res = mp_init_multi (&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {\n    return res;\n  }\n\n  /* t1 = get the GCD of the two inputs */\n  if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {\n    goto LBL_T;\n  }\n\n  /* divide the smallest by the GCD */\n  if (mp_cmp_mag(a, b) == MP_LT) {\n     /* store quotient in t2 such that t2 * b is the LCM */\n     if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {\n        goto LBL_T;\n     }\n     res = mp_mul(b, &t2, c);\n  } else {\n     /* store quotient in t2 such that t2 * a is the LCM */\n     if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {\n        goto LBL_T;\n     }\n     res = mp_mul(a, &t2, c);\n  }\n\n  /* fix the sign to positive */\n  c->sign = MP_ZPOS;\n\nLBL_T:\n  mp_clear(&t1);\n  mp_clear(&t2);\n  return res;\n}\n\n\n\n/* Greatest Common Divisor using the binary method */\nint mp_gcd (mp_int * a, mp_int * b, mp_int * c)\n{\n    mp_int  u, v;\n    int     k, u_lsb, v_lsb, res;\n\n    /* either zero than gcd is the largest */\n    if (mp_iszero (a) == MP_YES) {\n        return mp_abs (b, c);\n    }\n    if (mp_iszero (b) == MP_YES) {\n        return mp_abs (a, c);\n    }\n\n    /* get copies of a and b we can modify */\n    if ((res = mp_init_copy (&u, a)) != MP_OKAY) {\n        return res;\n    }\n\n    if ((res = mp_init_copy (&v, b)) != MP_OKAY) {\n        goto LBL_U;\n    }\n\n    /* must be positive for the remainder of the algorithm */\n    u.sign = v.sign = MP_ZPOS;\n\n    /* B1.  Find the common power of two for u and v */\n    u_lsb = mp_cnt_lsb(&u);\n    v_lsb = mp_cnt_lsb(&v);\n    k     = MIN(u_lsb, v_lsb);\n\n    if (k > 0) {\n        /* divide the power of two out */\n        if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {\n            goto LBL_V;\n        }\n\n        if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {\n            goto LBL_V;\n        }\n    }\n\n    /* divide any remaining factors of two out */\n    if (u_lsb != k) {\n        if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {\n            goto LBL_V;\n        }\n    }\n\n    if (v_lsb != k) {\n        if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {\n            goto LBL_V;\n        }\n    }\n\n    while (mp_iszero(&v) == MP_NO) {\n        /* make sure v is the largest */\n        if (mp_cmp_mag(&u, &v) == MP_GT) {\n            /* swap u and v to make sure v is >= u */\n            mp_exch(&u, &v);\n        }\n\n        /* subtract smallest from largest */\n        if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {\n            goto LBL_V;\n        }\n\n        /* Divide out all factors of two */\n        if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {\n            goto LBL_V;\n        }\n    }\n\n    /* multiply by 2**k which we divided out at the beginning */\n    if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {\n        goto LBL_V;\n    }\n    c->sign = MP_ZPOS;\n    res = MP_OKAY;\nLBL_V:mp_clear (&v);\nLBL_U:mp_clear (&u);\n    return res;\n}\n\n#endif /* WOLFSSL_KEY_GEN */\n\n\n#if !defined(NO_DSA) || defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || \\\n    defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) || \\\n    defined(DEBUG_WOLFSSL) || defined(OPENSSL_EXTRA)\n\n/* chars used in radix conversions */\nconst char *mp_s_rmap = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\\\n                         abcdefghijklmnopqrstuvwxyz+/\";\n#endif\n\n#if !defined(NO_DSA) || defined(HAVE_ECC)\n/* read a string [ASCII] in a given radix */\nint mp_read_radix (mp_int * a, const char *str, int radix)\n{\n  int     y, res, neg;\n  char    ch;\n\n  /* zero the digit bignum */\n  mp_zero(a);\n\n  /* make sure the radix is ok */\n  if (radix < MP_RADIX_BIN || radix > MP_RADIX_MAX) {\n    return MP_VAL;\n  }\n\n  /* if the leading digit is a\n   * minus set the sign to negative.\n   */\n  if (*str == '-') {\n    ++str;\n    neg = MP_NEG;\n  } else {\n    neg = MP_ZPOS;\n  }\n\n  /* set the integer to the default of zero */\n  mp_zero (a);\n\n  /* process each digit of the string */\n  while (*str != '\\0') {\n    /* if the radix <= 36 the conversion is case insensitive\n     * this allows numbers like 1AB and 1ab to represent the same  value\n     * [e.g. in hex]\n     */\n    ch = (radix <= 36) ? (char)XTOUPPER((unsigned char)*str) : *str;\n    for (y = 0; y < 64; y++) {\n      if (ch == mp_s_rmap[y]) {\n         break;\n      }\n    }\n\n    /* if the char was found in the map\n     * and is less than the given radix add it\n     * to the number, otherwise exit the loop.\n     */\n    if (y < radix) {\n      if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {\n         return res;\n      }\n      if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {\n         return res;\n      }\n    } else {\n      break;\n    }\n    ++str;\n  }\n\n  /* if digit in isn't null term, then invalid character was found */\n  if (*str != '\\0') {\n     mp_zero (a);\n     return MP_VAL;\n  }\n\n  /* set the sign only if a != 0 */\n  if (mp_iszero(a) != MP_YES) {\n     a->sign = neg;\n  }\n  return MP_OKAY;\n}\n#endif /* !defined(NO_DSA) || defined(HAVE_ECC) */\n\n#ifdef WC_MP_TO_RADIX\n\n/* returns size of ASCII representation */\nint mp_radix_size (mp_int *a, int radix, int *size)\n{\n    int     res, digs;\n    mp_int  t;\n    mp_digit d;\n\n    *size = 0;\n\n    /* special case for binary */\n    if (radix == MP_RADIX_BIN) {\n        *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;\n        return MP_OKAY;\n    }\n\n    /* make sure the radix is in range */\n    if (radix < MP_RADIX_BIN || radix > MP_RADIX_MAX) {\n        return MP_VAL;\n    }\n\n    if (mp_iszero(a) == MP_YES) {\n        *size = 2;\n        return MP_OKAY;\n    }\n\n    /* digs is the digit count */\n    digs = 0;\n\n    /* if it's negative add one for the sign */\n    if (a->sign == MP_NEG) {\n        ++digs;\n    }\n\n    /* init a copy of the input */\n    if ((res = mp_init_copy (&t, a)) != MP_OKAY) {\n        return res;\n    }\n\n    /* force temp to positive */\n    t.sign = MP_ZPOS;\n\n    /* fetch out all of the digits */\n    while (mp_iszero (&t) == MP_NO) {\n        if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {\n            mp_clear (&t);\n            return res;\n        }\n        ++digs;\n    }\n    mp_clear (&t);\n\n    /* return digs + 1, the 1 is for the NULL byte that would be required. */\n    *size = digs + 1;\n    return MP_OKAY;\n}\n\n/* stores a bignum as a ASCII string in a given radix (2..64) */\nint mp_toradix (mp_int *a, char *str, int radix)\n{\n    int     res, digs;\n    mp_int  t;\n    mp_digit d;\n    char   *_s = str;\n\n    /* check range of the radix */\n    if (radix < MP_RADIX_BIN || radix > MP_RADIX_MAX) {\n        return MP_VAL;\n    }\n\n    /* quick out if its zero */\n    if (mp_iszero(a) == MP_YES) {\n        *str++ = '0';\n        *str = '\\0';\n        return MP_OKAY;\n    }\n\n    if ((res = mp_init_copy (&t, a)) != MP_OKAY) {\n        return res;\n    }\n\n    /* if it is negative output a - */\n    if (t.sign == MP_NEG) {\n        ++_s;\n        *str++ = '-';\n        t.sign = MP_ZPOS;\n    }\n\n    digs = 0;\n    while (mp_iszero (&t) == MP_NO) {\n        if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {\n            mp_clear (&t);\n            return res;\n        }\n        *str++ = mp_s_rmap[d];\n        ++digs;\n    }\n#ifndef WC_DISABLE_RADIX_ZERO_PAD\n    /* For hexadecimal output, add zero padding when number of digits is odd */\n    if ((digs & 1) && (radix == 16)) {\n        *str++ = mp_s_rmap[0];\n        ++digs;\n    }\n#endif\n    /* reverse the digits of the string.  In this case _s points\n     * to the first digit [excluding the sign] of the number]\n     */\n    bn_reverse ((unsigned char *)_s, digs);\n\n    /* append a NULL so the string is properly terminated */\n    *str = '\\0';\n\n    mp_clear (&t);\n    return MP_OKAY;\n}\n\n#ifdef WOLFSSL_DEBUG_MATH\nvoid mp_dump(const char* desc, mp_int* a, byte verbose)\n{\n  char *buffer;\n  int size = a->alloc;\n\n  buffer = (char*)XMALLOC(size * sizeof(mp_digit) * 2, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n  if (buffer == NULL) {\n    return;\n  }\n\n  printf(\"%s: ptr=%p, used=%d, sign=%d, size=%d, mpd=%d\\n\",\n    desc, a, a->used, a->sign, size, (int)sizeof(mp_digit));\n\n  mp_tohex(a, buffer);\n  printf(\"  %s\\n  \", buffer);\n\n  if (verbose) {\n    int i;\n    for(i=0; i<a->alloc * (int)sizeof(mp_digit); i++) {\n      printf(\"%02x \", *(((byte*)a->dp) + i));\n    }\n    printf(\"\\n\");\n  }\n\n  XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n}\n#endif /* WOLFSSL_DEBUG_MATH */\n\n#endif /* WC_MP_TO_RADIX */\n\n#endif /* WOLFSSL_SP_MATH */\n\n#endif /* USE_FAST_MATH */\n\n#endif /* NO_BIG_INT */\n"
  },
  {
    "path": "src/wolfcrypt/src/logging.c",
    "content": "/* logging.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#include <wolfssl/wolfcrypt/logging.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)\n/* avoid adding WANT_READ and WANT_WRITE to error queue */\n#include <wolfssl/error-ssl.h>\n#endif\n\n#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)\nstatic wolfSSL_Mutex debug_mutex; /* mutex for access to debug structure */\n\n/* accessing any node from the queue should be wrapped in a lock of\n * debug_mutex */\nstatic void* wc_error_heap;\nstruct wc_error_queue {\n    void*  heap; /* the heap hint used with nodes creation */\n    struct wc_error_queue* next;\n    struct wc_error_queue* prev;\n    char   error[WOLFSSL_MAX_ERROR_SZ];\n    char   file[WOLFSSL_MAX_ERROR_SZ];\n    int    value;\n    int    line;\n};\nvolatile struct wc_error_queue* wc_errors;\nstatic struct wc_error_queue* wc_current_node;\nstatic struct wc_error_queue* wc_last_node;\n/* pointer to last node in queue to make insertion O(1) */\n#endif\n\n#ifdef WOLFSSL_FUNC_TIME\n/* WARNING: This code is only to be used for debugging performance.\n *          The code is not thread-safe.\n *          Do not use WOLFSSL_FUNC_TIME in production code.\n */\nstatic double wc_func_start[WC_FUNC_COUNT];\nstatic double wc_func_time[WC_FUNC_COUNT] = { 0, };\nstatic const char* wc_func_name[WC_FUNC_COUNT] = {\n    \"SendHelloRequest\",\n    \"DoHelloRequest\",\n    \"SendClientHello\",\n    \"DoClientHello\",\n    \"SendServerHello\",\n    \"DoServerHello\",\n    \"SendEncryptedExtensions\",\n    \"DoEncryptedExtensions\",\n    \"SendCertificateRequest\",\n    \"DoCertificateRequest\",\n    \"SendCertificate\",\n    \"DoCertificate\",\n    \"SendCertificateVerify\",\n    \"DoCertificateVerify\",\n    \"SendFinished\",\n    \"DoFinished\",\n    \"SendKeyUpdate\",\n    \"DoKeyUpdate\",\n    \"SendEarlyData\",\n    \"DoEarlyData\",\n    \"SendNewSessionTicket\",\n    \"DoNewSessionTicket\",\n    \"SendServerHelloDone\",\n    \"DoServerHelloDone\",\n    \"SendTicket\",\n    \"DoTicket\",\n    \"SendClientKeyExchange\",\n    \"DoClientKeyExchange\",\n    \"SendCertificateStatus\",\n    \"DoCertificateStatus\",\n    \"SendServerKeyExchange\",\n    \"DoServerKeyExchange\",\n    \"SendEarlyData\",\n    \"DoEarlyData\",\n};\n\n#include <sys/time.h>\n\n/* WARNING: This function is not portable. */\nstatic WC_INLINE double current_time(int reset)\n{\n    struct timeval tv;\n    gettimeofday(&tv, 0);\n    (void)reset;\n\n    return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;\n}\n#endif /* WOLFSSL_FUNC_TIME */\n\n#ifdef DEBUG_WOLFSSL\n\n/* Set these to default values initially. */\nstatic wolfSSL_Logging_cb log_function = NULL;\nstatic int loggingEnabled = 0;\n\n#if defined(WOLFSSL_APACHE_MYNEWT)\n#include \"log/log.h\"\nstatic struct log mynewt_log;\n#endif /* WOLFSSL_APACHE_MYNEWT */\n\n#endif /* DEBUG_WOLFSSL */\n\n\n/* allow this to be set to NULL, so logs can be redirected to default output */\nint wolfSSL_SetLoggingCb(wolfSSL_Logging_cb f)\n{\n#ifdef DEBUG_WOLFSSL\n    log_function = f;\n    return 0;\n#else\n    (void)f;\n    return NOT_COMPILED_IN;\n#endif\n}\n\n\nint wolfSSL_Debugging_ON(void)\n{\n#ifdef DEBUG_WOLFSSL\n    loggingEnabled = 1;\n#if defined(WOLFSSL_APACHE_MYNEWT)\n    log_register(\"wolfcrypt\", &mynewt_log, &log_console_handler, NULL, LOG_SYSLEVEL);\n#endif /* WOLFSSL_APACHE_MYNEWT */\n    return 0;\n#else\n    return NOT_COMPILED_IN;\n#endif\n}\n\n\nvoid wolfSSL_Debugging_OFF(void)\n{\n#ifdef DEBUG_WOLFSSL\n    loggingEnabled = 0;\n#endif\n}\n\n#ifdef WOLFSSL_FUNC_TIME\n/* WARNING: This code is only to be used for debugging performance.\n *          The code is not thread-safe.\n *          Do not use WOLFSSL_FUNC_TIME in production code.\n */\nvoid WOLFSSL_START(int funcNum)\n{\n    double now = current_time(0) * 1000.0;\n#ifdef WOLFSSL_FUNC_TIME_LOG\n    fprintf(stderr, \"%17.3f: START - %s\\n\", now, wc_func_name[funcNum]);\n#endif\n    wc_func_start[funcNum] = now;\n}\n\nvoid WOLFSSL_END(int funcNum)\n{\n    double now = current_time(0) * 1000.0;\n    wc_func_time[funcNum] += now - wc_func_start[funcNum];\n#ifdef WOLFSSL_FUNC_TIME_LOG\n    fprintf(stderr, \"%17.3f: END   - %s\\n\", now, wc_func_name[funcNum]);\n#endif\n}\n\nvoid WOLFSSL_TIME(int count)\n{\n    int i;\n    double avg, total = 0;\n\n    for (i = 0; i < WC_FUNC_COUNT; i++) {\n        if (wc_func_time[i] > 0) {\n            avg = wc_func_time[i] / count;\n            fprintf(stderr, \"%8.3f ms: %s\\n\", avg, wc_func_name[i]);\n            total += avg;\n        }\n    }\n    fprintf(stderr, \"%8.3f ms\\n\", total);\n}\n#endif\n\n#ifdef DEBUG_WOLFSSL\n\n#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)\n    /* see wc_port.h for fio.h and nio.h includes */\n#elif defined(WOLFSSL_SGX)\n    /* Declare sprintf for ocall */\n    int sprintf(char* buf, const char *fmt, ...);\n#elif defined(WOLFSSL_DEOS)\n#elif defined(MICRIUM)\n    #if (BSP_SER_COMM_EN  == DEF_ENABLED)\n        #include <bsp_ser.h>\n    #endif\n#elif defined(WOLFSSL_USER_LOG)\n    /* user includes their own headers */\n#elif defined(WOLFSSL_ESPIDF)\n    #include \"esp_types.h\"\n    #include \"esp_log.h\"\n#elif defined(WOLFSSL_TELIT_M2MB)\n    #include <stdio.h>\n    #include \"m2m_log.h\"\n#else\n    #include <stdio.h>   /* for default printf stuff */\n#endif\n\n#if defined(THREADX) && !defined(THREADX_NO_DC_PRINTF)\n    int dc_log_printf(char*, ...);\n#endif\n\nstatic void wolfssl_log(const int logLevel, const char *const logMessage)\n{\n    if (log_function)\n        log_function(logLevel, logMessage);\n    else {\n#if defined(WOLFSSL_USER_LOG)\n        WOLFSSL_USER_LOG(logMessage);\n#elif defined(WOLFSSL_LOG_PRINTF)\n        printf(\"%s\\n\", logMessage);\n\n#elif defined(THREADX) && !defined(THREADX_NO_DC_PRINTF)\n        dc_log_printf(\"%s\\n\", logMessage);\n#elif defined(WOLFSSL_DEOS)\n        printf(\"%s\\r\\n\", logMessage);\n#elif defined(MICRIUM)\n        BSP_Ser_Printf(\"%s\\r\\n\", logMessage);\n#elif defined(WOLFSSL_MDK_ARM)\n        fflush(stdout) ;\n        printf(\"%s\\n\", logMessage);\n        fflush(stdout) ;\n#elif defined(WOLFSSL_UTASKER)\n        fnDebugMsg((char*)logMessage);\n        fnDebugMsg(\"\\r\\n\");\n#elif defined(MQX_USE_IO_OLD)\n        fprintf(_mqxio_stderr, \"%s\\n\", logMessage);\n\n#elif defined(WOLFSSL_APACHE_MYNEWT)\n        LOG_DEBUG(&mynewt_log, LOG_MODULE_DEFAULT, \"%s\\n\", logMessage);\n#elif defined(WOLFSSL_ESPIDF)\n        ESP_LOGI(\"wolfssl\", \"%s\", logMessage);\n#elif defined(WOLFSSL_ZEPHYR)\n        printk(\"%s\\n\", logMessage);\n#elif defined(WOLFSSL_TELIT_M2MB)\n        M2M_LOG_INFO(\"%s\\n\", logMessage);\n#else\n        fprintf(stderr, \"%s\\n\", logMessage);\n#endif\n    }\n}\n\n#ifndef WOLFSSL_DEBUG_ERRORS_ONLY\nvoid WOLFSSL_MSG(const char* msg)\n{\n    if (loggingEnabled)\n        wolfssl_log(INFO_LOG , msg);\n}\n\n#ifndef LINE_LEN\n#define LINE_LEN 16\n#endif\nvoid WOLFSSL_BUFFER(const byte* buffer, word32 length)\n{\n    int i, buflen = (int)length, bufidx;\n    char line[(LINE_LEN * 4) + 3]; /* \\t00..0F | chars...chars\\0 */\n\n    if (!loggingEnabled) {\n        return;\n    }\n\n    if (!buffer) {\n        wolfssl_log(INFO_LOG, \"\\tNULL\");\n        return;\n    }\n\n    while (buflen > 0) {\n        bufidx = 0;\n        XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, \"\\t\");\n        bufidx++;\n\n        for (i = 0; i < LINE_LEN; i++) {\n            if (i < buflen) {\n                XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, \"%02x \", buffer[i]);\n            }\n            else {\n                XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, \"   \");\n            }\n            bufidx += 3;\n        }\n\n        XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, \"| \");\n        bufidx++;\n\n        for (i = 0; i < LINE_LEN; i++) {\n            if (i < buflen) {\n                XSNPRINTF(&line[bufidx], sizeof(line)-bufidx,\n                     \"%c\", 31 < buffer[i] && buffer[i] < 127 ? buffer[i] : '.');\n                bufidx++;\n            }\n        }\n\n        wolfssl_log(INFO_LOG, line);\n        buffer += LINE_LEN;\n        buflen -= LINE_LEN;\n    }\n}\n\n\nvoid WOLFSSL_ENTER(const char* msg)\n{\n    if (loggingEnabled) {\n        char buffer[WOLFSSL_MAX_ERROR_SZ];\n        XSNPRINTF(buffer, sizeof(buffer), \"wolfSSL Entering %s\", msg);\n        wolfssl_log(ENTER_LOG , buffer);\n    }\n}\n\n\nvoid WOLFSSL_LEAVE(const char* msg, int ret)\n{\n    if (loggingEnabled) {\n        char buffer[WOLFSSL_MAX_ERROR_SZ];\n        XSNPRINTF(buffer, sizeof(buffer), \"wolfSSL Leaving %s, return %d\",\n                msg, ret);\n        wolfssl_log(LEAVE_LOG , buffer);\n    }\n}\n#endif /* !WOLFSSL_DEBUG_ERRORS_ONLY */\n#endif /* DEBUG_WOLFSSL */\n\n/*\n * When using OPENSSL_EXTRA or DEBUG_WOLFSSL_VERBOSE macro then WOLFSSL_ERROR is\n * mapped to new funtion WOLFSSL_ERROR_LINE which gets the line # and function\n * name where WOLFSSL_ERROR is called at.\n */\n#if defined(DEBUG_WOLFSSL) || defined(OPENSSL_ALL) || \\\n    defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \\\n    defined(OPENSSL_EXTRA)\n\n#if (defined(OPENSSL_EXTRA) && !defined(_WIN32) && !defined(NO_ERROR_QUEUE)) \\\n    || defined(DEBUG_WOLFSSL_VERBOSE)\nvoid WOLFSSL_ERROR_LINE(int error, const char* func, unsigned int line,\n        const char* file, void* usrCtx)\n#else\nvoid WOLFSSL_ERROR(int error)\n#endif\n{\n#ifdef WOLFSSL_ASYNC_CRYPT\n    if (error != WC_PENDING_E)\n#endif\n    {\n        char buffer[WOLFSSL_MAX_ERROR_SZ];\n\n    #if (defined(OPENSSL_EXTRA) && !defined(_WIN32) && \\\n            !defined(NO_ERROR_QUEUE)) || defined(DEBUG_WOLFSSL_VERBOSE)\n        (void)usrCtx; /* a user ctx for future flexibility */\n        (void)func;\n\n        if (wc_LockMutex(&debug_mutex) != 0) {\n            WOLFSSL_MSG(\"Lock debug mutex failed\");\n            XSNPRINTF(buffer, sizeof(buffer),\n                    \"wolfSSL error occurred, error = %d\", error);\n        }\n        else {\n            #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)\n            /* If running in compatibility mode do not add want read and\n               want right to error queue */\n            if (error != WANT_READ && error != WANT_WRITE) {\n            #endif\n            if (error < 0)\n                error = error - (2 * error); /* get absolute value */\n            XSNPRINTF(buffer, sizeof(buffer),\n                    \"wolfSSL error occurred, error = %d line:%d file:%s\",\n                    error, line, file);\n            if (wc_AddErrorNode(error, line, buffer, (char*)file) != 0) {\n                WOLFSSL_MSG(\"Error creating logging node\");\n                /* with void function there is no return here, continue on\n                 * to unlock mutex and log what buffer was created. */\n            }\n            #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)\n            }\n            else {\n                XSNPRINTF(buffer, sizeof(buffer),\n                    \"wolfSSL error occurred, error = %d\", error);\n\n            }\n            #endif\n\n            wc_UnLockMutex(&debug_mutex);\n        }\n    #else\n        XSNPRINTF(buffer, sizeof(buffer),\n                \"wolfSSL error occurred, error = %d\", error);\n    #endif\n\n    #ifdef DEBUG_WOLFSSL\n        if (loggingEnabled)\n            wolfssl_log(ERROR_LOG , buffer);\n    #endif\n    }\n}\n\nvoid WOLFSSL_ERROR_MSG(const char* msg)\n{\n#ifdef DEBUG_WOLFSSL\n    if (loggingEnabled)\n        wolfssl_log(ERROR_LOG , msg);\n#else\n    (void)msg;\n#endif\n}\n\n#endif  /* DEBUG_WOLFSSL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */\n\n#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)\n/* Internal function that is called by wolfCrypt_Init() */\nint wc_LoggingInit(void)\n{\n    if (wc_InitMutex(&debug_mutex) != 0) {\n        WOLFSSL_MSG(\"Bad Init Mutex\");\n        return BAD_MUTEX_E;\n    }\n    wc_errors          = NULL;\n    wc_current_node    = NULL;\n    wc_last_node       = NULL;\n\n    return 0;\n}\n\n\n/* internal function that is called by wolfCrypt_Cleanup */\nint wc_LoggingCleanup(void)\n{\n    /* clear logging entries */\n    wc_ClearErrorNodes();\n\n    /* free mutex */\n    if (wc_FreeMutex(&debug_mutex) != 0) {\n        WOLFSSL_MSG(\"Bad Mutex free\");\n        return BAD_MUTEX_E;\n    }\n    return 0;\n}\n\n\n/* peek at an error node\n *\n * idx : if -1 then the most recent node is looked at, otherwise search\n *         through queue for node at the given index\n * file  : pointer to internal file string\n * reason : pointer to internal error reason\n * line  : line number that error happened at\n *\n * Returns a negative value in error case, on success returns the nodes error\n * value which is positve (absolute value)\n */\nint wc_PeekErrorNode(int idx, const char **file, const char **reason,\n        int *line)\n{\n    struct wc_error_queue* err;\n\n    if (wc_LockMutex(&debug_mutex) != 0) {\n        WOLFSSL_MSG(\"Lock debug mutex failed\");\n        return BAD_MUTEX_E;\n    }\n\n    if (idx < 0) {\n        err = wc_last_node;\n    }\n    else {\n        int i;\n\n        err = (struct wc_error_queue*)wc_errors;\n        for (i = 0; i < idx; i++) {\n            if (err == NULL) {\n                WOLFSSL_MSG(\"Error node not found. Bad index?\");\n                wc_UnLockMutex(&debug_mutex);\n                return BAD_FUNC_ARG;\n            }\n            err = err->next;\n        }\n    }\n\n    if (err == NULL) {\n        WOLFSSL_MSG(\"No Errors in queue\");\n        wc_UnLockMutex(&debug_mutex);\n        return BAD_STATE_E;\n    }\n\n    if (file != NULL) {\n        *file = err->file;\n    }\n\n    if (reason != NULL) {\n        *reason = err->error;\n    }\n\n    if (line != NULL) {\n        *line = err->line;\n    }\n\n    wc_UnLockMutex(&debug_mutex);\n\n    return err->value;\n}\n\n\n/* Pulls the current node from error queue and increments current state.\n * Note: this does not delete nodes because input arguments are pointing to\n *       node buffers.\n *\n * file   pointer to file that error was in. Can be NULL to return no file.\n * reason error string giving reason for error. Can be NULL to return no reason.\n * line   return line number of where error happened.\n *\n * returns the error value on success and BAD_MUTEX_E or BAD_STATE_E on failure\n */\nint wc_PullErrorNode(const char **file, const char **reason, int *line)\n{\n    struct wc_error_queue* err;\n    int value;\n\n    if (wc_LockMutex(&debug_mutex) != 0) {\n        WOLFSSL_MSG(\"Lock debug mutex failed\");\n        return BAD_MUTEX_E;\n    }\n\n    err = wc_current_node;\n    if (err == NULL) {\n        WOLFSSL_MSG(\"No Errors in queue\");\n        wc_UnLockMutex(&debug_mutex);\n        return BAD_STATE_E;\n    }\n\n    if (file != NULL) {\n        *file = err->file;\n    }\n\n    if (reason != NULL) {\n        *reason = err->error;\n    }\n\n    if (line != NULL) {\n        *line = err->line;\n    }\n\n    value = err->value;\n    wc_current_node = err->next;\n    wc_UnLockMutex(&debug_mutex);\n\n    return value;\n}\n\n\n/* create new error node and add it to the queue\n * buffers are assumed to be of size WOLFSSL_MAX_ERROR_SZ for this internal\n * function. debug_mutex should be locked before a call to this function. */\nint wc_AddErrorNode(int error, int line, char* buf, char* file)\n{\n#if defined(NO_ERROR_QUEUE)\n    (void)error;\n    (void)line;\n    (void)buf;\n    (void)file;\n    WOLFSSL_MSG(\"Error queue turned off, can not add nodes\");\n#else\n    struct wc_error_queue* err;\n    err = (struct wc_error_queue*)XMALLOC(\n            sizeof(struct wc_error_queue), wc_error_heap, DYNAMIC_TYPE_LOG);\n    if (err == NULL) {\n        WOLFSSL_MSG(\"Unable to create error node for log\");\n        return MEMORY_E;\n    }\n    else {\n        int sz;\n\n        XMEMSET(err, 0, sizeof(struct wc_error_queue));\n        err->heap = wc_error_heap;\n        sz = (int)XSTRLEN(buf);\n        if (sz > WOLFSSL_MAX_ERROR_SZ - 1) {\n            sz = WOLFSSL_MAX_ERROR_SZ - 1;\n        }\n        if (sz > 0) {\n            XMEMCPY(err->error, buf, sz);\n        }\n\n        sz = (int)XSTRLEN(file);\n        if (sz > WOLFSSL_MAX_ERROR_SZ - 1) {\n            sz = WOLFSSL_MAX_ERROR_SZ - 1;\n        }\n        if (sz > 0) {\n            XMEMCPY(err->file, file, sz);\n        }\n\n        err->value = error;\n        err->line  = line;\n\n        /* make sure is terminated */\n        err->error[WOLFSSL_MAX_ERROR_SZ - 1] = '\\0';\n        err->file[WOLFSSL_MAX_ERROR_SZ - 1]  = '\\0';\n\n\n        /* since is queue place new node at last of the list */\n        if (wc_last_node == NULL) {\n            /* case of first node added to queue */\n            if (wc_errors != NULL) {\n                /* check for unexpected case before over writing wc_errors */\n                WOLFSSL_MSG(\"ERROR in adding new node to logging queue!!\\n\");\n                /* In the event both wc_last_node and wc_errors are NULL, err\n                 * goes unassigned to external wc_errors, wc_last_node. Free\n                 * err in this instance since wc_ClearErrorNodes will not\n                 */\n                XFREE(err, wc_error_heap, DYNAMIC_TYPE_LOG);\n            }\n            else {\n                wc_errors    = err;\n                wc_last_node = err;\n                wc_current_node = err;\n            }\n        }\n        else {\n            wc_last_node->next = err;\n            err->prev = wc_last_node;\n            wc_last_node = err;\n\n            /* check the case where have read to the end of the queue and the\n             * current node to read needs updated */\n            if (wc_current_node == NULL) {\n                wc_current_node = err;\n            }\n        }\n    }\n#endif\n    return 0;\n}\n\n/* Removes the error node at the specified index.\n * idx : if -1 then the most recent node is looked at, otherwise search\n *         through queue for node at the given index\n */\nvoid wc_RemoveErrorNode(int idx)\n{\n    struct wc_error_queue* current;\n\n    if (wc_LockMutex(&debug_mutex) != 0) {\n        WOLFSSL_MSG(\"Lock debug mutex failed\");\n        return;\n    }\n\n    if (idx == -1)\n        current = wc_last_node;\n    else {\n        current = (struct wc_error_queue*)wc_errors;\n        for (; current != NULL && idx > 0; idx--)\n             current = current->next;\n    }\n    if (current != NULL) {\n        if (current->prev != NULL)\n            current->prev->next = current->next;\n        if (current->next != NULL)\n            current->next->prev = current->prev;\n        if (wc_last_node == current)\n            wc_last_node = current->prev;\n        if (wc_errors == current)\n            wc_errors = current->next;\n        if (wc_current_node == current)\n            wc_current_node = current->next;\n        XFREE(current, current->heap, DYNAMIC_TYPE_LOG);\n    }\n\n    wc_UnLockMutex(&debug_mutex);\n}\n\n\n/* Clears out the list of error nodes.\n */\nvoid wc_ClearErrorNodes(void)\n{\n#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \\\n    defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)\n\n    if (wc_LockMutex(&debug_mutex) != 0) {\n        WOLFSSL_MSG(\"Lock debug mutex failed\");\n        return;\n    }\n\n    /* free all nodes from error queue */\n    {\n        struct wc_error_queue* current;\n        struct wc_error_queue* next;\n\n        current = (struct wc_error_queue*)wc_errors;\n        while (current != NULL) {\n            next = current->next;\n            XFREE(current, current->heap, DYNAMIC_TYPE_LOG);\n            current = next;\n        }\n    }\n\n    wc_errors       = NULL;\n    wc_last_node    = NULL;\n    wc_current_node = NULL;\n    wc_UnLockMutex(&debug_mutex);\n#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */\n}\n\nint wc_SetLoggingHeap(void* h)\n{\n    if (wc_LockMutex(&debug_mutex) != 0) {\n        WOLFSSL_MSG(\"Lock debug mutex failed\");\n        return BAD_MUTEX_E;\n    }\n    wc_error_heap = h;\n    wc_UnLockMutex(&debug_mutex);\n    return 0;\n}\n\n\n/* frees all nodes in the queue\n *\n * id  this is the thread id\n */\nint wc_ERR_remove_state(void)\n{\n    struct wc_error_queue* current;\n    struct wc_error_queue* next;\n\n    if (wc_LockMutex(&debug_mutex) != 0) {\n        WOLFSSL_MSG(\"Lock debug mutex failed\");\n        return BAD_MUTEX_E;\n    }\n\n    /* free all nodes from error queue */\n    current = (struct wc_error_queue*)wc_errors;\n    while (current != NULL) {\n        next = current->next;\n        XFREE(current, current->heap, DYNAMIC_TYPE_LOG);\n        current = next;\n    }\n\n    wc_errors          = NULL;\n    wc_last_node       = NULL;\n\n    wc_UnLockMutex(&debug_mutex);\n\n    return 0;\n}\n\n\n#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)\n/* empties out the error queue into the file */\nvoid wc_ERR_print_errors_fp(XFILE fp)\n{\n    WOLFSSL_ENTER(\"wc_ERR_print_errors_fp\");\n\n        if (wc_LockMutex(&debug_mutex) != 0)\n        {\n            WOLFSSL_MSG(\"Lock debug mutex failed\");\n        }\n        else\n        {\n            /* free all nodes from error queue and print them to file */\n            {\n                struct wc_error_queue *current;\n                struct wc_error_queue *next;\n\n                current = (struct wc_error_queue *)wc_errors;\n                while (current != NULL)\n                {\n                    next = current->next;\n                    fprintf(fp, \"%s\\n\", current->error);\n                    XFREE(current, current->heap, DYNAMIC_TYPE_LOG);\n                    current = next;\n                }\n\n                /* set global pointers to match having been freed */\n                wc_errors = NULL;\n                wc_last_node = NULL;\n            }\n\n            wc_UnLockMutex(&debug_mutex);\n        }\n}\n#endif /* !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) */\n\n#endif /* defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) */\n"
  },
  {
    "path": "src/wolfcrypt/src/md2.c",
    "content": "/* md2.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef WOLFSSL_MD2\n\n#include <wolfssl/wolfcrypt/md2.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\nvoid wc_InitMd2(Md2* md2)\n{\n    XMEMSET(md2->X, 0, MD2_X_SIZE);\n    XMEMSET(md2->C, 0, MD2_BLOCK_SIZE);\n    XMEMSET(md2->buffer, 0, MD2_BLOCK_SIZE);\n    md2->count = 0;\n}\n\n\nvoid wc_Md2Update(Md2* md2, const byte* data, word32 len)\n{\n    static const byte S[256] =\n    {\n        41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,\n        19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,\n        76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,\n        138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,\n        245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,\n        148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,\n        39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,\n        181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,\n        150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,\n        112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,\n        96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,\n        85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,\n        234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,\n        129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,\n        8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,\n        203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,\n        166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,\n        31, 26, 219, 153, 141, 51, 159, 17, 131, 20\n    };\n\n    while (len) {\n        word32 L = (MD2_PAD_SIZE - md2->count) < len ?\n                   (MD2_PAD_SIZE - md2->count) : len;\n        XMEMCPY(md2->buffer + md2->count, data, L);\n        md2->count += L;\n        data += L;\n        len  -= L;\n\n        if (md2->count == MD2_PAD_SIZE) {\n            int  i;\n            byte t;\n\n            md2->count = 0;\n            XMEMCPY(md2->X + MD2_PAD_SIZE, md2->buffer, MD2_PAD_SIZE);\n            t = md2->C[15];\n\n            for(i = 0; i < MD2_PAD_SIZE; i++) {\n                md2->X[32 + i] = md2->X[MD2_PAD_SIZE + i] ^ md2->X[i];\n                t = md2->C[i] ^= S[md2->buffer[i] ^ t];\n            }\n\n            t=0;\n            for(i = 0; i < 18; i++) {\n                int j;\n                for(j = 0; j < MD2_X_SIZE; j += 8) {\n                    t = md2->X[j+0] ^= S[t];\n                    t = md2->X[j+1] ^= S[t];\n                    t = md2->X[j+2] ^= S[t];\n                    t = md2->X[j+3] ^= S[t];\n                    t = md2->X[j+4] ^= S[t];\n                    t = md2->X[j+5] ^= S[t];\n                    t = md2->X[j+6] ^= S[t];\n                    t = md2->X[j+7] ^= S[t];\n                }\n                t = (t + i) & 0xFF;\n            }\n        }\n    }\n}\n\n\nvoid wc_Md2Final(Md2* md2, byte* hash)\n{\n    byte   padding[MD2_BLOCK_SIZE];\n    word32 padLen = MD2_PAD_SIZE - md2->count;\n    word32 i;\n\n    for (i = 0; i < padLen; i++)\n        padding[i] = (byte)padLen;\n\n    wc_Md2Update(md2, padding, padLen);\n    wc_Md2Update(md2, md2->C, MD2_BLOCK_SIZE);\n\n    XMEMCPY(hash, md2->X, MD2_DIGEST_SIZE);\n\n    wc_InitMd2(md2);\n}\n\n\nint wc_Md2Hash(const byte* data, word32 len, byte* hash)\n{\n#ifdef WOLFSSL_SMALL_STACK\n    Md2* md2;\n#else\n    Md2 md2[1];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    md2 = (Md2*)XMALLOC(sizeof(Md2), NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (md2 == NULL)\n        return MEMORY_E;\n#endif\n\n    wc_InitMd2(md2);\n    wc_Md2Update(md2, data, len);\n    wc_Md2Final(md2, hash);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(md2, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return 0;\n}\n\n\n#endif /* WOLFSSL_MD2 */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/md4.c",
    "content": "/* md4.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifndef NO_MD4\n\n#include <wolfssl/wolfcrypt/md4.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\nvoid wc_InitMd4(Md4* md4)\n{\n    md4->digest[0] = 0x67452301L;\n    md4->digest[1] = 0xefcdab89L;\n    md4->digest[2] = 0x98badcfeL;\n    md4->digest[3] = 0x10325476L;\n\n    md4->buffLen = 0;\n    md4->loLen   = 0;\n    md4->hiLen   = 0;\n}\n\n\nstatic void Transform(Md4* md4)\n{\n#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))\n#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))\n#define H(x, y, z) ((x) ^ (y) ^ (z))\n\n    /* Copy context->state[] to working vars  */\n    word32 A = md4->digest[0];\n    word32 B = md4->digest[1];\n    word32 C = md4->digest[2];\n    word32 D = md4->digest[3];\n\n#define function(a,b,c,d,k,s) a=rotlFixed(a+F(b,c,d)+md4->buffer[k],s);\n    function(A,B,C,D, 0, 3);\n    function(D,A,B,C, 1, 7);\n    function(C,D,A,B, 2,11);\n    function(B,C,D,A, 3,19);\n    function(A,B,C,D, 4, 3);\n    function(D,A,B,C, 5, 7);\n    function(C,D,A,B, 6,11);\n    function(B,C,D,A, 7,19);\n    function(A,B,C,D, 8, 3);\n    function(D,A,B,C, 9, 7);\n    function(C,D,A,B,10,11);\n    function(B,C,D,A,11,19);\n    function(A,B,C,D,12, 3);\n    function(D,A,B,C,13, 7);\n    function(C,D,A,B,14,11);\n    function(B,C,D,A,15,19);\n\n#undef function\n#define function(a,b,c,d,k,s) \\\n    a=rotlFixed(a+G(b,c,d)+md4->buffer[k]+0x5a827999,s);\n\n    function(A,B,C,D, 0, 3);\n    function(D,A,B,C, 4, 5);\n    function(C,D,A,B, 8, 9);\n    function(B,C,D,A,12,13);\n    function(A,B,C,D, 1, 3);\n    function(D,A,B,C, 5, 5);\n    function(C,D,A,B, 9, 9);\n    function(B,C,D,A,13,13);\n    function(A,B,C,D, 2, 3);\n    function(D,A,B,C, 6, 5);\n    function(C,D,A,B,10, 9);\n    function(B,C,D,A,14,13);\n    function(A,B,C,D, 3, 3);\n    function(D,A,B,C, 7, 5);\n    function(C,D,A,B,11, 9);\n    function(B,C,D,A,15,13);\n\n#undef function\n#define function(a,b,c,d,k,s) \\\n    a=rotlFixed(a+H(b,c,d)+md4->buffer[k]+0x6ed9eba1,s);\n\n    function(A,B,C,D, 0, 3);\n    function(D,A,B,C, 8, 9);\n    function(C,D,A,B, 4,11);\n    function(B,C,D,A,12,15);\n    function(A,B,C,D, 2, 3);\n    function(D,A,B,C,10, 9);\n    function(C,D,A,B, 6,11);\n    function(B,C,D,A,14,15);\n    function(A,B,C,D, 1, 3);\n    function(D,A,B,C, 9, 9);\n    function(C,D,A,B, 5,11);\n    function(B,C,D,A,13,15);\n    function(A,B,C,D, 3, 3);\n    function(D,A,B,C,11, 9);\n    function(C,D,A,B, 7,11);\n    function(B,C,D,A,15,15);\n\n    /* Add the working vars back into digest state[]  */\n    md4->digest[0] += A;\n    md4->digest[1] += B;\n    md4->digest[2] += C;\n    md4->digest[3] += D;\n}\n\n\nstatic WC_INLINE void AddLength(Md4* md4, word32 len)\n{\n    word32 tmp = md4->loLen;\n    if ( (md4->loLen += len) < tmp)\n        md4->hiLen++;                       /* carry low to high */\n}\n\n\nvoid wc_Md4Update(Md4* md4, const byte* data, word32 len)\n{\n    /* do block size increments */\n    byte* local = (byte*)md4->buffer;\n\n    while (len) {\n        word32 add = min(len, MD4_BLOCK_SIZE - md4->buffLen);\n        XMEMCPY(&local[md4->buffLen], data, add);\n\n        md4->buffLen += add;\n        data         += add;\n        len          -= add;\n\n        if (md4->buffLen == MD4_BLOCK_SIZE) {\n            #ifdef BIG_ENDIAN_ORDER\n                ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE);\n            #endif\n            Transform(md4);\n            AddLength(md4, MD4_BLOCK_SIZE);\n            md4->buffLen = 0;\n        }\n    }\n}\n\n\nvoid wc_Md4Final(Md4* md4, byte* hash)\n{\n    byte* local = (byte*)md4->buffer;\n\n    AddLength(md4, md4->buffLen);               /* before adding pads */\n\n    local[md4->buffLen++] = 0x80;  /* add 1 */\n\n    /* pad with zeros */\n    if (md4->buffLen > MD4_PAD_SIZE) {\n        XMEMSET(&local[md4->buffLen], 0, MD4_BLOCK_SIZE - md4->buffLen);\n        md4->buffLen += MD4_BLOCK_SIZE - md4->buffLen;\n\n        #ifdef BIG_ENDIAN_ORDER\n            ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE);\n        #endif\n        Transform(md4);\n        md4->buffLen = 0;\n    }\n    XMEMSET(&local[md4->buffLen], 0, MD4_PAD_SIZE - md4->buffLen);\n\n    /* put lengths in bits */\n    md4->hiLen = (md4->loLen >> (8*sizeof(md4->loLen) - 3)) +\n                 (md4->hiLen << 3);\n    md4->loLen = md4->loLen << 3;\n\n    /* store lengths */\n    #ifdef BIG_ENDIAN_ORDER\n        ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE);\n    #endif\n    /* ! length ordering dependent on digest endian type ! */\n    XMEMCPY(&local[MD4_PAD_SIZE], &md4->loLen, sizeof(word32));\n    XMEMCPY(&local[MD4_PAD_SIZE + sizeof(word32)], &md4->hiLen, sizeof(word32));\n\n    Transform(md4);\n    #ifdef BIG_ENDIAN_ORDER\n        ByteReverseWords(md4->digest, md4->digest, MD4_DIGEST_SIZE);\n    #endif\n    XMEMCPY(hash, md4->digest, MD4_DIGEST_SIZE);\n\n    wc_InitMd4(md4);  /* reset state */\n}\n\n\n#endif /* NO_MD4 */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/md5.c",
    "content": "/* md5.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if !defined(NO_MD5)\n\n#if defined(WOLFSSL_TI_HASH)\n/* #include <wolfcrypt/src/port/ti/ti-hash.c> included by wc_port.c */\n\n#else\n\n#include <wolfssl/wolfcrypt/md5.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#include <wolfssl/wolfcrypt/hash.h>\n\n#ifdef NO_INLINE\n#include <wolfssl/wolfcrypt/misc.h>\n#else\n#define WOLFSSL_MISC_INCLUDED\n#include <wolfcrypt/src/misc.c>\n#endif\n\n\n/* Hardware Acceleration */\n#if defined(STM32_HASH)\n\n/* Supports CubeMX HAL or Standard Peripheral Library */\n#define HAVE_MD5_CUST_API\n\nint wc_InitMd5_ex(wc_Md5* md5, void* heap, int devId)\n{\n    if (md5 == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    (void)devId;\n    (void)heap;\n\n    wc_Stm32_Hash_Init(&md5->stmCtx);\n\n    return 0;\n}\n\nint wc_Md5Update(wc_Md5* md5, const byte* data, word32 len)\n{\n    int ret;\n\n    if (md5 == NULL || (data == NULL && len > 0)) {\n        return BAD_FUNC_ARG;\n    }\n\n    ret = wolfSSL_CryptHwMutexLock();\n    if (ret == 0) {\n        ret = wc_Stm32_Hash_Update(&md5->stmCtx, HASH_AlgoSelection_MD5,\n                                   data, len);\n        wolfSSL_CryptHwMutexUnLock();\n    }\n    return ret;\n}\n\nint wc_Md5Final(wc_Md5* md5, byte* hash)\n{\n    int ret;\n\n    if (md5 == NULL || hash == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    ret = wolfSSL_CryptHwMutexLock();\n    if (ret == 0) {\n        ret = wc_Stm32_Hash_Final(&md5->stmCtx, HASH_AlgoSelection_MD5,\n                                  hash, WC_MD5_DIGEST_SIZE);\n        wolfSSL_CryptHwMutexUnLock();\n    }\n\n    (void)wc_InitMd5(md5);  /* reset state */\n\n    return ret;\n}\n\n#elif defined(FREESCALE_MMCAU_SHA)\n\n#ifdef FREESCALE_MMCAU_CLASSIC_SHA\n    #include \"cau_api.h\"\n#else\n    #include \"fsl_mmcau.h\"\n#endif\n\n#define XTRANSFORM(S,B)       Transform((S), (B))\n#define XTRANSFORM_LEN(S,B,L) Transform_Len((S), (B), (L))\n\n#ifndef WC_HASH_DATA_ALIGNMENT\n    /* these hardware API's require 4 byte (word32) alignment */\n    #define WC_HASH_DATA_ALIGNMENT 4\n#endif\n\nstatic int Transform(wc_Md5* md5, const byte* data)\n{\n    int ret = wolfSSL_CryptHwMutexLock();\n    if (ret == 0) {\n#ifdef FREESCALE_MMCAU_CLASSIC_SHA\n        cau_md5_hash_n((byte*)data, 1, (unsigned char*)md5->digest);\n#else\n        MMCAU_MD5_HashN((byte*)data, 1, (uint32_t*)md5->digest);\n#endif\n        wolfSSL_CryptHwMutexUnLock();\n    }\n    return ret;\n}\n\nstatic int Transform_Len(wc_Md5* md5, const byte* data, word32 len)\n{\n    int ret = wolfSSL_CryptHwMutexLock();\n    if (ret == 0) {\n    #if defined(WC_HASH_DATA_ALIGNMENT) && WC_HASH_DATA_ALIGNMENT > 0\n        if ((size_t)data % WC_HASH_DATA_ALIGNMENT) {\n            /* data pointer is NOT aligned,\n             * so copy and perform one block at a time */\n            byte* local = (byte*)md5->buffer;\n            while (len >= WC_MD5_BLOCK_SIZE) {\n                XMEMCPY(local, data, WC_MD5_BLOCK_SIZE);\n            #ifdef FREESCALE_MMCAU_CLASSIC_SHA\n                cau_md5_hash_n(local, 1, (unsigned char*)md5->digest);\n            #else\n                MMCAU_MD5_HashN(local, 1, (uint32_t*)md5->digest);\n            #endif\n                data += WC_MD5_BLOCK_SIZE;\n                len  -= WC_MD5_BLOCK_SIZE;\n            }\n        }\n        else\n    #endif\n        {\n#ifdef FREESCALE_MMCAU_CLASSIC_SHA\n        cau_md5_hash_n((byte*)data, len / WC_MD5_BLOCK_SIZE,\n            (unsigned char*)md5->digest);\n#else\n        MMCAU_MD5_HashN((byte*)data, len / WC_MD5_BLOCK_SIZE,\n            (uint32_t*)md5->digest);\n#endif\n        }\n        wolfSSL_CryptHwMutexUnLock();\n    }\n    return ret;\n}\n\n#elif defined(WOLFSSL_PIC32MZ_HASH)\n#include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>\n#define HAVE_MD5_CUST_API\n\n#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)\n/* functions implemented in wolfcrypt/src/port/caam/caam_sha.c */\n#define HAVE_MD5_CUST_API\n#else\n#define NEED_SOFT_MD5\n#endif /* End Hardware Acceleration */\n\n#ifdef NEED_SOFT_MD5\n\n#define XTRANSFORM(S,B)  Transform((S),(B))\n\n#define F1(x, y, z) (z ^ (x & (y ^ z)))\n#define F2(x, y, z) F1(z, x, y)\n#define F3(x, y, z) (x ^ y ^ z)\n#define F4(x, y, z) (y ^ (x | ~z))\n\n#define MD5STEP(f, w, x, y, z, data, s) \\\n        w = rotlFixed(w + f(x, y, z) + data, s) + x\n\nstatic int Transform(wc_Md5* md5, const byte* data)\n{\n    word32* buffer = (word32*)data;\n    /* Copy context->state[] to working vars  */\n    word32 a = md5->digest[0];\n    word32 b = md5->digest[1];\n    word32 c = md5->digest[2];\n    word32 d = md5->digest[3];\n\n    MD5STEP(F1, a, b, c, d, buffer[0]  + 0xd76aa478,  7);\n    MD5STEP(F1, d, a, b, c, buffer[1]  + 0xe8c7b756, 12);\n    MD5STEP(F1, c, d, a, b, buffer[2]  + 0x242070db, 17);\n    MD5STEP(F1, b, c, d, a, buffer[3]  + 0xc1bdceee, 22);\n    MD5STEP(F1, a, b, c, d, buffer[4]  + 0xf57c0faf,  7);\n    MD5STEP(F1, d, a, b, c, buffer[5]  + 0x4787c62a, 12);\n    MD5STEP(F1, c, d, a, b, buffer[6]  + 0xa8304613, 17);\n    MD5STEP(F1, b, c, d, a, buffer[7]  + 0xfd469501, 22);\n    MD5STEP(F1, a, b, c, d, buffer[8]  + 0x698098d8,  7);\n    MD5STEP(F1, d, a, b, c, buffer[9]  + 0x8b44f7af, 12);\n    MD5STEP(F1, c, d, a, b, buffer[10] + 0xffff5bb1, 17);\n    MD5STEP(F1, b, c, d, a, buffer[11] + 0x895cd7be, 22);\n    MD5STEP(F1, a, b, c, d, buffer[12] + 0x6b901122,  7);\n    MD5STEP(F1, d, a, b, c, buffer[13] + 0xfd987193, 12);\n    MD5STEP(F1, c, d, a, b, buffer[14] + 0xa679438e, 17);\n    MD5STEP(F1, b, c, d, a, buffer[15] + 0x49b40821, 22);\n\n    MD5STEP(F2, a, b, c, d, buffer[1]  + 0xf61e2562,  5);\n    MD5STEP(F2, d, a, b, c, buffer[6]  + 0xc040b340,  9);\n    MD5STEP(F2, c, d, a, b, buffer[11] + 0x265e5a51, 14);\n    MD5STEP(F2, b, c, d, a, buffer[0]  + 0xe9b6c7aa, 20);\n    MD5STEP(F2, a, b, c, d, buffer[5]  + 0xd62f105d,  5);\n    MD5STEP(F2, d, a, b, c, buffer[10] + 0x02441453,  9);\n    MD5STEP(F2, c, d, a, b, buffer[15] + 0xd8a1e681, 14);\n    MD5STEP(F2, b, c, d, a, buffer[4]  + 0xe7d3fbc8, 20);\n    MD5STEP(F2, a, b, c, d, buffer[9]  + 0x21e1cde6,  5);\n    MD5STEP(F2, d, a, b, c, buffer[14] + 0xc33707d6,  9);\n    MD5STEP(F2, c, d, a, b, buffer[3]  + 0xf4d50d87, 14);\n    MD5STEP(F2, b, c, d, a, buffer[8]  + 0x455a14ed, 20);\n    MD5STEP(F2, a, b, c, d, buffer[13] + 0xa9e3e905,  5);\n    MD5STEP(F2, d, a, b, c, buffer[2]  + 0xfcefa3f8,  9);\n    MD5STEP(F2, c, d, a, b, buffer[7]  + 0x676f02d9, 14);\n    MD5STEP(F2, b, c, d, a, buffer[12] + 0x8d2a4c8a, 20);\n\n    MD5STEP(F3, a, b, c, d, buffer[5]  + 0xfffa3942,  4);\n    MD5STEP(F3, d, a, b, c, buffer[8]  + 0x8771f681, 11);\n    MD5STEP(F3, c, d, a, b, buffer[11] + 0x6d9d6122, 16);\n    MD5STEP(F3, b, c, d, a, buffer[14] + 0xfde5380c, 23);\n    MD5STEP(F3, a, b, c, d, buffer[1]  + 0xa4beea44,  4);\n    MD5STEP(F3, d, a, b, c, buffer[4]  + 0x4bdecfa9, 11);\n    MD5STEP(F3, c, d, a, b, buffer[7]  + 0xf6bb4b60, 16);\n    MD5STEP(F3, b, c, d, a, buffer[10] + 0xbebfbc70, 23);\n    MD5STEP(F3, a, b, c, d, buffer[13] + 0x289b7ec6,  4);\n    MD5STEP(F3, d, a, b, c, buffer[0]  + 0xeaa127fa, 11);\n    MD5STEP(F3, c, d, a, b, buffer[3]  + 0xd4ef3085, 16);\n    MD5STEP(F3, b, c, d, a, buffer[6]  + 0x04881d05, 23);\n    MD5STEP(F3, a, b, c, d, buffer[9]  + 0xd9d4d039,  4);\n    MD5STEP(F3, d, a, b, c, buffer[12] + 0xe6db99e5, 11);\n    MD5STEP(F3, c, d, a, b, buffer[15] + 0x1fa27cf8, 16);\n    MD5STEP(F3, b, c, d, a, buffer[2]  + 0xc4ac5665, 23);\n\n    MD5STEP(F4, a, b, c, d, buffer[0]  + 0xf4292244,  6);\n    MD5STEP(F4, d, a, b, c, buffer[7]  + 0x432aff97, 10);\n    MD5STEP(F4, c, d, a, b, buffer[14] + 0xab9423a7, 15);\n    MD5STEP(F4, b, c, d, a, buffer[5]  + 0xfc93a039, 21);\n    MD5STEP(F4, a, b, c, d, buffer[12] + 0x655b59c3,  6);\n    MD5STEP(F4, d, a, b, c, buffer[3]  + 0x8f0ccc92, 10);\n    MD5STEP(F4, c, d, a, b, buffer[10] + 0xffeff47d, 15);\n    MD5STEP(F4, b, c, d, a, buffer[1]  + 0x85845dd1, 21);\n    MD5STEP(F4, a, b, c, d, buffer[8]  + 0x6fa87e4f,  6);\n    MD5STEP(F4, d, a, b, c, buffer[15] + 0xfe2ce6e0, 10);\n    MD5STEP(F4, c, d, a, b, buffer[6]  + 0xa3014314, 15);\n    MD5STEP(F4, b, c, d, a, buffer[13] + 0x4e0811a1, 21);\n    MD5STEP(F4, a, b, c, d, buffer[4]  + 0xf7537e82,  6);\n    MD5STEP(F4, d, a, b, c, buffer[11] + 0xbd3af235, 10);\n    MD5STEP(F4, c, d, a, b, buffer[2]  + 0x2ad7d2bb, 15);\n    MD5STEP(F4, b, c, d, a, buffer[9]  + 0xeb86d391, 21);\n\n    /* Add the working vars back into digest state[]  */\n    md5->digest[0] += a;\n    md5->digest[1] += b;\n    md5->digest[2] += c;\n    md5->digest[3] += d;\n\n    return 0;\n}\n#endif /* NEED_SOFT_MD5 */\n\n#ifndef HAVE_MD5_CUST_API\n\nstatic WC_INLINE void AddLength(wc_Md5* md5, word32 len)\n{\n    word32 tmp = md5->loLen;\n    if ((md5->loLen += len) < tmp) {\n        md5->hiLen++;                       /* carry low to high */\n    }\n}\n\nstatic int _InitMd5(wc_Md5* md5)\n{\n    int ret = 0;\n\n    md5->digest[0] = 0x67452301L;\n    md5->digest[1] = 0xefcdab89L;\n    md5->digest[2] = 0x98badcfeL;\n    md5->digest[3] = 0x10325476L;\n\n    md5->buffLen = 0;\n    md5->loLen   = 0;\n    md5->hiLen   = 0;\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    md5->flags = 0;\n#endif\n\n    return ret;\n}\n\nint wc_InitMd5_ex(wc_Md5* md5, void* heap, int devId)\n{\n    int ret = 0;\n\n    if (md5 == NULL)\n        return BAD_FUNC_ARG;\n\n    md5->heap = heap;\n\n    ret = _InitMd5(md5);\n    if (ret != 0)\n        return ret;\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5)\n    ret = wolfAsync_DevCtxInit(&md5->asyncDev, WOLFSSL_ASYNC_MARKER_MD5,\n                               md5->heap, devId);\n#else\n    (void)devId;\n#endif\n    return ret;\n}\n\n/* do block size increments/updates */\nint wc_Md5Update(wc_Md5* md5, const byte* data, word32 len)\n{\n    int ret = 0;\n    word32 blocksLen;\n    byte* local;\n\n    if (md5 == NULL || (data == NULL && len > 0)) {\n        return BAD_FUNC_ARG;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5)\n    if (md5->asyncDev.marker == WOLFSSL_ASYNC_MARKER_MD5) {\n#if defined(HAVE_INTEL_QA)\n        return IntelQaSymMd5(&md5->asyncDev, NULL, data, len);\n#endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    /* check that internal buffLen is valid */\n    if (md5->buffLen >= WC_MD5_BLOCK_SIZE)\n        return BUFFER_E;\n\n    if (data == NULL && len == 0) {\n        /* valid, but do nothing */\n        return 0;\n    }\n\n    /* add length for final */\n    AddLength(md5, len);\n\n    local = (byte*)md5->buffer;\n\n    /* process any remainder from previous operation */\n    if (md5->buffLen > 0) {\n        blocksLen = min(len, WC_MD5_BLOCK_SIZE - md5->buffLen);\n        XMEMCPY(&local[md5->buffLen], data, blocksLen);\n\n        md5->buffLen += blocksLen;\n        data         += blocksLen;\n        len          -= blocksLen;\n\n        if (md5->buffLen == WC_MD5_BLOCK_SIZE) {\n        #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)\n            ByteReverseWords(md5->buffer, md5->buffer, WC_MD5_BLOCK_SIZE);\n        #endif\n\n            ret = XTRANSFORM(md5, (const byte*)local);\n            if (ret != 0)\n                return ret;\n\n            md5->buffLen = 0;\n        }\n    }\n\n    /* process blocks */\n#ifdef XTRANSFORM_LEN\n    /* get number of blocks */\n    /* 64-1 = 0x3F (~ Inverted = 0xFFFFFFC0) */\n    /* len (masked by 0xFFFFFFC0) returns block aligned length */\n    blocksLen = len & ~(WC_MD5_BLOCK_SIZE-1);\n    if (blocksLen > 0) {\n        /* Byte reversal performed in function if required. */\n        XTRANSFORM_LEN(md5, data, blocksLen);\n        data += blocksLen;\n        len  -= blocksLen;\n    }\n#else\n    while (len >= WC_MD5_BLOCK_SIZE) {\n        word32* local32 = md5->buffer;\n        /* optimization to avoid memcpy if data pointer is properly aligned */\n        /* Big Endian requires byte swap, so can't use data directly */\n    #if defined(WC_HASH_DATA_ALIGNMENT) && !defined(BIG_ENDIAN_ORDER)\n        if (((size_t)data % WC_HASH_DATA_ALIGNMENT) == 0) {\n            local32 = (word32*)data;\n        }\n        else\n    #endif\n        {\n            XMEMCPY(local32, data, WC_MD5_BLOCK_SIZE);\n        }\n\n        data += WC_MD5_BLOCK_SIZE;\n        len  -= WC_MD5_BLOCK_SIZE;\n\n    #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)\n        ByteReverseWords(local32, local32, WC_MD5_BLOCK_SIZE);\n    #endif\n\n        ret = XTRANSFORM(md5, (const byte*)local32);\n    }\n#endif /* XTRANSFORM_LEN */\n\n    /* save remainder */\n    if (len > 0) {\n        XMEMCPY(local, data, len);\n        md5->buffLen = len;\n    }\n\n    return ret;\n}\n\nint wc_Md5Final(wc_Md5* md5, byte* hash)\n{\n    byte* local;\n\n    if (md5 == NULL || hash == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5)\n    if (md5->asyncDev.marker == WOLFSSL_ASYNC_MARKER_MD5) {\n#if defined(HAVE_INTEL_QA)\n        return IntelQaSymMd5(&md5->asyncDev, hash, NULL, WC_MD5_DIGEST_SIZE);\n#endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    local = (byte*)md5->buffer;\n\n    local[md5->buffLen++] = 0x80;  /* add 1 */\n\n    /* pad with zeros */\n    if (md5->buffLen > WC_MD5_PAD_SIZE) {\n        XMEMSET(&local[md5->buffLen], 0, WC_MD5_BLOCK_SIZE - md5->buffLen);\n        md5->buffLen += WC_MD5_BLOCK_SIZE - md5->buffLen;\n\n#if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)\n        ByteReverseWords(md5->buffer, md5->buffer, WC_MD5_BLOCK_SIZE);\n#endif\n        XTRANSFORM(md5, local);\n        md5->buffLen = 0;\n    }\n    XMEMSET(&local[md5->buffLen], 0, WC_MD5_PAD_SIZE - md5->buffLen);\n\n#if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)\n    ByteReverseWords(md5->buffer, md5->buffer, WC_MD5_BLOCK_SIZE);\n#endif\n\n    /* put lengths in bits */\n    md5->hiLen = (md5->loLen >> (8 * sizeof(md5->loLen) - 3)) +\n                 (md5->hiLen << 3);\n    md5->loLen = md5->loLen << 3;\n\n    /* store lengths */\n    /* ! length ordering dependent on digest endian type ! */\n    XMEMCPY(&local[WC_MD5_PAD_SIZE], &md5->loLen, sizeof(word32));\n    XMEMCPY(&local[WC_MD5_PAD_SIZE + sizeof(word32)], &md5->hiLen, sizeof(word32));\n\n    /* final transform and result to hash */\n    XTRANSFORM(md5, local);\n#ifdef BIG_ENDIAN_ORDER\n    ByteReverseWords(md5->digest, md5->digest, WC_MD5_DIGEST_SIZE);\n#endif\n    XMEMCPY(hash, md5->digest, WC_MD5_DIGEST_SIZE);\n\n    return _InitMd5(md5); /* reset state */\n}\n#endif /* !HAVE_MD5_CUST_API */\n\n\nint wc_InitMd5(wc_Md5* md5)\n{\n    if (md5 == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    return wc_InitMd5_ex(md5, NULL, INVALID_DEVID);\n}\n\nvoid wc_Md5Free(wc_Md5* md5)\n{\n    if (md5 == NULL)\n        return;\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5)\n    wolfAsync_DevCtxFree(&md5->asyncDev, WOLFSSL_ASYNC_MARKER_MD5);\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n#ifdef WOLFSSL_PIC32MZ_HASH\n    wc_Md5Pic32Free(md5);\n#endif\n}\n\nint wc_Md5GetHash(wc_Md5* md5, byte* hash)\n{\n    int ret;\n    wc_Md5 tmpMd5;\n\n    if (md5 == NULL || hash == NULL)\n        return BAD_FUNC_ARG;\n\n    ret = wc_Md5Copy(md5, &tmpMd5);\n    if (ret == 0) {\n        ret = wc_Md5Final(&tmpMd5, hash);\n    }\n\n    return ret;\n}\n\nint wc_Md5Copy(wc_Md5* src, wc_Md5* dst)\n{\n    int ret = 0;\n\n    if (src == NULL || dst == NULL)\n        return BAD_FUNC_ARG;\n\n    XMEMCPY(dst, src, sizeof(wc_Md5));\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);\n#endif\n#ifdef WOLFSSL_PIC32MZ_HASH\n    ret = wc_Pic32HashCopy(&src->cache, &dst->cache);\n#endif\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    dst->flags |= WC_HASH_FLAG_ISCOPY;\n#endif\n\n    return ret;\n}\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\nint wc_Md5SetFlags(wc_Md5* md5, word32 flags)\n{\n    if (md5) {\n        md5->flags = flags;\n    }\n    return 0;\n}\nint wc_Md5GetFlags(wc_Md5* md5, word32* flags)\n{\n    if (md5 && flags) {\n        *flags = md5->flags;\n    }\n    return 0;\n}\n#endif\n\n#endif /* WOLFSSL_TI_HASH */\n#endif /* NO_MD5 */\n"
  },
  {
    "path": "src/wolfcrypt/src/memory.c",
    "content": "/* memory.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n/* check old macros @wc_fips */\n#if defined(USE_CYASSL_MEMORY) && !defined(USE_WOLFSSL_MEMORY)\n    #define USE_WOLFSSL_MEMORY\n#endif\n#if defined(CYASSL_MALLOC_CHECK) && !defined(WOLFSSL_MALLOC_CHECK)\n    #define WOLFSSL_MALLOC_CHECK\n#endif\n\n\n/*\nPossible memory options:\n * NO_WOLFSSL_MEMORY:               Disables wolf memory callback support. When not defined settings.h defines USE_WOLFSSL_MEMORY.\n * WOLFSSL_STATIC_MEMORY:           Turns on the use of static memory buffers and functions.\n                                        This allows for using static memory instead of dynamic.\n * WOLFSSL_STATIC_ALIGN:            Define defaults to 16 to indicate static memory alignment.\n * HAVE_IO_POOL:                    Enables use of static thread safe memory pool for input/output buffers.\n * XMALLOC_OVERRIDE:                Allows override of the XMALLOC, XFREE and XREALLOC macros.\n * XMALLOC_USER:                    Allows custom XMALLOC, XFREE and XREALLOC functions to be defined.\n * WOLFSSL_NO_MALLOC:               Disables the fall-back case to use STDIO malloc/free when no callbacks are set.\n * WOLFSSL_TRACK_MEMORY:            Enables memory tracking for total stats and list of allocated memory.\n * WOLFSSL_DEBUG_MEMORY:            Enables extra function and line number args for memory callbacks.\n * WOLFSSL_DEBUG_MEMORY_PRINT:      Enables printing of each malloc/free.\n * WOLFSSL_MALLOC_CHECK:            Reports malloc or alignment failure using WOLFSSL_STATIC_ALIGN\n * WOLFSSL_FORCE_MALLOC_FAIL_TEST:  Used for internal testing to induce random malloc failures.\n * WOLFSSL_HEAP_TEST:               Used for internal testing of heap hint\n */\n\n#ifdef WOLFSSL_ZEPHYR\n#undef realloc\nvoid *z_realloc(void *ptr, size_t size)\n{\n    if (ptr == NULL)\n        ptr = malloc(size);\n    else\n        ptr = realloc(ptr, size);\n\n    return ptr;\n}\n#define realloc z_realloc\n#endif\n\n#ifdef USE_WOLFSSL_MEMORY\n\n#include <wolfssl/wolfcrypt/memory.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n\n#if defined(WOLFSSL_DEBUG_MEMORY) && defined(WOLFSSL_DEBUG_MEMORY_PRINT)\n#include <stdio.h>\n#endif\n\n#ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST\n    static int gMemFailCountSeed;\n    static int gMemFailCount;\n    void wolfSSL_SetMemFailCount(int memFailCount)\n    {\n        if (gMemFailCountSeed == 0) {\n            gMemFailCountSeed = memFailCount;\n            gMemFailCount = memFailCount;\n        }\n    }\n#endif\n#if defined(WOLFSSL_MALLOC_CHECK) || defined(WOLFSSL_TRACK_MEMORY_FULL) || \\\n                                                     defined(WOLFSSL_MEMORY_LOG)\n    #include <stdio.h>\n#endif\n\n\n/* Set these to default values initially. */\nstatic wolfSSL_Malloc_cb  malloc_function = NULL;\nstatic wolfSSL_Free_cb    free_function = NULL;\nstatic wolfSSL_Realloc_cb realloc_function = NULL;\n\nint wolfSSL_SetAllocators(wolfSSL_Malloc_cb  mf,\n                          wolfSSL_Free_cb    ff,\n                          wolfSSL_Realloc_cb rf)\n{\n    malloc_function = mf;\n    free_function = ff;\n    realloc_function = rf;\n    return 0;\n}\n\nint wolfSSL_GetAllocators(wolfSSL_Malloc_cb*  mf,\n                          wolfSSL_Free_cb*    ff,\n                          wolfSSL_Realloc_cb* rf)\n{\n    if (mf) *mf = malloc_function;\n    if (ff) *ff = free_function;\n    if (rf) *rf = realloc_function;\n    return 0;\n}\n\n#ifndef WOLFSSL_STATIC_MEMORY\n#ifdef WOLFSSL_DEBUG_MEMORY\nvoid* wolfSSL_Malloc(size_t size, const char* func, unsigned int line)\n#else\nvoid* wolfSSL_Malloc(size_t size)\n#endif\n{\n    void* res = 0;\n\n    if (malloc_function) {\n    #ifdef WOLFSSL_DEBUG_MEMORY\n        res = malloc_function(size, func, line);\n    #else\n        res = malloc_function(size);\n    #endif\n    }\n    else {\n    #ifndef WOLFSSL_NO_MALLOC\n        res = malloc(size);\n    #else\n        WOLFSSL_MSG(\"No malloc available\");\n    #endif\n    }\n\n#ifdef WOLFSSL_DEBUG_MEMORY\n#if defined(WOLFSSL_DEBUG_MEMORY_PRINT) && !defined(WOLFSSL_TRACK_MEMORY)\n    printf(\"Alloc: %p -> %u at %s:%d\\n\", res, (word32)size, func, line);\n#else\n    (void)func;\n    (void)line;\n#endif\n#endif\n\n#ifdef WOLFSSL_MALLOC_CHECK\n    if (res == NULL)\n        WOLFSSL_MSG(\"wolfSSL_malloc failed\");\n#endif\n\n#ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST\n    if (res && --gMemFailCount == 0) {\n        printf(\"\\n---FORCED MEM FAIL TEST---\\n\");\n        if (free_function) {\n        #ifdef WOLFSSL_DEBUG_MEMORY\n            free_function(res, func, line);\n        #else\n            free_function(res);\n        #endif\n        }\n        else {\n            free(res); /* clear */\n        }\n        gMemFailCount = gMemFailCountSeed; /* reset */\n        return NULL;\n    }\n#endif\n\n    return res;\n}\n\n#ifdef WOLFSSL_DEBUG_MEMORY\nvoid wolfSSL_Free(void *ptr, const char* func, unsigned int line)\n#else\nvoid wolfSSL_Free(void *ptr)\n#endif\n{\n#ifdef WOLFSSL_DEBUG_MEMORY\n#if defined(WOLFSSL_DEBUG_MEMORY_PRINT) && !defined(WOLFSSL_TRACK_MEMORY)\n    printf(\"Free: %p at %s:%d\\n\", ptr, func, line);\n#else\n    (void)func;\n    (void)line;\n#endif\n#endif\n\n    if (free_function) {\n    #ifdef WOLFSSL_DEBUG_MEMORY\n        free_function(ptr, func, line);\n    #else\n        free_function(ptr);\n    #endif\n    }\n    else {\n    #ifndef WOLFSSL_NO_MALLOC\n        free(ptr);\n    #else\n        WOLFSSL_MSG(\"No free available\");\n    #endif\n    }\n}\n\n#ifdef WOLFSSL_DEBUG_MEMORY\nvoid* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line)\n#else\nvoid* wolfSSL_Realloc(void *ptr, size_t size)\n#endif\n{\n    void* res = 0;\n\n    if (realloc_function) {\n    #ifdef WOLFSSL_DEBUG_MEMORY\n        res = realloc_function(ptr, size, func, line);\n    #else\n        res = realloc_function(ptr, size);\n    #endif\n    }\n    else {\n    #ifndef WOLFSSL_NO_MALLOC\n        res = realloc(ptr, size);\n    #else\n        WOLFSSL_MSG(\"No realloc available\");\n    #endif\n    }\n\n    return res;\n}\n#endif /* WOLFSSL_STATIC_MEMORY */\n\n#ifdef WOLFSSL_STATIC_MEMORY\n\nstruct wc_Memory {\n    byte*  buffer;\n    struct wc_Memory* next;\n    word32 sz;\n};\n\n\n/* returns amount of memory used on success. On error returns negative value\n   wc_Memory** list is the list that new buckets are prepended to\n */\nstatic int create_memory_buckets(byte* buffer, word32 bufSz,\n                              word32 buckSz, word32 buckNum, wc_Memory** list) {\n    word32 i;\n    byte*  pt  = buffer;\n    int    ret = 0;\n    word32 memSz = (word32)sizeof(wc_Memory);\n    word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);\n\n    /* if not enough space available for bucket size then do not try */\n    if (buckSz + memSz + padSz > bufSz) {\n        return ret;\n    }\n\n    for (i = 0; i < buckNum; i++) {\n        if ((buckSz + memSz + padSz) <= (bufSz - ret)) {\n            /* create a new struct and set its values */\n            wc_Memory* mem = (struct wc_Memory*)(pt);\n            mem->sz = buckSz;\n            mem->buffer = (byte*)pt + padSz + memSz;\n            mem->next = NULL;\n\n            /* add the newly created struct to front of list */\n            if (*list == NULL) {\n                *list = mem;\n            } else {\n                mem->next = *list;\n                *list = mem;\n            }\n\n            /* advance pointer and keep track of memory used */\n            ret += buckSz + padSz + memSz;\n            pt  += buckSz + padSz + memSz;\n        }\n        else {\n            break; /* not enough space left for more buckets of this size */\n        }\n    }\n\n    return ret;\n}\n\nint wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap)\n{\n    word32 wc_MemSz[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS };\n    word32 wc_Dist[WOLFMEM_DEF_BUCKETS]  = { WOLFMEM_DIST };\n\n    if (heap == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    XMEMSET(heap, 0, sizeof(WOLFSSL_HEAP));\n\n    XMEMCPY(heap->sizeList, wc_MemSz, sizeof(wc_MemSz));\n    XMEMCPY(heap->distList, wc_Dist,  sizeof(wc_Dist));\n\n    if (wc_InitMutex(&(heap->memory_mutex)) != 0) {\n        WOLFSSL_MSG(\"Error creating heap memory mutex\");\n        return BAD_MUTEX_E;\n    }\n\n    return 0;\n}\n\nint wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint,\n    unsigned char* buf, unsigned int sz, int flag, int max)\n{\n    int ret;\n    WOLFSSL_HEAP*      heap;\n    WOLFSSL_HEAP_HINT* hint;\n    word32 idx = 0;\n\n    if (pHint == NULL || buf == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if ((sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)) > sz - idx) {\n        return BUFFER_E; /* not enough memory for structures */\n    }\n\n    /* check if hint has already been assigned */\n    if (*pHint == NULL) {\n        heap = (WOLFSSL_HEAP*)buf;\n        idx += sizeof(WOLFSSL_HEAP);\n        hint = (WOLFSSL_HEAP_HINT*)(buf + idx);\n        idx += sizeof(WOLFSSL_HEAP_HINT);\n\n        ret = wolfSSL_init_memory_heap(heap);\n        if (ret != 0) {\n            return ret;\n        }\n\n        XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT));\n        hint->memory = heap;\n    }\n    else {\n    #ifdef WOLFSSL_HEAP_TEST\n        /* do not load in memory if test has been set */\n        if (heap == (void*)WOLFSSL_HEAP_TEST) {\n            return 0;\n        }\n    #endif\n\n        hint = (WOLFSSL_HEAP_HINT*)(*pHint);\n        heap = hint->memory;\n    }\n\n    ret = wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap);\n    if (ret != 1) {\n        WOLFSSL_MSG(\"Error partitioning memory\");\n        return -1;\n    }\n\n    /* determine what max applies too */\n    if ((flag & WOLFMEM_IO_POOL) || (flag & WOLFMEM_IO_POOL_FIXED)) {\n        heap->maxIO = max;\n    }\n    else { /* general memory used in handshakes */\n        heap->maxHa = max;\n    }\n\n    heap->flag |= flag;\n    *pHint = hint;\n\n    (void)max;\n\n    return 0;\n}\n\nint wolfSSL_load_static_memory(byte* buffer, word32 sz, int flag,\n                                                             WOLFSSL_HEAP* heap)\n{\n    word32 ava = sz;\n    byte*  pt  = buffer;\n    int    ret = 0;\n    word32 memSz = (word32)sizeof(wc_Memory);\n    word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);\n\n    WOLFSSL_ENTER(\"wolfSSL_load_static_memory\");\n\n    if (buffer == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* align pt */\n    while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) {\n        *pt = 0x00;\n        pt++;\n        ava--;\n    }\n\n#ifdef WOLFSSL_DEBUG_MEMORY\n    printf(\"Allocated %d bytes for static memory @ %p\\n\", ava, pt);\n#endif\n\n    /* devide into chunks of memory and add them to available list */\n    while (ava >= (heap->sizeList[0] + padSz + memSz)) {\n        int i;\n        /* creating only IO buffers from memory passed in, max TLS is 16k */\n        if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {\n            if ((ret = create_memory_buckets(pt, ava,\n                                          WOLFMEM_IO_SZ, 1, &(heap->io))) < 0) {\n                WOLFSSL_LEAVE(\"wolfSSL_load_static_memory\", ret);\n                return ret;\n            }\n\n            /* check if no more room left for creating IO buffers */\n            if (ret == 0) {\n                break;\n            }\n\n            /* advance pointer in buffer for next buckets and keep track\n               of how much memory is left available */\n            pt  += ret;\n            ava -= ret;\n        }\n        else {\n            /* start at largest and move to smaller buckets */\n            for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) {\n                if ((heap->sizeList[i] + padSz + memSz) <= ava) {\n                    if ((ret = create_memory_buckets(pt, ava, heap->sizeList[i],\n                                     heap->distList[i], &(heap->ava[i]))) < 0) {\n                        WOLFSSL_LEAVE(\"wolfSSL_load_static_memory\", ret);\n                        return ret;\n                    }\n\n                    /* advance pointer in buffer for next buckets and keep track\n                       of how much memory is left available */\n                    pt  += ret;\n                    ava -= ret;\n                }\n            }\n        }\n    }\n\n    return 1;\n}\n\n\n/* returns the size of management memory needed for each bucket.\n * This is memory that is used to keep track of and align memory buckets. */\nint wolfSSL_MemoryPaddingSz(void)\n{\n    word32 memSz = (word32)sizeof(wc_Memory);\n    word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);\n    return memSz + padSz;\n}\n\n\n/* Used to calculate memory size for optimum use with buckets.\n   returns the suggested size rounded down to the nearest bucket. */\nint wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag)\n{\n    word32 bucketSz[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_BUCKETS};\n    word32 distList[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_DIST};\n\n    word32 ava = sz;\n    byte*  pt  = buffer;\n    word32 memSz = (word32)sizeof(wc_Memory);\n    word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);\n\n    WOLFSSL_ENTER(\"wolfSSL_static_size\");\n\n    if (buffer == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* align pt */\n    while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) {\n        pt++;\n        ava--;\n    }\n\n    /* creating only IO buffers from memory passed in, max TLS is 16k */\n    if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {\n        if (ava < (memSz + padSz + WOLFMEM_IO_SZ)) {\n            return 0; /* not enough room for even one bucket */\n        }\n\n        ava = ava % (memSz + padSz + WOLFMEM_IO_SZ);\n    }\n    else {\n        int i, k;\n\n        if (ava < (bucketSz[0] + padSz + memSz)) {\n            return 0; /* not enough room for even one bucket */\n        }\n\n        while ((ava >= (bucketSz[0] + padSz + memSz)) && (ava > 0)) {\n            /* start at largest and move to smaller buckets */\n            for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) {\n                for (k = distList[i]; k > 0; k--) {\n                    if ((bucketSz[i] + padSz + memSz) <= ava) {\n                        ava -= bucketSz[i] + padSz + memSz;\n                    }\n                }\n            }\n        }\n    }\n\n    return sz - ava; /* round down */\n}\n\n\nint FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io)\n{\n    WOLFSSL_MSG(\"Freeing fixed IO buffer\");\n\n    /* check if fixed buffer was set */\n    if (*io == NULL) {\n        return 1;\n    }\n\n    if (heap == NULL) {\n        WOLFSSL_MSG(\"No heap to return fixed IO too\");\n    }\n    else {\n        /* put IO buffer back into IO pool */\n        (*io)->next = heap->io;\n        heap->io    = *io;\n        *io         = NULL;\n    }\n\n    return 1;\n}\n\n\nint SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io)\n{\n    WOLFSSL_MSG(\"Setting fixed IO for SSL\");\n    if (heap == NULL) {\n        return MEMORY_E;\n    }\n\n    *io = heap->io;\n\n    if (*io != NULL) {\n        heap->io = (*io)->next;\n        (*io)->next = NULL;\n    }\n    else { /* failed to grab an IO buffer */\n        return 0;\n    }\n\n    return 1;\n}\n\n\nint wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, WOLFSSL_MEM_STATS* stats)\n{\n        word32     i;\n        wc_Memory* pt;\n\n        XMEMSET(stats, 0, sizeof(WOLFSSL_MEM_STATS));\n\n        stats->totalAlloc = heap->alloc;\n        stats->totalFr    = heap->frAlc;\n        stats->curAlloc   = stats->totalAlloc - stats->totalFr;\n        stats->maxHa      = heap->maxHa;\n        stats->maxIO      = heap->maxIO;\n        for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {\n            stats->blockSz[i] = heap->sizeList[i];\n            for (pt = heap->ava[i]; pt != NULL; pt = pt->next) {\n                stats->avaBlock[i] += 1;\n            }\n        }\n\n        for (pt = heap->io; pt != NULL; pt = pt->next) {\n            stats->avaIO++;\n        }\n\n        stats->flag       = heap->flag; /* flag used */\n\n    return 1;\n}\n\n\n#ifdef WOLFSSL_DEBUG_MEMORY\nvoid* wolfSSL_Malloc(size_t size, void* heap, int type, const char* func, unsigned int line)\n#else\nvoid* wolfSSL_Malloc(size_t size, void* heap, int type)\n#endif\n{\n    void* res = 0;\n    wc_Memory* pt = NULL;\n    int   i;\n\n    /* check for testing heap hint was set */\n#ifdef WOLFSSL_HEAP_TEST\n    if (heap == (void*)WOLFSSL_HEAP_TEST) {\n        return malloc(size);\n    }\n#endif\n\n    /* if no heap hint then use dynamic memory*/\n    if (heap == NULL) {\n        #ifdef WOLFSSL_HEAP_TEST\n            /* allow using malloc for creating ctx and method */\n            if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD ||\n                                            type == DYNAMIC_TYPE_CERT_MANAGER) {\n                WOLFSSL_MSG(\"ERROR allowing null heap hint for ctx/method\\n\");\n                res = malloc(size);\n            }\n            else {\n                WOLFSSL_MSG(\"ERROR null heap hint passed into XMALLOC\\n\");\n                res = NULL;\n            }\n        #else\n        #ifndef WOLFSSL_NO_MALLOC\n            #ifdef FREERTOS\n                res = pvPortMalloc(size);\n            #else\n                res = malloc(size);\n            #endif\n        #else\n            WOLFSSL_MSG(\"No heap hint found to use and no malloc\");\n            #ifdef WOLFSSL_DEBUG_MEMORY\n            printf(\"ERROR: at %s:%d\\n\", func, line);\n            #endif\n        #endif /* WOLFSSL_NO_MALLOC */\n        #endif /* WOLFSSL_HEAP_TEST */\n    }\n    else {\n        WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;\n        WOLFSSL_HEAP*      mem  = hint->memory;\n\n        if (wc_LockMutex(&(mem->memory_mutex)) != 0) {\n            WOLFSSL_MSG(\"Bad memory_mutex lock\");\n            return NULL;\n        }\n\n        /* case of using fixed IO buffers */\n        if (mem->flag & WOLFMEM_IO_POOL_FIXED &&\n                                             (type == DYNAMIC_TYPE_OUT_BUFFER ||\n                                              type == DYNAMIC_TYPE_IN_BUFFER)) {\n            if (type == DYNAMIC_TYPE_OUT_BUFFER) {\n                pt = hint->outBuf;\n            }\n            if (type == DYNAMIC_TYPE_IN_BUFFER) {\n                pt = hint->inBuf;\n            }\n        }\n        else {\n            /* check if using IO pool flag */\n            if (mem->flag & WOLFMEM_IO_POOL &&\n                                             (type == DYNAMIC_TYPE_OUT_BUFFER ||\n                                              type == DYNAMIC_TYPE_IN_BUFFER)) {\n                if (mem->io != NULL) {\n                    pt      = mem->io;\n                    mem->io = pt->next;\n                }\n            }\n\n            /* general static memory */\n            if (pt == NULL) {\n                for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {\n                    if ((word32)size < mem->sizeList[i]) {\n                        if (mem->ava[i] != NULL) {\n                            pt = mem->ava[i];\n                            mem->ava[i] = pt->next;\n                            break;\n                        }\n                    #ifdef WOLFSSL_DEBUG_STATIC_MEMORY\n                        else {\n                            printf(\"Size: %ld, Empty: %d\\n\", size,\n                                                              mem->sizeList[i]);\n                        }\n                    #endif\n                    }\n                }\n            }\n        }\n\n        if (pt != NULL) {\n            mem->inUse += pt->sz;\n            mem->alloc += 1;\n            res = pt->buffer;\n\n        #ifdef WOLFSSL_DEBUG_MEMORY\n            printf(\"Alloc: %p -> %u at %s:%d\\n\", pt->buffer, pt->sz, func, line);\n        #endif\n\n            /* keep track of connection statistics if flag is set */\n            if (mem->flag & WOLFMEM_TRACK_STATS) {\n                WOLFSSL_MEM_CONN_STATS* stats = hint->stats;\n                if (stats != NULL) {\n                    stats->curMem += pt->sz;\n                    if (stats->peakMem < stats->curMem) {\n                        stats->peakMem = stats->curMem;\n                    }\n                    stats->curAlloc++;\n                    if (stats->peakAlloc < stats->curAlloc) {\n                        stats->peakAlloc = stats->curAlloc;\n                    }\n                    stats->totalAlloc++;\n                }\n            }\n        }\n        else {\n            WOLFSSL_MSG(\"ERROR ran out of static memory\");\n            #ifdef WOLFSSL_DEBUG_MEMORY\n            printf(\"Looking for %lu bytes at %s:%d\\n\", size, func, line);\n            #endif\n        }\n\n        wc_UnLockMutex(&(mem->memory_mutex));\n    }\n\n    #ifdef WOLFSSL_MALLOC_CHECK\n        if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) {\n            WOLFSSL_MSG(\"ERROR memory is not alligned\");\n            res = NULL;\n        }\n    #endif\n\n\n    (void)i;\n    (void)pt;\n    (void)type;\n\n    return res;\n}\n\n\n#ifdef WOLFSSL_DEBUG_MEMORY\nvoid wolfSSL_Free(void *ptr, void* heap, int type, const char* func, unsigned int line)\n#else\nvoid wolfSSL_Free(void *ptr, void* heap, int type)\n#endif\n{\n    int i;\n    wc_Memory* pt;\n\n    if (ptr) {\n        /* check for testing heap hint was set */\n    #ifdef WOLFSSL_HEAP_TEST\n        if (heap == (void*)WOLFSSL_HEAP_TEST) {\n            return free(ptr);\n        }\n    #endif\n\n        if (heap == NULL) {\n        #ifdef WOLFSSL_HEAP_TEST\n            /* allow using malloc for creating ctx and method */\n            if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD ||\n                                            type == DYNAMIC_TYPE_CERT_MANAGER) {\n                WOLFSSL_MSG(\"ERROR allowing null heap hint for ctx/method\\n\");\n            }\n            else {\n                WOLFSSL_MSG(\"ERROR null heap hint passed into XFREE\\n\");\n            }\n        #endif\n        #ifndef WOLFSSL_NO_MALLOC\n            #ifdef FREERTOS\n                vPortFree(ptr);\n            #else\n                free(ptr);\n            #endif\n        #else\n            WOLFSSL_MSG(\"Error trying to call free when turned off\");\n        #endif /* WOLFSSL_NO_MALLOC */\n        }\n        else {\n            WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;\n            WOLFSSL_HEAP*      mem  = hint->memory;\n            word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1);\n\n            /* get memory struct and add it to available list */\n            pt = (wc_Memory*)((byte*)ptr - sizeof(wc_Memory) - padSz);\n            if (wc_LockMutex(&(mem->memory_mutex)) != 0) {\n                WOLFSSL_MSG(\"Bad memory_mutex lock\");\n                return;\n            }\n\n            /* case of using fixed IO buffers */\n            if (mem->flag & WOLFMEM_IO_POOL_FIXED &&\n                                             (type == DYNAMIC_TYPE_OUT_BUFFER ||\n                                              type == DYNAMIC_TYPE_IN_BUFFER)) {\n                /* fixed IO pools are free'd at the end of SSL lifetime\n                   using FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io) */\n            }\n            else if (mem->flag & WOLFMEM_IO_POOL && pt->sz == WOLFMEM_IO_SZ &&\n                                             (type == DYNAMIC_TYPE_OUT_BUFFER ||\n                                              type == DYNAMIC_TYPE_IN_BUFFER)) {\n                pt->next = mem->io;\n                mem->io  = pt;\n            }\n            else { /* general memory free */\n                for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {\n                    if (pt->sz == mem->sizeList[i]) {\n                        pt->next = mem->ava[i];\n                        mem->ava[i] = pt;\n                        break;\n                    }\n                }\n            }\n            mem->inUse -= pt->sz;\n            mem->frAlc += 1;\n\n        #ifdef WOLFSSL_DEBUG_MEMORY\n            printf(\"Free: %p -> %u at %s:%d\\n\", pt->buffer, pt->sz, func, line);\n        #endif\n\n            /* keep track of connection statistics if flag is set */\n            if (mem->flag & WOLFMEM_TRACK_STATS) {\n                WOLFSSL_MEM_CONN_STATS* stats = hint->stats;\n                if (stats != NULL) {\n                    /* avoid under flow */\n                    if (stats->curMem > pt->sz) {\n                        stats->curMem -= pt->sz;\n                    }\n                    else {\n                        stats->curMem = 0;\n                    }\n\n                    if (stats->curAlloc > 0) {\n                        stats->curAlloc--;\n                    }\n                    stats->totalFr++;\n                }\n            }\n            wc_UnLockMutex(&(mem->memory_mutex));\n        }\n    }\n\n    (void)i;\n    (void)pt;\n    (void)type;\n}\n\n#ifdef WOLFSSL_DEBUG_MEMORY\nvoid* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line)\n#else\nvoid* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type)\n#endif\n{\n    void* res = 0;\n    wc_Memory* pt = NULL;\n    word32 prvSz;\n    int    i;\n\n    /* check for testing heap hint was set */\n#ifdef WOLFSSL_HEAP_TEST\n    if (heap == (void*)WOLFSSL_HEAP_TEST) {\n        return realloc(ptr, size);\n    }\n#endif\n\n    if (heap == NULL) {\n        #ifdef WOLFSSL_HEAP_TEST\n            WOLFSSL_MSG(\"ERROR null heap hint passed in to XREALLOC\\n\");\n        #endif\n        #ifndef WOLFSSL_NO_MALLOC\n            res = realloc(ptr, size);\n        #else\n            WOLFSSL_MSG(\"NO heap found to use for realloc\");\n        #endif /* WOLFSSL_NO_MALLOC */\n    }\n    else {\n        WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;\n        WOLFSSL_HEAP*      mem  = hint->memory;\n        word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1);\n\n        if (ptr == NULL) {\n        #ifdef WOLFSSL_DEBUG_MEMORY\n            return wolfSSL_Malloc(size, heap, type, func, line);\n        #else\n            return wolfSSL_Malloc(size, heap, type);\n        #endif\n        }\n\n        if (wc_LockMutex(&(mem->memory_mutex)) != 0) {\n            WOLFSSL_MSG(\"Bad memory_mutex lock\");\n            return NULL;\n        }\n\n        /* case of using fixed IO buffers or IO pool */\n        if (((mem->flag & WOLFMEM_IO_POOL)||(mem->flag & WOLFMEM_IO_POOL_FIXED))\n                                          && (type == DYNAMIC_TYPE_OUT_BUFFER ||\n                                              type == DYNAMIC_TYPE_IN_BUFFER)) {\n            /* no realloc, is fixed size */\n            pt = (wc_Memory*)((byte*)ptr - padSz - sizeof(wc_Memory));\n            if (pt->sz < size) {\n                WOLFSSL_MSG(\"Error IO memory was not large enough\");\n                res = NULL; /* return NULL in error case */\n            }\n            res = pt->buffer;\n        }\n        else {\n        /* general memory */\n            for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {\n                if ((word32)size < mem->sizeList[i]) {\n                    if (mem->ava[i] != NULL) {\n                        pt = mem->ava[i];\n                        mem->ava[i] = pt->next;\n                        break;\n                    }\n                }\n            }\n\n            if (pt != NULL && res == NULL) {\n                res = pt->buffer;\n\n                /* copy over original information and free ptr */\n                prvSz = ((wc_Memory*)((byte*)ptr - padSz -\n                                               sizeof(wc_Memory)))->sz;\n                prvSz = (prvSz > pt->sz)? pt->sz: prvSz;\n                XMEMCPY(pt->buffer, ptr, prvSz);\n                mem->inUse += pt->sz;\n                mem->alloc += 1;\n\n                /* free memory that was previously being used */\n                wc_UnLockMutex(&(mem->memory_mutex));\n                wolfSSL_Free(ptr, heap, type\n            #ifdef WOLFSSL_DEBUG_MEMORY\n                    , func, line\n            #endif\n                );\n                if (wc_LockMutex(&(mem->memory_mutex)) != 0) {\n                    WOLFSSL_MSG(\"Bad memory_mutex lock\");\n                    return NULL;\n                }\n            }\n        }\n        wc_UnLockMutex(&(mem->memory_mutex));\n    }\n\n    #ifdef WOLFSSL_MALLOC_CHECK\n        if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) {\n            WOLFSSL_MSG(\"ERROR memory is not alligned\");\n            res = NULL;\n        }\n    #endif\n\n    (void)i;\n    (void)pt;\n    (void)type;\n\n    return res;\n}\n#endif /* WOLFSSL_STATIC_MEMORY */\n\n#endif /* USE_WOLFSSL_MEMORY */\n\n\n#ifdef HAVE_IO_POOL\n\n/* Example for user io pool, shared build may need definitions in lib proper */\n\n#include <wolfssl/wolfcrypt/types.h>\n#include <stdlib.h>\n\n#ifndef HAVE_THREAD_LS\n    #error \"Oops, simple I/O pool example needs thread local storage\"\n#endif\n\n\n/* allow simple per thread in and out pools */\n/* use 17k size since max record size is 16k plus overhead */\nstatic THREAD_LS_T byte pool_in[17*1024];\nstatic THREAD_LS_T byte pool_out[17*1024];\n\n\nvoid* XMALLOC(size_t n, void* heap, int type)\n{\n    (void)heap;\n\n    if (type == DYNAMIC_TYPE_IN_BUFFER) {\n        if (n < sizeof(pool_in))\n            return pool_in;\n        else\n            return NULL;\n    }\n\n    if (type == DYNAMIC_TYPE_OUT_BUFFER) {\n        if (n < sizeof(pool_out))\n            return pool_out;\n        else\n            return NULL;\n    }\n\n    return malloc(n);\n}\n\nvoid* XREALLOC(void *p, size_t n, void* heap, int type)\n{\n    (void)heap;\n\n    if (type == DYNAMIC_TYPE_IN_BUFFER) {\n        if (n < sizeof(pool_in))\n            return pool_in;\n        else\n            return NULL;\n    }\n\n    if (type == DYNAMIC_TYPE_OUT_BUFFER) {\n        if (n < sizeof(pool_out))\n            return pool_out;\n        else\n            return NULL;\n    }\n\n    return realloc(p, n);\n}\n\nvoid XFREE(void *p, void* heap, int type)\n{\n    (void)heap;\n\n    if (type == DYNAMIC_TYPE_IN_BUFFER)\n        return;  /* do nothing, static pool */\n\n    if (type == DYNAMIC_TYPE_OUT_BUFFER)\n        return;  /* do nothing, static pool */\n\n    free(p);\n}\n\n#endif /* HAVE_IO_POOL */\n\n#ifdef WOLFSSL_MEMORY_LOG\nvoid *xmalloc(size_t n, void* heap, int type, const char* func,\n              const char* file, unsigned int line)\n{\n    void*   p;\n    word32* p32;\n\n    if (malloc_function)\n        p32 = malloc_function(n + sizeof(word32) * 4);\n    else\n        p32 = malloc(n + sizeof(word32) * 4);\n\n    p32[0] = (word32)n;\n    p = (void*)(p32 + 4);\n\n    fprintf(stderr, \"Alloc: %p -> %u (%d) at %s:%s:%d\\n\", p, (word32)n, type,\n                                                              func, file, line);\n\n    (void)heap;\n\n    return p;\n}\nvoid *xrealloc(void *p, size_t n, void* heap, int type, const char* func,\n               const char* file, unsigned int line)\n{\n    void*   newp = NULL;\n    word32* p32;\n    word32* oldp32 = NULL;\n    word32  oldLen;\n\n    if (p != NULL) {\n        oldp32 = (word32*)p;\n        oldp32 -= 4;\n        oldLen = oldp32[0];\n    }\n\n    if (realloc_function)\n        p32 = realloc_function(oldp32, n + sizeof(word32) * 4);\n    else\n        p32 = realloc(oldp32, n + sizeof(word32) * 4);\n\n    if (p32 != NULL) {\n        p32[0] = (word32)n;\n        newp = (void*)(p32 + 4);\n\n        fprintf(stderr, \"Alloc: %p -> %u (%d) at %s:%s:%d\\n\", newp, (word32)n,\n                                                        type, func, file, line);\n        if (p != NULL) {\n            fprintf(stderr, \"Free: %p -> %u (%d) at %s:%s:%d\\n\", p, oldLen,\n                                                        type, func, file, line);\n        }\n    }\n\n    (void)heap;\n\n    return newp;\n}\nvoid xfree(void *p, void* heap, int type, const char* func, const char* file,\n           unsigned int line)\n{\n    word32* p32 = (word32*)p;\n\n    if (p != NULL) {\n        p32 -= 4;\n\n        fprintf(stderr, \"Free: %p -> %u (%d) at %s:%s:%d\\n\", p, p32[0], type,\n                                                              func, file, line);\n\n        if (free_function)\n            free_function(p32);\n        else\n            free(p32);\n    }\n\n    (void)heap;\n}\n#endif /* WOLFSSL_MEMORY_LOG */\n\n#ifdef WOLFSSL_STACK_LOG\n/* Note: this code only works with GCC using -finstrument-functions. */\nvoid __attribute__((no_instrument_function))\n     __cyg_profile_func_enter(void *func,  void *caller)\n{\n    register void* sp asm(\"sp\");\n    fprintf(stderr, \"ENTER: %016lx %p\\n\", (size_t)func, sp);\n    (void)caller;\n}\n\nvoid __attribute__((no_instrument_function))\n     __cyg_profile_func_exit(void *func, void *caller)\n{\n    register void* sp asm(\"sp\");\n    fprintf(stderr, \"EXIT: %016lx %p\\n\", (size_t)func, sp);\n    (void)caller;\n}\n#endif\n\n"
  },
  {
    "path": "src/wolfcrypt/src/misc.c",
    "content": "/* misc.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifndef WOLF_CRYPT_MISC_C\n#define WOLF_CRYPT_MISC_C\n\n#include <wolfssl/wolfcrypt/misc.h>\n\n/* inlining these functions is a huge speed increase and a small size decrease,\n   because the functions are smaller than function call setup/cleanup, e.g.,\n   md5 benchmark is twice as fast with inline.  If you don't want it, then\n   define NO_INLINE and compile this file into wolfssl, otherwise it's used as\n   a source header\n */\n\n#ifdef NO_INLINE\n    #define WC_STATIC\n#else\n    #define WC_STATIC static\n#endif\n\n/* Check for if compiling misc.c when not needed. */\n#if !defined(WOLFSSL_MISC_INCLUDED) && !defined(NO_INLINE)\n    #ifndef WOLFSSL_IGNORE_FILE_WARN\n        #warning misc.c does not need to be compiled when using inline (NO_INLINE not defined)\n    #endif\n\n#else\n\n\n#if defined(__ICCARM__)\n    #include <intrinsics.h>\n#endif\n\n\n#ifdef INTEL_INTRINSICS\n\n    #include <stdlib.h>      /* get intrinsic definitions */\n\n    /* for non visual studio probably need no long version, 32 bit only\n     * i.e., _rotl and _rotr */\n    #pragma intrinsic(_lrotl, _lrotr)\n\n    WC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)\n    {\n        return y ? _lrotl(x, y) : x;\n    }\n\n    WC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)\n    {\n        return y ? _lrotr(x, y) : x;\n    }\n\n#else /* generic */\n\n    WC_STATIC WC_INLINE word32 rotlFixed(word32 x, word32 y)\n    {\n        return (x << y) | (x >> (sizeof(y) * 8 - y));\n    }\n\n\n    WC_STATIC WC_INLINE word32 rotrFixed(word32 x, word32 y)\n    {\n        return (x >> y) | (x << (sizeof(y) * 8 - y));\n    }\n\n#endif\n\n\nWC_STATIC WC_INLINE word32 ByteReverseWord32(word32 value)\n{\n#ifdef PPC_INTRINSICS\n    /* PPC: load reverse indexed instruction */\n    return (word32)__lwbrx(&value,0);\n#elif defined(__ICCARM__)\n    return (word32)__REV(value);\n#elif defined(KEIL_INTRINSICS)\n    return (word32)__rev(value);\n#elif defined(WOLF_ALLOW_BUILTIN) && \\\n        defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3)\n    return (word32)__builtin_bswap32(value);\n#elif defined(FAST_ROTATE)\n    /* 5 instructions with rotate instruction, 9 without */\n    return (rotrFixed(value, 8U) & 0xff00ff00) |\n           (rotlFixed(value, 8U) & 0x00ff00ff);\n#else\n    /* 6 instructions with rotate instruction, 8 without */\n    value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);\n    return rotlFixed(value, 16U);\n#endif\n}\n\n\nWC_STATIC WC_INLINE void ByteReverseWords(word32* out, const word32* in,\n                                    word32 byteCount)\n{\n    word32 count = byteCount/(word32)sizeof(word32), i;\n\n    for (i = 0; i < count; i++)\n        out[i] = ByteReverseWord32(in[i]);\n\n}\n\n\n#if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_NO_WORD64_OPS)\n\n\nWC_STATIC WC_INLINE word64 rotlFixed64(word64 x, word64 y)\n{\n    return (x << y) | (x >> (sizeof(y) * 8 - y));\n}\n\n\nWC_STATIC WC_INLINE word64 rotrFixed64(word64 x, word64 y)\n{\n    return (x >> y) | (x << (sizeof(y) * 8 - y));\n}\n\n\nWC_STATIC WC_INLINE word64 ByteReverseWord64(word64 value)\n{\n#if defined(WOLF_ALLOW_BUILTIN) && defined(__GNUC_PREREQ) && __GNUC_PREREQ(4, 3)\n    return (word64)__builtin_bswap64(value);\n#elif defined(WOLFCRYPT_SLOW_WORD64)\n\treturn (word64)((word64)ByteReverseWord32((word32) value)) << 32 |\n                    (word64)ByteReverseWord32((word32)(value   >> 32));\n#else\n\tvalue = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) |\n            ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);\n\tvalue = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) |\n            ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);\n\treturn rotlFixed64(value, 32U);\n#endif\n}\n\n\nWC_STATIC WC_INLINE void ByteReverseWords64(word64* out, const word64* in,\n                                      word32 byteCount)\n{\n    word32 count = byteCount/(word32)sizeof(word64), i;\n\n    for (i = 0; i < count; i++)\n        out[i] = ByteReverseWord64(in[i]);\n\n}\n\n#endif /* WORD64_AVAILABLE && !WOLFSSL_NO_WORD64_OPS */\n\n#ifndef WOLFSSL_NO_XOR_OPS\nWC_STATIC WC_INLINE void XorWords(wolfssl_word* r, const wolfssl_word* a, word32 n)\n{\n    word32 i;\n\n    for (i = 0; i < n; i++) r[i] ^= a[i];\n}\n\n\nWC_STATIC WC_INLINE void xorbuf(void* buf, const void* mask, word32 count)\n{\n    if (((wolfssl_word)buf | (wolfssl_word)mask | count) % WOLFSSL_WORD_SIZE == 0)\n        XorWords( (wolfssl_word*)buf,\n                  (const wolfssl_word*)mask, count / WOLFSSL_WORD_SIZE);\n    else {\n        word32 i;\n        byte*       b = (byte*)buf;\n        const byte* m = (const byte*)mask;\n\n        for (i = 0; i < count; i++) b[i] ^= m[i];\n    }\n}\n#endif\n\n#ifndef WOLFSSL_NO_FORCE_ZERO\n/* Make sure compiler doesn't skip */\nWC_STATIC WC_INLINE void ForceZero(const void* mem, word32 len)\n{\n    volatile byte* z = (volatile byte*)mem;\n\n#if defined(WOLFSSL_X86_64_BUILD) && defined(WORD64_AVAILABLE)\n    volatile word64* w;\n    #ifndef WOLFSSL_UNALIGNED_64BIT_ACCESS\n        word32 l = (sizeof(word64) - ((size_t)z & (sizeof(word64)-1))) &\n                                                             (sizeof(word64)-1);\n\n        if (len < l) l = len;\n        len -= l;\n        while (l--) *z++ = 0;\n    #endif\n    for (w = (volatile word64*)z; len >= sizeof(*w); len -= sizeof(*w))\n        *w++ = 0;\n    z = (volatile byte*)w;\n#endif\n\n    while (len--) *z++ = 0;\n}\n#endif\n\n\n#ifndef WOLFSSL_NO_CONST_CMP\n/* check all length bytes for equality, return 0 on success */\nWC_STATIC WC_INLINE int ConstantCompare(const byte* a, const byte* b, int length)\n{\n    int i;\n    int compareSum = 0;\n\n    for (i = 0; i < length; i++) {\n        compareSum |= a[i] ^ b[i];\n    }\n\n    return compareSum;\n}\n#endif\n\n\n#ifndef WOLFSSL_HAVE_MIN\n    #define WOLFSSL_HAVE_MIN\n    #if defined(HAVE_FIPS) && !defined(min) /* so ifdef check passes */\n        #define min min\n    #endif\n    WC_STATIC WC_INLINE word32 min(word32 a, word32 b)\n    {\n        return a > b ? b : a;\n    }\n#endif /* !WOLFSSL_HAVE_MIN */\n\n#ifndef WOLFSSL_HAVE_MAX\n    #define WOLFSSL_HAVE_MAX\n    #if defined(HAVE_FIPS) && !defined(max) /* so ifdef check passes */\n        #define max max\n    #endif\n    WC_STATIC WC_INLINE word32 max(word32 a, word32 b)\n    {\n        return a > b ? a : b;\n    }\n#endif /* !WOLFSSL_HAVE_MAX */\n\n#ifndef WOLFSSL_NO_INT_ENCODE\n/* converts a 32 bit integer to 24 bit */\nWC_STATIC WC_INLINE void c32to24(word32 in, word24 out)\n{\n    out[0] = (in >> 16) & 0xff;\n    out[1] = (in >>  8) & 0xff;\n    out[2] =  in & 0xff;\n}\n\n/* convert 16 bit integer to opaque */\nWC_STATIC WC_INLINE void c16toa(word16 wc_u16, byte* c)\n{\n    c[0] = (wc_u16 >> 8) & 0xff;\n    c[1] =  wc_u16 & 0xff;\n}\n\n/* convert 32 bit integer to opaque */\nWC_STATIC WC_INLINE void c32toa(word32 wc_u32, byte* c)\n{\n    c[0] = (wc_u32 >> 24) & 0xff;\n    c[1] = (wc_u32 >> 16) & 0xff;\n    c[2] = (wc_u32 >>  8) & 0xff;\n    c[3] =  wc_u32 & 0xff;\n}\n#endif\n\n#ifndef WOLFSSL_NO_INT_DECODE\n/* convert a 24 bit integer into a 32 bit one */\nWC_STATIC WC_INLINE void c24to32(const word24 wc_u24, word32* wc_u32)\n{\n    *wc_u32 = ((word32)wc_u24[0] << 16) | (wc_u24[1] << 8) | wc_u24[2];\n}\n\n\n/* convert opaque to 24 bit integer */\nWC_STATIC WC_INLINE void ato24(const byte* c, word32* wc_u24)\n{\n    *wc_u24 = ((word32)c[0] << 16) | (c[1] << 8) | c[2];\n}\n\n/* convert opaque to 16 bit integer */\nWC_STATIC WC_INLINE void ato16(const byte* c, word16* wc_u16)\n{\n    *wc_u16 = (word16) ((c[0] << 8) | (c[1]));\n}\n\n/* convert opaque to 32 bit integer */\nWC_STATIC WC_INLINE void ato32(const byte* c, word32* wc_u32)\n{\n    *wc_u32 = ((word32)c[0] << 24) | ((word32)c[1] << 16) | (c[2] << 8) | c[3];\n}\n\n\nWC_STATIC WC_INLINE word32 btoi(byte b)\n{\n    return (word32)(b - 0x30);\n}\n#endif\n\n\n#ifndef WOLFSSL_NO_CT_OPS\n/* Constant time - mask set when a > b. */\nWC_STATIC WC_INLINE byte ctMaskGT(int a, int b)\n{\n    return (((word32)a - b - 1) >> 31) - 1;\n}\n\n/* Constant time - mask set when a >= b. */\nWC_STATIC WC_INLINE byte ctMaskGTE(int a, int b)\n{\n    return (((word32)a - b    ) >> 31) - 1;\n}\n\n/* Constant time - mask set when a >= b. */\nWC_STATIC WC_INLINE int ctMaskIntGTE(int a, int b)\n{\n    return (((word32)a - b    ) >> 31) - 1;\n}\n\n/* Constant time - mask set when a < b. */\nWC_STATIC WC_INLINE byte ctMaskLT(int a, int b)\n{\n    return (((word32)b - a - 1) >> 31) - 1;\n}\n\n/* Constant time - mask set when a <= b. */\nWC_STATIC WC_INLINE byte ctMaskLTE(int a, int b)\n{\n    return (((word32)b - a    ) >> 31) - 1;\n}\n\n/* Constant time - mask set when a == b. */\nWC_STATIC WC_INLINE byte ctMaskEq(int a, int b)\n{\n    return (~ctMaskGT(a, b)) & (~ctMaskLT(a, b));\n}\n\nWC_STATIC WC_INLINE word16 ctMask16Eq(int a, int b)\n{\n    return (~ctMaskGT(a, b)) & (~ctMaskLT(a, b));\n}\n\n/* Constant time - mask set when a != b. */\nWC_STATIC WC_INLINE byte ctMaskNotEq(int a, int b)\n{\n    return ctMaskGT(a, b) | ctMaskLT(a, b);\n}\n\n/* Constant time - select a when mask is set and b otherwise. */\nWC_STATIC WC_INLINE byte ctMaskSel(byte m, byte a, byte b)\n{\n    return (b & ((byte)~(word32)m)) | (a & m);\n}\n\n/* Constant time - select integer a when mask is set and integer b otherwise. */\nWC_STATIC WC_INLINE int ctMaskSelInt(byte m, int a, int b)\n{\n    return (b & (~(signed int)(signed char)m)) |\n           (a & ( (signed int)(signed char)m));\n}\n\n/* Constant time - bit set when a <= b. */\nWC_STATIC WC_INLINE byte ctSetLTE(int a, int b)\n{\n    return ((word32)a - b - 1) >> 31;\n}\n#endif\n\n\n#undef WC_STATIC\n\n#endif /* !WOLFSSL_MISC_INCLUDED && !NO_INLINE */\n\n#endif /* WOLF_CRYPT_MISC_C */\n"
  },
  {
    "path": "src/wolfcrypt/src/pkcs12.c",
    "content": "/* pkcs12.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)\n\n#include <wolfssl/wolfcrypt/asn.h>\n#include <wolfssl/wolfcrypt/asn_public.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/hmac.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n#include <wolfssl/wolfcrypt/pkcs12.h>\n#include <wolfssl/wolfcrypt/pwdbased.h>\n#include <wolfssl/wolfcrypt/hash.h>\n\n\n#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }\n\nenum {\n    WC_PKCS12_KeyBag = 667,\n    WC_PKCS12_ShroudedKeyBag = 668,\n    WC_PKCS12_CertBag = 669,\n    WC_PKCS12_CertBag_Type1 = 675,\n    WC_PKCS12_CrlBag = 670,\n    WC_PKCS12_SecretBag = 671,\n    WC_PKCS12_SafeContentsBag = 672,\n    WC_PKCS12_DATA = 651,\n    WC_PKCS12_ENCRYPTED_DATA = 656,\n\n    WC_PKCS12_DATA_OBJ_SZ = 11,\n};\n\n/* static const byte WC_PKCS12_ENCRYPTED_OID[] =\n                         {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06}; */\nstatic const byte WC_PKCS12_DATA_OID[] =\n                         {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01};\nstatic const byte WC_PKCS12_CertBag_Type1_OID[] =\n                   {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x16, 0x01};\nstatic const byte WC_PKCS12_CertBag_OID[] =\n             {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0c, 0x0a, 0x01, 0x03};\nstatic const byte WC_PKCS12_KeyBag_OID[] =\n             {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0c, 0x0a, 0x01, 0x01};\nstatic const byte WC_PKCS12_ShroudedKeyBag_OID[] =\n             {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0c, 0x0a, 0x01, 0x02};\n\n\ntypedef struct ContentInfo {\n    byte* data;\n    struct ContentInfo* next;\n    word32 encC;  /* encryptedContent */\n    word32 dataSz;\n    int type; /* DATA / encrypted / enveloped */\n} ContentInfo;\n\n\ntypedef struct AuthenticatedSafe {\n    ContentInfo* CI;\n    byte* data; /* T contents.... */\n    word32 oid; /* encrypted or not */\n    word32 numCI; /* number of Content Info structs */\n    word32 dataSz;\n} AuthenticatedSafe;\n\n\ntypedef struct MacData {\n    byte* digest;\n    byte* salt;\n    word32 oid;\n    word32 digestSz;\n    word32 saltSz;\n    int itt; /* number of iterations when creating HMAC key */\n} MacData;\n\n\nstruct WC_PKCS12 {\n    void* heap;\n    AuthenticatedSafe* safe;\n    MacData* signData;\n    word32 oid; /* DATA / Enveloped DATA ... */\n};\n\n\n/* for friendlyName, localKeyId .... */\ntypedef struct WC_PKCS12_ATTRIBUTE {\n    byte* data;\n    word32 oid;\n    word32 dataSz;\n} WC_PKCS12_ATTRIBUTE;\n\n\nWC_PKCS12* wc_PKCS12_new(void)\n{\n    WC_PKCS12* pkcs12 = (WC_PKCS12*)XMALLOC(sizeof(WC_PKCS12),\n                                                      NULL, DYNAMIC_TYPE_PKCS);\n    if (pkcs12 == NULL) {\n        WOLFSSL_MSG(\"Memory issue when creating WC_PKCS12 struct\");\n        return NULL;\n    }\n\n    XMEMSET(pkcs12, 0, sizeof(WC_PKCS12));\n\n    return pkcs12;\n}\n\n\nstatic void freeSafe(AuthenticatedSafe* safe, void* heap)\n{\n    int i;\n\n    if (safe == NULL) {\n        return;\n    }\n\n    /* free content info structs */\n    for (i = safe->numCI; i > 0; i--) {\n        ContentInfo* ci = safe->CI;\n        safe->CI = ci->next;\n        XFREE(ci, heap, DYNAMIC_TYPE_PKCS);\n    }\n    if (safe->data != NULL) {\n        XFREE(safe->data, heap, DYNAMIC_TYPE_PKCS);\n    }\n    XFREE(safe, heap, DYNAMIC_TYPE_PKCS);\n\n    (void)heap;\n}\n\n\nvoid wc_PKCS12_free(WC_PKCS12* pkcs12)\n{\n    void* heap;\n\n    /* if null pointer is passed in do nothing */\n    if (pkcs12 == NULL) {\n        WOLFSSL_MSG(\"Trying to free null WC_PKCS12 object\");\n        return;\n    }\n\n    heap = pkcs12->heap;\n    if (pkcs12->safe != NULL) {\n    \tfreeSafe(pkcs12->safe, heap);\n    }\n\n    /* free mac data */\n    if (pkcs12->signData != NULL) {\n        if (pkcs12->signData->digest != NULL) {\n            XFREE(pkcs12->signData->digest, heap, DYNAMIC_TYPE_DIGEST);\n            pkcs12->signData->digest = NULL;\n        }\n        if (pkcs12->signData->salt != NULL) {\n            XFREE(pkcs12->signData->salt, heap, DYNAMIC_TYPE_SALT);\n            pkcs12->signData->salt = NULL;\n        }\n        XFREE(pkcs12->signData, heap, DYNAMIC_TYPE_PKCS);\n        pkcs12->signData = NULL;\n    }\n\n    XFREE(pkcs12, NULL, DYNAMIC_TYPE_PKCS);\n    pkcs12 = NULL;\n}\n\n\nstatic int GetSafeContent(WC_PKCS12* pkcs12, const byte* input,\n                          word32* idx, int maxIdx)\n{\n    AuthenticatedSafe* safe;\n    word32 oid;\n    word32 localIdx = *idx;\n    int ret;\n    int size = 0;\n    byte tag;\n\n    safe = (AuthenticatedSafe*)XMALLOC(sizeof(AuthenticatedSafe), pkcs12->heap,\n                                       DYNAMIC_TYPE_PKCS);\n    if (safe == NULL) {\n        return MEMORY_E;\n    }\n    XMEMSET(safe, 0, sizeof(AuthenticatedSafe));\n\n    ret = GetObjectId(input, &localIdx, &oid, oidIgnoreType, maxIdx);\n    if (ret < 0) {\n        WOLFSSL_LEAVE(\"Get object id failed\", ret);\n        freeSafe(safe, pkcs12->heap);\n        return ASN_PARSE_E;\n    }\n\n    safe->oid = oid;\n    /* check tag, length */\n    if (GetASNTag(input, &localIdx, &tag, maxIdx) < 0) {\n        freeSafe(safe, pkcs12->heap);\n        return ASN_PARSE_E;\n    }\n\n    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {\n        WOLFSSL_MSG(\"Unexpected tag in PKCS12 DER\");\n        freeSafe(safe, pkcs12->heap);\n        return ASN_PARSE_E;\n    }\n    if ((ret = GetLength(input, &localIdx, &size, maxIdx)) <= 0) {\n        freeSafe(safe, pkcs12->heap);\n        return ret;\n    }\n\n    switch (oid) {\n        case WC_PKCS12_ENCRYPTED_DATA:\n            WOLFSSL_MSG(\"Found PKCS12 OBJECT: ENCRYPTED DATA\\n\");\n            break;\n\n        case WC_PKCS12_DATA:\n            WOLFSSL_MSG(\"Found PKCS12 OBJECT: DATA\");\n            /* get octets holding contents */\n            if (GetASNTag(input, &localIdx, &tag, maxIdx) < 0) {\n                freeSafe(safe, pkcs12->heap);\n                return ASN_PARSE_E;\n            }\n\n            if (tag != ASN_OCTET_STRING) {\n                WOLFSSL_MSG(\"Wrong tag with content PKCS12 type DATA\");\n                freeSafe(safe, pkcs12->heap);\n                return ASN_PARSE_E;\n            }\n            if ((ret = GetLength(input, &localIdx, &size, maxIdx)) <= 0) {\n                freeSafe(safe, pkcs12->heap);\n                return ret;\n            }\n\n            break;\n    }\n\n    safe->dataSz = size;\n    safe->data = (byte*)XMALLOC(size, pkcs12->heap, DYNAMIC_TYPE_PKCS);\n    if (safe->data == NULL) {\n        freeSafe(safe, pkcs12->heap);\n        return MEMORY_E;\n    }\n    XMEMCPY(safe->data, input + localIdx, size);\n    *idx = localIdx;\n\n    /* an instance of AuthenticatedSafe is created from\n     * ContentInfo's strung together in a SEQUENCE. Here we iterate\n     * through the ContentInfo's and add them to our\n     * AuthenticatedSafe struct */\n    localIdx = 0;\n    input = safe->data;\n    {\n        int CISz;\n        ret = GetSequence(input, &localIdx, &CISz, safe->dataSz);\n        if (ret < 0) {\n            freeSafe(safe, pkcs12->heap);\n            return ASN_PARSE_E;\n        }\n        CISz += localIdx;\n        while ((int)localIdx < CISz) {\n            int curSz = 0;\n            word32 curIdx;\n            ContentInfo* ci = NULL;\n\n        #ifdef WOLFSSL_DEBUG_PKCS12\n            printf(\"\\t\\tlooking for Content Info.... \");\n        #endif\n\n            if ((ret = GetSequence(input, &localIdx, &curSz, safe->dataSz))\n                                                                          < 0) {\n                freeSafe(safe, pkcs12->heap);\n                return ret;\n            }\n\n            if (curSz > CISz) {\n                /* subset should not be larger than universe */\n                freeSafe(safe, pkcs12->heap);\n                return ASN_PARSE_E;\n            }\n\n            curIdx = localIdx;\n            if ((ret = GetObjectId(input, &localIdx, &oid, oidIgnoreType,\n                                                           safe->dataSz)) < 0) {\n                WOLFSSL_LEAVE(\"Get object id failed\", ret);\n                freeSafe(safe, pkcs12->heap);\n                return ret;\n            }\n\n            /* create new content info struct ... possible OID sanity check? */\n            ci = (ContentInfo*)XMALLOC(sizeof(ContentInfo), pkcs12->heap,\n                                       DYNAMIC_TYPE_PKCS);\n            if (ci == NULL) {\n                freeSafe(safe, pkcs12->heap);\n                return MEMORY_E;\n            }\n\n            ci->type   = oid;\n            ci->dataSz = curSz - (localIdx-curIdx);\n            ci->data   = (byte*)input + localIdx;\n            localIdx  += ci->dataSz;\n\n        #ifdef WOLFSSL_DEBUG_PKCS12\n            switch (oid) {\n                case WC_PKCS12_ENCRYPTED_DATA:\n                    printf(\"CONTENT INFO: ENCRYPTED DATA, size = %d\\n\", ci->dataSz);\n                    break;\n\n                case WC_PKCS12_DATA:\n                    printf(\"CONTENT INFO: DATA, size = %d\\n\", ci->dataSz);\n                    break;\n                default:\n                    printf(\"CONTENT INFO: UNKNOWN, size = %d\\n\", ci->dataSz);\n            }\n        #endif\n\n            /* insert to head of list */\n            ci->next = safe->CI;\n            safe->CI = ci;\n            safe->numCI += 1;\n        }\n    }\n\n    pkcs12->safe = safe;\n    *idx += localIdx;\n\n    return ret;\n}\n\n\n/* optional mac data */\nstatic int GetSignData(WC_PKCS12* pkcs12, const byte* mem, word32* idx,\n                       word32 totalSz)\n{\n    MacData* mac;\n    word32 curIdx = *idx;\n    word32 oid = 0;\n    int size, ret;\n    byte tag;\n\n    /* Digest Info : Sequence\n     *      DigestAlgorithmIdentifier\n     *      Digest\n     */\n    if ((ret = GetSequence(mem, &curIdx, &size, totalSz)) <= 0) {\n        WOLFSSL_MSG(\"Failed to get PKCS12 sequence\");\n        return ret;\n    }\n\n#ifdef WOLFSSL_DEBUG_PKCS12\n    printf(\"\\t\\tSEQUENCE: DigestInfo size = %d\\n\", size);\n#endif\n\n    mac = (MacData*)XMALLOC(sizeof(MacData), pkcs12->heap, DYNAMIC_TYPE_PKCS);\n    if (mac == NULL) {\n        return MEMORY_E;\n    }\n    XMEMSET(mac, 0, sizeof(MacData));\n\n    /* DigestAlgorithmIdentifier */\n    if ((ret = GetAlgoId(mem, &curIdx, &oid, oidIgnoreType, totalSz)) < 0) {\n        WOLFSSL_MSG(\"Failed to get PKCS12 sequence\");\n        XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);\n        return ret;\n    }\n    mac->oid = oid;\n\n#ifdef WOLFSSL_DEBUG_PKCS12\n    printf(\"\\t\\tALGO ID = %d\\n\", oid);\n#endif\n\n    /* Digest: should be octet type holding digest */\n    if (GetASNTag(mem, &curIdx, &tag, totalSz) < 0) {\n        XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);\n        return ASN_PARSE_E;\n    }\n\n    if (tag != ASN_OCTET_STRING) {\n        WOLFSSL_MSG(\"Failed to get digest\");\n        XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);\n        return ASN_PARSE_E;\n    }\n\n    if ((ret = GetLength(mem, &curIdx, &size, totalSz)) <= 0) {\n        XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);\n        return ret;\n    }\n    mac->digestSz = size;\n    mac->digest = (byte*)XMALLOC(mac->digestSz, pkcs12->heap,\n                                 DYNAMIC_TYPE_DIGEST);\n    if (mac->digest == NULL || mac->digestSz + curIdx > totalSz) {\n        ERROR_OUT(MEMORY_E, exit_gsd);\n    }\n    XMEMCPY(mac->digest, mem + curIdx, mac->digestSz);\n\n#ifdef WOLFSSL_DEBUG_PKCS12\n    {\n        byte* p;\n        for (printf(\"\\t\\tDigest = \"), p = (byte*)mem+curIdx;\n             p < (byte*)mem + curIdx + mac->digestSz;\n             printf(\"%02X\", *p), p++);\n        printf(\" : size = %d\\n\", mac->digestSz);\n    }\n#endif\n\n    curIdx += mac->digestSz;\n\n    /* get salt, should be octet string */\n    if (GetASNTag(mem, &curIdx, &tag, totalSz) < 0) {\n        ERROR_OUT(ASN_PARSE_E, exit_gsd);\n    }\n\n    if (tag != ASN_OCTET_STRING) {\n        WOLFSSL_MSG(\"Failed to get salt\");\n        ERROR_OUT(ASN_PARSE_E, exit_gsd);\n    }\n\n    if ((ret = GetLength(mem, &curIdx, &size, totalSz)) < 0) {\n        goto exit_gsd;\n    }\n    mac->saltSz = size;\n    mac->salt = (byte*)XMALLOC(mac->saltSz, pkcs12->heap, DYNAMIC_TYPE_SALT);\n    if (mac->salt == NULL || mac->saltSz + curIdx > totalSz) {\n        ERROR_OUT(MEMORY_E, exit_gsd);\n    }\n    XMEMCPY(mac->salt, mem + curIdx, mac->saltSz);\n\n#ifdef WOLFSSL_DEBUG_PKCS12\n    {\n        byte* p;\n        for (printf(\"\\t\\tSalt = \"), p = (byte*)mem + curIdx;\n             p < (byte*)mem + curIdx + mac->saltSz;\n             printf(\"%02X\", *p), p++);\n        printf(\" : size = %d\\n\", mac->saltSz);\n    }\n#endif\n\n    curIdx += mac->saltSz;\n\n    /* check for MAC iterations, default to 1 */\n    mac->itt = WC_PKCS12_MAC_DEFAULT;\n    if (curIdx < totalSz) {\n        int number = 0;\n        if ((ret = GetShortInt(mem, &curIdx, &number, totalSz)) >= 0) {\n            /* found a iteration value */\n            mac->itt = number;\n        }\n    }\n\n#ifdef WOLFSSL_DEBUG_PKCS12\n    printf(\"\\t\\tITERATIONS : %d\\n\", mac->itt);\n#endif\n\n    *idx = curIdx;\n    pkcs12->signData = mac;\n    ret = 0; /* success */\n\nexit_gsd:\n\n    /* failure cleanup */\n    if (ret != 0) {\n        if (mac) {\n            if (mac->digest)\n                XFREE(mac->digest, pkcs12->heap, DYNAMIC_TYPE_DIGEST);\n            XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);\n        }\n    }\n\n    return ret;\n}\n\n\n/* expects PKCS12 signData to be set up with OID\n *\n * returns the size of mac created on success. A negative value will be returned\n *         in the case that an error happened.\n */\nstatic int wc_PKCS12_create_mac(WC_PKCS12* pkcs12, byte* data, word32 dataSz,\n                         const byte* psw, word32 pswSz, byte* out, word32 outSz)\n{\n    Hmac     hmac;\n    MacData* mac;\n    int ret, kLen;\n    enum wc_HashType hashT;\n    int idx = 0;\n    int id  = 3; /* value from RFC 7292 indicating key is used for MAC */\n    word32 i;\n    byte unicodePasswd[MAX_UNICODE_SZ];\n    byte key[MAX_KEY_SIZE];\n\n    if (pkcs12 == NULL || pkcs12->signData == NULL || data == NULL ||\n            out == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    mac = pkcs12->signData;\n\n    /* unicode set up from asn.c */\n    if ((pswSz * 2 + 2) > (int)sizeof(unicodePasswd)) {\n        WOLFSSL_MSG(\"PKCS12 max unicode size too small\");\n        return UNICODE_SIZE_E;\n    }\n\n    for (i = 0; i < pswSz; i++) {\n        unicodePasswd[idx++] = 0x00;\n        unicodePasswd[idx++] = (byte)psw[i];\n    }\n    /* add trailing NULL */\n    unicodePasswd[idx++] = 0x00;\n    unicodePasswd[idx++] = 0x00;\n\n    /* get hash type used and resulting size of HMAC key */\n    hashT = wc_OidGetHash(mac->oid);\n    if (hashT == WC_HASH_TYPE_NONE) {\n        WOLFSSL_MSG(\"Unsupported hash used\");\n        return BAD_FUNC_ARG;\n    }\n    kLen = wc_HashGetDigestSize(hashT);\n\n    /* check out buffer is large enough */\n    if (kLen < 0 || outSz < (word32)kLen) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* idx contains size of unicodePasswd */\n    if ((ret = wc_PKCS12_PBKDF_ex(key, unicodePasswd, idx, mac->salt,\n              mac->saltSz, mac->itt, kLen, (int)hashT, id, pkcs12->heap)) < 0) {\n        return ret;\n    }\n\n    /* now that key has been created use it to get HMAC hash on data */\n    if ((ret = wc_HmacInit(&hmac, pkcs12->heap, INVALID_DEVID)) != 0) {\n        return ret;\n    }\n    ret = wc_HmacSetKey(&hmac, (int)hashT, key, kLen);\n    if (ret == 0)\n        ret = wc_HmacUpdate(&hmac, data, dataSz);\n    if (ret == 0)\n        ret = wc_HmacFinal(&hmac, out);\n    wc_HmacFree(&hmac);\n\n    if (ret != 0)\n        return ret;\n\n    return kLen; /* same as digest size */\n}\n\n\n/* check mac on pkcs12, pkcs12->mac has been sanity checked before entering *\n * returns the result of comparison, success is 0 */\nstatic int wc_PKCS12_verify(WC_PKCS12* pkcs12, byte* data, word32 dataSz,\n                            const byte* psw, word32 pswSz)\n{\n    MacData* mac;\n    int ret;\n    byte digest[WC_MAX_DIGEST_SIZE];\n\n    if (pkcs12 == NULL || pkcs12->signData == NULL || data == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    mac = pkcs12->signData;\n\n#ifdef WOLFSSL_DEBUG_PKCS12\n    printf(\"Verifying MAC with OID = %d\\n\", mac->oid);\n#endif\n\n    /* check if this builds digest size is too small */\n    if (mac->digestSz > WC_MAX_DIGEST_SIZE) {\n        WOLFSSL_MSG(\"PKCS12 max digest size too small\");\n        return BAD_FUNC_ARG;\n    }\n\n    if ((ret = wc_PKCS12_create_mac(pkcs12, data, dataSz, psw, pswSz,\n            digest, WC_MAX_DIGEST_SIZE)) < 0) {\n        return ret;\n    }\n\n#ifdef WOLFSSL_DEBUG_PKCS12\n    {\n        byte* p;\n        for (printf(\"\\t\\tHash = \"), p = (byte*)digest;\n             p < (byte*)digest + mac->digestSz;\n             printf(\"%02X\", *p), p++);\n        printf(\" : size = %d\\n\", mac->digestSz);\n    }\n#endif\n\n    return XMEMCMP(digest, mac->digest, mac->digestSz);\n}\n\n\n/* Convert DER format stored in der buffer to WC_PKCS12 struct\n * Puts the raw contents of Content Info into structure without completely\n * parsing or decoding.\n * der    : pointer to der buffer holding PKCS12\n * derSz  : size of der buffer\n * pkcs12 : non-null pkcs12 pointer\n * return 0 on success and negative on failure.\n */\nint wc_d2i_PKCS12(const byte* der, word32 derSz, WC_PKCS12* pkcs12)\n{\n    word32 idx  = 0;\n    word32 totalSz = 0;\n    int ret;\n    int size    = 0;\n    int version = 0;\n\n    WOLFSSL_ENTER(\"wolfSSL_d2i_PKCS12_bio\");\n\n    if (der == NULL || pkcs12 == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    totalSz = derSz;\n    if ((ret = GetSequence(der, &idx, &size, totalSz)) <= 0) {\n        WOLFSSL_MSG(\"Failed to get PKCS12 sequence\");\n        return ret;\n    }\n\n    /* get version */\n    if ((ret = GetMyVersion(der, &idx, &version, totalSz)) < 0) {\n        return ret;\n    }\n\n#ifdef WOLFSSL_DEBUG_PKCS12\n    printf(\"\\nBEGIN: PKCS12 size = %d\\n\", totalSz);\n    printf(\"version = %d\\n\", version);\n#endif\n\n    if (version != WC_PKCS12_VERSION_DEFAULT) {\n        WOLFSSL_MSG(\"PKCS12 unsupported version!\");\n        return ASN_VERSION_E;\n    }\n\n    if ((ret = GetSequence(der, &idx, &size, totalSz)) < 0) {\n        return ret;\n    }\n\n#ifdef WOLFSSL_DEBUG_PKCS12\n    printf(\"\\tSEQUENCE: AuthenticatedSafe size = %d\\n\", size);\n#endif\n\n    if ((ret = GetSafeContent(pkcs12, der, &idx, size + idx)) < 0) {\n        WOLFSSL_MSG(\"GetSafeContent error\");\n        return ret;\n    }\n\n    /* if more buffer left check for MAC data */\n    if (idx < totalSz) {\n        if ((ret = GetSequence(der, &idx, &size, totalSz)) < 0) {\n            WOLFSSL_MSG(\"Ignoring unknown data at end of PKCS12 DER buffer\");\n        }\n        else {\n        #ifdef WOLFSSL_DEBUG_PKCS12\n            printf(\"\\tSEQUENCE: Signature size = %d\\n\", size);\n        #endif\n\n            if ((ret = GetSignData(pkcs12, der, &idx, totalSz)) < 0) {\n                return ASN_PARSE_E;\n            }\n        }\n    }\n\n#ifdef WOLFSSL_DEBUG_PKCS12\n    printf(\"END: PKCS12\\n\");\n#endif\n\n    return ret;\n}\n\n/* Convert WC_PKCS12 struct to allocated DER buffer.\n * pkcs12 : non-null pkcs12 pointer\n * der    : pointer-pointer to der buffer. If NULL space will be\n *          allocated for der, which must be freed by application.\n * derSz  : size of buffer passed in when der is not NULL. NULL arg disables\n *          sanity checks on buffer read/writes. Max size gets set to derSz when\n *          the \"der\" buffer passed in is NULL and LENGTH_ONLY_E is returned.\n * return size of DER on success and negative on failure.\n */\nint wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der, int* derSz)\n{\n    int ret = 0;\n    word32 seqSz = 0, verSz = 0, totalSz = 0, idx = 0, sdBufSz = 0;\n    byte *buf = NULL;\n    byte ver[MAX_VERSION_SZ];\n    byte seq[MAX_SEQ_SZ];\n    byte *sdBuf = NULL;\n\n    if ((pkcs12 == NULL) || (pkcs12->safe == NULL) ||\n            (der == NULL && derSz == NULL)) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* Create the MAC portion */\n    if ((ret == 0) && (pkcs12->signData != NULL)) {\n        MacData *mac = (MacData*)pkcs12->signData;\n        word32 aSz = (2 + (2 + 5) + (2));\n        word32 bSz = (2 + mac->digestSz);\n        word32 cSz = (2 + mac->saltSz);\n        word32 dSz = (2 + sizeof(short int));\n        word32 innerSz = aSz + bSz;\n        word32 outerSz = 2 + innerSz + cSz + dSz;\n\n        sdBufSz = 2 + outerSz;\n        sdBuf = (byte*)XMALLOC(sdBufSz, pkcs12->heap, DYNAMIC_TYPE_PKCS);\n        if (sdBuf == NULL) {\n            ret = MEMORY_E;\n        }\n\n        if (ret == 0) {\n            idx += SetSequence(outerSz, sdBuf);\n            idx += SetSequence(innerSz, &sdBuf[idx]);\n\n            /* Set Algorithm Identifier */\n            {\n                word32 algoIdSz;\n\n                algoIdSz = SetAlgoID(mac->oid, &sdBuf[idx], oidHashType, 0);\n                if (algoIdSz == 0) {\n                    ret = ALGO_ID_E;\n                }\n                else {\n                    idx += algoIdSz;\n                }\n            }\n        }\n\n        if (ret == 0) {\n            /* Octet string holding digest */\n            sdBuf[idx++] = ASN_OCTET_STRING;\n            idx += SetLength(mac->digestSz, &sdBuf[idx]);\n            XMEMCPY(&sdBuf[idx], mac->digest, mac->digestSz);\n            idx += mac->digestSz;\n\n            /* Set salt */\n            sdBuf[idx++] = ASN_OCTET_STRING;\n            idx += SetLength(mac->saltSz, &sdBuf[idx]);\n            XMEMCPY(&sdBuf[idx], mac->salt, mac->saltSz);\n            idx += mac->saltSz;\n\n            /* MAC iterations */\n            {\n                int tmpSz;\n                word32 tmpIdx = 0;\n                byte ar[MAX_LENGTH_SZ + 2];\n                tmpSz = SetShortInt(ar, &tmpIdx, mac->itt, MAX_LENGTH_SZ + 2);\n                if (tmpSz < 0) {\n                    ret = tmpSz;\n                }\n                else {\n                    XMEMCPY(&sdBuf[idx], ar, tmpSz);\n                }\n            }\n\n            totalSz += sdBufSz;\n        }\n    }\n\n    /* Calculate size of der */\n    if (ret == 0) {\n        totalSz += pkcs12->safe->dataSz;\n\n        totalSz += 4; /* Octet string */\n\n        totalSz += 4; /* Element */\n\n        totalSz += 2 + sizeof(WC_PKCS12_DATA_OID);\n\n        totalSz += 4; /* Seq */\n\n        ret = SetMyVersion(WC_PKCS12_VERSION_DEFAULT, ver, FALSE);\n        if (ret > 0) {\n            verSz = (word32)ret;\n            ret   = 0; /* value larger than 0 is success */\n            totalSz += verSz;\n\n            seqSz = SetSequence(totalSz, seq);\n            totalSz += seqSz;\n\n            /* check if getting length only */\n            if (der == NULL && derSz != NULL) {\n                *derSz = totalSz;\n                XFREE(sdBuf, pkcs12->heap, DYNAMIC_TYPE_PKCS);\n                return LENGTH_ONLY_E;\n            }\n\n            if (*der == NULL) {\n                /* Allocate if requested */\n                buf = (byte*)XMALLOC(totalSz, NULL, DYNAMIC_TYPE_PKCS);\n            }\n            else {\n                buf = *der;\n\n                /* sanity check on buffer size if passed in */\n                if (derSz != NULL) {\n                    if (*derSz < (int)totalSz) {\n                        WOLFSSL_MSG(\"Buffer passed in is too small\");\n                        ret = BUFFER_E;\n                    }\n                }\n            }\n        }\n    }\n\n    if (buf == NULL) {\n        ret = MEMORY_E;\n    }\n\n    if (ret == 0) {\n        idx = 0;\n\n        /* Copy parts to buf */\n        XMEMCPY(&buf[idx], seq, seqSz);\n        idx += seqSz;\n\n        XMEMCPY(&buf[idx], ver, verSz);\n        idx += verSz;\n\n        seqSz = SetSequence(totalSz - sdBufSz - idx - 4, seq);\n        XMEMCPY(&buf[idx], seq, seqSz);\n        idx += seqSz;\n\n        /* OID */\n        idx += SetObjectId(sizeof(WC_PKCS12_DATA_OID), &buf[idx]);\n        XMEMCPY(&buf[idx], WC_PKCS12_DATA_OID, sizeof(WC_PKCS12_DATA_OID));\n        idx += sizeof(WC_PKCS12_DATA_OID);\n\n        /* Element */\n        buf[idx++] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC;\n        idx += SetLength(totalSz - sdBufSz - idx - 3, &buf[idx]);\n\n        /* Octet string */\n        idx += SetOctetString(totalSz - sdBufSz - idx - 4, &buf[idx]);\n\n        XMEMCPY(&buf[idx], pkcs12->safe->data, pkcs12->safe->dataSz);\n        idx += pkcs12->safe->dataSz;\n\n        if (pkcs12->signData != NULL) {\n            XMEMCPY(&buf[idx], sdBuf, sdBufSz);\n        }\n\n        if (*der == NULL) {\n            /* Point to start of data allocated for DER */\n            *der = buf;\n        }\n        else {\n            /* Increment pointer to byte past DER */\n            *der = &buf[totalSz];\n        }\n\n        /* Return size of der */\n        ret = totalSz;\n    }\n\n    XFREE(sdBuf, pkcs12->heap, DYNAMIC_TYPE_PKCS);\n    /* Allocation of buf was the last time ret could be a failure,\n     * so no need to free here */\n\n    return ret;\n}\n\n/* helper function to free WC_DerCertList */\nvoid wc_FreeCertList(WC_DerCertList* list, void* heap)\n{\n    WC_DerCertList* current = list;\n    WC_DerCertList* next;\n\n    if (list == NULL) {\n        return;\n    }\n\n    while (current != NULL) {\n        next = current->next;\n        if (current->buffer != NULL) {\n            XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);\n        }\n        XFREE(current, heap, DYNAMIC_TYPE_PKCS);\n        current = next;\n    }\n\n    (void)heap;\n}\n\nstatic void freeDecCertList(WC_DerCertList** list, byte** pkey, word32* pkeySz,\n    byte** cert, word32* certSz, void* heap)\n{\n    WC_DerCertList* current  = *list;\n    WC_DerCertList* previous = NULL;\n    DecodedCert DeCert;\n\n    while (current != NULL) {\n\n        InitDecodedCert(&DeCert, current->buffer, current->bufferSz, heap);\n        if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) == 0) {\n            if (wc_CheckPrivateKey(*pkey, *pkeySz, &DeCert) == 1) {\n                WOLFSSL_MSG(\"Key Pair found\");\n                *cert = current->buffer;\n                *certSz = current->bufferSz;\n\n                if (previous == NULL) {\n                    *list = current->next;\n                }\n                else {\n                    previous->next = current->next;\n                }\n                FreeDecodedCert(&DeCert);\n                XFREE(current, heap, DYNAMIC_TYPE_PKCS);\n                break;\n            }\n        }\n        FreeDecodedCert(&DeCert);\n\n        previous = current;\n        current  = current->next;\n    }\n}\n\n\n/* return 0 on success and negative on failure.\n * By side effect returns private key, cert, and optionally ca.\n * Parses and decodes the parts of PKCS12\n *\n * NOTE: can parse with USER RSA enabled but may return cert that is not the\n *       pair for the key when using RSA key pairs.\n *\n * pkcs12 : non-null WC_PKCS12 struct\n * psw    : password to use for PKCS12 decode\n * pkey   : Private key returned\n * cert   : x509 cert returned\n * ca     : optional ca returned\n */\nint wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,\n        byte** pkey, word32* pkeySz, byte** cert, word32* certSz,\n        WC_DerCertList** ca)\n{\n    ContentInfo* ci       = NULL;\n    WC_DerCertList* certList = NULL;\n    WC_DerCertList* tailList = NULL;\n    byte* buf             = NULL;\n    word32 i, oid;\n    int ret, pswSz;\n    word32 algId;\n\n    WOLFSSL_ENTER(\"wc_PKCS12_parse\");\n\n    if (pkcs12 == NULL || psw == NULL || cert == NULL || certSz == NULL ||\n        pkey == NULL   || pkeySz == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    pswSz = (int)XSTRLEN(psw);\n    *cert = NULL;\n    *pkey = NULL;\n    if (ca != NULL)\n        *ca = NULL;\n\n    /* if there is sign data then verify the MAC */\n    if (pkcs12->signData != NULL ) {\n        if ((ret = wc_PKCS12_verify(pkcs12, pkcs12->safe->data,\n                               pkcs12->safe->dataSz, (byte*)psw, pswSz)) != 0) {\n            WOLFSSL_MSG(\"PKCS12 Bad MAC on verify\");\n            WOLFSSL_LEAVE(\"wc_PKCS12_parse verify \", ret);\n            return MAC_CMP_FAILED_E;\n        }\n    }\n\n    if (pkcs12->safe == NULL) {\n        WOLFSSL_MSG(\"No PKCS12 safes to parse\");\n        return BAD_FUNC_ARG;\n    }\n\n    /* Decode content infos */\n    ci = pkcs12->safe->CI;\n    for (i = 0; i < pkcs12->safe->numCI; i++) {\n        byte*  data;\n        word32 idx = 0;\n        int    size, totalSz;\n        byte   tag;\n\n        if (ci->type == WC_PKCS12_ENCRYPTED_DATA) {\n            int number;\n\n            WOLFSSL_MSG(\"Decrypting PKCS12 Content Info Container\");\n            data = ci->data;\n            if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {\n                ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n            }\n\n            if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {\n                ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n            }\n            if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {\n                goto exit_pk12par;\n            }\n\n            if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) < 0) {\n                goto exit_pk12par;\n            }\n\n            if ((ret = GetShortInt(data, &idx, &number, ci->dataSz)) < 0) {\n                goto exit_pk12par;\n            }\n\n            if (number != 0) {\n                WOLFSSL_MSG(\"Expecting 0 for Integer with Encrypted PKCS12\");\n            }\n\n            if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) < 0) {\n                goto exit_pk12par;\n            }\n\n            ret = GetObjectId(data, &idx, &oid, oidIgnoreType, ci->dataSz);\n            if (ret < 0 || oid != WC_PKCS12_DATA) {\n                WOLFSSL_MSG(\"Not PKCS12 DATA object or get object parse error\");\n                ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n            }\n\n            /* decrypted content overwrites input buffer */\n            size = ci->dataSz - idx;\n            buf = (byte*)XMALLOC(size, pkcs12->heap, DYNAMIC_TYPE_PKCS);\n            if (buf == NULL) {\n                ERROR_OUT(MEMORY_E, exit_pk12par);\n            }\n            XMEMCPY(buf, data + idx, size);\n\n            if ((ret = DecryptContent(buf, size, psw, pswSz)) < 0) {\n                WOLFSSL_MSG(\"Decryption failed, algorithm not compiled in?\");\n                goto exit_pk12par;\n            }\n\n            data = buf;\n            idx = 0;\n\n        #ifdef WOLFSSL_DEBUG_PKCS12\n            {\n                byte* p;\n                for (printf(\"\\tData = \"), p = (byte*)buf;\n                    p < (byte*)buf + size;\n                    printf(\"%02X\", *p), p++);\n                printf(\"\\n\");\n            }\n        #endif\n        }\n        else { /* type DATA */\n            WOLFSSL_MSG(\"Parsing PKCS12 DATA Content Info Container\");\n            data = ci->data;\n            if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {\n                ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n            }\n\n            if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {\n                ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n            }\n            if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {\n                ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n            }\n\n            if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {\n                ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n            }\n            if (tag != ASN_OCTET_STRING) {\n                ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n            }\n            if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {\n                goto exit_pk12par;\n            }\n\n        }\n\n        /* parse through bags in ContentInfo */\n        if ((ret = GetSequence(data, &idx, &totalSz, ci->dataSz)) < 0) {\n            goto exit_pk12par;\n        }\n        totalSz += idx;\n\n        while ((int)idx < totalSz) {\n            int bagSz;\n            if ((ret = GetSequence(data, &idx, &bagSz, ci->dataSz)) < 0) {\n                goto exit_pk12par;\n            }\n            bagSz += idx;\n\n            if ((ret = GetObjectId(data, &idx, &oid, oidIgnoreType,\n                                                             ci->dataSz)) < 0) {\n                goto exit_pk12par;\n            }\n\n            switch (oid) {\n                case WC_PKCS12_KeyBag: /* 667 */\n                    WOLFSSL_MSG(\"PKCS12 Key Bag found\");\n                    if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {\n                        ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n                    }\n                    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {\n                        ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n                    }\n                    if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {\n                        if (ret == 0)\n                            ret = ASN_PARSE_E;\n                        goto exit_pk12par;\n                    }\n                    if (*pkey == NULL) {\n                        *pkey = (byte*)XMALLOC(size, pkcs12->heap,\n                                                       DYNAMIC_TYPE_PUBLIC_KEY);\n                        if (*pkey == NULL) {\n                            ERROR_OUT(MEMORY_E, exit_pk12par);\n                        }\n                        XMEMCPY(*pkey, data + idx, size);\n                        *pkeySz =  ToTraditional_ex(*pkey, size, &algId);\n                    }\n\n                #ifdef WOLFSSL_DEBUG_PKCS12\n                    {\n                        byte* p;\n                        for (printf(\"\\tKey = \"), p = (byte*)*pkey;\n                            p < (byte*)*pkey + size;\n                            printf(\"%02X\", *p), p++);\n                        printf(\"\\n\");\n                    }\n                #endif\n                    idx += size;\n                    break;\n\n                case WC_PKCS12_ShroudedKeyBag: /* 668 */\n                    {\n                        byte* k;\n\n                        WOLFSSL_MSG(\"PKCS12 Shrouded Key Bag found\");\n                        if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {\n                            ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n                        }\n                        if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {\n                            ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n                        }\n                        if ((ret = GetLength(data, &idx, &size,\n                                                             ci->dataSz)) < 0) {\n                            goto exit_pk12par;\n                        }\n\n                        k = (byte*)XMALLOC(size, pkcs12->heap,\n                                                       DYNAMIC_TYPE_PUBLIC_KEY);\n                        if (k == NULL) {\n                            ERROR_OUT(MEMORY_E, exit_pk12par);\n                        }\n                        XMEMCPY(k, data + idx, size);\n\n                        /* overwrites input, be warned */\n                        if ((ret = ToTraditionalEnc(k, size, psw, pswSz,\n                                                                 &algId)) < 0) {\n                            XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);\n                            goto exit_pk12par;\n                        }\n\n                        if (ret < size) {\n                            /* shrink key buffer */\n                            byte* tmp = (byte*)XMALLOC(ret, pkcs12->heap,\n                                                 DYNAMIC_TYPE_PUBLIC_KEY);\n                            if (tmp == NULL) {\n                                XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);\n                                ERROR_OUT(MEMORY_E, exit_pk12par);\n                            }\n                            XMEMCPY(tmp, k, ret);\n                            XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);\n                            k = tmp;\n                        }\n                        size = ret;\n\n                        if (*pkey == NULL) {\n                            *pkey = k;\n                            *pkeySz = size;\n                        }\n                        else { /* only expecting one key */\n                            XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);\n                        }\n                        idx += size;\n\n                    #ifdef WOLFSSL_DEBUG_PKCS12\n                        {\n                            byte* p;\n                            for (printf(\"\\tKey = \"), p = (byte*)k;\n                                p < (byte*)k + ret;\n                                printf(\"%02X\", *p), p++);\n                            printf(\"\\n\");\n                        }\n                    #endif\n                    }\n                    break;\n\n                case WC_PKCS12_CertBag: /* 669 */\n                {\n                    WC_DerCertList* node;\n                    WOLFSSL_MSG(\"PKCS12 Cert Bag found\");\n                    if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {\n                        ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n                    }\n                    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {\n                        ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n                    }\n                    if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {\n                        goto exit_pk12par;\n                    }\n\n                    /* get cert bag type */\n                    if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) <0) {\n                        goto exit_pk12par;\n                    }\n\n                    if ((ret = GetObjectId(data, &idx, &oid, oidIgnoreType,\n                                                             ci->dataSz)) < 0) {\n                        goto exit_pk12par;\n                    }\n\n                    switch (oid) {\n                        case WC_PKCS12_CertBag_Type1:  /* 675 */\n                            /* type 1 */\n                            WOLFSSL_MSG(\"PKCS12 cert bag type 1\");\n                            if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {\n                                ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n                            }\n                            if (tag != (ASN_CONSTRUCTED |\n                                        ASN_CONTEXT_SPECIFIC)) {\n                                ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n                            }\n                            if ((ret = GetLength(data, &idx, &size, ci->dataSz))\n                                                                         <= 0) {\n                                if (ret == 0)\n                                    ret = ASN_PARSE_E;\n                                goto exit_pk12par;\n                            }\n                            if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {\n                                ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n                            }\n                            if (tag != ASN_OCTET_STRING) {\n                                ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n\n                            }\n                            if ((ret = GetLength(data, &idx, &size, ci->dataSz))\n                                                                          < 0) {\n                                goto exit_pk12par;\n                            }\n                            break;\n                       default:\n                            WOLFSSL_MSG(\"Unknown PKCS12 cert bag type\");\n                    }\n\n                    if (size + idx > (word32)bagSz) {\n                        ERROR_OUT(ASN_PARSE_E, exit_pk12par);\n                    }\n\n                    /* list to hold all certs found */\n                    node = (WC_DerCertList*)XMALLOC(sizeof(WC_DerCertList),\n                                               pkcs12->heap, DYNAMIC_TYPE_PKCS);\n                    if (node == NULL) {\n                        ERROR_OUT(MEMORY_E, exit_pk12par);\n                    }\n                    XMEMSET(node, 0, sizeof(WC_DerCertList));\n\n                    node->buffer = (byte*)XMALLOC(size, pkcs12->heap,\n                                                             DYNAMIC_TYPE_PKCS);\n                    if (node->buffer == NULL) {\n                        XFREE(node, pkcs12->heap, DYNAMIC_TYPE_PKCS);\n                        ERROR_OUT(MEMORY_E, exit_pk12par);\n                    }\n                    XMEMCPY(node->buffer, data + idx, size);\n                    node->bufferSz = size;\n\n                    /* put the new node into the list */\n                    if (certList != NULL) {\n                        WOLFSSL_MSG(\"Pushing new cert onto queue\");\n                        tailList->next = node;\n                        tailList = node;\n                    }\n                    else {\n                        certList = node;\n                        tailList = node;\n                    }\n\n                    /* on to next */\n                    idx += size;\n                }\n                    break;\n\n                case WC_PKCS12_CrlBag: /* 670 */\n                    WOLFSSL_MSG(\"PKCS12 CRL BAG not yet supported\");\n                    break;\n\n                case WC_PKCS12_SecretBag: /* 671 */\n                    WOLFSSL_MSG(\"PKCS12 Secret BAG not yet supported\");\n                    break;\n\n                case WC_PKCS12_SafeContentsBag: /* 672 */\n                    WOLFSSL_MSG(\"PKCS12 Safe Contents BAG not yet supported\");\n                    break;\n\n                default:\n                    WOLFSSL_MSG(\"Unknown PKCS12 BAG type found\");\n            }\n\n            /* Attribute, unknown bag or unsupported */\n            if ((int)idx < bagSz) {\n                idx = bagSz; /* skip for now */\n            }\n        }\n\n        /* free temporary buffer */\n        if (buf != NULL) {\n            XFREE(buf, pkcs12->heap, DYNAMIC_TYPE_PKCS);\n            buf = NULL;\n        }\n\n        ci = ci->next;\n        WOLFSSL_MSG(\"Done Parsing PKCS12 Content Info Container\");\n    }\n\n    /* check if key pair, remove from list */\n    if (*pkey != NULL) {\n        freeDecCertList(&certList, pkey, pkeySz, cert, certSz, pkcs12->heap);\n    }\n\n    /* if ca arg provided return certList, otherwise free it */\n    if (ca != NULL) {\n        *ca = certList;\n    }\n    else {\n        /* free list, not wanted */\n        wc_FreeCertList(certList, pkcs12->heap);\n    }\n    (void)tailList; /* not used */\n\n    ret = 0; /* success */\n\nexit_pk12par:\n\n    if (ret != 0) {\n        /* failure cleanup */\n        if (*pkey) {\n            XFREE(*pkey, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);\n            *pkey = NULL;\n        }\n        if (buf) {\n            XFREE(buf, pkcs12->heap, DYNAMIC_TYPE_PKCS);\n            buf = NULL;\n        }\n\n        wc_FreeCertList(certList, pkcs12->heap);\n    }\n\n    return ret;\n}\n\n\n/* Helper function to shroud keys.\n *\n * pkcs12 structure to use with shrouding key\n * rng    random number generator used\n * out    buffer to hold results\n * outSz  size of out buffer\n * key    key that is going to be shrouded\n * keySz  size of key buffer\n * vAlgo  algorithm version\n * pass   password to use\n * passSz size of pass buffer\n * itt    number of iterations\n *\n * returns the size of the shrouded key on success\n */\nstatic int wc_PKCS12_shroud_key(WC_PKCS12* pkcs12, WC_RNG* rng,\n        byte* out, word32* outSz, byte* key, word32 keySz, int vAlgo,\n        const char* pass, int passSz, int itt)\n{\n    void* heap;\n    word32 tmpIdx = 0;\n    int vPKCS     = 1; /* PKCS#12 default set to 1 */\n    word32 sz;\n    word32 totalSz = 0;\n    int ret;\n\n\n    if (outSz == NULL || pkcs12 == NULL || rng == NULL || key == NULL ||\n            pass == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    heap = wc_PKCS12_GetHeap(pkcs12);\n\n    /* check if trying to get size */\n    if (out != NULL) {\n        tmpIdx += MAX_LENGTH_SZ + 1; /* save room for length and tag (+1) */\n        sz = *outSz - tmpIdx;\n    }\n\n    /* case of no encryption */\n    if (vAlgo < 0) {\n        const byte* curveOID = NULL;\n        word32 oidSz = 0;\n        int algoID;\n\n        WOLFSSL_MSG(\"creating PKCS12 Key Bag\");\n\n        /* check key type and get OID if ECC */\n        if ((ret = wc_GetKeyOID(key, keySz, &curveOID, &oidSz, &algoID, heap))\n                < 0) {\n            return ret;\n        }\n\n        /* PKCS#8 wrapping around key */\n        ret = wc_CreatePKCS8Key(out + tmpIdx, &sz, key, keySz, algoID,\n                curveOID, oidSz);\n    }\n    else {\n        WOLFSSL_MSG(\"creating PKCS12 Shrouded Key Bag\");\n\n        if (vAlgo == PBE_SHA1_DES) {\n            vPKCS = PKCS5;\n            vAlgo = 10;\n        }\n\n        ret = UnTraditionalEnc(key, keySz, out + tmpIdx, &sz, pass, passSz,\n                vPKCS, vAlgo, NULL, 0, itt, rng, heap);\n    }\n    if (ret == LENGTH_ONLY_E) {\n        *outSz =  sz + MAX_LENGTH_SZ + 1;\n        return LENGTH_ONLY_E;\n    }\n    if (ret < 0) {\n        return ret;\n    }\n\n    totalSz += ret;\n\n    /* out should not be null at this point but check before writing */\n    if (out == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* rewind index and set tag and length */\n    tmpIdx -= MAX_LENGTH_SZ + 1;\n    sz = SetExplicit(0, ret, out + tmpIdx);\n    tmpIdx += sz; totalSz += sz;\n    XMEMMOVE(out + tmpIdx, out + MAX_LENGTH_SZ + 1, ret);\n\n    return totalSz;\n}\n\n\n/* Helper function to create key bag.\n *\n * pkcs12 structure to use with key bag\n * rng    random number generator used\n * out    buffer to hold results\n * outSz  size of out buffer\n * key    key that is going into key bag\n * keySz  size of key buffer\n * algo   algorithm version\n * iter   number of iterations\n * pass   password to use\n * passSz size of pass buffer\n *\n * returns the size of the key bag on success\n */\nstatic int wc_PKCS12_create_key_bag(WC_PKCS12* pkcs12, WC_RNG* rng,\n        byte* out, word32* outSz, byte* key, word32 keySz, int algo, int iter,\n        char* pass, int passSz)\n{\n    void* heap;\n    byte* tmp;\n    word32 length  = 0;\n    word32 idx     = 0;\n    word32 totalSz = 0;\n    word32 sz;\n    word32 i;\n    word32 tmpSz;\n    int ret;\n\n    /* get max size for shrouded key */\n    ret =  wc_PKCS12_shroud_key(pkcs12, rng, NULL, &length, key, keySz,\n            algo, pass, passSz, iter);\n    if (ret != LENGTH_ONLY_E && ret < 0) {\n        return ret;\n    }\n\n    if (out == NULL) {\n        *outSz = MAX_SEQ_SZ + WC_PKCS12_DATA_OBJ_SZ + 1 + MAX_LENGTH_SZ +\n            length;\n        return LENGTH_ONLY_E;\n    }\n\n    heap = wc_PKCS12_GetHeap(pkcs12);\n\n    /* leave room for sequence */\n    idx += MAX_SEQ_SZ;\n\n    if (algo < 0) { /* not encrypted */\n        out[idx++] = ASN_OBJECT_ID; totalSz++;\n        sz = SetLength(sizeof(WC_PKCS12_KeyBag_OID), out + idx);\n        idx += sz; totalSz += sz;\n        for (i = 0; i < sizeof(WC_PKCS12_KeyBag_OID); i++) {\n            out[idx++] = WC_PKCS12_KeyBag_OID[i]; totalSz++;\n        }\n    }\n    else { /* encrypted */\n        out[idx++] = ASN_OBJECT_ID; totalSz++;\n        sz = SetLength(sizeof(WC_PKCS12_ShroudedKeyBag_OID), out + idx);\n        idx += sz; totalSz += sz;\n        for (i = 0; i < sizeof(WC_PKCS12_ShroudedKeyBag_OID); i++) {\n            out[idx++] = WC_PKCS12_ShroudedKeyBag_OID[i]; totalSz++;\n        }\n    }\n\n    /* shroud key */\n    tmp = (byte*)XMALLOC(length, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (tmp == NULL) {\n        return MEMORY_E;\n    }\n\n    ret =  wc_PKCS12_shroud_key(pkcs12, rng, tmp, &length, key, keySz,\n            algo, pass, passSz, iter);\n    if (ret < 0) {\n        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return ret;\n    }\n    length = ret;\n    XMEMCPY(out + idx, tmp, length);\n    XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    totalSz += length;\n\n    /* set beginning sequence */\n    tmpSz = SetSequence(totalSz, out);\n    XMEMMOVE(out + tmpSz, out + MAX_SEQ_SZ, totalSz);\n\n    (void)heap;\n    return totalSz + tmpSz;\n}\n\n\n/* Helper function to create cert bag.\n *\n * pkcs12 structure to use with cert bag\n * out    buffer to hold results\n * outSz  size of out buffer\n * cert   cert that is going into cert bag\n * certSz size of cert buffer\n *\n * returns the size of the cert bag on success\n */\nstatic int wc_PKCS12_create_cert_bag(WC_PKCS12* pkcs12,\n        byte* out, word32* outSz, byte* cert, word32 certSz)\n{\n    word32 length = 0;\n    word32 idx = 0;\n    word32 totalSz = 0;\n    word32 sz;\n    int WC_CERTBAG_OBJECT_ID  = 13;\n    int WC_CERTBAG1_OBJECT_ID = 12;\n    word32 i;\n    word32 tmpSz;\n\n    if (out == NULL) {\n        *outSz = MAX_SEQ_SZ + WC_CERTBAG_OBJECT_ID + 1 + MAX_LENGTH_SZ +\n            MAX_SEQ_SZ + WC_CERTBAG1_OBJECT_ID + 1 + MAX_LENGTH_SZ + 1 +\n            MAX_LENGTH_SZ + certSz;\n        return LENGTH_ONLY_E;\n    }\n\n    /* check buffer size able to handle max size */\n    if (*outSz < (MAX_SEQ_SZ + WC_CERTBAG_OBJECT_ID + 1 + MAX_LENGTH_SZ +\n            MAX_SEQ_SZ + WC_CERTBAG1_OBJECT_ID + 1 + MAX_LENGTH_SZ + 1 +\n            MAX_LENGTH_SZ + certSz)) {\n        return BUFFER_E;\n    }\n\n    /* save room for sequence */\n    idx += MAX_SEQ_SZ;\n\n    /* objectId WC_PKCS12_CertBag */\n    out[idx++] = ASN_OBJECT_ID; totalSz++;\n    sz = SetLength(sizeof(WC_PKCS12_CertBag_OID), out + idx);\n    idx += sz; totalSz += sz;\n    for (i = 0; i < sizeof(WC_PKCS12_CertBag_OID); i++) {\n        out[idx++] = WC_PKCS12_CertBag_OID[i]; totalSz++;\n    }\n\n    /**** Cert Bag type 1 ****/\n    out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); totalSz++;\n\n    /* save room for length and sequence */\n    idx += MAX_LENGTH_SZ;\n    idx += MAX_SEQ_SZ;\n\n    /* object id WC_PKCS12_CertBag_Type1 */\n    out[idx++] = ASN_OBJECT_ID; length++;\n    sz = SetLength(sizeof(WC_PKCS12_CertBag_Type1_OID), out + idx);\n    idx += sz; length += sz;\n    for (i = 0; i < sizeof(WC_PKCS12_CertBag_Type1_OID); i++) {\n        out[idx++] = WC_PKCS12_CertBag_Type1_OID[i]; length++;\n    }\n\n    out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); length++;\n    sz = 0;\n    idx += MAX_LENGTH_SZ; /* save room for length */\n\n    /* place the cert in the buffer */\n    out[idx++] = ASN_OCTET_STRING; sz++;\n    tmpSz = SetLength(certSz, out + idx);\n    idx += tmpSz; sz += tmpSz;\n    XMEMCPY(out + idx, cert, certSz);\n    idx += certSz; sz += certSz;\n\n    /* rewind idx and place length */\n    idx -= (sz + MAX_LENGTH_SZ);\n    tmpSz = SetLength(sz, out + idx);\n    XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, sz);\n    idx += tmpSz + sz; length += tmpSz + sz;\n\n    /* rewind idx and set sequence */\n    idx -= (length + MAX_SEQ_SZ);\n    tmpSz = SetSequence(length, out + idx);\n    XMEMMOVE(out + idx + tmpSz, out + idx + MAX_SEQ_SZ, length);\n    length += tmpSz;\n\n    /* place final length */\n    idx -= MAX_LENGTH_SZ;\n    tmpSz = SetLength(length, out + idx);\n    XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, length);\n    length += tmpSz;\n\n    /* place final sequence */\n    totalSz += length;\n    tmpSz = SetSequence(totalSz, out);\n    XMEMMOVE(out + tmpSz, out + MAX_SEQ_SZ, totalSz);\n\n    (void)pkcs12;\n\n    return totalSz + tmpSz;\n}\n\n\n/* Helper function to encrypt content.\n *\n * pkcs12    structure to use with key bag\n * rng       random number generator used\n * out       buffer to hold results\n * outSz     size of out buffer\n * content   content to encrypt\n * contentSz size of content buffer\n * vAlgo     algorithm version\n * pass      password to use\n * passSz    size of pass buffer\n * iter      number of iterations\n * type      content type i.e WC_PKCS12_ENCRYPTED_DATA or WC_PKCS12_DATA\n *\n * returns the size of result on success\n */\nstatic int wc_PKCS12_encrypt_content(WC_PKCS12* pkcs12, WC_RNG* rng,\n        byte* out, word32* outSz, byte* content, word32 contentSz, int vAlgo,\n        const char* pass, int passSz, int iter, int type)\n{\n    void* heap;\n    int vPKCS     = 1; /* PKCS#12 is always set to 1 */\n    int ret;\n    byte*  tmp;\n    word32 idx = 0;\n    word32 totalSz = 0;\n    word32 length = 0;\n    word32 tmpSz;\n    word32 encSz;\n    word32 i;\n\n    WOLFSSL_MSG(\"encrypting PKCS12 content\");\n\n    heap = wc_PKCS12_GetHeap(pkcs12);\n\n    /* ENCRYPTED DATA\n     * ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC\n     * length\n     * sequence\n     * short int\n     * sequence\n     * get object id */\n    if (type == WC_PKCS12_ENCRYPTED_DATA) {\n        if (out == NULL) {\n            *outSz = 1 + MAX_LENGTH_SZ + MAX_SEQ_SZ + MAX_VERSION_SZ +\n                MAX_SEQ_SZ + WC_PKCS12_DATA_OBJ_SZ;\n            ret = EncryptContent(NULL, contentSz + MAX_SEQ_SZ, NULL, &encSz,\n                    pass, passSz, vPKCS, vAlgo, NULL, 0, iter, rng, heap);\n            if (ret != LENGTH_ONLY_E) {\n                return ret;\n            }\n\n            *outSz += encSz;\n            return LENGTH_ONLY_E;\n        }\n\n        if (*outSz < (1 + MAX_LENGTH_SZ + MAX_SEQ_SZ + MAX_VERSION_SZ)) {\n            return BUFFER_E;\n        }\n        out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); totalSz++;\n\n        /* save room for length and sequence */\n        idx += MAX_LENGTH_SZ;\n        idx += MAX_SEQ_SZ;\n\n        tmpSz = SetMyVersion(0, out + idx, 0);\n        idx += tmpSz; length += tmpSz;\n\n        encSz = contentSz;\n        if ((ret = EncryptContent(NULL, contentSz, NULL, &encSz,\n                   pass, passSz, vPKCS, vAlgo, NULL, 0, iter, rng, heap)) < 0) {\n            if (ret != LENGTH_ONLY_E) {\n                return ret;\n            }\n        }\n\n        if (*outSz < (idx + MAX_SEQ_SZ + WC_PKCS12_DATA_OBJ_SZ + encSz)) {\n            return BUFFER_E;\n        }\n        tmp = (byte*)XMALLOC(encSz, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (tmp == NULL) {\n            return MEMORY_E;\n        }\n\n        if ((ret = EncryptContent(content, contentSz, tmp, &encSz,\n                   pass, passSz, vPKCS, vAlgo, NULL, 0, iter, rng, heap)) < 0) {\n            XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n            return ret;\n        }\n        encSz = ret;\n\n        #ifdef WOLFSSL_DEBUG_PKCS12\n        {\n            byte* p;\n            for (printf(\"(size %u) Encrypted Content = \", encSz),\n                    p = (byte*)tmp;\n                p < (byte*)tmp + encSz;\n                printf(\"%02X\", *p), p++);\n            printf(\"\\n\");\n        }\n        #endif\n\n        tmpSz = SetSequence(WC_PKCS12_DATA_OBJ_SZ + encSz, out + idx);\n        idx += tmpSz; length += tmpSz;\n\n        out[idx++] = ASN_OBJECT_ID; length++;\n        tmpSz = SetLength(sizeof(WC_PKCS12_DATA_OID), out + idx);\n        idx += tmpSz; length += tmpSz;\n        for (i = 0; i < sizeof(WC_PKCS12_DATA_OID); i++) {\n            out[idx++] = WC_PKCS12_DATA_OID[i]; length++;\n        }\n\n        /* copy over encrypted data */\n        XMEMCPY(out + idx, tmp, encSz);\n        XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        idx += encSz; length += encSz;\n\n        /* rewind and place sequence */\n        idx -= (length + MAX_SEQ_SZ);\n        tmpSz = SetSequence(length, out + idx);\n        XMEMMOVE(out + idx + tmpSz, out + idx + MAX_SEQ_SZ, length);\n        length += tmpSz;\n\n        /* now place length */\n        idx -= MAX_LENGTH_SZ;\n        tmpSz = SetLength(length, out + idx);\n        XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, length);\n        totalSz += length + tmpSz;\n\n        return totalSz;\n    }\n\n    /* DATA\n     * ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC\n     * length\n     * ASN_OCTET_STRING\n     * length\n     * sequence containing all bags */\n    if (type == WC_PKCS12_DATA) {\n        if (out == NULL) {\n            *outSz = 1 + MAX_LENGTH_SZ + 1 + MAX_LENGTH_SZ + contentSz;\n            return LENGTH_ONLY_E;\n        }\n\n        if (*outSz < (1 + MAX_LENGTH_SZ + 1 + MAX_LENGTH_SZ + contentSz)) {\n            return BUFFER_E;\n        }\n\n        out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC);\n        totalSz++;\n\n        /* save room for length */\n        idx += MAX_LENGTH_SZ;\n\n        out[idx++] = ASN_OCTET_STRING; length++;\n        tmpSz = SetLength(contentSz, out + idx);\n        idx += tmpSz; length += tmpSz;\n\n        /* sequence containing all bags */\n        XMEMCPY(out + idx, content, contentSz);\n        idx += contentSz; length += contentSz;\n\n        idx -= (MAX_LENGTH_SZ + length);\n        tmpSz = SetLength(length, out + idx);\n        XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, length);\n        totalSz += length + tmpSz;\n\n        return totalSz;\n    }\n\n    WOLFSSL_MSG(\"Unknown/Unsupported content type\");\n    return BAD_FUNC_ARG;\n}\n\n\n/*\n * pass : password to use with encryption\n * passSz : size of the password buffer\n * name : friendlyName to use\n * key  : DER format of key\n * keySz : size of key buffer\n * cert : DER format of certificate\n * certSz : size of the certificate buffer\n * ca   : a list of extra certificates\n * nidKey  : type of encryption to use on the key (-1 means no encryption)\n * nidCert : type of encryption to use on the certificate\n *           (-1 means no encryption)\n * iter    : number of iterations with encryption\n * macIter : number of iterations when creating MAC\n * keyType : flag for signature and/or encryption key\n * heap : pointer to allocate from memory\n *\n * returns a pointer to a new WC_PKCS12 structure on success and NULL if failed\n */\nWC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name,\n        byte* key, word32 keySz, byte* cert, word32 certSz, WC_DerCertList* ca,\n        int nidKey, int nidCert, int iter, int macIter, int keyType, void* heap)\n{\n    WC_PKCS12*         pkcs12;\n    AuthenticatedSafe* safe;\n    ContentInfo*       ci;\n    WC_RNG rng;\n    int algo;\n    int ret;\n    int type;\n    word32 idx;\n    word32 sz;\n    word32 tmpSz;\n\n    byte*  certCi = NULL;\n    word32 certCiSz;\n    byte*  keyCi;\n    word32 keyCiSz;\n\n    byte*  certBuf = NULL;\n    word32 certBufSz;\n    byte*  keyBuf;\n    word32 keyBufSz = 0;\n\n    WOLFSSL_ENTER(\"wc_PKCS12_create()\");\n\n    if ((ret = wc_InitRng_ex(&rng, heap, INVALID_DEVID)) != 0) {\n        return NULL;\n    }\n\n    if ((pkcs12 = wc_PKCS12_new()) == NULL) {\n        wc_FreeRng(&rng);\n        WOLFSSL_LEAVE(\"wc_PKCS12_create\", MEMORY_E);\n        return NULL;\n    }\n\n    if ((ret = wc_PKCS12_SetHeap(pkcs12, heap)) != 0) {\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        WOLFSSL_LEAVE(\"wc_PKCS12_create\", ret);\n        return NULL;\n    }\n\n    if (iter <= 0) {\n        iter = WC_PKCS12_ITT_DEFAULT;\n    }\n\n    /**** add private key bag ****/\n    switch (nidKey) {\n        case PBE_SHA1_RC4_128:\n            algo = 1;\n            break;\n\n        case PBE_SHA1_DES:\n            algo = 2;\n            break;\n\n        case PBE_SHA1_DES3:\n            algo = 3;\n            break;\n\n        /* no encryption */\n        case -1:\n            algo = -1;\n            break;\n\n        default:\n            WOLFSSL_MSG(\"Unknown/Unsupported key encryption\");\n            wc_PKCS12_free(pkcs12);\n            wc_FreeRng(&rng);\n            return NULL;\n    }\n\n    /* get max size for key bag */\n    ret = wc_PKCS12_create_key_bag(pkcs12, &rng, NULL, &keyBufSz, key, keySz,\n            algo, iter, pass, passSz);\n    if (ret != LENGTH_ONLY_E && ret < 0) {\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        WOLFSSL_LEAVE(\"wc_PKCS12_create\", ret);\n        return NULL;\n    }\n\n    /* account for sequence around bag */\n    keyBufSz += MAX_SEQ_SZ;\n\n    keyBuf = (byte*)XMALLOC(keyBufSz, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (keyBuf == NULL) {\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        WOLFSSL_LEAVE(\"wc_PKCS12_create\", MEMORY_E);\n        return NULL;\n    }\n\n    ret = wc_PKCS12_create_key_bag(pkcs12, &rng, keyBuf + MAX_SEQ_SZ, &keyBufSz,\n            key, keySz, algo, iter, pass, passSz);\n    if (ret < 0) {\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        WOLFSSL_LEAVE(\"wc_PKCS12_create\", ret);\n        return NULL;\n    }\n    keyBufSz = ret;\n\n    tmpSz = SetSequence(keyBufSz, keyBuf);\n    XMEMMOVE(keyBuf + tmpSz, keyBuf + MAX_SEQ_SZ, keyBufSz);\n    keyBufSz += tmpSz;\n\n    ret = wc_PKCS12_encrypt_content(pkcs12, &rng, NULL, &keyCiSz,\n            NULL, keyBufSz, algo, pass, passSz, iter, WC_PKCS12_DATA);\n    if (ret != LENGTH_ONLY_E) {\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        WOLFSSL_LEAVE(\"wc_PKCS12_create\", ret);\n        return NULL;\n    }\n    keyCi = (byte*)XMALLOC(keyCiSz, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (keyCi == NULL) {\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return NULL;\n    }\n\n    ret = wc_PKCS12_encrypt_content(pkcs12, &rng, keyCi, &keyCiSz,\n            keyBuf, keyBufSz, algo, pass, passSz, iter, WC_PKCS12_DATA);\n    if (ret < 0 ) {\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        WOLFSSL_LEAVE(\"wc_PKCS12_create\", ret);\n        return NULL;\n    }\n    keyCiSz = ret;\n    XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    #ifdef WOLFSSL_DEBUG_PKCS12\n    {\n        byte* p;\n        for (printf(\"(size %u) Key Content Info = \", keyCiSz), p = (byte*)keyCi;\n            p < (byte*)keyCi + keyCiSz;\n            printf(\"%02X\", *p), p++);\n        printf(\"\\n\");\n    }\n    #endif\n\n\n    /**** add main certificate bag and extras ****/\n    switch (nidCert) {\n        case PBE_SHA1_RC4_128:\n            type = WC_PKCS12_ENCRYPTED_DATA;\n            algo = 1;\n            break;\n\n        case PBE_SHA1_DES:\n            type = WC_PKCS12_ENCRYPTED_DATA;\n            algo = 2;\n            break;\n\n        case PBE_SHA1_DES3:\n            type = WC_PKCS12_ENCRYPTED_DATA;\n            algo = 3;\n            break;\n\n        case -1:\n            type = WC_PKCS12_DATA;\n            algo = -1;\n            break;\n\n        default:\n            WOLFSSL_MSG(\"Unknown/Unsupported certificate encryption\");\n            XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n            wc_PKCS12_free(pkcs12);\n            wc_FreeRng(&rng);\n            return NULL;\n    }\n\n    /* get max size of buffer needed */\n    ret = wc_PKCS12_create_cert_bag(pkcs12, NULL, &certBufSz, cert, certSz);\n    if (ret != LENGTH_ONLY_E) {\n        XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        return NULL;\n    }\n\n    if (ca != NULL) {\n        WC_DerCertList* current = ca;\n        word32 curBufSz = 0;\n\n        /* get max buffer size */\n        while (current != NULL) {\n            ret = wc_PKCS12_create_cert_bag(pkcs12, NULL, &curBufSz,\n                    current->buffer, current->bufferSz);\n            if (ret != LENGTH_ONLY_E) {\n                XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n                wc_PKCS12_free(pkcs12);\n                wc_FreeRng(&rng);\n                return NULL;\n            }\n            certBufSz += curBufSz;\n            current    = current->next;\n        }\n    }\n\n    /* account for Sequence that holds all certificate bags */\n    certBufSz += MAX_SEQ_SZ;\n\n    /* completed getting max size, now create buffer and start adding bags */\n    certBuf = (byte*)XMALLOC(certBufSz, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (certBuf == NULL) {\n        XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        WOLFSSL_MSG(\"Memory error creating certificate bags\");\n        return NULL;\n    }\n\n    idx = 0;\n    idx += MAX_SEQ_SZ;\n\n    sz = certBufSz - idx;\n    if ((ret = wc_PKCS12_create_cert_bag(pkcs12, certBuf + idx, &sz,\n            cert, certSz)) < 0) {\n        XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        return NULL;\n    }\n    idx += ret;\n\n    if (ca != NULL) {\n        WC_DerCertList* current = ca;\n\n        while (current != NULL) {\n            sz = certBufSz - idx;\n            if ((ret = wc_PKCS12_create_cert_bag(pkcs12, certBuf + idx, &sz,\n               current->buffer, current->bufferSz)) < 0) {\n                XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n                XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);\n                wc_PKCS12_free(pkcs12);\n                wc_FreeRng(&rng);\n                return NULL;\n            }\n            idx    += ret;\n            current = current->next;\n        }\n    }\n\n    /* set sequence and create encrypted content with all certificate bags */\n    tmpSz = SetSequence(idx - MAX_SEQ_SZ, certBuf);\n    XMEMMOVE(certBuf + tmpSz, certBuf + MAX_SEQ_SZ, idx - MAX_SEQ_SZ);\n    certBufSz = tmpSz + (idx - MAX_SEQ_SZ);\n\n    /* get buffer size needed for content info */\n    ret = wc_PKCS12_encrypt_content(pkcs12, &rng, NULL, &certCiSz,\n            NULL, certBufSz, algo, pass, passSz, iter, type);\n    if (ret != LENGTH_ONLY_E) {\n        XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        WOLFSSL_LEAVE(\"wc_PKCS12_create()\", ret);\n        return NULL;\n    }\n    certCi = (byte*)XMALLOC(certCiSz, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (certCi == NULL) {\n        XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        return NULL;\n    }\n\n    ret = wc_PKCS12_encrypt_content(pkcs12, &rng, certCi, &certCiSz,\n            certBuf, certBufSz, algo, pass, passSz, iter, type);\n    if (ret < 0) {\n        XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        WOLFSSL_LEAVE(\"wc_PKCS12_create()\", ret);\n        return NULL;\n    }\n    certCiSz = ret;\n    XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    #ifdef WOLFSSL_DEBUG_PKCS12\n    {\n        byte* p;\n        for (printf(\"(size %u) Encrypted Certificate Content Info = \",certCiSz),\n                p = (byte*)certCi;\n            p < (byte*)certCi + certCiSz;\n            printf(\"%02X\", *p), p++);\n        printf(\"\\n\");\n    }\n    #endif\n\n    /**** create safe and and Content Info ****/\n    safe = (AuthenticatedSafe*)XMALLOC(sizeof(AuthenticatedSafe), heap,\n            DYNAMIC_TYPE_PKCS);\n    if (safe == NULL) {\n        XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        return NULL;\n    }\n    pkcs12->safe = safe; /* set so all of safe is free'd with wc_PKCS12_free */\n    XMEMSET(safe, 0, sizeof(AuthenticatedSafe));\n\n    safe->dataSz = certCiSz + keyCiSz;\n    safe->data   = (byte*)XMALLOC(safe->dataSz, heap, DYNAMIC_TYPE_PKCS);\n    if (safe->data == NULL) {\n        XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        return NULL;\n    }\n    XMEMCPY(safe->data, certCi, certCiSz);\n    XMEMCPY(safe->data + certCiSz, keyCi, keyCiSz);\n    XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(keyCi,  heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    safe->numCI = 2;\n\n    /* add Content Info structs to safe, key first then cert */\n    ci = (ContentInfo*)XMALLOC(sizeof(ContentInfo), heap, DYNAMIC_TYPE_PKCS);\n    if (ci == NULL) {\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        return NULL;\n    }\n    XMEMSET(ci, 0, sizeof(ContentInfo));\n    safe->CI = ci;\n    ci->data = safe->data + certCiSz;\n    ci->dataSz = keyCiSz;\n    ci->type = WC_PKCS12_DATA;\n\n    ci = (ContentInfo*)XMALLOC(sizeof(ContentInfo), heap, DYNAMIC_TYPE_PKCS);\n    if (ci == NULL) {\n        wc_PKCS12_free(pkcs12);\n        wc_FreeRng(&rng);\n        return NULL;\n    }\n    XMEMSET(ci, 0, sizeof(ContentInfo));\n    ci->next = safe->CI;\n    safe->CI = ci;\n    ci->data = safe->data;\n    ci->dataSz = certCiSz;\n    if (nidCert < 0) {\n        ci->type = WC_PKCS12_DATA;\n    }\n    else {\n        ci->type = WC_PKCS12_ENCRYPTED_DATA;\n    }\n\n    /* create MAC */\n    if (macIter > 0) {\n        MacData* mac;\n        byte digest[WC_MAX_DIGEST_SIZE]; /* for MAC */\n\n        mac = (MacData*)XMALLOC(sizeof(MacData), heap, DYNAMIC_TYPE_PKCS);\n        if (mac == NULL) {\n            wc_PKCS12_free(pkcs12);\n            wc_FreeRng(&rng);\n            return NULL;\n        }\n        XMEMSET(mac, 0, sizeof(MacData));\n        pkcs12->signData = mac; /* now wc_PKCS12_free will free all mac too */\n\n        #ifndef NO_SHA256\n            mac->oid = SHA256h;\n        #elif !defined(NO_SHA)\n            mac->oid = SHA;\n        #elif defined(WOLFSSL_SHA384)\n            mac->oid = SHA384;\n        #elif defined(WOLFSSL_SHA512)\n            mac->oid = SHA512;\n        #else\n            WOLFSSL_MSG(\"No supported hash algorithm compiled in!\");\n            wc_PKCS12_free(pkcs12);\n            wc_FreeRng(&rng);\n            return NULL;\n        #endif\n\n        /* store number of iterations */\n        mac->itt = macIter;\n\n        /* set mac salt */\n        mac->saltSz = 8;\n        mac->salt = (byte*)XMALLOC(mac->saltSz, heap, DYNAMIC_TYPE_PKCS);\n        if (mac->salt == NULL) {\n            wc_PKCS12_free(pkcs12);\n            wc_FreeRng(&rng);\n            return NULL;\n        }\n\n        if ((ret = wc_RNG_GenerateBlock(&rng, mac->salt, mac->saltSz)) != 0) {\n            WOLFSSL_MSG(\"Error generating random salt\");\n            wc_PKCS12_free(pkcs12);\n            wc_FreeRng(&rng);\n            return NULL;\n        }\n        ret = wc_PKCS12_create_mac(pkcs12, safe->data, safe->dataSz,\n                         (const byte*)pass, passSz, digest, WC_MAX_DIGEST_SIZE);\n        if (ret < 0) {\n            wc_PKCS12_free(pkcs12);\n            wc_FreeRng(&rng);\n            return NULL;\n        }\n\n        mac->digestSz = ret;\n        mac->digest = (byte*)XMALLOC(ret, heap, DYNAMIC_TYPE_PKCS);\n        if (mac->digest == NULL) {\n            wc_PKCS12_free(pkcs12);\n            wc_FreeRng(&rng);\n            return NULL;\n        }\n        XMEMCPY(mac->digest, digest, mac->digestSz);\n    }\n    else {\n        pkcs12->signData = NULL;\n    }\n\n    wc_FreeRng(&rng);\n    (void)name;\n    (void)keyType;\n\n    return pkcs12;\n}\n\n\n/* if using a specific memory heap */\nint wc_PKCS12_SetHeap(WC_PKCS12* pkcs12, void* heap)\n{\n    if (pkcs12 == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    pkcs12->heap = heap;\n\n    return 0;\n}\n\n\n/* getter for heap */\nvoid* wc_PKCS12_GetHeap(WC_PKCS12* pkcs12)\n{\n    if (pkcs12 == NULL) {\n        return NULL;\n    }\n\n    return pkcs12->heap;\n}\n\n#undef ERROR_OUT\n\n#endif /* !NO_ASN && !NO_PWDBASED && HAVE_PKCS12 */\n"
  },
  {
    "path": "src/wolfcrypt/src/pkcs7.c",
    "content": "/* pkcs7.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_PKCS7\n\n#include <wolfssl/wolfcrypt/pkcs7.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#include <wolfssl/wolfcrypt/hash.h>\n#ifndef NO_RSA\n    #include <wolfssl/wolfcrypt/rsa.h>\n#endif\n#ifdef HAVE_ECC\n    #include <wolfssl/wolfcrypt/ecc.h>\n#endif\n#ifdef HAVE_LIBZ\n    #include <wolfssl/wolfcrypt/compress.h>\n#endif\n#ifndef NO_PWDBASED\n    #include <wolfssl/wolfcrypt/pwdbased.h>\n#endif\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n/* direction for processing, encoding or decoding */\ntypedef enum {\n    WC_PKCS7_ENCODE,\n    WC_PKCS7_DECODE\n} pkcs7Direction;\n\n#define NO_USER_CHECK 0\n\n/* holds information about the signers */\nstruct PKCS7SignerInfo {\n    int version;\n    byte  *sid;\n    word32 sidSz;\n};\n\n\n#ifndef NO_PKCS7_STREAM\n\n#define MAX_PKCS7_STREAM_BUFFER 256\nstruct PKCS7State {\n    byte* tmpCert;\n    byte* bufferPt;\n    byte* key;\n    byte* nonce;    /* stored nonce */\n    byte* aad;      /* additional data for AEAD algos */\n    byte* tag;      /* tag data for AEAD algos */\n    byte* content;\n    byte* buffer;   /* main internal read buffer */\n\n    /* stack variables to store for when returning */\n    word32 varOne;\n    int    varTwo;\n    int    varThree;\n\n    word32 vers;\n    word32 idx;      /* index read into current input buffer */\n    word32 maxLen;   /* sanity cap on maximum amount of data to allow\n                      * needed for GetSequence and other calls */\n    word32 length;   /* amount of data stored */\n    word32 bufferSz; /* size of internal buffer */\n    word32 expected; /* next amount of data expected, if needed */\n    word32 totalRd;  /* total amount of bytes read */\n    word32 nonceSz;  /* size of nonce stored */\n    word32 aadSz;    /* size of additional AEAD data */\n    word32 tagSz;    /* size of tag for AEAD */\n    word32 contentSz;\n    byte tmpIv[MAX_CONTENT_IV_SIZE]; /* store IV if needed */\n#ifdef WC_PKCS7_STREAM_DEBUG\n    word32 peakUsed; /* most bytes used for struct at any one time */\n    word32 peakRead; /* most bytes used by read buffer */\n#endif\n    byte   multi:1;  /* flag for if content is in multiple parts */\n    byte   flagOne:1;\n    byte   detached:1; /* flag to indicate detached signature is present */\n};\n\n\nenum PKCS7_MaxLen {\n    PKCS7_DEFAULT_PEEK = 0,\n    PKCS7_SEQ_PEEK\n};\n\n/* creates a PKCS7State structure and returns 0 on success */\nstatic int wc_PKCS7_CreateStream(PKCS7* pkcs7)\n{\n    WOLFSSL_MSG(\"creating PKCS7 stream structure\");\n    pkcs7->stream = (PKCS7State*)XMALLOC(sizeof(PKCS7State), pkcs7->heap,\n        DYNAMIC_TYPE_PKCS7);\n    if (pkcs7->stream == NULL) {\n        return MEMORY_E;\n    }\n    XMEMSET(pkcs7->stream, 0, sizeof(PKCS7State));\n#ifdef WC_PKCS7_STREAM_DEBUG\n    printf(\"\\nCreating new PKCS#7 stream %p\\n\", pkcs7->stream);\n#endif\n    return 0;\n}\n\n\nstatic void wc_PKCS7_ResetStream(PKCS7* pkcs7)\n{\n    if (pkcs7 != NULL && pkcs7->stream != NULL) {\n#ifdef WC_PKCS7_STREAM_DEBUG\n        /* collect final data point in case more was read right before reset */\n        if (pkcs7->stream->length > pkcs7->stream->peakRead) {\n            pkcs7->stream->peakRead = pkcs7->stream->length;\n        }\n        if (pkcs7->stream->bufferSz + pkcs7->stream->aadSz +\n                pkcs7->stream->nonceSz + pkcs7->stream->tagSz >\n                pkcs7->stream->peakUsed) {\n            pkcs7->stream->peakUsed = pkcs7->stream->bufferSz +\n                pkcs7->stream->aadSz + pkcs7->stream->nonceSz +\n                pkcs7->stream->tagSz;\n        }\n\n        /* print out debugging statistics */\n        if (pkcs7->stream->peakUsed > 0 || pkcs7->stream->peakRead > 0) {\n            printf(\"PKCS#7 STREAM:\\n\\tPeak heap used by struct = %d\"\n                                 \"\\n\\tPeak read buffer bytes   = %d\"\n                                 \"\\n\\tTotal bytes read         = %d\"\n                                 \"\\n\",\n                   pkcs7->stream->peakUsed, pkcs7->stream->peakRead,\n                   pkcs7->stream->totalRd);\n        }\n        printf(\"PKCS#7 stream reset : Address [%p]\\n\", pkcs7->stream);\n    #endif\n\n        /* free any buffers that may be allocated */\n        XFREE(pkcs7->stream->aad, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(pkcs7->stream->tag, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(pkcs7->stream->nonce, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(pkcs7->stream->buffer, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(pkcs7->stream->key, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        pkcs7->stream->aad    = NULL;\n        pkcs7->stream->tag    = NULL;\n        pkcs7->stream->nonce  = NULL;\n        pkcs7->stream->buffer = NULL;\n        pkcs7->stream->key    = NULL;\n\n        /* reset values, note that content and tmpCert are saved */\n        pkcs7->stream->maxLen   = 0;\n        pkcs7->stream->length   = 0;\n        pkcs7->stream->idx      = 0;\n        pkcs7->stream->expected = 0;\n        pkcs7->stream->totalRd  = 0;\n        pkcs7->stream->bufferSz = 0;\n\n        pkcs7->stream->multi    = 0;\n        pkcs7->stream->flagOne  = 0;\n        pkcs7->stream->detached = 0;\n        pkcs7->stream->varOne   = 0;\n        pkcs7->stream->varTwo   = 0;\n        pkcs7->stream->varThree = 0;\n    }\n}\n\n\nstatic void wc_PKCS7_FreeStream(PKCS7* pkcs7)\n{\n    if (pkcs7 != NULL && pkcs7->stream != NULL) {\n        wc_PKCS7_ResetStream(pkcs7);\n\n        XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        pkcs7->stream->content = NULL;\n        pkcs7->stream->tmpCert = NULL;\n\n        XFREE(pkcs7->stream, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        pkcs7->stream = NULL;\n    }\n}\n\n\n/* used to increase the max size for internal buffer\n * returns 0 on success  */\nstatic int wc_PKCS7_GrowStream(PKCS7* pkcs7, word32 newSz)\n{\n    byte* pt;\n\n    pt = (byte*)XMALLOC(newSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (pt == NULL) {\n        return MEMORY_E;\n    }\n    XMEMCPY(pt, pkcs7->stream->buffer, pkcs7->stream->bufferSz);\n\n#ifdef WC_PKCS7_STREAM_DEBUG\n    printf(\"PKCS7 increasing internal stream buffer %d -> %d\\n\",\n            pkcs7->stream->bufferSz, newSz);\n#endif\n    pkcs7->stream->bufferSz = newSz;\n    XFREE(pkcs7->stream->buffer, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    pkcs7->stream->buffer = pt;\n    return 0;\n}\n\n\n/* pt gets set to the buffer that is holding data in the case that stream struct\n *    is used.\n *\n * Sets idx to be the current offset into \"pt\" buffer\n * returns 0 on success\n */\nstatic int wc_PKCS7_AddDataToStream(PKCS7* pkcs7, byte* in, word32 inSz,\n        word32 expected, byte** pt, word32* idx)\n{\n    word32 rdSz = pkcs7->stream->idx;\n\n    /* If the input size minus current index into input buffer is greater than\n     * the expected size then use the input buffer. If data is already stored\n     * in stream buffer or if there is not enough input data available then use\n     * the stream buffer. */\n    if (inSz - rdSz >= expected && pkcs7->stream->length == 0) {\n        /* storing input buffer is not needed */\n        *pt  = in; /* reset in case previously used internal buffer */\n        *idx = rdSz;\n        return 0;\n    }\n\n    /* is there enough stored in buffer already? */\n    if (pkcs7->stream->length >= expected) {\n        *idx = 0; /* start reading from beginning of stream buffer */\n        *pt  = pkcs7->stream->buffer;\n        return 0;\n    }\n\n    /* check if all data has been read from input */\n    if (rdSz >= inSz) {\n        /* no more input to read, reset input index and request more data */\n        pkcs7->stream->idx = 0;\n        return WC_PKCS7_WANT_READ_E;\n    }\n\n    /* try to store input data into stream buffer */\n    if (inSz - rdSz > 0 && pkcs7->stream->length < expected) {\n        int len = min(inSz - rdSz, expected - pkcs7->stream->length);\n\n        /* sanity check that the input buffer is not internal buffer */\n        if (in == pkcs7->stream->buffer) {\n            return WC_PKCS7_WANT_READ_E;\n        }\n\n        /* check if internal buffer size needs to be increased */\n        if (len + pkcs7->stream->length > pkcs7->stream->bufferSz) {\n            int ret = wc_PKCS7_GrowStream(pkcs7, expected);\n            if (ret < 0) {\n                return ret;\n            }\n        }\n        XMEMCPY(pkcs7->stream->buffer + pkcs7->stream->length, in + rdSz, len);\n        pkcs7->stream->length  += len;\n        pkcs7->stream->idx     += len;\n        pkcs7->stream->totalRd += len;\n    }\n\n#ifdef WC_PKCS7_STREAM_DEBUG\n    /* collects memory usage for debugging */\n    if (pkcs7->stream->length > pkcs7->stream->peakRead) {\n        pkcs7->stream->peakRead = pkcs7->stream->length;\n    }\n    if (pkcs7->stream->bufferSz + pkcs7->stream->aadSz + pkcs7->stream->nonceSz +\n        pkcs7->stream->tagSz > pkcs7->stream->peakUsed) {\n        pkcs7->stream->peakUsed = pkcs7->stream->bufferSz +\n           pkcs7->stream->aadSz + pkcs7->stream->nonceSz + pkcs7->stream->tagSz;\n    }\n#endif\n\n    /* if not enough data was read in then request more */\n    if (pkcs7->stream->length < expected) {\n        pkcs7->stream->idx = 0;\n        return WC_PKCS7_WANT_READ_E;\n    }\n\n    /* adjust pointer to read from stored buffer */\n    *idx = 0;\n    *pt  = pkcs7->stream->buffer;\n    return 0;\n}\n\n\n/* Does two things\n *  1) Tries to get the length from current buffer and set it as max length\n *  2) Retrieves the set max length\n *\n * if no flag value is set then the stored max length is returned.\n * returns length found on success and defSz if no stored data is found\n */\nstatic long wc_PKCS7_GetMaxStream(PKCS7* pkcs7, byte flag, byte* in,\n        word32 defSz)\n{\n    /* check there is a buffer to read from */\n    if (pkcs7) {\n        int     length = 0, ret;\n        word32  idx = 0, maxIdx;\n        byte*   pt;\n\n        if (flag != PKCS7_DEFAULT_PEEK) {\n            if (pkcs7->stream->length > 0) {\n                length = pkcs7->stream->length;\n                pt     = pkcs7->stream->buffer;\n            }\n            else {\n                length = defSz;\n                pt     = in;\n            }\n            maxIdx = (word32)length;\n\n            if (length < MAX_SEQ_SZ) {\n                WOLFSSL_MSG(\"PKCS7 Error not enough data for SEQ peek\\n\");\n                return 0;\n            }\n            if (flag == PKCS7_SEQ_PEEK) {\n                if ((ret = GetSequence_ex(pt, &idx, &length, maxIdx,\n                                NO_USER_CHECK)) < 0) {\n                    return ret;\n                }\n\n            #ifdef ASN_BER_TO_DER\n                if (length == 0 && ret == 0) {\n                    idx = 0;\n                    if ((ret = wc_BerToDer(pt, defSz, NULL,\n                                    (word32*)&length)) != LENGTH_ONLY_E) {\n                        return ret;\n                    }\n                }\n            #endif /* ASN_BER_TO_DER */\n                pkcs7->stream->maxLen = length + idx;\n            }\n        }\n\n        if (pkcs7->stream->maxLen == 0) {\n            pkcs7->stream->maxLen = defSz;\n        }\n\n        return pkcs7->stream->maxLen;\n    }\n\n    return defSz;\n}\n\n\n/* setter function for stored variables */\nstatic void wc_PKCS7_StreamStoreVar(PKCS7* pkcs7, word32 var1, int var2,\n        int var3)\n{\n    if (pkcs7 != NULL && pkcs7->stream != NULL) {\n        pkcs7->stream->varOne   = var1;\n        pkcs7->stream->varTwo   = var2;\n        pkcs7->stream->varThree = var3;\n    }\n}\n\n/* getter function for stored variables */\nstatic void wc_PKCS7_StreamGetVar(PKCS7* pkcs7, word32* var1, int* var2,\n        int* var3)\n{\n    if (pkcs7 != NULL && pkcs7->stream != NULL) {\n        if (var1 != NULL) *var1 = pkcs7->stream->varOne;\n        if (var2 != NULL) *var2 = pkcs7->stream->varTwo;\n        if (var3 != NULL) *var3 = pkcs7->stream->varThree;\n    }\n}\n\n\n/* common update of index and total read after section complete\n * returns 0 on success */\nstatic int wc_PKCS7_StreamEndCase(PKCS7* pkcs7, word32* tmpIdx, word32* idx)\n{\n    int ret = 0;\n\n    if (pkcs7->stream->length > 0) {\n        if (pkcs7->stream->length < *idx) {\n            WOLFSSL_MSG(\"PKCS7 read too much data from internal buffer\");\n            ret = BUFFER_E;\n        }\n        else {\n            XMEMMOVE(pkcs7->stream->buffer, pkcs7->stream->buffer + *idx,\n                 pkcs7->stream->length - *idx);\n            pkcs7->stream->length -= *idx;\n        }\n    }\n    else {\n        pkcs7->stream->totalRd += *idx - *tmpIdx;\n        pkcs7->stream->idx = *idx; /* adjust index into input buffer */\n        *tmpIdx = *idx;\n    }\n\n    return ret;\n}\n#endif /* NO_PKCS7_STREAM */\n\n#ifdef WC_PKCS7_STREAM_DEBUG\n/* used to print out human readable state for debugging */\nstatic const char* wc_PKCS7_GetStateName(int in)\n{\n    switch (in) {\n        case WC_PKCS7_START: return \"WC_PKCS7_START\";\n\n        case WC_PKCS7_STAGE2: return \"WC_PKCS7_STAGE2\";\n        case WC_PKCS7_STAGE3: return \"WC_PKCS7_STAGE3\";\n        case WC_PKCS7_STAGE4: return \"WC_PKCS7_STAGE4\";\n        case WC_PKCS7_STAGE5: return \"WC_PKCS7_STAGE5\";\n        case WC_PKCS7_STAGE6: return \"WC_PKCS7_STAGE6\";\n\n        /* parse info set */\n        case WC_PKCS7_INFOSET_START:  return \"WC_PKCS7_INFOSET_START\";\n        case WC_PKCS7_INFOSET_BER:    return \"WC_PKCS7_INFOSET_BER\";\n        case WC_PKCS7_INFOSET_STAGE1: return \"WC_PKCS7_INFOSET_STAGE1\";\n        case WC_PKCS7_INFOSET_STAGE2: return \"WC_PKCS7_INFOSET_STAGE2\";\n        case WC_PKCS7_INFOSET_END:    return \"WC_PKCS7_INFOSET_END\";\n\n        /* decode enveloped data */\n        case WC_PKCS7_ENV_2: return \"WC_PKCS7_ENV_2\";\n        case WC_PKCS7_ENV_3: return \"WC_PKCS7_ENV_3\";\n        case WC_PKCS7_ENV_4: return \"WC_PKCS7_ENV_4\";\n        case WC_PKCS7_ENV_5: return \"WC_PKCS7_ENV_5\";\n\n        /* decode auth enveloped */\n        case WC_PKCS7_AUTHENV_2: return \"WC_PKCS7_AUTHENV_2\";\n        case WC_PKCS7_AUTHENV_3: return \"WC_PKCS7_AUTHENV_3\";\n        case WC_PKCS7_AUTHENV_4: return \"WC_PKCS7_AUTHENV_4\";\n        case WC_PKCS7_AUTHENV_5: return \"WC_PKCS7_AUTHENV_5\";\n        case WC_PKCS7_AUTHENV_6: return \"WC_PKCS7_AUTHENV_6\";\n        case WC_PKCS7_AUTHENV_ATRB: return \"WC_PKCS7_AUTHENV_ATRB\";\n        case WC_PKCS7_AUTHENV_ATRBEND: return \"WC_PKCS7_AUTHENV_ATRBEND\";\n        case WC_PKCS7_AUTHENV_7: return \"WC_PKCS7_AUTHENV_7\";\n\n        /* decryption state types */\n        case WC_PKCS7_DECRYPT_KTRI:   return \"WC_PKCS7_DECRYPT_KTRI\";\n        case WC_PKCS7_DECRYPT_KTRI_2: return \"WC_PKCS7_DECRYPT_KTRI_2\";\n        case WC_PKCS7_DECRYPT_KTRI_3: return \"WC_PKCS7_DECRYPT_KTRI_3\";\n\n        case WC_PKCS7_DECRYPT_KARI:  return \"WC_PKCS7_DECRYPT_KARI\";\n        case WC_PKCS7_DECRYPT_KEKRI: return \"WC_PKCS7_DECRYPT_KEKRI\";\n        case WC_PKCS7_DECRYPT_PWRI:  return \"WC_PKCS7_DECRYPT_PWRI\";\n        case WC_PKCS7_DECRYPT_ORI:   return \"WC_PKCS7_DECRYPT_ORI\";\n        case WC_PKCS7_DECRYPT_DONE:  return \"WC_PKCS7_DECRYPT_DONE\";\n\n        case WC_PKCS7_VERIFY_STAGE2: return \"WC_PKCS7_VERIFY_STAGE2\";\n        case WC_PKCS7_VERIFY_STAGE3: return \"WC_PKCS7_VERIFY_STAGE3\";\n        case WC_PKCS7_VERIFY_STAGE4: return \"WC_PKCS7_VERIFY_STAGE4\";\n        case WC_PKCS7_VERIFY_STAGE5: return \"WC_PKCS7_VERIFY_STAGE5\";\n        case WC_PKCS7_VERIFY_STAGE6: return \"WC_PKCS7_VERIFY_STAGE6\";\n\n        default:\n            return \"Unknown state\";\n    }\n}\n#endif\n\n/* Used to change the PKCS7 state. Having state change as a function allows\n * for easier debugging */\nstatic void wc_PKCS7_ChangeState(PKCS7* pkcs7, int newState)\n{\n#ifdef WC_PKCS7_STREAM_DEBUG\n    printf(\"\\tChanging from state [%02d] %s to [%02d] %s\\n\",\n            pkcs7->state, wc_PKCS7_GetStateName(pkcs7->state),\n            newState, wc_PKCS7_GetStateName(newState));\n#endif\n    pkcs7->state = newState;\n}\n\n#define MAX_PKCS7_DIGEST_SZ (MAX_SEQ_SZ + MAX_ALGO_SZ + \\\n                             MAX_OCTET_STR_SZ + WC_MAX_DIGEST_SIZE)\n\n\n/* placed ASN.1 contentType OID into *output, return idx on success,\n * 0 upon failure */\nstatic int wc_SetContentType(int pkcs7TypeOID, byte* output, word32 outputSz)\n{\n    /* PKCS#7 content types, RFC 2315, section 14 */\n    const byte pkcs7[]              = { 0x2A, 0x86, 0x48, 0x86, 0xF7,\n                                               0x0D, 0x01, 0x07 };\n    const byte data[]               = { 0x2A, 0x86, 0x48, 0x86, 0xF7,\n                                               0x0D, 0x01, 0x07, 0x01 };\n    const byte signedData[]         = { 0x2A, 0x86, 0x48, 0x86, 0xF7,\n                                               0x0D, 0x01, 0x07, 0x02};\n    const byte envelopedData[]      = { 0x2A, 0x86, 0x48, 0x86, 0xF7,\n                                               0x0D, 0x01, 0x07, 0x03 };\n    const byte authEnvelopedData[]  = { 0x2A, 0x86, 0x48, 0x86, 0xF7,\n                                        0x0D, 0x01, 0x09, 0x10, 0x01, 0x17};\n    const byte signedAndEnveloped[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,\n                                               0x0D, 0x01, 0x07, 0x04 };\n    const byte digestedData[]       = { 0x2A, 0x86, 0x48, 0x86, 0xF7,\n                                               0x0D, 0x01, 0x07, 0x05 };\n#ifndef NO_PKCS7_ENCRYPTED_DATA\n    const byte encryptedData[]      = { 0x2A, 0x86, 0x48, 0x86, 0xF7,\n                                               0x0D, 0x01, 0x07, 0x06 };\n#endif\n    /* FirmwarePkgData (1.2.840.113549.1.9.16.1.16), RFC 4108 */\n    const byte firmwarePkgData[]    = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,\n                                        0x01, 0x09, 0x10, 0x01, 0x10 };\n#if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)\n    /* id-ct-compressedData (1.2.840.113549.1.9.16.1.9), RFC 3274 */\n    const byte compressedData[]     = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,\n                                        0x01, 0x09, 0x10, 0x01, 0x09 };\n#endif\n\n#if !defined(NO_PWDBASED) && !defined(NO_SHA)\n    const byte pwriKek[]            = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,\n                                        0x01, 0x09, 0x10, 0x03, 0x09 };\n    const byte pbkdf2[]             = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,\n                                        0x01, 0x05, 0x0C };\n#endif\n\n    int idSz, idx = 0;\n    word32 typeSz = 0;\n    const byte* typeName = 0;\n    byte ID_Length[MAX_LENGTH_SZ];\n\n    switch (pkcs7TypeOID) {\n        case PKCS7_MSG:\n            typeSz = sizeof(pkcs7);\n            typeName = pkcs7;\n            break;\n\n        case DATA:\n            typeSz = sizeof(data);\n            typeName = data;\n            break;\n\n        case SIGNED_DATA:\n            typeSz = sizeof(signedData);\n            typeName = signedData;\n            break;\n\n        case ENVELOPED_DATA:\n            typeSz = sizeof(envelopedData);\n            typeName = envelopedData;\n            break;\n\n        case AUTH_ENVELOPED_DATA:\n            typeSz = sizeof(authEnvelopedData);\n            typeName = authEnvelopedData;\n            break;\n\n        case SIGNED_AND_ENVELOPED_DATA:\n            typeSz = sizeof(signedAndEnveloped);\n            typeName = signedAndEnveloped;\n            break;\n\n        case DIGESTED_DATA:\n            typeSz = sizeof(digestedData);\n            typeName = digestedData;\n            break;\n\n#ifndef NO_PKCS7_ENCRYPTED_DATA\n        case ENCRYPTED_DATA:\n            typeSz = sizeof(encryptedData);\n            typeName = encryptedData;\n            break;\n#endif\n#if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)\n        case COMPRESSED_DATA:\n            typeSz = sizeof(compressedData);\n            typeName = compressedData;\n            break;\n#endif\n        case FIRMWARE_PKG_DATA:\n            typeSz = sizeof(firmwarePkgData);\n            typeName = firmwarePkgData;\n            break;\n\n#if !defined(NO_PWDBASED) && !defined(NO_SHA)\n        case PWRI_KEK_WRAP:\n            typeSz = sizeof(pwriKek);\n            typeName = pwriKek;\n            break;\n\n        case PBKDF2_OID:\n            typeSz = sizeof(pbkdf2);\n            typeName = pbkdf2;\n            break;\n#endif\n\n        default:\n            WOLFSSL_MSG(\"Unknown PKCS#7 Type\");\n            return 0;\n    };\n\n    if (outputSz < (MAX_LENGTH_SZ + 1 + typeSz)) {\n        WOLFSSL_MSG(\"CMS content type buffer too small\");\n        return BAD_FUNC_ARG;\n    }\n\n    idSz  = SetLength(typeSz, ID_Length);\n    output[idx++] = ASN_OBJECT_ID;\n    XMEMCPY(output + idx, ID_Length, idSz);\n    idx += idSz;\n    XMEMCPY(output + idx, typeName, typeSz);\n    idx += typeSz;\n\n    return idx;\n}\n\n\n/* get ASN.1 contentType OID sum, return 0 on success, <0 on failure */\nstatic int wc_GetContentType(const byte* input, word32* inOutIdx, word32* oid,\n                             word32 maxIdx)\n{\n    WOLFSSL_ENTER(\"wc_GetContentType\");\n    if (GetObjectId(input, inOutIdx, oid, oidIgnoreType, maxIdx) < 0)\n        return ASN_PARSE_E;\n\n    return 0;\n}\n\n\n/* return block size for algorithm represented by oid, or <0 on error */\nstatic int wc_PKCS7_GetOIDBlockSize(int oid)\n{\n    int blockSz;\n\n    switch (oid) {\n#ifndef NO_AES\n    #ifdef WOLFSSL_AES_128\n        case AES128CBCb:\n        case AES128GCMb:\n        case AES128CCMb:\n    #endif\n    #ifdef WOLFSSL_AES_192\n        case AES192CBCb:\n        case AES192GCMb:\n        case AES192CCMb:\n    #endif\n    #ifdef WOLFSSL_AES_256\n        case AES256CBCb:\n        case AES256GCMb:\n        case AES256CCMb:\n    #endif\n            blockSz = AES_BLOCK_SIZE;\n            break;\n#endif\n#ifndef NO_DES3\n        case DESb:\n        case DES3b:\n            blockSz = DES_BLOCK_SIZE;\n            break;\n#endif\n        default:\n            WOLFSSL_MSG(\"Unsupported content cipher type\");\n            return ALGO_ID_E;\n    };\n\n    return blockSz;\n}\n\n\n/* get key size for algorithm represented by oid, or <0 on error */\nstatic int wc_PKCS7_GetOIDKeySize(int oid)\n{\n    int blockKeySz;\n\n    switch (oid) {\n#ifndef NO_AES\n    #ifdef WOLFSSL_AES_128\n        case AES128CBCb:\n        case AES128GCMb:\n        case AES128CCMb:\n        case AES128_WRAP:\n            blockKeySz = 16;\n            break;\n    #endif\n    #ifdef WOLFSSL_AES_192\n        case AES192CBCb:\n        case AES192GCMb:\n        case AES192CCMb:\n        case AES192_WRAP:\n            blockKeySz = 24;\n            break;\n    #endif\n    #ifdef WOLFSSL_AES_256\n        case AES256CBCb:\n        case AES256GCMb:\n        case AES256CCMb:\n        case AES256_WRAP:\n            blockKeySz = 32;\n            break;\n    #endif\n#endif\n#ifndef NO_DES3\n        case DESb:\n            blockKeySz = DES_KEYLEN;\n            break;\n\n        case DES3b:\n            blockKeySz = DES3_KEYLEN;\n            break;\n#endif\n        default:\n            WOLFSSL_MSG(\"Unsupported content cipher type\");\n            return ALGO_ID_E;\n    };\n\n    return blockKeySz;\n}\n\n\nPKCS7* wc_PKCS7_New(void* heap, int devId)\n{\n    PKCS7* pkcs7 = (PKCS7*)XMALLOC(sizeof(PKCS7), heap, DYNAMIC_TYPE_PKCS7);\n    if (pkcs7) {\n        XMEMSET(pkcs7, 0, sizeof(PKCS7));\n        if (wc_PKCS7_Init(pkcs7, heap, devId) == 0) {\n            pkcs7->isDynamic = 1;\n        }\n        else {\n            XFREE(pkcs7, heap, DYNAMIC_TYPE_PKCS7);\n            pkcs7 = NULL;\n        }\n    }\n    return pkcs7;\n}\n\n/* This is to initialize a PKCS7 structure. It sets all values to 0 and can be\n * used to set the heap hint.\n *\n * pkcs7 PKCS7 structure to initialize\n * heap  memory heap hint for PKCS7 structure to use\n * devId currently not used but a place holder for async operations\n *\n * returns 0 on success or a negative value for failure\n */\nint wc_PKCS7_Init(PKCS7* pkcs7, void* heap, int devId)\n{\n    word16 isDynamic;\n\n    WOLFSSL_ENTER(\"wc_PKCS7_Init\");\n\n    if (pkcs7 == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    isDynamic = pkcs7->isDynamic;\n    XMEMSET(pkcs7, 0, sizeof(PKCS7));\n    pkcs7->isDynamic = isDynamic;\n#ifdef WOLFSSL_HEAP_TEST\n    pkcs7->heap = (void*)WOLFSSL_HEAP_TEST;\n#else\n    pkcs7->heap = heap;\n#endif\n    pkcs7->devId = devId;\n\n    return 0;\n}\n\n\n/* Certificate structure holding der pointer, size, and pointer to next\n * Pkcs7Cert struct. Used when creating SignedData types with multiple\n * certificates. */\nstruct Pkcs7Cert {\n    byte*  der;\n    word32 derSz;\n    Pkcs7Cert* next;\n};\n\n\n/* Linked list of ASN.1 encoded RecipientInfos */\nstruct Pkcs7EncodedRecip {\n    byte recip[MAX_RECIP_SZ];\n    word32 recipSz;\n    int recipType;\n    int recipVersion;\n    Pkcs7EncodedRecip* next;\n};\n\n\n/* free all members of Pkcs7Cert linked list */\nstatic void wc_PKCS7_FreeCertSet(PKCS7* pkcs7)\n{\n    Pkcs7Cert* curr = NULL;\n    Pkcs7Cert* next = NULL;\n\n    if (pkcs7 == NULL)\n        return;\n\n    curr = pkcs7->certList;\n    pkcs7->certList = NULL;\n\n    while (curr != NULL) {\n        next = curr->next;\n        curr->next = NULL;\n        XFREE(curr, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        curr = next;\n    }\n\n    return;\n}\n\n\n/* Get total size of all recipients in recipient list.\n *\n * Returns total size of recipients, or negative upon error */\nstatic int wc_PKCS7_GetRecipientListSize(PKCS7* pkcs7)\n{\n    int totalSz = 0;\n    Pkcs7EncodedRecip* tmp = NULL;\n\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    tmp = pkcs7->recipList;\n\n    while (tmp != NULL) {\n        totalSz += tmp->recipSz;\n        tmp = tmp->next;\n    }\n\n    return totalSz;\n}\n\n\n/* free all members of Pkcs7EncodedRecip linked list */\nstatic void wc_PKCS7_FreeEncodedRecipientSet(PKCS7* pkcs7)\n{\n    Pkcs7EncodedRecip* curr = NULL;\n    Pkcs7EncodedRecip* next = NULL;\n\n    if (pkcs7 == NULL)\n        return;\n\n    curr = pkcs7->recipList;\n    pkcs7->recipList = NULL;\n\n    while (curr != NULL) {\n        next = curr->next;\n        curr->next = NULL;\n        XFREE(curr, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        curr = next;\n    }\n\n    return;\n}\n\n\n/* search through RecipientInfo list for specific type.\n * return 1 if ANY recipient of type specified is present, otherwise\n * return 0 */\nstatic int wc_PKCS7_RecipientListIncludesType(PKCS7* pkcs7, int type)\n{\n    Pkcs7EncodedRecip* tmp = NULL;\n\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    tmp = pkcs7->recipList;\n\n    while (tmp != NULL) {\n        if (tmp->recipType == type)\n            return 1;\n\n        tmp = tmp->next;\n    }\n\n    return 0;\n}\n\n\n/* searches through RecipientInfo list, returns 1 if all structure\n * versions are set to 0, otherwise returns 0 */\nstatic int wc_PKCS7_RecipientListVersionsAllZero(PKCS7* pkcs7)\n{\n    Pkcs7EncodedRecip* tmp = NULL;\n\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    tmp = pkcs7->recipList;\n\n    while (tmp != NULL) {\n        if (tmp->recipVersion != 0)\n            return 0;\n\n        tmp = tmp->next;\n    }\n\n    return 1;\n}\n\n\n/* Init PKCS7 struct with recipient cert, decode into DecodedCert\n * NOTE: keeps previously set pkcs7 heap hint, devId and isDynamic */\nint wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* derCert, word32 derCertSz)\n{\n    int ret = 0;\n    void* heap;\n    int devId;\n    Pkcs7Cert* cert;\n    Pkcs7Cert* lastCert;\n\n    if (pkcs7 == NULL || (derCert == NULL && derCertSz != 0)) {\n        return BAD_FUNC_ARG;\n    }\n\n    heap = pkcs7->heap;\n    devId = pkcs7->devId;\n    cert = pkcs7->certList;\n    ret = wc_PKCS7_Init(pkcs7, heap, devId);\n    if (ret != 0)\n        return ret;\n    pkcs7->certList = cert;\n\n    if (derCert != NULL && derCertSz > 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        DecodedCert* dCert;\n\n        dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,\n                                                       DYNAMIC_TYPE_DCERT);\n        if (dCert == NULL)\n            return MEMORY_E;\n#else\n        DecodedCert dCert[1];\n#endif\n\n        pkcs7->singleCert = derCert;\n        pkcs7->singleCertSz = derCertSz;\n        pkcs7->cert[0] = derCert;\n        pkcs7->certSz[0] = derCertSz;\n\n        /* create new Pkcs7Cert for recipient, freed during cleanup */\n        cert = (Pkcs7Cert*)XMALLOC(sizeof(Pkcs7Cert), pkcs7->heap,\n                                   DYNAMIC_TYPE_PKCS7);\n        XMEMSET(cert, 0, sizeof(Pkcs7Cert));\n        cert->der = derCert;\n        cert->derSz = derCertSz;\n        cert->next = NULL;\n\n        /* free existing cert list if existing */\n        wc_PKCS7_FreeCertSet(pkcs7);\n\n        /* add cert to list */\n        if (pkcs7->certList == NULL) {\n            pkcs7->certList = cert;\n        } else {\n           lastCert = pkcs7->certList;\n           while (lastCert->next != NULL) {\n               lastCert = lastCert->next;\n           }\n           lastCert->next = cert;\n        }\n\n        InitDecodedCert(dCert, derCert, derCertSz, pkcs7->heap);\n        ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);\n        if (ret < 0) {\n            FreeDecodedCert(dCert);\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);\n#endif\n            return ret;\n        }\n\n        XMEMCPY(pkcs7->publicKey, dCert->publicKey, dCert->pubKeySize);\n        pkcs7->publicKeySz = dCert->pubKeySize;\n        pkcs7->publicKeyOID = dCert->keyOID;\n        XMEMCPY(pkcs7->issuerHash, dCert->issuerHash, KEYID_SIZE);\n        pkcs7->issuer = dCert->issuerRaw;\n        pkcs7->issuerSz = dCert->issuerRawLen;\n        XMEMCPY(pkcs7->issuerSn, dCert->serial, dCert->serialSz);\n        pkcs7->issuerSnSz = dCert->serialSz;\n        XMEMCPY(pkcs7->issuerSubjKeyId, dCert->extSubjKeyId, KEYID_SIZE);\n\n        /* default to IssuerAndSerialNumber for SignerIdentifier */\n        pkcs7->sidType = CMS_ISSUER_AND_SERIAL_NUMBER;\n\n        /* free existing recipient list if existing */\n        wc_PKCS7_FreeEncodedRecipientSet(pkcs7);\n\n        FreeDecodedCert(dCert);\n\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);\n#endif\n    }\n\n    return ret;\n}\n\n\n/* Adds one DER-formatted certificate to the internal PKCS7/CMS certificate\n * list, to be added as part of the certificates CertificateSet. Currently\n * used in SignedData content type.\n *\n * Must be called after wc_PKCS7_Init() or wc_PKCS7_InitWithCert().\n *\n * Does not represent the recipient/signer certificate, only certificates that\n * are part of the certificate chain used to build and verify signer\n * certificates.\n *\n * This API does not currently validate certificates.\n *\n * Returns 0 on success, negative upon error */\nint wc_PKCS7_AddCertificate(PKCS7* pkcs7, byte* derCert, word32 derCertSz)\n{\n    Pkcs7Cert* cert;\n\n    if (pkcs7 == NULL || derCert == NULL || derCertSz == 0)\n        return BAD_FUNC_ARG;\n\n    cert = (Pkcs7Cert*)XMALLOC(sizeof(Pkcs7Cert), pkcs7->heap,\n                               DYNAMIC_TYPE_PKCS7);\n    if (cert == NULL)\n        return MEMORY_E;\n\n    cert->der = derCert;\n    cert->derSz = derCertSz;\n\n    if (pkcs7->certList == NULL) {\n        pkcs7->certList = cert;\n    } else {\n        cert->next = pkcs7->certList;\n        pkcs7->certList = cert;\n    }\n\n    return 0;\n}\n\n\n/* free linked list of PKCS7DecodedAttrib structs */\nstatic void wc_PKCS7_FreeDecodedAttrib(PKCS7DecodedAttrib* attrib, void* heap)\n{\n    PKCS7DecodedAttrib* current;\n\n    if (attrib == NULL) {\n        return;\n    }\n\n    current = attrib;\n    while (current != NULL) {\n        PKCS7DecodedAttrib* next = current->next;\n        if (current->oid != NULL)  {\n            XFREE(current->oid, heap, DYNAMIC_TYPE_PKCS7);\n        }\n        if (current->value != NULL) {\n            XFREE(current->value, heap, DYNAMIC_TYPE_PKCS7);\n        }\n        XFREE(current, heap, DYNAMIC_TYPE_PKCS7);\n        current = next;\n    }\n\n    (void)heap;\n}\n\n\n/* return 0 on success */\nstatic int wc_PKCS7_SignerInfoNew(PKCS7* pkcs7)\n{\n    if (pkcs7->signerInfo != NULL) {\n        XFREE(pkcs7->signerInfo, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        pkcs7->signerInfo = NULL;\n    }\n\n    pkcs7->signerInfo = (PKCS7SignerInfo*)XMALLOC(sizeof(PKCS7SignerInfo),\n            pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (pkcs7->signerInfo == NULL) {\n        WOLFSSL_MSG(\"Unable to malloc memory for signer info\");\n        return MEMORY_E;\n    }\n    XMEMSET(pkcs7->signerInfo, 0, sizeof(PKCS7SignerInfo));\n    return 0;\n}\n\n\nstatic void wc_PKCS7_SignerInfoFree(PKCS7* pkcs7)\n{\n    if (pkcs7->signerInfo != NULL) {\n        if (pkcs7->signerInfo->sid != NULL) {\n            XFREE(pkcs7->signerInfo->sid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            pkcs7->signerInfo->sid = NULL;\n        }\n        XFREE(pkcs7->signerInfo, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        pkcs7->signerInfo = NULL;\n    }\n}\n\n\n/* free's any current SID and sets it to \"in\"\n * returns 0 on success\n */\nstatic int wc_PKCS7_SignerInfoSetSID(PKCS7* pkcs7, byte* in, int inSz)\n{\n    if (pkcs7 == NULL || in == NULL || inSz < 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (pkcs7->signerInfo->sid != NULL) {\n        XFREE(pkcs7->signerInfo->sid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        pkcs7->signerInfo->sid = NULL;\n    }\n    pkcs7->signerInfo->sid = (byte*)XMALLOC(inSz, pkcs7->heap,\n            DYNAMIC_TYPE_PKCS7);\n    if (pkcs7->signerInfo->sid == NULL) {\n        return MEMORY_E;\n    }\n    XMEMCPY(pkcs7->signerInfo->sid, in, inSz);\n    pkcs7->signerInfo->sidSz = inSz;\n    return 0;\n}\n\n\n/* releases any memory allocated by a PKCS7 initializer */\nvoid wc_PKCS7_Free(PKCS7* pkcs7)\n{\n    if (pkcs7 == NULL)\n        return;\n\n#ifndef NO_PKCS7_STREAM\n    wc_PKCS7_FreeStream(pkcs7);\n#endif\n\n    wc_PKCS7_SignerInfoFree(pkcs7);\n    wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap);\n    wc_PKCS7_FreeCertSet(pkcs7);\n\n#ifdef ASN_BER_TO_DER\n    if (pkcs7->der != NULL)\n        XFREE(pkcs7->der, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n#endif\n    if (pkcs7->contentDynamic != NULL)\n        XFREE(pkcs7->contentDynamic, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n\n    if (pkcs7->cek != NULL) {\n        ForceZero(pkcs7->cek, pkcs7->cekSz);\n        XFREE(pkcs7->cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    }\n\n    pkcs7->contentTypeSz = 0;\n\n    if (pkcs7->signature) {\n        XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGNATURE);\n        pkcs7->signature = NULL;\n        pkcs7->signatureSz = 0;\n    }\n    if (pkcs7->plainDigest) {\n        XFREE(pkcs7->plainDigest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);\n        pkcs7->plainDigest = NULL;\n        pkcs7->plainDigestSz = 0;\n    }\n    if (pkcs7->pkcs7Digest) {\n        XFREE(pkcs7->pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);\n        pkcs7->pkcs7Digest = NULL;\n        pkcs7->pkcs7DigestSz = 0;\n    }\n\n    if (pkcs7->isDynamic) {\n        pkcs7->isDynamic = 0;\n        XFREE(pkcs7, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    }\n}\n\n\n/* helper function for parsing through attributes and finding a specific one.\n * returns PKCS7DecodedAttrib pointer on success */\nstatic PKCS7DecodedAttrib* findAttrib(PKCS7* pkcs7, const byte* oid, word32 oidSz)\n{\n    PKCS7DecodedAttrib* list;\n\n    if (pkcs7 == NULL || oid == NULL) {\n        return NULL;\n    }\n\n    /* search attributes for pkiStatus */\n    list = pkcs7->decodedAttrib;\n    while (list != NULL) {\n        word32 sz  = oidSz;\n        word32 idx = 0;\n        int    length = 0;\n        byte   tag;\n\n        if (GetASNTag(list->oid, &idx, &tag, list->oidSz) < 0) {\n            return NULL;\n        }\n        if (tag != ASN_OBJECT_ID) {\n            WOLFSSL_MSG(\"Bad attribute ASN1 syntax\");\n            return NULL;\n        }\n\n        if (GetLength(list->oid, &idx, &length, list->oidSz) < 0) {\n            WOLFSSL_MSG(\"Bad attribute length\");\n            return NULL;\n        }\n\n        sz = (sz < (word32)length)? sz : (word32)length;\n        if (XMEMCMP(oid, list->oid + idx, sz) == 0) {\n            return list;\n        }\n        list = list->next;\n    }\n    return NULL;\n}\n\n\n/* Searches through decoded attributes and returns the value for the first one\n * matching the oid passed in. Note that this value includes the leading ASN1\n * syntax. So for a printable string of \"3\" this would be something like\n *\n * 0x13, 0x01, 0x33\n *  ID   SIZE  \"3\"\n *\n * pkcs7  structure to get value from\n * oid    OID value to search for with attributes\n * oidSz  size of oid buffer\n * out    buffer to hold result\n * outSz  size of out buffer (if out is NULL this is set to needed size and\n          LENGTH_ONLY_E is returned)\n *\n * returns size of value on success\n */\nint wc_PKCS7_GetAttributeValue(PKCS7* pkcs7, const byte* oid, word32 oidSz,\n        byte* out, word32* outSz)\n{\n    PKCS7DecodedAttrib* attrib;\n\n    if (pkcs7 == NULL || oid == NULL || outSz == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    attrib = findAttrib(pkcs7, oid, oidSz);\n    if (attrib == NULL) {\n        return ASN_PARSE_E;\n    }\n\n    if (out == NULL) {\n        *outSz = attrib->valueSz;\n        return LENGTH_ONLY_E;\n    }\n\n    if (*outSz < attrib->valueSz) {\n        return BUFFER_E;\n    }\n\n    XMEMCPY(out, attrib->value, attrib->valueSz);\n    return attrib->valueSz;\n}\n\n\n/* build PKCS#7 data content type */\nint wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz)\n{\n    static const byte oid[] =\n        { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,\n                         0x07, 0x01 };\n    byte seq[MAX_SEQ_SZ];\n    byte octetStr[MAX_OCTET_STR_SZ];\n    word32 seqSz;\n    word32 octetStrSz;\n    word32 oidSz = (word32)sizeof(oid);\n    int idx = 0;\n\n    if (pkcs7 == NULL || output == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    octetStrSz = SetOctetString(pkcs7->contentSz, octetStr);\n    seqSz = SetSequence(pkcs7->contentSz + octetStrSz + oidSz, seq);\n\n    if (outputSz < pkcs7->contentSz + octetStrSz + oidSz + seqSz)\n        return BUFFER_E;\n\n    XMEMCPY(output, seq, seqSz);\n    idx += seqSz;\n    XMEMCPY(output + idx, oid, oidSz);\n    idx += oidSz;\n    XMEMCPY(output + idx, octetStr, octetStrSz);\n    idx += octetStrSz;\n    XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);\n    idx += pkcs7->contentSz;\n\n    return idx;\n}\n\n\ntypedef struct EncodedAttrib {\n    byte valueSeq[MAX_SEQ_SZ];\n        const byte* oid;\n        byte valueSet[MAX_SET_SZ];\n        const byte* value;\n    word32 valueSeqSz, oidSz, idSz, valueSetSz, valueSz, totalSz;\n} EncodedAttrib;\n\n\ntypedef struct ESD {\n    wc_HashAlg  hash;\n    enum wc_HashType hashType;\n    byte contentDigest[WC_MAX_DIGEST_SIZE + 2]; /* content only + ASN.1 heading */\n    byte contentAttribsDigest[WC_MAX_DIGEST_SIZE];\n    byte encContentDigest[MAX_ENCRYPTED_KEY_SZ];\n\n    byte outerSeq[MAX_SEQ_SZ];\n        byte outerContent[MAX_EXP_SZ];\n            byte innerSeq[MAX_SEQ_SZ];\n                byte version[MAX_VERSION_SZ];\n                byte digAlgoIdSet[MAX_SET_SZ];\n                    byte singleDigAlgoId[MAX_ALGO_SZ];\n\n                byte contentInfoSeq[MAX_SEQ_SZ];\n                    byte innerContSeq[MAX_EXP_SZ];\n                        byte innerOctets[MAX_OCTET_STR_SZ];\n\n                byte certsSet[MAX_SET_SZ];\n\n                byte signerInfoSet[MAX_SET_SZ];\n                    byte signerInfoSeq[MAX_SEQ_SZ];\n                        byte signerVersion[MAX_VERSION_SZ];\n                        /* issuerAndSerialNumber ...*/\n                        byte issuerSnSeq[MAX_SEQ_SZ];\n                            byte issuerName[MAX_SEQ_SZ];\n                            byte issuerSn[MAX_SN_SZ];\n                        /* OR subjectKeyIdentifier */\n                        byte issuerSKIDSeq[MAX_SEQ_SZ];\n                            byte issuerSKID[MAX_OCTET_STR_SZ];\n                        byte signerDigAlgoId[MAX_ALGO_SZ];\n                        byte digEncAlgoId[MAX_ALGO_SZ];\n                        byte signedAttribSet[MAX_SET_SZ];\n                            EncodedAttrib signedAttribs[7];\n                        byte signerDigest[MAX_OCTET_STR_SZ];\n    word32 innerOctetsSz, innerContSeqSz, contentInfoSeqSz;\n    word32 outerSeqSz, outerContentSz, innerSeqSz, versionSz, digAlgoIdSetSz,\n           singleDigAlgoIdSz, certsSetSz;\n    word32 signerInfoSetSz, signerInfoSeqSz, signerVersionSz,\n           issuerSnSeqSz, issuerNameSz, issuerSnSz, issuerSKIDSz,\n           issuerSKIDSeqSz, signerDigAlgoIdSz, digEncAlgoIdSz, signerDigestSz;\n    word32 encContentDigestSz, signedAttribsSz, signedAttribsCount,\n           signedAttribSetSz;\n} ESD;\n\n\nstatic int EncodeAttributes(EncodedAttrib* ea, int eaSz,\n                                            PKCS7Attrib* attribs, int attribsSz)\n{\n    int i;\n    int maxSz = min(eaSz, attribsSz);\n    int allAttribsSz = 0;\n\n    for (i = 0; i < maxSz; i++)\n    {\n        int attribSz = 0;\n\n        ea[i].value = attribs[i].value;\n        ea[i].valueSz = attribs[i].valueSz;\n        attribSz += ea[i].valueSz;\n        ea[i].valueSetSz = SetSet(attribSz, ea[i].valueSet);\n        attribSz += ea[i].valueSetSz;\n        ea[i].oid = attribs[i].oid;\n        ea[i].oidSz = attribs[i].oidSz;\n        attribSz += ea[i].oidSz;\n        ea[i].valueSeqSz = SetSequence(attribSz, ea[i].valueSeq);\n        attribSz += ea[i].valueSeqSz;\n        ea[i].totalSz = attribSz;\n\n        allAttribsSz += attribSz;\n    }\n    return allAttribsSz;\n}\n\n\ntypedef struct FlatAttrib {\n    byte* data;\n    word32 dataSz;\n} FlatAttrib;\n\n/* Returns a pointer to FlatAttrib whose members are initialized to 0.\n*  Caller is expected to free.\n*/\nstatic FlatAttrib* NewAttrib(void* heap)\n{\n    FlatAttrib* fb = (FlatAttrib*) XMALLOC(sizeof(FlatAttrib), heap,\n                                                   DYNAMIC_TYPE_TMP_BUFFER);\n    if (fb != NULL) {\n        ForceZero(fb, sizeof(FlatAttrib));\n    }\n    (void)heap;\n    return fb;\n}\n\n/* Free FlatAttrib array and memory allocated to internal struct members */\nstatic void FreeAttribArray(PKCS7* pkcs7, FlatAttrib** arr, int rows)\n{\n    int i;\n\n    if (arr) {\n        for (i = 0; i < rows; i++) {\n            if (arr[i]) {\n                if (arr[i]->data) {\n                    ForceZero(arr[i]->data, arr[i]->dataSz);\n                    XFREE(arr[i]->data, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n                }\n                ForceZero(arr[i], sizeof(FlatAttrib));\n                XFREE(arr[i], pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            }\n        }\n        ForceZero(arr, rows);\n        XFREE(arr, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n    (void)pkcs7;\n}\n\n\n/* Sort FlatAttrib array in ascending order */\nstatic int SortAttribArray(FlatAttrib** arr, int rows)\n{\n    int i, j;\n    word32 minSz, minIdx;\n    FlatAttrib* a   = NULL;\n    FlatAttrib* b   = NULL;\n    FlatAttrib* tmp = NULL;\n\n    if (arr == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    for (i = 0; i < rows; i++) {\n        a = arr[i];\n        minSz = a->dataSz;\n        minIdx = i;\n        for (j = i+1; j < rows; j++) {\n            b = arr[j];\n            if (b->dataSz < minSz) {\n                minSz = b->dataSz;\n                minIdx = j;\n            }\n        }\n        if (minSz < a->dataSz) {\n            /* swap array positions */\n            tmp = arr[i];\n            arr[i] = arr[minIdx];\n            arr[minIdx] = tmp;\n        }\n    }\n\n    return 0;\n}\n\n\n/* Build up array of FlatAttrib structs from EncodedAttrib ones. FlatAttrib\n * holds flattened DER encoding of each attribute */\nstatic int FlattenEncodedAttribs(PKCS7* pkcs7, FlatAttrib** derArr, int rows,\n                                 EncodedAttrib* ea, int eaSz)\n{\n    int i, idx, sz;\n    byte* output   = NULL;\n    FlatAttrib* fa = NULL;\n\n    if (pkcs7 == NULL || derArr == NULL || ea == NULL) {\n        WOLFSSL_MSG(\"Invalid arguments to FlattenEncodedAttribs\");\n        return BAD_FUNC_ARG;\n    }\n\n    if (rows != eaSz) {\n        WOLFSSL_MSG(\"DER array not large enough to hold attribute count\");\n        return BAD_FUNC_ARG;\n    }\n\n    for (i = 0; i < eaSz; i++) {\n        sz = ea[i].valueSeqSz + ea[i].oidSz + ea[i].valueSetSz + ea[i].valueSz;\n\n        output = (byte*)XMALLOC(sz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (output == NULL) {\n            return MEMORY_E;\n        }\n\n        idx = 0;\n        XMEMCPY(output + idx, ea[i].valueSeq, ea[i].valueSeqSz);\n        idx += ea[i].valueSeqSz;\n        XMEMCPY(output + idx, ea[i].oid, ea[i].oidSz);\n        idx += ea[i].oidSz;\n        XMEMCPY(output + idx, ea[i].valueSet, ea[i].valueSetSz);\n        idx += ea[i].valueSetSz;\n        XMEMCPY(output + idx, ea[i].value, ea[i].valueSz);\n\n        fa = derArr[i];\n        fa->data = output;\n        fa->dataSz = sz;\n    }\n\n    return 0;\n}\n\n\n/* Sort and Flatten EncodedAttrib attributes into output buffer */\nstatic int FlattenAttributes(PKCS7* pkcs7, byte* output, EncodedAttrib* ea,\n                             int eaSz)\n{\n    int i, idx, ret;\n    FlatAttrib** derArr = NULL;\n    FlatAttrib*  fa     = NULL;\n\n    if (pkcs7 == NULL || output == NULL || ea == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* create array of FlatAttrib struct pointers to hold DER attribs */\n    derArr = (FlatAttrib**) XMALLOC(eaSz * sizeof(FlatAttrib*), pkcs7->heap,\n                                    DYNAMIC_TYPE_TMP_BUFFER);\n    if (derArr == NULL) {\n        return MEMORY_E;\n    }\n    XMEMSET(derArr, 0, eaSz * sizeof(FlatAttrib*));\n\n    for (i = 0; i < eaSz; i++) {\n        derArr[i] = NewAttrib(pkcs7->heap);\n        if (derArr[i] == NULL) {\n            FreeAttribArray(pkcs7, derArr, eaSz);\n            return MEMORY_E;\n        }\n        ForceZero(derArr[i], sizeof(FlatAttrib));\n    }\n\n    /* flatten EncodedAttrib into DER byte arrays */\n    ret = FlattenEncodedAttribs(pkcs7, derArr, eaSz, ea, eaSz);\n    if (ret != 0) {\n        FreeAttribArray(pkcs7, derArr, eaSz);\n        return ret;\n    }\n\n    /* SET OF DER signed attributes must be sorted in ascending order */\n    ret = SortAttribArray(derArr, eaSz);\n    if (ret != 0) {\n        FreeAttribArray(pkcs7, derArr, eaSz);\n        return ret;\n    }\n\n    /* copy sorted DER attribute arrays into output buffer */\n    idx = 0;\n    for (i = 0; i < eaSz; i++) {\n        fa = derArr[i];\n        XMEMCPY(output + idx, fa->data, fa->dataSz);\n        idx += fa->dataSz;\n    }\n\n    FreeAttribArray(pkcs7, derArr, eaSz);\n\n    return 0;\n}\n\n\n#ifndef NO_RSA\n\n/* returns size of signature put into out, negative on error */\nstatic int wc_PKCS7_RsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)\n{\n    int ret;\n    word32 idx;\n#ifdef WOLFSSL_SMALL_STACK\n    RsaKey* privKey;\n#else\n    RsaKey  privKey[1];\n#endif\n\n    if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,\n        DYNAMIC_TYPE_TMP_BUFFER);\n    if (privKey == NULL)\n        return MEMORY_E;\n#endif\n\n    ret = wc_InitRsaKey_ex(privKey, pkcs7->heap, pkcs7->devId);\n    if (ret == 0) {\n        if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {\n            idx = 0;\n            ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,\n                                         pkcs7->privateKeySz);\n        }\n        else if (pkcs7->devId == INVALID_DEVID) {\n            ret = BAD_FUNC_ARG;\n        }\n    }\n    if (ret == 0) {\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        do {\n            ret = wc_AsyncWait(ret, &privKey->asyncDev,\n                WC_ASYNC_FLAG_CALL_AGAIN);\n    #endif\n            if (ret >= 0) {\n                ret = wc_RsaSSL_Sign(in, inSz, esd->encContentDigest,\n                                     sizeof(esd->encContentDigest),\n                                     privKey, pkcs7->rng);\n            }\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        } while (ret == WC_PENDING_E);\n    #endif\n    }\n\n    wc_FreeRsaKey(privKey);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n#endif /* NO_RSA */\n\n\n#ifdef HAVE_ECC\n\n/* returns size of signature put into out, negative on error */\nstatic int wc_PKCS7_EcdsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)\n{\n    int ret;\n    word32 outSz, idx;\n#ifdef WOLFSSL_SMALL_STACK\n    ecc_key* privKey;\n#else\n    ecc_key  privKey[1];\n#endif\n\n    if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    privKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,\n        DYNAMIC_TYPE_TMP_BUFFER);\n    if (privKey == NULL)\n        return MEMORY_E;\n#endif\n\n    ret = wc_ecc_init_ex(privKey, pkcs7->heap, pkcs7->devId);\n    if (ret == 0) {\n        if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {\n            idx = 0;\n            ret = wc_EccPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,\n                                         pkcs7->privateKeySz);\n        }\n        else if (pkcs7->devId == INVALID_DEVID) {\n            ret = BAD_FUNC_ARG;\n        }\n    }\n    if (ret == 0) {\n        outSz = sizeof(esd->encContentDigest);\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        do {\n            ret = wc_AsyncWait(ret, &privKey->asyncDev,\n                WC_ASYNC_FLAG_CALL_AGAIN);\n    #endif\n            if (ret >= 0) {\n                ret = wc_ecc_sign_hash(in, inSz, esd->encContentDigest,\n                                       &outSz, pkcs7->rng, privKey);\n            }\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        } while (ret == WC_PENDING_E);\n    #endif\n        if (ret == 0)\n            ret = (int)outSz;\n    }\n\n    wc_ecc_free(privKey);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n#endif /* HAVE_ECC */\n\n\n/* builds up SignedData signed attributes, including default ones.\n *\n * pkcs7 - pointer to initialized PKCS7 structure\n * esd   - pointer to initialized ESD structure, used for output\n *\n * return 0 on success, negative on error */\nstatic int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd,\n                    const byte* contentType, word32 contentTypeSz,\n                    const byte* contentTypeOid, word32 contentTypeOidSz,\n                    const byte* messageDigestOid, word32 messageDigestOidSz,\n                    const byte* signingTimeOid, word32 signingTimeOidSz,\n                    byte* signingTime, word32 signingTimeSz)\n{\n    int hashSz;\n#ifdef NO_ASN_TIME\n    PKCS7Attrib cannedAttribs[2];\n#else\n    time_t tm;\n    int timeSz;\n    PKCS7Attrib cannedAttribs[3];\n#endif\n    word32 idx = 0;\n    word32 cannedAttribsCount;\n\n    if (pkcs7 == NULL || esd == NULL || contentType == NULL ||\n        contentTypeOid == NULL || messageDigestOid == NULL ||\n        signingTimeOid == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (pkcs7->skipDefaultSignedAttribs == 0) {\n        hashSz = wc_HashGetDigestSize(esd->hashType);\n        if (hashSz < 0)\n            return hashSz;\n\n    #ifndef NO_ASN_TIME\n        if (signingTime == NULL || signingTimeSz == 0)\n            return BAD_FUNC_ARG;\n\n        tm = XTIME(0);\n        timeSz = GetAsnTimeString(&tm, signingTime, signingTimeSz);\n        if (timeSz < 0)\n            return timeSz;\n    #endif\n\n        cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib);\n\n        cannedAttribs[idx].oid     = contentTypeOid;\n        cannedAttribs[idx].oidSz   = contentTypeOidSz;\n        cannedAttribs[idx].value   = contentType;\n        cannedAttribs[idx].valueSz = contentTypeSz;\n        idx++;\n    #ifndef NO_ASN_TIME\n        cannedAttribs[idx].oid     = signingTimeOid;\n        cannedAttribs[idx].oidSz   = signingTimeOidSz;\n        cannedAttribs[idx].value   = signingTime;\n        cannedAttribs[idx].valueSz = timeSz;\n        idx++;\n    #endif\n        cannedAttribs[idx].oid     = messageDigestOid;\n        cannedAttribs[idx].oidSz   = messageDigestOidSz;\n        cannedAttribs[idx].value   = esd->contentDigest;\n        cannedAttribs[idx].valueSz = hashSz + 2;  /* ASN.1 heading */\n\n        esd->signedAttribsCount += cannedAttribsCount;\n        esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 3,\n                                             cannedAttribs, cannedAttribsCount);\n    } else {\n        esd->signedAttribsCount = 0;\n        esd->signedAttribsSz = 0;\n    }\n\n    /* add custom signed attributes if set */\n    if (pkcs7->signedAttribsSz > 0 && pkcs7->signedAttribs != NULL) {\n        esd->signedAttribsCount += pkcs7->signedAttribsSz;\n    #ifdef NO_ASN_TIME\n        esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4,\n                                  pkcs7->signedAttribs, pkcs7->signedAttribsSz);\n    #else\n        esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[3], 4,\n                                  pkcs7->signedAttribs, pkcs7->signedAttribsSz);\n    #endif\n    }\n\n#ifdef NO_ASN_TIME\n    (void)signingTimeOidSz;\n    (void)signingTime;\n    (void)signingTimeSz;\n#endif\n\n    return 0;\n}\n\n\n/* gets correct encryption algo ID for SignedData, either CTC_<hash>wRSA or\n * CTC_<hash>wECDSA, from pkcs7->publicKeyOID and pkcs7->hashOID.\n *\n * pkcs7          - pointer to PKCS7 structure\n * digEncAlgoId   - [OUT] output int to store correct algo ID in\n * digEncAlgoType - [OUT] output for algo ID type\n *\n * return 0 on success, negative on error */\nstatic int wc_PKCS7_SignedDataGetEncAlgoId(PKCS7* pkcs7, int* digEncAlgoId,\n                                           int* digEncAlgoType)\n{\n    int algoId   = 0;\n    int algoType = 0;\n\n    if (pkcs7 == NULL || digEncAlgoId == NULL || digEncAlgoType == NULL)\n        return BAD_FUNC_ARG;\n\n    if (pkcs7->publicKeyOID == RSAk) {\n\n        algoType = oidSigType;\n\n        switch (pkcs7->hashOID) {\n        #ifndef NO_SHA\n            case SHAh:\n                algoId = CTC_SHAwRSA;\n                break;\n        #endif\n        #ifdef WOLFSSL_SHA224\n            case SHA224h:\n                algoId = CTC_SHA224wRSA;\n                break;\n        #endif\n        #ifndef NO_SHA256\n            case SHA256h:\n                algoId = CTC_SHA256wRSA;\n                break;\n        #endif\n        #ifdef WOLFSSL_SHA384\n            case SHA384h:\n                algoId = CTC_SHA384wRSA;\n                break;\n        #endif\n        #ifdef WOLFSSL_SHA512\n            case SHA512h:\n                algoId = CTC_SHA512wRSA;\n                break;\n        #endif\n        }\n\n    }\n#ifdef HAVE_ECC\n    else if (pkcs7->publicKeyOID == ECDSAk) {\n\n        algoType = oidSigType;\n\n        switch (pkcs7->hashOID) {\n        #ifndef NO_SHA\n            case SHAh:\n                algoId = CTC_SHAwECDSA;\n                break;\n        #endif\n        #ifdef WOLFSSL_SHA224\n            case SHA224h:\n                algoId = CTC_SHA224wECDSA;\n                break;\n        #endif\n        #ifndef NO_SHA256\n            case SHA256h:\n                algoId = CTC_SHA256wECDSA;\n                break;\n        #endif\n        #ifdef WOLFSSL_SHA384\n            case SHA384h:\n                algoId = CTC_SHA384wECDSA;\n                break;\n        #endif\n        #ifdef WOLFSSL_SHA512\n            case SHA512h:\n                algoId = CTC_SHA512wECDSA;\n                break;\n        #endif\n        }\n    }\n#endif /* HAVE_ECC */\n\n    if (algoId == 0) {\n        WOLFSSL_MSG(\"Invalid signature algorithm type\");\n        return BAD_FUNC_ARG;\n    }\n\n    *digEncAlgoId = algoId;\n    *digEncAlgoType = algoType;\n\n    return 0;\n}\n\n\n/* build SignedData DigestInfo for use with PKCS#7/RSA\n *\n * pkcs7 - pointer to initialized PKCS7 struct\n * flatSignedAttribs - flattened, signed attributes\n * flatSignedAttrbsSz - size of flatSignedAttribs, octets\n * esd - pointer to initialized ESD struct\n * digestInfo - [OUT] output array for DigestInfo\n * digestInfoSz - [IN/OUT] - input size of array, size of digestInfo\n *\n * return 0 on success, negative on error */\nstatic int wc_PKCS7_BuildDigestInfo(PKCS7* pkcs7, byte* flatSignedAttribs,\n                                    word32 flatSignedAttribsSz, ESD* esd,\n                                    byte* digestInfo, word32* digestInfoSz)\n{\n    int ret, hashSz, digIdx = 0;\n    byte digestInfoSeq[MAX_SEQ_SZ];\n    byte digestStr[MAX_OCTET_STR_SZ];\n    byte attribSet[MAX_SET_SZ];\n    byte algoId[MAX_ALGO_SZ];\n    word32 digestInfoSeqSz, digestStrSz, algoIdSz;\n    word32 attribSetSz;\n\n    if (pkcs7 == NULL || esd == NULL || digestInfo == NULL ||\n        digestInfoSz == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    hashSz = wc_HashGetDigestSize(esd->hashType);\n    if (hashSz < 0)\n        return hashSz;\n\n    if (flatSignedAttribsSz != 0) {\n\n        if (flatSignedAttribs == NULL)\n            return BAD_FUNC_ARG;\n\n        attribSetSz = SetSet(flatSignedAttribsSz, attribSet);\n\n        ret = wc_HashInit(&esd->hash, esd->hashType);\n        if (ret < 0)\n            return ret;\n\n        ret = wc_HashUpdate(&esd->hash, esd->hashType,\n                            attribSet, attribSetSz);\n        if (ret == 0)\n            ret = wc_HashUpdate(&esd->hash, esd->hashType,\n                                flatSignedAttribs, flatSignedAttribsSz);\n        if (ret == 0)\n            ret = wc_HashFinal(&esd->hash, esd->hashType,\n                               esd->contentAttribsDigest);\n        wc_HashFree(&esd->hash, esd->hashType);\n\n        if (ret < 0)\n            return ret;\n\n    } else {\n        /* when no attrs, digest is contentDigest without tag and length */\n        XMEMCPY(esd->contentAttribsDigest, esd->contentDigest + 2, hashSz);\n    }\n\n    /* set algoID, with NULL attributes */\n    algoIdSz = SetAlgoID(pkcs7->hashOID, algoId, oidHashType, 0);\n\n    digestStrSz = SetOctetString(hashSz, digestStr);\n    digestInfoSeqSz = SetSequence(algoIdSz + digestStrSz + hashSz,\n                                  digestInfoSeq);\n\n    if (*digestInfoSz < (digestInfoSeqSz + algoIdSz + digestStrSz + hashSz)) {\n        return BUFFER_E;\n    }\n\n    XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);\n    digIdx += digestInfoSeqSz;\n    XMEMCPY(digestInfo + digIdx, algoId, algoIdSz);\n    digIdx += algoIdSz;\n    XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);\n    digIdx += digestStrSz;\n    XMEMCPY(digestInfo + digIdx, esd->contentAttribsDigest, hashSz);\n    digIdx += hashSz;\n\n    *digestInfoSz = digIdx;\n\n    return 0;\n}\n\n\n/* build SignedData signature over DigestInfo or content digest\n *\n * pkcs7 - pointer to initialized PKCS7 struct\n * flatSignedAttribs - flattened, signed attributes\n * flatSignedAttribsSz - size of flatSignedAttribs, octets\n * esd - pointer to initialized ESD struct\n *\n * returns length of signature on success, negative on error */\nstatic int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,\n                                             byte* flatSignedAttribs,\n                                             word32 flatSignedAttribsSz,\n                                             ESD* esd)\n{\n    int ret = 0;\n#if defined(HAVE_ECC) || \\\n    (defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA))\n    int hashSz = 0;\n#endif\n#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)\n    int hashOID;\n#endif\n    word32 digestInfoSz = MAX_PKCS7_DIGEST_SZ;\n#ifdef WOLFSSL_SMALL_STACK\n    byte* digestInfo;\n#else\n    byte  digestInfo[MAX_PKCS7_DIGEST_SZ];\n#endif\n\n    if (pkcs7 == NULL || esd == NULL)\n        return BAD_FUNC_ARG;\n\n#ifdef WOLFSSL_SMALL_STACK\n    digestInfo = (byte*)XMALLOC(digestInfoSz, pkcs7->heap,\n        DYNAMIC_TYPE_TMP_BUFFER);\n    if (digestInfo == NULL) {\n        return MEMORY_E;\n    }\n#endif\n    XMEMSET(digestInfo, 0, digestInfoSz);\n\n    ret = wc_PKCS7_BuildDigestInfo(pkcs7, flatSignedAttribs,\n                                   flatSignedAttribsSz, esd, digestInfo,\n                                   &digestInfoSz);\n    if (ret < 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return ret;\n    }\n\n#if defined(HAVE_ECC) || \\\n    (defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA))\n    /* get digest size from hash type */\n    hashSz = wc_HashGetDigestSize(esd->hashType);\n    if (hashSz < 0) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        return hashSz;\n    }\n#endif\n\n    /* sign digestInfo */\n    switch (pkcs7->publicKeyOID) {\n\n#ifndef NO_RSA\n        case RSAk:\n        #ifdef HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK\n            if (pkcs7->rsaSignRawDigestCb != NULL) {\n                /* get hash OID */\n                hashOID = wc_HashGetOID(esd->hashType);\n\n                /* user signing plain digest, build DigestInfo themselves */\n                ret = pkcs7->rsaSignRawDigestCb(pkcs7,\n                           esd->contentAttribsDigest, hashSz,\n                           esd->encContentDigest, sizeof(esd->encContentDigest),\n                           pkcs7->privateKey, pkcs7->privateKeySz, pkcs7->devId,\n                           hashOID);\n                break;\n            }\n        #endif\n            ret = wc_PKCS7_RsaSign(pkcs7, digestInfo, digestInfoSz, esd);\n            break;\n#endif\n\n#ifdef HAVE_ECC\n        case ECDSAk:\n            /* CMS with ECDSA does not sign DigestInfo structure\n             * like PKCS#7 with RSA does */\n            ret = wc_PKCS7_EcdsaSign(pkcs7, esd->contentAttribsDigest,\n                                     hashSz, esd);\n            break;\n#endif\n\n        default:\n            WOLFSSL_MSG(\"Unsupported public key type\");\n            ret = BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    if (ret >= 0) {\n        esd->encContentDigestSz = (word32)ret;\n    }\n\n    return ret;\n}\n\n\n/* build PKCS#7 signedData content type */\nstatic int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd,\n    const byte* hashBuf, word32 hashSz, byte* output, word32* outputSz,\n    byte* output2, word32* output2Sz)\n{\n    /* contentType OID (1.2.840.113549.1.9.3) */\n    const byte contentTypeOid[] =\n            { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,\n                             0x09, 0x03 };\n\n    /* messageDigest OID (1.2.840.113549.1.9.4) */\n    const byte messageDigestOid[] =\n            { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,\n                             0x09, 0x04 };\n\n    /* signingTime OID () */\n    byte signingTimeOid[] =\n            { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,\n                             0x09, 0x05};\n\n    Pkcs7Cert* certPtr = NULL;\n    word32 certSetSz = 0;\n\n    word32 signerInfoSz = 0;\n    word32 totalSz, total2Sz;\n    int idx = 0, ret = 0;\n    int digEncAlgoId, digEncAlgoType;\n    byte* flatSignedAttribs = NULL;\n    word32 flatSignedAttribsSz = 0;\n\n    byte signedDataOid[MAX_OID_SZ];\n    word32 signedDataOidSz;\n\n    byte signingTime[MAX_TIME_STRING_SZ];\n\n    if (pkcs7 == NULL || pkcs7->contentSz == 0 ||\n        pkcs7->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 ||\n        output == NULL || outputSz == NULL || *outputSz == 0 || hashSz == 0 ||\n        hashBuf == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* verify the hash size matches */\n#ifdef WOLFSSL_SMALL_STACK\n    esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (esd == NULL)\n        return MEMORY_E;\n#endif\n\n    XMEMSET(esd, 0, sizeof(ESD));\n\n    /* set content type based on contentOID, unless user has set custom one\n       with wc_PKCS7_SetContentType() */\n    if (pkcs7->contentTypeSz == 0) {\n\n        /* default to DATA content type if user has not set */\n        if (pkcs7->contentOID == 0) {\n            pkcs7->contentOID = DATA;\n        }\n\n        ret = wc_SetContentType(pkcs7->contentOID, pkcs7->contentType,\n                                sizeof(pkcs7->contentType));\n        if (ret < 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n            return ret;\n        }\n        pkcs7->contentTypeSz = ret;\n    }\n\n    /* set signedData outer content type */\n    ret = wc_SetContentType(SIGNED_DATA, signedDataOid, sizeof(signedDataOid));\n    if (ret < 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return ret;\n    }\n    signedDataOidSz = ret;\n\n    if (pkcs7->sidType != DEGENERATE_SID) {\n        esd->hashType = wc_OidGetHash(pkcs7->hashOID);\n        if (wc_HashGetDigestSize(esd->hashType) != (int)hashSz) {\n            WOLFSSL_MSG(\"hashSz did not match hashOID\");\n    #ifdef WOLFSSL_SMALL_STACK\n            XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n            return BUFFER_E;\n        }\n\n        /* include hash */\n        esd->contentDigest[0] = ASN_OCTET_STRING;\n        esd->contentDigest[1] = (byte)hashSz;\n        XMEMCPY(&esd->contentDigest[2], hashBuf, hashSz);\n    }\n\n    if (pkcs7->detached == 1) {\n        /* do not include content if generating detached signature */\n        esd->innerOctetsSz = 0;\n        esd->innerContSeqSz = 0;\n        esd->contentInfoSeqSz = SetSequence(pkcs7->contentTypeSz,\n                                            esd->contentInfoSeq);\n    } else {\n        esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets);\n        esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz +\n                                    pkcs7->contentSz, esd->innerContSeq);\n        esd->contentInfoSeqSz = SetSequence(pkcs7->contentSz +\n                                    esd->innerOctetsSz + pkcs7->contentTypeSz +\n                                    esd->innerContSeqSz, esd->contentInfoSeq);\n    }\n\n    /* SignerIdentifier */\n    if (pkcs7->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {\n        /* IssuerAndSerialNumber */\n        esd->issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz,\n                                          esd->issuerSn, MAX_SN_SZ, MAX_SN_SZ);\n        signerInfoSz += esd->issuerSnSz;\n        esd->issuerNameSz = SetSequence(pkcs7->issuerSz, esd->issuerName);\n        signerInfoSz += esd->issuerNameSz + pkcs7->issuerSz;\n        esd->issuerSnSeqSz = SetSequence(signerInfoSz, esd->issuerSnSeq);\n        signerInfoSz += esd->issuerSnSeqSz;\n\n        if (pkcs7->version == 3) {\n            /* RFC 4108 version MUST be 3 for firmware package signer */\n            esd->signerVersionSz = SetMyVersion(3, esd->signerVersion, 0);\n        }\n        else {\n            /* version MUST be 1 otherwise*/\n            esd->signerVersionSz = SetMyVersion(1, esd->signerVersion, 0);\n        }\n\n    } else if (pkcs7->sidType == CMS_SKID) {\n        /* SubjectKeyIdentifier */\n        esd->issuerSKIDSz = SetOctetString(KEYID_SIZE, esd->issuerSKID);\n        esd->issuerSKIDSeqSz = SetExplicit(0, esd->issuerSKIDSz + KEYID_SIZE,\n                                           esd->issuerSKIDSeq);\n        signerInfoSz += (esd->issuerSKIDSz + esd->issuerSKIDSeqSz +\n                         KEYID_SIZE);\n\n        /* version MUST be 3 */\n        esd->signerVersionSz = SetMyVersion(3, esd->signerVersion, 0);\n    } else if (pkcs7->sidType == DEGENERATE_SID) {\n        /* no signer info added */\n    } else {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        return SKID_E;\n    }\n\n    if (pkcs7->sidType != DEGENERATE_SID) {\n        signerInfoSz += esd->signerVersionSz;\n        esd->signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->signerDigAlgoId,\n                                          oidHashType, 0);\n        signerInfoSz += esd->signerDigAlgoIdSz;\n\n        /* set signatureAlgorithm */\n        ret = wc_PKCS7_SignedDataGetEncAlgoId(pkcs7, &digEncAlgoId,\n                                              &digEncAlgoType);\n        if (ret < 0) {\n    #ifdef WOLFSSL_SMALL_STACK\n            XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n            return ret;\n        }\n        esd->digEncAlgoIdSz = SetAlgoID(digEncAlgoId, esd->digEncAlgoId,\n                                        digEncAlgoType, 0);\n        signerInfoSz += esd->digEncAlgoIdSz;\n\n        /* build up signed attributes, include contentType, signingTime, and\n           messageDigest by default */\n        ret = wc_PKCS7_BuildSignedAttributes(pkcs7, esd, pkcs7->contentType,\n                                     pkcs7->contentTypeSz,\n                                     contentTypeOid, sizeof(contentTypeOid),\n                                     messageDigestOid, sizeof(messageDigestOid),\n                                     signingTimeOid, sizeof(signingTimeOid),\n                                     signingTime, sizeof(signingTime));\n        if (ret < 0) {\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n            return ret;\n        }\n\n        if (esd->signedAttribsSz > 0) {\n            flatSignedAttribs = (byte*)XMALLOC(esd->signedAttribsSz, pkcs7->heap,\n                                                             DYNAMIC_TYPE_PKCS7);\n            flatSignedAttribsSz = esd->signedAttribsSz;\n            if (flatSignedAttribs == NULL) {\n            #ifdef WOLFSSL_SMALL_STACK\n                XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            #endif\n                return MEMORY_E;\n            }\n\n            FlattenAttributes(pkcs7, flatSignedAttribs,\n                                       esd->signedAttribs, esd->signedAttribsCount);\n            esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz,\n                                                              esd->signedAttribSet);\n        } else {\n            esd->signedAttribSetSz = 0;\n        }\n\n        /* Calculate the final hash and encrypt it. */\n        ret = wc_PKCS7_SignedDataBuildSignature(pkcs7, flatSignedAttribs,\n                                                flatSignedAttribsSz, esd);\n        if (ret < 0) {\n            if (pkcs7->signedAttribsSz != 0)\n                XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n            return ret;\n        }\n\n        signerInfoSz += flatSignedAttribsSz + esd->signedAttribSetSz;\n\n        esd->signerDigestSz = SetOctetString(esd->encContentDigestSz,\n                                                                 esd->signerDigest);\n        signerInfoSz += esd->signerDigestSz + esd->encContentDigestSz;\n\n        esd->signerInfoSeqSz = SetSequence(signerInfoSz, esd->signerInfoSeq);\n        signerInfoSz += esd->signerInfoSeqSz;\n    }\n    esd->signerInfoSetSz = SetSet(signerInfoSz, esd->signerInfoSet);\n    signerInfoSz += esd->signerInfoSetSz;\n\n    /* certificates [0] IMPLICIT CertificateSet */\n    /* get total certificates size */\n    certPtr = pkcs7->certList;\n    while (certPtr != NULL) {\n        certSetSz += certPtr->derSz;\n        certPtr = certPtr->next;\n    }\n    certPtr = NULL;\n\n    if (certSetSz > 0)\n        esd->certsSetSz = SetImplicit(ASN_SET, 0, certSetSz, esd->certsSet);\n\n    if (pkcs7->sidType != DEGENERATE_SID) {\n        esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId,\n                                      oidHashType, 0);\n    }\n    esd->digAlgoIdSetSz = SetSet(esd->singleDigAlgoIdSz, esd->digAlgoIdSet);\n\n    if (pkcs7->version == 3) {\n        /* RFC 4108 version MUST be 3 for firmware package signer */\n        esd->versionSz = SetMyVersion(3, esd->version, 0);\n    }\n    else {\n        esd->versionSz = SetMyVersion(1, esd->version, 0);\n    }\n\n    totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz +\n              esd->contentInfoSeqSz + pkcs7->contentTypeSz +\n              esd->innerContSeqSz + esd->innerOctetsSz + pkcs7->contentSz;\n    total2Sz = esd->certsSetSz + certSetSz + signerInfoSz;\n\n    if (pkcs7->detached) {\n        totalSz -= pkcs7->contentSz;\n    }\n\n    esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq);\n    totalSz += esd->innerSeqSz;\n    esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent);\n    totalSz += esd->outerContentSz + signedDataOidSz;\n    esd->outerSeqSz = SetSequence(totalSz + total2Sz, esd->outerSeq);\n    totalSz += esd->outerSeqSz;\n\n    /* if using header/footer, we are not returning the content */\n    if (output2 && output2Sz) {\n        if (total2Sz > *output2Sz) {\n            if (pkcs7->signedAttribsSz != 0)\n                XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n            return BUFFER_E;\n        }\n\n        if (!pkcs7->detached) {\n            totalSz -= pkcs7->contentSz;\n        }\n    }\n    else {\n        /* if using single output buffer include content and footer */\n        totalSz += total2Sz;\n    }\n\n    if (totalSz > *outputSz) {\n        if (pkcs7->signedAttribsSz != 0)\n            XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        return BUFFER_E;\n    }\n\n    idx = 0;\n    XMEMCPY(output + idx, esd->outerSeq, esd->outerSeqSz);\n    idx += esd->outerSeqSz;\n    XMEMCPY(output + idx, signedDataOid, signedDataOidSz);\n    idx += signedDataOidSz;\n    XMEMCPY(output + idx, esd->outerContent, esd->outerContentSz);\n    idx += esd->outerContentSz;\n    XMEMCPY(output + idx, esd->innerSeq, esd->innerSeqSz);\n    idx += esd->innerSeqSz;\n    XMEMCPY(output + idx, esd->version, esd->versionSz);\n    idx += esd->versionSz;\n    XMEMCPY(output + idx, esd->digAlgoIdSet, esd->digAlgoIdSetSz);\n    idx += esd->digAlgoIdSetSz;\n    XMEMCPY(output + idx, esd->singleDigAlgoId, esd->singleDigAlgoIdSz);\n    idx += esd->singleDigAlgoIdSz;\n    XMEMCPY(output + idx, esd->contentInfoSeq, esd->contentInfoSeqSz);\n    idx += esd->contentInfoSeqSz;\n    XMEMCPY(output + idx, pkcs7->contentType, pkcs7->contentTypeSz);\n    idx += pkcs7->contentTypeSz;\n    XMEMCPY(output + idx, esd->innerContSeq, esd->innerContSeqSz);\n    idx += esd->innerContSeqSz;\n    XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz);\n    idx += esd->innerOctetsSz;\n\n    /* support returning header and footer without content */\n    if (output2 && output2Sz) {\n        *outputSz = idx;\n        idx = 0;\n    }\n    else {\n        if (!pkcs7->detached) {\n            XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);\n            idx += pkcs7->contentSz;\n        }\n        output2 = output;\n    }\n\n    /* certificates */\n    XMEMCPY(output2 + idx, esd->certsSet, esd->certsSetSz);\n    idx += esd->certsSetSz;\n    certPtr = pkcs7->certList;\n    while (certPtr != NULL) {\n        XMEMCPY(output2 + idx, certPtr->der, certPtr->derSz);\n        idx += certPtr->derSz;\n        certPtr = certPtr->next;\n    }\n    wc_PKCS7_FreeCertSet(pkcs7);\n\n    XMEMCPY(output2 + idx, esd->signerInfoSet, esd->signerInfoSetSz);\n    idx += esd->signerInfoSetSz;\n    XMEMCPY(output2 + idx, esd->signerInfoSeq, esd->signerInfoSeqSz);\n    idx += esd->signerInfoSeqSz;\n    XMEMCPY(output2 + idx, esd->signerVersion, esd->signerVersionSz);\n    idx += esd->signerVersionSz;\n    /* SignerIdentifier */\n    if (pkcs7->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {\n        /* IssuerAndSerialNumber */\n        XMEMCPY(output2 + idx, esd->issuerSnSeq, esd->issuerSnSeqSz);\n        idx += esd->issuerSnSeqSz;\n        XMEMCPY(output2 + idx, esd->issuerName, esd->issuerNameSz);\n        idx += esd->issuerNameSz;\n        XMEMCPY(output2 + idx, pkcs7->issuer, pkcs7->issuerSz);\n        idx += pkcs7->issuerSz;\n        XMEMCPY(output2 + idx, esd->issuerSn, esd->issuerSnSz);\n        idx += esd->issuerSnSz;\n    } else if (pkcs7->sidType == CMS_SKID) {\n        /* SubjectKeyIdentifier */\n        XMEMCPY(output2 + idx, esd->issuerSKIDSeq, esd->issuerSKIDSeqSz);\n        idx += esd->issuerSKIDSeqSz;\n        XMEMCPY(output2 + idx, esd->issuerSKID, esd->issuerSKIDSz);\n        idx += esd->issuerSKIDSz;\n        XMEMCPY(output2 + idx, pkcs7->issuerSubjKeyId, KEYID_SIZE);\n        idx += KEYID_SIZE;\n    } else if (pkcs7->sidType == DEGENERATE_SID) {\n        /* no signer infos in degenerate case */\n    } else {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        return SKID_E;\n    }\n    XMEMCPY(output2 + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz);\n    idx += esd->signerDigAlgoIdSz;\n\n    /* SignerInfo:Attributes */\n    if (flatSignedAttribsSz > 0) {\n        XMEMCPY(output2 + idx, esd->signedAttribSet, esd->signedAttribSetSz);\n        idx += esd->signedAttribSetSz;\n        XMEMCPY(output2 + idx, flatSignedAttribs, flatSignedAttribsSz);\n        idx += flatSignedAttribsSz;\n        XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    }\n\n    XMEMCPY(output2 + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz);\n    idx += esd->digEncAlgoIdSz;\n    XMEMCPY(output2 + idx, esd->signerDigest, esd->signerDigestSz);\n    idx += esd->signerDigestSz;\n    XMEMCPY(output2 + idx, esd->encContentDigest, esd->encContentDigestSz);\n    idx += esd->encContentDigestSz;\n\n    if (output2 && output2Sz) {\n        *output2Sz = idx;\n        idx = 0; /* success */\n    }\n    else {\n        *outputSz = idx;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n    return idx;\n}\n\n/* hashBuf: The computed digest for the pkcs7->content\n * hashSz: The size of computed digest for the pkcs7->content based on hashOID\n * outputHead: The PKCS7 header that goes on top of the raw data signed.\n * outputFoot: The PKCS7 footer that goes at the end of the raw data signed.\n * pkcs7->content: Not used\n * pkcs7->contentSz: Must be provided as actual sign of raw data\n * return codes: 0=success, negative=error\n */\nint wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf, word32 hashSz,\n    byte* outputHead, word32* outputHeadSz, byte* outputFoot, word32* outputFootSz)\n{\n    int ret;\n#ifdef WOLFSSL_SMALL_STACK\n    ESD* esd;\n#else\n    ESD  esd[1];\n#endif\n\n    /* other args checked in wc_PKCS7_EncodeSigned_ex */\n    if (pkcs7 == NULL || outputFoot == NULL || outputFootSz == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (esd == NULL)\n        return MEMORY_E;\n#endif\n\n    XMEMSET(esd, 0, sizeof(ESD));\n\n    ret = PKCS7_EncodeSigned(pkcs7, esd, hashBuf, hashSz,\n        outputHead, outputHeadSz, outputFoot, outputFootSz);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n/* Toggle detached signature mode on/off for PKCS#7/CMS SignedData content type.\n * By default wolfCrypt includes the data to be signed in the SignedData\n * bundle. This data can be omitted in the case when a detached signature is\n * being created. To enable generation of detached signatures, set flag to \"1\",\n * otherwise set to \"0\":\n *\n *     flag 1 turns on support\n *     flag 0 turns off support\n *\n * pkcs7 - pointer to initialized PKCS7 structure\n * flag  - turn on/off detached signature generation (1 or 0)\n *\n * Returns 0 on success, negative upon error. */\nint wc_PKCS7_SetDetached(PKCS7* pkcs7, word16 flag)\n{\n    if (pkcs7 == NULL || (flag != 0 && flag != 1))\n        return BAD_FUNC_ARG;\n\n    pkcs7->detached = flag;\n\n    return 0;\n}\n\n/* By default, SignedData bundles have the following signed attributes attached:\n *     contentType (1.2.840.113549.1.9.3)\n *     signgingTime (1.2.840.113549.1.9.5)\n *     messageDigest (1.2.840.113549.1.9.4)\n *\n * Calling this API before wc_PKCS7_EncodeSignedData() will disable the\n * inclusion of those attributes.\n *\n * pkcs7 - pointer to initialized PKCS7 structure\n *\n * Returns 0 on success, negative upon error. */\nint wc_PKCS7_NoDefaultSignedAttribs(PKCS7* pkcs7)\n{\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    pkcs7->skipDefaultSignedAttribs = 1;\n\n    return 0;\n}\n\n/* return codes: >0: Size of signed PKCS7 output buffer, negative: error */\nint wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)\n{\n    int ret;\n    int hashSz;\n    enum wc_HashType hashType;\n    byte hashBuf[WC_MAX_DIGEST_SIZE];\n#ifdef WOLFSSL_SMALL_STACK\n    ESD* esd;\n#else\n    ESD  esd[1];\n#endif\n\n    /* other args checked in wc_PKCS7_EncodeSigned_ex */\n    if (pkcs7 == NULL || pkcs7->contentSz == 0 || pkcs7->content == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* get hash type and size, validate hashOID */\n    hashType = wc_OidGetHash(pkcs7->hashOID);\n    hashSz = wc_HashGetDigestSize(hashType);\n    if (hashSz < 0)\n        return hashSz;\n\n#ifdef WOLFSSL_SMALL_STACK\n    esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (esd == NULL)\n        return MEMORY_E;\n#endif\n\n    XMEMSET(esd, 0, sizeof(ESD));\n    esd->hashType = hashType;\n\n    /* calculate hash for content */\n    ret = wc_HashInit(&esd->hash, esd->hashType);\n    if (ret == 0) {\n        ret = wc_HashUpdate(&esd->hash, esd->hashType,\n                            pkcs7->content, pkcs7->contentSz);\n        if (ret == 0) {\n            ret = wc_HashFinal(&esd->hash, esd->hashType, hashBuf);\n        }\n        wc_HashFree(&esd->hash, esd->hashType);\n    }\n\n    if (ret == 0) {\n        ret = PKCS7_EncodeSigned(pkcs7, esd, hashBuf, hashSz,\n            output, &outputSz, NULL, NULL);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n\n/* Single-shot API to generate a CMS SignedData bundle that encapsulates a\n * content of type FirmwarePkgData. Any recipient certificates should be\n * loaded into the PKCS7 structure prior to calling this function, using\n * wc_PKCS7_InitWithCert() and/or wc_PKCS7_AddCertificate().\n *\n * pkcs7                - pointer to initialized PKCS7 struct\n * privateKey           - private RSA/ECC key, used for signing SignedData\n * privateKeySz         - size of privateKey, octets\n * signOID              - public key algorithm OID, used for sign operation\n * hashOID              - hash algorithm OID, used for signature generation\n * content              - content to be encapsulated, of type FirmwarePkgData\n * contentSz            - size of content, octets\n * signedAttribs        - optional signed attributes\n * signedAttribsSz      - number of PKCS7Attrib members in signedAttribs\n * output               - output buffer for final bundle\n * outputSz             - size of output buffer, octets\n *\n * Returns length of generated bundle on success, negative upon error. */\nint wc_PKCS7_EncodeSignedFPD(PKCS7* pkcs7, byte* privateKey,\n                             word32 privateKeySz, int signOID, int hashOID,\n                             byte* content, word32 contentSz,\n                             PKCS7Attrib* signedAttribs, word32 signedAttribsSz,\n                             byte* output, word32 outputSz)\n{\n    int ret = 0;\n    WC_RNG rng;\n\n    if (pkcs7 == NULL || privateKey == NULL || privateKeySz == 0 ||\n        content == NULL || contentSz == 0 || output == NULL || outputSz == 0)\n        return BAD_FUNC_ARG;\n\n    ret = wc_InitRng(&rng);\n    if (ret != 0)\n        return ret;\n\n    pkcs7->rng = &rng;\n    pkcs7->content = content;\n    pkcs7->contentSz = contentSz;\n    pkcs7->contentOID = FIRMWARE_PKG_DATA;\n    pkcs7->hashOID = hashOID;\n    pkcs7->encryptOID = signOID;\n    pkcs7->privateKey = privateKey;\n    pkcs7->privateKeySz = privateKeySz;\n    pkcs7->signedAttribs = signedAttribs;\n    pkcs7->signedAttribsSz = signedAttribsSz;\n    pkcs7->version = 3;\n\n    ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);\n    if (ret <= 0) {\n        WOLFSSL_MSG(\"Error encoding CMS SignedData content type\");\n        wc_FreeRng(&rng);\n        return ret;\n    }\n\n    wc_FreeRng(&rng);\n\n    return ret;\n}\n\n#ifndef NO_PKCS7_ENCRYPTED_DATA\n\n/* Single-shot API to generate a CMS SignedData bundle that encapsulates a\n * CMS EncryptedData bundle. Content of inner EncryptedData is set to that\n * of FirmwarePkgData. Any recipient certificates should be loaded into the\n * PKCS7 structure prior to calling this function, using wc_PKCS7_InitWithCert()\n * and/or wc_PKCS7_AddCertificate().\n *\n * pkcs7                - pointer to initialized PKCS7 struct\n * encryptKey           - encryption key used for encrypting EncryptedData\n * encryptKeySz         - size of encryptKey, octets\n * privateKey           - private RSA/ECC key, used for signing SignedData\n * privateKeySz         - size of privateKey, octets\n * encryptOID           - encryption algorithm OID, to be used as encryption\n *                        algorithm for EncryptedData\n * signOID              - public key algorithm OID, to be used for sign\n *                        operation in SignedData generation\n * hashOID              - hash algorithm OID, to be used for signature in\n *                        SignedData generation\n * content              - content to be encapsulated\n * contentSz            - size of content, octets\n * unprotectedAttribs   - optional unprotected attributes, for EncryptedData\n * unprotectedAttribsSz - number of PKCS7Attrib members in unprotectedAttribs\n * signedAttribs        - optional signed attributes, for SignedData\n * signedAttribsSz      - number of PKCS7Attrib members in signedAttribs\n * output               - output buffer for final bundle\n * outputSz             - size of output buffer, octets\n *\n * Returns length of generated bundle on success, negative upon error. */\nint wc_PKCS7_EncodeSignedEncryptedFPD(PKCS7* pkcs7, byte* encryptKey,\n                                      word32 encryptKeySz, byte* privateKey,\n                                      word32 privateKeySz, int encryptOID,\n                                      int signOID, int hashOID,\n                                      byte* content, word32 contentSz,\n                                      PKCS7Attrib* unprotectedAttribs,\n                                      word32 unprotectedAttribsSz,\n                                      PKCS7Attrib* signedAttribs,\n                                      word32 signedAttribsSz,\n                                      byte* output, word32 outputSz)\n{\n    int ret = 0, encryptedSz = 0;\n    byte* encrypted = NULL;\n    WC_RNG rng;\n\n    if (pkcs7 == NULL || encryptKey == NULL || encryptKeySz == 0 ||\n        privateKey == NULL || privateKeySz == 0 || content == NULL ||\n        contentSz == 0 || output == NULL || outputSz == 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* 1: build up EncryptedData using FirmwarePkgData type, use output\n     *    buffer as tmp for storage and to get size */\n\n    /* set struct elements, inner content type is FirmwarePkgData */\n    pkcs7->content = content;\n    pkcs7->contentSz = contentSz;\n    pkcs7->contentOID = FIRMWARE_PKG_DATA;\n    pkcs7->encryptOID = encryptOID;\n    pkcs7->encryptionKey = encryptKey;\n    pkcs7->encryptionKeySz = encryptKeySz;\n    pkcs7->unprotectedAttribs = unprotectedAttribs;\n    pkcs7->unprotectedAttribsSz = unprotectedAttribsSz;\n    pkcs7->version = 3;\n\n    encryptedSz = wc_PKCS7_EncodeEncryptedData(pkcs7, output, outputSz);\n    if (encryptedSz < 0) {\n        WOLFSSL_MSG(\"Error encoding CMS EncryptedData content type\");\n        return encryptedSz;\n    }\n\n    /* save encryptedData, reset output buffer and struct */\n    encrypted = (byte*)XMALLOC(encryptedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (encrypted == NULL) {\n        ForceZero(output, outputSz);\n        return MEMORY_E;\n    }\n\n    XMEMCPY(encrypted, output, encryptedSz);\n    ForceZero(output, outputSz);\n\n    ret = wc_InitRng(&rng);\n    if (ret != 0) {\n        ForceZero(encrypted, encryptedSz);\n        XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    /* 2: build up SignedData, encapsulating EncryptedData */\n    pkcs7->rng = &rng;\n    pkcs7->content = encrypted;\n    pkcs7->contentSz = encryptedSz;\n    pkcs7->contentOID = ENCRYPTED_DATA;\n    pkcs7->hashOID = hashOID;\n    pkcs7->encryptOID = signOID;\n    pkcs7->privateKey = privateKey;\n    pkcs7->privateKeySz = privateKeySz;\n    pkcs7->signedAttribs = signedAttribs;\n    pkcs7->signedAttribsSz = signedAttribsSz;\n\n    ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);\n    if (ret <= 0) {\n        WOLFSSL_MSG(\"Error encoding CMS SignedData content type\");\n        ForceZero(encrypted, encryptedSz);\n        XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        wc_FreeRng(&rng);\n        return ret;\n    }\n\n    ForceZero(encrypted, encryptedSz);\n    XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    wc_FreeRng(&rng);\n\n    return ret;\n}\n\n#endif /* NO_PKCS7_ENCRYPTED_DATA */\n\n#if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)\n/* Single-shot API to generate a CMS SignedData bundle that encapsulates a\n * CMS CompressedData bundle. Content of inner CompressedData is set to that\n * of FirmwarePkgData. Any recipient certificates should be loaded into the\n * PKCS7 structure prior to calling this function, using wc_PKCS7_InitWithCert()\n * and/or wc_PKCS7_AddCertificate().\n *\n * pkcs7                - pointer to initialized PKCS7 struct\n * privateKey           - private RSA/ECC key, used for signing SignedData\n * privateKeySz         - size of privateKey, octets\n * signOID              - public key algorithm OID, to be used for sign\n *                        operation in SignedData generation\n * hashOID              - hash algorithm OID, to be used for signature in\n *                        SignedData generation\n * content              - content to be encapsulated\n * contentSz            - size of content, octets\n * signedAttribs        - optional signed attributes, for SignedData\n * signedAttribsSz      - number of PKCS7Attrib members in signedAttribs\n * output               - output buffer for final bundle\n * outputSz             - size of output buffer, octets\n *\n * Returns length of generated bundle on success, negative upon error. */\nint wc_PKCS7_EncodeSignedCompressedFPD(PKCS7* pkcs7, byte* privateKey,\n                                       word32 privateKeySz, int signOID,\n                                       int hashOID, byte* content,\n                                       word32 contentSz,\n                                       PKCS7Attrib* signedAttribs,\n                                       word32 signedAttribsSz, byte* output,\n                                       word32 outputSz)\n{\n    int ret = 0, compressedSz = 0;\n    byte* compressed = NULL;\n    WC_RNG rng;\n\n    if (pkcs7 == NULL || privateKey == NULL || privateKeySz == 0 ||\n        content == NULL || contentSz == 0 || output == NULL || outputSz == 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* 1: build up CompressedData using FirmwarePkgData type, use output\n     *    buffer as tmp for storage and to get size */\n\n    /* set struct elements, inner content type is FirmwarePkgData */\n    pkcs7->content = content;\n    pkcs7->contentSz = contentSz;\n    pkcs7->contentOID = FIRMWARE_PKG_DATA;\n    pkcs7->version = 3;\n\n    compressedSz = wc_PKCS7_EncodeCompressedData(pkcs7, output, outputSz);\n    if (compressedSz < 0) {\n        WOLFSSL_MSG(\"Error encoding CMS CompressedData content type\");\n        return compressedSz;\n    }\n\n    /* save compressedData, reset output buffer and struct */\n    compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (compressed == NULL) {\n        ForceZero(output, outputSz);\n        return MEMORY_E;\n    }\n\n    XMEMCPY(compressed, output, compressedSz);\n    ForceZero(output, outputSz);\n\n    ret = wc_InitRng(&rng);\n    if (ret != 0) {\n        ForceZero(compressed, compressedSz);\n        XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    /* 2: build up SignedData, encapsulating EncryptedData */\n    pkcs7->rng = &rng;\n    pkcs7->content = compressed;\n    pkcs7->contentSz = compressedSz;\n    pkcs7->contentOID = COMPRESSED_DATA;\n    pkcs7->hashOID = hashOID;\n    pkcs7->encryptOID = signOID;\n    pkcs7->privateKey = privateKey;\n    pkcs7->privateKeySz = privateKeySz;\n    pkcs7->signedAttribs = signedAttribs;\n    pkcs7->signedAttribsSz = signedAttribsSz;\n\n    ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);\n    if (ret <= 0) {\n        WOLFSSL_MSG(\"Error encoding CMS SignedData content type\");\n        ForceZero(compressed, compressedSz);\n        XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        wc_FreeRng(&rng);\n        return ret;\n    }\n\n    ForceZero(compressed, compressedSz);\n    XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    wc_FreeRng(&rng);\n\n    return ret;\n}\n\n#ifndef NO_PKCS7_ENCRYPTED_DATA\n\n/* Single-shot API to generate a CMS SignedData bundle that encapsulates a\n * CMS EncryptedData bundle, which then encapsulates a CMS CompressedData\n * bundle. Content of inner CompressedData is set to that of FirmwarePkgData.\n * Any recipient certificates should be loaded into the PKCS7 structure prior\n * to calling this function, using wc_PKCS7_InitWithCert() and/or\n * wc_PKCS7_AddCertificate().\n *\n * pkcs7                - pointer to initialized PKCS7 struct\n * encryptKey           - encryption key used for encrypting EncryptedData\n * encryptKeySz         - size of encryptKey, octets\n * privateKey           - private RSA/ECC key, used for signing SignedData\n * privateKeySz         - size of privateKey, octets\n * encryptOID           - encryption algorithm OID, to be used as encryption\n *                        algorithm for EncryptedData\n * signOID              - public key algorithm OID, to be used for sign\n *                        operation in SignedData generation\n * hashOID              - hash algorithm OID, to be used for signature in\n *                        SignedData generation\n * content              - content to be encapsulated\n * contentSz            - size of content, octets\n * unprotectedAttribs   - optional unprotected attributes, for EncryptedData\n * unprotectedAttribsSz - number of PKCS7Attrib members in unprotectedAttribs\n * signedAttribs        - optional signed attributes, for SignedData\n * signedAttribsSz      - number of PKCS7Attrib members in signedAttribs\n * output               - output buffer for final bundle\n * outputSz             - size of output buffer, octets\n *\n * Returns length of generated bundle on success, negative upon error. */\nint  wc_PKCS7_EncodeSignedEncryptedCompressedFPD(PKCS7* pkcs7, byte* encryptKey,\n                                       word32 encryptKeySz, byte* privateKey,\n                                       word32 privateKeySz, int encryptOID,\n                                       int signOID, int hashOID, byte* content,\n                                       word32 contentSz,\n                                       PKCS7Attrib* unprotectedAttribs,\n                                       word32 unprotectedAttribsSz,\n                                       PKCS7Attrib* signedAttribs,\n                                       word32 signedAttribsSz,\n                                       byte* output, word32 outputSz)\n{\n    int ret = 0, compressedSz = 0, encryptedSz = 0;\n    byte* compressed = NULL;\n    byte* encrypted = NULL;\n    WC_RNG rng;\n\n    if (pkcs7 == NULL || encryptKey == NULL || encryptKeySz == 0 ||\n        privateKey == NULL || privateKeySz == 0 || content == NULL ||\n        contentSz == 0 || output == NULL || outputSz == 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* 1: build up CompressedData using FirmwarePkgData type, use output\n     *    buffer as tmp for storage and to get size */\n    pkcs7->content = content;\n    pkcs7->contentSz = contentSz;\n    pkcs7->contentOID = FIRMWARE_PKG_DATA;\n    pkcs7->version = 3;\n\n    compressedSz = wc_PKCS7_EncodeCompressedData(pkcs7, output, outputSz);\n    if (compressedSz < 0) {\n        WOLFSSL_MSG(\"Error encoding CMS CompressedData content type\");\n        return compressedSz;\n    }\n\n    /* save compressedData, reset output buffer and struct */\n    compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (compressed == NULL)\n        return MEMORY_E;\n\n    XMEMCPY(compressed, output, compressedSz);\n    ForceZero(output, outputSz);\n\n    /* 2: build up EncryptedData using CompressedData, use output\n     *    buffer as tmp for storage and to get size */\n    pkcs7->content = compressed;\n    pkcs7->contentSz = compressedSz;\n    pkcs7->contentOID = COMPRESSED_DATA;\n    pkcs7->encryptOID = encryptOID;\n    pkcs7->encryptionKey = encryptKey;\n    pkcs7->encryptionKeySz = encryptKeySz;\n    pkcs7->unprotectedAttribs = unprotectedAttribs;\n    pkcs7->unprotectedAttribsSz = unprotectedAttribsSz;\n\n    encryptedSz = wc_PKCS7_EncodeEncryptedData(pkcs7, output, outputSz);\n    if (encryptedSz < 0) {\n        WOLFSSL_MSG(\"Error encoding CMS EncryptedData content type\");\n        XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return encryptedSz;\n    }\n\n    /* save encryptedData, reset output buffer and struct */\n    encrypted = (byte*)XMALLOC(encryptedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (encrypted == NULL) {\n        ForceZero(compressed, compressedSz);\n        XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return MEMORY_E;\n    }\n\n    XMEMCPY(encrypted, output, encryptedSz);\n    ForceZero(compressed, compressedSz);\n    XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    ForceZero(output, outputSz);\n\n    ret = wc_InitRng(&rng);\n    if (ret != 0) {\n        ForceZero(encrypted, encryptedSz);\n        XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    /* 3: build up SignedData, encapsulating EncryptedData */\n    pkcs7->rng = &rng;\n    pkcs7->content = encrypted;\n    pkcs7->contentSz = encryptedSz;\n    pkcs7->contentOID = ENCRYPTED_DATA;\n    pkcs7->hashOID = hashOID;\n    pkcs7->encryptOID = signOID;\n    pkcs7->privateKey = privateKey;\n    pkcs7->privateKeySz = privateKeySz;\n    pkcs7->signedAttribs = signedAttribs;\n    pkcs7->signedAttribsSz = signedAttribsSz;\n\n    ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);\n    if (ret <= 0) {\n        WOLFSSL_MSG(\"Error encoding CMS SignedData content type\");\n        ForceZero(encrypted, encryptedSz);\n        XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        wc_FreeRng(&rng);\n        return ret;\n    }\n\n    ForceZero(encrypted, encryptedSz);\n    XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    wc_FreeRng(&rng);\n\n    return ret;\n}\n\n#endif /* !NO_PKCS7_ENCRYPTED_DATA */\n#endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */\n\n\n#ifndef NO_RSA\n\n#ifdef HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK\n/* register raw RSA sign digest callback */\nint wc_PKCS7_SetRsaSignRawDigestCb(PKCS7* pkcs7, CallbackRsaSignRawDigest cb)\n{\n    if (pkcs7 == NULL || cb == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    pkcs7->rsaSignRawDigestCb = cb;\n\n    return 0;\n}\n#endif\n\n/* returns size of signature put into out, negative on error */\nstatic int wc_PKCS7_RsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,\n                              byte* hash, word32 hashSz)\n{\n    int ret = 0, i;\n    word32 scratch = 0, verified = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    byte* digest;\n    RsaKey* key;\n    DecodedCert* dCert;\n#else\n    byte digest[MAX_PKCS7_DIGEST_SZ];\n    RsaKey key[1];\n    DecodedCert stack_dCert;\n    DecodedCert* dCert = &stack_dCert;\n#endif\n\n    if (pkcs7 == NULL || sig == NULL || hash == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (digest == NULL)\n        return MEMORY_E;\n\n    key = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (key == NULL) {\n        XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n\n    dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,\n                                  DYNAMIC_TYPE_DCERT);\n    if (dCert == NULL) {\n        XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n#endif\n\n    XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);\n\n    /* loop over certs received in certificates set, try to find one\n     * that will validate signature */\n    for (i = 0; i < MAX_PKCS7_CERTS; i++) {\n\n        verified = 0;\n        scratch  = 0;\n\n        if (pkcs7->certSz[i] == 0)\n            continue;\n\n        ret = wc_InitRsaKey_ex(key, pkcs7->heap, pkcs7->devId);\n        if (ret != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(key,    pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(dCert,  pkcs7->heap, DYNAMIC_TYPE_DCERT);\n#endif\n            return ret;\n        }\n\n        InitDecodedCert(dCert, pkcs7->cert[i], pkcs7->certSz[i], pkcs7->heap);\n        /* not verifying, only using this to extract public key */\n        ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);\n        if (ret < 0) {\n            WOLFSSL_MSG(\"ASN RSA cert parse error\");\n            FreeDecodedCert(dCert);\n            wc_FreeRsaKey(key);\n            continue;\n        }\n\n        if (wc_RsaPublicKeyDecode(dCert->publicKey, &scratch, key,\n                                  dCert->pubKeySize) < 0) {\n            WOLFSSL_MSG(\"ASN RSA key decode error\");\n            FreeDecodedCert(dCert);\n            wc_FreeRsaKey(key);\n            continue;\n        }\n\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        do {\n            ret = wc_AsyncWait(ret, &key->asyncDev,\n                WC_ASYNC_FLAG_CALL_AGAIN);\n    #endif\n            if (ret >= 0) {\n                ret = wc_RsaSSL_Verify(sig, sigSz, digest, MAX_PKCS7_DIGEST_SZ,\n                    key);\n            }\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        } while (ret == WC_PENDING_E);\n    #endif\n        FreeDecodedCert(dCert);\n        wc_FreeRsaKey(key);\n\n        if ((ret > 0) && (hashSz == (word32)ret)) {\n            if (XMEMCMP(digest, hash, hashSz) == 0) {\n                /* found signer that successfully verified signature */\n                verified = 1;\n                break;\n            }\n        }\n    }\n\n    if (verified == 0) {\n        ret = SIG_VERIFY_E;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(key,    pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(dCert,  pkcs7->heap, DYNAMIC_TYPE_DCERT);\n#endif\n\n    return ret;\n}\n\n#endif /* NO_RSA */\n\n\n#ifdef HAVE_ECC\n\n/* returns size of signature put into out, negative on error */\nstatic int wc_PKCS7_EcdsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,\n                                byte* hash, word32 hashSz)\n{\n    int ret = 0, i;\n    int res = 0;\n    int verified = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    byte* digest;\n    ecc_key* key;\n    DecodedCert* dCert;\n#else\n    byte digest[MAX_PKCS7_DIGEST_SZ];\n    ecc_key key[1];\n    DecodedCert stack_dCert;\n    DecodedCert* dCert = &stack_dCert;\n#endif\n    word32 idx = 0;\n\n    if (pkcs7 == NULL || sig == NULL)\n        return BAD_FUNC_ARG;\n\n#ifdef WOLFSSL_SMALL_STACK\n    digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (digest == NULL)\n        return MEMORY_E;\n\n    key = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (key == NULL) {\n        XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n\n    dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,\n                                  DYNAMIC_TYPE_DCERT);\n    if (dCert == NULL) {\n        XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(key,    pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n#endif\n\n    XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);\n\n    /* loop over certs received in certificates set, try to find one\n     * that will validate signature */\n    for (i = 0; i < MAX_PKCS7_CERTS; i++) {\n\n        verified = 0;\n\n        if (pkcs7->certSz[i] == 0)\n            continue;\n\n        ret = wc_ecc_init_ex(key, pkcs7->heap, pkcs7->devId);\n        if (ret != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(key,    pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(dCert,  pkcs7->heap, DYNAMIC_TYPE_DCERT);\n#endif\n            return ret;\n        }\n\n        InitDecodedCert(dCert, pkcs7->cert[i], pkcs7->certSz[i], pkcs7->heap);\n        /* not verifying, only using this to extract public key */\n        ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);\n        if (ret < 0) {\n            WOLFSSL_MSG(\"ASN ECC cert parse error\");\n            FreeDecodedCert(dCert);\n            wc_ecc_free(key);\n            continue;\n        }\n\n        if (wc_EccPublicKeyDecode(pkcs7->publicKey, &idx, key,\n                                  pkcs7->publicKeySz) < 0) {\n            WOLFSSL_MSG(\"ASN ECC key decode error\");\n            FreeDecodedCert(dCert);\n            wc_ecc_free(key);\n            continue;\n        }\n\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        do {\n            ret = wc_AsyncWait(ret, &key->asyncDev,\n                WC_ASYNC_FLAG_CALL_AGAIN);\n    #endif\n            if (ret >= 0) {\n                ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, &res, key);\n            }\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        } while (ret == WC_PENDING_E);\n    #endif\n\n        FreeDecodedCert(dCert);\n        wc_ecc_free(key);\n\n        if (ret == 0 && res == 1) {\n            /* found signer that successfully verified signature */\n            verified = 1;\n            break;\n        }\n    }\n\n    if (verified == 0) {\n        ret = SIG_VERIFY_E;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(key,    pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(dCert,  pkcs7->heap, DYNAMIC_TYPE_DCERT);\n#endif\n\n    return ret;\n}\n\n#endif /* HAVE_ECC */\n\n\n/* build SignedData digest, both in PKCS#7 DigestInfo format and\n * as plain digest for CMS.\n *\n * pkcs7          - pointer to initialized PKCS7 struct\n * signedAttrib   - signed attributes\n * signedAttribSz - size of signedAttrib, octets\n * pkcs7Digest    - [OUT] PKCS#7 DigestInfo\n * pkcs7DigestSz  - [IN/OUT] size of pkcs7Digest\n * plainDigest    - [OUT] pointer to plain digest, offset into pkcs7Digest\n * plainDigestSz  - [OUT] size of digest at plainDigest\n *\n * returns 0 on success, negative on error */\nstatic int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,\n                                      word32 signedAttribSz, byte* pkcs7Digest,\n                                      word32* pkcs7DigestSz, byte** plainDigest,\n                                      word32* plainDigestSz,\n                                      const byte* hashBuf, word32 hashBufSz)\n{\n    int ret = 0, digIdx = 0;\n    word32 attribSetSz = 0, hashSz = 0;\n    byte attribSet[MAX_SET_SZ];\n    byte digest[WC_MAX_DIGEST_SIZE];\n    byte digestInfoSeq[MAX_SEQ_SZ];\n    byte digestStr[MAX_OCTET_STR_SZ];\n    byte algoId[MAX_ALGO_SZ];\n    word32 digestInfoSeqSz, digestStrSz, algoIdSz;\n#ifdef WOLFSSL_SMALL_STACK\n    byte* digestInfo;\n#else\n    byte  digestInfo[MAX_PKCS7_DIGEST_SZ];\n#endif\n\n    wc_HashAlg hash;\n    enum wc_HashType hashType;\n\n    /* check arguments */\n    if (pkcs7 == NULL || pkcs7Digest == NULL ||\n        pkcs7DigestSz == NULL || plainDigest == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    hashType = wc_OidGetHash(pkcs7->hashOID);\n    ret = wc_HashGetDigestSize(hashType);\n    if (ret < 0)\n        return ret;\n    hashSz = ret;\n\n    if (signedAttribSz > 0) {\n        if (signedAttrib == NULL)\n            return BAD_FUNC_ARG;\n    }\n    else {\n        if (hashBuf && hashBufSz > 0) {\n            if (hashSz != hashBufSz)\n                return BAD_FUNC_ARG;\n        }\n        else if (pkcs7->content == NULL)\n            return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    digestInfo = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,\n        DYNAMIC_TYPE_TMP_BUFFER);\n    if (digestInfo == NULL)\n        return MEMORY_E;\n#endif\n\n    XMEMSET(pkcs7Digest, 0, *pkcs7DigestSz);\n    XMEMSET(digest,      0, WC_MAX_DIGEST_SIZE);\n    XMEMSET(digestInfo,  0, MAX_PKCS7_DIGEST_SZ);\n\n\n    /* calculate digest */\n    if (hashBuf && hashBufSz > 0 && signedAttribSz == 0) {\n        XMEMCPY(digest, hashBuf, hashBufSz);\n    }\n    else {\n        ret = wc_HashInit(&hash, hashType);\n        if (ret < 0) {\n    #ifdef WOLFSSL_SMALL_STACK\n            XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n            return ret;\n        }\n\n        if (signedAttribSz > 0) {\n            attribSetSz = SetSet(signedAttribSz, attribSet);\n\n            /* calculate digest */\n            ret = wc_HashUpdate(&hash, hashType, attribSet, attribSetSz);\n            if (ret == 0)\n                ret = wc_HashUpdate(&hash, hashType, signedAttrib, signedAttribSz);\n            if (ret == 0)\n                ret = wc_HashFinal(&hash, hashType, digest);\n        } else {\n            ret = wc_HashUpdate(&hash, hashType, pkcs7->content, pkcs7->contentSz);\n            if (ret == 0)\n                ret = wc_HashFinal(&hash, hashType, digest);\n        }\n\n        wc_HashFree(&hash, hashType);\n        if (ret < 0) {\n    #ifdef WOLFSSL_SMALL_STACK\n            XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n            return ret;\n        }\n    }\n\n    /* Set algoID, with NULL attributes */\n    algoIdSz = SetAlgoID(pkcs7->hashOID, algoId, oidHashType, 0);\n\n    digestStrSz = SetOctetString(hashSz, digestStr);\n    digestInfoSeqSz = SetSequence(algoIdSz + digestStrSz + hashSz,\n                                  digestInfoSeq);\n\n    XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);\n    digIdx += digestInfoSeqSz;\n    XMEMCPY(digestInfo + digIdx, algoId, algoIdSz);\n    digIdx += algoIdSz;\n    XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);\n    digIdx += digestStrSz;\n    XMEMCPY(digestInfo + digIdx, digest, hashSz);\n    digIdx += hashSz;\n\n    XMEMCPY(pkcs7Digest, digestInfo, digIdx);\n    *pkcs7DigestSz = digIdx;\n\n    /* set plain digest pointer */\n    *plainDigest = pkcs7Digest + digIdx - hashSz;\n    *plainDigestSz = hashSz;\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n    return 0;\n}\n\n\n/* Verifies CMS/PKCS7 SignedData content digest matches that which is\n * included in the messageDigest signed attribute. Only called when\n * signed attributes are present, otherwise original signature verification\n * is done over content.\n *\n * pkcs7          - pointer to initialized PKCS7 struct\n * hashBuf        - pointer to user-provided hash buffer, used with\n *                  wc_PKCS7_VerifySignedData_ex()\n * hashBufSz      - size of hashBuf, octets\n *\n * return 0 on success, negative on error */\nstatic int wc_PKCS7_VerifyContentMessageDigest(PKCS7* pkcs7,\n                                               const byte* hashBuf,\n                                               word32 hashSz)\n{\n    int ret = 0, digestSz = 0, innerAttribSz = 0;\n    word32 idx = 0;\n    byte* digestBuf = NULL;\n#ifdef WOLFSSL_SMALL_STACK\n    byte* digest = NULL;\n#else\n    byte  digest[MAX_PKCS7_DIGEST_SZ];\n#endif\n    PKCS7DecodedAttrib* attrib;\n    enum wc_HashType hashType;\n\n    /* messageDigest OID (1.2.840.113549.1.9.4) */\n    const byte mdOid[] =\n            { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04 };\n\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    if ((pkcs7->content == NULL || pkcs7->contentSz == 0) &&\n        (hashBuf == NULL || hashSz == 0)) {\n        WOLFSSL_MSG(\"SignedData bundle has no content or hash to verify\");\n        return BAD_FUNC_ARG;\n    }\n\n    /* lookup messageDigest attribute */\n    attrib = findAttrib(pkcs7, mdOid, sizeof(mdOid));\n    if (attrib == NULL) {\n        WOLFSSL_MSG(\"messageDigest attribute not in bundle, must be when \"\n                    \"signed attribs are present\");\n        return ASN_PARSE_E;\n    }\n\n    /* advance past attrib->value ASN.1 header and length */\n    if (attrib->value == NULL || attrib->valueSz == 0)\n        return ASN_PARSE_E;\n\n    if (attrib->value[idx++] != ASN_OCTET_STRING)\n        return ASN_PARSE_E;\n\n    if (GetLength(attrib->value, &idx, &innerAttribSz, attrib->valueSz) < 0)\n        return ASN_PARSE_E;\n\n    /* get hash type and size */\n    hashType = wc_OidGetHash(pkcs7->hashOID);\n    if (hashType == WC_HASH_TYPE_NONE) {\n        WOLFSSL_MSG(\"Error getting hash type for PKCS7 content verification\");\n        return BAD_FUNC_ARG;\n    }\n\n    /* build content hash if needed, or use existing hash value */\n    if (hashBuf == NULL) {\n\n#ifdef WOLFSSL_SMALL_STACK\n        digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,\n                                DYNAMIC_TYPE_TMP_BUFFER);\n        if (digest == NULL)\n            return MEMORY_E;\n#endif\n        XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);\n\n        ret = wc_Hash(hashType, pkcs7->content, pkcs7->contentSz, digest,\n                      MAX_PKCS7_DIGEST_SZ);\n        if (ret < 0) {\n            WOLFSSL_MSG(\"Error hashing PKCS7 content for verification\");\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n            return ret;\n        }\n\n        digestBuf = digest;\n        digestSz = wc_HashGetDigestSize(hashType);\n        if (digestSz < 0) {\n            WOLFSSL_MSG(\"Invalid hash type\");\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n            return digestSz;\n        }\n    } else {\n\n        /* user passed in pre-computed hash */\n        digestBuf = (byte*)hashBuf;\n        digestSz  = (int)hashSz;\n    }\n\n    /* compare generated to hash in messageDigest attribute */\n    if ((innerAttribSz != digestSz) ||\n        (XMEMCMP(attrib->value + idx, digestBuf, (word32)digestSz) != 0)) {\n        WOLFSSL_MSG(\"Content digest does not match messageDigest attrib value\");\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return SIG_VERIFY_E;\n    }\n\n    if (hashBuf == NULL) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n    }\n\n    return 0;\n}\n\n\n/* verifies SignedData signature, over either PKCS#7 DigestInfo or\n * content digest.\n *\n * pkcs7          - pointer to initialized PKCS7 struct\n * sig            - signature to verify\n * sigSz          - size of sig\n * signedAttrib   - signed attributes, or null if empty\n * signedAttribSz - size of signedAttributes\n *\n * return 0 on success, negative on error */\nstatic int wc_PKCS7_SignedDataVerifySignature(PKCS7* pkcs7, byte* sig,\n                                             word32 sigSz, byte* signedAttrib,\n                                             word32 signedAttribSz,\n                                             const byte* hashBuf, word32 hashSz)\n{\n    int ret = 0;\n    word32 plainDigestSz = 0, pkcs7DigestSz;\n    byte* plainDigest = NULL; /* offset into pkcs7Digest */\n#ifdef WOLFSSL_SMALL_STACK\n    byte* pkcs7Digest;\n#else\n    byte  pkcs7Digest[MAX_PKCS7_DIGEST_SZ];\n#endif\n\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    /* allocate space to build hash */\n    pkcs7DigestSz = MAX_PKCS7_DIGEST_SZ;\n#ifdef WOLFSSL_SMALL_STACK\n    pkcs7Digest = (byte*)XMALLOC(pkcs7DigestSz, pkcs7->heap,\n                                 DYNAMIC_TYPE_TMP_BUFFER);\n    if (pkcs7Digest == NULL)\n        return MEMORY_E;\n#endif\n\n    XMEMSET(pkcs7Digest, 0, pkcs7DigestSz);\n\n    /* verify signed attrib digest matches that of content */\n    if (signedAttrib != NULL) {\n        ret = wc_PKCS7_VerifyContentMessageDigest(pkcs7, hashBuf, hashSz);\n        if (ret != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n            return ret;\n        }\n    }\n\n    /* build hash to verify against */\n    ret = wc_PKCS7_BuildSignedDataDigest(pkcs7, signedAttrib,\n                                         signedAttribSz, pkcs7Digest,\n                                         &pkcs7DigestSz, &plainDigest,\n                                         &plainDigestSz, hashBuf, hashSz);\n    if (ret < 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return ret;\n    }\n\n    /* If no certificates are available then store the signature and hash for\n     * user to verify. Make sure that different return value than success is\n     * returned because the signature was not verified here. */\n    if (ret == 0) {\n        byte haveCert = 0;\n        int  i;\n\n        for (i = 0; i < MAX_PKCS7_CERTS; i++) {\n            if (pkcs7->certSz[i] == 0)\n                continue;\n            haveCert = 1;\n        }\n\n        if (!haveCert) {\n            WOLFSSL_MSG(\"No certificates in bundle to verify signature\");\n\n            /* store signature */\n            XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGNATURE);\n            pkcs7->signature = NULL;\n            pkcs7->signatureSz = 0;\n            pkcs7->signature = (byte*)XMALLOC(sigSz, pkcs7->heap,\n                    DYNAMIC_TYPE_SIGNATURE);\n            if (pkcs7->signature == NULL) {\n            #ifdef WOLFSSL_SMALL_STACK\n                XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            #endif\n                return MEMORY_E;\n            }\n            XMEMCPY(pkcs7->signature, sig, sigSz);\n            pkcs7->signatureSz = sigSz;\n\n            /* store plain digest (CMS and ECC) */\n            XFREE(pkcs7->plainDigest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);\n            pkcs7->plainDigest = NULL;\n            pkcs7->plainDigestSz = 0;\n            pkcs7->plainDigest = (byte*)XMALLOC(plainDigestSz, pkcs7->heap,\n                    DYNAMIC_TYPE_DIGEST);\n            if (pkcs7->plainDigest == NULL) {\n            #ifdef WOLFSSL_SMALL_STACK\n                XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            #endif\n                return MEMORY_E;\n            }\n            XMEMCPY(pkcs7->plainDigest, plainDigest, plainDigestSz);\n            pkcs7->plainDigestSz = plainDigestSz;\n\n            /* store pkcs7 digest (default RSA) */\n            XFREE(pkcs7->pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);\n            pkcs7->pkcs7Digest = NULL;\n            pkcs7->pkcs7DigestSz = 0;\n            pkcs7->pkcs7Digest = (byte*)XMALLOC(pkcs7DigestSz, pkcs7->heap,\n                    DYNAMIC_TYPE_DIGEST);\n            if (pkcs7->pkcs7Digest == NULL) {\n            #ifdef WOLFSSL_SMALL_STACK\n                XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            #endif\n                return MEMORY_E;\n            }\n            XMEMCPY(pkcs7->pkcs7Digest, pkcs7Digest, pkcs7DigestSz);\n            pkcs7->pkcs7DigestSz = pkcs7DigestSz;\n\n            #ifdef WOLFSSL_SMALL_STACK\n            XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            #endif\n            return PKCS7_SIGNEEDS_CHECK;\n        }\n    }\n\n\n\n    switch (pkcs7->publicKeyOID) {\n\n#ifndef NO_RSA\n        case RSAk:\n            ret = wc_PKCS7_RsaVerify(pkcs7, sig, sigSz, pkcs7Digest,\n                                     pkcs7DigestSz);\n            if (ret < 0) {\n                WOLFSSL_MSG(\"PKCS#7 verification failed, trying CMS\");\n                ret = wc_PKCS7_RsaVerify(pkcs7, sig, sigSz, plainDigest,\n                                         plainDigestSz);\n            }\n            break;\n#endif\n\n#ifdef HAVE_ECC\n        case ECDSAk:\n            ret = wc_PKCS7_EcdsaVerify(pkcs7, sig, sigSz, plainDigest,\n                                       plainDigestSz);\n            break;\n#endif\n\n        default:\n            WOLFSSL_MSG(\"Unsupported public key type\");\n            ret = BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n     XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n    return ret;\n}\n\n\n/* set correct public key OID based on signature OID, stores in\n * pkcs7->publicKeyOID and returns same value */\nstatic int wc_PKCS7_SetPublicKeyOID(PKCS7* pkcs7, int sigOID)\n{\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    pkcs7->publicKeyOID = 0;\n\n    switch (sigOID) {\n\n    #ifndef NO_RSA\n        /* RSA signature types */\n        case CTC_MD2wRSA:\n        case CTC_MD5wRSA:\n        case CTC_SHAwRSA:\n        case CTC_SHA224wRSA:\n        case CTC_SHA256wRSA:\n        case CTC_SHA384wRSA:\n        case CTC_SHA512wRSA:\n            pkcs7->publicKeyOID = RSAk;\n            break;\n\n        /* if sigOID is already RSAk */\n        case RSAk:\n            pkcs7->publicKeyOID = sigOID;\n            break;\n    #endif\n\n    #ifndef NO_DSA\n        /* DSA signature types */\n        case CTC_SHAwDSA:\n            pkcs7->publicKeyOID = DSAk;\n            break;\n\n        /* if sigOID is already DSAk */\n        case DSAk:\n            pkcs7->publicKeyOID = sigOID;\n            break;\n    #endif\n\n    #ifdef HAVE_ECC\n        /* ECDSA signature types */\n        case CTC_SHAwECDSA:\n        case CTC_SHA224wECDSA:\n        case CTC_SHA256wECDSA:\n        case CTC_SHA384wECDSA:\n        case CTC_SHA512wECDSA:\n            pkcs7->publicKeyOID = ECDSAk;\n            break;\n\n        /* if sigOID is already ECDSAk */\n        case ECDSAk:\n            pkcs7->publicKeyOID = sigOID;\n            break;\n    #endif\n\n        default:\n            WOLFSSL_MSG(\"Unsupported public key algorithm\");\n            return ASN_SIG_KEY_E;\n    }\n\n    return pkcs7->publicKeyOID;\n}\n\n\n/* Parses through the attributes and adds them to the PKCS7 structure\n * Creates dynamic attribute structures that are free'd with calling\n * wc_PKCS7_Free()\n *\n * NOTE: An attribute has the ASN1 format of\n ** Sequence\n ****** Object ID\n ****** Set\n ********** {PritnableString, UTCTime, OCTET STRING ...}\n *\n * pkcs7  the PKCS7 structure to put the parsed attributes into\n * in     buffer holding all attributes\n * inSz   size of in buffer\n *\n * returns the number of attributes parsed on success\n */\nstatic int wc_PKCS7_ParseAttribs(PKCS7* pkcs7, byte* in, int inSz)\n{\n    int    found = 0;\n    word32 idx   = 0;\n    word32 oid;\n\n    if (pkcs7 == NULL || in == NULL || inSz < 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    while (idx < (word32)inSz) {\n        int length  = 0;\n        int oidIdx;\n        PKCS7DecodedAttrib* attrib;\n\n        if (GetSequence(in, &idx, &length, inSz) < 0)\n            return ASN_PARSE_E;\n\n        attrib = (PKCS7DecodedAttrib*)XMALLOC(sizeof(PKCS7DecodedAttrib),\n                pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        if (attrib == NULL) {\n            return MEMORY_E;\n        }\n        XMEMSET(attrib, 0, sizeof(PKCS7DecodedAttrib));\n\n        oidIdx = idx;\n        if (GetObjectId(in, &idx, &oid, oidIgnoreType, inSz)\n                < 0) {\n            XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return ASN_PARSE_E;\n        }\n        attrib->oidSz = idx - oidIdx;\n        attrib->oid = (byte*)XMALLOC(attrib->oidSz, pkcs7->heap,\n                                     DYNAMIC_TYPE_PKCS7);\n        if (attrib->oid == NULL) {\n            XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return MEMORY_E;\n        }\n        XMEMCPY(attrib->oid, in + oidIdx, attrib->oidSz);\n\n        /* Get Set that contains the printable string value */\n        if (GetSet(in, &idx, &length, inSz) < 0) {\n            XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return ASN_PARSE_E;\n        }\n\n        if ((inSz - idx) < (word32)length) {\n            XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return ASN_PARSE_E;\n        }\n\n        attrib->valueSz = (word32)length;\n        attrib->value = (byte*)XMALLOC(attrib->valueSz, pkcs7->heap,\n                                       DYNAMIC_TYPE_PKCS7);\n        if (attrib->value == NULL) {\n            XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return MEMORY_E;\n        }\n        XMEMCPY(attrib->value, in + idx, attrib->valueSz);\n        idx += length;\n\n        /* store attribute in linked list */\n        if (pkcs7->decodedAttrib != NULL) {\n            attrib->next = pkcs7->decodedAttrib;\n            pkcs7->decodedAttrib = attrib;\n        } else {\n            pkcs7->decodedAttrib = attrib;\n        }\n        found++;\n    }\n\n    return found;\n}\n\n\n/* option to turn off support for degenerate cases\n * flag 0 turns off support\n * flag 1 turns on support\n *\n * by default support for SignedData degenerate cases is on\n */\nvoid wc_PKCS7_AllowDegenerate(PKCS7* pkcs7, word16 flag)\n{\n    if (pkcs7) {\n        if (flag) { /* flag of 1 turns on support for degenerate */\n            pkcs7->noDegenerate = 0;\n        }\n        else { /* flag of 0 turns off support */\n            pkcs7->noDegenerate = 1;\n        }\n    }\n}\n\n/* Parses through a signerInfo set. Reads buffer \"in\" from \"idxIn\" to \"idxIn\" +\n * length treating the current \"idxIn\" plus the length of set as max possible\n * index.\n *\n * In the case that signed attributes are found \"signedAttrib\" gets set to point\n *  at their location in the buffer \"in\". Also in this case signedAttribSz gets\n *  set to the size of the signedAttrib buffer.\n *\n * returns 0 on success\n */\nstatic int wc_PKCS7_ParseSignerInfo(PKCS7* pkcs7, byte* in, word32 inSz,\n        word32* idxIn, int degenerate, byte** signedAttrib, int* signedAttribSz)\n{\n    int ret = 0;\n    int length;\n    int version;\n    word32 sigOID = 0, hashOID = 0;\n    word32 idx = *idxIn, localIdx;\n    byte tag;\n\n    WOLFSSL_ENTER(\"wc_PKCS7_ParseSignerInfo\");\n    /* require a signer if degenerate case not allowed */\n    if (inSz == 0 && pkcs7->noDegenerate == 1) {\n        WOLFSSL_MSG(\"Set to not allow degenerate cases\");\n        return PKCS7_NO_SIGNER_E;\n    }\n\n    if (inSz == 0 && degenerate == 0) {\n        WOLFSSL_MSG(\"PKCS7 signers expected\");\n        return PKCS7_NO_SIGNER_E;\n    }\n\n    /* not a degenerate case and there is elements in the set */\n    if (inSz > 0 && degenerate == 0) {\n        ret = wc_PKCS7_SignerInfoNew(pkcs7);\n\n        /* Get the sequence of the first signerInfo */\n        if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0)\n            ret = ASN_PARSE_E;\n\n        /* Get the version */\n        if (ret == 0 && GetMyVersion(in, &idx, &version, inSz) < 0)\n            ret = ASN_PARSE_E;\n\n        if (ret == 0) {\n            pkcs7->signerInfo->version = version;\n        }\n\n        if (ret == 0 && version == 1) {\n            /* Get the sequence of IssuerAndSerialNumber */\n            if (GetSequence(in, &idx, &length, inSz) < 0)\n                ret = ASN_PARSE_E;\n\n            if (ret == 0) {\n                ret = wc_PKCS7_SignerInfoSetSID(pkcs7, in + idx, length);\n                idx += length;\n            }\n\n        } else if (ret == 0 && version == 3) {\n            /* Get the sequence of SubjectKeyIdentifier */\n            if (idx + 1 > inSz)\n                ret = BUFFER_E;\n\n            localIdx = idx;\n            if (ret == 0 && GetASNTag(in, &localIdx, &tag, inSz) == 0 &&\n                   tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {\n                idx++;\n\n                if (ret == 0 && GetLength(in, &idx, &length, inSz) <= 0) {\n                    ret = ASN_PARSE_E;\n                }\n\n                if (idx + 1 > inSz)\n                    ret = BUFFER_E;\n\n                if (ret == 0 && GetASNTag(in, &idx, &tag, inSz) < 0)\n                    ret = ASN_PARSE_E;\n\n                if (ret == 0 && tag != ASN_OCTET_STRING)\n                    ret = ASN_PARSE_E;\n\n                if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0)\n                    ret = ASN_PARSE_E;\n            }\n            else {\n                /* check if SKID with ASN_CONTEXT_SPECIFIC otherwise in version\n                 * 3 try to get issuerAndSerial */\n                localIdx = idx;\n                if (GetASNTag(in, &localIdx, &tag, inSz) == 0 &&\n                        tag == ASN_CONTEXT_SPECIFIC) {\n                    idx++;\n                    if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0)\n                        ret = ASN_PARSE_E;\n                }\n                else {\n                    if (pkcs7->version != 3) {\n                        WOLFSSL_MSG(\"Unexpected signer info found with version\");\n                        ret = ASN_PARSE_E;\n                    }\n\n                    if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0)\n                        ret = ASN_PARSE_E;\n                }\n            }\n\n            if (ret == 0) {\n                ret = wc_PKCS7_SignerInfoSetSID(pkcs7, in + idx, length);\n                idx += length;\n            }\n\n        } else {\n            WOLFSSL_MSG(\"PKCS#7 signerInfo version must be 1 or 3\");\n            ret = ASN_VERSION_E;\n        }\n\n        /* Get the sequence of digestAlgorithm */\n        if (ret == 0 && GetAlgoId(in, &idx, &hashOID, oidHashType, inSz) < 0) {\n            ret = ASN_PARSE_E;\n        }\n        pkcs7->hashOID = (int)hashOID;\n\n        /* Get the IMPLICIT[0] SET OF signedAttributes */\n        localIdx = idx;\n        if (ret == 0 && GetASNTag(in, &localIdx, &tag, inSz) == 0 &&\n                tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {\n            idx++;\n\n            if (GetLength(in, &idx, &length, inSz) < 0)\n                ret = ASN_PARSE_E;\n\n            /* save pointer and length */\n            *signedAttrib = &in[idx];\n            *signedAttribSz = length;\n\n            if (ret == 0 && wc_PKCS7_ParseAttribs(pkcs7, *signedAttrib,\n                        *signedAttribSz) < 0) {\n                WOLFSSL_MSG(\"Error parsing signed attributes\");\n                ret = ASN_PARSE_E;\n            }\n\n            idx += length;\n        }\n\n        /* Get digestEncryptionAlgorithm */\n        if (ret == 0 && GetAlgoId(in, &idx, &sigOID, oidSigType, inSz) < 0) {\n            ret = ASN_PARSE_E;\n        }\n\n        /* store public key type based on digestEncryptionAlgorithm */\n        if (ret == 0) {\n            ret = wc_PKCS7_SetPublicKeyOID(pkcs7, sigOID);\n            if (ret < 0) {\n                WOLFSSL_MSG(\"Failed to set public key OID from signature\");\n            }\n            else {\n                /* if previous return was positive then was success */\n                ret = 0;\n            }\n        }\n    }\n\n    /* update index on success */\n    if (ret == 0) {\n        *idxIn = idx;\n    }\n\n    return ret;\n}\n\n\n/* Finds the certificates in the message and saves it. By default allows\n * degenerate cases which can have no signer.\n *\n * By default expects type SIGNED_DATA (SignedData) which can have any number of\n * elements in signerInfos collection, including zero. (RFC2315 section 9.1)\n * When adding support for the case of SignedAndEnvelopedData content types a\n * signer is required. In this case the PKCS7 flag noDegenerate could be set.\n */\nstatic int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,\n    word32 hashSz, byte* in, word32 inSz,\n    byte* in2, word32 in2Sz)\n{\n    word32 idx, maxIdx = inSz, outerContentType, contentTypeSz = 0, totalSz = 0;\n    int length = 0, version = 0, ret = 0;\n    byte* content = NULL;\n    byte* contentDynamic = NULL;\n    byte* sig = NULL;\n    byte* cert = NULL;\n    byte* signedAttrib = NULL;\n    byte* contentType = NULL;\n    int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0;\n    word32 localIdx, start;\n    byte degenerate = 0;\n    byte detached = 0;\n    byte tag = 0;\n#ifdef ASN_BER_TO_DER\n    byte* der;\n#endif\n    int multiPart = 0, keepContent;\n    int contentLen = 0;\n\n    byte* pkiMsg    = in;\n    word32 pkiMsgSz = inSz;\n#ifndef NO_PKCS7_STREAM\n    word32 stateIdx = 0;\n    long rc;\n#endif\n\n    byte* pkiMsg2 = in2;\n    word32 pkiMsg2Sz = in2Sz;\n\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n#ifndef NO_PKCS7_STREAM\n    /* allow for 0 size inputs with stream mode */\n    if (pkcs7 == NULL || (pkiMsg == NULL && pkiMsgSz > 0))\n        return BAD_FUNC_ARG;\n\n#else\n    if (pkiMsg == NULL || pkiMsgSz == 0)\n        return BAD_FUNC_ARG;\n\n#endif\n\n    if ((hashSz > 0 && hashBuf == NULL) || (pkiMsg2Sz > 0 && pkiMsg2 == NULL)) {\n        return BAD_FUNC_ARG;\n    }\n    idx = 0;\n\n#ifdef ASN_BER_TO_DER\n    if (pkcs7->derSz > 0 && pkcs7->der) {\n        pkiMsg = in = pkcs7->der;\n    }\n#endif\n\n#ifndef NO_PKCS7_STREAM\n    if (pkcs7->stream == NULL) {\n        if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {\n            return ret;\n        }\n    }\n#endif\n\n    switch (pkcs7->state) {\n        case WC_PKCS7_START:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +\n                            MAX_VERSION_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ +\n                            ASN_TAG_SZ + MAX_OID_SZ + MAX_SEQ_SZ,\n                            &pkiMsg, &idx)) != 0) {\n                break;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK, in, inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length :inSz;\n        #endif\n\n            /* determine total message size */\n            totalSz = pkiMsgSz;\n            if (pkiMsg2 && pkiMsg2Sz > 0) {\n                totalSz += pkiMsg2Sz + pkcs7->contentSz;\n            }\n\n            /* Get the contentInfo sequence */\n            if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, totalSz,\n                        NO_USER_CHECK) < 0)\n                ret = ASN_PARSE_E;\n\n            if (ret == 0 && length == 0 && pkiMsg[idx-1] == 0x80) {\n        #ifdef ASN_BER_TO_DER\n                word32 len = 0;\n\n                ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len);\n                if (ret != LENGTH_ONLY_E)\n                    return ret;\n                pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                if (pkcs7->der == NULL)\n                    return MEMORY_E;\n                ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len);\n                if (ret < 0)\n                    return ret;\n\n                pkiMsg   = in = pkcs7->der;\n                pkiMsgSz = pkcs7->derSz = len;\n                idx = 0;\n                if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,\n                            NO_USER_CHECK) < 0)\n                    return ASN_PARSE_E;\n\n            #ifndef NO_PKCS7_STREAM\n                rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK,\n                    pkiMsg, pkiMsgSz);\n                if (rc < 0) {\n                    ret = (int)rc;\n                    break;\n                }\n            #endif\n        #else\n                ret = BER_INDEF_E;\n        #endif\n            }\n\n            /* Get the contentInfo contentType */\n            if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &outerContentType,\n                        pkiMsgSz) < 0)\n                ret = ASN_PARSE_E;\n\n            if (ret == 0 && outerContentType != SIGNED_DATA) {\n                WOLFSSL_MSG(\"PKCS#7 input not of type SignedData\");\n                ret = PKCS7_OID_E;\n            }\n\n            /* get the ContentInfo content */\n            if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, totalSz) != 0)\n                ret = ASN_PARSE_E;\n\n            if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))\n                ret = ASN_PARSE_E;\n\n            if (ret == 0 && GetLength_ex(pkiMsg, &idx, &length, totalSz,\n                        NO_USER_CHECK) < 0)\n                ret = ASN_PARSE_E;\n\n            /* Get the signedData sequence */\n            if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, totalSz,\n                        NO_USER_CHECK) < 0)\n                ret = ASN_PARSE_E;\n\n            /* Get the version */\n            if (ret == 0 && GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)\n                ret = ASN_PARSE_E;\n\n\n            /* version 1 follows RFC 2315 */\n            /* version 3 follows RFC 4108 */\n            if (ret == 0 && (version != 1 && version != 3)) {\n                WOLFSSL_MSG(\"PKCS#7 signedData needs to be version 1 or 3\");\n                ret = ASN_VERSION_E;\n            }\n            pkcs7->version = version;\n\n            /* Get the set of DigestAlgorithmIdentifiers */\n            if (ret == 0 && GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)\n                ret = ASN_PARSE_E;\n\n            /* Skip the set. */\n            idx += length;\n            degenerate = (length == 0)? 1 : 0;\n            if (pkcs7->noDegenerate == 1 && degenerate == 1) {\n                ret = PKCS7_NO_SIGNER_E;\n            }\n\n            if (ret != 0)\n                break;\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {\n                break;\n            }\n            if (pkiMsg2 && pkiMsg2Sz > 0) {\n                pkcs7->stream->maxLen += pkiMsg2Sz + pkcs7->contentSz;\n            }\n            wc_PKCS7_StreamStoreVar(pkcs7, totalSz, 0, 0);\n        #endif\n\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE2);\n            FALL_THROUGH;\n\n        case WC_PKCS7_VERIFY_STAGE2:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,\n                           MAX_SEQ_SZ + MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ\n                           + ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {\n                break;\n            }\n\n            wc_PKCS7_StreamGetVar(pkcs7, &totalSz, 0, 0);\n            if (pkcs7->stream->length > 0)\n                pkiMsgSz = pkcs7->stream->length;\n        #ifdef ASN_BER_TO_DER\n            else if (pkcs7->der)\n                pkiMsgSz = pkcs7->derSz;\n        #endif\n            else\n                pkiMsgSz = inSz;\n\n        #endif\n            /* Get the inner ContentInfo sequence */\n            if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,\n                        NO_USER_CHECK) < 0)\n                ret = ASN_PARSE_E;\n\n            /* Get the inner ContentInfo contentType */\n            if (ret == 0) {\n                word32 tmpIdx = idx;\n\n                if (GetASNObjectId(pkiMsg, &idx, &length, pkiMsgSz) != 0)\n                    ret = ASN_PARSE_E;\n\n                contentType = pkiMsg + tmpIdx;\n                contentTypeSz = length + (idx - tmpIdx);\n\n                idx += length;\n            }\n\n            if (ret != 0)\n                break;\n\n            /* Check for content info, it could be omitted when degenerate */\n            localIdx = idx;\n            ret = 0;\n            if (localIdx + 1 > pkiMsgSz) {\n                ret = BUFFER_E;\n                break;\n            }\n\n            if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) != 0)\n                ret = ASN_PARSE_E;\n\n            if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))\n                ret = ASN_PARSE_E;\n\n            if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length, pkiMsgSz,\n                        NO_USER_CHECK) <= 0)\n                ret = ASN_PARSE_E;\n\n            if (localIdx >= pkiMsgSz) {\n                ret = BUFFER_E;\n            }\n\n            /* get length of content in the case that there is multiple parts */\n            if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)\n                ret = ASN_PARSE_E;\n\n            if (ret == 0 && tag == (ASN_OCTET_STRING | ASN_CONSTRUCTED)) {\n                multiPart = 1;\n\n                /* Get length of all OCTET_STRINGs. */\n                if (GetLength_ex(pkiMsg, &localIdx, &contentLen, pkiMsgSz,\n                            NO_USER_CHECK) < 0)\n                    ret = ASN_PARSE_E;\n\n                /* Check whether there is one OCTET_STRING inside. */\n                start = localIdx;\n                if (localIdx >= pkiMsgSz) {\n                    ret = BUFFER_E;\n                }\n\n                if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz)\n                        != 0)\n                    ret = ASN_PARSE_E;\n\n                if (ret == 0 && tag != ASN_OCTET_STRING)\n                    ret = ASN_PARSE_E;\n\n                if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length, pkiMsgSz,\n                            NO_USER_CHECK) < 0)\n                    ret = ASN_PARSE_E;\n\n                if (ret == 0) {\n                    /* Use single OCTET_STRING directly. */\n                    if (localIdx - start + length == (word32)contentLen)\n                        multiPart = 0;\n                    localIdx = start;\n                }\n            }\n\n            /* get length of content in case of single part */\n            if (ret == 0 && !multiPart) {\n                if (ret == 0 && tag != ASN_OCTET_STRING)\n                    ret = ASN_PARSE_E;\n\n                if (ret == 0 && GetLength_ex(pkiMsg, &localIdx,\n                            &length, pkiMsgSz, NO_USER_CHECK) < 0)\n                    ret = ASN_PARSE_E;\n            }\n\n            /* update idx if successful */\n            if (ret == 0) {\n                /* support using header and footer without content */\n                if (pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0) {\n                    localIdx = 0;\n                }\n                idx = localIdx;\n            }\n            else {\n\n                /* if pkcs7->content and pkcs7->contentSz are set, try to\n                   process as a detached signature */\n                if (!degenerate &&\n                    (pkcs7->content != NULL && pkcs7->contentSz != 0)) {\n                    detached = 1;\n                }\n\n                if (!degenerate && !detached && ret != 0)\n                    break;\n\n                length = 0; /* no content to read */\n                pkiMsg2   = pkiMsg;\n                pkiMsg2Sz = pkiMsgSz;\n            }\n\n        #ifndef NO_PKCS7_STREAM\n            /* save detached flag value */\n            pkcs7->stream->detached = detached;\n\n            /* save contentType */\n            pkcs7->stream->nonce = (byte*)XMALLOC(contentTypeSz, pkcs7->heap,\n                    DYNAMIC_TYPE_PKCS7);\n            if (pkcs7->stream->nonce == NULL) {\n                ret = MEMORY_E;\n                break;\n            }\n            else {\n                pkcs7->stream->nonceSz = contentTypeSz;\n                XMEMCPY(pkcs7->stream->nonce, contentType, contentTypeSz);\n            }\n\n            /* content expected? */\n            if ((ret == 0 && length > 0) &&\n                !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0)) {\n                pkcs7->stream->expected = length + ASN_TAG_SZ + MAX_LENGTH_SZ;\n            }\n            else {\n                pkcs7->stream->expected = ASN_TAG_SZ + MAX_LENGTH_SZ;\n            }\n\n            if (pkcs7->stream->expected > (pkcs7->stream->maxLen - idx)) {\n                pkcs7->stream->expected = pkcs7->stream->maxLen - idx;\n            }\n\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {\n                break;\n            }\n            wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, localIdx, length);\n\n            /* content length is in multiple parts */\n            if (multiPart) {\n                pkcs7->stream->expected = contentLen + ASN_TAG_SZ;\n            }\n            pkcs7->stream->multi = multiPart;\n\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE3);\n            FALL_THROUGH;\n\n        case WC_PKCS7_VERIFY_STAGE3:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,\n                            pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {\n                break;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,\n                    pkiMsg, pkiMsgSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n        #ifdef ASN_BER_TO_DER\n            if (pkcs7->derSz != 0)\n                pkiMsgSz = pkcs7->derSz;\n            else\n        #endif\n                pkiMsgSz = (word32)rc;\n            wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, (int*)&localIdx, &length);\n\n            if (pkcs7->stream->length > 0) {\n                localIdx = 0;\n            }\n            multiPart = pkcs7->stream->multi;\n            detached  = pkcs7->stream->detached;\n            maxIdx = idx + pkcs7->stream->expected;\n        #endif\n\n            /* Break out before content because it can be optional in degenerate\n             * cases. */\n            if (ret != 0 && !degenerate)\n                break;\n\n            /* get parts of content */\n            if (ret == 0 && multiPart) {\n                int i = 0;\n                keepContent = !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0);\n\n                if (keepContent) {\n                    /* Create a buffer to hold content of OCTET_STRINGs. */\n                    pkcs7->contentDynamic = (byte*)XMALLOC(contentLen, pkcs7->heap,\n                                                            DYNAMIC_TYPE_PKCS7);\n                    if (pkcs7->contentDynamic == NULL)\n                        ret = MEMORY_E;\n                }\n\n                start = localIdx;\n                /* Use the data from each OCTET_STRING. */\n                while (ret == 0 && localIdx < start + contentLen) {\n                    if (GetASNTag(pkiMsg, &localIdx, &tag, totalSz) < 0)\n                        ret = ASN_PARSE_E;\n                    if (ret == 0 && tag != ASN_OCTET_STRING)\n                        ret = ASN_PARSE_E;\n\n                    if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) < 0)\n                        ret = ASN_PARSE_E;\n                    if (ret == 0 && length + localIdx > start + contentLen)\n                        ret = ASN_PARSE_E;\n\n                    if (ret == 0) {\n                        if (keepContent) {\n                            XMEMCPY(pkcs7->contentDynamic + i, pkiMsg + localIdx,\n                                                                        length);\n                        }\n                        i += length;\n                        localIdx += length;\n                    }\n                }\n                localIdx = start; /* reset for sanity check, increment later */\n                length = i;\n            }\n\n            /* Save the inner data as the content. */\n            if (ret == 0 && length > 0) {\n                contentSz = length;\n\n                /* support using header and footer without content */\n                if (pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0) {\n                    /* Content not provided, use provided pkiMsg2 footer */\n                    content = NULL;\n                    localIdx = 0;\n                    if (contentSz != (int)pkcs7->contentSz) {\n                        WOLFSSL_MSG(\"Data signed does not match contentSz provided\");\n                        ret = BUFFER_E;\n                    }\n                }\n                else {\n                    if ((word32)length > pkiMsgSz - localIdx) {\n                        ret = BUFFER_E;\n                    }\n\n                    /* Content pointer for calculating hashes later */\n                    if (ret == 0 && !multiPart) {\n                        content = &pkiMsg[localIdx];\n                    }\n                    if (ret == 0 && multiPart) {\n                        content = pkcs7->contentDynamic;\n                    }\n\n                    if (ret == 0) {\n                        idx += length;\n\n                        pkiMsg2   = pkiMsg;\n                        pkiMsg2Sz = pkiMsgSz;\n                    #ifndef NO_PKCS7_STREAM\n                        pkcs7->stream->varOne = pkiMsg2Sz;\n                        pkcs7->stream->flagOne = 1;\n                    #endif\n                    }\n                }\n            }\n            else {\n                pkiMsg2 = pkiMsg;\n                pkiMsg2Sz = pkiMsgSz;\n            #ifndef NO_PKCS7_STREAM\n                pkcs7->stream->varOne = pkiMsg2Sz;\n                pkcs7->stream->flagOne = 1;\n            #endif\n            }\n\n            /* If getting the content info failed with non degenerate then return the\n             * error case. Otherwise with a degenerate it is ok if the content\n             * info was omitted */\n            if (!degenerate && !detached && (ret != 0)) {\n                break;\n            }\n            else {\n                ret = 0; /* reset ret state on degenerate case */\n            }\n\n        #ifndef NO_PKCS7_STREAM\n            /* save content */\n            if (detached == 1) {\n                /* if detached, use content from user in pkcs7 struct */\n                content = pkcs7->content;\n                contentSz = pkcs7->contentSz;\n            }\n\n            if (content != NULL) {\n                XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                pkcs7->stream->content = (byte*)XMALLOC(contentSz, pkcs7->heap,\n                        DYNAMIC_TYPE_PKCS7);\n                if (pkcs7->stream->content == NULL) {\n                    ret = MEMORY_E;\n                    break;\n                }\n                else {\n                    XMEMCPY(pkcs7->stream->content, content, contentSz);\n                    pkcs7->stream->contentSz = contentSz;\n                }\n            }\n        #endif /* !NO_PKCS7_STREAM */\n\n            /* Get the implicit[0] set of certificates */\n            if (ret == 0 && idx >= pkiMsg2Sz)\n                ret = BUFFER_E;\n\n            length = 0; /* set length to 0 to check if reading in any certs */\n            localIdx = idx;\n            if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag, pkiMsg2Sz) == 0\n                    && tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {\n                idx++;\n                if (GetLength_ex(pkiMsg2, &idx, &length, maxIdx, NO_USER_CHECK)\n                        < 0)\n                    ret = ASN_PARSE_E;\n            }\n\n            if (ret != 0) {\n                break;\n            }\n        #ifndef NO_PKCS7_STREAM\n            if (in2 && in2Sz > 0 && hashBuf && hashSz > 0) {\n                stateIdx = idx; /* case where all data was read from in2 */\n            }\n\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {\n                break;\n            }\n            wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);\n            if (length > 0) {\n                pkcs7->stream->expected = length;\n            }\n            else {\n                pkcs7->stream->expected = MAX_SEQ_SZ;\n                if (pkcs7->stream->expected > (pkcs7->stream->maxLen -\n                                pkcs7->stream->totalRd) + pkcs7->stream->length) {\n                    pkcs7->stream->expected = (pkcs7->stream->maxLen -\n                                pkcs7->stream->totalRd) + pkcs7->stream->length;\n                }\n            }\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE4);\n            FALL_THROUGH;\n\n        case WC_PKCS7_VERIFY_STAGE4:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,\n                            pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {\n                break;\n            }\n\n            wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);\n            if (pkcs7->stream->flagOne) {\n                pkiMsg2 = pkiMsg;\n            }\n\n            /* restore content */\n            content   = pkcs7->stream->content;\n            contentSz = pkcs7->stream->contentSz;\n\n            /* restore detached flag */\n            detached = pkcs7->stream->detached;\n\n            /* store certificate if needed */\n            if (length > 0 && in2Sz == 0) {\n                /* free tmpCert if not NULL */\n                XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                pkcs7->stream->tmpCert = (byte*)XMALLOC(length,\n                        pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                if ((pkiMsg2 == NULL) || (pkcs7->stream->tmpCert == NULL)) {\n                    ret = MEMORY_E;\n                    break;\n                }\n                XMEMCPY(pkcs7->stream->tmpCert, pkiMsg2 + idx, length);\n                pkiMsg2 = pkcs7->stream->tmpCert;\n                pkiMsg2Sz = length;\n                idx = 0;\n            }\n        #endif\n\n                if (length > 0) {\n                    /* At this point, idx is at the first certificate in\n                     * a set of certificates. There may be more than one,\n                     * or none, or they may be a PKCS 6 extended\n                     * certificate. We want to save the first cert if it\n                     * is X.509. */\n\n                    word32 certIdx = idx;\n\n                    if (length < MAX_LENGTH_SZ + ASN_TAG_SZ)\n                        ret = BUFFER_E;\n\n                    if (ret == 0)\n                        ret = GetASNTag(pkiMsg2, &certIdx, &tag, pkiMsg2Sz);\n\n                    if (ret == 0 && tag == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {\n                        if (GetLength(pkiMsg2, &certIdx, &certSz, pkiMsg2Sz) < 0)\n                            ret = ASN_PARSE_E;\n\n                        cert = &pkiMsg2[idx];\n                        certSz += (certIdx - idx);\n                        if (certSz > length) {\n                            ret = BUFFER_E;\n                            break;\n                        }\n                    }\n        #ifdef ASN_BER_TO_DER\n                    der = pkcs7->der;\n        #endif\n                    contentDynamic = pkcs7->contentDynamic;\n                    version = pkcs7->version;\n\n\n                    if (ret == 0) {\n                    #ifndef NO_PKCS7_STREAM\n                        PKCS7State* stream = pkcs7->stream;\n                    #endif\n                        /* This will reset PKCS7 structure and then set the\n                         * certificate */\n                        ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz);\n                    #ifndef NO_PKCS7_STREAM\n                        pkcs7->stream = stream;\n                    #endif\n                    }\n                    pkcs7->contentDynamic = contentDynamic;\n                    pkcs7->version = version;\n        #ifdef ASN_BER_TO_DER\n                    pkcs7->der = der;\n        #endif\n                    if (ret != 0)\n                        break;\n\n                    /* iterate through any additional certificates */\n                    if (ret == 0 && MAX_PKCS7_CERTS > 0) {\n                        int sz = 0;\n                        int i;\n\n                        pkcs7->cert[0]   = cert;\n                        pkcs7->certSz[0] = certSz;\n                        certIdx = idx + certSz;\n\n                        for (i = 1; i < MAX_PKCS7_CERTS &&\n                                certIdx + 1 < pkiMsg2Sz &&\n                                certIdx + 1 < (word32)length; i++) {\n                            localIdx = certIdx;\n\n                            if (ret == 0 && GetASNTag(pkiMsg2, &certIdx, &tag,\n                                        pkiMsg2Sz) < 0) {\n                                ret = ASN_PARSE_E;\n                                break;\n                            }\n\n                            if (ret == 0 &&\n                                    tag == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {\n                                if (GetLength(pkiMsg2, &certIdx, &sz,\n                                            pkiMsg2Sz) < 0) {\n                                    ret = ASN_PARSE_E;\n                                    break;\n                                }\n\n                                pkcs7->cert[i]   = &pkiMsg2[localIdx];\n                                pkcs7->certSz[i] = sz + (certIdx - localIdx);\n                                certIdx += sz;\n                            }\n                        }\n                    }\n                }\n                idx += length;\n\n            if (!detached) {\n                /* set content and size after init of PKCS7 structure */\n                pkcs7->content   = content;\n                pkcs7->contentSz = contentSz;\n            }\n        #ifndef NO_PKCS7_STREAM\n            else {\n                /* save content if detached and using streaming API */\n                if (pkcs7->content != NULL) {\n                    XFREE(pkcs7->stream->content, pkcs7->heap,\n                          DYNAMIC_TYPE_PKCS7);\n                    pkcs7->stream->content = (byte*)XMALLOC(pkcs7->contentSz,\n                                                            pkcs7->heap,\n                                                            DYNAMIC_TYPE_PKCS7);\n                    if (pkcs7->stream->content == NULL) {\n                        ret = MEMORY_E;\n                        break;\n                    }\n                    else {\n                        XMEMCPY(pkcs7->stream->content, pkcs7->content,\n                                contentSz);\n                        pkcs7->stream->contentSz = pkcs7->contentSz;\n                    }\n                }\n            }\n        #endif\n\n            if (ret != 0) {\n                break;\n            }\n        #ifndef NO_PKCS7_STREAM\n            /* factor in that recent idx was in cert buffer. If in2 buffer was\n             * used then don't advance idx. */\n            if (length > 0 && pkcs7->stream->flagOne &&\n                    pkcs7->stream->length == 0) {\n                idx = stateIdx + idx;\n                if (idx > inSz) {\n                    /* index is more than input size */\n                    ret = BUFFER_E;\n                    break;\n                }\n            }\n            else {\n                stateIdx = idx; /* didn't read any from internal buffer */\n            }\n\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {\n                break;\n            }\n            if (pkcs7->stream->flagOne && pkcs7->stream->length > 0) {\n                idx = stateIdx + idx;\n            }\n\n            pkcs7->stream->expected = MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ +\n                                      MAX_SET_SZ;\n\n            if (pkcs7->stream->expected > (pkcs7->stream->maxLen -\n                                pkcs7->stream->totalRd) + pkcs7->stream->length)\n                pkcs7->stream->expected = (pkcs7->stream->maxLen -\n                                pkcs7->stream->totalRd) + pkcs7->stream->length;\n\n            wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz,  0, 0);\n            wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE5);\n            FALL_THROUGH;\n\n        case WC_PKCS7_VERIFY_STAGE5:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,\n                            pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {\n                break;\n            }\n            wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);\n            if (pkcs7->stream->flagOne) {\n                pkiMsg2 = pkiMsg;\n            }\n\n            /* restore content type */\n            contentType   = pkcs7->stream->nonce;\n            contentTypeSz = pkcs7->stream->nonceSz;\n\n            maxIdx = idx + pkcs7->stream->expected;\n            if (maxIdx > pkiMsg2Sz) {\n                ret = BUFFER_E;\n                break;\n            }\n            stateIdx = idx;\n        #endif\n\n            /* set contentType and size after init of PKCS7 structure */\n            if (ret == 0 && wc_PKCS7_SetContentType(pkcs7, contentType,\n                        contentTypeSz) < 0)\n                ret = ASN_PARSE_E;\n\n            /* Get the implicit[1] set of crls */\n            if (ret == 0 && idx >= maxIdx)\n                ret = BUFFER_E;\n\n            localIdx = idx;\n            if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag, pkiMsg2Sz) == 0\n                    && tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {\n                idx++;\n                if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)\n                    ret = ASN_PARSE_E;\n\n                /* Skip the set */\n                idx += length;\n            }\n\n            /* Get the set of signerInfos */\n            if (ret == 0 && GetSet_ex(pkiMsg2, &idx, &length, maxIdx,\n                        NO_USER_CHECK) < 0)\n                ret = ASN_PARSE_E;\n\n            if (ret != 0)\n                break;\n        #ifndef NO_PKCS7_STREAM\n            if (!pkcs7->stream->flagOne) {\n                stateIdx = idx; /* didn't read any from internal buffer */\n            }\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {\n                break;\n            }\n            wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);\n\n            if (in2 && in2Sz > 0 && hashBuf && hashSz > 0) {\n                if (length > 0) {\n                    pkcs7->stream->expected = length;\n                }\n                else {\n                    pkcs7->stream->expected = 0;\n                }\n            }\n            else {\n                /* last state expect the reset of the buffer */\n                pkcs7->stream->expected = (pkcs7->stream->maxLen -\n                    pkcs7->stream->totalRd) + pkcs7->stream->length;\n            }\n\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE6);\n            FALL_THROUGH;\n\n        case WC_PKCS7_VERIFY_STAGE6:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,\n                            pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {\n                break;\n            }\n\n            wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);\n            if (pkcs7->stream->flagOne) {\n                pkiMsg2 = pkiMsg;\n            }\n\n            /* restore content */\n            content   = pkcs7->stream->content;\n            contentSz = pkcs7->stream->contentSz;\n        #endif\n\n            ret = wc_PKCS7_ParseSignerInfo(pkcs7, pkiMsg2, pkiMsg2Sz, &idx,\n                    degenerate, &signedAttrib, &signedAttribSz);\n\n            /* parse out the signature if present and verify it */\n            if (ret == 0 && length > 0 && degenerate == 0) {\n                WOLFSSL_MSG(\"Parsing signature and verifying\");\n                if (idx >= pkiMsg2Sz)\n                    ret = BUFFER_E;\n\n                /* Get the signature */\n                localIdx = idx;\n                if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag,\n                            pkiMsg2Sz) == 0 && tag == ASN_OCTET_STRING) {\n                    idx++;\n\n                    if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)\n                        ret = ASN_PARSE_E;\n\n                    /* save pointer and length */\n                    sig = &pkiMsg2[idx];\n                    sigSz = length;\n\n                    idx += length;\n                }\n\n                pkcs7->content = content;\n                pkcs7->contentSz = contentSz;\n\n                if (ret == 0) {\n                    ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,\n                                                   signedAttrib, signedAttribSz,\n                                                   hashBuf, hashSz);\n                }\n            }\n\n            if (ret < 0)\n                break;\n\n            ret = 0; /* success */\n        #ifndef NO_PKCS7_STREAM\n            wc_PKCS7_ResetStream(pkcs7);\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);\n            break;\n\n        default:\n            WOLFSSL_MSG(\"PKCS7 Unknown verify state\");\n            ret = BAD_FUNC_ARG;\n    }\n\n    if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {\n    #ifndef NO_PKCS7_STREAM\n        wc_PKCS7_ResetStream(pkcs7);\n    #endif\n        wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);\n    }\n    return ret;\n}\n\n\n/* Gets a copy of the SID parsed from signerInfo. This can be called after\n * wc_PKCS7_VerifySignedData has been called. SID can be SKID in version 3 case\n * or issuerAndSerialNumber.\n *\n * return 0 on success and LENGTH_ONLY_E if just setting \"outSz\" for buffer\n *  length needed.\n */\nint wc_PKCS7_GetSignerSID(PKCS7* pkcs7, byte* out, word32* outSz)\n{\n    if (outSz == NULL || pkcs7 == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (pkcs7->signerInfo == NULL) {\n        WOLFSSL_MSG(\"Either the bundle had no signers or\"\n                \"wc_PKCS7_VerifySignedData needs called yet\");\n        return PKCS7_NO_SIGNER_E;\n    }\n\n    if (pkcs7->signerInfo->sidSz == 0) {\n        WOLFSSL_MSG(\"Bundle had no signer SID set\");\n        return PKCS7_NO_SIGNER_E;\n    }\n\n    if (out == NULL) {\n        *outSz = pkcs7->signerInfo->sidSz;\n        return LENGTH_ONLY_E;\n    }\n\n    if (*outSz < pkcs7->signerInfo->sidSz) {\n        WOLFSSL_MSG(\"Buffer being passed in is not large enough for SKID\");\n        return BUFFER_E;\n    }\n    XMEMCPY(out, pkcs7->signerInfo->sid, pkcs7->signerInfo->sidSz);\n    *outSz = pkcs7->signerInfo->sidSz;\n    return 0;\n}\n\n\n/* variant that allows computed data hash and header/foot,\n * which is useful for large data signing */\nint wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf,\n    word32 hashSz, byte* pkiMsgHead, word32 pkiMsgHeadSz, byte* pkiMsgFoot,\n    word32 pkiMsgFootSz)\n{\n    return PKCS7_VerifySignedData(pkcs7, hashBuf, hashSz,\n        pkiMsgHead, pkiMsgHeadSz, pkiMsgFoot, pkiMsgFootSz);\n}\n\nint wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)\n{\n    return PKCS7_VerifySignedData(pkcs7, NULL, 0, pkiMsg, pkiMsgSz, NULL, 0);\n}\n\n\n/* Generate random content encryption key, store into pkcs7->cek and\n * pkcs7->cekSz.\n *\n * pkcs7 - pointer to initialized PKCS7 structure\n * len   - length of key to be generated\n *\n * Returns 0 on success, negative upon error */\nstatic int PKCS7_GenerateContentEncryptionKey(PKCS7* pkcs7, word32 len)\n{\n    int ret;\n    WC_RNG rng;\n    byte* tmpKey;\n\n    if (pkcs7 == NULL || len == 0)\n        return BAD_FUNC_ARG;\n\n    /* if key already exists, don't need to re-generate */\n    if (pkcs7->cek != NULL && pkcs7->cekSz != 0) {\n\n        /* if key exists, but is different size, return error */\n        if (pkcs7->cekSz != len) {\n            WOLFSSL_MSG(\"Random content-encryption key size is inconsistent \"\n                        \"between CMS recipients\");\n            return WC_KEY_SIZE_E;\n        }\n\n        return 0;\n    }\n\n    /* allocate space for cek */\n    tmpKey = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (tmpKey == NULL)\n        return MEMORY_E;\n\n    XMEMSET(tmpKey, 0, len);\n\n    ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);\n    if (ret != 0) {\n        XFREE(tmpKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    ret = wc_RNG_GenerateBlock(&rng, tmpKey, len);\n    if (ret != 0) {\n        wc_FreeRng(&rng);\n        XFREE(tmpKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    /* store into PKCS7, memory freed during final cleanup */\n    pkcs7->cek = tmpKey;\n    pkcs7->cekSz = len;\n\n    wc_FreeRng(&rng);\n\n    return 0;\n}\n\n\n/* wrap CEK (content encryption key) with KEK, 0 on success, < 0 on error */\nstatic int wc_PKCS7_KeyWrap(byte* cek, word32 cekSz, byte* kek,\n                            word32 kekSz, byte* out, word32 outSz,\n                            int keyWrapAlgo, int direction)\n{\n    int ret = 0;\n\n    if (cek == NULL || kek == NULL || out == NULL)\n        return BAD_FUNC_ARG;\n\n    switch (keyWrapAlgo) {\n#ifndef NO_AES\n    #ifdef WOLFSSL_AES_128\n        case AES128_WRAP:\n    #endif\n    #ifdef WOLFSSL_AES_192\n        case AES192_WRAP:\n    #endif\n    #ifdef WOLFSSL_AES_256\n        case AES256_WRAP:\n    #endif\n\n            if (direction == AES_ENCRYPTION) {\n\n                ret = wc_AesKeyWrap(kek, kekSz, cek, cekSz,\n                                    out, outSz, NULL);\n\n            } else if (direction == AES_DECRYPTION) {\n\n                ret = wc_AesKeyUnWrap(kek, kekSz, cek, cekSz,\n                                      out, outSz, NULL);\n            } else {\n                WOLFSSL_MSG(\"Bad key un/wrap direction\");\n                return BAD_FUNC_ARG;\n            }\n\n            if (ret <= 0)\n                return ret;\n            break;\n#endif /* NO_AES */\n\n        default:\n            WOLFSSL_MSG(\"Unsupported key wrap algorithm\");\n            return BAD_KEYWRAP_ALG_E;\n    };\n\n    (void)cekSz;\n    (void)kekSz;\n    (void)outSz;\n    (void)direction;\n    return ret;\n}\n\n\n#ifdef HAVE_ECC\n\n/* KARI == KeyAgreeRecipientInfo (key agreement) */\ntypedef struct WC_PKCS7_KARI {\n    DecodedCert* decoded;          /* decoded recip cert */\n    void*    heap;                 /* user heap, points to PKCS7->heap */\n    int      devId;                /* device ID for HW based private key */\n    ecc_key* recipKey;             /* recip key  (pub | priv) */\n    ecc_key* senderKey;            /* sender key (pub | priv) */\n    byte*    senderKeyExport;      /* sender ephemeral key DER */\n    byte*    kek;                  /* key encryption key */\n    byte*    ukm;                  /* OPTIONAL user keying material */\n    byte*    sharedInfo;           /* ECC-CMS-SharedInfo ASN.1 encoded blob */\n    word32   senderKeyExportSz;    /* size of sender ephemeral key DER */\n    word32   kekSz;                /* size of key encryption key */\n    word32   ukmSz;                /* size of user keying material */\n    word32   sharedInfoSz;         /* size of ECC-CMS-SharedInfo encoded */\n    byte     ukmOwner;             /* do we own ukm buffer? 1:yes, 0:no */\n    byte     direction;            /* WC_PKCS7_ENCODE | WC_PKCS7_DECODE */\n    byte     decodedInit : 1;      /* indicates decoded was initialized */\n    byte     recipKeyInit : 1;     /* indicates recipKey was initialized */\n    byte     senderKeyInit : 1;    /* indicates senderKey was initialized */\n} WC_PKCS7_KARI;\n\n\n/* allocate and create new WC_PKCS7_KARI struct,\n * returns struct pointer on success, NULL on failure */\nstatic WC_PKCS7_KARI* wc_PKCS7_KariNew(PKCS7* pkcs7, byte direction)\n{\n    WC_PKCS7_KARI* kari = NULL;\n\n    if (pkcs7 == NULL)\n        return NULL;\n\n    kari = (WC_PKCS7_KARI*)XMALLOC(sizeof(WC_PKCS7_KARI), pkcs7->heap,\n                                   DYNAMIC_TYPE_PKCS7);\n    if (kari == NULL) {\n        WOLFSSL_MSG(\"Failed to allocate WC_PKCS7_KARI\");\n        return NULL;\n    }\n\n    kari->decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,\n                                          DYNAMIC_TYPE_PKCS7);\n    if (kari->decoded == NULL) {\n        WOLFSSL_MSG(\"Failed to allocate DecodedCert\");\n        XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return NULL;\n    }\n\n    kari->recipKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,\n                                       DYNAMIC_TYPE_PKCS7);\n    if (kari->recipKey == NULL) {\n        WOLFSSL_MSG(\"Failed to allocate recipient ecc_key\");\n        XFREE(kari->decoded, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return NULL;\n    }\n\n    kari->senderKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,\n                                        DYNAMIC_TYPE_PKCS7);\n    if (kari->senderKey == NULL) {\n        WOLFSSL_MSG(\"Failed to allocate sender ecc_key\");\n        XFREE(kari->recipKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(kari->decoded, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return NULL;\n    }\n\n    kari->senderKeyExport = NULL;\n    kari->senderKeyExportSz = 0;\n    kari->kek = NULL;\n    kari->kekSz = 0;\n    kari->ukm = NULL;\n    kari->ukmSz = 0;\n    kari->ukmOwner = 0;\n    kari->sharedInfo = NULL;\n    kari->sharedInfoSz = 0;\n    kari->direction = direction;\n    kari->decodedInit = 0;\n    kari->recipKeyInit = 0;\n    kari->senderKeyInit = 0;\n\n    kari->heap = pkcs7->heap;\n    kari->devId = pkcs7->devId;\n\n    return kari;\n}\n\n\n/* free WC_PKCS7_KARI struct, return 0 on success */\nstatic int wc_PKCS7_KariFree(WC_PKCS7_KARI* kari)\n{\n    void* heap;\n\n    if (kari) {\n        heap = kari->heap;\n\n        if (kari->decoded) {\n            if (kari->decodedInit)\n                FreeDecodedCert(kari->decoded);\n            XFREE(kari->decoded, heap, DYNAMIC_TYPE_PKCS7);\n        }\n        if (kari->senderKey) {\n            if (kari->senderKeyInit)\n                wc_ecc_free(kari->senderKey);\n            XFREE(kari->senderKey, heap, DYNAMIC_TYPE_PKCS7);\n        }\n        if (kari->recipKey) {\n            if (kari->recipKeyInit)\n                wc_ecc_free(kari->recipKey);\n            XFREE(kari->recipKey, heap, DYNAMIC_TYPE_PKCS7);\n        }\n        if (kari->senderKeyExport) {\n            ForceZero(kari->senderKeyExport, kari->senderKeyExportSz);\n            XFREE(kari->senderKeyExport, heap, DYNAMIC_TYPE_PKCS7);\n            kari->senderKeyExportSz = 0;\n        }\n        if (kari->kek) {\n            ForceZero(kari->kek, kari->kekSz);\n            XFREE(kari->kek, heap, DYNAMIC_TYPE_PKCS7);\n            kari->kekSz = 0;\n        }\n        if (kari->ukm) {\n            if (kari->ukmOwner == 1) {\n                XFREE(kari->ukm, heap, DYNAMIC_TYPE_PKCS7);\n            }\n            kari->ukmSz = 0;\n        }\n        if (kari->sharedInfo) {\n            ForceZero(kari->sharedInfo, kari->sharedInfoSz);\n            XFREE(kari->sharedInfo, heap, DYNAMIC_TYPE_PKCS7);\n            kari->sharedInfoSz = 0;\n        }\n        XFREE(kari, heap, DYNAMIC_TYPE_PKCS7);\n    }\n\n    (void)heap;\n\n    return 0;\n}\n\n\n/* parse recipient cert/key, return 0 on success, negative on error\n * key/keySz only needed during decoding (WC_PKCS7_DECODE) */\nstatic int wc_PKCS7_KariParseRecipCert(WC_PKCS7_KARI* kari, const byte* cert,\n                                       word32 certSz, const byte* key,\n                                       word32 keySz)\n{\n    int ret;\n    word32 idx;\n\n    if (kari == NULL || kari->decoded == NULL ||\n        cert == NULL || certSz == 0)\n        return BAD_FUNC_ARG;\n\n    /* decode certificate */\n    InitDecodedCert(kari->decoded, (byte*)cert, certSz, kari->heap);\n    kari->decodedInit = 1;\n    ret = ParseCert(kari->decoded, CA_TYPE, NO_VERIFY, 0);\n    if (ret < 0)\n        return ret;\n\n    /* only supports ECDSA for now */\n    if (kari->decoded->keyOID != ECDSAk) {\n        WOLFSSL_MSG(\"CMS KARI only supports ECDSA key types\");\n        return BAD_FUNC_ARG;\n    }\n\n    /* make sure subject key id was read from cert */\n    if (kari->decoded->extSubjKeyIdSet == 0) {\n        WOLFSSL_MSG(\"Failed to read subject key ID from recipient cert\");\n        return BAD_FUNC_ARG;\n    }\n\n    ret = wc_ecc_init_ex(kari->recipKey, kari->heap, kari->devId);\n    if (ret != 0)\n        return ret;\n\n    kari->recipKeyInit = 1;\n\n    /* get recip public key */\n    if (kari->direction == WC_PKCS7_ENCODE) {\n\n        idx = 0;\n        ret = wc_EccPublicKeyDecode(kari->decoded->publicKey, &idx,\n                                    kari->recipKey, kari->decoded->pubKeySize);\n        if (ret != 0)\n            return ret;\n    }\n    /* get recip private key */\n    else if (kari->direction == WC_PKCS7_DECODE) {\n        if (key != NULL && keySz > 0) {\n            idx = 0;\n            ret = wc_EccPrivateKeyDecode(key, &idx, kari->recipKey, keySz);\n        }\n        else if (kari->devId == INVALID_DEVID) {\n            ret = BAD_FUNC_ARG;\n        }\n        if (ret != 0)\n            return ret;\n\n    } else {\n        /* bad direction */\n        return BAD_FUNC_ARG;\n    }\n\n    (void)idx;\n\n    return 0;\n}\n\n\n/* create ephemeral ECC key, places ecc_key in kari->senderKey,\n * DER encoded in kari->senderKeyExport. return 0 on success,\n * negative on error */\nstatic int wc_PKCS7_KariGenerateEphemeralKey(WC_PKCS7_KARI* kari)\n{\n    int ret;\n    WC_RNG rng;\n\n    if (kari == NULL || kari->decoded == NULL ||\n        kari->recipKey == NULL || kari->recipKey->dp == NULL)\n        return BAD_FUNC_ARG;\n\n    kari->senderKeyExport = (byte*)XMALLOC(kari->decoded->pubKeySize,\n                                           kari->heap, DYNAMIC_TYPE_PKCS7);\n    if (kari->senderKeyExport == NULL)\n        return MEMORY_E;\n\n    kari->senderKeyExportSz = kari->decoded->pubKeySize;\n\n    ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId);\n    if (ret != 0) {\n        XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    kari->senderKeyInit = 1;\n\n    ret = wc_InitRng_ex(&rng, kari->heap, kari->devId);\n    if (ret != 0) {\n        XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    ret = wc_ecc_make_key_ex(&rng, kari->recipKey->dp->size,\n                             kari->senderKey, kari->recipKey->dp->id);\n    if (ret != 0) {\n        XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);\n        wc_FreeRng(&rng);\n        return ret;\n    }\n\n    wc_FreeRng(&rng);\n\n    /* dump generated key to X.963 DER for output in CMS bundle */\n    ret = wc_ecc_export_x963(kari->senderKey, kari->senderKeyExport,\n                             &kari->senderKeyExportSz);\n    if (ret != 0) {\n        XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    return 0;\n}\n\n\n/* create ASN.1 encoded ECC-CMS-SharedInfo using specified key wrap algorithm,\n * place in kari->sharedInfo. returns 0 on success, negative on error */\nstatic int wc_PKCS7_KariGenerateSharedInfo(WC_PKCS7_KARI* kari, int keyWrapOID)\n{\n    int idx = 0;\n    int sharedInfoSeqSz = 0;\n    int keyInfoSz = 0;\n    int suppPubInfoSeqSz = 0;\n    int entityUInfoOctetSz = 0;\n    int entityUInfoExplicitSz = 0;\n    int kekOctetSz = 0;\n    int sharedInfoSz = 0;\n\n    word32 kekBitSz = 0;\n\n    byte sharedInfoSeq[MAX_SEQ_SZ];\n    byte keyInfo[MAX_ALGO_SZ];\n    byte suppPubInfoSeq[MAX_SEQ_SZ];\n    byte entityUInfoOctet[MAX_OCTET_STR_SZ];\n    byte entityUInfoExplicitSeq[MAX_SEQ_SZ];\n    byte kekOctet[MAX_OCTET_STR_SZ];\n\n    if (kari == NULL)\n        return BAD_FUNC_ARG;\n\n    if ((kari->ukmSz > 0) && (kari->ukm == NULL))\n        return BAD_FUNC_ARG;\n\n    /* kekOctet */\n    kekOctetSz = SetOctetString(sizeof(word32), kekOctet);\n    sharedInfoSz += (kekOctetSz + sizeof(word32));\n\n    /* suppPubInfo */\n    suppPubInfoSeqSz = SetImplicit(ASN_SEQUENCE, 2,\n                                   kekOctetSz + sizeof(word32),\n                                   suppPubInfoSeq);\n    sharedInfoSz += suppPubInfoSeqSz;\n\n    /* optional ukm/entityInfo */\n    if (kari->ukmSz > 0) {\n        entityUInfoOctetSz = SetOctetString(kari->ukmSz, entityUInfoOctet);\n        sharedInfoSz += (entityUInfoOctetSz + kari->ukmSz);\n\n        entityUInfoExplicitSz = SetExplicit(0, entityUInfoOctetSz +\n                                            kari->ukmSz,\n                                            entityUInfoExplicitSeq);\n        sharedInfoSz += entityUInfoExplicitSz;\n    }\n\n    /* keyInfo */\n    keyInfoSz = SetAlgoID(keyWrapOID, keyInfo, oidKeyWrapType, 0);\n    sharedInfoSz += keyInfoSz;\n\n    /* sharedInfo */\n    sharedInfoSeqSz = SetSequence(sharedInfoSz, sharedInfoSeq);\n    sharedInfoSz += sharedInfoSeqSz;\n\n    kari->sharedInfo = (byte*)XMALLOC(sharedInfoSz, kari->heap,\n                                      DYNAMIC_TYPE_PKCS7);\n    if (kari->sharedInfo == NULL)\n        return MEMORY_E;\n\n    kari->sharedInfoSz = sharedInfoSz;\n\n    XMEMCPY(kari->sharedInfo + idx, sharedInfoSeq, sharedInfoSeqSz);\n    idx += sharedInfoSeqSz;\n    XMEMCPY(kari->sharedInfo + idx, keyInfo, keyInfoSz);\n    idx += keyInfoSz;\n    if (kari->ukmSz > 0) {\n        XMEMCPY(kari->sharedInfo + idx, entityUInfoExplicitSeq,\n                entityUInfoExplicitSz);\n        idx += entityUInfoExplicitSz;\n        XMEMCPY(kari->sharedInfo + idx, entityUInfoOctet, entityUInfoOctetSz);\n        idx += entityUInfoOctetSz;\n        XMEMCPY(kari->sharedInfo + idx, kari->ukm, kari->ukmSz);\n        idx += kari->ukmSz;\n    }\n    XMEMCPY(kari->sharedInfo + idx, suppPubInfoSeq, suppPubInfoSeqSz);\n    idx += suppPubInfoSeqSz;\n    XMEMCPY(kari->sharedInfo + idx, kekOctet, kekOctetSz);\n    idx += kekOctetSz;\n\n    kekBitSz = (kari->kekSz) * 8;              /* convert to bits */\n#ifdef LITTLE_ENDIAN_ORDER\n    kekBitSz = ByteReverseWord32(kekBitSz);    /* network byte order */\n#endif\n    XMEMCPY(kari->sharedInfo + idx, &kekBitSz, sizeof(kekBitSz));\n\n    return 0;\n}\n\n\n/* create key encryption key (KEK) using key wrap algorithm and key encryption\n * algorithm, place in kari->kek. return 0 on success, <0 on error. */\nstatic int wc_PKCS7_KariGenerateKEK(WC_PKCS7_KARI* kari,\n                                    int keyWrapOID, int keyEncOID)\n{\n    int ret;\n    int kSz;\n    enum wc_HashType kdfType;\n    byte*  secret;\n    word32 secretSz;\n\n    if (kari == NULL || kari->recipKey == NULL ||\n        kari->senderKey == NULL || kari->senderKey->dp == NULL)\n        return BAD_FUNC_ARG;\n\n    /* get KEK size, allocate buff */\n    kSz = wc_PKCS7_GetOIDKeySize(keyWrapOID);\n    if (kSz < 0)\n        return kSz;\n\n    kari->kek = (byte*)XMALLOC(kSz, kari->heap, DYNAMIC_TYPE_PKCS7);\n    if (kari->kek == NULL)\n        return MEMORY_E;\n\n    kari->kekSz = (word32)kSz;\n\n    /* generate ECC-CMS-SharedInfo */\n    ret = wc_PKCS7_KariGenerateSharedInfo(kari, keyWrapOID);\n    if (ret != 0)\n        return ret;\n\n    /* generate shared secret */\n    secretSz = kari->senderKey->dp->size;\n    secret = (byte*)XMALLOC(secretSz, kari->heap, DYNAMIC_TYPE_PKCS7);\n    if (secret == NULL)\n        return MEMORY_E;\n\n    if (kari->direction == WC_PKCS7_ENCODE) {\n\n        ret = wc_ecc_shared_secret(kari->senderKey, kari->recipKey,\n                                   secret, &secretSz);\n\n    } else if (kari->direction == WC_PKCS7_DECODE) {\n\n        ret = wc_ecc_shared_secret(kari->recipKey, kari->senderKey,\n                                   secret, &secretSz);\n\n    } else {\n        /* bad direction */\n        XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);\n        return BAD_FUNC_ARG;\n    }\n\n    if (ret != 0) {\n        XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    /* run through KDF */\n    switch (keyEncOID) {\n\n    #ifndef NO_SHA\n        case dhSinglePass_stdDH_sha1kdf_scheme:\n            kdfType = WC_HASH_TYPE_SHA;\n            break;\n    #endif\n    #ifndef WOLFSSL_SHA224\n        case dhSinglePass_stdDH_sha224kdf_scheme:\n            kdfType = WC_HASH_TYPE_SHA224;\n            break;\n    #endif\n    #ifndef NO_SHA256\n        case dhSinglePass_stdDH_sha256kdf_scheme:\n            kdfType = WC_HASH_TYPE_SHA256;\n            break;\n    #endif\n    #ifdef WOLFSSL_SHA384\n        case dhSinglePass_stdDH_sha384kdf_scheme:\n            kdfType = WC_HASH_TYPE_SHA384;\n            break;\n    #endif\n    #ifdef WOLFSSL_SHA512\n        case dhSinglePass_stdDH_sha512kdf_scheme:\n            kdfType = WC_HASH_TYPE_SHA512;\n            break;\n    #endif\n        default:\n            WOLFSSL_MSG(\"Unsupported key agreement algorithm\");\n            XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);\n            return BAD_FUNC_ARG;\n    };\n\n    ret = wc_X963_KDF(kdfType, secret, secretSz, kari->sharedInfo,\n                      kari->sharedInfoSz, kari->kek, kari->kekSz);\n    if (ret != 0) {\n        XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);\n\n    return 0;\n}\n\n\n/* Encode and add CMS EnvelopedData KARI (KeyAgreeRecipientInfo) RecipientInfo\n * to CMS/PKCS#7 EnvelopedData structure.\n *\n * Returns 0 on success, negative upon error */\nint wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz,\n                               int keyWrapOID, int keyAgreeOID, byte* ukm,\n                               word32 ukmSz, int options)\n{\n    Pkcs7EncodedRecip* recip = NULL;\n    Pkcs7EncodedRecip* lastRecip = NULL;\n    WC_PKCS7_KARI* kari = NULL;\n\n    word32 idx = 0;\n    word32 encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;\n\n    int ret = 0;\n    int keySz, direction = 0;\n    int blockKeySz = 0;\n\n    /* ASN.1 layout */\n    int totalSz = 0;\n    int kariSeqSz = 0;\n    byte kariSeq[MAX_SEQ_SZ];           /* IMPLICIT [1] */\n    int verSz = 0;\n    byte ver[MAX_VERSION_SZ];\n\n    int origIdOrKeySeqSz = 0;\n    byte origIdOrKeySeq[MAX_SEQ_SZ];    /* IMPLICIT [0] */\n    int origPubKeySeqSz = 0;\n    byte origPubKeySeq[MAX_SEQ_SZ];     /* IMPLICIT [1] */\n    int origAlgIdSz = 0;\n    byte origAlgId[MAX_ALGO_SZ];\n    int origPubKeyStrSz = 0;\n    byte origPubKeyStr[MAX_OCTET_STR_SZ];\n\n    /* optional user keying material */\n    int ukmOctetSz = 0;\n    byte ukmOctetStr[MAX_OCTET_STR_SZ];\n    int ukmExplicitSz = 0;\n    byte ukmExplicitSeq[MAX_SEQ_SZ];\n\n    int keyEncryptAlgoIdSz = 0;\n    byte keyEncryptAlgoId[MAX_ALGO_SZ];\n    int keyWrapAlgSz = 0;\n    byte keyWrapAlg[MAX_ALGO_SZ];\n\n    int recipEncKeysSeqSz = 0;\n    byte recipEncKeysSeq[MAX_SEQ_SZ];\n    int recipEncKeySeqSz = 0;\n    byte recipEncKeySeq[MAX_SEQ_SZ];\n    int recipKeyIdSeqSz = 0;\n    byte recipKeyIdSeq[MAX_SEQ_SZ];     /* IMPLICIT [0] */\n    int subjKeyIdOctetSz = 0;\n    byte subjKeyIdOctet[MAX_OCTET_STR_SZ];\n    int encryptedKeyOctetSz = 0;\n    byte encryptedKeyOctet[MAX_OCTET_STR_SZ];\n\n#ifdef WOLFSSL_SMALL_STACK\n    byte* encryptedKey;\n\n    encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,\n                                  DYNAMIC_TYPE_TMP_BUFFER);\n    if (encryptedKey == NULL) {\n        return MEMORY_E;\n    }\n#else\n    byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];\n#endif\n\n    /* allocate and init memory for recipient */\n    recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,\n                                 DYNAMIC_TYPE_PKCS7);\n    if (recip == NULL) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return MEMORY_E;\n    }\n    XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));\n\n    /* get key size for content-encryption key based on algorithm */\n    blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);\n    if (blockKeySz < 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return blockKeySz;\n    }\n\n    /* generate random content encryption key, if needed */\n    ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);\n    if (ret < 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    /* set direction based on keyWrapAlgo */\n    switch (keyWrapOID) {\n#ifndef NO_AES\n    #ifdef WOLFSSL_AES_128\n        case AES128_WRAP:\n    #endif\n    #ifdef WOLFSSL_AES_192\n        case AES192_WRAP:\n    #endif\n    #ifdef WOLFSSL_AES_256\n        case AES256_WRAP:\n    #endif\n            direction = AES_ENCRYPTION;\n            break;\n#endif\n        default:\n            WOLFSSL_MSG(\"Unsupported key wrap algorithm\");\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n            XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return BAD_KEYWRAP_ALG_E;\n    }\n\n    kari = wc_PKCS7_KariNew(pkcs7, WC_PKCS7_ENCODE);\n    if (kari == NULL) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return MEMORY_E;\n    }\n\n    /* set user keying material if available */\n    if (ukmSz > 0 && ukm != NULL) {\n        kari->ukm = ukm;\n        kari->ukmSz = ukmSz;\n        kari->ukmOwner = 0;\n    }\n\n    /* parse recipient cert, get public key */\n    ret = wc_PKCS7_KariParseRecipCert(kari, cert, certSz, NULL, 0);\n    if (ret != 0) {\n        wc_PKCS7_KariFree(kari);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    /* generate sender ephemeral ECC key */\n    ret = wc_PKCS7_KariGenerateEphemeralKey(kari);\n    if (ret != 0) {\n        wc_PKCS7_KariFree(kari);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    /* generate KEK (key encryption key) */\n    ret = wc_PKCS7_KariGenerateKEK(kari, keyWrapOID, keyAgreeOID);\n    if (ret != 0) {\n        wc_PKCS7_KariFree(kari);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    /* encrypt CEK with KEK */\n    keySz = wc_PKCS7_KeyWrap(pkcs7->cek, pkcs7->cekSz, kari->kek,\n                             kari->kekSz, encryptedKey, encryptedKeySz,\n                             keyWrapOID, direction);\n    if (keySz <= 0) {\n        wc_PKCS7_KariFree(kari);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return keySz;\n    }\n    encryptedKeySz = (word32)keySz;\n\n    /* Start of RecipientEncryptedKeys */\n\n    /* EncryptedKey */\n    encryptedKeyOctetSz = SetOctetString(encryptedKeySz, encryptedKeyOctet);\n    totalSz += (encryptedKeyOctetSz + encryptedKeySz);\n\n    /* SubjectKeyIdentifier */\n    subjKeyIdOctetSz = SetOctetString(KEYID_SIZE, subjKeyIdOctet);\n    totalSz += (subjKeyIdOctetSz + KEYID_SIZE);\n\n    /* RecipientKeyIdentifier IMPLICIT [0] */\n    recipKeyIdSeqSz = SetImplicit(ASN_SEQUENCE, 0, subjKeyIdOctetSz +\n                                  KEYID_SIZE, recipKeyIdSeq);\n    totalSz += recipKeyIdSeqSz;\n\n    /* RecipientEncryptedKey */\n    recipEncKeySeqSz = SetSequence(totalSz, recipEncKeySeq);\n    totalSz += recipEncKeySeqSz;\n\n    /* RecipientEncryptedKeys */\n    recipEncKeysSeqSz = SetSequence(totalSz, recipEncKeysSeq);\n    totalSz += recipEncKeysSeqSz;\n\n    /* Start of optional UserKeyingMaterial */\n\n    if (kari->ukmSz > 0) {\n        ukmOctetSz = SetOctetString(kari->ukmSz, ukmOctetStr);\n        totalSz += (ukmOctetSz + kari->ukmSz);\n\n        ukmExplicitSz = SetExplicit(1, ukmOctetSz + kari->ukmSz,\n                                    ukmExplicitSeq);\n        totalSz += ukmExplicitSz;\n    }\n\n    /* Start of KeyEncryptionAlgorithmIdentifier */\n\n    /* KeyWrapAlgorithm */\n    keyWrapAlgSz = SetAlgoID(keyWrapOID, keyWrapAlg, oidKeyWrapType, 0);\n    totalSz += keyWrapAlgSz;\n\n    /* KeyEncryptionAlgorithmIdentifier */\n    keyEncryptAlgoIdSz = SetAlgoID(keyAgreeOID, keyEncryptAlgoId,\n                                   oidCmsKeyAgreeType, keyWrapAlgSz);\n    totalSz += keyEncryptAlgoIdSz;\n\n    /* Start of OriginatorIdentifierOrKey */\n\n    /* recipient ECPoint, public key */\n    XMEMSET(origPubKeyStr, 0, sizeof(origPubKeyStr)); /* no unused bits */\n    origPubKeyStr[0] = ASN_BIT_STRING;\n    origPubKeyStrSz = SetLength(kari->senderKeyExportSz + 1,\n                                origPubKeyStr + 1) + 2;\n    totalSz += (origPubKeyStrSz + kari->senderKeyExportSz);\n\n    /* Originator AlgorithmIdentifier, params set to NULL for interop\n       compatibility */\n    origAlgIdSz = SetAlgoID(ECDSAk, origAlgId, oidKeyType, 2);\n    origAlgId[origAlgIdSz++] = ASN_TAG_NULL;\n    origAlgId[origAlgIdSz++] = 0;\n    totalSz += origAlgIdSz;\n\n    /* outer OriginatorPublicKey IMPLICIT [1] */\n    origPubKeySeqSz = SetImplicit(ASN_SEQUENCE, 1,\n                                  origAlgIdSz + origPubKeyStrSz +\n                                  kari->senderKeyExportSz, origPubKeySeq);\n    totalSz += origPubKeySeqSz;\n\n    /* outer OriginatorIdentiferOrKey IMPLICIT [0] */\n    origIdOrKeySeqSz = SetImplicit(ASN_SEQUENCE, 0,\n                                   origPubKeySeqSz + origAlgIdSz +\n                                   origPubKeyStrSz + kari->senderKeyExportSz,\n                                   origIdOrKeySeq);\n    totalSz += origIdOrKeySeqSz;\n\n    /* version, always 3 */\n    verSz = SetMyVersion(3, ver, 0);\n    totalSz += verSz;\n    recip->recipVersion = 3;\n\n    /* outer IMPLICIT [1] kari */\n    kariSeqSz = SetImplicit(ASN_SEQUENCE, 1, totalSz, kariSeq);\n    totalSz += kariSeqSz;\n\n    if (totalSz > MAX_RECIP_SZ) {\n        WOLFSSL_MSG(\"KeyAgreeRecipientInfo output buffer too small\");\n        wc_PKCS7_KariFree(kari);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return BUFFER_E;\n    }\n\n    XMEMCPY(recip->recip + idx, kariSeq, kariSeqSz);\n    idx += kariSeqSz;\n    XMEMCPY(recip->recip + idx, ver, verSz);\n    idx += verSz;\n\n    XMEMCPY(recip->recip + idx, origIdOrKeySeq, origIdOrKeySeqSz);\n    idx += origIdOrKeySeqSz;\n    XMEMCPY(recip->recip + idx, origPubKeySeq, origPubKeySeqSz);\n    idx += origPubKeySeqSz;\n\n    /* AlgorithmIdentifier with NULL parameter */\n    XMEMCPY(recip->recip + idx, origAlgId, origAlgIdSz);\n    idx += origAlgIdSz;\n\n    XMEMCPY(recip->recip + idx, origPubKeyStr, origPubKeyStrSz);\n    idx += origPubKeyStrSz;\n    /* ephemeral public key */\n    XMEMCPY(recip->recip + idx, kari->senderKeyExport, kari->senderKeyExportSz);\n    idx += kari->senderKeyExportSz;\n\n    if (kari->ukmSz > 0) {\n        XMEMCPY(recip->recip + idx, ukmExplicitSeq, ukmExplicitSz);\n        idx += ukmExplicitSz;\n        XMEMCPY(recip->recip + idx, ukmOctetStr, ukmOctetSz);\n        idx += ukmOctetSz;\n        XMEMCPY(recip->recip + idx, kari->ukm, kari->ukmSz);\n        idx += kari->ukmSz;\n    }\n\n    XMEMCPY(recip->recip + idx, keyEncryptAlgoId, keyEncryptAlgoIdSz);\n    idx += keyEncryptAlgoIdSz;\n    XMEMCPY(recip->recip + idx, keyWrapAlg, keyWrapAlgSz);\n    idx += keyWrapAlgSz;\n\n    XMEMCPY(recip->recip + idx, recipEncKeysSeq, recipEncKeysSeqSz);\n    idx += recipEncKeysSeqSz;\n    XMEMCPY(recip->recip + idx, recipEncKeySeq, recipEncKeySeqSz);\n    idx += recipEncKeySeqSz;\n    XMEMCPY(recip->recip + idx, recipKeyIdSeq, recipKeyIdSeqSz);\n    idx += recipKeyIdSeqSz;\n    XMEMCPY(recip->recip + idx, subjKeyIdOctet, subjKeyIdOctetSz);\n    idx += subjKeyIdOctetSz;\n    /* subject key id */\n    XMEMCPY(recip->recip + idx, kari->decoded->extSubjKeyId, KEYID_SIZE);\n    idx += KEYID_SIZE;\n    XMEMCPY(recip->recip + idx, encryptedKeyOctet, encryptedKeyOctetSz);\n    idx += encryptedKeyOctetSz;\n    /* encrypted CEK */\n    XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);\n    idx += encryptedKeySz;\n\n    wc_PKCS7_KariFree(kari);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    /* store recipient size */\n    recip->recipSz = idx;\n    recip->recipType = PKCS7_KARI;\n\n    /* add recipient to recip list */\n    if (pkcs7->recipList == NULL) {\n        pkcs7->recipList = recip;\n    } else {\n        lastRecip = pkcs7->recipList;\n        while (lastRecip->next != NULL) {\n            lastRecip = lastRecip->next;\n        }\n        lastRecip->next = recip;\n    }\n\n    (void)options;\n\n    return idx;\n}\n\n#endif /* HAVE_ECC */\n\n#ifndef NO_RSA\n\n/* Encode and add CMS EnvelopedData KTRI (KeyTransRecipientInfo) RecipientInfo\n * to CMS/PKCS#7 EnvelopedData structure.\n *\n * Returns 0 on success, negative upon error */\nint wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz,\n                               int options)\n{\n    Pkcs7EncodedRecip* recip = NULL;\n    Pkcs7EncodedRecip* lastRecip = NULL;\n\n    WC_RNG rng;\n    word32 idx = 0;\n    word32 encryptedKeySz = 0;\n\n    int ret = 0, blockKeySz;\n    int verSz = 0, issuerSz = 0, snSz = 0, keyEncAlgSz = 0;\n    int issuerSeqSz = 0, recipSeqSz = 0, issuerSerialSeqSz = 0;\n    int encKeyOctetStrSz;\n    int sidType;\n\n    byte ver[MAX_VERSION_SZ];\n    byte issuerSerialSeq[MAX_SEQ_SZ];\n    byte recipSeq[MAX_SEQ_SZ];\n    byte issuerSeq[MAX_SEQ_SZ];\n    byte encKeyOctetStr[MAX_OCTET_STR_SZ];\n\n    byte issuerSKIDSeq[MAX_SEQ_SZ];\n    byte issuerSKID[MAX_OCTET_STR_SZ];\n    word32 issuerSKIDSeqSz = 0, issuerSKIDSz = 0;\n\n#ifdef WOLFSSL_SMALL_STACK\n    byte*   serial;\n    byte*   keyAlgArray;\n    byte*   encryptedKey;\n    RsaKey* pubKey;\n    DecodedCert* decoded;\n\n    serial = (byte*)XMALLOC(MAX_SN_SZ, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    keyAlgArray = (byte*)XMALLOC(MAX_SN_SZ, pkcs7->heap,\n                                 DYNAMIC_TYPE_TMP_BUFFER);\n    encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,\n                                  DYNAMIC_TYPE_TMP_BUFFER);\n    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,\n                                    DYNAMIC_TYPE_TMP_BUFFER);\n\n    if (decoded == NULL || serial == NULL ||\n        encryptedKey == NULL || keyAlgArray == NULL) {\n        if (serial)\n            XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (keyAlgArray)\n            XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (encryptedKey)\n            XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (decoded)\n            XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n#else\n    byte serial[MAX_SN_SZ];\n    byte keyAlgArray[MAX_ALGO_SZ];\n    byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];\n\n    RsaKey pubKey[1];\n    DecodedCert decoded[1];\n#endif\n\n    encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;\n    XMEMSET(encryptedKey, 0, encryptedKeySz);\n\n    /* default to IssuerAndSerialNumber if not set */\n    if (pkcs7->sidType != 0) {\n        sidType = pkcs7->sidType;\n    } else {\n        sidType = CMS_ISSUER_AND_SERIAL_NUMBER;\n    }\n\n    /* allow options to override SubjectIdentifier type if set */\n    if (options & CMS_SKID) {\n        sidType = CMS_SKID;\n    } else if (options & CMS_ISSUER_AND_SERIAL_NUMBER) {\n        sidType = CMS_ISSUER_AND_SERIAL_NUMBER;\n    }\n\n    /* allocate recipient struct */\n    recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,\n                                 DYNAMIC_TYPE_PKCS7);\n    if (recip == NULL) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return MEMORY_E;\n    }\n    XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));\n\n    /* get key size for content-encryption key based on algorithm */\n    blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);\n    if (blockKeySz < 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return blockKeySz;\n    }\n\n    /* generate random content encryption key, if needed */\n    ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);\n    if (ret < 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    InitDecodedCert(decoded, (byte*)cert, certSz, pkcs7->heap);\n    ret = ParseCert(decoded, CA_TYPE, NO_VERIFY, 0);\n    if (ret < 0) {\n        FreeDecodedCert(decoded);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {\n\n        /* version, must be 0 for IssuerAndSerialNumber */\n        verSz = SetMyVersion(0, ver, 0);\n        recip->recipVersion = 0;\n\n        /* IssuerAndSerialNumber */\n        if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) {\n            WOLFSSL_MSG(\"DecodedCert lacks raw issuer pointer and length\");\n            FreeDecodedCert(decoded);\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n            XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return -1;\n        }\n        issuerSz    = decoded->issuerRawLen;\n        issuerSeqSz = SetSequence(issuerSz, issuerSeq);\n\n        if (decoded->serialSz == 0) {\n            WOLFSSL_MSG(\"DecodedCert missing serial number\");\n            FreeDecodedCert(decoded);\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n            XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return -1;\n        }\n        snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial,\n                               MAX_SN_SZ, MAX_SN_SZ);\n\n        issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz,\n                                        issuerSerialSeq);\n\n    } else if (sidType == CMS_SKID) {\n\n        /* version, must be 2 for SubjectKeyIdentifier */\n        verSz = SetMyVersion(2, ver, 0);\n        recip->recipVersion = 2;\n\n        issuerSKIDSz = SetOctetString(KEYID_SIZE, issuerSKID);\n        issuerSKIDSeqSz = SetExplicit(0, issuerSKIDSz + KEYID_SIZE,\n                                      issuerSKIDSeq);\n    } else {\n        FreeDecodedCert(decoded);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return PKCS7_RECIP_E;\n    }\n\n    pkcs7->publicKeyOID = decoded->keyOID;\n\n    /* KeyEncryptionAlgorithmIdentifier, only support RSA now */\n    if (pkcs7->publicKeyOID != RSAk) {\n        FreeDecodedCert(decoded);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ALGO_ID_E;\n    }\n\n    keyEncAlgSz = SetAlgoID(pkcs7->publicKeyOID, keyAlgArray, oidKeyType, 0);\n    if (keyEncAlgSz == 0) {\n        FreeDecodedCert(decoded);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,\n            DYNAMIC_TYPE_TMP_BUFFER);\n    if (pubKey == NULL) {\n        FreeDecodedCert(decoded);\n        XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return MEMORY_E;\n    }\n#endif\n\n    /* EncryptedKey */\n    ret = wc_InitRsaKey_ex(pubKey, pkcs7->heap, INVALID_DEVID);\n    if (ret != 0) {\n        FreeDecodedCert(decoded);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(pubKey,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    if (wc_RsaPublicKeyDecode(decoded->publicKey, &idx, pubKey,\n                              decoded->pubKeySize) < 0) {\n        WOLFSSL_MSG(\"ASN RSA key decode error\");\n        wc_FreeRsaKey(pubKey);\n        FreeDecodedCert(decoded);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(pubKey,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return PUBLIC_KEY_E;\n    }\n\n    ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);\n    if (ret != 0) {\n        wc_FreeRsaKey(pubKey);\n        FreeDecodedCert(decoded);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(pubKey,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return MEMORY_E;\n    }\n\n\n    ret = wc_RsaPublicEncrypt(pkcs7->cek, pkcs7->cekSz, encryptedKey,\n                              encryptedKeySz, pubKey, &rng);\n    wc_FreeRsaKey(pubKey);\n    wc_FreeRng(&rng);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    if (ret < 0) {\n        WOLFSSL_MSG(\"RSA Public Encrypt failed\");\n        FreeDecodedCert(decoded);\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n    encryptedKeySz = ret;\n\n    encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);\n\n    /* RecipientInfo */\n    if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {\n        recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz +\n                                 issuerSz + snSz + keyEncAlgSz +\n                                 encKeyOctetStrSz + encryptedKeySz, recipSeq);\n\n        if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz +\n            keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) {\n            WOLFSSL_MSG(\"RecipientInfo output buffer too small\");\n            FreeDecodedCert(decoded);\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n            XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return BUFFER_E;\n        }\n\n    } else {\n        recipSeqSz = SetSequence(verSz + issuerSKIDSeqSz + issuerSKIDSz +\n                                 KEYID_SIZE + keyEncAlgSz + encKeyOctetStrSz +\n                                 encryptedKeySz, recipSeq);\n\n        if (recipSeqSz + verSz + issuerSKIDSeqSz + issuerSKIDSz + KEYID_SIZE +\n            keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) {\n            WOLFSSL_MSG(\"RecipientInfo output buffer too small\");\n            FreeDecodedCert(decoded);\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n            XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return BUFFER_E;\n        }\n    }\n\n    idx = 0;\n    XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);\n    idx += recipSeqSz;\n    XMEMCPY(recip->recip + idx, ver, verSz);\n    idx += verSz;\n    if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {\n        XMEMCPY(recip->recip + idx, issuerSerialSeq, issuerSerialSeqSz);\n        idx += issuerSerialSeqSz;\n        XMEMCPY(recip->recip + idx, issuerSeq, issuerSeqSz);\n        idx += issuerSeqSz;\n        XMEMCPY(recip->recip + idx, decoded->issuerRaw, issuerSz);\n        idx += issuerSz;\n        XMEMCPY(recip->recip + idx, serial, snSz);\n        idx += snSz;\n    } else {\n        XMEMCPY(recip->recip + idx, issuerSKIDSeq, issuerSKIDSeqSz);\n        idx += issuerSKIDSeqSz;\n        XMEMCPY(recip->recip + idx, issuerSKID, issuerSKIDSz);\n        idx += issuerSKIDSz;\n        XMEMCPY(recip->recip + idx, pkcs7->issuerSubjKeyId, KEYID_SIZE);\n        idx += KEYID_SIZE;\n    }\n    XMEMCPY(recip->recip + idx, keyAlgArray, keyEncAlgSz);\n    idx += keyEncAlgSz;\n    XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);\n    idx += encKeyOctetStrSz;\n    XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);\n    idx += encryptedKeySz;\n\n    FreeDecodedCert(decoded);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(serial,       pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(keyAlgArray,  pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(decoded,      pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    /* store recipient size */\n    recip->recipSz = idx;\n    recip->recipType = PKCS7_KTRI;\n\n    /* add recipient to recip list */\n    if (pkcs7->recipList == NULL) {\n        pkcs7->recipList = recip;\n    } else {\n        lastRecip = pkcs7->recipList;\n        while (lastRecip->next != NULL) {\n            lastRecip = lastRecip->next;\n        }\n        lastRecip->next = recip;\n    }\n\n    return idx;\n}\n\n#endif /* !NO_RSA */\n\n\n/* encrypt content using encryptOID algo */\nstatic int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz,\n                                   byte* iv, int ivSz, byte* aad, word32 aadSz,\n                                   byte* authTag, word32 authTagSz, byte* in,\n                                   int inSz, byte* out)\n{\n    int ret;\n#ifndef NO_AES\n    Aes  aes;\n#endif\n#ifndef NO_DES3\n    Des  des;\n    Des3 des3;\n#endif\n\n    if (key == NULL || iv == NULL || in == NULL || out == NULL)\n        return BAD_FUNC_ARG;\n\n    switch (encryptOID) {\n#ifndef NO_AES\n    #ifdef WOLFSSL_AES_128\n        case AES128CBCb:\n    #endif\n    #ifdef WOLFSSL_AES_192\n        case AES192CBCb:\n    #endif\n    #ifdef WOLFSSL_AES_256\n        case AES256CBCb:\n    #endif\n            if (\n                #ifdef WOLFSSL_AES_128\n                    (encryptOID == AES128CBCb && keySz != 16 ) ||\n                #endif\n                #ifdef WOLFSSL_AES_192\n                    (encryptOID == AES192CBCb && keySz != 24 ) ||\n                #endif\n                #ifdef WOLFSSL_AES_256\n                    (encryptOID == AES256CBCb && keySz != 32 ) ||\n                #endif\n                    (ivSz  != AES_BLOCK_SIZE) )\n                return BAD_FUNC_ARG;\n\n            ret = wc_AesInit(&aes, NULL, INVALID_DEVID);\n            if (ret == 0) {\n                ret = wc_AesSetKey(&aes, key, keySz, iv, AES_ENCRYPTION);\n                if (ret == 0)\n                    ret = wc_AesCbcEncrypt(&aes, out, in, inSz);\n                wc_AesFree(&aes);\n            }\n            break;\n    #ifdef HAVE_AESGCM\n        #ifdef WOLFSSL_AES_128\n        case AES128GCMb:\n        #endif\n        #ifdef WOLFSSL_AES_192\n        case AES192GCMb:\n        #endif\n        #ifdef WOLFSSL_AES_256\n        case AES256GCMb:\n        #endif\n        #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \\\n            defined(WOLFSSL_AES_256)\n            if (authTag == NULL)\n                return BAD_FUNC_ARG;\n\n            ret = wc_AesInit(&aes, NULL, INVALID_DEVID);\n            if (ret == 0) {\n                ret = wc_AesGcmSetKey(&aes, key, keySz);\n                if (ret == 0)\n                    ret = wc_AesGcmEncrypt(&aes, out, in, inSz, iv, ivSz,\n                                           authTag, authTagSz, aad, aadSz);\n                wc_AesFree(&aes);\n            }\n            break;\n        #endif\n    #endif /* HAVE_AESGCM */\n    #ifdef HAVE_AESCCM\n        #ifdef WOLFSSL_AES_128\n        case AES128CCMb:\n        #endif\n        #ifdef WOLFSSL_AES_192\n        case AES192CCMb:\n        #endif\n        #ifdef WOLFSSL_AES_256\n        case AES256CCMb:\n        #endif\n        #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \\\n            defined(WOLFSSL_AES_256)\n            if (authTag == NULL)\n                return BAD_FUNC_ARG;\n\n            ret = wc_AesInit(&aes, NULL, INVALID_DEVID);\n            if (ret == 0) {\n                ret = wc_AesCcmSetKey(&aes, key, keySz);\n                if (ret == 0)\n                    ret = wc_AesCcmEncrypt(&aes, out, in, inSz, iv, ivSz,\n                                           authTag, authTagSz, aad, aadSz);\n                wc_AesFree(&aes);\n            }\n            break;\n        #endif\n    #endif /* HAVE_AESCCM */\n#endif /* NO_AES */\n#ifndef NO_DES3\n        case DESb:\n            if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)\n                return BAD_FUNC_ARG;\n\n            ret = wc_Des_SetKey(&des, key, iv, DES_ENCRYPTION);\n            if (ret == 0)\n                ret = wc_Des_CbcEncrypt(&des, out, in, inSz);\n\n            break;\n\n        case DES3b:\n            if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)\n                return BAD_FUNC_ARG;\n\n            ret = wc_Des3Init(&des3, NULL, INVALID_DEVID);\n            if (ret == 0) {\n                ret = wc_Des3_SetKey(&des3, key, iv, DES_ENCRYPTION);\n                if (ret == 0)\n                    ret = wc_Des3_CbcEncrypt(&des3, out, in, inSz);\n                wc_Des3Free(&des3);\n            }\n            break;\n#endif\n        default:\n            WOLFSSL_MSG(\"Unsupported content cipher type\");\n            return ALGO_ID_E;\n    };\n\n#if defined(NO_AES) || (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM))\n    (void)authTag;\n    (void)authTagSz;\n    (void)aad;\n    (void)aadSz;\n#endif\n    return ret;\n}\n\n\n/* decrypt content using encryptOID algo\n * returns 0 on success */\nstatic int wc_PKCS7_DecryptContent(PKCS7* pkcs7, int encryptOID, byte* key,\n        int keySz, byte* iv, int ivSz, byte* aad, word32 aadSz, byte* authTag,\n        word32 authTagSz, byte* in, int inSz, byte* out)\n{\n    int ret;\n#ifndef NO_AES\n    Aes  aes;\n#endif\n#ifndef NO_DES3\n    Des  des;\n    Des3 des3;\n#endif\n\n    if (iv == NULL || in == NULL || out == NULL)\n        return BAD_FUNC_ARG;\n\n    if (pkcs7->decryptionCb != NULL) {\n        return pkcs7->decryptionCb(pkcs7, encryptOID, iv, ivSz,\n                                      aad, aadSz, authTag, authTagSz, in,\n                                      inSz, out, pkcs7->decryptionCtx);\n    }\n\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    switch (encryptOID) {\n#ifndef NO_AES\n    #ifdef WOLFSSL_AES_128\n        case AES128CBCb:\n    #endif\n    #ifdef WOLFSSL_AES_192\n        case AES192CBCb:\n    #endif\n    #ifdef WOLFSSL_AES_256\n        case AES256CBCb:\n    #endif\n            if (\n                #ifdef WOLFSSL_AES_128\n                    (encryptOID == AES128CBCb && keySz != 16 ) ||\n                #endif\n                #ifdef WOLFSSL_AES_192\n                    (encryptOID == AES192CBCb && keySz != 24 ) ||\n                #endif\n                #ifdef WOLFSSL_AES_256\n                    (encryptOID == AES256CBCb && keySz != 32 ) ||\n                #endif\n                    (ivSz  != AES_BLOCK_SIZE) )\n                return BAD_FUNC_ARG;\n            ret = wc_AesInit(&aes, NULL, INVALID_DEVID);\n            if (ret == 0) {\n                ret = wc_AesSetKey(&aes, key, keySz, iv, AES_DECRYPTION);\n                if (ret == 0)\n                    ret = wc_AesCbcDecrypt(&aes, out, in, inSz);\n                wc_AesFree(&aes);\n            }\n            break;\n    #ifdef HAVE_AESGCM\n        #ifdef WOLFSSL_AES_128\n        case AES128GCMb:\n        #endif\n        #ifdef WOLFSSL_AES_192\n        case AES192GCMb:\n        #endif\n        #ifdef WOLFSSL_AES_256\n        case AES256GCMb:\n        #endif\n        #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \\\n            defined(WOLFSSL_AES_256)\n            if (authTag == NULL)\n                return BAD_FUNC_ARG;\n\n            ret = wc_AesInit(&aes, NULL, INVALID_DEVID);\n            if (ret == 0) {\n                ret = wc_AesGcmSetKey(&aes, key, keySz);\n                if (ret == 0)\n                    ret = wc_AesGcmDecrypt(&aes, out, in, inSz, iv, ivSz,\n                                           authTag, authTagSz, aad, aadSz);\n                wc_AesFree(&aes);\n            }\n            break;\n        #endif\n    #endif /* HAVE_AESGCM */\n    #ifdef HAVE_AESCCM\n        #ifdef WOLFSSL_AES_128\n        case AES128CCMb:\n        #endif\n        #ifdef WOLFSSL_AES_192\n        case AES192CCMb:\n        #endif\n        #ifdef WOLFSSL_AES_256\n        case AES256CCMb:\n        #endif\n        #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \\\n            defined(WOLFSSL_AES_256)\n            if (authTag == NULL)\n                return BAD_FUNC_ARG;\n\n            ret = wc_AesInit(&aes, NULL, INVALID_DEVID);\n            if (ret == 0) {\n                ret = wc_AesCcmSetKey(&aes, key, keySz);\n                if (ret == 0)\n                    ret = wc_AesCcmDecrypt(&aes, out, in, inSz, iv, ivSz,\n                                           authTag, authTagSz, aad, aadSz);\n                wc_AesFree(&aes);\n            }\n            break;\n        #endif\n    #endif /* HAVE_AESCCM */\n#endif /* NO_AES */\n#ifndef NO_DES3\n        case DESb:\n            if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)\n                return BAD_FUNC_ARG;\n\n            ret = wc_Des_SetKey(&des, key, iv, DES_DECRYPTION);\n            if (ret == 0)\n                ret = wc_Des_CbcDecrypt(&des, out, in, inSz);\n\n            break;\n        case DES3b:\n            if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)\n                return BAD_FUNC_ARG;\n\n            ret = wc_Des3Init(&des3, NULL, INVALID_DEVID);\n            if (ret == 0) {\n                ret = wc_Des3_SetKey(&des3, key, iv, DES_DECRYPTION);\n                if (ret == 0)\n                    ret = wc_Des3_CbcDecrypt(&des3, out, in, inSz);\n                wc_Des3Free(&des3);\n            }\n\n            break;\n#endif\n        default:\n            WOLFSSL_MSG(\"Unsupported content cipher type\");\n            return ALGO_ID_E;\n    };\n\n#if defined(NO_AES) || (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM))\n    (void)authTag;\n    (void)authTagSz;\n    (void)aad;\n    (void)aadSz;\n#endif\n\n    return ret;\n}\n\n\n/* Generate random block, place in out, return 0 on success negative on error.\n * Used for generation of IV, nonce, etc */\nstatic int wc_PKCS7_GenerateBlock(PKCS7* pkcs7, WC_RNG* rng, byte* out,\n                                  word32 outSz)\n{\n    int ret;\n    WC_RNG* rnd = NULL;\n\n    if (out == NULL || outSz == 0)\n        return BAD_FUNC_ARG;\n\n    /* input RNG is optional, init local one if input rng is NULL */\n    if (rng == NULL) {\n        rnd = (WC_RNG*)XMALLOC(sizeof(WC_RNG), pkcs7->heap, DYNAMIC_TYPE_RNG);\n        if (rnd == NULL)\n            return MEMORY_E;\n\n        ret = wc_InitRng_ex(rnd, pkcs7->heap, pkcs7->devId);\n        if (ret != 0) {\n            XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG);\n            return ret;\n        }\n\n    } else {\n        rnd = rng;\n    }\n\n    ret = wc_RNG_GenerateBlock(rnd, out, outSz);\n\n    if (rng == NULL) {\n        wc_FreeRng(rnd);\n        XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG);\n    }\n\n    return ret;\n}\n\n\n/* Set default SignerIdentifier type to be used. Is either\n * IssuerAndSerialNumber or SubjectKeyIdentifier. Encoding defaults to using\n * IssuerAndSerialNumber unless set with this function or explicitly\n * overriden via options when adding RecipientInfo type.\n *\n * Using the type DEGENERATE_SID skips over signer information. In degenerate\n * cases there are no signers.\n *\n * pkcs7 - pointer to initialized PKCS7 structure\n * type  - either CMS_ISSUER_AND_SERIAL_NUMBER, CMS_SKID or DEGENERATE_SID\n *\n * return 0 on success, negative upon error */\nint wc_PKCS7_SetSignerIdentifierType(PKCS7* pkcs7, int type)\n{\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    if (type != CMS_ISSUER_AND_SERIAL_NUMBER &&\n        type != CMS_SKID &&\n        type != DEGENERATE_SID) {\n        return BAD_FUNC_ARG;\n    }\n\n    pkcs7->sidType = type;\n\n    return 0;\n}\n\n\n/* Set custom contentType, currently supported with SignedData type\n *\n * pkcs7       - pointer to initialized PKCS7 structure\n * contentType - pointer to array with ASN.1 encoded OID value\n * sz          - length of contentType array, octets\n *\n * return 0 on success, negative upon error */\nint wc_PKCS7_SetContentType(PKCS7* pkcs7, byte* contentType, word32 sz)\n{\n    if (pkcs7 == NULL || contentType == NULL || sz == 0)\n        return BAD_FUNC_ARG;\n\n    if (sz > MAX_OID_SZ) {\n        WOLFSSL_MSG(\"input array too large, bounded by MAX_OID_SZ\");\n        return BAD_FUNC_ARG;\n    }\n\n    XMEMCPY(pkcs7->contentType, contentType, sz);\n    pkcs7->contentTypeSz = sz;\n\n    return 0;\n}\n\n\n/* return size of padded data, padded to blockSz chunks, or negative on error */\nint wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz)\n{\n    int padSz;\n\n    if (blockSz == 0)\n        return BAD_FUNC_ARG;\n\n    padSz = blockSz - (inputSz % blockSz);\n\n    return padSz;\n}\n\n\n/* pad input data to blockSz chunk, place in outSz. out must be big enough\n * for input + pad bytes. See wc_PKCS7_GetPadSize() helper. */\nint wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,\n                     word32 blockSz)\n{\n    int i, padSz;\n\n    if (in == NULL  || inSz == 0 ||\n        out == NULL || outSz == 0)\n        return BAD_FUNC_ARG;\n\n    padSz = wc_PKCS7_GetPadSize(inSz, blockSz);\n\n    if (outSz < (inSz + padSz))\n        return BAD_FUNC_ARG;\n\n    XMEMCPY(out, in, inSz);\n\n    for (i = 0; i < padSz; i++) {\n        out[inSz + i] = (byte)padSz;\n    }\n\n    return inSz + padSz;\n}\n\n\n/* Encode and add CMS EnvelopedData ORI (OtherRecipientInfo) RecipientInfo\n * to CMS/PKCS#7 EnvelopedData structure.\n *\n * Return 0 on success, negative upon error */\nint wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt oriEncryptCb,\n                              int options)\n{\n    int oriTypeLenSz, blockKeySz, ret;\n    word32 idx, recipSeqSz;\n\n    Pkcs7EncodedRecip* recip = NULL;\n    Pkcs7EncodedRecip* lastRecip = NULL;\n\n    byte recipSeq[MAX_SEQ_SZ];\n    byte oriTypeLen[MAX_LENGTH_SZ];\n\n    byte oriType[MAX_ORI_TYPE_SZ];\n    byte oriValue[MAX_ORI_VALUE_SZ];\n    word32 oriTypeSz = MAX_ORI_TYPE_SZ;\n    word32 oriValueSz = MAX_ORI_VALUE_SZ;\n\n    if (pkcs7 == NULL || oriEncryptCb == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* allocate memory for RecipientInfo, KEK, encrypted key */\n    recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip),\n                                        pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (recip == NULL)\n        return MEMORY_E;\n    XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));\n\n    /* get key size for content-encryption key based on algorithm */\n    blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);\n    if (blockKeySz < 0) {\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return blockKeySz;\n    }\n\n    /* generate random content encryption key, if needed */\n    ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);\n    if (ret < 0) {\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    /* call user callback to encrypt CEK and get oriType and oriValue\n       values back */\n    ret = oriEncryptCb(pkcs7, pkcs7->cek, pkcs7->cekSz, oriType, &oriTypeSz,\n                       oriValue, &oriValueSz, pkcs7->oriEncryptCtx);\n    if (ret != 0) {\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    oriTypeLenSz = SetLength(oriTypeSz, oriTypeLen);\n\n    recipSeqSz = SetImplicit(ASN_SEQUENCE, 4, 1 + oriTypeLenSz + oriTypeSz +\n                             oriValueSz, recipSeq);\n\n    idx = 0;\n    XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);\n    idx += recipSeqSz;\n    /* oriType */\n    recip->recip[idx] = ASN_OBJECT_ID;\n    idx += 1;\n    XMEMCPY(recip->recip + idx, oriTypeLen, oriTypeLenSz);\n    idx += oriTypeLenSz;\n    XMEMCPY(recip->recip + idx, oriType, oriTypeSz);\n    idx += oriTypeSz;\n    /* oriValue, input MUST already be ASN.1 encoded */\n    XMEMCPY(recip->recip + idx, oriValue, oriValueSz);\n    idx += oriValueSz;\n\n    /* store recipient size */\n    recip->recipSz = idx;\n    recip->recipType = PKCS7_ORI;\n    recip->recipVersion = 4;\n\n    /* add recipient to recip list */\n    if (pkcs7->recipList == NULL) {\n        pkcs7->recipList = recip;\n    } else {\n        lastRecip = pkcs7->recipList;\n        while (lastRecip->next != NULL) {\n            lastRecip = lastRecip->next;\n        }\n        lastRecip->next = recip;\n    }\n\n    (void)options;\n\n    return idx;\n}\n\n#if !defined(NO_PWDBASED) && !defined(NO_SHA)\n\n\nstatic int wc_PKCS7_GenerateKEK_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen,\n                                     byte* salt, word32 saltSz, int kdfOID,\n                                     int prfOID, int iterations, byte* out,\n                                     word32 outSz)\n{\n    int ret;\n\n    if (pkcs7 == NULL || passwd == NULL || salt == NULL || out == NULL)\n        return BAD_FUNC_ARG;\n\n    switch (kdfOID) {\n\n        case PBKDF2_OID:\n\n            ret = wc_PBKDF2(out, passwd, pLen, salt, saltSz, iterations,\n                            outSz, prfOID);\n            if (ret != 0) {\n                return ret;\n            }\n\n            break;\n\n        default:\n            WOLFSSL_MSG(\"Unsupported KDF OID\");\n            return PKCS7_OID_E;\n    }\n\n    return 0;\n}\n\n\n/* RFC3211 (Section 2.3.1) key wrap algorithm (id-alg-PWRI-KEK).\n *\n * Returns output size on success, negative upon error */\nstatic int wc_PKCS7_PwriKek_KeyWrap(PKCS7* pkcs7, const byte* kek, word32 kekSz,\n                                    const byte* cek, word32 cekSz,\n                                    byte* out, word32 *outSz,\n                                    const byte* iv, word32 ivSz, int algID)\n{\n    WC_RNG rng;\n    int blockSz, outLen, ret;\n    word32 padSz;\n    byte* lastBlock;\n\n    if (kek == NULL || cek == NULL || iv == NULL || outSz == NULL)\n        return BAD_FUNC_ARG;\n\n    /* get encryption algorithm block size */\n    blockSz = wc_PKCS7_GetOIDBlockSize(algID);\n    if (blockSz < 0)\n        return blockSz;\n\n    /* get pad bytes needed to block boundary */\n    padSz = blockSz - ((4 + cekSz) % blockSz);\n    outLen = 4 + cekSz + padSz;\n\n    /* must be at least two blocks long */\n    if (outLen < 2 * blockSz)\n        padSz += blockSz;\n\n    /* if user set out to NULL, give back required length */\n    if (out == NULL) {\n        *outSz = outLen;\n        return LENGTH_ONLY_E;\n    }\n\n    /* verify output buffer is large enough */\n    if (*outSz < (word32)outLen)\n        return BUFFER_E;\n\n    out[0] = cekSz;\n    out[1] = ~cek[0];\n    out[2] = ~cek[1];\n    out[3] = ~cek[2];\n    XMEMCPY(out + 4, cek, cekSz);\n\n    /* random padding of size padSz */\n    ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);\n    if (ret != 0)\n        return ret;\n\n    ret = wc_RNG_GenerateBlock(&rng, out + 4 + cekSz, padSz);\n\n    if (ret == 0) {\n        /* encrypt, normal */\n        ret = wc_PKCS7_EncryptContent(algID, (byte*)kek, kekSz, (byte*)iv,\n                                      ivSz, NULL, 0, NULL, 0, out, outLen, out);\n    }\n\n    if (ret == 0) {\n        /* encrypt again, using last ciphertext block as IV */\n        lastBlock = out + (((outLen / blockSz) - 1) * blockSz);\n        ret = wc_PKCS7_EncryptContent(algID, (byte*)kek, kekSz, lastBlock,\n                                      blockSz, NULL, 0, NULL, 0, out,\n                                      outLen, out);\n    }\n\n    if (ret == 0) {\n        *outSz = outLen;\n    } else {\n        outLen = ret;\n    }\n\n    wc_FreeRng(&rng);\n\n    return outLen;\n}\n\n\n/* RFC3211 (Section 2.3.2) key unwrap algorithm (id-alg-PWRI-KEK).\n *\n * Returns cek size on success, negative upon error */\nstatic int wc_PKCS7_PwriKek_KeyUnWrap(PKCS7* pkcs7, const byte* kek,\n                                      word32 kekSz, const byte* in, word32 inSz,\n                                      byte* out, word32 outSz, const byte* iv,\n                                      word32 ivSz, int algID)\n{\n    int blockSz, cekLen, ret;\n    byte* tmpIv     = NULL;\n    byte* lastBlock = NULL;\n    byte* outTmp    = NULL;\n\n    if (pkcs7 == NULL || kek == NULL || in == NULL ||\n        out == NULL || iv == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    outTmp = (byte*)XMALLOC(inSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (outTmp == NULL)\n        return MEMORY_E;\n\n    /* get encryption algorithm block size */\n    blockSz = wc_PKCS7_GetOIDBlockSize(algID);\n    if (blockSz < 0) {\n        XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return blockSz;\n    }\n\n    /* input needs to be blockSz multiple and at least 2 * blockSz */\n    if (((inSz % blockSz) != 0) || (inSz < (2 * (word32)blockSz))) {\n        WOLFSSL_MSG(\"PWRI-KEK unwrap input must of block size and >= 2 \"\n                    \"times block size\");\n        XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return BAD_FUNC_ARG;\n    }\n\n    /* use block out[n-1] as IV to decrypt block out[n] */\n    lastBlock = (byte*)in + inSz - blockSz;\n    tmpIv = lastBlock - blockSz;\n\n    /* decrypt last block */\n    ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz, tmpIv,\n            blockSz, NULL, 0, NULL, 0, lastBlock, blockSz,\n            outTmp + inSz - blockSz);\n\n    if (ret == 0) {\n        /* using last decrypted block as IV, decrypt [0 ... n-1] blocks */\n        lastBlock = outTmp + inSz - blockSz;\n        ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz,\n                lastBlock, blockSz, NULL, 0, NULL, 0, (byte*)in, inSz - blockSz,\n                outTmp);\n    }\n\n    if (ret == 0) {\n        /* decrypt using original kek and iv */\n        ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz,\n                (byte*)iv, ivSz, NULL, 0, NULL, 0, outTmp, inSz, outTmp);\n    }\n\n    if (ret != 0) {\n        ForceZero(outTmp, inSz);\n        XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return ret;\n    }\n\n    cekLen = outTmp[0];\n\n    /* verify length */\n    if ((word32)cekLen > inSz) {\n        ForceZero(outTmp, inSz);\n        XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return BAD_FUNC_ARG;\n    }\n\n    /* verify check bytes */\n    if ((outTmp[1] ^ outTmp[4]) != 0xFF ||\n        (outTmp[2] ^ outTmp[5]) != 0xFF ||\n        (outTmp[3] ^ outTmp[6]) != 0xFF) {\n        ForceZero(outTmp, inSz);\n        XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return BAD_FUNC_ARG;\n    }\n\n    if (outSz < (word32)cekLen) {\n        ForceZero(outTmp, inSz);\n        XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return BUFFER_E;\n    }\n\n    XMEMCPY(out, outTmp + 4, outTmp[0]);\n    ForceZero(outTmp, inSz);\n    XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    return cekLen;\n}\n\n\n/* Encode and add CMS EnvelopedData PWRI (PasswordRecipientInfo) RecipientInfo\n * to CMS/PKCS#7 EnvelopedData structure.\n *\n * Return 0 on success, negative upon error */\nint wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen,\n                               byte* salt, word32 saltSz, int kdfOID,\n                               int hashOID, int iterations, int kekEncryptOID,\n                               int options)\n{\n    Pkcs7EncodedRecip* recip = NULL;\n    Pkcs7EncodedRecip* lastRecip = NULL;\n\n    /* PasswordRecipientInfo */\n    byte recipSeq[MAX_SEQ_SZ];\n    byte ver[MAX_VERSION_SZ];\n    word32 recipSeqSz, verSz;\n\n    /* KeyDerivationAlgorithmIdentifier */\n    byte kdfAlgoIdSeq[MAX_SEQ_SZ];\n    byte kdfAlgoId[MAX_OID_SZ];\n    byte kdfParamsSeq[MAX_SEQ_SZ];              /* PBKDF2-params */\n    byte kdfSaltOctetStr[MAX_OCTET_STR_SZ];     /* salt OCTET STRING */\n    byte kdfIterations[MAX_VERSION_SZ];\n    word32 kdfAlgoIdSeqSz, kdfAlgoIdSz;\n    word32 kdfParamsSeqSz, kdfSaltOctetStrSz, kdfIterationsSz;\n    /* OPTIONAL: keyLength, not supported yet */\n    /* OPTIONAL: prf AlgorithIdentifier, not supported yet */\n\n    /* KeyEncryptionAlgorithmIdentifier */\n    byte keyEncAlgoIdSeq[MAX_SEQ_SZ];\n    byte keyEncAlgoId[MAX_OID_SZ];              /* id-alg-PWRI-KEK */\n    byte pwriEncAlgoId[MAX_ALGO_SZ];\n    byte ivOctetString[MAX_OCTET_STR_SZ];\n    word32 keyEncAlgoIdSeqSz, keyEncAlgoIdSz;\n    word32 pwriEncAlgoIdSz, ivOctetStringSz;\n\n    /* EncryptedKey */\n    byte encKeyOctetStr[MAX_OCTET_STR_SZ];\n    word32 encKeyOctetStrSz;\n\n    byte tmpIv[MAX_CONTENT_IV_SIZE];\n    byte* encryptedKey = NULL;\n    byte* kek = NULL;\n\n    int cekKeySz = 0, kekKeySz = 0, kekBlockSz = 0, ret = 0;\n    int encryptOID;\n    word32 idx, totalSz = 0, encryptedKeySz;\n\n    if (pkcs7 == NULL || passwd == NULL || pLen == 0 ||\n        salt == NULL || saltSz == 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* allow user to use different KEK encryption algorithm than used for\n     * main content encryption algorithm, if passed in */\n    if (kekEncryptOID != 0) {\n        encryptOID = kekEncryptOID;\n    } else {\n        encryptOID = pkcs7->encryptOID;\n    }\n\n    /* get content-encryption key size, based on algorithm */\n    cekKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);\n    if (cekKeySz < 0)\n        return cekKeySz;\n\n    /* get KEK encryption key size, based on algorithm */\n    if (encryptOID != pkcs7->encryptOID) {\n        kekKeySz = wc_PKCS7_GetOIDKeySize(encryptOID);\n    } else {\n        kekKeySz = cekKeySz;\n    }\n\n    /* get KEK encryption block size */\n    kekBlockSz = wc_PKCS7_GetOIDBlockSize(encryptOID);\n    if (kekBlockSz < 0)\n        return kekBlockSz;\n\n    /* generate random CEK */\n    ret = PKCS7_GenerateContentEncryptionKey(pkcs7, cekKeySz);\n    if (ret < 0)\n        return ret;\n\n    /* generate random IV */\n    ret = wc_PKCS7_GenerateBlock(pkcs7, NULL, tmpIv, kekBlockSz);\n    if (ret != 0)\n        return ret;\n\n    /* allocate memory for RecipientInfo, KEK, encrypted key */\n    recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip),\n                                        pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (recip == NULL)\n        return MEMORY_E;\n\n    kek = (byte*)XMALLOC(kekKeySz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (kek == NULL) {\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return MEMORY_E;\n    }\n\n    encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ,\n                                  pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (encryptedKey == NULL) {\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return MEMORY_E;\n    }\n\n    encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;\n    XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));\n    XMEMSET(kek, 0, kekKeySz);\n    XMEMSET(encryptedKey, 0, encryptedKeySz);\n\n    /* generate KEK: expand password into KEK */\n    ret = wc_PKCS7_GenerateKEK_PWRI(pkcs7, passwd, pLen, salt, saltSz,\n                                    kdfOID, hashOID, iterations, kek,\n                                    kekKeySz);\n    if (ret < 0) {\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    /* generate encrypted key: encrypt CEK with KEK */\n    ret = wc_PKCS7_PwriKek_KeyWrap(pkcs7, kek, kekKeySz, pkcs7->cek,\n                                   pkcs7->cekSz, encryptedKey, &encryptedKeySz,\n                                   tmpIv, kekBlockSz, encryptOID);\n    if (ret < 0) {\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n    encryptedKeySz = ret;\n\n    /* put together encrypted key OCTET STRING */\n    encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);\n    totalSz += (encKeyOctetStrSz + encryptedKeySz);\n\n    /* put together IV OCTET STRING */\n    ivOctetStringSz = SetOctetString(kekBlockSz, ivOctetString);\n    totalSz += (ivOctetStringSz + kekBlockSz);\n\n    /* set PWRIAlgorithms AlgorithmIdentifier, adding (ivOctetStringSz +\n       blockKeySz) for IV OCTET STRING */\n    pwriEncAlgoIdSz = SetAlgoID(encryptOID, pwriEncAlgoId,\n                                oidBlkType, ivOctetStringSz + kekBlockSz);\n    totalSz += pwriEncAlgoIdSz;\n\n    /* set KeyEncryptionAlgorithms OID */\n    ret = wc_SetContentType(PWRI_KEK_WRAP, keyEncAlgoId, sizeof(keyEncAlgoId));\n    if (ret <= 0) {\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n    keyEncAlgoIdSz = ret;\n    totalSz += keyEncAlgoIdSz;\n\n    /* KeyEncryptionAlgorithm SEQ */\n    keyEncAlgoIdSeqSz = SetSequence(keyEncAlgoIdSz + pwriEncAlgoIdSz +\n                                    ivOctetStringSz + kekBlockSz,\n                                    keyEncAlgoIdSeq);\n    totalSz += keyEncAlgoIdSeqSz;\n\n    /* set KDF salt */\n    kdfSaltOctetStrSz = SetOctetString(saltSz, kdfSaltOctetStr);\n    totalSz += (kdfSaltOctetStrSz + saltSz);\n\n    /* set KDF iteration count */\n    kdfIterationsSz = SetMyVersion(iterations, kdfIterations, 0);\n    totalSz += kdfIterationsSz;\n\n    /* set KDF params SEQ */\n    kdfParamsSeqSz = SetSequence(kdfSaltOctetStrSz + saltSz + kdfIterationsSz,\n                                 kdfParamsSeq);\n    totalSz += kdfParamsSeqSz;\n\n    /* set KDF algo OID */\n    ret = wc_SetContentType(kdfOID, kdfAlgoId, sizeof(kdfAlgoId));\n    if (ret <= 0) {\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n    kdfAlgoIdSz = ret;\n    totalSz += kdfAlgoIdSz;\n\n    /* set KeyDerivationAlgorithmIdentifier EXPLICIT [0] SEQ */\n    kdfAlgoIdSeqSz = SetExplicit(0, kdfAlgoIdSz + kdfParamsSeqSz +\n                                 kdfSaltOctetStrSz + saltSz + kdfIterationsSz,\n                                 kdfAlgoIdSeq);\n    totalSz += kdfAlgoIdSeqSz;\n\n    /* set PasswordRecipientInfo CMSVersion, MUST be 0 */\n    verSz = SetMyVersion(0, ver, 0);\n    totalSz += verSz;\n    recip->recipVersion = 0;\n\n    /* set PasswordRecipientInfo SEQ */\n    recipSeqSz = SetImplicit(ASN_SEQUENCE, 3, totalSz, recipSeq);\n    totalSz += recipSeqSz;\n\n    if (totalSz > MAX_RECIP_SZ) {\n        WOLFSSL_MSG(\"CMS Recipient output buffer too small\");\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return BUFFER_E;\n    }\n\n    idx = 0;\n    XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);\n    idx += recipSeqSz;\n    XMEMCPY(recip->recip + idx, ver, verSz);\n    idx += verSz;\n    XMEMCPY(recip->recip + idx, kdfAlgoIdSeq, kdfAlgoIdSeqSz);\n    idx += kdfAlgoIdSeqSz;\n    XMEMCPY(recip->recip + idx, kdfAlgoId, kdfAlgoIdSz);\n    idx += kdfAlgoIdSz;\n    XMEMCPY(recip->recip + idx, kdfParamsSeq, kdfParamsSeqSz);\n    idx += kdfParamsSeqSz;\n    XMEMCPY(recip->recip + idx, kdfSaltOctetStr, kdfSaltOctetStrSz);\n    idx += kdfSaltOctetStrSz;\n    XMEMCPY(recip->recip + idx, salt, saltSz);\n    idx += saltSz;\n    XMEMCPY(recip->recip + idx, kdfIterations, kdfIterationsSz);\n    idx += kdfIterationsSz;\n    XMEMCPY(recip->recip + idx, keyEncAlgoIdSeq, keyEncAlgoIdSeqSz);\n    idx += keyEncAlgoIdSeqSz;\n    XMEMCPY(recip->recip + idx, keyEncAlgoId, keyEncAlgoIdSz);\n    idx += keyEncAlgoIdSz;\n    XMEMCPY(recip->recip + idx, pwriEncAlgoId, pwriEncAlgoIdSz);\n    idx += pwriEncAlgoIdSz;\n    XMEMCPY(recip->recip + idx, ivOctetString, ivOctetStringSz);\n    idx += ivOctetStringSz;\n    XMEMCPY(recip->recip + idx, tmpIv, kekBlockSz);\n    idx += kekBlockSz;\n    XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);\n    idx += encKeyOctetStrSz;\n    XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);\n    idx += encryptedKeySz;\n\n    ForceZero(kek, kekBlockSz);\n    ForceZero(encryptedKey, encryptedKeySz);\n    XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n\n    /* store recipient size */\n    recip->recipSz = idx;\n    recip->recipType = PKCS7_PWRI;\n\n    /* add recipient to recip list */\n    if (pkcs7->recipList == NULL) {\n        pkcs7->recipList = recip;\n    } else {\n        lastRecip = pkcs7->recipList;\n        while (lastRecip->next != NULL) {\n            lastRecip = lastRecip->next;\n        }\n        lastRecip->next = recip;\n    }\n\n    (void)options;\n\n    return idx;\n}\n\n/* Import password and KDF settings into a PKCS7 structure. Used for setting\n * the password info for decryption a EnvelopedData PWRI RecipientInfo.\n *\n * Returns 0 on success, negative upon error */\nint wc_PKCS7_SetPassword(PKCS7* pkcs7, byte* passwd, word32 pLen)\n{\n    if (pkcs7 == NULL || passwd == NULL || pLen == 0)\n        return BAD_FUNC_ARG;\n\n    pkcs7->pass = passwd;\n    pkcs7->passSz = pLen;\n\n    return 0;\n}\n\n#endif /* NO_PWDBASED */\n\n\n/* Encode and add CMS EnvelopedData KEKRI (KEKRecipientInfo) RecipientInfo\n * to CMS/PKCS#7 EnvelopedData structure.\n *\n * pkcs7 - pointer to initialized PKCS7 structure\n * keyWrapOID - OID sum of key wrap algorithm identifier\n * kek        - key encryption key\n * kekSz      - size of kek, bytes\n * keyID      - key-encryption key identifier, pre-distributed to endpoints\n * keyIDSz    - size of keyID, bytes\n * timePtr    - pointer to \"time_t\", which is typically \"long\" (OPTIONAL)\n * otherOID   - ASN.1 encoded OID of other attribute (OPTIONAL)\n * otherOIDSz - size of otherOID, bytes (OPTIONAL)\n * other      - other attribute (OPTIONAL)\n * otherSz    - size of other (OPTIONAL)\n *\n * Returns 0 on success, negative upon error */\nint wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID, byte* kek,\n                                word32 kekSz, byte* keyId, word32 keyIdSz,\n                                void* timePtr, byte* otherOID,\n                                word32 otherOIDSz, byte* other, word32 otherSz,\n                                int options)\n{\n    Pkcs7EncodedRecip* recip = NULL;\n    Pkcs7EncodedRecip* lastRecip = NULL;\n\n    byte recipSeq[MAX_SEQ_SZ];\n    byte ver[MAX_VERSION_SZ];\n    byte kekIdSeq[MAX_SEQ_SZ];\n    byte kekIdOctetStr[MAX_OCTET_STR_SZ];\n    byte genTime[ASN_GENERALIZED_TIME_SIZE];\n    byte otherAttSeq[MAX_SEQ_SZ];\n    byte encAlgoId[MAX_ALGO_SZ];\n    byte encKeyOctetStr[MAX_OCTET_STR_SZ];\n#ifdef WOLFSSL_SMALL_STACK\n    byte* encryptedKey;\n#else\n    byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];\n#endif\n\n    int blockKeySz = 0, ret = 0, direction;\n    word32 idx = 0;\n    word32 totalSz = 0;\n    word32 recipSeqSz = 0, verSz = 0;\n    word32 kekIdSeqSz = 0, kekIdOctetStrSz = 0;\n    word32 otherAttSeqSz = 0, encAlgoIdSz = 0, encKeyOctetStrSz = 0;\n    int encryptedKeySz;\n\n    int timeSz = 0;\n#ifndef NO_ASN_TIME\n    time_t* tm = NULL;\n#endif\n\n    if (pkcs7 == NULL || kek == NULL || keyId == NULL)\n        return BAD_FUNC_ARG;\n\n    recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,\n                                 DYNAMIC_TYPE_PKCS7);\n    if (recip == NULL)\n        return MEMORY_E;\n\n    XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));\n\n    /* get key size for content-encryption key based on algorithm */\n    blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);\n    if (blockKeySz < 0) {\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return blockKeySz;\n    }\n\n    /* generate random content encryption key, if needed */\n    ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);\n    if (ret < 0) {\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    /* EncryptedKey */\n#ifdef WOLFSSL_SMALL_STACK\n    encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,\n                                  DYNAMIC_TYPE_PKCS7);\n    if (encryptedKey == NULL) {\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return MEMORY_E;\n    }\n#endif\n    encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;\n    XMEMSET(encryptedKey, 0, encryptedKeySz);\n\n    #ifndef NO_AES\n        direction = AES_ENCRYPTION;\n    #else\n        direction = DES_ENCRYPTION;\n    #endif\n\n    encryptedKeySz = wc_PKCS7_KeyWrap(pkcs7->cek, pkcs7->cekSz, kek, kekSz,\n                                      encryptedKey, encryptedKeySz, keyWrapOID,\n                                      direction);\n    if (encryptedKeySz < 0) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    #endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return encryptedKeySz;\n    }\n    /* handle a zero size encKey case as WC_KEY_SIZE_E */\n    if (encryptedKeySz == 0 || encryptedKeySz > MAX_ENCRYPTED_KEY_SZ) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    #endif\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return WC_KEY_SIZE_E;\n    }\n\n    encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);\n    totalSz += (encKeyOctetStrSz + encryptedKeySz);\n\n    /* KeyEncryptionAlgorithmIdentifier */\n    encAlgoIdSz = SetAlgoID(keyWrapOID, encAlgoId, oidKeyWrapType, 0);\n    totalSz += encAlgoIdSz;\n\n    /* KEKIdentifier: keyIdentifier */\n    kekIdOctetStrSz = SetOctetString(keyIdSz, kekIdOctetStr);\n    totalSz += (kekIdOctetStrSz + keyIdSz);\n\n    /* KEKIdentifier: GeneralizedTime (OPTIONAL) */\n#ifndef NO_ASN_TIME\n    if (timePtr != NULL) {\n        tm = (time_t*)timePtr;\n        timeSz = GetAsnTimeString(tm, genTime, sizeof(genTime));\n        if (timeSz < 0) {\n            XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        #endif\n            return timeSz;\n        }\n        totalSz += timeSz;\n    }\n#endif\n\n    /* KEKIdentifier: OtherKeyAttribute SEQ (OPTIONAL) */\n    if (other != NULL && otherSz > 0) {\n        otherAttSeqSz = SetSequence(otherOIDSz + otherSz, otherAttSeq);\n        totalSz += otherAttSeqSz + otherOIDSz + otherSz;\n    }\n\n    /* KEKIdentifier SEQ */\n    kekIdSeqSz = SetSequence(kekIdOctetStrSz + keyIdSz + timeSz +\n                             otherAttSeqSz + otherOIDSz + otherSz, kekIdSeq);\n    totalSz += kekIdSeqSz;\n\n    /* version */\n    verSz = SetMyVersion(4, ver, 0);\n    totalSz += verSz;\n    recip->recipVersion = 4;\n\n    /* KEKRecipientInfo SEQ */\n    recipSeqSz = SetImplicit(ASN_SEQUENCE, 2, totalSz, recipSeq);\n    totalSz += recipSeqSz;\n\n    if (totalSz > MAX_RECIP_SZ) {\n        WOLFSSL_MSG(\"CMS Recipient output buffer too small\");\n        XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    #endif\n        return BUFFER_E;\n    }\n\n    XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);\n    idx += recipSeqSz;\n    XMEMCPY(recip->recip + idx, ver, verSz);\n    idx += verSz;\n    XMEMCPY(recip->recip + idx, kekIdSeq, kekIdSeqSz);\n    idx += kekIdSeqSz;\n    XMEMCPY(recip->recip + idx, kekIdOctetStr, kekIdOctetStrSz);\n    idx += kekIdOctetStrSz;\n    XMEMCPY(recip->recip + idx, keyId, keyIdSz);\n    idx += keyIdSz;\n    if (timePtr != NULL) {\n        XMEMCPY(recip->recip + idx, genTime, timeSz);\n        idx += timeSz;\n    }\n    if (other != NULL && otherSz > 0) {\n        XMEMCPY(recip->recip + idx, otherAttSeq, otherAttSeqSz);\n        idx += otherAttSeqSz;\n        XMEMCPY(recip->recip + idx, otherOID, otherOIDSz);\n        idx += otherOIDSz;\n        XMEMCPY(recip->recip + idx, other, otherSz);\n        idx += otherSz;\n    }\n    XMEMCPY(recip->recip + idx, encAlgoId, encAlgoIdSz);\n    idx += encAlgoIdSz;\n    XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);\n    idx += encKeyOctetStrSz;\n    XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);\n    idx += encryptedKeySz;\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n#endif\n\n    /* store recipient size */\n    recip->recipSz = idx;\n    recip->recipType = PKCS7_KEKRI;\n\n    /* add recipient to recip list */\n    if (pkcs7->recipList == NULL) {\n        pkcs7->recipList = recip;\n    } else {\n        lastRecip = pkcs7->recipList;\n        while(lastRecip->next != NULL) {\n            lastRecip = lastRecip->next;\n        }\n        lastRecip->next = recip;\n    }\n\n    (void)options;\n\n    return idx;\n}\n\n\nstatic int wc_PKCS7_GetCMSVersion(PKCS7* pkcs7, int cmsContentType)\n{\n    int version = -1;\n\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    switch (cmsContentType) {\n        case ENVELOPED_DATA:\n\n            /* NOTE: EnvelopedData does not currently support\n               originatorInfo or unprotectedAttributes. When either of these\n               are added, version checking below needs to be updated to match\n               Section 6.1 of RFC 5652 */\n\n            /* if RecipientInfos include pwri or ori, version is 3 */\n            if (wc_PKCS7_RecipientListIncludesType(pkcs7, PKCS7_PWRI) ||\n                wc_PKCS7_RecipientListIncludesType(pkcs7, PKCS7_ORI)) {\n                version = 3;\n                break;\n            }\n\n            /* if unprotectedAttrs is absent AND all RecipientInfo structs\n               are version 0, version is 0 */\n            if (wc_PKCS7_RecipientListVersionsAllZero(pkcs7)) {\n                version = 0;\n                break;\n            }\n\n            /* otherwise, version is 2 */\n            version = 2;\n            break;\n\n        default:\n            break;\n    }\n\n    return version;\n}\n\n\n/* build PKCS#7 envelopedData content type, return enveloped size */\nint wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)\n{\n    int ret, idx = 0;\n    int totalSz, padSz, encryptedOutSz;\n\n    int contentInfoSeqSz = 0, outerContentTypeSz = 0, outerContentSz;\n    byte contentInfoSeq[MAX_SEQ_SZ];\n    byte outerContentType[MAX_ALGO_SZ];\n    byte outerContent[MAX_SEQ_SZ];\n\n    int kariVersion;\n    int envDataSeqSz, verSz;\n    byte envDataSeq[MAX_SEQ_SZ];\n    byte ver[MAX_VERSION_SZ];\n\n    WC_RNG rng;\n    int blockSz, blockKeySz;\n    byte* plain;\n    byte* encryptedContent;\n\n    Pkcs7EncodedRecip* tmpRecip = NULL;\n    int recipSz, recipSetSz;\n    byte recipSet[MAX_SET_SZ];\n\n    int encContentOctetSz, encContentSeqSz, contentTypeSz;\n    int contentEncAlgoSz, ivOctetStringSz;\n    byte encContentSeq[MAX_SEQ_SZ];\n    byte contentType[MAX_ALGO_SZ];\n    byte contentEncAlgo[MAX_ALGO_SZ];\n    byte tmpIv[MAX_CONTENT_IV_SIZE];\n    byte ivOctetString[MAX_OCTET_STR_SZ];\n    byte encContentOctet[MAX_OCTET_STR_SZ];\n\n    if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0)\n        return BAD_FUNC_ARG;\n\n    if (output == NULL || outputSz == 0)\n        return BAD_FUNC_ARG;\n\n    blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);\n    if (blockKeySz < 0)\n        return blockKeySz;\n\n    blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);\n    if (blockSz < 0)\n        return blockSz;\n\n    if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {\n        /* outer content type */\n        ret = wc_SetContentType(ENVELOPED_DATA, outerContentType,\n                                sizeof(outerContentType));\n        if (ret < 0)\n            return ret;\n\n        outerContentTypeSz = ret;\n    }\n\n    /* generate random content encryption key */\n    ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);\n    if (ret != 0) {\n        return ret;\n    }\n\n    /* build RecipientInfo, only if user manually set singleCert and size */\n    if (pkcs7->singleCert != NULL && pkcs7->singleCertSz > 0) {\n        switch (pkcs7->publicKeyOID) {\n        #ifndef NO_RSA\n            case RSAk:\n                ret = wc_PKCS7_AddRecipient_KTRI(pkcs7, pkcs7->singleCert,\n                                                 pkcs7->singleCertSz, 0);\n                break;\n        #endif\n        #ifdef HAVE_ECC\n            case ECDSAk:\n                ret = wc_PKCS7_AddRecipient_KARI(pkcs7, pkcs7->singleCert,\n                                                 pkcs7->singleCertSz,\n                                                 pkcs7->keyWrapOID,\n                                                 pkcs7->keyAgreeOID, pkcs7->ukm,\n                                                 pkcs7->ukmSz, 0);\n                break;\n        #endif\n\n            default:\n                WOLFSSL_MSG(\"Unsupported RecipientInfo public key type\");\n                return BAD_FUNC_ARG;\n        };\n\n        if (ret < 0) {\n            WOLFSSL_MSG(\"Failed to create RecipientInfo\");\n            return ret;\n        }\n    }\n\n    recipSz = wc_PKCS7_GetRecipientListSize(pkcs7);\n    if (recipSz < 0) {\n        return ret;\n\n    } else if (recipSz == 0) {\n        WOLFSSL_MSG(\"You must add at least one CMS recipient\");\n        return PKCS7_RECIP_E;\n    }\n    recipSetSz = SetSet(recipSz, recipSet);\n\n    /* version, defined in Section 6.1 of RFC 5652 */\n    kariVersion = wc_PKCS7_GetCMSVersion(pkcs7, ENVELOPED_DATA);\n    if (kariVersion < 0) {\n        WOLFSSL_MSG(\"Failed to set CMS EnvelopedData version\");\n        return PKCS7_RECIP_E;\n    }\n\n    verSz = SetMyVersion(kariVersion, ver, 0);\n\n    ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);\n    if (ret != 0)\n        return ret;\n\n    /* generate IV for block cipher */\n    ret = wc_PKCS7_GenerateBlock(pkcs7, &rng, tmpIv, blockSz);\n    wc_FreeRng(&rng);\n    if (ret != 0)\n        return ret;\n\n    /* EncryptedContentInfo */\n    ret = wc_SetContentType(pkcs7->contentOID, contentType,\n                            sizeof(contentType));\n    if (ret < 0)\n        return ret;\n\n    contentTypeSz = ret;\n\n    /* allocate encrypted content buffer and PKCS#7 padding */\n    padSz = wc_PKCS7_GetPadSize(pkcs7->contentSz, blockSz);\n    if (padSz < 0)\n        return padSz;\n\n    encryptedOutSz = pkcs7->contentSz + padSz;\n\n    plain = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (plain == NULL)\n        return MEMORY_E;\n\n    ret = wc_PKCS7_PadData(pkcs7->content, pkcs7->contentSz, plain,\n                           encryptedOutSz, blockSz);\n    if (ret < 0) {\n        XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,\n                                      DYNAMIC_TYPE_PKCS7);\n    if (encryptedContent == NULL) {\n        XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return MEMORY_E;\n    }\n\n    /* put together IV OCTET STRING */\n    ivOctetStringSz = SetOctetString(blockSz, ivOctetString);\n\n    /* build up our ContentEncryptionAlgorithmIdentifier sequence,\n     * adding (ivOctetStringSz + blockSz) for IV OCTET STRING */\n    contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,\n                                 oidBlkType, ivOctetStringSz + blockSz);\n\n    if (contentEncAlgoSz == 0) {\n        XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return BAD_FUNC_ARG;\n    }\n\n    /* encrypt content */\n    ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->cek,\n            pkcs7->cekSz, tmpIv, blockSz, NULL, 0, NULL, 0, plain,\n            encryptedOutSz, encryptedContent);\n\n    if (ret != 0) {\n        XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz,\n                                    encContentOctet);\n\n    encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +\n                                  ivOctetStringSz + blockSz +\n                                  encContentOctetSz + encryptedOutSz,\n                                  encContentSeq);\n\n    /* keep track of sizes for outer wrapper layering */\n    totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +\n              contentEncAlgoSz + ivOctetStringSz + blockSz +\n              encContentOctetSz + encryptedOutSz;\n\n    /* EnvelopedData */\n    envDataSeqSz = SetSequence(totalSz, envDataSeq);\n    totalSz += envDataSeqSz;\n\n    /* outer content */\n    outerContentSz = SetExplicit(0, totalSz, outerContent);\n    totalSz += outerContentTypeSz;\n    totalSz += outerContentSz;\n\n    if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {\n        /* ContentInfo */\n        contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);\n        totalSz += contentInfoSeqSz;\n    }\n\n    if (totalSz > (int)outputSz) {\n        WOLFSSL_MSG(\"Pkcs7_encrypt output buffer too small\");\n        XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return BUFFER_E;\n    }\n\n    if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {\n        XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);\n        idx += contentInfoSeqSz;\n        XMEMCPY(output + idx, outerContentType, outerContentTypeSz);\n        idx += outerContentTypeSz;\n        XMEMCPY(output + idx, outerContent, outerContentSz);\n        idx += outerContentSz;\n    }\n    XMEMCPY(output + idx, envDataSeq, envDataSeqSz);\n    idx += envDataSeqSz;\n    XMEMCPY(output + idx, ver, verSz);\n    idx += verSz;\n    XMEMCPY(output + idx, recipSet, recipSetSz);\n    idx += recipSetSz;\n    /* copy in recipients from list */\n    tmpRecip = pkcs7->recipList;\n    while (tmpRecip != NULL) {\n        XMEMCPY(output + idx, tmpRecip->recip, tmpRecip->recipSz);\n        idx += tmpRecip->recipSz;\n        tmpRecip = tmpRecip->next;\n    }\n    wc_PKCS7_FreeEncodedRecipientSet(pkcs7);\n    XMEMCPY(output + idx, encContentSeq, encContentSeqSz);\n    idx += encContentSeqSz;\n    XMEMCPY(output + idx, contentType, contentTypeSz);\n    idx += contentTypeSz;\n    XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);\n    idx += contentEncAlgoSz;\n    XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);\n    idx += ivOctetStringSz;\n    XMEMCPY(output + idx, tmpIv, blockSz);\n    idx += blockSz;\n    XMEMCPY(output + idx, encContentOctet, encContentOctetSz);\n    idx += encContentOctetSz;\n    XMEMCPY(output + idx, encryptedContent, encryptedOutSz);\n    idx += encryptedOutSz;\n\n    XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n\n    return idx;\n}\n\n#ifndef NO_RSA\n/* decode KeyTransRecipientInfo (ktri), return 0 on success, <0 on error */\nstatic int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz,\n                               word32* idx, byte* decryptedKey,\n                               word32* decryptedKeySz, int* recipFound)\n{\n    int length, encryptedKeySz = 0, ret = 0;\n    int keySz, version, sidType = 0;\n    word32 encOID;\n    word32 keyIdx;\n    byte   issuerHash[KEYID_SIZE];\n    byte*  outKey   = NULL;\n    byte* pkiMsg    = in;\n    word32 pkiMsgSz = inSz;\n    byte   tag;\n\n\n#ifndef NO_PKCS7_STREAM\n    word32 tmpIdx = *idx;\n    long rc;\n#endif\n#ifdef WC_RSA_BLINDING\n    WC_RNG rng;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int* serialNum  = NULL;\n    byte* encryptedKey = NULL;\n    RsaKey* privKey    = NULL;\n#else\n    mp_int serialNum[1];\n    byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];\n    RsaKey privKey[1];\n#endif\n\n    switch (pkcs7->state) {\n        case WC_PKCS7_DECRYPT_KTRI:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_VERSION_SZ,\n                            &pkiMsg, idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,\n                    in, inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n\n        #endif\n            if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            if (version == 0) {\n                sidType = CMS_ISSUER_AND_SERIAL_NUMBER;\n            } else if (version == 2) {\n                sidType = CMS_SKID;\n            } else {\n                return ASN_VERSION_E;\n            }\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                    break;\n            }\n            wc_PKCS7_StreamStoreVar(pkcs7, 0, sidType, version);\n\n            /* @TODO getting total amount left because of GetInt call later on\n             * this could be optimized to stream better */\n            pkcs7->stream->expected = (pkcs7->stream->maxLen -\n                                pkcs7->stream->totalRd) + pkcs7->stream->length;\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_2);\n            FALL_THROUGH;\n\n        case WC_PKCS7_DECRYPT_KTRI_2:\n        #ifndef NO_PKCS7_STREAM\n\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, pkcs7->stream->expected,\n                            &pkiMsg, idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,\n                    in, inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n\n            wc_PKCS7_StreamGetVar(pkcs7, NULL, &sidType, &version);\n\n            /* @TODO get expected size for next part, does not account for\n             * GetInt call well */\n            if (pkcs7->stream->expected == MAX_SEQ_SZ) {\n                int sz;\n                word32 lidx;\n\n                if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {\n                    lidx = *idx;\n                    ret = GetSequence(pkiMsg, &lidx, &sz, pkiMsgSz);\n                    if (ret < 0)\n                        return ret;\n                }\n                else {\n                    lidx = *idx + ASN_TAG_SZ;\n                    ret = GetLength(pkiMsg, &lidx, &sz, pkiMsgSz);\n                    if (ret < 0)\n                        return ret;\n                }\n\n                pkcs7->stream->expected = sz + MAX_ALGO_SZ + ASN_TAG_SZ +\n                                          MAX_LENGTH_SZ;\n                if (pkcs7->stream->length > 0 &&\n                        pkcs7->stream->length < pkcs7->stream->expected) {\n                    return WC_PKCS7_WANT_READ_E;\n                }\n            }\n        #endif /* !NO_PKCS7_STREAM */\n\n            if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {\n\n                /* remove IssuerAndSerialNumber */\n                if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)\n                    return ASN_PARSE_E;\n\n                if (GetNameHash(pkiMsg, idx, issuerHash, pkiMsgSz) < 0)\n                    return ASN_PARSE_E;\n\n                /* if we found correct recipient, issuer hashes will match */\n                if (XMEMCMP(issuerHash, pkcs7->issuerHash, KEYID_SIZE) == 0) {\n                    *recipFound = 1;\n                }\n\n        #ifdef WOLFSSL_SMALL_STACK\n                serialNum = (mp_int*)XMALLOC(sizeof(mp_int), pkcs7->heap,\n                                             DYNAMIC_TYPE_TMP_BUFFER);\n                if (serialNum == NULL)\n                    return MEMORY_E;\n        #endif\n\n                if (GetInt(serialNum, pkiMsg, idx, pkiMsgSz) < 0) {\n        #ifdef WOLFSSL_SMALL_STACK\n                    XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n                    return ASN_PARSE_E;\n                }\n\n                mp_clear(serialNum);\n\n        #ifdef WOLFSSL_SMALL_STACK\n                XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n\n            } else {\n                /* remove SubjectKeyIdentifier */\n                if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)\n                    return ASN_PARSE_E;\n\n                if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))\n                    return ASN_PARSE_E;\n\n                if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)\n                    return ASN_PARSE_E;\n\n                if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)\n                    return ASN_PARSE_E;\n\n                if (tag != ASN_OCTET_STRING)\n                    return ASN_PARSE_E;\n\n                if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)\n                    return ASN_PARSE_E;\n\n                /* if we found correct recipient, SKID will match */\n                if (XMEMCMP(pkiMsg + (*idx), pkcs7->issuerSubjKeyId,\n                            KEYID_SIZE) == 0) {\n                    *recipFound = 1;\n                }\n                (*idx) += KEYID_SIZE;\n            }\n\n            if (GetAlgoId(pkiMsg, idx, &encOID, oidKeyType, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            /* key encryption algorithm must be RSA for now */\n            if (encOID != RSAk)\n                return ALGO_ID_E;\n\n            /* read encryptedKey */\n            if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            if (tag != ASN_OCTET_STRING)\n                return ASN_PARSE_E;\n\n            if (GetLength(pkiMsg, idx, &encryptedKeySz, pkiMsgSz) < 0) {\n                return ASN_PARSE_E;\n            }\n            if (encryptedKeySz > MAX_ENCRYPTED_KEY_SZ) {\n               return BUFFER_E;\n            }\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                    break;\n            }\n            wc_PKCS7_StreamStoreVar(pkcs7, encryptedKeySz, sidType, version);\n            pkcs7->stream->expected = encryptedKeySz;\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_3);\n            FALL_THROUGH;\n\n        case WC_PKCS7_DECRYPT_KTRI_3:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                            pkcs7->stream->expected, &pkiMsg, idx)) != 0) {\n                return ret;\n            }\n            encryptedKeySz = pkcs7->stream->expected;\n        #endif\n\n        #ifdef WOLFSSL_SMALL_STACK\n            encryptedKey = (byte*)XMALLOC(encryptedKeySz, pkcs7->heap,\n                                          DYNAMIC_TYPE_TMP_BUFFER);\n            if (encryptedKey == NULL)\n                return MEMORY_E;\n        #endif\n\n            if (*recipFound == 1)\n                XMEMCPY(encryptedKey, &pkiMsg[*idx], encryptedKeySz);\n            *idx += encryptedKeySz;\n\n            /* load private key */\n        #ifdef WOLFSSL_SMALL_STACK\n            privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,\n                DYNAMIC_TYPE_TMP_BUFFER);\n            if (privKey == NULL) {\n                XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n                return MEMORY_E;\n            }\n        #endif\n\n            ret = wc_InitRsaKey_ex(privKey, pkcs7->heap, INVALID_DEVID);\n            if (ret != 0) {\n        #ifdef WOLFSSL_SMALL_STACK\n                XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n                XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n                return ret;\n            }\n\n            if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {\n                keyIdx = 0;\n                ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &keyIdx,\n                        privKey, pkcs7->privateKeySz);\n            }\n            else if (pkcs7->devId == INVALID_DEVID) {\n                ret = BAD_FUNC_ARG;\n            }\n            if (ret != 0) {\n                WOLFSSL_MSG(\"Failed to decode RSA private key\");\n                wc_FreeRsaKey(privKey);\n        #ifdef WOLFSSL_SMALL_STACK\n                XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n                XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n                return ret;\n            }\n\n            /* decrypt encryptedKey */\n            #ifdef WC_RSA_BLINDING\n            ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);\n            if (ret == 0) {\n                ret = wc_RsaSetRNG(privKey, &rng);\n            }\n            #endif\n            if (ret == 0) {\n                keySz = wc_RsaPrivateDecryptInline(encryptedKey, encryptedKeySz,\n                                                   &outKey, privKey);\n                #ifdef WC_RSA_BLINDING\n                    wc_FreeRng(&rng);\n                #endif\n            } else {\n                keySz = ret;\n            }\n            wc_FreeRsaKey(privKey);\n\n            if (keySz <= 0 || outKey == NULL) {\n                ForceZero(encryptedKey, encryptedKeySz);\n        #ifdef WOLFSSL_SMALL_STACK\n                XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n                XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n                return keySz;\n            } else {\n                *decryptedKeySz = keySz;\n                XMEMCPY(decryptedKey, outKey, keySz);\n                ForceZero(encryptedKey, encryptedKeySz);\n            }\n\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                break;\n            }\n        #endif\n            ret = 0; /* success */\n            break;\n\n        default:\n            WOLFSSL_MSG(\"PKCS7 Unknown KTRI decrypt state\");\n            ret = BAD_FUNC_ARG;\n    }\n\n    return ret;\n}\n#endif /* !NO_RSA */\n\n#ifdef HAVE_ECC\n\n/* remove ASN.1 OriginatorIdentifierOrKey, return 0 on success, <0 on error */\nstatic int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari,\n                        byte* pkiMsg, word32 pkiMsgSz, word32* idx)\n{\n    int ret, length;\n    word32 keyOID, oidSum = 0;\n    int curve_id = ECC_CURVE_DEF;\n    byte tag;\n\n    if (kari == NULL || pkiMsg == NULL || idx == NULL)\n        return BAD_FUNC_ARG;\n\n    /* remove OriginatorIdentifierOrKey */\n    if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) == 0 &&\n            tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {\n        if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)\n            return ASN_PARSE_E;\n\n    } else {\n        return ASN_PARSE_E;\n    }\n\n    /* remove OriginatorPublicKey */\n    if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) == 0 &&\n            tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {\n        if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)\n            return ASN_PARSE_E;\n\n    } else {\n        return ASN_PARSE_E;\n    }\n\n    /* remove AlgorithmIdentifier */\n    if (GetAlgoId(pkiMsg, idx, &keyOID, oidKeyType, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    if (keyOID != ECDSAk)\n        return ASN_PARSE_E;\n\n    /* optional algorithm parameters */\n    ret = GetObjectId(pkiMsg, idx, &oidSum, oidIgnoreType, pkiMsgSz);\n    if (ret == 0) {\n        /* get curve id */\n        curve_id = wc_ecc_get_oid(oidSum, NULL, 0);\n        if (curve_id < 0)\n            return ECC_CURVE_OID_E;\n    }\n\n    /* remove ECPoint BIT STRING */\n    if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    if (tag != ASN_BIT_STRING)\n        return ASN_PARSE_E;\n\n    if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)\n        return ASN_EXPECT_0_E;\n\n    if (tag != ASN_OTHER_TYPE)\n        return ASN_EXPECT_0_E;\n\n    /* get sender ephemeral public ECDSA key */\n    ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId);\n    if (ret != 0)\n        return ret;\n\n    kari->senderKeyInit = 1;\n\n    /* length-1 for unused bits counter */\n    ret = wc_ecc_import_x963_ex(pkiMsg + (*idx), length - 1, kari->senderKey,\n            curve_id);\n    if (ret != 0) {\n        ret = wc_EccPublicKeyDecode(pkiMsg, idx, kari->senderKey, *idx + length - 1);\n        if (ret != 0)\n            return ret;\n    }\n    else {\n        (*idx) += length - 1;\n    }\n\n    return 0;\n}\n\n\n/* remove optional UserKeyingMaterial if available, return 0 on success,\n * < 0 on error */\nstatic int wc_PKCS7_KariGetUserKeyingMaterial(WC_PKCS7_KARI* kari,\n                        byte* pkiMsg, word32 pkiMsgSz, word32* idx)\n{\n    int length;\n    word32 savedIdx;\n    byte tag;\n\n    if (kari == NULL || pkiMsg == NULL || idx == NULL)\n        return BAD_FUNC_ARG;\n\n    savedIdx = *idx;\n\n    /* starts with EXPLICIT [1] */\n    if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {\n        *idx = savedIdx;\n        return 0;\n    }\n    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {\n        *idx = savedIdx;\n        return 0;\n    }\n\n    if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {\n        *idx = savedIdx;\n        return 0;\n    }\n\n    /* get OCTET STRING */\n    if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {\n        *idx = savedIdx;\n        return 0;\n    }\n    if (tag != ASN_OCTET_STRING) {\n        *idx = savedIdx;\n        return 0;\n    }\n\n    if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {\n        *idx = savedIdx;\n        return 0;\n    }\n\n    kari->ukm = NULL;\n    if (length > 0) {\n        kari->ukm = (byte*)XMALLOC(length, kari->heap, DYNAMIC_TYPE_PKCS7);\n        if (kari->ukm == NULL)\n            return MEMORY_E;\n\n        XMEMCPY(kari->ukm, pkiMsg + (*idx), length);\n        kari->ukmOwner = 1;\n    }\n\n    (*idx) += length;\n    kari->ukmSz = length;\n\n    return 0;\n}\n\n\n/* remove ASN.1 KeyEncryptionAlgorithmIdentifier, return 0 on success,\n * < 0 on error */\nstatic int wc_PKCS7_KariGetKeyEncryptionAlgorithmId(WC_PKCS7_KARI* kari,\n        byte* pkiMsg, word32 pkiMsgSz, word32* idx,\n        word32* keyAgreeOID, word32* keyWrapOID)\n{\n    int length = 0;\n    word32 localIdx;\n\n    if (kari == NULL || pkiMsg == NULL || idx == NULL ||\n        keyAgreeOID == NULL || keyWrapOID == NULL)\n        return BAD_FUNC_ARG;\n\n    localIdx = *idx;\n\n    /* remove KeyEncryptionAlgorithmIdentifier */\n    if (GetSequence(pkiMsg, &localIdx, &length, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    localIdx = *idx;\n    if (GetAlgoId(pkiMsg, &localIdx, keyAgreeOID, oidCmsKeyAgreeType,\n              pkiMsgSz) < 0) {\n        return ASN_PARSE_E;\n    }\n\n    if (localIdx < *idx + length) {\n        *idx = localIdx;\n    }\n    /* remove KeyWrapAlgorithm, stored in parameter of KeyEncAlgoId */\n    if (GetAlgoId(pkiMsg, idx, keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    return 0;\n}\n\n\n/* remove ASN.1 SubjectKeyIdentifier, return 0 on success, < 0 on error\n * if subject key ID matches, recipFound is set to 1 */\nstatic int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari,\n                        byte* pkiMsg, word32 pkiMsgSz, word32* idx,\n                        int* recipFound, byte* rid)\n{\n    int length;\n    byte tag;\n\n    if (kari == NULL || pkiMsg == NULL || idx == NULL || recipFound == NULL ||\n            rid == NULL)\n        return BAD_FUNC_ARG;\n\n    /* remove RecipientKeyIdentifier IMPLICIT [0] */\n    if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {\n        return ASN_PARSE_E;\n    }\n\n    if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {\n        if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)\n            return ASN_PARSE_E;\n\n    } else {\n        return ASN_PARSE_E;\n    }\n\n    /* remove SubjectKeyIdentifier */\n    if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {\n        return ASN_PARSE_E;\n    }\n\n    if (tag != ASN_OCTET_STRING)\n        return ASN_PARSE_E;\n\n    if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    if (length != KEYID_SIZE)\n        return ASN_PARSE_E;\n\n    XMEMCPY(rid, pkiMsg + (*idx), KEYID_SIZE);\n    (*idx) += length;\n\n    /* subject key id should match if recipient found */\n    if (XMEMCMP(rid, kari->decoded->extSubjKeyId, KEYID_SIZE) == 0) {\n        *recipFound = 1;\n    }\n\n    return 0;\n}\n\n\n/* remove ASN.1 IssuerAndSerialNumber, return 0 on success, < 0 on error\n * if issuer and serial number match, recipFound is set to 1 */\nstatic int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,\n                        byte* pkiMsg, word32 pkiMsgSz, word32* idx,\n                        int* recipFound, byte* rid)\n{\n    int length, ret;\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int* serial;\n    mp_int* recipSerial;\n#else\n    mp_int  serial[1];\n    mp_int  recipSerial[1];\n#endif\n\n    if (rid == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* remove IssuerAndSerialNumber */\n    if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    if (GetNameHash(pkiMsg, idx, rid, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    /* if we found correct recipient, issuer hashes will match */\n    if (XMEMCMP(rid, kari->decoded->issuerHash, KEYID_SIZE) == 0) {\n        *recipFound = 1;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    serial = (mp_int*)XMALLOC(sizeof(mp_int), kari->heap,\n                              DYNAMIC_TYPE_TMP_BUFFER);\n    if (serial == NULL)\n        return MEMORY_E;\n\n    recipSerial = (mp_int*)XMALLOC(sizeof(mp_int), kari->heap,\n                                   DYNAMIC_TYPE_TMP_BUFFER);\n    if (recipSerial == NULL) {\n        XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n#endif\n\n    if (GetInt(serial, pkiMsg, idx, pkiMsgSz) < 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(serial,      kari->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return ASN_PARSE_E;\n    }\n\n    ret = mp_read_unsigned_bin(recipSerial, kari->decoded->serial,\n                             kari->decoded->serialSz);\n    if (ret != MP_OKAY) {\n        mp_clear(serial);\n        WOLFSSL_MSG(\"Failed to parse CMS recipient serial number\");\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(serial,      kari->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return ret;\n    }\n\n    if (mp_cmp(recipSerial, serial) != MP_EQ) {\n        mp_clear(serial);\n        mp_clear(recipSerial);\n        WOLFSSL_MSG(\"CMS serial number does not match recipient\");\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(serial,      kari->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return PKCS7_RECIP_E;\n    }\n\n    mp_clear(serial);\n    mp_clear(recipSerial);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(serial,      kari->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return 0;\n}\n\n\n/* remove ASN.1 RecipientEncryptedKeys, return 0 on success, < 0 on error */\nstatic int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,\n                        byte* pkiMsg, word32 pkiMsgSz, word32* idx,\n                        int* recipFound, byte* encryptedKey,\n                        int* encryptedKeySz, byte* rid)\n{\n    int length;\n    int ret = 0;\n    byte tag;\n    word32 localIdx;\n\n    if (kari == NULL || pkiMsg == NULL || idx == NULL ||\n        recipFound == NULL || encryptedKey == NULL)\n        return BAD_FUNC_ARG;\n\n    /* remove RecipientEncryptedKeys */\n    if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    /* remove RecipientEncryptedKeys */\n    if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    /* KeyAgreeRecipientIdentifier is CHOICE of IssuerAndSerialNumber\n     * or [0] IMMPLICIT RecipientKeyIdentifier */\n    localIdx = *idx;\n    if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {\n        /* try to get RecipientKeyIdentifier */\n        ret = wc_PKCS7_KariGetSubjectKeyIdentifier(kari, pkiMsg, pkiMsgSz,\n                                                   idx, recipFound, rid);\n    } else {\n        /* try to get IssuerAndSerialNumber */\n        ret = wc_PKCS7_KariGetIssuerAndSerialNumber(kari, pkiMsg, pkiMsgSz,\n                                                    idx, recipFound, rid);\n    }\n\n    /* if we don't have either option, malformed CMS */\n    if (ret != 0)\n        return ret;\n\n    /* remove EncryptedKey */\n    if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    if (tag != ASN_OCTET_STRING)\n        return ASN_PARSE_E;\n\n    if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    /* put encrypted CEK in decryptedKey buffer for now, decrypt later */\n    if (length > *encryptedKeySz)\n        return BUFFER_E;\n\n    XMEMCPY(encryptedKey, pkiMsg + (*idx), length);\n    *encryptedKeySz = length;\n    (*idx) += length;\n\n    return 0;\n}\n\n#endif /* HAVE_ECC */\n\n\nint wc_PKCS7_SetOriEncryptCtx(PKCS7* pkcs7, void* ctx)\n{\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    pkcs7->oriEncryptCtx = ctx;\n\n    return 0;\n}\n\n\nint wc_PKCS7_SetOriDecryptCtx(PKCS7* pkcs7, void* ctx)\n{\n\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    pkcs7->oriDecryptCtx = ctx;\n\n    return 0;\n}\n\n\nint wc_PKCS7_SetOriDecryptCb(PKCS7* pkcs7, CallbackOriDecrypt cb)\n{\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    pkcs7->oriDecryptCb = cb;\n\n    return 0;\n}\n\n\n/* return 0 on success */\nint wc_PKCS7_SetWrapCEKCb(PKCS7* pkcs7, CallbackWrapCEK cb)\n{\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    pkcs7->wrapCEKCb = cb;\n\n    return 0;\n}\n\n/* Decrypt ASN.1 OtherRecipientInfo (ori), as defined by:\n *\n *   OtherRecipientInfo ::= SEQUENCE {\n *     oriType OBJECT IDENTIFIER,\n *     oriValue ANY DEFINED BY oriType }\n *\n * pkcs7          - pointer to initialized PKCS7 structure\n * pkiMsg         - pointer to encoded CMS bundle\n * pkiMsgSz       - size of pkiMsg, bytes\n * idx            - [IN/OUT] pointer to index into pkiMsg\n * decryptedKey   - [OUT] output buf for decrypted content encryption key\n * decryptedKeySz - [IN/OUT] size of buffer, size of decrypted key\n * recipFound     - [OUT] 1 if recipient has been found, 0 if not\n *\n * Return 0 on success, negative upon error.\n */\nstatic int wc_PKCS7_DecryptOri(PKCS7* pkcs7, byte* in, word32 inSz,\n                               word32* idx, byte* decryptedKey,\n                               word32* decryptedKeySz, int* recipFound)\n{\n    int ret, seqSz, oriOIDSz;\n    word32 oriValueSz, tmpIdx;\n    byte* oriValue;\n    byte oriOID[MAX_OID_SZ];\n\n    byte* pkiMsg    = in;\n    word32 pkiMsgSz = inSz;\n#ifndef NO_PKCS7_STREAM\n    word32 stateIdx = *idx;\n    long rc;\n#endif\n\n    if (pkcs7->oriDecryptCb == NULL) {\n        WOLFSSL_MSG(\"You must register an ORI Decrypt callback\");\n        return BAD_FUNC_ARG;\n    }\n\n    switch (pkcs7->state) {\n\n        case WC_PKCS7_DECRYPT_ORI:\n        #ifndef NO_PKCS7_STREAM\n            /* @TODO for now just get full buffer, needs divided up */\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                   (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +\n                   pkcs7->stream->length, &pkiMsg, idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n        #endif\n            /* get OtherRecipientInfo sequence length */\n            if (GetLength(pkiMsg, idx, &seqSz, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            tmpIdx = *idx;\n\n            /* remove and store oriType OBJECT IDENTIFIER */\n            if (GetASNObjectId(pkiMsg, idx, &oriOIDSz, pkiMsgSz) != 0)\n                return ASN_PARSE_E;\n\n            XMEMCPY(oriOID, pkiMsg + *idx, oriOIDSz);\n            *idx += oriOIDSz;\n\n            /* get oriValue, increment idx */\n            oriValue = pkiMsg + *idx;\n            oriValueSz = seqSz - (*idx - tmpIdx);\n            *idx += oriValueSz;\n\n            /* pass oriOID and oriValue to user callback, expect back\n               decryptedKey and size */\n            ret = pkcs7->oriDecryptCb(pkcs7, oriOID, (word32)oriOIDSz, oriValue,\n                                      oriValueSz, decryptedKey, decryptedKeySz,\n                                      pkcs7->oriDecryptCtx);\n\n            if (ret != 0 || decryptedKey == NULL || *decryptedKeySz == 0) {\n                /* decrypt operation failed */\n                *recipFound = 0;\n                return PKCS7_RECIP_E;\n            }\n\n            /* mark recipFound, since we only support one RecipientInfo for now */\n            *recipFound = 1;\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, idx)) != 0) {\n                break;\n            }\n        #endif\n            ret = 0; /* success */\n            break;\n\n        default:\n            WOLFSSL_MSG(\"PKCS7 ORI unknown state\");\n            ret = BAD_FUNC_ARG;\n\n    }\n\n    return ret;\n}\n\n#if !defined(NO_PWDBASED) && !defined(NO_SHA)\n\n/* decode ASN.1 PasswordRecipientInfo (pwri), return 0 on success,\n * < 0 on error */\nstatic int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz,\n                               word32* idx, byte* decryptedKey,\n                               word32* decryptedKeySz, int* recipFound)\n{\n    byte* salt;\n    byte* cek;\n    byte* kek;\n\n    byte tmpIv[MAX_CONTENT_IV_SIZE];\n\n    int ret = 0, length, saltSz, iterations, blockSz, kekKeySz;\n    int hashOID = WC_SHA; /* default to SHA1 */\n    word32 kdfAlgoId, pwriEncAlgoId, keyEncAlgoId, cekSz;\n    byte* pkiMsg = in;\n    word32 pkiMsgSz = inSz;\n    byte  tag;\n#ifndef NO_PKCS7_STREAM\n    word32 tmpIdx = *idx;\n    long rc;\n#endif\n\n    switch (pkcs7->state) {\n        case WC_PKCS7_DECRYPT_PWRI:\n        #ifndef NO_PKCS7_STREAM\n            /*@TODO for now just get full buffer, needs divided up */\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                   (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +\n                   pkcs7->stream->length, &pkiMsg, idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n        #endif\n            /* remove KeyDerivationAlgorithmIdentifier */\n            if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))\n                return ASN_PARSE_E;\n\n            if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            /* get KeyDerivationAlgorithmIdentifier */\n            if (wc_GetContentType(pkiMsg, idx, &kdfAlgoId, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            /* get KDF params SEQ */\n            if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            /* get KDF salt OCTET STRING */\n            if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            if (tag != ASN_OCTET_STRING)\n                return ASN_PARSE_E;\n\n            if (GetLength(pkiMsg, idx, &saltSz, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            salt = (byte*)XMALLOC(saltSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            if (salt == NULL)\n                return MEMORY_E;\n\n            XMEMCPY(salt, pkiMsg + (*idx), saltSz);\n            *idx += saltSz;\n\n            /* get KDF iterations */\n            if (GetMyVersion(pkiMsg, idx, &iterations, pkiMsgSz) < 0) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ASN_PARSE_E;\n            }\n\n            /* get KeyEncAlgoId SEQ */\n            if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ASN_PARSE_E;\n            }\n\n            /* get KeyEncAlgoId */\n            if (wc_GetContentType(pkiMsg, idx, &keyEncAlgoId, pkiMsgSz) < 0) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ASN_PARSE_E;\n            }\n\n            /* get pwriEncAlgoId */\n            if (GetAlgoId(pkiMsg, idx, &pwriEncAlgoId, oidBlkType, pkiMsgSz) < 0) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ASN_PARSE_E;\n            }\n\n            blockSz = wc_PKCS7_GetOIDBlockSize(pwriEncAlgoId);\n            if (blockSz < 0) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return blockSz;\n            }\n\n            /* get content-encryption key size, based on algorithm */\n            kekKeySz = wc_PKCS7_GetOIDKeySize(pwriEncAlgoId);\n            if (kekKeySz < 0) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return kekKeySz;\n            }\n\n            /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */\n            if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ASN_PARSE_E;\n            }\n\n            if (tag != ASN_OCTET_STRING) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ASN_PARSE_E;\n            }\n\n            if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ASN_PARSE_E;\n            }\n\n            if (length != blockSz) {\n                WOLFSSL_MSG(\"Incorrect IV length, must be of content alg block size\");\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ASN_PARSE_E;\n            }\n\n            XMEMCPY(tmpIv, pkiMsg + (*idx), length);\n            *idx += length;\n\n            /* get EncryptedKey */\n            if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ASN_PARSE_E;\n            }\n\n            if (tag != ASN_OCTET_STRING) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ASN_PARSE_E;\n            }\n\n            if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ASN_PARSE_E;\n            }\n\n            /* allocate temporary space for decrypted key */\n            cekSz = length;\n            cek = (byte*)XMALLOC(cekSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            if (cek == NULL) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return MEMORY_E;\n            }\n\n            /* generate KEK */\n            kek = (byte*)XMALLOC(kekKeySz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            if (kek == NULL) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return MEMORY_E;\n            }\n\n            ret = wc_PKCS7_GenerateKEK_PWRI(pkcs7, pkcs7->pass, pkcs7->passSz,\n                                            salt, saltSz, kdfAlgoId, hashOID,\n                                            iterations, kek, kekKeySz);\n            if (ret < 0) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ASN_PARSE_E;\n            }\n\n            /* decrypt CEK with KEK */\n            ret = wc_PKCS7_PwriKek_KeyUnWrap(pkcs7, kek, kekKeySz,\n                                             pkiMsg + (*idx), length, cek,\n                                             cekSz, tmpIv, blockSz,\n                                             pwriEncAlgoId);\n            if (ret < 0) {\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ret;\n            }\n            cekSz = ret;\n\n            if (*decryptedKeySz < cekSz) {\n                WOLFSSL_MSG(\"Decrypted key buffer too small for CEK\");\n                XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return BUFFER_E;\n            }\n\n            XMEMCPY(decryptedKey, cek, cekSz);\n            *decryptedKeySz = cekSz;\n\n            XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n\n            /* mark recipFound, since we only support one RecipientInfo for now */\n            *recipFound = 1;\n            *idx += length;\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                break;\n            }\n        #endif\n            ret = 0; /* success */\n            break;\n\n        default:\n            WOLFSSL_MSG(\"PKCS7 PWRI unknown state\");\n            ret = BAD_FUNC_ARG;\n    }\n\n    return ret;\n}\n\n#endif /* NO_PWDBASED | NO_SHA */\n\n/* decode ASN.1 KEKRecipientInfo (kekri), return 0 on success,\n * < 0 on error */\nstatic int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz,\n                               word32* idx, byte* decryptedKey,\n                               word32* decryptedKeySz, int* recipFound)\n{\n    int length, keySz, dateLen, direction;\n    byte* keyId = NULL;\n    const byte* datePtr = NULL;\n    byte  dateFormat, tag;\n    word32 keyIdSz, kekIdSz, keyWrapOID, localIdx;\n\n    int ret = 0;\n    byte* pkiMsg    = in;\n    word32 pkiMsgSz = inSz;\n#ifndef NO_PKCS7_STREAM\n    word32 tmpIdx = *idx;\n    long rc;\n#endif\n\n    WOLFSSL_ENTER(\"wc_PKCS7_DecryptKekri\");\n    switch (pkcs7->state) {\n        case WC_PKCS7_DECRYPT_KEKRI:\n        #ifndef NO_PKCS7_STREAM\n            /* @TODO for now just get full buffer, needs divided up */\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                   (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +\n                   pkcs7->stream->length, &pkiMsg, idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n        #endif\n            /* remove KEKIdentifier */\n            if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            kekIdSz = length;\n\n            if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            if (tag != ASN_OCTET_STRING)\n                return ASN_PARSE_E;\n\n            if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            /* save keyIdentifier and length */\n            keyId = pkiMsg + *idx;\n            keyIdSz = length;\n            *idx += keyIdSz;\n\n            /* may have OPTIONAL GeneralizedTime */\n            localIdx = *idx;\n            if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag,\n                        pkiMsgSz) == 0 && tag == ASN_GENERALIZED_TIME) {\n                if (wc_GetDateInfo(pkiMsg + *idx, pkiMsgSz, &datePtr, &dateFormat,\n                                   &dateLen) != 0) {\n                    return ASN_PARSE_E;\n                }\n                *idx += (dateLen + 1);\n            }\n\n            /* may have OPTIONAL OtherKeyAttribute */\n            localIdx = *idx;\n            if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag,\n                            pkiMsgSz) == 0 && tag == (ASN_SEQUENCE |\n                            ASN_CONSTRUCTED)) {\n                if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)\n                    return ASN_PARSE_E;\n\n                /* skip it */\n                *idx += length;\n            }\n\n            /* get KeyEncryptionAlgorithmIdentifier */\n            if (GetAlgoId(pkiMsg, idx, &keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            /* get EncryptedKey */\n            if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            if (tag != ASN_OCTET_STRING)\n                return ASN_PARSE_E;\n\n            if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)\n                return ASN_PARSE_E;\n\n            #ifndef NO_AES\n                direction = AES_DECRYPTION;\n            #else\n                direction = DES_DECRYPTION;\n            #endif\n\n            /* decrypt CEK with KEK */\n            if (pkcs7->wrapCEKCb) {\n                keySz = pkcs7->wrapCEKCb(pkcs7, pkiMsg + *idx, length, keyId,\n                                     keyIdSz, NULL, 0, decryptedKey,\n                                     *decryptedKeySz, keyWrapOID,\n                                     (int)PKCS7_KEKRI, direction);\n            }\n            else {\n                keySz = wc_PKCS7_KeyWrap(pkiMsg + *idx, length, pkcs7->privateKey,\n                                     pkcs7->privateKeySz, decryptedKey, *decryptedKeySz,\n                                     keyWrapOID, direction);\n            }\n            if (keySz <= 0)\n                return keySz;\n\n            *decryptedKeySz = (word32)keySz;\n\n            /* mark recipFound, since we only support one RecipientInfo for now */\n            *recipFound = 1;\n            *idx += length;\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                break;\n            }\n        #endif\n            ret = 0; /* success */\n            break;\n\n        default:\n            WOLFSSL_MSG(\"PKCS7 KEKRI unknown state\");\n            ret = BAD_FUNC_ARG;\n\n    }\n\n    (void)keyId;\n    return ret;\n}\n\n\n/* decode ASN.1 KeyAgreeRecipientInfo (kari), return 0 on success,\n * < 0 on error */\nstatic int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,\n                               word32* idx, byte* decryptedKey,\n                               word32* decryptedKeySz, int* recipFound)\n{\n#ifdef HAVE_ECC\n    int ret, keySz;\n    int encryptedKeySz;\n    int direction = 0;\n    word32 keyAgreeOID, keyWrapOID;\n    byte rid[KEYID_SIZE];\n\n#ifdef WOLFSSL_SMALL_STACK\n    byte* encryptedKey;\n#else\n    byte  encryptedKey[MAX_ENCRYPTED_KEY_SZ];\n#endif\n\n    byte* pkiMsg    = in;\n    word32 pkiMsgSz = inSz;\n#ifndef NO_PKCS7_STREAM\n    word32 tmpIdx = (idx) ? *idx : 0;\n    long rc;\n#endif\n\n    WOLFSSL_ENTER(\"wc_PKCS7_DecryptKari\");\n    if (pkcs7 == NULL || pkiMsg == NULL ||\n            ((pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0) &&\n              pkcs7->wrapCEKCb == NULL) ||\n        idx == NULL || decryptedKey == NULL || decryptedKeySz == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    switch (pkcs7->state) {\n        case WC_PKCS7_DECRYPT_KARI: {\n        #ifndef NO_PKCS7_STREAM\n            /* @TODO for now just get full buffer, needs divided up */\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                   (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +\n                   pkcs7->stream->length, &pkiMsg, idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n        #endif\n            WC_PKCS7_KARI* kari;\n\n            kari = wc_PKCS7_KariNew(pkcs7, WC_PKCS7_DECODE);\n            if (kari == NULL)\n                return MEMORY_E;\n\n        #ifdef WOLFSSL_SMALL_STACK\n            encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,\n                                          DYNAMIC_TYPE_PKCS7);\n            if (encryptedKey == NULL) {\n                wc_PKCS7_KariFree(kari);\n                return MEMORY_E;\n            }\n        #endif\n            encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;\n\n            /* parse cert and key */\n            if (pkcs7->singleCert != NULL) {\n                ret = wc_PKCS7_KariParseRecipCert(kari, (byte*)pkcs7->singleCert,\n                                              pkcs7->singleCertSz, pkcs7->privateKey,\n                                              pkcs7->privateKeySz);\n                if (ret != 0) {\n                    wc_PKCS7_KariFree(kari);\n                #ifdef WOLFSSL_SMALL_STACK\n                    XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                #endif\n                    return ret;\n                }\n            }\n\n            /* remove OriginatorIdentifierOrKey */\n            ret = wc_PKCS7_KariGetOriginatorIdentifierOrKey(kari, pkiMsg,\n                                                            pkiMsgSz, idx);\n            if (ret != 0) {\n                wc_PKCS7_KariFree(kari);\n                #ifdef WOLFSSL_SMALL_STACK\n                    XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                #endif\n                return ret;\n            }\n\n            /* try and remove optional UserKeyingMaterial */\n            ret = wc_PKCS7_KariGetUserKeyingMaterial(kari, pkiMsg, pkiMsgSz, idx);\n            if (ret != 0) {\n                wc_PKCS7_KariFree(kari);\n                #ifdef WOLFSSL_SMALL_STACK\n                    XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                #endif\n                return ret;\n            }\n\n            /* remove KeyEncryptionAlgorithmIdentifier */\n            ret = wc_PKCS7_KariGetKeyEncryptionAlgorithmId(kari, pkiMsg,\n                    pkiMsgSz, idx, &keyAgreeOID, &keyWrapOID);\n            if (ret != 0) {\n                wc_PKCS7_KariFree(kari);\n                #ifdef WOLFSSL_SMALL_STACK\n                    XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                #endif\n                return ret;\n            }\n\n            /* if user has not explicitly set keyAgreeOID, set from one in bundle */\n            if (pkcs7->keyAgreeOID == 0)\n                pkcs7->keyAgreeOID = keyAgreeOID;\n\n            /* set direction based on key wrap algorithm */\n            switch (keyWrapOID) {\n        #ifndef NO_AES\n            #ifdef WOLFSSL_AES_128\n                case AES128_WRAP:\n            #endif\n            #ifdef WOLFSSL_AES_192\n                case AES192_WRAP:\n            #endif\n            #ifdef WOLFSSL_AES_256\n                case AES256_WRAP:\n            #endif\n                    direction = AES_DECRYPTION;\n                    break;\n        #endif\n                default:\n                    WOLFSSL_MSG(\"AES key wrap algorithm unsupported\");\n                    if (pkcs7->wrapCEKCb) {\n                        WOLFSSL_MSG(\"Direction not set!\");\n                        break; /* if unwrapping callback is set then do not\n                                * force restriction of supported wrap\n                                * algorithms */\n                    }\n\n                    wc_PKCS7_KariFree(kari);\n                    #ifdef WOLFSSL_SMALL_STACK\n                        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                    #endif\n                    return BAD_KEYWRAP_ALG_E;\n            }\n\n            /* remove RecipientEncryptedKeys */\n            ret = wc_PKCS7_KariGetRecipientEncryptedKeys(kari, pkiMsg, pkiMsgSz,\n                           idx, recipFound, encryptedKey, &encryptedKeySz, rid);\n            if (ret != 0) {\n                wc_PKCS7_KariFree(kari);\n                #ifdef WOLFSSL_SMALL_STACK\n                    XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                #endif\n                return ret;\n            }\n\n            /* decrypt CEK with KEK */\n            if (pkcs7->wrapCEKCb) {\n                word32 tmpKeySz = 0;\n                byte* tmpKeyDer = NULL;\n\n                ret = wc_ecc_export_x963(kari->senderKey, NULL, &tmpKeySz);\n                if (ret != LENGTH_ONLY_E) {\n                    return ret;\n                }\n\n                /* buffer space for algorithm/curve */\n                tmpKeySz += MAX_SEQ_SZ;\n                tmpKeySz += 2 * MAX_ALGO_SZ;\n\n                /* buffer space for public key sequence */\n                tmpKeySz += MAX_SEQ_SZ;\n                tmpKeySz += TRAILING_ZERO;\n\n                tmpKeyDer = (byte*)XMALLOC(tmpKeySz, pkcs7->heap,\n                        DYNAMIC_TYPE_TMP_BUFFER);\n                if (tmpKeyDer == NULL) {\n                    return MEMORY_E;\n                }\n\n                ret = wc_EccPublicKeyToDer(kari->senderKey, tmpKeyDer,\n                                         tmpKeySz, 1);\n                if (ret < 0) {\n                    XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n                    return ret;\n                }\n                tmpKeySz = (word32)ret;\n\n                keySz = pkcs7->wrapCEKCb(pkcs7, encryptedKey, encryptedKeySz,\n                        rid, KEYID_SIZE, tmpKeyDer, tmpKeySz,\n                        decryptedKey, *decryptedKeySz,\n                        keyWrapOID, (int)PKCS7_KARI, direction);\n                XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n                if (keySz  > 0) {\n                    /* If unwrapping was successful then consider recipient\n                     * found. Checking for NULL singleCert to confirm previous\n                     * SID check was not done */\n                    if (pkcs7->singleCert == NULL)\n                        *recipFound = 1;\n                }\n            }\n            else {\n                /* create KEK */\n                ret = wc_PKCS7_KariGenerateKEK(kari, keyWrapOID, pkcs7->keyAgreeOID);\n                if (ret != 0) {\n                    wc_PKCS7_KariFree(kari);\n                    #ifdef WOLFSSL_SMALL_STACK\n                        XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                    #endif\n                    return ret;\n                }\n\n                /* decrypt CEK with KEK */\n                keySz = wc_PKCS7_KeyWrap(encryptedKey, encryptedKeySz, kari->kek,\n                                         kari->kekSz, decryptedKey, *decryptedKeySz,\n                                         keyWrapOID, direction);\n            }\n            if (keySz <= 0) {\n                wc_PKCS7_KariFree(kari);\n                #ifdef WOLFSSL_SMALL_STACK\n                    XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                #endif\n                return keySz;\n            }\n            *decryptedKeySz = (word32)keySz;\n\n            wc_PKCS7_KariFree(kari);\n            #ifdef WOLFSSL_SMALL_STACK\n                XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            #endif\n            #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                break;\n            }\n            #endif\n            ret = 0; /* success */\n        }\n        break;\n\n        default:\n            WOLFSSL_MSG(\"PKCS7 kari unknown state\");\n            ret = BAD_FUNC_ARG;\n\n    }\n\n    (void)pkiMsg;\n    (void)pkiMsgSz;\n\n    return ret;\n#else\n    (void)in;\n    (void)inSz;\n    (void)pkcs7;\n    (void)idx;\n    (void)decryptedKey;\n    (void)decryptedKeySz;\n    (void)recipFound;\n\n    return NOT_COMPILED_IN;\n#endif /* HAVE_ECC */\n}\n\n\n/* decode ASN.1 RecipientInfos SET, return 0 on success, < 0 on error */\nstatic int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in,\n                            word32  inSz, word32* idx, byte* decryptedKey,\n                            word32* decryptedKeySz, int* recipFound)\n{\n    word32 savedIdx;\n    int version, ret = 0, length;\n    byte* pkiMsg = in;\n    word32 pkiMsgSz = inSz;\n    byte  tag;\n#ifndef NO_PKCS7_STREAM\n    word32 tmpIdx;\n    long rc;\n#endif\n\n    if (pkcs7 == NULL || pkiMsg == NULL || idx == NULL ||\n        decryptedKey == NULL || decryptedKeySz == NULL ||\n        recipFound == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    WOLFSSL_ENTER(\"wc_PKCS7_DecryptRecipientInfos\");\n#ifndef NO_PKCS7_STREAM\n    tmpIdx = *idx;\n#endif\n\n    /* check if in the process of decrypting */\n    switch (pkcs7->state) {\n        case WC_PKCS7_DECRYPT_KTRI:\n        case WC_PKCS7_DECRYPT_KTRI_2:\n        case WC_PKCS7_DECRYPT_KTRI_3:\n        #ifndef NO_RSA\n            ret = wc_PKCS7_DecryptKtri(pkcs7, in, inSz, idx,\n                                      decryptedKey, decryptedKeySz, recipFound);\n        #else\n            return NOT_COMPILED_IN;\n        #endif\n            break;\n\n        case WC_PKCS7_DECRYPT_KARI:\n                ret = wc_PKCS7_DecryptKari(pkcs7, in, inSz, idx,\n                                      decryptedKey, decryptedKeySz, recipFound);\n                break;\n\n        case WC_PKCS7_DECRYPT_KEKRI:\n                ret = wc_PKCS7_DecryptKekri(pkcs7, in, inSz, idx,\n                                      decryptedKey, decryptedKeySz, recipFound);\n                break;\n\n        case WC_PKCS7_DECRYPT_PWRI:\n        #if !defined(NO_PWDBASED) && !defined(NO_SHA)\n                ret = wc_PKCS7_DecryptPwri(pkcs7, in, inSz, idx,\n                                      decryptedKey, decryptedKeySz, recipFound);\n        #else\n                return NOT_COMPILED_IN;\n        #endif\n                break;\n\n        case WC_PKCS7_DECRYPT_ORI:\n            ret = wc_PKCS7_DecryptOri(pkcs7, in, inSz, idx,\n                                      decryptedKey, decryptedKeySz, recipFound);\n            break;\n\n        default:\n            /* not in decrypting state */\n            break;\n    }\n\n    if (ret < 0) {\n        return ret;\n    }\n\n    savedIdx = *idx;\n#ifndef NO_PKCS7_STREAM\n    rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in, inSz);\n    if (rc < 0) {\n        return (int)rc;\n    }\n    pkiMsgSz = (word32)rc;\n    if (pkcs7->stream->length > 0)\n        pkiMsg = pkcs7->stream->buffer;\n#endif\n\n    /* when looking for next recipient, use first sequence and version to\n     * indicate there is another, if not, move on */\n    while(*recipFound == 0) {\n\n        /* remove RecipientInfo, if we don't have a SEQUENCE, back up idx to\n         * last good saved one */\n        if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) > 0) {\n\n        #ifndef NO_RSA\n            /* found ktri */\n            #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                break;\n            }\n            #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI);\n            ret = wc_PKCS7_DecryptKtri(pkcs7, in, inSz, idx,\n                                      decryptedKey, decryptedKeySz,\n                                      recipFound);\n            if (ret != 0)\n                return ret;\n        #else\n            return NOT_COMPILED_IN;\n        #endif\n        }\n        else {\n            word32 localIdx;\n            /* kari is IMPLICIT[1] */\n            *idx = savedIdx;\n            localIdx = *idx;\n\n            if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) != 0) {\n                /* no room for recipient info */\n                break;\n            }\n\n            if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {\n                (*idx)++;\n                if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)\n                    return ASN_PARSE_E;\n\n                if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {\n                    *idx = savedIdx;\n                    break;\n                }\n\n                if (version != 3)\n                    return ASN_VERSION_E;\n\n                /* found kari */\n            #ifndef NO_PKCS7_STREAM\n                if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                    break;\n                }\n            #endif\n                wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KARI);\n                ret = wc_PKCS7_DecryptKari(pkcs7, in, inSz, idx,\n                                          decryptedKey, decryptedKeySz,\n                                          recipFound);\n                if (ret != 0)\n                    return ret;\n\n            /* kekri is IMPLICIT[2] */\n            } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) {\n                (*idx)++;\n\n                if (GetLength(pkiMsg, idx, &version, pkiMsgSz) < 0)\n                    return ASN_PARSE_E;\n\n                if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {\n                    *idx = savedIdx;\n                    break;\n                }\n\n                if (version != 4)\n                    return ASN_VERSION_E;\n\n                /* found kekri */\n            #ifndef NO_PKCS7_STREAM\n                if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                    break;\n                }\n            #endif\n                wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KEKRI);\n                ret = wc_PKCS7_DecryptKekri(pkcs7, in, inSz, idx,\n                                           decryptedKey, decryptedKeySz,\n                                           recipFound);\n                if (ret != 0)\n                    return ret;\n\n            /* pwri is IMPLICIT[3] */\n            } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 3)) {\n        #if !defined(NO_PWDBASED) && !defined(NO_SHA)\n                (*idx)++;\n\n                if (GetLength(pkiMsg, idx, &version, pkiMsgSz) < 0)\n                    return ASN_PARSE_E;\n\n                if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {\n                    *idx = savedIdx;\n                    break;\n                }\n\n                if (version != 0)\n                    return ASN_VERSION_E;\n\n                /* found pwri */\n            #ifndef NO_PKCS7_STREAM\n                if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                    break;\n                }\n            #endif\n                wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_PWRI);\n                ret = wc_PKCS7_DecryptPwri(pkcs7, in, inSz, idx,\n                                           decryptedKey, decryptedKeySz,\n                                           recipFound);\n                if (ret != 0)\n                    return ret;\n        #else\n                return NOT_COMPILED_IN;\n        #endif\n\n            /* ori is IMPLICIT[4] */\n            } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 4)) {\n                (*idx)++;\n\n                /* found ori */\n            #ifndef NO_PKCS7_STREAM\n                if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                    break;\n                }\n            #endif\n                wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_ORI);\n                ret = wc_PKCS7_DecryptOri(pkcs7, in, inSz, idx,\n                                          decryptedKey, decryptedKeySz,\n                                          recipFound);\n                if (ret != 0)\n                    return ret;\n\n            } else {\n                /* failed to find RecipientInfo, restore idx and continue */\n                *idx = savedIdx;\n                break;\n            }\n        }\n\n        /* update good idx */\n        savedIdx = *idx;\n    }\n\n    return ret;\n}\n\n\n/* Parse encoded EnvelopedData bundle up to RecipientInfo set.\n *\n * return size of RecipientInfo SET on success, negative upon error */\nstatic int wc_PKCS7_ParseToRecipientInfoSet(PKCS7* pkcs7, byte* in,\n                                            word32 inSz, word32* idx,\n                                            int type)\n{\n    int version = 0, length, ret = 0;\n    word32 contentType;\n    byte* pkiMsg = in;\n    word32 pkiMsgSz = inSz;\n    byte  tag;\n#ifndef NO_PKCS7_STREAM\n    word32 tmpIdx = 0;\n    long rc;\n#endif\n\n    if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0 || idx == NULL)\n        return BAD_FUNC_ARG;\n\n    if ((type != ENVELOPED_DATA) && (type != AUTH_ENVELOPED_DATA) &&\n            pkcs7->contentOID != FIRMWARE_PKG_DATA)\n        return BAD_FUNC_ARG;\n\n#ifndef NO_PKCS7_STREAM\n    if (pkcs7->stream == NULL) {\n        if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {\n            return ret;\n        }\n    }\n#endif\n\n    switch (pkcs7->state) {\n        case WC_PKCS7_INFOSET_START:\n        case WC_PKCS7_INFOSET_BER:\n        case WC_PKCS7_INFOSET_STAGE1:\n        case WC_PKCS7_INFOSET_STAGE2:\n        case WC_PKCS7_INFOSET_END:\n            break;\n\n        default:\n            WOLFSSL_MSG(\"Warning, setting PKCS7 info state to start\");\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_START);\n    }\n\n    switch (pkcs7->state) {\n        case WC_PKCS7_INFOSET_START:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +\n                            ASN_TAG_SZ, &pkiMsg, idx)) != 0) {\n                return ret;\n            }\n\n            rc  = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK, in, inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n        #endif\n            /* read past ContentInfo, verify type is envelopedData */\n            if (ret == 0 && GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)\n            {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && length == 0 && pkiMsg[(*idx)-1] == 0x80) {\n        #ifdef ASN_BER_TO_DER\n                word32 len;\n\n                wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_BER);\n                FALL_THROUGH;\n\n                /* full buffer is needed for conversion */\n                case WC_PKCS7_INFOSET_BER:\n                #ifndef NO_PKCS7_STREAM\n                if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                            pkcs7->stream->maxLen - pkcs7->stream->length,\n                            &pkiMsg, idx)) != 0) {\n                    return ret;\n                }\n\n                rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,\n                        in, inSz);\n                if (rc < 0) {\n                    ret = (int)rc;\n                    break;\n                }\n                pkiMsgSz = (word32)rc;\n                #endif\n\n                len = 0;\n\n                ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len);\n                if (ret != LENGTH_ONLY_E)\n                    return ret;\n                pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                if (pkcs7->der == NULL)\n                    return MEMORY_E;\n                ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len);\n                if (ret < 0)\n                    return ret;\n\n                pkiMsg = in = pkcs7->der;\n                pkiMsgSz = pkcs7->derSz = len;\n                *idx = 0;\n\n                if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)\n                    return ASN_PARSE_E;\n        #else\n                return BER_INDEF_E;\n        #endif\n            }\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                break;\n            }\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_STAGE1);\n            FALL_THROUGH;\n\n        case WC_PKCS7_INFOSET_STAGE1:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_OID_SZ +\n                            MAX_LENGTH_SZ + ASN_TAG_SZ, &pkiMsg, idx)) != 0) {\n                return ret;\n            }\n\n            pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length :inSz;\n        #endif\n            if (pkcs7->contentOID != FIRMWARE_PKG_DATA ||\n                    type == AUTH_ENVELOPED_DATA) {\n                if (ret == 0 && wc_GetContentType(pkiMsg, idx, &contentType,\n                            pkiMsgSz) < 0)\n                    ret = ASN_PARSE_E;\n\n                if (ret == 0) {\n                    if (type == ENVELOPED_DATA && contentType != ENVELOPED_DATA) {\n                        WOLFSSL_MSG(\"PKCS#7 input not of type EnvelopedData\");\n                        ret = PKCS7_OID_E;\n                    } else if (type == AUTH_ENVELOPED_DATA &&\n                           contentType != AUTH_ENVELOPED_DATA) {\n                        WOLFSSL_MSG(\"PKCS#7 input not of type AuthEnvelopedData\");\n                        ret = PKCS7_OID_E;\n                    }\n                }\n\n                if (ret == 0 && GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) != 0)\n                    ret = ASN_PARSE_E;\n\n                if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC\n                            | 0))\n                    ret = ASN_PARSE_E;\n\n                if (ret == 0 && GetLength_ex(pkiMsg, idx, &length, pkiMsgSz,\n                            NO_USER_CHECK) < 0)\n                    ret = ASN_PARSE_E;\n            }\n\n            if (ret < 0)\n                break;\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                    break;\n            }\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_STAGE2);\n            FALL_THROUGH;\n\n        case WC_PKCS7_INFOSET_STAGE2:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +\n                            MAX_VERSION_SZ, &pkiMsg, idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n        #endif\n            /* remove EnvelopedData and version */\n            if (pkcs7->contentOID != FIRMWARE_PKG_DATA ||\n                    type == AUTH_ENVELOPED_DATA) {\n                if (ret == 0 && GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)\n                    ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0)\n                ret = ASN_PARSE_E;\n\n            if (ret < 0)\n                break;\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                break;\n            }\n\n            pkcs7->stream->varOne = version;\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_END);\n            FALL_THROUGH;\n\n        case WC_PKCS7_INFOSET_END:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                            MAX_SET_SZ, &pkiMsg, idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n            version = pkcs7->stream->varOne;\n        #endif\n\n            if (type == ENVELOPED_DATA) {\n                /* TODO :: make this more accurate */\n                if ((pkcs7->publicKeyOID == RSAk &&\n                     (version != 0 && version != 2))\n                #ifdef HAVE_ECC\n                        || (pkcs7->publicKeyOID == ECDSAk &&\n                            (version != 0 && version != 2 && version != 3))\n                #endif\n                        ) {\n                    WOLFSSL_MSG(\"PKCS#7 envelopedData version incorrect\");\n                    ret = ASN_VERSION_E;\n                }\n            } else {\n                /* AuthEnvelopedData version MUST be 0 */\n                if (version != 0) {\n                    WOLFSSL_MSG(\"PKCS#7 AuthEnvelopedData needs to be of version 0\");\n                    ret = ASN_VERSION_E;\n                }\n            }\n\n            /* remove RecipientInfo set, get length of set */\n            if (ret == 0 && GetSet(pkiMsg, idx, &length, pkiMsgSz) < 0)\n                ret = ASN_PARSE_E;\n\n            if (ret < 0)\n                break;\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {\n                break;\n            }\n        #endif\n\n            if (ret == 0)\n                ret = length;\n\n            break;\n\n        default:\n            WOLFSSL_MSG(\"Bad PKCS7 info set state\");\n            ret = BAD_FUNC_ARG;\n            break;\n    }\n\n    return ret;\n}\n\n\n/* Import secret/private key into a PKCS7 structure. Used for setting\n * the secret key for decryption a EnvelopedData KEKRI RecipientInfo.\n *\n * Returns 0 on success, negative upon error */\nWOLFSSL_API int wc_PKCS7_SetKey(PKCS7* pkcs7, byte* key, word32 keySz)\n{\n    if (pkcs7 == NULL || key == NULL || keySz == 0)\n        return BAD_FUNC_ARG;\n\n    pkcs7->privateKey = key;\n    pkcs7->privateKeySz = keySz;\n\n    return 0;\n}\n\n\n/* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */\nWOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in,\n                                         word32 inSz, byte* output,\n                                         word32 outputSz)\n{\n    int recipFound = 0;\n    int ret, length = 0;\n    word32 idx = 0;\n#ifndef NO_PKCS7_STREAM\n    word32 tmpIdx = 0;\n    long rc;\n#endif\n    word32 contentType, encOID = 0;\n    word32 decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;\n\n    int expBlockSz = 0, blockKeySz = 0;\n    byte  tmpIvBuf[MAX_CONTENT_IV_SIZE];\n    byte* tmpIv = tmpIvBuf;\n\n    byte* pkiMsg    = in;\n    word32 pkiMsgSz = inSz;\n    byte* decryptedKey = NULL;\n    int encryptedContentSz = 0;\n    byte padLen;\n    byte* encryptedContent = NULL;\n    int explicitOctet;\n    word32 localIdx;\n    byte   tag;\n\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    if (pkiMsg == NULL || pkiMsgSz == 0 ||\n        output == NULL || outputSz == 0)\n        return BAD_FUNC_ARG;\n\n#ifndef NO_PKCS7_STREAM\n    (void)tmpIv; /* help out static analysis */\n    if (pkcs7->stream == NULL) {\n        if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {\n            return ret;\n        }\n    }\n#endif\n\n    switch (pkcs7->state) {\n        case WC_PKCS7_START:\n        case WC_PKCS7_INFOSET_START:\n        case WC_PKCS7_INFOSET_BER:\n        case WC_PKCS7_INFOSET_STAGE1:\n        case WC_PKCS7_INFOSET_STAGE2:\n        case WC_PKCS7_INFOSET_END:\n            ret = wc_PKCS7_ParseToRecipientInfoSet(pkcs7, pkiMsg, pkiMsgSz,\n                    &idx, ENVELOPED_DATA);\n            if (ret < 0) {\n                break;\n            }\n\n        #ifdef ASN_BER_TO_DER\n            /* check if content was BER and has been converted to DER */\n            if (pkcs7->derSz > 0)\n                pkiMsg = in = pkcs7->der;\n        #endif\n\n            decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,\n                                                       DYNAMIC_TYPE_PKCS7);\n            if (decryptedKey == NULL)\n                return MEMORY_E;\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_2);\n        #ifndef NO_PKCS7_STREAM\n            tmpIdx = idx;\n            pkcs7->stream->aad = decryptedKey;\n        #endif\n            FALL_THROUGH;\n\n        case WC_PKCS7_ENV_2:\n        #ifndef NO_PKCS7_STREAM\n            /* store up enough buffer for initial info set decode */\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +\n                            MAX_VERSION_SZ + ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {\n                return ret;\n            }\n        #endif\n            FALL_THROUGH;\n\n        case WC_PKCS7_DECRYPT_KTRI:\n        case WC_PKCS7_DECRYPT_KTRI_2:\n        case WC_PKCS7_DECRYPT_KTRI_3:\n        case WC_PKCS7_DECRYPT_KARI:\n        case WC_PKCS7_DECRYPT_KEKRI:\n        case WC_PKCS7_DECRYPT_PWRI:\n        case WC_PKCS7_DECRYPT_ORI:\n        #ifndef NO_PKCS7_STREAM\n            decryptedKey   = pkcs7->stream->aad;\n            decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;\n        #endif\n\n            ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx,\n                                        decryptedKey, &decryptedKeySz,\n                                        &recipFound);\n            if (ret == 0 && recipFound == 0) {\n                WOLFSSL_MSG(\"No recipient found in envelopedData that matches input\");\n                ret = PKCS7_RECIP_E;\n            }\n\n            if (ret != 0)\n                break;\n        #ifndef NO_PKCS7_STREAM\n            tmpIdx               = idx;\n            pkcs7->stream->aadSz = decryptedKeySz;\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_3);\n            FALL_THROUGH;\n\n        case WC_PKCS7_ENV_3:\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +\n                                                MAX_VERSION_SZ + ASN_TAG_SZ +\n                                                MAX_LENGTH_SZ, &pkiMsg, &idx))\n                                                != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n        #else\n            ret = 0;\n        #endif\n\n            /* remove EncryptedContentInfo */\n            if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,\n                        pkiMsgSz) < 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,\n                        pkiMsgSz) < 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            blockKeySz = wc_PKCS7_GetOIDKeySize(encOID);\n            if (ret == 0 && blockKeySz < 0) {\n                ret = blockKeySz;\n            }\n\n            expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID);\n            if (ret == 0 && expBlockSz < 0) {\n                ret = expBlockSz;\n            }\n\n            /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */\n            if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) != 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && tag != ASN_OCTET_STRING) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && length != expBlockSz) {\n                WOLFSSL_MSG(\"Incorrect IV length, must be of content alg block size\");\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret != 0)\n                break;\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {\n                break;\n            }\n            wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, length);\n            pkcs7->stream->contentSz = blockKeySz;\n            pkcs7->stream->expected = length + MAX_LENGTH_SZ + MAX_LENGTH_SZ +\n                ASN_TAG_SZ + ASN_TAG_SZ;\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_4);\n            FALL_THROUGH;\n\n        case WC_PKCS7_ENV_4:\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                            pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n\n            wc_PKCS7_StreamGetVar(pkcs7, 0, 0, &length);\n            tmpIv = pkcs7->stream->tmpIv;\n            if (tmpIv == NULL) {\n                /* check added to help out static analysis tool */\n                ret = MEMORY_E;\n                break;\n            }\n        #else\n            ret = 0;\n        #endif\n\n            XMEMCPY(tmpIv, &pkiMsg[idx], length);\n            idx += length;\n\n            explicitOctet = 0;\n            localIdx = idx;\n            if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&\n                    tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {\n                explicitOctet = 1;\n            }\n\n            /* read encryptedContent, cont[0] */\n            if (ret == 0 && tag != (ASN_CONTEXT_SPECIFIC | 0) &&\n                          tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {\n                ret = ASN_PARSE_E;\n            }\n            idx++;\n\n            if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,\n                                                               pkiMsgSz) <= 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && explicitOctet) {\n                if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {\n                    ret = ASN_PARSE_E;\n                    break;\n                }\n\n                if (tag != ASN_OCTET_STRING) {\n                    ret = ASN_PARSE_E;\n                    break;\n                }\n\n                if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,\n                            pkiMsgSz) <= 0) {\n                    ret = ASN_PARSE_E;\n                    break;\n                }\n            }\n\n            if (ret != 0)\n                break;\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {\n                break;\n            }\n            pkcs7->stream->expected = encryptedContentSz;\n            wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, 0);\n            wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz,\n                    encryptedContentSz);\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_5);\n            FALL_THROUGH;\n\n        case WC_PKCS7_ENV_5:\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                            pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {\n                return ret;\n            }\n\n            wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz,\n                    &encryptedContentSz);\n            tmpIv = pkcs7->stream->tmpIv;\n\n            /* restore decrypted key */\n            decryptedKey   = pkcs7->stream->aad;\n            decryptedKeySz = pkcs7->stream->aadSz;\n            blockKeySz = pkcs7->stream->contentSz;\n        #else\n            ret = 0;\n        #endif\n            encryptedContent = (byte*)XMALLOC(encryptedContentSz, pkcs7->heap,\n                                                       DYNAMIC_TYPE_PKCS7);\n            if (ret == 0 && encryptedContent == NULL) {\n                ret = MEMORY_E;\n                break;\n            }\n\n            if (ret == 0) {\n                XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);\n            }\n\n            /* decrypt encryptedContent */\n            ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey,\n                    blockKeySz, tmpIv, expBlockSz, NULL, 0, NULL, 0,\n                    encryptedContent, encryptedContentSz, encryptedContent);\n            if (ret != 0) {\n                XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                break;\n            }\n\n            padLen = encryptedContent[encryptedContentSz-1];\n\n            /* copy plaintext to output */\n            if (padLen > encryptedContentSz ||\n                    (word32)(encryptedContentSz - padLen) > outputSz) {\n                XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                ret = BUFFER_E;\n                break;\n            }\n            XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);\n\n            /* free memory, zero out keys */\n            ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);\n            ForceZero(encryptedContent, encryptedContentSz);\n            XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n\n            ret = encryptedContentSz - padLen;\n        #ifndef NO_PKCS7_STREAM\n            pkcs7->stream->aad = NULL;\n            pkcs7->stream->aadSz = 0;\n            wc_PKCS7_ResetStream(pkcs7);\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);\n            break;\n\n        default:\n            WOLFSSL_MSG(\"PKCS#7 unknown decode enveloped state\");\n            ret = BAD_FUNC_ARG;\n    }\n\n#ifndef NO_PKCS7_STREAM\n    if (ret < 0 && ret != WC_PKCS7_WANT_READ_E) {\n        wc_PKCS7_ResetStream(pkcs7);\n        wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);\n    }\n#else\n    if (decryptedKey != NULL && ret < 0) {\n        ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);\n        XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    }\n#endif\n    return ret;\n}\n\n\n/* build PKCS#7 authEnvelopedData content type, return enveloped size */\nint wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output,\n                                     word32 outputSz)\n{\n#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)\n    int ret, idx = 0;\n    int totalSz, encryptedOutSz;\n\n    int contentInfoSeqSz, outerContentTypeSz, outerContentSz;\n    byte contentInfoSeq[MAX_SEQ_SZ];\n    byte outerContentType[MAX_ALGO_SZ];\n    byte outerContent[MAX_SEQ_SZ];\n\n    int envDataSeqSz, verSz;\n    byte envDataSeq[MAX_SEQ_SZ];\n    byte ver[MAX_VERSION_SZ];\n\n    WC_RNG rng;\n    int blockSz, blockKeySz;\n    byte* encryptedContent;\n\n    Pkcs7EncodedRecip* tmpRecip = NULL;\n    int recipSz, recipSetSz;\n    byte recipSet[MAX_SET_SZ];\n\n    int encContentOctetSz, encContentSeqSz, contentTypeSz;\n    int contentEncAlgoSz, nonceOctetStringSz, macOctetStringSz;\n    byte encContentSeq[MAX_SEQ_SZ];\n    byte contentType[MAX_ALGO_SZ];\n    byte contentEncAlgo[MAX_ALGO_SZ];\n    byte nonceOctetString[MAX_OCTET_STR_SZ];\n    byte encContentOctet[MAX_OCTET_STR_SZ];\n    byte macOctetString[MAX_OCTET_STR_SZ];\n\n    byte authTag[AES_BLOCK_SIZE];\n    byte nonce[GCM_NONCE_MID_SZ];   /* GCM nonce is larger than CCM */\n    byte macInt[MAX_VERSION_SZ];\n    word32 nonceSz = 0, macIntSz = 0;\n\n    /* authAttribs */\n    byte* flatAuthAttribs = NULL;\n    byte authAttribSet[MAX_SET_SZ];\n    EncodedAttrib authAttribs[MAX_AUTH_ATTRIBS_SZ];\n    word32 authAttribsSz = 0, authAttribsCount = 0;\n    word32 authAttribsSetSz = 0;\n\n    byte* aadBuffer = NULL;\n    word32 aadBufferSz = 0;\n    byte authAttribAadSet[MAX_SET_SZ];\n    word32 authAttribsAadSetSz = 0;\n\n    /* unauthAttribs */\n    byte* flatUnauthAttribs = NULL;\n    byte unauthAttribSet[MAX_SET_SZ];\n    EncodedAttrib unauthAttribs[MAX_UNAUTH_ATTRIBS_SZ];\n    word32 unauthAttribsSz = 0, unauthAttribsCount = 0;\n    word32 unauthAttribsSetSz = 0;\n\n\n    PKCS7Attrib contentTypeAttrib;\n    byte contentTypeValue[MAX_OID_SZ];\n    /* contentType OID (1.2.840.113549.1.9.3) */\n    const byte contentTypeOid[] =\n            { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,\n                             0x09, 0x03 };\n\n    if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0)\n        return BAD_FUNC_ARG;\n\n    if (output == NULL || outputSz == 0)\n        return BAD_FUNC_ARG;\n\n    switch (pkcs7->encryptOID) {\n#ifdef HAVE_AESGCM\n    #ifdef WOLFSSL_AES_128\n        case AES128GCMb:\n            break;\n    #endif\n    #ifdef WOLFSSL_AES_192\n        case AES192GCMb:\n            break;\n    #endif\n    #ifdef WOLFSSL_AES_256\n        case AES256GCMb:\n            break;\n    #endif\n#endif\n#ifdef HAVE_AESCCM\n    #ifdef WOLFSSL_AES_128\n        case AES128CCMb:\n            break;\n    #endif\n    #ifdef WOLFSSL_AES_192\n        case AES192CCMb:\n            break;\n    #endif\n    #ifdef WOLFSSL_AES_256\n        case AES256CCMb:\n            break;\n    #endif\n#endif\n        default:\n            WOLFSSL_MSG(\"CMS AuthEnvelopedData must use AES-GCM or AES-CCM\");\n            return BAD_FUNC_ARG;\n    }\n\n    blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);\n    if (blockKeySz < 0)\n        return blockKeySz;\n\n    blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);\n    if (blockKeySz < 0 || blockSz < 0)\n        return blockSz;\n\n    /* outer content type */\n    ret = wc_SetContentType(AUTH_ENVELOPED_DATA, outerContentType,\n                            sizeof(outerContentType));\n    if (ret < 0)\n        return ret;\n\n    outerContentTypeSz = ret;\n\n    /* version, defined as 0 in RFC 5083 */\n    verSz = SetMyVersion(0, ver, 0);\n\n    /* generate random content encryption key */\n    ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);\n    if (ret != 0) {\n        return ret;\n    }\n\n    /* build RecipientInfo, only if user manually set singleCert and size */\n    if (pkcs7->singleCert != NULL && pkcs7->singleCertSz > 0) {\n        switch (pkcs7->publicKeyOID) {\n        #ifndef NO_RSA\n            case RSAk:\n                ret = wc_PKCS7_AddRecipient_KTRI(pkcs7, pkcs7->singleCert,\n                                                 pkcs7->singleCertSz, 0);\n                break;\n        #endif\n        #ifdef HAVE_ECC\n            case ECDSAk:\n                ret = wc_PKCS7_AddRecipient_KARI(pkcs7, pkcs7->singleCert,\n                                                 pkcs7->singleCertSz,\n                                                 pkcs7->keyWrapOID,\n                                                 pkcs7->keyAgreeOID, pkcs7->ukm,\n                                                 pkcs7->ukmSz, 0);\n                break;\n        #endif\n\n            default:\n                WOLFSSL_MSG(\"Unsupported RecipientInfo public key type\");\n                return BAD_FUNC_ARG;\n        };\n\n        if (ret < 0) {\n            WOLFSSL_MSG(\"Failed to create RecipientInfo\");\n            return ret;\n        }\n    }\n\n    recipSz = wc_PKCS7_GetRecipientListSize(pkcs7);\n    if (recipSz < 0) {\n        return ret;\n\n    } else if (recipSz == 0) {\n        WOLFSSL_MSG(\"You must add at least one CMS recipient\");\n        return PKCS7_RECIP_E;\n    }\n    recipSetSz = SetSet(recipSz, recipSet);\n\n    /* generate random nonce and IV for encryption */\n    switch (pkcs7->encryptOID) {\n#ifdef HAVE_AESGCM\n    #ifdef WOLFSSL_AES_128\n        case AES128GCMb:\n            FALL_THROUGH;\n    #endif\n    #ifdef WOLFSSL_AES_192\n        case AES192GCMb:\n            FALL_THROUGH;\n    #endif\n    #ifdef WOLFSSL_AES_256\n        case AES256GCMb:\n    #endif\n    #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \\\n        defined(WOLFSSL_AES_256)\n            /* GCM nonce is GCM_NONCE_MID_SZ (12) */\n            nonceSz = GCM_NONCE_MID_SZ;\n            break;\n    #endif\n#endif /* HAVE_AESGCM */\n#ifdef HAVE_AESCCM\n    #ifdef WOLFSSL_AES_128\n        case AES128CCMb:\n            FALL_THROUGH;\n    #endif\n    #ifdef WOLFSSL_AES_192\n        case AES192CCMb:\n            FALL_THROUGH;\n    #endif\n    #ifdef WOLFSSL_AES_256\n        case AES256CCMb:\n    #endif\n    #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \\\n        defined(WOLFSSL_AES_256)\n            /* CCM nonce is CCM_NONCE_MIN_SZ (7) */\n            nonceSz = CCM_NONCE_MIN_SZ;\n            break;\n    #endif\n#endif /* HAVE_AESCCM */\n    }\n\n    ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);\n    if (ret != 0)\n        return ret;\n\n    ret = wc_PKCS7_GenerateBlock(pkcs7, &rng, nonce, nonceSz);\n    wc_FreeRng(&rng);\n    if (ret != 0) {\n        return ret;\n    }\n\n\n    /* authAttribs: add contentType attrib if needed */\n    if (pkcs7->contentOID != DATA) {\n\n        /* if type is not id-data, contentType attribute MUST be added */\n        contentTypeAttrib.oid = contentTypeOid;\n        contentTypeAttrib.oidSz = sizeof(contentTypeOid);\n\n        /* try to set from contentOID first, known types */\n        ret = wc_SetContentType(pkcs7->contentOID, contentTypeValue,\n                                sizeof(contentTypeValue));\n        if (ret > 0) {\n            contentTypeAttrib.value = contentTypeValue;\n            contentTypeAttrib.valueSz = ret;\n\n        /* otherwise, try to set from custom content type */\n        } else if (ret <= 0) {\n            if (pkcs7->contentTypeSz == 0) {\n                WOLFSSL_MSG(\"CMS pkcs7->contentType must be set if \"\n                            \"contentOID is not\");\n                return BAD_FUNC_ARG;\n            }\n            contentTypeAttrib.value = pkcs7->contentType;\n            contentTypeAttrib.valueSz = pkcs7->contentTypeSz;\n        }\n\n        authAttribsSz += EncodeAttributes(authAttribs, 1,\n                                          &contentTypeAttrib, 1);\n        authAttribsCount += 1;\n    }\n\n    /* authAttribs: add in user authenticated attributes */\n    if (pkcs7->authAttribs != NULL && pkcs7->authAttribsSz > 0) {\n        authAttribsSz += EncodeAttributes(authAttribs + authAttribsCount,\n                                 MAX_AUTH_ATTRIBS_SZ - authAttribsCount,\n                                 pkcs7->authAttribs,\n                                 pkcs7->authAttribsSz);\n        authAttribsCount += pkcs7->authAttribsSz;\n    }\n\n    /* authAttribs: flatten authAttribs */\n    if (authAttribsSz > 0 && authAttribsCount > 0) {\n        flatAuthAttribs = (byte*)XMALLOC(authAttribsSz, pkcs7->heap,\n                                         DYNAMIC_TYPE_PKCS7);\n        if (flatAuthAttribs == NULL) {\n            return MEMORY_E;\n        }\n\n        FlattenAttributes(pkcs7, flatAuthAttribs, authAttribs,\n                          authAttribsCount);\n\n        authAttribsSetSz = SetImplicit(ASN_SET, 1, authAttribsSz,\n                                       authAttribSet);\n\n        /* From RFC5083, \"For the purpose of constructing the AAD, the\n         * IMPLICIT [1] tag in the authAttrs field is not used for the\n         * DER encoding: rather a universal SET OF tag is used. */\n        authAttribsAadSetSz = SetSet(authAttribsSz, authAttribAadSet);\n\n        /* allocate temp buffer to hold alternate attrib encoding for aad */\n        aadBuffer = (byte*)XMALLOC(authAttribsSz + authAttribsAadSetSz,\n                                   pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (aadBuffer == NULL) {\n            XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return MEMORY_E;\n        }\n\n        /* build up alternate attrib encoding for aad */\n        aadBufferSz = 0;\n        XMEMCPY(aadBuffer + aadBufferSz, authAttribAadSet, authAttribsAadSetSz);\n        aadBufferSz += authAttribsAadSetSz;\n        XMEMCPY(aadBuffer + aadBufferSz, flatAuthAttribs, authAttribsSz);\n        aadBufferSz += authAttribsSz;\n    }\n\n    /* build up unauthenticated attributes (unauthAttrs) */\n    if (pkcs7->unauthAttribsSz > 0) {\n        unauthAttribsSz = EncodeAttributes(unauthAttribs + unauthAttribsCount,\n                                     MAX_UNAUTH_ATTRIBS_SZ - unauthAttribsCount,\n                                     pkcs7->unauthAttribs,\n                                     pkcs7->unauthAttribsSz);\n        unauthAttribsCount = pkcs7->unauthAttribsSz;\n\n        flatUnauthAttribs = (byte*)XMALLOC(unauthAttribsSz, pkcs7->heap,\n                                            DYNAMIC_TYPE_PKCS7);\n        if (flatUnauthAttribs == NULL) {\n            if (aadBuffer)\n                XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            if (flatAuthAttribs)\n                XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return MEMORY_E;\n        }\n\n        FlattenAttributes(pkcs7, flatUnauthAttribs, unauthAttribs,\n                          unauthAttribsCount);\n        unauthAttribsSetSz = SetImplicit(ASN_SET, 2, unauthAttribsSz,\n                                         unauthAttribSet);\n    }\n\n    /* allocate encrypted content buffer */\n    encryptedOutSz = pkcs7->contentSz;\n    encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,\n                                      DYNAMIC_TYPE_PKCS7);\n    if (encryptedContent == NULL) {\n        if (aadBuffer)\n            XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        if (flatUnauthAttribs)\n            XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        if (flatAuthAttribs)\n            XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return MEMORY_E;\n    }\n\n    /* encrypt content */\n    ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->cek,\n            pkcs7->cekSz, nonce, nonceSz, aadBuffer, aadBufferSz, authTag,\n            sizeof(authTag), pkcs7->content, encryptedOutSz, encryptedContent);\n\n    if (aadBuffer) {\n        XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        aadBuffer = NULL;\n    }\n\n    if (ret != 0) {\n        if (flatUnauthAttribs)\n            XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        if (flatAuthAttribs)\n            XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    /* EncryptedContentInfo */\n    ret = wc_SetContentType(pkcs7->contentOID, contentType,\n                            sizeof(contentType));\n    if (ret < 0) {\n        if (flatUnauthAttribs)\n            XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        if (flatAuthAttribs)\n            XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    contentTypeSz = ret;\n\n    /* put together nonce OCTET STRING */\n    nonceOctetStringSz = SetOctetString(nonceSz, nonceOctetString);\n\n    /* put together aes-ICVlen INTEGER */\n    macIntSz = SetMyVersion(sizeof(authTag), macInt, 0);\n\n    /* build up our ContentEncryptionAlgorithmIdentifier sequence,\n     * adding (nonceOctetStringSz + blockSz + macIntSz) for nonce OCTET STRING\n     * and tag size */\n    contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,\n                                 oidBlkType, nonceOctetStringSz + nonceSz +\n                                 macIntSz);\n\n    if (contentEncAlgoSz == 0) {\n        if (flatUnauthAttribs)\n            XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        if (flatAuthAttribs)\n            XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return BAD_FUNC_ARG;\n    }\n\n    encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz,\n                                    encContentOctet);\n\n    encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +\n                                  nonceOctetStringSz + nonceSz + macIntSz +\n                                  encContentOctetSz + encryptedOutSz,\n                                  encContentSeq);\n\n    macOctetStringSz = SetOctetString(sizeof(authTag), macOctetString);\n\n    /* keep track of sizes for outer wrapper layering */\n    totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +\n              contentEncAlgoSz + nonceOctetStringSz + nonceSz + macIntSz +\n              encContentOctetSz + encryptedOutSz + authAttribsSz +\n              authAttribsSetSz + macOctetStringSz + sizeof(authTag) +\n              unauthAttribsSz + unauthAttribsSetSz;\n\n    /* EnvelopedData */\n    envDataSeqSz = SetSequence(totalSz, envDataSeq);\n    totalSz += envDataSeqSz;\n\n    /* outer content */\n    outerContentSz = SetExplicit(0, totalSz, outerContent);\n    totalSz += outerContentTypeSz;\n    totalSz += outerContentSz;\n\n    /* ContentInfo */\n    contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);\n    totalSz += contentInfoSeqSz;\n\n    if (totalSz > (int)outputSz) {\n        WOLFSSL_MSG(\"Pkcs7_encrypt output buffer too small\");\n        if (flatUnauthAttribs)\n            XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        if (flatAuthAttribs)\n            XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return BUFFER_E;\n    }\n\n    XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);\n    idx += contentInfoSeqSz;\n    XMEMCPY(output + idx, outerContentType, outerContentTypeSz);\n    idx += outerContentTypeSz;\n    XMEMCPY(output + idx, outerContent, outerContentSz);\n    idx += outerContentSz;\n    XMEMCPY(output + idx, envDataSeq, envDataSeqSz);\n    idx += envDataSeqSz;\n    XMEMCPY(output + idx, ver, verSz);\n    idx += verSz;\n    XMEMCPY(output + idx, recipSet, recipSetSz);\n    idx += recipSetSz;\n    /* copy in recipients from list */\n    tmpRecip = pkcs7->recipList;\n    while (tmpRecip != NULL) {\n        XMEMCPY(output + idx, tmpRecip->recip, tmpRecip->recipSz);\n        idx += tmpRecip->recipSz;\n        tmpRecip = tmpRecip->next;\n    }\n    wc_PKCS7_FreeEncodedRecipientSet(pkcs7);\n    XMEMCPY(output + idx, encContentSeq, encContentSeqSz);\n    idx += encContentSeqSz;\n    XMEMCPY(output + idx, contentType, contentTypeSz);\n    idx += contentTypeSz;\n    XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);\n    idx += contentEncAlgoSz;\n    XMEMCPY(output + idx, nonceOctetString, nonceOctetStringSz);\n    idx += nonceOctetStringSz;\n    XMEMCPY(output + idx, nonce, nonceSz);\n    idx += nonceSz;\n    XMEMCPY(output + idx, macInt, macIntSz);\n    idx += macIntSz;\n    XMEMCPY(output + idx, encContentOctet, encContentOctetSz);\n    idx += encContentOctetSz;\n    XMEMCPY(output + idx, encryptedContent, encryptedOutSz);\n    idx += encryptedOutSz;\n\n    /* authenticated attributes */\n    if (flatAuthAttribs && authAttribsSz > 0) {\n        XMEMCPY(output + idx, authAttribSet, authAttribsSetSz);\n        idx += authAttribsSetSz;\n        XMEMCPY(output + idx, flatAuthAttribs, authAttribsSz);\n        idx += authAttribsSz;\n        XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    }\n\n    XMEMCPY(output + idx, macOctetString, macOctetStringSz);\n    idx += macOctetStringSz;\n    XMEMCPY(output + idx, authTag, sizeof(authTag));\n    idx += sizeof(authTag);\n\n    /* unauthenticated attributes */\n    if (unauthAttribsSz > 0) {\n        XMEMCPY(output + idx, unauthAttribSet, unauthAttribsSetSz);\n        idx += unauthAttribsSetSz;\n        XMEMCPY(output + idx, flatUnauthAttribs, unauthAttribsSz);\n        idx += unauthAttribsSz;\n    }\n\n    if (flatUnauthAttribs != NULL) {\n        XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    }\n\n    XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n\n    return idx;\n\n#else\n    WOLFSSL_MSG(\"AuthEnvelopedData requires AES-GCM or AES-CCM to be enabled\");\n    (void)pkcs7;\n    (void)output;\n    (void)outputSz;\n\n    return NOT_COMPILED_IN;\n#endif /* HAVE_AESGCM | HAVE_AESCCM */\n}\n\n\n/* unwrap and decrypt PKCS#7 AuthEnvelopedData object, return decoded size */\nWOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in,\n                                                 word32 inSz, byte* output,\n                                                 word32 outputSz)\n{\n#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)\n    int recipFound = 0;\n    int ret = 0, length;\n    word32 idx = 0;\n#ifndef NO_PKCS7_STREAM\n    word32 tmpIdx = 0;\n    long rc;\n#endif\n    word32 contentType, encOID = 0;\n    word32 decryptedKeySz = 0;\n    byte* pkiMsg = in;\n    word32 pkiMsgSz = inSz;\n\n    int expBlockSz = 0, blockKeySz = 0;\n    byte authTag[AES_BLOCK_SIZE];\n    byte nonce[GCM_NONCE_MID_SZ];       /* GCM nonce is larger than CCM */\n    int nonceSz = 0, authTagSz = 0, macSz = 0;\n\n#ifdef WOLFSSL_SMALL_STACK\n    byte* decryptedKey = NULL;\n#else\n    byte  decryptedKey[MAX_ENCRYPTED_KEY_SZ];\n#endif\n    int encryptedContentSz = 0;\n    byte* encryptedContent = NULL;\n    int explicitOctet = 0;\n\n    byte authAttribSetByte = 0;\n    byte* encodedAttribs = NULL;\n    word32 encodedAttribIdx = 0, encodedAttribSz = 0;\n    byte* authAttrib = NULL;\n    int authAttribSz = 0;\n    word32 localIdx;\n    byte tag;\n\n    if (pkcs7 == NULL)\n        return BAD_FUNC_ARG;\n\n    if (pkiMsg == NULL || pkiMsgSz == 0 ||\n        output == NULL || outputSz == 0)\n        return BAD_FUNC_ARG;\n#ifndef NO_PKCS7_STREAM\n    if (pkcs7->stream == NULL) {\n        if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {\n            return ret;\n        }\n    }\n#endif\n\n    switch (pkcs7->state) {\n        case WC_PKCS7_START:\n        case WC_PKCS7_INFOSET_START:\n        case WC_PKCS7_INFOSET_STAGE1:\n        case WC_PKCS7_INFOSET_STAGE2:\n        case WC_PKCS7_INFOSET_END:\n            ret = wc_PKCS7_ParseToRecipientInfoSet(pkcs7, pkiMsg, pkiMsgSz,\n                    &idx, AUTH_ENVELOPED_DATA);\n            if (ret < 0)\n                break;\n\n        #ifndef NO_PKCS7_STREAM\n            tmpIdx = idx;\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_2);\n            FALL_THROUGH;\n\n        case WC_PKCS7_AUTHENV_2:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +\n                            MAX_VERSION_SZ + ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {\n                break;\n            }\n        #endif\n        #ifdef WOLFSSL_SMALL_STACK\n            decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,\n                                                               DYNAMIC_TYPE_PKCS7);\n            if (decryptedKey == NULL) {\n                ret = MEMORY_E;\n                break;\n            }\n        #ifndef NO_PKCS7_STREAM\n            pkcs7->stream->key = decryptedKey;\n        #endif\n        #endif\n            FALL_THROUGH;\n\n        case WC_PKCS7_DECRYPT_KTRI:\n        case WC_PKCS7_DECRYPT_KTRI_2:\n        case WC_PKCS7_DECRYPT_KTRI_3:\n        case WC_PKCS7_DECRYPT_KARI:\n        case WC_PKCS7_DECRYPT_KEKRI:\n        case WC_PKCS7_DECRYPT_PWRI:\n        case WC_PKCS7_DECRYPT_ORI:\n\n            decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;\n        #ifdef WOLFSSL_SMALL_STACK\n            #ifndef NO_PKCS7_STREAM\n            decryptedKey = pkcs7->stream->key;\n            #endif\n        #endif\n\n            ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx,\n                                                decryptedKey, &decryptedKeySz,\n                                                &recipFound);\n            if (ret != 0) {\n                break;\n            }\n\n            if (recipFound == 0) {\n                WOLFSSL_MSG(\"No recipient found in envelopedData that matches input\");\n                ret = PKCS7_RECIP_E;\n                break;\n            }\n\n        #ifndef NO_PKCS7_STREAM\n            tmpIdx = idx;\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_3);\n            FALL_THROUGH;\n\n        case WC_PKCS7_AUTHENV_3:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +\n                            MAX_ALGO_SZ + MAX_ALGO_SZ + ASN_TAG_SZ,\n                            &pkiMsg, &idx)) != 0) {\n                break;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,\n                in, inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n        #endif\n\n            /* remove EncryptedContentInfo */\n            if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,\n                        pkiMsgSz) < 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,\n                        pkiMsgSz) < 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            blockKeySz = wc_PKCS7_GetOIDKeySize(encOID);\n            if (ret == 0 && blockKeySz < 0) {\n                ret = blockKeySz;\n            }\n\n            expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID);\n            if (ret == 0 && expBlockSz < 0) {\n                ret = expBlockSz;\n            }\n\n            /* get nonce, stored in OPTIONAL parameter of AlgoID */\n            if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && tag != ASN_OCTET_STRING) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret < 0)\n                break;\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {\n                break;\n            }\n            wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz, 0);\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_4);\n            FALL_THROUGH;\n\n        case WC_PKCS7_AUTHENV_4:\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +\n                            MAX_VERSION_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ,\n                            &pkiMsg, &idx)) != 0) {\n                break;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n        #endif\n            if (ret == 0 && GetLength(pkiMsg, &idx, &nonceSz, pkiMsgSz) < 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && nonceSz > (int)sizeof(nonce)) {\n                WOLFSSL_MSG(\"AuthEnvelopedData nonce too large for buffer\");\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0) {\n                XMEMCPY(nonce, &pkiMsg[idx], nonceSz);\n                idx += nonceSz;\n            }\n\n            /* get mac size, also stored in OPTIONAL parameter of AlgoID */\n            if (ret == 0 && GetMyVersion(pkiMsg, &idx, &macSz, pkiMsgSz) < 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0) {\n                explicitOctet = 0;\n                localIdx = idx;\n                if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&\n                        tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))\n                    explicitOctet = 1;\n            }\n\n            /* read encryptedContent, cont[0] */\n            if (ret == 0) {\n                ret = GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz);\n            }\n\n            if (ret == 0 &&\n                    tag != (ASN_CONTEXT_SPECIFIC | 0) &&\n                    tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,\n                        pkiMsgSz) <= 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (explicitOctet) {\n                if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {\n                    ret = ASN_PARSE_E;\n                }\n                if (ret == 0 && tag != ASN_OCTET_STRING) {\n                    ret = ASN_PARSE_E;\n                }\n\n                if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,\n                            pkiMsgSz) <= 0) {\n                    ret = ASN_PARSE_E;\n                }\n            }\n\n            if (ret < 0)\n                break;\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {\n                break;\n            }\n\n            /* store nonce for later */\n            if (nonceSz > 0) {\n                pkcs7->stream->nonceSz = nonceSz;\n                pkcs7->stream->nonce = (byte*)XMALLOC(nonceSz, pkcs7->heap,\n                        DYNAMIC_TYPE_PKCS7);\n                if (pkcs7->stream->nonce == NULL) {\n                    ret = MEMORY_E;\n                    break;\n                }\n                else {\n                    XMEMCPY(pkcs7->stream->nonce, nonce, nonceSz);\n                }\n            }\n\n            pkcs7->stream->expected = encryptedContentSz;\n            wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz,\n                    encryptedContentSz);\n        #endif\n\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_5);\n            FALL_THROUGH;\n\n        case WC_PKCS7_AUTHENV_5:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +\n                            ASN_TAG_SZ + ASN_TAG_SZ + pkcs7->stream->expected,\n                            &pkiMsg, &idx)) != 0) {\n                break;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n\n            encryptedContentSz = pkcs7->stream->expected;\n        #endif\n\n            encryptedContent = (byte*)XMALLOC(encryptedContentSz, pkcs7->heap,\n                                                               DYNAMIC_TYPE_PKCS7);\n            if (ret == 0 && encryptedContent == NULL) {\n                ret = MEMORY_E;\n            }\n\n            if (ret == 0) {\n                XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);\n                idx += encryptedContentSz;\n            }\n        #ifndef NO_PKCS7_STREAM\n                pkcs7->stream->bufferPt = encryptedContent;\n        #endif\n\n            /* may have IMPLICIT [1] authenticatedAttributes */\n            localIdx = idx;\n            if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&\n                    tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {\n                encodedAttribIdx = idx;\n                encodedAttribs = pkiMsg + idx;\n                idx++;\n\n                if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)\n                    ret = ASN_PARSE_E;\n            #ifndef NO_PKCS7_STREAM\n                pkcs7->stream->expected = length;\n            #endif\n                encodedAttribSz = length + (idx - encodedAttribIdx);\n\n                if (ret != 0)\n                    break;\n\n            #ifndef NO_PKCS7_STREAM\n                if (encodedAttribSz > 0) {\n                    pkcs7->stream->aadSz = encodedAttribSz;\n                    pkcs7->stream->aad = (byte*)XMALLOC(encodedAttribSz,\n                            pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                    if (pkcs7->stream->aad == NULL) {\n                        ret = MEMORY_E;\n                        break;\n                    }\n                    else {\n                        XMEMCPY(pkcs7->stream->aad, encodedAttribs,\n                                (idx - encodedAttribIdx));\n                    }\n                }\n\n                if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {\n                    break;\n                }\n            #endif\n                wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_ATRB);\n            }\n            else {\n            #ifndef NO_PKCS7_STREAM\n                if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {\n                    break;\n                }\n            #endif\n                goto authenv_atrbend; /* jump over attribute cases */\n            }\n            FALL_THROUGH;\n\n        case WC_PKCS7_AUTHENV_ATRB:\n    #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                            pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {\n                return ret;\n            }\n\n            length = pkcs7->stream->expected;\n            encodedAttribs = pkcs7->stream->aad;\n    #else\n            length = 0;\n    #endif\n\n            /* save pointer and length */\n            authAttrib = &pkiMsg[idx];\n            authAttribSz = length;\n\n            if (ret == 0 && wc_PKCS7_ParseAttribs(pkcs7, authAttrib, authAttribSz) < 0) {\n                WOLFSSL_MSG(\"Error parsing authenticated attributes\");\n                ret = ASN_PARSE_E;\n                break;\n            }\n\n            idx += length;\n\n    #ifndef NO_PKCS7_STREAM\n            if (encodedAttribSz > 0) {\n                XMEMCPY(pkcs7->stream->aad + (encodedAttribSz - length),\n                        authAttrib, authAttribSz);\n            }\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {\n                break;\n            }\n\n    #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_ATRBEND);\n            FALL_THROUGH;\n\nauthenv_atrbend:\n        case WC_PKCS7_AUTHENV_ATRBEND:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +\n                            ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,\n                in, inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n\n            if (pkcs7->stream->aadSz > 0) {\n                encodedAttribSz = pkcs7->stream->aadSz;\n                encodedAttribs  = pkcs7->stream->aad;\n            }\n        #endif\n\n\n            /* get authTag OCTET STRING */\n            if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {\n                ret = ASN_PARSE_E;\n            }\n            if (ret == 0 && tag != ASN_OCTET_STRING) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && GetLength(pkiMsg, &idx, &authTagSz, pkiMsgSz) < 0) {\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0 && authTagSz > (int)sizeof(authTag)) {\n                WOLFSSL_MSG(\"AuthEnvelopedData authTag too large for buffer\");\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret == 0) {\n                XMEMCPY(authTag, &pkiMsg[idx], authTagSz);\n                idx += authTagSz;\n            }\n\n            if (ret == 0 && authAttrib != NULL) {\n                /* temporarily swap authAttribs byte[0] to SET OF instead of\n                 * IMPLICIT [1], for aad calculation */\n                authAttribSetByte = encodedAttribs[0];\n\n                encodedAttribs[0] = ASN_SET | ASN_CONSTRUCTED;\n            }\n\n            if (ret < 0)\n                break;\n\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {\n                break;\n            }\n            pkcs7->stream->expected = (pkcs7->stream->maxLen -\n                pkcs7->stream->totalRd) + pkcs7->stream->length;\n\n\n            /* store tag for later */\n            if (authTagSz > 0) {\n                pkcs7->stream->tagSz = authTagSz;\n                pkcs7->stream->tag = (byte*)XMALLOC(authTagSz, pkcs7->heap,\n                        DYNAMIC_TYPE_PKCS7);\n                if (pkcs7->stream->tag == NULL) {\n                    ret = MEMORY_E;\n                    break;\n                }\n                else {\n                    XMEMCPY(pkcs7->stream->tag, authTag, authTagSz);\n                }\n            }\n\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_6);\n            FALL_THROUGH;\n\n        case WC_PKCS7_AUTHENV_6:\n        #ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                            pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {\n                break;\n            }\n\n            /* restore all variables needed */\n            if (pkcs7->stream->nonceSz > 0) {\n                nonceSz = pkcs7->stream->nonceSz;\n                if (nonceSz > GCM_NONCE_MID_SZ) {\n                    WOLFSSL_MSG(\"PKCS7 saved nonce is too large\");\n                    ret = BUFFER_E;\n                    break;\n                }\n                else {\n                    XMEMCPY(nonce, pkcs7->stream->nonce, nonceSz);\n                }\n            }\n\n            if (pkcs7->stream->tagSz > 0) {\n                authTagSz = pkcs7->stream->tagSz;\n                if (authTagSz > AES_BLOCK_SIZE) {\n                    WOLFSSL_MSG(\"PKCS7 saved tag is too large\");\n                    ret = BUFFER_E;\n                    break;\n                }\n                else {\n                    XMEMCPY(authTag, pkcs7->stream->tag, authTagSz);\n                }\n            }\n\n            if (pkcs7->stream->aadSz > 0) {\n                encodedAttribSz = pkcs7->stream->aadSz;\n                encodedAttribs  = pkcs7->stream->aad;\n            }\n\n            wc_PKCS7_StreamGetVar(pkcs7, &encOID, &blockKeySz, &encryptedContentSz);\n            encryptedContent   = pkcs7->stream->bufferPt;\n        #ifdef WOLFSSL_SMALL_STACK\n            decryptedKey = pkcs7->stream->key;\n        #endif\n        #endif\n\n            /* decrypt encryptedContent */\n            ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey,\n                    blockKeySz, nonce, nonceSz, encodedAttribs, encodedAttribSz,\n                    authTag, authTagSz, encryptedContent, encryptedContentSz,\n                    encryptedContent);\n            if (ret != 0) {\n                XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                return ret;\n            }\n\n            if (authAttrib != NULL) {\n                /* restore authAttrib IMPLICIT [1] */\n                encodedAttribs[0] = authAttribSetByte;\n            }\n\n            /* copy plaintext to output */\n            XMEMCPY(output, encryptedContent, encryptedContentSz);\n\n            /* free memory, zero out keys */\n            ForceZero(encryptedContent, encryptedContentSz);\n            XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            decryptedKey = NULL;\n        #ifdef WOLFSSL_SMALL_STACK\n            pkcs7->stream->key = NULL;\n        #endif\n        #endif\n            ret = encryptedContentSz;\n        #ifndef NO_PKCS7_STREAM\n            wc_PKCS7_ResetStream(pkcs7);\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);\n            break;\n        default:\n            WOLFSSL_MSG(\"Unknown PKCS7 state\");\n            ret = BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {\n        if (decryptedKey != NULL) {\n            ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);\n        }\n        XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    }\n#endif\n#ifndef NO_PKCS7_STREAM\n    if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {\n        wc_PKCS7_ResetStream(pkcs7);\n    }\n#endif\n\n    return ret;\n\n#else\n    WOLFSSL_MSG(\"AuthEnvelopedData requires AES-GCM or AES-CCM to be enabled\");\n    (void)pkcs7;\n    (void)in;\n    (void)inSz;\n    (void)output;\n    (void)outputSz;\n\n    return NOT_COMPILED_IN;\n#endif /* HAVE_AESGCM | HAVE_AESCCM */\n}\n\n\n#ifndef NO_PKCS7_ENCRYPTED_DATA\n\n/* build PKCS#7 encryptedData content type, return encrypted size */\nint wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz)\n{\n    int ret, idx = 0;\n    int totalSz, padSz, encryptedOutSz;\n\n    int contentInfoSeqSz, outerContentTypeSz, outerContentSz;\n    byte contentInfoSeq[MAX_SEQ_SZ];\n    byte outerContentType[MAX_ALGO_SZ];\n    byte outerContent[MAX_SEQ_SZ];\n\n    int encDataSeqSz, verSz, blockSz;\n    byte encDataSeq[MAX_SEQ_SZ];\n    byte ver[MAX_VERSION_SZ];\n\n    byte* plain = NULL;\n    byte* encryptedContent = NULL;\n\n    int encContentOctetSz, encContentSeqSz, contentTypeSz;\n    int contentEncAlgoSz, ivOctetStringSz;\n    byte encContentSeq[MAX_SEQ_SZ];\n    byte contentType[MAX_OID_SZ];\n    byte contentEncAlgo[MAX_ALGO_SZ];\n    byte tmpIv[MAX_CONTENT_IV_SIZE];\n    byte ivOctetString[MAX_OCTET_STR_SZ];\n    byte encContentOctet[MAX_OCTET_STR_SZ];\n\n    byte attribSet[MAX_SET_SZ];\n    EncodedAttrib* attribs = NULL;\n    word32 attribsSz;\n    word32 attribsCount;\n    word32 attribsSetSz;\n\n    byte* flatAttribs = NULL;\n\n    if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||\n        pkcs7->encryptOID == 0 || pkcs7->encryptionKey == NULL ||\n        pkcs7->encryptionKeySz == 0)\n        return BAD_FUNC_ARG;\n\n    if (output == NULL || outputSz == 0)\n        return BAD_FUNC_ARG;\n\n    if (pkcs7->version == 3) {\n        verSz = SetMyVersion(0, ver, 0);\n        outerContentTypeSz = 0;\n    }\n    else {\n        /* outer content type */\n        ret = wc_SetContentType(ENCRYPTED_DATA, outerContentType,\n                                sizeof(outerContentType));\n        if (ret < 0)\n            return ret;\n\n        outerContentTypeSz = ret;\n\n        /* version, 2 if unprotectedAttrs present, 0 if absent */\n        if (pkcs7->unprotectedAttribsSz > 0) {\n            verSz = SetMyVersion(2, ver, 0);\n        } else {\n            verSz = SetMyVersion(0, ver, 0);\n        }\n    }\n\n    /* EncryptedContentInfo */\n    ret = wc_SetContentType(pkcs7->contentOID, contentType,\n                            sizeof(contentType));\n    if (ret < 0)\n        return ret;\n\n    contentTypeSz = ret;\n\n    /* allocate encrypted content buffer, do PKCS#7 padding */\n    blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);\n    if (blockSz < 0)\n        return blockSz;\n\n    padSz = wc_PKCS7_GetPadSize(pkcs7->contentSz, blockSz);\n    if (padSz < 0)\n        return padSz;\n\n    encryptedOutSz = pkcs7->contentSz + padSz;\n\n    plain = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,\n                           DYNAMIC_TYPE_PKCS7);\n    if (plain == NULL)\n        return MEMORY_E;\n\n    ret = wc_PKCS7_PadData(pkcs7->content, pkcs7->contentSz, plain,\n                           encryptedOutSz, blockSz);\n    if (ret < 0) {\n        XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,\n                                      DYNAMIC_TYPE_PKCS7);\n    if (encryptedContent == NULL) {\n        XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return MEMORY_E;\n    }\n\n    /* put together IV OCTET STRING */\n    ivOctetStringSz = SetOctetString(blockSz, ivOctetString);\n\n    /* build up ContentEncryptionAlgorithmIdentifier sequence,\n       adding (ivOctetStringSz + blockSz) for IV OCTET STRING */\n    contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,\n                                 oidBlkType, ivOctetStringSz + blockSz);\n    if (contentEncAlgoSz == 0) {\n        XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return BAD_FUNC_ARG;\n    }\n\n    /* encrypt content */\n    WOLFSSL_MSG(\"Encrypting the content\");\n    ret = wc_PKCS7_GenerateBlock(pkcs7, NULL, tmpIv, blockSz);\n    if (ret != 0) {\n        XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->encryptionKey,\n            pkcs7->encryptionKeySz, tmpIv, blockSz, NULL, 0, NULL, 0,\n            plain, encryptedOutSz, encryptedContent);\n    if (ret != 0) {\n        XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0,\n                                    encryptedOutSz, encContentOctet);\n\n    encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +\n                                  ivOctetStringSz + blockSz +\n                                  encContentOctetSz + encryptedOutSz,\n                                  encContentSeq);\n\n    /* optional UnprotectedAttributes */\n    if (pkcs7->unprotectedAttribsSz != 0) {\n\n        if (pkcs7->unprotectedAttribs == NULL) {\n            XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return BAD_FUNC_ARG;\n        }\n\n        attribs = (EncodedAttrib*)XMALLOC(\n                sizeof(EncodedAttrib) * pkcs7->unprotectedAttribsSz,\n                pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        if (attribs == NULL) {\n            XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return MEMORY_E;\n        }\n\n        attribsCount = pkcs7->unprotectedAttribsSz;\n        attribsSz = EncodeAttributes(attribs, pkcs7->unprotectedAttribsSz,\n                                     pkcs7->unprotectedAttribs,\n                                     pkcs7->unprotectedAttribsSz);\n\n        flatAttribs = (byte*)XMALLOC(attribsSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        if (flatAttribs == NULL) {\n            XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return MEMORY_E;\n        }\n\n        FlattenAttributes(pkcs7, flatAttribs, attribs, attribsCount);\n        attribsSetSz = SetImplicit(ASN_SET, 1, attribsSz, attribSet);\n\n    } else {\n        attribsSz = 0;\n        attribsSetSz = 0;\n    }\n\n    /* keep track of sizes for outer wrapper layering */\n    totalSz = verSz + encContentSeqSz + contentTypeSz + contentEncAlgoSz +\n              ivOctetStringSz + blockSz + encContentOctetSz + encryptedOutSz +\n              attribsSz + attribsSetSz;\n\n    /* EncryptedData */\n    encDataSeqSz = SetSequence(totalSz, encDataSeq);\n    totalSz += encDataSeqSz;\n\n    if (pkcs7->version != 3) {\n        /* outer content */\n        outerContentSz = SetExplicit(0, totalSz, outerContent);\n        totalSz += outerContentTypeSz;\n        totalSz += outerContentSz;\n        /* ContentInfo */\n        contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);\n        totalSz += contentInfoSeqSz;\n    } else {\n        contentInfoSeqSz = 0;\n        outerContentSz = 0;\n    }\n\n    if (totalSz > (int)outputSz) {\n        WOLFSSL_MSG(\"PKCS#7 output buffer too small\");\n        if (pkcs7->unprotectedAttribsSz != 0) {\n            XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        }\n        XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return BUFFER_E;\n    }\n\n    XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);\n    idx += contentInfoSeqSz;\n    XMEMCPY(output + idx, outerContentType, outerContentTypeSz);\n    idx += outerContentTypeSz;\n    XMEMCPY(output + idx, outerContent, outerContentSz);\n    idx += outerContentSz;\n    XMEMCPY(output + idx, encDataSeq, encDataSeqSz);\n    idx += encDataSeqSz;\n    XMEMCPY(output + idx, ver, verSz);\n    idx += verSz;\n    XMEMCPY(output + idx, encContentSeq, encContentSeqSz);\n    idx += encContentSeqSz;\n    XMEMCPY(output + idx, contentType, contentTypeSz);\n    idx += contentTypeSz;\n    XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);\n    idx += contentEncAlgoSz;\n    XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);\n    idx += ivOctetStringSz;\n    XMEMCPY(output + idx, tmpIv, blockSz);\n    idx += blockSz;\n    XMEMCPY(output + idx, encContentOctet, encContentOctetSz);\n    idx += encContentOctetSz;\n    XMEMCPY(output + idx, encryptedContent, encryptedOutSz);\n    idx += encryptedOutSz;\n\n    if (pkcs7->unprotectedAttribsSz != 0) {\n        XMEMCPY(output + idx, attribSet, attribsSetSz);\n        idx += attribsSetSz;\n        XMEMCPY(output + idx, flatAttribs, attribsSz);\n        idx += attribsSz;\n        XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    }\n\n    XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n\n    return idx;\n}\n\n\n/* decode and store unprotected attributes in PKCS7->decodedAttrib. Return\n * 0 on success, negative on error. User must call wc_PKCS7_Free(). */\nstatic int wc_PKCS7_DecodeUnprotectedAttributes(PKCS7* pkcs7, byte* pkiMsg,\n                                             word32 pkiMsgSz, word32* inOutIdx)\n{\n    int ret, attribLen;\n    word32 idx;\n    byte tag;\n\n    if (pkcs7 == NULL || pkiMsg == NULL ||\n        pkiMsgSz == 0 || inOutIdx == NULL)\n        return BAD_FUNC_ARG;\n\n    idx = *inOutIdx;\n\n    if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))\n        return ASN_PARSE_E;\n\n    if (GetLength(pkiMsg, &idx, &attribLen, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    /* loop through attributes */\n    if ((ret = wc_PKCS7_ParseAttribs(pkcs7, pkiMsg + idx, attribLen)) < 0) {\n        return ret;\n    }\n\n    *inOutIdx = idx;\n\n    return 0;\n}\n\n\n/* unwrap and decrypt PKCS#7/CMS encrypted-data object, returned decoded size */\nint wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz,\n                                 byte* output, word32 outputSz)\n{\n    int ret = 0, version, length = 0, haveAttribs = 0;\n    word32 idx = 0;\n\n#ifndef NO_PKCS7_STREAM\n    word32 tmpIdx = 0;\n    long rc;\n#endif\n    word32 contentType, encOID;\n\n    int expBlockSz = 0;\n    byte tmpIvBuf[MAX_CONTENT_IV_SIZE];\n    byte *tmpIv = tmpIvBuf;\n\n    int encryptedContentSz = 0;\n    byte padLen;\n    byte* encryptedContent = NULL;\n\n    byte* pkiMsg = in;\n    word32 pkiMsgSz = inSz;\n    byte  tag;\n\n    if (pkcs7 == NULL ||\n            ((pkcs7->encryptionKey == NULL || pkcs7->encryptionKeySz == 0) &&\n              pkcs7->decryptionCb == NULL))\n        return BAD_FUNC_ARG;\n\n    if (pkiMsg == NULL || pkiMsgSz == 0 ||\n        output == NULL || outputSz == 0)\n        return BAD_FUNC_ARG;\n\n#ifndef NO_PKCS7_STREAM\n    (void)tmpIv; /* help out static analysis */\n    if (pkcs7->stream == NULL) {\n        if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {\n            return ret;\n        }\n    }\n#endif\n\n    switch (pkcs7->state) {\n        case WC_PKCS7_START:\n#ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +\n                            MAX_ALGO_SZ, &pkiMsg, &idx)) != 0) {\n                return ret;\n            }\n\n            rc  = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK, in, inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n#endif\n\n            if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)\n                ret = ASN_PARSE_E;\n\n            if (pkcs7->version != 3) { /* ContentInfo not in firmware bundles */\n                /* read past ContentInfo, verify type is encrypted-data */\n                if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,\n                            pkiMsgSz) < 0)\n                    ret = ASN_PARSE_E;\n\n                if (ret == 0 && contentType != ENCRYPTED_DATA) {\n                    WOLFSSL_MSG(\"PKCS#7 input not of type EncryptedData\");\n                    ret = PKCS7_OID_E;\n                }\n            }\n            if (ret != 0) break;\n#ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {\n                break;\n            }\n#endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE2);\n            FALL_THROUGH;\n            /* end of stage 1 */\n\n        case WC_PKCS7_STAGE2:\n#ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                            MAX_LENGTH_SZ + MAX_SEQ_SZ + ASN_TAG_SZ, &pkiMsg,\n                            &idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n#endif\n            if (pkcs7->version != 3) {\n                if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)\n                    ret = ASN_PARSE_E;\n                if (ret == 0 && tag !=\n                        (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))\n                    ret = ASN_PARSE_E;\n\n                if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)\n                    ret = ASN_PARSE_E;\n\n                /* remove EncryptedData and version */\n                if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)\n                    ret = ASN_PARSE_E;\n            }\n\n            if (ret != 0) break;\n#ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {\n                break;\n            }\n#endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE3);\n            FALL_THROUGH;\n            /* end of stage 2 */\n\n       case WC_PKCS7_STAGE3:\n#ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                            MAX_VERSION_SZ + MAX_SEQ_SZ + MAX_ALGO_SZ * 2,\n                            &pkiMsg, &idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n#endif\n            /* get version, check later */\n            haveAttribs = 0;\n            if (ret == 0 && GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)\n                ret = ASN_PARSE_E;\n\n            /* remove EncryptedContentInfo */\n            if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)\n                ret = ASN_PARSE_E;\n\n            if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,\n                        pkiMsgSz) < 0)\n                ret = ASN_PARSE_E;\n\n            if (ret == 0 && (ret = GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,\n                        pkiMsgSz)) < 0)\n                ret = ASN_PARSE_E;\n            if (ret == 0 && (expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID)) < 0)\n                ret = expBlockSz;\n\n            if (ret != 0) break;\n#ifndef NO_PKCS7_STREAM\n            /* store expBlockSz for later */\n            pkcs7->stream->varOne = expBlockSz;\n            pkcs7->stream->varTwo = encOID;\n\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {\n                break;\n            }\n\n            /* store version for later */\n            pkcs7->stream->vers = version;\n#endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE4);\n            FALL_THROUGH;\n            /* end of stage 3 */\n\n        /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */\n       case WC_PKCS7_STAGE4:\n#ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                            ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n\n            /* restore saved variables */\n            expBlockSz = pkcs7->stream->varOne;\n#endif\n            if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)\n                ret = ASN_PARSE_E;\n            if (ret == 0 && tag != ASN_OCTET_STRING)\n                ret = ASN_PARSE_E;\n\n            if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)\n                ret = ASN_PARSE_E;\n\n            if (ret == 0 && length != expBlockSz) {\n                WOLFSSL_MSG(\"Incorrect IV length, must be of content alg block size\");\n                ret = ASN_PARSE_E;\n            }\n\n            if (ret != 0) break;\n#ifndef NO_PKCS7_STREAM\n            /* next chunk of data expected should have the IV */\n            pkcs7->stream->expected = length;\n\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {\n                break;\n            }\n#endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE5);\n            FALL_THROUGH;\n            /* end of stage 4 */\n\n       case WC_PKCS7_STAGE5:\n#ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                            pkcs7->stream->expected + ASN_TAG_SZ +\n                            MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n\n            /* use IV buffer from stream structure */\n            tmpIv  = pkcs7->stream->tmpIv;\n            length = pkcs7->stream->expected;\n#endif\n            XMEMCPY(tmpIv, &pkiMsg[idx], length);\n            idx += length;\n            /* read encryptedContent, cont[0] */\n            if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)\n                ret = ASN_PARSE_E;\n            if (ret == 0 && tag != (ASN_CONTEXT_SPECIFIC | 0))\n                ret = ASN_PARSE_E;\n\n            if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,\n                        pkiMsgSz) <= 0)\n                ret = ASN_PARSE_E;\n\n            if (ret < 0)\n                break;\n#ifndef NO_PKCS7_STREAM\n            /* next chunk of data should contain encrypted content */\n            pkcs7->stream->varThree = encryptedContentSz;\n            if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {\n                break;\n            }\n\n            if (pkcs7->stream->totalRd +  encryptedContentSz < pkiMsgSz) {\n                pkcs7->stream->flagOne = 1;\n            }\n\n            pkcs7->stream->expected = (pkcs7->stream->maxLen -\n                pkcs7->stream->totalRd) + pkcs7->stream->length;\n\n#endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE6);\n            FALL_THROUGH;\n            /* end of stage 5 */\n\n        case WC_PKCS7_STAGE6:\n#ifndef NO_PKCS7_STREAM\n            if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,\n                            pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {\n                return ret;\n            }\n\n            rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,\n                    inSz);\n            if (rc < 0) {\n                ret = (int)rc;\n                break;\n            }\n            pkiMsgSz = (word32)rc;\n\n            /* restore saved variables */\n            expBlockSz = pkcs7->stream->varOne;\n            encOID     = pkcs7->stream->varTwo;\n            encryptedContentSz = pkcs7->stream->varThree;\n            version    = pkcs7->stream->vers;\n            tmpIv      = pkcs7->stream->tmpIv;\n#else\n            encOID = 0;\n#endif\n            if (ret == 0 && (encryptedContent = (byte*)XMALLOC(\n                encryptedContentSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7)) == NULL) {\n                ret = MEMORY_E;\n                break;\n            }\n\n            if (ret == 0) {\n                XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);\n                idx += encryptedContentSz;\n            }\n\n            /* decrypt encryptedContent */\n            if (ret == 0) {\n                ret = wc_PKCS7_DecryptContent(pkcs7, encOID,\n                            pkcs7->encryptionKey, pkcs7->encryptionKeySz, tmpIv,\n                            expBlockSz, NULL, 0, NULL, 0, encryptedContent,\n                            encryptedContentSz, encryptedContent);\n                if (ret != 0) {\n                    XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                }\n            }\n\n            if (ret == 0) {\n                padLen = encryptedContent[encryptedContentSz-1];\n\n                if (padLen > encryptedContentSz) {\n                    WOLFSSL_MSG(\"Bad padding size found\");\n                    ret = BUFFER_E;\n                    XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                    break;\n                }\n\n                /* copy plaintext to output */\n                XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);\n\n                /* get implicit[1] unprotected attributes, optional */\n                wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap);\n                pkcs7->decodedAttrib = NULL;\n            #ifndef NO_PKCS7_STREAM\n                if (pkcs7->stream->flagOne)\n            #else\n                if (idx < pkiMsgSz)\n            #endif\n                {\n                    haveAttribs = 1;\n\n                    ret = wc_PKCS7_DecodeUnprotectedAttributes(pkcs7, pkiMsg,\n                                                       pkiMsgSz, &idx);\n                    if (ret != 0) {\n                        ForceZero(encryptedContent, encryptedContentSz);\n                        XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n                        ret = ASN_PARSE_E;\n                    }\n                }\n            }\n\n            if (ret == 0) {\n                ForceZero(encryptedContent, encryptedContentSz);\n                XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n\n                /* go back and check the version now that attribs have been processed */\n                if (pkcs7->version == 3 && version != 0) {\n                    WOLFSSL_MSG(\"Wrong PKCS#7 FirmwareEncryptedData version\");\n                    return ASN_VERSION_E;\n                }\n\n                if (pkcs7->version != 3 &&\n                   ((haveAttribs == 0 && version != 0) ||\n                    (haveAttribs == 1 && version != 2))) {\n                    WOLFSSL_MSG(\"Wrong PKCS#7 EncryptedData version\");\n                    return ASN_VERSION_E;\n                }\n                ret = encryptedContentSz - padLen;\n            }\n\n            if (ret != 0) break;\n        #ifndef NO_PKCS7_STREAM\n            wc_PKCS7_ResetStream(pkcs7);\n        #endif\n            wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);\n            break;\n\n        default:\n            WOLFSSL_MSG(\"Error in unknown PKCS#7 Decode Encrypted Data state\");\n            return BAD_STATE_E;\n    }\n\n    if (ret != 0) {\n    #ifndef NO_PKCS7_STREAM\n        /* restart in error case */\n        wc_PKCS7_ResetStream(pkcs7);\n    #endif\n        wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);\n    }\n    return ret;\n}\n\n\n/* Function to set callback during decryption, this overrides the default\n * decryption function and can be used for choosing a key at run time based\n * on the parsed bundle so far.\n * returns 0 on success\n */\nint wc_PKCS7_SetDecodeEncryptedCb(PKCS7* pkcs7,\n        CallbackDecryptContent decryptionCb)\n{\n    if (pkcs7 != NULL) {\n        pkcs7->decryptionCb = decryptionCb;\n    }\n    return 0;\n}\n\n\n/* Set an optional user context that gets passed to callback\n * returns 0 on success\n */\nint wc_PKCS7_SetDecodeEncryptedCtx(PKCS7* pkcs7, void* ctx)\n{\n    if (pkcs7 != NULL) {\n        pkcs7->decryptionCtx = ctx;\n    }\n    return 0;\n}\n#endif /* NO_PKCS7_ENCRYPTED_DATA */\n\n#if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)\n\n/* build PKCS#7 compressedData content type, return encrypted size */\nint wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output, word32 outputSz)\n{\n    byte contentInfoSeq[MAX_SEQ_SZ];\n    byte contentInfoTypeOid[MAX_OID_SZ];\n    byte contentInfoContentSeq[MAX_SEQ_SZ]; /* EXPLICIT [0] */\n    byte compressedDataSeq[MAX_SEQ_SZ];\n    byte cmsVersion[MAX_VERSION_SZ];\n    byte compressAlgId[MAX_ALGO_SZ];\n    byte encapContentInfoSeq[MAX_SEQ_SZ];\n    byte contentTypeOid[MAX_OID_SZ];\n    byte contentSeq[MAX_SEQ_SZ];            /* EXPLICIT [0] */\n    byte contentOctetStr[MAX_OCTET_STR_SZ];\n\n    int ret;\n    word32 totalSz, idx;\n    word32 contentInfoSeqSz, contentInfoContentSeqSz, contentInfoTypeOidSz;\n    word32 compressedDataSeqSz, cmsVersionSz, compressAlgIdSz;\n    word32 encapContentInfoSeqSz, contentTypeOidSz, contentSeqSz;\n    word32 contentOctetStrSz;\n\n    byte* compressed;\n    word32 compressedSz;\n\n    if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||\n        output == NULL || outputSz == 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* allocate space for compressed content. The libz code says the compressed\n     * buffer should be srcSz + 0.1% + 12. */\n    compressedSz = (pkcs7->contentSz + (word32)(pkcs7->contentSz * 0.001) + 12);\n    compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (compressed == NULL) {\n        WOLFSSL_MSG(\"Error allocating memory for CMS compressed content\");\n        return MEMORY_E;\n    }\n\n    /* compress content */\n    ret = wc_Compress(compressed, compressedSz, pkcs7->content,\n                      pkcs7->contentSz, 0);\n    if (ret < 0) {\n        XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n    compressedSz = (word32)ret;\n\n    /* eContent OCTET STRING, working backwards */\n    contentOctetStrSz = SetOctetString(compressedSz, contentOctetStr);\n    totalSz = contentOctetStrSz + compressedSz;\n\n    /* EXPLICIT [0] eContentType */\n    contentSeqSz = SetExplicit(0, totalSz, contentSeq);\n    totalSz += contentSeqSz;\n\n    /* eContentType OBJECT IDENTIFIER */\n    ret = wc_SetContentType(pkcs7->contentOID, contentTypeOid,\n                            sizeof(contentTypeOid));\n    if (ret < 0) {\n        XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n\n    contentTypeOidSz = ret;\n    totalSz += contentTypeOidSz;\n\n    /* EncapsulatedContentInfo SEQUENCE */\n    encapContentInfoSeqSz = SetSequence(totalSz, encapContentInfoSeq);\n    totalSz += encapContentInfoSeqSz;\n\n    /* compressionAlgorithm AlgorithmIdentifier */\n    /* Only supports zlib for compression currently:\n     * id-alg-zlibCompress (1.2.840.113549.1.9.16.3.8) */\n    compressAlgIdSz = SetAlgoID(ZLIBc, compressAlgId, oidCompressType, 0);\n    totalSz += compressAlgIdSz;\n\n    /* version */\n    cmsVersionSz = SetMyVersion(0, cmsVersion, 0);\n    totalSz += cmsVersionSz;\n\n    /* CompressedData SEQUENCE */\n    compressedDataSeqSz = SetSequence(totalSz, compressedDataSeq);\n    totalSz += compressedDataSeqSz;\n\n    /* ContentInfo content EXPLICIT SEQUENCE */\n    contentInfoContentSeqSz = SetExplicit(0, totalSz, contentInfoContentSeq);\n    totalSz += contentInfoContentSeqSz;\n\n    /* ContentInfo ContentType (compressedData) */\n    if (pkcs7->version == 3) {\n        contentInfoTypeOidSz = 0;\n    }\n    else {\n        ret = wc_SetContentType(COMPRESSED_DATA, contentInfoTypeOid,\n                                sizeof(contentInfoTypeOid));\n        if (ret < 0) {\n            XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n            return ret;\n        }\n\n        contentInfoTypeOidSz = ret;\n        totalSz += contentInfoTypeOidSz;\n    }\n\n    /* ContentInfo SEQUENCE */\n    contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);\n    totalSz += contentInfoSeqSz;\n\n    if (outputSz < totalSz) {\n        XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return BUFFER_E;\n    }\n\n    idx = 0;\n    XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);\n    idx += contentInfoSeqSz;\n    XMEMCPY(output + idx, contentInfoTypeOid, contentInfoTypeOidSz);\n    idx += contentInfoTypeOidSz;\n    XMEMCPY(output + idx, contentInfoContentSeq, contentInfoContentSeqSz);\n    idx += contentInfoContentSeqSz;\n    XMEMCPY(output + idx, compressedDataSeq, compressedDataSeqSz);\n    idx += compressedDataSeqSz;\n    XMEMCPY(output + idx, cmsVersion, cmsVersionSz);\n    idx += cmsVersionSz;\n    XMEMCPY(output + idx, compressAlgId, compressAlgIdSz);\n    idx += compressAlgIdSz;\n    XMEMCPY(output + idx, encapContentInfoSeq, encapContentInfoSeqSz);\n    idx += encapContentInfoSeqSz;\n    XMEMCPY(output + idx, contentTypeOid, contentTypeOidSz);\n    idx += contentTypeOidSz;\n    XMEMCPY(output + idx, contentSeq, contentSeqSz);\n    idx += contentSeqSz;\n    XMEMCPY(output + idx, contentOctetStr, contentOctetStrSz);\n    idx += contentOctetStrSz;\n    XMEMCPY(output + idx, compressed, compressedSz);\n    idx += compressedSz;\n\n    XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n\n    return idx;\n}\n\n/* unwrap and decompress PKCS#7/CMS compressedData object,\n * returned decoded size */\nint wc_PKCS7_DecodeCompressedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,\n                                  byte* output, word32 outputSz)\n{\n    int length, version, ret;\n    word32 idx = 0, algOID, contentType;\n    byte tag;\n\n    byte* decompressed;\n    word32 decompressedSz;\n\n    if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0 ||\n        output == NULL || outputSz == 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* get ContentInfo SEQUENCE */\n    if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    if (pkcs7->version != 3) {\n        /* get ContentInfo contentType */\n        if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)\n            return ASN_PARSE_E;\n\n        if (contentType != COMPRESSED_DATA)\n            return ASN_PARSE_E;\n    }\n\n    /* get ContentInfo content EXPLICIT SEQUENCE */\n    if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))\n        return ASN_PARSE_E;\n\n    if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    /* get CompressedData SEQUENCE */\n    if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    /* get version */\n    if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    if (version != 0) {\n        WOLFSSL_MSG(\"CMS CompressedData version MUST be 0, but is not\");\n        return ASN_PARSE_E;\n    }\n\n    /* get CompressionAlgorithmIdentifier */\n    if (GetAlgoId(pkiMsg, &idx, &algOID, oidIgnoreType, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    /* Only supports zlib for compression currently:\n     * id-alg-zlibCompress (1.2.840.113549.1.9.16.3.8) */\n    if (algOID != ZLIBc) {\n        WOLFSSL_MSG(\"CMS CompressedData only supports zlib algorithm\");\n        return ASN_PARSE_E;\n    }\n\n    /* get EncapsulatedContentInfo SEQUENCE */\n    if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    /* get ContentType OID */\n    if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    pkcs7->contentOID = contentType;\n\n    /* get eContent EXPLICIT SEQUENCE */\n    if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))\n        return ASN_PARSE_E;\n\n    if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    /* get content OCTET STRING */\n    if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    if (tag != ASN_OCTET_STRING)\n        return ASN_PARSE_E;\n\n    if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)\n        return ASN_PARSE_E;\n\n    /* allocate space for decompressed data */\n    decompressed = (byte*)XMALLOC(length, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n    if (decompressed == NULL) {\n        WOLFSSL_MSG(\"Error allocating memory for CMS decompression buffer\");\n        return MEMORY_E;\n    }\n\n    /* decompress content */\n    ret = wc_DeCompress(decompressed, length, &pkiMsg[idx], length);\n    if (ret < 0) {\n        XFREE(decompressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return ret;\n    }\n    decompressedSz = (word32)ret;\n\n    /* get content */\n    if (outputSz < decompressedSz) {\n        WOLFSSL_MSG(\"CMS output buffer too small to hold decompressed data\");\n        XFREE(decompressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n        return BUFFER_E;\n    }\n\n    XMEMCPY(output, decompressed, decompressedSz);\n    XFREE(decompressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);\n\n    return decompressedSz;\n}\n\n#endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */\n\n#else  /* HAVE_PKCS7 */\n\n\n#ifdef _MSC_VER\n    /* 4206 warning for blank file */\n    #pragma warning(disable: 4206)\n#endif\n\n\n#endif /* HAVE_PKCS7 */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/poly1305.c",
    "content": "/* poly1305.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*\n * Based off the public domain implementations by Andrew Moon\n * and Daniel J. Bernstein\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_POLY1305\n#include <wolfssl/wolfcrypt/poly1305.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#include <wolfssl/wolfcrypt/cpuid.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n#ifdef CHACHA_AEAD_TEST\n    #include <stdio.h>\n#endif\n\n#ifdef _MSC_VER\n    /* 4127 warning constant while(1)  */\n    #pragma warning(disable: 4127)\n#endif\n\n#ifdef USE_INTEL_SPEEDUP\n    #include <emmintrin.h>\n    #include <immintrin.h>\n\n    #if defined(__GNUC__) && ((__GNUC__ < 4) || \\\n                              (__GNUC__ == 4 && __GNUC_MINOR__ <= 8))\n        #undef  NO_AVX2_SUPPORT\n        #define NO_AVX2_SUPPORT\n    #endif\n    #if defined(__clang__) && ((__clang_major__ < 3) || \\\n                               (__clang_major__ == 3 && __clang_minor__ <= 5))\n        #define NO_AVX2_SUPPORT\n    #elif defined(__clang__) && defined(NO_AVX2_SUPPORT)\n        #undef NO_AVX2_SUPPORT\n    #endif\n\n    #define HAVE_INTEL_AVX1\n    #ifndef NO_AVX2_SUPPORT\n        #define HAVE_INTEL_AVX2\n    #endif\n#endif\n\n#ifdef USE_INTEL_SPEEDUP\nstatic word32 intel_flags = 0;\nstatic word32 cpu_flags_set = 0;\n#endif\n\n#if defined(USE_INTEL_SPEEDUP) || defined(POLY130564)\n    #if defined(_MSC_VER)\n        #define POLY1305_NOINLINE __declspec(noinline)\n    #elif defined(__GNUC__)\n        #define POLY1305_NOINLINE __attribute__((noinline))\n    #else\n        #define POLY1305_NOINLINE\n    #endif\n\n    #if defined(_MSC_VER)\n        #include <intrin.h>\n\n        typedef struct word128 {\n            word64 lo;\n            word64 hi;\n        } word128;\n\n        #define MUL(out, x, y) out.lo = _umul128((x), (y), &out.hi)\n        #define ADD(out, in) { word64 t = out.lo; out.lo += in.lo; \\\n                               out.hi += (out.lo < t) + in.hi; }\n        #define ADDLO(out, in) { word64 t = out.lo; out.lo += in; \\\n                                 out.hi += (out.lo < t); }\n        #define SHR(in, shift) (__shiftright128(in.lo, in.hi, (shift)))\n        #define LO(in) (in.lo)\n\n    #elif defined(__GNUC__)\n        #if defined(__SIZEOF_INT128__)\n            typedef unsigned __int128 word128;\n        #else\n            typedef unsigned word128 __attribute__((mode(TI)));\n        #endif\n\n        #define MUL(out, x, y) out = ((word128)x * y)\n        #define ADD(out, in) out += in\n        #define ADDLO(out, in) out += in\n        #define SHR(in, shift) (word64)(in >> (shift))\n        #define LO(in) (word64)(in)\n    #endif\n#endif\n\n#ifdef USE_INTEL_SPEEDUP\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifdef HAVE_INTEL_AVX1\n/* Process one block (16 bytes) of data.\n *\n * ctx  Poly1305 context.\n * m    One block of message data.\n */\nextern void poly1305_block_avx(Poly1305* ctx, const unsigned char *m);\n/* Process multiple blocks (n * 16 bytes) of data.\n *\n * ctx    Poly1305 context.\n * m      Blocks of message data.\n * bytes  The number of bytes to process.\n */\nextern void poly1305_blocks_avx(Poly1305* ctx, const unsigned char* m,\n                                size_t bytes);\n/* Set the key to use when processing data.\n * Initialize the context.\n *\n * ctx  Poly1305 context.\n * key  The key data (16 bytes).\n */\nextern void poly1305_setkey_avx(Poly1305* ctx, const byte* key);\n/* Calculate the final result - authentication data.\n * Zeros out the private data in the context.\n *\n * ctx  Poly1305 context.\n * mac  Buffer to hold 16 bytes.\n */\nextern void poly1305_final_avx(Poly1305* ctx, byte* mac);\n#endif\n\n#ifdef HAVE_INTEL_AVX2\n/* Process multiple blocks (n * 16 bytes) of data.\n *\n * ctx    Poly1305 context.\n * m      Blocks of message data.\n * bytes  The number of bytes to process.\n */\nextern void poly1305_blocks_avx2(Poly1305* ctx, const unsigned char* m,\n                                 size_t bytes);\n/* Calculate R^1, R^2, R^3 and R^4 and store them in the context.\n *\n * ctx    Poly1305 context.\n */\nextern void poly1305_calc_powers_avx2(Poly1305* ctx);\n/* Set the key to use when processing data.\n * Initialize the context.\n * Calls AVX set key function as final function calls AVX code.\n *\n * ctx  Poly1305 context.\n * key  The key data (16 bytes).\n */\nextern void poly1305_setkey_avx2(Poly1305* ctx, const byte* key);\n/* Calculate the final result - authentication data.\n * Zeros out the private data in the context.\n * Calls AVX final function to quickly process last blocks.\n *\n * ctx  Poly1305 context.\n * mac  Buffer to hold 16 bytes - authentication data.\n */\nextern void poly1305_final_avx2(Poly1305* ctx, byte* mac);\n#endif\n\n#ifdef __cplusplus\n    }  /* extern \"C\" */\n#endif\n\n#elif defined(POLY130564)\n#ifndef WOLFSSL_ARMASM\n    static word64 U8TO64(const byte* p)\n    {\n        return\n            (((word64)(p[0] & 0xff)      ) |\n             ((word64)(p[1] & 0xff) <<  8) |\n             ((word64)(p[2] & 0xff) << 16) |\n             ((word64)(p[3] & 0xff) << 24) |\n             ((word64)(p[4] & 0xff) << 32) |\n             ((word64)(p[5] & 0xff) << 40) |\n             ((word64)(p[6] & 0xff) << 48) |\n             ((word64)(p[7] & 0xff) << 56));\n    }\n\n    static void U64TO8(byte* p, word64 v) {\n        p[0] = (v      ) & 0xff;\n        p[1] = (v >>  8) & 0xff;\n        p[2] = (v >> 16) & 0xff;\n        p[3] = (v >> 24) & 0xff;\n        p[4] = (v >> 32) & 0xff;\n        p[5] = (v >> 40) & 0xff;\n        p[6] = (v >> 48) & 0xff;\n        p[7] = (v >> 56) & 0xff;\n    }\n#endif/* WOLFSSL_ARMASM */\n#else /* if not 64 bit then use 32 bit */\n\n    static word32 U8TO32(const byte *p)\n    {\n        return\n            (((word32)(p[0] & 0xff)      ) |\n             ((word32)(p[1] & 0xff) <<  8) |\n             ((word32)(p[2] & 0xff) << 16) |\n             ((word32)(p[3] & 0xff) << 24));\n    }\n\n    static void U32TO8(byte *p, word32 v) {\n        p[0] = (v      ) & 0xff;\n        p[1] = (v >>  8) & 0xff;\n        p[2] = (v >> 16) & 0xff;\n        p[3] = (v >> 24) & 0xff;\n    }\n#endif\n\n\nstatic void U32TO64(word32 v, byte* p)\n{\n    XMEMSET(p, 0, 8);\n    p[0] = (v & 0xFF);\n    p[1] = (v >>  8) & 0xFF;\n    p[2] = (v >> 16) & 0xFF;\n    p[3] = (v >> 24) & 0xFF;\n}\n\n#if !defined(WOLFSSL_ARMASM) || !defined(__aarch64__)\nvoid poly1305_blocks(Poly1305* ctx, const unsigned char *m,\n                     size_t bytes)\n{\n#ifdef USE_INTEL_SPEEDUP\n    /* AVX2 is handled in wc_Poly1305Update. */\n    poly1305_blocks_avx(ctx, m, bytes);\n#elif defined(POLY130564)\n    const word64 hibit = (ctx->finished) ? 0 : ((word64)1 << 40); /* 1 << 128 */\n    word64 r0,r1,r2;\n    word64 s1,s2;\n    word64 h0,h1,h2;\n    word64 c;\n    word128 d0,d1,d2,d;\n\n    r0 = ctx->r[0];\n    r1 = ctx->r[1];\n    r2 = ctx->r[2];\n\n    h0 = ctx->h[0];\n    h1 = ctx->h[1];\n    h2 = ctx->h[2];\n\n    s1 = r1 * (5 << 2);\n    s2 = r2 * (5 << 2);\n\n    while (bytes >= POLY1305_BLOCK_SIZE) {\n        word64 t0,t1;\n\n        /* h += m[i] */\n        t0 = U8TO64(&m[0]);\n        t1 = U8TO64(&m[8]);\n\n        h0 += (( t0                    ) & 0xfffffffffff);\n        h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff);\n        h2 += (((t1 >> 24)             ) & 0x3ffffffffff) | hibit;\n\n        /* h *= r */\n        MUL(d0, h0, r0); MUL(d, h1, s2); ADD(d0, d); MUL(d, h2, s1); ADD(d0, d);\n        MUL(d1, h0, r1); MUL(d, h1, r0); ADD(d1, d); MUL(d, h2, s2); ADD(d1, d);\n        MUL(d2, h0, r2); MUL(d, h1, r1); ADD(d2, d); MUL(d, h2, r0); ADD(d2, d);\n\n        /* (partial) h %= p */\n                      c = SHR(d0, 44); h0 = LO(d0) & 0xfffffffffff;\n        ADDLO(d1, c); c = SHR(d1, 44); h1 = LO(d1) & 0xfffffffffff;\n        ADDLO(d2, c); c = SHR(d2, 42); h2 = LO(d2) & 0x3ffffffffff;\n        h0  += c * 5; c = (h0 >> 44);  h0 =    h0  & 0xfffffffffff;\n        h1  += c;\n\n        m += POLY1305_BLOCK_SIZE;\n        bytes -= POLY1305_BLOCK_SIZE;\n    }\n\n    ctx->h[0] = h0;\n    ctx->h[1] = h1;\n    ctx->h[2] = h2;\n\n#else /* if not 64 bit then use 32 bit */\n    const word32 hibit = (ctx->finished) ? 0 : ((word32)1 << 24); /* 1 << 128 */\n    word32 r0,r1,r2,r3,r4;\n    word32 s1,s2,s3,s4;\n    word32 h0,h1,h2,h3,h4;\n    word64 d0,d1,d2,d3,d4;\n    word32 c;\n\n\n    r0 = ctx->r[0];\n    r1 = ctx->r[1];\n    r2 = ctx->r[2];\n    r3 = ctx->r[3];\n    r4 = ctx->r[4];\n\n    s1 = r1 * 5;\n    s2 = r2 * 5;\n    s3 = r3 * 5;\n    s4 = r4 * 5;\n\n    h0 = ctx->h[0];\n    h1 = ctx->h[1];\n    h2 = ctx->h[2];\n    h3 = ctx->h[3];\n    h4 = ctx->h[4];\n\n    while (bytes >= POLY1305_BLOCK_SIZE) {\n        /* h += m[i] */\n        h0 += (U8TO32(m+ 0)     ) & 0x3ffffff;\n        h1 += (U8TO32(m+ 3) >> 2) & 0x3ffffff;\n        h2 += (U8TO32(m+ 6) >> 4) & 0x3ffffff;\n        h3 += (U8TO32(m+ 9) >> 6) & 0x3ffffff;\n        h4 += (U8TO32(m+12) >> 8) | hibit;\n\n        /* h *= r */\n        d0 = ((word64)h0 * r0) + ((word64)h1 * s4) + ((word64)h2 * s3) +\n             ((word64)h3 * s2) + ((word64)h4 * s1);\n        d1 = ((word64)h0 * r1) + ((word64)h1 * r0) + ((word64)h2 * s4) +\n             ((word64)h3 * s3) + ((word64)h4 * s2);\n        d2 = ((word64)h0 * r2) + ((word64)h1 * r1) + ((word64)h2 * r0) +\n             ((word64)h3 * s4) + ((word64)h4 * s3);\n        d3 = ((word64)h0 * r3) + ((word64)h1 * r2) + ((word64)h2 * r1) +\n             ((word64)h3 * r0) + ((word64)h4 * s4);\n        d4 = ((word64)h0 * r4) + ((word64)h1 * r3) + ((word64)h2 * r2) +\n             ((word64)h3 * r1) + ((word64)h4 * r0);\n\n        /* (partial) h %= p */\n                      c = (word32)(d0 >> 26); h0 = (word32)d0 & 0x3ffffff;\n        d1 += c;      c = (word32)(d1 >> 26); h1 = (word32)d1 & 0x3ffffff;\n        d2 += c;      c = (word32)(d2 >> 26); h2 = (word32)d2 & 0x3ffffff;\n        d3 += c;      c = (word32)(d3 >> 26); h3 = (word32)d3 & 0x3ffffff;\n        d4 += c;      c = (word32)(d4 >> 26); h4 = (word32)d4 & 0x3ffffff;\n        h0 += c * 5;  c =  (h0 >> 26); h0 =                h0 & 0x3ffffff;\n        h1 += c;\n\n        m += POLY1305_BLOCK_SIZE;\n        bytes -= POLY1305_BLOCK_SIZE;\n    }\n\n    ctx->h[0] = h0;\n    ctx->h[1] = h1;\n    ctx->h[2] = h2;\n    ctx->h[3] = h3;\n    ctx->h[4] = h4;\n\n#endif /* end of 64 bit cpu blocks or 32 bit cpu */\n}\n\nvoid poly1305_block(Poly1305* ctx, const unsigned char *m)\n{\n#ifdef USE_INTEL_SPEEDUP\n    /* No call to poly1305_block when AVX2, AVX2 does 4 blocks at a time. */\n    poly1305_block_avx(ctx, m);\n#else\n    poly1305_blocks(ctx, m, POLY1305_BLOCK_SIZE);\n#endif\n}\n#endif /* !defined(WOLFSSL_ARMASM) || !defined(__aarch64__) */\n\n#if !defined(WOLFSSL_ARMASM) || !defined(__aarch64__)\nint wc_Poly1305SetKey(Poly1305* ctx, const byte* key, word32 keySz)\n{\n#if defined(POLY130564)\n    word64 t0,t1;\n#endif\n\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n#ifdef CHACHA_AEAD_TEST\n    word32 k;\n    printf(\"Poly key used:\\n\");\n    for (k = 0; k < keySz; k++) {\n        printf(\"%02x\", key[k]);\n        if ((k+1) % 8 == 0)\n            printf(\"\\n\");\n    }\n    printf(\"\\n\");\n#endif\n\n    if (keySz != 32 || ctx == NULL)\n        return BAD_FUNC_ARG;\n\n#ifdef USE_INTEL_SPEEDUP\n    if (!cpu_flags_set) {\n        intel_flags = cpuid_get_flags();\n        cpu_flags_set = 1;\n    }\n    #ifdef HAVE_INTEL_AVX2\n    if (IS_INTEL_AVX2(intel_flags))\n        poly1305_setkey_avx2(ctx, key);\n    else\n    #endif\n        poly1305_setkey_avx(ctx, key);\n#elif defined(POLY130564)\n\n    /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */\n    t0 = U8TO64(key + 0);\n    t1 = U8TO64(key + 8);\n\n    ctx->r[0] = ( t0                    ) & 0xffc0fffffff;\n    ctx->r[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff;\n    ctx->r[2] = ((t1 >> 24)             ) & 0x00ffffffc0f;\n\n    /* h (accumulator) = 0 */\n    ctx->h[0] = 0;\n    ctx->h[1] = 0;\n    ctx->h[2] = 0;\n\n    /* save pad for later */\n    ctx->pad[0] = U8TO64(key + 16);\n    ctx->pad[1] = U8TO64(key + 24);\n\n    ctx->leftover = 0;\n    ctx->finished = 0;\n\n#else /* if not 64 bit then use 32 bit */\n\n    /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */\n    ctx->r[0] = (U8TO32(key +  0)     ) & 0x3ffffff;\n    ctx->r[1] = (U8TO32(key +  3) >> 2) & 0x3ffff03;\n    ctx->r[2] = (U8TO32(key +  6) >> 4) & 0x3ffc0ff;\n    ctx->r[3] = (U8TO32(key +  9) >> 6) & 0x3f03fff;\n    ctx->r[4] = (U8TO32(key + 12) >> 8) & 0x00fffff;\n\n    /* h = 0 */\n    ctx->h[0] = 0;\n    ctx->h[1] = 0;\n    ctx->h[2] = 0;\n    ctx->h[3] = 0;\n    ctx->h[4] = 0;\n\n    /* save pad for later */\n    ctx->pad[0] = U8TO32(key + 16);\n    ctx->pad[1] = U8TO32(key + 20);\n    ctx->pad[2] = U8TO32(key + 24);\n    ctx->pad[3] = U8TO32(key + 28);\n\n    ctx->leftover = 0;\n    ctx->finished = 0;\n\n#endif\n\n    return 0;\n}\n\nint wc_Poly1305Final(Poly1305* ctx, byte* mac)\n{\n#ifdef USE_INTEL_SPEEDUP\n#elif defined(POLY130564)\n\n    word64 h0,h1,h2,c;\n    word64 g0,g1,g2;\n    word64 t0,t1;\n\n#else\n\n    word32 h0,h1,h2,h3,h4,c;\n    word32 g0,g1,g2,g3,g4;\n    word64 f;\n    word32 mask;\n\n#endif\n\n    if (ctx == NULL)\n        return BAD_FUNC_ARG;\n\n#ifdef USE_INTEL_SPEEDUP\n    #ifdef HAVE_INTEL_AVX2\n    if (IS_INTEL_AVX2(intel_flags))\n        poly1305_final_avx2(ctx, mac);\n    else\n    #endif\n        poly1305_final_avx(ctx, mac);\n#elif defined(POLY130564)\n\n    /* process the remaining block */\n    if (ctx->leftover) {\n        size_t i = ctx->leftover;\n        ctx->buffer[i] = 1;\n        for (i = i + 1; i < POLY1305_BLOCK_SIZE; i++)\n            ctx->buffer[i] = 0;\n        ctx->finished = 1;\n        poly1305_block(ctx, ctx->buffer);\n    }\n\n    /* fully carry h */\n    h0 = ctx->h[0];\n    h1 = ctx->h[1];\n    h2 = ctx->h[2];\n\n                 c = (h1 >> 44); h1 &= 0xfffffffffff;\n    h2 += c;     c = (h2 >> 42); h2 &= 0x3ffffffffff;\n    h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff;\n    h1 += c;     c = (h1 >> 44); h1 &= 0xfffffffffff;\n    h2 += c;     c = (h2 >> 42); h2 &= 0x3ffffffffff;\n    h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff;\n    h1 += c;\n\n    /* compute h + -p */\n    g0 = h0 + 5; c = (g0 >> 44); g0 &= 0xfffffffffff;\n    g1 = h1 + c; c = (g1 >> 44); g1 &= 0xfffffffffff;\n    g2 = h2 + c - ((word64)1 << 42);\n\n    /* select h if h < p, or h + -p if h >= p */\n    c = (g2 >> ((sizeof(word64) * 8) - 1)) - 1;\n    g0 &= c;\n    g1 &= c;\n    g2 &= c;\n    c = ~c;\n    h0 = (h0 & c) | g0;\n    h1 = (h1 & c) | g1;\n    h2 = (h2 & c) | g2;\n\n    /* h = (h + pad) */\n    t0 = ctx->pad[0];\n    t1 = ctx->pad[1];\n\n    h0 += (( t0                    ) & 0xfffffffffff)    ;\n    c = (h0 >> 44); h0 &= 0xfffffffffff;\n    h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c;\n    c = (h1 >> 44); h1 &= 0xfffffffffff;\n    h2 += (((t1 >> 24)             ) & 0x3ffffffffff) + c;\n    h2 &= 0x3ffffffffff;\n\n    /* mac = h % (2^128) */\n    h0 = ((h0      ) | (h1 << 44));\n    h1 = ((h1 >> 20) | (h2 << 24));\n\n    U64TO8(mac + 0, h0);\n    U64TO8(mac + 8, h1);\n\n    /* zero out the state */\n    ctx->h[0] = 0;\n    ctx->h[1] = 0;\n    ctx->h[2] = 0;\n    ctx->r[0] = 0;\n    ctx->r[1] = 0;\n    ctx->r[2] = 0;\n    ctx->pad[0] = 0;\n    ctx->pad[1] = 0;\n\n#else /* if not 64 bit then use 32 bit */\n\n    /* process the remaining block */\n    if (ctx->leftover) {\n        size_t i = ctx->leftover;\n        ctx->buffer[i++] = 1;\n        for (; i < POLY1305_BLOCK_SIZE; i++)\n            ctx->buffer[i] = 0;\n        ctx->finished = 1;\n        poly1305_block(ctx, ctx->buffer);\n    }\n\n    /* fully carry h */\n    h0 = ctx->h[0];\n    h1 = ctx->h[1];\n    h2 = ctx->h[2];\n    h3 = ctx->h[3];\n    h4 = ctx->h[4];\n\n                 c = h1 >> 26; h1 = h1 & 0x3ffffff;\n    h2 +=     c; c = h2 >> 26; h2 = h2 & 0x3ffffff;\n    h3 +=     c; c = h3 >> 26; h3 = h3 & 0x3ffffff;\n    h4 +=     c; c = h4 >> 26; h4 = h4 & 0x3ffffff;\n    h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff;\n    h1 +=     c;\n\n    /* compute h + -p */\n    g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff;\n    g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff;\n    g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff;\n    g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff;\n    g4 = h4 + c - ((word32)1 << 26);\n\n    /* select h if h < p, or h + -p if h >= p */\n    mask = ((word32)g4 >> ((sizeof(word32) * 8) - 1)) - 1;\n    g0 &= mask;\n    g1 &= mask;\n    g2 &= mask;\n    g3 &= mask;\n    g4 &= mask;\n    mask = ~mask;\n    h0 = (h0 & mask) | g0;\n    h1 = (h1 & mask) | g1;\n    h2 = (h2 & mask) | g2;\n    h3 = (h3 & mask) | g3;\n    h4 = (h4 & mask) | g4;\n\n    /* h = h % (2^128) */\n    h0 = ((h0      ) | (h1 << 26)) & 0xffffffff;\n    h1 = ((h1 >>  6) | (h2 << 20)) & 0xffffffff;\n    h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;\n    h3 = ((h3 >> 18) | (h4 <<  8)) & 0xffffffff;\n\n    /* mac = (h + pad) % (2^128) */\n    f = (word64)h0 + ctx->pad[0]            ; h0 = (word32)f;\n    f = (word64)h1 + ctx->pad[1] + (f >> 32); h1 = (word32)f;\n    f = (word64)h2 + ctx->pad[2] + (f >> 32); h2 = (word32)f;\n    f = (word64)h3 + ctx->pad[3] + (f >> 32); h3 = (word32)f;\n\n    U32TO8(mac + 0, h0);\n    U32TO8(mac + 4, h1);\n    U32TO8(mac + 8, h2);\n    U32TO8(mac + 12, h3);\n\n    /* zero out the state */\n    ctx->h[0] = 0;\n    ctx->h[1] = 0;\n    ctx->h[2] = 0;\n    ctx->h[3] = 0;\n    ctx->h[4] = 0;\n    ctx->r[0] = 0;\n    ctx->r[1] = 0;\n    ctx->r[2] = 0;\n    ctx->r[3] = 0;\n    ctx->r[4] = 0;\n    ctx->pad[0] = 0;\n    ctx->pad[1] = 0;\n    ctx->pad[2] = 0;\n    ctx->pad[3] = 0;\n\n#endif\n\n    return 0;\n}\n#endif /* !defined(WOLFSSL_ARMASM) || !defined(__aarch64__) */\n\n\nint wc_Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes)\n{\n    size_t i;\n\n#ifdef CHACHA_AEAD_TEST\n    word32 k;\n    printf(\"Raw input to poly:\\n\");\n    for (k = 0; k < bytes; k++) {\n        printf(\"%02x\", m[k]);\n        if ((k+1) % 16 == 0)\n            printf(\"\\n\");\n    }\n    printf(\"\\n\");\n#endif\n\n    if (ctx == NULL)\n        return BAD_FUNC_ARG;\n\n#ifdef USE_INTEL_SPEEDUP\n    #ifdef HAVE_INTEL_AVX2\n    if (IS_INTEL_AVX2(intel_flags)) {\n        /* handle leftover */\n        if (ctx->leftover) {\n            size_t want = sizeof(ctx->buffer) - ctx->leftover;\n            if (want > bytes)\n                want = bytes;\n\n            for (i = 0; i < want; i++)\n                ctx->buffer[ctx->leftover + i] = m[i];\n            bytes -= (word32)want;\n            m += want;\n            ctx->leftover += want;\n            if (ctx->leftover < sizeof(ctx->buffer))\n                return 0;\n\n            if (!ctx->started)\n                poly1305_calc_powers_avx2(ctx);\n            poly1305_blocks_avx2(ctx, ctx->buffer, sizeof(ctx->buffer));\n            ctx->leftover = 0;\n        }\n\n        /* process full blocks */\n        if (bytes >= sizeof(ctx->buffer)) {\n            size_t want = bytes & ~(sizeof(ctx->buffer) - 1);\n\n            if (!ctx->started)\n                poly1305_calc_powers_avx2(ctx);\n            poly1305_blocks_avx2(ctx, m, want);\n            m += want;\n            bytes -= (word32)want;\n        }\n\n        /* store leftover */\n        if (bytes) {\n            for (i = 0; i < bytes; i++)\n                ctx->buffer[ctx->leftover + i] = m[i];\n            ctx->leftover += bytes;\n        }\n    }\n    else\n    #endif\n#endif\n    {\n        /* handle leftover */\n        if (ctx->leftover) {\n            size_t want = (POLY1305_BLOCK_SIZE - ctx->leftover);\n            if (want > bytes)\n                want = bytes;\n            for (i = 0; i < want; i++)\n                ctx->buffer[ctx->leftover + i] = m[i];\n            bytes -= (word32)want;\n            m += want;\n            ctx->leftover += want;\n            if (ctx->leftover < POLY1305_BLOCK_SIZE)\n                return 0;\n            poly1305_block(ctx, ctx->buffer);\n            ctx->leftover = 0;\n        }\n\n        /* process full blocks */\n        if (bytes >= POLY1305_BLOCK_SIZE) {\n            size_t want = (bytes & ~(POLY1305_BLOCK_SIZE - 1));\n            poly1305_blocks(ctx, m, want);\n            m += want;\n            bytes -= (word32)want;\n        }\n\n        /* store leftover */\n        if (bytes) {\n            for (i = 0; i < bytes; i++)\n                ctx->buffer[ctx->leftover + i] = m[i];\n            ctx->leftover += bytes;\n        }\n    }\n\n    return 0;\n}\n\n\n/*  Takes in an initialized Poly1305 struct that has a key loaded and creates\n    a MAC (tag) using recent TLS AEAD padding scheme.\n    ctx        : Initialized Poly1305 struct to use\n    additional : Additional data to use\n    addSz      : Size of additional buffer\n    input      : Input buffer to create tag from\n    sz         : Size of input buffer\n    tag        : Buffer to hold created tag\n    tagSz      : Size of input tag buffer (must be at least\n                 WC_POLY1305_MAC_SZ(16))\n */\nint wc_Poly1305_MAC(Poly1305* ctx, byte* additional, word32 addSz,\n                    byte* input, word32 sz, byte* tag, word32 tagSz)\n{\n    int ret;\n    byte padding[WC_POLY1305_PAD_SZ - 1];\n    word32 paddingLen;\n    byte little64[16];\n\n    XMEMSET(padding, 0, sizeof(padding));\n\n    /* sanity check on arguments */\n    if (ctx == NULL || input == NULL || tag == NULL ||\n                                                   tagSz < WC_POLY1305_MAC_SZ) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* additional allowed to be 0 */\n    if (addSz > 0) {\n        if (additional == NULL)\n            return BAD_FUNC_ARG;\n\n        /* additional data plus padding */\n        if ((ret = wc_Poly1305Update(ctx, additional, addSz)) != 0) {\n            return ret;\n        }\n        paddingLen = -((int)addSz) & (WC_POLY1305_PAD_SZ - 1);\n        if (paddingLen) {\n            if ((ret = wc_Poly1305Update(ctx, padding, paddingLen)) != 0) {\n                return ret;\n            }\n        }\n    }\n\n    /* input plus padding */\n    if ((ret = wc_Poly1305Update(ctx, input, sz)) != 0) {\n        return ret;\n    }\n    paddingLen = -((int)sz) & (WC_POLY1305_PAD_SZ - 1);\n    if (paddingLen) {\n        if ((ret = wc_Poly1305Update(ctx, padding, paddingLen)) != 0) {\n            return ret;\n        }\n    }\n\n    /* size of additional data and input as little endian 64 bit types */\n    U32TO64(addSz, little64);\n    U32TO64(sz, little64 + 8);\n    ret = wc_Poly1305Update(ctx, little64, sizeof(little64));\n    if (ret)\n    {\n        return ret;\n    }\n\n    /* Finalize the auth tag */\n    ret = wc_Poly1305Final(ctx, tag);\n\n    return ret;\n\n}\n#endif /* HAVE_POLY1305 */\n"
  },
  {
    "path": "src/wolfcrypt/src/port/Espressif/README.md",
    "content": "# ESP32 Port\n\nSupport for the ESP32-WROOM-32 on-board crypto hardware acceleration for symmetric AES, SHA1/SHA256/SHA384/SHA512 and RSA primitive including mul, mulmod and exptmod.\n\n## ESP32 Acceleration\n\nFor detail about ESP32 HW Acceleration, you can find in [Technical Reference Manual](https://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf)\n\n### Building\n\nTo enable hw acceleration :\n\nUncomment out #define WOLFSSL_ESPIDF in /path/to/wolfssl/wolfssl/wolfcrypt/settings.h  \nUncomment out #define WOLFSSL_ESPWROOM32 in /path/to/wolfssl/wolfssl/wolfcrypt/settings.h\n\nTo disable portions of the hardware acceleration you can optionally define:  \n\n```\n/* Disabled SHA, AES and RSA acceleration */\n#define NO_ESP32WROOM32_CRYPT\n/* Disabled AES acceleration */\n#define NO_WOLFSSL_ESP32WROOM32_CRYPT_AES\n/* Disabled SHA acceleration */\n#define NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH\n/* Disabled RSA Primitive acceleration */\n#define NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI\n```\n\n### Coding\n\nIn your application you must include <wolfssl/wolfcrypt/settings.h> before any other wolfSSL headers. If building the sources directly we recommend defining `WOLFSSL_USER_SETTINGS` and adding your own `user_settings.h` file. You can find a good reference for this in `IDE/GCC-ARM/Header/user_settings.h`.\n\n\n### Benchmarks\n\nw/ USE_FAST_MATH and WOLFSSL_SMALL_STACK options\n\nSoftware only implementation :\n\n```\nAES-128-CBC-enc      1 MB took 1.001 seconds,    1.146 MB/s\nAES-128-CBC-dec      1 MB took 1.017 seconds,    1.104 MB/s\nAES-192-CBC-enc      1 MB took 1.018 seconds,    1.055 MB/s\nAES-192-CBC-dec      1 MB took 1.006 seconds,    1.019 MB/s\nAES-256-CBC-enc   1000 KB took 1.000 seconds, 1000.000 KB/s\nAES-256-CBC-dec    975 KB took 1.007 seconds,  968.222 KB/s\nAES-128-GCM-enc    350 KB took 1.055 seconds,  331.754 KB/s\nAES-128-GCM-dec    350 KB took 1.054 seconds,  332.068 KB/s\nAES-192-GCM-enc    325 KB took 1.013 seconds,  320.829 KB/s\nAES-192-GCM-dec    325 KB took 1.013 seconds,  320.829 KB/s\nAES-256-GCM-enc    325 KB took 1.041 seconds,  312.200 KB/s\nAES-256-GCM-dec    325 KB took 1.041 seconds,  312.200 KB/s\nSHA                  6 MB took 1.004 seconds,    5.714 MB/s\nSHA-256              2 MB took 1.006 seconds,    1.747 MB/s\nSHA-384              1 MB took 1.011 seconds,    1.159 MB/s\nSHA-512              1 MB took 1.009 seconds,    1.161 MB/s\nHMAC-SHA             6 MB took 1.001 seconds,    5.634 MB/s\nHMAC-SHA256          2 MB took 1.000 seconds,    1.733 MB/s\nHMAC-SHA384          1 MB took 1.004 seconds,    1.046 MB/s\nHMAC-SHA512          1 MB took 1.002 seconds,    1.048 MB/s\nRSA     2048 public         16 ops took 1.056 sec, avg 66.000 ms, 15.152 ops/sec\nRSA     2048 private         2 ops took 2.488 sec, avg 1244.000 ms, 0.804 ops/sec\nECC      256 key gen         4 ops took 1.101 sec, avg 275.250 ms, 3.633 ops/sec\nECDHE    256 agree           4 ops took 1.098 sec, avg 274.500 ms, 3.643 ops/sec\nECDSA    256 sign            4 ops took 1.111 sec, avg 277.750 ms, 3.600 ops/sec\nECDSA    256 verify          2 ops took 1.099 sec, avg 549.500 ms, 1.820 ops/sec\n```\n\nHardware Acceleration :\n\n\n```\nAES-128-CBC-enc      6 MB took 1.004 seconds,    5.958 MB/s\nAES-128-CBC-dec      5 MB took 1.002 seconds,    5.287 MB/s\nAES-192-CBC-enc      6 MB took 1.004 seconds,    5.958 MB/s\nAES-192-CBC-dec      5 MB took 1.002 seconds,    5.287 MB/s\nAES-256-CBC-enc      6 MB took 1.001 seconds,    5.951 MB/s\nAES-256-CBC-dec      5 MB took 1.004 seconds,    5.277 MB/s\nAES-128-GCM-enc    375 KB took 1.067 seconds,  351.453 KB/s\nAES-128-GCM-dec    375 KB took 1.067 seconds,  351.453 KB/s\nAES-192-GCM-enc    350 KB took 1.010 seconds,  346.535 KB/s\nAES-192-GCM-dec    350 KB took 1.009 seconds,  346.878 KB/s\nAES-256-GCM-enc    350 KB took 1.016 seconds,  344.488 KB/s\nAES-256-GCM-dec    350 KB took 1.016 seconds,  344.488 KB/s\nSHA                 14 MB took 1.000 seconds,   14.062 MB/s\nSHA-256             15 MB took 1.000 seconds,   15.234 MB/s\nSHA-384             17 MB took 1.000 seconds,   17.383 MB/s\nSHA-512             18 MB took 1.001 seconds,   17.512 MB/s\nHMAC-SHA            14 MB took 1.000 seconds,   13.818 MB/s\nHMAC-SHA256         15 MB took 1.001 seconds,   14.951 MB/s\nHMAC-SHA384         17 MB took 1.001 seconds,   16.683 MB/s\nHMAC-SHA512         17 MB took 1.000 seconds,   16.943 MB/s\nRSA     2048 public         20 ops took 1.017 sec, avg 50.850 ms, 19.666 ops/sec\nRSA     2048 private         4 ops took 1.059 sec, avg 264.750 ms, 3.777 ops/sec\nECC      256 key gen         4 ops took 1.092 sec, avg 273.000 ms, 3.663 ops/sec\nECDHE    256 agree           4 ops took 1.089 sec, avg 272.250 ms, 3.673 ops/sec\nECDSA    256 sign            4 ops took 1.101 sec, avg 275.250 ms, 3.633 ops/sec\nECDSA    256 verify          2 ops took 1.092 sec, avg 546.000 ms, 1.832 ops/sec\n```\n\nCondition  :  \n- Model    : ESP32-WROOM-32  \n- CPU Speed: 240Mhz  \n- ESP-IDF  : v3.3-beta1-39-g6cb37ecc5(commit hash : 6cb37ecc5)  \n- OS       : Ubuntu 18.04.1 LTS (Bionic Beaver)\n\n## Support\n\nEmail us at [support@wolfssl.com](mailto:support@wolfssl.com).\n"
  },
  {
    "path": "src/wolfcrypt/src/port/Espressif/esp32_aes.c",
    "content": "/* esp32_aes.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n#include <string.h>\n#include <stdio.h>\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifndef NO_AES\n\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_AES)\n\n#include <wolfssl/wolfcrypt/aes.h>\n#include \"wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h\"\n\nstatic const char* TAG = \"wolf_hw_aes\";\n/* mutex */\nstatic wolfSSL_Mutex aes_mutex;\nstatic int espaes_CryptHwMutexInit = 0;\n\n/*\n* lock hw engine.\n* this should be called before using engine.\n*/\nstatic int esp_aes_hw_InUse()\n{\n    int ret = 0;\n\n    ESP_LOGV(TAG, \"enter esp_aes_hw_InUse\");\n\n    if(espaes_CryptHwMutexInit == 0) {\n        ret = esp_CryptHwMutexInit(&aes_mutex);\n        if(ret == 0){\n            espaes_CryptHwMutexInit = 1;\n        } else {\n            ESP_LOGE(TAG, \"aes mutx initialization failed.\");\n            return -1;\n        }\n    }\n    /* lock hardware */\n    ret = esp_CryptHwMutexLock(&aes_mutex, portMAX_DELAY);\n    if(ret != 0) {\n        ESP_LOGE(TAG, \"aes engine lock failed.\");\n        return -1;\n    }\n    /* Enable AES hardware */\n    periph_module_enable(PERIPH_AES_MODULE);\n\n    ESP_LOGV(TAG, \"leave esp_aes_hw_InUse\");\n    return ret;\n}\n\n/*\n*   release hw engine\n*/\nstatic void esp_aes_hw_Leave( void )\n{\n    ESP_LOGV(TAG, \"enter esp_aes_hw_Leave\");\n    /* Disable AES hardware */\n    periph_module_disable(PERIPH_AES_MODULE);\n\n    /* unlock */\n    esp_CryptHwMutexUnLock(&aes_mutex);\n\n    ESP_LOGV(TAG, \"leave esp_aes_hw_Leave\");\n}\n\n/*\n * set key to hardware key registers.\n */\nstatic void esp_aes_hw_Set_KeyMode(Aes *ctx, ESP32_AESPROCESS mode)\n{\n    int i;\n    word32 mode_ = 0;\n\n    ESP_LOGV(TAG, \"enter esp_aes_hw_Set_KeyMode\");\n\n    /* check mode */\n    if(mode == ESP32_AES_UPDATEKEY_ENCRYPT) {\n        mode_ = 0;\n    } else if(mode == ESP32_AES_UPDATEKEY_DECRYPT){\n        mode_ = 4;\n    } else {\n        ESP_LOGE(TAG, \"unexpected error.\");\n        return;\n    }\n\n    /* update key */\n    for(i=0;i<(ctx->keylen)/sizeof(word32);i++){\n        DPORT_REG_WRITE(AES_KEY_BASE + (i*4), *(((word32*)ctx->key) + i));\n    }\n\n    /* mode\n    *   0       AES-128 Encryption\n    *   1       AES-192 Encryption\n    *   2       AES-256 Encryption\n    *   4       AES-128 Decryption\n    *   5       AES-192 Decryption\n    *   6       AES-256 Decryption\n    */\n    switch(ctx->keylen){\n        case 24: mode_ += 1; break;\n        case 32: mode_ += 2; break;\n        default: break;\n    }\n\n    DPORT_REG_WRITE(AES_MODE_REG, mode_);\n    ESP_LOGV(TAG, \"leave esp_aes_hw_Setkey\");\n}\n\n/*\n * Process a one block of AES\n */\nstatic void esp_aes_bk(const byte* in, byte* out)\n{\n    const word32 *inwords = (const word32 *)in;\n    word32 *outwords      = (word32 *)out;\n\n    ESP_LOGV(TAG, \"enter esp_aes_bk\");\n\n    /* copy text for encrypting/decrypting blocks */\n    DPORT_REG_WRITE(AES_TEXT_BASE, inwords[0]);\n    DPORT_REG_WRITE(AES_TEXT_BASE + 4, inwords[1]);\n    DPORT_REG_WRITE(AES_TEXT_BASE + 8, inwords[2]);\n    DPORT_REG_WRITE(AES_TEXT_BASE + 12, inwords[3]);\n\n    /* start engine */\n    DPORT_REG_WRITE(AES_START_REG, 1);\n\n    /* wait until finishing the process */\n    while(1) {\n        if(DPORT_REG_READ(AES_IDLE_REG) == 1)\n            break;\n    }\n\n    /* read-out blocks */\n    esp_dport_access_read_buffer(outwords, AES_TEXT_BASE, 4);\n    ESP_LOGV(TAG, \"leave esp_aes_bk\");\n}\n\n/*\n* wc_esp32AesEncrypt\n* @brief: a one block encrypt of the input block, into the output block\n* @param aes: a pointer of the AES object used to encrypt data\n* @param in : a pointer of the input buffer containing plain text to be encrypted\n* @param out: a pointer of the output buffer in which to store the cipher text of\n*             the encrypted message\n*/\nint wc_esp32AesEncrypt(Aes *aes, const byte* in, byte* out)\n{\n    ESP_LOGV(TAG, \"enter wc_esp32AesEncrypt\");\n    /* lock the hw engine */\n    esp_aes_hw_InUse();\n    /* load the key into the register */\n    esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT);\n    /* process a one block of AES */\n    esp_aes_bk(in, out);\n    /* release hw */\n    esp_aes_hw_Leave();\n    return 0;\n}\n/*\n* wc_esp32AesDecrypt\n* @brief: a one block decrypt of the input block, into the output block\n* @param aes: a pointer of the AES object used to decrypt data\n* @param in : a pointer of the input buffer containing plain text to be decrypted\n* @param out: a pointer of the output buffer in which to store the cipher text of\n*             the decrypted message\n*/\nint wc_esp32AesDecrypt(Aes *aes, const byte* in, byte* out)\n{\n    ESP_LOGV(TAG, \"enter wc_esp32AesDecrypt\");\n    /* lock the hw engine */\n    esp_aes_hw_InUse();\n    /* load the key into the register */\n    esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT);\n    /* process a one block of AES */\n    esp_aes_bk(in, out);\n    /* release hw engine */\n    esp_aes_hw_Leave();\n    return 0;\n}\n/*\n* wc_esp32AesCbcEncrypt\n* @brief: Encrypts a plain text message from the input buffer, and places the\n*         resulting cipher text into the output buffer using cipher block chaining\n*         with AES.\n* @param aes: a pointer of the AES object used to encrypt data\n* @param out: a pointer of the output buffer in which to store the cipher text of\n*             the encrypted message\n* @param in : a pointer of the input buffer containing plain text to be encrypted\n* @param sz : size of input message\n*/\nint wc_esp32AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n{\n    int i;\n    int offset = 0;\n    word32 blocks = (sz / AES_BLOCK_SIZE);\n    byte *iv;\n    byte temp_block[AES_BLOCK_SIZE];\n\n    ESP_LOGV(TAG, \"enter wc_esp32AesCbcEncrypt\");\n\n    iv      = (byte*)aes->reg;\n\n    esp_aes_hw_InUse();\n\n    esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_ENCRYPT);\n\n    while (blocks--) {\n          XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);\n\n         /* XOR block with IV for CBC */\n         for (i = 0; i < AES_BLOCK_SIZE; i++)\n             temp_block[i] ^= iv[i];\n\n         esp_aes_bk(temp_block, (out + offset));\n\n         offset += AES_BLOCK_SIZE;\n\n         /* store IV for next block */\n         XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);\n    }\n\n    esp_aes_hw_Leave();\n    ESP_LOGV(TAG, \"leave wc_esp32AesCbcEncrypt\");\n    return 0;\n}\n/*\n* wc_esp32AesCbcDecrypt\n* @brief: Encrypts a plain text message from the input buffer, and places the\n*         resulting cipher text into the output buffer using cipher block chaining\n*         with AES.\n* @param aes: a pointer of the AES object used to decrypt data\n* @param out: a pointer of the output buffer in which to store the cipher text of\n*             the decrypted message\n* @param in : a pointer of the input buffer containing plain text to be decrypted\n* @param sz : size of input message\n*/\nint wc_esp32AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)\n{\n    int i;\n    int offset = 0;\n    word32 blocks = (sz / AES_BLOCK_SIZE);\n    byte* iv;\n    byte temp_block[AES_BLOCK_SIZE];\n\n    ESP_LOGV(TAG, \"enter wc_esp32AesCbcDecrypt\");\n\n    iv      = (byte*)aes->reg;\n\n    esp_aes_hw_InUse();\n\n    esp_aes_hw_Set_KeyMode(aes, ESP32_AES_UPDATEKEY_DECRYPT);\n\n    while (blocks--) {\n        XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);\n\n        esp_aes_bk((in + offset), (out + offset));\n\n        /* XOR block with IV for CBC */\n        for (i = 0; i < AES_BLOCK_SIZE; i++)\n            (out + offset)[i] ^= iv[i];\n\n        /* store IV for next block */\n        XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);\n\n        offset += AES_BLOCK_SIZE;\n    }\n\n    esp_aes_hw_Leave();\n    ESP_LOGV(TAG, \"leave wc_esp32AesCbcDecrypt\");\n    return 0;\n}\n\n#endif /* WOLFSSL_ESP32WROOM32_CRYPT */\n#endif /* NO_AES */\n"
  },
  {
    "path": "src/wolfcrypt/src/port/Espressif/esp32_mp.c",
    "content": "/* esp32_mp.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n#include <string.h>\n#include <stdio.h>\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n#include <wolfssl/wolfcrypt/settings.h>\n#include \"wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h\"  // ===== add this line\n\n#include \"wolfssl/wolfcrypt/logging.h\"\n\n#if !defined(NO_RSA) || defined(HAVE_ECC)\n\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \\\n   !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n#include <wolfssl/wolfcrypt/tfm.h>\n\nstatic const char* const TAG = \"wolfssl_mp\";\n\n#define ESP_HW_RSAMAX_BIT           4096\n#define ESP_HW_MULTI_RSAMAX_BITS    2048\n#define ESP_HW_RSAMIN_BIT           512\n#define BYTE_TO_WORDS(s)            (((s+3)>>2))           /* (s+(4-1))/ 4    */\n#define BITS_TO_WORDS(s)            (((s+31)>>3)>>2)       /* (s+(32-1))/ 8/ 4*/\n\n#define MP_NG   -1\n\n/* mutex */\nstatic wolfSSL_Mutex mp_mutex;\nstatic int espmp_CryptHwMutexInit = 0;\n/*\n* check if the hw is ready before accessing it\n*/\nstatic int esp_mp_hw_wait_clean()\n{\n    int timeout = 0;\n    while(++timeout < ESP_RSA_TIMEOUT && DPORT_REG_READ(RSA_CLEAN_REG) != 1){}\n\n    if(timeout >= ESP_RSA_TIMEOUT) {\n        ESP_LOGE(TAG, \"waiting hw ready is time-outed.\");\n        return MP_NG;\n    }\n    return MP_OKAY; \n}\n/*\n* lock hw engine.\n* this should be called before using engine.\n*/\nstatic int esp_mp_hw_lock()\n{\n    int ret = 0;\n\n    if(espmp_CryptHwMutexInit == 0) {\n        ret = esp_CryptHwMutexInit(&mp_mutex);\n        if(ret == 0){\n            espmp_CryptHwMutexInit = 1;\n        } else {\n            ESP_LOGE(TAG, \"mp mutx initialization failed.\");\n            return MP_NG;\n        }\n    }\n    /* lock hardware */\n    ret = esp_CryptHwMutexLock(&mp_mutex, portMAX_DELAY);\n    if(ret != 0) {\n        ESP_LOGE(TAG, \"mp engine lock failed.\");\n        return MP_NG;\n    }\n    /* Enable RSA hardware */\n    periph_module_enable(PERIPH_RSA_MODULE);\n\n    return ret;\n}\n/*\n*   Release hw engine\n*/\nstatic void esp_mp_hw_unlock( void )\n{\n    /* Disable RSA hardware */\n    periph_module_disable(PERIPH_RSA_MODULE);\n\n    /* unlock */\n    esp_CryptHwMutexUnLock(&mp_mutex);\n}\n/* this is based on an article by Cetin Kaya Koc, A New Algorithm for Inversion*/\n/* mod p^k, June 28 2017.                                                     */\nstatic int esp_calc_Mdash(mp_int *M, word32 k, mp_digit* md)\n{\n    int i;\n    int xi;\n    int b0 = 1;\n    int bi;\n    word32  N = 0;\n    word32  x;\n\n    N = M->dp[0];\n    bi = b0;\n    x  = 0;\n\n    for(i = 0; i < k; i++) {\n        xi = bi % 2;\n        if(xi < 0){\n            xi *= -1;\n        }\n        bi = (bi - N * xi) / 2;\n        x |= (xi << i);\n    }\n    /* 2's complement */\n    *md = ~x + 1;\n    return MP_OKAY;\n}\n/* start hw process */\nstatic void process_start(word32 reg)\n{\n     /* clear interrupt */\n    DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1);\n    /* start process  */\n    DPORT_REG_WRITE(reg, 1);\n}\n/* wait until done */\nstatic int wait_uitil_done(word32 reg)\n{\n    int timeout = 0;\n    /* wait until done && not timeout */\n    while(1) {\n        if(++timeout < ESP_RSA_TIMEOUT && DPORT_REG_READ(reg) == 1){\n            break;\n        }\n    }\n\n    /* clear interrupt */\n    DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1);\n\n    if(timeout >= ESP_RSA_TIMEOUT) {\n        ESP_LOGE(TAG, \"rsa operation is time-outed.\");\n        return MP_NG;\n    }\n\n    return MP_OKAY;\n}\n/* read data from memory into mp_init          */\nstatic void esp_memblock_to_mpint(word32 mem_address, mp_int* mp, word32 numwords)\n{\n    esp_dport_access_read_buffer((uint32_t*)mp->dp, mem_address, numwords);\n    mp->used = numwords;\n}\n\n/* write mp_init into memory block             */\nstatic void esp_mpint_to_memblock(word32 mem_address, const mp_int* mp,\n                                                      const word32 bits,\n                                                      const word32 hwords)\n{\n    word32 i;\n    word32 len = (bits / 8 + ((bits & 7) != 0 ? 1 : 0));\n\n    len = (len+sizeof(word32)-1)/sizeof(word32);\n\n    for(i=0;i < hwords; i++) {\n        if(i < len) {\n            DPORT_REG_WRITE(mem_address + (i * sizeof(word32)), mp->dp[i]);\n        } else {\n            DPORT_REG_WRITE(mem_address + (i * sizeof(word32)), 0);\n        }\n    }\n}\n/* return needed hw words.                                 */\n/* supported words length                                  */\n/*  words : {16 ,  32,  48,    64,   80,   96, 112,   128} */\n/*  bits  : {512,1024, 1536, 2048, 2560, 3072, 3584, 4096} */\nstatic word32 words2hwords(word32 wd)\n{\n    const word32 shit_ = 4;\n\n    return (((wd + 0xf)>>shit_)<<shit_);\n}\n/* count the number of words is needed for bits */\nstatic word32 bits2words(word32 bits)\n{\n    /* 32 bits */\n    const word32 d = sizeof(word32) * WOLFSSL_BIT_SIZE;\n\n    return((bits + (d - 1))/d);\n}\n/* get rinv */\nstatic int esp_get_rinv(mp_int *rinv, mp_int *M, word32 exp)\n{\n    int ret = 0;\n\n    /* 2^(exp)*/\n    if((ret = mp_2expt(rinv, exp)) != MP_OKAY) {\n        ESP_LOGE(TAG, \"failed to calculate mp_2expt()\");\n        return ret;\n    }\n\n    /* r_inv = R^2 mod M(=P) */\n    if(ret == 0 && (ret = mp_mod(rinv, M, rinv)) != MP_OKAY){\n        ESP_LOGE(TAG, \"failed to calculate mp_mod()\");\n        return ret;\n    }\n\n    return ret;\n}\n/* Z = X * Y;                                              */\nint esp_mp_mul(fp_int* X, fp_int* Y, fp_int* Z)\n{\n    int ret = 0;\n    int neg = (X->sign == Y->sign)? MP_ZPOS : MP_NEG;\n\n    word32 Xs;\n    word32 Ys;\n    word32 Zs;\n    word32 maxWords_sz;\n    word32 hwWords_sz;\n\n    /* ask bits number */\n    Xs = mp_count_bits(X);\n    Ys = mp_count_bits(Y);\n    Zs = Xs + Ys;\n\n    /* maximum bits and words for writing to hw */\n    maxWords_sz = bits2words(max(Xs, Ys));\n    hwWords_sz  = words2hwords(maxWords_sz);\n\n    /* sanity check */\n    if((hwWords_sz<<5) > ESP_HW_MULTI_RSAMAX_BITS) {\n        ESP_LOGW(TAG, \"exceeds max bit length(2048)\");\n        return -2;\n    }\n\n    /*Steps to use hw in the following order:\n    * 1. wait until clean hw engine\n    * 2. Write(2*N/512bits - 1 + 8) to MULT_MODE_REG\n    * 3. Write X and Y to memory blocks\n    *    need to write data to each memory block only according to the length\n    *    of the number.\n    * 4. Write 1  to MUL_START_REG\n    * 5. Wait for the first operation to be done. Poll INTERRUPT_REG until it reads 1.\n    *    (Or until the INTER interrupt is generated.)\n    * 6. Write 1 to RSA_INTERRUPT_REG to clear the interrupt.\n    * 7. Read the Z from RSA_Z_MEM\n    * 8. Write 1 to RSA_INTERUPT_REG to clear the interrupt.\n    * 9. Release the hw engine\n    */\n    /* lock hw for use */\n    if((ret = esp_mp_hw_lock()) != MP_OKAY)\n        return ret;\n\n    if((ret = esp_mp_hw_wait_clean()) != MP_OKAY){\n        return ret;\n    }\n\n    /* step.1  (2*N/512) => N/256. 512 bits => 16 words */\n    DPORT_REG_WRITE(RSA_MULT_MODE_REG, (hwWords_sz >> 3) - 1 + 8);\n    /* step.2 write X, M and r_inv into memory */\n    esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz);\n    /* Y(let-extend)                          */\n    esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE + (hwWords_sz<<2), Y, Ys, hwWords_sz);\n    /* step.3 start process                           */\n    process_start(RSA_MULT_START_REG);\n\n    /* step.4,5 wait until done                       */\n    wait_uitil_done(RSA_INTERRUPT_REG);\n    /* step.6 read the result form MEM_Z              */\n    esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Zs));\n\n    /* step.7 clear and release hw                    */\n    esp_mp_hw_unlock();\n\n    Z->sign = (Z->used > 0)? neg : MP_ZPOS;\n\n    return ret;\n}\n/* Z = X * Y (mod M)                                  */\nint esp_mp_mulmod(fp_int* X, fp_int* Y, fp_int* M, fp_int* Z)\n{\n    int ret = 0;\n    int negcheck = 0;\n    word32 Xs;\n    word32 Ys;\n    word32 Ms;\n    word32 maxWords_sz;\n    word32 hwWords_sz;\n    word32 zwords;\n\n    mp_int r_inv;\n    mp_int tmpZ;\n    mp_digit mp;\n\n    /* neg check */\n    if(X->sign != Y->sign) {\n        /* X*Y becomes negative */\n        negcheck = 1;\n    }\n    /* ask bits number */\n    Xs = mp_count_bits(X);\n    Ys = mp_count_bits(Y);\n    Ms = mp_count_bits(M);\n\n    /* maximum bits and words for writing to hw */\n    maxWords_sz = bits2words(max(Xs, max(Ys, Ms)));\n    zwords      = bits2words(min(Ms, Xs + Ys));\n    hwWords_sz  = words2hwords(maxWords_sz);\n\n    if((hwWords_sz<<5) > ESP_HW_RSAMAX_BIT) {\n        ESP_LOGE(TAG, \"exceeds hw maximum bits\");\n        return -2;\n    }\n    /* calculate r_inv = R^2 mode M\n    *    where: R = b^n, and b = 2^32\n    *    accordinalry R^2 = 2^(n*32*2)\n    */\n    ret = mp_init_multi(&tmpZ, &r_inv, NULL, NULL, NULL, NULL);\n    if(ret == 0 && (ret = esp_get_rinv(&r_inv, M, (hwWords_sz<<6))) != MP_OKAY) {\n        ESP_LOGE(TAG, \"calcurate r_inv failed.\");\n        mp_clear(&tmpZ);\n        mp_clear(&r_inv);\n        return ret;\n    }\n    /* lock hw for use */\n    if((ret = esp_mp_hw_lock()) != MP_OKAY){\n        mp_clear(&tmpZ);\n        mp_clear(&r_inv);\n        return ret;\n    }\n    /* Calculate M' */\n    if((ret = esp_calc_Mdash(M, 32/* bits */, &mp)) != MP_OKAY) {\n        ESP_LOGE(TAG, \"failed to calculate M dash\");\n        mp_clear(&tmpZ);\n        mp_clear(&r_inv);\n        return -1;\n    }\n    /*Steps to use hw in the following order:\n    * 1. wait until clean hw engine\n    * 2. Write(N/512bits - 1) to MULT_MODE_REG\n    * 3. Write X,M(=G, X, P) to memory blocks\n    *    need to write data to each memory block only according to the length\n    *    of the number.\n    * 4. Write M' to M_PRIME_REG\n    * 5. Write 1  to MODEXP_START_REG\n    * 6. Wait for the first operation to be done. Poll INTERRUPT_REG until it reads 1.\n    *    (Or until the INTER interrupt is generated.)\n    * 7. Write 1 to RSA_INTERRUPT_REG to clear the interrupt.\n    * 8. Write Y to RSA_X_MEM\n    * 9. Write 1 to RSA_MULT_START_REG\n    * 10. Wait for the second operation to be completed. Poll INTERRUPT_REG until it reads 1.\n    * 11. Read the Z from RSA_Z_MEM\n    * 12. Write 1 to RSA_INTERUPT_REG to clear the interrupt.\n    * 13. Release the hw engine\n    */\n\n    if((ret = esp_mp_hw_wait_clean()) != MP_OKAY){\n        return ret;\n    }\n    /* step.1                     512 bits => 16 words */\n    DPORT_REG_WRITE(RSA_MULT_MODE_REG, (hwWords_sz >> 4) - 1);\n\n    /* step.2 write X, M and r_inv into memory */\n    esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz);\n    esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE, M, Ms, hwWords_sz);\n    esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE, &r_inv, mp_count_bits(&r_inv),\n                                                                  hwWords_sz);\n    /* step.3 write M' into memory                   */\n    DPORT_REG_WRITE(RSA_M_DASH_REG, mp);\n    /* step.4 start process                           */\n    process_start(RSA_MULT_START_REG);\n\n    /* step.5,6 wait until done                       */\n    wait_uitil_done(RSA_INTERRUPT_REG);\n    /* step.7 Y to MEM_X                              */\n    esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, Y, Ys, hwWords_sz);\n\n    /* step.8 start process                           */\n    process_start(RSA_MULT_START_REG);\n\n    /* step.9,11 wait until done                      */\n    wait_uitil_done(RSA_INTERRUPT_REG);\n\n    /* step.12 read the result from MEM_Z             */\n    esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, &tmpZ, zwords);\n\n    /* step.13 clear and release hw                   */\n    esp_mp_hw_unlock();\n\n    /* additional steps                               */\n    /* this needs for known issue when Z is greather than M */\n    if(mp_cmp(&tmpZ, M)==FP_GT) {\n         /* Z -= M    */\n         mp_sub(&tmpZ, M, &tmpZ);\n    }\n    if(negcheck) {\n        mp_sub(M, &tmpZ, &tmpZ);\n    }\n\n    mp_copy(&tmpZ, Z);\n\n    mp_clear(&tmpZ);\n    mp_clear(&r_inv);\n\n    return ret;\n}\n/* Z = X^Y mod M                                      */\nint esp_mp_exptmod(fp_int* X, fp_int* Y, word32 Ys, fp_int* M, fp_int* Z)\n{\n    int ret = 0;\n\n    word32 Xs;\n    word32 Ms;\n    word32 maxWords_sz;\n    word32 hwWords_sz;\n\n    mp_int r_inv;\n    mp_digit mp;\n\n    /* ask bits number */\n    Xs = mp_count_bits(X);\n    Ms = mp_count_bits(M);\n    /* maximum bits and words for writing to hw */\n    maxWords_sz = bits2words(max(Xs, max(Ys, Ms)));\n    hwWords_sz  = words2hwords(maxWords_sz);\n\n    if((hwWords_sz<<5) > ESP_HW_RSAMAX_BIT) {\n        ESP_LOGE(TAG, \"exceeds hw maximum bits\");\n        return -2;\n    }\n    /* calculate r_inv = R^2 mode M\n    *    where: R = b^n, and b = 2^32\n    *    accordingly R^2 = 2^(n*32*2)\n    */\n    ret = mp_init(&r_inv);\n    if(ret == 0 && (ret = esp_get_rinv(&r_inv, M, (hwWords_sz<<6))) != MP_OKAY) {\n        ESP_LOGE(TAG, \"calculate r_inv failed.\");\n        mp_clear(&r_inv);\n        return ret;\n    }\n    /* lock and init the hw                           */\n    if((ret = esp_mp_hw_lock()) != MP_OKAY) {\n        mp_clear(&r_inv);\n        return ret;\n    }\n    /* calc M' */\n    /* if Pm is odd, uses mp_montgomery_setup() */\n    if((ret = esp_calc_Mdash(M, 32/* bits */, &mp)) != MP_OKAY) {\n        ESP_LOGE(TAG, \"failed to calculate M dash\");\n        mp_clear(&r_inv);\n        return -1;\n    }\n\n    /*Steps to use hw in the following order:\n    * 1. Write(N/512bits - 1) to MODEXP_MODE_REG\n    * 2. Write X, Y, M and r_inv to memory blocks\n    *    need to write data to each memory block only according to the length\n    *    of the number.\n    * 3. Write M' to M_PRIME_REG\n    * 4. Write 1  to MODEXP_START_REG\n    * 5. Wait for the operation to be done. Poll INTERRUPT_REG until it reads 1.\n    *    (Or until the INTER interrupt is generated.)\n    * 6. Read the result Z(=Y) from Z_MEM\n    * 7. Write 1 to INTERRUPT_REG to clear the interrupt.\n    */\n    if((ret = esp_mp_hw_wait_clean()) != MP_OKAY){\n        return ret;\n    }\n\n    /* step.1                                         */\n    DPORT_REG_WRITE(RSA_MODEXP_MODE_REG, (hwWords_sz >> 4) - 1);\n    /* step.2 write G, X, P, r_inv and M' into memory */\n    esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE, X, Xs, hwWords_sz);\n    esp_mpint_to_memblock(RSA_MEM_Y_BLOCK_BASE, Y, Ys, hwWords_sz);\n    esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE, M, Ms, hwWords_sz);\n    esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE, &r_inv, mp_count_bits(&r_inv),\n                                                                   hwWords_sz);\n    /* step.3 write M' into memory                    */\n    DPORT_REG_WRITE(RSA_M_DASH_REG, mp);\n    /* step.4 start process                           */\n    process_start(RSA_START_MODEXP_REG);\n\n    /* step.5 wait until done                         */\n    wait_uitil_done(RSA_INTERRUPT_REG);\n    /* step.6 read a result form memory               */\n    esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(Ms));\n    /* step.7 clear and release hw                    */\n    esp_mp_hw_unlock();\n\n    mp_clear(&r_inv);\n\n    return ret;\n}\n#endif /* !NO_RSA || HAVE_ECC */\n#endif /* (WOLFSS_ESP32WROOM32_CRYPT) && (NO_WOLFSSL_ESP32WROOM32_CRYPT_RES_PRI)*/\n"
  },
  {
    "path": "src/wolfcrypt/src/port/Espressif/esp32_sha.c",
    "content": "/* esp32_sha.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n#include <string.h>\n#include <stdio.h>\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if !defined(NO_SHA) || !defined(NO_SHA256) || defined(WC_SHA384) || \\\n     defined(WC_SHA512)\n\n#include \"wolfssl/wolfcrypt/logging.h\"\n\n\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n   !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n\n#include <wolfssl/wolfcrypt/sha.h>\n#include <wolfssl/wolfcrypt/sha256.h>\n#include <wolfssl/wolfcrypt/sha512.h>\n\n#include \"wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h\"\n#include \"wolfssl/wolfcrypt/error-crypt.h\"\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\nstatic const char* TAG = \"wolf_hw_sha\";\n/* continue register offset */\n#define CONTINUE_REG_OFFSET    (0x04)     /* start_reg + 0x04 */\n\n#ifdef NO_SHA\n    #define WC_SHA_DIGEST_SIZE 20\n#endif\n/* mutex */\n#if defined(SINGLE_THREADED)\nstatic int InUse = 0;\n#else\nstatic wolfSSL_Mutex sha_mutex;\nstatic int espsha_CryptHwMutexInit = 0;\n#endif\n/*\n    enum SHA_TYPE {\n        SHA1 = 0,\n        SHA2_256,\n        SHA2_384,\n        SHA2_512,\n        SHA_INVALID = -1,\n    };\n*/\nstatic word32 esp_sha_digest_size(enum SHA_TYPE type)\n{\n    ESP_LOGV(TAG, \"enter esp_sha_digest_size\");\n\n    switch(type){\n#ifndef NO_SHA\n        case SHA1:\n            return WC_SHA_DIGEST_SIZE;\n#endif\n#ifndef NO_SHA256\n        case SHA2_256:\n            return WC_SHA256_DIGEST_SIZE;\n#endif\n#ifdef WOLFSSL_SHA384\n        case SHA2_384:\n            return WC_SHA384_DIGEST_SIZE;\n#endif\n#ifdef WOLFSSL_SHA512\n        case SHA2_512:\n            return WC_SHA512_DIGEST_SIZE;\n#endif\n        default:\n            ESP_LOGE(TAG, \"Bad sha type\");\n            return WC_SHA_DIGEST_SIZE;\n    }\n    ESP_LOGV(TAG, \"leave esp_sha_digest_size\");\n}\n/*\n* wait until engines becomes idle\n*/\nstatic void esp_wait_until_idle()\n{\n    while((DPORT_REG_READ(SHA_1_BUSY_REG)  !=0) ||\n          (DPORT_REG_READ(SHA_256_BUSY_REG)!=0) ||\n          (DPORT_REG_READ(SHA_384_BUSY_REG)!=0) ||\n          (DPORT_REG_READ(SHA_512_BUSY_REG)!=0)){ }\n}\n/*\n* lock hw engine.\n* this should be called before using engine.\n*/\nint esp_sha_try_hw_lock(WC_ESP32SHA* ctx)\n{\n    int ret = 0;\n\n    ESP_LOGV(TAG, \"enter esp_sha_hw_lock\");\n\n    /* Init mutex */\n#if defined(SINGLE_THREADED)\n    if(ctx->mode == ESP32_SHA_INIT) {\n        if(!InUse) {\n            ctx->mode = ESP32_SHA_HW;\n            InUse = 1;\n        } else {\n            ctx->mode = ESP32_SHA_SW;\n        }\n    } else {\n         /* this should not happens */\n        ESP_LOGE(TAG, \"unexpected error in esp_sha_try_hw_lock.\");\n        return -1;\n    }\n#else\n    if(espsha_CryptHwMutexInit == 0){\n        ret = esp_CryptHwMutexInit(&sha_mutex);\n        if(ret == 0) {\n            espsha_CryptHwMutexInit = 1;\n        } else {\n            ESP_LOGE(TAG, \" mutex initialization failed.\");\n            ctx->mode = ESP32_SHA_SW;\n            return 0;\n        }\n    }\n    /* check if this sha has been operated as sw or hw, or not yet init */\n    if(ctx->mode == ESP32_SHA_INIT){\n        /* try to lock the hw engine */\n        if(esp_CryptHwMutexLock(&sha_mutex, (TickType_t)0) == 0) {\n            ctx->mode = ESP32_SHA_HW;\n        } else {\n            ESP_LOGI(TAG, \"someone used. hw is locked.....\");\n            ESP_LOGI(TAG, \"the rest of operation will use sw implementation for this sha\");\n            ctx->mode = ESP32_SHA_SW;\n            return 0;\n        }\n    } else {\n        /* this should not happens */\n        ESP_LOGE(TAG, \"unexpected error in esp_sha_try_hw_lock.\");\n        return -1;\n    }\n#endif\n   /* Enable SHA hardware */\n    periph_module_enable(PERIPH_SHA_MODULE);\n\n    ESP_LOGV(TAG, \"leave esp_sha_hw_lock\");\n    return ret;\n}\n/*\n* release hw engine\n*/\nvoid esp_sha_hw_unlock( void )\n{\n    ESP_LOGV(TAG, \"enter esp_sha_hw_unlock\");\n\n    /* Disable AES hardware */\n    periph_module_disable(PERIPH_SHA_MODULE);\n#if defined(SINGLE_THREADED)\n    InUse = 0;\n#else\n    /* unlock hw engine for next use */\n    esp_CryptHwMutexUnLock(&sha_mutex);\n#endif\n    ESP_LOGV(TAG, \"leave esp_sha_hw_unlock\");\n}\n/*\n* start sha process by using hw engine\n*/\nstatic void esp_sha_start_process(WC_ESP32SHA* sha, word32 address)\n{\n    ESP_LOGV(TAG, \"enter esp_sha_start_process\");\n\n    if(sha->isfirstblock){\n        /* start first message block */\n        DPORT_REG_WRITE(address, 1);\n        sha->isfirstblock = 0;\n    } else {\n        /* CONTINU_REG */\n        DPORT_REG_WRITE(address + CONTINUE_REG_OFFSET , 1);\n   }\n\n   ESP_LOGV(TAG, \"leave esp_sha_start_process\");\n}\n/*\n* process message block\n*/\nstatic void esp_process_block(WC_ESP32SHA* ctx,  word32 address,\n                                         const word32* data, word32 len)\n{\n    int i;\n\n    ESP_LOGV(TAG, \"enter esp_process_block\");\n\n    /* check if there are any busy engine */\n    esp_wait_until_idle();\n    /* load message data into hw */\n    for(i=0;i<((len)/(sizeof(word32)));++i){\n        DPORT_REG_WRITE(SHA_TEXT_BASE+(i*sizeof(word32)),*(data+i));\n    }\n    /* notify hw to start process */\n    esp_sha_start_process(ctx, address);\n\n    ESP_LOGV(TAG, \"leave esp_process_block\");\n}\n/*\n* retrieve sha digest from memory\n*/\nstatic void esp_digest_state(WC_ESP32SHA* ctx, byte* hash, enum SHA_TYPE sha_type)\n{\n    /* registers */\n    word32 SHA_LOAD_REG = SHA_1_LOAD_REG;\n    word32 SHA_BUSY_REG = SHA_1_BUSY_REG;\n\n    ESP_LOGV(TAG, \"enter esp_digest_state\");\n\n    /* sanity check */\n    if(sha_type == SHA_INVALID) {\n        ESP_LOGE(TAG, \"unexpected error. sha_type is invalid.\");\n        return;\n    }\n\n    SHA_LOAD_REG += (sha_type << 4);\n    SHA_BUSY_REG += (sha_type << 4);\n\n    if(ctx->isfirstblock == 1){\n        /* no hardware use yet. Nothing to do yet */\n        return ;\n    }\n\n    /* wait until idle */\n    esp_wait_until_idle();\n\n    /* LOAD final digest */\n    DPORT_REG_WRITE(SHA_LOAD_REG, 1);\n    /* wait until done */\n    while(DPORT_REG_READ(SHA_BUSY_REG) == 1){ }\n\n    esp_dport_access_read_buffer((word32*)(hash), SHA_TEXT_BASE,\n                                 esp_sha_digest_size(sha_type)/sizeof(word32));\n\n#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)\n    if(sha_type==SHA2_384||sha_type==SHA2_512) {\n        word32  i;\n        word32* pwrd1 = (word32*)(hash);\n        /* swap value */\n        for(i = 0; i <WC_SHA512_DIGEST_SIZE/4; i+=2 ) {\n            pwrd1[i]  ^= pwrd1[i+1];\n            pwrd1[i+1]^= pwrd1[i];\n            pwrd1[i]  ^= pwrd1[i+1];\n        }\n    }\n#endif\n\n    ESP_LOGV(TAG, \"leave esp_digest_state\");\n}\n\n#ifndef NO_SHA\n/*\n* sha1 process\n*/\nint esp_sha_process(struct wc_Sha* sha, const byte* data)\n{\n    int ret = 0;\n\n    ESP_LOGV(TAG, \"enter esp_sha_process\");\n\n    word32 SHA_START_REG = SHA_1_START_REG;\n\n    esp_process_block(&sha->ctx, SHA_START_REG, (const word32*)data,\n                                        WC_SHA_BLOCK_SIZE);\n\n    ESP_LOGV(TAG, \"leave esp_sha_process\");\n    return ret;\n}\n/*\n* retrieve sha1 digest\n*/\nint esp_sha_digest_process(struct wc_Sha* sha, byte blockproc)\n{\n    int ret = 0;\n\n    ESP_LOGV(TAG, \"enter esp_sha_digest_process\");\n\n    if(blockproc) {\n        word32 SHA_START_REG = SHA_1_START_REG;\n\n        esp_process_block(&sha->ctx, SHA_START_REG, sha->buffer,\n                                            WC_SHA_BLOCK_SIZE);\n    }\n\n    esp_digest_state(&sha->ctx, (byte*)sha->digest, SHA1);\n\n    ESP_LOGV(TAG, \"leave esp_sha_digest_process\");\n\n    return ret;\n}\n#endif /* NO_SHA */\n\n\n#ifndef NO_SHA256\n/*\n* sha256 process\n*/\nint esp_sha256_process(struct wc_Sha256* sha, const byte* data)\n{\n    int ret = 0;\n    word32 SHA_START_REG = SHA_1_START_REG;\n\n    ESP_LOGV(TAG, \"enter esp_sha256_process\");\n\n    /* start register offset */\n    SHA_START_REG += (SHA2_256 << 4);\n\n    esp_process_block(&sha->ctx, SHA_START_REG, (const word32*)data,\n        WC_SHA256_BLOCK_SIZE);\n\n    ESP_LOGV(TAG, \"leave esp_sha256_process\");\n\n    return ret;\n}\n/*\n* retrieve sha256 digest\n*/\nint esp_sha256_digest_process(struct wc_Sha256* sha, byte blockproc)\n{\n    int ret = 0;\n\n    ESP_LOGV(TAG, \"enter esp_sha256_digest_process\");\n\n    if(blockproc) {\n        word32 SHA_START_REG = SHA_1_START_REG + (SHA2_256 << 4);\n\n        esp_process_block(&sha->ctx, SHA_START_REG, sha->buffer,\n                                           WC_SHA256_BLOCK_SIZE);\n    }\n\n    esp_digest_state(&sha->ctx, (byte*)sha->digest, SHA2_256);\n\n    ESP_LOGV(TAG, \"leave esp_sha256_digest_process\");\n    return ret;\n}\n#endif /* NO_SHA256 */\n\n#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)\n/*\n* sha512 proess. this is used for sha384 too.\n*/\nvoid esp_sha512_block(struct wc_Sha512* sha, const word32* data, byte isfinal)\n{\n    enum SHA_TYPE sha_type = sha->ctx.sha_type;\n    word32 SHA_START_REG = SHA_1_START_REG;\n\n    ESP_LOGV(TAG, \"enter esp_sha512_block\");\n    /* start register offset */\n    SHA_START_REG += (sha_type << 4);\n\n    if(sha->ctx.mode == ESP32_SHA_SW){\n        ByteReverseWords64(sha->buffer, sha->buffer,\n                               WC_SHA512_BLOCK_SIZE);\n        if(isfinal){\n            sha->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha->hiLen;\n            sha->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha->loLen;\n        }\n\n    } else {\n        ByteReverseWords((word32*)sha->buffer, (word32*)sha->buffer,\n                                                        WC_SHA512_BLOCK_SIZE);\n        if(isfinal){\n            sha->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] =\n                                        rotlFixed64(sha->hiLen, 32U);\n            sha->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] =\n                                        rotlFixed64(sha->loLen, 32U);\n        }\n\n        esp_process_block(&sha->ctx, SHA_START_REG, data, WC_SHA512_BLOCK_SIZE);\n    }\n    ESP_LOGV(TAG, \"leave esp_sha512_block\");\n}\n/*\n* sha512 process. this is used for sha384 too.\n*/\nint esp_sha512_process(struct wc_Sha512* sha)\n{\n    word32 *data = (word32*)sha->buffer;\n\n    ESP_LOGV(TAG, \"enter esp_sha512_process\");\n\n    esp_sha512_block(sha, data, 0);\n\n    ESP_LOGV(TAG, \"leave esp_sha512_process\");\n    return 0;\n}\n/*\n* retrieve sha512 digest. this is used for sha384 too.\n*/\nint esp_sha512_digest_process(struct wc_Sha512* sha, byte blockproc)\n{\n    ESP_LOGV(TAG, \"enter esp_sha512_digest_process\");\n\n    if(blockproc) {\n        word32* data = (word32*)sha->buffer;\n\n        esp_sha512_block(sha, data, 1);\n    }\n    if(sha->ctx.mode != ESP32_SHA_SW)\n        esp_digest_state(&sha->ctx, (byte*)sha->digest, sha->ctx.sha_type);\n\n    ESP_LOGV(TAG, \"leave esp_sha512_digest_process\");\n    return 0;\n}\n#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */\n#endif /* WOLFSSL_ESP32WROOM32_CRYPT */\n#endif /* !defined(NO_SHA) ||... */\n"
  },
  {
    "path": "src/wolfcrypt/src/port/Espressif/esp32_util.c",
    "content": "/* esp32_util.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n  (!defined(NO_AES)        || !defined(NO_SHA) || !defined(NO_SHA256) ||\\\n   defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512))\n\n#include <wolfssl/wolfcrypt/wc_port.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n\nint esp_CryptHwMutexInit(wolfSSL_Mutex* mutex) {\n    return wc_InitMutex(mutex);\n}\n\nint esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t xBlockTime) {\n#ifdef SINGLE_THREADED\n    return wc_LockMutex(mutex);\n#else\n    return ((xSemaphoreTake( *mutex, xBlockTime ) == pdTRUE) ? 0 : BAD_MUTEX_E);\n#endif\n}\n\nint esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex) {\n    return wc_UnLockMutex(mutex);\n}\n\n#endif\n\n#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG\n\n#include \"esp_timer.h\"\n#include \"esp_log.h\"\n\nstatic uint64_t startTime = 0;\n\n\nvoid wc_esp32TimerStart()\n{\n    startTime = esp_timer_get_time();\n}\n\nuint64_t  wc_esp32elapsedTime()\n{\n    /* return elapsed time since wc_esp32AesTimeStart() is called in us */\n    return esp_timer_get_time() - startTime;\n}\n\n#endif /*WOLFSSL_ESP32WROOM32_CRYPT_DEBUG */\n"
  },
  {
    "path": "src/wolfcrypt/src/pwdbased.c.unused",
    "content": "/* pwdbased.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifndef NO_PWDBASED\n\n#include <wolfssl/wolfcrypt/pwdbased.h>\n#include <wolfssl/wolfcrypt/hmac.h>\n#include <wolfssl/wolfcrypt/hash.h>\n#include <wolfssl/wolfcrypt/integer.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\n#ifdef HAVE_PBKDF1\n\n/* PKCS#5 v1.5 with non standard extension to optionally derive the extra data (IV) */\nint wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,\n    const byte* passwd, int passwdLen, const byte* salt, int saltLen,\n    int iterations, int hashType, void* heap)\n{\n    int  err;\n    int  keyLeft, ivLeft, i;\n    int  digestLeft, store;\n    int  keyOutput = 0;\n    int  diestLen;\n    byte digest[WC_MAX_DIGEST_SIZE];\n#ifdef WOLFSSL_SMALL_STACK\n    wc_HashAlg* hash = NULL;\n#else\n    wc_HashAlg  hash[1];\n#endif\n    enum wc_HashType hashT;\n\n    (void)heap;\n\n    if (key == NULL || keyLen < 0 || passwdLen < 0 || saltLen < 0 || ivLen < 0){\n        return BAD_FUNC_ARG;\n    }\n\n    if (iterations <= 0)\n        iterations = 1;\n\n    hashT = wc_HashTypeConvert(hashType);\n    err = wc_HashGetDigestSize(hashT);\n    if (err < 0)\n        return err;\n    diestLen = err;\n\n    /* initialize hash */\n#ifdef WOLFSSL_SMALL_STACK\n    hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), heap,\n                                DYNAMIC_TYPE_HASHCTX);\n    if (hash == NULL)\n        return MEMORY_E;\n#endif\n\n    err = wc_HashInit_ex(hash, hashT, heap, INVALID_DEVID);\n    if (err != 0) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(hash, heap, DYNAMIC_TYPE_HASHCTX);\n    #endif\n        return err;\n    }\n\n    keyLeft = keyLen;\n    ivLeft  = ivLen;\n    while (keyOutput < (keyLen + ivLen)) {\n        digestLeft = diestLen;\n        /* D_(i - 1) */\n        if (keyOutput) { /* first time D_0 is empty */\n            err = wc_HashUpdate(hash, hashT, digest, diestLen);\n            if (err != 0) break;\n        }\n\n        /* data */\n        err = wc_HashUpdate(hash, hashT, passwd, passwdLen);\n        if (err != 0) break;\n\n        /* salt */\n        if (salt) {\n            err = wc_HashUpdate(hash, hashT, salt, saltLen);\n            if (err != 0) break;\n        }\n\n        err = wc_HashFinal(hash, hashT, digest);\n        if (err != 0) break;\n\n        /* count */\n        for (i = 1; i < iterations; i++) {\n            err = wc_HashUpdate(hash, hashT, digest, diestLen);\n            if (err != 0) break;\n\n            err = wc_HashFinal(hash, hashT, digest);\n            if (err != 0) break;\n        }\n\n        if (keyLeft) {\n            store = min(keyLeft, diestLen);\n            XMEMCPY(&key[keyLen - keyLeft], digest, store);\n\n            keyOutput  += store;\n            keyLeft    -= store;\n            digestLeft -= store;\n        }\n\n        if (ivLeft && digestLeft) {\n            store = min(ivLeft, digestLeft);\n            if (iv != NULL)\n                XMEMCPY(&iv[ivLen - ivLeft],\n                        &digest[diestLen - digestLeft], store);\n            keyOutput += store;\n            ivLeft    -= store;\n        }\n    }\n\n    wc_HashFree(hash, hashT);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(hash, heap, DYNAMIC_TYPE_HASHCTX);\n#endif\n\n    if (err != 0)\n        return err;\n\n    if (keyOutput != (keyLen + ivLen))\n        return BUFFER_E;\n\n    return err;\n}\n\n/* PKCS#5 v1.5 */\nint wc_PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt,\n           int sLen, int iterations, int kLen, int hashType)\n{\n    return wc_PBKDF1_ex(output, kLen, NULL, 0,\n        passwd, pLen, salt, sLen, iterations, hashType, NULL);\n}\n\n#endif /* HAVE_PKCS5 */\n\n#ifdef HAVE_PBKDF2\n\nint wc_PBKDF2_ex(byte* output, const byte* passwd, int pLen, const byte* salt,\n           int sLen, int iterations, int kLen, int hashType, void* heap, int devId)\n{\n    word32 i = 1;\n    int    hLen;\n    int    j, ret;\n#ifdef WOLFSSL_SMALL_STACK\n    byte*  buffer;\n    Hmac*  hmac;\n#else\n    byte   buffer[WC_MAX_DIGEST_SIZE];\n    Hmac   hmac[1];\n#endif\n    enum wc_HashType hashT;\n\n    if (output == NULL || pLen < 0 || sLen < 0 || kLen < 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (iterations <= 0)\n        iterations = 1;\n\n    hashT = wc_HashTypeConvert(hashType);\n    hLen = wc_HashGetDigestSize(hashT);\n    if (hLen < 0)\n        return BAD_FUNC_ARG;\n\n#ifdef WOLFSSL_SMALL_STACK\n    buffer = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (buffer == NULL)\n        return MEMORY_E;\n    hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC);\n    if (hmac == NULL) {\n        XFREE(buffer, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n#endif\n\n    ret = wc_HmacInit(hmac, heap, devId);\n    if (ret == 0) {\n        /* use int hashType here, since HMAC FIPS uses the old unique value */\n        ret = wc_HmacSetKey(hmac, hashType, passwd, pLen);\n\n        while (ret == 0 && kLen) {\n            int currentLen;\n\n            ret = wc_HmacUpdate(hmac, salt, sLen);\n            if (ret != 0)\n                break;\n\n            /* encode i */\n            for (j = 0; j < 4; j++) {\n                byte b = (byte)(i >> ((3-j) * 8));\n\n                ret = wc_HmacUpdate(hmac, &b, 1);\n                if (ret != 0)\n                    break;\n            }\n\n            /* check ret from inside for loop */\n            if (ret != 0)\n                break;\n\n            ret = wc_HmacFinal(hmac, buffer);\n            if (ret != 0)\n                break;\n\n            currentLen = min(kLen, hLen);\n            XMEMCPY(output, buffer, currentLen);\n\n            for (j = 1; j < iterations; j++) {\n                ret = wc_HmacUpdate(hmac, buffer, hLen);\n                if (ret != 0)\n                    break;\n                ret = wc_HmacFinal(hmac, buffer);\n                if (ret != 0)\n                    break;\n                xorbuf(output, buffer, currentLen);\n            }\n\n            /* check ret from inside for loop */\n            if (ret != 0)\n                break;\n\n            output += currentLen;\n            kLen   -= currentLen;\n            i++;\n        }\n        wc_HmacFree(hmac);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(buffer, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);\n#endif\n\n    return ret;\n}\n\nint wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,\n           int sLen, int iterations, int kLen, int hashType)\n{\n    return wc_PBKDF2_ex(output, passwd, pLen, salt, sLen, iterations, kLen,\n        hashType, NULL, INVALID_DEVID);\n}\n\n#endif /* HAVE_PBKDF2 */\n\n#ifdef HAVE_PKCS12\n\n/* helper for PKCS12_PBKDF(), does hash operation */\nstatic int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,\n                 byte* Ai, word32 u, int iterations)\n{\n    int i;\n    int ret = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    wc_HashAlg* hash = NULL;\n#else\n    wc_HashAlg  hash[1];\n#endif\n    enum wc_HashType hashT;\n\n    if (buffer == NULL || Ai == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    hashT = wc_HashTypeConvert(hashType);\n\n    /* initialize hash */\n#ifdef WOLFSSL_SMALL_STACK\n    hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL,\n                                DYNAMIC_TYPE_HASHCTX);\n    if (hash == NULL)\n        return MEMORY_E;\n#endif\n\n    ret = wc_HashInit(hash, hashT);\n    if (ret != 0) {\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(hash, NULL, DYNAMIC_TYPE_HASHCTX);\n    #endif\n        return ret;\n    }\n\n    ret = wc_HashUpdate(hash, hashT, buffer, totalLen);\n\n    if (ret == 0)\n        ret = wc_HashFinal(hash, hashT, Ai);\n\n    for (i = 1; i < iterations; i++) {\n        if (ret == 0)\n            ret = wc_HashUpdate(hash, hashT, Ai, u);\n        if (ret == 0)\n            ret = wc_HashFinal(hash, hashT, Ai);\n    }\n\n    wc_HashFree(hash, hashT);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(hash, NULL, DYNAMIC_TYPE_HASHCTX);\n#endif\n\n    return ret;\n}\n\n\nint wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,\n    const byte* salt, int saltLen, int iterations, int kLen, int hashType,\n    int id)\n{\n    return wc_PKCS12_PBKDF_ex(output, passwd, passLen, salt, saltLen,\n                              iterations, kLen, hashType, id, NULL);\n}\n\n\n/* extended API that allows a heap hint to be used */\nint wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,\n                       const byte* salt, int saltLen, int iterations, int kLen,\n                       int hashType, int id, void* heap)\n{\n    /* all in bytes instead of bits */\n    word32 u, v, dLen, pLen, iLen, sLen, totalLen;\n    int    dynamic = 0;\n    int    ret = 0;\n    int    i;\n    byte   *D, *S, *P, *I;\n#ifdef WOLFSSL_SMALL_STACK\n    byte   staticBuffer[1]; /* force dynamic usage */\n#else\n    byte   staticBuffer[1024];\n#endif\n    byte*  buffer = staticBuffer;\n\n#ifdef WOLFSSL_SMALL_STACK\n    byte*  Ai;\n    byte*  B;\n#else\n    byte   Ai[WC_MAX_DIGEST_SIZE];\n    byte   B[WC_MAX_BLOCK_SIZE];\n#endif\n    enum wc_HashType hashT;\n\n    (void)heap;\n\n    if (output == NULL || passLen < 0 || saltLen < 0 || kLen < 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (iterations <= 0)\n        iterations = 1;\n\n    hashT = wc_HashTypeConvert(hashType);\n    ret = wc_HashGetDigestSize(hashT);\n    if (ret < 0)\n        return ret;\n    u = ret;\n\n    ret = wc_HashGetBlockSize(hashT);\n    if (ret < 0)\n        return ret;\n    v = ret;\n\n#ifdef WOLFSSL_SMALL_STACK\n    Ai = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (Ai == NULL)\n        return MEMORY_E;\n\n    B = (byte*)XMALLOC(WC_MAX_BLOCK_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (B == NULL) {\n        XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);\n        return MEMORY_E;\n    }\n#endif\n\n    XMEMSET(Ai, 0, WC_MAX_DIGEST_SIZE);\n    XMEMSET(B,  0, WC_MAX_BLOCK_SIZE);\n\n    dLen = v;\n    sLen = v * ((saltLen + v - 1) / v);\n    if (passLen)\n        pLen = v * ((passLen + v - 1) / v);\n    else\n        pLen = 0;\n    iLen = sLen + pLen;\n\n    totalLen = dLen + sLen + pLen;\n\n    if (totalLen > sizeof(staticBuffer)) {\n        buffer = (byte*)XMALLOC(totalLen, heap, DYNAMIC_TYPE_KEY);\n        if (buffer == NULL) {\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);\n            XFREE(B,  heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n            return MEMORY_E;\n        }\n        dynamic = 1;\n    }\n\n    D = buffer;\n    S = D + dLen;\n    P = S + sLen;\n    I = S;\n\n    XMEMSET(D, id, dLen);\n\n    for (i = 0; i < (int)sLen; i++)\n        S[i] = salt[i % saltLen];\n    for (i = 0; i < (int)pLen; i++)\n        P[i] = passwd[i % passLen];\n\n    while (kLen > 0) {\n        word32 currentLen;\n        mp_int B1;\n\n        ret = DoPKCS12Hash(hashType, buffer, totalLen, Ai, u, iterations);\n        if (ret < 0)\n            break;\n\n        for (i = 0; i < (int)v; i++)\n            B[i] = Ai[i % u];\n\n        if (mp_init(&B1) != MP_OKAY)\n            ret = MP_INIT_E;\n        else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY)\n            ret = MP_READ_E;\n        else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY)\n            ret = MP_ADD_E;\n\n        if (ret != 0) {\n            mp_clear(&B1);\n            break;\n        }\n\n        for (i = 0; i < (int)iLen; i += v) {\n            int    outSz;\n            mp_int i1;\n            mp_int res;\n\n            if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) {\n                ret = MP_INIT_E;\n                break;\n            }\n            if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY)\n                ret = MP_READ_E;\n            else if (mp_add(&i1, &B1, &res) != MP_OKAY)\n                ret = MP_ADD_E;\n            else if ( (outSz = mp_unsigned_bin_size(&res)) < 0)\n                ret = MP_TO_E;\n            else {\n                if (outSz > (int)v) {\n                    /* take off MSB */\n                    byte  tmp[WC_MAX_BLOCK_SIZE + 1];\n                    ret = mp_to_unsigned_bin(&res, tmp);\n                    XMEMCPY(I + i, tmp + 1, v);\n                }\n                else if (outSz < (int)v) {\n                    XMEMSET(I + i, 0, v - outSz);\n                    ret = mp_to_unsigned_bin(&res, I + i + v - outSz);\n                }\n                else\n                    ret = mp_to_unsigned_bin(&res, I + i);\n            }\n\n            mp_clear(&i1);\n            mp_clear(&res);\n            if (ret < 0) break;\n        }\n\n        currentLen = min(kLen, (int)u);\n        XMEMCPY(output, Ai, currentLen);\n        output += currentLen;\n        kLen   -= currentLen;\n        mp_clear(&B1);\n    }\n\n    if (dynamic) XFREE(buffer, heap, DYNAMIC_TYPE_KEY);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    XFREE(B,  heap, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n#endif /* HAVE_PKCS12 */\n\n#ifdef HAVE_SCRYPT\n/* Rotate the 32-bit value a by b bits to the left.\n *\n * a  32-bit value.\n * b  Number of bits to rotate.\n * returns rotated value.\n */\n#define R(a, b) rotlFixed(a, b)\n\n/* One round of Salsa20/8.\n * Code taken from RFC 7914: scrypt PBKDF.\n *\n * out  Output buffer.\n * in   Input data to hash.\n */\nstatic void scryptSalsa(word32* out, word32* in)\n{\n    int    i;\n    word32 x[16];\n\n#ifdef LITTLE_ENDIAN_ORDER\n    for (i = 0; i < 16; ++i)\n        x[i] = in[i];\n#else\n    for (i = 0; i < 16; i++)\n        x[i] = ByteReverseWord32(in[i]);\n#endif\n    for (i = 8; i > 0; i -= 2) {\n        x[ 4] ^= R(x[ 0] + x[12],  7);  x[ 8] ^= R(x[ 4] + x[ 0],  9);\n        x[12] ^= R(x[ 8] + x[ 4], 13);  x[ 0] ^= R(x[12] + x[ 8], 18);\n        x[ 9] ^= R(x[ 5] + x[ 1],  7);  x[13] ^= R(x[ 9] + x[ 5],  9);\n        x[ 1] ^= R(x[13] + x[ 9], 13);  x[ 5] ^= R(x[ 1] + x[13], 18);\n        x[14] ^= R(x[10] + x[ 6],  7);  x[ 2] ^= R(x[14] + x[10],  9);\n        x[ 6] ^= R(x[ 2] + x[14], 13);  x[10] ^= R(x[ 6] + x[ 2], 18);\n        x[ 3] ^= R(x[15] + x[11],  7);  x[ 7] ^= R(x[ 3] + x[15],  9);\n        x[11] ^= R(x[ 7] + x[ 3], 13);  x[15] ^= R(x[11] + x[ 7], 18);\n        x[ 1] ^= R(x[ 0] + x[ 3],  7);  x[ 2] ^= R(x[ 1] + x[ 0],  9);\n        x[ 3] ^= R(x[ 2] + x[ 1], 13);  x[ 0] ^= R(x[ 3] + x[ 2], 18);\n        x[ 6] ^= R(x[ 5] + x[ 4],  7);  x[ 7] ^= R(x[ 6] + x[ 5],  9);\n        x[ 4] ^= R(x[ 7] + x[ 6], 13);  x[ 5] ^= R(x[ 4] + x[ 7], 18);\n        x[11] ^= R(x[10] + x[ 9],  7);  x[ 8] ^= R(x[11] + x[10],  9);\n        x[ 9] ^= R(x[ 8] + x[11], 13);  x[10] ^= R(x[ 9] + x[ 8], 18);\n        x[12] ^= R(x[15] + x[14],  7);  x[13] ^= R(x[12] + x[15],  9);\n        x[14] ^= R(x[13] + x[12], 13);  x[15] ^= R(x[14] + x[13], 18);\n    }\n#ifdef LITTLE_ENDIAN_ORDER\n    for (i = 0; i < 16; ++i)\n        out[i] = in[i] + x[i];\n#else\n    for (i = 0; i < 16; i++)\n        out[i] = ByteReverseWord32(ByteReverseWord32(in[i]) + x[i]);\n#endif\n}\n\n/* Mix a block using Salsa20/8.\n * Based on RFC 7914: scrypt PBKDF.\n *\n * b  Blocks to mix.\n * y  Temporary storage.\n * r  Size of the block.\n */\nstatic void scryptBlockMix(byte* b, byte* y, int r)\n{\n    byte x[64];\n#ifdef WORD64_AVAILABLE\n    word64* b64 = (word64*)b;\n    word64* y64 = (word64*)y;\n    word64* x64 = (word64*)x;\n#else\n    word32* b32 = (word32*)b;\n    word32* y32 = (word32*)y;\n    word32* x32 = (word32*)x;\n#endif\n    int  i;\n    int  j;\n\n    /* Step 1. */\n    XMEMCPY(x, b + (2 * r - 1) * 64, sizeof(x));\n    /* Step 2. */\n    for (i = 0; i < 2 * r; i++)\n    {\n#ifdef WORD64_AVAILABLE\n        for (j = 0; j < 8; j++)\n            x64[j] ^= b64[i * 8 + j];\n#else\n        for (j = 0; j < 16; j++)\n            x32[j] ^= b32[i * 16 + j];\n#endif\n        scryptSalsa((word32*)x, (word32*)x);\n        XMEMCPY(y + i * 64, x, sizeof(x));\n    }\n    /* Step 3. */\n    for (i = 0; i < r; i++) {\n#ifdef WORD64_AVAILABLE\n        for (j = 0; j < 8; j++) {\n            b64[i * 8 + j] = y64[2 * i * 8 + j];\n            b64[(r + i) * 8 + j] = y64[(2 * i + 1) * 8 + j];\n        }\n#else\n        for (j = 0; j < 16; j++) {\n            b32[i * 16 + j] = y32[2 * i * 16 + j];\n            b32[(r + i) * 16 + j] = y32[(2 * i + 1) * 16 + j];\n        }\n#endif\n    }\n}\n\n/* Random oracles mix.\n * Based on RFC 7914: scrypt PBKDF.\n *\n * x  Data to mix.\n * v  Temporary buffer.\n * y  Temporary buffer for the block mix.\n * r  Block size parameter.\n * n  CPU/Memory cost parameter.\n */\nstatic void scryptROMix(byte* x, byte* v, byte* y, int r, word32 n)\n{\n    word32 i;\n    word32 j;\n    word32 k;\n    word32 bSz = 128 * r;\n#ifdef WORD64_AVAILABLE\n    word64* x64 = (word64*)x;\n    word64* v64 = (word64*)v;\n#else\n    word32* x32 = (word32*)x;\n    word32* v32 = (word32*)v;\n#endif\n\n    /* Step 1. X = B (B not needed therefore not implemented) */\n    /* Step 2. */\n    for (i = 0; i < n; i++)\n    {\n        XMEMCPY(v + i * bSz, x, bSz);\n        scryptBlockMix(x, y, r);\n    }\n\n    /* Step 3. */\n    for (i = 0; i < n; i++)\n    {\n#ifdef LITTLE_ENDIAN_ORDER\n#ifdef WORD64_AVAILABLE\n        j = *(word64*)(x + (2*r - 1) * 64) & (n-1);\n#else\n        j = *(word32*)(x + (2*r - 1) * 64) & (n-1);\n#endif\n#else\n        byte* t = x + (2*r - 1) * 64;\n        j = (t[0] | (t[1] << 8) | (t[2] << 16) | ((word32)t[3] << 24)) & (n-1);\n#endif\n#ifdef WORD64_AVAILABLE\n        for (k = 0; k < bSz / 8; k++)\n            x64[k] ^= v64[j * bSz / 8 + k];\n#else\n        for (k = 0; k < bSz / 4; k++)\n            x32[k] ^= v32[j * bSz / 4 + k];\n#endif\n        scryptBlockMix(x, y, r);\n    }\n    /* Step 4. B' = X (B = X = B' so not needed, therefore not implemented) */\n}\n\n/* Generates an key derived from a password and salt using a memory hard\n * algorithm.\n * Implements RFC 7914: scrypt PBKDF.\n *\n * output     The derived key.\n * passwd     The password to derive key from.\n * passLen    The length of the password.\n * salt       The key specific data.\n * saltLen    The length of the salt data.\n * cost       The CPU/memory cost parameter. Range: 1..(128*r/8-1)\n *            (Iterations = 2^cost)\n * blockSize  The number of 128 byte octets in a working block.\n * parallel   The number of parallel mix operations to perform.\n *            (Note: this implementation does not use threads.)\n * dkLen      The length of the derived key in bytes.\n * returns BAD_FUNC_ARG when: blockSize is too large for cost.\n */\nint wc_scrypt(byte* output, const byte* passwd, int passLen,\n              const byte* salt, int saltLen, int cost, int blockSize,\n              int parallel, int dkLen)\n{\n    int    ret = 0;\n    int    i;\n    byte*  v = NULL;\n    byte*  y = NULL;\n    byte*  blocks = NULL;\n    word32 blocksSz;\n    word32 bSz;\n\n    if (blockSize > 8)\n        return BAD_FUNC_ARG;\n\n    if (cost < 1 || cost >= 128 * blockSize / 8 || parallel < 1 || dkLen < 1)\n        return BAD_FUNC_ARG;\n\n    bSz = 128 * blockSize;\n    blocksSz = bSz * parallel;\n    blocks = (byte*)XMALLOC(blocksSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (blocks == NULL)\n        goto end;\n    /* Temporary for scryptROMix. */\n    v = (byte*)XMALLOC((1 << cost) * bSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (v == NULL)\n        goto end;\n    /* Temporary for scryptBlockMix. */\n    y = (byte*)XMALLOC(blockSize * 128, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (y == NULL)\n        goto end;\n\n    /* Step 1. */\n    ret = wc_PBKDF2(blocks, passwd, passLen, salt, saltLen, 1, blocksSz,\n                    WC_SHA256);\n    if (ret != 0)\n        goto end;\n\n    /* Step 2. */\n    for (i = 0; i < parallel; i++)\n        scryptROMix(blocks + i * bSz, v, y, blockSize, 1 << cost);\n\n    /* Step 3. */\n    ret = wc_PBKDF2(output, passwd, passLen, blocks, blocksSz, 1, dkLen,\n                    WC_SHA256);\nend:\n    if (blocks != NULL)\n        XFREE(blocks, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (v != NULL)\n        XFREE(v, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (y != NULL)\n        XFREE(y, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n\n    return ret;\n}\n\n/* Generates an key derived from a password and salt using a memory hard\n * algorithm.\n * Implements RFC 7914: scrypt PBKDF.\n *\n * output      Derived key.\n * passwd      Password to derive key from.\n * passLen     Length of the password.\n * salt        Key specific data.\n * saltLen     Length of the salt data.\n * iterations  Number of iterations to perform. Range: 1 << (1..(128*r/8-1))\n * blockSize   Number of 128 byte octets in a working block.\n * parallel    Number of parallel mix operations to perform.\n *             (Note: this implementation does not use threads.)\n * dkLen       Length of the derived key in bytes.\n * returns BAD_FUNC_ARG when: iterations is not a power of 2 or blockSize is too\n *                            large for iterations.\n */\nint wc_scrypt_ex(byte* output, const byte* passwd, int passLen,\n                 const byte* salt, int saltLen, word32 iterations,\n                 int blockSize, int parallel, int dkLen)\n{\n    int cost;\n\n    /* Iterations must be a power of 2. */\n    if ((iterations & (iterations - 1)) != 0)\n        return BAD_FUNC_ARG;\n\n    for (cost = -1; iterations != 0; cost++) {\n        iterations >>= 1;\n    }\n\n    return wc_scrypt(output, passwd, passLen, salt, saltLen, cost, blockSize,\n                     parallel, dkLen);\n}\n#endif /* HAVE_SCRYPT */\n\n#endif /* NO_PWDBASED */\n"
  },
  {
    "path": "src/wolfcrypt/src/rabbit.c",
    "content": "/* rabbit.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifndef NO_RABBIT\n\n#include <wolfssl/wolfcrypt/rabbit.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\n#ifdef BIG_ENDIAN_ORDER\n    #define LITTLE32(x) ByteReverseWord32(x)\n#else\n    #define LITTLE32(x) (x)\n#endif\n\n#define U32V(x) ((word32)(x) & 0xFFFFFFFFU)\n\n\n/* Square a 32-bit unsigned integer to obtain the 64-bit result and return */\n/* the upper 32 bits XOR the lower 32 bits */\nstatic word32 RABBIT_g_func(word32 x)\n{\n    /* Temporary variables */\n    word32 a, b, h, l;\n\n    /* Construct high and low argument for squaring */\n    a = x&0xFFFF;\n    b = x>>16;\n\n    /* Calculate high and low result of squaring */\n    h = (((U32V(a*a)>>17) + U32V(a*b))>>15) + b*b;\n    l = x*x;\n\n    /* Return high XOR low */\n    return U32V(h^l);\n}\n\n\n/* Calculate the next internal state */\nstatic void RABBIT_next_state(RabbitCtx* ctx)\n{\n    /* Temporary variables */\n    word32 g[8], c_old[8], i;\n\n    /* Save old counter values */\n    for (i=0; i<8; i++)\n        c_old[i] = ctx->c[i];\n\n    /* Calculate new counter values */\n    ctx->c[0] = U32V(ctx->c[0] + 0x4D34D34D + ctx->carry);\n    ctx->c[1] = U32V(ctx->c[1] + 0xD34D34D3 + (ctx->c[0] < c_old[0]));\n    ctx->c[2] = U32V(ctx->c[2] + 0x34D34D34 + (ctx->c[1] < c_old[1]));\n    ctx->c[3] = U32V(ctx->c[3] + 0x4D34D34D + (ctx->c[2] < c_old[2]));\n    ctx->c[4] = U32V(ctx->c[4] + 0xD34D34D3 + (ctx->c[3] < c_old[3]));\n    ctx->c[5] = U32V(ctx->c[5] + 0x34D34D34 + (ctx->c[4] < c_old[4]));\n    ctx->c[6] = U32V(ctx->c[6] + 0x4D34D34D + (ctx->c[5] < c_old[5]));\n    ctx->c[7] = U32V(ctx->c[7] + 0xD34D34D3 + (ctx->c[6] < c_old[6]));\n    ctx->carry = (ctx->c[7] < c_old[7]);\n\n    /* Calculate the g-values */\n    for (i=0;i<8;i++)\n        g[i] = RABBIT_g_func(U32V(ctx->x[i] + ctx->c[i]));\n\n    /* Calculate new state values */\n    ctx->x[0] = U32V(g[0] + rotlFixed(g[7],16) + rotlFixed(g[6], 16));\n    ctx->x[1] = U32V(g[1] + rotlFixed(g[0], 8) + g[7]);\n    ctx->x[2] = U32V(g[2] + rotlFixed(g[1],16) + rotlFixed(g[0], 16));\n    ctx->x[3] = U32V(g[3] + rotlFixed(g[2], 8) + g[1]);\n    ctx->x[4] = U32V(g[4] + rotlFixed(g[3],16) + rotlFixed(g[2], 16));\n    ctx->x[5] = U32V(g[5] + rotlFixed(g[4], 8) + g[3]);\n    ctx->x[6] = U32V(g[6] + rotlFixed(g[5],16) + rotlFixed(g[4], 16));\n    ctx->x[7] = U32V(g[7] + rotlFixed(g[6], 8) + g[5]);\n}\n\n\n/* IV setup */\nstatic void wc_RabbitSetIV(Rabbit* ctx, const byte* inIv)\n{\n    /* Temporary variables */\n    word32 i0, i1, i2, i3, i;\n    word32 iv[2];\n\n    if (inIv)\n        XMEMCPY(iv, inIv, sizeof(iv));\n    else\n        XMEMSET(iv,    0, sizeof(iv));\n\n    /* Generate four subvectors */\n    i0 = LITTLE32(iv[0]);\n    i2 = LITTLE32(iv[1]);\n    i1 = (i0>>16) | (i2&0xFFFF0000);\n    i3 = (i2<<16) | (i0&0x0000FFFF);\n\n    /* Modify counter values */\n    ctx->workCtx.c[0] = ctx->masterCtx.c[0] ^ i0;\n    ctx->workCtx.c[1] = ctx->masterCtx.c[1] ^ i1;\n    ctx->workCtx.c[2] = ctx->masterCtx.c[2] ^ i2;\n    ctx->workCtx.c[3] = ctx->masterCtx.c[3] ^ i3;\n    ctx->workCtx.c[4] = ctx->masterCtx.c[4] ^ i0;\n    ctx->workCtx.c[5] = ctx->masterCtx.c[5] ^ i1;\n    ctx->workCtx.c[6] = ctx->masterCtx.c[6] ^ i2;\n    ctx->workCtx.c[7] = ctx->masterCtx.c[7] ^ i3;\n\n    /* Copy state variables */\n    for (i=0; i<8; i++)\n        ctx->workCtx.x[i] = ctx->masterCtx.x[i];\n    ctx->workCtx.carry = ctx->masterCtx.carry;\n\n    /* Iterate the system four times */\n    for (i=0; i<4; i++)\n        RABBIT_next_state(&(ctx->workCtx));\n}\n\n\n/* Key setup */\nstatic WC_INLINE int DoKey(Rabbit* ctx, const byte* key, const byte* iv)\n{\n    /* Temporary variables */\n    word32 k0, k1, k2, k3, i;\n\n    /* Generate four subkeys */\n    k0 = LITTLE32(*(word32*)(key+ 0));\n    k1 = LITTLE32(*(word32*)(key+ 4));\n    k2 = LITTLE32(*(word32*)(key+ 8));\n    k3 = LITTLE32(*(word32*)(key+12));\n\n    /* Generate initial state variables */\n    ctx->masterCtx.x[0] = k0;\n    ctx->masterCtx.x[2] = k1;\n    ctx->masterCtx.x[4] = k2;\n    ctx->masterCtx.x[6] = k3;\n    ctx->masterCtx.x[1] = U32V(k3<<16) | (k2>>16);\n    ctx->masterCtx.x[3] = U32V(k0<<16) | (k3>>16);\n    ctx->masterCtx.x[5] = U32V(k1<<16) | (k0>>16);\n    ctx->masterCtx.x[7] = U32V(k2<<16) | (k1>>16);\n\n    /* Generate initial counter values */\n    ctx->masterCtx.c[0] = rotlFixed(k2, 16);\n    ctx->masterCtx.c[2] = rotlFixed(k3, 16);\n    ctx->masterCtx.c[4] = rotlFixed(k0, 16);\n    ctx->masterCtx.c[6] = rotlFixed(k1, 16);\n    ctx->masterCtx.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF);\n    ctx->masterCtx.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF);\n    ctx->masterCtx.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF);\n    ctx->masterCtx.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF);\n\n    /* Clear carry bit */\n    ctx->masterCtx.carry = 0;\n\n    /* Iterate the system four times */\n    for (i=0; i<4; i++)\n        RABBIT_next_state(&(ctx->masterCtx));\n\n    /* Modify the counters */\n    for (i=0; i<8; i++)\n        ctx->masterCtx.c[i] ^= ctx->masterCtx.x[(i+4)&0x7];\n\n    /* Copy master instance to work instance */\n    for (i=0; i<8; i++) {\n        ctx->workCtx.x[i] = ctx->masterCtx.x[i];\n        ctx->workCtx.c[i] = ctx->masterCtx.c[i];\n    }\n    ctx->workCtx.carry = ctx->masterCtx.carry;\n\n    wc_RabbitSetIV(ctx, iv);\n\n    return 0;\n}\n\n\nint wc_Rabbit_SetHeap(Rabbit* ctx, void* heap)\n{\n    if (ctx == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef XSTREAM_ALIGN\n    ctx->heap = heap;\n#endif\n\n    (void)heap;\n    return 0;\n}\n\n\n/* Key setup */\nint wc_RabbitSetKey(Rabbit* ctx, const byte* key, const byte* iv)\n{\n    if (ctx == NULL || key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef XSTREAM_ALIGN\n    /* default heap to NULL or heap test value */\n    #ifdef WOLFSSL_HEAP_TEST\n        ctx->heap = (void*)WOLFSSL_HEAP_TEST;\n    #else\n        ctx->heap = NULL;\n    #endif /* WOLFSSL_HEAP_TEST */\n\n    if ((wolfssl_word)key % 4) {\n        int alignKey[4];\n\n        /* iv aligned in SetIV */\n        WOLFSSL_MSG(\"wc_RabbitSetKey unaligned key\");\n\n        XMEMCPY(alignKey, key, sizeof(alignKey));\n\n        return DoKey(ctx, (const byte*)alignKey, iv);\n    }\n#endif /* XSTREAM_ALIGN */\n\n    return DoKey(ctx, key, iv);\n}\n\n\n/* Encrypt/decrypt a message of any size */\nstatic WC_INLINE int DoProcess(Rabbit* ctx, byte* output, const byte* input,\n                            word32 msglen)\n{\n    /* Encrypt/decrypt all full blocks */\n    while (msglen >= 16) {\n        /* Iterate the system */\n        RABBIT_next_state(&(ctx->workCtx));\n\n        /* Encrypt/decrypt 16 bytes of data */\n        *(word32*)(output+ 0) = *(word32*)(input+ 0) ^\n                   LITTLE32(ctx->workCtx.x[0] ^ (ctx->workCtx.x[5]>>16) ^\n                   U32V(ctx->workCtx.x[3]<<16));\n        *(word32*)(output+ 4) = *(word32*)(input+ 4) ^\n                   LITTLE32(ctx->workCtx.x[2] ^ (ctx->workCtx.x[7]>>16) ^\n                   U32V(ctx->workCtx.x[5]<<16));\n        *(word32*)(output+ 8) = *(word32*)(input+ 8) ^\n                   LITTLE32(ctx->workCtx.x[4] ^ (ctx->workCtx.x[1]>>16) ^\n                   U32V(ctx->workCtx.x[7]<<16));\n        *(word32*)(output+12) = *(word32*)(input+12) ^\n                   LITTLE32(ctx->workCtx.x[6] ^ (ctx->workCtx.x[3]>>16) ^\n                   U32V(ctx->workCtx.x[1]<<16));\n\n        /* Increment pointers and decrement length */\n        input  += 16;\n        output += 16;\n        msglen -= 16;\n    }\n\n    /* Encrypt/decrypt remaining data */\n    if (msglen) {\n\n        word32 i;\n        word32 tmp[4];\n        byte*  buffer = (byte*)tmp;\n\n        XMEMSET(tmp, 0, sizeof(tmp));   /* help static analysis */\n\n        /* Iterate the system */\n        RABBIT_next_state(&(ctx->workCtx));\n\n        /* Generate 16 bytes of pseudo-random data */\n        tmp[0] = LITTLE32(ctx->workCtx.x[0] ^\n                  (ctx->workCtx.x[5]>>16) ^ U32V(ctx->workCtx.x[3]<<16));\n        tmp[1] = LITTLE32(ctx->workCtx.x[2] ^\n                  (ctx->workCtx.x[7]>>16) ^ U32V(ctx->workCtx.x[5]<<16));\n        tmp[2] = LITTLE32(ctx->workCtx.x[4] ^\n                  (ctx->workCtx.x[1]>>16) ^ U32V(ctx->workCtx.x[7]<<16));\n        tmp[3] = LITTLE32(ctx->workCtx.x[6] ^\n                  (ctx->workCtx.x[3]>>16) ^ U32V(ctx->workCtx.x[1]<<16));\n\n        /* Encrypt/decrypt the data */\n        for (i=0; i<msglen; i++)\n            output[i] = input[i] ^ buffer[i];\n    }\n\n    return 0;\n}\n\n\n/* Encrypt/decrypt a message of any size */\nint wc_RabbitProcess(Rabbit* ctx, byte* output, const byte* input, word32 msglen)\n{\n    if (ctx == NULL || output == NULL || input == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef XSTREAM_ALIGN\n    if ((wolfssl_word)input % 4 || (wolfssl_word)output % 4) {\n        #ifndef NO_WOLFSSL_ALLOC_ALIGN\n            byte* tmp;\n            WOLFSSL_MSG(\"wc_RabbitProcess unaligned\");\n\n            tmp = (byte*)XMALLOC(msglen, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);\n            if (tmp == NULL) return MEMORY_E;\n\n            XMEMCPY(tmp, input, msglen);\n            DoProcess(ctx, tmp, tmp, msglen);\n            XMEMCPY(output, tmp, msglen);\n\n            XFREE(tmp, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n            return 0;\n        #else\n            return BAD_ALIGN_E;\n        #endif\n    }\n#endif /* XSTREAM_ALIGN */\n\n    return DoProcess(ctx, output, input, msglen);\n}\n\n\n#endif /* NO_RABBIT */\n"
  },
  {
    "path": "src/wolfcrypt/src/random.c",
    "content": "/* random.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n\n/* on HPUX 11 you may need to install /dev/random see\n   http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I\n\n*/\n\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n\n    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */\n    #define FIPS_NO_WRAPPERS\n\n    #ifdef USE_WINDOWS_API\n        #pragma code_seg(\".fipsA$c\")\n        #pragma const_seg(\".fipsB$c\")\n    #endif\n#endif\n\n\n#include <wolfssl/wolfcrypt/random.h>\n#include <wolfssl/wolfcrypt/cpuid.h>\n\n\n/* If building for old FIPS. */\n#if defined(HAVE_FIPS) && \\\n    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n\nint wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz)\n{\n    return GenerateSeed(os, seed, sz);\n}\n\nint wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)\n{\n    (void)heap;\n    (void)devId;\n    return InitRng_fips(rng);\n}\n\nint wc_InitRng(WC_RNG* rng)\n{\n    return InitRng_fips(rng);\n}\n\n\nint wc_RNG_GenerateBlock(WC_RNG* rng, byte* b, word32 sz)\n{\n    return RNG_GenerateBlock_fips(rng, b, sz);\n}\n\n\nint wc_RNG_GenerateByte(WC_RNG* rng, byte* b)\n{\n    return RNG_GenerateByte(rng, b);\n}\n\n#ifdef HAVE_HASHDRBG\n\n    int wc_FreeRng(WC_RNG* rng)\n    {\n        return FreeRng_fips(rng);\n    }\n\n    int wc_RNG_HealthTest(int reseed, const byte* seedA, word32 seedASz,\n                                      const byte* seedB, word32 seedBSz,\n                                      byte* output, word32 outputSz)\n    {\n        return RNG_HealthTest_fips(reseed, seedA, seedASz,\n                              seedB, seedBSz, output, outputSz);\n   }\n#endif /* HAVE_HASHDRBG */\n\n#else /* else build without fips, or for new fips */\n\n#ifndef WC_NO_RNG /* if not FIPS and RNG is disabled then do not compile */\n\n#include <wolfssl/wolfcrypt/sha256.h>\n\n#ifdef WOLF_CRYPTO_CB\n    #include <wolfssl/wolfcrypt/cryptocb.h>\n#endif\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#if defined(WOLFSSL_SGX)\n    #include <sgx_trts.h>\n#elif defined(USE_WINDOWS_API)\n    #ifndef _WIN32_WINNT\n        #define _WIN32_WINNT 0x0400\n    #endif\n    #include <windows.h>\n    #include <wincrypt.h>\n#elif defined(HAVE_WNR)\n    #include <wnr.h>\n    #include <wolfssl/wolfcrypt/logging.h>\n    wolfSSL_Mutex wnr_mutex;    /* global netRandom mutex */\n    int wnr_timeout     = 0;    /* entropy timeout, mililseconds */\n    int wnr_mutex_init  = 0;    /* flag for mutex init */\n    wnr_context*  wnr_ctx;      /* global netRandom context */\n#elif defined(FREESCALE_KSDK_2_0_TRNG)\n    #include \"fsl_trng.h\"\n#elif defined(FREESCALE_KSDK_2_0_RNGA)\n    #include \"fsl_rnga.h\"\n#elif defined(WOLFSSL_WICED)\n    #include \"wiced_crypto.h\"\n#elif defined(WOLFSSL_NETBURNER)\n    #include <predef.h>\n    #include <basictypes.h>\n    #include <random.h>\n#elif defined(NO_DEV_RANDOM)\n#elif defined(CUSTOM_RAND_GENERATE)\n#elif defined(CUSTOM_RAND_GENERATE_BLOCK)\n#elif defined(CUSTOM_RAND_GENERATE_SEED)\n#elif defined(WOLFSSL_GENSEED_FORTEST)\n#elif defined(WOLFSSL_MDK_ARM)\n#elif defined(WOLFSSL_IAR_ARM)\n#elif defined(WOLFSSL_ROWLEY_ARM)\n#elif defined(WOLFSSL_EMBOS)\n#elif defined(WOLFSSL_DEOS)\n#elif defined(MICRIUM)\n#elif defined(WOLFSSL_NUCLEUS)\n#elif defined(WOLFSSL_PB)\n#elif defined(WOLFSSL_ZEPHYR)\n#elif defined(WOLFSSL_TELIT_M2MB)\n#else\n    /* include headers that may be needed to get good seed */\n    #include <fcntl.h>\n    #ifndef EBSNET\n        #include <unistd.h>\n    #endif\n#endif\n\n\n#if defined(HAVE_INTEL_RDRAND) || defined(HAVE_INTEL_RDSEED)\n    static word32 intel_flags = 0;\n    static void wc_InitRng_IntelRD(void)\n    {\n        intel_flags = cpuid_get_flags();\n    }\n    #ifdef HAVE_INTEL_RDSEED\n    static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz);\n    #endif\n    #ifdef HAVE_INTEL_RDRAND\n    static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz);\n    #endif\n\n#ifdef USE_WINDOWS_API\n    #include <immintrin.h>\n#endif /* USE_WINDOWS_API */\n#endif\n\n/* Start NIST DRBG code */\n#ifdef HAVE_HASHDRBG\n\n#define OUTPUT_BLOCK_LEN  (WC_SHA256_DIGEST_SIZE)\n#define MAX_REQUEST_LEN   (0x10000)\n#define RESEED_INTERVAL   WC_RESEED_INTERVAL\n\n\n/* For FIPS builds, the user should not be adjusting the values. */\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n    #if defined(RNG_SECURITY_STRENGTH) \\\n            || defined(ENTROPY_SCALE_FACTOR) \\\n            || defined(SEED_BLOCK_SZ)\n\n        #error \"Do not change the RNG parameters for FIPS builds.\"\n    #endif\n#endif\n\n\n/* The security strength for the RNG is the target number of bits of\n * entropy you are looking for in a seed. */\n#ifndef RNG_SECURITY_STRENGTH\n    #if defined(HAVE_FIPS) && \\\n        defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n        /* SHA-256 requires a minimum of 256-bits of entropy. The goal\n         * of 1024 will provide 4 times that. */\n        #define RNG_SECURITY_STRENGTH (1024)\n    #else\n        /* If not using FIPS or using old FIPS, set the number down a bit.\n         * More is better, but more is also slower. */\n        #define RNG_SECURITY_STRENGTH (256)\n    #endif\n#endif\n\n#ifndef ENTROPY_SCALE_FACTOR\n    /* The entropy scale factor should be the whole number inverse of the\n     * minimum bits of entropy per bit of NDRNG output. */\n    #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)\n        /* The value of 2 applies to Intel's RDSEED which provides about\n         * 0.5 bits minimum of entropy per bit. */\n        #define ENTROPY_SCALE_FACTOR 2\n    #else\n        /* Setting the default to 1. */\n        #define ENTROPY_SCALE_FACTOR 1\n    #endif\n#endif\n\n#ifndef SEED_BLOCK_SZ\n    /* The seed block size, is the size of the output of the underlying NDRNG.\n     * This value is used for testing the output of the NDRNG. */\n    #if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)\n        /* RDSEED outputs in blocks of 64-bits. */\n        #define SEED_BLOCK_SZ sizeof(word64)\n    #else\n        /* Setting the default to 4. */\n        #define SEED_BLOCK_SZ 4\n    #endif\n#endif\n\n#define SEED_SZ        (RNG_SECURITY_STRENGTH*ENTROPY_SCALE_FACTOR/8)\n\n/* The maximum seed size will be the seed size plus a seed block for the\n * test, and an additional half of the seed size. This additional half\n * is in case the user does not supply a nonce. A nonce will be obtained\n * from the NDRNG. */\n#define MAX_SEED_SZ    (SEED_SZ + SEED_SZ/2 + SEED_BLOCK_SZ)\n\n\n/* Internal return codes */\n#define DRBG_SUCCESS      0\n#define DRBG_FAILURE      1\n#define DRBG_NEED_RESEED  2\n#define DRBG_CONT_FAILURE 3\n\n/* RNG health states */\n#define DRBG_NOT_INIT     0\n#define DRBG_OK           1\n#define DRBG_FAILED       2\n#define DRBG_CONT_FAILED  3\n\n#define RNG_HEALTH_TEST_CHECK_SIZE (WC_SHA256_DIGEST_SIZE * 4)\n\n/* Verify max gen block len */\n#if RNG_MAX_BLOCK_LEN > MAX_REQUEST_LEN\n    #error RNG_MAX_BLOCK_LEN is larger than NIST DBRG max request length\n#endif\n\nenum {\n    drbgInitC     = 0,\n    drbgReseed    = 1,\n    drbgGenerateW = 2,\n    drbgGenerateH = 3,\n    drbgInitV\n};\n\n/* NOTE: if DRBG struct is changed please update random.h drbg_data size */\ntypedef struct DRBG {\n    word32 reseedCtr;\n    word32 lastBlock;\n    byte V[DRBG_SEED_LEN];\n    byte C[DRBG_SEED_LEN];\n#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)\n    void* heap;\n    int devId;\n#endif\n    byte   matchCount;\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    wc_Sha256 sha256;\n#endif\n} DRBG;\n\n\nstatic int wc_RNG_HealthTestLocal(int reseed);\n\n/* Hash Derivation Function */\n/* Returns: DRBG_SUCCESS or DRBG_FAILURE */\nstatic int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type,\n                                                  const byte* inA, word32 inASz,\n                                                  const byte* inB, word32 inBSz)\n{\n    int ret = DRBG_FAILURE;\n    byte ctr;\n    int i;\n    int len;\n    word32 bits = (outSz * 8); /* reverse byte order */\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    wc_Sha256* sha = &drbg->sha256;\n#else\n    wc_Sha256 sha[1];\n#endif\n#ifdef WC_ASYNC_ENABLE_SHA256\n    DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);\n    if (digest == NULL)\n        return MEMORY_E;\n#else\n    byte digest[WC_SHA256_DIGEST_SIZE];\n#endif\n\n    (void)drbg;\n#ifdef WC_ASYNC_ENABLE_SHA256\n    if (digest == NULL)\n        return DRBG_FAILURE;\n#endif\n\n#ifdef LITTLE_ENDIAN_ORDER\n    bits = ByteReverseWord32(bits);\n#endif\n    len = (outSz / OUTPUT_BLOCK_LEN)\n        + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);\n\n    for (i = 0, ctr = 1; i < len; i++, ctr++) {\n#ifndef WOLFSSL_SMALL_STACK_CACHE\n    #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)\n        ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);\n    #else\n        ret = wc_InitSha256(sha);\n    #endif\n        if (ret != 0)\n            break;\n\n        if (ret == 0)\n#endif\n            ret = wc_Sha256Update(sha, &ctr, sizeof(ctr));\n        if (ret == 0)\n            ret = wc_Sha256Update(sha, (byte*)&bits, sizeof(bits));\n\n        if (ret == 0) {\n            /* churning V is the only string that doesn't have the type added */\n            if (type != drbgInitV)\n                ret = wc_Sha256Update(sha, &type, sizeof(type));\n        }\n        if (ret == 0)\n            ret = wc_Sha256Update(sha, inA, inASz);\n        if (ret == 0) {\n            if (inB != NULL && inBSz > 0)\n                ret = wc_Sha256Update(sha, inB, inBSz);\n        }\n        if (ret == 0)\n            ret = wc_Sha256Final(sha, digest);\n\n#ifndef WOLFSSL_SMALL_STACK_CACHE\n        wc_Sha256Free(sha);\n#endif\n        if (ret == 0) {\n            if (outSz > OUTPUT_BLOCK_LEN) {\n                XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);\n                outSz -= OUTPUT_BLOCK_LEN;\n                out += OUTPUT_BLOCK_LEN;\n            }\n            else {\n                XMEMCPY(out, digest, outSz);\n            }\n        }\n    }\n\n    ForceZero(digest, WC_SHA256_DIGEST_SIZE);\n\n#ifdef WC_ASYNC_ENABLE_SHA256\n    FREE_VAR(digest, drbg->heap);\n#endif\n\n    return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;\n}\n\n/* Returns: DRBG_SUCCESS or DRBG_FAILURE */\nstatic int Hash_DRBG_Reseed(DRBG* drbg, const byte* seed, word32 seedSz)\n{\n    byte newV[DRBG_SEED_LEN];\n\n    XMEMSET(newV, 0, DRBG_SEED_LEN);\n\n    if (Hash_df(drbg, newV, sizeof(newV), drbgReseed,\n                drbg->V, sizeof(drbg->V), seed, seedSz) != DRBG_SUCCESS) {\n        return DRBG_FAILURE;\n    }\n\n    XMEMCPY(drbg->V, newV, sizeof(drbg->V));\n    ForceZero(newV, sizeof(newV));\n\n    if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,\n                                    sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) {\n        return DRBG_FAILURE;\n    }\n\n    drbg->reseedCtr = 1;\n    drbg->lastBlock = 0;\n    drbg->matchCount = 0;\n    return DRBG_SUCCESS;\n}\n\n/* Returns: DRBG_SUCCESS and DRBG_FAILURE or BAD_FUNC_ARG on fail */\nint wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* seed, word32 seedSz)\n{\n    if (rng == NULL || seed == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    return Hash_DRBG_Reseed(rng->drbg, seed, seedSz);\n}\n\nstatic WC_INLINE void array_add_one(byte* data, word32 dataSz)\n{\n    int i;\n\n    for (i = dataSz - 1; i >= 0; i--)\n    {\n        data[i]++;\n        if (data[i] != 0) break;\n    }\n}\n\n/* Returns: DRBG_SUCCESS or DRBG_FAILURE */\nstatic int Hash_gen(DRBG* drbg, byte* out, word32 outSz, const byte* V)\n{\n    int ret = DRBG_FAILURE;\n    byte data[DRBG_SEED_LEN];\n    int i;\n    int len;\n    word32 checkBlock;\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    wc_Sha256* sha = &drbg->sha256;\n#else\n    wc_Sha256 sha[1];\n#endif\n#ifdef WC_ASYNC_ENABLE_SHA256\n    DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);\n    if (digest == NULL)\n        return MEMORY_E;\n#else\n    byte digest[WC_SHA256_DIGEST_SIZE];\n#endif\n\n    /* Special case: outSz is 0 and out is NULL. wc_Generate a block to save for\n     * the continuous test. */\n\n    if (outSz == 0) outSz = 1;\n\n    len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);\n\n    XMEMCPY(data, V, sizeof(data));\n    for (i = 0; i < len; i++) {\n#ifndef WOLFSSL_SMALL_STACK_CACHE\n    #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)\n        ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);\n    #else\n        ret = wc_InitSha256(sha);\n    #endif\n        if (ret == 0)\n#endif\n            ret = wc_Sha256Update(sha, data, sizeof(data));\n        if (ret == 0)\n            ret = wc_Sha256Final(sha, digest);\n#ifndef WOLFSSL_SMALL_STACK_CACHE\n        wc_Sha256Free(sha);\n#endif\n\n        if (ret == 0) {\n            XMEMCPY(&checkBlock, digest, sizeof(word32));\n            if (drbg->reseedCtr > 1 && checkBlock == drbg->lastBlock) {\n                if (drbg->matchCount == 1) {\n                    return DRBG_CONT_FAILURE;\n                }\n                else {\n                    if (i == len) {\n                        len++;\n                    }\n                    drbg->matchCount = 1;\n                }\n            }\n            else {\n                drbg->matchCount = 0;\n                drbg->lastBlock = checkBlock;\n            }\n\n            if (out != NULL && outSz != 0) {\n                if (outSz >= OUTPUT_BLOCK_LEN) {\n                    XMEMCPY(out, digest, OUTPUT_BLOCK_LEN);\n                    outSz -= OUTPUT_BLOCK_LEN;\n                    out += OUTPUT_BLOCK_LEN;\n                    array_add_one(data, DRBG_SEED_LEN);\n                }\n                else {\n                    XMEMCPY(out, digest, outSz);\n                    outSz = 0;\n                }\n            }\n        }\n    }\n    ForceZero(data, sizeof(data));\n\n#ifdef WC_ASYNC_ENABLE_SHA256\n    FREE_VAR(digest, drbg->heap);\n#endif\n\n    return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;\n}\n\nstatic WC_INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)\n{\n    word16 carry = 0;\n\n    if (dLen > 0 && sLen > 0 && dLen >= sLen) {\n        int sIdx, dIdx;\n\n        for (sIdx = sLen - 1, dIdx = dLen - 1; sIdx >= 0; dIdx--, sIdx--)\n        {\n            carry += d[dIdx] + s[sIdx];\n            d[dIdx] = (byte)carry;\n            carry >>= 8;\n        }\n\n        for (; carry != 0 && dIdx >= 0; dIdx--) {\n            carry += d[dIdx];\n            d[dIdx] = (byte)carry;\n            carry >>= 8;\n        }\n    }\n}\n\n/* Returns: DRBG_SUCCESS, DRBG_NEED_RESEED, or DRBG_FAILURE */\nstatic int Hash_DRBG_Generate(DRBG* drbg, byte* out, word32 outSz)\n{\n    int ret;\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    wc_Sha256* sha = &drbg->sha256;\n#else\n    wc_Sha256 sha[1];\n#endif\n    byte type;\n    word32 reseedCtr;\n\n    if (drbg->reseedCtr == RESEED_INTERVAL) {\n        return DRBG_NEED_RESEED;\n    } else {\n    #ifdef WC_ASYNC_ENABLE_SHA256\n        DECLARE_VAR(digest, byte, WC_SHA256_DIGEST_SIZE, drbg->heap);\n        if (digest == NULL)\n            return MEMORY_E;\n    #else\n        byte digest[WC_SHA256_DIGEST_SIZE];\n    #endif\n        type = drbgGenerateH;\n        reseedCtr = drbg->reseedCtr;\n\n        ret = Hash_gen(drbg, out, outSz, drbg->V);\n        if (ret == DRBG_SUCCESS) {\n#ifndef WOLFSSL_SMALL_STACK_CACHE\n        #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)\n            ret = wc_InitSha256_ex(sha, drbg->heap, drbg->devId);\n        #else\n            ret = wc_InitSha256(sha);\n        #endif\n            if (ret == 0)\n#endif\n                ret = wc_Sha256Update(sha, &type, sizeof(type));\n            if (ret == 0)\n                ret = wc_Sha256Update(sha, drbg->V, sizeof(drbg->V));\n            if (ret == 0)\n                ret = wc_Sha256Final(sha, digest);\n\n#ifndef WOLFSSL_SMALL_STACK_CACHE\n            wc_Sha256Free(sha);\n#endif\n\n            if (ret == 0) {\n                array_add(drbg->V, sizeof(drbg->V), digest, WC_SHA256_DIGEST_SIZE);\n                array_add(drbg->V, sizeof(drbg->V), drbg->C, sizeof(drbg->C));\n            #ifdef LITTLE_ENDIAN_ORDER\n                reseedCtr = ByteReverseWord32(reseedCtr);\n            #endif\n                array_add(drbg->V, sizeof(drbg->V),\n                                          (byte*)&reseedCtr, sizeof(reseedCtr));\n                ret = DRBG_SUCCESS;\n            }\n            drbg->reseedCtr++;\n        }\n        ForceZero(digest, WC_SHA256_DIGEST_SIZE);\n    #ifdef WC_ASYNC_ENABLE_SHA256\n        FREE_VAR(digest, drbg->heap);\n    #endif\n    }\n\n    return (ret == 0) ? DRBG_SUCCESS : DRBG_FAILURE;\n}\n\n/* Returns: DRBG_SUCCESS or DRBG_FAILURE */\nstatic int Hash_DRBG_Instantiate(DRBG* drbg, const byte* seed, word32 seedSz,\n                                             const byte* nonce, word32 nonceSz,\n                                             void* heap, int devId)\n{\n    int ret = DRBG_FAILURE;\n\n    XMEMSET(drbg, 0, sizeof(DRBG));\n#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)\n    drbg->heap = heap;\n    drbg->devId = devId;\n#else\n    (void)heap;\n    (void)devId;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)\n        ret = wc_InitSha256_ex(&drbg->sha256, drbg->heap, drbg->devId);\n    #else\n        ret = wc_InitSha256(&drbg->sha256);\n    #endif\n    if (ret != 0)\n        return ret;\n#endif\n\n    if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz,\n                                              nonce, nonceSz) == DRBG_SUCCESS &&\n        Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,\n                                    sizeof(drbg->V), NULL, 0) == DRBG_SUCCESS) {\n\n        drbg->reseedCtr = 1;\n        drbg->lastBlock = 0;\n        drbg->matchCount = 0;\n        ret = DRBG_SUCCESS;\n    }\n\n    return ret;\n}\n\n/* Returns: DRBG_SUCCESS or DRBG_FAILURE */\nstatic int Hash_DRBG_Uninstantiate(DRBG* drbg)\n{\n    word32 i;\n    int    compareSum = 0;\n    byte*  compareDrbg = (byte*)drbg;\n\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    wc_Sha256Free(&drbg->sha256);\n#endif\n\n    ForceZero(drbg, sizeof(DRBG));\n\n    for (i = 0; i < sizeof(DRBG); i++)\n        compareSum |= compareDrbg[i] ^ 0;\n\n    return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE;\n}\n\n\nint wc_RNG_TestSeed(const byte* seed, word32 seedSz)\n{\n    int ret = DRBG_SUCCESS;\n\n    /* Check the seed for duplicate words. */\n    word32 seedIdx = 0;\n    word32 scratchSz = min(SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ);\n\n    while (seedIdx < seedSz - SEED_BLOCK_SZ) {\n        if (ConstantCompare(seed + seedIdx,\n                            seed + seedIdx + scratchSz,\n                            scratchSz) == 0) {\n\n            ret = DRBG_CONT_FAILURE;\n        }\n        seedIdx += SEED_BLOCK_SZ;\n        scratchSz = min(SEED_BLOCK_SZ, (seedSz - seedIdx));\n    }\n\n    return ret;\n}\n#endif /* HAVE_HASHDRBG */\n/* End NIST DRBG Code */\n\n\nstatic int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,\n                    void* heap, int devId)\n{\n    int ret = RNG_FAILURE_E;\n#ifdef HAVE_HASHDRBG\n    word32 seedSz = SEED_SZ + SEED_BLOCK_SZ;\n#endif\n\n    (void)nonce;\n    (void)nonceSz;\n\n    if (rng == NULL)\n        return BAD_FUNC_ARG;\n    if (nonce == NULL && nonceSz != 0)\n        return BAD_FUNC_ARG;\n\n#ifdef WOLFSSL_HEAP_TEST\n    rng->heap = (void*)WOLFSSL_HEAP_TEST;\n    (void)heap;\n#else\n    rng->heap = heap;\n#endif\n#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)\n    rng->devId = devId;\n    #if defined(WOLF_CRYPTO_CB)\n        rng->seed.devId = devId;\n    #endif\n#else\n    (void)devId;\n#endif\n\n#ifdef HAVE_HASHDRBG\n    /* init the DBRG to known values */\n    rng->drbg = NULL;\n    rng->status = DRBG_NOT_INIT;\n#endif\n\n#if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)\n    /* init the intel RD seed and/or rand */\n    wc_InitRng_IntelRD();\n#endif\n\n    /* configure async RNG source if available */\n#ifdef WOLFSSL_ASYNC_CRYPT\n    ret = wolfAsync_DevCtxInit(&rng->asyncDev, WOLFSSL_ASYNC_MARKER_RNG,\n                                                        rng->heap, rng->devId);\n    if (ret != 0)\n        return ret;\n#endif\n\n#ifdef HAVE_INTEL_RDRAND\n    /* if CPU supports RDRAND, use it directly and by-pass DRBG init */\n    if (IS_INTEL_RDRAND(intel_flags))\n        return 0;\n#endif\n\n#ifdef CUSTOM_RAND_GENERATE_BLOCK\n    ret = 0; /* success */\n#else\n#ifdef HAVE_HASHDRBG\n    if (nonceSz == 0)\n        seedSz = MAX_SEED_SZ;\n\n    if (wc_RNG_HealthTestLocal(0) == 0) {\n    #ifdef WC_ASYNC_ENABLE_SHA256\n        DECLARE_VAR(seed, byte, MAX_SEED_SZ, rng->heap);\n        if (seed == NULL)\n            return MEMORY_E;\n    #else\n        byte seed[MAX_SEED_SZ];\n    #endif\n\n#if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)\n        rng->drbg =\n                (struct DRBG*)XMALLOC(sizeof(DRBG), rng->heap,\n                                                          DYNAMIC_TYPE_RNG);\n#else\n        /* compile-time validation of drbg_data size */\n        typedef char drbg_data_test[sizeof(rng->drbg_data) >=\n                sizeof(struct DRBG) ? 1 : -1];\n        (void)sizeof(drbg_data_test);\n        rng->drbg = (struct DRBG*)rng->drbg_data;\n#endif\n\n        if (rng->drbg == NULL) {\n            ret = MEMORY_E;\n        }\n        else {\n            ret = wc_GenerateSeed(&rng->seed, seed, seedSz);\n            if (ret != 0)\n                ret = DRBG_FAILURE;\n            else\n                ret = wc_RNG_TestSeed(seed, seedSz);\n\n            if (ret == DRBG_SUCCESS)\n                 ret = Hash_DRBG_Instantiate(rng->drbg,\n                            seed + SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ,\n                            nonce, nonceSz, rng->heap, devId);\n\n            if (ret != DRBG_SUCCESS) {\n            #if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)\n                XFREE(rng->drbg, rng->heap, DYNAMIC_TYPE_RNG);\n            #endif\n                rng->drbg = NULL;\n            }\n        }\n\n        ForceZero(seed, seedSz);\n    #ifdef WC_ASYNC_ENABLE_SHA256\n        FREE_VAR(seed, rng->heap);\n    #endif\n    }\n    else\n        ret = DRBG_CONT_FAILURE;\n\n    if (ret == DRBG_SUCCESS) {\n        rng->status = DRBG_OK;\n        ret = 0;\n    }\n    else if (ret == DRBG_CONT_FAILURE) {\n        rng->status = DRBG_CONT_FAILED;\n        ret = DRBG_CONT_FIPS_E;\n    }\n    else if (ret == DRBG_FAILURE) {\n        rng->status = DRBG_FAILED;\n        ret = RNG_FAILURE_E;\n    }\n    else {\n        rng->status = DRBG_FAILED;\n    }\n#endif /* HAVE_HASHDRBG */\n#endif /* CUSTOM_RAND_GENERATE_BLOCK */\n\n    return ret;\n}\n\n\nWOLFSSL_ABI\nWC_RNG* wc_rng_new(byte* nonce, word32 nonceSz, void* heap)\n{\n    WC_RNG* rng;\n\n    rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), heap, DYNAMIC_TYPE_RNG);\n    if (rng) {\n        int error = _InitRng(rng, nonce, nonceSz, heap, INVALID_DEVID) != 0;\n        if (error) {\n            XFREE(rng, heap, DYNAMIC_TYPE_RNG);\n            rng = NULL;\n        }\n    }\n\n    return rng;\n}\n\n\nWOLFSSL_ABI\nvoid wc_rng_free(WC_RNG* rng)\n{\n    if (rng) {\n        void* heap = rng->heap;\n\n        wc_FreeRng(rng);\n        ForceZero(rng, sizeof(WC_RNG));\n        XFREE(rng, heap, DYNAMIC_TYPE_RNG);\n        (void)heap;\n    }\n}\n\n\nint wc_InitRng(WC_RNG* rng)\n{\n    return _InitRng(rng, NULL, 0, NULL, INVALID_DEVID);\n}\n\n\nint wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)\n{\n    return _InitRng(rng, NULL, 0, heap, devId);\n}\n\n\nint wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz)\n{\n    return _InitRng(rng, nonce, nonceSz, NULL, INVALID_DEVID);\n}\n\n\nint wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz,\n                       void* heap, int devId)\n{\n    return _InitRng(rng, nonce, nonceSz, heap, devId);\n}\n\n\n/* place a generated block in output */\nint wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz)\n{\n    int ret;\n\n    if (rng == NULL || output == NULL)\n        return BAD_FUNC_ARG;\n\n#ifdef WOLF_CRYPTO_CB\n    if (rng->devId != INVALID_DEVID) {\n        ret = wc_CryptoCb_RandomBlock(rng, output, sz);\n        if (ret != CRYPTOCB_UNAVAILABLE)\n            return ret;\n        /* fall-through when unavailable */\n    }\n#endif\n\n#ifdef HAVE_INTEL_RDRAND\n    if (IS_INTEL_RDRAND(intel_flags))\n        return wc_GenerateRand_IntelRD(NULL, output, sz);\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT)\n    if (rng->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RNG) {\n        /* these are blocking */\n    #ifdef HAVE_CAVIUM\n        return NitroxRngGenerateBlock(rng, output, sz);\n    #elif defined(HAVE_INTEL_QA) && defined(QAT_ENABLE_RNG)\n        return IntelQaDrbg(&rng->asyncDev, output, sz);\n    #else\n        /* simulator not supported */\n    #endif\n    }\n#endif\n\n#ifdef CUSTOM_RAND_GENERATE_BLOCK\n    XMEMSET(output, 0, sz);\n    ret = CUSTOM_RAND_GENERATE_BLOCK(output, sz);\n#else\n\n#ifdef HAVE_HASHDRBG\n    if (sz > RNG_MAX_BLOCK_LEN)\n        return BAD_FUNC_ARG;\n\n    if (rng->status != DRBG_OK)\n        return RNG_FAILURE_E;\n\n    ret = Hash_DRBG_Generate(rng->drbg, output, sz);\n    if (ret == DRBG_NEED_RESEED) {\n        if (wc_RNG_HealthTestLocal(1) == 0) {\n            byte newSeed[SEED_SZ + SEED_BLOCK_SZ];\n\n            ret = wc_GenerateSeed(&rng->seed, newSeed,\n                                  SEED_SZ + SEED_BLOCK_SZ);\n            if (ret != 0)\n                ret = DRBG_FAILURE;\n            else\n                ret = wc_RNG_TestSeed(newSeed, SEED_SZ + SEED_BLOCK_SZ);\n\n            if (ret == DRBG_SUCCESS)\n                ret = Hash_DRBG_Reseed(rng->drbg, newSeed + SEED_BLOCK_SZ,\n                                       SEED_SZ);\n            if (ret == DRBG_SUCCESS)\n                ret = Hash_DRBG_Generate(rng->drbg, output, sz);\n\n            ForceZero(newSeed, sizeof(newSeed));\n        }\n        else\n            ret = DRBG_CONT_FAILURE;\n    }\n\n    if (ret == DRBG_SUCCESS) {\n        ret = 0;\n    }\n    else if (ret == DRBG_CONT_FAILURE) {\n        ret = DRBG_CONT_FIPS_E;\n        rng->status = DRBG_CONT_FAILED;\n    }\n    else {\n        ret = RNG_FAILURE_E;\n        rng->status = DRBG_FAILED;\n    }\n#else\n\n    /* if we get here then there is an RNG configuration error */\n    ret = RNG_FAILURE_E;\n\n#endif /* HAVE_HASHDRBG */\n#endif /* CUSTOM_RAND_GENERATE_BLOCK */\n\n    return ret;\n}\n\n\nint wc_RNG_GenerateByte(WC_RNG* rng, byte* b)\n{\n    return wc_RNG_GenerateBlock(rng, b, 1);\n}\n\n\nint wc_FreeRng(WC_RNG* rng)\n{\n    int ret = 0;\n\n    if (rng == NULL)\n        return BAD_FUNC_ARG;\n\n#if defined(WOLFSSL_ASYNC_CRYPT)\n    wolfAsync_DevCtxFree(&rng->asyncDev, WOLFSSL_ASYNC_MARKER_RNG);\n#endif\n\n#ifdef HAVE_HASHDRBG\n    if (rng->drbg != NULL) {\n        if (Hash_DRBG_Uninstantiate(rng->drbg) != DRBG_SUCCESS)\n            ret = RNG_FAILURE_E;\n\n    #if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)\n        XFREE(rng->drbg, rng->heap, DYNAMIC_TYPE_RNG);\n    #endif\n        rng->drbg = NULL;\n    }\n\n    rng->status = DRBG_NOT_INIT;\n#endif /* HAVE_HASHDRBG */\n\n    return ret;\n}\n\n#ifdef HAVE_HASHDRBG\nint wc_RNG_HealthTest(int reseed, const byte* seedA, word32 seedASz,\n                                  const byte* seedB, word32 seedBSz,\n                                  byte* output, word32 outputSz)\n{\n    return wc_RNG_HealthTest_ex(reseed, NULL, 0,\n                                seedA, seedASz, seedB, seedBSz,\n                                output, outputSz,\n                                NULL, INVALID_DEVID);\n}\n\n\nint wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz,\n                                  const byte* seedA, word32 seedASz,\n                                  const byte* seedB, word32 seedBSz,\n                                  byte* output, word32 outputSz,\n                                  void* heap, int devId)\n{\n    int ret = -1;\n    DRBG* drbg;\n#ifndef WOLFSSL_SMALL_STACK\n    DRBG  drbg_var;\n#endif\n\n    if (seedA == NULL || output == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (reseed != 0 && seedB == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (outputSz != RNG_HEALTH_TEST_CHECK_SIZE) {\n        return ret;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    drbg = (DRBG*)XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);\n    if (drbg == NULL) {\n        return MEMORY_E;\n    }\n#else\n    drbg = &drbg_var;\n#endif\n\n    if (Hash_DRBG_Instantiate(drbg, seedA, seedASz, nonce, nonceSz,\n                              heap, devId) != 0) {\n        goto exit_rng_ht;\n    }\n\n    if (reseed) {\n        if (Hash_DRBG_Reseed(drbg, seedB, seedBSz) != 0) {\n            goto exit_rng_ht;\n        }\n    }\n\n    /* This call to generate is prescribed by the NIST DRBGVS\n     * procedure. The results are thrown away. The known\n     * answer test checks the second block of DRBG out of\n     * the generator to ensure the internal state is updated\n     * as expected. */\n    if (Hash_DRBG_Generate(drbg, output, outputSz) != 0) {\n        goto exit_rng_ht;\n    }\n\n    if (Hash_DRBG_Generate(drbg, output, outputSz) != 0) {\n        goto exit_rng_ht;\n    }\n\n    /* Mark success */\n    ret = 0;\n\nexit_rng_ht:\n\n    /* This is safe to call even if Hash_DRBG_Instantiate fails */\n    if (Hash_DRBG_Uninstantiate(drbg) != 0) {\n        ret = -1;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(drbg, NULL, DYNAMIC_TYPE_RNG);\n#endif\n\n    return ret;\n}\n\n\nconst byte seedA[] = {\n    0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4,\n    0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00,\n    0x45, 0x4e, 0x81, 0xe9, 0x53, 0x58, 0xa5, 0x69, 0x80, 0x8a, 0xa3, 0x8f,\n    0x2a, 0x72, 0xa6, 0x23, 0x59, 0x91, 0x5a, 0x9f, 0x8a, 0x04, 0xca, 0x68\n};\n\nconst byte reseedSeedA[] = {\n    0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3,\n    0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22,\n    0x80, 0x01, 0x0a, 0x67, 0x39, 0xbc, 0x83, 0xd3\n};\n\nconst byte outputA[] = {\n    0x04, 0xee, 0xc6, 0x3b, 0xb2, 0x31, 0xdf, 0x2c, 0x63, 0x0a, 0x1a, 0xfb,\n    0xe7, 0x24, 0x94, 0x9d, 0x00, 0x5a, 0x58, 0x78, 0x51, 0xe1, 0xaa, 0x79,\n    0x5e, 0x47, 0x73, 0x47, 0xc8, 0xb0, 0x56, 0x62, 0x1c, 0x18, 0xbd, 0xdc,\n    0xdd, 0x8d, 0x99, 0xfc, 0x5f, 0xc2, 0xb9, 0x20, 0x53, 0xd8, 0xcf, 0xac,\n    0xfb, 0x0b, 0xb8, 0x83, 0x12, 0x05, 0xfa, 0xd1, 0xdd, 0xd6, 0xc0, 0x71,\n    0x31, 0x8a, 0x60, 0x18, 0xf0, 0x3b, 0x73, 0xf5, 0xed, 0xe4, 0xd4, 0xd0,\n    0x71, 0xf9, 0xde, 0x03, 0xfd, 0x7a, 0xea, 0x10, 0x5d, 0x92, 0x99, 0xb8,\n    0xaf, 0x99, 0xaa, 0x07, 0x5b, 0xdb, 0x4d, 0xb9, 0xaa, 0x28, 0xc1, 0x8d,\n    0x17, 0x4b, 0x56, 0xee, 0x2a, 0x01, 0x4d, 0x09, 0x88, 0x96, 0xff, 0x22,\n    0x82, 0xc9, 0x55, 0xa8, 0x19, 0x69, 0xe0, 0x69, 0xfa, 0x8c, 0xe0, 0x07,\n    0xa1, 0x80, 0x18, 0x3a, 0x07, 0xdf, 0xae, 0x17\n};\n\nconst byte seedB[] = {\n    0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3,\n    0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19,\n    0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, /* nonce next */\n    0x85, 0x81, 0xf9, 0x31, 0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d,\n    0xdb, 0xcb, 0xcc, 0x2e\n};\n\nconst byte outputB[] = {\n    0xd3, 0xe1, 0x60, 0xc3, 0x5b, 0x99, 0xf3, 0x40, 0xb2, 0x62, 0x82, 0x64,\n    0xd1, 0x75, 0x10, 0x60, 0xe0, 0x04, 0x5d, 0xa3, 0x83, 0xff, 0x57, 0xa5,\n    0x7d, 0x73, 0xa6, 0x73, 0xd2, 0xb8, 0xd8, 0x0d, 0xaa, 0xf6, 0xa6, 0xc3,\n    0x5a, 0x91, 0xbb, 0x45, 0x79, 0xd7, 0x3f, 0xd0, 0xc8, 0xfe, 0xd1, 0x11,\n    0xb0, 0x39, 0x13, 0x06, 0x82, 0x8a, 0xdf, 0xed, 0x52, 0x8f, 0x01, 0x81,\n    0x21, 0xb3, 0xfe, 0xbd, 0xc3, 0x43, 0xe7, 0x97, 0xb8, 0x7d, 0xbb, 0x63,\n    0xdb, 0x13, 0x33, 0xde, 0xd9, 0xd1, 0xec, 0xe1, 0x77, 0xcf, 0xa6, 0xb7,\n    0x1f, 0xe8, 0xab, 0x1d, 0xa4, 0x66, 0x24, 0xed, 0x64, 0x15, 0xe5, 0x1c,\n    0xcd, 0xe2, 0xc7, 0xca, 0x86, 0xe2, 0x83, 0x99, 0x0e, 0xea, 0xeb, 0x91,\n    0x12, 0x04, 0x15, 0x52, 0x8b, 0x22, 0x95, 0x91, 0x02, 0x81, 0xb0, 0x2d,\n    0xd4, 0x31, 0xf4, 0xc9, 0xf7, 0x04, 0x27, 0xdf\n};\n\n\nstatic int wc_RNG_HealthTestLocal(int reseed)\n{\n    int ret = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    byte* check;\n#else\n    byte  check[RNG_HEALTH_TEST_CHECK_SIZE];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    check = (byte*)XMALLOC(RNG_HEALTH_TEST_CHECK_SIZE, NULL,\n                           DYNAMIC_TYPE_TMP_BUFFER);\n    if (check == NULL) {\n        return MEMORY_E;\n    }\n#endif\n\n    if (reseed) {\n        ret = wc_RNG_HealthTest(1, seedA, sizeof(seedA),\n                                reseedSeedA, sizeof(reseedSeedA),\n                                check, RNG_HEALTH_TEST_CHECK_SIZE);\n        if (ret == 0) {\n            if (ConstantCompare(check, outputA,\n                                RNG_HEALTH_TEST_CHECK_SIZE) != 0)\n                ret = -1;\n        }\n    }\n    else {\n        ret = wc_RNG_HealthTest(0, seedB, sizeof(seedB),\n                                NULL, 0,\n                                check, RNG_HEALTH_TEST_CHECK_SIZE);\n        if (ret == 0) {\n            if (ConstantCompare(check, outputB,\n                                RNG_HEALTH_TEST_CHECK_SIZE) != 0)\n                ret = -1;\n        }\n\n        /* The previous test cases use a large seed instead of a seed and nonce.\n         * seedB is actually from a test case with a seed and nonce, and\n         * just concatenates them. The pivot point between seed and nonce is\n         * byte 32, feed them into the health test separately. */\n        if (ret == 0) {\n            ret = wc_RNG_HealthTest_ex(0,\n                                    seedB + 32, sizeof(seedB) - 32,\n                                    seedB, 32,\n                                    NULL, 0,\n                                    check, RNG_HEALTH_TEST_CHECK_SIZE,\n                                    NULL, INVALID_DEVID);\n            if (ret == 0) {\n                if (ConstantCompare(check, outputB, sizeof(outputB)) != 0)\n                    ret = -1;\n            }\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(check, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n#endif /* HAVE_HASHDRBG */\n\n\n#ifdef HAVE_WNR\n\n/*\n * Init global Whitewood netRandom context\n * Returns 0 on success, negative on error\n */\nint wc_InitNetRandom(const char* configFile, wnr_hmac_key hmac_cb, int timeout)\n{\n    if (configFile == NULL || timeout < 0)\n        return BAD_FUNC_ARG;\n\n    if (wnr_mutex_init > 0) {\n        WOLFSSL_MSG(\"netRandom context already created, skipping\");\n        return 0;\n    }\n\n    if (wc_InitMutex(&wnr_mutex) != 0) {\n        WOLFSSL_MSG(\"Bad Init Mutex wnr_mutex\");\n        return BAD_MUTEX_E;\n    }\n    wnr_mutex_init = 1;\n\n    if (wc_LockMutex(&wnr_mutex) != 0) {\n        WOLFSSL_MSG(\"Bad Lock Mutex wnr_mutex\");\n        return BAD_MUTEX_E;\n    }\n\n    /* store entropy timeout */\n    wnr_timeout = timeout;\n\n    /* create global wnr_context struct */\n    if (wnr_create(&wnr_ctx) != WNR_ERROR_NONE) {\n        WOLFSSL_MSG(\"Error creating global netRandom context\");\n        return RNG_FAILURE_E;\n    }\n\n    /* load config file */\n    if (wnr_config_loadf(wnr_ctx, (char*)configFile) != WNR_ERROR_NONE) {\n        WOLFSSL_MSG(\"Error loading config file into netRandom context\");\n        wnr_destroy(wnr_ctx);\n        wnr_ctx = NULL;\n        return RNG_FAILURE_E;\n    }\n\n    /* create/init polling mechanism */\n    if (wnr_poll_create() != WNR_ERROR_NONE) {\n        printf(\"ERROR: wnr_poll_create() failed\\n\");\n        WOLFSSL_MSG(\"Error initializing netRandom polling mechanism\");\n        wnr_destroy(wnr_ctx);\n        wnr_ctx = NULL;\n        return RNG_FAILURE_E;\n    }\n\n    /* validate config, set HMAC callback (optional) */\n    if (wnr_setup(wnr_ctx, hmac_cb) != WNR_ERROR_NONE) {\n        WOLFSSL_MSG(\"Error setting up netRandom context\");\n        wnr_destroy(wnr_ctx);\n        wnr_ctx = NULL;\n        wnr_poll_destroy();\n        return RNG_FAILURE_E;\n    }\n\n    wc_UnLockMutex(&wnr_mutex);\n\n    return 0;\n}\n\n/*\n * Free global Whitewood netRandom context\n * Returns 0 on success, negative on error\n */\nint wc_FreeNetRandom(void)\n{\n    if (wnr_mutex_init > 0) {\n\n        if (wc_LockMutex(&wnr_mutex) != 0) {\n            WOLFSSL_MSG(\"Bad Lock Mutex wnr_mutex\");\n            return BAD_MUTEX_E;\n        }\n\n        if (wnr_ctx != NULL) {\n            wnr_destroy(wnr_ctx);\n            wnr_ctx = NULL;\n        }\n        wnr_poll_destroy();\n\n        wc_UnLockMutex(&wnr_mutex);\n\n        wc_FreeMutex(&wnr_mutex);\n        wnr_mutex_init = 0;\n    }\n\n    return 0;\n}\n\n#endif /* HAVE_WNR */\n\n\n#if defined(HAVE_INTEL_RDRAND) || defined(HAVE_INTEL_RDSEED)\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    /* need more retries if multiple cores */\n    #define INTELRD_RETRY (32 * 8)\n#else\n    #define INTELRD_RETRY 32\n#endif\n\n#ifdef HAVE_INTEL_RDSEED\n\n#ifndef USE_WINDOWS_API\n\n    /* return 0 on success */\n    static WC_INLINE int IntelRDseed64(word64* seed)\n    {\n        unsigned char ok;\n\n        __asm__ volatile(\"rdseed %0; setc %1\":\"=r\"(*seed), \"=qm\"(ok));\n        return (ok) ? 0 : -1;\n    }\n\n#else /* USE_WINDOWS_API */\n    /* The compiler Visual Studio uses does not allow inline assembly.\n     * It does allow for Intel intrinsic functions. */\n\n    /* return 0 on success */\n    static WC_INLINE int IntelRDseed64(word64* seed)\n    {\n        int ok;\n\n        ok = _rdseed64_step(seed);\n        return (ok) ? 0 : -1;\n    }\n\n#endif /* USE_WINDOWS_API */\n\n/* return 0 on success */\nstatic WC_INLINE int IntelRDseed64_r(word64* rnd)\n{\n    int i;\n    for (i = 0; i < INTELRD_RETRY; i++) {\n        if (IntelRDseed64(rnd) == 0)\n            return 0;\n    }\n    return -1;\n}\n\n/* return 0 on success */\nstatic int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz)\n{\n    int ret;\n    word64 rndTmp;\n\n    (void)os;\n\n    if (!IS_INTEL_RDSEED(intel_flags))\n        return -1;\n\n    for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64),\n                                                    output += sizeof(word64)) {\n        ret = IntelRDseed64_r((word64*)output);\n        if (ret != 0)\n            return ret;\n    }\n    if (sz == 0)\n        return 0;\n\n    /* handle unaligned remainder */\n    ret = IntelRDseed64_r(&rndTmp);\n    if (ret != 0)\n        return ret;\n\n    XMEMCPY(output, &rndTmp, sz);\n    ForceZero(&rndTmp, sizeof(rndTmp));\n\n    return 0;\n}\n\n#endif /* HAVE_INTEL_RDSEED */\n\n#ifdef HAVE_INTEL_RDRAND\n\n#ifndef USE_WINDOWS_API\n\n/* return 0 on success */\nstatic WC_INLINE int IntelRDrand64(word64 *rnd)\n{\n    unsigned char ok;\n\n    __asm__ volatile(\"rdrand %0; setc %1\":\"=r\"(*rnd), \"=qm\"(ok));\n\n    return (ok) ? 0 : -1;\n}\n\n#else /* USE_WINDOWS_API */\n    /* The compiler Visual Studio uses does not allow inline assembly.\n     * It does allow for Intel intrinsic functions. */\n\n/* return 0 on success */\nstatic WC_INLINE int IntelRDrand64(word64 *rnd)\n{\n    int ok;\n\n    ok = _rdrand64_step(rnd);\n\n    return (ok) ? 0 : -1;\n}\n\n#endif /* USE_WINDOWS_API */\n\n/* return 0 on success */\nstatic WC_INLINE int IntelRDrand64_r(word64 *rnd)\n{\n    int i;\n    for (i = 0; i < INTELRD_RETRY; i++) {\n        if (IntelRDrand64(rnd) == 0)\n            return 0;\n    }\n    return -1;\n}\n\n/* return 0 on success */\nstatic int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz)\n{\n    int ret;\n    word64 rndTmp;\n\n    (void)os;\n\n    if (!IS_INTEL_RDRAND(intel_flags))\n        return -1;\n\n    for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64),\n                                                    output += sizeof(word64)) {\n        ret = IntelRDrand64_r((word64 *)output);\n        if (ret != 0)\n            return ret;\n    }\n    if (sz == 0)\n        return 0;\n\n    /* handle unaligned remainder */\n    ret = IntelRDrand64_r(&rndTmp);\n    if (ret != 0)\n        return ret;\n\n    XMEMCPY(output, &rndTmp, sz);\n\n    return 0;\n}\n\n#endif /* HAVE_INTEL_RDRAND */\n#endif /* HAVE_INTEL_RDRAND || HAVE_INTEL_RDSEED */\n\n\n/* Begin wc_GenerateSeed Implementations */\n#if defined(CUSTOM_RAND_GENERATE_SEED)\n\n    /* Implement your own random generation function\n     * Return 0 to indicate success\n     * int rand_gen_seed(byte* output, word32 sz);\n     * #define CUSTOM_RAND_GENERATE_SEED  rand_gen_seed */\n\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        (void)os; /* Suppress unused arg warning */\n        return CUSTOM_RAND_GENERATE_SEED(output, sz);\n    }\n\n#elif defined(CUSTOM_RAND_GENERATE_SEED_OS)\n\n    /* Implement your own random generation function,\n     *  which includes OS_Seed.\n     * Return 0 to indicate success\n     * int rand_gen_seed(OS_Seed* os, byte* output, word32 sz);\n     * #define CUSTOM_RAND_GENERATE_SEED_OS  rand_gen_seed */\n\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        return CUSTOM_RAND_GENERATE_SEED_OS(os, output, sz);\n    }\n\n#elif defined(CUSTOM_RAND_GENERATE)\n\n   /* Implement your own random generation function\n    * word32 rand_gen(void);\n    * #define CUSTOM_RAND_GENERATE  rand_gen  */\n\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        word32 i = 0;\n\n        (void)os;\n\n        while (i < sz)\n        {\n            /* If not aligned or there is odd/remainder */\n            if( (i + sizeof(CUSTOM_RAND_TYPE)) > sz ||\n                ((wolfssl_word)&output[i] % sizeof(CUSTOM_RAND_TYPE)) != 0\n            ) {\n                /* Single byte at a time */\n                output[i++] = (byte)CUSTOM_RAND_GENERATE();\n            }\n            else {\n                /* Use native 8, 16, 32 or 64 copy instruction */\n                *((CUSTOM_RAND_TYPE*)&output[i]) = CUSTOM_RAND_GENERATE();\n                i += sizeof(CUSTOM_RAND_TYPE);\n            }\n        }\n\n        return 0;\n    }\n\n#elif defined(WOLFSSL_SGX)\n\nint wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n{\n    int ret = !SGX_SUCCESS;\n\tint i, read_max = 10;\n\n\tfor (i = 0; i < read_max && ret != SGX_SUCCESS; i++) {\n\t\tret = sgx_read_rand(output, sz);\n\t}\n\n\t(void)os;\n\treturn (ret == SGX_SUCCESS) ? 0 : 1;\n}\n\n#elif defined(USE_WINDOWS_API)\n\nint wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n{\n#ifdef WOLF_CRYPTO_CB\n    int ret;\n\n    if (os != NULL && os->devId != INVALID_DEVID) {\n        ret = wc_CryptoCb_RandomSeed(os, output, sz);\n        if (ret != CRYPTOCB_UNAVAILABLE)\n            return ret;\n        /* fall-through when unavailable */\n    }\n#endif\n\n    #ifdef HAVE_INTEL_RDSEED\n        if (IS_INTEL_RDSEED(intel_flags)) {\n             if (!wc_GenerateSeed_IntelRD(NULL, output, sz)) {\n                 /* success, we're done */\n                 return 0;\n             }\n        #ifdef FORCE_FAILURE_RDSEED\n             /* don't fall back to CryptoAPI */\n             return READ_RAN_E;\n        #endif\n        }\n    #endif /* HAVE_INTEL_RDSEED */\n\n    if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,\n                            CRYPT_VERIFYCONTEXT))\n        return WINCRYPT_E;\n\n    if (!CryptGenRandom(os->handle, sz, output))\n        return CRYPTGEN_E;\n\n    CryptReleaseContext(os->handle, 0);\n\n    return 0;\n}\n\n\n#elif defined(HAVE_RTP_SYS) || defined(EBSNET)\n\n#include \"rtprand.h\"   /* rtp_rand () */\n#include \"rtptime.h\"   /* rtp_get_system_msec() */\n\nint wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n{\n    word32 i;\n\n    rtp_srand(rtp_get_system_msec());\n    for (i = 0; i < sz; i++ ) {\n        output[i] = rtp_rand() % 256;\n    }\n\n    return 0;\n}\n\n\n#elif defined(MICROCHIP_PIC32)\n\n    #ifdef MICROCHIP_MPLAB_HARMONY\n        #ifdef MICROCHIP_MPLAB_HARMONY_3\n            #include \"system/time/sys_time.h\"\n            #define PIC32_SEED_COUNT SYS_TIME_CounterGet\n        #else\n            #define PIC32_SEED_COUNT _CP0_GET_COUNT\n        #endif\n    #else\n        #if !defined(WOLFSSL_MICROCHIP_PIC32MZ)\n            #include <peripheral/timer.h>\n        #endif\n        extern word32 ReadCoreTimer(void);\n        #define PIC32_SEED_COUNT ReadCoreTimer\n    #endif\n\n    #ifdef WOLFSSL_PIC32MZ_RNG\n        #include \"xc.h\"\n        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n        {\n            int i;\n            byte rnd[8];\n            word32 *rnd32 = (word32 *)rnd;\n            word32 size = sz;\n            byte* op = output;\n\n#if ((__PIC32_FEATURE_SET0 == 'E') && (__PIC32_FEATURE_SET1 == 'C'))\n            RNGNUMGEN1 = _CP0_GET_COUNT();\n            RNGPOLY1 = _CP0_GET_COUNT();\n            RNGPOLY2 = _CP0_GET_COUNT();\n            RNGNUMGEN2 = _CP0_GET_COUNT();\n#else\n            // All others can be seeded from the TRNG\n            RNGCONbits.TRNGMODE = 1;\n            RNGCONbits.TRNGEN = 1;\n            while (RNGCNT < 64);\n            RNGCONbits.LOAD = 1;\n            while (RNGCONbits.LOAD == 1);\n            while (RNGCNT < 64);\n            RNGPOLY2 = RNGSEED2;\n            RNGPOLY1 = RNGSEED1;\n#endif\n\n            RNGCONbits.PLEN = 0x40;\n            RNGCONbits.PRNGEN = 1;\n            for (i=0; i<5; i++) { /* wait for RNGNUMGEN ready */\n                volatile int x;\n                x = RNGNUMGEN1;\n                x = RNGNUMGEN2;\n                (void)x;\n            }\n            do {\n                rnd32[0] = RNGNUMGEN1;\n                rnd32[1] = RNGNUMGEN2;\n\n                for(i=0; i<8; i++, op++) {\n                    *op = rnd[i];\n                    size --;\n                    if(size==0)break;\n                }\n            } while(size);\n            return 0;\n        }\n    #else  /* WOLFSSL_PIC32MZ_RNG */\n        /* uses the core timer, in nanoseconds to seed srand */\n        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n        {\n            int i;\n            srand(PIC32_SEED_COUNT() * 25);\n\n            for (i = 0; i < sz; i++ ) {\n                output[i] = rand() % 256;\n                if ( (i % 8) == 7)\n                    srand(PIC32_SEED_COUNT() * 25);\n            }\n            return 0;\n        }\n    #endif /* WOLFSSL_PIC32MZ_RNG */\n\n#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) || \\\n      defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS)\n\n    #if defined(FREESCALE_K70_RNGA) || defined(FREESCALE_RNGA)\n        /*\n         * wc_Generates a RNG seed using the Random Number Generator Accelerator\n         * on the Kinetis K70. Documentation located in Chapter 37 of\n         * K70 Sub-Family Reference Manual (see Note 3 in the README for link).\n         */\n        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n        {\n            word32 i;\n\n            /* turn on RNGA module */\n            #if defined(SIM_SCGC3_RNGA_MASK)\n                SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK;\n            #endif\n            #if defined(SIM_SCGC6_RNGA_MASK)\n                /* additionally needed for at least K64F */\n                SIM_SCGC6 |= SIM_SCGC6_RNGA_MASK;\n            #endif\n\n            /* set SLP bit to 0 - \"RNGA is not in sleep mode\" */\n            RNG_CR &= ~RNG_CR_SLP_MASK;\n\n            /* set HA bit to 1 - \"security violations masked\" */\n            RNG_CR |= RNG_CR_HA_MASK;\n\n            /* set GO bit to 1 - \"output register loaded with data\" */\n            RNG_CR |= RNG_CR_GO_MASK;\n\n            for (i = 0; i < sz; i++) {\n\n                /* wait for RNG FIFO to be full */\n                while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {}\n\n                /* get value */\n                output[i] = RNG_OR;\n            }\n\n            return 0;\n        }\n\n    #elif defined(FREESCALE_K53_RNGB) || defined(FREESCALE_RNGB)\n        /*\n         * wc_Generates a RNG seed using the Random Number Generator (RNGB)\n         * on the Kinetis K53. Documentation located in Chapter 33 of\n         * K53 Sub-Family Reference Manual (see note in the README for link).\n         */\n        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n        {\n            int i;\n\n            /* turn on RNGB module */\n            SIM_SCGC3 |= SIM_SCGC3_RNGB_MASK;\n\n            /* reset RNGB */\n            RNG_CMD |= RNG_CMD_SR_MASK;\n\n            /* FIFO generate interrupt, return all zeros on underflow,\n             * set auto reseed */\n            RNG_CR |= (RNG_CR_FUFMOD_MASK | RNG_CR_AR_MASK);\n\n            /* gen seed, clear interrupts, clear errors */\n            RNG_CMD |= (RNG_CMD_GS_MASK | RNG_CMD_CI_MASK | RNG_CMD_CE_MASK);\n\n            /* wait for seeding to complete */\n            while ((RNG_SR & RNG_SR_SDN_MASK) == 0) {}\n\n            for (i = 0; i < sz; i++) {\n\n                /* wait for a word to be available from FIFO */\n                while((RNG_SR & RNG_SR_FIFO_LVL_MASK) == 0) {}\n\n                /* get value */\n                output[i] = RNG_OUT;\n            }\n\n            return 0;\n        }\n\n    #elif defined(FREESCALE_KSDK_2_0_TRNG)\n\n        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n        {\n            status_t status;\n            status = TRNG_GetRandomData(TRNG0, output, sz);\n            if (status == kStatus_Success)\n            {\n                return(0);\n            }\n            else\n            {\n                return RAN_BLOCK_E;\n            }\n        }\n\n    #elif defined(FREESCALE_KSDK_2_0_RNGA)\n\n        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n        {\n            status_t status;\n            status = RNGA_GetRandomData(RNG, output, sz);\n            if (status == kStatus_Success)\n            {\n                return(0);\n            }\n            else\n            {\n                return RAN_BLOCK_E;\n            }\n        }\n\n\n    #elif defined(FREESCALE_RNGA)\n\n        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n        {\n            RNGA_DRV_GetRandomData(RNGA_INSTANCE, output, sz);\n            return 0;\n        }\n\n    #else\n        #define USE_TEST_GENSEED\n    #endif /* FREESCALE_K70_RNGA */\n\n#elif defined(STM32_RNG)\n     /* Generate a RNG seed using the hardware random number generator\n      * on the STM32F2/F4/F7/L4. */\n\n    #ifdef WOLFSSL_STM32_CUBEMX\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        int ret;\n        RNG_HandleTypeDef hrng;\n        word32 i = 0;\n        (void)os;\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret != 0) {\n            return ret;\n        }\n\n        /* enable RNG clock source */\n        __HAL_RCC_RNG_CLK_ENABLE();\n\n        /* enable RNG peripheral */\n        XMEMSET(&hrng, 0, sizeof(hrng));\n        hrng.Instance = RNG;\n        HAL_RNG_Init(&hrng);\n\n        while (i < sz) {\n            /* If not aligned or there is odd/remainder */\n            if( (i + sizeof(word32)) > sz ||\n                ((wolfssl_word)&output[i] % sizeof(word32)) != 0\n            ) {\n                /* Single byte at a time */\n                uint32_t tmpRng = 0;\n                if (HAL_RNG_GenerateRandomNumber(&hrng, &tmpRng) != HAL_OK) {\n                    wolfSSL_CryptHwMutexUnLock();\n                    return RAN_BLOCK_E;\n                }\n                output[i++] = (byte)tmpRng;\n            }\n            else {\n                /* Use native 32 instruction */\n                if (HAL_RNG_GenerateRandomNumber(&hrng, (uint32_t*)&output[i]) != HAL_OK) {\n                    wolfSSL_CryptHwMutexUnLock();\n                    return RAN_BLOCK_E;\n                }\n                i += sizeof(word32);\n            }\n        }\n\n        wolfSSL_CryptHwMutexUnLock();\n\n        return 0;\n    }\n    #elif defined(WOLFSSL_STM32F427_RNG) || defined(WOLFSSL_STM32_RNG_NOLIB)\n\n    /* Generate a RNG seed using the hardware RNG on the STM32F427\n     * directly, following steps outlined in STM32F4 Reference\n     * Manual (Chapter 24) for STM32F4xx family. */\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        int ret;\n        word32 i;\n        (void)os;\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret != 0) {\n            return ret;\n        }\n\n        /* enable RNG peripheral clock */\n        RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN;\n\n        /* enable RNG interrupt, set IE bit in RNG->CR register */\n        RNG->CR |= RNG_CR_IE;\n\n        /* enable RNG, set RNGEN bit in RNG->CR. Activates RNG,\n         * RNG_LFSR, and error detector */\n        RNG->CR |= RNG_CR_RNGEN;\n\n        /* verify no errors, make sure SEIS and CEIS bits are 0\n         * in RNG->SR register */\n        if (RNG->SR & (RNG_SR_SECS | RNG_SR_CECS)) {\n            wolfSSL_CryptHwMutexUnLock();\n            return RNG_FAILURE_E;\n        }\n\n        for (i = 0; i < sz; i++) {\n            /* wait until RNG number is ready */\n            while ((RNG->SR & RNG_SR_DRDY) == 0) { }\n\n            /* get value */\n            output[i] = RNG->DR;\n        }\n\n        wolfSSL_CryptHwMutexUnLock();\n\n        return 0;\n    }\n\n    #else\n\n    /* Generate a RNG seed using the STM32 Standard Peripheral Library */\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        int ret;\n        word32 i;\n        (void)os;\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret != 0) {\n            return ret;\n        }\n\n        /* enable RNG clock source */\n        RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);\n\n        /* reset RNG */\n        RNG_DeInit();\n\n        /* enable RNG peripheral */\n        RNG_Cmd(ENABLE);\n\n        /* verify no errors with RNG_CLK or Seed */\n        if (RNG_GetFlagStatus(RNG_FLAG_SECS | RNG_FLAG_CECS) != RESET) {\n            wolfSSL_CryptHwMutexUnLock();\n            return RNG_FAILURE_E;\n        }\n\n        for (i = 0; i < sz; i++) {\n            /* wait until RNG number is ready */\n            while (RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET) { }\n\n            /* get value */\n            output[i] = RNG_GetRandomNumber();\n        }\n\n        wolfSSL_CryptHwMutexUnLock();\n\n        return 0;\n    }\n    #endif /* WOLFSSL_STM32_CUBEMX */\n\n#elif defined(WOLFSSL_TIRTOS)\n\n    #include <xdc/runtime/Timestamp.h>\n    #include <stdlib.h>\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        int i;\n        srand(xdc_runtime_Timestamp_get32());\n\n        for (i = 0; i < sz; i++ ) {\n            output[i] = rand() % 256;\n            if ((i % 8) == 7) {\n                srand(xdc_runtime_Timestamp_get32());\n            }\n        }\n\n        return 0;\n    }\n\n#elif defined(WOLFSSL_PB)\n\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        word32 i;\n        for (i = 0; i < sz; i++)\n            output[i] = UTL_Rand();\n\n        (void)os;\n\n        return 0;\n    }\n\n#elif defined(WOLFSSL_NUCLEUS)\n#include \"nucleus.h\"\n#include \"kernel/plus_common.h\"\n\n#warning \"potential for not enough entropy, currently being used for testing\"\nint wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n{\n    int i;\n    srand(NU_Get_Time_Stamp());\n\n    for (i = 0; i < sz; i++ ) {\n        output[i] = rand() % 256;\n        if ((i % 8) == 7) {\n            srand(NU_Get_Time_Stamp());\n        }\n    }\n\n    return 0;\n}\n#elif defined(WOLFSSL_DEOS) && !defined(CUSTOM_RAND_GENERATE)\n    #include \"stdlib.h\"\n\n    #warning \"potential for not enough entropy, currently being used for testing Deos\"\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        int i;\n        int seed = XTIME(0);\n        (void)os;\n\n        for (i = 0; i < sz; i++ ) {\n            output[i] = rand_r(&seed) % 256;\n            if ((i % 8) == 7) {\n                seed = XTIME(0);\n                rand_r(&seed);\n            }\n        }\n\n        return 0;\n    }\n#elif defined(WOLFSSL_VXWORKS)\n\n    #include <randomNumGen.h>\n\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) {\n        STATUS        status;\n\n        #ifdef VXWORKS_SIM\n            /* cannot generate true entropy with VxWorks simulator */\n            #warning \"not enough entropy, simulator for testing only\"\n            int i = 0;\n\n            for (i = 0; i < 1000; i++) {\n                randomAddTimeStamp();\n            }\n        #endif\n\n        status = randBytes (output, sz);\n        if (status == ERROR) {\n            return RNG_FAILURE_E;\n        }\n\n        return 0;\n    }\n\n#elif defined(WOLFSSL_NRF51)\n    #include \"app_error.h\"\n    #include \"nrf_drv_rng.h\"\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        int remaining = sz, length, pos = 0;\n        uint8_t available;\n        uint32_t err_code;\n\n        (void)os;\n\n        /* Make sure RNG is running */\n        err_code = nrf_drv_rng_init(NULL);\n        if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE) {\n            return -1;\n        }\n\n        while (remaining > 0) {\n            err_code = nrf_drv_rng_bytes_available(&available);\n            if (err_code == NRF_SUCCESS) {\n                length = (remaining < available) ? remaining : available;\n                if (length > 0) {\n                    err_code = nrf_drv_rng_rand(&output[pos], length);\n                    remaining -= length;\n                    pos += length;\n                }\n            }\n\n            if (err_code != NRF_SUCCESS) {\n                break;\n            }\n        }\n\n        return (err_code == NRF_SUCCESS) ? 0 : -1;\n    }\n\n#elif defined(HAVE_WNR)\n\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        if (os == NULL || output == NULL || wnr_ctx == NULL ||\n                wnr_timeout < 0) {\n            return BAD_FUNC_ARG;\n        }\n\n        if (wnr_mutex_init == 0) {\n            WOLFSSL_MSG(\"netRandom context must be created before use\");\n            return RNG_FAILURE_E;\n        }\n\n        if (wc_LockMutex(&wnr_mutex) != 0) {\n            WOLFSSL_MSG(\"Bad Lock Mutex wnr_mutex\\n\");\n            return BAD_MUTEX_E;\n        }\n\n        if (wnr_get_entropy(wnr_ctx, wnr_timeout, output, sz, sz) !=\n                WNR_ERROR_NONE)\n            return RNG_FAILURE_E;\n\n        wc_UnLockMutex(&wnr_mutex);\n\n        return 0;\n    }\n\n#elif defined(WOLFSSL_ATMEL)\n    #include <wolfssl/wolfcrypt/port/atmel/atmel.h>\n\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        int ret = 0;\n\n        (void)os;\n        if (output == NULL) {\n            return BUFFER_E;\n        }\n\n        ret = atmel_get_random_number(sz, output);\n\n        return ret;\n    }\n\n#elif defined(INTIME_RTOS)\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        int ret = 0;\n\n        (void)os;\n\n        if (output == NULL) {\n            return BUFFER_E;\n        }\n\n        /* Note: Investigate better solution */\n        /* no return to check */\n        arc4random_buf(output, sz);\n\n        return ret;\n    }\n\n#elif defined(WOLFSSL_WICED)\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        int ret;\n        (void)os;\n\n        if (output == NULL || UINT16_MAX < sz) {\n            return BUFFER_E;\n        }\n\n        if ((ret = wiced_crypto_get_random((void*) output, sz) )\n                         != WICED_SUCCESS) {\n            return ret;\n        }\n\n        return ret;\n    }\n\n#elif defined(WOLFSSL_NETBURNER)\n    #warning using NetBurner pseudo random GetRandomByte for seed\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        word32 i;\n        (void)os;\n\n        if (output == NULL) {\n            return BUFFER_E;\n        }\n\n        for (i = 0; i < sz; i++) {\n            output[i] = GetRandomByte();\n\n            /* check if was a valid random number */\n            if (!RandomValid())\n                return RNG_FAILURE_E;\n        }\n\n        return 0;\n    }\n#elif defined(IDIRECT_DEV_RANDOM)\n\n    extern int getRandom( int sz, unsigned char *output );\n\n    int GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        int num_bytes_returned = 0;\n\n        num_bytes_returned = getRandom( (int) sz, (unsigned char *) output );\n\n        return 0;\n    }\n\n#elif (defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG))\n\n    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>\n    #include <wolfssl/wolfcrypt/port/caam/caam_driver.h>\n\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        Buffer buf[1];\n        int ret  = 0;\n        int times = 1000, i;\n\n        (void)os;\n\n        if (output == NULL) {\n            return BUFFER_E;\n        }\n\n        buf[0].BufferType = DataBuffer | LastBuffer;\n        buf[0].TheAddress = (Address)output;\n        buf[0].Length     = sz;\n\n        /* Check Waiting to make sure entropy is ready */\n        for (i = 0; i < times; i++) {\n            ret = wc_caamAddAndWait(buf, NULL, CAAM_ENTROPY);\n            if (ret == Success) {\n                break;\n            }\n\n            /* driver could be waiting for entropy */\n            if (ret != RAN_BLOCK_E) {\n                return ret;\n            }\n            usleep(100);\n        }\n\n        if (i == times && ret != Success) {\n             return RNG_FAILURE_E;\n        }\n        else { /* Success case */\n            ret = 0;\n        }\n\n        return ret;\n    }\n\n#elif defined(WOLFSSL_APACHE_MYNEWT)\n\n    #include <stdlib.h>\n    #include \"os/os_time.h\"\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        int i;\n        srand(os_time_get());\n\n        for (i = 0; i < sz; i++ ) {\n            output[i] = rand() % 256;\n            if ((i % 8) == 7) {\n                srand(os_time_get());\n            }\n        }\n\n        return 0;\n    }\n\n#elif defined(WOLFSSL_ESPIDF)\n    #if defined(WOLFSSL_ESPWROOM32) || defined(WOLFSSL_ESPWROOM32SE)\n        #include <esp_system.h>\n\n        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n        {\n            word32 rand;\n            while (sz > 0) {\n                word32 len = sizeof(rand);\n                if (sz < len)\n                    len = sz;\n                /* Get one random 32-bit word from hw RNG */\n                rand = esp_random( );\n                XMEMCPY(output, &rand, len);\n                output += len;\n                sz -= len;\n            }\n\n            return 0;\n        }\n    #endif /* end WOLFSSL_ESPWROOM32 */\n\n#elif defined(WOLFSSL_RENESAS_TSIP)\n#if defined(WOLFSSL_RENESA_TSIP_IAREWRX)\n    #include \"r_bsp/mcu/all/r_rx_compiler.h\"\n#endif\n    #include \"r_bsp/platform.h\"\n    #include \"r_tsip_rx_if.h\"\n    \n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        int ret;\n        uint32_t buffer[4];\n\n        while (sz > 0) {\n            uint32_t len = sizeof(buffer);\n            \n            if (sz < len) {\n                len = sz;\n            }\n            /* retun 4 words random number*/\n            ret = R_TSIP_GenerateRandomNumber(buffer);\n            if(ret == TSIP_SUCCESS) {\n                XMEMCPY(output, &buffer, len);\n                output += len;\n                sz -= len;\n            } else\n                return ret;\n        }\n        return ret;\n    }\n    \n    \n#elif defined(CUSTOM_RAND_GENERATE_BLOCK)\n    /* #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc\n     * extern int myRngFunc(byte* output, word32 sz);\n     */\n\n#elif defined(WOLFSSL_SAFERTOS) || defined(WOLFSSL_LEANPSK) || \\\n      defined(WOLFSSL_IAR_ARM)  || defined(WOLFSSL_MDK_ARM) || \\\n      defined(WOLFSSL_uITRON4)  || defined(WOLFSSL_uTKERNEL2) || \\\n      defined(WOLFSSL_LPC43xx)  || defined(WOLFSSL_STM32F2xx) || \\\n      defined(MBED)             || defined(WOLFSSL_EMBOS) || \\\n      defined(WOLFSSL_GENSEED_FORTEST) || defined(WOLFSSL_CHIBIOS) || \\\n      defined(WOLFSSL_CONTIKI)  || defined(WOLFSSL_AZSPHERE)\n\n    /* these platforms do not have a default random seed and\n       you'll need to implement your own wc_GenerateSeed or define via\n       CUSTOM_RAND_GENERATE_BLOCK */\n\n    #define USE_TEST_GENSEED\n\n#elif defined(WOLFSSL_ZEPHYR)\n\n        #include <entropy.h>\n    #ifndef _POSIX_C_SOURCE\n        #include <posix/time.h>\n    #else\n        #include <sys/time.h>\n    #endif\n\n        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n        {\n            int ret = 0;\n            word32 rand;\n            while (sz > 0) {\n                word32 len = sizeof(rand);\n                if (sz < len)\n                    len = sz;\n                rand = sys_rand32_get();\n                XMEMCPY(output, &rand, len);\n                output += len;\n                sz -= len;\n            }\n\n            return ret;\n        }\n\n#elif defined(WOLFSSL_TELIT_M2MB)\n\n        #include \"stdlib.h\"\n        static long get_timestamp(void) {\n            long myTime = 0;\n            INT32 fd = m2mb_rtc_open(\"/dev/rtc0\", 0);\n            if (fd >= 0) {\n                M2MB_RTC_TIMEVAL_T timeval;\n                m2mb_rtc_ioctl(fd, M2MB_RTC_IOCTL_GET_TIMEVAL, &timeval);\n                myTime = timeval.msec;\n                m2mb_rtc_close(fd);\n            }\n            return myTime;\n        }\n        int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n        {\n            int i;\n            srand(get_timestamp());\n            for (i = 0; i < sz; i++ ) {\n                output[i] = rand() % 256;\n                if ((i % 8) == 7) {\n                    srand(get_timestamp());\n                }\n            }\n            return 0;\n        }\n\n#elif defined(NO_DEV_RANDOM)\n\n    #error \"you need to write an os specific wc_GenerateSeed() here\"\n\n    /*\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        return 0;\n    }\n    */\n\n#else\n\n    /* may block */\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        int ret = 0;\n\n#ifdef WOLF_CRYPTO_CB\n    if (os != NULL && os->devId != INVALID_DEVID) {\n        ret = wc_CryptoCb_RandomSeed(os, output, sz);\n        if (ret != CRYPTOCB_UNAVAILABLE)\n            return ret;\n        /* fall-through when unavailable */\n        ret = 0; /* reset error code */\n    }\n#endif\n\n    #ifdef HAVE_INTEL_RDSEED\n        if (IS_INTEL_RDSEED(intel_flags)) {\n             ret = wc_GenerateSeed_IntelRD(NULL, output, sz);\n             if (ret == 0) {\n                 /* success, we're done */\n                 return ret;\n             }\n        #ifdef FORCE_FAILURE_RDSEED\n             /* don't fallback to /dev/urandom */\n             return ret;\n        #else\n             /* reset error and fallback to using /dev/urandom */\n             ret = 0;\n        #endif\n        }\n    #endif /* HAVE_INTEL_RDSEED */\n\n    #ifndef NO_DEV_URANDOM /* way to disable use of /dev/urandom */\n        os->fd = open(\"/dev/urandom\", O_RDONLY);\n        if (os->fd == -1)\n    #endif\n        {\n            /* may still have /dev/random */\n            os->fd = open(\"/dev/random\", O_RDONLY);\n            if (os->fd == -1)\n                return OPEN_RAN_E;\n        }\n\n        while (sz) {\n            int len = (int)read(os->fd, output, sz);\n            if (len == -1) {\n                ret = READ_RAN_E;\n                break;\n            }\n\n            sz     -= len;\n            output += len;\n\n            if (sz) {\n    #if defined(BLOCKING) || defined(WC_RNG_BLOCKING)\n                sleep(0);             /* context switch */\n    #else\n                ret = RAN_BLOCK_E;\n                break;\n    #endif\n            }\n        }\n        close(os->fd);\n\n        return ret;\n    }\n\n#endif\n\n#ifdef USE_TEST_GENSEED\n    #ifndef _MSC_VER\n        #warning \"write a real random seed!!!!, just for testing now\"\n    #else\n        #pragma message(\"Warning: write a real random seed!!!!, just for testing now\")\n    #endif\n    int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)\n    {\n        word32 i;\n        for (i = 0; i < sz; i++ )\n            output[i] = i;\n\n        (void)os;\n\n        return 0;\n    }\n#endif\n\n\n/* End wc_GenerateSeed */\n#endif /* WC_NO_RNG */\n#endif /* HAVE_FIPS */\n"
  },
  {
    "path": "src/wolfcrypt/src/ripemd.c",
    "content": "/* ripemd.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef WOLFSSL_RIPEMD\n\n#include <wolfssl/wolfcrypt/ripemd.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#include <wolfssl/wolfcrypt/error-crypt.h>\n\nint wc_InitRipeMd(RipeMd* ripemd)\n{\n    if (ripemd == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    ripemd->digest[0] = 0x67452301L;\n    ripemd->digest[1] = 0xEFCDAB89L;\n    ripemd->digest[2] = 0x98BADCFEL;\n    ripemd->digest[3] = 0x10325476L;\n    ripemd->digest[4] = 0xC3D2E1F0L;\n\n    ripemd->buffLen = 0;\n    ripemd->loLen   = 0;\n    ripemd->hiLen   = 0;\n\n    return 0;\n}\n\n\n/* for all */\n#define F(x, y, z)    (x ^ y ^ z)\n#define G(x, y, z)    (z ^ (x & (y^z)))\n#define H(x, y, z)    (z ^ (x | ~y))\n#define I(x, y, z)    (y ^ (z & (x^y)))\n#define J(x, y, z)    (x ^ (y | ~z))\n\n#define k0 0\n#define k1 0x5a827999\n#define k2 0x6ed9eba1\n#define k3 0x8f1bbcdc\n#define k4 0xa953fd4e\n#define k5 0x50a28be6\n#define k6 0x5c4dd124\n#define k7 0x6d703ef3\n#define k8 0x7a6d76e9\n#define k9 0\n\n/* for 160 and 320 */\n#define Subround(f, a, b, c, d, e, x, s, k) \\\n    a += f(b, c, d) + x + k;\\\n    a = rotlFixed((word32)a, s) + e;\\\n    c = rotlFixed((word32)c, 10U)\n\nstatic void Transform(RipeMd* ripemd)\n{\n    word32 a1, b1, c1, d1, e1, a2, b2, c2, d2, e2;\n    a1 = a2 = ripemd->digest[0];\n    b1 = b2 = ripemd->digest[1];\n    c1 = c2 = ripemd->digest[2];\n    d1 = d2 = ripemd->digest[3];\n    e1 = e2 = ripemd->digest[4];\n\n    Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 11, k0);\n    Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[ 1], 14, k0);\n    Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[ 2], 15, k0);\n    Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[ 3], 12, k0);\n    Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[ 4],  5, k0);\n    Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[ 5],  8, k0);\n    Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[ 6],  7, k0);\n    Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[ 7],  9, k0);\n    Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 11, k0);\n    Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[ 9], 13, k0);\n    Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[10], 14, k0);\n    Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[11], 15, k0);\n    Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[12],  6, k0);\n    Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[13],  7, k0);\n    Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[14],  9, k0);\n    Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[15],  8, k0);\n\n    Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 7],  7, k1);\n    Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[ 4],  6, k1);\n    Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[13],  8, k1);\n    Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[ 1], 13, k1);\n    Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[10], 11, k1);\n    Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 6],  9, k1);\n    Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[15],  7, k1);\n    Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[ 3], 15, k1);\n    Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[12],  7, k1);\n    Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 12, k1);\n    Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 9], 15, k1);\n    Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[ 5],  9, k1);\n    Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[ 2], 11, k1);\n    Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[14],  7, k1);\n    Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[11], 13, k1);\n    Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 8], 12, k1);\n\n    Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[ 3], 11, k2);\n    Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[10], 13, k2);\n    Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[14],  6, k2);\n    Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[ 4],  7, k2);\n    Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 9], 14, k2);\n    Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[15],  9, k2);\n    Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 13, k2);\n    Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[ 1], 15, k2);\n    Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[ 2], 14, k2);\n    Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 7],  8, k2);\n    Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[ 0], 13, k2);\n    Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[ 6],  6, k2);\n    Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[13],  5, k2);\n    Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[11], 12, k2);\n    Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 5],  7, k2);\n    Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[12],  5, k2);\n\n    Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 1], 11, k3);\n    Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[ 9], 12, k3);\n    Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[11], 14, k3);\n    Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[10], 15, k3);\n    Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 0], 14, k3);\n    Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 15, k3);\n    Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[12],  9, k3);\n    Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[ 4],  8, k3);\n    Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[13],  9, k3);\n    Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 3], 14, k3);\n    Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 7],  5, k3);\n    Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[15],  6, k3);\n    Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[14],  8, k3);\n    Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[ 5],  6, k3);\n    Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 6],  5, k3);\n    Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 2], 12, k3);\n\n    Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[ 4],  9, k4);\n    Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 15, k4);\n    Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[ 5],  5, k4);\n    Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[ 9], 11, k4);\n    Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[ 7],  6, k4);\n    Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[12],  8, k4);\n    Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 2], 13, k4);\n    Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[10], 12, k4);\n    Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[14],  5, k4);\n    Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[ 1], 12, k4);\n    Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[ 3], 13, k4);\n    Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 8], 14, k4);\n    Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[11], 11, k4);\n    Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[ 6],  8, k4);\n    Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[15],  5, k4);\n    Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[13],  6, k4);\n\n    Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[ 5],  8, k5);\n    Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[14],  9, k5);\n    Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 7],  9, k5);\n    Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[ 0], 11, k5);\n    Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 13, k5);\n    Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[ 2], 15, k5);\n    Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[11], 15, k5);\n    Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 4],  5, k5);\n    Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[13],  7, k5);\n    Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 6],  7, k5);\n    Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[15],  8, k5);\n    Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 11, k5);\n    Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 1], 14, k5);\n    Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[10], 14, k5);\n    Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 3], 12, k5);\n    Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[12],  6, k5);\n\n    Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 6],  9, k6);\n    Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[11], 13, k6);\n    Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[ 3], 15, k6);\n    Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[ 7],  7, k6);\n    Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 12, k6);\n    Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[13],  8, k6);\n    Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[ 5],  9, k6);\n    Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[10], 11, k6);\n    Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[14],  7, k6);\n    Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[15],  7, k6);\n    Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 12, k6);\n    Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[12],  7, k6);\n    Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[ 4],  6, k6);\n    Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 15, k6);\n    Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[ 1], 13, k6);\n    Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 2], 11, k6);\n\n    Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[15],  9, k7);\n    Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 5],  7, k7);\n    Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[ 1], 15, k7);\n    Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[ 3], 11, k7);\n    Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 7],  8, k7);\n    Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[14],  6, k7);\n    Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 6],  6, k7);\n    Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 14, k7);\n    Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[11], 12, k7);\n    Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 13, k7);\n    Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[12],  5, k7);\n    Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 14, k7);\n    Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[10], 13, k7);\n    Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 13, k7);\n    Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 4],  7, k7);\n    Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[13],  5, k7);\n\n    Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[ 8], 15, k8);\n    Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[ 6],  5, k8);\n    Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 4],  8, k8);\n    Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 1], 11, k8);\n    Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[ 3], 14, k8);\n    Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[11], 14, k8);\n    Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[15],  6, k8);\n    Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 14, k8);\n    Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 5],  6, k8);\n    Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[12],  9, k8);\n    Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 12, k8);\n    Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[13],  9, k8);\n    Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 9], 12, k8);\n    Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 7],  5, k8);\n    Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[10], 15, k8);\n    Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[14],  8, k8);\n\n    Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[12],  8, k9);\n    Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[15],  5, k9);\n    Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[10], 12, k9);\n    Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 4],  9, k9);\n    Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 1], 12, k9);\n    Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[ 5],  5, k9);\n    Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[ 8], 14, k9);\n    Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[ 7],  6, k9);\n    Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 6],  8, k9);\n    Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 13, k9);\n    Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[13],  6, k9);\n    Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[14],  5, k9);\n    Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[ 0], 15, k9);\n    Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 3], 13, k9);\n    Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 9], 11, k9);\n    Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[11], 11, k9);\n\n    c1                = ripemd->digest[1] + c1 + d2;\n    ripemd->digest[1] = ripemd->digest[2] + d1 + e2;\n    ripemd->digest[2] = ripemd->digest[3] + e1 + a2;\n    ripemd->digest[3] = ripemd->digest[4] + a1 + b2;\n    ripemd->digest[4] = ripemd->digest[0] + b1 + c2;\n    ripemd->digest[0] = c1;\n}\n\n\nstatic WC_INLINE void AddLength(RipeMd* ripemd, word32 len)\n{\n    word32 tmp = ripemd->loLen;\n    if ( (ripemd->loLen += len) < tmp)\n        ripemd->hiLen++;                       /* carry low to high */\n}\n\n\nint wc_RipeMdUpdate(RipeMd* ripemd, const byte* data, word32 len)\n{\n    /* do block size increments */\n    byte* local;\n\n    if (ripemd == NULL || (data == NULL && len > 0)) {\n        return BAD_FUNC_ARG;\n    }\n\n    local = (byte*)ripemd->buffer;\n\n    while (len) {\n        word32 add = min(len, RIPEMD_BLOCK_SIZE - ripemd->buffLen);\n        XMEMCPY(&local[ripemd->buffLen], data, add);\n\n        ripemd->buffLen += add;\n        data         += add;\n        len          -= add;\n\n        if (ripemd->buffLen == RIPEMD_BLOCK_SIZE) {\n            #ifdef BIG_ENDIAN_ORDER\n                ByteReverseWords(ripemd->buffer, ripemd->buffer,\n                                 RIPEMD_BLOCK_SIZE);\n            #endif\n            Transform(ripemd);\n            AddLength(ripemd, RIPEMD_BLOCK_SIZE);\n            ripemd->buffLen = 0;\n        }\n    }\n    return 0;\n}\n\n\nint wc_RipeMdFinal(RipeMd* ripemd, byte* hash)\n{\n    byte* local;\n\n    if (ripemd == NULL || hash == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    local = (byte*)ripemd->buffer;\n\n    AddLength(ripemd, ripemd->buffLen);               /* before adding pads */\n\n    local[ripemd->buffLen++] = 0x80;  /* add 1 */\n\n    /* pad with zeros */\n    if (ripemd->buffLen > RIPEMD_PAD_SIZE) {\n        XMEMSET(&local[ripemd->buffLen], 0, RIPEMD_BLOCK_SIZE - ripemd->buffLen);\n        ripemd->buffLen += RIPEMD_BLOCK_SIZE - ripemd->buffLen;\n\n        #ifdef BIG_ENDIAN_ORDER\n            ByteReverseWords(ripemd->buffer, ripemd->buffer, RIPEMD_BLOCK_SIZE);\n        #endif\n        Transform(ripemd);\n        ripemd->buffLen = 0;\n    }\n    XMEMSET(&local[ripemd->buffLen], 0, RIPEMD_PAD_SIZE - ripemd->buffLen);\n\n    /* put lengths in bits */\n    ripemd->loLen = ripemd->loLen << 3;\n    ripemd->hiLen = (ripemd->loLen >> (8*sizeof(ripemd->loLen) - 3)) +\n                 (ripemd->hiLen << 3);\n\n    /* store lengths */\n    #ifdef BIG_ENDIAN_ORDER\n        ByteReverseWords(ripemd->buffer, ripemd->buffer, RIPEMD_BLOCK_SIZE);\n    #endif\n    /* ! length ordering dependent on digest endian type ! */\n    XMEMCPY(&local[RIPEMD_PAD_SIZE], &ripemd->loLen, sizeof(word32));\n    XMEMCPY(&local[RIPEMD_PAD_SIZE + sizeof(word32)], &ripemd->hiLen,\n           sizeof(word32));\n\n    Transform(ripemd);\n    #ifdef BIG_ENDIAN_ORDER\n        ByteReverseWords(ripemd->digest, ripemd->digest, RIPEMD_DIGEST_SIZE);\n    #endif\n    XMEMCPY(hash, ripemd->digest, RIPEMD_DIGEST_SIZE);\n\n    return wc_InitRipeMd(ripemd);  /* reset state */\n}\n\n\n#endif /* WOLFSSL_RIPEMD */\n"
  },
  {
    "path": "src/wolfcrypt/src/rsa.c",
    "content": "/* rsa.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n\n#ifndef NO_RSA\n\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n\n    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */\n    #define FIPS_NO_WRAPPERS\n\n       #ifdef USE_WINDOWS_API\n               #pragma code_seg(\".fipsA$e\")\n               #pragma const_seg(\".fipsB$e\")\n       #endif\n#endif\n\n#include <wolfssl/wolfcrypt/rsa.h>\n\n#ifdef WOLFSSL_AFALG_XILINX_RSA\n#include <wolfssl/wolfcrypt/port/af_alg/wc_afalg.h>\n#endif\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n#include <wolfssl/wolfcrypt/sp.h>\n#endif\n\n/*\nPossible RSA enable options:\n * NO_RSA:              Overall control of RSA                      default: on (not defined)\n * WC_RSA_BLINDING:     Uses Blinding w/ Private Ops                default: off\n                        Note: slower by ~20%\n * WOLFSSL_KEY_GEN:     Allows Private Key Generation               default: off\n * RSA_LOW_MEM:         NON CRT Private Operations, less memory     default: off\n * WC_NO_RSA_OAEP:      Disables RSA OAEP padding                   default: on (not defined)\n * WC_RSA_NONBLOCK:     Enables support for RSA non-blocking        default: off\n * WC_RSA_NONBLOCK_TIME:Enables support for time based blocking     default: off\n *                      time calculation.\n*/\n\n/*\nRSA Key Size Configuration:\n * FP_MAX_BITS:         With USE_FAST_MATH only                     default: 4096\n    If USE_FAST_MATH then use this to override default.\n    Value is key size * 2. Example: RSA 3072 = 6144\n*/\n\n\n/* If building for old FIPS. */\n#if defined(HAVE_FIPS) && \\\n    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n\nint  wc_InitRsaKey(RsaKey* key, void* ptr)\n{\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    return InitRsaKey_fips(key, ptr);\n}\n\n\nint  wc_InitRsaKey_ex(RsaKey* key, void* ptr, int devId)\n{\n    (void)devId;\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    return InitRsaKey_fips(key, ptr);\n}\n\n\nint  wc_FreeRsaKey(RsaKey* key)\n{\n    return FreeRsaKey_fips(key);\n}\n\n\n#ifndef WOLFSSL_RSA_VERIFY_ONLY\nint  wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out,\n                                 word32 outLen, RsaKey* key, WC_RNG* rng)\n{\n    if (in == NULL || out == NULL || key == NULL || rng == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    return RsaPublicEncrypt_fips(in, inLen, out, outLen, key, rng);\n}\n#endif\n\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\nint  wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out,\n                                        RsaKey* key)\n{\n    if (in == NULL || out == NULL || key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    return RsaPrivateDecryptInline_fips(in, inLen, out, key);\n}\n\n\nint  wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,\n                                  word32 outLen, RsaKey* key)\n{\n    if (in == NULL || out == NULL || key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    return RsaPrivateDecrypt_fips(in, inLen, out, outLen, key);\n}\n\n\nint  wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out,\n                            word32 outLen, RsaKey* key, WC_RNG* rng)\n{\n    if (in == NULL || out == NULL || key == NULL || inLen == 0) {\n        return BAD_FUNC_ARG;\n    }\n    return RsaSSL_Sign_fips(in, inLen, out, outLen, key, rng);\n}\n#endif\n\n\nint  wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)\n{\n    if (in == NULL || out == NULL || key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    return RsaSSL_VerifyInline_fips(in, inLen, out, key);\n}\n\n\nint  wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out,\n                              word32 outLen, RsaKey* key)\n{\n    if (in == NULL || out == NULL || key == NULL || inLen == 0) {\n        return BAD_FUNC_ARG;\n    }\n    return RsaSSL_Verify_fips(in, inLen, out, outLen, key);\n}\n\n\nint  wc_RsaEncryptSize(RsaKey* key)\n{\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n    return RsaEncryptSize_fips(key);\n}\n\n\n#ifndef WOLFSSL_RSA_VERIFY_ONLY\nint wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b,\n                           word32* bSz)\n{\n\n    /* not specified as fips so not needing _fips */\n    return RsaFlattenPublicKey(key, a, aSz, b, bSz);\n}\n#endif\n\n\n#ifdef WOLFSSL_KEY_GEN\n    int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)\n    {\n        return MakeRsaKey(key, size, e, rng);\n    }\n#endif\n\n\n/* these are functions in asn and are routed to wolfssl/wolfcrypt/asn.c\n* wc_RsaPrivateKeyDecode\n* wc_RsaPublicKeyDecode\n*/\n\n#else /* else build without fips, or for new fips */\n\n#include <wolfssl/wolfcrypt/random.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#ifdef WOLF_CRYPTO_CB\n    #include <wolfssl/wolfcrypt/cryptocb.h>\n#endif\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\nenum {\n    RSA_STATE_NONE = 0,\n\n    RSA_STATE_ENCRYPT_PAD,\n    RSA_STATE_ENCRYPT_EXPTMOD,\n    RSA_STATE_ENCRYPT_RES,\n\n    RSA_STATE_DECRYPT_EXPTMOD,\n    RSA_STATE_DECRYPT_UNPAD,\n    RSA_STATE_DECRYPT_RES,\n};\n\n\nstatic void wc_RsaCleanup(RsaKey* key)\n{\n#ifndef WOLFSSL_RSA_VERIFY_INLINE\n    if (key && key->data) {\n        /* make sure any allocated memory is free'd */\n        if (key->dataIsAlloc) {\n        #ifndef WOLFSSL_RSA_PUBLIC_ONLY\n            if (key->type == RSA_PRIVATE_DECRYPT ||\n                key->type == RSA_PRIVATE_ENCRYPT) {\n                ForceZero(key->data, key->dataLen);\n            }\n        #endif\n            XFREE(key->data, key->heap, DYNAMIC_TYPE_WOLF_BIGINT);\n            key->dataIsAlloc = 0;\n        }\n        key->data = NULL;\n        key->dataLen = 0;\n    }\n#else\n    (void)key;\n#endif\n}\n\nint wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId)\n{\n    int ret = 0;\n\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    XMEMSET(key, 0, sizeof(RsaKey));\n\n    key->type = RSA_TYPE_UNKNOWN;\n    key->state = RSA_STATE_NONE;\n    key->heap = heap;\n#ifndef WOLFSSL_RSA_VERIFY_INLINE\n    key->dataIsAlloc = 0;\n    key->data = NULL;\n#endif\n    key->dataLen = 0;\n#ifdef WC_RSA_BLINDING\n    key->rng = NULL;\n#endif\n\n#ifdef WOLF_CRYPTO_CB\n    key->devId = devId;\n#else\n    (void)devId;\n#endif\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #ifdef WOLFSSL_CERT_GEN\n        XMEMSET(&key->certSignCtx, 0, sizeof(CertSignCtx));\n    #endif\n\n    #ifdef WC_ASYNC_ENABLE_RSA\n        /* handle as async */\n        ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_RSA,\n                                                            key->heap, devId);\n        if (ret != 0)\n            return ret;\n    #endif /* WC_ASYNC_ENABLE_RSA */\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n    ret = mp_init_multi(&key->n, &key->e, NULL, NULL, NULL, NULL);\n    if (ret != MP_OKAY)\n        return ret;\n\n#if !defined(WOLFSSL_KEY_GEN) && !defined(OPENSSL_EXTRA) && defined(RSA_LOW_MEM)\n    ret = mp_init_multi(&key->d, &key->p, &key->q, NULL, NULL, NULL);\n#else\n    ret = mp_init_multi(&key->d, &key->p, &key->q, &key->dP, &key->dQ, &key->u);\n#endif\n    if (ret != MP_OKAY) {\n        mp_clear(&key->n);\n        mp_clear(&key->e);\n        return ret;\n    }\n#else\n    ret = mp_init(&key->n);\n    if (ret != MP_OKAY)\n        return ret;\n    ret = mp_init(&key->e);\n    if (ret != MP_OKAY) {\n        mp_clear(&key->n);\n        return ret;\n    }\n#endif\n\n#ifdef WOLFSSL_XILINX_CRYPT\n    key->pubExp = 0;\n    key->mod    = NULL;\n#endif\n\n#ifdef WOLFSSL_AFALG_XILINX_RSA\n    key->alFd = WC_SOCK_NOTSET;\n    key->rdFd = WC_SOCK_NOTSET;\n#endif\n\n    return ret;\n}\n\nint wc_InitRsaKey(RsaKey* key, void* heap)\n{\n    return wc_InitRsaKey_ex(key, heap, INVALID_DEVID);\n}\n\n#ifdef HAVE_PKCS11\nint wc_InitRsaKey_Id(RsaKey* key, unsigned char* id, int len, void* heap,\n                     int devId)\n{\n    int ret = 0;\n\n    if (key == NULL)\n        ret = BAD_FUNC_ARG;\n    if (ret == 0 && (len < 0 || len > RSA_MAX_ID_LEN))\n        ret = BUFFER_E;\n\n    if (ret == 0)\n        ret = wc_InitRsaKey_ex(key, heap, devId);\n\n    if (ret == 0 && id != NULL && len != 0) {\n        XMEMCPY(key->id, id, len);\n        key->idLen = len;\n    }\n\n    return ret;\n}\n#endif\n\n\n#ifdef WOLFSSL_XILINX_CRYPT\n#define MAX_E_SIZE 4\n/* Used to setup hardware state\n *\n * key  the RSA key to setup\n *\n * returns 0 on success\n */\nint wc_InitRsaHw(RsaKey* key)\n{\n    unsigned char* m; /* RSA modulous */\n    word32 e = 0;     /* RSA public exponent */\n    int mSz;\n    int eSz;\n\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    mSz = mp_unsigned_bin_size(&(key->n));\n    m = (unsigned char*)XMALLOC(mSz, key->heap, DYNAMIC_TYPE_KEY);\n    if (m == 0) {\n        return MEMORY_E;\n    }\n\n    if (mp_to_unsigned_bin(&(key->n), m) != MP_OKAY) {\n        WOLFSSL_MSG(\"Unable to get RSA key modulus\");\n        XFREE(m, key->heap, DYNAMIC_TYPE_KEY);\n        return MP_READ_E;\n    }\n\n    eSz = mp_unsigned_bin_size(&(key->e));\n    if (eSz > MAX_E_SIZE) {\n        WOLFSSL_MSG(\"Exponent of size 4 bytes expected\");\n        XFREE(m, key->heap, DYNAMIC_TYPE_KEY);\n        return BAD_FUNC_ARG;\n    }\n\n    if (mp_to_unsigned_bin(&(key->e), (byte*)&e + (MAX_E_SIZE - eSz))\n                != MP_OKAY) {\n        XFREE(m, key->heap, DYNAMIC_TYPE_KEY);\n        WOLFSSL_MSG(\"Unable to get RSA key exponent\");\n        return MP_READ_E;\n    }\n\n    /* check for existing mod buffer to avoid memory leak */\n    if (key->mod != NULL) {\n        XFREE(key->mod, key->heap, DYNAMIC_TYPE_KEY);\n    }\n\n    key->pubExp = e;\n    key->mod    = m;\n\n    if (XSecure_RsaInitialize(&(key->xRsa), key->mod, NULL,\n                (byte*)&(key->pubExp)) != XST_SUCCESS) {\n        WOLFSSL_MSG(\"Unable to initialize RSA on hardware\");\n        XFREE(m, key->heap, DYNAMIC_TYPE_KEY);\n        return BAD_STATE_E;\n    }\n\n#ifdef WOLFSSL_XILINX_PATCH\n   /* currently a patch of xsecure_rsa.c for 2048 bit keys */\n   if (wc_RsaEncryptSize(key) == 256) {\n       if (XSecure_RsaSetSize(&(key->xRsa), 2048) != XST_SUCCESS) {\n           WOLFSSL_MSG(\"Unable to set RSA key size on hardware\");\n           XFREE(m, key->heap, DYNAMIC_TYPE_KEY);\n           return BAD_STATE_E;\n       }\n   }\n#endif\n    return 0;\n} /* WOLFSSL_XILINX_CRYPT*/\n\n#elif defined(WOLFSSL_CRYPTOCELL)\n\nint wc_InitRsaHw(RsaKey* key)\n{\n    CRYSError_t ret = 0;\n    byte e[3];\n    word32 eSz = sizeof(e);\n    byte n[256];\n    word32 nSz = sizeof(n);\n    byte d[256];\n    word32 dSz = sizeof(d);\n    byte p[128];\n    word32 pSz = sizeof(p);\n    byte q[128];\n    word32 qSz = sizeof(q);\n\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, &pSz, q, &qSz);\n    if (ret != 0)\n        return MP_READ_E;\n\n    ret = CRYS_RSA_Build_PubKey(&key->ctx.pubKey, e, eSz, n, nSz);\n    if (ret != SA_SILIB_RET_OK){\n        WOLFSSL_MSG(\"CRYS_RSA_Build_PubKey failed\");\n        return ret;\n    }\n\n    ret =  CRYS_RSA_Build_PrivKey(&key->ctx.privKey, d, dSz, e, eSz, n, nSz);\n\n    if (ret != SA_SILIB_RET_OK){\n        WOLFSSL_MSG(\"CRYS_RSA_Build_PrivKey failed\");\n        return ret;\n    }\n    key->type = RSA_PRIVATE;\n    return 0;\n}\nstatic int cc310_RSA_GenerateKeyPair(RsaKey* key, int size, long e)\n{\n    CRYSError_t             ret = 0;\n    CRYS_RSAKGData_t        KeyGenData;\n    CRYS_RSAKGFipsContext_t FipsCtx;\n    byte ex[3];\n    uint16_t eSz = sizeof(ex);\n    byte n[256];\n    uint16_t nSz = sizeof(n);\n\n    ret = CRYS_RSA_KG_GenerateKeyPair(&wc_rndState,\n                        wc_rndGenVectFunc,\n                        (byte*)&e,\n                        3*sizeof(uint8_t),\n                        size,\n                        &key->ctx.privKey,\n                        &key->ctx.pubKey,\n                        &KeyGenData,\n                        &FipsCtx);\n\n    if (ret != SA_SILIB_RET_OK){\n        WOLFSSL_MSG(\"CRYS_RSA_KG_GenerateKeyPair failed\");\n        return ret;\n    }\n\n    ret = CRYS_RSA_Get_PubKey(&key->ctx.pubKey, ex, &eSz, n, &nSz);\n    if (ret != SA_SILIB_RET_OK){\n        WOLFSSL_MSG(\"CRYS_RSA_Get_PubKey failed\");\n        return ret;\n    }\n    ret = wc_RsaPublicKeyDecodeRaw(n, nSz, ex, eSz, key);\n\n    key->type = RSA_PRIVATE;\n\n    return ret;\n}\n#endif /* WOLFSSL_CRYPTOCELL */\n\nint wc_FreeRsaKey(RsaKey* key)\n{\n    int ret = 0;\n\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    wc_RsaCleanup(key);\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)\n    wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_RSA);\n#endif\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n    if (key->type == RSA_PRIVATE) {\n#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)\n        mp_forcezero(&key->u);\n        mp_forcezero(&key->dQ);\n        mp_forcezero(&key->dP);\n#endif\n        mp_forcezero(&key->q);\n        mp_forcezero(&key->p);\n        mp_forcezero(&key->d);\n    }\n    /* private part */\n#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)\n    mp_clear(&key->u);\n    mp_clear(&key->dQ);\n    mp_clear(&key->dP);\n#endif\n    mp_clear(&key->q);\n    mp_clear(&key->p);\n    mp_clear(&key->d);\n#endif /* WOLFSSL_RSA_PUBLIC_ONLY */\n\n    /* public part */\n    mp_clear(&key->e);\n    mp_clear(&key->n);\n\n#ifdef WOLFSSL_XILINX_CRYPT\n    XFREE(key->mod, key->heap, DYNAMIC_TYPE_KEY);\n    key->mod = NULL;\n#endif\n\n#ifdef WOLFSSL_AFALG_XILINX_RSA\n    /* make sure that sockets are closed on cleanup */\n    if (key->alFd > 0) {\n        close(key->alFd);\n        key->alFd = WC_SOCK_NOTSET;\n    }\n    if (key->rdFd > 0) {\n        close(key->rdFd);\n        key->rdFd = WC_SOCK_NOTSET;\n    }\n#endif\n\n    return ret;\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n#if defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_NO_RSA_KEY_CHECK)\n/* Check the pair-wise consistency of the RSA key.\n * From NIST SP 800-56B, section 6.4.1.1.\n * Verify that k = (k^e)^d, for some k: 1 < k < n-1. */\nint wc_CheckRsaKey(RsaKey* key)\n{\n#if defined(WOLFSSL_CRYPTOCELL)\n    return 0;\n#endif\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int *k = NULL, *tmp = NULL;\n#else\n    mp_int k[1], tmp[1];\n#endif\n    int ret = 0;\n\n#ifdef WOLFSSL_SMALL_STACK\n    k = (mp_int*)XMALLOC(sizeof(mp_int) * 2, NULL, DYNAMIC_TYPE_RSA);\n    if (k == NULL)\n        return MEMORY_E;\n    tmp = k + 1;\n#endif\n\n    if (mp_init_multi(k, tmp, NULL, NULL, NULL, NULL) != MP_OKAY)\n        ret = MP_INIT_E;\n\n    if (ret == 0) {\n        if (key == NULL)\n            ret = BAD_FUNC_ARG;\n    }\n\n    if (ret == 0) {\n        if (mp_set_int(k, 0x2342) != MP_OKAY)\n            ret = MP_READ_E;\n    }\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n#ifndef WOLFSSL_SP_NO_2048\n    if (mp_count_bits(&key->n) == 2048) {\n        ret = sp_ModExp_2048(k, &key->e, &key->n, tmp);\n        if (ret != 0)\n            ret = MP_EXPTMOD_E;\n        ret = sp_ModExp_2048(tmp, &key->d, &key->n, tmp);\n        if (ret != 0)\n            ret = MP_EXPTMOD_E;\n    }\n    else\n#endif\n#ifndef WOLFSSL_SP_NO_3072\n    if (mp_count_bits(&key->n) == 3072) {\n        ret = sp_ModExp_3072(k, &key->e, &key->n, tmp);\n        if (ret != 0)\n            ret = MP_EXPTMOD_E;\n        ret = sp_ModExp_3072(tmp, &key->d, &key->n, tmp);\n        if (ret != 0)\n            ret = MP_EXPTMOD_E;\n    }\n    else\n#endif\n#ifdef WOLFSSL_SP_4096\n    if (mp_count_bits(&key->n) == 4096) {\n        ret = sp_ModExp_4096(k, &key->e, &key->n, tmp);\n        if (ret != 0)\n            ret = MP_EXPTMOD_E;\n        ret = sp_ModExp_4096(tmp, &key->d, &key->n, tmp);\n        if (ret != 0)\n            ret = MP_EXPTMOD_E;\n    }\n    else\n#endif\n#endif\n#ifdef WOLFSSL_SP_MATH\n    {\n        ret = WC_KEY_SIZE_E;\n    }\n#else\n    {\n        if (ret == 0) {\n            if (mp_exptmod(k, &key->e, &key->n, tmp) != MP_OKAY)\n                ret = MP_EXPTMOD_E;\n        }\n\n        if (ret == 0) {\n            if (mp_exptmod(tmp, &key->d, &key->n, tmp) != MP_OKAY)\n                ret = MP_EXPTMOD_E;\n        }\n    }\n#endif\n\n    if (ret == 0) {\n        if (mp_cmp(k, tmp) != MP_EQ)\n            ret = RSA_KEY_PAIR_E;\n    }\n\n    /* Check d is less than n. */\n    if (ret == 0 ) {\n        if (mp_cmp(&key->d, &key->n) != MP_LT) {\n            ret = MP_EXPTMOD_E;\n        }\n    }\n    /* Check p*q = n. */\n    if (ret == 0 ) {\n        if (mp_mul(&key->p, &key->q, tmp) != MP_OKAY) {\n            ret = MP_EXPTMOD_E;\n        }\n    }\n    if (ret == 0 ) {\n        if (mp_cmp(&key->n, tmp) != MP_EQ) {\n            ret = MP_EXPTMOD_E;\n        }\n    }\n\n    /* Check dP, dQ and u if they exist */\n    if (ret == 0 && !mp_iszero(&key->dP)) {\n        if (ret == 0) {\n            if (mp_sub_d(&key->p, 1, tmp) != MP_OKAY) {\n                ret = MP_EXPTMOD_E;\n            }\n        }\n        /* Check dP <= p-1. */\n        if (ret == 0) {\n            if (mp_cmp(&key->dP, tmp) != MP_LT) {\n                ret = MP_EXPTMOD_E;\n            }\n        }\n        /* Check e*dP mod p-1 = 1. (dP = 1/e mod p-1) */\n        if (ret == 0) {\n            if (mp_mulmod(&key->dP, &key->e, tmp, tmp) != MP_OKAY) {\n                ret = MP_EXPTMOD_E;\n            }\n        }\n        if (ret == 0 ) {\n            if (!mp_isone(tmp)) {\n                ret = MP_EXPTMOD_E;\n            }\n        }\n\n        if (ret == 0) {\n            if (mp_sub_d(&key->q, 1, tmp) != MP_OKAY) {\n                ret = MP_EXPTMOD_E;\n            }\n        }\n        /* Check dQ <= q-1. */\n        if (ret == 0) {\n            if (mp_cmp(&key->dQ, tmp) != MP_LT) {\n                ret = MP_EXPTMOD_E;\n            }\n        }\n        /* Check e*dP mod p-1 = 1. (dQ = 1/e mod q-1) */\n        if (ret == 0) {\n            if (mp_mulmod(&key->dQ, &key->e, tmp, tmp) != MP_OKAY) {\n                ret = MP_EXPTMOD_E;\n            }\n        }\n        if (ret == 0 ) {\n            if (!mp_isone(tmp)) {\n                ret = MP_EXPTMOD_E;\n            }\n        }\n\n        /* Check u <= p. */\n        if (ret == 0) {\n            if (mp_cmp(&key->u, &key->p) != MP_LT) {\n                ret = MP_EXPTMOD_E;\n            }\n        }\n        /* Check u*q mod p = 1. (u = 1/q mod p) */\n        if (ret == 0) {\n            if (mp_mulmod(&key->u, &key->q, &key->p, tmp) != MP_OKAY) {\n                ret = MP_EXPTMOD_E;\n            }\n        }\n        if (ret == 0 ) {\n            if (!mp_isone(tmp)) {\n                ret = MP_EXPTMOD_E;\n            }\n        }\n    }\n\n    mp_forcezero(tmp);\n    mp_clear(tmp);\n    mp_clear(k);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(k, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return ret;\n}\n#endif\n#endif\n\n\n#if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_PSS)\n/* Uses MGF1 standard as a mask generation function\n   hType: hash type used\n   seed:  seed to use for generating mask\n   seedSz: size of seed buffer\n   out:   mask output after generation\n   outSz: size of output buffer\n */\nstatic int RsaMGF1(enum wc_HashType hType, byte* seed, word32 seedSz,\n                                        byte* out, word32 outSz, void* heap)\n{\n    byte* tmp;\n    /* needs to be large enough for seed size plus counter(4) */\n    byte  tmpA[WC_MAX_DIGEST_SIZE + 4];\n    byte   tmpF;     /* 1 if dynamic memory needs freed */\n    word32 tmpSz;\n    int hLen;\n    int ret;\n    word32 counter;\n    word32 idx;\n    hLen    = wc_HashGetDigestSize(hType);\n    counter = 0;\n    idx     = 0;\n\n    (void)heap;\n\n    /* check error return of wc_HashGetDigestSize */\n    if (hLen < 0) {\n        return hLen;\n    }\n\n    /* if tmp is not large enough than use some dynamic memory */\n    if ((seedSz + 4) > sizeof(tmpA) || (word32)hLen > sizeof(tmpA)) {\n        /* find largest amount of memory needed which will be the max of\n         * hLen and (seedSz + 4) since tmp is used to store the hash digest */\n        tmpSz = ((seedSz + 4) > (word32)hLen)? seedSz + 4: (word32)hLen;\n        tmp = (byte*)XMALLOC(tmpSz, heap, DYNAMIC_TYPE_RSA_BUFFER);\n        if (tmp == NULL) {\n            return MEMORY_E;\n        }\n        tmpF = 1; /* make sure to free memory when done */\n    }\n    else {\n        /* use array on the stack */\n        tmpSz = sizeof(tmpA);\n        tmp  = tmpA;\n        tmpF = 0; /* no need to free memory at end */\n    }\n\n    do {\n        int i = 0;\n        XMEMCPY(tmp, seed, seedSz);\n\n        /* counter to byte array appended to tmp */\n        tmp[seedSz]     = (counter >> 24) & 0xFF;\n        tmp[seedSz + 1] = (counter >> 16) & 0xFF;\n        tmp[seedSz + 2] = (counter >>  8) & 0xFF;\n        tmp[seedSz + 3] = (counter)       & 0xFF;\n\n        /* hash and append to existing output */\n        if ((ret = wc_Hash(hType, tmp, (seedSz + 4), tmp, tmpSz)) != 0) {\n            /* check for if dynamic memory was needed, then free */\n            if (tmpF) {\n                XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);\n            }\n            return ret;\n        }\n\n        for (i = 0; i < hLen && idx < outSz; i++) {\n            out[idx++] = tmp[i];\n        }\n        counter++;\n    } while (idx < outSz);\n\n    /* check for if dynamic memory was needed, then free */\n    if (tmpF) {\n        XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);\n    }\n\n    return 0;\n}\n\n/* helper function to direct which mask generation function is used\n   switeched on type input\n */\nstatic int RsaMGF(int type, byte* seed, word32 seedSz, byte* out,\n                                                    word32 outSz, void* heap)\n{\n    int ret;\n\n    switch(type) {\n    #ifndef NO_SHA\n        case WC_MGF1SHA1:\n            ret = RsaMGF1(WC_HASH_TYPE_SHA, seed, seedSz, out, outSz, heap);\n            break;\n    #endif\n    #ifndef NO_SHA256\n    #ifdef WOLFSSL_SHA224\n        case WC_MGF1SHA224:\n            ret = RsaMGF1(WC_HASH_TYPE_SHA224, seed, seedSz, out, outSz, heap);\n            break;\n    #endif\n        case WC_MGF1SHA256:\n            ret = RsaMGF1(WC_HASH_TYPE_SHA256, seed, seedSz, out, outSz, heap);\n            break;\n    #endif\n    #ifdef WOLFSSL_SHA384\n        case WC_MGF1SHA384:\n            ret = RsaMGF1(WC_HASH_TYPE_SHA384, seed, seedSz, out, outSz, heap);\n            break;\n    #endif\n    #ifdef WOLFSSL_SHA512\n        case WC_MGF1SHA512:\n            ret = RsaMGF1(WC_HASH_TYPE_SHA512, seed, seedSz, out, outSz, heap);\n            break;\n    #endif\n        default:\n            WOLFSSL_MSG(\"Unknown MGF type: check build options\");\n            ret = BAD_FUNC_ARG;\n    }\n\n    /* in case of default avoid unused warning */\n    (void)seed;\n    (void)seedSz;\n    (void)out;\n    (void)outSz;\n    (void)heap;\n\n    return ret;\n}\n#endif /* !WC_NO_RSA_OAEP */\n\n\n/* Padding */\n#ifndef WOLFSSL_RSA_VERIFY_ONLY\n#ifndef WC_NO_RNG\n#ifndef WC_NO_RSA_OAEP\nstatic int RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock,\n        word32 pkcsBlockLen, byte padValue, WC_RNG* rng,\n        enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen,\n        void* heap)\n{\n    int ret;\n    int hLen;\n    int psLen;\n    int i;\n    word32 idx;\n\n    byte* dbMask;\n\n    #ifdef WOLFSSL_SMALL_STACK\n        byte* lHash = NULL;\n        byte* seed  = NULL;\n    #else\n        /* must be large enough to contain largest hash */\n        byte lHash[WC_MAX_DIGEST_SIZE];\n        byte seed[ WC_MAX_DIGEST_SIZE];\n    #endif\n\n    /* no label is allowed, but catch if no label provided and length > 0 */\n    if (optLabel == NULL && labelLen > 0) {\n        return BUFFER_E;\n    }\n\n    /* limit of label is the same as limit of hash function which is massive */\n    hLen = wc_HashGetDigestSize(hType);\n    if (hLen < 0) {\n        return hLen;\n    }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        lHash = (byte*)XMALLOC(hLen, heap, DYNAMIC_TYPE_RSA_BUFFER);\n        if (lHash == NULL) {\n            return MEMORY_E;\n        }\n        seed = (byte*)XMALLOC(hLen, heap, DYNAMIC_TYPE_RSA_BUFFER);\n        if (seed == NULL) {\n            XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER);\n            return MEMORY_E;\n        }\n    #else\n        /* hLen should never be larger than lHash since size is max digest size,\n           but check before blindly calling wc_Hash */\n        if ((word32)hLen > sizeof(lHash)) {\n            WOLFSSL_MSG(\"OAEP lHash to small for digest!!\");\n            return MEMORY_E;\n        }\n    #endif\n\n    if ((ret = wc_Hash(hType, optLabel, labelLen, lHash, hLen)) != 0) {\n        WOLFSSL_MSG(\"OAEP hash type possibly not supported or lHash to small\");\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER);\n            XFREE(seed,  heap, DYNAMIC_TYPE_RSA_BUFFER);\n        #endif\n        return ret;\n    }\n\n    /* handles check of location for idx as well as psLen, cast to int to check\n       for pkcsBlockLen(k) - 2 * hLen - 2 being negative\n       This check is similar to decryption where k > 2 * hLen + 2 as msg\n       size approaches 0. In decryption if k is less than or equal -- then there\n       is no possible room for msg.\n       k = RSA key size\n       hLen = hash digest size -- will always be >= 0 at this point\n     */\n    if ((word32)(2 * hLen + 2) > pkcsBlockLen) {\n        WOLFSSL_MSG(\"OAEP pad error hash to big for RSA key size\");\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER);\n            XFREE(seed,  heap, DYNAMIC_TYPE_RSA_BUFFER);\n        #endif\n        return BAD_FUNC_ARG;\n    }\n\n    if (inputLen > (pkcsBlockLen - 2 * hLen - 2)) {\n        WOLFSSL_MSG(\"OAEP pad error message too long\");\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER);\n            XFREE(seed,  heap, DYNAMIC_TYPE_RSA_BUFFER);\n        #endif\n        return BAD_FUNC_ARG;\n    }\n\n    /* concatenate lHash || PS || 0x01 || msg */\n    idx = pkcsBlockLen - 1 - inputLen;\n    psLen = pkcsBlockLen - inputLen - 2 * hLen - 2;\n    if (pkcsBlockLen < inputLen) { /*make sure not writing over end of buffer */\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER);\n            XFREE(seed,  heap, DYNAMIC_TYPE_RSA_BUFFER);\n        #endif\n        return BUFFER_E;\n    }\n    XMEMCPY(pkcsBlock + (pkcsBlockLen - inputLen), input, inputLen);\n    pkcsBlock[idx--] = 0x01; /* PS and M separator */\n    while (psLen > 0 && idx > 0) {\n        pkcsBlock[idx--] = 0x00;\n        psLen--;\n    }\n\n    idx = idx - hLen + 1;\n    XMEMCPY(pkcsBlock + idx, lHash, hLen);\n\n    /* generate random seed */\n    if ((ret = wc_RNG_GenerateBlock(rng, seed, hLen)) != 0) {\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER);\n            XFREE(seed,  heap, DYNAMIC_TYPE_RSA_BUFFER);\n        #endif\n        return ret;\n    }\n\n    /* create maskedDB from dbMask */\n    dbMask = (byte*)XMALLOC(pkcsBlockLen - hLen - 1, heap, DYNAMIC_TYPE_RSA);\n    if (dbMask == NULL) {\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER);\n            XFREE(seed,  heap, DYNAMIC_TYPE_RSA_BUFFER);\n        #endif\n        return MEMORY_E;\n    }\n    XMEMSET(dbMask, 0, pkcsBlockLen - hLen - 1); /* help static analyzer */\n\n    ret = RsaMGF(mgf, seed, hLen, dbMask, pkcsBlockLen - hLen - 1, heap);\n    if (ret != 0) {\n        XFREE(dbMask, heap, DYNAMIC_TYPE_RSA);\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER);\n            XFREE(seed,  heap, DYNAMIC_TYPE_RSA_BUFFER);\n        #endif\n        return ret;\n    }\n\n    i = 0;\n    idx = hLen + 1;\n    while (idx < pkcsBlockLen && (word32)i < (pkcsBlockLen - hLen -1)) {\n        pkcsBlock[idx] = dbMask[i++] ^ pkcsBlock[idx];\n        idx++;\n    }\n    XFREE(dbMask, heap, DYNAMIC_TYPE_RSA);\n\n\n    /* create maskedSeed from seedMask */\n    idx = 0;\n    pkcsBlock[idx++] = 0x00;\n    /* create seedMask inline */\n    if ((ret = RsaMGF(mgf, pkcsBlock + hLen + 1, pkcsBlockLen - hLen - 1,\n                                           pkcsBlock + 1, hLen, heap)) != 0) {\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER);\n            XFREE(seed,  heap, DYNAMIC_TYPE_RSA_BUFFER);\n        #endif\n        return ret;\n    }\n\n    /* xor created seedMask with seed to make maskedSeed */\n    i = 0;\n    while (idx < (word32)(hLen + 1) && i < hLen) {\n        pkcsBlock[idx] = pkcsBlock[idx] ^ seed[i++];\n        idx++;\n    }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER);\n        XFREE(seed,  heap, DYNAMIC_TYPE_RSA_BUFFER);\n    #endif\n    (void)padValue;\n\n    return 0;\n}\n#endif /* !WC_NO_RSA_OAEP */\n\n#ifdef WC_RSA_PSS\n\n/* 0x00 .. 0x00 0x01 | Salt | Gen Hash | 0xbc\n * XOR MGF over all bytes down to end of Salt\n * Gen Hash = HASH(8 * 0x00 | Message Hash | Salt)\n *\n * input         Digest of the message.\n * inputLen      Length of digest.\n * pkcsBlock     Buffer to write to.\n * pkcsBlockLen  Length of buffer to write to.\n * rng           Random number generator (for salt).\n * htype         Hash function to use.\n * mgf           Mask generation function.\n * saltLen       Length of salt to put in padding.\n * bits          Length of key in bits.\n * heap          Used for dynamic memory allocation.\n * returns 0 on success, PSS_SALTLEN_E when the salt length is invalid\n * and other negative values on error.\n */\nstatic int RsaPad_PSS(const byte* input, word32 inputLen, byte* pkcsBlock,\n        word32 pkcsBlockLen, WC_RNG* rng, enum wc_HashType hType, int mgf,\n        int saltLen, int bits, void* heap)\n{\n    int   ret = 0;\n    int   hLen, i, o, maskLen, hiBits;\n    byte* m;\n    byte* s;\n#if defined(WOLFSSL_PSS_LONG_SALT) || defined(WOLFSSL_PSS_SALT_LEN_DISCOVER)\n    #if defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_STATIC_MEMORY)\n        byte salt[RSA_MAX_SIZE/8 + RSA_PSS_PAD_SZ];\n    #else\n        byte* salt = NULL;\n    #endif\n#else\n    byte salt[WC_MAX_DIGEST_SIZE];\n#endif\n\n#if defined(WOLFSSL_PSS_LONG_SALT) || defined(WOLFSSL_PSS_SALT_LEN_DISCOVER)\n    if (pkcsBlockLen > RSA_MAX_SIZE/8) {\n        return MEMORY_E;\n    }\n#endif\n\n    hLen = wc_HashGetDigestSize(hType);\n    if (hLen < 0)\n        return hLen;\n\n    hiBits = (bits - 1) & 0x7;\n    if (hiBits == 0) {\n        *(pkcsBlock++) = 0;\n        pkcsBlockLen--;\n    }\n\n    if (saltLen == RSA_PSS_SALT_LEN_DEFAULT) {\n        saltLen = hLen;\n        #ifdef WOLFSSL_SHA512\n            /* See FIPS 186-4 section 5.5 item (e). */\n            if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE) {\n                saltLen = RSA_PSS_SALT_MAX_SZ;\n            }\n        #endif\n    }\n#ifndef WOLFSSL_PSS_LONG_SALT\n    else if (saltLen > hLen) {\n        return PSS_SALTLEN_E;\n    }\n#endif\n#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER\n    else if (saltLen < RSA_PSS_SALT_LEN_DEFAULT) {\n        return PSS_SALTLEN_E;\n    }\n#else\n    else if (saltLen == RSA_PSS_SALT_LEN_DISCOVER) {\n        saltLen = (int)pkcsBlockLen - hLen - 2;\n        if (saltLen < 0) {\n            return PSS_SALTLEN_E;\n        }\n    }\n    else if (saltLen < RSA_PSS_SALT_LEN_DISCOVER) {\n        return PSS_SALTLEN_E;\n    }\n#endif\n    if ((int)pkcsBlockLen - hLen < saltLen + 2) {\n        return PSS_SALTLEN_E;\n    }\n\n    maskLen = pkcsBlockLen - 1 - hLen;\n\n#if defined(WOLFSSL_PSS_LONG_SALT) || defined(WOLFSSL_PSS_SALT_LEN_DISCOVER)\n    #if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)\n        salt = (byte*)XMALLOC(RSA_PSS_PAD_SZ + inputLen + saltLen, heap,\n                                                       DYNAMIC_TYPE_RSA_BUFFER);\n        if (salt == NULL) {\n            return MEMORY_E;\n        }\n    #endif\n    s = m = salt;\n    XMEMSET(m, 0, RSA_PSS_PAD_SZ);\n    m += RSA_PSS_PAD_SZ;\n    XMEMCPY(m, input, inputLen);\n    m += inputLen;\n    o = (int)(m - s);\n    if (saltLen > 0) {\n        ret = wc_RNG_GenerateBlock(rng, m, saltLen);\n        if (ret == 0) {\n            m += saltLen;\n        }\n    }\n#else\n    s = m = pkcsBlock;\n    XMEMSET(m, 0, RSA_PSS_PAD_SZ);\n    m += RSA_PSS_PAD_SZ;\n    XMEMCPY(m, input, inputLen);\n    m += inputLen;\n    o = 0;\n    if (saltLen > 0) {\n        ret = wc_RNG_GenerateBlock(rng, salt, saltLen);\n        if (ret == 0) {\n            XMEMCPY(m, salt, saltLen);\n            m += saltLen;\n        }\n    }\n#endif\n    if (ret == 0) {\n        /* Put Hash at end of pkcsBlock - 1 */\n        ret = wc_Hash(hType, s, (word32)(m - s), pkcsBlock + maskLen, hLen);\n    }\n    if (ret == 0) {\n        pkcsBlock[pkcsBlockLen - 1] = RSA_PSS_PAD_TERM;\n\n        ret = RsaMGF(mgf, pkcsBlock + maskLen, hLen, pkcsBlock, maskLen, heap);\n    }\n    if (ret == 0) {\n        pkcsBlock[0] &= (1 << hiBits) - 1;\n\n        m = pkcsBlock + maskLen - saltLen - 1;\n        *(m++) ^= 0x01;\n        for (i = 0; i < saltLen; i++) {\n            m[i] ^= salt[o + i];\n        }\n    }\n\n#if defined(WOLFSSL_PSS_LONG_SALT) || defined(WOLFSSL_PSS_SALT_LEN_DISCOVER)\n    #if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)\n        if (salt != NULL) {\n            XFREE(salt, heap, DYNAMIC_TYPE_RSA_BUFFER);\n        }\n    #endif\n#endif\n    return ret;\n}\n#endif /* WC_RSA_PSS */\n\nstatic int RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,\n                           word32 pkcsBlockLen, byte padValue, WC_RNG* rng)\n{\n    if (input == NULL || inputLen == 0 || pkcsBlock == NULL ||\n                                                        pkcsBlockLen == 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    pkcsBlock[0] = 0x0;       /* set first byte to zero and advance */\n    pkcsBlock++; pkcsBlockLen--;\n    pkcsBlock[0] = padValue;  /* insert padValue */\n\n    if (padValue == RSA_BLOCK_TYPE_1) {\n        if (pkcsBlockLen < inputLen + 2) {\n            WOLFSSL_MSG(\"RsaPad error, invalid length\");\n            return RSA_PAD_E;\n        }\n\n        /* pad with 0xff bytes */\n        XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2);\n    }\n    else {\n#ifndef WOLFSSL_RSA_VERIFY_ONLY\n        /* pad with non-zero random bytes */\n        word32 padLen, i;\n        int    ret;\n\n        if (pkcsBlockLen < inputLen + 1) {\n            WOLFSSL_MSG(\"RsaPad error, invalid length\");\n            return RSA_PAD_E;\n        }\n\n        padLen = pkcsBlockLen - inputLen - 1;\n        ret    = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen);\n        if (ret != 0) {\n            return ret;\n        }\n\n        /* remove zeros */\n        for (i = 1; i < padLen; i++) {\n            if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;\n        }\n#else\n        (void)rng;\n        return RSA_WRONG_TYPE_E;\n#endif\n    }\n\n    pkcsBlock[pkcsBlockLen-inputLen-1] = 0;     /* separator */\n    XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);\n\n    return 0;\n}\n#endif /* !WC_NO_RNG */\n\n/* helper function to direct which padding is used */\nstatic int wc_RsaPad_ex(const byte* input, word32 inputLen, byte* pkcsBlock,\n    word32 pkcsBlockLen, byte padValue, WC_RNG* rng, int padType,\n    enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen,\n    int saltLen, int bits, void* heap)\n{\n    int ret;\n\n    switch (padType)\n    {\n#ifndef WC_NO_RNG\n        case WC_RSA_PKCSV15_PAD:\n            /*WOLFSSL_MSG(\"wolfSSL Using RSA PKCSV15 padding\");*/\n            ret = RsaPad(input, inputLen, pkcsBlock, pkcsBlockLen,\n                                                                 padValue, rng);\n            break;\n\n    #ifndef WC_NO_RSA_OAEP\n        case WC_RSA_OAEP_PAD:\n            WOLFSSL_MSG(\"wolfSSL Using RSA OAEP padding\");\n            ret = RsaPad_OAEP(input, inputLen, pkcsBlock, pkcsBlockLen,\n                           padValue, rng, hType, mgf, optLabel, labelLen, heap);\n            break;\n    #endif\n\n    #ifdef WC_RSA_PSS\n        case WC_RSA_PSS_PAD:\n            WOLFSSL_MSG(\"wolfSSL Using RSA PSS padding\");\n            ret = RsaPad_PSS(input, inputLen, pkcsBlock, pkcsBlockLen, rng,\n                                               hType, mgf, saltLen, bits, heap);\n            break;\n    #endif\n#endif /* !WC_NO_RNG */\n\n    #ifdef WC_RSA_NO_PADDING\n        case WC_RSA_NO_PAD:\n            WOLFSSL_MSG(\"wolfSSL Using NO padding\");\n\n            /* In the case of no padding being used check that input is exactly\n             * the RSA key length */\n            if (bits <= 0 || inputLen != ((word32)bits/WOLFSSL_BIT_SIZE)) {\n                WOLFSSL_MSG(\"Bad input size\");\n                ret = RSA_PAD_E;\n            }\n            else {\n                XMEMCPY(pkcsBlock, input, inputLen);\n                ret = 0;\n            }\n            break;\n    #endif\n\n        default:\n            WOLFSSL_MSG(\"Unknown RSA Pad Type\");\n            ret = RSA_PAD_E;\n    }\n\n    /* silence warning if not used with padding scheme */\n    (void)input;\n    (void)inputLen;\n    (void)pkcsBlock;\n    (void)pkcsBlockLen;\n    (void)padValue;\n    (void)rng;\n    (void)padType;\n    (void)hType;\n    (void)mgf;\n    (void)optLabel;\n    (void)labelLen;\n    (void)saltLen;\n    (void)bits;\n    (void)heap;\n\n    return ret;\n}\n#endif /* WOLFSSL_RSA_VERIFY_ONLY */\n\n\n/* UnPadding */\n#ifndef WC_NO_RSA_OAEP\n/* UnPad plaintext, set start to *output, return length of plaintext,\n * < 0 on error */\nstatic int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,\n                            byte **output, enum wc_HashType hType, int mgf,\n                            byte* optLabel, word32 labelLen, void* heap)\n{\n    int hLen;\n    int ret;\n    byte h[WC_MAX_DIGEST_SIZE]; /* max digest size */\n    byte* tmp;\n    word32 idx;\n\n    /* no label is allowed, but catch if no label provided and length > 0 */\n    if (optLabel == NULL && labelLen > 0) {\n        return BUFFER_E;\n    }\n\n    hLen = wc_HashGetDigestSize(hType);\n    if ((hLen < 0) || (pkcsBlockLen < (2 * (word32)hLen + 2))) {\n        return BAD_FUNC_ARG;\n    }\n\n    tmp = (byte*)XMALLOC(pkcsBlockLen, heap, DYNAMIC_TYPE_RSA_BUFFER);\n    if (tmp == NULL) {\n        return MEMORY_E;\n    }\n    XMEMSET(tmp, 0, pkcsBlockLen);\n\n    /* find seedMask value */\n    if ((ret = RsaMGF(mgf, (byte*)(pkcsBlock + (hLen + 1)),\n                            pkcsBlockLen - hLen - 1, tmp, hLen, heap)) != 0) {\n        XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);\n        return ret;\n    }\n\n    /* xor seedMask value with maskedSeed to get seed value */\n    for (idx = 0; idx < (word32)hLen; idx++) {\n        tmp[idx] = tmp[idx] ^ pkcsBlock[1 + idx];\n    }\n\n    /* get dbMask value */\n    if ((ret = RsaMGF(mgf, tmp, hLen, tmp + hLen,\n                                       pkcsBlockLen - hLen - 1, heap)) != 0) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_RSA_BUFFER);\n        return ret;\n    }\n\n    /* get DB value by doing maskedDB xor dbMask */\n    for (idx = 0; idx < (pkcsBlockLen - hLen - 1); idx++) {\n        pkcsBlock[hLen + 1 + idx] = pkcsBlock[hLen + 1 + idx] ^ tmp[idx + hLen];\n    }\n\n    /* done with use of tmp buffer */\n    XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);\n\n    /* advance idx to index of PS and msg separator, account for PS size of 0*/\n    idx = hLen + 1 + hLen;\n    while (idx < pkcsBlockLen && pkcsBlock[idx] == 0) {idx++;}\n\n    /* create hash of label for comparison with hash sent */\n    if ((ret = wc_Hash(hType, optLabel, labelLen, h, hLen)) != 0) {\n        return ret;\n    }\n\n    /* say no to chosen ciphertext attack.\n       Comparison of lHash, Y, and separator value needs to all happen in\n       constant time.\n       Attackers should not be able to get error condition from the timing of\n       these checks.\n     */\n    ret = 0;\n    ret |= ConstantCompare(pkcsBlock + hLen + 1, h, hLen);\n    ret += pkcsBlock[idx++] ^ 0x01; /* separator value is 0x01 */\n    ret += pkcsBlock[0]     ^ 0x00; /* Y, the first value, should be 0 */\n\n    /* Return 0 data length on error. */\n    idx = ctMaskSelInt(ctMaskEq(ret, 0), idx, pkcsBlockLen);\n\n    /* adjust pointer to correct location in array and return size of M */\n    *output = (byte*)(pkcsBlock + idx);\n    return pkcsBlockLen - idx;\n}\n#endif /* WC_NO_RSA_OAEP */\n\n#ifdef WC_RSA_PSS\n/* 0x00 .. 0x00 0x01 | Salt | Gen Hash | 0xbc\n * MGF over all bytes down to end of Salt\n *\n * pkcsBlock     Buffer holding decrypted data.\n * pkcsBlockLen  Length of buffer.\n * htype         Hash function to use.\n * mgf           Mask generation function.\n * saltLen       Length of salt to put in padding.\n * bits          Length of key in bits.\n * heap          Used for dynamic memory allocation.\n * returns 0 on success, PSS_SALTLEN_E when the salt length is invalid,\n * BAD_PADDING_E when the padding is not valid, MEMORY_E when allocation fails\n * and other negative values on error.\n */\nstatic int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,\n                        byte **output, enum wc_HashType hType, int mgf,\n                        int saltLen, int bits, void* heap)\n{\n    int   ret;\n    byte* tmp;\n    int   hLen, i, maskLen, orig_bits = bits;\n#if defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_STATIC_MEMORY)\n    byte tmp_buf[RSA_MAX_SIZE/8];\n    tmp = tmp_buf;\n\n    if (pkcsBlockLen > RSA_MAX_SIZE/8) {\n        return MEMORY_E;\n    }\n#endif\n\n    hLen = wc_HashGetDigestSize(hType);\n    if (hLen < 0)\n        return hLen;\n    bits = (bits - 1) & 0x7;\n    if ((pkcsBlock[0] & (0xff << bits)) != 0) {\n        return BAD_PADDING_E;\n    }\n    if (bits == 0) {\n        pkcsBlock++;\n        pkcsBlockLen--;\n    }\n    maskLen = (int)pkcsBlockLen - 1 - hLen;\n    if (maskLen < 0) {\n        WOLFSSL_MSG(\"RsaUnPad_PSS: Hash too large\");\n        return WC_KEY_SIZE_E;\n    }\n\n    if (saltLen == RSA_PSS_SALT_LEN_DEFAULT) {\n        saltLen = hLen;\n        #ifdef WOLFSSL_SHA512\n            /* See FIPS 186-4 section 5.5 item (e). */\n            if (orig_bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE)\n                saltLen = RSA_PSS_SALT_MAX_SZ;\n        #endif\n    }\n#ifndef WOLFSSL_PSS_LONG_SALT\n    else if (saltLen > hLen)\n        return PSS_SALTLEN_E;\n#endif\n#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER\n    else if (saltLen < RSA_PSS_SALT_LEN_DEFAULT)\n        return PSS_SALTLEN_E;\n    if (maskLen < saltLen + 1) {\n        return PSS_SALTLEN_E;\n    }\n#else\n    else if (saltLen < RSA_PSS_SALT_LEN_DISCOVER)\n        return PSS_SALTLEN_E;\n    if (saltLen != RSA_PSS_SALT_LEN_DISCOVER && maskLen < saltLen + 1) {\n        return WC_KEY_SIZE_E;\n    }\n#endif\n\n    if (pkcsBlock[pkcsBlockLen - 1] != RSA_PSS_PAD_TERM) {\n        WOLFSSL_MSG(\"RsaUnPad_PSS: Padding Term Error\");\n        return BAD_PADDING_E;\n    }\n\n#if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)\n    tmp = (byte*)XMALLOC(maskLen, heap, DYNAMIC_TYPE_RSA_BUFFER);\n    if (tmp == NULL) {\n        return MEMORY_E;\n    }\n#endif\n\n    if ((ret = RsaMGF(mgf, pkcsBlock + maskLen, hLen, tmp, maskLen,\n                                                                  heap)) != 0) {\n        XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);\n        return ret;\n    }\n\n    tmp[0] &= (1 << bits) - 1;\n    pkcsBlock[0] &= (1 << bits) - 1;\n#ifdef WOLFSSL_PSS_SALT_LEN_DISCOVER\n    if (saltLen == RSA_PSS_SALT_LEN_DISCOVER) {\n        for (i = 0; i < maskLen - 1; i++) {\n            if (tmp[i] != pkcsBlock[i]) {\n                break;\n            }\n        }\n        if (tmp[i] != (pkcsBlock[i] ^ 0x01)) {\n            XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);\n            WOLFSSL_MSG(\"RsaUnPad_PSS: Padding Error Match\");\n            return PSS_SALTLEN_RECOVER_E;\n        }\n        saltLen = maskLen - (i + 1);\n    }\n    else\n#endif\n    {\n        for (i = 0; i < maskLen - 1 - saltLen; i++) {\n            if (tmp[i] != pkcsBlock[i]) {\n                XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);\n                WOLFSSL_MSG(\"RsaUnPad_PSS: Padding Error Match\");\n                return PSS_SALTLEN_E;\n            }\n        }\n        if (tmp[i] != (pkcsBlock[i] ^ 0x01)) {\n            XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);\n            WOLFSSL_MSG(\"RsaUnPad_PSS: Padding Error End\");\n            return PSS_SALTLEN_E;\n        }\n    }\n    for (i++; i < maskLen; i++)\n        pkcsBlock[i] ^= tmp[i];\n\n#if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)\n    XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);\n#endif\n\n    *output = pkcsBlock + maskLen - saltLen;\n    return saltLen + hLen;\n}\n#endif\n\n/* UnPad plaintext, set start to *output, return length of plaintext,\n * < 0 on error */\nstatic int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,\n                    byte **output, byte padValue)\n{\n    int    ret = BAD_FUNC_ARG;\n    word16 i;\n#ifndef WOLFSSL_RSA_VERIFY_ONLY\n    byte   invalid = 0;\n#endif\n\n    if (output == NULL || pkcsBlockLen == 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (padValue == RSA_BLOCK_TYPE_1) {\n        /* First byte must be 0x00 and Second byte, block type, 0x01 */\n        if (pkcsBlock[0] != 0 || pkcsBlock[1] != RSA_BLOCK_TYPE_1) {\n            WOLFSSL_MSG(\"RsaUnPad error, invalid formatting\");\n            return RSA_PAD_E;\n        }\n\n        /* check the padding until we find the separator */\n        for (i = 2; i < pkcsBlockLen && pkcsBlock[i++] == 0xFF; ) { }\n\n        /* Minimum of 11 bytes of pre-message data and must have separator. */\n        if (i < RSA_MIN_PAD_SZ || pkcsBlock[i-1] != 0) {\n            WOLFSSL_MSG(\"RsaUnPad error, bad formatting\");\n            return RSA_PAD_E;\n        }\n\n        *output = (byte *)(pkcsBlock + i);\n        ret = pkcsBlockLen - i;\n    }\n#ifndef WOLFSSL_RSA_VERIFY_ONLY\n    else {\n        word16 j;\n        word16 pastSep = 0;\n\n        /* Decrypted with private key - unpad must be constant time. */\n        for (i = 0, j = 2; j < pkcsBlockLen; j++) {\n           /* Update i if not passed the separator and at separator. */\n            i |= (~pastSep) & ctMask16Eq(pkcsBlock[j], 0x00) & (j + 1);\n            pastSep |= ctMask16Eq(pkcsBlock[j], 0x00);\n        }\n\n        /* Minimum of 11 bytes of pre-message data - including leading 0x00. */\n        invalid |= ctMaskLT(i, RSA_MIN_PAD_SZ);\n        /* Must have seen separator. */\n        invalid |= ~pastSep;\n        /* First byte must be 0x00. */\n        invalid |= ctMaskNotEq(pkcsBlock[0], 0x00);\n        /* Check against expected block type: padValue */\n        invalid |= ctMaskNotEq(pkcsBlock[1], padValue);\n\n        *output = (byte *)(pkcsBlock + i);\n        ret = ((int)~invalid) & (pkcsBlockLen - i);\n    }\n#endif\n\n    return ret;\n}\n\n/* helper function to direct unpadding\n *\n * bits is the key modulus size in bits\n */\nstatic int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out,\n                          byte padValue, int padType, enum wc_HashType hType,\n                          int mgf, byte* optLabel, word32 labelLen, int saltLen,\n                          int bits, void* heap)\n{\n    int ret;\n\n    switch (padType) {\n        case WC_RSA_PKCSV15_PAD:\n            /*WOLFSSL_MSG(\"wolfSSL Using RSA PKCSV15 un-padding\");*/\n            ret = RsaUnPad(pkcsBlock, pkcsBlockLen, out, padValue);\n            break;\n\n    #ifndef WC_NO_RSA_OAEP\n        case WC_RSA_OAEP_PAD:\n            WOLFSSL_MSG(\"wolfSSL Using RSA OAEP un-padding\");\n            ret = RsaUnPad_OAEP((byte*)pkcsBlock, pkcsBlockLen, out,\n                                        hType, mgf, optLabel, labelLen, heap);\n            break;\n    #endif\n\n    #ifdef WC_RSA_PSS\n        case WC_RSA_PSS_PAD:\n            WOLFSSL_MSG(\"wolfSSL Using RSA PSS un-padding\");\n            ret = RsaUnPad_PSS((byte*)pkcsBlock, pkcsBlockLen, out, hType, mgf,\n                                                           saltLen, bits, heap);\n            break;\n    #endif\n\n    #ifdef WC_RSA_NO_PADDING\n        case WC_RSA_NO_PAD:\n            WOLFSSL_MSG(\"wolfSSL Using NO un-padding\");\n\n            /* In the case of no padding being used check that input is exactly\n             * the RSA key length */\n            if (bits <= 0 || pkcsBlockLen !=\n                         ((word32)(bits+WOLFSSL_BIT_SIZE-1)/WOLFSSL_BIT_SIZE)) {\n                WOLFSSL_MSG(\"Bad input size\");\n                ret = RSA_PAD_E;\n            }\n            else {\n                if (out != NULL) {\n                    *out = pkcsBlock;\n                }\n                ret = pkcsBlockLen;\n            }\n            break;\n    #endif /* WC_RSA_NO_PADDING */\n\n        default:\n            WOLFSSL_MSG(\"Unknown RSA UnPad Type\");\n            ret = RSA_PAD_E;\n    }\n\n    /* silence warning if not used with padding scheme */\n    (void)hType;\n    (void)mgf;\n    (void)optLabel;\n    (void)labelLen;\n    (void)saltLen;\n    (void)bits;\n    (void)heap;\n\n    return ret;\n}\n\n#if defined(WOLFSSL_XILINX_CRYPT)\n/*\n * Xilinx hardened crypto acceleration.\n *\n * Returns 0 on success and negative values on error.\n */\nstatic int wc_RsaFunctionXil(const byte* in, word32 inLen, byte* out,\n                          word32* outLen, int type, RsaKey* key, WC_RNG* rng)\n{\n    int    ret = 0;\n    word32 keyLen, len;\n    (void)rng;\n\n    keyLen = wc_RsaEncryptSize(key);\n    if (keyLen > *outLen) {\n        WOLFSSL_MSG(\"Output buffer is not big enough\");\n        return BAD_FUNC_ARG;\n    }\n\n    if (inLen != keyLen) {\n        WOLFSSL_MSG(\"Expected that inLen equals RSA key length\");\n        return BAD_FUNC_ARG;\n    }\n\n    switch(type) {\n    case RSA_PRIVATE_DECRYPT:\n    case RSA_PRIVATE_ENCRYPT:\n        /* Currently public exponent is loaded by default.\n         * In SDK 2017.1 RSA exponent values are expected to be of 4 bytes\n         * leading to private key operations with Xsecure_RsaDecrypt not being\n         * supported */\n        ret = RSA_WRONG_TYPE_E;\n        break;\n    case RSA_PUBLIC_ENCRYPT:\n    case RSA_PUBLIC_DECRYPT:\n        if (XSecure_RsaDecrypt(&(key->xRsa), in, out) != XST_SUCCESS) {\n            ret = BAD_STATE_E;\n        }\n        break;\n    default:\n        ret = RSA_WRONG_TYPE_E;\n    }\n\n    *outLen = keyLen;\n\n    return ret;\n}\n#endif /* WOLFSSL_XILINX_CRYPT */\n\n#ifdef WC_RSA_NONBLOCK\nstatic int wc_RsaFunctionNonBlock(const byte* in, word32 inLen, byte* out,\n                          word32* outLen, int type, RsaKey* key)\n{\n    int    ret = 0;\n    word32 keyLen, len;\n\n    if (key == NULL || key->nb == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (key->nb->exptmod.state == TFM_EXPTMOD_NB_INIT) {\n        if (mp_init(&key->nb->tmp) != MP_OKAY) {\n            ret = MP_INIT_E;\n        }\n\n        if (ret == 0) {\n            if (mp_read_unsigned_bin(&key->nb->tmp, (byte*)in, inLen) != MP_OKAY) {\n                ret = MP_READ_E;\n            }\n        }\n    }\n\n    if (ret == 0) {\n        switch(type) {\n        case RSA_PRIVATE_DECRYPT:\n        case RSA_PRIVATE_ENCRYPT:\n            ret = fp_exptmod_nb(&key->nb->exptmod, &key->nb->tmp, &key->d,\n                &key->n, &key->nb->tmp);\n            if (ret == FP_WOULDBLOCK)\n                return ret;\n            if (ret != MP_OKAY)\n                ret = MP_EXPTMOD_E;\n            break;\n\n        case RSA_PUBLIC_ENCRYPT:\n        case RSA_PUBLIC_DECRYPT:\n            ret = fp_exptmod_nb(&key->nb->exptmod, &key->nb->tmp, &key->e,\n                &key->n, &key->nb->tmp);\n            if (ret == FP_WOULDBLOCK)\n                return ret;\n            if (ret != MP_OKAY)\n                ret = MP_EXPTMOD_E;\n            break;\n        default:\n            ret = RSA_WRONG_TYPE_E;\n            break;\n        }\n    }\n\n    if (ret == 0) {\n        keyLen = wc_RsaEncryptSize(key);\n        if (keyLen > *outLen)\n            ret = RSA_BUFFER_E;\n    }\n    if (ret == 0) {\n        len = mp_unsigned_bin_size(&key->nb->tmp);\n\n        /* pad front w/ zeros to match key length */\n        while (len < keyLen) {\n            *out++ = 0x00;\n            len++;\n        }\n\n        *outLen = keyLen;\n\n        /* convert */\n        if (mp_to_unsigned_bin(&key->nb->tmp, out) != MP_OKAY) {\n             ret = MP_TO_E;\n        }\n    }\n\n    mp_clear(&key->nb->tmp);\n\n    return ret;\n}\n#endif /* WC_RSA_NONBLOCK */\n\n#ifdef WOLFSSL_AFALG_XILINX_RSA\n#ifndef ERROR_OUT\n#define ERROR_OUT(x) ret = (x); goto done\n#endif\n\nstatic const char WC_TYPE_ASYMKEY[] = \"skcipher\";\nstatic const char WC_NAME_RSA[] = \"xilinx-zynqmp-rsa\";\n#ifndef MAX_XILINX_RSA_KEY\n    /* max key size of 4096 bits / 512 bytes */\n    #define MAX_XILINX_RSA_KEY 512\n#endif\nstatic const byte XILINX_RSA_FLAG[] = {0x1};\n\n\n/* AF_ALG implementation of RSA */\nstatic int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,\n                          word32* outLen, int type, RsaKey* key, WC_RNG* rng)\n{\n    struct msghdr   msg;\n    struct cmsghdr* cmsg;\n    struct iovec      iov;\n    byte*  keyBuf   = NULL;\n    word32 keyBufSz = 0;\n    char cbuf[CMSG_SPACE(4) + CMSG_SPACE(sizeof(struct af_alg_iv) + 1)] = {0};\n    int    ret = 0;\n    int    op  = 0;    /* decryption vs encryption flag */\n    word32 keyLen;\n\n    /* input and output buffer need to be aligned */\n    ALIGN64 byte outBuf[MAX_XILINX_RSA_KEY];\n    ALIGN64 byte inBuf[MAX_XILINX_RSA_KEY];\n\n    XMEMSET(&msg, 0, sizeof(struct msghdr));\n    (void)rng;\n\n    keyLen = wc_RsaEncryptSize(key);\n    if (keyLen > *outLen) {\n        ERROR_OUT(RSA_BUFFER_E);\n    }\n\n    if (keyLen > MAX_XILINX_RSA_KEY) {\n        WOLFSSL_MSG(\"RSA key size larger than supported\");\n        ERROR_OUT(BAD_FUNC_ARG);\n    }\n\n    if ((keyBuf = (byte*)XMALLOC(keyLen * 2, key->heap, DYNAMIC_TYPE_KEY))\n            == NULL) {\n        ERROR_OUT(MEMORY_E);\n    }\n\n    if ((ret = mp_to_unsigned_bin(&(key->n), keyBuf)) != MP_OKAY) {\n        ERROR_OUT(MP_TO_E);\n    }\n\n    switch(type) {\n        case RSA_PRIVATE_DECRYPT:\n        case RSA_PRIVATE_ENCRYPT:\n            op = 1; /* set as decrypt */\n            {\n                keyBufSz = mp_unsigned_bin_size(&(key->d));\n                if ((mp_to_unsigned_bin(&(key->d), keyBuf + keyLen))\n                        != MP_OKAY) {\n                    ERROR_OUT(MP_TO_E);\n                }\n            }\n            break;\n\n        case RSA_PUBLIC_DECRYPT:\n        case RSA_PUBLIC_ENCRYPT: {\n            word32 exp = 0;\n            word32 eSz = mp_unsigned_bin_size(&(key->e));\n            if ((mp_to_unsigned_bin(&(key->e), (byte*)&exp +\n                            (sizeof(word32) - eSz))) != MP_OKAY) {\n                ERROR_OUT(MP_TO_E);\n            }\n            keyBufSz = sizeof(word32);\n            XMEMCPY(keyBuf + keyLen, (byte*)&exp, keyBufSz);\n            break;\n        }\n\n        default:\n            ERROR_OUT(RSA_WRONG_TYPE_E);\n    }\n    keyBufSz += keyLen; /* add size of modulus */\n\n    /* check for existing sockets before creating new ones */\n    if (key->alFd > 0) {\n        close(key->alFd);\n        key->alFd = WC_SOCK_NOTSET;\n    }\n    if (key->rdFd > 0) {\n        close(key->rdFd);\n        key->rdFd = WC_SOCK_NOTSET;\n    }\n\n    /* create new sockets and set the key to use */\n    if ((key->alFd = wc_Afalg_Socket()) < 0) {\n        WOLFSSL_MSG(\"Unable to create socket\");\n        ERROR_OUT(key->alFd);\n    }\n    if ((key->rdFd = wc_Afalg_CreateRead(key->alFd, WC_TYPE_ASYMKEY,\n                    WC_NAME_RSA)) < 0) {\n        WOLFSSL_MSG(\"Unable to bind and create read/send socket\");\n        ERROR_OUT(key->rdFd);\n    }\n    if ((ret = setsockopt(key->alFd, SOL_ALG, ALG_SET_KEY, keyBuf,\n                    keyBufSz)) < 0) {\n        WOLFSSL_MSG(\"Error setting RSA key\");\n        ERROR_OUT(ret);\n    }\n\n    msg.msg_control    = cbuf;\n    msg.msg_controllen = sizeof(cbuf);\n    cmsg = CMSG_FIRSTHDR(&msg);\n    if ((ret = wc_Afalg_SetOp(cmsg, op)) < 0) {\n        ERROR_OUT(ret);\n    }\n\n    /* set flag in IV spot, needed for Xilinx hardware acceleration use */\n    cmsg = CMSG_NXTHDR(&msg, cmsg);\n    if ((ret = wc_Afalg_SetIv(cmsg, (byte*)XILINX_RSA_FLAG,\n                    sizeof(XILINX_RSA_FLAG))) != 0) {\n        ERROR_OUT(ret);\n    }\n\n    /* compose and send msg */\n    XMEMCPY(inBuf, (byte*)in, inLen); /* for alignment */\n    iov.iov_base = inBuf;\n    iov.iov_len  = inLen;\n    msg.msg_iov  = &iov;\n    msg.msg_iovlen = 1;\n    if ((ret = sendmsg(key->rdFd, &msg, 0)) <= 0) {\n        ERROR_OUT(WC_AFALG_SOCK_E);\n    }\n\n    if ((ret = read(key->rdFd, outBuf, inLen)) <= 0) {\n        ERROR_OUT(WC_AFALG_SOCK_E);\n    }\n    XMEMCPY(out, outBuf, ret);\n    *outLen = keyLen;\n\ndone:\n    /* clear key data and free buffer */\n    if (keyBuf != NULL) {\n        ForceZero(keyBuf, keyBufSz);\n    }\n    XFREE(keyBuf, key->heap, DYNAMIC_TYPE_KEY);\n\n    if (key->alFd > 0) {\n        close(key->alFd);\n        key->alFd = WC_SOCK_NOTSET;\n    }\n    if (key->rdFd > 0) {\n        close(key->rdFd);\n        key->rdFd = WC_SOCK_NOTSET;\n    }\n\n    return ret;\n}\n\n#else\nstatic int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,\n                          word32* outLen, int type, RsaKey* key, WC_RNG* rng)\n{\n#ifndef WOLFSSL_SP_MATH\n#ifdef WOLFSSL_SMALL_STACK\n    mp_int* tmp = NULL;\n#ifdef WC_RSA_BLINDING\n    mp_int* rnd = NULL;\n    mp_int* rndi = NULL;\n#endif\n#else\n    mp_int tmp[1];\n#ifdef WC_RSA_BLINDING\n    mp_int rnd[1], rndi[1];\n#endif\n#endif\n    int    ret = 0;\n    word32 keyLen = 0;\n#endif\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n#ifndef WOLFSSL_SP_NO_2048\n    if (mp_count_bits(&key->n) == 2048) {\n        switch(type) {\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n        case RSA_PRIVATE_DECRYPT:\n        case RSA_PRIVATE_ENCRYPT:\n    #ifdef WC_RSA_BLINDING\n            if (rng == NULL)\n                return MISSING_RNG_E;\n    #endif\n    #ifndef RSA_LOW_MEM\n            return sp_RsaPrivate_2048(in, inLen, &key->d, &key->p, &key->q,\n                                      &key->dP, &key->dQ, &key->u, &key->n,\n                                      out, outLen);\n    #else\n            return sp_RsaPrivate_2048(in, inLen, &key->d, &key->p, &key->q,\n                                      NULL, NULL, NULL, &key->n, out, outLen);\n    #endif\n#endif\n        case RSA_PUBLIC_ENCRYPT:\n        case RSA_PUBLIC_DECRYPT:\n            return sp_RsaPublic_2048(in, inLen, &key->e, &key->n, out, outLen);\n        }\n    }\n#endif\n#ifndef WOLFSSL_SP_NO_3072\n    if (mp_count_bits(&key->n) == 3072) {\n        switch(type) {\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n        case RSA_PRIVATE_DECRYPT:\n        case RSA_PRIVATE_ENCRYPT:\n    #ifdef WC_RSA_BLINDING\n            if (rng == NULL)\n                return MISSING_RNG_E;\n    #endif\n    #ifndef RSA_LOW_MEM\n            return sp_RsaPrivate_3072(in, inLen, &key->d, &key->p, &key->q,\n                                      &key->dP, &key->dQ, &key->u, &key->n,\n                                      out, outLen);\n    #else\n            return sp_RsaPrivate_3072(in, inLen, &key->d, &key->p, &key->q,\n                                      NULL, NULL, NULL, &key->n, out, outLen);\n    #endif\n#endif\n        case RSA_PUBLIC_ENCRYPT:\n        case RSA_PUBLIC_DECRYPT:\n            return sp_RsaPublic_3072(in, inLen, &key->e, &key->n, out, outLen);\n        }\n    }\n#endif\n#ifdef WOLFSSL_SP_4096\n    if (mp_count_bits(&key->n) == 4096) {\n        switch(type) {\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n        case RSA_PRIVATE_DECRYPT:\n        case RSA_PRIVATE_ENCRYPT:\n    #ifdef WC_RSA_BLINDING\n            if (rng == NULL)\n                return MISSING_RNG_E;\n    #endif\n    #ifndef RSA_LOW_MEM\n            return sp_RsaPrivate_4096(in, inLen, &key->d, &key->p, &key->q,\n                                      &key->dP, &key->dQ, &key->u, &key->n,\n                                      out, outLen);\n    #else\n            return sp_RsaPrivate_4096(in, inLen, &key->d, &key->p, &key->q,\n                                      NULL, NULL, NULL, &key->n, out, outLen);\n    #endif\n#endif\n        case RSA_PUBLIC_ENCRYPT:\n        case RSA_PUBLIC_DECRYPT:\n            return sp_RsaPublic_4096(in, inLen, &key->e, &key->n, out, outLen);\n        }\n    }\n#endif\n#endif /* WOLFSSL_HAVE_SP_RSA */\n\n#ifdef WOLFSSL_SP_MATH\n    (void)rng;\n    WOLFSSL_MSG(\"SP Key Size Error\");\n    return WC_KEY_SIZE_E;\n#else\n    (void)rng;\n\n#ifdef WOLFSSL_SMALL_STACK\n    tmp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_RSA);\n    if (tmp == NULL)\n        return MEMORY_E;\n#ifdef WC_RSA_BLINDING\n    rnd = (mp_int*)XMALLOC(sizeof(mp_int) * 2, key->heap, DYNAMIC_TYPE_RSA);\n    if (rnd == NULL) {\n        XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);\n        return MEMORY_E;\n    }\n    rndi = rnd + 1;\n#endif /* WC_RSA_BLINDING */\n#endif /* WOLFSSL_SMALL_STACK */\n\n    if (mp_init(tmp) != MP_OKAY)\n        ret = MP_INIT_E;\n\n#ifdef WC_RSA_BLINDING\n    if (ret == 0) {\n        if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {\n            if (mp_init_multi(rnd, rndi, NULL, NULL, NULL, NULL) != MP_OKAY) {\n                mp_clear(tmp);\n                ret = MP_INIT_E;\n            }\n        }\n    }\n#endif\n\n#ifndef TEST_UNPAD_CONSTANT_TIME\n    if (ret == 0 && mp_read_unsigned_bin(tmp, (byte*)in, inLen) != MP_OKAY)\n        ret = MP_READ_E;\n\n    if (ret == 0) {\n        switch(type) {\n    #ifndef WOLFSSL_RSA_PUBLIC_ONLY\n        case RSA_PRIVATE_DECRYPT:\n        case RSA_PRIVATE_ENCRYPT:\n        {\n        #if defined(WC_RSA_BLINDING) && !defined(WC_NO_RNG)\n            /* blind */\n            ret = mp_rand(rnd, get_digit_count(&key->n), rng);\n\n            /* rndi = 1/rnd mod n */\n            if (ret == 0 && mp_invmod(rnd, &key->n, rndi) != MP_OKAY)\n                ret = MP_INVMOD_E;\n\n            /* rnd = rnd^e */\n            if (ret == 0 && mp_exptmod(rnd, &key->e, &key->n, rnd) != MP_OKAY)\n                ret = MP_EXPTMOD_E;\n\n            /* tmp = tmp*rnd mod n */\n            if (ret == 0 && mp_mulmod(tmp, rnd, &key->n, tmp) != MP_OKAY)\n                ret = MP_MULMOD_E;\n        #endif /* WC_RSA_BLINDING && !WC_NO_RNG */\n\n        #ifdef RSA_LOW_MEM      /* half as much memory but twice as slow */\n            if (ret == 0 && mp_exptmod(tmp, &key->d, &key->n, tmp) != MP_OKAY)\n                ret = MP_EXPTMOD_E;\n        #else\n            if (ret == 0) {\n            #ifdef WOLFSSL_SMALL_STACK\n                mp_int* tmpa = NULL;\n                mp_int* tmpb = NULL;\n            #else\n                mp_int tmpa[1], tmpb[1];\n            #endif\n                int cleara = 0, clearb = 0;\n\n            #ifdef WOLFSSL_SMALL_STACK\n                tmpa = (mp_int*)XMALLOC(sizeof(mp_int) * 2,\n                        key->heap, DYNAMIC_TYPE_RSA);\n                if (tmpa != NULL)\n                    tmpb = tmpa + 1;\n                else\n                    ret = MEMORY_E;\n            #endif\n\n                if (ret == 0) {\n                    if (mp_init(tmpa) != MP_OKAY)\n                        ret = MP_INIT_E;\n                    else\n                        cleara = 1;\n                }\n\n                if (ret == 0) {\n                    if (mp_init(tmpb) != MP_OKAY)\n                        ret = MP_INIT_E;\n                    else\n                        clearb = 1;\n                }\n\n                /* tmpa = tmp^dP mod p */\n                if (ret == 0 && mp_exptmod(tmp, &key->dP, &key->p,\n                                                               tmpa) != MP_OKAY)\n                    ret = MP_EXPTMOD_E;\n\n                /* tmpb = tmp^dQ mod q */\n                if (ret == 0 && mp_exptmod(tmp, &key->dQ, &key->q,\n                                                               tmpb) != MP_OKAY)\n                    ret = MP_EXPTMOD_E;\n\n                /* tmp = (tmpa - tmpb) * qInv (mod p) */\n                if (ret == 0 && mp_sub(tmpa, tmpb, tmp) != MP_OKAY)\n                    ret = MP_SUB_E;\n\n                if (ret == 0 && mp_mulmod(tmp, &key->u, &key->p,\n                                                                tmp) != MP_OKAY)\n                    ret = MP_MULMOD_E;\n\n                /* tmp = tmpb + q * tmp */\n                if (ret == 0 && mp_mul(tmp, &key->q, tmp) != MP_OKAY)\n                    ret = MP_MUL_E;\n\n                if (ret == 0 && mp_add(tmp, tmpb, tmp) != MP_OKAY)\n                    ret = MP_ADD_E;\n\n            #ifdef WOLFSSL_SMALL_STACK\n                if (tmpa != NULL)\n            #endif\n                {\n                    if (cleara)\n                        mp_clear(tmpa);\n                    if (clearb)\n                        mp_clear(tmpb);\n            #ifdef WOLFSSL_SMALL_STACK\n                    XFREE(tmpa, key->heap, DYNAMIC_TYPE_RSA);\n            #endif\n                }\n            } /* tmpa/b scope */\n        #endif   /* RSA_LOW_MEM */\n\n        #ifdef WC_RSA_BLINDING\n            /* unblind */\n            if (ret == 0 && mp_mulmod(tmp, rndi, &key->n, tmp) != MP_OKAY)\n                ret = MP_MULMOD_E;\n        #endif   /* WC_RSA_BLINDING */\n\n            break;\n        }\n    #endif\n        case RSA_PUBLIC_ENCRYPT:\n        case RSA_PUBLIC_DECRYPT:\n        #ifdef WOLFSSL_XILINX_CRYPT\n            ret = wc_RsaFunctionXil(in, inLen, out, outLen, type, key, rng);\n        #else\n            if (mp_exptmod(tmp, &key->e, &key->n, tmp) != MP_OKAY)\n                ret = MP_EXPTMOD_E;\n            break;\n        #endif\n        default:\n            ret = RSA_WRONG_TYPE_E;\n            break;\n        }\n    }\n\n    if (ret == 0) {\n        keyLen = wc_RsaEncryptSize(key);\n        if (keyLen > *outLen)\n            ret = RSA_BUFFER_E;\n    }\n    if (ret == 0) {\n        *outLen = keyLen;\n        if (mp_to_unsigned_bin_len(tmp, out, keyLen) != MP_OKAY)\n             ret = MP_TO_E;\n    }\n#else\n    (void)type;\n    (void)key;\n    (void)keyLen;\n    XMEMCPY(out, in, inLen);\n    *outLen = inLen;\n#endif\n\n    mp_clear(tmp);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);\n#endif\n#ifdef WC_RSA_BLINDING\n    if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {\n        mp_clear(rndi);\n        mp_clear(rnd);\n    }\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(rnd, key->heap, DYNAMIC_TYPE_RSA);\n#endif\n#endif /* WC_RSA_BLINDING */\n    return ret;\n#endif /* WOLFSSL_SP_MATH */\n}\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)\nstatic int wc_RsaFunctionAsync(const byte* in, word32 inLen, byte* out,\n                          word32* outLen, int type, RsaKey* key, WC_RNG* rng)\n{\n    int ret = 0;\n\n    (void)rng;\n\n#ifdef WOLFSSL_ASYNC_CRYPT_TEST\n    if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_RSA_FUNC)) {\n        WC_ASYNC_TEST* testDev = &key->asyncDev.test;\n        testDev->rsaFunc.in = in;\n        testDev->rsaFunc.inSz = inLen;\n        testDev->rsaFunc.out = out;\n        testDev->rsaFunc.outSz = outLen;\n        testDev->rsaFunc.type = type;\n        testDev->rsaFunc.key = key;\n        testDev->rsaFunc.rng = rng;\n        return WC_PENDING_E;\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT_TEST */\n\n    switch(type) {\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n    case RSA_PRIVATE_DECRYPT:\n    case RSA_PRIVATE_ENCRYPT:\n    #ifdef HAVE_CAVIUM\n        key->dataLen = key->n.raw.len;\n        ret = NitroxRsaExptMod(in, inLen,\n                               key->d.raw.buf, key->d.raw.len,\n                               key->n.raw.buf, key->n.raw.len,\n                               out, outLen, key);\n    #elif defined(HAVE_INTEL_QA)\n        #ifdef RSA_LOW_MEM\n            ret = IntelQaRsaPrivate(&key->asyncDev, in, inLen,\n                                    &key->d.raw, &key->n.raw,\n                                    out, outLen);\n        #else\n            ret = IntelQaRsaCrtPrivate(&key->asyncDev, in, inLen,\n                                &key->p.raw, &key->q.raw,\n                                &key->dP.raw, &key->dQ.raw,\n                                &key->u.raw,\n                                out, outLen);\n        #endif\n    #else /* WOLFSSL_ASYNC_CRYPT_TEST */\n        ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng);\n    #endif\n        break;\n#endif\n\n    case RSA_PUBLIC_ENCRYPT:\n    case RSA_PUBLIC_DECRYPT:\n    #ifdef HAVE_CAVIUM\n        key->dataLen = key->n.raw.len;\n        ret = NitroxRsaExptMod(in, inLen,\n                               key->e.raw.buf, key->e.raw.len,\n                               key->n.raw.buf, key->n.raw.len,\n                               out, outLen, key);\n    #elif defined(HAVE_INTEL_QA)\n        ret = IntelQaRsaPublic(&key->asyncDev, in, inLen,\n                               &key->e.raw, &key->n.raw,\n                               out, outLen);\n    #else /* WOLFSSL_ASYNC_CRYPT_TEST */\n        ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng);\n    #endif\n        break;\n\n    default:\n        ret = RSA_WRONG_TYPE_E;\n    }\n\n    return ret;\n}\n#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_RSA */\n\n#if defined(WC_RSA_DIRECT) || defined(WC_RSA_NO_PADDING)\n/* Function that does the RSA operation directly with no padding.\n *\n * in       buffer to do operation on\n * inLen    length of input buffer\n * out      buffer to hold results\n * outSz    gets set to size of result buffer. Should be passed in as length\n *          of out buffer. If the pointer \"out\" is null then outSz gets set to\n *          the expected buffer size needed and LENGTH_ONLY_E gets returned.\n * key      RSA key to use for encrypt/decrypt\n * type     if using private or public key {RSA_PUBLIC_ENCRYPT,\n *          RSA_PUBLIC_DECRYPT, RSA_PRIVATE_ENCRYPT, RSA_PRIVATE_DECRYPT}\n * rng      wolfSSL RNG to use if needed\n *\n * returns size of result on success\n */\nint wc_RsaDirect(byte* in, word32 inLen, byte* out, word32* outSz,\n        RsaKey* key, int type, WC_RNG* rng)\n{\n    int ret;\n\n    if (in == NULL || outSz == NULL || key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* sanity check on type of RSA operation */\n    switch (type) {\n        case RSA_PUBLIC_ENCRYPT:\n        case RSA_PUBLIC_DECRYPT:\n        case RSA_PRIVATE_ENCRYPT:\n        case RSA_PRIVATE_DECRYPT:\n            break;\n        default:\n            WOLFSSL_MSG(\"Bad RSA type\");\n            return BAD_FUNC_ARG;\n    }\n\n    if ((ret = wc_RsaEncryptSize(key)) < 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (inLen != (word32)ret) {\n        WOLFSSL_MSG(\"Bad input length. Should be RSA key size\");\n        return BAD_FUNC_ARG;\n    }\n\n    if (out == NULL) {\n        *outSz = inLen;\n        return LENGTH_ONLY_E;\n    }\n\n    switch (key->state) {\n        case RSA_STATE_NONE:\n        case RSA_STATE_ENCRYPT_PAD:\n        case RSA_STATE_ENCRYPT_EXPTMOD:\n        case RSA_STATE_DECRYPT_EXPTMOD:\n        case RSA_STATE_DECRYPT_UNPAD:\n            key->state = (type == RSA_PRIVATE_ENCRYPT ||\n                    type == RSA_PUBLIC_ENCRYPT) ? RSA_STATE_ENCRYPT_EXPTMOD:\n                                                  RSA_STATE_DECRYPT_EXPTMOD;\n\n            key->dataLen = *outSz;\n\n            ret = wc_RsaFunction(in, inLen, out, &key->dataLen, type, key, rng);\n            if (ret >= 0 || ret == WC_PENDING_E) {\n                key->state = (type == RSA_PRIVATE_ENCRYPT ||\n                    type == RSA_PUBLIC_ENCRYPT) ? RSA_STATE_ENCRYPT_RES:\n                                                  RSA_STATE_DECRYPT_RES;\n            }\n            if (ret < 0) {\n                break;\n            }\n\n            FALL_THROUGH;\n\n        case RSA_STATE_ENCRYPT_RES:\n        case RSA_STATE_DECRYPT_RES:\n            ret = key->dataLen;\n            break;\n\n        default:\n            ret = BAD_STATE_E;\n    }\n\n    /* if async pending then skip cleanup*/\n    if (ret == WC_PENDING_E\n    #ifdef WC_RSA_NONBLOCK\n        || ret == FP_WOULDBLOCK\n    #endif\n    ) {\n        return ret;\n    }\n\n    key->state = RSA_STATE_NONE;\n    wc_RsaCleanup(key);\n\n    return ret;\n}\n#endif /* WC_RSA_DIRECT || WC_RSA_NO_PADDING */\n\n#if defined(WOLFSSL_CRYPTOCELL)\nstatic int cc310_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out,\n                            word32 outLen, RsaKey* key)\n{\n    CRYSError_t ret = 0;\n    CRYS_RSAPrimeData_t primeData;\n    int modulusSize = wc_RsaEncryptSize(key);\n\n    /* The out buffer must be at least modulus size bytes long. */\n    if (outLen < modulusSize)\n        return BAD_FUNC_ARG;\n\n    ret = CRYS_RSA_PKCS1v15_Encrypt(&wc_rndState,\n                                    wc_rndGenVectFunc,\n                                    &key->ctx.pubKey,\n                                    &primeData,\n                                    (byte*)in,\n                                    inLen,\n                                    out);\n\n    if (ret != SA_SILIB_RET_OK){\n        WOLFSSL_MSG(\"CRYS_RSA_PKCS1v15_Encrypt failed\");\n        return -1;\n    }\n\n    return modulusSize;\n}\nstatic int cc310_RsaPublicDecrypt(const byte* in, word32 inLen, byte* out,\n                            word32 outLen, RsaKey* key)\n{\n    CRYSError_t ret = 0;\n    CRYS_RSAPrimeData_t primeData;\n    uint16_t actualOutLen = outLen;\n\n    ret = CRYS_RSA_PKCS1v15_Decrypt(&key->ctx.privKey,\n                                    &primeData,\n                                    (byte*)in,\n                                    inLen,\n                                    out,\n                                    &actualOutLen);\n\n    if (ret != SA_SILIB_RET_OK){\n        WOLFSSL_MSG(\"CRYS_RSA_PKCS1v15_Decrypt failed\");\n        return -1;\n    }\n    return actualOutLen;\n}\n\nstatic int cc310_RsaSSL_Sign(const byte* in, word32 inLen, byte* out,\n                            word32 outLen, RsaKey* key, enum wc_HashType hash)\n{\n    CRYSError_t ret = 0;\n    uint16_t actualOutLen = outLen*sizeof(byte);\n    CRYS_RSAPrivUserContext_t  contextPrivate;\n    CRYS_RSA_HASH_OpMode_t mode = cc310_hashModeRSA(hash);\n\n    if (mode == CRYS_RSA_After_HASH_NOT_KNOWN_mode) {\n        mode = CRYS_RSA_HASH_SHA256_mode;\n    }\n\n    ret =  CRYS_RSA_PKCS1v15_Sign(&wc_rndState,\n                wc_rndGenVectFunc,\n                &contextPrivate,\n                &key->ctx.privKey,\n                mode,\n                (byte*)in,\n                inLen,\n                out,\n                &actualOutLen);\n\n    if (ret != SA_SILIB_RET_OK){\n        WOLFSSL_MSG(\"CRYS_RSA_PKCS1v15_Sign failed\");\n        return -1;\n    }\n    return actualOutLen;\n}\n\nstatic int cc310_RsaSSL_Verify(const byte* in, word32 inLen, byte* sig,\n                               RsaKey* key, enum wc_HashType hash)\n{\n    CRYSError_t ret = 0;\n    CRYS_RSAPubUserContext_t contextPub;\n    CRYS_RSA_HASH_OpMode_t mode = cc310_hashModeRSA(hash);\n\n    if (mode == CRYS_RSA_After_HASH_NOT_KNOWN_mode) {\n        mode = CRYS_RSA_HASH_SHA256_mode;\n    }\n    /* verify the signature in the sig pointer */\n    ret =  CRYS_RSA_PKCS1v15_Verify(&contextPub,\n                &key->ctx.pubKey,\n                mode,\n                (byte*)in,\n                inLen,\n                sig);\n\n    if (ret != SA_SILIB_RET_OK){\n        WOLFSSL_MSG(\"CRYS_RSA_PKCS1v15_Verify failed\");\n        return -1;\n    }\n\n    return ret;\n}\n#endif /* WOLFSSL_CRYPTOCELL */\n\nint wc_RsaFunction(const byte* in, word32 inLen, byte* out,\n                          word32* outLen, int type, RsaKey* key, WC_RNG* rng)\n{\n    int ret = 0;\n\n    if (key == NULL || in == NULL || inLen == 0 || out == NULL ||\n            outLen == NULL || *outLen == 0 || type == RSA_TYPE_UNKNOWN) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLF_CRYPTO_CB\n    if (key->devId != INVALID_DEVID) {\n        ret = wc_CryptoCb_Rsa(in, inLen, out, outLen, type, key, rng);\n        if (ret != CRYPTOCB_UNAVAILABLE)\n            return ret;\n        /* fall-through when unavailable */\n        ret = 0; /* reset error code and try using software */\n    }\n#endif\n\n#ifndef TEST_UNPAD_CONSTANT_TIME\n#ifndef NO_RSA_BOUNDS_CHECK\n    if (type == RSA_PRIVATE_DECRYPT &&\n        key->state == RSA_STATE_DECRYPT_EXPTMOD) {\n\n        /* Check that 1 < in < n-1. (Requirement of 800-56B.) */\n#ifdef WOLFSSL_SMALL_STACK\n        mp_int* c = NULL;\n#else\n        mp_int c[1];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n        c = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_RSA);\n        if (c == NULL)\n            ret = MEMORY_E;\n#endif\n\n        if (mp_init(c) != MP_OKAY)\n            ret = MEMORY_E;\n        if (ret == 0) {\n            if (mp_read_unsigned_bin(c, in, inLen) != 0)\n                ret = MP_READ_E;\n        }\n        if (ret == 0) {\n            /* check c > 1 */\n            if (mp_cmp_d(c, 1) != MP_GT)\n                ret = RSA_OUT_OF_RANGE_E;\n        }\n        if (ret == 0) {\n            /* add c+1 */\n            if (mp_add_d(c, 1, c) != MP_OKAY)\n                ret = MP_ADD_E;\n        }\n        if (ret == 0) {\n            /* check c+1 < n */\n            if (mp_cmp(c, &key->n) != MP_LT)\n                ret = RSA_OUT_OF_RANGE_E;\n        }\n        mp_clear(c);\n\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(c, key->heap, DYNAMIC_TYPE_RSA);\n#endif\n\n        if (ret != 0)\n            return ret;\n    }\n#endif /* NO_RSA_BOUNDS_CHECK */\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)\n    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&\n                                                        key->n.raw.len > 0) {\n        ret = wc_RsaFunctionAsync(in, inLen, out, outLen, type, key, rng);\n    }\n    else\n#endif\n#ifdef WC_RSA_NONBLOCK\n    if (key->nb) {\n        ret = wc_RsaFunctionNonBlock(in, inLen, out, outLen, type, key);\n    }\n    else\n#endif\n    {\n        ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng);\n    }\n\n    /* handle error */\n    if (ret < 0 && ret != WC_PENDING_E\n    #ifdef WC_RSA_NONBLOCK\n        && ret != FP_WOULDBLOCK\n    #endif\n    ) {\n        if (ret == MP_EXPTMOD_E) {\n            /* This can happen due to incorrectly set FP_MAX_BITS or missing XREALLOC */\n            WOLFSSL_MSG(\"RSA_FUNCTION MP_EXPTMOD_E: memory/config problem\");\n        }\n\n        key->state = RSA_STATE_NONE;\n        wc_RsaCleanup(key);\n    }\n\n    return ret;\n}\n\n\n#ifndef WOLFSSL_RSA_VERIFY_ONLY\n/* Internal Wrappers */\n/* Gives the option of choosing padding type\n   in : input to be encrypted\n   inLen: length of input buffer\n   out: encrypted output\n   outLen: length of encrypted output buffer\n   key   : wolfSSL initialized RSA key struct\n   rng   : wolfSSL initialized random number struct\n   rsa_type  : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT,\n        RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT\n   pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2\n   pad_type  : type of padding: WC_RSA_PKCSV15_PAD, WC_RSA_OAEP_PAD,\n        WC_RSA_NO_PAD or WC_RSA_PSS_PAD\n   hash  : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h\n   mgf   : type of mask generation function to use\n   label : optional label\n   labelSz : size of optional label buffer\n   saltLen : Length of salt used in PSS\n   rng : random number generator */\nstatic int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,\n                            word32 outLen, RsaKey* key, int rsa_type,\n                            byte pad_value, int pad_type,\n                            enum wc_HashType hash, int mgf,\n                            byte* label, word32 labelSz, int saltLen,\n                            WC_RNG* rng)\n{\n    int ret, sz;\n\n    if (in == NULL || inLen == 0 || out == NULL || key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    sz = wc_RsaEncryptSize(key);\n    if (sz > (int)outLen) {\n        return RSA_BUFFER_E;\n    }\n\n    if (sz < RSA_MIN_PAD_SZ) {\n        return WC_KEY_SIZE_E;\n    }\n\n    if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) {\n#ifdef WC_RSA_NO_PADDING\n        /* In the case that no padding is used the input length can and should\n         * be the same size as the RSA key. */\n        if (pad_type != WC_RSA_NO_PAD)\n#endif\n        return RSA_BUFFER_E;\n    }\n\n    switch (key->state) {\n    case RSA_STATE_NONE:\n    case RSA_STATE_ENCRYPT_PAD:\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \\\n            defined(HAVE_CAVIUM)\n        if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&\n                                 pad_type != WC_RSA_PSS_PAD && key->n.raw.buf) {\n            /* Async operations that include padding */\n            if (rsa_type == RSA_PUBLIC_ENCRYPT &&\n                                                pad_value == RSA_BLOCK_TYPE_2) {\n                key->state = RSA_STATE_ENCRYPT_RES;\n                key->dataLen = key->n.raw.len;\n                return NitroxRsaPublicEncrypt(in, inLen, out, outLen, key);\n            }\n            else if (rsa_type == RSA_PRIVATE_ENCRYPT &&\n                                                pad_value == RSA_BLOCK_TYPE_1) {\n                key->state = RSA_STATE_ENCRYPT_RES;\n                key->dataLen = key->n.raw.len;\n                return NitroxRsaSSL_Sign(in, inLen, out, outLen, key);\n            }\n        }\n    #elif defined(WOLFSSL_CRYPTOCELL)\n        if (rsa_type == RSA_PUBLIC_ENCRYPT &&\n                                            pad_value == RSA_BLOCK_TYPE_2) {\n\n            return cc310_RsaPublicEncrypt(in, inLen, out, outLen, key);\n        }\n        else if (rsa_type == RSA_PRIVATE_ENCRYPT &&\n                                         pad_value == RSA_BLOCK_TYPE_1) {\n         return cc310_RsaSSL_Sign(in, inLen, out, outLen, key, hash);\n        }\n    #endif /* WOLFSSL_CRYPTOCELL */\n\n        key->state = RSA_STATE_ENCRYPT_PAD;\n        ret = wc_RsaPad_ex(in, inLen, out, sz, pad_value, rng, pad_type, hash,\n                           mgf, label, labelSz, saltLen, mp_count_bits(&key->n),\n                           key->heap);\n        if (ret < 0) {\n            break;\n        }\n\n        key->state = RSA_STATE_ENCRYPT_EXPTMOD;\n        FALL_THROUGH;\n\n    case RSA_STATE_ENCRYPT_EXPTMOD:\n\n        key->dataLen = outLen;\n        ret = wc_RsaFunction(out, sz, out, &key->dataLen, rsa_type, key, rng);\n\n        if (ret >= 0 || ret == WC_PENDING_E) {\n            key->state = RSA_STATE_ENCRYPT_RES;\n        }\n        if (ret < 0) {\n            break;\n        }\n\n        FALL_THROUGH;\n\n    case RSA_STATE_ENCRYPT_RES:\n        ret = key->dataLen;\n        break;\n\n    default:\n        ret = BAD_STATE_E;\n        break;\n    }\n\n    /* if async pending then return and skip done cleanup below */\n    if (ret == WC_PENDING_E\n    #ifdef WC_RSA_NONBLOCK\n        || ret == FP_WOULDBLOCK\n    #endif\n    ) {\n        return ret;\n    }\n\n    key->state = RSA_STATE_NONE;\n    wc_RsaCleanup(key);\n\n    return ret;\n}\n\n#endif\n\n/* Gives the option of choosing padding type\n   in : input to be decrypted\n   inLen: length of input buffer\n   out:  decrypted message\n   outLen: length of decrypted message in bytes\n   outPtr: optional inline output pointer (if provided doing inline)\n   key   : wolfSSL initialized RSA key struct\n   rsa_type  : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT,\n        RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT\n   pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2\n   pad_type  : type of padding: WC_RSA_PKCSV15_PAD, WC_RSA_OAEP_PAD,\n        WC_RSA_NO_PAD, WC_RSA_PSS_PAD\n   hash  : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h\n   mgf   : type of mask generation function to use\n   label : optional label\n   labelSz : size of optional label buffer\n   saltLen : Length of salt used in PSS\n   rng : random number generator */\nstatic int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out,\n                            word32 outLen, byte** outPtr, RsaKey* key,\n                            int rsa_type, byte pad_value, int pad_type,\n                            enum wc_HashType hash, int mgf,\n                            byte* label, word32 labelSz, int saltLen,\n                            WC_RNG* rng)\n{\n    int ret = RSA_WRONG_TYPE_E;\n\n    if (in == NULL || inLen == 0 || out == NULL || key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    switch (key->state) {\n    case RSA_STATE_NONE:\n        key->dataLen = inLen;\n\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \\\n            defined(HAVE_CAVIUM)\n        /* Async operations that include padding */\n        if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&\n                                                   pad_type != WC_RSA_PSS_PAD) {\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n            if (rsa_type == RSA_PRIVATE_DECRYPT &&\n                                                pad_value == RSA_BLOCK_TYPE_2) {\n                key->state = RSA_STATE_DECRYPT_RES;\n                key->data = NULL;\n                return NitroxRsaPrivateDecrypt(in, inLen, out, &key->dataLen,\n                                               key);\n#endif\n            }\n            else if (rsa_type == RSA_PUBLIC_DECRYPT &&\n                                                pad_value == RSA_BLOCK_TYPE_1) {\n                key->state = RSA_STATE_DECRYPT_RES;\n                key->data = NULL;\n                return NitroxRsaSSL_Verify(in, inLen, out, &key->dataLen, key);\n            }\n        }\n    #elif defined(WOLFSSL_CRYPTOCELL)\n        if (rsa_type == RSA_PRIVATE_DECRYPT &&\n                                            pad_value == RSA_BLOCK_TYPE_2) {\n            ret = cc310_RsaPublicDecrypt(in, inLen, out, outLen, key);\n            if (outPtr != NULL)\n                *outPtr = out; /* for inline */\n            return ret;\n        }\n        else if (rsa_type == RSA_PUBLIC_DECRYPT &&\n                                            pad_value == RSA_BLOCK_TYPE_1) {\n            return cc310_RsaSSL_Verify(in, inLen, out, key, hash);\n        }\n    #endif /* WOLFSSL_CRYPTOCELL */\n\n\n#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE)\n        /* verify the tmp ptr is NULL, otherwise indicates bad state */\n        if (key->data != NULL) {\n            ret = BAD_STATE_E;\n            break;\n        }\n\n        /* if not doing this inline then allocate a buffer for it */\n        if (outPtr == NULL) {\n            key->data = (byte*)XMALLOC(inLen, key->heap,\n                                                      DYNAMIC_TYPE_WOLF_BIGINT);\n            key->dataIsAlloc = 1;\n            if (key->data == NULL) {\n                ret = MEMORY_E;\n                break;\n            }\n            XMEMCPY(key->data, in, inLen);\n        }\n        else {\n            key->data = out;\n        }\n#endif\n\n        key->state = RSA_STATE_DECRYPT_EXPTMOD;\n        FALL_THROUGH;\n\n    case RSA_STATE_DECRYPT_EXPTMOD:\n#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE)\n        ret = wc_RsaFunction(key->data, inLen, key->data, &key->dataLen,\n                                                            rsa_type, key, rng);\n#else\n        ret = wc_RsaFunction(in, inLen, out, &key->dataLen, rsa_type, key, rng);\n#endif\n\n        if (ret >= 0 || ret == WC_PENDING_E) {\n            key->state = RSA_STATE_DECRYPT_UNPAD;\n        }\n        if (ret < 0) {\n            break;\n        }\n\n        FALL_THROUGH;\n\n    case RSA_STATE_DECRYPT_UNPAD:\n    {\n        byte* pad = NULL;\n#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE)\n        ret = wc_RsaUnPad_ex(key->data, key->dataLen, &pad, pad_value, pad_type,\n                             hash, mgf, label, labelSz, saltLen,\n                             mp_count_bits(&key->n), key->heap);\n#else\n        ret = wc_RsaUnPad_ex(out, key->dataLen, &pad, pad_value, pad_type, hash,\n                             mgf, label, labelSz, saltLen,\n                             mp_count_bits(&key->n), key->heap);\n#endif\n        if (rsa_type == RSA_PUBLIC_DECRYPT && ret > (int)outLen)\n            ret = RSA_BUFFER_E;\n        else if (ret >= 0 && pad != NULL) {\n#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE)\n            signed char c;\n#endif\n\n            /* only copy output if not inline */\n            if (outPtr == NULL) {\n#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE)\n                word32 i, j;\n                int start = (int)((size_t)pad - (size_t)key->data);\n\n                for (i = 0, j = 0; j < key->dataLen; j++) {\n                    out[i] = key->data[j];\n                    c  = ctMaskGTE(j, start);\n                    c &= ctMaskLT(i, outLen);\n                    /* 0 - no add, -1 add */\n                    i += (word32)((byte)(-c));\n                }\n#else\n                XMEMCPY(out, pad, ret);\n#endif\n            }\n            else\n                *outPtr = pad;\n\n#if !defined(WOLFSSL_RSA_VERIFY_ONLY)\n            ret = ctMaskSelInt(ctMaskLTE(ret, outLen), ret, RSA_BUFFER_E);\n            ret = ctMaskSelInt(ctMaskNotEq(ret, 0), ret, RSA_BUFFER_E);\n#else\n            if (outLen < (word32)ret)\n                ret = RSA_BUFFER_E;\n#endif\n        }\n\n        key->state = RSA_STATE_DECRYPT_RES;\n\n        FALL_THROUGH;\n    }\n    case RSA_STATE_DECRYPT_RES:\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \\\n            defined(HAVE_CAVIUM)\n        if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&\n                                                   pad_type != WC_RSA_PSS_PAD) {\n            if (ret > 0) {\n                /* convert result */\n                byte* dataLen = (byte*)&key->dataLen;\n                ret = (dataLen[0] << 8) | (dataLen[1]);\n\n                if (outPtr)\n                    *outPtr = in;\n            }\n        }\n    #endif\n        break;\n\n    default:\n        ret = BAD_STATE_E;\n        break;\n    }\n\n    /* if async pending then return and skip done cleanup below */\n    if (ret == WC_PENDING_E\n    #ifdef WC_RSA_NONBLOCK\n        || ret == FP_WOULDBLOCK\n    #endif\n    ) {\n        return ret;\n    }\n\n    key->state = RSA_STATE_NONE;\n    wc_RsaCleanup(key);\n\n    return ret;\n}\n\n\n#ifndef WOLFSSL_RSA_VERIFY_ONLY\n/* Public RSA Functions */\nint wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,\n                                                     RsaKey* key, WC_RNG* rng)\n{\n    return RsaPublicEncryptEx(in, inLen, out, outLen, key,\n        RSA_PUBLIC_ENCRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD,\n        WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng);\n}\n\n\n#if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_NO_PADDING)\nint wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out,\n                    word32 outLen, RsaKey* key, WC_RNG* rng, int type,\n                    enum wc_HashType hash, int mgf, byte* label,\n                    word32 labelSz)\n{\n    return RsaPublicEncryptEx(in, inLen, out, outLen, key, RSA_PUBLIC_ENCRYPT,\n        RSA_BLOCK_TYPE_2, type, hash, mgf, label, labelSz, 0, rng);\n}\n#endif /* WC_NO_RSA_OAEP */\n#endif\n\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\nint wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)\n{\n    WC_RNG* rng = NULL;\n#ifdef WC_RSA_BLINDING\n    rng = key->rng;\n#endif\n    return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,\n        RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD,\n        WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng);\n}\n\n\n#ifndef WC_NO_RSA_OAEP\nint wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen, byte** out,\n                                  RsaKey* key, int type, enum wc_HashType hash,\n                                  int mgf, byte* label, word32 labelSz)\n{\n    WC_RNG* rng = NULL;\n#ifdef WC_RSA_BLINDING\n    rng = key->rng;\n#endif\n    return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,\n        RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash,\n        mgf, label, labelSz, 0, rng);\n}\n#endif /* WC_NO_RSA_OAEP */\n\n\nint wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,\n                                                 word32 outLen, RsaKey* key)\n{\n    WC_RNG* rng = NULL;\n#ifdef WC_RSA_BLINDING\n    rng = key->rng;\n#endif\n    return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,\n        RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD,\n        WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng);\n}\n\n#if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_NO_PADDING)\nint wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, byte* out,\n                            word32 outLen, RsaKey* key, int type,\n                            enum wc_HashType hash, int mgf, byte* label,\n                            word32 labelSz)\n{\n    WC_RNG* rng = NULL;\n#ifdef WC_RSA_BLINDING\n    rng = key->rng;\n#endif\n    return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,\n        RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash, mgf, label,\n        labelSz, 0, rng);\n}\n#endif /* WC_NO_RSA_OAEP || WC_RSA_NO_PADDING */\n#endif /* WOLFSSL_RSA_PUBLIC_ONLY */\n\n\nint wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)\n{\n    WC_RNG* rng = NULL;\n#ifdef WC_RSA_BLINDING\n    rng = key->rng;\n#endif\n    return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,\n        RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,\n        WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng);\n}\n\n#ifndef WOLFSSL_RSA_VERIFY_ONLY\nint wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,\n                                                                 RsaKey* key)\n{\n    WC_RNG* rng;\n\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    rng = NULL;\n#ifdef WC_RSA_BLINDING\n    rng = key->rng;\n#endif\n\n    return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,\n        RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,\n        WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng);\n}\n#endif\n\n#ifdef WC_RSA_PSS\n/* Verify the message signed with RSA-PSS.\n * The input buffer is reused for the output buffer.\n * Salt length is equal to hash length.\n *\n * in     Buffer holding encrypted data.\n * inLen  Length of data in buffer.\n * out    Pointer to address containing the PSS data.\n * hash   Hash algorithm.\n * mgf    Mask generation function.\n * key    Public RSA key.\n * returns the length of the PSS data on success and negative indicates failure.\n */\nint wc_RsaPSS_VerifyInline(byte* in, word32 inLen, byte** out,\n                           enum wc_HashType hash, int mgf, RsaKey* key)\n{\n#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER\n    return wc_RsaPSS_VerifyInline_ex(in, inLen, out, hash, mgf,\n                                                 RSA_PSS_SALT_LEN_DEFAULT, key);\n#else\n    return wc_RsaPSS_VerifyInline_ex(in, inLen, out, hash, mgf,\n                                                RSA_PSS_SALT_LEN_DISCOVER, key);\n#endif\n}\n\n/* Verify the message signed with RSA-PSS.\n * The input buffer is reused for the output buffer.\n *\n * in       Buffer holding encrypted data.\n * inLen    Length of data in buffer.\n * out      Pointer to address containing the PSS data.\n * hash     Hash algorithm.\n * mgf      Mask generation function.\n * key      Public RSA key.\n * saltLen  Length of salt used. RSA_PSS_SALT_LEN_DEFAULT (-1) indicates salt\n *          length is the same as the hash length. RSA_PSS_SALT_LEN_DISCOVER\n *          indicates salt length is determined from the data.\n * returns the length of the PSS data on success and negative indicates failure.\n */\nint wc_RsaPSS_VerifyInline_ex(byte* in, word32 inLen, byte** out,\n                              enum wc_HashType hash, int mgf, int saltLen,\n                              RsaKey* key)\n{\n    WC_RNG* rng = NULL;\n#ifdef WC_RSA_BLINDING\n    rng = key->rng;\n#endif\n    return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,\n        RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD,\n        hash, mgf, NULL, 0, saltLen, rng);\n}\n\n/* Verify the message signed with RSA-PSS.\n * Salt length is equal to hash length.\n *\n * in     Buffer holding encrypted data.\n * inLen  Length of data in buffer.\n * out    Pointer to address containing the PSS data.\n * hash   Hash algorithm.\n * mgf    Mask generation function.\n * key    Public RSA key.\n * returns the length of the PSS data on success and negative indicates failure.\n */\nint wc_RsaPSS_Verify(byte* in, word32 inLen, byte* out, word32 outLen,\n                     enum wc_HashType hash, int mgf, RsaKey* key)\n{\n#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER\n    return wc_RsaPSS_Verify_ex(in, inLen, out, outLen, hash, mgf,\n                                                 RSA_PSS_SALT_LEN_DEFAULT, key);\n#else\n    return wc_RsaPSS_Verify_ex(in, inLen, out, outLen, hash, mgf,\n                                                RSA_PSS_SALT_LEN_DISCOVER, key);\n#endif\n}\n\n/* Verify the message signed with RSA-PSS.\n *\n * in       Buffer holding encrypted data.\n * inLen    Length of data in buffer.\n * out      Pointer to address containing the PSS data.\n * hash     Hash algorithm.\n * mgf      Mask generation function.\n * key      Public RSA key.\n * saltLen  Length of salt used. RSA_PSS_SALT_LEN_DEFAULT (-1) indicates salt\n *          length is the same as the hash length. RSA_PSS_SALT_LEN_DISCOVER\n *          indicates salt length is determined from the data.\n * returns the length of the PSS data on success and negative indicates failure.\n */\nint wc_RsaPSS_Verify_ex(byte* in, word32 inLen, byte* out, word32 outLen,\n                        enum wc_HashType hash, int mgf, int saltLen,\n                        RsaKey* key)\n{\n    WC_RNG* rng = NULL;\n#ifdef WC_RSA_BLINDING\n    rng = key->rng;\n#endif\n    return RsaPrivateDecryptEx(in, inLen, out, outLen, NULL, key,\n        RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD,\n        hash, mgf, NULL, 0, saltLen, rng);\n}\n\n\n/* Checks the PSS data to ensure that the signature matches.\n * Salt length is equal to hash length.\n *\n * in        Hash of the data that is being verified.\n * inSz      Length of hash.\n * sig       Buffer holding PSS data.\n * sigSz     Size of PSS data.\n * hashType  Hash algorithm.\n * returns BAD_PADDING_E when the PSS data is invalid, BAD_FUNC_ARG when\n * NULL is passed in to in or sig or inSz is not the same as the hash\n * algorithm length and 0 on success.\n */\nint wc_RsaPSS_CheckPadding(const byte* in, word32 inSz, byte* sig,\n                           word32 sigSz, enum wc_HashType hashType)\n{\n    return wc_RsaPSS_CheckPadding_ex(in, inSz, sig, sigSz, hashType, inSz, 0);\n}\n\n/* Checks the PSS data to ensure that the signature matches.\n *\n * in        Hash of the data that is being verified.\n * inSz      Length of hash.\n * sig       Buffer holding PSS data.\n * sigSz     Size of PSS data.\n * hashType  Hash algorithm.\n * saltLen   Length of salt used. RSA_PSS_SALT_LEN_DEFAULT (-1) indicates salt\n *           length is the same as the hash length. RSA_PSS_SALT_LEN_DISCOVER\n *           indicates salt length is determined from the data.\n * returns BAD_PADDING_E when the PSS data is invalid, BAD_FUNC_ARG when\n * NULL is passed in to in or sig or inSz is not the same as the hash\n * algorithm length and 0 on success.\n */\nint wc_RsaPSS_CheckPadding_ex(const byte* in, word32 inSz, byte* sig,\n                              word32 sigSz, enum wc_HashType hashType,\n                              int saltLen, int bits)\n{\n    int ret = 0;\n#ifndef WOLFSSL_PSS_LONG_SALT\n    byte sigCheck[WC_MAX_DIGEST_SIZE*2 + RSA_PSS_PAD_SZ];\n#else\n    byte *sigCheck = NULL;\n#endif\n\n    (void)bits;\n\n    if (in == NULL || sig == NULL ||\n                               inSz != (word32)wc_HashGetDigestSize(hashType)) {\n        ret = BAD_FUNC_ARG;\n    }\n\n    if (ret == 0) {\n        if (saltLen == RSA_PSS_SALT_LEN_DEFAULT) {\n            saltLen = inSz;\n            #ifdef WOLFSSL_SHA512\n                /* See FIPS 186-4 section 5.5 item (e). */\n                if (bits == 1024 && inSz == WC_SHA512_DIGEST_SIZE) {\n                    saltLen = RSA_PSS_SALT_MAX_SZ;\n                }\n            #endif\n        }\n#ifndef WOLFSSL_PSS_LONG_SALT\n        else if ((word32)saltLen > inSz) {\n            ret = PSS_SALTLEN_E;\n        }\n#endif\n#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER\n        else if (saltLen < RSA_PSS_SALT_LEN_DEFAULT) {\n            ret = PSS_SALTLEN_E;\n        }\n#else\n        else if (saltLen == RSA_PSS_SALT_LEN_DISCOVER) {\n            saltLen = sigSz - inSz;\n            if (saltLen < 0) {\n                ret = PSS_SALTLEN_E;\n            }\n        }\n        else if (saltLen < RSA_PSS_SALT_LEN_DISCOVER) {\n            ret = PSS_SALTLEN_E;\n        }\n#endif\n    }\n\n    /* Sig = Salt | Exp Hash */\n    if (ret == 0) {\n        if (sigSz != inSz + saltLen) {\n            ret = PSS_SALTLEN_E;\n        }\n    }\n\n#ifdef WOLFSSL_PSS_LONG_SALT\n    if (ret == 0) {\n        sigCheck = (byte*)XMALLOC(RSA_PSS_PAD_SZ + inSz + saltLen, NULL,\n                                                       DYNAMIC_TYPE_RSA_BUFFER);\n        if (sigCheck == NULL) {\n            ret = MEMORY_E;\n        }\n    }\n#endif\n\n    /* Exp Hash = HASH(8 * 0x00 | Message Hash | Salt) */\n    if (ret == 0) {\n        XMEMSET(sigCheck, 0, RSA_PSS_PAD_SZ);\n        XMEMCPY(sigCheck + RSA_PSS_PAD_SZ, in, inSz);\n        XMEMCPY(sigCheck + RSA_PSS_PAD_SZ + inSz, sig, saltLen);\n        ret = wc_Hash(hashType, sigCheck, RSA_PSS_PAD_SZ + inSz + saltLen,\n                      sigCheck, inSz);\n    }\n    if (ret == 0) {\n        if (XMEMCMP(sigCheck, sig + saltLen, inSz) != 0) {\n            WOLFSSL_MSG(\"RsaPSS_CheckPadding: Padding Error\");\n            ret = BAD_PADDING_E;\n        }\n    }\n\n#ifdef WOLFSSL_PSS_LONG_SALT\n    if (sigCheck != NULL) {\n        XFREE(sigCheck, NULL, DYNAMIC_TYPE_RSA_BUFFER);\n    }\n#endif\n    return ret;\n}\n\n\n/* Verify the message signed with RSA-PSS.\n * The input buffer is reused for the output buffer.\n * Salt length is equal to hash length.\n *\n * in     Buffer holding encrypted data.\n * inLen  Length of data in buffer.\n * out    Pointer to address containing the PSS data.\n * digest Hash of the data that is being verified.\n * digestLen Length of hash.\n * hash   Hash algorithm.\n * mgf    Mask generation function.\n * key    Public RSA key.\n * returns the length of the PSS data on success and negative indicates failure.\n */\nint wc_RsaPSS_VerifyCheckInline(byte* in, word32 inLen, byte** out,\n                           const byte* digest, word32 digestLen,\n                           enum wc_HashType hash, int mgf, RsaKey* key)\n{\n    int ret = 0, verify, saltLen, hLen, bits = 0;\n\n    hLen = wc_HashGetDigestSize(hash);\n    if (hLen < 0)\n        return hLen;\n    if ((word32)hLen != digestLen)\n        return BAD_FUNC_ARG;\n\n    saltLen = hLen;\n    #ifdef WOLFSSL_SHA512\n        /* See FIPS 186-4 section 5.5 item (e). */\n        bits = mp_count_bits(&key->n);\n        if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE)\n            saltLen = RSA_PSS_SALT_MAX_SZ;\n    #endif\n\n    verify = wc_RsaPSS_VerifyInline_ex(in, inLen, out, hash, mgf, saltLen, key);\n    if (verify > 0)\n        ret = wc_RsaPSS_CheckPadding_ex(digest, digestLen, *out, verify,\n                                        hash, saltLen, bits);\n    if (ret == 0)\n        ret = verify;\n\n    return ret;\n}\n\n\n/* Verify the message signed with RSA-PSS.\n * Salt length is equal to hash length.\n *\n * in     Buffer holding encrypted data.\n * inLen  Length of data in buffer.\n * out    Pointer to address containing the PSS data.\n * outLen Length of the output.\n * digest Hash of the data that is being verified.\n * digestLen Length of hash.\n * hash   Hash algorithm.\n * mgf    Mask generation function.\n * key    Public RSA key.\n * returns the length of the PSS data on success and negative indicates failure.\n */\nint wc_RsaPSS_VerifyCheck(byte* in, word32 inLen, byte* out, word32 outLen,\n                          const byte* digest, word32 digestLen,\n                          enum wc_HashType hash, int mgf,\n                          RsaKey* key)\n{\n    int ret = 0, verify, saltLen, hLen, bits = 0;\n\n    hLen = wc_HashGetDigestSize(hash);\n    if (hLen < 0)\n        return hLen;\n    if ((word32)hLen != digestLen)\n        return BAD_FUNC_ARG;\n\n    saltLen = hLen;\n    #ifdef WOLFSSL_SHA512\n        /* See FIPS 186-4 section 5.5 item (e). */\n        bits = mp_count_bits(&key->n);\n        if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE)\n            saltLen = RSA_PSS_SALT_MAX_SZ;\n    #endif\n\n    verify = wc_RsaPSS_Verify_ex(in, inLen, out, outLen, hash,\n                                 mgf, saltLen, key);\n    if (verify > 0)\n        ret = wc_RsaPSS_CheckPadding_ex(digest, digestLen, out, verify,\n                                        hash, saltLen, bits);\n    if (ret == 0)\n        ret = verify;\n\n    return ret;\n}\n\n#endif\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\nint wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,\n                                                   RsaKey* key, WC_RNG* rng)\n{\n    return RsaPublicEncryptEx(in, inLen, out, outLen, key,\n        RSA_PRIVATE_ENCRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,\n        WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng);\n}\n\n#ifdef WC_RSA_PSS\n/* Sign the hash of a message using RSA-PSS.\n * Salt length is equal to hash length.\n *\n * in      Buffer holding hash of message.\n * inLen   Length of data in buffer (hash length).\n * out     Buffer to write encrypted signature into.\n * outLen  Size of buffer to write to.\n * hash    Hash algorithm.\n * mgf     Mask generation function.\n * key     Public RSA key.\n * rng     Random number generator.\n * returns the length of the encrypted signature on success, a negative value\n * indicates failure.\n */\nint wc_RsaPSS_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,\n                       enum wc_HashType hash, int mgf, RsaKey* key, WC_RNG* rng)\n{\n    return wc_RsaPSS_Sign_ex(in, inLen, out, outLen, hash, mgf,\n                                            RSA_PSS_SALT_LEN_DEFAULT, key, rng);\n}\n\n/* Sign the hash of a message using RSA-PSS.\n *\n * in       Buffer holding hash of message.\n * inLen    Length of data in buffer (hash length).\n * out      Buffer to write encrypted signature into.\n * outLen   Size of buffer to write to.\n * hash     Hash algorithm.\n * mgf      Mask generation function.\n * saltLen  Length of salt used. RSA_PSS_SALT_LEN_DEFAULT (-1) indicates salt\n *          length is the same as the hash length. RSA_PSS_SALT_LEN_DISCOVER\n *          indicates salt length is determined from the data.\n * key      Public RSA key.\n * rng      Random number generator.\n * returns the length of the encrypted signature on success, a negative value\n * indicates failure.\n */\nint wc_RsaPSS_Sign_ex(const byte* in, word32 inLen, byte* out, word32 outLen,\n                      enum wc_HashType hash, int mgf, int saltLen, RsaKey* key,\n                      WC_RNG* rng)\n{\n    return RsaPublicEncryptEx(in, inLen, out, outLen, key,\n        RSA_PRIVATE_ENCRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD,\n        hash, mgf, NULL, 0, saltLen, rng);\n}\n#endif\n#endif\n\n#if !defined(WOLFSSL_RSA_VERIFY_ONLY) || !defined(WOLFSSL_SP_MATH) || \\\n                                                             defined(WC_RSA_PSS)\nint wc_RsaEncryptSize(RsaKey* key)\n{\n    int ret;\n\n    if (key == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    ret = mp_unsigned_bin_size(&key->n);\n\n#ifdef WOLF_CRYPTO_CB\n    if (ret == 0 && key->devId != INVALID_DEVID) {\n        ret = 2048/8; /* hardware handles, use 2048-bit as default */\n    }\n#endif\n\n    return ret;\n}\n#endif\n\n#ifndef WOLFSSL_RSA_VERIFY_ONLY\n/* flatten RsaKey structure into individual elements (e, n) */\nint wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n,\n                                                                   word32* nSz)\n{\n    int sz, ret;\n\n    if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    sz = mp_unsigned_bin_size(&key->e);\n    if ((word32)sz > *eSz)\n        return RSA_BUFFER_E;\n    ret = mp_to_unsigned_bin(&key->e, e);\n    if (ret != MP_OKAY)\n        return ret;\n    *eSz = (word32)sz;\n\n    sz = wc_RsaEncryptSize(key);\n    if ((word32)sz > *nSz)\n        return RSA_BUFFER_E;\n    ret = mp_to_unsigned_bin(&key->n, n);\n    if (ret != MP_OKAY)\n        return ret;\n    *nSz = (word32)sz;\n\n    return 0;\n}\n#endif\n\n#endif /* HAVE_FIPS */\n\n\n#ifndef WOLFSSL_RSA_VERIFY_ONLY\nstatic int RsaGetValue(mp_int* in, byte* out, word32* outSz)\n{\n    word32 sz;\n    int ret = 0;\n\n    /* Parameters ensured by calling function. */\n\n    sz = (word32)mp_unsigned_bin_size(in);\n    if (sz > *outSz)\n        ret = RSA_BUFFER_E;\n\n    if (ret == 0)\n        ret = mp_to_unsigned_bin(in, out);\n\n    if (ret == MP_OKAY)\n        *outSz = sz;\n\n    return ret;\n}\n\n\nint wc_RsaExportKey(RsaKey* key,\n                    byte* e, word32* eSz, byte* n, word32* nSz,\n                    byte* d, word32* dSz, byte* p, word32* pSz,\n                    byte* q, word32* qSz)\n{\n    int ret = BAD_FUNC_ARG;\n\n    if (key && e && eSz && n && nSz && d && dSz && p && pSz && q && qSz)\n        ret = 0;\n\n    if (ret == 0)\n        ret = RsaGetValue(&key->e, e, eSz);\n    if (ret == 0)\n        ret = RsaGetValue(&key->n, n, nSz);\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n    if (ret == 0)\n        ret = RsaGetValue(&key->d, d, dSz);\n    if (ret == 0)\n        ret = RsaGetValue(&key->p, p, pSz);\n    if (ret == 0)\n        ret = RsaGetValue(&key->q, q, qSz);\n#else\n    /* no private parts to key */\n    if (d == NULL || p == NULL || q == NULL || dSz == NULL || pSz == NULL\n            || qSz == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n    else {\n        *dSz = 0;\n        *pSz = 0;\n        *qSz = 0;\n    }\n#endif /* WOLFSSL_RSA_PUBLIC_ONLY */\n\n    return ret;\n}\n#endif\n\n\n#ifdef WOLFSSL_KEY_GEN\n\n/* Check that |p-q| > 2^((size/2)-100) */\nstatic int wc_CompareDiffPQ(mp_int* p, mp_int* q, int size)\n{\n    mp_int c, d;\n    int ret;\n\n    if (p == NULL || q == NULL)\n        return BAD_FUNC_ARG;\n\n    ret = mp_init_multi(&c, &d, NULL, NULL, NULL, NULL);\n\n    /* c = 2^((size/2)-100) */\n    if (ret == 0)\n        ret = mp_2expt(&c, (size/2)-100);\n\n    /* d = |p-q| */\n    if (ret == 0)\n        ret = mp_sub(p, q, &d);\n\n    if (ret == 0)\n        ret = mp_abs(&d, &d);\n\n    /* compare */\n    if (ret == 0)\n        ret = mp_cmp(&d, &c);\n\n    if (ret == MP_GT)\n        ret = MP_OKAY;\n\n    mp_clear(&d);\n    mp_clear(&c);\n\n    return ret;\n}\n\n\n/* The lower_bound value is floor(2^(0.5) * 2^((nlen/2)-1)) where nlen is 4096.\n * This number was calculated using a small test tool written with a common\n * large number math library. Other values of nlen may be checked with a subset\n * of lower_bound. */\nstatic const byte lower_bound[] = {\n    0xB5, 0x04, 0xF3, 0x33, 0xF9, 0xDE, 0x64, 0x84,\n    0x59, 0x7D, 0x89, 0xB3, 0x75, 0x4A, 0xBE, 0x9F,\n    0x1D, 0x6F, 0x60, 0xBA, 0x89, 0x3B, 0xA8, 0x4C,\n    0xED, 0x17, 0xAC, 0x85, 0x83, 0x33, 0x99, 0x15,\n/* 512 */\n    0x4A, 0xFC, 0x83, 0x04, 0x3A, 0xB8, 0xA2, 0xC3,\n    0xA8, 0xB1, 0xFE, 0x6F, 0xDC, 0x83, 0xDB, 0x39,\n    0x0F, 0x74, 0xA8, 0x5E, 0x43, 0x9C, 0x7B, 0x4A,\n    0x78, 0x04, 0x87, 0x36, 0x3D, 0xFA, 0x27, 0x68,\n/* 1024 */\n    0xD2, 0x20, 0x2E, 0x87, 0x42, 0xAF, 0x1F, 0x4E,\n    0x53, 0x05, 0x9C, 0x60, 0x11, 0xBC, 0x33, 0x7B,\n    0xCA, 0xB1, 0xBC, 0x91, 0x16, 0x88, 0x45, 0x8A,\n    0x46, 0x0A, 0xBC, 0x72, 0x2F, 0x7C, 0x4E, 0x33,\n    0xC6, 0xD5, 0xA8, 0xA3, 0x8B, 0xB7, 0xE9, 0xDC,\n    0xCB, 0x2A, 0x63, 0x43, 0x31, 0xF3, 0xC8, 0x4D,\n    0xF5, 0x2F, 0x12, 0x0F, 0x83, 0x6E, 0x58, 0x2E,\n    0xEA, 0xA4, 0xA0, 0x89, 0x90, 0x40, 0xCA, 0x4A,\n/* 2048 */\n    0x81, 0x39, 0x4A, 0xB6, 0xD8, 0xFD, 0x0E, 0xFD,\n    0xF4, 0xD3, 0xA0, 0x2C, 0xEB, 0xC9, 0x3E, 0x0C,\n    0x42, 0x64, 0xDA, 0xBC, 0xD5, 0x28, 0xB6, 0x51,\n    0xB8, 0xCF, 0x34, 0x1B, 0x6F, 0x82, 0x36, 0xC7,\n    0x01, 0x04, 0xDC, 0x01, 0xFE, 0x32, 0x35, 0x2F,\n    0x33, 0x2A, 0x5E, 0x9F, 0x7B, 0xDA, 0x1E, 0xBF,\n    0xF6, 0xA1, 0xBE, 0x3F, 0xCA, 0x22, 0x13, 0x07,\n    0xDE, 0xA0, 0x62, 0x41, 0xF7, 0xAA, 0x81, 0xC2,\n/* 3072 */\n    0xC1, 0xFC, 0xBD, 0xDE, 0xA2, 0xF7, 0xDC, 0x33,\n    0x18, 0x83, 0x8A, 0x2E, 0xAF, 0xF5, 0xF3, 0xB2,\n    0xD2, 0x4F, 0x4A, 0x76, 0x3F, 0xAC, 0xB8, 0x82,\n    0xFD, 0xFE, 0x17, 0x0F, 0xD3, 0xB1, 0xF7, 0x80,\n    0xF9, 0xAC, 0xCE, 0x41, 0x79, 0x7F, 0x28, 0x05,\n    0xC2, 0x46, 0x78, 0x5E, 0x92, 0x95, 0x70, 0x23,\n    0x5F, 0xCF, 0x8F, 0x7B, 0xCA, 0x3E, 0xA3, 0x3B,\n    0x4D, 0x7C, 0x60, 0xA5, 0xE6, 0x33, 0xE3, 0xE1\n/* 4096 */\n};\n\n\n/* returns 1 on key size ok and 0 if not ok */\nstatic WC_INLINE int RsaSizeCheck(int size)\n{\n    if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE) {\n        return 0;\n    }\n\n#ifdef HAVE_FIPS\n    /* Key size requirements for CAVP */\n    switch (size) {\n        case 1024:\n        case 2048:\n        case 3072:\n        case 4096:\n            return 1;\n    }\n\n    return 0;\n#else\n    return 1; /* allow unusual key sizes in non FIPS mode */\n#endif /* HAVE_FIPS */\n}\n\n\nstatic int _CheckProbablePrime(mp_int* p, mp_int* q, mp_int* e, int nlen,\n                                    int* isPrime, WC_RNG* rng)\n{\n    int ret;\n    mp_int tmp1, tmp2;\n    mp_int* prime;\n\n    if (p == NULL || e == NULL || isPrime == NULL)\n        return BAD_FUNC_ARG;\n\n    if (!RsaSizeCheck(nlen))\n        return BAD_FUNC_ARG;\n\n    *isPrime = MP_NO;\n\n    if (q != NULL) {\n        /* 5.4 - check that |p-q| <= (2^(1/2))(2^((nlen/2)-1)) */\n        ret = wc_CompareDiffPQ(p, q, nlen);\n        if (ret != MP_OKAY) goto notOkay;\n        prime = q;\n    }\n    else\n        prime = p;\n\n    ret = mp_init_multi(&tmp1, &tmp2, NULL, NULL, NULL, NULL);\n    if (ret != MP_OKAY) goto notOkay;\n\n    /* 4.4,5.5 - Check that prime >= (2^(1/2))(2^((nlen/2)-1))\n     *           This is a comparison against lowerBound */\n    ret = mp_read_unsigned_bin(&tmp1, lower_bound, nlen/16);\n    if (ret != MP_OKAY) goto notOkay;\n    ret = mp_cmp(prime, &tmp1);\n    if (ret == MP_LT) goto exit;\n\n    /* 4.5,5.6 - Check that GCD(p-1, e) == 1 */\n    ret = mp_sub_d(prime, 1, &tmp1);  /* tmp1 = prime-1 */\n    if (ret != MP_OKAY) goto notOkay;\n    ret = mp_gcd(&tmp1, e, &tmp2);  /* tmp2 = gcd(prime-1, e) */\n    if (ret != MP_OKAY) goto notOkay;\n    ret = mp_cmp_d(&tmp2, 1);\n    if (ret != MP_EQ) goto exit; /* e divides p-1 */\n\n    /* 4.5.1,5.6.1 - Check primality of p with 8 rounds of M-R.\n     * mp_prime_is_prime_ex() performs test divisions against the first 256\n     * prime numbers. After that it performs 8 rounds of M-R using random\n     * bases between 2 and n-2.\n     * mp_prime_is_prime() performs the same test divisions and then does\n     * M-R with the first 8 primes. Both functions set isPrime as a\n     * side-effect. */\n    if (rng != NULL)\n        ret = mp_prime_is_prime_ex(prime, 8, isPrime, rng);\n    else\n        ret = mp_prime_is_prime(prime, 8, isPrime);\n    if (ret != MP_OKAY) goto notOkay;\n\nexit:\n    ret = MP_OKAY;\nnotOkay:\n    mp_clear(&tmp1);\n    mp_clear(&tmp2);\n    return ret;\n}\n\n\nint wc_CheckProbablePrime_ex(const byte* pRaw, word32 pRawSz,\n                          const byte* qRaw, word32 qRawSz,\n                          const byte* eRaw, word32 eRawSz,\n                          int nlen, int* isPrime, WC_RNG* rng)\n{\n    mp_int p, q, e;\n    mp_int* Q = NULL;\n    int ret;\n\n    if (pRaw == NULL || pRawSz == 0 ||\n        eRaw == NULL || eRawSz == 0 ||\n        isPrime == NULL) {\n\n        return BAD_FUNC_ARG;\n    }\n\n    if ((qRaw != NULL && qRawSz == 0) || (qRaw == NULL && qRawSz != 0))\n        return BAD_FUNC_ARG;\n\n    ret = mp_init_multi(&p, &q, &e, NULL, NULL, NULL);\n\n    if (ret == MP_OKAY)\n        ret = mp_read_unsigned_bin(&p, pRaw, pRawSz);\n\n    if (ret == MP_OKAY) {\n        if (qRaw != NULL) {\n            ret = mp_read_unsigned_bin(&q, qRaw, qRawSz);\n            if (ret == MP_OKAY)\n                Q = &q;\n        }\n    }\n\n    if (ret == MP_OKAY)\n        ret = mp_read_unsigned_bin(&e, eRaw, eRawSz);\n\n    if (ret == MP_OKAY)\n        ret = _CheckProbablePrime(&p, Q, &e, nlen, isPrime, rng);\n\n    ret = (ret == MP_OKAY) ? 0 : PRIME_GEN_E;\n\n    mp_clear(&p);\n    mp_clear(&q);\n    mp_clear(&e);\n\n    return ret;\n}\n\n\nint wc_CheckProbablePrime(const byte* pRaw, word32 pRawSz,\n                          const byte* qRaw, word32 qRawSz,\n                          const byte* eRaw, word32 eRawSz,\n                          int nlen, int* isPrime)\n{\n    return wc_CheckProbablePrime_ex(pRaw, pRawSz, qRaw, qRawSz,\n                          eRaw, eRawSz, nlen, isPrime, NULL);\n}\n\n#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS) && \\\n        defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))\n/* Make an RSA key for size bits, with e specified, 65537 is a good e */\nint wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)\n{\n#ifndef WC_NO_RNG\n    mp_int p, q, tmp1, tmp2, tmp3;\n    int err, i, failCount, primeSz, isPrime = 0;\n    byte* buf = NULL;\n\n    if (key == NULL || rng == NULL)\n        return BAD_FUNC_ARG;\n\n    if (!RsaSizeCheck(size))\n        return BAD_FUNC_ARG;\n\n    if (e < 3 || (e & 1) == 0)\n        return BAD_FUNC_ARG;\n\n#if defined(WOLFSSL_CRYPTOCELL)\n\n    return cc310_RSA_GenerateKeyPair(key, size, e);\n\n#endif /*WOLFSSL_CRYPTOCELL*/\n\n#ifdef WOLF_CRYPTO_CB\n    if (key->devId != INVALID_DEVID) {\n        int ret = wc_CryptoCb_MakeRsaKey(key, size, e, rng);\n        if (ret != CRYPTOCB_UNAVAILABLE)\n            return ret;\n        /* fall-through when unavailable */\n    }\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \\\n    defined(WC_ASYNC_ENABLE_RSA_KEYGEN)\n    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {\n    #ifdef HAVE_CAVIUM\n        /* TODO: Not implemented */\n    #elif defined(HAVE_INTEL_QA)\n        return IntelQaRsaKeyGen(&key->asyncDev, key, size, e, rng);\n    #else\n        if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_RSA_MAKE)) {\n            WC_ASYNC_TEST* testDev = &key->asyncDev.test;\n            testDev->rsaMake.rng = rng;\n            testDev->rsaMake.key = key;\n            testDev->rsaMake.size = size;\n            testDev->rsaMake.e = e;\n            return WC_PENDING_E;\n        }\n    #endif\n    }\n#endif\n\n    err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL);\n\n    if (err == MP_OKAY)\n        err = mp_set_int(&tmp3, e);\n\n    /* The failCount value comes from NIST FIPS 186-4, section B.3.3,\n     * process steps 4.7 and 5.8. */\n    failCount = 5 * (size / 2);\n    primeSz = size / 16; /* size is the size of n in bits.\n                            primeSz is in bytes. */\n\n    /* allocate buffer to work with */\n    if (err == MP_OKAY) {\n        buf = (byte*)XMALLOC(primeSz, key->heap, DYNAMIC_TYPE_RSA);\n        if (buf == NULL)\n            err = MEMORY_E;\n    }\n\n    /* make p */\n    if (err == MP_OKAY) {\n        isPrime = 0;\n        i = 0;\n        do {\n#ifdef SHOW_GEN\n            printf(\".\");\n            fflush(stdout);\n#endif\n            /* generate value */\n            err = wc_RNG_GenerateBlock(rng, buf, primeSz);\n            if (err == 0) {\n                /* prime lower bound has the MSB set, set it in candidate */\n                buf[0] |= 0x80;\n                /* make candidate odd */\n                buf[primeSz-1] |= 0x01;\n                /* load value */\n                err = mp_read_unsigned_bin(&p, buf, primeSz);\n            }\n\n            if (err == MP_OKAY)\n                err = _CheckProbablePrime(&p, NULL, &tmp3, size, &isPrime, rng);\n\n#ifdef HAVE_FIPS\n            i++;\n#else\n            /* Keep the old retry behavior in non-FIPS build. */\n            (void)i;\n#endif\n        } while (err == MP_OKAY && !isPrime && i < failCount);\n    }\n\n    if (err == MP_OKAY && !isPrime)\n        err = PRIME_GEN_E;\n\n    /* make q */\n    if (err == MP_OKAY) {\n        isPrime = 0;\n        i = 0;\n        do {\n#ifdef SHOW_GEN\n            printf(\".\");\n            fflush(stdout);\n#endif\n            /* generate value */\n            err = wc_RNG_GenerateBlock(rng, buf, primeSz);\n            if (err == 0) {\n                /* prime lower bound has the MSB set, set it in candidate */\n                buf[0] |= 0x80;\n                /* make candidate odd */\n                buf[primeSz-1] |= 0x01;\n                /* load value */\n                err = mp_read_unsigned_bin(&q, buf, primeSz);\n            }\n\n            if (err == MP_OKAY)\n                err = _CheckProbablePrime(&p, &q, &tmp3, size, &isPrime, rng);\n\n#ifdef HAVE_FIPS\n            i++;\n#else\n            /* Keep the old retry behavior in non-FIPS build. */\n            (void)i;\n#endif\n        } while (err == MP_OKAY && !isPrime && i < failCount);\n    }\n\n    if (err == MP_OKAY && !isPrime)\n        err = PRIME_GEN_E;\n\n    if (buf) {\n        ForceZero(buf, primeSz);\n        XFREE(buf, key->heap, DYNAMIC_TYPE_RSA);\n    }\n\n    if (err == MP_OKAY && mp_cmp(&p, &q) < 0) {\n        err = mp_copy(&p, &tmp1);\n        if (err == MP_OKAY)\n            err = mp_copy(&q, &p);\n        if (err == MP_OKAY)\n            mp_copy(&tmp1, &q);\n    }\n\n    /* Setup RsaKey buffers */\n    if (err == MP_OKAY)\n        err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL);\n    if (err == MP_OKAY)\n        err = mp_init_multi(&key->dP, &key->dQ, &key->u, NULL, NULL, NULL);\n\n    /* Software Key Calculation */\n    if (err == MP_OKAY)                /* tmp1 = p-1 */\n        err = mp_sub_d(&p, 1, &tmp1);\n    if (err == MP_OKAY)                /* tmp2 = q-1 */\n        err = mp_sub_d(&q, 1, &tmp2);\n    if (err == MP_OKAY)                /* tmp3 = lcm(p-1, q-1), last loop */\n        err = mp_lcm(&tmp1, &tmp2, &tmp3);\n    /* make key */\n    if (err == MP_OKAY)                /* key->e = e */\n        err = mp_set_int(&key->e, (mp_digit)e);\n    if (err == MP_OKAY)                /* key->d = 1/e mod lcm(p-1, q-1) */\n        err = mp_invmod(&key->e, &tmp3, &key->d);\n    if (err == MP_OKAY)                /* key->n = pq */\n        err = mp_mul(&p, &q, &key->n);\n    if (err == MP_OKAY)                /* key->dP = d mod(p-1) */\n        err = mp_mod(&key->d, &tmp1, &key->dP);\n    if (err == MP_OKAY)                /* key->dQ = d mod(q-1) */\n        err = mp_mod(&key->d, &tmp2, &key->dQ);\n    if (err == MP_OKAY)                /* key->u = 1/q mod p */\n        err = mp_invmod(&q, &p, &key->u);\n    if (err == MP_OKAY)\n        err = mp_copy(&p, &key->p);\n    if (err == MP_OKAY)\n        err = mp_copy(&q, &key->q);\n\n#ifdef HAVE_WOLF_BIGINT\n    /* make sure raw unsigned bin version is available */\n    if (err == MP_OKAY)\n         err = wc_mp_to_bigint(&key->n, &key->n.raw);\n    if (err == MP_OKAY)\n         err = wc_mp_to_bigint(&key->e, &key->e.raw);\n    if (err == MP_OKAY)\n         err = wc_mp_to_bigint(&key->d, &key->d.raw);\n    if (err == MP_OKAY)\n         err = wc_mp_to_bigint(&key->p, &key->p.raw);\n    if (err == MP_OKAY)\n         err = wc_mp_to_bigint(&key->q, &key->q.raw);\n    if (err == MP_OKAY)\n         err = wc_mp_to_bigint(&key->dP, &key->dP.raw);\n    if (err == MP_OKAY)\n         err = wc_mp_to_bigint(&key->dQ, &key->dQ.raw);\n    if (err == MP_OKAY)\n         err = wc_mp_to_bigint(&key->u, &key->u.raw);\n#endif\n\n    if (err == MP_OKAY)\n        key->type = RSA_PRIVATE;\n\n    mp_clear(&tmp1);\n    mp_clear(&tmp2);\n    mp_clear(&tmp3);\n    mp_clear(&p);\n    mp_clear(&q);\n\n#if defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_NO_RSA_KEY_CHECK)\n    /* Perform the pair-wise consistency test on the new key. */\n    if (err == 0)\n        err = wc_CheckRsaKey(key);\n#endif\n\n    if (err != 0) {\n        wc_FreeRsaKey(key);\n        return err;\n    }\n\n#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)\n    if (wc_InitRsaHw(key) != 0) {\n        return BAD_STATE_E;\n    }\n#endif\n    return 0;\n#else\n    return NOT_COMPILED_IN;\n#endif\n}\n#endif /* !FIPS || FIPS_VER >= 2 */\n#endif /* WOLFSSL_KEY_GEN */\n\n\n#ifdef WC_RSA_BLINDING\nint wc_RsaSetRNG(RsaKey* key, WC_RNG* rng)\n{\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    key->rng = rng;\n\n    return 0;\n}\n#endif /* WC_RSA_BLINDING */\n\n#ifdef WC_RSA_NONBLOCK\nint wc_RsaSetNonBlock(RsaKey* key, RsaNb* nb)\n{\n    if (key == NULL)\n        return BAD_FUNC_ARG;\n\n    if (nb) {\n        XMEMSET(nb, 0, sizeof(RsaNb));\n    }\n\n    /* Allow nb == NULL to clear non-block mode */\n    key->nb = nb;\n\n    return 0;\n}\n#ifdef WC_RSA_NONBLOCK_TIME\nint wc_RsaSetNonBlockTime(RsaKey* key, word32 maxBlockUs, word32 cpuMHz)\n{\n    if (key == NULL || key->nb == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* calculate maximum number of instructions to block */\n    key->nb->exptmod.maxBlockInst = cpuMHz * maxBlockUs;\n\n    return 0;\n}\n#endif /* WC_RSA_NONBLOCK_TIME */\n#endif /* WC_RSA_NONBLOCK */\n\n#endif /* NO_RSA */\n"
  },
  {
    "path": "src/wolfcrypt/src/sha.c",
    "content": "/* sha.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if !defined(NO_SHA)\n\n#if defined(HAVE_FIPS) && \\\n\tdefined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n\n    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */\n    #define FIPS_NO_WRAPPERS\n\n    #ifdef USE_WINDOWS_API\n        #pragma code_seg(\".fipsA$j\")\n        #pragma const_seg(\".fipsB$j\")\n    #endif\n#endif\n\n#include <wolfssl/wolfcrypt/sha.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/hash.h>\n\n#ifdef WOLF_CRYPTO_CB\n    #include <wolfssl/wolfcrypt/cryptocb.h>\n#endif\n\n/* fips wrapper calls, user can call direct */\n#if defined(HAVE_FIPS) && \\\n    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n\n    int wc_InitSha(wc_Sha* sha)\n    {\n        if (sha == NULL) {\n            return BAD_FUNC_ARG;\n        }\n        return InitSha_fips(sha);\n    }\n    int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)\n    {\n        (void)heap;\n        (void)devId;\n        if (sha == NULL) {\n            return BAD_FUNC_ARG;\n        }\n        return InitSha_fips(sha);\n    }\n\n    int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)\n    {\n        if (sha == NULL || (data == NULL && len > 0)) {\n            return BAD_FUNC_ARG;\n        }\n        return ShaUpdate_fips(sha, data, len);\n    }\n\n    int wc_ShaFinal(wc_Sha* sha, byte* out)\n    {\n        if (sha == NULL || out == NULL) {\n            return BAD_FUNC_ARG;\n        }\n        return ShaFinal_fips(sha,out);\n    }\n    void wc_ShaFree(wc_Sha* sha)\n    {\n        (void)sha;\n        /* Not supported in FIPS */\n    }\n\n#else /* else build without fips, or for FIPS v2 */\n\n\n#if defined(WOLFSSL_TI_HASH)\n    /* #include <wolfcrypt/src/port/ti/ti-hash.c> included by wc_port.c */\n\n#else\n\n#include <wolfssl/wolfcrypt/logging.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\n/* Hardware Acceleration */\n#if defined(WOLFSSL_PIC32MZ_HASH)\n    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>\n\n#elif defined(STM32_HASH)\n\n    /* Supports CubeMX HAL or Standard Peripheral Library */\n    int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)\n    {\n        if (sha == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n        (void)devId;\n        (void)heap;\n\n        wc_Stm32_Hash_Init(&sha->stmCtx);\n\n        return 0;\n    }\n\n    int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)\n    {\n        int ret;\n\n        if (sha == NULL || (data == NULL && len > 0)) {\n            return BAD_FUNC_ARG;\n        }\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret == 0) {\n            ret = wc_Stm32_Hash_Update(&sha->stmCtx, HASH_AlgoSelection_SHA1,\n                data, len);\n            wolfSSL_CryptHwMutexUnLock();\n        }\n        return ret;\n    }\n\n    int wc_ShaFinal(wc_Sha* sha, byte* hash)\n    {\n        int ret;\n\n        if (sha == NULL || hash == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret == 0) {\n            ret = wc_Stm32_Hash_Final(&sha->stmCtx, HASH_AlgoSelection_SHA1,\n                hash, WC_SHA_DIGEST_SIZE);\n            wolfSSL_CryptHwMutexUnLock();\n        }\n\n        (void)wc_InitSha(sha);  /* reset state */\n\n        return ret;\n    }\n\n\n#elif defined(FREESCALE_LTC_SHA)\n\n    #include \"fsl_ltc.h\"\n    int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)\n    {\n        if (sha == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n        (void)devId;\n        (void)heap;\n\n        LTC_HASH_Init(LTC_BASE, &sha->ctx, kLTC_Sha1, NULL, 0);\n        return 0;\n    }\n\n    int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)\n    {\n        LTC_HASH_Update(&sha->ctx, data, len);\n        return 0;\n    }\n\n    int wc_ShaFinal(wc_Sha* sha, byte* hash)\n    {\n        uint32_t hashlen = WC_SHA_DIGEST_SIZE;\n        LTC_HASH_Finish(&sha->ctx, hash, &hashlen);\n        return wc_InitSha(sha);  /* reset state */\n    }\n\n\n#elif defined(FREESCALE_MMCAU_SHA)\n\n    #ifdef FREESCALE_MMCAU_CLASSIC_SHA\n        #include \"cau_api.h\"\n    #else\n        #include \"fsl_mmcau.h\"\n    #endif\n\n    #define USE_SHA_SOFTWARE_IMPL /* Only for API's, actual transform is here */\n\n    #define XTRANSFORM(S,B)       Transform((S),(B))\n    #define XTRANSFORM_LEN(S,B,L) Transform_Len((S),(B),(L))\n\n    #ifndef WC_HASH_DATA_ALIGNMENT\n        /* these hardware API's require 4 byte (word32) alignment */\n        #define WC_HASH_DATA_ALIGNMENT 4\n    #endif\n\n    static int InitSha(wc_Sha* sha)\n    {\n        int ret = 0;\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret != 0) {\n            return ret;\n        }\n    #ifdef FREESCALE_MMCAU_CLASSIC_SHA\n        cau_sha1_initialize_output(sha->digest);\n    #else\n        MMCAU_SHA1_InitializeOutput((uint32_t*)sha->digest);\n    #endif\n        wolfSSL_CryptHwMutexUnLock();\n\n        sha->buffLen = 0;\n        sha->loLen   = 0;\n        sha->hiLen   = 0;\n\n        return ret;\n    }\n\n    static int Transform(wc_Sha* sha, const byte* data)\n    {\n        int ret = wolfSSL_CryptHwMutexLock();\n        if (ret == 0) {\n    #ifdef FREESCALE_MMCAU_CLASSIC_SHA\n            cau_sha1_hash_n((byte*)data, 1, sha->digest);\n    #else\n            MMCAU_SHA1_HashN((byte*)data, 1, (uint32_t*)sha->digest);\n    #endif\n            wolfSSL_CryptHwMutexUnLock();\n        }\n        return ret;\n    }\n\n    static int Transform_Len(wc_Sha* sha, const byte* data, word32 len)\n    {\n        int ret = wolfSSL_CryptHwMutexLock();\n        if (ret == 0) {\n        #if defined(WC_HASH_DATA_ALIGNMENT) && WC_HASH_DATA_ALIGNMENT > 0\n            if ((size_t)data % WC_HASH_DATA_ALIGNMENT) {\n                /* data pointer is NOT aligned,\n                 * so copy and perform one block at a time */\n                byte* local = (byte*)sha->buffer;\n                while (len >= WC_SHA_BLOCK_SIZE) {\n                    XMEMCPY(local, data, WC_SHA_BLOCK_SIZE);\n                #ifdef FREESCALE_MMCAU_CLASSIC_SHA\n                    cau_sha1_hash_n(local, 1, sha->digest);\n                #else\n                    MMCAU_SHA1_HashN(local, 1, sha->digest);\n                #endif\n                    data += WC_SHA_BLOCK_SIZE;\n                    len  -= WC_SHA_BLOCK_SIZE;\n                }\n            }\n            else\n        #endif\n            {\n    #ifdef FREESCALE_MMCAU_CLASSIC_SHA\n            cau_sha1_hash_n((byte*)data, len/WC_SHA_BLOCK_SIZE, sha->digest);\n    #else\n            MMCAU_SHA1_HashN((byte*)data, len/WC_SHA_BLOCK_SIZE,\n                (uint32_t*)sha->digest);\n    #endif\n            }\n            wolfSSL_CryptHwMutexUnLock();\n        }\n        return ret;\n    }\n\n#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)\n    /* wolfcrypt/src/port/caam/caam_sha.c */\n\n#elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n\n    #include \"wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h\"\n\n    #define USE_SHA_SOFTWARE_IMPL\n\n    static int InitSha(wc_Sha* sha)\n    {\n        int ret = 0;\n\n        sha->digest[0] = 0x67452301L;\n        sha->digest[1] = 0xEFCDAB89L;\n        sha->digest[2] = 0x98BADCFEL;\n        sha->digest[3] = 0x10325476L;\n        sha->digest[4] = 0xC3D2E1F0L;\n\n        sha->buffLen = 0;\n        sha->loLen   = 0;\n        sha->hiLen   = 0;\n\n        /* alwasy start firstblock = 1 when using hw engine */\n        sha->ctx.isfirstblock = 1;\n        sha->ctx.sha_type = SHA1;\n        if(sha->ctx.mode == ESP32_SHA_HW){\n            /* release hw engine */\n            esp_sha_hw_unlock();\n        }\n        /* always set mode as INIT\n        *  whether using HW or SW is detemined at first call of update()\n        */\n        sha->ctx.mode = ESP32_SHA_INIT;\n\n        return ret;\n    }\n\n#elif defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \\\n    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)\n\n    /* implemented in wolfcrypt/src/port/Renesas/renesas_tsip_sha.c */\n\n#else\n    /* Software implementation */\n    #define USE_SHA_SOFTWARE_IMPL\n\n    static int InitSha(wc_Sha* sha)\n    {\n        int ret = 0;\n\n        sha->digest[0] = 0x67452301L;\n        sha->digest[1] = 0xEFCDAB89L;\n        sha->digest[2] = 0x98BADCFEL;\n        sha->digest[3] = 0x10325476L;\n        sha->digest[4] = 0xC3D2E1F0L;\n\n        sha->buffLen = 0;\n        sha->loLen   = 0;\n        sha->hiLen   = 0;\n    #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n        sha->flags = 0;\n    #endif\n\n        return ret;\n    }\n#endif /* End Hardware Acceleration */\n\n/* Software implementation */\n#ifdef USE_SHA_SOFTWARE_IMPL\n\nstatic WC_INLINE void AddLength(wc_Sha* sha, word32 len)\n{\n    word32 tmp = sha->loLen;\n    if ((sha->loLen += len) < tmp)\n        sha->hiLen++;                       /* carry low to high */\n}\n\n/* Check if custom wc_Sha transform is used */\n#ifndef XTRANSFORM\n    #define XTRANSFORM(S,B)   Transform((S),(B))\n\n    #define blk0(i) (W[i] = *((word32*)&data[i*sizeof(word32)]))\n    #define blk1(i) (W[(i)&15] = \\\n        rotlFixed(W[((i)+13)&15]^W[((i)+8)&15]^W[((i)+2)&15]^W[(i)&15],1))\n\n    #define f1(x,y,z) ((z)^((x) &((y)^(z))))\n    #define f2(x,y,z) ((x)^(y)^(z))\n    #define f3(x,y,z) (((x)&(y))|((z)&((x)|(y))))\n    #define f4(x,y,z) ((x)^(y)^(z))\n\n    #ifdef WOLFSSL_NUCLEUS_1_2\n        /* nucleus.h also defines R1-R4 */\n        #undef R1\n        #undef R2\n        #undef R3\n        #undef R4\n    #endif\n\n    /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */\n    #define R0(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk0((i)) + 0x5A827999+ \\\n        rotlFixed((v),5); (w) = rotlFixed((w),30);\n    #define R1(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk1((i)) + 0x5A827999+ \\\n        rotlFixed((v),5); (w) = rotlFixed((w),30);\n    #define R2(v,w,x,y,z,i) (z)+= f2((w),(x),(y)) + blk1((i)) + 0x6ED9EBA1+ \\\n        rotlFixed((v),5); (w) = rotlFixed((w),30);\n    #define R3(v,w,x,y,z,i) (z)+= f3((w),(x),(y)) + blk1((i)) + 0x8F1BBCDC+ \\\n        rotlFixed((v),5); (w) = rotlFixed((w),30);\n    #define R4(v,w,x,y,z,i) (z)+= f4((w),(x),(y)) + blk1((i)) + 0xCA62C1D6+ \\\n        rotlFixed((v),5); (w) = rotlFixed((w),30);\n\n    static int Transform(wc_Sha* sha, const byte* data)\n    {\n        word32 W[WC_SHA_BLOCK_SIZE / sizeof(word32)];\n\n        /* Copy context->state[] to working vars */\n        word32 a = sha->digest[0];\n        word32 b = sha->digest[1];\n        word32 c = sha->digest[2];\n        word32 d = sha->digest[3];\n        word32 e = sha->digest[4];\n\n    #ifdef USE_SLOW_SHA\n        word32 t, i;\n\n        for (i = 0; i < 16; i++) {\n            R0(a, b, c, d, e, i);\n            t = e; e = d; d = c; c = b; b = a; a = t;\n        }\n\n        for (; i < 20; i++) {\n            R1(a, b, c, d, e, i);\n            t = e; e = d; d = c; c = b; b = a; a = t;\n        }\n\n        for (; i < 40; i++) {\n            R2(a, b, c, d, e, i);\n            t = e; e = d; d = c; c = b; b = a; a = t;\n        }\n\n        for (; i < 60; i++) {\n            R3(a, b, c, d, e, i);\n            t = e; e = d; d = c; c = b; b = a; a = t;\n        }\n\n        for (; i < 80; i++) {\n            R4(a, b, c, d, e, i);\n            t = e; e = d; d = c; c = b; b = a; a = t;\n        }\n    #else\n        /* nearly 1 K bigger in code size but 25% faster */\n        /* 4 rounds of 20 operations each. Loop unrolled. */\n        R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);\n        R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);\n        R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);\n        R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);\n\n        R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);\n\n        R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);\n        R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);\n        R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);\n        R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);\n        R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);\n\n        R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);\n        R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);\n        R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);\n        R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);\n        R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);\n\n        R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);\n        R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);\n        R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);\n        R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);\n        R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);\n    #endif\n\n        /* Add the working vars back into digest state[] */\n        sha->digest[0] += a;\n        sha->digest[1] += b;\n        sha->digest[2] += c;\n        sha->digest[3] += d;\n        sha->digest[4] += e;\n\n        (void)data; /* Not used */\n\n        return 0;\n    }\n#endif /* !USE_CUSTOM_SHA_TRANSFORM */\n\n\nint wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)\n{\n    int ret = 0;\n\n    if (sha == NULL)\n        return BAD_FUNC_ARG;\n\n    sha->heap = heap;\n#ifdef WOLF_CRYPTO_CB\n    sha->devId = devId;\n#endif\n\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    sha->ctx.mode = ESP32_SHA_INIT;\n    sha->ctx.isfirstblock = 1;\n#endif\n    ret = InitSha(sha);\n    if (ret != 0)\n        return ret;\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)\n    ret = wolfAsync_DevCtxInit(&sha->asyncDev, WOLFSSL_ASYNC_MARKER_SHA,\n                                                            sha->heap, devId);\n#else\n    (void)devId;\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    return ret;\n}\n\n/* do block size increments/updates */\nint wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)\n{\n    int ret = 0;\n    word32 blocksLen;\n    byte* local;\n\n    if (sha == NULL || (data == NULL && len > 0)) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLF_CRYPTO_CB\n    if (sha->devId != INVALID_DEVID) {\n        ret = wc_CryptoCb_ShaHash(sha, data, len, NULL);\n        if (ret != CRYPTOCB_UNAVAILABLE)\n            return ret;\n        ret = 0; /* reset ret */\n        /* fall-through when unavailable */\n    }\n#endif\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)\n    if (sha->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA) {\n    #if defined(HAVE_INTEL_QA)\n        return IntelQaSymSha(&sha->asyncDev, NULL, data, len);\n    #endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    /* check that internal buffLen is valid */\n    if (sha->buffLen >= WC_SHA_BLOCK_SIZE)\n        return BUFFER_E;\n\n    if (data == NULL && len == 0) {\n        /* valid, but do nothing */\n        return 0;\n    }\n\n    /* add length for final */\n    AddLength(sha, len);\n\n    local = (byte*)sha->buffer;\n\n    /* process any remainder from previous operation */\n    if (sha->buffLen > 0) {\n        blocksLen = min(len, WC_SHA_BLOCK_SIZE - sha->buffLen);\n        XMEMCPY(&local[sha->buffLen], data, blocksLen);\n\n        sha->buffLen += blocksLen;\n        data         += blocksLen;\n        len          -= blocksLen;\n\n        if (sha->buffLen == WC_SHA_BLOCK_SIZE) {\n        #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)\n            ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE);\n        #endif\n\n        #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n            !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n            if (sha->ctx.mode == ESP32_SHA_INIT) {\n                esp_sha_try_hw_lock(&sha->ctx);\n            }\n            if (sha->ctx.mode == ESP32_SHA_SW) {\n                ret = XTRANSFORM(sha, (const byte*)local);\n            } else {\n                esp_sha_process(sha, (const byte*)local);\n            }\n        #else\n            ret = XTRANSFORM(sha, (const byte*)local);\n        #endif\n            if (ret != 0)\n                return ret;\n\n            sha->buffLen = 0;\n        }\n    }\n\n    /* process blocks */\n#ifdef XTRANSFORM_LEN\n    /* get number of blocks */\n    /* 64-1 = 0x3F (~ Inverted = 0xFFFFFFC0) */\n    /* len (masked by 0xFFFFFFC0) returns block aligned length */\n    blocksLen = len & ~(WC_SHA_BLOCK_SIZE-1);\n    if (blocksLen > 0) {\n        /* Byte reversal performed in function if required. */\n        XTRANSFORM_LEN(sha, data, blocksLen);\n        data += blocksLen;\n        len  -= blocksLen;\n    }\n#else\n    while (len >= WC_SHA_BLOCK_SIZE) {\n        word32* local32 = sha->buffer;\n        /* optimization to avoid memcpy if data pointer is properly aligned */\n        /* Little Endian requires byte swap, so can't use data directly */\n    #if defined(WC_HASH_DATA_ALIGNMENT) && !defined(LITTLE_ENDIAN_ORDER)\n        if (((size_t)data % WC_HASH_DATA_ALIGNMENT) == 0) {\n            local32 = (word32*)data;\n        }\n        else\n    #endif\n        {\n            XMEMCPY(local32, data, WC_SHA_BLOCK_SIZE);\n        }\n\n        data += WC_SHA_BLOCK_SIZE;\n        len  -= WC_SHA_BLOCK_SIZE;\n\n    #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)\n        ByteReverseWords(local32, local32, WC_SHA_BLOCK_SIZE);\n    #endif\n\n    #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n        !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n        if (sha->ctx.mode == ESP32_SHA_INIT){\n            esp_sha_try_hw_lock(&sha->ctx);\n        }\n        if (sha->ctx.mode == ESP32_SHA_SW){\n            ret = XTRANSFORM(sha, (const byte*)local32);\n        } else {\n            esp_sha_process(sha, (const byte*)local32);\n        }\n    #else\n        ret = XTRANSFORM(sha, (const byte*)local32);\n    #endif\n    }\n#endif /* XTRANSFORM_LEN */\n\n    /* save remainder */\n    if (len > 0) {\n        XMEMCPY(local, data, len);\n        sha->buffLen = len;\n    }\n\n    return ret;\n}\n\nint wc_ShaFinalRaw(wc_Sha* sha, byte* hash)\n{\n#ifdef LITTLE_ENDIAN_ORDER\n    word32 digest[WC_SHA_DIGEST_SIZE / sizeof(word32)];\n#endif\n\n    if (sha == NULL || hash == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef LITTLE_ENDIAN_ORDER\n    ByteReverseWords((word32*)digest, (word32*)sha->digest, WC_SHA_DIGEST_SIZE);\n    XMEMCPY(hash, digest, WC_SHA_DIGEST_SIZE);\n#else\n    XMEMCPY(hash, sha->digest, WC_SHA_DIGEST_SIZE);\n#endif\n\n    return 0;\n}\n\nint wc_ShaFinal(wc_Sha* sha, byte* hash)\n{\n    int ret;\n    byte* local;\n\n    if (sha == NULL || hash == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    local = (byte*)sha->buffer;\n\n#ifdef WOLF_CRYPTO_CB\n    if (sha->devId != INVALID_DEVID) {\n        ret = wc_CryptoCb_ShaHash(sha, NULL, 0, hash);\n        if (ret != CRYPTOCB_UNAVAILABLE)\n            return ret;\n        ret = 0; /* reset ret */\n        /* fall-through when unavailable */\n    }\n#endif\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)\n    if (sha->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA) {\n    #if defined(HAVE_INTEL_QA)\n        return IntelQaSymSha(&sha->asyncDev, hash, NULL, WC_SHA_DIGEST_SIZE);\n    #endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    local[sha->buffLen++] = 0x80;  /* add 1 */\n\n    /* pad with zeros */\n    if (sha->buffLen > WC_SHA_PAD_SIZE) {\n        XMEMSET(&local[sha->buffLen], 0, WC_SHA_BLOCK_SIZE - sha->buffLen);\n        sha->buffLen += WC_SHA_BLOCK_SIZE - sha->buffLen;\n\n    #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)\n        ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE);\n    #endif\n\n    #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n        !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n        if (sha->ctx.mode == ESP32_SHA_INIT) {\n            esp_sha_try_hw_lock(&sha->ctx);\n        }\n        if (sha->ctx.mode == ESP32_SHA_SW) {\n            ret = XTRANSFORM(sha, (const byte*)local);\n        } else {\n            ret = esp_sha_process(sha, (const byte*)local);\n        }\n    #else\n        ret = XTRANSFORM(sha, (const byte*)local);\n    #endif\n        if (ret != 0)\n            return ret;\n\n        sha->buffLen = 0;\n    }\n    XMEMSET(&local[sha->buffLen], 0, WC_SHA_PAD_SIZE - sha->buffLen);\n\n#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)\n    ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE);\n#endif\n\n    /* store lengths */\n    /* put lengths in bits */\n    sha->hiLen = (sha->loLen >> (8*sizeof(sha->loLen) - 3)) + (sha->hiLen << 3);\n    sha->loLen = sha->loLen << 3;\n\n    /* ! length ordering dependent on digest endian type ! */\n    XMEMCPY(&local[WC_SHA_PAD_SIZE], &sha->hiLen, sizeof(word32));\n    XMEMCPY(&local[WC_SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32));\n\n#if defined(FREESCALE_MMCAU_SHA)\n    /* Kinetis requires only these bytes reversed */\n    ByteReverseWords(&sha->buffer[WC_SHA_PAD_SIZE/sizeof(word32)],\n                     &sha->buffer[WC_SHA_PAD_SIZE/sizeof(word32)],\n                     2 * sizeof(word32));\n#endif\n\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    if (sha->ctx.mode == ESP32_SHA_INIT) {\n        esp_sha_try_hw_lock(&sha->ctx);\n    }\n    if (sha->ctx.mode == ESP32_SHA_SW) {\n        ret = XTRANSFORM(sha, (const byte*)local);\n    } else {\n        ret = esp_sha_digest_process(sha, 1);\n    }\n#else\n    ret = XTRANSFORM(sha, (const byte*)local);\n#endif\n\n#ifdef LITTLE_ENDIAN_ORDER\n    ByteReverseWords(sha->digest, sha->digest, WC_SHA_DIGEST_SIZE);\n#endif\n\n    XMEMCPY(hash, sha->digest, WC_SHA_DIGEST_SIZE);\n\n    (void)InitSha(sha); /* reset state */\n\n    return ret;\n}\n\n#endif /* USE_SHA_SOFTWARE_IMPL */\n\n\nint wc_InitSha(wc_Sha* sha)\n{\n    return wc_InitSha_ex(sha, NULL, INVALID_DEVID);\n}\n\nvoid wc_ShaFree(wc_Sha* sha)\n{\n    if (sha == NULL)\n        return;\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)\n    wolfAsync_DevCtxFree(&sha->asyncDev, WOLFSSL_ASYNC_MARKER_SHA);\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n#ifdef WOLFSSL_PIC32MZ_HASH\n    wc_ShaPic32Free(sha);\n#endif\n#if (defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \\\n    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH))\n    if (sha->msg != NULL) {\n        XFREE(sha->msg, sha->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        sha->msg = NULL;\n    }\n#endif\n}\n\n#endif /* !WOLFSSL_TI_HASH */\n#endif /* HAVE_FIPS */\n\n#ifndef WOLFSSL_TI_HASH\n#if !defined(WOLFSSL_RENESAS_TSIP_CRYPT) || \\\n    defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)\nint wc_ShaGetHash(wc_Sha* sha, byte* hash)\n{\n    int ret;\n    wc_Sha tmpSha;\n\n    if (sha == NULL || hash == NULL)\n        return BAD_FUNC_ARG;\n\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    if(sha->ctx.mode == ESP32_SHA_INIT){\n        esp_sha_try_hw_lock(&sha->ctx);\n    }\n    if(sha->ctx.mode != ESP32_SHA_SW)\n        esp_sha_digest_process(sha, 0);\n#endif\n\n    ret = wc_ShaCopy(sha, &tmpSha);\n    if (ret == 0) {\n       ret = wc_ShaFinal(&tmpSha, hash);\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n        sha->ctx.mode = ESP32_SHA_SW;\n#endif\n\n\n    }\n    return ret;\n}\n\nint wc_ShaCopy(wc_Sha* src, wc_Sha* dst)\n{\n    int ret = 0;\n\n    if (src == NULL || dst == NULL)\n        return BAD_FUNC_ARG;\n\n    XMEMCPY(dst, src, sizeof(wc_Sha));\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);\n#endif\n#ifdef WOLFSSL_PIC32MZ_HASH\n    ret = wc_Pic32HashCopy(&src->cache, &dst->cache);\n#endif\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n     dst->ctx.mode = src->ctx.mode;\n     dst->ctx.isfirstblock = src->ctx.isfirstblock;\n     dst->ctx.sha_type = src->ctx.sha_type;\n#endif\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n     dst->flags |= WC_HASH_FLAG_ISCOPY;\n#endif\n    return ret;\n}\n#endif /* defined(WOLFSSL_RENESAS_TSIP_CRYPT) ... */\n#endif /* !WOLFSSL_TI_HASH */\n\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\nint wc_ShaSetFlags(wc_Sha* sha, word32 flags)\n{\n    if (sha) {\n        sha->flags = flags;\n    }\n    return 0;\n}\nint wc_ShaGetFlags(wc_Sha* sha, word32* flags)\n{\n    if (sha && flags) {\n        *flags = sha->flags;\n    }\n    return 0;\n}\n#endif\n\n#endif /* !NO_SHA */\n"
  },
  {
    "path": "src/wolfcrypt/src/sha256.c",
    "content": "/* sha256.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n/*\n * SHA256 Build Options:\n * USE_SLOW_SHA256:            Reduces code size by not partially unrolling\n                                (~2KB smaller and ~25% slower) (default OFF)\n * WOLFSSL_SHA256_BY_SPEC:     Uses the Ch/Maj based on SHA256 specification\n                                (default ON)\n * WOLFSSL_SHA256_ALT_CH_MAJ:  Alternate Ch/Maj that is easier for compilers to\n                                optimize and recognize as SHA256 (default OFF)\n * SHA256_MANY_REGISTERS:      A SHA256 version that keeps all data in registers\n                                and partial unrolled (default OFF)\n */\n\n/* Default SHA256 to use Ch/Maj based on specification */\n#if !defined(WOLFSSL_SHA256_BY_SPEC) && !defined(WOLFSSL_SHA256_ALT_CH_MAJ)\n    #define WOLFSSL_SHA256_BY_SPEC\n#endif\n\n\n#if !defined(NO_SHA256) && !defined(WOLFSSL_ARMASM)\n\n#if defined(HAVE_FIPS) && \\\n\tdefined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n\n    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */\n    #define FIPS_NO_WRAPPERS\n\n    #ifdef USE_WINDOWS_API\n        #pragma code_seg(\".fipsA$d\")\n        #pragma const_seg(\".fipsB$d\")\n    #endif\n#endif\n\n#include <wolfssl/wolfcrypt/sha256.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/cpuid.h>\n#include <wolfssl/wolfcrypt/hash.h>\n\n#ifdef WOLF_CRYPTO_CB\n    #include <wolfssl/wolfcrypt/cryptocb.h>\n#endif\n\n/* fips wrapper calls, user can call direct */\n#if defined(HAVE_FIPS) && \\\n    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n\n    int wc_InitSha256(wc_Sha256* sha)\n    {\n        if (sha == NULL) {\n            return BAD_FUNC_ARG;\n        }\n        return InitSha256_fips(sha);\n    }\n    int wc_InitSha256_ex(wc_Sha256* sha, void* heap, int devId)\n    {\n        (void)heap;\n        (void)devId;\n        if (sha == NULL) {\n            return BAD_FUNC_ARG;\n        }\n        return InitSha256_fips(sha);\n    }\n    int wc_Sha256Update(wc_Sha256* sha, const byte* data, word32 len)\n    {\n        if (sha == NULL ||  (data == NULL && len > 0)) {\n            return BAD_FUNC_ARG;\n        }\n\n        if (data == NULL && len == 0) {\n            /* valid, but do nothing */\n            return 0;\n        }\n\n        return Sha256Update_fips(sha, data, len);\n    }\n    int wc_Sha256Final(wc_Sha256* sha, byte* out)\n    {\n        if (sha == NULL || out == NULL) {\n            return BAD_FUNC_ARG;\n        }\n        return Sha256Final_fips(sha, out);\n    }\n    void wc_Sha256Free(wc_Sha256* sha)\n    {\n        (void)sha;\n        /* Not supported in FIPS */\n    }\n\n#else /* else build without fips, or for FIPS v2 */\n\n\n#if defined(WOLFSSL_TI_HASH)\n    /* #include <wolfcrypt/src/port/ti/ti-hash.c> included by wc_port.c */\n#elif defined(WOLFSSL_CRYPTOCELL)\n    /* wc_port.c includes wolfcrypt/src/port/arm/cryptoCellHash.c */\n#else\n\n#include <wolfssl/wolfcrypt/logging.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#ifdef WOLFSSL_DEVCRYPTO_HASH\n    #include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>\n#endif\n\n\n\n#if defined(USE_INTEL_SPEEDUP)\n    #if defined(__GNUC__) && ((__GNUC__ < 4) || \\\n                              (__GNUC__ == 4 && __GNUC_MINOR__ <= 8))\n        #undef  NO_AVX2_SUPPORT\n        #define NO_AVX2_SUPPORT\n    #endif\n    #if defined(__clang__) && ((__clang_major__ < 3) || \\\n                               (__clang_major__ == 3 && __clang_minor__ <= 5))\n        #define NO_AVX2_SUPPORT\n    #elif defined(__clang__) && defined(NO_AVX2_SUPPORT)\n        #undef NO_AVX2_SUPPORT\n    #endif\n\n    #define HAVE_INTEL_AVX1\n    #ifndef NO_AVX2_SUPPORT\n        #define HAVE_INTEL_AVX2\n    #endif\n#endif /* USE_INTEL_SPEEDUP */\n\n#if defined(HAVE_INTEL_AVX2)\n    #define HAVE_INTEL_RORX\n#endif\n\n\n#if !defined(WOLFSSL_PIC32MZ_HASH) && !defined(STM32_HASH_SHA2) && \\\n    (!defined(WOLFSSL_IMX6_CAAM) || defined(NO_IMX6_CAAM_HASH)) && \\\n    !defined(WOLFSSL_AFALG_HASH) && !defined(WOLFSSL_DEVCRYPTO_HASH) && \\\n    (!defined(WOLFSSL_ESP32WROOM32_CRYPT) || defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)) && \\\n    (!defined(WOLFSSL_RENESAS_TSIP_CRYPT) || defined(NO_WOLFSSL_RENESAS_TSIP_HASH))\n\nstatic int InitSha256(wc_Sha256* sha256)\n{\n    int ret = 0;\n\n    if (sha256 == NULL)\n        return BAD_FUNC_ARG;\n\n    XMEMSET(sha256->digest, 0, sizeof(sha256->digest));\n    sha256->digest[0] = 0x6A09E667L;\n    sha256->digest[1] = 0xBB67AE85L;\n    sha256->digest[2] = 0x3C6EF372L;\n    sha256->digest[3] = 0xA54FF53AL;\n    sha256->digest[4] = 0x510E527FL;\n    sha256->digest[5] = 0x9B05688CL;\n    sha256->digest[6] = 0x1F83D9ABL;\n    sha256->digest[7] = 0x5BE0CD19L;\n\n    sha256->buffLen = 0;\n    sha256->loLen   = 0;\n    sha256->hiLen   = 0;\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    sha256->flags = 0;\n#endif\n\n    return ret;\n}\n#endif\n\n\n/* Hardware Acceleration */\n#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n\n    /* in case intel instructions aren't available, plus we need the K[] global */\n    #define NEED_SOFT_SHA256\n\n    /*****\n    Intel AVX1/AVX2 Macro Control Structure\n\n    #define HAVE_INTEL_AVX1\n    #define HAVE_INTEL_AVX2\n\n    #define HAVE_INTEL_RORX\n\n\n    int InitSha256(wc_Sha256* sha256) {\n         Save/Recover XMM, YMM\n         ...\n    }\n\n    #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)\n      Transform_Sha256(); Function prototype\n    #else\n      Transform_Sha256() {   }\n      int Sha256Final() {\n         Save/Recover XMM, YMM\n         ...\n      }\n    #endif\n\n    #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)\n        #if defined(HAVE_INTEL_RORX\n             #define RND with rorx instuction\n        #else\n            #define RND\n        #endif\n    #endif\n\n    #if defined(HAVE_INTEL_AVX1)\n\n       #define XMM Instructions/inline asm\n\n       int Transform_Sha256() {\n           Stitched Message Sched/Round\n        }\n\n    #elif defined(HAVE_INTEL_AVX2)\n\n      #define YMM Instructions/inline asm\n\n      int Transform_Sha256() {\n          More granural Stitched Message Sched/Round\n      }\n\n    #endif\n\n    */\n\n    /* Each platform needs to query info type 1 from cpuid to see if aesni is\n     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts\n     */\n\n    /* #if defined(HAVE_INTEL_AVX1/2) at the tail of sha256 */\n    static int Transform_Sha256(wc_Sha256* sha256, const byte* data);\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n    #if defined(HAVE_INTEL_AVX1)\n        extern int Transform_Sha256_AVX1(wc_Sha256 *sha256, const byte* data);\n        extern int Transform_Sha256_AVX1_Len(wc_Sha256* sha256,\n                                             const byte* data, word32 len);\n    #endif\n    #if defined(HAVE_INTEL_AVX2)\n        extern int Transform_Sha256_AVX2(wc_Sha256 *sha256, const byte* data);\n        extern int Transform_Sha256_AVX2_Len(wc_Sha256* sha256,\n                                             const byte* data, word32 len);\n        #ifdef HAVE_INTEL_RORX\n        extern int Transform_Sha256_AVX1_RORX(wc_Sha256 *sha256, const byte* data);\n        extern int Transform_Sha256_AVX1_RORX_Len(wc_Sha256* sha256,\n                                                  const byte* data, word32 len);\n        extern int Transform_Sha256_AVX2_RORX(wc_Sha256 *sha256, const byte* data);\n        extern int Transform_Sha256_AVX2_RORX_Len(wc_Sha256* sha256,\n                                                  const byte* data, word32 len);\n        #endif /* HAVE_INTEL_RORX */\n    #endif /* HAVE_INTEL_AVX2 */\n\n#ifdef __cplusplus\n    }  /* extern \"C\" */\n#endif\n\n    static int (*Transform_Sha256_p)(wc_Sha256* sha256, const byte* data);\n                                                       /* = _Transform_Sha256 */\n    static int (*Transform_Sha256_Len_p)(wc_Sha256* sha256, const byte* data,\n                                         word32 len);\n                                                                    /* = NULL */\n    static int transform_check = 0;\n    static word32 intel_flags;\n\n    #define XTRANSFORM(S, D)         (*Transform_Sha256_p)((S),(D))\n    #define XTRANSFORM_LEN(S, D, L)  (*Transform_Sha256_Len_p)((S),(D),(L))\n\n    static void Sha256_SetTransform(void)\n    {\n\n        if (transform_check)\n            return;\n\n        intel_flags = cpuid_get_flags();\n\n    #ifdef HAVE_INTEL_AVX2\n        if (1 && IS_INTEL_AVX2(intel_flags)) {\n        #ifdef HAVE_INTEL_RORX\n            if (IS_INTEL_BMI2(intel_flags)) {\n                Transform_Sha256_p = Transform_Sha256_AVX2_RORX;\n                Transform_Sha256_Len_p = Transform_Sha256_AVX2_RORX_Len;\n            }\n            else\n        #endif\n            if (1)\n            {\n                Transform_Sha256_p = Transform_Sha256_AVX2;\n                Transform_Sha256_Len_p = Transform_Sha256_AVX2_Len;\n            }\n        #ifdef HAVE_INTEL_RORX\n            else {\n                Transform_Sha256_p = Transform_Sha256_AVX1_RORX;\n                Transform_Sha256_Len_p = Transform_Sha256_AVX1_RORX_Len;\n            }\n        #endif\n        }\n        else\n    #endif\n    #ifdef HAVE_INTEL_AVX1\n        if (IS_INTEL_AVX1(intel_flags)) {\n            Transform_Sha256_p = Transform_Sha256_AVX1;\n            Transform_Sha256_Len_p = Transform_Sha256_AVX1_Len;\n        }\n        else\n    #endif\n        {\n            Transform_Sha256_p = Transform_Sha256;\n            Transform_Sha256_Len_p = NULL;\n        }\n\n        transform_check = 1;\n    }\n\n    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)\n    {\n        int ret = 0;\n        if (sha256 == NULL)\n            return BAD_FUNC_ARG;\n\n        sha256->heap = heap;\n    #ifdef WOLF_CRYPTO_CB\n        sha256->devId = devId;\n    #endif\n\n        ret = InitSha256(sha256);\n        if (ret != 0)\n            return ret;\n\n        /* choose best Transform function under this runtime environment */\n        Sha256_SetTransform();\n\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)\n        ret = wolfAsync_DevCtxInit(&sha256->asyncDev,\n                            WOLFSSL_ASYNC_MARKER_SHA256, sha256->heap, devId);\n    #else\n        (void)devId;\n    #endif /* WOLFSSL_ASYNC_CRYPT */\n\n        return ret;\n    }\n\n#elif defined(FREESCALE_LTC_SHA)\n    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)\n    {\n        (void)heap;\n        (void)devId;\n\n        LTC_HASH_Init(LTC_BASE, &sha256->ctx, kLTC_Sha256, NULL, 0);\n\n        return 0;\n    }\n\n#elif defined(FREESCALE_MMCAU_SHA)\n\n    #ifdef FREESCALE_MMCAU_CLASSIC_SHA\n        #include \"cau_api.h\"\n    #else\n        #include \"fsl_mmcau.h\"\n    #endif\n\n    #define XTRANSFORM(S, D)         Transform_Sha256((S),(D))\n    #define XTRANSFORM_LEN(S, D, L)  Transform_Sha256_Len((S),(D),(L))\n\n    #ifndef WC_HASH_DATA_ALIGNMENT\n        /* these hardware API's require 4 byte (word32) alignment */\n        #define WC_HASH_DATA_ALIGNMENT 4\n    #endif\n\n    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)\n    {\n        int ret = 0;\n\n        (void)heap;\n        (void)devId;\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret != 0) {\n            return ret;\n        }\n    #ifdef FREESCALE_MMCAU_CLASSIC_SHA\n        cau_sha256_initialize_output(sha256->digest);\n    #else\n        MMCAU_SHA256_InitializeOutput((uint32_t*)sha256->digest);\n    #endif\n        wolfSSL_CryptHwMutexUnLock();\n\n        sha256->buffLen = 0;\n        sha256->loLen   = 0;\n        sha256->hiLen   = 0;\n\n        return ret;\n    }\n\n    static int Transform_Sha256(wc_Sha256* sha256, const byte* data)\n    {\n        int ret = wolfSSL_CryptHwMutexLock();\n        if (ret == 0) {\n    #ifdef FREESCALE_MMCAU_CLASSIC_SHA\n            cau_sha256_hash_n((byte*)data, 1, sha256->digest);\n    #else\n            MMCAU_SHA256_HashN((byte*)data, 1, sha256->digest);\n    #endif\n            wolfSSL_CryptHwMutexUnLock();\n        }\n        return ret;\n    }\n\n    static int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,\n        word32 len)\n    {\n        int ret = wolfSSL_CryptHwMutexLock();\n        if (ret == 0) {\n        #if defined(WC_HASH_DATA_ALIGNMENT) && WC_HASH_DATA_ALIGNMENT > 0\n            if ((size_t)data % WC_HASH_DATA_ALIGNMENT) {\n                /* data pointer is NOT aligned,\n                 * so copy and perform one block at a time */\n                byte* local = (byte*)sha256->buffer;\n                while (len >= WC_SHA256_BLOCK_SIZE) {\n                    XMEMCPY(local, data, WC_SHA256_BLOCK_SIZE);\n                #ifdef FREESCALE_MMCAU_CLASSIC_SHA\n                    cau_sha256_hash_n(local, 1, sha256->digest);\n                #else\n                    MMCAU_SHA256_HashN(local, 1, sha256->digest);\n                #endif\n                    data += WC_SHA256_BLOCK_SIZE;\n                    len  -= WC_SHA256_BLOCK_SIZE;\n                }\n            }\n            else\n        #endif\n            {\n    #ifdef FREESCALE_MMCAU_CLASSIC_SHA\n            cau_sha256_hash_n((byte*)data, len/WC_SHA256_BLOCK_SIZE,\n                sha256->digest);\n    #else\n            MMCAU_SHA256_HashN((byte*)data, len/WC_SHA256_BLOCK_SIZE,\n                sha256->digest);\n    #endif\n            }\n            wolfSSL_CryptHwMutexUnLock();\n        }\n        return ret;\n    }\n\n#elif defined(WOLFSSL_PIC32MZ_HASH)\n    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>\n\n#elif defined(STM32_HASH_SHA2)\n\n    /* Supports CubeMX HAL or Standard Peripheral Library */\n\n    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)\n    {\n        if (sha256 == NULL)\n            return BAD_FUNC_ARG;\n\n        (void)devId;\n        (void)heap;\n\n        wc_Stm32_Hash_Init(&sha256->stmCtx);\n        return 0;\n    }\n\n    int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)\n    {\n        int ret = 0;\n\n        if (sha256 == NULL || (data == NULL && len > 0)) {\n            return BAD_FUNC_ARG;\n        }\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret == 0) {\n            ret = wc_Stm32_Hash_Update(&sha256->stmCtx,\n                HASH_AlgoSelection_SHA256, data, len);\n            wolfSSL_CryptHwMutexUnLock();\n        }\n        return ret;\n    }\n\n    int wc_Sha256Final(wc_Sha256* sha256, byte* hash)\n    {\n        int ret = 0;\n\n        if (sha256 == NULL || hash == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret == 0) {\n            ret = wc_Stm32_Hash_Final(&sha256->stmCtx,\n                HASH_AlgoSelection_SHA256, hash, WC_SHA256_DIGEST_SIZE);\n            wolfSSL_CryptHwMutexUnLock();\n        }\n\n        (void)wc_InitSha256(sha256); /* reset state */\n\n        return ret;\n    }\n\n#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)\n    /* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */\n\n#elif defined(WOLFSSL_AFALG_HASH)\n    /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */\n\n#elif defined(WOLFSSL_DEVCRYPTO_HASH)\n    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */\n\n#elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n\n    #define NEED_SOFT_SHA256\n\n    static int InitSha256(wc_Sha256* sha256)\n    {\n        int ret = 0;\n\n        if (sha256 == NULL)\n            return BAD_FUNC_ARG;\n\n        XMEMSET(sha256->digest, 0, sizeof(sha256->digest));\n        sha256->digest[0] = 0x6A09E667L;\n        sha256->digest[1] = 0xBB67AE85L;\n        sha256->digest[2] = 0x3C6EF372L;\n        sha256->digest[3] = 0xA54FF53AL;\n        sha256->digest[4] = 0x510E527FL;\n        sha256->digest[5] = 0x9B05688CL;\n        sha256->digest[6] = 0x1F83D9ABL;\n        sha256->digest[7] = 0x5BE0CD19L;\n\n        sha256->buffLen = 0;\n        sha256->loLen   = 0;\n        sha256->hiLen   = 0;\n\n        /* always start firstblock = 1 when using hw engine */\n        sha256->ctx.isfirstblock = 1;\n        sha256->ctx.sha_type = SHA2_256;\n        if(sha256->ctx.mode == ESP32_SHA_HW) {\n            /* release hw */\n            esp_sha_hw_unlock();\n        }\n        /* always set mode as INIT\n        *  whether using HW or SW is detemined at first call of update()\n        */\n        sha256->ctx.mode = ESP32_SHA_INIT;\n\n        return ret;\n    }\n    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)\n    {\n        int ret = 0;\n\n        if (sha256 == NULL)\n            return BAD_FUNC_ARG;\n\n        XMEMSET(sha256, 0, sizeof(wc_Sha256));\n        sha256->ctx.mode = ESP32_SHA_INIT;\n        sha256->ctx.isfirstblock = 1;\n        (void)devId;\n\n        ret = InitSha256(sha256);\n\n        return ret;\n    }\n\n#elif defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \\\n    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)\n\n    /* implemented in wolfcrypt/src/port/Renesas/renesas_tsip_sha.c */\n\n#else\n    #define NEED_SOFT_SHA256\n\n    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)\n    {\n        int ret = 0;\n        if (sha256 == NULL)\n            return BAD_FUNC_ARG;\n\n        sha256->heap = heap;\n    #ifdef WOLF_CRYPTO_CB\n        sha256->devId = devId;\n        sha256->devCtx = NULL;\n    #endif\n\n        ret = InitSha256(sha256);\n        if (ret != 0)\n            return ret;\n\n    #ifdef WOLFSSL_SMALL_STACK_CACHE\n        sha256->W = NULL;\n    #endif\n\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)\n        ret = wolfAsync_DevCtxInit(&sha256->asyncDev,\n                            WOLFSSL_ASYNC_MARKER_SHA256, sha256->heap, devId);\n    #else\n        (void)devId;\n    #endif /* WOLFSSL_ASYNC_CRYPT */\n\n        return ret;\n    }\n#endif /* End Hardware Acceleration */\n\n#ifdef NEED_SOFT_SHA256\n\n    static const ALIGN32 word32 K[64] = {\n        0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL,\n        0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L,\n        0x243185BEL, 0x550C7DC3L, 0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L,\n        0xC19BF174L, 0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL,\n        0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL, 0x983E5152L,\n        0xA831C66DL, 0xB00327C8L, 0xBF597FC7L, 0xC6E00BF3L, 0xD5A79147L,\n        0x06CA6351L, 0x14292967L, 0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL,\n        0x53380D13L, 0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L,\n        0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L, 0xD192E819L,\n        0xD6990624L, 0xF40E3585L, 0x106AA070L, 0x19A4C116L, 0x1E376C08L,\n        0x2748774CL, 0x34B0BCB5L, 0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL,\n        0x682E6FF3L, 0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L,\n        0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L\n    };\n\n/* Both versions of Ch and Maj are logically the same, but with the second set\n    the compilers can recognize them better for optimization */\n#ifdef WOLFSSL_SHA256_BY_SPEC\n    /* SHA256 math based on specification */\n    #define Ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))\n    #define Maj(x,y,z)      ((((x) | (y)) & (z)) | ((x) & (y)))\n#else\n    /* SHA256 math reworked for easier compiler optimization */\n    #define Ch(x,y,z)       ((((y) ^ (z)) & (x)) ^ (z))\n    #define Maj(x,y,z)      ((((x) ^ (y)) & ((y) ^ (z))) ^ (y))\n#endif\n    #define R(x, n)         (((x) & 0xFFFFFFFFU) >> (n))\n\n    #define S(x, n)         rotrFixed(x, n)\n    #define Sigma0(x)       (S(x, 2)  ^ S(x, 13) ^ S(x, 22))\n    #define Sigma1(x)       (S(x, 6)  ^ S(x, 11) ^ S(x, 25))\n    #define Gamma0(x)       (S(x, 7)  ^ S(x, 18) ^ R(x, 3))\n    #define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))\n\n    #define a(i) S[(0-i) & 7]\n    #define b(i) S[(1-i) & 7]\n    #define c(i) S[(2-i) & 7]\n    #define d(i) S[(3-i) & 7]\n    #define e(i) S[(4-i) & 7]\n    #define f(i) S[(5-i) & 7]\n    #define g(i) S[(6-i) & 7]\n    #define h(i) S[(7-i) & 7]\n\n    #ifndef XTRANSFORM\n         #define XTRANSFORM(S, D)         Transform_Sha256((S),(D))\n    #endif\n\n#ifndef SHA256_MANY_REGISTERS\n    #define RND(j) \\\n         t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+j] + W[i+j]; \\\n         t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \\\n         d(j) += t0; \\\n         h(j)  = t0 + t1\n\n    static int Transform_Sha256(wc_Sha256* sha256, const byte* data)\n    {\n        word32 S[8], t0, t1;\n        int i;\n\n    #ifdef WOLFSSL_SMALL_STACK_CACHE\n        word32* W = sha256->W;\n        if (W == NULL) {\n            W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE, NULL,\n                                                           DYNAMIC_TYPE_DIGEST);\n            if (W == NULL)\n                return MEMORY_E;\n            sha256->W = W;\n        }\n    #elif defined(WOLFSSL_SMALL_STACK)\n        word32* W;\n        W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE, NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n        if (W == NULL)\n            return MEMORY_E;\n    #else\n        word32 W[WC_SHA256_BLOCK_SIZE];\n    #endif\n\n        /* Copy context->state[] to working vars */\n        for (i = 0; i < 8; i++)\n            S[i] = sha256->digest[i];\n\n        for (i = 0; i < 16; i++)\n            W[i] = *((word32*)&data[i*sizeof(word32)]);\n\n        for (i = 16; i < WC_SHA256_BLOCK_SIZE; i++)\n            W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16];\n\n    #ifdef USE_SLOW_SHA256\n        /* not unrolled - ~2k smaller and ~25% slower */\n        for (i = 0; i < WC_SHA256_BLOCK_SIZE; i += 8) {\n            int j;\n            for (j = 0; j < 8; j++) { /* braces needed here for macros {} */\n                RND(j);\n            }\n        }\n    #else\n        /* partially loop unrolled */\n        for (i = 0; i < WC_SHA256_BLOCK_SIZE; i += 8) {\n            RND(0); RND(1); RND(2); RND(3);\n            RND(4); RND(5); RND(6); RND(7);\n        }\n    #endif /* USE_SLOW_SHA256 */\n\n        /* Add the working vars back into digest state[] */\n        for (i = 0; i < 8; i++) {\n            sha256->digest[i] += S[i];\n        }\n\n    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE)\n        XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    #endif\n        return 0;\n    }\n#else\n    /* SHA256 version that keeps all data in registers */\n    #define SCHED1(j) (W[j] = *((word32*)&data[j*sizeof(word32)]))\n    #define SCHED(j) (               \\\n                   W[ j     & 15] += \\\n            Gamma1(W[(j-2)  & 15])+  \\\n                   W[(j-7)  & 15] +  \\\n            Gamma0(W[(j-15) & 15])   \\\n        )\n\n    #define RND1(j) \\\n         t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+j] + SCHED1(j); \\\n         t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \\\n         d(j) += t0; \\\n         h(j)  = t0 + t1\n    #define RNDN(j) \\\n         t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+j] + SCHED(j); \\\n         t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \\\n         d(j) += t0; \\\n         h(j)  = t0 + t1\n\n    static int Transform_Sha256(wc_Sha256* sha256, const byte* data)\n    {\n        word32 S[8], t0, t1;\n        int i;\n        word32 W[WC_SHA256_BLOCK_SIZE/sizeof(word32)];\n\n        /* Copy digest to working vars */\n        S[0] = sha256->digest[0];\n        S[1] = sha256->digest[1];\n        S[2] = sha256->digest[2];\n        S[3] = sha256->digest[3];\n        S[4] = sha256->digest[4];\n        S[5] = sha256->digest[5];\n        S[6] = sha256->digest[6];\n        S[7] = sha256->digest[7];\n\n        i = 0;\n        RND1( 0); RND1( 1); RND1( 2); RND1( 3);\n        RND1( 4); RND1( 5); RND1( 6); RND1( 7);\n        RND1( 8); RND1( 9); RND1(10); RND1(11);\n        RND1(12); RND1(13); RND1(14); RND1(15);\n        /* 64 operations, partially loop unrolled */\n        for (i = 16; i < 64; i += 16) {\n            RNDN( 0); RNDN( 1); RNDN( 2); RNDN( 3);\n            RNDN( 4); RNDN( 5); RNDN( 6); RNDN( 7);\n            RNDN( 8); RNDN( 9); RNDN(10); RNDN(11);\n            RNDN(12); RNDN(13); RNDN(14); RNDN(15);\n        }\n\n        /* Add the working vars back into digest */\n        sha256->digest[0] += S[0];\n        sha256->digest[1] += S[1];\n        sha256->digest[2] += S[2];\n        sha256->digest[3] += S[3];\n        sha256->digest[4] += S[4];\n        sha256->digest[5] += S[5];\n        sha256->digest[6] += S[6];\n        sha256->digest[7] += S[7];\n\n        return 0;\n    }\n#endif /* SHA256_MANY_REGISTERS */\n#endif\n/* End wc_ software implementation */\n\n\n#ifdef XTRANSFORM\n\n    static WC_INLINE void AddLength(wc_Sha256* sha256, word32 len)\n    {\n        word32 tmp = sha256->loLen;\n        if ((sha256->loLen += len) < tmp) {\n            sha256->hiLen++;                       /* carry low to high */\n        }\n    }\n\n    /* do block size increments/updates */\n    static WC_INLINE int Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)\n    {\n        int ret = 0;\n        word32 blocksLen;\n        byte* local;\n\n        if (sha256 == NULL || (data == NULL && len > 0)) {\n            return BAD_FUNC_ARG;\n        }\n\n        if (data == NULL && len == 0) {\n            /* valid, but do nothing */\n            return 0;\n        }\n\n        /* check that internal buffLen is valid */\n        if (sha256->buffLen >= WC_SHA256_BLOCK_SIZE) {\n            return BUFFER_E;\n        }\n\n        /* add length for final */\n        AddLength(sha256, len);\n\n        local = (byte*)sha256->buffer;\n\n        /* process any remainder from previous operation */\n        if (sha256->buffLen > 0) {\n            blocksLen = min(len, WC_SHA256_BLOCK_SIZE - sha256->buffLen);\n            XMEMCPY(&local[sha256->buffLen], data, blocksLen);\n\n            sha256->buffLen += blocksLen;\n            data            += blocksLen;\n            len             -= blocksLen;\n\n            if (sha256->buffLen == WC_SHA256_BLOCK_SIZE) {\n            #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)\n                #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n                if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))\n                #endif\n                {\n                    ByteReverseWords(sha256->buffer, sha256->buffer,\n                        WC_SHA256_BLOCK_SIZE);\n                }\n            #endif\n\n            #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n                !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n                if (sha256->ctx.mode == ESP32_SHA_INIT){\n                    esp_sha_try_hw_lock(&sha256->ctx);\n                }\n                if (sha256->ctx.mode == ESP32_SHA_SW){\n                    ret = XTRANSFORM(sha256, (const byte*)local);\n                } else {\n                    esp_sha256_process(sha256, (const byte*)local);\n                }\n            #else\n                ret = XTRANSFORM(sha256, (const byte*)local);\n            #endif\n\n                if (ret == 0)\n                    sha256->buffLen = 0;\n                else\n                    len = 0; /* error */\n            }\n        }\n\n        /* process blocks */\n    #ifdef XTRANSFORM_LEN\n        #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n        if (Transform_Sha256_Len_p != NULL)\n        #endif\n        {\n            /* get number of blocks */\n            /* 64-1 = 0x3F (~ Inverted = 0xFFFFFFC0) */\n            /* len (masked by 0xFFFFFFC0) returns block aligned length */\n            blocksLen = len & ~(WC_SHA256_BLOCK_SIZE-1);\n            if (blocksLen > 0) {\n                /* Byte reversal and alignment handled in function if required */\n                XTRANSFORM_LEN(sha256, data, blocksLen);\n                data += blocksLen;\n                len  -= blocksLen;\n            }\n        }\n        #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n        else\n        #endif\n    #endif /* XTRANSFORM_LEN */\n    #if !defined(XTRANSFORM_LEN) || defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n        {\n            while (len >= WC_SHA256_BLOCK_SIZE) {\n                word32* local32 = sha256->buffer;\n                /* optimization to avoid memcpy if data pointer is properly aligned */\n                /* Intel transform function requires use of sha256->buffer */\n                /* Little Endian requires byte swap, so can't use data directly */\n            #if defined(WC_HASH_DATA_ALIGNMENT) && !defined(LITTLE_ENDIAN_ORDER) && \\\n                !defined(HAVE_INTEL_AVX1) && !defined(HAVE_INTEL_AVX2)\n                if (((size_t)data % WC_HASH_DATA_ALIGNMENT) == 0) {\n                    local32 = (word32*)data;\n                }\n                else\n            #endif\n                {\n                    XMEMCPY(local32, data, WC_SHA256_BLOCK_SIZE);\n                }\n\n                data += WC_SHA256_BLOCK_SIZE;\n                len  -= WC_SHA256_BLOCK_SIZE;\n\n            #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)\n                #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n                if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))\n                #endif\n                {\n                    ByteReverseWords(local32, local32, WC_SHA256_BLOCK_SIZE);\n                }\n            #endif\n\n            #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n                !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n                if (sha256->ctx.mode == ESP32_SHA_INIT){\n                    esp_sha_try_hw_lock(&sha256->ctx);\n                }\n                if (sha256->ctx.mode == ESP32_SHA_SW){\n                    ret = XTRANSFORM(sha256, (const byte*)local32);\n                } else {\n                    esp_sha256_process(sha256, (const byte*)local32);\n                }\n            #else\n                ret = XTRANSFORM(sha256, (const byte*)local32);\n            #endif\n\n                if (ret != 0)\n                    break;\n            }\n        }\n    #endif\n\n        /* save remainder */\n        if (len > 0) {\n            XMEMCPY(local, data, len);\n            sha256->buffLen = len;\n        }\n\n        return ret;\n    }\n\n    int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)\n    {\n        if (sha256 == NULL || (data == NULL && len > 0)) {\n            return BAD_FUNC_ARG;\n        }\n\n        if (data == NULL && len == 0) {\n            /* valid, but do nothing */\n            return 0;\n        }\n\n    #ifdef WOLF_CRYPTO_CB\n        if (sha256->devId != INVALID_DEVID) {\n            int ret = wc_CryptoCb_Sha256Hash(sha256, data, len, NULL);\n            if (ret != CRYPTOCB_UNAVAILABLE)\n                return ret;\n            /* fall-through when unavailable */\n        }\n    #endif\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)\n        if (sha256->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA256) {\n        #if defined(HAVE_INTEL_QA)\n            return IntelQaSymSha256(&sha256->asyncDev, NULL, data, len);\n        #endif\n        }\n    #endif /* WOLFSSL_ASYNC_CRYPT */\n\n        return Sha256Update(sha256, data, len);\n    }\n\n    static WC_INLINE int Sha256Final(wc_Sha256* sha256)\n    {\n\n        int ret;\n        byte* local;\n\n        if (sha256 == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n        local = (byte*)sha256->buffer;\n        local[sha256->buffLen++] = 0x80; /* add 1 */\n\n        /* pad with zeros */\n        if (sha256->buffLen > WC_SHA256_PAD_SIZE) {\n            XMEMSET(&local[sha256->buffLen], 0,\n                WC_SHA256_BLOCK_SIZE - sha256->buffLen);\n            sha256->buffLen += WC_SHA256_BLOCK_SIZE - sha256->buffLen;\n\n        #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)\n            #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n            if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))\n            #endif\n            {\n                ByteReverseWords(sha256->buffer, sha256->buffer,\n                                                      WC_SHA256_BLOCK_SIZE);\n            }\n        #endif\n\n        #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n             !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n            if (sha256->ctx.mode == ESP32_SHA_INIT) {\n                esp_sha_try_hw_lock(&sha256->ctx);\n            }\n            if (sha256->ctx.mode == ESP32_SHA_SW) {\n                ret = XTRANSFORM(sha256, (const byte*)local);\n            } else {\n                ret = esp_sha256_process(sha256, (const byte*)local);\n            }\n        #else\n            ret = XTRANSFORM(sha256, (const byte*)local);\n        #endif\n            if (ret != 0)\n                return ret;\n\n            sha256->buffLen = 0;\n        }\n        XMEMSET(&local[sha256->buffLen], 0,\n            WC_SHA256_PAD_SIZE - sha256->buffLen);\n\n        /* put lengths in bits */\n        sha256->hiLen = (sha256->loLen >> (8 * sizeof(sha256->loLen) - 3)) +\n                                                         (sha256->hiLen << 3);\n        sha256->loLen = sha256->loLen << 3;\n\n        /* store lengths */\n    #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)\n        #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n        if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))\n        #endif\n        {\n            ByteReverseWords(sha256->buffer, sha256->buffer,\n                WC_SHA256_BLOCK_SIZE);\n        }\n    #endif\n        /* ! length ordering dependent on digest endian type ! */\n        XMEMCPY(&local[WC_SHA256_PAD_SIZE], &sha256->hiLen, sizeof(word32));\n        XMEMCPY(&local[WC_SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen,\n                sizeof(word32));\n\n    #if defined(FREESCALE_MMCAU_SHA) || defined(HAVE_INTEL_AVX1) || \\\n        defined(HAVE_INTEL_AVX2)\n        /* Kinetis requires only these bytes reversed */\n        #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n        if (IS_INTEL_AVX1(intel_flags) || IS_INTEL_AVX2(intel_flags))\n        #endif\n        {\n            ByteReverseWords(\n                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],\n                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],\n                2 * sizeof(word32));\n        }\n    #endif\n\n    #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n         !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n        if (sha256->ctx.mode == ESP32_SHA_INIT) {\n            esp_sha_try_hw_lock(&sha256->ctx);\n        }\n        if (sha256->ctx.mode == ESP32_SHA_SW) {\n            ret = XTRANSFORM(sha256, (const byte*)local);\n        } else {\n            ret = esp_sha256_digest_process(sha256, 1);\n        }\n    #else\n        ret = XTRANSFORM(sha256, (const byte*)local);\n    #endif\n\n        return ret;\n    }\n\n    int wc_Sha256FinalRaw(wc_Sha256* sha256, byte* hash)\n    {\n    #ifdef LITTLE_ENDIAN_ORDER\n        word32 digest[WC_SHA256_DIGEST_SIZE / sizeof(word32)];\n    #endif\n\n        if (sha256 == NULL || hash == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n    #ifdef LITTLE_ENDIAN_ORDER\n        ByteReverseWords((word32*)digest, (word32*)sha256->digest,\n                                                         WC_SHA256_DIGEST_SIZE);\n        XMEMCPY(hash, digest, WC_SHA256_DIGEST_SIZE);\n    #else\n        XMEMCPY(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);\n    #endif\n\n        return 0;\n    }\n\n    int wc_Sha256Final(wc_Sha256* sha256, byte* hash)\n    {\n        int ret;\n\n        if (sha256 == NULL || hash == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n    #ifdef WOLF_CRYPTO_CB\n        if (sha256->devId != INVALID_DEVID) {\n            ret = wc_CryptoCb_Sha256Hash(sha256, NULL, 0, hash);\n            if (ret != CRYPTOCB_UNAVAILABLE)\n                return ret;\n            /* fall-through when unavailable */\n        }\n    #endif\n\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)\n        if (sha256->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA256) {\n        #if defined(HAVE_INTEL_QA)\n            return IntelQaSymSha256(&sha256->asyncDev, hash, NULL,\n                                            WC_SHA256_DIGEST_SIZE);\n        #endif\n        }\n    #endif /* WOLFSSL_ASYNC_CRYPT */\n\n        ret = Sha256Final(sha256);\n        if (ret != 0)\n            return ret;\n\n    #if defined(LITTLE_ENDIAN_ORDER)\n        ByteReverseWords(sha256->digest, sha256->digest, WC_SHA256_DIGEST_SIZE);\n    #endif\n        XMEMCPY(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);\n\n        return InitSha256(sha256);  /* reset state */\n    }\n\n#endif /* XTRANSFORM */\n\n#ifdef WOLFSSL_SHA224\n\n#ifdef STM32_HASH_SHA2\n\n    /* Supports CubeMX HAL or Standard Peripheral Library */\n\n    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)\n    {\n        if (sha224 == NULL)\n            return BAD_FUNC_ARG;\n\n        (void)devId;\n        (void)heap;\n\n        wc_Stm32_Hash_Init(&sha224->stmCtx);\n        return 0;\n    }\n\n    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)\n    {\n        int ret = 0;\n\n        if (sha224 == NULL || (data == NULL && len > 0)) {\n            return BAD_FUNC_ARG;\n        }\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret == 0) {\n            ret = wc_Stm32_Hash_Update(&sha224->stmCtx,\n                HASH_AlgoSelection_SHA224, data, len);\n            wolfSSL_CryptHwMutexUnLock();\n        }\n        return ret;\n    }\n\n    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)\n    {\n        int ret = 0;\n\n        if (sha224 == NULL || hash == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n        ret = wolfSSL_CryptHwMutexLock();\n        if (ret == 0) {\n            ret = wc_Stm32_Hash_Final(&sha224->stmCtx,\n                HASH_AlgoSelection_SHA224, hash, WC_SHA224_DIGEST_SIZE);\n            wolfSSL_CryptHwMutexUnLock();\n        }\n\n        (void)wc_InitSha224(sha224); /* reset state */\n\n        return ret;\n    }\n\n#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)\n    /* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */\n\n#elif defined(WOLFSSL_AFALG_HASH)\n    #error SHA224 currently not supported with AF_ALG enabled\n\n#elif defined(WOLFSSL_DEVCRYPTO_HASH)\n    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */\n\n#else\n\n    #define NEED_SOFT_SHA224\n\n\n    static int InitSha224(wc_Sha224* sha224)\n    {\n        int ret = 0;\n\n        if (sha224 == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n        sha224->digest[0] = 0xc1059ed8;\n        sha224->digest[1] = 0x367cd507;\n        sha224->digest[2] = 0x3070dd17;\n        sha224->digest[3] = 0xf70e5939;\n        sha224->digest[4] = 0xffc00b31;\n        sha224->digest[5] = 0x68581511;\n        sha224->digest[6] = 0x64f98fa7;\n        sha224->digest[7] = 0xbefa4fa4;\n\n        sha224->buffLen = 0;\n        sha224->loLen   = 0;\n        sha224->hiLen   = 0;\n\n    #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)\n        /* choose best Transform function under this runtime environment */\n        Sha256_SetTransform();\n    #endif\n    #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n        sha224->flags = 0;\n    #endif\n\n        return ret;\n    }\n\n#endif\n\n#ifdef NEED_SOFT_SHA224\n    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)\n    {\n        int ret = 0;\n\n        if (sha224 == NULL)\n            return BAD_FUNC_ARG;\n\n        sha224->heap = heap;\n\n        ret = InitSha224(sha224);\n        if (ret != 0)\n            return ret;\n\n    #ifdef WOLFSSL_SMALL_STACK_CACHE\n        sha224->W = NULL;\n    #endif\n\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)\n        ret = wolfAsync_DevCtxInit(&sha224->asyncDev,\n                            WOLFSSL_ASYNC_MARKER_SHA224, sha224->heap, devId);\n    #else\n        (void)devId;\n    #endif /* WOLFSSL_ASYNC_CRYPT */\n\n        return ret;\n    }\n\n    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)\n    {\n        int ret;\n\n        if (sha224 == NULL || (data == NULL && len > 0)) {\n            return BAD_FUNC_ARG;\n        }\n\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)\n        if (sha224->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA224) {\n        #if defined(HAVE_INTEL_QA)\n            return IntelQaSymSha224(&sha224->asyncDev, NULL, data, len);\n        #endif\n        }\n    #endif /* WOLFSSL_ASYNC_CRYPT */\n\n        ret = Sha256Update((wc_Sha256*)sha224, data, len);\n\n        return ret;\n    }\n\n    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)\n    {\n        int ret;\n\n        if (sha224 == NULL || hash == NULL) {\n            return BAD_FUNC_ARG;\n        }\n\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)\n        if (sha224->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA224) {\n        #if defined(HAVE_INTEL_QA)\n            return IntelQaSymSha224(&sha224->asyncDev, hash, NULL,\n                                            WC_SHA224_DIGEST_SIZE);\n        #endif\n        }\n    #endif /* WOLFSSL_ASYNC_CRYPT */\n\n        ret = Sha256Final((wc_Sha256*)sha224);\n        if (ret != 0)\n            return ret;\n\n    #if defined(LITTLE_ENDIAN_ORDER)\n        ByteReverseWords(sha224->digest, sha224->digest, WC_SHA224_DIGEST_SIZE);\n    #endif\n        XMEMCPY(hash, sha224->digest, WC_SHA224_DIGEST_SIZE);\n\n        return InitSha224(sha224);  /* reset state */\n    }\n#endif /* end of SHA224 software implementation */\n\n    int wc_InitSha224(wc_Sha224* sha224)\n    {\n        return wc_InitSha224_ex(sha224, NULL, INVALID_DEVID);\n    }\n\n    void wc_Sha224Free(wc_Sha224* sha224)\n    {\n        if (sha224 == NULL)\n            return;\n\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    if (sha224->W != NULL) {\n        XFREE(sha224->W, NULL, DYNAMIC_TYPE_DIGEST);\n        sha224->W = NULL;\n    }\n#endif\n\n    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)\n        wolfAsync_DevCtxFree(&sha224->asyncDev, WOLFSSL_ASYNC_MARKER_SHA224);\n    #endif /* WOLFSSL_ASYNC_CRYPT */\n\n    #ifdef WOLFSSL_PIC32MZ_HASH\n        wc_Sha256Pic32Free(sha224);\n    #endif\n    }\n#endif /* WOLFSSL_SHA224 */\n\n\nint wc_InitSha256(wc_Sha256* sha256)\n{\n    return wc_InitSha256_ex(sha256, NULL, INVALID_DEVID);\n}\n\nvoid wc_Sha256Free(wc_Sha256* sha256)\n{\n    if (sha256 == NULL)\n        return;\n\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    if (sha256->W != NULL) {\n        XFREE(sha256->W, NULL, DYNAMIC_TYPE_DIGEST);\n        sha256->W = NULL;\n    }\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)\n    wolfAsync_DevCtxFree(&sha256->asyncDev, WOLFSSL_ASYNC_MARKER_SHA256);\n#endif /* WOLFSSL_ASYNC_CRYPT */\n#ifdef WOLFSSL_PIC32MZ_HASH\n    wc_Sha256Pic32Free(sha256);\n#endif\n#if defined(WOLFSSL_AFALG_HASH)\n    if (sha256->alFd > 0) {\n        close(sha256->alFd);\n        sha256->alFd = -1; /* avoid possible double close on socket */\n    }\n    if (sha256->rdFd > 0) {\n        close(sha256->rdFd);\n        sha256->rdFd = -1; /* avoid possible double close on socket */\n    }\n#endif /* WOLFSSL_AFALG_HASH */\n#ifdef WOLFSSL_DEVCRYPTO_HASH\n    wc_DevCryptoFree(&sha256->ctx);\n#endif /* WOLFSSL_DEVCRYPTO */\n#if (defined(WOLFSSL_AFALG_HASH) && defined(WOLFSSL_AFALG_HASH_KEEP)) || \\\n    (defined(WOLFSSL_DEVCRYPTO_HASH) && defined(WOLFSSL_DEVCRYPTO_HASH_KEEP)) || \\\n    (defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \\\n    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH))\n    if (sha256->msg != NULL) {\n        XFREE(sha256->msg, sha256->heap, DYNAMIC_TYPE_TMP_BUFFER);\n        sha256->msg = NULL;\n    }\n#endif\n}\n\n#endif /* !WOLFSSL_TI_HASH */\n#endif /* HAVE_FIPS */\n\n\n#ifndef WOLFSSL_TI_HASH\n#ifdef WOLFSSL_SHA224\n    int wc_Sha224GetHash(wc_Sha224* sha224, byte* hash)\n    {\n        int ret;\n        wc_Sha224 tmpSha224;\n\n        if (sha224 == NULL || hash == NULL)\n            return BAD_FUNC_ARG;\n\n        ret = wc_Sha224Copy(sha224, &tmpSha224);\n        if (ret == 0) {\n            ret = wc_Sha224Final(&tmpSha224, hash);\n            wc_Sha224Free(&tmpSha224);\n        }\n        return ret;\n    }\n    int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst)\n    {\n        int ret = 0;\n\n        if (src == NULL || dst == NULL)\n            return BAD_FUNC_ARG;\n\n        XMEMCPY(dst, src, sizeof(wc_Sha224));\n    #ifdef WOLFSSL_SMALL_STACK_CACHE\n        dst->W = NULL;\n    #endif\n\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);\n    #endif\n    #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n        dst->flags |= WC_HASH_FLAG_ISCOPY;\n    #endif\n\n        return ret;\n    }\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    int wc_Sha224SetFlags(wc_Sha224* sha224, word32 flags)\n    {\n        if (sha224) {\n            sha224->flags = flags;\n        }\n        return 0;\n    }\n    int wc_Sha224GetFlags(wc_Sha224* sha224, word32* flags)\n    {\n        if (sha224 && flags) {\n            *flags = sha224->flags;\n        }\n        return 0;\n    }\n#endif\n\n#endif /* WOLFSSL_SHA224 */\n\n#ifdef WOLFSSL_AFALG_HASH\n    /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */\n\n#elif defined(WOLFSSL_DEVCRYPTO_HASH)\n    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */\n\n#elif defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \\\n    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)\n\n    /* implemented in wolfcrypt/src/port/Renesas/renesas_tsip_sha.c */\n#else\n\nint wc_Sha256GetHash(wc_Sha256* sha256, byte* hash)\n{\n    int ret;\n    wc_Sha256 tmpSha256;\n\n    if (sha256 == NULL || hash == NULL)\n        return BAD_FUNC_ARG;\n\n#if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    if(sha256->ctx.mode == ESP32_SHA_INIT){\n        esp_sha_try_hw_lock(&sha256->ctx);\n    }\n    if(sha256->ctx.mode == ESP32_SHA_HW)\n    {\n        esp_sha256_digest_process(sha256, 0);\n    }\n#endif\n    ret = wc_Sha256Copy(sha256, &tmpSha256);\n    if (ret == 0) {\n        ret = wc_Sha256Final(&tmpSha256, hash);\n#if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n        sha256->ctx.mode = ESP32_SHA_SW;\n#endif\n\n        wc_Sha256Free(&tmpSha256);\n    }\n    return ret;\n}\nint wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)\n{\n    int ret = 0;\n\n    if (src == NULL || dst == NULL)\n        return BAD_FUNC_ARG;\n\n    XMEMCPY(dst, src, sizeof(wc_Sha256));\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    dst->W = NULL;\n#endif\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);\n#endif\n#ifdef WOLFSSL_PIC32MZ_HASH\n    ret = wc_Pic32HashCopy(&src->cache, &dst->cache);\n#endif\n#if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n     dst->ctx.mode = src->ctx.mode;\n     dst->ctx.isfirstblock = src->ctx.isfirstblock;\n     dst->ctx.sha_type = src->ctx.sha_type;\n#endif\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n     dst->flags |= WC_HASH_FLAG_ISCOPY;\n#endif\n\n    return ret;\n}\n#endif\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\nint wc_Sha256SetFlags(wc_Sha256* sha256, word32 flags)\n{\n    if (sha256) {\n        sha256->flags = flags;\n    }\n    return 0;\n}\nint wc_Sha256GetFlags(wc_Sha256* sha256, word32* flags)\n{\n    if (sha256 && flags) {\n        *flags = sha256->flags;\n    }\n    return 0;\n}\n#endif\n#endif /* !WOLFSSL_TI_HASH */\n\n#endif /* NO_SHA256 */\n"
  },
  {
    "path": "src/wolfcrypt/src/sha3.c",
    "content": "/* sha3.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_XILINX_CRYPT) && \\\n   !defined(WOLFSSL_AFALG_XILINX_SHA3)\n\n#if defined(HAVE_FIPS) && \\\n\tdefined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n\n    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */\n    #define FIPS_NO_WRAPPERS\n\n    #ifdef USE_WINDOWS_API\n        #pragma code_seg(\".fipsA$l\")\n        #pragma const_seg(\".fipsB$l\")\n    #endif\n#endif\n\n#include <wolfssl/wolfcrypt/sha3.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/hash.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\n#ifdef WOLFSSL_SHA3_SMALL\n/* Rotate a 64-bit value left.\n *\n * a  Number to rotate left.\n * r  Number od bits to rotate left.\n * returns the rotated number.\n */\n#define ROTL64(a, n)    (((a)<<(n))|((a)>>(64-(n))))\n\n/* An array of values to XOR for block operation. */\nstatic const word64 hash_keccak_r[24] =\n{\n    0x0000000000000001UL, 0x0000000000008082UL,\n    0x800000000000808aUL, 0x8000000080008000UL,\n    0x000000000000808bUL, 0x0000000080000001UL,\n    0x8000000080008081UL, 0x8000000000008009UL,\n    0x000000000000008aUL, 0x0000000000000088UL,\n    0x0000000080008009UL, 0x000000008000000aUL,\n    0x000000008000808bUL, 0x800000000000008bUL,\n    0x8000000000008089UL, 0x8000000000008003UL,\n    0x8000000000008002UL, 0x8000000000000080UL,\n    0x000000000000800aUL, 0x800000008000000aUL,\n    0x8000000080008081UL, 0x8000000000008080UL,\n    0x0000000080000001UL, 0x8000000080008008UL\n};\n\n/* Indeces used in swap and rotate operation. */\n#define K_I_0   10\n#define K_I_1    7\n#define K_I_2   11\n#define K_I_3   17\n#define K_I_4   18\n#define K_I_5    3\n#define K_I_6    5\n#define K_I_7   16\n#define K_I_8    8\n#define K_I_9   21\n#define K_I_10  24\n#define K_I_11   4\n#define K_I_12  15\n#define K_I_13  23\n#define K_I_14  19\n#define K_I_15  13\n#define K_I_16  12\n#define K_I_17   2\n#define K_I_18  20\n#define K_I_19  14\n#define K_I_20  22\n#define K_I_21   9\n#define K_I_22   6\n#define K_I_23   1\n\n/* Number of bits to rotate in swap and rotate operation. */\n#define K_R_0    1\n#define K_R_1    3\n#define K_R_2    6\n#define K_R_3   10\n#define K_R_4   15\n#define K_R_5   21\n#define K_R_6   28\n#define K_R_7   36\n#define K_R_8   45\n#define K_R_9   55\n#define K_R_10   2\n#define K_R_11  14\n#define K_R_12  27\n#define K_R_13  41\n#define K_R_14  56\n#define K_R_15   8\n#define K_R_16  25\n#define K_R_17  43\n#define K_R_18  62\n#define K_R_19  18\n#define K_R_20  39\n#define K_R_21  61\n#define K_R_22  20\n#define K_R_23  44\n\n/* Swap and rotate left operation.\n *\n * s   The state.\n * t1  Temporary value.\n * t2  Second temporary value.\n * i   The index of the loop.\n */\n#define SWAP_ROTL(s, t1, t2, i)                                         \\\ndo                                                                      \\\n{                                                                       \\\n    t2 = s[K_I_##i]; s[K_I_##i] = ROTL64(t1, K_R_##i);                  \\\n}                                                                       \\\nwhile (0)\n\n/* Mix the XOR of the column's values into each number by column.\n *\n * s  The state.\n * b  Temporary array of XORed column values.\n * x  The index of the column.\n * t  Temporary variable.\n */\n#define COL_MIX(s, b, x, t)                                             \\\ndo                                                                      \\\n{                                                                       \\\n    for (x = 0; x < 5; x++)                                             \\\n        b[x] = s[x + 0] ^ s[x + 5] ^ s[x + 10] ^ s[x + 15] ^ s[x + 20]; \\\n    for (x = 0; x < 5; x++)                                             \\\n    {                                                                   \\\n        t = b[(x + 4) % 5] ^ ROTL64(b[(x + 1) % 5], 1);                 \\\n        s[x +  0] ^= t;                                                 \\\n        s[x +  5] ^= t;                                                 \\\n        s[x + 10] ^= t;                                                 \\\n        s[x + 15] ^= t;                                                 \\\n        s[x + 20] ^= t;                                                 \\\n    }                                                                   \\\n}                                                                       \\\nwhile (0)\n\n#ifdef SHA3_BY_SPEC\n/* Mix the row values.\n * BMI1 has ANDN instruction ((~a) & b) - Haswell and above.\n *\n * s   The state.\n * b   Temporary array of XORed row values.\n * y   The index of the row to work on.\n * x   The index of the column.\n * t0  Temporary variable.\n * t1  Temporary variable.\n */\n#define ROW_MIX(s, b, y, x, t0, t1)                                     \\\ndo                                                                      \\\n{                                                                       \\\n    for (y = 0; y < 5; y++)                                             \\\n    {                                                                   \\\n        for (x = 0; x < 5; x++)                                         \\\n            b[x] = s[y * 5 + x];                                        \\\n        for (x = 0; x < 5; x++)                                         \\\n           s[y * 5 + x] = b[x] ^ (~b[(x + 1) % 5] & b[(x + 2) % 5]);    \\\n    }                                                                   \\\n}                                                                       \\\nwhile (0)\n#else\n/* Mix the row values.\n * a ^ (~b & c) == a ^ (c & (b ^ c)) == (a ^ b) ^ (b | c)\n *\n * s   The state.\n * b   Temporary array of XORed row values.\n * y   The index of the row to work on.\n * x   The index of the column.\n * t0  Temporary variable.\n * t1  Temporary variable.\n */\n#define ROW_MIX(s, b, y, x, t12, t34)                                   \\\ndo                                                                      \\\n{                                                                       \\\n    for (y = 0; y < 5; y++)                                             \\\n    {                                                                   \\\n        for (x = 0; x < 5; x++)                                         \\\n            b[x] = s[y * 5 + x];                                        \\\n        t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]);                       \\\n        s[y * 5 + 0] = b[0] ^ (b[2] &  t12);                            \\\n        s[y * 5 + 1] =  t12 ^ (b[2] | b[3]);                            \\\n        s[y * 5 + 2] = b[2] ^ (b[4] &  t34);                            \\\n        s[y * 5 + 3] =  t34 ^ (b[4] | b[0]);                            \\\n        s[y * 5 + 4] = b[4] ^ (b[1] & (b[0] ^ b[1]));                   \\\n    }                                                                   \\\n}                                                                       \\\nwhile (0)\n#endif /* SHA3_BY_SPEC */\n\n/* The block operation performed on the state.\n *\n * s  The state.\n */\nstatic void BlockSha3(word64 *s)\n{\n    byte i, x, y;\n    word64 t0, t1;\n    word64 b[5];\n\n    for (i = 0; i < 24; i++)\n    {\n        COL_MIX(s, b, x, t0);\n\n        t0 = s[1];\n        SWAP_ROTL(s, t0, t1,  0);\n        SWAP_ROTL(s, t1, t0,  1);\n        SWAP_ROTL(s, t0, t1,  2);\n        SWAP_ROTL(s, t1, t0,  3);\n        SWAP_ROTL(s, t0, t1,  4);\n        SWAP_ROTL(s, t1, t0,  5);\n        SWAP_ROTL(s, t0, t1,  6);\n        SWAP_ROTL(s, t1, t0,  7);\n        SWAP_ROTL(s, t0, t1,  8);\n        SWAP_ROTL(s, t1, t0,  9);\n        SWAP_ROTL(s, t0, t1, 10);\n        SWAP_ROTL(s, t1, t0, 11);\n        SWAP_ROTL(s, t0, t1, 12);\n        SWAP_ROTL(s, t1, t0, 13);\n        SWAP_ROTL(s, t0, t1, 14);\n        SWAP_ROTL(s, t1, t0, 15);\n        SWAP_ROTL(s, t0, t1, 16);\n        SWAP_ROTL(s, t1, t0, 17);\n        SWAP_ROTL(s, t0, t1, 18);\n        SWAP_ROTL(s, t1, t0, 19);\n        SWAP_ROTL(s, t0, t1, 20);\n        SWAP_ROTL(s, t1, t0, 21);\n        SWAP_ROTL(s, t0, t1, 22);\n        SWAP_ROTL(s, t1, t0, 23);\n\n        ROW_MIX(s, b, y, x, t0, t1);\n\n        s[0] ^= hash_keccak_r[i];\n    }\n}\n#else\n/* Rotate a 64-bit value left.\n *\n * a  Number to rotate left.\n * r  Number od bits to rotate left.\n * returns the rotated number.\n */\n#define ROTL64(a, n)    (((a)<<(n))|((a)>>(64-(n))))\n\n/* An array of values to XOR for block operation. */\nstatic const word64 hash_keccak_r[24] =\n{\n    0x0000000000000001UL, 0x0000000000008082UL,\n    0x800000000000808aUL, 0x8000000080008000UL,\n    0x000000000000808bUL, 0x0000000080000001UL,\n    0x8000000080008081UL, 0x8000000000008009UL,\n    0x000000000000008aUL, 0x0000000000000088UL,\n    0x0000000080008009UL, 0x000000008000000aUL,\n    0x000000008000808bUL, 0x800000000000008bUL,\n    0x8000000000008089UL, 0x8000000000008003UL,\n    0x8000000000008002UL, 0x8000000000000080UL,\n    0x000000000000800aUL, 0x800000008000000aUL,\n    0x8000000080008081UL, 0x8000000000008080UL,\n    0x0000000080000001UL, 0x8000000080008008UL\n};\n\n/* Indeces used in swap and rotate operation. */\n#define KI_0     6\n#define KI_1    12\n#define KI_2    18\n#define KI_3    24\n#define KI_4     3\n#define KI_5     9\n#define KI_6    10\n#define KI_7    16\n#define KI_8    22\n#define KI_9     1\n#define KI_10    7\n#define KI_11   13\n#define KI_12   19\n#define KI_13   20\n#define KI_14    4\n#define KI_15    5\n#define KI_16   11\n#define KI_17   17\n#define KI_18   23\n#define KI_19    2\n#define KI_20    8\n#define KI_21   14\n#define KI_22   15\n#define KI_23   21\n\n/* Number of bits to rotate in swap and rotate operation. */\n#define KR_0    44\n#define KR_1    43\n#define KR_2    21\n#define KR_3    14\n#define KR_4    28\n#define KR_5    20\n#define KR_6     3\n#define KR_7    45\n#define KR_8    61\n#define KR_9     1\n#define KR_10    6\n#define KR_11   25\n#define KR_12    8\n#define KR_13   18\n#define KR_14   27\n#define KR_15   36\n#define KR_16   10\n#define KR_17   15\n#define KR_18   56\n#define KR_19   62\n#define KR_20   55\n#define KR_21   39\n#define KR_22   41\n#define KR_23    2\n\n/* Mix the XOR of the column's values into each number by column.\n *\n * s  The state.\n * b  Temporary array of XORed column values.\n * x  The index of the column.\n * t  Temporary variable.\n */\n#define COL_MIX(s, b, x, t)                                     \\\ndo                                                              \\\n{                                                               \\\n    b[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];                 \\\n    b[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];                 \\\n    b[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];                 \\\n    b[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];                 \\\n    b[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];                 \\\n    t = b[(0 + 4) % 5] ^ ROTL64(b[(0 + 1) % 5], 1);             \\\n    s[ 0] ^= t; s[ 5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t; \\\n    t = b[(1 + 4) % 5] ^ ROTL64(b[(1 + 1) % 5], 1);             \\\n    s[ 1] ^= t; s[ 6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t; \\\n    t = b[(2 + 4) % 5] ^ ROTL64(b[(2 + 1) % 5], 1);             \\\n    s[ 2] ^= t; s[ 7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t; \\\n    t = b[(3 + 4) % 5] ^ ROTL64(b[(3 + 1) % 5], 1);             \\\n    s[ 3] ^= t; s[ 8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t; \\\n    t = b[(4 + 4) % 5] ^ ROTL64(b[(4 + 1) % 5], 1);             \\\n    s[ 4] ^= t; s[ 9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t; \\\n}                                                               \\\nwhile (0)\n\n#define S(s1, i) ROTL64(s1[KI_##i], KR_##i)\n\n#ifdef SHA3_BY_SPEC\n/* Mix the row values.\n * BMI1 has ANDN instruction ((~a) & b) - Haswell and above.\n *\n * s2  The new state.\n * s1  The current state.\n * b   Temporary array of XORed row values.\n * t0  Temporary variable. (Unused)\n * t1  Temporary variable. (Unused)\n */\n#define ROW_MIX(s2, s1, b, t0, t1)            \\\ndo                                            \\\n{                                             \\\n    b[0] = s1[0];                             \\\n    b[1] = S(s1, 0);                          \\\n    b[2] = S(s1, 1);                          \\\n    b[3] = S(s1, 2);                          \\\n    b[4] = S(s1, 3);                          \\\n    s2[0] = b[0] ^ (~b[1] & b[2]);            \\\n    s2[1] = b[1] ^ (~b[2] & b[3]);            \\\n    s2[2] = b[2] ^ (~b[3] & b[4]);            \\\n    s2[3] = b[3] ^ (~b[4] & b[0]);            \\\n    s2[4] = b[4] ^ (~b[0] & b[1]);            \\\n    b[0] = S(s1, 4);                          \\\n    b[1] = S(s1, 5);                          \\\n    b[2] = S(s1, 6);                          \\\n    b[3] = S(s1, 7);                          \\\n    b[4] = S(s1, 8);                          \\\n    s2[5] = b[0] ^ (~b[1] & b[2]);            \\\n    s2[6] = b[1] ^ (~b[2] & b[3]);            \\\n    s2[7] = b[2] ^ (~b[3] & b[4]);            \\\n    s2[8] = b[3] ^ (~b[4] & b[0]);            \\\n    s2[9] = b[4] ^ (~b[0] & b[1]);            \\\n    b[0] = S(s1, 9);                          \\\n    b[1] = S(s1, 10);                         \\\n    b[2] = S(s1, 11);                         \\\n    b[3] = S(s1, 12);                         \\\n    b[4] = S(s1, 13);                         \\\n    s2[10] = b[0] ^ (~b[1] & b[2]);           \\\n    s2[11] = b[1] ^ (~b[2] & b[3]);           \\\n    s2[12] = b[2] ^ (~b[3] & b[4]);           \\\n    s2[13] = b[3] ^ (~b[4] & b[0]);           \\\n    s2[14] = b[4] ^ (~b[0] & b[1]);           \\\n    b[0] = S(s1, 14);                         \\\n    b[1] = S(s1, 15);                         \\\n    b[2] = S(s1, 16);                         \\\n    b[3] = S(s1, 17);                         \\\n    b[4] = S(s1, 18);                         \\\n    s2[15] = b[0] ^ (~b[1] & b[2]);           \\\n    s2[16] = b[1] ^ (~b[2] & b[3]);           \\\n    s2[17] = b[2] ^ (~b[3] & b[4]);           \\\n    s2[18] = b[3] ^ (~b[4] & b[0]);           \\\n    s2[19] = b[4] ^ (~b[0] & b[1]);           \\\n    b[0] = S(s1, 19);                         \\\n    b[1] = S(s1, 20);                         \\\n    b[2] = S(s1, 21);                         \\\n    b[3] = S(s1, 22);                         \\\n    b[4] = S(s1, 23);                         \\\n    s2[20] = b[0] ^ (~b[1] & b[2]);           \\\n    s2[21] = b[1] ^ (~b[2] & b[3]);           \\\n    s2[22] = b[2] ^ (~b[3] & b[4]);           \\\n    s2[23] = b[3] ^ (~b[4] & b[0]);           \\\n    s2[24] = b[4] ^ (~b[0] & b[1]);           \\\n}                                             \\\nwhile (0)\n#else\n/* Mix the row values.\n * a ^ (~b & c) == a ^ (c & (b ^ c)) == (a ^ b) ^ (b | c)\n *\n * s2  The new state.\n * s1  The current state.\n * b   Temporary array of XORed row values.\n * t12 Temporary variable.\n * t34 Temporary variable.\n */\n#define ROW_MIX(s2, s1, b, t12, t34)          \\\ndo                                            \\\n{                                             \\\n    b[0] = s1[0];                             \\\n    b[1] = S(s1, 0);                          \\\n    b[2] = S(s1, 1);                          \\\n    b[3] = S(s1, 2);                          \\\n    b[4] = S(s1, 3);                          \\\n    t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \\\n    s2[0] = b[0] ^ (b[2] &  t12);             \\\n    s2[1] =  t12 ^ (b[2] | b[3]);             \\\n    s2[2] = b[2] ^ (b[4] &  t34);             \\\n    s2[3] =  t34 ^ (b[4] | b[0]);             \\\n    s2[4] = b[4] ^ (b[1] & (b[0] ^ b[1]));    \\\n    b[0] = S(s1, 4);                          \\\n    b[1] = S(s1, 5);                          \\\n    b[2] = S(s1, 6);                          \\\n    b[3] = S(s1, 7);                          \\\n    b[4] = S(s1, 8);                          \\\n    t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \\\n    s2[5] = b[0] ^ (b[2] &  t12);             \\\n    s2[6] =  t12 ^ (b[2] | b[3]);             \\\n    s2[7] = b[2] ^ (b[4] &  t34);             \\\n    s2[8] =  t34 ^ (b[4] | b[0]);             \\\n    s2[9] = b[4] ^ (b[1] & (b[0] ^ b[1]));    \\\n    b[0] = S(s1, 9);                          \\\n    b[1] = S(s1, 10);                         \\\n    b[2] = S(s1, 11);                         \\\n    b[3] = S(s1, 12);                         \\\n    b[4] = S(s1, 13);                         \\\n    t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \\\n    s2[10] = b[0] ^ (b[2] &  t12);            \\\n    s2[11] =  t12 ^ (b[2] | b[3]);            \\\n    s2[12] = b[2] ^ (b[4] &  t34);            \\\n    s2[13] =  t34 ^ (b[4] | b[0]);            \\\n    s2[14] = b[4] ^ (b[1] & (b[0] ^ b[1]));   \\\n    b[0] = S(s1, 14);                         \\\n    b[1] = S(s1, 15);                         \\\n    b[2] = S(s1, 16);                         \\\n    b[3] = S(s1, 17);                         \\\n    b[4] = S(s1, 18);                         \\\n    t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \\\n    s2[15] = b[0] ^ (b[2] &  t12);            \\\n    s2[16] =  t12 ^ (b[2] | b[3]);            \\\n    s2[17] = b[2] ^ (b[4] &  t34);            \\\n    s2[18] =  t34 ^ (b[4] | b[0]);            \\\n    s2[19] = b[4] ^ (b[1] & (b[0] ^ b[1]));   \\\n    b[0] = S(s1, 19);                         \\\n    b[1] = S(s1, 20);                         \\\n    b[2] = S(s1, 21);                         \\\n    b[3] = S(s1, 22);                         \\\n    b[4] = S(s1, 23);                         \\\n    t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \\\n    s2[20] = b[0] ^ (b[2] &  t12);            \\\n    s2[21] =  t12 ^ (b[2] | b[3]);            \\\n    s2[22] = b[2] ^ (b[4] &  t34);            \\\n    s2[23] =  t34 ^ (b[4] | b[0]);            \\\n    s2[24] = b[4] ^ (b[1] & (b[0] ^ b[1]));   \\\n}                                             \\\nwhile (0)\n#endif /* SHA3_BY_SPEC */\n\n/* The block operation performed on the state.\n *\n * s  The state.\n */\nstatic void BlockSha3(word64 *s)\n{\n    word64 n[25];\n    word64 b[5];\n    word64 t0;\n#ifndef SHA3_BY_SPEC\n    word64 t1;\n#endif\n    byte i;\n\n    for (i = 0; i < 24; i += 2)\n    {\n        COL_MIX(s, b, x, t0);\n        ROW_MIX(n, s, b, t0, t1);\n        n[0] ^= hash_keccak_r[i];\n\n        COL_MIX(n, b, x, t0);\n        ROW_MIX(s, n, b, t0, t1);\n        s[0] ^= hash_keccak_r[i+1];\n    }\n}\n#endif /* WOLFSSL_SHA3_SMALL */\n\n/* Convert the array of bytes, in little-endian order, to a 64-bit integer.\n *\n * a  Array of bytes.\n * returns a 64-bit integer.\n */\nstatic word64 Load64BitBigEndian(const byte* a)\n{\n#ifdef BIG_ENDIAN_ORDER\n    word64 n = 0;\n    int i;\n\n    for (i = 0; i < 8; i++)\n        n |= (word64)a[i] << (8 * i);\n\n    return n;\n#else\n    return *(word64*)a;\n#endif\n}\n\n/* Initialize the state for a SHA3-224 hash operation.\n *\n * sha3   wc_Sha3 object holding state.\n * returns 0 on success.\n */\nstatic int InitSha3(wc_Sha3* sha3)\n{\n    int i;\n\n    for (i = 0; i < 25; i++)\n        sha3->s[i] = 0;\n    sha3->i = 0;\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    sha3->flags = 0;\n#endif\n\n    return 0;\n}\n\n/* Update the SHA-3 hash state with message data.\n *\n * sha3  wc_Sha3 object holding state.\n * data  Message data to be hashed.\n * len   Length of the message data.\n * p     Number of 64-bit numbers in a block of data to process.\n * returns 0 on success.\n */\nstatic int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)\n{\n    byte i;\n    byte l;\n    byte *t;\n\n    if (sha3->i > 0)\n    {\n        l = p * 8 - sha3->i;\n        if (l > len) {\n            l = (byte)len;\n        }\n\n        t = &sha3->t[sha3->i];\n        for (i = 0; i < l; i++)\n            t[i] = data[i];\n        data += i;\n        len -= i;\n        sha3->i += i;\n\n        if (sha3->i == p * 8)\n        {\n            for (i = 0; i < p; i++)\n                sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i);\n            BlockSha3(sha3->s);\n            sha3->i = 0;\n        }\n    }\n    while (len >= ((word32)(p * 8)))\n    {\n        for (i = 0; i < p; i++)\n            sha3->s[i] ^= Load64BitBigEndian(data + 8 * i);\n        BlockSha3(sha3->s);\n        len -= p * 8;\n        data += p * 8;\n    }\n    for (i = 0; i < len; i++)\n        sha3->t[i] = data[i];\n    sha3->i += i;\n\n    return 0;\n}\n\n/* Calculate the SHA-3 hash based on all the message data seen.\n *\n * sha3  wc_Sha3 object holding state.\n * hash  Buffer to hold the hash result.\n * p     Number of 64-bit numbers in a block of data to process.\n * len   Number of bytes in output.\n * returns 0 on success.\n */\nstatic int Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte l)\n{\n    byte i;\n    byte *s8 = (byte *)sha3->s;\n    byte padChar = 0x06; /* NIST SHA-3 */\n\n    sha3->t[p * 8 - 1]  = 0x00;\n#ifdef WOLFSSL_HASH_FLAGS\n    if (p == WC_SHA3_256_COUNT && sha3->flags & WC_HASH_SHA3_KECCAK256) {\n        padChar = 0x01;\n    }\n#endif\n    sha3->t[  sha3->i]  = padChar;\n    sha3->t[p * 8 - 1] |= 0x80;\n    for (i=sha3->i + 1; i < p * 8 - 1; i++)\n        sha3->t[i] = 0;\n    for (i = 0; i < p; i++)\n        sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i);\n    BlockSha3(sha3->s);\n#if defined(BIG_ENDIAN_ORDER)\n    ByteReverseWords64(sha3->s, sha3->s, ((l+7)/8)*8);\n#endif\n    for (i = 0; i < l; i++)\n        hash[i] = s8[i];\n\n    return 0;\n}\n\n/* Initialize the state for a SHA-3 hash operation.\n *\n * sha3   wc_Sha3 object holding state.\n * heap   Heap reference for dynamic memory allocation. (Used in async ops.)\n * devId  Device identifier for asynchronous operation.\n * returns 0 on success.\n */\nstatic int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId)\n{\n    int ret = 0;\n\n    if (sha3 == NULL)\n        return BAD_FUNC_ARG;\n\n    sha3->heap = heap;\n    ret = InitSha3(sha3);\n    if (ret != 0)\n        return ret;\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)\n    ret = wolfAsync_DevCtxInit(&sha3->asyncDev,\n                        WOLFSSL_ASYNC_MARKER_SHA3, sha3->heap, devId);\n#else\n    (void)devId;\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    return ret;\n}\n\n/* Update the SHA-3 hash state with message data.\n *\n * sha3  wc_Sha3 object holding state.\n * data  Message data to be hashed.\n * len   Length of the message data.\n * p     Number of 64-bit numbers in a block of data to process.\n * returns 0 on success.\n */\nstatic int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)\n{\n    int ret;\n\n    if (sha3 == NULL || (data == NULL && len > 0)) {\n        return BAD_FUNC_ARG;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)\n    if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) {\n    #if defined(HAVE_INTEL_QA) && defined(QAT_V2)\n        /* QAT only supports SHA3_256 */\n        if (p == WC_SHA3_256_COUNT) {\n            ret = IntelQaSymSha3(&sha3->asyncDev, NULL, data, len);\n            if (ret != NOT_COMPILED_IN)\n                return ret;\n            /* fall-through when unavailable */\n        }\n    #endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    ret = Sha3Update(sha3, data, len, p);\n\n    return ret;\n}\n\n/* Calculate the SHA-3 hash based on all the message data seen.\n *\n * sha3  wc_Sha3 object holding state.\n * hash  Buffer to hold the hash result.\n * p     Number of 64-bit numbers in a block of data to process.\n * len   Number of bytes in output.\n * returns 0 on success.\n */\nstatic int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len)\n{\n    int ret;\n\n    if (sha3 == NULL || hash == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)\n    if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) {\n    #if defined(HAVE_INTEL_QA) && defined(QAT_V2)\n        /* QAT only supports SHA3_256 */\n        /* QAT SHA-3 only supported on v2 (8970 or later cards) */\n        if (len == WC_SHA3_256_DIGEST_SIZE) {\n            ret = IntelQaSymSha3(&sha3->asyncDev, hash, NULL, len);\n            if (ret != NOT_COMPILED_IN)\n                return ret;\n            /* fall-through when unavailable */\n        }\n    #endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    ret = Sha3Final(sha3, hash, p, len);\n    if (ret != 0)\n        return ret;\n\n    return InitSha3(sha3);  /* reset state */\n}\n\n/* Dispose of any dynamically allocated data from the SHA3-384 operation.\n * (Required for async ops.)\n *\n * sha3  wc_Sha3 object holding state.\n * returns 0 on success.\n */\nstatic void wc_Sha3Free(wc_Sha3* sha3)\n{\n    (void)sha3;\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)\n    if (sha3 == NULL)\n        return;\n\n    wolfAsync_DevCtxFree(&sha3->asyncDev, WOLFSSL_ASYNC_MARKER_SHA3);\n#endif /* WOLFSSL_ASYNC_CRYPT */\n}\n\n\n/* Copy the state of the SHA3 operation.\n *\n * src  wc_Sha3 object holding state top copy.\n * dst  wc_Sha3 object to copy into.\n * returns 0 on success.\n */\nstatic int wc_Sha3Copy(wc_Sha3* src, wc_Sha3* dst)\n{\n    int ret = 0;\n\n    if (src == NULL || dst == NULL)\n        return BAD_FUNC_ARG;\n\n    XMEMCPY(dst, src, sizeof(wc_Sha3));\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);\n#endif\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n     dst->flags |= WC_HASH_FLAG_ISCOPY;\n#endif\n\n    return ret;\n}\n\n/* Calculate the SHA3-224 hash based on all the message data so far.\n * More message data can be added, after this operation, using the current\n * state.\n *\n * sha3  wc_Sha3 object holding state.\n * hash  Buffer to hold the hash result. Must be at least 28 bytes.\n * p     Number of 64-bit numbers in a block of data to process.\n * len   Number of bytes in output.\n * returns 0 on success.\n */\nstatic int wc_Sha3GetHash(wc_Sha3* sha3, byte* hash, byte p, byte len)\n{\n    int ret;\n    wc_Sha3 tmpSha3;\n\n    if (sha3 == NULL || hash == NULL)\n        return BAD_FUNC_ARG;\n\n    ret = wc_Sha3Copy(sha3, &tmpSha3);\n    if (ret == 0) {\n        ret = wc_Sha3Final(&tmpSha3, hash, p, len);\n    }\n    return ret;\n}\n\n\n/* Initialize the state for a SHA3-224 hash operation.\n *\n * sha3   wc_Sha3 object holding state.\n * heap   Heap reference for dynamic memory allocation. (Used in async ops.)\n * devId  Device identifier for asynchronous operation.\n * returns 0 on success.\n */\nint wc_InitSha3_224(wc_Sha3* sha3, void* heap, int devId)\n{\n    return wc_InitSha3(sha3, heap, devId);\n}\n\n/* Update the SHA3-224 hash state with message data.\n *\n * sha3  wc_Sha3 object holding state.\n * data  Message data to be hashed.\n * len   Length of the message data.\n * returns 0 on success.\n */\nint wc_Sha3_224_Update(wc_Sha3* sha3, const byte* data, word32 len)\n{\n    return wc_Sha3Update(sha3, data, len, WC_SHA3_224_COUNT);\n}\n\n/* Calculate the SHA3-224 hash based on all the message data seen.\n * The state is initialized ready for a new message to hash.\n *\n * sha3  wc_Sha3 object holding state.\n * hash  Buffer to hold the hash result. Must be at least 28 bytes.\n * returns 0 on success.\n */\nint wc_Sha3_224_Final(wc_Sha3* sha3, byte* hash)\n{\n    return wc_Sha3Final(sha3, hash, WC_SHA3_224_COUNT, WC_SHA3_224_DIGEST_SIZE);\n}\n\n/* Dispose of any dynamically allocated data from the SHA3-224 operation.\n * (Required for async ops.)\n *\n * sha3  wc_Sha3 object holding state.\n * returns 0 on success.\n */\nvoid wc_Sha3_224_Free(wc_Sha3* sha3)\n{\n    wc_Sha3Free(sha3);\n}\n\n/* Calculate the SHA3-224 hash based on all the message data so far.\n * More message data can be added, after this operation, using the current\n * state.\n *\n * sha3  wc_Sha3 object holding state.\n * hash  Buffer to hold the hash result. Must be at least 28 bytes.\n * returns 0 on success.\n */\nint wc_Sha3_224_GetHash(wc_Sha3* sha3, byte* hash)\n{\n    return wc_Sha3GetHash(sha3, hash, WC_SHA3_224_COUNT, WC_SHA3_224_DIGEST_SIZE);\n}\n\n/* Copy the state of the SHA3-224 operation.\n *\n * src  wc_Sha3 object holding state top copy.\n * dst  wc_Sha3 object to copy into.\n * returns 0 on success.\n */\nint wc_Sha3_224_Copy(wc_Sha3* src, wc_Sha3* dst)\n{\n    return wc_Sha3Copy(src, dst);\n}\n\n\n/* Initialize the state for a SHA3-256 hash operation.\n *\n * sha3   wc_Sha3 object holding state.\n * heap   Heap reference for dynamic memory allocation. (Used in async ops.)\n * devId  Device identifier for asynchronous operation.\n * returns 0 on success.\n */\nint wc_InitSha3_256(wc_Sha3* sha3, void* heap, int devId)\n{\n    return wc_InitSha3(sha3, heap, devId);\n}\n\n/* Update the SHA3-256 hash state with message data.\n *\n * sha3  wc_Sha3 object holding state.\n * data  Message data to be hashed.\n * len   Length of the message data.\n * returns 0 on success.\n */\nint wc_Sha3_256_Update(wc_Sha3* sha3, const byte* data, word32 len)\n{\n    return wc_Sha3Update(sha3, data, len, WC_SHA3_256_COUNT);\n}\n\n/* Calculate the SHA3-256 hash based on all the message data seen.\n * The state is initialized ready for a new message to hash.\n *\n * sha3  wc_Sha3 object holding state.\n * hash  Buffer to hold the hash result. Must be at least 32 bytes.\n * returns 0 on success.\n */\nint wc_Sha3_256_Final(wc_Sha3* sha3, byte* hash)\n{\n    return wc_Sha3Final(sha3, hash, WC_SHA3_256_COUNT, WC_SHA3_256_DIGEST_SIZE);\n}\n\n/* Dispose of any dynamically allocated data from the SHA3-256 operation.\n * (Required for async ops.)\n *\n * sha3  wc_Sha3 object holding state.\n * returns 0 on success.\n */\nvoid wc_Sha3_256_Free(wc_Sha3* sha3)\n{\n    wc_Sha3Free(sha3);\n}\n\n/* Calculate the SHA3-256 hash based on all the message data so far.\n * More message data can be added, after this operation, using the current\n * state.\n *\n * sha3  wc_Sha3 object holding state.\n * hash  Buffer to hold the hash result. Must be at least 32 bytes.\n * returns 0 on success.\n */\nint wc_Sha3_256_GetHash(wc_Sha3* sha3, byte* hash)\n{\n    return wc_Sha3GetHash(sha3, hash, WC_SHA3_256_COUNT, WC_SHA3_256_DIGEST_SIZE);\n}\n\n/* Copy the state of the SHA3-256 operation.\n *\n * src  wc_Sha3 object holding state top copy.\n * dst  wc_Sha3 object to copy into.\n * returns 0 on success.\n */\nint wc_Sha3_256_Copy(wc_Sha3* src, wc_Sha3* dst)\n{\n    return wc_Sha3Copy(src, dst);\n}\n\n\n/* Initialize the state for a SHA3-384 hash operation.\n *\n * sha3   wc_Sha3 object holding state.\n * heap   Heap reference for dynamic memory allocation. (Used in async ops.)\n * devId  Device identifier for asynchronous operation.\n * returns 0 on success.\n */\nint wc_InitSha3_384(wc_Sha3* sha3, void* heap, int devId)\n{\n    return wc_InitSha3(sha3, heap, devId);\n}\n\n/* Update the SHA3-384 hash state with message data.\n *\n * sha3  wc_Sha3 object holding state.\n * data  Message data to be hashed.\n * len   Length of the message data.\n * returns 0 on success.\n */\nint wc_Sha3_384_Update(wc_Sha3* sha3, const byte* data, word32 len)\n{\n    return wc_Sha3Update(sha3, data, len, WC_SHA3_384_COUNT);\n}\n\n/* Calculate the SHA3-384 hash based on all the message data seen.\n * The state is initialized ready for a new message to hash.\n *\n * sha3  wc_Sha3 object holding state.\n * hash  Buffer to hold the hash result. Must be at least 48 bytes.\n * returns 0 on success.\n */\nint wc_Sha3_384_Final(wc_Sha3* sha3, byte* hash)\n{\n    return wc_Sha3Final(sha3, hash, WC_SHA3_384_COUNT, WC_SHA3_384_DIGEST_SIZE);\n}\n\n/* Dispose of any dynamically allocated data from the SHA3-384 operation.\n * (Required for async ops.)\n *\n * sha3  wc_Sha3 object holding state.\n * returns 0 on success.\n */\nvoid wc_Sha3_384_Free(wc_Sha3* sha3)\n{\n    wc_Sha3Free(sha3);\n}\n\n/* Calculate the SHA3-384 hash based on all the message data so far.\n * More message data can be added, after this operation, using the current\n * state.\n *\n * sha3  wc_Sha3 object holding state.\n * hash  Buffer to hold the hash result. Must be at least 48 bytes.\n * returns 0 on success.\n */\nint wc_Sha3_384_GetHash(wc_Sha3* sha3, byte* hash)\n{\n    return wc_Sha3GetHash(sha3, hash, WC_SHA3_384_COUNT, WC_SHA3_384_DIGEST_SIZE);\n}\n\n/* Copy the state of the SHA3-384 operation.\n *\n * src  wc_Sha3 object holding state top copy.\n * dst  wc_Sha3 object to copy into.\n * returns 0 on success.\n */\nint wc_Sha3_384_Copy(wc_Sha3* src, wc_Sha3* dst)\n{\n    return wc_Sha3Copy(src, dst);\n}\n\n\n/* Initialize the state for a SHA3-512 hash operation.\n *\n * sha3   wc_Sha3 object holding state.\n * heap   Heap reference for dynamic memory allocation. (Used in async ops.)\n * devId  Device identifier for asynchronous operation.\n * returns 0 on success.\n */\nint wc_InitSha3_512(wc_Sha3* sha3, void* heap, int devId)\n{\n    return wc_InitSha3(sha3, heap, devId);\n}\n\n/* Update the SHA3-512 hash state with message data.\n *\n * sha3  wc_Sha3 object holding state.\n * data  Message data to be hashed.\n * len   Length of the message data.\n * returns 0 on success.\n */\nint wc_Sha3_512_Update(wc_Sha3* sha3, const byte* data, word32 len)\n{\n    return wc_Sha3Update(sha3, data, len, WC_SHA3_512_COUNT);\n}\n\n/* Calculate the SHA3-512 hash based on all the message data seen.\n * The state is initialized ready for a new message to hash.\n *\n * sha3  wc_Sha3 object holding state.\n * hash  Buffer to hold the hash result. Must be at least 64 bytes.\n * returns 0 on success.\n */\nint wc_Sha3_512_Final(wc_Sha3* sha3, byte* hash)\n{\n    return wc_Sha3Final(sha3, hash, WC_SHA3_512_COUNT, WC_SHA3_512_DIGEST_SIZE);\n}\n\n/* Dispose of any dynamically allocated data from the SHA3-512 operation.\n * (Required for async ops.)\n *\n * sha3  wc_Sha3 object holding state.\n * returns 0 on success.\n */\nvoid wc_Sha3_512_Free(wc_Sha3* sha3)\n{\n    wc_Sha3Free(sha3);\n}\n\n/* Calculate the SHA3-512 hash based on all the message data so far.\n * More message data can be added, after this operation, using the current\n * state.\n *\n * sha3  wc_Sha3 object holding state.\n * hash  Buffer to hold the hash result. Must be at least 64 bytes.\n * returns 0 on success.\n */\nint wc_Sha3_512_GetHash(wc_Sha3* sha3, byte* hash)\n{\n    return wc_Sha3GetHash(sha3, hash, WC_SHA3_512_COUNT, WC_SHA3_512_DIGEST_SIZE);\n}\n\n/* Copy the state of the SHA3-512 operation.\n *\n * src  wc_Sha3 object holding state top copy.\n * dst  wc_Sha3 object to copy into.\n * returns 0 on success.\n */\nint wc_Sha3_512_Copy(wc_Sha3* src, wc_Sha3* dst)\n{\n    return wc_Sha3Copy(src, dst);\n}\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\nint wc_Sha3_SetFlags(wc_Sha3* sha3, word32 flags)\n{\n    if (sha3) {\n        sha3->flags = flags;\n    }\n    return 0;\n}\nint wc_Sha3_GetFlags(wc_Sha3* sha3, word32* flags)\n{\n    if (sha3 && flags) {\n        *flags = sha3->flags;\n    }\n    return 0;\n}\n#endif\n\n#endif /* WOLFSSL_SHA3 */\n"
  },
  {
    "path": "src/wolfcrypt/src/sha512.c",
    "content": "/* sha512.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)\n\n#if defined(HAVE_FIPS) && \\\n\tdefined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n\n    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */\n    #define FIPS_NO_WRAPPERS\n\n    #ifdef USE_WINDOWS_API\n        #pragma code_seg(\".fipsA$k\")\n        #pragma const_seg(\".fipsB$k\")\n    #endif\n#endif\n\n#include <wolfssl/wolfcrypt/sha512.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/cpuid.h>\n#include <wolfssl/wolfcrypt/hash.h>\n\n/* deprecated USE_SLOW_SHA2 (replaced with USE_SLOW_SHA512) */\n#if defined(USE_SLOW_SHA2) && !defined(USE_SLOW_SHA512)\n    #define USE_SLOW_SHA512\n#endif\n\n/* fips wrapper calls, user can call direct */\n#if defined(HAVE_FIPS) && \\\n    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n\n    #ifdef WOLFSSL_SHA512\n\n        int wc_InitSha512(wc_Sha512* sha)\n        {\n            if (sha == NULL) {\n                return BAD_FUNC_ARG;\n            }\n\n            return InitSha512_fips(sha);\n        }\n        int wc_InitSha512_ex(wc_Sha512* sha, void* heap, int devId)\n        {\n            (void)heap;\n            (void)devId;\n            if (sha == NULL) {\n                return BAD_FUNC_ARG;\n            }\n            return InitSha512_fips(sha);\n        }\n        int wc_Sha512Update(wc_Sha512* sha, const byte* data, word32 len)\n        {\n            if (sha == NULL || (data == NULL && len > 0)) {\n                return BAD_FUNC_ARG;\n            }\n\n            return Sha512Update_fips(sha, data, len);\n        }\n        int wc_Sha512Final(wc_Sha512* sha, byte* out)\n        {\n            if (sha == NULL || out == NULL) {\n                return BAD_FUNC_ARG;\n            }\n\n            return Sha512Final_fips(sha, out);\n        }\n        void wc_Sha512Free(wc_Sha512* sha)\n        {\n            (void)sha;\n            /* Not supported in FIPS */\n        }\n    #endif\n\n    #if defined(WOLFSSL_SHA384) || defined(HAVE_AESGCM)\n        int wc_InitSha384(wc_Sha384* sha)\n        {\n            if (sha == NULL) {\n                return BAD_FUNC_ARG;\n            }\n            return InitSha384_fips(sha);\n        }\n        int wc_InitSha384_ex(wc_Sha384* sha, void* heap, int devId)\n        {\n            (void)heap;\n            (void)devId;\n            if (sha == NULL) {\n                return BAD_FUNC_ARG;\n            }\n            return InitSha384_fips(sha);\n        }\n        int wc_Sha384Update(wc_Sha384* sha, const byte* data, word32 len)\n        {\n            if (sha == NULL || (data == NULL && len > 0)) {\n                return BAD_FUNC_ARG;\n            }\n            return Sha384Update_fips(sha, data, len);\n        }\n        int wc_Sha384Final(wc_Sha384* sha, byte* out)\n        {\n            if (sha == NULL || out == NULL) {\n                return BAD_FUNC_ARG;\n            }\n            return Sha384Final_fips(sha, out);\n        }\n        void wc_Sha384Free(wc_Sha384* sha)\n        {\n            (void)sha;\n            /* Not supported in FIPS */\n        }\n    #endif /* WOLFSSL_SHA384 || HAVE_AESGCM */\n\n#else /* else build without fips, or for FIPS v2 */\n\n#include <wolfssl/wolfcrypt/logging.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\n#if defined(USE_INTEL_SPEEDUP)\n    #if defined(__GNUC__) && ((__GNUC__ < 4) || \\\n                              (__GNUC__ == 4 && __GNUC_MINOR__ <= 8))\n        #undef  NO_AVX2_SUPPORT\n        #define NO_AVX2_SUPPORT\n    #endif\n    #if defined(__clang__) && ((__clang_major__ < 3) || \\\n                               (__clang_major__ == 3 && __clang_minor__ <= 5))\n        #define NO_AVX2_SUPPORT\n    #elif defined(__clang__) && defined(NO_AVX2_SUPPORT)\n        #undef NO_AVX2_SUPPORT\n    #endif\n\n    #define HAVE_INTEL_AVX1\n    #ifndef NO_AVX2_SUPPORT\n        #define HAVE_INTEL_AVX2\n    #endif\n#endif\n\n#if defined(HAVE_INTEL_AVX1)\n    /* #define DEBUG_XMM  */\n#endif\n\n#if defined(HAVE_INTEL_AVX2)\n    #define HAVE_INTEL_RORX\n    /* #define DEBUG_YMM  */\n#endif\n\n#if defined(HAVE_BYTEREVERSE64) && \\\n        !defined(HAVE_INTEL_AVX1) && !defined(HAVE_INTEL_AVX2)\n    #define ByteReverseWords64(out, in, size) ByteReverseWords64_1(out, size)\n    #define ByteReverseWords64_1(buf, size) \\\n        { unsigned int i ;\\\n            for(i=0; i< size/sizeof(word64); i++){\\\n                __asm__ volatile(\"bswapq %0\":\"+r\"(buf[i])::) ;\\\n            }\\\n        }\n#endif\n\n#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)\n    /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */\n\n#else\n\n#ifdef WOLFSSL_SHA512\n\nstatic int InitSha512(wc_Sha512* sha512)\n{\n    if (sha512 == NULL)\n        return BAD_FUNC_ARG;\n\n    sha512->digest[0] = W64LIT(0x6a09e667f3bcc908);\n    sha512->digest[1] = W64LIT(0xbb67ae8584caa73b);\n    sha512->digest[2] = W64LIT(0x3c6ef372fe94f82b);\n    sha512->digest[3] = W64LIT(0xa54ff53a5f1d36f1);\n    sha512->digest[4] = W64LIT(0x510e527fade682d1);\n    sha512->digest[5] = W64LIT(0x9b05688c2b3e6c1f);\n    sha512->digest[6] = W64LIT(0x1f83d9abfb41bd6b);\n    sha512->digest[7] = W64LIT(0x5be0cd19137e2179);\n\n    sha512->buffLen = 0;\n    sha512->loLen   = 0;\n    sha512->hiLen   = 0;\n\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n\n    sha512->ctx.sha_type = SHA2_512;\n     /* always start firstblock = 1 when using hw engine */\n    sha512->ctx.isfirstblock = 1;\n    if(sha512->ctx.mode == ESP32_SHA_HW) {\n        /* release hw */\n        esp_sha_hw_unlock();\n    }\n    /* always set mode as INIT\n    *  whether using HW or SW is detemined at first call of update()\n    */\n    sha512->ctx.mode = ESP32_SHA_INIT;\n#endif\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    sha512->flags = 0;\n#endif\n    return 0;\n}\n\n#endif /* WOLFSSL_SHA512 */\n\n/* Hardware Acceleration */\n#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n\n#ifdef WOLFSSL_SHA512\n\n    /*****\n    Intel AVX1/AVX2 Macro Control Structure\n\n    #if defined(HAVE_INteL_SPEEDUP)\n        #define HAVE_INTEL_AVX1\n        #define HAVE_INTEL_AVX2\n    #endif\n\n    int InitSha512(wc_Sha512* sha512) {\n         Save/Recover XMM, YMM\n         ...\n\n         Check Intel AVX cpuid flags\n    }\n\n    #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)\n      Transform_Sha512_AVX1(); # Function prototype\n      Transform_Sha512_AVX2(); #\n    #endif\n\n      _Transform_Sha512() {     # Native Transform Function body\n\n      }\n\n      int Sha512Update() {\n         Save/Recover XMM, YMM\n         ...\n      }\n\n      int Sha512Final() {\n         Save/Recover XMM, YMM\n         ...\n      }\n\n\n    #if defined(HAVE_INTEL_AVX1)\n\n       XMM Instructions/INLINE asm Definitions\n\n    #endif\n\n    #if defined(HAVE_INTEL_AVX2)\n\n       YMM Instructions/INLINE asm Definitions\n\n    #endif\n\n    #if defnied(HAVE_INTEL_AVX1)\n\n      int Transform_Sha512_AVX1() {\n          Stitched Message Sched/Round\n      }\n\n    #endif\n\n    #if defnied(HAVE_INTEL_AVX2)\n\n      int Transform_Sha512_AVX2() {\n          Stitched Message Sched/Round\n      }\n    #endif\n\n    */\n\n\n    /* Each platform needs to query info type 1 from cpuid to see if aesni is\n     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts\n     */\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n    #if defined(HAVE_INTEL_AVX1)\n        extern int Transform_Sha512_AVX1(wc_Sha512 *sha512);\n        extern int Transform_Sha512_AVX1_Len(wc_Sha512 *sha512, word32 len);\n    #endif\n    #if defined(HAVE_INTEL_AVX2)\n        extern int Transform_Sha512_AVX2(wc_Sha512 *sha512);\n        extern int Transform_Sha512_AVX2_Len(wc_Sha512 *sha512, word32 len);\n        #if defined(HAVE_INTEL_RORX)\n            extern int Transform_Sha512_AVX1_RORX(wc_Sha512 *sha512);\n            extern int Transform_Sha512_AVX1_RORX_Len(wc_Sha512 *sha512,\n                                                      word32 len);\n            extern int Transform_Sha512_AVX2_RORX(wc_Sha512 *sha512);\n            extern int Transform_Sha512_AVX2_RORX_Len(wc_Sha512 *sha512,\n                                                      word32 len);\n        #endif\n    #endif\n\n#ifdef __cplusplus\n    }  /* extern \"C\" */\n#endif\n\n    static int _Transform_Sha512(wc_Sha512 *sha512);\n    static int (*Transform_Sha512_p)(wc_Sha512* sha512) = _Transform_Sha512;\n    static int (*Transform_Sha512_Len_p)(wc_Sha512* sha512, word32 len) = NULL;\n    static int transform_check = 0;\n    static int intel_flags;\n    #define Transform_Sha512(sha512)     (*Transform_Sha512_p)(sha512)\n    #define Transform_Sha512_Len(sha512, len) \\\n                                          (*Transform_Sha512_Len_p)(sha512, len)\n\n    static void Sha512_SetTransform()\n    {\n        if (transform_check)\n            return;\n\n        intel_flags = cpuid_get_flags();\n\n    #if defined(HAVE_INTEL_AVX2)\n        if (IS_INTEL_AVX2(intel_flags)) {\n        #ifdef HAVE_INTEL_RORX\n            if (IS_INTEL_BMI2(intel_flags)) {\n                Transform_Sha512_p = Transform_Sha512_AVX2_RORX;\n                Transform_Sha512_Len_p = Transform_Sha512_AVX2_RORX_Len;\n            }\n            else\n        #endif\n            if (1) {\n                Transform_Sha512_p = Transform_Sha512_AVX2;\n                Transform_Sha512_Len_p = Transform_Sha512_AVX2_Len;\n            }\n        #ifdef HAVE_INTEL_RORX\n            else {\n                Transform_Sha512_p = Transform_Sha512_AVX1_RORX;\n                Transform_Sha512_Len_p = Transform_Sha512_AVX1_RORX_Len;\n            }\n        #endif\n        }\n        else\n    #endif\n    #if defined(HAVE_INTEL_AVX1)\n        if (IS_INTEL_AVX1(intel_flags)) {\n            Transform_Sha512_p = Transform_Sha512_AVX1;\n            Transform_Sha512_Len_p = Transform_Sha512_AVX1_Len;\n        }\n        else\n    #endif\n            Transform_Sha512_p = _Transform_Sha512;\n\n        transform_check = 1;\n    }\n#endif /* WOLFSSL_SHA512 */\n\n#else\n    #define Transform_Sha512(sha512) _Transform_Sha512(sha512)\n\n#endif\n\n#ifdef WOLFSSL_SHA512\n\nint wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)\n{\n    int ret = 0;\n\n    if (sha512 == NULL)\n        return BAD_FUNC_ARG;\n\n    sha512->heap = heap;\n\n    ret = InitSha512(sha512);\n    if (ret != 0)\n        return ret;\n\n#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n    Sha512_SetTransform();\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    sha512->W = NULL;\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)\n    ret = wolfAsync_DevCtxInit(&sha512->asyncDev,\n                        WOLFSSL_ASYNC_MARKER_SHA512, sha512->heap, devId);\n#else\n    (void)devId;\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    return ret;\n}\n\n#endif /* WOLFSSL_SHA512 */\n\n\nstatic const word64 K512[80] = {\n    W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),\n    W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),\n    W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),\n    W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),\n    W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),\n    W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),\n    W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),\n    W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),\n    W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),\n    W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),\n    W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),\n    W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),\n    W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),\n    W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),\n    W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),\n    W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),\n    W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),\n    W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),\n    W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),\n    W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),\n    W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),\n    W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),\n    W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),\n    W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),\n    W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),\n    W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),\n    W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),\n    W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),\n    W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),\n    W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),\n    W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),\n    W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),\n    W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),\n    W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),\n    W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),\n    W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),\n    W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),\n    W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),\n    W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),\n    W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)\n};\n\n#define blk0(i) (W[i] = sha512->buffer[i])\n\n#define blk2(i) (\\\n               W[ i     & 15] += \\\n            s1(W[(i-2)  & 15])+ \\\n               W[(i-7)  & 15] + \\\n            s0(W[(i-15) & 15])  \\\n        )\n\n#define Ch(x,y,z)  (z ^ (x & (y ^ z)))\n#define Maj(x,y,z) ((x & y) | (z & (x | y)))\n\n#define a(i) T[(0-i) & 7]\n#define b(i) T[(1-i) & 7]\n#define c(i) T[(2-i) & 7]\n#define d(i) T[(3-i) & 7]\n#define e(i) T[(4-i) & 7]\n#define f(i) T[(5-i) & 7]\n#define g(i) T[(6-i) & 7]\n#define h(i) T[(7-i) & 7]\n\n#define S0(x) (rotrFixed64(x,28) ^ rotrFixed64(x,34) ^ rotrFixed64(x,39))\n#define S1(x) (rotrFixed64(x,14) ^ rotrFixed64(x,18) ^ rotrFixed64(x,41))\n#define s0(x) (rotrFixed64(x,1)  ^ rotrFixed64(x,8)  ^ (x>>7))\n#define s1(x) (rotrFixed64(x,19) ^ rotrFixed64(x,61) ^ (x>>6))\n\n#define R(i) \\\n    h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j ? blk2(i) : blk0(i)); \\\n    d(i) += h(i); \\\n    h(i) += S0(a(i)) + Maj(a(i),b(i),c(i))\n\nstatic int _Transform_Sha512(wc_Sha512* sha512)\n{\n    const word64* K = K512;\n    word32 j;\n    word64 T[8];\n\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    word64* W = sha512->W;\n    if (W == NULL) {\n        W = (word64*) XMALLOC(sizeof(word64) * 16, NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n        if (W == NULL)\n            return MEMORY_E;\n        sha512->W = W;\n    }\n#elif defined(WOLFSSL_SMALL_STACK)\n    word64* W;\n    W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (W == NULL)\n        return MEMORY_E;\n#else\n    word64 W[16];\n#endif\n\n    /* Copy digest to working vars */\n    XMEMCPY(T, sha512->digest, sizeof(T));\n\n#ifdef USE_SLOW_SHA512\n    /* over twice as small, but 50% slower */\n    /* 80 operations, not unrolled */\n    for (j = 0; j < 80; j += 16) {\n        int m;\n        for (m = 0; m < 16; m++) { /* braces needed here for macros {} */\n            R(m);\n        }\n    }\n#else\n    /* 80 operations, partially loop unrolled */\n    for (j = 0; j < 80; j += 16) {\n        R( 0); R( 1); R( 2); R( 3);\n        R( 4); R( 5); R( 6); R( 7);\n        R( 8); R( 9); R(10); R(11);\n        R(12); R(13); R(14); R(15);\n    }\n#endif /* USE_SLOW_SHA512 */\n\n    /* Add the working vars back into digest */\n    sha512->digest[0] += a(0);\n    sha512->digest[1] += b(0);\n    sha512->digest[2] += c(0);\n    sha512->digest[3] += d(0);\n    sha512->digest[4] += e(0);\n    sha512->digest[5] += f(0);\n    sha512->digest[6] += g(0);\n    sha512->digest[7] += h(0);\n\n    /* Wipe variables */\n    ForceZero(W, sizeof(word64) * 16);\n    ForceZero(T, sizeof(T));\n\n#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE)\n    XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return 0;\n}\n\n\nstatic WC_INLINE void AddLength(wc_Sha512* sha512, word32 len)\n{\n    word64 tmp = sha512->loLen;\n    if ( (sha512->loLen += len) < tmp)\n        sha512->hiLen++;                       /* carry low to high */\n}\n\nstatic WC_INLINE int Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)\n{\n    int ret = 0;\n    /* do block size increments */\n    byte* local = (byte*)sha512->buffer;\n\n    /* check that internal buffLen is valid */\n    if (sha512->buffLen >= WC_SHA512_BLOCK_SIZE)\n        return BUFFER_E;\n\n    AddLength(sha512, len);\n\n    if (sha512->buffLen > 0) {\n        word32 add = min(len, WC_SHA512_BLOCK_SIZE - sha512->buffLen);\n        if (add > 0) {\n            XMEMCPY(&local[sha512->buffLen], data, add);\n\n            sha512->buffLen += add;\n            data            += add;\n            len             -= add;\n        }\n\n        if (sha512->buffLen == WC_SHA512_BLOCK_SIZE) {\n    #if defined(LITTLE_ENDIAN_ORDER)\n        #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n            if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))\n        #endif\n            {\n        #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \\\n             defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n                ByteReverseWords64(sha512->buffer, sha512->buffer,\n                                                         WC_SHA512_BLOCK_SIZE);\n        #endif\n            }\n    #endif\n    #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \\\n         defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n            ret = Transform_Sha512(sha512);\n    #else\n            if(sha512->ctx.mode == ESP32_SHA_INIT) {\n                esp_sha_try_hw_lock(&sha512->ctx);\n            }\n            ret = esp_sha512_process(sha512);\n            if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW){\n                ret = Transform_Sha512(sha512);\n            }\n    #endif\n            if (ret == 0)\n                sha512->buffLen = 0;\n            else\n                len = 0;\n        }\n    }\n\n#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n    if (Transform_Sha512_Len_p != NULL) {\n        word32 blocksLen = len & ~(WC_SHA512_BLOCK_SIZE-1);\n\n        if (blocksLen > 0) {\n            sha512->data = data;\n            /* Byte reversal performed in function if required. */\n            Transform_Sha512_Len(sha512, blocksLen);\n            data += blocksLen;\n            len  -= blocksLen;\n        }\n    }\n    else\n#endif\n#if !defined(LITTLE_ENDIAN_ORDER) || defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n    {\n        while (len >= WC_SHA512_BLOCK_SIZE) {\n            XMEMCPY(local, data, WC_SHA512_BLOCK_SIZE);\n\n            data += WC_SHA512_BLOCK_SIZE;\n            len  -= WC_SHA512_BLOCK_SIZE;\n\n        #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n            if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))\n            {\n                ByteReverseWords64(sha512->buffer, sha512->buffer,\n                                                          WC_SHA512_BLOCK_SIZE);\n            }\n        #endif\n            /* Byte reversal performed in function if required. */\n            ret = Transform_Sha512(sha512);\n            if (ret != 0)\n                break;\n        }\n    }\n#else\n    {\n        while (len >= WC_SHA512_BLOCK_SIZE) {\n            XMEMCPY(local, data, WC_SHA512_BLOCK_SIZE);\n\n            data += WC_SHA512_BLOCK_SIZE;\n            len  -= WC_SHA512_BLOCK_SIZE;\n    #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \\\n         defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n            ByteReverseWords64(sha512->buffer, sha512->buffer,\n                                                       WC_SHA512_BLOCK_SIZE);\n    #endif\n    #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \\\n         defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n            ret = Transform_Sha512(sha512);\n    #else\n            if(sha512->ctx.mode == ESP32_SHA_INIT) {\n                esp_sha_try_hw_lock(&sha512->ctx);\n            }\n            ret = esp_sha512_process(sha512);\n            if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW){\n                ret = Transform_Sha512(sha512);\n            }\n    #endif\n            if (ret != 0)\n                break;\n        }\n    }\n#endif\n\n    if (len > 0) {\n        XMEMCPY(local, data, len);\n        sha512->buffLen = len;\n    }\n\n    return ret;\n}\n\n#ifdef WOLFSSL_SHA512\n\nint wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)\n{\n    if (sha512 == NULL || (data == NULL && len > 0)) {\n        return BAD_FUNC_ARG;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)\n    if (sha512->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA512) {\n    #if defined(HAVE_INTEL_QA)\n        return IntelQaSymSha512(&sha512->asyncDev, NULL, data, len);\n    #endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    return Sha512Update(sha512, data, len);\n}\n\n#endif /* WOLFSSL_SHA512 */\n\n#endif /* WOLFSSL_IMX6_CAAM */\n\nstatic WC_INLINE int Sha512Final(wc_Sha512* sha512)\n{\n    byte* local = (byte*)sha512->buffer;\n    int ret;\n\n    if (sha512 == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    local[sha512->buffLen++] = 0x80;  /* add 1 */\n\n    /* pad with zeros */\n    if (sha512->buffLen > WC_SHA512_PAD_SIZE) {\n        XMEMSET(&local[sha512->buffLen], 0, WC_SHA512_BLOCK_SIZE - sha512->buffLen);\n        sha512->buffLen += WC_SHA512_BLOCK_SIZE - sha512->buffLen;\n#if defined(LITTLE_ENDIAN_ORDER)\n    #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n        if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))\n    #endif\n        {\n\n       #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \\\n            defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n            ByteReverseWords64(sha512->buffer,sha512->buffer,\n                                                         WC_SHA512_BLOCK_SIZE);\n       #endif\n        }\n#endif /* LITTLE_ENDIAN_ORDER */\n#if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \\\n     defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n        ret = Transform_Sha512(sha512);\n#else\n       if(sha512->ctx.mode == ESP32_SHA_INIT) {\n            esp_sha_try_hw_lock(&sha512->ctx);\n       }\n        ret = esp_sha512_process(sha512);\n        if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW){\n            ret = Transform_Sha512(sha512);\n        }\n#endif\n        if (ret != 0)\n            return ret;\n\n        sha512->buffLen = 0;\n    }\n    XMEMSET(&local[sha512->buffLen], 0, WC_SHA512_PAD_SIZE - sha512->buffLen);\n\n    /* put lengths in bits */\n    sha512->hiLen = (sha512->loLen >> (8 * sizeof(sha512->loLen) - 3)) +\n                                                         (sha512->hiLen << 3);\n    sha512->loLen = sha512->loLen << 3;\n\n    /* store lengths */\n#if defined(LITTLE_ENDIAN_ORDER)\n    #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n        if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))\n    #endif\n    #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \\\n         defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n            ByteReverseWords64(sha512->buffer, sha512->buffer, WC_SHA512_PAD_SIZE);\n    #endif\n#endif\n    /* ! length ordering dependent on digest endian type ! */\n\n#if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \\\n     defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen;\n    sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen;\n#endif\n\n#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n    if (IS_INTEL_AVX1(intel_flags) || IS_INTEL_AVX2(intel_flags))\n        ByteReverseWords64(&(sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2]),\n                           &(sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2]),\n                           WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE);\n#endif\n#if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \\\n    defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    ret = Transform_Sha512(sha512);\n#else\n    if(sha512->ctx.mode == ESP32_SHA_INIT) {\n        esp_sha_try_hw_lock(&sha512->ctx);\n    }\n    ret = esp_sha512_digest_process(sha512, 1);\n    if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW) {\n        ret = Transform_Sha512(sha512);\n    }\n#endif\n    if (ret != 0)\n        return ret;\n\n    #ifdef LITTLE_ENDIAN_ORDER\n        ByteReverseWords64(sha512->digest, sha512->digest, WC_SHA512_DIGEST_SIZE);\n    #endif\n\n    return 0;\n}\n\n#ifdef WOLFSSL_SHA512\n\nint wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash)\n{\n#ifdef LITTLE_ENDIAN_ORDER\n    word64 digest[WC_SHA512_DIGEST_SIZE / sizeof(word64)];\n#endif\n\n    if (sha512 == NULL || hash == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef LITTLE_ENDIAN_ORDER\n    ByteReverseWords64((word64*)digest, (word64*)sha512->digest,\n                                                         WC_SHA512_DIGEST_SIZE);\n    XMEMCPY(hash, digest, WC_SHA512_DIGEST_SIZE);\n#else\n    XMEMCPY(hash, sha512->digest, WC_SHA512_DIGEST_SIZE);\n#endif\n\n    return 0;\n}\n\nint wc_Sha512Final(wc_Sha512* sha512, byte* hash)\n{\n    int ret;\n\n    if (sha512 == NULL || hash == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)\n    if (sha512->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA512) {\n    #if defined(HAVE_INTEL_QA)\n        return IntelQaSymSha512(&sha512->asyncDev, hash, NULL,\n                                            WC_SHA512_DIGEST_SIZE);\n    #endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    ret = Sha512Final(sha512);\n    if (ret != 0)\n        return ret;\n\n    XMEMCPY(hash, sha512->digest, WC_SHA512_DIGEST_SIZE);\n\n    return InitSha512(sha512);  /* reset state */\n}\n\nint wc_InitSha512(wc_Sha512* sha512)\n{\n    return wc_InitSha512_ex(sha512, NULL, INVALID_DEVID);\n}\n\nvoid wc_Sha512Free(wc_Sha512* sha512)\n{\n    if (sha512 == NULL)\n        return;\n\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    if (sha512->W != NULL) {\n        XFREE(sha512->W, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        sha512->W = NULL;\n    }\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)\n    wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512);\n#endif /* WOLFSSL_ASYNC_CRYPT */\n}\n\n#endif /* WOLFSSL_SHA512 */\n\n/* -------------------------------------------------------------------------- */\n/* SHA384 */\n/* -------------------------------------------------------------------------- */\n#ifdef WOLFSSL_SHA384\n\n#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)\n    /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */\n\n#else\n\nstatic int InitSha384(wc_Sha384* sha384)\n{\n    if (sha384 == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    sha384->digest[0] = W64LIT(0xcbbb9d5dc1059ed8);\n    sha384->digest[1] = W64LIT(0x629a292a367cd507);\n    sha384->digest[2] = W64LIT(0x9159015a3070dd17);\n    sha384->digest[3] = W64LIT(0x152fecd8f70e5939);\n    sha384->digest[4] = W64LIT(0x67332667ffc00b31);\n    sha384->digest[5] = W64LIT(0x8eb44a8768581511);\n    sha384->digest[6] = W64LIT(0xdb0c2e0d64f98fa7);\n    sha384->digest[7] = W64LIT(0x47b5481dbefa4fa4);\n\n    sha384->buffLen = 0;\n    sha384->loLen   = 0;\n    sha384->hiLen   = 0;\n\n#if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    sha384->ctx.sha_type = SHA2_384;\n     /* always start firstblock = 1 when using hw engine */\n    sha384->ctx.isfirstblock = 1;\n    if(sha384->ctx.mode == ESP32_SHA_HW) {\n        /* release hw */\n        esp_sha_hw_unlock();\n    }\n    /* always set mode as INIT\n    *  whether using HW or SW is detemined at first call of update()\n    */\n    sha384->ctx.mode = ESP32_SHA_INIT;\n\n#endif\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    sha384->flags = 0;\n#endif\n\n    return 0;\n}\n\nint wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)\n{\n    if (sha384 == NULL || (data == NULL && len > 0)) {\n        return BAD_FUNC_ARG;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)\n    if (sha384->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA384) {\n    #if defined(HAVE_INTEL_QA)\n        return IntelQaSymSha384(&sha384->asyncDev, NULL, data, len);\n    #endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    return Sha512Update((wc_Sha512*)sha384, data, len);\n}\n\n\nint wc_Sha384FinalRaw(wc_Sha384* sha384, byte* hash)\n{\n#ifdef LITTLE_ENDIAN_ORDER\n    word64 digest[WC_SHA384_DIGEST_SIZE / sizeof(word64)];\n#endif\n\n    if (sha384 == NULL || hash == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef LITTLE_ENDIAN_ORDER\n    ByteReverseWords64((word64*)digest, (word64*)sha384->digest,\n                                                         WC_SHA384_DIGEST_SIZE);\n    XMEMCPY(hash, digest, WC_SHA384_DIGEST_SIZE);\n#else\n    XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);\n#endif\n\n    return 0;\n}\n\nint wc_Sha384Final(wc_Sha384* sha384, byte* hash)\n{\n    int ret;\n\n    if (sha384 == NULL || hash == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)\n    if (sha384->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA384) {\n    #if defined(HAVE_INTEL_QA)\n        return IntelQaSymSha384(&sha384->asyncDev, hash, NULL,\n                                            WC_SHA384_DIGEST_SIZE);\n    #endif\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    ret = Sha512Final((wc_Sha512*)sha384);\n    if (ret != 0)\n        return ret;\n\n    XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);\n\n    return InitSha384(sha384);  /* reset state */\n}\n\nint wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)\n{\n    int ret;\n\n    if (sha384 == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    sha384->heap = heap;\n    ret = InitSha384(sha384);\n    if (ret != 0)\n        return ret;\n\n#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)\n    Sha512_SetTransform();\n#endif\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    sha384->W = NULL;\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)\n    ret = wolfAsync_DevCtxInit(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384,\n                                                           sha384->heap, devId);\n#else\n    (void)devId;\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    return ret;\n}\n\n#endif /* WOLFSSL_IMX6_CAAM */\n\nint wc_InitSha384(wc_Sha384* sha384)\n{\n    return wc_InitSha384_ex(sha384, NULL, INVALID_DEVID);\n}\n\nvoid wc_Sha384Free(wc_Sha384* sha384)\n{\n    if (sha384 == NULL)\n        return;\n\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    if (sha384->W != NULL) {\n        XFREE(sha384->W, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        sha384->W = NULL;\n    }\n#endif\n\n#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)\n    wolfAsync_DevCtxFree(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384);\n#endif /* WOLFSSL_ASYNC_CRYPT */\n}\n\n#endif /* WOLFSSL_SHA384 */\n\n#endif /* HAVE_FIPS */\n\n#ifdef WOLFSSL_SHA512\n\nint wc_Sha512GetHash(wc_Sha512* sha512, byte* hash)\n{\n    int ret;\n    wc_Sha512 tmpSha512;\n\n    if (sha512 == NULL || hash == NULL)\n        return BAD_FUNC_ARG;\n\n#if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    if(sha512->ctx.mode == ESP32_SHA_INIT) {\n        esp_sha_try_hw_lock(&sha512->ctx);\n    }\n    if(sha512->ctx.mode != ESP32_SHA_SW)\n       esp_sha512_digest_process(sha512, 0);\n#endif\n\n    ret = wc_Sha512Copy(sha512, &tmpSha512);\n    if (ret == 0) {\n        ret = wc_Sha512Final(&tmpSha512, hash);\n#if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n        sha512->ctx.mode = ESP32_SHA_SW;;\n#endif\n        wc_Sha512Free(&tmpSha512);\n    }\n    return ret;\n}\n\nint wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst)\n{\n    int ret = 0;\n\n    if (src == NULL || dst == NULL)\n        return BAD_FUNC_ARG;\n\n    XMEMCPY(dst, src, sizeof(wc_Sha512));\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    dst->W = NULL;\n#endif\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);\n#endif\n#if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    dst->ctx.mode = src->ctx.mode;\n    dst->ctx.isfirstblock = src->ctx.isfirstblock;\n    dst->ctx.sha_type = src->ctx.sha_type;\n#endif\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n     dst->flags |= WC_HASH_FLAG_ISCOPY;\n#endif\n\n    return ret;\n}\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\nint wc_Sha512SetFlags(wc_Sha512* sha512, word32 flags)\n{\n    if (sha512) {\n        sha512->flags = flags;\n    }\n    return 0;\n}\nint wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags)\n{\n    if (sha512 && flags) {\n        *flags = sha512->flags;\n    }\n    return 0;\n}\n#endif\n\n#endif /* WOLFSSL_SHA512 */\n\n#ifdef WOLFSSL_SHA384\n\nint wc_Sha384GetHash(wc_Sha384* sha384, byte* hash)\n{\n    int ret;\n    wc_Sha384 tmpSha384;\n\n    if (sha384 == NULL || hash == NULL)\n        return BAD_FUNC_ARG;\n#if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    if(sha384->ctx.mode == ESP32_SHA_INIT) {\n        esp_sha_try_hw_lock(&sha384->ctx);\n    }\n    if(sha384->ctx.mode != ESP32_SHA_SW) {\n        esp_sha512_digest_process(sha384, 0);\n    }\n#endif\n    ret = wc_Sha384Copy(sha384, &tmpSha384);\n    if (ret == 0) {\n        ret = wc_Sha384Final(&tmpSha384, hash);\n#if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n        sha384->ctx.mode = ESP32_SHA_SW;\n#endif\n        wc_Sha384Free(&tmpSha384);\n    }\n    return ret;\n}\nint wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst)\n{\n    int ret = 0;\n\n    if (src == NULL || dst == NULL)\n        return BAD_FUNC_ARG;\n\n    XMEMCPY(dst, src, sizeof(wc_Sha384));\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    dst->W = NULL;\n#endif\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);\n#endif\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n   !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    dst->ctx.mode = src->ctx.mode;\n    dst->ctx.isfirstblock = src->ctx.isfirstblock;\n    dst->ctx.sha_type = src->ctx.sha_type;\n#endif\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n     dst->flags |= WC_HASH_FLAG_ISCOPY;\n#endif\n\n    return ret;\n}\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\nint wc_Sha384SetFlags(wc_Sha384* sha384, word32 flags)\n{\n    if (sha384) {\n        sha384->flags = flags;\n    }\n    return 0;\n}\nint wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags)\n{\n    if (sha384 && flags) {\n        *flags = sha384->flags;\n    }\n    return 0;\n}\n#endif\n\n#endif /* WOLFSSL_SHA384 */\n\n#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */\n"
  },
  {
    "path": "src/wolfcrypt/src/signature.c",
    "content": "/* signature.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/signature.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#ifndef NO_ASN\n#include <wolfssl/wolfcrypt/asn.h>\n#endif\n#ifdef HAVE_ECC\n#include <wolfssl/wolfcrypt/ecc.h>\n#endif\n#ifndef NO_RSA\n#include <wolfssl/wolfcrypt/rsa.h>\n#endif\n\n/* If ECC and RSA are disabled then disable signature wrapper */\n#if (!defined(HAVE_ECC) || (defined(HAVE_ECC) && !defined(HAVE_ECC_SIGN) \\\n    && !defined(HAVE_ECC_VERIFY))) && defined(NO_RSA)\n    #undef NO_SIG_WRAPPER\n    #define NO_SIG_WRAPPER\n#endif\n\n/* Signature wrapper disabled check */\n#ifndef NO_SIG_WRAPPER\n\n#if !defined(NO_RSA) && !defined(NO_ASN)\nstatic int wc_SignatureDerEncode(enum wc_HashType hash_type, byte* hash_data,\n    word32 hash_len, word32* hash_enc_len)\n{\n    int ret, oid;\n\n    ret = wc_HashGetOID(hash_type);\n    if (ret < 0) {\n        return ret;\n    }\n    oid = ret;\n\n    ret = wc_EncodeSignature(hash_data, hash_data, hash_len, oid);\n    if (ret > 0) {\n        *hash_enc_len = ret;\n        ret = 0;\n    }\n\n    return ret;\n}\n#endif /* !NO_RSA && !NO_ASN */\n\nint wc_SignatureGetSize(enum wc_SignatureType sig_type,\n    const void* key, word32 key_len)\n{\n    int sig_len = BAD_FUNC_ARG;\n\n    /* Suppress possible unused args if all signature types are disabled */\n    (void)key;\n    (void)key_len;\n\n    switch(sig_type) {\n        case WC_SIGNATURE_TYPE_ECC:\n#ifdef HAVE_ECC\n            /* Sanity check that void* key is at least ecc_key in size */\n            if (key_len >= sizeof(ecc_key)) {\n                sig_len = wc_ecc_sig_size((ecc_key*)key);\n            }\n            else {\n                WOLFSSL_MSG(\"wc_SignatureGetSize: Invalid ECC key size\");\n            }\n#else\n            sig_len = SIG_TYPE_E;\n#endif\n            break;\n\n        case WC_SIGNATURE_TYPE_RSA_W_ENC:\n        case WC_SIGNATURE_TYPE_RSA:\n#ifndef NO_RSA\n            /* Sanity check that void* key is at least RsaKey in size */\n            if (key_len >= sizeof(RsaKey)) {\n                sig_len = wc_RsaEncryptSize((RsaKey*)key);\n            }\n            else {\n                WOLFSSL_MSG(\"wc_SignatureGetSize: Invalid RsaKey key size\");\n            }\n#else\n            sig_len = SIG_TYPE_E;\n#endif\n            break;\n\n        case WC_SIGNATURE_TYPE_NONE:\n        default:\n            sig_len = BAD_FUNC_ARG;\n            break;\n    }\n    return sig_len;\n}\n\nint wc_SignatureVerifyHash(\n    enum wc_HashType hash_type, enum wc_SignatureType sig_type,\n    const byte* hash_data, word32 hash_len,\n    const byte* sig, word32 sig_len,\n    const void* key, word32 key_len)\n{\n    int ret;\n\n    /* Check arguments */\n    if (hash_data == NULL || hash_len <= 0 ||\n        sig == NULL || sig_len <= 0 ||\n        key == NULL || key_len <= 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* Validate signature len (1 to max is okay) */\n    if ((int)sig_len > wc_SignatureGetSize(sig_type, key, key_len)) {\n        WOLFSSL_MSG(\"wc_SignatureVerify: Invalid sig type/len\");\n        return BAD_FUNC_ARG;\n    }\n\n    /* Validate hash size */\n    ret = wc_HashGetDigestSize(hash_type);\n    if (ret < 0) {\n        WOLFSSL_MSG(\"wc_SignatureVerify: Invalid hash type/len\");\n        return ret;\n    }\n    ret = 0;\n\n    /* Verify signature using hash */\n    switch (sig_type) {\n        case WC_SIGNATURE_TYPE_ECC:\n        {\n#if defined(HAVE_ECC) && defined(HAVE_ECC_VERIFY)\n            int is_valid_sig = 0;\n\n            /* Perform verification of signature using provided ECC key */\n            do {\n            #ifdef WOLFSSL_ASYNC_CRYPT\n                ret = wc_AsyncWait(ret, &((ecc_key*)key)->asyncDev,\n                    WC_ASYNC_FLAG_CALL_AGAIN);\n            #endif\n            if (ret >= 0)\n                ret = wc_ecc_verify_hash(sig, sig_len, hash_data, hash_len,\n                    &is_valid_sig, (ecc_key*)key);\n            } while (ret == WC_PENDING_E);\n            if (ret != 0 || is_valid_sig != 1) {\n                ret = SIG_VERIFY_E;\n            }\n#else\n            ret = SIG_TYPE_E;\n#endif\n            break;\n        }\n\n        case WC_SIGNATURE_TYPE_RSA_W_ENC:\n        case WC_SIGNATURE_TYPE_RSA:\n        {\n#ifndef NO_RSA\n#if defined(WOLFSSL_CRYPTOCELL)\n        /* the signature must propagate to the cryptocell to get verfied */\n        ret = wc_RsaSSL_Verify(hash_data, hash_len, (byte*)sig, sig_len, (RsaKey*)key);\n        if (ret != 0) {\n            WOLFSSL_MSG(\"RSA Signature Verify difference!\");\n            ret = SIG_VERIFY_E;\n        }\n\n#else /* WOLFSSL_CRYPTOCELL */\n\n            word32 plain_len = hash_len;\n            byte *plain_data;\n\n            /* Make sure the plain text output is at least key size */\n            if (plain_len < sig_len) {\n                plain_len = sig_len;\n            }\n            plain_data = (byte*)XMALLOC(plain_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n            if (plain_data) {\n                /* Perform verification of signature using provided RSA key */\n                do {\n                #ifdef WOLFSSL_ASYNC_CRYPT\n                    ret = wc_AsyncWait(ret, &((RsaKey*)key)->asyncDev,\n                        WC_ASYNC_FLAG_CALL_AGAIN);\n                #endif\n                if (ret >= 0)\n                    ret = wc_RsaSSL_Verify(sig, sig_len, plain_data,\n                        plain_len, (RsaKey*)key);\n                } while (ret == WC_PENDING_E);\n                if (ret >= 0) {\n                    if ((word32)ret == hash_len &&\n                            XMEMCMP(plain_data, hash_data, hash_len) == 0) {\n                        ret = 0; /* Success */\n                    }\n                    else {\n                        WOLFSSL_MSG(\"RSA Signature Verify difference!\");\n                        ret = SIG_VERIFY_E;\n                    }\n                }\n                XFREE(plain_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n            }\n            else {\n                ret = MEMORY_E;\n            }\n#endif /* !WOLFSSL_CRYPTOCELL */\n#else\n            ret = SIG_TYPE_E;\n#endif\n            break;\n        }\n\n        case WC_SIGNATURE_TYPE_NONE:\n        default:\n            ret = BAD_FUNC_ARG;\n            break;\n    }\n\n    return ret;\n}\n\nint wc_SignatureVerify(\n    enum wc_HashType hash_type, enum wc_SignatureType sig_type,\n    const byte* data, word32 data_len,\n    const byte* sig, word32 sig_len,\n    const void* key, word32 key_len)\n{\n    int ret;\n    word32 hash_len, hash_enc_len;\n#ifdef WOLFSSL_SMALL_STACK\n    byte *hash_data;\n#else\n    byte hash_data[MAX_DER_DIGEST_SZ];\n#endif\n\n    /* Check arguments */\n    if (data == NULL || data_len <= 0 ||\n        sig == NULL || sig_len <= 0 ||\n        key == NULL || key_len <= 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* Validate signature len (1 to max is okay) */\n    if ((int)sig_len > wc_SignatureGetSize(sig_type, key, key_len)) {\n        WOLFSSL_MSG(\"wc_SignatureVerify: Invalid sig type/len\");\n        return BAD_FUNC_ARG;\n    }\n\n    /* Validate hash size */\n    ret = wc_HashGetDigestSize(hash_type);\n    if (ret < 0) {\n        WOLFSSL_MSG(\"wc_SignatureVerify: Invalid hash type/len\");\n        return ret;\n    }\n    hash_enc_len = hash_len = ret;\n\n#ifndef NO_RSA\n    if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) {\n        /* For RSA with ASN.1 encoding include room */\n        hash_enc_len += MAX_DER_DIGEST_ASN_SZ;\n    }\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    /* Allocate temporary buffer for hash data */\n    hash_data = (byte*)XMALLOC(hash_enc_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (hash_data == NULL) {\n        return MEMORY_E;\n    }\n#endif\n\n    /* Perform hash of data */\n    ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len);\n    if (ret == 0) {\n        /* Handle RSA with DER encoding */\n        if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) {\n        #if defined(NO_RSA) || defined(NO_ASN)\n            ret = SIG_TYPE_E;\n        #else\n            ret = wc_SignatureDerEncode(hash_type, hash_data, hash_len,\n                &hash_enc_len);\n        #endif\n        }\n\n        if (ret == 0) {\n            /* Verify signature using hash */\n            ret = wc_SignatureVerifyHash(hash_type, sig_type,\n                hash_data, hash_enc_len, sig, sig_len, key, key_len);\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n\nint wc_SignatureGenerateHash(\n    enum wc_HashType hash_type, enum wc_SignatureType sig_type,\n    const byte* hash_data, word32 hash_len,\n    byte* sig, word32 *sig_len,\n    const void* key, word32 key_len, WC_RNG* rng)\n{\n    return wc_SignatureGenerateHash_ex(hash_type, sig_type, hash_data, hash_len,\n        sig, sig_len, key, key_len, rng, 1);\n}\n\nint wc_SignatureGenerateHash_ex(\n    enum wc_HashType hash_type, enum wc_SignatureType sig_type,\n    const byte* hash_data, word32 hash_len,\n    byte* sig, word32 *sig_len,\n    const void* key, word32 key_len, WC_RNG* rng, int verify)\n{\n    int ret;\n\n    /* Suppress possible unused arg if all signature types are disabled */\n    (void)rng;\n\n    /* Check arguments */\n    if (hash_data == NULL || hash_len <= 0 ||\n        sig == NULL || sig_len == NULL || *sig_len <= 0 ||\n        key == NULL || key_len <= 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* Validate signature len (needs to be at least max) */\n    if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) {\n        WOLFSSL_MSG(\"wc_SignatureGenerate: Invalid sig type/len\");\n        return BAD_FUNC_ARG;\n    }\n\n    /* Validate hash size */\n    ret = wc_HashGetDigestSize(hash_type);\n    if (ret < 0) {\n        WOLFSSL_MSG(\"wc_SignatureGenerate: Invalid hash type/len\");\n        return ret;\n    }\n    ret = 0;\n\n    /* Create signature using hash as data */\n    switch (sig_type) {\n        case WC_SIGNATURE_TYPE_ECC:\n#if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN)\n            /* Create signature using provided ECC key */\n            do {\n            #ifdef WOLFSSL_ASYNC_CRYPT\n                ret = wc_AsyncWait(ret, &((ecc_key*)key)->asyncDev,\n                    WC_ASYNC_FLAG_CALL_AGAIN);\n            #endif\n            if (ret >= 0)\n                ret = wc_ecc_sign_hash(hash_data, hash_len, sig, sig_len,\n                    rng, (ecc_key*)key);\n            } while (ret == WC_PENDING_E);\n#else\n            ret = SIG_TYPE_E;\n#endif\n            break;\n\n        case WC_SIGNATURE_TYPE_RSA_W_ENC:\n        case WC_SIGNATURE_TYPE_RSA:\n#if !defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n            /* Create signature using provided RSA key */\n            do {\n            #ifdef WOLFSSL_ASYNC_CRYPT\n                ret = wc_AsyncWait(ret, &((RsaKey*)key)->asyncDev,\n                    WC_ASYNC_FLAG_CALL_AGAIN);\n            #endif\n                if (ret >= 0)\n                    ret = wc_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len,\n                        (RsaKey*)key, rng);\n            } while (ret == WC_PENDING_E);\n            if (ret >= 0) {\n                *sig_len = ret;\n                ret = 0; /* Success */\n            }\n#else\n            ret = SIG_TYPE_E;\n#endif\n            break;\n\n        case WC_SIGNATURE_TYPE_NONE:\n        default:\n            ret = BAD_FUNC_ARG;\n            break;\n    }\n\n    if (ret == 0 && verify) {\n        ret = wc_SignatureVerifyHash(hash_type, sig_type, hash_data, hash_len,\n            sig, *sig_len, key, key_len);\n    }\n\n    return ret;\n}\n\nint wc_SignatureGenerate(\n    enum wc_HashType hash_type, enum wc_SignatureType sig_type,\n    const byte* data, word32 data_len,\n    byte* sig, word32 *sig_len,\n    const void* key, word32 key_len, WC_RNG* rng)\n{\n    return wc_SignatureGenerate_ex(hash_type, sig_type, data, data_len, sig,\n        sig_len, key, key_len, rng, 1);\n}\n\nint wc_SignatureGenerate_ex(\n    enum wc_HashType hash_type, enum wc_SignatureType sig_type,\n    const byte* data, word32 data_len,\n    byte* sig, word32 *sig_len,\n    const void* key, word32 key_len, WC_RNG* rng, int verify)\n{\n    int ret;\n    word32 hash_len, hash_enc_len;\n#ifdef WOLFSSL_SMALL_STACK\n    byte *hash_data;\n#else\n    byte hash_data[MAX_DER_DIGEST_SZ];\n#endif\n\n    /* Check arguments */\n    if (data == NULL || data_len <= 0 ||\n        sig == NULL || sig_len == NULL || *sig_len <= 0 ||\n        key == NULL || key_len <= 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* Validate signature len (needs to be at least max) */\n    if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) {\n        WOLFSSL_MSG(\"wc_SignatureGenerate: Invalid sig type/len\");\n        return BAD_FUNC_ARG;\n    }\n\n    /* Validate hash size */\n    ret = wc_HashGetDigestSize(hash_type);\n    if (ret < 0) {\n        WOLFSSL_MSG(\"wc_SignatureGenerate: Invalid hash type/len\");\n        return ret;\n    }\n    hash_enc_len = hash_len = ret;\n\n#if !defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n    if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) {\n        /* For RSA with ASN.1 encoding include room */\n        hash_enc_len += MAX_DER_DIGEST_ASN_SZ;\n    }\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    /* Allocate temporary buffer for hash data */\n    hash_data = (byte*)XMALLOC(hash_enc_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (hash_data == NULL) {\n        return MEMORY_E;\n    }\n#endif\n\n    /* Perform hash of data */\n    ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len);\n    if (ret == 0) {\n        /* Handle RSA with DER encoding */\n        if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) {\n        #if defined(NO_RSA) || defined(NO_ASN) || \\\n                                                defined(WOLFSSL_RSA_PUBLIC_ONLY)\n            ret = SIG_TYPE_E;\n        #else\n            ret = wc_SignatureDerEncode(hash_type, hash_data, hash_len,\n                &hash_enc_len);\n        #endif\n        }\n\n        if (ret == 0) {\n            /* Generate signature using hash */\n            ret = wc_SignatureGenerateHash(hash_type, sig_type,\n                hash_data, hash_enc_len, sig, sig_len, key, key_len, rng);\n        }\n    }\n\n    if (ret == 0 && verify) {\n        ret = wc_SignatureVerifyHash(hash_type, sig_type, hash_data,\n            hash_enc_len, sig, *sig_len, key, key_len);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n#endif /* NO_SIG_WRAPPER */\n"
  },
  {
    "path": "src/wolfcrypt/src/sp_arm32.c",
    "content": "/* sp.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/* Implementation by Sean Parkinson. */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/cpuid.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \\\n                                    defined(WOLFSSL_HAVE_SP_ECC)\n\n#ifdef RSA_LOW_MEM\n#ifndef WOLFSSL_SP_SMALL\n#define WOLFSSL_SP_SMALL\n#endif\n#endif\n\n#include <wolfssl/wolfcrypt/sp.h>\n\n#ifdef WOLFSSL_SP_ARM32_ASM\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n#ifndef WOLFSSL_SP_NO_2048\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 24U) {\n            r[j] &= 0xffffffff;\n            s = 32U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 32\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 32\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffff;\n        s = 32U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 32U) <= (word32)DIGIT_BIT) {\n            s += 32U;\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 32) {\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 32 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 256\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_2048_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 2048 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<64 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 32) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 32);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #32\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        \"#  A[0] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr3, r4, r8, r9\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [sp]\\n\\t\"\n        \"#  A[0] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #4]\\n\\t\"\n        \"#  A[0] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #8]\\n\\t\"\n        \"#  A[0] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #12]\\n\\t\"\n        \"#  A[0] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #16]\\n\\t\"\n        \"#  A[0] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #20]\\n\\t\"\n        \"#  A[0] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #24]\\n\\t\"\n        \"#  A[0] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #28]\\n\\t\"\n        \"#  A[1] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[2] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #32]\\n\\t\"\n        \"#  A[2] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[3] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"#  A[3] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[4] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"#  A[4] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[5] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #44]\\n\\t\"\n        \"#  A[5] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[6] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"#  A[6] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[7] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"#  A[7] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr5, [%[r], #56]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"ldr\tr3, [sp, #0]\\n\\t\"\n        \"ldr\tr4, [sp, #4]\\n\\t\"\n        \"ldr\tr5, [sp, #8]\\n\\t\"\n        \"ldr\tr6, [sp, #12]\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [sp, #16]\\n\\t\"\n        \"ldr\tr4, [sp, #20]\\n\\t\"\n        \"ldr\tr5, [sp, #24]\\n\\t\"\n        \"ldr\tr6, [sp, #28]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"str\tr5, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        \"add\tsp, sp, #32\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_2048_sqr_8(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #32\\n\\t\"\n        \"mov\tr14, #0\\n\\t\"\n        \"#  A[0] * A[0]\\n\\t\"\n        \"ldr\tr10, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r3, r10, r10\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr8, [sp]\\n\\t\"\n        \"#  A[0] * A[1]\\n\\t\"\n        \"ldr\tr10, [%[a], #4]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [sp, #4]\\n\\t\"\n        \"#  A[0] * A[2]\\n\\t\"\n        \"ldr\tr10, [%[a], #8]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r14, r14\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"#  A[1] * A[1]\\n\\t\"\n        \"ldr\tr10, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"str\tr4, [sp, #8]\\n\\t\"\n        \"#  A[0] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r14, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"#  A[1] * A[2]\\n\\t\"\n        \"ldr\tr10, [%[a], #8]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"str\tr2, [sp, #12]\\n\\t\"\n        \"#  A[0] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[1] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[2] * A[2]\\n\\t\"\n        \"ldr\tr10, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [sp, #16]\\n\\t\"\n        \"#  A[0] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #20]\\n\\t\"\n        \"#  A[0] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #24]\\n\\t\"\n        \"#  A[0] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #28]\\n\\t\"\n        \"#  A[1] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[2] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"#  A[2] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[3] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #36]\\n\\t\"\n        \"#  A[3] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[4] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[5] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [%[r], #40]\\n\\t\"\n        \"#  A[4] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r14, r14\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"#  A[5] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"#  A[5] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r14, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"#  A[6] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"str\tr2, [%[r], #48]\\n\\t\"\n        \"#  A[6] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [%[r], #52]\\n\\t\"\n        \"#  A[7] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adc\tr2, r2, r9\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"str\tr2, [%[r], #60]\\n\\t\"\n        \"ldr\tr2, [sp, #0]\\n\\t\"\n        \"ldr\tr3, [sp, #4]\\n\\t\"\n        \"ldr\tr4, [sp, #8]\\n\\t\"\n        \"ldr\tr8, [sp, #12]\\n\\t\"\n        \"str\tr2, [%[r], #0]\\n\\t\"\n        \"str\tr3, [%[r], #4]\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"str\tr8, [%[r], #12]\\n\\t\"\n        \"ldr\tr2, [sp, #16]\\n\\t\"\n        \"ldr\tr3, [sp, #20]\\n\\t\"\n        \"ldr\tr4, [sp, #24]\\n\\t\"\n        \"ldr\tr8, [sp, #28]\\n\\t\"\n        \"str\tr2, [%[r], #16]\\n\\t\"\n        \"str\tr3, [%[r], #20]\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"str\tr8, [%[r], #28]\\n\\t\"\n        \"add\tsp, sp, #32\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r8\", \"r9\", \"r10\", \"r8\", \"r5\", \"r6\", \"r7\", \"r14\"\n    );\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_add_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[a], #4]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[b], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"ldr\tr10, [%[b], #8]\\n\\t\"\n        \"ldr\tr14, [%[b], #12]\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr5, [%[r], #4]\\n\\t\"\n        \"str\tr6, [%[r], #8]\\n\\t\"\n        \"str\tr7, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[a], #20]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[b], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"ldr\tr10, [%[b], #24]\\n\\t\"\n        \"ldr\tr14, [%[b], #28]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"str\tr6, [%[r], #24]\\n\\t\"\n        \"str\tr7, [%[r], #28]\\n\\t\"\n        \"adc\t%[c], r12, r12\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_sub_in_place_16(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr6, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"ldr\tr8, [%[b], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"subs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr6, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"ldr\tr8, [%[b], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr6, [%[b], #32]\\n\\t\"\n        \"ldr\tr7, [%[b], #36]\\n\\t\"\n        \"ldr\tr8, [%[b], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[a], #60]\\n\\t\"\n        \"ldr\tr6, [%[b], #48]\\n\\t\"\n        \"ldr\tr7, [%[b], #52]\\n\\t\"\n        \"ldr\tr8, [%[b], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr5, [%[a], #60]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_add_16(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[a], #4]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[b], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"ldr\tr10, [%[b], #8]\\n\\t\"\n        \"ldr\tr14, [%[b], #12]\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr5, [%[r], #4]\\n\\t\"\n        \"str\tr6, [%[r], #8]\\n\\t\"\n        \"str\tr7, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[a], #20]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[b], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"ldr\tr10, [%[b], #24]\\n\\t\"\n        \"ldr\tr14, [%[b], #28]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"str\tr6, [%[r], #24]\\n\\t\"\n        \"str\tr7, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[a], #36]\\n\\t\"\n        \"ldr\tr6, [%[a], #40]\\n\\t\"\n        \"ldr\tr7, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[b], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"ldr\tr10, [%[b], #40]\\n\\t\"\n        \"ldr\tr14, [%[b], #44]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr5, [%[r], #36]\\n\\t\"\n        \"str\tr6, [%[r], #40]\\n\\t\"\n        \"str\tr7, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[a], #52]\\n\\t\"\n        \"ldr\tr6, [%[a], #56]\\n\\t\"\n        \"ldr\tr7, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[b], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"ldr\tr10, [%[b], #56]\\n\\t\"\n        \"ldr\tr14, [%[b], #60]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"str\tr5, [%[r], #52]\\n\\t\"\n        \"str\tr6, [%[r], #56]\\n\\t\"\n        \"str\tr7, [%[r], #60]\\n\\t\"\n        \"adc\t%[c], r12, r12\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_8(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<8; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    r[0] = a[0] & m;\n    r[1] = a[1] & m;\n    r[2] = a[2] & m;\n    r[3] = a[3] & m;\n    r[4] = a[4] & m;\n    r[5] = a[5] & m;\n    r[6] = a[6] & m;\n    r[7] = a[7] & m;\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_16(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[16];\n    sp_digit a1[8];\n    sp_digit b1[8];\n    sp_digit z2[16];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_8(a1, a, &a[8]);\n    cb = sp_2048_add_8(b1, b, &b[8]);\n    u  = ca & cb;\n    sp_2048_mul_8(z1, a1, b1);\n    sp_2048_mul_8(z2, &a[8], &b[8]);\n    sp_2048_mul_8(z0, a, b);\n    sp_2048_mask_8(r + 16, a1, 0 - cb);\n    sp_2048_mask_8(b1, b1, 0 - ca);\n    u += sp_2048_add_8(r + 16, r + 16, b1);\n    u += sp_2048_sub_in_place_16(z1, z2);\n    u += sp_2048_sub_in_place_16(z1, z0);\n    u += sp_2048_add_16(r + 8, r + 8, z1);\n    r[24] = u;\n    XMEMSET(r + 24 + 1, 0, sizeof(sp_digit) * (8 - 1));\n    (void)sp_2048_add_16(r + 16, r + 16, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_16(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[16];\n    sp_digit z1[16];\n    sp_digit a1[8];\n    sp_digit u;\n\n    u = sp_2048_add_8(a1, a, &a[8]);\n    sp_2048_sqr_8(z1, a1);\n    sp_2048_sqr_8(z2, &a[8]);\n    sp_2048_sqr_8(z0, a);\n    sp_2048_mask_8(r + 16, a1, 0 - u);\n    u += sp_2048_add_8(r + 16, r + 16, r + 16);\n    u += sp_2048_sub_in_place_16(z1, z2);\n    u += sp_2048_sub_in_place_16(z1, z0);\n    u += sp_2048_add_16(r + 8, r + 8, z1);\n    r[24] = u;\n    XMEMSET(r + 24 + 1, 0, sizeof(sp_digit) * (8 - 1));\n    (void)sp_2048_add_16(r + 16, r + 16, z2);\n}\n\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_sub_in_place_32(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr6, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"ldr\tr8, [%[b], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"subs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr6, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"ldr\tr8, [%[b], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr6, [%[b], #32]\\n\\t\"\n        \"ldr\tr7, [%[b], #36]\\n\\t\"\n        \"ldr\tr8, [%[b], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[a], #60]\\n\\t\"\n        \"ldr\tr6, [%[b], #48]\\n\\t\"\n        \"ldr\tr7, [%[b], #52]\\n\\t\"\n        \"ldr\tr8, [%[b], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr5, [%[a], #60]\\n\\t\"\n        \"ldr\tr2, [%[a], #64]\\n\\t\"\n        \"ldr\tr3, [%[a], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[a], #76]\\n\\t\"\n        \"ldr\tr6, [%[b], #64]\\n\\t\"\n        \"ldr\tr7, [%[b], #68]\\n\\t\"\n        \"ldr\tr8, [%[b], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #64]\\n\\t\"\n        \"str\tr3, [%[a], #68]\\n\\t\"\n        \"str\tr4, [%[a], #72]\\n\\t\"\n        \"str\tr5, [%[a], #76]\\n\\t\"\n        \"ldr\tr2, [%[a], #80]\\n\\t\"\n        \"ldr\tr3, [%[a], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[a], #92]\\n\\t\"\n        \"ldr\tr6, [%[b], #80]\\n\\t\"\n        \"ldr\tr7, [%[b], #84]\\n\\t\"\n        \"ldr\tr8, [%[b], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #80]\\n\\t\"\n        \"str\tr3, [%[a], #84]\\n\\t\"\n        \"str\tr4, [%[a], #88]\\n\\t\"\n        \"str\tr5, [%[a], #92]\\n\\t\"\n        \"ldr\tr2, [%[a], #96]\\n\\t\"\n        \"ldr\tr3, [%[a], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[a], #108]\\n\\t\"\n        \"ldr\tr6, [%[b], #96]\\n\\t\"\n        \"ldr\tr7, [%[b], #100]\\n\\t\"\n        \"ldr\tr8, [%[b], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #96]\\n\\t\"\n        \"str\tr3, [%[a], #100]\\n\\t\"\n        \"str\tr4, [%[a], #104]\\n\\t\"\n        \"str\tr5, [%[a], #108]\\n\\t\"\n        \"ldr\tr2, [%[a], #112]\\n\\t\"\n        \"ldr\tr3, [%[a], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[a], #124]\\n\\t\"\n        \"ldr\tr6, [%[b], #112]\\n\\t\"\n        \"ldr\tr7, [%[b], #116]\\n\\t\"\n        \"ldr\tr8, [%[b], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #112]\\n\\t\"\n        \"str\tr3, [%[a], #116]\\n\\t\"\n        \"str\tr4, [%[a], #120]\\n\\t\"\n        \"str\tr5, [%[a], #124]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[a], #4]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[b], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"ldr\tr10, [%[b], #8]\\n\\t\"\n        \"ldr\tr14, [%[b], #12]\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr5, [%[r], #4]\\n\\t\"\n        \"str\tr6, [%[r], #8]\\n\\t\"\n        \"str\tr7, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[a], #20]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[b], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"ldr\tr10, [%[b], #24]\\n\\t\"\n        \"ldr\tr14, [%[b], #28]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"str\tr6, [%[r], #24]\\n\\t\"\n        \"str\tr7, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[a], #36]\\n\\t\"\n        \"ldr\tr6, [%[a], #40]\\n\\t\"\n        \"ldr\tr7, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[b], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"ldr\tr10, [%[b], #40]\\n\\t\"\n        \"ldr\tr14, [%[b], #44]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr5, [%[r], #36]\\n\\t\"\n        \"str\tr6, [%[r], #40]\\n\\t\"\n        \"str\tr7, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[a], #52]\\n\\t\"\n        \"ldr\tr6, [%[a], #56]\\n\\t\"\n        \"ldr\tr7, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[b], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"ldr\tr10, [%[b], #56]\\n\\t\"\n        \"ldr\tr14, [%[b], #60]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"str\tr5, [%[r], #52]\\n\\t\"\n        \"str\tr6, [%[r], #56]\\n\\t\"\n        \"str\tr7, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[a], #68]\\n\\t\"\n        \"ldr\tr6, [%[a], #72]\\n\\t\"\n        \"ldr\tr7, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[b], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"ldr\tr10, [%[b], #72]\\n\\t\"\n        \"ldr\tr14, [%[b], #76]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"str\tr5, [%[r], #68]\\n\\t\"\n        \"str\tr6, [%[r], #72]\\n\\t\"\n        \"str\tr7, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[a], #84]\\n\\t\"\n        \"ldr\tr6, [%[a], #88]\\n\\t\"\n        \"ldr\tr7, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[b], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"ldr\tr10, [%[b], #88]\\n\\t\"\n        \"ldr\tr14, [%[b], #92]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"str\tr5, [%[r], #84]\\n\\t\"\n        \"str\tr6, [%[r], #88]\\n\\t\"\n        \"str\tr7, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[a], #100]\\n\\t\"\n        \"ldr\tr6, [%[a], #104]\\n\\t\"\n        \"ldr\tr7, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[b], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"ldr\tr10, [%[b], #104]\\n\\t\"\n        \"ldr\tr14, [%[b], #108]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"str\tr5, [%[r], #100]\\n\\t\"\n        \"str\tr6, [%[r], #104]\\n\\t\"\n        \"str\tr7, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[a], #116]\\n\\t\"\n        \"ldr\tr6, [%[a], #120]\\n\\t\"\n        \"ldr\tr7, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[b], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"ldr\tr10, [%[b], #120]\\n\\t\"\n        \"ldr\tr14, [%[b], #124]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"str\tr5, [%[r], #116]\\n\\t\"\n        \"str\tr6, [%[r], #120]\\n\\t\"\n        \"str\tr7, [%[r], #124]\\n\\t\"\n        \"adc\t%[c], r12, r12\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_16(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<16; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 16; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[32];\n    sp_digit a1[16];\n    sp_digit b1[16];\n    sp_digit z2[32];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_16(a1, a, &a[16]);\n    cb = sp_2048_add_16(b1, b, &b[16]);\n    u  = ca & cb;\n    sp_2048_mul_16(z1, a1, b1);\n    sp_2048_mul_16(z2, &a[16], &b[16]);\n    sp_2048_mul_16(z0, a, b);\n    sp_2048_mask_16(r + 32, a1, 0 - cb);\n    sp_2048_mask_16(b1, b1, 0 - ca);\n    u += sp_2048_add_16(r + 32, r + 32, b1);\n    u += sp_2048_sub_in_place_32(z1, z2);\n    u += sp_2048_sub_in_place_32(z1, z0);\n    u += sp_2048_add_32(r + 16, r + 16, z1);\n    r[48] = u;\n    XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));\n    (void)sp_2048_add_32(r + 32, r + 32, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[32];\n    sp_digit z1[32];\n    sp_digit a1[16];\n    sp_digit u;\n\n    u = sp_2048_add_16(a1, a, &a[16]);\n    sp_2048_sqr_16(z1, a1);\n    sp_2048_sqr_16(z2, &a[16]);\n    sp_2048_sqr_16(z0, a);\n    sp_2048_mask_16(r + 32, a1, 0 - u);\n    u += sp_2048_add_16(r + 32, r + 32, r + 32);\n    u += sp_2048_sub_in_place_32(z1, z2);\n    u += sp_2048_sub_in_place_32(z1, z0);\n    u += sp_2048_add_32(r + 16, r + 16, z1);\n    r[48] = u;\n    XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));\n    (void)sp_2048_add_32(r + 32, r + 32, z2);\n}\n\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_sub_in_place_64(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr6, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"ldr\tr8, [%[b], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"subs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr6, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"ldr\tr8, [%[b], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr6, [%[b], #32]\\n\\t\"\n        \"ldr\tr7, [%[b], #36]\\n\\t\"\n        \"ldr\tr8, [%[b], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[a], #60]\\n\\t\"\n        \"ldr\tr6, [%[b], #48]\\n\\t\"\n        \"ldr\tr7, [%[b], #52]\\n\\t\"\n        \"ldr\tr8, [%[b], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr5, [%[a], #60]\\n\\t\"\n        \"ldr\tr2, [%[a], #64]\\n\\t\"\n        \"ldr\tr3, [%[a], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[a], #76]\\n\\t\"\n        \"ldr\tr6, [%[b], #64]\\n\\t\"\n        \"ldr\tr7, [%[b], #68]\\n\\t\"\n        \"ldr\tr8, [%[b], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #64]\\n\\t\"\n        \"str\tr3, [%[a], #68]\\n\\t\"\n        \"str\tr4, [%[a], #72]\\n\\t\"\n        \"str\tr5, [%[a], #76]\\n\\t\"\n        \"ldr\tr2, [%[a], #80]\\n\\t\"\n        \"ldr\tr3, [%[a], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[a], #92]\\n\\t\"\n        \"ldr\tr6, [%[b], #80]\\n\\t\"\n        \"ldr\tr7, [%[b], #84]\\n\\t\"\n        \"ldr\tr8, [%[b], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #80]\\n\\t\"\n        \"str\tr3, [%[a], #84]\\n\\t\"\n        \"str\tr4, [%[a], #88]\\n\\t\"\n        \"str\tr5, [%[a], #92]\\n\\t\"\n        \"ldr\tr2, [%[a], #96]\\n\\t\"\n        \"ldr\tr3, [%[a], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[a], #108]\\n\\t\"\n        \"ldr\tr6, [%[b], #96]\\n\\t\"\n        \"ldr\tr7, [%[b], #100]\\n\\t\"\n        \"ldr\tr8, [%[b], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #96]\\n\\t\"\n        \"str\tr3, [%[a], #100]\\n\\t\"\n        \"str\tr4, [%[a], #104]\\n\\t\"\n        \"str\tr5, [%[a], #108]\\n\\t\"\n        \"ldr\tr2, [%[a], #112]\\n\\t\"\n        \"ldr\tr3, [%[a], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[a], #124]\\n\\t\"\n        \"ldr\tr6, [%[b], #112]\\n\\t\"\n        \"ldr\tr7, [%[b], #116]\\n\\t\"\n        \"ldr\tr8, [%[b], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #112]\\n\\t\"\n        \"str\tr3, [%[a], #116]\\n\\t\"\n        \"str\tr4, [%[a], #120]\\n\\t\"\n        \"str\tr5, [%[a], #124]\\n\\t\"\n        \"ldr\tr2, [%[a], #128]\\n\\t\"\n        \"ldr\tr3, [%[a], #132]\\n\\t\"\n        \"ldr\tr4, [%[a], #136]\\n\\t\"\n        \"ldr\tr5, [%[a], #140]\\n\\t\"\n        \"ldr\tr6, [%[b], #128]\\n\\t\"\n        \"ldr\tr7, [%[b], #132]\\n\\t\"\n        \"ldr\tr8, [%[b], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #128]\\n\\t\"\n        \"str\tr3, [%[a], #132]\\n\\t\"\n        \"str\tr4, [%[a], #136]\\n\\t\"\n        \"str\tr5, [%[a], #140]\\n\\t\"\n        \"ldr\tr2, [%[a], #144]\\n\\t\"\n        \"ldr\tr3, [%[a], #148]\\n\\t\"\n        \"ldr\tr4, [%[a], #152]\\n\\t\"\n        \"ldr\tr5, [%[a], #156]\\n\\t\"\n        \"ldr\tr6, [%[b], #144]\\n\\t\"\n        \"ldr\tr7, [%[b], #148]\\n\\t\"\n        \"ldr\tr8, [%[b], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #144]\\n\\t\"\n        \"str\tr3, [%[a], #148]\\n\\t\"\n        \"str\tr4, [%[a], #152]\\n\\t\"\n        \"str\tr5, [%[a], #156]\\n\\t\"\n        \"ldr\tr2, [%[a], #160]\\n\\t\"\n        \"ldr\tr3, [%[a], #164]\\n\\t\"\n        \"ldr\tr4, [%[a], #168]\\n\\t\"\n        \"ldr\tr5, [%[a], #172]\\n\\t\"\n        \"ldr\tr6, [%[b], #160]\\n\\t\"\n        \"ldr\tr7, [%[b], #164]\\n\\t\"\n        \"ldr\tr8, [%[b], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #160]\\n\\t\"\n        \"str\tr3, [%[a], #164]\\n\\t\"\n        \"str\tr4, [%[a], #168]\\n\\t\"\n        \"str\tr5, [%[a], #172]\\n\\t\"\n        \"ldr\tr2, [%[a], #176]\\n\\t\"\n        \"ldr\tr3, [%[a], #180]\\n\\t\"\n        \"ldr\tr4, [%[a], #184]\\n\\t\"\n        \"ldr\tr5, [%[a], #188]\\n\\t\"\n        \"ldr\tr6, [%[b], #176]\\n\\t\"\n        \"ldr\tr7, [%[b], #180]\\n\\t\"\n        \"ldr\tr8, [%[b], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #176]\\n\\t\"\n        \"str\tr3, [%[a], #180]\\n\\t\"\n        \"str\tr4, [%[a], #184]\\n\\t\"\n        \"str\tr5, [%[a], #188]\\n\\t\"\n        \"ldr\tr2, [%[a], #192]\\n\\t\"\n        \"ldr\tr3, [%[a], #196]\\n\\t\"\n        \"ldr\tr4, [%[a], #200]\\n\\t\"\n        \"ldr\tr5, [%[a], #204]\\n\\t\"\n        \"ldr\tr6, [%[b], #192]\\n\\t\"\n        \"ldr\tr7, [%[b], #196]\\n\\t\"\n        \"ldr\tr8, [%[b], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #192]\\n\\t\"\n        \"str\tr3, [%[a], #196]\\n\\t\"\n        \"str\tr4, [%[a], #200]\\n\\t\"\n        \"str\tr5, [%[a], #204]\\n\\t\"\n        \"ldr\tr2, [%[a], #208]\\n\\t\"\n        \"ldr\tr3, [%[a], #212]\\n\\t\"\n        \"ldr\tr4, [%[a], #216]\\n\\t\"\n        \"ldr\tr5, [%[a], #220]\\n\\t\"\n        \"ldr\tr6, [%[b], #208]\\n\\t\"\n        \"ldr\tr7, [%[b], #212]\\n\\t\"\n        \"ldr\tr8, [%[b], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #208]\\n\\t\"\n        \"str\tr3, [%[a], #212]\\n\\t\"\n        \"str\tr4, [%[a], #216]\\n\\t\"\n        \"str\tr5, [%[a], #220]\\n\\t\"\n        \"ldr\tr2, [%[a], #224]\\n\\t\"\n        \"ldr\tr3, [%[a], #228]\\n\\t\"\n        \"ldr\tr4, [%[a], #232]\\n\\t\"\n        \"ldr\tr5, [%[a], #236]\\n\\t\"\n        \"ldr\tr6, [%[b], #224]\\n\\t\"\n        \"ldr\tr7, [%[b], #228]\\n\\t\"\n        \"ldr\tr8, [%[b], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #224]\\n\\t\"\n        \"str\tr3, [%[a], #228]\\n\\t\"\n        \"str\tr4, [%[a], #232]\\n\\t\"\n        \"str\tr5, [%[a], #236]\\n\\t\"\n        \"ldr\tr2, [%[a], #240]\\n\\t\"\n        \"ldr\tr3, [%[a], #244]\\n\\t\"\n        \"ldr\tr4, [%[a], #248]\\n\\t\"\n        \"ldr\tr5, [%[a], #252]\\n\\t\"\n        \"ldr\tr6, [%[b], #240]\\n\\t\"\n        \"ldr\tr7, [%[b], #244]\\n\\t\"\n        \"ldr\tr8, [%[b], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #240]\\n\\t\"\n        \"str\tr3, [%[a], #244]\\n\\t\"\n        \"str\tr4, [%[a], #248]\\n\\t\"\n        \"str\tr5, [%[a], #252]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[a], #4]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[b], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"ldr\tr10, [%[b], #8]\\n\\t\"\n        \"ldr\tr14, [%[b], #12]\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr5, [%[r], #4]\\n\\t\"\n        \"str\tr6, [%[r], #8]\\n\\t\"\n        \"str\tr7, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[a], #20]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[b], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"ldr\tr10, [%[b], #24]\\n\\t\"\n        \"ldr\tr14, [%[b], #28]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"str\tr6, [%[r], #24]\\n\\t\"\n        \"str\tr7, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[a], #36]\\n\\t\"\n        \"ldr\tr6, [%[a], #40]\\n\\t\"\n        \"ldr\tr7, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[b], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"ldr\tr10, [%[b], #40]\\n\\t\"\n        \"ldr\tr14, [%[b], #44]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr5, [%[r], #36]\\n\\t\"\n        \"str\tr6, [%[r], #40]\\n\\t\"\n        \"str\tr7, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[a], #52]\\n\\t\"\n        \"ldr\tr6, [%[a], #56]\\n\\t\"\n        \"ldr\tr7, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[b], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"ldr\tr10, [%[b], #56]\\n\\t\"\n        \"ldr\tr14, [%[b], #60]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"str\tr5, [%[r], #52]\\n\\t\"\n        \"str\tr6, [%[r], #56]\\n\\t\"\n        \"str\tr7, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[a], #68]\\n\\t\"\n        \"ldr\tr6, [%[a], #72]\\n\\t\"\n        \"ldr\tr7, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[b], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"ldr\tr10, [%[b], #72]\\n\\t\"\n        \"ldr\tr14, [%[b], #76]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"str\tr5, [%[r], #68]\\n\\t\"\n        \"str\tr6, [%[r], #72]\\n\\t\"\n        \"str\tr7, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[a], #84]\\n\\t\"\n        \"ldr\tr6, [%[a], #88]\\n\\t\"\n        \"ldr\tr7, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[b], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"ldr\tr10, [%[b], #88]\\n\\t\"\n        \"ldr\tr14, [%[b], #92]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"str\tr5, [%[r], #84]\\n\\t\"\n        \"str\tr6, [%[r], #88]\\n\\t\"\n        \"str\tr7, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[a], #100]\\n\\t\"\n        \"ldr\tr6, [%[a], #104]\\n\\t\"\n        \"ldr\tr7, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[b], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"ldr\tr10, [%[b], #104]\\n\\t\"\n        \"ldr\tr14, [%[b], #108]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"str\tr5, [%[r], #100]\\n\\t\"\n        \"str\tr6, [%[r], #104]\\n\\t\"\n        \"str\tr7, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[a], #116]\\n\\t\"\n        \"ldr\tr6, [%[a], #120]\\n\\t\"\n        \"ldr\tr7, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[b], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"ldr\tr10, [%[b], #120]\\n\\t\"\n        \"ldr\tr14, [%[b], #124]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"str\tr5, [%[r], #116]\\n\\t\"\n        \"str\tr6, [%[r], #120]\\n\\t\"\n        \"str\tr7, [%[r], #124]\\n\\t\"\n        \"ldr\tr4, [%[a], #128]\\n\\t\"\n        \"ldr\tr5, [%[a], #132]\\n\\t\"\n        \"ldr\tr6, [%[a], #136]\\n\\t\"\n        \"ldr\tr7, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[b], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"ldr\tr10, [%[b], #136]\\n\\t\"\n        \"ldr\tr14, [%[b], #140]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #128]\\n\\t\"\n        \"str\tr5, [%[r], #132]\\n\\t\"\n        \"str\tr6, [%[r], #136]\\n\\t\"\n        \"str\tr7, [%[r], #140]\\n\\t\"\n        \"ldr\tr4, [%[a], #144]\\n\\t\"\n        \"ldr\tr5, [%[a], #148]\\n\\t\"\n        \"ldr\tr6, [%[a], #152]\\n\\t\"\n        \"ldr\tr7, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[b], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"ldr\tr10, [%[b], #152]\\n\\t\"\n        \"ldr\tr14, [%[b], #156]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #144]\\n\\t\"\n        \"str\tr5, [%[r], #148]\\n\\t\"\n        \"str\tr6, [%[r], #152]\\n\\t\"\n        \"str\tr7, [%[r], #156]\\n\\t\"\n        \"ldr\tr4, [%[a], #160]\\n\\t\"\n        \"ldr\tr5, [%[a], #164]\\n\\t\"\n        \"ldr\tr6, [%[a], #168]\\n\\t\"\n        \"ldr\tr7, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[b], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"ldr\tr10, [%[b], #168]\\n\\t\"\n        \"ldr\tr14, [%[b], #172]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"str\tr5, [%[r], #164]\\n\\t\"\n        \"str\tr6, [%[r], #168]\\n\\t\"\n        \"str\tr7, [%[r], #172]\\n\\t\"\n        \"ldr\tr4, [%[a], #176]\\n\\t\"\n        \"ldr\tr5, [%[a], #180]\\n\\t\"\n        \"ldr\tr6, [%[a], #184]\\n\\t\"\n        \"ldr\tr7, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[b], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"ldr\tr10, [%[b], #184]\\n\\t\"\n        \"ldr\tr14, [%[b], #188]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #176]\\n\\t\"\n        \"str\tr5, [%[r], #180]\\n\\t\"\n        \"str\tr6, [%[r], #184]\\n\\t\"\n        \"str\tr7, [%[r], #188]\\n\\t\"\n        \"ldr\tr4, [%[a], #192]\\n\\t\"\n        \"ldr\tr5, [%[a], #196]\\n\\t\"\n        \"ldr\tr6, [%[a], #200]\\n\\t\"\n        \"ldr\tr7, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[b], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"ldr\tr10, [%[b], #200]\\n\\t\"\n        \"ldr\tr14, [%[b], #204]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #192]\\n\\t\"\n        \"str\tr5, [%[r], #196]\\n\\t\"\n        \"str\tr6, [%[r], #200]\\n\\t\"\n        \"str\tr7, [%[r], #204]\\n\\t\"\n        \"ldr\tr4, [%[a], #208]\\n\\t\"\n        \"ldr\tr5, [%[a], #212]\\n\\t\"\n        \"ldr\tr6, [%[a], #216]\\n\\t\"\n        \"ldr\tr7, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[b], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"ldr\tr10, [%[b], #216]\\n\\t\"\n        \"ldr\tr14, [%[b], #220]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #208]\\n\\t\"\n        \"str\tr5, [%[r], #212]\\n\\t\"\n        \"str\tr6, [%[r], #216]\\n\\t\"\n        \"str\tr7, [%[r], #220]\\n\\t\"\n        \"ldr\tr4, [%[a], #224]\\n\\t\"\n        \"ldr\tr5, [%[a], #228]\\n\\t\"\n        \"ldr\tr6, [%[a], #232]\\n\\t\"\n        \"ldr\tr7, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[b], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"ldr\tr10, [%[b], #232]\\n\\t\"\n        \"ldr\tr14, [%[b], #236]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #224]\\n\\t\"\n        \"str\tr5, [%[r], #228]\\n\\t\"\n        \"str\tr6, [%[r], #232]\\n\\t\"\n        \"str\tr7, [%[r], #236]\\n\\t\"\n        \"ldr\tr4, [%[a], #240]\\n\\t\"\n        \"ldr\tr5, [%[a], #244]\\n\\t\"\n        \"ldr\tr6, [%[a], #248]\\n\\t\"\n        \"ldr\tr7, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[b], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"ldr\tr10, [%[b], #248]\\n\\t\"\n        \"ldr\tr14, [%[b], #252]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #240]\\n\\t\"\n        \"str\tr5, [%[r], #244]\\n\\t\"\n        \"str\tr6, [%[r], #248]\\n\\t\"\n        \"str\tr7, [%[r], #252]\\n\\t\"\n        \"adc\t%[c], r12, r12\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_32(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<32; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[64];\n    sp_digit a1[32];\n    sp_digit b1[32];\n    sp_digit z2[64];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_32(a1, a, &a[32]);\n    cb = sp_2048_add_32(b1, b, &b[32]);\n    u  = ca & cb;\n    sp_2048_mul_32(z1, a1, b1);\n    sp_2048_mul_32(z2, &a[32], &b[32]);\n    sp_2048_mul_32(z0, a, b);\n    sp_2048_mask_32(r + 64, a1, 0 - cb);\n    sp_2048_mask_32(b1, b1, 0 - ca);\n    u += sp_2048_add_32(r + 64, r + 64, b1);\n    u += sp_2048_sub_in_place_64(z1, z2);\n    u += sp_2048_sub_in_place_64(z1, z0);\n    u += sp_2048_add_64(r + 32, r + 32, z1);\n    r[96] = u;\n    XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));\n    (void)sp_2048_add_64(r + 64, r + 64, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_64(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[64];\n    sp_digit z1[64];\n    sp_digit a1[32];\n    sp_digit u;\n\n    u = sp_2048_add_32(a1, a, &a[32]);\n    sp_2048_sqr_32(z1, a1);\n    sp_2048_sqr_32(z2, &a[32]);\n    sp_2048_sqr_32(z0, a);\n    sp_2048_mask_32(r + 64, a1, 0 - u);\n    u += sp_2048_add_32(r + 64, r + 64, r + 64);\n    u += sp_2048_sub_in_place_64(z1, z2);\n    u += sp_2048_sub_in_place_64(z1, z0);\n    u += sp_2048_add_64(r + 32, r + 32, z1);\n    r[96] = u;\n    XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));\n    (void)sp_2048_add_64(r + 64, r + 64, z2);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tr12, %[a], #256\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], #-1\\n\\t\"\n        \"ldr\tr4, [%[a]], #4\\n\\t\"\n        \"ldr\tr5, [%[a]], #4\\n\\t\"\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"ldr\tr7, [%[a]], #4\\n\\t\"\n        \"ldr\tr8, [%[b]], #4\\n\\t\"\n        \"ldr\tr9, [%[b]], #4\\n\\t\"\n        \"ldr\tr10, [%[b]], #4\\n\\t\"\n        \"ldr\tr14, [%[b]], #4\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r]], #4\\n\\t\"\n        \"str\tr5, [%[r]], #4\\n\\t\"\n        \"str\tr6, [%[r]], #4\\n\\t\"\n        \"str\tr7, [%[r]], #4\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"adc\t%[c], r4, #0\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_sub_in_place_64(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr14, #0\\n\\t\"\n        \"add\tr12, %[a], #256\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\t%[c], r14, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b]], #4\\n\\t\"\n        \"ldr\tr8, [%[b]], #4\\n\\t\"\n        \"ldr\tr9, [%[b]], #4\\n\\t\"\n        \"ldr\tr10, [%[b]], #4\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"sbcs\tr6, r6, r10\\n\\t\"\n        \"str\tr3, [%[a]], #4\\n\\t\"\n        \"str\tr4, [%[a]], #4\\n\\t\"\n        \"str\tr5, [%[a]], #4\\n\\t\"\n        \"str\tr6, [%[a]], #4\\n\\t\"\n        \"sbc\t%[c], r14, r14\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r12\", \"r14\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_2048_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #512\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tr3, r5, #252\\n\\t\"\n        \"it\tcc\\n\\t\"\n        \"movcc\tr3, #0\\n\\t\"\n        \"sub\tr4, r5, r3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"ldr\tr12, [%[b], r4]\\n\\t\"\n        \"umull\tr9, r10, r14, r12\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, #0\\n\\t\"\n        \"add\tr3, r3, #4\\n\\t\"\n        \"sub\tr4, r4, #4\\n\\t\"\n        \"cmp\tr3, #256\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\tr3, r5\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"mov\tr6, r7\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"add\tr5, r5, #4\\n\\t\"\n        \"cmp\tr5, #504\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [sp, #0]\\n\\t\"\n        \"ldr\tr7, [sp, #4]\\n\\t\"\n        \"ldr\tr8, [sp, #8]\\n\\t\"\n        \"ldr\tr3, [sp, #12]\\n\\t\"\n        \"str\tr6, [%[r], #0]\\n\\t\"\n        \"str\tr7, [%[r], #4]\\n\\t\"\n        \"str\tr8, [%[r], #8]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"add\tsp, sp, #16\\n\\t\"\n        \"add\t%[r], %[r], #16\\n\\t\"\n        \"subs\tr5, r5, #16\\n\\t\"\n        \"bgt\t4b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_2048_sqr_64(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #512\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tr3, r5, #252\\n\\t\"\n        \"it\tcc\\n\\t\"\n        \"movcc\tr3, r12\\n\\t\"\n        \"sub\tr4, r5, r3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr4, r3\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"ldr\tr9, [%[a], r4]\\n\\t\"\n        \"umull\tr9, r10, r14, r9\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"umull\tr9, r10, r14, r14\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\tr3, r3, #4\\n\\t\"\n        \"sub\tr4, r4, #4\\n\\t\"\n        \"cmp\tr3, #256\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\tr3, r4\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"cmp\tr3, r5\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"mov\tr6, r7\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"add\tr5, r5, #4\\n\\t\"\n        \"cmp\tr5, #504\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [sp, #0]\\n\\t\"\n        \"ldr\tr7, [sp, #4]\\n\\t\"\n        \"ldr\tr8, [sp, #8]\\n\\t\"\n        \"ldr\tr3, [sp, #12]\\n\\t\"\n        \"str\tr6, [%[r], #0]\\n\\t\"\n        \"str\tr7, [%[r], #4]\\n\\t\"\n        \"str\tr8, [%[r], #8]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"add\tsp, sp, #16\\n\\t\"\n        \"add\t%[r], %[r], #16\\n\\t\"\n        \"subs\tr5, r5, #16\\n\\t\"\n        \"bgt\t4b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r9\", \"r12\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_32(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n    int i;\n\n    for (i=0; i<32; i++) {\n        r[i] = a[i] & m;\n    }\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tr12, %[a], #128\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], #-1\\n\\t\"\n        \"ldr\tr4, [%[a]], #4\\n\\t\"\n        \"ldr\tr5, [%[a]], #4\\n\\t\"\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"ldr\tr7, [%[a]], #4\\n\\t\"\n        \"ldr\tr8, [%[b]], #4\\n\\t\"\n        \"ldr\tr9, [%[b]], #4\\n\\t\"\n        \"ldr\tr10, [%[b]], #4\\n\\t\"\n        \"ldr\tr14, [%[b]], #4\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r]], #4\\n\\t\"\n        \"str\tr5, [%[r]], #4\\n\\t\"\n        \"str\tr6, [%[r]], #4\\n\\t\"\n        \"str\tr7, [%[r]], #4\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"adc\t%[c], r4, #0\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_sub_in_place_32(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr14, #0\\n\\t\"\n        \"add\tr12, %[a], #128\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\t%[c], r14, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b]], #4\\n\\t\"\n        \"ldr\tr8, [%[b]], #4\\n\\t\"\n        \"ldr\tr9, [%[b]], #4\\n\\t\"\n        \"ldr\tr10, [%[b]], #4\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"sbcs\tr6, r6, r10\\n\\t\"\n        \"str\tr3, [%[a]], #4\\n\\t\"\n        \"str\tr4, [%[a]], #4\\n\\t\"\n        \"str\tr5, [%[a]], #4\\n\\t\"\n        \"str\tr6, [%[a]], #4\\n\\t\"\n        \"sbc\t%[c], r14, r14\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r12\", \"r14\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_2048_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #256\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tr3, r5, #124\\n\\t\"\n        \"it\tcc\\n\\t\"\n        \"movcc\tr3, #0\\n\\t\"\n        \"sub\tr4, r5, r3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"ldr\tr12, [%[b], r4]\\n\\t\"\n        \"umull\tr9, r10, r14, r12\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, #0\\n\\t\"\n        \"add\tr3, r3, #4\\n\\t\"\n        \"sub\tr4, r4, #4\\n\\t\"\n        \"cmp\tr3, #128\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\tr3, r5\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"mov\tr6, r7\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"add\tr5, r5, #4\\n\\t\"\n        \"cmp\tr5, #248\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [sp, #0]\\n\\t\"\n        \"ldr\tr7, [sp, #4]\\n\\t\"\n        \"ldr\tr8, [sp, #8]\\n\\t\"\n        \"ldr\tr3, [sp, #12]\\n\\t\"\n        \"str\tr6, [%[r], #0]\\n\\t\"\n        \"str\tr7, [%[r], #4]\\n\\t\"\n        \"str\tr8, [%[r], #8]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"add\tsp, sp, #16\\n\\t\"\n        \"add\t%[r], %[r], #16\\n\\t\"\n        \"subs\tr5, r5, #16\\n\\t\"\n        \"bgt\t4b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_2048_sqr_32(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #256\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tr3, r5, #124\\n\\t\"\n        \"it\tcc\\n\\t\"\n        \"movcc\tr3, r12\\n\\t\"\n        \"sub\tr4, r5, r3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr4, r3\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"ldr\tr9, [%[a], r4]\\n\\t\"\n        \"umull\tr9, r10, r14, r9\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"umull\tr9, r10, r14, r14\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\tr3, r3, #4\\n\\t\"\n        \"sub\tr4, r4, #4\\n\\t\"\n        \"cmp\tr3, #128\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\tr3, r4\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"cmp\tr3, r5\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"mov\tr6, r7\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"add\tr5, r5, #4\\n\\t\"\n        \"cmp\tr5, #248\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [sp, #0]\\n\\t\"\n        \"ldr\tr7, [sp, #4]\\n\\t\"\n        \"ldr\tr8, [sp, #8]\\n\\t\"\n        \"ldr\tr3, [sp, #12]\\n\\t\"\n        \"str\tr6, [%[r], #0]\\n\\t\"\n        \"str\tr7, [%[r], #4]\\n\\t\"\n        \"str\tr8, [%[r], #8]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"add\tsp, sp, #16\\n\\t\"\n        \"add\t%[r], %[r], #16\\n\\t\"\n        \"subs\tr5, r5, #16\\n\\t\"\n        \"bgt\t4b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r9\", \"r12\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nstatic void sp_2048_mul_d_64(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr10, #0\\n\\t\"\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tr8, [%[a]]\\n\\t\"\n        \"umull\tr5, r3, %[b], r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr5, [%[r]]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr9, #4\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr8, [%[a], r9]\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], r9]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr9, r9, #4\\n\\t\"\n        \"cmp\tr9, #256\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r], #256]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tr10, #0\\n\\t\"\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tr8, [%[a]]\\n\\t\"\n        \"umull\tr3, r4, %[b], r8\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"# A[1] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"# A[2] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"# A[3] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"# A[4] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"# A[5] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"# A[6] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"# A[7] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"# A[8] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #32]\\n\\t\"\n        \"# A[9] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"# A[10] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"# A[11] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #44]\\n\\t\"\n        \"# A[12] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"# A[13] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"# A[14] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #56]\\n\\t\"\n        \"# A[15] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"# A[16] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"# A[17] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #68]\\n\\t\"\n        \"# A[18] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #72]\\n\\t\"\n        \"# A[19] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"# A[20] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #80]\\n\\t\"\n        \"# A[21] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #84]\\n\\t\"\n        \"# A[22] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"# A[23] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #92]\\n\\t\"\n        \"# A[24] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #96]\\n\\t\"\n        \"# A[25] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"# A[26] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #104]\\n\\t\"\n        \"# A[27] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #108]\\n\\t\"\n        \"# A[28] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"# A[29] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #116]\\n\\t\"\n        \"# A[30] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #120]\\n\\t\"\n        \"# A[31] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"# A[32] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #128]\\n\\t\"\n        \"# A[33] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #132]\\n\\t\"\n        \"# A[34] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #136]\\n\\t\"\n        \"# A[35] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #140]\\n\\t\"\n        \"# A[36] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #144]\\n\\t\"\n        \"# A[37] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #148]\\n\\t\"\n        \"# A[38] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #152]\\n\\t\"\n        \"# A[39] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #156]\\n\\t\"\n        \"# A[40] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"# A[41] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #164]\\n\\t\"\n        \"# A[42] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #168]\\n\\t\"\n        \"# A[43] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #172]\\n\\t\"\n        \"# A[44] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #176]\\n\\t\"\n        \"# A[45] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #180]\\n\\t\"\n        \"# A[46] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #184]\\n\\t\"\n        \"# A[47] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #188]\\n\\t\"\n        \"# A[48] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #192]\\n\\t\"\n        \"# A[49] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #196]\\n\\t\"\n        \"# A[50] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #200]\\n\\t\"\n        \"# A[51] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #204]\\n\\t\"\n        \"# A[52] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #208]\\n\\t\"\n        \"# A[53] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #212]\\n\\t\"\n        \"# A[54] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #216]\\n\\t\"\n        \"# A[55] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #220]\\n\\t\"\n        \"# A[56] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #224]\\n\\t\"\n        \"# A[57] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #228]\\n\\t\"\n        \"# A[58] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #232]\\n\\t\"\n        \"# A[59] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #236]\\n\\t\"\n        \"# A[60] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #240]\\n\\t\"\n        \"# A[61] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #244]\\n\\t\"\n        \"# A[62] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #248]\\n\\t\"\n        \"# A[63] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr3, [%[r], #252]\\n\\t\"\n        \"str\tr4, [%[r], #256]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n#endif\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_32(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 32);\n\n    /* r = 2^n mod m */\n    sp_2048_sub_in_place_32(r, m);\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        sp_digit m)\n{\n    sp_digit c = 0;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr9, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"subs\t%[c], r9, %[c]\\n\\t\"\n        \"ldr\tr4, [%[a], r8]\\n\\t\"\n        \"ldr\tr5, [%[b], r8]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        \"str\tr4, [%[r], r8]\\n\\t\"\n        \"add\tr8, r8, #4\\n\\t\"\n        \"cmp\tr8, #128\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r4\", \"r6\", \"r5\", \"r7\", \"r8\", \"r9\"\n    );\n#else\n    __asm__ __volatile__ (\n\n        \"mov\tr9, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr6, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr6, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr6, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr7, [%[b], #36]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr6, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr6, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr7, [%[b], #44]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"str\tr6, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr6, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr7, [%[b], #52]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"str\tr6, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr6, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr7, [%[b], #60]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"str\tr6, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr6, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr7, [%[b], #68]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"str\tr6, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr6, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr7, [%[b], #76]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"str\tr6, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr6, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr7, [%[b], #84]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"str\tr6, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr6, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr7, [%[b], #92]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"str\tr6, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr6, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr7, [%[b], #100]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"str\tr6, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr6, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr7, [%[b], #108]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"str\tr6, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr6, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr7, [%[b], #116]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"str\tr6, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr6, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr7, [%[b], #124]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"str\tr6, [%[r], #124]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r4\", \"r6\", \"r5\", \"r7\", \"r8\", \"r9\"\n    );\n#endif /* WOLFSSL_SP_SMALL */\n\n    return c;\n}\n\n/* Reduce the number back to 2048 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"# i = 0\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr10, [%[a], #0]\\n\\t\"\n        \"ldr\tr14, [%[a], #4]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mul\tr8, %[mp], r10\\n\\t\"\n        \"# a[i+0] += m[0] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #0]\\n\\t\"\n        \"ldr\tr9, [%[a], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr10, r10, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"# a[i+1] += m[1] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #4]\\n\\t\"\n        \"ldr\tr9, [%[a], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr10, r14, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr10, r10, r5\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+2] += m[2] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #8]\\n\\t\"\n        \"ldr\tr14, [%[a], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr14, r14, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr14, r14, r4\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+3] += m[3] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #12]\\n\\t\"\n        \"ldr\tr9, [%[a], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #12]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+4] += m[4] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #16]\\n\\t\"\n        \"ldr\tr9, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #16]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+5] += m[5] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #20]\\n\\t\"\n        \"ldr\tr9, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #20]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+6] += m[6] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #24]\\n\\t\"\n        \"ldr\tr9, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #24]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+7] += m[7] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #28]\\n\\t\"\n        \"ldr\tr9, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #28]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+8] += m[8] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #32]\\n\\t\"\n        \"ldr\tr9, [%[a], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #32]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+9] += m[9] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #36]\\n\\t\"\n        \"ldr\tr9, [%[a], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #36]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+10] += m[10] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #40]\\n\\t\"\n        \"ldr\tr9, [%[a], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #40]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+11] += m[11] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #44]\\n\\t\"\n        \"ldr\tr9, [%[a], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #44]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+12] += m[12] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #48]\\n\\t\"\n        \"ldr\tr9, [%[a], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #48]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+13] += m[13] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #52]\\n\\t\"\n        \"ldr\tr9, [%[a], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #52]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+14] += m[14] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #56]\\n\\t\"\n        \"ldr\tr9, [%[a], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #56]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+15] += m[15] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #60]\\n\\t\"\n        \"ldr\tr9, [%[a], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #60]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+16] += m[16] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #64]\\n\\t\"\n        \"ldr\tr9, [%[a], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #64]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+17] += m[17] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #68]\\n\\t\"\n        \"ldr\tr9, [%[a], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #68]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+18] += m[18] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #72]\\n\\t\"\n        \"ldr\tr9, [%[a], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #72]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+19] += m[19] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #76]\\n\\t\"\n        \"ldr\tr9, [%[a], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #76]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+20] += m[20] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #80]\\n\\t\"\n        \"ldr\tr9, [%[a], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #80]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+21] += m[21] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #84]\\n\\t\"\n        \"ldr\tr9, [%[a], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #84]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+22] += m[22] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #88]\\n\\t\"\n        \"ldr\tr9, [%[a], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #88]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+23] += m[23] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #92]\\n\\t\"\n        \"ldr\tr9, [%[a], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #92]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+24] += m[24] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #96]\\n\\t\"\n        \"ldr\tr9, [%[a], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #96]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+25] += m[25] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #100]\\n\\t\"\n        \"ldr\tr9, [%[a], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #100]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+26] += m[26] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #104]\\n\\t\"\n        \"ldr\tr9, [%[a], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #104]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+27] += m[27] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #108]\\n\\t\"\n        \"ldr\tr9, [%[a], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #108]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+28] += m[28] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #112]\\n\\t\"\n        \"ldr\tr9, [%[a], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #112]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+29] += m[29] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #116]\\n\\t\"\n        \"ldr\tr9, [%[a], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #116]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+30] += m[30] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #120]\\n\\t\"\n        \"ldr\tr9, [%[a], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #120]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+31] += m[31] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #124]\\n\\t\"\n        \"ldr   r9, [%[a], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr7, r7, %[ca]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"adc\t%[ca], %[ca], %[ca]\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[a], #128]\\n\\t\"\n        \"adcs\tr9, r9, r7\\n\\t\"\n        \"str\tr9, [%[a], #128]\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"add\tr12, r12, #4\\n\\t\"\n        \"cmp\tr12, #128\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr10, [%[a], #0]\\n\\t\"\n        \"str\tr14, [%[a], #4]\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    sp_2048_cond_sub_32(a - 32, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_32(r, a, b);\n    sp_2048_mont_reduce_32(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_32(r, a);\n    sp_2048_mont_reduce_32(r, m, mp);\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nstatic void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr10, #0\\n\\t\"\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tr8, [%[a]]\\n\\t\"\n        \"umull\tr5, r3, %[b], r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr5, [%[r]]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr9, #4\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr8, [%[a], r9]\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], r9]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr9, r9, #4\\n\\t\"\n        \"cmp\tr9, #128\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r], #128]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tr10, #0\\n\\t\"\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tr8, [%[a]]\\n\\t\"\n        \"umull\tr3, r4, %[b], r8\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"# A[1] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"# A[2] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"# A[3] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"# A[4] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"# A[5] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"# A[6] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"# A[7] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"# A[8] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #32]\\n\\t\"\n        \"# A[9] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"# A[10] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"# A[11] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #44]\\n\\t\"\n        \"# A[12] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"# A[13] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"# A[14] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #56]\\n\\t\"\n        \"# A[15] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"# A[16] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"# A[17] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #68]\\n\\t\"\n        \"# A[18] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #72]\\n\\t\"\n        \"# A[19] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"# A[20] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #80]\\n\\t\"\n        \"# A[21] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #84]\\n\\t\"\n        \"# A[22] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"# A[23] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #92]\\n\\t\"\n        \"# A[24] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #96]\\n\\t\"\n        \"# A[25] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"# A[26] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #104]\\n\\t\"\n        \"# A[27] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #108]\\n\\t\"\n        \"# A[28] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"# A[29] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #116]\\n\\t\"\n        \"# A[30] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #120]\\n\\t\"\n        \"# A[31] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"str\tr5, [%[r], #128]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n#endif\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nstatic sp_digit div_2048_word_32(sp_digit d1, sp_digit d0, sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr5, %[div], #1\\n\\t\"\n        \"add\tr5, r5, #1\\n\\t\"\n        \"mov\tr6, %[d0]\\n\\t\"\n        \"mov\tr7, %[d1]\\n\\t\"\n        \"# Do top 32\\n\\t\"\n        \"subs\tr8, r5, r7\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        \"and\tr8, r8, r5\\n\\t\"\n        \"subs\tr7, r7, r8\\n\\t\"\n        \"# Next 30 bits\\n\\t\"\n        \"mov\tr4, #29\\n\\t\"\n        \"1:\\n\\t\"\n        \"movs\tr6, r6, lsl #1\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"subs\tr8, r5, r7\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        \"and\tr8, r8, r5\\n\\t\"\n        \"subs\tr7, r7, r8\\n\\t\"\n        \"subs\tr4, r4, #1\\n\\t\"\n        \"bpl\t1b\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"add\t%[r], %[r], #1\\n\\t\"\n        \"umull\tr4, r5, %[r], %[div]\\n\\t\"\n        \"subs\tr4, %[d0], r4\\n\\t\"\n        \"sbc\tr5, %[d1], r5\\n\\t\"\n        \"add\t%[r], %[r], r5\\n\\t\"\n        \"umull\tr4, r5, %[r], %[div]\\n\\t\"\n        \"subs\tr4, %[d0], r4\\n\\t\"\n        \"sbc\tr5, %[d1], r5\\n\\t\"\n        \"add\t%[r], %[r], r5\\n\\t\"\n        \"subs\tr8, %[div], r4\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n    return r;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic int32_t sp_2048_cmp_32(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = -1;\n    sp_digit one = 1;\n\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr3, #-1\\n\\t\"\n        \"mov\tr6, #124\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr4, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr4, r4, r3\\n\\t\"\n        \"and\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"subs\tr6, r6, #4\\n\\t\"\n        \"bcs\t1b\\n\\t\"\n        \"eor\t%[r], %[r], r3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr3, #-1\\n\\t\"\n        \"ldr\t\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #124]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #120]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #116]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #112]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #108]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #104]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #100]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #96]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #92]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #88]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #84]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #80]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #76]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #72]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #68]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #64]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #60]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #56]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #52]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #48]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #44]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #40]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #36]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #32]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #28]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #24]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #20]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #16]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #12]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #8]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #4]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #0]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"eor\t%[r], %[r], r3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n#endif\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_32(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[64], t2[33];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n\n    div = d[31];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 32);\n    for (i=31; i>=0; i--) {\n        r1 = div_2048_word_32(t1[32 + i], t1[32 + i - 1], div);\n\n        sp_2048_mul_d_32(t2, d, r1);\n        t1[32 + i] += sp_2048_sub_in_place_32(&t1[i], t2);\n        t1[32 + i] -= t2[32];\n        sp_2048_mask_32(t2, d, t1[32 + i]);\n        t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], t2);\n        sp_2048_mask_32(t2, d, t1[32 + i]);\n        t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_2048_cmp_32(t1, d) >= 0;\n    sp_2048_cond_sub_32(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_32(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_32(a, m, NULL, r);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][64];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 64, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 64;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_32(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 32U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_32(t[1] + 32, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_32(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 32, a, sizeof(sp_digit) * 32);\n            err = sp_2048_mod_32(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_32(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_32(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_32(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_32(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_32(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_32(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_32(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_32(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_32(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_32(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_32(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_32(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_32(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_32(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 32);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n\n            sp_2048_mont_mul_32(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[32], 0, sizeof(sp_digit) * 32U);\n        sp_2048_mont_reduce_32(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_32(r, m) >= 0);\n        sp_2048_cond_sub_32(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][64];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 64, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 64;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_32(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 32U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_32(t[1] + 32, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_32(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 32, a, sizeof(sp_digit) * 32);\n            err = sp_2048_mod_32(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_32(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_32(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_32(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_32(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_32(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_32(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_32(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_32(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_32(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_32(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_32(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_32(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_32(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_32(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_32(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_32(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_32(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_32(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_32(t[20], t[10], m, mp);\n        sp_2048_mont_mul_32(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_32(t[22], t[11], m, mp);\n        sp_2048_mont_mul_32(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_32(t[24], t[12], m, mp);\n        sp_2048_mont_mul_32(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_32(t[26], t[13], m, mp);\n        sp_2048_mont_mul_32(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_32(t[28], t[14], m, mp);\n        sp_2048_mont_mul_32(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_32(t[30], t[15], m, mp);\n        sp_2048_mont_mul_32(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 32);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n\n            sp_2048_mont_mul_32(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[32], 0, sizeof(sp_digit) * 32U);\n        sp_2048_mont_reduce_32(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_32(r, m) >= 0);\n        sp_2048_cond_sub_32(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_64(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 64);\n\n    /* r = 2^n mod m */\n    sp_2048_sub_in_place_64(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        sp_digit m)\n{\n    sp_digit c = 0;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr9, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"subs\t%[c], r9, %[c]\\n\\t\"\n        \"ldr\tr4, [%[a], r8]\\n\\t\"\n        \"ldr\tr5, [%[b], r8]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        \"str\tr4, [%[r], r8]\\n\\t\"\n        \"add\tr8, r8, #4\\n\\t\"\n        \"cmp\tr8, #256\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r4\", \"r6\", \"r5\", \"r7\", \"r8\", \"r9\"\n    );\n#else\n    __asm__ __volatile__ (\n\n        \"mov\tr9, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr6, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr6, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr6, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr7, [%[b], #36]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr6, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr6, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr7, [%[b], #44]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"str\tr6, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr6, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr7, [%[b], #52]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"str\tr6, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr6, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr7, [%[b], #60]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"str\tr6, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr6, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr7, [%[b], #68]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"str\tr6, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr6, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr7, [%[b], #76]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"str\tr6, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr6, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr7, [%[b], #84]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"str\tr6, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr6, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr7, [%[b], #92]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"str\tr6, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr6, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr7, [%[b], #100]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"str\tr6, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr6, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr7, [%[b], #108]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"str\tr6, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr6, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr7, [%[b], #116]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"str\tr6, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr6, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr7, [%[b], #124]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"str\tr6, [%[r], #124]\\n\\t\"\n        \"ldr\tr4, [%[a], #128]\\n\\t\"\n        \"ldr\tr6, [%[a], #132]\\n\\t\"\n        \"ldr\tr5, [%[b], #128]\\n\\t\"\n        \"ldr\tr7, [%[b], #132]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #128]\\n\\t\"\n        \"str\tr6, [%[r], #132]\\n\\t\"\n        \"ldr\tr4, [%[a], #136]\\n\\t\"\n        \"ldr\tr6, [%[a], #140]\\n\\t\"\n        \"ldr\tr5, [%[b], #136]\\n\\t\"\n        \"ldr\tr7, [%[b], #140]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #136]\\n\\t\"\n        \"str\tr6, [%[r], #140]\\n\\t\"\n        \"ldr\tr4, [%[a], #144]\\n\\t\"\n        \"ldr\tr6, [%[a], #148]\\n\\t\"\n        \"ldr\tr5, [%[b], #144]\\n\\t\"\n        \"ldr\tr7, [%[b], #148]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #144]\\n\\t\"\n        \"str\tr6, [%[r], #148]\\n\\t\"\n        \"ldr\tr4, [%[a], #152]\\n\\t\"\n        \"ldr\tr6, [%[a], #156]\\n\\t\"\n        \"ldr\tr5, [%[b], #152]\\n\\t\"\n        \"ldr\tr7, [%[b], #156]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #152]\\n\\t\"\n        \"str\tr6, [%[r], #156]\\n\\t\"\n        \"ldr\tr4, [%[a], #160]\\n\\t\"\n        \"ldr\tr6, [%[a], #164]\\n\\t\"\n        \"ldr\tr5, [%[b], #160]\\n\\t\"\n        \"ldr\tr7, [%[b], #164]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"str\tr6, [%[r], #164]\\n\\t\"\n        \"ldr\tr4, [%[a], #168]\\n\\t\"\n        \"ldr\tr6, [%[a], #172]\\n\\t\"\n        \"ldr\tr5, [%[b], #168]\\n\\t\"\n        \"ldr\tr7, [%[b], #172]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #168]\\n\\t\"\n        \"str\tr6, [%[r], #172]\\n\\t\"\n        \"ldr\tr4, [%[a], #176]\\n\\t\"\n        \"ldr\tr6, [%[a], #180]\\n\\t\"\n        \"ldr\tr5, [%[b], #176]\\n\\t\"\n        \"ldr\tr7, [%[b], #180]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #176]\\n\\t\"\n        \"str\tr6, [%[r], #180]\\n\\t\"\n        \"ldr\tr4, [%[a], #184]\\n\\t\"\n        \"ldr\tr6, [%[a], #188]\\n\\t\"\n        \"ldr\tr5, [%[b], #184]\\n\\t\"\n        \"ldr\tr7, [%[b], #188]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #184]\\n\\t\"\n        \"str\tr6, [%[r], #188]\\n\\t\"\n        \"ldr\tr4, [%[a], #192]\\n\\t\"\n        \"ldr\tr6, [%[a], #196]\\n\\t\"\n        \"ldr\tr5, [%[b], #192]\\n\\t\"\n        \"ldr\tr7, [%[b], #196]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #192]\\n\\t\"\n        \"str\tr6, [%[r], #196]\\n\\t\"\n        \"ldr\tr4, [%[a], #200]\\n\\t\"\n        \"ldr\tr6, [%[a], #204]\\n\\t\"\n        \"ldr\tr5, [%[b], #200]\\n\\t\"\n        \"ldr\tr7, [%[b], #204]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #200]\\n\\t\"\n        \"str\tr6, [%[r], #204]\\n\\t\"\n        \"ldr\tr4, [%[a], #208]\\n\\t\"\n        \"ldr\tr6, [%[a], #212]\\n\\t\"\n        \"ldr\tr5, [%[b], #208]\\n\\t\"\n        \"ldr\tr7, [%[b], #212]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #208]\\n\\t\"\n        \"str\tr6, [%[r], #212]\\n\\t\"\n        \"ldr\tr4, [%[a], #216]\\n\\t\"\n        \"ldr\tr6, [%[a], #220]\\n\\t\"\n        \"ldr\tr5, [%[b], #216]\\n\\t\"\n        \"ldr\tr7, [%[b], #220]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #216]\\n\\t\"\n        \"str\tr6, [%[r], #220]\\n\\t\"\n        \"ldr\tr4, [%[a], #224]\\n\\t\"\n        \"ldr\tr6, [%[a], #228]\\n\\t\"\n        \"ldr\tr5, [%[b], #224]\\n\\t\"\n        \"ldr\tr7, [%[b], #228]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #224]\\n\\t\"\n        \"str\tr6, [%[r], #228]\\n\\t\"\n        \"ldr\tr4, [%[a], #232]\\n\\t\"\n        \"ldr\tr6, [%[a], #236]\\n\\t\"\n        \"ldr\tr5, [%[b], #232]\\n\\t\"\n        \"ldr\tr7, [%[b], #236]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #232]\\n\\t\"\n        \"str\tr6, [%[r], #236]\\n\\t\"\n        \"ldr\tr4, [%[a], #240]\\n\\t\"\n        \"ldr\tr6, [%[a], #244]\\n\\t\"\n        \"ldr\tr5, [%[b], #240]\\n\\t\"\n        \"ldr\tr7, [%[b], #244]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #240]\\n\\t\"\n        \"str\tr6, [%[r], #244]\\n\\t\"\n        \"ldr\tr4, [%[a], #248]\\n\\t\"\n        \"ldr\tr6, [%[a], #252]\\n\\t\"\n        \"ldr\tr5, [%[b], #248]\\n\\t\"\n        \"ldr\tr7, [%[b], #252]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #248]\\n\\t\"\n        \"str\tr6, [%[r], #252]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r4\", \"r6\", \"r5\", \"r7\", \"r8\", \"r9\"\n    );\n#endif /* WOLFSSL_SP_SMALL */\n\n    return c;\n}\n\n/* Reduce the number back to 2048 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"# i = 0\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr10, [%[a], #0]\\n\\t\"\n        \"ldr\tr14, [%[a], #4]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mul\tr8, %[mp], r10\\n\\t\"\n        \"# a[i+0] += m[0] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #0]\\n\\t\"\n        \"ldr\tr9, [%[a], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr10, r10, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"# a[i+1] += m[1] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #4]\\n\\t\"\n        \"ldr\tr9, [%[a], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr10, r14, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr10, r10, r5\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+2] += m[2] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #8]\\n\\t\"\n        \"ldr\tr14, [%[a], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr14, r14, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr14, r14, r4\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+3] += m[3] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #12]\\n\\t\"\n        \"ldr\tr9, [%[a], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #12]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+4] += m[4] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #16]\\n\\t\"\n        \"ldr\tr9, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #16]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+5] += m[5] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #20]\\n\\t\"\n        \"ldr\tr9, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #20]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+6] += m[6] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #24]\\n\\t\"\n        \"ldr\tr9, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #24]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+7] += m[7] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #28]\\n\\t\"\n        \"ldr\tr9, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #28]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+8] += m[8] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #32]\\n\\t\"\n        \"ldr\tr9, [%[a], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #32]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+9] += m[9] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #36]\\n\\t\"\n        \"ldr\tr9, [%[a], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #36]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+10] += m[10] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #40]\\n\\t\"\n        \"ldr\tr9, [%[a], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #40]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+11] += m[11] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #44]\\n\\t\"\n        \"ldr\tr9, [%[a], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #44]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+12] += m[12] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #48]\\n\\t\"\n        \"ldr\tr9, [%[a], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #48]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+13] += m[13] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #52]\\n\\t\"\n        \"ldr\tr9, [%[a], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #52]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+14] += m[14] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #56]\\n\\t\"\n        \"ldr\tr9, [%[a], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #56]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+15] += m[15] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #60]\\n\\t\"\n        \"ldr\tr9, [%[a], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #60]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+16] += m[16] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #64]\\n\\t\"\n        \"ldr\tr9, [%[a], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #64]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+17] += m[17] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #68]\\n\\t\"\n        \"ldr\tr9, [%[a], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #68]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+18] += m[18] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #72]\\n\\t\"\n        \"ldr\tr9, [%[a], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #72]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+19] += m[19] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #76]\\n\\t\"\n        \"ldr\tr9, [%[a], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #76]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+20] += m[20] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #80]\\n\\t\"\n        \"ldr\tr9, [%[a], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #80]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+21] += m[21] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #84]\\n\\t\"\n        \"ldr\tr9, [%[a], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #84]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+22] += m[22] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #88]\\n\\t\"\n        \"ldr\tr9, [%[a], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #88]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+23] += m[23] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #92]\\n\\t\"\n        \"ldr\tr9, [%[a], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #92]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+24] += m[24] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #96]\\n\\t\"\n        \"ldr\tr9, [%[a], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #96]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+25] += m[25] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #100]\\n\\t\"\n        \"ldr\tr9, [%[a], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #100]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+26] += m[26] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #104]\\n\\t\"\n        \"ldr\tr9, [%[a], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #104]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+27] += m[27] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #108]\\n\\t\"\n        \"ldr\tr9, [%[a], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #108]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+28] += m[28] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #112]\\n\\t\"\n        \"ldr\tr9, [%[a], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #112]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+29] += m[29] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #116]\\n\\t\"\n        \"ldr\tr9, [%[a], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #116]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+30] += m[30] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #120]\\n\\t\"\n        \"ldr\tr9, [%[a], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #120]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+31] += m[31] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #124]\\n\\t\"\n        \"ldr\tr9, [%[a], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #124]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+32] += m[32] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #128]\\n\\t\"\n        \"ldr\tr9, [%[a], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #128]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+33] += m[33] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #132]\\n\\t\"\n        \"ldr\tr9, [%[a], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #132]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+34] += m[34] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #136]\\n\\t\"\n        \"ldr\tr9, [%[a], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #136]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+35] += m[35] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #140]\\n\\t\"\n        \"ldr\tr9, [%[a], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #140]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+36] += m[36] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #144]\\n\\t\"\n        \"ldr\tr9, [%[a], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #144]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+37] += m[37] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #148]\\n\\t\"\n        \"ldr\tr9, [%[a], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #148]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+38] += m[38] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #152]\\n\\t\"\n        \"ldr\tr9, [%[a], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #152]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+39] += m[39] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #156]\\n\\t\"\n        \"ldr\tr9, [%[a], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #156]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+40] += m[40] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #160]\\n\\t\"\n        \"ldr\tr9, [%[a], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #160]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+41] += m[41] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #164]\\n\\t\"\n        \"ldr\tr9, [%[a], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #164]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+42] += m[42] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #168]\\n\\t\"\n        \"ldr\tr9, [%[a], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #168]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+43] += m[43] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #172]\\n\\t\"\n        \"ldr\tr9, [%[a], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #172]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+44] += m[44] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #176]\\n\\t\"\n        \"ldr\tr9, [%[a], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #176]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+45] += m[45] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #180]\\n\\t\"\n        \"ldr\tr9, [%[a], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #180]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+46] += m[46] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #184]\\n\\t\"\n        \"ldr\tr9, [%[a], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #184]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+47] += m[47] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #188]\\n\\t\"\n        \"ldr\tr9, [%[a], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #188]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+48] += m[48] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #192]\\n\\t\"\n        \"ldr\tr9, [%[a], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #192]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+49] += m[49] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #196]\\n\\t\"\n        \"ldr\tr9, [%[a], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #196]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+50] += m[50] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #200]\\n\\t\"\n        \"ldr\tr9, [%[a], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #200]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+51] += m[51] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #204]\\n\\t\"\n        \"ldr\tr9, [%[a], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #204]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+52] += m[52] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #208]\\n\\t\"\n        \"ldr\tr9, [%[a], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #208]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+53] += m[53] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #212]\\n\\t\"\n        \"ldr\tr9, [%[a], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #212]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+54] += m[54] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #216]\\n\\t\"\n        \"ldr\tr9, [%[a], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #216]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+55] += m[55] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #220]\\n\\t\"\n        \"ldr\tr9, [%[a], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #220]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+56] += m[56] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #224]\\n\\t\"\n        \"ldr\tr9, [%[a], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #224]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+57] += m[57] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #228]\\n\\t\"\n        \"ldr\tr9, [%[a], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #228]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+58] += m[58] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #232]\\n\\t\"\n        \"ldr\tr9, [%[a], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #232]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+59] += m[59] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #236]\\n\\t\"\n        \"ldr\tr9, [%[a], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #236]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+60] += m[60] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #240]\\n\\t\"\n        \"ldr\tr9, [%[a], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #240]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+61] += m[61] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #244]\\n\\t\"\n        \"ldr\tr9, [%[a], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #244]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+62] += m[62] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #248]\\n\\t\"\n        \"ldr\tr9, [%[a], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #248]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+63] += m[63] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #252]\\n\\t\"\n        \"ldr   r9, [%[a], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr7, r7, %[ca]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"adc\t%[ca], %[ca], %[ca]\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[a], #256]\\n\\t\"\n        \"adcs\tr9, r9, r7\\n\\t\"\n        \"str\tr9, [%[a], #256]\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"add\tr12, r12, #4\\n\\t\"\n        \"cmp\tr12, #256\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr10, [%[a], #0]\\n\\t\"\n        \"str\tr14, [%[a], #4]\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    sp_2048_cond_sub_64(a - 64, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_64(r, a, b);\n    sp_2048_mont_reduce_64(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_64(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_64(r, a);\n    sp_2048_mont_reduce_64(r, m, mp);\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nstatic sp_digit div_2048_word_64(sp_digit d1, sp_digit d0, sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr5, %[div], #1\\n\\t\"\n        \"add\tr5, r5, #1\\n\\t\"\n        \"mov\tr6, %[d0]\\n\\t\"\n        \"mov\tr7, %[d1]\\n\\t\"\n        \"# Do top 32\\n\\t\"\n        \"subs\tr8, r5, r7\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        \"and\tr8, r8, r5\\n\\t\"\n        \"subs\tr7, r7, r8\\n\\t\"\n        \"# Next 30 bits\\n\\t\"\n        \"mov\tr4, #29\\n\\t\"\n        \"1:\\n\\t\"\n        \"movs\tr6, r6, lsl #1\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"subs\tr8, r5, r7\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        \"and\tr8, r8, r5\\n\\t\"\n        \"subs\tr7, r7, r8\\n\\t\"\n        \"subs\tr4, r4, #1\\n\\t\"\n        \"bpl\t1b\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"add\t%[r], %[r], #1\\n\\t\"\n        \"umull\tr4, r5, %[r], %[div]\\n\\t\"\n        \"subs\tr4, %[d0], r4\\n\\t\"\n        \"sbc\tr5, %[d1], r5\\n\\t\"\n        \"add\t%[r], %[r], r5\\n\\t\"\n        \"umull\tr4, r5, %[r], %[div]\\n\\t\"\n        \"subs\tr4, %[d0], r4\\n\\t\"\n        \"sbc\tr5, %[d1], r5\\n\\t\"\n        \"add\t%[r], %[r], r5\\n\\t\"\n        \"subs\tr8, %[div], r4\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_64(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<64; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic int32_t sp_2048_cmp_64(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = -1;\n    sp_digit one = 1;\n\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr3, #-1\\n\\t\"\n        \"mov\tr6, #252\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr4, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr4, r4, r3\\n\\t\"\n        \"and\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"subs\tr6, r6, #4\\n\\t\"\n        \"bcs\t1b\\n\\t\"\n        \"eor\t%[r], %[r], r3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr3, #-1\\n\\t\"\n        \"ldr\t\tr4, [%[a], #252]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #252]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #248]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #248]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #244]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #244]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #240]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #240]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #236]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #236]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #232]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #232]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #228]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #228]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #224]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #224]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #220]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #220]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #216]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #216]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #212]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #212]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #208]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #208]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #204]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #204]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #200]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #200]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #196]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #196]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #192]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #192]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #188]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #188]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #184]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #184]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #180]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #180]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #176]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #176]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #172]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #172]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #168]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #168]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #164]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #164]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #160]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #160]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #156]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #156]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #152]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #152]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #148]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #148]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #144]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #144]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #140]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #140]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #136]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #136]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #132]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #132]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #128]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #128]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #124]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #120]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #116]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #112]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #108]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #104]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #100]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #96]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #92]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #88]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #84]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #80]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #76]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #72]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #68]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #64]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #60]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #56]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #52]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #48]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #44]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #40]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #36]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #32]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #28]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #24]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #20]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #16]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #12]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #8]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #4]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #0]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"eor\t%[r], %[r], r3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n#endif\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_64(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[128], t2[65];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n\n    div = d[63];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 64);\n    for (i=63; i>=0; i--) {\n        r1 = div_2048_word_64(t1[64 + i], t1[64 + i - 1], div);\n\n        sp_2048_mul_d_64(t2, d, r1);\n        t1[64 + i] += sp_2048_sub_in_place_64(&t1[i], t2);\n        t1[64 + i] -= t2[64];\n        sp_2048_mask_64(t2, d, t1[64 + i]);\n        t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], t2);\n        sp_2048_mask_64(t2, d, t1[64 + i]);\n        t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_2048_cmp_64(t1, d) >= 0;\n    sp_2048_cond_sub_64(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_64(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_64(a, m, NULL, r);\n}\n\n#endif /* WOLFSSL_RSA_PUBLIC_ONLY */\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_64_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[128], t2[65];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n\n    div = d[63];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 64);\n    for (i=63; i>=0; i--) {\n        r1 = div_2048_word_64(t1[64 + i], t1[64 + i - 1], div);\n\n        sp_2048_mul_d_64(t2, d, r1);\n        t1[64 + i] += sp_2048_sub_in_place_64(&t1[i], t2);\n        t1[64 + i] -= t2[64];\n        if (t1[64 + i] != 0) {\n            t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], d);\n            if (t1[64 + i] != 0)\n                t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_2048_cmp_64(t1, d) >= 0;\n    sp_2048_cond_sub_64(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_64_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_64_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][128];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 128, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 128;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_64(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 64U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_64(t[1] + 64, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_64(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 64, a, sizeof(sp_digit) * 64);\n            err = sp_2048_mod_64(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_64(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_64(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_64(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_64(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_64(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_64(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_64(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_64(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_64(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_64(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_64(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_64(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_64(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_64(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 64);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n\n            sp_2048_mont_mul_64(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);\n        sp_2048_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_64(r, m) >= 0);\n        sp_2048_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][128];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 128, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 128;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_64(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 64U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_64(t[1] + 64, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_64(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 64, a, sizeof(sp_digit) * 64);\n            err = sp_2048_mod_64(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_64(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_64(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_64(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_64(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_64(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_64(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_64(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_64(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_64(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_64(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_64(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_64(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_64(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_64(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_64(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_64(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_64(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_64(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_64(t[20], t[10], m, mp);\n        sp_2048_mont_mul_64(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_64(t[22], t[11], m, mp);\n        sp_2048_mont_mul_64(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_64(t[24], t[12], m, mp);\n        sp_2048_mont_mul_64(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_64(t[26], t[13], m, mp);\n        sp_2048_mont_mul_64(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_64(t[28], t[14], m, mp);\n        sp_2048_mont_mul_64(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_64(t[30], t[15], m, mp);\n        sp_2048_mont_mul_64(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 64);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n\n            sp_2048_mont_mul_64(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);\n        sp_2048_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_64(r, m) >= 0);\n        sp_2048_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[128], md[64], rd[128];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1];\n    int err = MP_OKAY;\n\n    if (*outLen < 256)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 32 || inLen > 256 ||\n                                                     mp_count_bits(mm) != 2048))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 64 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 64 * 2;\n        m = r + 64 * 2;\n        ah = a + 64;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 64;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(ah, 64, in, inLen);\n#if DIGIT_BIT >= 32\n        e[0] = em->dp[0];\n#else\n        e[0] = em->dp[0];\n        if (em->used > 1)\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e[0] == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(m, 64, mm);\n\n        if (e[0] == 0x3) {\n            if (err == MP_OKAY) {\n                sp_2048_sqr_64(r, ah);\n                err = sp_2048_mod_64_cond(r, r, m);\n            }\n            if (err == MP_OKAY) {\n                sp_2048_mul_64(r, ah, r);\n                err = sp_2048_mod_64_cond(r, r, m);\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_2048_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 64);\n            err = sp_2048_mod_64_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=31; i>=0; i--)\n                    if (e[0] >> i)\n                        break;\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 64);\n                for (i--; i>=0; i--) {\n                    sp_2048_mont_sqr_64(r, r, m, mp);\n                    if (((e[0] >> i) & 1) == 1)\n                        sp_2048_mont_mul_64(r, r, a, m, mp);\n                }\n                XMEMSET(&r[64], 0, sizeof(sp_digit) * 64);\n                sp_2048_mont_reduce_64(r, m, mp);\n\n                for (i = 63; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_2048_sub_in_place_64(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[64 * 2];\n    sp_digit pd[32], qd[32], dpd[32];\n    sp_digit tmpad[64], tmpbd[64];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 256)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 256 || mp_count_bits(mm) != 2048))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 64 * 2;\n        q = p + 32;\n        qi = dq = dp = q + 32;\n        tmpa = qi + 32;\n        tmpb = tmpa + 64;\n\n        tmp = t;\n        r = tmp + 64;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 64;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(a, 64, in, inLen);\n        sp_2048_from_mp(p, 32, pm);\n        sp_2048_from_mp(q, 32, qm);\n        sp_2048_from_mp(dp, 32, dpm);\n\n        err = sp_2048_mod_exp_32(tmpa, a, dp, 1024, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(dq, 32, dqm);\n        err = sp_2048_mod_exp_32(tmpb, a, dq, 1024, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_2048_sub_in_place_32(tmpa, tmpb);\n        sp_2048_mask_32(tmp, p, c);\n        sp_2048_add_32(tmpa, tmpa, tmp);\n\n        sp_2048_from_mp(qi, 32, qim);\n        sp_2048_mul_32(tmpa, tmpa, qi);\n        err = sp_2048_mod_32(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mul_32(tmpa, q, tmpa);\n        XMEMSET(&tmpb[32], 0, sizeof(sp_digit) * 32);\n        sp_2048_add_64(r, tmpb, tmpa);\n\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 32 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_2048_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 32\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 64);\n        r->used = 64;\n        mp_clamp(r);\n#elif DIGIT_BIT < 32\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 64; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 32) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 32 - s;\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 64; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 32 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 32 - s;\n            }\n            else {\n                s += 32;\n            }\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[128], e[64], m[64];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 64, base);\n        sp_2048_from_mp(e, 64, exp);\n        sp_2048_from_mp(m, 64, mod);\n\n        err = sp_2048_mod_exp_64(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_2048_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_2048\nstatic void sp_2048_lshift_64(sp_digit* r, sp_digit* a, byte n)\n{\n    __asm__ __volatile__ (\n        \"mov\tr6, #31\\n\\t\"\n        \"sub\tr6, r6, %[n]\\n\\t\"\n        \"ldr\tr3, [%[a], #252]\\n\\t\"\n        \"lsr\tr4, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr4, r4, r6\\n\\t\"\n        \"ldr\tr2, [%[a], #248]\\n\\t\"\n        \"str\tr4, [%[r], #256]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #244]\\n\\t\"\n        \"str\tr3, [%[r], #252]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #240]\\n\\t\"\n        \"str\tr2, [%[r], #248]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #236]\\n\\t\"\n        \"str\tr4, [%[r], #244]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #232]\\n\\t\"\n        \"str\tr3, [%[r], #240]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #228]\\n\\t\"\n        \"str\tr2, [%[r], #236]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #224]\\n\\t\"\n        \"str\tr4, [%[r], #232]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #220]\\n\\t\"\n        \"str\tr3, [%[r], #228]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #216]\\n\\t\"\n        \"str\tr2, [%[r], #224]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #212]\\n\\t\"\n        \"str\tr4, [%[r], #220]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #208]\\n\\t\"\n        \"str\tr3, [%[r], #216]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #204]\\n\\t\"\n        \"str\tr2, [%[r], #212]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #200]\\n\\t\"\n        \"str\tr4, [%[r], #208]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #196]\\n\\t\"\n        \"str\tr3, [%[r], #204]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #192]\\n\\t\"\n        \"str\tr2, [%[r], #200]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #188]\\n\\t\"\n        \"str\tr4, [%[r], #196]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #184]\\n\\t\"\n        \"str\tr3, [%[r], #192]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #180]\\n\\t\"\n        \"str\tr2, [%[r], #188]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #176]\\n\\t\"\n        \"str\tr4, [%[r], #184]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #172]\\n\\t\"\n        \"str\tr3, [%[r], #180]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #168]\\n\\t\"\n        \"str\tr2, [%[r], #176]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #164]\\n\\t\"\n        \"str\tr4, [%[r], #172]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #160]\\n\\t\"\n        \"str\tr3, [%[r], #168]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #156]\\n\\t\"\n        \"str\tr2, [%[r], #164]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #152]\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #148]\\n\\t\"\n        \"str\tr3, [%[r], #156]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #144]\\n\\t\"\n        \"str\tr2, [%[r], #152]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #140]\\n\\t\"\n        \"str\tr4, [%[r], #148]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #136]\\n\\t\"\n        \"str\tr3, [%[r], #144]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #132]\\n\\t\"\n        \"str\tr2, [%[r], #140]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #128]\\n\\t\"\n        \"str\tr4, [%[r], #136]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"str\tr3, [%[r], #132]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #120]\\n\\t\"\n        \"str\tr2, [%[r], #128]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #116]\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"str\tr3, [%[r], #120]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #108]\\n\\t\"\n        \"str\tr2, [%[r], #116]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #104]\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"str\tr3, [%[r], #108]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #96]\\n\\t\"\n        \"str\tr2, [%[r], #104]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #92]\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"str\tr3, [%[r], #96]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #84]\\n\\t\"\n        \"str\tr2, [%[r], #92]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #80]\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"str\tr3, [%[r], #84]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #72]\\n\\t\"\n        \"str\tr2, [%[r], #80]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #68]\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"str\tr3, [%[r], #72]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #60]\\n\\t\"\n        \"str\tr2, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr2, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #44]\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr2, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr2, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #12]\\n\\t\"\n        \"str\tr2, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr2, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [n] \"r\" (n)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[128];\n    sp_digit td[65];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 193, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 128;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_64(norm, m);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        sp_2048_lshift_64(r, norm, y);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n\n            sp_2048_lshift_64(r, r, y);\n            sp_2048_mul_d_64(tmp, norm, r[64]);\n            r[64] = 0;\n            o = sp_2048_add_64(r, r, tmp);\n            sp_2048_cond_sub_64(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);\n        sp_2048_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_64(r, m) >= 0);\n        sp_2048_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* HAVE_FFDHE_2048 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 256 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[128], e[64], m[64];\n    sp_digit* r = b;\n    word32 i;\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 256) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 64, base);\n        sp_2048_from_bin(e, 64, exp, expLen);\n        sp_2048_from_mp(m, 64, mod);\n\n    #ifdef HAVE_FFDHE_2048\n        if (base->used == 1 && base->dp[0] == 2 && m[63] == (sp_digit)-1)\n            err = sp_2048_mod_exp_2_64(r, e, expLen * 8, m);\n        else\n    #endif\n            err = sp_2048_mod_exp_64(r, b, e, expLen * 8, m, 0);\n\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n        for (i=0; i<256 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[64], e[32], m[32];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1024) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 32, base);\n        sp_2048_from_mp(e, 32, exp);\n        sp_2048_from_mp(m, 32, mod);\n\n        err = sp_2048_mod_exp_32(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 32, 0, sizeof(*r) * 32U);\n        err = sp_2048_to_mp(r, res);\n        res->used = mod->used;\n        mp_clamp(res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_2048 */\n\n#ifndef WOLFSSL_SP_NO_3072\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 24U) {\n            r[j] &= 0xffffffff;\n            s = 32U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 32\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 32\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffff;\n        s = 32U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 32U) <= (word32)DIGIT_BIT) {\n            s += 32U;\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 32) {\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 32 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 384\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_3072_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 3072 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<96 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 32) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 32);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #48\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        \"#  A[0] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr3, r4, r8, r9\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [sp]\\n\\t\"\n        \"#  A[0] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #4]\\n\\t\"\n        \"#  A[0] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #8]\\n\\t\"\n        \"#  A[0] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #12]\\n\\t\"\n        \"#  A[0] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #16]\\n\\t\"\n        \"#  A[0] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #20]\\n\\t\"\n        \"#  A[0] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #24]\\n\\t\"\n        \"#  A[0] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #28]\\n\\t\"\n        \"#  A[0] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #32]\\n\\t\"\n        \"#  A[0] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #36]\\n\\t\"\n        \"#  A[0] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #40]\\n\\t\"\n        \"#  A[0] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #44]\\n\\t\"\n        \"#  A[1] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[2] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"#  A[2] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[3] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"#  A[3] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[4] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #56]\\n\\t\"\n        \"#  A[4] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[5] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"#  A[5] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[6] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"#  A[6] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[7] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #68]\\n\\t\"\n        \"#  A[7] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[8] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #72]\\n\\t\"\n        \"#  A[8] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[9] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"#  A[9] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[10] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #80]\\n\\t\"\n        \"#  A[10] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[11] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #84]\\n\\t\"\n        \"#  A[11] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"str\tr5, [%[r], #92]\\n\\t\"\n        \"ldr\tr3, [sp, #0]\\n\\t\"\n        \"ldr\tr4, [sp, #4]\\n\\t\"\n        \"ldr\tr5, [sp, #8]\\n\\t\"\n        \"ldr\tr6, [sp, #12]\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [sp, #16]\\n\\t\"\n        \"ldr\tr4, [sp, #20]\\n\\t\"\n        \"ldr\tr5, [sp, #24]\\n\\t\"\n        \"ldr\tr6, [sp, #28]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"str\tr5, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        \"ldr\tr3, [sp, #32]\\n\\t\"\n        \"ldr\tr4, [sp, #36]\\n\\t\"\n        \"ldr\tr5, [sp, #40]\\n\\t\"\n        \"ldr\tr6, [sp, #44]\\n\\t\"\n        \"str\tr3, [%[r], #32]\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"str\tr5, [%[r], #40]\\n\\t\"\n        \"str\tr6, [%[r], #44]\\n\\t\"\n        \"add\tsp, sp, #48\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_3072_sqr_12(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #48\\n\\t\"\n        \"mov\tr14, #0\\n\\t\"\n        \"#  A[0] * A[0]\\n\\t\"\n        \"ldr\tr10, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r3, r10, r10\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr8, [sp]\\n\\t\"\n        \"#  A[0] * A[1]\\n\\t\"\n        \"ldr\tr10, [%[a], #4]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [sp, #4]\\n\\t\"\n        \"#  A[0] * A[2]\\n\\t\"\n        \"ldr\tr10, [%[a], #8]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r14, r14\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"#  A[1] * A[1]\\n\\t\"\n        \"ldr\tr10, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"str\tr4, [sp, #8]\\n\\t\"\n        \"#  A[0] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r14, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"#  A[1] * A[2]\\n\\t\"\n        \"ldr\tr10, [%[a], #8]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"str\tr2, [sp, #12]\\n\\t\"\n        \"#  A[0] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[1] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[2] * A[2]\\n\\t\"\n        \"ldr\tr10, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [sp, #16]\\n\\t\"\n        \"#  A[0] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #20]\\n\\t\"\n        \"#  A[0] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #24]\\n\\t\"\n        \"#  A[0] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #28]\\n\\t\"\n        \"#  A[0] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #32]\\n\\t\"\n        \"#  A[0] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #36]\\n\\t\"\n        \"#  A[0] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #40]\\n\\t\"\n        \"#  A[0] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #44]\\n\\t\"\n        \"#  A[1] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[2] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #48]\\n\\t\"\n        \"#  A[2] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[3] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #52]\\n\\t\"\n        \"#  A[3] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[4] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"#  A[4] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[5] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #60]\\n\\t\"\n        \"#  A[5] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[6] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #64]\\n\\t\"\n        \"#  A[6] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[7] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"#  A[7] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r14, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"#  A[8] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"#  A[9] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"str\tr2, [%[r], #72]\\n\\t\"\n        \"#  A[8] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[9] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [%[r], #76]\\n\\t\"\n        \"#  A[9] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r14, r14\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"#  A[10] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"#  A[10] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r14, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"str\tr2, [%[r], #84]\\n\\t\"\n        \"#  A[11] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adc\tr4, r4, r9\\n\\t\"\n        \"str\tr3, [%[r], #88]\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr2, [sp, #0]\\n\\t\"\n        \"ldr\tr3, [sp, #4]\\n\\t\"\n        \"ldr\tr4, [sp, #8]\\n\\t\"\n        \"ldr\tr8, [sp, #12]\\n\\t\"\n        \"str\tr2, [%[r], #0]\\n\\t\"\n        \"str\tr3, [%[r], #4]\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"str\tr8, [%[r], #12]\\n\\t\"\n        \"ldr\tr2, [sp, #16]\\n\\t\"\n        \"ldr\tr3, [sp, #20]\\n\\t\"\n        \"ldr\tr4, [sp, #24]\\n\\t\"\n        \"ldr\tr8, [sp, #28]\\n\\t\"\n        \"str\tr2, [%[r], #16]\\n\\t\"\n        \"str\tr3, [%[r], #20]\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"str\tr8, [%[r], #28]\\n\\t\"\n        \"ldr\tr2, [sp, #32]\\n\\t\"\n        \"ldr\tr3, [sp, #36]\\n\\t\"\n        \"ldr\tr4, [sp, #40]\\n\\t\"\n        \"ldr\tr8, [sp, #44]\\n\\t\"\n        \"str\tr2, [%[r], #32]\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"str\tr8, [%[r], #44]\\n\\t\"\n        \"add\tsp, sp, #48\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r8\", \"r9\", \"r10\", \"r8\", \"r5\", \"r6\", \"r7\", \"r14\"\n    );\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_add_12(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[a], #4]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[b], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"ldr\tr10, [%[b], #8]\\n\\t\"\n        \"ldr\tr14, [%[b], #12]\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr5, [%[r], #4]\\n\\t\"\n        \"str\tr6, [%[r], #8]\\n\\t\"\n        \"str\tr7, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[a], #20]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[b], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"ldr\tr10, [%[b], #24]\\n\\t\"\n        \"ldr\tr14, [%[b], #28]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"str\tr6, [%[r], #24]\\n\\t\"\n        \"str\tr7, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[a], #36]\\n\\t\"\n        \"ldr\tr6, [%[a], #40]\\n\\t\"\n        \"ldr\tr7, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[b], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"ldr\tr10, [%[b], #40]\\n\\t\"\n        \"ldr\tr14, [%[b], #44]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr5, [%[r], #36]\\n\\t\"\n        \"str\tr6, [%[r], #40]\\n\\t\"\n        \"str\tr7, [%[r], #44]\\n\\t\"\n        \"adc\t%[c], r12, r12\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_sub_in_place_24(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr6, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"ldr\tr8, [%[b], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"subs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr6, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"ldr\tr8, [%[b], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr6, [%[b], #32]\\n\\t\"\n        \"ldr\tr7, [%[b], #36]\\n\\t\"\n        \"ldr\tr8, [%[b], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[a], #60]\\n\\t\"\n        \"ldr\tr6, [%[b], #48]\\n\\t\"\n        \"ldr\tr7, [%[b], #52]\\n\\t\"\n        \"ldr\tr8, [%[b], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr5, [%[a], #60]\\n\\t\"\n        \"ldr\tr2, [%[a], #64]\\n\\t\"\n        \"ldr\tr3, [%[a], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[a], #76]\\n\\t\"\n        \"ldr\tr6, [%[b], #64]\\n\\t\"\n        \"ldr\tr7, [%[b], #68]\\n\\t\"\n        \"ldr\tr8, [%[b], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #64]\\n\\t\"\n        \"str\tr3, [%[a], #68]\\n\\t\"\n        \"str\tr4, [%[a], #72]\\n\\t\"\n        \"str\tr5, [%[a], #76]\\n\\t\"\n        \"ldr\tr2, [%[a], #80]\\n\\t\"\n        \"ldr\tr3, [%[a], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[a], #92]\\n\\t\"\n        \"ldr\tr6, [%[b], #80]\\n\\t\"\n        \"ldr\tr7, [%[b], #84]\\n\\t\"\n        \"ldr\tr8, [%[b], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #80]\\n\\t\"\n        \"str\tr3, [%[a], #84]\\n\\t\"\n        \"str\tr4, [%[a], #88]\\n\\t\"\n        \"str\tr5, [%[a], #92]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_add_24(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[a], #4]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[b], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"ldr\tr10, [%[b], #8]\\n\\t\"\n        \"ldr\tr14, [%[b], #12]\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr5, [%[r], #4]\\n\\t\"\n        \"str\tr6, [%[r], #8]\\n\\t\"\n        \"str\tr7, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[a], #20]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[b], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"ldr\tr10, [%[b], #24]\\n\\t\"\n        \"ldr\tr14, [%[b], #28]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"str\tr6, [%[r], #24]\\n\\t\"\n        \"str\tr7, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[a], #36]\\n\\t\"\n        \"ldr\tr6, [%[a], #40]\\n\\t\"\n        \"ldr\tr7, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[b], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"ldr\tr10, [%[b], #40]\\n\\t\"\n        \"ldr\tr14, [%[b], #44]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr5, [%[r], #36]\\n\\t\"\n        \"str\tr6, [%[r], #40]\\n\\t\"\n        \"str\tr7, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[a], #52]\\n\\t\"\n        \"ldr\tr6, [%[a], #56]\\n\\t\"\n        \"ldr\tr7, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[b], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"ldr\tr10, [%[b], #56]\\n\\t\"\n        \"ldr\tr14, [%[b], #60]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"str\tr5, [%[r], #52]\\n\\t\"\n        \"str\tr6, [%[r], #56]\\n\\t\"\n        \"str\tr7, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[a], #68]\\n\\t\"\n        \"ldr\tr6, [%[a], #72]\\n\\t\"\n        \"ldr\tr7, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[b], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"ldr\tr10, [%[b], #72]\\n\\t\"\n        \"ldr\tr14, [%[b], #76]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"str\tr5, [%[r], #68]\\n\\t\"\n        \"str\tr6, [%[r], #72]\\n\\t\"\n        \"str\tr7, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[a], #84]\\n\\t\"\n        \"ldr\tr6, [%[a], #88]\\n\\t\"\n        \"ldr\tr7, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[b], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"ldr\tr10, [%[b], #88]\\n\\t\"\n        \"ldr\tr14, [%[b], #92]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"str\tr5, [%[r], #84]\\n\\t\"\n        \"str\tr6, [%[r], #88]\\n\\t\"\n        \"str\tr7, [%[r], #92]\\n\\t\"\n        \"adc\t%[c], r12, r12\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_12(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<12; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    r[0] = a[0] & m;\n    r[1] = a[1] & m;\n    r[2] = a[2] & m;\n    r[3] = a[3] & m;\n    r[4] = a[4] & m;\n    r[5] = a[5] & m;\n    r[6] = a[6] & m;\n    r[7] = a[7] & m;\n    r[8] = a[8] & m;\n    r[9] = a[9] & m;\n    r[10] = a[10] & m;\n    r[11] = a[11] & m;\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_24(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[24];\n    sp_digit a1[12];\n    sp_digit b1[12];\n    sp_digit z2[24];\n    sp_digit u, ca, cb;\n\n    ca = sp_3072_add_12(a1, a, &a[12]);\n    cb = sp_3072_add_12(b1, b, &b[12]);\n    u  = ca & cb;\n    sp_3072_mul_12(z1, a1, b1);\n    sp_3072_mul_12(z2, &a[12], &b[12]);\n    sp_3072_mul_12(z0, a, b);\n    sp_3072_mask_12(r + 24, a1, 0 - cb);\n    sp_3072_mask_12(b1, b1, 0 - ca);\n    u += sp_3072_add_12(r + 24, r + 24, b1);\n    u += sp_3072_sub_in_place_24(z1, z2);\n    u += sp_3072_sub_in_place_24(z1, z0);\n    u += sp_3072_add_24(r + 12, r + 12, z1);\n    r[36] = u;\n    XMEMSET(r + 36 + 1, 0, sizeof(sp_digit) * (12 - 1));\n    (void)sp_3072_add_24(r + 24, r + 24, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_24(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[24];\n    sp_digit z1[24];\n    sp_digit a1[12];\n    sp_digit u;\n\n    u = sp_3072_add_12(a1, a, &a[12]);\n    sp_3072_sqr_12(z1, a1);\n    sp_3072_sqr_12(z2, &a[12]);\n    sp_3072_sqr_12(z0, a);\n    sp_3072_mask_12(r + 24, a1, 0 - u);\n    u += sp_3072_add_12(r + 24, r + 24, r + 24);\n    u += sp_3072_sub_in_place_24(z1, z2);\n    u += sp_3072_sub_in_place_24(z1, z0);\n    u += sp_3072_add_24(r + 12, r + 12, z1);\n    r[36] = u;\n    XMEMSET(r + 36 + 1, 0, sizeof(sp_digit) * (12 - 1));\n    (void)sp_3072_add_24(r + 24, r + 24, z2);\n}\n\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_sub_in_place_48(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr6, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"ldr\tr8, [%[b], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"subs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr6, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"ldr\tr8, [%[b], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr6, [%[b], #32]\\n\\t\"\n        \"ldr\tr7, [%[b], #36]\\n\\t\"\n        \"ldr\tr8, [%[b], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[a], #60]\\n\\t\"\n        \"ldr\tr6, [%[b], #48]\\n\\t\"\n        \"ldr\tr7, [%[b], #52]\\n\\t\"\n        \"ldr\tr8, [%[b], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr5, [%[a], #60]\\n\\t\"\n        \"ldr\tr2, [%[a], #64]\\n\\t\"\n        \"ldr\tr3, [%[a], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[a], #76]\\n\\t\"\n        \"ldr\tr6, [%[b], #64]\\n\\t\"\n        \"ldr\tr7, [%[b], #68]\\n\\t\"\n        \"ldr\tr8, [%[b], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #64]\\n\\t\"\n        \"str\tr3, [%[a], #68]\\n\\t\"\n        \"str\tr4, [%[a], #72]\\n\\t\"\n        \"str\tr5, [%[a], #76]\\n\\t\"\n        \"ldr\tr2, [%[a], #80]\\n\\t\"\n        \"ldr\tr3, [%[a], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[a], #92]\\n\\t\"\n        \"ldr\tr6, [%[b], #80]\\n\\t\"\n        \"ldr\tr7, [%[b], #84]\\n\\t\"\n        \"ldr\tr8, [%[b], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #80]\\n\\t\"\n        \"str\tr3, [%[a], #84]\\n\\t\"\n        \"str\tr4, [%[a], #88]\\n\\t\"\n        \"str\tr5, [%[a], #92]\\n\\t\"\n        \"ldr\tr2, [%[a], #96]\\n\\t\"\n        \"ldr\tr3, [%[a], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[a], #108]\\n\\t\"\n        \"ldr\tr6, [%[b], #96]\\n\\t\"\n        \"ldr\tr7, [%[b], #100]\\n\\t\"\n        \"ldr\tr8, [%[b], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #96]\\n\\t\"\n        \"str\tr3, [%[a], #100]\\n\\t\"\n        \"str\tr4, [%[a], #104]\\n\\t\"\n        \"str\tr5, [%[a], #108]\\n\\t\"\n        \"ldr\tr2, [%[a], #112]\\n\\t\"\n        \"ldr\tr3, [%[a], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[a], #124]\\n\\t\"\n        \"ldr\tr6, [%[b], #112]\\n\\t\"\n        \"ldr\tr7, [%[b], #116]\\n\\t\"\n        \"ldr\tr8, [%[b], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #112]\\n\\t\"\n        \"str\tr3, [%[a], #116]\\n\\t\"\n        \"str\tr4, [%[a], #120]\\n\\t\"\n        \"str\tr5, [%[a], #124]\\n\\t\"\n        \"ldr\tr2, [%[a], #128]\\n\\t\"\n        \"ldr\tr3, [%[a], #132]\\n\\t\"\n        \"ldr\tr4, [%[a], #136]\\n\\t\"\n        \"ldr\tr5, [%[a], #140]\\n\\t\"\n        \"ldr\tr6, [%[b], #128]\\n\\t\"\n        \"ldr\tr7, [%[b], #132]\\n\\t\"\n        \"ldr\tr8, [%[b], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #128]\\n\\t\"\n        \"str\tr3, [%[a], #132]\\n\\t\"\n        \"str\tr4, [%[a], #136]\\n\\t\"\n        \"str\tr5, [%[a], #140]\\n\\t\"\n        \"ldr\tr2, [%[a], #144]\\n\\t\"\n        \"ldr\tr3, [%[a], #148]\\n\\t\"\n        \"ldr\tr4, [%[a], #152]\\n\\t\"\n        \"ldr\tr5, [%[a], #156]\\n\\t\"\n        \"ldr\tr6, [%[b], #144]\\n\\t\"\n        \"ldr\tr7, [%[b], #148]\\n\\t\"\n        \"ldr\tr8, [%[b], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #144]\\n\\t\"\n        \"str\tr3, [%[a], #148]\\n\\t\"\n        \"str\tr4, [%[a], #152]\\n\\t\"\n        \"str\tr5, [%[a], #156]\\n\\t\"\n        \"ldr\tr2, [%[a], #160]\\n\\t\"\n        \"ldr\tr3, [%[a], #164]\\n\\t\"\n        \"ldr\tr4, [%[a], #168]\\n\\t\"\n        \"ldr\tr5, [%[a], #172]\\n\\t\"\n        \"ldr\tr6, [%[b], #160]\\n\\t\"\n        \"ldr\tr7, [%[b], #164]\\n\\t\"\n        \"ldr\tr8, [%[b], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #160]\\n\\t\"\n        \"str\tr3, [%[a], #164]\\n\\t\"\n        \"str\tr4, [%[a], #168]\\n\\t\"\n        \"str\tr5, [%[a], #172]\\n\\t\"\n        \"ldr\tr2, [%[a], #176]\\n\\t\"\n        \"ldr\tr3, [%[a], #180]\\n\\t\"\n        \"ldr\tr4, [%[a], #184]\\n\\t\"\n        \"ldr\tr5, [%[a], #188]\\n\\t\"\n        \"ldr\tr6, [%[b], #176]\\n\\t\"\n        \"ldr\tr7, [%[b], #180]\\n\\t\"\n        \"ldr\tr8, [%[b], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #176]\\n\\t\"\n        \"str\tr3, [%[a], #180]\\n\\t\"\n        \"str\tr4, [%[a], #184]\\n\\t\"\n        \"str\tr5, [%[a], #188]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[a], #4]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[b], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"ldr\tr10, [%[b], #8]\\n\\t\"\n        \"ldr\tr14, [%[b], #12]\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr5, [%[r], #4]\\n\\t\"\n        \"str\tr6, [%[r], #8]\\n\\t\"\n        \"str\tr7, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[a], #20]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[b], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"ldr\tr10, [%[b], #24]\\n\\t\"\n        \"ldr\tr14, [%[b], #28]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"str\tr6, [%[r], #24]\\n\\t\"\n        \"str\tr7, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[a], #36]\\n\\t\"\n        \"ldr\tr6, [%[a], #40]\\n\\t\"\n        \"ldr\tr7, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[b], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"ldr\tr10, [%[b], #40]\\n\\t\"\n        \"ldr\tr14, [%[b], #44]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr5, [%[r], #36]\\n\\t\"\n        \"str\tr6, [%[r], #40]\\n\\t\"\n        \"str\tr7, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[a], #52]\\n\\t\"\n        \"ldr\tr6, [%[a], #56]\\n\\t\"\n        \"ldr\tr7, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[b], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"ldr\tr10, [%[b], #56]\\n\\t\"\n        \"ldr\tr14, [%[b], #60]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"str\tr5, [%[r], #52]\\n\\t\"\n        \"str\tr6, [%[r], #56]\\n\\t\"\n        \"str\tr7, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[a], #68]\\n\\t\"\n        \"ldr\tr6, [%[a], #72]\\n\\t\"\n        \"ldr\tr7, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[b], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"ldr\tr10, [%[b], #72]\\n\\t\"\n        \"ldr\tr14, [%[b], #76]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"str\tr5, [%[r], #68]\\n\\t\"\n        \"str\tr6, [%[r], #72]\\n\\t\"\n        \"str\tr7, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[a], #84]\\n\\t\"\n        \"ldr\tr6, [%[a], #88]\\n\\t\"\n        \"ldr\tr7, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[b], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"ldr\tr10, [%[b], #88]\\n\\t\"\n        \"ldr\tr14, [%[b], #92]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"str\tr5, [%[r], #84]\\n\\t\"\n        \"str\tr6, [%[r], #88]\\n\\t\"\n        \"str\tr7, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[a], #100]\\n\\t\"\n        \"ldr\tr6, [%[a], #104]\\n\\t\"\n        \"ldr\tr7, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[b], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"ldr\tr10, [%[b], #104]\\n\\t\"\n        \"ldr\tr14, [%[b], #108]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"str\tr5, [%[r], #100]\\n\\t\"\n        \"str\tr6, [%[r], #104]\\n\\t\"\n        \"str\tr7, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[a], #116]\\n\\t\"\n        \"ldr\tr6, [%[a], #120]\\n\\t\"\n        \"ldr\tr7, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[b], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"ldr\tr10, [%[b], #120]\\n\\t\"\n        \"ldr\tr14, [%[b], #124]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"str\tr5, [%[r], #116]\\n\\t\"\n        \"str\tr6, [%[r], #120]\\n\\t\"\n        \"str\tr7, [%[r], #124]\\n\\t\"\n        \"ldr\tr4, [%[a], #128]\\n\\t\"\n        \"ldr\tr5, [%[a], #132]\\n\\t\"\n        \"ldr\tr6, [%[a], #136]\\n\\t\"\n        \"ldr\tr7, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[b], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"ldr\tr10, [%[b], #136]\\n\\t\"\n        \"ldr\tr14, [%[b], #140]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #128]\\n\\t\"\n        \"str\tr5, [%[r], #132]\\n\\t\"\n        \"str\tr6, [%[r], #136]\\n\\t\"\n        \"str\tr7, [%[r], #140]\\n\\t\"\n        \"ldr\tr4, [%[a], #144]\\n\\t\"\n        \"ldr\tr5, [%[a], #148]\\n\\t\"\n        \"ldr\tr6, [%[a], #152]\\n\\t\"\n        \"ldr\tr7, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[b], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"ldr\tr10, [%[b], #152]\\n\\t\"\n        \"ldr\tr14, [%[b], #156]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #144]\\n\\t\"\n        \"str\tr5, [%[r], #148]\\n\\t\"\n        \"str\tr6, [%[r], #152]\\n\\t\"\n        \"str\tr7, [%[r], #156]\\n\\t\"\n        \"ldr\tr4, [%[a], #160]\\n\\t\"\n        \"ldr\tr5, [%[a], #164]\\n\\t\"\n        \"ldr\tr6, [%[a], #168]\\n\\t\"\n        \"ldr\tr7, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[b], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"ldr\tr10, [%[b], #168]\\n\\t\"\n        \"ldr\tr14, [%[b], #172]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"str\tr5, [%[r], #164]\\n\\t\"\n        \"str\tr6, [%[r], #168]\\n\\t\"\n        \"str\tr7, [%[r], #172]\\n\\t\"\n        \"ldr\tr4, [%[a], #176]\\n\\t\"\n        \"ldr\tr5, [%[a], #180]\\n\\t\"\n        \"ldr\tr6, [%[a], #184]\\n\\t\"\n        \"ldr\tr7, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[b], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"ldr\tr10, [%[b], #184]\\n\\t\"\n        \"ldr\tr14, [%[b], #188]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #176]\\n\\t\"\n        \"str\tr5, [%[r], #180]\\n\\t\"\n        \"str\tr6, [%[r], #184]\\n\\t\"\n        \"str\tr7, [%[r], #188]\\n\\t\"\n        \"adc\t%[c], r12, r12\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_24(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<24; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[48];\n    sp_digit a1[24];\n    sp_digit b1[24];\n    sp_digit z2[48];\n    sp_digit u, ca, cb;\n\n    ca = sp_3072_add_24(a1, a, &a[24]);\n    cb = sp_3072_add_24(b1, b, &b[24]);\n    u  = ca & cb;\n    sp_3072_mul_24(z1, a1, b1);\n    sp_3072_mul_24(z2, &a[24], &b[24]);\n    sp_3072_mul_24(z0, a, b);\n    sp_3072_mask_24(r + 48, a1, 0 - cb);\n    sp_3072_mask_24(b1, b1, 0 - ca);\n    u += sp_3072_add_24(r + 48, r + 48, b1);\n    u += sp_3072_sub_in_place_48(z1, z2);\n    u += sp_3072_sub_in_place_48(z1, z0);\n    u += sp_3072_add_48(r + 24, r + 24, z1);\n    r[72] = u;\n    XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));\n    (void)sp_3072_add_48(r + 48, r + 48, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[48];\n    sp_digit z1[48];\n    sp_digit a1[24];\n    sp_digit u;\n\n    u = sp_3072_add_24(a1, a, &a[24]);\n    sp_3072_sqr_24(z1, a1);\n    sp_3072_sqr_24(z2, &a[24]);\n    sp_3072_sqr_24(z0, a);\n    sp_3072_mask_24(r + 48, a1, 0 - u);\n    u += sp_3072_add_24(r + 48, r + 48, r + 48);\n    u += sp_3072_sub_in_place_48(z1, z2);\n    u += sp_3072_sub_in_place_48(z1, z0);\n    u += sp_3072_add_48(r + 24, r + 24, z1);\n    r[72] = u;\n    XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));\n    (void)sp_3072_add_48(r + 48, r + 48, z2);\n}\n\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_sub_in_place_96(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr6, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"ldr\tr8, [%[b], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"subs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr6, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"ldr\tr8, [%[b], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr6, [%[b], #32]\\n\\t\"\n        \"ldr\tr7, [%[b], #36]\\n\\t\"\n        \"ldr\tr8, [%[b], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[a], #60]\\n\\t\"\n        \"ldr\tr6, [%[b], #48]\\n\\t\"\n        \"ldr\tr7, [%[b], #52]\\n\\t\"\n        \"ldr\tr8, [%[b], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr5, [%[a], #60]\\n\\t\"\n        \"ldr\tr2, [%[a], #64]\\n\\t\"\n        \"ldr\tr3, [%[a], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[a], #76]\\n\\t\"\n        \"ldr\tr6, [%[b], #64]\\n\\t\"\n        \"ldr\tr7, [%[b], #68]\\n\\t\"\n        \"ldr\tr8, [%[b], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #64]\\n\\t\"\n        \"str\tr3, [%[a], #68]\\n\\t\"\n        \"str\tr4, [%[a], #72]\\n\\t\"\n        \"str\tr5, [%[a], #76]\\n\\t\"\n        \"ldr\tr2, [%[a], #80]\\n\\t\"\n        \"ldr\tr3, [%[a], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[a], #92]\\n\\t\"\n        \"ldr\tr6, [%[b], #80]\\n\\t\"\n        \"ldr\tr7, [%[b], #84]\\n\\t\"\n        \"ldr\tr8, [%[b], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #80]\\n\\t\"\n        \"str\tr3, [%[a], #84]\\n\\t\"\n        \"str\tr4, [%[a], #88]\\n\\t\"\n        \"str\tr5, [%[a], #92]\\n\\t\"\n        \"ldr\tr2, [%[a], #96]\\n\\t\"\n        \"ldr\tr3, [%[a], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[a], #108]\\n\\t\"\n        \"ldr\tr6, [%[b], #96]\\n\\t\"\n        \"ldr\tr7, [%[b], #100]\\n\\t\"\n        \"ldr\tr8, [%[b], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #96]\\n\\t\"\n        \"str\tr3, [%[a], #100]\\n\\t\"\n        \"str\tr4, [%[a], #104]\\n\\t\"\n        \"str\tr5, [%[a], #108]\\n\\t\"\n        \"ldr\tr2, [%[a], #112]\\n\\t\"\n        \"ldr\tr3, [%[a], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[a], #124]\\n\\t\"\n        \"ldr\tr6, [%[b], #112]\\n\\t\"\n        \"ldr\tr7, [%[b], #116]\\n\\t\"\n        \"ldr\tr8, [%[b], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #112]\\n\\t\"\n        \"str\tr3, [%[a], #116]\\n\\t\"\n        \"str\tr4, [%[a], #120]\\n\\t\"\n        \"str\tr5, [%[a], #124]\\n\\t\"\n        \"ldr\tr2, [%[a], #128]\\n\\t\"\n        \"ldr\tr3, [%[a], #132]\\n\\t\"\n        \"ldr\tr4, [%[a], #136]\\n\\t\"\n        \"ldr\tr5, [%[a], #140]\\n\\t\"\n        \"ldr\tr6, [%[b], #128]\\n\\t\"\n        \"ldr\tr7, [%[b], #132]\\n\\t\"\n        \"ldr\tr8, [%[b], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #128]\\n\\t\"\n        \"str\tr3, [%[a], #132]\\n\\t\"\n        \"str\tr4, [%[a], #136]\\n\\t\"\n        \"str\tr5, [%[a], #140]\\n\\t\"\n        \"ldr\tr2, [%[a], #144]\\n\\t\"\n        \"ldr\tr3, [%[a], #148]\\n\\t\"\n        \"ldr\tr4, [%[a], #152]\\n\\t\"\n        \"ldr\tr5, [%[a], #156]\\n\\t\"\n        \"ldr\tr6, [%[b], #144]\\n\\t\"\n        \"ldr\tr7, [%[b], #148]\\n\\t\"\n        \"ldr\tr8, [%[b], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #144]\\n\\t\"\n        \"str\tr3, [%[a], #148]\\n\\t\"\n        \"str\tr4, [%[a], #152]\\n\\t\"\n        \"str\tr5, [%[a], #156]\\n\\t\"\n        \"ldr\tr2, [%[a], #160]\\n\\t\"\n        \"ldr\tr3, [%[a], #164]\\n\\t\"\n        \"ldr\tr4, [%[a], #168]\\n\\t\"\n        \"ldr\tr5, [%[a], #172]\\n\\t\"\n        \"ldr\tr6, [%[b], #160]\\n\\t\"\n        \"ldr\tr7, [%[b], #164]\\n\\t\"\n        \"ldr\tr8, [%[b], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #160]\\n\\t\"\n        \"str\tr3, [%[a], #164]\\n\\t\"\n        \"str\tr4, [%[a], #168]\\n\\t\"\n        \"str\tr5, [%[a], #172]\\n\\t\"\n        \"ldr\tr2, [%[a], #176]\\n\\t\"\n        \"ldr\tr3, [%[a], #180]\\n\\t\"\n        \"ldr\tr4, [%[a], #184]\\n\\t\"\n        \"ldr\tr5, [%[a], #188]\\n\\t\"\n        \"ldr\tr6, [%[b], #176]\\n\\t\"\n        \"ldr\tr7, [%[b], #180]\\n\\t\"\n        \"ldr\tr8, [%[b], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #176]\\n\\t\"\n        \"str\tr3, [%[a], #180]\\n\\t\"\n        \"str\tr4, [%[a], #184]\\n\\t\"\n        \"str\tr5, [%[a], #188]\\n\\t\"\n        \"ldr\tr2, [%[a], #192]\\n\\t\"\n        \"ldr\tr3, [%[a], #196]\\n\\t\"\n        \"ldr\tr4, [%[a], #200]\\n\\t\"\n        \"ldr\tr5, [%[a], #204]\\n\\t\"\n        \"ldr\tr6, [%[b], #192]\\n\\t\"\n        \"ldr\tr7, [%[b], #196]\\n\\t\"\n        \"ldr\tr8, [%[b], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #192]\\n\\t\"\n        \"str\tr3, [%[a], #196]\\n\\t\"\n        \"str\tr4, [%[a], #200]\\n\\t\"\n        \"str\tr5, [%[a], #204]\\n\\t\"\n        \"ldr\tr2, [%[a], #208]\\n\\t\"\n        \"ldr\tr3, [%[a], #212]\\n\\t\"\n        \"ldr\tr4, [%[a], #216]\\n\\t\"\n        \"ldr\tr5, [%[a], #220]\\n\\t\"\n        \"ldr\tr6, [%[b], #208]\\n\\t\"\n        \"ldr\tr7, [%[b], #212]\\n\\t\"\n        \"ldr\tr8, [%[b], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #208]\\n\\t\"\n        \"str\tr3, [%[a], #212]\\n\\t\"\n        \"str\tr4, [%[a], #216]\\n\\t\"\n        \"str\tr5, [%[a], #220]\\n\\t\"\n        \"ldr\tr2, [%[a], #224]\\n\\t\"\n        \"ldr\tr3, [%[a], #228]\\n\\t\"\n        \"ldr\tr4, [%[a], #232]\\n\\t\"\n        \"ldr\tr5, [%[a], #236]\\n\\t\"\n        \"ldr\tr6, [%[b], #224]\\n\\t\"\n        \"ldr\tr7, [%[b], #228]\\n\\t\"\n        \"ldr\tr8, [%[b], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #224]\\n\\t\"\n        \"str\tr3, [%[a], #228]\\n\\t\"\n        \"str\tr4, [%[a], #232]\\n\\t\"\n        \"str\tr5, [%[a], #236]\\n\\t\"\n        \"ldr\tr2, [%[a], #240]\\n\\t\"\n        \"ldr\tr3, [%[a], #244]\\n\\t\"\n        \"ldr\tr4, [%[a], #248]\\n\\t\"\n        \"ldr\tr5, [%[a], #252]\\n\\t\"\n        \"ldr\tr6, [%[b], #240]\\n\\t\"\n        \"ldr\tr7, [%[b], #244]\\n\\t\"\n        \"ldr\tr8, [%[b], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #240]\\n\\t\"\n        \"str\tr3, [%[a], #244]\\n\\t\"\n        \"str\tr4, [%[a], #248]\\n\\t\"\n        \"str\tr5, [%[a], #252]\\n\\t\"\n        \"ldr\tr2, [%[a], #256]\\n\\t\"\n        \"ldr\tr3, [%[a], #260]\\n\\t\"\n        \"ldr\tr4, [%[a], #264]\\n\\t\"\n        \"ldr\tr5, [%[a], #268]\\n\\t\"\n        \"ldr\tr6, [%[b], #256]\\n\\t\"\n        \"ldr\tr7, [%[b], #260]\\n\\t\"\n        \"ldr\tr8, [%[b], #264]\\n\\t\"\n        \"ldr\tr9, [%[b], #268]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #256]\\n\\t\"\n        \"str\tr3, [%[a], #260]\\n\\t\"\n        \"str\tr4, [%[a], #264]\\n\\t\"\n        \"str\tr5, [%[a], #268]\\n\\t\"\n        \"ldr\tr2, [%[a], #272]\\n\\t\"\n        \"ldr\tr3, [%[a], #276]\\n\\t\"\n        \"ldr\tr4, [%[a], #280]\\n\\t\"\n        \"ldr\tr5, [%[a], #284]\\n\\t\"\n        \"ldr\tr6, [%[b], #272]\\n\\t\"\n        \"ldr\tr7, [%[b], #276]\\n\\t\"\n        \"ldr\tr8, [%[b], #280]\\n\\t\"\n        \"ldr\tr9, [%[b], #284]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #272]\\n\\t\"\n        \"str\tr3, [%[a], #276]\\n\\t\"\n        \"str\tr4, [%[a], #280]\\n\\t\"\n        \"str\tr5, [%[a], #284]\\n\\t\"\n        \"ldr\tr2, [%[a], #288]\\n\\t\"\n        \"ldr\tr3, [%[a], #292]\\n\\t\"\n        \"ldr\tr4, [%[a], #296]\\n\\t\"\n        \"ldr\tr5, [%[a], #300]\\n\\t\"\n        \"ldr\tr6, [%[b], #288]\\n\\t\"\n        \"ldr\tr7, [%[b], #292]\\n\\t\"\n        \"ldr\tr8, [%[b], #296]\\n\\t\"\n        \"ldr\tr9, [%[b], #300]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #288]\\n\\t\"\n        \"str\tr3, [%[a], #292]\\n\\t\"\n        \"str\tr4, [%[a], #296]\\n\\t\"\n        \"str\tr5, [%[a], #300]\\n\\t\"\n        \"ldr\tr2, [%[a], #304]\\n\\t\"\n        \"ldr\tr3, [%[a], #308]\\n\\t\"\n        \"ldr\tr4, [%[a], #312]\\n\\t\"\n        \"ldr\tr5, [%[a], #316]\\n\\t\"\n        \"ldr\tr6, [%[b], #304]\\n\\t\"\n        \"ldr\tr7, [%[b], #308]\\n\\t\"\n        \"ldr\tr8, [%[b], #312]\\n\\t\"\n        \"ldr\tr9, [%[b], #316]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #304]\\n\\t\"\n        \"str\tr3, [%[a], #308]\\n\\t\"\n        \"str\tr4, [%[a], #312]\\n\\t\"\n        \"str\tr5, [%[a], #316]\\n\\t\"\n        \"ldr\tr2, [%[a], #320]\\n\\t\"\n        \"ldr\tr3, [%[a], #324]\\n\\t\"\n        \"ldr\tr4, [%[a], #328]\\n\\t\"\n        \"ldr\tr5, [%[a], #332]\\n\\t\"\n        \"ldr\tr6, [%[b], #320]\\n\\t\"\n        \"ldr\tr7, [%[b], #324]\\n\\t\"\n        \"ldr\tr8, [%[b], #328]\\n\\t\"\n        \"ldr\tr9, [%[b], #332]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #320]\\n\\t\"\n        \"str\tr3, [%[a], #324]\\n\\t\"\n        \"str\tr4, [%[a], #328]\\n\\t\"\n        \"str\tr5, [%[a], #332]\\n\\t\"\n        \"ldr\tr2, [%[a], #336]\\n\\t\"\n        \"ldr\tr3, [%[a], #340]\\n\\t\"\n        \"ldr\tr4, [%[a], #344]\\n\\t\"\n        \"ldr\tr5, [%[a], #348]\\n\\t\"\n        \"ldr\tr6, [%[b], #336]\\n\\t\"\n        \"ldr\tr7, [%[b], #340]\\n\\t\"\n        \"ldr\tr8, [%[b], #344]\\n\\t\"\n        \"ldr\tr9, [%[b], #348]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #336]\\n\\t\"\n        \"str\tr3, [%[a], #340]\\n\\t\"\n        \"str\tr4, [%[a], #344]\\n\\t\"\n        \"str\tr5, [%[a], #348]\\n\\t\"\n        \"ldr\tr2, [%[a], #352]\\n\\t\"\n        \"ldr\tr3, [%[a], #356]\\n\\t\"\n        \"ldr\tr4, [%[a], #360]\\n\\t\"\n        \"ldr\tr5, [%[a], #364]\\n\\t\"\n        \"ldr\tr6, [%[b], #352]\\n\\t\"\n        \"ldr\tr7, [%[b], #356]\\n\\t\"\n        \"ldr\tr8, [%[b], #360]\\n\\t\"\n        \"ldr\tr9, [%[b], #364]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #352]\\n\\t\"\n        \"str\tr3, [%[a], #356]\\n\\t\"\n        \"str\tr4, [%[a], #360]\\n\\t\"\n        \"str\tr5, [%[a], #364]\\n\\t\"\n        \"ldr\tr2, [%[a], #368]\\n\\t\"\n        \"ldr\tr3, [%[a], #372]\\n\\t\"\n        \"ldr\tr4, [%[a], #376]\\n\\t\"\n        \"ldr\tr5, [%[a], #380]\\n\\t\"\n        \"ldr\tr6, [%[b], #368]\\n\\t\"\n        \"ldr\tr7, [%[b], #372]\\n\\t\"\n        \"ldr\tr8, [%[b], #376]\\n\\t\"\n        \"ldr\tr9, [%[b], #380]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #368]\\n\\t\"\n        \"str\tr3, [%[a], #372]\\n\\t\"\n        \"str\tr4, [%[a], #376]\\n\\t\"\n        \"str\tr5, [%[a], #380]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[a], #4]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[b], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"ldr\tr10, [%[b], #8]\\n\\t\"\n        \"ldr\tr14, [%[b], #12]\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr5, [%[r], #4]\\n\\t\"\n        \"str\tr6, [%[r], #8]\\n\\t\"\n        \"str\tr7, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[a], #20]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[b], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"ldr\tr10, [%[b], #24]\\n\\t\"\n        \"ldr\tr14, [%[b], #28]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"str\tr6, [%[r], #24]\\n\\t\"\n        \"str\tr7, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[a], #36]\\n\\t\"\n        \"ldr\tr6, [%[a], #40]\\n\\t\"\n        \"ldr\tr7, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[b], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"ldr\tr10, [%[b], #40]\\n\\t\"\n        \"ldr\tr14, [%[b], #44]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr5, [%[r], #36]\\n\\t\"\n        \"str\tr6, [%[r], #40]\\n\\t\"\n        \"str\tr7, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[a], #52]\\n\\t\"\n        \"ldr\tr6, [%[a], #56]\\n\\t\"\n        \"ldr\tr7, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[b], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"ldr\tr10, [%[b], #56]\\n\\t\"\n        \"ldr\tr14, [%[b], #60]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"str\tr5, [%[r], #52]\\n\\t\"\n        \"str\tr6, [%[r], #56]\\n\\t\"\n        \"str\tr7, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[a], #68]\\n\\t\"\n        \"ldr\tr6, [%[a], #72]\\n\\t\"\n        \"ldr\tr7, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[b], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"ldr\tr10, [%[b], #72]\\n\\t\"\n        \"ldr\tr14, [%[b], #76]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"str\tr5, [%[r], #68]\\n\\t\"\n        \"str\tr6, [%[r], #72]\\n\\t\"\n        \"str\tr7, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[a], #84]\\n\\t\"\n        \"ldr\tr6, [%[a], #88]\\n\\t\"\n        \"ldr\tr7, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[b], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"ldr\tr10, [%[b], #88]\\n\\t\"\n        \"ldr\tr14, [%[b], #92]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"str\tr5, [%[r], #84]\\n\\t\"\n        \"str\tr6, [%[r], #88]\\n\\t\"\n        \"str\tr7, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[a], #100]\\n\\t\"\n        \"ldr\tr6, [%[a], #104]\\n\\t\"\n        \"ldr\tr7, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[b], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"ldr\tr10, [%[b], #104]\\n\\t\"\n        \"ldr\tr14, [%[b], #108]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"str\tr5, [%[r], #100]\\n\\t\"\n        \"str\tr6, [%[r], #104]\\n\\t\"\n        \"str\tr7, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[a], #116]\\n\\t\"\n        \"ldr\tr6, [%[a], #120]\\n\\t\"\n        \"ldr\tr7, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[b], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"ldr\tr10, [%[b], #120]\\n\\t\"\n        \"ldr\tr14, [%[b], #124]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"str\tr5, [%[r], #116]\\n\\t\"\n        \"str\tr6, [%[r], #120]\\n\\t\"\n        \"str\tr7, [%[r], #124]\\n\\t\"\n        \"ldr\tr4, [%[a], #128]\\n\\t\"\n        \"ldr\tr5, [%[a], #132]\\n\\t\"\n        \"ldr\tr6, [%[a], #136]\\n\\t\"\n        \"ldr\tr7, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[b], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"ldr\tr10, [%[b], #136]\\n\\t\"\n        \"ldr\tr14, [%[b], #140]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #128]\\n\\t\"\n        \"str\tr5, [%[r], #132]\\n\\t\"\n        \"str\tr6, [%[r], #136]\\n\\t\"\n        \"str\tr7, [%[r], #140]\\n\\t\"\n        \"ldr\tr4, [%[a], #144]\\n\\t\"\n        \"ldr\tr5, [%[a], #148]\\n\\t\"\n        \"ldr\tr6, [%[a], #152]\\n\\t\"\n        \"ldr\tr7, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[b], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"ldr\tr10, [%[b], #152]\\n\\t\"\n        \"ldr\tr14, [%[b], #156]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #144]\\n\\t\"\n        \"str\tr5, [%[r], #148]\\n\\t\"\n        \"str\tr6, [%[r], #152]\\n\\t\"\n        \"str\tr7, [%[r], #156]\\n\\t\"\n        \"ldr\tr4, [%[a], #160]\\n\\t\"\n        \"ldr\tr5, [%[a], #164]\\n\\t\"\n        \"ldr\tr6, [%[a], #168]\\n\\t\"\n        \"ldr\tr7, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[b], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"ldr\tr10, [%[b], #168]\\n\\t\"\n        \"ldr\tr14, [%[b], #172]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"str\tr5, [%[r], #164]\\n\\t\"\n        \"str\tr6, [%[r], #168]\\n\\t\"\n        \"str\tr7, [%[r], #172]\\n\\t\"\n        \"ldr\tr4, [%[a], #176]\\n\\t\"\n        \"ldr\tr5, [%[a], #180]\\n\\t\"\n        \"ldr\tr6, [%[a], #184]\\n\\t\"\n        \"ldr\tr7, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[b], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"ldr\tr10, [%[b], #184]\\n\\t\"\n        \"ldr\tr14, [%[b], #188]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #176]\\n\\t\"\n        \"str\tr5, [%[r], #180]\\n\\t\"\n        \"str\tr6, [%[r], #184]\\n\\t\"\n        \"str\tr7, [%[r], #188]\\n\\t\"\n        \"ldr\tr4, [%[a], #192]\\n\\t\"\n        \"ldr\tr5, [%[a], #196]\\n\\t\"\n        \"ldr\tr6, [%[a], #200]\\n\\t\"\n        \"ldr\tr7, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[b], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"ldr\tr10, [%[b], #200]\\n\\t\"\n        \"ldr\tr14, [%[b], #204]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #192]\\n\\t\"\n        \"str\tr5, [%[r], #196]\\n\\t\"\n        \"str\tr6, [%[r], #200]\\n\\t\"\n        \"str\tr7, [%[r], #204]\\n\\t\"\n        \"ldr\tr4, [%[a], #208]\\n\\t\"\n        \"ldr\tr5, [%[a], #212]\\n\\t\"\n        \"ldr\tr6, [%[a], #216]\\n\\t\"\n        \"ldr\tr7, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[b], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"ldr\tr10, [%[b], #216]\\n\\t\"\n        \"ldr\tr14, [%[b], #220]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #208]\\n\\t\"\n        \"str\tr5, [%[r], #212]\\n\\t\"\n        \"str\tr6, [%[r], #216]\\n\\t\"\n        \"str\tr7, [%[r], #220]\\n\\t\"\n        \"ldr\tr4, [%[a], #224]\\n\\t\"\n        \"ldr\tr5, [%[a], #228]\\n\\t\"\n        \"ldr\tr6, [%[a], #232]\\n\\t\"\n        \"ldr\tr7, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[b], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"ldr\tr10, [%[b], #232]\\n\\t\"\n        \"ldr\tr14, [%[b], #236]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #224]\\n\\t\"\n        \"str\tr5, [%[r], #228]\\n\\t\"\n        \"str\tr6, [%[r], #232]\\n\\t\"\n        \"str\tr7, [%[r], #236]\\n\\t\"\n        \"ldr\tr4, [%[a], #240]\\n\\t\"\n        \"ldr\tr5, [%[a], #244]\\n\\t\"\n        \"ldr\tr6, [%[a], #248]\\n\\t\"\n        \"ldr\tr7, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[b], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"ldr\tr10, [%[b], #248]\\n\\t\"\n        \"ldr\tr14, [%[b], #252]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #240]\\n\\t\"\n        \"str\tr5, [%[r], #244]\\n\\t\"\n        \"str\tr6, [%[r], #248]\\n\\t\"\n        \"str\tr7, [%[r], #252]\\n\\t\"\n        \"ldr\tr4, [%[a], #256]\\n\\t\"\n        \"ldr\tr5, [%[a], #260]\\n\\t\"\n        \"ldr\tr6, [%[a], #264]\\n\\t\"\n        \"ldr\tr7, [%[a], #268]\\n\\t\"\n        \"ldr\tr8, [%[b], #256]\\n\\t\"\n        \"ldr\tr9, [%[b], #260]\\n\\t\"\n        \"ldr\tr10, [%[b], #264]\\n\\t\"\n        \"ldr\tr14, [%[b], #268]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #256]\\n\\t\"\n        \"str\tr5, [%[r], #260]\\n\\t\"\n        \"str\tr6, [%[r], #264]\\n\\t\"\n        \"str\tr7, [%[r], #268]\\n\\t\"\n        \"ldr\tr4, [%[a], #272]\\n\\t\"\n        \"ldr\tr5, [%[a], #276]\\n\\t\"\n        \"ldr\tr6, [%[a], #280]\\n\\t\"\n        \"ldr\tr7, [%[a], #284]\\n\\t\"\n        \"ldr\tr8, [%[b], #272]\\n\\t\"\n        \"ldr\tr9, [%[b], #276]\\n\\t\"\n        \"ldr\tr10, [%[b], #280]\\n\\t\"\n        \"ldr\tr14, [%[b], #284]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #272]\\n\\t\"\n        \"str\tr5, [%[r], #276]\\n\\t\"\n        \"str\tr6, [%[r], #280]\\n\\t\"\n        \"str\tr7, [%[r], #284]\\n\\t\"\n        \"ldr\tr4, [%[a], #288]\\n\\t\"\n        \"ldr\tr5, [%[a], #292]\\n\\t\"\n        \"ldr\tr6, [%[a], #296]\\n\\t\"\n        \"ldr\tr7, [%[a], #300]\\n\\t\"\n        \"ldr\tr8, [%[b], #288]\\n\\t\"\n        \"ldr\tr9, [%[b], #292]\\n\\t\"\n        \"ldr\tr10, [%[b], #296]\\n\\t\"\n        \"ldr\tr14, [%[b], #300]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #288]\\n\\t\"\n        \"str\tr5, [%[r], #292]\\n\\t\"\n        \"str\tr6, [%[r], #296]\\n\\t\"\n        \"str\tr7, [%[r], #300]\\n\\t\"\n        \"ldr\tr4, [%[a], #304]\\n\\t\"\n        \"ldr\tr5, [%[a], #308]\\n\\t\"\n        \"ldr\tr6, [%[a], #312]\\n\\t\"\n        \"ldr\tr7, [%[a], #316]\\n\\t\"\n        \"ldr\tr8, [%[b], #304]\\n\\t\"\n        \"ldr\tr9, [%[b], #308]\\n\\t\"\n        \"ldr\tr10, [%[b], #312]\\n\\t\"\n        \"ldr\tr14, [%[b], #316]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #304]\\n\\t\"\n        \"str\tr5, [%[r], #308]\\n\\t\"\n        \"str\tr6, [%[r], #312]\\n\\t\"\n        \"str\tr7, [%[r], #316]\\n\\t\"\n        \"ldr\tr4, [%[a], #320]\\n\\t\"\n        \"ldr\tr5, [%[a], #324]\\n\\t\"\n        \"ldr\tr6, [%[a], #328]\\n\\t\"\n        \"ldr\tr7, [%[a], #332]\\n\\t\"\n        \"ldr\tr8, [%[b], #320]\\n\\t\"\n        \"ldr\tr9, [%[b], #324]\\n\\t\"\n        \"ldr\tr10, [%[b], #328]\\n\\t\"\n        \"ldr\tr14, [%[b], #332]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #320]\\n\\t\"\n        \"str\tr5, [%[r], #324]\\n\\t\"\n        \"str\tr6, [%[r], #328]\\n\\t\"\n        \"str\tr7, [%[r], #332]\\n\\t\"\n        \"ldr\tr4, [%[a], #336]\\n\\t\"\n        \"ldr\tr5, [%[a], #340]\\n\\t\"\n        \"ldr\tr6, [%[a], #344]\\n\\t\"\n        \"ldr\tr7, [%[a], #348]\\n\\t\"\n        \"ldr\tr8, [%[b], #336]\\n\\t\"\n        \"ldr\tr9, [%[b], #340]\\n\\t\"\n        \"ldr\tr10, [%[b], #344]\\n\\t\"\n        \"ldr\tr14, [%[b], #348]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #336]\\n\\t\"\n        \"str\tr5, [%[r], #340]\\n\\t\"\n        \"str\tr6, [%[r], #344]\\n\\t\"\n        \"str\tr7, [%[r], #348]\\n\\t\"\n        \"ldr\tr4, [%[a], #352]\\n\\t\"\n        \"ldr\tr5, [%[a], #356]\\n\\t\"\n        \"ldr\tr6, [%[a], #360]\\n\\t\"\n        \"ldr\tr7, [%[a], #364]\\n\\t\"\n        \"ldr\tr8, [%[b], #352]\\n\\t\"\n        \"ldr\tr9, [%[b], #356]\\n\\t\"\n        \"ldr\tr10, [%[b], #360]\\n\\t\"\n        \"ldr\tr14, [%[b], #364]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #352]\\n\\t\"\n        \"str\tr5, [%[r], #356]\\n\\t\"\n        \"str\tr6, [%[r], #360]\\n\\t\"\n        \"str\tr7, [%[r], #364]\\n\\t\"\n        \"ldr\tr4, [%[a], #368]\\n\\t\"\n        \"ldr\tr5, [%[a], #372]\\n\\t\"\n        \"ldr\tr6, [%[a], #376]\\n\\t\"\n        \"ldr\tr7, [%[a], #380]\\n\\t\"\n        \"ldr\tr8, [%[b], #368]\\n\\t\"\n        \"ldr\tr9, [%[b], #372]\\n\\t\"\n        \"ldr\tr10, [%[b], #376]\\n\\t\"\n        \"ldr\tr14, [%[b], #380]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #368]\\n\\t\"\n        \"str\tr5, [%[r], #372]\\n\\t\"\n        \"str\tr6, [%[r], #376]\\n\\t\"\n        \"str\tr7, [%[r], #380]\\n\\t\"\n        \"adc\t%[c], r12, r12\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_48(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<48; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 48; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_96(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[96];\n    sp_digit a1[48];\n    sp_digit b1[48];\n    sp_digit z2[96];\n    sp_digit u, ca, cb;\n\n    ca = sp_3072_add_48(a1, a, &a[48]);\n    cb = sp_3072_add_48(b1, b, &b[48]);\n    u  = ca & cb;\n    sp_3072_mul_48(z1, a1, b1);\n    sp_3072_mul_48(z2, &a[48], &b[48]);\n    sp_3072_mul_48(z0, a, b);\n    sp_3072_mask_48(r + 96, a1, 0 - cb);\n    sp_3072_mask_48(b1, b1, 0 - ca);\n    u += sp_3072_add_48(r + 96, r + 96, b1);\n    u += sp_3072_sub_in_place_96(z1, z2);\n    u += sp_3072_sub_in_place_96(z1, z0);\n    u += sp_3072_add_96(r + 48, r + 48, z1);\n    r[144] = u;\n    XMEMSET(r + 144 + 1, 0, sizeof(sp_digit) * (48 - 1));\n    (void)sp_3072_add_96(r + 96, r + 96, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_96(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[96];\n    sp_digit z1[96];\n    sp_digit a1[48];\n    sp_digit u;\n\n    u = sp_3072_add_48(a1, a, &a[48]);\n    sp_3072_sqr_48(z1, a1);\n    sp_3072_sqr_48(z2, &a[48]);\n    sp_3072_sqr_48(z0, a);\n    sp_3072_mask_48(r + 96, a1, 0 - u);\n    u += sp_3072_add_48(r + 96, r + 96, r + 96);\n    u += sp_3072_sub_in_place_96(z1, z2);\n    u += sp_3072_sub_in_place_96(z1, z0);\n    u += sp_3072_add_96(r + 48, r + 48, z1);\n    r[144] = u;\n    XMEMSET(r + 144 + 1, 0, sizeof(sp_digit) * (48 - 1));\n    (void)sp_3072_add_96(r + 96, r + 96, z2);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tr12, %[a], #384\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], #-1\\n\\t\"\n        \"ldr\tr4, [%[a]], #4\\n\\t\"\n        \"ldr\tr5, [%[a]], #4\\n\\t\"\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"ldr\tr7, [%[a]], #4\\n\\t\"\n        \"ldr\tr8, [%[b]], #4\\n\\t\"\n        \"ldr\tr9, [%[b]], #4\\n\\t\"\n        \"ldr\tr10, [%[b]], #4\\n\\t\"\n        \"ldr\tr14, [%[b]], #4\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r]], #4\\n\\t\"\n        \"str\tr5, [%[r]], #4\\n\\t\"\n        \"str\tr6, [%[r]], #4\\n\\t\"\n        \"str\tr7, [%[r]], #4\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"adc\t%[c], r4, #0\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_sub_in_place_96(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr14, #0\\n\\t\"\n        \"add\tr12, %[a], #384\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\t%[c], r14, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b]], #4\\n\\t\"\n        \"ldr\tr8, [%[b]], #4\\n\\t\"\n        \"ldr\tr9, [%[b]], #4\\n\\t\"\n        \"ldr\tr10, [%[b]], #4\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"sbcs\tr6, r6, r10\\n\\t\"\n        \"str\tr3, [%[a]], #4\\n\\t\"\n        \"str\tr4, [%[a]], #4\\n\\t\"\n        \"str\tr5, [%[a]], #4\\n\\t\"\n        \"str\tr6, [%[a]], #4\\n\\t\"\n        \"sbc\t%[c], r14, r14\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r12\", \"r14\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_3072_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #768\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tr3, r5, #380\\n\\t\"\n        \"it\tcc\\n\\t\"\n        \"movcc\tr3, #0\\n\\t\"\n        \"sub\tr4, r5, r3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"ldr\tr12, [%[b], r4]\\n\\t\"\n        \"umull\tr9, r10, r14, r12\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, #0\\n\\t\"\n        \"add\tr3, r3, #4\\n\\t\"\n        \"sub\tr4, r4, #4\\n\\t\"\n        \"cmp\tr3, #384\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\tr3, r5\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"mov\tr6, r7\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"add\tr5, r5, #4\\n\\t\"\n        \"cmp\tr5, #760\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [sp, #0]\\n\\t\"\n        \"ldr\tr7, [sp, #4]\\n\\t\"\n        \"ldr\tr8, [sp, #8]\\n\\t\"\n        \"ldr\tr3, [sp, #12]\\n\\t\"\n        \"str\tr6, [%[r], #0]\\n\\t\"\n        \"str\tr7, [%[r], #4]\\n\\t\"\n        \"str\tr8, [%[r], #8]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"add\tsp, sp, #16\\n\\t\"\n        \"add\t%[r], %[r], #16\\n\\t\"\n        \"subs\tr5, r5, #16\\n\\t\"\n        \"bgt\t4b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_3072_sqr_96(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #768\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tr3, r5, #380\\n\\t\"\n        \"it\tcc\\n\\t\"\n        \"movcc\tr3, r12\\n\\t\"\n        \"sub\tr4, r5, r3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr4, r3\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"ldr\tr9, [%[a], r4]\\n\\t\"\n        \"umull\tr9, r10, r14, r9\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"umull\tr9, r10, r14, r14\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\tr3, r3, #4\\n\\t\"\n        \"sub\tr4, r4, #4\\n\\t\"\n        \"cmp\tr3, #384\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\tr3, r4\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"cmp\tr3, r5\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"mov\tr6, r7\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"add\tr5, r5, #4\\n\\t\"\n        \"cmp\tr5, #760\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [sp, #0]\\n\\t\"\n        \"ldr\tr7, [sp, #4]\\n\\t\"\n        \"ldr\tr8, [sp, #8]\\n\\t\"\n        \"ldr\tr3, [sp, #12]\\n\\t\"\n        \"str\tr6, [%[r], #0]\\n\\t\"\n        \"str\tr7, [%[r], #4]\\n\\t\"\n        \"str\tr8, [%[r], #8]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"add\tsp, sp, #16\\n\\t\"\n        \"add\t%[r], %[r], #16\\n\\t\"\n        \"subs\tr5, r5, #16\\n\\t\"\n        \"bgt\t4b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r9\", \"r12\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_48(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n    int i;\n\n    for (i=0; i<48; i++) {\n        r[i] = a[i] & m;\n    }\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tr12, %[a], #192\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], #-1\\n\\t\"\n        \"ldr\tr4, [%[a]], #4\\n\\t\"\n        \"ldr\tr5, [%[a]], #4\\n\\t\"\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"ldr\tr7, [%[a]], #4\\n\\t\"\n        \"ldr\tr8, [%[b]], #4\\n\\t\"\n        \"ldr\tr9, [%[b]], #4\\n\\t\"\n        \"ldr\tr10, [%[b]], #4\\n\\t\"\n        \"ldr\tr14, [%[b]], #4\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r]], #4\\n\\t\"\n        \"str\tr5, [%[r]], #4\\n\\t\"\n        \"str\tr6, [%[r]], #4\\n\\t\"\n        \"str\tr7, [%[r]], #4\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"adc\t%[c], r4, #0\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_sub_in_place_48(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr14, #0\\n\\t\"\n        \"add\tr12, %[a], #192\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\t%[c], r14, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b]], #4\\n\\t\"\n        \"ldr\tr8, [%[b]], #4\\n\\t\"\n        \"ldr\tr9, [%[b]], #4\\n\\t\"\n        \"ldr\tr10, [%[b]], #4\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"sbcs\tr6, r6, r10\\n\\t\"\n        \"str\tr3, [%[a]], #4\\n\\t\"\n        \"str\tr4, [%[a]], #4\\n\\t\"\n        \"str\tr5, [%[a]], #4\\n\\t\"\n        \"str\tr6, [%[a]], #4\\n\\t\"\n        \"sbc\t%[c], r14, r14\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r12\", \"r14\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_3072_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #384\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tr3, r5, #188\\n\\t\"\n        \"it\tcc\\n\\t\"\n        \"movcc\tr3, #0\\n\\t\"\n        \"sub\tr4, r5, r3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"ldr\tr12, [%[b], r4]\\n\\t\"\n        \"umull\tr9, r10, r14, r12\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, #0\\n\\t\"\n        \"add\tr3, r3, #4\\n\\t\"\n        \"sub\tr4, r4, #4\\n\\t\"\n        \"cmp\tr3, #192\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\tr3, r5\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"mov\tr6, r7\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"add\tr5, r5, #4\\n\\t\"\n        \"cmp\tr5, #376\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [sp, #0]\\n\\t\"\n        \"ldr\tr7, [sp, #4]\\n\\t\"\n        \"ldr\tr8, [sp, #8]\\n\\t\"\n        \"ldr\tr3, [sp, #12]\\n\\t\"\n        \"str\tr6, [%[r], #0]\\n\\t\"\n        \"str\tr7, [%[r], #4]\\n\\t\"\n        \"str\tr8, [%[r], #8]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"add\tsp, sp, #16\\n\\t\"\n        \"add\t%[r], %[r], #16\\n\\t\"\n        \"subs\tr5, r5, #16\\n\\t\"\n        \"bgt\t4b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_3072_sqr_48(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #384\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tr3, r5, #188\\n\\t\"\n        \"it\tcc\\n\\t\"\n        \"movcc\tr3, r12\\n\\t\"\n        \"sub\tr4, r5, r3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr4, r3\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"ldr\tr9, [%[a], r4]\\n\\t\"\n        \"umull\tr9, r10, r14, r9\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"umull\tr9, r10, r14, r14\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\tr3, r3, #4\\n\\t\"\n        \"sub\tr4, r4, #4\\n\\t\"\n        \"cmp\tr3, #192\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\tr3, r4\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"cmp\tr3, r5\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"mov\tr6, r7\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"add\tr5, r5, #4\\n\\t\"\n        \"cmp\tr5, #376\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [sp, #0]\\n\\t\"\n        \"ldr\tr7, [sp, #4]\\n\\t\"\n        \"ldr\tr8, [sp, #8]\\n\\t\"\n        \"ldr\tr3, [sp, #12]\\n\\t\"\n        \"str\tr6, [%[r], #0]\\n\\t\"\n        \"str\tr7, [%[r], #4]\\n\\t\"\n        \"str\tr8, [%[r], #8]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"add\tsp, sp, #16\\n\\t\"\n        \"add\t%[r], %[r], #16\\n\\t\"\n        \"subs\tr5, r5, #16\\n\\t\"\n        \"bgt\t4b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r9\", \"r12\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nstatic void sp_3072_mul_d_96(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr10, #0\\n\\t\"\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tr8, [%[a]]\\n\\t\"\n        \"umull\tr5, r3, %[b], r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr5, [%[r]]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr9, #4\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr8, [%[a], r9]\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], r9]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr9, r9, #4\\n\\t\"\n        \"cmp\tr9, #384\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r], #384]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tr10, #0\\n\\t\"\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tr8, [%[a]]\\n\\t\"\n        \"umull\tr3, r4, %[b], r8\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"# A[1] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"# A[2] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"# A[3] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"# A[4] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"# A[5] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"# A[6] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"# A[7] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"# A[8] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #32]\\n\\t\"\n        \"# A[9] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"# A[10] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"# A[11] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #44]\\n\\t\"\n        \"# A[12] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"# A[13] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"# A[14] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #56]\\n\\t\"\n        \"# A[15] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"# A[16] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"# A[17] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #68]\\n\\t\"\n        \"# A[18] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #72]\\n\\t\"\n        \"# A[19] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"# A[20] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #80]\\n\\t\"\n        \"# A[21] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #84]\\n\\t\"\n        \"# A[22] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"# A[23] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #92]\\n\\t\"\n        \"# A[24] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #96]\\n\\t\"\n        \"# A[25] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"# A[26] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #104]\\n\\t\"\n        \"# A[27] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #108]\\n\\t\"\n        \"# A[28] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"# A[29] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #116]\\n\\t\"\n        \"# A[30] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #120]\\n\\t\"\n        \"# A[31] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"# A[32] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #128]\\n\\t\"\n        \"# A[33] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #132]\\n\\t\"\n        \"# A[34] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #136]\\n\\t\"\n        \"# A[35] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #140]\\n\\t\"\n        \"# A[36] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #144]\\n\\t\"\n        \"# A[37] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #148]\\n\\t\"\n        \"# A[38] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #152]\\n\\t\"\n        \"# A[39] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #156]\\n\\t\"\n        \"# A[40] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"# A[41] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #164]\\n\\t\"\n        \"# A[42] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #168]\\n\\t\"\n        \"# A[43] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #172]\\n\\t\"\n        \"# A[44] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #176]\\n\\t\"\n        \"# A[45] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #180]\\n\\t\"\n        \"# A[46] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #184]\\n\\t\"\n        \"# A[47] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #188]\\n\\t\"\n        \"# A[48] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #192]\\n\\t\"\n        \"# A[49] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #196]\\n\\t\"\n        \"# A[50] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #200]\\n\\t\"\n        \"# A[51] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #204]\\n\\t\"\n        \"# A[52] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #208]\\n\\t\"\n        \"# A[53] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #212]\\n\\t\"\n        \"# A[54] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #216]\\n\\t\"\n        \"# A[55] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #220]\\n\\t\"\n        \"# A[56] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #224]\\n\\t\"\n        \"# A[57] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #228]\\n\\t\"\n        \"# A[58] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #232]\\n\\t\"\n        \"# A[59] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #236]\\n\\t\"\n        \"# A[60] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #240]\\n\\t\"\n        \"# A[61] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #244]\\n\\t\"\n        \"# A[62] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #248]\\n\\t\"\n        \"# A[63] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #252]\\n\\t\"\n        \"# A[64] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #256]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #256]\\n\\t\"\n        \"# A[65] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #260]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #260]\\n\\t\"\n        \"# A[66] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #264]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #264]\\n\\t\"\n        \"# A[67] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #268]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #268]\\n\\t\"\n        \"# A[68] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #272]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #272]\\n\\t\"\n        \"# A[69] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #276]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #276]\\n\\t\"\n        \"# A[70] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #280]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #280]\\n\\t\"\n        \"# A[71] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #284]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #284]\\n\\t\"\n        \"# A[72] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #288]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #288]\\n\\t\"\n        \"# A[73] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #292]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #292]\\n\\t\"\n        \"# A[74] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #296]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #296]\\n\\t\"\n        \"# A[75] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #300]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #300]\\n\\t\"\n        \"# A[76] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #304]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #304]\\n\\t\"\n        \"# A[77] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #308]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #308]\\n\\t\"\n        \"# A[78] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #312]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #312]\\n\\t\"\n        \"# A[79] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #316]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #316]\\n\\t\"\n        \"# A[80] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #320]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #320]\\n\\t\"\n        \"# A[81] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #324]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #324]\\n\\t\"\n        \"# A[82] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #328]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #328]\\n\\t\"\n        \"# A[83] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #332]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #332]\\n\\t\"\n        \"# A[84] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #336]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #336]\\n\\t\"\n        \"# A[85] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #340]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #340]\\n\\t\"\n        \"# A[86] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #344]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #344]\\n\\t\"\n        \"# A[87] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #348]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #348]\\n\\t\"\n        \"# A[88] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #352]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #352]\\n\\t\"\n        \"# A[89] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #356]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #356]\\n\\t\"\n        \"# A[90] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #360]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #360]\\n\\t\"\n        \"# A[91] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #364]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #364]\\n\\t\"\n        \"# A[92] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #368]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #368]\\n\\t\"\n        \"# A[93] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #372]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #372]\\n\\t\"\n        \"# A[94] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #376]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #376]\\n\\t\"\n        \"# A[95] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #380]\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr5, [%[r], #380]\\n\\t\"\n        \"str\tr3, [%[r], #384]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n#endif\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_48(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 48);\n\n    /* r = 2^n mod m */\n    sp_3072_sub_in_place_48(r, m);\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        sp_digit m)\n{\n    sp_digit c = 0;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr9, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"subs\t%[c], r9, %[c]\\n\\t\"\n        \"ldr\tr4, [%[a], r8]\\n\\t\"\n        \"ldr\tr5, [%[b], r8]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        \"str\tr4, [%[r], r8]\\n\\t\"\n        \"add\tr8, r8, #4\\n\\t\"\n        \"cmp\tr8, #192\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r4\", \"r6\", \"r5\", \"r7\", \"r8\", \"r9\"\n    );\n#else\n    __asm__ __volatile__ (\n\n        \"mov\tr9, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr6, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr6, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr6, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr7, [%[b], #36]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr6, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr6, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr7, [%[b], #44]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"str\tr6, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr6, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr7, [%[b], #52]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"str\tr6, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr6, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr7, [%[b], #60]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"str\tr6, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr6, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr7, [%[b], #68]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"str\tr6, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr6, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr7, [%[b], #76]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"str\tr6, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr6, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr7, [%[b], #84]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"str\tr6, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr6, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr7, [%[b], #92]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"str\tr6, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr6, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr7, [%[b], #100]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"str\tr6, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr6, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr7, [%[b], #108]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"str\tr6, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr6, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr7, [%[b], #116]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"str\tr6, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr6, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr7, [%[b], #124]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"str\tr6, [%[r], #124]\\n\\t\"\n        \"ldr\tr4, [%[a], #128]\\n\\t\"\n        \"ldr\tr6, [%[a], #132]\\n\\t\"\n        \"ldr\tr5, [%[b], #128]\\n\\t\"\n        \"ldr\tr7, [%[b], #132]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #128]\\n\\t\"\n        \"str\tr6, [%[r], #132]\\n\\t\"\n        \"ldr\tr4, [%[a], #136]\\n\\t\"\n        \"ldr\tr6, [%[a], #140]\\n\\t\"\n        \"ldr\tr5, [%[b], #136]\\n\\t\"\n        \"ldr\tr7, [%[b], #140]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #136]\\n\\t\"\n        \"str\tr6, [%[r], #140]\\n\\t\"\n        \"ldr\tr4, [%[a], #144]\\n\\t\"\n        \"ldr\tr6, [%[a], #148]\\n\\t\"\n        \"ldr\tr5, [%[b], #144]\\n\\t\"\n        \"ldr\tr7, [%[b], #148]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #144]\\n\\t\"\n        \"str\tr6, [%[r], #148]\\n\\t\"\n        \"ldr\tr4, [%[a], #152]\\n\\t\"\n        \"ldr\tr6, [%[a], #156]\\n\\t\"\n        \"ldr\tr5, [%[b], #152]\\n\\t\"\n        \"ldr\tr7, [%[b], #156]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #152]\\n\\t\"\n        \"str\tr6, [%[r], #156]\\n\\t\"\n        \"ldr\tr4, [%[a], #160]\\n\\t\"\n        \"ldr\tr6, [%[a], #164]\\n\\t\"\n        \"ldr\tr5, [%[b], #160]\\n\\t\"\n        \"ldr\tr7, [%[b], #164]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"str\tr6, [%[r], #164]\\n\\t\"\n        \"ldr\tr4, [%[a], #168]\\n\\t\"\n        \"ldr\tr6, [%[a], #172]\\n\\t\"\n        \"ldr\tr5, [%[b], #168]\\n\\t\"\n        \"ldr\tr7, [%[b], #172]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #168]\\n\\t\"\n        \"str\tr6, [%[r], #172]\\n\\t\"\n        \"ldr\tr4, [%[a], #176]\\n\\t\"\n        \"ldr\tr6, [%[a], #180]\\n\\t\"\n        \"ldr\tr5, [%[b], #176]\\n\\t\"\n        \"ldr\tr7, [%[b], #180]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #176]\\n\\t\"\n        \"str\tr6, [%[r], #180]\\n\\t\"\n        \"ldr\tr4, [%[a], #184]\\n\\t\"\n        \"ldr\tr6, [%[a], #188]\\n\\t\"\n        \"ldr\tr5, [%[b], #184]\\n\\t\"\n        \"ldr\tr7, [%[b], #188]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #184]\\n\\t\"\n        \"str\tr6, [%[r], #188]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r4\", \"r6\", \"r5\", \"r7\", \"r8\", \"r9\"\n    );\n#endif /* WOLFSSL_SP_SMALL */\n\n    return c;\n}\n\n/* Reduce the number back to 3072 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"# i = 0\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr10, [%[a], #0]\\n\\t\"\n        \"ldr\tr14, [%[a], #4]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mul\tr8, %[mp], r10\\n\\t\"\n        \"# a[i+0] += m[0] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #0]\\n\\t\"\n        \"ldr\tr9, [%[a], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr10, r10, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"# a[i+1] += m[1] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #4]\\n\\t\"\n        \"ldr\tr9, [%[a], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr10, r14, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr10, r10, r5\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+2] += m[2] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #8]\\n\\t\"\n        \"ldr\tr14, [%[a], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr14, r14, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr14, r14, r4\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+3] += m[3] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #12]\\n\\t\"\n        \"ldr\tr9, [%[a], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #12]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+4] += m[4] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #16]\\n\\t\"\n        \"ldr\tr9, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #16]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+5] += m[5] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #20]\\n\\t\"\n        \"ldr\tr9, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #20]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+6] += m[6] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #24]\\n\\t\"\n        \"ldr\tr9, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #24]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+7] += m[7] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #28]\\n\\t\"\n        \"ldr\tr9, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #28]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+8] += m[8] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #32]\\n\\t\"\n        \"ldr\tr9, [%[a], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #32]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+9] += m[9] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #36]\\n\\t\"\n        \"ldr\tr9, [%[a], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #36]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+10] += m[10] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #40]\\n\\t\"\n        \"ldr\tr9, [%[a], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #40]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+11] += m[11] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #44]\\n\\t\"\n        \"ldr\tr9, [%[a], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #44]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+12] += m[12] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #48]\\n\\t\"\n        \"ldr\tr9, [%[a], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #48]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+13] += m[13] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #52]\\n\\t\"\n        \"ldr\tr9, [%[a], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #52]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+14] += m[14] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #56]\\n\\t\"\n        \"ldr\tr9, [%[a], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #56]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+15] += m[15] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #60]\\n\\t\"\n        \"ldr\tr9, [%[a], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #60]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+16] += m[16] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #64]\\n\\t\"\n        \"ldr\tr9, [%[a], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #64]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+17] += m[17] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #68]\\n\\t\"\n        \"ldr\tr9, [%[a], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #68]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+18] += m[18] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #72]\\n\\t\"\n        \"ldr\tr9, [%[a], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #72]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+19] += m[19] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #76]\\n\\t\"\n        \"ldr\tr9, [%[a], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #76]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+20] += m[20] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #80]\\n\\t\"\n        \"ldr\tr9, [%[a], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #80]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+21] += m[21] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #84]\\n\\t\"\n        \"ldr\tr9, [%[a], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #84]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+22] += m[22] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #88]\\n\\t\"\n        \"ldr\tr9, [%[a], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #88]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+23] += m[23] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #92]\\n\\t\"\n        \"ldr\tr9, [%[a], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #92]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+24] += m[24] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #96]\\n\\t\"\n        \"ldr\tr9, [%[a], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #96]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+25] += m[25] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #100]\\n\\t\"\n        \"ldr\tr9, [%[a], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #100]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+26] += m[26] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #104]\\n\\t\"\n        \"ldr\tr9, [%[a], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #104]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+27] += m[27] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #108]\\n\\t\"\n        \"ldr\tr9, [%[a], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #108]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+28] += m[28] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #112]\\n\\t\"\n        \"ldr\tr9, [%[a], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #112]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+29] += m[29] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #116]\\n\\t\"\n        \"ldr\tr9, [%[a], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #116]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+30] += m[30] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #120]\\n\\t\"\n        \"ldr\tr9, [%[a], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #120]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+31] += m[31] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #124]\\n\\t\"\n        \"ldr\tr9, [%[a], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #124]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+32] += m[32] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #128]\\n\\t\"\n        \"ldr\tr9, [%[a], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #128]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+33] += m[33] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #132]\\n\\t\"\n        \"ldr\tr9, [%[a], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #132]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+34] += m[34] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #136]\\n\\t\"\n        \"ldr\tr9, [%[a], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #136]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+35] += m[35] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #140]\\n\\t\"\n        \"ldr\tr9, [%[a], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #140]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+36] += m[36] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #144]\\n\\t\"\n        \"ldr\tr9, [%[a], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #144]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+37] += m[37] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #148]\\n\\t\"\n        \"ldr\tr9, [%[a], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #148]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+38] += m[38] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #152]\\n\\t\"\n        \"ldr\tr9, [%[a], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #152]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+39] += m[39] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #156]\\n\\t\"\n        \"ldr\tr9, [%[a], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #156]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+40] += m[40] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #160]\\n\\t\"\n        \"ldr\tr9, [%[a], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #160]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+41] += m[41] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #164]\\n\\t\"\n        \"ldr\tr9, [%[a], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #164]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+42] += m[42] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #168]\\n\\t\"\n        \"ldr\tr9, [%[a], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #168]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+43] += m[43] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #172]\\n\\t\"\n        \"ldr\tr9, [%[a], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #172]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+44] += m[44] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #176]\\n\\t\"\n        \"ldr\tr9, [%[a], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #176]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+45] += m[45] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #180]\\n\\t\"\n        \"ldr\tr9, [%[a], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #180]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+46] += m[46] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #184]\\n\\t\"\n        \"ldr\tr9, [%[a], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #184]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+47] += m[47] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #188]\\n\\t\"\n        \"ldr   r9, [%[a], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr7, r7, %[ca]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"adc\t%[ca], %[ca], %[ca]\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[a], #192]\\n\\t\"\n        \"adcs\tr9, r9, r7\\n\\t\"\n        \"str\tr9, [%[a], #192]\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"add\tr12, r12, #4\\n\\t\"\n        \"cmp\tr12, #192\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr10, [%[a], #0]\\n\\t\"\n        \"str\tr14, [%[a], #4]\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    sp_3072_cond_sub_48(a - 48, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_48(r, a, b);\n    sp_3072_mont_reduce_48(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_48(r, a);\n    sp_3072_mont_reduce_48(r, m, mp);\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nstatic void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr10, #0\\n\\t\"\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tr8, [%[a]]\\n\\t\"\n        \"umull\tr5, r3, %[b], r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr5, [%[r]]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr9, #4\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr8, [%[a], r9]\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], r9]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr9, r9, #4\\n\\t\"\n        \"cmp\tr9, #192\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r], #192]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tr10, #0\\n\\t\"\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tr8, [%[a]]\\n\\t\"\n        \"umull\tr3, r4, %[b], r8\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"# A[1] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"# A[2] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"# A[3] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"# A[4] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"# A[5] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"# A[6] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"# A[7] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"# A[8] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #32]\\n\\t\"\n        \"# A[9] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"# A[10] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"# A[11] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #44]\\n\\t\"\n        \"# A[12] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"# A[13] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"# A[14] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #56]\\n\\t\"\n        \"# A[15] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"# A[16] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"# A[17] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #68]\\n\\t\"\n        \"# A[18] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #72]\\n\\t\"\n        \"# A[19] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"# A[20] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #80]\\n\\t\"\n        \"# A[21] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #84]\\n\\t\"\n        \"# A[22] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"# A[23] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #92]\\n\\t\"\n        \"# A[24] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #96]\\n\\t\"\n        \"# A[25] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"# A[26] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #104]\\n\\t\"\n        \"# A[27] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #108]\\n\\t\"\n        \"# A[28] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"# A[29] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #116]\\n\\t\"\n        \"# A[30] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #120]\\n\\t\"\n        \"# A[31] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"# A[32] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #128]\\n\\t\"\n        \"# A[33] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #132]\\n\\t\"\n        \"# A[34] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #136]\\n\\t\"\n        \"# A[35] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #140]\\n\\t\"\n        \"# A[36] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #144]\\n\\t\"\n        \"# A[37] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #148]\\n\\t\"\n        \"# A[38] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #152]\\n\\t\"\n        \"# A[39] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #156]\\n\\t\"\n        \"# A[40] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"# A[41] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #164]\\n\\t\"\n        \"# A[42] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #168]\\n\\t\"\n        \"# A[43] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #172]\\n\\t\"\n        \"# A[44] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #176]\\n\\t\"\n        \"# A[45] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #180]\\n\\t\"\n        \"# A[46] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #184]\\n\\t\"\n        \"# A[47] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr5, [%[r], #188]\\n\\t\"\n        \"str\tr3, [%[r], #192]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n#endif\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nstatic sp_digit div_3072_word_48(sp_digit d1, sp_digit d0, sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr5, %[div], #1\\n\\t\"\n        \"add\tr5, r5, #1\\n\\t\"\n        \"mov\tr6, %[d0]\\n\\t\"\n        \"mov\tr7, %[d1]\\n\\t\"\n        \"# Do top 32\\n\\t\"\n        \"subs\tr8, r5, r7\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        \"and\tr8, r8, r5\\n\\t\"\n        \"subs\tr7, r7, r8\\n\\t\"\n        \"# Next 30 bits\\n\\t\"\n        \"mov\tr4, #29\\n\\t\"\n        \"1:\\n\\t\"\n        \"movs\tr6, r6, lsl #1\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"subs\tr8, r5, r7\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        \"and\tr8, r8, r5\\n\\t\"\n        \"subs\tr7, r7, r8\\n\\t\"\n        \"subs\tr4, r4, #1\\n\\t\"\n        \"bpl\t1b\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"add\t%[r], %[r], #1\\n\\t\"\n        \"umull\tr4, r5, %[r], %[div]\\n\\t\"\n        \"subs\tr4, %[d0], r4\\n\\t\"\n        \"sbc\tr5, %[d1], r5\\n\\t\"\n        \"add\t%[r], %[r], r5\\n\\t\"\n        \"umull\tr4, r5, %[r], %[div]\\n\\t\"\n        \"subs\tr4, %[d0], r4\\n\\t\"\n        \"sbc\tr5, %[d1], r5\\n\\t\"\n        \"add\t%[r], %[r], r5\\n\\t\"\n        \"subs\tr8, %[div], r4\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n    return r;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic int32_t sp_3072_cmp_48(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = -1;\n    sp_digit one = 1;\n\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr3, #-1\\n\\t\"\n        \"mov\tr6, #188\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr4, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr4, r4, r3\\n\\t\"\n        \"and\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"subs\tr6, r6, #4\\n\\t\"\n        \"bcs\t1b\\n\\t\"\n        \"eor\t%[r], %[r], r3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr3, #-1\\n\\t\"\n        \"ldr\t\tr4, [%[a], #188]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #188]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #184]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #184]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #180]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #180]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #176]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #176]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #172]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #172]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #168]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #168]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #164]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #164]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #160]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #160]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #156]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #156]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #152]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #152]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #148]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #148]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #144]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #144]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #140]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #140]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #136]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #136]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #132]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #132]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #128]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #128]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #124]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #120]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #116]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #112]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #108]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #104]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #100]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #96]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #92]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #88]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #84]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #80]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #76]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #72]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #68]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #64]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #60]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #56]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #52]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #48]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #44]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #40]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #36]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #32]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #28]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #24]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #20]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #16]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #12]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #8]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #4]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #0]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"eor\t%[r], %[r], r3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n#endif\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_48(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[96], t2[49];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n\n    div = d[47];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 48);\n    for (i=47; i>=0; i--) {\n        r1 = div_3072_word_48(t1[48 + i], t1[48 + i - 1], div);\n\n        sp_3072_mul_d_48(t2, d, r1);\n        t1[48 + i] += sp_3072_sub_in_place_48(&t1[i], t2);\n        t1[48 + i] -= t2[48];\n        sp_3072_mask_48(t2, d, t1[48 + i]);\n        t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], t2);\n        sp_3072_mask_48(t2, d, t1[48 + i]);\n        t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_3072_cmp_48(t1, d) >= 0;\n    sp_3072_cond_sub_48(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_48(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_48(a, m, NULL, r);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][96];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 96, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 96;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_48(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 48U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_48(t[1] + 48, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_48(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 48, a, sizeof(sp_digit) * 48);\n            err = sp_3072_mod_48(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_48(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_48(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_48(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_48(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_48(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_48(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_48(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_48(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_48(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_48(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_48(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_48(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_48(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_48(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 48);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n\n            sp_3072_mont_mul_48(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[48], 0, sizeof(sp_digit) * 48U);\n        sp_3072_mont_reduce_48(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_48(r, m) >= 0);\n        sp_3072_cond_sub_48(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][96];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 96, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 96;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_48(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 48U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_48(t[1] + 48, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_48(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 48, a, sizeof(sp_digit) * 48);\n            err = sp_3072_mod_48(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_48(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_48(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_48(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_48(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_48(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_48(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_48(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_48(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_48(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_48(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_48(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_48(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_48(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_48(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_48(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_48(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_48(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_48(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_48(t[20], t[10], m, mp);\n        sp_3072_mont_mul_48(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_48(t[22], t[11], m, mp);\n        sp_3072_mont_mul_48(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_48(t[24], t[12], m, mp);\n        sp_3072_mont_mul_48(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_48(t[26], t[13], m, mp);\n        sp_3072_mont_mul_48(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_48(t[28], t[14], m, mp);\n        sp_3072_mont_mul_48(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_48(t[30], t[15], m, mp);\n        sp_3072_mont_mul_48(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 48);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n\n            sp_3072_mont_mul_48(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[48], 0, sizeof(sp_digit) * 48U);\n        sp_3072_mont_reduce_48(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_48(r, m) >= 0);\n        sp_3072_cond_sub_48(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_96(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 96);\n\n    /* r = 2^n mod m */\n    sp_3072_sub_in_place_96(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        sp_digit m)\n{\n    sp_digit c = 0;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr9, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"subs\t%[c], r9, %[c]\\n\\t\"\n        \"ldr\tr4, [%[a], r8]\\n\\t\"\n        \"ldr\tr5, [%[b], r8]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        \"str\tr4, [%[r], r8]\\n\\t\"\n        \"add\tr8, r8, #4\\n\\t\"\n        \"cmp\tr8, #384\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r4\", \"r6\", \"r5\", \"r7\", \"r8\", \"r9\"\n    );\n#else\n    __asm__ __volatile__ (\n\n        \"mov\tr9, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr6, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr6, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr6, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr7, [%[b], #36]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr6, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr6, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr7, [%[b], #44]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"str\tr6, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr6, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr7, [%[b], #52]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"str\tr6, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr6, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr7, [%[b], #60]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"str\tr6, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr6, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr7, [%[b], #68]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"str\tr6, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr6, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr7, [%[b], #76]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"str\tr6, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr6, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr7, [%[b], #84]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"str\tr6, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr6, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr7, [%[b], #92]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"str\tr6, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr6, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr7, [%[b], #100]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"str\tr6, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr6, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr7, [%[b], #108]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"str\tr6, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr6, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr7, [%[b], #116]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"str\tr6, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr6, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr7, [%[b], #124]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"str\tr6, [%[r], #124]\\n\\t\"\n        \"ldr\tr4, [%[a], #128]\\n\\t\"\n        \"ldr\tr6, [%[a], #132]\\n\\t\"\n        \"ldr\tr5, [%[b], #128]\\n\\t\"\n        \"ldr\tr7, [%[b], #132]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #128]\\n\\t\"\n        \"str\tr6, [%[r], #132]\\n\\t\"\n        \"ldr\tr4, [%[a], #136]\\n\\t\"\n        \"ldr\tr6, [%[a], #140]\\n\\t\"\n        \"ldr\tr5, [%[b], #136]\\n\\t\"\n        \"ldr\tr7, [%[b], #140]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #136]\\n\\t\"\n        \"str\tr6, [%[r], #140]\\n\\t\"\n        \"ldr\tr4, [%[a], #144]\\n\\t\"\n        \"ldr\tr6, [%[a], #148]\\n\\t\"\n        \"ldr\tr5, [%[b], #144]\\n\\t\"\n        \"ldr\tr7, [%[b], #148]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #144]\\n\\t\"\n        \"str\tr6, [%[r], #148]\\n\\t\"\n        \"ldr\tr4, [%[a], #152]\\n\\t\"\n        \"ldr\tr6, [%[a], #156]\\n\\t\"\n        \"ldr\tr5, [%[b], #152]\\n\\t\"\n        \"ldr\tr7, [%[b], #156]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #152]\\n\\t\"\n        \"str\tr6, [%[r], #156]\\n\\t\"\n        \"ldr\tr4, [%[a], #160]\\n\\t\"\n        \"ldr\tr6, [%[a], #164]\\n\\t\"\n        \"ldr\tr5, [%[b], #160]\\n\\t\"\n        \"ldr\tr7, [%[b], #164]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"str\tr6, [%[r], #164]\\n\\t\"\n        \"ldr\tr4, [%[a], #168]\\n\\t\"\n        \"ldr\tr6, [%[a], #172]\\n\\t\"\n        \"ldr\tr5, [%[b], #168]\\n\\t\"\n        \"ldr\tr7, [%[b], #172]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #168]\\n\\t\"\n        \"str\tr6, [%[r], #172]\\n\\t\"\n        \"ldr\tr4, [%[a], #176]\\n\\t\"\n        \"ldr\tr6, [%[a], #180]\\n\\t\"\n        \"ldr\tr5, [%[b], #176]\\n\\t\"\n        \"ldr\tr7, [%[b], #180]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #176]\\n\\t\"\n        \"str\tr6, [%[r], #180]\\n\\t\"\n        \"ldr\tr4, [%[a], #184]\\n\\t\"\n        \"ldr\tr6, [%[a], #188]\\n\\t\"\n        \"ldr\tr5, [%[b], #184]\\n\\t\"\n        \"ldr\tr7, [%[b], #188]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #184]\\n\\t\"\n        \"str\tr6, [%[r], #188]\\n\\t\"\n        \"ldr\tr4, [%[a], #192]\\n\\t\"\n        \"ldr\tr6, [%[a], #196]\\n\\t\"\n        \"ldr\tr5, [%[b], #192]\\n\\t\"\n        \"ldr\tr7, [%[b], #196]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #192]\\n\\t\"\n        \"str\tr6, [%[r], #196]\\n\\t\"\n        \"ldr\tr4, [%[a], #200]\\n\\t\"\n        \"ldr\tr6, [%[a], #204]\\n\\t\"\n        \"ldr\tr5, [%[b], #200]\\n\\t\"\n        \"ldr\tr7, [%[b], #204]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #200]\\n\\t\"\n        \"str\tr6, [%[r], #204]\\n\\t\"\n        \"ldr\tr4, [%[a], #208]\\n\\t\"\n        \"ldr\tr6, [%[a], #212]\\n\\t\"\n        \"ldr\tr5, [%[b], #208]\\n\\t\"\n        \"ldr\tr7, [%[b], #212]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #208]\\n\\t\"\n        \"str\tr6, [%[r], #212]\\n\\t\"\n        \"ldr\tr4, [%[a], #216]\\n\\t\"\n        \"ldr\tr6, [%[a], #220]\\n\\t\"\n        \"ldr\tr5, [%[b], #216]\\n\\t\"\n        \"ldr\tr7, [%[b], #220]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #216]\\n\\t\"\n        \"str\tr6, [%[r], #220]\\n\\t\"\n        \"ldr\tr4, [%[a], #224]\\n\\t\"\n        \"ldr\tr6, [%[a], #228]\\n\\t\"\n        \"ldr\tr5, [%[b], #224]\\n\\t\"\n        \"ldr\tr7, [%[b], #228]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #224]\\n\\t\"\n        \"str\tr6, [%[r], #228]\\n\\t\"\n        \"ldr\tr4, [%[a], #232]\\n\\t\"\n        \"ldr\tr6, [%[a], #236]\\n\\t\"\n        \"ldr\tr5, [%[b], #232]\\n\\t\"\n        \"ldr\tr7, [%[b], #236]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #232]\\n\\t\"\n        \"str\tr6, [%[r], #236]\\n\\t\"\n        \"ldr\tr4, [%[a], #240]\\n\\t\"\n        \"ldr\tr6, [%[a], #244]\\n\\t\"\n        \"ldr\tr5, [%[b], #240]\\n\\t\"\n        \"ldr\tr7, [%[b], #244]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #240]\\n\\t\"\n        \"str\tr6, [%[r], #244]\\n\\t\"\n        \"ldr\tr4, [%[a], #248]\\n\\t\"\n        \"ldr\tr6, [%[a], #252]\\n\\t\"\n        \"ldr\tr5, [%[b], #248]\\n\\t\"\n        \"ldr\tr7, [%[b], #252]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #248]\\n\\t\"\n        \"str\tr6, [%[r], #252]\\n\\t\"\n        \"ldr\tr4, [%[a], #256]\\n\\t\"\n        \"ldr\tr6, [%[a], #260]\\n\\t\"\n        \"ldr\tr5, [%[b], #256]\\n\\t\"\n        \"ldr\tr7, [%[b], #260]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #256]\\n\\t\"\n        \"str\tr6, [%[r], #260]\\n\\t\"\n        \"ldr\tr4, [%[a], #264]\\n\\t\"\n        \"ldr\tr6, [%[a], #268]\\n\\t\"\n        \"ldr\tr5, [%[b], #264]\\n\\t\"\n        \"ldr\tr7, [%[b], #268]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #264]\\n\\t\"\n        \"str\tr6, [%[r], #268]\\n\\t\"\n        \"ldr\tr4, [%[a], #272]\\n\\t\"\n        \"ldr\tr6, [%[a], #276]\\n\\t\"\n        \"ldr\tr5, [%[b], #272]\\n\\t\"\n        \"ldr\tr7, [%[b], #276]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #272]\\n\\t\"\n        \"str\tr6, [%[r], #276]\\n\\t\"\n        \"ldr\tr4, [%[a], #280]\\n\\t\"\n        \"ldr\tr6, [%[a], #284]\\n\\t\"\n        \"ldr\tr5, [%[b], #280]\\n\\t\"\n        \"ldr\tr7, [%[b], #284]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #280]\\n\\t\"\n        \"str\tr6, [%[r], #284]\\n\\t\"\n        \"ldr\tr4, [%[a], #288]\\n\\t\"\n        \"ldr\tr6, [%[a], #292]\\n\\t\"\n        \"ldr\tr5, [%[b], #288]\\n\\t\"\n        \"ldr\tr7, [%[b], #292]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #288]\\n\\t\"\n        \"str\tr6, [%[r], #292]\\n\\t\"\n        \"ldr\tr4, [%[a], #296]\\n\\t\"\n        \"ldr\tr6, [%[a], #300]\\n\\t\"\n        \"ldr\tr5, [%[b], #296]\\n\\t\"\n        \"ldr\tr7, [%[b], #300]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #296]\\n\\t\"\n        \"str\tr6, [%[r], #300]\\n\\t\"\n        \"ldr\tr4, [%[a], #304]\\n\\t\"\n        \"ldr\tr6, [%[a], #308]\\n\\t\"\n        \"ldr\tr5, [%[b], #304]\\n\\t\"\n        \"ldr\tr7, [%[b], #308]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #304]\\n\\t\"\n        \"str\tr6, [%[r], #308]\\n\\t\"\n        \"ldr\tr4, [%[a], #312]\\n\\t\"\n        \"ldr\tr6, [%[a], #316]\\n\\t\"\n        \"ldr\tr5, [%[b], #312]\\n\\t\"\n        \"ldr\tr7, [%[b], #316]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #312]\\n\\t\"\n        \"str\tr6, [%[r], #316]\\n\\t\"\n        \"ldr\tr4, [%[a], #320]\\n\\t\"\n        \"ldr\tr6, [%[a], #324]\\n\\t\"\n        \"ldr\tr5, [%[b], #320]\\n\\t\"\n        \"ldr\tr7, [%[b], #324]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #320]\\n\\t\"\n        \"str\tr6, [%[r], #324]\\n\\t\"\n        \"ldr\tr4, [%[a], #328]\\n\\t\"\n        \"ldr\tr6, [%[a], #332]\\n\\t\"\n        \"ldr\tr5, [%[b], #328]\\n\\t\"\n        \"ldr\tr7, [%[b], #332]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #328]\\n\\t\"\n        \"str\tr6, [%[r], #332]\\n\\t\"\n        \"ldr\tr4, [%[a], #336]\\n\\t\"\n        \"ldr\tr6, [%[a], #340]\\n\\t\"\n        \"ldr\tr5, [%[b], #336]\\n\\t\"\n        \"ldr\tr7, [%[b], #340]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #336]\\n\\t\"\n        \"str\tr6, [%[r], #340]\\n\\t\"\n        \"ldr\tr4, [%[a], #344]\\n\\t\"\n        \"ldr\tr6, [%[a], #348]\\n\\t\"\n        \"ldr\tr5, [%[b], #344]\\n\\t\"\n        \"ldr\tr7, [%[b], #348]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #344]\\n\\t\"\n        \"str\tr6, [%[r], #348]\\n\\t\"\n        \"ldr\tr4, [%[a], #352]\\n\\t\"\n        \"ldr\tr6, [%[a], #356]\\n\\t\"\n        \"ldr\tr5, [%[b], #352]\\n\\t\"\n        \"ldr\tr7, [%[b], #356]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #352]\\n\\t\"\n        \"str\tr6, [%[r], #356]\\n\\t\"\n        \"ldr\tr4, [%[a], #360]\\n\\t\"\n        \"ldr\tr6, [%[a], #364]\\n\\t\"\n        \"ldr\tr5, [%[b], #360]\\n\\t\"\n        \"ldr\tr7, [%[b], #364]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #360]\\n\\t\"\n        \"str\tr6, [%[r], #364]\\n\\t\"\n        \"ldr\tr4, [%[a], #368]\\n\\t\"\n        \"ldr\tr6, [%[a], #372]\\n\\t\"\n        \"ldr\tr5, [%[b], #368]\\n\\t\"\n        \"ldr\tr7, [%[b], #372]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #368]\\n\\t\"\n        \"str\tr6, [%[r], #372]\\n\\t\"\n        \"ldr\tr4, [%[a], #376]\\n\\t\"\n        \"ldr\tr6, [%[a], #380]\\n\\t\"\n        \"ldr\tr5, [%[b], #376]\\n\\t\"\n        \"ldr\tr7, [%[b], #380]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #376]\\n\\t\"\n        \"str\tr6, [%[r], #380]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r4\", \"r6\", \"r5\", \"r7\", \"r8\", \"r9\"\n    );\n#endif /* WOLFSSL_SP_SMALL */\n\n    return c;\n}\n\n/* Reduce the number back to 3072 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"# i = 0\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr10, [%[a], #0]\\n\\t\"\n        \"ldr\tr14, [%[a], #4]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mul\tr8, %[mp], r10\\n\\t\"\n        \"# a[i+0] += m[0] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #0]\\n\\t\"\n        \"ldr\tr9, [%[a], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr10, r10, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"# a[i+1] += m[1] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #4]\\n\\t\"\n        \"ldr\tr9, [%[a], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr10, r14, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr10, r10, r5\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+2] += m[2] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #8]\\n\\t\"\n        \"ldr\tr14, [%[a], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr14, r14, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr14, r14, r4\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+3] += m[3] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #12]\\n\\t\"\n        \"ldr\tr9, [%[a], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #12]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+4] += m[4] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #16]\\n\\t\"\n        \"ldr\tr9, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #16]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+5] += m[5] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #20]\\n\\t\"\n        \"ldr\tr9, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #20]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+6] += m[6] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #24]\\n\\t\"\n        \"ldr\tr9, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #24]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+7] += m[7] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #28]\\n\\t\"\n        \"ldr\tr9, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #28]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+8] += m[8] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #32]\\n\\t\"\n        \"ldr\tr9, [%[a], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #32]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+9] += m[9] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #36]\\n\\t\"\n        \"ldr\tr9, [%[a], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #36]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+10] += m[10] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #40]\\n\\t\"\n        \"ldr\tr9, [%[a], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #40]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+11] += m[11] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #44]\\n\\t\"\n        \"ldr\tr9, [%[a], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #44]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+12] += m[12] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #48]\\n\\t\"\n        \"ldr\tr9, [%[a], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #48]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+13] += m[13] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #52]\\n\\t\"\n        \"ldr\tr9, [%[a], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #52]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+14] += m[14] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #56]\\n\\t\"\n        \"ldr\tr9, [%[a], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #56]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+15] += m[15] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #60]\\n\\t\"\n        \"ldr\tr9, [%[a], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #60]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+16] += m[16] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #64]\\n\\t\"\n        \"ldr\tr9, [%[a], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #64]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+17] += m[17] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #68]\\n\\t\"\n        \"ldr\tr9, [%[a], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #68]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+18] += m[18] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #72]\\n\\t\"\n        \"ldr\tr9, [%[a], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #72]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+19] += m[19] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #76]\\n\\t\"\n        \"ldr\tr9, [%[a], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #76]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+20] += m[20] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #80]\\n\\t\"\n        \"ldr\tr9, [%[a], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #80]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+21] += m[21] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #84]\\n\\t\"\n        \"ldr\tr9, [%[a], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #84]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+22] += m[22] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #88]\\n\\t\"\n        \"ldr\tr9, [%[a], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #88]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+23] += m[23] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #92]\\n\\t\"\n        \"ldr\tr9, [%[a], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #92]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+24] += m[24] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #96]\\n\\t\"\n        \"ldr\tr9, [%[a], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #96]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+25] += m[25] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #100]\\n\\t\"\n        \"ldr\tr9, [%[a], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #100]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+26] += m[26] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #104]\\n\\t\"\n        \"ldr\tr9, [%[a], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #104]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+27] += m[27] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #108]\\n\\t\"\n        \"ldr\tr9, [%[a], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #108]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+28] += m[28] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #112]\\n\\t\"\n        \"ldr\tr9, [%[a], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #112]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+29] += m[29] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #116]\\n\\t\"\n        \"ldr\tr9, [%[a], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #116]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+30] += m[30] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #120]\\n\\t\"\n        \"ldr\tr9, [%[a], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #120]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+31] += m[31] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #124]\\n\\t\"\n        \"ldr\tr9, [%[a], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #124]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+32] += m[32] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #128]\\n\\t\"\n        \"ldr\tr9, [%[a], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #128]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+33] += m[33] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #132]\\n\\t\"\n        \"ldr\tr9, [%[a], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #132]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+34] += m[34] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #136]\\n\\t\"\n        \"ldr\tr9, [%[a], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #136]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+35] += m[35] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #140]\\n\\t\"\n        \"ldr\tr9, [%[a], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #140]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+36] += m[36] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #144]\\n\\t\"\n        \"ldr\tr9, [%[a], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #144]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+37] += m[37] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #148]\\n\\t\"\n        \"ldr\tr9, [%[a], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #148]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+38] += m[38] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #152]\\n\\t\"\n        \"ldr\tr9, [%[a], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #152]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+39] += m[39] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #156]\\n\\t\"\n        \"ldr\tr9, [%[a], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #156]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+40] += m[40] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #160]\\n\\t\"\n        \"ldr\tr9, [%[a], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #160]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+41] += m[41] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #164]\\n\\t\"\n        \"ldr\tr9, [%[a], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #164]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+42] += m[42] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #168]\\n\\t\"\n        \"ldr\tr9, [%[a], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #168]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+43] += m[43] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #172]\\n\\t\"\n        \"ldr\tr9, [%[a], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #172]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+44] += m[44] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #176]\\n\\t\"\n        \"ldr\tr9, [%[a], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #176]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+45] += m[45] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #180]\\n\\t\"\n        \"ldr\tr9, [%[a], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #180]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+46] += m[46] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #184]\\n\\t\"\n        \"ldr\tr9, [%[a], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #184]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+47] += m[47] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #188]\\n\\t\"\n        \"ldr\tr9, [%[a], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #188]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+48] += m[48] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #192]\\n\\t\"\n        \"ldr\tr9, [%[a], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #192]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+49] += m[49] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #196]\\n\\t\"\n        \"ldr\tr9, [%[a], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #196]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+50] += m[50] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #200]\\n\\t\"\n        \"ldr\tr9, [%[a], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #200]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+51] += m[51] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #204]\\n\\t\"\n        \"ldr\tr9, [%[a], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #204]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+52] += m[52] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #208]\\n\\t\"\n        \"ldr\tr9, [%[a], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #208]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+53] += m[53] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #212]\\n\\t\"\n        \"ldr\tr9, [%[a], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #212]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+54] += m[54] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #216]\\n\\t\"\n        \"ldr\tr9, [%[a], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #216]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+55] += m[55] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #220]\\n\\t\"\n        \"ldr\tr9, [%[a], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #220]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+56] += m[56] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #224]\\n\\t\"\n        \"ldr\tr9, [%[a], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #224]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+57] += m[57] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #228]\\n\\t\"\n        \"ldr\tr9, [%[a], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #228]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+58] += m[58] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #232]\\n\\t\"\n        \"ldr\tr9, [%[a], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #232]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+59] += m[59] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #236]\\n\\t\"\n        \"ldr\tr9, [%[a], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #236]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+60] += m[60] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #240]\\n\\t\"\n        \"ldr\tr9, [%[a], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #240]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+61] += m[61] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #244]\\n\\t\"\n        \"ldr\tr9, [%[a], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #244]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+62] += m[62] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #248]\\n\\t\"\n        \"ldr\tr9, [%[a], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #248]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+63] += m[63] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #252]\\n\\t\"\n        \"ldr\tr9, [%[a], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #252]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+64] += m[64] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #256]\\n\\t\"\n        \"ldr\tr9, [%[a], #256]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #256]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+65] += m[65] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #260]\\n\\t\"\n        \"ldr\tr9, [%[a], #260]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #260]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+66] += m[66] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #264]\\n\\t\"\n        \"ldr\tr9, [%[a], #264]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #264]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+67] += m[67] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #268]\\n\\t\"\n        \"ldr\tr9, [%[a], #268]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #268]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+68] += m[68] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #272]\\n\\t\"\n        \"ldr\tr9, [%[a], #272]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #272]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+69] += m[69] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #276]\\n\\t\"\n        \"ldr\tr9, [%[a], #276]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #276]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+70] += m[70] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #280]\\n\\t\"\n        \"ldr\tr9, [%[a], #280]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #280]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+71] += m[71] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #284]\\n\\t\"\n        \"ldr\tr9, [%[a], #284]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #284]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+72] += m[72] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #288]\\n\\t\"\n        \"ldr\tr9, [%[a], #288]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #288]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+73] += m[73] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #292]\\n\\t\"\n        \"ldr\tr9, [%[a], #292]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #292]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+74] += m[74] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #296]\\n\\t\"\n        \"ldr\tr9, [%[a], #296]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #296]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+75] += m[75] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #300]\\n\\t\"\n        \"ldr\tr9, [%[a], #300]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #300]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+76] += m[76] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #304]\\n\\t\"\n        \"ldr\tr9, [%[a], #304]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #304]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+77] += m[77] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #308]\\n\\t\"\n        \"ldr\tr9, [%[a], #308]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #308]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+78] += m[78] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #312]\\n\\t\"\n        \"ldr\tr9, [%[a], #312]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #312]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+79] += m[79] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #316]\\n\\t\"\n        \"ldr\tr9, [%[a], #316]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #316]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+80] += m[80] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #320]\\n\\t\"\n        \"ldr\tr9, [%[a], #320]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #320]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+81] += m[81] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #324]\\n\\t\"\n        \"ldr\tr9, [%[a], #324]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #324]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+82] += m[82] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #328]\\n\\t\"\n        \"ldr\tr9, [%[a], #328]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #328]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+83] += m[83] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #332]\\n\\t\"\n        \"ldr\tr9, [%[a], #332]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #332]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+84] += m[84] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #336]\\n\\t\"\n        \"ldr\tr9, [%[a], #336]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #336]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+85] += m[85] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #340]\\n\\t\"\n        \"ldr\tr9, [%[a], #340]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #340]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+86] += m[86] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #344]\\n\\t\"\n        \"ldr\tr9, [%[a], #344]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #344]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+87] += m[87] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #348]\\n\\t\"\n        \"ldr\tr9, [%[a], #348]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #348]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+88] += m[88] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #352]\\n\\t\"\n        \"ldr\tr9, [%[a], #352]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #352]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+89] += m[89] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #356]\\n\\t\"\n        \"ldr\tr9, [%[a], #356]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #356]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+90] += m[90] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #360]\\n\\t\"\n        \"ldr\tr9, [%[a], #360]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #360]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+91] += m[91] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #364]\\n\\t\"\n        \"ldr\tr9, [%[a], #364]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #364]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+92] += m[92] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #368]\\n\\t\"\n        \"ldr\tr9, [%[a], #368]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #368]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+93] += m[93] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #372]\\n\\t\"\n        \"ldr\tr9, [%[a], #372]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #372]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+94] += m[94] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #376]\\n\\t\"\n        \"ldr\tr9, [%[a], #376]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #376]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+95] += m[95] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #380]\\n\\t\"\n        \"ldr   r9, [%[a], #380]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr7, r7, %[ca]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"adc\t%[ca], %[ca], %[ca]\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #380]\\n\\t\"\n        \"ldr\tr9, [%[a], #384]\\n\\t\"\n        \"adcs\tr9, r9, r7\\n\\t\"\n        \"str\tr9, [%[a], #384]\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"add\tr12, r12, #4\\n\\t\"\n        \"cmp\tr12, #384\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr10, [%[a], #0]\\n\\t\"\n        \"str\tr14, [%[a], #4]\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    sp_3072_cond_sub_96(a - 96, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_96(r, a, b);\n    sp_3072_mont_reduce_96(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_96(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_96(r, a);\n    sp_3072_mont_reduce_96(r, m, mp);\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nstatic sp_digit div_3072_word_96(sp_digit d1, sp_digit d0, sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr5, %[div], #1\\n\\t\"\n        \"add\tr5, r5, #1\\n\\t\"\n        \"mov\tr6, %[d0]\\n\\t\"\n        \"mov\tr7, %[d1]\\n\\t\"\n        \"# Do top 32\\n\\t\"\n        \"subs\tr8, r5, r7\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        \"and\tr8, r8, r5\\n\\t\"\n        \"subs\tr7, r7, r8\\n\\t\"\n        \"# Next 30 bits\\n\\t\"\n        \"mov\tr4, #29\\n\\t\"\n        \"1:\\n\\t\"\n        \"movs\tr6, r6, lsl #1\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"subs\tr8, r5, r7\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        \"and\tr8, r8, r5\\n\\t\"\n        \"subs\tr7, r7, r8\\n\\t\"\n        \"subs\tr4, r4, #1\\n\\t\"\n        \"bpl\t1b\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"add\t%[r], %[r], #1\\n\\t\"\n        \"umull\tr4, r5, %[r], %[div]\\n\\t\"\n        \"subs\tr4, %[d0], r4\\n\\t\"\n        \"sbc\tr5, %[d1], r5\\n\\t\"\n        \"add\t%[r], %[r], r5\\n\\t\"\n        \"umull\tr4, r5, %[r], %[div]\\n\\t\"\n        \"subs\tr4, %[d0], r4\\n\\t\"\n        \"sbc\tr5, %[d1], r5\\n\\t\"\n        \"add\t%[r], %[r], r5\\n\\t\"\n        \"subs\tr8, %[div], r4\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_96(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<96; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 96; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic int32_t sp_3072_cmp_96(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = -1;\n    sp_digit one = 1;\n\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr3, #-1\\n\\t\"\n        \"mov\tr6, #380\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr4, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr4, r4, r3\\n\\t\"\n        \"and\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"subs\tr6, r6, #4\\n\\t\"\n        \"bcs\t1b\\n\\t\"\n        \"eor\t%[r], %[r], r3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr3, #-1\\n\\t\"\n        \"ldr\t\tr4, [%[a], #380]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #380]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #376]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #376]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #372]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #372]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #368]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #368]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #364]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #364]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #360]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #360]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #356]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #356]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #352]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #352]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #348]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #348]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #344]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #344]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #340]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #340]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #336]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #336]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #332]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #332]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #328]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #328]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #324]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #324]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #320]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #320]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #316]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #316]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #312]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #312]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #308]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #308]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #304]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #304]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #300]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #300]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #296]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #296]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #292]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #292]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #288]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #288]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #284]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #284]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #280]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #280]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #276]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #276]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #272]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #272]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #268]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #268]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #264]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #264]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #260]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #260]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #256]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #256]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #252]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #252]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #248]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #248]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #244]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #244]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #240]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #240]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #236]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #236]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #232]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #232]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #228]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #228]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #224]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #224]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #220]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #220]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #216]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #216]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #212]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #212]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #208]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #208]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #204]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #204]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #200]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #200]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #196]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #196]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #192]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #192]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #188]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #188]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #184]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #184]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #180]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #180]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #176]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #176]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #172]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #172]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #168]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #168]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #164]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #164]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #160]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #160]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #156]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #156]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #152]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #152]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #148]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #148]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #144]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #144]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #140]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #140]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #136]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #136]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #132]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #132]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #128]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #128]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #124]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #120]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #116]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #112]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #108]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #104]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #100]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #96]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #92]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #88]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #84]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #80]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #76]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #72]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #68]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #64]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #60]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #56]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #52]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #48]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #44]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #40]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #36]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #32]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #28]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #24]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #20]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #16]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #12]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #8]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #4]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #0]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"eor\t%[r], %[r], r3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n#endif\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_96(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[192], t2[97];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n\n    div = d[95];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 96);\n    for (i=95; i>=0; i--) {\n        r1 = div_3072_word_96(t1[96 + i], t1[96 + i - 1], div);\n\n        sp_3072_mul_d_96(t2, d, r1);\n        t1[96 + i] += sp_3072_sub_in_place_96(&t1[i], t2);\n        t1[96 + i] -= t2[96];\n        sp_3072_mask_96(t2, d, t1[96 + i]);\n        t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], t2);\n        sp_3072_mask_96(t2, d, t1[96 + i]);\n        t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_3072_cmp_96(t1, d) >= 0;\n    sp_3072_cond_sub_96(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_96(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_96(a, m, NULL, r);\n}\n\n#endif /* WOLFSSL_RSA_PUBLIC_ONLY */\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_96_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[192], t2[97];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n\n    div = d[95];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 96);\n    for (i=95; i>=0; i--) {\n        r1 = div_3072_word_96(t1[96 + i], t1[96 + i - 1], div);\n\n        sp_3072_mul_d_96(t2, d, r1);\n        t1[96 + i] += sp_3072_sub_in_place_96(&t1[i], t2);\n        t1[96 + i] -= t2[96];\n        if (t1[96 + i] != 0) {\n            t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], d);\n            if (t1[96 + i] != 0)\n                t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_3072_cmp_96(t1, d) >= 0;\n    sp_3072_cond_sub_96(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_96_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_96_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][192];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 192, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 192;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_96(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 96U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_96(t[1] + 96, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_96(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 96, a, sizeof(sp_digit) * 96);\n            err = sp_3072_mod_96(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_96(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_96(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_96(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_96(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_96(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_96(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_96(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_96(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_96(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_96(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_96(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_96(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_96(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_96(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 96);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n\n            sp_3072_mont_mul_96(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[96], 0, sizeof(sp_digit) * 96U);\n        sp_3072_mont_reduce_96(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_96(r, m) >= 0);\n        sp_3072_cond_sub_96(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][192];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 192, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 192;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_96(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 96U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_96(t[1] + 96, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_96(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 96, a, sizeof(sp_digit) * 96);\n            err = sp_3072_mod_96(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_96(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_96(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_96(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_96(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_96(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_96(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_96(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_96(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_96(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_96(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_96(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_96(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_96(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_96(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_96(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_96(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_96(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_96(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_96(t[20], t[10], m, mp);\n        sp_3072_mont_mul_96(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_96(t[22], t[11], m, mp);\n        sp_3072_mont_mul_96(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_96(t[24], t[12], m, mp);\n        sp_3072_mont_mul_96(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_96(t[26], t[13], m, mp);\n        sp_3072_mont_mul_96(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_96(t[28], t[14], m, mp);\n        sp_3072_mont_mul_96(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_96(t[30], t[15], m, mp);\n        sp_3072_mont_mul_96(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 96);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n\n            sp_3072_mont_mul_96(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[96], 0, sizeof(sp_digit) * 96U);\n        sp_3072_mont_reduce_96(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_96(r, m) >= 0);\n        sp_3072_cond_sub_96(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[192], md[96], rd[192];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1];\n    int err = MP_OKAY;\n\n    if (*outLen < 384)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 32 || inLen > 384 ||\n                                                     mp_count_bits(mm) != 3072))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 96 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 96 * 2;\n        m = r + 96 * 2;\n        ah = a + 96;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 96;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(ah, 96, in, inLen);\n#if DIGIT_BIT >= 32\n        e[0] = em->dp[0];\n#else\n        e[0] = em->dp[0];\n        if (em->used > 1)\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e[0] == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(m, 96, mm);\n\n        if (e[0] == 0x3) {\n            if (err == MP_OKAY) {\n                sp_3072_sqr_96(r, ah);\n                err = sp_3072_mod_96_cond(r, r, m);\n            }\n            if (err == MP_OKAY) {\n                sp_3072_mul_96(r, ah, r);\n                err = sp_3072_mod_96_cond(r, r, m);\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_3072_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 96);\n            err = sp_3072_mod_96_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=31; i>=0; i--)\n                    if (e[0] >> i)\n                        break;\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 96);\n                for (i--; i>=0; i--) {\n                    sp_3072_mont_sqr_96(r, r, m, mp);\n                    if (((e[0] >> i) & 1) == 1)\n                        sp_3072_mont_mul_96(r, r, a, m, mp);\n                }\n                XMEMSET(&r[96], 0, sizeof(sp_digit) * 96);\n                sp_3072_mont_reduce_96(r, m, mp);\n\n                for (i = 95; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_3072_sub_in_place_96(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[96 * 2];\n    sp_digit pd[48], qd[48], dpd[48];\n    sp_digit tmpad[96], tmpbd[96];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 384)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 384 || mp_count_bits(mm) != 3072))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 48 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 96 * 2;\n        q = p + 48;\n        qi = dq = dp = q + 48;\n        tmpa = qi + 48;\n        tmpb = tmpa + 96;\n\n        tmp = t;\n        r = tmp + 96;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 96;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(a, 96, in, inLen);\n        sp_3072_from_mp(p, 48, pm);\n        sp_3072_from_mp(q, 48, qm);\n        sp_3072_from_mp(dp, 48, dpm);\n\n        err = sp_3072_mod_exp_48(tmpa, a, dp, 1536, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(dq, 48, dqm);\n        err = sp_3072_mod_exp_48(tmpb, a, dq, 1536, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_3072_sub_in_place_48(tmpa, tmpb);\n        sp_3072_mask_48(tmp, p, c);\n        sp_3072_add_48(tmpa, tmpa, tmp);\n\n        sp_3072_from_mp(qi, 48, qim);\n        sp_3072_mul_48(tmpa, tmpa, qi);\n        err = sp_3072_mod_48(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mul_48(tmpa, q, tmpa);\n        XMEMSET(&tmpb[48], 0, sizeof(sp_digit) * 48);\n        sp_3072_add_96(r, tmpb, tmpa);\n\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 48 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_3072_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 32\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 96);\n        r->used = 96;\n        mp_clamp(r);\n#elif DIGIT_BIT < 32\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 96; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 32) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 32 - s;\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 96; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 32 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 32 - s;\n            }\n            else {\n                s += 32;\n            }\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[192], e[96], m[96];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 96, base);\n        sp_3072_from_mp(e, 96, exp);\n        sp_3072_from_mp(m, 96, mod);\n\n        err = sp_3072_mod_exp_96(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_3072_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_3072\nstatic void sp_3072_lshift_96(sp_digit* r, sp_digit* a, byte n)\n{\n    __asm__ __volatile__ (\n        \"mov\tr6, #31\\n\\t\"\n        \"sub\tr6, r6, %[n]\\n\\t\"\n        \"ldr\tr3, [%[a], #380]\\n\\t\"\n        \"lsr\tr4, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr4, r4, r6\\n\\t\"\n        \"ldr\tr2, [%[a], #376]\\n\\t\"\n        \"str\tr4, [%[r], #384]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #372]\\n\\t\"\n        \"str\tr3, [%[r], #380]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #368]\\n\\t\"\n        \"str\tr2, [%[r], #376]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #364]\\n\\t\"\n        \"str\tr4, [%[r], #372]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #360]\\n\\t\"\n        \"str\tr3, [%[r], #368]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #356]\\n\\t\"\n        \"str\tr2, [%[r], #364]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #352]\\n\\t\"\n        \"str\tr4, [%[r], #360]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #348]\\n\\t\"\n        \"str\tr3, [%[r], #356]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #344]\\n\\t\"\n        \"str\tr2, [%[r], #352]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #340]\\n\\t\"\n        \"str\tr4, [%[r], #348]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #336]\\n\\t\"\n        \"str\tr3, [%[r], #344]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #332]\\n\\t\"\n        \"str\tr2, [%[r], #340]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #328]\\n\\t\"\n        \"str\tr4, [%[r], #336]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #324]\\n\\t\"\n        \"str\tr3, [%[r], #332]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #320]\\n\\t\"\n        \"str\tr2, [%[r], #328]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #316]\\n\\t\"\n        \"str\tr4, [%[r], #324]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #312]\\n\\t\"\n        \"str\tr3, [%[r], #320]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #308]\\n\\t\"\n        \"str\tr2, [%[r], #316]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #304]\\n\\t\"\n        \"str\tr4, [%[r], #312]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #300]\\n\\t\"\n        \"str\tr3, [%[r], #308]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #296]\\n\\t\"\n        \"str\tr2, [%[r], #304]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #292]\\n\\t\"\n        \"str\tr4, [%[r], #300]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #288]\\n\\t\"\n        \"str\tr3, [%[r], #296]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #284]\\n\\t\"\n        \"str\tr2, [%[r], #292]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #280]\\n\\t\"\n        \"str\tr4, [%[r], #288]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #276]\\n\\t\"\n        \"str\tr3, [%[r], #284]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #272]\\n\\t\"\n        \"str\tr2, [%[r], #280]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #268]\\n\\t\"\n        \"str\tr4, [%[r], #276]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #264]\\n\\t\"\n        \"str\tr3, [%[r], #272]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #260]\\n\\t\"\n        \"str\tr2, [%[r], #268]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #256]\\n\\t\"\n        \"str\tr4, [%[r], #264]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #252]\\n\\t\"\n        \"str\tr3, [%[r], #260]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #248]\\n\\t\"\n        \"str\tr2, [%[r], #256]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #244]\\n\\t\"\n        \"str\tr4, [%[r], #252]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #240]\\n\\t\"\n        \"str\tr3, [%[r], #248]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #236]\\n\\t\"\n        \"str\tr2, [%[r], #244]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #232]\\n\\t\"\n        \"str\tr4, [%[r], #240]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #228]\\n\\t\"\n        \"str\tr3, [%[r], #236]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #224]\\n\\t\"\n        \"str\tr2, [%[r], #232]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #220]\\n\\t\"\n        \"str\tr4, [%[r], #228]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #216]\\n\\t\"\n        \"str\tr3, [%[r], #224]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #212]\\n\\t\"\n        \"str\tr2, [%[r], #220]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #208]\\n\\t\"\n        \"str\tr4, [%[r], #216]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #204]\\n\\t\"\n        \"str\tr3, [%[r], #212]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #200]\\n\\t\"\n        \"str\tr2, [%[r], #208]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #196]\\n\\t\"\n        \"str\tr4, [%[r], #204]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #192]\\n\\t\"\n        \"str\tr3, [%[r], #200]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #188]\\n\\t\"\n        \"str\tr2, [%[r], #196]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #184]\\n\\t\"\n        \"str\tr4, [%[r], #192]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #180]\\n\\t\"\n        \"str\tr3, [%[r], #188]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #176]\\n\\t\"\n        \"str\tr2, [%[r], #184]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #172]\\n\\t\"\n        \"str\tr4, [%[r], #180]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #168]\\n\\t\"\n        \"str\tr3, [%[r], #176]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #164]\\n\\t\"\n        \"str\tr2, [%[r], #172]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #160]\\n\\t\"\n        \"str\tr4, [%[r], #168]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #156]\\n\\t\"\n        \"str\tr3, [%[r], #164]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #152]\\n\\t\"\n        \"str\tr2, [%[r], #160]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #148]\\n\\t\"\n        \"str\tr4, [%[r], #156]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #144]\\n\\t\"\n        \"str\tr3, [%[r], #152]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #140]\\n\\t\"\n        \"str\tr2, [%[r], #148]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #136]\\n\\t\"\n        \"str\tr4, [%[r], #144]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #132]\\n\\t\"\n        \"str\tr3, [%[r], #140]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #128]\\n\\t\"\n        \"str\tr2, [%[r], #136]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #124]\\n\\t\"\n        \"str\tr4, [%[r], #132]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"str\tr3, [%[r], #128]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #116]\\n\\t\"\n        \"str\tr2, [%[r], #124]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #112]\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"str\tr3, [%[r], #116]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #104]\\n\\t\"\n        \"str\tr2, [%[r], #112]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #100]\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"str\tr3, [%[r], #104]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #92]\\n\\t\"\n        \"str\tr2, [%[r], #100]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #88]\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"str\tr3, [%[r], #92]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #80]\\n\\t\"\n        \"str\tr2, [%[r], #88]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #76]\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"str\tr3, [%[r], #80]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #68]\\n\\t\"\n        \"str\tr2, [%[r], #76]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #64]\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"str\tr3, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr2, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #52]\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"str\tr3, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #44]\\n\\t\"\n        \"str\tr2, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"str\tr3, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr2, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #28]\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr3, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr2, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"str\tr3, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr2, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"str\tr2, [%[r], #4]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [n] \"r\" (n)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[192];\n    sp_digit td[97];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 289, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 192;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_96(norm, m);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        sp_3072_lshift_96(r, norm, y);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n\n            sp_3072_lshift_96(r, r, y);\n            sp_3072_mul_d_96(tmp, norm, r[96]);\n            r[96] = 0;\n            o = sp_3072_add_96(r, r, tmp);\n            sp_3072_cond_sub_96(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[96], 0, sizeof(sp_digit) * 96U);\n        sp_3072_mont_reduce_96(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_96(r, m) >= 0);\n        sp_3072_cond_sub_96(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* HAVE_FFDHE_3072 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 384 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[192], e[96], m[96];\n    sp_digit* r = b;\n    word32 i;\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 384) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 96, base);\n        sp_3072_from_bin(e, 96, exp, expLen);\n        sp_3072_from_mp(m, 96, mod);\n\n    #ifdef HAVE_FFDHE_3072\n        if (base->used == 1 && base->dp[0] == 2 && m[95] == (sp_digit)-1)\n            err = sp_3072_mod_exp_2_96(r, e, expLen * 8, m);\n        else\n    #endif\n            err = sp_3072_mod_exp_96(r, b, e, expLen * 8, m, 0);\n\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n        for (i=0; i<384 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[96], e[48], m[48];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1536) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 48, base);\n        sp_3072_from_mp(e, 48, exp);\n        sp_3072_from_mp(m, 48, mod);\n\n        err = sp_3072_mod_exp_48(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 48, 0, sizeof(*r) * 48U);\n        err = sp_3072_to_mp(r, res);\n        res->used = mod->used;\n        mp_clamp(res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_3072 */\n\n#ifdef WOLFSSL_SP_4096\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 24U) {\n            r[j] &= 0xffffffff;\n            s = 32U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 32\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 32\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffff;\n        s = 32U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 32U) <= (word32)DIGIT_BIT) {\n            s += 32U;\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 32) {\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 32 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 512\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_4096_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 4096 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<128 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 32) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 32);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_4096_add_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[a], #4]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[b], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"ldr\tr10, [%[b], #8]\\n\\t\"\n        \"ldr\tr14, [%[b], #12]\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr5, [%[r], #4]\\n\\t\"\n        \"str\tr6, [%[r], #8]\\n\\t\"\n        \"str\tr7, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[a], #20]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[b], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"ldr\tr10, [%[b], #24]\\n\\t\"\n        \"ldr\tr14, [%[b], #28]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"str\tr6, [%[r], #24]\\n\\t\"\n        \"str\tr7, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[a], #36]\\n\\t\"\n        \"ldr\tr6, [%[a], #40]\\n\\t\"\n        \"ldr\tr7, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[b], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"ldr\tr10, [%[b], #40]\\n\\t\"\n        \"ldr\tr14, [%[b], #44]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr5, [%[r], #36]\\n\\t\"\n        \"str\tr6, [%[r], #40]\\n\\t\"\n        \"str\tr7, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[a], #52]\\n\\t\"\n        \"ldr\tr6, [%[a], #56]\\n\\t\"\n        \"ldr\tr7, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[b], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"ldr\tr10, [%[b], #56]\\n\\t\"\n        \"ldr\tr14, [%[b], #60]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"str\tr5, [%[r], #52]\\n\\t\"\n        \"str\tr6, [%[r], #56]\\n\\t\"\n        \"str\tr7, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[a], #68]\\n\\t\"\n        \"ldr\tr6, [%[a], #72]\\n\\t\"\n        \"ldr\tr7, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[b], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"ldr\tr10, [%[b], #72]\\n\\t\"\n        \"ldr\tr14, [%[b], #76]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"str\tr5, [%[r], #68]\\n\\t\"\n        \"str\tr6, [%[r], #72]\\n\\t\"\n        \"str\tr7, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[a], #84]\\n\\t\"\n        \"ldr\tr6, [%[a], #88]\\n\\t\"\n        \"ldr\tr7, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[b], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"ldr\tr10, [%[b], #88]\\n\\t\"\n        \"ldr\tr14, [%[b], #92]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"str\tr5, [%[r], #84]\\n\\t\"\n        \"str\tr6, [%[r], #88]\\n\\t\"\n        \"str\tr7, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[a], #100]\\n\\t\"\n        \"ldr\tr6, [%[a], #104]\\n\\t\"\n        \"ldr\tr7, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[b], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"ldr\tr10, [%[b], #104]\\n\\t\"\n        \"ldr\tr14, [%[b], #108]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"str\tr5, [%[r], #100]\\n\\t\"\n        \"str\tr6, [%[r], #104]\\n\\t\"\n        \"str\tr7, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[a], #116]\\n\\t\"\n        \"ldr\tr6, [%[a], #120]\\n\\t\"\n        \"ldr\tr7, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[b], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"ldr\tr10, [%[b], #120]\\n\\t\"\n        \"ldr\tr14, [%[b], #124]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"str\tr5, [%[r], #116]\\n\\t\"\n        \"str\tr6, [%[r], #120]\\n\\t\"\n        \"str\tr7, [%[r], #124]\\n\\t\"\n        \"ldr\tr4, [%[a], #128]\\n\\t\"\n        \"ldr\tr5, [%[a], #132]\\n\\t\"\n        \"ldr\tr6, [%[a], #136]\\n\\t\"\n        \"ldr\tr7, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[b], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"ldr\tr10, [%[b], #136]\\n\\t\"\n        \"ldr\tr14, [%[b], #140]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #128]\\n\\t\"\n        \"str\tr5, [%[r], #132]\\n\\t\"\n        \"str\tr6, [%[r], #136]\\n\\t\"\n        \"str\tr7, [%[r], #140]\\n\\t\"\n        \"ldr\tr4, [%[a], #144]\\n\\t\"\n        \"ldr\tr5, [%[a], #148]\\n\\t\"\n        \"ldr\tr6, [%[a], #152]\\n\\t\"\n        \"ldr\tr7, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[b], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"ldr\tr10, [%[b], #152]\\n\\t\"\n        \"ldr\tr14, [%[b], #156]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #144]\\n\\t\"\n        \"str\tr5, [%[r], #148]\\n\\t\"\n        \"str\tr6, [%[r], #152]\\n\\t\"\n        \"str\tr7, [%[r], #156]\\n\\t\"\n        \"ldr\tr4, [%[a], #160]\\n\\t\"\n        \"ldr\tr5, [%[a], #164]\\n\\t\"\n        \"ldr\tr6, [%[a], #168]\\n\\t\"\n        \"ldr\tr7, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[b], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"ldr\tr10, [%[b], #168]\\n\\t\"\n        \"ldr\tr14, [%[b], #172]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"str\tr5, [%[r], #164]\\n\\t\"\n        \"str\tr6, [%[r], #168]\\n\\t\"\n        \"str\tr7, [%[r], #172]\\n\\t\"\n        \"ldr\tr4, [%[a], #176]\\n\\t\"\n        \"ldr\tr5, [%[a], #180]\\n\\t\"\n        \"ldr\tr6, [%[a], #184]\\n\\t\"\n        \"ldr\tr7, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[b], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"ldr\tr10, [%[b], #184]\\n\\t\"\n        \"ldr\tr14, [%[b], #188]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #176]\\n\\t\"\n        \"str\tr5, [%[r], #180]\\n\\t\"\n        \"str\tr6, [%[r], #184]\\n\\t\"\n        \"str\tr7, [%[r], #188]\\n\\t\"\n        \"ldr\tr4, [%[a], #192]\\n\\t\"\n        \"ldr\tr5, [%[a], #196]\\n\\t\"\n        \"ldr\tr6, [%[a], #200]\\n\\t\"\n        \"ldr\tr7, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[b], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"ldr\tr10, [%[b], #200]\\n\\t\"\n        \"ldr\tr14, [%[b], #204]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #192]\\n\\t\"\n        \"str\tr5, [%[r], #196]\\n\\t\"\n        \"str\tr6, [%[r], #200]\\n\\t\"\n        \"str\tr7, [%[r], #204]\\n\\t\"\n        \"ldr\tr4, [%[a], #208]\\n\\t\"\n        \"ldr\tr5, [%[a], #212]\\n\\t\"\n        \"ldr\tr6, [%[a], #216]\\n\\t\"\n        \"ldr\tr7, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[b], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"ldr\tr10, [%[b], #216]\\n\\t\"\n        \"ldr\tr14, [%[b], #220]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #208]\\n\\t\"\n        \"str\tr5, [%[r], #212]\\n\\t\"\n        \"str\tr6, [%[r], #216]\\n\\t\"\n        \"str\tr7, [%[r], #220]\\n\\t\"\n        \"ldr\tr4, [%[a], #224]\\n\\t\"\n        \"ldr\tr5, [%[a], #228]\\n\\t\"\n        \"ldr\tr6, [%[a], #232]\\n\\t\"\n        \"ldr\tr7, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[b], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"ldr\tr10, [%[b], #232]\\n\\t\"\n        \"ldr\tr14, [%[b], #236]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #224]\\n\\t\"\n        \"str\tr5, [%[r], #228]\\n\\t\"\n        \"str\tr6, [%[r], #232]\\n\\t\"\n        \"str\tr7, [%[r], #236]\\n\\t\"\n        \"ldr\tr4, [%[a], #240]\\n\\t\"\n        \"ldr\tr5, [%[a], #244]\\n\\t\"\n        \"ldr\tr6, [%[a], #248]\\n\\t\"\n        \"ldr\tr7, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[b], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"ldr\tr10, [%[b], #248]\\n\\t\"\n        \"ldr\tr14, [%[b], #252]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #240]\\n\\t\"\n        \"str\tr5, [%[r], #244]\\n\\t\"\n        \"str\tr6, [%[r], #248]\\n\\t\"\n        \"str\tr7, [%[r], #252]\\n\\t\"\n        \"adc\t%[c], r12, r12\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_4096_sub_in_place_128(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr6, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"ldr\tr8, [%[b], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"subs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr6, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"ldr\tr8, [%[b], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr6, [%[b], #32]\\n\\t\"\n        \"ldr\tr7, [%[b], #36]\\n\\t\"\n        \"ldr\tr8, [%[b], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr5, [%[a], #44]\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[a], #60]\\n\\t\"\n        \"ldr\tr6, [%[b], #48]\\n\\t\"\n        \"ldr\tr7, [%[b], #52]\\n\\t\"\n        \"ldr\tr8, [%[b], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr5, [%[a], #60]\\n\\t\"\n        \"ldr\tr2, [%[a], #64]\\n\\t\"\n        \"ldr\tr3, [%[a], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[a], #76]\\n\\t\"\n        \"ldr\tr6, [%[b], #64]\\n\\t\"\n        \"ldr\tr7, [%[b], #68]\\n\\t\"\n        \"ldr\tr8, [%[b], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #64]\\n\\t\"\n        \"str\tr3, [%[a], #68]\\n\\t\"\n        \"str\tr4, [%[a], #72]\\n\\t\"\n        \"str\tr5, [%[a], #76]\\n\\t\"\n        \"ldr\tr2, [%[a], #80]\\n\\t\"\n        \"ldr\tr3, [%[a], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[a], #92]\\n\\t\"\n        \"ldr\tr6, [%[b], #80]\\n\\t\"\n        \"ldr\tr7, [%[b], #84]\\n\\t\"\n        \"ldr\tr8, [%[b], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #80]\\n\\t\"\n        \"str\tr3, [%[a], #84]\\n\\t\"\n        \"str\tr4, [%[a], #88]\\n\\t\"\n        \"str\tr5, [%[a], #92]\\n\\t\"\n        \"ldr\tr2, [%[a], #96]\\n\\t\"\n        \"ldr\tr3, [%[a], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[a], #108]\\n\\t\"\n        \"ldr\tr6, [%[b], #96]\\n\\t\"\n        \"ldr\tr7, [%[b], #100]\\n\\t\"\n        \"ldr\tr8, [%[b], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #96]\\n\\t\"\n        \"str\tr3, [%[a], #100]\\n\\t\"\n        \"str\tr4, [%[a], #104]\\n\\t\"\n        \"str\tr5, [%[a], #108]\\n\\t\"\n        \"ldr\tr2, [%[a], #112]\\n\\t\"\n        \"ldr\tr3, [%[a], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[a], #124]\\n\\t\"\n        \"ldr\tr6, [%[b], #112]\\n\\t\"\n        \"ldr\tr7, [%[b], #116]\\n\\t\"\n        \"ldr\tr8, [%[b], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #112]\\n\\t\"\n        \"str\tr3, [%[a], #116]\\n\\t\"\n        \"str\tr4, [%[a], #120]\\n\\t\"\n        \"str\tr5, [%[a], #124]\\n\\t\"\n        \"ldr\tr2, [%[a], #128]\\n\\t\"\n        \"ldr\tr3, [%[a], #132]\\n\\t\"\n        \"ldr\tr4, [%[a], #136]\\n\\t\"\n        \"ldr\tr5, [%[a], #140]\\n\\t\"\n        \"ldr\tr6, [%[b], #128]\\n\\t\"\n        \"ldr\tr7, [%[b], #132]\\n\\t\"\n        \"ldr\tr8, [%[b], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #128]\\n\\t\"\n        \"str\tr3, [%[a], #132]\\n\\t\"\n        \"str\tr4, [%[a], #136]\\n\\t\"\n        \"str\tr5, [%[a], #140]\\n\\t\"\n        \"ldr\tr2, [%[a], #144]\\n\\t\"\n        \"ldr\tr3, [%[a], #148]\\n\\t\"\n        \"ldr\tr4, [%[a], #152]\\n\\t\"\n        \"ldr\tr5, [%[a], #156]\\n\\t\"\n        \"ldr\tr6, [%[b], #144]\\n\\t\"\n        \"ldr\tr7, [%[b], #148]\\n\\t\"\n        \"ldr\tr8, [%[b], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #144]\\n\\t\"\n        \"str\tr3, [%[a], #148]\\n\\t\"\n        \"str\tr4, [%[a], #152]\\n\\t\"\n        \"str\tr5, [%[a], #156]\\n\\t\"\n        \"ldr\tr2, [%[a], #160]\\n\\t\"\n        \"ldr\tr3, [%[a], #164]\\n\\t\"\n        \"ldr\tr4, [%[a], #168]\\n\\t\"\n        \"ldr\tr5, [%[a], #172]\\n\\t\"\n        \"ldr\tr6, [%[b], #160]\\n\\t\"\n        \"ldr\tr7, [%[b], #164]\\n\\t\"\n        \"ldr\tr8, [%[b], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #160]\\n\\t\"\n        \"str\tr3, [%[a], #164]\\n\\t\"\n        \"str\tr4, [%[a], #168]\\n\\t\"\n        \"str\tr5, [%[a], #172]\\n\\t\"\n        \"ldr\tr2, [%[a], #176]\\n\\t\"\n        \"ldr\tr3, [%[a], #180]\\n\\t\"\n        \"ldr\tr4, [%[a], #184]\\n\\t\"\n        \"ldr\tr5, [%[a], #188]\\n\\t\"\n        \"ldr\tr6, [%[b], #176]\\n\\t\"\n        \"ldr\tr7, [%[b], #180]\\n\\t\"\n        \"ldr\tr8, [%[b], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #176]\\n\\t\"\n        \"str\tr3, [%[a], #180]\\n\\t\"\n        \"str\tr4, [%[a], #184]\\n\\t\"\n        \"str\tr5, [%[a], #188]\\n\\t\"\n        \"ldr\tr2, [%[a], #192]\\n\\t\"\n        \"ldr\tr3, [%[a], #196]\\n\\t\"\n        \"ldr\tr4, [%[a], #200]\\n\\t\"\n        \"ldr\tr5, [%[a], #204]\\n\\t\"\n        \"ldr\tr6, [%[b], #192]\\n\\t\"\n        \"ldr\tr7, [%[b], #196]\\n\\t\"\n        \"ldr\tr8, [%[b], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #192]\\n\\t\"\n        \"str\tr3, [%[a], #196]\\n\\t\"\n        \"str\tr4, [%[a], #200]\\n\\t\"\n        \"str\tr5, [%[a], #204]\\n\\t\"\n        \"ldr\tr2, [%[a], #208]\\n\\t\"\n        \"ldr\tr3, [%[a], #212]\\n\\t\"\n        \"ldr\tr4, [%[a], #216]\\n\\t\"\n        \"ldr\tr5, [%[a], #220]\\n\\t\"\n        \"ldr\tr6, [%[b], #208]\\n\\t\"\n        \"ldr\tr7, [%[b], #212]\\n\\t\"\n        \"ldr\tr8, [%[b], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #208]\\n\\t\"\n        \"str\tr3, [%[a], #212]\\n\\t\"\n        \"str\tr4, [%[a], #216]\\n\\t\"\n        \"str\tr5, [%[a], #220]\\n\\t\"\n        \"ldr\tr2, [%[a], #224]\\n\\t\"\n        \"ldr\tr3, [%[a], #228]\\n\\t\"\n        \"ldr\tr4, [%[a], #232]\\n\\t\"\n        \"ldr\tr5, [%[a], #236]\\n\\t\"\n        \"ldr\tr6, [%[b], #224]\\n\\t\"\n        \"ldr\tr7, [%[b], #228]\\n\\t\"\n        \"ldr\tr8, [%[b], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #224]\\n\\t\"\n        \"str\tr3, [%[a], #228]\\n\\t\"\n        \"str\tr4, [%[a], #232]\\n\\t\"\n        \"str\tr5, [%[a], #236]\\n\\t\"\n        \"ldr\tr2, [%[a], #240]\\n\\t\"\n        \"ldr\tr3, [%[a], #244]\\n\\t\"\n        \"ldr\tr4, [%[a], #248]\\n\\t\"\n        \"ldr\tr5, [%[a], #252]\\n\\t\"\n        \"ldr\tr6, [%[b], #240]\\n\\t\"\n        \"ldr\tr7, [%[b], #244]\\n\\t\"\n        \"ldr\tr8, [%[b], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #240]\\n\\t\"\n        \"str\tr3, [%[a], #244]\\n\\t\"\n        \"str\tr4, [%[a], #248]\\n\\t\"\n        \"str\tr5, [%[a], #252]\\n\\t\"\n        \"ldr\tr2, [%[a], #256]\\n\\t\"\n        \"ldr\tr3, [%[a], #260]\\n\\t\"\n        \"ldr\tr4, [%[a], #264]\\n\\t\"\n        \"ldr\tr5, [%[a], #268]\\n\\t\"\n        \"ldr\tr6, [%[b], #256]\\n\\t\"\n        \"ldr\tr7, [%[b], #260]\\n\\t\"\n        \"ldr\tr8, [%[b], #264]\\n\\t\"\n        \"ldr\tr9, [%[b], #268]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #256]\\n\\t\"\n        \"str\tr3, [%[a], #260]\\n\\t\"\n        \"str\tr4, [%[a], #264]\\n\\t\"\n        \"str\tr5, [%[a], #268]\\n\\t\"\n        \"ldr\tr2, [%[a], #272]\\n\\t\"\n        \"ldr\tr3, [%[a], #276]\\n\\t\"\n        \"ldr\tr4, [%[a], #280]\\n\\t\"\n        \"ldr\tr5, [%[a], #284]\\n\\t\"\n        \"ldr\tr6, [%[b], #272]\\n\\t\"\n        \"ldr\tr7, [%[b], #276]\\n\\t\"\n        \"ldr\tr8, [%[b], #280]\\n\\t\"\n        \"ldr\tr9, [%[b], #284]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #272]\\n\\t\"\n        \"str\tr3, [%[a], #276]\\n\\t\"\n        \"str\tr4, [%[a], #280]\\n\\t\"\n        \"str\tr5, [%[a], #284]\\n\\t\"\n        \"ldr\tr2, [%[a], #288]\\n\\t\"\n        \"ldr\tr3, [%[a], #292]\\n\\t\"\n        \"ldr\tr4, [%[a], #296]\\n\\t\"\n        \"ldr\tr5, [%[a], #300]\\n\\t\"\n        \"ldr\tr6, [%[b], #288]\\n\\t\"\n        \"ldr\tr7, [%[b], #292]\\n\\t\"\n        \"ldr\tr8, [%[b], #296]\\n\\t\"\n        \"ldr\tr9, [%[b], #300]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #288]\\n\\t\"\n        \"str\tr3, [%[a], #292]\\n\\t\"\n        \"str\tr4, [%[a], #296]\\n\\t\"\n        \"str\tr5, [%[a], #300]\\n\\t\"\n        \"ldr\tr2, [%[a], #304]\\n\\t\"\n        \"ldr\tr3, [%[a], #308]\\n\\t\"\n        \"ldr\tr4, [%[a], #312]\\n\\t\"\n        \"ldr\tr5, [%[a], #316]\\n\\t\"\n        \"ldr\tr6, [%[b], #304]\\n\\t\"\n        \"ldr\tr7, [%[b], #308]\\n\\t\"\n        \"ldr\tr8, [%[b], #312]\\n\\t\"\n        \"ldr\tr9, [%[b], #316]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #304]\\n\\t\"\n        \"str\tr3, [%[a], #308]\\n\\t\"\n        \"str\tr4, [%[a], #312]\\n\\t\"\n        \"str\tr5, [%[a], #316]\\n\\t\"\n        \"ldr\tr2, [%[a], #320]\\n\\t\"\n        \"ldr\tr3, [%[a], #324]\\n\\t\"\n        \"ldr\tr4, [%[a], #328]\\n\\t\"\n        \"ldr\tr5, [%[a], #332]\\n\\t\"\n        \"ldr\tr6, [%[b], #320]\\n\\t\"\n        \"ldr\tr7, [%[b], #324]\\n\\t\"\n        \"ldr\tr8, [%[b], #328]\\n\\t\"\n        \"ldr\tr9, [%[b], #332]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #320]\\n\\t\"\n        \"str\tr3, [%[a], #324]\\n\\t\"\n        \"str\tr4, [%[a], #328]\\n\\t\"\n        \"str\tr5, [%[a], #332]\\n\\t\"\n        \"ldr\tr2, [%[a], #336]\\n\\t\"\n        \"ldr\tr3, [%[a], #340]\\n\\t\"\n        \"ldr\tr4, [%[a], #344]\\n\\t\"\n        \"ldr\tr5, [%[a], #348]\\n\\t\"\n        \"ldr\tr6, [%[b], #336]\\n\\t\"\n        \"ldr\tr7, [%[b], #340]\\n\\t\"\n        \"ldr\tr8, [%[b], #344]\\n\\t\"\n        \"ldr\tr9, [%[b], #348]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #336]\\n\\t\"\n        \"str\tr3, [%[a], #340]\\n\\t\"\n        \"str\tr4, [%[a], #344]\\n\\t\"\n        \"str\tr5, [%[a], #348]\\n\\t\"\n        \"ldr\tr2, [%[a], #352]\\n\\t\"\n        \"ldr\tr3, [%[a], #356]\\n\\t\"\n        \"ldr\tr4, [%[a], #360]\\n\\t\"\n        \"ldr\tr5, [%[a], #364]\\n\\t\"\n        \"ldr\tr6, [%[b], #352]\\n\\t\"\n        \"ldr\tr7, [%[b], #356]\\n\\t\"\n        \"ldr\tr8, [%[b], #360]\\n\\t\"\n        \"ldr\tr9, [%[b], #364]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #352]\\n\\t\"\n        \"str\tr3, [%[a], #356]\\n\\t\"\n        \"str\tr4, [%[a], #360]\\n\\t\"\n        \"str\tr5, [%[a], #364]\\n\\t\"\n        \"ldr\tr2, [%[a], #368]\\n\\t\"\n        \"ldr\tr3, [%[a], #372]\\n\\t\"\n        \"ldr\tr4, [%[a], #376]\\n\\t\"\n        \"ldr\tr5, [%[a], #380]\\n\\t\"\n        \"ldr\tr6, [%[b], #368]\\n\\t\"\n        \"ldr\tr7, [%[b], #372]\\n\\t\"\n        \"ldr\tr8, [%[b], #376]\\n\\t\"\n        \"ldr\tr9, [%[b], #380]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #368]\\n\\t\"\n        \"str\tr3, [%[a], #372]\\n\\t\"\n        \"str\tr4, [%[a], #376]\\n\\t\"\n        \"str\tr5, [%[a], #380]\\n\\t\"\n        \"ldr\tr2, [%[a], #384]\\n\\t\"\n        \"ldr\tr3, [%[a], #388]\\n\\t\"\n        \"ldr\tr4, [%[a], #392]\\n\\t\"\n        \"ldr\tr5, [%[a], #396]\\n\\t\"\n        \"ldr\tr6, [%[b], #384]\\n\\t\"\n        \"ldr\tr7, [%[b], #388]\\n\\t\"\n        \"ldr\tr8, [%[b], #392]\\n\\t\"\n        \"ldr\tr9, [%[b], #396]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #384]\\n\\t\"\n        \"str\tr3, [%[a], #388]\\n\\t\"\n        \"str\tr4, [%[a], #392]\\n\\t\"\n        \"str\tr5, [%[a], #396]\\n\\t\"\n        \"ldr\tr2, [%[a], #400]\\n\\t\"\n        \"ldr\tr3, [%[a], #404]\\n\\t\"\n        \"ldr\tr4, [%[a], #408]\\n\\t\"\n        \"ldr\tr5, [%[a], #412]\\n\\t\"\n        \"ldr\tr6, [%[b], #400]\\n\\t\"\n        \"ldr\tr7, [%[b], #404]\\n\\t\"\n        \"ldr\tr8, [%[b], #408]\\n\\t\"\n        \"ldr\tr9, [%[b], #412]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #400]\\n\\t\"\n        \"str\tr3, [%[a], #404]\\n\\t\"\n        \"str\tr4, [%[a], #408]\\n\\t\"\n        \"str\tr5, [%[a], #412]\\n\\t\"\n        \"ldr\tr2, [%[a], #416]\\n\\t\"\n        \"ldr\tr3, [%[a], #420]\\n\\t\"\n        \"ldr\tr4, [%[a], #424]\\n\\t\"\n        \"ldr\tr5, [%[a], #428]\\n\\t\"\n        \"ldr\tr6, [%[b], #416]\\n\\t\"\n        \"ldr\tr7, [%[b], #420]\\n\\t\"\n        \"ldr\tr8, [%[b], #424]\\n\\t\"\n        \"ldr\tr9, [%[b], #428]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #416]\\n\\t\"\n        \"str\tr3, [%[a], #420]\\n\\t\"\n        \"str\tr4, [%[a], #424]\\n\\t\"\n        \"str\tr5, [%[a], #428]\\n\\t\"\n        \"ldr\tr2, [%[a], #432]\\n\\t\"\n        \"ldr\tr3, [%[a], #436]\\n\\t\"\n        \"ldr\tr4, [%[a], #440]\\n\\t\"\n        \"ldr\tr5, [%[a], #444]\\n\\t\"\n        \"ldr\tr6, [%[b], #432]\\n\\t\"\n        \"ldr\tr7, [%[b], #436]\\n\\t\"\n        \"ldr\tr8, [%[b], #440]\\n\\t\"\n        \"ldr\tr9, [%[b], #444]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #432]\\n\\t\"\n        \"str\tr3, [%[a], #436]\\n\\t\"\n        \"str\tr4, [%[a], #440]\\n\\t\"\n        \"str\tr5, [%[a], #444]\\n\\t\"\n        \"ldr\tr2, [%[a], #448]\\n\\t\"\n        \"ldr\tr3, [%[a], #452]\\n\\t\"\n        \"ldr\tr4, [%[a], #456]\\n\\t\"\n        \"ldr\tr5, [%[a], #460]\\n\\t\"\n        \"ldr\tr6, [%[b], #448]\\n\\t\"\n        \"ldr\tr7, [%[b], #452]\\n\\t\"\n        \"ldr\tr8, [%[b], #456]\\n\\t\"\n        \"ldr\tr9, [%[b], #460]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #448]\\n\\t\"\n        \"str\tr3, [%[a], #452]\\n\\t\"\n        \"str\tr4, [%[a], #456]\\n\\t\"\n        \"str\tr5, [%[a], #460]\\n\\t\"\n        \"ldr\tr2, [%[a], #464]\\n\\t\"\n        \"ldr\tr3, [%[a], #468]\\n\\t\"\n        \"ldr\tr4, [%[a], #472]\\n\\t\"\n        \"ldr\tr5, [%[a], #476]\\n\\t\"\n        \"ldr\tr6, [%[b], #464]\\n\\t\"\n        \"ldr\tr7, [%[b], #468]\\n\\t\"\n        \"ldr\tr8, [%[b], #472]\\n\\t\"\n        \"ldr\tr9, [%[b], #476]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #464]\\n\\t\"\n        \"str\tr3, [%[a], #468]\\n\\t\"\n        \"str\tr4, [%[a], #472]\\n\\t\"\n        \"str\tr5, [%[a], #476]\\n\\t\"\n        \"ldr\tr2, [%[a], #480]\\n\\t\"\n        \"ldr\tr3, [%[a], #484]\\n\\t\"\n        \"ldr\tr4, [%[a], #488]\\n\\t\"\n        \"ldr\tr5, [%[a], #492]\\n\\t\"\n        \"ldr\tr6, [%[b], #480]\\n\\t\"\n        \"ldr\tr7, [%[b], #484]\\n\\t\"\n        \"ldr\tr8, [%[b], #488]\\n\\t\"\n        \"ldr\tr9, [%[b], #492]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #480]\\n\\t\"\n        \"str\tr3, [%[a], #484]\\n\\t\"\n        \"str\tr4, [%[a], #488]\\n\\t\"\n        \"str\tr5, [%[a], #492]\\n\\t\"\n        \"ldr\tr2, [%[a], #496]\\n\\t\"\n        \"ldr\tr3, [%[a], #500]\\n\\t\"\n        \"ldr\tr4, [%[a], #504]\\n\\t\"\n        \"ldr\tr5, [%[a], #508]\\n\\t\"\n        \"ldr\tr6, [%[b], #496]\\n\\t\"\n        \"ldr\tr7, [%[b], #500]\\n\\t\"\n        \"ldr\tr8, [%[b], #504]\\n\\t\"\n        \"ldr\tr9, [%[b], #508]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #496]\\n\\t\"\n        \"str\tr3, [%[a], #500]\\n\\t\"\n        \"str\tr4, [%[a], #504]\\n\\t\"\n        \"str\tr5, [%[a], #508]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[a], #4]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[b], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"ldr\tr10, [%[b], #8]\\n\\t\"\n        \"ldr\tr14, [%[b], #12]\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr5, [%[r], #4]\\n\\t\"\n        \"str\tr6, [%[r], #8]\\n\\t\"\n        \"str\tr7, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[a], #20]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[b], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"ldr\tr10, [%[b], #24]\\n\\t\"\n        \"ldr\tr14, [%[b], #28]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"str\tr6, [%[r], #24]\\n\\t\"\n        \"str\tr7, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[a], #36]\\n\\t\"\n        \"ldr\tr6, [%[a], #40]\\n\\t\"\n        \"ldr\tr7, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[b], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"ldr\tr10, [%[b], #40]\\n\\t\"\n        \"ldr\tr14, [%[b], #44]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr5, [%[r], #36]\\n\\t\"\n        \"str\tr6, [%[r], #40]\\n\\t\"\n        \"str\tr7, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[a], #52]\\n\\t\"\n        \"ldr\tr6, [%[a], #56]\\n\\t\"\n        \"ldr\tr7, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[b], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"ldr\tr10, [%[b], #56]\\n\\t\"\n        \"ldr\tr14, [%[b], #60]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"str\tr5, [%[r], #52]\\n\\t\"\n        \"str\tr6, [%[r], #56]\\n\\t\"\n        \"str\tr7, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[a], #68]\\n\\t\"\n        \"ldr\tr6, [%[a], #72]\\n\\t\"\n        \"ldr\tr7, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[b], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"ldr\tr10, [%[b], #72]\\n\\t\"\n        \"ldr\tr14, [%[b], #76]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"str\tr5, [%[r], #68]\\n\\t\"\n        \"str\tr6, [%[r], #72]\\n\\t\"\n        \"str\tr7, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[a], #84]\\n\\t\"\n        \"ldr\tr6, [%[a], #88]\\n\\t\"\n        \"ldr\tr7, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[b], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"ldr\tr10, [%[b], #88]\\n\\t\"\n        \"ldr\tr14, [%[b], #92]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"str\tr5, [%[r], #84]\\n\\t\"\n        \"str\tr6, [%[r], #88]\\n\\t\"\n        \"str\tr7, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[a], #100]\\n\\t\"\n        \"ldr\tr6, [%[a], #104]\\n\\t\"\n        \"ldr\tr7, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[b], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"ldr\tr10, [%[b], #104]\\n\\t\"\n        \"ldr\tr14, [%[b], #108]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"str\tr5, [%[r], #100]\\n\\t\"\n        \"str\tr6, [%[r], #104]\\n\\t\"\n        \"str\tr7, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[a], #116]\\n\\t\"\n        \"ldr\tr6, [%[a], #120]\\n\\t\"\n        \"ldr\tr7, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[b], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"ldr\tr10, [%[b], #120]\\n\\t\"\n        \"ldr\tr14, [%[b], #124]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"str\tr5, [%[r], #116]\\n\\t\"\n        \"str\tr6, [%[r], #120]\\n\\t\"\n        \"str\tr7, [%[r], #124]\\n\\t\"\n        \"ldr\tr4, [%[a], #128]\\n\\t\"\n        \"ldr\tr5, [%[a], #132]\\n\\t\"\n        \"ldr\tr6, [%[a], #136]\\n\\t\"\n        \"ldr\tr7, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[b], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"ldr\tr10, [%[b], #136]\\n\\t\"\n        \"ldr\tr14, [%[b], #140]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #128]\\n\\t\"\n        \"str\tr5, [%[r], #132]\\n\\t\"\n        \"str\tr6, [%[r], #136]\\n\\t\"\n        \"str\tr7, [%[r], #140]\\n\\t\"\n        \"ldr\tr4, [%[a], #144]\\n\\t\"\n        \"ldr\tr5, [%[a], #148]\\n\\t\"\n        \"ldr\tr6, [%[a], #152]\\n\\t\"\n        \"ldr\tr7, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[b], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"ldr\tr10, [%[b], #152]\\n\\t\"\n        \"ldr\tr14, [%[b], #156]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #144]\\n\\t\"\n        \"str\tr5, [%[r], #148]\\n\\t\"\n        \"str\tr6, [%[r], #152]\\n\\t\"\n        \"str\tr7, [%[r], #156]\\n\\t\"\n        \"ldr\tr4, [%[a], #160]\\n\\t\"\n        \"ldr\tr5, [%[a], #164]\\n\\t\"\n        \"ldr\tr6, [%[a], #168]\\n\\t\"\n        \"ldr\tr7, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[b], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"ldr\tr10, [%[b], #168]\\n\\t\"\n        \"ldr\tr14, [%[b], #172]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"str\tr5, [%[r], #164]\\n\\t\"\n        \"str\tr6, [%[r], #168]\\n\\t\"\n        \"str\tr7, [%[r], #172]\\n\\t\"\n        \"ldr\tr4, [%[a], #176]\\n\\t\"\n        \"ldr\tr5, [%[a], #180]\\n\\t\"\n        \"ldr\tr6, [%[a], #184]\\n\\t\"\n        \"ldr\tr7, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[b], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"ldr\tr10, [%[b], #184]\\n\\t\"\n        \"ldr\tr14, [%[b], #188]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #176]\\n\\t\"\n        \"str\tr5, [%[r], #180]\\n\\t\"\n        \"str\tr6, [%[r], #184]\\n\\t\"\n        \"str\tr7, [%[r], #188]\\n\\t\"\n        \"ldr\tr4, [%[a], #192]\\n\\t\"\n        \"ldr\tr5, [%[a], #196]\\n\\t\"\n        \"ldr\tr6, [%[a], #200]\\n\\t\"\n        \"ldr\tr7, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[b], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"ldr\tr10, [%[b], #200]\\n\\t\"\n        \"ldr\tr14, [%[b], #204]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #192]\\n\\t\"\n        \"str\tr5, [%[r], #196]\\n\\t\"\n        \"str\tr6, [%[r], #200]\\n\\t\"\n        \"str\tr7, [%[r], #204]\\n\\t\"\n        \"ldr\tr4, [%[a], #208]\\n\\t\"\n        \"ldr\tr5, [%[a], #212]\\n\\t\"\n        \"ldr\tr6, [%[a], #216]\\n\\t\"\n        \"ldr\tr7, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[b], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"ldr\tr10, [%[b], #216]\\n\\t\"\n        \"ldr\tr14, [%[b], #220]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #208]\\n\\t\"\n        \"str\tr5, [%[r], #212]\\n\\t\"\n        \"str\tr6, [%[r], #216]\\n\\t\"\n        \"str\tr7, [%[r], #220]\\n\\t\"\n        \"ldr\tr4, [%[a], #224]\\n\\t\"\n        \"ldr\tr5, [%[a], #228]\\n\\t\"\n        \"ldr\tr6, [%[a], #232]\\n\\t\"\n        \"ldr\tr7, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[b], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"ldr\tr10, [%[b], #232]\\n\\t\"\n        \"ldr\tr14, [%[b], #236]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #224]\\n\\t\"\n        \"str\tr5, [%[r], #228]\\n\\t\"\n        \"str\tr6, [%[r], #232]\\n\\t\"\n        \"str\tr7, [%[r], #236]\\n\\t\"\n        \"ldr\tr4, [%[a], #240]\\n\\t\"\n        \"ldr\tr5, [%[a], #244]\\n\\t\"\n        \"ldr\tr6, [%[a], #248]\\n\\t\"\n        \"ldr\tr7, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[b], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"ldr\tr10, [%[b], #248]\\n\\t\"\n        \"ldr\tr14, [%[b], #252]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #240]\\n\\t\"\n        \"str\tr5, [%[r], #244]\\n\\t\"\n        \"str\tr6, [%[r], #248]\\n\\t\"\n        \"str\tr7, [%[r], #252]\\n\\t\"\n        \"ldr\tr4, [%[a], #256]\\n\\t\"\n        \"ldr\tr5, [%[a], #260]\\n\\t\"\n        \"ldr\tr6, [%[a], #264]\\n\\t\"\n        \"ldr\tr7, [%[a], #268]\\n\\t\"\n        \"ldr\tr8, [%[b], #256]\\n\\t\"\n        \"ldr\tr9, [%[b], #260]\\n\\t\"\n        \"ldr\tr10, [%[b], #264]\\n\\t\"\n        \"ldr\tr14, [%[b], #268]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #256]\\n\\t\"\n        \"str\tr5, [%[r], #260]\\n\\t\"\n        \"str\tr6, [%[r], #264]\\n\\t\"\n        \"str\tr7, [%[r], #268]\\n\\t\"\n        \"ldr\tr4, [%[a], #272]\\n\\t\"\n        \"ldr\tr5, [%[a], #276]\\n\\t\"\n        \"ldr\tr6, [%[a], #280]\\n\\t\"\n        \"ldr\tr7, [%[a], #284]\\n\\t\"\n        \"ldr\tr8, [%[b], #272]\\n\\t\"\n        \"ldr\tr9, [%[b], #276]\\n\\t\"\n        \"ldr\tr10, [%[b], #280]\\n\\t\"\n        \"ldr\tr14, [%[b], #284]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #272]\\n\\t\"\n        \"str\tr5, [%[r], #276]\\n\\t\"\n        \"str\tr6, [%[r], #280]\\n\\t\"\n        \"str\tr7, [%[r], #284]\\n\\t\"\n        \"ldr\tr4, [%[a], #288]\\n\\t\"\n        \"ldr\tr5, [%[a], #292]\\n\\t\"\n        \"ldr\tr6, [%[a], #296]\\n\\t\"\n        \"ldr\tr7, [%[a], #300]\\n\\t\"\n        \"ldr\tr8, [%[b], #288]\\n\\t\"\n        \"ldr\tr9, [%[b], #292]\\n\\t\"\n        \"ldr\tr10, [%[b], #296]\\n\\t\"\n        \"ldr\tr14, [%[b], #300]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #288]\\n\\t\"\n        \"str\tr5, [%[r], #292]\\n\\t\"\n        \"str\tr6, [%[r], #296]\\n\\t\"\n        \"str\tr7, [%[r], #300]\\n\\t\"\n        \"ldr\tr4, [%[a], #304]\\n\\t\"\n        \"ldr\tr5, [%[a], #308]\\n\\t\"\n        \"ldr\tr6, [%[a], #312]\\n\\t\"\n        \"ldr\tr7, [%[a], #316]\\n\\t\"\n        \"ldr\tr8, [%[b], #304]\\n\\t\"\n        \"ldr\tr9, [%[b], #308]\\n\\t\"\n        \"ldr\tr10, [%[b], #312]\\n\\t\"\n        \"ldr\tr14, [%[b], #316]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #304]\\n\\t\"\n        \"str\tr5, [%[r], #308]\\n\\t\"\n        \"str\tr6, [%[r], #312]\\n\\t\"\n        \"str\tr7, [%[r], #316]\\n\\t\"\n        \"ldr\tr4, [%[a], #320]\\n\\t\"\n        \"ldr\tr5, [%[a], #324]\\n\\t\"\n        \"ldr\tr6, [%[a], #328]\\n\\t\"\n        \"ldr\tr7, [%[a], #332]\\n\\t\"\n        \"ldr\tr8, [%[b], #320]\\n\\t\"\n        \"ldr\tr9, [%[b], #324]\\n\\t\"\n        \"ldr\tr10, [%[b], #328]\\n\\t\"\n        \"ldr\tr14, [%[b], #332]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #320]\\n\\t\"\n        \"str\tr5, [%[r], #324]\\n\\t\"\n        \"str\tr6, [%[r], #328]\\n\\t\"\n        \"str\tr7, [%[r], #332]\\n\\t\"\n        \"ldr\tr4, [%[a], #336]\\n\\t\"\n        \"ldr\tr5, [%[a], #340]\\n\\t\"\n        \"ldr\tr6, [%[a], #344]\\n\\t\"\n        \"ldr\tr7, [%[a], #348]\\n\\t\"\n        \"ldr\tr8, [%[b], #336]\\n\\t\"\n        \"ldr\tr9, [%[b], #340]\\n\\t\"\n        \"ldr\tr10, [%[b], #344]\\n\\t\"\n        \"ldr\tr14, [%[b], #348]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #336]\\n\\t\"\n        \"str\tr5, [%[r], #340]\\n\\t\"\n        \"str\tr6, [%[r], #344]\\n\\t\"\n        \"str\tr7, [%[r], #348]\\n\\t\"\n        \"ldr\tr4, [%[a], #352]\\n\\t\"\n        \"ldr\tr5, [%[a], #356]\\n\\t\"\n        \"ldr\tr6, [%[a], #360]\\n\\t\"\n        \"ldr\tr7, [%[a], #364]\\n\\t\"\n        \"ldr\tr8, [%[b], #352]\\n\\t\"\n        \"ldr\tr9, [%[b], #356]\\n\\t\"\n        \"ldr\tr10, [%[b], #360]\\n\\t\"\n        \"ldr\tr14, [%[b], #364]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #352]\\n\\t\"\n        \"str\tr5, [%[r], #356]\\n\\t\"\n        \"str\tr6, [%[r], #360]\\n\\t\"\n        \"str\tr7, [%[r], #364]\\n\\t\"\n        \"ldr\tr4, [%[a], #368]\\n\\t\"\n        \"ldr\tr5, [%[a], #372]\\n\\t\"\n        \"ldr\tr6, [%[a], #376]\\n\\t\"\n        \"ldr\tr7, [%[a], #380]\\n\\t\"\n        \"ldr\tr8, [%[b], #368]\\n\\t\"\n        \"ldr\tr9, [%[b], #372]\\n\\t\"\n        \"ldr\tr10, [%[b], #376]\\n\\t\"\n        \"ldr\tr14, [%[b], #380]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #368]\\n\\t\"\n        \"str\tr5, [%[r], #372]\\n\\t\"\n        \"str\tr6, [%[r], #376]\\n\\t\"\n        \"str\tr7, [%[r], #380]\\n\\t\"\n        \"ldr\tr4, [%[a], #384]\\n\\t\"\n        \"ldr\tr5, [%[a], #388]\\n\\t\"\n        \"ldr\tr6, [%[a], #392]\\n\\t\"\n        \"ldr\tr7, [%[a], #396]\\n\\t\"\n        \"ldr\tr8, [%[b], #384]\\n\\t\"\n        \"ldr\tr9, [%[b], #388]\\n\\t\"\n        \"ldr\tr10, [%[b], #392]\\n\\t\"\n        \"ldr\tr14, [%[b], #396]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #384]\\n\\t\"\n        \"str\tr5, [%[r], #388]\\n\\t\"\n        \"str\tr6, [%[r], #392]\\n\\t\"\n        \"str\tr7, [%[r], #396]\\n\\t\"\n        \"ldr\tr4, [%[a], #400]\\n\\t\"\n        \"ldr\tr5, [%[a], #404]\\n\\t\"\n        \"ldr\tr6, [%[a], #408]\\n\\t\"\n        \"ldr\tr7, [%[a], #412]\\n\\t\"\n        \"ldr\tr8, [%[b], #400]\\n\\t\"\n        \"ldr\tr9, [%[b], #404]\\n\\t\"\n        \"ldr\tr10, [%[b], #408]\\n\\t\"\n        \"ldr\tr14, [%[b], #412]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #400]\\n\\t\"\n        \"str\tr5, [%[r], #404]\\n\\t\"\n        \"str\tr6, [%[r], #408]\\n\\t\"\n        \"str\tr7, [%[r], #412]\\n\\t\"\n        \"ldr\tr4, [%[a], #416]\\n\\t\"\n        \"ldr\tr5, [%[a], #420]\\n\\t\"\n        \"ldr\tr6, [%[a], #424]\\n\\t\"\n        \"ldr\tr7, [%[a], #428]\\n\\t\"\n        \"ldr\tr8, [%[b], #416]\\n\\t\"\n        \"ldr\tr9, [%[b], #420]\\n\\t\"\n        \"ldr\tr10, [%[b], #424]\\n\\t\"\n        \"ldr\tr14, [%[b], #428]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #416]\\n\\t\"\n        \"str\tr5, [%[r], #420]\\n\\t\"\n        \"str\tr6, [%[r], #424]\\n\\t\"\n        \"str\tr7, [%[r], #428]\\n\\t\"\n        \"ldr\tr4, [%[a], #432]\\n\\t\"\n        \"ldr\tr5, [%[a], #436]\\n\\t\"\n        \"ldr\tr6, [%[a], #440]\\n\\t\"\n        \"ldr\tr7, [%[a], #444]\\n\\t\"\n        \"ldr\tr8, [%[b], #432]\\n\\t\"\n        \"ldr\tr9, [%[b], #436]\\n\\t\"\n        \"ldr\tr10, [%[b], #440]\\n\\t\"\n        \"ldr\tr14, [%[b], #444]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #432]\\n\\t\"\n        \"str\tr5, [%[r], #436]\\n\\t\"\n        \"str\tr6, [%[r], #440]\\n\\t\"\n        \"str\tr7, [%[r], #444]\\n\\t\"\n        \"ldr\tr4, [%[a], #448]\\n\\t\"\n        \"ldr\tr5, [%[a], #452]\\n\\t\"\n        \"ldr\tr6, [%[a], #456]\\n\\t\"\n        \"ldr\tr7, [%[a], #460]\\n\\t\"\n        \"ldr\tr8, [%[b], #448]\\n\\t\"\n        \"ldr\tr9, [%[b], #452]\\n\\t\"\n        \"ldr\tr10, [%[b], #456]\\n\\t\"\n        \"ldr\tr14, [%[b], #460]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #448]\\n\\t\"\n        \"str\tr5, [%[r], #452]\\n\\t\"\n        \"str\tr6, [%[r], #456]\\n\\t\"\n        \"str\tr7, [%[r], #460]\\n\\t\"\n        \"ldr\tr4, [%[a], #464]\\n\\t\"\n        \"ldr\tr5, [%[a], #468]\\n\\t\"\n        \"ldr\tr6, [%[a], #472]\\n\\t\"\n        \"ldr\tr7, [%[a], #476]\\n\\t\"\n        \"ldr\tr8, [%[b], #464]\\n\\t\"\n        \"ldr\tr9, [%[b], #468]\\n\\t\"\n        \"ldr\tr10, [%[b], #472]\\n\\t\"\n        \"ldr\tr14, [%[b], #476]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #464]\\n\\t\"\n        \"str\tr5, [%[r], #468]\\n\\t\"\n        \"str\tr6, [%[r], #472]\\n\\t\"\n        \"str\tr7, [%[r], #476]\\n\\t\"\n        \"ldr\tr4, [%[a], #480]\\n\\t\"\n        \"ldr\tr5, [%[a], #484]\\n\\t\"\n        \"ldr\tr6, [%[a], #488]\\n\\t\"\n        \"ldr\tr7, [%[a], #492]\\n\\t\"\n        \"ldr\tr8, [%[b], #480]\\n\\t\"\n        \"ldr\tr9, [%[b], #484]\\n\\t\"\n        \"ldr\tr10, [%[b], #488]\\n\\t\"\n        \"ldr\tr14, [%[b], #492]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #480]\\n\\t\"\n        \"str\tr5, [%[r], #484]\\n\\t\"\n        \"str\tr6, [%[r], #488]\\n\\t\"\n        \"str\tr7, [%[r], #492]\\n\\t\"\n        \"ldr\tr4, [%[a], #496]\\n\\t\"\n        \"ldr\tr5, [%[a], #500]\\n\\t\"\n        \"ldr\tr6, [%[a], #504]\\n\\t\"\n        \"ldr\tr7, [%[a], #508]\\n\\t\"\n        \"ldr\tr8, [%[b], #496]\\n\\t\"\n        \"ldr\tr9, [%[b], #500]\\n\\t\"\n        \"ldr\tr10, [%[b], #504]\\n\\t\"\n        \"ldr\tr14, [%[b], #508]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #496]\\n\\t\"\n        \"str\tr5, [%[r], #500]\\n\\t\"\n        \"str\tr6, [%[r], #504]\\n\\t\"\n        \"str\tr7, [%[r], #508]\\n\\t\"\n        \"adc\t%[c], r12, r12\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_4096_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #256\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        \"#  A[0] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr3, r4, r8, r9\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [sp]\\n\\t\"\n        \"#  A[0] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #4]\\n\\t\"\n        \"#  A[0] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #8]\\n\\t\"\n        \"#  A[0] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #12]\\n\\t\"\n        \"#  A[0] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #16]\\n\\t\"\n        \"#  A[0] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #20]\\n\\t\"\n        \"#  A[0] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #24]\\n\\t\"\n        \"#  A[0] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #28]\\n\\t\"\n        \"#  A[0] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #32]\\n\\t\"\n        \"#  A[0] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #36]\\n\\t\"\n        \"#  A[0] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #40]\\n\\t\"\n        \"#  A[0] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #44]\\n\\t\"\n        \"#  A[0] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #48]\\n\\t\"\n        \"#  A[0] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #52]\\n\\t\"\n        \"#  A[0] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #56]\\n\\t\"\n        \"#  A[0] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #60]\\n\\t\"\n        \"#  A[0] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #64]\\n\\t\"\n        \"#  A[0] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #68]\\n\\t\"\n        \"#  A[0] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #72]\\n\\t\"\n        \"#  A[0] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #76]\\n\\t\"\n        \"#  A[0] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #80]\\n\\t\"\n        \"#  A[0] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #84]\\n\\t\"\n        \"#  A[0] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #88]\\n\\t\"\n        \"#  A[0] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #92]\\n\\t\"\n        \"#  A[0] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #96]\\n\\t\"\n        \"#  A[0] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #100]\\n\\t\"\n        \"#  A[0] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #104]\\n\\t\"\n        \"#  A[0] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #108]\\n\\t\"\n        \"#  A[0] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #112]\\n\\t\"\n        \"#  A[0] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #116]\\n\\t\"\n        \"#  A[0] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #120]\\n\\t\"\n        \"#  A[0] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #124]\\n\\t\"\n        \"#  A[0] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #128]\\n\\t\"\n        \"#  A[0] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #132]\\n\\t\"\n        \"#  A[0] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #136]\\n\\t\"\n        \"#  A[0] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #140]\\n\\t\"\n        \"#  A[0] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #144]\\n\\t\"\n        \"#  A[0] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #148]\\n\\t\"\n        \"#  A[0] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #152]\\n\\t\"\n        \"#  A[0] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #156]\\n\\t\"\n        \"#  A[0] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #160]\\n\\t\"\n        \"#  A[0] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #164]\\n\\t\"\n        \"#  A[0] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #168]\\n\\t\"\n        \"#  A[0] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #172]\\n\\t\"\n        \"#  A[0] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #176]\\n\\t\"\n        \"#  A[0] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #180]\\n\\t\"\n        \"#  A[0] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #184]\\n\\t\"\n        \"#  A[0] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #188]\\n\\t\"\n        \"#  A[0] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #192]\\n\\t\"\n        \"#  A[0] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #196]\\n\\t\"\n        \"#  A[0] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #200]\\n\\t\"\n        \"#  A[0] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #204]\\n\\t\"\n        \"#  A[0] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #208]\\n\\t\"\n        \"#  A[0] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #212]\\n\\t\"\n        \"#  A[0] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #216]\\n\\t\"\n        \"#  A[0] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #220]\\n\\t\"\n        \"#  A[0] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #224]\\n\\t\"\n        \"#  A[0] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #228]\\n\\t\"\n        \"#  A[0] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #232]\\n\\t\"\n        \"#  A[0] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #236]\\n\\t\"\n        \"#  A[0] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #240]\\n\\t\"\n        \"#  A[0] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #244]\\n\\t\"\n        \"#  A[0] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #248]\\n\\t\"\n        \"#  A[0] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #252]\\n\\t\"\n        \"#  A[1] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[2] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #256]\\n\\t\"\n        \"#  A[2] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[3] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #260]\\n\\t\"\n        \"#  A[3] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[4] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #264]\\n\\t\"\n        \"#  A[4] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[5] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[8] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #268]\\n\\t\"\n        \"#  A[5] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[6] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[8] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[9] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #272]\\n\\t\"\n        \"#  A[6] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[7] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[8] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[9] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[10] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #276]\\n\\t\"\n        \"#  A[7] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[8] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[9] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[10] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[11] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #280]\\n\\t\"\n        \"#  A[8] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[9] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[10] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[11] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[12] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[8]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #284]\\n\\t\"\n        \"#  A[9] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[10] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[11] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[12] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[13] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[9]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #288]\\n\\t\"\n        \"#  A[10] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[11] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[12] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[13] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[14] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[10]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #292]\\n\\t\"\n        \"#  A[11] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[12] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[13] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[14] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[15] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[11]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #296]\\n\\t\"\n        \"#  A[12] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[13] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[14] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[15] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[16] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[12]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #300]\\n\\t\"\n        \"#  A[13] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[14] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[15] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[16] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[17] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[13]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #304]\\n\\t\"\n        \"#  A[14] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[15] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[16] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[17] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[18] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[14]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #308]\\n\\t\"\n        \"#  A[15] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[16] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[17] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[18] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[19] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[15]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #312]\\n\\t\"\n        \"#  A[16] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[17] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[18] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[19] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[20] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[16]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #316]\\n\\t\"\n        \"#  A[17] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[18] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[19] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[20] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[21] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[17]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #320]\\n\\t\"\n        \"#  A[18] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[19] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[20] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[21] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[22] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[18]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #324]\\n\\t\"\n        \"#  A[19] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[20] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[21] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[22] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[23] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[19]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #328]\\n\\t\"\n        \"#  A[20] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[21] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[22] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[23] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[24] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[20]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #332]\\n\\t\"\n        \"#  A[21] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[22] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[23] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[24] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[25] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[21]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #336]\\n\\t\"\n        \"#  A[22] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[23] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[24] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[25] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[26] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[22]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #340]\\n\\t\"\n        \"#  A[23] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[24] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[25] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[26] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[27] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[23]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #344]\\n\\t\"\n        \"#  A[24] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[25] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[26] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[27] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[28] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[24]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #348]\\n\\t\"\n        \"#  A[25] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[26] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[27] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[28] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[29] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[25]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #352]\\n\\t\"\n        \"#  A[26] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[27] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[28] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[29] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[30] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[26]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #356]\\n\\t\"\n        \"#  A[27] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[28] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[29] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[30] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[31] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[27]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #360]\\n\\t\"\n        \"#  A[28] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[29] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[30] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[31] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[32] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[28]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #364]\\n\\t\"\n        \"#  A[29] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[30] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[31] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[32] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[33] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[29]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #368]\\n\\t\"\n        \"#  A[30] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[31] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[32] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[33] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[34] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[30]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #372]\\n\\t\"\n        \"#  A[31] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[32] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[33] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[34] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[35] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[31]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #376]\\n\\t\"\n        \"#  A[32] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[33] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[34] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[35] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[36] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[32]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #380]\\n\\t\"\n        \"#  A[33] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[34] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[35] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[36] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[37] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[33]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #384]\\n\\t\"\n        \"#  A[34] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[35] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[36] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[37] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[38] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[34]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #388]\\n\\t\"\n        \"#  A[35] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[36] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[37] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[38] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[39] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[35]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #392]\\n\\t\"\n        \"#  A[36] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[37] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[38] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[39] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[40] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[36]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #396]\\n\\t\"\n        \"#  A[37] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[38] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[39] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[40] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[41] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[37]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #400]\\n\\t\"\n        \"#  A[38] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[39] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[40] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[41] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[42] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[38]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #404]\\n\\t\"\n        \"#  A[39] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[40] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[41] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[42] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[43] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[39]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #408]\\n\\t\"\n        \"#  A[40] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[41] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[42] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[43] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[44] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[40]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #412]\\n\\t\"\n        \"#  A[41] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[42] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[43] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[44] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[45] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[41]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #416]\\n\\t\"\n        \"#  A[42] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[43] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[44] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[45] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[46] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[42]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #420]\\n\\t\"\n        \"#  A[43] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[44] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[45] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[46] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[47] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[43]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #424]\\n\\t\"\n        \"#  A[44] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[45] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[46] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[47] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[48] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[44]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #428]\\n\\t\"\n        \"#  A[45] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[46] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[47] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[48] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[49] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[45]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #432]\\n\\t\"\n        \"#  A[46] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[47] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[48] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[49] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[50] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[46]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #436]\\n\\t\"\n        \"#  A[47] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[48] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[49] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[50] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[51] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[47]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #440]\\n\\t\"\n        \"#  A[48] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[49] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[50] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[51] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[52] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[48]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #444]\\n\\t\"\n        \"#  A[49] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[50] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[51] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[52] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[53] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[49]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #448]\\n\\t\"\n        \"#  A[50] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[51] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[52] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[53] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[54] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[50]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #452]\\n\\t\"\n        \"#  A[51] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[52] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[53] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[54] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[55] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[51]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #456]\\n\\t\"\n        \"#  A[52] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[53] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[54] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[55] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[56] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[52]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #460]\\n\\t\"\n        \"#  A[53] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[54] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[55] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[56] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[57] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[53]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #464]\\n\\t\"\n        \"#  A[54] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[55] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[56] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[57] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[58] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[54]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #468]\\n\\t\"\n        \"#  A[55] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[56] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[57] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[58] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[59] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[55]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #472]\\n\\t\"\n        \"#  A[56] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[57] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[58] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[59] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[60] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[56]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #476]\\n\\t\"\n        \"#  A[57] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[58] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[59] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[60] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[61] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[57]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #480]\\n\\t\"\n        \"#  A[58] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[59] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[60] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[61] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[62] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[58]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #484]\\n\\t\"\n        \"#  A[59] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[60] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[61] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[62] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[63] * B[59]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #488]\\n\\t\"\n        \"#  A[60] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[61] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[62] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[63] * B[60]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #492]\\n\\t\"\n        \"#  A[61] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[62] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[63] * B[61]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #496]\\n\\t\"\n        \"#  A[62] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[63] * B[62]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #500]\\n\\t\"\n        \"#  A[63] * B[63]\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"ldr\tr9, [%[b], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr3, [%[r], #504]\\n\\t\"\n        \"str\tr4, [%[r], #508]\\n\\t\"\n        \"ldr\tr3, [sp, #0]\\n\\t\"\n        \"ldr\tr4, [sp, #4]\\n\\t\"\n        \"ldr\tr5, [sp, #8]\\n\\t\"\n        \"ldr\tr6, [sp, #12]\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [sp, #16]\\n\\t\"\n        \"ldr\tr4, [sp, #20]\\n\\t\"\n        \"ldr\tr5, [sp, #24]\\n\\t\"\n        \"ldr\tr6, [sp, #28]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"str\tr5, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        \"ldr\tr3, [sp, #32]\\n\\t\"\n        \"ldr\tr4, [sp, #36]\\n\\t\"\n        \"ldr\tr5, [sp, #40]\\n\\t\"\n        \"ldr\tr6, [sp, #44]\\n\\t\"\n        \"str\tr3, [%[r], #32]\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"str\tr5, [%[r], #40]\\n\\t\"\n        \"str\tr6, [%[r], #44]\\n\\t\"\n        \"ldr\tr3, [sp, #48]\\n\\t\"\n        \"ldr\tr4, [sp, #52]\\n\\t\"\n        \"ldr\tr5, [sp, #56]\\n\\t\"\n        \"ldr\tr6, [sp, #60]\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"str\tr5, [%[r], #56]\\n\\t\"\n        \"str\tr6, [%[r], #60]\\n\\t\"\n        \"ldr\tr3, [sp, #64]\\n\\t\"\n        \"ldr\tr4, [sp, #68]\\n\\t\"\n        \"ldr\tr5, [sp, #72]\\n\\t\"\n        \"ldr\tr6, [sp, #76]\\n\\t\"\n        \"str\tr3, [%[r], #64]\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"str\tr5, [%[r], #72]\\n\\t\"\n        \"str\tr6, [%[r], #76]\\n\\t\"\n        \"ldr\tr3, [sp, #80]\\n\\t\"\n        \"ldr\tr4, [sp, #84]\\n\\t\"\n        \"ldr\tr5, [sp, #88]\\n\\t\"\n        \"ldr\tr6, [sp, #92]\\n\\t\"\n        \"str\tr3, [%[r], #80]\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"str\tr5, [%[r], #88]\\n\\t\"\n        \"str\tr6, [%[r], #92]\\n\\t\"\n        \"ldr\tr3, [sp, #96]\\n\\t\"\n        \"ldr\tr4, [sp, #100]\\n\\t\"\n        \"ldr\tr5, [sp, #104]\\n\\t\"\n        \"ldr\tr6, [sp, #108]\\n\\t\"\n        \"str\tr3, [%[r], #96]\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"str\tr5, [%[r], #104]\\n\\t\"\n        \"str\tr6, [%[r], #108]\\n\\t\"\n        \"ldr\tr3, [sp, #112]\\n\\t\"\n        \"ldr\tr4, [sp, #116]\\n\\t\"\n        \"ldr\tr5, [sp, #120]\\n\\t\"\n        \"ldr\tr6, [sp, #124]\\n\\t\"\n        \"str\tr3, [%[r], #112]\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"str\tr5, [%[r], #120]\\n\\t\"\n        \"str\tr6, [%[r], #124]\\n\\t\"\n        \"ldr\tr3, [sp, #128]\\n\\t\"\n        \"ldr\tr4, [sp, #132]\\n\\t\"\n        \"ldr\tr5, [sp, #136]\\n\\t\"\n        \"ldr\tr6, [sp, #140]\\n\\t\"\n        \"str\tr3, [%[r], #128]\\n\\t\"\n        \"str\tr4, [%[r], #132]\\n\\t\"\n        \"str\tr5, [%[r], #136]\\n\\t\"\n        \"str\tr6, [%[r], #140]\\n\\t\"\n        \"ldr\tr3, [sp, #144]\\n\\t\"\n        \"ldr\tr4, [sp, #148]\\n\\t\"\n        \"ldr\tr5, [sp, #152]\\n\\t\"\n        \"ldr\tr6, [sp, #156]\\n\\t\"\n        \"str\tr3, [%[r], #144]\\n\\t\"\n        \"str\tr4, [%[r], #148]\\n\\t\"\n        \"str\tr5, [%[r], #152]\\n\\t\"\n        \"str\tr6, [%[r], #156]\\n\\t\"\n        \"ldr\tr3, [sp, #160]\\n\\t\"\n        \"ldr\tr4, [sp, #164]\\n\\t\"\n        \"ldr\tr5, [sp, #168]\\n\\t\"\n        \"ldr\tr6, [sp, #172]\\n\\t\"\n        \"str\tr3, [%[r], #160]\\n\\t\"\n        \"str\tr4, [%[r], #164]\\n\\t\"\n        \"str\tr5, [%[r], #168]\\n\\t\"\n        \"str\tr6, [%[r], #172]\\n\\t\"\n        \"ldr\tr3, [sp, #176]\\n\\t\"\n        \"ldr\tr4, [sp, #180]\\n\\t\"\n        \"ldr\tr5, [sp, #184]\\n\\t\"\n        \"ldr\tr6, [sp, #188]\\n\\t\"\n        \"str\tr3, [%[r], #176]\\n\\t\"\n        \"str\tr4, [%[r], #180]\\n\\t\"\n        \"str\tr5, [%[r], #184]\\n\\t\"\n        \"str\tr6, [%[r], #188]\\n\\t\"\n        \"ldr\tr3, [sp, #192]\\n\\t\"\n        \"ldr\tr4, [sp, #196]\\n\\t\"\n        \"ldr\tr5, [sp, #200]\\n\\t\"\n        \"ldr\tr6, [sp, #204]\\n\\t\"\n        \"str\tr3, [%[r], #192]\\n\\t\"\n        \"str\tr4, [%[r], #196]\\n\\t\"\n        \"str\tr5, [%[r], #200]\\n\\t\"\n        \"str\tr6, [%[r], #204]\\n\\t\"\n        \"ldr\tr3, [sp, #208]\\n\\t\"\n        \"ldr\tr4, [sp, #212]\\n\\t\"\n        \"ldr\tr5, [sp, #216]\\n\\t\"\n        \"ldr\tr6, [sp, #220]\\n\\t\"\n        \"str\tr3, [%[r], #208]\\n\\t\"\n        \"str\tr4, [%[r], #212]\\n\\t\"\n        \"str\tr5, [%[r], #216]\\n\\t\"\n        \"str\tr6, [%[r], #220]\\n\\t\"\n        \"ldr\tr3, [sp, #224]\\n\\t\"\n        \"ldr\tr4, [sp, #228]\\n\\t\"\n        \"ldr\tr5, [sp, #232]\\n\\t\"\n        \"ldr\tr6, [sp, #236]\\n\\t\"\n        \"str\tr3, [%[r], #224]\\n\\t\"\n        \"str\tr4, [%[r], #228]\\n\\t\"\n        \"str\tr5, [%[r], #232]\\n\\t\"\n        \"str\tr6, [%[r], #236]\\n\\t\"\n        \"ldr\tr3, [sp, #240]\\n\\t\"\n        \"ldr\tr4, [sp, #244]\\n\\t\"\n        \"ldr\tr5, [sp, #248]\\n\\t\"\n        \"ldr\tr6, [sp, #252]\\n\\t\"\n        \"str\tr3, [%[r], #240]\\n\\t\"\n        \"str\tr4, [%[r], #244]\\n\\t\"\n        \"str\tr5, [%[r], #248]\\n\\t\"\n        \"str\tr6, [%[r], #252]\\n\\t\"\n        \"add\tsp, sp, #256\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_4096_mask_64(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<64; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_128(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[128];\n    sp_digit a1[64];\n    sp_digit b1[64];\n    sp_digit z2[128];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_64(a1, a, &a[64]);\n    cb = sp_2048_add_64(b1, b, &b[64]);\n    u  = ca & cb;\n    sp_2048_mul_64(z1, a1, b1);\n    sp_2048_mul_64(z2, &a[64], &b[64]);\n    sp_2048_mul_64(z0, a, b);\n    sp_2048_mask_64(r + 128, a1, 0 - cb);\n    sp_2048_mask_64(b1, b1, 0 - ca);\n    u += sp_2048_add_64(r + 128, r + 128, b1);\n    u += sp_4096_sub_in_place_128(z1, z2);\n    u += sp_4096_sub_in_place_128(z1, z0);\n    u += sp_4096_add_128(r + 64, r + 64, z1);\n    r[192] = u;\n    XMEMSET(r + 192 + 1, 0, sizeof(sp_digit) * (64 - 1));\n    (void)sp_4096_add_128(r + 128, r + 128, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_4096_sqr_64(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #256\\n\\t\"\n        \"mov\tr14, #0\\n\\t\"\n        \"#  A[0] * A[0]\\n\\t\"\n        \"ldr\tr10, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r3, r10, r10\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr8, [sp]\\n\\t\"\n        \"#  A[0] * A[1]\\n\\t\"\n        \"ldr\tr10, [%[a], #4]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [sp, #4]\\n\\t\"\n        \"#  A[0] * A[2]\\n\\t\"\n        \"ldr\tr10, [%[a], #8]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r14, r14\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"#  A[1] * A[1]\\n\\t\"\n        \"ldr\tr10, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"str\tr4, [sp, #8]\\n\\t\"\n        \"#  A[0] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r14, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"#  A[1] * A[2]\\n\\t\"\n        \"ldr\tr10, [%[a], #8]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"str\tr2, [sp, #12]\\n\\t\"\n        \"#  A[0] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[1] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[2] * A[2]\\n\\t\"\n        \"ldr\tr10, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [sp, #16]\\n\\t\"\n        \"#  A[0] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #20]\\n\\t\"\n        \"#  A[0] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #24]\\n\\t\"\n        \"#  A[0] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #28]\\n\\t\"\n        \"#  A[0] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #32]\\n\\t\"\n        \"#  A[0] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #36]\\n\\t\"\n        \"#  A[0] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #40]\\n\\t\"\n        \"#  A[0] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #44]\\n\\t\"\n        \"#  A[0] * A[12]\\n\\t\"\n        \"ldr\tr10, [%[a], #48]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #48]\\n\\t\"\n        \"#  A[0] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[12]\\n\\t\"\n        \"ldr\tr10, [%[a], #48]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #52]\\n\\t\"\n        \"#  A[0] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[12]\\n\\t\"\n        \"ldr\tr10, [%[a], #48]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #56]\\n\\t\"\n        \"#  A[0] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[12]\\n\\t\"\n        \"ldr\tr10, [%[a], #48]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #60]\\n\\t\"\n        \"#  A[0] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[12]\\n\\t\"\n        \"ldr\tr10, [%[a], #48]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[8]\\n\\t\"\n        \"ldr\tr10, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #64]\\n\\t\"\n        \"#  A[0] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[12]\\n\\t\"\n        \"ldr\tr10, [%[a], #48]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #68]\\n\\t\"\n        \"#  A[0] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[12]\\n\\t\"\n        \"ldr\tr10, [%[a], #48]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[9]\\n\\t\"\n        \"ldr\tr10, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #72]\\n\\t\"\n        \"#  A[0] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[12]\\n\\t\"\n        \"ldr\tr10, [%[a], #48]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #76]\\n\\t\"\n        \"#  A[0] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[12]\\n\\t\"\n        \"ldr\tr10, [%[a], #48]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[10]\\n\\t\"\n        \"ldr\tr10, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #80]\\n\\t\"\n        \"#  A[0] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[12]\\n\\t\"\n        \"ldr\tr10, [%[a], #48]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #84]\\n\\t\"\n        \"#  A[0] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[12]\\n\\t\"\n        \"ldr\tr10, [%[a], #48]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[11]\\n\\t\"\n        \"ldr\tr10, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #88]\\n\\t\"\n        \"#  A[0] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[12]\\n\\t\"\n        \"ldr\tr10, [%[a], #48]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #92]\\n\\t\"\n        \"#  A[0] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[12]\\n\\t\"\n        \"ldr\tr10, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #96]\\n\\t\"\n        \"#  A[0] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #100]\\n\\t\"\n        \"#  A[0] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[13]\\n\\t\"\n        \"ldr\tr10, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #104]\\n\\t\"\n        \"#  A[0] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #108]\\n\\t\"\n        \"#  A[0] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[14]\\n\\t\"\n        \"ldr\tr10, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #112]\\n\\t\"\n        \"#  A[0] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #116]\\n\\t\"\n        \"#  A[0] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[15]\\n\\t\"\n        \"ldr\tr10, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #120]\\n\\t\"\n        \"#  A[0] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #124]\\n\\t\"\n        \"#  A[0] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[16]\\n\\t\"\n        \"ldr\tr10, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #128]\\n\\t\"\n        \"#  A[0] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #132]\\n\\t\"\n        \"#  A[0] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[17]\\n\\t\"\n        \"ldr\tr10, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #136]\\n\\t\"\n        \"#  A[0] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #140]\\n\\t\"\n        \"#  A[0] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[18]\\n\\t\"\n        \"ldr\tr10, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #144]\\n\\t\"\n        \"#  A[0] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #148]\\n\\t\"\n        \"#  A[0] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[19]\\n\\t\"\n        \"ldr\tr10, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #152]\\n\\t\"\n        \"#  A[0] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #156]\\n\\t\"\n        \"#  A[0] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[20]\\n\\t\"\n        \"ldr\tr10, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #160]\\n\\t\"\n        \"#  A[0] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #164]\\n\\t\"\n        \"#  A[0] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[21]\\n\\t\"\n        \"ldr\tr10, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #168]\\n\\t\"\n        \"#  A[0] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #172]\\n\\t\"\n        \"#  A[0] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[22]\\n\\t\"\n        \"ldr\tr10, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #176]\\n\\t\"\n        \"#  A[0] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #180]\\n\\t\"\n        \"#  A[0] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[23]\\n\\t\"\n        \"ldr\tr10, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #184]\\n\\t\"\n        \"#  A[0] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #188]\\n\\t\"\n        \"#  A[0] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[24]\\n\\t\"\n        \"ldr\tr10, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #192]\\n\\t\"\n        \"#  A[0] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #196]\\n\\t\"\n        \"#  A[0] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[25]\\n\\t\"\n        \"ldr\tr10, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #200]\\n\\t\"\n        \"#  A[0] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #204]\\n\\t\"\n        \"#  A[0] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[26]\\n\\t\"\n        \"ldr\tr10, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #208]\\n\\t\"\n        \"#  A[0] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #212]\\n\\t\"\n        \"#  A[0] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[27]\\n\\t\"\n        \"ldr\tr10, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #216]\\n\\t\"\n        \"#  A[0] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #220]\\n\\t\"\n        \"#  A[0] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[28]\\n\\t\"\n        \"ldr\tr10, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #224]\\n\\t\"\n        \"#  A[0] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #228]\\n\\t\"\n        \"#  A[0] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[29]\\n\\t\"\n        \"ldr\tr10, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #232]\\n\\t\"\n        \"#  A[0] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #236]\\n\\t\"\n        \"#  A[0] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[30]\\n\\t\"\n        \"ldr\tr10, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #240]\\n\\t\"\n        \"#  A[0] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #244]\\n\\t\"\n        \"#  A[0] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[31]\\n\\t\"\n        \"ldr\tr10, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #248]\\n\\t\"\n        \"#  A[0] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #252]\\n\\t\"\n        \"#  A[1] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[2] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[32]\\n\\t\"\n        \"ldr\tr10, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #256]\\n\\t\"\n        \"#  A[2] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[3] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #260]\\n\\t\"\n        \"#  A[3] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[4] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[5] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[33]\\n\\t\"\n        \"ldr\tr10, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #264]\\n\\t\"\n        \"#  A[4] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[5] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[6] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #268]\\n\\t\"\n        \"#  A[5] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[6] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[7] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[34]\\n\\t\"\n        \"ldr\tr10, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #272]\\n\\t\"\n        \"#  A[6] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[7] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[8] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #276]\\n\\t\"\n        \"#  A[7] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[8] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[9] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[35]\\n\\t\"\n        \"ldr\tr10, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #280]\\n\\t\"\n        \"#  A[8] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[9] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[10] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #284]\\n\\t\"\n        \"#  A[9] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[10] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[11] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[36]\\n\\t\"\n        \"ldr\tr10, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #288]\\n\\t\"\n        \"#  A[10] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[11] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[12] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #292]\\n\\t\"\n        \"#  A[11] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[12] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[13] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[37]\\n\\t\"\n        \"ldr\tr10, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #296]\\n\\t\"\n        \"#  A[12] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[13] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[14] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #300]\\n\\t\"\n        \"#  A[13] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[14] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[15] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[38]\\n\\t\"\n        \"ldr\tr10, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #304]\\n\\t\"\n        \"#  A[14] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[15] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[16] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #308]\\n\\t\"\n        \"#  A[15] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[16] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[17] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[39]\\n\\t\"\n        \"ldr\tr10, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #312]\\n\\t\"\n        \"#  A[16] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[17] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[18] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #316]\\n\\t\"\n        \"#  A[17] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[18] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[19] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[40]\\n\\t\"\n        \"ldr\tr10, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #320]\\n\\t\"\n        \"#  A[18] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[19] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[20] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #324]\\n\\t\"\n        \"#  A[19] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[20] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[21] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[41]\\n\\t\"\n        \"ldr\tr10, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #328]\\n\\t\"\n        \"#  A[20] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[21] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[22] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #332]\\n\\t\"\n        \"#  A[21] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[22] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[23] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[42]\\n\\t\"\n        \"ldr\tr10, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #336]\\n\\t\"\n        \"#  A[22] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[23] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[24] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #340]\\n\\t\"\n        \"#  A[23] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[24] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[25] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[43]\\n\\t\"\n        \"ldr\tr10, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #344]\\n\\t\"\n        \"#  A[24] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[25] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[26] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #348]\\n\\t\"\n        \"#  A[25] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[26] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[27] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[44]\\n\\t\"\n        \"ldr\tr10, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #352]\\n\\t\"\n        \"#  A[26] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[27] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[28] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #356]\\n\\t\"\n        \"#  A[27] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[28] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[29] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[45]\\n\\t\"\n        \"ldr\tr10, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #360]\\n\\t\"\n        \"#  A[28] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[29] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[30] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #364]\\n\\t\"\n        \"#  A[29] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[30] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[31] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[46]\\n\\t\"\n        \"ldr\tr10, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #368]\\n\\t\"\n        \"#  A[30] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[31] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[32] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #372]\\n\\t\"\n        \"#  A[31] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[32] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[33] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[47]\\n\\t\"\n        \"ldr\tr10, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #376]\\n\\t\"\n        \"#  A[32] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[33] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[34] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #380]\\n\\t\"\n        \"#  A[33] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[34] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[35] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[48]\\n\\t\"\n        \"ldr\tr10, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #384]\\n\\t\"\n        \"#  A[34] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[35] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[36] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #388]\\n\\t\"\n        \"#  A[35] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[36] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[37] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[49] * A[49]\\n\\t\"\n        \"ldr\tr10, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #392]\\n\\t\"\n        \"#  A[36] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[37] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[38] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[49] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #396]\\n\\t\"\n        \"#  A[37] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[38] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[39] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[49] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[50] * A[50]\\n\\t\"\n        \"ldr\tr10, [%[a], #200]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #400]\\n\\t\"\n        \"#  A[38] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[39] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[40] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[49] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[50] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #404]\\n\\t\"\n        \"#  A[39] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[40] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[41] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[49] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[50] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[51] * A[51]\\n\\t\"\n        \"ldr\tr10, [%[a], #204]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #408]\\n\\t\"\n        \"#  A[40] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[41] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[42] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[49] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[50] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[51] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #412]\\n\\t\"\n        \"#  A[41] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[42] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[43] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[49] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[50] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[51] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[52] * A[52]\\n\\t\"\n        \"ldr\tr10, [%[a], #208]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #416]\\n\\t\"\n        \"#  A[42] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[43] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[44] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[49] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[50] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[51] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[52] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #420]\\n\\t\"\n        \"#  A[43] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[44] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[45] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[49] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[50] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[51] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[52] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[53] * A[53]\\n\\t\"\n        \"ldr\tr10, [%[a], #212]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #424]\\n\\t\"\n        \"#  A[44] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[45] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[46] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[49] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[50] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[51] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[52] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[53] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #428]\\n\\t\"\n        \"#  A[45] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[46] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[47] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[49] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[50] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[51] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[52] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[53] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[54] * A[54]\\n\\t\"\n        \"ldr\tr10, [%[a], #216]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #432]\\n\\t\"\n        \"#  A[46] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[47] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[48] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[49] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[50] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[51] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[52] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[53] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[54] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #436]\\n\\t\"\n        \"#  A[47] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[48] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[49] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[50] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[51] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[52] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[53] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[54] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[55] * A[55]\\n\\t\"\n        \"ldr\tr10, [%[a], #220]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #440]\\n\\t\"\n        \"#  A[48] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[49] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[50] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[51] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[52] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[53] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[54] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[55] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #444]\\n\\t\"\n        \"#  A[49] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[50] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[51] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[52] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[53] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[54] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[55] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[56] * A[56]\\n\\t\"\n        \"ldr\tr10, [%[a], #224]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #448]\\n\\t\"\n        \"#  A[50] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[51] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[52] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[53] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[54] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[55] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[56] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #452]\\n\\t\"\n        \"#  A[51] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[52] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[53] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[54] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[55] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[56] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[57] * A[57]\\n\\t\"\n        \"ldr\tr10, [%[a], #228]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #456]\\n\\t\"\n        \"#  A[52] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[53] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[54] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[55] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[56] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[57] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #460]\\n\\t\"\n        \"#  A[53] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[54] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[55] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[56] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[57] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[58] * A[58]\\n\\t\"\n        \"ldr\tr10, [%[a], #232]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #464]\\n\\t\"\n        \"#  A[54] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[55] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[56] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[57] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[58] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #468]\\n\\t\"\n        \"#  A[55] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[56] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[57] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[58] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[59] * A[59]\\n\\t\"\n        \"ldr\tr10, [%[a], #236]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #472]\\n\\t\"\n        \"#  A[56] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[57] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[58] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[59] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #476]\\n\\t\"\n        \"#  A[57] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[58] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[59] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[60] * A[60]\\n\\t\"\n        \"ldr\tr10, [%[a], #240]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #480]\\n\\t\"\n        \"#  A[58] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[59] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[60] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [%[r], #484]\\n\\t\"\n        \"#  A[59] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r14, r14\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"#  A[60] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"#  A[61] * A[61]\\n\\t\"\n        \"ldr\tr10, [%[a], #244]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"str\tr4, [%[r], #488]\\n\\t\"\n        \"#  A[60] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r14, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"#  A[61] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"str\tr2, [%[r], #492]\\n\\t\"\n        \"#  A[61] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[62] * A[62]\\n\\t\"\n        \"ldr\tr10, [%[a], #248]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [%[r], #496]\\n\\t\"\n        \"#  A[62] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r14, r14\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"str\tr4, [%[r], #500]\\n\\t\"\n        \"#  A[63] * A[63]\\n\\t\"\n        \"ldr\tr10, [%[a], #252]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adc\tr3, r3, r9\\n\\t\"\n        \"str\tr2, [%[r], #504]\\n\\t\"\n        \"str\tr3, [%[r], #508]\\n\\t\"\n        \"ldr\tr2, [sp, #0]\\n\\t\"\n        \"ldr\tr3, [sp, #4]\\n\\t\"\n        \"ldr\tr4, [sp, #8]\\n\\t\"\n        \"ldr\tr8, [sp, #12]\\n\\t\"\n        \"str\tr2, [%[r], #0]\\n\\t\"\n        \"str\tr3, [%[r], #4]\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"str\tr8, [%[r], #12]\\n\\t\"\n        \"ldr\tr2, [sp, #16]\\n\\t\"\n        \"ldr\tr3, [sp, #20]\\n\\t\"\n        \"ldr\tr4, [sp, #24]\\n\\t\"\n        \"ldr\tr8, [sp, #28]\\n\\t\"\n        \"str\tr2, [%[r], #16]\\n\\t\"\n        \"str\tr3, [%[r], #20]\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"str\tr8, [%[r], #28]\\n\\t\"\n        \"ldr\tr2, [sp, #32]\\n\\t\"\n        \"ldr\tr3, [sp, #36]\\n\\t\"\n        \"ldr\tr4, [sp, #40]\\n\\t\"\n        \"ldr\tr8, [sp, #44]\\n\\t\"\n        \"str\tr2, [%[r], #32]\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"str\tr8, [%[r], #44]\\n\\t\"\n        \"ldr\tr2, [sp, #48]\\n\\t\"\n        \"ldr\tr3, [sp, #52]\\n\\t\"\n        \"ldr\tr4, [sp, #56]\\n\\t\"\n        \"ldr\tr8, [sp, #60]\\n\\t\"\n        \"str\tr2, [%[r], #48]\\n\\t\"\n        \"str\tr3, [%[r], #52]\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"str\tr8, [%[r], #60]\\n\\t\"\n        \"ldr\tr2, [sp, #64]\\n\\t\"\n        \"ldr\tr3, [sp, #68]\\n\\t\"\n        \"ldr\tr4, [sp, #72]\\n\\t\"\n        \"ldr\tr8, [sp, #76]\\n\\t\"\n        \"str\tr2, [%[r], #64]\\n\\t\"\n        \"str\tr3, [%[r], #68]\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"str\tr8, [%[r], #76]\\n\\t\"\n        \"ldr\tr2, [sp, #80]\\n\\t\"\n        \"ldr\tr3, [sp, #84]\\n\\t\"\n        \"ldr\tr4, [sp, #88]\\n\\t\"\n        \"ldr\tr8, [sp, #92]\\n\\t\"\n        \"str\tr2, [%[r], #80]\\n\\t\"\n        \"str\tr3, [%[r], #84]\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"str\tr8, [%[r], #92]\\n\\t\"\n        \"ldr\tr2, [sp, #96]\\n\\t\"\n        \"ldr\tr3, [sp, #100]\\n\\t\"\n        \"ldr\tr4, [sp, #104]\\n\\t\"\n        \"ldr\tr8, [sp, #108]\\n\\t\"\n        \"str\tr2, [%[r], #96]\\n\\t\"\n        \"str\tr3, [%[r], #100]\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"str\tr8, [%[r], #108]\\n\\t\"\n        \"ldr\tr2, [sp, #112]\\n\\t\"\n        \"ldr\tr3, [sp, #116]\\n\\t\"\n        \"ldr\tr4, [sp, #120]\\n\\t\"\n        \"ldr\tr8, [sp, #124]\\n\\t\"\n        \"str\tr2, [%[r], #112]\\n\\t\"\n        \"str\tr3, [%[r], #116]\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"str\tr8, [%[r], #124]\\n\\t\"\n        \"ldr\tr2, [sp, #128]\\n\\t\"\n        \"ldr\tr3, [sp, #132]\\n\\t\"\n        \"ldr\tr4, [sp, #136]\\n\\t\"\n        \"ldr\tr8, [sp, #140]\\n\\t\"\n        \"str\tr2, [%[r], #128]\\n\\t\"\n        \"str\tr3, [%[r], #132]\\n\\t\"\n        \"str\tr4, [%[r], #136]\\n\\t\"\n        \"str\tr8, [%[r], #140]\\n\\t\"\n        \"ldr\tr2, [sp, #144]\\n\\t\"\n        \"ldr\tr3, [sp, #148]\\n\\t\"\n        \"ldr\tr4, [sp, #152]\\n\\t\"\n        \"ldr\tr8, [sp, #156]\\n\\t\"\n        \"str\tr2, [%[r], #144]\\n\\t\"\n        \"str\tr3, [%[r], #148]\\n\\t\"\n        \"str\tr4, [%[r], #152]\\n\\t\"\n        \"str\tr8, [%[r], #156]\\n\\t\"\n        \"ldr\tr2, [sp, #160]\\n\\t\"\n        \"ldr\tr3, [sp, #164]\\n\\t\"\n        \"ldr\tr4, [sp, #168]\\n\\t\"\n        \"ldr\tr8, [sp, #172]\\n\\t\"\n        \"str\tr2, [%[r], #160]\\n\\t\"\n        \"str\tr3, [%[r], #164]\\n\\t\"\n        \"str\tr4, [%[r], #168]\\n\\t\"\n        \"str\tr8, [%[r], #172]\\n\\t\"\n        \"ldr\tr2, [sp, #176]\\n\\t\"\n        \"ldr\tr3, [sp, #180]\\n\\t\"\n        \"ldr\tr4, [sp, #184]\\n\\t\"\n        \"ldr\tr8, [sp, #188]\\n\\t\"\n        \"str\tr2, [%[r], #176]\\n\\t\"\n        \"str\tr3, [%[r], #180]\\n\\t\"\n        \"str\tr4, [%[r], #184]\\n\\t\"\n        \"str\tr8, [%[r], #188]\\n\\t\"\n        \"ldr\tr2, [sp, #192]\\n\\t\"\n        \"ldr\tr3, [sp, #196]\\n\\t\"\n        \"ldr\tr4, [sp, #200]\\n\\t\"\n        \"ldr\tr8, [sp, #204]\\n\\t\"\n        \"str\tr2, [%[r], #192]\\n\\t\"\n        \"str\tr3, [%[r], #196]\\n\\t\"\n        \"str\tr4, [%[r], #200]\\n\\t\"\n        \"str\tr8, [%[r], #204]\\n\\t\"\n        \"ldr\tr2, [sp, #208]\\n\\t\"\n        \"ldr\tr3, [sp, #212]\\n\\t\"\n        \"ldr\tr4, [sp, #216]\\n\\t\"\n        \"ldr\tr8, [sp, #220]\\n\\t\"\n        \"str\tr2, [%[r], #208]\\n\\t\"\n        \"str\tr3, [%[r], #212]\\n\\t\"\n        \"str\tr4, [%[r], #216]\\n\\t\"\n        \"str\tr8, [%[r], #220]\\n\\t\"\n        \"ldr\tr2, [sp, #224]\\n\\t\"\n        \"ldr\tr3, [sp, #228]\\n\\t\"\n        \"ldr\tr4, [sp, #232]\\n\\t\"\n        \"ldr\tr8, [sp, #236]\\n\\t\"\n        \"str\tr2, [%[r], #224]\\n\\t\"\n        \"str\tr3, [%[r], #228]\\n\\t\"\n        \"str\tr4, [%[r], #232]\\n\\t\"\n        \"str\tr8, [%[r], #236]\\n\\t\"\n        \"ldr\tr2, [sp, #240]\\n\\t\"\n        \"ldr\tr3, [sp, #244]\\n\\t\"\n        \"ldr\tr4, [sp, #248]\\n\\t\"\n        \"ldr\tr8, [sp, #252]\\n\\t\"\n        \"str\tr2, [%[r], #240]\\n\\t\"\n        \"str\tr3, [%[r], #244]\\n\\t\"\n        \"str\tr4, [%[r], #248]\\n\\t\"\n        \"str\tr8, [%[r], #252]\\n\\t\"\n        \"add\tsp, sp, #256\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r8\", \"r9\", \"r10\", \"r8\", \"r5\", \"r6\", \"r7\", \"r14\"\n    );\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[128];\n    sp_digit z1[128];\n    sp_digit a1[64];\n    sp_digit u;\n\n    u = sp_2048_add_64(a1, a, &a[64]);\n    sp_2048_sqr_64(z1, a1);\n    sp_2048_sqr_64(z2, &a[64]);\n    sp_2048_sqr_64(z0, a);\n    sp_2048_mask_64(r + 128, a1, 0 - u);\n    u += sp_2048_add_64(r + 128, r + 128, r + 128);\n    u += sp_4096_sub_in_place_128(z1, z2);\n    u += sp_4096_sub_in_place_128(z1, z0);\n    u += sp_4096_add_128(r + 64, r + 64, z1);\n    r[192] = u;\n    XMEMSET(r + 192 + 1, 0, sizeof(sp_digit) * (64 - 1));\n    (void)sp_4096_add_128(r + 128, r + 128, z2);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tr12, %[a], #512\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], #-1\\n\\t\"\n        \"ldr\tr4, [%[a]], #4\\n\\t\"\n        \"ldr\tr5, [%[a]], #4\\n\\t\"\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"ldr\tr7, [%[a]], #4\\n\\t\"\n        \"ldr\tr8, [%[b]], #4\\n\\t\"\n        \"ldr\tr9, [%[b]], #4\\n\\t\"\n        \"ldr\tr10, [%[b]], #4\\n\\t\"\n        \"ldr\tr14, [%[b]], #4\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r]], #4\\n\\t\"\n        \"str\tr5, [%[r]], #4\\n\\t\"\n        \"str\tr6, [%[r]], #4\\n\\t\"\n        \"str\tr7, [%[r]], #4\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"adc\t%[c], r4, #0\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_4096_sub_in_place_128(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr14, #0\\n\\t\"\n        \"add\tr12, %[a], #512\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\t%[c], r14, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b]], #4\\n\\t\"\n        \"ldr\tr8, [%[b]], #4\\n\\t\"\n        \"ldr\tr9, [%[b]], #4\\n\\t\"\n        \"ldr\tr10, [%[b]], #4\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"sbcs\tr6, r6, r10\\n\\t\"\n        \"str\tr3, [%[a]], #4\\n\\t\"\n        \"str\tr4, [%[a]], #4\\n\\t\"\n        \"str\tr5, [%[a]], #4\\n\\t\"\n        \"str\tr6, [%[a]], #4\\n\\t\"\n        \"sbc\t%[c], r14, r14\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r12\", \"r14\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_4096_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #1024\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tr3, r5, #508\\n\\t\"\n        \"it\tcc\\n\\t\"\n        \"movcc\tr3, #0\\n\\t\"\n        \"sub\tr4, r5, r3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"ldr\tr12, [%[b], r4]\\n\\t\"\n        \"umull\tr9, r10, r14, r12\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, #0\\n\\t\"\n        \"add\tr3, r3, #4\\n\\t\"\n        \"sub\tr4, r4, #4\\n\\t\"\n        \"cmp\tr3, #512\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\tr3, r5\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"mov\tr6, r7\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"add\tr5, r5, #4\\n\\t\"\n        \"cmp\tr5, #1016\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [sp, #0]\\n\\t\"\n        \"ldr\tr7, [sp, #4]\\n\\t\"\n        \"ldr\tr8, [sp, #8]\\n\\t\"\n        \"ldr\tr3, [sp, #12]\\n\\t\"\n        \"str\tr6, [%[r], #0]\\n\\t\"\n        \"str\tr7, [%[r], #4]\\n\\t\"\n        \"str\tr8, [%[r], #8]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"add\tsp, sp, #16\\n\\t\"\n        \"add\t%[r], %[r], #16\\n\\t\"\n        \"subs\tr5, r5, #16\\n\\t\"\n        \"bgt\t4b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_4096_sqr_128(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #1024\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tr3, r5, #508\\n\\t\"\n        \"it\tcc\\n\\t\"\n        \"movcc\tr3, r12\\n\\t\"\n        \"sub\tr4, r5, r3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr4, r3\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"ldr\tr9, [%[a], r4]\\n\\t\"\n        \"umull\tr9, r10, r14, r9\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"umull\tr9, r10, r14, r14\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\tr3, r3, #4\\n\\t\"\n        \"sub\tr4, r4, #4\\n\\t\"\n        \"cmp\tr3, #512\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\tr3, r4\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"cmp\tr3, r5\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"mov\tr6, r7\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"add\tr5, r5, #4\\n\\t\"\n        \"cmp\tr5, #1016\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [sp, #0]\\n\\t\"\n        \"ldr\tr7, [sp, #4]\\n\\t\"\n        \"ldr\tr8, [sp, #8]\\n\\t\"\n        \"ldr\tr3, [sp, #12]\\n\\t\"\n        \"str\tr6, [%[r], #0]\\n\\t\"\n        \"str\tr7, [%[r], #4]\\n\\t\"\n        \"str\tr8, [%[r], #8]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"add\tsp, sp, #16\\n\\t\"\n        \"add\t%[r], %[r], #16\\n\\t\"\n        \"subs\tr5, r5, #16\\n\\t\"\n        \"bgt\t4b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r9\", \"r12\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nstatic void sp_4096_mul_d_128(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr10, #0\\n\\t\"\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tr8, [%[a]]\\n\\t\"\n        \"umull\tr5, r3, %[b], r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr5, [%[r]]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr9, #4\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr8, [%[a], r9]\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], r9]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr9, r9, #4\\n\\t\"\n        \"cmp\tr9, #512\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r], #512]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tr10, #0\\n\\t\"\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tr8, [%[a]]\\n\\t\"\n        \"umull\tr3, r4, %[b], r8\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"# A[1] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"# A[2] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"# A[3] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"# A[4] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"# A[5] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"# A[6] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"# A[7] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"# A[8] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #32]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #32]\\n\\t\"\n        \"# A[9] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #36]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"# A[10] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #40]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"# A[11] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #44]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #44]\\n\\t\"\n        \"# A[12] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #48]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"# A[13] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #52]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"# A[14] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #56]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #56]\\n\\t\"\n        \"# A[15] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #60]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"# A[16] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #64]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"# A[17] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #68]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #68]\\n\\t\"\n        \"# A[18] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #72]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #72]\\n\\t\"\n        \"# A[19] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #76]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"# A[20] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #80]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #80]\\n\\t\"\n        \"# A[21] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #84]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #84]\\n\\t\"\n        \"# A[22] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #88]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"# A[23] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #92]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #92]\\n\\t\"\n        \"# A[24] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #96]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #96]\\n\\t\"\n        \"# A[25] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #100]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"# A[26] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #104]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #104]\\n\\t\"\n        \"# A[27] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #108]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #108]\\n\\t\"\n        \"# A[28] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #112]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"# A[29] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #116]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #116]\\n\\t\"\n        \"# A[30] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #120]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #120]\\n\\t\"\n        \"# A[31] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #124]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"# A[32] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #128]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #128]\\n\\t\"\n        \"# A[33] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #132]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #132]\\n\\t\"\n        \"# A[34] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #136]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #136]\\n\\t\"\n        \"# A[35] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #140]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #140]\\n\\t\"\n        \"# A[36] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #144]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #144]\\n\\t\"\n        \"# A[37] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #148]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #148]\\n\\t\"\n        \"# A[38] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #152]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #152]\\n\\t\"\n        \"# A[39] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #156]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #156]\\n\\t\"\n        \"# A[40] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #160]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"# A[41] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #164]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #164]\\n\\t\"\n        \"# A[42] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #168]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #168]\\n\\t\"\n        \"# A[43] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #172]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #172]\\n\\t\"\n        \"# A[44] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #176]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #176]\\n\\t\"\n        \"# A[45] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #180]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #180]\\n\\t\"\n        \"# A[46] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #184]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #184]\\n\\t\"\n        \"# A[47] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #188]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #188]\\n\\t\"\n        \"# A[48] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #192]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #192]\\n\\t\"\n        \"# A[49] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #196]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #196]\\n\\t\"\n        \"# A[50] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #200]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #200]\\n\\t\"\n        \"# A[51] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #204]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #204]\\n\\t\"\n        \"# A[52] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #208]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #208]\\n\\t\"\n        \"# A[53] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #212]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #212]\\n\\t\"\n        \"# A[54] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #216]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #216]\\n\\t\"\n        \"# A[55] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #220]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #220]\\n\\t\"\n        \"# A[56] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #224]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #224]\\n\\t\"\n        \"# A[57] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #228]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #228]\\n\\t\"\n        \"# A[58] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #232]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #232]\\n\\t\"\n        \"# A[59] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #236]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #236]\\n\\t\"\n        \"# A[60] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #240]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #240]\\n\\t\"\n        \"# A[61] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #244]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #244]\\n\\t\"\n        \"# A[62] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #248]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #248]\\n\\t\"\n        \"# A[63] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #252]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #252]\\n\\t\"\n        \"# A[64] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #256]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #256]\\n\\t\"\n        \"# A[65] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #260]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #260]\\n\\t\"\n        \"# A[66] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #264]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #264]\\n\\t\"\n        \"# A[67] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #268]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #268]\\n\\t\"\n        \"# A[68] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #272]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #272]\\n\\t\"\n        \"# A[69] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #276]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #276]\\n\\t\"\n        \"# A[70] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #280]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #280]\\n\\t\"\n        \"# A[71] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #284]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #284]\\n\\t\"\n        \"# A[72] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #288]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #288]\\n\\t\"\n        \"# A[73] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #292]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #292]\\n\\t\"\n        \"# A[74] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #296]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #296]\\n\\t\"\n        \"# A[75] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #300]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #300]\\n\\t\"\n        \"# A[76] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #304]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #304]\\n\\t\"\n        \"# A[77] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #308]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #308]\\n\\t\"\n        \"# A[78] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #312]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #312]\\n\\t\"\n        \"# A[79] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #316]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #316]\\n\\t\"\n        \"# A[80] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #320]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #320]\\n\\t\"\n        \"# A[81] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #324]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #324]\\n\\t\"\n        \"# A[82] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #328]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #328]\\n\\t\"\n        \"# A[83] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #332]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #332]\\n\\t\"\n        \"# A[84] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #336]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #336]\\n\\t\"\n        \"# A[85] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #340]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #340]\\n\\t\"\n        \"# A[86] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #344]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #344]\\n\\t\"\n        \"# A[87] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #348]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #348]\\n\\t\"\n        \"# A[88] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #352]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #352]\\n\\t\"\n        \"# A[89] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #356]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #356]\\n\\t\"\n        \"# A[90] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #360]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #360]\\n\\t\"\n        \"# A[91] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #364]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #364]\\n\\t\"\n        \"# A[92] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #368]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #368]\\n\\t\"\n        \"# A[93] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #372]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #372]\\n\\t\"\n        \"# A[94] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #376]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #376]\\n\\t\"\n        \"# A[95] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #380]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #380]\\n\\t\"\n        \"# A[96] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #384]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #384]\\n\\t\"\n        \"# A[97] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #388]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #388]\\n\\t\"\n        \"# A[98] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #392]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #392]\\n\\t\"\n        \"# A[99] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #396]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #396]\\n\\t\"\n        \"# A[100] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #400]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #400]\\n\\t\"\n        \"# A[101] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #404]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #404]\\n\\t\"\n        \"# A[102] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #408]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #408]\\n\\t\"\n        \"# A[103] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #412]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #412]\\n\\t\"\n        \"# A[104] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #416]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #416]\\n\\t\"\n        \"# A[105] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #420]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #420]\\n\\t\"\n        \"# A[106] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #424]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #424]\\n\\t\"\n        \"# A[107] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #428]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #428]\\n\\t\"\n        \"# A[108] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #432]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #432]\\n\\t\"\n        \"# A[109] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #436]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #436]\\n\\t\"\n        \"# A[110] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #440]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #440]\\n\\t\"\n        \"# A[111] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #444]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #444]\\n\\t\"\n        \"# A[112] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #448]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #448]\\n\\t\"\n        \"# A[113] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #452]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #452]\\n\\t\"\n        \"# A[114] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #456]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #456]\\n\\t\"\n        \"# A[115] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #460]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #460]\\n\\t\"\n        \"# A[116] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #464]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #464]\\n\\t\"\n        \"# A[117] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #468]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #468]\\n\\t\"\n        \"# A[118] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #472]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #472]\\n\\t\"\n        \"# A[119] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #476]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #476]\\n\\t\"\n        \"# A[120] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #480]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #480]\\n\\t\"\n        \"# A[121] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #484]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #484]\\n\\t\"\n        \"# A[122] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #488]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #488]\\n\\t\"\n        \"# A[123] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #492]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #492]\\n\\t\"\n        \"# A[124] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #496]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #496]\\n\\t\"\n        \"# A[125] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #500]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #500]\\n\\t\"\n        \"# A[126] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #504]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #504]\\n\\t\"\n        \"# A[127] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #508]\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r], #508]\\n\\t\"\n        \"str\tr5, [%[r], #512]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n#endif\n}\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 4096 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_4096_mont_norm_128(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 128);\n\n    /* r = 2^n mod m */\n    sp_4096_sub_in_place_128(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        sp_digit m)\n{\n    sp_digit c = 0;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr9, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"subs\t%[c], r9, %[c]\\n\\t\"\n        \"ldr\tr4, [%[a], r8]\\n\\t\"\n        \"ldr\tr5, [%[b], r8]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        \"str\tr4, [%[r], r8]\\n\\t\"\n        \"add\tr8, r8, #4\\n\\t\"\n        \"cmp\tr8, #512\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r4\", \"r6\", \"r5\", \"r7\", \"r8\", \"r9\"\n    );\n#else\n    __asm__ __volatile__ (\n\n        \"mov\tr9, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr6, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr6, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr6, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr7, [%[b], #36]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"str\tr6, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr6, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr7, [%[b], #44]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"str\tr6, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr6, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr7, [%[b], #52]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"str\tr6, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr6, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr7, [%[b], #60]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"str\tr6, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr6, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr7, [%[b], #68]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"str\tr6, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr6, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr7, [%[b], #76]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"str\tr6, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr6, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr7, [%[b], #84]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"str\tr6, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr6, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr7, [%[b], #92]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"str\tr6, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr6, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr7, [%[b], #100]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"str\tr6, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr6, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr7, [%[b], #108]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"str\tr6, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr6, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr7, [%[b], #116]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"str\tr6, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr6, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr7, [%[b], #124]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"str\tr6, [%[r], #124]\\n\\t\"\n        \"ldr\tr4, [%[a], #128]\\n\\t\"\n        \"ldr\tr6, [%[a], #132]\\n\\t\"\n        \"ldr\tr5, [%[b], #128]\\n\\t\"\n        \"ldr\tr7, [%[b], #132]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #128]\\n\\t\"\n        \"str\tr6, [%[r], #132]\\n\\t\"\n        \"ldr\tr4, [%[a], #136]\\n\\t\"\n        \"ldr\tr6, [%[a], #140]\\n\\t\"\n        \"ldr\tr5, [%[b], #136]\\n\\t\"\n        \"ldr\tr7, [%[b], #140]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #136]\\n\\t\"\n        \"str\tr6, [%[r], #140]\\n\\t\"\n        \"ldr\tr4, [%[a], #144]\\n\\t\"\n        \"ldr\tr6, [%[a], #148]\\n\\t\"\n        \"ldr\tr5, [%[b], #144]\\n\\t\"\n        \"ldr\tr7, [%[b], #148]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #144]\\n\\t\"\n        \"str\tr6, [%[r], #148]\\n\\t\"\n        \"ldr\tr4, [%[a], #152]\\n\\t\"\n        \"ldr\tr6, [%[a], #156]\\n\\t\"\n        \"ldr\tr5, [%[b], #152]\\n\\t\"\n        \"ldr\tr7, [%[b], #156]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #152]\\n\\t\"\n        \"str\tr6, [%[r], #156]\\n\\t\"\n        \"ldr\tr4, [%[a], #160]\\n\\t\"\n        \"ldr\tr6, [%[a], #164]\\n\\t\"\n        \"ldr\tr5, [%[b], #160]\\n\\t\"\n        \"ldr\tr7, [%[b], #164]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #160]\\n\\t\"\n        \"str\tr6, [%[r], #164]\\n\\t\"\n        \"ldr\tr4, [%[a], #168]\\n\\t\"\n        \"ldr\tr6, [%[a], #172]\\n\\t\"\n        \"ldr\tr5, [%[b], #168]\\n\\t\"\n        \"ldr\tr7, [%[b], #172]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #168]\\n\\t\"\n        \"str\tr6, [%[r], #172]\\n\\t\"\n        \"ldr\tr4, [%[a], #176]\\n\\t\"\n        \"ldr\tr6, [%[a], #180]\\n\\t\"\n        \"ldr\tr5, [%[b], #176]\\n\\t\"\n        \"ldr\tr7, [%[b], #180]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #176]\\n\\t\"\n        \"str\tr6, [%[r], #180]\\n\\t\"\n        \"ldr\tr4, [%[a], #184]\\n\\t\"\n        \"ldr\tr6, [%[a], #188]\\n\\t\"\n        \"ldr\tr5, [%[b], #184]\\n\\t\"\n        \"ldr\tr7, [%[b], #188]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #184]\\n\\t\"\n        \"str\tr6, [%[r], #188]\\n\\t\"\n        \"ldr\tr4, [%[a], #192]\\n\\t\"\n        \"ldr\tr6, [%[a], #196]\\n\\t\"\n        \"ldr\tr5, [%[b], #192]\\n\\t\"\n        \"ldr\tr7, [%[b], #196]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #192]\\n\\t\"\n        \"str\tr6, [%[r], #196]\\n\\t\"\n        \"ldr\tr4, [%[a], #200]\\n\\t\"\n        \"ldr\tr6, [%[a], #204]\\n\\t\"\n        \"ldr\tr5, [%[b], #200]\\n\\t\"\n        \"ldr\tr7, [%[b], #204]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #200]\\n\\t\"\n        \"str\tr6, [%[r], #204]\\n\\t\"\n        \"ldr\tr4, [%[a], #208]\\n\\t\"\n        \"ldr\tr6, [%[a], #212]\\n\\t\"\n        \"ldr\tr5, [%[b], #208]\\n\\t\"\n        \"ldr\tr7, [%[b], #212]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #208]\\n\\t\"\n        \"str\tr6, [%[r], #212]\\n\\t\"\n        \"ldr\tr4, [%[a], #216]\\n\\t\"\n        \"ldr\tr6, [%[a], #220]\\n\\t\"\n        \"ldr\tr5, [%[b], #216]\\n\\t\"\n        \"ldr\tr7, [%[b], #220]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #216]\\n\\t\"\n        \"str\tr6, [%[r], #220]\\n\\t\"\n        \"ldr\tr4, [%[a], #224]\\n\\t\"\n        \"ldr\tr6, [%[a], #228]\\n\\t\"\n        \"ldr\tr5, [%[b], #224]\\n\\t\"\n        \"ldr\tr7, [%[b], #228]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #224]\\n\\t\"\n        \"str\tr6, [%[r], #228]\\n\\t\"\n        \"ldr\tr4, [%[a], #232]\\n\\t\"\n        \"ldr\tr6, [%[a], #236]\\n\\t\"\n        \"ldr\tr5, [%[b], #232]\\n\\t\"\n        \"ldr\tr7, [%[b], #236]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #232]\\n\\t\"\n        \"str\tr6, [%[r], #236]\\n\\t\"\n        \"ldr\tr4, [%[a], #240]\\n\\t\"\n        \"ldr\tr6, [%[a], #244]\\n\\t\"\n        \"ldr\tr5, [%[b], #240]\\n\\t\"\n        \"ldr\tr7, [%[b], #244]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #240]\\n\\t\"\n        \"str\tr6, [%[r], #244]\\n\\t\"\n        \"ldr\tr4, [%[a], #248]\\n\\t\"\n        \"ldr\tr6, [%[a], #252]\\n\\t\"\n        \"ldr\tr5, [%[b], #248]\\n\\t\"\n        \"ldr\tr7, [%[b], #252]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #248]\\n\\t\"\n        \"str\tr6, [%[r], #252]\\n\\t\"\n        \"ldr\tr4, [%[a], #256]\\n\\t\"\n        \"ldr\tr6, [%[a], #260]\\n\\t\"\n        \"ldr\tr5, [%[b], #256]\\n\\t\"\n        \"ldr\tr7, [%[b], #260]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #256]\\n\\t\"\n        \"str\tr6, [%[r], #260]\\n\\t\"\n        \"ldr\tr4, [%[a], #264]\\n\\t\"\n        \"ldr\tr6, [%[a], #268]\\n\\t\"\n        \"ldr\tr5, [%[b], #264]\\n\\t\"\n        \"ldr\tr7, [%[b], #268]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #264]\\n\\t\"\n        \"str\tr6, [%[r], #268]\\n\\t\"\n        \"ldr\tr4, [%[a], #272]\\n\\t\"\n        \"ldr\tr6, [%[a], #276]\\n\\t\"\n        \"ldr\tr5, [%[b], #272]\\n\\t\"\n        \"ldr\tr7, [%[b], #276]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #272]\\n\\t\"\n        \"str\tr6, [%[r], #276]\\n\\t\"\n        \"ldr\tr4, [%[a], #280]\\n\\t\"\n        \"ldr\tr6, [%[a], #284]\\n\\t\"\n        \"ldr\tr5, [%[b], #280]\\n\\t\"\n        \"ldr\tr7, [%[b], #284]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #280]\\n\\t\"\n        \"str\tr6, [%[r], #284]\\n\\t\"\n        \"ldr\tr4, [%[a], #288]\\n\\t\"\n        \"ldr\tr6, [%[a], #292]\\n\\t\"\n        \"ldr\tr5, [%[b], #288]\\n\\t\"\n        \"ldr\tr7, [%[b], #292]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #288]\\n\\t\"\n        \"str\tr6, [%[r], #292]\\n\\t\"\n        \"ldr\tr4, [%[a], #296]\\n\\t\"\n        \"ldr\tr6, [%[a], #300]\\n\\t\"\n        \"ldr\tr5, [%[b], #296]\\n\\t\"\n        \"ldr\tr7, [%[b], #300]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #296]\\n\\t\"\n        \"str\tr6, [%[r], #300]\\n\\t\"\n        \"ldr\tr4, [%[a], #304]\\n\\t\"\n        \"ldr\tr6, [%[a], #308]\\n\\t\"\n        \"ldr\tr5, [%[b], #304]\\n\\t\"\n        \"ldr\tr7, [%[b], #308]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #304]\\n\\t\"\n        \"str\tr6, [%[r], #308]\\n\\t\"\n        \"ldr\tr4, [%[a], #312]\\n\\t\"\n        \"ldr\tr6, [%[a], #316]\\n\\t\"\n        \"ldr\tr5, [%[b], #312]\\n\\t\"\n        \"ldr\tr7, [%[b], #316]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #312]\\n\\t\"\n        \"str\tr6, [%[r], #316]\\n\\t\"\n        \"ldr\tr4, [%[a], #320]\\n\\t\"\n        \"ldr\tr6, [%[a], #324]\\n\\t\"\n        \"ldr\tr5, [%[b], #320]\\n\\t\"\n        \"ldr\tr7, [%[b], #324]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #320]\\n\\t\"\n        \"str\tr6, [%[r], #324]\\n\\t\"\n        \"ldr\tr4, [%[a], #328]\\n\\t\"\n        \"ldr\tr6, [%[a], #332]\\n\\t\"\n        \"ldr\tr5, [%[b], #328]\\n\\t\"\n        \"ldr\tr7, [%[b], #332]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #328]\\n\\t\"\n        \"str\tr6, [%[r], #332]\\n\\t\"\n        \"ldr\tr4, [%[a], #336]\\n\\t\"\n        \"ldr\tr6, [%[a], #340]\\n\\t\"\n        \"ldr\tr5, [%[b], #336]\\n\\t\"\n        \"ldr\tr7, [%[b], #340]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #336]\\n\\t\"\n        \"str\tr6, [%[r], #340]\\n\\t\"\n        \"ldr\tr4, [%[a], #344]\\n\\t\"\n        \"ldr\tr6, [%[a], #348]\\n\\t\"\n        \"ldr\tr5, [%[b], #344]\\n\\t\"\n        \"ldr\tr7, [%[b], #348]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #344]\\n\\t\"\n        \"str\tr6, [%[r], #348]\\n\\t\"\n        \"ldr\tr4, [%[a], #352]\\n\\t\"\n        \"ldr\tr6, [%[a], #356]\\n\\t\"\n        \"ldr\tr5, [%[b], #352]\\n\\t\"\n        \"ldr\tr7, [%[b], #356]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #352]\\n\\t\"\n        \"str\tr6, [%[r], #356]\\n\\t\"\n        \"ldr\tr4, [%[a], #360]\\n\\t\"\n        \"ldr\tr6, [%[a], #364]\\n\\t\"\n        \"ldr\tr5, [%[b], #360]\\n\\t\"\n        \"ldr\tr7, [%[b], #364]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #360]\\n\\t\"\n        \"str\tr6, [%[r], #364]\\n\\t\"\n        \"ldr\tr4, [%[a], #368]\\n\\t\"\n        \"ldr\tr6, [%[a], #372]\\n\\t\"\n        \"ldr\tr5, [%[b], #368]\\n\\t\"\n        \"ldr\tr7, [%[b], #372]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #368]\\n\\t\"\n        \"str\tr6, [%[r], #372]\\n\\t\"\n        \"ldr\tr4, [%[a], #376]\\n\\t\"\n        \"ldr\tr6, [%[a], #380]\\n\\t\"\n        \"ldr\tr5, [%[b], #376]\\n\\t\"\n        \"ldr\tr7, [%[b], #380]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #376]\\n\\t\"\n        \"str\tr6, [%[r], #380]\\n\\t\"\n        \"ldr\tr4, [%[a], #384]\\n\\t\"\n        \"ldr\tr6, [%[a], #388]\\n\\t\"\n        \"ldr\tr5, [%[b], #384]\\n\\t\"\n        \"ldr\tr7, [%[b], #388]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #384]\\n\\t\"\n        \"str\tr6, [%[r], #388]\\n\\t\"\n        \"ldr\tr4, [%[a], #392]\\n\\t\"\n        \"ldr\tr6, [%[a], #396]\\n\\t\"\n        \"ldr\tr5, [%[b], #392]\\n\\t\"\n        \"ldr\tr7, [%[b], #396]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #392]\\n\\t\"\n        \"str\tr6, [%[r], #396]\\n\\t\"\n        \"ldr\tr4, [%[a], #400]\\n\\t\"\n        \"ldr\tr6, [%[a], #404]\\n\\t\"\n        \"ldr\tr5, [%[b], #400]\\n\\t\"\n        \"ldr\tr7, [%[b], #404]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #400]\\n\\t\"\n        \"str\tr6, [%[r], #404]\\n\\t\"\n        \"ldr\tr4, [%[a], #408]\\n\\t\"\n        \"ldr\tr6, [%[a], #412]\\n\\t\"\n        \"ldr\tr5, [%[b], #408]\\n\\t\"\n        \"ldr\tr7, [%[b], #412]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #408]\\n\\t\"\n        \"str\tr6, [%[r], #412]\\n\\t\"\n        \"ldr\tr4, [%[a], #416]\\n\\t\"\n        \"ldr\tr6, [%[a], #420]\\n\\t\"\n        \"ldr\tr5, [%[b], #416]\\n\\t\"\n        \"ldr\tr7, [%[b], #420]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #416]\\n\\t\"\n        \"str\tr6, [%[r], #420]\\n\\t\"\n        \"ldr\tr4, [%[a], #424]\\n\\t\"\n        \"ldr\tr6, [%[a], #428]\\n\\t\"\n        \"ldr\tr5, [%[b], #424]\\n\\t\"\n        \"ldr\tr7, [%[b], #428]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #424]\\n\\t\"\n        \"str\tr6, [%[r], #428]\\n\\t\"\n        \"ldr\tr4, [%[a], #432]\\n\\t\"\n        \"ldr\tr6, [%[a], #436]\\n\\t\"\n        \"ldr\tr5, [%[b], #432]\\n\\t\"\n        \"ldr\tr7, [%[b], #436]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #432]\\n\\t\"\n        \"str\tr6, [%[r], #436]\\n\\t\"\n        \"ldr\tr4, [%[a], #440]\\n\\t\"\n        \"ldr\tr6, [%[a], #444]\\n\\t\"\n        \"ldr\tr5, [%[b], #440]\\n\\t\"\n        \"ldr\tr7, [%[b], #444]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #440]\\n\\t\"\n        \"str\tr6, [%[r], #444]\\n\\t\"\n        \"ldr\tr4, [%[a], #448]\\n\\t\"\n        \"ldr\tr6, [%[a], #452]\\n\\t\"\n        \"ldr\tr5, [%[b], #448]\\n\\t\"\n        \"ldr\tr7, [%[b], #452]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #448]\\n\\t\"\n        \"str\tr6, [%[r], #452]\\n\\t\"\n        \"ldr\tr4, [%[a], #456]\\n\\t\"\n        \"ldr\tr6, [%[a], #460]\\n\\t\"\n        \"ldr\tr5, [%[b], #456]\\n\\t\"\n        \"ldr\tr7, [%[b], #460]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #456]\\n\\t\"\n        \"str\tr6, [%[r], #460]\\n\\t\"\n        \"ldr\tr4, [%[a], #464]\\n\\t\"\n        \"ldr\tr6, [%[a], #468]\\n\\t\"\n        \"ldr\tr5, [%[b], #464]\\n\\t\"\n        \"ldr\tr7, [%[b], #468]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #464]\\n\\t\"\n        \"str\tr6, [%[r], #468]\\n\\t\"\n        \"ldr\tr4, [%[a], #472]\\n\\t\"\n        \"ldr\tr6, [%[a], #476]\\n\\t\"\n        \"ldr\tr5, [%[b], #472]\\n\\t\"\n        \"ldr\tr7, [%[b], #476]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #472]\\n\\t\"\n        \"str\tr6, [%[r], #476]\\n\\t\"\n        \"ldr\tr4, [%[a], #480]\\n\\t\"\n        \"ldr\tr6, [%[a], #484]\\n\\t\"\n        \"ldr\tr5, [%[b], #480]\\n\\t\"\n        \"ldr\tr7, [%[b], #484]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #480]\\n\\t\"\n        \"str\tr6, [%[r], #484]\\n\\t\"\n        \"ldr\tr4, [%[a], #488]\\n\\t\"\n        \"ldr\tr6, [%[a], #492]\\n\\t\"\n        \"ldr\tr5, [%[b], #488]\\n\\t\"\n        \"ldr\tr7, [%[b], #492]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #488]\\n\\t\"\n        \"str\tr6, [%[r], #492]\\n\\t\"\n        \"ldr\tr4, [%[a], #496]\\n\\t\"\n        \"ldr\tr6, [%[a], #500]\\n\\t\"\n        \"ldr\tr5, [%[b], #496]\\n\\t\"\n        \"ldr\tr7, [%[b], #500]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #496]\\n\\t\"\n        \"str\tr6, [%[r], #500]\\n\\t\"\n        \"ldr\tr4, [%[a], #504]\\n\\t\"\n        \"ldr\tr6, [%[a], #508]\\n\\t\"\n        \"ldr\tr5, [%[b], #504]\\n\\t\"\n        \"ldr\tr7, [%[b], #508]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #504]\\n\\t\"\n        \"str\tr6, [%[r], #508]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r4\", \"r6\", \"r5\", \"r7\", \"r8\", \"r9\"\n    );\n#endif /* WOLFSSL_SP_SMALL */\n\n    return c;\n}\n\n/* Reduce the number back to 4096 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"# i = 0\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr10, [%[a], #0]\\n\\t\"\n        \"ldr\tr14, [%[a], #4]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mul\tr8, %[mp], r10\\n\\t\"\n        \"# a[i+0] += m[0] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #0]\\n\\t\"\n        \"ldr\tr9, [%[a], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr10, r10, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"# a[i+1] += m[1] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #4]\\n\\t\"\n        \"ldr\tr9, [%[a], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr10, r14, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr10, r10, r5\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+2] += m[2] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #8]\\n\\t\"\n        \"ldr\tr14, [%[a], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr14, r14, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr14, r14, r4\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+3] += m[3] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #12]\\n\\t\"\n        \"ldr\tr9, [%[a], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #12]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+4] += m[4] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #16]\\n\\t\"\n        \"ldr\tr9, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #16]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+5] += m[5] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #20]\\n\\t\"\n        \"ldr\tr9, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #20]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+6] += m[6] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #24]\\n\\t\"\n        \"ldr\tr9, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #24]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+7] += m[7] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #28]\\n\\t\"\n        \"ldr\tr9, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #28]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+8] += m[8] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #32]\\n\\t\"\n        \"ldr\tr9, [%[a], #32]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #32]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+9] += m[9] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #36]\\n\\t\"\n        \"ldr\tr9, [%[a], #36]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #36]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+10] += m[10] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #40]\\n\\t\"\n        \"ldr\tr9, [%[a], #40]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #40]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+11] += m[11] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #44]\\n\\t\"\n        \"ldr\tr9, [%[a], #44]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #44]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+12] += m[12] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #48]\\n\\t\"\n        \"ldr\tr9, [%[a], #48]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #48]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+13] += m[13] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #52]\\n\\t\"\n        \"ldr\tr9, [%[a], #52]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #52]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+14] += m[14] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #56]\\n\\t\"\n        \"ldr\tr9, [%[a], #56]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #56]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+15] += m[15] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #60]\\n\\t\"\n        \"ldr\tr9, [%[a], #60]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #60]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+16] += m[16] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #64]\\n\\t\"\n        \"ldr\tr9, [%[a], #64]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #64]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+17] += m[17] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #68]\\n\\t\"\n        \"ldr\tr9, [%[a], #68]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #68]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+18] += m[18] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #72]\\n\\t\"\n        \"ldr\tr9, [%[a], #72]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #72]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+19] += m[19] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #76]\\n\\t\"\n        \"ldr\tr9, [%[a], #76]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #76]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+20] += m[20] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #80]\\n\\t\"\n        \"ldr\tr9, [%[a], #80]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #80]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+21] += m[21] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #84]\\n\\t\"\n        \"ldr\tr9, [%[a], #84]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #84]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+22] += m[22] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #88]\\n\\t\"\n        \"ldr\tr9, [%[a], #88]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #88]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+23] += m[23] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #92]\\n\\t\"\n        \"ldr\tr9, [%[a], #92]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #92]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+24] += m[24] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #96]\\n\\t\"\n        \"ldr\tr9, [%[a], #96]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #96]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+25] += m[25] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #100]\\n\\t\"\n        \"ldr\tr9, [%[a], #100]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #100]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+26] += m[26] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #104]\\n\\t\"\n        \"ldr\tr9, [%[a], #104]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #104]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+27] += m[27] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #108]\\n\\t\"\n        \"ldr\tr9, [%[a], #108]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #108]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+28] += m[28] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #112]\\n\\t\"\n        \"ldr\tr9, [%[a], #112]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #112]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+29] += m[29] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #116]\\n\\t\"\n        \"ldr\tr9, [%[a], #116]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #116]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+30] += m[30] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #120]\\n\\t\"\n        \"ldr\tr9, [%[a], #120]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #120]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+31] += m[31] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #124]\\n\\t\"\n        \"ldr\tr9, [%[a], #124]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #124]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+32] += m[32] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #128]\\n\\t\"\n        \"ldr\tr9, [%[a], #128]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #128]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+33] += m[33] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #132]\\n\\t\"\n        \"ldr\tr9, [%[a], #132]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #132]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+34] += m[34] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #136]\\n\\t\"\n        \"ldr\tr9, [%[a], #136]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #136]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+35] += m[35] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #140]\\n\\t\"\n        \"ldr\tr9, [%[a], #140]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #140]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+36] += m[36] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #144]\\n\\t\"\n        \"ldr\tr9, [%[a], #144]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #144]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+37] += m[37] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #148]\\n\\t\"\n        \"ldr\tr9, [%[a], #148]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #148]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+38] += m[38] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #152]\\n\\t\"\n        \"ldr\tr9, [%[a], #152]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #152]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+39] += m[39] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #156]\\n\\t\"\n        \"ldr\tr9, [%[a], #156]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #156]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+40] += m[40] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #160]\\n\\t\"\n        \"ldr\tr9, [%[a], #160]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #160]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+41] += m[41] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #164]\\n\\t\"\n        \"ldr\tr9, [%[a], #164]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #164]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+42] += m[42] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #168]\\n\\t\"\n        \"ldr\tr9, [%[a], #168]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #168]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+43] += m[43] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #172]\\n\\t\"\n        \"ldr\tr9, [%[a], #172]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #172]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+44] += m[44] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #176]\\n\\t\"\n        \"ldr\tr9, [%[a], #176]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #176]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+45] += m[45] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #180]\\n\\t\"\n        \"ldr\tr9, [%[a], #180]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #180]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+46] += m[46] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #184]\\n\\t\"\n        \"ldr\tr9, [%[a], #184]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #184]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+47] += m[47] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #188]\\n\\t\"\n        \"ldr\tr9, [%[a], #188]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #188]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+48] += m[48] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #192]\\n\\t\"\n        \"ldr\tr9, [%[a], #192]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #192]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+49] += m[49] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #196]\\n\\t\"\n        \"ldr\tr9, [%[a], #196]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #196]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+50] += m[50] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #200]\\n\\t\"\n        \"ldr\tr9, [%[a], #200]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #200]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+51] += m[51] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #204]\\n\\t\"\n        \"ldr\tr9, [%[a], #204]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #204]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+52] += m[52] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #208]\\n\\t\"\n        \"ldr\tr9, [%[a], #208]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #208]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+53] += m[53] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #212]\\n\\t\"\n        \"ldr\tr9, [%[a], #212]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #212]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+54] += m[54] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #216]\\n\\t\"\n        \"ldr\tr9, [%[a], #216]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #216]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+55] += m[55] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #220]\\n\\t\"\n        \"ldr\tr9, [%[a], #220]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #220]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+56] += m[56] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #224]\\n\\t\"\n        \"ldr\tr9, [%[a], #224]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #224]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+57] += m[57] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #228]\\n\\t\"\n        \"ldr\tr9, [%[a], #228]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #228]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+58] += m[58] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #232]\\n\\t\"\n        \"ldr\tr9, [%[a], #232]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #232]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+59] += m[59] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #236]\\n\\t\"\n        \"ldr\tr9, [%[a], #236]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #236]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+60] += m[60] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #240]\\n\\t\"\n        \"ldr\tr9, [%[a], #240]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #240]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+61] += m[61] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #244]\\n\\t\"\n        \"ldr\tr9, [%[a], #244]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #244]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+62] += m[62] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #248]\\n\\t\"\n        \"ldr\tr9, [%[a], #248]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #248]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+63] += m[63] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #252]\\n\\t\"\n        \"ldr\tr9, [%[a], #252]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #252]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+64] += m[64] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #256]\\n\\t\"\n        \"ldr\tr9, [%[a], #256]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #256]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+65] += m[65] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #260]\\n\\t\"\n        \"ldr\tr9, [%[a], #260]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #260]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+66] += m[66] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #264]\\n\\t\"\n        \"ldr\tr9, [%[a], #264]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #264]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+67] += m[67] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #268]\\n\\t\"\n        \"ldr\tr9, [%[a], #268]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #268]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+68] += m[68] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #272]\\n\\t\"\n        \"ldr\tr9, [%[a], #272]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #272]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+69] += m[69] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #276]\\n\\t\"\n        \"ldr\tr9, [%[a], #276]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #276]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+70] += m[70] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #280]\\n\\t\"\n        \"ldr\tr9, [%[a], #280]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #280]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+71] += m[71] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #284]\\n\\t\"\n        \"ldr\tr9, [%[a], #284]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #284]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+72] += m[72] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #288]\\n\\t\"\n        \"ldr\tr9, [%[a], #288]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #288]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+73] += m[73] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #292]\\n\\t\"\n        \"ldr\tr9, [%[a], #292]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #292]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+74] += m[74] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #296]\\n\\t\"\n        \"ldr\tr9, [%[a], #296]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #296]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+75] += m[75] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #300]\\n\\t\"\n        \"ldr\tr9, [%[a], #300]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #300]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+76] += m[76] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #304]\\n\\t\"\n        \"ldr\tr9, [%[a], #304]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #304]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+77] += m[77] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #308]\\n\\t\"\n        \"ldr\tr9, [%[a], #308]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #308]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+78] += m[78] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #312]\\n\\t\"\n        \"ldr\tr9, [%[a], #312]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #312]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+79] += m[79] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #316]\\n\\t\"\n        \"ldr\tr9, [%[a], #316]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #316]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+80] += m[80] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #320]\\n\\t\"\n        \"ldr\tr9, [%[a], #320]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #320]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+81] += m[81] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #324]\\n\\t\"\n        \"ldr\tr9, [%[a], #324]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #324]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+82] += m[82] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #328]\\n\\t\"\n        \"ldr\tr9, [%[a], #328]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #328]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+83] += m[83] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #332]\\n\\t\"\n        \"ldr\tr9, [%[a], #332]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #332]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+84] += m[84] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #336]\\n\\t\"\n        \"ldr\tr9, [%[a], #336]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #336]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+85] += m[85] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #340]\\n\\t\"\n        \"ldr\tr9, [%[a], #340]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #340]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+86] += m[86] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #344]\\n\\t\"\n        \"ldr\tr9, [%[a], #344]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #344]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+87] += m[87] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #348]\\n\\t\"\n        \"ldr\tr9, [%[a], #348]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #348]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+88] += m[88] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #352]\\n\\t\"\n        \"ldr\tr9, [%[a], #352]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #352]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+89] += m[89] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #356]\\n\\t\"\n        \"ldr\tr9, [%[a], #356]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #356]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+90] += m[90] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #360]\\n\\t\"\n        \"ldr\tr9, [%[a], #360]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #360]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+91] += m[91] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #364]\\n\\t\"\n        \"ldr\tr9, [%[a], #364]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #364]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+92] += m[92] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #368]\\n\\t\"\n        \"ldr\tr9, [%[a], #368]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #368]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+93] += m[93] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #372]\\n\\t\"\n        \"ldr\tr9, [%[a], #372]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #372]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+94] += m[94] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #376]\\n\\t\"\n        \"ldr\tr9, [%[a], #376]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #376]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+95] += m[95] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #380]\\n\\t\"\n        \"ldr\tr9, [%[a], #380]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #380]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+96] += m[96] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #384]\\n\\t\"\n        \"ldr\tr9, [%[a], #384]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #384]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+97] += m[97] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #388]\\n\\t\"\n        \"ldr\tr9, [%[a], #388]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #388]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+98] += m[98] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #392]\\n\\t\"\n        \"ldr\tr9, [%[a], #392]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #392]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+99] += m[99] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #396]\\n\\t\"\n        \"ldr\tr9, [%[a], #396]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #396]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+100] += m[100] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #400]\\n\\t\"\n        \"ldr\tr9, [%[a], #400]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #400]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+101] += m[101] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #404]\\n\\t\"\n        \"ldr\tr9, [%[a], #404]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #404]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+102] += m[102] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #408]\\n\\t\"\n        \"ldr\tr9, [%[a], #408]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #408]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+103] += m[103] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #412]\\n\\t\"\n        \"ldr\tr9, [%[a], #412]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #412]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+104] += m[104] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #416]\\n\\t\"\n        \"ldr\tr9, [%[a], #416]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #416]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+105] += m[105] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #420]\\n\\t\"\n        \"ldr\tr9, [%[a], #420]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #420]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+106] += m[106] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #424]\\n\\t\"\n        \"ldr\tr9, [%[a], #424]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #424]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+107] += m[107] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #428]\\n\\t\"\n        \"ldr\tr9, [%[a], #428]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #428]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+108] += m[108] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #432]\\n\\t\"\n        \"ldr\tr9, [%[a], #432]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #432]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+109] += m[109] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #436]\\n\\t\"\n        \"ldr\tr9, [%[a], #436]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #436]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+110] += m[110] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #440]\\n\\t\"\n        \"ldr\tr9, [%[a], #440]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #440]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+111] += m[111] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #444]\\n\\t\"\n        \"ldr\tr9, [%[a], #444]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #444]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+112] += m[112] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #448]\\n\\t\"\n        \"ldr\tr9, [%[a], #448]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #448]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+113] += m[113] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #452]\\n\\t\"\n        \"ldr\tr9, [%[a], #452]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #452]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+114] += m[114] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #456]\\n\\t\"\n        \"ldr\tr9, [%[a], #456]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #456]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+115] += m[115] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #460]\\n\\t\"\n        \"ldr\tr9, [%[a], #460]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #460]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+116] += m[116] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #464]\\n\\t\"\n        \"ldr\tr9, [%[a], #464]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #464]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+117] += m[117] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #468]\\n\\t\"\n        \"ldr\tr9, [%[a], #468]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #468]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+118] += m[118] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #472]\\n\\t\"\n        \"ldr\tr9, [%[a], #472]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #472]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+119] += m[119] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #476]\\n\\t\"\n        \"ldr\tr9, [%[a], #476]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #476]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+120] += m[120] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #480]\\n\\t\"\n        \"ldr\tr9, [%[a], #480]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #480]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+121] += m[121] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #484]\\n\\t\"\n        \"ldr\tr9, [%[a], #484]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #484]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+122] += m[122] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #488]\\n\\t\"\n        \"ldr\tr9, [%[a], #488]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #488]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+123] += m[123] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #492]\\n\\t\"\n        \"ldr\tr9, [%[a], #492]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #492]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+124] += m[124] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #496]\\n\\t\"\n        \"ldr\tr9, [%[a], #496]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #496]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+125] += m[125] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #500]\\n\\t\"\n        \"ldr\tr9, [%[a], #500]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #500]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+126] += m[126] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #504]\\n\\t\"\n        \"ldr\tr9, [%[a], #504]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #504]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+127] += m[127] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #508]\\n\\t\"\n        \"ldr   r9, [%[a], #508]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr7, r7, %[ca]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"adc\t%[ca], %[ca], %[ca]\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #508]\\n\\t\"\n        \"ldr\tr9, [%[a], #512]\\n\\t\"\n        \"adcs\tr9, r9, r7\\n\\t\"\n        \"str\tr9, [%[a], #512]\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"add\tr12, r12, #4\\n\\t\"\n        \"cmp\tr12, #512\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr10, [%[a], #0]\\n\\t\"\n        \"str\tr14, [%[a], #4]\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    sp_4096_cond_sub_128(a - 128, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_4096_mul_128(r, a, b);\n    sp_4096_mont_reduce_128(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_sqr_128(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_4096_sqr_128(r, a);\n    sp_4096_mont_reduce_128(r, m, mp);\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nstatic sp_digit div_4096_word_128(sp_digit d1, sp_digit d0, sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr5, %[div], #1\\n\\t\"\n        \"add\tr5, r5, #1\\n\\t\"\n        \"mov\tr6, %[d0]\\n\\t\"\n        \"mov\tr7, %[d1]\\n\\t\"\n        \"# Do top 32\\n\\t\"\n        \"subs\tr8, r5, r7\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        \"and\tr8, r8, r5\\n\\t\"\n        \"subs\tr7, r7, r8\\n\\t\"\n        \"# Next 30 bits\\n\\t\"\n        \"mov\tr4, #29\\n\\t\"\n        \"1:\\n\\t\"\n        \"movs\tr6, r6, lsl #1\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"subs\tr8, r5, r7\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        \"and\tr8, r8, r5\\n\\t\"\n        \"subs\tr7, r7, r8\\n\\t\"\n        \"subs\tr4, r4, #1\\n\\t\"\n        \"bpl\t1b\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"add\t%[r], %[r], #1\\n\\t\"\n        \"umull\tr4, r5, %[r], %[div]\\n\\t\"\n        \"subs\tr4, %[d0], r4\\n\\t\"\n        \"sbc\tr5, %[d1], r5\\n\\t\"\n        \"add\t%[r], %[r], r5\\n\\t\"\n        \"umull\tr4, r5, %[r], %[div]\\n\\t\"\n        \"subs\tr4, %[d0], r4\\n\\t\"\n        \"sbc\tr5, %[d1], r5\\n\\t\"\n        \"add\t%[r], %[r], r5\\n\\t\"\n        \"subs\tr8, %[div], r4\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_4096_mask_128(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<128; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 128; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic int32_t sp_4096_cmp_128(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = -1;\n    sp_digit one = 1;\n\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr3, #-1\\n\\t\"\n        \"mov\tr6, #508\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr4, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr4, r4, r3\\n\\t\"\n        \"and\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"subs\tr6, r6, #4\\n\\t\"\n        \"bcs\t1b\\n\\t\"\n        \"eor\t%[r], %[r], r3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr3, #-1\\n\\t\"\n        \"ldr\t\tr4, [%[a], #508]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #508]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #504]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #504]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #500]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #500]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #496]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #496]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #492]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #492]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #488]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #488]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #484]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #484]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #480]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #480]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #476]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #476]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #472]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #472]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #468]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #468]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #464]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #464]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #460]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #460]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #456]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #456]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #452]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #452]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #448]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #448]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #444]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #444]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #440]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #440]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #436]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #436]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #432]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #432]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #428]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #428]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #424]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #424]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #420]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #420]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #416]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #416]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #412]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #412]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #408]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #408]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #404]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #404]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #400]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #400]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #396]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #396]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #392]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #392]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #388]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #388]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #384]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #384]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #380]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #380]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #376]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #376]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #372]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #372]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #368]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #368]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #364]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #364]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #360]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #360]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #356]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #356]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #352]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #352]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #348]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #348]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #344]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #344]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #340]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #340]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #336]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #336]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #332]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #332]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #328]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #328]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #324]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #324]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #320]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #320]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #316]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #316]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #312]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #312]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #308]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #308]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #304]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #304]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #300]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #300]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #296]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #296]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #292]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #292]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #288]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #288]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #284]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #284]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #280]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #280]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #276]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #276]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #272]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #272]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #268]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #268]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #264]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #264]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #260]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #260]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #256]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #256]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #252]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #252]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #248]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #248]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #244]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #244]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #240]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #240]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #236]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #236]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #232]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #232]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #228]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #228]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #224]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #224]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #220]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #220]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #216]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #216]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #212]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #212]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #208]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #208]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #204]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #204]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #200]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #200]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #196]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #196]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #192]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #192]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #188]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #188]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #184]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #184]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #180]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #180]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #176]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #176]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #172]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #172]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #168]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #168]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #164]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #164]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #160]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #160]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #156]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #156]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #152]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #152]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #148]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #148]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #144]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #144]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #140]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #140]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #136]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #136]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #132]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #132]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #128]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #128]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #124]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #120]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #116]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #112]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #108]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #104]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #100]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #96]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #92]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #88]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #84]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #80]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #76]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #72]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #68]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #64]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #60]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #56]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #52]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #48]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #44]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #40]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #36]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #32]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #28]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #24]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #20]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #16]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #12]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #8]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #4]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #0]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"eor\t%[r], %[r], r3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n#endif\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_div_128(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[256], t2[129];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n\n    div = d[127];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 128);\n    for (i=127; i>=0; i--) {\n        r1 = div_4096_word_128(t1[128 + i], t1[128 + i - 1], div);\n\n        sp_4096_mul_d_128(t2, d, r1);\n        t1[128 + i] += sp_4096_sub_in_place_128(&t1[i], t2);\n        t1[128 + i] -= t2[128];\n        sp_4096_mask_128(t2, d, t1[128 + i]);\n        t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], t2);\n        sp_4096_mask_128(t2, d, t1[128 + i]);\n        t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_4096_cmp_128(t1, d) >= 0;\n    sp_4096_cond_sub_128(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_mod_128(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_128(a, m, NULL, r);\n}\n\n#endif /* WOLFSSL_RSA_PUBLIC_ONLY */\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_div_128_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[256], t2[129];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n\n    div = d[127];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 128);\n    for (i=127; i>=0; i--) {\n        r1 = div_4096_word_128(t1[128 + i], t1[128 + i - 1], div);\n\n        sp_4096_mul_d_128(t2, d, r1);\n        t1[128 + i] += sp_4096_sub_in_place_128(&t1[i], t2);\n        t1[128 + i] -= t2[128];\n        if (t1[128 + i] != 0) {\n            t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], d);\n            if (t1[128 + i] != 0)\n                t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_4096_cmp_128(t1, d) >= 0;\n    sp_4096_cond_sub_128(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_mod_128_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_128_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][256];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 256, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 256;\n        }\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_128(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 128U);\n        if (reduceA != 0) {\n            err = sp_4096_mod_128(t[1] + 128, a, m);\n            if (err == MP_OKAY) {\n                err = sp_4096_mod_128(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 128, a, sizeof(sp_digit) * 128);\n            err = sp_4096_mod_128(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_128(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_128(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_128(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_128(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_128(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_128(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_128(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_128(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_128(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_128(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_128(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_128(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_128(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_128(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 128);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n\n            sp_4096_mont_mul_128(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[128], 0, sizeof(sp_digit) * 128U);\n        sp_4096_mont_reduce_128(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_128(r, m) >= 0);\n        sp_4096_cond_sub_128(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][256];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 256, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 256;\n        }\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_128(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 128U);\n        if (reduceA != 0) {\n            err = sp_4096_mod_128(t[1] + 128, a, m);\n            if (err == MP_OKAY) {\n                err = sp_4096_mod_128(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 128, a, sizeof(sp_digit) * 128);\n            err = sp_4096_mod_128(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_128(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_128(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_128(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_128(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_128(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_128(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_128(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_128(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_128(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_128(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_128(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_128(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_128(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_128(t[15], t[ 8], t[ 7], m, mp);\n        sp_4096_mont_sqr_128(t[16], t[ 8], m, mp);\n        sp_4096_mont_mul_128(t[17], t[ 9], t[ 8], m, mp);\n        sp_4096_mont_sqr_128(t[18], t[ 9], m, mp);\n        sp_4096_mont_mul_128(t[19], t[10], t[ 9], m, mp);\n        sp_4096_mont_sqr_128(t[20], t[10], m, mp);\n        sp_4096_mont_mul_128(t[21], t[11], t[10], m, mp);\n        sp_4096_mont_sqr_128(t[22], t[11], m, mp);\n        sp_4096_mont_mul_128(t[23], t[12], t[11], m, mp);\n        sp_4096_mont_sqr_128(t[24], t[12], m, mp);\n        sp_4096_mont_mul_128(t[25], t[13], t[12], m, mp);\n        sp_4096_mont_sqr_128(t[26], t[13], m, mp);\n        sp_4096_mont_mul_128(t[27], t[14], t[13], m, mp);\n        sp_4096_mont_sqr_128(t[28], t[14], m, mp);\n        sp_4096_mont_mul_128(t[29], t[15], t[14], m, mp);\n        sp_4096_mont_sqr_128(t[30], t[15], m, mp);\n        sp_4096_mont_mul_128(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 128);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n\n            sp_4096_mont_mul_128(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[128], 0, sizeof(sp_digit) * 128U);\n        sp_4096_mont_reduce_128(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_128(r, m) >= 0);\n        sp_4096_cond_sub_128(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[256], md[128], rd[256];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1];\n    int err = MP_OKAY;\n\n    if (*outLen < 512)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 32 || inLen > 512 ||\n                                                     mp_count_bits(mm) != 4096))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 128 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 128 * 2;\n        m = r + 128 * 2;\n        ah = a + 128;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 128;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(ah, 128, in, inLen);\n#if DIGIT_BIT >= 32\n        e[0] = em->dp[0];\n#else\n        e[0] = em->dp[0];\n        if (em->used > 1)\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e[0] == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(m, 128, mm);\n\n        if (e[0] == 0x3) {\n            if (err == MP_OKAY) {\n                sp_4096_sqr_128(r, ah);\n                err = sp_4096_mod_128_cond(r, r, m);\n            }\n            if (err == MP_OKAY) {\n                sp_4096_mul_128(r, ah, r);\n                err = sp_4096_mod_128_cond(r, r, m);\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_4096_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 128);\n            err = sp_4096_mod_128_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=31; i>=0; i--)\n                    if (e[0] >> i)\n                        break;\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 128);\n                for (i--; i>=0; i--) {\n                    sp_4096_mont_sqr_128(r, r, m, mp);\n                    if (((e[0] >> i) & 1) == 1)\n                        sp_4096_mont_mul_128(r, r, a, m, mp);\n                }\n                XMEMSET(&r[128], 0, sizeof(sp_digit) * 128);\n                sp_4096_mont_reduce_128(r, m, mp);\n\n                for (i = 127; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_4096_sub_in_place_128(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[128 * 2];\n    sp_digit pd[64], qd[64], dpd[64];\n    sp_digit tmpad[128], tmpbd[128];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 512)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 512 || mp_count_bits(mm) != 4096))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 64 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 128 * 2;\n        q = p + 64;\n        qi = dq = dp = q + 64;\n        tmpa = qi + 64;\n        tmpb = tmpa + 128;\n\n        tmp = t;\n        r = tmp + 128;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 128;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(a, 128, in, inLen);\n        sp_4096_from_mp(p, 64, pm);\n        sp_4096_from_mp(q, 64, qm);\n        sp_4096_from_mp(dp, 64, dpm);\n\n        err = sp_4096_mod_exp_64(tmpa, a, dp, 2048, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(dq, 64, dqm);\n        err = sp_4096_mod_exp_64(tmpb, a, dq, 2048, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_4096_sub_in_place_64(tmpa, tmpb);\n        sp_4096_mask_64(tmp, p, c);\n        sp_4096_add_64(tmpa, tmpa, tmp);\n\n        sp_4096_from_mp(qi, 64, qim);\n        sp_4096_mul_64(tmpa, tmpa, qi);\n        err = sp_4096_mod_64(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mul_64(tmpa, q, tmpa);\n        XMEMSET(&tmpb[64], 0, sizeof(sp_digit) * 64);\n        sp_4096_add_128(r, tmpb, tmpa);\n\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 64 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_4096_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (4096 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 32\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 128);\n        r->used = 128;\n        mp_clamp(r);\n#elif DIGIT_BIT < 32\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 128; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 32) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 32 - s;\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 128; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 32 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 32 - s;\n            }\n            else {\n                s += 32;\n            }\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[256], e[128], m[128];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 128, base);\n        sp_4096_from_mp(e, 128, exp);\n        sp_4096_from_mp(m, 128, mod);\n\n        err = sp_4096_mod_exp_128(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_4096_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_4096\nstatic void sp_4096_lshift_128(sp_digit* r, sp_digit* a, byte n)\n{\n    __asm__ __volatile__ (\n        \"mov\tr6, #31\\n\\t\"\n        \"sub\tr6, r6, %[n]\\n\\t\"\n        \"ldr\tr3, [%[a], #508]\\n\\t\"\n        \"lsr\tr4, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr4, r4, r6\\n\\t\"\n        \"ldr\tr2, [%[a], #504]\\n\\t\"\n        \"str\tr4, [%[r], #512]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #500]\\n\\t\"\n        \"str\tr3, [%[r], #508]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #496]\\n\\t\"\n        \"str\tr2, [%[r], #504]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #492]\\n\\t\"\n        \"str\tr4, [%[r], #500]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #488]\\n\\t\"\n        \"str\tr3, [%[r], #496]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #484]\\n\\t\"\n        \"str\tr2, [%[r], #492]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #480]\\n\\t\"\n        \"str\tr4, [%[r], #488]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #476]\\n\\t\"\n        \"str\tr3, [%[r], #484]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #472]\\n\\t\"\n        \"str\tr2, [%[r], #480]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #468]\\n\\t\"\n        \"str\tr4, [%[r], #476]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #464]\\n\\t\"\n        \"str\tr3, [%[r], #472]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #460]\\n\\t\"\n        \"str\tr2, [%[r], #468]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #456]\\n\\t\"\n        \"str\tr4, [%[r], #464]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #452]\\n\\t\"\n        \"str\tr3, [%[r], #460]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #448]\\n\\t\"\n        \"str\tr2, [%[r], #456]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #444]\\n\\t\"\n        \"str\tr4, [%[r], #452]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #440]\\n\\t\"\n        \"str\tr3, [%[r], #448]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #436]\\n\\t\"\n        \"str\tr2, [%[r], #444]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #432]\\n\\t\"\n        \"str\tr4, [%[r], #440]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #428]\\n\\t\"\n        \"str\tr3, [%[r], #436]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #424]\\n\\t\"\n        \"str\tr2, [%[r], #432]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #420]\\n\\t\"\n        \"str\tr4, [%[r], #428]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #416]\\n\\t\"\n        \"str\tr3, [%[r], #424]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #412]\\n\\t\"\n        \"str\tr2, [%[r], #420]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #408]\\n\\t\"\n        \"str\tr4, [%[r], #416]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #404]\\n\\t\"\n        \"str\tr3, [%[r], #412]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #400]\\n\\t\"\n        \"str\tr2, [%[r], #408]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #396]\\n\\t\"\n        \"str\tr4, [%[r], #404]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #392]\\n\\t\"\n        \"str\tr3, [%[r], #400]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #388]\\n\\t\"\n        \"str\tr2, [%[r], #396]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #384]\\n\\t\"\n        \"str\tr4, [%[r], #392]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #380]\\n\\t\"\n        \"str\tr3, [%[r], #388]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #376]\\n\\t\"\n        \"str\tr2, [%[r], #384]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #372]\\n\\t\"\n        \"str\tr4, [%[r], #380]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #368]\\n\\t\"\n        \"str\tr3, [%[r], #376]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #364]\\n\\t\"\n        \"str\tr2, [%[r], #372]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #360]\\n\\t\"\n        \"str\tr4, [%[r], #368]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #356]\\n\\t\"\n        \"str\tr3, [%[r], #364]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #352]\\n\\t\"\n        \"str\tr2, [%[r], #360]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #348]\\n\\t\"\n        \"str\tr4, [%[r], #356]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #344]\\n\\t\"\n        \"str\tr3, [%[r], #352]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #340]\\n\\t\"\n        \"str\tr2, [%[r], #348]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #336]\\n\\t\"\n        \"str\tr4, [%[r], #344]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #332]\\n\\t\"\n        \"str\tr3, [%[r], #340]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #328]\\n\\t\"\n        \"str\tr2, [%[r], #336]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #324]\\n\\t\"\n        \"str\tr4, [%[r], #332]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #320]\\n\\t\"\n        \"str\tr3, [%[r], #328]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #316]\\n\\t\"\n        \"str\tr2, [%[r], #324]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #312]\\n\\t\"\n        \"str\tr4, [%[r], #320]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #308]\\n\\t\"\n        \"str\tr3, [%[r], #316]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #304]\\n\\t\"\n        \"str\tr2, [%[r], #312]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #300]\\n\\t\"\n        \"str\tr4, [%[r], #308]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #296]\\n\\t\"\n        \"str\tr3, [%[r], #304]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #292]\\n\\t\"\n        \"str\tr2, [%[r], #300]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #288]\\n\\t\"\n        \"str\tr4, [%[r], #296]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #284]\\n\\t\"\n        \"str\tr3, [%[r], #292]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #280]\\n\\t\"\n        \"str\tr2, [%[r], #288]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #276]\\n\\t\"\n        \"str\tr4, [%[r], #284]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #272]\\n\\t\"\n        \"str\tr3, [%[r], #280]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #268]\\n\\t\"\n        \"str\tr2, [%[r], #276]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #264]\\n\\t\"\n        \"str\tr4, [%[r], #272]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #260]\\n\\t\"\n        \"str\tr3, [%[r], #268]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #256]\\n\\t\"\n        \"str\tr2, [%[r], #264]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #252]\\n\\t\"\n        \"str\tr4, [%[r], #260]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #248]\\n\\t\"\n        \"str\tr3, [%[r], #256]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #244]\\n\\t\"\n        \"str\tr2, [%[r], #252]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #240]\\n\\t\"\n        \"str\tr4, [%[r], #248]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #236]\\n\\t\"\n        \"str\tr3, [%[r], #244]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #232]\\n\\t\"\n        \"str\tr2, [%[r], #240]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #228]\\n\\t\"\n        \"str\tr4, [%[r], #236]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #224]\\n\\t\"\n        \"str\tr3, [%[r], #232]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #220]\\n\\t\"\n        \"str\tr2, [%[r], #228]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #216]\\n\\t\"\n        \"str\tr4, [%[r], #224]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #212]\\n\\t\"\n        \"str\tr3, [%[r], #220]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #208]\\n\\t\"\n        \"str\tr2, [%[r], #216]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #204]\\n\\t\"\n        \"str\tr4, [%[r], #212]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #200]\\n\\t\"\n        \"str\tr3, [%[r], #208]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #196]\\n\\t\"\n        \"str\tr2, [%[r], #204]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #192]\\n\\t\"\n        \"str\tr4, [%[r], #200]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #188]\\n\\t\"\n        \"str\tr3, [%[r], #196]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #184]\\n\\t\"\n        \"str\tr2, [%[r], #192]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #180]\\n\\t\"\n        \"str\tr4, [%[r], #188]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #176]\\n\\t\"\n        \"str\tr3, [%[r], #184]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #172]\\n\\t\"\n        \"str\tr2, [%[r], #180]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #168]\\n\\t\"\n        \"str\tr4, [%[r], #176]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #164]\\n\\t\"\n        \"str\tr3, [%[r], #172]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #160]\\n\\t\"\n        \"str\tr2, [%[r], #168]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #156]\\n\\t\"\n        \"str\tr4, [%[r], #164]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #152]\\n\\t\"\n        \"str\tr3, [%[r], #160]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #148]\\n\\t\"\n        \"str\tr2, [%[r], #156]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #144]\\n\\t\"\n        \"str\tr4, [%[r], #152]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #140]\\n\\t\"\n        \"str\tr3, [%[r], #148]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #136]\\n\\t\"\n        \"str\tr2, [%[r], #144]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #132]\\n\\t\"\n        \"str\tr4, [%[r], #140]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #128]\\n\\t\"\n        \"str\tr3, [%[r], #136]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #124]\\n\\t\"\n        \"str\tr2, [%[r], #132]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #120]\\n\\t\"\n        \"str\tr4, [%[r], #128]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"str\tr3, [%[r], #124]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #112]\\n\\t\"\n        \"str\tr2, [%[r], #120]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #108]\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"str\tr3, [%[r], #112]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #100]\\n\\t\"\n        \"str\tr2, [%[r], #108]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #96]\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"str\tr3, [%[r], #100]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #88]\\n\\t\"\n        \"str\tr2, [%[r], #96]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #84]\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"str\tr3, [%[r], #88]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #76]\\n\\t\"\n        \"str\tr2, [%[r], #84]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #72]\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"str\tr3, [%[r], #76]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #64]\\n\\t\"\n        \"str\tr2, [%[r], #72]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #60]\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr3, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr2, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"str\tr3, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr2, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #28]\\n\\t\"\n        \"str\tr2, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"str\tr3, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr2, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #12]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr2, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"str\tr2, [%[r]]\\n\\t\"\n        \"str\tr3, [%[r], #4]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [n] \"r\" (n)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[256];\n    sp_digit td[129];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 385, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 256;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_128(norm, m);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        sp_4096_lshift_128(r, norm, y);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n\n            sp_4096_lshift_128(r, r, y);\n            sp_4096_mul_d_128(tmp, norm, r[128]);\n            r[128] = 0;\n            o = sp_4096_add_128(r, r, tmp);\n            sp_4096_cond_sub_128(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[128], 0, sizeof(sp_digit) * 128U);\n        sp_4096_mont_reduce_128(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_128(r, m) >= 0);\n        sp_4096_cond_sub_128(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* HAVE_FFDHE_4096 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 512 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[256], e[128], m[128];\n    sp_digit* r = b;\n    word32 i;\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 512) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 128, base);\n        sp_4096_from_bin(e, 128, exp, expLen);\n        sp_4096_from_mp(m, 128, mod);\n\n    #ifdef HAVE_FFDHE_4096\n        if (base->used == 1 && base->dp[0] == 2 && m[127] == (sp_digit)-1)\n            err = sp_4096_mod_exp_2_128(r, e, expLen * 8, m);\n        else\n    #endif\n            err = sp_4096_mod_exp_128(r, b, e, expLen * 8, m, 0);\n\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n        for (i=0; i<512 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* WOLFSSL_SP_4096 */\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n#ifdef WOLFSSL_HAVE_SP_ECC\n#ifndef WOLFSSL_SP_NO_256\n\n/* Point structure to use. */\ntypedef struct sp_point {\n    sp_digit x[2 * 8];\n    sp_digit y[2 * 8];\n    sp_digit z[2 * 8];\n    int infinity;\n} sp_point;\n\n/* The modulus (prime) of the curve P256. */\nstatic const sp_digit p256_mod[8] = {\n    0xffffffff,0xffffffff,0xffffffff,0x00000000,0x00000000,0x00000000,\n    0x00000001,0xffffffff\n};\n/* The Montogmery normalizer for modulus of the curve P256. */\nstatic const sp_digit p256_norm_mod[8] = {\n    0x00000001,0x00000000,0x00000000,0xffffffff,0xffffffff,0xffffffff,\n    0xfffffffe,0x00000000\n};\n/* The Montogmery multiplier for modulus of the curve P256. */\nstatic const sp_digit p256_mp_mod = 0x00000001;\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                            defined(HAVE_ECC_VERIFY)\n/* The order of the curve P256. */\nstatic const sp_digit p256_order[8] = {\n    0xfc632551,0xf3b9cac2,0xa7179e84,0xbce6faad,0xffffffff,0xffffffff,\n    0x00000000,0xffffffff\n};\n#endif\n/* The order of the curve P256 minus 2. */\nstatic const sp_digit p256_order2[8] = {\n    0xfc63254f,0xf3b9cac2,0xa7179e84,0xbce6faad,0xffffffff,0xffffffff,\n    0x00000000,0xffffffff\n};\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery normalizer for order of the curve P256. */\nstatic const sp_digit p256_norm_order[8] = {\n    0x039cdaaf,0x0c46353d,0x58e8617b,0x43190552,0x00000000,0x00000000,\n    0xffffffff,0x00000000\n};\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery multiplier for order of the curve P256. */\nstatic const sp_digit p256_mp_order = 0xee00bc4f;\n#endif\n/* The base point of curve P256. */\nstatic const sp_point p256_base = {\n    /* X ordinate */\n    {\n        0xd898c296,0xf4a13945,0x2deb33a0,0x77037d81,0x63a440f2,0xf8bce6e5,\n        0xe12c4247,0x6b17d1f2, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L\n    },\n    /* Y ordinate */\n    {\n        0x37bf51f5,0xcbb64068,0x6b315ece,0x2bce3357,0x7c0f9e16,0x8ee7eb4a,\n        0xfe1a7f9b,0x4fe342e2, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L\n    },\n    /* Z ordinate */\n    {\n        0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,\n        0x00000000,0x00000000, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L\n    },\n    /* infinity */\n    0\n};\n#if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)\nstatic const sp_digit p256_b[8] = {\n    0x27d2604b,0x3bce3c3e,0xcc53b0f6,0x651d06b0,0x769886bc,0xb3ebbd55,\n    0xaa3a93e7,0x5ac635d8\n};\n#endif\n\nstatic int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p)\n{\n    int ret = MP_OKAY;\n    (void)heap;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    (void)sp;\n    *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC);\n#else\n    *p = sp;\n#endif\n    if (p == NULL) {\n        ret = MEMORY_E;\n    }\n    return ret;\n}\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* Allocate memory for point and return error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p))\n#else\n/* Set pointer to data and return no error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p))\n#endif\n\n\nstatic void sp_ecc_point_free(sp_point* p, int clear, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* If valid pointer then clear point data if requested and free data. */\n    if (p != NULL) {\n        if (clear != 0) {\n            XMEMSET(p, 0, sizeof(*p));\n        }\n        XFREE(p, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n/* Clear point data if requested. */\n    if (clear != 0) {\n        XMEMSET(p, 0, sizeof(*p));\n    }\n#endif\n    (void)heap;\n}\n\n/* Multiply a number by Montogmery normalizer mod modulus (prime).\n *\n * r  The resulting Montgomery form number.\n * a  The number to convert.\n * m  The modulus (prime).\n */\nstatic int sp_256_mod_mul_norm_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #24\\n\\t\"\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[a], #28]\\n\\t\"\n        \"# Clear overflow and underflow\\n\\t\"\n        \"mov\tr14, #0\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"# t[0] =  1  1  0 -1 -1 -1 -1  0\\n\\t\"\n        \"adds\tr10, r2, r3\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"subs\tr10, r10, r5\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr10, r10, r6\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr10, r10, r7\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr10, r10, r8\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"# Store t[0]\\n\\t\"\n        \"str\tr10, [sp, #0]\\n\\t\"\n        \"neg\tr12, r12\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        \"# t[1] =  0  1  1  0 -1 -1 -1 -1\\n\\t\"\n        \"adds\tr14, r14, r3\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr14, r14, r4\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"subs\tr14, r14, r12\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr14, r14, r6\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr14, r14, r7\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr14, r14, r8\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr14, r14, r9\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"# Store t[1]\\n\\t\"\n        \"str\tr14, [sp, #4]\\n\\t\"\n        \"neg\tr12, r12\\n\\t\"\n        \"mov\tr14, #0\\n\\t\"\n        \"# t[2] =  0  0  1  1  0 -1 -1 -1\\n\\t\"\n        \"adds\tr10, r10, r4\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"adds\tr10, r10, r5\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"subs\tr10, r10, r12\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr10, r10, r7\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr10, r10, r8\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr10, r10, r9\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"# Store t[2]\\n\\t\"\n        \"str\tr10, [sp, #8]\\n\\t\"\n        \"neg\tr12, r12\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        \"# t[3] = -1 -1  0  2  2  1  0 -1\\n\\t\"\n        \"adds\tr14, r14, r5\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr14, r14, r5\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr14, r14, r6\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr14, r14, r6\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr14, r14, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"subs\tr14, r14, r12\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr14, r14, r2\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr14, r14, r3\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr14, r14, r9\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"# Store t[3]\\n\\t\"\n        \"str\tr14, [sp, #12]\\n\\t\"\n        \"neg\tr12, r12\\n\\t\"\n        \"mov\tr14, #0\\n\\t\"\n        \"# t[4] =  0 -1 -1  0  2  2  1  0\\n\\t\"\n        \"adds\tr10, r10, r6\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"adds\tr10, r10, r6\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"adds\tr10, r10, r7\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"adds\tr10, r10, r7\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"adds\tr10, r10, r8\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"subs\tr10, r10, r12\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr10, r10, r3\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr10, r10, r4\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"# Store t[4]\\n\\t\"\n        \"str\tr10, [sp, #16]\\n\\t\"\n        \"neg\tr12, r12\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        \"# t[5] =  0  0 -1 -1  0  2  2  1\\n\\t\"\n        \"adds\tr14, r14, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr14, r14, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr14, r14, r8\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr14, r14, r8\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr14, r14, r9\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"subs\tr14, r14, r12\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr14, r14, r4\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr14, r14, r5\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"# Store t[5]\\n\\t\"\n        \"str\tr14, [sp, #20]\\n\\t\"\n        \"neg\tr12, r12\\n\\t\"\n        \"mov\tr14, #0\\n\\t\"\n        \"# t[6] = -1 -1  0  0  0  1  3  2\\n\\t\"\n        \"adds\tr10, r10, r7\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"adds\tr10, r10, r8\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"adds\tr10, r10, r8\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"adds\tr10, r10, r8\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"adds\tr10, r10, r9\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"adds\tr10, r10, r9\\n\\t\"\n        \"adc\tr14, r14, #0\\n\\t\"\n        \"subs\tr10, r10, r12\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr10, r10, r2\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr10, r10, r3\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"# Store t[6]\\n\\t\"\n        \"mov\tr8, r10\\n\\t\"\n        \"neg\tr12, r12\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        \"# t[7] =  1  0 -1 -1 -1 -1  0  3\\n\\t\"\n        \"adds\tr14, r14, r2\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr14, r14, r9\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr14, r14, r9\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr14, r14, r9\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"subs\tr14, r14, r12\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr14, r14, r4\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr14, r14, r5\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr14, r14, r6\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"subs\tr14, r14, r7\\n\\t\"\n        \"sbc\tr12, r12, #0\\n\\t\"\n        \"# Store t[7]\\n\\t\"\n        \"# Load intermediate\\n\\t\"\n        \"ldr\tr2, [sp, #0]\\n\\t\"\n        \"ldr\tr3, [sp, #4]\\n\\t\"\n        \"ldr\tr4, [sp, #8]\\n\\t\"\n        \"ldr\tr5, [sp, #12]\\n\\t\"\n        \"ldr\tr6, [sp, #16]\\n\\t\"\n        \"ldr\tr7, [sp, #20]\\n\\t\"\n        \"neg\tr12, r12\\n\\t\"\n        \"# Add overflow\\n\\t\"\n        \"# Subtract underflow - add neg underflow\\n\\t\"\n        \"adds\tr2, r2, r10\\n\\t\"\n        \"adcs\tr3, r3, #0\\n\\t\"\n        \"adcs\tr4, r4, #0\\n\\t\"\n        \"adds\tr5, r5, r12\\n\\t\"\n        \"adcs\tr6, r6, #0\\n\\t\"\n        \"adcs\tr7, r7, #0\\n\\t\"\n        \"adcs\tr8, r8, r12\\n\\t\"\n        \"adc\tr14, r14, r10\\n\\t\"\n        \"# Subtract overflow\\n\\t\"\n        \"# Add underflow - subtract neg underflow\\n\\t\"\n        \"subs\tr2, r2, r12\\n\\t\"\n        \"sbcs\tr3, r3, #0\\n\\t\"\n        \"sbcs\tr4, r4, #0\\n\\t\"\n        \"subs\tr5, r5, r10\\n\\t\"\n        \"sbcs\tr6, r6, #0\\n\\t\"\n        \"sbcs\tr7, r7, #0\\n\\t\"\n        \"sbcs\tr8, r8, r10\\n\\t\"\n        \"sbc\tr14, r14, r12\\n\\t\"\n        \"# Store result\\n\\t\"\n        \"str\tr2, [%[r], #0]\\n\\t\"\n        \"str\tr3, [%[r], #4]\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"str\tr5, [%[r], #12]\\n\\t\"\n        \"str\tr6, [%[r], #16]\\n\\t\"\n        \"str\tr7, [%[r], #20]\\n\\t\"\n        \"str\tr8, [%[r], #24]\\n\\t\"\n        \"str\tr14, [%[r], #28]\\n\\t\"\n        \"add\tsp, sp, #24\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return MP_OKAY;\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_256_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 32\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 32\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffff;\n        s = 32U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 32U) <= (word32)DIGIT_BIT) {\n            s += 32U;\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 32) {\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 32 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Convert a point of type ecc_point to type sp_point.\n *\n * p   Point of type sp_point (result).\n * pm  Point of type ecc_point.\n */\nstatic void sp_256_point_from_ecc_point_8(sp_point* p, const ecc_point* pm)\n{\n    XMEMSET(p->x, 0, sizeof(p->x));\n    XMEMSET(p->y, 0, sizeof(p->y));\n    XMEMSET(p->z, 0, sizeof(p->z));\n    sp_256_from_mp(p->x, 8, pm->x);\n    sp_256_from_mp(p->y, 8, pm->y);\n    sp_256_from_mp(p->z, 8, pm->z);\n    p->infinity = 0;\n}\n\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_256_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 32\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 8);\n        r->used = 8;\n        mp_clamp(r);\n#elif DIGIT_BIT < 32\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 8; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 32) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 32 - s;\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 8; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 32 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 32 - s;\n            }\n            else {\n                s += 32;\n            }\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Convert a point of type sp_point to type ecc_point.\n *\n * p   Point of type sp_point.\n * pm  Point of type ecc_point (result).\n * returns MEMORY_E when allocation of memory in ecc_point fails otherwise\n * MP_OKAY.\n */\nstatic int sp_256_point_to_ecc_point_8(const sp_point* p, ecc_point* pm)\n{\n    int err;\n\n    err = sp_256_to_mp(p->x, pm->x);\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pm->y);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pm->z);\n    }\n\n    return err;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic int32_t sp_256_cmp_8(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = -1;\n    sp_digit one = 1;\n\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr3, #-1\\n\\t\"\n        \"mov\tr6, #28\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr4, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr4, r4, r3\\n\\t\"\n        \"and\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"subs\tr6, r6, #4\\n\\t\"\n        \"bcs\t1b\\n\\t\"\n        \"eor\t%[r], %[r], r3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr3, #-1\\n\\t\"\n        \"ldr\t\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #28]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #24]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #20]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #16]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #12]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #8]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #4]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"ldr\t\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\t\tr5, [%[b], #0]\\n\\t\"\n        \"and\t\tr4, r4, r3\\n\\t\"\n        \"and\t\tr5, r5, r3\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"it\thi\\n\\t\"\n        \"movhi\t%[r], %[one]\\n\\t\"\n        \"it\tlo\\n\\t\"\n        \"movlo\t%[r], r3\\n\\t\"\n        \"it\tne\\n\\t\"\n        \"movne\tr3, r7\\n\\t\"\n        \"eor\t%[r], %[r], r3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n#endif\n\n    return r;\n}\n\n/* Normalize the values in each word to 32.\n *\n * a  Array of sp_digit to normalize.\n */\n#define sp_256_norm_8(a)\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        sp_digit m)\n{\n    sp_digit c = 0;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr9, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"subs\t%[c], r9, %[c]\\n\\t\"\n        \"ldr\tr4, [%[a], r8]\\n\\t\"\n        \"ldr\tr5, [%[b], r8]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        \"str\tr4, [%[r], r8]\\n\\t\"\n        \"add\tr8, r8, #4\\n\\t\"\n        \"cmp\tr8, #32\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r4\", \"r6\", \"r5\", \"r7\", \"r8\", \"r9\"\n    );\n#else\n    __asm__ __volatile__ (\n\n        \"mov\tr9, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"subs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr6, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr6, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"and\tr5, r5, %[m]\\n\\t\"\n        \"and\tr7, r7, %[m]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r4\", \"r6\", \"r5\", \"r7\", \"r8\", \"r9\"\n    );\n#endif /* WOLFSSL_SP_SMALL */\n\n    return c;\n}\n\n#define sp_256_mont_reduce_order_8    sp_256_mont_reduce_8\n\n/* Reduce the number back to 256 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"# i = 0\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr10, [%[a], #0]\\n\\t\"\n        \"ldr\tr14, [%[a], #4]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mul\tr8, %[mp], r10\\n\\t\"\n        \"# a[i+0] += m[0] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #0]\\n\\t\"\n        \"ldr\tr9, [%[a], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr10, r10, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"# a[i+1] += m[1] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #4]\\n\\t\"\n        \"ldr\tr9, [%[a], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr10, r14, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr10, r10, r5\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+2] += m[2] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #8]\\n\\t\"\n        \"ldr\tr14, [%[a], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr14, r14, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr14, r14, r4\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+3] += m[3] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #12]\\n\\t\"\n        \"ldr\tr9, [%[a], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #12]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+4] += m[4] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #16]\\n\\t\"\n        \"ldr\tr9, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #16]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+5] += m[5] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #20]\\n\\t\"\n        \"ldr\tr9, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr4, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #20]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"# a[i+6] += m[6] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #24]\\n\\t\"\n        \"ldr\tr9, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr9, r9, r6\\n\\t\"\n        \"adc\tr5, r7, #0\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"str\tr9, [%[a], #24]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"# a[i+7] += m[7] * mu\\n\\t\"\n        \"ldr\tr7, [%[m], #28]\\n\\t\"\n        \"ldr   r9, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr7, r7, %[ca]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"adc\t%[ca], %[ca], %[ca]\\n\\t\"\n        \"adds\tr9, r9, r5\\n\\t\"\n        \"str\tr9, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[a], #32]\\n\\t\"\n        \"adcs\tr9, r9, r7\\n\\t\"\n        \"str\tr9, [%[a], #32]\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"add\tr12, r12, #4\\n\\t\"\n        \"cmp\tr12, #32\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr10, [%[a], #0]\\n\\t\"\n        \"str\tr14, [%[a], #4]\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    sp_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nSP_NOINLINE static void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    (void)mp;\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #68\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"#  A[0] * B[0]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"str\tr8, [sp, #0]\\n\\t\"\n        \"#  A[0] * B[1]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adc\tr10, r4, #0\\n\\t\"\n        \"#  A[1] * B[0]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, #0\\n\\t\"\n        \"str\tr9, [sp, #4]\\n\\t\"\n        \"#  A[0] * B[2]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adc\tr14, r4, r14\\n\\t\"\n        \"#  A[1] * B[1]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, #0\\n\\t\"\n        \"#  A[2] * B[0]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"str\tr10, [sp, #8]\\n\\t\"\n        \"#  A[0] * B[3]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, #0\\n\\t\"\n        \"#  A[1] * B[2]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"#  A[2] * B[1]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"#  A[3] * B[0]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"str\tr14, [sp, #12]\\n\\t\"\n        \"#  A[0] * B[4]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, #0\\n\\t\"\n        \"#  A[1] * B[3]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"#  A[2] * B[2]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"#  A[3] * B[1]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"#  A[4] * B[0]\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"str\tr8, [sp, #16]\\n\\t\"\n        \"#  A[0] * B[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, #0\\n\\t\"\n        \"#  A[1] * B[4]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"#  A[2] * B[3]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"#  A[3] * B[2]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"#  A[4] * B[1]\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"#  A[5] * B[0]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"str\tr9, [sp, #20]\\n\\t\"\n        \"#  A[0] * B[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, #0\\n\\t\"\n        \"#  A[1] * B[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"#  A[2] * B[4]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"#  A[3] * B[3]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"#  A[4] * B[2]\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"#  A[5] * B[1]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"#  A[6] * B[0]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"str\tr10, [sp, #24]\\n\\t\"\n        \"#  A[0] * B[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, #0\\n\\t\"\n        \"#  A[1] * B[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"#  A[2] * B[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"#  A[3] * B[4]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"#  A[4] * B[3]\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"#  A[5] * B[2]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"#  A[6] * B[1]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"#  A[7] * B[0]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"str\tr14, [sp, #28]\\n\\t\"\n        \"#  A[1] * B[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, #0\\n\\t\"\n        \"#  A[2] * B[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"#  A[3] * B[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"#  A[4] * B[4]\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"#  A[5] * B[3]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"#  A[6] * B[2]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"#  A[7] * B[1]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"str\tr8, [sp, #32]\\n\\t\"\n        \"#  A[2] * B[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, #0\\n\\t\"\n        \"#  A[3] * B[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"#  A[4] * B[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"#  A[5] * B[4]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"#  A[6] * B[3]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"#  A[7] * B[2]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"str\tr9, [sp, #36]\\n\\t\"\n        \"#  A[3] * B[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, #0\\n\\t\"\n        \"#  A[4] * B[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"#  A[5] * B[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"#  A[6] * B[4]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"#  A[7] * B[3]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"str\tr10, [sp, #40]\\n\\t\"\n        \"#  A[4] * B[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, #0\\n\\t\"\n        \"#  A[5] * B[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"#  A[6] * B[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"#  A[7] * B[4]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"str\tr14, [sp, #44]\\n\\t\"\n        \"#  A[5] * B[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, #0\\n\\t\"\n        \"#  A[6] * B[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"#  A[7] * B[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"#  A[6] * B[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, #0\\n\\t\"\n        \"#  A[7] * B[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"#  A[7] * B[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adc\tr14, r4, r14\\n\\t\"\n        \"str\tr8, [sp, #48]\\n\\t\"\n        \"str\tr9, [sp, #52]\\n\\t\"\n        \"str\tr10, [sp, #56]\\n\\t\"\n        \"str\tr14, [sp, #60]\\n\\t\"\n        \"# Start Reduction\\n\\t\"\n        \"ldr\tr4, [sp, #0]\\n\\t\"\n        \"ldr\tr5, [sp, #4]\\n\\t\"\n        \"ldr\tr6, [sp, #8]\\n\\t\"\n        \"ldr\tr7, [sp, #12]\\n\\t\"\n        \"ldr\tr8, [sp, #16]\\n\\t\"\n        \"ldr\tr9, [sp, #20]\\n\\t\"\n        \"ldr\tr10, [sp, #24]\\n\\t\"\n        \"ldr\tr14, [sp, #28]\\n\\t\"\n        \"# mu = a[0]-a[7] + a[0]-a[4] << 96 + (a[0]-a[1] * 2) << 192\\n\\t\"\n        \"#    - a[0] << 224\\n\\t\"\n        \"#   + (a[0]-a[1] * 2) << (6 * 32)\\n\\t\"\n        \"adds\tr10, r10, r4\\n\\t\"\n        \"adc\tr14, r14, r5\\n\\t\"\n        \"adds\tr10, r10, r4\\n\\t\"\n        \"adc\tr14, r14, r5\\n\\t\"\n        \"#   - a[0] << (7 * 32)\\n\\t\"\n        \"sub\tr14, r14, r4\\n\\t\"\n        \"#   + a[0]-a[4] << (3 * 32)\\n\\t\"\n        \"mov\t%[a], r7\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"adds\tr7, r7, r4\\n\\t\"\n        \"adcs\tr8, r8, r5\\n\\t\"\n        \"adcs\tr9, r9, r6\\n\\t\"\n        \"adcs\tr10, r10, %[a]\\n\\t\"\n        \"adc\tr14, r14, %[b]\\n\\t\"\n        \"str\tr4, [sp, #0]\\n\\t\"\n        \"str\tr5, [sp, #4]\\n\\t\"\n        \"str\tr6, [sp, #8]\\n\\t\"\n        \"str\tr7, [sp, #12]\\n\\t\"\n        \"str\tr8, [sp, #16]\\n\\t\"\n        \"str\tr9, [sp, #20]\\n\\t\"\n        \"# a += mu * m\\n\\t\"\n        \"#   += mu * ((1 << 256) - (1 << 224) + (1 << 192) + (1 << 96) - 1)\\n\\t\"\n        \"mov\t%[a], #0\\n\\t\"\n        \"# a[6] +=        t[0] + t[3]\\n\\t\"\n        \"ldr\tr3, [sp, #24]\\n\\t\"\n        \"adds\tr3, r3, r4\\n\\t\"\n        \"adc\t%[b], %[a], #0\\n\\t\"\n        \"adds\tr3, r3, r7\\n\\t\"\n        \"adc\t%[b], %[b], #0\\n\\t\"\n        \"str\tr10, [sp, #24]\\n\\t\"\n        \"# a[7] +=        t[1] + t[4]\\n\\t\"\n        \"ldr\tr3, [sp, #28]\\n\\t\"\n        \"adds\tr3, r3, %[b]\\n\\t\"\n        \"adc\t%[b], %[a], #0\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adc\t%[b], %[b], #0\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adc\t%[b], %[b], #0\\n\\t\"\n        \"str\tr14, [sp, #28]\\n\\t\"\n        \"str\tr3, [sp, #64]\\n\\t\"\n        \"# a[8] += t[0] + t[2] + t[5]\\n\\t\"\n        \"ldr\tr3, [sp, #32]\\n\\t\"\n        \"adds\tr3, r3, %[b]\\n\\t\"\n        \"adc\t%[b], %[a], #0\\n\\t\"\n        \"adds\tr3, r3, r4\\n\\t\"\n        \"adc\t%[b], %[b], #0\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adc\t%[b], %[b], #0\\n\\t\"\n        \"adds\tr3, r3, r9\\n\\t\"\n        \"adc\t%[b], %[b], #0\\n\\t\"\n        \"str\tr3, [sp, #32]\\n\\t\"\n        \"# a[9]  += t[1] + t[3] + t[6]\\n\\t\"\n        \"# a[10] += t[2] + t[4] + t[7]\\n\\t\"\n        \"ldr\tr3, [sp, #36]\\n\\t\"\n        \"ldr\tr4, [sp, #40]\\n\\t\"\n        \"adds\tr3, r3, %[b]\\n\\t\"\n        \"adcs\tr4, r4, #0\\n\\t\"\n        \"adc\t%[b], %[a], #0\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\t%[b], %[b], #0\\n\\t\"\n        \"adds\tr3, r3, r7\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adc\t%[b], %[b], #0\\n\\t\"\n        \"adds\tr3, r3, r10\\n\\t\"\n        \"adcs\tr4, r4, r14\\n\\t\"\n        \"adc\t%[b], %[b], #0\\n\\t\"\n        \"str\tr3, [sp, #36]\\n\\t\"\n        \"str\tr4, [sp, #40]\\n\\t\"\n        \"# a[11] += t[3] + t[5]\\n\\t\"\n        \"# a[12] += t[4] + t[6]\\n\\t\"\n        \"# a[13] += t[5] + t[7]\\n\\t\"\n        \"# a[14] += t[6]\\n\\t\"\n        \"ldr\tr3, [sp, #44]\\n\\t\"\n        \"ldr\tr4, [sp, #48]\\n\\t\"\n        \"ldr\tr5, [sp, #52]\\n\\t\"\n        \"ldr\tr6, [sp, #56]\\n\\t\"\n        \"adds\tr3, r3, %[b]\\n\\t\"\n        \"adcs\tr4, r4, #0\\n\\t\"\n        \"adcs\tr5, r5, #0\\n\\t\"\n        \"adcs\tr6, r6, #0\\n\\t\"\n        \"adc\t%[b], %[a], #0\\n\\t\"\n        \"adds\tr3, r3, r7\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adc\t%[b], %[b], #0\\n\\t\"\n        \"adds\tr3, r3, r9\\n\\t\"\n        \"adcs\tr4, r4, r10\\n\\t\"\n        \"adcs\tr5, r5, r14\\n\\t\"\n        \"adcs\tr6, r6, #0\\n\\t\"\n        \"adc\t%[b], %[b], #0\\n\\t\"\n        \"str\tr3, [sp, #44]\\n\\t\"\n        \"str\tr4, [sp, #48]\\n\\t\"\n        \"str\tr5, [sp, #52]\\n\\t\"\n        \"str\tr6, [sp, #56]\\n\\t\"\n        \"# a[15] += t[7]\\n\\t\"\n        \"ldr\tr3, [sp, #60]\\n\\t\"\n        \"adds\tr3, r3, %[b]\\n\\t\"\n        \"adc\t%[b], %[a], #0\\n\\t\"\n        \"adds\tr3, r3, r14\\n\\t\"\n        \"adc\t%[b], %[b], #0\\n\\t\"\n        \"str\tr3, [sp, #60]\\n\\t\"\n        \"ldr\tr3, [sp, #64]\\n\\t\"\n        \"ldr\tr4, [sp, #32]\\n\\t\"\n        \"ldr\tr5, [sp, #36]\\n\\t\"\n        \"ldr\tr6, [sp, #40]\\n\\t\"\n        \"ldr\tr8, [sp, #0]\\n\\t\"\n        \"ldr\tr9, [sp, #4]\\n\\t\"\n        \"ldr\tr10, [sp, #8]\\n\\t\"\n        \"ldr\tr14, [sp, #12]\\n\\t\"\n        \"subs\tr3, r3, r8\\n\\t\"\n        \"sbcs\tr4, r4, r9\\n\\t\"\n        \"sbcs\tr5, r5, r10\\n\\t\"\n        \"sbcs\tr6, r6, r14\\n\\t\"\n        \"str\tr4, [sp, #32]\\n\\t\"\n        \"str\tr5, [sp, #36]\\n\\t\"\n        \"str\tr6, [sp, #40]\\n\\t\"\n        \"ldr\tr3, [sp, #44]\\n\\t\"\n        \"ldr\tr4, [sp, #48]\\n\\t\"\n        \"ldr\tr5, [sp, #52]\\n\\t\"\n        \"ldr\tr6, [sp, #56]\\n\\t\"\n        \"ldr\tr7, [sp, #60]\\n\\t\"\n        \"ldr\tr8, [sp, #16]\\n\\t\"\n        \"ldr\tr9, [sp, #20]\\n\\t\"\n        \"ldr\tr10, [sp, #24]\\n\\t\"\n        \"ldr\tr14, [sp, #28]\\n\\t\"\n        \"sbcs\tr3, r3, r8\\n\\t\"\n        \"sbcs\tr4, r4, r9\\n\\t\"\n        \"sbcs\tr5, r5, r10\\n\\t\"\n        \"sbcs\tr6, r6, r14\\n\\t\"\n        \"sbc\tr7, r7, #0\\n\\t\"\n        \"str\tr3, [sp, #44]\\n\\t\"\n        \"str\tr4, [sp, #48]\\n\\t\"\n        \"str\tr5, [sp, #52]\\n\\t\"\n        \"str\tr6, [sp, #56]\\n\\t\"\n        \"str\tr7, [sp, #60]\\n\\t\"\n        \"# mask m and sub from result if overflow\\n\\t\"\n        \"sub\t%[b], %[a], %[b]\\n\\t\"\n        \"and\t%[a], %[b], #1\\n\\t\"\n        \"ldr\tr3, [sp, #32]\\n\\t\"\n        \"ldr\tr4, [sp, #36]\\n\\t\"\n        \"ldr\tr5, [sp, #40]\\n\\t\"\n        \"ldr\tr6, [sp, #44]\\n\\t\"\n        \"ldr\tr7, [sp, #48]\\n\\t\"\n        \"ldr\tr8, [sp, #52]\\n\\t\"\n        \"ldr\tr9, [sp, #56]\\n\\t\"\n        \"ldr\tr10, [sp, #60]\\n\\t\"\n        \"subs\tr3, r3, %[b]\\n\\t\"\n        \"sbcs\tr4, r4, %[b]\\n\\t\"\n        \"sbcs\tr5, r5, %[b]\\n\\t\"\n        \"sbcs\tr6, r6, #0\\n\\t\"\n        \"sbcs\tr7, r7, #0\\n\\t\"\n        \"sbcs\tr8, r8, #0\\n\\t\"\n        \"sbcs\tr9, r9, %[a]\\n\\t\"\n        \"sbc\tr10, r10, %[b]\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"str\tr7, [%[r], #16]\\n\\t\"\n        \"str\tr8, [%[r], #20]\\n\\t\"\n        \"str\tr9, [%[r], #24]\\n\\t\"\n        \"str\tr10, [%[r], #28]\\n\\t\"\n        \"add\tsp, sp, #68\\n\\t\"\n        : [a] \"+r\" (a), [b] \"+r\" (b)\n        : [r] \"r\" (r)\n        : \"memory\", \"r8\", \"r9\", \"r10\", \"r14\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n}\n\n/* Square the Montgomery form number mod the modulus (prime). (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nSP_NOINLINE static void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    (void)mp;\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #68\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"#  A[0] * A[1]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #4]\\n\\t\"\n        \"umull\tr9, r10, r6, r7\\n\\t\"\n        \"str\tr9, [sp, #4]\\n\\t\"\n        \"#  A[0] * A[2]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #8]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adc\tr14, r4, #0\\n\\t\"\n        \"str\tr10, [sp, #8]\\n\\t\"\n        \"#  A[0] * A[3]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adc\tr8, r4, #0\\n\\t\"\n        \"#  A[1] * A[2]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #8]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, #0\\n\\t\"\n        \"str\tr14, [sp, #12]\\n\\t\"\n        \"#  A[0] * A[4]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #16]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adc\tr9, r4, r9\\n\\t\"\n        \"#  A[1] * A[3]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, #0\\n\\t\"\n        \"str\tr8, [sp, #16]\\n\\t\"\n        \"#  A[0] * A[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adc\tr10, r4, r10\\n\\t\"\n        \"#  A[1] * A[4]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #16]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, #0\\n\\t\"\n        \"#  A[2] * A[3]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"str\tr9, [sp, #20]\\n\\t\"\n        \"#  A[0] * A[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, #0\\n\\t\"\n        \"#  A[1] * A[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"#  A[2] * A[4]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #16]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"str\tr10, [sp, #24]\\n\\t\"\n        \"#  A[0] * A[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, #0\\n\\t\"\n        \"#  A[1] * A[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"#  A[2] * A[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"#  A[3] * A[4]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[a], #16]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"str\tr14, [sp, #28]\\n\\t\"\n        \"#  A[1] * A[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, #0\\n\\t\"\n        \"#  A[2] * A[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"#  A[3] * A[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, r10\\n\\t\"\n        \"str\tr8, [sp, #32]\\n\\t\"\n        \"#  A[2] * A[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, #0\\n\\t\"\n        \"#  A[3] * A[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"#  A[4] * A[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adcs\tr10, r4, r10\\n\\t\"\n        \"adc\tr14, r5, r14\\n\\t\"\n        \"str\tr9, [sp, #36]\\n\\t\"\n        \"#  A[3] * A[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, #0\\n\\t\"\n        \"#  A[4] * A[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr10, r3, r10\\n\\t\"\n        \"adcs\tr14, r4, r14\\n\\t\"\n        \"adc\tr8, r5, r8\\n\\t\"\n        \"str\tr10, [sp, #40]\\n\\t\"\n        \"#  A[4] * A[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, #0\\n\\t\"\n        \"#  A[5] * A[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr14, r3, r14\\n\\t\"\n        \"adcs\tr8, r4, r8\\n\\t\"\n        \"adc\tr9, r5, r9\\n\\t\"\n        \"str\tr14, [sp, #44]\\n\\t\"\n        \"#  A[5] * A[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr8, r3, r8\\n\\t\"\n        \"adcs\tr9, r4, r9\\n\\t\"\n        \"adc\tr10, r5, #0\\n\\t\"\n        \"str\tr8, [sp, #48]\\n\\t\"\n        \"#  A[6] * A[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"adds\tr9, r3, r9\\n\\t\"\n        \"adc\tr10, r4, r10\\n\\t\"\n        \"str\tr9, [sp, #52]\\n\\t\"\n        \"str\tr10, [sp, #56]\\n\\t\"\n        \"# Double\\n\\t\"\n        \"ldr\tr4, [sp, #4]\\n\\t\"\n        \"ldr\tr6, [sp, #8]\\n\\t\"\n        \"ldr\tr7, [sp, #12]\\n\\t\"\n        \"ldr\tr8, [sp, #16]\\n\\t\"\n        \"ldr\tr9, [sp, #20]\\n\\t\"\n        \"ldr\tr10, [sp, #24]\\n\\t\"\n        \"ldr\tr14, [sp, #28]\\n\\t\"\n        \"ldr\tr12, [sp, #32]\\n\\t\"\n        \"ldr\tr3, [sp, #36]\\n\\t\"\n        \"adds\tr4, r4, r4\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adcs\tr7, r7, r7\\n\\t\"\n        \"adcs\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adcs\tr10, r10, r10\\n\\t\"\n        \"adcs\tr14, r14, r14\\n\\t\"\n        \"adcs\tr12, r12, r12\\n\\t\"\n        \"adcs\tr3, r3, r3\\n\\t\"\n        \"str\tr4, [sp, #4]\\n\\t\"\n        \"str\tr6, [sp, #8]\\n\\t\"\n        \"str\tr7, [sp, #12]\\n\\t\"\n        \"str\tr8, [sp, #16]\\n\\t\"\n        \"str\tr9, [sp, #20]\\n\\t\"\n        \"str\tr10, [sp, #24]\\n\\t\"\n        \"str\tr14, [sp, #28]\\n\\t\"\n        \"str\tr12, [sp, #32]\\n\\t\"\n        \"str\tr3, [sp, #36]\\n\\t\"\n        \"ldr\tr4, [sp, #40]\\n\\t\"\n        \"ldr\tr6, [sp, #44]\\n\\t\"\n        \"ldr\tr7, [sp, #48]\\n\\t\"\n        \"ldr\tr8, [sp, #52]\\n\\t\"\n        \"ldr\tr9, [sp, #56]\\n\\t\"\n        \"adcs\tr4, r4, r4\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adcs\tr7, r7, r7\\n\\t\"\n        \"adcs\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"str\tr4, [sp, #40]\\n\\t\"\n        \"str\tr6, [sp, #44]\\n\\t\"\n        \"str\tr7, [sp, #48]\\n\\t\"\n        \"str\tr8, [sp, #52]\\n\\t\"\n        \"str\tr9, [sp, #56]\\n\\t\"\n        \"adc\tr10, r5, #0\\n\\t\"\n        \"str\tr10, [sp, #60]\\n\\t\"\n        \"ldr\tr4, [sp, #4]\\n\\t\"\n        \"ldr\tr5, [sp, #8]\\n\\t\"\n        \"ldr\tr12, [sp, #12]\\n\\t\"\n        \"#  A[0] * A[0]\\n\\t\"\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r6, r6\\n\\t\"\n        \"#  A[1] * A[1]\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"umull\tr10, r14, r6, r6\\n\\t\"\n        \"adds\tr9, r9, r4\\n\\t\"\n        \"adcs\tr10, r10, r5\\n\\t\"\n        \"adcs\tr14, r14, r12\\n\\t\"\n        \"str\tr8, [sp, #0]\\n\\t\"\n        \"str\tr9, [sp, #4]\\n\\t\"\n        \"str\tr10, [sp, #8]\\n\\t\"\n        \"str\tr14, [sp, #12]\\n\\t\"\n        \"ldr\tr3, [sp, #16]\\n\\t\"\n        \"ldr\tr4, [sp, #20]\\n\\t\"\n        \"ldr\tr5, [sp, #24]\\n\\t\"\n        \"ldr\tr12, [sp, #28]\\n\\t\"\n        \"#  A[2] * A[2]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r6, r6\\n\\t\"\n        \"#  A[3] * A[3]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"umull\tr10, r14, r6, r6\\n\\t\"\n        \"adcs\tr8, r8, r3\\n\\t\"\n        \"adcs\tr9, r9, r4\\n\\t\"\n        \"adcs\tr10, r10, r5\\n\\t\"\n        \"adcs\tr14, r14, r12\\n\\t\"\n        \"str\tr8, [sp, #16]\\n\\t\"\n        \"str\tr9, [sp, #20]\\n\\t\"\n        \"str\tr10, [sp, #24]\\n\\t\"\n        \"str\tr14, [sp, #28]\\n\\t\"\n        \"ldr\tr3, [sp, #32]\\n\\t\"\n        \"ldr\tr4, [sp, #36]\\n\\t\"\n        \"ldr\tr5, [sp, #40]\\n\\t\"\n        \"ldr\tr12, [sp, #44]\\n\\t\"\n        \"#  A[4] * A[4]\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r6, r6\\n\\t\"\n        \"#  A[5] * A[5]\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"umull\tr10, r14, r6, r6\\n\\t\"\n        \"adcs\tr8, r8, r3\\n\\t\"\n        \"adcs\tr9, r9, r4\\n\\t\"\n        \"adcs\tr10, r10, r5\\n\\t\"\n        \"adcs\tr14, r14, r12\\n\\t\"\n        \"str\tr8, [sp, #32]\\n\\t\"\n        \"str\tr9, [sp, #36]\\n\\t\"\n        \"str\tr10, [sp, #40]\\n\\t\"\n        \"str\tr14, [sp, #44]\\n\\t\"\n        \"ldr\tr3, [sp, #48]\\n\\t\"\n        \"ldr\tr4, [sp, #52]\\n\\t\"\n        \"ldr\tr5, [sp, #56]\\n\\t\"\n        \"ldr\tr12, [sp, #60]\\n\\t\"\n        \"#  A[6] * A[6]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r6, r6\\n\\t\"\n        \"#  A[7] * A[7]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"umull\tr10, r14, r6, r6\\n\\t\"\n        \"adcs\tr8, r8, r3\\n\\t\"\n        \"adcs\tr9, r9, r4\\n\\t\"\n        \"adcs\tr10, r10, r5\\n\\t\"\n        \"adc\tr14, r14, r12\\n\\t\"\n        \"str\tr8, [sp, #48]\\n\\t\"\n        \"str\tr9, [sp, #52]\\n\\t\"\n        \"str\tr10, [sp, #56]\\n\\t\"\n        \"str\tr14, [sp, #60]\\n\\t\"\n        \"# Start Reduction\\n\\t\"\n        \"ldr\tr4, [sp, #0]\\n\\t\"\n        \"ldr\tr5, [sp, #4]\\n\\t\"\n        \"ldr\tr6, [sp, #8]\\n\\t\"\n        \"ldr\tr7, [sp, #12]\\n\\t\"\n        \"ldr\tr8, [sp, #16]\\n\\t\"\n        \"ldr\tr9, [sp, #20]\\n\\t\"\n        \"ldr\tr10, [sp, #24]\\n\\t\"\n        \"ldr\tr14, [sp, #28]\\n\\t\"\n        \"# mu = a[0]-a[7] + a[0]-a[4] << 96 + (a[0]-a[1] * 2) << 192\\n\\t\"\n        \"#    - a[0] << 224\\n\\t\"\n        \"#   + (a[0]-a[1] * 2) << (6 * 32)\\n\\t\"\n        \"adds\tr10, r10, r4\\n\\t\"\n        \"adc\tr14, r14, r5\\n\\t\"\n        \"adds\tr10, r10, r4\\n\\t\"\n        \"adc\tr14, r14, r5\\n\\t\"\n        \"#   - a[0] << (7 * 32)\\n\\t\"\n        \"sub\tr14, r14, r4\\n\\t\"\n        \"#   + a[0]-a[4] << (3 * 32)\\n\\t\"\n        \"mov\t%[a], r7\\n\\t\"\n        \"mov\tr12, r8\\n\\t\"\n        \"adds\tr7, r7, r4\\n\\t\"\n        \"adcs\tr8, r8, r5\\n\\t\"\n        \"adcs\tr9, r9, r6\\n\\t\"\n        \"adcs\tr10, r10, %[a]\\n\\t\"\n        \"adc\tr14, r14, r12\\n\\t\"\n        \"str\tr4, [sp, #0]\\n\\t\"\n        \"str\tr5, [sp, #4]\\n\\t\"\n        \"str\tr6, [sp, #8]\\n\\t\"\n        \"str\tr7, [sp, #12]\\n\\t\"\n        \"str\tr8, [sp, #16]\\n\\t\"\n        \"str\tr9, [sp, #20]\\n\\t\"\n        \"# a += mu * m\\n\\t\"\n        \"#   += mu * ((1 << 256) - (1 << 224) + (1 << 192) + (1 << 96) - 1)\\n\\t\"\n        \"mov\t%[a], #0\\n\\t\"\n        \"# a[6] +=        t[0] + t[3]\\n\\t\"\n        \"ldr\tr3, [sp, #24]\\n\\t\"\n        \"adds\tr3, r3, r4\\n\\t\"\n        \"adc\tr12, %[a], #0\\n\\t\"\n        \"adds\tr3, r3, r7\\n\\t\"\n        \"adc\tr12, r12, #0\\n\\t\"\n        \"str\tr10, [sp, #24]\\n\\t\"\n        \"# a[7] +=        t[1] + t[4]\\n\\t\"\n        \"ldr\tr3, [sp, #28]\\n\\t\"\n        \"adds\tr3, r3, r12\\n\\t\"\n        \"adc\tr12, %[a], #0\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adc\tr12, r12, #0\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adc\tr12, r12, #0\\n\\t\"\n        \"str\tr14, [sp, #28]\\n\\t\"\n        \"str\tr3, [sp, #64]\\n\\t\"\n        \"# a[8] += t[0] + t[2] + t[5]\\n\\t\"\n        \"ldr\tr3, [sp, #32]\\n\\t\"\n        \"adds\tr3, r3, r12\\n\\t\"\n        \"adc\tr12, %[a], #0\\n\\t\"\n        \"adds\tr3, r3, r4\\n\\t\"\n        \"adc\tr12, r12, #0\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adc\tr12, r12, #0\\n\\t\"\n        \"adds\tr3, r3, r9\\n\\t\"\n        \"adc\tr12, r12, #0\\n\\t\"\n        \"str\tr3, [sp, #32]\\n\\t\"\n        \"# a[9]  += t[1] + t[3] + t[6]\\n\\t\"\n        \"# a[10] += t[2] + t[4] + t[7]\\n\\t\"\n        \"ldr\tr3, [sp, #36]\\n\\t\"\n        \"ldr\tr4, [sp, #40]\\n\\t\"\n        \"adds\tr3, r3, r12\\n\\t\"\n        \"adcs\tr4, r4, #0\\n\\t\"\n        \"adc\tr12, %[a], #0\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr12, r12, #0\\n\\t\"\n        \"adds\tr3, r3, r7\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adc\tr12, r12, #0\\n\\t\"\n        \"adds\tr3, r3, r10\\n\\t\"\n        \"adcs\tr4, r4, r14\\n\\t\"\n        \"adc\tr12, r12, #0\\n\\t\"\n        \"str\tr3, [sp, #36]\\n\\t\"\n        \"str\tr4, [sp, #40]\\n\\t\"\n        \"# a[11] += t[3] + t[5]\\n\\t\"\n        \"# a[12] += t[4] + t[6]\\n\\t\"\n        \"# a[13] += t[5] + t[7]\\n\\t\"\n        \"# a[14] += t[6]\\n\\t\"\n        \"ldr\tr3, [sp, #44]\\n\\t\"\n        \"ldr\tr4, [sp, #48]\\n\\t\"\n        \"ldr\tr5, [sp, #52]\\n\\t\"\n        \"ldr\tr6, [sp, #56]\\n\\t\"\n        \"adds\tr3, r3, r12\\n\\t\"\n        \"adcs\tr4, r4, #0\\n\\t\"\n        \"adcs\tr5, r5, #0\\n\\t\"\n        \"adcs\tr6, r6, #0\\n\\t\"\n        \"adc\tr12, %[a], #0\\n\\t\"\n        \"adds\tr3, r3, r7\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adc\tr12, r12, #0\\n\\t\"\n        \"adds\tr3, r3, r9\\n\\t\"\n        \"adcs\tr4, r4, r10\\n\\t\"\n        \"adcs\tr5, r5, r14\\n\\t\"\n        \"adcs\tr6, r6, #0\\n\\t\"\n        \"adc\tr12, r12, #0\\n\\t\"\n        \"str\tr3, [sp, #44]\\n\\t\"\n        \"str\tr4, [sp, #48]\\n\\t\"\n        \"str\tr5, [sp, #52]\\n\\t\"\n        \"str\tr6, [sp, #56]\\n\\t\"\n        \"# a[15] += t[7]\\n\\t\"\n        \"ldr\tr3, [sp, #60]\\n\\t\"\n        \"adds\tr3, r3, r12\\n\\t\"\n        \"adc\tr12, %[a], #0\\n\\t\"\n        \"adds\tr3, r3, r14\\n\\t\"\n        \"adc\tr12, r12, #0\\n\\t\"\n        \"str\tr3, [sp, #60]\\n\\t\"\n        \"ldr\tr3, [sp, #64]\\n\\t\"\n        \"ldr\tr4, [sp, #32]\\n\\t\"\n        \"ldr\tr5, [sp, #36]\\n\\t\"\n        \"ldr\tr6, [sp, #40]\\n\\t\"\n        \"ldr\tr8, [sp, #0]\\n\\t\"\n        \"ldr\tr9, [sp, #4]\\n\\t\"\n        \"ldr\tr10, [sp, #8]\\n\\t\"\n        \"ldr\tr14, [sp, #12]\\n\\t\"\n        \"subs\tr3, r3, r8\\n\\t\"\n        \"sbcs\tr4, r4, r9\\n\\t\"\n        \"sbcs\tr5, r5, r10\\n\\t\"\n        \"sbcs\tr6, r6, r14\\n\\t\"\n        \"str\tr4, [sp, #32]\\n\\t\"\n        \"str\tr5, [sp, #36]\\n\\t\"\n        \"str\tr6, [sp, #40]\\n\\t\"\n        \"ldr\tr3, [sp, #44]\\n\\t\"\n        \"ldr\tr4, [sp, #48]\\n\\t\"\n        \"ldr\tr5, [sp, #52]\\n\\t\"\n        \"ldr\tr6, [sp, #56]\\n\\t\"\n        \"ldr\tr7, [sp, #60]\\n\\t\"\n        \"ldr\tr8, [sp, #16]\\n\\t\"\n        \"ldr\tr9, [sp, #20]\\n\\t\"\n        \"ldr\tr10, [sp, #24]\\n\\t\"\n        \"ldr\tr14, [sp, #28]\\n\\t\"\n        \"sbcs\tr3, r3, r8\\n\\t\"\n        \"sbcs\tr4, r4, r9\\n\\t\"\n        \"sbcs\tr5, r5, r10\\n\\t\"\n        \"sbcs\tr6, r6, r14\\n\\t\"\n        \"sbc\tr7, r7, #0\\n\\t\"\n        \"str\tr3, [sp, #44]\\n\\t\"\n        \"str\tr4, [sp, #48]\\n\\t\"\n        \"str\tr5, [sp, #52]\\n\\t\"\n        \"str\tr6, [sp, #56]\\n\\t\"\n        \"str\tr7, [sp, #60]\\n\\t\"\n        \"# mask m and sub from result if overflow\\n\\t\"\n        \"sub\tr12, %[a], r12\\n\\t\"\n        \"and\t%[a], r12, #1\\n\\t\"\n        \"ldr\tr3, [sp, #32]\\n\\t\"\n        \"ldr\tr4, [sp, #36]\\n\\t\"\n        \"ldr\tr5, [sp, #40]\\n\\t\"\n        \"ldr\tr6, [sp, #44]\\n\\t\"\n        \"ldr\tr7, [sp, #48]\\n\\t\"\n        \"ldr\tr8, [sp, #52]\\n\\t\"\n        \"ldr\tr9, [sp, #56]\\n\\t\"\n        \"ldr\tr10, [sp, #60]\\n\\t\"\n        \"subs\tr3, r3, r12\\n\\t\"\n        \"sbcs\tr4, r4, r12\\n\\t\"\n        \"sbcs\tr5, r5, r12\\n\\t\"\n        \"sbcs\tr6, r6, #0\\n\\t\"\n        \"sbcs\tr7, r7, #0\\n\\t\"\n        \"sbcs\tr8, r8, #0\\n\\t\"\n        \"sbcs\tr9, r9, %[a]\\n\\t\"\n        \"sbc\tr10, r10, r12\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"str\tr7, [%[r], #16]\\n\\t\"\n        \"str\tr8, [%[r], #20]\\n\\t\"\n        \"str\tr9, [%[r], #24]\\n\\t\"\n        \"str\tr10, [%[r], #28]\\n\\t\"\n        \"add\tsp, sp, #68\\n\\t\"\n        : [a] \"+r\" (a)\n        : [r] \"r\" (r)\n        : \"memory\", \"r8\", \"r9\", \"r10\", \"r14\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r12\"\n    );\n}\n\n#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)\n/* Square the Montgomery form number a number of times. (r = a ^ n mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * n   Number of times to square.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_sqr_n_8(sp_digit* r, const sp_digit* a, int n,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_256_mont_sqr_8(r, a, m, mp);\n    for (; n > 1; n--) {\n        sp_256_mont_sqr_8(r, r, m, mp);\n    }\n}\n\n#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */\n#ifdef WOLFSSL_SP_SMALL\n/* Mod-2 for the P256 curve. */\nstatic const uint32_t p256_mod_2[8] = {\n    0xfffffffdU,0xffffffffU,0xffffffffU,0x00000000U,0x00000000U,0x00000000U,\n    0x00000001U,0xffffffffU\n};\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the modulus (prime) of the\n * P256 curve. (r = 1 / a mod m)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_8(sp_digit* r, const sp_digit* a, sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 8);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_8(t, t, p256_mod, p256_mp_mod);\n        if (p256_mod_2[i / 32] & ((sp_digit)1 << (i % 32)))\n            sp_256_mont_mul_8(t, t, a, p256_mod, p256_mp_mod);\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 8);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 8;\n    sp_digit* t3 = td + 4 * 8;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_8(t, a, p256_mod, p256_mp_mod);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_8(t, t, a, p256_mod, p256_mp_mod);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_8(t2, t, 2, p256_mod, p256_mp_mod);\n    /* t3= a^d = t2 * a */\n    sp_256_mont_mul_8(t3, t2, a, p256_mod, p256_mp_mod);\n    /* t = a^f = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^f0 = t ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_8(t2, t, 4, p256_mod, p256_mp_mod);\n    /* t3= a^fd = t2 * t3 */\n    sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ff = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_8(t2, t, 8, p256_mod, p256_mp_mod);\n    /* t3= a^fffd = t2 * t3 */\n    sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_8(t2, t, 16, p256_mod, p256_mp_mod);\n    /* t3= a^fffffffd = t2 * t3 */\n    sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff00000000 = t ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_8(t2, t, 32, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001 = t2 * a */\n    sp_256_mont_mul_8(t2, t2, a, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff000000010000000000000000000000000000000000000000\n     *   = t2 ^ 2 ^ 160 */\n    sp_256_mont_sqr_n_8(t2, t2, 160, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff\n     *   = t2 * t */\n    sp_256_mont_mul_8(t2, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000\n     *   = t2 ^ 2 ^ 32 */\n    sp_256_mont_sqr_n_8(t2, t2, 32, p256_mod, p256_mp_mod);\n    /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd\n     *   = t2 * t3 */\n    sp_256_mont_mul_8(r, t2, t3, p256_mod, p256_mp_mod);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Map the Montgomery form projective co-ordinate point to an affine point.\n *\n * r  Resulting affine co-ordinate point.\n * p  Montgomery form projective co-ordinate point.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_map_8(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*8;\n    int32_t n;\n\n    sp_256_mont_inv_8(t1, p->z, t + 2*8);\n\n    sp_256_mont_sqr_8(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_8(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    /* x /= z^2 */\n    sp_256_mont_mul_8(r->x, p->x, t2, p256_mod, p256_mp_mod);\n    XMEMSET(r->x + 8, 0, sizeof(r->x) / 2U);\n    sp_256_mont_reduce_8(r->x, p256_mod, p256_mp_mod);\n    /* Reduce x to less than modulus */\n    n = sp_256_cmp_8(r->x, p256_mod);\n    sp_256_cond_sub_8(r->x, r->x, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_8(r->x);\n\n    /* y /= z^3 */\n    sp_256_mont_mul_8(r->y, p->y, t1, p256_mod, p256_mp_mod);\n    XMEMSET(r->y + 8, 0, sizeof(r->y) / 2U);\n    sp_256_mont_reduce_8(r->y, p256_mod, p256_mp_mod);\n    /* Reduce y to less than modulus */\n    n = sp_256_cmp_8(r->y, p256_mod);\n    sp_256_cond_sub_8(r->y, r->y, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_8(r->y);\n\n    XMEMSET(r->z, 0, sizeof(r->z));\n    r->z[0] = 1;\n\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tr12, %[a], #32\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], #-1\\n\\t\"\n        \"ldr\tr4, [%[a]], #4\\n\\t\"\n        \"ldr\tr5, [%[a]], #4\\n\\t\"\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"ldr\tr7, [%[a]], #4\\n\\t\"\n        \"ldr\tr8, [%[b]], #4\\n\\t\"\n        \"ldr\tr9, [%[b]], #4\\n\\t\"\n        \"ldr\tr10, [%[b]], #4\\n\\t\"\n        \"ldr\tr14, [%[b]], #4\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r]], #4\\n\\t\"\n        \"str\tr5, [%[r]], #4\\n\\t\"\n        \"str\tr6, [%[r]], #4\\n\\t\"\n        \"str\tr7, [%[r]], #4\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"adc\t%[c], r4, #0\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n#else\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[a], #4]\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[b], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"ldr\tr10, [%[b], #8]\\n\\t\"\n        \"ldr\tr14, [%[b], #12]\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr5, [%[r], #4]\\n\\t\"\n        \"str\tr6, [%[r], #8]\\n\\t\"\n        \"str\tr7, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[a], #20]\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[b], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"ldr\tr10, [%[b], #24]\\n\\t\"\n        \"ldr\tr14, [%[b], #28]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"str\tr6, [%[r], #24]\\n\\t\"\n        \"str\tr7, [%[r], #28]\\n\\t\"\n        \"adc\t%[c], r12, r12\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Add two Montgomery form numbers (r = a + b % m).\n *\n * r   Result of addition.\n * a   First number to add in Montogmery form.\n * b   Second number to add in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m)\n{\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a],#0]\\n\\t\"\n        \"ldr\tr5, [%[a],#4]\\n\\t\"\n        \"ldr\tr6, [%[a],#8]\\n\\t\"\n        \"ldr\tr7, [%[a],#12]\\n\\t\"\n        \"ldr\tr8, [%[b],#0]\\n\\t\"\n        \"ldr\tr9, [%[b],#4]\\n\\t\"\n        \"ldr\tr10, [%[b],#8]\\n\\t\"\n        \"ldr\tr14, [%[b],#12]\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"str\tr6, [%[r],#8]\\n\\t\"\n        \"str\tr7, [%[r],#12]\\n\\t\"\n        \"ldr\tr4, [%[a],#16]\\n\\t\"\n        \"ldr\tr5, [%[a],#20]\\n\\t\"\n        \"ldr\tr6, [%[a],#24]\\n\\t\"\n        \"ldr\tr7, [%[a],#28]\\n\\t\"\n        \"ldr\tr8, [%[b],#16]\\n\\t\"\n        \"ldr\tr9, [%[b],#20]\\n\\t\"\n        \"ldr\tr10, [%[b],#24]\\n\\t\"\n        \"ldr\tr14, [%[b],#28]\\n\\t\"\n        \"adcs\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"adcs\tr7, r7, r14\\n\\t\"\n        \"adc\tr3, r12, #0\\n\\t\"\n        \"sub\tr3, r12, r3\\n\\t\"\n        \"and\tr12, r3, #1\\n\\t\"\n        \"ldr\tr8, [%[r],#0]\\n\\t\"\n        \"ldr\tr9, [%[r],#4]\\n\\t\"\n        \"ldr\tr10, [%[r],#8]\\n\\t\"\n        \"ldr\tr14, [%[r],#12]\\n\\t\"\n        \"subs\tr8, r8, r3\\n\\t\"\n        \"sbcs\tr9, r9, r3\\n\\t\"\n        \"sbcs\tr10, r10, r3\\n\\t\"\n        \"sbcs\tr14, r14, #0\\n\\t\"\n        \"sbcs\tr4, r4, #0\\n\\t\"\n        \"sbcs\tr5, r5, #0\\n\\t\"\n        \"sbcs\tr6, r6, r12\\n\\t\"\n        \"sbc\tr7, r7, r3\\n\\t\"\n        \"str\tr8, [%[r],#0]\\n\\t\"\n        \"str\tr9, [%[r],#4]\\n\\t\"\n        \"str\tr10, [%[r],#8]\\n\\t\"\n        \"str\tr14, [%[r],#12]\\n\\t\"\n        \"str\tr4, [%[r],#16]\\n\\t\"\n        \"str\tr5, [%[r],#20]\\n\\t\"\n        \"str\tr6, [%[r],#24]\\n\\t\"\n        \"str\tr7, [%[r],#28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r3\", \"r12\"\n    );\n}\n\n/* Double a Montgomery form number (r = a + a % m).\n *\n * r   Result of doubling.\n * a   Number to double in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_dbl_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a],#0]\\n\\t\"\n        \"ldr\tr5, [%[a],#4]\\n\\t\"\n        \"ldr\tr6, [%[a],#8]\\n\\t\"\n        \"ldr\tr7, [%[a],#12]\\n\\t\"\n        \"ldr\tr8, [%[a],#16]\\n\\t\"\n        \"ldr\tr9, [%[a],#20]\\n\\t\"\n        \"ldr\tr10, [%[a],#24]\\n\\t\"\n        \"ldr\tr14, [%[a],#28]\\n\\t\"\n        \"adds\tr4, r4, r4\\n\\t\"\n        \"adcs\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adcs\tr7, r7, r7\\n\\t\"\n        \"adcs\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adcs\tr10, r10, r10\\n\\t\"\n        \"adcs\tr14, r14, r14\\n\\t\"\n        \"adc\tr3, r12, #0\\n\\t\"\n        \"sub\tr3, r12, r3\\n\\t\"\n        \"and\tr12, r3, #1\\n\\t\"\n        \"subs\tr4, r4, r3\\n\\t\"\n        \"sbcs\tr5, r5, r3\\n\\t\"\n        \"sbcs\tr6, r6, r3\\n\\t\"\n        \"sbcs\tr7, r7, #0\\n\\t\"\n        \"sbcs\tr8, r8, #0\\n\\t\"\n        \"sbcs\tr9, r9, #0\\n\\t\"\n        \"sbcs\tr10, r10, r12\\n\\t\"\n        \"sbc\tr14, r14, r3\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"str\tr6, [%[r],#8]\\n\\t\"\n        \"str\tr7, [%[r],#12]\\n\\t\"\n        \"str\tr8, [%[r],#16]\\n\\t\"\n        \"str\tr9, [%[r],#20]\\n\\t\"\n        \"str\tr10, [%[r],#24]\\n\\t\"\n        \"str\tr14, [%[r],#28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r3\", \"r12\"\n    );\n}\n\n/* Triple a Montgomery form number (r = a + a + a % m).\n *\n * r   Result of Tripling.\n * a   Number to triple in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_tpl_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a],#0]\\n\\t\"\n        \"ldr\tr5, [%[a],#4]\\n\\t\"\n        \"ldr\tr6, [%[a],#8]\\n\\t\"\n        \"ldr\tr7, [%[a],#12]\\n\\t\"\n        \"ldr\tr8, [%[a],#16]\\n\\t\"\n        \"ldr\tr9, [%[a],#20]\\n\\t\"\n        \"ldr\tr10, [%[a],#24]\\n\\t\"\n        \"ldr\tr14, [%[a],#28]\\n\\t\"\n        \"adds\tr4, r4, r4\\n\\t\"\n        \"adcs\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adcs\tr7, r7, r7\\n\\t\"\n        \"adcs\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adcs\tr10, r10, r10\\n\\t\"\n        \"adcs\tr14, r14, r14\\n\\t\"\n        \"adc\tr3, r12, #0\\n\\t\"\n        \"sub\tr3, r12, r3\\n\\t\"\n        \"and\tr12, r3, #1\\n\\t\"\n        \"subs\tr4, r4, r3\\n\\t\"\n        \"sbcs\tr5, r5, r3\\n\\t\"\n        \"sbcs\tr6, r6, r3\\n\\t\"\n        \"sbcs\tr7, r7, #0\\n\\t\"\n        \"sbcs\tr8, r8, #0\\n\\t\"\n        \"sbcs\tr9, r9, #0\\n\\t\"\n        \"sbcs\tr10, r10, r12\\n\\t\"\n        \"sbc\tr14, r14, r3\\n\\t\"\n        \"str\tr8, [%[r],#16]\\n\\t\"\n        \"str\tr9, [%[r],#20]\\n\\t\"\n        \"str\tr10, [%[r],#24]\\n\\t\"\n        \"str\tr14, [%[r],#28]\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr8, [%[a],#0]\\n\\t\"\n        \"ldr\tr9, [%[a],#4]\\n\\t\"\n        \"ldr\tr10, [%[a],#8]\\n\\t\"\n        \"ldr\tr14, [%[a],#12]\\n\\t\"\n        \"adds\tr8, r8, r4\\n\\t\"\n        \"adcs\tr9, r9, r5\\n\\t\"\n        \"adcs\tr10, r10, r6\\n\\t\"\n        \"adcs\tr14, r14, r7\\n\\t\"\n        \"str\tr8, [%[r],#0]\\n\\t\"\n        \"str\tr9, [%[r],#4]\\n\\t\"\n        \"str\tr10, [%[r],#8]\\n\\t\"\n        \"str\tr14, [%[r],#12]\\n\\t\"\n        \"ldr\tr8, [%[a],#16]\\n\\t\"\n        \"ldr\tr9, [%[a],#20]\\n\\t\"\n        \"ldr\tr10, [%[a],#24]\\n\\t\"\n        \"ldr\tr14, [%[a],#28]\\n\\t\"\n        \"ldr\tr4, [%[r],#16]\\n\\t\"\n        \"ldr\tr5, [%[r],#20]\\n\\t\"\n        \"ldr\tr6, [%[r],#24]\\n\\t\"\n        \"ldr\tr7, [%[r],#28]\\n\\t\"\n        \"adcs\tr8, r8, r4\\n\\t\"\n        \"adcs\tr9, r9, r5\\n\\t\"\n        \"adcs\tr10, r10, r6\\n\\t\"\n        \"adcs\tr14, r14, r7\\n\\t\"\n        \"adc\tr3, r12, #0\\n\\t\"\n        \"sub\tr3, r12, r3\\n\\t\"\n        \"and\tr12, r3, #1\\n\\t\"\n        \"ldr\tr4, [%[r],#0]\\n\\t\"\n        \"ldr\tr5, [%[r],#4]\\n\\t\"\n        \"ldr\tr6, [%[r],#8]\\n\\t\"\n        \"ldr\tr7, [%[r],#12]\\n\\t\"\n        \"subs\tr4, r4, r3\\n\\t\"\n        \"sbcs\tr5, r5, r3\\n\\t\"\n        \"sbcs\tr6, r6, r3\\n\\t\"\n        \"sbcs\tr7, r7, #0\\n\\t\"\n        \"sbcs\tr8, r8, #0\\n\\t\"\n        \"sbcs\tr9, r9, #0\\n\\t\"\n        \"sbcs\tr10, r10, r12\\n\\t\"\n        \"sbc\tr14, r14, r3\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"str\tr6, [%[r],#8]\\n\\t\"\n        \"str\tr7, [%[r],#12]\\n\\t\"\n        \"str\tr8, [%[r],#16]\\n\\t\"\n        \"str\tr9, [%[r],#20]\\n\\t\"\n        \"str\tr10, [%[r],#24]\\n\\t\"\n        \"str\tr14, [%[r],#28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r3\", \"r12\"\n    );\n}\n\n/* Subtract two Montgomery form numbers (r = a - b % m).\n *\n * r   Result of subtration.\n * a   Number to subtract from in Montogmery form.\n * b   Number to subtract with in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m)\n{\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"mov\tr12, #0\\n\\t\"\n        \"ldr\tr4, [%[a],#0]\\n\\t\"\n        \"ldr\tr5, [%[a],#4]\\n\\t\"\n        \"ldr\tr6, [%[a],#8]\\n\\t\"\n        \"ldr\tr7, [%[a],#12]\\n\\t\"\n        \"ldr\tr8, [%[b],#0]\\n\\t\"\n        \"ldr\tr9, [%[b],#4]\\n\\t\"\n        \"ldr\tr10, [%[b],#8]\\n\\t\"\n        \"ldr\tr14, [%[b],#12]\\n\\t\"\n        \"subs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"sbcs\tr6, r6, r10\\n\\t\"\n        \"sbcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"str\tr6, [%[r],#8]\\n\\t\"\n        \"str\tr7, [%[r],#12]\\n\\t\"\n        \"ldr\tr4, [%[a],#16]\\n\\t\"\n        \"ldr\tr5, [%[a],#20]\\n\\t\"\n        \"ldr\tr6, [%[a],#24]\\n\\t\"\n        \"ldr\tr7, [%[a],#28]\\n\\t\"\n        \"ldr\tr8, [%[b],#16]\\n\\t\"\n        \"ldr\tr9, [%[b],#20]\\n\\t\"\n        \"ldr\tr10, [%[b],#24]\\n\\t\"\n        \"ldr\tr14, [%[b],#28]\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"sbcs\tr6, r6, r10\\n\\t\"\n        \"sbcs\tr7, r7, r14\\n\\t\"\n        \"sbc\tr3, r12, #0\\n\\t\"\n        \"and\tr12, r3, #1\\n\\t\"\n        \"ldr\tr8, [%[r],#0]\\n\\t\"\n        \"ldr\tr9, [%[r],#4]\\n\\t\"\n        \"ldr\tr10, [%[r],#8]\\n\\t\"\n        \"ldr\tr14, [%[r],#12]\\n\\t\"\n        \"adds\tr8, r8, r3\\n\\t\"\n        \"adcs\tr9, r9, r3\\n\\t\"\n        \"adcs\tr10, r10, r3\\n\\t\"\n        \"adcs\tr14, r14, #0\\n\\t\"\n        \"adcs\tr4, r4, #0\\n\\t\"\n        \"adcs\tr5, r5, #0\\n\\t\"\n        \"adcs\tr6, r6, r12\\n\\t\"\n        \"adc\tr7, r7, r3\\n\\t\"\n        \"str\tr8, [%[r],#0]\\n\\t\"\n        \"str\tr9, [%[r],#4]\\n\\t\"\n        \"str\tr10, [%[r],#8]\\n\\t\"\n        \"str\tr14, [%[r],#12]\\n\\t\"\n        \"str\tr4, [%[r],#16]\\n\\t\"\n        \"str\tr5, [%[r],#20]\\n\\t\"\n        \"str\tr6, [%[r],#24]\\n\\t\"\n        \"str\tr7, [%[r],#28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r3\", \"r12\"\n    );\n}\n\n/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)\n *\n * r  Result of division by 2.\n * a  Number to divide.\n * m  Modulus (prime).\n */\nstatic void sp_256_div2_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    __asm__ __volatile__ (\n        \"mov\tr10, #0\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"and\tr9, r3, #1\\n\\t\"\n        \"sub\tr7, r10, r9\\n\\t\"\n        \"and\tr8, r7, #1\\n\\t\"\n        \"adds\tr3, r3, r7\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adcs\tr6, r6, r10\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[a], #24]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"adcs\tr3, r3, r10\\n\\t\"\n        \"adcs\tr4, r4, r10\\n\\t\"\n        \"adcs\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r7\\n\\t\"\n        \"adc\tr9, r10, r10\\n\\t\"\n        \"lsr\tr7, r3, #1\\n\\t\"\n        \"and\tr3, r3, #1\\n\\t\"\n        \"lsr\tr8, r4, #1\\n\\t\"\n        \"lsr\tr10, r5, #1\\n\\t\"\n        \"lsr\tr14, r6, #1\\n\\t\"\n        \"orr\tr7, r7, r4, lsl #31\\n\\t\"\n        \"orr\tr8, r8, r5, lsl #31\\n\\t\"\n        \"orr\tr10, r10, r6, lsl #31\\n\\t\"\n        \"orr\tr14, r14, r9, lsl #31\\n\\t\"\n        \"mov\tr9, r3\\n\\t\"\n        \"str\tr7, [%[r], #16]\\n\\t\"\n        \"str\tr8, [%[r], #20]\\n\\t\"\n        \"str\tr10, [%[r], #24]\\n\\t\"\n        \"str\tr14, [%[r], #28]\\n\\t\"\n        \"ldr\tr3, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr5, [%[r], #8]\\n\\t\"\n        \"ldr\tr6, [%[r], #12]\\n\\t\"\n        \"lsr\tr7, r3, #1\\n\\t\"\n        \"lsr\tr8, r4, #1\\n\\t\"\n        \"lsr\tr10, r5, #1\\n\\t\"\n        \"lsr\tr14, r6, #1\\n\\t\"\n        \"orr\tr7, r7, r4, lsl #31\\n\\t\"\n        \"orr\tr8, r8, r5, lsl #31\\n\\t\"\n        \"orr\tr10, r10, r6, lsl #31\\n\\t\"\n        \"orr\tr14, r14, r9, lsl #31\\n\\t\"\n        \"str\tr7, [%[r], #0]\\n\\t\"\n        \"str\tr8, [%[r], #4]\\n\\t\"\n        \"str\tr10, [%[r], #8]\\n\\t\"\n        \"str\tr14, [%[r], #12]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [m] \"r\" (m)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r10\", \"r14\", \"r9\"\n    );\n\n}\n\n/* Double the Montgomery form projective point p.\n *\n * r  Result of doubling point.\n * p  Point to double.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_8(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*8;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* When infinity don't double point passed in - constant time. */\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    /* Put point to double into result - good for infinty. */\n    if (r != p) {\n        for (i=0; i<8; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<8; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<8; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* T1 = Z * Z */\n    sp_256_mont_sqr_8(t1, z, p256_mod, p256_mp_mod);\n    /* Z = Y * Z */\n    sp_256_mont_mul_8(z, y, z, p256_mod, p256_mp_mod);\n    /* Z = 2Z */\n    sp_256_mont_dbl_8(z, z, p256_mod);\n    /* T2 = X - T1 */\n    sp_256_mont_sub_8(t2, x, t1, p256_mod);\n    /* T1 = X + T1 */\n    sp_256_mont_add_8(t1, x, t1, p256_mod);\n    /* T2 = T1 * T2 */\n    sp_256_mont_mul_8(t2, t1, t2, p256_mod, p256_mp_mod);\n    /* T1 = 3T2 */\n    sp_256_mont_tpl_8(t1, t2, p256_mod);\n    /* Y = 2Y */\n    sp_256_mont_dbl_8(y, y, p256_mod);\n    /* Y = Y * Y */\n    sp_256_mont_sqr_8(y, y, p256_mod, p256_mp_mod);\n    /* T2 = Y * Y */\n    sp_256_mont_sqr_8(t2, y, p256_mod, p256_mp_mod);\n    /* T2 = T2/2 */\n    sp_256_div2_8(t2, t2, p256_mod);\n    /* Y = Y * X */\n    sp_256_mont_mul_8(y, y, x, p256_mod, p256_mp_mod);\n    /* X = T1 * T1 */\n    sp_256_mont_mul_8(x, t1, t1, p256_mod, p256_mp_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_8(x, x, y, p256_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_8(x, x, y, p256_mod);\n    /* Y = Y - X */\n    sp_256_mont_sub_8(y, y, x, p256_mod);\n    /* Y = Y * T1 */\n    sp_256_mont_mul_8(y, y, t1, p256_mod, p256_mp_mod);\n    /* Y = Y - T2 */\n    sp_256_mont_sub_8(y, y, t2, p256_mod);\n\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tr12, %[a], #32\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"rsbs\t%[c], %[c], #0\\n\\t\"\n        \"ldr\tr4, [%[a]], #4\\n\\t\"\n        \"ldr\tr5, [%[a]], #4\\n\\t\"\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"ldr\tr7, [%[a]], #4\\n\\t\"\n        \"ldr\tr8, [%[b]], #4\\n\\t\"\n        \"ldr\tr9, [%[b]], #4\\n\\t\"\n        \"ldr\tr10, [%[b]], #4\\n\\t\"\n        \"ldr\tr14, [%[b]], #4\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"sbcs\tr6, r6, r10\\n\\t\"\n        \"sbcs\tr7, r7, r14\\n\\t\"\n        \"str\tr4, [%[r]], #4\\n\\t\"\n        \"str\tr5, [%[r]], #4\\n\\t\"\n        \"str\tr6, [%[r]], #4\\n\\t\"\n        \"str\tr7, [%[r]], #4\\n\\t\"\n        \"sbc\t%[c], r4, r4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n\n    return c;\n}\n\n#else\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"ldr\tr8, [%[b], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"ldr\tr10, [%[b], #12]\\n\\t\"\n        \"subs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"sbcs\tr6, r6, r10\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[a], #24]\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"ldr\tr8, [%[b], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"ldr\tr10, [%[b], #28]\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"sbcs\tr6, r6, r10\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"str\tr5, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        \"sbc\t%[c], %[c], #0\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Compare two numbers to determine if they are equal.\n * Constant time implementation.\n *\n * a  First number to compare.\n * b  Second number to compare.\n * returns 1 when equal and 0 otherwise.\n */\nstatic int sp_256_cmp_equal_8(const sp_digit* a, const sp_digit* b)\n{\n    return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) |\n            (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7])) == 0;\n}\n\n/* Add two Montgomery form projective points.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_point* q,\n        sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*8;\n    sp_digit* t3 = t + 4*8;\n    sp_digit* t4 = t + 6*8;\n    sp_digit* t5 = t + 8*8;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Ensure only the first point is the same as the result. */\n    if (q == r) {\n        const sp_point* a = p;\n        p = q;\n        q = a;\n    }\n\n    /* Check double */\n    (void)sp_256_sub_8(t1, p256_mod, q->y);\n    sp_256_norm_8(t1);\n    if ((sp_256_cmp_equal_8(p->x, q->x) & sp_256_cmp_equal_8(p->z, q->z) &\n        (sp_256_cmp_equal_8(p->y, q->y) | sp_256_cmp_equal_8(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_8(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<8; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<8; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<8; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U1 = X1*Z2^2 */\n        sp_256_mont_sqr_8(t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t3, t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t1, t1, x, p256_mod, p256_mp_mod);\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_8(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S1 = Y1*Z2^3 */\n        sp_256_mont_mul_8(t3, t3, y, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_8(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - U1 */\n        sp_256_mont_sub_8(t2, t2, t1, p256_mod);\n        /* R = S2 - S1 */\n        sp_256_mont_sub_8(t4, t4, t3, p256_mod);\n        /* Z3 = H*Z1*Z2 */\n        sp_256_mont_mul_8(z, z, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*U1*H^2 */\n        sp_256_mont_sqr_8(x, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_8(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(y, t1, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(x, x, t5, p256_mod);\n        sp_256_mont_dbl_8(t1, y, p256_mod);\n        sp_256_mont_sub_8(x, x, t1, p256_mod);\n        /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */\n        sp_256_mont_sub_8(y, y, x, p256_mod);\n        sp_256_mont_mul_8(y, y, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t5, t5, t3, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(y, y, t5, p256_mod);\n    }\n}\n\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td[16];\n    sp_point rtd;\n    sp_digit tmpd[2 * 8 * 5];\n#endif\n    sp_point* t;\n    sp_point* rt;\n    sp_digit* tmp;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_point*)XMALLOC(sizeof(sp_point) * 16, heap, DYNAMIC_TYPE_ECC);\n    if (t == NULL)\n        err = MEMORY_E;\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap,\n                             DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n#else\n    t = td;\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        /* t[0] = {0, 0, 1} * norm */\n        XMEMSET(&t[0], 0, sizeof(t[0]));\n        t[0].infinity = 1;\n        /* t[1] = {g->x, g->y, g->z} * norm */\n        (void)sp_256_mod_mul_norm_8(t[1].x, g->x, p256_mod);\n        (void)sp_256_mod_mul_norm_8(t[1].y, g->y, p256_mod);\n        (void)sp_256_mod_mul_norm_8(t[1].z, g->z, p256_mod);\n        t[1].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[ 2], &t[ 1], tmp);\n        t[ 2].infinity = 0;\n        sp_256_proj_point_add_8(&t[ 3], &t[ 2], &t[ 1], tmp);\n        t[ 3].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[ 4], &t[ 2], tmp);\n        t[ 4].infinity = 0;\n        sp_256_proj_point_add_8(&t[ 5], &t[ 3], &t[ 2], tmp);\n        t[ 5].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[ 6], &t[ 3], tmp);\n        t[ 6].infinity = 0;\n        sp_256_proj_point_add_8(&t[ 7], &t[ 4], &t[ 3], tmp);\n        t[ 7].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[ 8], &t[ 4], tmp);\n        t[ 8].infinity = 0;\n        sp_256_proj_point_add_8(&t[ 9], &t[ 5], &t[ 4], tmp);\n        t[ 9].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[10], &t[ 5], tmp);\n        t[10].infinity = 0;\n        sp_256_proj_point_add_8(&t[11], &t[ 6], &t[ 5], tmp);\n        t[11].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[12], &t[ 6], tmp);\n        t[12].infinity = 0;\n        sp_256_proj_point_add_8(&t[13], &t[ 7], &t[ 6], tmp);\n        t[13].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[14], &t[ 7], tmp);\n        t[14].infinity = 0;\n        sp_256_proj_point_add_8(&t[15], &t[ 8], &t[ 7], tmp);\n        t[15].infinity = 0;\n\n        i = 6;\n        n = k[i+1] << 0;\n        c = 28;\n        y = n >> 28;\n        XMEMCPY(rt, &t[y], sizeof(sp_point));\n        n <<= 4;\n        for (; i>=0 || c>=4; ) {\n            if (c < 4) {\n                n |= k[i--] << (0 - c);\n                c += 32;\n            }\n            y = (n >> 28) & 0xf;\n            n <<= 4;\n            c -= 4;\n\n            sp_256_proj_point_dbl_8(rt, rt, tmp);\n            sp_256_proj_point_dbl_8(rt, rt, tmp);\n            sp_256_proj_point_dbl_8(rt, rt, tmp);\n            sp_256_proj_point_dbl_8(rt, rt, tmp);\n\n            sp_256_proj_point_add_8(rt, rt, &t[y], tmp);\n        }\n\n        if (map != 0) {\n            sp_256_map_8(r, rt, tmp);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 8 * 5);\n        XFREE(tmp, heap, DYNAMIC_TYPE_ECC);\n    }\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_point) * 16);\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    ForceZero(tmpd, sizeof(tmpd));\n    ForceZero(td, sizeof(td));\n#endif\n    sp_ecc_point_free(rt, 1, heap);\n\n    return err;\n}\n\n/* A table entry for pre-computed points. */\ntypedef struct sp_table_entry {\n    sp_digit x[8];\n    sp_digit y[8];\n} sp_table_entry;\n\n#ifdef FP_ECC\n/* Double the Montgomery form projective point p a number of times.\n *\n * r  Result of repeated doubling of point.\n * p  Point to double.\n * n  Number of times to double\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_n_8(sp_point* r, const sp_point* p, int n,\n        sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* w = t;\n    sp_digit* a = t + 2*8;\n    sp_digit* b = t + 4*8;\n    sp_digit* t1 = t + 6*8;\n    sp_digit* t2 = t + 8*8;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    if (r != p) {\n        for (i=0; i<8; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<8; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<8; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* Y = 2*Y */\n    sp_256_mont_dbl_8(y, y, p256_mod);\n    /* W = Z^4 */\n    sp_256_mont_sqr_8(w, z, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_8(w, w, p256_mod, p256_mp_mod);\n    while (n-- > 0) {\n        /* A = 3*(X^2 - W) */\n        sp_256_mont_sqr_8(t1, x, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(t1, t1, w, p256_mod);\n        sp_256_mont_tpl_8(a, t1, p256_mod);\n        /* B = X*Y^2 */\n        sp_256_mont_sqr_8(t2, y, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(b, t2, x, p256_mod, p256_mp_mod);\n        /* X = A^2 - 2B */\n        sp_256_mont_sqr_8(x, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_8(t1, b, p256_mod);\n        sp_256_mont_sub_8(x, x, t1, p256_mod);\n        /* Z = Z*Y */\n        sp_256_mont_mul_8(z, z, y, p256_mod, p256_mp_mod);\n        /* t2 = Y^4 */\n        sp_256_mont_sqr_8(t2, t2, p256_mod, p256_mp_mod);\n        if (n != 0) {\n            /* W = W*Y^4 */\n            sp_256_mont_mul_8(w, w, t2, p256_mod, p256_mp_mod);\n        }\n        /* y = 2*A*(B - X) - Y^4 */\n        sp_256_mont_sub_8(y, b, x, p256_mod);\n        sp_256_mont_mul_8(y, y, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_8(y, y, p256_mod);\n        sp_256_mont_sub_8(y, y, t2, p256_mod);\n    }\n    /* Y = Y/2 */\n    sp_256_div2_8(y, y, p256_mod);\n}\n\n#endif /* FP_ECC */\n/* Add two Montgomery form projective points. The second point has a q value of\n * one.\n * Only the first point can be the same pointer as the result point.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_qz1_8(sp_point* r, const sp_point* p,\n        const sp_point* q, sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*8;\n    sp_digit* t3 = t + 4*8;\n    sp_digit* t4 = t + 6*8;\n    sp_digit* t5 = t + 8*8;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Check double */\n    (void)sp_256_sub_8(t1, p256_mod, q->y);\n    sp_256_norm_8(t1);\n    if ((sp_256_cmp_equal_8(p->x, q->x) & sp_256_cmp_equal_8(p->z, q->z) &\n        (sp_256_cmp_equal_8(p->y, q->y) | sp_256_cmp_equal_8(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_8(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<8; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<8; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<8; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_8(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_8(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - X1 */\n        sp_256_mont_sub_8(t2, t2, x, p256_mod);\n        /* R = S2 - Y1 */\n        sp_256_mont_sub_8(t4, t4, y, p256_mod);\n        /* Z3 = H*Z1 */\n        sp_256_mont_mul_8(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*X1*H^2 */\n        sp_256_mont_sqr_8(t1, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_8(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t3, x, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(x, t1, t5, p256_mod);\n        sp_256_mont_dbl_8(t1, t3, p256_mod);\n        sp_256_mont_sub_8(x, x, t1, p256_mod);\n        /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */\n        sp_256_mont_sub_8(t3, t3, x, p256_mod);\n        sp_256_mont_mul_8(t3, t3, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t5, t5, y, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(y, t3, t5, p256_mod);\n    }\n}\n\n#ifdef WOLFSSL_SP_SMALL\n#ifdef FP_ECC\n/* Convert the projective point to affine.\n * Ordinates are in Montgomery form.\n *\n * a  Point to convert.\n * t  Temprorary data.\n */\nstatic void sp_256_proj_to_affine_8(sp_point* a, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2 * 8;\n    sp_digit* tmp = t + 4 * 8;\n\n    sp_256_mont_inv_8(t1, a->z, tmp);\n\n    sp_256_mont_sqr_8(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_8(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    sp_256_mont_mul_8(a->x, a->x, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_8(a->y, a->y, t1, p256_mod, p256_mp_mod);\n    XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod));\n}\n\n/* Generate the pre-computed table of points for the base point.\n *\n * a      The base point.\n * table  Place to store generated point data.\n * tmp    Temprorary data.\n * heap  Heap to use for allocation.\n */\nstatic int sp_256_gen_stripe_table_8(const sp_point* a,\n        sp_table_entry* table, sp_digit* tmp, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td, s1d, s2d;\n#endif\n    sp_point* t;\n    sp_point* s1 = NULL;\n    sp_point* s2 = NULL;\n    int i, j;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, td, t);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s1d, s1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s2d, s2);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->x, a->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->y, a->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->z, a->z, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        t->infinity = 0;\n        sp_256_proj_to_affine_8(t, tmp);\n\n        XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s1->infinity = 0;\n        XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s2->infinity = 0;\n\n        /* table[0] = {0, 0, infinity} */\n        XMEMSET(&table[0], 0, sizeof(sp_table_entry));\n        /* table[1] = Affine version of 'a' in Montgomery form */\n        XMEMCPY(table[1].x, t->x, sizeof(table->x));\n        XMEMCPY(table[1].y, t->y, sizeof(table->y));\n\n        for (i=1; i<4; i++) {\n            sp_256_proj_point_dbl_n_8(t, t, 64, tmp);\n            sp_256_proj_to_affine_8(t, tmp);\n            XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));\n            XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));\n        }\n\n        for (i=1; i<4; i++) {\n            XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));\n            XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));\n            for (j=(1<<i)+1; j<(1<<(i+1)); j++) {\n                XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));\n                XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));\n                sp_256_proj_point_add_qz1_8(t, s1, s2, tmp);\n                sp_256_proj_to_affine_8(t, tmp);\n                XMEMCPY(table[j].x, t->x, sizeof(table->x));\n                XMEMCPY(table[j].y, t->y, sizeof(table->y));\n            }\n        }\n    }\n\n    sp_ecc_point_free(s2, 0, heap);\n    sp_ecc_point_free(s1, 0, heap);\n    sp_ecc_point_free( t, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC */\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit td[2 * 8 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* t;\n    int i, j;\n    int y, x;\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap,\n                           DYNAMIC_TYPE_ECC);\n    if (t == NULL) {\n        err = MEMORY_E;\n    }\n#else\n    t = td;\n#endif\n\n    if (err == MP_OKAY) {\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        y = 0;\n        for (j=0,x=63; j<4; j++,x+=64) {\n            y |= ((k[x / 32] >> (x % 32)) & 1) << j;\n        }\n        XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));\n        XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));\n        rt->infinity = !y;\n        for (i=62; i>=0; i--) {\n            y = 0;\n            for (j=0,x=i; j<4; j++,x+=64) {\n                y |= ((k[x / 32] >> (x % 32)) & 1) << j;\n            }\n\n            sp_256_proj_point_dbl_8(rt, rt, t);\n            XMEMCPY(p->x, table[y].x, sizeof(table[y].x));\n            XMEMCPY(p->y, table[y].y, sizeof(table[y].y));\n            p->infinity = !y;\n            sp_256_proj_point_add_qz1_8(rt, rt, p, t);\n        }\n\n        if (map != 0) {\n            sp_256_map_8(r, rt, t);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n#ifdef FP_ECC\n#ifndef FP_ENTRIES\n    #define FP_ENTRIES 16\n#endif\n\ntypedef struct sp_cache_t {\n    sp_digit x[8];\n    sp_digit y[8];\n    sp_table_entry table[16];\n    uint32_t cnt;\n    int set;\n} sp_cache_t;\n\nstatic THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES];\nstatic THREAD_LS_T int sp_cache_last = -1;\nstatic THREAD_LS_T int sp_cache_inited = 0;\n\n#ifndef HAVE_THREAD_LS\n    static volatile int initCacheMutex = 0;\n    static wolfSSL_Mutex sp_cache_lock;\n#endif\n\nstatic void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache)\n{\n    int i, j;\n    uint32_t least;\n\n    if (sp_cache_inited == 0) {\n        for (i=0; i<FP_ENTRIES; i++) {\n            sp_cache[i].set = 0;\n        }\n        sp_cache_inited = 1;\n    }\n\n    /* Compare point with those in cache. */\n    for (i=0; i<FP_ENTRIES; i++) {\n        if (!sp_cache[i].set)\n            continue;\n\n        if (sp_256_cmp_equal_8(g->x, sp_cache[i].x) &\n                           sp_256_cmp_equal_8(g->y, sp_cache[i].y)) {\n            sp_cache[i].cnt++;\n            break;\n        }\n    }\n\n    /* No match. */\n    if (i == FP_ENTRIES) {\n        /* Find empty entry. */\n        i = (sp_cache_last + 1) % FP_ENTRIES;\n        for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) {\n            if (!sp_cache[i].set) {\n                break;\n            }\n        }\n\n        /* Evict least used. */\n        if (i == sp_cache_last) {\n            least = sp_cache[0].cnt;\n            for (j=1; j<FP_ENTRIES; j++) {\n                if (sp_cache[j].cnt < least) {\n                    i = j;\n                    least = sp_cache[i].cnt;\n                }\n            }\n        }\n\n        XMEMCPY(sp_cache[i].x, g->x, sizeof(sp_cache[i].x));\n        XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y));\n        sp_cache[i].set = 1;\n        sp_cache[i].cnt = 1;\n    }\n\n    *cache = &sp_cache[i];\n    sp_cache_last = i;\n}\n#endif /* FP_ECC */\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#ifndef FP_ECC\n    return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);\n#else\n    sp_digit tmp[2 * 8 * 5];\n    sp_cache_t* cache;\n    int err = MP_OKAY;\n\n#ifndef HAVE_THREAD_LS\n    if (initCacheMutex == 0) {\n         wc_InitMutex(&sp_cache_lock);\n         initCacheMutex = 1;\n    }\n    if (wc_LockMutex(&sp_cache_lock) != 0)\n       err = BAD_MUTEX_E;\n#endif /* HAVE_THREAD_LS */\n\n    if (err == MP_OKAY) {\n        sp_ecc_get_cache(g, &cache);\n        if (cache->cnt == 2)\n            sp_256_gen_stripe_table_8(g, cache->table, tmp, heap);\n\n#ifndef HAVE_THREAD_LS\n        wc_UnLockMutex(&sp_cache_lock);\n#endif /* HAVE_THREAD_LS */\n\n        if (cache->cnt < 2) {\n            err = sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);\n        }\n        else {\n            err = sp_256_ecc_mulmod_stripe_8(r, g, cache->table, k,\n                    map, heap);\n        }\n    }\n\n    return err;\n#endif\n}\n\n#else\n#ifdef FP_ECC\n/* Generate the pre-computed table of points for the base point.\n *\n * a      The base point.\n * table  Place to store generated point data.\n * tmp    Temprorary data.\n * heap  Heap to use for allocation.\n */\nstatic int sp_256_gen_stripe_table_8(const sp_point* a,\n        sp_table_entry* table, sp_digit* tmp, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td, s1d, s2d;\n#endif\n    sp_point* t;\n    sp_point* s1 = NULL;\n    sp_point* s2 = NULL;\n    int i, j;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, td, t);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s1d, s1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s2d, s2);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->x, a->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->y, a->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->z, a->z, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        t->infinity = 0;\n        sp_256_proj_to_affine_8(t, tmp);\n\n        XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s1->infinity = 0;\n        XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s2->infinity = 0;\n\n        /* table[0] = {0, 0, infinity} */\n        XMEMSET(&table[0], 0, sizeof(sp_table_entry));\n        /* table[1] = Affine version of 'a' in Montgomery form */\n        XMEMCPY(table[1].x, t->x, sizeof(table->x));\n        XMEMCPY(table[1].y, t->y, sizeof(table->y));\n\n        for (i=1; i<8; i++) {\n            sp_256_proj_point_dbl_n_8(t, t, 32, tmp);\n            sp_256_proj_to_affine_8(t, tmp);\n            XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));\n            XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));\n        }\n\n        for (i=1; i<8; i++) {\n            XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));\n            XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));\n            for (j=(1<<i)+1; j<(1<<(i+1)); j++) {\n                XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));\n                XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));\n                sp_256_proj_point_add_qz1_8(t, s1, s2, tmp);\n                sp_256_proj_to_affine_8(t, tmp);\n                XMEMCPY(table[j].x, t->x, sizeof(table->x));\n                XMEMCPY(table[j].y, t->y, sizeof(table->y));\n            }\n        }\n    }\n\n    sp_ecc_point_free(s2, 0, heap);\n    sp_ecc_point_free(s1, 0, heap);\n    sp_ecc_point_free( t, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC */\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit td[2 * 8 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* t;\n    int i, j;\n    int y, x;\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap,\n                           DYNAMIC_TYPE_ECC);\n    if (t == NULL) {\n        err = MEMORY_E;\n    }\n#else\n    t = td;\n#endif\n\n    if (err == MP_OKAY) {\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        y = 0;\n        for (j=0,x=31; j<8; j++,x+=32) {\n            y |= ((k[x / 32] >> (x % 32)) & 1) << j;\n        }\n        XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));\n        XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));\n        rt->infinity = !y;\n        for (i=30; i>=0; i--) {\n            y = 0;\n            for (j=0,x=i; j<8; j++,x+=32) {\n                y |= ((k[x / 32] >> (x % 32)) & 1) << j;\n            }\n\n            sp_256_proj_point_dbl_8(rt, rt, t);\n            XMEMCPY(p->x, table[y].x, sizeof(table[y].x));\n            XMEMCPY(p->y, table[y].y, sizeof(table[y].y));\n            p->infinity = !y;\n            sp_256_proj_point_add_qz1_8(rt, rt, p, t);\n        }\n\n        if (map != 0) {\n            sp_256_map_8(r, rt, t);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n#ifdef FP_ECC\n#ifndef FP_ENTRIES\n    #define FP_ENTRIES 16\n#endif\n\ntypedef struct sp_cache_t {\n    sp_digit x[8];\n    sp_digit y[8];\n    sp_table_entry table[256];\n    uint32_t cnt;\n    int set;\n} sp_cache_t;\n\nstatic THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES];\nstatic THREAD_LS_T int sp_cache_last = -1;\nstatic THREAD_LS_T int sp_cache_inited = 0;\n\n#ifndef HAVE_THREAD_LS\n    static volatile int initCacheMutex = 0;\n    static wolfSSL_Mutex sp_cache_lock;\n#endif\n\nstatic void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache)\n{\n    int i, j;\n    uint32_t least;\n\n    if (sp_cache_inited == 0) {\n        for (i=0; i<FP_ENTRIES; i++) {\n            sp_cache[i].set = 0;\n        }\n        sp_cache_inited = 1;\n    }\n\n    /* Compare point with those in cache. */\n    for (i=0; i<FP_ENTRIES; i++) {\n        if (!sp_cache[i].set)\n            continue;\n\n        if (sp_256_cmp_equal_8(g->x, sp_cache[i].x) &\n                           sp_256_cmp_equal_8(g->y, sp_cache[i].y)) {\n            sp_cache[i].cnt++;\n            break;\n        }\n    }\n\n    /* No match. */\n    if (i == FP_ENTRIES) {\n        /* Find empty entry. */\n        i = (sp_cache_last + 1) % FP_ENTRIES;\n        for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) {\n            if (!sp_cache[i].set) {\n                break;\n            }\n        }\n\n        /* Evict least used. */\n        if (i == sp_cache_last) {\n            least = sp_cache[0].cnt;\n            for (j=1; j<FP_ENTRIES; j++) {\n                if (sp_cache[j].cnt < least) {\n                    i = j;\n                    least = sp_cache[i].cnt;\n                }\n            }\n        }\n\n        XMEMCPY(sp_cache[i].x, g->x, sizeof(sp_cache[i].x));\n        XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y));\n        sp_cache[i].set = 1;\n        sp_cache[i].cnt = 1;\n    }\n\n    *cache = &sp_cache[i];\n    sp_cache_last = i;\n}\n#endif /* FP_ECC */\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#ifndef FP_ECC\n    return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);\n#else\n    sp_digit tmp[2 * 8 * 5];\n    sp_cache_t* cache;\n    int err = MP_OKAY;\n\n#ifndef HAVE_THREAD_LS\n    if (initCacheMutex == 0) {\n         wc_InitMutex(&sp_cache_lock);\n         initCacheMutex = 1;\n    }\n    if (wc_LockMutex(&sp_cache_lock) != 0)\n       err = BAD_MUTEX_E;\n#endif /* HAVE_THREAD_LS */\n\n    if (err == MP_OKAY) {\n        sp_ecc_get_cache(g, &cache);\n        if (cache->cnt == 2)\n            sp_256_gen_stripe_table_8(g, cache->table, tmp, heap);\n\n#ifndef HAVE_THREAD_LS\n        wc_UnLockMutex(&sp_cache_lock);\n#endif /* HAVE_THREAD_LS */\n\n        if (cache->cnt < 2) {\n            err = sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);\n        }\n        else {\n            err = sp_256_ecc_mulmod_stripe_8(r, g, cache->table, k,\n                    map, heap);\n        }\n    }\n\n    return err;\n#endif\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * p     Point to multiply.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map,\n        void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[8];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 8, km);\n        sp_256_point_from_ecc_point_8(point, gm);\n\n            err = sp_256_ecc_mulmod_8(point, point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_8(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#ifdef WOLFSSL_SP_SMALL\nstatic const sp_table_entry p256_table[16] = {\n    /* 0 */\n    { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 */\n    { { 0x18a9143c,0x79e730d4,0x5fedb601,0x75ba95fc,0x77622510,0x79fb732b,\n        0xa53755c6,0x18905f76 },\n      { 0xce95560a,0xddf25357,0xba19e45c,0x8b4ab8e4,0xdd21f325,0xd2e88688,\n        0x25885d85,0x8571ff18 } },\n    /* 2 */\n    { { 0x16a0d2bb,0x4f922fc5,0x1a623499,0x0d5cc16c,0x57c62c8b,0x9241cf3a,\n        0xfd1b667f,0x2f5e6961 },\n      { 0xf5a01797,0x5c15c70b,0x60956192,0x3d20b44d,0x071fdb52,0x04911b37,\n        0x8d6f0f7b,0xf648f916 } },\n    /* 3 */\n    { { 0xe137bbbc,0x9e566847,0x8a6a0bec,0xe434469e,0x79d73463,0xb1c42761,\n        0x133d0015,0x5abe0285 },\n      { 0xc04c7dab,0x92aa837c,0x43260c07,0x573d9f4c,0x78e6cc37,0x0c931562,\n        0x6b6f7383,0x94bb725b } },\n    /* 4 */\n    { { 0xbfe20925,0x62a8c244,0x8fdce867,0x91c19ac3,0xdd387063,0x5a96a5d5,\n        0x21d324f6,0x61d587d4 },\n      { 0xa37173ea,0xe87673a2,0x53778b65,0x23848008,0x05bab43e,0x10f8441e,\n        0x4621efbe,0xfa11fe12 } },\n    /* 5 */\n    { { 0x2cb19ffd,0x1c891f2b,0xb1923c23,0x01ba8d5b,0x8ac5ca8e,0xb6d03d67,\n        0x1f13bedc,0x586eb04c },\n      { 0x27e8ed09,0x0c35c6e5,0x1819ede2,0x1e81a33c,0x56c652fa,0x278fd6c0,\n        0x70864f11,0x19d5ac08 } },\n    /* 6 */\n    { { 0xd2b533d5,0x62577734,0xa1bdddc0,0x673b8af6,0xa79ec293,0x577e7c9a,\n        0xc3b266b1,0xbb6de651 },\n      { 0xb65259b3,0xe7e9303a,0xd03a7480,0xd6a0afd3,0x9b3cfc27,0xc5ac83d1,\n        0x5d18b99b,0x60b4619a } },\n    /* 7 */\n    { { 0x1ae5aa1c,0xbd6a38e1,0x49e73658,0xb8b7652b,0xee5f87ed,0x0b130014,\n        0xaeebffcd,0x9d0f27b2 },\n      { 0x7a730a55,0xca924631,0xddbbc83a,0x9c955b2f,0xac019a71,0x07c1dfe0,\n        0x356ec48d,0x244a566d } },\n    /* 8 */\n    { { 0xf4f8b16a,0x56f8410e,0xc47b266a,0x97241afe,0x6d9c87c1,0x0a406b8e,\n        0xcd42ab1b,0x803f3e02 },\n      { 0x04dbec69,0x7f0309a8,0x3bbad05f,0xa83b85f7,0xad8e197f,0xc6097273,\n        0x5067adc1,0xc097440e } },\n    /* 9 */\n    { { 0xc379ab34,0x846a56f2,0x841df8d1,0xa8ee068b,0x176c68ef,0x20314459,\n        0x915f1f30,0xf1af32d5 },\n      { 0x5d75bd50,0x99c37531,0xf72f67bc,0x837cffba,0x48d7723f,0x0613a418,\n        0xe2d41c8b,0x23d0f130 } },\n    /* 10 */\n    { { 0xd5be5a2b,0xed93e225,0x5934f3c6,0x6fe79983,0x22626ffc,0x43140926,\n        0x7990216a,0x50bbb4d9 },\n      { 0xe57ec63e,0x378191c6,0x181dcdb2,0x65422c40,0x0236e0f6,0x41a8099b,\n        0x01fe49c3,0x2b100118 } },\n    /* 11 */\n    { { 0x9b391593,0xfc68b5c5,0x598270fc,0xc385f5a2,0xd19adcbb,0x7144f3aa,\n        0x83fbae0c,0xdd558999 },\n      { 0x74b82ff4,0x93b88b8e,0x71e734c9,0xd2e03c40,0x43c0322a,0x9a7a9eaf,\n        0x149d6041,0xe6e4c551 } },\n    /* 12 */\n    { { 0x80ec21fe,0x5fe14bfe,0xc255be82,0xf6ce116a,0x2f4a5d67,0x98bc5a07,\n        0xdb7e63af,0xfad27148 },\n      { 0x29ab05b3,0x90c0b6ac,0x4e251ae6,0x37a9a83c,0xc2aade7d,0x0a7dc875,\n        0x9f0e1a84,0x77387de3 } },\n    /* 13 */\n    { { 0xa56c0dd7,0x1e9ecc49,0x46086c74,0xa5cffcd8,0xf505aece,0x8f7a1408,\n        0xbef0c47e,0xb37b85c0 },\n      { 0xcc0e6a8f,0x3596b6e4,0x6b388f23,0xfd6d4bbf,0xc39cef4e,0xaba453fa,\n        0xf9f628d5,0x9c135ac8 } },\n    /* 14 */\n    { { 0x95c8f8be,0x0a1c7294,0x3bf362bf,0x2961c480,0xdf63d4ac,0x9e418403,\n        0x91ece900,0xc109f9cb },\n      { 0x58945705,0xc2d095d0,0xddeb85c0,0xb9083d96,0x7a40449b,0x84692b8d,\n        0x2eee1ee1,0x9bc3344f } },\n    /* 15 */\n    { { 0x42913074,0x0d5ae356,0x48a542b1,0x55491b27,0xb310732a,0x469ca665,\n        0x5f1a4cc1,0x29591d52 },\n      { 0xb84f983f,0xe76f5b6b,0x9f5f84e1,0xbe7eef41,0x80baa189,0x1200d496,\n        0x18ef332c,0x6376551f } },\n};\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table,\n                                      k, map, heap);\n}\n\n#else\nstatic const sp_table_entry p256_table[256] = {\n    /* 0 */\n    { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 */\n    { { 0x18a9143c,0x79e730d4,0x5fedb601,0x75ba95fc,0x77622510,0x79fb732b,\n        0xa53755c6,0x18905f76 },\n      { 0xce95560a,0xddf25357,0xba19e45c,0x8b4ab8e4,0xdd21f325,0xd2e88688,\n        0x25885d85,0x8571ff18 } },\n    /* 2 */\n    { { 0x4147519a,0x20288602,0x26b372f0,0xd0981eac,0xa785ebc8,0xa9d4a7ca,\n        0xdbdf58e9,0xd953c50d },\n      { 0xfd590f8f,0x9d6361cc,0x44e6c917,0x72e9626b,0x22eb64cf,0x7fd96110,\n        0x9eb288f3,0x863ebb7e } },\n    /* 3 */\n    { { 0x5cdb6485,0x7856b623,0x2f0a2f97,0x808f0ea2,0x4f7e300b,0x3e68d954,\n        0xb5ff80a0,0x00076055 },\n      { 0x838d2010,0x7634eb9b,0x3243708a,0x54014fbb,0x842a6606,0xe0e47d39,\n        0x34373ee0,0x83087761 } },\n    /* 4 */\n    { { 0x16a0d2bb,0x4f922fc5,0x1a623499,0x0d5cc16c,0x57c62c8b,0x9241cf3a,\n        0xfd1b667f,0x2f5e6961 },\n      { 0xf5a01797,0x5c15c70b,0x60956192,0x3d20b44d,0x071fdb52,0x04911b37,\n        0x8d6f0f7b,0xf648f916 } },\n    /* 5 */\n    { { 0xe137bbbc,0x9e566847,0x8a6a0bec,0xe434469e,0x79d73463,0xb1c42761,\n        0x133d0015,0x5abe0285 },\n      { 0xc04c7dab,0x92aa837c,0x43260c07,0x573d9f4c,0x78e6cc37,0x0c931562,\n        0x6b6f7383,0x94bb725b } },\n    /* 6 */\n    { { 0x720f141c,0xbbf9b48f,0x2df5bc74,0x6199b3cd,0x411045c4,0xdc3f6129,\n        0x2f7dc4ef,0xcdd6bbcb },\n      { 0xeaf436fd,0xcca6700b,0xb99326be,0x6f647f6d,0x014f2522,0x0c0fa792,\n        0x4bdae5f6,0xa361bebd } },\n    /* 7 */\n    { { 0x597c13c7,0x28aa2558,0x50b7c3e1,0xc38d635f,0xf3c09d1d,0x07039aec,\n        0xc4b5292c,0xba12ca09 },\n      { 0x59f91dfd,0x9e408fa4,0xceea07fb,0x3af43b66,0x9d780b29,0x1eceb089,\n        0x701fef4b,0x53ebb99d } },\n    /* 8 */\n    { { 0xb0e63d34,0x4fe7ee31,0xa9e54fab,0xf4600572,0xd5e7b5a4,0xc0493334,\n        0x06d54831,0x8589fb92 },\n      { 0x6583553a,0xaa70f5cc,0xe25649e5,0x0879094a,0x10044652,0xcc904507,\n        0x02541c4f,0xebb0696d } },\n    /* 9 */\n    { { 0xac1647c5,0x4616ca15,0xc4cf5799,0xb8127d47,0x764dfbac,0xdc666aa3,\n        0xd1b27da3,0xeb2820cb },\n      { 0x6a87e008,0x9406f8d8,0x922378f3,0xd87dfa9d,0x80ccecb2,0x56ed2e42,\n        0x55a7da1d,0x1f28289b } },\n    /* 10 */\n    { { 0x3b89da99,0xabbaa0c0,0xb8284022,0xa6f2d79e,0xb81c05e8,0x27847862,\n        0x05e54d63,0x337a4b59 },\n      { 0x21f7794a,0x3c67500d,0x7d6d7f61,0x207005b7,0x04cfd6e8,0x0a5a3781,\n        0xf4c2fbd6,0x0d65e0d5 } },\n    /* 11 */\n    { { 0xb5275d38,0xd9d09bbe,0x0be0a358,0x4268a745,0x973eb265,0xf0762ff4,\n        0x52f4a232,0xc23da242 },\n      { 0x0b94520c,0x5da1b84f,0xb05bd78e,0x09666763,0x94d29ea1,0x3a4dcb86,\n        0xc790cff1,0x19de3b8c } },\n    /* 12 */\n    { { 0x26c5fe04,0x183a716c,0x3bba1bdb,0x3b28de0b,0xa4cb712c,0x7432c586,\n        0x91fccbfd,0xe34dcbd4 },\n      { 0xaaa58403,0xb408d46b,0x82e97a53,0x9a697486,0x36aaa8af,0x9e390127,\n        0x7b4e0f7f,0xe7641f44 } },\n    /* 13 */\n    { { 0xdf64ba59,0x7d753941,0x0b0242fc,0xd33f10ec,0xa1581859,0x4f06dfc6,\n        0x052a57bf,0x4a12df57 },\n      { 0x9439dbd0,0xbfa6338f,0xbde53e1f,0xd3c24bd4,0x21f1b314,0xfd5e4ffa,\n        0xbb5bea46,0x6af5aa93 } },\n    /* 14 */\n    { { 0x10c91999,0xda10b699,0x2a580491,0x0a24b440,0xb8cc2090,0x3e0094b4,\n        0x66a44013,0x5fe3475a },\n      { 0xf93e7b4b,0xb0f8cabd,0x7c23f91a,0x292b501a,0xcd1e6263,0x42e889ae,\n        0xecfea916,0xb544e308 } },\n    /* 15 */\n    { { 0x16ddfdce,0x6478c6e9,0xf89179e6,0x2c329166,0x4d4e67e1,0x4e8d6e76,\n        0xa6b0c20b,0xe0b6b2bd },\n      { 0xbb7efb57,0x0d312df2,0x790c4007,0x1aac0dde,0x679bc944,0xf90336ad,\n        0x25a63774,0x71c023de } },\n    /* 16 */\n    { { 0xbfe20925,0x62a8c244,0x8fdce867,0x91c19ac3,0xdd387063,0x5a96a5d5,\n        0x21d324f6,0x61d587d4 },\n      { 0xa37173ea,0xe87673a2,0x53778b65,0x23848008,0x05bab43e,0x10f8441e,\n        0x4621efbe,0xfa11fe12 } },\n    /* 17 */\n    { { 0x2cb19ffd,0x1c891f2b,0xb1923c23,0x01ba8d5b,0x8ac5ca8e,0xb6d03d67,\n        0x1f13bedc,0x586eb04c },\n      { 0x27e8ed09,0x0c35c6e5,0x1819ede2,0x1e81a33c,0x56c652fa,0x278fd6c0,\n        0x70864f11,0x19d5ac08 } },\n    /* 18 */\n    { { 0x309a4e1f,0x1e99f581,0xe9270074,0xab7de71b,0xefd28d20,0x26a5ef0b,\n        0x7f9c563f,0xe7c0073f },\n      { 0x0ef59f76,0x1f6d663a,0x20fcb050,0x669b3b54,0x7a6602d4,0xc08c1f7a,\n        0xc65b3c0a,0xe08504fe } },\n    /* 19 */\n    { { 0xa031b3ca,0xf098f68d,0xe6da6d66,0x6d1cab9e,0x94f246e8,0x5bfd81fa,\n        0x5b0996b4,0x78f01882 },\n      { 0x3a25787f,0xb7eefde4,0x1dccac9b,0x8016f80d,0xb35bfc36,0x0cea4877,\n        0x7e94747a,0x43a773b8 } },\n    /* 20 */\n    { { 0xd2b533d5,0x62577734,0xa1bdddc0,0x673b8af6,0xa79ec293,0x577e7c9a,\n        0xc3b266b1,0xbb6de651 },\n      { 0xb65259b3,0xe7e9303a,0xd03a7480,0xd6a0afd3,0x9b3cfc27,0xc5ac83d1,\n        0x5d18b99b,0x60b4619a } },\n    /* 21 */\n    { { 0x1ae5aa1c,0xbd6a38e1,0x49e73658,0xb8b7652b,0xee5f87ed,0x0b130014,\n        0xaeebffcd,0x9d0f27b2 },\n      { 0x7a730a55,0xca924631,0xddbbc83a,0x9c955b2f,0xac019a71,0x07c1dfe0,\n        0x356ec48d,0x244a566d } },\n    /* 22 */\n    { { 0xeacf1f96,0x6db0394a,0x024c271c,0x9f2122a9,0x82cbd3b9,0x2626ac1b,\n        0x3581ef69,0x45e58c87 },\n      { 0xa38f9dbc,0xd3ff479d,0xe888a040,0xa8aaf146,0x46e0bed7,0x945adfb2,\n        0xc1e4b7a4,0xc040e21c } },\n    /* 23 */\n    { { 0x6f8117b6,0x847af000,0x73a35433,0x651969ff,0x1d9475eb,0x482b3576,\n        0x682c6ec7,0x1cdf5c97 },\n      { 0x11f04839,0x7db775b4,0x48de1698,0x7dbeacf4,0xb70b3219,0xb2921dd1,\n        0xa92dff3d,0x046755f8 } },\n    /* 24 */\n    { { 0xbce8ffcd,0xcc8ac5d2,0x2fe61a82,0x0d53c48b,0x7202d6c7,0xf6f16172,\n        0x3b83a5f3,0x046e5e11 },\n      { 0xd8007f01,0xe7b8ff64,0x5af43183,0x7fb1ef12,0x35e1a03c,0x045c5ea6,\n        0x303d005b,0x6e0106c3 } },\n    /* 25 */\n    { { 0x88dd73b1,0x48c73584,0x995ed0d9,0x7670708f,0xc56a2ab7,0x38385ea8,\n        0xe901cf1f,0x442594ed },\n      { 0x12d4b65b,0xf8faa2c9,0x96c90c37,0x94c2343b,0x5e978d1f,0xd326e4a1,\n        0x4c2ee68e,0xa796fa51 } },\n    /* 26 */\n    { { 0x823addd7,0x359fb604,0xe56693b3,0x9e2a6183,0x3cbf3c80,0xf885b78e,\n        0xc69766e9,0xe4ad2da9 },\n      { 0x8e048a61,0x357f7f42,0xc092d9a0,0x082d198c,0xc03ed8ef,0xfc3a1af4,\n        0xc37b5143,0xc5e94046 } },\n    /* 27 */\n    { { 0x2be75f9e,0x476a538c,0xcb123a78,0x6fd1a9e8,0xb109c04b,0xd85e4df0,\n        0xdb464747,0x63283daf },\n      { 0xbaf2df15,0xce728cf7,0x0ad9a7f4,0xe592c455,0xe834bcc3,0xfab226ad,\n        0x1981a938,0x68bd19ab } },\n    /* 28 */\n    { { 0x1887d659,0xc08ead51,0xb359305a,0x3374d5f4,0xcfe74fe3,0x96986981,\n        0x3c6fdfd6,0x495292f5 },\n      { 0x1acec896,0x4a878c9e,0xec5b4484,0xd964b210,0x664d60a7,0x6696f7e2,\n        0x26036837,0x0ec7530d } },\n    /* 29 */\n    { { 0xad2687bb,0x2da13a05,0xf32e21fa,0xa1f83b6a,0x1dd4607b,0x390f5ef5,\n        0x64863f0b,0x0f6207a6 },\n      { 0x0f138233,0xbd67e3bb,0x272aa718,0xdd66b96c,0x26ec88ae,0x8ed00407,\n        0x08ed6dcf,0xff0db072 } },\n    /* 30 */\n    { { 0x4c95d553,0x749fa101,0x5d680a8a,0xa44052fd,0xff3b566f,0x183b4317,\n        0x88740ea3,0x313b513c },\n      { 0x08d11549,0xb402e2ac,0xb4dee21c,0x071ee10b,0x47f2320e,0x26b987dd,\n        0x86f19f81,0x2d3abcf9 } },\n    /* 31 */\n    { { 0x815581a2,0x4c288501,0x632211af,0x9a0a6d56,0x0cab2e99,0x19ba7a0f,\n        0xded98cdf,0xc036fa10 },\n      { 0xc1fbd009,0x29ae08ba,0x06d15816,0x0b68b190,0x9b9e0d8f,0xc2eb3277,\n        0xb6d40194,0xa6b2a2c4 } },\n    /* 32 */\n    { { 0x6d3549cf,0xd433e50f,0xfacd665e,0x6f33696f,0xce11fcb4,0x695bfdac,\n        0xaf7c9860,0x810ee252 },\n      { 0x7159bb2c,0x65450fe1,0x758b357b,0xf7dfbebe,0xd69fea72,0x2b057e74,\n        0x92731745,0xd485717a } },\n    /* 33 */\n    { { 0xf0cb5a98,0x11741a8a,0x1f3110bf,0xd3da8f93,0xab382adf,0x1994e2cb,\n        0x2f9a604e,0x6a6045a7 },\n      { 0xa2b2411d,0x170c0d3f,0x510e96e0,0xbe0eb83e,0x8865b3cc,0x3bcc9f73,\n        0xf9e15790,0xd3e45cfa } },\n    /* 34 */\n    { { 0xe83f7669,0xce1f69bb,0x72877d6b,0x09f8ae82,0x3244278d,0x9548ae54,\n        0xe3c2c19c,0x207755de },\n      { 0x6fef1945,0x87bd61d9,0xb12d28c3,0x18813cef,0x72df64aa,0x9fbcd1d6,\n        0x7154b00d,0x48dc5ee5 } },\n    /* 35 */\n    { { 0xf7e5a199,0x123790bf,0x989ccbb7,0xe0efb8cf,0x0a519c79,0xc27a2bfe,\n        0xdff6f445,0xf2fb0aed },\n      { 0xf0b5025f,0x41c09575,0x40fa9f22,0x550543d7,0x380bfbd0,0x8fa3c8ad,\n        0xdb28d525,0xa13e9015 } },\n    /* 36 */\n    { { 0xa2b65cbc,0xf9f7a350,0x2a464226,0x0b04b972,0xe23f07a1,0x265ce241,\n        0x1497526f,0x2bf0d6b0 },\n      { 0x4b216fb7,0xd3d4dd3f,0xfbdda26a,0xf7d7b867,0x6708505c,0xaeb7b83f,\n        0x162fe89f,0x42a94a5a } },\n    /* 37 */\n    { { 0xeaadf191,0x5846ad0b,0x25a268d7,0x0f8a4890,0x494dc1f6,0xe8603050,\n        0xc65ede3d,0x2c2dd969 },\n      { 0x93849c17,0x6d02171d,0x1da250dd,0x460488ba,0x3c3a5485,0x4810c706,\n        0x42c56dbc,0xf437fa1f } },\n    /* 38 */\n    { { 0x4a0f7dab,0x6aa0d714,0x1776e9ac,0x0f049793,0xf5f39786,0x52c0a050,\n        0x54707aa8,0xaaf45b33 },\n      { 0xc18d364a,0x85e37c33,0x3e497165,0xd40b9b06,0x15ec5444,0xf4171681,\n        0xf4f272bc,0xcdf6310d } },\n    /* 39 */\n    { { 0x8ea8b7ef,0x7473c623,0x85bc2287,0x08e93518,0x2bda8e34,0x41956772,\n        0xda9e2ff2,0xf0d008ba },\n      { 0x2414d3b1,0x2912671d,0xb019ea76,0xb3754985,0x453bcbdb,0x5c61b96d,\n        0xca887b8b,0x5bd5c2f5 } },\n    /* 40 */\n    { { 0xf49a3154,0xef0f469e,0x6e2b2e9a,0x3e85a595,0xaa924a9c,0x45aaec1e,\n        0xa09e4719,0xaa12dfc8 },\n      { 0x4df69f1d,0x26f27227,0xa2ff5e73,0xe0e4c82c,0xb7a9dd44,0xb9d8ce73,\n        0xe48ca901,0x6c036e73 } },\n    /* 41 */\n    { { 0x0f6e3138,0x5cfae12a,0x25ad345a,0x6966ef00,0x45672bc5,0x8993c64b,\n        0x96afbe24,0x292ff658 },\n      { 0x5e213402,0xd5250d44,0x4392c9fe,0xf6580e27,0xda1c72e8,0x097b397f,\n        0x311b7276,0x644e0c90 } },\n    /* 42 */\n    { { 0xa47153f0,0xe1e421e1,0x920418c9,0xb86c3b79,0x705d7672,0x93bdce87,\n        0xcab79a77,0xf25ae793 },\n      { 0x6d869d0c,0x1f3194a3,0x4986c264,0x9d55c882,0x096e945e,0x49fb5ea3,\n        0x13db0a3e,0x39b8e653 } },\n    /* 43 */\n    { { 0xb6fd2e59,0x37754200,0x9255c98f,0x35e2c066,0x0e2a5739,0xd9dab21a,\n        0x0f19db06,0x39122f2f },\n      { 0x03cad53c,0xcfbce1e0,0xe65c17e3,0x225b2c0f,0x9aa13877,0x72baf1d2,\n        0xce80ff8d,0x8de80af8 } },\n    /* 44 */\n    { { 0x207bbb76,0xafbea8d9,0x21782758,0x921c7e7c,0x1c0436b1,0xdfa2b74b,\n        0x2e368c04,0x87194906 },\n      { 0xa3993df5,0xb5f928bb,0xf3b3d26a,0x639d75b5,0x85b55050,0x011aa78a,\n        0x5b74fde1,0xfc315e6a } },\n    /* 45 */\n    { { 0xe8d6ecfa,0x561fd41a,0x1aec7f86,0x5f8c44f6,0x4924741d,0x98452a7b,\n        0xee389088,0xe6d4a7ad },\n      { 0x4593c75d,0x60552ed1,0xdd271162,0x70a70da4,0x7ba2c7db,0xd2aede93,\n        0x9be2ae57,0x35dfaf9a } },\n    /* 46 */\n    { { 0xaa736636,0x6b956fcd,0xae2cab7e,0x09f51d97,0x0f349966,0xfb10bf41,\n        0x1c830d2b,0x1da5c7d7 },\n      { 0x3cce6825,0x5c41e483,0xf9573c3b,0x15ad118f,0xf23036b8,0xa28552c7,\n        0xdbf4b9d6,0x7077c0fd } },\n    /* 47 */\n    { { 0x46b9661c,0xbf63ff8d,0x0d2cfd71,0xa1dfd36b,0xa847f8f7,0x0373e140,\n        0xe50efe44,0x53a8632e },\n      { 0x696d8051,0x0976ff68,0xc74f468a,0xdaec0c95,0x5e4e26bd,0x62994dc3,\n        0x34e1fcc1,0x028ca76d } },\n    /* 48 */\n    { { 0xfc9877ee,0xd11d47dc,0x801d0002,0xc8b36210,0x54c260b6,0xd002c117,\n        0x6962f046,0x04c17cd8 },\n      { 0xb0daddf5,0x6d9bd094,0x24ce55c0,0xbea23575,0x72da03b5,0x663356e6,\n        0xfed97474,0xf7ba4de9 } },\n    /* 49 */\n    { { 0xebe1263f,0xd0dbfa34,0x71ae7ce6,0x55763735,0x82a6f523,0xd2440553,\n        0x52131c41,0xe31f9600 },\n      { 0xea6b6ec6,0xd1bb9216,0x73c2fc44,0x37a1d12e,0x89d0a294,0xc10e7eac,\n        0xce34d47b,0xaa3a6259 } },\n    /* 50 */\n    { { 0x36f3dcd3,0xfbcf9df5,0xd2bf7360,0x6ceded50,0xdf504f5b,0x491710fa,\n        0x7e79daee,0x2398dd62 },\n      { 0x6d09569e,0xcf4705a3,0x5149f769,0xea0619bb,0x35f6034c,0xff9c0377,\n        0x1c046210,0x5717f5b2 } },\n    /* 51 */\n    { { 0x21dd895e,0x9fe229c9,0x40c28451,0x8e518500,0x1d637ecd,0xfa13d239,\n        0x0e3c28de,0x660a2c56 },\n      { 0xd67fcbd0,0x9cca88ae,0x0ea9f096,0xc8472478,0x72e92b4d,0x32b2f481,\n        0x4f522453,0x624ee54c } },\n    /* 52 */\n    { { 0xd897eccc,0x09549ce4,0x3f9880aa,0x4d49d1d9,0x043a7c20,0x723c2423,\n        0x92bdfbc0,0x4f392afb },\n      { 0x7de44fd9,0x6969f8fa,0x57b32156,0xb66cfbe4,0x368ebc3c,0xdb2fa803,\n        0xccdb399c,0x8a3e7977 } },\n    /* 53 */\n    { { 0x06c4b125,0xdde1881f,0xf6e3ca8c,0xae34e300,0x5c7a13e9,0xef6999de,\n        0x70c24404,0x3888d023 },\n      { 0x44f91081,0x76280356,0x5f015504,0x3d9fcf61,0x632cd36e,0x1827edc8,\n        0x18102336,0xa5e62e47 } },\n    /* 54 */\n    { { 0x2facd6c8,0x1a825ee3,0x54bcbc66,0x699c6354,0x98df9931,0x0ce3edf7,\n        0x466a5adc,0x2c4768e6 },\n      { 0x90a64bc9,0xb346ff8c,0xe4779f5c,0x630a6020,0xbc05e884,0xd949d064,\n        0xf9e652a0,0x7b5e6441 } },\n    /* 55 */\n    { { 0x1d28444a,0x2169422c,0xbe136a39,0xe996c5d8,0xfb0c7fce,0x2387afe5,\n        0x0c8d744a,0xb8af73cb },\n      { 0x338b86fd,0x5fde83aa,0xa58a5cff,0xfee3f158,0x20ac9433,0xc9ee8f6f,\n        0x7f3f0895,0xa036395f } },\n    /* 56 */\n    { { 0xa10f7770,0x8c73c6bb,0xa12a0e24,0xa6f16d81,0x51bc2b9f,0x100df682,\n        0x875fb533,0x4be36b01 },\n      { 0x9fb56dbb,0x9226086e,0x07e7a4f8,0x306fef8b,0x66d52f20,0xeeaccc05,\n        0x1bdc00c0,0x8cbc9a87 } },\n    /* 57 */\n    { { 0xc0dac4ab,0xe131895c,0x712ff112,0xa874a440,0x6a1cee57,0x6332ae7c,\n        0x0c0835f8,0x44e7553e },\n      { 0x7734002d,0x6d503fff,0x0b34425c,0x9d35cb8b,0x0e8738b5,0x95f70276,\n        0x5eb8fc18,0x470a683a } },\n    /* 58 */\n    { { 0x90513482,0x81b761dc,0x01e9276a,0x0287202a,0x0ce73083,0xcda441ee,\n        0xc63dc6ef,0x16410690 },\n      { 0x6d06a2ed,0xf5034a06,0x189b100b,0xdd4d7745,0xab8218c9,0xd914ae72,\n        0x7abcbb4f,0xd73479fd } },\n    /* 59 */\n    { { 0x5ad4c6e5,0x7edefb16,0x5b06d04d,0x262cf08f,0x8575cb14,0x12ed5bb1,\n        0x0771666b,0x816469e3 },\n      { 0x561e291e,0xd7ab9d79,0xc1de1661,0xeb9daf22,0x135e0513,0xf49827eb,\n        0xf0dd3f9c,0x0a36dd23 } },\n    /* 60 */\n    { { 0x41d5533c,0x098d32c7,0x8684628f,0x7c5f5a9e,0xe349bd11,0x39a228ad,\n        0xfdbab118,0xe331dfd6 },\n      { 0x6bcc6ed8,0x5100ab68,0xef7a260e,0x7160c3bd,0xbce850d7,0x9063d9a7,\n        0x492e3389,0xd3b4782a } },\n    /* 61 */\n    { { 0xf3821f90,0xa149b6e8,0x66eb7aad,0x92edd9ed,0x1a013116,0x0bb66953,\n        0x4c86a5bd,0x7281275a },\n      { 0xd3ff47e5,0x503858f7,0x61016441,0x5e1616bc,0x7dfd9bb1,0x62b0f11a,\n        0xce145059,0x2c062e7e } },\n    /* 62 */\n    { { 0x0159ac2e,0xa76f996f,0xcbdb2713,0x281e7736,0x08e46047,0x2ad6d288,\n        0x2c4e7ef1,0x282a35f9 },\n      { 0xc0ce5cd2,0x9c354b1e,0x1379c229,0xcf99efc9,0x3e82c11e,0x992caf38,\n        0x554d2abd,0xc71cd513 } },\n    /* 63 */\n    { { 0x09b578f4,0x4885de9c,0xe3affa7a,0x1884e258,0x59182f1f,0x8f76b1b7,\n        0xcf47f3a3,0xc50f6740 },\n      { 0x374b68ea,0xa9c4adf3,0x69965fe2,0xa406f323,0x85a53050,0x2f86a222,\n        0x212958dc,0xb9ecb3a7 } },\n    /* 64 */\n    { { 0xf4f8b16a,0x56f8410e,0xc47b266a,0x97241afe,0x6d9c87c1,0x0a406b8e,\n        0xcd42ab1b,0x803f3e02 },\n      { 0x04dbec69,0x7f0309a8,0x3bbad05f,0xa83b85f7,0xad8e197f,0xc6097273,\n        0x5067adc1,0xc097440e } },\n    /* 65 */\n    { { 0xc379ab34,0x846a56f2,0x841df8d1,0xa8ee068b,0x176c68ef,0x20314459,\n        0x915f1f30,0xf1af32d5 },\n      { 0x5d75bd50,0x99c37531,0xf72f67bc,0x837cffba,0x48d7723f,0x0613a418,\n        0xe2d41c8b,0x23d0f130 } },\n    /* 66 */\n    { { 0xf41500d9,0x857ab6ed,0xfcbeada8,0x0d890ae5,0x89725951,0x52fe8648,\n        0xc0a3fadd,0xb0288dd6 },\n      { 0x650bcb08,0x85320f30,0x695d6e16,0x71af6313,0xb989aa76,0x31f520a7,\n        0xf408c8d2,0xffd3724f } },\n    /* 67 */\n    { { 0xb458e6cb,0x53968e64,0x317a5d28,0x992dad20,0x7aa75f56,0x3814ae0b,\n        0xd78c26df,0xf5590f4a },\n      { 0xcf0ba55a,0x0fc24bd3,0x0c778bae,0x0fc4724a,0x683b674a,0x1ce9864f,\n        0xf6f74a20,0x18d6da54 } },\n    /* 68 */\n    { { 0xd5be5a2b,0xed93e225,0x5934f3c6,0x6fe79983,0x22626ffc,0x43140926,\n        0x7990216a,0x50bbb4d9 },\n      { 0xe57ec63e,0x378191c6,0x181dcdb2,0x65422c40,0x0236e0f6,0x41a8099b,\n        0x01fe49c3,0x2b100118 } },\n    /* 69 */\n    { { 0x9b391593,0xfc68b5c5,0x598270fc,0xc385f5a2,0xd19adcbb,0x7144f3aa,\n        0x83fbae0c,0xdd558999 },\n      { 0x74b82ff4,0x93b88b8e,0x71e734c9,0xd2e03c40,0x43c0322a,0x9a7a9eaf,\n        0x149d6041,0xe6e4c551 } },\n    /* 70 */\n    { { 0x1e9af288,0x55f655bb,0xf7ada931,0x647e1a64,0xcb2820e5,0x43697e4b,\n        0x07ed56ff,0x51e00db1 },\n      { 0x771c327e,0x43d169b8,0x4a96c2ad,0x29cdb20b,0x3deb4779,0xc07d51f5,\n        0x49829177,0xe22f4241 } },\n    /* 71 */\n    { { 0x635f1abb,0xcd45e8f4,0x68538874,0x7edc0cb5,0xb5a8034d,0xc9472c1f,\n        0x52dc48c9,0xf709373d },\n      { 0xa8af30d6,0x401966bb,0xf137b69c,0x95bf5f4a,0x9361c47e,0x3966162a,\n        0xe7275b11,0xbd52d288 } },\n    /* 72 */\n    { { 0x9c5fa877,0xab155c7a,0x7d3a3d48,0x17dad672,0x73d189d8,0x43f43f9e,\n        0xc8aa77a6,0xa0d0f8e4 },\n      { 0xcc94f92d,0x0bbeafd8,0x0c4ddb3a,0xd818c8be,0xb82eba14,0x22cc65f8,\n        0x946d6a00,0xa56c78c7 } },\n    /* 73 */\n    { { 0x0dd09529,0x2962391b,0x3daddfcf,0x803e0ea6,0x5b5bf481,0x2c77351f,\n        0x731a367a,0xd8befdf8 },\n      { 0xfc0157f4,0xab919d42,0xfec8e650,0xf51caed7,0x02d48b0a,0xcdf9cb40,\n        0xce9f6478,0x854a68a5 } },\n    /* 74 */\n    { { 0x63506ea5,0xdc35f67b,0xa4fe0d66,0x9286c489,0xfe95cd4d,0x3f101d3b,\n        0x98846a95,0x5cacea0b },\n      { 0x9ceac44d,0xa90df60c,0x354d1c3a,0x3db29af4,0xad5dbabe,0x08dd3de8,\n        0x35e4efa9,0xe4982d12 } },\n    /* 75 */\n    { { 0xc34cd55e,0x23104a22,0x2680d132,0x58695bb3,0x1fa1d943,0xfb345afa,\n        0x16b20499,0x8046b7f6 },\n      { 0x38e7d098,0xb533581e,0xf46f0b70,0xd7f61e8d,0x44cb78c4,0x30dea9ea,\n        0x9082af55,0xeb17ca7b } },\n    /* 76 */\n    { { 0x76a145b9,0x1751b598,0xc1bc71ec,0xa5cf6b0f,0x392715bb,0xd3e03565,\n        0xfab5e131,0x097b00ba },\n      { 0x565f69e1,0xaa66c8e9,0xb5be5199,0x77e8f75a,0xda4fd984,0x6033ba11,\n        0xafdbcc9e,0xf95c747b } },\n    /* 77 */\n    { { 0xbebae45e,0x558f01d3,0xc4bc6955,0xa8ebe9f0,0xdbc64fc6,0xaeb705b1,\n        0x566ed837,0x3512601e },\n      { 0xfa1161cd,0x9336f1e1,0x4c65ef87,0x328ab8d5,0x724f21e5,0x4757eee2,\n        0x6068ab6b,0x0ef97123 } },\n    /* 78 */\n    { { 0x54ca4226,0x02598cf7,0xf8642c8e,0x5eede138,0x468e1790,0x48963f74,\n        0x3b4fbc95,0xfc16d933 },\n      { 0xe7c800ca,0xbe96fb31,0x2678adaa,0x13806331,0x6ff3e8b5,0x3d624497,\n        0xb95d7a17,0x14ca4af1 } },\n    /* 79 */\n    { { 0xbd2f81d5,0x7a4771ba,0x01f7d196,0x1a5f9d69,0xcad9c907,0xd898bef7,\n        0xf59c231d,0x4057b063 },\n      { 0x89c05c0a,0xbffd82fe,0x1dc0df85,0xe4911c6f,0xa35a16db,0x3befccae,\n        0xf1330b13,0x1c3b5d64 } },\n    /* 80 */\n    { { 0x80ec21fe,0x5fe14bfe,0xc255be82,0xf6ce116a,0x2f4a5d67,0x98bc5a07,\n        0xdb7e63af,0xfad27148 },\n      { 0x29ab05b3,0x90c0b6ac,0x4e251ae6,0x37a9a83c,0xc2aade7d,0x0a7dc875,\n        0x9f0e1a84,0x77387de3 } },\n    /* 81 */\n    { { 0xa56c0dd7,0x1e9ecc49,0x46086c74,0xa5cffcd8,0xf505aece,0x8f7a1408,\n        0xbef0c47e,0xb37b85c0 },\n      { 0xcc0e6a8f,0x3596b6e4,0x6b388f23,0xfd6d4bbf,0xc39cef4e,0xaba453fa,\n        0xf9f628d5,0x9c135ac8 } },\n    /* 82 */\n    { { 0x84e35743,0x32aa3202,0x85a3cdef,0x320d6ab1,0x1df19819,0xb821b176,\n        0xc433851f,0x5721361f },\n      { 0x71fc9168,0x1f0db36a,0x5e5c403c,0x5f98ba73,0x37bcd8f5,0xf64ca87e,\n        0xe6bb11bd,0xdcbac3c9 } },\n    /* 83 */\n    { { 0x4518cbe2,0xf01d9968,0x9c9eb04e,0xd242fc18,0xe47feebf,0x727663c7,\n        0x2d626862,0xb8c1c89e },\n      { 0xc8e1d569,0x51a58bdd,0xb7d88cd0,0x563809c8,0xf11f31eb,0x26c27fd9,\n        0x2f9422d4,0x5d23bbda } },\n    /* 84 */\n    { { 0x95c8f8be,0x0a1c7294,0x3bf362bf,0x2961c480,0xdf63d4ac,0x9e418403,\n        0x91ece900,0xc109f9cb },\n      { 0x58945705,0xc2d095d0,0xddeb85c0,0xb9083d96,0x7a40449b,0x84692b8d,\n        0x2eee1ee1,0x9bc3344f } },\n    /* 85 */\n    { { 0x42913074,0x0d5ae356,0x48a542b1,0x55491b27,0xb310732a,0x469ca665,\n        0x5f1a4cc1,0x29591d52 },\n      { 0xb84f983f,0xe76f5b6b,0x9f5f84e1,0xbe7eef41,0x80baa189,0x1200d496,\n        0x18ef332c,0x6376551f } },\n    /* 86 */\n    { { 0x562976cc,0xbda5f14e,0x0ef12c38,0x22bca3e6,0x6cca9852,0xbbfa3064,\n        0x08e2987a,0xbdb79dc8 },\n      { 0xcb06a772,0xfd2cb5c9,0xfe536dce,0x38f475aa,0x7c2b5db8,0xc2a3e022,\n        0xadd3c14a,0x8ee86001 } },\n    /* 87 */\n    { { 0xa4ade873,0xcbe96981,0xc4fba48c,0x7ee9aa4d,0x5a054ba5,0x2cee2899,\n        0x6f77aa4b,0x92e51d7a },\n      { 0x7190a34d,0x948bafa8,0xf6bd1ed1,0xd698f75b,0x0caf1144,0xd00ee6e3,\n        0x0a56aaaa,0x5182f86f } },\n    /* 88 */\n    { { 0x7a4cc99c,0xfba6212c,0x3e6d9ca1,0xff609b68,0x5ac98c5a,0x5dbb27cb,\n        0x4073a6f2,0x91dcab5d },\n      { 0x5f575a70,0x01b6cc3d,0x6f8d87fa,0x0cb36139,0x89981736,0x165d4e8c,\n        0x97974f2b,0x17a0cedb } },\n    /* 89 */\n    { { 0x076c8d3a,0x38861e2a,0x210f924b,0x701aad39,0x13a835d9,0x94d0eae4,\n        0x7f4cdf41,0x2e8ce36c },\n      { 0x037a862b,0x91273dab,0x60e4c8fa,0x01ba9bb7,0x33baf2dd,0xf9645388,\n        0x34f668f3,0xf4ccc6cb } },\n    /* 90 */\n    { { 0xf1f79687,0x44ef525c,0x92efa815,0x7c595495,0xa5c78d29,0xe1231741,\n        0x9a0df3c9,0xac0db488 },\n      { 0xdf01747f,0x86bfc711,0xef17df13,0x592b9358,0x5ccb6bb5,0xe5880e4f,\n        0x94c974a2,0x95a64a61 } },\n    /* 91 */\n    { { 0xc15a4c93,0x72c1efda,0x82585141,0x40269b73,0x16cb0bad,0x6a8dfb1c,\n        0x29210677,0x231e54ba },\n      { 0x8ae6d2dc,0xa70df917,0x39112918,0x4d6aa63f,0x5e5b7223,0xf627726b,\n        0xd8a731e1,0xab0be032 } },\n    /* 92 */\n    { { 0x8d131f2d,0x097ad0e9,0x3b04f101,0x637f09e3,0xd5e9a748,0x1ac86196,\n        0x2cf6a679,0xf1bcc880 },\n      { 0xe8daacb4,0x25c69140,0x60f65009,0x3c4e4055,0x477937a6,0x591cc8fc,\n        0x5aebb271,0x85169469 } },\n    /* 93 */\n    { { 0xf1dcf593,0xde35c143,0xb018be3b,0x78202b29,0x9bdd9d3d,0xe9cdadc2,\n        0xdaad55d8,0x8f67d9d2 },\n      { 0x7481ea5f,0x84111656,0xe34c590c,0xe7d2dde9,0x05053fa8,0xffdd43f4,\n        0xc0728b5d,0xf84572b9 } },\n    /* 94 */\n    { { 0x97af71c9,0x5e1a7a71,0x7a736565,0xa1449444,0x0e1d5063,0xa1b4ae07,\n        0x616b2c19,0xedee2710 },\n      { 0x11734121,0xb2f034f5,0x4a25e9f0,0x1cac6e55,0xa40c2ecf,0x8dc148f3,\n        0x44ebd7f4,0x9fd27e9b } },\n    /* 95 */\n    { { 0xf6e2cb16,0x3cc7658a,0xfe5919b6,0xe3eb7d2c,0x168d5583,0x5a8c5816,\n        0x958ff387,0xa40c2fb6 },\n      { 0xfedcc158,0x8c9ec560,0x55f23056,0x7ad804c6,0x9a307e12,0xd9396704,\n        0x7dc6decf,0x99bc9bb8 } },\n    /* 96 */\n    { { 0x927dafc6,0x84a9521d,0x5c09cd19,0x52c1fb69,0xf9366dde,0x9d9581a0,\n        0xa16d7e64,0x9abe210b },\n      { 0x48915220,0x480af84a,0x4dd816c6,0xfa73176a,0x1681ca5a,0xc7d53987,\n        0x87f344b0,0x7881c257 } },\n    /* 97 */\n    { { 0xe0bcf3ff,0x93399b51,0x127f74f6,0x0d02cbc5,0xdd01d968,0x8fb465a2,\n        0xa30e8940,0x15e6e319 },\n      { 0x3e0e05f4,0x646d6e0d,0x43588404,0xfad7bddc,0xc4f850d3,0xbe61c7d1,\n        0x191172ce,0x0e55facf } },\n    /* 98 */\n    { { 0xf8787564,0x7e9d9806,0x31e85ce6,0x1a331721,0xb819e8d6,0x6b0158ca,\n        0x6fe96577,0xd73d0976 },\n      { 0x1eb7206e,0x42483425,0xc618bb42,0xa519290f,0x5e30a520,0x5dcbb859,\n        0x8f15a50b,0x9250a374 } },\n    /* 99 */\n    { { 0xbe577410,0xcaff08f8,0x5077a8c6,0xfd408a03,0xec0a63a4,0xf1f63289,\n        0xc1cc8c0b,0x77414082 },\n      { 0xeb0991cd,0x05a40fa6,0x49fdc296,0xc1ca0866,0xb324fd40,0x3a68a3c7,\n        0x12eb20b9,0x8cb04f4d } },\n    /* 100 */\n    { { 0x6906171c,0xb1c2d055,0xb0240c3f,0x9073e9cd,0xd8906841,0xdb8e6b4f,\n        0x47123b51,0xe4e429ef },\n      { 0x38ec36f4,0x0b8dd53c,0xff4b6a27,0xf9d2dc01,0x879a9a48,0x5d066e07,\n        0x3c6e6552,0x37bca2ff } },\n    /* 101 */\n    { { 0xdf562470,0x4cd2e3c7,0xc0964ac9,0x44f272a2,0x80c793be,0x7c6d5df9,\n        0x3002b22a,0x59913edc },\n      { 0x5750592a,0x7a139a83,0xe783de02,0x99e01d80,0xea05d64f,0xcf8c0375,\n        0xb013e226,0x43786e4a } },\n    /* 102 */\n    { { 0x9e56b5a6,0xff32b0ed,0xd9fc68f9,0x0750d9a6,0x597846a7,0xec15e845,\n        0xb7e79e7a,0x8638ca98 },\n      { 0x0afc24b2,0x2f5ae096,0x4dace8f2,0x05398eaf,0xaecba78f,0x3b765dd0,\n        0x7b3aa6f0,0x1ecdd36a } },\n    /* 103 */\n    { { 0x6c5ff2f3,0x5d3acd62,0x2873a978,0xa2d516c0,0xd2110d54,0xad94c9fa,\n        0xd459f32d,0xd85d0f85 },\n      { 0x10b11da3,0x9f700b8d,0xa78318c4,0xd2c22c30,0x9208decd,0x556988f4,\n        0xb4ed3c62,0xa04f19c3 } },\n    /* 104 */\n    { { 0xed7f93bd,0x087924c8,0x392f51f6,0xcb64ac5d,0x821b71af,0x7cae330a,\n        0x5c0950b0,0x92b2eeea },\n      { 0x85b6e235,0x85ac4c94,0x2936c0f0,0xab2ca4a9,0xe0508891,0x80faa6b3,\n        0x5834276c,0x1ee78221 } },\n    /* 105 */\n    { { 0xe63e79f7,0xa60a2e00,0xf399d906,0xf590e7b2,0x6607c09d,0x9021054a,\n        0x57a6e150,0xf3f2ced8 },\n      { 0xf10d9b55,0x200510f3,0xd8642648,0x9d2fcfac,0xe8bd0e7c,0xe5631aa7,\n        0x3da3e210,0x0f56a454 } },\n    /* 106 */\n    { { 0x1043e0df,0x5b21bffa,0x9c007e6d,0x6c74b6cc,0xd4a8517a,0x1a656ec0,\n        0x1969e263,0xbd8f1741 },\n      { 0xbeb7494a,0x8a9bbb86,0x45f3b838,0x1567d46f,0xa4e5a79a,0xdf7a12a7,\n        0x30ccfa09,0x2d1a1c35 } },\n    /* 107 */\n    { { 0x506508da,0x192e3813,0xa1d795a7,0x336180c4,0x7a9944b3,0xcddb5949,\n        0xb91fba46,0xa107a65e },\n      { 0x0f94d639,0xe6d1d1c5,0x8a58b7d7,0x8b4af375,0xbd37ca1c,0x1a7c5584,\n        0xf87a9af2,0x183d760a } },\n    /* 108 */\n    { { 0x0dde59a4,0x29d69711,0x0e8bef87,0xf1ad8d07,0x4f2ebe78,0x229b4963,\n        0xc269d754,0x1d44179d },\n      { 0x8390d30e,0xb32dc0cf,0x0de8110c,0x0a3b2753,0x2bc0339a,0x31af1dc5,\n        0x9606d262,0x771f9cc2 } },\n    /* 109 */\n    { { 0x85040739,0x99993e77,0x8026a939,0x44539db9,0xf5f8fc26,0xcf40f6f2,\n        0x0362718e,0x64427a31 },\n      { 0x85428aa8,0x4f4f2d87,0xebfb49a8,0x7b7adc3f,0xf23d01ac,0x201b2c6d,\n        0x6ae90d6d,0x49d9b749 } },\n    /* 110 */\n    { { 0x435d1099,0xcc78d8bc,0x8e8d1a08,0x2adbcd4e,0x2cb68a41,0x02c2e2a0,\n        0x3f605445,0x9037d81b },\n      { 0x074c7b61,0x7cdbac27,0x57bfd72e,0xfe2031ab,0x596d5352,0x61ccec96,\n        0x7cc0639c,0x08c3de6a } },\n    /* 111 */\n    { { 0xf6d552ab,0x20fdd020,0x05cd81f1,0x56baff98,0x91351291,0x06fb7c3e,\n        0x45796b2f,0xc6909442 },\n      { 0x41231bd1,0x17b3ae9c,0x5cc58205,0x1eac6e87,0xf9d6a122,0x208837ab,\n        0xcafe3ac0,0x3fa3db02 } },\n    /* 112 */\n    { { 0x05058880,0xd75a3e65,0x643943f2,0x7da365ef,0xfab24925,0x4147861c,\n        0xfdb808ff,0xc5c4bdb0 },\n      { 0xb272b56b,0x73513e34,0x11b9043a,0xc8327e95,0xf8844969,0xfd8ce37d,\n        0x46c2b6b5,0x2d56db94 } },\n    /* 113 */\n    { { 0xff46ac6b,0x2461782f,0x07a2e425,0xd19f7926,0x09a48de1,0xfafea3c4,\n        0xe503ba42,0x0f56bd9d },\n      { 0x345cda49,0x137d4ed1,0x816f299d,0x821158fc,0xaeb43402,0xe7c6a54a,\n        0x1173b5f1,0x4003bb9d } },\n    /* 114 */\n    { { 0xa0803387,0x3b8e8189,0x39cbd404,0xece115f5,0xd2877f21,0x4297208d,\n        0xa07f2f9e,0x53765522 },\n      { 0xa8a4182d,0xa4980a21,0x3219df79,0xa2bbd07a,0x1a19a2d4,0x674d0a2e,\n        0x6c5d4549,0x7a056f58 } },\n    /* 115 */\n    { { 0x9d8a2a47,0x646b2558,0xc3df2773,0x5b582948,0xabf0d539,0x51ec000e,\n        0x7a1a2675,0x77d482f1 },\n      { 0x87853948,0xb8a1bd95,0x6cfbffee,0xa6f817bd,0x80681e47,0xab6ec057,\n        0x2b38b0e4,0x4115012b } },\n    /* 116 */\n    { { 0x6de28ced,0x3c73f0f4,0x9b13ec47,0x1d5da760,0x6e5c6392,0x61b8ce9e,\n        0xfbea0946,0xcdf04572 },\n      { 0x6c53c3b0,0x1cb3c58b,0x447b843c,0x97fe3c10,0x2cb9780e,0xfb2b8ae1,\n        0x97383109,0xee703dda } },\n    /* 117 */\n    { { 0xff57e43a,0x34515140,0xb1b811b8,0xd44660d3,0x8f42b986,0x2b3b5dff,\n        0xa162ce21,0x2a0ad89d },\n      { 0x6bc277ba,0x64e4a694,0xc141c276,0xc788c954,0xcabf6274,0x141aa64c,\n        0xac2b4659,0xd62d0b67 } },\n    /* 118 */\n    { { 0x2c054ac4,0x39c5d87b,0xf27df788,0x57005859,0xb18128d6,0xedf7cbf3,\n        0x991c2426,0xb39a23f2 },\n      { 0xf0b16ae5,0x95284a15,0xa136f51b,0x0c6a05b1,0xf2700783,0x1d63c137,\n        0xc0674cc5,0x04ed0092 } },\n    /* 119 */\n    { { 0x9ae90393,0x1f4185d1,0x4a3d64e6,0x3047b429,0x9854fc14,0xae0001a6,\n        0x0177c387,0xa0a91fc1 },\n      { 0xae2c831e,0xff0a3f01,0x2b727e16,0xbb76ae82,0x5a3075b4,0x8f12c8a1,\n        0x9ed20c41,0x084cf988 } },\n    /* 120 */\n    { { 0xfca6becf,0xd98509de,0x7dffb328,0x2fceae80,0x4778e8b9,0x5d8a15c4,\n        0x73abf77e,0xd57955b2 },\n      { 0x31b5d4f1,0x210da79e,0x3cfa7a1c,0xaa52f04b,0xdc27c20b,0xd4d12089,\n        0x02d141f1,0x8e14ea42 } },\n    /* 121 */\n    { { 0xf2897042,0xeed50345,0x43402c4a,0x8d05331f,0xc8bdfb21,0xc8d9c194,\n        0x2aa4d158,0x597e1a37 },\n      { 0xcf0bd68c,0x0327ec1a,0xab024945,0x6d4be0dc,0xc9fe3e84,0x5b9c8d7a,\n        0x199b4dea,0xca3f0236 } },\n    /* 122 */\n    { { 0x6170bd20,0x592a10b5,0x6d3f5de7,0x0ea897f1,0x44b2ade2,0xa3363ff1,\n        0x309c07e4,0xbde7fd7e },\n      { 0xb8f5432c,0x516bb6d2,0xe043444b,0x210dc1cb,0xf8f95b5a,0x3db01e6f,\n        0x0a7dd198,0xb623ad0e } },\n    /* 123 */\n    { { 0x60c7b65b,0xa75bd675,0x23a4a289,0xab8c5590,0xd7b26795,0xf8220fd0,\n        0x58ec137b,0xd6aa2e46 },\n      { 0x5138bb85,0x10abc00b,0xd833a95c,0x8c31d121,0x1702a32e,0xb24ff00b,\n        0x2dcc513a,0x111662e0 } },\n    /* 124 */\n    { { 0xefb42b87,0x78114015,0x1b6c4dff,0xbd9f5d70,0xa7d7c129,0x66ecccd7,\n        0x94b750f8,0xdb3ee1cb },\n      { 0xf34837cf,0xb26f3db0,0xb9578d4f,0xe7eed18b,0x7c56657d,0x5d2cdf93,\n        0x52206a59,0x886a6442 } },\n    /* 125 */\n    { { 0x65b569ea,0x3c234cfb,0xf72119c1,0x20011141,0xa15a619e,0x8badc85d,\n        0x018a17bc,0xa70cf4eb },\n      { 0x8c4a6a65,0x224f97ae,0x0134378f,0x36e5cf27,0x4f7e0960,0xbe3a609e,\n        0xd1747b77,0xaa4772ab } },\n    /* 126 */\n    { { 0x7aa60cc0,0x67676131,0x0368115f,0xc7916361,0xbbc1bb5a,0xded98bb4,\n        0x30faf974,0x611a6ddc },\n      { 0xc15ee47a,0x30e78cbc,0x4e0d96a5,0x2e896282,0x3dd9ed88,0x36f35adf,\n        0x16429c88,0x5cfffaf8 } },\n    /* 127 */\n    { { 0x9b7a99cd,0xc0d54cff,0x843c45a1,0x7bf3b99d,0x62c739e1,0x038a908f,\n        0x7dc1994c,0x6e5a6b23 },\n      { 0x0ba5db77,0xef8b454e,0xacf60d63,0xb7b8807f,0x76608378,0xe591c0c6,\n        0x242dabcc,0x481a238d } },\n    /* 128 */\n    { { 0x35d0b34a,0xe3417bc0,0x8327c0a7,0x440b386b,0xac0362d1,0x8fb7262d,\n        0xe0cdf943,0x2c41114c },\n      { 0xad95a0b1,0x2ba5cef1,0x67d54362,0xc09b37a8,0x01e486c9,0x26d6cdd2,\n        0x42ff9297,0x20477abf } },\n    /* 129 */\n    { { 0x18d65dbf,0x2f75173c,0x339edad8,0x77bf940e,0xdcf1001c,0x7022d26b,\n        0xc77396b6,0xac66409a },\n      { 0xc6261cc3,0x8b0bb36f,0x190e7e90,0x213f7bc9,0xa45e6c10,0x6541ceba,\n        0xcc122f85,0xce8e6975 } },\n    /* 130 */\n    { { 0xbc0a67d2,0x0f121b41,0x444d248a,0x62d4760a,0x659b4737,0x0e044f1d,\n        0x250bb4a8,0x08fde365 },\n      { 0x848bf287,0xaceec3da,0xd3369d6e,0xc2a62182,0x92449482,0x3582dfdc,\n        0x565d6cd7,0x2f7e2fd2 } },\n    /* 131 */\n    { { 0xc3770fa7,0xae4b92db,0x379043f9,0x095e8d5c,0x17761171,0x54f34e9d,\n        0x907702ae,0xc65be92e },\n      { 0xf6fd0a40,0x2758a303,0xbcce784b,0xe7d822e3,0x4f9767bf,0x7ae4f585,\n        0xd1193b3a,0x4bff8e47 } },\n    /* 132 */\n    { { 0x00ff1480,0xcd41d21f,0x0754db16,0x2ab8fb7d,0xbbe0f3ea,0xac81d2ef,\n        0x5772967d,0x3e4e4ae6 },\n      { 0x3c5303e6,0x7e18f36d,0x92262397,0x3bd9994b,0x1324c3c0,0x9ed70e26,\n        0x58ec6028,0x5388aefd } },\n    /* 133 */\n    { { 0x5e5d7713,0xad1317eb,0x75de49da,0x09b985ee,0xc74fb261,0x32f5bc4f,\n        0x4f75be0e,0x5cf908d1 },\n      { 0x8e657b12,0x76043510,0xb96ed9e6,0xbfd421a5,0x8970ccc2,0x0e29f51f,\n        0x60f00ce2,0xa698ba40 } },\n    /* 134 */\n    { { 0xef748fec,0x73db1686,0x7e9d2cf9,0xe6e755a2,0xce265eff,0x630b6544,\n        0x7aebad8d,0xb142ef8a },\n      { 0x17d5770a,0xad31af9f,0x2cb3412f,0x66af3b67,0xdf3359de,0x6bd60d1b,\n        0x58515075,0xd1896a96 } },\n    /* 135 */\n    { { 0x33c41c08,0xec5957ab,0x5468e2e1,0x87de94ac,0xac472f6c,0x18816b73,\n        0x7981da39,0x267b0e0b },\n      { 0x8e62b988,0x6e554e5d,0x116d21e7,0xd8ddc755,0x3d2a6f99,0x4610faf0,\n        0xa1119393,0xb54e287a } },\n    /* 136 */\n    { { 0x178a876b,0x0a0122b5,0x085104b4,0x51ff96ff,0x14f29f76,0x050b31ab,\n        0x5f87d4e6,0x84abb28b },\n      { 0x8270790a,0xd5ed439f,0x85e3f46b,0x2d6cb59d,0x6c1e2212,0x75f55c1b,\n        0x17655640,0xe5436f67 } },\n    /* 137 */\n    { { 0x2286e8d5,0x53f9025e,0x864453be,0x353c95b4,0xe408e3a0,0xd832f5bd,\n        0x5b9ce99e,0x0404f68b },\n      { 0xa781e8e5,0xcad33bde,0x163c2f5b,0x3cdf5018,0x0119caa3,0x57576960,\n        0x0ac1c701,0x3a4263df } },\n    /* 138 */\n    { { 0x9aeb596d,0xc2965ecc,0x023c92b4,0x01ea03e7,0x2e013961,0x4704b4b6,\n        0x905ea367,0x0ca8fd3f },\n      { 0x551b2b61,0x92523a42,0x390fcd06,0x1eb7a89c,0x0392a63e,0xe7f1d2be,\n        0x4ddb0c33,0x96dca264 } },\n    /* 139 */\n    { { 0x387510af,0x203bb43a,0xa9a36a01,0x846feaa8,0x2f950378,0xd23a5770,\n        0x3aad59dc,0x4363e212 },\n      { 0x40246a47,0xca43a1c7,0xe55dd24d,0xb362b8d2,0x5d8faf96,0xf9b08604,\n        0xd8bb98c4,0x840e115c } },\n    /* 140 */\n    { { 0x1023e8a7,0xf12205e2,0xd8dc7a0b,0xc808a8cd,0x163a5ddf,0xe292a272,\n        0x30ded6d4,0x5e0d6abd },\n      { 0x7cfc0f64,0x07a721c2,0x0e55ed88,0x42eec01d,0x1d1f9db2,0x26a7bef9,\n        0x2945a25a,0x7dea48f4 } },\n    /* 141 */\n    { { 0xe5060a81,0xabdf6f1c,0xf8f95615,0xe79f9c72,0x06ac268b,0xcfd36c54,\n        0xebfd16d1,0xabc2a2be },\n      { 0xd3e2eac7,0x8ac66f91,0xd2dd0466,0x6f10ba63,0x0282d31b,0x6790e377,\n        0x6c7eefc1,0x4ea35394 } },\n    /* 142 */\n    { { 0x5266309d,0xed8a2f8d,0x81945a3e,0x0a51c6c0,0x578c5dc1,0xcecaf45a,\n        0x1c94ffc3,0x3a76e689 },\n      { 0x7d7b0d0f,0x9aace8a4,0x8f584a5f,0x963ace96,0x4e697fbe,0x51a30c72,\n        0x465e6464,0x8212a10a } },\n    /* 143 */\n    { { 0xcfab8caa,0xef7c61c3,0x0e142390,0x18eb8e84,0x7e9733ca,0xcd1dff67,\n        0x599cb164,0xaa7cab71 },\n      { 0xbc837bd1,0x02fc9273,0xc36af5d7,0xc06407d0,0xf423da49,0x17621292,\n        0xfe0617c3,0x40e38073 } },\n    /* 144 */\n    { { 0xa7bf9b7c,0xf4f80824,0x3fbe30d0,0x365d2320,0x97cf9ce3,0xbfbe5320,\n        0xb3055526,0xe3604700 },\n      { 0x6cc6c2c7,0x4dcb9911,0xba4cbee6,0x72683708,0x637ad9ec,0xdcded434,\n        0xa3dee15f,0x6542d677 } },\n    /* 145 */\n    { { 0x7b6c377a,0x3f32b6d0,0x903448be,0x6cb03847,0x20da8af7,0xd6fdd3a8,\n        0x09bb6f21,0xa6534aee },\n      { 0x1035facf,0x30a1780d,0x9dcb47e6,0x35e55a33,0xc447f393,0x6ea50fe1,\n        0xdc9aef22,0xf3cb672f } },\n    /* 146 */\n    { { 0x3b55fd83,0xeb3719fe,0x875ddd10,0xe0d7a46c,0x05cea784,0x33ac9fa9,\n        0xaae870e7,0x7cafaa2e },\n      { 0x1d53b338,0x9b814d04,0xef87e6c6,0xe0acc0a0,0x11672b0f,0xfb93d108,\n        0xb9bd522e,0x0aab13c1 } },\n    /* 147 */\n    { { 0xd2681297,0xddcce278,0xb509546a,0xcb350eb1,0x7661aaf2,0x2dc43173,\n        0x847012e9,0x4b91a602 },\n      { 0x72f8ddcf,0xdcff1095,0x9a911af4,0x08ebf61e,0xc372430e,0x48f4360a,\n        0x72321cab,0x49534c53 } },\n    /* 148 */\n    { { 0xf07b7e9d,0x83df7d71,0x13cd516f,0xa478efa3,0x6c047ee3,0x78ef264b,\n        0xd65ac5ee,0xcaf46c4f },\n      { 0x92aa8266,0xa04d0c77,0x913684bb,0xedf45466,0xae4b16b0,0x56e65168,\n        0x04c6770f,0x14ce9e57 } },\n    /* 149 */\n    { { 0x965e8f91,0x99445e3e,0xcb0f2492,0xd3aca1ba,0x90c8a0a0,0xd31cc70f,\n        0x3e4c9a71,0x1bb708a5 },\n      { 0x558bdd7a,0xd5ca9e69,0x018a26b1,0x734a0508,0x4c9cf1ec,0xb093aa71,\n        0xda300102,0xf9d126f2 } },\n    /* 150 */\n    { { 0xaff9563e,0x749bca7a,0xb49914a0,0xdd077afe,0xbf5f1671,0xe27a0311,\n        0x729ecc69,0x807afcb9 },\n      { 0xc9b08b77,0x7f8a9337,0x443c7e38,0x86c3a785,0x476fd8ba,0x85fafa59,\n        0x6568cd8c,0x751adcd1 } },\n    /* 151 */\n    { { 0x10715c0d,0x8aea38b4,0x8f7697f7,0xd113ea71,0x93fbf06d,0x665eab14,\n        0x2537743f,0x29ec4468 },\n      { 0xb50bebbc,0x3d94719c,0xe4505422,0x399ee5bf,0x8d2dedb1,0x90cd5b3a,\n        0x92a4077d,0xff9370e3 } },\n    /* 152 */\n    { { 0xc6b75b65,0x59a2d69b,0x266651c5,0x4188f8d5,0x3de9d7d2,0x28a9f33e,\n        0xa2a9d01a,0x9776478b },\n      { 0x929af2c7,0x8852622d,0x4e690923,0x334f5d6d,0xa89a51e9,0xce6cc7e5,\n        0xac2f82fa,0x74a6313f } },\n    /* 153 */\n    { { 0xb75f079c,0xb2f4dfdd,0x18e36fbb,0x85b07c95,0xe7cd36dd,0x1b6cfcf0,\n        0x0ff4863d,0xab75be15 },\n      { 0x173fc9b7,0x81b367c0,0xd2594fd0,0xb90a7420,0xc4091236,0x15fdbf03,\n        0x0b4459f6,0x4ebeac2e } },\n    /* 154 */\n    { { 0x5c9f2c53,0xeb6c5fe7,0x8eae9411,0xd2522011,0xf95ac5d8,0xc8887633,\n        0x2c1baffc,0xdf99887b },\n      { 0x850aaecb,0xbb78eed2,0x01d6a272,0x9d49181b,0xb1cdbcac,0x978dd511,\n        0x779f4058,0x27b040a7 } },\n    /* 155 */\n    { { 0xf73b2eb2,0x90405db7,0x8e1b2118,0xe0df8508,0x5962327e,0x501b7152,\n        0xe4cfa3f5,0xb393dd37 },\n      { 0x3fd75165,0xa1230e7b,0xbcd33554,0xd66344c2,0x0f7b5022,0x6c36f1be,\n        0xd0463419,0x09588c12 } },\n    /* 156 */\n    { { 0x02601c3b,0xe086093f,0xcf5c335f,0xfb0252f8,0x894aff28,0x955cf280,\n        0xdb9f648b,0x81c879a9 },\n      { 0xc6f56c51,0x040e687c,0x3f17618c,0xfed47169,0x9059353b,0x44f88a41,\n        0x5fc11bc4,0xfa0d48f5 } },\n    /* 157 */\n    { { 0xe1608e4d,0xbc6e1c9d,0x3582822c,0x010dda11,0x157ec2d7,0xf6b7ddc1,\n        0xb6a367d6,0x8ea0e156 },\n      { 0x2383b3b4,0xa354e02f,0x3f01f53c,0x69966b94,0x2de03ca5,0x4ff6632b,\n        0xfa00b5ac,0x3f5ab924 } },\n    /* 158 */\n    { { 0x59739efb,0x337bb0d9,0xe7ebec0d,0xc751b0f4,0x411a67d1,0x2da52dd6,\n        0x2b74256e,0x8bc76887 },\n      { 0x82d3d253,0xa5be3b72,0xf58d779f,0xa9f679a1,0xe16767bb,0xa1cac168,\n        0x60fcf34f,0xb386f190 } },\n    /* 159 */\n    { { 0x2fedcfc2,0x31f3c135,0x62f8af0d,0x5396bf62,0xe57288c2,0x9a02b4ea,\n        0x1b069c4d,0x4cb460f7 },\n      { 0x5b8095ea,0xae67b4d3,0x6fc07603,0x92bbf859,0xb614a165,0xe1475f66,\n        0x95ef5223,0x52c0d508 } },\n    /* 160 */\n    { { 0x15339848,0x231c210e,0x70778c8d,0xe87a28e8,0x6956e170,0x9d1de661,\n        0x2bb09c0b,0x4ac3c938 },\n      { 0x6998987d,0x19be0551,0xae09f4d6,0x8b2376c4,0x1a3f933d,0x1de0b765,\n        0xe39705f4,0x380d94c7 } },\n    /* 161 */\n    { { 0x81542e75,0x01a355aa,0xee01b9b7,0x96c724a1,0x624d7087,0x6b3a2977,\n        0xde2637af,0x2ce3e171 },\n      { 0xf5d5bc1a,0xcfefeb49,0x2777e2b5,0xa655607e,0x9513756c,0x4feaac2f,\n        0x0b624e4d,0x2e6cd852 } },\n    /* 162 */\n    { { 0x8c31c31d,0x3685954b,0x5bf21a0c,0x68533d00,0x75c79ec9,0x0bd7626e,\n        0x42c69d54,0xca177547 },\n      { 0xf6d2dbb2,0xcc6edaff,0x174a9d18,0xfd0d8cbd,0xaa4578e8,0x875e8793,\n        0x9cab2ce6,0xa976a713 } },\n    /* 163 */\n    { { 0x93fb353d,0x0a651f1b,0x57fcfa72,0xd75cab8b,0x31b15281,0xaa88cfa7,\n        0x0a1f4999,0x8720a717 },\n      { 0x693e1b90,0x8c3e8d37,0x16f6dfc3,0xd345dc0b,0xb52a8742,0x8ea8d00a,\n        0xc769893c,0x9719ef29 } },\n    /* 164 */\n    { { 0x58e35909,0x820eed8d,0x33ddc116,0x9366d8dc,0x6e205026,0xd7f999d0,\n        0xe15704c1,0xa5072976 },\n      { 0xc4e70b2e,0x002a37ea,0x6890aa8a,0x84dcf657,0x645b2a5c,0xcd71bf18,\n        0xf7b77725,0x99389c9d } },\n    /* 165 */\n    { { 0x7ada7a4b,0x238c08f2,0xfd389366,0x3abe9d03,0x766f512c,0x6b672e89,\n        0x202c82e4,0xa88806aa },\n      { 0xd380184e,0x6602044a,0x126a8b85,0xa8cb78c4,0xad844f17,0x79d670c0,\n        0x4738dcfe,0x0043bffb } },\n    /* 166 */\n    { { 0x36d5192e,0x8d59b5dc,0x4590b2af,0xacf885d3,0x11601781,0x83566d0a,\n        0xba6c4866,0x52f3ef01 },\n      { 0x0edcb64d,0x3986732a,0x8068379f,0x0a482c23,0x7040f309,0x16cbe5fa,\n        0x9ef27e75,0x3296bd89 } },\n    /* 167 */\n    { { 0x454d81d7,0x476aba89,0x51eb9b3c,0x9eade7ef,0x81c57986,0x619a21cd,\n        0xaee571e9,0x3b90febf },\n      { 0x5496f7cb,0x9393023e,0x7fb51bc4,0x55be41d8,0x99beb5ce,0x03f1dd48,\n        0x9f810b18,0x6e88069d } },\n    /* 168 */\n    { { 0xb43ea1db,0xce37ab11,0x5259d292,0x0a7ff1a9,0x8f84f186,0x851b0221,\n        0xdefaad13,0xa7222bea },\n      { 0x2b0a9144,0xa2ac78ec,0xf2fa59c5,0x5a024051,0x6147ce38,0x91d1eca5,\n        0xbc2ac690,0xbe94d523 } },\n    /* 169 */\n    { { 0x0b226ce7,0x72f4945e,0x967e8b70,0xb8afd747,0x85a6c63e,0xedea46f1,\n        0x9be8c766,0x7782defe },\n      { 0x3db38626,0x760d2aa4,0x76f67ad1,0x460ae787,0x54499cdb,0x341b86fc,\n        0xa2892e4b,0x03838567 } },\n    /* 170 */\n    { { 0x79ec1a0f,0x2d8daefd,0xceb39c97,0x3bbcd6fd,0x58f61a95,0xf5575ffc,\n        0xadf7b420,0xdbd986c4 },\n      { 0x15f39eb7,0x81aa8814,0xb98d976c,0x6ee2fcf5,0xcf2f717d,0x5465475d,\n        0x6860bbd0,0x8e24d3c4 } },\n    /* 171 */\n    { { 0x9a587390,0x749d8e54,0x0cbec588,0x12bb194f,0xb25983c6,0x46e07da4,\n        0x407bafc8,0x541a99c4 },\n      { 0x624c8842,0xdb241692,0xd86c05ff,0x6044c12a,0x4f7fcf62,0xc59d14b4,\n        0xf57d35d1,0xc0092c49 } },\n    /* 172 */\n    { { 0xdf2e61ef,0xd3cc75c3,0x2e1b35ca,0x7e8841c8,0x909f29f4,0xc62d30d1,\n        0x7286944d,0x75e40634 },\n      { 0xbbc237d0,0xe7d41fc5,0xec4f01c9,0xc9537bf0,0x282bd534,0x91c51a16,\n        0xc7848586,0x5b7cb658 } },\n    /* 173 */\n    { { 0x8a28ead1,0x964a7084,0xfd3b47f6,0x802dc508,0x767e5b39,0x9ae4bfd1,\n        0x8df097a1,0x7ae13eba },\n      { 0xeadd384e,0xfd216ef8,0xb6b2ff06,0x0361a2d9,0x4bcdb5f3,0x204b9878,\n        0xe2a8e3fd,0x787d8074 } },\n    /* 174 */\n    { { 0x757fbb1c,0xc5e25d6b,0xca201deb,0xe47bddb2,0x6d2233ff,0x4a55e9a3,\n        0x9ef28484,0x5c222819 },\n      { 0x88315250,0x773d4a85,0x827097c1,0x21b21a2b,0xdef5d33f,0xab7c4ea1,\n        0xbaf0f2b0,0xe45d37ab } },\n    /* 175 */\n    { { 0x28511c8a,0xd2df1e34,0xbdca6cd3,0xebb229c8,0x627c39a7,0x578a71a7,\n        0x84dfb9d3,0xed7bc122 },\n      { 0x93dea561,0xcf22a6df,0xd48f0ed1,0x5443f18d,0x5bad23e8,0xd8b86140,\n        0x45ca6d27,0xaac97cc9 } },\n    /* 176 */\n    { { 0xa16bd00a,0xeb54ea74,0xf5c0bcc1,0xd839e9ad,0x1f9bfc06,0x092bb7f1,\n        0x1163dc4e,0x318f97b3 },\n      { 0xc30d7138,0xecc0c5be,0xabc30220,0x44e8df23,0xb0223606,0x2bb7972f,\n        0x9a84ff4d,0xfa41faa1 } },\n    /* 177 */\n    { { 0xa6642269,0x4402d974,0x9bb783bd,0xc81814ce,0x7941e60b,0x398d38e4,\n        0x1d26e9e2,0x38bb6b2c },\n      { 0x6a577f87,0xc64e4a25,0xdc11fe1c,0x8b52d253,0x62280728,0xff336abf,\n        0xce7601a5,0x94dd0905 } },\n    /* 178 */\n    { { 0xde93f92a,0x156cf7dc,0x89b5f315,0xa01333cb,0xc995e750,0x02404df9,\n        0xd25c2ae9,0x92077867 },\n      { 0x0bf39d44,0xe2471e01,0x96bb53d7,0x5f2c9020,0x5c9c3d8f,0x4c44b7b3,\n        0xd29beb51,0x81e8428b } },\n    /* 179 */\n    { { 0xc477199f,0x6dd9c2ba,0x6b5ecdd9,0x8cb8eeee,0xee40fd0e,0x8af7db3f,\n        0xdbbfa4b1,0x1b94ab62 },\n      { 0xce47f143,0x44f0d8b3,0x63f46163,0x51e623fc,0xcc599383,0xf18f270f,\n        0x055590ee,0x06a38e28 } },\n    /* 180 */\n    { { 0xb3355b49,0x2e5b0139,0xb4ebf99b,0x20e26560,0xd269f3dc,0xc08ffa6b,\n        0x83d9d4f8,0xa7b36c20 },\n      { 0x1b3e8830,0x64d15c3a,0xa89f9c0b,0xd5fceae1,0xe2d16930,0xcfeee4a2,\n        0xa2822a20,0xbe54c6b4 } },\n    /* 181 */\n    { { 0x8d91167c,0xd6cdb3df,0xe7a6625e,0x517c3f79,0x346ac7f4,0x7105648f,\n        0xeae022bb,0xbf30a5ab },\n      { 0x93828a68,0x8e7785be,0x7f3ef036,0x5161c332,0x592146b2,0xe11b5feb,\n        0x2732d13a,0xd1c820de } },\n    /* 182 */\n    { { 0x9038b363,0x043e1347,0x6b05e519,0x58c11f54,0x6026cad1,0x4fe57abe,\n        0x68a18da3,0xb7d17bed },\n      { 0xe29c2559,0x44ca5891,0x5bfffd84,0x4f7a0376,0x74e46948,0x498de4af,\n        0x6412cc64,0x3997fd5e } },\n    /* 183 */\n    { { 0x8bd61507,0xf2074682,0x34a64d2a,0x29e132d5,0x8a8a15e3,0xffeddfb0,\n        0x3c6c13e8,0x0eeb8929 },\n      { 0xa7e259f8,0xe9b69a3e,0xd13e7e67,0xce1db7e6,0xad1fa685,0x277318f6,\n        0xc922b6ef,0x228916f8 } },\n    /* 184 */\n    { { 0x0a12ab5b,0x959ae25b,0x957bc136,0xcc11171f,0xd16e2b0c,0x8058429e,\n        0x6e93097e,0xec05ad1d },\n      { 0xac3f3708,0x157ba5be,0x30b59d77,0x31baf935,0x118234e5,0x47b55237,\n        0x7ff11b37,0x7d314156 } },\n    /* 185 */\n    { { 0xf6dfefab,0x7bd9c05c,0xdcb37707,0xbe2f2268,0x3a38bb95,0xe53ead97,\n        0x9bc1d7a3,0xe9ce66fc },\n      { 0x6f6a02a1,0x75aa1576,0x60e600ed,0x38c087df,0x68cdc1b9,0xf8947f34,\n        0x72280651,0xd9650b01 } },\n    /* 186 */\n    { { 0x5a057e60,0x504b4c4a,0x8def25e4,0xcbccc3be,0x17c1ccbd,0xa6353208,\n        0x804eb7a2,0x14d6699a },\n      { 0xdb1f411a,0x2c8a8415,0xf80d769c,0x09fbaf0b,0x1c2f77ad,0xb4deef90,\n        0x0d43598a,0x6f4c6841 } },\n    /* 187 */\n    { { 0x96c24a96,0x8726df4e,0xfcbd99a3,0x534dbc85,0x8b2ae30a,0x3c466ef2,\n        0x61189abb,0x4c4350fd },\n      { 0xf855b8da,0x2967f716,0x463c38a1,0x41a42394,0xeae93343,0xc37e1413,\n        0x5a3118b5,0xa726d242 } },\n    /* 188 */\n    { { 0x948c1086,0xdae6b3ee,0xcbd3a2e1,0xf1de503d,0x03d022f3,0x3f35ed3f,\n        0xcc6cf392,0x13639e82 },\n      { 0xcdafaa86,0x9ac938fb,0x2654a258,0xf45bc5fb,0x45051329,0x1963b26e,\n        0xc1a335a3,0xca9365e1 } },\n    /* 189 */\n    { { 0x4c3b2d20,0x3615ac75,0x904e241b,0x742a5417,0xcc9d071d,0xb08521c4,\n        0x970b72a5,0x9ce29c34 },\n      { 0x6d3e0ad6,0x8cc81f73,0xf2f8434c,0x8060da9e,0x6ce862d9,0x35ed1d1a,\n        0xab42af98,0x48c4abd7 } },\n    /* 190 */\n    { { 0x40c7485a,0xd221b0cc,0xe5274dbf,0xead455bb,0x9263d2e8,0x493c7698,\n        0xf67b33cb,0x78017c32 },\n      { 0x930cb5ee,0xb9d35769,0x0c408ed2,0xc0d14e94,0x272f1a4d,0xf8b7bf55,\n        0xde5c1c04,0x53cd0454 } },\n    /* 191 */\n    { { 0x5d28ccac,0xbcd585fa,0x005b746e,0x5f823e56,0xcd0123aa,0x7c79f0a1,\n        0xd3d7fa8f,0xeea465c1 },\n      { 0x0551803b,0x7810659f,0x7ce6af70,0x6c0b599f,0x29288e70,0x4195a770,\n        0x7ae69193,0x1b6e42a4 } },\n    /* 192 */\n    { { 0xf67d04c3,0x2e80937c,0x89eeb811,0x1e312be2,0x92594d60,0x56b5d887,\n        0x187fbd3d,0x0224da14 },\n      { 0x0c5fe36f,0x87abb863,0x4ef51f5f,0x580f3c60,0xb3b429ec,0x964fb1bf,\n        0x42bfff33,0x60838ef0 } },\n    /* 193 */\n    { { 0x7e0bbe99,0x432cb2f2,0x04aa39ee,0x7bda44f3,0x9fa93903,0x5f497c7a,\n        0x2d331643,0x636eb202 },\n      { 0x93ae00aa,0xfcfd0e61,0x31ae6d2f,0x875a00fe,0x9f93901c,0xf43658a2,\n        0x39218bac,0x8844eeb6 } },\n    /* 194 */\n    { { 0x6b3bae58,0x114171d2,0x17e39f3e,0x7db3df71,0x81a8eada,0xcd37bc7f,\n        0x51fb789e,0x27ba83dc },\n      { 0xfbf54de5,0xa7df439f,0xb5fe1a71,0x7277030b,0xdb297a48,0x42ee8e35,\n        0x87f3a4ab,0xadb62d34 } },\n    /* 195 */\n    { { 0xa175df2a,0x9b1168a2,0x618c32e9,0x082aa04f,0x146b0916,0xc9e4f2e7,\n        0x75e7c8b2,0xb990fd76 },\n      { 0x4df37313,0x0829d96b,0xd0b40789,0x1c205579,0x78087711,0x66c9ae4a,\n        0x4d10d18d,0x81707ef9 } },\n    /* 196 */\n    { { 0x03d6ff96,0x97d7cab2,0x0d843360,0x5b851bfc,0xd042db4b,0x268823c4,\n        0xd5a8aa5c,0x3792daea },\n      { 0x941afa0b,0x52818865,0x42d83671,0xf3e9e741,0x5be4e0a7,0x17c82527,\n        0x94b001ba,0x5abd635e } },\n    /* 197 */\n    { { 0x0ac4927c,0x727fa84e,0xa7c8cf23,0xe3886035,0x4adca0df,0xa4bcd5ea,\n        0x846ab610,0x5995bf21 },\n      { 0x829dfa33,0xe90f860b,0x958fc18b,0xcaafe2ae,0x78630366,0x9b3baf44,\n        0xd483411e,0x44c32ca2 } },\n    /* 198 */\n    { { 0xe40ed80c,0xa74a97f1,0x31d2ca82,0x5f938cb1,0x7c2d6ad9,0x53f2124b,\n        0x8082a54c,0x1f2162fb },\n      { 0x720b173e,0x7e467cc5,0x085f12f9,0x40e8a666,0x4c9d65dc,0x8cebc20e,\n        0xc3e907c9,0x8f1d402b } },\n    /* 199 */\n    { { 0xfbc4058a,0x4f592f9c,0x292f5670,0xb15e14b6,0xbc1d8c57,0xc55cfe37,\n        0x926edbf9,0xb1980f43 },\n      { 0x32c76b09,0x98c33e09,0x33b07f78,0x1df5279d,0x863bb461,0x6f08ead4,\n        0x37448e45,0x2828ad9b } },\n    /* 200 */\n    { { 0xc4cf4ac5,0x696722c4,0xdde64afb,0xf5ac1a3f,0xe0890832,0x0551baa2,\n        0x5a14b390,0x4973f127 },\n      { 0x322eac5d,0xe59d8335,0x0bd9b568,0x5e07eef5,0xa2588393,0xab36720f,\n        0xdb168ac7,0x6dac8ed0 } },\n    /* 201 */\n    { { 0xeda835ef,0xf7b545ae,0x1d10ed51,0x4aa113d2,0x13741b09,0x035a65e0,\n        0x20b9de4c,0x4b23ef59 },\n      { 0x3c4c7341,0xe82bb680,0x3f58bc37,0xd457706d,0xa51e3ee8,0x73527863,\n        0xddf49a4e,0x4dd71534 } },\n    /* 202 */\n    { { 0x95476cd9,0xbf944672,0xe31a725b,0x648d072f,0xfc4b67e0,0x1441c8b8,\n        0x2f4a4dbb,0xfd317000 },\n      { 0x8995d0e1,0x1cb43ff4,0x0ef729aa,0x76e695d1,0x41798982,0xe0d5f976,\n        0x9569f365,0x14fac58c } },\n    /* 203 */\n    { { 0xf312ae18,0xad9a0065,0xfcc93fc9,0x51958dc0,0x8a7d2846,0xd9a14240,\n        0x36abda50,0xed7c7651 },\n      { 0x25d4abbc,0x46270f1a,0xf1a113ea,0x9b5dd8f3,0x5b51952f,0xc609b075,\n        0x4d2e9f53,0xfefcb7f7 } },\n    /* 204 */\n    { { 0xba119185,0xbd09497a,0xaac45ba4,0xd54e8c30,0xaa521179,0x492479de,\n        0x87e0d80b,0x1801a57e },\n      { 0xfcafffb0,0x073d3f8d,0xae255240,0x6cf33c0b,0x5b5fdfbc,0x781d763b,\n        0x1ead1064,0x9f8fc11e } },\n    /* 205 */\n    { { 0x5e69544c,0x1583a171,0xf04b7813,0x0eaf8567,0x278a4c32,0x1e22a8fd,\n        0x3d3a69a9,0xa9d3809d },\n      { 0x59a2da3b,0x936c2c2c,0x1895c847,0x38ccbcf6,0x63d50869,0x5e65244e,\n        0xe1178ef7,0x3006b9ae } },\n    /* 206 */\n    { { 0xc9eead28,0x0bb1f2b0,0x89f4dfbc,0x7eef635d,0xb2ce8939,0x074757fd,\n        0x45f8f761,0x0ab85fd7 },\n      { 0x3e5b4549,0xecda7c93,0x97922f21,0x4be2bb5c,0xb43b8040,0x261a1274,\n        0x11e942c2,0xb122d675 } },\n    /* 207 */\n    { { 0x66a5ae7a,0x3be607be,0x76adcbe3,0x01e703fa,0x4eb6e5c5,0xaf904301,\n        0x097dbaec,0x9f599dc1 },\n      { 0x0ff250ed,0x6d75b718,0x349a20dc,0x8eb91574,0x10b227a3,0x425605a4,\n        0x8a294b78,0x7d5528e0 } },\n    /* 208 */\n    { { 0x20c26def,0xf0f58f66,0x582b2d1e,0x025585ea,0x01ce3881,0xfbe7d79b,\n        0x303f1730,0x28ccea01 },\n      { 0x79644ba5,0xd1dabcd1,0x06fff0b8,0x1fc643e8,0x66b3e17b,0xa60a76fc,\n        0xa1d013bf,0xc18baf48 } },\n    /* 209 */\n    { { 0x5dc4216d,0x34e638c8,0x206142ac,0x00c01067,0x95f5064a,0xd453a171,\n        0xb7a9596b,0x9def809d },\n      { 0x67ab8d2c,0x41e8642e,0x6237a2b6,0xb4240433,0x64c4218b,0x7d506a6d,\n        0x68808ce5,0x0357f8b0 } },\n    /* 210 */\n    { { 0x4cd2cc88,0x8e9dbe64,0xf0b8f39d,0xcc61c28d,0xcd30a0c8,0x4a309874,\n        0x1b489887,0xe4a01add },\n      { 0xf57cd8f9,0x2ed1eeac,0xbd594c48,0x1b767d3e,0x7bd2f787,0xa7295c71,\n        0xce10cc30,0x466d7d79 } },\n    /* 211 */\n    { { 0x9dada2c7,0x47d31892,0x8f9aa27d,0x4fa0a6c3,0x820a59e1,0x90e4fd28,\n        0x451ead1a,0xc672a522 },\n      { 0x5d86b655,0x30607cc8,0xf9ad4af1,0xf0235d3b,0x571172a6,0x99a08680,\n        0xf2a67513,0x5e3d64fa } },\n    /* 212 */\n    { { 0x9b3b4416,0xaa6410c7,0xeab26d99,0xcd8fcf85,0xdb656a74,0x5ebff74a,\n        0xeb8e42fc,0x6c8a7a95 },\n      { 0xb02a63bd,0x10c60ba7,0x8b8f0047,0x6b2f2303,0x312d90b0,0x8c6c3738,\n        0xad82ca91,0x348ae422 } },\n    /* 213 */\n    { { 0x5ccda2fb,0x7f474663,0x8e0726d2,0x22accaa1,0x492b1f20,0x85adf782,\n        0xd9ef2d2e,0xc1074de0 },\n      { 0xae9a65b3,0xfcf3ce44,0x05d7151b,0xfd71e4ac,0xce6a9788,0xd4711f50,\n        0xc9e54ffc,0xfbadfbdb } },\n    /* 214 */\n    { { 0x20a99363,0x1713f1cd,0x6cf22775,0xb915658f,0x24d359b2,0x968175cd,\n        0x83716fcd,0xb7f976b4 },\n      { 0x5d6dbf74,0x5758e24d,0x71c3af36,0x8d23bafd,0x0243dfe3,0x48f47760,\n        0xcafcc805,0xf4d41b2e } },\n    /* 215 */\n    { { 0xfdabd48d,0x51f1cf28,0x32c078a4,0xce81be36,0x117146e9,0x6ace2974,\n        0xe0160f10,0x180824ea },\n      { 0x66e58358,0x0387698b,0xce6ca358,0x63568752,0x5e41e6c5,0x82380e34,\n        0x83cf6d25,0x67e5f639 } },\n    /* 216 */\n    { { 0xcf4899ef,0xf89ccb8d,0x9ebb44c0,0x949015f0,0xb2598ec9,0x546f9276,\n        0x04c11fc6,0x9fef789a },\n      { 0x53d2a071,0x6d367ecf,0xa4519b09,0xb10e1a7f,0x611e2eef,0xca6b3fb0,\n        0xa99c4e20,0xbc80c181 } },\n    /* 217 */\n    { { 0xe5eb82e6,0x972536f8,0xf56cb920,0x1a484fc7,0x50b5da5e,0xc78e2171,\n        0x9f8cdf10,0x49270e62 },\n      { 0xea6b50ad,0x1a39b7bb,0xa2388ffc,0x9a0284c1,0x8107197b,0x5403eb17,\n        0x61372f7f,0xd2ee52f9 } },\n    /* 218 */\n    { { 0x88e0362a,0xd37cd285,0x8fa5d94d,0x442fa8a7,0xa434a526,0xaff836e5,\n        0xe5abb733,0xdfb478be },\n      { 0x673eede6,0xa91f1ce7,0x2b5b2f04,0xa5390ad4,0x5530da2f,0x5e66f7bf,\n        0x08df473a,0xd9a140b4 } },\n    /* 219 */\n    { { 0x6e8ea498,0x0e0221b5,0x3563ee09,0x62347829,0x335d2ade,0xe06b8391,\n        0x623f4b1a,0x760c058d },\n      { 0xc198aa79,0x0b89b58c,0xf07aba7f,0xf74890d2,0xfde2556a,0x4e204110,\n        0x8f190409,0x7141982d } },\n    /* 220 */\n    { { 0x4d4b0f45,0x6f0a0e33,0x392a94e1,0xd9280b38,0xb3c61d5e,0x3af324c6,\n        0x89d54e47,0x3af9d1ce },\n      { 0x20930371,0xfd8f7981,0x21c17097,0xeda2664c,0xdc42309b,0x0e9545dc,\n        0x73957dd6,0xb1f815c3 } },\n    /* 221 */\n    { { 0x89fec44a,0x84faa78e,0x3caa4caf,0xc8c2ae47,0xc1b6a624,0x691c807d,\n        0x1543f052,0xa41aed14 },\n      { 0x7d5ffe04,0x42435399,0x625b6e20,0x8bacb2df,0x87817775,0x85d660be,\n        0x86fb60ef,0xd6e9c1dd } },\n    /* 222 */\n    { { 0xc6853264,0x3aa2e97e,0xe2304a0b,0x771533b7,0xb8eae9be,0x1b912bb7,\n        0xae9bf8c2,0x9c9c6e10 },\n      { 0xe030b74c,0xa2309a59,0x6a631e90,0x4ed7494d,0xa49b79f2,0x89f44b23,\n        0x40fa61b6,0x566bd596 } },\n    /* 223 */\n    { { 0xc18061f3,0x066c0118,0x7c83fc70,0x190b25d3,0x27273245,0xf05fc8e0,\n        0xf525345e,0xcf2c7390 },\n      { 0x10eb30cf,0xa09bceb4,0x0d77703a,0xcfd2ebba,0x150ff255,0xe842c43a,\n        0x8aa20979,0x02f51755 } },\n    /* 224 */\n    { { 0xaddb7d07,0x396ef794,0x24455500,0x0b4fc742,0xc78aa3ce,0xfaff8eac,\n        0xe8d4d97d,0x14e9ada5 },\n      { 0x2f7079e2,0xdaa480a1,0xe4b0800e,0x45baa3cd,0x7838157d,0x01765e2d,\n        0x8e9d9ae8,0xa0ad4fab } },\n    /* 225 */\n    { { 0x4a653618,0x0bfb7621,0x31eaaa5f,0x1872813c,0x44949d5e,0x1553e737,\n        0x6e56ed1e,0xbcd530b8 },\n      { 0x32e9c47b,0x169be853,0xb50059ab,0xdc2776fe,0x192bfbb4,0xcdba9761,\n        0x6979341d,0x909283cf } },\n    /* 226 */\n    { { 0x76e81a13,0x67b00324,0x62171239,0x9bee1a99,0xd32e19d6,0x08ed361b,\n        0xace1549a,0x35eeb7c9 },\n      { 0x7e4e5bdc,0x1280ae5a,0xb6ceec6e,0x2dcd2cd3,0x6e266bc1,0x52e4224c,\n        0x448ae864,0x9a8b2cf4 } },\n    /* 227 */\n    { { 0x09d03b59,0xf6471bf2,0xb65af2ab,0xc90e62a3,0xebd5eec9,0xff7ff168,\n        0xd4491379,0x6bdb60f4 },\n      { 0x8a55bc30,0xdadafebc,0x10097fe0,0xc79ead16,0x4c1e3bdd,0x42e19741,\n        0x94ba08a9,0x01ec3cfd } },\n    /* 228 */\n    { { 0xdc9485c2,0xba6277eb,0x22fb10c7,0x48cc9a79,0x70a28d8a,0x4f61d60f,\n        0x475464f6,0xd1acb1c0 },\n      { 0x26f36612,0xd26902b1,0xe0618d8b,0x59c3a44e,0x308357ee,0x4df8a813,\n        0x405626c2,0x7dcd079d } },\n    /* 229 */\n    { { 0xf05a4b48,0x5ce7d4d3,0x37230772,0xadcd2952,0x812a915a,0xd18f7971,\n        0x377d19b8,0x0bf53589 },\n      { 0x6c68ea73,0x35ecd95a,0x823a584d,0xc7f3bbca,0xf473a723,0x9fb674c6,\n        0xe16686fc,0xd28be4d9 } },\n    /* 230 */\n    { { 0x38fa8e4b,0x5d2b9906,0x893fd8fc,0x559f186e,0x436fb6fc,0x3a6de2aa,\n        0x510f88ce,0xd76007aa },\n      { 0x523a4988,0x2d10aab6,0x74dd0273,0xb455cf44,0xa3407278,0x7f467082,\n        0xb303bb01,0xf2b52f68 } },\n    /* 231 */\n    { { 0x9835b4ca,0x0d57eafa,0xbb669cbc,0x2d2232fc,0xc6643198,0x8eeeb680,\n        0xcc5aed3a,0xd8dbe98e },\n      { 0xc5a02709,0xcba9be3f,0xf5ba1fa8,0x30be68e5,0xf10ea852,0xfebd43cd,\n        0xee559705,0xe01593a3 } },\n    /* 232 */\n    { { 0xea75a0a6,0xd3e5af50,0x57858033,0x512226ac,0xd0176406,0x6fe6d50f,\n        0xaeb8ef06,0xafec07b1 },\n      { 0x80bb0a31,0x7fb99567,0x37309aae,0x6f1af3cc,0x01abf389,0x9153a15a,\n        0x6e2dbfdd,0xa71b9354 } },\n    /* 233 */\n    { { 0x18f593d2,0xbf8e12e0,0xa078122b,0xd1a90428,0x0ba4f2ad,0x150505db,\n        0x628523d9,0x53a2005c },\n      { 0xe7f2b935,0x07c8b639,0xc182961a,0x2bff975a,0x7518ca2c,0x86bceea7,\n        0x3d588e3d,0xbf47d19b } },\n    /* 234 */\n    { { 0xdd7665d5,0x672967a7,0x2f2f4de5,0x4e303057,0x80d4903f,0x144005ae,\n        0x39c9a1b6,0x001c2c7f },\n      { 0x69efc6d6,0x143a8014,0x7bc7a724,0xc810bdaa,0xa78150a4,0x5f65670b,\n        0x86ffb99b,0xfdadf8e7 } },\n    /* 235 */\n    { { 0xffc00785,0xfd38cb88,0x3b48eb67,0x77fa7591,0xbf368fbc,0x0454d055,\n        0x5aa43c94,0x3a838e4d },\n      { 0x3e97bb9a,0x56166329,0x441d94d9,0x9eb93363,0x0adb2a83,0x515591a6,\n        0x873e1da3,0x3cdb8257 } },\n    /* 236 */\n    { { 0x7de77eab,0x137140a9,0x41648109,0xf7e1c50d,0xceb1d0df,0x762dcad2,\n        0xf1f57fba,0x5a60cc89 },\n      { 0x40d45673,0x80b36382,0x5913c655,0x1b82be19,0xdd64b741,0x057284b8,\n        0xdbfd8fc0,0x922ff56f } },\n    /* 237 */\n    { { 0xc9a129a1,0x1b265dee,0xcc284e04,0xa5b1ce57,0xcebfbe3c,0x04380c46,\n        0xf6c5cd62,0x72919a7d },\n      { 0x8fb90f9a,0x298f453a,0x88e4031b,0xd719c00b,0x796f1856,0xe32c0e77,\n        0x3624089a,0x5e791780 } },\n    /* 238 */\n    { { 0x7f63cdfb,0x5c16ec55,0xf1cae4fd,0x8e6a3571,0x560597ca,0xfce26bea,\n        0xe24c2fab,0x4e0a5371 },\n      { 0xa5765357,0x276a40d3,0x0d73a2b4,0x3c89af44,0x41d11a32,0xb8f370ae,\n        0xd56604ee,0xf5ff7818 } },\n    /* 239 */\n    { { 0x1a09df21,0xfbf3e3fe,0xe66e8e47,0x26d5d28e,0x29c89015,0x2096bd0a,\n        0x533f5e64,0xe41df0e9 },\n      { 0xb3ba9e3f,0x305fda40,0x2604d895,0xf2340ceb,0x7f0367c7,0x0866e192,\n        0xac4f155f,0x8edd7d6e } },\n    /* 240 */\n    { { 0x0bfc8ff3,0xc9a1dc0e,0xe936f42f,0x14efd82b,0xcca381ef,0x67016f7c,\n        0xed8aee96,0x1432c1ca },\n      { 0x70b23c26,0xec684829,0x0735b273,0xa64fe873,0xeaef0f5a,0xe389f6e5,\n        0x5ac8d2c6,0xcaef480b } },\n    /* 241 */\n    { { 0x75315922,0x5245c978,0x3063cca5,0xd8295171,0xb64ef2cb,0xf3ce60d0,\n        0x8efae236,0xd0ba177e },\n      { 0xb1b3af60,0x53a9ae8f,0x3d2da20e,0x1a796ae5,0xdf9eef28,0x01d63605,\n        0x1c54ae16,0xf31c957c } },\n    /* 242 */\n    { { 0x49cc4597,0xc0f58d52,0xbae0a028,0xdc5015b0,0x734a814a,0xefc5fc55,\n        0x96e17c3a,0x013404cb },\n      { 0xc9a824bf,0xb29e2585,0x001eaed7,0xd593185e,0x61ef68ac,0x8d6ee682,\n        0x91933e6c,0x6f377c4b } },\n    /* 243 */\n    { { 0xa8333fd2,0x9f93bad1,0x5a2a95b8,0xa8930202,0xeaf75ace,0x211e5037,\n        0xd2d09506,0x6dba3e4e },\n      { 0xd04399cd,0xa48ef98c,0xe6b73ade,0x1811c66e,0xc17ecaf3,0x72f60752,\n        0x3becf4a7,0xf13cf342 } },\n    /* 244 */\n    { { 0xa919e2eb,0xceeb9ec0,0xf62c0f68,0x83a9a195,0x7aba2299,0xcfba3bb6,\n        0x274bbad3,0xc83fa9a9 },\n      { 0x62fa1ce0,0x0d7d1b0b,0x3418efbf,0xe58b60f5,0x52706f04,0xbfa8ef9e,\n        0x5d702683,0xb49d70f4 } },\n    /* 245 */\n    { { 0xfad5513b,0x914c7510,0xb1751e2d,0x05f32eec,0xd9fb9d59,0x6d850418,\n        0x0c30f1cf,0x59cfadbb },\n      { 0x55cb7fd6,0xe167ac23,0x820426a3,0x249367b8,0x90a78864,0xeaeec58c,\n        0x354a4b67,0x5babf362 } },\n    /* 246 */\n    { { 0xee424865,0x37c981d1,0xf2e5577f,0x8b002878,0xb9e0c058,0x702970f1,\n        0x9026c8f0,0x6188c6a7 },\n      { 0xd0f244da,0x06f9a19b,0xfb080873,0x1ecced5c,0x9f213637,0x35470f9b,\n        0xdf50b9d9,0x993fe475 } },\n    /* 247 */\n    { { 0x9b2c3609,0x68e31cdf,0x2c46d4ea,0x84eb19c0,0x9a775101,0x7ac9ec1a,\n        0x4c80616b,0x81f76466 },\n      { 0x75fbe978,0x1d7c2a5a,0xf183b356,0x6743fed3,0x501dd2bf,0x838d1f04,\n        0x5fe9060d,0x564a812a } },\n    /* 248 */\n    { { 0xfa817d1d,0x7a5a64f4,0xbea82e0f,0x55f96844,0xcd57f9aa,0xb5ff5a0f,\n        0x00e51d6c,0x226bf3cf },\n      { 0x2f2833cf,0xd6d1a9f9,0x4f4f89a8,0x20a0a35a,0x8f3f7f77,0x11536c49,\n        0xff257836,0x68779f47 } },\n    /* 249 */\n    { { 0x73043d08,0x79b0c1c1,0x1fc020fa,0xa5446774,0x9a6d26d0,0xd3767e28,\n        0xeb092e0b,0x97bcb0d1 },\n      { 0xf32ed3c3,0x2ab6eaa8,0xb281bc48,0xc8a4f151,0xbfa178f3,0x4d1bf4f3,\n        0x0a784655,0xa872ffe8 } },\n    /* 250 */\n    { { 0xa32b2086,0xb1ab7935,0x8160f486,0xe1eb710e,0x3b6ae6be,0x9bd0cd91,\n        0xb732a36a,0x02812bfc },\n      { 0xcf605318,0xa63fd7ca,0xfdfd6d1d,0x646e5d50,0x2102d619,0xa1d68398,\n        0xfe5396af,0x07391cc9 } },\n    /* 251 */\n    { { 0x8b80d02b,0xc50157f0,0x62877f7f,0x6b8333d1,0x78d542ae,0x7aca1af8,\n        0x7e6d2a08,0x355d2adc },\n      { 0x287386e1,0xb41f335a,0xf8e43275,0xfd272a94,0xe79989ea,0x286ca2cd,\n        0x7c2a3a79,0x3dc2b1e3 } },\n    /* 252 */\n    { { 0x04581352,0xd689d21c,0x376782be,0x0a00c825,0x9fed701f,0x203bd590,\n        0x3ccd846b,0xc4786910 },\n      { 0x24c768ed,0x5dba7708,0x6841f657,0x72feea02,0x6accce0e,0x73313ed5,\n        0xd5bb4d32,0xccc42968 } },\n    /* 253 */\n    { { 0x3d7620b9,0x94e50de1,0x5992a56a,0xd89a5c8a,0x675487c9,0xdc007640,\n        0xaa4871cf,0xe147eb42 },\n      { 0xacf3ae46,0x274ab4ee,0x50350fbe,0xfd4936fb,0x48c840ea,0xdf2afe47,\n        0x080e96e3,0x239ac047 } },\n    /* 254 */\n    { { 0x2bfee8d4,0x481d1f35,0xfa7b0fec,0xce80b5cf,0x2ce9af3c,0x105c4c9e,\n        0xf5f7e59d,0xc55fa1a3 },\n      { 0x8257c227,0x3186f14e,0x342be00b,0xc5b1653f,0xaa904fb2,0x09afc998,\n        0xd4f4b699,0x094cd99c } },\n    /* 255 */\n    { { 0xd703beba,0x8a981c84,0x32ceb291,0x8631d150,0xe3bd49ec,0xa445f2c9,\n        0x42abad33,0xb90a30b6 },\n      { 0xb4a5abf9,0xb465404f,0x75db7603,0x004750c3,0xca35d89f,0x6f9a42cc,\n        0x1b7924f7,0x019f8b9a } },\n};\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table,\n                                      k, map, heap);\n}\n\n#endif\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[8];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 8, km);\n\n            err = sp_256_ecc_mulmod_base_8(point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_8(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                                        defined(HAVE_ECC_VERIFY)\n/* Returns 1 if the number of zero.\n * Implementation is constant time.\n *\n * a  Number to check.\n * returns 1 if the number is zero and 0 otherwise.\n */\nstatic int sp_256_iszero_8(const sp_digit* a)\n{\n    return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7]) == 0;\n}\n\n#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\n/* Add 1 to a. (a = a + 1)\n *\n * a  A single precision integer.\n */\nstatic void sp_256_add_one_8(sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"ldr\tr1, [%[a], #0]\\n\\t\"\n        \"ldr\tr2, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"adds\tr1, r1, #1\\n\\t\"\n        \"adcs\tr2, r2, #0\\n\\t\"\n        \"adcs\tr3, r3, #0\\n\\t\"\n        \"adcs\tr4, r4, #0\\n\\t\"\n        \"str\tr1, [%[a], #0]\\n\\t\"\n        \"str\tr2, [%[a], #4]\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr1, [%[a], #16]\\n\\t\"\n        \"ldr\tr2, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"adcs\tr1, r1, #0\\n\\t\"\n        \"adcs\tr2, r2, #0\\n\\t\"\n        \"adcs\tr3, r3, #0\\n\\t\"\n        \"adcs\tr4, r4, #0\\n\\t\"\n        \"str\tr1, [%[a], #16]\\n\\t\"\n        \"str\tr2, [%[a], #20]\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        :\n        : [a] \"r\" (a)\n        : \"memory\", \"r1\", \"r2\", \"r3\", \"r4\"\n    );\n}\n\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 24U) {\n            r[j] &= 0xffffffff;\n            s = 32U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Generates a scalar that is in the range 1..order-1.\n *\n * rng  Random number generator.\n * k    Scalar value.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nstatic int sp_256_ecc_gen_k_8(WC_RNG* rng, sp_digit* k)\n{\n    int err;\n    byte buf[32];\n\n    do {\n        err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));\n        if (err == 0) {\n            sp_256_from_bin(k, 8, buf, (int)sizeof(buf));\n            if (sp_256_cmp_8(k, p256_order2) < 0) {\n                sp_256_add_one_8(k);\n                break;\n            }\n        }\n    }\n    while (err == 0);\n\n    return err;\n}\n\n/* Makes a random EC key pair.\n *\n * rng   Random number generator.\n * priv  Generated private value.\n * pub   Generated public point.\n * heap  Heap to use for allocation.\n * returns ECC_INF_E when the point does not have the correct order, RNG\n * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[8];\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point inf;\n#endif\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point* infinity;\n#endif\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, inf, infinity);\n    }\n#endif\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_ecc_gen_k_8(rng, k);\n    }\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);\n    }\n\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_8(infinity, point, p256_order, 1, NULL);\n    }\n    if (err == MP_OKAY) {\n        if ((sp_256_iszero_8(point->x) == 0) || (sp_256_iszero_8(point->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(k, priv);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_8(point, pub);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_ecc_point_free(infinity, 1, heap);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n\n#ifdef HAVE_ECC_DHE\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 32\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_256_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 256 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<8 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 32) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 32);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n/* Multiply the point by the scalar and serialize the X ordinate.\n * The number is 0 padded to maximum size on output.\n *\n * priv    Scalar to multiply the point by.\n * pub     Point to multiply.\n * out     Buffer to hold X ordinate.\n * outLen  On entry, size of the buffer in bytes.\n *         On exit, length of data in buffer in bytes.\n * heap    Heap to use for allocation.\n * returns BUFFER_E if the buffer is to small for output size,\n * MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out,\n                          word32* outLen, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[8];\n#endif\n    sp_point* point = NULL;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    if (*outLen < 32U) {\n        err = BUFFER_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p, point);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 8, priv);\n        sp_256_point_from_ecc_point_8(point, pub);\n            err = sp_256_ecc_mulmod_8(point, point, k, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        sp_256_to_bin(point->x, out);\n        *outLen = 32;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_DHE */\n\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #64\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tr3, r5, #28\\n\\t\"\n        \"it\tcc\\n\\t\"\n        \"movcc\tr3, #0\\n\\t\"\n        \"sub\tr4, r5, r3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"ldr\tr12, [%[b], r4]\\n\\t\"\n        \"umull\tr9, r10, r14, r12\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, #0\\n\\t\"\n        \"add\tr3, r3, #4\\n\\t\"\n        \"sub\tr4, r4, #4\\n\\t\"\n        \"cmp\tr3, #32\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\tr3, r5\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"mov\tr6, r7\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"add\tr5, r5, #4\\n\\t\"\n        \"cmp\tr5, #56\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [sp, #0]\\n\\t\"\n        \"ldr\tr7, [sp, #4]\\n\\t\"\n        \"ldr\tr8, [sp, #8]\\n\\t\"\n        \"ldr\tr3, [sp, #12]\\n\\t\"\n        \"str\tr6, [%[r], #0]\\n\\t\"\n        \"str\tr7, [%[r], #4]\\n\\t\"\n        \"str\tr8, [%[r], #8]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"add\tsp, sp, #16\\n\\t\"\n        \"add\t%[r], %[r], #16\\n\\t\"\n        \"subs\tr5, r5, #16\\n\\t\"\n        \"bgt\t4b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r12\"\n    );\n}\n\n#else\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #32\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        \"#  A[0] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr3, r4, r8, r9\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [sp]\\n\\t\"\n        \"#  A[0] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #4]\\n\\t\"\n        \"#  A[0] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #8]\\n\\t\"\n        \"#  A[0] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #12]\\n\\t\"\n        \"#  A[0] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #16]\\n\\t\"\n        \"#  A[0] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[1] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[2] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [sp, #20]\\n\\t\"\n        \"#  A[0] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[1] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[2] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[3] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [sp, #24]\\n\\t\"\n        \"#  A[0] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[1] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[2] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[3] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[4] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[0]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [sp, #28]\\n\\t\"\n        \"#  A[1] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[2] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[3] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[4] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[5] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[1]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #32]\\n\\t\"\n        \"#  A[2] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[3] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[4] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[5] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[6] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[2]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"#  A[3] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[4] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[5] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[6] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"#  A[7] * B[3]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"#  A[4] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r10, r10\\n\\t\"\n        \"#  A[5] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[6] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"#  A[7] * B[4]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #44]\\n\\t\"\n        \"#  A[5] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r10, r10\\n\\t\"\n        \"#  A[6] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"#  A[7] * B[5]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"#  A[6] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r10, r10\\n\\t\"\n        \"#  A[7] * B[6]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"#  A[7] * B[7]\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r8, r9\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr5, [%[r], #56]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"ldr\tr3, [sp, #0]\\n\\t\"\n        \"ldr\tr4, [sp, #4]\\n\\t\"\n        \"ldr\tr5, [sp, #8]\\n\\t\"\n        \"ldr\tr6, [sp, #12]\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [sp, #16]\\n\\t\"\n        \"ldr\tr4, [sp, #20]\\n\\t\"\n        \"ldr\tr5, [sp, #24]\\n\\t\"\n        \"ldr\tr6, [sp, #28]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"str\tr5, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        \"add\tsp, sp, #32\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_256_sub_in_place_8(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr14, #0\\n\\t\"\n        \"add\tr12, %[a], #32\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\t%[c], r14, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[a], #8]\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b]], #4\\n\\t\"\n        \"ldr\tr8, [%[b]], #4\\n\\t\"\n        \"ldr\tr9, [%[b]], #4\\n\\t\"\n        \"ldr\tr10, [%[b]], #4\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"sbcs\tr6, r6, r10\\n\\t\"\n        \"str\tr3, [%[a]], #4\\n\\t\"\n        \"str\tr4, [%[a]], #4\\n\\t\"\n        \"str\tr5, [%[a]], #4\\n\\t\"\n        \"str\tr6, [%[a]], #4\\n\\t\"\n        \"sbc\t%[c], r14, r14\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r12\", \"r14\"\n    );\n\n    return c;\n}\n\n#else\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_256_sub_in_place_8(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr6, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"ldr\tr8, [%[b], #8]\\n\\t\"\n        \"ldr\tr9, [%[b], #12]\\n\\t\"\n        \"subs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr6, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"ldr\tr8, [%[b], #24]\\n\\t\"\n        \"ldr\tr9, [%[b], #28]\\n\\t\"\n        \"sbcs\tr2, r2, r6\\n\\t\"\n        \"sbcs\tr3, r3, r7\\n\\t\"\n        \"sbcs\tr4, r4, r8\\n\\t\"\n        \"sbcs\tr5, r5, r9\\n\\t\"\n        \"str\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr5, [%[a], #28]\\n\\t\"\n        \"sbc\t%[c], r9, r9\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nstatic void sp_256_mul_d_8(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tr10, #0\\n\\t\"\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tr8, [%[a]]\\n\\t\"\n        \"umull\tr5, r3, %[b], r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr5, [%[r]]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr9, #4\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr8, [%[a], r9]\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], r9]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr9, r9, #4\\n\\t\"\n        \"cmp\tr9, #32\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r], #32]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tr10, #0\\n\\t\"\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tr8, [%[a]]\\n\\t\"\n        \"umull\tr3, r4, %[b], r8\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"# A[1] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"# A[2] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"# A[3] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"# A[4] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"# A[5] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"# A[6] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"# A[7] * B\\n\\t\"\n        \"ldr\tr8, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, %[b], r8\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"str\tr5, [%[r], #32]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n#endif\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nstatic sp_digit div_256_word_8(sp_digit d1, sp_digit d0, sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr5, %[div], #1\\n\\t\"\n        \"add\tr5, r5, #1\\n\\t\"\n        \"mov\tr6, %[d0]\\n\\t\"\n        \"mov\tr7, %[d1]\\n\\t\"\n        \"# Do top 32\\n\\t\"\n        \"subs\tr8, r5, r7\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        \"and\tr8, r8, r5\\n\\t\"\n        \"subs\tr7, r7, r8\\n\\t\"\n        \"# Next 30 bits\\n\\t\"\n        \"mov\tr4, #29\\n\\t\"\n        \"1:\\n\\t\"\n        \"movs\tr6, r6, lsl #1\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"subs\tr8, r5, r7\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        \"and\tr8, r8, r5\\n\\t\"\n        \"subs\tr7, r7, r8\\n\\t\"\n        \"subs\tr4, r4, #1\\n\\t\"\n        \"bpl\t1b\\n\\t\"\n        \"add\t%[r], %[r], %[r]\\n\\t\"\n        \"add\t%[r], %[r], #1\\n\\t\"\n        \"umull\tr4, r5, %[r], %[div]\\n\\t\"\n        \"subs\tr4, %[d0], r4\\n\\t\"\n        \"sbc\tr5, %[d1], r5\\n\\t\"\n        \"add\t%[r], %[r], r5\\n\\t\"\n        \"umull\tr4, r5, %[r], %[div]\\n\\t\"\n        \"subs\tr4, %[d0], r4\\n\\t\"\n        \"sbc\tr5, %[d1], r5\\n\\t\"\n        \"add\t%[r], %[r], r5\\n\\t\"\n        \"subs\tr8, %[div], r4\\n\\t\"\n        \"sbc\tr8, r8, r8\\n\\t\"\n        \"sub\t%[r], %[r], r8\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_256_mask_8(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<8; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    r[0] = a[0] & m;\n    r[1] = a[1] & m;\n    r[2] = a[2] & m;\n    r[3] = a[3] & m;\n    r[4] = a[4] & m;\n    r[5] = a[5] & m;\n    r[6] = a[6] & m;\n    r[7] = a[7] & m;\n#endif\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_256_div_8(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[16], t2[9];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n\n    div = d[7];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 8);\n    for (i=7; i>=0; i--) {\n        r1 = div_256_word_8(t1[8 + i], t1[8 + i - 1], div);\n\n        sp_256_mul_d_8(t2, d, r1);\n        t1[8 + i] += sp_256_sub_in_place_8(&t1[i], t2);\n        t1[8 + i] -= t2[8];\n        sp_256_mask_8(t2, d, t1[8 + i]);\n        t1[8 + i] += sp_256_add_8(&t1[i], &t1[i], t2);\n        sp_256_mask_8(t2, d, t1[8 + i]);\n        t1[8 + i] += sp_256_add_8(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_256_cmp_8(t1, d) >= 0;\n    sp_256_cond_sub_8(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_256_mod_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_256_div_8(a, m, NULL, r);\n}\n\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#ifdef WOLFSSL_SP_SMALL\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_256_sqr_8(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #64\\n\\t\"\n        \"mov\tr12, #0\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tr3, r5, #28\\n\\t\"\n        \"it\tcc\\n\\t\"\n        \"movcc\tr3, r12\\n\\t\"\n        \"sub\tr4, r5, r3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr4, r3\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"ldr\tr9, [%[a], r4]\\n\\t\"\n        \"umull\tr9, r10, r14, r9\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr14, [%[a], r3]\\n\\t\"\n        \"umull\tr9, r10, r14, r14\\n\\t\"\n        \"adds\tr6, r6, r9\\n\\t\"\n        \"adcs\tr7, r7, r10\\n\\t\"\n        \"adc\tr8, r8, r12\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\tr3, r3, #4\\n\\t\"\n        \"sub\tr4, r4, #4\\n\\t\"\n        \"cmp\tr3, #32\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\tr3, r4\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"cmp\tr3, r5\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"mov\tr6, r7\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"mov\tr8, #0\\n\\t\"\n        \"add\tr5, r5, #4\\n\\t\"\n        \"cmp\tr5, #56\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr6, [sp, r5]\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [sp, #0]\\n\\t\"\n        \"ldr\tr7, [sp, #4]\\n\\t\"\n        \"ldr\tr8, [sp, #8]\\n\\t\"\n        \"ldr\tr3, [sp, #12]\\n\\t\"\n        \"str\tr6, [%[r], #0]\\n\\t\"\n        \"str\tr7, [%[r], #4]\\n\\t\"\n        \"str\tr8, [%[r], #8]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"add\tsp, sp, #16\\n\\t\"\n        \"add\t%[r], %[r], #16\\n\\t\"\n        \"subs\tr5, r5, #16\\n\\t\"\n        \"bgt\t4b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r14\", \"r9\", \"r12\"\n    );\n}\n\n#else\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_256_sqr_8(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"sub\tsp, sp, #32\\n\\t\"\n        \"mov\tr14, #0\\n\\t\"\n        \"#  A[0] * A[0]\\n\\t\"\n        \"ldr\tr10, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r3, r10, r10\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr8, [sp]\\n\\t\"\n        \"#  A[0] * A[1]\\n\\t\"\n        \"ldr\tr10, [%[a], #4]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [sp, #4]\\n\\t\"\n        \"#  A[0] * A[2]\\n\\t\"\n        \"ldr\tr10, [%[a], #8]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r14, r14\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"#  A[1] * A[1]\\n\\t\"\n        \"ldr\tr10, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"str\tr4, [sp, #8]\\n\\t\"\n        \"#  A[0] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r14, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"#  A[1] * A[2]\\n\\t\"\n        \"ldr\tr10, [%[a], #8]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"str\tr2, [sp, #12]\\n\\t\"\n        \"#  A[0] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[1] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[2] * A[2]\\n\\t\"\n        \"ldr\tr10, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [sp, #16]\\n\\t\"\n        \"#  A[0] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [sp, #20]\\n\\t\"\n        \"#  A[0] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[3]\\n\\t\"\n        \"ldr\tr10, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [sp, #24]\\n\\t\"\n        \"#  A[0] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #0]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[1] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[2] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adc\tr2, r2, r7\\n\\t\"\n        \"str\tr3, [sp, #28]\\n\\t\"\n        \"#  A[1] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #4]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[2] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[3] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[4]\\n\\t\"\n        \"ldr\tr10, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr4, r4, r5\\n\\t\"\n        \"adcs\tr2, r2, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"#  A[2] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #8]\\n\\t\"\n        \"umull\tr5, r6, r10, r8\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"#  A[3] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"#  A[4] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr6, r6, r9\\n\\t\"\n        \"adc\tr7, r7, r14\\n\\t\"\n        \"adds\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"adds\tr2, r2, r5\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        \"str\tr2, [%[r], #36]\\n\\t\"\n        \"#  A[3] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[4] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"#  A[5] * A[5]\\n\\t\"\n        \"ldr\tr10, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [%[r], #40]\\n\\t\"\n        \"#  A[4] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r14, r14\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"#  A[5] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr2, r2, r9\\n\\t\"\n        \"adc\tr3, r3, r14\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"#  A[5] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r14, r14\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"#  A[6] * A[6]\\n\\t\"\n        \"ldr\tr10, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr2, r2, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r14\\n\\t\"\n        \"str\tr2, [%[r], #48]\\n\\t\"\n        \"#  A[6] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"ldr\tr8, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r10, r8\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r14, r14\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr2, r2, r14\\n\\t\"\n        \"str\tr3, [%[r], #52]\\n\\t\"\n        \"#  A[7] * A[7]\\n\\t\"\n        \"ldr\tr10, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adc\tr2, r2, r9\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"str\tr2, [%[r], #60]\\n\\t\"\n        \"ldr\tr2, [sp, #0]\\n\\t\"\n        \"ldr\tr3, [sp, #4]\\n\\t\"\n        \"ldr\tr4, [sp, #8]\\n\\t\"\n        \"ldr\tr8, [sp, #12]\\n\\t\"\n        \"str\tr2, [%[r], #0]\\n\\t\"\n        \"str\tr3, [%[r], #4]\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"str\tr8, [%[r], #12]\\n\\t\"\n        \"ldr\tr2, [sp, #16]\\n\\t\"\n        \"ldr\tr3, [sp, #20]\\n\\t\"\n        \"ldr\tr4, [sp, #24]\\n\\t\"\n        \"ldr\tr8, [sp, #28]\\n\\t\"\n        \"str\tr2, [%[r], #16]\\n\\t\"\n        \"str\tr3, [%[r], #20]\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"str\tr8, [%[r], #28]\\n\\t\"\n        \"add\tsp, sp, #32\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r8\", \"r9\", \"r10\", \"r8\", \"r5\", \"r6\", \"r7\", \"r14\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Order-2 for the P256 curve. */\nstatic const uint32_t p256_order_2[8] = {\n    0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU,0xffffffffU,0xffffffffU,\n    0x00000000U,0xffffffffU\n};\n#else\n/* The low half of the order-2 of the P256 curve. */\nstatic const uint32_t p256_order_low[4] = {\n    0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU\n};\n#endif /* WOLFSSL_SP_SMALL */\n\n/* Multiply two number mod the order of P256 curve. (r = a * b mod order)\n *\n * r  Result of the multiplication.\n * a  First operand of the multiplication.\n * b  Second operand of the multiplication.\n */\nstatic void sp_256_mont_mul_order_8(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_256_mul_8(r, a, b);\n    sp_256_mont_reduce_order_8(r, p256_order, p256_mp_order);\n}\n\n/* Square number mod the order of P256 curve. (r = a * a mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_order_8(sp_digit* r, const sp_digit* a)\n{\n    sp_256_sqr_8(r, a);\n    sp_256_mont_reduce_order_8(r, p256_order, p256_mp_order);\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Square number mod the order of P256 curve a number of times.\n * (r = a ^ n mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_n_order_8(sp_digit* r, const sp_digit* a, int n)\n{\n    int i;\n\n    sp_256_mont_sqr_order_8(r, a);\n    for (i=1; i<n; i++) {\n        sp_256_mont_sqr_order_8(r, r);\n    }\n}\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the order of the P256 curve.\n * (r = 1 / a mod order)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a,\n        sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 8);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_order_8(t, t);\n        if ((p256_order_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t, t, a);\n        }\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 8U);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 8;\n    sp_digit* t3 = td + 4 * 8;\n    int i;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_order_8(t, a);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_order_8(t, t, a);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_order_8(t2, t, 2);\n    /* t3= a^f = t2 * t */\n    sp_256_mont_mul_order_8(t3, t2, t);\n    /* t2= a^f0 = t3 ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_order_8(t2, t3, 4);\n    /* t = a^ff = t2 * t3 */\n    sp_256_mont_mul_order_8(t, t2, t3);\n    /* t3= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_order_8(t2, t, 8);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_order_8(t, t2, t);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_order_8(t2, t, 16);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_order_8(t, t2, t);\n    /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64  */\n    sp_256_mont_sqr_n_order_8(t2, t, 64);\n    /* t2= a^ffffffff00000000ffffffff = t2 * t */\n    sp_256_mont_mul_order_8(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_order_8(t2, t2, 32);\n    /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_order_8(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6 */\n    for (i=127; i>=112; i--) {\n        sp_256_mont_sqr_order_8(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6f */\n    sp_256_mont_sqr_n_order_8(t2, t2, 4);\n    sp_256_mont_mul_order_8(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */\n    for (i=107; i>=64; i--) {\n        sp_256_mont_sqr_order_8(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */\n    sp_256_mont_sqr_n_order_8(t2, t2, 4);\n    sp_256_mont_mul_order_8(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */\n    for (i=59; i>=32; i--) {\n        sp_256_mont_sqr_order_8(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */\n    sp_256_mont_sqr_n_order_8(t2, t2, 4);\n    sp_256_mont_mul_order_8(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */\n    for (i=27; i>=0; i--) {\n        sp_256_mont_sqr_order_8(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */\n    sp_256_mont_sqr_n_order_8(t2, t2, 4);\n    /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */\n    sp_256_mont_mul_order_8(r, t2, t3);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\n#ifdef HAVE_ECC_SIGN\n#ifndef SP_ECC_MAX_SIG_GEN\n#define SP_ECC_MAX_SIG_GEN  64\n#endif\n\n/* Sign the hash using the private key.\n *   e = [hash, 256 bits] from binary\n *   r = (k.G)->x mod order\n *   s = (r * x + e) / k mod order\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,\n                    mp_int* rm, mp_int* sm, mp_int* km, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit ed[2*8];\n    sp_digit xd[2*8];\n    sp_digit kd[2*8];\n    sp_digit rd[2*8];\n    sp_digit td[3 * 2*8];\n    sp_point p;\n#endif\n    sp_digit* e = NULL;\n    sp_digit* x = NULL;\n    sp_digit* k = NULL;\n    sp_digit* r = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* point = NULL;\n    sp_digit carry;\n    sp_digit* s = NULL;\n    sp_digit* kInv = NULL;\n    int err = MP_OKAY;\n    int32_t c;\n    int i;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        e = d + 0 * 8;\n        x = d + 2 * 8;\n        k = d + 4 * 8;\n        r = d + 6 * 8;\n        tmp = d + 8 * 8;\n#else\n        e = ed;\n        x = xd;\n        k = kd;\n        r = rd;\n        tmp = td;\n#endif\n        s = e;\n        kInv = k;\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(e, 8, hash, (int)hashLen);\n    }\n\n    for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {\n        sp_256_from_mp(x, 8, priv);\n\n        /* New random point. */\n        if (km == NULL || mp_iszero(km)) {\n            err = sp_256_ecc_gen_k_8(rng, k);\n        }\n        else {\n            sp_256_from_mp(k, 8, km);\n            mp_zero(km);\n        }\n        if (err == MP_OKAY) {\n                err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);\n        }\n\n        if (err == MP_OKAY) {\n            /* r = point->x mod order */\n            XMEMCPY(r, point->x, sizeof(sp_digit) * 8U);\n            sp_256_norm_8(r);\n            c = sp_256_cmp_8(r, p256_order);\n            sp_256_cond_sub_8(r, r, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_8(r);\n\n            /* Conv k to Montgomery form (mod order) */\n                sp_256_mul_8(k, k, p256_norm_order);\n            err = sp_256_mod_8(k, k, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_8(k);\n            /* kInv = 1/k mod order */\n                sp_256_mont_inv_order_8(kInv, k, tmp);\n            sp_256_norm_8(kInv);\n\n            /* s = r * x + e */\n                sp_256_mul_8(x, x, r);\n            err = sp_256_mod_8(x, x, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_8(x);\n            carry = sp_256_add_8(s, e, x);\n            sp_256_cond_sub_8(s, s, p256_order, 0 - carry);\n            sp_256_norm_8(s);\n            c = sp_256_cmp_8(s, p256_order);\n            sp_256_cond_sub_8(s, s, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_8(s);\n\n            /* s = s * k^-1 mod order */\n                sp_256_mont_mul_order_8(s, s, kInv);\n            sp_256_norm_8(s);\n\n            /* Check that signature is usable. */\n            if (sp_256_iszero_8(s) == 0) {\n                break;\n            }\n        }\n    }\n\n    if (i == 0) {\n        err = RNG_FAILURE_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(r, rm);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(s, sm);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XMEMSET(d, 0, sizeof(sp_digit) * 8 * 8);\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    XMEMSET(e, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(x, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(k, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 8U);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_SIGN */\n\n#ifdef HAVE_ECC_VERIFY\n/* Verify the signature values with the hash and public key.\n *   e = Truncate(hash, 256)\n *   u1 = e/s mod order\n *   u2 = r/s mod order\n *   r == (u1.G + u2.Q)->x mod order\n * Optimization: Leave point in projective form.\n *   (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')\n *   (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,\n    mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit u1d[2*8];\n    sp_digit u2d[2*8];\n    sp_digit sd[2*8];\n    sp_digit tmpd[2*8 * 5];\n    sp_point p1d;\n    sp_point p2d;\n#endif\n    sp_digit* u1 = NULL;\n    sp_digit* u2 = NULL;\n    sp_digit* s = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* p1;\n    sp_point* p2 = NULL;\n    sp_digit carry;\n    int32_t c;\n    int err;\n\n    err = sp_ecc_point_new(heap, p1d, p1);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p2d, p2);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        u1  = d + 0 * 8;\n        u2  = d + 2 * 8;\n        s   = d + 4 * 8;\n        tmp = d + 6 * 8;\n#else\n        u1 = u1d;\n        u2 = u2d;\n        s  = sd;\n        tmp = tmpd;\n#endif\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(u1, 8, hash, (int)hashLen);\n        sp_256_from_mp(u2, 8, r);\n        sp_256_from_mp(s, 8, sm);\n        sp_256_from_mp(p2->x, 8, pX);\n        sp_256_from_mp(p2->y, 8, pY);\n        sp_256_from_mp(p2->z, 8, pZ);\n\n        {\n            sp_256_mul_8(s, s, p256_norm_order);\n        }\n        err = sp_256_mod_8(s, s, p256_order);\n    }\n    if (err == MP_OKAY) {\n        sp_256_norm_8(s);\n        {\n            sp_256_mont_inv_order_8(s, s, tmp);\n            sp_256_mont_mul_order_8(u1, u1, s);\n            sp_256_mont_mul_order_8(u2, u2, s);\n        }\n\n            err = sp_256_ecc_mulmod_base_8(p1, u1, 0, heap);\n    }\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_8(p2, p2, u2, 0, heap);\n    }\n\n    if (err == MP_OKAY) {\n        {\n            sp_256_proj_point_add_8(p1, p1, p2, tmp);\n            if (sp_256_iszero_8(p1->z)) {\n                if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) {\n                    sp_256_proj_point_dbl_8(p1, p2, tmp);\n                }\n                else {\n                    /* Y ordinate is not used from here - don't set. */\n                    p1->x[0] = 0;\n                    p1->x[1] = 0;\n                    p1->x[2] = 0;\n                    p1->x[3] = 0;\n                    p1->x[4] = 0;\n                    p1->x[5] = 0;\n                    p1->x[6] = 0;\n                    p1->x[7] = 0;\n                    XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));\n                }\n            }\n        }\n\n        /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */\n        /* Reload r and convert to Montgomery form. */\n        sp_256_from_mp(u2, 8, r);\n        err = sp_256_mod_mul_norm_8(u2, u2, p256_mod);\n    }\n\n    if (err == MP_OKAY) {\n        /* u1 = r.z'.z' mod prime */\n        sp_256_mont_sqr_8(p1->z, p1->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(u1, u2, p1->z, p256_mod, p256_mp_mod);\n        *res = (int)(sp_256_cmp_8(p1->x, u1) == 0);\n        if (*res == 0) {\n            /* Reload r and add order. */\n            sp_256_from_mp(u2, 8, r);\n            carry = sp_256_add_8(u2, u2, p256_order);\n            /* Carry means result is greater than mod and is not valid. */\n            if (carry == 0) {\n                sp_256_norm_8(u2);\n\n                /* Compare with mod and if greater or equal then not valid. */\n                c = sp_256_cmp_8(u2, p256_mod);\n                if (c < 0) {\n                    /* Convert to Montogomery form */\n                    err = sp_256_mod_mul_norm_8(u2, u2, p256_mod);\n                    if (err == MP_OKAY) {\n                        /* u1 = (r + 1*order).z'.z' mod prime */\n                        sp_256_mont_mul_8(u1, u2, p1->z, p256_mod,\n                                                                  p256_mp_mod);\n                        *res = (int)(sp_256_cmp_8(p1->x, u1) == 0);\n                    }\n                }\n            }\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n#endif\n    sp_ecc_point_free(p1, 0, heap);\n    sp_ecc_point_free(p2, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_VERIFY */\n\n#ifdef HAVE_ECC_CHECK_KEY\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * point  EC point.\n * heap   Heap to use if dynamically allocating.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nstatic int sp_256_ecc_is_point_8(sp_point* point, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit t1d[2*8];\n    sp_digit t2d[2*8];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8 * 4, heap, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 8;\n        t2 = d + 2 * 8;\n#else\n        (void)heap;\n\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        sp_256_sqr_8(t1, point->y);\n        (void)sp_256_mod_8(t1, t1, p256_mod);\n        sp_256_sqr_8(t2, point->x);\n        (void)sp_256_mod_8(t2, t2, p256_mod);\n        sp_256_mul_8(t2, t2, point->x);\n        (void)sp_256_mod_8(t2, t2, p256_mod);\n        (void)sp_256_sub_8(t2, p256_mod, t2);\n        sp_256_mont_add_8(t1, t1, t2, p256_mod);\n\n        sp_256_mont_add_8(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_8(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_8(t1, t1, point->x, p256_mod);\n\n        if (sp_256_cmp_8(t1, p256_b) != 0) {\n            err = MP_VAL;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * pX  X ordinate of EC point.\n * pY  Y ordinate of EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nint sp_ecc_is_point_256(mp_int* pX, mp_int* pY)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point pubd;\n#endif\n    sp_point* pub;\n    byte one[1] = { 1 };\n    int err;\n\n    err = sp_ecc_point_new(NULL, pubd, pub);\n    if (err == MP_OKAY) {\n        sp_256_from_mp(pub->x, 8, pX);\n        sp_256_from_mp(pub->y, 8, pY);\n        sp_256_from_bin(pub->z, 8, one, (int)sizeof(one));\n\n        err = sp_256_ecc_is_point_8(pub, NULL);\n    }\n\n    sp_ecc_point_free(pub, 0, NULL);\n\n    return err;\n}\n\n/* Check that the private scalar generates the EC point (px, py), the point is\n * on the curve and the point has the correct order.\n *\n * pX     X ordinate of EC point.\n * pY     Y ordinate of EC point.\n * privm  Private scalar that generates EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve, ECC_INF_E if the point does not have the correct order,\n * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and\n * MP_OKAY otherwise.\n */\nint sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit privd[8];\n    sp_point pubd;\n    sp_point pd;\n#endif\n    sp_digit* priv = NULL;\n    sp_point* pub;\n    sp_point* p = NULL;\n    byte one[1] = { 1 };\n    int err;\n\n    err = sp_ecc_point_new(heap, pubd, pub);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (priv == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK))\n        priv = privd;\n#endif\n\n        sp_256_from_mp(pub->x, 8, pX);\n        sp_256_from_mp(pub->y, 8, pY);\n        sp_256_from_bin(pub->z, 8, one, (int)sizeof(one));\n        sp_256_from_mp(priv, 8, privm);\n\n        /* Check point at infinitiy. */\n        if ((sp_256_iszero_8(pub->x) != 0) &&\n            (sp_256_iszero_8(pub->y) != 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check range of X and Y */\n        if (sp_256_cmp_8(pub->x, p256_mod) >= 0 ||\n            sp_256_cmp_8(pub->y, p256_mod) >= 0) {\n            err = ECC_OUT_OF_RANGE_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check point is on curve */\n        err = sp_256_ecc_is_point_8(pub, heap);\n    }\n\n    if (err == MP_OKAY) {\n        /* Point * order = infinity */\n            err = sp_256_ecc_mulmod_8(p, pub, p256_order, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is infinity */\n        if ((sp_256_iszero_8(p->x) == 0) ||\n            (sp_256_iszero_8(p->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Base * private = point */\n            err = sp_256_ecc_mulmod_base_8(p, priv, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is public key */\n        if (sp_256_cmp_8(p->x, pub->x) != 0 ||\n            sp_256_cmp_8(p->y, pub->y) != 0) {\n            err = ECC_PRIV_KEY_E;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (priv != NULL) {\n        XFREE(priv, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(pub, 0, heap);\n\n    return err;\n}\n#endif\n#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL\n/* Add two projective EC points together.\n * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)\n *\n * pX   First EC point's X ordinate.\n * pY   First EC point's Y ordinate.\n * pZ   First EC point's Z ordinate.\n * qX   Second EC point's X ordinate.\n * qY   Second EC point's Y ordinate.\n * qZ   Second EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* qX, mp_int* qY, mp_int* qZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 8 * 5];\n    sp_point pd;\n    sp_point qd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    sp_point* q = NULL;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(NULL, qd, q);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 8, pX);\n        sp_256_from_mp(p->y, 8, pY);\n        sp_256_from_mp(p->z, 8, pZ);\n        sp_256_from_mp(q->x, 8, qX);\n        sp_256_from_mp(q->y, 8, qY);\n        sp_256_from_mp(q->z, 8, qZ);\n\n            sp_256_proj_point_add_8(p, p, q, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(q, 0, NULL);\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Double a projective EC point.\n * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 8 * 2];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 2, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 8, pX);\n        sp_256_from_mp(p->y, 8, pY);\n        sp_256_from_mp(p->z, 8, pZ);\n\n            sp_256_proj_point_dbl_8(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Map a projective EC point to affine in place.\n * pZ will be one.\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 8 * 4];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 4, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 8, pX);\n        sp_256_from_mp(p->y, 8, pY);\n        sp_256_from_mp(p->z, 8, pZ);\n\n        sp_256_map_8(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, pX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */\n#ifdef HAVE_COMP_KEY\n/* Find the square root of a number mod the prime of the curve.\n *\n * y  The number to operate on and the result.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nstatic int sp_256_mont_sqrt_8(sp_digit* y)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit t1d[2 * 8];\n    sp_digit t2d[2 * 8];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 8, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 8;\n        t2 = d + 2 * 8;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        {\n            /* t2 = y ^ 0x2 */\n            sp_256_mont_sqr_8(t2, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0x3 */\n            sp_256_mont_mul_8(t1, t2, y, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xc */\n            sp_256_mont_sqr_n_8(t2, t1, 2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xf */\n            sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xf0 */\n            sp_256_mont_sqr_n_8(t2, t1, 4, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xff */\n            sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xff00 */\n            sp_256_mont_sqr_n_8(t2, t1, 8, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffff */\n            sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xffff0000 */\n            sp_256_mont_sqr_n_8(t2, t1, 16, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff */\n            sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000000 */\n            sp_256_mont_sqr_n_8(t1, t1, 32, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001 */\n            sp_256_mont_mul_8(t1, t1, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */\n            sp_256_mont_sqr_n_8(t1, t1, 96, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */\n            sp_256_mont_mul_8(t1, t1, y, p256_mod, p256_mp_mod);\n            sp_256_mont_sqr_n_8(y, t1, 94, p256_mod, p256_mp_mod);\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Uncompress the point given the X ordinate.\n *\n * xm    X ordinate.\n * odd   Whether the Y ordinate is odd.\n * ym    Calculated Y ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit xd[2 * 8];\n    sp_digit yd[2 * 8];\n#endif\n    sp_digit* x = NULL;\n    sp_digit* y = NULL;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 8, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        x = d + 0 * 8;\n        y = d + 2 * 8;\n#else\n        x = xd;\n        y = yd;\n#endif\n\n        sp_256_from_mp(x, 8, xm);\n        err = sp_256_mod_mul_norm_8(x, x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        /* y = x^3 */\n        {\n            sp_256_mont_sqr_8(y, x, p256_mod, p256_mp_mod);\n            sp_256_mont_mul_8(y, y, x, p256_mod, p256_mp_mod);\n        }\n        /* y = x^3 - 3x */\n        sp_256_mont_sub_8(y, y, x, p256_mod);\n        sp_256_mont_sub_8(y, y, x, p256_mod);\n        sp_256_mont_sub_8(y, y, x, p256_mod);\n        /* y = x^3 - 3x + b */\n        err = sp_256_mod_mul_norm_8(x, p256_b, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        sp_256_mont_add_8(y, y, x, p256_mod);\n        /* y = sqrt(x^3 - 3x + b) */\n        err = sp_256_mont_sqrt_8(y);\n    }\n    if (err == MP_OKAY) {\n        XMEMSET(y + 8, 0, 8U * sizeof(sp_digit));\n        sp_256_mont_reduce_8(y, p256_mod, p256_mp_mod);\n        if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {\n            sp_256_mont_sub_8(y, p256_mod, y, p256_mod);\n        }\n\n        err = sp_256_to_mp(y, ym);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n#endif\n#endif /* !WOLFSSL_SP_NO_256 */\n#endif /* WOLFSSL_HAVE_SP_ECC */\n#endif /* WOLFSSL_SP_ARM32_ASM */\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */\n"
  },
  {
    "path": "src/wolfcrypt/src/sp_arm64.c",
    "content": "/* sp.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/* Implementation by Sean Parkinson. */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/cpuid.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \\\n                                    defined(WOLFSSL_HAVE_SP_ECC)\n\n#ifdef RSA_LOW_MEM\n#ifndef WOLFSSL_SP_SMALL\n#define WOLFSSL_SP_SMALL\n#endif\n#endif\n\n#include <wolfssl/wolfcrypt/sp.h>\n\n#ifdef WOLFSSL_SP_ARM64_ASM\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n#ifndef WOLFSSL_SP_NO_2048\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 56U) {\n            r[j] &= 0xffffffffffffffffl;\n            s = 64U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 64\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 64\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffffffffffffl;\n        s = 64U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 64U) <= (word32)DIGIT_BIT) {\n            s += 64U;\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 64) {\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 64 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 256\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_2048_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 2048 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<32 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 64) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 64);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_digit tmp[8];\n\n    __asm__ __volatile__ (\n        \"ldp\tx8, x9, [%[a], 0]\\n\\t\"\n        \"ldp\tx10, x11, [%[a], 16]\\n\\t\"\n        \"ldp\tx12, x13, [%[a], 32]\\n\\t\"\n        \"ldp\tx14, x15, [%[a], 48]\\n\\t\"\n        \"ldp\tx16, x17, [%[b], 0]\\n\\t\"\n        \"ldp\tx19, x20, [%[b], 16]\\n\\t\"\n        \"ldp\tx21, x22, [%[b], 32]\\n\\t\"\n        \"ldp\tx23, x24, [%[b], 48]\\n\\t\"\n        \"#  A[0] * B[0]\\n\\t\"\n        \"mul\tx3, x8, x16\\n\\t\"\n        \"umulh\tx4, x8, x16\\n\\t\"\n        \"str\tx3, [%[tmp]]\\n\\t\"\n        \"#  A[0] * B[1]\\n\\t\"\n        \"mul\tx6, x8, x17\\n\\t\"\n        \"umulh\tx7, x8, x17\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adc\tx5, xzr, x7\\n\\t\"\n        \"#  A[1] * B[0]\\n\\t\"\n        \"mul\tx6, x9, x16\\n\\t\"\n        \"umulh\tx7, x9, x16\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 8]\\n\\t\"\n        \"#  A[0] * B[2]\\n\\t\"\n        \"mul\tx6, x8, x19\\n\\t\"\n        \"umulh\tx7, x8, x19\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[1]\\n\\t\"\n        \"mul\tx6, x9, x17\\n\\t\"\n        \"umulh\tx7, x9, x17\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[0]\\n\\t\"\n        \"mul\tx6, x10, x16\\n\\t\"\n        \"umulh\tx7, x10, x16\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 16]\\n\\t\"\n        \"#  A[0] * B[3]\\n\\t\"\n        \"mul\tx6, x8, x20\\n\\t\"\n        \"umulh\tx7, x8, x20\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[2]\\n\\t\"\n        \"mul\tx6, x9, x19\\n\\t\"\n        \"umulh\tx7, x9, x19\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[1]\\n\\t\"\n        \"mul\tx6, x10, x17\\n\\t\"\n        \"umulh\tx7, x10, x17\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[0]\\n\\t\"\n        \"mul\tx6, x11, x16\\n\\t\"\n        \"umulh\tx7, x11, x16\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 24]\\n\\t\"\n        \"#  A[0] * B[4]\\n\\t\"\n        \"mul\tx6, x8, x21\\n\\t\"\n        \"umulh\tx7, x8, x21\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[3]\\n\\t\"\n        \"mul\tx6, x9, x20\\n\\t\"\n        \"umulh\tx7, x9, x20\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[2]\\n\\t\"\n        \"mul\tx6, x10, x19\\n\\t\"\n        \"umulh\tx7, x10, x19\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[1]\\n\\t\"\n        \"mul\tx6, x11, x17\\n\\t\"\n        \"umulh\tx7, x11, x17\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[0]\\n\\t\"\n        \"mul\tx6, x12, x16\\n\\t\"\n        \"umulh\tx7, x12, x16\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 32]\\n\\t\"\n        \"#  A[0] * B[5]\\n\\t\"\n        \"mul\tx6, x8, x22\\n\\t\"\n        \"umulh\tx7, x8, x22\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[4]\\n\\t\"\n        \"mul\tx6, x9, x21\\n\\t\"\n        \"umulh\tx7, x9, x21\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[3]\\n\\t\"\n        \"mul\tx6, x10, x20\\n\\t\"\n        \"umulh\tx7, x10, x20\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[2]\\n\\t\"\n        \"mul\tx6, x11, x19\\n\\t\"\n        \"umulh\tx7, x11, x19\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[1]\\n\\t\"\n        \"mul\tx6, x12, x17\\n\\t\"\n        \"umulh\tx7, x12, x17\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[0]\\n\\t\"\n        \"mul\tx6, x13, x16\\n\\t\"\n        \"umulh\tx7, x13, x16\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 40]\\n\\t\"\n        \"#  A[0] * B[6]\\n\\t\"\n        \"mul\tx6, x8, x23\\n\\t\"\n        \"umulh\tx7, x8, x23\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[5]\\n\\t\"\n        \"mul\tx6, x9, x22\\n\\t\"\n        \"umulh\tx7, x9, x22\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[4]\\n\\t\"\n        \"mul\tx6, x10, x21\\n\\t\"\n        \"umulh\tx7, x10, x21\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[3]\\n\\t\"\n        \"mul\tx6, x11, x20\\n\\t\"\n        \"umulh\tx7, x11, x20\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[2]\\n\\t\"\n        \"mul\tx6, x12, x19\\n\\t\"\n        \"umulh\tx7, x12, x19\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[1]\\n\\t\"\n        \"mul\tx6, x13, x17\\n\\t\"\n        \"umulh\tx7, x13, x17\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[0]\\n\\t\"\n        \"mul\tx6, x14, x16\\n\\t\"\n        \"umulh\tx7, x14, x16\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 48]\\n\\t\"\n        \"#  A[0] * B[7]\\n\\t\"\n        \"mul\tx6, x8, x24\\n\\t\"\n        \"umulh\tx7, x8, x24\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[6]\\n\\t\"\n        \"mul\tx6, x9, x23\\n\\t\"\n        \"umulh\tx7, x9, x23\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[5]\\n\\t\"\n        \"mul\tx6, x10, x22\\n\\t\"\n        \"umulh\tx7, x10, x22\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[4]\\n\\t\"\n        \"mul\tx6, x11, x21\\n\\t\"\n        \"umulh\tx7, x11, x21\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[3]\\n\\t\"\n        \"mul\tx6, x12, x20\\n\\t\"\n        \"umulh\tx7, x12, x20\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[2]\\n\\t\"\n        \"mul\tx6, x13, x19\\n\\t\"\n        \"umulh\tx7, x13, x19\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[1]\\n\\t\"\n        \"mul\tx6, x14, x17\\n\\t\"\n        \"umulh\tx7, x14, x17\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[0]\\n\\t\"\n        \"mul\tx6, x15, x16\\n\\t\"\n        \"umulh\tx7, x15, x16\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 56]\\n\\t\"\n        \"#  A[1] * B[7]\\n\\t\"\n        \"mul\tx6, x9, x24\\n\\t\"\n        \"umulh\tx7, x9, x24\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[2] * B[6]\\n\\t\"\n        \"mul\tx6, x10, x23\\n\\t\"\n        \"umulh\tx7, x10, x23\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[5]\\n\\t\"\n        \"mul\tx6, x11, x22\\n\\t\"\n        \"umulh\tx7, x11, x22\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[4]\\n\\t\"\n        \"mul\tx6, x12, x21\\n\\t\"\n        \"umulh\tx7, x12, x21\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[3]\\n\\t\"\n        \"mul\tx6, x13, x20\\n\\t\"\n        \"umulh\tx7, x13, x20\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[2]\\n\\t\"\n        \"mul\tx6, x14, x19\\n\\t\"\n        \"umulh\tx7, x14, x19\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[1]\\n\\t\"\n        \"mul\tx6, x15, x17\\n\\t\"\n        \"umulh\tx7, x15, x17\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 64]\\n\\t\"\n        \"#  A[2] * B[7]\\n\\t\"\n        \"mul\tx6, x10, x24\\n\\t\"\n        \"umulh\tx7, x10, x24\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[3] * B[6]\\n\\t\"\n        \"mul\tx6, x11, x23\\n\\t\"\n        \"umulh\tx7, x11, x23\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[5]\\n\\t\"\n        \"mul\tx6, x12, x22\\n\\t\"\n        \"umulh\tx7, x12, x22\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[4]\\n\\t\"\n        \"mul\tx6, x13, x21\\n\\t\"\n        \"umulh\tx7, x13, x21\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[3]\\n\\t\"\n        \"mul\tx6, x14, x20\\n\\t\"\n        \"umulh\tx7, x14, x20\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[2]\\n\\t\"\n        \"mul\tx6, x15, x19\\n\\t\"\n        \"umulh\tx7, x15, x19\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 72]\\n\\t\"\n        \"#  A[3] * B[7]\\n\\t\"\n        \"mul\tx6, x11, x24\\n\\t\"\n        \"umulh\tx7, x11, x24\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[4] * B[6]\\n\\t\"\n        \"mul\tx6, x12, x23\\n\\t\"\n        \"umulh\tx7, x12, x23\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[5]\\n\\t\"\n        \"mul\tx6, x13, x22\\n\\t\"\n        \"umulh\tx7, x13, x22\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[4]\\n\\t\"\n        \"mul\tx6, x14, x21\\n\\t\"\n        \"umulh\tx7, x14, x21\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[3]\\n\\t\"\n        \"mul\tx6, x15, x20\\n\\t\"\n        \"umulh\tx7, x15, x20\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 80]\\n\\t\"\n        \"#  A[4] * B[7]\\n\\t\"\n        \"mul\tx6, x12, x24\\n\\t\"\n        \"umulh\tx7, x12, x24\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[5] * B[6]\\n\\t\"\n        \"mul\tx6, x13, x23\\n\\t\"\n        \"umulh\tx7, x13, x23\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[5]\\n\\t\"\n        \"mul\tx6, x14, x22\\n\\t\"\n        \"umulh\tx7, x14, x22\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[4]\\n\\t\"\n        \"mul\tx6, x15, x21\\n\\t\"\n        \"umulh\tx7, x15, x21\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 88]\\n\\t\"\n        \"#  A[5] * B[7]\\n\\t\"\n        \"mul\tx6, x13, x24\\n\\t\"\n        \"umulh\tx7, x13, x24\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[6] * B[6]\\n\\t\"\n        \"mul\tx6, x14, x23\\n\\t\"\n        \"umulh\tx7, x14, x23\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[5]\\n\\t\"\n        \"mul\tx6, x15, x22\\n\\t\"\n        \"umulh\tx7, x15, x22\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 96]\\n\\t\"\n        \"#  A[6] * B[7]\\n\\t\"\n        \"mul\tx6, x14, x24\\n\\t\"\n        \"umulh\tx7, x14, x24\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[7] * B[6]\\n\\t\"\n        \"mul\tx6, x15, x23\\n\\t\"\n        \"umulh\tx7, x15, x23\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 104]\\n\\t\"\n        \"#  A[7] * B[7]\\n\\t\"\n        \"mul\tx6, x15, x24\\n\\t\"\n        \"umulh\tx7, x15, x24\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"stp\tx5, x3, [%[r], 112]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [tmp] \"r\" (tmp)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x8\", \"x9\", \"x10\", \"x11\", \"x12\", \"x13\", \"x14\", \"x15\", \"x16\", \"x17\", \"x19\", \"x20\", \"x21\", \"x22\", \"x23\", \"x24\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_2048_sqr_8(sp_digit* r, const sp_digit* a)\n{\n    sp_digit tmp[8];\n\n    __asm__ __volatile__ (\n        \"ldp\tx10, x11, [%[a], 0]\\n\\t\"\n        \"ldp\tx12, x13, [%[a], 16]\\n\\t\"\n        \"ldp\tx14, x15, [%[a], 32]\\n\\t\"\n        \"ldp\tx16, x17, [%[a], 48]\\n\\t\"\n        \"#  A[0] * A[0]\\n\\t\"\n        \"mul\tx2, x10, x10\\n\\t\"\n        \"umulh\tx3, x10, x10\\n\\t\"\n        \"str\tx2, [%[tmp]]\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"#  A[0] * A[1]\\n\\t\"\n        \"mul\tx8, x10, x11\\n\\t\"\n        \"umulh\tx9, x10, x11\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, xzr, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 8]\\n\\t\"\n        \"#  A[0] * A[2]\\n\\t\"\n        \"mul\tx8, x10, x12\\n\\t\"\n        \"umulh\tx9, x10, x12\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[1] * A[1]\\n\\t\"\n        \"mul\tx8, x11, x11\\n\\t\"\n        \"umulh\tx9, x11, x11\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 16]\\n\\t\"\n        \"#  A[0] * A[3]\\n\\t\"\n        \"mul\tx8, x10, x13\\n\\t\"\n        \"umulh\tx9, x10, x13\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[1] * A[2]\\n\\t\"\n        \"mul\tx8, x11, x12\\n\\t\"\n        \"umulh\tx9, x11, x12\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx2, [%[tmp], 24]\\n\\t\"\n        \"#  A[0] * A[4]\\n\\t\"\n        \"mul\tx8, x10, x14\\n\\t\"\n        \"umulh\tx9, x10, x14\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, xzr, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"#  A[1] * A[3]\\n\\t\"\n        \"mul\tx8, x11, x13\\n\\t\"\n        \"umulh\tx9, x11, x13\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"#  A[2] * A[2]\\n\\t\"\n        \"mul\tx8, x12, x12\\n\\t\"\n        \"umulh\tx9, x12, x12\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 32]\\n\\t\"\n        \"#  A[0] * A[5]\\n\\t\"\n        \"mul\tx5, x10, x15\\n\\t\"\n        \"umulh\tx6, x10, x15\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[4]\\n\\t\"\n        \"mul\tx8, x11, x14\\n\\t\"\n        \"umulh\tx9, x11, x14\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[3]\\n\\t\"\n        \"mul\tx8, x12, x13\\n\\t\"\n        \"umulh\tx9, x12, x13\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[tmp], 40]\\n\\t\"\n        \"#  A[0] * A[6]\\n\\t\"\n        \"mul\tx5, x10, x16\\n\\t\"\n        \"umulh\tx6, x10, x16\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[5]\\n\\t\"\n        \"mul\tx8, x11, x15\\n\\t\"\n        \"umulh\tx9, x11, x15\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[4]\\n\\t\"\n        \"mul\tx8, x12, x14\\n\\t\"\n        \"umulh\tx9, x12, x14\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[3]\\n\\t\"\n        \"mul\tx8, x13, x13\\n\\t\"\n        \"umulh\tx9, x13, x13\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[tmp], 48]\\n\\t\"\n        \"#  A[0] * A[7]\\n\\t\"\n        \"mul\tx5, x10, x17\\n\\t\"\n        \"umulh\tx6, x10, x17\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[6]\\n\\t\"\n        \"mul\tx8, x11, x16\\n\\t\"\n        \"umulh\tx9, x11, x16\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[5]\\n\\t\"\n        \"mul\tx8, x12, x15\\n\\t\"\n        \"umulh\tx9, x12, x15\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[4]\\n\\t\"\n        \"mul\tx8, x13, x14\\n\\t\"\n        \"umulh\tx9, x13, x14\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[tmp], 56]\\n\\t\"\n        \"#  A[1] * A[7]\\n\\t\"\n        \"mul\tx5, x11, x17\\n\\t\"\n        \"umulh\tx6, x11, x17\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[2] * A[6]\\n\\t\"\n        \"mul\tx8, x12, x16\\n\\t\"\n        \"umulh\tx9, x12, x16\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[5]\\n\\t\"\n        \"mul\tx8, x13, x15\\n\\t\"\n        \"umulh\tx9, x13, x15\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[4]\\n\\t\"\n        \"mul\tx8, x14, x14\\n\\t\"\n        \"umulh\tx9, x14, x14\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[r], 64]\\n\\t\"\n        \"#  A[2] * A[7]\\n\\t\"\n        \"mul\tx5, x12, x17\\n\\t\"\n        \"umulh\tx6, x12, x17\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[3] * A[6]\\n\\t\"\n        \"mul\tx8, x13, x16\\n\\t\"\n        \"umulh\tx9, x13, x16\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[5]\\n\\t\"\n        \"mul\tx8, x14, x15\\n\\t\"\n        \"umulh\tx9, x14, x15\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[r], 72]\\n\\t\"\n        \"#  A[3] * A[7]\\n\\t\"\n        \"mul\tx8, x13, x17\\n\\t\"\n        \"umulh\tx9, x13, x17\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, xzr, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"#  A[4] * A[6]\\n\\t\"\n        \"mul\tx8, x14, x16\\n\\t\"\n        \"umulh\tx9, x14, x16\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"#  A[5] * A[5]\\n\\t\"\n        \"mul\tx8, x15, x15\\n\\t\"\n        \"umulh\tx9, x15, x15\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"str\tx3, [%[r], 80]\\n\\t\"\n        \"#  A[4] * A[7]\\n\\t\"\n        \"mul\tx8, x14, x17\\n\\t\"\n        \"umulh\tx9, x14, x17\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * A[6]\\n\\t\"\n        \"mul\tx8, x15, x16\\n\\t\"\n        \"umulh\tx9, x15, x16\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 88]\\n\\t\"\n        \"#  A[5] * A[7]\\n\\t\"\n        \"mul\tx8, x15, x17\\n\\t\"\n        \"umulh\tx9, x15, x17\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * A[6]\\n\\t\"\n        \"mul\tx8, x16, x16\\n\\t\"\n        \"umulh\tx9, x16, x16\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx2, [%[r], 96]\\n\\t\"\n        \"#  A[6] * A[7]\\n\\t\"\n        \"mul\tx8, x16, x17\\n\\t\"\n        \"umulh\tx9, x16, x17\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, xzr, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"str\tx3, [%[r], 104]\\n\\t\"\n        \"#  A[7] * A[7]\\n\\t\"\n        \"mul\tx8, x17, x17\\n\\t\"\n        \"umulh\tx9, x17, x17\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adc\tx2, x2, x9\\n\\t\"\n        \"stp\tx4, x2, [%[r], 112]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [tmp] \"r\" (tmp)\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x8\", \"x9\", \"x10\", \"x5\", \"x6\", \"x7\", \"x10\", \"x11\", \"x12\", \"x13\", \"x14\", \"x15\", \"x16\", \"x17\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_add_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx3, x4, [%[a], 0]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 16]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 0]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 16]\\n\\t\"\n        \"adds\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 0]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 16]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 32]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 48]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 32]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 48]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 32]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 48]\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_sub_in_place_16(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx2, x3, [%[a], 0]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 16]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 0]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 16]\\n\\t\"\n        \"subs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 0]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 16]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 32]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 48]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 32]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 48]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 32]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 48]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 64]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 80]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 64]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 80]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 64]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 80]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 96]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 112]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 96]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 112]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 96]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 112]\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_add_16(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx3, x4, [%[a], 0]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 16]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 0]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 16]\\n\\t\"\n        \"adds\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 0]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 16]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 32]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 48]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 32]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 48]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 32]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 48]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 64]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 80]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 64]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 80]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 64]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 80]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 96]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 112]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 96]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 112]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 96]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 112]\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_8(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<8; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    r[0] = a[0] & m;\n    r[1] = a[1] & m;\n    r[2] = a[2] & m;\n    r[3] = a[3] & m;\n    r[4] = a[4] & m;\n    r[5] = a[5] & m;\n    r[6] = a[6] & m;\n    r[7] = a[7] & m;\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_16(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[16];\n    sp_digit a1[8];\n    sp_digit b1[8];\n    sp_digit z2[16];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_8(a1, a, &a[8]);\n    cb = sp_2048_add_8(b1, b, &b[8]);\n    u  = ca & cb;\n    sp_2048_mul_8(z1, a1, b1);\n    sp_2048_mul_8(z2, &a[8], &b[8]);\n    sp_2048_mul_8(z0, a, b);\n    sp_2048_mask_8(r + 16, a1, 0 - cb);\n    sp_2048_mask_8(b1, b1, 0 - ca);\n    u += sp_2048_add_8(r + 16, r + 16, b1);\n    u += sp_2048_sub_in_place_16(z1, z2);\n    u += sp_2048_sub_in_place_16(z1, z0);\n    u += sp_2048_add_16(r + 8, r + 8, z1);\n    r[24] = u;\n    XMEMSET(r + 24 + 1, 0, sizeof(sp_digit) * (8 - 1));\n    (void)sp_2048_add_16(r + 16, r + 16, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_16(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[16];\n    sp_digit z1[16];\n    sp_digit a1[8];\n    sp_digit u;\n\n    u = sp_2048_add_8(a1, a, &a[8]);\n    sp_2048_sqr_8(z1, a1);\n    sp_2048_sqr_8(z2, &a[8]);\n    sp_2048_sqr_8(z0, a);\n    sp_2048_mask_8(r + 16, a1, 0 - u);\n    u += sp_2048_add_8(r + 16, r + 16, r + 16);\n    u += sp_2048_sub_in_place_16(z1, z2);\n    u += sp_2048_sub_in_place_16(z1, z0);\n    u += sp_2048_add_16(r + 8, r + 8, z1);\n    r[24] = u;\n    XMEMSET(r + 24 + 1, 0, sizeof(sp_digit) * (8 - 1));\n    (void)sp_2048_add_16(r + 16, r + 16, z2);\n}\n\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_sub_in_place_32(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx2, x3, [%[a], 0]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 16]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 0]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 16]\\n\\t\"\n        \"subs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 0]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 16]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 32]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 48]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 32]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 48]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 32]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 48]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 64]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 80]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 64]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 80]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 64]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 80]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 96]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 112]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 96]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 112]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 96]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 112]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 128]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 144]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 128]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 144]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 128]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 144]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 160]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 176]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 160]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 176]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 160]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 176]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 192]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 208]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 192]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 208]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 192]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 208]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 224]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 240]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 224]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 240]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 224]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 240]\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx3, x4, [%[a], 0]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 16]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 0]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 16]\\n\\t\"\n        \"adds\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 0]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 16]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 32]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 48]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 32]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 48]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 32]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 48]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 64]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 80]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 64]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 80]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 64]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 80]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 96]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 112]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 96]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 112]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 96]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 112]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 128]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 144]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 128]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 144]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 128]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 144]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 160]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 176]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 160]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 176]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 160]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 176]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 192]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 208]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 192]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 208]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 192]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 208]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 224]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 240]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 224]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 240]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 224]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 240]\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_16(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<16; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 16; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[32];\n    sp_digit a1[16];\n    sp_digit b1[16];\n    sp_digit z2[32];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_16(a1, a, &a[16]);\n    cb = sp_2048_add_16(b1, b, &b[16]);\n    u  = ca & cb;\n    sp_2048_mul_16(z1, a1, b1);\n    sp_2048_mul_16(z2, &a[16], &b[16]);\n    sp_2048_mul_16(z0, a, b);\n    sp_2048_mask_16(r + 32, a1, 0 - cb);\n    sp_2048_mask_16(b1, b1, 0 - ca);\n    u += sp_2048_add_16(r + 32, r + 32, b1);\n    u += sp_2048_sub_in_place_32(z1, z2);\n    u += sp_2048_sub_in_place_32(z1, z0);\n    u += sp_2048_add_32(r + 16, r + 16, z1);\n    r[48] = u;\n    XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));\n    (void)sp_2048_add_32(r + 32, r + 32, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[32];\n    sp_digit z1[32];\n    sp_digit a1[16];\n    sp_digit u;\n\n    u = sp_2048_add_16(a1, a, &a[16]);\n    sp_2048_sqr_16(z1, a1);\n    sp_2048_sqr_16(z2, &a[16]);\n    sp_2048_sqr_16(z0, a);\n    sp_2048_mask_16(r + 32, a1, 0 - u);\n    u += sp_2048_add_16(r + 32, r + 32, r + 32);\n    u += sp_2048_sub_in_place_32(z1, z2);\n    u += sp_2048_sub_in_place_32(z1, z0);\n    u += sp_2048_add_32(r + 16, r + 16, z1);\n    r[48] = u;\n    XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));\n    (void)sp_2048_add_32(r + 32, r + 32, z2);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tx11, %[a], 256\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], #-1\\n\\t\"\n        \"ldp\tx3, x4, [%[a]], #16\\n\\t\"\n        \"ldp\tx5, x6, [%[a]], #16\\n\\t\"\n        \"ldp\tx7, x8, [%[b]], #16\\n\\t\"\n        \"ldp\tx9, x10, [%[b]], #16\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r]], #16\\n\\t\"\n        \"stp\tx5, x6, [%[r]], #16\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        \"cmp\t%[a], x11\\n\\t\"\n        \"b.ne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_sub_in_place_32(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tx10, %[a], 256\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\t%[c], xzr, %[c]\\n\\t\"\n        \"ldp\tx2, x3, [%[a]]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], #16]\\n\\t\"\n        \"ldp\tx6, x7, [%[b]], #16\\n\\t\"\n        \"ldp\tx8, x9, [%[b]], #16\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a]], #16\\n\\t\"\n        \"stp\tx4, x5, [%[a]], #16\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        \"cmp\t%[a], x10\\n\\t\"\n        \"b.ne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_2048_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_digit tmp[64];\n\n    __asm__ __volatile__ (\n        \"mov\tx5, 0\\n\\t\"\n        \"mov\tx6, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"mov\tx8, 0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tx3, x5, 248\\n\\t\"\n        \"csel\tx3, xzr, x3, cc\\n\\t\"\n        \"sub\tx4, x5, x3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"ldr\tx11, [%[b], x4]\\n\\t\"\n        \"mul\tx9, x10, x11\\n\\t\"\n        \"umulh\tx10, x10, x11\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"add\tx3, x3, #8\\n\\t\"\n        \"sub\tx4, x4, #8\\n\\t\"\n        \"cmp\tx3, 256\\n\\t\"\n        \"b.eq\t3f\\n\\t\"\n        \"cmp\tx3, x5\\n\\t\"\n        \"b.le\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        \"mov\tx6, x7\\n\\t\"\n        \"mov\tx7, x8\\n\\t\"\n        \"mov\tx8, #0\\n\\t\"\n        \"add\tx5, x5, #8\\n\\t\"\n        \"cmp\tx5, 496\\n\\t\"\n        \"b.le\t1b\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_2048_sqr_32(sp_digit* r, const sp_digit* a)\n{\n    sp_digit tmp[64];\n\n    __asm__ __volatile__ (\n        \"mov\tx6, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"mov\tx8, 0\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tx3, x5, 248\\n\\t\"\n        \"csel\tx3, xzr, x3, cc\\n\\t\"\n        \"sub\tx4, x5, x3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tx4, x3\\n\\t\"\n        \"b.eq\t4f\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"ldr\tx11, [%[a], x4]\\n\\t\"\n        \"mul\tx9, x10, x11\\n\\t\"\n        \"umulh\tx10, x10, x11\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"b.al\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"mul\tx9, x10, x10\\n\\t\"\n        \"umulh\tx10, x10, x10\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\tx3, x3, #8\\n\\t\"\n        \"sub\tx4, x4, #8\\n\\t\"\n        \"cmp\tx3, 256\\n\\t\"\n        \"b.eq\t3f\\n\\t\"\n        \"cmp\tx3, x4\\n\\t\"\n        \"b.gt\t3f\\n\\t\"\n        \"cmp\tx3, x5\\n\\t\"\n        \"b.le\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        \"mov\tx6, x7\\n\\t\"\n        \"mov\tx7, x8\\n\\t\"\n        \"mov\tx8, #0\\n\\t\"\n        \"add\tx5, x5, #8\\n\\t\"\n        \"cmp\tx5, 496\\n\\t\"\n        \"b.le\t1b\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_16(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n    int i;\n\n    for (i=0; i<16; i++) {\n        r[i] = a[i] & m;\n    }\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_add_16(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tx11, %[a], 128\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], #-1\\n\\t\"\n        \"ldp\tx3, x4, [%[a]], #16\\n\\t\"\n        \"ldp\tx5, x6, [%[a]], #16\\n\\t\"\n        \"ldp\tx7, x8, [%[b]], #16\\n\\t\"\n        \"ldp\tx9, x10, [%[b]], #16\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r]], #16\\n\\t\"\n        \"stp\tx5, x6, [%[r]], #16\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        \"cmp\t%[a], x11\\n\\t\"\n        \"b.ne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_2048_sub_in_place_16(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tx10, %[a], 128\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\t%[c], xzr, %[c]\\n\\t\"\n        \"ldp\tx2, x3, [%[a]]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], #16]\\n\\t\"\n        \"ldp\tx6, x7, [%[b]], #16\\n\\t\"\n        \"ldp\tx8, x9, [%[b]], #16\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a]], #16\\n\\t\"\n        \"stp\tx4, x5, [%[a]], #16\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        \"cmp\t%[a], x10\\n\\t\"\n        \"b.ne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_2048_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_digit tmp[32];\n\n    __asm__ __volatile__ (\n        \"mov\tx5, 0\\n\\t\"\n        \"mov\tx6, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"mov\tx8, 0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tx3, x5, 120\\n\\t\"\n        \"csel\tx3, xzr, x3, cc\\n\\t\"\n        \"sub\tx4, x5, x3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"ldr\tx11, [%[b], x4]\\n\\t\"\n        \"mul\tx9, x10, x11\\n\\t\"\n        \"umulh\tx10, x10, x11\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"add\tx3, x3, #8\\n\\t\"\n        \"sub\tx4, x4, #8\\n\\t\"\n        \"cmp\tx3, 128\\n\\t\"\n        \"b.eq\t3f\\n\\t\"\n        \"cmp\tx3, x5\\n\\t\"\n        \"b.le\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        \"mov\tx6, x7\\n\\t\"\n        \"mov\tx7, x8\\n\\t\"\n        \"mov\tx8, #0\\n\\t\"\n        \"add\tx5, x5, #8\\n\\t\"\n        \"cmp\tx5, 240\\n\\t\"\n        \"b.le\t1b\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_2048_sqr_16(sp_digit* r, const sp_digit* a)\n{\n    sp_digit tmp[32];\n\n    __asm__ __volatile__ (\n        \"mov\tx6, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"mov\tx8, 0\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tx3, x5, 120\\n\\t\"\n        \"csel\tx3, xzr, x3, cc\\n\\t\"\n        \"sub\tx4, x5, x3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tx4, x3\\n\\t\"\n        \"b.eq\t4f\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"ldr\tx11, [%[a], x4]\\n\\t\"\n        \"mul\tx9, x10, x11\\n\\t\"\n        \"umulh\tx10, x10, x11\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"b.al\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"mul\tx9, x10, x10\\n\\t\"\n        \"umulh\tx10, x10, x10\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\tx3, x3, #8\\n\\t\"\n        \"sub\tx4, x4, #8\\n\\t\"\n        \"cmp\tx3, 128\\n\\t\"\n        \"b.eq\t3f\\n\\t\"\n        \"cmp\tx3, x4\\n\\t\"\n        \"b.gt\t3f\\n\\t\"\n        \"cmp\tx3, x5\\n\\t\"\n        \"b.le\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        \"mov\tx6, x7\\n\\t\"\n        \"mov\tx7, x8\\n\\t\"\n        \"mov\tx8, #0\\n\\t\"\n        \"add\tx5, x5, #8\\n\\t\"\n        \"cmp\tx5, 240\\n\\t\"\n        \"b.le\t1b\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**64 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nstatic void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tx8, [%[a]]\\n\\t\"\n        \"mul\tx5, %[b], x8\\n\\t\"\n        \"umulh\tx3, %[b], x8\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"str\tx5, [%[r]]\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"mov\tx9, #8\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tx8, [%[a], x9]\\n\\t\"\n        \"mul\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"str\tx3, [%[r], x9]\\n\\t\"\n        \"mov\tx3, x4\\n\\t\"\n        \"mov\tx4, x5\\n\\t\"\n        \"mov\tx5, #0\\n\\t\"\n        \"add\tx9, x9, #8\\n\\t\"\n        \"cmp\tx9, 256\\n\\t\"\n        \"b.lt\t1b\\n\\t\"\n        \"str\tx3, [%[r], 256]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tx8, [%[a]]\\n\\t\"\n        \"mul\tx3, %[b], x8\\n\\t\"\n        \"umulh\tx4, %[b], x8\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"str\tx3, [%[r]]\\n\\t\"\n        \"# A[1] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 8]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 8]\\n\\t\"\n        \"# A[2] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 16]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 16]\\n\\t\"\n        \"# A[3] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 24]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 24]\\n\\t\"\n        \"# A[4] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 32]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 32]\\n\\t\"\n        \"# A[5] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 40]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 40]\\n\\t\"\n        \"# A[6] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 48]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 48]\\n\\t\"\n        \"# A[7] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 56]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 56]\\n\\t\"\n        \"# A[8] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 64]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 64]\\n\\t\"\n        \"# A[9] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 72]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 72]\\n\\t\"\n        \"# A[10] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 80]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 80]\\n\\t\"\n        \"# A[11] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 88]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 88]\\n\\t\"\n        \"# A[12] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 96]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 96]\\n\\t\"\n        \"# A[13] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 104]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 104]\\n\\t\"\n        \"# A[14] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 112]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 112]\\n\\t\"\n        \"# A[15] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 120]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 120]\\n\\t\"\n        \"# A[16] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 128]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 128]\\n\\t\"\n        \"# A[17] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 136]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 136]\\n\\t\"\n        \"# A[18] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 144]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 144]\\n\\t\"\n        \"# A[19] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 152]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 152]\\n\\t\"\n        \"# A[20] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 160]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 160]\\n\\t\"\n        \"# A[21] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 168]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 168]\\n\\t\"\n        \"# A[22] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 176]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 176]\\n\\t\"\n        \"# A[23] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 184]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 184]\\n\\t\"\n        \"# A[24] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 192]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 192]\\n\\t\"\n        \"# A[25] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 200]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 200]\\n\\t\"\n        \"# A[26] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 208]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 208]\\n\\t\"\n        \"# A[27] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 216]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 216]\\n\\t\"\n        \"# A[28] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 224]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 224]\\n\\t\"\n        \"# A[29] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 232]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 232]\\n\\t\"\n        \"# A[30] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 240]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 240]\\n\\t\"\n        \"# A[31] * B\\n\\t\"\n        \"ldr\tx8, [%[a], 248]\\n\\t\"\n        \"mul\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adc\tx5, x5, x7\\n\\t\"\n        \"str\tx4, [%[r], 248]\\n\\t\"\n        \"str\tx5, [%[r], 256]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\"\n    );\n#endif\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_16(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 16);\n\n    /* r = 2^n mod m */\n    sp_2048_sub_in_place_16(r, m);\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic sp_digit sp_2048_cond_sub_16(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        sp_digit m)\n{\n    sp_digit c = 0;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tx8, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"subs\t%[c], xzr, %[c]\\n\\t\"\n        \"ldr\tx4, [%[a], x8]\\n\\t\"\n        \"ldr\tx5, [%[b], x8]\\n\\t\"\n        \"and\tx5, x5, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        \"str\tx4, [%[r], x8]\\n\\t\"\n        \"add\tx8, x8, #8\\n\\t\"\n        \"cmp\tx8, 128\\n\\t\"\n        \"b.lt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"x4\", \"x6\", \"x5\", \"x7\", \"x8\"\n    );\n#else\n    __asm__ __volatile__ (\n\n        \"ldr\t\tx4, [%[a], 0]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 8]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 0]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 8]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 0]\\n\\t\"\n        \"str\t\tx6, [%[r], 8]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 16]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 24]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 16]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 24]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 16]\\n\\t\"\n        \"str\t\tx6, [%[r], 24]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 32]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 40]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 32]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 40]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 32]\\n\\t\"\n        \"str\t\tx6, [%[r], 40]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 48]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 56]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 48]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 56]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 48]\\n\\t\"\n        \"str\t\tx6, [%[r], 56]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 64]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 72]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 64]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 72]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 64]\\n\\t\"\n        \"str\t\tx6, [%[r], 72]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 80]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 88]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 80]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 88]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 80]\\n\\t\"\n        \"str\t\tx6, [%[r], 88]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 96]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 104]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 96]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 104]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 96]\\n\\t\"\n        \"str\t\tx6, [%[r], 104]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 112]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 120]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 112]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 120]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 112]\\n\\t\"\n        \"str\t\tx6, [%[r], 120]\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"x4\", \"x6\", \"x5\", \"x7\", \"x8\"\n    );\n#endif /* WOLFSSL_SP_SMALL */\n\n    return c;\n}\n\n/* Reduce the number back to 2048 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_2048_mont_reduce_16(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"ldp       x12, x13, [%[m], 0]\\n\\t\"\n        \"ldp       x14, x15, [%[m], 16]\\n\\t\"\n        \"ldp       x16, x17, [%[m], 32]\\n\\t\"\n        \"ldp       x19, x20, [%[m], 48]\\n\\t\"\n        \"ldp       x21, x22, [%[m], 64]\\n\\t\"\n        \"ldp       x23, x24, [%[m], 80]\\n\\t\"\n        \"ldp       x25, x26, [%[m], 96]\\n\\t\"\n        \"ldp       x27, x28, [%[m], 112]\\n\\t\"\n        \"# i = 0\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"ldp\tx10, x11, [%[a], 0]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mul\tx8, %[mp], x10\\n\\t\"\n        \"# a[i+0] += m[0] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 0]\\n\\t\"\n        \"mul\t\tx6, x12, x8\\n\\t\"\n        \"umulh\tx7, x12, x8\\n\\t\"\n        \"adds\tx10, x10, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"# a[i+1] += m[1] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 8]\\n\\t\"\n        \"mul\t\tx6, x13, x8\\n\\t\"\n        \"umulh\tx7, x13, x8\\n\\t\"\n        \"adds\tx10, x11, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx10, x10, x5\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+2] += m[2] * mu\\n\\t\"\n        \"ldr\tx11, [%[a], 16]\\n\\t\"\n        \"mul\t\tx6, x14, x8\\n\\t\"\n        \"umulh\tx7, x14, x8\\n\\t\"\n        \"adds\tx11, x11, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx11, x11, x4\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+3] += m[3] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 24]\\n\\t\"\n        \"mul\t\tx6, x15, x8\\n\\t\"\n        \"umulh\tx7, x15, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 24]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+4] += m[4] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 32]\\n\\t\"\n        \"mul\t\tx6, x16, x8\\n\\t\"\n        \"umulh\tx7, x16, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 32]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+5] += m[5] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 40]\\n\\t\"\n        \"mul\t\tx6, x17, x8\\n\\t\"\n        \"umulh\tx7, x17, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 40]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+6] += m[6] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 48]\\n\\t\"\n        \"mul\t\tx6, x19, x8\\n\\t\"\n        \"umulh\tx7, x19, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 48]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+7] += m[7] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 56]\\n\\t\"\n        \"mul\t\tx6, x20, x8\\n\\t\"\n        \"umulh\tx7, x20, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 56]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+8] += m[8] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"mul\t\tx6, x21, x8\\n\\t\"\n        \"umulh\tx7, x21, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 64]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+9] += m[9] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"mul\t\tx6, x22, x8\\n\\t\"\n        \"umulh\tx7, x22, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 72]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+10] += m[10] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"mul\t\tx6, x23, x8\\n\\t\"\n        \"umulh\tx7, x23, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 80]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+11] += m[11] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"mul\t\tx6, x24, x8\\n\\t\"\n        \"umulh\tx7, x24, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 88]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+12] += m[12] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"mul\t\tx6, x25, x8\\n\\t\"\n        \"umulh\tx7, x25, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 96]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+13] += m[13] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"mul\t\tx6, x26, x8\\n\\t\"\n        \"umulh\tx7, x26, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 104]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+14] += m[14] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"mul\t\tx6, x27, x8\\n\\t\"\n        \"umulh\tx7, x27, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 112]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+15] += m[15] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"mul\tx6, x28, x8\\n\\t\"\n        \"umulh\tx7, x28, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx7, x7, %[ca]\\n\\t\"\n        \"cset  %[ca], cs\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"adcs\tx9, x9, x7\\n\\t\"\n        \"str\tx9, [%[a], 128]\\n\\t\"\n        \"adc\t%[ca], %[ca], xzr\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"add\t%[a], %[a], 8\\n\\t\"\n        \"add\tx3, x3, 8\\n\\t\"\n        \"cmp\tx3, 128\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tx10, [%[a], 0]\\n\\t\"\n        \"str\tx11, [%[a], 8]\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\", \"x12\", \"x13\", \"x14\", \"x15\", \"x16\", \"x17\", \"x19\", \"x20\", \"x21\", \"x22\", \"x23\", \"x24\", \"x25\", \"x26\", \"x27\", \"x28\"\n    );\n\n    sp_2048_cond_sub_16(a - 16, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_16(r, a, b);\n    sp_2048_mont_reduce_16(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_16(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_16(r, a);\n    sp_2048_mont_reduce_16(r, m, mp);\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nstatic void sp_2048_mul_d_16(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tx8, [%[a]]\\n\\t\"\n        \"mul\tx5, %[b], x8\\n\\t\"\n        \"umulh\tx3, %[b], x8\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"str\tx5, [%[r]]\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"mov\tx9, #8\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tx8, [%[a], x9]\\n\\t\"\n        \"mul\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"str\tx3, [%[r], x9]\\n\\t\"\n        \"mov\tx3, x4\\n\\t\"\n        \"mov\tx4, x5\\n\\t\"\n        \"mov\tx5, #0\\n\\t\"\n        \"add\tx9, x9, #8\\n\\t\"\n        \"cmp\tx9, 128\\n\\t\"\n        \"b.lt\t1b\\n\\t\"\n        \"str\tx3, [%[r], 128]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tx8, [%[a]]\\n\\t\"\n        \"mul\tx3, %[b], x8\\n\\t\"\n        \"umulh\tx4, %[b], x8\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"str\tx3, [%[r]]\\n\\t\"\n        \"# A[1] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 8]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 8]\\n\\t\"\n        \"# A[2] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 16]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 16]\\n\\t\"\n        \"# A[3] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 24]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 24]\\n\\t\"\n        \"# A[4] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 32]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 32]\\n\\t\"\n        \"# A[5] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 40]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 40]\\n\\t\"\n        \"# A[6] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 48]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 48]\\n\\t\"\n        \"# A[7] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 56]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 56]\\n\\t\"\n        \"# A[8] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 64]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 64]\\n\\t\"\n        \"# A[9] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 72]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 72]\\n\\t\"\n        \"# A[10] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 80]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 80]\\n\\t\"\n        \"# A[11] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 88]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 88]\\n\\t\"\n        \"# A[12] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 96]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 96]\\n\\t\"\n        \"# A[13] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 104]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 104]\\n\\t\"\n        \"# A[14] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 112]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 112]\\n\\t\"\n        \"# A[15] * B\\n\\t\"\n        \"ldr\tx8, [%[a], 120]\\n\\t\"\n        \"mul\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx3, [%[r], 120]\\n\\t\"\n        \"str\tx4, [%[r], 128]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\"\n    );\n#endif\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n */\nstatic sp_digit div_2048_word_16(sp_digit d1, sp_digit d0, sp_digit div)\n{\n    sp_digit r;\n\n    __asm__ __volatile__ (\n        \"lsr\tx5, %[div], 32\\n\\t\"\n        \"add\tx5, x5, 1\\n\\t\"\n\n        \"udiv\tx3, %[d1], x5\\n\\t\"\n        \"lsl\tx6, x3, 32\\n\\t\"\n        \"mul\tx4, %[div], x6\\n\\t\"\n        \"umulh\tx3, %[div], x6\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"udiv\tx3, %[d1], x5\\n\\t\"\n        \"lsl\tx3, x3, 32\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"lsl\tx3, %[d1], 32\\n\\t\"\n        \"orr\tx3, x3, %[d0], lsr 32\\n\\t\"\n\n        \"udiv\tx3, x3, x5\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"lsl\tx3, %[d1], 32\\n\\t\"\n        \"orr\tx3, x3, %[d0], lsr 32\\n\\t\"\n\n        \"udiv\tx3, x3, x5\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"udiv\tx3, %[d0], %[div]\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx3, %[div], x3\\n\\t\"\n        \"sub\t%[d0], %[d0], x3\\n\\t\"\n        \"mov\t%[r], x6\\n\\t\"\n\n        : [r] \"=r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n\n    return r;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic int64_t sp_2048_cmp_16(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = -1;\n    sp_digit one = 1;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tx3, -1\\n\\t\"\n        \"mov\tx6, 120\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tx4, [%[a], x6]\\n\\t\"\n        \"ldr\tx5, [%[b], x6]\\n\\t\"\n        \"and\tx4, x4, x3\\n\\t\"\n        \"and\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"subs\tx6, x6, #8\\n\\t\"\n        \"b.cs\t1b\\n\\t\"\n        \"eor\t%[r], %[r], x3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tx3, -1\\n\\t\"\n        \"ldr\t\tx4, [%[a], 120]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 120]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 112]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 112]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 104]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 104]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 96]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 96]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 88]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 88]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 80]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 80]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 72]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 72]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 64]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 64]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 56]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 56]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 48]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 48]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 40]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 40]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 32]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 32]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 24]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 24]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 16]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 16]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 8]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 8]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 0]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 0]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"eor\t%[r], %[r], x3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n#endif\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_16(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[32], t2[17];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[15];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 16);\n    for (i=15; i>=0; i--) {\n        r1 = div_2048_word_16(t1[16 + i], t1[16 + i - 1], div);\n\n        sp_2048_mul_d_16(t2, d, r1);\n        t1[16 + i] += sp_2048_sub_in_place_16(&t1[i], t2);\n        t1[16 + i] -= t2[16];\n        sp_2048_mask_16(t2, d, t1[16 + i]);\n        t1[16 + i] += sp_2048_add_16(&t1[i], &t1[i], t2);\n        sp_2048_mask_16(t2, d, t1[16 + i]);\n        t1[16 + i] += sp_2048_add_16(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_2048_cmp_16(t1, d) >= 0;\n    sp_2048_cond_sub_16(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_16(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_16(a, m, NULL, r);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][32];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 32, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 32;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_16(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 16U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_16(t[1] + 16, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_16(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 16, a, sizeof(sp_digit) * 16);\n            err = sp_2048_mod_16(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_16(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_16(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_16(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_16(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_16(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_16(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_16(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_16(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_16(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_16(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_16(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_16(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_16(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_16(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0) {\n            c = 64;\n        }\n        c -= bits % 4;\n        if (c == 64) {\n            c = 60;\n        }\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 16);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 60;\n                n <<= 4;\n                c = 60;\n            }\n            else if (c < 4) {\n                y = n >> 60;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 60) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_2048_mont_sqr_16(r, r, m, mp);\n            sp_2048_mont_sqr_16(r, r, m, mp);\n            sp_2048_mont_sqr_16(r, r, m, mp);\n            sp_2048_mont_sqr_16(r, r, m, mp);\n\n            sp_2048_mont_mul_16(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[16], 0, sizeof(sp_digit) * 16U);\n        sp_2048_mont_reduce_16(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_16(r, m) >= 0);\n        sp_2048_cond_sub_16(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][32];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 32, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 32;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_16(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 16U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_16(t[1] + 16, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_16(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 16, a, sizeof(sp_digit) * 16);\n            err = sp_2048_mod_16(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_16(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_16(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_16(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_16(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_16(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_16(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_16(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_16(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_16(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_16(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_16(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_16(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_16(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_16(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_16(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_16(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_16(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_16(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_16(t[20], t[10], m, mp);\n        sp_2048_mont_mul_16(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_16(t[22], t[11], m, mp);\n        sp_2048_mont_mul_16(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_16(t[24], t[12], m, mp);\n        sp_2048_mont_mul_16(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_16(t[26], t[13], m, mp);\n        sp_2048_mont_mul_16(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_16(t[28], t[14], m, mp);\n        sp_2048_mont_mul_16(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_16(t[30], t[15], m, mp);\n        sp_2048_mont_mul_16(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0) {\n            c = 64;\n        }\n        c -= bits % 5;\n        if (c == 64) {\n            c = 59;\n        }\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 16);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 59;\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = n >> 59;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_16(r, r, m, mp);\n            sp_2048_mont_sqr_16(r, r, m, mp);\n            sp_2048_mont_sqr_16(r, r, m, mp);\n            sp_2048_mont_sqr_16(r, r, m, mp);\n            sp_2048_mont_sqr_16(r, r, m, mp);\n\n            sp_2048_mont_mul_16(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[16], 0, sizeof(sp_digit) * 16U);\n        sp_2048_mont_reduce_16(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_16(r, m) >= 0);\n        sp_2048_cond_sub_16(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_32(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 32);\n\n    /* r = 2^n mod m */\n    sp_2048_sub_in_place_32(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        sp_digit m)\n{\n    sp_digit c = 0;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tx8, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"subs\t%[c], xzr, %[c]\\n\\t\"\n        \"ldr\tx4, [%[a], x8]\\n\\t\"\n        \"ldr\tx5, [%[b], x8]\\n\\t\"\n        \"and\tx5, x5, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        \"str\tx4, [%[r], x8]\\n\\t\"\n        \"add\tx8, x8, #8\\n\\t\"\n        \"cmp\tx8, 256\\n\\t\"\n        \"b.lt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"x4\", \"x6\", \"x5\", \"x7\", \"x8\"\n    );\n#else\n    __asm__ __volatile__ (\n\n        \"ldr\t\tx4, [%[a], 0]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 8]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 0]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 8]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 0]\\n\\t\"\n        \"str\t\tx6, [%[r], 8]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 16]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 24]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 16]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 24]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 16]\\n\\t\"\n        \"str\t\tx6, [%[r], 24]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 32]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 40]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 32]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 40]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 32]\\n\\t\"\n        \"str\t\tx6, [%[r], 40]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 48]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 56]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 48]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 56]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 48]\\n\\t\"\n        \"str\t\tx6, [%[r], 56]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 64]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 72]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 64]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 72]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 64]\\n\\t\"\n        \"str\t\tx6, [%[r], 72]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 80]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 88]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 80]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 88]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 80]\\n\\t\"\n        \"str\t\tx6, [%[r], 88]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 96]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 104]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 96]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 104]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 96]\\n\\t\"\n        \"str\t\tx6, [%[r], 104]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 112]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 120]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 112]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 120]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 112]\\n\\t\"\n        \"str\t\tx6, [%[r], 120]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 128]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 136]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 128]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 136]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 128]\\n\\t\"\n        \"str\t\tx6, [%[r], 136]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 144]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 152]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 144]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 152]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 144]\\n\\t\"\n        \"str\t\tx6, [%[r], 152]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 160]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 168]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 160]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 168]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 160]\\n\\t\"\n        \"str\t\tx6, [%[r], 168]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 176]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 184]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 176]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 184]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 176]\\n\\t\"\n        \"str\t\tx6, [%[r], 184]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 192]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 200]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 192]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 200]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 192]\\n\\t\"\n        \"str\t\tx6, [%[r], 200]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 208]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 216]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 208]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 216]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 208]\\n\\t\"\n        \"str\t\tx6, [%[r], 216]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 224]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 232]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 224]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 232]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 224]\\n\\t\"\n        \"str\t\tx6, [%[r], 232]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 240]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 248]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 240]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 248]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 240]\\n\\t\"\n        \"str\t\tx6, [%[r], 248]\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"x4\", \"x6\", \"x5\", \"x7\", \"x8\"\n    );\n#endif /* WOLFSSL_SP_SMALL */\n\n    return c;\n}\n\n/* Reduce the number back to 2048 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"ldp       x12, x13, [%[m], 0]\\n\\t\"\n        \"ldp       x14, x15, [%[m], 16]\\n\\t\"\n        \"ldp       x16, x17, [%[m], 32]\\n\\t\"\n        \"ldp       x19, x20, [%[m], 48]\\n\\t\"\n        \"ldp       x21, x22, [%[m], 64]\\n\\t\"\n        \"ldp       x23, x24, [%[m], 80]\\n\\t\"\n        \"ldp       x25, x26, [%[m], 96]\\n\\t\"\n        \"ldp       x27, x28, [%[m], 112]\\n\\t\"\n        \"# i = 0\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"ldp\tx10, x11, [%[a], 0]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mul\tx8, %[mp], x10\\n\\t\"\n        \"# a[i+0] += m[0] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 0]\\n\\t\"\n        \"mul\t\tx6, x12, x8\\n\\t\"\n        \"umulh\tx7, x12, x8\\n\\t\"\n        \"adds\tx10, x10, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"# a[i+1] += m[1] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 8]\\n\\t\"\n        \"mul\t\tx6, x13, x8\\n\\t\"\n        \"umulh\tx7, x13, x8\\n\\t\"\n        \"adds\tx10, x11, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx10, x10, x5\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+2] += m[2] * mu\\n\\t\"\n        \"ldr\tx11, [%[a], 16]\\n\\t\"\n        \"mul\t\tx6, x14, x8\\n\\t\"\n        \"umulh\tx7, x14, x8\\n\\t\"\n        \"adds\tx11, x11, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx11, x11, x4\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+3] += m[3] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 24]\\n\\t\"\n        \"mul\t\tx6, x15, x8\\n\\t\"\n        \"umulh\tx7, x15, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 24]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+4] += m[4] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 32]\\n\\t\"\n        \"mul\t\tx6, x16, x8\\n\\t\"\n        \"umulh\tx7, x16, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 32]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+5] += m[5] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 40]\\n\\t\"\n        \"mul\t\tx6, x17, x8\\n\\t\"\n        \"umulh\tx7, x17, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 40]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+6] += m[6] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 48]\\n\\t\"\n        \"mul\t\tx6, x19, x8\\n\\t\"\n        \"umulh\tx7, x19, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 48]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+7] += m[7] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 56]\\n\\t\"\n        \"mul\t\tx6, x20, x8\\n\\t\"\n        \"umulh\tx7, x20, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 56]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+8] += m[8] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"mul\t\tx6, x21, x8\\n\\t\"\n        \"umulh\tx7, x21, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 64]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+9] += m[9] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"mul\t\tx6, x22, x8\\n\\t\"\n        \"umulh\tx7, x22, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 72]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+10] += m[10] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"mul\t\tx6, x23, x8\\n\\t\"\n        \"umulh\tx7, x23, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 80]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+11] += m[11] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"mul\t\tx6, x24, x8\\n\\t\"\n        \"umulh\tx7, x24, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 88]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+12] += m[12] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"mul\t\tx6, x25, x8\\n\\t\"\n        \"umulh\tx7, x25, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 96]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+13] += m[13] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"mul\t\tx6, x26, x8\\n\\t\"\n        \"umulh\tx7, x26, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 104]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+14] += m[14] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"mul\t\tx6, x27, x8\\n\\t\"\n        \"umulh\tx7, x27, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 112]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+15] += m[15] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"mul\t\tx6, x28, x8\\n\\t\"\n        \"umulh\tx7, x28, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 120]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+16] += m[16] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 128]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 128]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+17] += m[17] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 136]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 136]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+18] += m[18] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 144]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 144]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+19] += m[19] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 152]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 152]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+20] += m[20] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 160]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 160]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+21] += m[21] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 168]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 168]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+22] += m[22] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 176]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 176]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+23] += m[23] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 184]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 184]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+24] += m[24] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 192]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 192]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+25] += m[25] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 200]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 200]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+26] += m[26] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 208]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 208]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+27] += m[27] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 216]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 216]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+28] += m[28] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 224]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 224]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+29] += m[29] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 232]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 232]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+30] += m[30] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 240]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 240]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+31] += m[31] * mu\\n\\t\"\n        \"ldr\tx7, [%[m], 248]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx7, x7, %[ca]\\n\\t\"\n        \"cset  %[ca], cs\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx9, [%[a], 256]\\n\\t\"\n        \"adcs\tx9, x9, x7\\n\\t\"\n        \"str\tx9, [%[a], 256]\\n\\t\"\n        \"adc\t%[ca], %[ca], xzr\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"add\t%[a], %[a], 8\\n\\t\"\n        \"add\tx3, x3, 8\\n\\t\"\n        \"cmp\tx3, 256\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tx10, [%[a], 0]\\n\\t\"\n        \"str\tx11, [%[a], 8]\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\", \"x12\", \"x13\", \"x14\", \"x15\", \"x16\", \"x17\", \"x19\", \"x20\", \"x21\", \"x22\", \"x23\", \"x24\", \"x25\", \"x26\", \"x27\", \"x28\"\n    );\n\n    sp_2048_cond_sub_32(a - 32, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_32(r, a, b);\n    sp_2048_mont_reduce_32(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_32(r, a);\n    sp_2048_mont_reduce_32(r, m, mp);\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n */\nstatic sp_digit div_2048_word_32(sp_digit d1, sp_digit d0, sp_digit div)\n{\n    sp_digit r;\n\n    __asm__ __volatile__ (\n        \"lsr\tx5, %[div], 32\\n\\t\"\n        \"add\tx5, x5, 1\\n\\t\"\n\n        \"udiv\tx3, %[d1], x5\\n\\t\"\n        \"lsl\tx6, x3, 32\\n\\t\"\n        \"mul\tx4, %[div], x6\\n\\t\"\n        \"umulh\tx3, %[div], x6\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"udiv\tx3, %[d1], x5\\n\\t\"\n        \"lsl\tx3, x3, 32\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"lsl\tx3, %[d1], 32\\n\\t\"\n        \"orr\tx3, x3, %[d0], lsr 32\\n\\t\"\n\n        \"udiv\tx3, x3, x5\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"lsl\tx3, %[d1], 32\\n\\t\"\n        \"orr\tx3, x3, %[d0], lsr 32\\n\\t\"\n\n        \"udiv\tx3, x3, x5\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"udiv\tx3, %[d0], %[div]\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx3, %[div], x3\\n\\t\"\n        \"sub\t%[d0], %[d0], x3\\n\\t\"\n        \"mov\t%[r], x6\\n\\t\"\n\n        : [r] \"=r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_32(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<32; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic int64_t sp_2048_cmp_32(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = -1;\n    sp_digit one = 1;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tx3, -1\\n\\t\"\n        \"mov\tx6, 248\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tx4, [%[a], x6]\\n\\t\"\n        \"ldr\tx5, [%[b], x6]\\n\\t\"\n        \"and\tx4, x4, x3\\n\\t\"\n        \"and\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"subs\tx6, x6, #8\\n\\t\"\n        \"b.cs\t1b\\n\\t\"\n        \"eor\t%[r], %[r], x3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tx3, -1\\n\\t\"\n        \"ldr\t\tx4, [%[a], 248]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 248]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 240]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 240]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 232]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 232]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 224]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 224]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 216]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 216]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 208]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 208]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 200]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 200]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 192]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 192]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 184]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 184]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 176]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 176]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 168]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 168]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 160]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 160]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 152]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 152]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 144]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 144]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 136]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 136]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 128]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 128]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 120]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 120]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 112]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 112]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 104]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 104]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 96]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 96]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 88]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 88]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 80]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 80]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 72]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 72]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 64]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 64]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 56]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 56]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 48]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 48]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 40]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 40]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 32]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 32]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 24]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 24]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 16]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 16]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 8]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 8]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 0]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 0]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"eor\t%[r], %[r], x3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n#endif\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_32(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[64], t2[33];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[31];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 32);\n    for (i=31; i>=0; i--) {\n        r1 = div_2048_word_32(t1[32 + i], t1[32 + i - 1], div);\n\n        sp_2048_mul_d_32(t2, d, r1);\n        t1[32 + i] += sp_2048_sub_in_place_32(&t1[i], t2);\n        t1[32 + i] -= t2[32];\n        sp_2048_mask_32(t2, d, t1[32 + i]);\n        t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], t2);\n        sp_2048_mask_32(t2, d, t1[32 + i]);\n        t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_2048_cmp_32(t1, d) >= 0;\n    sp_2048_cond_sub_32(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_32(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_32(a, m, NULL, r);\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_32_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[64], t2[33];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[31];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 32);\n    for (i=31; i>=0; i--) {\n        r1 = div_2048_word_32(t1[32 + i], t1[32 + i - 1], div);\n\n        sp_2048_mul_d_32(t2, d, r1);\n        t1[32 + i] += sp_2048_sub_in_place_32(&t1[i], t2);\n        t1[32 + i] -= t2[32];\n        if (t1[32 + i] != 0) {\n            t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], d);\n            if (t1[32 + i] != 0)\n                t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_2048_cmp_32(t1, d) >= 0;\n    sp_2048_cond_sub_32(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_32_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_32_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][64];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 64, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 64;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_32(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 32U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_32(t[1] + 32, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_32(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 32, a, sizeof(sp_digit) * 32);\n            err = sp_2048_mod_32(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_32(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_32(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_32(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_32(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_32(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_32(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_32(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_32(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_32(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_32(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_32(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_32(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_32(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_32(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0) {\n            c = 64;\n        }\n        c -= bits % 4;\n        if (c == 64) {\n            c = 60;\n        }\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 32);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 60;\n                n <<= 4;\n                c = 60;\n            }\n            else if (c < 4) {\n                y = n >> 60;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 60) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n\n            sp_2048_mont_mul_32(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[32], 0, sizeof(sp_digit) * 32U);\n        sp_2048_mont_reduce_32(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_32(r, m) >= 0);\n        sp_2048_cond_sub_32(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][64];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 64, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 64;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_32(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 32U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_32(t[1] + 32, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_32(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 32, a, sizeof(sp_digit) * 32);\n            err = sp_2048_mod_32(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_32(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_32(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_32(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_32(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_32(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_32(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_32(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_32(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_32(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_32(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_32(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_32(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_32(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_32(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_32(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_32(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_32(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_32(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_32(t[20], t[10], m, mp);\n        sp_2048_mont_mul_32(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_32(t[22], t[11], m, mp);\n        sp_2048_mont_mul_32(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_32(t[24], t[12], m, mp);\n        sp_2048_mont_mul_32(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_32(t[26], t[13], m, mp);\n        sp_2048_mont_mul_32(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_32(t[28], t[14], m, mp);\n        sp_2048_mont_mul_32(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_32(t[30], t[15], m, mp);\n        sp_2048_mont_mul_32(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0) {\n            c = 64;\n        }\n        c -= bits % 5;\n        if (c == 64) {\n            c = 59;\n        }\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 32);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 59;\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = n >> 59;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n\n            sp_2048_mont_mul_32(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[32], 0, sizeof(sp_digit) * 32U);\n        sp_2048_mont_reduce_32(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_32(r, m) >= 0);\n        sp_2048_cond_sub_32(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[64], md[32], rd[64];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1];\n    int err = MP_OKAY;\n\n    if (*outLen < 256)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 64 || inLen > 256 ||\n                                                     mp_count_bits(mm) != 2048))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 32 * 2;\n        m = r + 32 * 2;\n        ah = a + 32;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 32;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(ah, 32, in, inLen);\n#if DIGIT_BIT >= 64\n        e[0] = em->dp[0];\n#else\n        e[0] = em->dp[0];\n        if (em->used > 1)\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e[0] == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(m, 32, mm);\n\n        if (e[0] == 0x3) {\n            if (err == MP_OKAY) {\n                sp_2048_sqr_32(r, ah);\n                err = sp_2048_mod_32_cond(r, r, m);\n            }\n            if (err == MP_OKAY) {\n                sp_2048_mul_32(r, ah, r);\n                err = sp_2048_mod_32_cond(r, r, m);\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_2048_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 32);\n            err = sp_2048_mod_32_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=63; i>=0; i--)\n                    if (e[0] >> i)\n                        break;\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 32);\n                for (i--; i>=0; i--) {\n                    sp_2048_mont_sqr_32(r, r, m, mp);\n                    if (((e[0] >> i) & 1) == 1)\n                        sp_2048_mont_mul_32(r, r, a, m, mp);\n                }\n                XMEMSET(&r[32], 0, sizeof(sp_digit) * 32);\n                sp_2048_mont_reduce_32(r, m, mp);\n\n                for (i = 31; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_2048_sub_in_place_32(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[32 * 2];\n    sp_digit pd[16], qd[16], dpd[16];\n    sp_digit tmpad[32], tmpbd[32];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 256)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 256 || mp_count_bits(mm) != 2048))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 32 * 2;\n        q = p + 16;\n        qi = dq = dp = q + 16;\n        tmpa = qi + 16;\n        tmpb = tmpa + 32;\n\n        tmp = t;\n        r = tmp + 32;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 32;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(a, 32, in, inLen);\n        sp_2048_from_mp(p, 16, pm);\n        sp_2048_from_mp(q, 16, qm);\n        sp_2048_from_mp(dp, 16, dpm);\n\n        err = sp_2048_mod_exp_16(tmpa, a, dp, 1024, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(dq, 16, dqm);\n        err = sp_2048_mod_exp_16(tmpb, a, dq, 1024, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_2048_sub_in_place_16(tmpa, tmpb);\n        sp_2048_mask_16(tmp, p, c);\n        sp_2048_add_16(tmpa, tmpa, tmp);\n\n        sp_2048_from_mp(qi, 16, qim);\n        sp_2048_mul_16(tmpa, tmpa, qi);\n        err = sp_2048_mod_16(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mul_16(tmpa, q, tmpa);\n        XMEMSET(&tmpb[16], 0, sizeof(sp_digit) * 16);\n        sp_2048_add_32(r, tmpb, tmpa);\n\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 16 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_2048_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 64\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 32);\n        r->used = 32;\n        mp_clamp(r);\n#elif DIGIT_BIT < 64\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 32; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 64) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 64 - s;\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 32; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 64 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 64 - s;\n            }\n            else {\n                s += 64;\n            }\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[64], e[32], m[32];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 32, base);\n        sp_2048_from_mp(e, 32, exp);\n        sp_2048_from_mp(m, 32, mod);\n\n        err = sp_2048_mod_exp_32(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_2048_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_2048\nstatic void sp_2048_lshift_32(sp_digit* r, sp_digit* a, byte n)\n{\n    __asm__ __volatile__ (\n        \"mov\tx6, 63\\n\\t\"\n        \"sub\tx6, x6, %[n]\\n\\t\"\n        \"ldr\tx3, [%[a], 248]\\n\\t\"\n        \"lsr\tx4, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx4, x4, x6\\n\\t\"\n        \"ldr\tx2, [%[a], 240]\\n\\t\"\n        \"str\tx4, [%[r], 256]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 232]\\n\\t\"\n        \"str\tx3, [%[r], 248]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 224]\\n\\t\"\n        \"str\tx2, [%[r], 240]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 216]\\n\\t\"\n        \"str\tx4, [%[r], 232]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 208]\\n\\t\"\n        \"str\tx3, [%[r], 224]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 200]\\n\\t\"\n        \"str\tx2, [%[r], 216]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 192]\\n\\t\"\n        \"str\tx4, [%[r], 208]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 184]\\n\\t\"\n        \"str\tx3, [%[r], 200]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 176]\\n\\t\"\n        \"str\tx2, [%[r], 192]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 168]\\n\\t\"\n        \"str\tx4, [%[r], 184]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 160]\\n\\t\"\n        \"str\tx3, [%[r], 176]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 152]\\n\\t\"\n        \"str\tx2, [%[r], 168]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 144]\\n\\t\"\n        \"str\tx4, [%[r], 160]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 136]\\n\\t\"\n        \"str\tx3, [%[r], 152]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 128]\\n\\t\"\n        \"str\tx2, [%[r], 144]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 120]\\n\\t\"\n        \"str\tx4, [%[r], 136]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 112]\\n\\t\"\n        \"str\tx3, [%[r], 128]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 104]\\n\\t\"\n        \"str\tx2, [%[r], 120]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 96]\\n\\t\"\n        \"str\tx4, [%[r], 112]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 88]\\n\\t\"\n        \"str\tx3, [%[r], 104]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 80]\\n\\t\"\n        \"str\tx2, [%[r], 96]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 72]\\n\\t\"\n        \"str\tx4, [%[r], 88]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 64]\\n\\t\"\n        \"str\tx3, [%[r], 80]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 56]\\n\\t\"\n        \"str\tx2, [%[r], 72]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 48]\\n\\t\"\n        \"str\tx4, [%[r], 64]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 40]\\n\\t\"\n        \"str\tx3, [%[r], 56]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 32]\\n\\t\"\n        \"str\tx2, [%[r], 48]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 24]\\n\\t\"\n        \"str\tx4, [%[r], 40]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 16]\\n\\t\"\n        \"str\tx3, [%[r], 32]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 8]\\n\\t\"\n        \"str\tx2, [%[r], 24]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 0]\\n\\t\"\n        \"str\tx4, [%[r], 16]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"str\tx2, [%[r]]\\n\\t\"\n        \"str\tx3, [%[r], 8]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [n] \"r\" (n)\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_2_32(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[64];\n    sp_digit td[33];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 97, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 64;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_32(norm, m);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0) {\n            c = 64;\n        }\n        c -= bits % 6;\n        if (c == 64) {\n            c = 58;\n        }\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        sp_2048_lshift_32(r, norm, y);\n        for (; i>=0 || c>=6; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 58;\n                n <<= 6;\n                c = 58;\n            }\n            else if (c < 6) {\n                y = n >> 58;\n                n = e[i--];\n                c = 6 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 58) & 0x3f;\n                n <<= 6;\n                c -= 6;\n            }\n\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n\n            sp_2048_lshift_32(r, r, y);\n            sp_2048_mul_d_32(tmp, norm, r[32]);\n            r[32] = 0;\n            o = sp_2048_add_32(r, r, tmp);\n            sp_2048_cond_sub_32(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[32], 0, sizeof(sp_digit) * 32U);\n        sp_2048_mont_reduce_32(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_32(r, m) >= 0);\n        sp_2048_cond_sub_32(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* HAVE_FFDHE_2048 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 256 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[64], e[32], m[32];\n    sp_digit* r = b;\n    word32 i;\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 256) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 32, base);\n        sp_2048_from_bin(e, 32, exp, expLen);\n        sp_2048_from_mp(m, 32, mod);\n\n    #ifdef HAVE_FFDHE_2048\n        if (base->used == 1 && base->dp[0] == 2 && m[31] == (sp_digit)-1)\n            err = sp_2048_mod_exp_2_32(r, e, expLen * 8, m);\n        else\n    #endif\n            err = sp_2048_mod_exp_32(r, b, e, expLen * 8, m, 0);\n\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n        for (i=0; i<256 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[32], e[16], m[16];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1024) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 16, base);\n        sp_2048_from_mp(e, 16, exp);\n        sp_2048_from_mp(m, 16, mod);\n\n        err = sp_2048_mod_exp_16(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 16, 0, sizeof(*r) * 16U);\n        err = sp_2048_to_mp(r, res);\n        res->used = mod->used;\n        mp_clamp(res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_2048 */\n\n#ifndef WOLFSSL_SP_NO_3072\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 56U) {\n            r[j] &= 0xffffffffffffffffl;\n            s = 64U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 64\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 64\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffffffffffffl;\n        s = 64U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 64U) <= (word32)DIGIT_BIT) {\n            s += 64U;\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 64) {\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 64 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 384\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_3072_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 3072 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<48 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 64) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 64);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_digit tmp[12];\n\n    __asm__ __volatile__ (\n        \"#  A[0] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx3, x7, x8\\n\\t\"\n        \"umulh\tx4, x7, x8\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"str\tx3, [%[tmp]]\\n\\t\"\n        \"#  A[0] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 8]\\n\\t\"\n        \"#  A[0] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 16]\\n\\t\"\n        \"#  A[0] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 24]\\n\\t\"\n        \"#  A[0] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 32]\\n\\t\"\n        \"#  A[0] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 40]\\n\\t\"\n        \"#  A[0] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 48]\\n\\t\"\n        \"#  A[0] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 56]\\n\\t\"\n        \"#  A[0] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 64]\\n\\t\"\n        \"#  A[0] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[8] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 72]\\n\\t\"\n        \"#  A[0] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[8] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[9] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 80]\\n\\t\"\n        \"#  A[0] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[10] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 88]\\n\\t\"\n        \"#  A[1] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[2] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[8] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[10] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[11] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 96]\\n\\t\"\n        \"#  A[2] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[3] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[8] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[9] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[11] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 104]\\n\\t\"\n        \"#  A[3] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[4] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[10] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 112]\\n\\t\"\n        \"#  A[4] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[5] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[8] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[10] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[11] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 120]\\n\\t\"\n        \"#  A[5] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[6] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[8] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[9] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[11] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 128]\\n\\t\"\n        \"#  A[6] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[7] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[10] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 136]\\n\\t\"\n        \"#  A[7] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[8] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[10] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[11] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 144]\\n\\t\"\n        \"#  A[8] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[9] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[11] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 152]\\n\\t\"\n        \"#  A[9] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[10] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 160]\\n\\t\"\n        \"#  A[10] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[11] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 168]\\n\\t\"\n        \"#  A[11] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adc\tx5, x5, x7\\n\\t\"\n        \"stp\tx4, x5, [%[r], 176]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [tmp] \"r\" (tmp)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_3072_sqr_12(sp_digit* r, const sp_digit* a)\n{\n    sp_digit tmp[12];\n\n    __asm__ __volatile__ (\n        \"ldp\tx10, x11, [%[a], 0]\\n\\t\"\n        \"ldp\tx12, x13, [%[a], 16]\\n\\t\"\n        \"ldp\tx14, x15, [%[a], 32]\\n\\t\"\n        \"ldp\tx16, x17, [%[a], 48]\\n\\t\"\n        \"ldp\tx19, x20, [%[a], 64]\\n\\t\"\n        \"ldp\tx21, x22, [%[a], 80]\\n\\t\"\n        \"#  A[0] * A[0]\\n\\t\"\n        \"mul\tx2, x10, x10\\n\\t\"\n        \"umulh\tx3, x10, x10\\n\\t\"\n        \"str\tx2, [%[tmp]]\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"#  A[0] * A[1]\\n\\t\"\n        \"mul\tx8, x10, x11\\n\\t\"\n        \"umulh\tx9, x10, x11\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, xzr, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 8]\\n\\t\"\n        \"#  A[0] * A[2]\\n\\t\"\n        \"mul\tx8, x10, x12\\n\\t\"\n        \"umulh\tx9, x10, x12\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[1] * A[1]\\n\\t\"\n        \"mul\tx8, x11, x11\\n\\t\"\n        \"umulh\tx9, x11, x11\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 16]\\n\\t\"\n        \"#  A[0] * A[3]\\n\\t\"\n        \"mul\tx8, x10, x13\\n\\t\"\n        \"umulh\tx9, x10, x13\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[1] * A[2]\\n\\t\"\n        \"mul\tx8, x11, x12\\n\\t\"\n        \"umulh\tx9, x11, x12\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx2, [%[tmp], 24]\\n\\t\"\n        \"#  A[0] * A[4]\\n\\t\"\n        \"mul\tx8, x10, x14\\n\\t\"\n        \"umulh\tx9, x10, x14\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, xzr, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"#  A[1] * A[3]\\n\\t\"\n        \"mul\tx8, x11, x13\\n\\t\"\n        \"umulh\tx9, x11, x13\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"#  A[2] * A[2]\\n\\t\"\n        \"mul\tx8, x12, x12\\n\\t\"\n        \"umulh\tx9, x12, x12\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 32]\\n\\t\"\n        \"#  A[0] * A[5]\\n\\t\"\n        \"mul\tx5, x10, x15\\n\\t\"\n        \"umulh\tx6, x10, x15\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[4]\\n\\t\"\n        \"mul\tx8, x11, x14\\n\\t\"\n        \"umulh\tx9, x11, x14\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[3]\\n\\t\"\n        \"mul\tx8, x12, x13\\n\\t\"\n        \"umulh\tx9, x12, x13\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[tmp], 40]\\n\\t\"\n        \"#  A[0] * A[6]\\n\\t\"\n        \"mul\tx5, x10, x16\\n\\t\"\n        \"umulh\tx6, x10, x16\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[5]\\n\\t\"\n        \"mul\tx8, x11, x15\\n\\t\"\n        \"umulh\tx9, x11, x15\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[4]\\n\\t\"\n        \"mul\tx8, x12, x14\\n\\t\"\n        \"umulh\tx9, x12, x14\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[3]\\n\\t\"\n        \"mul\tx8, x13, x13\\n\\t\"\n        \"umulh\tx9, x13, x13\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[tmp], 48]\\n\\t\"\n        \"#  A[0] * A[7]\\n\\t\"\n        \"mul\tx5, x10, x17\\n\\t\"\n        \"umulh\tx6, x10, x17\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[6]\\n\\t\"\n        \"mul\tx8, x11, x16\\n\\t\"\n        \"umulh\tx9, x11, x16\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[5]\\n\\t\"\n        \"mul\tx8, x12, x15\\n\\t\"\n        \"umulh\tx9, x12, x15\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[4]\\n\\t\"\n        \"mul\tx8, x13, x14\\n\\t\"\n        \"umulh\tx9, x13, x14\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[tmp], 56]\\n\\t\"\n        \"#  A[0] * A[8]\\n\\t\"\n        \"mul\tx5, x10, x19\\n\\t\"\n        \"umulh\tx6, x10, x19\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[7]\\n\\t\"\n        \"mul\tx8, x11, x17\\n\\t\"\n        \"umulh\tx9, x11, x17\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[6]\\n\\t\"\n        \"mul\tx8, x12, x16\\n\\t\"\n        \"umulh\tx9, x12, x16\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[5]\\n\\t\"\n        \"mul\tx8, x13, x15\\n\\t\"\n        \"umulh\tx9, x13, x15\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[4]\\n\\t\"\n        \"mul\tx8, x14, x14\\n\\t\"\n        \"umulh\tx9, x14, x14\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[tmp], 64]\\n\\t\"\n        \"#  A[0] * A[9]\\n\\t\"\n        \"mul\tx5, x10, x20\\n\\t\"\n        \"umulh\tx6, x10, x20\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[8]\\n\\t\"\n        \"mul\tx8, x11, x19\\n\\t\"\n        \"umulh\tx9, x11, x19\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[7]\\n\\t\"\n        \"mul\tx8, x12, x17\\n\\t\"\n        \"umulh\tx9, x12, x17\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[6]\\n\\t\"\n        \"mul\tx8, x13, x16\\n\\t\"\n        \"umulh\tx9, x13, x16\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[5]\\n\\t\"\n        \"mul\tx8, x14, x15\\n\\t\"\n        \"umulh\tx9, x14, x15\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[tmp], 72]\\n\\t\"\n        \"#  A[0] * A[10]\\n\\t\"\n        \"mul\tx5, x10, x21\\n\\t\"\n        \"umulh\tx6, x10, x21\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[9]\\n\\t\"\n        \"mul\tx8, x11, x20\\n\\t\"\n        \"umulh\tx9, x11, x20\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[8]\\n\\t\"\n        \"mul\tx8, x12, x19\\n\\t\"\n        \"umulh\tx9, x12, x19\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[7]\\n\\t\"\n        \"mul\tx8, x13, x17\\n\\t\"\n        \"umulh\tx9, x13, x17\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[6]\\n\\t\"\n        \"mul\tx8, x14, x16\\n\\t\"\n        \"umulh\tx9, x14, x16\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[5]\\n\\t\"\n        \"mul\tx8, x15, x15\\n\\t\"\n        \"umulh\tx9, x15, x15\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[tmp], 80]\\n\\t\"\n        \"#  A[0] * A[11]\\n\\t\"\n        \"mul\tx5, x10, x22\\n\\t\"\n        \"umulh\tx6, x10, x22\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[10]\\n\\t\"\n        \"mul\tx8, x11, x21\\n\\t\"\n        \"umulh\tx9, x11, x21\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[9]\\n\\t\"\n        \"mul\tx8, x12, x20\\n\\t\"\n        \"umulh\tx9, x12, x20\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[8]\\n\\t\"\n        \"mul\tx8, x13, x19\\n\\t\"\n        \"umulh\tx9, x13, x19\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[7]\\n\\t\"\n        \"mul\tx8, x14, x17\\n\\t\"\n        \"umulh\tx9, x14, x17\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[6]\\n\\t\"\n        \"mul\tx8, x15, x16\\n\\t\"\n        \"umulh\tx9, x15, x16\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[tmp], 88]\\n\\t\"\n        \"#  A[1] * A[11]\\n\\t\"\n        \"mul\tx5, x11, x22\\n\\t\"\n        \"umulh\tx6, x11, x22\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[2] * A[10]\\n\\t\"\n        \"mul\tx8, x12, x21\\n\\t\"\n        \"umulh\tx9, x12, x21\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[9]\\n\\t\"\n        \"mul\tx8, x13, x20\\n\\t\"\n        \"umulh\tx9, x13, x20\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[8]\\n\\t\"\n        \"mul\tx8, x14, x19\\n\\t\"\n        \"umulh\tx9, x14, x19\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[7]\\n\\t\"\n        \"mul\tx8, x15, x17\\n\\t\"\n        \"umulh\tx9, x15, x17\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[6]\\n\\t\"\n        \"mul\tx8, x16, x16\\n\\t\"\n        \"umulh\tx9, x16, x16\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[r], 96]\\n\\t\"\n        \"#  A[2] * A[11]\\n\\t\"\n        \"mul\tx5, x12, x22\\n\\t\"\n        \"umulh\tx6, x12, x22\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[3] * A[10]\\n\\t\"\n        \"mul\tx8, x13, x21\\n\\t\"\n        \"umulh\tx9, x13, x21\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[9]\\n\\t\"\n        \"mul\tx8, x14, x20\\n\\t\"\n        \"umulh\tx9, x14, x20\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[8]\\n\\t\"\n        \"mul\tx8, x15, x19\\n\\t\"\n        \"umulh\tx9, x15, x19\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[7]\\n\\t\"\n        \"mul\tx8, x16, x17\\n\\t\"\n        \"umulh\tx9, x16, x17\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[r], 104]\\n\\t\"\n        \"#  A[3] * A[11]\\n\\t\"\n        \"mul\tx5, x13, x22\\n\\t\"\n        \"umulh\tx6, x13, x22\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[4] * A[10]\\n\\t\"\n        \"mul\tx8, x14, x21\\n\\t\"\n        \"umulh\tx9, x14, x21\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[9]\\n\\t\"\n        \"mul\tx8, x15, x20\\n\\t\"\n        \"umulh\tx9, x15, x20\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[8]\\n\\t\"\n        \"mul\tx8, x16, x19\\n\\t\"\n        \"umulh\tx9, x16, x19\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[7]\\n\\t\"\n        \"mul\tx8, x17, x17\\n\\t\"\n        \"umulh\tx9, x17, x17\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[r], 112]\\n\\t\"\n        \"#  A[4] * A[11]\\n\\t\"\n        \"mul\tx5, x14, x22\\n\\t\"\n        \"umulh\tx6, x14, x22\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[5] * A[10]\\n\\t\"\n        \"mul\tx8, x15, x21\\n\\t\"\n        \"umulh\tx9, x15, x21\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[9]\\n\\t\"\n        \"mul\tx8, x16, x20\\n\\t\"\n        \"umulh\tx9, x16, x20\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[8]\\n\\t\"\n        \"mul\tx8, x17, x19\\n\\t\"\n        \"umulh\tx9, x17, x19\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[r], 120]\\n\\t\"\n        \"#  A[5] * A[11]\\n\\t\"\n        \"mul\tx5, x15, x22\\n\\t\"\n        \"umulh\tx6, x15, x22\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[6] * A[10]\\n\\t\"\n        \"mul\tx8, x16, x21\\n\\t\"\n        \"umulh\tx9, x16, x21\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[9]\\n\\t\"\n        \"mul\tx8, x17, x20\\n\\t\"\n        \"umulh\tx9, x17, x20\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[8]\\n\\t\"\n        \"mul\tx8, x19, x19\\n\\t\"\n        \"umulh\tx9, x19, x19\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[r], 128]\\n\\t\"\n        \"#  A[6] * A[11]\\n\\t\"\n        \"mul\tx5, x16, x22\\n\\t\"\n        \"umulh\tx6, x16, x22\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[7] * A[10]\\n\\t\"\n        \"mul\tx8, x17, x21\\n\\t\"\n        \"umulh\tx9, x17, x21\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[9]\\n\\t\"\n        \"mul\tx8, x19, x20\\n\\t\"\n        \"umulh\tx9, x19, x20\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[r], 136]\\n\\t\"\n        \"#  A[7] * A[11]\\n\\t\"\n        \"mul\tx8, x17, x22\\n\\t\"\n        \"umulh\tx9, x17, x22\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * A[10]\\n\\t\"\n        \"mul\tx8, x19, x21\\n\\t\"\n        \"umulh\tx9, x19, x21\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * A[9]\\n\\t\"\n        \"mul\tx8, x20, x20\\n\\t\"\n        \"umulh\tx9, x20, x20\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx2, [%[r], 144]\\n\\t\"\n        \"#  A[8] * A[11]\\n\\t\"\n        \"mul\tx8, x19, x22\\n\\t\"\n        \"umulh\tx9, x19, x22\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, xzr, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"#  A[9] * A[10]\\n\\t\"\n        \"mul\tx8, x20, x21\\n\\t\"\n        \"umulh\tx9, x20, x21\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"str\tx3, [%[r], 152]\\n\\t\"\n        \"#  A[9] * A[11]\\n\\t\"\n        \"mul\tx8, x20, x22\\n\\t\"\n        \"umulh\tx9, x20, x22\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * A[10]\\n\\t\"\n        \"mul\tx8, x21, x21\\n\\t\"\n        \"umulh\tx9, x21, x21\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 160]\\n\\t\"\n        \"#  A[10] * A[11]\\n\\t\"\n        \"mul\tx8, x21, x22\\n\\t\"\n        \"umulh\tx9, x21, x22\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx2, [%[r], 168]\\n\\t\"\n        \"#  A[11] * A[11]\\n\\t\"\n        \"mul\tx8, x22, x22\\n\\t\"\n        \"umulh\tx9, x22, x22\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adc\tx4, x4, x9\\n\\t\"\n        \"stp\tx3, x4, [%[r], 176]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [tmp] \"r\" (tmp)\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x8\", \"x9\", \"x10\", \"x5\", \"x6\", \"x7\", \"x10\", \"x11\", \"x12\", \"x13\", \"x14\", \"x15\", \"x16\", \"x17\", \"x19\", \"x20\", \"x21\", \"x22\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_add_12(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx3, x4, [%[a], 0]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 16]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 0]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 16]\\n\\t\"\n        \"adds\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 0]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 16]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 32]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 48]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 32]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 48]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 32]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 48]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 64]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 80]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 64]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 80]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 64]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 80]\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_sub_in_place_24(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx2, x3, [%[a], 0]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 16]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 0]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 16]\\n\\t\"\n        \"subs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 0]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 16]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 32]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 48]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 32]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 48]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 32]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 48]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 64]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 80]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 64]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 80]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 64]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 80]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 96]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 112]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 96]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 112]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 96]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 112]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 128]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 144]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 128]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 144]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 128]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 144]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 160]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 176]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 160]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 176]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 160]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 176]\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_add_24(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx3, x4, [%[a], 0]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 16]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 0]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 16]\\n\\t\"\n        \"adds\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 0]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 16]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 32]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 48]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 32]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 48]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 32]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 48]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 64]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 80]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 64]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 80]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 64]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 80]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 96]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 112]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 96]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 112]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 96]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 112]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 128]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 144]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 128]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 144]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 128]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 144]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 160]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 176]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 160]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 176]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 160]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 176]\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_12(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<12; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    r[0] = a[0] & m;\n    r[1] = a[1] & m;\n    r[2] = a[2] & m;\n    r[3] = a[3] & m;\n    r[4] = a[4] & m;\n    r[5] = a[5] & m;\n    r[6] = a[6] & m;\n    r[7] = a[7] & m;\n    r[8] = a[8] & m;\n    r[9] = a[9] & m;\n    r[10] = a[10] & m;\n    r[11] = a[11] & m;\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_24(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[24];\n    sp_digit a1[12];\n    sp_digit b1[12];\n    sp_digit z2[24];\n    sp_digit u, ca, cb;\n\n    ca = sp_3072_add_12(a1, a, &a[12]);\n    cb = sp_3072_add_12(b1, b, &b[12]);\n    u  = ca & cb;\n    sp_3072_mul_12(z1, a1, b1);\n    sp_3072_mul_12(z2, &a[12], &b[12]);\n    sp_3072_mul_12(z0, a, b);\n    sp_3072_mask_12(r + 24, a1, 0 - cb);\n    sp_3072_mask_12(b1, b1, 0 - ca);\n    u += sp_3072_add_12(r + 24, r + 24, b1);\n    u += sp_3072_sub_in_place_24(z1, z2);\n    u += sp_3072_sub_in_place_24(z1, z0);\n    u += sp_3072_add_24(r + 12, r + 12, z1);\n    r[36] = u;\n    XMEMSET(r + 36 + 1, 0, sizeof(sp_digit) * (12 - 1));\n    (void)sp_3072_add_24(r + 24, r + 24, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_24(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[24];\n    sp_digit z1[24];\n    sp_digit a1[12];\n    sp_digit u;\n\n    u = sp_3072_add_12(a1, a, &a[12]);\n    sp_3072_sqr_12(z1, a1);\n    sp_3072_sqr_12(z2, &a[12]);\n    sp_3072_sqr_12(z0, a);\n    sp_3072_mask_12(r + 24, a1, 0 - u);\n    u += sp_3072_add_12(r + 24, r + 24, r + 24);\n    u += sp_3072_sub_in_place_24(z1, z2);\n    u += sp_3072_sub_in_place_24(z1, z0);\n    u += sp_3072_add_24(r + 12, r + 12, z1);\n    r[36] = u;\n    XMEMSET(r + 36 + 1, 0, sizeof(sp_digit) * (12 - 1));\n    (void)sp_3072_add_24(r + 24, r + 24, z2);\n}\n\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_sub_in_place_48(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx2, x3, [%[a], 0]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 16]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 0]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 16]\\n\\t\"\n        \"subs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 0]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 16]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 32]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 48]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 32]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 48]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 32]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 48]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 64]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 80]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 64]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 80]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 64]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 80]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 96]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 112]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 96]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 112]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 96]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 112]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 128]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 144]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 128]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 144]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 128]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 144]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 160]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 176]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 160]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 176]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 160]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 176]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 192]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 208]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 192]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 208]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 192]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 208]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 224]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 240]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 224]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 240]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 224]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 240]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 256]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 272]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 256]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 272]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 256]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 272]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 288]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 304]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 288]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 304]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 288]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 304]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 320]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 336]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 320]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 336]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 320]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 336]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 352]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 368]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 352]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 368]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 352]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 368]\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx3, x4, [%[a], 0]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 16]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 0]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 16]\\n\\t\"\n        \"adds\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 0]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 16]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 32]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 48]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 32]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 48]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 32]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 48]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 64]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 80]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 64]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 80]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 64]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 80]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 96]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 112]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 96]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 112]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 96]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 112]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 128]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 144]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 128]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 144]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 128]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 144]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 160]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 176]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 160]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 176]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 160]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 176]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 192]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 208]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 192]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 208]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 192]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 208]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 224]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 240]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 224]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 240]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 224]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 240]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 256]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 272]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 256]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 272]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 256]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 272]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 288]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 304]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 288]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 304]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 288]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 304]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 320]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 336]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 320]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 336]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 320]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 336]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 352]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 368]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 352]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 368]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 352]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 368]\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_24(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<24; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[48];\n    sp_digit a1[24];\n    sp_digit b1[24];\n    sp_digit z2[48];\n    sp_digit u, ca, cb;\n\n    ca = sp_3072_add_24(a1, a, &a[24]);\n    cb = sp_3072_add_24(b1, b, &b[24]);\n    u  = ca & cb;\n    sp_3072_mul_24(z1, a1, b1);\n    sp_3072_mul_24(z2, &a[24], &b[24]);\n    sp_3072_mul_24(z0, a, b);\n    sp_3072_mask_24(r + 48, a1, 0 - cb);\n    sp_3072_mask_24(b1, b1, 0 - ca);\n    u += sp_3072_add_24(r + 48, r + 48, b1);\n    u += sp_3072_sub_in_place_48(z1, z2);\n    u += sp_3072_sub_in_place_48(z1, z0);\n    u += sp_3072_add_48(r + 24, r + 24, z1);\n    r[72] = u;\n    XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));\n    (void)sp_3072_add_48(r + 48, r + 48, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[48];\n    sp_digit z1[48];\n    sp_digit a1[24];\n    sp_digit u;\n\n    u = sp_3072_add_24(a1, a, &a[24]);\n    sp_3072_sqr_24(z1, a1);\n    sp_3072_sqr_24(z2, &a[24]);\n    sp_3072_sqr_24(z0, a);\n    sp_3072_mask_24(r + 48, a1, 0 - u);\n    u += sp_3072_add_24(r + 48, r + 48, r + 48);\n    u += sp_3072_sub_in_place_48(z1, z2);\n    u += sp_3072_sub_in_place_48(z1, z0);\n    u += sp_3072_add_48(r + 24, r + 24, z1);\n    r[72] = u;\n    XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));\n    (void)sp_3072_add_48(r + 48, r + 48, z2);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tx11, %[a], 384\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], #-1\\n\\t\"\n        \"ldp\tx3, x4, [%[a]], #16\\n\\t\"\n        \"ldp\tx5, x6, [%[a]], #16\\n\\t\"\n        \"ldp\tx7, x8, [%[b]], #16\\n\\t\"\n        \"ldp\tx9, x10, [%[b]], #16\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r]], #16\\n\\t\"\n        \"stp\tx5, x6, [%[r]], #16\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        \"cmp\t%[a], x11\\n\\t\"\n        \"b.ne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_sub_in_place_48(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tx10, %[a], 384\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\t%[c], xzr, %[c]\\n\\t\"\n        \"ldp\tx2, x3, [%[a]]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], #16]\\n\\t\"\n        \"ldp\tx6, x7, [%[b]], #16\\n\\t\"\n        \"ldp\tx8, x9, [%[b]], #16\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a]], #16\\n\\t\"\n        \"stp\tx4, x5, [%[a]], #16\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        \"cmp\t%[a], x10\\n\\t\"\n        \"b.ne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_3072_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_digit tmp[96];\n\n    __asm__ __volatile__ (\n        \"mov\tx5, 0\\n\\t\"\n        \"mov\tx6, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"mov\tx8, 0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tx3, x5, 376\\n\\t\"\n        \"csel\tx3, xzr, x3, cc\\n\\t\"\n        \"sub\tx4, x5, x3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"ldr\tx11, [%[b], x4]\\n\\t\"\n        \"mul\tx9, x10, x11\\n\\t\"\n        \"umulh\tx10, x10, x11\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"add\tx3, x3, #8\\n\\t\"\n        \"sub\tx4, x4, #8\\n\\t\"\n        \"cmp\tx3, 384\\n\\t\"\n        \"b.eq\t3f\\n\\t\"\n        \"cmp\tx3, x5\\n\\t\"\n        \"b.le\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        \"mov\tx6, x7\\n\\t\"\n        \"mov\tx7, x8\\n\\t\"\n        \"mov\tx8, #0\\n\\t\"\n        \"add\tx5, x5, #8\\n\\t\"\n        \"cmp\tx5, 752\\n\\t\"\n        \"b.le\t1b\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_3072_sqr_48(sp_digit* r, const sp_digit* a)\n{\n    sp_digit tmp[96];\n\n    __asm__ __volatile__ (\n        \"mov\tx6, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"mov\tx8, 0\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tx3, x5, 376\\n\\t\"\n        \"csel\tx3, xzr, x3, cc\\n\\t\"\n        \"sub\tx4, x5, x3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tx4, x3\\n\\t\"\n        \"b.eq\t4f\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"ldr\tx11, [%[a], x4]\\n\\t\"\n        \"mul\tx9, x10, x11\\n\\t\"\n        \"umulh\tx10, x10, x11\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"b.al\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"mul\tx9, x10, x10\\n\\t\"\n        \"umulh\tx10, x10, x10\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\tx3, x3, #8\\n\\t\"\n        \"sub\tx4, x4, #8\\n\\t\"\n        \"cmp\tx3, 384\\n\\t\"\n        \"b.eq\t3f\\n\\t\"\n        \"cmp\tx3, x4\\n\\t\"\n        \"b.gt\t3f\\n\\t\"\n        \"cmp\tx3, x5\\n\\t\"\n        \"b.le\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        \"mov\tx6, x7\\n\\t\"\n        \"mov\tx7, x8\\n\\t\"\n        \"mov\tx8, #0\\n\\t\"\n        \"add\tx5, x5, #8\\n\\t\"\n        \"cmp\tx5, 752\\n\\t\"\n        \"b.le\t1b\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_24(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n    int i;\n\n    for (i=0; i<24; i++) {\n        r[i] = a[i] & m;\n    }\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_add_24(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tx11, %[a], 192\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], #-1\\n\\t\"\n        \"ldp\tx3, x4, [%[a]], #16\\n\\t\"\n        \"ldp\tx5, x6, [%[a]], #16\\n\\t\"\n        \"ldp\tx7, x8, [%[b]], #16\\n\\t\"\n        \"ldp\tx9, x10, [%[b]], #16\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r]], #16\\n\\t\"\n        \"stp\tx5, x6, [%[r]], #16\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        \"cmp\t%[a], x11\\n\\t\"\n        \"b.ne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_3072_sub_in_place_24(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tx10, %[a], 192\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\t%[c], xzr, %[c]\\n\\t\"\n        \"ldp\tx2, x3, [%[a]]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], #16]\\n\\t\"\n        \"ldp\tx6, x7, [%[b]], #16\\n\\t\"\n        \"ldp\tx8, x9, [%[b]], #16\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a]], #16\\n\\t\"\n        \"stp\tx4, x5, [%[a]], #16\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        \"cmp\t%[a], x10\\n\\t\"\n        \"b.ne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_3072_mul_24(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_digit tmp[48];\n\n    __asm__ __volatile__ (\n        \"mov\tx5, 0\\n\\t\"\n        \"mov\tx6, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"mov\tx8, 0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tx3, x5, 184\\n\\t\"\n        \"csel\tx3, xzr, x3, cc\\n\\t\"\n        \"sub\tx4, x5, x3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"ldr\tx11, [%[b], x4]\\n\\t\"\n        \"mul\tx9, x10, x11\\n\\t\"\n        \"umulh\tx10, x10, x11\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"add\tx3, x3, #8\\n\\t\"\n        \"sub\tx4, x4, #8\\n\\t\"\n        \"cmp\tx3, 192\\n\\t\"\n        \"b.eq\t3f\\n\\t\"\n        \"cmp\tx3, x5\\n\\t\"\n        \"b.le\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        \"mov\tx6, x7\\n\\t\"\n        \"mov\tx7, x8\\n\\t\"\n        \"mov\tx8, #0\\n\\t\"\n        \"add\tx5, x5, #8\\n\\t\"\n        \"cmp\tx5, 368\\n\\t\"\n        \"b.le\t1b\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_3072_sqr_24(sp_digit* r, const sp_digit* a)\n{\n    sp_digit tmp[48];\n\n    __asm__ __volatile__ (\n        \"mov\tx6, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"mov\tx8, 0\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tx3, x5, 184\\n\\t\"\n        \"csel\tx3, xzr, x3, cc\\n\\t\"\n        \"sub\tx4, x5, x3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tx4, x3\\n\\t\"\n        \"b.eq\t4f\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"ldr\tx11, [%[a], x4]\\n\\t\"\n        \"mul\tx9, x10, x11\\n\\t\"\n        \"umulh\tx10, x10, x11\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"b.al\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"mul\tx9, x10, x10\\n\\t\"\n        \"umulh\tx10, x10, x10\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\tx3, x3, #8\\n\\t\"\n        \"sub\tx4, x4, #8\\n\\t\"\n        \"cmp\tx3, 192\\n\\t\"\n        \"b.eq\t3f\\n\\t\"\n        \"cmp\tx3, x4\\n\\t\"\n        \"b.gt\t3f\\n\\t\"\n        \"cmp\tx3, x5\\n\\t\"\n        \"b.le\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        \"mov\tx6, x7\\n\\t\"\n        \"mov\tx7, x8\\n\\t\"\n        \"mov\tx8, #0\\n\\t\"\n        \"add\tx5, x5, #8\\n\\t\"\n        \"cmp\tx5, 368\\n\\t\"\n        \"b.le\t1b\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**64 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nstatic void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tx8, [%[a]]\\n\\t\"\n        \"mul\tx5, %[b], x8\\n\\t\"\n        \"umulh\tx3, %[b], x8\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"str\tx5, [%[r]]\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"mov\tx9, #8\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tx8, [%[a], x9]\\n\\t\"\n        \"mul\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"str\tx3, [%[r], x9]\\n\\t\"\n        \"mov\tx3, x4\\n\\t\"\n        \"mov\tx4, x5\\n\\t\"\n        \"mov\tx5, #0\\n\\t\"\n        \"add\tx9, x9, #8\\n\\t\"\n        \"cmp\tx9, 384\\n\\t\"\n        \"b.lt\t1b\\n\\t\"\n        \"str\tx3, [%[r], 384]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tx8, [%[a]]\\n\\t\"\n        \"mul\tx3, %[b], x8\\n\\t\"\n        \"umulh\tx4, %[b], x8\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"str\tx3, [%[r]]\\n\\t\"\n        \"# A[1] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 8]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 8]\\n\\t\"\n        \"# A[2] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 16]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 16]\\n\\t\"\n        \"# A[3] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 24]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 24]\\n\\t\"\n        \"# A[4] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 32]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 32]\\n\\t\"\n        \"# A[5] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 40]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 40]\\n\\t\"\n        \"# A[6] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 48]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 48]\\n\\t\"\n        \"# A[7] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 56]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 56]\\n\\t\"\n        \"# A[8] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 64]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 64]\\n\\t\"\n        \"# A[9] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 72]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 72]\\n\\t\"\n        \"# A[10] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 80]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 80]\\n\\t\"\n        \"# A[11] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 88]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 88]\\n\\t\"\n        \"# A[12] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 96]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 96]\\n\\t\"\n        \"# A[13] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 104]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 104]\\n\\t\"\n        \"# A[14] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 112]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 112]\\n\\t\"\n        \"# A[15] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 120]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 120]\\n\\t\"\n        \"# A[16] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 128]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 128]\\n\\t\"\n        \"# A[17] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 136]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 136]\\n\\t\"\n        \"# A[18] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 144]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 144]\\n\\t\"\n        \"# A[19] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 152]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 152]\\n\\t\"\n        \"# A[20] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 160]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 160]\\n\\t\"\n        \"# A[21] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 168]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 168]\\n\\t\"\n        \"# A[22] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 176]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 176]\\n\\t\"\n        \"# A[23] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 184]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 184]\\n\\t\"\n        \"# A[24] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 192]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 192]\\n\\t\"\n        \"# A[25] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 200]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 200]\\n\\t\"\n        \"# A[26] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 208]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 208]\\n\\t\"\n        \"# A[27] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 216]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 216]\\n\\t\"\n        \"# A[28] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 224]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 224]\\n\\t\"\n        \"# A[29] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 232]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 232]\\n\\t\"\n        \"# A[30] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 240]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 240]\\n\\t\"\n        \"# A[31] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 248]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 248]\\n\\t\"\n        \"# A[32] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 256]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 256]\\n\\t\"\n        \"# A[33] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 264]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 264]\\n\\t\"\n        \"# A[34] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 272]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 272]\\n\\t\"\n        \"# A[35] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 280]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 280]\\n\\t\"\n        \"# A[36] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 288]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 288]\\n\\t\"\n        \"# A[37] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 296]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 296]\\n\\t\"\n        \"# A[38] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 304]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 304]\\n\\t\"\n        \"# A[39] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 312]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 312]\\n\\t\"\n        \"# A[40] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 320]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 320]\\n\\t\"\n        \"# A[41] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 328]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 328]\\n\\t\"\n        \"# A[42] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 336]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 336]\\n\\t\"\n        \"# A[43] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 344]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 344]\\n\\t\"\n        \"# A[44] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 352]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 352]\\n\\t\"\n        \"# A[45] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 360]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 360]\\n\\t\"\n        \"# A[46] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 368]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 368]\\n\\t\"\n        \"# A[47] * B\\n\\t\"\n        \"ldr\tx8, [%[a], 376]\\n\\t\"\n        \"mul\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx5, [%[r], 376]\\n\\t\"\n        \"str\tx3, [%[r], 384]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\"\n    );\n#endif\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_24(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 24);\n\n    /* r = 2^n mod m */\n    sp_3072_sub_in_place_24(r, m);\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic sp_digit sp_3072_cond_sub_24(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        sp_digit m)\n{\n    sp_digit c = 0;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tx8, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"subs\t%[c], xzr, %[c]\\n\\t\"\n        \"ldr\tx4, [%[a], x8]\\n\\t\"\n        \"ldr\tx5, [%[b], x8]\\n\\t\"\n        \"and\tx5, x5, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        \"str\tx4, [%[r], x8]\\n\\t\"\n        \"add\tx8, x8, #8\\n\\t\"\n        \"cmp\tx8, 192\\n\\t\"\n        \"b.lt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"x4\", \"x6\", \"x5\", \"x7\", \"x8\"\n    );\n#else\n    __asm__ __volatile__ (\n\n        \"ldr\t\tx4, [%[a], 0]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 8]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 0]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 8]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 0]\\n\\t\"\n        \"str\t\tx6, [%[r], 8]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 16]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 24]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 16]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 24]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 16]\\n\\t\"\n        \"str\t\tx6, [%[r], 24]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 32]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 40]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 32]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 40]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 32]\\n\\t\"\n        \"str\t\tx6, [%[r], 40]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 48]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 56]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 48]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 56]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 48]\\n\\t\"\n        \"str\t\tx6, [%[r], 56]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 64]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 72]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 64]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 72]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 64]\\n\\t\"\n        \"str\t\tx6, [%[r], 72]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 80]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 88]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 80]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 88]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 80]\\n\\t\"\n        \"str\t\tx6, [%[r], 88]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 96]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 104]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 96]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 104]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 96]\\n\\t\"\n        \"str\t\tx6, [%[r], 104]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 112]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 120]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 112]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 120]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 112]\\n\\t\"\n        \"str\t\tx6, [%[r], 120]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 128]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 136]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 128]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 136]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 128]\\n\\t\"\n        \"str\t\tx6, [%[r], 136]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 144]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 152]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 144]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 152]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 144]\\n\\t\"\n        \"str\t\tx6, [%[r], 152]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 160]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 168]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 160]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 168]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 160]\\n\\t\"\n        \"str\t\tx6, [%[r], 168]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 176]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 184]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 176]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 184]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 176]\\n\\t\"\n        \"str\t\tx6, [%[r], 184]\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"x4\", \"x6\", \"x5\", \"x7\", \"x8\"\n    );\n#endif /* WOLFSSL_SP_SMALL */\n\n    return c;\n}\n\n/* Reduce the number back to 3072 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_3072_mont_reduce_24(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"ldp       x12, x13, [%[m], 0]\\n\\t\"\n        \"ldp       x14, x15, [%[m], 16]\\n\\t\"\n        \"ldp       x16, x17, [%[m], 32]\\n\\t\"\n        \"ldp       x19, x20, [%[m], 48]\\n\\t\"\n        \"ldp       x21, x22, [%[m], 64]\\n\\t\"\n        \"ldp       x23, x24, [%[m], 80]\\n\\t\"\n        \"ldp       x25, x26, [%[m], 96]\\n\\t\"\n        \"ldp       x27, x28, [%[m], 112]\\n\\t\"\n        \"# i = 0\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"ldp\tx10, x11, [%[a], 0]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mul\tx8, %[mp], x10\\n\\t\"\n        \"# a[i+0] += m[0] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 0]\\n\\t\"\n        \"mul\t\tx6, x12, x8\\n\\t\"\n        \"umulh\tx7, x12, x8\\n\\t\"\n        \"adds\tx10, x10, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"# a[i+1] += m[1] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 8]\\n\\t\"\n        \"mul\t\tx6, x13, x8\\n\\t\"\n        \"umulh\tx7, x13, x8\\n\\t\"\n        \"adds\tx10, x11, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx10, x10, x5\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+2] += m[2] * mu\\n\\t\"\n        \"ldr\tx11, [%[a], 16]\\n\\t\"\n        \"mul\t\tx6, x14, x8\\n\\t\"\n        \"umulh\tx7, x14, x8\\n\\t\"\n        \"adds\tx11, x11, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx11, x11, x4\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+3] += m[3] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 24]\\n\\t\"\n        \"mul\t\tx6, x15, x8\\n\\t\"\n        \"umulh\tx7, x15, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 24]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+4] += m[4] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 32]\\n\\t\"\n        \"mul\t\tx6, x16, x8\\n\\t\"\n        \"umulh\tx7, x16, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 32]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+5] += m[5] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 40]\\n\\t\"\n        \"mul\t\tx6, x17, x8\\n\\t\"\n        \"umulh\tx7, x17, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 40]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+6] += m[6] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 48]\\n\\t\"\n        \"mul\t\tx6, x19, x8\\n\\t\"\n        \"umulh\tx7, x19, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 48]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+7] += m[7] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 56]\\n\\t\"\n        \"mul\t\tx6, x20, x8\\n\\t\"\n        \"umulh\tx7, x20, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 56]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+8] += m[8] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"mul\t\tx6, x21, x8\\n\\t\"\n        \"umulh\tx7, x21, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 64]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+9] += m[9] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"mul\t\tx6, x22, x8\\n\\t\"\n        \"umulh\tx7, x22, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 72]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+10] += m[10] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"mul\t\tx6, x23, x8\\n\\t\"\n        \"umulh\tx7, x23, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 80]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+11] += m[11] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"mul\t\tx6, x24, x8\\n\\t\"\n        \"umulh\tx7, x24, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 88]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+12] += m[12] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"mul\t\tx6, x25, x8\\n\\t\"\n        \"umulh\tx7, x25, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 96]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+13] += m[13] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"mul\t\tx6, x26, x8\\n\\t\"\n        \"umulh\tx7, x26, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 104]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+14] += m[14] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"mul\t\tx6, x27, x8\\n\\t\"\n        \"umulh\tx7, x27, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 112]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+15] += m[15] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"mul\t\tx6, x28, x8\\n\\t\"\n        \"umulh\tx7, x28, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 120]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+16] += m[16] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 128]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 128]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+17] += m[17] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 136]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 136]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+18] += m[18] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 144]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 144]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+19] += m[19] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 152]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 152]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+20] += m[20] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 160]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 160]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+21] += m[21] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 168]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 168]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+22] += m[22] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 176]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 176]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+23] += m[23] * mu\\n\\t\"\n        \"ldr\tx7, [%[m], 184]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx7, x7, %[ca]\\n\\t\"\n        \"cset  %[ca], cs\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"adcs\tx9, x9, x7\\n\\t\"\n        \"str\tx9, [%[a], 192]\\n\\t\"\n        \"adc\t%[ca], %[ca], xzr\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"add\t%[a], %[a], 8\\n\\t\"\n        \"add\tx3, x3, 8\\n\\t\"\n        \"cmp\tx3, 192\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tx10, [%[a], 0]\\n\\t\"\n        \"str\tx11, [%[a], 8]\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\", \"x12\", \"x13\", \"x14\", \"x15\", \"x16\", \"x17\", \"x19\", \"x20\", \"x21\", \"x22\", \"x23\", \"x24\", \"x25\", \"x26\", \"x27\", \"x28\"\n    );\n\n    sp_3072_cond_sub_24(a - 24, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_24(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_24(r, a, b);\n    sp_3072_mont_reduce_24(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_24(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_24(r, a);\n    sp_3072_mont_reduce_24(r, m, mp);\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nstatic void sp_3072_mul_d_24(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tx8, [%[a]]\\n\\t\"\n        \"mul\tx5, %[b], x8\\n\\t\"\n        \"umulh\tx3, %[b], x8\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"str\tx5, [%[r]]\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"mov\tx9, #8\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tx8, [%[a], x9]\\n\\t\"\n        \"mul\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"str\tx3, [%[r], x9]\\n\\t\"\n        \"mov\tx3, x4\\n\\t\"\n        \"mov\tx4, x5\\n\\t\"\n        \"mov\tx5, #0\\n\\t\"\n        \"add\tx9, x9, #8\\n\\t\"\n        \"cmp\tx9, 192\\n\\t\"\n        \"b.lt\t1b\\n\\t\"\n        \"str\tx3, [%[r], 192]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tx8, [%[a]]\\n\\t\"\n        \"mul\tx3, %[b], x8\\n\\t\"\n        \"umulh\tx4, %[b], x8\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"str\tx3, [%[r]]\\n\\t\"\n        \"# A[1] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 8]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 8]\\n\\t\"\n        \"# A[2] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 16]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 16]\\n\\t\"\n        \"# A[3] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 24]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 24]\\n\\t\"\n        \"# A[4] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 32]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 32]\\n\\t\"\n        \"# A[5] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 40]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 40]\\n\\t\"\n        \"# A[6] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 48]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 48]\\n\\t\"\n        \"# A[7] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 56]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 56]\\n\\t\"\n        \"# A[8] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 64]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 64]\\n\\t\"\n        \"# A[9] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 72]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 72]\\n\\t\"\n        \"# A[10] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 80]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 80]\\n\\t\"\n        \"# A[11] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 88]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 88]\\n\\t\"\n        \"# A[12] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 96]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 96]\\n\\t\"\n        \"# A[13] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 104]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 104]\\n\\t\"\n        \"# A[14] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 112]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 112]\\n\\t\"\n        \"# A[15] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 120]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 120]\\n\\t\"\n        \"# A[16] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 128]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 128]\\n\\t\"\n        \"# A[17] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 136]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 136]\\n\\t\"\n        \"# A[18] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 144]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 144]\\n\\t\"\n        \"# A[19] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 152]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 152]\\n\\t\"\n        \"# A[20] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 160]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 160]\\n\\t\"\n        \"# A[21] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 168]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 168]\\n\\t\"\n        \"# A[22] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 176]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 176]\\n\\t\"\n        \"# A[23] * B\\n\\t\"\n        \"ldr\tx8, [%[a], 184]\\n\\t\"\n        \"mul\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx5, [%[r], 184]\\n\\t\"\n        \"str\tx3, [%[r], 192]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\"\n    );\n#endif\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n */\nstatic sp_digit div_3072_word_24(sp_digit d1, sp_digit d0, sp_digit div)\n{\n    sp_digit r;\n\n    __asm__ __volatile__ (\n        \"lsr\tx5, %[div], 32\\n\\t\"\n        \"add\tx5, x5, 1\\n\\t\"\n\n        \"udiv\tx3, %[d1], x5\\n\\t\"\n        \"lsl\tx6, x3, 32\\n\\t\"\n        \"mul\tx4, %[div], x6\\n\\t\"\n        \"umulh\tx3, %[div], x6\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"udiv\tx3, %[d1], x5\\n\\t\"\n        \"lsl\tx3, x3, 32\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"lsl\tx3, %[d1], 32\\n\\t\"\n        \"orr\tx3, x3, %[d0], lsr 32\\n\\t\"\n\n        \"udiv\tx3, x3, x5\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"lsl\tx3, %[d1], 32\\n\\t\"\n        \"orr\tx3, x3, %[d0], lsr 32\\n\\t\"\n\n        \"udiv\tx3, x3, x5\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"udiv\tx3, %[d0], %[div]\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx3, %[div], x3\\n\\t\"\n        \"sub\t%[d0], %[d0], x3\\n\\t\"\n        \"mov\t%[r], x6\\n\\t\"\n\n        : [r] \"=r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n\n    return r;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic int64_t sp_3072_cmp_24(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = -1;\n    sp_digit one = 1;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tx3, -1\\n\\t\"\n        \"mov\tx6, 184\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tx4, [%[a], x6]\\n\\t\"\n        \"ldr\tx5, [%[b], x6]\\n\\t\"\n        \"and\tx4, x4, x3\\n\\t\"\n        \"and\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"subs\tx6, x6, #8\\n\\t\"\n        \"b.cs\t1b\\n\\t\"\n        \"eor\t%[r], %[r], x3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tx3, -1\\n\\t\"\n        \"ldr\t\tx4, [%[a], 184]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 184]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 176]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 176]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 168]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 168]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 160]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 160]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 152]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 152]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 144]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 144]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 136]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 136]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 128]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 128]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 120]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 120]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 112]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 112]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 104]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 104]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 96]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 96]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 88]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 88]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 80]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 80]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 72]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 72]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 64]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 64]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 56]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 56]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 48]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 48]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 40]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 40]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 32]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 32]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 24]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 24]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 16]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 16]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 8]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 8]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 0]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 0]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"eor\t%[r], %[r], x3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n#endif\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_24(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[48], t2[25];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[23];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 24);\n    for (i=23; i>=0; i--) {\n        r1 = div_3072_word_24(t1[24 + i], t1[24 + i - 1], div);\n\n        sp_3072_mul_d_24(t2, d, r1);\n        t1[24 + i] += sp_3072_sub_in_place_24(&t1[i], t2);\n        t1[24 + i] -= t2[24];\n        sp_3072_mask_24(t2, d, t1[24 + i]);\n        t1[24 + i] += sp_3072_add_24(&t1[i], &t1[i], t2);\n        sp_3072_mask_24(t2, d, t1[24 + i]);\n        t1[24 + i] += sp_3072_add_24(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_3072_cmp_24(t1, d) >= 0;\n    sp_3072_cond_sub_24(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_24(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_24(a, m, NULL, r);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][48];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 48, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 48;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_24(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 24U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_24(t[1] + 24, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_24(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 24, a, sizeof(sp_digit) * 24);\n            err = sp_3072_mod_24(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_24(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_24(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_24(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_24(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_24(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_24(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_24(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_24(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_24(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_24(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_24(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_24(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_24(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_24(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0) {\n            c = 64;\n        }\n        c -= bits % 4;\n        if (c == 64) {\n            c = 60;\n        }\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 24);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 60;\n                n <<= 4;\n                c = 60;\n            }\n            else if (c < 4) {\n                y = n >> 60;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 60) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_3072_mont_sqr_24(r, r, m, mp);\n            sp_3072_mont_sqr_24(r, r, m, mp);\n            sp_3072_mont_sqr_24(r, r, m, mp);\n            sp_3072_mont_sqr_24(r, r, m, mp);\n\n            sp_3072_mont_mul_24(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[24], 0, sizeof(sp_digit) * 24U);\n        sp_3072_mont_reduce_24(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_24(r, m) >= 0);\n        sp_3072_cond_sub_24(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][48];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 48, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 48;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_24(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 24U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_24(t[1] + 24, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_24(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 24, a, sizeof(sp_digit) * 24);\n            err = sp_3072_mod_24(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_24(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_24(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_24(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_24(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_24(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_24(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_24(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_24(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_24(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_24(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_24(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_24(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_24(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_24(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_24(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_24(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_24(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_24(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_24(t[20], t[10], m, mp);\n        sp_3072_mont_mul_24(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_24(t[22], t[11], m, mp);\n        sp_3072_mont_mul_24(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_24(t[24], t[12], m, mp);\n        sp_3072_mont_mul_24(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_24(t[26], t[13], m, mp);\n        sp_3072_mont_mul_24(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_24(t[28], t[14], m, mp);\n        sp_3072_mont_mul_24(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_24(t[30], t[15], m, mp);\n        sp_3072_mont_mul_24(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0) {\n            c = 64;\n        }\n        c -= bits % 5;\n        if (c == 64) {\n            c = 59;\n        }\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 24);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 59;\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = n >> 59;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_24(r, r, m, mp);\n            sp_3072_mont_sqr_24(r, r, m, mp);\n            sp_3072_mont_sqr_24(r, r, m, mp);\n            sp_3072_mont_sqr_24(r, r, m, mp);\n            sp_3072_mont_sqr_24(r, r, m, mp);\n\n            sp_3072_mont_mul_24(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[24], 0, sizeof(sp_digit) * 24U);\n        sp_3072_mont_reduce_24(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_24(r, m) >= 0);\n        sp_3072_cond_sub_24(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_48(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 48);\n\n    /* r = 2^n mod m */\n    sp_3072_sub_in_place_48(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        sp_digit m)\n{\n    sp_digit c = 0;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tx8, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"subs\t%[c], xzr, %[c]\\n\\t\"\n        \"ldr\tx4, [%[a], x8]\\n\\t\"\n        \"ldr\tx5, [%[b], x8]\\n\\t\"\n        \"and\tx5, x5, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        \"str\tx4, [%[r], x8]\\n\\t\"\n        \"add\tx8, x8, #8\\n\\t\"\n        \"cmp\tx8, 384\\n\\t\"\n        \"b.lt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"x4\", \"x6\", \"x5\", \"x7\", \"x8\"\n    );\n#else\n    __asm__ __volatile__ (\n\n        \"ldr\t\tx4, [%[a], 0]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 8]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 0]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 8]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 0]\\n\\t\"\n        \"str\t\tx6, [%[r], 8]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 16]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 24]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 16]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 24]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 16]\\n\\t\"\n        \"str\t\tx6, [%[r], 24]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 32]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 40]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 32]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 40]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 32]\\n\\t\"\n        \"str\t\tx6, [%[r], 40]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 48]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 56]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 48]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 56]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 48]\\n\\t\"\n        \"str\t\tx6, [%[r], 56]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 64]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 72]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 64]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 72]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 64]\\n\\t\"\n        \"str\t\tx6, [%[r], 72]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 80]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 88]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 80]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 88]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 80]\\n\\t\"\n        \"str\t\tx6, [%[r], 88]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 96]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 104]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 96]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 104]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 96]\\n\\t\"\n        \"str\t\tx6, [%[r], 104]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 112]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 120]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 112]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 120]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 112]\\n\\t\"\n        \"str\t\tx6, [%[r], 120]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 128]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 136]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 128]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 136]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 128]\\n\\t\"\n        \"str\t\tx6, [%[r], 136]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 144]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 152]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 144]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 152]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 144]\\n\\t\"\n        \"str\t\tx6, [%[r], 152]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 160]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 168]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 160]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 168]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 160]\\n\\t\"\n        \"str\t\tx6, [%[r], 168]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 176]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 184]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 176]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 184]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 176]\\n\\t\"\n        \"str\t\tx6, [%[r], 184]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 192]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 200]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 192]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 200]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 192]\\n\\t\"\n        \"str\t\tx6, [%[r], 200]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 208]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 216]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 208]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 216]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 208]\\n\\t\"\n        \"str\t\tx6, [%[r], 216]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 224]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 232]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 224]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 232]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 224]\\n\\t\"\n        \"str\t\tx6, [%[r], 232]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 240]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 248]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 240]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 248]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 240]\\n\\t\"\n        \"str\t\tx6, [%[r], 248]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 256]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 264]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 256]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 264]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 256]\\n\\t\"\n        \"str\t\tx6, [%[r], 264]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 272]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 280]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 272]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 280]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 272]\\n\\t\"\n        \"str\t\tx6, [%[r], 280]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 288]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 296]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 288]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 296]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 288]\\n\\t\"\n        \"str\t\tx6, [%[r], 296]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 304]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 312]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 304]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 312]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 304]\\n\\t\"\n        \"str\t\tx6, [%[r], 312]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 320]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 328]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 320]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 328]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 320]\\n\\t\"\n        \"str\t\tx6, [%[r], 328]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 336]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 344]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 336]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 344]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 336]\\n\\t\"\n        \"str\t\tx6, [%[r], 344]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 352]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 360]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 352]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 360]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 352]\\n\\t\"\n        \"str\t\tx6, [%[r], 360]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 368]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 376]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 368]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 376]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 368]\\n\\t\"\n        \"str\t\tx6, [%[r], 376]\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"x4\", \"x6\", \"x5\", \"x7\", \"x8\"\n    );\n#endif /* WOLFSSL_SP_SMALL */\n\n    return c;\n}\n\n/* Reduce the number back to 3072 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"ldp       x12, x13, [%[m], 0]\\n\\t\"\n        \"ldp       x14, x15, [%[m], 16]\\n\\t\"\n        \"ldp       x16, x17, [%[m], 32]\\n\\t\"\n        \"ldp       x19, x20, [%[m], 48]\\n\\t\"\n        \"ldp       x21, x22, [%[m], 64]\\n\\t\"\n        \"ldp       x23, x24, [%[m], 80]\\n\\t\"\n        \"ldp       x25, x26, [%[m], 96]\\n\\t\"\n        \"ldp       x27, x28, [%[m], 112]\\n\\t\"\n        \"# i = 0\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"ldp\tx10, x11, [%[a], 0]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mul\tx8, %[mp], x10\\n\\t\"\n        \"# a[i+0] += m[0] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 0]\\n\\t\"\n        \"mul\t\tx6, x12, x8\\n\\t\"\n        \"umulh\tx7, x12, x8\\n\\t\"\n        \"adds\tx10, x10, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"# a[i+1] += m[1] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 8]\\n\\t\"\n        \"mul\t\tx6, x13, x8\\n\\t\"\n        \"umulh\tx7, x13, x8\\n\\t\"\n        \"adds\tx10, x11, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx10, x10, x5\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+2] += m[2] * mu\\n\\t\"\n        \"ldr\tx11, [%[a], 16]\\n\\t\"\n        \"mul\t\tx6, x14, x8\\n\\t\"\n        \"umulh\tx7, x14, x8\\n\\t\"\n        \"adds\tx11, x11, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx11, x11, x4\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+3] += m[3] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 24]\\n\\t\"\n        \"mul\t\tx6, x15, x8\\n\\t\"\n        \"umulh\tx7, x15, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 24]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+4] += m[4] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 32]\\n\\t\"\n        \"mul\t\tx6, x16, x8\\n\\t\"\n        \"umulh\tx7, x16, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 32]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+5] += m[5] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 40]\\n\\t\"\n        \"mul\t\tx6, x17, x8\\n\\t\"\n        \"umulh\tx7, x17, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 40]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+6] += m[6] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 48]\\n\\t\"\n        \"mul\t\tx6, x19, x8\\n\\t\"\n        \"umulh\tx7, x19, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 48]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+7] += m[7] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 56]\\n\\t\"\n        \"mul\t\tx6, x20, x8\\n\\t\"\n        \"umulh\tx7, x20, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 56]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+8] += m[8] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"mul\t\tx6, x21, x8\\n\\t\"\n        \"umulh\tx7, x21, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 64]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+9] += m[9] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"mul\t\tx6, x22, x8\\n\\t\"\n        \"umulh\tx7, x22, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 72]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+10] += m[10] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"mul\t\tx6, x23, x8\\n\\t\"\n        \"umulh\tx7, x23, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 80]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+11] += m[11] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"mul\t\tx6, x24, x8\\n\\t\"\n        \"umulh\tx7, x24, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 88]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+12] += m[12] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"mul\t\tx6, x25, x8\\n\\t\"\n        \"umulh\tx7, x25, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 96]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+13] += m[13] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"mul\t\tx6, x26, x8\\n\\t\"\n        \"umulh\tx7, x26, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 104]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+14] += m[14] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"mul\t\tx6, x27, x8\\n\\t\"\n        \"umulh\tx7, x27, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 112]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+15] += m[15] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"mul\t\tx6, x28, x8\\n\\t\"\n        \"umulh\tx7, x28, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 120]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+16] += m[16] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 128]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 128]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+17] += m[17] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 136]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 136]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+18] += m[18] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 144]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 144]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+19] += m[19] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 152]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 152]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+20] += m[20] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 160]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 160]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+21] += m[21] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 168]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 168]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+22] += m[22] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 176]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 176]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+23] += m[23] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 184]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 184]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+24] += m[24] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 192]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 192]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+25] += m[25] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 200]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 200]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+26] += m[26] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 208]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 208]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+27] += m[27] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 216]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 216]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+28] += m[28] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 224]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 224]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+29] += m[29] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 232]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 232]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+30] += m[30] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 240]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 240]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+31] += m[31] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 248]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 248]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+32] += m[32] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 256]\\n\\t\"\n        \"ldr\tx9, [%[a], 256]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 256]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+33] += m[33] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 264]\\n\\t\"\n        \"ldr\tx9, [%[a], 264]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 264]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+34] += m[34] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 272]\\n\\t\"\n        \"ldr\tx9, [%[a], 272]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 272]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+35] += m[35] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 280]\\n\\t\"\n        \"ldr\tx9, [%[a], 280]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 280]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+36] += m[36] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 288]\\n\\t\"\n        \"ldr\tx9, [%[a], 288]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 288]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+37] += m[37] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 296]\\n\\t\"\n        \"ldr\tx9, [%[a], 296]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 296]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+38] += m[38] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 304]\\n\\t\"\n        \"ldr\tx9, [%[a], 304]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 304]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+39] += m[39] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 312]\\n\\t\"\n        \"ldr\tx9, [%[a], 312]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 312]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+40] += m[40] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 320]\\n\\t\"\n        \"ldr\tx9, [%[a], 320]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 320]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+41] += m[41] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 328]\\n\\t\"\n        \"ldr\tx9, [%[a], 328]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 328]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+42] += m[42] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 336]\\n\\t\"\n        \"ldr\tx9, [%[a], 336]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 336]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+43] += m[43] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 344]\\n\\t\"\n        \"ldr\tx9, [%[a], 344]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 344]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+44] += m[44] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 352]\\n\\t\"\n        \"ldr\tx9, [%[a], 352]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 352]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+45] += m[45] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 360]\\n\\t\"\n        \"ldr\tx9, [%[a], 360]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 360]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+46] += m[46] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 368]\\n\\t\"\n        \"ldr\tx9, [%[a], 368]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 368]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+47] += m[47] * mu\\n\\t\"\n        \"ldr\tx7, [%[m], 376]\\n\\t\"\n        \"ldr\tx9, [%[a], 376]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx7, x7, %[ca]\\n\\t\"\n        \"cset  %[ca], cs\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 376]\\n\\t\"\n        \"ldr\tx9, [%[a], 384]\\n\\t\"\n        \"adcs\tx9, x9, x7\\n\\t\"\n        \"str\tx9, [%[a], 384]\\n\\t\"\n        \"adc\t%[ca], %[ca], xzr\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"add\t%[a], %[a], 8\\n\\t\"\n        \"add\tx3, x3, 8\\n\\t\"\n        \"cmp\tx3, 384\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tx10, [%[a], 0]\\n\\t\"\n        \"str\tx11, [%[a], 8]\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\", \"x12\", \"x13\", \"x14\", \"x15\", \"x16\", \"x17\", \"x19\", \"x20\", \"x21\", \"x22\", \"x23\", \"x24\", \"x25\", \"x26\", \"x27\", \"x28\"\n    );\n\n    sp_3072_cond_sub_48(a - 48, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_48(r, a, b);\n    sp_3072_mont_reduce_48(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_48(r, a);\n    sp_3072_mont_reduce_48(r, m, mp);\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n */\nstatic sp_digit div_3072_word_48(sp_digit d1, sp_digit d0, sp_digit div)\n{\n    sp_digit r;\n\n    __asm__ __volatile__ (\n        \"lsr\tx5, %[div], 32\\n\\t\"\n        \"add\tx5, x5, 1\\n\\t\"\n\n        \"udiv\tx3, %[d1], x5\\n\\t\"\n        \"lsl\tx6, x3, 32\\n\\t\"\n        \"mul\tx4, %[div], x6\\n\\t\"\n        \"umulh\tx3, %[div], x6\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"udiv\tx3, %[d1], x5\\n\\t\"\n        \"lsl\tx3, x3, 32\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"lsl\tx3, %[d1], 32\\n\\t\"\n        \"orr\tx3, x3, %[d0], lsr 32\\n\\t\"\n\n        \"udiv\tx3, x3, x5\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"lsl\tx3, %[d1], 32\\n\\t\"\n        \"orr\tx3, x3, %[d0], lsr 32\\n\\t\"\n\n        \"udiv\tx3, x3, x5\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"udiv\tx3, %[d0], %[div]\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx3, %[div], x3\\n\\t\"\n        \"sub\t%[d0], %[d0], x3\\n\\t\"\n        \"mov\t%[r], x6\\n\\t\"\n\n        : [r] \"=r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_48(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<48; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 48; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic int64_t sp_3072_cmp_48(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = -1;\n    sp_digit one = 1;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tx3, -1\\n\\t\"\n        \"mov\tx6, 376\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tx4, [%[a], x6]\\n\\t\"\n        \"ldr\tx5, [%[b], x6]\\n\\t\"\n        \"and\tx4, x4, x3\\n\\t\"\n        \"and\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"subs\tx6, x6, #8\\n\\t\"\n        \"b.cs\t1b\\n\\t\"\n        \"eor\t%[r], %[r], x3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tx3, -1\\n\\t\"\n        \"ldr\t\tx4, [%[a], 376]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 376]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 368]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 368]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 360]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 360]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 352]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 352]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 344]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 344]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 336]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 336]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 328]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 328]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 320]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 320]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 312]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 312]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 304]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 304]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 296]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 296]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 288]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 288]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 280]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 280]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 272]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 272]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 264]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 264]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 256]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 256]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 248]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 248]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 240]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 240]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 232]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 232]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 224]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 224]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 216]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 216]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 208]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 208]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 200]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 200]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 192]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 192]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 184]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 184]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 176]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 176]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 168]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 168]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 160]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 160]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 152]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 152]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 144]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 144]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 136]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 136]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 128]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 128]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 120]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 120]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 112]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 112]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 104]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 104]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 96]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 96]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 88]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 88]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 80]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 80]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 72]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 72]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 64]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 64]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 56]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 56]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 48]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 48]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 40]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 40]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 32]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 32]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 24]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 24]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 16]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 16]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 8]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 8]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 0]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 0]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"eor\t%[r], %[r], x3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n#endif\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_48(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[96], t2[49];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[47];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 48);\n    for (i=47; i>=0; i--) {\n        r1 = div_3072_word_48(t1[48 + i], t1[48 + i - 1], div);\n\n        sp_3072_mul_d_48(t2, d, r1);\n        t1[48 + i] += sp_3072_sub_in_place_48(&t1[i], t2);\n        t1[48 + i] -= t2[48];\n        sp_3072_mask_48(t2, d, t1[48 + i]);\n        t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], t2);\n        sp_3072_mask_48(t2, d, t1[48 + i]);\n        t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_3072_cmp_48(t1, d) >= 0;\n    sp_3072_cond_sub_48(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_48(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_48(a, m, NULL, r);\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_48_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[96], t2[49];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[47];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 48);\n    for (i=47; i>=0; i--) {\n        r1 = div_3072_word_48(t1[48 + i], t1[48 + i - 1], div);\n\n        sp_3072_mul_d_48(t2, d, r1);\n        t1[48 + i] += sp_3072_sub_in_place_48(&t1[i], t2);\n        t1[48 + i] -= t2[48];\n        if (t1[48 + i] != 0) {\n            t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], d);\n            if (t1[48 + i] != 0)\n                t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_3072_cmp_48(t1, d) >= 0;\n    sp_3072_cond_sub_48(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_48_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_48_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][96];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 96, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 96;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_48(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 48U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_48(t[1] + 48, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_48(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 48, a, sizeof(sp_digit) * 48);\n            err = sp_3072_mod_48(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_48(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_48(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_48(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_48(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_48(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_48(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_48(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_48(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_48(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_48(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_48(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_48(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_48(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_48(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0) {\n            c = 64;\n        }\n        c -= bits % 4;\n        if (c == 64) {\n            c = 60;\n        }\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 48);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 60;\n                n <<= 4;\n                c = 60;\n            }\n            else if (c < 4) {\n                y = n >> 60;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 60) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n\n            sp_3072_mont_mul_48(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[48], 0, sizeof(sp_digit) * 48U);\n        sp_3072_mont_reduce_48(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_48(r, m) >= 0);\n        sp_3072_cond_sub_48(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][96];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 96, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 96;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_48(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 48U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_48(t[1] + 48, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_48(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 48, a, sizeof(sp_digit) * 48);\n            err = sp_3072_mod_48(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_48(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_48(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_48(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_48(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_48(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_48(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_48(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_48(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_48(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_48(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_48(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_48(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_48(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_48(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_48(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_48(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_48(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_48(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_48(t[20], t[10], m, mp);\n        sp_3072_mont_mul_48(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_48(t[22], t[11], m, mp);\n        sp_3072_mont_mul_48(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_48(t[24], t[12], m, mp);\n        sp_3072_mont_mul_48(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_48(t[26], t[13], m, mp);\n        sp_3072_mont_mul_48(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_48(t[28], t[14], m, mp);\n        sp_3072_mont_mul_48(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_48(t[30], t[15], m, mp);\n        sp_3072_mont_mul_48(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0) {\n            c = 64;\n        }\n        c -= bits % 5;\n        if (c == 64) {\n            c = 59;\n        }\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 48);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 59;\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = n >> 59;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n\n            sp_3072_mont_mul_48(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[48], 0, sizeof(sp_digit) * 48U);\n        sp_3072_mont_reduce_48(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_48(r, m) >= 0);\n        sp_3072_cond_sub_48(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[96], md[48], rd[96];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1];\n    int err = MP_OKAY;\n\n    if (*outLen < 384)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 64 || inLen > 384 ||\n                                                     mp_count_bits(mm) != 3072))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 48 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 48 * 2;\n        m = r + 48 * 2;\n        ah = a + 48;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 48;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(ah, 48, in, inLen);\n#if DIGIT_BIT >= 64\n        e[0] = em->dp[0];\n#else\n        e[0] = em->dp[0];\n        if (em->used > 1)\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e[0] == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(m, 48, mm);\n\n        if (e[0] == 0x3) {\n            if (err == MP_OKAY) {\n                sp_3072_sqr_48(r, ah);\n                err = sp_3072_mod_48_cond(r, r, m);\n            }\n            if (err == MP_OKAY) {\n                sp_3072_mul_48(r, ah, r);\n                err = sp_3072_mod_48_cond(r, r, m);\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_3072_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 48);\n            err = sp_3072_mod_48_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=63; i>=0; i--)\n                    if (e[0] >> i)\n                        break;\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 48);\n                for (i--; i>=0; i--) {\n                    sp_3072_mont_sqr_48(r, r, m, mp);\n                    if (((e[0] >> i) & 1) == 1)\n                        sp_3072_mont_mul_48(r, r, a, m, mp);\n                }\n                XMEMSET(&r[48], 0, sizeof(sp_digit) * 48);\n                sp_3072_mont_reduce_48(r, m, mp);\n\n                for (i = 47; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_3072_sub_in_place_48(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[48 * 2];\n    sp_digit pd[24], qd[24], dpd[24];\n    sp_digit tmpad[48], tmpbd[48];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 384)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 384 || mp_count_bits(mm) != 3072))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 24 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 48 * 2;\n        q = p + 24;\n        qi = dq = dp = q + 24;\n        tmpa = qi + 24;\n        tmpb = tmpa + 48;\n\n        tmp = t;\n        r = tmp + 48;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 48;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(a, 48, in, inLen);\n        sp_3072_from_mp(p, 24, pm);\n        sp_3072_from_mp(q, 24, qm);\n        sp_3072_from_mp(dp, 24, dpm);\n\n        err = sp_3072_mod_exp_24(tmpa, a, dp, 1536, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(dq, 24, dqm);\n        err = sp_3072_mod_exp_24(tmpb, a, dq, 1536, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_3072_sub_in_place_24(tmpa, tmpb);\n        sp_3072_mask_24(tmp, p, c);\n        sp_3072_add_24(tmpa, tmpa, tmp);\n\n        sp_3072_from_mp(qi, 24, qim);\n        sp_3072_mul_24(tmpa, tmpa, qi);\n        err = sp_3072_mod_24(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mul_24(tmpa, q, tmpa);\n        XMEMSET(&tmpb[24], 0, sizeof(sp_digit) * 24);\n        sp_3072_add_48(r, tmpb, tmpa);\n\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 24 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_3072_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 64\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 48);\n        r->used = 48;\n        mp_clamp(r);\n#elif DIGIT_BIT < 64\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 48; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 64) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 64 - s;\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 48; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 64 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 64 - s;\n            }\n            else {\n                s += 64;\n            }\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[96], e[48], m[48];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 48, base);\n        sp_3072_from_mp(e, 48, exp);\n        sp_3072_from_mp(m, 48, mod);\n\n        err = sp_3072_mod_exp_48(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_3072_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_3072\nstatic void sp_3072_lshift_48(sp_digit* r, sp_digit* a, byte n)\n{\n    __asm__ __volatile__ (\n        \"mov\tx6, 63\\n\\t\"\n        \"sub\tx6, x6, %[n]\\n\\t\"\n        \"ldr\tx3, [%[a], 376]\\n\\t\"\n        \"lsr\tx4, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx4, x4, x6\\n\\t\"\n        \"ldr\tx2, [%[a], 368]\\n\\t\"\n        \"str\tx4, [%[r], 384]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 360]\\n\\t\"\n        \"str\tx3, [%[r], 376]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 352]\\n\\t\"\n        \"str\tx2, [%[r], 368]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 344]\\n\\t\"\n        \"str\tx4, [%[r], 360]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 336]\\n\\t\"\n        \"str\tx3, [%[r], 352]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 328]\\n\\t\"\n        \"str\tx2, [%[r], 344]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 320]\\n\\t\"\n        \"str\tx4, [%[r], 336]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 312]\\n\\t\"\n        \"str\tx3, [%[r], 328]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 304]\\n\\t\"\n        \"str\tx2, [%[r], 320]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 296]\\n\\t\"\n        \"str\tx4, [%[r], 312]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 288]\\n\\t\"\n        \"str\tx3, [%[r], 304]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 280]\\n\\t\"\n        \"str\tx2, [%[r], 296]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 272]\\n\\t\"\n        \"str\tx4, [%[r], 288]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 264]\\n\\t\"\n        \"str\tx3, [%[r], 280]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 256]\\n\\t\"\n        \"str\tx2, [%[r], 272]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 248]\\n\\t\"\n        \"str\tx4, [%[r], 264]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 240]\\n\\t\"\n        \"str\tx3, [%[r], 256]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 232]\\n\\t\"\n        \"str\tx2, [%[r], 248]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 224]\\n\\t\"\n        \"str\tx4, [%[r], 240]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 216]\\n\\t\"\n        \"str\tx3, [%[r], 232]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 208]\\n\\t\"\n        \"str\tx2, [%[r], 224]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 200]\\n\\t\"\n        \"str\tx4, [%[r], 216]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 192]\\n\\t\"\n        \"str\tx3, [%[r], 208]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 184]\\n\\t\"\n        \"str\tx2, [%[r], 200]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 176]\\n\\t\"\n        \"str\tx4, [%[r], 192]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 168]\\n\\t\"\n        \"str\tx3, [%[r], 184]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 160]\\n\\t\"\n        \"str\tx2, [%[r], 176]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 152]\\n\\t\"\n        \"str\tx4, [%[r], 168]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 144]\\n\\t\"\n        \"str\tx3, [%[r], 160]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 136]\\n\\t\"\n        \"str\tx2, [%[r], 152]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 128]\\n\\t\"\n        \"str\tx4, [%[r], 144]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 120]\\n\\t\"\n        \"str\tx3, [%[r], 136]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 112]\\n\\t\"\n        \"str\tx2, [%[r], 128]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 104]\\n\\t\"\n        \"str\tx4, [%[r], 120]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 96]\\n\\t\"\n        \"str\tx3, [%[r], 112]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 88]\\n\\t\"\n        \"str\tx2, [%[r], 104]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 80]\\n\\t\"\n        \"str\tx4, [%[r], 96]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 72]\\n\\t\"\n        \"str\tx3, [%[r], 88]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 64]\\n\\t\"\n        \"str\tx2, [%[r], 80]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 56]\\n\\t\"\n        \"str\tx4, [%[r], 72]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 48]\\n\\t\"\n        \"str\tx3, [%[r], 64]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 40]\\n\\t\"\n        \"str\tx2, [%[r], 56]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 32]\\n\\t\"\n        \"str\tx4, [%[r], 48]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 24]\\n\\t\"\n        \"str\tx3, [%[r], 40]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 16]\\n\\t\"\n        \"str\tx2, [%[r], 32]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 8]\\n\\t\"\n        \"str\tx4, [%[r], 24]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 0]\\n\\t\"\n        \"str\tx3, [%[r], 16]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"str\tx4, [%[r]]\\n\\t\"\n        \"str\tx2, [%[r], 8]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [n] \"r\" (n)\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_2_48(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[96];\n    sp_digit td[49];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 145, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 96;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_48(norm, m);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0) {\n            c = 64;\n        }\n        c -= bits % 6;\n        if (c == 64) {\n            c = 58;\n        }\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        sp_3072_lshift_48(r, norm, y);\n        for (; i>=0 || c>=6; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 58;\n                n <<= 6;\n                c = 58;\n            }\n            else if (c < 6) {\n                y = n >> 58;\n                n = e[i--];\n                c = 6 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 58) & 0x3f;\n                n <<= 6;\n                c -= 6;\n            }\n\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n\n            sp_3072_lshift_48(r, r, y);\n            sp_3072_mul_d_48(tmp, norm, r[48]);\n            r[48] = 0;\n            o = sp_3072_add_48(r, r, tmp);\n            sp_3072_cond_sub_48(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[48], 0, sizeof(sp_digit) * 48U);\n        sp_3072_mont_reduce_48(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_48(r, m) >= 0);\n        sp_3072_cond_sub_48(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* HAVE_FFDHE_3072 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 384 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[96], e[48], m[48];\n    sp_digit* r = b;\n    word32 i;\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 384) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 48, base);\n        sp_3072_from_bin(e, 48, exp, expLen);\n        sp_3072_from_mp(m, 48, mod);\n\n    #ifdef HAVE_FFDHE_3072\n        if (base->used == 1 && base->dp[0] == 2 && m[47] == (sp_digit)-1)\n            err = sp_3072_mod_exp_2_48(r, e, expLen * 8, m);\n        else\n    #endif\n            err = sp_3072_mod_exp_48(r, b, e, expLen * 8, m, 0);\n\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n        for (i=0; i<384 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[48], e[24], m[24];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1536) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 24, base);\n        sp_3072_from_mp(e, 24, exp);\n        sp_3072_from_mp(m, 24, mod);\n\n        err = sp_3072_mod_exp_24(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 24, 0, sizeof(*r) * 24U);\n        err = sp_3072_to_mp(r, res);\n        res->used = mod->used;\n        mp_clamp(res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_3072 */\n\n#ifdef WOLFSSL_SP_4096\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 56U) {\n            r[j] &= 0xffffffffffffffffl;\n            s = 64U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 64\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 64\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffffffffffffl;\n        s = 64U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 64U) <= (word32)DIGIT_BIT) {\n            s += 64U;\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 64) {\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 64 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 512\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_4096_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 4096 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<64 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 64) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 64);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_4096_add_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx3, x4, [%[a], 0]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 16]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 0]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 16]\\n\\t\"\n        \"adds\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 0]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 16]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 32]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 48]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 32]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 48]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 32]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 48]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 64]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 80]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 64]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 80]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 64]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 80]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 96]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 112]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 96]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 112]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 96]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 112]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 128]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 144]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 128]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 144]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 128]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 144]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 160]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 176]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 160]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 176]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 160]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 176]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 192]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 208]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 192]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 208]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 192]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 208]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 224]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 240]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 224]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 240]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 224]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 240]\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_4096_sub_in_place_64(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx2, x3, [%[a], 0]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 16]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 0]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 16]\\n\\t\"\n        \"subs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 0]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 16]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 32]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 48]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 32]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 48]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 32]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 48]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 64]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 80]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 64]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 80]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 64]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 80]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 96]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 112]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 96]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 112]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 96]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 112]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 128]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 144]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 128]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 144]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 128]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 144]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 160]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 176]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 160]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 176]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 160]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 176]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 192]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 208]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 192]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 208]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 192]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 208]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 224]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 240]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 224]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 240]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 224]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 240]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 256]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 272]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 256]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 272]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 256]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 272]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 288]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 304]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 288]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 304]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 288]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 304]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 320]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 336]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 320]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 336]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 320]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 336]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 352]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 368]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 352]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 368]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 352]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 368]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 384]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 400]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 384]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 400]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 384]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 400]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 416]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 432]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 416]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 432]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 416]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 432]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 448]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 464]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 448]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 464]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 448]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 464]\\n\\t\"\n        \"ldp\tx2, x3, [%[a], 480]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 496]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 480]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 496]\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 480]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 496]\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_4096_add_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx3, x4, [%[a], 0]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 16]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 0]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 16]\\n\\t\"\n        \"adds\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 0]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 16]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 32]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 48]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 32]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 48]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 32]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 48]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 64]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 80]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 64]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 80]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 64]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 80]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 96]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 112]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 96]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 112]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 96]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 112]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 128]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 144]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 128]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 144]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 128]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 144]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 160]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 176]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 160]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 176]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 160]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 176]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 192]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 208]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 192]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 208]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 192]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 208]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 224]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 240]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 224]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 240]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 224]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 240]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 256]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 272]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 256]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 272]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 256]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 272]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 288]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 304]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 288]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 304]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 288]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 304]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 320]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 336]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 320]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 336]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 320]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 336]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 352]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 368]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 352]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 368]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 352]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 368]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 384]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 400]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 384]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 400]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 384]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 400]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 416]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 432]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 416]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 432]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 416]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 432]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 448]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 464]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 448]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 464]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 448]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 464]\\n\\t\"\n        \"ldp\tx3, x4, [%[a], 480]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 496]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 480]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 496]\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 480]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 496]\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_4096_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_digit tmp[32];\n\n    __asm__ __volatile__ (\n        \"#  A[0] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx3, x7, x8\\n\\t\"\n        \"umulh\tx4, x7, x8\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"str\tx3, [%[tmp]]\\n\\t\"\n        \"#  A[0] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 8]\\n\\t\"\n        \"#  A[0] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 16]\\n\\t\"\n        \"#  A[0] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 24]\\n\\t\"\n        \"#  A[0] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 32]\\n\\t\"\n        \"#  A[0] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 40]\\n\\t\"\n        \"#  A[0] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 48]\\n\\t\"\n        \"#  A[0] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 56]\\n\\t\"\n        \"#  A[0] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 64]\\n\\t\"\n        \"#  A[0] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[8] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 72]\\n\\t\"\n        \"#  A[0] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[8] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[9] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 80]\\n\\t\"\n        \"#  A[0] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[10] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 88]\\n\\t\"\n        \"#  A[0] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[8] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[10] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[11] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[12] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 96]\\n\\t\"\n        \"#  A[0] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[8] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[9] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[11] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[12] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[13] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 104]\\n\\t\"\n        \"#  A[0] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[10] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[12] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[13] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[14] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 112]\\n\\t\"\n        \"#  A[0] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[8] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[10] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[11] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[12] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[13] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[14] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[15] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 120]\\n\\t\"\n        \"#  A[0] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[8] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[9] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[11] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[12] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[13] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[14] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[15] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[16] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 128]\\n\\t\"\n        \"#  A[0] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[10] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[12] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[13] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[14] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[15] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[16] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[17] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 136]\\n\\t\"\n        \"#  A[0] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[8] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[10] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[11] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[12] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[13] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[14] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[15] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[16] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[17] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[18] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 144]\\n\\t\"\n        \"#  A[0] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[8] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[9] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[11] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[12] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[13] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[14] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[15] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[16] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[17] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[18] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[19] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 152]\\n\\t\"\n        \"#  A[0] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[10] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[12] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[13] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[14] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[15] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[16] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[17] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[18] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[19] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[20] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 160]\\n\\t\"\n        \"#  A[0] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[8] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[10] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[11] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[12] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[13] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[14] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[15] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[16] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[17] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[18] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[19] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[20] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[21] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 168]\\n\\t\"\n        \"#  A[0] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[8] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[9] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[11] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[12] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[13] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[14] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[15] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[16] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[17] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[18] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[19] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[20] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[21] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[22] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 176]\\n\\t\"\n        \"#  A[0] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[10] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[12] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[13] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[14] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[15] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[16] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[17] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[18] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[19] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[20] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[21] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[22] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[23] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 184]\\n\\t\"\n        \"#  A[0] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[8] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[10] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[11] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[12] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[13] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[14] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[15] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[16] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[17] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[18] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[19] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[20] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[21] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[22] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[23] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[24] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 192]\\n\\t\"\n        \"#  A[0] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[8] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[9] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[11] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[12] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[13] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[14] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[15] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[16] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[17] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[18] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[19] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[20] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[21] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[22] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[23] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[24] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[25] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 200]\\n\\t\"\n        \"#  A[0] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[10] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[12] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[13] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[14] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[15] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[16] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[17] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[18] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[19] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[20] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[21] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[22] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[23] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[24] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[25] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[26] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 208]\\n\\t\"\n        \"#  A[0] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[8] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[10] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[11] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[12] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[13] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[14] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[15] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[16] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[17] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[18] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[19] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[20] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[21] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[22] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[23] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[24] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[25] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[26] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[27] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 216]\\n\\t\"\n        \"#  A[0] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[8] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[9] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[11] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[12] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[13] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[14] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[15] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[16] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[17] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[18] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[19] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[20] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[21] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[22] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[23] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[24] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[25] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[26] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[27] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[28] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 224]\\n\\t\"\n        \"#  A[0] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[10] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[12] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[13] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[14] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[15] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[16] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[17] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[18] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[19] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[20] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[21] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[22] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[23] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[24] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[25] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[26] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[27] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[28] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[29] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 232]\\n\\t\"\n        \"#  A[0] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[8] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[10] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[11] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[12] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[13] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[14] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[15] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[16] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[17] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[18] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[19] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[20] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[21] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[22] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[23] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[24] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[25] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[26] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[27] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[28] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[29] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[30] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 240]\\n\\t\"\n        \"#  A[0] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 0]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[2] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[4] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[8] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[9] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[11] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[12] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[13] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[14] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[15] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[16] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[17] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[18] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[19] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[20] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[21] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[22] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[23] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[24] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[25] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[26] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[27] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[28] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[29] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[30] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[31] * B[0]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 0]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 248]\\n\\t\"\n        \"#  A[1] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 8]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[2] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[3] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[4] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[5] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[10] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[12] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[13] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[14] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[15] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[16] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[17] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[18] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[19] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[20] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[21] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[22] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[23] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[24] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[25] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[26] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[27] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[28] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[29] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[30] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[31] * B[1]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 8]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 256]\\n\\t\"\n        \"#  A[2] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 16]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[3] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[4] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[5] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[6] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[8] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[10] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[11] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[12] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[13] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[14] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[15] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[16] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[17] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[18] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[19] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[20] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[21] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[22] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[23] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[24] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[25] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[26] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[27] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[28] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[29] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[30] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[31] * B[2]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 16]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 264]\\n\\t\"\n        \"#  A[3] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 24]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[4] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[5] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[6] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[7] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[8] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[9] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[11] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[12] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[13] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[14] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[15] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[16] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[17] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[18] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[19] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[20] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[21] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[22] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[23] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[24] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[25] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[26] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[27] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[28] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[29] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[30] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[31] * B[3]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 24]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 272]\\n\\t\"\n        \"#  A[4] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 32]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[5] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[6] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[7] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[8] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[10] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[12] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[13] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[14] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[15] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[16] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[17] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[18] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[19] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[20] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[21] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[22] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[23] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[24] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[25] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[26] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[27] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[28] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[29] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[30] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[31] * B[4]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 32]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 280]\\n\\t\"\n        \"#  A[5] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 40]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[6] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[7] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[8] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[9] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[10] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[11] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[12] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[13] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[14] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[15] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[16] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[17] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[18] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[19] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[20] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[21] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[22] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[23] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[24] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[25] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[26] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[27] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[28] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[29] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[30] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[31] * B[5]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 40]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 288]\\n\\t\"\n        \"#  A[6] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[7] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[8] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[9] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[10] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[11] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[12] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[13] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[14] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[15] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[16] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[17] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[18] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[19] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[20] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[21] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[22] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[23] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[24] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[25] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[26] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[27] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[28] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[29] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[30] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[31] * B[6]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 48]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 296]\\n\\t\"\n        \"#  A[7] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 56]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[8] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[9] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[10] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[11] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[12] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[13] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[14] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[15] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[16] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[17] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[18] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[19] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[20] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[21] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[22] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[23] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[24] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[25] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[26] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[27] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[28] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[29] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[30] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[31] * B[7]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 56]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 304]\\n\\t\"\n        \"#  A[8] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 64]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[9] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[10] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[11] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[12] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[13] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[14] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[15] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[16] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[17] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[18] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[19] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[20] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[21] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[22] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[23] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[24] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[25] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[26] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[27] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[28] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[29] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[30] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[31] * B[8]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 64]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 312]\\n\\t\"\n        \"#  A[9] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 72]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[10] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[11] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[12] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[13] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[14] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[15] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[16] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[17] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[18] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[19] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[20] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[21] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[22] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[23] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[24] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[25] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[26] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[27] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[28] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[29] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[30] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[31] * B[9]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 72]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 320]\\n\\t\"\n        \"#  A[10] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 80]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[11] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[12] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[13] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[14] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[15] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[16] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[17] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[18] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[19] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[20] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[21] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[22] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[23] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[24] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[25] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[26] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[27] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[28] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[29] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[30] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[31] * B[10]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 80]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 328]\\n\\t\"\n        \"#  A[11] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 88]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[12] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[13] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[14] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[15] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[16] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[17] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[18] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[19] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[20] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[21] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[22] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[23] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[24] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[25] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[26] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[27] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[28] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[29] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[30] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[31] * B[11]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 88]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 336]\\n\\t\"\n        \"#  A[12] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 96]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[13] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[14] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[15] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[16] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[17] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[18] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[19] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[20] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[21] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[22] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[23] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[24] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[25] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[26] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[27] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[28] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[29] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[30] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[31] * B[12]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 96]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 344]\\n\\t\"\n        \"#  A[13] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 104]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[14] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[15] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[16] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[17] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[18] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[19] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[20] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[21] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[22] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[23] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[24] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[25] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[26] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[27] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[28] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[29] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[30] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[31] * B[13]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 104]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 352]\\n\\t\"\n        \"#  A[14] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 112]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[15] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[16] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[17] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[18] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[19] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[20] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[21] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[22] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[23] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[24] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[25] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[26] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[27] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[28] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[29] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[30] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[31] * B[14]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 112]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 360]\\n\\t\"\n        \"#  A[15] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 120]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[16] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[17] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[18] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[19] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[20] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[21] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[22] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[23] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[24] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[25] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[26] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[27] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[28] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[29] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[30] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[31] * B[15]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 120]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 368]\\n\\t\"\n        \"#  A[16] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 128]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[17] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[18] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[19] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[20] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[21] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[22] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[23] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[24] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[25] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[26] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[27] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[28] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[29] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[30] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[31] * B[16]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 128]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 376]\\n\\t\"\n        \"#  A[17] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 136]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[18] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[19] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[20] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[21] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[22] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[23] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[24] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[25] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[26] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[27] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[28] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[29] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[30] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[31] * B[17]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 136]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 384]\\n\\t\"\n        \"#  A[18] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 144]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[19] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[20] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[21] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[22] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[23] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[24] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[25] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[26] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[27] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[28] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[29] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[30] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[31] * B[18]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 144]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 392]\\n\\t\"\n        \"#  A[19] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 152]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[20] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[21] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[22] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[23] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[24] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[25] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[26] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[27] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[28] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[29] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[30] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[31] * B[19]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 152]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 400]\\n\\t\"\n        \"#  A[20] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 160]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[21] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[22] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[23] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[24] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[25] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[26] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[27] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[28] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[29] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[30] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[31] * B[20]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 160]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 408]\\n\\t\"\n        \"#  A[21] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 168]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[22] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[23] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[24] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[25] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[26] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[27] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[28] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[29] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[30] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[31] * B[21]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 168]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 416]\\n\\t\"\n        \"#  A[22] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 176]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[23] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[24] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[25] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[26] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[27] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[28] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[29] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[30] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[31] * B[22]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 176]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 424]\\n\\t\"\n        \"#  A[23] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 184]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[24] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[25] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[26] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[27] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[28] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[29] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[30] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[31] * B[23]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 184]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 432]\\n\\t\"\n        \"#  A[24] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 192]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[25] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[26] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[27] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[28] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[29] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[30] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[31] * B[24]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 192]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 440]\\n\\t\"\n        \"#  A[25] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 200]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[26] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[27] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[28] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[29] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[30] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[31] * B[25]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 200]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 448]\\n\\t\"\n        \"#  A[26] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 208]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[27] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[28] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[29] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[30] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[31] * B[26]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 208]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 456]\\n\\t\"\n        \"#  A[27] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 216]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[28] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[29] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[30] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[31] * B[27]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 216]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 464]\\n\\t\"\n        \"#  A[28] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 224]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[29] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[30] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[31] * B[28]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 224]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 472]\\n\\t\"\n        \"#  A[29] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 232]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[30] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[31] * B[29]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 232]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[r], 480]\\n\\t\"\n        \"#  A[30] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 240]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[31] * B[30]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 240]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 488]\\n\\t\"\n        \"#  A[31] * B[31]\\n\\t\"\n        \"ldr\tx7, [%[a], 248]\\n\\t\"\n        \"ldr\tx8, [%[b], 248]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"stp\tx5, x3, [%[r], 496]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [tmp] \"r\" (tmp)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_4096_mask_32(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<32; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[64];\n    sp_digit a1[32];\n    sp_digit b1[32];\n    sp_digit z2[64];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_32(a1, a, &a[32]);\n    cb = sp_2048_add_32(b1, b, &b[32]);\n    u  = ca & cb;\n    sp_2048_mul_32(z1, a1, b1);\n    sp_2048_mul_32(z2, &a[32], &b[32]);\n    sp_2048_mul_32(z0, a, b);\n    sp_2048_mask_32(r + 64, a1, 0 - cb);\n    sp_2048_mask_32(b1, b1, 0 - ca);\n    u += sp_2048_add_32(r + 64, r + 64, b1);\n    u += sp_4096_sub_in_place_64(z1, z2);\n    u += sp_4096_sub_in_place_64(z1, z0);\n    u += sp_4096_add_64(r + 32, r + 32, z1);\n    r[96] = u;\n    XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));\n    (void)sp_4096_add_64(r + 64, r + 64, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_4096_sqr_32(sp_digit* r, const sp_digit* a)\n{\n    sp_digit tmp[32];\n\n    __asm__ __volatile__ (\n        \"#  A[0] * A[0]\\n\\t\"\n        \"ldr\tx9, [%[a], 0]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx3, x9, x9\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"str\tx8, [%[tmp]]\\n\\t\"\n        \"#  A[0] * A[1]\\n\\t\"\n        \"ldr\tx9, [%[a], 8]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, xzr, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 8]\\n\\t\"\n        \"#  A[0] * A[2]\\n\\t\"\n        \"ldr\tx9, [%[a], 16]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[1] * A[1]\\n\\t\"\n        \"ldr\tx9, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 16]\\n\\t\"\n        \"#  A[0] * A[3]\\n\\t\"\n        \"ldr\tx9, [%[a], 24]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[1] * A[2]\\n\\t\"\n        \"ldr\tx9, [%[a], 16]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx2, [%[tmp], 24]\\n\\t\"\n        \"#  A[0] * A[4]\\n\\t\"\n        \"ldr\tx9, [%[a], 32]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, xzr, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"#  A[1] * A[3]\\n\\t\"\n        \"ldr\tx9, [%[a], 24]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"#  A[2] * A[2]\\n\\t\"\n        \"ldr\tx9, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 32]\\n\\t\"\n        \"#  A[0] * A[5]\\n\\t\"\n        \"ldr\tx9, [%[a], 40]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[4]\\n\\t\"\n        \"ldr\tx9, [%[a], 32]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[3]\\n\\t\"\n        \"ldr\tx9, [%[a], 24]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[tmp], 40]\\n\\t\"\n        \"#  A[0] * A[6]\\n\\t\"\n        \"ldr\tx9, [%[a], 48]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[5]\\n\\t\"\n        \"ldr\tx9, [%[a], 40]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[4]\\n\\t\"\n        \"ldr\tx9, [%[a], 32]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[3]\\n\\t\"\n        \"ldr\tx9, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[tmp], 48]\\n\\t\"\n        \"#  A[0] * A[7]\\n\\t\"\n        \"ldr\tx9, [%[a], 56]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[6]\\n\\t\"\n        \"ldr\tx9, [%[a], 48]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[5]\\n\\t\"\n        \"ldr\tx9, [%[a], 40]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[4]\\n\\t\"\n        \"ldr\tx9, [%[a], 32]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[tmp], 56]\\n\\t\"\n        \"#  A[0] * A[8]\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[7]\\n\\t\"\n        \"ldr\tx9, [%[a], 56]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[6]\\n\\t\"\n        \"ldr\tx9, [%[a], 48]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[5]\\n\\t\"\n        \"ldr\tx9, [%[a], 40]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[4]\\n\\t\"\n        \"ldr\tx9, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[tmp], 64]\\n\\t\"\n        \"#  A[0] * A[9]\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[8]\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[7]\\n\\t\"\n        \"ldr\tx9, [%[a], 56]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[6]\\n\\t\"\n        \"ldr\tx9, [%[a], 48]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[5]\\n\\t\"\n        \"ldr\tx9, [%[a], 40]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[tmp], 72]\\n\\t\"\n        \"#  A[0] * A[10]\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[9]\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[8]\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[7]\\n\\t\"\n        \"ldr\tx9, [%[a], 56]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[6]\\n\\t\"\n        \"ldr\tx9, [%[a], 48]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[5]\\n\\t\"\n        \"ldr\tx9, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[tmp], 80]\\n\\t\"\n        \"#  A[0] * A[11]\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[10]\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[9]\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[8]\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[7]\\n\\t\"\n        \"ldr\tx9, [%[a], 56]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[6]\\n\\t\"\n        \"ldr\tx9, [%[a], 48]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[tmp], 88]\\n\\t\"\n        \"#  A[0] * A[12]\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[11]\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[10]\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[9]\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[8]\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[7]\\n\\t\"\n        \"ldr\tx9, [%[a], 56]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[6]\\n\\t\"\n        \"ldr\tx9, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[tmp], 96]\\n\\t\"\n        \"#  A[0] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[12]\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[11]\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[10]\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[9]\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[8]\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[7]\\n\\t\"\n        \"ldr\tx9, [%[a], 56]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[tmp], 104]\\n\\t\"\n        \"#  A[0] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[12]\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[11]\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[10]\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[9]\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[8]\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[7]\\n\\t\"\n        \"ldr\tx9, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[tmp], 112]\\n\\t\"\n        \"#  A[0] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[12]\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[11]\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[10]\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[9]\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[8]\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[tmp], 120]\\n\\t\"\n        \"#  A[0] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[12]\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[11]\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[10]\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[9]\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[8]\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[tmp], 128]\\n\\t\"\n        \"#  A[0] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[12]\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[11]\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[10]\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[9]\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[tmp], 136]\\n\\t\"\n        \"#  A[0] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[12]\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[11]\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[10]\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[9]\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[tmp], 144]\\n\\t\"\n        \"#  A[0] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[12]\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[11]\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[10]\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[tmp], 152]\\n\\t\"\n        \"#  A[0] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[12]\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[11]\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[10]\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[tmp], 160]\\n\\t\"\n        \"#  A[0] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[12]\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[11]\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[tmp], 168]\\n\\t\"\n        \"#  A[0] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[12]\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[11]\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[tmp], 176]\\n\\t\"\n        \"#  A[0] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[12]\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[tmp], 184]\\n\\t\"\n        \"#  A[0] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[12]\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[tmp], 192]\\n\\t\"\n        \"#  A[0] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[tmp], 200]\\n\\t\"\n        \"#  A[0] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[13]\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[tmp], 208]\\n\\t\"\n        \"#  A[0] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[tmp], 216]\\n\\t\"\n        \"#  A[0] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[14]\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[tmp], 224]\\n\\t\"\n        \"#  A[0] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[tmp], 232]\\n\\t\"\n        \"#  A[0] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[15]\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[tmp], 240]\\n\\t\"\n        \"#  A[0] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 0]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[1] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[2] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[tmp], 248]\\n\\t\"\n        \"#  A[1] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 8]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[2] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[3] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[16]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[r], 256]\\n\\t\"\n        \"#  A[2] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 16]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[3] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[4] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[r], 264]\\n\\t\"\n        \"#  A[3] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 24]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[4] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[5] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[17] * A[17]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[r], 272]\\n\\t\"\n        \"#  A[4] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 32]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[5] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[6] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[17] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[r], 280]\\n\\t\"\n        \"#  A[5] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 40]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[6] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[7] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[17] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[18] * A[18]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[r], 288]\\n\\t\"\n        \"#  A[6] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 48]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[7] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[8] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[17] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[18] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"ldr\tx10, [%[a], 144]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[r], 296]\\n\\t\"\n        \"#  A[7] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 56]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[8] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[9] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[17] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[18] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 144]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[19] * A[19]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[r], 304]\\n\\t\"\n        \"#  A[8] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 64]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[9] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[10] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[17] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[18] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 144]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[19] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"ldr\tx10, [%[a], 152]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[r], 312]\\n\\t\"\n        \"#  A[9] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 72]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[10] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[11] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[17] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[18] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 144]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[19] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 152]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[20] * A[20]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[r], 320]\\n\\t\"\n        \"#  A[10] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 80]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[11] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[12] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[17] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[18] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 144]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[19] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 152]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[20] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"ldr\tx10, [%[a], 160]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[r], 328]\\n\\t\"\n        \"#  A[11] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 88]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[12] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[13] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[17] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[18] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 144]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[19] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 152]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[20] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 160]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[21] * A[21]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[r], 336]\\n\\t\"\n        \"#  A[12] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 96]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[13] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[14] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[17] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[18] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 144]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[19] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 152]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[20] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 160]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[21] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"ldr\tx10, [%[a], 168]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[r], 344]\\n\\t\"\n        \"#  A[13] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 104]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[14] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[15] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[17] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[18] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 144]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[19] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 152]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[20] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 160]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[21] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 168]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[22] * A[22]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[r], 352]\\n\\t\"\n        \"#  A[14] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 112]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[15] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[16] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[17] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[18] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 144]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[19] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 152]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[20] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 160]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[21] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 168]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[22] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"ldr\tx10, [%[a], 176]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[r], 360]\\n\\t\"\n        \"#  A[15] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 120]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[16] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[17] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[18] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 144]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[19] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 152]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[20] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 160]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[21] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 168]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[22] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 176]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[23] * A[23]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[r], 368]\\n\\t\"\n        \"#  A[16] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 128]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[17] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[18] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 144]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[19] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 152]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[20] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 160]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[21] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 168]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[22] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 176]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[23] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"ldr\tx10, [%[a], 184]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[r], 376]\\n\\t\"\n        \"#  A[17] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 136]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[18] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 144]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[19] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 152]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[20] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 160]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[21] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 168]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[22] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 176]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[23] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 184]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[24] * A[24]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[r], 384]\\n\\t\"\n        \"#  A[18] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 144]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[19] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 152]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[20] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 160]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[21] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 168]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[22] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 176]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[23] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 184]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[24] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"ldr\tx10, [%[a], 192]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[r], 392]\\n\\t\"\n        \"#  A[19] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 152]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[20] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 160]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[21] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 168]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[22] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 176]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[23] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 184]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[24] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 192]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[25] * A[25]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[r], 400]\\n\\t\"\n        \"#  A[20] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 160]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[21] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 168]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[22] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 176]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[23] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 184]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[24] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 192]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[25] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"ldr\tx10, [%[a], 200]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[r], 408]\\n\\t\"\n        \"#  A[21] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 168]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[22] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 176]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[23] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 184]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[24] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 192]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[25] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 200]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[26] * A[26]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[r], 416]\\n\\t\"\n        \"#  A[22] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 176]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[23] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 184]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[24] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 192]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[25] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 200]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[26] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"ldr\tx10, [%[a], 208]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[r], 424]\\n\\t\"\n        \"#  A[23] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 184]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[24] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 192]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[25] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 200]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[26] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 208]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[27] * A[27]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[r], 432]\\n\\t\"\n        \"#  A[24] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 192]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx2, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[25] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 200]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[26] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 208]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[27] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"ldr\tx10, [%[a], 216]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx3, x3, x5\\n\\t\"\n        \"adcs\tx4, x4, x6\\n\\t\"\n        \"adc\tx2, x2, x7\\n\\t\"\n        \"str\tx3, [%[r], 440]\\n\\t\"\n        \"#  A[25] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 200]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[26] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 208]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[27] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 216]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[28] * A[28]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx4, x4, x5\\n\\t\"\n        \"adcs\tx2, x2, x6\\n\\t\"\n        \"adc\tx3, x3, x7\\n\\t\"\n        \"str\tx4, [%[r], 448]\\n\\t\"\n        \"#  A[26] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 208]\\n\\t\"\n        \"mul\tx5, x9, x10\\n\\t\"\n        \"umulh\tx6, x9, x10\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"#  A[27] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 216]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"#  A[28] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"ldr\tx10, [%[a], 224]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx5, x5, x8\\n\\t\"\n        \"adcs\tx6, x6, x9\\n\\t\"\n        \"adc\tx7, x7, xzr\\n\\t\"\n        \"adds\tx5, x5, x5\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"adc\tx7, x7, x7\\n\\t\"\n        \"adds\tx2, x2, x5\\n\\t\"\n        \"adcs\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx2, [%[r], 456]\\n\\t\"\n        \"#  A[27] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 216]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, xzr, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"#  A[28] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 224]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"#  A[29] * A[29]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"str\tx3, [%[r], 464]\\n\\t\"\n        \"#  A[28] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 224]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[29] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"ldr\tx10, [%[a], 232]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 472]\\n\\t\"\n        \"#  A[29] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 232]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[30] * A[30]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx2, [%[r], 480]\\n\\t\"\n        \"#  A[30] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"ldr\tx10, [%[a], 240]\\n\\t\"\n        \"mul\tx8, x9, x10\\n\\t\"\n        \"umulh\tx9, x9, x10\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, xzr, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"str\tx3, [%[r], 488]\\n\\t\"\n        \"#  A[31] * A[31]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"mul\tx8, x9, x9\\n\\t\"\n        \"umulh\tx9, x9, x9\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adc\tx2, x2, x9\\n\\t\"\n        \"stp\tx4, x2, [%[r], 496]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [tmp] \"r\" (tmp)\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x8\", \"x9\", \"x10\", \"x5\", \"x6\", \"x7\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_64(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[64];\n    sp_digit z1[64];\n    sp_digit a1[32];\n    sp_digit u;\n\n    u = sp_2048_add_32(a1, a, &a[32]);\n    sp_2048_sqr_32(z1, a1);\n    sp_2048_sqr_32(z2, &a[32]);\n    sp_2048_sqr_32(z0, a);\n    sp_2048_mask_32(r + 64, a1, 0 - u);\n    u += sp_2048_add_32(r + 64, r + 64, r + 64);\n    u += sp_4096_sub_in_place_64(z1, z2);\n    u += sp_4096_sub_in_place_64(z1, z0);\n    u += sp_4096_add_64(r + 32, r + 32, z1);\n    r[96] = u;\n    XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));\n    (void)sp_4096_add_64(r + 64, r + 64, z2);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_4096_add_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tx11, %[a], 512\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], #-1\\n\\t\"\n        \"ldp\tx3, x4, [%[a]], #16\\n\\t\"\n        \"ldp\tx5, x6, [%[a]], #16\\n\\t\"\n        \"ldp\tx7, x8, [%[b]], #16\\n\\t\"\n        \"ldp\tx9, x10, [%[b]], #16\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r]], #16\\n\\t\"\n        \"stp\tx5, x6, [%[r]], #16\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        \"cmp\t%[a], x11\\n\\t\"\n        \"b.ne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_4096_sub_in_place_64(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"add\tx10, %[a], 512\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\t%[c], xzr, %[c]\\n\\t\"\n        \"ldp\tx2, x3, [%[a]]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], #16]\\n\\t\"\n        \"ldp\tx6, x7, [%[b]], #16\\n\\t\"\n        \"ldp\tx8, x9, [%[b]], #16\\n\\t\"\n        \"sbcs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a]], #16\\n\\t\"\n        \"stp\tx4, x5, [%[a]], #16\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        \"cmp\t%[a], x10\\n\\t\"\n        \"b.ne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_4096_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_digit tmp[128];\n\n    __asm__ __volatile__ (\n        \"mov\tx5, 0\\n\\t\"\n        \"mov\tx6, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"mov\tx8, 0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tx3, x5, 504\\n\\t\"\n        \"csel\tx3, xzr, x3, cc\\n\\t\"\n        \"sub\tx4, x5, x3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"ldr\tx11, [%[b], x4]\\n\\t\"\n        \"mul\tx9, x10, x11\\n\\t\"\n        \"umulh\tx10, x10, x11\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"add\tx3, x3, #8\\n\\t\"\n        \"sub\tx4, x4, #8\\n\\t\"\n        \"cmp\tx3, 512\\n\\t\"\n        \"b.eq\t3f\\n\\t\"\n        \"cmp\tx3, x5\\n\\t\"\n        \"b.le\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        \"mov\tx6, x7\\n\\t\"\n        \"mov\tx7, x8\\n\\t\"\n        \"mov\tx8, #0\\n\\t\"\n        \"add\tx5, x5, #8\\n\\t\"\n        \"cmp\tx5, 1008\\n\\t\"\n        \"b.le\t1b\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_4096_sqr_64(sp_digit* r, const sp_digit* a)\n{\n    sp_digit tmp[128];\n\n    __asm__ __volatile__ (\n        \"mov\tx6, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"mov\tx8, 0\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tx3, x5, 504\\n\\t\"\n        \"csel\tx3, xzr, x3, cc\\n\\t\"\n        \"sub\tx4, x5, x3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tx4, x3\\n\\t\"\n        \"b.eq\t4f\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"ldr\tx11, [%[a], x4]\\n\\t\"\n        \"mul\tx9, x10, x11\\n\\t\"\n        \"umulh\tx10, x10, x11\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"b.al\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"mul\tx9, x10, x10\\n\\t\"\n        \"umulh\tx10, x10, x10\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\tx3, x3, #8\\n\\t\"\n        \"sub\tx4, x4, #8\\n\\t\"\n        \"cmp\tx3, 512\\n\\t\"\n        \"b.eq\t3f\\n\\t\"\n        \"cmp\tx3, x4\\n\\t\"\n        \"b.gt\t3f\\n\\t\"\n        \"cmp\tx3, x5\\n\\t\"\n        \"b.le\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        \"mov\tx6, x7\\n\\t\"\n        \"mov\tx7, x8\\n\\t\"\n        \"mov\tx8, #0\\n\\t\"\n        \"add\tx5, x5, #8\\n\\t\"\n        \"cmp\tx5, 1008\\n\\t\"\n        \"b.le\t1b\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**64 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nstatic void sp_4096_mul_d_64(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tx8, [%[a]]\\n\\t\"\n        \"mul\tx5, %[b], x8\\n\\t\"\n        \"umulh\tx3, %[b], x8\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"str\tx5, [%[r]]\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"mov\tx9, #8\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tx8, [%[a], x9]\\n\\t\"\n        \"mul\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"str\tx3, [%[r], x9]\\n\\t\"\n        \"mov\tx3, x4\\n\\t\"\n        \"mov\tx4, x5\\n\\t\"\n        \"mov\tx5, #0\\n\\t\"\n        \"add\tx9, x9, #8\\n\\t\"\n        \"cmp\tx9, 512\\n\\t\"\n        \"b.lt\t1b\\n\\t\"\n        \"str\tx3, [%[r], 512]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tx8, [%[a]]\\n\\t\"\n        \"mul\tx3, %[b], x8\\n\\t\"\n        \"umulh\tx4, %[b], x8\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"str\tx3, [%[r]]\\n\\t\"\n        \"# A[1] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 8]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 8]\\n\\t\"\n        \"# A[2] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 16]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 16]\\n\\t\"\n        \"# A[3] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 24]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 24]\\n\\t\"\n        \"# A[4] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 32]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 32]\\n\\t\"\n        \"# A[5] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 40]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 40]\\n\\t\"\n        \"# A[6] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 48]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 48]\\n\\t\"\n        \"# A[7] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 56]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 56]\\n\\t\"\n        \"# A[8] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 64]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 64]\\n\\t\"\n        \"# A[9] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 72]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 72]\\n\\t\"\n        \"# A[10] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 80]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 80]\\n\\t\"\n        \"# A[11] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 88]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 88]\\n\\t\"\n        \"# A[12] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 96]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 96]\\n\\t\"\n        \"# A[13] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 104]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 104]\\n\\t\"\n        \"# A[14] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 112]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 112]\\n\\t\"\n        \"# A[15] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 120]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 120]\\n\\t\"\n        \"# A[16] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 128]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 128]\\n\\t\"\n        \"# A[17] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 136]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 136]\\n\\t\"\n        \"# A[18] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 144]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 144]\\n\\t\"\n        \"# A[19] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 152]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 152]\\n\\t\"\n        \"# A[20] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 160]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 160]\\n\\t\"\n        \"# A[21] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 168]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 168]\\n\\t\"\n        \"# A[22] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 176]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 176]\\n\\t\"\n        \"# A[23] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 184]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 184]\\n\\t\"\n        \"# A[24] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 192]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 192]\\n\\t\"\n        \"# A[25] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 200]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 200]\\n\\t\"\n        \"# A[26] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 208]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 208]\\n\\t\"\n        \"# A[27] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 216]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 216]\\n\\t\"\n        \"# A[28] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 224]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 224]\\n\\t\"\n        \"# A[29] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 232]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 232]\\n\\t\"\n        \"# A[30] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 240]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 240]\\n\\t\"\n        \"# A[31] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 248]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 248]\\n\\t\"\n        \"# A[32] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 256]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 256]\\n\\t\"\n        \"# A[33] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 264]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 264]\\n\\t\"\n        \"# A[34] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 272]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 272]\\n\\t\"\n        \"# A[35] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 280]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 280]\\n\\t\"\n        \"# A[36] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 288]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 288]\\n\\t\"\n        \"# A[37] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 296]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 296]\\n\\t\"\n        \"# A[38] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 304]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 304]\\n\\t\"\n        \"# A[39] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 312]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 312]\\n\\t\"\n        \"# A[40] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 320]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 320]\\n\\t\"\n        \"# A[41] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 328]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 328]\\n\\t\"\n        \"# A[42] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 336]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 336]\\n\\t\"\n        \"# A[43] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 344]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 344]\\n\\t\"\n        \"# A[44] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 352]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 352]\\n\\t\"\n        \"# A[45] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 360]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 360]\\n\\t\"\n        \"# A[46] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 368]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 368]\\n\\t\"\n        \"# A[47] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 376]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 376]\\n\\t\"\n        \"# A[48] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 384]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 384]\\n\\t\"\n        \"# A[49] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 392]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 392]\\n\\t\"\n        \"# A[50] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 400]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 400]\\n\\t\"\n        \"# A[51] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 408]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 408]\\n\\t\"\n        \"# A[52] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 416]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 416]\\n\\t\"\n        \"# A[53] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 424]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 424]\\n\\t\"\n        \"# A[54] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 432]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 432]\\n\\t\"\n        \"# A[55] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 440]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 440]\\n\\t\"\n        \"# A[56] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 448]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 448]\\n\\t\"\n        \"# A[57] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 456]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 456]\\n\\t\"\n        \"# A[58] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 464]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 464]\\n\\t\"\n        \"# A[59] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 472]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 472]\\n\\t\"\n        \"# A[60] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 480]\\n\\t\"\n        \"mov\t\tx5, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\t\tx5, xzr, xzr\\n\\t\"\n        \"str\t\tx3, [%[r], 480]\\n\\t\"\n        \"# A[61] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 488]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 488]\\n\\t\"\n        \"# A[62] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 496]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 496]\\n\\t\"\n        \"# A[63] * B\\n\\t\"\n        \"ldr\tx8, [%[a], 504]\\n\\t\"\n        \"mul\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx3, [%[r], 504]\\n\\t\"\n        \"str\tx4, [%[r], 512]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\"\n    );\n#endif\n}\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 4096 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_4096_mont_norm_64(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 64);\n\n    /* r = 2^n mod m */\n    sp_4096_sub_in_place_64(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic sp_digit sp_4096_cond_sub_64(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        sp_digit m)\n{\n    sp_digit c = 0;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tx8, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"subs\t%[c], xzr, %[c]\\n\\t\"\n        \"ldr\tx4, [%[a], x8]\\n\\t\"\n        \"ldr\tx5, [%[b], x8]\\n\\t\"\n        \"and\tx5, x5, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        \"str\tx4, [%[r], x8]\\n\\t\"\n        \"add\tx8, x8, #8\\n\\t\"\n        \"cmp\tx8, 512\\n\\t\"\n        \"b.lt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"x4\", \"x6\", \"x5\", \"x7\", \"x8\"\n    );\n#else\n    __asm__ __volatile__ (\n\n        \"ldr\t\tx4, [%[a], 0]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 8]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 0]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 8]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 0]\\n\\t\"\n        \"str\t\tx6, [%[r], 8]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 16]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 24]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 16]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 24]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 16]\\n\\t\"\n        \"str\t\tx6, [%[r], 24]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 32]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 40]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 32]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 40]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 32]\\n\\t\"\n        \"str\t\tx6, [%[r], 40]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 48]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 56]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 48]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 56]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 48]\\n\\t\"\n        \"str\t\tx6, [%[r], 56]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 64]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 72]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 64]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 72]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 64]\\n\\t\"\n        \"str\t\tx6, [%[r], 72]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 80]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 88]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 80]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 88]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 80]\\n\\t\"\n        \"str\t\tx6, [%[r], 88]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 96]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 104]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 96]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 104]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 96]\\n\\t\"\n        \"str\t\tx6, [%[r], 104]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 112]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 120]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 112]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 120]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 112]\\n\\t\"\n        \"str\t\tx6, [%[r], 120]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 128]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 136]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 128]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 136]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 128]\\n\\t\"\n        \"str\t\tx6, [%[r], 136]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 144]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 152]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 144]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 152]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 144]\\n\\t\"\n        \"str\t\tx6, [%[r], 152]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 160]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 168]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 160]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 168]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 160]\\n\\t\"\n        \"str\t\tx6, [%[r], 168]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 176]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 184]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 176]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 184]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 176]\\n\\t\"\n        \"str\t\tx6, [%[r], 184]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 192]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 200]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 192]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 200]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 192]\\n\\t\"\n        \"str\t\tx6, [%[r], 200]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 208]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 216]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 208]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 216]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 208]\\n\\t\"\n        \"str\t\tx6, [%[r], 216]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 224]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 232]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 224]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 232]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 224]\\n\\t\"\n        \"str\t\tx6, [%[r], 232]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 240]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 248]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 240]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 248]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 240]\\n\\t\"\n        \"str\t\tx6, [%[r], 248]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 256]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 264]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 256]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 264]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 256]\\n\\t\"\n        \"str\t\tx6, [%[r], 264]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 272]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 280]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 272]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 280]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 272]\\n\\t\"\n        \"str\t\tx6, [%[r], 280]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 288]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 296]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 288]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 296]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 288]\\n\\t\"\n        \"str\t\tx6, [%[r], 296]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 304]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 312]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 304]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 312]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 304]\\n\\t\"\n        \"str\t\tx6, [%[r], 312]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 320]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 328]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 320]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 328]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 320]\\n\\t\"\n        \"str\t\tx6, [%[r], 328]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 336]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 344]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 336]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 344]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 336]\\n\\t\"\n        \"str\t\tx6, [%[r], 344]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 352]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 360]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 352]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 360]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 352]\\n\\t\"\n        \"str\t\tx6, [%[r], 360]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 368]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 376]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 368]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 376]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 368]\\n\\t\"\n        \"str\t\tx6, [%[r], 376]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 384]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 392]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 384]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 392]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 384]\\n\\t\"\n        \"str\t\tx6, [%[r], 392]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 400]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 408]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 400]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 408]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 400]\\n\\t\"\n        \"str\t\tx6, [%[r], 408]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 416]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 424]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 416]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 424]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 416]\\n\\t\"\n        \"str\t\tx6, [%[r], 424]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 432]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 440]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 432]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 440]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 432]\\n\\t\"\n        \"str\t\tx6, [%[r], 440]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 448]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 456]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 448]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 456]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 448]\\n\\t\"\n        \"str\t\tx6, [%[r], 456]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 464]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 472]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 464]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 472]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 464]\\n\\t\"\n        \"str\t\tx6, [%[r], 472]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 480]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 488]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 480]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 488]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 480]\\n\\t\"\n        \"str\t\tx6, [%[r], 488]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 496]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 504]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 496]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 504]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 496]\\n\\t\"\n        \"str\t\tx6, [%[r], 504]\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"x4\", \"x6\", \"x5\", \"x7\", \"x8\"\n    );\n#endif /* WOLFSSL_SP_SMALL */\n\n    return c;\n}\n\n/* Reduce the number back to 4096 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_4096_mont_reduce_64(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"ldp       x12, x13, [%[m], 0]\\n\\t\"\n        \"ldp       x14, x15, [%[m], 16]\\n\\t\"\n        \"ldp       x16, x17, [%[m], 32]\\n\\t\"\n        \"ldp       x19, x20, [%[m], 48]\\n\\t\"\n        \"ldp       x21, x22, [%[m], 64]\\n\\t\"\n        \"ldp       x23, x24, [%[m], 80]\\n\\t\"\n        \"ldp       x25, x26, [%[m], 96]\\n\\t\"\n        \"ldp       x27, x28, [%[m], 112]\\n\\t\"\n        \"# i = 0\\n\\t\"\n        \"mov\tx3, 0\\n\\t\"\n        \"ldp\tx10, x11, [%[a], 0]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mul\tx8, %[mp], x10\\n\\t\"\n        \"# a[i+0] += m[0] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 0]\\n\\t\"\n        \"mul\t\tx6, x12, x8\\n\\t\"\n        \"umulh\tx7, x12, x8\\n\\t\"\n        \"adds\tx10, x10, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"# a[i+1] += m[1] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 8]\\n\\t\"\n        \"mul\t\tx6, x13, x8\\n\\t\"\n        \"umulh\tx7, x13, x8\\n\\t\"\n        \"adds\tx10, x11, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx10, x10, x5\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+2] += m[2] * mu\\n\\t\"\n        \"ldr\tx11, [%[a], 16]\\n\\t\"\n        \"mul\t\tx6, x14, x8\\n\\t\"\n        \"umulh\tx7, x14, x8\\n\\t\"\n        \"adds\tx11, x11, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx11, x11, x4\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+3] += m[3] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 24]\\n\\t\"\n        \"mul\t\tx6, x15, x8\\n\\t\"\n        \"umulh\tx7, x15, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 24]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+4] += m[4] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 32]\\n\\t\"\n        \"mul\t\tx6, x16, x8\\n\\t\"\n        \"umulh\tx7, x16, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 32]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+5] += m[5] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 40]\\n\\t\"\n        \"mul\t\tx6, x17, x8\\n\\t\"\n        \"umulh\tx7, x17, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 40]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+6] += m[6] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 48]\\n\\t\"\n        \"mul\t\tx6, x19, x8\\n\\t\"\n        \"umulh\tx7, x19, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 48]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+7] += m[7] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 56]\\n\\t\"\n        \"mul\t\tx6, x20, x8\\n\\t\"\n        \"umulh\tx7, x20, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 56]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+8] += m[8] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 64]\\n\\t\"\n        \"mul\t\tx6, x21, x8\\n\\t\"\n        \"umulh\tx7, x21, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 64]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+9] += m[9] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 72]\\n\\t\"\n        \"mul\t\tx6, x22, x8\\n\\t\"\n        \"umulh\tx7, x22, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 72]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+10] += m[10] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 80]\\n\\t\"\n        \"mul\t\tx6, x23, x8\\n\\t\"\n        \"umulh\tx7, x23, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 80]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+11] += m[11] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 88]\\n\\t\"\n        \"mul\t\tx6, x24, x8\\n\\t\"\n        \"umulh\tx7, x24, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 88]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+12] += m[12] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 96]\\n\\t\"\n        \"mul\t\tx6, x25, x8\\n\\t\"\n        \"umulh\tx7, x25, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 96]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+13] += m[13] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 104]\\n\\t\"\n        \"mul\t\tx6, x26, x8\\n\\t\"\n        \"umulh\tx7, x26, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 104]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+14] += m[14] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 112]\\n\\t\"\n        \"mul\t\tx6, x27, x8\\n\\t\"\n        \"umulh\tx7, x27, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 112]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+15] += m[15] * mu\\n\\t\"\n        \"ldr\tx9, [%[a], 120]\\n\\t\"\n        \"mul\t\tx6, x28, x8\\n\\t\"\n        \"umulh\tx7, x28, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 120]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+16] += m[16] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 128]\\n\\t\"\n        \"ldr\tx9, [%[a], 128]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 128]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+17] += m[17] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 136]\\n\\t\"\n        \"ldr\tx9, [%[a], 136]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 136]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+18] += m[18] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 144]\\n\\t\"\n        \"ldr\tx9, [%[a], 144]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 144]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+19] += m[19] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 152]\\n\\t\"\n        \"ldr\tx9, [%[a], 152]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 152]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+20] += m[20] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 160]\\n\\t\"\n        \"ldr\tx9, [%[a], 160]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 160]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+21] += m[21] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 168]\\n\\t\"\n        \"ldr\tx9, [%[a], 168]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 168]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+22] += m[22] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 176]\\n\\t\"\n        \"ldr\tx9, [%[a], 176]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 176]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+23] += m[23] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 184]\\n\\t\"\n        \"ldr\tx9, [%[a], 184]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 184]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+24] += m[24] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 192]\\n\\t\"\n        \"ldr\tx9, [%[a], 192]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 192]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+25] += m[25] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 200]\\n\\t\"\n        \"ldr\tx9, [%[a], 200]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 200]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+26] += m[26] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 208]\\n\\t\"\n        \"ldr\tx9, [%[a], 208]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 208]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+27] += m[27] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 216]\\n\\t\"\n        \"ldr\tx9, [%[a], 216]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 216]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+28] += m[28] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 224]\\n\\t\"\n        \"ldr\tx9, [%[a], 224]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 224]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+29] += m[29] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 232]\\n\\t\"\n        \"ldr\tx9, [%[a], 232]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 232]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+30] += m[30] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 240]\\n\\t\"\n        \"ldr\tx9, [%[a], 240]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 240]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+31] += m[31] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 248]\\n\\t\"\n        \"ldr\tx9, [%[a], 248]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 248]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+32] += m[32] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 256]\\n\\t\"\n        \"ldr\tx9, [%[a], 256]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 256]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+33] += m[33] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 264]\\n\\t\"\n        \"ldr\tx9, [%[a], 264]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 264]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+34] += m[34] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 272]\\n\\t\"\n        \"ldr\tx9, [%[a], 272]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 272]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+35] += m[35] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 280]\\n\\t\"\n        \"ldr\tx9, [%[a], 280]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 280]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+36] += m[36] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 288]\\n\\t\"\n        \"ldr\tx9, [%[a], 288]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 288]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+37] += m[37] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 296]\\n\\t\"\n        \"ldr\tx9, [%[a], 296]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 296]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+38] += m[38] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 304]\\n\\t\"\n        \"ldr\tx9, [%[a], 304]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 304]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+39] += m[39] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 312]\\n\\t\"\n        \"ldr\tx9, [%[a], 312]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 312]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+40] += m[40] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 320]\\n\\t\"\n        \"ldr\tx9, [%[a], 320]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 320]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+41] += m[41] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 328]\\n\\t\"\n        \"ldr\tx9, [%[a], 328]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 328]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+42] += m[42] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 336]\\n\\t\"\n        \"ldr\tx9, [%[a], 336]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 336]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+43] += m[43] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 344]\\n\\t\"\n        \"ldr\tx9, [%[a], 344]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 344]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+44] += m[44] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 352]\\n\\t\"\n        \"ldr\tx9, [%[a], 352]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 352]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+45] += m[45] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 360]\\n\\t\"\n        \"ldr\tx9, [%[a], 360]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 360]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+46] += m[46] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 368]\\n\\t\"\n        \"ldr\tx9, [%[a], 368]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 368]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+47] += m[47] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 376]\\n\\t\"\n        \"ldr\tx9, [%[a], 376]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 376]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+48] += m[48] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 384]\\n\\t\"\n        \"ldr\tx9, [%[a], 384]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 384]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+49] += m[49] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 392]\\n\\t\"\n        \"ldr\tx9, [%[a], 392]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 392]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+50] += m[50] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 400]\\n\\t\"\n        \"ldr\tx9, [%[a], 400]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 400]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+51] += m[51] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 408]\\n\\t\"\n        \"ldr\tx9, [%[a], 408]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 408]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+52] += m[52] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 416]\\n\\t\"\n        \"ldr\tx9, [%[a], 416]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 416]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+53] += m[53] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 424]\\n\\t\"\n        \"ldr\tx9, [%[a], 424]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 424]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+54] += m[54] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 432]\\n\\t\"\n        \"ldr\tx9, [%[a], 432]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 432]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+55] += m[55] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 440]\\n\\t\"\n        \"ldr\tx9, [%[a], 440]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 440]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+56] += m[56] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 448]\\n\\t\"\n        \"ldr\tx9, [%[a], 448]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 448]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+57] += m[57] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 456]\\n\\t\"\n        \"ldr\tx9, [%[a], 456]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 456]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+58] += m[58] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 464]\\n\\t\"\n        \"ldr\tx9, [%[a], 464]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 464]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+59] += m[59] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 472]\\n\\t\"\n        \"ldr\tx9, [%[a], 472]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 472]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+60] += m[60] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 480]\\n\\t\"\n        \"ldr\tx9, [%[a], 480]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 480]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+61] += m[61] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 488]\\n\\t\"\n        \"ldr\tx9, [%[a], 488]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx4, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 488]\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"# a[i+62] += m[62] * mu\\n\\t\"\n        \"ldr\t\tx7, [%[m], 496]\\n\\t\"\n        \"ldr\tx9, [%[a], 496]\\n\\t\"\n        \"mul\t\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx9, x9, x6\\n\\t\"\n        \"adc\tx5, x7, xzr\\n\\t\"\n        \"adds\tx9, x9, x4\\n\\t\"\n        \"str\tx9, [%[a], 496]\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"# a[i+63] += m[63] * mu\\n\\t\"\n        \"ldr\tx7, [%[m], 504]\\n\\t\"\n        \"ldr\tx9, [%[a], 504]\\n\\t\"\n        \"mul\tx6, x7, x8\\n\\t\"\n        \"umulh\tx7, x7, x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx7, x7, %[ca]\\n\\t\"\n        \"cset  %[ca], cs\\n\\t\"\n        \"adds\tx9, x9, x5\\n\\t\"\n        \"str\tx9, [%[a], 504]\\n\\t\"\n        \"ldr\tx9, [%[a], 512]\\n\\t\"\n        \"adcs\tx9, x9, x7\\n\\t\"\n        \"str\tx9, [%[a], 512]\\n\\t\"\n        \"adc\t%[ca], %[ca], xzr\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"add\t%[a], %[a], 8\\n\\t\"\n        \"add\tx3, x3, 8\\n\\t\"\n        \"cmp\tx3, 512\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tx10, [%[a], 0]\\n\\t\"\n        \"str\tx11, [%[a], 8]\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\", \"x12\", \"x13\", \"x14\", \"x15\", \"x16\", \"x17\", \"x19\", \"x20\", \"x21\", \"x22\", \"x23\", \"x24\", \"x25\", \"x26\", \"x27\", \"x28\"\n    );\n\n    sp_4096_cond_sub_64(a - 64, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_4096_mul_64(r, a, b);\n    sp_4096_mont_reduce_64(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_sqr_64(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_4096_sqr_64(r, a);\n    sp_4096_mont_reduce_64(r, m, mp);\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n */\nstatic sp_digit div_4096_word_64(sp_digit d1, sp_digit d0, sp_digit div)\n{\n    sp_digit r;\n\n    __asm__ __volatile__ (\n        \"lsr\tx5, %[div], 32\\n\\t\"\n        \"add\tx5, x5, 1\\n\\t\"\n\n        \"udiv\tx3, %[d1], x5\\n\\t\"\n        \"lsl\tx6, x3, 32\\n\\t\"\n        \"mul\tx4, %[div], x6\\n\\t\"\n        \"umulh\tx3, %[div], x6\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"udiv\tx3, %[d1], x5\\n\\t\"\n        \"lsl\tx3, x3, 32\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"lsl\tx3, %[d1], 32\\n\\t\"\n        \"orr\tx3, x3, %[d0], lsr 32\\n\\t\"\n\n        \"udiv\tx3, x3, x5\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"lsl\tx3, %[d1], 32\\n\\t\"\n        \"orr\tx3, x3, %[d0], lsr 32\\n\\t\"\n\n        \"udiv\tx3, x3, x5\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"udiv\tx3, %[d0], %[div]\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx3, %[div], x3\\n\\t\"\n        \"sub\t%[d0], %[d0], x3\\n\\t\"\n        \"mov\t%[r], x6\\n\\t\"\n\n        : [r] \"=r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_4096_mask_64(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<64; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic int64_t sp_4096_cmp_64(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = -1;\n    sp_digit one = 1;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tx3, -1\\n\\t\"\n        \"mov\tx6, 504\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tx4, [%[a], x6]\\n\\t\"\n        \"ldr\tx5, [%[b], x6]\\n\\t\"\n        \"and\tx4, x4, x3\\n\\t\"\n        \"and\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"subs\tx6, x6, #8\\n\\t\"\n        \"b.cs\t1b\\n\\t\"\n        \"eor\t%[r], %[r], x3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tx3, -1\\n\\t\"\n        \"ldr\t\tx4, [%[a], 504]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 504]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 496]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 496]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 488]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 488]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 480]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 480]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 472]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 472]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 464]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 464]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 456]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 456]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 448]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 448]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 440]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 440]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 432]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 432]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 424]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 424]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 416]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 416]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 408]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 408]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 400]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 400]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 392]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 392]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 384]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 384]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 376]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 376]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 368]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 368]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 360]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 360]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 352]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 352]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 344]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 344]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 336]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 336]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 328]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 328]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 320]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 320]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 312]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 312]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 304]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 304]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 296]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 296]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 288]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 288]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 280]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 280]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 272]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 272]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 264]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 264]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 256]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 256]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 248]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 248]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 240]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 240]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 232]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 232]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 224]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 224]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 216]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 216]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 208]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 208]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 200]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 200]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 192]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 192]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 184]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 184]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 176]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 176]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 168]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 168]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 160]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 160]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 152]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 152]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 144]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 144]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 136]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 136]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 128]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 128]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 120]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 120]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 112]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 112]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 104]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 104]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 96]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 96]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 88]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 88]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 80]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 80]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 72]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 72]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 64]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 64]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 56]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 56]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 48]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 48]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 40]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 40]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 32]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 32]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 24]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 24]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 16]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 16]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 8]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 8]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 0]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 0]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"eor\t%[r], %[r], x3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n#endif\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_div_64(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[128], t2[65];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[63];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 64);\n    for (i=63; i>=0; i--) {\n        r1 = div_4096_word_64(t1[64 + i], t1[64 + i - 1], div);\n\n        sp_4096_mul_d_64(t2, d, r1);\n        t1[64 + i] += sp_4096_sub_in_place_64(&t1[i], t2);\n        t1[64 + i] -= t2[64];\n        sp_4096_mask_64(t2, d, t1[64 + i]);\n        t1[64 + i] += sp_4096_add_64(&t1[i], &t1[i], t2);\n        sp_4096_mask_64(t2, d, t1[64 + i]);\n        t1[64 + i] += sp_4096_add_64(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_4096_cmp_64(t1, d) >= 0;\n    sp_4096_cond_sub_64(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_mod_64(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_64(a, m, NULL, r);\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_div_64_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[128], t2[65];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[63];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 64);\n    for (i=63; i>=0; i--) {\n        r1 = div_4096_word_64(t1[64 + i], t1[64 + i - 1], div);\n\n        sp_4096_mul_d_64(t2, d, r1);\n        t1[64 + i] += sp_4096_sub_in_place_64(&t1[i], t2);\n        t1[64 + i] -= t2[64];\n        if (t1[64 + i] != 0) {\n            t1[64 + i] += sp_4096_add_64(&t1[i], &t1[i], d);\n            if (t1[64 + i] != 0)\n                t1[64 + i] += sp_4096_add_64(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_4096_cmp_64(t1, d) >= 0;\n    sp_4096_cond_sub_64(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_mod_64_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_64_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][128];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 128, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 128;\n        }\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_64(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 64U);\n        if (reduceA != 0) {\n            err = sp_4096_mod_64(t[1] + 64, a, m);\n            if (err == MP_OKAY) {\n                err = sp_4096_mod_64(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 64, a, sizeof(sp_digit) * 64);\n            err = sp_4096_mod_64(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_64(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_64(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_64(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_64(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_64(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_64(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_64(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_64(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_64(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_64(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_64(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_64(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_64(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_64(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0) {\n            c = 64;\n        }\n        c -= bits % 4;\n        if (c == 64) {\n            c = 60;\n        }\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 64);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 60;\n                n <<= 4;\n                c = 60;\n            }\n            else if (c < 4) {\n                y = n >> 60;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 60) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n\n            sp_4096_mont_mul_64(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);\n        sp_4096_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_64(r, m) >= 0);\n        sp_4096_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][128];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 128, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 128;\n        }\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_64(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 64U);\n        if (reduceA != 0) {\n            err = sp_4096_mod_64(t[1] + 64, a, m);\n            if (err == MP_OKAY) {\n                err = sp_4096_mod_64(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 64, a, sizeof(sp_digit) * 64);\n            err = sp_4096_mod_64(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_64(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_64(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_64(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_64(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_64(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_64(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_64(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_64(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_64(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_64(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_64(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_64(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_64(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_64(t[15], t[ 8], t[ 7], m, mp);\n        sp_4096_mont_sqr_64(t[16], t[ 8], m, mp);\n        sp_4096_mont_mul_64(t[17], t[ 9], t[ 8], m, mp);\n        sp_4096_mont_sqr_64(t[18], t[ 9], m, mp);\n        sp_4096_mont_mul_64(t[19], t[10], t[ 9], m, mp);\n        sp_4096_mont_sqr_64(t[20], t[10], m, mp);\n        sp_4096_mont_mul_64(t[21], t[11], t[10], m, mp);\n        sp_4096_mont_sqr_64(t[22], t[11], m, mp);\n        sp_4096_mont_mul_64(t[23], t[12], t[11], m, mp);\n        sp_4096_mont_sqr_64(t[24], t[12], m, mp);\n        sp_4096_mont_mul_64(t[25], t[13], t[12], m, mp);\n        sp_4096_mont_sqr_64(t[26], t[13], m, mp);\n        sp_4096_mont_mul_64(t[27], t[14], t[13], m, mp);\n        sp_4096_mont_sqr_64(t[28], t[14], m, mp);\n        sp_4096_mont_mul_64(t[29], t[15], t[14], m, mp);\n        sp_4096_mont_sqr_64(t[30], t[15], m, mp);\n        sp_4096_mont_mul_64(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0) {\n            c = 64;\n        }\n        c -= bits % 5;\n        if (c == 64) {\n            c = 59;\n        }\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 64);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 59;\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = n >> 59;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n\n            sp_4096_mont_mul_64(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);\n        sp_4096_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_64(r, m) >= 0);\n        sp_4096_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[128], md[64], rd[128];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1];\n    int err = MP_OKAY;\n\n    if (*outLen < 512)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 64 || inLen > 512 ||\n                                                     mp_count_bits(mm) != 4096))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 64 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 64 * 2;\n        m = r + 64 * 2;\n        ah = a + 64;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 64;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(ah, 64, in, inLen);\n#if DIGIT_BIT >= 64\n        e[0] = em->dp[0];\n#else\n        e[0] = em->dp[0];\n        if (em->used > 1)\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e[0] == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(m, 64, mm);\n\n        if (e[0] == 0x3) {\n            if (err == MP_OKAY) {\n                sp_4096_sqr_64(r, ah);\n                err = sp_4096_mod_64_cond(r, r, m);\n            }\n            if (err == MP_OKAY) {\n                sp_4096_mul_64(r, ah, r);\n                err = sp_4096_mod_64_cond(r, r, m);\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_4096_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 64);\n            err = sp_4096_mod_64_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=63; i>=0; i--)\n                    if (e[0] >> i)\n                        break;\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 64);\n                for (i--; i>=0; i--) {\n                    sp_4096_mont_sqr_64(r, r, m, mp);\n                    if (((e[0] >> i) & 1) == 1)\n                        sp_4096_mont_mul_64(r, r, a, m, mp);\n                }\n                XMEMSET(&r[64], 0, sizeof(sp_digit) * 64);\n                sp_4096_mont_reduce_64(r, m, mp);\n\n                for (i = 63; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_4096_sub_in_place_64(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[64 * 2];\n    sp_digit pd[32], qd[32], dpd[32];\n    sp_digit tmpad[64], tmpbd[64];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 512)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 512 || mp_count_bits(mm) != 4096))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 64 * 2;\n        q = p + 32;\n        qi = dq = dp = q + 32;\n        tmpa = qi + 32;\n        tmpb = tmpa + 64;\n\n        tmp = t;\n        r = tmp + 64;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 64;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(a, 64, in, inLen);\n        sp_4096_from_mp(p, 32, pm);\n        sp_4096_from_mp(q, 32, qm);\n        sp_4096_from_mp(dp, 32, dpm);\n\n        err = sp_4096_mod_exp_32(tmpa, a, dp, 2048, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(dq, 32, dqm);\n        err = sp_4096_mod_exp_32(tmpb, a, dq, 2048, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_4096_sub_in_place_32(tmpa, tmpb);\n        sp_4096_mask_32(tmp, p, c);\n        sp_4096_add_32(tmpa, tmpa, tmp);\n\n        sp_4096_from_mp(qi, 32, qim);\n        sp_4096_mul_32(tmpa, tmpa, qi);\n        err = sp_4096_mod_32(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mul_32(tmpa, q, tmpa);\n        XMEMSET(&tmpb[32], 0, sizeof(sp_digit) * 32);\n        sp_4096_add_64(r, tmpb, tmpa);\n\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 32 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_4096_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (4096 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 64\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 64);\n        r->used = 64;\n        mp_clamp(r);\n#elif DIGIT_BIT < 64\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 64; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 64) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 64 - s;\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 64; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 64 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 64 - s;\n            }\n            else {\n                s += 64;\n            }\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[128], e[64], m[64];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 64, base);\n        sp_4096_from_mp(e, 64, exp);\n        sp_4096_from_mp(m, 64, mod);\n\n        err = sp_4096_mod_exp_64(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_4096_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_4096\nstatic void sp_4096_lshift_64(sp_digit* r, sp_digit* a, byte n)\n{\n    __asm__ __volatile__ (\n        \"mov\tx6, 63\\n\\t\"\n        \"sub\tx6, x6, %[n]\\n\\t\"\n        \"ldr\tx3, [%[a], 504]\\n\\t\"\n        \"lsr\tx4, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx4, x4, x6\\n\\t\"\n        \"ldr\tx2, [%[a], 496]\\n\\t\"\n        \"str\tx4, [%[r], 512]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 488]\\n\\t\"\n        \"str\tx3, [%[r], 504]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 480]\\n\\t\"\n        \"str\tx2, [%[r], 496]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 472]\\n\\t\"\n        \"str\tx4, [%[r], 488]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 464]\\n\\t\"\n        \"str\tx3, [%[r], 480]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 456]\\n\\t\"\n        \"str\tx2, [%[r], 472]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 448]\\n\\t\"\n        \"str\tx4, [%[r], 464]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 440]\\n\\t\"\n        \"str\tx3, [%[r], 456]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 432]\\n\\t\"\n        \"str\tx2, [%[r], 448]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 424]\\n\\t\"\n        \"str\tx4, [%[r], 440]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 416]\\n\\t\"\n        \"str\tx3, [%[r], 432]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 408]\\n\\t\"\n        \"str\tx2, [%[r], 424]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 400]\\n\\t\"\n        \"str\tx4, [%[r], 416]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 392]\\n\\t\"\n        \"str\tx3, [%[r], 408]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 384]\\n\\t\"\n        \"str\tx2, [%[r], 400]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 376]\\n\\t\"\n        \"str\tx4, [%[r], 392]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 368]\\n\\t\"\n        \"str\tx3, [%[r], 384]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 360]\\n\\t\"\n        \"str\tx2, [%[r], 376]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 352]\\n\\t\"\n        \"str\tx4, [%[r], 368]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 344]\\n\\t\"\n        \"str\tx3, [%[r], 360]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 336]\\n\\t\"\n        \"str\tx2, [%[r], 352]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 328]\\n\\t\"\n        \"str\tx4, [%[r], 344]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 320]\\n\\t\"\n        \"str\tx3, [%[r], 336]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 312]\\n\\t\"\n        \"str\tx2, [%[r], 328]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 304]\\n\\t\"\n        \"str\tx4, [%[r], 320]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 296]\\n\\t\"\n        \"str\tx3, [%[r], 312]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 288]\\n\\t\"\n        \"str\tx2, [%[r], 304]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 280]\\n\\t\"\n        \"str\tx4, [%[r], 296]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 272]\\n\\t\"\n        \"str\tx3, [%[r], 288]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 264]\\n\\t\"\n        \"str\tx2, [%[r], 280]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 256]\\n\\t\"\n        \"str\tx4, [%[r], 272]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 248]\\n\\t\"\n        \"str\tx3, [%[r], 264]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 240]\\n\\t\"\n        \"str\tx2, [%[r], 256]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 232]\\n\\t\"\n        \"str\tx4, [%[r], 248]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 224]\\n\\t\"\n        \"str\tx3, [%[r], 240]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 216]\\n\\t\"\n        \"str\tx2, [%[r], 232]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 208]\\n\\t\"\n        \"str\tx4, [%[r], 224]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 200]\\n\\t\"\n        \"str\tx3, [%[r], 216]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 192]\\n\\t\"\n        \"str\tx2, [%[r], 208]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 184]\\n\\t\"\n        \"str\tx4, [%[r], 200]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 176]\\n\\t\"\n        \"str\tx3, [%[r], 192]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 168]\\n\\t\"\n        \"str\tx2, [%[r], 184]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 160]\\n\\t\"\n        \"str\tx4, [%[r], 176]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 152]\\n\\t\"\n        \"str\tx3, [%[r], 168]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 144]\\n\\t\"\n        \"str\tx2, [%[r], 160]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 136]\\n\\t\"\n        \"str\tx4, [%[r], 152]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 128]\\n\\t\"\n        \"str\tx3, [%[r], 144]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 120]\\n\\t\"\n        \"str\tx2, [%[r], 136]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 112]\\n\\t\"\n        \"str\tx4, [%[r], 128]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 104]\\n\\t\"\n        \"str\tx3, [%[r], 120]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 96]\\n\\t\"\n        \"str\tx2, [%[r], 112]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 88]\\n\\t\"\n        \"str\tx4, [%[r], 104]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 80]\\n\\t\"\n        \"str\tx3, [%[r], 96]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 72]\\n\\t\"\n        \"str\tx2, [%[r], 88]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 64]\\n\\t\"\n        \"str\tx4, [%[r], 80]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 56]\\n\\t\"\n        \"str\tx3, [%[r], 72]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 48]\\n\\t\"\n        \"str\tx2, [%[r], 64]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 40]\\n\\t\"\n        \"str\tx4, [%[r], 56]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 32]\\n\\t\"\n        \"str\tx3, [%[r], 48]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 24]\\n\\t\"\n        \"str\tx2, [%[r], 40]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"ldr\tx2, [%[a], 16]\\n\\t\"\n        \"str\tx4, [%[r], 32]\\n\\t\"\n        \"lsr\tx5, x2, 1\\n\\t\"\n        \"lsl\tx2, x2, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx3, x3, x5\\n\\t\"\n        \"ldr\tx4, [%[a], 8]\\n\\t\"\n        \"str\tx3, [%[r], 24]\\n\\t\"\n        \"lsr\tx5, x4, 1\\n\\t\"\n        \"lsl\tx4, x4, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx2, x2, x5\\n\\t\"\n        \"ldr\tx3, [%[a], 0]\\n\\t\"\n        \"str\tx2, [%[r], 16]\\n\\t\"\n        \"lsr\tx5, x3, 1\\n\\t\"\n        \"lsl\tx3, x3, %[n]\\n\\t\"\n        \"lsr\tx5, x5, x6\\n\\t\"\n        \"orr\tx4, x4, x5\\n\\t\"\n        \"str\tx3, [%[r]]\\n\\t\"\n        \"str\tx4, [%[r], 8]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [n] \"r\" (n)\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[128];\n    sp_digit td[65];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 193, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 128;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_64(norm, m);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0) {\n            c = 64;\n        }\n        c -= bits % 6;\n        if (c == 64) {\n            c = 58;\n        }\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        sp_4096_lshift_64(r, norm, y);\n        for (; i>=0 || c>=6; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 58;\n                n <<= 6;\n                c = 58;\n            }\n            else if (c < 6) {\n                y = n >> 58;\n                n = e[i--];\n                c = 6 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 58) & 0x3f;\n                n <<= 6;\n                c -= 6;\n            }\n\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n\n            sp_4096_lshift_64(r, r, y);\n            sp_4096_mul_d_64(tmp, norm, r[64]);\n            r[64] = 0;\n            o = sp_4096_add_64(r, r, tmp);\n            sp_4096_cond_sub_64(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);\n        sp_4096_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_64(r, m) >= 0);\n        sp_4096_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* HAVE_FFDHE_4096 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 512 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[128], e[64], m[64];\n    sp_digit* r = b;\n    word32 i;\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 512) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 64, base);\n        sp_4096_from_bin(e, 64, exp, expLen);\n        sp_4096_from_mp(m, 64, mod);\n\n    #ifdef HAVE_FFDHE_4096\n        if (base->used == 1 && base->dp[0] == 2 && m[63] == (sp_digit)-1)\n            err = sp_4096_mod_exp_2_64(r, e, expLen * 8, m);\n        else\n    #endif\n            err = sp_4096_mod_exp_64(r, b, e, expLen * 8, m, 0);\n\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n        for (i=0; i<512 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* WOLFSSL_SP_4096 */\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n#ifdef WOLFSSL_HAVE_SP_ECC\n#ifndef WOLFSSL_SP_NO_256\n\n/* Point structure to use. */\ntypedef struct sp_point {\n    sp_digit x[2 * 4];\n    sp_digit y[2 * 4];\n    sp_digit z[2 * 4];\n    int infinity;\n} sp_point;\n\n/* The modulus (prime) of the curve P256. */\nstatic const sp_digit p256_mod[4] = {\n    0xffffffffffffffffL,0x00000000ffffffffL,0x0000000000000000L,\n    0xffffffff00000001L\n};\n/* The Montogmery normalizer for modulus of the curve P256. */\nstatic const sp_digit p256_norm_mod[4] = {\n    0x0000000000000001L,0xffffffff00000000L,0xffffffffffffffffL,\n    0x00000000fffffffeL\n};\n/* The Montogmery multiplier for modulus of the curve P256. */\nstatic const sp_digit p256_mp_mod = 0x0000000000000001;\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                            defined(HAVE_ECC_VERIFY)\n/* The order of the curve P256. */\nstatic const sp_digit p256_order[4] = {\n    0xf3b9cac2fc632551L,0xbce6faada7179e84L,0xffffffffffffffffL,\n    0xffffffff00000000L\n};\n#endif\n/* The order of the curve P256 minus 2. */\nstatic const sp_digit p256_order2[4] = {\n    0xf3b9cac2fc63254fL,0xbce6faada7179e84L,0xffffffffffffffffL,\n    0xffffffff00000000L\n};\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery normalizer for order of the curve P256. */\nstatic const sp_digit p256_norm_order[4] = {\n    0x0c46353d039cdaafL,0x4319055258e8617bL,0x0000000000000000L,\n    0x00000000ffffffffL\n};\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery multiplier for order of the curve P256. */\nstatic const sp_digit p256_mp_order = 0xccd1c8aaee00bc4fL;\n#endif\n#ifdef WOLFSSL_SP_SMALL\n/* The base point of curve P256. */\nstatic const sp_point p256_base = {\n    /* X ordinate */\n    {\n        0xf4a13945d898c296L,0x77037d812deb33a0L,0xf8bce6e563a440f2L,\n        0x6b17d1f2e12c4247L, 0L, 0L, 0L, 0L\n    },\n    /* Y ordinate */\n    {\n        0xcbb6406837bf51f5L,0x2bce33576b315eceL,0x8ee7eb4a7c0f9e16L,\n        0x4fe342e2fe1a7f9bL, 0L, 0L, 0L, 0L\n    },\n    /* Z ordinate */\n    {\n        0x0000000000000001L,0x0000000000000000L,0x0000000000000000L,\n        0x0000000000000000L, 0L, 0L, 0L, 0L\n    },\n    /* infinity */\n    0\n};\n#endif /* WOLFSSL_SP_SMALL */\n#if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)\nstatic const sp_digit p256_b[4] = {\n    0x3bce3c3e27d2604bL,0x651d06b0cc53b0f6L,0xb3ebbd55769886bcL,\n    0x5ac635d8aa3a93e7L\n};\n#endif\n\nstatic int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p)\n{\n    int ret = MP_OKAY;\n    (void)heap;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    (void)sp;\n    *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC);\n#else\n    *p = sp;\n#endif\n    if (p == NULL) {\n        ret = MEMORY_E;\n    }\n    return ret;\n}\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* Allocate memory for point and return error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p))\n#else\n/* Set pointer to data and return no error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p))\n#endif\n\n\nstatic void sp_ecc_point_free(sp_point* p, int clear, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* If valid pointer then clear point data if requested and free data. */\n    if (p != NULL) {\n        if (clear != 0) {\n            XMEMSET(p, 0, sizeof(*p));\n        }\n        XFREE(p, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n/* Clear point data if requested. */\n    if (clear != 0) {\n        XMEMSET(p, 0, sizeof(*p));\n    }\n#endif\n    (void)heap;\n}\n\n/* Multiply a number by Montogmery normalizer mod modulus (prime).\n *\n * r  The resulting Montgomery form number.\n * a  The number to convert.\n * m  The modulus (prime).\n */\nstatic int sp_256_mod_mul_norm_4(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    int64_t t[8];\n    int64_t a32[8];\n    int64_t o;\n\n    (void)m;\n\n    a32[0] = a[0] & 0xffffffff;\n    a32[1] = a[0] >> 32;\n    a32[2] = a[1] & 0xffffffff;\n    a32[3] = a[1] >> 32;\n    a32[4] = a[2] & 0xffffffff;\n    a32[5] = a[2] >> 32;\n    a32[6] = a[3] & 0xffffffff;\n    a32[7] = a[3] >> 32;\n\n    /*  1  1  0 -1 -1 -1 -1  0 */\n    t[0] = 0 + a32[0] + a32[1] - a32[3] - a32[4] - a32[5] - a32[6];\n    /*  0  1  1  0 -1 -1 -1 -1 */\n    t[1] = 0 + a32[1] + a32[2] - a32[4] - a32[5] - a32[6] - a32[7];\n    /*  0  0  1  1  0 -1 -1 -1 */\n    t[2] = 0 + a32[2] + a32[3] - a32[5] - a32[6] - a32[7];\n    /* -1 -1  0  2  2  1  0 -1 */\n    t[3] = 0 - a32[0] - a32[1] + 2 * a32[3] + 2 * a32[4] + a32[5] - a32[7];\n    /*  0 -1 -1  0  2  2  1  0 */\n    t[4] = 0 - a32[1] - a32[2] + 2 * a32[4] + 2 * a32[5] + a32[6];\n    /*  0  0 -1 -1  0  2  2  1 */\n    t[5] = 0 - a32[2] - a32[3] + 2 * a32[5] + 2 * a32[6] + a32[7];\n    /* -1 -1  0  0  0  1  3  2 */\n    t[6] = 0 - a32[0] - a32[1] + a32[5] + 3 * a32[6] + 2 * a32[7];\n    /*  1  0 -1 -1 -1 -1  0  3 */\n    t[7] = 0 + a32[0] - a32[2] - a32[3] - a32[4] - a32[5] + 3 * a32[7];\n\n    t[1] += t[0] >> 32; t[0] &= 0xffffffff;\n    t[2] += t[1] >> 32; t[1] &= 0xffffffff;\n    t[3] += t[2] >> 32; t[2] &= 0xffffffff;\n    t[4] += t[3] >> 32; t[3] &= 0xffffffff;\n    t[5] += t[4] >> 32; t[4] &= 0xffffffff;\n    t[6] += t[5] >> 32; t[5] &= 0xffffffff;\n    t[7] += t[6] >> 32; t[6] &= 0xffffffff;\n    o     = t[7] >> 32; t[7] &= 0xffffffff;\n    t[0] += o;\n    t[3] -= o;\n    t[6] -= o;\n    t[7] += o;\n    t[1] += t[0] >> 32; t[0] &= 0xffffffff;\n    t[2] += t[1] >> 32; t[1] &= 0xffffffff;\n    t[3] += t[2] >> 32; t[2] &= 0xffffffff;\n    t[4] += t[3] >> 32; t[3] &= 0xffffffff;\n    t[5] += t[4] >> 32; t[4] &= 0xffffffff;\n    t[6] += t[5] >> 32; t[5] &= 0xffffffff;\n    t[7] += t[6] >> 32; t[6] &= 0xffffffff;\n    r[0] = (t[1] << 32) | t[0];\n    r[1] = (t[3] << 32) | t[2];\n    r[2] = (t[5] << 32) | t[4];\n    r[3] = (t[7] << 32) | t[6];\n\n    return MP_OKAY;\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_256_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 64\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 64\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffffffffffffl;\n        s = 64U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 64U) <= (word32)DIGIT_BIT) {\n            s += 64U;\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 64) {\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 64 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Convert a point of type ecc_point to type sp_point.\n *\n * p   Point of type sp_point (result).\n * pm  Point of type ecc_point.\n */\nstatic void sp_256_point_from_ecc_point_4(sp_point* p, const ecc_point* pm)\n{\n    XMEMSET(p->x, 0, sizeof(p->x));\n    XMEMSET(p->y, 0, sizeof(p->y));\n    XMEMSET(p->z, 0, sizeof(p->z));\n    sp_256_from_mp(p->x, 4, pm->x);\n    sp_256_from_mp(p->y, 4, pm->y);\n    sp_256_from_mp(p->z, 4, pm->z);\n    p->infinity = 0;\n}\n\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_256_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 64\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 4);\n        r->used = 4;\n        mp_clamp(r);\n#elif DIGIT_BIT < 64\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 4; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 64) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 64 - s;\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 4; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 64 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 64 - s;\n            }\n            else {\n                s += 64;\n            }\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Convert a point of type sp_point to type ecc_point.\n *\n * p   Point of type sp_point.\n * pm  Point of type ecc_point (result).\n * returns MEMORY_E when allocation of memory in ecc_point fails otherwise\n * MP_OKAY.\n */\nstatic int sp_256_point_to_ecc_point_4(const sp_point* p, ecc_point* pm)\n{\n    int err;\n\n    err = sp_256_to_mp(p->x, pm->x);\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pm->y);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pm->z);\n    }\n\n    return err;\n}\n\n/* Conditionally copy a into r using the mask m.\n * m is -1 to copy and 0 when not.\n *\n * r  A single precision number to copy over.\n * a  A single precision number to copy.\n * m  Mask value to apply.\n */\nstatic void sp_256_cond_copy_4(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n    __asm__ __volatile__ (\n        \"ldp\tx3, x4, [%[r], 0]\\n\\t\"\n        \"ldp\tx5, x6, [%[r], 16]\\n\\t\"\n        \"ldp\tx7, x8, [%[a], 0]\\n\\t\"\n        \"ldp\tx9, x10, [%[a], 16]\\n\\t\"\n        \"eor\tx7, x7, x3\\n\\t\"\n        \"eor\tx8, x8, x4\\n\\t\"\n        \"eor\tx9, x9, x5\\n\\t\"\n        \"eor\tx10, x10, x6\\n\\t\"\n        \"and\tx7, x7, %[m]\\n\\t\"\n        \"and\tx8, x8, %[m]\\n\\t\"\n        \"and\tx9, x9, %[m]\\n\\t\"\n        \"and\tx10, x10, %[m]\\n\\t\"\n        \"eor\tx3, x3, x7\\n\\t\"\n        \"eor\tx4, x4, x8\\n\\t\"\n        \"eor\tx5, x5, x9\\n\\t\"\n        \"eor\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 0]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 16]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [m] \"r\" (m)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic int64_t sp_256_cmp_4(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = -1;\n    sp_digit one = 1;\n\n#ifdef WOLFSSL_SP_SMALL\n    __asm__ __volatile__ (\n        \"mov\tx3, -1\\n\\t\"\n        \"mov\tx6, 24\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tx4, [%[a], x6]\\n\\t\"\n        \"ldr\tx5, [%[b], x6]\\n\\t\"\n        \"and\tx4, x4, x3\\n\\t\"\n        \"and\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"subs\tx6, x6, #8\\n\\t\"\n        \"b.cs\t1b\\n\\t\"\n        \"eor\t%[r], %[r], x3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n#else\n    __asm__ __volatile__ (\n        \"mov\tx3, -1\\n\\t\"\n        \"ldr\t\tx4, [%[a], 24]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 24]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 16]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 16]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 8]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 8]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"ldr\t\tx4, [%[a], 0]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 0]\\n\\t\"\n        \"and\t\tx4, x4, x3\\n\\t\"\n        \"and\t\tx5, x5, x3\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"csel\t%[r], %[one], %[r], hi\\n\\t\"\n        \"csel\t%[r], x3, %[r], lo\\n\\t\"\n        \"csel\tx3, x3, xzr, eq\\n\\t\"\n        \"eor\t%[r], %[r], x3\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b), [one] \"r\" (one)\n        : \"x2\", \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n#endif\n\n    return r;\n}\n\n/* Normalize the values in each word to 64.\n *\n * a  Array of sp_digit to normalize.\n */\n#define sp_256_norm_4(a)\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic sp_digit sp_256_cond_sub_4(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        sp_digit m)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n\n        \"ldr\t\tx4, [%[a], 0]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 8]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 0]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 8]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"subs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 0]\\n\\t\"\n        \"str\t\tx6, [%[r], 8]\\n\\t\"\n        \"ldr\t\tx4, [%[a], 16]\\n\\t\"\n        \"ldr\t\tx6, [%[a], 24]\\n\\t\"\n        \"ldr\t\tx5, [%[b], 16]\\n\\t\"\n        \"ldr\t\tx7, [%[b], 24]\\n\\t\"\n        \"and\t\tx5, x5, %[m]\\n\\t\"\n        \"and\t\tx7, x7, %[m]\\n\\t\"\n        \"sbcs\tx4, x4, x5\\n\\t\"\n        \"sbcs\tx6, x6, x7\\n\\t\"\n        \"str\t\tx4, [%[r], 16]\\n\\t\"\n        \"str\t\tx6, [%[r], 24]\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"x4\", \"x6\", \"x5\", \"x7\", \"x8\"\n    );\n\n    return c;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_256_sub_4(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx3, x4, [%[a], 0]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 16]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 0]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 16]\\n\\t\"\n        \"subs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"sbcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 0]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 16]\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n#define sp_256_mont_reduce_order_4    sp_256_mont_reduce_4\n\n/* Reduce the number back to 256 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_256_mont_reduce_4(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    __asm__ __volatile__ (\n        \"# i = 0\\n\\t\"\n        \"mov\tx9, xzr\\n\\t\"\n        \"mov\tx8, xzr\\n\\t\"\n        \"mov\tx6, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"ldr\tx5, [x6, 0]\\n\\t\"\n        \"mov\tx7, x5\\n\\t\"\n        \"mul\tx5, %[mp], x5\\n\\t\"\n        \"# a[i+0] += m[0] * mu\\n\\t\"\n        \"ldr\tx4, [%[m], 0]\\n\\t\"\n        \"ldr\tx11, [%[m], 8]\\n\\t\"\n        \"mul\tx3, x4, x5\\n\\t\"\n        \"umulh\tx10, x4, x5\\n\\t\"\n        \"adds\tx7, x7, x3\\n\\t\"\n        \"str\tx7, [x6, 0]\\n\\t\"\n        \"adc\tx10, x10, xzr\\n\\t\"\n        \"# a[i+1] += m[1] * mu\\n\\t\"\n        \"mul\tx3, x11, x5\\n\\t\"\n        \"umulh\tx12, x11, x5\\n\\t\"\n        \"ldr\tx11, [%[m], 16]\\n\\t\"\n        \"ldr\tx7, [x6, 8]\\n\\t\"\n        \"adds\tx3, x3, x10\\n\\t\"\n        \"adc\tx12, x12, xzr\\n\\t\"\n        \"adds\tx7, x7, x3\\n\\t\"\n        \"str\tx7, [x6, 8]\\n\\t\"\n        \"adc\tx12, x12, xzr\\n\\t\"\n        \"# a[i+2] += m[2] * mu\\n\\t\"\n        \"mul\tx3, x11, x5\\n\\t\"\n        \"umulh\tx10, x11, x5\\n\\t\"\n        \"ldr\tx11, [%[m], 24]\\n\\t\"\n        \"ldr\tx7, [x6, 16]\\n\\t\"\n        \"adds\tx3, x3, x12\\n\\t\"\n        \"adc\tx10, x10, xzr\\n\\t\"\n        \"adds\tx7, x7, x3\\n\\t\"\n        \"str\tx7, [x6, 16]\\n\\t\"\n        \"adc\tx10, x10, xzr\\n\\t\"\n        \"# a[i+3] += m[3] * mu\\n\\t\"\n        \"mul\tx3, x11, x5\\n\\t\"\n        \"umulh\tx4, x11, x5\\n\\t\"\n        \"ldr\tx7, [x6, 24]\\n\\t\"\n        \"ldr\tx12, [x6, 32]\\n\\t\"\n        \"adds\tx3, x3, x10\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"cset\tx9, cs\\n\\t\"\n        \"adds\tx7, x7, x3\\n\\t\"\n        \"str\tx7, [x6, 24]\\n\\t\"\n        \"adcs\tx12, x12, x4\\n\\t\"\n        \"str\tx12, [x6, 32]\\n\\t\"\n        \"adc\tx9, x9, xzr\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"add\tx6, x6, 8\\n\\t\"\n        \"add\tx8, x8, 8\\n\\t\"\n        \"cmp\tx8, 32\\n\\t\"\n        \"b.lt\t1b\\n\\t\"\n        \"ldr\tx5, [%[a], 32]\\n\\t\"\n        \"ldr\tx6, [%[a], 40]\\n\\t\"\n        \"ldr\tx7, [%[a], 48]\\n\\t\"\n        \"ldr\tx8, [%[a], 56]\\n\\t\"\n        \"sub\tx3, xzr, x9\\n\\t\"\n        \"ldr\tx9, [%[m], 0]\\n\\t\"\n        \"ldr\tx10, [%[m], 8]\\n\\t\"\n        \"ldr\tx11, [%[m], 16]\\n\\t\"\n        \"ldr\tx12, [%[m], 24]\\n\\t\"\n        \"and\tx9, x9, x3\\n\\t\"\n        \"and\tx10, x10, x3\\n\\t\"\n        \"and\tx11, x11, x3\\n\\t\"\n        \"and\tx12, x12, x3\\n\\t\"\n        \"subs\tx5, x5, x9\\n\\t\"\n        \"sbcs\tx6, x6, x10\\n\\t\"\n        \"sbcs\tx7, x7, x11\\n\\t\"\n        \"sbc\tx8, x8, x12\\n\\t\"\n        \"str\tx5, [%[a], 0]\\n\\t\"\n        \"str\tx6, [%[a], 8]\\n\\t\"\n        \"str\tx7, [%[a], 16]\\n\\t\"\n        \"str\tx8, [%[a], 24]\\n\\t\"\n        :\n        : [a] \"r\" (a), [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\",\n          \"x12\"\n    );\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nSP_NOINLINE static void sp_256_mont_mul_4(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    (void)mp;\n\n    __asm__ __volatile__ (\n        \"ldr\tx19, [%[a], 0]\\n\\t\"\n        \"ldr\tx20, [%[a], 8]\\n\\t\"\n        \"ldr\tx21, [%[a], 16]\\n\\t\"\n        \"ldr\tx22, [%[a], 24]\\n\\t\"\n        \"ldr\tx23, [%[b], 0]\\n\\t\"\n        \"ldr\tx24, [%[b], 8]\\n\\t\"\n        \"ldr\tx25, [%[b], 16]\\n\\t\"\n        \"ldr\tx26, [%[b], 24]\\n\\t\"\n        \"#  A[0] * B[0]\\n\\t\"\n        \"mul\tx10, x19, x23\\n\\t\"\n        \"umulh\tx11, x19, x23\\n\\t\"\n        \"#  A[0] * B[1]\\n\\t\"\n        \"mul\tx5, x19, x24\\n\\t\"\n        \"umulh\tx6, x19, x24\\n\\t\"\n        \"adds\tx11, x11, x5\\n\\t\"\n        \"adc\tx12, xzr, x6\\n\\t\"\n        \"#  A[1] * B[0]\\n\\t\"\n        \"mul\tx5, x20, x23\\n\\t\"\n        \"umulh\tx6, x20, x23\\n\\t\"\n        \"adds\tx11, x11, x5\\n\\t\"\n        \"adcs\tx12, x12, x6\\n\\t\"\n        \"adc\tx13, xzr, xzr\\n\\t\"\n        \"#  A[0] * B[2]\\n\\t\"\n        \"mul\tx5, x19, x25\\n\\t\"\n        \"umulh\tx6, x19, x25\\n\\t\"\n        \"adds\tx12, x12, x5\\n\\t\"\n        \"adc\tx13, x13, x6\\n\\t\"\n        \"#  A[1] * B[1]\\n\\t\"\n        \"mul\tx5, x20, x24\\n\\t\"\n        \"umulh\tx6, x20, x24\\n\\t\"\n        \"adds\tx12, x12, x5\\n\\t\"\n        \"adcs\tx13, x13, x6\\n\\t\"\n        \"adc\tx14, xzr, xzr\\n\\t\"\n        \"#  A[2] * B[0]\\n\\t\"\n        \"mul\tx5, x21, x23\\n\\t\"\n        \"umulh\tx6, x21, x23\\n\\t\"\n        \"adds\tx12, x12, x5\\n\\t\"\n        \"adcs\tx13, x13, x6\\n\\t\"\n        \"adc\tx14, x14, xzr\\n\\t\"\n        \"#  A[0] * B[3]\\n\\t\"\n        \"mul\tx5, x19, x26\\n\\t\"\n        \"umulh\tx6, x19, x26\\n\\t\"\n        \"adds\tx13, x13, x5\\n\\t\"\n        \"adcs\tx14, x14, x6\\n\\t\"\n        \"adc\tx15, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[2]\\n\\t\"\n        \"mul\tx5, x20, x25\\n\\t\"\n        \"umulh\tx6, x20, x25\\n\\t\"\n        \"adds\tx13, x13, x5\\n\\t\"\n        \"adcs\tx14, x14, x6\\n\\t\"\n        \"adc\tx15, x15, xzr\\n\\t\"\n        \"#  A[2] * B[1]\\n\\t\"\n        \"mul\tx5, x21, x24\\n\\t\"\n        \"umulh\tx6, x21, x24\\n\\t\"\n        \"adds\tx13, x13, x5\\n\\t\"\n        \"adcs\tx14, x14, x6\\n\\t\"\n        \"adc\tx15, x15, xzr\\n\\t\"\n        \"#  A[3] * B[0]\\n\\t\"\n        \"mul\tx5, x22, x23\\n\\t\"\n        \"umulh\tx6, x22, x23\\n\\t\"\n        \"adds\tx13, x13, x5\\n\\t\"\n        \"adcs\tx14, x14, x6\\n\\t\"\n        \"adc\tx15, x15, xzr\\n\\t\"\n        \"#  A[1] * B[3]\\n\\t\"\n        \"mul\tx5, x20, x26\\n\\t\"\n        \"umulh\tx6, x20, x26\\n\\t\"\n        \"adds\tx14, x14, x5\\n\\t\"\n        \"adcs\tx15, x15, x6\\n\\t\"\n        \"adc\tx16, xzr, xzr\\n\\t\"\n        \"#  A[2] * B[2]\\n\\t\"\n        \"mul\tx5, x21, x25\\n\\t\"\n        \"umulh\tx6, x21, x25\\n\\t\"\n        \"adds\tx14, x14, x5\\n\\t\"\n        \"adcs\tx15, x15, x6\\n\\t\"\n        \"adc\tx16, x16, xzr\\n\\t\"\n        \"#  A[3] * B[1]\\n\\t\"\n        \"mul\tx5, x22, x24\\n\\t\"\n        \"umulh\tx6, x22, x24\\n\\t\"\n        \"adds\tx14, x14, x5\\n\\t\"\n        \"adcs\tx15, x15, x6\\n\\t\"\n        \"adc\tx16, x16, xzr\\n\\t\"\n        \"#  A[2] * B[3]\\n\\t\"\n        \"mul\tx5, x21, x26\\n\\t\"\n        \"umulh\tx6, x21, x26\\n\\t\"\n        \"adds\tx15, x15, x5\\n\\t\"\n        \"adcs\tx16, x16, x6\\n\\t\"\n        \"adc\tx17, xzr, xzr\\n\\t\"\n        \"#  A[3] * B[2]\\n\\t\"\n        \"mul\tx5, x22, x25\\n\\t\"\n        \"umulh\tx6, x22, x25\\n\\t\"\n        \"adds\tx15, x15, x5\\n\\t\"\n        \"adcs\tx16, x16, x6\\n\\t\"\n        \"adc\tx17, x17, xzr\\n\\t\"\n        \"#  A[3] * B[3]\\n\\t\"\n        \"mul\tx5, x22, x26\\n\\t\"\n        \"umulh\tx6, x22, x26\\n\\t\"\n        \"adds\tx16, x16, x5\\n\\t\"\n        \"adc\tx17, x17, x6\\n\\t\"\n        \"# Start Reduction\\n\\t\"\n        \"mov\tx5, x10\\n\\t\"\n        \"mov\tx6, x11\\n\\t\"\n        \"mov\tx7, x12\\n\\t\"\n        \"mov\tx8, x13\\n\\t\"\n        \"# mu = a[0]-a[3] + a[0]-a[2] << 32 << 64 + (a[0] * 2) << 192\\n\\t\"\n        \"#    - a[0] << 32 << 192\\n\\t\"\n        \"#   + (a[0] * 2) << 192\\n\\t\"\n        \"add\tx8, x8, x10\\n\\t\"\n        \"add\tx8, x8, x10\\n\\t\"\n        \"#   a[0]-a[2] << 32\\n\\t\"\n        \"lsl\tx10, x10, 32\\n\\t\"\n        \"lsr\tx19, x5, 32\\n\\t\"\n        \"lsl\tx11, x6, 32\\n\\t\"\n        \"lsr\tx20, x6, 32\\n\\t\"\n        \"lsl\tx12, x7, 32\\n\\t\"\n        \"eor\tx11, x11, x19\\n\\t\"\n        \"eor\tx12, x12, x20\\n\\t\"\n        \"#   - a[0] << 32 << 192\\n\\t\"\n        \"sub\tx8, x8, x10\\n\\t\"\n        \"#   + a[0]-a[2] << 32 << 64\\n\\t\"\n        \"adds\tx6, x6, x10\\n\\t\"\n        \"adcs\tx7, x7, x11\\n\\t\"\n        \"adc\tx8, x8, x12\\n\\t\"\n        \"# a += (mu << 256) - (mu << 224) + (mu << 192) + (mu << 96) - mu\\n\\t\"\n        \"#   a += mu << 256\\n\\t\"\n        \"adds\tx14, x14, x5\\n\\t\"\n        \"adcs\tx15, x15, x6\\n\\t\"\n        \"adcs\tx16, x16, x7\\n\\t\"\n        \"adcs\tx17, x17, x8\\n\\t\"\n        \"csetm\tx10, cs\\n\\t\"\n        \"#   a += mu << 192\\n\\t\"\n        \"adds\tx13, x13, x5\\n\\t\"\n        \"adcs\tx14, x14, x6\\n\\t\"\n        \"adcs\tx15, x15, x7\\n\\t\"\n        \"adcs\tx16, x16, x8\\n\\t\"\n        \"adcs\tx17, x17, xzr\\n\\t\"\n        \"csetm\tx21, cs\\n\\t\"\n        \"add\tx10, x10, x21\\n\\t\"\n        \"# mu <<= 32\\n\\t\"\n        \"lsr\tx9, x8, 32\\n\\t\"\n        \"lsr\tx19, x5, 32\\n\\t\"\n        \"lsl\tx5, x5, 32\\n\\t\"\n        \"lsr\tx20, x6, 32\\n\\t\"\n        \"lsl\tx6, x6, 32\\n\\t\"\n        \"lsr\tx21, x7, 32\\n\\t\"\n        \"lsl\tx7, x7, 32\\n\\t\"\n        \"lsl\tx8, x8, 32\\n\\t\"\n        \"eor\tx6, x6, x19\\n\\t\"\n        \"eor\tx7, x7, x20\\n\\t\"\n        \"eor\tx8, x8, x21\\n\\t\"\n        \"#   a += (mu << 32) << 64\\n\\t\"\n        \"adds\tx13, x13, x7\\n\\t\"\n        \"adcs\tx14, x14, x8\\n\\t\"\n        \"adcs\tx15, x15, x9\\n\\t\"\n        \"adcs\tx16, x16, xzr\\n\\t\"\n        \"adcs\tx17, x17, xzr\\n\\t\"\n        \"csetm\tx21, cs\\n\\t\"\n        \"add\tx10, x10, x21\\n\\t\"\n        \"#   a -= (mu << 32) << 192\\n\\t\"\n        \"subs\tx13, x13, x5\\n\\t\"\n        \"mov\tx19, 0xffffffff\\n\\t\"\n        \"sbcs\tx14, x14, x6\\n\\t\"\n        \"mov\tx20, 0xffffffff00000001\\n\\t\"\n        \"sbcs\tx15, x15, x7\\n\\t\"\n        \"sbcs\tx16, x16, x8\\n\\t\"\n        \"sbcs\tx17, x17, x9\\n\\t\"\n        \"cset\tx21, cc\\n\\t\"\n        \"add\tx10, x10, x21\\n\\t\"\n        \"# mask m and sub from result if overflow\\n\\t\"\n        \"#  m[0] = -1 & mask = mask\\n\\t\"\n        \"and\tx19, x19, x10\\n\\t\"\n        \"#  m[2] =  0 & mask = 0\\n\\t\"\n        \"and\tx20, x20, x10\\n\\t\"\n        \"subs\tx14, x14, x10\\n\\t\"\n        \"sbcs\tx15, x15, x19\\n\\t\"\n        \"sbcs\tx16, x16, xzr\\n\\t\"\n        \"sbc\tx17, x17, x20\\n\\t\"\n        \"str\tx14, [%[r], 0]\\n\\t\"\n        \"str\tx15, [%[r], 8]\\n\\t\"\n        \"str\tx16, [%[r], 16]\\n\\t\"\n        \"str\tx17, [%[r], 24]\\n\\t\"\n        : [m] \"+r\" (m), [a] \"+r\" (a), [b] \"+r\" (b)\n        : [r] \"r\" (r)\n        : \"memory\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\",\n          \"x19\", \"x20\", \"x21\", \"x22\",\n          \"x23\", \"x24\", \"x25\", \"x26\",\n          \"x10\", \"x11\", \"x12\", \"x13\", \"x14\", \"x15\", \"x16\", \"x17\"\n    );\n}\n\n/* Square the Montgomery form number mod the modulus (prime). (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nSP_NOINLINE static void sp_256_mont_sqr_4(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    __asm__ __volatile__ (\n        \"ldr\tx19, [%[a], 0]\\n\\t\"\n        \"ldr\tx20, [%[a], 8]\\n\\t\"\n        \"ldr\tx21, [%[a], 16]\\n\\t\"\n        \"ldr\tx22, [%[a], 24]\\n\\t\"\n        \"#  A[0] * A[1]\\n\\t\"\n        \"mul\tx11, x19, x20\\n\\t\"\n        \"umulh\tx12, x19, x20\\n\\t\"\n        \"#  A[0] * A[2]\\n\\t\"\n        \"mul\tx5, x19, x21\\n\\t\"\n        \"umulh\tx6, x19, x21\\n\\t\"\n        \"adds\tx12, x12, x5\\n\\t\"\n        \"adc\tx13, xzr, x6\\n\\t\"\n        \"#  A[0] * A[3]\\n\\t\"\n        \"mul\tx5, x19, x22\\n\\t\"\n        \"umulh\tx6, x19, x22\\n\\t\"\n        \"adds\tx13, x13, x5\\n\\t\"\n        \"adc\tx14, xzr, x6\\n\\t\"\n        \"#  A[1] * A[2]\\n\\t\"\n        \"mul\tx5, x20, x21\\n\\t\"\n        \"umulh\tx6, x20, x21\\n\\t\"\n        \"adds\tx13, x13, x5\\n\\t\"\n        \"adcs\tx14, x14, x6\\n\\t\"\n        \"adc\tx15, xzr, xzr\\n\\t\"\n        \"#  A[1] * A[3]\\n\\t\"\n        \"mul\tx5, x20, x22\\n\\t\"\n        \"umulh\tx6, x20, x22\\n\\t\"\n        \"adds\tx14, x14, x5\\n\\t\"\n        \"adc\tx15, x15, x6\\n\\t\"\n        \"#  A[2] * A[3]\\n\\t\"\n        \"mul\tx5, x21, x22\\n\\t\"\n        \"umulh\tx6, x21, x22\\n\\t\"\n        \"adds\tx15, x15, x5\\n\\t\"\n        \"adc\tx16, xzr, x6\\n\\t\"\n        \"# Double\\n\\t\"\n        \"adds\tx11, x11, x11\\n\\t\"\n        \"adcs\tx12, x12, x12\\n\\t\"\n        \"adcs\tx13, x13, x13\\n\\t\"\n        \"adcs\tx14, x14, x14\\n\\t\"\n        \"adcs\tx15, x15, x15\\n\\t\"\n        \"adcs\tx16, x16, x16\\n\\t\"\n        \"cset\tx17, cs\\n\\t\"\n        \"#  A[0] * A[0]\\n\\t\"\n        \"mul\tx10, x19, x19\\n\\t\"\n        \"umulh\tx4, x19, x19\\n\\t\"\n        \"#  A[1] * A[1]\\n\\t\"\n        \"mul\tx5, x20, x20\\n\\t\"\n        \"umulh\tx6, x20, x20\\n\\t\"\n        \"#  A[2] * A[2]\\n\\t\"\n        \"mul\tx7, x21, x21\\n\\t\"\n        \"umulh\tx8, x21, x21\\n\\t\"\n        \"#  A[3] * A[3]\\n\\t\"\n        \"mul\tx9, x22, x22\\n\\t\"\n        \"umulh\tx19, x22, x22\\n\\t\"\n        \"adds\tx11, x11, x4\\n\\t\"\n        \"adcs\tx12, x12, x5\\n\\t\"\n        \"adcs\tx13, x13, x6\\n\\t\"\n        \"adcs\tx14, x14, x7\\n\\t\"\n        \"adcs\tx15, x15, x8\\n\\t\"\n        \"adcs\tx16, x16, x9\\n\\t\"\n        \"adc\tx17, x17, x19\\n\\t\"\n        \"# Start Reduction\\n\\t\"\n        \"mov\tx5, x10\\n\\t\"\n        \"mov\tx6, x11\\n\\t\"\n        \"mov\tx7, x12\\n\\t\"\n        \"mov\tx8, x13\\n\\t\"\n        \"# mu = a[0]-a[3] + a[0]-a[2] << 32 << 64 + (a[0] * 2) << 192\\n\\t\"\n        \"#    - a[0] << 32 << 192\\n\\t\"\n        \"#   + (a[0] * 2) << 192\\n\\t\"\n        \"add\tx8, x8, x10\\n\\t\"\n        \"add\tx8, x8, x10\\n\\t\"\n        \"#   a[0]-a[2] << 32\\n\\t\"\n        \"lsl\tx10, x10, 32\\n\\t\"\n        \"lsr\tx19, x5, 32\\n\\t\"\n        \"lsl\tx11, x6, 32\\n\\t\"\n        \"lsr\tx20, x6, 32\\n\\t\"\n        \"lsl\tx12, x7, 32\\n\\t\"\n        \"eor\tx11, x11, x19\\n\\t\"\n        \"eor\tx12, x12, x20\\n\\t\"\n        \"#   - a[0] << 32 << 192\\n\\t\"\n        \"sub\tx8, x8, x10\\n\\t\"\n        \"#   + a[0]-a[2] << 32 << 64\\n\\t\"\n        \"adds\tx6, x6, x10\\n\\t\"\n        \"adcs\tx7, x7, x11\\n\\t\"\n        \"adc\tx8, x8, x12\\n\\t\"\n        \"# a += (mu << 256) - (mu << 224) + (mu << 192) + (mu << 96) - mu\\n\\t\"\n        \"#   a += mu << 256\\n\\t\"\n        \"adds\tx14, x14, x5\\n\\t\"\n        \"adcs\tx15, x15, x6\\n\\t\"\n        \"adcs\tx16, x16, x7\\n\\t\"\n        \"adcs\tx17, x17, x8\\n\\t\"\n        \"csetm\tx10, cs\\n\\t\"\n        \"#   a += mu << 192\\n\\t\"\n        \"adds\tx13, x13, x5\\n\\t\"\n        \"adcs\tx14, x14, x6\\n\\t\"\n        \"adcs\tx15, x15, x7\\n\\t\"\n        \"adcs\tx16, x16, x8\\n\\t\"\n        \"adcs\tx17, x17, xzr\\n\\t\"\n        \"csetm\tx21, cs\\n\\t\"\n        \"add\tx10, x10, x21\\n\\t\"\n        \"# mu <<= 32\\n\\t\"\n        \"lsr\tx9, x8, 32\\n\\t\"\n        \"lsr\tx19, x5, 32\\n\\t\"\n        \"lsl\tx5, x5, 32\\n\\t\"\n        \"lsr\tx20, x6, 32\\n\\t\"\n        \"lsl\tx6, x6, 32\\n\\t\"\n        \"lsr\tx21, x7, 32\\n\\t\"\n        \"lsl\tx7, x7, 32\\n\\t\"\n        \"lsl\tx8, x8, 32\\n\\t\"\n        \"eor\tx6, x6, x19\\n\\t\"\n        \"eor\tx7, x7, x20\\n\\t\"\n        \"eor\tx8, x8, x21\\n\\t\"\n        \"#   a += (mu << 32) << 64\\n\\t\"\n        \"adds\tx13, x13, x7\\n\\t\"\n        \"adcs\tx14, x14, x8\\n\\t\"\n        \"adcs\tx15, x15, x9\\n\\t\"\n        \"adcs\tx16, x16, xzr\\n\\t\"\n        \"adcs\tx17, x17, xzr\\n\\t\"\n        \"csetm\tx21, cs\\n\\t\"\n        \"add\tx10, x10, x21\\n\\t\"\n        \"#   a -= (mu << 32) << 192\\n\\t\"\n        \"subs\tx13, x13, x5\\n\\t\"\n        \"mov\tx19, 0xffffffff\\n\\t\"\n        \"sbcs\tx14, x14, x6\\n\\t\"\n        \"mov\tx20, 0xffffffff00000001\\n\\t\"\n        \"sbcs\tx15, x15, x7\\n\\t\"\n        \"sbcs\tx16, x16, x8\\n\\t\"\n        \"sbcs\tx17, x17, x9\\n\\t\"\n        \"cset\tx21, cc\\n\\t\"\n        \"add\tx10, x10, x21\\n\\t\"\n        \"# mask m and sub from result if overflow\\n\\t\"\n        \"#  m[0] = -1 & mask = mask\\n\\t\"\n        \"and\tx19, x19, x10\\n\\t\"\n        \"#  m[2] =  0 & mask = 0\\n\\t\"\n        \"and\tx20, x20, x10\\n\\t\"\n        \"subs\tx14, x14, x10\\n\\t\"\n        \"sbcs\tx15, x15, x19\\n\\t\"\n        \"sbcs\tx16, x16, xzr\\n\\t\"\n        \"sbc\tx17, x17, x20\\n\\t\"\n        \"str\tx14, [%[r], 0]\\n\\t\"\n        \"str\tx15, [%[r], 8]\\n\\t\"\n        \"str\tx16, [%[r], 16]\\n\\t\"\n        \"str\tx17, [%[r], 24]\\n\\t\"\n        : [m] \"+r\" (m), [a] \"+r\" (a), [mp] \"+r\" (mp)\n        : [r] \"r\" (r)\n        : \"memory\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\",\n          \"x19\", \"x20\", \"x21\", \"x22\",\n          \"x10\", \"x11\", \"x12\", \"x13\", \"x14\", \"x15\", \"x16\", \"x17\"\n    );\n}\n\n#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)\n/* Square the Montgomery form number a number of times. (r = a ^ n mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * n   Number of times to square.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_sqr_n_4(sp_digit* r, const sp_digit* a, int n,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_256_mont_sqr_4(r, a, m, mp);\n    for (; n > 1; n--) {\n        sp_256_mont_sqr_4(r, r, m, mp);\n    }\n}\n\n#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */\n#ifdef WOLFSSL_SP_SMALL\n/* Mod-2 for the P256 curve. */\nstatic const uint64_t p256_mod_2[4] = {\n    0xfffffffffffffffdU,0x00000000ffffffffU,0x0000000000000000U,\n    0xffffffff00000001U\n};\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the modulus (prime) of the\n * P256 curve. (r = 1 / a mod m)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_4(sp_digit* r, const sp_digit* a, sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 4);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_4(t, t, p256_mod, p256_mp_mod);\n        if (p256_mod_2[i / 64] & ((sp_digit)1 << (i % 64)))\n            sp_256_mont_mul_4(t, t, a, p256_mod, p256_mp_mod);\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 4);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 4;\n    sp_digit* t3 = td + 4 * 4;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_4(t, a, p256_mod, p256_mp_mod);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_4(t, t, a, p256_mod, p256_mp_mod);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_4(t2, t, 2, p256_mod, p256_mp_mod);\n    /* t3= a^d = t2 * a */\n    sp_256_mont_mul_4(t3, t2, a, p256_mod, p256_mp_mod);\n    /* t = a^f = t2 * t */\n    sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^f0 = t ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_4(t2, t, 4, p256_mod, p256_mp_mod);\n    /* t3= a^fd = t2 * t3 */\n    sp_256_mont_mul_4(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ff = t2 * t */\n    sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_4(t2, t, 8, p256_mod, p256_mp_mod);\n    /* t3= a^fffd = t2 * t3 */\n    sp_256_mont_mul_4(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_4(t2, t, 16, p256_mod, p256_mp_mod);\n    /* t3= a^fffffffd = t2 * t3 */\n    sp_256_mont_mul_4(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff00000000 = t ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_4(t2, t, 32, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001 = t2 * a */\n    sp_256_mont_mul_4(t2, t2, a, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff000000010000000000000000000000000000000000000000\n     *   = t2 ^ 2 ^ 160 */\n    sp_256_mont_sqr_n_4(t2, t2, 160, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff\n     *   = t2 * t */\n    sp_256_mont_mul_4(t2, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000\n     *   = t2 ^ 2 ^ 32 */\n    sp_256_mont_sqr_n_4(t2, t2, 32, p256_mod, p256_mp_mod);\n    /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd\n     *   = t2 * t3 */\n    sp_256_mont_mul_4(r, t2, t3, p256_mod, p256_mp_mod);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Map the Montgomery form projective co-ordinate point to an affine point.\n *\n * r  Resulting affine co-ordinate point.\n * p  Montgomery form projective co-ordinate point.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_map_4(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    int64_t n;\n\n    sp_256_mont_inv_4(t1, p->z, t + 2*4);\n\n    sp_256_mont_sqr_4(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    /* x /= z^2 */\n    sp_256_mont_mul_4(r->x, p->x, t2, p256_mod, p256_mp_mod);\n    XMEMSET(r->x + 4, 0, sizeof(r->x) / 2U);\n    sp_256_mont_reduce_4(r->x, p256_mod, p256_mp_mod);\n    /* Reduce x to less than modulus */\n    n = sp_256_cmp_4(r->x, p256_mod);\n    sp_256_cond_sub_4(r->x, r->x, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_4(r->x);\n\n    /* y /= z^3 */\n    sp_256_mont_mul_4(r->y, p->y, t1, p256_mod, p256_mp_mod);\n    XMEMSET(r->y + 4, 0, sizeof(r->y) / 2U);\n    sp_256_mont_reduce_4(r->y, p256_mod, p256_mp_mod);\n    /* Reduce y to less than modulus */\n    n = sp_256_cmp_4(r->y, p256_mod);\n    sp_256_cond_sub_4(r->y, r->y, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_4(r->y);\n\n    XMEMSET(r->z, 0, sizeof(r->z));\n    r->z[0] = 1;\n\n}\n\n/* Add two Montgomery form numbers (r = a + b % m).\n *\n * r   Result of addition.\n * a   First number to add in Montogmery form.\n * b   Second number to add in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_add_4(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m)\n{\n    __asm__ __volatile__ (\n        \"ldr\tx4, [%[a],0]\\n\\t\"\n        \"ldr\tx5, [%[a],8]\\n\\t\"\n        \"ldr\tx6, [%[a],16]\\n\\t\"\n        \"ldr\tx7, [%[a],24]\\n\\t\"\n        \"ldr\tx8, [%[b],0]\\n\\t\"\n        \"ldr\tx9, [%[b],8]\\n\\t\"\n        \"ldr\tx10, [%[b],16]\\n\\t\"\n        \"ldr\tx11, [%[b],24]\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"mov\tx12, 0xffffffff\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"adcs\tx7, x7, x11\\n\\t\"\n        \"mov\tx13, 0xffffffff00000001\\n\\t\"\n        \"csetm\tx14, cs\\n\\t\"\n        \"and\tx12, x12, x14\\n\\t\"\n        \"and\tx13, x13, x14\\n\\t\"\n        \"subs\tx4, x4, x14\\n\\t\"\n        \"sbcs\tx5, x5, x12\\n\\t\"\n        \"str\tx4, [%[r],0]\\n\\t\"\n        \"sbcs\tx6, x6, xzr\\n\\t\"\n        \"str\tx5, [%[r],8]\\n\\t\"\n        \"sbc\tx7, x7, x13\\n\\t\"\n        \"str\tx6, [%[r],16]\\n\\t\"\n        \"str\tx7, [%[r],24]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\", \"x12\", \"x13\", \"x14\"\n    );\n}\n\n/* Double a Montgomery form number (r = a + a % m).\n *\n * r   Result of doubling.\n * a   Number to double in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_dbl_4(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    __asm__ __volatile__ (\n        \"ldr\tx3, [%[a]]\\n\\t\"\n        \"ldr\tx4, [%[a],8]\\n\\t\"\n        \"ldr\tx5, [%[a],16]\\n\\t\"\n        \"ldr\tx6, [%[a],24]\\n\\t\"\n        \"adds\tx3, x3, x3\\n\\t\"\n        \"adcs\tx4, x4, x4\\n\\t\"\n        \"mov\tx7, 0xffffffff\\n\\t\"\n        \"adcs\tx5, x5, x5\\n\\t\"\n        \"mov\tx8, 0xffffffff00000001\\n\\t\"\n        \"adcs\tx6, x6, x6\\n\\t\"\n        \"csetm\tx9, cs\\n\\t\"\n        \"and\tx7, x7, x9\\n\\t\"\n        \"and\tx8, x8, x9\\n\\t\"\n        \"subs\tx3, x3, x9\\n\\t\"\n        \"sbcs\tx4, x4, x7\\n\\t\"\n        \"str\tx3, [%[r],0]\\n\\t\"\n        \"sbcs\tx5, x5, xzr\\n\\t\"\n        \"str\tx4, [%[r],8]\\n\\t\"\n        \"sbc\tx6, x6, x8\\n\\t\"\n        \"str\tx5, [%[r],16]\\n\\t\"\n        \"str\tx6, [%[r],24]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\"\n    );\n\n    (void)m;\n}\n\n/* Triple a Montgomery form number (r = a + a + a % m).\n *\n * r   Result of Tripling.\n * a   Number to triple in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_tpl_4(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    __asm__ __volatile__ (\n        \"ldr\tx10, [%[a]]\\n\\t\"\n        \"ldr\tx11, [%[a],8]\\n\\t\"\n        \"ldr\tx12, [%[a],16]\\n\\t\"\n        \"ldr\tx13, [%[a],24]\\n\\t\"\n        \"adds\tx3, x10, x10\\n\\t\"\n        \"adcs\tx4, x11, x11\\n\\t\"\n        \"mov\tx7, 0xffffffff\\n\\t\"\n        \"adcs\tx5, x12, x12\\n\\t\"\n        \"mov\tx8, 0xffffffff00000001\\n\\t\"\n        \"adcs\tx6, x13, x13\\n\\t\"\n        \"csetm\tx9, cs\\n\\t\"\n        \"and\tx7, x7, x9\\n\\t\"\n        \"and\tx8, x8, x9\\n\\t\"\n        \"subs\tx3, x3, x9\\n\\t\"\n        \"sbcs\tx4, x4, x7\\n\\t\"\n        \"sbcs\tx5, x5, xzr\\n\\t\"\n        \"sbc\tx6, x6, x8\\n\\t\"\n        \"adds\tx3, x3, x10\\n\\t\"\n        \"adcs\tx4, x4, x11\\n\\t\"\n        \"mov\tx7, 0xffffffff\\n\\t\"\n        \"adcs\tx5, x5, x12\\n\\t\"\n        \"mov\tx8, 0xffffffff00000001\\n\\t\"\n        \"adcs\tx6, x6, x13\\n\\t\"\n        \"csetm\tx9, cs\\n\\t\"\n        \"and\tx7, x7, x9\\n\\t\"\n        \"and\tx8, x8, x9\\n\\t\"\n        \"subs\tx3, x3, x9\\n\\t\"\n        \"sbcs\tx4, x4, x7\\n\\t\"\n        \"sbcs\tx5, x5, xzr\\n\\t\"\n        \"sbc\tx6, x6, x8\\n\\t\"\n        \"str\tx3, [%[r], 0]\\n\\t\"\n        \"str\tx4, [%[r], 8]\\n\\t\"\n        \"str\tx5, [%[r], 16]\\n\\t\"\n        \"str\tx6, [%[r], 24]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"x10\", \"x11\", \"x12\", \"x13\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\"\n    );\n\n    (void)m;\n}\n\n/* Subtract two Montgomery form numbers (r = a - b % m).\n *\n * r   Result of subtration.\n * a   Number to subtract from in Montogmery form.\n * b   Number to subtract with in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_sub_4(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m)\n{\n    __asm__ __volatile__ (\n        \"ldr\tx4, [%[a],0]\\n\\t\"\n        \"ldr\tx5, [%[a],8]\\n\\t\"\n        \"ldr\tx6, [%[a],16]\\n\\t\"\n        \"ldr\tx7, [%[a],24]\\n\\t\"\n        \"ldr\tx8, [%[b],0]\\n\\t\"\n        \"ldr\tx9, [%[b],8]\\n\\t\"\n        \"ldr\tx10, [%[b],16]\\n\\t\"\n        \"ldr\tx11, [%[b],24]\\n\\t\"\n        \"subs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"mov\tx12, 0xffffffff\\n\\t\"\n        \"sbcs\tx6, x6, x10\\n\\t\"\n        \"sbcs\tx7, x7, x11\\n\\t\"\n        \"mov\tx13, 0xffffffff00000001\\n\\t\"\n        \"csetm\tx14, cc\\n\\t\"\n        \"and\tx12, x12, x14\\n\\t\"\n        \"and\tx13, x13, x14\\n\\t\"\n        \"adds\tx4, x4, x14\\n\\t\"\n        \"adcs\tx5, x5, x12\\n\\t\"\n        \"str\tx4, [%[r],0]\\n\\t\"\n        \"adcs\tx6, x6, xzr\\n\\t\"\n        \"str\tx5, [%[r],8]\\n\\t\"\n        \"adc\tx7, x7, x13\\n\\t\"\n        \"str\tx6, [%[r],16]\\n\\t\"\n        \"str\tx7, [%[r],24]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\", \"x12\", \"x13\", \"x14\"\n    );\n}\n\n/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)\n *\n * r  Result of division by 2.\n * a  Number to divide.\n * m  Modulus (prime).\n */\nstatic void sp_256_div2_4(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    __asm__ __volatile__ (\n        \"ldr\tx3, [%[a], 0]\\n\\t\"\n        \"ldr\tx4, [%[a], 8]\\n\\t\"\n        \"ldr\tx5, [%[a], 16]\\n\\t\"\n        \"ldr\tx6, [%[a], 24]\\n\\t\"\n        \"and\tx9, x3, 1\\n\\t\"\n        \"sub\tx10, xzr, x9\\n\\t\"\n        \"and\tx7, x10, 0xffffffff\\n\\t\"\n        \"and\tx8, x10, 0xffffffff00000001\\n\\t\"\n        \"adds\tx3, x3, x10\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adcs\tx5, x5, xzr\\n\\t\"\n        \"adcs\tx6, x6, x8\\n\\t\"\n        \"cset\tx9, cs\\n\\t\"\n        \"lsr\tx3, x3, 1\\n\\t\"\n        \"lsr\tx7, x4, 1\\n\\t\"\n        \"lsr\tx8, x5, 1\\n\\t\"\n        \"lsr\tx10, x6, 1\\n\\t\"\n        \"orr\tx3, x3, x4, lsl 63\\n\\t\"\n        \"orr\tx4, x7, x5, lsl 63\\n\\t\"\n        \"orr\tx5, x8, x6, lsl 63\\n\\t\"\n        \"orr\tx6, x10, x9, lsl 63\\n\\t\"\n        \"str\tx3, [%[r], 0]\\n\\t\"\n        \"str\tx4, [%[r], 8]\\n\\t\"\n        \"str\tx5, [%[r], 16]\\n\\t\"\n        \"str\tx6, [%[r], 24]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [m] \"r\" (m)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n}\n\n/* Double the Montgomery form projective point p.\n *\n * r  Result of doubling point.\n * p  Point to double.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_4(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* When infinity don't double point passed in - constant time. */\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    /* Put point to double into result - good for infinty. */\n    if (r != p) {\n        for (i=0; i<4; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<4; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<4; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* T1 = Z * Z */\n    sp_256_mont_sqr_4(t1, z, p256_mod, p256_mp_mod);\n    /* Z = Y * Z */\n    sp_256_mont_mul_4(z, y, z, p256_mod, p256_mp_mod);\n    /* Z = 2Z */\n    sp_256_mont_dbl_4(z, z, p256_mod);\n    /* T2 = X - T1 */\n    sp_256_mont_sub_4(t2, x, t1, p256_mod);\n    /* T1 = X + T1 */\n    sp_256_mont_add_4(t1, x, t1, p256_mod);\n    /* T2 = T1 * T2 */\n    sp_256_mont_mul_4(t2, t1, t2, p256_mod, p256_mp_mod);\n    /* T1 = 3T2 */\n    sp_256_mont_tpl_4(t1, t2, p256_mod);\n    /* Y = 2Y */\n    sp_256_mont_dbl_4(y, y, p256_mod);\n    /* Y = Y * Y */\n    sp_256_mont_sqr_4(y, y, p256_mod, p256_mp_mod);\n    /* T2 = Y * Y */\n    sp_256_mont_sqr_4(t2, y, p256_mod, p256_mp_mod);\n    /* T2 = T2/2 */\n    sp_256_div2_4(t2, t2, p256_mod);\n    /* Y = Y * X */\n    sp_256_mont_mul_4(y, y, x, p256_mod, p256_mp_mod);\n    /* X = T1 * T1 */\n    sp_256_mont_mul_4(x, t1, t1, p256_mod, p256_mp_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_4(x, x, y, p256_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_4(x, x, y, p256_mod);\n    /* Y = Y - X */\n    sp_256_mont_sub_4(y, y, x, p256_mod);\n    /* Y = Y * T1 */\n    sp_256_mont_mul_4(y, y, t1, p256_mod, p256_mp_mod);\n    /* Y = Y - T2 */\n    sp_256_mont_sub_4(y, y, t2, p256_mod);\n\n}\n\n/* Double the Montgomery form projective point p a number of times.\n *\n * r  Result of repeated doubling of point.\n * p  Point to double.\n * n  Number of times to double\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_n_4(sp_point* r, const sp_point* p, int n,\n        sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* w = t;\n    sp_digit* a = t + 2*4;\n    sp_digit* b = t + 4*4;\n    sp_digit* t1 = t + 6*4;\n    sp_digit* t2 = t + 8*4;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    if (r != p) {\n        for (i=0; i<4; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<4; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<4; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* Y = 2*Y */\n    sp_256_mont_dbl_4(y, y, p256_mod);\n    /* W = Z^4 */\n    sp_256_mont_sqr_4(w, z, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_4(w, w, p256_mod, p256_mp_mod);\n    while (n-- > 0) {\n        /* A = 3*(X^2 - W) */\n        sp_256_mont_sqr_4(t1, x, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(t1, t1, w, p256_mod);\n        sp_256_mont_tpl_4(a, t1, p256_mod);\n        /* B = X*Y^2 */\n        sp_256_mont_sqr_4(t2, y, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(b, t2, x, p256_mod, p256_mp_mod);\n        /* X = A^2 - 2B */\n        sp_256_mont_sqr_4(x, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_4(t1, b, p256_mod);\n        sp_256_mont_sub_4(x, x, t1, p256_mod);\n        /* Z = Z*Y */\n        sp_256_mont_mul_4(z, z, y, p256_mod, p256_mp_mod);\n        /* t2 = Y^4 */\n        sp_256_mont_sqr_4(t2, t2, p256_mod, p256_mp_mod);\n        if (n != 0) {\n            /* W = W*Y^4 */\n            sp_256_mont_mul_4(w, w, t2, p256_mod, p256_mp_mod);\n        }\n        /* y = 2*A*(B - X) - Y^4 */\n        sp_256_mont_sub_4(y, b, x, p256_mod);\n        sp_256_mont_mul_4(y, y, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_4(y, y, p256_mod);\n        sp_256_mont_sub_4(y, y, t2, p256_mod);\n    }\n    /* Y = Y/2 */\n    sp_256_div2_4(y, y, p256_mod);\n}\n\n/* Compare two numbers to determine if they are equal.\n * Constant time implementation.\n *\n * a  First number to compare.\n * b  Second number to compare.\n * returns 1 when equal and 0 otherwise.\n */\nstatic int sp_256_cmp_equal_4(const sp_digit* a, const sp_digit* b)\n{\n    return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3])) == 0;\n}\n\n/* Add two Montgomery form projective points.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_4(sp_point* r, const sp_point* p, const sp_point* q,\n        sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    sp_digit* t3 = t + 4*4;\n    sp_digit* t4 = t + 6*4;\n    sp_digit* t5 = t + 8*4;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Ensure only the first point is the same as the result. */\n    if (q == r) {\n        const sp_point* a = p;\n        p = q;\n        q = a;\n    }\n\n    /* Check double */\n    (void)sp_256_sub_4(t1, p256_mod, q->y);\n    sp_256_norm_4(t1);\n    if ((sp_256_cmp_equal_4(p->x, q->x) & sp_256_cmp_equal_4(p->z, q->z) &\n        (sp_256_cmp_equal_4(p->y, q->y) | sp_256_cmp_equal_4(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_4(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<4; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<4; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<4; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U1 = X1*Z2^2 */\n        sp_256_mont_sqr_4(t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t3, t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t1, t1, x, p256_mod, p256_mp_mod);\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_4(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S1 = Y1*Z2^3 */\n        sp_256_mont_mul_4(t3, t3, y, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_4(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - U1 */\n        sp_256_mont_sub_4(t2, t2, t1, p256_mod);\n        /* R = S2 - S1 */\n        sp_256_mont_sub_4(t4, t4, t3, p256_mod);\n        /* Z3 = H*Z1*Z2 */\n        sp_256_mont_mul_4(z, z, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*U1*H^2 */\n        sp_256_mont_sqr_4(x, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_4(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(y, t1, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(x, x, t5, p256_mod);\n        sp_256_mont_dbl_4(t1, y, p256_mod);\n        sp_256_mont_sub_4(x, x, t1, p256_mod);\n        /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */\n        sp_256_mont_sub_4(y, y, x, p256_mod);\n        sp_256_mont_mul_4(y, y, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t5, t5, t3, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(y, y, t5, p256_mod);\n    }\n}\n\n/* Double the Montgomery form projective point p a number of times.\n *\n * r  Result of repeated doubling of point.\n * p  Point to double.\n * n  Number of times to double\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_n_store_4(sp_point* r, const sp_point* p,\n        int n, int m, sp_digit* t)\n{\n    sp_digit* w = t;\n    sp_digit* a = t + 2*4;\n    sp_digit* b = t + 4*4;\n    sp_digit* t1 = t + 6*4;\n    sp_digit* t2 = t + 8*4;\n    sp_digit* x = r[2*m].x;\n    sp_digit* y = r[(1<<n)*m].y;\n    sp_digit* z = r[2*m].z;\n    int i;\n\n    for (i=0; i<4; i++) {\n        x[i] = p->x[i];\n    }\n    for (i=0; i<4; i++) {\n        y[i] = p->y[i];\n    }\n    for (i=0; i<4; i++) {\n        z[i] = p->z[i];\n    }\n\n    /* Y = 2*Y */\n    sp_256_mont_dbl_4(y, y, p256_mod);\n    /* W = Z^4 */\n    sp_256_mont_sqr_4(w, z, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_4(w, w, p256_mod, p256_mp_mod);\n    for (i=1; i<=n; i++) {\n        /* A = 3*(X^2 - W) */\n        sp_256_mont_sqr_4(t1, x, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(t1, t1, w, p256_mod);\n        sp_256_mont_tpl_4(a, t1, p256_mod);\n        /* B = X*Y^2 */\n        sp_256_mont_sqr_4(t2, y, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(b, t2, x, p256_mod, p256_mp_mod);\n        x = r[(1<<i)*m].x;\n        /* X = A^2 - 2B */\n        sp_256_mont_sqr_4(x, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_4(t1, b, p256_mod);\n        sp_256_mont_sub_4(x, x, t1, p256_mod);\n        /* Z = Z*Y */\n        sp_256_mont_mul_4(r[(1<<i)*m].z, z, y, p256_mod, p256_mp_mod);\n        z = r[(1<<i)*m].z;\n        /* t2 = Y^4 */\n        sp_256_mont_sqr_4(t2, t2, p256_mod, p256_mp_mod);\n        if (i != n) {\n            /* W = W*Y^4 */\n            sp_256_mont_mul_4(w, w, t2, p256_mod, p256_mp_mod);\n        }\n        /* y = 2*A*(B - X) - Y^4 */\n        sp_256_mont_sub_4(y, b, x, p256_mod);\n        sp_256_mont_mul_4(y, y, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_4(y, y, p256_mod);\n        sp_256_mont_sub_4(y, y, t2, p256_mod);\n\n        /* Y = Y/2 */\n        sp_256_div2_4(r[(1<<i)*m].y, y, p256_mod);\n        r[(1<<i)*m].infinity = 0;\n    }\n}\n\n/* Add two Montgomery form projective points.\n *\n * ra  Result of addition.\n * rs  Result of subtraction.\n * p   Frist point to add.\n * q   Second point to add.\n * t   Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_sub_4(sp_point* ra, sp_point* rs,\n        const sp_point* p, const sp_point* q, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    sp_digit* t3 = t + 4*4;\n    sp_digit* t4 = t + 6*4;\n    sp_digit* t5 = t + 8*4;\n    sp_digit* t6 = t + 10*4;\n    sp_digit* x = ra->x;\n    sp_digit* y = ra->y;\n    sp_digit* z = ra->z;\n    sp_digit* xs = rs->x;\n    sp_digit* ys = rs->y;\n    sp_digit* zs = rs->z;\n\n\n    XMEMCPY(x, p->x, sizeof(p->x) / 2);\n    XMEMCPY(y, p->y, sizeof(p->y) / 2);\n    XMEMCPY(z, p->z, sizeof(p->z) / 2);\n    ra->infinity = 0;\n    rs->infinity = 0;\n\n    /* U1 = X1*Z2^2 */\n    sp_256_mont_sqr_4(t1, q->z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t3, t1, q->z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t1, t1, x, p256_mod, p256_mp_mod);\n    /* U2 = X2*Z1^2 */\n    sp_256_mont_sqr_4(t2, z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t4, t2, z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t2, t2, q->x, p256_mod, p256_mp_mod);\n    /* S1 = Y1*Z2^3 */\n    sp_256_mont_mul_4(t3, t3, y, p256_mod, p256_mp_mod);\n    /* S2 = Y2*Z1^3 */\n    sp_256_mont_mul_4(t4, t4, q->y, p256_mod, p256_mp_mod);\n    /* H = U2 - U1 */\n    sp_256_mont_sub_4(t2, t2, t1, p256_mod);\n    /* RS = S2 + S1 */\n    sp_256_mont_add_4(t6, t4, t3, p256_mod);\n    /* R = S2 - S1 */\n    sp_256_mont_sub_4(t4, t4, t3, p256_mod);\n    /* Z3 = H*Z1*Z2 */\n    /* ZS = H*Z1*Z2 */\n    sp_256_mont_mul_4(z, z, q->z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(z, z, t2, p256_mod, p256_mp_mod);\n    XMEMCPY(zs, z, sizeof(p->z)/2);\n    /* X3 = R^2 - H^3 - 2*U1*H^2 */\n    /* XS = RS^2 - H^3 - 2*U1*H^2 */\n    sp_256_mont_sqr_4(x, t4, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_4(xs, t6, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_4(t5, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(y, t1, t5, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t5, t5, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_sub_4(x, x, t5, p256_mod);\n    sp_256_mont_sub_4(xs, xs, t5, p256_mod);\n    sp_256_mont_dbl_4(t1, y, p256_mod);\n    sp_256_mont_sub_4(x, x, t1, p256_mod);\n    sp_256_mont_sub_4(xs, xs, t1, p256_mod);\n    /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */\n    /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */\n    sp_256_mont_sub_4(ys, y, xs, p256_mod);\n    sp_256_mont_sub_4(y, y, x, p256_mod);\n    sp_256_mont_mul_4(y, y, t4, p256_mod, p256_mp_mod);\n    sp_256_sub_4(t6, p256_mod, t6);\n    sp_256_mont_mul_4(ys, ys, t6, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t5, t5, t3, p256_mod, p256_mp_mod);\n    sp_256_mont_sub_4(y, y, t5, p256_mod);\n    sp_256_mont_sub_4(ys, ys, t5, p256_mod);\n}\n\n/* Structure used to describe recoding of scalar multiplication. */\ntypedef struct ecc_recode {\n    /* Index into pre-computation table. */\n    uint8_t i;\n    /* Use the negative of the point. */\n    uint8_t neg;\n} ecc_recode;\n\n/* The index into pre-computation table to use. */\nstatic const uint8_t recode_index_4_6[66] = {\n     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n    32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,\n    16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,\n     0,  1,\n};\n\n/* Whether to negate y-ordinate. */\nstatic const uint8_t recode_neg_4_6[66] = {\n     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n     0,  0,\n};\n\n/* Recode the scalar for multiplication using pre-computed values and\n * subtraction.\n *\n * k  Scalar to multiply by.\n * v  Vector of operations to peform.\n */\nstatic void sp_256_ecc_recode_6_4(const sp_digit* k, ecc_recode* v)\n{\n    int i, j;\n    uint8_t y;\n    int carry = 0;\n    int o;\n    sp_digit n;\n\n    j = 0;\n    n = k[j];\n    o = 0;\n    for (i=0; i<43; i++) {\n        y = n;\n        if (o + 6 < 64) {\n            y &= 0x3f;\n            n >>= 6;\n            o += 6;\n        }\n        else if (o + 6 == 64) {\n            n >>= 6;\n            if (++j < 4)\n                n = k[j];\n            o = 0;\n        }\n        else if (++j < 4) {\n            n = k[j];\n            y |= (n << (64 - o)) & 0x3f;\n            o -= 58;\n            n >>= o;\n        }\n\n        y += carry;\n        v[i].i = recode_index_4_6[y];\n        v[i].neg = recode_neg_4_6[y];\n        carry = (y >> 6) + v[i].neg;\n    }\n}\n\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_win_add_sub_4(sp_point* r, const sp_point* g,\n        const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td[33];\n    sp_point rtd, pd;\n    sp_digit tmpd[2 * 4 * 6];\n#endif\n    sp_point* t;\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* tmp;\n    sp_digit* negy;\n    int i;\n    ecc_recode v[43];\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY)\n        err = sp_ecc_point_new(heap, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_point*)XMALLOC(sizeof(sp_point) * 33, heap, DYNAMIC_TYPE_ECC);\n    if (t == NULL)\n        err = MEMORY_E;\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 6, heap,\n                             DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n#else\n    t = td;\n    tmp = tmpd;\n#endif\n\n\n    if (err == MP_OKAY) {\n        /* t[0] = {0, 0, 1} * norm */\n        XMEMSET(&t[0], 0, sizeof(t[0]));\n        t[0].infinity = 1;\n        /* t[1] = {g->x, g->y, g->z} * norm */\n        err = sp_256_mod_mul_norm_4(t[1].x, g->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t[1].y, g->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t[1].z, g->z, p256_mod);\n    }\n\n    if (err == MP_OKAY) {\n        t[1].infinity = 0;\n        /* t[2] ... t[32]  */\n    sp_256_proj_point_dbl_n_store_4(t, &t[ 1], 5, 1, tmp);\n    sp_256_proj_point_add_4(&t[ 3], &t[ 2], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[ 6], &t[ 3], tmp);\n    sp_256_proj_point_add_sub_4(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[10], &t[ 5], tmp);\n    sp_256_proj_point_add_sub_4(&t[11], &t[ 9], &t[10], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[12], &t[ 6], tmp);\n    sp_256_proj_point_dbl_4(&t[14], &t[ 7], tmp);\n    sp_256_proj_point_add_sub_4(&t[15], &t[13], &t[14], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[18], &t[ 9], tmp);\n    sp_256_proj_point_add_sub_4(&t[19], &t[17], &t[18], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[20], &t[10], tmp);\n    sp_256_proj_point_dbl_4(&t[22], &t[11], tmp);\n    sp_256_proj_point_add_sub_4(&t[23], &t[21], &t[22], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[24], &t[12], tmp);\n    sp_256_proj_point_dbl_4(&t[26], &t[13], tmp);\n    sp_256_proj_point_add_sub_4(&t[27], &t[25], &t[26], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[28], &t[14], tmp);\n    sp_256_proj_point_dbl_4(&t[30], &t[15], tmp);\n    sp_256_proj_point_add_sub_4(&t[31], &t[29], &t[30], &t[ 1], tmp);\n\n        negy = t[0].y;\n\n        sp_256_ecc_recode_6_4(k, v);\n\n        i = 42;\n        XMEMCPY(rt, &t[v[i].i], sizeof(sp_point));\n        for (--i; i>=0; i--) {\n            sp_256_proj_point_dbl_n_4(rt, rt, 6, tmp);\n\n            XMEMCPY(p, &t[v[i].i], sizeof(sp_point));\n            sp_256_sub_4(negy, p256_mod, p->y);\n            sp_256_cond_copy_4(p->y, negy, (sp_digit)0 - v[i].neg);\n            sp_256_proj_point_add_4(rt, rt, p, tmp);\n        }\n\n        if (map != 0) {\n            sp_256_map_4(r, rt, tmp);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL)\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    if (tmp != NULL)\n        XFREE(tmp, heap, DYNAMIC_TYPE_ECC);\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n/* A table entry for pre-computed points. */\ntypedef struct sp_table_entry {\n    sp_digit x[4];\n    sp_digit y[4];\n} sp_table_entry;\n\n#if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL)\n#endif /* FP_ECC || WOLFSSL_SP_SMALL */\n/* Add two Montgomery form projective points. The second point has a q value of\n * one.\n * Only the first point can be the same pointer as the result point.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_qz1_4(sp_point* r, const sp_point* p,\n        const sp_point* q, sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    sp_digit* t3 = t + 4*4;\n    sp_digit* t4 = t + 6*4;\n    sp_digit* t5 = t + 8*4;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Check double */\n    (void)sp_256_sub_4(t1, p256_mod, q->y);\n    sp_256_norm_4(t1);\n    if ((sp_256_cmp_equal_4(p->x, q->x) & sp_256_cmp_equal_4(p->z, q->z) &\n        (sp_256_cmp_equal_4(p->y, q->y) | sp_256_cmp_equal_4(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_4(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<4; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<4; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<4; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_4(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_4(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - X1 */\n        sp_256_mont_sub_4(t2, t2, x, p256_mod);\n        /* R = S2 - Y1 */\n        sp_256_mont_sub_4(t4, t4, y, p256_mod);\n        /* Z3 = H*Z1 */\n        sp_256_mont_mul_4(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*X1*H^2 */\n        sp_256_mont_sqr_4(t1, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_4(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t3, x, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(x, t1, t5, p256_mod);\n        sp_256_mont_dbl_4(t1, t3, p256_mod);\n        sp_256_mont_sub_4(x, x, t1, p256_mod);\n        /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */\n        sp_256_mont_sub_4(t3, t3, x, p256_mod);\n        sp_256_mont_mul_4(t3, t3, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t5, t5, y, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(y, t3, t5, p256_mod);\n    }\n}\n\n#ifdef FP_ECC\n/* Convert the projective point to affine.\n * Ordinates are in Montgomery form.\n *\n * a  Point to convert.\n * t  Temprorary data.\n */\nstatic void sp_256_proj_to_affine_4(sp_point* a, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2 * 4;\n    sp_digit* tmp = t + 4 * 4;\n\n    sp_256_mont_inv_4(t1, a->z, tmp);\n\n    sp_256_mont_sqr_4(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    sp_256_mont_mul_4(a->x, a->x, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(a->y, a->y, t1, p256_mod, p256_mp_mod);\n    XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod));\n}\n\n/* Generate the pre-computed table of points for the base point.\n *\n * a      The base point.\n * table  Place to store generated point data.\n * tmp    Temprorary data.\n * heap  Heap to use for allocation.\n */\nstatic int sp_256_gen_stripe_table_4(const sp_point* a,\n        sp_table_entry* table, sp_digit* tmp, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td, s1d, s2d;\n#endif\n    sp_point* t;\n    sp_point* s1 = NULL;\n    sp_point* s2 = NULL;\n    int i, j;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, td, t);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s1d, s1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s2d, s2);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t->x, a->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t->y, a->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t->z, a->z, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        t->infinity = 0;\n        sp_256_proj_to_affine_4(t, tmp);\n\n        XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s1->infinity = 0;\n        XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s2->infinity = 0;\n\n        /* table[0] = {0, 0, infinity} */\n        XMEMSET(&table[0], 0, sizeof(sp_table_entry));\n        /* table[1] = Affine version of 'a' in Montgomery form */\n        XMEMCPY(table[1].x, t->x, sizeof(table->x));\n        XMEMCPY(table[1].y, t->y, sizeof(table->y));\n\n        for (i=1; i<8; i++) {\n            sp_256_proj_point_dbl_n_4(t, t, 32, tmp);\n            sp_256_proj_to_affine_4(t, tmp);\n            XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));\n            XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));\n        }\n\n        for (i=1; i<8; i++) {\n            XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));\n            XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));\n            for (j=(1<<i)+1; j<(1<<(i+1)); j++) {\n                XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));\n                XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));\n                sp_256_proj_point_add_qz1_4(t, s1, s2, tmp);\n                sp_256_proj_to_affine_4(t, tmp);\n                XMEMCPY(table[j].x, t->x, sizeof(table->x));\n                XMEMCPY(table[j].y, t->y, sizeof(table->y));\n            }\n        }\n    }\n\n    sp_ecc_point_free(s2, 0, heap);\n    sp_ecc_point_free(s1, 0, heap);\n    sp_ecc_point_free( t, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC */\n#if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL)\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_stripe_4(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit td[2 * 4 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* t;\n    int i, j;\n    int y, x;\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, heap,\n                           DYNAMIC_TYPE_ECC);\n    if (t == NULL) {\n        err = MEMORY_E;\n    }\n#else\n    t = td;\n#endif\n\n    if (err == MP_OKAY) {\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        y = 0;\n        for (j=0,x=31; j<8; j++,x+=32) {\n            y |= ((k[x / 64] >> (x % 64)) & 1) << j;\n        }\n        XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));\n        XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));\n        rt->infinity = !y;\n        for (i=30; i>=0; i--) {\n            y = 0;\n            for (j=0,x=i; j<8; j++,x+=32) {\n                y |= ((k[x / 64] >> (x % 64)) & 1) << j;\n            }\n\n            sp_256_proj_point_dbl_4(rt, rt, t);\n            XMEMCPY(p->x, table[y].x, sizeof(table[y].x));\n            XMEMCPY(p->y, table[y].y, sizeof(table[y].y));\n            p->infinity = !y;\n            sp_256_proj_point_add_qz1_4(rt, rt, p, t);\n        }\n\n        if (map != 0) {\n            sp_256_map_4(r, rt, t);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC || WOLFSSL_SP_SMALL */\n#ifdef FP_ECC\n#ifndef FP_ENTRIES\n    #define FP_ENTRIES 16\n#endif\n\ntypedef struct sp_cache_t {\n    sp_digit x[4];\n    sp_digit y[4];\n    sp_table_entry table[256];\n    uint32_t cnt;\n    int set;\n} sp_cache_t;\n\nstatic THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES];\nstatic THREAD_LS_T int sp_cache_last = -1;\nstatic THREAD_LS_T int sp_cache_inited = 0;\n\n#ifndef HAVE_THREAD_LS\n    static volatile int initCacheMutex = 0;\n    static wolfSSL_Mutex sp_cache_lock;\n#endif\n\nstatic void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache)\n{\n    int i, j;\n    uint32_t least;\n\n    if (sp_cache_inited == 0) {\n        for (i=0; i<FP_ENTRIES; i++) {\n            sp_cache[i].set = 0;\n        }\n        sp_cache_inited = 1;\n    }\n\n    /* Compare point with those in cache. */\n    for (i=0; i<FP_ENTRIES; i++) {\n        if (!sp_cache[i].set)\n            continue;\n\n        if (sp_256_cmp_equal_4(g->x, sp_cache[i].x) &\n                           sp_256_cmp_equal_4(g->y, sp_cache[i].y)) {\n            sp_cache[i].cnt++;\n            break;\n        }\n    }\n\n    /* No match. */\n    if (i == FP_ENTRIES) {\n        /* Find empty entry. */\n        i = (sp_cache_last + 1) % FP_ENTRIES;\n        for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) {\n            if (!sp_cache[i].set) {\n                break;\n            }\n        }\n\n        /* Evict least used. */\n        if (i == sp_cache_last) {\n            least = sp_cache[0].cnt;\n            for (j=1; j<FP_ENTRIES; j++) {\n                if (sp_cache[j].cnt < least) {\n                    i = j;\n                    least = sp_cache[i].cnt;\n                }\n            }\n        }\n\n        XMEMCPY(sp_cache[i].x, g->x, sizeof(sp_cache[i].x));\n        XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y));\n        sp_cache[i].set = 1;\n        sp_cache[i].cnt = 1;\n    }\n\n    *cache = &sp_cache[i];\n    sp_cache_last = i;\n}\n#endif /* FP_ECC */\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_4(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#ifndef FP_ECC\n    return sp_256_ecc_mulmod_win_add_sub_4(r, g, k, map, heap);\n#else\n    sp_digit tmp[2 * 4 * 5];\n    sp_cache_t* cache;\n    int err = MP_OKAY;\n\n#ifndef HAVE_THREAD_LS\n    if (initCacheMutex == 0) {\n         wc_InitMutex(&sp_cache_lock);\n         initCacheMutex = 1;\n    }\n    if (wc_LockMutex(&sp_cache_lock) != 0)\n       err = BAD_MUTEX_E;\n#endif /* HAVE_THREAD_LS */\n\n    if (err == MP_OKAY) {\n        sp_ecc_get_cache(g, &cache);\n        if (cache->cnt == 2)\n            sp_256_gen_stripe_table_4(g, cache->table, tmp, heap);\n\n#ifndef HAVE_THREAD_LS\n        wc_UnLockMutex(&sp_cache_lock);\n#endif /* HAVE_THREAD_LS */\n\n        if (cache->cnt < 2) {\n            err = sp_256_ecc_mulmod_win_add_sub_4(r, g, k, map, heap);\n        }\n        else {\n            err = sp_256_ecc_mulmod_stripe_4(r, g, cache->table, k,\n                    map, heap);\n        }\n    }\n\n    return err;\n#endif\n}\n\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * p     Point to multiply.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map,\n        void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[4];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 4, km);\n        sp_256_point_from_ecc_point_4(point, gm);\n\n            err = sp_256_ecc_mulmod_4(point, point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_4(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#ifdef WOLFSSL_SP_SMALL\nstatic const sp_table_entry p256_table[256] = {\n    /* 0 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 */\n    { { 0x79e730d418a9143cL,0x75ba95fc5fedb601L,0x79fb732b77622510L,\n        0x18905f76a53755c6L },\n      { 0xddf25357ce95560aL,0x8b4ab8e4ba19e45cL,0xd2e88688dd21f325L,\n        0x8571ff1825885d85L } },\n    /* 2 */\n    { { 0x202886024147519aL,0xd0981eac26b372f0L,0xa9d4a7caa785ebc8L,\n        0xd953c50ddbdf58e9L },\n      { 0x9d6361ccfd590f8fL,0x72e9626b44e6c917L,0x7fd9611022eb64cfL,\n        0x863ebb7e9eb288f3L } },\n    /* 3 */\n    { { 0x7856b6235cdb6485L,0x808f0ea22f0a2f97L,0x3e68d9544f7e300bL,\n        0x00076055b5ff80a0L },\n      { 0x7634eb9b838d2010L,0x54014fbb3243708aL,0xe0e47d39842a6606L,\n        0x8308776134373ee0L } },\n    /* 4 */\n    { { 0x4f922fc516a0d2bbL,0x0d5cc16c1a623499L,0x9241cf3a57c62c8bL,\n        0x2f5e6961fd1b667fL },\n      { 0x5c15c70bf5a01797L,0x3d20b44d60956192L,0x04911b37071fdb52L,\n        0xf648f9168d6f0f7bL } },\n    /* 5 */\n    { { 0x9e566847e137bbbcL,0xe434469e8a6a0becL,0xb1c4276179d73463L,\n        0x5abe0285133d0015L },\n      { 0x92aa837cc04c7dabL,0x573d9f4c43260c07L,0x0c93156278e6cc37L,\n        0x94bb725b6b6f7383L } },\n    /* 6 */\n    { { 0xbbf9b48f720f141cL,0x6199b3cd2df5bc74L,0xdc3f6129411045c4L,\n        0xcdd6bbcb2f7dc4efL },\n      { 0xcca6700beaf436fdL,0x6f647f6db99326beL,0x0c0fa792014f2522L,\n        0xa361bebd4bdae5f6L } },\n    /* 7 */\n    { { 0x28aa2558597c13c7L,0xc38d635f50b7c3e1L,0x07039aecf3c09d1dL,\n        0xba12ca09c4b5292cL },\n      { 0x9e408fa459f91dfdL,0x3af43b66ceea07fbL,0x1eceb0899d780b29L,\n        0x53ebb99d701fef4bL } },\n    /* 8 */\n    { { 0x4fe7ee31b0e63d34L,0xf4600572a9e54fabL,0xc0493334d5e7b5a4L,\n        0x8589fb9206d54831L },\n      { 0xaa70f5cc6583553aL,0x0879094ae25649e5L,0xcc90450710044652L,\n        0xebb0696d02541c4fL } },\n    /* 9 */\n    { { 0x4616ca15ac1647c5L,0xb8127d47c4cf5799L,0xdc666aa3764dfbacL,\n        0xeb2820cbd1b27da3L },\n      { 0x9406f8d86a87e008L,0xd87dfa9d922378f3L,0x56ed2e4280ccecb2L,\n        0x1f28289b55a7da1dL } },\n    /* 10 */\n    { { 0xabbaa0c03b89da99L,0xa6f2d79eb8284022L,0x27847862b81c05e8L,\n        0x337a4b5905e54d63L },\n      { 0x3c67500d21f7794aL,0x207005b77d6d7f61L,0x0a5a378104cfd6e8L,\n        0x0d65e0d5f4c2fbd6L } },\n    /* 11 */\n    { { 0xd9d09bbeb5275d38L,0x4268a7450be0a358L,0xf0762ff4973eb265L,\n        0xc23da24252f4a232L },\n      { 0x5da1b84f0b94520cL,0x09666763b05bd78eL,0x3a4dcb8694d29ea1L,\n        0x19de3b8cc790cff1L } },\n    /* 12 */\n    { { 0x183a716c26c5fe04L,0x3b28de0b3bba1bdbL,0x7432c586a4cb712cL,\n        0xe34dcbd491fccbfdL },\n      { 0xb408d46baaa58403L,0x9a69748682e97a53L,0x9e39012736aaa8afL,\n        0xe7641f447b4e0f7fL } },\n    /* 13 */\n    { { 0x7d753941df64ba59L,0xd33f10ec0b0242fcL,0x4f06dfc6a1581859L,\n        0x4a12df57052a57bfL },\n      { 0xbfa6338f9439dbd0L,0xd3c24bd4bde53e1fL,0xfd5e4ffa21f1b314L,\n        0x6af5aa93bb5bea46L } },\n    /* 14 */\n    { { 0xda10b69910c91999L,0x0a24b4402a580491L,0x3e0094b4b8cc2090L,\n        0x5fe3475a66a44013L },\n      { 0xb0f8cabdf93e7b4bL,0x292b501a7c23f91aL,0x42e889aecd1e6263L,\n        0xb544e308ecfea916L } },\n    /* 15 */\n    { { 0x6478c6e916ddfdceL,0x2c329166f89179e6L,0x4e8d6e764d4e67e1L,\n        0xe0b6b2bda6b0c20bL },\n      { 0x0d312df2bb7efb57L,0x1aac0dde790c4007L,0xf90336ad679bc944L,\n        0x71c023de25a63774L } },\n    /* 16 */\n    { { 0x62a8c244bfe20925L,0x91c19ac38fdce867L,0x5a96a5d5dd387063L,\n        0x61d587d421d324f6L },\n      { 0xe87673a2a37173eaL,0x2384800853778b65L,0x10f8441e05bab43eL,\n        0xfa11fe124621efbeL } },\n    /* 17 */\n    { { 0x1c891f2b2cb19ffdL,0x01ba8d5bb1923c23L,0xb6d03d678ac5ca8eL,\n        0x586eb04c1f13bedcL },\n      { 0x0c35c6e527e8ed09L,0x1e81a33c1819ede2L,0x278fd6c056c652faL,\n        0x19d5ac0870864f11L } },\n    /* 18 */\n    { { 0x1e99f581309a4e1fL,0xab7de71be9270074L,0x26a5ef0befd28d20L,\n        0xe7c0073f7f9c563fL },\n      { 0x1f6d663a0ef59f76L,0x669b3b5420fcb050L,0xc08c1f7a7a6602d4L,\n        0xe08504fec65b3c0aL } },\n    /* 19 */\n    { { 0xf098f68da031b3caL,0x6d1cab9ee6da6d66L,0x5bfd81fa94f246e8L,\n        0x78f018825b0996b4L },\n      { 0xb7eefde43a25787fL,0x8016f80d1dccac9bL,0x0cea4877b35bfc36L,\n        0x43a773b87e94747aL } },\n    /* 20 */\n    { { 0x62577734d2b533d5L,0x673b8af6a1bdddc0L,0x577e7c9aa79ec293L,\n        0xbb6de651c3b266b1L },\n      { 0xe7e9303ab65259b3L,0xd6a0afd3d03a7480L,0xc5ac83d19b3cfc27L,\n        0x60b4619a5d18b99bL } },\n    /* 21 */\n    { { 0xbd6a38e11ae5aa1cL,0xb8b7652b49e73658L,0x0b130014ee5f87edL,\n        0x9d0f27b2aeebffcdL },\n      { 0xca9246317a730a55L,0x9c955b2fddbbc83aL,0x07c1dfe0ac019a71L,\n        0x244a566d356ec48dL } },\n    /* 22 */\n    { { 0x6db0394aeacf1f96L,0x9f2122a9024c271cL,0x2626ac1b82cbd3b9L,\n        0x45e58c873581ef69L },\n      { 0xd3ff479da38f9dbcL,0xa8aaf146e888a040L,0x945adfb246e0bed7L,\n        0xc040e21cc1e4b7a4L } },\n    /* 23 */\n    { { 0x847af0006f8117b6L,0x651969ff73a35433L,0x482b35761d9475ebL,\n        0x1cdf5c97682c6ec7L },\n      { 0x7db775b411f04839L,0x7dbeacf448de1698L,0xb2921dd1b70b3219L,\n        0x046755f8a92dff3dL } },\n    /* 24 */\n    { { 0xcc8ac5d2bce8ffcdL,0x0d53c48b2fe61a82L,0xf6f161727202d6c7L,\n        0x046e5e113b83a5f3L },\n      { 0xe7b8ff64d8007f01L,0x7fb1ef125af43183L,0x045c5ea635e1a03cL,\n        0x6e0106c3303d005bL } },\n    /* 25 */\n    { { 0x48c7358488dd73b1L,0x7670708f995ed0d9L,0x38385ea8c56a2ab7L,\n        0x442594ede901cf1fL },\n      { 0xf8faa2c912d4b65bL,0x94c2343b96c90c37L,0xd326e4a15e978d1fL,\n        0xa796fa514c2ee68eL } },\n    /* 26 */\n    { { 0x359fb604823addd7L,0x9e2a6183e56693b3L,0xf885b78e3cbf3c80L,\n        0xe4ad2da9c69766e9L },\n      { 0x357f7f428e048a61L,0x082d198cc092d9a0L,0xfc3a1af4c03ed8efL,\n        0xc5e94046c37b5143L } },\n    /* 27 */\n    { { 0x476a538c2be75f9eL,0x6fd1a9e8cb123a78L,0xd85e4df0b109c04bL,\n        0x63283dafdb464747L },\n      { 0xce728cf7baf2df15L,0xe592c4550ad9a7f4L,0xfab226ade834bcc3L,\n        0x68bd19ab1981a938L } },\n    /* 28 */\n    { { 0xc08ead511887d659L,0x3374d5f4b359305aL,0x96986981cfe74fe3L,\n        0x495292f53c6fdfd6L },\n      { 0x4a878c9e1acec896L,0xd964b210ec5b4484L,0x6696f7e2664d60a7L,\n        0x0ec7530d26036837L } },\n    /* 29 */\n    { { 0x2da13a05ad2687bbL,0xa1f83b6af32e21faL,0x390f5ef51dd4607bL,\n        0x0f6207a664863f0bL },\n      { 0xbd67e3bb0f138233L,0xdd66b96c272aa718L,0x8ed0040726ec88aeL,\n        0xff0db07208ed6dcfL } },\n    /* 30 */\n    { { 0x749fa1014c95d553L,0xa44052fd5d680a8aL,0x183b4317ff3b566fL,\n        0x313b513c88740ea3L },\n      { 0xb402e2ac08d11549L,0x071ee10bb4dee21cL,0x26b987dd47f2320eL,\n        0x2d3abcf986f19f81L } },\n    /* 31 */\n    { { 0x4c288501815581a2L,0x9a0a6d56632211afL,0x19ba7a0f0cab2e99L,\n        0xc036fa10ded98cdfL },\n      { 0x29ae08bac1fbd009L,0x0b68b19006d15816L,0xc2eb32779b9e0d8fL,\n        0xa6b2a2c4b6d40194L } },\n    /* 32 */\n    { { 0xd433e50f6d3549cfL,0x6f33696ffacd665eL,0x695bfdacce11fcb4L,\n        0x810ee252af7c9860L },\n      { 0x65450fe17159bb2cL,0xf7dfbebe758b357bL,0x2b057e74d69fea72L,\n        0xd485717a92731745L } },\n    /* 33 */\n    { { 0x11741a8af0cb5a98L,0xd3da8f931f3110bfL,0x1994e2cbab382adfL,\n        0x6a6045a72f9a604eL },\n      { 0x170c0d3fa2b2411dL,0xbe0eb83e510e96e0L,0x3bcc9f738865b3ccL,\n        0xd3e45cfaf9e15790L } },\n    /* 34 */\n    { { 0xce1f69bbe83f7669L,0x09f8ae8272877d6bL,0x9548ae543244278dL,\n        0x207755dee3c2c19cL },\n      { 0x87bd61d96fef1945L,0x18813cefb12d28c3L,0x9fbcd1d672df64aaL,\n        0x48dc5ee57154b00dL } },\n    /* 35 */\n    { { 0x123790bff7e5a199L,0xe0efb8cf989ccbb7L,0xc27a2bfe0a519c79L,\n        0xf2fb0aeddff6f445L },\n      { 0x41c09575f0b5025fL,0x550543d740fa9f22L,0x8fa3c8ad380bfbd0L,\n        0xa13e9015db28d525L } },\n    /* 36 */\n    { { 0xf9f7a350a2b65cbcL,0x0b04b9722a464226L,0x265ce241e23f07a1L,\n        0x2bf0d6b01497526fL },\n      { 0xd3d4dd3f4b216fb7L,0xf7d7b867fbdda26aL,0xaeb7b83f6708505cL,\n        0x42a94a5a162fe89fL } },\n    /* 37 */\n    { { 0x5846ad0beaadf191L,0x0f8a489025a268d7L,0xe8603050494dc1f6L,\n        0x2c2dd969c65ede3dL },\n      { 0x6d02171d93849c17L,0x460488ba1da250ddL,0x4810c7063c3a5485L,\n        0xf437fa1f42c56dbcL } },\n    /* 38 */\n    { { 0x6aa0d7144a0f7dabL,0x0f0497931776e9acL,0x52c0a050f5f39786L,\n        0xaaf45b3354707aa8L },\n      { 0x85e37c33c18d364aL,0xd40b9b063e497165L,0xf417168115ec5444L,\n        0xcdf6310df4f272bcL } },\n    /* 39 */\n    { { 0x7473c6238ea8b7efL,0x08e9351885bc2287L,0x419567722bda8e34L,\n        0xf0d008bada9e2ff2L },\n      { 0x2912671d2414d3b1L,0xb3754985b019ea76L,0x5c61b96d453bcbdbL,\n        0x5bd5c2f5ca887b8bL } },\n    /* 40 */\n    { { 0xef0f469ef49a3154L,0x3e85a5956e2b2e9aL,0x45aaec1eaa924a9cL,\n        0xaa12dfc8a09e4719L },\n      { 0x26f272274df69f1dL,0xe0e4c82ca2ff5e73L,0xb9d8ce73b7a9dd44L,\n        0x6c036e73e48ca901L } },\n    /* 41 */\n    { { 0x5cfae12a0f6e3138L,0x6966ef0025ad345aL,0x8993c64b45672bc5L,\n        0x292ff65896afbe24L },\n      { 0xd5250d445e213402L,0xf6580e274392c9feL,0x097b397fda1c72e8L,\n        0x644e0c90311b7276L } },\n    /* 42 */\n    { { 0xe1e421e1a47153f0L,0xb86c3b79920418c9L,0x93bdce87705d7672L,\n        0xf25ae793cab79a77L },\n      { 0x1f3194a36d869d0cL,0x9d55c8824986c264L,0x49fb5ea3096e945eL,\n        0x39b8e65313db0a3eL } },\n    /* 43 */\n    { { 0x37754200b6fd2e59L,0x35e2c0669255c98fL,0xd9dab21a0e2a5739L,\n        0x39122f2f0f19db06L },\n      { 0xcfbce1e003cad53cL,0x225b2c0fe65c17e3L,0x72baf1d29aa13877L,\n        0x8de80af8ce80ff8dL } },\n    /* 44 */\n    { { 0xafbea8d9207bbb76L,0x921c7e7c21782758L,0xdfa2b74b1c0436b1L,\n        0x871949062e368c04L },\n      { 0xb5f928bba3993df5L,0x639d75b5f3b3d26aL,0x011aa78a85b55050L,\n        0xfc315e6a5b74fde1L } },\n    /* 45 */\n    { { 0x561fd41ae8d6ecfaL,0x5f8c44f61aec7f86L,0x98452a7b4924741dL,\n        0xe6d4a7adee389088L },\n      { 0x60552ed14593c75dL,0x70a70da4dd271162L,0xd2aede937ba2c7dbL,\n        0x35dfaf9a9be2ae57L } },\n    /* 46 */\n    { { 0x6b956fcdaa736636L,0x09f51d97ae2cab7eL,0xfb10bf410f349966L,\n        0x1da5c7d71c830d2bL },\n      { 0x5c41e4833cce6825L,0x15ad118ff9573c3bL,0xa28552c7f23036b8L,\n        0x7077c0fddbf4b9d6L } },\n    /* 47 */\n    { { 0xbf63ff8d46b9661cL,0xa1dfd36b0d2cfd71L,0x0373e140a847f8f7L,\n        0x53a8632ee50efe44L },\n      { 0x0976ff68696d8051L,0xdaec0c95c74f468aL,0x62994dc35e4e26bdL,\n        0x028ca76d34e1fcc1L } },\n    /* 48 */\n    { { 0xd11d47dcfc9877eeL,0xc8b36210801d0002L,0xd002c11754c260b6L,\n        0x04c17cd86962f046L },\n      { 0x6d9bd094b0daddf5L,0xbea2357524ce55c0L,0x663356e672da03b5L,\n        0xf7ba4de9fed97474L } },\n    /* 49 */\n    { { 0xd0dbfa34ebe1263fL,0x5576373571ae7ce6L,0xd244055382a6f523L,\n        0xe31f960052131c41L },\n      { 0xd1bb9216ea6b6ec6L,0x37a1d12e73c2fc44L,0xc10e7eac89d0a294L,\n        0xaa3a6259ce34d47bL } },\n    /* 50 */\n    { { 0xfbcf9df536f3dcd3L,0x6ceded50d2bf7360L,0x491710fadf504f5bL,\n        0x2398dd627e79daeeL },\n      { 0xcf4705a36d09569eL,0xea0619bb5149f769L,0xff9c037735f6034cL,\n        0x5717f5b21c046210L } },\n    /* 51 */\n    { { 0x9fe229c921dd895eL,0x8e51850040c28451L,0xfa13d2391d637ecdL,\n        0x660a2c560e3c28deL },\n      { 0x9cca88aed67fcbd0L,0xc84724780ea9f096L,0x32b2f48172e92b4dL,\n        0x624ee54c4f522453L } },\n    /* 52 */\n    { { 0x09549ce4d897ecccL,0x4d49d1d93f9880aaL,0x723c2423043a7c20L,\n        0x4f392afb92bdfbc0L },\n      { 0x6969f8fa7de44fd9L,0xb66cfbe457b32156L,0xdb2fa803368ebc3cL,\n        0x8a3e7977ccdb399cL } },\n    /* 53 */\n    { { 0xdde1881f06c4b125L,0xae34e300f6e3ca8cL,0xef6999de5c7a13e9L,\n        0x3888d02370c24404L },\n      { 0x7628035644f91081L,0x3d9fcf615f015504L,0x1827edc8632cd36eL,\n        0xa5e62e4718102336L } },\n    /* 54 */\n    { { 0x1a825ee32facd6c8L,0x699c635454bcbc66L,0x0ce3edf798df9931L,\n        0x2c4768e6466a5adcL },\n      { 0xb346ff8c90a64bc9L,0x630a6020e4779f5cL,0xd949d064bc05e884L,\n        0x7b5e6441f9e652a0L } },\n    /* 55 */\n    { { 0x2169422c1d28444aL,0xe996c5d8be136a39L,0x2387afe5fb0c7fceL,\n        0xb8af73cb0c8d744aL },\n      { 0x5fde83aa338b86fdL,0xfee3f158a58a5cffL,0xc9ee8f6f20ac9433L,\n        0xa036395f7f3f0895L } },\n    /* 56 */\n    { { 0x8c73c6bba10f7770L,0xa6f16d81a12a0e24L,0x100df68251bc2b9fL,\n        0x4be36b01875fb533L },\n      { 0x9226086e9fb56dbbL,0x306fef8b07e7a4f8L,0xeeaccc0566d52f20L,\n        0x8cbc9a871bdc00c0L } },\n    /* 57 */\n    { { 0xe131895cc0dac4abL,0xa874a440712ff112L,0x6332ae7c6a1cee57L,\n        0x44e7553e0c0835f8L },\n      { 0x6d503fff7734002dL,0x9d35cb8b0b34425cL,0x95f702760e8738b5L,\n        0x470a683a5eb8fc18L } },\n    /* 58 */\n    { { 0x81b761dc90513482L,0x0287202a01e9276aL,0xcda441ee0ce73083L,\n        0x16410690c63dc6efL },\n      { 0xf5034a066d06a2edL,0xdd4d7745189b100bL,0xd914ae72ab8218c9L,\n        0xd73479fd7abcbb4fL } },\n    /* 59 */\n    { { 0x7edefb165ad4c6e5L,0x262cf08f5b06d04dL,0x12ed5bb18575cb14L,\n        0x816469e30771666bL },\n      { 0xd7ab9d79561e291eL,0xeb9daf22c1de1661L,0xf49827eb135e0513L,\n        0x0a36dd23f0dd3f9cL } },\n    /* 60 */\n    { { 0x098d32c741d5533cL,0x7c5f5a9e8684628fL,0x39a228ade349bd11L,\n        0xe331dfd6fdbab118L },\n      { 0x5100ab686bcc6ed8L,0x7160c3bdef7a260eL,0x9063d9a7bce850d7L,\n        0xd3b4782a492e3389L } },\n    /* 61 */\n    { { 0xa149b6e8f3821f90L,0x92edd9ed66eb7aadL,0x0bb669531a013116L,\n        0x7281275a4c86a5bdL },\n      { 0x503858f7d3ff47e5L,0x5e1616bc61016441L,0x62b0f11a7dfd9bb1L,\n        0x2c062e7ece145059L } },\n    /* 62 */\n    { { 0xa76f996f0159ac2eL,0x281e7736cbdb2713L,0x2ad6d28808e46047L,\n        0x282a35f92c4e7ef1L },\n      { 0x9c354b1ec0ce5cd2L,0xcf99efc91379c229L,0x992caf383e82c11eL,\n        0xc71cd513554d2abdL } },\n    /* 63 */\n    { { 0x4885de9c09b578f4L,0x1884e258e3affa7aL,0x8f76b1b759182f1fL,\n        0xc50f6740cf47f3a3L },\n      { 0xa9c4adf3374b68eaL,0xa406f32369965fe2L,0x2f86a22285a53050L,\n        0xb9ecb3a7212958dcL } },\n    /* 64 */\n    { { 0x56f8410ef4f8b16aL,0x97241afec47b266aL,0x0a406b8e6d9c87c1L,\n        0x803f3e02cd42ab1bL },\n      { 0x7f0309a804dbec69L,0xa83b85f73bbad05fL,0xc6097273ad8e197fL,\n        0xc097440e5067adc1L } },\n    /* 65 */\n    { { 0x846a56f2c379ab34L,0xa8ee068b841df8d1L,0x20314459176c68efL,\n        0xf1af32d5915f1f30L },\n      { 0x99c375315d75bd50L,0x837cffbaf72f67bcL,0x0613a41848d7723fL,\n        0x23d0f130e2d41c8bL } },\n    /* 66 */\n    { { 0x857ab6edf41500d9L,0x0d890ae5fcbeada8L,0x52fe864889725951L,\n        0xb0288dd6c0a3faddL },\n      { 0x85320f30650bcb08L,0x71af6313695d6e16L,0x31f520a7b989aa76L,\n        0xffd3724ff408c8d2L } },\n    /* 67 */\n    { { 0x53968e64b458e6cbL,0x992dad20317a5d28L,0x3814ae0b7aa75f56L,\n        0xf5590f4ad78c26dfL },\n      { 0x0fc24bd3cf0ba55aL,0x0fc4724a0c778baeL,0x1ce9864f683b674aL,\n        0x18d6da54f6f74a20L } },\n    /* 68 */\n    { { 0xed93e225d5be5a2bL,0x6fe799835934f3c6L,0x4314092622626ffcL,\n        0x50bbb4d97990216aL },\n      { 0x378191c6e57ec63eL,0x65422c40181dcdb2L,0x41a8099b0236e0f6L,\n        0x2b10011801fe49c3L } },\n    /* 69 */\n    { { 0xfc68b5c59b391593L,0xc385f5a2598270fcL,0x7144f3aad19adcbbL,\n        0xdd55899983fbae0cL },\n      { 0x93b88b8e74b82ff4L,0xd2e03c4071e734c9L,0x9a7a9eaf43c0322aL,\n        0xe6e4c551149d6041L } },\n    /* 70 */\n    { { 0x55f655bb1e9af288L,0x647e1a64f7ada931L,0x43697e4bcb2820e5L,\n        0x51e00db107ed56ffL },\n      { 0x43d169b8771c327eL,0x29cdb20b4a96c2adL,0xc07d51f53deb4779L,\n        0xe22f424149829177L } },\n    /* 71 */\n    { { 0xcd45e8f4635f1abbL,0x7edc0cb568538874L,0xc9472c1fb5a8034dL,\n        0xf709373d52dc48c9L },\n      { 0x401966bba8af30d6L,0x95bf5f4af137b69cL,0x3966162a9361c47eL,\n        0xbd52d288e7275b11L } },\n    /* 72 */\n    { { 0xab155c7a9c5fa877L,0x17dad6727d3a3d48L,0x43f43f9e73d189d8L,\n        0xa0d0f8e4c8aa77a6L },\n      { 0x0bbeafd8cc94f92dL,0xd818c8be0c4ddb3aL,0x22cc65f8b82eba14L,\n        0xa56c78c7946d6a00L } },\n    /* 73 */\n    { { 0x2962391b0dd09529L,0x803e0ea63daddfcfL,0x2c77351f5b5bf481L,\n        0xd8befdf8731a367aL },\n      { 0xab919d42fc0157f4L,0xf51caed7fec8e650L,0xcdf9cb4002d48b0aL,\n        0x854a68a5ce9f6478L } },\n    /* 74 */\n    { { 0xdc35f67b63506ea5L,0x9286c489a4fe0d66L,0x3f101d3bfe95cd4dL,\n        0x5cacea0b98846a95L },\n      { 0xa90df60c9ceac44dL,0x3db29af4354d1c3aL,0x08dd3de8ad5dbabeL,\n        0xe4982d1235e4efa9L } },\n    /* 75 */\n    { { 0x23104a22c34cd55eL,0x58695bb32680d132L,0xfb345afa1fa1d943L,\n        0x8046b7f616b20499L },\n      { 0xb533581e38e7d098L,0xd7f61e8df46f0b70L,0x30dea9ea44cb78c4L,\n        0xeb17ca7b9082af55L } },\n    /* 76 */\n    { { 0x1751b59876a145b9L,0xa5cf6b0fc1bc71ecL,0xd3e03565392715bbL,\n        0x097b00bafab5e131L },\n      { 0xaa66c8e9565f69e1L,0x77e8f75ab5be5199L,0x6033ba11da4fd984L,\n        0xf95c747bafdbcc9eL } },\n    /* 77 */\n    { { 0x558f01d3bebae45eL,0xa8ebe9f0c4bc6955L,0xaeb705b1dbc64fc6L,\n        0x3512601e566ed837L },\n      { 0x9336f1e1fa1161cdL,0x328ab8d54c65ef87L,0x4757eee2724f21e5L,\n        0x0ef971236068ab6bL } },\n    /* 78 */\n    { { 0x02598cf754ca4226L,0x5eede138f8642c8eL,0x48963f74468e1790L,\n        0xfc16d9333b4fbc95L },\n      { 0xbe96fb31e7c800caL,0x138063312678adaaL,0x3d6244976ff3e8b5L,\n        0x14ca4af1b95d7a17L } },\n    /* 79 */\n    { { 0x7a4771babd2f81d5L,0x1a5f9d6901f7d196L,0xd898bef7cad9c907L,\n        0x4057b063f59c231dL },\n      { 0xbffd82fe89c05c0aL,0xe4911c6f1dc0df85L,0x3befccaea35a16dbL,\n        0x1c3b5d64f1330b13L } },\n    /* 80 */\n    { { 0x5fe14bfe80ec21feL,0xf6ce116ac255be82L,0x98bc5a072f4a5d67L,\n        0xfad27148db7e63afL },\n      { 0x90c0b6ac29ab05b3L,0x37a9a83c4e251ae6L,0x0a7dc875c2aade7dL,\n        0x77387de39f0e1a84L } },\n    /* 81 */\n    { { 0x1e9ecc49a56c0dd7L,0xa5cffcd846086c74L,0x8f7a1408f505aeceL,\n        0xb37b85c0bef0c47eL },\n      { 0x3596b6e4cc0e6a8fL,0xfd6d4bbf6b388f23L,0xaba453fac39cef4eL,\n        0x9c135ac8f9f628d5L } },\n    /* 82 */\n    { { 0x32aa320284e35743L,0x320d6ab185a3cdefL,0xb821b1761df19819L,\n        0x5721361fc433851fL },\n      { 0x1f0db36a71fc9168L,0x5f98ba735e5c403cL,0xf64ca87e37bcd8f5L,\n        0xdcbac3c9e6bb11bdL } },\n    /* 83 */\n    { { 0xf01d99684518cbe2L,0xd242fc189c9eb04eL,0x727663c7e47feebfL,\n        0xb8c1c89e2d626862L },\n      { 0x51a58bddc8e1d569L,0x563809c8b7d88cd0L,0x26c27fd9f11f31ebL,\n        0x5d23bbda2f9422d4L } },\n    /* 84 */\n    { { 0x0a1c729495c8f8beL,0x2961c4803bf362bfL,0x9e418403df63d4acL,\n        0xc109f9cb91ece900L },\n      { 0xc2d095d058945705L,0xb9083d96ddeb85c0L,0x84692b8d7a40449bL,\n        0x9bc3344f2eee1ee1L } },\n    /* 85 */\n    { { 0x0d5ae35642913074L,0x55491b2748a542b1L,0x469ca665b310732aL,\n        0x29591d525f1a4cc1L },\n      { 0xe76f5b6bb84f983fL,0xbe7eef419f5f84e1L,0x1200d49680baa189L,\n        0x6376551f18ef332cL } },\n    /* 86 */\n    { { 0xbda5f14e562976ccL,0x22bca3e60ef12c38L,0xbbfa30646cca9852L,\n        0xbdb79dc808e2987aL },\n      { 0xfd2cb5c9cb06a772L,0x38f475aafe536dceL,0xc2a3e0227c2b5db8L,\n        0x8ee86001add3c14aL } },\n    /* 87 */\n    { { 0xcbe96981a4ade873L,0x7ee9aa4dc4fba48cL,0x2cee28995a054ba5L,\n        0x92e51d7a6f77aa4bL },\n      { 0x948bafa87190a34dL,0xd698f75bf6bd1ed1L,0xd00ee6e30caf1144L,\n        0x5182f86f0a56aaaaL } },\n    /* 88 */\n    { { 0xfba6212c7a4cc99cL,0xff609b683e6d9ca1L,0x5dbb27cb5ac98c5aL,\n        0x91dcab5d4073a6f2L },\n      { 0x01b6cc3d5f575a70L,0x0cb361396f8d87faL,0x165d4e8c89981736L,\n        0x17a0cedb97974f2bL } },\n    /* 89 */\n    { { 0x38861e2a076c8d3aL,0x701aad39210f924bL,0x94d0eae413a835d9L,\n        0x2e8ce36c7f4cdf41L },\n      { 0x91273dab037a862bL,0x01ba9bb760e4c8faL,0xf964538833baf2ddL,\n        0xf4ccc6cb34f668f3L } },\n    /* 90 */\n    { { 0x44ef525cf1f79687L,0x7c59549592efa815L,0xe1231741a5c78d29L,\n        0xac0db4889a0df3c9L },\n      { 0x86bfc711df01747fL,0x592b9358ef17df13L,0xe5880e4f5ccb6bb5L,\n        0x95a64a6194c974a2L } },\n    /* 91 */\n    { { 0x72c1efdac15a4c93L,0x40269b7382585141L,0x6a8dfb1c16cb0badL,\n        0x231e54ba29210677L },\n      { 0xa70df9178ae6d2dcL,0x4d6aa63f39112918L,0xf627726b5e5b7223L,\n        0xab0be032d8a731e1L } },\n    /* 92 */\n    { { 0x097ad0e98d131f2dL,0x637f09e33b04f101L,0x1ac86196d5e9a748L,\n        0xf1bcc8802cf6a679L },\n      { 0x25c69140e8daacb4L,0x3c4e405560f65009L,0x591cc8fc477937a6L,\n        0x851694695aebb271L } },\n    /* 93 */\n    { { 0xde35c143f1dcf593L,0x78202b29b018be3bL,0xe9cdadc29bdd9d3dL,\n        0x8f67d9d2daad55d8L },\n      { 0x841116567481ea5fL,0xe7d2dde9e34c590cL,0xffdd43f405053fa8L,\n        0xf84572b9c0728b5dL } },\n    /* 94 */\n    { { 0x5e1a7a7197af71c9L,0xa14494447a736565L,0xa1b4ae070e1d5063L,\n        0xedee2710616b2c19L },\n      { 0xb2f034f511734121L,0x1cac6e554a25e9f0L,0x8dc148f3a40c2ecfL,\n        0x9fd27e9b44ebd7f4L } },\n    /* 95 */\n    { { 0x3cc7658af6e2cb16L,0xe3eb7d2cfe5919b6L,0x5a8c5816168d5583L,\n        0xa40c2fb6958ff387L },\n      { 0x8c9ec560fedcc158L,0x7ad804c655f23056L,0xd93967049a307e12L,\n        0x99bc9bb87dc6decfL } },\n    /* 96 */\n    { { 0x84a9521d927dafc6L,0x52c1fb695c09cd19L,0x9d9581a0f9366ddeL,\n        0x9abe210ba16d7e64L },\n      { 0x480af84a48915220L,0xfa73176a4dd816c6L,0xc7d539871681ca5aL,\n        0x7881c25787f344b0L } },\n    /* 97 */\n    { { 0x93399b51e0bcf3ffL,0x0d02cbc5127f74f6L,0x8fb465a2dd01d968L,\n        0x15e6e319a30e8940L },\n      { 0x646d6e0d3e0e05f4L,0xfad7bddc43588404L,0xbe61c7d1c4f850d3L,\n        0x0e55facf191172ceL } },\n    /* 98 */\n    { { 0x7e9d9806f8787564L,0x1a33172131e85ce6L,0x6b0158cab819e8d6L,\n        0xd73d09766fe96577L },\n      { 0x424834251eb7206eL,0xa519290fc618bb42L,0x5dcbb8595e30a520L,\n        0x9250a3748f15a50bL } },\n    /* 99 */\n    { { 0xcaff08f8be577410L,0xfd408a035077a8c6L,0xf1f63289ec0a63a4L,\n        0x77414082c1cc8c0bL },\n      { 0x05a40fa6eb0991cdL,0xc1ca086649fdc296L,0x3a68a3c7b324fd40L,\n        0x8cb04f4d12eb20b9L } },\n    /* 100 */\n    { { 0xb1c2d0556906171cL,0x9073e9cdb0240c3fL,0xdb8e6b4fd8906841L,\n        0xe4e429ef47123b51L },\n      { 0x0b8dd53c38ec36f4L,0xf9d2dc01ff4b6a27L,0x5d066e07879a9a48L,\n        0x37bca2ff3c6e6552L } },\n    /* 101 */\n    { { 0x4cd2e3c7df562470L,0x44f272a2c0964ac9L,0x7c6d5df980c793beL,\n        0x59913edc3002b22aL },\n      { 0x7a139a835750592aL,0x99e01d80e783de02L,0xcf8c0375ea05d64fL,\n        0x43786e4ab013e226L } },\n    /* 102 */\n    { { 0xff32b0ed9e56b5a6L,0x0750d9a6d9fc68f9L,0xec15e845597846a7L,\n        0x8638ca98b7e79e7aL },\n      { 0x2f5ae0960afc24b2L,0x05398eaf4dace8f2L,0x3b765dd0aecba78fL,\n        0x1ecdd36a7b3aa6f0L } },\n    /* 103 */\n    { { 0x5d3acd626c5ff2f3L,0xa2d516c02873a978L,0xad94c9fad2110d54L,\n        0xd85d0f85d459f32dL },\n      { 0x9f700b8d10b11da3L,0xd2c22c30a78318c4L,0x556988f49208decdL,\n        0xa04f19c3b4ed3c62L } },\n    /* 104 */\n    { { 0x087924c8ed7f93bdL,0xcb64ac5d392f51f6L,0x7cae330a821b71afL,\n        0x92b2eeea5c0950b0L },\n      { 0x85ac4c9485b6e235L,0xab2ca4a92936c0f0L,0x80faa6b3e0508891L,\n        0x1ee782215834276cL } },\n    /* 105 */\n    { { 0xa60a2e00e63e79f7L,0xf590e7b2f399d906L,0x9021054a6607c09dL,\n        0xf3f2ced857a6e150L },\n      { 0x200510f3f10d9b55L,0x9d2fcfacd8642648L,0xe5631aa7e8bd0e7cL,\n        0x0f56a4543da3e210L } },\n    /* 106 */\n    { { 0x5b21bffa1043e0dfL,0x6c74b6cc9c007e6dL,0x1a656ec0d4a8517aL,\n        0xbd8f17411969e263L },\n      { 0x8a9bbb86beb7494aL,0x1567d46f45f3b838L,0xdf7a12a7a4e5a79aL,\n        0x2d1a1c3530ccfa09L } },\n    /* 107 */\n    { { 0x192e3813506508daL,0x336180c4a1d795a7L,0xcddb59497a9944b3L,\n        0xa107a65eb91fba46L },\n      { 0xe6d1d1c50f94d639L,0x8b4af3758a58b7d7L,0x1a7c5584bd37ca1cL,\n        0x183d760af87a9af2L } },\n    /* 108 */\n    { { 0x29d697110dde59a4L,0xf1ad8d070e8bef87L,0x229b49634f2ebe78L,\n        0x1d44179dc269d754L },\n      { 0xb32dc0cf8390d30eL,0x0a3b27530de8110cL,0x31af1dc52bc0339aL,\n        0x771f9cc29606d262L } },\n    /* 109 */\n    { { 0x99993e7785040739L,0x44539db98026a939L,0xcf40f6f2f5f8fc26L,\n        0x64427a310362718eL },\n      { 0x4f4f2d8785428aa8L,0x7b7adc3febfb49a8L,0x201b2c6df23d01acL,\n        0x49d9b7496ae90d6dL } },\n    /* 110 */\n    { { 0xcc78d8bc435d1099L,0x2adbcd4e8e8d1a08L,0x02c2e2a02cb68a41L,\n        0x9037d81b3f605445L },\n      { 0x7cdbac27074c7b61L,0xfe2031ab57bfd72eL,0x61ccec96596d5352L,\n        0x08c3de6a7cc0639cL } },\n    /* 111 */\n    { { 0x20fdd020f6d552abL,0x56baff9805cd81f1L,0x06fb7c3e91351291L,\n        0xc690944245796b2fL },\n      { 0x17b3ae9c41231bd1L,0x1eac6e875cc58205L,0x208837abf9d6a122L,\n        0x3fa3db02cafe3ac0L } },\n    /* 112 */\n    { { 0xd75a3e6505058880L,0x7da365ef643943f2L,0x4147861cfab24925L,\n        0xc5c4bdb0fdb808ffL },\n      { 0x73513e34b272b56bL,0xc8327e9511b9043aL,0xfd8ce37df8844969L,\n        0x2d56db9446c2b6b5L } },\n    /* 113 */\n    { { 0x2461782fff46ac6bL,0xd19f792607a2e425L,0xfafea3c409a48de1L,\n        0x0f56bd9de503ba42L },\n      { 0x137d4ed1345cda49L,0x821158fc816f299dL,0xe7c6a54aaeb43402L,\n        0x4003bb9d1173b5f1L } },\n    /* 114 */\n    { { 0x3b8e8189a0803387L,0xece115f539cbd404L,0x4297208dd2877f21L,\n        0x53765522a07f2f9eL },\n      { 0xa4980a21a8a4182dL,0xa2bbd07a3219df79L,0x674d0a2e1a19a2d4L,\n        0x7a056f586c5d4549L } },\n    /* 115 */\n    { { 0x646b25589d8a2a47L,0x5b582948c3df2773L,0x51ec000eabf0d539L,\n        0x77d482f17a1a2675L },\n      { 0xb8a1bd9587853948L,0xa6f817bd6cfbffeeL,0xab6ec05780681e47L,\n        0x4115012b2b38b0e4L } },\n    /* 116 */\n    { { 0x3c73f0f46de28cedL,0x1d5da7609b13ec47L,0x61b8ce9e6e5c6392L,\n        0xcdf04572fbea0946L },\n      { 0x1cb3c58b6c53c3b0L,0x97fe3c10447b843cL,0xfb2b8ae12cb9780eL,\n        0xee703dda97383109L } },\n    /* 117 */\n    { { 0x34515140ff57e43aL,0xd44660d3b1b811b8L,0x2b3b5dff8f42b986L,\n        0x2a0ad89da162ce21L },\n      { 0x64e4a6946bc277baL,0xc788c954c141c276L,0x141aa64ccabf6274L,\n        0xd62d0b67ac2b4659L } },\n    /* 118 */\n    { { 0x39c5d87b2c054ac4L,0x57005859f27df788L,0xedf7cbf3b18128d6L,\n        0xb39a23f2991c2426L },\n      { 0x95284a15f0b16ae5L,0x0c6a05b1a136f51bL,0x1d63c137f2700783L,\n        0x04ed0092c0674cc5L } },\n    /* 119 */\n    { { 0x1f4185d19ae90393L,0x3047b4294a3d64e6L,0xae0001a69854fc14L,\n        0xa0a91fc10177c387L },\n      { 0xff0a3f01ae2c831eL,0xbb76ae822b727e16L,0x8f12c8a15a3075b4L,\n        0x084cf9889ed20c41L } },\n    /* 120 */\n    { { 0xd98509defca6becfL,0x2fceae807dffb328L,0x5d8a15c44778e8b9L,\n        0xd57955b273abf77eL },\n      { 0x210da79e31b5d4f1L,0xaa52f04b3cfa7a1cL,0xd4d12089dc27c20bL,\n        0x8e14ea4202d141f1L } },\n    /* 121 */\n    { { 0xeed50345f2897042L,0x8d05331f43402c4aL,0xc8d9c194c8bdfb21L,\n        0x597e1a372aa4d158L },\n      { 0x0327ec1acf0bd68cL,0x6d4be0dcab024945L,0x5b9c8d7ac9fe3e84L,\n        0xca3f0236199b4deaL } },\n    /* 122 */\n    { { 0x592a10b56170bd20L,0x0ea897f16d3f5de7L,0xa3363ff144b2ade2L,\n        0xbde7fd7e309c07e4L },\n      { 0x516bb6d2b8f5432cL,0x210dc1cbe043444bL,0x3db01e6ff8f95b5aL,\n        0xb623ad0e0a7dd198L } },\n    /* 123 */\n    { { 0xa75bd67560c7b65bL,0xab8c559023a4a289L,0xf8220fd0d7b26795L,\n        0xd6aa2e4658ec137bL },\n      { 0x10abc00b5138bb85L,0x8c31d121d833a95cL,0xb24ff00b1702a32eL,\n        0x111662e02dcc513aL } },\n    /* 124 */\n    { { 0x78114015efb42b87L,0xbd9f5d701b6c4dffL,0x66ecccd7a7d7c129L,\n        0xdb3ee1cb94b750f8L },\n      { 0xb26f3db0f34837cfL,0xe7eed18bb9578d4fL,0x5d2cdf937c56657dL,\n        0x886a644252206a59L } },\n    /* 125 */\n    { { 0x3c234cfb65b569eaL,0x20011141f72119c1L,0x8badc85da15a619eL,\n        0xa70cf4eb018a17bcL },\n      { 0x224f97ae8c4a6a65L,0x36e5cf270134378fL,0xbe3a609e4f7e0960L,\n        0xaa4772abd1747b77L } },\n    /* 126 */\n    { { 0x676761317aa60cc0L,0xc79163610368115fL,0xded98bb4bbc1bb5aL,\n        0x611a6ddc30faf974L },\n      { 0x30e78cbcc15ee47aL,0x2e8962824e0d96a5L,0x36f35adf3dd9ed88L,\n        0x5cfffaf816429c88L } },\n    /* 127 */\n    { { 0xc0d54cff9b7a99cdL,0x7bf3b99d843c45a1L,0x038a908f62c739e1L,\n        0x6e5a6b237dc1994cL },\n      { 0xef8b454e0ba5db77L,0xb7b8807facf60d63L,0xe591c0c676608378L,\n        0x481a238d242dabccL } },\n    /* 128 */\n    { { 0xe3417bc035d0b34aL,0x440b386b8327c0a7L,0x8fb7262dac0362d1L,\n        0x2c41114ce0cdf943L },\n      { 0x2ba5cef1ad95a0b1L,0xc09b37a867d54362L,0x26d6cdd201e486c9L,\n        0x20477abf42ff9297L } },\n    /* 129 */\n    { { 0x2f75173c18d65dbfL,0x77bf940e339edad8L,0x7022d26bdcf1001cL,\n        0xac66409ac77396b6L },\n      { 0x8b0bb36fc6261cc3L,0x213f7bc9190e7e90L,0x6541cebaa45e6c10L,\n        0xce8e6975cc122f85L } },\n    /* 130 */\n    { { 0x0f121b41bc0a67d2L,0x62d4760a444d248aL,0x0e044f1d659b4737L,\n        0x08fde365250bb4a8L },\n      { 0xaceec3da848bf287L,0xc2a62182d3369d6eL,0x3582dfdc92449482L,\n        0x2f7e2fd2565d6cd7L } },\n    /* 131 */\n    { { 0xae4b92dbc3770fa7L,0x095e8d5c379043f9L,0x54f34e9d17761171L,\n        0xc65be92e907702aeL },\n      { 0x2758a303f6fd0a40L,0xe7d822e3bcce784bL,0x7ae4f5854f9767bfL,\n        0x4bff8e47d1193b3aL } },\n    /* 132 */\n    { { 0xcd41d21f00ff1480L,0x2ab8fb7d0754db16L,0xac81d2efbbe0f3eaL,\n        0x3e4e4ae65772967dL },\n      { 0x7e18f36d3c5303e6L,0x3bd9994b92262397L,0x9ed70e261324c3c0L,\n        0x5388aefd58ec6028L } },\n    /* 133 */\n    { { 0xad1317eb5e5d7713L,0x09b985ee75de49daL,0x32f5bc4fc74fb261L,\n        0x5cf908d14f75be0eL },\n      { 0x760435108e657b12L,0xbfd421a5b96ed9e6L,0x0e29f51f8970ccc2L,\n        0xa698ba4060f00ce2L } },\n    /* 134 */\n    { { 0x73db1686ef748fecL,0xe6e755a27e9d2cf9L,0x630b6544ce265effL,\n        0xb142ef8a7aebad8dL },\n      { 0xad31af9f17d5770aL,0x66af3b672cb3412fL,0x6bd60d1bdf3359deL,\n        0xd1896a9658515075L } },\n    /* 135 */\n    { { 0xec5957ab33c41c08L,0x87de94ac5468e2e1L,0x18816b73ac472f6cL,\n        0x267b0e0b7981da39L },\n      { 0x6e554e5d8e62b988L,0xd8ddc755116d21e7L,0x4610faf03d2a6f99L,\n        0xb54e287aa1119393L } },\n    /* 136 */\n    { { 0x0a0122b5178a876bL,0x51ff96ff085104b4L,0x050b31ab14f29f76L,\n        0x84abb28b5f87d4e6L },\n      { 0xd5ed439f8270790aL,0x2d6cb59d85e3f46bL,0x75f55c1b6c1e2212L,\n        0xe5436f6717655640L } },\n    /* 137 */\n    { { 0x53f9025e2286e8d5L,0x353c95b4864453beL,0xd832f5bde408e3a0L,\n        0x0404f68b5b9ce99eL },\n      { 0xcad33bdea781e8e5L,0x3cdf5018163c2f5bL,0x575769600119caa3L,\n        0x3a4263df0ac1c701L } },\n    /* 138 */\n    { { 0xc2965ecc9aeb596dL,0x01ea03e7023c92b4L,0x4704b4b62e013961L,\n        0x0ca8fd3f905ea367L },\n      { 0x92523a42551b2b61L,0x1eb7a89c390fcd06L,0xe7f1d2be0392a63eL,\n        0x96dca2644ddb0c33L } },\n    /* 139 */\n    { { 0x203bb43a387510afL,0x846feaa8a9a36a01L,0xd23a57702f950378L,\n        0x4363e2123aad59dcL },\n      { 0xca43a1c740246a47L,0xb362b8d2e55dd24dL,0xf9b086045d8faf96L,\n        0x840e115cd8bb98c4L } },\n    /* 140 */\n    { { 0xf12205e21023e8a7L,0xc808a8cdd8dc7a0bL,0xe292a272163a5ddfL,\n        0x5e0d6abd30ded6d4L },\n      { 0x07a721c27cfc0f64L,0x42eec01d0e55ed88L,0x26a7bef91d1f9db2L,\n        0x7dea48f42945a25aL } },\n    /* 141 */\n    { { 0xabdf6f1ce5060a81L,0xe79f9c72f8f95615L,0xcfd36c5406ac268bL,\n        0xabc2a2beebfd16d1L },\n      { 0x8ac66f91d3e2eac7L,0x6f10ba63d2dd0466L,0x6790e3770282d31bL,\n        0x4ea353946c7eefc1L } },\n    /* 142 */\n    { { 0xed8a2f8d5266309dL,0x0a51c6c081945a3eL,0xcecaf45a578c5dc1L,\n        0x3a76e6891c94ffc3L },\n      { 0x9aace8a47d7b0d0fL,0x963ace968f584a5fL,0x51a30c724e697fbeL,\n        0x8212a10a465e6464L } },\n    /* 143 */\n    { { 0xef7c61c3cfab8caaL,0x18eb8e840e142390L,0xcd1dff677e9733caL,\n        0xaa7cab71599cb164L },\n      { 0x02fc9273bc837bd1L,0xc06407d0c36af5d7L,0x17621292f423da49L,\n        0x40e38073fe0617c3L } },\n    /* 144 */\n    { { 0xf4f80824a7bf9b7cL,0x365d23203fbe30d0L,0xbfbe532097cf9ce3L,\n        0xe3604700b3055526L },\n      { 0x4dcb99116cc6c2c7L,0x72683708ba4cbee6L,0xdcded434637ad9ecL,\n        0x6542d677a3dee15fL } },\n    /* 145 */\n    { { 0x3f32b6d07b6c377aL,0x6cb03847903448beL,0xd6fdd3a820da8af7L,\n        0xa6534aee09bb6f21L },\n      { 0x30a1780d1035facfL,0x35e55a339dcb47e6L,0x6ea50fe1c447f393L,\n        0xf3cb672fdc9aef22L } },\n    /* 146 */\n    { { 0xeb3719fe3b55fd83L,0xe0d7a46c875ddd10L,0x33ac9fa905cea784L,\n        0x7cafaa2eaae870e7L },\n      { 0x9b814d041d53b338L,0xe0acc0a0ef87e6c6L,0xfb93d10811672b0fL,\n        0x0aab13c1b9bd522eL } },\n    /* 147 */\n    { { 0xddcce278d2681297L,0xcb350eb1b509546aL,0x2dc431737661aaf2L,\n        0x4b91a602847012e9L },\n      { 0xdcff109572f8ddcfL,0x08ebf61e9a911af4L,0x48f4360ac372430eL,\n        0x49534c5372321cabL } },\n    /* 148 */\n    { { 0x83df7d71f07b7e9dL,0xa478efa313cd516fL,0x78ef264b6c047ee3L,\n        0xcaf46c4fd65ac5eeL },\n      { 0xa04d0c7792aa8266L,0xedf45466913684bbL,0x56e65168ae4b16b0L,\n        0x14ce9e5704c6770fL } },\n    /* 149 */\n    { { 0x99445e3e965e8f91L,0xd3aca1bacb0f2492L,0xd31cc70f90c8a0a0L,\n        0x1bb708a53e4c9a71L },\n      { 0xd5ca9e69558bdd7aL,0x734a0508018a26b1L,0xb093aa714c9cf1ecL,\n        0xf9d126f2da300102L } },\n    /* 150 */\n    { { 0x749bca7aaff9563eL,0xdd077afeb49914a0L,0xe27a0311bf5f1671L,\n        0x807afcb9729ecc69L },\n      { 0x7f8a9337c9b08b77L,0x86c3a785443c7e38L,0x85fafa59476fd8baL,\n        0x751adcd16568cd8cL } },\n    /* 151 */\n    { { 0x8aea38b410715c0dL,0xd113ea718f7697f7L,0x665eab1493fbf06dL,\n        0x29ec44682537743fL },\n      { 0x3d94719cb50bebbcL,0x399ee5bfe4505422L,0x90cd5b3a8d2dedb1L,\n        0xff9370e392a4077dL } },\n    /* 152 */\n    { { 0x59a2d69bc6b75b65L,0x4188f8d5266651c5L,0x28a9f33e3de9d7d2L,\n        0x9776478ba2a9d01aL },\n      { 0x8852622d929af2c7L,0x334f5d6d4e690923L,0xce6cc7e5a89a51e9L,\n        0x74a6313fac2f82faL } },\n    /* 153 */\n    { { 0xb2f4dfddb75f079cL,0x85b07c9518e36fbbL,0x1b6cfcf0e7cd36ddL,\n        0xab75be150ff4863dL },\n      { 0x81b367c0173fc9b7L,0xb90a7420d2594fd0L,0x15fdbf03c4091236L,\n        0x4ebeac2e0b4459f6L } },\n    /* 154 */\n    { { 0xeb6c5fe75c9f2c53L,0xd25220118eae9411L,0xc8887633f95ac5d8L,\n        0xdf99887b2c1baffcL },\n      { 0xbb78eed2850aaecbL,0x9d49181b01d6a272L,0x978dd511b1cdbcacL,\n        0x27b040a7779f4058L } },\n    /* 155 */\n    { { 0x90405db7f73b2eb2L,0xe0df85088e1b2118L,0x501b71525962327eL,\n        0xb393dd37e4cfa3f5L },\n      { 0xa1230e7b3fd75165L,0xd66344c2bcd33554L,0x6c36f1be0f7b5022L,\n        0x09588c12d0463419L } },\n    /* 156 */\n    { { 0xe086093f02601c3bL,0xfb0252f8cf5c335fL,0x955cf280894aff28L,\n        0x81c879a9db9f648bL },\n      { 0x040e687cc6f56c51L,0xfed471693f17618cL,0x44f88a419059353bL,\n        0xfa0d48f55fc11bc4L } },\n    /* 157 */\n    { { 0xbc6e1c9de1608e4dL,0x010dda113582822cL,0xf6b7ddc1157ec2d7L,\n        0x8ea0e156b6a367d6L },\n      { 0xa354e02f2383b3b4L,0x69966b943f01f53cL,0x4ff6632b2de03ca5L,\n        0x3f5ab924fa00b5acL } },\n    /* 158 */\n    { { 0x337bb0d959739efbL,0xc751b0f4e7ebec0dL,0x2da52dd6411a67d1L,\n        0x8bc768872b74256eL },\n      { 0xa5be3b7282d3d253L,0xa9f679a1f58d779fL,0xa1cac168e16767bbL,\n        0xb386f19060fcf34fL } },\n    /* 159 */\n    { { 0x31f3c1352fedcfc2L,0x5396bf6262f8af0dL,0x9a02b4eae57288c2L,\n        0x4cb460f71b069c4dL },\n      { 0xae67b4d35b8095eaL,0x92bbf8596fc07603L,0xe1475f66b614a165L,\n        0x52c0d50895ef5223L } },\n    /* 160 */\n    { { 0x231c210e15339848L,0xe87a28e870778c8dL,0x9d1de6616956e170L,\n        0x4ac3c9382bb09c0bL },\n      { 0x19be05516998987dL,0x8b2376c4ae09f4d6L,0x1de0b7651a3f933dL,\n        0x380d94c7e39705f4L } },\n    /* 161 */\n    { { 0x01a355aa81542e75L,0x96c724a1ee01b9b7L,0x6b3a2977624d7087L,\n        0x2ce3e171de2637afL },\n      { 0xcfefeb49f5d5bc1aL,0xa655607e2777e2b5L,0x4feaac2f9513756cL,\n        0x2e6cd8520b624e4dL } },\n    /* 162 */\n    { { 0x3685954b8c31c31dL,0x68533d005bf21a0cL,0x0bd7626e75c79ec9L,\n        0xca17754742c69d54L },\n      { 0xcc6edafff6d2dbb2L,0xfd0d8cbd174a9d18L,0x875e8793aa4578e8L,\n        0xa976a7139cab2ce6L } },\n    /* 163 */\n    { { 0x0a651f1b93fb353dL,0xd75cab8b57fcfa72L,0xaa88cfa731b15281L,\n        0x8720a7170a1f4999L },\n      { 0x8c3e8d37693e1b90L,0xd345dc0b16f6dfc3L,0x8ea8d00ab52a8742L,\n        0x9719ef29c769893cL } },\n    /* 164 */\n    { { 0x820eed8d58e35909L,0x9366d8dc33ddc116L,0xd7f999d06e205026L,\n        0xa5072976e15704c1L },\n      { 0x002a37eac4e70b2eL,0x84dcf6576890aa8aL,0xcd71bf18645b2a5cL,\n        0x99389c9df7b77725L } },\n    /* 165 */\n    { { 0x238c08f27ada7a4bL,0x3abe9d03fd389366L,0x6b672e89766f512cL,\n        0xa88806aa202c82e4L },\n      { 0x6602044ad380184eL,0xa8cb78c4126a8b85L,0x79d670c0ad844f17L,\n        0x0043bffb4738dcfeL } },\n    /* 166 */\n    { { 0x8d59b5dc36d5192eL,0xacf885d34590b2afL,0x83566d0a11601781L,\n        0x52f3ef01ba6c4866L },\n      { 0x3986732a0edcb64dL,0x0a482c238068379fL,0x16cbe5fa7040f309L,\n        0x3296bd899ef27e75L } },\n    /* 167 */\n    { { 0x476aba89454d81d7L,0x9eade7ef51eb9b3cL,0x619a21cd81c57986L,\n        0x3b90febfaee571e9L },\n      { 0x9393023e5496f7cbL,0x55be41d87fb51bc4L,0x03f1dd4899beb5ceL,\n        0x6e88069d9f810b18L } },\n    /* 168 */\n    { { 0xce37ab11b43ea1dbL,0x0a7ff1a95259d292L,0x851b02218f84f186L,\n        0xa7222beadefaad13L },\n      { 0xa2ac78ec2b0a9144L,0x5a024051f2fa59c5L,0x91d1eca56147ce38L,\n        0xbe94d523bc2ac690L } },\n    /* 169 */\n    { { 0x72f4945e0b226ce7L,0xb8afd747967e8b70L,0xedea46f185a6c63eL,\n        0x7782defe9be8c766L },\n      { 0x760d2aa43db38626L,0x460ae78776f67ad1L,0x341b86fc54499cdbL,\n        0x03838567a2892e4bL } },\n    /* 170 */\n    { { 0x2d8daefd79ec1a0fL,0x3bbcd6fdceb39c97L,0xf5575ffc58f61a95L,\n        0xdbd986c4adf7b420L },\n      { 0x81aa881415f39eb7L,0x6ee2fcf5b98d976cL,0x5465475dcf2f717dL,\n        0x8e24d3c46860bbd0L } },\n    /* 171 */\n    { { 0x749d8e549a587390L,0x12bb194f0cbec588L,0x46e07da4b25983c6L,\n        0x541a99c4407bafc8L },\n      { 0xdb241692624c8842L,0x6044c12ad86c05ffL,0xc59d14b44f7fcf62L,\n        0xc0092c49f57d35d1L } },\n    /* 172 */\n    { { 0xd3cc75c3df2e61efL,0x7e8841c82e1b35caL,0xc62d30d1909f29f4L,\n        0x75e406347286944dL },\n      { 0xe7d41fc5bbc237d0L,0xc9537bf0ec4f01c9L,0x91c51a16282bd534L,\n        0x5b7cb658c7848586L } },\n    /* 173 */\n    { { 0x964a70848a28ead1L,0x802dc508fd3b47f6L,0x9ae4bfd1767e5b39L,\n        0x7ae13eba8df097a1L },\n      { 0xfd216ef8eadd384eL,0x0361a2d9b6b2ff06L,0x204b98784bcdb5f3L,\n        0x787d8074e2a8e3fdL } },\n    /* 174 */\n    { { 0xc5e25d6b757fbb1cL,0xe47bddb2ca201debL,0x4a55e9a36d2233ffL,\n        0x5c2228199ef28484L },\n      { 0x773d4a8588315250L,0x21b21a2b827097c1L,0xab7c4ea1def5d33fL,\n        0xe45d37abbaf0f2b0L } },\n    /* 175 */\n    { { 0xd2df1e3428511c8aL,0xebb229c8bdca6cd3L,0x578a71a7627c39a7L,\n        0xed7bc12284dfb9d3L },\n      { 0xcf22a6df93dea561L,0x5443f18dd48f0ed1L,0xd8b861405bad23e8L,\n        0xaac97cc945ca6d27L } },\n    /* 176 */\n    { { 0xeb54ea74a16bd00aL,0xd839e9adf5c0bcc1L,0x092bb7f11f9bfc06L,\n        0x318f97b31163dc4eL },\n      { 0xecc0c5bec30d7138L,0x44e8df23abc30220L,0x2bb7972fb0223606L,\n        0xfa41faa19a84ff4dL } },\n    /* 177 */\n    { { 0x4402d974a6642269L,0xc81814ce9bb783bdL,0x398d38e47941e60bL,\n        0x38bb6b2c1d26e9e2L },\n      { 0xc64e4a256a577f87L,0x8b52d253dc11fe1cL,0xff336abf62280728L,\n        0x94dd0905ce7601a5L } },\n    /* 178 */\n    { { 0x156cf7dcde93f92aL,0xa01333cb89b5f315L,0x02404df9c995e750L,\n        0x92077867d25c2ae9L },\n      { 0xe2471e010bf39d44L,0x5f2c902096bb53d7L,0x4c44b7b35c9c3d8fL,\n        0x81e8428bd29beb51L } },\n    /* 179 */\n    { { 0x6dd9c2bac477199fL,0x8cb8eeee6b5ecdd9L,0x8af7db3fee40fd0eL,\n        0x1b94ab62dbbfa4b1L },\n      { 0x44f0d8b3ce47f143L,0x51e623fc63f46163L,0xf18f270fcc599383L,\n        0x06a38e28055590eeL } },\n    /* 180 */\n    { { 0x2e5b0139b3355b49L,0x20e26560b4ebf99bL,0xc08ffa6bd269f3dcL,\n        0xa7b36c2083d9d4f8L },\n      { 0x64d15c3a1b3e8830L,0xd5fceae1a89f9c0bL,0xcfeee4a2e2d16930L,\n        0xbe54c6b4a2822a20L } },\n    /* 181 */\n    { { 0xd6cdb3df8d91167cL,0x517c3f79e7a6625eL,0x7105648f346ac7f4L,\n        0xbf30a5abeae022bbL },\n      { 0x8e7785be93828a68L,0x5161c3327f3ef036L,0xe11b5feb592146b2L,\n        0xd1c820de2732d13aL } },\n    /* 182 */\n    { { 0x043e13479038b363L,0x58c11f546b05e519L,0x4fe57abe6026cad1L,\n        0xb7d17bed68a18da3L },\n      { 0x44ca5891e29c2559L,0x4f7a03765bfffd84L,0x498de4af74e46948L,\n        0x3997fd5e6412cc64L } },\n    /* 183 */\n    { { 0xf20746828bd61507L,0x29e132d534a64d2aL,0xffeddfb08a8a15e3L,\n        0x0eeb89293c6c13e8L },\n      { 0xe9b69a3ea7e259f8L,0xce1db7e6d13e7e67L,0x277318f6ad1fa685L,\n        0x228916f8c922b6efL } },\n    /* 184 */\n    { { 0x959ae25b0a12ab5bL,0xcc11171f957bc136L,0x8058429ed16e2b0cL,\n        0xec05ad1d6e93097eL },\n      { 0x157ba5beac3f3708L,0x31baf93530b59d77L,0x47b55237118234e5L,\n        0x7d3141567ff11b37L } },\n    /* 185 */\n    { { 0x7bd9c05cf6dfefabL,0xbe2f2268dcb37707L,0xe53ead973a38bb95L,\n        0xe9ce66fc9bc1d7a3L },\n      { 0x75aa15766f6a02a1L,0x38c087df60e600edL,0xf8947f3468cdc1b9L,\n        0xd9650b0172280651L } },\n    /* 186 */\n    { { 0x504b4c4a5a057e60L,0xcbccc3be8def25e4L,0xa635320817c1ccbdL,\n        0x14d6699a804eb7a2L },\n      { 0x2c8a8415db1f411aL,0x09fbaf0bf80d769cL,0xb4deef901c2f77adL,\n        0x6f4c68410d43598aL } },\n    /* 187 */\n    { { 0x8726df4e96c24a96L,0x534dbc85fcbd99a3L,0x3c466ef28b2ae30aL,\n        0x4c4350fd61189abbL },\n      { 0x2967f716f855b8daL,0x41a42394463c38a1L,0xc37e1413eae93343L,\n        0xa726d2425a3118b5L } },\n    /* 188 */\n    { { 0xdae6b3ee948c1086L,0xf1de503dcbd3a2e1L,0x3f35ed3f03d022f3L,\n        0x13639e82cc6cf392L },\n      { 0x9ac938fbcdafaa86L,0xf45bc5fb2654a258L,0x1963b26e45051329L,\n        0xca9365e1c1a335a3L } },\n    /* 189 */\n    { { 0x3615ac754c3b2d20L,0x742a5417904e241bL,0xb08521c4cc9d071dL,\n        0x9ce29c34970b72a5L },\n      { 0x8cc81f736d3e0ad6L,0x8060da9ef2f8434cL,0x35ed1d1a6ce862d9L,\n        0x48c4abd7ab42af98L } },\n    /* 190 */\n    { { 0xd221b0cc40c7485aL,0xead455bbe5274dbfL,0x493c76989263d2e8L,\n        0x78017c32f67b33cbL },\n      { 0xb9d35769930cb5eeL,0xc0d14e940c408ed2L,0xf8b7bf55272f1a4dL,\n        0x53cd0454de5c1c04L } },\n    /* 191 */\n    { { 0xbcd585fa5d28ccacL,0x5f823e56005b746eL,0x7c79f0a1cd0123aaL,\n        0xeea465c1d3d7fa8fL },\n      { 0x7810659f0551803bL,0x6c0b599f7ce6af70L,0x4195a77029288e70L,\n        0x1b6e42a47ae69193L } },\n    /* 192 */\n    { { 0x2e80937cf67d04c3L,0x1e312be289eeb811L,0x56b5d88792594d60L,\n        0x0224da14187fbd3dL },\n      { 0x87abb8630c5fe36fL,0x580f3c604ef51f5fL,0x964fb1bfb3b429ecL,\n        0x60838ef042bfff33L } },\n    /* 193 */\n    { { 0x432cb2f27e0bbe99L,0x7bda44f304aa39eeL,0x5f497c7a9fa93903L,\n        0x636eb2022d331643L },\n      { 0xfcfd0e6193ae00aaL,0x875a00fe31ae6d2fL,0xf43658a29f93901cL,\n        0x8844eeb639218bacL } },\n    /* 194 */\n    { { 0x114171d26b3bae58L,0x7db3df7117e39f3eL,0xcd37bc7f81a8eadaL,\n        0x27ba83dc51fb789eL },\n      { 0xa7df439ffbf54de5L,0x7277030bb5fe1a71L,0x42ee8e35db297a48L,\n        0xadb62d3487f3a4abL } },\n    /* 195 */\n    { { 0x9b1168a2a175df2aL,0x082aa04f618c32e9L,0xc9e4f2e7146b0916L,\n        0xb990fd7675e7c8b2L },\n      { 0x0829d96b4df37313L,0x1c205579d0b40789L,0x66c9ae4a78087711L,\n        0x81707ef94d10d18dL } },\n    /* 196 */\n    { { 0x97d7cab203d6ff96L,0x5b851bfc0d843360L,0x268823c4d042db4bL,\n        0x3792daead5a8aa5cL },\n      { 0x52818865941afa0bL,0xf3e9e74142d83671L,0x17c825275be4e0a7L,\n        0x5abd635e94b001baL } },\n    /* 197 */\n    { { 0x727fa84e0ac4927cL,0xe3886035a7c8cf23L,0xa4bcd5ea4adca0dfL,\n        0x5995bf21846ab610L },\n      { 0xe90f860b829dfa33L,0xcaafe2ae958fc18bL,0x9b3baf4478630366L,\n        0x44c32ca2d483411eL } },\n    /* 198 */\n    { { 0xa74a97f1e40ed80cL,0x5f938cb131d2ca82L,0x53f2124b7c2d6ad9L,\n        0x1f2162fb8082a54cL },\n      { 0x7e467cc5720b173eL,0x40e8a666085f12f9L,0x8cebc20e4c9d65dcL,\n        0x8f1d402bc3e907c9L } },\n    /* 199 */\n    { { 0x4f592f9cfbc4058aL,0xb15e14b6292f5670L,0xc55cfe37bc1d8c57L,\n        0xb1980f43926edbf9L },\n      { 0x98c33e0932c76b09L,0x1df5279d33b07f78L,0x6f08ead4863bb461L,\n        0x2828ad9b37448e45L } },\n    /* 200 */\n    { { 0x696722c4c4cf4ac5L,0xf5ac1a3fdde64afbL,0x0551baa2e0890832L,\n        0x4973f1275a14b390L },\n      { 0xe59d8335322eac5dL,0x5e07eef50bd9b568L,0xab36720fa2588393L,\n        0x6dac8ed0db168ac7L } },\n    /* 201 */\n    { { 0xf7b545aeeda835efL,0x4aa113d21d10ed51L,0x035a65e013741b09L,\n        0x4b23ef5920b9de4cL },\n      { 0xe82bb6803c4c7341L,0xd457706d3f58bc37L,0x73527863a51e3ee8L,\n        0x4dd71534ddf49a4eL } },\n    /* 202 */\n    { { 0xbf94467295476cd9L,0x648d072fe31a725bL,0x1441c8b8fc4b67e0L,\n        0xfd3170002f4a4dbbL },\n      { 0x1cb43ff48995d0e1L,0x76e695d10ef729aaL,0xe0d5f97641798982L,\n        0x14fac58c9569f365L } },\n    /* 203 */\n    { { 0xad9a0065f312ae18L,0x51958dc0fcc93fc9L,0xd9a142408a7d2846L,\n        0xed7c765136abda50L },\n      { 0x46270f1a25d4abbcL,0x9b5dd8f3f1a113eaL,0xc609b0755b51952fL,\n        0xfefcb7f74d2e9f53L } },\n    /* 204 */\n    { { 0xbd09497aba119185L,0xd54e8c30aac45ba4L,0x492479deaa521179L,\n        0x1801a57e87e0d80bL },\n      { 0x073d3f8dfcafffb0L,0x6cf33c0bae255240L,0x781d763b5b5fdfbcL,\n        0x9f8fc11e1ead1064L } },\n    /* 205 */\n    { { 0x1583a1715e69544cL,0x0eaf8567f04b7813L,0x1e22a8fd278a4c32L,\n        0xa9d3809d3d3a69a9L },\n      { 0x936c2c2c59a2da3bL,0x38ccbcf61895c847L,0x5e65244e63d50869L,\n        0x3006b9aee1178ef7L } },\n    /* 206 */\n    { { 0x0bb1f2b0c9eead28L,0x7eef635d89f4dfbcL,0x074757fdb2ce8939L,\n        0x0ab85fd745f8f761L },\n      { 0xecda7c933e5b4549L,0x4be2bb5c97922f21L,0x261a1274b43b8040L,\n        0xb122d67511e942c2L } },\n    /* 207 */\n    { { 0x3be607be66a5ae7aL,0x01e703fa76adcbe3L,0xaf9043014eb6e5c5L,\n        0x9f599dc1097dbaecL },\n      { 0x6d75b7180ff250edL,0x8eb91574349a20dcL,0x425605a410b227a3L,\n        0x7d5528e08a294b78L } },\n    /* 208 */\n    { { 0xf0f58f6620c26defL,0x025585ea582b2d1eL,0xfbe7d79b01ce3881L,\n        0x28ccea01303f1730L },\n      { 0xd1dabcd179644ba5L,0x1fc643e806fff0b8L,0xa60a76fc66b3e17bL,\n        0xc18baf48a1d013bfL } },\n    /* 209 */\n    { { 0x34e638c85dc4216dL,0x00c01067206142acL,0xd453a17195f5064aL,\n        0x9def809db7a9596bL },\n      { 0x41e8642e67ab8d2cL,0xb42404336237a2b6L,0x7d506a6d64c4218bL,\n        0x0357f8b068808ce5L } },\n    /* 210 */\n    { { 0x8e9dbe644cd2cc88L,0xcc61c28df0b8f39dL,0x4a309874cd30a0c8L,\n        0xe4a01add1b489887L },\n      { 0x2ed1eeacf57cd8f9L,0x1b767d3ebd594c48L,0xa7295c717bd2f787L,\n        0x466d7d79ce10cc30L } },\n    /* 211 */\n    { { 0x47d318929dada2c7L,0x4fa0a6c38f9aa27dL,0x90e4fd28820a59e1L,\n        0xc672a522451ead1aL },\n      { 0x30607cc85d86b655L,0xf0235d3bf9ad4af1L,0x99a08680571172a6L,\n        0x5e3d64faf2a67513L } },\n    /* 212 */\n    { { 0xaa6410c79b3b4416L,0xcd8fcf85eab26d99L,0x5ebff74adb656a74L,\n        0x6c8a7a95eb8e42fcL },\n      { 0x10c60ba7b02a63bdL,0x6b2f23038b8f0047L,0x8c6c3738312d90b0L,\n        0x348ae422ad82ca91L } },\n    /* 213 */\n    { { 0x7f4746635ccda2fbL,0x22accaa18e0726d2L,0x85adf782492b1f20L,\n        0xc1074de0d9ef2d2eL },\n      { 0xfcf3ce44ae9a65b3L,0xfd71e4ac05d7151bL,0xd4711f50ce6a9788L,\n        0xfbadfbdbc9e54ffcL } },\n    /* 214 */\n    { { 0x1713f1cd20a99363L,0xb915658f6cf22775L,0x968175cd24d359b2L,\n        0xb7f976b483716fcdL },\n      { 0x5758e24d5d6dbf74L,0x8d23bafd71c3af36L,0x48f477600243dfe3L,\n        0xf4d41b2ecafcc805L } },\n    /* 215 */\n    { { 0x51f1cf28fdabd48dL,0xce81be3632c078a4L,0x6ace2974117146e9L,\n        0x180824eae0160f10L },\n      { 0x0387698b66e58358L,0x63568752ce6ca358L,0x82380e345e41e6c5L,\n        0x67e5f63983cf6d25L } },\n    /* 216 */\n    { { 0xf89ccb8dcf4899efL,0x949015f09ebb44c0L,0x546f9276b2598ec9L,\n        0x9fef789a04c11fc6L },\n      { 0x6d367ecf53d2a071L,0xb10e1a7fa4519b09L,0xca6b3fb0611e2eefL,\n        0xbc80c181a99c4e20L } },\n    /* 217 */\n    { { 0x972536f8e5eb82e6L,0x1a484fc7f56cb920L,0xc78e217150b5da5eL,\n        0x49270e629f8cdf10L },\n      { 0x1a39b7bbea6b50adL,0x9a0284c1a2388ffcL,0x5403eb178107197bL,\n        0xd2ee52f961372f7fL } },\n    /* 218 */\n    { { 0xd37cd28588e0362aL,0x442fa8a78fa5d94dL,0xaff836e5a434a526L,\n        0xdfb478bee5abb733L },\n      { 0xa91f1ce7673eede6L,0xa5390ad42b5b2f04L,0x5e66f7bf5530da2fL,\n        0xd9a140b408df473aL } },\n    /* 219 */\n    { { 0x0e0221b56e8ea498L,0x623478293563ee09L,0xe06b8391335d2adeL,\n        0x760c058d623f4b1aL },\n      { 0x0b89b58cc198aa79L,0xf74890d2f07aba7fL,0x4e204110fde2556aL,\n        0x7141982d8f190409L } },\n    /* 220 */\n    { { 0x6f0a0e334d4b0f45L,0xd9280b38392a94e1L,0x3af324c6b3c61d5eL,\n        0x3af9d1ce89d54e47L },\n      { 0xfd8f798120930371L,0xeda2664c21c17097L,0x0e9545dcdc42309bL,\n        0xb1f815c373957dd6L } },\n    /* 221 */\n    { { 0x84faa78e89fec44aL,0xc8c2ae473caa4cafL,0x691c807dc1b6a624L,\n        0xa41aed141543f052L },\n      { 0x424353997d5ffe04L,0x8bacb2df625b6e20L,0x85d660be87817775L,\n        0xd6e9c1dd86fb60efL } },\n    /* 222 */\n    { { 0x3aa2e97ec6853264L,0x771533b7e2304a0bL,0x1b912bb7b8eae9beL,\n        0x9c9c6e10ae9bf8c2L },\n      { 0xa2309a59e030b74cL,0x4ed7494d6a631e90L,0x89f44b23a49b79f2L,\n        0x566bd59640fa61b6L } },\n    /* 223 */\n    { { 0x066c0118c18061f3L,0x190b25d37c83fc70L,0xf05fc8e027273245L,\n        0xcf2c7390f525345eL },\n      { 0xa09bceb410eb30cfL,0xcfd2ebba0d77703aL,0xe842c43a150ff255L,\n        0x02f517558aa20979L } },\n    /* 224 */\n    { { 0x396ef794addb7d07L,0x0b4fc74224455500L,0xfaff8eacc78aa3ceL,\n        0x14e9ada5e8d4d97dL },\n      { 0xdaa480a12f7079e2L,0x45baa3cde4b0800eL,0x01765e2d7838157dL,\n        0xa0ad4fab8e9d9ae8L } },\n    /* 225 */\n    { { 0x0bfb76214a653618L,0x1872813c31eaaa5fL,0x1553e73744949d5eL,\n        0xbcd530b86e56ed1eL },\n      { 0x169be85332e9c47bL,0xdc2776feb50059abL,0xcdba9761192bfbb4L,\n        0x909283cf6979341dL } },\n    /* 226 */\n    { { 0x67b0032476e81a13L,0x9bee1a9962171239L,0x08ed361bd32e19d6L,\n        0x35eeb7c9ace1549aL },\n      { 0x1280ae5a7e4e5bdcL,0x2dcd2cd3b6ceec6eL,0x52e4224c6e266bc1L,\n        0x9a8b2cf4448ae864L } },\n    /* 227 */\n    { { 0xf6471bf209d03b59L,0xc90e62a3b65af2abL,0xff7ff168ebd5eec9L,\n        0x6bdb60f4d4491379L },\n      { 0xdadafebc8a55bc30L,0xc79ead1610097fe0L,0x42e197414c1e3bddL,\n        0x01ec3cfd94ba08a9L } },\n    /* 228 */\n    { { 0xba6277ebdc9485c2L,0x48cc9a7922fb10c7L,0x4f61d60f70a28d8aL,\n        0xd1acb1c0475464f6L },\n      { 0xd26902b126f36612L,0x59c3a44ee0618d8bL,0x4df8a813308357eeL,\n        0x7dcd079d405626c2L } },\n    /* 229 */\n    { { 0x5ce7d4d3f05a4b48L,0xadcd295237230772L,0xd18f7971812a915aL,\n        0x0bf53589377d19b8L },\n      { 0x35ecd95a6c68ea73L,0xc7f3bbca823a584dL,0x9fb674c6f473a723L,\n        0xd28be4d9e16686fcL } },\n    /* 230 */\n    { { 0x5d2b990638fa8e4bL,0x559f186e893fd8fcL,0x3a6de2aa436fb6fcL,\n        0xd76007aa510f88ceL },\n      { 0x2d10aab6523a4988L,0xb455cf4474dd0273L,0x7f467082a3407278L,\n        0xf2b52f68b303bb01L } },\n    /* 231 */\n    { { 0x0d57eafa9835b4caL,0x2d2232fcbb669cbcL,0x8eeeb680c6643198L,\n        0xd8dbe98ecc5aed3aL },\n      { 0xcba9be3fc5a02709L,0x30be68e5f5ba1fa8L,0xfebd43cdf10ea852L,\n        0xe01593a3ee559705L } },\n    /* 232 */\n    { { 0xd3e5af50ea75a0a6L,0x512226ac57858033L,0x6fe6d50fd0176406L,\n        0xafec07b1aeb8ef06L },\n      { 0x7fb9956780bb0a31L,0x6f1af3cc37309aaeL,0x9153a15a01abf389L,\n        0xa71b93546e2dbfddL } },\n    /* 233 */\n    { { 0xbf8e12e018f593d2L,0xd1a90428a078122bL,0x150505db0ba4f2adL,\n        0x53a2005c628523d9L },\n      { 0x07c8b639e7f2b935L,0x2bff975ac182961aL,0x86bceea77518ca2cL,\n        0xbf47d19b3d588e3dL } },\n    /* 234 */\n    { { 0x672967a7dd7665d5L,0x4e3030572f2f4de5L,0x144005ae80d4903fL,\n        0x001c2c7f39c9a1b6L },\n      { 0x143a801469efc6d6L,0xc810bdaa7bc7a724L,0x5f65670ba78150a4L,\n        0xfdadf8e786ffb99bL } },\n    /* 235 */\n    { { 0xfd38cb88ffc00785L,0x77fa75913b48eb67L,0x0454d055bf368fbcL,\n        0x3a838e4d5aa43c94L },\n      { 0x561663293e97bb9aL,0x9eb93363441d94d9L,0x515591a60adb2a83L,\n        0x3cdb8257873e1da3L } },\n    /* 236 */\n    { { 0x137140a97de77eabL,0xf7e1c50d41648109L,0x762dcad2ceb1d0dfL,\n        0x5a60cc89f1f57fbaL },\n      { 0x80b3638240d45673L,0x1b82be195913c655L,0x057284b8dd64b741L,\n        0x922ff56fdbfd8fc0L } },\n    /* 237 */\n    { { 0x1b265deec9a129a1L,0xa5b1ce57cc284e04L,0x04380c46cebfbe3cL,\n        0x72919a7df6c5cd62L },\n      { 0x298f453a8fb90f9aL,0xd719c00b88e4031bL,0xe32c0e77796f1856L,\n        0x5e7917803624089aL } },\n    /* 238 */\n    { { 0x5c16ec557f63cdfbL,0x8e6a3571f1cae4fdL,0xfce26bea560597caL,\n        0x4e0a5371e24c2fabL },\n      { 0x276a40d3a5765357L,0x3c89af440d73a2b4L,0xb8f370ae41d11a32L,\n        0xf5ff7818d56604eeL } },\n    /* 239 */\n    { { 0xfbf3e3fe1a09df21L,0x26d5d28ee66e8e47L,0x2096bd0a29c89015L,\n        0xe41df0e9533f5e64L },\n      { 0x305fda40b3ba9e3fL,0xf2340ceb2604d895L,0x0866e1927f0367c7L,\n        0x8edd7d6eac4f155fL } },\n    /* 240 */\n    { { 0xc9a1dc0e0bfc8ff3L,0x14efd82be936f42fL,0x67016f7ccca381efL,\n        0x1432c1caed8aee96L },\n      { 0xec68482970b23c26L,0xa64fe8730735b273L,0xe389f6e5eaef0f5aL,\n        0xcaef480b5ac8d2c6L } },\n    /* 241 */\n    { { 0x5245c97875315922L,0xd82951713063cca5L,0xf3ce60d0b64ef2cbL,\n        0xd0ba177e8efae236L },\n      { 0x53a9ae8fb1b3af60L,0x1a796ae53d2da20eL,0x01d63605df9eef28L,\n        0xf31c957c1c54ae16L } },\n    /* 242 */\n    { { 0xc0f58d5249cc4597L,0xdc5015b0bae0a028L,0xefc5fc55734a814aL,\n        0x013404cb96e17c3aL },\n      { 0xb29e2585c9a824bfL,0xd593185e001eaed7L,0x8d6ee68261ef68acL,\n        0x6f377c4b91933e6cL } },\n    /* 243 */\n    { { 0x9f93bad1a8333fd2L,0xa89302025a2a95b8L,0x211e5037eaf75aceL,\n        0x6dba3e4ed2d09506L },\n      { 0xa48ef98cd04399cdL,0x1811c66ee6b73adeL,0x72f60752c17ecaf3L,\n        0xf13cf3423becf4a7L } },\n    /* 244 */\n    { { 0xceeb9ec0a919e2ebL,0x83a9a195f62c0f68L,0xcfba3bb67aba2299L,\n        0xc83fa9a9274bbad3L },\n      { 0x0d7d1b0b62fa1ce0L,0xe58b60f53418efbfL,0xbfa8ef9e52706f04L,\n        0xb49d70f45d702683L } },\n    /* 245 */\n    { { 0x914c7510fad5513bL,0x05f32eecb1751e2dL,0x6d850418d9fb9d59L,\n        0x59cfadbb0c30f1cfL },\n      { 0xe167ac2355cb7fd6L,0x249367b8820426a3L,0xeaeec58c90a78864L,\n        0x5babf362354a4b67L } },\n    /* 246 */\n    { { 0x37c981d1ee424865L,0x8b002878f2e5577fL,0x702970f1b9e0c058L,\n        0x6188c6a79026c8f0L },\n      { 0x06f9a19bd0f244daL,0x1ecced5cfb080873L,0x35470f9b9f213637L,\n        0x993fe475df50b9d9L } },\n    /* 247 */\n    { { 0x68e31cdf9b2c3609L,0x84eb19c02c46d4eaL,0x7ac9ec1a9a775101L,\n        0x81f764664c80616bL },\n      { 0x1d7c2a5a75fbe978L,0x6743fed3f183b356L,0x838d1f04501dd2bfL,\n        0x564a812a5fe9060dL } },\n    /* 248 */\n    { { 0x7a5a64f4fa817d1dL,0x55f96844bea82e0fL,0xb5ff5a0fcd57f9aaL,\n        0x226bf3cf00e51d6cL },\n      { 0xd6d1a9f92f2833cfL,0x20a0a35a4f4f89a8L,0x11536c498f3f7f77L,\n        0x68779f47ff257836L } },\n    /* 249 */\n    { { 0x79b0c1c173043d08L,0xa54467741fc020faL,0xd3767e289a6d26d0L,\n        0x97bcb0d1eb092e0bL },\n      { 0x2ab6eaa8f32ed3c3L,0xc8a4f151b281bc48L,0x4d1bf4f3bfa178f3L,\n        0xa872ffe80a784655L } },\n    /* 250 */\n    { { 0xb1ab7935a32b2086L,0xe1eb710e8160f486L,0x9bd0cd913b6ae6beL,\n        0x02812bfcb732a36aL },\n      { 0xa63fd7cacf605318L,0x646e5d50fdfd6d1dL,0xa1d683982102d619L,\n        0x07391cc9fe5396afL } },\n    /* 251 */\n    { { 0xc50157f08b80d02bL,0x6b8333d162877f7fL,0x7aca1af878d542aeL,\n        0x355d2adc7e6d2a08L },\n      { 0xb41f335a287386e1L,0xfd272a94f8e43275L,0x286ca2cde79989eaL,\n        0x3dc2b1e37c2a3a79L } },\n    /* 252 */\n    { { 0xd689d21c04581352L,0x0a00c825376782beL,0x203bd5909fed701fL,\n        0xc47869103ccd846bL },\n      { 0x5dba770824c768edL,0x72feea026841f657L,0x73313ed56accce0eL,\n        0xccc42968d5bb4d32L } },\n    /* 253 */\n    { { 0x94e50de13d7620b9L,0xd89a5c8a5992a56aL,0xdc007640675487c9L,\n        0xe147eb42aa4871cfL },\n      { 0x274ab4eeacf3ae46L,0xfd4936fb50350fbeL,0xdf2afe4748c840eaL,\n        0x239ac047080e96e3L } },\n    /* 254 */\n    { { 0x481d1f352bfee8d4L,0xce80b5cffa7b0fecL,0x105c4c9e2ce9af3cL,\n        0xc55fa1a3f5f7e59dL },\n      { 0x3186f14e8257c227L,0xc5b1653f342be00bL,0x09afc998aa904fb2L,\n        0x094cd99cd4f4b699L } },\n    /* 255 */\n    { { 0x8a981c84d703bebaL,0x8631d15032ceb291L,0xa445f2c9e3bd49ecL,\n        0xb90a30b642abad33L },\n      { 0xb465404fb4a5abf9L,0x004750c375db7603L,0x6f9a42ccca35d89fL,\n        0x019f8b9a1b7924f7L } },\n};\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_4(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_stripe_4(r, &p256_base, p256_table,\n                                      k, map, heap);\n}\n\n#else\n/* The index into pre-computation table to use. */\nstatic const uint8_t recode_index_4_7[130] = {\n     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\n    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\n    64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,\n    48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,\n    32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,\n    16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,\n     0,  1,\n};\n\n/* Whether to negate y-ordinate. */\nstatic const uint8_t recode_neg_4_7[130] = {\n     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n     0,  0,\n};\n\n/* Recode the scalar for multiplication using pre-computed values and\n * subtraction.\n *\n * k  Scalar to multiply by.\n * v  Vector of operations to peform.\n */\nstatic void sp_256_ecc_recode_7_4(const sp_digit* k, ecc_recode* v)\n{\n    int i, j;\n    uint8_t y;\n    int carry = 0;\n    int o;\n    sp_digit n;\n\n    j = 0;\n    n = k[j];\n    o = 0;\n    for (i=0; i<37; i++) {\n        y = n;\n        if (o + 7 < 64) {\n            y &= 0x7f;\n            n >>= 7;\n            o += 7;\n        }\n        else if (o + 7 == 64) {\n            n >>= 7;\n            if (++j < 4)\n                n = k[j];\n            o = 0;\n        }\n        else if (++j < 4) {\n            n = k[j];\n            y |= (n << (64 - o)) & 0x7f;\n            o -= 57;\n            n >>= o;\n        }\n\n        y += carry;\n        v[i].i = recode_index_4_7[y];\n        v[i].neg = recode_neg_4_7[y];\n        carry = (y >> 7) + v[i].neg;\n    }\n}\n\nstatic const sp_table_entry p256_table[2405] = {\n    /* 0 << 0 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 0 */\n    { { 0x79e730d418a9143cL,0x75ba95fc5fedb601L,0x79fb732b77622510L,\n        0x18905f76a53755c6L },\n      { 0xddf25357ce95560aL,0x8b4ab8e4ba19e45cL,0xd2e88688dd21f325L,\n        0x8571ff1825885d85L } },\n    /* 2 << 0 */\n    { { 0x850046d410ddd64dL,0xaa6ae3c1a433827dL,0x732205038d1490d9L,\n        0xf6bb32e43dcf3a3bL },\n      { 0x2f3648d361bee1a5L,0x152cd7cbeb236ff8L,0x19a8fb0e92042dbeL,\n        0x78c577510a5b8a3bL } },\n    /* 3 << 0 */\n    { { 0xffac3f904eebc127L,0xb027f84a087d81fbL,0x66ad77dd87cbbc98L,\n        0x26936a3fb6ff747eL },\n      { 0xb04c5c1fc983a7ebL,0x583e47ad0861fe1aL,0x788208311a2ee98eL,\n        0xd5f06a29e587cc07L } },\n    /* 4 << 0 */\n    { { 0x74b0b50d46918dccL,0x4650a6edc623c173L,0x0cdaacace8100af2L,\n        0x577362f541b0176bL },\n      { 0x2d96f24ce4cbaba6L,0x17628471fad6f447L,0x6b6c36dee5ddd22eL,\n        0x84b14c394c5ab863L } },\n    /* 5 << 0 */\n    { { 0xbe1b8aaec45c61f5L,0x90ec649a94b9537dL,0x941cb5aad076c20cL,\n        0xc9079605890523c8L },\n      { 0xeb309b4ae7ba4f10L,0x73c568efe5eb882bL,0x3540a9877e7a1f68L,\n        0x73a076bb2dd1e916L } },\n    /* 6 << 0 */\n    { { 0x403947373e77664aL,0x55ae744f346cee3eL,0xd50a961a5b17a3adL,\n        0x13074b5954213673L },\n      { 0x93d36220d377e44bL,0x299c2b53adff14b5L,0xf424d44cef639f11L,\n        0xa4c9916d4a07f75fL } },\n    /* 7 << 0 */\n    { { 0x0746354ea0173b4fL,0x2bd20213d23c00f7L,0xf43eaab50c23bb08L,\n        0x13ba5119c3123e03L },\n      { 0x2847d0303f5b9d4dL,0x6742f2f25da67bddL,0xef933bdc77c94195L,\n        0xeaedd9156e240867L } },\n    /* 8 << 0 */\n    { { 0x27f14cd19499a78fL,0x462ab5c56f9b3455L,0x8f90f02af02cfc6bL,\n        0xb763891eb265230dL },\n      { 0xf59da3a9532d4977L,0x21e3327dcf9eba15L,0x123c7b84be60bbf0L,\n        0x56ec12f27706df76L } },\n    /* 9 << 0 */\n    { { 0x75c96e8f264e20e8L,0xabe6bfed59a7a841L,0x2cc09c0444c8eb00L,\n        0xe05b3080f0c4e16bL },\n      { 0x1eb7777aa45f3314L,0x56af7bedce5d45e3L,0x2b6e019a88b12f1aL,\n        0x086659cdfd835f9bL } },\n    /* 10 << 0 */\n    { { 0x2c18dbd19dc21ec8L,0x98f9868a0fcf8139L,0x737d2cd648250b49L,\n        0xcc61c94724b3428fL },\n      { 0x0c2b407880dd9e76L,0xc43a8991383fbe08L,0x5f7d2d65779be5d2L,\n        0x78719a54eb3b4ab5L } },\n    /* 11 << 0 */\n    { { 0xea7d260a6245e404L,0x9de407956e7fdfe0L,0x1ff3a4158dac1ab5L,\n        0x3e7090f1649c9073L },\n      { 0x1a7685612b944e88L,0x250f939ee57f61c8L,0x0c0daa891ead643dL,\n        0x68930023e125b88eL } },\n    /* 12 << 0 */\n    { { 0x04b71aa7d2697768L,0xabdedef5ca345a33L,0x2409d29dee37385eL,\n        0x4ee1df77cb83e156L },\n      { 0x0cac12d91cbb5b43L,0x170ed2f6ca895637L,0x28228cfa8ade6d66L,\n        0x7ff57c9553238acaL } },\n    /* 13 << 0 */\n    { { 0xccc425634b2ed709L,0x0e356769856fd30dL,0xbcbcd43f559e9811L,\n        0x738477ac5395b759L },\n      { 0x35752b90c00ee17fL,0x68748390742ed2e3L,0x7cd06422bd1f5bc1L,\n        0xfbc08769c9e7b797L } },\n    /* 14 << 0 */\n    { { 0xa242a35bb0cf664aL,0x126e48f77f9707e3L,0x1717bf54c6832660L,\n        0xfaae7332fd12c72eL },\n      { 0x27b52db7995d586bL,0xbe29569e832237c2L,0xe8e4193e2a65e7dbL,\n        0x152706dc2eaa1bbbL } },\n    /* 15 << 0 */\n    { { 0x72bcd8b7bc60055bL,0x03cc23ee56e27e4bL,0xee337424e4819370L,\n        0xe2aa0e430ad3da09L },\n      { 0x40b8524f6383c45dL,0xd766355442a41b25L,0x64efa6de778a4797L,\n        0x2042170a7079adf4L } },\n    /* 16 << 0 */\n    { { 0x808b0b650bc6fb80L,0x5882e0753ffe2e6bL,0xd5ef2f7c2c83f549L,\n        0x54d63c809103b723L },\n      { 0xf2f11bd652a23f9bL,0x3670c3194b0b6587L,0x55c4623bb1580e9eL,\n        0x64edf7b201efe220L } },\n    /* 17 << 0 */\n    { { 0x97091dcbd53c5c9dL,0xf17624b6ac0a177bL,0xb0f139752cfe2dffL,\n        0xc1a35c0a6c7a574eL },\n      { 0x227d314693e79987L,0x0575bf30e89cb80eL,0x2f4e247f0d1883bbL,\n        0xebd512263274c3d0L } },\n    /* 18 << 0 */\n    { { 0x5f3e51c856ada97aL,0x4afc964d8f8b403eL,0xa6f247ab412e2979L,\n        0x675abd1b6f80ebdaL },\n      { 0x66a2bd725e485a1dL,0x4b2a5caf8f4f0b3cL,0x2626927f1b847bbaL,\n        0x6c6fc7d90502394dL } },\n    /* 19 << 0 */\n    { { 0xfea912baa5659ae8L,0x68363aba25e1a16eL,0xb8842277752c41acL,\n        0xfe545c282897c3fcL },\n      { 0x2d36e9e7dc4c696bL,0x5806244afba977c5L,0x85665e9be39508c1L,\n        0xf720ee256d12597bL } },\n    /* 20 << 0 */\n    { { 0x8a979129d2337a31L,0x5916868f0f862bdcL,0x048099d95dd283baL,\n        0xe2d1eeb6fe5bfb4eL },\n      { 0x82ef1c417884005dL,0xa2d4ec17ffffcbaeL,0x9161c53f8aa95e66L,\n        0x5ee104e1c5fee0d0L } },\n    /* 21 << 0 */\n    { { 0x562e4cecc135b208L,0x74e1b2654783f47dL,0x6d2a506c5a3f3b30L,\n        0xecead9f4c16762fcL },\n      { 0xf29dd4b2e286e5b9L,0x1b0fadc083bb3c61L,0x7a75023e7fac29a4L,\n        0xc086d5f1c9477fa3L } },\n    /* 22 << 0 */\n    { { 0x0fc611352f6f3076L,0xc99ffa23e3912a9aL,0x6a0b0685d2f8ba3dL,\n        0xfdc777e8e93358a4L },\n      { 0x94a787bb35415f04L,0x640c2d6a4d23fea4L,0x9de917da153a35b5L,\n        0x793e8d075d5cd074L } },\n    /* 23 << 0 */\n    { { 0xf4f876532de45068L,0x37c7a7e89e2e1f6eL,0xd0825fa2a3584069L,\n        0xaf2cea7c1727bf42L },\n      { 0x0360a4fb9e4785a9L,0xe5fda49c27299f4aL,0x48068e1371ac2f71L,\n        0x83d0687b9077666fL } },\n    /* 24 << 0 */\n    { { 0x6d3883b215d02819L,0x6d0d755040dd9a35L,0x61d7cbf91d2b469fL,\n        0xf97b232f2efc3115L },\n      { 0xa551d750b24bcbc7L,0x11ea494988a1e356L,0x7669f03193cb7501L,\n        0x595dc55eca737b8aL } },\n    /* 25 << 0 */\n    { { 0xa4a319acd837879fL,0x6fc1b49eed6b67b0L,0xe395993332f1f3afL,\n        0x966742eb65432a2eL },\n      { 0x4b8dc9feb4966228L,0x96cc631243f43950L,0x12068859c9b731eeL,\n        0x7b948dc356f79968L } },\n    /* 26 << 0 */\n    { { 0x61e4ad32ed1f8008L,0xe6c9267ad8b17538L,0x1ac7c5eb857ff6fbL,\n        0x994baaa855f2fb10L },\n      { 0x84cf14e11d248018L,0x5a39898b628ac508L,0x14fde97b5fa944f5L,\n        0xed178030d12e5ac7L } },\n    /* 27 << 0 */\n    { { 0x042c2af497e2feb4L,0xd36a42d7aebf7313L,0x49d2c9eb084ffdd7L,\n        0x9f8aa54b2ef7c76aL },\n      { 0x9200b7ba09895e70L,0x3bd0c66fddb7fb58L,0x2d97d10878eb4cbbL,\n        0x2d431068d84bde31L } },\n    /* 28 << 0 */\n    { { 0x4b523eb7172ccd1fL,0x7323cb2830a6a892L,0x97082ec0cfe153ebL,\n        0xe97f6b6af2aadb97L },\n      { 0x1d3d393ed1a83da1L,0xa6a7f9c7804b2a68L,0x4a688b482d0cb71eL,\n        0xa9b4cc5f40585278L } },\n    /* 29 << 0 */\n    { { 0x5e5db46acb66e132L,0xf1be963a0d925880L,0x944a70270317b9e2L,\n        0xe266f95948603d48L },\n      { 0x98db66735c208899L,0x90472447a2fb18a3L,0x8a966939777c619fL,\n        0x3798142a2a3be21bL } },\n    /* 30 << 0 */\n    { { 0xb4241cb13298b343L,0xa3a14e49b44f65a1L,0xc5f4d6cd3ac77acdL,\n        0xd0288cb552b6fc3cL },\n      { 0xd5cc8c2f1c040abcL,0xb675511e06bf9b4aL,0xd667da379b3aa441L,\n        0x460d45ce51601f72L } },\n    /* 31 << 0 */\n    { { 0xe2f73c696755ff89L,0xdd3cf7e7473017e6L,0x8ef5689d3cf7600dL,\n        0x948dc4f8b1fc87b4L },\n      { 0xd9e9fe814ea53299L,0x2d921ca298eb6028L,0xfaecedfd0c9803fcL,\n        0xf38ae8914d7b4745L } },\n    /* 32 << 0 */\n    { { 0xd8c5fccfc5e3a3d8L,0xbefd904c4079dfbfL,0xbc6d6a58fead0197L,\n        0x39227077695532a4L },\n      { 0x09e23e6ddbef42f5L,0x7e449b64480a9908L,0x7b969c1aad9a2e40L,\n        0x6231d7929591c2a4L } },\n    /* 33 << 0 */\n    { { 0x871514560f664534L,0x85ceae7c4b68f103L,0xac09c4ae65578ab9L,\n        0x33ec6868f044b10cL },\n      { 0x6ac4832b3a8ec1f1L,0x5509d1285847d5efL,0xf909604f763f1574L,\n        0xb16c4303c32f63c4L } },\n    /* 34 << 0 */\n    { { 0xb6ab20147ca23cd3L,0xcaa7a5c6a391849dL,0x5b0673a375678d94L,\n        0xc982ddd4dd303e64L },\n      { 0xfd7b000b5db6f971L,0xbba2cb1f6f876f92L,0xc77332a33c569426L,\n        0xa159100c570d74f8L } },\n    /* 35 << 0 */\n    { { 0xfd16847fdec67ef5L,0x742ee464233e76b7L,0x0b8e4134efc2b4c8L,\n        0xca640b8642a3e521L },\n      { 0x653a01908ceb6aa9L,0x313c300c547852d5L,0x24e4ab126b237af7L,\n        0x2ba901628bb47af8L } },\n    /* 36 << 0 */\n    { { 0x3d5e58d6a8219bb7L,0xc691d0bd1b06c57fL,0x0ae4cb10d257576eL,\n        0x3569656cd54a3dc3L },\n      { 0xe5ebaebd94cda03aL,0x934e82d3162bfe13L,0x450ac0bae251a0c6L,\n        0x480b9e11dd6da526L } },\n    /* 37 << 0 */\n    { { 0x00467bc58cce08b5L,0xb636458c7f178d55L,0xc5748baea677d806L,\n        0x2763a387dfa394ebL },\n      { 0xa12b448a7d3cebb6L,0xe7adda3e6f20d850L,0xf63ebce51558462cL,\n        0x58b36143620088a8L } },\n    /* 38 << 0 */\n    { { 0x8a2cc3ca4d63c0eeL,0x512331170fe948ceL,0x7463fd85222ef33bL,\n        0xadf0c7dc7c603d6cL },\n      { 0x0ec32d3bfe7765e5L,0xccaab359bf380409L,0xbdaa84d68e59319cL,\n        0xd9a4c2809c80c34dL } },\n    /* 39 << 0 */\n    { { 0xa9d89488a059c142L,0x6f5ae714ff0b9346L,0x068f237d16fb3664L,\n        0x5853e4c4363186acL },\n      { 0xe2d87d2363c52f98L,0x2ec4a76681828876L,0x47b864fae14e7b1cL,\n        0x0c0bc0e569192408L } },\n    /* 40 << 0 */\n    { { 0xe4d7681db82e9f3eL,0x83200f0bdf25e13cL,0x8909984c66f27280L,\n        0x462d7b0075f73227L },\n      { 0xd90ba188f2651798L,0x74c6e18c36ab1c34L,0xab256ea35ef54359L,\n        0x03466612d1aa702fL } },\n    /* 41 << 0 */\n    { { 0x624d60492ed22e91L,0x6fdfe0b56f072822L,0xeeca111539ce2271L,\n        0x98100a4fdb01614fL },\n      { 0xb6b0daa2a35c628fL,0xb6f94d2ec87e9a47L,0xc67732591d57d9ceL,\n        0xf70bfeec03884a7bL } },\n    /* 42 << 0 */\n    { { 0x5fb35ccfed2bad01L,0xa155cbe31da6a5c7L,0xc2e2594c30a92f8fL,\n        0x649c89ce5bfafe43L },\n      { 0xd158667de9ff257aL,0x9b359611f32c50aeL,0x4b00b20b906014cfL,\n        0xf3a8cfe389bc7d3dL } },\n    /* 43 << 0 */\n    { { 0x4ff23ffd248a7d06L,0x80c5bfb4878873faL,0xb7d9ad9005745981L,\n        0x179c85db3db01994L },\n      { 0xba41b06261a6966cL,0x4d82d052eadce5a8L,0x9e91cd3ba5e6a318L,\n        0x47795f4f95b2dda0L } },\n    /* 44 << 0 */\n    { { 0xecfd7c1fd55a897cL,0x009194abb29110fbL,0x5f0e2046e381d3b0L,\n        0x5f3425f6a98dd291L },\n      { 0xbfa06687730d50daL,0x0423446c4b083b7fL,0x397a247dd69d3417L,\n        0xeb629f90387ba42aL } },\n    /* 45 << 0 */\n    { { 0x1ee426ccd5cd79bfL,0x0032940b946c6e18L,0x1b1e8ae057477f58L,\n        0xe94f7d346d823278L },\n      { 0xc747cb96782ba21aL,0xc5254469f72b33a5L,0x772ef6dec7f80c81L,\n        0xd73acbfe2cd9e6b5L } },\n    /* 46 << 0 */\n    { { 0x4075b5b149ee90d9L,0x785c339aa06e9ebaL,0xa1030d5babf825e0L,\n        0xcec684c3a42931dcL },\n      { 0x42ab62c9c1586e63L,0x45431d665ab43f2bL,0x57c8b2c055f7835dL,\n        0x033da338c1b7f865L } },\n    /* 47 << 0 */\n    { { 0x283c7513caa76097L,0x0a624fa936c83906L,0x6b20afec715af2c7L,\n        0x4b969974eba78bfdL },\n      { 0x220755ccd921d60eL,0x9b944e107baeca13L,0x04819d515ded93d4L,\n        0x9bbff86e6dddfd27L } },\n    /* 48 << 0 */\n    { { 0x6b34413077adc612L,0xa7496529bbd803a0L,0x1a1baaa76d8805bdL,\n        0xc8403902470343adL },\n      { 0x39f59f66175adff1L,0x0b26d7fbb7d8c5b7L,0xa875f5ce529d75e3L,\n        0x85efc7e941325cc2L } },\n    /* 49 << 0 */\n    { { 0x21950b421ff6acd3L,0xffe7048453dc6909L,0xff4cd0b228766127L,\n        0xabdbe6084fb7db2bL },\n      { 0x837c92285e1109e8L,0x26147d27f4645b5aL,0x4d78f592f7818ed8L,\n        0xd394077ef247fa36L } },\n    /* 50 << 0 */\n    { { 0x0fb9c2d0488c171aL,0xa78bfbaa13685278L,0xedfbe268d5b1fa6aL,\n        0x0dceb8db2b7eaba7L },\n      { 0xbf9e80899ae2b710L,0xefde7ae6a4449c96L,0x43b7716bcc143a46L,\n        0xd7d34194c3628c13L } },\n    /* 51 << 0 */\n    { { 0x508cec1c3b3f64c9L,0xe20bc0ba1e5edf3fL,0xda1deb852f4318d4L,\n        0xd20ebe0d5c3fa443L },\n      { 0x370b4ea773241ea3L,0x61f1511c5e1a5f65L,0x99a5e23d82681c62L,\n        0xd731e383a2f54c2dL } },\n    /* 52 << 0 */\n    { { 0x2692f36e83445904L,0x2e0ec469af45f9c0L,0x905a3201c67528b7L,\n        0x88f77f34d0e5e542L },\n      { 0xf67a8d295864687cL,0x23b92eae22df3562L,0x5c27014b9bbec39eL,\n        0x7ef2f2269c0f0f8dL } },\n    /* 53 << 0 */\n    { { 0x97359638546c4d8dL,0x5f9c3fc492f24679L,0x912e8beda8c8acd9L,\n        0xec3a318d306634b0L },\n      { 0x80167f41c31cb264L,0x3db82f6f522113f2L,0xb155bcd2dcafe197L,\n        0xfba1da5943465283L } },\n    /* 54 << 0 */\n    { { 0xa0425b8eb212cf53L,0x4f2e512ef8557c5fL,0xc1286ff925c4d56cL,\n        0xbb8a0feaee26c851L },\n      { 0xc28f70d2e7d6107eL,0x7ee0c444e76265aaL,0x3df277a41d1936b1L,\n        0x1a556e3fea9595ebL } },\n    /* 55 << 0 */\n    { { 0x258bbbf9e7305683L,0x31eea5bf07ef5be6L,0x0deb0e4a46c814c1L,\n        0x5cee8449a7b730ddL },\n      { 0xeab495c5a0182bdeL,0xee759f879e27a6b4L,0xc2cf6a6880e518caL,\n        0x25e8013ff14cf3f4L } },\n    /* 56 << 0 */\n    { { 0x8fc441407e8d7a14L,0xbb1ff3ca9556f36aL,0x6a84438514600044L,\n        0xba3f0c4a7451ae63L },\n      { 0xdfcac25b1f9af32aL,0x01e0db86b1f2214bL,0x4e9a5bc2a4b596acL,\n        0x83927681026c2c08L } },\n    /* 57 << 0 */\n    { { 0x3ec832e77acaca28L,0x1bfeea57c7385b29L,0x068212e3fd1eaf38L,\n        0xc13298306acf8cccL },\n      { 0xb909f2db2aac9e59L,0x5748060db661782aL,0xc5ab2632c79b7a01L,\n        0xda44c6c600017626L } },\n    /* 58 << 0 */\n    { { 0xf26c00e8a7ea82f0L,0x99cac80de4299aafL,0xd66fe3b67ed78be1L,\n        0x305f725f648d02cdL },\n      { 0x33ed1bc4623fb21bL,0xfa70533e7a6319adL,0x17ab562dbe5ffb3eL,\n        0x0637499456674741L } },\n    /* 59 << 0 */\n    { { 0x69d44ed65c46aa8eL,0x2100d5d3a8d063d1L,0xcb9727eaa2d17c36L,\n        0x4c2bab1b8add53b7L },\n      { 0xa084e90c15426704L,0x778afcd3a837ebeaL,0x6651f7017ce477f8L,\n        0xa062499846fb7a8bL } },\n    /* 60 << 0 */\n    { { 0xdc1e6828ed8a6e19L,0x33fc23364189d9c7L,0x026f8fe2671c39bcL,\n        0xd40c4ccdbc6f9915L },\n      { 0xafa135bbf80e75caL,0x12c651a022adff2cL,0xc40a04bd4f51ad96L,\n        0x04820109bbe4e832L } },\n    /* 61 << 0 */\n    { { 0x3667eb1a7f4c04ccL,0x59556621a9404f84L,0x71cdf6537eceb50aL,\n        0x994a44a69b8335faL },\n      { 0xd7faf819dbeb9b69L,0x473c5680eed4350dL,0xb6658466da44bba2L,\n        0x0d1bc780872bdbf3L } },\n    /* 62 << 0 */\n    { { 0xe535f175a1962f91L,0x6ed7e061ed58f5a7L,0x177aa4c02089a233L,\n        0x0dbcb03ae539b413L },\n      { 0xe3dc424ebb32e38eL,0x6472e5ef6806701eL,0xdd47ff98814be9eeL,\n        0x6b60cfff35ace009L } },\n    /* 63 << 0 */\n    { { 0xb8d3d9319ff91fe5L,0x039c4800f0518eedL,0x95c376329182cb26L,\n        0x0763a43482fc568dL },\n      { 0x707c04d5383e76baL,0xac98b930824e8197L,0x92bf7c8f91230de0L,\n        0x90876a0140959b70L } },\n    /* 64 << 0 */\n    { { 0xdb6d96f305968b80L,0x380a0913089f73b9L,0x7da70b83c2c61e01L,\n        0x95fb8394569b38c7L },\n      { 0x9a3c651280edfe2fL,0x8f726bb98faeaf82L,0x8010a4a078424bf8L,\n        0x296720440e844970L } },\n    /* 0 << 7 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 7 */\n    { { 0x63c5cb817a2ad62aL,0x7ef2b6b9ac62ff54L,0x3749bba4b3ad9db5L,\n        0xad311f2c46d5a617L },\n      { 0xb77a8087c2ff3b6dL,0xb46feaf3367834ffL,0xf8aa266d75d6b138L,\n        0xfa38d320ec008188L } },\n    /* 2 << 7 */\n    { { 0x486d8ffa696946fcL,0x50fbc6d8b9cba56dL,0x7e3d423e90f35a15L,\n        0x7c3da195c0dd962cL },\n      { 0xe673fdb03cfd5d8bL,0x0704b7c2889dfca5L,0xf6ce581ff52305aaL,\n        0x399d49eb914d5e53L } },\n    /* 3 << 7 */\n    { { 0x380a496d6ec293cdL,0x733dbda78e7051f5L,0x037e388db849140aL,\n        0xee4b32b05946dbf6L },\n      { 0xb1c4fda9cae368d1L,0x5001a7b0fdb0b2f3L,0x6df593742e3ac46eL,\n        0x4af675f239b3e656L } },\n    /* 4 << 7 */\n    { { 0x44e3811039949296L,0x5b63827b361db1b5L,0x3e5323ed206eaff5L,\n        0x942370d2c21f4290L },\n      { 0xf2caaf2ee0d985a1L,0x192cc64b7239846dL,0x7c0b8f47ae6312f8L,\n        0x7dc61f9196620108L } },\n    /* 5 << 7 */\n    { { 0xb830fb5bc2da7de9L,0xd0e643df0ff8d3beL,0x31ee77ba188a9641L,\n        0x4e8aa3aabcf6d502L },\n      { 0xf9fb65329a49110fL,0xd18317f62dd6b220L,0x7e3ced4152c3ea5aL,\n        0x0d296a147d579c4aL } },\n    /* 6 << 7 */\n    { { 0x35d6a53eed4c3717L,0x9f8240cf3d0ed2a3L,0x8c0d4d05e5543aa5L,\n        0x45d5bbfbdd33b4b4L },\n      { 0xfa04cc73137fd28eL,0x862ac6efc73b3ffdL,0x403ff9f531f51ef2L,\n        0x34d5e0fcbc73f5a2L } },\n    /* 7 << 7 */\n    { { 0xf252682008913f4fL,0xea20ed61eac93d95L,0x51ed38b46ca6b26cL,\n        0x8662dcbcea4327b0L },\n      { 0x6daf295c725d2aaaL,0xbad2752f8e52dcdaL,0x2210e7210b17daccL,\n        0xa37f7912d51e8232L } },\n    /* 8 << 7 */\n    { { 0x4f7081e144cc3addL,0xd5ffa1d687be82cfL,0x89890b6c0edd6472L,\n        0xada26e1a3ed17863L },\n      { 0x276f271563483caaL,0xe6924cd92f6077fdL,0x05a7fe980a466e3cL,\n        0xf1c794b0b1902d1fL } },\n    /* 9 << 7 */\n    { { 0xe521368882a8042cL,0xd931cfafcd278298L,0x069a0ae0f597a740L,\n        0x0adbb3f3eb59107cL },\n      { 0x983e951e5eaa8eb8L,0xe663a8b511b48e78L,0x1631cc0d8a03f2c5L,\n        0x7577c11e11e271e2L } },\n    /* 10 << 7 */\n    { { 0x33b2385c08369a90L,0x2990c59b190eb4f8L,0x819a6145c68eac80L,\n        0x7a786d622ec4a014L },\n      { 0x33faadbe20ac3a8dL,0x31a217815aba2d30L,0x209d2742dba4f565L,\n        0xdb2ce9e355aa0fbbL } },\n    /* 11 << 7 */\n    { { 0x8cef334b168984dfL,0xe81dce1733879638L,0xf6e6949c263720f0L,\n        0x5c56feaff593cbecL },\n      { 0x8bff5601fde58c84L,0x74e241172eccb314L,0xbcf01b614c9a8a78L,\n        0xa233e35e544c9868L } },\n    /* 12 << 7 */\n    { { 0xb3156bf38bd7aff1L,0x1b5ee4cb1d81b146L,0x7ba1ac41d628a915L,\n        0x8f3a8f9cfd89699eL },\n      { 0x7329b9c9a0748be7L,0x1d391c95a92e621fL,0xe51e6b214d10a837L,\n        0xd255f53a4947b435L } },\n    /* 13 << 7 */\n    { { 0x07669e04f1788ee3L,0xc14f27afa86938a2L,0x8b47a334e93a01c0L,\n        0xff627438d9366808L },\n      { 0x7a0985d8ca2a5965L,0x3d9a5542d6e9b9b3L,0xc23eb80b4cf972e8L,\n        0x5c1c33bb4fdf72fdL } },\n    /* 14 << 7 */\n    { { 0x0c4a58d474a86108L,0xf8048a8fee4c5d90L,0xe3c7c924e86d4c80L,\n        0x28c889de056a1e60L },\n      { 0x57e2662eb214a040L,0xe8c48e9837e10347L,0x8774286280ac748aL,\n        0xf1c24022186b06f2L } },\n    /* 15 << 7 */\n    { { 0xac2dd4c35f74040aL,0x409aeb71fceac957L,0x4fbad78255c4ec23L,\n        0xb359ed618a7b76ecL },\n      { 0x12744926ed6f4a60L,0xe21e8d7f4b912de3L,0xe2575a59fc705a59L,\n        0x72f1d4deed2dbc0eL } },\n    /* 16 << 7 */\n    { { 0x3d2b24b9eb7926b8L,0xbff88cb3cdbe5509L,0xd0f399afe4dd640bL,\n        0x3c5fe1302f76ed45L },\n      { 0x6f3562f43764fb3dL,0x7b5af3183151b62dL,0xd5bd0bc7d79ce5f3L,\n        0xfdaf6b20ec66890fL } },\n    /* 17 << 7 */\n    { { 0x735c67ec6063540cL,0x50b259c2e5f9cb8fL,0xb8734f9a3f99c6abL,\n        0xf8cc13d5a3a7bc85L },\n      { 0x80c1b305c5217659L,0xfe5364d44ec12a54L,0xbd87045e681345feL,\n        0x7f8efeb1582f897fL } },\n    /* 18 << 7 */\n    { { 0xe8cbf1e5d5923359L,0xdb0cea9d539b9fb0L,0x0c5b34cf49859b98L,\n        0x5e583c56a4403cc6L },\n      { 0x11fc1a2dd48185b7L,0xc93fbc7e6e521787L,0x47e7a05805105b8bL,\n        0x7b4d4d58db8260c8L } },\n    /* 19 << 7 */\n    { { 0xe33930b046eb842aL,0x8e844a9a7bdae56dL,0x34ef3a9e13f7fdfcL,\n        0xb3768f82636ca176L },\n      { 0x2821f4e04e09e61cL,0x414dc3a1a0c7cddcL,0xd537943754945fcdL,\n        0x151b6eefb3555ff1L } },\n    /* 20 << 7 */\n    { { 0xb31bd6136339c083L,0x39ff8155dfb64701L,0x7c3388d2e29604abL,\n        0x1e19084ba6b10442L },\n      { 0x17cf54c0eccd47efL,0x896933854a5dfb30L,0x69d023fb47daf9f6L,\n        0x9222840b7d91d959L } },\n    /* 21 << 7 */\n    { { 0x439108f5803bac62L,0x0b7dd91d379bd45fL,0xd651e827ca63c581L,\n        0x5c5d75f6509c104fL },\n      { 0x7d5fc7381f2dc308L,0x20faa7bfd98454beL,0x95374beea517b031L,\n        0xf036b9b1642692acL } },\n    /* 22 << 7 */\n    { { 0xc510610939842194L,0xb7e2353e49d05295L,0xfc8c1d5cefb42ee0L,\n        0xe04884eb08ce811cL },\n      { 0xf1f75d817419f40eL,0x5b0ac162a995c241L,0x120921bbc4c55646L,\n        0x713520c28d33cf97L } },\n    /* 23 << 7 */\n    { { 0xb4a65a5ce98c5100L,0x6cec871d2ddd0f5aL,0x251f0b7f9ba2e78bL,\n        0x224a8434ce3a2a5fL },\n      { 0x26827f6125f5c46fL,0x6a22bedc48545ec0L,0x25ae5fa0b1bb5cdcL,\n        0xd693682ffcb9b98fL } },\n    /* 24 << 7 */\n    { { 0x32027fe891e5d7d3L,0xf14b7d1773a07678L,0xf88497b3c0dfdd61L,\n        0xf7c2eec02a8c4f48L },\n      { 0xaa5573f43756e621L,0xc013a2401825b948L,0x1c03b34563878572L,\n        0xa0472bea653a4184L } },\n    /* 25 << 7 */\n    { { 0xf4222e270ac69a80L,0x34096d25f51e54f6L,0x00a648cb8fffa591L,\n        0x4e87acdc69b6527fL },\n      { 0x0575e037e285ccb4L,0x188089e450ddcf52L,0xaa96c9a8870ff719L,\n        0x74a56cd81fc7e369L } },\n    /* 26 << 7 */\n    { { 0x41d04ee21726931aL,0x0bbbb2c83660ecfdL,0xa6ef6de524818e18L,\n        0xe421cc51e7d57887L },\n      { 0xf127d208bea87be6L,0x16a475d3b1cdd682L,0x9db1b684439b63f7L,\n        0x5359b3dbf0f113b6L } },\n    /* 27 << 7 */\n    { { 0xdfccf1de8bf06e31L,0x1fdf8f44dd383901L,0x10775cad5017e7d2L,\n        0xdfc3a59758d11eefL },\n      { 0x6ec9c8a0b1ecff10L,0xee6ed6cc28400549L,0xb5ad7bae1b4f8d73L,\n        0x61b4f11de00aaab9L } },\n    /* 28 << 7 */\n    { { 0x7b32d69bd4eff2d7L,0x88ae67714288b60fL,0x159461b437a1e723L,\n        0x1f3d4789570aae8cL },\n      { 0x869118c07f9871daL,0x35fbda78f635e278L,0x738f3641e1541dacL,\n        0x6794b13ac0dae45fL } },\n    /* 29 << 7 */\n    { { 0x065064ac09cc0917L,0x27c53729c68540fdL,0x0d2d4c8eef227671L,\n        0xd23a9f80a1785a04L },\n      { 0x98c5952852650359L,0xfa09ad0174a1acadL,0x082d5a290b55bf5cL,\n        0xa40f1c67419b8084L } },\n    /* 30 << 7 */\n    { { 0x3a5c752edcc18770L,0x4baf1f2f8825c3a5L,0xebd63f7421b153edL,\n        0xa2383e47b2f64723L },\n      { 0xe7bf620a2646d19aL,0x56cb44ec03c83ffdL,0xaf7267c94f6be9f1L,\n        0x8b2dfd7bc06bb5e9L } },\n    /* 31 << 7 */\n    { { 0xb87072f2a672c5c7L,0xeacb11c80d53c5e2L,0x22dac29dff435932L,\n        0x37bdb99d4408693cL },\n      { 0xf6e62fb62899c20fL,0x3535d512447ece24L,0xfbdc6b88ff577ce3L,\n        0x726693bd190575f2L } },\n    /* 32 << 7 */\n    { { 0x6772b0e5ab4b35a2L,0x1d8b6001f5eeaacfL,0x728f7ce4795b9580L,\n        0x4a20ed2a41fb81daL },\n      { 0x9f685cd44fec01e6L,0x3ed7ddcca7ff50adL,0x460fd2640c2d97fdL,\n        0x3a241426eb82f4f9L } },\n    /* 33 << 7 */\n    { { 0x17d1df2c6a8ea820L,0xb2b50d3bf22cc254L,0x03856cbab7291426L,\n        0x87fd26ae04f5ee39L },\n      { 0x9cb696cc02bee4baL,0x5312180406820fd6L,0xa5dfc2690212e985L,\n        0x666f7ffa160f9a09L } },\n    /* 34 << 7 */\n    { { 0xc503cd33bccd9617L,0x365dede4ba7730a3L,0x798c63555ddb0786L,\n        0xa6c3200efc9cd3bcL },\n      { 0x060ffb2ce5e35efdL,0x99a4e25b5555a1c1L,0x11d95375f70b3751L,\n        0x0a57354a160e1bf6L } },\n    /* 35 << 7 */\n    { { 0xecb3ae4bf8e4b065L,0x07a834c42e53022bL,0x1cd300b38692ed96L,\n        0x16a6f79261ee14ecL },\n      { 0x8f1063c66a8649edL,0xfbcdfcfe869f3e14L,0x2cfb97c100a7b3ecL,\n        0xcea49b3c7130c2f1L } },\n    /* 36 << 7 */\n    { { 0x462d044fe9d96488L,0x4b53d52e8182a0c1L,0x84b6ddd30391e9e9L,\n        0x80ab7b48b1741a09L },\n      { 0xec0e15d427d3317fL,0x8dfc1ddb1a64671eL,0x93cc5d5fd49c5b92L,\n        0xc995d53d3674a331L } },\n    /* 37 << 7 */\n    { { 0x302e41ec090090aeL,0x2278a0ccedb06830L,0x1d025932fbc99690L,\n        0x0c32fbd2b80d68daL },\n      { 0xd79146daf341a6c1L,0xae0ba1391bef68a0L,0xc6b8a5638d774b3aL,\n        0x1cf307bd880ba4d7L } },\n    /* 38 << 7 */\n    { { 0xc033bdc719803511L,0xa9f97b3b8888c3beL,0x3d68aebc85c6d05eL,\n        0xc3b88a9d193919ebL },\n      { 0x2d300748c48b0ee3L,0x7506bc7c07a746c1L,0xfc48437c6e6d57f3L,\n        0x5bd71587cfeaa91aL } },\n    /* 39 << 7 */\n    { { 0xa4ed0408c1bc5225L,0xd0b946db2719226dL,0x109ecd62758d2d43L,\n        0x75c8485a2751759bL },\n      { 0xb0b75f499ce4177aL,0x4fa61a1e79c10c3dL,0xc062d300a167fcd7L,\n        0x4df3874c750f0fa8L } },\n    /* 40 << 7 */\n    { { 0x29ae2cf983dfedc9L,0xf84371348d87631aL,0xaf5717117429c8d2L,\n        0x18d15867146d9272L },\n      { 0x83053ecf69769bb7L,0xc55eb856c479ab82L,0x5ef7791c21b0f4b2L,\n        0xaa5956ba3d491525L } },\n    /* 41 << 7 */\n    { { 0x407a96c29fe20ebaL,0xf27168bbe52a5ad3L,0x43b60ab3bf1d9d89L,\n        0xe45c51ef710e727aL },\n      { 0xdfca5276099b4221L,0x8dc6407c2557a159L,0x0ead833591035895L,\n        0x0a9db9579c55dc32L } },\n    /* 42 << 7 */\n    { { 0xe40736d3df61bc76L,0x13a619c03f778cdbL,0x6dd921a4c56ea28fL,\n        0x76a524332fa647b4L },\n      { 0x23591891ac5bdc5dL,0xff4a1a72bac7dc01L,0x9905e26162df8453L,\n        0x3ac045dfe63b265fL } },\n    /* 43 << 7 */\n    { { 0x8a3f341bad53dba7L,0x8ec269cc837b625aL,0xd71a27823ae31189L,\n        0x8fb4f9a355e96120L },\n      { 0x804af823ff9875cfL,0x23224f575d442a9bL,0x1c4d3b9eecc62679L,\n        0x91da22fba0e7ddb1L } },\n    /* 44 << 7 */\n    { { 0xa370324d6c04a661L,0x9710d3b65e376d17L,0xed8c98f03044e357L,\n        0xc364ebbe6422701cL },\n      { 0x347f5d517733d61cL,0xd55644b9cea826c3L,0x80c6e0ad55a25548L,\n        0x0aa7641d844220a7L } },\n    /* 45 << 7 */\n    { { 0x1438ec8131810660L,0x9dfa6507de4b4043L,0x10b515d8cc3e0273L,\n        0x1b6066dd28d8cfb2L },\n      { 0xd3b045919c9efebdL,0x425d4bdfa21c1ff4L,0x5fe5af19d57607d3L,\n        0xbbf773f754481084L } },\n    /* 46 << 7 */\n    { { 0x8435bd6994b03ed1L,0xd9ad1de3634cc546L,0x2cf423fc00e420caL,\n        0xeed26d80a03096ddL },\n      { 0xd7f60be7a4db09d2L,0xf47f569d960622f7L,0xe5925fd77296c729L,\n        0xeff2db2626ca2715L } },\n    /* 47 << 7 */\n    { { 0xa6fcd014b913e759L,0x53da47868ff4de93L,0x14616d79c32068e1L,\n        0xb187d664ccdf352eL },\n      { 0xf7afb6501dc90b59L,0x8170e9437daa1b26L,0xc8e3bdd8700c0a84L,\n        0x6e8d345f6482bdfaL } },\n    /* 48 << 7 */\n    { { 0x84cfbfa1c5c5ea50L,0xd3baf14c67960681L,0x263984030dd50942L,\n        0xe4b7839c4716a663L },\n      { 0xd5f1f794e7de6dc0L,0x5cd0f4d4622aa7ceL,0x5295f3f159acfeecL,\n        0x8d933552953e0607L } },\n    /* 49 << 7 */\n    { { 0xc7db8ec5776c5722L,0xdc467e622b5f290cL,0xd4297e704ff425a9L,\n        0x4be924c10cf7bb72L },\n      { 0x0d5dc5aea1892131L,0x8bf8a8e3a705c992L,0x73a0b0647a305ac5L,\n        0x00c9ca4e9a8c77a8L } },\n    /* 50 << 7 */\n    { { 0x5dfee80f83774bddL,0x6313160285734485L,0xa1b524ae914a69a9L,\n        0xebc2ffafd4e300d7L },\n      { 0x52c93db77cfa46a5L,0x71e6161f21653b50L,0x3574fc57a4bc580aL,\n        0xc09015dde1bc1253L } },\n    /* 51 << 7 */\n    { { 0x4b7b47b2d174d7aaL,0x4072d8e8f3a15d04L,0xeeb7d47fd6fa07edL,\n        0x6f2b9ff9edbdafb1L },\n      { 0x18c516153760fe8aL,0x7a96e6bff06c6c13L,0x4d7a04100ea2d071L,\n        0xa1914e9b0be2a5ceL } },\n    /* 52 << 7 */\n    { { 0x5726e357d8a3c5cfL,0x1197ecc32abb2b13L,0x6c0d7f7f31ae88ddL,\n        0x15b20d1afdbb3efeL },\n      { 0xcd06aa2670584039L,0x2277c969a7dc9747L,0xbca695877855d815L,\n        0x899ea2385188b32aL } },\n    /* 53 << 7 */\n    { { 0x37d9228b760c1c9dL,0xc7efbb119b5c18daL,0x7f0d1bc819f6dbc5L,\n        0x4875384b07e6905bL },\n      { 0xc7c50baa3ba8cd86L,0xb0ce40fbc2905de0L,0x708406737a231952L,\n        0xa912a262cf43de26L } },\n    /* 54 << 7 */\n    { { 0x9c38ddcceb5b76c1L,0x746f528526fc0ab4L,0x52a63a50d62c269fL,\n        0x60049c5599458621L },\n      { 0xe7f48f823c2f7c9eL,0x6bd99043917d5cf3L,0xeb1317a88701f469L,\n        0xbd3fe2ed9a449fe0L } },\n    /* 55 << 7 */\n    { { 0x421e79ca12ef3d36L,0x9ee3c36c3e7ea5deL,0xe48198b5cdff36f7L,\n        0xaff4f967c6b82228L },\n      { 0x15e19dd0c47adb7eL,0x45699b23032e7dfaL,0x40680c8b1fae026aL,\n        0x5a347a48550dbf4dL } },\n    /* 56 << 7 */\n    { { 0xe652533b3cef0d7dL,0xd94f7b182bbb4381L,0x838752be0e80f500L,\n        0x8e6e24889e9c9bfbL },\n      { 0xc975169716caca6aL,0x866c49d838531ad9L,0xc917e2397151ade1L,\n        0x2d016ec16037c407L } },\n    /* 57 << 7 */\n    { { 0xa407ccc900eac3f9L,0x835f6280e2ed4748L,0xcc54c3471cc98e0dL,\n        0x0e969937dcb572ebL },\n      { 0x1b16c8e88f30c9cbL,0xa606ae75373c4661L,0x47aa689b35502cabL,\n        0xf89014ae4d9bb64fL } },\n    /* 58 << 7 */\n    { { 0x202f6a9c31c71f7bL,0x01f95aa3296ffe5cL,0x5fc0601453cec3a3L,\n        0xeb9912375f498a45L },\n      { 0xae9a935e5d91ba87L,0xc6ac62810b564a19L,0x8a8fe81c3bd44e69L,\n        0x7c8b467f9dd11d45L } },\n    /* 59 << 7 */\n    { { 0xf772251fea5b8e69L,0xaeecb3bdc5b75fbcL,0x1aca3331887ff0e5L,\n        0xbe5d49ff19f0a131L },\n      { 0x582c13aae5c8646fL,0xdbaa12e820e19980L,0x8f40f31af7abbd94L,\n        0x1f13f5a81dfc7663L } },\n    /* 60 << 7 */\n    { { 0x5d81f1eeaceb4fc0L,0x362560025e6f0f42L,0x4b67d6d7751370c8L,\n        0x2608b69803e80589L },\n      { 0xcfc0d2fc05268301L,0xa6943d3940309212L,0x192a90c21fd0e1c2L,\n        0xb209f11337f1dc76L } },\n    /* 61 << 7 */\n    { { 0xefcc5e0697bf1298L,0xcbdb6730219d639eL,0xd009c116b81e8c6fL,\n        0xa3ffdde31a7ce2e5L },\n      { 0xc53fbaaaa914d3baL,0x836d500f88df85eeL,0xd98dc71b66ee0751L,\n        0x5a3d7005714516fdL } },\n    /* 62 << 7 */\n    { { 0x21d3634d39eedbbaL,0x35cd2e680455a46dL,0xc8cafe65f9d7eb0cL,\n        0xbda3ce9e00cefb3eL },\n      { 0xddc17a602c9cf7a4L,0x01572ee47bcb8773L,0xa92b2b018c7548dfL,\n        0x732fd309a84600e3L } },\n    /* 63 << 7 */\n    { { 0xe22109c716543a40L,0x9acafd36fede3c6cL,0xfb2068526824e614L,\n        0x2a4544a9da25dca0L },\n      { 0x2598526291d60b06L,0x281b7be928753545L,0xec667b1a90f13b27L,\n        0x33a83aff940e2eb4L } },\n    /* 64 << 7 */\n    { { 0x80009862d5d721d5L,0x0c3357a35bd3a182L,0x27f3a83b7aa2cda4L,\n        0xb58ae74ef6f83085L },\n      { 0x2a911a812e6dad6bL,0xde286051f43d6c5bL,0x4bdccc41f996c4d8L,\n        0xe7312ec00ae1e24eL } },\n    /* 0 << 14 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 14 */\n    { { 0xf8d112e76e6485b3L,0x4d3e24db771c52f8L,0x48e3ee41684a2f6dL,\n        0x7161957d21d95551L },\n      { 0x19631283cdb12a6cL,0xbf3fa8822e50e164L,0xf6254b633166cc73L,\n        0x3aefa7aeaee8cc38L } },\n    /* 2 << 14 */\n    { { 0x79b0fe623b36f9fdL,0x26543b23fde19fc0L,0x136e64a0958482efL,\n        0x23f637719b095825L },\n      { 0x14cfd596b6a1142eL,0x5ea6aac6335aac0bL,0x86a0e8bdf3081dd5L,\n        0x5fb89d79003dc12aL } },\n    /* 3 << 14 */\n    { { 0xf615c33af72e34d4L,0x0bd9ea40110eec35L,0x1c12bc5bc1dea34eL,\n        0x686584c949ae4699L },\n      { 0x13ad95d38c97b942L,0x4609561a4e5c7562L,0x9e94a4aef2737f89L,\n        0xf57594c6371c78b6L } },\n    /* 4 << 14 */\n    { { 0x0f0165fce3779ee3L,0xe00e7f9dbd495d9eL,0x1fa4efa220284e7aL,\n        0x4564bade47ac6219L },\n      { 0x90e6312ac4708e8eL,0x4f5725fba71e9adfL,0xe95f55ae3d684b9fL,\n        0x47f7ccb11e94b415L } },\n    /* 5 << 14 */\n    { { 0x7322851b8d946581L,0xf0d13133bdf4a012L,0xa3510f696584dae0L,\n        0x03a7c1713c9f6c6dL },\n      { 0x5be97f38e475381aL,0xca1ba42285823334L,0xf83cc5c70be17ddaL,\n        0x158b14940b918c0fL } },\n    /* 6 << 14 */\n    { { 0xda3a77e5522e6b69L,0x69c908c3bbcd6c18L,0x1f1b9e48d924fd56L,\n        0x37c64e36aa4bb3f7L },\n      { 0x5a4fdbdfee478d7dL,0xba75c8bc0193f7a0L,0x84bc1e8456cd16dfL,\n        0x1fb08f0846fad151L } },\n    /* 7 << 14 */\n    { { 0x8a7cabf9842e9f30L,0xa331d4bf5eab83afL,0xd272cfba017f2a6aL,\n        0x27560abc83aba0e3L },\n      { 0x94b833870e3a6b75L,0x25c6aea26b9f50f5L,0x803d691db5fdf6d0L,\n        0x03b77509e6333514L } },\n    /* 8 << 14 */\n    { { 0x3617890361a341c1L,0x3604dc600cfd6142L,0x022295eb8533316cL,\n        0x3dbde4ac44af2922L },\n      { 0x898afc5d1c7eef69L,0x58896805d14f4fa1L,0x05002160203c21caL,\n        0x6f0d1f3040ef730bL } },\n    /* 9 << 14 */\n    { { 0x8e8c44d4196224f8L,0x75a4ab95374d079dL,0x79085ecc7d48f123L,\n        0x56f04d311bf65ad8L },\n      { 0xe220bf1cbda602b2L,0x73ee1742f9612c69L,0x76008fc8084fd06bL,\n        0x4000ef9ff11380d1L } },\n    /* 10 << 14 */\n    { { 0x48201b4b12cfe297L,0x3eee129c292f74e5L,0xe1fe114ec9e874e8L,\n        0x899b055c92c5fc41L },\n      { 0x4e477a643a39c8cfL,0x82f09efe78963cc9L,0x6fd3fd8fd333f863L,\n        0x85132b2adc949c63L } },\n    /* 11 << 14 */\n    { { 0x7e06a3ab516eb17bL,0x73bec06fd2c7372bL,0xe4f74f55ba896da6L,\n        0xbb4afef88e9eb40fL },\n      { 0x2d75bec8e61d66b0L,0x02bda4b4ef29300bL,0x8bbaa8de026baa5aL,\n        0xff54befda07f4440L } },\n    /* 12 << 14 */\n    { { 0xbd9b8b1dbe7a2af3L,0xec51caa94fb74a72L,0xb9937a4b63879697L,\n        0x7c9a9d20ec2687d5L },\n      { 0x1773e44f6ef5f014L,0x8abcf412e90c6900L,0x387bd0228142161eL,\n        0x50393755fcb6ff2aL } },\n    /* 13 << 14 */\n    { { 0x9813fd56ed6def63L,0x53cf64827d53106cL,0x991a35bd431f7ac1L,\n        0xf1e274dd63e65fafL },\n      { 0xf63ffa3c44cc7880L,0x411a426b7c256981L,0xb698b9fd93a420e0L,\n        0x89fdddc0ae53f8feL } },\n    /* 14 << 14 */\n    { { 0x766e072232398baaL,0x205fee425cfca031L,0xa49f53417a029cf2L,\n        0xa88c68b84023890dL },\n      { 0xbc2750417337aaa8L,0x9ed364ad0eb384f4L,0xe0816f8529aba92fL,\n        0x2e9e194104e38a88L } },\n    /* 15 << 14 */\n    { { 0x57eef44a3dafd2d5L,0x35d1fae597ed98d8L,0x50628c092307f9b1L,\n        0x09d84aaed6cba5c6L },\n      { 0x67071bc788aaa691L,0x2dea57a9afe6cb03L,0xdfe11bb43d78ac01L,\n        0x7286418c7fd7aa51L } },\n    /* 16 << 14 */\n    { { 0xfabf770977f7195aL,0x8ec86167adeb838fL,0xea1285a8bb4f012dL,\n        0xd68835039a3eab3fL },\n      { 0xee5d24f8309004c2L,0xa96e4b7613ffe95eL,0x0cdffe12bd223ea4L,\n        0x8f5c2ee5b6739a53L } },\n    /* 17 << 14 */\n    { { 0x5cb4aaa5dd968198L,0xfa131c5272413a6cL,0x53d46a909536d903L,\n        0xb270f0d348606d8eL },\n      { 0x518c7564a053a3bcL,0x088254b71a86caefL,0xb3ba8cb40ab5efd0L,\n        0x5c59900e4605945dL } },\n    /* 18 << 14 */\n    { { 0xecace1dda1887395L,0x40960f36932a65deL,0x9611ff5c3aa95529L,\n        0xc58215b07c1e5a36L },\n      { 0xd48c9b58f0e1a524L,0xb406856bf590dfb8L,0xc7605e049cd95662L,\n        0x0dd036eea33ecf82L } },\n    /* 19 << 14 */\n    { { 0xa50171acc33156b3L,0xf09d24ea4a80172eL,0x4e1f72c676dc8eefL,\n        0xe60caadc5e3d44eeL },\n      { 0x006ef8a6979b1d8fL,0x60908a1c97788d26L,0x6e08f95b266feec0L,\n        0x618427c222e8c94eL } },\n    /* 20 << 14 */\n    { { 0x3d61333959145a65L,0xcd9bc368fa406337L,0x82d11be32d8a52a0L,\n        0xf6877b2797a1c590L },\n      { 0x837a819bf5cbdb25L,0x2a4fd1d8de090249L,0x622a7de774990e5fL,\n        0x840fa5a07945511bL } },\n    /* 21 << 14 */\n    { { 0x30b974be6558842dL,0x70df8c6417f3d0a6L,0x7c8035207542e46dL,\n        0x7251fe7fe4ecc823L },\n      { 0xe59134cb5e9aac9aL,0x11bb0934f0045d71L,0x53e5d9b5dbcb1d4eL,\n        0x8d97a90592defc91L } },\n    /* 22 << 14 */\n    { { 0xfe2893277946d3f9L,0xe132bd2407472273L,0xeeeb510c1eb6ae86L,\n        0x777708c5f0595067L },\n      { 0x18e2c8cd1297029eL,0x2c61095cbbf9305eL,0xe466c2586b85d6d9L,\n        0x8ac06c36da1ea530L } },\n    /* 23 << 14 */\n    { { 0xa365dc39a1304668L,0xe4a9c88507f89606L,0x65a4898facc7228dL,\n        0x3e2347ff84ca8303L },\n      { 0xa5f6fb77ea7d23a3L,0x2fac257d672a71cdL,0x6908bef87e6a44d3L,\n        0x8ff87566891d3d7aL } },\n    /* 24 << 14 */\n    { { 0xe58e90b36b0cf82eL,0x6438d2462615b5e7L,0x07b1f8fc669c145aL,\n        0xb0d8b2da36f1e1cbL },\n      { 0x54d5dadbd9184c4dL,0x3dbb18d5f93d9976L,0x0a3e0f56d1147d47L,\n        0x2afa8c8da0a48609L } },\n    /* 25 << 14 */\n    { { 0x275353e8bc36742cL,0x898f427eeea0ed90L,0x26f4947e3e477b00L,\n        0x8ad8848a308741e3L },\n      { 0x6c703c38d74a2a46L,0x5e3e05a99ba17ba2L,0xc1fa6f664ab9a9e4L,\n        0x474a2d9a3841d6ecL } },\n    /* 26 << 14 */\n    { { 0x871239ad653ae326L,0x14bcf72aa74cbb43L,0x8737650e20d4c083L,\n        0x3df86536110ed4afL },\n      { 0xd2d86fe7b53ca555L,0x688cb00dabd5d538L,0xcf81bda31ad38468L,\n        0x7ccfe3ccf01167b6L } },\n    /* 27 << 14 */\n    { { 0xcf4f47e06c4c1fe6L,0x557e1f1a298bbb79L,0xf93b974f30d45a14L,\n        0x174a1d2d0baf97c4L },\n      { 0x7a003b30c51fbf53L,0xd8940991ee68b225L,0x5b0aa7b71c0f4173L,\n        0x975797c9a20a7153L } },\n    /* 28 << 14 */\n    { { 0x26e08c07e3533d77L,0xd7222e6a2e341c99L,0x9d60ec3d8d2dc4edL,\n        0xbdfe0d8f7c476cf8L },\n      { 0x1fe59ab61d056605L,0xa9ea9df686a8551fL,0x8489941e47fb8d8cL,\n        0xfeb874eb4a7f1b10L } },\n    /* 29 << 14 */\n    { { 0xfe5fea867ee0d98fL,0x201ad34bdbf61864L,0x45d8fe4737c031d4L,\n        0xd5f49fae795f0822L },\n      { 0xdb0fb291c7f4a40cL,0x2e69d9c1730ddd92L,0x754e105449d76987L,\n        0x8a24911d7662db87L } },\n    /* 30 << 14 */\n    { { 0x61fc181060a71676L,0xe852d1a8f66a8ad1L,0x172bbd656417231eL,\n        0x0d6de7bd3babb11fL },\n      { 0x6fde6f88c8e347f8L,0x1c5875479bd99cc3L,0x78e54ed034076950L,\n        0x97f0f334796e83baL } },\n    /* 31 << 14 */\n    { { 0xe4dbe1ce4924867aL,0xbd5f51b060b84917L,0x375300403cb09a79L,\n        0xdb3fe0f8ff1743d8L },\n      { 0xed7894d8556fa9dbL,0xfa26216923412fbfL,0x563be0dbba7b9291L,\n        0x6ca8b8c00c9fb234L } },\n    /* 32 << 14 */\n    { { 0xed406aa9bd763802L,0xc21486a065303da1L,0x61ae291ec7e62ec4L,\n        0x622a0492df99333eL },\n      { 0x7fd80c9dbb7a8ee0L,0xdc2ed3bc6c01aedbL,0x35c35a1208be74ecL,\n        0xd540cb1a469f671fL } },\n    /* 33 << 14 */\n    { { 0xd16ced4ecf84f6c7L,0x8561fb9c2d090f43L,0x7e693d796f239db4L,\n        0xa736f92877bd0d94L },\n      { 0x07b4d9292c1950eeL,0xda17754356dc11b3L,0xa5dfbbaa7a6a878eL,\n        0x1c70cb294decb08aL } },\n    /* 34 << 14 */\n    { { 0xfba28c8b6f0f7c50L,0xa8eba2b8854dcc6dL,0x5ff8e89a36b78642L,\n        0x070c1c8ef6873adfL },\n      { 0xbbd3c3716484d2e4L,0xfb78318f0d414129L,0x2621a39c6ad93b0bL,\n        0x979d74c2a9e917f7L } },\n    /* 35 << 14 */\n    { { 0xfc19564761fb0428L,0x4d78954abee624d4L,0xb94896e0b8ae86fdL,\n        0x6667ac0cc91c8b13L },\n      { 0x9f18051243bcf832L,0xfbadf8b7a0010137L,0xc69b4089b3ba8aa7L,\n        0xfac4bacde687ce85L } },\n    /* 36 << 14 */\n    { { 0x9164088d977eab40L,0x51f4c5b62760b390L,0xd238238f340dd553L,\n        0x358566c3db1d31c9L },\n      { 0x3a5ad69e5068f5ffL,0xf31435fcdaff6b06L,0xae549a5bd6debff0L,\n        0x59e5f0b775e01331L } },\n    /* 37 << 14 */\n    { { 0x5d492fb898559acfL,0x96018c2e4db79b50L,0x55f4a48f609f66aaL,\n        0x1943b3af4900a14fL },\n      { 0xc22496df15a40d39L,0xb2a446844c20f7c5L,0x76a35afa3b98404cL,\n        0xbec75725ff5d1b77L } },\n    /* 38 << 14 */\n    { { 0xb67aa163bea06444L,0x27e95bb2f724b6f2L,0x3c20e3e9d238c8abL,\n        0x1213754eddd6ae17L },\n      { 0x8c431020716e0f74L,0x6679c82effc095c2L,0x2eb3adf4d0ac2932L,\n        0x2cc970d301bb7a76L } },\n    /* 39 << 14 */\n    { { 0x70c71f2f740f0e66L,0x545c616b2b6b23ccL,0x4528cfcbb40a8bd7L,\n        0xff8396332ab27722L },\n      { 0x049127d9025ac99aL,0xd314d4a02b63e33bL,0xc8c310e728d84519L,\n        0x0fcb8983b3bc84baL } },\n    /* 40 << 14 */\n    { { 0x2cc5226138634818L,0x501814f4b44c2e0bL,0xf7e181aa54dfdba3L,\n        0xcfd58ff0e759718cL },\n      { 0xf90cdb14d3b507a8L,0x57bd478ec50bdad8L,0x29c197e250e5f9aaL,\n        0x4db6eef8e40bc855L } },\n    /* 41 << 14 */\n    { { 0x2cc8f21ad1fc0654L,0xc71cc96381269d73L,0xecfbb204077f49f9L,\n        0xdde92571ca56b793L },\n      { 0x9abed6a3f97ad8f7L,0xe6c19d3f924de3bdL,0x8dce92f4a140a800L,\n        0x85f44d1e1337af07L } },\n    /* 42 << 14 */\n    { { 0x5953c08b09d64c52L,0xa1b5e49ff5df9749L,0x336a8fb852735f7dL,\n        0xb332b6db9add676bL },\n      { 0x558b88a0b4511aa4L,0x09788752dbd5cc55L,0x16b43b9cd8cd52bdL,\n        0x7f0bc5a0c2a2696bL } },\n    /* 43 << 14 */\n    { { 0x146e12d4c11f61efL,0x9ce107543a83e79eL,0x08ec73d96cbfca15L,\n        0x09ff29ad5b49653fL },\n      { 0xe31b72bde7da946eL,0xebf9eb3bee80a4f2L,0xd1aabd0817598ce4L,\n        0x18b5fef453f37e80L } },\n    /* 44 << 14 */\n    { { 0xd5d5cdd35958cd79L,0x3580a1b51d373114L,0xa36e4c91fa935726L,\n        0xa38c534def20d760L },\n      { 0x7088e40a2ff5845bL,0xe5bb40bdbd78177fL,0x4f06a7a8857f9920L,\n        0xe3cc3e50e968f05dL } },\n    /* 45 << 14 */\n    { { 0x1d68b7fee5682d26L,0x5206f76faec7f87cL,0x41110530041951abL,\n        0x58ec52c1d4b5a71aL },\n      { 0xf3488f990f75cf9aL,0xf411951fba82d0d5L,0x27ee75be618895abL,\n        0xeae060d46d8aab14L } },\n    /* 46 << 14 */\n    { { 0x9ae1df737fb54dc2L,0x1f3e391b25963649L,0x242ec32afe055081L,\n        0x5bd450ef8491c9bdL },\n      { 0x367efc67981eb389L,0xed7e19283a0550d5L,0x362e776bab3ce75cL,\n        0xe890e3081f24c523L } },\n    /* 47 << 14 */\n    { { 0xb961b682feccef76L,0x8b8e11f58bba6d92L,0x8f2ccc4c2b2375c4L,\n        0x0d7f7a52e2f86cfaL },\n      { 0xfd94d30a9efe5633L,0x2d8d246b5451f934L,0x2234c6e3244e6a00L,\n        0xde2b5b0dddec8c50L } },\n    /* 48 << 14 */\n    { { 0x2ce53c5abf776f5bL,0x6f72407160357b05L,0xb259371771bf3f7aL,\n        0x87d2501c440c4a9fL },\n      { 0x440552e187b05340L,0xb7bf7cc821624c32L,0x4155a6ce22facddbL,\n        0x5a4228cb889837efL } },\n    /* 49 << 14 */\n    { { 0xef87d6d6fd4fd671L,0xa233687ec2daa10eL,0x7562224403c0eb96L,\n        0x7632d1848bf19be6L },\n      { 0x05d0f8e940735ff4L,0x3a3e6e13c00931f1L,0x31ccde6adafe3f18L,\n        0xf381366acfe51207L } },\n    /* 50 << 14 */\n    { { 0x24c222a960167d92L,0x62f9d6f87529f18cL,0x412397c00353b114L,\n        0x334d89dcef808043L },\n      { 0xd9ec63ba2a4383ceL,0xcec8e9375cf92ba0L,0xfb8b4288c8be74c0L,\n        0x67d6912f105d4391L } },\n    /* 51 << 14 */\n    { { 0x7b996c461b913149L,0x36aae2ef3a4e02daL,0xb68aa003972de594L,\n        0x284ec70d4ec6d545L },\n      { 0xf3d2b2d061391d54L,0x69c5d5d6fe114e92L,0xbe0f00b5b4482dffL,\n        0xe1596fa5f5bf33c5L } },\n    /* 52 << 14 */\n    { { 0x10595b5696a71cbaL,0x944938b2fdcadeb7L,0xa282da4cfccd8471L,\n        0x98ec05f30d37bfe1L },\n      { 0xe171ce1b0698304aL,0x2d69144421bdf79bL,0xd0cd3b741b21dec1L,\n        0x712ecd8b16a15f71L } },\n    /* 53 << 14 */\n    { { 0x8d4c00a700fd56e1L,0x02ec9692f9527c18L,0x21c449374a3e42e1L,\n        0x9176fbab1392ae0aL },\n      { 0x8726f1ba44b7b618L,0xb4d7aae9f1de491cL,0xf91df7b907b582c0L,\n        0x7e116c30ef60aa3aL } },\n    /* 54 << 14 */\n    { { 0x99270f81466265d7L,0xb15b6fe24df7adf0L,0xfe33b2d3f9738f7fL,\n        0x48553ab9d6d70f95L },\n      { 0x2cc72ac8c21e94dbL,0x795ac38dbdc0bbeeL,0x0a1be4492e40478fL,\n        0x81bd3394052bde55L } },\n    /* 55 << 14 */\n    { { 0x63c8dbe956b3c4f2L,0x017a99cf904177ccL,0x947bbddb4d010fc1L,\n        0xacf9b00bbb2c9b21L },\n      { 0x2970bc8d47173611L,0x1a4cbe08ac7d756fL,0x06d9f4aa67d541a2L,\n        0xa3e8b68959c2cf44L } },\n    /* 56 << 14 */\n    { { 0xaad066da4d88f1ddL,0xc604f1657ad35deaL,0x7edc07204478ca67L,\n        0xa10dfae0ba02ce06L },\n      { 0xeceb1c76af36f4e4L,0x994b2292af3f8f48L,0xbf9ed77b77c8a68cL,\n        0x74f544ea51744c9dL } },\n    /* 57 << 14 */\n    { { 0x82d05bb98113a757L,0x4ef2d2b48a9885e4L,0x1e332be51aa7865fL,\n        0x22b76b18290d1a52L },\n      { 0x308a231044351683L,0x9d861896a3f22840L,0x5959ddcd841ed947L,\n        0x0def0c94154b73bfL } },\n    /* 58 << 14 */\n    { { 0xf01054174c7c15e0L,0x539bfb023a277c32L,0xe699268ef9dccf5fL,\n        0x9f5796a50247a3bdL },\n      { 0x8b839de84f157269L,0xc825c1e57a30196bL,0x6ef0aabcdc8a5a91L,\n        0xf4a8ce6c498b7fe6L } },\n    /* 59 << 14 */\n    { { 0x1cce35a770cbac78L,0x83488e9bf6b23958L,0x0341a070d76cb011L,\n        0xda6c9d06ae1b2658L },\n      { 0xb701fb30dd648c52L,0x994ca02c52fb9fd1L,0x069331176f563086L,\n        0x3d2b810017856babL } },\n    /* 60 << 14 */\n    { { 0xe89f48c85963a46eL,0x658ab875a99e61c7L,0x6e296f874b8517b4L,\n        0x36c4fcdcfc1bc656L },\n      { 0xde5227a1a3906defL,0x9fe95f5762418945L,0x20c91e81fdd96cdeL,\n        0x5adbe47eda4480deL } },\n    /* 61 << 14 */\n    { { 0xa009370f396de2b6L,0x98583d4bf0ecc7bdL,0xf44f6b57e51d0672L,\n        0x03d6b078556b1984L },\n      { 0x27dbdd93b0b64912L,0x9b3a343415687b09L,0x0dba646151ec20a9L,\n        0xec93db7fff28187cL } },\n    /* 62 << 14 */\n    { { 0x00ff8c2466e48bddL,0x2514f2f911ccd78eL,0xeba11f4fe1250603L,\n        0x8a22cd41243fa156L },\n      { 0xa4e58df4b283e4c6L,0x78c298598b39783fL,0x5235aee2a5259809L,\n        0xc16284b50e0227ddL } },\n    /* 63 << 14 */\n    { { 0xa5f579161338830dL,0x6d4b8a6bd2123fcaL,0x236ea68af9c546f8L,\n        0xc1d36873fa608d36L },\n      { 0xcd76e4958d436d13L,0xd4d9c2218fb080afL,0x665c1728e8ad3fb5L,\n        0xcf1ebe4db3d572e0L } },\n    /* 64 << 14 */\n    { { 0xa7a8746a584c5e20L,0x267e4ea1b9dc7035L,0x593a15cfb9548c9bL,\n        0x5e6e21354bd012f3L },\n      { 0xdf31cc6a8c8f936eL,0x8af84d04b5c241dcL,0x63990a6f345efb86L,\n        0x6fef4e61b9b962cbL } },\n    /* 0 << 21 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 21 */\n    { { 0xf6368f0925722608L,0x131260db131cf5c6L,0x40eb353bfab4f7acL,\n        0x85c7888037eee829L },\n      { 0x4c1581ffc3bdf24eL,0x5bff75cbf5c3c5a8L,0x35e8c83fa14e6f40L,\n        0xb81d1c0f0295e0caL } },\n    /* 2 << 21 */\n    { { 0xfcde7cc8f43a730fL,0xe89b6f3c33ab590eL,0xc823f529ad03240bL,\n        0x82b79afe98bea5dbL },\n      { 0x568f2856962fe5deL,0x0c590adb60c591f3L,0x1fc74a144a28a858L,\n        0x3b662498b3203f4cL } },\n    /* 3 << 21 */\n    { { 0x91e3cf0d6c39765aL,0xa2db3acdac3cca0bL,0x288f2f08cb953b50L,\n        0x2414582ccf43cf1aL },\n      { 0x8dec8bbc60eee9a8L,0x54c79f02729aa042L,0xd81cd5ec6532f5d5L,\n        0xa672303acf82e15fL } },\n    /* 4 << 21 */\n    { { 0x376aafa8719c0563L,0xcd8ad2dcbc5fc79fL,0x303fdb9fcb750cd3L,\n        0x14ff052f4418b08eL },\n      { 0xf75084cf3e2d6520L,0x7ebdf0f8144ed509L,0xf43bf0f2d3f25b98L,\n        0x86ad71cfa354d837L } },\n    /* 5 << 21 */\n    { { 0xb827fe9226f43572L,0xdfd3ab5b5d824758L,0x315dd23a539094c1L,\n        0x85c0e37a66623d68L },\n      { 0x575c79727be19ae0L,0x616a3396df0d36b5L,0xa1ebb3c826b1ff7eL,\n        0x635b9485140ad453L } },\n    /* 6 << 21 */\n    { { 0x92bf3cdada430c0bL,0x4702850e3a96dac6L,0xc91cf0a515ac326aL,\n        0x95de4f49ab8c25e4L },\n      { 0xb01bad09e265c17cL,0x24e45464087b3881L,0xd43e583ce1fac5caL,\n        0xe17cb3186ead97a6L } },\n    /* 7 << 21 */\n    { { 0x6cc3924374dcec46L,0x33cfc02d54c2b73fL,0x82917844f26cd99cL,\n        0x8819dd95d1773f89L },\n      { 0x09572aa60871f427L,0x8e0cf365f6f01c34L,0x7fa52988bff1f5afL,\n        0x4eb357eae75e8e50L } },\n    /* 8 << 21 */\n    { { 0xd9d0c8c4868af75dL,0xd7325cff45c8c7eaL,0xab471996cc81ecb0L,\n        0xff5d55f3611824edL },\n      { 0xbe3145411977a0eeL,0x5085c4c5722038c6L,0x2d5335bff94bb495L,\n        0x894ad8a6c8e2a082L } },\n    /* 9 << 21 */\n    { { 0x5c3e2341ada35438L,0xf4a9fc89049b8c4eL,0xbeeb355a9f17cf34L,\n        0x3f311e0e6c91fe10L },\n      { 0xc2d2003892ab9891L,0x257bdcc13e8ce9a9L,0x1b2d978988c53beeL,\n        0x927ce89acdba143aL } },\n    /* 10 << 21 */\n    { { 0xb0a32cca523db280L,0x5c889f8a50d43783L,0x503e04b34897d16fL,\n        0x8cdb6e7808f5f2e8L },\n      { 0x6ab91cf0179c8e74L,0xd8874e5248211d60L,0xf948d4d5ea851200L,\n        0x4076d41ee6f9840aL } },\n    /* 11 << 21 */\n    { { 0xc20e263c47b517eaL,0x79a448fd30685e5eL,0xe55f6f78f90631a0L,\n        0x88a790b1a79e6346L },\n      { 0x62160c7d80969fe8L,0x54f92fd441491bb9L,0xa6645c235c957526L,\n        0xf44cc5aebea3ce7bL } },\n    /* 12 << 21 */\n    { { 0xf76283278b1e68b7L,0xc731ad7a303f29d3L,0xfe5a9ca957d03ecbL,\n        0x96c0d50c41bc97a7L },\n      { 0xc4669fe79b4f7f24L,0xfdd781d83d9967efL,0x7892c7c35d2c208dL,\n        0x8bf64f7cae545cb3L } },\n    /* 13 << 21 */\n    { { 0xc01f862c467be912L,0xf4c85ee9c73d30ccL,0x1fa6f4be6ab83ec7L,\n        0xa07a3c1c4e3e3cf9L },\n      { 0x87f8ef450c00beb3L,0x30e2c2b3000d4c3eL,0x1aa00b94fe08bf5bL,\n        0x32c133aa9224ef52L } },\n    /* 14 << 21 */\n    { { 0x38df16bb32e5685dL,0x68a9e06958e6f544L,0x495aaff7cdc5ebc6L,\n        0xf894a645378b135fL },\n      { 0xf316350a09e27ecfL,0xeced201e58f7179dL,0x2eec273ce97861baL,\n        0x47ec2caed693be2eL } },\n    /* 15 << 21 */\n    { { 0xfa4c97c4f68367ceL,0xe4f47d0bbe5a5755L,0x17de815db298a979L,\n        0xd7eca659c177dc7dL },\n      { 0x20fdbb7149ded0a3L,0x4cb2aad4fb34d3c5L,0x2cf31d2860858a33L,\n        0x3b6873efa24aa40fL } },\n    /* 16 << 21 */\n    { { 0x540234b22c11bb37L,0x2d0366dded4c74a3L,0xf9a968daeec5f25dL,\n        0x3660106867b63142L },\n      { 0x07cd6d2c68d7b6d4L,0xa8f74f090c842942L,0xe27514047768b1eeL,\n        0x4b5f7e89fe62aee4L } },\n    /* 17 << 21 */\n    { { 0xc6a7717789070d26L,0xa1f28e4edd1c8bc7L,0xea5f4f06469e1f17L,\n        0x78fc242afbdb78e0L },\n      { 0xc9c7c5928b0588f1L,0xb6b7a0fd1535921eL,0xcc5bdb91bde5ae35L,\n        0xb42c485e12ff1864L } },\n    /* 18 << 21 */\n    { { 0xa1113e13dbab98aaL,0xde9d469ba17b1024L,0x23f48b37c0462d3aL,\n        0x3752e5377c5c078dL },\n      { 0xe3a86add15544eb9L,0xf013aea780fba279L,0x8b5bb76cf22001b5L,\n        0xe617ba14f02891abL } },\n    /* 19 << 21 */\n    { { 0xd39182a6936219d3L,0x5ce1f194ae51cb19L,0xc78f8598bf07a74cL,\n        0x6d7158f222cbf1bcL },\n      { 0x3b846b21e300ce18L,0x35fba6302d11275dL,0x5fe25c36a0239b9bL,\n        0xd8beb35ddf05d940L } },\n    /* 20 << 21 */\n    { { 0x4db02bb01f7e320dL,0x0641c3646da320eaL,0x6d95fa5d821389a3L,\n        0x926997488fcd8e3dL },\n      { 0x316fef17ceb6c143L,0x67fcb841d933762bL,0xbb837e35118b17f8L,\n        0x4b92552f9fd24821L } },\n    /* 21 << 21 */\n    { { 0xae6bc70e46aca793L,0x1cf0b0e4e579311bL,0x8dc631be5802f716L,\n        0x099bdc6fbddbee4dL },\n      { 0xcc352bb20caf8b05L,0xf74d505a72d63df2L,0xb9876d4b91c4f408L,\n        0x1ce184739e229b2dL } },\n    /* 22 << 21 */\n    { { 0x4950759783abdb4aL,0x850fbcb6dee84b18L,0x6325236e609e67dcL,\n        0x04d831d99336c6d8L },\n      { 0x8deaae3bfa12d45dL,0xe425f8ce4746e246L,0x8004c17524f5f31eL,\n        0xaca16d8fad62c3b7L } },\n    /* 23 << 21 */\n    { { 0x0dc15a6a9152f934L,0xf1235e5ded0e12c1L,0xc33c06ecda477dacL,\n        0x76be8732b2ea0006L },\n      { 0xcf3f78310c0cd313L,0x3c524553a614260dL,0x31a756f8cab22d15L,\n        0x03ee10d177827a20L } },\n    /* 24 << 21 */\n    { { 0xd1e059b21994ef20L,0x2a653b69638ae318L,0x70d5eb582f699010L,\n        0x279739f709f5f84aL },\n      { 0x5da4663c8b799336L,0xfdfdf14d203c37ebL,0x32d8a9dca1dbfb2dL,\n        0xab40cff077d48f9bL } },\n    /* 25 << 21 */\n    { { 0xc018b383d20b42d5L,0xf9a810ef9f78845fL,0x40af3753bdba9df0L,\n        0xb90bdcfc131dfdf9L },\n      { 0x18720591f01ab782L,0xc823f2116af12a88L,0xa51b80f30dc14401L,\n        0xde248f77fb2dfbe3L } },\n    /* 26 << 21 */\n    { { 0xef5a44e50cafe751L,0x73997c9cd4dcd221L,0x32fd86d1de854024L,\n        0xd5b53adca09b84bbL },\n      { 0x008d7a11dcedd8d1L,0x406bd1c874b32c84L,0x5d4472ff05dde8b1L,\n        0x2e25f2cdfce2b32fL } },\n    /* 27 << 21 */\n    { { 0xbec0dd5e29dfc254L,0x4455fcf62b98b267L,0x0b4d43a5c72df2adL,\n        0xea70e6be48a75397L },\n      { 0x2aad61695820f3bfL,0xf410d2dd9e37f68fL,0x70fb7dba7be5ac83L,\n        0x636bb64536ec3eecL } },\n    /* 28 << 21 */\n    { { 0x27104ea39754e21cL,0xbc87a3e68d63c373L,0x483351d74109db9aL,\n        0x0fa724e360134da7L },\n      { 0x9ff44c29b0720b16L,0x2dd0cf1306aceeadL,0x5942758ce26929a6L,\n        0x96c5db92b766a92bL } },\n    /* 29 << 21 */\n    { { 0xcec7d4c05f18395eL,0xd3f227441f80d032L,0x7a68b37acb86075bL,\n        0x074764ddafef92dbL },\n      { 0xded1e9507bc7f389L,0xc580c850b9756460L,0xaeeec2a47da48157L,\n        0x3f0b4e7f82c587b3L } },\n    /* 30 << 21 */\n    { { 0x231c6de8a9f19c53L,0x5717bd736974e34eL,0xd9e1d216f1508fa9L,\n        0x9f112361dadaa124L },\n      { 0x80145e31823b7348L,0x4dd8f0d5ac634069L,0xe3d82fc72297c258L,\n        0x276fcfee9cee7431L } },\n    /* 31 << 21 */\n    { { 0x8eb61b5e2bc0aea9L,0x4f668fd5de329431L,0x03a32ab138e4b87eL,\n        0xe137451773d0ef0bL },\n      { 0x1a46f7e6853ac983L,0xc3bdf42e68e78a57L,0xacf207852ea96dd1L,\n        0xa10649b9f1638460L } },\n    /* 32 << 21 */\n    { { 0xf2369f0b879fbbedL,0x0ff0ae86da9d1869L,0x5251d75956766f45L,\n        0x4984d8c02be8d0fcL },\n      { 0x7ecc95a6d21008f0L,0x29bd54a03a1a1c49L,0xab9828c5d26c50f3L,\n        0x32c0087c51d0d251L } },\n    /* 33 << 21 */\n    { { 0x9bac3ce60c1cdb26L,0xcd94d947557ca205L,0x1b1bd5989db1fdcdL,\n        0x0eda0108a3d8b149L },\n      { 0x9506661056152fccL,0xc2f037e6e7192b33L,0xdeffb41ac92e05a4L,\n        0x1105f6c2c2f6c62eL } },\n    /* 34 << 21 */\n    { { 0x68e735008733913cL,0xcce861633f3adc40L,0xf407a94238a278e9L,\n        0xd13c1b9d2ab21292L },\n      { 0x93ed7ec71c74cf5cL,0x8887dc48f1a4c1b4L,0x3830ff304b3a11f1L,\n        0x358c5a3c58937cb6L } },\n    /* 35 << 21 */\n    { { 0x027dc40489022829L,0x40e939773b798f79L,0x90ad333738be6eadL,\n        0x9c23f6bcf34c0a5dL },\n      { 0xd1711a35fbffd8bbL,0x60fcfb491949d3ddL,0x09c8ef4b7825d93aL,\n        0x24233cffa0a8c968L } },\n    /* 36 << 21 */\n    { { 0x67ade46ce6d982afL,0xebb6bf3ee7544d7cL,0xd6b9ba763d8bd087L,\n        0x46fe382d4dc61280L },\n      { 0xbd39a7e8b5bdbd75L,0xab381331b8f228feL,0x0709a77cce1c4300L,\n        0x6a247e56f337ceacL } },\n    /* 37 << 21 */\n    { { 0x8f34f21b636288beL,0x9dfdca74c8a7c305L,0x6decfd1bea919e04L,\n        0xcdf2688d8e1991f8L },\n      { 0xe607df44d0f8a67eL,0xd985df4b0b58d010L,0x57f834c50c24f8f4L,\n        0xe976ef56a0bf01aeL } },\n    /* 38 << 21 */\n    { { 0x536395aca1c32373L,0x351027aa734c0a13L,0xd2f1b5d65e6bd5bcL,\n        0x2b539e24223debedL },\n      { 0xd4994cec0eaa1d71L,0x2a83381d661dcf65L,0x5f1aed2f7b54c740L,\n        0x0bea3fa5d6dda5eeL } },\n    /* 39 << 21 */\n    { { 0x9d4fb68436cc6134L,0x8eb9bbf3c0a443ddL,0xfc500e2e383b7d2aL,\n        0x7aad621c5b775257L },\n      { 0x69284d740a8f7cc0L,0xe820c2ce07562d65L,0xbf9531b9499758eeL,\n        0x73e95ca56ee0cc2dL } },\n    /* 40 << 21 */\n    { { 0xf61790abfbaf50a5L,0xdf55e76b684e0750L,0xec516da7f176b005L,\n        0x575553bb7a2dddc7L },\n      { 0x37c87ca3553afa73L,0x315f3ffc4d55c251L,0xe846442aaf3e5d35L,\n        0x61b911496495ff28L } },\n    /* 41 << 21 */\n    { { 0x23cc95d3fa326dc3L,0x1df4da1f18fc2ceaL,0x24bf9adcd0a37d59L,\n        0xb6710053320d6e1eL },\n      { 0x96f9667e618344d1L,0xcc7ce042a06445afL,0xa02d8514d68dbc3aL,\n        0x4ea109e4280b5a5bL } },\n    /* 42 << 21 */\n    { { 0x5741a7acb40961bfL,0x4ada59376aa56bfaL,0x7feb914502b765d1L,\n        0x561e97bee6ad1582L },\n      { 0xbbc4a5b6da3982f5L,0x0c2659edb546f468L,0xb8e7e6aa59612d20L,\n        0xd83dfe20ac19e8e0L } },\n    /* 43 << 21 */\n    { { 0x8530c45fb835398cL,0x6106a8bfb38a41c2L,0x21e8f9a635f5dcdbL,\n        0x39707137cae498edL },\n      { 0x70c23834d8249f00L,0x9f14b58fab2537a0L,0xd043c3655f61c0c2L,\n        0xdc5926d609a194a7L } },\n    /* 44 << 21 */\n    { { 0xddec03398e77738aL,0xd07a63effba46426L,0x2e58e79cee7f6e86L,\n        0xe59b0459ff32d241L },\n      { 0xc5ec84e520fa0338L,0x97939ac8eaff5aceL,0x0310a4e3b4a38313L,\n        0x9115fba28f9d9885L } },\n    /* 45 << 21 */\n    { { 0x8dd710c25fadf8c3L,0x66be38a2ce19c0e2L,0xd42a279c4cfe5022L,\n        0x597bb5300e24e1b8L },\n      { 0x3cde86b7c153ca7fL,0xa8d30fb3707d63bdL,0xac905f92bd60d21eL,\n        0x98e7ffb67b9a54abL } },\n    /* 46 << 21 */\n    { { 0xd7147df8e9726a30L,0xb5e216ffafce3533L,0xb550b7992ff1ec40L,\n        0x6b613b87a1e953fdL },\n      { 0x87b88dba792d5610L,0x2ee1270aa190fbe1L,0x02f4e2dc2ef581daL,\n        0x016530e4eff82a95L } },\n    /* 47 << 21 */\n    { { 0xcbb93dfd8fd6ee89L,0x16d3d98646848fffL,0x600eff241da47adfL,\n        0x1b9754a00ad47a71L },\n      { 0x8f9266df70c33b98L,0xaadc87aedf34186eL,0x0d2ce8e14ad24132L,\n        0x8a47cbfc19946ebaL } },\n    /* 48 << 21 */\n    { { 0x47feeb6662b5f3afL,0xcefab5610abb3734L,0x449de60e19f35cb1L,\n        0x39f8db14157f0eb9L },\n      { 0xffaecc5b3c61bfd6L,0xa5a4d41d41216703L,0x7f8fabed224e1cc2L,\n        0x0d5a8186871ad953L } },\n    /* 49 << 21 */\n    { { 0xf10774f7d22da9a9L,0x45b8a678cc8a9b0dL,0xd9c2e722bdc32cffL,\n        0xbf71b5f5337202a5L },\n      { 0x95c57f2f69fc4db9L,0xb6dad34c765d01e1L,0x7e0bd13fcb904635L,\n        0x61751253763a588cL } },\n    /* 50 << 21 */\n    { { 0xd85c299781af2c2dL,0xc0f7d9c481b9d7daL,0x838a34ae08533e8dL,\n        0x15c4cb08311d8311L },\n      { 0x97f832858e121e14L,0xeea7dc1e85000a5fL,0x0c6059b65d256274L,\n        0xec9beaceb95075c0L } },\n    /* 51 << 21 */\n    { { 0x173daad71df97828L,0xbf851cb5a8937877L,0xb083c59401646f3cL,\n        0x3bad30cf50c6d352L },\n      { 0xfeb2b202496bbceaL,0x3cf9fd4f18a1e8baL,0xd26de7ff1c066029L,\n        0x39c81e9e4e9ed4f8L } },\n    /* 52 << 21 */\n    { { 0xd8be0cb97b390d35L,0x01df2bbd964aab27L,0x3e8c1a65c3ef64f8L,\n        0x567291d1716ed1ddL },\n      { 0x95499c6c5f5406d3L,0x71fdda395ba8e23fL,0xcfeb320ed5096eceL,\n        0xbe7ba92bca66dd16L } },\n    /* 53 << 21 */\n    { { 0x4608d36bc6fb5a7dL,0xe3eea15a6d2dd0e0L,0x75b0a3eb8f97a36aL,\n        0xf59814cc1c83de1eL },\n      { 0x56c9c5b01c33c23fL,0xa96c1da46faa4136L,0x46bf2074de316551L,\n        0x3b866e7b1f756c8fL } },\n    /* 54 << 21 */\n    { { 0x727727d81495ed6bL,0xb2394243b682dce7L,0x8ab8454e758610f3L,\n        0xc243ce84857d72a4L },\n      { 0x7b320d71dbbf370fL,0xff9afa3778e0f7caL,0x0119d1e0ea7b523fL,\n        0xb997f8cb058c7d42L } },\n    /* 55 << 21 */\n    { { 0x285bcd2a37bbb184L,0x51dcec49a45d1fa6L,0x6ade3b64e29634cbL,\n        0x080c94a726b86ef1L },\n      { 0xba583db12283fbe3L,0x902bddc85a9315edL,0x07c1ccb386964becL,\n        0x78f4eacfb6258301L } },\n    /* 56 << 21 */\n    { { 0x4bdf3a4956f90823L,0xba0f5080741d777bL,0x091d71c3f38bf760L,\n        0x9633d50f9b625b02L },\n      { 0x03ecb743b8c9de61L,0xb47512545de74720L,0x9f9defc974ce1cb2L,\n        0x774a4f6a00bd32efL } },\n    /* 57 << 21 */\n    { { 0xaca385f773848f22L,0x53dad716f3f8558eL,0xab7b34b093c471f9L,\n        0xf530e06919644bc7L },\n      { 0x3d9fb1ffdd59d31aL,0x4382e0df08daa795L,0x165c6f4bd5cc88d7L,\n        0xeaa392d54a18c900L } },\n    /* 58 << 21 */\n    { { 0x94203c67648024eeL,0x188763f28c2fabcdL,0xa80f87acbbaec835L,\n        0x632c96e0f29d8d54L },\n      { 0x29b0a60e4c00a95eL,0x2ef17f40e011e9faL,0xf6c0e1d115b77223L,\n        0xaaec2c6214b04e32L } },\n    /* 59 << 21 */\n    { { 0xd35688d83d84e58cL,0x2af5094c958571dbL,0x4fff7e19760682a6L,\n        0x4cb27077e39a407cL },\n      { 0x0f59c5474ff0e321L,0x169f34a61b34c8ffL,0x2bff109652bc1ba7L,\n        0xa25423b783583544L } },\n    /* 60 << 21 */\n    { { 0x5d55d5d50ac8b782L,0xff6622ec2db3c892L,0x48fce7416b8bb642L,\n        0x31d6998c69d7e3dcL },\n      { 0xdbaf8004cadcaed0L,0x801b0142d81d053cL,0x94b189fc59630ec6L,\n        0x120e9934af762c8eL } },\n    /* 61 << 21 */\n    { { 0x53a29aa4fdc6a404L,0x19d8e01ea1909948L,0x3cfcabf1d7e89681L,\n        0x3321a50d4e132d37L },\n      { 0xd0496863e9a86111L,0x8c0cde6106a3bc65L,0xaf866c49fc9f8eefL,\n        0x2066350eff7f5141L } },\n    /* 62 << 21 */\n    { { 0x4f8a4689e56ddfbdL,0xea1b0c07fe32983aL,0x2b317462873cb8cbL,\n        0x658deddc2d93229fL },\n      { 0x65efaf4d0f64ef58L,0xfe43287d730cc7a8L,0xaebc0c723d047d70L,\n        0x92efa539d92d26c9L } },\n    /* 63 << 21 */\n    { { 0x06e7845794b56526L,0x415cb80f0961002dL,0x89e5c56576dcb10fL,\n        0x8bbb6982ff9259feL },\n      { 0x4fe8795b9abc2668L,0xb5d4f5341e678fb1L,0x6601f3be7b7da2b9L,\n        0x98da59e2a13d6805L } },\n    /* 64 << 21 */\n    { { 0x190d8ea601799a52L,0xa20cec41b86d2952L,0x3062ffb27fff2a7cL,\n        0x741b32e579f19d37L },\n      { 0xf80d81814eb57d47L,0x7a2d0ed416aef06bL,0x09735fb01cecb588L,\n        0x1641caaac6061f5bL } },\n    /* 0 << 28 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 28 */\n    { { 0x7f99824f20151427L,0x206828b692430206L,0xaa9097d7e1112357L,\n        0xacf9a2f209e414ecL },\n      { 0xdbdac9da27915356L,0x7e0734b7001efee3L,0x54fab5bbd2b288e2L,\n        0x4c630fc4f62dd09cL } },\n    /* 2 << 28 */\n    { { 0x8537107a1ac2703bL,0xb49258d86bc857b5L,0x57df14debcdaccd1L,\n        0x24ab68d7c4ae8529L },\n      { 0x7ed8b5d4734e59d0L,0x5f8740c8c495cc80L,0x84aedd5a291db9b3L,\n        0x80b360f84fb995beL } },\n    /* 3 << 28 */\n    { { 0xae915f5d5fa067d1L,0x4134b57f9668960cL,0xbd3656d6a48edaacL,\n        0xdac1e3e4fc1d7436L },\n      { 0x674ff869d81fbb26L,0x449ed3ecb26c33d4L,0x85138705d94203e8L,\n        0xccde538bbeeb6f4aL } },\n    /* 4 << 28 */\n    { { 0x55d5c68da61a76faL,0x598b441dca1554dcL,0xd39923b9773b279cL,\n        0x33331d3c36bf9efcL },\n      { 0x2d4c848e298de399L,0xcfdb8e77a1a27f56L,0x94c855ea57b8ab70L,\n        0xdcdb9dae6f7879baL } },\n    /* 5 << 28 */\n    { { 0x7bdff8c2019f2a59L,0xb3ce5bb3cb4fbc74L,0xea907f688a9173ddL,\n        0x6cd3d0d395a75439L },\n      { 0x92ecc4d6efed021cL,0x09a9f9b06a77339aL,0x87ca6b157188c64aL,\n        0x10c2996844899158L } },\n    /* 6 << 28 */\n    { { 0x5859a229ed6e82efL,0x16f338e365ebaf4eL,0x0cd313875ead67aeL,\n        0x1c73d22854ef0bb4L },\n      { 0x4cb5513174a5c8c7L,0x01cd29707f69ad6aL,0xa04d00dde966f87eL,\n        0xd96fe4470b7b0321L } },\n    /* 7 << 28 */\n    { { 0x342ac06e88fbd381L,0x02cd4a845c35a493L,0xe8fa89de54f1bbcdL,\n        0x341d63672575ed4cL },\n      { 0xebe357fbd238202bL,0x600b4d1aa984ead9L,0xc35c9f4452436ea0L,\n        0x96fe0a39a370751bL } },\n    /* 8 << 28 */\n    { { 0x4c4f07367f636a38L,0x9f943fb70e76d5cbL,0xb03510baa8b68b8bL,\n        0xc246780a9ed07a1fL },\n      { 0x3c0514156d549fc2L,0xc2953f31607781caL,0x955e2c69d8d95413L,\n        0xb300fadc7bd282e3L } },\n    /* 9 << 28 */\n    { { 0x81fe7b5087e9189fL,0xdb17375cf42dda27L,0x22f7d896cf0a5904L,\n        0xa0e57c5aebe348e6L },\n      { 0xa61011d3f40e3c80L,0xb11893218db705c5L,0x4ed9309e50fedec3L,\n        0xdcf14a104d6d5c1dL } },\n    /* 10 << 28 */\n    { { 0x056c265b55691342L,0xe8e0850491049dc7L,0x131329f5c9bae20aL,\n        0x96c8b3e8d9dccdb4L },\n      { 0x8c5ff838fb4ee6b4L,0xfc5a9aeb41e8ccf0L,0x7417b764fae050c6L,\n        0x0953c3d700452080L } },\n    /* 11 << 28 */\n    { { 0x2137268238dfe7e8L,0xea417e152bb79d4bL,0x59641f1c76e7cf2dL,\n        0x271e3059ea0bcfccL },\n      { 0x624c7dfd7253ecbdL,0x2f552e254fca6186L,0xcbf84ecd4d866e9cL,\n        0x73967709f68d4610L } },\n    /* 12 << 28 */\n    { { 0xa14b1163c27901b4L,0xfd9236e0899b8bf3L,0x42b091eccbc6da0aL,\n        0xbb1dac6f5ad1d297L },\n      { 0x80e61d53a91cf76eL,0x4110a412d31f1ee7L,0x2d87c3ba13efcf77L,\n        0x1f374bb4df450d76L } },\n    /* 13 << 28 */\n    { { 0x5e78e2f20d188dabL,0xe3968ed0f4b885efL,0x46c0568e7314570fL,\n        0x3161633801170521L },\n      { 0x18e1e7e24f0c8afeL,0x4caa75ffdeea78daL,0x82db67f27c5d8a51L,\n        0x36a44d866f505370L } },\n    /* 14 << 28 */\n    { { 0xd72c5bda0333974fL,0x5db516ae27a70146L,0x34705281210ef921L,\n        0xbff17a8f0c9c38e5L },\n      { 0x78f4814e12476da1L,0xc1e1661333c16980L,0x9e5b386f424d4bcaL,\n        0x4c274e87c85740deL } },\n    /* 15 << 28 */\n    { { 0xb6a9b88d6c2f5226L,0x14d1b944550d7ca8L,0x580c85fc1fc41709L,\n        0xc1da368b54c6d519L },\n      { 0x2b0785ced5113cf7L,0x0670f6335a34708fL,0x46e2376715cc3f88L,\n        0x1b480cfa50c72c8fL } },\n    /* 16 << 28 */\n    { { 0x202886024147519aL,0xd0981eac26b372f0L,0xa9d4a7caa785ebc8L,\n        0xd953c50ddbdf58e9L },\n      { 0x9d6361ccfd590f8fL,0x72e9626b44e6c917L,0x7fd9611022eb64cfL,\n        0x863ebb7e9eb288f3L } },\n    /* 17 << 28 */\n    { { 0x6e6ab7616aca8ee7L,0x97d10b39d7b40358L,0x1687d3771e5feb0dL,\n        0xc83e50e48265a27aL },\n      { 0x8f75a9fec954b313L,0xcc2e8f47310d1f61L,0xf5ba81c56557d0e0L,\n        0x25f9680c3eaf6207L } },\n    /* 18 << 28 */\n    { { 0xf95c66094354080bL,0x5225bfa57bf2fe1cL,0xc5c004e25c7d98faL,\n        0x3561bf1c019aaf60L },\n      { 0x5e6f9f17ba151474L,0xdec2f934b04f6ecaL,0x64e368a1269acb1eL,\n        0x1332d9e40cdda493L } },\n    /* 19 << 28 */\n    { { 0x60d6cf69df23de05L,0x66d17da2009339a0L,0x9fcac9850a693923L,\n        0xbcf057fced7c6a6dL },\n      { 0xc3c5c8c5f0b5662cL,0x25318dd8dcba4f24L,0x60e8cb75082b69ffL,\n        0x7c23b3ee1e728c01L } },\n    /* 20 << 28 */\n    { { 0x15e10a0a097e4403L,0xcb3d0a8619854665L,0x88d8e211d67d4826L,\n        0xb39af66e0b9d2839L },\n      { 0xa5f94588bd475ca8L,0xe06b7966c077b80bL,0xfedb1485da27c26cL,\n        0xd290d33afe0fd5e0L } },\n    /* 21 << 28 */\n    { { 0xa40bcc47f34fb0faL,0xb4760cc81fb1ab09L,0x8fca0993a273bfe3L,\n        0x13e4fe07f70b213cL },\n      { 0x3bcdb992fdb05163L,0x8c484b110c2b19b6L,0x1acb815faaf2e3e2L,\n        0xc6905935b89ff1b4L } },\n    /* 22 << 28 */\n    { { 0xb2ad6f9d586e74e1L,0x488883ad67b80484L,0x758aa2c7369c3ddbL,\n        0x8ab74e699f9afd31L },\n      { 0x10fc2d285e21beb1L,0x3484518a318c42f9L,0x377427dc53cf40c3L,\n        0x9de0781a391bc1d9L } },\n    /* 23 << 28 */\n    { { 0x8faee858693807e1L,0xa38653274e81ccc7L,0x02c30ff26f835b84L,\n        0xb604437b0d3d38d4L },\n      { 0xb3fc8a985ca1823dL,0xb82f7ec903be0324L,0xee36d761cf684a33L,\n        0x5a01df0e9f29bf7dL } },\n    /* 24 << 28 */\n    { { 0x686202f31306583dL,0x05b10da0437c622eL,0xbf9aaa0f076a7bc8L,\n        0x25e94efb8f8f4e43L },\n      { 0x8a35c9b7fa3dc26dL,0xe0e5fb9396ff03c5L,0xa77e3843ebc394ceL,\n        0xcede65958361de60L } },\n    /* 25 << 28 */\n    { { 0xd27c22f6a1993545L,0xab01cc3624d671baL,0x63fa2877a169c28eL,\n        0x925ef9042eb08376L },\n      { 0x3b2fa3cf53aa0b32L,0xb27beb5b71c49d7aL,0xb60e1834d105e27fL,\n        0xd60897884f68570dL } },\n    /* 26 << 28 */\n    { { 0x23094ce0d6fbc2acL,0x738037a1815ff551L,0xda73b1bb6bef119cL,\n        0xdcf6c430eef506baL },\n      { 0x00e4fe7be3ef104aL,0xebdd9a2c0a065628L,0x853a81c38792043eL,\n        0x22ad6eceb3b59108L } },\n    /* 27 << 28 */\n    { { 0x9fb813c039cd297dL,0x8ec7e16e05bda5d9L,0x2834797c0d104b96L,\n        0xcc11a2e77c511510L },\n      { 0x96ca5a5396ee6380L,0x054c8655cea38742L,0xb5946852d54dfa7dL,\n        0x97c422e71f4ab207L } },\n    /* 28 << 28 */\n    { { 0xbf9075090c22b540L,0x2cde42aab7c267d4L,0xba18f9ed5ab0d693L,\n        0x3ba62aa66e4660d9L },\n      { 0xb24bf97bab9ea96aL,0x5d039642e3b60e32L,0x4e6a45067c4d9bd5L,\n        0x666c5b9e7ed4a6a4L } },\n    /* 29 << 28 */\n    { { 0xfa3fdcd98edbd7ccL,0x4660bb87c6ccd753L,0x9ae9082021e6b64fL,\n        0x8a56a713b36bfb3fL },\n      { 0xabfce0965726d47fL,0x9eed01b20b1a9a7fL,0x30e9cad44eb74a37L,\n        0x7b2524cc53e9666dL } },\n    /* 30 << 28 */\n    { { 0x6a29683b8f4b002fL,0xc2200d7a41f4fc20L,0xcf3af47a3a338accL,\n        0x6539a4fbe7128975L },\n      { 0xcec31c14c33c7fcfL,0x7eb6799bc7be322bL,0x119ef4e96646f623L,\n        0x7b7a26a554d7299bL } },\n    /* 31 << 28 */\n    { { 0xcb37f08d403f46f2L,0x94b8fc431a0ec0c7L,0xbb8514e3c332142fL,\n        0xf3ed2c33e80d2a7aL },\n      { 0x8d2080afb639126cL,0xf7b6be60e3553adeL,0x3950aa9f1c7e2b09L,\n        0x847ff9586410f02bL } },\n    /* 32 << 28 */\n    { { 0x877b7cf5678a31b0L,0xd50301ae3998b620L,0x734257c5c00fb396L,\n        0xf9fb18a004e672a6L },\n      { 0xff8bd8ebe8758851L,0x1e64e4c65d99ba44L,0x4b8eaedf7dfd93b7L,\n        0xba2f2a9804e76b8cL } },\n    /* 33 << 28 */\n    { { 0x7d790cbae8053433L,0xc8e725a03d2c9585L,0x58c5c476cdd8f5edL,\n        0xd106b952efa9fe1dL },\n      { 0x3c5c775b0eff13a9L,0x242442bae057b930L,0xe9f458d4c9b70cbdL,\n        0x69b71448a3cdb89aL } },\n    /* 34 << 28 */\n    { { 0x41ee46f60e2ed742L,0x573f104540067493L,0xb1e154ff9d54c304L,\n        0x2ad0436a8d3a7502L },\n      { 0xee4aaa2d431a8121L,0xcd38b3ab886f11edL,0x57d49ea6034a0eb7L,\n        0xd2b773bdf7e85e58L } },\n    /* 35 << 28 */\n    { { 0x4a559ac49b5c1f14L,0xc444be1a3e54df2bL,0x13aad704eda41891L,\n        0xcd927bec5eb5c788L },\n      { 0xeb3c8516e48c8a34L,0x1b7ac8124b546669L,0x1815f896594df8ecL,\n        0x87c6a79c79227865L } },\n    /* 36 << 28 */\n    { { 0xae02a2f09b56ddbdL,0x1339b5ac8a2f1cf3L,0xf2b569c7839dff0dL,\n        0xb0b9e864fee9a43dL },\n      { 0x4ff8ca4177bb064eL,0x145a2812fd249f63L,0x3ab7beacf86f689aL,\n        0x9bafec2701d35f5eL } },\n    /* 37 << 28 */\n    { { 0x28054c654265aa91L,0xa4b18304035efe42L,0x6887b0e69639dec7L,\n        0xf4b8f6ad3d52aea5L },\n      { 0xfb9293cc971a8a13L,0x3f159e5d4c934d07L,0x2c50e9b109acbc29L,\n        0x08eb65e67154d129L } },\n    /* 38 << 28 */\n    { { 0x4feff58930b75c3eL,0x0bb82fe294491c93L,0xd8ac377a89af62bbL,\n        0xd7b514909685e49fL },\n      { 0xabca9a7b04497f19L,0x1b35ed0a1a7ad13fL,0x6b601e213ec86ed6L,\n        0xda91fcb9ce0c76f1L } },\n    /* 39 << 28 */\n    { { 0x9e28507bd7ab27e1L,0x7c19a55563945b7bL,0x6b43f0a1aafc9827L,\n        0x443b4fbd3aa55b91L },\n      { 0x962b2e656962c88fL,0x139da8d4ce0db0caL,0xb93f05dd1b8d6c4fL,\n        0x779cdff7180b9824L } },\n    /* 40 << 28 */\n    { { 0xbba23fddae57c7b7L,0x345342f21b932522L,0xfd9c80fe556d4aa3L,\n        0xa03907ba6525bb61L },\n      { 0x38b010e1ff218933L,0xc066b654aa52117bL,0x8e14192094f2e6eaL,\n        0x66a27dca0d32f2b2L } },\n    /* 41 << 28 */\n    { { 0x69c7f993048b3717L,0xbf5a989ab178ae1cL,0x49fa9058564f1d6bL,\n        0x27ec6e15d31fde4eL },\n      { 0x4cce03737276e7fcL,0x64086d7989d6bf02L,0x5a72f0464ccdd979L,\n        0x909c356647775631L } },\n    /* 42 << 28 */\n    { { 0x1c07bc6b75dd7125L,0xb4c6bc9787a0428dL,0x507ece52fdeb6b9dL,\n        0xfca56512b2c95432L },\n      { 0x15d97181d0e8bd06L,0x384dd317c6bb46eaL,0x5441ea203952b624L,\n        0xbcf70dee4e7dc2fbL } },\n    /* 43 << 28 */\n    { { 0x372b016e6628e8c3L,0x07a0d667b60a7522L,0xcf05751b0a344ee2L,\n        0x0ec09a48118bdeecL },\n      { 0x6e4b3d4ed83dce46L,0x43a6316d99d2fc6eL,0xa99d898956cf044cL,\n        0x7c7f4454ae3e5fb7L } },\n    /* 44 << 28 */\n    { { 0xb2e6b121fbabbe92L,0x281850fbe1330076L,0x093581ec97890015L,\n        0x69b1dded75ff77f5L },\n      { 0x7cf0b18fab105105L,0x953ced31a89ccfefL,0x3151f85feb914009L,\n        0x3c9f1b8788ed48adL } },\n    /* 45 << 28 */\n    { { 0xc9aba1a14a7eadcbL,0x928e7501522e71cfL,0xeaede7273a2e4f83L,\n        0x467e10d11ce3bbd3L },\n      { 0xf3442ac3b955dcf0L,0xba96307dd3d5e527L,0xf763a10efd77f474L,\n        0x5d744bd06a6e1ff0L } },\n    /* 46 << 28 */\n    { { 0xd287282aa777899eL,0xe20eda8fd03f3cdeL,0x6a7e75bb50b07d31L,\n        0x0b7e2a946f379de4L },\n      { 0x31cb64ad19f593cfL,0x7b1a9e4f1e76ef1dL,0xe18c9c9db62d609cL,\n        0x439bad6de779a650L } },\n    /* 47 << 28 */\n    { { 0x219d9066e032f144L,0x1db632b8e8b2ec6aL,0xff0d0fd4fda12f78L,\n        0x56fb4c2d2a25d265L },\n      { 0x5f4e2ee1255a03f1L,0x61cd6af2e96af176L,0xe0317ba8d068bc97L,\n        0x927d6bab264b988eL } },\n    /* 48 << 28 */\n    { { 0xa18f07e0e90fb21eL,0x00fd2b80bba7fca1L,0x20387f2795cd67b5L,\n        0x5b89a4e7d39707f7L },\n      { 0x8f83ad3f894407ceL,0xa0025b946c226132L,0xc79563c7f906c13bL,\n        0x5f548f314e7bb025L } },\n    /* 49 << 28 */\n    { { 0x2b4c6b8feac6d113L,0xa67e3f9c0e813c76L,0x3982717c3fe1f4b9L,\n        0x5886581926d8050eL },\n      { 0x99f3640cf7f06f20L,0xdc6102162a66ebc2L,0x52f2c175767a1e08L,\n        0x05660e1a5999871bL } },\n    /* 50 << 28 */\n    { { 0x6b0f17626d3c4693L,0xf0e7d62737ed7beaL,0xc51758c7b75b226dL,\n        0x40a886281f91613bL },\n      { 0x889dbaa7bbb38ce0L,0xe0404b65bddcad81L,0xfebccd3a8bc9671fL,\n        0xfbf9a357ee1f5375L } },\n    /* 51 << 28 */\n    { { 0x5dc169b028f33398L,0xb07ec11d72e90f65L,0xae7f3b4afaab1eb1L,\n        0xd970195e5f17538aL },\n      { 0x52b05cbe0181e640L,0xf5debd622643313dL,0x761481545df31f82L,\n        0x23e03b333a9e13c5L } },\n    /* 52 << 28 */\n    { { 0xff7589494fde0c1fL,0xbf8a1abee5b6ec20L,0x702278fb87e1db6cL,\n        0xc447ad7a35ed658fL },\n      { 0x48d4aa3803d0ccf2L,0x80acb338819a7c03L,0x9bc7c89e6e17ceccL,\n        0x46736b8b03be1d82L } },\n    /* 53 << 28 */\n    { { 0xd65d7b60c0432f96L,0xddebe7a3deb5442fL,0x79a253077dff69a2L,\n        0x37a56d9402cf3122L },\n      { 0x8bab8aedf2350d0aL,0x13c3f276037b0d9aL,0xc664957c44c65caeL,\n        0x88b44089c2e71a88L } },\n    /* 54 << 28 */\n    { { 0xdb88e5a35cb02664L,0x5d4c0bf18686c72eL,0xea3d9b62a682d53eL,\n        0x9b605ef40b2ad431L },\n      { 0x71bac202c69645d0L,0xa115f03a6a1b66e7L,0xfe2c563a158f4dc4L,\n        0xf715b3a04d12a78cL } },\n    /* 55 << 28 */\n    { { 0x8f7f0a48d413213aL,0x2035806dc04becdbL,0xecd34a995d8587f5L,\n        0x4d8c30799f6d3a71L },\n      { 0x1b2a2a678d95a8f6L,0xc58c9d7df2110d0dL,0xdeee81d5cf8fba3fL,\n        0xa42be3c00c7cdf68L } },\n    /* 56 << 28 */\n    { { 0x2126f742d43b5eaaL,0x054a0766dfa59b85L,0x9d0d5e36126bfd45L,\n        0xa1f8fbd7384f8a8fL },\n      { 0x317680f5d563fcccL,0x48ca5055f280a928L,0xe00b81b227b578cfL,\n        0x10aad9182994a514L } },\n    /* 57 << 28 */\n    { { 0xd9e07b62b7bdc953L,0x9f0f6ff25bc086ddL,0x09d1ccff655eee77L,\n        0x45475f795bef7df1L },\n      { 0x3faa28fa86f702ccL,0x92e609050f021f07L,0xe9e629687f8fa8c6L,\n        0xbd71419af036ea2cL } },\n    /* 58 << 28 */\n    { { 0x171ee1cc6028da9aL,0x5352fe1ac251f573L,0xf8ff236e3fa997f4L,\n        0xd831b6c9a5749d5fL },\n      { 0x7c872e1de350e2c2L,0xc56240d91e0ce403L,0xf9deb0776974f5cbL,\n        0x7d50ba87961c3728L } },\n    /* 59 << 28 */\n    { { 0xd6f894265a3a2518L,0xcf817799c6303d43L,0x510a0471619e5696L,\n        0xab049ff63a5e307bL },\n      { 0xe4cdf9b0feb13ec7L,0xd5e971179d8ff90cL,0xf6f64d069afa96afL,\n        0x00d0bf5e9d2012a2L } },\n    /* 60 << 28 */\n    { { 0xe63f301f358bcdc0L,0x07689e990a9d47f8L,0x1f689e2f4f43d43aL,\n        0x4d542a1690920904L },\n      { 0xaea293d59ca0a707L,0xd061fe458ac68065L,0x1033bf1b0090008cL,\n        0x29749558c08a6db6L } },\n    /* 61 << 28 */\n    { { 0x74b5fc59c1d5d034L,0xf712e9f667e215e0L,0xfd520cbd860200e6L,\n        0x0229acb43ea22588L },\n      { 0x9cd1e14cfff0c82eL,0x87684b6259c69e73L,0xda85e61c96ccb989L,\n        0x2d5dbb02a3d06493L } },\n    /* 62 << 28 */\n    { { 0xf22ad33ae86b173cL,0xe8e41ea5a79ff0e3L,0x01d2d725dd0d0c10L,\n        0x31f39088032d28f9L },\n      { 0x7b3f71e17829839eL,0x0cf691b44502ae58L,0xef658dbdbefc6115L,\n        0xa5cd6ee5b3ab5314L } },\n    /* 63 << 28 */\n    { { 0x206c8d7b5f1d2347L,0x794645ba4cc2253aL,0xd517d8ff58389e08L,\n        0x4fa20dee9f847288L },\n      { 0xeba072d8d797770aL,0x7360c91dbf429e26L,0x7200a3b380af8279L,\n        0x6a1c915082dadce3L } },\n    /* 64 << 28 */\n    { { 0x0ee6d3a7c35d8794L,0x042e65580356bae5L,0x9f59698d643322fdL,\n        0x9379ae1550a61967L },\n      { 0x64b9ae62fcc9981eL,0xaed3d6316d2934c6L,0x2454b3025e4e65ebL,\n        0xab09f647f9950428L } },\n    /* 0 << 35 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 35 */\n    { { 0xb2083a1222248accL,0x1f6ec0ef3264e366L,0x5659b7045afdee28L,\n        0x7a823a40e6430bb5L },\n      { 0x24592a04e1900a79L,0xcde09d4ac9ee6576L,0x52b6463f4b5ea54aL,\n        0x1efe9ed3d3ca65a7L } },\n    /* 2 << 35 */\n    { { 0xe27a6dbe305406ddL,0x8eb7dc7fdd5d1957L,0xf54a6876387d4d8fL,\n        0x9c479409c7762de4L },\n      { 0xbe4d5b5d99b30778L,0x25380c566e793682L,0x602d37f3dac740e3L,\n        0x140deabe1566e4aeL } },\n    /* 3 << 35 */\n    { { 0x4481d067afd32acfL,0xd8f0fccae1f71ccfL,0xd208dd0cb596f2daL,\n        0xd049d7309aad93f9L },\n      { 0xc79f263d42ab580eL,0x09411bb123f707b4L,0x8cfde1ff835e0edaL,\n        0x7270749090f03402L } },\n    /* 4 << 35 */\n    { { 0xeaee6126c49a861eL,0x024f3b65e14f0d06L,0x51a3f1e8c69bfc17L,\n        0xc3c3a8e9a7686381L },\n      { 0x3400752cb103d4c8L,0x02bc46139218b36bL,0xc67f75eb7651504aL,\n        0xd6848b56d02aebfaL } },\n    /* 5 << 35 */\n    { { 0xbd9802e6c30fa92bL,0x5a70d96d9a552784L,0x9085c4ea3f83169bL,\n        0xfa9423bb06908228L },\n      { 0x2ffebe12fe97a5b9L,0x85da604971b99118L,0x9cbc2f7f63178846L,\n        0xfd96bc709153218eL } },\n    /* 6 << 35 */\n    { { 0x958381db1782269bL,0xae34bf792597e550L,0xbb5c60645f385153L,\n        0x6f0e96afe3088048L },\n      { 0xbf6a021577884456L,0xb3b5688c69310ea7L,0x17c9429504fad2deL,\n        0xe020f0e517896d4dL } },\n    /* 7 << 35 */\n    { { 0x730ba0ab0976505fL,0x567f6813095e2ec5L,0x470620106331ab71L,\n        0x72cfa97741d22b9fL },\n      { 0x33e55ead8a2373daL,0xa8d0d5f47ba45a68L,0xba1d8f9c03029d15L,\n        0x8f34f1ccfc55b9f3L } },\n    /* 8 << 35 */\n    { { 0xcca4428dbbe5a1a9L,0x8187fd5f3126bd67L,0x0036973a48105826L,\n        0xa39b6663b8bd61a0L },\n      { 0x6d42deef2d65a808L,0x4969044f94636b19L,0xf611ee47dd5d564cL,\n        0x7b2f3a49d2873077L } },\n    /* 9 << 35 */\n    { { 0x94157d45300eb294L,0x2b2a656e169c1494L,0xc000dd76d3a47aa9L,\n        0xa2864e4fa6243ea4L },\n      { 0x82716c47db89842eL,0x12dfd7d761479fb7L,0x3b9a2c56e0b2f6dcL,\n        0x46be862ad7f85d67L } },\n    /* 10 << 35 */\n    { { 0x03b0d8dd0f82b214L,0x460c34f9f103cbc6L,0xf32e5c0318d79e19L,\n        0x8b8888baa84117f8L },\n      { 0x8f3c37dcc0722677L,0x10d21be91c1c0f27L,0xd47c8468e0f7a0c6L,\n        0x9bf02213adecc0e0L } },\n    /* 11 << 35 */\n    { { 0x0baa7d1242b48b99L,0x1bcb665d48424096L,0x8b847cd6ebfb5cfbL,\n        0x87c2ae569ad4d10dL },\n      { 0xf1cbb1220de36726L,0xe7043c683fdfbd21L,0x4bd0826a4e79d460L,\n        0x11f5e5984bd1a2cbL } },\n    /* 12 << 35 */\n    { { 0x97554160b7fe7b6eL,0x7d16189a400a3fb2L,0xd73e9beae328ca1eL,\n        0x0dd04b97e793d8ccL },\n      { 0xa9c83c9b506db8ccL,0x5cd47aaecf38814cL,0x26fc430db64b45e6L,\n        0x079b5499d818ea84L } },\n    /* 13 << 35 */\n    { { 0xebb01102c1c24a3bL,0xca24e5681c161c1aL,0x103eea6936f00a4aL,\n        0x9ad76ee876176c7bL },\n      { 0x97451fc2538e0ff7L,0x94f898096604b3b0L,0x6311436e3249cfd7L,\n        0x27b4a7bd41224f69L } },\n    /* 14 << 35 */\n    { { 0x03b5d21ae0ac2941L,0x279b0254c2d31937L,0x3307c052cac992d0L,\n        0x6aa7cb92efa8b1f3L },\n      { 0x5a1825800d37c7a5L,0x13380c37342d5422L,0x92ac2d66d5d2ef92L,\n        0x035a70c9030c63c6L } },\n    /* 15 << 35 */\n    { { 0xc16025dd4ce4f152L,0x1f419a71f9df7c06L,0x6d5b221491e4bb14L,\n        0xfc43c6cc839fb4ceL },\n      { 0x49f06591925d6b2dL,0x4b37d9d362186598L,0x8c54a971d01b1629L,\n        0xe1a9c29f51d50e05L } },\n    /* 16 << 35 */\n    { { 0x5109b78571ba1861L,0x48b22d5cd0c8f93dL,0xe8fa84a78633bb93L,\n        0x53fba6ba5aebbd08L },\n      { 0x7ff27df3e5eea7d8L,0x521c879668ca7158L,0xb9d5133bce6f1a05L,\n        0x2d50cd53fd0ebee4L } },\n    /* 17 << 35 */\n    { { 0xc82115d6c5a3ef16L,0x993eff9dba079221L,0xe4da2c5e4b5da81cL,\n        0x9a89dbdb8033fd85L },\n      { 0x60819ebf2b892891L,0x53902b215d14a4d5L,0x6ac35051d7fda421L,\n        0xcc6ab88561c83284L } },\n    /* 18 << 35 */\n    { { 0x14eba133f74cff17L,0x240aaa03ecb813f2L,0xcfbb65406f665beeL,\n        0x084b1fe4a425ad73L },\n      { 0x009d5d16d081f6a6L,0x35304fe8eef82c90L,0xf20346d5aa9eaa22L,\n        0x0ada9f07ac1c91e3L } },\n    /* 19 << 35 */\n    { { 0xa6e21678968a6144L,0x54c1f77c07b31a1eL,0xd6bb787e5781fbe1L,\n        0x61bd2ee0e31f1c4aL },\n      { 0xf25aa1e9781105fcL,0x9cf2971f7b2f8e80L,0x26d15412cdff919bL,\n        0x01db4ebe34bc896eL } },\n    /* 20 << 35 */\n    { { 0x7d9b3e23b40df1cfL,0x5933737394e971b4L,0xbf57bd14669cf921L,\n        0x865daedf0c1a1064L },\n      { 0x3eb70bd383279125L,0xbc3d5b9f34ecdaabL,0x91e3ed7e5f755cafL,\n        0x49699f54d41e6f02L } },\n    /* 21 << 35 */\n    { { 0x185770e1d4a7a15bL,0x08f3587aeaac87e7L,0x352018db473133eaL,\n        0x674ce71904fd30fcL },\n      { 0x7b8d9835088b3e0eL,0x7a0356a95d0d47a1L,0x9d9e76596474a3c4L,\n        0x61ea48a7ff66966cL } },\n    /* 22 << 35 */\n    { { 0x304177580f3e4834L,0xfdbb21c217a9afcbL,0x756fa17f2f9a67b3L,\n        0x2a6b2421a245c1a8L },\n      { 0x64be27944af02291L,0xade465c62a5804feL,0x8dffbd39a6f08fd7L,\n        0xc4efa84caa14403bL } },\n    /* 23 << 35 */\n    { { 0xa1b91b2a442b0f5cL,0xb748e317cf997736L,0x8d1b62bfcee90e16L,\n        0x907ae2710b2078c0L },\n      { 0xdf31534b0c9bcdddL,0x043fb05439adce83L,0x99031043d826846aL,\n        0x61a9c0d6b144f393L } },\n    /* 24 << 35 */\n    { { 0xdab4804647718427L,0xdf17ff9b6e830f8bL,0x408d7ee8e49a1347L,\n        0x6ac71e2391c1d4aeL },\n      { 0xc8cbb9fd1defd73cL,0x19840657bbbbfec5L,0x39db1cb59e7ef8eaL,\n        0x78aa829664105f30L } },\n    /* 25 << 35 */\n    { { 0xa3d9b7f0a3738c29L,0x0a2f235abc3250a3L,0x55e506f6445e4cafL,\n        0x0974f73d33475f7aL },\n      { 0xd37dbba35ba2f5a8L,0x542c6e636af40066L,0x26d99b53c5d73e2cL,\n        0x06060d7d6c3ca33eL } },\n    /* 26 << 35 */\n    { { 0xcdbef1c2065fef4aL,0x77e60f7dfd5b92e3L,0xd7c549f026708350L,\n        0x201b3ad034f121bfL },\n      { 0x5fcac2a10334fc14L,0x8a9a9e09344552f6L,0x7dd8a1d397653082L,\n        0x5fc0738f79d4f289L } },\n    /* 27 << 35 */\n    { { 0x787d244d17d2d8c3L,0xeffc634570830684L,0x5ddb96dde4f73ae5L,\n        0x8efb14b1172549a5L },\n      { 0x6eb73eee2245ae7aL,0xbca4061eea11f13eL,0xb577421d30b01f5dL,\n        0xaa688b24782e152cL } },\n    /* 28 << 35 */\n    { { 0x67608e71bd3502baL,0x4ef41f24b4de75a0L,0xb08dde5efd6125e5L,\n        0xde484825a409543fL },\n      { 0x1f198d9865cc2295L,0x428a37716e0edfa2L,0x4f9697a2adf35fc7L,\n        0x01a43c79f7cac3c7L } },\n    /* 29 << 35 */\n    { { 0xb05d70590fd3659aL,0x8927f30cbb7f2d9aL,0x4023d1ac8cf984d3L,\n        0x32125ed302897a45L },\n      { 0xfb572dad3d414205L,0x73000ef2e3fa82a9L,0x4c0868e9f10a5581L,\n        0x5b61fc676b0b3ca5L } },\n    /* 30 << 35 */\n    { { 0xc1258d5b7cae440cL,0x21c08b41402b7531L,0xf61a8955de932321L,\n        0x3568faf82d1408afL },\n      { 0x71b15e999ecf965bL,0xf14ed248e917276fL,0xc6f4caa1820cf9e2L,\n        0x681b20b218d83c7eL } },\n    /* 31 << 35 */\n    { { 0x6cde738dc6c01120L,0x71db0813ae70e0dbL,0x95fc064474afe18cL,\n        0x34619053129e2be7L },\n      { 0x80615ceadb2a3b15L,0x0a49a19edb4c7073L,0x0e1b84c88fd2d367L,\n        0xd74bf462033fb8aaL } },\n    /* 32 << 35 */\n    { { 0x889f6d65533ef217L,0x7158c7e4c3ca2e87L,0xfb670dfbdc2b4167L,\n        0x75910a01844c257fL },\n      { 0xf336bf07cf88577dL,0x22245250e45e2aceL,0x2ed92e8d7ca23d85L,\n        0x29f8be4c2b812f58L } },\n    /* 33 << 35 */\n    { { 0xdd9ebaa7076fe12bL,0x3f2400cbae1537f9L,0x1aa9352817bdfb46L,\n        0xc0f9843067883b41L },\n      { 0x5590ede10170911dL,0x7562f5bb34d4b17fL,0xe1fa1df21826b8d2L,\n        0xb40b796a6bd80d59L } },\n    /* 34 << 35 */\n    { { 0xd65bf1973467ba92L,0x8c9b46dbf70954b0L,0x97c8a0f30e78f15dL,\n        0xa8f3a69a85a4c961L },\n      { 0x4242660f61e4ce9bL,0xbf06aab36ea6790cL,0xc6706f8eec986416L,\n        0x9e56dec19a9fc225L } },\n    /* 35 << 35 */\n    { { 0x527c46f49a9898d9L,0xd799e77b5633cdefL,0x24eacc167d9e4297L,\n        0xabb61cea6b1cb734L },\n      { 0xbee2e8a7f778443cL,0x3bb42bf129de2fe6L,0xcbed86a13003bb6fL,\n        0xd3918e6cd781cdf6L } },\n    /* 36 << 35 */\n    { { 0x4bee32719a5103f1L,0x5243efc6f50eac06L,0xb8e122cb6adcc119L,\n        0x1b7faa84c0b80a08L },\n      { 0x32c3d1bd6dfcd08cL,0x129dec4e0be427deL,0x98ab679c1d263c83L,\n        0xafc83cb7cef64effL } },\n    /* 37 << 35 */\n    { { 0x85eb60882fa6be76L,0x892585fb1328cbfeL,0xc154d3edcf618ddaL,\n        0xc44f601b3abaf26eL },\n      { 0x7bf57d0b2be1fdfdL,0xa833bd2d21137feeL,0x9353af362db591a8L,\n        0xc76f26dc5562a056L } },\n    /* 38 << 35 */\n    { { 0x1d87e47d3fdf5a51L,0x7afb5f9355c9cab0L,0x91bbf58f89e0586eL,\n        0x7c72c0180d843709L },\n      { 0xa9a5aafb99b5c3dcL,0xa48a0f1d3844aeb0L,0x7178b7ddb667e482L,\n        0x453985e96e23a59aL } },\n    /* 39 << 35 */\n    { { 0x4a54c86001b25dd8L,0x0dd37f48fb897c8aL,0x5f8aa6100ea90cd9L,\n        0xc8892c6816d5830dL },\n      { 0xeb4befc0ef514ca5L,0x478eb679e72c9ee6L,0x9bca20dadbc40d5fL,\n        0xf015de21dde4f64aL } },\n    /* 40 << 35 */\n    { { 0xaa6a4de0eaf4b8a5L,0x68cfd9ca4bc60e32L,0x668a4b017fd15e70L,\n        0xd9f0694af27dc09dL },\n      { 0xf6c3cad5ba708bcdL,0x5cd2ba695bb95c2aL,0xaa28c1d333c0a58fL,\n        0x23e274e3abc77870L } },\n    /* 41 << 35 */\n    { { 0x44c3692ddfd20a4aL,0x091c5fd381a66653L,0x6c0bb69109a0757dL,\n        0x9072e8b9667343eaL },\n      { 0x31d40eb080848becL,0x95bd480a79fd36ccL,0x01a77c6165ed43f5L,\n        0xafccd1272e0d40bfL } },\n    /* 42 << 35 */\n    { { 0xeccfc82d1cc1884bL,0xc85ac2015d4753b4L,0xc7a6caac658e099fL,\n        0xcf46369e04b27390L },\n      { 0xe2e7d049506467eaL,0x481b63a237cdecccL,0x4029abd8ed80143aL,\n        0x28bfe3c7bcb00b88L } },\n    /* 43 << 35 */\n    { { 0x3bec10090643d84aL,0x885f3668abd11041L,0xdb02432cf83a34d6L,\n        0x32f7b360719ceebeL },\n      { 0xf06c7837dad1fe7aL,0x60a157a95441a0b0L,0x704970e9e2d47550L,\n        0xcd2bd553271b9020L } },\n    /* 44 << 35 */\n    { { 0xff57f82f33e24a0bL,0x9cbee23ff2565079L,0x16353427eb5f5825L,\n        0x276feec4e948d662L },\n      { 0xd1b62bc6da10032bL,0x718351ddf0e72a53L,0x934520762420e7baL,\n        0x96368fff3a00118dL } },\n    /* 45 << 35 */\n    { { 0x00ce2d26150a49e4L,0x0c28b6363f04706bL,0xbad65a4658b196d0L,\n        0x6c8455fcec9f8b7cL },\n      { 0xe90c895f2d71867eL,0x5c0be31bedf9f38cL,0x2a37a15ed8f6ec04L,\n        0x239639e78cd85251L } },\n    /* 46 << 35 */\n    { { 0xd89753159c7c4c6bL,0x603aa3c0d7409af7L,0xb8d53d0c007132fbL,\n        0x68d12af7a6849238L },\n      { 0xbe0607e7bf5d9279L,0x9aa50055aada74ceL,0xe81079cbba7e8ccbL,\n        0x610c71d1a5f4ff5eL } },\n    /* 47 << 35 */\n    { { 0x9e2ee1a75aa07093L,0xca84004ba75da47cL,0x074d39513de75401L,\n        0xf938f756bb311592L },\n      { 0x9619761800a43421L,0x39a2536207bc78c8L,0x278f710a0a171276L,\n        0xb28446ea8d1a8f08L } },\n    /* 48 << 35 */\n    { { 0x184781bfe3b6a661L,0x7751cb1de6d279f7L,0xf8ff95d6c59eb662L,\n        0x186d90b758d3dea7L },\n      { 0x0e4bb6c1dfb4f754L,0x5c5cf56b2b2801dcL,0xc561e4521f54564dL,\n        0xb4fb8c60f0dd7f13L } },\n    /* 49 << 35 */\n    { { 0xf884963033ff98c7L,0x9619fffacf17769cL,0xf8090bf61bfdd80aL,\n        0x14d9a149422cfe63L },\n      { 0xb354c3606f6df9eaL,0xdbcf770d218f17eaL,0x207db7c879eb3480L,\n        0x213dbda8559b6a26L } },\n    /* 50 << 35 */\n    { { 0xac4c200b29fc81b3L,0xebc3e09f171d87c1L,0x917995301481aa9eL,\n        0x051b92e192e114faL },\n      { 0xdf8f92e9ecb5537fL,0x44b1b2cc290c7483L,0xa711455a2adeb016L,\n        0x964b685681a10c2cL } },\n    /* 51 << 35 */\n    { { 0x4f159d99cec03623L,0x05532225ef3271eaL,0xb231bea3c5ee4849L,\n        0x57a54f507094f103L },\n      { 0x3e2d421d9598b352L,0xe865a49c67412ab4L,0xd2998a251cc3a912L,\n        0x5d0928080c74d65dL } },\n    /* 52 << 35 */\n    { { 0x73f459084088567aL,0xeb6b280e1f214a61L,0x8c9adc34caf0c13dL,\n        0x39d12938f561fb80L },\n      { 0xb2dc3a5ebc6edfb4L,0x7485b1b1fe4d210eL,0x062e0400e186ae72L,\n        0x91e32d5c6eeb3b88L } },\n    /* 53 << 35 */\n    { { 0x6df574d74be59224L,0xebc88ccc716d55f3L,0x26c2e6d0cad6ed33L,\n        0xc6e21e7d0d3e8b10L },\n      { 0x2cc5840e5bcc36bbL,0x9292445e7da74f69L,0x8be8d3214e5193a8L,\n        0x3ec236298df06413L } },\n    /* 54 << 35 */\n    { { 0xc7e9ae85b134defaL,0x6073b1d01bb2d475L,0xb9ad615e2863c00dL,\n        0x9e29493d525f4ac4L },\n      { 0xc32b1dea4e9acf4fL,0x3e1f01c8a50db88dL,0xb05d70ea04da916cL,\n        0x714b0d0ad865803eL } },\n    /* 55 << 35 */\n    { { 0x4bd493fc9920cb5eL,0x5b44b1f792c7a3acL,0xa2a77293bcec9235L,\n        0x5ee06e87cd378553L },\n      { 0xceff8173da621607L,0x2bb03e4c99f5d290L,0x2945106aa6f734acL,\n        0xb5056604d25c4732L } },\n    /* 56 << 35 */\n    { { 0x5945920ce079afeeL,0x686e17a06789831fL,0x5966bee8b74a5ae5L,\n        0x38a673a21e258d46L },\n      { 0xbd1cc1f283141c95L,0x3b2ecf4f0e96e486L,0xcd3aa89674e5fc78L,\n        0x415ec10c2482fa7aL } },\n    /* 57 << 35 */\n    { { 0x1523441980503380L,0x513d917ad314b392L,0xb0b52f4e63caecaeL,\n        0x07bf22ad2dc7780bL },\n      { 0xe761e8a1e4306839L,0x1b3be9625dd7feaaL,0x4fe728de74c778f1L,\n        0xf1fa0bda5e0070f6L } },\n    /* 58 << 35 */\n    { { 0x85205a316ec3f510L,0x2c7e4a14d2980475L,0xde3c19c06f30ebfdL,\n        0xdb1c1f38d4b7e644L },\n      { 0xfe291a755dce364aL,0xb7b22a3c058f5be3L,0x2cd2c30237fea38cL,\n        0x2930967a2e17be17L } },\n    /* 59 << 35 */\n    { { 0x87f009de0c061c65L,0xcb014aacedc6ed44L,0x49bd1cb43bafb1ebL,\n        0x81bd8b5c282d3688L },\n      { 0x1cdab87ef01a17afL,0x21f37ac4e710063bL,0x5a6c567642fc8193L,\n        0xf4753e7056a6015cL } },\n    /* 60 << 35 */\n    { { 0x020f795ea15b0a44L,0x8f37c8d78958a958L,0x63b7e89ba4b675b5L,\n        0xb4fb0c0c0fc31aeaL },\n      { 0xed95e639a7ff1f2eL,0x9880f5a3619614fbL,0xdeb6ff02947151abL,\n        0x5bc5118ca868dcdbL } },\n    /* 61 << 35 */\n    { { 0xd8da20554c20cea5L,0xcac2776e14c4d69aL,0xcccb22c1622d599bL,\n        0xa4ddb65368a9bb50L },\n      { 0x2c4ff1511b4941b4L,0xe1ff19b46efba588L,0x35034363c48345e0L,\n        0x45542e3d1e29dfc4L } },\n    /* 62 << 35 */\n    { { 0xf197cb91349f7aedL,0x3b2b5a008fca8420L,0x7c175ee823aaf6d8L,\n        0x54dcf42135af32b6L },\n      { 0x0ba1430727d6561eL,0x879d5ee4d175b1e2L,0xc7c4367399807db5L,\n        0x77a544559cd55bcdL } },\n    /* 63 << 35 */\n    { { 0xe6c2ff130105c072L,0x18f7a99f8dda7da4L,0x4c3018200e2d35c1L,\n        0x06a53ca0d9cc6c82L },\n      { 0xaa21cc1ef1aa1d9eL,0x324143344a75b1e8L,0x2a6d13280ebe9fdcL,\n        0x16bd173f98a4755aL } },\n    /* 64 << 35 */\n    { { 0xfbb9b2452133ffd9L,0x39a8b2f1830f1a20L,0x484bc97dd5a1f52aL,\n        0xd6aebf56a40eddf8L },\n      { 0x32257acb76ccdac6L,0xaf4d36ec1586ff27L,0x8eaa8863f8de7dd1L,\n        0x0045d5cf88647c16L } },\n    /* 0 << 42 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 42 */\n    { { 0xa6f3d574c005979dL,0xc2072b426a40e350L,0xfca5c1568de2ecf9L,\n        0xa8c8bf5ba515344eL },\n      { 0x97aee555114df14aL,0xd4374a4dfdc5ec6bL,0x754cc28f2ca85418L,\n        0x71cb9e27d3c41f78L } },\n    /* 2 << 42 */\n    { { 0x8910507903605c39L,0xf0843d9ea142c96cL,0xf374493416923684L,\n        0x732caa2ffa0a2893L },\n      { 0xb2e8c27061160170L,0xc32788cc437fbaa3L,0x39cd818ea6eda3acL,\n        0xe2e942399e2b2e07L } },\n    /* 3 << 42 */\n    { { 0x6967d39b0260e52aL,0xd42585cc90653325L,0x0d9bd60521ca7954L,\n        0x4fa2087781ed57b3L },\n      { 0x60c1eff8e34a0bbeL,0x56b0040c84f6ef64L,0x28be2b24b1af8483L,\n        0xb2278163f5531614L } },\n    /* 4 << 42 */\n    { { 0x8df275455922ac1cL,0xa7b3ef5ca52b3f63L,0x8e77b21471de57c4L,\n        0x31682c10834c008bL },\n      { 0xc76824f04bd55d31L,0xb6d1c08617b61c71L,0x31db0903c2a5089dL,\n        0x9c092172184e5d3fL } },\n    /* 5 << 42 */\n    { { 0xdd7ced5bc00cc638L,0x1a2015eb61278fc2L,0x2e8e52886a37f8d6L,\n        0xc457786fe79933adL },\n      { 0xb3fe4cce2c51211aL,0xad9b10b224c20498L,0x90d87a4fd28db5e5L,\n        0x698cd1053aca2fc3L } },\n    /* 6 << 42 */\n    { { 0x4f112d07e91b536dL,0xceb982f29eba09d6L,0x3c157b2c197c396fL,\n        0xe23c2d417b66eb24L },\n      { 0x480c57d93f330d37L,0xb3a4c8a179108debL,0x702388decb199ce5L,\n        0x0b019211b944a8d4L } },\n    /* 7 << 42 */\n    { { 0x24f2a692840bb336L,0x7c353bdca669fa7bL,0xda20d6fcdec9c300L,\n        0x625fbe2fa13a4f17L },\n      { 0xa2b1b61adbc17328L,0x008965bfa9515621L,0x49690939c620ff46L,\n        0x182dd27d8717e91cL } },\n    /* 8 << 42 */\n    { { 0x5ace5035ea6c3997L,0x54259aaac2610befL,0xef18bb3f3c80dd39L,\n        0x6910b95b5fc3fa39L },\n      { 0xfce2f51043e09aeeL,0xced56c9fa7675665L,0x10e265acd872db61L,\n        0x6982812eae9fce69L } },\n    /* 9 << 42 */\n    { { 0x29be11c6ce800998L,0x72bb1752b90360d9L,0x2c1931975a4ad590L,\n        0x2ba2f5489fc1dbc0L },\n      { 0x7fe4eebbe490ebe0L,0x12a0a4cd7fae11c0L,0x7197cf81e903ba37L,\n        0xcf7d4aa8de1c6dd8L } },\n    /* 10 << 42 */\n    { { 0x92af6bf43fd5684cL,0x2b26eecf80360aa1L,0xbd960f3000546a82L,\n        0x407b3c43f59ad8feL },\n      { 0x86cae5fe249c82baL,0x9e0faec72463744cL,0x87f551e894916272L,\n        0x033f93446ceb0615L } },\n    /* 11 << 42 */\n    { { 0x1e5eb0d18be82e84L,0x89967f0e7a582fefL,0xbcf687d5a6e921faL,\n        0xdfee4cf3d37a09baL },\n      { 0x94f06965b493c465L,0x638b9a1c7635c030L,0x7666786466f05e9fL,\n        0xccaf6808c04da725L } },\n    /* 12 << 42 */\n    { { 0xca2eb690768fccfcL,0xf402d37db835b362L,0x0efac0d0e2fdfcceL,\n        0xefc9cdefb638d990L },\n      { 0x2af12b72d1669a8bL,0x33c536bc5774ccbdL,0x30b21909fb34870eL,\n        0xc38fa2f77df25acaL } },\n    /* 13 << 42 */\n    { { 0x74c5f02bbf81f3f5L,0x0525a5aeaf7e4581L,0x88d2aaba433c54aeL,\n        0xed9775db806a56c5L },\n      { 0xd320738ac0edb37dL,0x25fdb6ee66cc1f51L,0xac661d1710600d76L,\n        0x931ec1f3bdd1ed76L } },\n    /* 14 << 42 */\n    { { 0x65c11d6219ee43f1L,0x5cd57c3e60829d97L,0xd26c91a3984be6e8L,\n        0xf08d93098b0c53bdL },\n      { 0x94bc9e5bc016e4eaL,0xd391683911d43d2bL,0x886c5ad773701155L,\n        0xe037762620b00715L } },\n    /* 15 << 42 */\n    { { 0x7f01c9ecaa80ba59L,0x3083411a68538e51L,0x970370f1e88128afL,\n        0x625cc3db91dec14bL },\n      { 0xfef9666c01ac3107L,0xb2a8d577d5057ac3L,0xb0f2629992be5df7L,\n        0xf579c8e500353924L } },\n    /* 16 << 42 */\n    { { 0xb8fa3d931341ed7aL,0x4223272ca7b59d49L,0x3dcb194783b8c4a4L,\n        0x4e413c01ed1302e4L },\n      { 0x6d999127e17e44ceL,0xee86bf7533b3adfbL,0xf6902fe625aa96caL,\n        0xb73540e4e5aae47dL } },\n    /* 17 << 42 */\n    { { 0x32801d7b1b4a158cL,0xe571c99e27e2a369L,0x40cb76c010d9f197L,\n        0xc308c2893167c0aeL },\n      { 0xa6ef9dd3eb7958f2L,0xa7226dfc300879b1L,0x6cd0b3627edf0636L,\n        0x4efbce6c7bc37eedL } },\n    /* 18 << 42 */\n    { { 0x75f92a058d699021L,0x586d4c79772566e3L,0x378ca5f1761ad23aL,\n        0x650d86fc1465a8acL },\n      { 0x7a4ed457842ba251L,0x6b65e3e642234933L,0xaf1543b731aad657L,\n        0xa4cefe98cbfec369L } },\n    /* 19 << 42 */\n    { { 0xb587da909f47befbL,0x6562e9fb41312d13L,0xa691ea59eff1cefeL,\n        0xcc30477a05fc4cf6L },\n      { 0xa16324610b0ffd3dL,0xa1f16f3b5b355956L,0x5b148d534224ec24L,\n        0xdc834e7bf977012aL } },\n    /* 20 << 42 */\n    { { 0x7bfc5e75b2c69dbcL,0x3aa77a2903c3da6cL,0xde0df03cca910271L,\n        0xcbd5ca4a7806dc55L },\n      { 0xe1ca58076db476cbL,0xfde15d625f37a31eL,0xf49af520f41af416L,\n        0x96c5c5b17d342db5L } },\n    /* 21 << 42 */\n    { { 0x155c43b7eb4ceb9bL,0x2e9930104e77371aL,0x1d2987da675d43afL,\n        0xef2bc1c08599fd72L },\n      { 0x96894b7b9342f6b2L,0x201eadf27c8e71f0L,0xf3479d9f4a1f3efcL,\n        0xe0f8a742702a9704L } },\n    /* 22 << 42 */\n    { { 0xeafd44b6b3eba40cL,0xf9739f29c1c1e0d0L,0x0091471a619d505eL,\n        0xc15f9c969d7c263eL },\n      { 0x5be4728583afbe33L,0xa3b6d6af04f1e092L,0xe76526b9751a9d11L,\n        0x2ec5b26d9a4ae4d2L } },\n    /* 23 << 42 */\n    { { 0xeb66f4d902f6fb8dL,0x4063c56196912164L,0xeb7050c180ef3000L,\n        0x288d1c33eaa5b3f0L },\n      { 0xe87c68d607806fd8L,0xb2f7f9d54bbbf50fL,0x25972f3aac8d6627L,\n        0xf854777410e8c13bL } },\n    /* 24 << 42 */\n    { { 0xcc50ef6c872b4a60L,0xab2a34a44613521bL,0x39c5c190983e15d1L,\n        0x61dde5df59905512L },\n      { 0xe417f6219f2275f3L,0x0750c8b6451d894bL,0x75b04ab978b0bdaaL,\n        0x3bfd9fd4458589bdL } },\n    /* 25 << 42 */\n    { { 0xf1013e30ee9120b6L,0x2b51af9323a4743eL,0xea96ffae48d14d9eL,\n        0x71dc0dbe698a1d32L },\n      { 0x914962d20180cca4L,0x1ae60677c3568963L,0x8cf227b1437bc444L,\n        0xc650c83bc9962c7aL } },\n    /* 26 << 42 */\n    { { 0x23c2c7ddfe7ccfc4L,0xf925c89d1b929d48L,0x4460f74b06783c33L,\n        0xac2c8d49a590475aL },\n      { 0xfb40b407b807bba0L,0x9d1e362d69ff8f3aL,0xa33e9681cbef64a4L,\n        0x67ece5fa332fb4b2L } },\n    /* 27 << 42 */\n    { { 0x6900a99b739f10e3L,0xc3341ca9ff525925L,0xee18a626a9e2d041L,\n        0xa5a8368529580dddL },\n      { 0xf3470c819d7de3cdL,0xedf025862062cf9cL,0xf43522fac010edb0L,\n        0x3031413513a4b1aeL } },\n    /* 28 << 42 */\n    { { 0xc792e02adb22b94bL,0x993d8ae9a1eaa45bL,0x8aad6cd3cd1e1c63L,\n        0x89529ca7c5ce688aL },\n      { 0x2ccee3aae572a253L,0xe02b643802a21efbL,0xa7091b6ec9430358L,\n        0x06d1b1fa9d7db504L } },\n    /* 29 << 42 */\n    { { 0x58846d32c4744733L,0x40517c71379f9e34L,0x2f65655f130ef6caL,\n        0x526e4488f1f3503fL },\n      { 0x8467bd177ee4a976L,0x1d9dc913921363d1L,0xd8d24c33b069e041L,\n        0x5eb5da0a2cdf7f51L } },\n    /* 30 << 42 */\n    { { 0x1c0f3cb1197b994fL,0x3c95a6c52843eae9L,0x7766ffc9a6097ea5L,\n        0x7bea4093d723b867L },\n      { 0xb48e1f734db378f9L,0x70025b00e37b77acL,0x943dc8e7af24ad46L,\n        0xb98a15ac16d00a85L } },\n    /* 31 << 42 */\n    { { 0x3adc38ba2743b004L,0xb1c7f4f7334415eeL,0xea43df8f1e62d05aL,\n        0x326189059d76a3b6L },\n      { 0x2fbd0bb5a23a0f46L,0x5bc971db6a01918cL,0x7801d94ab4743f94L,\n        0xb94df65e676ae22bL } },\n    /* 32 << 42 */\n    { { 0xaafcbfabaf95894cL,0x7b9bdc07276b2241L,0xeaf983625bdda48bL,\n        0x5977faf2a3fcb4dfL },\n      { 0xbed042ef052c4b5bL,0x9fe87f71067591f0L,0xc89c73ca22f24ec7L,\n        0x7d37fa9ee64a9f1bL } },\n    /* 33 << 42 */\n    { { 0x2710841a15562627L,0x2c01a613c243b034L,0x1d135c562bc68609L,\n        0xc2ca17158b03f1f6L },\n      { 0xc9966c2d3eb81d82L,0xc02abf4a8f6df13eL,0x77b34bd78f72b43bL,\n        0xaff6218f360c82b0L } },\n    /* 34 << 42 */\n    { { 0x0aa5726c8d55b9d2L,0xdc0adbe999e9bffbL,0x9097549cefb9e72aL,\n        0x167557129dfb3111L },\n      { 0xdd8bf984f26847f9L,0xbcb8e387dfb30cb7L,0xc1fd32a75171ef9cL,\n        0x977f3fc7389b363fL } },\n    /* 35 << 42 */\n    { { 0x116eaf2bf4babda0L,0xfeab68bdf7113c8eL,0xd1e3f064b7def526L,\n        0x1ac30885e0b3fa02L },\n      { 0x1c5a6e7b40142d9dL,0x839b560330921c0bL,0x48f301fa36a116a3L,\n        0x380e1107cfd9ee6dL } },\n    /* 36 << 42 */\n    { { 0x7945ead858854be1L,0x4111c12ecbd4d49dL,0xece3b1ec3a29c2efL,\n        0x6356d4048d3616f5L },\n      { 0x9f0d6a8f594d320eL,0x0989316df651ccd2L,0x6c32117a0f8fdde4L,\n        0x9abe5cc5a26a9bbcL } },\n    /* 37 << 42 */\n    { { 0xcff560fb9723f671L,0x21b2a12d7f3d593cL,0xe4cb18da24ba0696L,\n        0x186e2220c3543384L },\n      { 0x722f64e088312c29L,0x94282a9917dc7752L,0x62467bbf5a85ee89L,\n        0xf435c650f10076a0L } },\n    /* 38 << 42 */\n    { { 0xc9ff153943b3a50bL,0x7132130c1a53efbcL,0x31bfe063f7b0c5b7L,\n        0xb0179a7d4ea994ccL },\n      { 0x12d064b3c85f455bL,0x472593288f6e0062L,0xf64e590bb875d6d9L,\n        0x22dd6225ad92bcc7L } },\n    /* 39 << 42 */\n    { { 0xb658038eb9c3bd6dL,0x00cdb0d6fbba27c8L,0x0c6813371062c45dL,\n        0xd8515b8c2d33407dL },\n      { 0xcb8f699e8cbb5ecfL,0x8c4347f8c608d7d8L,0x2c11850abb3e00dbL,\n        0x20a8dafdecb49d19L } },\n    /* 40 << 42 */\n    { { 0xbd78148045ee2f40L,0x75e354af416b60cfL,0xde0b58a18d49a8c4L,\n        0xe40e94e2fa359536L },\n      { 0xbd4fa59f62accd76L,0x05cf466a8c762837L,0xb5abda99448c277bL,\n        0x5a9e01bf48b13740L } },\n    /* 41 << 42 */\n    { { 0x9d457798326aad8dL,0xbdef4954c396f7e7L,0x6fb274a2c253e292L,\n        0x2800bf0a1cfe53e7L },\n      { 0x22426d3144438fd4L,0xef2339235e259f9aL,0x4188503c03f66264L,\n        0x9e5e7f137f9fdfabL } },\n    /* 42 << 42 */\n    { { 0x565eb76c5fcc1abaL,0xea63254859b5bff8L,0x5587c087aab6d3faL,\n        0x92b639ea6ce39c1bL },\n      { 0x0706e782953b135cL,0x7308912e425268efL,0x599e92c7090e7469L,\n        0x83b90f529bc35e75L } },\n    /* 43 << 42 */\n    { { 0x4750b3d0244975b3L,0xf3a4435811965d72L,0x179c67749c8dc751L,\n        0xff18cdfed23d9ff0L },\n      { 0xc40138332028e247L,0x96e280e2f3bfbc79L,0xf60417bdd0880a84L,\n        0x263c9f3d2a568151L } },\n    /* 44 << 42 */\n    { { 0x36be15b32d2ce811L,0x846dc0c2f8291d21L,0x5cfa0ecb789fcfdbL,\n        0x45a0beedd7535b9aL },\n      { 0xec8e9f0796d69af1L,0x31a7c5b8599ab6dcL,0xd36d45eff9e2e09fL,\n        0x3cf49ef1dcee954bL } },\n    /* 45 << 42 */\n    { { 0x6be34cf3086cff9bL,0x88dbd49139a3360fL,0x1e96b8cc0dbfbd1dL,\n        0xc1e5f7bfcb7e2552L },\n      { 0x0547b21428819d98L,0xc770dd9c7aea9dcbL,0xaef0d4c7041d68c8L,\n        0xcc2b981813cb9ba8L } },\n    /* 46 << 42 */\n    { { 0x7fc7bc76fe86c607L,0x6b7b9337502a9a95L,0x1948dc27d14dab63L,\n        0x249dd198dae047beL },\n      { 0xe8356584a981a202L,0x3531dd183a893387L,0x1be11f90c85c7209L,\n        0x93d2fe1ee2a52b5aL } },\n    /* 47 << 42 */\n    { { 0x8225bfe2ec6d6b97L,0x9cf6d6f4bd0aa5deL,0x911459cb54779f5fL,\n        0x5649cddb86aeb1f3L },\n      { 0x321335793f26ce5aL,0xc289a102550f431eL,0x559dcfda73b84c6fL,\n        0x84973819ee3ac4d7L } },\n    /* 48 << 42 */\n    { { 0xb51e55e6f2606a82L,0xe25f706190f2fb57L,0xacef6c2ab1a4e37cL,\n        0x864e359d5dcf2706L },\n      { 0x479e6b187ce57316L,0x2cab25003a96b23dL,0xed4898628ef16df7L,\n        0x2056538cef3758b5L } },\n    /* 49 << 42 */\n    { { 0xa7df865ef15d3101L,0x80c5533a61b553d7L,0x366e19974ed14294L,\n        0x6620741fb3c0bcd6L },\n      { 0x21d1d9c4edc45418L,0x005b859ec1cc4a9dL,0xdf01f630a1c462f0L,\n        0x15d06cf3f26820c7L } },\n    /* 50 << 42 */\n    { { 0x9f7f24ee3484be47L,0x2ff33e964a0c902fL,0x00bdf4575a0bc453L,\n        0x2378dfaf1aa238dbL },\n      { 0x272420ec856720f2L,0x2ad9d95b96797291L,0xd1242cc6768a1558L,\n        0x2e287f8b5cc86aa8L } },\n    /* 51 << 42 */\n    { { 0x796873d0990cecaaL,0xade55f81675d4080L,0x2645eea321f0cd84L,\n        0x7a1efa0fb4e17d02L },\n      { 0xf6858420037cc061L,0x682e05f0d5d43e12L,0x59c3699427218710L,\n        0x85cbba4d3f7cd2fcL } },\n    /* 52 << 42 */\n    { { 0x726f97297a3cd22aL,0x9f8cd5dc4a628397L,0x17b93ab9c23165edL,\n        0xff5f5dbf122823d4L },\n      { 0xc1e4e4b5654a446dL,0xd1a9496f677257baL,0x6387ba94de766a56L,\n        0x23608bc8521ec74aL } },\n    /* 53 << 42 */\n    { { 0x16a522d76688c4d4L,0x9d6b428207373abdL,0xa62f07acb42efaa3L,\n        0xf73e00f7e3b90180L },\n      { 0x36175fec49421c3eL,0xc4e44f9b3dcf2678L,0x76df436b7220f09fL,\n        0x172755fb3aa8b6cfL } },\n    /* 54 << 42 */\n    { { 0xbab89d57446139ccL,0x0a0a6e025fe0208fL,0xcdbb63e211e5d399L,\n        0x33ecaa12a8977f0bL },\n      { 0x59598b21f7c42664L,0xb3e91b32ab65d08aL,0x035822eef4502526L,\n        0x1dcf0176720a82a9L } },\n    /* 55 << 42 */\n    { { 0x50f8598f3d589e02L,0xdf0478ffb1d63d2cL,0x8b8068bd1571cd07L,\n        0x30c3aa4fd79670cdL },\n      { 0x25e8fd4b941ade7fL,0x3d1debdc32790011L,0x65b6dcbd3a3f9ff0L,\n        0x282736a4793de69cL } },\n    /* 56 << 42 */\n    { { 0xef69a0c3d41d3bd3L,0xb533b8c907a26bdeL,0xe2801d97db2edf9fL,\n        0xdc4a8269e1877af0L },\n      { 0x6c1c58513d590dbeL,0x84632f6bee4e9357L,0xd36d36b779b33374L,\n        0xb46833e39bbca2e6L } },\n    /* 57 << 42 */\n    { { 0x37893913f7fc0586L,0x385315f766bf4719L,0x72c56293b31855dcL,\n        0xd1416d4e849061feL },\n      { 0xbeb3ab7851047213L,0x447f6e61f040c996L,0xd06d310d638b1d0cL,\n        0xe28a413fbad1522eL } },\n    /* 58 << 42 */\n    { { 0x685a76cb82003f86L,0x610d07f70bcdbca3L,0x6ff660219ca4c455L,\n        0x7df39b87cea10eecL },\n      { 0xb9255f96e22db218L,0x8cc6d9eb08a34c44L,0xcd4ffb86859f9276L,\n        0x8fa15eb250d07335L } },\n    /* 59 << 42 */\n    { { 0xdf553845cf2c24b5L,0x89f66a9f52f9c3baL,0x8f22b5b9e4a7ceb3L,\n        0xaffef8090e134686L },\n      { 0x3e53e1c68eb8fac2L,0x93c1e4eb28aec98eL,0xb6b91ec532a43bcbL,\n        0x2dbfa947b2d74a51L } },\n    /* 60 << 42 */\n    { { 0xe065d190ca84bad7L,0xfb13919fad58e65cL,0x3c41718bf1cb6e31L,\n        0x688969f006d05c3fL },\n      { 0xd4f94ce721264d45L,0xfdfb65e97367532bL,0x5b1be8b10945a39dL,\n        0x229f789c2b8baf3bL } },\n    /* 61 << 42 */\n    { { 0xd8f41f3e6f49f15dL,0x678ce828907f0792L,0xc69ace82fca6e867L,\n        0x106451aed01dcc89L },\n      { 0x1bb4f7f019fc32d2L,0x64633dfcb00c52d2L,0x8f13549aad9ea445L,\n        0x99a3bf50fb323705L } },\n    /* 62 << 42 */\n    { { 0x0c9625a2534d4dbcL,0x45b8f1d1c2a2fea3L,0x76ec21a1a530fc1aL,\n        0x4bac9c2a9e5bd734L },\n      { 0x5996d76a7b4e3587L,0x0045cdee1182d9e3L,0x1aee24b91207f13dL,\n        0x66452e9797345a41L } },\n    /* 63 << 42 */\n    { { 0x16e5b0549f950cd0L,0x9cc72fb1d7fdd075L,0x6edd61e766249663L,\n        0xde4caa4df043cccbL },\n      { 0x11b1f57a55c7ac17L,0x779cbd441a85e24dL,0x78030f86e46081e7L,\n        0xfd4a60328e20f643L } },\n    /* 64 << 42 */\n    { { 0xcc7a64880a750c0fL,0x39bacfe34e548e83L,0x3d418c760c110f05L,\n        0x3e4daa4cb1f11588L },\n      { 0x2733e7b55ffc69ffL,0x46f147bc92053127L,0x885b2434d722df94L,\n        0x6a444f65e6fc6b7cL } },\n    /* 0 << 49 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 49 */\n    { { 0x7a1a465ac3f16ea8L,0x115a461db2f1d11cL,0x4767dd956c68a172L,\n        0x3392f2ebd13a4698L },\n      { 0xc7a99ccde526cdc7L,0x8e537fdc22292b81L,0x76d8cf69a6d39198L,\n        0xffc5ff432446852dL } },\n    /* 2 << 49 */\n    { { 0x97b14f7ea90567e6L,0x513257b7b6ae5cb7L,0x85454a3c9f10903dL,\n        0xd8d2c9ad69bc3724L },\n      { 0x38da93246b29cb44L,0xb540a21d77c8cbacL,0x9bbfe43501918e42L,\n        0xfffa707a56c3614eL } },\n    /* 3 << 49 */\n    { { 0x0ce4e3f1d4e353b7L,0x062d8a14ef46b0a0L,0x6408d5ab574b73fdL,\n        0xbc41d1c9d3273ffdL },\n      { 0x3538e1e76be77800L,0x71fe8b37c5655031L,0x1cd916216b9b331aL,\n        0xad825d0bbb388f73L } },\n    /* 4 << 49 */\n    { { 0x56c2e05b1cb76219L,0x0ec0bf9171567e7eL,0xe7076f8661c4c910L,\n        0xd67b085bbabc04d9L },\n      { 0x9fb904595e93a96aL,0x7526c1eafbdc249aL,0x0d44d367ecdd0bb7L,\n        0x953999179dc0d695L } },\n    /* 5 << 49 */\n    { { 0x61360ee99e240d18L,0x057cdcacb4b94466L,0xe7667cd12fe5325cL,\n        0x1fa297b521974e3bL },\n      { 0xfa4081e7db083d76L,0x31993be6f206bd15L,0x8949269b14c19f8cL,\n        0x21468d72a9d92357L } },\n    /* 6 << 49 */\n    { { 0x2ccbc583a4c506ecL,0x957ed188d1acfe97L,0x8baed83312f1aea2L,\n        0xef2a6cb48325362dL },\n      { 0x130dde428e195c43L,0xc842025a0e6050c6L,0x2da972a708686a5dL,\n        0xb52999a1e508b4a8L } },\n    /* 7 << 49 */\n    { { 0xd9f090b910a5a8bdL,0xca91d249096864daL,0x8e6a93be3f67dbc1L,\n        0xacae6fbaf5f4764cL },\n      { 0x1563c6e0d21411a0L,0x28fa787fda0a4ad8L,0xd524491c908c8030L,\n        0x1257ba0e4c795f07L } },\n    /* 8 << 49 */\n    { { 0x83f49167ceca9754L,0x426d2cf64b7939a0L,0x2555e355723fd0bfL,\n        0xa96e6d06c4f144e2L },\n      { 0x4768a8dd87880e61L,0x15543815e508e4d5L,0x09d7e772b1b65e15L,\n        0x63439dd6ac302fa0L } },\n    /* 9 << 49 */\n    { { 0xb93f802fc14e35c2L,0x71735b7c4341333cL,0x03a2510416d4f362L,\n        0x3f4d069bbf433c8eL },\n      { 0x0d83ae01f78f5a7cL,0x50a8ffbe7c4eed07L,0xc74f890676e10f83L,\n        0x7d0809669ddaf8e1L } },\n    /* 10 << 49 */\n    { { 0xb11df8e1698e04ccL,0x877be203169005c8L,0x32749e8c4f3c6179L,\n        0x2dbc9d0a7853fc05L },\n      { 0x187d4f939454d937L,0xe682ce9db4800e1bL,0xa9129ad8165e68e8L,\n        0x0fe29735be7f785bL } },\n    /* 11 << 49 */\n    { { 0x5303f40c5b9e02b7L,0xa37c969235ee04e8L,0x5f46cc2034d6632bL,\n        0x55ef72b296ac545bL },\n      { 0xabec5c1f7b91b062L,0x0a79e1c7bb33e821L,0xbb04b4283a9f4117L,\n        0x0de1f28ffd2a475aL } },\n    /* 12 << 49 */\n    { { 0x31019ccf3a4434b4L,0xa34581111a7954dcL,0xa9dac80de34972a7L,\n        0xb043d05474f6b8ddL },\n      { 0x021c319e11137b1aL,0x00a754ceed5cc03fL,0x0aa2c794cbea5ad4L,\n        0x093e67f470c015b6L } },\n    /* 13 << 49 */\n    { { 0x72cdfee9c97e3f6bL,0xc10bcab4b6da7461L,0x3b02d2fcb59806b9L,\n        0x85185e89a1de6f47L },\n      { 0x39e6931f0eb6c4d4L,0x4d4440bdd4fa5b04L,0x5418786e34be7eb8L,\n        0x6380e5219d7259bcL } },\n    /* 14 << 49 */\n    { { 0x20ac0351d598d710L,0x272c4166cb3a4da4L,0xdb82fe1aca71de1fL,\n        0x746e79f2d8f54b0fL },\n      { 0x6e7fc7364b573e9bL,0x75d03f46fd4b5040L,0x5c1cc36d0b98d87bL,\n        0x513ba3f11f472da1L } },\n    /* 15 << 49 */\n    { { 0x79d0af26abb177ddL,0xf82ab5687891d564L,0x2b6768a972232173L,\n        0xefbb3bb08c1f6619L },\n      { 0xb29c11dba6d18358L,0x519e2797b0916d3aL,0xd4dc18f09188e290L,\n        0x648e86e398b0ca7fL } },\n    /* 16 << 49 */\n    { { 0x859d3145983c38b5L,0xb14f176c637abc8bL,0x2793fb9dcaff7be6L,\n        0xebe5a55f35a66a5aL },\n      { 0x7cec1dcd9f87dc59L,0x7c595cd3fbdbf560L,0x5b543b2226eb3257L,\n        0x69080646c4c935fdL } },\n    /* 17 << 49 */\n    { { 0x7f2e440381e9ede3L,0x243c3894caf6df0aL,0x7c605bb11c073b11L,\n        0xcd06a541ba6a4a62L },\n      { 0x2916894949d4e2e5L,0x33649d074af66880L,0xbfc0c885e9a85035L,\n        0xb4e52113fc410f4bL } },\n    /* 18 << 49 */\n    { { 0xdca3b70678a6513bL,0x92ea4a2a9edb1943L,0x02642216db6e2dd8L,\n        0x9b45d0b49fd57894L },\n      { 0x114e70dbc69d11aeL,0x1477dd194c57595fL,0xbc2208b4ec77c272L,\n        0x95c5b4d7db68f59cL } },\n    /* 19 << 49 */\n    { { 0xb8c4fc6342e532b7L,0x386ba4229ae35290L,0xfb5dda42d201ecbcL,\n        0x2353dc8ba0e38fd6L },\n      { 0x9a0b85ea68f7e978L,0x96ec56822ad6d11fL,0x5e279d6ce5f6886dL,\n        0xd3fe03cd3cb1914dL } },\n    /* 20 << 49 */\n    { { 0xfe541fa47ea67c77L,0x952bd2afe3ea810cL,0x791fef568d01d374L,\n        0xa3a1c6210f11336eL },\n      { 0x5ad0d5a9c7ec6d79L,0xff7038af3225c342L,0x003c6689bc69601bL,\n        0x25059bc745e8747dL } },\n    /* 21 << 49 */\n    { { 0xfa4965b2f2086fbfL,0xf6840ea686916078L,0xd7ac762070081d6cL,\n        0xe600da31b5328645L },\n      { 0x01916f63529b8a80L,0xe80e48582d7d6f3eL,0x29eb0fe8d664ca7cL,\n        0xf017637be7b43b0cL } },\n    /* 22 << 49 */\n    { { 0x9a75c80676cb2566L,0x8f76acb1b24892d9L,0x7ae7b9cc1f08fe45L,\n        0x19ef73296a4907d8L },\n      { 0x2db4ab715f228bf0L,0xf3cdea39817032d7L,0x0b1f482edcabe3c0L,\n        0x3baf76b4bb86325cL } },\n    /* 23 << 49 */\n    { { 0xd49065e010089465L,0x3bab5d298e77c596L,0x7636c3a6193dbd95L,\n        0xdef5d294b246e499L },\n      { 0xb22c58b9286b2475L,0xa0b93939cd80862bL,0x3002c83af0992388L,\n        0x6de01f9beacbe14cL } },\n    /* 24 << 49 */\n    { { 0x6aac688eadd70482L,0x708de92a7b4a4e8aL,0x75b6dd73758a6eefL,\n        0xea4bf352725b3c43L },\n      { 0x10041f2c87912868L,0xb1b1be95ef09297aL,0x19ae23c5a9f3860aL,\n        0xc4f0f839515dcf4bL } },\n    /* 25 << 49 */\n    { { 0x3c7ecca397f6306aL,0x744c44ae68a3a4b0L,0x69cd13a0b3a1d8a2L,\n        0x7cad0a1e5256b578L },\n      { 0xea653fcd33791d9eL,0x9cc2a05d74b2e05fL,0x73b391dcfd7affa2L,\n        0xddb7091eb6b05442L } },\n    /* 26 << 49 */\n    { { 0xc71e27bf8538a5c6L,0x195c63dd89abff17L,0xfd3152851b71e3daL,\n        0x9cbdfda7fa680fa0L },\n      { 0x9db876ca849d7eabL,0xebe2764b3c273271L,0x663357e3f208dceaL,\n        0x8c5bd833565b1b70L } },\n    /* 27 << 49 */\n    { { 0xccc3b4f59837fc0dL,0x9b641ba8a79cf00fL,0x7428243ddfdf3990L,\n        0x83a594c4020786b1L },\n      { 0xb712451a526c4502L,0x9d39438e6adb3f93L,0xfdb261e3e9ff0ccdL,\n        0x80344e3ce07af4c3L } },\n    /* 28 << 49 */\n    { { 0x75900d7c2fa4f126L,0x08a3b8655c99a232L,0x2478b6bfdb25e0c3L,\n        0x482cc2c271db2edfL },\n      { 0x37df7e645f321bb8L,0x8a93821b9a8005b4L,0x3fa2f10ccc8c1958L,\n        0x0d3322182c269d0aL } },\n    /* 29 << 49 */\n    { { 0x20ab8119e246b0e6L,0xb39781e4d349fd17L,0xd293231eb31aa100L,\n        0x4b779c97bb032168L },\n      { 0x4b3f19e1c8470500L,0x45b7efe90c4c869dL,0xdb84f38aa1a6bbccL,\n        0x3b59cb15b2fddbc1L } },\n    /* 30 << 49 */\n    { { 0xba5514df3fd165e8L,0x499fd6a9061f8811L,0x72cd1fe0bfef9f00L,\n        0x120a4bb979ad7e8aL },\n      { 0xf2ffd0955f4a5ac5L,0xcfd174f195a7a2f0L,0xd42301ba9d17baf1L,\n        0xd2fa487a77f22089L } },\n    /* 31 << 49 */\n    { { 0x9cb09efeb1dc77e1L,0xe956693921c99682L,0x8c5469016c6067bbL,\n        0xfd37857461c24456L },\n      { 0x2b6a6cbe81796b33L,0x62d550f658e87f8bL,0x1b763e1c7f1b01b4L,\n        0x4b93cfea1b1b5e12L } },\n    /* 32 << 49 */\n    { { 0xb93452381d531696L,0x57201c0088cdde69L,0xdde922519a86afc7L,\n        0xe3043895bd35cea8L },\n      { 0x7608c1e18555970dL,0x8267dfa92535935eL,0xd4c60a57322ea38bL,\n        0xe0bf7977804ef8b5L } },\n    /* 33 << 49 */\n    { { 0x1a0dab28c06fece4L,0xd405991e94e7b49dL,0xc542b6d2706dab28L,\n        0xcb228da3a91618fbL },\n      { 0x224e4164107d1ceaL,0xeb9fdab3d0f5d8f1L,0xc02ba3860d6e41cdL,\n        0x676a72c59b1f7146L } },\n    /* 34 << 49 */\n    { { 0xffd6dd984d6cb00bL,0xcef9c5cade2e8d7cL,0xa1bbf5d7641c7936L,\n        0x1b95b230ee8f772eL },\n      { 0xf765a92ee8ac25b1L,0xceb04cfc3a18b7c6L,0x27944cef0acc8966L,\n        0xcbb3c957434c1004L } },\n    /* 35 << 49 */\n    { { 0x9c9971a1a43ff93cL,0x5bc2db17a1e358a9L,0x45b4862ea8d9bc82L,\n        0x70ebfbfb2201e052L },\n      { 0xafdf64c792871591L,0xea5bcae6b42d0219L,0xde536c552ad8f03cL,\n        0xcd6c3f4da76aa33cL } },\n    /* 36 << 49 */\n    { { 0xbeb5f6230bca6de3L,0xdd20dd99b1e706fdL,0x90b3ff9dac9059d4L,\n        0x2d7b29027ccccc4eL },\n      { 0x8a090a59ce98840fL,0xa5d947e08410680aL,0x49ae346a923379a5L,\n        0x7dbc84f9b28a3156L } },\n    /* 37 << 49 */\n    { { 0xfd40d91654a1aff2L,0xabf318ba3a78fb9bL,0x50152ed83029f95eL,\n        0x9fc1dd77c58ad7faL },\n      { 0x5fa5791513595c17L,0xb95046688f62b3a9L,0x907b5b24ff3055b0L,\n        0x2e995e359a84f125L } },\n    /* 38 << 49 */\n    { { 0x87dacf697e9bbcfbL,0x95d0c1d6e86d96e3L,0x65726e3c2d95a75cL,\n        0x2c3c9001acd27f21L },\n      { 0x1deab5616c973f57L,0x108b7e2ca5221643L,0x5fee9859c4ef79d4L,\n        0xbd62b88a40d4b8c6L } },\n    /* 39 << 49 */\n    { { 0xb4dd29c4197c75d6L,0x266a6df2b7076febL,0x9512d0ea4bf2df11L,\n        0x1320c24f6b0cc9ecL },\n      { 0x6bb1e0e101a59596L,0x8317c5bbeff9aaacL,0x65bb405e385aa6c9L,\n        0x613439c18f07988fL } },\n    /* 40 << 49 */\n    { { 0xd730049f16a66e91L,0xe97f2820fa1b0e0dL,0x4131e003304c28eaL,\n        0x820ab732526bac62L },\n      { 0xb2ac9ef928714423L,0x54ecfffaadb10cb2L,0x8781476ef886a4ccL,\n        0x4b2c87b5db2f8d49L } },\n    /* 41 << 49 */\n    { { 0xe857cd200a44295dL,0x707d7d2158c6b044L,0xae8521f9f596757cL,\n        0x87448f0367b2b714L },\n      { 0x13a9bc455ebcd58dL,0x79bcced99122d3c1L,0x3c6442479e076642L,\n        0x0cf227782df4767dL } },\n    /* 42 << 49 */\n    { { 0x5e61aee471d444b6L,0x211236bfc5084a1dL,0x7e15bc9a4fd3eaf6L,\n        0x68df2c34ab622bf5L },\n      { 0x9e674f0f59bf4f36L,0xf883669bd7f34d73L,0xc48ac1b831497b1dL,\n        0x323b925d5106703bL } },\n    /* 43 << 49 */\n    { { 0x22156f4274082008L,0xeffc521ac8482bcbL,0x5c6831bf12173479L,\n        0xcaa2528fc4739490L },\n      { 0x84d2102a8f1b3c4dL,0xcf64dfc12d9bec0dL,0x433febad78a546efL,\n        0x1f621ec37b73cef1L } },\n    /* 44 << 49 */\n    { { 0x6aecd62737338615L,0x162082ab01d8edf6L,0x833a811919e86b66L,\n        0x6023a251d299b5dbL },\n      { 0xf5bb0c3abbf04b89L,0x6735eb69ae749a44L,0xd0e058c54713de3bL,\n        0xfdf2593e2c3d4ccdL } },\n    /* 45 << 49 */\n    { { 0x1b8f414efdd23667L,0xdd52aacafa2015eeL,0x3e31b517bd9625ffL,\n        0x5ec9322d8db5918cL },\n      { 0xbc73ac85a96f5294L,0x82aa5bf361a0666aL,0x49755810bf08ac42L,\n        0xd21cdfd5891cedfcL } },\n    /* 46 << 49 */\n    { { 0x918cb57b67f8be10L,0x365d1a7c56ffa726L,0x2435c5046532de93L,\n        0xc0fc5e102674cd02L },\n      { 0x6e51fcf89cbbb142L,0x1d436e5aafc50692L,0x766bffff3fbcae22L,\n        0x3148c2fdfd55d3b8L } },\n    /* 47 << 49 */\n    { { 0x52c7fdc9233222faL,0x89ff1092e419fb6bL,0x3cd6db9925254977L,\n        0x2e85a1611cf12ca7L },\n      { 0xadd2547cdc810bc9L,0xea3f458f9d257c22L,0x642c1fbe27d6b19bL,\n        0xed07e6b5140481a6L } },\n    /* 48 << 49 */\n    { { 0x6ada1d4286d2e0f8L,0xe59201220e8a9fd5L,0x02c936af708c1b49L,\n        0x60f30fee2b4bfaffL },\n      { 0x6637ad06858e6a61L,0xce4c77673fd374d0L,0x39d54b2d7188defbL,\n        0xa8c9d250f56a6b66L } },\n    /* 49 << 49 */\n    { { 0x58fc0f5eb24fe1dcL,0x9eaf9dee6b73f24cL,0xa90d588b33650705L,\n        0xde5b62c5af2ec729L },\n      { 0x5c72cfaed3c2b36eL,0x868c19d5034435daL,0x88605f93e17ee145L,\n        0xaa60c4ee77a5d5b1L } },\n    /* 50 << 49 */\n    { { 0xbcf5bfd23b60c472L,0xaf4ef13ceb1d3049L,0x373f44fce13895c9L,\n        0xf29b382f0cbc9822L },\n      { 0x1bfcb85373efaef6L,0xcf56ac9ca8c96f40L,0xd7adf1097a191e24L,\n        0x98035f44bf8a8dc2L } },\n    /* 51 << 49 */\n    { { 0xf40a71b91e750c84L,0xc57f7b0c5dc6c469L,0x49a0e79c6fbc19c1L,\n        0x6b0f5889a48ebdb8L },\n      { 0x5d3fd084a07c4e9fL,0xc3830111ab27de14L,0x0e4929fe33e08dccL,\n        0xf4a5ad2440bb73a3L } },\n    /* 52 << 49 */\n    { { 0xde86c2bf490f97caL,0x288f09c667a1ce18L,0x364bb8861844478dL,\n        0x7840fa42ceedb040L },\n      { 0x1269fdd25a631b37L,0x94761f1ea47c8b7dL,0xfc0c2e17481c6266L,\n        0x85e16ea23daa5fa7L } },\n    /* 53 << 49 */\n    { { 0xccd8603392491048L,0x0c2f6963f4d402d7L,0x6336f7dfdf6a865cL,\n        0x0a2a463cb5c02a87L },\n      { 0xb0e29be7bf2f12eeL,0xf0a2200266bad988L,0x27f87e039123c1d7L,\n        0x21669c55328a8c98L } },\n    /* 54 << 49 */\n    { { 0x186b980392f14529L,0xd3d056cc63954df3L,0x2f03fd58175a46f6L,\n        0x63e34ebe11558558L },\n      { 0xe13fedee5b80cfa5L,0xe872a120d401dbd1L,0x52657616e8a9d667L,\n        0xbc8da4b6e08d6693L } },\n    /* 55 << 49 */\n    { { 0x370fb9bb1b703e75L,0x6773b186d4338363L,0x18dad378ecef7bffL,\n        0xaac787ed995677daL },\n      { 0x4801ea8b0437164bL,0xf430ad2073fe795eL,0xb164154d8ee5eb73L,\n        0x0884ecd8108f7c0eL } },\n    /* 56 << 49 */\n    { { 0x0e6ec0965f520698L,0x640631fe44f7b8d9L,0x92fd34fca35a68b9L,\n        0x9c5a4b664d40cf4eL },\n      { 0x949454bf80b6783dL,0x80e701fe3a320a10L,0x8d1a564a1a0a39b2L,\n        0x1436d53d320587dbL } },\n    /* 57 << 49 */\n    { { 0xf5096e6d6556c362L,0xbc23a3c0e2455d7eL,0x3a7aee54807230f9L,\n        0x9ba1cfa622ae82fdL },\n      { 0x833a057a99c5d706L,0x8be85f4b842315c9L,0xd083179a66a72f12L,\n        0x2fc77d5dcdcc73cdL } },\n    /* 58 << 49 */\n    { { 0x22b88a805616ee30L,0xfb09548fe7ab1083L,0x8ad6ab0d511270cdL,\n        0x61f6c57a6924d9abL },\n      { 0xa0f7bf7290aecb08L,0x849f87c90df784a4L,0x27c79c15cfaf1d03L,\n        0xbbf9f675c463faceL } },\n    /* 59 << 49 */\n    { { 0x91502c65765ba543L,0x18ce3cac42ea60ddL,0xe5cee6ac6e43ecb3L,\n        0x63e4e91068f2aeebL },\n      { 0x26234fa3c85932eeL,0x96883e8b4c90c44dL,0x29b9e738a18a50f6L,\n        0xbfc62b2a3f0420dfL } },\n    /* 60 << 49 */\n    { { 0xd22a7d906d3e1fa9L,0x17115618fe05b8a3L,0x2a0c9926bb2b9c01L,\n        0xc739fcc6e07e76a2L },\n      { 0x540e9157165e439aL,0x06353a626a9063d8L,0x84d9559461e927a3L,\n        0x013b9b26e2e0be7fL } },\n    /* 61 << 49 */\n    { { 0x4feaec3b973497f1L,0x15c0f94e093ebc2dL,0x6af5f22733af0583L,\n        0x0c2af206c61f3340L },\n      { 0xd25dbdf14457397cL,0x2e8ed017cabcbae0L,0xe3010938c2815306L,\n        0xbaa99337e8c6cd68L } },\n    /* 62 << 49 */\n    { { 0x085131823b0ec7deL,0x1e1b822b58df05dfL,0x5c14842fa5c3b683L,\n        0x98fe977e3eba34ceL },\n      { 0xfd2316c20d5e8873L,0xe48d839abd0d427dL,0x495b2218623fc961L,\n        0x24ee56e7b46fba5eL } },\n    /* 63 << 49 */\n    { { 0x9184a55b91e4de58L,0xa7488ca5dfdea288L,0xa723862ea8dcc943L,\n        0x92d762b2849dc0fcL },\n      { 0x3c444a12091ff4a9L,0x581113fa0cada274L,0xb9de0a4530d8eae2L,\n        0x5e0fcd85df6b41eaL } },\n    /* 64 << 49 */\n    { { 0x6233ea68c094dbb5L,0xb77d062ed968d410L,0x3e719bbc58b3002dL,\n        0x68e7dd3d3dc49d58L },\n      { 0x8d825740013a5e58L,0x213117473c9e3c1bL,0x0cb0a2a77c99b6abL,\n        0x5c48a3b3c2f888f2L } },\n    /* 0 << 56 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 56 */\n    { { 0xc7913e91991724f3L,0x5eda799c39cbd686L,0xddb595c763d4fc1eL,\n        0x6b63b80bac4fed54L },\n      { 0x6ea0fc697e5fb516L,0x737708bad0f1c964L,0x9628745f11a92ca5L,\n        0x61f379589a86967aL } },\n    /* 2 << 56 */\n    { { 0x9af39b2caa665072L,0x78322fa4efd324efL,0x3d153394c327bd31L,\n        0x81d5f2713129dab0L },\n      { 0xc72e0c42f48027f5L,0xaa40cdbc8536e717L,0xf45a657a2d369d0fL,\n        0xb03bbfc4ea7f74e6L } },\n    /* 3 << 56 */\n    { { 0x46a8c4180d738dedL,0x6f1a5bb0e0de5729L,0xf10230b98ba81675L,\n        0x32c6f30c112b33d4L },\n      { 0x7559129dd8fffb62L,0x6a281b47b459bf05L,0x77c1bd3afa3b6776L,\n        0x0709b3807829973aL } },\n    /* 4 << 56 */\n    { { 0x8c26b232a3326505L,0x38d69272ee1d41bfL,0x0459453effe32afaL,\n        0xce8143ad7cb3ea87L },\n      { 0x932ec1fa7e6ab666L,0x6cd2d23022286264L,0x459a46fe6736f8edL,\n        0x50bf0d009eca85bbL } },\n    /* 5 << 56 */\n    { { 0x0b825852877a21ecL,0x300414a70f537a94L,0x3f1cba4021a9a6a2L,\n        0x50824eee76943c00L },\n      { 0xa0dbfcecf83cba5dL,0xf953814893b4f3c0L,0x6174416248f24dd7L,\n        0x5322d64de4fb09ddL } },\n    /* 6 << 56 */\n    { { 0x574473843d9325f3L,0xa9bef2d0f371cb84L,0x77d2188ba61e36c5L,\n        0xbbd6a7d7c602df72L },\n      { 0xba3aa9028f61bc0bL,0xf49085ed6ed0b6a1L,0x8bc625d6ae6e8298L,\n        0x832b0b1da2e9c01dL } },\n    /* 7 << 56 */\n    { { 0xa337c447f1f0ced1L,0x800cc7939492dd2bL,0x4b93151dbea08efaL,\n        0x820cf3f8de0a741eL },\n      { 0xff1982dc1c0f7d13L,0xef92196084dde6caL,0x1ad7d97245f96ee3L,\n        0x319c8dbe29dea0c7L } },\n    /* 8 << 56 */\n    { { 0xd3ea38717b82b99bL,0x75922d4d470eb624L,0x8f66ec543b95d466L,\n        0x66e673ccbee1e346L },\n      { 0x6afe67c4b5f2b89aL,0x3de9c1e6290e5cd3L,0x8c278bb6310a2adaL,\n        0x420fa3840bdb323bL } },\n    /* 9 << 56 */\n    { { 0x0ae1d63b0eb919b0L,0xd74ee51da74b9620L,0x395458d0a674290cL,\n        0x324c930f4620a510L },\n      { 0x2d1f4d19fbac27d4L,0x4086e8ca9bedeeacL,0x0cdd211b9b679ab8L,\n        0x5970167d7090fec4L } },\n    /* 10 << 56 */\n    { { 0x3420f2c9faf1fc63L,0x616d333a328c8bb4L,0x7d65364c57f1fe4aL,\n        0x9343e87755e5c73aL },\n      { 0x5795176be970e78cL,0xa36ccebf60533627L,0xfc7c738009cdfc1bL,\n        0xb39a2afeb3fec326L } },\n    /* 11 << 56 */\n    { { 0xb7ff1ba16224408aL,0xcc856e92247cfc5eL,0x01f102e7c18bc493L,\n        0x4613ab742091c727L },\n      { 0xaa25e89cc420bf2bL,0x00a5317690337ec2L,0xd2be9f437d025fc7L,\n        0x3316fb856e6fe3dcL } },\n    /* 12 << 56 */\n    { { 0x27520af59ac50814L,0xfdf95e789a8e4223L,0xb7e7df2a56bec5a0L,\n        0xf7022f7ddf159e5dL },\n      { 0x93eeeab1cac1fe8fL,0x8040188c37451168L,0x7ee8aa8ad967dce6L,\n        0xfa0e79e73abc9299L } },\n    /* 13 << 56 */\n    { { 0x67332cfc2064cfd1L,0x339c31deb0651934L,0x719b28d52a3bcbeaL,\n        0xee74c82b9d6ae5c6L },\n      { 0x0927d05ebaf28ee6L,0x82cecf2c9d719028L,0x0b0d353eddb30289L,\n        0xfe4bb977fddb2e29L } },\n    /* 14 << 56 */\n    { { 0xbb5bb990640bfd9eL,0xd226e27782f62108L,0x4bf0098502ffdd56L,\n        0x7756758a2ca1b1b5L },\n      { 0xc32b62a35285fe91L,0xedbc546a8c9cd140L,0x1e47a013af5cb008L,\n        0xbca7e720073ce8f2L } },\n    /* 15 << 56 */\n    { { 0xe10b2ab817a91caeL,0xb89aab6508e27f63L,0x7b3074a7dba3ddf9L,\n        0x1c20ce09330c2972L },\n      { 0x6b9917b45fcf7e33L,0xe6793743945ceb42L,0x18fc22155c633d19L,\n        0xad1adb3cc7485474L } },\n    /* 16 << 56 */\n    { { 0x646f96796424c49bL,0xf888dfe867c241c9L,0xe12d4b9324f68b49L,\n        0x9a6b62d8a571df20L },\n      { 0x81b4b26d179483cbL,0x666f96329511fae2L,0xd281b3e4d53aa51fL,\n        0x7f96a7657f3dbd16L } },\n    /* 17 << 56 */\n    { { 0xa7f8b5bf074a30ceL,0xd7f52107005a32e6L,0x6f9e090750237ed4L,\n        0x2f21da478096fa2bL },\n      { 0xf3e19cb4eec863a0L,0xd18f77fd9527620aL,0x9505c81c407c1cf8L,\n        0x9998db4e1b6ec284L } },\n    /* 18 << 56 */\n    { { 0x7e3389e5c247d44dL,0x125071413f4f3d80L,0xd4ba01104a78a6c7L,\n        0x312874a0767720beL },\n      { 0xded059a675944370L,0xd6123d903b2c0bddL,0xa56b717b51c108e3L,\n        0x9bb7940e070623e9L } },\n    /* 19 << 56 */\n    { { 0x794e2d5984ac066cL,0xf5954a92e68c69a0L,0x28c524584fd99dccL,\n        0x60e639fcb1012517L },\n      { 0xc2e601257de79248L,0xe9ef6404f12fc6d7L,0x4c4f28082a3b5d32L,\n        0x865ad32ec768eb8aL } },\n    /* 20 << 56 */\n    { { 0xac02331b13fb70b6L,0x037b44c195599b27L,0x1a860fc460bd082cL,\n        0xa2e25745c980cd01L },\n      { 0xee3387a81da0263eL,0x931bfb952d10f3d6L,0x5b687270a1f24a32L,\n        0xf140e65dca494b86L } },\n    /* 21 << 56 */\n    { { 0x4f4ddf91b2f1ac7aL,0xf99eaabb760fee27L,0x57f4008a49c228e5L,\n        0x090be4401cf713bbL },\n      { 0xac91fbe45004f022L,0xd838c2c2569e1af6L,0xd6c7d20b0f1daaa5L,\n        0xaa063ac11bbb02c0L } },\n    /* 22 << 56 */\n    { { 0x0938a42259558a78L,0x5343c6698435da2fL,0x96f67b18034410dcL,\n        0x7cc1e42484510804L },\n      { 0x86a1543f16dfbb7dL,0x921fa9425b5bd592L,0x9dcccb6eb33dd03cL,\n        0x8581ddd9b843f51eL } },\n    /* 23 << 56 */\n    { { 0x54935fcb81d73c9eL,0x6d07e9790a5e97abL,0x4dc7b30acf3a6babL,\n        0x147ab1f3170bee11L },\n      { 0x0aaf8e3d9fafdee4L,0xfab3dbcb538a8b95L,0x405df4b36ef13871L,\n        0xf1f4e9cb088d5a49L } },\n    /* 24 << 56 */\n    { { 0x9bcd24d366b33f1dL,0x3b97b8205ce445c0L,0xe2926549ba93ff61L,\n        0xd9c341ce4dafe616L },\n      { 0xfb30a76e16efb6f3L,0xdf24b8ca605b953cL,0x8bd52afec2fffb9fL,\n        0xbbac5ff7e19d0b96L } },\n    /* 25 << 56 */\n    { { 0x43c01b87459afccdL,0x6bd45143b7432652L,0x8473453055b5d78eL,\n        0x81088fdb1554ba7dL },\n      { 0xada0a52c1e269375L,0xf9f037c42dc5ec10L,0xc066060794bfbc11L,\n        0xc0a630bbc9c40d2fL } },\n    /* 26 << 56 */\n    { { 0x5efc797eab64c31eL,0xffdb1dab74507144L,0xf61242871ca6790cL,\n        0xe9609d81e69bf1bfL },\n      { 0xdb89859500d24fc9L,0x9c750333e51fb417L,0x51830a91fef7bbdeL,\n        0x0ce67dc8945f585cL } },\n    /* 27 << 56 */\n    { { 0x9a730ed44763eb50L,0x24a0e221c1ab0d66L,0x643b6393648748f3L,\n        0x1982daa16d3c6291L },\n      { 0x6f00a9f78bbc5549L,0x7a1783e17f36384eL,0xe8346323de977f50L,\n        0x91ab688db245502aL } },\n    /* 28 << 56 */\n    { { 0x331ab6b56d0bdd66L,0x0a6ef32e64b71229L,0x1028150efe7c352fL,\n        0x27e04350ce7b39d3L },\n      { 0x2a3c8acdc1070c82L,0xfb2034d380c9feefL,0x2d729621709f3729L,\n        0x8df290bf62cb4549L } },\n    /* 29 << 56 */\n    { { 0x02f99f33fc2e4326L,0x3b30076d5eddf032L,0xbb21f8cf0c652fb5L,\n        0x314fb49eed91cf7bL },\n      { 0xa013eca52f700750L,0x2b9e3c23712a4575L,0xe5355557af30fbb0L,\n        0x1ada35167c77e771L } },\n    /* 30 << 56 */\n    { { 0x45f6ecb27b135670L,0xe85d19df7cfc202eL,0x0f1b50c758d1be9fL,\n        0x5ebf2c0aead2e344L },\n      { 0x1531fe4eabc199c9L,0xc703259256bab0aeL,0x16ab2e486c1fec54L,\n        0x0f87fda804280188L } },\n    /* 31 << 56 */\n    { { 0xdc9f46fc609e4a74L,0x2a44a143ba667f91L,0xbc3d8b95b4d83436L,\n        0xa01e4bd0c7bd2958L },\n      { 0x7b18293273483c90L,0xa79c6aa1a7c7b598L,0xbf3983c6eaaac07eL,\n        0x8f18181e96e0d4e6L } },\n    /* 32 << 56 */\n    { { 0x8553d37c051af62bL,0xe9a998eb0bf94496L,0xe0844f9fb0d59aa1L,\n        0x983fd558e6afb813L },\n      { 0x9670c0ca65d69804L,0x732b22de6ea5ff2dL,0xd7640ba95fd8623bL,\n        0x9f619163a6351782L } },\n    /* 33 << 56 */\n    { { 0x0bfc27eeacee5043L,0xae419e732eb10f02L,0x19c028d18943fb05L,\n        0x71f01cf7ff13aa2aL },\n      { 0x7790737e8887a132L,0x6751330966318410L,0x9819e8a37ddb795eL,\n        0xfecb8ef5dad100b2L } },\n    /* 34 << 56 */\n    { { 0x59f74a223021926aL,0xb7c28a496f9b4c1cL,0xed1a733f912ad0abL,\n        0x42a910af01a5659cL },\n      { 0x3842c6e07bd68cabL,0x2b57fa3876d70ac8L,0x8a6707a83c53aaebL,\n        0x62c1c51065b4db18L } },\n    /* 35 << 56 */\n    { { 0x8de2c1fbb2d09dc7L,0xc3dfed12266bd23bL,0x927d039bd5b27db6L,\n        0x2fb2f0f1103243daL },\n      { 0xf855a07b80be7399L,0xed9327ce1f9f27a8L,0xa0bd99c7729bdef7L,\n        0x2b67125e28250d88L } },\n    /* 36 << 56 */\n    { { 0x784b26e88670ced7L,0xe3dfe41fc31bd3b4L,0x9e353a06bcc85cbcL,\n        0x302e290960178a9dL },\n      { 0x860abf11a6eac16eL,0x76447000aa2b3aacL,0x46ff9d19850afdabL,\n        0x35bdd6a5fdb2d4c1L } },\n    /* 37 << 56 */\n    { { 0xe82594b07e5c9ce9L,0x0f379e5320af346eL,0x608b31e3bc65ad4aL,\n        0x710c6b12267c4826L },\n      { 0x51c966f971954cf1L,0xb1cec7930d0aa215L,0x1f15598986bd23a8L,\n        0xae2ff99cf9452e86L } },\n    /* 38 << 56 */\n    { { 0xd8dd953c340ceaa2L,0x263552752e2e9333L,0x15d4e5f98586f06dL,\n        0xd6bf94a8f7cab546L },\n      { 0x33c59a0ab76a9af0L,0x52740ab3ba095af7L,0xc444de8a24389ca0L,\n        0xcc6f9863706da0cbL } },\n    /* 39 << 56 */\n    { { 0xb5a741a76b2515cfL,0x71c416019585c749L,0x78350d4fe683de97L,\n        0x31d6152463d0b5f5L },\n      { 0x7a0cc5e1fbce090bL,0xaac927edfbcb2a5bL,0xe920de4920d84c35L,\n        0x8c06a0b622b4de26L } },\n    /* 40 << 56 */\n    { { 0xd34dd58bafe7ddf3L,0x55851fedc1e6e55bL,0xd1395616960696e7L,\n        0x940304b25f22705fL },\n      { 0x6f43f861b0a2a860L,0xcf1212820e7cc981L,0x121862120ab64a96L,\n        0x09215b9ab789383cL } },\n    /* 41 << 56 */\n    { { 0x311eb30537387c09L,0xc5832fcef03ee760L,0x30358f5832f7ea19L,\n        0xe01d3c3491d53551L },\n      { 0x1ca5ee41da48ea80L,0x34e71e8ecf4fa4c1L,0x312abd257af1e1c7L,\n        0xe3afcdeb2153f4a5L } },\n    /* 42 << 56 */\n    { { 0x9d5c84d700235e9aL,0x0308d3f48c4c836fL,0xc0a66b0489332de5L,\n        0x610dd39989e566efL },\n      { 0xf8eea460d1ac1635L,0x84cbb3fb20a2c0dfL,0x40afb488e74a48c5L,\n        0x29738198d326b150L } },\n    /* 43 << 56 */\n    { { 0x2a17747fa6d74081L,0x60ea4c0555a26214L,0x53514bb41f88c5feL,\n        0xedd645677e83426cL },\n      { 0xd5d6cbec96460b25L,0xa12fd0ce68dc115eL,0xc5bc3ed2697840eaL,\n        0x969876a8a6331e31L } },\n    /* 44 << 56 */\n    { { 0x60c36217472ff580L,0xf42297054ad41393L,0x4bd99ef0a03b8b92L,\n        0x501c7317c144f4f6L },\n      { 0x159009b318464945L,0x6d5e594c74c5c6beL,0x2d587011321a3660L,\n        0xd1e184b13898d022L } },\n    /* 45 << 56 */\n    { { 0x5ba047524c6a7e04L,0x47fa1e2b45550b65L,0x9419daf048c0a9a5L,\n        0x663629537c243236L },\n      { 0xcd0744b15cb12a88L,0x561b6f9a2b646188L,0x599415a566c2c0c0L,\n        0xbe3f08590f83f09aL } },\n    /* 46 << 56 */\n    { { 0x9141c5beb92041b8L,0x01ae38c726477d0dL,0xca8b71f3d12c7a94L,\n        0xfab5b31f765c70dbL },\n      { 0x76ae7492487443e9L,0x8595a310990d1349L,0xf8dbeda87d460a37L,\n        0x7f7ad0821e45a38fL } },\n    /* 47 << 56 */\n    { { 0xed1d4db61059705aL,0xa3dd492ae6b9c697L,0x4b92ee3a6eb38bd5L,\n        0xbab2609d67cc0bb7L },\n      { 0x7fc4fe896e70ee82L,0xeff2c56e13e6b7e3L,0x9b18959e34d26fcaL,\n        0x2517ab66889d6b45L } },\n    /* 48 << 56 */\n    { { 0xf167b4e0bdefdd4fL,0x69958465f366e401L,0x5aa368aba73bbec0L,\n        0x121487097b240c21L },\n      { 0x378c323318969006L,0xcb4d73cee1fe53d1L,0x5f50a80e130c4361L,\n        0xd67f59517ef5212bL } },\n    /* 49 << 56 */\n    { { 0xf145e21e9e70c72eL,0xb2e52e295566d2fbL,0x44eaba4a032397f5L,\n        0x5e56937b7e31a7deL },\n      { 0x68dcf517456c61e1L,0xbc2e954aa8b0a388L,0xe3552fa760a8b755L,\n        0x03442dae73ad0cdeL } },\n    /* 50 << 56 */\n    { { 0x37ffe747ceb26210L,0x983545e8787baef9L,0x8b8c853586a3de31L,\n        0xc621dbcbfacd46dbL },\n      { 0x82e442e959266fbbL,0xa3514c37339d471cL,0x3a11b77162cdad96L,\n        0xf0cb3b3cecf9bdf0L } },\n    /* 51 << 56 */\n    { { 0x3fcbdbce478e2135L,0x7547b5cfbda35342L,0xa97e81f18a677af6L,\n        0xc8c2bf8328817987L },\n      { 0xdf07eaaf45580985L,0xc68d1f05c93b45cbL,0x106aa2fec77b4cacL,\n        0x4c1d8afc04a7ae86L } },\n    /* 52 << 56 */\n    { { 0xdb41c3fd9eb45ab2L,0x5b234b5bd4b22e74L,0xda253decf215958aL,\n        0x67e0606ea04edfa0L },\n      { 0xabbbf070ef751b11L,0xf352f175f6f06dceL,0xdfc4b6af6839f6b4L,\n        0x53ddf9a89959848eL } },\n    /* 53 << 56 */\n    { { 0xda49c379c21520b0L,0x90864ff0dbd5d1b6L,0x2f055d235f49c7f7L,\n        0xe51e4e6aa796b2d8L },\n      { 0xc361a67f5c9dc340L,0x5ad53c37bca7c620L,0xda1d658832c756d0L,\n        0xad60d9118bb67e13L } },\n    /* 54 << 56 */\n    { { 0xd6c47bdf0eeec8c6L,0x4a27fec1078a1821L,0x081f7415c3099524L,\n        0x8effdf0b82cd8060L },\n      { 0xdb70ec1c65842df8L,0x8821b358d319a901L,0x72ee56eede42b529L,\n        0x5bb39592236e4286L } },\n    /* 55 << 56 */\n    { { 0xd1183316fd6f7140L,0xf9fadb5bbd8e81f7L,0x701d5e0c5a02d962L,\n        0xfdee4dbf1b601324L },\n      { 0xbed1740735d7620eL,0x04e3c2c3f48c0012L,0x9ee29da73455449aL,\n        0x562cdef491a836c4L } },\n    /* 56 << 56 */\n    { { 0x8f682a5f47701097L,0x617125d8ff88d0c2L,0x948fda2457bb86ddL,\n        0x348abb8f289f7286L },\n      { 0xeb10eab599d94bbdL,0xd51ba28e4684d160L,0xabe0e51c30c8f41aL,\n        0x66588b4513254f4aL } },\n    /* 57 << 56 */\n    { { 0x147ebf01fad097a5L,0x49883ea8610e815dL,0xe44d60ba8a11de56L,\n        0xa970de6e827a7a6dL },\n      { 0x2be414245e17fc19L,0xd833c65701214057L,0x1375813b363e723fL,\n        0x6820bb88e6a52e9bL } },\n    /* 58 << 56 */\n    { { 0x7e7f6970d875d56aL,0xd6a0a9ac51fbf6bfL,0x54ba8790a3083c12L,\n        0xebaeb23d6ae7eb64L },\n      { 0xa8685c3ab99a907aL,0xf1e74550026bf40bL,0x7b73a027c802cd9eL,\n        0x9a8a927c4fef4635L } },\n    /* 59 << 56 */\n    { { 0xe1b6f60c08191224L,0xc4126ebbde4ec091L,0xe1dff4dc4ae38d84L,\n        0xde3f57db4f2ef985L },\n      { 0x34964337d446a1ddL,0x7bf217a0859e77f6L,0x8ff105278e1d13f5L,\n        0xa304ef0374eeae27L } },\n    /* 60 << 56 */\n    { { 0xfc6f5e47d19dfa5aL,0xdb007de37fad982bL,0x28205ad1613715f5L,\n        0x251e67297889529eL },\n      { 0x727051841ae98e78L,0xf818537d271cac32L,0xc8a15b7eb7f410f5L,\n        0xc474356f81f62393L } },\n    /* 61 << 56 */\n    { { 0x92dbdc5ac242316bL,0xabe060acdbf4aff5L,0x6e8c38fe909a8ec6L,\n        0x43e514e56116cb94L },\n      { 0x2078fa3807d784f9L,0x1161a880f4b5b357L,0x5283ce7913adea3dL,\n        0x0756c3e6cc6a910bL } },\n    /* 62 << 56 */\n    { { 0x60bcfe01aaa79697L,0x04a73b2956391db1L,0xdd8dad47189b45a0L,\n        0xbfac0dd048d5b8d9L },\n      { 0x34ab3af57d3d2ec2L,0x6fa2fc2d207bd3afL,0x9ff4009266550dedL,\n        0x719b3e871fd5b913L } },\n    /* 63 << 56 */\n    { { 0xa573a4966d17fbc7L,0x0cd1a70a73d2b24eL,0x34e2c5cab2676937L,\n        0xe7050b06bf669f21L },\n      { 0xfbe948b61ede9046L,0xa053005197662659L,0x58cbd4edf10124c5L,\n        0xde2646e4dd6c06c8L } },\n    /* 64 << 56 */\n    { { 0x332f81088cad38c0L,0x471b7e906bd68ae2L,0x56ac3fb20d8e27a3L,\n        0xb54660db136b4b0dL },\n      { 0x123a1e11a6fd8de4L,0x44dbffeaa37799efL,0x4540b977ce6ac17cL,\n        0x495173a8af60acefL } },\n    /* 0 << 63 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 63 */\n    { { 0x9ebb284d391c2a82L,0xbcdd4863158308e8L,0x006f16ec83f1edcaL,\n        0xa13e2c37695dc6c8L },\n      { 0x2ab756f04a057a87L,0xa8765500a6b48f98L,0x4252face68651c44L,\n        0xa52b540be1765e02L } },\n    /* 2 << 63 */\n    { { 0x4f922fc516a0d2bbL,0x0d5cc16c1a623499L,0x9241cf3a57c62c8bL,\n        0x2f5e6961fd1b667fL },\n      { 0x5c15c70bf5a01797L,0x3d20b44d60956192L,0x04911b37071fdb52L,\n        0xf648f9168d6f0f7bL } },\n    /* 3 << 63 */\n    { { 0x6dc1acafe60b7cf7L,0x25860a5084a9d869L,0x56fc6f09e7ba8ac4L,\n        0x828c5bd06148d29eL },\n      { 0xac6b435edc55ae5fL,0xa527f56cc0117411L,0x94d5045efd24342cL,\n        0x2c4c0a3570b67c0dL } },\n    /* 4 << 63 */\n    { { 0x027cc8b8fac61d9aL,0x7d25e062e3c6fe8aL,0xe08805bfe5bff503L,\n        0x13271e6c6ff632f7L },\n      { 0x55dca6c0232f76a5L,0x8957c32d701ef426L,0xee728bcba10a5178L,\n        0x5ea60411b62c5173L } },\n    /* 5 << 63 */\n    { { 0xfc4e964ed0b8892bL,0x9ea176839301bb74L,0x6265c5aefcc48626L,\n        0xe60cf82ebb3e9102L },\n      { 0x57adf797d4df5531L,0x235b59a18deeefe2L,0x60adcf583f306eb1L,\n        0x105c27533d09492dL } },\n    /* 6 << 63 */\n    { { 0x4090914bb5def996L,0x1cb69c83233dd1e7L,0xc1e9c1d39b3d5e76L,\n        0x1f3338edfccf6012L },\n      { 0xb1e95d0d2f5378a8L,0xacf4c2c72f00cd21L,0x6e984240eb5fe290L,\n        0xd66c038d248088aeL } },\n    /* 7 << 63 */\n    { { 0x804d264af94d70cfL,0xbdb802ef7314bf7eL,0x8fb54de24333ed02L,\n        0x740461e0285635d9L },\n      { 0x4113b2c8365e9383L,0xea762c833fdef652L,0x4eec6e2e47b956c1L,\n        0xa3d814be65620fa4L } },\n    /* 8 << 63 */\n    { { 0x9ad5462bb4d8bc50L,0x181c0b16a9195770L,0xebd4fe1c78412a68L,\n        0xae0341bcc0dff48cL },\n      { 0xb6bc45cf7003e866L,0xf11a6dea8a24a41bL,0x5407151ad04c24c2L,\n        0x62c9d27dda5b7b68L } },\n    /* 9 << 63 */\n    { { 0x2e96423588cceff6L,0x8594c54f8b07ed69L,0x1578e73cc84d0d0dL,\n        0x7b4e1055ff532868L },\n      { 0xa348c0d5b5ec995aL,0xbf4b9d5514289a54L,0x9ba155a658fbd777L,\n        0x186ed7a81a84491dL } },\n    /* 10 << 63 */\n    { { 0xd4992b30614c0900L,0xda98d121bd00c24bL,0x7f534dc87ec4bfa1L,\n        0x4a5ff67437dc34bcL },\n      { 0x68c196b81d7ea1d7L,0x38cf289380a6d208L,0xfd56cd09e3cbbd6eL,\n        0xec72e27e4205a5b6L } },\n    /* 11 << 63 */\n    { { 0x15ea68f5a44f77f7L,0x7aa5f9fdb43c52bcL,0x86ff676f94f0e609L,\n        0xa4cde9632e2d432bL },\n      { 0x8cafa0c0eee470afL,0x84137d0e8a3f5ec8L,0xebb40411faa31231L,\n        0xa239c13f6f7f7ccfL } },\n    /* 12 << 63 */\n    { { 0x32865719a8afd30bL,0x867983288a826dceL,0xdf04e891c4a8fbe0L,\n        0xbb6b6e1bebf56ad3L },\n      { 0x0a695b11471f1ff0L,0xd76c3389be15baf0L,0x018edb95be96c43eL,\n        0xf2beaaf490794158L } },\n    /* 13 << 63 */\n    { { 0x152db09ec3076a27L,0x5e82908ee416545dL,0xa2c41272356d6f2eL,\n        0xdc9c964231fd74e1L },\n      { 0x66ceb88d519bf615L,0xe29ecd7605a2274eL,0x3a0473c4bf5e2fa0L,\n        0x6b6eb67164284e67L } },\n    /* 14 << 63 */\n    { { 0xe8b97932b88756ddL,0xed4e8652f17e3e61L,0xc2dd14993ee1c4a4L,\n        0xc0aaee17597f8c0eL },\n      { 0x15c4edb96c168af3L,0x6563c7bfb39ae875L,0xadfadb6f20adb436L,\n        0xad55e8c99a042ac0L } },\n    /* 15 << 63 */\n    { { 0x975a1ed8b76da1f5L,0x10dfa466a58acb94L,0x8dd7f7e3ac060282L,\n        0x6813e66a572a051eL },\n      { 0xb4ccae1e350cb901L,0xb653d65650cb7822L,0x42484710dfab3b87L,\n        0xcd7ee5379b670fd0L } },\n    /* 16 << 63 */\n    { { 0x0a50b12e523b8bf6L,0x8009eb5b8f910c1bL,0xf535af824a167588L,\n        0x0f835f9cfb2a2abdL },\n      { 0xf59b29312afceb62L,0xc797df2a169d383fL,0xeb3f5fb066ac02b0L,\n        0x029d4c6fdaa2d0caL } },\n    /* 17 << 63 */\n    { { 0xd4059bc1afab4bc5L,0x833f5c6f56783247L,0xb53466308d2d3605L,\n        0x83387891d34d8433L },\n      { 0xd973b30fadd9419aL,0xbcca1099afe3fce8L,0x081783150809aac6L,\n        0x01b7f21a540f0f11L } },\n    /* 18 << 63 */\n    { { 0x65c29219909523c8L,0xa62f648fa3a1c741L,0x88598d4f60c9e55aL,\n        0xbce9141b0e4f347aL },\n      { 0x9af97d8435f9b988L,0x0210da62320475b6L,0x3c076e229191476cL,\n        0x7520dbd944fc7834L } },\n    /* 19 << 63 */\n    { { 0x6a6b2cfec1ab1bbdL,0xef8a65bedc650938L,0x72855540805d7bc4L,\n        0xda389396ed11fdfdL },\n      { 0xa9d5bd3674660876L,0x11d67c54b45dff35L,0x6af7d148a4f5da94L,\n        0xbb8d4c3fc0bbeb31L } },\n    /* 20 << 63 */\n    { { 0x87a7ebd1e0a1b12aL,0x1e4ef88d770ba95fL,0x8c33345cdc2ae9cbL,\n        0xcecf127601cc8403L },\n      { 0x687c012e1b39b80fL,0xfd90d0ad35c33ba4L,0xa3ef5a675c9661c2L,\n        0x368fc88ee017429eL } },\n    /* 21 << 63 */\n    { { 0xd30c6761196a2fa2L,0x931b9817bd5b312eL,0xba01000c72f54a31L,\n        0xa203d2c866eaa541L },\n      { 0xf2abdee098939db3L,0xe37d6c2c3e606c02L,0xf2921574521ff643L,\n        0x2781b3c4d7e2fca3L } },\n    /* 22 << 63 */\n    { { 0x664300b07850ec06L,0xac5a38b97d3a10cfL,0x9233188de34ab39dL,\n        0xe77057e45072cbb9L },\n      { 0xbcf0c042b59e78dfL,0x4cfc91e81d97de52L,0x4661a26c3ee0ca4aL,\n        0x5620a4c1fb8507bcL } },\n    /* 23 << 63 */\n    { { 0x4b44d4aa049f842cL,0xceabc5d51540e82bL,0x306710fd15c6f156L,\n        0xbe5ae52b63db1d72L },\n      { 0x06f1e7e6334957f1L,0x57e388f031144a70L,0xfb69bb2fdf96447bL,\n        0x0f78ebd373e38a12L } },\n    /* 24 << 63 */\n    { { 0xb82226052b7ce542L,0xe6d4ce997472bde1L,0x53e16ebe09d2f4daL,\n        0x180ff42e53b92b2eL },\n      { 0xc59bcc022c34a1c6L,0x3803d6f9422c46c2L,0x18aff74f5c14a8a2L,\n        0x55aebf8010a08b28L } },\n    /* 25 << 63 */\n    { { 0x66097d587135593fL,0x32e6eff72be570cdL,0x584e6a102a8c860dL,\n        0xcd185890a2eb4163L },\n      { 0x7ceae99d6d97e134L,0xd42c6b70dd8447ceL,0x59ddbb4ab8c50273L,\n        0x03c612df3cf34e1eL } },\n    /* 26 << 63 */\n    { { 0x84b9ca1504b6c5a0L,0x35216f3918f0e3a3L,0x3ec2d2bcbd986c00L,\n        0x8bf546d9d19228feL },\n      { 0xd1c655a44cd623c3L,0x366ce718502b8e5aL,0x2cfc84b4eea0bfe7L,\n        0xe01d5ceecf443e8eL } },\n    /* 27 << 63 */\n    { { 0x8ec045d9036520f8L,0xdfb3c3d192d40e98L,0x0bac4ccecc559a04L,\n        0x35eccae5240ea6b1L },\n      { 0x180b32dbf8a5a0acL,0x547972a5eb699700L,0xa3765801ca26bca0L,\n        0x57e09d0ea647f25aL } },\n    /* 28 << 63 */\n    { { 0xb956970e2fdd23ccL,0xb80288bc5682e971L,0xe6e6d91e9ae86ebcL,\n        0x0564c83f8c9f1939L },\n      { 0x551932a239560368L,0xe893752b049c28e2L,0x0b03cee5a6a158c3L,\n        0xe12d656b04964263L } },\n    /* 29 << 63 */\n    { { 0x4b47554e63e3bc1dL,0xc719b6a245044ff7L,0x4f24d30ae48daa07L,\n        0xa3f37556c8c1edc3L },\n      { 0x9a47bf760700d360L,0xbb1a1824822ae4e2L,0x22e275a389f1fb4cL,\n        0x72b1aa239968c5f5L } },\n    /* 30 << 63 */\n    { { 0xa75feacabe063f64L,0x9b392f43bce47a09L,0xd42415091ad07acaL,\n        0x4b0c591b8d26cd0fL },\n      { 0x2d42ddfd92f1169aL,0x63aeb1ac4cbf2392L,0x1de9e8770691a2afL,\n        0xebe79af7d98021daL } },\n    /* 31 << 63 */\n    { { 0xcfdf2a4e40e50acfL,0xf0a98ad7af01d665L,0xefb640bf1831be1fL,\n        0x6fe8bd2f80e9ada0L },\n      { 0x94c103a16cafbc91L,0x170f87598308e08cL,0x5de2d2ab9780ff4fL,\n        0x666466bc45b201f2L } },\n    /* 32 << 63 */\n    { { 0x58af2010f5b343bcL,0x0f2e400af2f142feL,0x3483bfdea85f4bdfL,\n        0xf0b1d09303bfeaa9L },\n      { 0x2ea01b95c7081603L,0xe943e4c93dba1097L,0x47be92adb438f3a6L,\n        0x00bb7742e5bf6636L } },\n    /* 33 << 63 */\n    { { 0x136b7083824297b4L,0x9d0e55805584455fL,0xab48cedcf1c7d69eL,\n        0x53a9e4812a256e76L },\n      { 0x0402b0e065eb2413L,0xdadbbb848fc407a7L,0xa65cd5a48d7f5492L,\n        0x21d4429374bae294L } },\n    /* 34 << 63 */\n    { { 0x66917ce63b5f1cc4L,0x37ae52eace872e62L,0xbb087b722905f244L,\n        0x120770861e6af74fL },\n      { 0x4b644e491058edeaL,0x827510e3b638ca1dL,0x8cf2b7046038591cL,\n        0xffc8b47afe635063L } },\n    /* 35 << 63 */\n    { { 0x3ae220e61b4d5e63L,0xbd8647429d961b4bL,0x610c107e9bd16bedL,\n        0x4270352a1127147bL },\n      { 0x7d17ffe664cfc50eL,0x50dee01a1e36cb42L,0x068a762235dc5f9aL,\n        0x9a08d536df53f62cL } },\n    /* 36 << 63 */\n    { { 0x4ed714576be5f7deL,0xd93006f8c2263c9eL,0xe073694ccacacb36L,\n        0x2ff7a5b43ae118abL },\n      { 0x3cce53f1cd871236L,0xf156a39dc2aa6d52L,0x9cc5f271b198d76dL,\n        0xbc615b6f81383d39L } },\n    /* 37 << 63 */\n    { { 0xa54538e8de3eee6bL,0x58c77538ab910d91L,0x31e5bdbc58d278bdL,\n        0x3cde4adfb963acaeL },\n      { 0xb1881fd25302169cL,0x8ca60fa0a989ed8bL,0xa1999458ff96a0eeL,\n        0xc1141f03ac6c283dL } },\n    /* 38 << 63 */\n    { { 0x7677408d6dfafed3L,0x33a0165339661588L,0x3c9c15ec0b726fa0L,\n        0x090cfd936c9b56daL },\n      { 0xe34f4baea3c40af5L,0x3469eadbd21129f1L,0xcc51674a1e207ce8L,\n        0x1e293b24c83b1ef9L } },\n    /* 39 << 63 */\n    { { 0x17173d131e6c0bb4L,0x1900469590776d35L,0xe7980e346de6f922L,\n        0x873554cbf4dd9a22L },\n      { 0x0316c627cbf18a51L,0x4d93651b3032c081L,0x207f27713946834dL,\n        0x2c08d7b430cdbf80L } },\n    /* 40 << 63 */\n    { { 0x137a4fb486df2a61L,0xa1ed9c07ecf7b4a2L,0xb2e460e27bd042ffL,\n        0xb7f5e2fa5f62f5ecL },\n      { 0x7aa6ec6bcc2423b7L,0x75ce0a7fba63eea7L,0x67a45fb1f250a6e1L,\n        0x93bc919ce53cdc9fL } },\n    /* 41 << 63 */\n    { { 0x9271f56f871942dfL,0x2372ff6f7859ad66L,0x5f4c2b9633cb1a78L,\n        0xe3e291015838aa83L },\n      { 0xa7ed1611e4e8110cL,0x2a2d70d5330198ceL,0xbdf132e86720efe0L,\n        0xe61a896266a471bfL } },\n    /* 42 << 63 */\n    { { 0x796d3a85825808bdL,0x51dc3cb73fd6e902L,0x643c768a916219d1L,\n        0x36cd7685a2ad7d32L },\n      { 0xe3db9d05b22922a4L,0x6494c87edba29660L,0xf0ac91dfbcd2ebc7L,\n        0x4deb57a045107f8dL } },\n    /* 43 << 63 */\n    { { 0x42271f59c3d12a73L,0x5f71687ca5c2c51dL,0xcb1f50c605797bcbL,\n        0x29ed0ed9d6d34eb0L },\n      { 0xe5fe5b474683c2ebL,0x4956eeb597447c46L,0x5b163a4371207167L,\n        0x93fa2fed0248c5efL } },\n    /* 44 << 63 */\n    { { 0x67930af231f63950L,0xa77797c114caa2c9L,0x526e80ee27ac7e62L,\n        0xe1e6e62658b28aecL },\n      { 0x636178b0b3c9fef0L,0xaf7752e06d5f90beL,0x94ecaf18eece51cfL,\n        0x2864d0edca806e1fL } },\n    /* 45 << 63 */\n    { { 0x6de2e38397c69134L,0x5a42c316eb291293L,0xc77792196a60bae0L,\n        0xa24de3466b7599d1L },\n      { 0x49d374aab75d4941L,0x989005862d501ff0L,0x9f16d40eeb7974cfL,\n        0x1033860bcdd8c115L } },\n    /* 46 << 63 */\n    { { 0xb6c69ac82094cec3L,0x9976fb88403b770cL,0x1dea026c4859590dL,\n        0xb6acbb468562d1fdL },\n      { 0x7cd6c46144569d85L,0xc3190a3697f0891dL,0xc6f5319548d5a17dL,\n        0x7d919966d749abc8L } },\n    /* 47 << 63 */\n    { { 0x65104837dd1c8a20L,0x7e5410c82f683419L,0x958c3ca8be94022eL,\n        0x605c31976145dac2L },\n      { 0x3fc0750101683d54L,0x1d7127c5595b1234L,0x10b8f87c9481277fL,\n        0x677db2a8e65a1adbL } },\n    /* 48 << 63 */\n    { { 0xec2fccaaddce3345L,0x2a6811b7012a4350L,0x96760ff1ac598bdcL,\n        0x054d652ad1bf4128L },\n      { 0x0a1151d492a21005L,0xad7f397133110fdfL,0x8c95928c1960100fL,\n        0x6c91c8257bf03362L } },\n    /* 49 << 63 */\n    { { 0xc8c8b2a2ce309f06L,0xfdb27b59ca27204bL,0xd223eaa50848e32eL,\n        0xb93e4b2ee7bfaf1eL },\n      { 0xc5308ae644aa3dedL,0x317a666ac015d573L,0xc888ce231a979707L,\n        0xf141c1e60d5c4958L } },\n    /* 50 << 63 */\n    { { 0xb53b7de561906373L,0x858dbadeeb999595L,0x8cbb47b2a59e5c36L,\n        0x660318b3dcf4e842L },\n      { 0xbd161ccd12ba4b7aL,0xf399daabf8c8282aL,0x1587633aeeb2130dL,\n        0xa465311ada38dd7dL } },\n    /* 51 << 63 */\n    { { 0x5f75eec864d3779bL,0x3c5d0476ad64c171L,0x874103712a914428L,\n        0x8096a89190e2fc29L },\n      { 0xd3d2ae9d23b3ebc2L,0x90bdd6dba580cfd6L,0x52dbb7f3c5b01f6cL,\n        0xe68eded4e102a2dcL } },\n    /* 52 << 63 */\n    { { 0x17785b7799eb6df0L,0x26c3cc517386b779L,0x345ed9886417a48eL,\n        0xe990b4e407d6ef31L },\n      { 0x0f456b7e2586abbaL,0x239ca6a559c96e9aL,0xe327459ce2eb4206L,\n        0x3a4c3313a002b90aL } },\n    /* 53 << 63 */\n    { { 0x2a114806f6a3f6fbL,0xad5cad2f85c251ddL,0x92c1f613f5a784d3L,\n        0xec7bfacf349766d5L },\n      { 0x04b3cd333e23cb3bL,0x3979fe84c5a64b2dL,0x192e27207e589106L,\n        0xa60c43d1a15b527fL } },\n    /* 54 << 63 */\n    { { 0x2dae9082be7cf3a6L,0xcc86ba92bc967274L,0xf28a2ce8aea0a8a9L,\n        0x404ca6d96ee988b3L },\n      { 0xfd7e9c5d005921b8L,0xf56297f144e79bf9L,0xa163b4600d75ddc2L,\n        0x30b23616a1f2be87L } },\n    /* 55 << 63 */\n    { { 0x4b070d21bfe50e2bL,0x7ef8cfd0e1bfede1L,0xadba00112aac4ae0L,\n        0x2a3e7d01b9ebd033L },\n      { 0x995277ece38d9d1cL,0xb500249e9c5d2de3L,0x8912b820f13ca8c9L,\n        0xc8798114877793afL } },\n    /* 56 << 63 */\n    { { 0x19e6125dec3f1decL,0x07b1f040911178daL,0xd93ededa904a6738L,\n        0x55187a5a0bebedcdL },\n      { 0xf7d04722eb329d41L,0xf449099ef170b391L,0xfd317a69ca99f828L,\n        0x50c3db2b34a4976dL } },\n    /* 57 << 63 */\n    { { 0xe9ba77843757b392L,0x326caefdaa3ca05aL,0x78e5293bf1e593d4L,\n        0x7842a9370d98fd13L },\n      { 0xe694bf965f96b10dL,0x373a9df606a8cd05L,0x997d1e51e8f0c7fcL,\n        0x1d01979063fd972eL } },\n    /* 58 << 63 */\n    { { 0x0064d8585499fb32L,0x7b67bad977a8aeb7L,0x1d3eb9772d08eec5L,\n        0x5fc047a6cbabae1dL },\n      { 0x0577d159e54a64bbL,0x8862201bc43497e4L,0xad6b4e282ce0608dL,\n        0x8b687b7d0b167aacL } },\n    /* 59 << 63 */\n    { { 0x6ed4d3678b2ecfa9L,0x24dfe62da90c3c38L,0xa1862e103fe5c42bL,\n        0x1ca73dcad5732a9fL },\n      { 0x35f038b776bb87adL,0x674976abf242b81fL,0x4f2bde7eb0fd90cdL,\n        0x6efc172ea7fdf092L } },\n    /* 60 << 63 */\n    { { 0x3806b69b92222f1fL,0x5a2459ca6cf7ae70L,0x6789f69ca85217eeL,\n        0x5f232b5ee3dc85acL },\n      { 0x660e3ec548e9e516L,0x124b4e473197eb31L,0x10a0cb13aafcca23L,\n        0x7bd63ba48213224fL } },\n    /* 61 << 63 */\n    { { 0xaffad7cc290a7f4fL,0x6b409c9e0286b461L,0x58ab809fffa407afL,\n        0xc3122eedc68ac073L },\n      { 0x17bf9e504ef24d7eL,0x5d9297943e2a5811L,0x519bc86702902e01L,\n        0x76bba5da39c8a851L } },\n    /* 62 << 63 */\n    { { 0xe9f9669cda94951eL,0x4b6af58d66b8d418L,0xfa32107417d426a4L,\n        0xc78e66a99dde6027L },\n      { 0x0516c0834a53b964L,0xfc659d38ff602330L,0x0ab55e5c58c5c897L,\n        0x985099b2838bc5dfL } },\n    /* 63 << 63 */\n    { { 0x061d9efcc52fc238L,0x712b27286ac1da3fL,0xfb6581499283fe08L,\n        0x4954ac94b8aaa2f7L },\n      { 0x85c0ada47fb2e74fL,0xee8ba98eb89926b0L,0xe4f9d37d23d1af5bL,\n        0x14ccdbf9ba9b015eL } },\n    /* 64 << 63 */\n    { { 0xb674481b7bfe7178L,0x4e1debae65405868L,0x061b2821c48c867dL,\n        0x69c15b35513b30eaL },\n      { 0x3b4a166636871088L,0xe5e29f5d1220b1ffL,0x4b82bb35233d9f4dL,\n        0x4e07633318cdc675L } },\n    /* 0 << 70 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 70 */\n    { { 0x0d53f5c7a3e6fcedL,0xe8cbbdd5f45fbdebL,0xf85c01df13339a70L,\n        0x0ff71880142ceb81L },\n      { 0x4c4e8774bd70437aL,0x5fb32891ba0bda6aL,0x1cdbebd2f18bd26eL,\n        0x2f9526f103a9d522L } },\n    /* 2 << 70 */\n    { { 0x40ce305192c4d684L,0x8b04d7257612efcdL,0xb9dcda366f9cae20L,\n        0x0edc4d24f058856cL },\n      { 0x64f2e6bf85427900L,0x3de81295dc09dfeaL,0xd41b4487379bf26cL,\n        0x50b62c6d6df135a9L } },\n    /* 3 << 70 */\n    { { 0xd4f8e3b4c72dfe67L,0xc416b0f690e19fdfL,0x18b9098d4c13bd35L,\n        0xac11118a15b8cb9eL },\n      { 0xf598a318f0062841L,0xbfe0602f89f356f4L,0x7ae3637e30177a0cL,\n        0x3409774761136537L } },\n    /* 4 << 70 */\n    { { 0x0db2fb5ed005832aL,0x5f5efd3b91042e4fL,0x8c4ffdc6ed70f8caL,\n        0xe4645d0bb52da9ccL },\n      { 0x9596f58bc9001d1fL,0x52c8f0bc4e117205L,0xfd4aa0d2e398a084L,\n        0x815bfe3a104f49deL } },\n    /* 5 << 70 */\n    { { 0x97e5443f23885e5fL,0xf72f8f99e8433aabL,0xbd00b154e4d4e604L,\n        0xd0b35e6ae5e173ffL },\n      { 0x57b2a0489164722dL,0x3e3c665b88761ec8L,0x6bdd13973da83832L,\n        0x3c8b1a1e73dafe3bL } },\n    /* 6 << 70 */\n    { { 0x4497ace654317cacL,0xbe600ab9521771b3L,0xb42e409eb0dfe8b8L,\n        0x386a67d73942310fL },\n      { 0x25548d8d4431cc28L,0xa7cff142985dc524L,0x4d60f5a193c4be32L,\n        0x83ebd5c8d071c6e1L } },\n    /* 7 << 70 */\n    { { 0xba3a80a7b1fd2b0bL,0x9b3ad3965bec33e8L,0xb3868d6179743fb3L,\n        0xcfd169fcfdb462faL },\n      { 0xd3b499d79ce0a6afL,0x55dc1cf1e42d3ff8L,0x04fb9e6cc6c3e1b2L,\n        0x47e6961d6f69a474L } },\n    /* 8 << 70 */\n    { { 0x54eb3acce548b37bL,0xb38e754284d40549L,0x8c3daa517b341b4fL,\n        0x2f6928ec690bf7faL },\n      { 0x0496b32386ce6c41L,0x01be1c5510adadcdL,0xc04e67e74bb5faf9L,\n        0x3cbaf678e15c9985L } },\n    /* 9 << 70 */\n    { { 0x8cd1214550ca4247L,0xba1aa47ae7dd30aaL,0x2f81ddf1e58fee24L,\n        0x03452936eec9b0e8L },\n      { 0x8bdc3b81243aea96L,0x9a2919af15c3d0e5L,0x9ea640ec10948361L,\n        0x5ac86d5b6e0bcccfL } },\n    /* 10 << 70 */\n    { { 0xf892d918c36cf440L,0xaed3e837c939719cL,0xb07b08d2c0218b64L,\n        0x6f1bcbbace9790ddL },\n      { 0x4a84d6ed60919b8eL,0xd89007918ac1f9ebL,0xf84941aa0dd5daefL,\n        0xb22fe40a67fd62c5L } },\n    /* 11 << 70 */\n    { { 0x97e15ba2157f2db3L,0xbda2fc8f8e28ca9cL,0x5d050da437b9f454L,\n        0x3d57eb572379d72eL },\n      { 0xe9b5eba2fb5ee997L,0x01648ca2e11538caL,0x32bb76f6f6327974L,\n        0x338f14b8ff3f4bb7L } },\n    /* 12 << 70 */\n    { { 0x524d226ad7ab9a2dL,0x9c00090d7dfae958L,0x0ba5f5398751d8c2L,\n        0x8afcbcdd3ab8262dL },\n      { 0x57392729e99d043bL,0xef51263baebc943aL,0x9feace9320862935L,\n        0x639efc03b06c817bL } },\n    /* 13 << 70 */\n    { { 0x1fe054b366b4be7aL,0x3f25a9de84a37a1eL,0xf39ef1ad78d75cd9L,\n        0xd7b58f495062c1b5L },\n      { 0x6f74f9a9ff563436L,0xf718ff29e8af51e7L,0x5234d31315e97fecL,\n        0xb6a8e2b1292f1c0aL } },\n    /* 14 << 70 */\n    { { 0xa7f53aa8327720c1L,0x956ca322ba092cc8L,0x8f03d64a28746c4dL,\n        0x51fe178266d0d392L },\n      { 0xd19b34db3c832c80L,0x60dccc5c6da2e3b4L,0x245dd62e0a104cccL,\n        0xa7ab1de1620b21fdL } },\n    /* 15 << 70 */\n    { { 0xb293ae0b3893d123L,0xf7b75783b15ee71cL,0x5aa3c61442a9468bL,\n        0xd686123cdb15d744L },\n      { 0x8c616891a7ab4116L,0x6fcd72c8a4e6a459L,0xac21911077e5fad7L,\n        0xfb6a20e7704fa46bL } },\n    /* 16 << 70 */\n    { { 0xe839be7d341d81dcL,0xcddb688932148379L,0xda6211a1f7026eadL,\n        0xf3b2575ff4d1cc5eL },\n      { 0x40cfc8f6a7a73ae6L,0x83879a5e61d5b483L,0xc5acb1ed41a50ebcL,\n        0x59a60cc83c07d8faL } },\n    /* 17 << 70 */\n    { { 0x1b73bdceb1876262L,0x2b0d79f012af4ee9L,0x8bcf3b0bd46e1d07L,\n        0x17d6af9de45d152fL },\n      { 0x735204616d736451L,0x43cbbd9756b0bf5aL,0xb0833a5bd5999b9dL,\n        0x702614f0eb72e398L } },\n    /* 18 << 70 */\n    { { 0x0aadf01a59c3e9f8L,0x40200e77ce6b3d16L,0xda22bdd3deddafadL,\n        0x76dedaf4310d72e1L },\n      { 0x49ef807c4bc2e88fL,0x6ba81291146dd5a5L,0xa1a4077a7d8d59e9L,\n        0x87b6a2e7802db349L } },\n    /* 19 << 70 */\n    { { 0xd56799971b4e598eL,0xf499ef1f06fe4b1dL,0x3978d3aefcb267c5L,\n        0xb582b557235786d0L },\n      { 0x32b3b2ca1715cb07L,0x4c3de6a28480241dL,0x63b5ffedcb571ecdL,\n        0xeaf53900ed2fe9a9L } },\n    /* 20 << 70 */\n    { { 0xdec98d4ac3b81990L,0x1cb837229e0cc8feL,0xfe0b0491d2b427b9L,\n        0x0f2386ace983a66cL },\n      { 0x930c4d1eb3291213L,0xa2f82b2e59a62ae4L,0x77233853f93e89e3L,\n        0x7f8063ac11777c7fL } },\n    /* 21 << 70 */\n    { { 0xff0eb56759ad2877L,0x6f4546429865c754L,0xe6fe701a236e9a84L,\n        0xc586ef1606e40fc3L },\n      { 0x3f62b6e024bafad9L,0xc8b42bd264da906aL,0xc98e1eb4da3276a0L,\n        0x30d0e5fc06cbf852L } },\n    /* 22 << 70 */\n    { { 0x1b6b2ae1e8b4dfd4L,0xd754d5c78301cbacL,0x66097629112a39acL,\n        0xf86b599993ba4ab9L },\n      { 0x26c9dea799f9d581L,0x0473b1a8c2fafeaaL,0x1469af553b2505a5L,\n        0x227d16d7d6a43323L } },\n    /* 23 << 70 */\n    { { 0x3316f73cad3d97f9L,0x52bf3bb51f137455L,0x953eafeb09954e7cL,\n        0xa721dfeddd732411L },\n      { 0xb4929821141d4579L,0x3411321caa3bd435L,0xafb355aa17fa6015L,\n        0xb4e7ef4a18e42f0eL } },\n    /* 24 << 70 */\n    { { 0x604ac97c59371000L,0xe1c48c707f759c18L,0x3f62ecc5a5db6b65L,\n        0x0a78b17338a21495L },\n      { 0x6be1819dbcc8ad94L,0x70dc04f6d89c3400L,0x462557b4a6b4840aL,\n        0x544c6ade60bd21c0L } },\n    /* 25 << 70 */\n    { { 0x6a00f24e907a544bL,0xa7520dcb313da210L,0xfe939b7511e4994bL,\n        0x918b6ba6bc275d70L },\n      { 0xd3e5e0fc644be892L,0x707a9816fdaf6c42L,0x60145567f15c13feL,\n        0x4818ebaae130a54aL } },\n    /* 26 << 70 */\n    { { 0x28aad3ad58d2f767L,0xdc5267fdd7e7c773L,0x4919cc88c3afcc98L,\n        0xaa2e6ab02db8cd4bL },\n      { 0xd46fec04d0c63eaaL,0xa1cb92c519ffa832L,0x678dd178e43a631fL,\n        0xfb5ae1cd3dc788b3L } },\n    /* 27 << 70 */\n    { { 0x68b4fb906e77de04L,0x7992bcf0f06dbb97L,0x896e6a13c417c01dL,\n        0x8d96332cb956be01L },\n      { 0x902fc93a413aa2b9L,0x99a4d915fc98c8a5L,0x52c29407565f1137L,\n        0x4072690f21e4f281L } },\n    /* 28 << 70 */\n    { { 0x36e607cf02ff6072L,0xa47d2ca98ad98cdcL,0xbf471d1ef5f56609L,\n        0xbcf86623f264ada0L },\n      { 0xb70c0687aa9e5cb6L,0xc98124f217401c6cL,0x8189635fd4a61435L,\n        0xd28fb8afa9d98ea6L } },\n    /* 29 << 70 */\n    { { 0xb9a67c2a40c251f8L,0x88cd5d87a2da44beL,0x437deb96e09b5423L,\n        0x150467db64287dc1L },\n      { 0xe161debbcdabb839L,0xa79e9742f1839a3eL,0xbb8dd3c2652d202bL,\n        0x7b3e67f7e9f97d96L } },\n    /* 30 << 70 */\n    { { 0x5aa5d78fb1cb6ac9L,0xffa13e8eca1d0d45L,0x369295dd2ba5bf95L,\n        0xd68bd1f839aff05eL },\n      { 0xaf0d86f926d783f2L,0x543a59b3fc3aafc1L,0x3fcf81d27b7da97cL,\n        0xc990a056d25dee46L } },\n    /* 31 << 70 */\n    { { 0x3e6775b8519cce2cL,0xfc9af71fae13d863L,0x774a4a6f47c1605cL,\n        0x46ba42452fd205e8L },\n      { 0xa06feea4d3fd524dL,0x1e7246416de1acc2L,0xf53816f1334e2b42L,\n        0x49e5918e922f0024L } },\n    /* 32 << 70 */\n    { { 0x439530b665c7322dL,0xcf12cc01b3c1b3fbL,0xc70b01860172f685L,\n        0xb915ee221b58391dL },\n      { 0x9afdf03ba317db24L,0x87dec65917b8ffc4L,0x7f46597be4d3d050L,\n        0x80a1c1ed006500e7L } },\n    /* 33 << 70 */\n    { { 0x84902a9678bf030eL,0xfb5e9c9a50560148L,0x6dae0a9263362426L,\n        0xdcaeecf4a9e30c40L },\n      { 0xc0d887bb518d0c6bL,0x99181152cb985b9dL,0xad186898ef7bc381L,\n        0x18168ffb9ee46201L } },\n    /* 34 << 70 */\n    { { 0x9a04cdaa2502753cL,0xbb279e2651407c41L,0xeacb03aaf23564e5L,\n        0x1833658271e61016L },\n      { 0x8684b8c4eb809877L,0xb336e18dea0e672eL,0xefb601f034ee5867L,\n        0x2733edbe1341cfd1L } },\n    /* 35 << 70 */\n    { { 0xb15e809a26025c3cL,0xe6e981a69350df88L,0x923762378502fd8eL,\n        0x4791f2160c12be9bL },\n      { 0xb725678925f02425L,0xec8631947a974443L,0x7c0ce882fb41cc52L,\n        0xc266ff7ef25c07f2L } },\n    /* 36 << 70 */\n    { { 0x3d4da8c3017025f3L,0xefcf628cfb9579b4L,0x5c4d00161f3716ecL,\n        0x9c27ebc46801116eL },\n      { 0x5eba0ea11da1767eL,0xfe15145247004c57L,0x3ace6df68c2373b7L,\n        0x75c3dffe5dbc37acL } },\n    /* 37 << 70 */\n    { { 0x3dc32a73ddc925fcL,0xb679c8412f65ee0bL,0x715a3295451cbfebL,\n        0xd9889768f76e9a29L },\n      { 0xec20ce7fb28ad247L,0xe99146c400894d79L,0x71457d7c9f5e3ea7L,\n        0x097b266238030031L } },\n    /* 38 << 70 */\n    { { 0xdb7f6ae6cf9f82a8L,0x319decb9438f473aL,0xa63ab386283856c3L,\n        0x13e3172fb06a361bL },\n      { 0x2959f8dc7d5a006cL,0x2dbc27c675fba752L,0xc1227ab287c22c9eL,\n        0x06f61f7571a268b2L } },\n    /* 39 << 70 */\n    { { 0x1b6bb97104779ce2L,0xaca838120aadcb1dL,0x297ae0bcaeaab2d5L,\n        0xa5c14ee75bfb9f13L },\n      { 0xaa00c583f17a62c7L,0x39eb962c173759f6L,0x1eeba1d486c9a88fL,\n        0x0ab6c37adf016c5eL } },\n    /* 40 << 70 */\n    { { 0xa2a147dba28a0749L,0x246c20d6ee519165L,0x5068d1b1d3810715L,\n        0xb1e7018c748160b9L },\n      { 0x03f5b1faf380ff62L,0xef7fb1ddf3cb2c1eL,0xeab539a8fc91a7daL,\n        0x83ddb707f3f9b561L } },\n    /* 41 << 70 */\n    { { 0xc550e211fe7df7a4L,0xa7cd07f2063f6f40L,0xb0de36352976879cL,\n        0xb5f83f85e55741daL },\n      { 0x4ea9d25ef3d8ac3dL,0x6fe2066f62819f02L,0x4ab2b9c2cef4a564L,\n        0x1e155d965ffa2de3L } },\n    /* 42 << 70 */\n    { { 0x0eb0a19bc3a72d00L,0x4037665b8513c31bL,0x2fb2b6bf04c64637L,\n        0x45c34d6e08cdc639L },\n      { 0x56f1e10ff01fd796L,0x4dfb8101fe3667b8L,0xe0eda2539021d0c0L,\n        0x7a94e9ff8a06c6abL } },\n    /* 43 << 70 */\n    { { 0x2d3bb0d9bb9aa882L,0xea20e4e5ec05fd10L,0xed7eeb5f1a1ca64eL,\n        0x2fa6b43cc6327cbdL },\n      { 0xb577e3cf3aa91121L,0x8c6bd5ea3a34079bL,0xd7e5ba3960e02fc0L,\n        0xf16dd2c390141bf8L } },\n    /* 44 << 70 */\n    { { 0xb57276d980101b98L,0x760883fdb82f0f66L,0x89d7de754bc3eff3L,\n        0x03b606435dc2ab40L },\n      { 0xcd6e53dfe05beeacL,0xf2f1e862bc3325cdL,0xdd0f7921774f03c3L,\n        0x97ca72214552cc1bL } },\n    /* 45 << 70 */\n    { { 0x5a0d6afe1cd19f72L,0xa20915dcf183fbebL,0x9fda4b40832c403cL,\n        0x32738eddbe425442L },\n      { 0x469a1df6b5eccf1aL,0x4b5aff4228bbe1f0L,0x31359d7f570dfc93L,\n        0xa18be235f0088628L } },\n    /* 46 << 70 */\n    { { 0xa5b30fbab00ed3a9L,0x34c6137473cdf8beL,0x2c5c5f46abc56797L,\n        0x5cecf93db82a8ae2L },\n      { 0x7d3dbe41a968fbf0L,0xd23d45831a5c7f3dL,0xf28f69a0c087a9c7L,\n        0xc2d75471474471caL } },\n    /* 47 << 70 */\n    { { 0x36ec9f4a4eb732ecL,0x6c943bbdb1ca6bedL,0xd64535e1f2457892L,\n        0x8b84a8eaf7e2ac06L },\n      { 0xe0936cd32499dd5fL,0x12053d7e0ed04e57L,0x4bdd0076e4305d9dL,\n        0x34a527b91f67f0a2L } },\n    /* 48 << 70 */\n    { { 0xe79a4af09cec46eaL,0xb15347a1658b9bc7L,0x6bd2796f35af2f75L,\n        0xac9579904051c435L },\n      { 0x2669dda3c33a655dL,0x5d503c2e88514aa3L,0xdfa113373753dd41L,\n        0x3f0546730b754f78L } },\n    /* 49 << 70 */\n    { { 0xbf185677496125bdL,0xfb0023c83775006cL,0xfa0f072f3a037899L,\n        0x4222b6eb0e4aea57L },\n      { 0x3dde5e767866d25aL,0xb6eb04f84837aa6fL,0x5315591a2cf1cdb8L,\n        0x6dfb4f412d4e683cL } },\n    /* 50 << 70 */\n    { { 0x7e923ea448ee1f3aL,0x9604d9f705a2afd5L,0xbe1d4a3340ea4948L,\n        0x5b45f1f4b44cbd2fL },\n      { 0x5faf83764acc757eL,0xa7cf9ab863d68ff7L,0x8ad62f69df0e404bL,\n        0xd65f33c212bdafdfL } },\n    /* 51 << 70 */\n    { { 0xc365de15a377b14eL,0x6bf5463b8e39f60cL,0x62030d2d2ce68148L,\n        0xd95867efe6f843a8L },\n      { 0xd39a0244ef5ab017L,0x0bd2d8c14ab55d12L,0xc9503db341639169L,\n        0x2d4e25b0f7660c8aL } },\n    /* 52 << 70 */\n    { { 0x760cb3b5e224c5d7L,0xfa3baf8c68616919L,0x9fbca1138d142552L,\n        0x1ab18bf17669ebf5L },\n      { 0x55e6f53e9bdf25ddL,0x04cc0bf3cb6cd154L,0x595bef4995e89080L,\n        0xfe9459a8104a9ac1L } },\n    /* 53 << 70 */\n    { { 0xad2d89cacce9bb32L,0xddea65e1f7de8285L,0x62ed8c35b351bd4bL,\n        0x4150ff360c0e19a7L },\n      { 0x86e3c801345f4e47L,0x3bf21f71203a266cL,0x7ae110d4855b1f13L,\n        0x5d6aaf6a07262517L } },\n    /* 54 << 70 */\n    { { 0x1e0f12e1813d28f1L,0x6000e11d7ad7a523L,0xc7d8deefc744a17bL,\n        0x1e990b4814c05a00L },\n      { 0x68fddaee93e976d5L,0x696241d146610d63L,0xb204e7c3893dda88L,\n        0x8bccfa656a3a6946L } },\n    /* 55 << 70 */\n    { { 0xb59425b4c5cd1411L,0x701b4042ff3658b1L,0xe3e56bca4784cf93L,\n        0x27de5f158fe68d60L },\n      { 0x4ab9cfcef8d53f19L,0xddb10311a40a730dL,0x6fa73cd14eee0a8aL,\n        0xfd5487485249719dL } },\n    /* 56 << 70 */\n    { { 0x49d66316a8123ef0L,0x73c32db4e7f95438L,0x2e2ed2090d9e7854L,\n        0xf98a93299d9f0507L },\n      { 0xc5d33cf60c6aa20aL,0x9a32ba1475279bb2L,0x7e3202cb774a7307L,\n        0x64ed4bc4e8c42dbdL } },\n    /* 57 << 70 */\n    { { 0xc20f1a06d4caed0dL,0xb8021407171d22b3L,0xd426ca04d13268d7L,\n        0x9237700725f4d126L },\n      { 0x4204cbc371f21a85L,0x18461b7af82369baL,0xc0c07d313fc858f9L,\n        0x5deb5a50e2bab569L } },\n    /* 58 << 70 */\n    { { 0xd5959d46d5eea89eL,0xfdff842408437f4bL,0xf21071e43cfe254fL,\n        0x7241769695468321L },\n      { 0x5d8288b9102cae3eL,0x2d143e3df1965dffL,0x00c9a376a078d847L,\n        0x6fc0da3126028731L } },\n    /* 59 << 70 */\n    { { 0xa2baeadfe45083a2L,0x66bc72185e5b4bcdL,0x2c826442d04b8e7fL,\n        0xc19f54516c4b586bL },\n      { 0x60182c495b7eeed5L,0xd9954ecd7aa9dfa1L,0xa403a8ecc73884adL,\n        0x7fb17de29bb39041L } },\n    /* 60 << 70 */\n    { { 0x694b64c5abb020e8L,0x3d18c18419c4eec7L,0x9c4673ef1c4793e5L,\n        0xc7b8aeb5056092e6L },\n      { 0x3aa1ca43f0f8c16bL,0x224ed5ecd679b2f6L,0x0d56eeaf55a205c9L,\n        0xbfe115ba4b8e028bL } },\n    /* 61 << 70 */\n    { { 0x97e608493927f4feL,0xf91fbf94759aa7c5L,0x985af7696be90a51L,\n        0xc1277b7878ccb823L },\n      { 0x395b656ee7a75952L,0x00df7de0928da5f5L,0x09c231754ca4454fL,\n        0x4ec971f47aa2d3c1L } },\n    /* 62 << 70 */\n    { { 0x45c3c507e75d9cccL,0x63b7be8a3dc90306L,0x37e09c665db44bdcL,\n        0x50d60da16841c6a2L },\n      { 0x6f9b65ee08df1b12L,0x387348797ff089dfL,0x9c331a663fe8013dL,\n        0x017f5de95f42fcc8L } },\n    /* 63 << 70 */\n    { { 0x43077866e8e57567L,0xc9f781cef9fcdb18L,0x38131dda9b12e174L,\n        0x25d84aa38a03752aL },\n      { 0x45e09e094d0c0ce2L,0x1564008b92bebba5L,0xf7e8ad31a87284c7L,\n        0xb7c4b46c97e7bbaaL } },\n    /* 64 << 70 */\n    { { 0x3e22a7b397acf4ecL,0x0426c4005ea8b640L,0x5e3295a64e969285L,\n        0x22aabc59a6a45670L },\n      { 0xb929714c5f5942bcL,0x9a6168bdfa3182edL,0x2216a665104152baL,\n        0x46908d03b6926368L } },\n    /* 0 << 77 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 77 */\n    { { 0xa9f5d8745a1251fbL,0x967747a8c72725c7L,0x195c33e531ffe89eL,\n        0x609d210fe964935eL },\n      { 0xcafd6ca82fe12227L,0xaf9b5b960426469dL,0x2e9ee04c5693183cL,\n        0x1084a333c8146fefL } },\n    /* 2 << 77 */\n    { { 0x96649933aed1d1f7L,0x566eaff350563090L,0x345057f0ad2e39cfL,\n        0x148ff65b1f832124L },\n      { 0x042e89d4cf94cf0dL,0x319bec84520c58b3L,0x2a2676265361aa0dL,\n        0xc86fa3028fbc87adL } },\n    /* 3 << 77 */\n    { { 0xfc83d2ab5c8b06d5L,0xb1a785a2fe4eac46L,0xb99315bc846f7779L,\n        0xcf31d816ef9ea505L },\n      { 0x2391fe6a15d7dc85L,0x2f132b04b4016b33L,0x29547fe3181cb4c7L,\n        0xdb66d8a6650155a1L } },\n    /* 4 << 77 */\n    { { 0x6b66d7e1adc1696fL,0x98ebe5930acd72d0L,0x65f24550cc1b7435L,\n        0xce231393b4b9a5ecL },\n      { 0x234a22d4db067df9L,0x98dda095caff9b00L,0x1bbc75a06100c9c1L,\n        0x1560a9c8939cf695L } },\n    /* 5 << 77 */\n    { { 0xcf006d3e99e0925fL,0x2dd74a966322375aL,0xc58b446ab56af5baL,\n        0x50292683e0b9b4f1L },\n      { 0xe2c34cb41aeaffa3L,0x8b17203f9b9587c1L,0x6d559207ead1350cL,\n        0x2b66a215fb7f9604L } },\n    /* 6 << 77 */\n    { { 0x0850325efe51bf74L,0x9c4f579e5e460094L,0x5c87b92a76da2f25L,\n        0x889de4e06febef33L },\n      { 0x6900ec06646083ceL,0xbe2a0335bfe12773L,0xadd1da35c5344110L,\n        0x757568b7b802cd20L } },\n    /* 7 << 77 */\n    { { 0x7555977900f7e6c8L,0x38e8b94f0facd2f0L,0xfea1f3af03fde375L,\n        0x5e11a1d875881dfcL },\n      { 0xb3a6b02ec1e2f2efL,0x193d2bbbc605a6c5L,0x325ffeee339a0b2dL,\n        0x27b6a7249e0c8846L } },\n    /* 8 << 77 */\n    { { 0xe4050f1cf1c367caL,0x9bc85a9bc90fbc7dL,0xa373c4a2e1a11032L,\n        0xb64232b7ad0393a9L },\n      { 0xf5577eb0167dad29L,0x1604f30194b78ab2L,0x0baa94afe829348bL,\n        0x77fbd8dd41654342L } },\n    /* 9 << 77 */\n    { { 0xdab50ea5b964e39aL,0xd4c29e3cd0d3c76eL,0x80dae67c56d11964L,\n        0x7307a8bfe5ffcc2fL },\n      { 0x65bbc1aa91708c3bL,0xa151e62c28bf0eebL,0x6cb533816fa34db7L,\n        0x5139e05ca29403a8L } },\n    /* 10 << 77 */\n    { { 0x6ff651b494a7cd2eL,0x5671ffd10699336cL,0x6f5fd2cc979a896aL,\n        0x11e893a8d8148cefL },\n      { 0x988906a165cf7b10L,0x81b67178c50d8485L,0x7c0deb358a35b3deL,\n        0x423ac855c1d29799L } },\n    /* 11 << 77 */\n    { { 0xaf580d87dac50b74L,0x28b2b89f5869734cL,0x99a3b936874e28fbL,\n        0xbb2c919025f3f73aL },\n      { 0x199f691884a9d5b7L,0x7ebe23257e770374L,0xf442e1070738efe2L,\n        0xcf9f3f56cf9082d2L } },\n    /* 12 << 77 */\n    { { 0x719f69e109618708L,0xcc9e8364c183f9b1L,0xec203a95366a21afL,\n        0x6aec5d6d068b141fL },\n      { 0xee2df78a994f04e9L,0xb39ccae8271245b0L,0xb875a4a997e43f4fL,\n        0x507dfe11db2cea98L } },\n    /* 13 << 77 */\n    { { 0x4fbf81cb489b03e9L,0xdb86ec5b6ec414faL,0xfad444f9f51b3ae5L,\n        0xca7d33d61914e3feL },\n      { 0xa9c32f5c0ae6c4d0L,0xa9ca1d1e73969568L,0x98043c311aa7467eL,\n        0xe832e75ce21b5ac6L } },\n    /* 14 << 77 */\n    { { 0x314b7aea5232123dL,0x08307c8c65ae86dbL,0x06e7165caa4668edL,\n        0xb170458bb4d3ec39L },\n      { 0x4d2e3ec6c19bb986L,0xc5f34846ae0304edL,0x917695a06c9f9722L,\n        0x6c7f73174cab1c0aL } },\n    /* 15 << 77 */\n    { { 0x6295940e9d6d2e8bL,0xd318b8c1549f7c97L,0x2245320497713885L,\n        0x468d834ba8a440feL },\n      { 0xd81fe5b2bfba796eL,0x152364db6d71f116L,0xbb8c7c59b5b66e53L,\n        0x0b12c61b2641a192L } },\n    /* 16 << 77 */\n    { { 0x31f14802fcf0a7fdL,0x42fd07895488b01eL,0x71d78d6d9952b498L,\n        0x8eb572d907ac5201L },\n      { 0xe0a2a44c4d194a88L,0xd2b63fd9ba017e66L,0x78efc6c8f888aefcL,\n        0xb76f6bda4a881a11L } },\n    /* 17 << 77 */\n    { { 0x187f314bb46c2397L,0x004cf5665ded2819L,0xa9ea570438764d34L,\n        0xbba4521778084709L },\n      { 0x064745711171121eL,0xad7b7eb1e7c9b671L,0xdacfbc40730f7507L,\n        0x178cd8c6c7ad7bd1L } },\n    /* 18 << 77 */\n    { { 0xbf0be101b2a67238L,0x3556d367af9c14f2L,0x104b7831a5662075L,\n        0x58ca59bb79d9e60aL },\n      { 0x4bc45392a569a73bL,0x517a52e85698f6c9L,0x85643da5aeadd755L,\n        0x1aed0cd52a581b84L } },\n    /* 19 << 77 */\n    { { 0xb9b4ff8480af1372L,0x244c3113f1ba5d1fL,0x2a5dacbef5f98d31L,\n        0x2c3323e84375bc2aL },\n      { 0x17a3ab4a5594b1ddL,0xa1928bfbceb4797eL,0xe83af245e4886a19L,\n        0x8979d54672b5a74aL } },\n    /* 20 << 77 */\n    { { 0xa0f726bc19f9e967L,0xd9d03152e8fbbf4eL,0xcfd6f51db7707d40L,\n        0x633084d963f6e6e0L },\n      { 0xedcd9cdc55667eafL,0x73b7f92b2e44d56fL,0xfb2e39b64e962b14L,\n        0x7d408f6ef671fcbfL } },\n    /* 21 << 77 */\n    { { 0xcc634ddc164a89bbL,0x74a42bb23ef3bd05L,0x1280dbb2428decbbL,\n        0x6103f6bb402c8596L },\n      { 0xfa2bf581355a5752L,0x562f96a800946674L,0x4e4ca16d6da0223bL,\n        0xfe47819f28d3aa25L } },\n    /* 22 << 77 */\n    { { 0x9eea3075f8dfcf8aL,0xa284f0aa95669825L,0xb3fca250867d3fd8L,\n        0x20757b5f269d691eL },\n      { 0xf2c2402093b8a5deL,0xd3f93359ebc06da6L,0x1178293eb2739c33L,\n        0xd2a3e770bcd686e5L } },\n    /* 23 << 77 */\n    { { 0xa76f49f4cd941534L,0x0d37406be3c71c0eL,0x172d93973b97f7e3L,\n        0xec17e239bd7fd0deL },\n      { 0xe32905516f496ba2L,0x6a69317236ad50e7L,0xc4e539a283e7eff5L,\n        0x752737e718e1b4cfL } },\n    /* 24 << 77 */\n    { { 0xa2f7932c68af43eeL,0x5502468e703d00bdL,0xe5dc978f2fb061f5L,\n        0xc9a1904a28c815adL },\n      { 0xd3af538d470c56a4L,0x159abc5f193d8cedL,0x2a37245f20108ef3L,\n        0xfa17081e223f7178L } },\n    /* 25 << 77 */\n    { { 0x27b0fb2b10c8c0f5L,0x2102c3ea40650547L,0x594564df8ac3bfa7L,\n        0x98102033509dad96L },\n      { 0x6989643ff1d18a13L,0x35eebd91d7fc5af0L,0x078d096afaeaafd8L,\n        0xb7a89341def3de98L } },\n    /* 26 << 77 */\n    { { 0x2a206e8decf2a73aL,0x066a63978e551994L,0x3a6a088ab98d53a2L,\n        0x0ce7c67c2d1124aaL },\n      { 0x48cec671759a113cL,0xe3b373d34f6f67faL,0x5455d479fd36727bL,\n        0xe5a428eea13c0d81L } },\n    /* 27 << 77 */\n    { { 0xb853dbc81c86682bL,0xb78d2727b8d02b2aL,0xaaf69bed8ebc329aL,\n        0xdb6b40b3293b2148L },\n      { 0xe42ea77db8c4961fL,0xb1a12f7c20e5e0abL,0xa0ec527479e8b05eL,\n        0x68027391fab60a80L } },\n    /* 28 << 77 */\n    { { 0x6bfeea5f16b1bd5eL,0xf957e4204de30ad3L,0xcbaf664e6a353b9eL,\n        0x5c87331226d14febL },\n      { 0x4e87f98cb65f57cbL,0xdb60a6215e0cdd41L,0x67c16865a6881440L,\n        0x1093ef1a46ab52aaL } },\n    /* 29 << 77 */\n    { { 0xc095afb53f4ece64L,0x6a6bb02e7604551aL,0x55d44b4e0b26b8cdL,\n        0xe5f9a999f971268aL },\n      { 0xc08ec42511a7de84L,0x83568095fda469ddL,0x737bfba16c6c90a2L,\n        0x1cb9c4a0be229831L } },\n    /* 30 << 77 */\n    { { 0x93bccbbabb2eec64L,0xa0c23b64da03adbeL,0x5f7aa00ae0e86ac4L,\n        0x470b941efc1401e6L },\n      { 0x5ad8d6799df43574L,0x4ccfb8a90f65d810L,0x1bce80e3aa7fbd81L,\n        0x273291ad9508d20aL } },\n    /* 31 << 77 */\n    { { 0xf5c4b46b42a92806L,0x810684eca86ab44aL,0x4591640bca0bc9f8L,\n        0xb5efcdfc5c4b6054L },\n      { 0x16fc89076e9edd12L,0xe29d0b50d4d792f9L,0xa45fd01c9b03116dL,\n        0x85035235c81765a4L } },\n    /* 32 << 77 */\n    { { 0x1fe2a9b2b4b4b67cL,0xc1d10df0e8020604L,0x9d64abfcbc8058d8L,\n        0x8943b9b2712a0fbbL },\n      { 0x90eed9143b3def04L,0x85ab3aa24ce775ffL,0x605fd4ca7bbc9040L,\n        0x8b34a564e2c75dfbL } },\n    /* 33 << 77 */\n    { { 0x41ffc94a10358560L,0x2d8a50729e5c28aaL,0xe915a0fc4cc7eb15L,\n        0xe9efab058f6d0f5dL },\n      { 0xdbab47a9d19e9b91L,0x8cfed7450276154cL,0x154357ae2cfede0dL,\n        0x520630df19f5a4efL } },\n    /* 34 << 77 */\n    { { 0x25759f7ce382360fL,0xb6db05c988bf5857L,0x2917d61d6c58d46cL,\n        0x14f8e491fd20cb7aL },\n      { 0xb68a727a11c20340L,0x0386f86faf7ccbb6L,0x5c8bc6ccfee09a20L,\n        0x7d76ff4abb7eea35L } },\n    /* 35 << 77 */\n    { { 0xa7bdebe7db15be7aL,0x67a08054d89f0302L,0x56bf0ea9c1193364L,\n        0xc824446762837ebeL },\n      { 0x32bd8e8b20d841b8L,0x127a0548dbb8a54fL,0x83dd4ca663b20236L,\n        0x87714718203491faL } },\n    /* 36 << 77 */\n    { { 0x4dabcaaaaa8a5288L,0x91cc0c8aaf23a1c9L,0x34c72c6a3f220e0cL,\n        0xbcc20bdf1232144aL },\n      { 0x6e2f42daa20ede1bL,0xc441f00c74a00515L,0xbf46a5b6734b8c4bL,\n        0x574095037b56c9a4L } },\n    /* 37 << 77 */\n    { { 0x9f735261e4585d45L,0x9231faed6734e642L,0x1158a176be70ee6cL,\n        0x35f1068d7c3501bfL },\n      { 0x6beef900a2d26115L,0x649406f2ef0afee3L,0x3f43a60abc2420a1L,\n        0x509002a7d5aee4acL } },\n    /* 38 << 77 */\n    { { 0xb46836a53ff3571bL,0x24f98b78837927c1L,0x6254256a4533c716L,\n        0xf27abb0bd07ee196L },\n      { 0xd7cf64fc5c6d5bfdL,0x6915c751f0cd7a77L,0xd9f590128798f534L,\n        0x772b0da8f81d8b5fL } },\n    /* 39 << 77 */\n    { { 0x1244260c2e03fa69L,0x36cf0e3a3be1a374L,0x6e7c1633ef06b960L,\n        0xa71a4c55671f90f6L },\n      { 0x7a94125133c673dbL,0xc0bea51073e8c131L,0x61a8a699d4f6c734L,\n        0x25e78c88341ed001L } },\n    /* 40 << 77 */\n    { { 0x5c18acf88e2f7d90L,0xfdbf33d777be32cdL,0x0a085cd7d2eb5ee9L,\n        0x2d702cfbb3201115L },\n      { 0xb6e0ebdb85c88ce8L,0x23a3ce3c1e01d617L,0x3041618e567333acL,\n        0x9dd0fd8f157edb6bL } },\n    /* 41 << 77 */\n    { { 0x27f74702b57872b8L,0x2ef26b4f657d5fe1L,0x95426f0a57cf3d40L,\n        0x847e2ad165a6067aL },\n      { 0xd474d9a009996a74L,0x16a56acd2a26115cL,0x02a615c3d16f4d43L,\n        0xcc3fc965aadb85b7L } },\n    /* 42 << 77 */\n    { { 0x386bda73ce07d1b0L,0xd82910c258ad4178L,0x124f82cfcd2617f4L,\n        0xcc2f5e8def691770L },\n      { 0x82702550b8c30cccL,0x7b856aea1a8e575aL,0xbb822fefb1ab9459L,\n        0x085928bcec24e38eL } },\n    /* 43 << 77 */\n    { { 0x5d0402ecba8f4b4dL,0xc07cd4ba00b4d58bL,0x5d8dffd529227e7aL,\n        0x61d44d0c31bf386fL },\n      { 0xe486dc2b135e6f4dL,0x680962ebe79410efL,0xa61bd343f10088b5L,\n        0x6aa76076e2e28686L } },\n    /* 44 << 77 */\n    { { 0x80463d118fb98871L,0xcb26f5c3bbc76affL,0xd4ab8eddfbe03614L,\n        0xc8eb579bc0cf2deeL },\n      { 0xcc004c15c93bae41L,0x46fbae5d3aeca3b2L,0x671235cf0f1e9ab1L,\n        0xadfba9349ec285c1L } },\n    /* 45 << 77 */\n    { { 0x88ded013f216c980L,0xc8ac4fb8f79e0bc1L,0xa29b89c6fb97a237L,\n        0xb697b7809922d8e7L },\n      { 0x3142c639ddb945b5L,0x447b06c7e094c3a9L,0xcdcb364272266c90L,\n        0x633aad08a9385046L } },\n    /* 46 << 77 */\n    { { 0xa36c936bb57c6477L,0x871f8b64e94dbcc6L,0x28d0fb62a591a67bL,\n        0x9d40e081c1d926f5L },\n      { 0x3111eaf6f2d84b5aL,0x228993f9a565b644L,0x0ccbf5922c83188bL,\n        0xf87b30ab3df3e197L } },\n    /* 47 << 77 */\n    { { 0xb8658b317642bca8L,0x1a032d7f52800f17L,0x051dcae579bf9445L,\n        0xeba6b8ee54a2e253L },\n      { 0x5c8b9cadd4485692L,0x84bda40e8986e9beL,0xd16d16a42f0db448L,\n        0x8ec80050a14d4188L } },\n    /* 48 << 77 */\n    { { 0xb2b2610798fa7aaaL,0x41209ee4f073aa4eL,0xf1570359f2d6b19bL,\n        0xcbe6868cfc577cafL },\n      { 0x186c4bdc32c04dd3L,0xa6c35faecfeee397L,0xb4a1b312f086c0cfL,\n        0xe0a5ccc6d9461fe2L } },\n    /* 49 << 77 */\n    { { 0xc32278aa1536189fL,0x1126c55fba6df571L,0x0f71a602b194560eL,\n        0x8b2d7405324bd6e1L },\n      { 0x8481939e3738be71L,0xb5090b1a1a4d97a9L,0x116c65a3f05ba915L,\n        0x21863ad3aae448aaL } },\n    /* 50 << 77 */\n    { { 0xd24e2679a7aae5d3L,0x7076013d0de5c1c4L,0x2d50f8babb05b629L,\n        0x73c1abe26e66efbbL },\n      { 0xefd4b422f2488af7L,0xe4105d02663ba575L,0x7eb60a8b53a69457L,\n        0x62210008c945973bL } },\n    /* 51 << 77 */\n    { { 0xfb25547877a50ec6L,0xbf0392f70a37a72cL,0xa0a7a19c4be18e7aL,\n        0x90d8ea1625b1e0afL },\n      { 0x7582a293ef953f57L,0x90a64d05bdc5465aL,0xca79c497e2510717L,\n        0x560dbb7c18cb641fL } },\n    /* 52 << 77 */\n    { { 0x1d8e32864b66abfbL,0xd26f52e559030900L,0x1ee3f6435584941aL,\n        0x6d3b3730569f5958L },\n      { 0x9ff2a62f4789dba5L,0x91fcb81572b5c9b7L,0xf446cb7d6c8f9a0eL,\n        0x48f625c139b7ecb5L } },\n    /* 53 << 77 */\n    { { 0xbabae8011c6219b8L,0xe7a562d928ac2f23L,0xe1b4873226e20588L,\n        0x06ee1cad775af051L },\n      { 0xda29ae43faff79f7L,0xc141a412652ee9e0L,0x1e127f6f195f4bd0L,\n        0x29c6ab4f072f34f8L } },\n    /* 54 << 77 */\n    { { 0x7b7c147730448112L,0x82b51af1e4a38656L,0x2bf2028a2f315010L,\n        0xc9a4a01f6ea88cd4L },\n      { 0xf63e95d8257e5818L,0xdd8efa10b4519b16L,0xed8973e00da910bfL,\n        0xed49d0775c0fe4a9L } },\n    /* 55 << 77 */\n    { { 0xac3aac5eb7caee1eL,0x1033898da7f4da57L,0x42145c0e5c6669b9L,\n        0x42daa688c1aa2aa0L },\n      { 0x629cc15c1a1d885aL,0x25572ec0f4b76817L,0x8312e4359c8f8f28L,\n        0x8107f8cd81965490L } },\n    /* 56 << 77 */\n    { { 0x516ff3a36fa6110cL,0x74fb1eb1fb93561fL,0x6c0c90478457522bL,\n        0xcfd321046bb8bdc6L },\n      { 0x2d6884a2cc80ad57L,0x7c27fc3586a9b637L,0x3461baedadf4e8cdL,\n        0x1d56251a617242f0L } },\n    /* 57 << 77 */\n    { { 0x0b80d209c955bef4L,0xdf02cad206adb047L,0xf0d7cb915ec74feeL,\n        0xd25033751111ba44L },\n      { 0x9671755edf53cb36L,0x54dcb6123368551bL,0x66d69aacc8a025a4L,\n        0x6be946c6e77ef445L } },\n    /* 58 << 77 */\n    { { 0x719946d1a995e094L,0x65e848f6e51e04d8L,0xe62f33006a1e3113L,\n        0x1541c7c1501de503L },\n      { 0x4daac9faf4acfadeL,0x0e58589744cd0b71L,0x544fd8690a51cd77L,\n        0x60fc20ed0031016dL } },\n    /* 59 << 77 */\n    { { 0x58b404eca4276867L,0x46f6c3cc34f34993L,0x477ca007c636e5bdL,\n        0x8018f5e57c458b47L },\n      { 0xa1202270e47b668fL,0xcef48ccdee14f203L,0x23f98bae62ff9b4dL,\n        0x55acc035c589edddL } },\n    /* 60 << 77 */\n    { { 0x3fe712af64db4444L,0x19e9d634becdd480L,0xe08bc047a930978aL,\n        0x2dbf24eca1280733L },\n      { 0x3c0ae38c2cd706b2L,0x5b012a5b359017b9L,0x3943c38c72e0f5aeL,\n        0x786167ea57176fa3L } },\n    /* 61 << 77 */\n    { { 0xe5f9897d594881dcL,0x6b5efad8cfb820c1L,0xb2179093d55018deL,\n        0x39ad7d320bac56ceL },\n      { 0xb55122e02cfc0e81L,0x117c4661f6d89daaL,0x362d01e1cb64fa09L,\n        0x6a309b4e3e9c4dddL } },\n    /* 62 << 77 */\n    { { 0xfa979fb7abea49b1L,0xb4b1d27d10e2c6c5L,0xbd61c2c423afde7aL,\n        0xeb6614f89786d358L },\n      { 0x4a5d816b7f6f7459L,0xe431a44f09360e7bL,0x8c27a032c309914cL,\n        0xcea5d68acaede3d8L } },\n    /* 63 << 77 */\n    { { 0x3668f6653a0a3f95L,0x893694167ceba27bL,0x89981fade4728fe9L,\n        0x7102c8a08a093562L },\n      { 0xbb80310e235d21c8L,0x505e55d1befb7f7bL,0xa0a9081112958a67L,\n        0xd67e106a4d851fefL } },\n    /* 64 << 77 */\n    { { 0xb84011a9431dd80eL,0xeb7c7cca73306cd9L,0x20fadd29d1b3b730L,\n        0x83858b5bfe37b3d3L },\n      { 0xbf4cd193b6251d5cL,0x1cca1fd31352d952L,0xc66157a490fbc051L,\n        0x7990a63889b98636L } },\n    /* 0 << 84 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 84 */\n    { { 0xe5aa692a87dec0e1L,0x010ded8df7b39d00L,0x7b1b80c854cfa0b5L,\n        0x66beb876a0f8ea28L },\n      { 0x50d7f5313476cd0eL,0xa63d0e65b08d3949L,0x1a09eea953479fc6L,\n        0x82ae9891f499e742L } },\n    /* 2 << 84 */\n    { { 0xab58b9105ca7d866L,0x582967e23adb3b34L,0x89ae4447cceac0bcL,\n        0x919c667c7bf56af5L },\n      { 0x9aec17b160f5dcd7L,0xec697b9fddcaadbcL,0x0b98f341463467f5L,\n        0xb187f1f7a967132fL } },\n    /* 3 << 84 */\n    { { 0x90fe7a1d214aeb18L,0x1506af3c741432f7L,0xbb5565f9e591a0c4L,\n        0x10d41a77b44f1bc3L },\n      { 0xa09d65e4a84bde96L,0x42f060d8f20a6a1cL,0x652a3bfdf27f9ce7L,\n        0xb6bdb65c3b3d739fL } },\n    /* 4 << 84 */\n    { { 0xeb5ddcb6ec7fae9fL,0x995f2714efb66e5aL,0xdee95d8e69445d52L,\n        0x1b6c2d4609e27620L },\n      { 0x32621c318129d716L,0xb03909f10958c1aaL,0x8c468ef91af4af63L,\n        0x162c429ffba5cdf6L } },\n    /* 5 << 84 */\n    { { 0x2f682343753b9371L,0x29cab45a5f1f9cd7L,0x571623abb245db96L,\n        0xc507db093fd79999L },\n      { 0x4e2ef652af036c32L,0x86f0cc7805018e5cL,0xc10a73d4ab8be350L,\n        0x6519b3977e826327L } },\n    /* 6 << 84 */\n    { { 0xe8cb5eef9c053df7L,0x8de25b37b300ea6fL,0xdb03fa92c849cffbL,\n        0x242e43a7e84169bbL },\n      { 0xe4fa51f4dd6f958eL,0x6925a77ff4445a8dL,0xe6e72a50e90d8949L,\n        0xc66648e32b1f6390L } },\n    /* 7 << 84 */\n    { { 0xb2ab1957173e460cL,0x1bbbce7530704590L,0xc0a90dbddb1c7162L,\n        0x505e399e15cdd65dL },\n      { 0x68434dcb57797ab7L,0x60ad35ba6a2ca8e8L,0x4bfdb1e0de3336c1L,\n        0xbbef99ebd8b39015L } },\n    /* 8 << 84 */\n    { { 0x6c3b96f31711ebecL,0x2da40f1fce98fdc4L,0xb99774d357b4411fL,\n        0x87c8bdf415b65bb6L },\n      { 0xda3a89e3c2eef12dL,0xde95bb9b3c7471f3L,0x600f225bd812c594L,\n        0x54907c5d2b75a56bL } },\n    /* 9 << 84 */\n    { { 0xa93cc5f08db60e35L,0x743e3cd6fa833319L,0x7dad5c41f81683c9L,\n        0x70c1e7d99c34107eL },\n      { 0x0edc4a39a6be0907L,0x36d4703586d0b7d3L,0x8c76da03272bfa60L,\n        0x0b4a07ea0f08a414L } },\n    /* 10 << 84 */\n    { { 0x699e4d2945c1dd53L,0xcadc5898231debb5L,0xdf49fcc7a77f00e0L,\n        0x93057bbfa73e5a0eL },\n      { 0x2f8b7ecd027a4cd1L,0x114734b3c614011aL,0xe7a01db767677c68L,\n        0x89d9be5e7e273f4fL } },\n    /* 11 << 84 */\n    { { 0xd225cb2e089808efL,0xf1f7a27dd59e4107L,0x53afc7618211b9c9L,\n        0x0361bc67e6819159L },\n      { 0x2a865d0b7f071426L,0x6a3c1810e7072567L,0x3e3bca1e0d6bcabdL,\n        0xa1b02bc1408591bcL } },\n    /* 12 << 84 */\n    { { 0xe0deee5931fba239L,0xf47424d398bd91d1L,0x0f8886f4071a3c1dL,\n        0x3f7d41e8a819233bL },\n      { 0x708623c2cf6eb998L,0x86bb49af609a287fL,0x942bb24963c90762L,\n        0x0ef6eea555a9654bL } },\n    /* 13 << 84 */\n    { { 0x5f6d2d7236f5defeL,0xfa9922dc56f99176L,0x6c8c5ecef78ce0c7L,\n        0x7b44589dbe09b55eL },\n      { 0xe11b3bca9ea83770L,0xd7fa2c7f2ab71547L,0x2a3dd6fa2a1ddcc0L,\n        0x09acb4305a7b7707L } },\n    /* 14 << 84 */\n    { { 0x4add4a2e649d4e57L,0xcd53a2b01917526eL,0xc526233020b44ac4L,\n        0x4028746abaa2c31dL },\n      { 0x5131839064291d4cL,0xbf48f151ee5ad909L,0xcce57f597b185681L,\n        0x7c3ac1b04854d442L } },\n    /* 15 << 84 */\n    { { 0x65587dc3c093c171L,0xae7acb2424f42b65L,0x5a338adb955996cbL,\n        0xc8e656756051f91bL },\n      { 0x66711fba28b8d0b1L,0x15d74137b6c10a90L,0x70cdd7eb3a232a80L,\n        0xc9e2f07f6191ed24L } },\n    /* 16 << 84 */\n    { { 0xa80d1db6f79588c0L,0xfa52fc69b55768ccL,0x0b4df1ae7f54438aL,\n        0x0cadd1a7f9b46a4fL },\n      { 0xb40ea6b31803dd6fL,0x488e4fa555eaae35L,0x9f047d55382e4e16L,\n        0xc9b5b7e02f6e0c98L } },\n    /* 17 << 84 */\n    { { 0x6b1bd2d395762649L,0xa9604ee7c7aea3f6L,0x3646ff276dc6f896L,\n        0x9bf0e7f52860bad1L },\n      { 0x2d92c8217cb44b92L,0xa2f5ce63aea9c182L,0xd0a2afb19154a5fdL,\n        0x482e474c95801da6L } },\n    /* 18 << 84 */\n    { { 0xc19972d0b611c24bL,0x1d468e6560a8f351L,0xeb7580697bcf6421L,\n        0xec9dd0ee88fbc491L },\n      { 0x5b59d2bf956c2e32L,0x73dc6864dcddf94eL,0xfd5e2321bcee7665L,\n        0xa7b4f8ef5e9a06c4L } },\n    /* 19 << 84 */\n    { { 0xfba918dd7280f855L,0xbbaac2608baec688L,0xa3b3f00f33400f42L,\n        0x3d2dba2966f2e6e4L },\n      { 0xb6f71a9498509375L,0x8f33031fcea423ccL,0x009b8dd04807e6fbL,\n        0x5163cfe55cdb954cL } },\n    /* 20 << 84 */\n    { { 0x03cc8f17cf41c6e8L,0xf1f03c2a037b925cL,0xc39c19cc66d2427cL,\n        0x823d24ba7b6c18e4L },\n      { 0x32ef9013901f0b4fL,0x684360f1f8941c2eL,0x0ebaff522c28092eL,\n        0x7891e4e3256c932fL } },\n    /* 21 << 84 */\n    { { 0x51264319ac445e3dL,0x553432e78ea74381L,0xe6eeaa6967e9c50aL,\n        0x27ced28462e628c7L },\n      { 0x3f96d3757a4afa57L,0xde0a14c3e484c150L,0x364a24eb38bd9923L,\n        0x1df18da0e5177422L } },\n    /* 22 << 84 */\n    { { 0x174e8f82d8d38a9bL,0x2e97c600e7de1391L,0xc5709850a1c175ddL,\n        0x969041a032ae5035L },\n      { 0xcbfd533b76a2086bL,0xd6bba71bd7c2e8feL,0xb2d58ee6099dfb67L,\n        0x3a8b342d064a85d9L } },\n    /* 23 << 84 */\n    { { 0x3bc07649522f9be3L,0x690c075bdf1f49a8L,0x80e1aee83854ec42L,\n        0x2a7dbf4417689dc7L },\n      { 0xc004fc0e3faf4078L,0xb2f02e9edf11862cL,0xf10a5e0fa0a1b7b3L,\n        0x30aca6238936ec80L } },\n    /* 24 << 84 */\n    { { 0xf83cbf0502f40d9aL,0x4681c4682c318a4dL,0x985756180e9c2674L,\n        0xbe79d0461847092eL },\n      { 0xaf1e480a78bd01e0L,0x6dd359e472a51db9L,0x62ce3821e3afbab6L,\n        0xc5cee5b617733199L } },\n    /* 25 << 84 */\n    { { 0xe08b30d46ffd9fbbL,0x6e5bc69936c610b7L,0xf343cff29ce262cfL,\n        0xca2e4e3568b914c1L },\n      { 0x011d64c016de36c5L,0xe0b10fdd42e2b829L,0x789429816685aaf8L,\n        0xe7511708230ede97L } },\n    /* 26 << 84 */\n    { { 0x671ed8fc3b922bf8L,0xe4d8c0a04c29b133L,0x87eb12393b6e99c4L,\n        0xaff3974c8793bebaL },\n      { 0x037494052c18df9bL,0xc5c3a29391007139L,0x6a77234fe37a0b95L,\n        0x02c29a21b661c96bL } },\n    /* 27 << 84 */\n    { { 0xc3aaf1d6141ecf61L,0x9195509e3bb22f53L,0x2959740422d51357L,\n        0x1b083822537bed60L },\n      { 0xcd7d6e35e07289f0L,0x1f94c48c6dd86effL,0xc8bb1f82eb0f9cfaL,\n        0x9ee0b7e61b2eb97dL } },\n    /* 28 << 84 */\n    { { 0x5a52fe2e34d74e31L,0xa352c3103bf79ab6L,0x97ff6c5aabfeeb8fL,\n        0xbfbe8feff5c97305L },\n      { 0xd6081ce6a7904608L,0x1f812f3ac4fca249L,0x9b24bc9ab9e5e200L,\n        0x91022c6738012ee8L } },\n    /* 29 << 84 */\n    { { 0xe83d9c5d30a713a1L,0x4876e3f084ef0f93L,0xc9777029c1fbf928L,\n        0xef7a6bb3bce7d2a4L },\n      { 0xb8067228dfa2a659L,0xd5cd3398d877a48fL,0xbea4fd8f025d0f3fL,\n        0xd67d2e352eae7c2bL } },\n    /* 30 << 84 */\n    { { 0x184de7d7cc5f4394L,0xb5551b5c4536e142L,0x2e89b212d34aa60aL,\n        0x14a96feaf50051d5L },\n      { 0x4e21ef740d12bb0bL,0xc522f02060b9677eL,0x8b12e4672df7731dL,\n        0x39f803827b326d31L } },\n    /* 31 << 84 */\n    { { 0xdfb8630c39024a94L,0xaacb96a897319452L,0xd68a3961eda3867cL,\n        0x0c58e2b077c4ffcaL },\n      { 0x3d545d634da919faL,0xef79b69af15e2289L,0x54bc3d3d808bab10L,\n        0xc8ab300745f82c37L } },\n    /* 32 << 84 */\n    { { 0xc12738b67c4a658aL,0xb3c4763940e72182L,0x3b77be468798e44fL,\n        0xdc047df217a7f85fL },\n      { 0x2439d4c55e59d92dL,0xcedca475e8e64d8dL,0xa724cd0d87ca9b16L,\n        0x35e4fd59a5540dfeL } },\n    /* 33 << 84 */\n    { { 0xf8c1ff18e4bcf6b1L,0x856d6285295018faL,0x433f665c3263c949L,\n        0xa6a76dd6a1f21409L },\n      { 0x17d32334cc7b4f79L,0xa1d0312206720e4aL,0xadb6661d81d9bed5L,\n        0xf0d6fb0211db15d1L } },\n    /* 34 << 84 */\n    { { 0x7fd11ad51fb747d2L,0xab50f9593033762bL,0x2a7e711bfbefaf5aL,\n        0xc73932783fef2bbfL },\n      { 0xe29fa2440df6f9beL,0x9092757b71efd215L,0xee60e3114f3d6fd9L,\n        0x338542d40acfb78bL } },\n    /* 35 << 84 */\n    { { 0x44a23f0838961a0fL,0x1426eade986987caL,0x36e6ee2e4a863cc6L,\n        0x48059420628b8b79L },\n      { 0x30303ad87396e1deL,0x5c8bdc4838c5aad1L,0x3e40e11f5c8f5066L,\n        0xabd6e7688d246bbdL } },\n    /* 36 << 84 */\n    { { 0x68aa40bb23330a01L,0xd23f5ee4c34eafa0L,0x3bbee3155de02c21L,\n        0x18dd4397d1d8dd06L },\n      { 0x3ba1939a122d7b44L,0xe6d3b40aa33870d6L,0x8e620f701c4fe3f8L,\n        0xf6bba1a5d3a50cbfL } },\n    /* 37 << 84 */\n    { { 0x4a78bde5cfc0aee0L,0x847edc46c08c50bdL,0xbaa2439cad63c9b2L,\n        0xceb4a72810fc2acbL },\n      { 0xa419e40e26da033dL,0x6cc3889d03e02683L,0x1cd28559fdccf725L,\n        0x0fd7e0f18d13d208L } },\n    /* 38 << 84 */\n    { { 0x01b9733b1f0df9d4L,0x8cc2c5f3a2b5e4f3L,0x43053bfa3a304fd4L,\n        0x8e87665c0a9f1aa7L },\n      { 0x087f29ecd73dc965L,0x15ace4553e9023dbL,0x2370e3092bce28b4L,\n        0xf9723442b6b1e84aL } },\n    /* 39 << 84 */\n    { { 0xbeee662eb72d9f26L,0xb19396def0e47109L,0x85b1fa73e13289d0L,\n        0x436cf77e54e58e32L },\n      { 0x0ec833b3e990ef77L,0x7373e3ed1b11fc25L,0xbe0eda870fc332ceL,\n        0xced049708d7ea856L } },\n    /* 40 << 84 */\n    { { 0xf85ff7857e977ca0L,0xb66ee8dadfdd5d2bL,0xf5e37950905af461L,\n        0x587b9090966d487cL },\n      { 0x6a198a1b32ba0127L,0xa7720e07141615acL,0xa23f3499996ef2f2L,\n        0xef5f64b4470bcb3dL } },\n    /* 41 << 84 */\n    { { 0xa526a96292b8c559L,0x0c14aac069740a0fL,0x0d41a9e3a6bdc0a5L,\n        0x97d521069c48aef4L },\n      { 0xcf16bd303e7c253bL,0xcc834b1a47fdedc1L,0x7362c6e5373aab2eL,\n        0x264ed85ec5f590ffL } },\n    /* 42 << 84 */\n    { { 0x7a46d9c066d41870L,0xa50c20b14787ba09L,0x185e7e51e3d44635L,\n        0xb3b3e08031e2d8dcL },\n      { 0xbed1e558a179e9d9L,0x2daa3f7974a76781L,0x4372baf23a40864fL,\n        0x46900c544fe75cb5L } },\n    /* 43 << 84 */\n    { { 0xb95f171ef76765d0L,0x4ad726d295c87502L,0x2ec769da4d7c99bdL,\n        0x5e2ddd19c36cdfa8L },\n      { 0xc22117fca93e6deaL,0xe8a2583b93771123L,0xbe2f6089fa08a3a2L,\n        0x4809d5ed8f0e1112L } },\n    /* 44 << 84 */\n    { { 0x3b414aa3da7a095eL,0x9049acf126f5aaddL,0x78d46a4d6be8b84aL,\n        0xd66b1963b732b9b3L },\n      { 0x5c2ac2a0de6e9555L,0xcf52d098b5bd8770L,0x15a15fa60fd28921L,\n        0x56ccb81e8b27536dL } },\n    /* 45 << 84 */\n    { { 0x0f0d8ab89f4ccbb8L,0xed5f44d2db221729L,0x4314198800bed10cL,\n        0xc94348a41d735b8bL },\n      { 0x79f3e9c429ef8479L,0x4c13a4e3614c693fL,0x32c9af568e143a14L,\n        0xbc517799e29ac5c4L } },\n    /* 46 << 84 */\n    { { 0x05e179922774856fL,0x6e52fb056c1bf55fL,0xaeda4225e4f19e16L,\n        0x70f4728aaf5ccb26L },\n      { 0x5d2118d1b2947f22L,0xc827ea16281d6fb9L,0x8412328d8cf0eabdL,\n        0x45ee9fb203ef9dcfL } },\n    /* 47 << 84 */\n    { { 0x8e700421bb937d63L,0xdf8ff2d5cc4b37a6L,0xa4c0d5b25ced7b68L,\n        0x6537c1efc7308f59L },\n      { 0x25ce6a263b37f8e8L,0x170e9a9bdeebc6ceL,0xdd0379528728d72cL,\n        0x445b0e55850154bcL } },\n    /* 48 << 84 */\n    { { 0x4b7d0e0683a7337bL,0x1e3416d4ffecf249L,0x24840eff66a2b71fL,\n        0xd0d9a50ab37cc26dL },\n      { 0xe21981506fe28ef7L,0x3cc5ef1623324c7fL,0x220f3455769b5263L,\n        0xe2ade2f1a10bf475L } },\n    /* 49 << 84 */\n    { { 0x28cd20fa458d3671L,0x1549722c2dc4847bL,0x6dd01e55591941e3L,\n        0x0e6fbcea27128ccbL },\n      { 0xae1a1e6b3bef0262L,0xfa8c472c8f54e103L,0x7539c0a872c052ecL,\n        0xd7b273695a3490e9L } },\n    /* 50 << 84 */\n    { { 0x143fe1f171684349L,0x36b4722e32e19b97L,0xdc05922790980affL,\n        0x175c9c889e13d674L },\n      { 0xa7de5b226e6bfdb1L,0x5ea5b7b2bedb4b46L,0xd5570191d34a6e44L,\n        0xfcf60d2ea24ff7e6L } },\n    /* 51 << 84 */\n    { { 0x614a392d677819e1L,0x7be74c7eaa5a29e8L,0xab50fece63c85f3fL,\n        0xaca2e2a946cab337L },\n      { 0x7f700388122a6fe3L,0xdb69f703882a04a8L,0x9a77935dcf7aed57L,\n        0xdf16207c8d91c86fL } },\n    /* 52 << 84 */\n    { { 0x2fca49ab63ed9998L,0xa3125c44a77ddf96L,0x05dd8a8624344072L,\n        0xa023dda2fec3fb56L },\n      { 0x421b41fc0c743032L,0x4f2120c15e438639L,0xfb7cae51c83c1b07L,\n        0xb2370caacac2171aL } },\n    /* 53 << 84 */\n    { { 0x2eb2d9626cc820fbL,0x59feee5cb85a44bfL,0x94620fca5b6598f0L,\n        0x6b922cae7e314051L },\n      { 0xff8745ad106bed4eL,0x546e71f5dfa1e9abL,0x935c1e481ec29487L,\n        0x9509216c4d936530L } },\n    /* 54 << 84 */\n    { { 0xc7ca306785c9a2dbL,0xd6ae51526be8606fL,0x09dbcae6e14c651dL,\n        0xc9536e239bc32f96L },\n      { 0xa90535a934521b03L,0xf39c526c878756ffL,0x383172ec8aedf03cL,\n        0x20a8075eefe0c034L } },\n    /* 55 << 84 */\n    { { 0xf22f9c6264026422L,0x8dd1078024b9d076L,0x944c742a3bef2950L,\n        0x55b9502e88a2b00bL },\n      { 0xa59e14b486a09817L,0xa39dd3ac47bb4071L,0x55137f663be0592fL,\n        0x07fcafd4c9e63f5bL } },\n    /* 56 << 84 */\n    { { 0x963652ee346eb226L,0x7dfab085ec2facb7L,0x273bf2b8691add26L,\n        0x30d74540f2b46c44L },\n      { 0x05e8e73ef2c2d065L,0xff9b8a00d42eeac9L,0x2fcbd20597209d22L,\n        0xeb740ffade14ea2cL } },\n    /* 57 << 84 */\n    { { 0xc71ff913a8aef518L,0x7bfc74bbfff4cfa2L,0x1716680cb6b36048L,\n        0x121b2cce9ef79af1L },\n      { 0xbff3c836a01eb3d3L,0x50eb1c6a5f79077bL,0xa48c32d6a004bbcfL,\n        0x47a593167d64f61dL } },\n    /* 58 << 84 */\n    { { 0x6068147f93102016L,0x12c5f65494d12576L,0xefb071a7c9bc6b91L,\n        0x7c2da0c56e23ea95L },\n      { 0xf4fd45b6d4a1dd5dL,0x3e7ad9b69122b13cL,0x342ca118e6f57a48L,\n        0x1c2e94a706f8288fL } },\n    /* 59 << 84 */\n    { { 0x99e68f075a97d231L,0x7c80de974d838758L,0xbce0f5d005872727L,\n        0xbe5d95c219c4d016L },\n      { 0x921d5cb19c2492eeL,0x42192dc1404d6fb3L,0x4c84dcd132f988d3L,\n        0xde26d61fa17b8e85L } },\n    /* 60 << 84 */\n    { { 0xc466dcb6137c7408L,0x9a38d7b636a266daL,0x7ef5cb0683bebf1bL,\n        0xe5cdcbbf0fd014e3L },\n      { 0x30aa376df65965a0L,0x60fe88c2ebb3e95eL,0x33fd0b6166ee6f20L,\n        0x8827dcdb3f41f0a0L } },\n    /* 61 << 84 */\n    { { 0xbf8a9d240c56c690L,0x40265dadddb7641dL,0x522b05bf3a6b662bL,\n        0x466d1dfeb1478c9bL },\n      { 0xaa6169621484469bL,0x0db6054902df8f9fL,0xc37bca023cb8bf51L,\n        0x5effe34621371ce8L } },\n    /* 62 << 84 */\n    { { 0xe8f65264ff112c32L,0x8a9c736d7b971fb2L,0xa4f194707b75080dL,\n        0xfc3f2c5a8839c59bL },\n      { 0x1d6c777e5aeb49c2L,0xf3db034dda1addfeL,0xd76fee5a5535affcL,\n        0x0853ac70b92251fdL } },\n    /* 63 << 84 */\n    { { 0x37e3d5948b2a29d5L,0x28f1f4574de00ddbL,0x8083c1b5f42c328bL,\n        0xd8ef1d8fe493c73bL },\n      { 0x96fb626041dc61bdL,0xf74e8a9d27ee2f8aL,0x7c605a802c946a5dL,\n        0xeed48d653839ccfdL } },\n    /* 64 << 84 */\n    { { 0x9894344f3a29467aL,0xde81e949c51eba6dL,0xdaea066ba5e5c2f2L,\n        0x3fc8a61408c8c7b3L },\n      { 0x7adff88f06d0de9fL,0xbbc11cf53b75ce0aL,0x9fbb7accfbbc87d5L,\n        0xa1458e267badfde2L } },\n    /* 0 << 91 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 91 */\n    { { 0x1cb43668e039c256L,0x5f26fb8b7c17fd5dL,0xeee426af79aa062bL,\n        0x072002d0d78fbf04L },\n      { 0x4c9ca237e84fb7e3L,0xb401d8a10c82133dL,0xaaa525926d7e4181L,\n        0xe943083373dbb152L } },\n    /* 2 << 91 */\n    { { 0xf92dda31be24319aL,0x03f7d28be095a8e7L,0xa52fe84098782185L,\n        0x276ddafe29c24dbcL },\n      { 0x80cd54961d7a64ebL,0xe43608897f1dbe42L,0x2f81a8778438d2d5L,\n        0x7e4d52a885169036L } },\n    /* 3 << 91 */\n    { { 0x19e3d5b11d59715dL,0xc7eaa762d788983eL,0xe5a730b0abf1f248L,\n        0xfbab8084fae3fd83L },\n      { 0x65e50d2153765b2fL,0xbdd4e083fa127f3dL,0x9cf3c074397b1b10L,\n        0x59f8090cb1b59fd3L } },\n    /* 4 << 91 */\n    { { 0x7b15fd9d615faa8fL,0x8fa1eb40968554edL,0x7bb4447e7aa44882L,\n        0x2bb2d0d1029fff32L },\n      { 0x075e2a646caa6d2fL,0x8eb879de22e7351bL,0xbcd5624e9a506c62L,\n        0x218eaef0a87e24dcL } },\n    /* 5 << 91 */\n    { { 0x37e5684744ddfa35L,0x9ccfc5c5dab3f747L,0x9ac1df3f1ee96cf4L,\n        0x0c0571a13b480b8fL },\n      { 0x2fbeb3d54b3a7b3cL,0x35c036695dcdbb99L,0x52a0f5dcb2415b3aL,\n        0xd57759b44413ed9aL } },\n    /* 6 << 91 */\n    { { 0x1fe647d83d30a2c5L,0x0857f77ef78a81dcL,0x11d5a334131a4a9bL,\n        0xc0a94af929d393f5L },\n      { 0xbc3a5c0bdaa6ec1aL,0xba9fe49388d2d7edL,0xbb4335b4bb614797L,\n        0x991c4d6872f83533L } },\n    /* 7 << 91 */\n    { { 0x53258c28d2f01cb3L,0x93d6eaa3d75db0b1L,0x419a2b0de87d0db4L,\n        0xa1e48f03d8fe8493L },\n      { 0xf747faf6c508b23aL,0xf137571a35d53549L,0x9f5e58e2fcf9b838L,\n        0xc7186ceea7fd3cf5L } },\n    /* 8 << 91 */\n    { { 0x77b868cee978a1d3L,0xe3a68b337ab92d04L,0x5102979487a5b862L,\n        0x5f0606c33a61d41dL },\n      { 0x2814be276f9326f1L,0x2f521c14c6fe3c2eL,0x17464d7dacdf7351L,\n        0x10f5f9d3777f7e44L } },\n    /* 9 << 91 */\n    { { 0xce8e616b269fb37dL,0xaaf738047de62de5L,0xaba111754fdd4153L,\n        0x515759ba3770b49bL },\n      { 0x8b09ebf8aa423a61L,0x592245a1cd41fb92L,0x1cba8ec19b4c8936L,\n        0xa87e91e3af36710eL } },\n    /* 10 << 91 */\n    { { 0x1fd84ce43d34a2e3L,0xee3759ceb43b5d61L,0x895bc78c619186c7L,\n        0xf19c3809cbb9725aL },\n      { 0xc0be21aade744b1fL,0xa7d222b060f8056bL,0x74be6157b23efe11L,\n        0x6fab2b4f0cd68253L } },\n    /* 11 << 91 */\n    { { 0xad33ea5f4bf1d725L,0x9c1d8ee24f6c950fL,0x544ee78aa377af06L,\n        0x54f489bb94a113e1L },\n      { 0x8f11d634992fb7e8L,0x0169a7aaa2a44347L,0x1d49d4af95020e00L,\n        0x95945722e08e120bL } },\n    /* 12 << 91 */\n    { { 0xb6e33878a4d32282L,0xe36e029d48020ae7L,0xe05847fb37a9b750L,\n        0xf876812cb29e3819L },\n      { 0x84ad138ed23a17f0L,0x6d7b4480f0b3950eL,0xdfa8aef42fd67ae0L,\n        0x8d3eea2452333af6L } },\n    /* 13 << 91 */\n    { { 0x0d052075b15d5accL,0xc6d9c79fbd815bc4L,0x8dcafd88dfa36cf2L,\n        0x908ccbe238aa9070L },\n      { 0x638722c4ba35afceL,0x5a3da8b0fd6abf0bL,0x2dce252cc9c335c1L,\n        0x84e7f0de65aa799bL } },\n    /* 14 << 91 */\n    { { 0x2101a522b99a72cbL,0x06de6e6787618016L,0x5ff8c7cde6f3653eL,\n        0x0a821ab5c7a6754aL },\n      { 0x7e3fa52b7cb0b5a2L,0xa7fb121cc9048790L,0x1a72502006ce053aL,\n        0xb490a31f04e929b0L } },\n    /* 15 << 91 */\n    { { 0xe17be47d62dd61adL,0x781a961c6be01371L,0x1063bfd3dae3cbbaL,\n        0x356474067f73c9baL },\n      { 0xf50e957b2736a129L,0xa6313702ed13f256L,0x9436ee653a19fcc5L,\n        0xcf2bdb29e7a4c8b6L } },\n    /* 16 << 91 */\n    { { 0xb06b1244c5f95cd8L,0xda8c8af0f4ab95f4L,0x1bae59c2b9e5836dL,\n        0x07d51e7e3acffffcL },\n      { 0x01e15e6ac2ccbcdaL,0x3bc1923f8528c3e0L,0x43324577a49fead4L,\n        0x61a1b8842aa7a711L } },\n    /* 17 << 91 */\n    { { 0xf9a86e08700230efL,0x0af585a1bd19adf8L,0x7645f361f55ad8f2L,\n        0x6e67622346c3614cL },\n      { 0x23cb257c4e774d3fL,0x82a38513ac102d1bL,0x9bcddd887b126aa5L,\n        0xe716998beefd3ee4L } },\n    /* 18 << 91 */\n    { { 0x4239d571fb167583L,0xdd011c78d16c8f8aL,0x271c289569a27519L,\n        0x9ce0a3b7d2d64b6aL },\n      { 0x8c977289d5ec6738L,0xa3b49f9a8840ef6bL,0x808c14c99a453419L,\n        0x5c00295b0cf0a2d5L } },\n    /* 19 << 91 */\n    { { 0x524414fb1d4bcc76L,0xb07691d2459a88f1L,0x77f43263f70d110fL,\n        0x64ada5e0b7abf9f3L },\n      { 0xafd0f94e5b544cf5L,0xb4a13a15fd2713feL,0xb99b7d6e250c74f4L,\n        0x097f2f7320324e45L } },\n    /* 20 << 91 */\n    { { 0x994b37d8affa8208L,0xc3c31b0bdc29aafcL,0x3da746517a3a607fL,\n        0xd8e1b8c1fe6955d6L },\n      { 0x716e1815c8418682L,0x541d487f7dc91d97L,0x48a04669c6996982L,\n        0xf39cab1583a6502eL } },\n    /* 21 << 91 */\n    { { 0x025801a0e68db055L,0xf3569758ba3338d5L,0xb0c8c0aaee2afa84L,\n        0x4f6985d3fb6562d1L },\n      { 0x351f1f15132ed17aL,0x510ed0b4c04365feL,0xa3f98138e5b1f066L,\n        0xbc9d95d632df03dcL } },\n    /* 22 << 91 */\n    { { 0xa83ccf6e19abd09eL,0x0b4097c14ff17edbL,0x58a5c478d64a06ceL,\n        0x2ddcc3fd544a58fdL },\n      { 0xd449503d9e8153b8L,0x3324fd027774179bL,0xaf5d47c8dbd9120cL,\n        0xeb86016234fa94dbL } },\n    /* 23 << 91 */\n    { { 0x5817bdd1972f07f4L,0xe5579e2ed27bbcebL,0x86847a1f5f11e5a6L,\n        0xb39ed2557c3cf048L },\n      { 0xe1076417a2f62e55L,0x6b9ab38f1bcf82a2L,0x4bb7c3197aeb29f9L,\n        0xf6d17da317227a46L } },\n    /* 24 << 91 */\n    { { 0xab53ddbd0f968c00L,0xa03da7ec000c880bL,0x7b2396246a9ad24dL,\n        0x612c040101ec60d0L },\n      { 0x70d10493109f5df1L,0xfbda403080af7550L,0x30b93f95c6b9a9b3L,\n        0x0c74ec71007d9418L } },\n    /* 25 << 91 */\n    { { 0x941755646edb951fL,0x5f4a9d787f22c282L,0xb7870895b38d1196L,\n        0xbc593df3a228ce7cL },\n      { 0xc78c5bd46af3641aL,0x7802200b3d9b3dccL,0x0dc73f328be33304L,\n        0x847ed87d61ffb79aL } },\n    /* 26 << 91 */\n    { { 0xf85c974e6d671192L,0x1e14100ade16f60fL,0x45cb0d5a95c38797L,\n        0x18923bba9b022da4L },\n      { 0xef2be899bbe7e86eL,0x4a1510ee216067bfL,0xd98c815484d5ce3eL,\n        0x1af777f0f92a2b90L } },\n    /* 27 << 91 */\n    { { 0x9fbcb4004ef65724L,0x3e04a4c93c0ca6feL,0xfb3e2cb555002994L,\n        0x1f3a93c55363ecabL },\n      { 0x1fe00efe3923555bL,0x744bedd91e1751eaL,0x3fb2db596ab69357L,\n        0x8dbd7365f5e6618bL } },\n    /* 28 << 91 */\n    { { 0x99d53099df1ea40eL,0xb3f24a0b57d61e64L,0xd088a198596eb812L,\n        0x22c8361b5762940bL },\n      { 0x66f01f97f9c0d95cL,0x884611728e43cdaeL,0x11599a7fb72b15c3L,\n        0x135a7536420d95ccL } },\n    /* 29 << 91 */\n    { { 0x2dcdf0f75f7ae2f6L,0x15fc6e1dd7fa6da2L,0x81ca829ad1d441b6L,\n        0x84c10cf804a106b6L },\n      { 0xa9b26c95a73fbbd0L,0x7f24e0cb4d8f6ee8L,0x48b459371e25a043L,\n        0xf8a74fca036f3dfeL } },\n    /* 30 << 91 */\n    { { 0x1ed46585c9f84296L,0x7fbaa8fb3bc278b0L,0xa8e96cd46c4fcbd0L,\n        0x940a120273b60a5fL },\n      { 0x34aae12055a4aec8L,0x550e9a74dbd742f0L,0x794456d7228c68abL,\n        0x492f8868a4e25ec6L } },\n    /* 31 << 91 */\n    { { 0x682915adb2d8f398L,0xf13b51cc5b84c953L,0xcda90ab85bb917d6L,\n        0x4b6155604ea3dee1L },\n      { 0x578b4e850a52c1c8L,0xeab1a69520b75fc4L,0x60c14f3caa0bb3c6L,\n        0x220f448ab8216094L } },\n    /* 32 << 91 */\n    { { 0x4fe7ee31b0e63d34L,0xf4600572a9e54fabL,0xc0493334d5e7b5a4L,\n        0x8589fb9206d54831L },\n      { 0xaa70f5cc6583553aL,0x0879094ae25649e5L,0xcc90450710044652L,\n        0xebb0696d02541c4fL } },\n    /* 33 << 91 */\n    { { 0x5a171fdeb9718710L,0x38f1bed8f374a9f5L,0xc8c582e1ba39bdc1L,\n        0xfc457b0a908cc0ceL },\n      { 0x9a187fd4883841e2L,0x8ec25b3938725381L,0x2553ed0596f84395L,\n        0x095c76616f6c6897L } },\n    /* 34 << 91 */\n    { { 0x917ac85c4bdc5610L,0xb2885fe4179eb301L,0x5fc655478b78bdccL,\n        0x4a9fc893e59e4699L },\n      { 0xbb7ff0cd3ce299afL,0x195be9b3adf38b20L,0x6a929c87d38ddb8fL,\n        0x55fcc99cb21a51b9L } },\n    /* 35 << 91 */\n    { { 0x2b695b4c721a4593L,0xed1e9a15768eaac2L,0xfb63d71c7489f914L,\n        0xf98ba31c78118910L },\n      { 0x802913739b128eb4L,0x7801214ed448af4aL,0xdbd2e22b55418dd3L,\n        0xeffb3c0dd3998242L } },\n    /* 36 << 91 */\n    { { 0xdfa6077cc7bf3827L,0xf2165bcb47f8238fL,0xfe37cf688564d554L,\n        0xe5f825c40a81fb98L },\n      { 0x43cc4f67ffed4d6fL,0xbc609578b50a34b0L,0x8aa8fcf95041faf1L,\n        0x5659f053651773b6L } },\n    /* 37 << 91 */\n    { { 0xe87582c36044d63bL,0xa60894090cdb0ca0L,0x8c993e0fbfb2bcf6L,\n        0xfc64a71945985cfcL },\n      { 0x15c4da8083dbedbaL,0x804ae1122be67df7L,0xda4c9658a23defdeL,\n        0x12002ddd5156e0d3L } },\n    /* 38 << 91 */\n    { { 0xe68eae895dd21b96L,0x8b99f28bcf44624dL,0x0ae008081ec8897aL,\n        0xdd0a93036712f76eL },\n      { 0x962375224e233de4L,0x192445b12b36a8a5L,0xabf9ff74023993d9L,\n        0x21f37bf42aad4a8fL } },\n    /* 39 << 91 */\n    { { 0x340a4349f8bd2bbdL,0x1d902cd94868195dL,0x3d27bbf1e5fdb6f1L,\n        0x7a5ab088124f9f1cL },\n      { 0xc466ab06f7a09e03L,0x2f8a197731f2c123L,0xda355dc7041b6657L,\n        0xcb840d128ece2a7cL } },\n    /* 40 << 91 */\n    { { 0xb600ad9f7db32675L,0x78fea13307a06f1bL,0x5d032269b31f6094L,\n        0x07753ef583ec37aaL },\n      { 0x03485aed9c0bea78L,0x41bb3989bc3f4524L,0x09403761697f726dL,\n        0x6109beb3df394820L } },\n    /* 41 << 91 */\n    { { 0x804111ea3b6d1145L,0xb6271ea9a8582654L,0x619615e624e66562L,\n        0xa2554945d7b6ad9cL },\n      { 0xd9c4985e99bfe35fL,0x9770ccc07b51cdf6L,0x7c32701392881832L,\n        0x8777d45f286b26d1L } },\n    /* 42 << 91 */\n    { { 0x9bbeda22d847999dL,0x03aa33b6c3525d32L,0x4b7b96d428a959a1L,\n        0xbb3786e531e5d234L },\n      { 0xaeb5d3ce6961f247L,0x20aa85af02f93d3fL,0x9cd1ad3dd7a7ae4fL,\n        0xbf6688f0781adaa8L } },\n    /* 43 << 91 */\n    { { 0xb1b40e867469ceadL,0x1904c524309fca48L,0x9b7312af4b54bbc7L,\n        0xbe24bf8f593affa2L },\n      { 0xbe5e0790bd98764bL,0xa0f45f17a26e299eL,0x4af0d2c26b8fe4c7L,\n        0xef170db18ae8a3e6L } },\n    /* 44 << 91 */\n    { { 0x0e8d61a029e0ccc1L,0xcd53e87e60ad36caL,0x328c6623c8173822L,\n        0x7ee1767da496be55L },\n      { 0x89f13259648945afL,0x9e45a5fd25c8009cL,0xaf2febd91f61ab8cL,\n        0x43f6bc868a275385L } },\n    /* 45 << 91 */\n    { { 0x87792348f2142e79L,0x17d89259c6e6238aL,0x7536d2f64a839d9bL,\n        0x1f428fce76a1fbdcL },\n      { 0x1c1096010db06dfeL,0xbfc16bc150a3a3ccL,0xf9cbd9ec9b30f41bL,\n        0x5b5da0d600138cceL } },\n    /* 46 << 91 */\n    { { 0xec1d0a4856ef96a7L,0xb47eb848982bf842L,0x66deae32ec3f700dL,\n        0x4e43c42caa1181e0L },\n      { 0xa1d72a31d1a4aa2aL,0x440d4668c004f3ceL,0x0d6a2d3b45fe8a7aL,\n        0x820e52e2fb128365L } },\n    /* 47 << 91 */\n    { { 0x29ac5fcf25e51b09L,0x180cd2bf2023d159L,0xa9892171a1ebf90eL,\n        0xf97c4c877c132181L },\n      { 0x9f1dc724c03dbb7eL,0xae043765018cbbe4L,0xfb0b2a360767d153L,\n        0xa8e2f4d6249cbaebL } },\n    /* 48 << 91 */\n    { { 0x172a5247d95ea168L,0x1758fada2970764aL,0xac803a511d978169L,\n        0x299cfe2ede77e01bL },\n      { 0x652a1e17b0a98927L,0x2e26e1d120014495L,0x7ae0af9f7175b56aL,\n        0xc2e22a80d64b9f95L } },\n    /* 49 << 91 */\n    { { 0x4d0ff9fbd90a060aL,0x496a27dbbaf38085L,0x32305401da776bcfL,\n        0xb8cdcef6725f209eL },\n      { 0x61ba0f37436a0bbaL,0x263fa10876860049L,0x92beb98eda3542cfL,\n        0xa2d4d14ad5849538L } },\n    /* 50 << 91 */\n    { { 0x989b9d6812e9a1bcL,0x61d9075c5f6e3268L,0x352c6aa999ace638L,\n        0xde4e4a55920f43ffL },\n      { 0xe5e4144ad673c017L,0x667417ae6f6e05eaL,0x613416aedcd1bd56L,\n        0x5eb3620186693711L } },\n    /* 51 << 91 */\n    { { 0x2d7bc5043a1aa914L,0x175a129976dc5975L,0xe900e0f23fc8125cL,\n        0x569ef68c11198875L },\n      { 0x9012db6363a113b4L,0xe3bd3f5698835766L,0xa5c94a5276412deaL,\n        0xad9e2a09aa735e5cL } },\n    /* 52 << 91 */\n    { { 0x405a984c508b65e9L,0xbde4a1d16df1a0d1L,0x1a9433a1dfba80daL,\n        0xe9192ff99440ad2eL },\n      { 0x9f6496965099fe92L,0x25ddb65c0b27a54aL,0x178279ddc590da61L,\n        0x5479a999fbde681aL } },\n    /* 53 << 91 */\n    { { 0xd0e84e05013fe162L,0xbe11dc92632d471bL,0xdf0b0c45fc0e089fL,\n        0x04fb15b04c144025L },\n      { 0xa61d5fc213c99927L,0xa033e9e03de2eb35L,0xf8185d5cb8dacbb4L,\n        0x9a88e2658644549dL } },\n    /* 54 << 91 */\n    { { 0xf717af6254671ff6L,0x4bd4241b5fa58603L,0x06fba40be67773c0L,\n        0xc1d933d26a2847e9L },\n      { 0xf4f5acf3689e2c70L,0x92aab0e746bafd31L,0x798d76aa3473f6e5L,\n        0xcc6641db93141934L } },\n    /* 55 << 91 */\n    { { 0xcae27757d31e535eL,0x04cc43b687c2ee11L,0x8d1f96752e029ffaL,\n        0xc2150672e4cc7a2cL },\n      { 0x3b03c1e08d68b013L,0xa9d6816fedf298f3L,0x1bfbb529a2804464L,\n        0x95a52fae5db22125L } },\n    /* 56 << 91 */\n    { { 0x55b321600e1cb64eL,0x004828f67e7fc9feL,0x13394b821bb0fb93L,\n        0xb6293a2d35f1a920L },\n      { 0xde35ef21d145d2d9L,0xbe6225b3bb8fa603L,0x00fc8f6b32cf252dL,\n        0xa28e52e6117cf8c2L } },\n    /* 57 << 91 */\n    { { 0x9d1dc89b4c371e6dL,0xcebe067536ef0f28L,0x5de05d09a4292f81L,\n        0xa8303593353e3083L },\n      { 0xa1715b0a7e37a9bbL,0x8c56f61e2b8faec3L,0x5250743133c9b102L,\n        0x0130cefca44431f0L } },\n    /* 58 << 91 */\n    { { 0x56039fa0bd865cfbL,0x4b03e578bc5f1dd7L,0x40edf2e4babe7224L,\n        0xc752496d3a1988f6L },\n      { 0xd1572d3b564beb6bL,0x0db1d11039a1c608L,0x568d193416f60126L,\n        0x05ae9668f354af33L } },\n    /* 59 << 91 */\n    { { 0x19de6d37c92544f2L,0xcc084353a35837d5L,0xcbb6869c1a514eceL,\n        0xb633e7282e1d1066L },\n      { 0xf15dd69f936c581cL,0x96e7b8ce7439c4f9L,0x5e676f482e448a5bL,\n        0xb2ca7d5bfd916bbbL } },\n    /* 60 << 91 */\n    { { 0xd55a2541f5024025L,0x47bc5769e4c2d937L,0x7d31b92a0362189fL,\n        0x83f3086eef7816f9L },\n      { 0xf9f46d94b587579aL,0xec2d22d830e76c5fL,0x27d57461b000ffcfL,\n        0xbb7e65f9364ffc2cL } },\n    /* 61 << 91 */\n    { { 0x7c7c94776652a220L,0x61618f89d696c981L,0x5021701d89effff3L,\n        0xf2c8ff8e7c314163L },\n      { 0x2da413ad8efb4d3eL,0x937b5adfce176d95L,0x22867d342a67d51cL,\n        0x262b9b1018eb3ac9L } },\n    /* 62 << 91 */\n    { { 0x4e314fe4c43ff28bL,0x764766276a664e7aL,0x3e90e40bb7a565c2L,\n        0x8588993ac1acf831L },\n      { 0xd7b501d68f938829L,0x996627ee3edd7d4cL,0x37d44a6290cd34c7L,\n        0xa8327499f3833e8dL } },\n    /* 63 << 91 */\n    { { 0x2e18917d4bf50353L,0x85dd726b556765fbL,0x54fe65d693d5ab66L,\n        0x3ddbaced915c25feL },\n      { 0xa799d9a412f22e85L,0xe2a248676d06f6bcL,0xf4f1ee5643ca1637L,\n        0xfda2828b61ece30aL } },\n    /* 64 << 91 */\n    { { 0x758c1a3ea2dee7a6L,0xdcde2f3c734b2284L,0xaba445d24eaba6adL,\n        0x35aaf66876cee0a7L },\n      { 0x7e0b04a9e5aa049aL,0xe74083ad91103e84L,0xbeb183ce40afecc3L,\n        0x6b89de9fea043f7aL } },\n    /* 0 << 98 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 98 */\n    { { 0x0e299d23fe67ba66L,0x9145076093cf2f34L,0xf45b5ea997fcf913L,\n        0x5be008438bd7dddaL },\n      { 0x358c3e05d53ff04dL,0xbf7ccdc35de91ef7L,0xad684dbfb69ec1a0L,\n        0x367e7cf2801fd997L } },\n    /* 2 << 98 */\n    { { 0x0ca1f3b7b0dc8595L,0x27de46089f1d9f2eL,0x1af3bf39badd82a7L,\n        0x79356a7965862448L },\n      { 0xc0602345f5f9a052L,0x1a8b0f89139a42f9L,0xb53eee42844d40fcL,\n        0x93b0bfe54e5b6368L } },\n    /* 3 << 98 */\n    { { 0x5434dd02c024789cL,0x90dca9ea41b57bfcL,0x8aa898e2243398dfL,\n        0xf607c834894a94bbL },\n      { 0xbb07be97c2c99b76L,0x6576ba6718c29302L,0x3d79efcce703a88cL,\n        0xf259ced7b6a0d106L } },\n    /* 4 << 98 */\n    { { 0x0f893a5dc8de610bL,0xe8c515fb67e223ceL,0x7774bfa64ead6dc5L,\n        0x89d20f95925c728fL },\n      { 0x7a1e0966098583ceL,0xa2eedb9493f2a7d7L,0x1b2820974c304d4aL,\n        0x0842e3dac077282dL } },\n    /* 5 << 98 */\n    { { 0xe4d972a33b9e2d7bL,0x7cc60b27c48218ffL,0x8fc7083884149d91L,\n        0x5c04346f2f461eccL },\n      { 0xebe9fdf2614650a9L,0x5e35b537c1f666acL,0x645613d188babc83L,\n        0x88cace3ac5e1c93eL } },\n    /* 6 << 98 */\n    { { 0x209ca3753de92e23L,0xccb03cc85fbbb6e3L,0xccb90f03d7b1487eL,\n        0xfa9c2a38c710941fL },\n      { 0x756c38236724ceedL,0x3a902258192d0323L,0xb150e519ea5e038eL,\n        0xdcba2865c7427591L } },\n    /* 7 << 98 */\n    { { 0xe549237f78890732L,0xc443bef953fcb4d9L,0x9884d8a6eb3480d6L,\n        0x8a35b6a13048b186L },\n      { 0xb4e4471665e9a90aL,0x45bf380d653006c0L,0x8f3f820d4fe9ae3bL,\n        0x244a35a0979a3b71L } },\n    /* 8 << 98 */\n    { { 0xa1010e9d74cd06ffL,0x9c17c7dfaca3eeacL,0x74c86cd38063aa2bL,\n        0x8595c4b3734614ffL },\n      { 0xa3de00ca990f62ccL,0xd9bed213ca0c3be5L,0x7886078adf8ce9f5L,\n        0xddb27ce35cd44444L } },\n    /* 9 << 98 */\n    { { 0xed374a6658926dddL,0x138b2d49908015b8L,0x886c6579de1f7ab8L,\n        0x888b9aa0c3020b7aL },\n      { 0xd3ec034e3a96e355L,0xba65b0b8f30fbe9aL,0x064c8e50ff21367aL,\n        0x1f508ea40b04b46eL } },\n    /* 10 << 98 */\n    { { 0x98561a49747c866cL,0xbbb1e5fe0518a062L,0x20ff4e8becdc3608L,\n        0x7f55cded20184027L },\n      { 0x8d73ec95f38c85f0L,0x5b589fdf8bc3b8c3L,0xbe95dd980f12b66fL,\n        0xf5bd1a090e338e01L } },\n    /* 11 << 98 */\n    { { 0x65163ae55e915918L,0x6158d6d986f8a46bL,0x8466b538eeebf99cL,\n        0xca8761f6bca477efL },\n      { 0xaf3449c29ebbc601L,0xef3b0f41e0c3ae2fL,0xaa6c577d5de63752L,\n        0xe916660164682a51L } },\n    /* 12 << 98 */\n    { { 0x5a3097befc15aa1eL,0x40d12548b54b0745L,0x5bad4706519a5f12L,\n        0xed03f717a439dee6L },\n      { 0x0794bb6c4a02c499L,0xf725083dcffe71d2L,0x2cad75190f3adcafL,\n        0x7f68ea1c43729310L } },\n    /* 13 << 98 */\n    { { 0xe747c8c7b7ffd977L,0xec104c3580761a22L,0x8395ebaf5a3ffb83L,\n        0xfb3261f4e4b63db7L },\n      { 0x53544960d883e544L,0x13520d708cc2eeb8L,0x08f6337bd3d65f99L,\n        0x83997db2781cf95bL } },\n    /* 14 << 98 */\n    { { 0xce6ff1060dbd2c01L,0x4f8eea6b1f9ce934L,0x546f7c4b0e993921L,\n        0x6236a3245e753fc7L },\n      { 0x65a41f84a16022e9L,0x0c18d87843d1dbb2L,0x73c556402d4cef9cL,\n        0xa042810870444c74L } },\n    /* 15 << 98 */\n    { { 0x68e4f15e9afdfb3cL,0x49a561435bdfb6dfL,0xa9bc1bd45f823d97L,\n        0xbceb5970ea111c2aL },\n      { 0x366b455fb269bbc4L,0x7cd85e1ee9bc5d62L,0xc743c41c4f18b086L,\n        0xa4b4099095294fb9L } },\n    /* 16 << 98 */\n    { { 0x9c7c581d26ee8382L,0xcf17dcc5359d638eL,0xee8273abb728ae3dL,\n        0x1d112926f821f047L },\n      { 0x1149847750491a74L,0x687fa761fde0dfb9L,0x2c2580227ea435abL,\n        0x6b8bdb9491ce7e3fL } },\n    /* 17 << 98 */\n    { { 0x4c5b5dc93bf834aaL,0x043718194f6c7e4bL,0xc284e00a3736bcadL,\n        0x0d88111821ae8f8dL },\n      { 0xf9cf0f82f48c8e33L,0xa11fd075a1bf40dbL,0xdceab0dedc2733e5L,\n        0xc560a8b58e986bd7L } },\n    /* 18 << 98 */\n    { { 0x48dd1fe23929d097L,0x3885b29092f188f1L,0x0f2ae613da6fcdacL,\n        0x9054303eb662a46cL },\n      { 0xb6871e440738042aL,0x98e6a977bdaf6449L,0xd8bc0650d1c9df1bL,\n        0xef3d645136e098f9L } },\n    /* 19 << 98 */\n    { { 0x03fbae82b6d72d28L,0x77ca9db1f5d84080L,0x8a112cffa58efc1cL,\n        0x518d761cc564cb4aL },\n      { 0x69b5740ef0d1b5ceL,0x717039cce9eb1785L,0x3fe29f9022f53382L,\n        0x8e54ba566bc7c95cL } },\n    /* 20 << 98 */\n    { { 0x9c806d8af7f91d0fL,0x3b61b0f1a82a5728L,0x4640032d94d76754L,\n        0x273eb5de47d834c6L },\n      { 0x2988abf77b4e4d53L,0xb7ce66bfde401777L,0x9fba6b32715071b3L,\n        0x82413c24ad3a1a98L } },\n    /* 21 << 98 */\n    { { 0x5b7fc8c4e0e8ad93L,0xb5679aee5fab868dL,0xb1f9d2fa2b3946f3L,\n        0x458897dc5685b50aL },\n      { 0x1e98c93089d0caf3L,0x39564c5f78642e92L,0x1b77729a0dbdaf18L,\n        0xf9170722579e82e6L } },\n    /* 22 << 98 */\n    { { 0x680c0317e4515fa5L,0xf85cff84fb0c790fL,0xc7a82aab6d2e0765L,\n        0x7446bca935c82b32L },\n      { 0x5de607aa6d63184fL,0x7c1a46a8262803a6L,0xd218313daebe8035L,\n        0x92113ffdc73c51f8L } },\n    /* 23 << 98 */\n    { { 0x4b38e08312e7e46cL,0x69d0a37a56126bd5L,0xfb3f324b73c07e04L,\n        0xa0c22f678fda7267L },\n      { 0x8f2c00514d2c7d8fL,0xbc45ced3cbe2cae5L,0xe1c6cf07a8f0f277L,\n        0xbc3923121eb99a98L } },\n    /* 24 << 98 */\n    { { 0x75537b7e3cc8ac85L,0x8d725f57dd02753bL,0xfd05ff64b737df2fL,\n        0x55fe8712f6d2531dL },\n      { 0x57ce04a96ab6b01cL,0x69a02a897cd93724L,0x4f82ac35cf86699bL,\n        0x8242d3ad9cb4b232L } },\n    /* 25 << 98 */\n    { { 0x713d0f65d62105e5L,0xbb222bfa2d29be61L,0xf2f9a79e6cfbef09L,\n        0xfc24d8d3d5d6782fL },\n      { 0x5db77085d4129967L,0xdb81c3ccdc3c2a43L,0x9d655fc005d8d9a3L,\n        0x3f5d057a54298026L } },\n    /* 26 << 98 */\n    { { 0x1157f56d88c54694L,0xb26baba59b09573eL,0x2cab03b022adffd1L,\n        0x60a412c8dd69f383L },\n      { 0xed76e98b54b25039L,0xd4ee67d3687e714dL,0x877396487b00b594L,\n        0xce419775c9ef709bL } },\n    /* 27 << 98 */\n    { { 0x40f76f851c203a40L,0x30d352d6eafd8f91L,0xaf196d3d95578dd2L,\n        0xea4bb3d777cc3f3dL },\n      { 0x42a5bd03b98e782bL,0xac958c400624920dL,0xb838134cfc56fcc8L,\n        0x86ec4ccf89572e5eL } },\n    /* 28 << 98 */\n    { { 0x69c435269be47be0L,0x323b7dd8cb28fea1L,0xfa5538ba3a6c67e5L,\n        0xef921d701d378e46L },\n      { 0xf92961fc3c4b880eL,0x3f6f914e98940a67L,0xa990eb0afef0ff39L,\n        0xa6c2920ff0eeff9cL } },\n    /* 29 << 98 */\n    { { 0xca80416651b8d9a3L,0x42531bc90ffb0db1L,0x72ce4718aa82e7ceL,\n        0x6e199913df574741L },\n      { 0xd5f1b13dd5d36946L,0x8255dc65f68f0194L,0xdc9df4cd8710d230L,\n        0x3453c20f138c1988L } },\n    /* 30 << 98 */\n    { { 0x9af98dc089a6ef01L,0x4dbcc3f09857df85L,0x348056015c1ad924L,\n        0x40448da5d0493046L },\n      { 0xf629926d4ee343e2L,0x6343f1bd90e8a301L,0xefc9349140815b3fL,\n        0xf882a423de8f66fbL } },\n    /* 31 << 98 */\n    { { 0x3a12d5f4e7db9f57L,0x7dfba38a3c384c27L,0x7a904bfd6fc660b1L,\n        0xeb6c5db32773b21cL },\n      { 0xc350ee661cdfe049L,0x9baac0ce44540f29L,0xbc57b6aba5ec6aadL,\n        0x167ce8c30a7c1baaL } },\n    /* 32 << 98 */\n    { { 0xb23a03a553fb2b56L,0x6ce141e74e057f78L,0x796525c389e490d9L,\n        0x0bc95725a31a7e75L },\n      { 0x1ec567911220fd06L,0x716e3a3c408b0bd6L,0x31cd6bf7e8ebeba9L,\n        0xa7326ca6bee6b670L } },\n    /* 33 << 98 */\n    { { 0x3d9f851ccd090c43L,0x561e8f13f12c3988L,0x50490b6a904b7be4L,\n        0x61690ce10410737bL },\n      { 0x299e9a370f009052L,0x258758f0f026092eL,0x9fa255f3fdfcdc0fL,\n        0xdbc9fb1fc0e1bcd2L } },\n    /* 34 << 98 */\n    { { 0x35f9dd6e24651840L,0xdca45a84a5c59abcL,0x103d396fecca4938L,\n        0x4532da0ab97b3f29L },\n      { 0xc4135ea51999a6bfL,0x3aa9505a5e6bf2eeL,0xf77cef063f5be093L,\n        0x97d1a0f8a943152eL } },\n    /* 35 << 98 */\n    { { 0x2cb0ebba2e1c21ddL,0xf41b29fc2c6797c4L,0xc6e17321b300101fL,\n        0x4422b0e9d0d79a89L },\n      { 0x49e4901c92f1bfc4L,0x06ab1f8fe1e10ed9L,0x84d35577db2926b8L,\n        0xca349d39356e8ec2L } },\n    /* 36 << 98 */\n    { { 0x70b63d32343bf1a9L,0x8fd3bd2837d1a6b1L,0x0454879c316865b4L,\n        0xee959ff6c458efa2L },\n      { 0x0461dcf89706dc3fL,0x737db0e2164e4b2eL,0x092626802f8843c8L,\n        0x54498bbc7745e6f6L } },\n    /* 37 << 98 */\n    { { 0x359473faa29e24afL,0xfcc3c45470aa87a1L,0xfd2c4bf500573aceL,\n        0xb65b514e28dd1965L },\n      { 0xe46ae7cf2193e393L,0x60e9a4e1f5444d97L,0xe7594e9600ff38edL,\n        0x43d84d2f0a0e0f02L } },\n    /* 38 << 98 */\n    { { 0x8b6db141ee398a21L,0xb88a56aee3bcc5beL,0x0a1aa52f373460eaL,\n        0x20da1a56160bb19bL },\n      { 0xfb54999d65bf0384L,0x71a14d245d5a180eL,0xbc44db7b21737b04L,\n        0xd84fcb1801dd8e92L } },\n    /* 39 << 98 */\n    { { 0x80de937bfa44b479L,0x535054995c98fd4fL,0x1edb12ab28f08727L,\n        0x4c58b582a5f3ef53L },\n      { 0xbfb236d88327f246L,0xc3a3bfaa4d7df320L,0xecd96c59b96024f2L,\n        0xfc293a537f4e0433L } },\n    /* 40 << 98 */\n    { { 0x5341352b5acf6e10L,0xc50343fdafe652c3L,0x4af3792d18577a7fL,\n        0xe1a4c617af16823dL },\n      { 0x9b26d0cd33425d0aL,0x306399ed9b7bc47fL,0x2a792f33706bb20bL,\n        0x3121961498111055L } },\n    /* 41 << 98 */\n    { { 0x864ec06487f5d28bL,0x11392d91962277fdL,0xb5aa7942bb6aed5fL,\n        0x080094dc47e799d9L },\n      { 0x4afa588c208ba19bL,0xd3e7570f8512f284L,0xcbae64e602f5799aL,\n        0xdeebe7ef514b9492L } },\n    /* 42 << 98 */\n    { { 0x30300f98e5c298ffL,0x17f561be3678361fL,0xf52ff31298cb9a16L,\n        0x6233c3bc5562d490L },\n      { 0x7bfa15a192e3a2cbL,0x961bcfd1e6365119L,0x3bdd29bf2c8c53b1L,\n        0x739704df822844baL } },\n    /* 43 << 98 */\n    { { 0x7dacfb587e7b754bL,0x23360791a806c9b9L,0xe7eb88c923504452L,\n        0x2983e996852c1783L },\n      { 0xdd4ae529958d881dL,0x026bae03262c7b3cL,0x3a6f9193960b52d1L,\n        0xd0980f9092696cfbL } },\n    /* 44 << 98 */\n    { { 0x4c1f428cd5f30851L,0x94dfed272a4f6630L,0x4df53772fc5d48a4L,\n        0xdd2d5a2f933260ceL },\n      { 0x574115bdd44cc7a5L,0x4ba6b20dbd12533aL,0x30e93cb8243057c9L,\n        0x794c486a14de320eL } },\n    /* 45 << 98 */\n    { { 0xe925d4cef21496e4L,0xf951d198ec696331L,0x9810e2de3e8d812fL,\n        0xd0a47259389294abL },\n      { 0x513ba2b50e3bab66L,0x462caff5abad306fL,0xe2dc6d59af04c49eL,\n        0x1aeb8750e0b84b0bL } },\n    /* 46 << 98 */\n    { { 0xc034f12f2f7d0ca2L,0x6d2e8128e06acf2fL,0x801f4f8321facc2fL,\n        0xa1170c03f40ef607L },\n      { 0xfe0a1d4f7805a99cL,0xbde56a36cc26aba5L,0x5b1629d035531f40L,\n        0xac212c2b9afa6108L } },\n    /* 47 << 98 */\n    { { 0x30a06bf315697be5L,0x6f0545dc2c63c7c1L,0x5d8cb8427ccdadafL,\n        0xd52e379bac7015bbL },\n      { 0xc4f56147f462c23eL,0xd44a429846bc24b0L,0xbc73d23ae2856d4fL,\n        0x61cedd8c0832bcdfL } },\n    /* 48 << 98 */\n    { { 0x6095355699f241d7L,0xee4adbd7001a349dL,0x0b35bf6aaa89e491L,\n        0x7f0076f4136f7546L },\n      { 0xd19a18ba9264da3dL,0x6eb2d2cd62a7a28bL,0xcdba941f8761c971L,\n        0x1550518ba3be4a5dL } },\n    /* 49 << 98 */\n    { { 0xd0e8e2f057d0b70cL,0xeea8612ecd133ba3L,0x814670f044416aecL,\n        0x424db6c330775061L },\n      { 0xd96039d116213fd1L,0xc61e7fa518a3478fL,0xa805bdcccb0c5021L,\n        0xbdd6f3a80cc616ddL } },\n    /* 50 << 98 */\n    { { 0x060096675d97f7e2L,0x31db0fc1af0bf4b6L,0x23680ed45491627aL,\n        0xb99a3c667d741fb1L },\n      { 0xe9bb5f5536b1ff92L,0x29738577512b388dL,0xdb8a2ce750fcf263L,\n        0x385346d46c4f7b47L } },\n    /* 51 << 98 */\n    { { 0xbe86c5ef31631f9eL,0xbf91da2103a57a29L,0xc3b1f7967b23f821L,\n        0x0f7d00d2770db354L },\n      { 0x8ffc6c3bd8fe79daL,0xcc5e8c40d525c996L,0x4640991dcfff632aL,\n        0x64d97e8c67112528L } },\n    /* 52 << 98 */\n    { { 0xc232d97302f1cd1eL,0xce87eacb1dd212a4L,0x6e4c8c73e69802f7L,\n        0x12ef02901fffddbdL },\n      { 0x941ec74e1bcea6e2L,0xd0b540243cb92cbbL,0x809fb9d47e8f9d05L,\n        0x3bf16159f2992aaeL } },\n    /* 53 << 98 */\n    { { 0xad40f279f8a7a838L,0x11aea63105615660L,0xbf52e6f1a01f6fa1L,\n        0xef0469953dc2aec9L },\n      { 0x785dbec9d8080711L,0xe1aec60a9fdedf76L,0xece797b5fa21c126L,\n        0xc66e898f05e52732L } },\n    /* 54 << 98 */\n    { { 0x39bb69c408811fdbL,0x8bfe1ef82fc7f082L,0xc8e7a393174f4138L,\n        0xfba8ad1dd58d1f98L },\n      { 0xbc21d0cebfd2fd5bL,0x0b839a826ee60d61L,0xaacf7658afd22253L,\n        0xb526bed8aae396b3L } },\n    /* 55 << 98 */\n    { { 0xccc1bbc238564464L,0x9e3ff9478c45bc73L,0xcde9bca358188a78L,\n        0x138b8ee0d73bf8f7L },\n      { 0x5c7e234c4123c489L,0x66e69368fa643297L,0x0629eeee39a15fa3L,\n        0x95fab881a9e2a927L } },\n    /* 56 << 98 */\n    { { 0xb2497007eafbb1e1L,0xd75c9ce6e75b7a93L,0x3558352defb68d78L,\n        0xa2f26699223f6396L },\n      { 0xeb911ecfe469b17aL,0x62545779e72d3ec2L,0x8ea47de782cb113fL,\n        0xebe4b0864e1fa98dL } },\n    /* 57 << 98 */\n    { { 0xec2d5ed78cdfedb1L,0xa535c077fe211a74L,0x9678109b11d244c5L,\n        0xf17c8bfbbe299a76L },\n      { 0xb651412efb11fbc4L,0xea0b548294ab3f65L,0xd8dffd950cf78243L,\n        0x2e719e57ce0361d4L } },\n    /* 58 << 98 */\n    { { 0x9007f085304ddc5bL,0x095e8c6d4daba2eaL,0x5a33cdb43f9d28a9L,\n        0x85b95cd8e2283003L },\n      { 0xbcd6c819b9744733L,0x29c5f538fc7f5783L,0x6c49b2fad59038e4L,\n        0x68349cc13bbe1018L } },\n    /* 59 << 98 */\n    { { 0xcc490c1d21830ee5L,0x36f9c4eee9bfa297L,0x58fd729448de1a94L,\n        0xaadb13a84e8f2cdcL },\n      { 0x515eaaa081313dbaL,0xc76bb468c2152dd8L,0x357f8d75a653dbf8L,\n        0xe4d8c4d1b14ac143L } },\n    /* 60 << 98 */\n    { { 0xbdb8e675b055cb40L,0x898f8e7b977b5167L,0xecc65651b82fb863L,\n        0x565448146d88f01fL },\n      { 0xb0928e95263a75a9L,0xcfb6836f1a22fcdaL,0x651d14db3f3bd37cL,\n        0x1d3837fbb6ad4664L } },\n    /* 61 << 98 */\n    { { 0x7c5fb538ff4f94abL,0x7243c7126d7fb8f2L,0xef13d60ca85c5287L,\n        0x18cfb7c74bb8dd1bL },\n      { 0x82f9bfe672908219L,0x35c4592b9d5144abL,0x52734f379cf4b42fL,\n        0x6bac55e78c60ddc4L } },\n    /* 62 << 98 */\n    { { 0xb5cd811e94dea0f6L,0x259ecae4e18cc1a3L,0x6a0e836e15e660f8L,\n        0x6c639ea60e02bff2L },\n      { 0x8721b8cb7e1026fdL,0x9e73b50b63261942L,0xb8c7097477f01da3L,\n        0x1839e6a68268f57fL } },\n    /* 63 << 98 */\n    { { 0x571b94155150b805L,0x1892389ef92c7097L,0x8d69c18e4a084b95L,\n        0x7014c512be5b495cL },\n      { 0x4780db361b07523cL,0x2f6219ce2c1c64faL,0xc38b81b0602c105aL,\n        0xab4f4f205dc8e360L } },\n    /* 64 << 98 */\n    { { 0x20d3c982cf7d62d2L,0x1f36e29d23ba8150L,0x48ae0bf092763f9eL,\n        0x7a527e6b1d3a7007L },\n      { 0xb4a89097581a85e3L,0x1f1a520fdc158be5L,0xf98db37d167d726eL,\n        0x8802786e1113e862L } },\n    /* 0 << 105 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 105 */\n    { { 0xefb2149e36f09ab0L,0x03f163ca4a10bb5bL,0xd029704506e20998L,\n        0x56f0af001b5a3babL },\n      { 0x7af4cfec70880e0dL,0x7332a66fbe3d913fL,0x32e6c84a7eceb4bdL,\n        0xedc4a79a9c228f55L } },\n    /* 2 << 105 */\n    { { 0xc37c7dd0c55c4496L,0xa6a9635725bbabd2L,0x5b7e63f2add7f363L,\n        0x9dce37822e73f1dfL },\n      { 0xe1e5a16ab2b91f71L,0xe44898235ba0163cL,0xf2759c32f6e515adL,\n        0xa5e2f1f88615eecfL } },\n    /* 3 << 105 */\n    { { 0x74519be7abded551L,0x03d358b8c8b74410L,0x4d00b10b0e10d9a9L,\n        0x6392b0b128da52b7L },\n      { 0x6744a2980b75c904L,0xc305b0aea8f7f96cL,0x042e421d182cf932L,\n        0xf6fc5d509e4636caL } },\n    /* 4 << 105 */\n    { { 0x795847c9d64cc78cL,0x6c50621b9b6cb27bL,0x07099bf8df8022abL,\n        0x48f862ebc04eda1dL },\n      { 0xd12732ede1603c16L,0x19a80e0f5c9a9450L,0xe2257f54b429b4fcL,\n        0x66d3b2c645460515L } },\n    /* 5 << 105 */\n    { { 0x6ca4f87e822e37beL,0x73f237b4253bda4eL,0xf747f3a241190aebL,\n        0xf06fa36f804cf284L },\n      { 0x0a6bbb6efc621c12L,0x5d624b6440b80ec6L,0x4b0724257ba556f3L,\n        0x7fa0c3543e2d20a8L } },\n    /* 6 << 105 */\n    { { 0xe921fa31e3229d41L,0xa929c65294531bd4L,0x84156027a6d38209L,\n        0xf3d69f736bdb97bdL },\n      { 0x8906d19a16833631L,0x68a34c2e03d51be3L,0xcb59583b0e511cd8L,\n        0x99ce6bfdfdc132a8L } },\n    /* 7 << 105 */\n    { { 0x3facdaaaffcdb463L,0x658bbc1a34a38b08L,0x12a801f8f1a9078dL,\n        0x1567bcf96ab855deL },\n      { 0xe08498e03572359bL,0xcf0353e58659e68bL,0xbb86e9c87d23807cL,\n        0xbc08728d2198e8a2L } },\n    /* 8 << 105 */\n    { { 0x8de2b7bc453cadd6L,0x203900a7bc0bc1f8L,0xbcd86e47a6abd3afL,\n        0x911cac128502effbL },\n      { 0x2d550242ec965469L,0x0e9f769229e0017eL,0x633f078f65979885L,\n        0xfb87d4494cf751efL } },\n    /* 9 << 105 */\n    { { 0xe1790e4bfc25419aL,0x364672034bff3cfdL,0xc8db638625b6e83fL,\n        0x6cc69f236cad6fd2L },\n      { 0x0219e45a6bc68bb9L,0xe43d79b6297f7334L,0x7d445368465dc97cL,\n        0x4b9eea322a0b949aL } },\n    /* 10 << 105 */\n    { { 0x1b96c6ba6102d021L,0xeaafac782f4461eaL,0xd4b85c41c49f19a8L,\n        0x275c28e4cf538875L },\n      { 0x35451a9ddd2e54e0L,0x6991adb50605618bL,0x5b8b4bcd7b36cd24L,\n        0x372a4f8c56f37216L } },\n    /* 11 << 105 */\n    { { 0xc890bd73a6a5da60L,0x6f083da0dc4c9ff0L,0xf4e14d94f0536e57L,\n        0xf9ee1edaaaec8243L },\n      { 0x571241ec8bdcf8e7L,0xa5db82710b041e26L,0x9a0b9a99e3fff040L,\n        0xcaaf21dd7c271202L } },\n    /* 12 << 105 */\n    { { 0xb4e2b2e14f0dd2e8L,0xe77e7c4f0a377ac7L,0x69202c3f0d7a2198L,\n        0xf759b7ff28200eb8L },\n      { 0xc87526eddcfe314eL,0xeb84c52453d5cf99L,0xb1b52ace515138b6L,\n        0x5aa7ff8c23fca3f4L } },\n    /* 13 << 105 */\n    { { 0xff0b13c3b9791a26L,0x960022dacdd58b16L,0xdbd55c9257aad2deL,\n        0x3baaaaa3f30fe619L },\n      { 0x9a4b23460d881efdL,0x506416c046325e2aL,0x91381e76035c18d4L,\n        0xb3bb68bef27817b0L } },\n    /* 14 << 105 */\n    { { 0x15bfb8bf5116f937L,0x7c64a586c1268943L,0x71e25cc38419a2c8L,\n        0x9fd6b0c48335f463L },\n      { 0x4bf0ba3ce8ee0e0eL,0x6f6fba60298c21faL,0x57d57b39ae66bee0L,\n        0x292d513022672544L } },\n    /* 15 << 105 */\n    { { 0xf451105dbab093b3L,0x012f59b902839986L,0x8a9158023474a89cL,\n        0x048c919c2de03e97L },\n      { 0xc476a2b591071cd5L,0x791ed89a034970a5L,0x89bd9042e1b7994bL,\n        0x8eaf5179a1057ffdL } },\n    /* 16 << 105 */\n    { { 0x6066e2a2d551ee10L,0x87a8f1d8727e09a6L,0x00d08bab2c01148dL,\n        0x6da8e4f1424f33feL },\n      { 0x466d17f0cf9a4e71L,0xff5020103bf5cb19L,0xdccf97d8d062ecc0L,\n        0x80c0d9af81d80ac4L } },\n    /* 17 << 105 */\n    { { 0xe87771d8033f2876L,0xb0186ec67d5cc3dbL,0x58e8bb803bc9bc1dL,\n        0x4d1395cc6f6ef60eL },\n      { 0xa73c62d6186244a0L,0x918e5f23110a5b53L,0xed4878ca741b7eabL,\n        0x3038d71adbe03e51L } },\n    /* 18 << 105 */\n    { { 0x840204b7a93c3246L,0x21ab6069a0b9b4cdL,0xf5fa6e2bb1d64218L,\n        0x1de6ad0ef3d56191L },\n      { 0x570aaa88ff1929c7L,0xc6df4c6b640e87b5L,0xde8a74f2c65f0cccL,\n        0x8b972fd5e6f6cc01L } },\n    /* 19 << 105 */\n    { { 0x3fff36b60b846531L,0xba7e45e610a5e475L,0x84a1d10e4145b6c5L,\n        0xf1f7f91a5e046d9dL },\n      { 0x0317a69244de90d7L,0x951a1d4af199c15eL,0x91f78046c9d73debL,\n        0x74c82828fab8224fL } },\n    /* 20 << 105 */\n    { { 0xaa6778fce7560b90L,0xb4073e61a7e824ceL,0xff0d693cd642eba8L,\n        0x7ce2e57a5dccef38L },\n      { 0x89c2c7891df1ad46L,0x83a06922098346fdL,0x2d715d72da2fc177L,\n        0x7b6dd71d85b6cf1dL } },\n    /* 21 << 105 */\n    { { 0xc60a6d0a73fa9cb0L,0xedd3992e328bf5a9L,0xc380ddd0832c8c82L,\n        0xd182d410a2a0bf50L },\n      { 0x7d9d7438d9a528dbL,0xe8b1a0e9caf53994L,0xddd6e5fe0e19987cL,\n        0xacb8df03190b059dL } },\n    /* 22 << 105 */\n    { { 0x53703a328300129fL,0x1f63766268c43bfdL,0xbcbd191300e54051L,\n        0x812fcc627bf5a8c5L },\n      { 0x3f969d5f29fb85daL,0x72f4e00a694759e8L,0x426b6e52790726b7L,\n        0x617bbc873bdbb209L } },\n    /* 23 << 105 */\n    { { 0x511f8bb997aee317L,0x812a4096e81536a8L,0x137dfe593ac09b9bL,\n        0x0682238fba8c9a7aL },\n      { 0x7072ead6aeccb4bdL,0x6a34e9aa692ba633L,0xc82eaec26fff9d33L,\n        0xfb7535121d4d2b62L } },\n    /* 24 << 105 */\n    { { 0x1a0445ff1d7aadabL,0x65d38260d5f6a67cL,0x6e62fb0891cfb26fL,\n        0xef1e0fa55c7d91d6L },\n      { 0x47e7c7ba33db72cdL,0x017cbc09fa7c74b2L,0x3c931590f50a503cL,\n        0xcac54f60616baa42L } },\n    /* 25 << 105 */\n    { { 0x9b6cd380b2369f0fL,0x97d3a70d23c76151L,0x5f9dd6fc9862a9c6L,\n        0x044c4ab212312f51L },\n      { 0x035ea0fd834a2ddcL,0x49e6b862cc7b826dL,0xb03d688362fce490L,\n        0x62f2497ab37e36e9L } },\n    /* 26 << 105 */\n    { { 0x04b005b6c6458293L,0x36bb5276e8d10af7L,0xacf2dc138ee617b8L,\n        0x470d2d35b004b3d4L },\n      { 0x06790832feeb1b77L,0x2bb75c3985657f9cL,0xd70bd4edc0f60004L,\n        0xfe797ecc219b018bL } },\n    /* 27 << 105 */\n    { { 0x9b5bec2a753aebccL,0xdaf9f3dcc939eca5L,0xd6bc6833d095ad09L,\n        0x98abdd51daa4d2fcL },\n      { 0xd9840a318d168be5L,0xcf7c10e02325a23cL,0xa5c02aa07e6ecfafL,\n        0x2462e7e6b5bfdf18L } },\n    /* 28 << 105 */\n    { { 0xab2d8a8ba0cc3f12L,0x68dd485dbc672a29L,0x72039752596f2cd3L,\n        0x5d3eea67a0cf3d8dL },\n      { 0x810a1a81e6602671L,0x8f144a4014026c0cL,0xbc753a6d76b50f85L,\n        0xc4dc21e8645cd4a4L } },\n    /* 29 << 105 */\n    { { 0xc5262dea521d0378L,0x802b8e0e05011c6fL,0x1ba19cbb0b4c19eaL,\n        0x21db64b5ebf0aaecL },\n      { 0x1f394ee970342f9dL,0x93a10aee1bc44a14L,0xa7eed31b3efd0baaL,\n        0x6e7c824e1d154e65L } },\n    /* 30 << 105 */\n    { { 0xee23fa819966e7eeL,0x64ec4aa805b7920dL,0x2d44462d2d90aad4L,\n        0xf44dd195df277ad5L },\n      { 0x8d6471f1bb46b6a1L,0x1e65d313fd885090L,0x33a800f513a977b4L,\n        0xaca9d7210797e1efL } },\n    /* 31 << 105 */\n    { { 0x9a5a85a0fcff6a17L,0x9970a3f31eca7ceeL,0xbb9f0d6bc9504be3L,\n        0xe0c504beadd24ee2L },\n      { 0x7e09d95677fcc2f4L,0xef1a522765bb5fc4L,0x145d4fb18b9286aaL,\n        0x66fd0c5d6649028bL } },\n    /* 32 << 105 */\n    { { 0x98857ceb1bf4581cL,0xe635e186aca7b166L,0x278ddd22659722acL,\n        0xa0903c4c1db68007L },\n      { 0x366e458948f21402L,0x31b49c14b96abda2L,0x329c4b09e0403190L,\n        0x97197ca3d29f43feL } },\n    /* 33 << 105 */\n    { { 0x8073dd1e274983d8L,0xda1a3bde55717c8fL,0xfd3d4da20361f9d1L,\n        0x1332d0814c7de1ceL },\n      { 0x9b7ef7a3aa6d0e10L,0x17db2e73f54f1c4aL,0xaf3dffae4cd35567L,\n        0xaaa2f406e56f4e71L } },\n    /* 34 << 105 */\n    { { 0x8966759e7ace3fc7L,0x9594eacf45a8d8c6L,0x8de3bd8b91834e0eL,\n        0xafe4ca53548c0421L },\n      { 0xfdd7e856e6ee81c6L,0x8f671beb6b891a3aL,0xf7a58f2bfae63829L,\n        0x9ab186fb9c11ac9fL } },\n    /* 35 << 105 */\n    { { 0x8d6eb36910b5be76L,0x046b7739fb040bcdL,0xccb4529fcb73de88L,\n        0x1df0fefccf26be03L },\n      { 0xad7757a6bcfcd027L,0xa8786c75bb3165caL,0xe9db1e347e99a4d9L,\n        0x99ee86dfb06c504bL } },\n    /* 36 << 105 */\n    { { 0x5b7c2dddc15c9f0aL,0xdf87a7344295989eL,0x59ece47c03d08fdaL,\n        0xb074d3ddad5fc702L },\n      { 0x2040790351a03776L,0x2bb1f77b2a608007L,0x25c58f4fe1153185L,\n        0xe6df62f6766e6447L } },\n    /* 37 << 105 */\n    { { 0xefb3d1beed51275aL,0x5de47dc72f0f483fL,0x7932d98e97c2bedfL,\n        0xd5c119270219f8a1L },\n      { 0x9d751200a73a294eL,0x5f88434a9dc20172L,0xd28d9fd3a26f506aL,\n        0xa890cd319d1dcd48L } },\n    /* 38 << 105 */\n    { { 0x0aebaec170f4d3b4L,0xfd1a13690ffc8d00L,0xb9d9c24057d57838L,\n        0x45929d2668bac361L },\n      { 0x5a2cd06025b15ca6L,0x4b3c83e16e474446L,0x1aac7578ee1e5134L,\n        0xa418f5d6c91e2f41L } },\n    /* 39 << 105 */\n    { { 0x6936fc8a213ed68bL,0x860ae7ed510a5224L,0x63660335def09b53L,\n        0x641b2897cd79c98dL },\n      { 0x29bd38e101110f35L,0x79c26f42648b1937L,0x64dae5199d9164f4L,\n        0xd85a23100265c273L } },\n    /* 40 << 105 */\n    { { 0x7173dd5d4b07e2b1L,0xd144c4cb8d9ea221L,0xe8b04ea41105ab14L,\n        0x92dda542fe80d8f1L },\n      { 0xe9982fa8cf03dce6L,0x8b5ea9651a22cffcL,0xf7f4ea7f3fad88c4L,\n        0x62db773e6a5ba95cL } },\n    /* 41 << 105 */\n    { { 0xd20f02fb93f24567L,0xfd46c69a315257caL,0x0ac74cc78bcab987L,\n        0x46f31c015ceca2f5L },\n      { 0x40aedb59888b219eL,0xe50ecc37e1fccd02L,0x1bcd9dad911f816cL,\n        0x583cc1ec8db9b00cL } },\n    /* 42 << 105 */\n    { { 0xf3cd2e66a483bf11L,0xfa08a6f5b1b2c169L,0xf375e2454be9fa28L,\n        0x99a7ffec5b6d011fL },\n      { 0x6a3ebddbc4ae62daL,0x6cea00ae374aef5dL,0xab5fb98d9d4d05bcL,\n        0x7cba1423d560f252L } },\n    /* 43 << 105 */\n    { { 0x49b2cc21208490deL,0x1ca66ec3bcfb2879L,0x7f1166b71b6fb16fL,\n        0xfff63e0865fe5db3L },\n      { 0xb8345abe8b2610beL,0xb732ed8039de3df4L,0x0e24ed50211c32b4L,\n        0xd10d8a69848ff27dL } },\n    /* 44 << 105 */\n    { { 0xc1074398ed4de248L,0xd7cedace10488927L,0xa4aa6bf885673e13L,\n        0xb46bae916daf30afL },\n      { 0x07088472fcef7ad8L,0x61151608d4b35e97L,0xbcfe8f26dde29986L,\n        0xeb84c4c7d5a34c79L } },\n    /* 45 << 105 */\n    { { 0xc1eec55c164e1214L,0x891be86da147bb03L,0x9fab4d100ba96835L,\n        0xbf01e9b8a5c1ae9fL },\n      { 0x6b4de139b186ebc0L,0xd5c74c2685b91bcaL,0x5086a99cc2d93854L,\n        0xeed62a7ba7a9dfbcL } },\n    /* 46 << 105 */\n    { { 0x8778ed6f76b7618aL,0xbff750a503b66062L,0x4cb7be22b65186dbL,\n        0x369dfbf0cc3a6d13L },\n      { 0xc7dab26c7191a321L,0x9edac3f940ed718eL,0xbc142b36d0cfd183L,\n        0xc8af82f67c991693L } },\n    /* 47 << 105 */\n    { { 0xb3d1e4d897ce0b2aL,0xe6d7c87fc3a55cdfL,0x35846b9568b81afeL,\n        0x018d12afd3c239d8L },\n      { 0x2b2c620801206e15L,0xe0e42453a3b882c6L,0x854470a3a50162d5L,\n        0x081574787017a62aL } },\n    /* 48 << 105 */\n    { { 0x18bd3fb4820357c7L,0x992039ae6f1458adL,0x9a1df3c525b44aa1L,\n        0x2d780357ed3d5281L },\n      { 0x58cf7e4dc77ad4d4L,0xd49a7998f9df4fc4L,0x4465a8b51d71205eL,\n        0xa0ee0ea6649254aaL } },\n    /* 49 << 105 */\n    { { 0x4b5eeecfab7bd771L,0x6c87307335c262b9L,0xdc5bd6483c9d61e7L,\n        0x233d6d54321460d2L },\n      { 0xd20c5626fc195bccL,0x2544595804d78b63L,0xe03fcb3d17ec8ef3L,\n        0x54b690d146b8f781L } },\n    /* 50 << 105 */\n    { { 0x82fa2c8a21230646L,0xf51aabb9084f418cL,0xff4fbec11a30ba43L,\n        0x6a5acf73743c9df7L },\n      { 0x1da2b357d635b4d5L,0xc3de68ddecd5c1daL,0xa689080bd61af0ddL,\n        0xdea5938ad665bf99L } },\n    /* 51 << 105 */\n    { { 0x0231d71afe637294L,0x01968aa6a5a81cd8L,0x11252d50048e63b5L,\n        0xc446bc526ca007e9L },\n      { 0xef8c50a696d6134bL,0x9361fbf59e09a05cL,0xf17f85a6dca3291aL,\n        0xb178d548ff251a21L } },\n    /* 52 << 105 */\n    { { 0x87f6374ba4df3915L,0x566ce1bf2fd5d608L,0x425cba4d7de35102L,\n        0x6b745f8f58c5d5e2L },\n      { 0x88402af663122edfL,0x3190f9ed3b989a89L,0x4ad3d387ebba3156L,\n        0xef385ad9c7c469a5L } },\n    /* 53 << 105 */\n    { { 0xb08281de3f642c29L,0x20be0888910ffb88L,0xf353dd4ad5292546L,\n        0x3f1627de8377a262L },\n      { 0xa5faa013eefcd638L,0x8f3bf62674cc77c3L,0x32618f65a348f55eL,\n        0x5787c0dc9fefeb9eL } },\n    /* 54 << 105 */\n    { { 0xf1673aa2d9a23e44L,0x88dfa9934e10690dL,0x1ced1b362bf91108L,\n        0x9193ceca3af48649L },\n      { 0xfb34327d2d738fc5L,0x6697b037975fee6cL,0x2f485da0c04079a5L,\n        0x2cdf57352feaa1acL } },\n    /* 55 << 105 */\n    { { 0x76944420bd55659eL,0x7973e32b4376090cL,0x86bb4fe1163b591aL,\n        0x10441aedc196f0caL },\n      { 0x3b431f4a045ad915L,0x6c11b437a4afacb1L,0x30b0c7db71fdbbd8L,\n        0xb642931feda65acdL } },\n    /* 56 << 105 */\n    { { 0x4baae6e89c92b235L,0xa73bbd0e6b3993a1L,0xd06d60ec693dd031L,\n        0x03cab91b7156881cL },\n      { 0xd615862f1db3574bL,0x485b018564bb061aL,0x27434988a0181e06L,\n        0x2cd61ad4c1c0c757L } },\n    /* 57 << 105 */\n    { { 0x3effed5a2ff9f403L,0x8dc98d8b62239029L,0x2206021e1f17b70dL,\n        0xafbec0cabf510015L },\n      { 0x9fed716480130dfaL,0x306dc2b58a02dcf5L,0x48f06620feb10fc0L,\n        0x78d1e1d55a57cf51L } },\n    /* 58 << 105 */\n    { { 0xadef8c5a192ef710L,0x88afbd4b3b7431f9L,0x7e1f740764250c9eL,\n        0x6e31318db58bec07L },\n      { 0xfd4fc4b824f89b4eL,0x65a5dd8848c36a2aL,0x4f1eccfff024baa7L,\n        0x22a21cf2cba94650L } },\n    /* 59 << 105 */\n    { { 0x95d29dee42a554f7L,0x828983a5002ec4baL,0x8112a1f78badb73dL,\n        0x79ea8897a27c1839L },\n      { 0x8969a5a7d065fd83L,0xf49af791b262a0bcL,0xfcdea8b6af2b5127L,\n        0x10e913e1564c2dbcL } },\n    /* 60 << 105 */\n    { { 0x51239d14bc21ef51L,0xe51c3ceb4ce57292L,0x795ff06847bbcc3bL,\n        0x86b46e1ebd7e11e6L },\n      { 0x0ea6ba2380041ef4L,0xd72fe5056262342eL,0x8abc6dfd31d294d4L,\n        0xbbe017a21278c2c9L } },\n    /* 61 << 105 */\n    { { 0xb1fcfa09b389328aL,0x322fbc62d01771b5L,0x04c0d06360b045bfL,\n        0xdb652edc10e52d01L },\n      { 0x50ef932c03ec6627L,0xde1b3b2dc1ee50e3L,0x5ab7bdc5dc37a90dL,\n        0xfea6721331e33a96L } },\n    /* 62 << 105 */\n    { { 0x6482b5cb4f2999aaL,0x38476cc6b8cbf0ddL,0x93ebfacb173405bbL,\n        0x15cdafe7e52369ecL },\n      { 0xd42d5ba4d935b7dbL,0x648b60041c99a4cdL,0x785101bda3b5545bL,\n        0x4bf2c38a9dd67fafL } },\n    /* 63 << 105 */\n    { { 0xb1aadc634442449cL,0xe0e9921a33ad4fb8L,0x5c552313aa686d82L,\n        0xdee635fa465d866cL },\n      { 0xbc3c224a18ee6e8aL,0xeed748a6ed42e02fL,0xe70f930ad474cd08L,\n        0x774ea6ecfff24adfL } },\n    /* 64 << 105 */\n    { { 0x03e2de1cf3480d4aL,0xf0d8edc7bc8acf1aL,0xf23e330368295a9cL,\n        0xfadd5f68c546a97dL },\n      { 0x895597ad96f8acb1L,0xbddd49d5671bdae2L,0x16fcd52821dd43f4L,\n        0xa5a454126619141aL } },\n    /* 0 << 112 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 112 */\n    { { 0x8ce9b6bfc360e25aL,0xe6425195075a1a78L,0x9dc756a8481732f4L,\n        0x83c0440f5432b57aL },\n      { 0xc670b3f1d720281fL,0x2205910ed135e051L,0xded14b0edb052be7L,\n        0x697b3d27c568ea39L } },\n    /* 2 << 112 */\n    { { 0x2e599b9afb3ff9edL,0x28c2e0ab17f6515cL,0x1cbee4fd474da449L,\n        0x071279a44f364452L },\n      { 0x97abff6601fbe855L,0x3ee394e85fda51c4L,0x190385f667597c0bL,\n        0x6e9fccc6a27ee34bL } },\n    /* 3 << 112 */\n    { { 0x0b89de9314092ebbL,0xf17256bd428e240cL,0xcf89a7f393d2f064L,\n        0x4f57841ee1ed3b14L },\n      { 0x4ee14405e708d855L,0x856aae7203f1c3d0L,0xc8e5424fbdd7eed5L,\n        0x3333e4ef73ab4270L } },\n    /* 4 << 112 */\n    { { 0x3bc77adedda492f8L,0xc11a3aea78297205L,0x5e89a3e734931b4cL,\n        0x17512e2e9f5694bbL },\n      { 0x5dc349f3177bf8b6L,0x232ea4ba08c7ff3eL,0x9c4f9d16f511145dL,\n        0xccf109a333b379c3L } },\n    /* 5 << 112 */\n    { { 0xe75e7a88a1f25897L,0x7ac6961fa1b5d4d8L,0xe3e1077308f3ed5cL,\n        0x208a54ec0a892dfbL },\n      { 0xbe826e1978660710L,0x0cf70a97237df2c8L,0x418a7340ed704da5L,\n        0xa3eeb9a908ca33fdL } },\n    /* 6 << 112 */\n    { { 0x49d96233169bca96L,0x04d286d42da6aafbL,0xc09606eca0c2fa94L,\n        0x8869d0d523ff0fb3L },\n      { 0xa99937e5d0150d65L,0xa92e2503240c14c9L,0x656bf945108e2d49L,\n        0x152a733aa2f59e2bL } },\n    /* 7 << 112 */\n    { { 0xb4323d588434a920L,0xc0af8e93622103c5L,0x667518ef938dbf9aL,\n        0xa184307383a9cdf2L },\n      { 0x350a94aa5447ab80L,0xe5e5a325c75a3d61L,0x74ba507f68411a9eL,\n        0x10581fc1594f70c5L } },\n    /* 8 << 112 */\n    { { 0x60e2857080eb24a9L,0x7bedfb4d488e0cfdL,0x721ebbd7c259cdb8L,\n        0x0b0da855bc6390a9L },\n      { 0x2b4d04dbde314c70L,0xcdbf1fbc6c32e846L,0x33833eabb162fc9eL,\n        0x9939b48bb0dd3ab7L } },\n    /* 9 << 112 */\n    { { 0x5aaa98a7cb0c9c8cL,0x75105f3081c4375cL,0xceee50575ef1c90fL,\n        0xb31e065fc23a17bfL },\n      { 0x5364d275d4b6d45aL,0xd363f3ad62ec8996L,0xb5d212394391c65bL,\n        0x84564765ebb41b47L } },\n    /* 10 << 112 */\n    { { 0x20d18ecc37107c78L,0xacff3b6b570c2a66L,0x22f975d99bd0d845L,\n        0xef0a0c46ba178fa0L },\n      { 0x1a41965176b6028eL,0xc49ec674248612d4L,0x5b6ac4f27338af55L,\n        0x06145e627bee5a36L } },\n    /* 11 << 112 */\n    { { 0x33e95d07e75746b5L,0x1c1e1f6dc40c78beL,0x967833ef222ff8e2L,\n        0x4bedcf6ab49180adL },\n      { 0x6b37e9c13d7a4c8aL,0x2748887c6ddfe760L,0xf7055123aa3a5bbcL,\n        0x954ff2257bbb8e74L } },\n    /* 12 << 112 */\n    { { 0xc42b8ab197c3dfb9L,0x55a549b0cf168154L,0xad6748e7c1b50692L,\n        0x2775780f6fc5cbcbL },\n      { 0x4eab80b8e1c9d7c8L,0x8c69dae13fdbcd56L,0x47e6b4fb9969eaceL,\n        0x002f1085a705cb5aL } },\n    /* 13 << 112 */\n    { { 0x4e23ca446d3fea55L,0xb4ae9c86f4810568L,0x47bfb91b2a62f27dL,\n        0x60deb4c9d9bac28cL },\n      { 0xa892d8947de6c34cL,0x4ee682594494587dL,0x914ee14e1a3f8a5bL,\n        0xbb113eaa28700385L } },\n    /* 14 << 112 */\n    { { 0x81ca03b92115b4c9L,0x7c163d388908cad1L,0xc912a118aa18179aL,\n        0xe09ed750886e3081L },\n      { 0xa676e3fa26f516caL,0x753cacf78e732f91L,0x51592aea833da8b4L,\n        0xc626f42f4cbea8aaL } },\n    /* 15 << 112 */\n    { { 0xef9dc899a7b56eafL,0x00c0e52c34ef7316L,0x5b1e4e24fe818a86L,\n        0x9d31e20dc538be47L },\n      { 0x22eb932d3ed68974L,0xe44bbc087c4e87c4L,0x4121086e0dde9aefL,\n        0x8e6b9cff134f4345L } },\n    /* 16 << 112 */\n    { { 0x96892c1f711b0eb9L,0xb905f2c8780ab954L,0xace26309a20792dbL,\n        0xec8ac9b30684e126L },\n      { 0x486ad8b6b40a2447L,0x60121fc19fe3fb24L,0x5626fccf1a8e3b3fL,\n        0x4e5686226ad1f394L } },\n    /* 17 << 112 */\n    { { 0xda7aae0d196aa5a1L,0xe0df8c771041b5fbL,0x451465d926b318b7L,\n        0xc29b6e557ab136e9L },\n      { 0x2c2ab48b71148463L,0xb5738de364454a76L,0x54ccf9a05a03abe4L,\n        0x377c02960427d58eL } },\n    /* 18 << 112 */\n    { { 0x73f5f0b92bb39c1fL,0x14373f2ce608d8c5L,0xdcbfd31400fbb805L,\n        0xdf18fb2083afdcfbL },\n      { 0x81a57f4242b3523fL,0xe958532d87f650fbL,0xaa8dc8b68b0a7d7cL,\n        0x1b75dfb7150166beL } },\n    /* 19 << 112 */\n    { { 0x90e4f7c92d7d1413L,0x67e2d6b59834f597L,0x4fd4f4f9a808c3e8L,\n        0xaf8237e0d5281ec1L },\n      { 0x25ab5fdc84687ceeL,0xc5ded6b1a5b26c09L,0x8e4a5aecc8ea7650L,\n        0x23b73e5c14cc417fL } },\n    /* 20 << 112 */\n    { { 0x2bfb43183037bf52L,0xb61e6db578c725d7L,0x8efd4060bbb3e5d7L,\n        0x2e014701dbac488eL },\n      { 0xac75cf9a360aa449L,0xb70cfd0579634d08L,0xa591536dfffb15efL,\n        0xb2c37582d07c106cL } },\n    /* 21 << 112 */\n    { { 0xb4293fdcf50225f9L,0xc52e175cb0e12b03L,0xf649c3bad0a8bf64L,\n        0x745a8fefeb8ae3c6L },\n      { 0x30d7e5a358321bc3L,0xb1732be70bc4df48L,0x1f217993e9ea5058L,\n        0xf7a71cde3e4fd745L } },\n    /* 22 << 112 */\n    { { 0x86cc533e894c5bbbL,0x6915c7d969d83082L,0xa6aa2d055815c244L,\n        0xaeeee59249b22ce5L },\n      { 0x89e39d1378135486L,0x3a275c1f16b76f2fL,0xdb6bcc1be036e8f5L,\n        0x4df69b215e4709f5L } },\n    /* 23 << 112 */\n    { { 0xa188b2502d0f39aaL,0x622118bb15a85947L,0x2ebf520ffde0f4faL,\n        0xa40e9f294860e539L },\n      { 0x7b6a51eb22b57f0fL,0x849a33b97e80644aL,0x50e5d16f1cf095feL,\n        0xd754b54eec55f002L } },\n    /* 24 << 112 */\n    { { 0x5cfbbb22236f4a98L,0x0b0c59e9066800bbL,0x4ac69a8f5a9a7774L,\n        0x2b33f804d6bec948L },\n      { 0xb372929532e6c466L,0x68956d0f4e599c73L,0xa47a249f155c31ccL,\n        0x24d80f0de1ce284eL } },\n    /* 25 << 112 */\n    { { 0xcd821dfb988baf01L,0xe6331a7ddbb16647L,0x1eb8ad33094cb960L,\n        0x593cca38c91bbca5L },\n      { 0x384aac8d26567456L,0x40fa0309c04b6490L,0x97834cd6dab6c8f6L,\n        0x68a7318d3f91e55fL } },\n    /* 26 << 112 */\n    { { 0xa00fd04efc4d3157L,0xb56f8ab22bf3bdeaL,0x014f56484fa57172L,\n        0x948c5860450abdb3L },\n      { 0x342b5df00ebd4f08L,0x3e5168cd0e82938eL,0x7aedc1ceb0df5dd0L,\n        0x6bbbc6d9e5732516L } },\n    /* 27 << 112 */\n    { { 0xc7bfd486605daaa6L,0x46fd72b7bb9a6c9eL,0xe4847fb1a124fb89L,\n        0x75959cbda2d8ffbcL },\n      { 0x42579f65c8a588eeL,0x368c92e6b80b499dL,0xea4ef6cd999a5df1L,\n        0xaa73bb7f936fe604L } },\n    /* 28 << 112 */\n    { { 0xf347a70d6457d188L,0x86eda86b8b7a388bL,0xb7cdff060ccd6013L,\n        0xbeb1b6c7d0053fb2L },\n      { 0x0b02238799240a9fL,0x1bbb384f776189b2L,0x8695e71e9066193aL,\n        0x2eb5009706ffac7eL } },\n    /* 29 << 112 */\n    { { 0x0654a9c04a7d2caaL,0x6f3fb3d1a5aaa290L,0x835db041ff476e8fL,\n        0x540b8b0bc42295e4L },\n      { 0xa5c73ac905e214f5L,0x9a74075a56a0b638L,0x2e4b1090ce9e680bL,\n        0x57a5b4796b8d9afaL } },\n    /* 30 << 112 */\n    { { 0x0dca48e726bfe65cL,0x097e391c7290c307L,0x683c462e6669e72eL,\n        0xf505be1e062559acL },\n      { 0x5fbe3ea1e3a3035aL,0x6431ebf69cd50da8L,0xfd169d5c1f6407f2L,\n        0x8d838a9560fce6b8L } },\n    /* 31 << 112 */\n    { { 0x2a2bfa7f650006f0L,0xdfd7dad350c0fbb2L,0x92452495ccf9ad96L,\n        0x183bf494d95635f9L },\n      { 0x02d5df434a7bd989L,0x505385cca5431095L,0xdd98e67dfd43f53eL,\n        0xd61e1a6c500c34a9L } },\n    /* 32 << 112 */\n    { { 0x5a4b46c64a8a3d62L,0x8469c4d0247743d2L,0x2bb3a13d88f7e433L,\n        0x62b23a1001be5849L },\n      { 0xe83596b4a63d1a4cL,0x454e7fea7d183f3eL,0x643fce6117afb01cL,\n        0x4e65e5e61c4c3638L } },\n    /* 33 << 112 */\n    { { 0x41d85ea1ef74c45bL,0x2cfbfa66ae328506L,0x98b078f53ada7da9L,\n        0xd985fe37ec752fbbL },\n      { 0xeece68fe5a0148b4L,0x6f9a55c72d78136dL,0x232dccc4d2b729ceL,\n        0xa27e0dfd90aafbc4L } },\n    /* 34 << 112 */\n    { { 0x9647445212b4603eL,0xa876c5516b706d14L,0xdf145fcf69a9d412L,\n        0xe2ab75b72d479c34L },\n      { 0x12df9a761a23ff97L,0xc61389925d359d10L,0x6e51c7aefa835f22L,\n        0x69a79cb1c0fcc4d9L } },\n    /* 35 << 112 */\n    { { 0xf57f350d594cc7e1L,0x3079ca633350ab79L,0x226fb6149aff594aL,\n        0x35afec026d59a62bL },\n      { 0x9bee46f406ed2c6eL,0x58da17357d939a57L,0x44c504028fd1797eL,\n        0xd8853e7c5ccea6caL } },\n    /* 36 << 112 */\n    { { 0x4065508da35fcd5fL,0x8965df8c495ccaebL,0x0f2da85012e1a962L,\n        0xee471b94c1cf1cc4L },\n      { 0xcef19bc80a08fb75L,0x704958f581de3591L,0x2867f8b23aef4f88L,\n        0x8d749384ea9f9a5fL } },\n    /* 37 << 112 */\n    { { 0x1b3855378c9049f4L,0x5be948f37b92d8b6L,0xd96f725db6e2bd6bL,\n        0x37a222bc958c454dL },\n      { 0xe7c61abb8809bf61L,0x46f07fbc1346f18dL,0xfb567a7ae87c0d1cL,\n        0x84a461c87ef3d07aL } },\n    /* 38 << 112 */\n    { { 0x0a5adce6d9278d98L,0x24d948139dfc73e1L,0x4f3528b6054321c3L,\n        0x2e03fdde692ea706L },\n      { 0x10e6061947b533c0L,0x1a8bc73f2ca3c055L,0xae58d4b21bb62b8fL,\n        0xb2045a73584a24e3L } },\n    /* 39 << 112 */\n    { { 0x3ab3d5afbd76e195L,0x478dd1ad6938a810L,0x6ffab3936ee3d5cbL,\n        0xdfb693db22b361e4L },\n      { 0xf969449651dbf1a7L,0xcab4b4ef08a2e762L,0xe8c92f25d39bba9aL,\n        0x850e61bcf1464d96L } },\n    /* 40 << 112 */\n    { { 0xb7e830e3dc09508bL,0xfaf6d2cf74317655L,0x72606cebdf690355L,\n        0x48bb92b3d0c3ded6L },\n      { 0x65b754845c7cf892L,0xf6cd7ac9d5d5f01fL,0xc2c30a5996401d69L,\n        0x91268650ed921878L } },\n    /* 41 << 112 */\n    { { 0x380bf913b78c558fL,0x43c0baebc8afdaa9L,0x377f61d554f169d3L,\n        0xf8da07e3ae5ff20bL },\n      { 0xb676c49da8a90ea8L,0x81c1ff2b83a29b21L,0x383297ac2ad8d276L,\n        0x3001122fba89f982L } },\n    /* 42 << 112 */\n    { { 0xe1d794be6718e448L,0x246c14827c3e6e13L,0x56646ef85d26b5efL,\n        0x80f5091e88069cddL },\n      { 0xc5992e2f724bdd38L,0x02e915b48471e8c7L,0x96ff320a0d0ff2a9L,\n        0xbf8864874384d1a0L } },\n    /* 43 << 112 */\n    { { 0xbbe1e6a6c93f72d6L,0xd5f75d12cad800eaL,0xfa40a09fe7acf117L,\n        0x32c8cdd57581a355L },\n      { 0x742219927023c499L,0xa8afe5d738ec3901L,0x5691afcba90e83f0L,\n        0x41bcaa030b8f8eacL } },\n    /* 44 << 112 */\n    { { 0xe38b5ff98d2668d5L,0x0715281a7ad81965L,0x1bc8fc7c03c6ce11L,\n        0xcbbee6e28b650436L },\n      { 0x06b00fe80cdb9808L,0x17d6e066fe3ed315L,0x2e9d38c64d0b5018L,\n        0xab8bfd56844dcaefL } },\n    /* 45 << 112 */\n    { { 0x42894a59513aed8bL,0xf77f3b6d314bd07aL,0xbbdecb8f8e42b582L,\n        0xf10e2fa8d2390fe6L },\n      { 0xefb9502262a2f201L,0x4d59ea5050ee32b0L,0xd87f77286da789a8L,\n        0xcf98a2cff79492c4L } },\n    /* 46 << 112 */\n    { { 0xf9577239720943c2L,0xba044cf53990b9d0L,0x5aa8e82395f2884aL,\n        0x834de6ed0278a0afL },\n      { 0xc8e1ee9a5f25bd12L,0x9259ceaa6f7ab271L,0x7e6d97a277d00b76L,\n        0x5c0c6eeaa437832aL } },\n    /* 47 << 112 */\n    { { 0x5232c20f5606b81dL,0xabd7b3750d991ee5L,0x4d2bfe358632d951L,\n        0x78f8514698ed9364L },\n      { 0x951873f0f30c3282L,0x0da8ac80a789230bL,0x3ac7789c5398967fL,\n        0xa69b8f7fbdda0fb5L } },\n    /* 48 << 112 */\n    { { 0xe5db77176add8545L,0x1b71cb6672c49b66L,0xd856073968421d77L,\n        0x03840fe883e3afeaL },\n      { 0xb391dad51ec69977L,0xae243fb9307f6726L,0xc88ac87be8ca160cL,\n        0x5174cced4ce355f4L } },\n    /* 49 << 112 */\n    { { 0x98a35966e58ba37dL,0xfdcc8da27817335dL,0x5b75283083fbc7bfL,\n        0x68e419d4d9c96984L },\n      { 0x409a39f402a40380L,0x88940faf1fe977bcL,0xc640a94b8f8edea6L,\n        0x1e22cd17ed11547dL } },\n    /* 50 << 112 */\n    { { 0xe28568ce59ffc3e2L,0x60aa1b55c1dee4e7L,0xc67497c8837cb363L,\n        0x06fb438a105a2bf2L },\n      { 0x30357ec4500d8e20L,0x1ad9095d0670db10L,0x7f589a05c73b7cfdL,\n        0xf544607d880d6d28L } },\n    /* 51 << 112 */\n    { { 0x17ba93b1a20ef103L,0xad8591306ba6577bL,0x65c91cf66fa214a0L,\n        0xd7d49c6c27990da5L },\n      { 0xecd9ec8d20bb569dL,0xbd4b2502eeffbc33L,0x2056ca5a6bed0467L,\n        0x7916a1f75b63728cL } },\n    /* 52 << 112 */\n    { { 0xd4f9497d53a4f566L,0x8973466497b56810L,0xf8e1da740494a621L,\n        0x82546a938d011c68L },\n      { 0x1f3acb19c61ac162L,0x52f8fa9cabad0d3eL,0x15356523b4b7ea43L,\n        0x5a16ad61ae608125L } },\n    /* 53 << 112 */\n    { { 0xb0bcb87f4faed184L,0x5f236b1d5029f45fL,0xd42c76070bc6b1fcL,\n        0xc644324e68aefce3L },\n      { 0x8e191d595c5d8446L,0xc020807713ae1979L,0xadcaee553ba59cc7L,\n        0x20ed6d6ba2cb81baL } },\n    /* 54 << 112 */\n    { { 0x0952ba19b6efcffcL,0x60f12d6897c0b87cL,0x4ee2c7c49caa30bcL,\n        0x767238b797fbff4eL },\n      { 0xebc73921501b5d92L,0x3279e3dfc2a37737L,0x9fc12bc86d197543L,\n        0xfa94dc6f0a40db4eL } },\n    /* 55 << 112 */\n    { { 0x7392b41a530ccbbdL,0x87c82146ea823525L,0xa52f984c05d98d0cL,\n        0x2ae57d735ef6974cL },\n      { 0x9377f7bf3042a6ddL,0xb1a007c019647a64L,0xfaa9079a0cca9767L,\n        0x3d81a25bf68f72d5L } },\n    /* 56 << 112 */\n    { { 0x752067f8ff81578eL,0x786221509045447dL,0xc0c22fcf0505aa6fL,\n        0x1030f0a66bed1c77L },\n      { 0x31f29f151f0bd739L,0x2d7989c7e6debe85L,0x5c070e728e677e98L,\n        0x0a817bd306e81fd5L } },\n    /* 57 << 112 */\n    { { 0xc110d830b0f2ac95L,0x48d0995aab20e64eL,0x0f3e00e17729cd9aL,\n        0x2a570c20dd556946L },\n      { 0x912dbcfd4e86214dL,0x2d014ee2cf615498L,0x55e2b1e63530d76eL,\n        0xc5135ae4fd0fd6d1L } },\n    /* 58 << 112 */\n    { { 0x0066273ad4f3049fL,0xbb8e9893e7087477L,0x2dba1ddb14c6e5fdL,\n        0xdba3788651f57e6cL },\n      { 0x5aaee0a65a72f2cfL,0x1208bfbf7bea5642L,0xf5c6aa3b67872c37L,\n        0xd726e08343f93224L } },\n    /* 59 << 112 */\n    { { 0x1854daa5061f1658L,0xc0016df1df0cd2b3L,0xc2a3f23e833d50deL,\n        0x73b681d2bbbd3017L },\n      { 0x2f046dc43ac343c0L,0x9c847e7d85716421L,0xe1e13c910917eed4L,\n        0x3fc9eebd63a1b9c6L } },\n    /* 60 << 112 */\n    { { 0x0f816a727fe02299L,0x6335ccc2294f3319L,0x3820179f4745c5beL,\n        0xe647b782922f066eL },\n      { 0xc22e49de02cafb8aL,0x299bc2fffcc2ecccL,0x9a8feea26e0e8282L,\n        0xa627278bfe893205L } },\n    /* 61 << 112 */\n    { { 0xa7e197337933e47bL,0xf4ff6b132e766402L,0xa4d8be0a98440d9fL,\n        0x658f5c2f38938808L },\n      { 0x90b75677c95b3b3eL,0xfa0442693137b6ffL,0x077b039b43c47c29L,\n        0xcca95dd38a6445b2L } },\n    /* 62 << 112 */\n    { { 0x0b498ba42333fc4cL,0x274f8e68f736a1b1L,0x6ca348fd5f1d4b2eL,\n        0x24d3be78a8f10199L },\n      { 0x8535f858ca14f530L,0xa6e7f1635b982e51L,0x847c851236e1bf62L,\n        0xf6a7c58e03448418L } },\n    /* 63 << 112 */\n    { { 0x583f3703f9374ab6L,0x864f91956e564145L,0x33bc3f4822526d50L,\n        0x9f323c801262a496L },\n      { 0xaa97a7ae3f046a9aL,0x70da183edf8a039aL,0x5b68f71c52aa0ba6L,\n        0x9be0fe5121459c2dL } },\n    /* 64 << 112 */\n    { { 0xc1e17eb6cbc613e5L,0x33131d55497ea61cL,0x2f69d39eaf7eded5L,\n        0x73c2f434de6af11bL },\n      { 0x4ca52493a4a375faL,0x5f06787cb833c5c2L,0x814e091f3e6e71cfL,\n        0x76451f578b746666L } },\n    /* 0 << 119 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 119 */\n    { { 0x80f9bdef694db7e0L,0xedca8787b9fcddc6L,0x51981c3403b8dce1L,\n        0x4274dcf170e10ba1L },\n      { 0xf72743b86def6d1aL,0xd25b1670ebdb1866L,0xc4491e8c050c6f58L,\n        0x2be2b2ab87fbd7f5L } },\n    /* 2 << 119 */\n    { { 0x3e0e5c9dd111f8ecL,0xbcc33f8db7c4e760L,0x702f9a91bd392a51L,\n        0x7da4a795c132e92dL },\n      { 0x1a0b0ae30bb1151bL,0x54febac802e32251L,0xea3a5082694e9e78L,\n        0xe58ffec1e4fe40b8L } },\n    /* 3 << 119 */\n    { { 0xf85592fcd1e0cf9eL,0xdea75f0dc0e7b2e8L,0xc04215cfc135584eL,\n        0x174fc7272f57092aL },\n      { 0xe7277877eb930beaL,0x504caccb5eb02a5aL,0xf9fe08f7f5241b9bL,\n        0xe7fb62f48d5ca954L } },\n    /* 4 << 119 */\n    { { 0xfbb8349d29c4120bL,0x9f94391fc0d0d915L,0xc4074fa75410ba51L,\n        0xa66adbf6150a5911L },\n      { 0xc164543c34bfca38L,0xe0f27560b9e1ccfcL,0x99da0f53e820219cL,\n        0xe8234498c6b4997aL } },\n    /* 5 << 119 */\n    { { 0xcfb88b769d4c5423L,0x9e56eb10b0521c49L,0x418e0b5ebe8700a1L,\n        0x00cbaad6f93cb58aL },\n      { 0xe923fbded92a5e67L,0xca4979ac1f347f11L,0x89162d856bc0585bL,\n        0xdd6254afac3c70e3L } },\n    /* 6 << 119 */\n    { { 0x7b23c513516e19e4L,0x56e2e847c5c4d593L,0x9f727d735ce71ef6L,\n        0x5b6304a6f79a44c5L },\n      { 0x6638a7363ab7e433L,0x1adea470fe742f83L,0xe054b8545b7fc19fL,\n        0xf935381aba1d0698L } },\n    /* 7 << 119 */\n    { { 0x546eab2d799e9a74L,0x96239e0ea949f729L,0xca274c6b7090055aL,\n        0x835142c39020c9b0L },\n      { 0xa405667aa2e8807fL,0x29f2c0851aa3d39eL,0xcc555d6442fc72f5L,\n        0xe856e0e7fbeacb3cL } },\n    /* 8 << 119 */\n    { { 0xb5504f9d918e4936L,0x65035ef6b2513982L,0x0553a0c26f4d9cb9L,\n        0x6cb10d56bea85509L },\n      { 0x48d957b7a242da11L,0x16a4d3dd672b7268L,0x3d7e637c8502a96bL,\n        0x27c7032b730d463bL } },\n    /* 9 << 119 */\n    { { 0xbdc02b18e4136a14L,0xbacf969d678e32bfL,0xc98d89a3dd9c3c03L,\n        0x7b92420a23becc4fL },\n      { 0xd4b41f78c64d565cL,0x9f969d0010f28295L,0xec7f7f76b13d051aL,\n        0x08945e1ea92da585L } },\n    /* 10 << 119 */\n    { { 0x55366b7d5846426fL,0xe7d09e89247d441dL,0x510b404d736fbf48L,\n        0x7fa003d0e784bd7dL },\n      { 0x25f7614f17fd9596L,0x49e0e0a135cb98dbL,0x2c65957b2e83a76aL,\n        0x5d40da8dcddbe0f8L } },\n    /* 11 << 119 */\n    { { 0xf2b8c405050bad24L,0x8918426dc2aa4823L,0x2aeab3dda38365a7L,\n        0x720317177c91b690L },\n      { 0x8b00d69960a94120L,0x478a255de99eaeecL,0xbf656a5f6f60aafdL,\n        0xdfd7cb755dee77b3L } },\n    /* 12 << 119 */\n    { { 0x37f68bb4a595939dL,0x0355647928740217L,0x8e740e7c84ad7612L,\n        0xd89bc8439044695fL },\n      { 0xf7f3da5d85a9184dL,0x562563bb9fc0b074L,0x06d2e6aaf88a888eL,\n        0x612d8643161fbe7cL } },\n    /* 13 << 119 */\n    { { 0x465edba7f64085e7L,0xb230f30429aa8511L,0x53388426cda2d188L,\n        0x908857354b666649L },\n      { 0x6f02ff9a652f54f6L,0x65c822945fae2bf0L,0x7816ade062f5eee3L,\n        0xdcdbdf43fcc56d70L } },\n    /* 14 << 119 */\n    { { 0x9fb3bba354530bb2L,0xbde3ef77cb0869eaL,0x89bc90460b431163L,\n        0x4d03d7d2e4819a35L },\n      { 0x33ae4f9e43b6a782L,0x216db3079c88a686L,0x91dd88e000ffedd9L,\n        0xb280da9f12bd4840L } },\n    /* 15 << 119 */\n    { { 0x32a7cb8a1635e741L,0xfe14008a78be02a7L,0x3fafb3341b7ae030L,\n        0x7fd508e75add0ce9L },\n      { 0x72c83219d607ad51L,0x0f229c0a8d40964aL,0x1be2c3361c878da2L,\n        0xe0c96742eab2ab86L } },\n    /* 16 << 119 */\n    { { 0x458f86913e538cd7L,0xa7001f6c8e08ad53L,0x52b8c6e6bf5d15ffL,\n        0x548234a4011215ddL },\n      { 0xff5a9d2d3d5b4045L,0xb0ffeeb64a904190L,0x55a3aca448607f8bL,\n        0x8cbd665c30a0672aL } },\n    /* 17 << 119 */\n    { { 0x87f834e042583068L,0x02da2aebf3f6e683L,0x6b763e5d05c12248L,\n        0x7230378f65a8aefcL },\n      { 0x93bd80b571e8e5caL,0x53ab041cb3b62524L,0x1b8605136c9c552eL,\n        0xe84d402cd5524e66L } },\n    /* 18 << 119 */\n    { { 0xa37f3573f37f5937L,0xeb0f6c7dd1e4fca5L,0x2965a554ac8ab0fcL,\n        0x17fbf56c274676acL },\n      { 0x2e2f6bd9acf7d720L,0x41fc8f8810224766L,0x517a14b385d53befL,\n        0xdae327a57d76a7d1L } },\n    /* 19 << 119 */\n    { { 0x6ad0a065c4818267L,0x33aa189b37c1bbc1L,0x64970b5227392a92L,\n        0x21699a1c2d1535eaL },\n      { 0xcd20779cc2d7a7fdL,0xe318605999c83cf2L,0x9b69440b72c0b8c7L,\n        0xa81497d77b9e0e4dL } },\n    /* 20 << 119 */\n    { { 0x515d5c891f5f82dcL,0x9a7f67d76361079eL,0xa8da81e311a35330L,\n        0xe44990c44b18be1bL },\n      { 0xc7d5ed95af103e59L,0xece8aba78dac9261L,0xbe82b0999394b8d3L,\n        0x6830f09a16adfe83L } },\n    /* 21 << 119 */\n    { { 0x250a29b488172d01L,0x8b20bd65caff9e02L,0xb8a7661ee8a6329aL,\n        0x4520304dd3fce920L },\n      { 0xae45da1f2b47f7efL,0xe07f52885bffc540L,0xf79970093464f874L,\n        0x2244c2cda6fa1f38L } },\n    /* 22 << 119 */\n    { { 0x43c41ac194d7d9b1L,0x5bafdd82c82e7f17L,0xdf0614c15fda0fcaL,\n        0x74b043a7a8ae37adL },\n      { 0x3ba6afa19e71734cL,0x15d5437e9c450f2eL,0x4a5883fe67e242b1L,\n        0x5143bdc22c1953c2L } },\n    /* 23 << 119 */\n    { { 0x542b8b53fc5e8920L,0x363bf9a89a9cee08L,0x02375f10c3486e08L,\n        0x2037543b8c5e70d2L },\n      { 0x7109bccc625640b4L,0xcbc1051e8bc62c3bL,0xf8455fed803f26eaL,\n        0x6badceabeb372424L } },\n    /* 24 << 119 */\n    { { 0xa2a9ce7c6b53f5f9L,0x642465951b176d99L,0xb1298d36b95c081bL,\n        0x53505bb81d9a9ee6L },\n      { 0x3f6f9e61f2ba70b0L,0xd07e16c98afad453L,0x9f1694bbe7eb4a6aL,\n        0xdfebced93cb0bc8eL } },\n    /* 25 << 119 */\n    { { 0x92d3dcdc53868c8bL,0x174311a2386107a6L,0x4109e07c689b4e64L,\n        0x30e4587f2df3dcb6L },\n      { 0x841aea310811b3b2L,0x6144d41d0cce43eaL,0x464c45812a9a7803L,\n        0xd03d371f3e158930L } },\n    /* 26 << 119 */\n    { { 0xc676d7f2b1f3390bL,0x9f7a1b8ca5b61272L,0x4ebebfc9c2e127a9L,\n        0x4602500c5dd997bfL },\n      { 0x7f09771c4711230fL,0x058eb37c020f09c1L,0xab693d4bfee5e38bL,\n        0x9289eb1f4653cbc0L } },\n    /* 27 << 119 */\n    { { 0xbecf46abd51b9cf5L,0xd2aa9c029f0121afL,0x36aaf7d2e90dc274L,\n        0x909e4ea048b95a3cL },\n      { 0xe6b704966f32dbdbL,0x672188a08b030b3eL,0xeeffe5b3cfb617e2L,\n        0x87e947de7c82709eL } },\n    /* 28 << 119 */\n    { { 0xa44d2b391770f5a7L,0xe4d4d7910e44eb82L,0x42e69d1e3f69712aL,\n        0xbf11c4d6ac6a820eL },\n      { 0xb5e7f3e542c4224cL,0xd6b4e81c449d941cL,0x5d72bd165450e878L,\n        0x6a61e28aee25ac54L } },\n    /* 29 << 119 */\n    { { 0x33272094e6f1cd95L,0x7512f30d0d18673fL,0x32f7a4ca5afc1464L,\n        0x2f0956566bbb977bL },\n      { 0x586f47caa8226200L,0x02c868ad1ac07369L,0x4ef2b845c613acbeL,\n        0x43d7563e0386054cL } },\n    /* 30 << 119 */\n    { { 0x54da9dc7ab952578L,0xb5423df226e84d0bL,0xa8b64eeb9b872042L,\n        0xac2057825990f6dfL },\n      { 0x4ff696eb21f4c77aL,0x1a79c3e4aab273afL,0x29bc922e9436b3f1L,\n        0xff807ef8d6d9a27aL } },\n    /* 31 << 119 */\n    { { 0x82acea3d778f22a0L,0xfb10b2e85b5e7469L,0xc0b169802818ee7dL,\n        0x011afff4c91c1a2fL },\n      { 0x95a6d126ad124418L,0x31c081a5e72e295fL,0x36bb283af2f4db75L,\n        0xd115540f7acef462L } },\n    /* 32 << 119 */\n    { { 0xc7f3a8f833f6746cL,0x21e46f65fea990caL,0x915fd5c5caddb0a9L,\n        0xbd41f01678614555L },\n      { 0x346f4434426ffb58L,0x8055943614dbc204L,0xf3dd20fe5a969b7fL,\n        0x9d59e956e899a39aL } },\n    /* 33 << 119 */\n    { { 0xf1b0971c8ad4cf4bL,0x034488602ffb8fb8L,0xf071ac3c65340ba4L,\n        0x408d0596b27fd758L },\n      { 0xe7c78ea498c364b0L,0xa4aac4a5051e8ab5L,0xb9e1d560485d9002L,\n        0x9acd518a88844455L } },\n    /* 34 << 119 */\n    { { 0xe4ca688fd06f56c0L,0xa48af70ddf027972L,0x691f0f045e9a609dL,\n        0xa9dd82cdee61270eL },\n      { 0x8903ca63a0ef18d3L,0x9fb7ee353d6ca3bdL,0xa7b4a09cabf47d03L,\n        0x4cdada011c67de8eL } },\n    /* 35 << 119 */\n    { { 0x520037499355a244L,0xe77fd2b64f2151a9L,0x695d6cf666b4efcbL,\n        0xc5a0cacfda2cfe25L },\n      { 0x104efe5cef811865L,0xf52813e89ea5cc3dL,0x855683dc40b58dbcL,\n        0x0338ecde175fcb11L } },\n    /* 36 << 119 */\n    { { 0xf9a0563774921592L,0xb4f1261db9bb9d31L,0x551429b74e9c5459L,\n        0xbe182e6f6ea71f53L },\n      { 0xd3a3b07cdfc50573L,0x9ba1afda62be8d44L,0x9bcfd2cb52ab65d3L,\n        0xdf11d547a9571802L } },\n    /* 37 << 119 */\n    { { 0x099403ee02a2404aL,0x497406f421088a71L,0x994794095004ae71L,\n        0xbdb42078a812c362L },\n      { 0x2b72a30fd8828442L,0x283add27fcb5ed1cL,0xf7c0e20066a40015L,\n        0x3e3be64108b295efL } },\n    /* 38 << 119 */\n    { { 0xac127dc1e038a675L,0x729deff38c5c6320L,0xb7df8fd4a90d2c53L,\n        0x9b74b0ec681e7cd3L },\n      { 0x5cb5a623dab407e5L,0xcdbd361576b340c6L,0xa184415a7d28392cL,\n        0xc184c1d8e96f7830L } },\n    /* 39 << 119 */\n    { { 0xc3204f1981d3a80fL,0xfde0c841c8e02432L,0x78203b3e8149e0c1L,\n        0x5904bdbb08053a73L },\n      { 0x30fc1dd1101b6805L,0x43c223bc49aa6d49L,0x9ed671417a174087L,\n        0x311469a0d5997008L } },\n    /* 40 << 119 */\n    { { 0xb189b6845e43fc61L,0xf3282375e0d3ab57L,0x4fa34b67b1181da8L,\n        0x621ed0b299ee52b8L },\n      { 0x9b178de1ad990676L,0xd51de67b56d54065L,0x2a2c27c47538c201L,\n        0x33856ec838a40f5cL } },\n    /* 41 << 119 */\n    { { 0x2522fc15be6cdcdeL,0x1e603f339f0c6f89L,0x7994edc3103e30a6L,\n        0x033a00db220c853eL },\n      { 0xd3cfa409f7bb7fd7L,0x70f8781e462d18f6L,0xbbd82980687fe295L,\n        0x6eef4c32595669f3L } },\n    /* 42 << 119 */\n    { { 0x86a9303b2f7e85c3L,0x5fce462171988f9bL,0x5b935bf6c138acb5L,\n        0x30ea7d6725661212L },\n      { 0xef1eb5f4e51ab9a2L,0x0587c98aae067c78L,0xb3ce1b3c77ca9ca6L,\n        0x2a553d4d54b5f057L } },\n    /* 43 << 119 */\n    { { 0xc78982364da29ec2L,0xdbdd5d13b9c57316L,0xc57d6e6b2cd80d47L,\n        0x80b460cffe9e7391L },\n      { 0x98648cabf963c31eL,0x67f9f633cc4d32fdL,0x0af42a9dfdf7c687L,\n        0x55f292a30b015ea7L } },\n    /* 44 << 119 */\n    { { 0x89e468b2cd21ab3dL,0xe504f022c393d392L,0xab21e1d4a5013af9L,\n        0xe3283f78c2c28acbL },\n      { 0xf38b35f6226bf99fL,0xe83542740e291e69L,0x61673a15b20c162dL,\n        0xc101dc75b04fbdbeL } },\n    /* 45 << 119 */\n    { { 0x8323b4c2255bd617L,0x6c9696936c2a9154L,0xc6e6586062679387L,\n        0x8e01db0cb8c88e23L },\n      { 0x33c42873893a5559L,0x7630f04b47a3e149L,0xb5d80805ddcf35f8L,\n        0x582ca08077dfe732L } },\n    /* 46 << 119 */\n    { { 0x2c7156e10b1894a0L,0x92034001d81c68c0L,0xed225d00c8b115b5L,\n        0x237f9c2283b907f2L },\n      { 0x0ea2f32f4470e2c0L,0xb725f7c158be4e95L,0x0f1dcafab1ae5463L,\n        0x59ed51871ba2fc04L } },\n    /* 47 << 119 */\n    { { 0xf6e0f316d0115d4dL,0x5180b12fd3691599L,0x157e32c9527f0a41L,\n        0x7b0b081da8e0ecc0L },\n      { 0x6dbaaa8abf4f0dd0L,0x99b289c74d252696L,0x79b7755edbf864feL,\n        0x6974e2b176cad3abL } },\n    /* 48 << 119 */\n    { { 0x35dbbee206ddd657L,0xe7cbdd112ff3a96dL,0x88381968076be758L,\n        0x2d737e7208c91f5dL },\n      { 0x5f83ab6286ec3776L,0x98aa649d945fa7a1L,0xf477ec3772ef0933L,\n        0x66f52b1e098c17b1L } },\n    /* 49 << 119 */\n    { { 0x9eec58fbd803738bL,0x91aaade7e4e86aa4L,0x6b1ae617a5b51492L,\n        0x63272121bbc45974L },\n      { 0x7e0e28f0862c5129L,0x0a8f79a93321a4a0L,0xe26d16645041c88fL,\n        0x0571b80553233e3aL } },\n    /* 50 << 119 */\n    { { 0xd1b0ccdec9520711L,0x55a9e4ed3c8b84bfL,0x9426bd39a1fef314L,\n        0x4f5f638e6eb93f2bL },\n      { 0xba2a1ed32bf9341bL,0xd63c13214d42d5a9L,0xd2964a89316dc7c5L,\n        0xd1759606ca511851L } },\n    /* 51 << 119 */\n    { { 0xd8a9201ff9e6ed35L,0xb7b5ee456736925aL,0x0a83fbbc99581af7L,\n        0x3076bc4064eeb051L },\n      { 0x5511c98c02dec312L,0x270de898238dcb78L,0x2cf4cf9c539c08c9L,\n        0xa70cb65e38d3b06eL } },\n    /* 52 << 119 */\n    { { 0xb12ec10ecfe57bbdL,0x82c7b65635a0c2b5L,0xddc7d5cd161c67bdL,\n        0xe32e8985ae3a32ccL },\n      { 0x7aba9444d11a5529L,0xe964ed022427fa1aL,0x1528392d24a1770aL,\n        0xa152ce2c12c72fcdL } },\n    /* 53 << 119 */\n    { { 0x714553a48ec07649L,0x18b4c290459dd453L,0xea32b7147b64b110L,\n        0xb871bfa52e6f07a2L },\n      { 0xb67112e59e2e3c9bL,0xfbf250e544aa90f6L,0xf77aedb8bd539006L,\n        0x3b0cdf9ad172a66fL } },\n    /* 54 << 119 */\n    { { 0xedf69feaf8c51187L,0x05bb67ec741e4da7L,0x47df0f3208114345L,\n        0x56facb07bb9792b1L },\n      { 0xf3e007e98f6229e4L,0x62d103f4526fba0fL,0x4f33bef7b0339d79L,\n        0x9841357bb59bfec1L } },\n    /* 55 << 119 */\n    { { 0xfa8dbb59c34e6705L,0xc3c7180b7fdaa84cL,0xf95872fca4108537L,\n        0x8750cc3b932a3e5aL },\n      { 0xb61cc69db7275d7dL,0xffa0168b2e59b2e9L,0xca032abc6ecbb493L,\n        0x1d86dbd32c9082d8L } },\n    /* 56 << 119 */\n    { { 0xae1e0b67e28ef5baL,0x2c9a4699cb18e169L,0x0ecd0e331e6bbd20L,\n        0x571b360eaf5e81d2L },\n      { 0xcd9fea58101c1d45L,0x6651788e18880452L,0xa99726351f8dd446L,\n        0x44bed022e37281d0L } },\n    /* 57 << 119 */\n    { { 0x094b2b2d33da525dL,0xf193678e13144fd8L,0xb8ab5ba4f4c1061dL,\n        0x4343b5fadccbe0f4L },\n      { 0xa870237163812713L,0x47bf6d2df7611d93L,0x46729b8cbd21e1d7L,\n        0x7484d4e0d629e77dL } },\n    /* 58 << 119 */\n    { { 0x830e6eea60dbac1fL,0x23d8c484da06a2f7L,0x896714b050ca535bL,\n        0xdc8d3644ebd97a9bL },\n      { 0x106ef9fab12177b4L,0xf79bf464534d5d9cL,0x2537a349a6ab360bL,\n        0xc7c54253a00c744fL } },\n    /* 59 << 119 */\n    { { 0xb3c7a047e5911a76L,0x61ffa5c8647f1ee7L,0x15aed36f8f56ab42L,\n        0x6a0d41b0a3ff9ac9L },\n      { 0x68f469f5cc30d357L,0xbe9adf816b72be96L,0x1cd926fe903ad461L,\n        0x7e89e38fcaca441bL } },\n    /* 60 << 119 */\n    { { 0xf0f82de5facf69d4L,0x363b7e764775344cL,0x6894f312b2e36d04L,\n        0x3c6cb4fe11d1c9a5L },\n      { 0x85d9c3394008e1f2L,0x5e9a85ea249f326cL,0xdc35c60a678c5e06L,\n        0xc08b944f9f86fba9L } },\n    /* 61 << 119 */\n    { { 0xde40c02c89f71f0fL,0xad8f3e31ff3da3c0L,0x3ea5096b42125dedL,\n        0x13879cbfa7379183L },\n      { 0x6f4714a56b306a0bL,0x359c2ea667646c5eL,0xfacf894307726368L,\n        0x07a5893565ff431eL } },\n    /* 62 << 119 */\n    { { 0x24d661d168754ab0L,0x801fce1d6f429a76L,0xc068a85fa58ce769L,\n        0xedc35c545d5eca2bL },\n      { 0xea31276fa3f660d1L,0xa0184ebeb8fc7167L,0x0f20f21a1d8db0aeL,\n        0xd96d095f56c35e12L } },\n    /* 63 << 119 */\n    { { 0xedf402b5f8c2a25bL,0x1bb772b9059204b6L,0x50cbeae219b4e34cL,\n        0x93109d803fa0845aL },\n      { 0x54f7ccf78ef59fb5L,0x3b438fe288070963L,0x9e28c65931f3ba9bL,\n        0x9cc31b46ead9da92L } },\n    /* 64 << 119 */\n    { { 0x3c2f0ba9b733aa5fL,0xdece47cbf05af235L,0xf8e3f715a2ac82a5L,\n        0xc97ba6412203f18aL },\n      { 0xc3af550409c11060L,0x56ea2c0546af512dL,0xfac28daff3f28146L,\n        0x87fab43a959ef494L } },\n    /* 0 << 126 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 126 */\n    { { 0x09891641d4c5105fL,0x1ae80f8e6d7fbd65L,0x9d67225fbee6bdb0L,\n        0x3b433b597fc4d860L },\n      { 0x44e66db693e85638L,0xf7b59252e3e9862fL,0xdb785157665c32ecL,\n        0x702fefd7ae362f50L } },\n    /* 2 << 126 */\n    { { 0x3754475d0fefb0c3L,0xd48fb56b46d7c35dL,0xa070b633363798a4L,\n        0xae89f3d28fdb98e6L },\n      { 0x970b89c86363d14cL,0x8981752167abd27dL,0x9bf7d47444d5a021L,\n        0xb3083bafcac72aeeL } },\n    /* 3 << 126 */\n    { { 0x389741debe949a44L,0x638e9388546a4fa5L,0x3fe6419ca0047bdcL,\n        0x7047f648aaea57caL },\n      { 0x54e48a9041fbab17L,0xda8e0b28576bdba2L,0xe807eebcc72afddcL,\n        0x07d3336df42577bfL } },\n    /* 4 << 126 */\n    { { 0x62a8c244bfe20925L,0x91c19ac38fdce867L,0x5a96a5d5dd387063L,\n        0x61d587d421d324f6L },\n      { 0xe87673a2a37173eaL,0x2384800853778b65L,0x10f8441e05bab43eL,\n        0xfa11fe124621efbeL } },\n    /* 5 << 126 */\n    { { 0x047b772e81685d7bL,0x23f27d81bf34a976L,0xc27608e2915f48efL,\n        0x3b0b43faa521d5c3L },\n      { 0x7613fb2663ca7284L,0x7f5729b41d4db837L,0x87b14898583b526bL,\n        0x00b732a6bbadd3d1L } },\n    /* 6 << 126 */\n    { { 0x8e02f4262048e396L,0x436b50b6383d9de4L,0xf78d3481471e85adL,\n        0x8b01ea6ad005c8d6L },\n      { 0xd3c7afee97015c07L,0x46cdf1a94e3ba2aeL,0x7a42e50183d3a1d2L,\n        0xd54b5268b541dff4L } },\n    /* 7 << 126 */\n    { { 0x3f24cf304e23e9bcL,0x4387f816126e3624L,0x26a46a033b0b6d61L,\n        0xaf1bc8458b2d777cL },\n      { 0x25c401ba527de79cL,0x0e1346d44261bbb6L,0x4b96c44b287b4bc7L,\n        0x658493c75254562fL } },\n    /* 8 << 126 */\n    { { 0x23f949feb8a24a20L,0x17ebfed1f52ca53fL,0x9b691bbebcfb4853L,\n        0x5617ff6b6278a05dL },\n      { 0x241b34c5e3c99ebdL,0xfc64242e1784156aL,0x4206482f695d67dfL,\n        0xb967ce0eee27c011L } },\n    /* 9 << 126 */\n    { { 0x65db375121c80b5dL,0x2e7a563ca31ecca0L,0xe56ffc4e5238a07eL,\n        0x3d6c296632ced854L },\n      { 0xe99d7d1aaf70b885L,0xafc3bad92d686459L,0x9c78bf460cc8ba5bL,\n        0x5a43951918955aa3L } },\n    /* 10 << 126 */\n    { { 0xf8b517a85fe4e314L,0xe60234d0fcb8906fL,0xffe542acf2061b23L,\n        0x287e191f6b4cb59cL },\n      { 0x21857ddc09d877d8L,0x1c23478c14678941L,0xbbf0c056b6e05ea4L,\n        0x82da4b53b01594feL } },\n    /* 11 << 126 */\n    { { 0xf7526791fadb8608L,0x049e832d7b74cdf6L,0xa43581ccc2b90a34L,\n        0x73639eb89360b10cL },\n      { 0x4fba331fe1e4a71bL,0x6ffd6b938072f919L,0x6e53271c65679032L,\n        0x67206444f14272ceL } },\n    /* 12 << 126 */\n    { { 0xc0f734a3b2335834L,0x9526205a90ef6860L,0xcb8be71704e2bb0dL,\n        0x2418871e02f383faL },\n      { 0xd71776814082c157L,0xcc914ad029c20073L,0xf186c1ebe587e728L,\n        0x6fdb3c2261bcd5fdL } },\n    /* 13 << 126 */\n    { { 0x30d014a6f2f9f8e9L,0x963ece234fec49d2L,0x862025c59605a8d9L,\n        0x3987444519f8929aL },\n      { 0x01b6ff6512bf476aL,0x598a64d809cf7d91L,0xd7ec774993be56caL,\n        0x10899785cbb33615L } },\n    /* 14 << 126 */\n    { { 0xb8a092fd02eee3adL,0xa86b3d3530145270L,0x323d98c68512b675L,\n        0x4b8bc78562ebb40fL },\n      { 0x7d301f54413f9cdeL,0xa5e4fb4f2bab5664L,0x1d2b252d1cbfec23L,\n        0xfcd576bbe177120dL } },\n    /* 15 << 126 */\n    { { 0x04427d3e83731a34L,0x2bb9028eed836e8eL,0xb36acff8b612ca7cL,\n        0xb88fe5efd3d9c73aL },\n      { 0xbe2a6bc6edea4eb3L,0x43b93133488eec77L,0xf41ff566b17106e1L,\n        0x469e9172654efa32L } },\n    /* 16 << 126 */\n    { { 0xb4480f0441c23fa3L,0xb4712eb0c1989a2eL,0x3ccbba0f93a29ca7L,\n        0x6e205c14d619428cL },\n      { 0x90db7957b3641686L,0x0432691d45ac8b4eL,0x07a759acf64e0350L,\n        0x0514d89c9c972517L } },\n    /* 17 << 126 */\n    { { 0x1701147fa8e67fc3L,0x9e2e0b8bab2085beL,0xd5651824ac284e57L,\n        0x890d432574893664L },\n      { 0x8a7c5e6ec55e68a3L,0xbf12e90b4339c85aL,0x31846b85f922b655L,\n        0x9a54ce4d0bf4d700L } },\n    /* 18 << 126 */\n    { { 0xd7f4e83af1a14295L,0x916f955cb285d4f9L,0xe57bb0e099ffdabaL,\n        0x28a43034eab0d152L },\n      { 0x0a36ffa2b8a9cef8L,0x5517407eb9ec051aL,0x9c796096ea68e672L,\n        0x853db5fbfb3c77fbL } },\n    /* 19 << 126 */\n    { { 0x21474ba9e864a51aL,0x6c2676996e8a1b8bL,0x7c82362694120a28L,\n        0xe61e9a488383a5dbL },\n      { 0x7dd750039f84216dL,0xab020d07ad43cd85L,0x9437ae48da12c659L,\n        0x6449c2ebe65452adL } },\n    /* 20 << 126 */\n    { { 0xcc7c4c1c2cf9d7c1L,0x1320886aee95e5abL,0xbb7b9056beae170cL,\n        0xc8a5b250dbc0d662L },\n      { 0x4ed81432c11d2303L,0x7da669121f03769fL,0x3ac7a5fd84539828L,\n        0x14dada943bccdd02L } },\n    /* 21 << 126 */\n    { { 0x8b84c3217ef6b0d1L,0x52a9477a7c933f22L,0x5ef6728afd440b82L,\n        0x5c3bd8596ce4bd5eL },\n      { 0x918b80f5f22c2d3eL,0x368d5040b7bb6cc5L,0xb66142a12695a11cL,\n        0x60ac583aeb19ea70L } },\n    /* 22 << 126 */\n    { { 0x317cbb980eab2437L,0x8cc08c555e2654c8L,0xfe2d6520e6d8307fL,\n        0xe9f147f357428993L },\n      { 0x5f9c7d14d2fd6cf1L,0xa3ecd0642d4fcbb0L,0xad83fef08e7341f7L,\n        0x643f23a03a63115cL } },\n    /* 23 << 126 */\n    { { 0xd38a78abe65ab743L,0xbf7c75b135edc89cL,0x3dd8752e530df568L,\n        0xf85c4a76e308c682L },\n      { 0x4c9955b2e68acf37L,0xa544df3dab32af85L,0x4b8ec3f5a25cf493L,\n        0x4d8f27641a622febL } },\n    /* 24 << 126 */\n    { { 0x7bb4f7aaf0dcbc49L,0x7de551f970bbb45bL,0xcfd0f3e49f2ca2e5L,\n        0xece587091f5c76efL },\n      { 0x32920edd167d79aeL,0x039df8a2fa7d7ec1L,0xf46206c0bb30af91L,\n        0x1ff5e2f522676b59L } },\n    /* 25 << 126 */\n    { { 0x11f4a0396ea51d66L,0x506c1445807d7a26L,0x60da5705755a9b24L,\n        0x8fc8cc321f1a319eL },\n      { 0x83642d4d9433d67dL,0x7fa5cb8f6a7dd296L,0x576591db9b7bde07L,\n        0x13173d25419716fbL } },\n    /* 26 << 126 */\n    { { 0xea30599dd5b340ffL,0xfc6b5297b0fe76c5L,0x1c6968c8ab8f5adcL,\n        0xf723c7f5901c928dL },\n      { 0x4203c3219773d402L,0xdf7c6aa31b51dd47L,0x3d49e37a552be23cL,\n        0x57febee80b5a6e87L } },\n    /* 27 << 126 */\n    { { 0xc5ecbee47bd8e739L,0x79d44994ae63bf75L,0x168bd00f38fb8923L,\n        0x75d48ee4d0533130L },\n      { 0x554f77aadb5cdf33L,0x3396e8963c696769L,0x2fdddbf2d3fd674eL,\n        0xbbb8f6ee99d0e3e5L } },\n    /* 28 << 126 */\n    { { 0x51b90651cbae2f70L,0xefc4bc0593aaa8ebL,0x8ecd8689dd1df499L,\n        0x1aee99a822f367a5L },\n      { 0x95d485b9ae8274c5L,0x6c14d4457d30b39cL,0xbafea90bbcc1ef81L,\n        0x7c5f317aa459a2edL } },\n    /* 29 << 126 */\n    { { 0x012110754ef44227L,0xa17bed6edc20f496L,0x0cdfe424819853cdL,\n        0x13793298f71e2ce7L },\n      { 0x3c1f3078dbbe307bL,0x6dd1c20e76ee9936L,0x23ee4b57423caa20L,\n        0x4ac3793b8efb840eL } },\n    /* 30 << 126 */\n    { { 0x934438ebed1f8ca0L,0x3e5466584ebb25a2L,0xc415af0ec069896fL,\n        0xc13eddb09a5aa43dL },\n      { 0x7a04204fd49eb8f6L,0xd0d5bdfcd74f1670L,0x3697e28656fc0558L,\n        0x1020737101cebadeL } },\n    /* 31 << 126 */\n    { { 0x5f87e6900647a82bL,0x908e0ed48f40054fL,0xa9f633d479853803L,\n        0x8ed13c9a4a28b252L },\n      { 0x3e2ef6761f460f64L,0x53930b9b36d06336L,0x347073ac8fc4979bL,\n        0x84380e0e5ecd5597L } },\n    /* 32 << 126 */\n    { { 0xe3b22c6bc4fe3c39L,0xba4a81536c7bebdfL,0xf23ab6b725693459L,\n        0x53bc377014922b11L },\n      { 0x4645c8ab5afc60dbL,0xaa02235520b9f2a3L,0x52a2954cce0fc507L,\n        0x8c2731bb7ce1c2e7L } },\n    /* 33 << 126 */\n    { { 0xf39608ab18a0339dL,0xac7a658d3735436cL,0xb22c2b07cd992b4fL,\n        0x4e83daecf40dcfd4L },\n      { 0x8a34c7be2f39ea3eL,0xef0c005fb0a56d2eL,0x62731f6a6edd8038L,\n        0x5721d7404e3cb075L } },\n    /* 34 << 126 */\n    { { 0x1ea41511fbeeee1bL,0xd1ef5e73ef1d0c05L,0x42feefd173c07d35L,\n        0xe530a00a8a329493L },\n      { 0x5d55b7fef15ebfb0L,0x549de03cd322491aL,0xf7b5f602745b3237L,\n        0x3632a3a21ab6e2b6L } },\n    /* 35 << 126 */\n    { { 0x0d3bba890ef59f78L,0x0dfc6443c9e52b9aL,0x1dc7969972631447L,\n        0xef033917b3be20b1L },\n      { 0x0c92735db1383948L,0xc1fc29a2c0dd7d7dL,0x6485b697403ed068L,\n        0x13bfaab3aac93bdcL } },\n    /* 36 << 126 */\n    { { 0x410dc6a90deeaf52L,0xb003fb024c641c15L,0x1384978c5bc504c4L,\n        0x37640487864a6a77L },\n      { 0x05991bc6222a77daL,0x62260a575e47eb11L,0xc7af6613f21b432cL,\n        0x22f3acc9ab4953e9L } },\n    /* 37 << 126 */\n    { { 0x529349228e41d155L,0x4d0245683ac059efL,0xb02017554d884411L,\n        0xce8055cfa59a178fL },\n      { 0xcd77d1aff6204549L,0xa0a00a3ec7066759L,0x471071ef0272c229L,\n        0x009bcf6bd3c4b6b0L } },\n    /* 38 << 126 */\n    { { 0x2a2638a822305177L,0xd51d59df41645bbfL,0xa81142fdc0a7a3c0L,\n        0xa17eca6d4c7063eeL },\n      { 0x0bb887ed60d9dcecL,0xd6d28e5120ad2455L,0xebed6308a67102baL,\n        0x042c31148bffa408L } },\n    /* 39 << 126 */\n    { { 0xfd099ac58aa68e30L,0x7a6a3d7c1483513eL,0xffcc6b75ba2d8f0cL,\n        0x54dacf961e78b954L },\n      { 0xf645696fa4a9af89L,0x3a41194006ac98ecL,0x41b8b3f622a67a20L,\n        0x2d0b1e0f99dec626L } },\n    /* 40 << 126 */\n    { { 0x27c8919240be34e8L,0xc7162b3791907f35L,0x90188ec1a956702bL,\n        0xca132f7ddf93769cL },\n      { 0x3ece44f90e2025b4L,0x67aaec690c62f14cL,0xad74141822e3cc11L,\n        0xcf9b75c37ff9a50eL } },\n    /* 41 << 126 */\n    { { 0x02fa2b164d348272L,0xbd99d61a9959d56dL,0xbc4f19db18762916L,\n        0xcc7cce5049c1ac80L },\n      { 0x4d59ebaad846bd83L,0x8775a9dca9202849L,0x07ec4ae16e1f4ca9L,\n        0x27eb5875ba893f11L } },\n    /* 42 << 126 */\n    { { 0x00284d51662cc565L,0x82353a6b0db4138dL,0xd9c7aaaaaa32a594L,\n        0xf5528b5ea5669c47L },\n      { 0xf32202312f23c5ffL,0xe3e8147a6affa3a1L,0xfb423d5c202ddda0L,\n        0x3d6414ac6b871bd4L } },\n    /* 43 << 126 */\n    { { 0x586f82e1a51a168aL,0xb712c67148ae5448L,0x9a2e4bd176233eb8L,\n        0x0188223a78811ca9L },\n      { 0x553c5e21f7c18de1L,0x7682e451b27bb286L,0x3ed036b30e51e929L,\n        0xf487211bec9cb34fL } },\n    /* 44 << 126 */\n    { { 0x0d0942770c24efc8L,0x0349fd04bef737a4L,0x6d1c9dd2514cdd28L,\n        0x29c135ff30da9521L },\n      { 0xea6e4508f78b0b6fL,0x176f5dd2678c143cL,0x081484184be21e65L,\n        0x27f7525ce7df38c4L } },\n    /* 45 << 126 */\n    { { 0x1fb70e09748ab1a4L,0x9cba50a05efe4433L,0x7846c7a615f75af2L,\n        0x2a7c2c575ee73ea8L },\n      { 0x42e566a43f0a449aL,0x45474c3bad90fc3dL,0x7447be3d8b61d057L,\n        0x3e9d1cf13a4ec092L } },\n    /* 46 << 126 */\n    { { 0x1603e453f380a6e6L,0x0b86e4319b1437c2L,0x7a4173f2ef29610aL,\n        0x8fa729a7f03d57f7L },\n      { 0x3e186f6e6c9c217eL,0xbe1d307991919524L,0x92a62a70153d4fb1L,\n        0x32ed3e34d68c2f71L } },\n    /* 47 << 126 */\n    { { 0xd785027f9eb1a8b7L,0xbc37eb77c5b22fe8L,0x466b34f0b9d6a191L,\n        0x008a89af9a05f816L },\n      { 0x19b028fb7d42c10aL,0x7fe8c92f49b3f6b8L,0x58907cc0a5a0ade3L,\n        0xb3154f51559d1a7cL } },\n    /* 48 << 126 */\n    { { 0x5066efb6d9790ed6L,0xa77a0cbca6aa793bL,0x1a915f3c223e042eL,\n        0x1c5def0469c5874bL },\n      { 0x0e83007873b6c1daL,0x55cf85d2fcd8557aL,0x0f7c7c760460f3b1L,\n        0x87052acb46e58063L } },\n    /* 49 << 126 */\n    { { 0x09212b80907eae66L,0x3cb068e04d721c89L,0xa87941aedd45ac1cL,\n        0xde8d5c0d0daa0dbbL },\n      { 0xda421fdce3502e6eL,0xc89442014d89a084L,0x7307ba5ef0c24bfbL,\n        0xda212beb20bde0efL } },\n    /* 50 << 126 */\n    { { 0xea2da24bf82ce682L,0x058d381607f71fe4L,0x35a024625ffad8deL,\n        0xcd7b05dcaadcefabL },\n      { 0xd442f8ed1d9f54ecL,0x8be3d618b2d3b5caL,0xe2220ed0e06b2ce2L,\n        0x82699a5f1b0da4c0L } },\n    /* 51 << 126 */\n    { { 0x3ff106f571c0c3a7L,0x8f580f5a0d34180cL,0x4ebb120e22d7d375L,\n        0x5e5782cce9513675L },\n      { 0x2275580c99c82a70L,0xe8359fbf15ea8c4cL,0x53b48db87b415e70L,\n        0xaacf2240100c6014L } },\n    /* 52 << 126 */\n    { { 0x9faaccf5e4652f1dL,0xbd6fdd2ad56157b2L,0xa4f4fb1f6261ec50L,\n        0x244e55ad476bcd52L },\n      { 0x881c9305047d320bL,0x1ca983d56181263fL,0x354e9a44278fb8eeL,\n        0xad2dbc0f396e4964L } },\n    /* 53 << 126 */\n    { { 0x723f3aa29268b3deL,0x0d1ca29ae6e0609aL,0x794866aa6cf44252L,\n        0x0b59f3e301af87edL },\n      { 0xe234e5ff7f4a6c51L,0xa8768fd261dc2f7eL,0xdafc73320a94d81fL,\n        0xd7f8428206938ce1L } },\n    /* 54 << 126 */\n    { { 0xae0b3c0e0546063eL,0x7fbadcb25d61abc6L,0xd5d7a2c9369ac400L,\n        0xa5978d09ae67d10cL },\n      { 0x290f211e4f85eaacL,0xe61e2ad1facac681L,0xae125225388384cdL,\n        0xa7fb68e9ccfde30fL } },\n    /* 55 << 126 */\n    { { 0x7a59b9363daed4c2L,0x80a9aa402606f789L,0xb40c1ea5f6a6d90aL,\n        0x948364d3514d5885L },\n      { 0x062ebc6070985182L,0xa6db5b0e33310895L,0x64a12175e329c2f5L,\n        0xc5f25bd290ea237eL } },\n    /* 56 << 126 */\n    { { 0x7915c5242d0a4c23L,0xeb5d26e46bb3cc52L,0x369a9116c09e2c92L,\n        0x0c527f92cf182cf8L },\n      { 0x9e5919382aede0acL,0xb29222086cc34939L,0x3c9d896299a34361L,\n        0x3c81836dc1905fe6L } },\n    /* 57 << 126 */\n    { { 0x4bfeb57fa001ec5aL,0xe993f5bba0dc5dbaL,0x47884109724a1380L,\n        0x8a0369ab32fe9a04L },\n      { 0xea068d608c927db8L,0xbf5f37cf94655741L,0x47d402a204b6c7eaL,\n        0x4551c2956af259cbL } },\n    /* 58 << 126 */\n    { { 0x698b71e7ed77ee8bL,0xbddf7bd0f309d5c7L,0x6201c22c34e780caL,\n        0xab04f7d84c295ef4L },\n      { 0x1c9472944313a8ceL,0xe532e4ac92ca4cfeL,0x89738f80d0a7a97aL,\n        0xec088c88a580fd5bL } },\n    /* 59 << 126 */\n    { { 0x612b1ecc42ce9e51L,0x8f9840fdb25fdd2aL,0x3cda78c001e7f839L,\n        0x546b3d3aece05480L },\n      { 0x271719a980d30916L,0x45497107584c20c4L,0xaf8f94785bc78608L,\n        0x28c7d484277e2a4cL } },\n    /* 60 << 126 */\n    { { 0xfce0176788a2ffe4L,0xdc506a3528e169a5L,0x0ea108617af9c93aL,\n        0x1ed2436103fa0e08L },\n      { 0x96eaaa92a3d694e7L,0xc0f43b4def50bc74L,0xce6aa58c64114db4L,\n        0x8218e8ea7c000fd4L } },\n    /* 61 << 126 */\n    { { 0xac815dfb185f8844L,0xcd7e90cb1557abfbL,0x23d16655afbfecdfL,\n        0x80f3271f085cac4aL },\n      { 0x7fc39aa7d0e62f47L,0x88d519d1460a48e5L,0x59559ac4d28f101eL,\n        0x7981d9e9ca9ae816L } },\n    /* 62 << 126 */\n    { { 0x5c38652c9ac38203L,0x86eaf87f57657fe5L,0x568fc472e21f5416L,\n        0x2afff39ce7e597b5L },\n      { 0x3adbbb07256d4eabL,0x225986928285ab89L,0x35f8112a041caefeL,\n        0x95df02e3a5064c8bL } },\n    /* 63 << 126 */\n    { { 0x4d63356ec7004bf3L,0x230a08f4db83c7deL,0xca27b2708709a7b7L,\n        0x0d1c4cc4cb9abd2dL },\n      { 0x8a0bc66e7550fee8L,0x369cd4c79cf7247eL,0x75562e8492b5b7e7L,\n        0x8fed0da05802af7bL } },\n    /* 64 << 126 */\n    { { 0x6a7091c2e48fb889L,0x26882c137b8a9d06L,0xa24986631b82a0e2L,\n        0x844ed7363518152dL },\n      { 0x282f476fd86e27c7L,0xa04edaca04afefdcL,0x8b256ebc6119e34dL,\n        0x56a413e90787d78bL } },\n    /* 0 << 133 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 133 */\n    { { 0x82ee061d5a74be50L,0xe41781c4dea16ff5L,0xe0b0c81e99bfc8a2L,\n        0x624f4d690b547e2dL },\n      { 0x3a83545dbdcc9ae4L,0x2573dbb6409b1e8eL,0x482960c4a6c93539L,\n        0xf01059ad5ae18798L } },\n    /* 2 << 133 */\n    { { 0x715c9f973112795fL,0xe8244437984e6ee1L,0x55cb4858ecb66bcdL,\n        0x7c136735abaffbeeL },\n      { 0x546615955dbec38eL,0x51c0782c388ad153L,0x9ba4c53ac6e0952fL,\n        0x27e6782a1b21dfa8L } },\n    /* 3 << 133 */\n    { { 0x682f903d4ed2dbc2L,0x0eba59c87c3b2d83L,0x8e9dc84d9c7e9335L,\n        0x5f9b21b00eb226d7L },\n      { 0xe33bd394af267baeL,0xaa86cc25be2e15aeL,0x4f0bf67d6a8ec500L,\n        0x5846aa44f9630658L } },\n    /* 4 << 133 */\n    { { 0xfeb09740e2c2bf15L,0x627a2205a9e99704L,0xec8d73d0c2fbc565L,\n        0x223eed8fc20c8de8L },\n      { 0x1ee32583a8363b49L,0x1a0b6cb9c9c2b0a6L,0x49f7c3d290dbc85cL,\n        0xa8dfbb971ef4c1acL } },\n    /* 5 << 133 */\n    { { 0xafb34d4c65c7c2abL,0x1d4610e7e2c5ea84L,0x893f6d1b973c4ab5L,\n        0xa3cdd7e9945ba5c4L },\n      { 0x60514983064417eeL,0x1459b23cad6bdf2bL,0x23b2c3415cf726c3L,\n        0x3a82963532d6354aL } },\n    /* 6 << 133 */\n    { { 0x294f901fab192c18L,0xec5fcbfe7030164fL,0xe2e2fcb7e2246ba6L,\n        0x1e7c88b3221a1a0cL },\n      { 0x72c7dd93c92d88c5L,0x41c2148e1106fb59L,0x547dd4f5a0f60f14L,\n        0xed9b52b263960f31L } },\n    /* 7 << 133 */\n    { { 0x6c8349ebb0a5b358L,0xb154c5c29e7e2ed6L,0xcad5eccfeda462dbL,\n        0xf2d6dbe42de66b69L },\n      { 0x426aedf38665e5b2L,0x488a85137b7f5723L,0x15cc43b38bcbb386L,\n        0x27ad0af3d791d879L } },\n    /* 8 << 133 */\n    { { 0xc16c236e846e364fL,0x7f33527cdea50ca0L,0xc48107750926b86dL,\n        0x6c2a36090598e70cL },\n      { 0xa6755e52f024e924L,0xe0fa07a49db4afcaL,0x15c3ce7d66831790L,\n        0x5b4ef350a6cbb0d6L } },\n    /* 9 << 133 */\n    { { 0x2c4aafc4b6205969L,0x42563f02f6c7854fL,0x016aced51d983b48L,\n        0xfeb356d899949755L },\n      { 0x8c2a2c81d1a39bd7L,0x8f44340fe6934ae9L,0x148cf91c447904daL,\n        0x7340185f0f51a926L } },\n    /* 10 << 133 */\n    { { 0x2f8f00fb7409ab46L,0x057e78e680e289b2L,0x03e5022ca888e5d1L,\n        0x3c87111a9dede4e2L },\n      { 0x5b9b0e1c7809460bL,0xe751c85271c9abc7L,0x8b944e28c7cc1dc9L,\n        0x4f201ffa1d3cfa08L } },\n    /* 11 << 133 */\n    { { 0x02fc905c3e6721ceL,0xd52d70dad0b3674cL,0x5dc2e5ca18810da4L,\n        0xa984b2735c69dd99L },\n      { 0x63b9252784de5ca4L,0x2f1c9872c852dec4L,0x18b03593c2e3de09L,\n        0x19d70b019813dc2fL } },\n    /* 12 << 133 */\n    { { 0x42806b2da6dc1d29L,0xd3030009f871e144L,0xa1feb333aaf49276L,\n        0xb5583b9ec70bc04bL },\n      { 0x1db0be7895695f20L,0xfc84181189d012b5L,0x6409f27205f61643L,\n        0x40d34174d5883128L } },\n    /* 13 << 133 */\n    { { 0xd79196f567419833L,0x6059e252863b7b08L,0x84da18171c56700cL,\n        0x5758ee56b28d3ec4L },\n      { 0x7da2771d013b0ea6L,0xfddf524b54c5e9b9L,0x7df4faf824305d80L,\n        0x58f5c1bf3a97763fL } },\n    /* 14 << 133 */\n    { { 0xa5af37f17c696042L,0xd4cba22c4a2538deL,0x211cb9959ea42600L,\n        0xcd105f417b069889L },\n      { 0xb1e1cf19ddb81e74L,0x472f2d895157b8caL,0x086fb008ee9db885L,\n        0x365cd5700f26d131L } },\n    /* 15 << 133 */\n    { { 0x284b02bba2be7053L,0xdcbbf7c67ab9a6d6L,0x4425559c20f7a530L,\n        0x961f2dfa188767c8L },\n      { 0xe2fd943570dc80c4L,0x104d6b63f0784120L,0x7f592bc153567122L,\n        0xf6bc1246f688ad77L } },\n    /* 16 << 133 */\n    { { 0x05214c050f15dde9L,0xa47a76a80d5f2b82L,0xbb254d3062e82b62L,\n        0x11a05fe03ec955eeL },\n      { 0x7eaff46e9d529b36L,0x55ab13018f9e3df6L,0xc463e37199317698L,\n        0xfd251438ccda47adL } },\n    /* 17 << 133 */\n    { { 0xca9c354723d695eaL,0x48ce626e16e589b5L,0x6b5b64c7b187d086L,\n        0xd02e1794b2207948L },\n      { 0x8b58e98f7198111dL,0x90ca6305dcf9c3ccL,0x5691fe72f34089b0L,\n        0x60941af1fc7c80ffL } },\n    /* 18 << 133 */\n    { { 0xa09bc0a222eb51e5L,0xc0bb7244aa9cf09aL,0x36a8077f80159f06L,\n        0x8b5c989edddc560eL },\n      { 0x19d2f316512e1f43L,0x02eac554ad08ff62L,0x012ab84c07d20b4eL,\n        0x37d1e115d6d4e4e1L } },\n    /* 19 << 133 */\n    { { 0xb6443e1aab7b19a8L,0xf08d067edef8cd45L,0x63adf3e9685e03daL,\n        0xcf15a10e4792b916L },\n      { 0xf44bcce5b738a425L,0xebe131d59636b2fdL,0x940688417850d605L,\n        0x09684eaab40d749dL } },\n    /* 20 << 133 */\n    { { 0x8c3c669c72ba075bL,0x89f78b55ba469015L,0x5706aade3e9f8ba8L,\n        0x6d8bd565b32d7ed7L },\n      { 0x25f4e63b805f08d6L,0x7f48200dc3bcc1b5L,0x4e801968b025d847L,\n        0x74afac0487cbe0a8L } },\n    /* 21 << 133 */\n    { { 0x43ed2c2b7e63d690L,0xefb6bbf00223cdb8L,0x4fec3cae2884d3feL,\n        0x065ecce6d75e25a4L },\n      { 0x6c2294ce69f79071L,0x0d9a8e5f044b8666L,0x5009f23817b69d8fL,\n        0x3c29f8fec5dfdaf7L } },\n    /* 22 << 133 */\n    { { 0x9067528febae68c4L,0x5b38563230c5ba21L,0x540df1191fdd1aecL,\n        0xcf37825bcfba4c78L },\n      { 0x77eff980beb11454L,0x40a1a99160c1b066L,0xe8018980f889a1c7L,\n        0xb9c52ae976c24be0L } },\n    /* 23 << 133 */\n    { { 0x05fbbcce45650ef4L,0xae000f108aa29ac7L,0x884b71724f04c470L,\n        0x7cd4fde219bb5c25L },\n      { 0x6477b22ae8840869L,0xa88688595fbd0686L,0xf23cc02e1116dfbaL,\n        0x76cd563fd87d7776L } },\n    /* 24 << 133 */\n    { { 0xe2a37598a9d82abfL,0x5f188ccbe6c170f5L,0x816822005066b087L,\n        0xda22c212c7155adaL },\n      { 0x151e5d3afbddb479L,0x4b606b846d715b99L,0x4a73b54bf997cb2eL,\n        0x9a1bfe433ecd8b66L } },\n    /* 25 << 133 */\n    { { 0x1c3128092a67d48aL,0xcd6a671e031fa9e2L,0xbec3312a0e43a34aL,\n        0x1d93563955ef47d3L },\n      { 0x5ea024898fea73eaL,0x8247b364a035afb2L,0xb58300a65265b54cL,\n        0x3286662f722c7148L } },\n    /* 26 << 133 */\n    { { 0xb77fd76bb4ec4c20L,0xf0a12fa70f3fe3fdL,0xf845bbf541d8c7e8L,\n        0xe4d969ca5ec10aa8L },\n      { 0x4c0053b743e232a3L,0xdc7a3fac37f8a45aL,0x3c4261c520d81c8fL,\n        0xfd4b3453b00eab00L } },\n    /* 27 << 133 */\n    { { 0x76d48f86d36e3062L,0x626c5277a143ff02L,0x538174deaf76f42eL,\n        0x2267aa866407ceacL },\n      { 0xfad7635172e572d5L,0xab861af7ba7330ebL,0xa0a1c8c7418d8657L,\n        0x988821cb20289a52L } },\n    /* 28 << 133 */\n    { { 0x79732522cccc18adL,0xaadf3f8df1a6e027L,0xf7382c9317c2354dL,\n        0x5ce1680cd818b689L },\n      { 0x359ebbfcd9ecbee9L,0x4330689c1cae62acL,0xb55ce5b4c51ac38aL,\n        0x7921dfeafe238ee8L } },\n    /* 29 << 133 */\n    { { 0x3972bef8271d1ca5L,0x3e423bc7e8aabd18L,0x57b09f3f44a3e5e3L,\n        0x5da886ae7b444d66L },\n      { 0x68206634a9964375L,0x356a2fa3699cd0ffL,0xaf0faa24dba515e9L,\n        0x536e1f5cb321d79aL } },\n    /* 30 << 133 */\n    { { 0xd3b9913a5c04e4eaL,0xd549dcfed6f11513L,0xee227bf579fd1d94L,\n        0x9f35afeeb43f2c67L },\n      { 0xd2638d24f1314f53L,0x62baf948cabcd822L,0x5542de294ef48db0L,\n        0xb3eb6a04fc5f6bb2L } },\n    /* 31 << 133 */\n    { { 0x23c110ae1208e16aL,0x1a4d15b5f8363e24L,0x30716844164be00bL,\n        0xa8e24824f6f4690dL },\n      { 0x548773a290b170cfL,0xa1bef33142f191f4L,0x70f418d09247aa97L,\n        0xea06028e48be9147L } },\n    /* 32 << 133 */\n    { { 0xe13122f3dbfb894eL,0xbe9b79f6ce274b18L,0x85a49de5ca58aadfL,\n        0x2495775811487351L },\n      { 0x111def61bb939099L,0x1d6a974a26d13694L,0x4474b4ced3fc253bL,\n        0x3a1485e64c5db15eL } },\n    /* 33 << 133 */\n    { { 0xe79667b4147c15b4L,0xe34f553b7bc61301L,0x032b80f817094381L,\n        0x55d8bafd723eaa21L },\n      { 0x5a987995f1c0e74eL,0x5a9b292eebba289cL,0x413cd4b2eb4c8251L,\n        0x98b5d243d162db0aL } },\n    /* 34 << 133 */\n    { { 0xbb47bf6668342520L,0x08d68949baa862d1L,0x11f349c7e906abcdL,\n        0x454ce985ed7bf00eL },\n      { 0xacab5c9eb55b803bL,0xb03468ea31e3c16dL,0x5c24213dd273bf12L,\n        0x211538eb71587887L } },\n    /* 35 << 133 */\n    { { 0x198e4a2f731dea2dL,0xd5856cf274ed7b2aL,0x86a632eb13a664feL,\n        0x932cd909bda41291L },\n      { 0x850e95d4c0c4ddc0L,0xc0f422f8347fc2c9L,0xe68cbec486076bcbL,\n        0xf9e7c0c0cd6cd286L } },\n    /* 36 << 133 */\n    { { 0x65994ddb0f5f27caL,0xe85461fba80d59ffL,0xff05481a66601023L,\n        0xc665427afc9ebbfbL },\n      { 0xb0571a697587fd52L,0x935289f88d49efceL,0x61becc60ea420688L,\n        0xb22639d913a786afL } },\n    /* 37 << 133 */\n    { { 0x1a8e6220361ecf90L,0x001f23e025506463L,0xe4ae9b5d0a5c2b79L,\n        0xebc9cdadd8149db5L },\n      { 0xb33164a1934aa728L,0x750eb00eae9b60f3L,0x5a91615b9b9cfbfdL,\n        0x97015cbfef45f7f6L } },\n    /* 38 << 133 */\n    { { 0xb462c4a5bf5151dfL,0x21adcc41b07118f2L,0xd60c545b043fa42cL,\n        0xfc21aa54e96be1abL },\n      { 0xe84bc32f4e51ea80L,0x3dae45f0259b5d8dL,0xbb73c7ebc38f1b5eL,\n        0xe405a74ae8ae617dL } },\n    /* 39 << 133 */\n    { { 0xbb1ae9c69f1c56bdL,0x8c176b9849f196a4L,0xc448f3116875092bL,\n        0xb5afe3de9f976033L },\n      { 0xa8dafd49145813e5L,0x687fc4d9e2b34226L,0xf2dfc92d4c7ff57fL,\n        0x004e3fc1401f1b46L } },\n    /* 40 << 133 */\n    { { 0x5afddab61430c9abL,0x0bdd41d32238e997L,0xf0947430418042aeL,\n        0x71f9addacdddc4cbL },\n      { 0x7090c016c52dd907L,0xd9bdf44d29e2047fL,0xe6f1fe801b1011a6L,\n        0xb63accbcd9acdc78L } },\n    /* 41 << 133 */\n    { { 0xcfc7e2351272a95bL,0x0c667717a6276ac8L,0x3c0d3709e2d7eef7L,\n        0x5add2b069a685b3eL },\n      { 0x363ad32d14ea5d65L,0xf8e01f068d7dd506L,0xc9ea221375b4aac6L,\n        0xed2a2bf90d353466L } },\n    /* 42 << 133 */\n    { { 0x439d79b5e9d3a7c3L,0x8e0ee5a681b7f34bL,0xcf3dacf51dc4ba75L,\n        0x1d3d1773eb3310c7L },\n      { 0xa8e671127747ae83L,0x31f43160197d6b40L,0x0521cceecd961400L,\n        0x67246f11f6535768L } },\n    /* 43 << 133 */\n    { { 0x702fcc5aef0c3133L,0x247cc45d7e16693bL,0xfd484e49c729b749L,\n        0x522cef7db218320fL },\n      { 0xe56ef40559ab93b3L,0x225fba119f181071L,0x33bd659515330ed0L,\n        0xc4be69d51ddb32f7L } },\n    /* 44 << 133 */\n    { { 0x264c76680448087cL,0xac30903f71432daeL,0x3851b26600f9bf47L,\n        0x400ed3116cdd6d03L },\n      { 0x045e79fef8fd2424L,0xfdfd974afa6da98bL,0x45c9f6410c1e673aL,\n        0x76f2e7335b2c5168L } },\n    /* 45 << 133 */\n    { { 0x1adaebb52a601753L,0xb286514cc57c2d49L,0xd87696701e0bfd24L,\n        0x950c547e04478922L },\n      { 0xd1d41969e5d32bfeL,0x30bc1472750d6c3eL,0x8f3679fee0e27f3aL,\n        0x8f64a7dca4a6ee0cL } },\n    /* 46 << 133 */\n    { { 0x2fe59937633dfb1fL,0xea82c395977f2547L,0xcbdfdf1a661ea646L,\n        0xc7ccc591b9085451L },\n      { 0x8217796281761e13L,0xda57596f9196885cL,0xbc17e84928ffbd70L,\n        0x1e6e0a412671d36fL } },\n    /* 47 << 133 */\n    { { 0x61ae872c4152fcf5L,0x441c87b09e77e754L,0xd0799dd5a34dff09L,\n        0x766b4e4488a6b171L },\n      { 0xdc06a51211f1c792L,0xea02ae934be35c3eL,0xe5ca4d6de90c469eL,\n        0x4df4368e56e4ff5cL } },\n    /* 48 << 133 */\n    { { 0x7817acab4baef62eL,0x9f5a2202a85b91e8L,0x9666ebe66ce57610L,\n        0x32ad31f3f73bfe03L },\n      { 0x628330a425bcf4d6L,0xea950593515056e6L,0x59811c89e1332156L,\n        0xc89cf1fe8c11b2d7L } },\n    /* 49 << 133 */\n    { { 0x75b6391304e60cc0L,0xce811e8d4625d375L,0x030e43fc2d26e562L,\n        0xfbb30b4b608d36a0L },\n      { 0x634ff82c48528118L,0x7c6fe085cd285911L,0x7f2830c099358f28L,\n        0x2e60a95e665e6c09L } },\n    /* 50 << 133 */\n    { { 0x08407d3d9b785dbfL,0x530889aba759bce7L,0xf228e0e652f61239L,\n        0x2b6d14616879be3cL },\n      { 0xe6902c0451a7bbf7L,0x30ad99f076f24a64L,0x66d9317a98bc6da0L,\n        0xf4f877f3cb596ac0L } },\n    /* 51 << 133 */\n    { { 0xb05ff62d4c44f119L,0x4555f536e9b77416L,0xc7c0d0598caed63bL,\n        0x0cd2b7cec358b2a9L },\n      { 0x3f33287b46945fa3L,0xf8785b20d67c8791L,0xc54a7a619637bd08L,\n        0x54d4598c18be79d7L } },\n    /* 52 << 133 */\n    { { 0x889e5acbc46d7ce1L,0x9a515bb78b085877L,0xfac1a03d0b7a5050L,\n        0x7d3e738af2926035L },\n      { 0x861cc2ce2a6cb0ebL,0x6f2e29558f7adc79L,0x61c4d45133016376L,\n        0xd9fd2c805ad59090L } },\n    /* 53 << 133 */\n    { { 0xe5a83738b2b836a1L,0x855b41a07c0d6622L,0x186fe3177cc19af1L,\n        0x6465c1fffdd99acbL },\n      { 0x46e5c23f6974b99eL,0x75a7cf8ba2717cbeL,0x4d2ebc3f062be658L,\n        0x094b44475f209c98L } },\n    /* 54 << 133 */\n    { { 0x4af285edb940cb5aL,0x6706d7927cc82f10L,0xc8c8776c030526faL,\n        0xfa8e6f76a0da9140L },\n      { 0x77ea9d34591ee4f0L,0x5f46e33740274166L,0x1bdf98bbea671457L,\n        0xd7c08b46862a1fe2L } },\n    /* 55 << 133 */\n    { { 0x46cc303c1c08ad63L,0x995434404c845e7bL,0x1b8fbdb548f36bf7L,\n        0x5b82c3928c8273a7L },\n      { 0x08f712c4928435d5L,0x071cf0f179330380L,0xc74c2d24a8da054aL,\n        0xcb0e720143c46b5cL } },\n    /* 56 << 133 */\n    { { 0x0ad7337ac0b7eff3L,0x8552225ec5e48b3cL,0xe6f78b0c73f13a5fL,\n        0x5e70062e82349cbeL },\n      { 0x6b8d5048e7073969L,0x392d2a29c33cb3d2L,0xee4f727c4ecaa20fL,\n        0xa068c99e2ccde707L } },\n    /* 57 << 133 */\n    { { 0xfcd5651fb87a2913L,0xea3e3c153cc252f0L,0x777d92df3b6cd3e4L,\n        0x7a414143c5a732e7L },\n      { 0xa895951aa71ff493L,0xfe980c92bbd37cf6L,0x45bd5e64decfeeffL,\n        0x910dc2a9a44c43e9L } },\n    /* 58 << 133 */\n    { { 0xcb403f26cca9f54dL,0x928bbdfb9303f6dbL,0x3c37951ea9eee67cL,\n        0x3bd61a52f79961c3L },\n      { 0x09a238e6395c9a79L,0x6940ca2d61eb352dL,0x7d1e5c5ec1875631L,\n        0x1e19742c1e1b20d1L } },\n    /* 59 << 133 */\n    { { 0x4633d90823fc2e6eL,0xa76e29a908959149L,0x61069d9c84ed7da5L,\n        0x0baa11cf5dbcad51L },\n      { 0xd01eec64961849daL,0x93b75f1faf3d8c28L,0x57bc4f9f1ca2ee44L,\n        0x5a26322d00e00558L } },\n    /* 60 << 133 */\n    { { 0x1888d65861a023efL,0x1d72aab4b9e5246eL,0xa9a26348e5563ec0L,\n        0xa0971963c3439a43L },\n      { 0x567dd54badb9b5b7L,0x73fac1a1c45a524bL,0x8fe97ef7fe38e608L,\n        0x608748d23f384f48L } },\n    /* 61 << 133 */\n    { { 0xb0571794c486094fL,0x869254a38bf3a8d6L,0x148a8dd1310b0e25L,\n        0x99ab9f3f9aa3f7d8L },\n      { 0x0927c68a6706c02eL,0x22b5e76c69790e6cL,0x6c3252606c71376cL,\n        0x53a5769009ef6657L } },\n    /* 62 << 133 */\n    { { 0x8d63f852edffcf3aL,0xb4d2ed043c0a6f55L,0xdb3aa8de12519b9eL,\n        0x5d38e9c41e0a569aL },\n      { 0x871528bf303747e2L,0xa208e77cf5b5c18dL,0x9d129c88ca6bf923L,\n        0xbcbf197fbf02839fL } },\n    /* 63 << 133 */\n    { { 0x9b9bf03027323194L,0x3b055a8b339ca59dL,0xb46b23120f669520L,\n        0x19789f1f497e5f24L },\n      { 0x9c499468aaf01801L,0x72ee11908b69d59cL,0x8bd39595acf4c079L,\n        0x3ee11ece8e0cd048L } },\n    /* 64 << 133 */\n    { { 0xebde86ec1ed66f18L,0x225d906bd61fce43L,0x5cab07d6e8bed74dL,\n        0x16e4617f27855ab7L },\n      { 0x6568aaddb2fbc3ddL,0xedb5484f8aeddf5bL,0x878f20e86dcf2fadL,\n        0x3516497c615f5699L } },\n    /* 0 << 140 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 140 */\n    { { 0xef0a3fecfa181e69L,0x9ea02f8130d69a98L,0xb2e9cf8e66eab95dL,\n        0x520f2beb24720021L },\n      { 0x621c540a1df84361L,0x1203772171fa6d5dL,0x6e3c7b510ff5f6ffL,\n        0x817a069babb2bef3L } },\n    /* 2 << 140 */\n    { { 0x83572fb6b294cda6L,0x6ce9bf75b9039f34L,0x20e012f0095cbb21L,\n        0xa0aecc1bd063f0daL },\n      { 0x57c21c3af02909e5L,0xc7d59ecf48ce9cdcL,0x2732b8448ae336f8L,\n        0x056e37233f4f85f4L } },\n    /* 3 << 140 */\n    { { 0x8a10b53189e800caL,0x50fe0c17145208fdL,0x9e43c0d3b714ba37L,\n        0x427d200e34189accL },\n      { 0x05dee24fe616e2c0L,0x9c25f4c8ee1854c1L,0x4d3222a58f342a73L,\n        0x0807804fa027c952L } },\n    /* 4 << 140 */\n    { { 0xc222653a4f0d56f3L,0x961e4047ca28b805L,0x2c03f8b04a73434bL,\n        0x4c966787ab712a19L },\n      { 0xcc196c42864fee42L,0xc1be93da5b0ece5cL,0xa87d9f22c131c159L,\n        0x2bb6d593dce45655L } },\n    /* 5 << 140 */\n    { { 0x22c49ec9b809b7ceL,0x8a41486be2c72c2cL,0x813b9420fea0bf36L,\n        0xb3d36ee9a66dac69L },\n      { 0x6fddc08a328cc987L,0x0a3bcd2c3a326461L,0x7103c49dd810dbbaL,\n        0xf9d81a284b78a4c4L } },\n    /* 6 << 140 */\n    { { 0x3de865ade4d55941L,0xdedafa5e30384087L,0x6f414abb4ef18b9bL,\n        0x9ee9ea42faee5268L },\n      { 0x260faa1637a55a4aL,0xeb19a514015f93b9L,0x51d7ebd29e9c3598L,\n        0x523fc56d1932178eL } },\n    /* 7 << 140 */\n    { { 0x501d070cb98fe684L,0xd60fbe9a124a1458L,0xa45761c892bc6b3fL,\n        0xf5384858fe6f27cbL },\n      { 0x4b0271f7b59e763bL,0x3d4606a95b5a8e5eL,0x1eda5d9b05a48292L,\n        0xda7731d0e6fec446L } },\n    /* 8 << 140 */\n    { { 0xa3e3369390d45871L,0xe976404006166d8dL,0xb5c3368289a90403L,\n        0x4bd1798372f1d637L },\n      { 0xa616679ed5d2c53aL,0x5ec4bcd8fdcf3b87L,0xae6d7613b66a694eL,\n        0x7460fc76e3fc27e5L } },\n    /* 9 << 140 */\n    { { 0x70469b8295caabeeL,0xde024ca5889501e3L,0x6bdadc06076ed265L,\n        0x0cb1236b5a0ef8b2L },\n      { 0x4065ddbf0972ebf9L,0xf1dd387522aca432L,0xa88b97cf744aff76L,\n        0xd1359afdfe8e3d24L } },\n    /* 10 << 140 */\n    { { 0x52a3ba2b91502cf3L,0x2c3832a8084db75dL,0x04a12dddde30b1c9L,\n        0x7802eabce31fd60cL },\n      { 0x33707327a37fddabL,0x65d6f2abfaafa973L,0x3525c5b811e6f91aL,\n        0x76aeb0c95f46530bL } },\n    /* 11 << 140 */\n    { { 0xe8815ff62f93a675L,0xa6ec968405f48679L,0x6dcbb556358ae884L,\n        0x0af61472e19e3873L },\n      { 0x72334372a5f696beL,0xc65e57ea6f22fb70L,0x268da30c946cea90L,\n        0x136a8a8765681b2aL } },\n    /* 12 << 140 */\n    { { 0xad5e81dc0f9f44d4L,0xf09a69602c46585aL,0xd1649164c447d1b1L,\n        0x3b4b36c8879dc8b1L },\n      { 0x20d4177b3b6b234cL,0x096a25051730d9d0L,0x0611b9b8ef80531dL,\n        0xba904b3b64bb495dL } },\n    /* 13 << 140 */\n    { { 0x1192d9d493a3147aL,0x9f30a5dc9a565545L,0x90b1f9cb6ef07212L,\n        0x299585460d87fc13L },\n      { 0xd3323effc17db9baL,0xcb18548ccb1644a8L,0x18a306d44f49ffbcL,\n        0x28d658f14c2e8684L } },\n    /* 14 << 140 */\n    { { 0x44ba60cda99f8c71L,0x67b7abdb4bf742ffL,0x66310f9c914b3f99L,\n        0xae430a32f412c161L },\n      { 0x1e6776d388ace52fL,0x4bc0fa2452d7067dL,0x03c286aa8f07cd1bL,\n        0x4cb8f38ca985b2c1L } },\n    /* 15 << 140 */\n    { { 0x83ccbe808c3bff36L,0x005a0bd25263e575L,0x460d7dda259bdcd1L,\n        0x4a1c5642fa5cab6bL },\n      { 0x2b7bdbb99fe4fc88L,0x09418e28cc97bbb5L,0xd8274fb4a12321aeL,\n        0xb137007d5c87b64eL } },\n    /* 16 << 140 */\n    { { 0x80531fe1c63c4962L,0x50541e89981fdb25L,0xdc1291a1fd4c2b6bL,\n        0xc0693a17a6df4fcaL },\n      { 0xb2c4604e0117f203L,0x245f19630a99b8d0L,0xaedc20aac6212c44L,\n        0xb1ed4e56520f52a8L } },\n    /* 17 << 140 */\n    { { 0xfe48f575f8547be3L,0x0a7033cda9e45f98L,0x4b45d3a918c50100L,\n        0xb2a6cd6aa61d41daL },\n      { 0x60bbb4f557933c6bL,0xa7538ebd2b0d7ffcL,0x9ea3ab8d8cd626b6L,\n        0x8273a4843601625aL } },\n    /* 18 << 140 */\n    { { 0x888598450168e508L,0x8cbc9bb299a94abdL,0x713ac792fab0a671L,\n        0xa3995b196c9ebffcL },\n      { 0xe711668e1239e152L,0x56892558bbb8dff4L,0x8bfc7dabdbf17963L,\n        0x5b59fe5ab3de1253L } },\n    /* 19 << 140 */\n    { { 0x7e3320eb34a9f7aeL,0xe5e8cf72d751efe4L,0x7ea003bcd9be2f37L,\n        0xc0f551a0b6c08ef7L },\n      { 0x56606268038f6725L,0x1dd38e356d92d3b6L,0x07dfce7cc3cbd686L,\n        0x4e549e04651c5da8L } },\n    /* 20 << 140 */\n    { { 0x4058f93b08b19340L,0xc2fae6f4cac6d89dL,0x4bad8a8c8f159cc7L,\n        0x0ddba4b3cb0b601cL },\n      { 0xda4fc7b51dd95f8cL,0x1d163cd7cea5c255L,0x30707d06274a8c4cL,\n        0x79d9e0082802e9ceL } },\n    /* 21 << 140 */\n    { { 0x02a29ebfe6ddd505L,0x37064e74b50bed1aL,0x3f6bae65a7327d57L,\n        0x3846f5f1f83920bcL },\n      { 0x87c3749160df1b9bL,0x4cfb28952d1da29fL,0x10a478ca4ed1743cL,\n        0x390c60303edd47c6L } },\n    /* 22 << 140 */\n    { { 0x8f3e53128c0a78deL,0xccd02bda1e85df70L,0xd6c75c03a61b6582L,\n        0x0762921cfc0eebd1L },\n      { 0xd34d0823d85010c0L,0xd73aaacb0044cf1fL,0xfb4159bba3b5e78aL,\n        0x2287c7f7e5826f3fL } },\n    /* 23 << 140 */\n    { { 0x4aeaf742580b1a01L,0xf080415d60423b79L,0xe12622cda7dea144L,\n        0x49ea499659d62472L },\n      { 0xb42991ef571f3913L,0x0610f214f5b25a8aL,0x47adc58530b79e8fL,\n        0xf90e3df607a065a2L } },\n    /* 24 << 140 */\n    { { 0x5d0a5deb43e2e034L,0x53fb5a34444024aaL,0xa8628c686b0c9f7fL,\n        0x9c69c29cac563656L },\n      { 0x5a231febbace47b6L,0xbdce02899ea5a2ecL,0x05da1fac9463853eL,\n        0x96812c52509e78aaL } },\n    /* 25 << 140 */\n    { { 0xd3fb577157151692L,0xeb2721f8d98e1c44L,0xc050608732399be1L,\n        0xda5a5511d979d8b8L },\n      { 0x737ed55dc6f56780L,0xe20d30040dc7a7f4L,0x02ce7301f5941a03L,\n        0x91ef5215ed30f83aL } },\n    /* 26 << 140 */\n    { { 0x28727fc14092d85fL,0x72d223c65c49e41aL,0xa7cf30a2ba6a4d81L,\n        0x7c086209b030d87dL },\n      { 0x04844c7dfc588b09L,0x728cd4995874bbb0L,0xcc1281eee84c0495L,\n        0x0769b5baec31958fL } },\n    /* 27 << 140 */\n    { { 0x665c228bf99c2471L,0xf2d8a11b191eb110L,0x4594f494d36d7024L,\n        0x482ded8bcdcb25a1L },\n      { 0xc958a9d8dadd4885L,0x7004477ef1d2b547L,0x0a45f6ef2a0af550L,\n        0x4fc739d62f8d6351L } },\n    /* 28 << 140 */\n    { { 0x75cdaf27786f08a9L,0x8700bb2642c2737fL,0x855a71411c4e2670L,\n        0x810188c115076fefL },\n      { 0xc251d0c9abcd3297L,0xae4c8967f48108ebL,0xbd146de718ceed30L,\n        0xf9d4f07ac986bcedL } },\n    /* 29 << 140 */\n    { { 0x5ad98ed583fa1e08L,0x7780d33ebeabd1fbL,0xe330513c903b1196L,\n        0xba11de9ea47bc8c4L },\n      { 0x684334da02c2d064L,0x7ecf360da48de23bL,0x57a1b4740a9089d8L,\n        0xf28fa439ff36734cL } },\n    /* 30 << 140 */\n    { { 0xf2a482cbea4570b3L,0xee65d68ba5ebcee9L,0x988d0036b9694cd5L,\n        0x53edd0e937885d32L },\n      { 0xe37e3307beb9bc6dL,0xe9abb9079f5c6768L,0x4396ccd551f2160fL,\n        0x2500888c47336da6L } },\n    /* 31 << 140 */\n    { { 0x383f9ed9926fce43L,0x809dd1c704da2930L,0x30f6f5968a4cb227L,\n        0x0d700c7f73a56b38L },\n      { 0x1825ea33ab64a065L,0xaab9b7351338df80L,0x1516100d9b63f57fL,\n        0x2574395a27a6a634L } },\n    /* 32 << 140 */\n    { { 0xb5560fb6700a1acdL,0xe823fd73fd999681L,0xda915d1f6cb4e1baL,\n        0x0d0301186ebe00a3L },\n      { 0x744fb0c989fca8cdL,0x970d01dbf9da0e0bL,0x0ad8c5647931d76fL,\n        0xb15737bff659b96aL } },\n    /* 33 << 140 */\n    { { 0xdc9933e8a8b484e7L,0xb2fdbdf97a26dec7L,0x2349e9a49f1f0136L,\n        0x7860368e70fddddbL },\n      { 0xd93d2c1cf9ad3e18L,0x6d6c5f17689f4e79L,0x7a544d91b24ff1b6L,\n        0x3e12a5ebfe16cd8cL } },\n    /* 34 << 140 */\n    { { 0x543574e9a56b872fL,0xa1ad550cfcf68ea2L,0x689e37d23f560ef7L,\n        0x8c54b9cac9d47a8bL },\n      { 0x46d40a4a088ac342L,0xec450c7c1576c6d0L,0xb589e31c1f9689e9L,\n        0xdacf2602b8781718L } },\n    /* 35 << 140 */\n    { { 0xa89237c6c8cb6b42L,0x1326fc93b96ef381L,0x55d56c6db5f07825L,\n        0xacba2eea7449e22dL },\n      { 0x74e0887a633c3000L,0xcb6cd172d7cbcf71L,0x309e81dec36cf1beL,\n        0x07a18a6d60ae399bL } },\n    /* 36 << 140 */\n    { { 0xb36c26799edce57eL,0x52b892f4df001d41L,0xd884ae5d16a1f2c6L,\n        0x9b329424efcc370aL },\n      { 0x3120daf2bd2e21dfL,0x55298d2d02470a99L,0x0b78af6ca05db32eL,\n        0x5c76a331601f5636L } },\n    /* 37 << 140 */\n    { { 0xaae861fff8a4f29cL,0x70dc9240d68f8d49L,0x960e649f81b1321cL,\n        0x3d2c801b8792e4ceL },\n      { 0xf479f77242521876L,0x0bed93bc416c79b1L,0xa67fbc05263e5bc9L,\n        0x01e8e630521db049L } },\n    /* 38 << 140 */\n    { { 0x76f26738c6f3431eL,0xe609cb02e3267541L,0xb10cff2d818c877cL,\n        0x1f0e75ce786a13cbL },\n      { 0xf4fdca641158544dL,0x5d777e896cb71ed0L,0x3c233737a9aa4755L,\n        0x7b453192e527ab40L } },\n    /* 39 << 140 */\n    { { 0xdb59f68839f05ffeL,0x8f4f4be06d82574eL,0xcce3450cee292d1bL,\n        0xaa448a1261ccd086L },\n      { 0xabce91b3f7914967L,0x4537f09b1908a5edL,0xa812421ef51042e7L,\n        0xfaf5cebcec0b3a34L } },\n    /* 40 << 140 */\n    { { 0x730ffd874ca6b39aL,0x70fb72ed02efd342L,0xeb4735f9d75c8edbL,\n        0xc11f2157c278aa51L },\n      { 0xc459f635bf3bfebfL,0x3a1ff0b46bd9601fL,0xc9d12823c420cb73L,\n        0x3e9af3e23c2915a3L } },\n    /* 41 << 140 */\n    { { 0xe0c82c72b41c3440L,0x175239e5e3039a5fL,0xe1084b8a558795a3L,\n        0x328d0a1dd01e5c60L },\n      { 0x0a495f2ed3788a04L,0x25d8ff1666c11a9fL,0xf5155f059ed692d6L,\n        0x954fa1074f425fe4L } },\n    /* 42 << 140 */\n    { { 0xd16aabf2e98aaa99L,0x90cd8ba096b0f88aL,0x957f4782c154026aL,\n        0x54ee073452af56d2L },\n      { 0xbcf89e5445b4147aL,0x3d102f219a52816cL,0x6808517e39b62e77L,\n        0x92e2542169169ad8L } },\n    /* 43 << 140 */\n    { { 0xd721d871bb608558L,0x60e4ebaef6d4ff9bL,0x0ba1081941f2763eL,\n        0xca2e45be51ee3247L },\n      { 0x66d172ec2bfd7a5fL,0x528a8f2f74d0b12dL,0xe17f1e38dabe70dcL,\n        0x1d5d73169f93983cL } },\n    /* 44 << 140 */\n    { { 0x51b2184adf423e31L,0xcb417291aedb1a10L,0x2054ca93625bcab9L,\n        0x54396860a98998f0L },\n      { 0x4e53f6c4a54ae57eL,0x0ffeb590ee648e9dL,0xfbbdaadc6afaf6bcL,\n        0xf88ae796aa3bfb8aL } },\n    /* 45 << 140 */\n    { { 0x209f1d44d2359ed9L,0xac68dd03f3544ce2L,0xf378da47fd51e569L,\n        0xe1abd8602cc80097L },\n      { 0x23ca18d9343b6e3aL,0x480797e8b40a1baeL,0xd1f0c717533f3e67L,\n        0x4489697006e6cdfcL } },\n    /* 46 << 140 */\n    { { 0x8ca2105552a82e8dL,0xb2caf78578460cdcL,0x4c1b7b62e9037178L,\n        0xefc09d2cdb514b58L },\n      { 0x5f2df9ee9113be5cL,0x2fbda78fb3f9271cL,0xe09a81af8f83fc54L,\n        0x06b138668afb5141L } },\n    /* 47 << 140 */\n    { { 0x38f6480f43e3865dL,0x72dd77a81ddf47d9L,0xf2a8e9714c205ff7L,\n        0x46d449d89d088ad8L },\n      { 0x926619ea185d706fL,0xe47e02ebc7dd7f62L,0xe7f120a78cbc2031L,\n        0xc18bef00998d4ac9L } },\n    /* 48 << 140 */\n    { { 0x18f37a9c6bdf22daL,0xefbc432f90dc82dfL,0xc52cef8e5d703651L,\n        0x82887ba0d99881a5L },\n      { 0x7cec9ddab920ec1dL,0xd0d7e8c3ec3e8d3bL,0x445bc3954ca88747L,\n        0xedeaa2e09fd53535L } },\n    /* 49 << 140 */\n    { { 0x461b1d936cc87475L,0xd92a52e26d2383bdL,0xfabccb59d7903546L,\n        0x6111a7613d14b112L },\n      { 0x0ae584feb3d5f612L,0x5ea69b8d60e828ecL,0x6c07898554087030L,\n        0x649cab04ac4821feL } },\n    /* 50 << 140 */\n    { { 0x25ecedcf8bdce214L,0xb5622f7286af7361L,0x0e1227aa7038b9e2L,\n        0xd0efb273ac20fa77L },\n      { 0x817ff88b79df975bL,0x856bf2861999503eL,0xb4d5351f5038ec46L,\n        0x740a52c5fc42af6eL } },\n    /* 51 << 140 */\n    { { 0x2e38bb152cbb1a3fL,0xc3eb99fe17a83429L,0xca4fcbf1dd66bb74L,\n        0x880784d6cde5e8fcL },\n      { 0xddc84c1cb4e7a0beL,0x8780510dbd15a72fL,0x44bcf1af81ec30e1L,\n        0x141e50a80a61073eL } },\n    /* 52 << 140 */\n    { { 0x0d95571847be87aeL,0x68a61417f76a4372L,0xf57e7e87c607c3d3L,\n        0x043afaf85252f332L },\n      { 0xcc14e1211552a4d2L,0xb6dee692bb4d4ab4L,0xb6ab74c8a03816a4L,\n        0x84001ae46f394a29L } },\n    /* 53 << 140 */\n    { { 0x5bed8344d795fb45L,0x57326e7db79f55a5L,0xc9533ce04accdffcL,\n        0x53473caf3993fa04L },\n      { 0x7906eb93a13df4c8L,0xa73e51f697cbe46fL,0xd1ab3ae10ae4ccf8L,\n        0x256145088a5b3dbcL } },\n    /* 54 << 140 */\n    { { 0x61eff96211a71b27L,0xdf71412b6bb7fa39L,0xb31ba6b82bd7f3efL,\n        0xb0b9c41569180d29L },\n      { 0xeec14552014cdde5L,0x702c624b227b4bbbL,0x2b15e8c2d3e988f3L,\n        0xee3bcc6da4f7fd04L } },\n    /* 55 << 140 */\n    { { 0x9d00822a42ac6c85L,0x2db0cea61df9f2b7L,0xd7cad2ab42de1e58L,\n        0x346ed5262d6fbb61L },\n      { 0xb39629951a2faf09L,0x2fa8a5807c25612eL,0x30ae04da7cf56490L,\n        0x756629080eea3961L } },\n    /* 56 << 140 */\n    { { 0x3609f5c53d080847L,0xcb081d395241d4f6L,0xb4fb381077961a63L,\n        0xc20c59842abb66fcL },\n      { 0x3d40aa7cf902f245L,0x9cb127364e536b1eL,0x5eda24da99b3134fL,\n        0xafbd9c695cd011afL } },\n    /* 57 << 140 */\n    { { 0x9a16e30ac7088c7dL,0x5ab657103207389fL,0x1b09547fe7407a53L,\n        0x2322f9d74fdc6eabL },\n      { 0xc0f2f22d7430de4dL,0x19382696e68ca9a9L,0x17f1eff1918e5868L,\n        0xe3b5b635586f4204L } },\n    /* 58 << 140 */\n    { { 0x146ef9803fbc4341L,0x359f2c805b5eed4eL,0x9f35744e7482e41dL,\n        0x9a9ac3ecf3b224c2L },\n      { 0x9161a6fe91fc50aeL,0x89ccc66bc613fa7cL,0x89268b14c732f15aL,\n        0x7cd6f4e2b467ed03L } },\n    /* 59 << 140 */\n    { { 0xfbf79869ce56b40eL,0xf93e094cc02dde98L,0xefe0c3a8edee2cd7L,\n        0x90f3ffc0b268fd42L },\n      { 0x81a7fd5608241aedL,0x95ab7ad800b1afe8L,0x401270563e310d52L,\n        0xd3ffdeb109d9fc43L } },\n    /* 60 << 140 */\n    { { 0xc8f85c91d11a8594L,0x2e74d25831cf6db8L,0x829c7ca302b5dfd0L,\n        0xe389cfbe69143c86L },\n      { 0xd01b6405941768d8L,0x4510399503bf825dL,0xcc4ee16656cd17e2L,\n        0xbea3c283ba037e79L } },\n    /* 61 << 140 */\n    { { 0x4e1ac06ed9a47520L,0xfbfe18aaaf852404L,0x5615f8e28087648aL,\n        0x7301e47eb9d150d9L },\n      { 0x79f9f9ddb299b977L,0x76697a7ba5b78314L,0x10d674687d7c90e7L,\n        0x7afffe03937210b5L } },\n    /* 62 << 140 */\n    { { 0x5aef3e4b28c22ceeL,0xefb0ecd809fd55aeL,0x4cea71320d2a5d6aL,\n        0x9cfb5fa101db6357L },\n      { 0x395e0b57f36e1ac5L,0x008fa9ad36cafb7dL,0x8f6cdf705308c4dbL,\n        0x51527a3795ed2477L } },\n    /* 63 << 140 */\n    { { 0xba0dee305bd21311L,0x6ed41b22909c90d7L,0xc5f6b7587c8696d3L,\n        0x0db8eaa83ce83a80L },\n      { 0xd297fe37b24b4b6fL,0xfe58afe8522d1f0dL,0x973587368c98dbd9L,\n        0x6bc226ca9454a527L } },\n    /* 64 << 140 */\n    { { 0xa12b384ece53c2d0L,0x779d897d5e4606daL,0xa53e47b073ec12b0L,\n        0x462dbbba5756f1adL },\n      { 0x69fe09f2cafe37b6L,0x273d1ebfecce2e17L,0x8ac1d5383cf607fdL,\n        0x8035f7ff12e10c25L } },\n    /* 0 << 147 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 147 */\n    { { 0x854d34c77e6c5520L,0xc27df9efdcb9ea58L,0x405f2369d686666dL,\n        0x29d1febf0417aa85L },\n      { 0x9846819e93470afeL,0x3e6a9669e2a27f9eL,0x24d008a2e31e6504L,\n        0xdba7cecf9cb7680aL } },\n    /* 2 << 147 */\n    { { 0xecaff541338d6e43L,0x56f7dd734541d5ccL,0xb5d426de96bc88caL,\n        0x48d94f6b9ed3a2c3L },\n      { 0x6354a3bb2ef8279cL,0xd575465b0b1867f2L,0xef99b0ff95225151L,\n        0xf3e19d88f94500d8L } },\n    /* 3 << 147 */\n    { { 0x92a83268e32dd620L,0x913ec99f627849a2L,0xedd8fdfa2c378882L,\n        0xaf96f33eee6f8cfeL },\n      { 0xc06737e5dc3fa8a5L,0x236bb531b0b03a1dL,0x33e59f2989f037b0L,\n        0x13f9b5a7d9a12a53L } },\n    /* 4 << 147 */\n    { { 0x0d0df6ce51efb310L,0xcb5b2eb4958df5beL,0xd6459e2936158e59L,\n        0x82aae2b91466e336L },\n      { 0xfb658a39411aa636L,0x7152ecc5d4c0a933L,0xf10c758a49f026b7L,\n        0xf4837f97cb09311fL } },\n    /* 5 << 147 */\n    { { 0xddfb02c4c753c45fL,0x18ca81b6f9c840feL,0x846fd09ab0f8a3e6L,\n        0xb1162adde7733dbcL },\n      { 0x7070ad20236e3ab6L,0xf88cdaf5b2a56326L,0x05fc8719997cbc7aL,\n        0x442cd4524b665272L } },\n    /* 6 << 147 */\n    { { 0x7807f364b71698f5L,0x6ba418d29f7b605eL,0xfd20b00fa03b2cbbL,\n        0x883eca37da54386fL },\n      { 0xff0be43ff3437f24L,0xe910b432a48bb33cL,0x4963a128329df765L,\n        0xac1dd556be2fe6f7L } },\n    /* 7 << 147 */\n    { { 0x557610f924a0a3fcL,0x38e17bf4e881c3f9L,0x6ba84fafed0dac99L,\n        0xd4a222c359eeb918L },\n      { 0xc79c1dbe13f542b6L,0x1fc65e0de425d457L,0xeffb754f1debb779L,\n        0x638d8fd09e08af60L } },\n    /* 8 << 147 */\n    { { 0x994f523a626332d5L,0x7bc388335561bb44L,0x005ed4b03d845ea2L,\n        0xd39d3ee1c2a1f08aL },\n      { 0x6561fdd3e7676b0dL,0x620e35fffb706017L,0x36ce424ff264f9a8L,\n        0xc4c3419fda2681f7L } },\n    /* 9 << 147 */\n    { { 0xfb6afd2f69beb6e8L,0x3a50b9936d700d03L,0xc840b2ad0c83a14fL,\n        0x573207be54085befL },\n      { 0x5af882e309fe7e5bL,0x957678a43b40a7e1L,0x172d4bdd543056e2L,\n        0x9c1b26b40df13c0aL } },\n    /* 10 << 147 */\n    { { 0x1c30861cf405ff06L,0xebac86bd486e828bL,0xe791a971636933fcL,\n        0x50e7c2be7aeee947L },\n      { 0xc3d4a095fa90d767L,0xae60eb7be670ab7bL,0x17633a64397b056dL,\n        0x93a21f33105012aaL } },\n    /* 11 << 147 */\n    { { 0x663c370babb88643L,0x91df36d722e21599L,0x183ba8358b761671L,\n        0x381eea1d728f3bf1L },\n      { 0xb9b2f1ba39966e6cL,0x7c464a28e7295492L,0x0fd5f70a09b26b7fL,\n        0xa9aba1f9fbe009dfL } },\n    /* 12 << 147 */\n    { { 0x857c1f22369b87adL,0x3c00e5d932fca556L,0x1ad74cab90b06466L,\n        0xa7112386550faaf2L },\n      { 0x7435e1986d9bd5f5L,0x2dcc7e3859c3463fL,0xdc7df748ca7bd4b2L,\n        0x13cd4c089dec2f31L } },\n    /* 13 << 147 */\n    { { 0x0d3b5df8e3237710L,0x0dadb26ecbd2f7b0L,0x9f5966abe4aa082bL,\n        0x666ec8de350e966eL },\n      { 0x1bfd1ed5ee524216L,0xcd93c59b41dab0b6L,0x658a8435d186d6baL,\n        0x1b7d34d2159d1195L } },\n    /* 14 << 147 */\n    { { 0x5936e46022caf46bL,0x6a45dd8f9a96fe4fL,0xf7925434b98f474eL,\n        0x414104120053ef15L },\n      { 0x71cf8d1241de97bfL,0xb8547b61bd80bef4L,0xb47d3970c4db0037L,\n        0xf1bcd328fef20dffL } },\n    /* 15 << 147 */\n    { { 0x31a92e0910caad67L,0x1f5919605531a1e1L,0x3bb852e05f4fc840L,\n        0x63e297ca93a72c6cL },\n      { 0x3c2b0b2e49abad67L,0x6ec405fced3db0d9L,0xdc14a5307fef1d40L,\n        0xccd19846280896fcL } },\n    /* 16 << 147 */\n    { { 0x00f831769bb81648L,0xd69eb485653120d0L,0xd17d75f44ccabc62L,\n        0x34a07f82b749fcb1L },\n      { 0x2c3af787bbfb5554L,0xb06ed4d062e283f8L,0x5722889fa19213a0L,\n        0x162b085edcf3c7b4L } },\n    /* 17 << 147 */\n    { { 0xbcaecb31e0dd3ecaL,0xc6237fbce52f13a5L,0xcc2b6b0327bac297L,\n        0x2ae1cac5b917f54aL },\n      { 0x474807d47845ae4fL,0xfec7dd92ce5972e0L,0xc3bd25411d7915bbL,\n        0x66f85dc4d94907caL } },\n    /* 18 << 147 */\n    { { 0xd981b888bdbcf0caL,0xd75f5da6df279e9fL,0x128bbf247054e934L,\n        0x3c6ff6e581db134bL },\n      { 0x795b7cf4047d26e4L,0xf370f7b85049ec37L,0xc6712d4dced945afL,\n        0xdf30b5ec095642bcL } },\n    /* 19 << 147 */\n    { { 0x9b034c624896246eL,0x5652c016ee90bbd1L,0xeb38636f87fedb73L,\n        0x5e32f8470135a613L },\n      { 0x0703b312cf933c83L,0xd05bb76e1a7f47e6L,0x825e4f0c949c2415L,\n        0x569e56227250d6f8L } },\n    /* 20 << 147 */\n    { { 0xbbe9eb3a6568013eL,0x8dbd203f22f243fcL,0x9dbd7694b342734aL,\n        0x8f6d12f846afa984L },\n      { 0xb98610a2c9eade29L,0xbab4f32347dd0f18L,0x5779737b671c0d46L,\n        0x10b6a7c6d3e0a42aL } },\n    /* 21 << 147 */\n    { { 0xfb19ddf33035b41cL,0xd336343f99c45895L,0x61fe493854c857e5L,\n        0xc4d506beae4e57d5L },\n      { 0x3cd8c8cbbbc33f75L,0x7281f08a9262c77dL,0x083f4ea6f11a2823L,\n        0x8895041e9fba2e33L } },\n    /* 22 << 147 */\n    { { 0xfcdfea499c438edfL,0x7678dcc391edba44L,0xf07b3b87e2ba50f0L,\n        0xc13888ef43948c1bL },\n      { 0xc2135ad41140af42L,0x8e5104f3926ed1a7L,0xf24430cb88f6695fL,\n        0x0ce0637b6d73c120L } },\n    /* 23 << 147 */\n    { { 0xb2db01e6fe631e8fL,0x1c5563d7d7bdd24bL,0x8daea3ba369ad44fL,\n        0x000c81b68187a9f9L },\n      { 0x5f48a951aae1fd9aL,0xe35626c78d5aed8aL,0x209527630498c622L,\n        0x76d17634773aa504L } },\n    /* 24 << 147 */\n    { { 0x36d90ddaeb300f7aL,0x9dcf7dfcedb5e801L,0x645cb26874d5244cL,\n        0xa127ee79348e3aa2L },\n      { 0x488acc53575f1dbbL,0x95037e8580e6161eL,0x57e59283292650d0L,\n        0xabe67d9914938216L } },\n    /* 25 << 147 */\n    { { 0x3c7f944b3f8e1065L,0xed908cb6330e8924L,0x08ee8fd56f530136L,\n        0x2227b7d5d7ffc169L },\n      { 0x4f55c893b5cd6dd5L,0x82225e11a62796e8L,0x5c6cead1cb18e12cL,\n        0x4381ae0c84f5a51aL } },\n    /* 26 << 147 */\n    { { 0x345913d37fafa4c8L,0x3d9180820491aac0L,0x9347871f3e69264cL,\n        0xbea9dd3cb4f4f0cdL },\n      { 0xbda5d0673eadd3e7L,0x0033c1b80573bcd8L,0x255893795da2486cL,\n        0xcb89ee5b86abbee7L } },\n    /* 27 << 147 */\n    { { 0x8fe0a8f322532e5dL,0xb6410ff0727dfc4cL,0x619b9d58226726dbL,\n        0x5ec256697a2b2dc7L },\n      { 0xaf4d2e064c3beb01L,0x852123d07acea556L,0x0e9470faf783487aL,\n        0x75a7ea045664b3ebL } },\n    /* 28 << 147 */\n    { { 0x4ad78f356798e4baL,0x9214e6e5c7d0e091L,0xc420b488b1290403L,\n        0x64049e0afc295749L },\n      { 0x03ef5af13ae9841fL,0xdbe4ca19b0b662a6L,0x46845c5ffa453458L,\n        0xf8dabf1910b66722L } },\n    /* 29 << 147 */\n    { { 0xb650f0aacce2793bL,0x71db851ec5ec47c1L,0x3eb78f3e3b234fa9L,\n        0xb0c60f35fc0106ceL },\n      { 0x05427121774eadbdL,0x25367fafce323863L,0x7541b5c9cd086976L,\n        0x4ff069e2dc507ad1L } },\n    /* 30 << 147 */\n    { { 0x741452568776e667L,0x6e76142cb23c6bb5L,0xdbf307121b3a8a87L,\n        0x60e7363e98450836L },\n      { 0x5741450eb7366d80L,0xe4ee14ca4837dbdfL,0xa765eb9b69d4316fL,\n        0x04548dca8ef43825L } },\n    /* 31 << 147 */\n    { { 0x9c9f4e4c5ae888ebL,0x733abb5156e9ac99L,0xdaad3c20ba6ac029L,\n        0x9b8dd3d32ba3e38eL },\n      { 0xa9bb4c920bc5d11aL,0xf20127a79c5f88a3L,0x4f52b06e161d3cb8L,\n        0x26c1ff096afaf0a6L } },\n    /* 32 << 147 */\n    { { 0x32670d2f7189e71fL,0xc64387485ecf91e7L,0x15758e57db757a21L,\n        0x427d09f8290a9ce5L },\n      { 0x846a308f38384a7aL,0xaac3acb4b0732b99L,0x9e94100917845819L,\n        0x95cba111a7ce5e03L } },\n    /* 33 << 147 */\n    { { 0x6f3d4f7fb00009c4L,0xb8396c278ff28b5fL,0xb1a9ae431c97975dL,\n        0x9d7ba8afe5d9fed5L },\n      { 0x338cf09f34f485b6L,0xbc0ddacc64122516L,0xa450da1205d471feL,\n        0x4c3a6250628dd8c9L } },\n    /* 34 << 147 */\n    { { 0x69c7d103d1295837L,0xa2893e503807eb2fL,0xd6e1e1debdb41491L,\n        0xc630745b5e138235L },\n      { 0xc892109e48661ae1L,0x8d17e7ebea2b2674L,0x00ec0f87c328d6b5L,\n        0x6d858645f079ff9eL } },\n    /* 35 << 147 */\n    { { 0x6cdf243e19115eadL,0x1ce1393e4bac4fcfL,0x2c960ed09c29f25bL,\n        0x59be4d8e9d388a05L },\n      { 0x0d46e06cd0def72bL,0xb923db5de0342748L,0xf7d3aacd936d4a3dL,\n        0x558519cc0b0b099eL } },\n    /* 36 << 147 */\n    { { 0x3ea8ebf8827097efL,0x259353dbd054f55dL,0x84c89abc6d2ed089L,\n        0x5c548b698e096a7cL },\n      { 0xd587f616994b995dL,0x4d1531f6a5845601L,0x792ab31e451fd9f0L,\n        0xc8b57bb265adf6caL } },\n    /* 37 << 147 */\n    { { 0x68440fcb1cd5ad73L,0xb9c860e66144da4fL,0x2ab286aa8462beb8L,\n        0xcc6b8fffef46797fL },\n      { 0xac820da420c8a471L,0x69ae05a177ff7fafL,0xb9163f39bfb5da77L,\n        0xbd03e5902c73ab7aL } },\n    /* 38 << 147 */\n    { { 0x7e862b5eb2940d9eL,0x3c663d864b9af564L,0xd8309031bde3033dL,\n        0x298231b2d42c5bc6L },\n      { 0x42090d2c552ad093L,0xa4799d1cff854695L,0x0a88b5d6d31f0d00L,\n        0xf8b40825a2f26b46L } },\n    /* 39 << 147 */\n    { { 0xec29b1edf1bd7218L,0xd491c53b4b24c86eL,0xd2fe588f3395ea65L,\n        0x6f3764f74456ef15L },\n      { 0xdb43116dcdc34800L,0xcdbcd456c1e33955L,0xefdb554074ab286bL,\n        0x948c7a51d18c5d7cL } },\n    /* 40 << 147 */\n    { { 0xeb81aa377378058eL,0x41c746a104411154L,0xa10c73bcfb828ac7L,\n        0x6439be919d972b29L },\n      { 0x4bf3b4b043a2fbadL,0x39e6dadf82b5e840L,0x4f7164086397bd4cL,\n        0x0f7de5687f1eeccbL } },\n    /* 41 << 147 */\n    { { 0x5865c5a1d2ffbfc1L,0xf74211fa4ccb6451L,0x66368a88c0b32558L,\n        0x5b539dc29ad7812eL },\n      { 0x579483d02f3af6f6L,0x5213207899934eceL,0x50b9650fdcc9e983L,\n        0xca989ec9aee42b8aL } },\n    /* 42 << 147 */\n    { { 0x6a44c829d6f62f99L,0x8f06a3094c2a7c0cL,0x4ea2b3a098a0cb0aL,\n        0x5c547b70beee8364L },\n      { 0x461d40e1682afe11L,0x9e0fc77a7b41c0a8L,0x79e4aefde20d5d36L,\n        0x2916e52032dd9f63L } },\n    /* 43 << 147 */\n    { { 0xf59e52e83f883fafL,0x396f96392b868d35L,0xc902a9df4ca19881L,\n        0x0fc96822db2401a6L },\n      { 0x4123758766f1c68dL,0x10fc6de3fb476c0dL,0xf8b6b579841f5d90L,\n        0x2ba8446cfa24f44aL } },\n    /* 44 << 147 */\n    { { 0xa237b920ef4a9975L,0x60bb60042330435fL,0xd6f4ab5acfb7e7b5L,\n        0xb2ac509783435391L },\n      { 0xf036ee2fb0d1ea67L,0xae779a6a74c56230L,0x59bff8c8ab838ae6L,\n        0xcd83ca999b38e6f0L } },\n    /* 45 << 147 */\n    { { 0xbb27bef5e33deed3L,0xe6356f6f001892a8L,0xbf3be6cc7adfbd3eL,\n        0xaecbc81c33d1ac9dL },\n      { 0xe4feb909e6e861dcL,0x90a247a453f5f801L,0x01c50acb27346e57L,\n        0xce29242e461acc1bL } },\n    /* 46 << 147 */\n    { { 0x04dd214a2f998a91L,0x271ee9b1d4baf27bL,0x7e3027d1e8c26722L,\n        0x21d1645c1820dce5L },\n      { 0x086f242c7501779cL,0xf0061407fa0e8009L,0xf23ce47760187129L,\n        0x05bbdedb0fde9bd0L } },\n    /* 47 << 147 */\n    { { 0x682f483225d98473L,0xf207fe855c658427L,0xb6fdd7ba4166ffa1L,\n        0x0c3140569eed799dL },\n      { 0x0db8048f4107e28fL,0x74ed387141216840L,0x74489f8f56a3c06eL,\n        0x1e1c005b12777134L } },\n    /* 48 << 147 */\n    { { 0xdb332a73f37ec3c3L,0xc65259bddd59eba0L,0x2291709cdb4d3257L,\n        0x9a793b25bd389390L },\n      { 0xf39fe34be43756f0L,0x2f76bdce9afb56c9L,0x9f37867a61208b27L,\n        0xea1d4307089972c3L } },\n    /* 49 << 147 */\n    { { 0x8c5953308bdf623aL,0x5f5accda8441fb7dL,0xfafa941832ddfd95L,\n        0x6ad40c5a0fde9be7L },\n      { 0x43faba89aeca8709L,0xc64a7cf12c248a9dL,0x1662025272637a76L,\n        0xaee1c79122b8d1bbL } },\n    /* 50 << 147 */\n    { { 0xf0f798fd21a843b2L,0x56e4ed4d8d005cb1L,0x355f77801f0d8abeL,\n        0x197b04cf34522326L },\n      { 0x41f9b31ffd42c13fL,0x5ef7feb2b40f933dL,0x27326f425d60bad4L,\n        0x027ecdb28c92cf89L } },\n    /* 51 << 147 */\n    { { 0x04aae4d14e3352feL,0x08414d2f73591b90L,0x5ed6124eb7da7d60L,\n        0xb985b9314d13d4ecL },\n      { 0xa592d3ab96bf36f9L,0x012dbed5bbdf51dfL,0xa57963c0df6c177dL,\n        0x010ec86987ca29cfL } },\n    /* 52 << 147 */\n    { { 0xba1700f6bf926dffL,0x7c9fdbd1f4bf6bc2L,0xdc18dc8f64da11f5L,\n        0xa6074b7ad938ae75L },\n      { 0x14270066e84f44a4L,0x99998d38d27b954eL,0xc1be8ab2b4f38e9aL,\n        0x8bb55bbf15c01016L } },\n    /* 53 << 147 */\n    { { 0xf73472b40ea2ab30L,0xd365a340f73d68ddL,0xc01a716819c2e1ebL,\n        0x32f49e3734061719L },\n      { 0xb73c57f101d8b4d6L,0x03c8423c26b47700L,0x321d0bc8a4d8826aL,\n        0x6004213c4bc0e638L } },\n    /* 54 << 147 */\n    { { 0xf78c64a1c1c06681L,0x16e0a16fef018e50L,0x31cbdf91db42b2b3L,\n        0xf8f4ffcee0d36f58L },\n      { 0xcdcc71cd4cc5e3e0L,0xd55c7cfaa129e3e0L,0xccdb6ba00fb2cbf1L,\n        0x6aba0005c4bce3cbL } },\n    /* 55 << 147 */\n    { { 0x501cdb30d232cfc4L,0x9ddcf12ed58a3cefL,0x02d2cf9c87e09149L,\n        0xdc5d7ec72c976257L },\n      { 0x6447986e0b50d7ddL,0x88fdbaf7807f112aL,0x58c9822ab00ae9f6L,\n        0x6abfb9506d3d27e0L } },\n    /* 56 << 147 */\n    { { 0xd0a744878a429f4fL,0x0649712bdb516609L,0xb826ba57e769b5dfL,\n        0x82335df21fc7aaf2L },\n      { 0x2389f0675c93d995L,0x59ac367a68677be6L,0xa77985ff21d9951bL,\n        0x038956fb85011cceL } },\n    /* 57 << 147 */\n    { { 0x608e48cbbb734e37L,0xc08c0bf22be5b26fL,0x17bbdd3bf9b1a0d9L,\n        0xeac7d89810483319L },\n      { 0xc95c4bafbc1a6deaL,0xfdd0e2bf172aafdbL,0x40373cbc8235c41aL,\n        0x14303f21fb6f41d5L } },\n    /* 58 << 147 */\n    { { 0xba0636210408f237L,0xcad3b09aecd2d1edL,0x4667855a52abb6a2L,\n        0xba9157dcaa8b417bL },\n      { 0xfe7f35074f013efbL,0x1b112c4baa38c4a2L,0xa1406a609ba64345L,\n        0xe53cba336993c80bL } },\n    /* 59 << 147 */\n    { { 0x45466063ded40d23L,0x3d5f1f4d54908e25L,0x9ebefe62403c3c31L,\n        0x274ea0b50672a624L },\n      { 0xff818d99451d1b71L,0x80e826438f79cf79L,0xa165df1373ce37f5L,\n        0xa744ef4ffe3a21fdL } },\n    /* 60 << 147 */\n    { { 0x73f1e7f5cf551396L,0xc616898e868c676bL,0x671c28c78c442c36L,\n        0xcfe5e5585e0a317dL },\n      { 0x1242d8187051f476L,0x56fad2a614f03442L,0x262068bc0a44d0f6L,\n        0xdfa2cd6ece6edf4eL } },\n    /* 61 << 147 */\n    { { 0x0f43813ad15d1517L,0x61214cb2377d44f5L,0xd399aa29c639b35fL,\n        0x42136d7154c51c19L },\n      { 0x9774711b08417221L,0x0a5546b352545a57L,0x80624c411150582dL,\n        0x9ec5c418fbc555bcL } },\n    /* 62 << 147 */\n    { { 0x2c87dcad771849f1L,0xb0c932c501d7bf6fL,0x6aa5cd3e89116eb2L,\n        0xd378c25a51ca7bd3L },\n      { 0xc612a0da9e6e3e31L,0x0417a54db68ad5d0L,0x00451e4a22c6edb8L,\n        0x9fbfe019b42827ceL } },\n    /* 63 << 147 */\n    { { 0x2fa92505ba9384a2L,0x21b8596e64ad69c1L,0x8f4fcc49983b35a6L,\n        0xde09376072754672L },\n      { 0x2f14ccc8f7bffe6dL,0x27566bff5d94263dL,0xb5b4e9c62df3ec30L,\n        0x94f1d7d53e6ea6baL } },\n    /* 64 << 147 */\n    { { 0x97b7851aaaca5e9bL,0x518aa52156713b97L,0x3357e8c7150a61f6L,\n        0x7842e7e2ec2c2b69L },\n      { 0x8dffaf656868a548L,0xd963bd82e068fc81L,0x64da5c8b65917733L,\n        0x927090ff7b247328L } },\n    /* 0 << 154 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 154 */\n    { { 0x214bc9a7d298c241L,0xe3b697ba56807cfdL,0xef1c78024564eadbL,\n        0xdde8cdcfb48149c5L },\n      { 0x946bf0a75a4d2604L,0x27154d7f6c1538afL,0x95cc9230de5b1fccL,\n        0xd88519e966864f82L } },\n    /* 2 << 154 */\n    { { 0xb828dd1a7cb1282cL,0xa08d7626be46973aL,0x6baf8d40e708d6b2L,\n        0x72571fa14daeb3f3L },\n      { 0x85b1732ff22dfd98L,0x87ab01a70087108dL,0xaaaafea85988207aL,\n        0xccc832f869f00755L } },\n    /* 3 << 154 */\n    { { 0x964d950e36ff3bf0L,0x8ad20f6ff0b34638L,0x4d9177b3b5d7585fL,\n        0xcf839760ef3f019fL },\n      { 0x582fc5b38288c545L,0x2f8e4e9b13116bd1L,0xf91e1b2f332120efL,\n        0xcf5687242a17dd23L } },\n    /* 4 << 154 */\n    { { 0x488f1185ca8d9d1aL,0xadf2c77dd987ded2L,0x5f3039f060c46124L,\n        0xe5d70b7571e095f4L },\n      { 0x82d586506260e70fL,0x39d75ea7f750d105L,0x8cf3d0b175bac364L,\n        0xf3a7564d21d01329L } },\n    /* 5 << 154 */\n    { { 0x182f04cd2f52d2a7L,0x4fde149ae2df565aL,0xb80c5eeca79fb2f7L,\n        0xab491d7b22ddc897L },\n      { 0x99d76c18c6312c7fL,0xca0d5f3d6aa41a57L,0x71207325d15363a0L,\n        0xe82aa265beb252c2L } },\n    /* 6 << 154 */\n    { { 0x94ab4700ec3128c2L,0x6c76d8628e383f49L,0xdc36b150c03024ebL,\n        0xfb43947753daac69L },\n      { 0xfc68764a8dc79623L,0x5b86995db440fbb2L,0xd66879bfccc5ee0dL,\n        0x0522894295aa8bd3L } },\n    /* 7 << 154 */\n    { { 0xb51a40a51e6a75c1L,0x24327c760ea7d817L,0x0663018207774597L,\n        0xd6fdbec397fa7164L },\n      { 0x20c99dfb13c90f48L,0xd6ac5273686ef263L,0xc6a50bdcfef64eebL,\n        0xcd87b28186fdfc32L } },\n    /* 8 << 154 */\n    { { 0xb24aa43e3fcd3efcL,0xdd26c034b8088e9aL,0xa5ef4dc9bd3d46eaL,\n        0xa2f99d588a4c6a6fL },\n      { 0xddabd3552f1da46cL,0x72c3f8ce1afacdd1L,0xd90c4eee92d40578L,\n        0xd28bb41fca623b94L } },\n    /* 9 << 154 */\n    { { 0x50fc0711745edc11L,0x9dd9ad7d3dc87558L,0xce6931fbb49d1e64L,\n        0x6c77a0a2c98bd0f9L },\n      { 0x62b9a6296baf7cb1L,0xcf065f91ccf72d22L,0x7203cce979639071L,\n        0x09ae4885f9cb732fL } },\n    /* 10 << 154 */\n    { { 0x5e7c3becee8314f3L,0x1c068aeddbea298fL,0x08d381f17c80acecL,\n        0x03b56be8e330495bL },\n      { 0xaeffb8f29222882dL,0x95ff38f6c4af8bf7L,0x50e32d351fc57d8cL,\n        0x6635be5217b444f0L } },\n    /* 11 << 154 */\n    { { 0x04d15276a5177900L,0x4e1dbb47f6858752L,0x5b475622c615796cL,\n        0xa6fa0387691867bfL },\n      { 0xed7f5d562844c6d0L,0xc633cf9b03a2477dL,0xf6be5c402d3721d6L,\n        0xaf312eb7e9fd68e6L } },\n    /* 12 << 154 */\n    { { 0x242792d2e7417ce1L,0xff42bc71970ee7f5L,0x1ff4dc6d5c67a41eL,\n        0x77709b7b20882a58L },\n      { 0x3554731dbe217f2cL,0x2af2a8cd5bb72177L,0x58eee769591dd059L,\n        0xbb2930c94bba6477L } },\n    /* 13 << 154 */\n    { { 0x863ee0477d930cfcL,0x4c262ad1396fd1f4L,0xf4765bc8039af7e1L,\n        0x2519834b5ba104f6L },\n      { 0x7cd61b4cd105f961L,0xa5415da5d63bca54L,0x778280a088a1f17cL,\n        0xc49689492329512cL } },\n    /* 14 << 154 */\n    { { 0x174a9126cecdaa7aL,0xfc8c7e0e0b13247bL,0x29c110d23484c1c4L,\n        0xf8eb8757831dfc3bL },\n      { 0x022f0212c0067452L,0x3f6f69ee7b9b926cL,0x09032da0ef42daf4L,\n        0x79f00ade83f80de4L } },\n    /* 15 << 154 */\n    { { 0x6210db7181236c97L,0x74f7685b3ee0781fL,0x4df7da7ba3e41372L,\n        0x2aae38b1b1a1553eL },\n      { 0x1688e222f6dd9d1bL,0x576954485b8b6487L,0x478d21274b2edeaaL,\n        0xb2818fa51e85956aL } },\n    /* 16 << 154 */\n    { { 0x1e6adddaf176f2c0L,0x01ca4604e2572658L,0x0a404ded85342ffbL,\n        0x8cf60f96441838d6L },\n      { 0x9bbc691cc9071c4aL,0xfd58874434442803L,0x97101c85809c0d81L,\n        0xa7fb754c8c456f7fL } },\n    /* 17 << 154 */\n    { { 0xc95f3c5cd51805e1L,0xab4ccd39b299dca8L,0x3e03d20b47eaf500L,\n        0xfa3165c1d7b80893L },\n      { 0x005e8b54e160e552L,0xdc4972ba9019d11fL,0x21a6972e0c9a4a7aL,\n        0xa52c258f37840fd7L } },\n    /* 18 << 154 */\n    { { 0xf8559ff4c1e99d81L,0x08e1a7d6a3c617c0L,0xb398fd43248c6ba7L,\n        0x6ffedd91d1283794L },\n      { 0x8a6a59d2d629d208L,0xa9d141d53490530eL,0x42f6fc1838505989L,\n        0x09bf250d479d94eeL } },\n    /* 19 << 154 */\n    { { 0x223ad3b1b3822790L,0x6c5926c093b8971cL,0x609efc7e75f7fa62L,\n        0x45d66a6d1ec2d989L },\n      { 0x4422d663987d2792L,0x4a73caad3eb31d2bL,0xf06c2ac1a32cb9e6L,\n        0xd9445c5f91aeba84L } },\n    /* 20 << 154 */\n    { { 0x6af7a1d5af71013fL,0xe68216e50bedc946L,0xf4cba30bd27370a0L,\n        0x7981afbf870421ccL },\n      { 0x02496a679449f0e1L,0x86cfc4be0a47edaeL,0x3073c936b1feca22L,\n        0xf569461203f8f8fbL } },\n    /* 21 << 154 */\n    { { 0xd063b723901515eaL,0x4c6c77a5749cf038L,0x6361e360ab9e5059L,\n        0x596cf171a76a37c0L },\n      { 0x800f53fa6530ae7aL,0x0f5e631e0792a7a6L,0x5cc29c24efdb81c9L,\n        0xa269e8683f9c40baL } },\n    /* 22 << 154 */\n    { { 0xec14f9e12cb7191eL,0x78ea1bd8e5b08ea6L,0x3c65aa9b46332bb9L,\n        0x84cc22b3bf80ce25L },\n      { 0x0098e9e9d49d5bf1L,0xcd4ec1c619087da4L,0x3c9d07c5aef6e357L,\n        0x839a02689f8f64b8L } },\n    /* 23 << 154 */\n    { { 0xc5e9eb62c6d8607fL,0x759689f56aa995e4L,0x70464669bbb48317L,\n        0x921474bfe402417dL },\n      { 0xcabe135b2a354c8cL,0xd51e52d2812fa4b5L,0xec74109653311fe8L,\n        0x4f774535b864514bL } },\n    /* 24 << 154 */\n    { { 0xbcadd6715bde48f8L,0xc97038732189bc7dL,0x5d45299ec709ee8aL,\n        0xd1287ee2845aaff8L },\n      { 0x7d1f8874db1dbf1fL,0xea46588b990c88d6L,0x60ba649a84368313L,\n        0xd5fdcbce60d543aeL } },\n    /* 25 << 154 */\n    { { 0x90b46d43810d5ab0L,0x6739d8f904d7e5ccL,0x021c1a580d337c33L,\n        0x00a6116268e67c40L },\n      { 0x95ef413b379f0a1fL,0xfe126605e9e2ab95L,0x67578b852f5f199cL,\n        0xf5c003292cb84913L } },\n    /* 26 << 154 */\n    { { 0xf795643037577dd8L,0x83b82af429c5fe88L,0x9c1bea26cdbdc132L,\n        0x589fa0869c04339eL },\n      { 0x033e9538b13799dfL,0x85fa8b21d295d034L,0xdf17f73fbd9ddccaL,\n        0xf32bd122ddb66334L } },\n    /* 27 << 154 */\n    { { 0x55ef88a7858b044cL,0x1f0d69c25aa9e397L,0x55fd9cc340d85559L,\n        0xc774df727785ddb2L },\n      { 0x5dcce9f6d3bd2e1cL,0xeb30da20a85dfed0L,0x5ed7f5bbd3ed09c4L,\n        0x7d42a35c82a9c1bdL } },\n    /* 28 << 154 */\n    { { 0xcf3de9959890272dL,0x75f3432a3e713a10L,0x5e13479fe28227b8L,\n        0xb8561ea9fefacdc8L },\n      { 0xa6a297a08332aafdL,0x9b0d8bb573809b62L,0xd2fa1cfd0c63036fL,\n        0x7a16eb55bd64bda8L } },\n    /* 29 << 154 */\n    { { 0x3f5cf5f678e62ddcL,0x2267c45407fd752bL,0x5e361b6b5e437bbeL,\n        0x95c595018354e075L },\n      { 0xec725f85f2b254d9L,0x844b617d2cb52b4eL,0xed8554f5cf425fb5L,\n        0xab67703e2af9f312L } },\n    /* 30 << 154 */\n    { { 0x4cc34ec13cf48283L,0xb09daa259c8a705eL,0xd1e9d0d05b7d4f84L,\n        0x4df6ef64db38929dL },\n      { 0xe16b0763aa21ba46L,0xc6b1d178a293f8fbL,0x0ff5b602d520aabfL,\n        0x94d671bdc339397aL } },\n    /* 31 << 154 */\n    { { 0x7c7d98cf4f5792faL,0x7c5e0d6711215261L,0x9b19a631a7c5a6d4L,\n        0xc8511a627a45274dL },\n      { 0x0c16621ca5a60d99L,0xf7fbab88cf5e48cbL,0xab1e6ca2f7ddee08L,\n        0x83bd08cee7867f3cL } },\n    /* 32 << 154 */\n    { { 0xf7e48e8a2ac13e27L,0x4494f6df4eb1a9f5L,0xedbf84eb981f0a62L,\n        0x49badc32536438f0L },\n      { 0x50bea541004f7571L,0xbac67d10df1c94eeL,0x253d73a1b727bc31L,\n        0xb3d01cf230686e28L } },\n    /* 33 << 154 */\n    { { 0x51b77b1b55fd0b8bL,0xa099d183feec3173L,0x202b1fb7670e72b7L,\n        0xadc88b33a8e1635fL },\n      { 0x34e8216af989d905L,0xc2e68d2029b58d01L,0x11f81c926fe55a93L,\n        0x15f1462a8f296f40L } },\n    /* 34 << 154 */\n    { { 0x1915d375ea3d62f2L,0xa17765a301c8977dL,0x7559710ae47b26f6L,\n        0xe0bd29c8535077a5L },\n      { 0x615f976d08d84858L,0x370dfe8569ced5c1L,0xbbc7503ca734fa56L,\n        0xfbb9f1ec91ac4574L } },\n    /* 35 << 154 */\n    { { 0x95d7ec53060dd7efL,0xeef2dacd6e657979L,0x54511af3e2a08235L,\n        0x1e324aa41f4aea3dL },\n      { 0x550e7e71e6e67671L,0xbccd5190bf52faf7L,0xf880d316223cc62aL,\n        0x0d402c7e2b32eb5dL } },\n    /* 36 << 154 */\n    { { 0xa40bc039306a5a3bL,0x4e0a41fd96783a1bL,0xa1e8d39a0253cdd4L,\n        0x6480be26c7388638L },\n      { 0xee365e1d2285f382L,0x188d8d8fec0b5c36L,0x34ef1a481f0f4d82L,\n        0x1a8f43e1a487d29aL } },\n    /* 37 << 154 */\n    { { 0x8168226d77aefb3aL,0xf69a751e1e72c253L,0x8e04359ae9594df1L,\n        0x475ffd7dd14c0467L },\n      { 0xb5a2c2b13844e95cL,0x85caf647dd12ef94L,0x1ecd2a9ff1063d00L,\n        0x1dd2e22923843311L } },\n    /* 38 << 154 */\n    { { 0x38f0e09d73d17244L,0x3ede77468fc653f1L,0xae4459f5dc20e21cL,\n        0x00db2ffa6a8599eaL },\n      { 0x11682c3930cfd905L,0x4934d074a5c112a6L,0xbdf063c5568bfe95L,\n        0x779a440a016c441aL } },\n    /* 39 << 154 */\n    { { 0x0c23f21897d6fbdcL,0xd3a5cd87e0776aacL,0xcee37f72d712e8dbL,\n        0xfb28c70d26f74e8dL },\n      { 0xffe0c728b61301a0L,0xa6282168d3724354L,0x7ff4cb00768ffedcL,\n        0xc51b308803b02de9L } },\n    /* 40 << 154 */\n    { { 0xa5a8147c3902dda5L,0x35d2f706fe6973b4L,0x5ac2efcfc257457eL,\n        0x933f48d48700611bL },\n      { 0xc365af884912beb2L,0x7f5a4de6162edf94L,0xc646ba7c0c32f34bL,\n        0x632c6af3b2091074L } },\n    /* 41 << 154 */\n    { { 0x58d4f2e3753e43a9L,0x70e1d21724d4e23fL,0xb24bf729afede6a6L,\n        0x7f4a94d8710c8b60L },\n      { 0xaad90a968d4faa6aL,0xd9ed0b32b066b690L,0x52fcd37b78b6dbfdL,\n        0x0b64615e8bd2b431L } },\n    /* 42 << 154 */\n    { { 0x228e2048cfb9fad5L,0xbeaa386d240b76bdL,0x2d6681c890dad7bcL,\n        0x3e553fc306d38f5eL },\n      { 0xf27cdb9b9d5f9750L,0x3e85c52ad28c5b0eL,0x190795af5247c39bL,\n        0x547831ebbddd6828L } },\n    /* 43 << 154 */\n    { { 0xf327a2274a82f424L,0x36919c787e47f89dL,0xe478391943c7392cL,\n        0xf101b9aa2316fefeL },\n      { 0xbcdc9e9c1c5009d2L,0xfb55ea139cd18345L,0xf5b5e231a3ce77c7L,\n        0xde6b4527d2f2cb3dL } },\n    /* 44 << 154 */\n    { { 0x10f6a3339bb26f5fL,0x1e85db8e044d85b6L,0xc3697a0894197e54L,\n        0x65e18cc0a7cb4ea8L },\n      { 0xa38c4f50a471fe6eL,0xf031747a2f13439cL,0x53c4a6bac007318bL,\n        0xa8da3ee51deccb3dL } },\n    /* 45 << 154 */\n    { { 0x0555b31c558216b1L,0x90c7810c2f79e6c2L,0x9b669f4dfe8eed3cL,\n        0x70398ec8e0fac126L },\n      { 0xa96a449ef701b235L,0x0ceecdb3eb94f395L,0x285fc368d0cb7431L,\n        0x0d37bb5216a18c64L } },\n    /* 46 << 154 */\n    { { 0x05110d38b880d2ddL,0xa60f177b65930d57L,0x7da34a67f36235f5L,\n        0x47f5e17c183816b9L },\n      { 0xc7664b57db394af4L,0x39ba215d7036f789L,0x46d2ca0e2f27b472L,\n        0xc42647eef73a84b7L } },\n    /* 47 << 154 */\n    { { 0x44bc754564488f1dL,0xaa922708f4cf85d5L,0x721a01d553e4df63L,\n        0x649c0c515db46cedL },\n      { 0x6bf0d64e3cffcb6cL,0xe3bf93fe50f71d96L,0x75044558bcc194a0L,\n        0x16ae33726afdc554L } },\n    /* 48 << 154 */\n    { { 0xbfc01adf5ca48f3fL,0x64352f06e22a9b84L,0xcee54da1c1099e4aL,\n        0xbbda54e8fa1b89c0L },\n      { 0x166a3df56f6e55fbL,0x1ca44a2420176f88L,0x936afd88dfb7b5ffL,\n        0xe34c24378611d4a0L } },\n    /* 49 << 154 */\n    { { 0x7effbb7586142103L,0x6704ba1b1f34fc4dL,0x7c2a468f10c1b122L,\n        0x36b3a6108c6aace9L },\n      { 0xabfcc0a775a0d050L,0x066f91973ce33e32L,0xce905ef429fe09beL,\n        0x89ee25baa8376351L } },\n    /* 50 << 154 */\n    { { 0x2a3ede22fd29dc76L,0x7fd32ed936f17260L,0x0cadcf68284b4126L,\n        0x63422f08a7951fc8L },\n      { 0x562b24f40807e199L,0xfe9ce5d122ad4490L,0xc2f51b100db2b1b4L,\n        0xeb3613ffe4541d0dL } },\n    /* 51 << 154 */\n    { { 0xbd2c4a052680813bL,0x527aa55d561b08d6L,0xa9f8a40ea7205558L,\n        0xe3eea56f243d0becL },\n      { 0x7b853817a0ff58b3L,0xb67d3f651a69e627L,0x0b76bbb9a869b5d6L,\n        0xa3afeb82546723edL } },\n    /* 52 << 154 */\n    { { 0x5f24416d3e554892L,0x8413b53d430e2a45L,0x99c56aee9032a2a0L,\n        0x09432bf6eec367b1L },\n      { 0x552850c6daf0ecc1L,0x49ebce555bc92048L,0xdfb66ba654811307L,\n        0x1b84f7976f298597L } },\n    /* 53 << 154 */\n    { { 0x795904818d1d7a0dL,0xd9fabe033a6fa556L,0xa40f9c59ba9e5d35L,\n        0xcb1771c1f6247577L },\n      { 0x542a47cae9a6312bL,0xa34b3560552dd8c5L,0xfdf94de00d794716L,\n        0xd46124a99c623094L } },\n    /* 54 << 154 */\n    { { 0x56b7435d68afe8b4L,0x27f205406c0d8ea1L,0x12b77e1473186898L,\n        0xdbc3dd467479490fL },\n      { 0x951a9842c03b0c05L,0x8b1b3bb37921bc96L,0xa573b3462b202e0aL,\n        0x77e4665d47254d56L } },\n    /* 55 << 154 */\n    { { 0x08b70dfcd23e3984L,0xab86e8bcebd14236L,0xaa3e07f857114ba7L,\n        0x5ac71689ab0ef4f2L },\n      { 0x88fca3840139d9afL,0x72733f8876644af0L,0xf122f72a65d74f4aL,\n        0x13931577a5626c7aL } },\n    /* 56 << 154 */\n    { { 0xd5b5d9eb70f8d5a4L,0x375adde7d7bbb228L,0x31e88b860c1c0b32L,\n        0xd1f568c4173edbaaL },\n      { 0x1592fc835459df02L,0x2beac0fb0fcd9a7eL,0xb0a6fdb81b473b0aL,\n        0xe3224c6f0fe8fc48L } },\n    /* 57 << 154 */\n    { { 0x680bd00ee87edf5bL,0x30385f0220e77cf5L,0xe9ab98c04d42d1b2L,\n        0x72d191d2d3816d77L },\n      { 0x1564daca0917d9e5L,0x394eab591f8fed7fL,0xa209aa8d7fbb3896L,\n        0x5564f3b9be6ac98eL } },\n    /* 58 << 154 */\n    { { 0xead21d05d73654efL,0x68d1a9c413d78d74L,0x61e017086d4973a0L,\n        0x83da350046e6d32aL },\n      { 0x6a3dfca468ae0118L,0xa1b9a4c9d02da069L,0x0b2ff9c7ebab8302L,\n        0x98af07c3944ba436L } },\n    /* 59 << 154 */\n    { { 0x85997326995f0f9fL,0x467fade071b58bc6L,0x47e4495abd625a2bL,\n        0xfdd2d01d33c3b8cdL },\n      { 0x2c38ae28c693f9faL,0x48622329348f7999L,0x97bf738e2161f583L,\n        0x15ee2fa7565e8cc9L } },\n    /* 60 << 154 */\n    { { 0xa1a5c8455777e189L,0xcc10bee0456f2829L,0x8ad95c56da762bd5L,\n        0x152e2214e9d91da8L },\n      { 0x975b0e727cb23c74L,0xfd5d7670a90c66dfL,0xb5b5b8ad225ffc53L,\n        0xab6dff73faded2aeL } },\n    /* 61 << 154 */\n    { { 0xebd567816f4cbe9dL,0x0ed8b2496a574bd7L,0x41c246fe81a881faL,\n        0x91564805c3db9c70L },\n      { 0xd7c12b085b862809L,0x1facd1f155858d7bL,0x7693747caf09e92aL,\n        0x3b69dcba189a425fL } },\n    /* 62 << 154 */\n    { { 0x0be28e9f967365efL,0x57300eb2e801f5c9L,0x93b8ac6ad583352fL,\n        0xa2cf1f89cd05b2b7L },\n      { 0x7c0c9b744dcc40ccL,0xfee38c45ada523fbL,0xb49a4dec1099cc4dL,\n        0x325c377f69f069c6L } },\n    /* 63 << 154 */\n    { { 0xe12458ce476cc9ffL,0x580e0b6cc6d4cb63L,0xd561c8b79072289bL,\n        0x0377f264a619e6daL },\n      { 0x2668536288e591a5L,0xa453a7bd7523ca2bL,0x8a9536d2c1df4533L,\n        0xc8e50f2fbe972f79L } },\n    /* 64 << 154 */\n    { { 0xd433e50f6d3549cfL,0x6f33696ffacd665eL,0x695bfdacce11fcb4L,\n        0x810ee252af7c9860L },\n      { 0x65450fe17159bb2cL,0xf7dfbebe758b357bL,0x2b057e74d69fea72L,\n        0xd485717a92731745L } },\n    /* 0 << 161 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 161 */\n    { { 0x896c42e8ee36860cL,0xdaf04dfd4113c22dL,0x1adbb7b744104213L,\n        0xe5fd5fa11fd394eaL },\n      { 0x68235d941a4e0551L,0x6772cfbe18d10151L,0x276071e309984523L,\n        0xe4e879de5a56ba98L } },\n    /* 2 << 161 */\n    { { 0xaaafafb0285b9491L,0x01a0be881e4c705eL,0xff1d4f5d2ad9caabL,\n        0x6e349a4ac37a233fL },\n      { 0xcf1c12464a1c6a16L,0xd99e6b6629383260L,0xea3d43665f6d5471L,\n        0x36974d04ff8cc89bL } },\n    /* 3 << 161 */\n    { { 0xc26c49a1cfe89d80L,0xb42c026dda9c8371L,0xca6c013adad066d2L,\n        0xfb8f722856a4f3eeL },\n      { 0x08b579ecd850935bL,0x34c1a74cd631e1b3L,0xcb5fe596ac198534L,\n        0x39ff21f6e1f24f25L } },\n    /* 4 << 161 */\n    { { 0x27f29e148f929057L,0x7a64ae06c0c853dfL,0x256cd18358e9c5ceL,\n        0x9d9cce82ded092a5L },\n      { 0xcc6e59796e93b7c7L,0xe1e4709231bb9e27L,0xb70b3083aa9e29a0L,\n        0xbf181a753785e644L } },\n    /* 5 << 161 */\n    { { 0xf53f2c658ead09f7L,0x1335e1d59780d14dL,0x69cc20e0cd1b66bcL,\n        0x9b670a37bbe0bfc8L },\n      { 0xce53dc8128efbeedL,0x0c74e77c8326a6e5L,0x3604e0d2b88e9a63L,\n        0xbab38fca13dc2248L } },\n    /* 6 << 161 */\n    { { 0x8ed6e8c85c0a3f1eL,0xbcad24927c87c37fL,0xfdfb62bb9ee3b78dL,\n        0xeba8e477cbceba46L },\n      { 0x37d38cb0eeaede4bL,0x0bc498e87976deb6L,0xb2944c046b6147fbL,\n        0x8b123f35f71f9609L } },\n    /* 7 << 161 */\n    { { 0xa155dcc7de79dc24L,0xf1168a32558f69cdL,0xbac215950d1850dfL,\n        0x15c8295bb204c848L },\n      { 0xf661aa367d8184ffL,0xc396228e30447bdbL,0x11cd5143bde4a59eL,\n        0xe3a26e3b6beab5e6L } },\n    /* 8 << 161 */\n    { { 0xd3b3a13f1402b9d0L,0x573441c32c7bc863L,0x4b301ec4578c3e6eL,\n        0xc26fc9c40adaf57eL },\n      { 0x96e71bfd7493cea3L,0xd05d4b3f1af81456L,0xdaca2a8a6a8c608fL,\n        0x53ef07f60725b276L } },\n    /* 9 << 161 */\n    { { 0x07a5fbd27824fc56L,0x3467521813289077L,0x5bf69fd5e0c48349L,\n        0xa613ddd3b6aa7875L },\n      { 0x7f78c19c5450d866L,0x46f4409c8f84a481L,0x9f1d192890fce239L,\n        0x016c4168b2ce44b9L } },\n    /* 10 << 161 */\n    { { 0xbae023f0c7435978L,0xb152c88820e30e19L,0x9c241645e3fa6fafL,\n        0x735d95c184823e60L },\n      { 0x0319757303955317L,0x0b4b02a9f03b4995L,0x076bf55970274600L,\n        0x32c5cc53aaf57508L } },\n    /* 11 << 161 */\n    { { 0xe8af6d1f60624129L,0xb7bc5d649a5e2b5eL,0x3814b0485f082d72L,\n        0x76f267f2ce19677aL },\n      { 0x626c630fb36eed93L,0x55230cd73bf56803L,0x78837949ce2736a0L,\n        0x0d792d60aa6c55f1L } },\n    /* 12 << 161 */\n    { { 0x0318dbfdd5c7c5d2L,0xb38f8da7072b342dL,0x3569bddc7b8de38aL,\n        0xf25b5887a1c94842L },\n      { 0xb2d5b2842946ad60L,0x854f29ade9d1707eL,0xaa5159dc2c6a4509L,\n        0x899f94c057189837L } },\n    /* 13 << 161 */\n    { { 0xcf6adc51f4a55b03L,0x261762de35e3b2d5L,0x4cc4301204827b51L,\n        0xcd22a113c6021442L },\n      { 0xce2fd61a247c9569L,0x59a50973d152becaL,0x6c835a1163a716d4L,\n        0xc26455ed187dedcfL } },\n    /* 14 << 161 */\n    { { 0x27f536e049ce89e7L,0x18908539cc890cb5L,0x308909abd83c2aa1L,\n        0xecd3142b1ab73bd3L },\n      { 0x6a85bf59b3f5ab84L,0x3c320a68f2bea4c6L,0xad8dc5386da4541fL,\n        0xeaf34eb0b7c41186L } },\n    /* 15 << 161 */\n    { { 0x1c780129977c97c4L,0x5ff9beebc57eb9faL,0xa24d0524c822c478L,\n        0xfd8eec2a461cd415L },\n      { 0xfbde194ef027458cL,0xb4ff53191d1be115L,0x63f874d94866d6f4L,\n        0x35c75015b21ad0c9L } },\n    /* 16 << 161 */\n    { { 0xa6b5c9d646ac49d2L,0x42c77c0b83137aa9L,0x24d000fc68225a38L,\n        0x0f63cfc82fe1e907L },\n      { 0x22d1b01bc6441f95L,0x7d38f719ec8e448fL,0x9b33fa5f787fb1baL,\n        0x94dcfda1190158dfL } },\n    /* 17 << 161 */\n    { { 0xc47cb3395f6d4a09L,0x6b4f355cee52b826L,0x3d100f5df51b930aL,\n        0xf4512fac9f668f69L },\n      { 0x546781d5206c4c74L,0xd021d4d4cb4d2e48L,0x494a54c2ca085c2dL,\n        0xf1dbaca4520850a8L } },\n    /* 18 << 161 */\n    { { 0x63c79326490a1acaL,0xcb64dd9c41526b02L,0xbb772591a2979258L,\n        0x3f58297048d97846L },\n      { 0xd66b70d17c213ba7L,0xc28febb5e8a0ced4L,0x6b911831c10338c1L,\n        0x0d54e389bf0126f3L } },\n    /* 19 << 161 */\n    { { 0x7048d4604af206eeL,0x786c88f677e97cb9L,0xd4375ae1ac64802eL,\n        0x469bcfe1d53ec11cL },\n      { 0xfc9b340d47062230L,0xe743bb57c5b4a3acL,0xfe00b4aa59ef45acL,\n        0x29a4ef2359edf188L } },\n    /* 20 << 161 */\n    { { 0x40242efeb483689bL,0x2575d3f6513ac262L,0xf30037c80ca6db72L,\n        0xc9fcce8298864be2L },\n      { 0x84a112ff0149362dL,0x95e575821c4ae971L,0x1fa4b1a8945cf86cL,\n        0x4525a7340b024a2fL } },\n    /* 21 << 161 */\n    { { 0xe76c8b628f338360L,0x483ff59328edf32bL,0x67e8e90a298b1aecL,\n        0x9caab338736d9a21L },\n      { 0x5c09d2fd66892709L,0x2496b4dcb55a1d41L,0x93f5fb1ae24a4394L,\n        0x08c750496fa8f6c1L } },\n    /* 22 << 161 */\n    { { 0xcaead1c2c905d85fL,0xe9d7f7900733ae57L,0x24c9a65cf07cdd94L,\n        0x7389359ca4b55931L },\n      { 0xf58709b7367e45f7L,0x1f203067cb7e7adcL,0x82444bffc7b72818L,\n        0x07303b35baac8033L } },\n    /* 23 << 161 */\n    { { 0x1e1ee4e4d13b7ea1L,0xe6489b24e0e74180L,0xa5f2c6107e70ef70L,\n        0xa1655412bdd10894L },\n      { 0x555ebefb7af4194eL,0x533c1c3c8e89bd9cL,0x735b9b5789895856L,\n        0x15fb3cd2567f5c15L } },\n    /* 24 << 161 */\n    { { 0x057fed45526f09fdL,0xe8a4f10c8128240aL,0x9332efc4ff2bfd8dL,\n        0x214e77a0bd35aa31L },\n      { 0x32896d7314faa40eL,0x767867ec01e5f186L,0xc9adf8f117a1813eL,\n        0xcb6cda7854741795L } },\n    /* 25 << 161 */\n    { { 0xb7521b6d349d51aaL,0xf56b5a9ee3c7b8e9L,0xc6f1e5c932a096dfL,\n        0x083667c4a3635024L },\n      { 0x365ea13518087f2fL,0xf1b8eaacd136e45dL,0xc8a0e48473aec989L,\n        0xd75a324b142c9259L } },\n    /* 26 << 161 */\n    { { 0xb7b4d00101dae185L,0x45434e0b9b7a94bcL,0xf54339affbd8cb0bL,\n        0xdcc4569ee98ef49eL },\n      { 0x7789318a09a51299L,0x81b4d206b2b025d8L,0xf64aa418fae85792L,\n        0x3e50258facd7baf7L } },\n    /* 27 << 161 */\n    { { 0xdce84cdb2996864bL,0xa2e670891f485fa4L,0xb28b2bb6534c6a5aL,\n        0x31a7ec6bc94b9d39L },\n      { 0x1d217766d6bc20daL,0x4acdb5ec86761190L,0x6872632873701063L,\n        0x4d24ee7c2128c29bL } },\n    /* 28 << 161 */\n    { { 0xc072ebd3a19fd868L,0x612e481cdb8ddd3bL,0xb4e1d7541a64d852L,\n        0x00ef95acc4c6c4abL },\n      { 0x1536d2edaa0a6c46L,0x6129408643774790L,0x54af25e8343fda10L,\n        0x9ff9d98dfd25d6f2L } },\n    /* 29 << 161 */\n    { { 0x0746af7c468b8835L,0x977a31cb730ecea7L,0xa5096b80c2cf4a81L,\n        0xaa9868336458c37aL },\n      { 0x6af29bf3a6bd9d34L,0x6a62fe9b33c5d854L,0x50e6c304b7133b5eL,\n        0x04b601597d6e6848L } },\n    /* 30 << 161 */\n    { { 0x4cd296df5579bea4L,0x10e35ac85ceedaf1L,0x04c4c5fde3bcc5b1L,\n        0x95f9ee8a89412cf9L },\n      { 0x2c9459ee82b6eb0fL,0x2e84576595c2aaddL,0x774a84aed327fcfeL,\n        0xd8c937220368d476L } },\n    /* 31 << 161 */\n    { { 0x0dbd5748f83e8a3bL,0xa579aa968d2495f3L,0x535996a0ae496e9bL,\n        0x07afbfe9b7f9bcc2L },\n      { 0x3ac1dc6d5b7bd293L,0x3b592cff7022323dL,0xba0deb989c0a3e76L,\n        0x18e78e9f4b197acbL } },\n    /* 32 << 161 */\n    { { 0x211cde10296c36efL,0x7ee8967282c4da77L,0xb617d270a57836daL,\n        0xf0cd9c319cb7560bL },\n      { 0x01fdcbf7e455fe90L,0x3fb53cbb7e7334f3L,0x781e2ea44e7de4ecL,\n        0x8adab3ad0b384fd0L } },\n    /* 33 << 161 */\n    { { 0x129eee2f53d64829L,0x7a471e17a261492bL,0xe4f9adb9e4cb4a2cL,\n        0x3d359f6f97ba2c2dL },\n      { 0x346c67860aacd697L,0x92b444c375c2f8a8L,0xc79fa117d85df44eL,\n        0x56782372398ddf31L } },\n    /* 34 << 161 */\n    { { 0x60e690f2bbbab3b8L,0x4851f8ae8b04816bL,0xc72046ab9c92e4d2L,\n        0x518c74a17cf3136bL },\n      { 0xff4eb50af9877d4cL,0x14578d90a919cabbL,0x8218f8c4ac5eb2b6L,\n        0xa3ccc547542016e4L } },\n    /* 35 << 161 */\n    { { 0x025bf48e327f8349L,0xf3e97346f43cb641L,0xdc2bafdf500f1085L,\n        0x571678762f063055L },\n      { 0x5bd914b9411925a6L,0x7c078d48a1123de5L,0xee6bf835182b165dL,\n        0xb11b5e5bba519727L } },\n    /* 36 << 161 */\n    { { 0xe33ea76c1eea7b85L,0x2352b46192d4f85eL,0xf101d334afe115bbL,\n        0xfabc1294889175a3L },\n      { 0x7f6bcdc05233f925L,0xe0a802dbe77fec55L,0xbdb47b758069b659L,\n        0x1c5e12def98fbd74L } },\n    /* 37 << 161 */\n    { { 0x869c58c64b8457eeL,0xa5360f694f7ea9f7L,0xe576c09ff460b38fL,\n        0x6b70d54822b7fb36L },\n      { 0x3fd237f13bfae315L,0x33797852cbdff369L,0x97df25f525b516f9L,\n        0x46f388f2ba38ad2dL } },\n    /* 38 << 161 */\n    { { 0x656c465889d8ddbbL,0x8830b26e70f38ee8L,0x4320fd5cde1212b0L,\n        0xc34f30cfe4a2edb2L },\n      { 0xabb131a356ab64b8L,0x7f77f0ccd99c5d26L,0x66856a37bf981d94L,\n        0x19e76d09738bd76eL } },\n    /* 39 << 161 */\n    { { 0xe76c8ac396238f39L,0xc0a482bea830b366L,0xb7b8eaff0b4eb499L,\n        0x8ecd83bc4bfb4865L },\n      { 0x971b2cb7a2f3776fL,0xb42176a4f4b88adfL,0xb9617df5be1fa446L,\n        0x8b32d508cd031bd2L } },\n    /* 40 << 161 */\n    { { 0x1c6bd47d53b618c0L,0xc424f46c6a227923L,0x7303ffdedd92d964L,\n        0xe971287871b5abf2L },\n      { 0x8f48a632f815561dL,0x85f48ff5d3c055d1L,0x222a14277525684fL,\n        0xd0d841a067360cc3L } },\n    /* 41 << 161 */\n    { { 0x4245a9260b9267c6L,0xc78913f1cf07f863L,0xaa844c8e4d0d9e24L,\n        0xa42ad5223d5f9017L },\n      { 0xbd371749a2c989d5L,0x928292dfe1f5e78eL,0x493b383e0a1ea6daL,\n        0x5136fd8d13aee529L } },\n    /* 42 << 161 */\n    { { 0x860c44b1f2c34a99L,0x3b00aca4bf5855acL,0xabf6aaa0faaf37beL,\n        0x65f436822a53ec08L },\n      { 0x1d9a5801a11b12e1L,0x78a7ab2ce20ed475L,0x0de1067e9a41e0d5L,\n        0x30473f5f305023eaL } },\n    /* 43 << 161 */\n    { { 0xdd3ae09d169c7d97L,0x5cd5baa4cfaef9cdL,0x5cd7440b65a44803L,\n        0xdc13966a47f364deL },\n      { 0x077b2be82b8357c1L,0x0cb1b4c5e9d57c2aL,0x7a4ceb3205ff363eL,\n        0xf310fa4dca35a9efL } },\n    /* 44 << 161 */\n    { { 0xdbb7b352f97f68c6L,0x0c773b500b02cf58L,0xea2e48213c1f96d9L,\n        0xffb357b0eee01815L },\n      { 0xb9c924cde0f28039L,0x0b36c95a46a3fbe4L,0x1faaaea45e46db6cL,\n        0xcae575c31928aaffL } },\n    /* 45 << 161 */\n    { { 0x7f671302a70dab86L,0xfcbd12a971c58cfcL,0xcbef9acfbee0cb92L,\n        0x573da0b9f8c1b583L },\n      { 0x4752fcfe0d41d550L,0xe7eec0e32155cffeL,0x0fc39fcb545ae248L,\n        0x522cb8d18065f44eL } },\n    /* 46 << 161 */\n    { { 0x263c962a70cbb96cL,0xe034362abcd124a9L,0xf120db283c2ae58dL,\n        0xb9a38d49fef6d507L },\n      { 0xb1fd2a821ff140fdL,0xbd162f3020aee7e0L,0x4e17a5d4cb251949L,\n        0x2aebcb834f7e1c3dL } },\n    /* 47 << 161 */\n    { { 0x608eb25f937b0527L,0xf42e1e47eb7d9997L,0xeba699c4b8a53a29L,\n        0x1f921c71e091b536L },\n      { 0xcce29e7b5b26bbd5L,0x7a8ef5ed3b61a680L,0xe5ef8043ba1f1c7eL,\n        0x16ea821718158ddaL } },\n    /* 48 << 161 */\n    { { 0x01778a2b599ff0f9L,0x68a923d78104fc6bL,0x5bfa44dfda694ff3L,\n        0x4f7199dbf7667f12L },\n      { 0xc06d8ff6e46f2a79L,0x08b5deade9f8131dL,0x02519a59abb4ce7cL,\n        0xc4f710bcb42aec3eL } },\n    /* 49 << 161 */\n    { { 0x3d77b05778bde41aL,0x6474bf80b4186b5aL,0x048b3f6788c65741L,\n        0xc64519de03c7c154L },\n      { 0xdf0738460edfcc4fL,0x319aa73748f1aa6bL,0x8b9f8a02ca909f77L,\n        0x902581397580bfefL } },\n    /* 50 << 161 */\n    { { 0xd8bfd3cac0c22719L,0xc60209e4c9ca151eL,0x7a744ab5d9a1a69cL,\n        0x6de5048b14937f8fL },\n      { 0x171938d8e115ac04L,0x7df709401c6b16d2L,0xa6aeb6637f8e94e7L,\n        0xc130388e2a2cf094L } },\n    /* 51 << 161 */\n    { { 0x1850be8477f54e6eL,0x9f258a7265d60fe5L,0xff7ff0c06c9146d6L,\n        0x039aaf90e63a830bL },\n      { 0x38f27a739460342fL,0x4703148c3f795f8aL,0x1bb5467b9681a97eL,\n        0x00931ba5ecaeb594L } },\n    /* 52 << 161 */\n    { { 0xcdb6719d786f337cL,0xd9c01cd2e704397dL,0x0f4a3f20555c2fefL,\n        0x004525097c0af223L },\n      { 0x54a5804784db8e76L,0x3bacf1aa93c8aa06L,0x11ca957cf7919422L,\n        0x5064105378cdaa40L } },\n    /* 53 << 161 */\n    { { 0x7a3038749f7144aeL,0x170c963f43d4acfdL,0x5e14814958ddd3efL,\n        0xa7bde5829e72dba8L },\n      { 0x0769da8b6fa68750L,0xfa64e532572e0249L,0xfcaadf9d2619ad31L,\n        0x87882daaa7b349cdL } },\n    /* 54 << 161 */\n    { { 0x9f6eb7316c67a775L,0xcb10471aefc5d0b1L,0xb433750ce1b806b2L,\n        0x19c5714d57b1ae7eL },\n      { 0xc0dc8b7bed03fd3fL,0xdd03344f31bc194eL,0xa66c52a78c6320b5L,\n        0x8bc82ce3d0b6fd93L } },\n    /* 55 << 161 */\n    { { 0xf8e13501b35f1341L,0xe53156dd25a43e42L,0xd3adf27e4daeb85cL,\n        0xb81d8379bbeddeb5L },\n      { 0x1b0b546e2e435867L,0x9020eb94eba5dd60L,0x37d911618210cb9dL,\n        0x4c596b315c91f1cfL } },\n    /* 56 << 161 */\n    { { 0xb228a90f0e0b040dL,0xbaf02d8245ff897fL,0x2aac79e600fa6122L,\n        0x248288178e36f557L },\n      { 0xb9521d31113ec356L,0x9e48861e15eff1f8L,0x2aa1d412e0d41715L,\n        0x71f8620353f131b8L } },\n    /* 57 << 161 */\n    { { 0xf60da8da3fd19408L,0x4aa716dc278d9d99L,0x394531f7a8c51c90L,\n        0xb560b0e8f59db51cL },\n      { 0xa28fc992fa34bdadL,0xf024fa149cd4f8bdL,0x5cf530f723a9d0d3L,\n        0x615ca193e28c9b56L } },\n    /* 58 << 161 */\n    { { 0x6d2a483d6f73c51eL,0xa4cb2412ea0dc2ddL,0x50663c411eb917ffL,\n        0x3d3a74cfeade299eL },\n      { 0x29b3990f4a7a9202L,0xa9bccf59a7b15c3dL,0x66a3ccdca5df9208L,\n        0x48027c1443f2f929L } },\n    /* 59 << 161 */\n    { { 0xd385377c40b557f0L,0xe001c366cd684660L,0x1b18ed6be2183a27L,\n        0x879738d863210329L },\n      { 0xa687c74bbda94882L,0xd1bbcc48a684b299L,0xaf6f1112863b3724L,\n        0x6943d1b42c8ce9f8L } },\n    /* 60 << 161 */\n    { { 0xe044a3bb098cafb4L,0x27ed231060d48cafL,0x542b56753a31b84dL,\n        0xcbf3dd50fcddbed7L },\n      { 0x25031f1641b1d830L,0xa7ec851dcb0c1e27L,0xac1c8fe0b5ae75dbL,\n        0xb24c755708c52120L } },\n    /* 61 << 161 */\n    { { 0x57f811dc1d4636c3L,0xf8436526681a9939L,0x1f6bc6d99c81adb3L,\n        0x840f8ac35b7d80d4L },\n      { 0x731a9811f4387f1aL,0x7c501cd3b5156880L,0xa5ca4a07dfe68867L,\n        0xf123d8f05fcea120L } },\n    /* 62 << 161 */\n    { { 0x1fbb0e71d607039eL,0x2b70e215cd3a4546L,0x32d2f01d53324091L,\n        0xb796ff08180ab19bL },\n      { 0x32d87a863c57c4aaL,0x2aed9cafb7c49a27L,0x9fb35eac31630d98L,\n        0x338e8cdf5c3e20a3L } },\n    /* 63 << 161 */\n    { { 0x80f1618266cde8dbL,0x4e1599802d72fd36L,0xd7b8f13b9b6e5072L,\n        0xf52139073b7b5dc1L },\n      { 0x4d431f1d8ce4396eL,0x37a1a680a7ed2142L,0xbf375696d01aaf6bL,\n        0xaa1c0c54e63aab66L } },\n    /* 64 << 161 */\n    { { 0x3014368b4ed80940L,0x67e6d0567a6fceddL,0x7c208c49ca97579fL,\n        0xfe3d7a81a23597f6L },\n      { 0x5e2032027e096ae2L,0xb1f3e1e724b39366L,0x26da26f32fdcdffcL,\n        0x79422f1d6097be83L } },\n    /* 0 << 168 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 168 */\n    { { 0x263a2cfb9db3b381L,0x9c3a2deed4df0a4bL,0x728d06e97d04e61fL,\n        0x8b1adfbc42449325L },\n      { 0x6ec1d9397e053a1bL,0xee2be5c766daf707L,0x80ba1e14810ac7abL,\n        0xdd2ae778f530f174L } },\n    /* 2 << 168 */\n    { { 0x0435d97a205b9d8bL,0x6eb8f064056756d4L,0xd5e88a8bb6f8210eL,\n        0x070ef12dec9fd9eaL },\n      { 0x4d8495053bcc876aL,0x12a75338a7404ce3L,0xd22b49e1b8a1db5eL,\n        0xec1f205114bfa5adL } },\n    /* 3 << 168 */\n    { { 0xadbaeb79b6828f36L,0x9d7a025801bd5b9eL,0xeda01e0d1e844b0cL,\n        0x4b625175887edfc9L },\n      { 0x14109fdd9669b621L,0x88a2ca56f6f87b98L,0xfe2eb788170df6bcL,\n        0x0cea06f4ffa473f9L } },\n    /* 4 << 168 */\n    { { 0x43ed81b5c4e83d33L,0xd9f358795efd488bL,0x164a620f9deb4d0fL,\n        0xc6927bdbac6a7394L },\n      { 0x45c28df79f9e0f03L,0x2868661efcd7e1a9L,0x7cf4e8d0ffa348f1L,\n        0x6bd4c284398538e0L } },\n    /* 5 << 168 */\n    { { 0x2618a091289a8619L,0xef796e606671b173L,0x664e46e59090c632L,\n        0xa38062d41e66f8fbL },\n      { 0x6c744a200573274eL,0xd07b67e4a9271394L,0x391223b26bdc0e20L,\n        0xbe2d93f1eb0a05a7L } },\n    /* 6 << 168 */\n    { { 0xf23e2e533f36d141L,0xe84bb3d44dfca442L,0xb804a48d6b7c023aL,\n        0x1e16a8fa76431c3bL },\n      { 0x1b5452adddd472e0L,0x7d405ee70d1ee127L,0x50fc6f1dffa27599L,\n        0x351ac53cbf391b35L } },\n    /* 7 << 168 */\n    { { 0x7efa14b84444896bL,0x64974d2ff94027fbL,0xefdcd0e8de84487dL,\n        0x8c45b2602b48989bL },\n      { 0xa8fcbbc2d8463487L,0xd1b2b3f73fbc476cL,0x21d005b7c8f443c0L,\n        0x518f2e6740c0139cL } },\n    /* 8 << 168 */\n    { { 0x56036e8c06d75fc1L,0x2dcf7bb73249a89fL,0x81dd1d3de245e7ddL,\n        0xf578dc4bebd6e2a7L },\n      { 0x4c028903df2ce7a0L,0xaee362889c39afacL,0xdc847c31146404abL,\n        0x6304c0d8a4e97818L } },\n    /* 9 << 168 */\n    { { 0xae51dca2a91f6791L,0x2abe41909baa9efcL,0xd9d2e2f4559c7ac1L,\n        0xe82f4b51fc9f773aL },\n      { 0xa77130274073e81cL,0xc0276facfbb596fcL,0x1d819fc9a684f70cL,\n        0x29b47fddc9f7b1e0L } },\n    /* 10 << 168 */\n    { { 0x358de103459b1940L,0xec881c595b013e93L,0x51574c9349532ad3L,\n        0x2db1d445b37b46deL },\n      { 0xc6445b87df239fd8L,0xc718af75151d24eeL,0xaea1c4a4f43c6259L,\n        0x40c0e5d770be02f7L } },\n    /* 11 << 168 */\n    { { 0x6a4590f4721b33f2L,0x2124f1fbfedf04eaL,0xf8e53cde9745efe7L,\n        0xe7e1043265f046d9L },\n      { 0xc3fca28ee4d0c7e6L,0x847e339a87253b1bL,0x9b5953483743e643L,\n        0xcb6a0a0b4fd12fc5L } },\n    /* 12 << 168 */\n    { { 0xfb6836c327d02dccL,0x5ad009827a68bcc2L,0x1b24b44c005e912dL,\n        0xcc83d20f811fdcfeL },\n      { 0x36527ec1666fba0cL,0x6994819714754635L,0xfcdcb1a8556da9c2L,\n        0xa593426781a732b2L } },\n    /* 13 << 168 */\n    { { 0xec1214eda714181dL,0x609ac13b6067b341L,0xff4b4c97a545df1fL,\n        0xa124050134d2076bL },\n      { 0x6efa0c231409ca97L,0x254cc1a820638c43L,0xd4e363afdcfb46cdL,\n        0x62c2adc303942a27L } },\n    /* 14 << 168 */\n    { { 0xc67b9df056e46483L,0xa55abb2063736356L,0xab93c098c551bc52L,\n        0x382b49f9b15fe64bL },\n      { 0x9ec221ad4dff8d47L,0x79caf615437df4d6L,0x5f13dc64bb456509L,\n        0xe4c589d9191f0714L } },\n    /* 15 << 168 */\n    { { 0x27b6a8ab3fd40e09L,0xe455842e77313ea9L,0x8b51d1e21f55988bL,\n        0x5716dd73062bbbfcL },\n      { 0x633c11e54e8bf3deL,0x9a0e77b61b85be3bL,0x565107290911cca6L,\n        0x27e76495efa6590fL } },\n    /* 16 << 168 */\n    { { 0xe4ac8b33070d3aabL,0x2643672b9a2cd5e5L,0x52eff79b1cfc9173L,\n        0x665ca49b90a7c13fL },\n      { 0x5a8dda59b3efb998L,0x8a5b922d052f1341L,0xae9ebbab3cf9a530L,\n        0x35986e7bf56da4d7L } },\n    /* 17 << 168 */\n    { { 0x3a636b5cff3513ccL,0xbb0cf8ba3198f7ddL,0xb8d4052241f16f86L,\n        0x760575d8de13a7bfL },\n      { 0x36f74e169f7aa181L,0x163a3ecff509ed1cL,0x6aead61f3c40a491L,\n        0x158c95fcdfe8fcaaL } },\n    /* 18 << 168 */\n    { { 0xa3991b6e13cda46fL,0x79482415342faed0L,0xf3ba5bde666b5970L,\n        0x1d52e6bcb26ab6ddL },\n      { 0x768ba1e78608dd3dL,0x4930db2aea076586L,0xd9575714e7dc1afaL,\n        0x1fc7bf7df7c58817L } },\n    /* 19 << 168 */\n    { { 0x6b47accdd9eee96cL,0x0ca277fbe58cec37L,0x113fe413e702c42aL,\n        0xdd1764eec47cbe51L },\n      { 0x041e7cde7b3ed739L,0x50cb74595ce9e1c0L,0x355685132925b212L,\n        0x7cff95c4001b081cL } },\n    /* 20 << 168 */\n    { { 0x63ee4cbd8088b454L,0xdb7f32f79a9e0c8aL,0xb377d4186b2447cbL,\n        0xe3e982aad370219bL },\n      { 0x06ccc1e4c2a2a593L,0x72c368650773f24fL,0xa13b4da795859423L,\n        0x8bbf1d3375040c8fL } },\n    /* 21 << 168 */\n    { { 0x726f0973da50c991L,0x48afcd5b822d6ee2L,0xe5fc718b20fd7771L,\n        0xb9e8e77dfd0807a1L },\n      { 0x7f5e0f4499a7703dL,0x6972930e618e36f3L,0x2b7c77b823807bbeL,\n        0xe5b82405cb27ff50L } },\n    /* 22 << 168 */\n    { { 0xba8b8be3bd379062L,0xd64b7a1d2dce4a92L,0x040a73c5b2952e37L,\n        0x0a9e252ed438aecaL },\n      { 0xdd43956bc39d3bcbL,0x1a31ca00b32b2d63L,0xd67133b85c417a18L,\n        0xd08e47902ef442c8L } },\n    /* 23 << 168 */\n    { { 0x98cb1ae9255c0980L,0x4bd863812b4a739fL,0x5a5c31e11e4a45a1L,\n        0x1e5d55fe9cb0db2fL },\n      { 0x74661b068ff5cc29L,0x026b389f0eb8a4f4L,0x536b21a458848c24L,\n        0x2e5bf8ec81dc72b0L } },\n    /* 24 << 168 */\n    { { 0x03c187d0ad886aacL,0x5c16878ab771b645L,0xb07dfc6fc74045abL,\n        0x2c6360bf7800caedL },\n      { 0x24295bb5b9c972a3L,0xc9e6f88e7c9a6dbaL,0x90ffbf2492a79aa6L,\n        0xde29d50a41c26ac2L } },\n    /* 25 << 168 */\n    { { 0x9f0af483d309cbe6L,0x5b020d8ae0bced4fL,0x606e986db38023e3L,\n        0xad8f2c9d1abc6933L },\n      { 0x19292e1de7400e93L,0xfe3e18a952be5e4dL,0xe8e9771d2e0680bfL,\n        0x8c5bec98c54db063L } },\n    /* 26 << 168 */\n    { { 0x2af9662a74a55d1fL,0xe3fbf28f046f66d8L,0xa3a72ab4d4dc4794L,\n        0x09779f455c7c2dd8L },\n      { 0xd893bdafc3d19d8dL,0xd5a7509457d6a6dfL,0x8cf8fef9952e6255L,\n        0x3da67cfbda9a8affL } },\n    /* 27 << 168 */\n    { { 0x4c23f62a2c160dcdL,0x34e6c5e38f90eaefL,0x35865519a9a65d5aL,\n        0x07c48aae8fd38a3dL },\n      { 0xb7e7aeda50068527L,0x2c09ef231c90936aL,0x31ecfeb6e879324cL,\n        0xa0871f6bfb0ec938L } },\n    /* 28 << 168 */\n    { { 0xb1f0fb68d84d835dL,0xc90caf39861dc1e6L,0x12e5b0467594f8d7L,\n        0x26897ae265012b92L },\n      { 0xbcf68a08a4d6755dL,0x403ee41c0991fbdaL,0x733e343e3bbf17e8L,\n        0xd2c7980d679b3d65L } },\n    /* 29 << 168 */\n    { { 0x33056232d2e11305L,0x966be492f3c07a6fL,0x6a8878ffbb15509dL,\n        0xff2211010a9b59a4L },\n      { 0x6c9f564aabe30129L,0xc6f2c940336e64cfL,0x0fe752628b0c8022L,\n        0xbe0267e96ae8db87L } },\n    /* 30 << 168 */\n    { { 0x22e192f193bc042bL,0xf085b534b237c458L,0xa0d192bd832c4168L,\n        0x7a76e9e3bdf6271dL },\n      { 0x52a882fab88911b5L,0xc85345e4b4db0eb5L,0xa3be02a681a7c3ffL,\n        0x51889c8cf0ec0469L } },\n    /* 31 << 168 */\n    { { 0x9d031369a5e829e5L,0xcbb4c6fc1607aa41L,0x75ac59a6241d84c1L,\n        0xc043f2bf8829e0eeL },\n      { 0x82a38f758ea5e185L,0x8bda40b9d87cbd9fL,0x9e65e75e2d8fc601L,\n        0x3d515f74a35690b3L } },\n    /* 32 << 168 */\n    { { 0x534acf4fda79e5acL,0x68b83b3a8630215fL,0x5c748b2ed085756eL,\n        0xb0317258e5d37cb2L },\n      { 0x6735841ac5ccc2c4L,0x7d7dc96b3d9d5069L,0xa147e410fd1754bdL,\n        0x65296e94d399ddd5L } },\n    /* 33 << 168 */\n    { { 0xf6b5b2d0bc8fa5bcL,0x8a5ead67500c277bL,0x214625e6dfa08a5dL,\n        0x51fdfedc959cf047L },\n      { 0x6bc9430b289fca32L,0xe36ff0cf9d9bdc3fL,0x2fe187cb58ea0edeL,\n        0xed66af205a900b3fL } },\n    /* 34 << 168 */\n    { { 0x00e0968b5fa9f4d6L,0x2d4066ce37a362e7L,0xa99a9748bd07e772L,\n        0x710989c006a4f1d0L },\n      { 0xd5dedf35ce40cbd8L,0xab55c5f01743293dL,0x766f11448aa24e2cL,\n        0x94d874f8605fbcb4L } },\n    /* 35 << 168 */\n    { { 0xa365f0e8a518001bL,0xee605eb69d04ef0fL,0x5a3915cdba8d4d25L,\n        0x44c0e1b8b5113472L },\n      { 0xcbb024e88b6740dcL,0x89087a53ee1d4f0cL,0xa88fa05c1fc4e372L,\n        0x8bf395cbaf8b3af2L } },\n    /* 36 << 168 */\n    { { 0x1e71c9a1deb8568bL,0xa35daea080fb3d32L,0xe8b6f2662cf8fb81L,\n        0x6d51afe89490696aL },\n      { 0x81beac6e51803a19L,0xe3d24b7f86219080L,0x727cfd9ddf6f463cL,\n        0x8c6865ca72284ee8L } },\n    /* 37 << 168 */\n    { { 0x32c88b7db743f4efL,0x3793909be7d11dceL,0xd398f9222ff2ebe8L,\n        0x2c70ca44e5e49796L },\n      { 0xdf4d9929cb1131b1L,0x7826f29825888e79L,0x4d3a112cf1d8740aL,\n        0x00384cb6270afa8bL } },\n    /* 38 << 168 */\n    { { 0xcb64125b3ab48095L,0x3451c25662d05106L,0xd73d577da4955845L,\n        0x39570c16bf9f4433L },\n      { 0xd7dfaad3adecf263L,0xf1c3d8d1dc76e102L,0x5e774a5854c6a836L,\n        0xdad4b6723e92d47bL } },\n    /* 39 << 168 */\n    { { 0xbe7e990ff0d796a0L,0x5fc62478df0e8b02L,0x8aae8bf4030c00adL,\n        0x3d2db93b9004ba0fL },\n      { 0xe48c8a79d85d5ddcL,0xe907caa76bb07f34L,0x58db343aa39eaed5L,\n        0x0ea6e007adaf5724L } },\n    /* 40 << 168 */\n    { { 0xe00df169d23233f3L,0x3e32279677cb637fL,0x1f897c0e1da0cf6cL,\n        0xa651f5d831d6bbddL },\n      { 0xdd61af191a230c76L,0xbd527272cdaa5e4aL,0xca753636d0abcd7eL,\n        0x78bdd37c370bd8dcL } },\n    /* 41 << 168 */\n    { { 0xc23916c217cd93feL,0x65b97a4ddadce6e2L,0xe04ed4eb174e42f8L,\n        0x1491ccaabb21480aL },\n      { 0x145a828023196332L,0x3c3862d7587b479aL,0x9f4a88a301dcd0edL,\n        0x4da2b7ef3ea12f1fL } },\n    /* 42 << 168 */\n    { { 0xf8e7ae33b126e48eL,0x404a0b32f494e237L,0x9beac474c55acadbL,\n        0x4ee5cf3bcbec9fd9L },\n      { 0x336b33b97df3c8c3L,0xbd905fe3b76808fdL,0x8f436981aa45c16aL,\n        0x255c5bfa3dd27b62L } },\n    /* 43 << 168 */\n    { { 0x71965cbfc3dd9b4dL,0xce23edbffc068a87L,0xb78d4725745b029bL,\n        0x74610713cefdd9bdL },\n      { 0x7116f75f1266bf52L,0x0204672218e49bb6L,0xdf43df9f3d6f19e3L,\n        0xef1bc7d0e685cb2fL } },\n    /* 44 << 168 */\n    { { 0xcddb27c17078c432L,0xe1961b9cb77fedb7L,0x1edc2f5cc2290570L,\n        0x2c3fefca19cbd886L },\n      { 0xcf880a36c2af389aL,0x96c610fdbda71ceaL,0xf03977a932aa8463L,\n        0x8eb7763f8586d90aL } },\n    /* 45 << 168 */\n    { { 0x3f3424542a296e77L,0xc871868342837a35L,0x7dc710906a09c731L,\n        0x54778ffb51b816dbL },\n      { 0x6b33bfecaf06defdL,0xfe3c105f8592b70bL,0xf937fda461da6114L,\n        0x3c13e6514c266ad7L } },\n    /* 46 << 168 */\n    { { 0xe363a829855938e8L,0x2eeb5d9e9de54b72L,0xbeb93b0e20ccfab9L,\n        0x3dffbb5f25e61a25L },\n      { 0x7f655e431acc093dL,0x0cb6cc3d3964ce61L,0x6ab283a1e5e9b460L,\n        0x55d787c5a1c7e72dL } },\n    /* 47 << 168 */\n    { { 0x4d2efd47deadbf02L,0x11e80219ac459068L,0x810c762671f311f0L,\n        0xfa17ef8d4ab6ef53L },\n      { 0xaf47fd2593e43bffL,0x5cb5ff3f0be40632L,0x546871068ee61da3L,\n        0x7764196eb08afd0fL } },\n    /* 48 << 168 */\n    { { 0x831ab3edf0290a8fL,0xcae81966cb47c387L,0xaad7dece184efb4fL,\n        0xdcfc53b34749110eL },\n      { 0x6698f23c4cb632f9L,0xc42a1ad6b91f8067L,0xb116a81d6284180aL,\n        0xebedf5f8e901326fL } },\n    /* 49 << 168 */\n    { { 0xf2274c9f97e3e044L,0x4201852011d09fc9L,0x56a65f17d18e6e23L,\n        0x2ea61e2a352b683cL },\n      { 0x27d291bc575eaa94L,0x9e7bc721b8ff522dL,0x5f7268bfa7f04d6fL,\n        0x5868c73faba41748L } },\n    /* 50 << 168 */\n    { { 0x9f85c2db7be0eeadL,0x511e7842ff719135L,0x5a06b1e9c5ea90d7L,\n        0x0c19e28326fab631L },\n      { 0x8af8f0cfe9206c55L,0x89389cb43553c06aL,0x39dbed97f65f8004L,\n        0x0621b037c508991dL } },\n    /* 51 << 168 */\n    { { 0x1c52e63596e78cc4L,0x5385c8b20c06b4a8L,0xd84ddfdbb0e87d03L,\n        0xc49dfb66934bafadL },\n      { 0x7071e17059f70772L,0x3a073a843a1db56bL,0x034949033b8af190L,\n        0x7d882de3d32920f0L } },\n    /* 52 << 168 */\n    { { 0x91633f0ab2cf8940L,0x72b0b1786f948f51L,0x2d28dc30782653c8L,\n        0x88829849db903a05L },\n      { 0xb8095d0c6a19d2bbL,0x4b9e7f0c86f782cbL,0x7af739882d907064L,\n        0xd12be0fe8b32643cL } },\n    /* 53 << 168 */\n    { { 0x358ed23d0e165dc3L,0x3d47ce624e2378ceL,0x7e2bb0b9feb8a087L,\n        0x3246e8aee29e10b9L },\n      { 0x459f4ec703ce2b4dL,0xe9b4ca1bbbc077cfL,0x2613b4f20e9940c1L,\n        0xfc598bb9047d1eb1L } },\n    /* 54 << 168 */\n    { { 0x9744c62b45036099L,0xa9dee742167c65d8L,0x0c511525dabe1943L,\n        0xda11055493c6c624L },\n      { 0xae00a52c651a3be2L,0xcda5111d884449a6L,0x063c06f4ff33bed1L,\n        0x73baaf9a0d3d76b4L } },\n    /* 55 << 168 */\n    { { 0x52fb0c9d7fc63668L,0x6886c9dd0c039cdeL,0x602bd59955b22351L,\n        0xb00cab02360c7c13L },\n      { 0x8cb616bc81b69442L,0x41486700b55c3ceeL,0x71093281f49ba278L,\n        0xad956d9c64a50710L } },\n    /* 56 << 168 */\n    { { 0x9561f28b638a7e81L,0x54155cdf5980ddc3L,0xb2db4a96d26f247aL,\n        0x9d774e4e4787d100L },\n      { 0x1a9e6e2e078637d2L,0x1c363e2d5e0ae06aL,0x7493483ee9cfa354L,\n        0x76843cb37f74b98dL } },\n    /* 57 << 168 */\n    { { 0xbaca6591d4b66947L,0xb452ce9804460a8cL,0x6830d24643768f55L,\n        0xf4197ed87dff12dfL },\n      { 0x6521b472400dd0f7L,0x59f5ca8f4b1e7093L,0x6feff11b080338aeL,\n        0x0ada31f6a29ca3c6L } },\n    /* 58 << 168 */\n    { { 0x24794eb694a2c215L,0xd83a43ab05a57ab4L,0x264a543a2a6f89feL,\n        0x2c2a3868dd5ec7c2L },\n      { 0xd33739408439d9b2L,0x715ea6720acd1f11L,0x42c1d235e7e6cc19L,\n        0x81ce6e96b990585cL } },\n    /* 59 << 168 */\n    { { 0x04e5dfe0d809c7bdL,0xd7b2580c8f1050abL,0x6d91ad78d8a4176fL,\n        0x0af556ee4e2e897cL },\n      { 0x162a8b73921de0acL,0x52ac9c227ea78400L,0xee2a4eeaefce2174L,\n        0xbe61844e6d637f79L } },\n    /* 60 << 168 */\n    { { 0x0491f1bc789a283bL,0x72d3ac3d880836f4L,0xaa1c5ea388e5402dL,\n        0x1b192421d5cc473dL },\n      { 0x5c0b99989dc84cacL,0xb0a8482d9c6e75b8L,0x639961d03a191ce2L,\n        0xda3bc8656d837930L } },\n    /* 61 << 168 */\n    { { 0xca990653056e6f8fL,0x84861c4164d133a7L,0x8b403276746abe40L,\n        0xb7b4d51aebf8e303L },\n      { 0x05b43211220a255dL,0xc997152c02419e6eL,0x76ff47b6630c2feaL,\n        0x50518677281fdadeL } },\n    /* 62 << 168 */\n    { { 0x3283b8bacf902b0bL,0x8d4b4eb537db303bL,0xcc89f42d755011bcL,\n        0xb43d74bbdd09d19bL },\n      { 0x65746bc98adba350L,0x364eaf8cb51c1927L,0x13c7659610ad72ecL,\n        0x30045121f8d40c20L } },\n    /* 63 << 168 */\n    { { 0x6d2d99b7ea7b979bL,0xcd78cd74e6fb3bcdL,0x11e45a9e86cffbfeL,\n        0x78a61cf4637024f6L },\n      { 0xd06bc8723d502295L,0xf1376854458cb288L,0xb9db26a1342f8586L,\n        0xf33effcf4beee09eL } },\n    /* 64 << 168 */\n    { { 0xd7e0c4cdb30cfb3aL,0x6d09b8c16c9db4c8L,0x40ba1a4207c8d9dfL,\n        0x6fd495f71c52c66dL },\n      { 0xfb0e169f275264daL,0x80c2b746e57d8362L,0xedd987f749ad7222L,\n        0xfdc229af4398ec7bL } },\n    /* 0 << 175 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 175 */\n    { { 0xb0d1ed8452666a58L,0x4bcb6e00e6a9c3c2L,0x3c57411c26906408L,\n        0xcfc2075513556400L },\n      { 0xa08b1c505294dba3L,0xa30ba2868b7dd31eL,0xd70ba90e991eca74L,\n        0x094e142ce762c2b9L } },\n    /* 2 << 175 */\n    { { 0xb81d783e979f3925L,0x1efd130aaf4c89a7L,0x525c2144fd1bf7faL,\n        0x4b2969041b265a9eL },\n      { 0xed8e9634b9db65b6L,0x35c82e3203599d8aL,0xdaa7a54f403563f3L,\n        0x9df088ad022c38abL } },\n    /* 3 << 175 */\n    { { 0xe5cfb066bb3fd30aL,0x429169daeff0354eL,0x809cf8523524e36cL,\n        0x136f4fb30155be1dL },\n      { 0x4826af011fbba712L,0x6ef0f0b4506ba1a1L,0xd9928b3177aea73eL,\n        0xe2bf6af25eaa244eL } },\n    /* 4 << 175 */\n    { { 0x8d084f124237b64bL,0x688ebe99e3ecfd07L,0x57b8a70cf6845dd8L,\n        0x808fc59c5da4a325L },\n      { 0xa9032b2ba3585862L,0xb66825d5edf29386L,0xb5a5a8db431ec29bL,\n        0xbb143a983a1e8dc8L } },\n    /* 5 << 175 */\n    { { 0x35ee94ce12ae381bL,0x3a7f176c86ccda90L,0xc63a657e4606eacaL,\n        0x9ae5a38043cd04dfL },\n      { 0x9bec8d15ed251b46L,0x1f5d6d30caca5e64L,0x347b3b359ff20f07L,\n        0x4d65f034f7e4b286L } },\n    /* 6 << 175 */\n    { { 0x9e93ba24f111661eL,0xedced484b105eb04L,0x96dc9ba1f424b578L,\n        0xbf8f66b7e83e9069L },\n      { 0x872d4df4d7ed8216L,0xbf07f3778e2cbecfL,0x4281d89998e73754L,\n        0xfec85fbb8aab8708L } },\n    /* 7 << 175 */\n    { { 0x9a3c0deea5ba5b0bL,0xe6a116ce42d05299L,0xae9775fee9b02d42L,\n        0x72b05200a1545cb6L },\n      { 0xbc506f7d31a3b4eaL,0xe58930788bbd9b32L,0xc8bc5f37e4b12a97L,\n        0x6b000c064a73b671L } },\n    /* 8 << 175 */\n    { { 0x13b5bf22765fa7d0L,0x59805bf01d6a5370L,0x67a5e29d4280db98L,\n        0x4f53916f776b1ce3L },\n      { 0x714ff61f33ddf626L,0x4206238ea085d103L,0x1c50d4b7e5809ee3L,\n        0x999f450d85f8eb1dL } },\n    /* 9 << 175 */\n    { { 0x658a6051e4c79e9bL,0x1394cb73c66a9feaL,0x27f31ed5c6be7b23L,\n        0xf4c88f365aa6f8feL },\n      { 0x0fb0721f4aaa499eL,0x68b3a7d5e3fb2a6bL,0xa788097d3a92851dL,\n        0x060e7f8ae96f4913L } },\n    /* 10 << 175 */\n    { { 0x82eebe731a3a93bcL,0x42bbf465a21adc1aL,0xc10b6fa4ef030efdL,\n        0x247aa4c787b097bbL },\n      { 0x8b8dc632f60c77daL,0x6ffbc26ac223523eL,0xa4f6ff11344579cfL,\n        0x5825653c980250f6L } },\n    /* 11 << 175 */\n    { { 0xb2dd097ebc1aa2b9L,0x0788939337a0333aL,0x1cf55e7137a0db38L,\n        0x2648487f792c1613L },\n      { 0xdad013363fcef261L,0x6239c81d0eabf129L,0x8ee761de9d276be2L,\n        0x406a7a341eda6ad3L } },\n    /* 12 << 175 */\n    { { 0x4bf367ba4a493b31L,0x54f20a529bf7f026L,0xb696e0629795914bL,\n        0xcddab96d8bf236acL },\n      { 0x4ff2c70aed25ea13L,0xfa1d09eb81cbbbe7L,0x88fc8c87468544c5L,\n        0x847a670d696b3317L } },\n    /* 13 << 175 */\n    { { 0xf133421e64bcb626L,0xaea638c826dee0b5L,0xd6e7680bb310346cL,\n        0xe06f4097d5d4ced3L },\n      { 0x099614527512a30bL,0xf3d867fde589a59aL,0x2e73254f52d0c180L,\n        0x9063d8a3333c74acL } },\n    /* 14 << 175 */\n    { { 0xeda6c595d314e7bcL,0x2ee7464b467899edL,0x1cef423c0a1ed5d3L,\n        0x217e76ea69cc7613L },\n      { 0x27ccce1fe7cda917L,0x12d8016b8a893f16L,0xbcd6de849fc74f6bL,\n        0xfa5817e2f3144e61L } },\n    /* 15 << 175 */\n    { { 0x1f3541640821ee4cL,0x1583eab40bc61992L,0x7490caf61d72879fL,\n        0x998ad9f3f76ae7b2L },\n      { 0x1e181950a41157f7L,0xa9d7e1e6e8da3a7eL,0x963784eb8426b95fL,\n        0x0ee4ed6e542e2a10L } },\n    /* 16 << 175 */\n    { { 0xb79d4cc5ac751e7bL,0x93f96472fd4211bdL,0x8c72d3d2c8de4fc6L,\n        0x7b69cbf5df44f064L },\n      { 0x3da90ca2f4bf94e1L,0x1a5325f8f12894e2L,0x0a437f6c7917d60bL,\n        0x9be7048696c9cb5dL } },\n    /* 17 << 175 */\n    { { 0xb4d880bfe1dc5c05L,0xd738addaeebeeb57L,0x6f0119d3df0fe6a3L,\n        0x5c686e5566eaaf5aL },\n      { 0x9cb10b50dfd0b7ecL,0xbdd0264b6a497c21L,0xfc0935148c546c96L,\n        0x58a947fa79dbf42aL } },\n    /* 18 << 175 */\n    { { 0xc0b48d4e49ccd6d7L,0xff8fb02c88bd5580L,0xc75235e907d473b2L,\n        0x4fab1ac5a2188af3L },\n      { 0x030fa3bc97576ec0L,0xe8c946e80b7e7d2fL,0x40a5c9cc70305600L,\n        0x6d8260a9c8b013b4L } },\n    /* 19 << 175 */\n    { { 0x0368304f70bba85cL,0xad090da1a4a0d311L,0x7170e8702415eec1L,\n        0xbfba35fe8461ea47L },\n      { 0x6279019ac1e91938L,0xa47638f31afc415fL,0x36c65cbbbcba0e0fL,\n        0x02160efb034e2c48L } },\n    /* 20 << 175 */\n    { { 0xe6c51073615cd9e4L,0x498ec047f1243c06L,0x3e5a8809b17b3d8cL,\n        0x5cd99e610cc565f1L },\n      { 0x81e312df7851dafeL,0xf156f5baa79061e2L,0x80d62b71880c590eL,\n        0xbec9746f0a39faa1L } },\n    /* 21 << 175 */\n    { { 0x1d98a9c1c8ed1f7aL,0x09e43bb5a81d5ff2L,0xd5f00f680da0794aL,\n        0x412050d9661aa836L },\n      { 0xa89f7c4e90747e40L,0x6dc05ebbb62a3686L,0xdf4de847308e3353L,\n        0x53868fbb9fb53bb9L } },\n    /* 22 << 175 */\n    { { 0x2b09d2c3cfdcf7ddL,0x41a9fce3723fcab4L,0x73d905f707f57ca3L,\n        0x080f9fb1ac8e1555L },\n      { 0x7c088e849ba7a531L,0x07d35586ed9a147fL,0x602846abaf48c336L,\n        0x7320fd320ccf0e79L } },\n    /* 23 << 175 */\n    { { 0xaa780798b18bd1ffL,0x52c2e300afdd2905L,0xf27ea3d6434267cdL,\n        0x8b96d16d15605b5fL },\n      { 0x7bb310494b45706bL,0xe7f58b8e743d25f8L,0xe9b5e45b87f30076L,\n        0xd19448d65d053d5aL } },\n    /* 24 << 175 */\n    { { 0x1ecc8cb9d3210a04L,0x6bc7d463dafb5269L,0x3e59b10a67c3489fL,\n        0x1769788c65641e1bL },\n      { 0x8a53b82dbd6cb838L,0x7066d6e6236d5f22L,0x03aa1c616908536eL,\n        0xc971da0d66ae9809L } },\n    /* 25 << 175 */\n    { { 0x01b3a86bc49a2facL,0x3b8420c03092e77aL,0x020573007d6fb556L,\n        0x6941b2a1bff40a87L },\n      { 0x140b63080658ff2aL,0x878043633424ab36L,0x0253bd515751e299L,\n        0xc75bcd76449c3e3aL } },\n    /* 26 << 175 */\n    { { 0x92eb40907f8f875dL,0x9c9d754e56c26bbfL,0x158cea618110bbe7L,\n        0x62a6b802745f91eaL },\n      { 0xa79c41aac6e7394bL,0x445b6a83ad57ef10L,0x0c5277eb6ea6f40cL,\n        0x319fe96b88633365L } },\n    /* 27 << 175 */\n    { { 0x0b0fc61f385f63cbL,0x41250c8422bdd127L,0x67d153f109e942c2L,\n        0x60920d08c021ad5dL },\n      { 0x229f5746724d81a5L,0xb7ffb8925bba3299L,0x518c51a1de413032L,\n        0x2a9bfe773c2fd94cL } },\n    /* 28 << 175 */\n    { { 0xcbcde2393191f4fdL,0x43093e16d3d6ada1L,0x184579f358769606L,\n        0x2c94a8b3d236625cL },\n      { 0x6922b9c05c437d8eL,0x3d4ae423d8d9f3c8L,0xf72c31c12e7090a2L,\n        0x4ac3f5f3d76a55bdL } },\n    /* 29 << 175 */\n    { { 0x342508fc6b6af991L,0x0d5271001b5cebbdL,0xb84740d0dd440dd7L,\n        0x748ef841780162fdL },\n      { 0xa8dbfe0edfc6fafbL,0xeadfdf05f7300f27L,0x7d06555ffeba4ec9L,\n        0x12c56f839e25fa97L } },\n    /* 30 << 175 */\n    { { 0x77f84203d39b8c34L,0xed8b1be63125eddbL,0x5bbf2441f6e39dc5L,\n        0xb00f6ee66a5d678aL },\n      { 0xba456ecf57d0ea99L,0xdcae0f5817e06c43L,0x01643de40f5b4baaL,\n        0x2c324341d161b9beL } },\n    /* 31 << 175 */\n    { { 0x80177f55e126d468L,0xed325f1f76748e09L,0x6116004acfa9bdc2L,\n        0x2d8607e63a9fb468L },\n      { 0x0e573e276009d660L,0x3a525d2e8d10c5a1L,0xd26cb45c3b9009a0L,\n        0xb6b0cdc0de9d7448L } },\n    /* 32 << 175 */\n    { { 0x949c9976e1337c26L,0x6faadebdd73d68e5L,0x9e158614f1b768d9L,\n        0x22dfa5579cc4f069L },\n      { 0xccd6da17be93c6d6L,0x24866c61a504f5b9L,0x2121353c8d694da1L,\n        0x1c6ca5800140b8c6L } },\n    /* 33 << 175 */\n    { { 0xc245ad8ce964021eL,0xb83bffba032b82b3L,0xfaa220c647ef9898L,\n        0x7e8d3ac6982c948aL },\n      { 0x1faa2091bc2d124aL,0xbd54c3dd05b15ff4L,0x386bf3abc87c6fb7L,\n        0xfb2b0563fdeb6f66L } },\n    /* 34 << 175 */\n    { { 0x4e77c5575b45afb4L,0xe9ded649efb8912dL,0x7ec9bbf542f6e557L,\n        0x2570dfff62671f00L },\n      { 0x2b3bfb7888e084bdL,0xa024b238f37fe5b4L,0x44e7dc0495649aeeL,\n        0x498ca2555e7ec1d8L } },\n    /* 35 << 175 */\n    { { 0x3bc766eaaaa07e86L,0x0db6facbf3608586L,0xbadd2549bdc259c8L,\n        0x95af3c6e041c649fL },\n      { 0xb36a928c02e30afbL,0x9b5356ad008a88b8L,0x4b67a5f1cf1d9e9dL,\n        0xc6542e47a5d8d8ceL } },\n    /* 36 << 175 */\n    { { 0x73061fe87adfb6ccL,0xcc826fd398678141L,0x00e758b13c80515aL,\n        0x6afe324741485083L },\n      { 0x0fcb08b9b6ae8a75L,0xb8cf388d4acf51e1L,0x344a55606961b9d6L,\n        0x1a6778b86a97fd0cL } },\n    /* 37 << 175 */\n    { { 0xd840fdc1ecc4c7e3L,0xde9fe47d16db68ccL,0xe95f89dea3e216aaL,\n        0x84f1a6a49594a8beL },\n      { 0x7ddc7d725a7b162bL,0xc5cfda19adc817a3L,0x80a5d35078b58d46L,\n        0x93365b1382978f19L } },\n    /* 38 << 175 */\n    { { 0x2e44d22526a1fc90L,0x0d6d10d24d70705dL,0xd94b6b10d70c45f4L,\n        0x0f201022b216c079L },\n      { 0xcec966c5658fde41L,0xa8d2bc7d7e27601dL,0xbfcce3e1ff230be7L,\n        0x3394ff6b0033ffb5L } },\n    /* 39 << 175 */\n    { { 0xd890c5098132c9afL,0xaac4b0eb361e7868L,0x5194ded3e82d15aaL,\n        0x4550bd2e23ae6b7dL },\n      { 0x3fda318eea5399d4L,0xd989bffa91638b80L,0x5ea124d0a14aa12dL,\n        0x1fb1b8993667b944L } },\n    /* 40 << 175 */\n    { { 0x95ec796944c44d6aL,0x91df144a57e86137L,0x915fd62073adac44L,\n        0x8f01732d59a83801L },\n      { 0xec579d253aa0a633L,0x06de5e7cc9d6d59cL,0xc132f958b1ef8010L,\n        0x29476f96e65c1a02L } },\n    /* 41 << 175 */\n    { { 0x336a77c0d34c3565L,0xef1105b21b9f1e9eL,0x63e6d08bf9e08002L,\n        0x9aff2f21c613809eL },\n      { 0xb5754f853a80e75dL,0xde71853e6bbda681L,0x86f041df8197fd7aL,\n        0x8b332e08127817faL } },\n    /* 42 << 175 */\n    { { 0x05d99be8b9c20cdaL,0x89f7aad5d5cd0c98L,0x7ef936fe5bb94183L,\n        0x92ca0753b05cd7f2L },\n      { 0x9d65db1174a1e035L,0x02628cc813eaea92L,0xf2d9e24249e4fbf2L,\n        0x94fdfd9be384f8b7L } },\n    /* 43 << 175 */\n    { { 0x65f5605463428c6bL,0x2f7205b290b409a5L,0xf778bb78ff45ae11L,\n        0xa13045bec5ee53b2L },\n      { 0xe00a14ff03ef77feL,0x689cd59fffef8befL,0x3578f0ed1e9ade22L,\n        0xe99f3ec06268b6a8L } },\n    /* 44 << 175 */\n    { { 0xa2057d91ea1b3c3eL,0x2d1a7053b8823a4aL,0xabbb336a2cca451eL,\n        0xcd2466e32218bb5dL },\n      { 0x3ac1f42fc8cb762dL,0x7e312aae7690211fL,0xebb9bd7345d07450L,\n        0x207c4b8246c2213fL } },\n    /* 45 << 175 */\n    { { 0x99d425c1375913ecL,0x94e45e9667908220L,0xc08f3087cd67dbf6L,\n        0xa5670fbec0887056L },\n      { 0x6717b64a66f5b8fcL,0xd5a56aea786fec28L,0xa8c3f55fc0ff4952L,\n        0xa77fefae457ac49bL } },\n    /* 46 << 175 */\n    { { 0x29882d7c98379d44L,0xd000bdfb509edc8aL,0xc6f95979e66fe464L,\n        0x504a6115fa61bde0L },\n      { 0x56b3b871effea31aL,0x2d3de26df0c21a54L,0x21dbff31834753bfL,\n        0xe67ecf4969269d86L } },\n    /* 47 << 175 */\n    { { 0x7a176952151fe690L,0x035158047f2adb5fL,0xee794b15d1b62a8dL,\n        0xf004ceecaae454e6L },\n      { 0x0897ea7cf0386facL,0x3b62ff12d1fca751L,0x154181df1b7a04ecL,\n        0x2008e04afb5847ecL } },\n    /* 48 << 175 */\n    { { 0xd147148e41dbd772L,0x2b419f7322942654L,0x669f30d3e9c544f7L,\n        0x52a2c223c8540149L },\n      { 0x5da9ee14634dfb02L,0x5f074ff0f47869f3L,0x74ee878da3933accL,\n        0xe65106514fe35ed1L } },\n    /* 49 << 175 */\n    { { 0xb3eb9482f1012e7aL,0x51013cc0a8a566aeL,0xdd5e924347c00d3bL,\n        0x7fde089d946bb0e5L },\n      { 0x030754fec731b4b3L,0x12a136a499fda062L,0x7c1064b85a1a35bcL,\n        0xbf1f5763446c84efL } },\n    /* 50 << 175 */\n    { { 0xed29a56da16d4b34L,0x7fba9d09dca21c4fL,0x66d7ac006d8de486L,\n        0x6006198773a2a5e1L },\n      { 0x8b400f869da28ff0L,0x3133f70843c4599cL,0x9911c9b8ee28cb0dL,\n        0xcd7e28748e0af61dL } },\n    /* 51 << 175 */\n    { { 0x5a85f0f272ed91fcL,0x85214f319cd4a373L,0x881fe5be1925253cL,\n        0xd8dc98e091e8bc76L },\n      { 0x7120affe585cc3a2L,0x724952ed735bf97aL,0x5581e7dc3eb34581L,\n        0x5cbff4f2e52ee57dL } },\n    /* 52 << 175 */\n    { { 0x8d320a0e87d8cc7bL,0x9beaa7f3f1d280d0L,0x7a0b95719beec704L,\n        0x9126332e5b7f0057L },\n      { 0x01fbc1b48ed3bd6dL,0x35bb2c12d945eb24L,0x6404694e9a8ae255L,\n        0xb6092eec8d6abfb3L } },\n    /* 53 << 175 */\n    { { 0x4d76143fcc058865L,0x7b0a5af26e249922L,0x8aef94406a50d353L,\n        0xe11e4bcc64f0e07aL },\n      { 0x4472993aa14a90faL,0x7706e20cba0c51d4L,0xf403292f1532672dL,\n        0x52573bfa21829382L } },\n    /* 54 << 175 */\n    { { 0x6a7bb6a93b5bdb83L,0x08da65c0a4a72318L,0xc58d22aa63eb065fL,\n        0x1717596c1b15d685L },\n      { 0x112df0d0b266d88bL,0xf688ae975941945aL,0x487386e37c292cacL,\n        0x42f3b50d57d6985cL } },\n    /* 55 << 175 */\n    { { 0x6da4f9986a90fc34L,0xc8f257d365ca8a8dL,0xc2feabca6951f762L,\n        0xe1bc81d074c323acL },\n      { 0x1bc68f67251a2a12L,0x10d86587be8a70dcL,0xd648af7ff0f84d2eL,\n        0xf0aa9ebc6a43ac92L } },\n    /* 56 << 175 */\n    { { 0x69e3be0427596893L,0xb6bb02a645bf452bL,0x0875c11af4c698c8L,\n        0x6652b5c7bece3794L },\n      { 0x7b3755fd4f5c0499L,0x6ea16558b5532b38L,0xd1c69889a2e96ef7L,\n        0x9c773c3a61ed8f48L } },\n    /* 57 << 175 */\n    { { 0x2b653a409b323abcL,0xe26605e1f0e1d791L,0x45d410644a87157aL,\n        0x8f9a78b7cbbce616L },\n      { 0xcf1e44aac407edddL,0x81ddd1d8a35b964fL,0x473e339efd083999L,\n        0x6c94bdde8e796802L } },\n    /* 58 << 175 */\n    { { 0x5a304ada8545d185L,0x82ae44ea738bb8cbL,0x628a35e3df87e10eL,\n        0xd3624f3da15b9fe3L },\n      { 0xcc44209b14be4254L,0x7d0efcbcbdbc2ea5L,0x1f60336204c37bbeL,\n        0x21f363f556a5852cL } },\n    /* 59 << 175 */\n    { { 0xa1503d1ca8501550L,0x2251e0e1d8ab10bbL,0xde129c966961c51cL,\n        0x1f7246a481910f68L },\n      { 0x2eb744ee5f2591f2L,0x3c47d33f5e627157L,0x4d6d62c922f3bd68L,\n        0x6120a64bcb8df856L } },\n    /* 60 << 175 */\n    { { 0x3a9ac6c07b5d07dfL,0xa92b95587ef39783L,0xe128a134ab3a9b4fL,\n        0x41c18807b1252f05L },\n      { 0xfc7ed08980ba9b1cL,0xac8dc6dec532a9ddL,0xbf829cef55246809L,\n        0x101b784f5b4ee80fL } },\n    /* 61 << 175 */\n    { { 0xc09945bbb6f11603L,0x57b09dbe41d2801eL,0xfba5202fa97534a8L,\n        0x7fd8ae5fc17b9614L },\n      { 0xa50ba66678308435L,0x9572f77cd3868c4dL,0x0cef7bfd2dd7aab0L,\n        0xe7958e082c7c79ffL } },\n    /* 62 << 175 */\n    { { 0x81262e4225346689L,0x716da290b07c7004L,0x35f911eab7950ee3L,\n        0x6fd72969261d21b5L },\n      { 0x5238980308b640d3L,0x5b0026ee887f12a1L,0x20e21660742e9311L,\n        0x0ef6d5415ff77ff7L } },\n    /* 63 << 175 */\n    { { 0x969127f0f9c41135L,0xf21d60c968a64993L,0x656e5d0ce541875cL,\n        0xf1e0f84ea1d3c233L },\n      { 0x9bcca35906002d60L,0xbe2da60c06191552L,0x5da8bbae61181ec3L,\n        0x9f04b82365806f19L } },\n    /* 64 << 175 */\n    { { 0xf1604a7dd4b79bb8L,0xaee806fb52c878c8L,0x34144f118d47b8e8L,\n        0x72edf52b949f9054L },\n      { 0xebfca84e2127015aL,0x9051d0c09cb7cef3L,0x86e8fe58296deec8L,\n        0x33b2818841010d74L } },\n    /* 0 << 182 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 182 */\n    { { 0x01079383171b445fL,0x9bcf21e38131ad4cL,0x8cdfe205c93987e8L,\n        0xe63f4152c92e8c8fL },\n      { 0x729462a930add43dL,0x62ebb143c980f05aL,0x4f3954e53b06e968L,\n        0xfe1d75ad242cf6b1L } },\n    /* 2 << 182 */\n    { { 0x5f95c6c7af8685c8L,0xd4c1c8ce2f8f01aaL,0xc44bbe322574692aL,\n        0xb8003478d4a4a068L },\n      { 0x7c8fc6e52eca3cdbL,0xea1db16bec04d399L,0xb05bc82e8f2bc5cfL,\n        0x763d517ff44793d2L } },\n    /* 3 << 182 */\n    { { 0x4451c1b808bd98d0L,0x644b1cd46575f240L,0x6907eb337375d270L,\n        0x56c8bebdfa2286bdL },\n      { 0xc713d2acc4632b46L,0x17da427aafd60242L,0x313065b7c95c7546L,\n        0xf8239898bf17a3deL } },\n    /* 4 << 182 */\n    { { 0xf3b7963f4c830320L,0x842c7aa0903203e3L,0xaf22ca0ae7327afbL,\n        0x38e13092967609b6L },\n      { 0x73b8fb62757558f1L,0x3cc3e831f7eca8c1L,0xe4174474f6331627L,\n        0xa77989cac3c40234L } },\n    /* 5 << 182 */\n    { { 0xe5fd17a144a081e0L,0xd797fb7db70e296aL,0x2b472b30481f719cL,\n        0x0e632a98fe6f8c52L },\n      { 0x89ccd116c5f0c284L,0xf51088af2d987c62L,0x2a2bccda4c2de6cfL,\n        0x810f9efef679f0f9L } },\n    /* 6 << 182 */\n    { { 0xb0f394b97ffe4b3eL,0x0b691d21e5fa5d21L,0xb0bd77479dfbbc75L,\n        0xd2830fdafaf78b00L },\n      { 0xf78c249c52434f57L,0x4b1f754598096dabL,0x73bf6f948ff8c0b3L,\n        0x34aef03d454e134cL } },\n    /* 7 << 182 */\n    { { 0xf8d151f4b7ac7ec5L,0xd6ceb95ae50da7d5L,0xa1b492b0dc3a0eb8L,\n        0x75157b69b3dd2863L },\n      { 0xe2c4c74ec5413d62L,0xbe329ff7bc5fc4c7L,0x835a2aea60fa9ddaL,\n        0xf117f5ad7445cb87L } },\n    /* 8 << 182 */\n    { { 0xae8317f4b0166f7aL,0xfbd3e3f7ceec74e6L,0xfdb516ace0874bfdL,\n        0x3d846019c681f3a3L },\n      { 0x0b12ee5c7c1620b0L,0xba68b4dd2b63c501L,0xac03cd326668c51eL,\n        0x2a6279f74e0bcb5bL } },\n    /* 9 << 182 */\n    { { 0x17bd69b06ae85c10L,0x729469791dfdd3a6L,0xd9a032682c078becL,\n        0x41c6a658bfd68a52L },\n      { 0xcdea10240e023900L,0xbaeec121b10d144dL,0x5a600e74058ab8dcL,\n        0x1333af21bb89ccddL } },\n    /* 10 << 182 */\n    { { 0xdf25eae03aaba1f1L,0x2cada16e3b7144cfL,0x657ee27d71ab98bcL,\n        0x99088b4c7a6fc96eL },\n      { 0x05d5c0a03549dbd4L,0x42cbdf8ff158c3acL,0x3fb6b3b087edd685L,\n        0x22071cf686f064d0L } },\n    /* 11 << 182 */\n    { { 0xd2d6721fff2811e5L,0xdb81b703fe7fae8cL,0x3cfb74efd3f1f7bbL,\n        0x0cdbcd7616cdeb5dL },\n      { 0x4f39642a566a808cL,0x02b74454340064d6L,0xfabbadca0528fa6fL,\n        0xe4c3074cd3fc0bb6L } },\n    /* 12 << 182 */\n    { { 0xb32cb8b0b796d219L,0xc3e95f4f34741dd9L,0x8721212568edf6f5L,\n        0x7a03aee4a2b9cb8eL },\n      { 0x0cd3c376f53a89aaL,0x0d8af9b1948a28dcL,0xcf86a3f4902ab04fL,\n        0x8aacb62a7f42002dL } },\n    /* 13 << 182 */\n    { { 0x106985ebf62ffd52L,0xe670b54e5797bf10L,0x4b405209c5e30aefL,\n        0x12c97a204365b5e9L },\n      { 0x104646ce1fe32093L,0x13cb4ff63907a8c9L,0x8b9f30d1d46e726bL,\n        0xe1985e21aba0f499L } },\n    /* 14 << 182 */\n    { { 0xc573dea910a230cdL,0x24f46a93cd30f947L,0xf2623fcfabe2010aL,\n        0x3f278cb273f00e4fL },\n      { 0xed55c67d50b920ebL,0xf1cb9a2d8e760571L,0x7c50d1090895b709L,\n        0x4207cf07190d4369L } },\n    /* 15 << 182 */\n    { { 0x3b027e81c4127fe1L,0xa9f8b9ad3ae9c566L,0x5ab10851acbfbba5L,\n        0xa747d648569556f5L },\n      { 0xcc172b5c2ba97bf7L,0x15e0f77dbcfa3324L,0xa345b7977686279dL,\n        0x5a723480e38003d3L } },\n    /* 16 << 182 */\n    { { 0xfd8e139f8f5fcda8L,0xf3e558c4bdee5bfdL,0xd76cbaf4e33f9f77L,\n        0x3a4c97a471771969L },\n      { 0xda27e84bf6dce6a7L,0xff373d9613e6c2d1L,0xf115193cd759a6e9L,\n        0x3f9b702563d2262cL } },\n    /* 17 << 182 */\n    { { 0xd9764a31317cd062L,0x30779d8e199f8332L,0xd807410616b11b0bL,\n        0x7917ab9f78aeaed8L },\n      { 0xb67a9cbe28fb1d8eL,0x2e313563136eda33L,0x010b7069a371a86cL,\n        0x44d90fa26744e6b7L } },\n    /* 18 << 182 */\n    { { 0x68190867d6b3e243L,0x9fe6cd9d59048c48L,0xb900b02895731538L,\n        0xa012062f32cae04fL },\n      { 0x8107c8bc9399d082L,0x47e8c54a41df12e2L,0x14ba5117b6ef3f73L,\n        0x22260bea81362f0bL } },\n    /* 19 << 182 */\n    { { 0x90ea261e1a18cc20L,0x2192999f2321d636L,0xef64d314e311b6a0L,\n        0xd7401e4c3b54a1f5L },\n      { 0x190199836fbca2baL,0x46ad32938fbffc4bL,0xa142d3f63786bf40L,\n        0xeb5cbc26b67039fcL } },\n    /* 20 << 182 */\n    { { 0x9cb0ae6c252bd479L,0x05e0f88a12b5848fL,0x78f6d2b2a5c97663L,\n        0x6f6e149bc162225cL },\n      { 0xe602235cde601a89L,0xd17bbe98f373be1fL,0xcaf49a5ba8471827L,\n        0x7e1a0a8518aaa116L } },\n    /* 21 << 182 */\n    { { 0x6c833196270580c3L,0x1e233839f1c98a14L,0x67b2f7b4ae34e0a5L,\n        0x47ac8745d8ce7289L },\n      { 0x2b74779a100dd467L,0x274a43374ee50d09L,0x603dcf1383608bc9L,\n        0xcd9da6c3c89e8388L } },\n    /* 22 << 182 */\n    { { 0x2660199f355116acL,0xcc38bb59b6d18eedL,0x3075f31f2f4bc071L,\n        0x9774457f265dc57eL },\n      { 0x06a6a9c8c6db88bbL,0x6429d07f4ec98e04L,0x8d05e57b05ecaa8bL,\n        0x20f140b17872ea7bL } },\n    /* 23 << 182 */\n    { { 0xdf8c0f09ca494693L,0x48d3a020f252e909L,0x4c5c29af57b14b12L,\n        0x7e6fa37dbf47ad1cL },\n      { 0x66e7b50649a0c938L,0xb72c0d486be5f41fL,0x6a6242b8b2359412L,\n        0xcd35c7748e859480L } },\n    /* 24 << 182 */\n    { { 0x12536fea87baa627L,0x58c1fec1f72aa680L,0x6c29b637601e5dc9L,\n        0x9e3c3c1cde9e01b9L },\n      { 0xefc8127b2bcfe0b0L,0x351071022a12f50dL,0x6ccd6cb14879b397L,\n        0xf792f804f8a82f21L } },\n    /* 25 << 182 */\n    { { 0x509d4804a9b46402L,0xedddf85dc10f0850L,0x928410dc4b6208aaL,\n        0xf6229c46391012dcL },\n      { 0xc5a7c41e7727b9b6L,0x289e4e4baa444842L,0x049ba1d9e9a947eaL,\n        0x44f9e47f83c8debcL } },\n    /* 26 << 182 */\n    { { 0xfa77a1fe611f8b8eL,0xfd2e416af518f427L,0xc5fffa70114ebac3L,\n        0xfe57c4e95d89697bL },\n      { 0xfdd053acb1aaf613L,0x31df210fea585a45L,0x318cc10e24985034L,\n        0x1a38efd15f1d6130L } },\n    /* 27 << 182 */\n    { { 0xbf86f2370b1e9e21L,0xb258514d1dbe88aaL,0x1e38a58890c1baf9L,\n        0x2936a01ebdb9b692L },\n      { 0xd576de986dd5b20cL,0xb586bf7170f98ecfL,0xcccf0f12c42d2fd7L,\n        0x8717e61cfb35bd7bL } },\n    /* 28 << 182 */\n    { { 0x8b1e572235e6fc06L,0x3477728f0b3e13d5L,0x150c294daa8a7372L,\n        0xc0291d433bfa528aL },\n      { 0xc6c8bc67cec5a196L,0xdeeb31e45c2e8a7cL,0xba93e244fb6e1c51L,\n        0xb9f8b71b2e28e156L } },\n    /* 29 << 182 */\n    { { 0xce65a287968a2ab9L,0xe3c5ce6946bbcb1fL,0xf8c835b9e7ae3f30L,\n        0x16bbee26ff72b82bL },\n      { 0x665e2017fd42cd22L,0x1e139970f8b1d2a0L,0x125cda2979204932L,\n        0x7aee94a549c3bee5L } },\n    /* 30 << 182 */\n    { { 0x68c7016089821a66L,0xf7c376788f981669L,0xd90829fc48cc3645L,\n        0x346af049d70addfcL },\n      { 0x2057b232370bf29cL,0xf90c73ce42e650eeL,0xe03386eaa126ab90L,\n        0x0e266e7e975a087bL } },\n    /* 31 << 182 */\n    { { 0x80578eb90fca65d9L,0x7e2989ea16af45b8L,0x7438212dcac75a4eL,\n        0x38c7ca394fef36b8L },\n      { 0x8650c494d402676aL,0x26ab5a66f72c7c48L,0x4e6cb426ce3a464eL,\n        0xf8f998962b72f841L } },\n    /* 32 << 182 */\n    { { 0x8c3184911a335cc8L,0x563459ba6a5913e4L,0x1b920d61c7b32919L,\n        0x805ab8b6a02425adL },\n      { 0x2ac512da8d006086L,0x6ca4846abcf5c0fdL,0xafea51d8ac2138d7L,\n        0xcb647545344cd443L } },\n    /* 33 << 182 */\n    { { 0x0429ee8fbd7d9040L,0xee66a2de819b9c96L,0x54f9ec25dea7d744L,\n        0x2ffea642671721bbL },\n      { 0x4f19dbd1114344eaL,0x04304536fd0dbc8bL,0x014b50aa29ec7f91L,\n        0xb5fc22febb06014dL } },\n    /* 34 << 182 */\n    { { 0x60d963a91ee682e0L,0xdf48abc0fe85c727L,0x0cadba132e707c2dL,\n        0xde608d3aa645aeffL },\n      { 0x05f1c28bedafd883L,0x3c362edebd94de1fL,0x8dd0629d13593e41L,\n        0x0a5e736f766d6eafL } },\n    /* 35 << 182 */\n    { { 0xbfa92311f68cf9d1L,0xa4f9ef87c1797556L,0x10d75a1f5601c209L,\n        0x651c374c09b07361L },\n      { 0x49950b5888b5ceadL,0x0ef000586fa9dbaaL,0xf51ddc264e15f33aL,\n        0x1f8b5ca62ef46140L } },\n    /* 36 << 182 */\n    { { 0x343ac0a3ee9523f0L,0xbb75eab2975ea978L,0x1bccf332107387f4L,\n        0x790f92599ab0062eL },\n      { 0xf1a363ad1e4f6a5fL,0x06e08b8462519a50L,0x609151877265f1eeL,\n        0x6a80ca3493ae985eL } },\n    /* 37 << 182 */\n    { { 0x81b29768aaba4864L,0xb13cabf28d52a7d6L,0xb5c363488ead03f1L,\n        0xc932ad9581c7c1c0L },\n      { 0x5452708ecae1e27bL,0x9dac42691b0df648L,0x233e3f0cdfcdb8bcL,\n        0xe6ceccdfec540174L } },\n    /* 38 << 182 */\n    { { 0xbd0d845e95081181L,0xcc8a7920699355d5L,0x111c0f6dc3b375a8L,\n        0xfd95bc6bfd51e0dcL },\n      { 0x4a106a266888523aL,0x4d142bd6cb01a06dL,0x79bfd289adb9b397L,\n        0x0bdbfb94e9863914L } },\n    /* 39 << 182 */\n    { { 0x29d8a2291660f6a6L,0x7f6abcd6551c042dL,0x13039deb0ac3ffe8L,\n        0xa01be628ec8523fbL },\n      { 0x6ea341030ca1c328L,0xc74114bdb903928eL,0x8aa4ff4e9e9144b0L,\n        0x7064091f7f9a4b17L } },\n    /* 40 << 182 */\n    { { 0xa3f4f521e447f2c4L,0x81b8da7a604291f0L,0xd680bc467d5926deL,\n        0x84f21fd534a1202fL },\n      { 0x1d1e31814e9df3d8L,0x1ca4861a39ab8d34L,0x809ddeec5b19aa4aL,\n        0x59f72f7e4d329366L } },\n    /* 41 << 182 */\n    { { 0xa2f93f41386d5087L,0x40bf739cdd67d64fL,0xb449420566702158L,\n        0xc33c65be73b1e178L },\n      { 0xcdcd657c38ca6153L,0x97f4519adc791976L,0xcc7c7f29cd6e1f39L,\n        0x38de9cfb7e3c3932L } },\n    /* 42 << 182 */\n    { { 0xe448eba37b793f85L,0xe9f8dbf9f067e914L,0xc0390266f114ae87L,\n        0x39ed75a7cd6a8e2aL },\n      { 0xadb148487ffba390L,0x67f8cb8b6af9bc09L,0x322c38489c7476dbL,\n        0xa320fecf52a538d6L } },\n    /* 43 << 182 */\n    { { 0xe0493002b2aced2bL,0xdfba1809616bd430L,0x531c4644c331be70L,\n        0xbc04d32e90d2e450L },\n      { 0x1805a0d10f9f142dL,0x2c44a0c547ee5a23L,0x31875a433989b4e3L,\n        0x6b1949fd0c063481L } },\n    /* 44 << 182 */\n    { { 0x2dfb9e08be0f4492L,0x3ff0da03e9d5e517L,0x03dbe9a1f79466a8L,\n        0x0b87bcd015ea9932L },\n      { 0xeb64fc83ab1f58abL,0x6d9598da817edc8aL,0x699cff661d3b67e5L,\n        0x645c0f2992635853L } },\n    /* 45 << 182 */\n    { { 0x253cdd82eabaf21cL,0x82b9602a2241659eL,0x2cae07ec2d9f7091L,\n        0xbe4c720c8b48cd9bL },\n      { 0x6ce5bc036f08d6c9L,0x36e8a997af10bf40L,0x83422d213e10ff12L,\n        0x7b26d3ebbcc12494L } },\n    /* 46 << 182 */\n    { { 0xb240d2d0c9469ad6L,0xc4a11b4d30afa05bL,0x4b604acedd6ba286L,\n        0x184866003ee2864cL },\n      { 0x5869d6ba8d9ce5beL,0x0d8f68c5ff4bfb0dL,0xb69f210b5700cf73L,\n        0x61f6653a6d37c135L } },\n    /* 47 << 182 */\n    { { 0xff3d432b5aff5a48L,0x0d81c4b972ba3a69L,0xee879ae9fa1899efL,\n        0xbac7e2a02d6acafdL },\n      { 0xd6d93f6c1c664399L,0x4c288de15bcb135dL,0x83031dab9dab7cbfL,\n        0xfe23feb03abbf5f0L } },\n    /* 48 << 182 */\n    { { 0x9f1b2466cdedca85L,0x140bb7101a09538cL,0xac8ae8515e11115dL,\n        0x0d63ff676f03f59eL },\n      { 0x755e55517d234afbL,0x61c2db4e7e208fc1L,0xaa9859cef28a4b5dL,\n        0xbdd6d4fc34af030fL } },\n    /* 49 << 182 */\n    { { 0xd1c4a26d3be01cb1L,0x9ba14ffc243aa07cL,0xf95cd3a9b2503502L,\n        0xe379bc067d2a93abL },\n      { 0x3efc18e9d4ca8d68L,0x083558ec80bb412aL,0xd903b9409645a968L,\n        0xa499f0b69ba6054fL } },\n    /* 50 << 182 */\n    { { 0x208b573cb8349abeL,0x3baab3e530b4fc1cL,0x87e978bacb524990L,\n        0x3524194eccdf0e80L },\n      { 0x627117257d4bcc42L,0xe90a3d9bb90109baL,0x3b1bdd571323e1e0L,\n        0xb78e9bd55eae1599L } },\n    /* 51 << 182 */\n    { { 0x0794b7469e03d278L,0x80178605d70e6297L,0x171792f899c97855L,\n        0x11b393eef5a86b5cL },\n      { 0x48ef6582d8884f27L,0xbd44737abf19ba5fL,0x8698de4ca42062c6L,\n        0x8975eb8061ce9c54L } },\n    /* 52 << 182 */\n    { { 0xd50e57c7d7fe71f3L,0x15342190bc97ce38L,0x51bda2de4df07b63L,\n        0xba12aeae200eb87dL },\n      { 0xabe135d2a9b4f8f6L,0x04619d65fad6d99cL,0x4a6683a77994937cL,\n        0x7a778c8b6f94f09aL } },\n    /* 53 << 182 */\n    { { 0x8c50862320a71b89L,0x241a2aed1c229165L,0x352be595aaf83a99L,\n        0x9fbfee7f1562bac8L },\n      { 0xeaf658b95c4017e3L,0x1dc7f9e015120b86L,0xd84f13dd4c034d6fL,\n        0x283dd737eaea3038L } },\n    /* 54 << 182 */\n    { { 0x197f2609cd85d6a2L,0x6ebbc345fae60177L,0xb80f031b4e12fedeL,\n        0xde55d0c207a2186bL },\n      { 0x1fb3e37f24dcdd5aL,0x8d602da57ed191fbL,0x108fb05676023e0dL,\n        0x70178c71459c20c0L } },\n    /* 55 << 182 */\n    { { 0xfad5a3863fe54cf0L,0xa4a3ec4f02bbb475L,0x1aa5ec20919d94d7L,\n        0x5d3b63b5a81e4ab3L },\n      { 0x7fa733d85ad3d2afL,0xfbc586ddd1ac7a37L,0x282925de40779614L,\n        0xfe0ffffbe74a242aL } },\n    /* 56 << 182 */\n    { { 0x3f39e67f906151e5L,0xcea27f5f55e10649L,0xdca1d4e1c17cf7b7L,\n        0x0c326d122fe2362dL },\n      { 0x05f7ac337dd35df3L,0x0c3b7639c396dbdfL,0x0912f5ac03b7db1cL,\n        0x9dea4b705c9ed4a9L } },\n    /* 57 << 182 */\n    { { 0x475e6e53aae3f639L,0xfaba0e7cfc278bacL,0x16f9e2219490375fL,\n        0xaebf9746a5a7ed0aL },\n      { 0x45f9af3ff41ad5d6L,0x03c4623cb2e99224L,0x82c5bb5cb3cf56aaL,\n        0x6431181934567ed3L } },\n    /* 58 << 182 */\n    { { 0xec57f2118be489acL,0x2821895db9a1104bL,0x610dc8756064e007L,\n        0x8e526f3f5b20d0feL },\n      { 0x6e71ca775b645aeeL,0x3d1dcb9f800e10ffL,0x36b51162189cf6deL,\n        0x2c5a3e306bb17353L } },\n    /* 59 << 182 */\n    { { 0xc186cd3e2a6c6fbfL,0xa74516fa4bf97906L,0x5b4b8f4b279d6901L,\n        0x0c4e57b42b573743L },\n      { 0x75fdb229b6e386b6L,0xb46793fd99deac27L,0xeeec47eacf712629L,\n        0xe965f3c4cbc3b2ddL } },\n    /* 60 << 182 */\n    { { 0x8dd1fb83425c6559L,0x7fc00ee60af06fdaL,0xe98c922533d956dfL,\n        0x0f1ef3354fbdc8a2L },\n      { 0x2abb5145b79b8ea2L,0x40fd2945bdbff288L,0x6a814ac4d7185db7L,\n        0xc4329d6fc084609aL } },\n    /* 61 << 182 */\n    { { 0xc9ba7b52ed1be45dL,0x891dd20de4cd2c74L,0x5a4d4a7f824139b1L,\n        0x66c17716b873c710L },\n      { 0x5e5bc1412843c4e0L,0xd5ac4817b97eb5bfL,0xc0f8af54450c95c7L,\n        0xc91b3fa0318406c5L } },\n    /* 62 << 182 */\n    { { 0x360c340aab9d97f8L,0xfb57bd0790a2d611L,0x4339ae3ca6a6f7e5L,\n        0x9c1fcd2a2feb8a10L },\n      { 0x972bcca9c7ea7432L,0x1b0b924c308076f6L,0x80b2814a2a5b4ca5L,\n        0x2f78f55b61ef3b29L } },\n    /* 63 << 182 */\n    { { 0xf838744ac18a414fL,0xc611eaae903d0a86L,0x94dabc162a453f55L,\n        0xe6f2e3da14efb279L },\n      { 0x5b7a60179320dc3cL,0x692e382f8df6b5a4L,0x3f5e15e02d40fa90L,\n        0xc87883ae643dd318L } },\n    /* 64 << 182 */\n    { { 0x511053e453544774L,0x834d0ecc3adba2bcL,0x4215d7f7bae371f5L,\n        0xfcfd57bf6c8663bcL },\n      { 0xded2383dd6901b1dL,0x3b49fbb4b5587dc3L,0xfd44a08d07625f62L,\n        0x3ee4d65b9de9b762L } },\n    /* 0 << 189 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 189 */\n    { { 0x64e5137d0d63d1faL,0x658fc05202a9d89fL,0x4889487450436309L,\n        0xe9ae30f8d598da61L },\n      { 0x2ed710d1818baf91L,0xe27e9e068b6a0c20L,0x1e28dcfb1c1a6b44L,\n        0x883acb64d6ac57dcL } },\n    /* 2 << 189 */\n    { { 0x8735728dc2c6ff70L,0x79d6122fc5dc2235L,0x23f5d00319e277f9L,\n        0x7ee84e25dded8cc7L },\n      { 0x91a8afb063cd880aL,0x3f3ea7c63574af60L,0x0cfcdc8402de7f42L,\n        0x62d0792fb31aa152L } },\n    /* 3 << 189 */\n    { { 0x8e1b4e438a5807ceL,0xad283893e4109a7eL,0xc30cc9cbafd59ddaL,\n        0xf65f36c63d8d8093L },\n      { 0xdf31469ea60d32b2L,0xee93df4b3e8191c8L,0x9c1017c5355bdeb5L,\n        0xd26231858616aa28L } },\n    /* 4 << 189 */\n    { { 0xb02c83f9dec31a21L,0x988c8b236ad9d573L,0x53e983aea57be365L,\n        0xe968734d646f834eL },\n      { 0x9137ea8f5da6309bL,0x10f3a624c1f1ce16L,0x782a9ea2ca440921L,\n        0xdf94739e5b46f1b5L } },\n    /* 5 << 189 */\n    { { 0x9f9be006cce85c9bL,0x360e70d6a4c7c2d3L,0x2cd5beeaaefa1e60L,\n        0x64cf63c08c3d2b6dL },\n      { 0xfb107fa3e1cf6f90L,0xb7e937c6d5e044e6L,0x74e8ca78ce34db9fL,\n        0x4f8b36c13e210bd0L } },\n    /* 6 << 189 */\n    { { 0x1df165a434a35ea8L,0x3418e0f74d4412f6L,0x5af1f8af518836c3L,\n        0x42ceef4d130e1965L },\n      { 0x5560ca0b543a1957L,0xc33761e5886cb123L,0x66624b1ffe98ed30L,\n        0xf772f4bf1090997dL } },\n    /* 7 << 189 */\n    { { 0xf4e540bb4885d410L,0x7287f8109ba5f8d7L,0x22d0d865de98dfb1L,\n        0x49ff51a1bcfbb8a3L },\n      { 0xb6b6fa536bc3012eL,0x3d31fd72170d541dL,0x8018724f4b0f4966L,\n        0x79e7399f87dbde07L } },\n    /* 8 << 189 */\n    { { 0x56f8410ef4f8b16aL,0x97241afec47b266aL,0x0a406b8e6d9c87c1L,\n        0x803f3e02cd42ab1bL },\n      { 0x7f0309a804dbec69L,0xa83b85f73bbad05fL,0xc6097273ad8e197fL,\n        0xc097440e5067adc1L } },\n    /* 9 << 189 */\n    { { 0x730eafb63524ff16L,0xd7f9b51e823fc6ceL,0x27bd0d32443e4ac0L,\n        0x40c59ad94d66f217L },\n      { 0x6c33136f17c387a4L,0x5043b8d5eb86804dL,0x74970312675a73c9L,\n        0x838fdb31f16669b6L } },\n    /* 10 << 189 */\n    { { 0xc507b6dd418e7dddL,0x39888d93472f19d6L,0x7eae26be0c27eb4dL,\n        0x17b53ed3fbabb884L },\n      { 0xfc27021b2b01ae4fL,0x88462e87cf488682L,0xbee096ec215e2d87L,\n        0xeb2fea9ad242e29bL } },\n    /* 11 << 189 */\n    { { 0x5d985b5fb821fc28L,0x89d2e197dc1e2ad2L,0x55b566b89030ba62L,\n        0xe3fd41b54f41b1c6L },\n      { 0xb738ac2eb9a96d61L,0x7f8567ca369443f4L,0x8698622df803a440L,\n        0x2b5862368fe2f4dcL } },\n    /* 12 << 189 */\n    { { 0xbbcc00c756b95bceL,0x5ec03906616da680L,0x79162ee672214252L,\n        0x43132b6386a892d2L },\n      { 0x4bdd3ff22f3263bfL,0xd5b3733c9cd0a142L,0x592eaa8244415ccbL,\n        0x663e89248d5474eaL } },\n    /* 13 << 189 */\n    { { 0x8058a25e5236344eL,0x82e8df9dbda76ee6L,0xdcf6efd811cc3d22L,\n        0x00089cda3b4ab529L },\n      { 0x91d3a071bd38a3dbL,0x4ea97fc0ef72b925L,0x0c9fc15bea3edf75L,\n        0x5a6297cda4348ed3L } },\n    /* 14 << 189 */\n    { { 0x0d38ab35ce7c42d4L,0x9fd493ef82feab10L,0x46056b6d82111b45L,\n        0xda11dae173efc5c3L },\n      { 0xdc7402785545a7fbL,0xbdb2601c40d507e6L,0x121dfeeb7066fa58L,\n        0x214369a839ae8c2aL } },\n    /* 15 << 189 */\n    { { 0x195709cb06e0956cL,0x4c9d254f010cd34bL,0xf51e13f70471a532L,\n        0xe19d67911e73054dL },\n      { 0xf702a628db5c7be3L,0xc7141218b24dde05L,0xdc18233cf29b2e2eL,\n        0x3a6bd1e885342dbaL } },\n    /* 16 << 189 */\n    { { 0x3f747fa0b311898cL,0xe2a272e4cd0eac65L,0x4bba5851f914d0bcL,\n        0x7a1a9660c4a43ee3L },\n      { 0xe5a367cea1c8cde9L,0x9d958ba97271abe3L,0xf3ff7eb63d1615cdL,\n        0xa2280dcef5ae20b0L } },\n    /* 17 << 189 */\n    { { 0x56dba5c1cf640147L,0xea5a2e3d5e83d118L,0x04cd6b6dda24c511L,\n        0x1c0f4671e854d214L },\n      { 0x91a6b7a969565381L,0xdc966240decf1f5bL,0x1b22d21cfcf5d009L,\n        0x2a05f6419021dbd5L } },\n    /* 18 << 189 */\n    { { 0x8c0ed566d4312483L,0x5179a95d643e216fL,0xcc185fec17044493L,\n        0xb306333954991a21L },\n      { 0xd801ecdb0081a726L,0x0149b0c64fa89bbbL,0xafe9065a4391b6b9L,\n        0xedc92786d633f3a3L } },\n    /* 19 << 189 */\n    { { 0xe408c24aae6a8e13L,0x85833fde9f3897abL,0x43800e7ed81a0715L,\n        0xde08e346b44ffc5fL },\n      { 0x7094184ccdeff2e0L,0x49f9387b165eaed1L,0x635d6129777c468aL,\n        0x8c0dcfd1538c2dd8L } },\n    /* 20 << 189 */\n    { { 0xd6d9d9e37a6a308bL,0x623758304c2767d3L,0x874a8bc6f38cbeb6L,\n        0xd94d3f1accb6fd9eL },\n      { 0x92a9735bba21f248L,0x272ad0e56cd1efb0L,0x7437b69c05b03284L,\n        0xe7f047026948c225L } },\n    /* 21 << 189 */\n    { { 0x8a56c04acba2ececL,0x0c181270e3a73e41L,0x6cb34e9d03e93725L,\n        0xf77c8713496521a9L },\n      { 0x94569183fa7f9f90L,0xf2e7aa4c8c9707adL,0xced2c9ba26c1c9a3L,\n        0x9109fe9640197507L } },\n    /* 22 << 189 */\n    { { 0x9ae868a9e9adfe1cL,0x3984403d314e39bbL,0xb5875720f2fe378fL,\n        0x33f901e0ba44a628L },\n      { 0xea1125fe3652438cL,0xae9ec4e69dd1f20bL,0x1e740d9ebebf7fbdL,\n        0x6dbd3ddc42dbe79cL } },\n    /* 23 << 189 */\n    { { 0x62082aecedd36776L,0xf612c478e9859039L,0xa493b201032f7065L,\n        0xebd4d8f24ff9b211L },\n      { 0x3f23a0aaaac4cb32L,0xea3aadb715ed4005L,0xacf17ea4afa27e63L,\n        0x56125c1ac11fd66cL } },\n    /* 24 << 189 */\n    { { 0x266344a43794f8dcL,0xdcca923a483c5c36L,0x2d6b6bbf3f9d10a0L,\n        0xb320c5ca81d9bdf3L },\n      { 0x620e28ff47b50a95L,0x933e3b01cef03371L,0xf081bf8599100153L,\n        0x183be9a0c3a8c8d6L } },\n    /* 25 << 189 */\n    { { 0x4e3ddc5ad6bbe24dL,0xc6c7463053843795L,0x78193dd765ec2d4cL,\n        0xb8df26cccd3c89b2L },\n      { 0x98dbe3995a483f8dL,0x72d8a9577dd3313aL,0x65087294ab0bd375L,\n        0xfcd892487c259d16L } },\n    /* 26 << 189 */\n    { { 0x8a9443d77613aa81L,0x8010080085fe6584L,0x70fc4dbc7fb10288L,\n        0xf58280d3e86beee8L },\n      { 0x14fdd82f7c978c38L,0xdf1204c10de44d7bL,0xa08a1c844160252fL,\n        0x591554cac17646a5L } },\n    /* 27 << 189 */\n    { { 0x214a37d6a05bd525L,0x48d5f09b07957b3cL,0x0247cdcbd7109bc9L,\n        0x40f9e4bb30599ce7L },\n      { 0xc325fa03f46ad2ecL,0x00f766cfc3e3f9eeL,0xab556668d43a4577L,\n        0x68d30a613ee03b93L } },\n    /* 28 << 189 */\n    { { 0x7ddc81ea77b46a08L,0xcf5a6477c7480699L,0x43a8cb346633f683L,\n        0x1b867e6b92363c60L },\n      { 0x439211141f60558eL,0xcdbcdd632f41450eL,0x7fc04601cc630e8bL,\n        0xea7c66d597038b43L } },\n    /* 29 << 189 */\n    { { 0x7259b8a504e99fd8L,0x98a8dd124785549aL,0x0e459a7c840552e1L,\n        0xcdfcf4d04bb0909eL },\n      { 0x34a86db253758da7L,0xe643bb83eac997e1L,0x96400bd7530c5b7eL,\n        0x9f97af87b41c8b52L } },\n    /* 30 << 189 */\n    { { 0x34fc8820fbeee3f9L,0x93e5349049091afdL,0x764b9be59a31f35cL,\n        0x71f3786457e3d924L },\n      { 0x02fb34e0943aa75eL,0xa18c9c58ab8ff6e4L,0x080f31b133cf0d19L,\n        0x5c9682db083518a7L } },\n    /* 31 << 189 */\n    { { 0x873d4ca6b709c3deL,0x64a842623575b8f0L,0x6275da1f020154bbL,\n        0x97678caad17cf1abL },\n      { 0x8779795f951a95c3L,0xdd35b16350fccc08L,0x3270962733d8f031L,\n        0x3c5ab10a498dd85cL } },\n    /* 32 << 189 */\n    { { 0xb6c185c341dca566L,0x7de7fedad8622aa3L,0x99e84d92901b6dfbL,\n        0x30a02b0e7c4ad288L },\n      { 0xc7c81daa2fd3cf36L,0xd1319547df89e59fL,0xb2be8184cd496733L,\n        0xd5f449eb93d3412bL } },\n    /* 33 << 189 */\n    { { 0x7ea41b1b25fe531dL,0xf97974326a1d5646L,0x86067f722bde501aL,\n        0xf91481c00c85e89cL },\n      { 0xca8ee465f8b05bc6L,0x1844e1cf02e83cdaL,0xca82114ab4dbe33bL,\n        0x0f9f87694eabfde2L } },\n    /* 34 << 189 */\n    { { 0x4936b1c038b27fe2L,0x63b6359baba402dfL,0x40c0ea2f656bdbabL,\n        0x9c992a896580c39cL },\n      { 0x600e8f152a60aed1L,0xeb089ca4e0bf49dfL,0x9c233d7d2d42d99aL,\n        0x648d3f954c6bc2faL } },\n    /* 35 << 189 */\n    { { 0xdcc383a8e1add3f3L,0xf42c0c6a4f64a348L,0x2abd176f0030dbdbL,\n        0x4de501a37d6c215eL },\n      { 0x4a107c1f4b9a64bcL,0xa77f0ad32496cd59L,0xfb78ac627688dffbL,\n        0x7025a2ca67937d8eL } },\n    /* 36 << 189 */\n    { { 0xfde8b2d1d1a8f4e7L,0xf5b3da477354927cL,0xe48606a3d9205735L,\n        0xac477cc6e177b917L },\n      { 0xfb1f73d2a883239aL,0xe12572f6cc8b8357L,0x9d355e9cfb1f4f86L,\n        0x89b795f8d9f3ec6eL } },\n    /* 37 << 189 */\n    { { 0x27be56f1b54398dcL,0x1890efd73fedeed5L,0x62f77f1f9c6d0140L,\n        0x7ef0e314596f0ee4L },\n      { 0x50ca6631cc61dab3L,0x4a39801df4866e4fL,0x66c8d032ae363b39L,\n        0x22c591e52ead66aaL } },\n    /* 38 << 189 */\n    { { 0x954ba308de02a53eL,0x2a6c060fd389f357L,0xe6cfcde8fbf40b66L,\n        0x8e02fc56c6340ce1L },\n      { 0xe495779573adb4baL,0x7b86122ca7b03805L,0x63f835120c8e6fa6L,\n        0x83660ea0057d7804L } },\n    /* 39 << 189 */\n    { { 0xbad7910521ba473cL,0xb6c50beeded5389dL,0xee2caf4daa7c9bc0L,\n        0xd97b8de48c4e98a7L },\n      { 0xa9f63e70ab3bbddbL,0x3898aabf2597815aL,0x7659af89ac15b3d9L,\n        0xedf7725b703ce784L } },\n    /* 40 << 189 */\n    { { 0x25470fabe085116bL,0x04a4337587285310L,0x4e39187ee2bfd52fL,\n        0x36166b447d9ebc74L },\n      { 0x92ad433cfd4b322cL,0x726aa817ba79ab51L,0xf96eacd8c1db15ebL,\n        0xfaf71e910476be63L } },\n    /* 41 << 189 */\n    { { 0xdd69a640641fad98L,0xb799591829622559L,0x03c6daa5de4199dcL,\n        0x92cadc97ad545eb4L },\n      { 0x1028238b256534e4L,0x73e80ce68595409aL,0x690d4c66d05dc59bL,\n        0xc95f7b8f981dee80L } },\n    /* 42 << 189 */\n    { { 0xf4337014d856ac25L,0x441bd9ddac524dcaL,0x640b3d855f0499f5L,\n        0x39cf84a9d5fda182L },\n      { 0x04e7b055b2aa95a0L,0x29e33f0a0ddf1860L,0x082e74b5423f6b43L,\n        0x217edeb90aaa2b0fL } },\n    /* 43 << 189 */\n    { { 0x58b83f3583cbea55L,0xc485ee4dbc185d70L,0x833ff03b1e5f6992L,\n        0xb5b9b9cccf0c0dd5L },\n      { 0x7caaee8e4e9e8a50L,0x462e907b6269dafdL,0x6ed5cee9fbe791c6L,\n        0x68ca3259ed430790L } },\n    /* 44 << 189 */\n    { { 0x2b72bdf213b5ba88L,0x60294c8a35ef0ac4L,0x9c3230ed19b99b08L,\n        0x560fff176c2589aaL },\n      { 0x552b8487d6770374L,0xa373202d9a56f685L,0xd3e7f90745f175d9L,\n        0x3c2f315fd080d810L } },\n    /* 45 << 189 */\n    { { 0x1130e9dd7b9520e8L,0xc078f9e20af037b5L,0x38cd2ec71e9c104cL,\n        0x0f684368c472fe92L },\n      { 0xd3f1b5ed6247e7efL,0xb32d33a9396dfe21L,0x46f59cf44a9aa2c2L,\n        0x69cd5168ff0f7e41L } },\n    /* 46 << 189 */\n    { { 0x3f59da0f4b3234daL,0xcf0b0235b4579ebeL,0x6d1cbb256d2476c7L,\n        0x4f0837e69dc30f08L },\n      { 0x9a4075bb906f6e98L,0x253bb434c761e7d1L,0xde2e645f6e73af10L,\n        0xb89a40600c5f131cL } },\n    /* 47 << 189 */\n    { { 0xd12840c5b8cc037fL,0x3d093a5b7405bb47L,0x6202c253206348b8L,\n        0xbf5d57fcc55a3ca7L },\n      { 0x89f6c90c8c3bef48L,0x23ac76235a0a960aL,0xdfbd3d6b552b42abL,\n        0x3ef22458132061f6L } },\n    /* 48 << 189 */\n    { { 0xd74e9bdac97e6516L,0x88779360c230f49eL,0xa6ec1de31e74ea49L,\n        0x581dcee53fb645a2L },\n      { 0xbaef23918f483f14L,0x6d2dddfcd137d13bL,0x54cde50ed2743a42L,\n        0x89a34fc5e4d97e67L } },\n    /* 49 << 189 */\n    { { 0x13f1f5b312e08ce5L,0xa80540b8a7f0b2caL,0x854bcf7701982805L,\n        0xb8653ffd233bea04L },\n      { 0x8e7b878702b0b4c9L,0x2675261f9acb170aL,0x061a9d90930c14e5L,\n        0xb59b30e0def0abeaL } },\n    /* 50 << 189 */\n    { { 0x1dc19ea60200ec7dL,0xb6f4a3f90bce132bL,0xb8d5de90f13e27e0L,\n        0xbaee5ef01fade16fL },\n      { 0x6f406aaae4c6cf38L,0xab4cfe06d1369815L,0x0dcffe87efd550c6L,\n        0x9d4f59c775ff7d39L } },\n    /* 51 << 189 */\n    { { 0xb02553b151deb6adL,0x812399a4b1877749L,0xce90f71fca6006e1L,\n        0xc32363a6b02b6e77L },\n      { 0x02284fbedc36c64dL,0x86c81e31a7e1ae61L,0x2576c7e5b909d94aL,\n        0x8b6f7d02818b2bb0L } },\n    /* 52 << 189 */\n    { { 0xeca3ed0756faa38aL,0xa3790e6c9305bb54L,0xd784eeda7bc73061L,\n        0xbd56d3696dd50614L },\n      { 0xd6575949229a8aa9L,0xdcca8f474595ec28L,0x814305c106ab4fe6L,\n        0xc8c3976824f43f16L } },\n    /* 53 << 189 */\n    { { 0xe2a45f36523f2b36L,0x995c6493920d93bbL,0xf8afdab790f1632bL,\n        0x79ebbecd1c295954L },\n      { 0xc7bb3ddb79592f48L,0x67216a7b5f88e998L,0xd91f098bbc01193eL,\n        0xf7d928a5b1db83fcL } },\n    /* 54 << 189 */\n    { { 0x55e38417e991f600L,0x2a91113e2981a934L,0xcbc9d64806b13bdeL,\n        0xb011b6ac0755ff44L },\n      { 0x6f4cb518045ec613L,0x522d2d31c2f5930aL,0x5acae1af382e65deL,\n        0x5764306727bc966fL } },\n    /* 55 << 189 */\n    { { 0x5e12705d1c7193f0L,0xf0f32f473be8858eL,0x785c3d7d96c6dfc7L,\n        0xd75b4a20bf31795dL },\n      { 0x91acf17b342659d4L,0xe596ea3444f0378fL,0x4515708fce52129dL,\n        0x17387e1e79f2f585L } },\n    /* 56 << 189 */\n    { { 0x72cfd2e949dee168L,0x1ae052233e2af239L,0x009e75be1d94066aL,\n        0x6cca31c738abf413L },\n      { 0xb50bd61d9bc49908L,0x4a9b4a8cf5e2bc1eL,0xeb6cc5f7946f83acL,\n        0x27da93fcebffab28L } },\n    /* 57 << 189 */\n    { { 0xea314c964821c8c5L,0x8de49deda83c15f4L,0x7a64cf207af33004L,\n        0x45f1bfebc9627e10L },\n      { 0x878b062654b9df60L,0x5e4fdc3ca95c0b33L,0xe54a37cac2035d8eL,\n        0x9087cda980f20b8cL } },\n    /* 58 << 189 */\n    { { 0x36f61c238319ade4L,0x766f287ade8cfdf8L,0x48821948346f3705L,\n        0x49a7b85316e4f4a2L },\n      { 0xb9b3f8a75cedadfdL,0x8f5628158db2a815L,0xc0b7d55401f68f95L,\n        0x12971e27688a208eL } },\n    /* 59 << 189 */\n    { { 0xc9f8b696d0ff34fcL,0x20824de21222718cL,0x7213cf9f0c95284dL,\n        0xe2ad741bdc158240L },\n      { 0x0ee3a6df54043ccfL,0x16ff479bd84412b3L,0xf6c74ee0dfc98af0L,\n        0xa78a169f52fcd2fbL } },\n    /* 60 << 189 */\n    { { 0xd8ae874699c930e9L,0x1d33e85849e117a5L,0x7581fcb46624759fL,\n        0xde50644f5bedc01dL },\n      { 0xbeec5d00caf3155eL,0x672d66acbc73e75fL,0x86b9d8c6270b01dbL,\n        0xd249ef8350f55b79L } },\n    /* 61 << 189 */\n    { { 0x6131d6d473978fe3L,0xcc4e4542754b00a1L,0x4e05df0557dfcfe9L,\n        0x94b29cdd51ef6bf0L },\n      { 0xe4530cff9bc7edf2L,0x8ac236fdd3da65f3L,0x0faf7d5fc8eb0b48L,\n        0x4d2de14c660eb039L } },\n    /* 62 << 189 */\n    { { 0xc006bba760430e54L,0x10a2d0d6da3289abL,0x9c037a5dd7979c59L,\n        0x04d1f3d3a116d944L },\n      { 0x9ff224738a0983cdL,0x28e25b38c883cabbL,0xe968dba547a58995L,\n        0x2c80b505774eebdfL } },\n    /* 63 << 189 */\n    { { 0xee763b714a953bebL,0x502e223f1642e7f6L,0x6fe4b64161d5e722L,\n        0x9d37c5b0dbef5316L },\n      { 0x0115ed70f8330bc7L,0x139850e675a72789L,0x27d7faecffceccc2L,\n        0x3016a8604fd9f7f6L } },\n    /* 64 << 189 */\n    { { 0xc492ec644cd8f64cL,0x58a2d790279d7b51L,0x0ced1fc51fc75256L,\n        0x3e658aed8f433017L },\n      { 0x0b61942e05da59ebL,0xba3d60a30ddc3722L,0x7c311cd1742e7f87L,\n        0x6473ffeef6b01b6eL } },\n    /* 0 << 196 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 196 */\n    { { 0x8303604f692ac542L,0xf079ffe1227b91d3L,0x19f63e6315aaf9bdL,\n        0xf99ee565f1f344fbL },\n      { 0x8a1d661fd6219199L,0x8c883bc6d48ce41cL,0x1065118f3c74d904L,\n        0x713889ee0faf8b1bL } },\n    /* 2 << 196 */\n    { { 0x972b3f8f81a1b3beL,0x4f3ce145ce2764a0L,0xe2d0f1cc28c4f5f7L,\n        0xdeee0c0dc7f3985bL },\n      { 0x7df4adc0d39e25c3L,0x40619820c467a080L,0x440ebc9361cf5a58L,\n        0x527729a6422ad600L } },\n    /* 3 << 196 */\n    { { 0xca6c0937b1b76ba6L,0x1a2eab854d2026dcL,0xb1715e1519d9ae0aL,\n        0xf1ad9199bac4a026L },\n      { 0x35b3dfb807ea7b0eL,0xedf5496f3ed9eb89L,0x8932e5ff2d6d08abL,\n        0xf314874e25bd2731L } },\n    /* 4 << 196 */\n    { { 0xefb26a753f73f449L,0x1d1c94f88d44fc79L,0x49f0fbc53bc0dc4dL,\n        0xb747ea0b3698a0d0L },\n      { 0x5218c3fe228d291eL,0x35b804b543c129d6L,0xfac859b8d1acc516L,\n        0x6c10697d95d6e668L } },\n    /* 5 << 196 */\n    { { 0xc38e438f0876fd4eL,0x45f0c30783d2f383L,0x203cc2ecb10934cbL,\n        0x6a8f24392c9d46eeL },\n      { 0xf16b431b65ccde7bL,0x41e2cd1827e76a6fL,0xb9c8cf8f4e3484d7L,\n        0x64426efd8315244aL } },\n    /* 6 << 196 */\n    { { 0x1c0a8e44fc94dea3L,0x34c8cdbfdad6a0b0L,0x919c384004113cefL,\n        0xfd32fba415490ffaL },\n      { 0x58d190f6795dcfb7L,0xfef01b0383588bafL,0x9e6d1d63ca1fc1c0L,\n        0x53173f96f0a41ac9L } },\n    /* 7 << 196 */\n    { { 0x2b1d402aba16f73bL,0x2fb310148cf9b9fcL,0x2d51e60e446ef7bfL,\n        0xc731021bb91e1745L },\n      { 0x9d3b47244fee99d4L,0x4bca48b6fac5c1eaL,0x70f5f514bbea9af7L,\n        0x751f55a5974c283aL } },\n    /* 8 << 196 */\n    { { 0x6e30251acb452fdbL,0x31ee696550f30650L,0xb0b3e508933548d9L,\n        0xb8949a4ff4b0ef5bL },\n      { 0x208b83263c88f3bdL,0xab147c30db1d9989L,0xed6515fd44d4df03L,\n        0x17a12f75e72eb0c5L } },\n    /* 9 << 196 */\n    { { 0x3b59796d36cf69dbL,0x1219eee956670c18L,0xfe3341f77a070d8eL,\n        0x9b70130ba327f90cL },\n      { 0x36a324620ae18e0eL,0x2021a62346c0a638L,0x251b5817c62eb0d4L,\n        0x87bfbcdf4c762293L } },\n    /* 10 << 196 */\n    { { 0xf78ab505cdd61d64L,0x8c7a53fcc8c18857L,0xa653ce6f16147515L,\n        0x9c923aa5ea7d52d5L },\n      { 0xc24709cb5c18871fL,0x7d53bec873b3cc74L,0x59264afffdd1d4c4L,\n        0x5555917e240da582L } },\n    /* 11 << 196 */\n    { { 0xcae8bbda548f5a0eL,0x1910eaba3bbfbbe1L,0xae5796857677afc3L,\n        0x49ea61f173ff0b5cL },\n      { 0x786554784f7c3922L,0x95d337cd20c68eefL,0x68f1e1e5df779ab9L,\n        0x14b491b0b5cf69a8L } },\n    /* 12 << 196 */\n    { { 0x7a6cbbe028e3fe89L,0xe7e1fee4c5aac0ebL,0x7f47eda5697e5140L,\n        0x4f450137b454921fL },\n      { 0xdb625f8495cd8185L,0x74be0ba1cdb2e583L,0xaee4fd7cdd5e6de4L,\n        0x4251437de8101739L } },\n    /* 13 << 196 */\n    { { 0x686d72a0ac620366L,0x4be3fb9cb6d59344L,0x6e8b44e7a1eb75b9L,\n        0x84e39da391a5c10cL },\n      { 0x37cc1490b38f0409L,0x029519432c2ade82L,0x9b6887831190a2d8L,\n        0x25627d14231182baL } },\n    /* 14 << 196 */\n    { { 0x6eb550aa658a6d87L,0x1405aaa7cf9c7325L,0xd147142e5c8748c9L,\n        0x7f637e4f53ede0e0L },\n      { 0xf8ca277614ffad2cL,0xe58fb1bdbafb6791L,0x17158c23bf8f93fcL,\n        0x7f15b3730a4a4655L } },\n    /* 15 << 196 */\n    { { 0x39d4add2d842ca72L,0xa71e43913ed96305L,0x5bb09cbe6700be14L,\n        0x68d69d54d8befcf6L },\n      { 0xa45f536737183bcfL,0x7152b7bb3370dff7L,0xcf887baabf12525bL,\n        0xe7ac7bddd6d1e3cdL } },\n    /* 16 << 196 */\n    { { 0x25914f7881fdad90L,0xcf638f560d2cf6abL,0xb90bc03fcc054de5L,\n        0x932811a718b06350L },\n      { 0x2f00b3309bbd11ffL,0x76108a6fb4044974L,0x801bb9e0a851d266L,\n        0x0dd099bebf8990c1L } },\n    /* 17 << 196 */\n    { { 0x58c5aaaaabe32986L,0x0fe9dd2a50d59c27L,0x84951ff48d307305L,\n        0x6c23f82986529b78L },\n      { 0x50bb22180b136a79L,0x7e2174de77a20996L,0x6f00a4b9c0bb4da6L,\n        0x89a25a17efdde8daL } },\n    /* 18 << 196 */\n    { { 0xf728a27ec11ee01dL,0xf900553ae5f10dfbL,0x189a83c802ec893cL,\n        0x3ca5bdc123f66d77L },\n      { 0x9878153797eada9fL,0x59c50ab310256230L,0x346042d9323c69b3L,\n        0x1b715a6d2c460449L } },\n    /* 19 << 196 */\n    { { 0xa41dd4766ae06e0bL,0xcdd7888e9d42e25fL,0x0f395f7456b25a20L,\n        0xeadfe0ae8700e27eL },\n      { 0xb09d52a969950093L,0x3525d9cb327f8d40L,0xb8235a9467df886aL,\n        0x77e4b0dd035faec2L } },\n    /* 20 << 196 */\n    { { 0x115eb20a517d7061L,0x77fe34336c2df683L,0x6870ddc7cdc6fc67L,\n        0xb16105880b87de83L },\n      { 0x343584cad9c4ddbeL,0xb3164f1c3d754be2L,0x0731ed3ac1e6c894L,\n        0x26327dec4f6b904cL } },\n    /* 21 << 196 */\n    { { 0x9d49c6de97b5cd32L,0x40835daeb5eceecdL,0xc66350edd9ded7feL,\n        0x8aeebb5c7a678804L },\n      { 0x51d42fb75b8ee9ecL,0xd7a17bdd8e3ca118L,0x40d7511a2ef4400eL,\n        0xc48990ac875a66f4L } },\n    /* 22 << 196 */\n    { { 0x8de07d2a2199e347L,0xbee755562a39e051L,0x56918786916e51dcL,\n        0xeb1913134a2d89ecL },\n      { 0x6679610d37d341edL,0x434fbb4156d51c2bL,0xe54b7ee7d7492dbaL,\n        0xaa33a79a59021493L } },\n    /* 23 << 196 */\n    { { 0x49fc5054e4bd6d3dL,0x09540f045ab551d0L,0x8acc90854942d3a6L,\n        0x231af02f2d28323bL },\n      { 0x93458cac0992c163L,0x1fef8e71888e3bb4L,0x27578da5be8c268cL,\n        0xcc8be792e805ec00L } },\n    /* 24 << 196 */\n    { { 0x29267baec61c3855L,0xebff429d58c1fd3bL,0x22d886c08c0b93b8L,\n        0xca5e00b22ddb8953L },\n      { 0xcf330117c3fed8b7L,0xd49ac6fa819c01f6L,0x6ddaa6bd3c0fbd54L,\n        0x917430688049a2cfL } },\n    /* 25 << 196 */\n    { { 0xd67f981eaff2ef81L,0xc3654d352818ae80L,0x81d050441b2aa892L,\n        0x2db067bf3d099328L },\n      { 0xe7c79e86703dcc97L,0xe66f9b37e133e215L,0xcdf119a6e39a7a5cL,\n        0x47c60de3876f1b61L } },\n    /* 26 << 196 */\n    { { 0x6e405939d860f1b2L,0x3e9a1dbcf5ed4d4aL,0x3f23619ec9b6bcbdL,\n        0x5ee790cf734e4497L },\n      { 0xf0a834b15bdaf9bbL,0x02cedda74ca295f0L,0x4619aa2bcb8e378cL,\n        0xe5613244cc987ea4L } },\n    /* 27 << 196 */\n    { { 0x0bc022cc76b23a50L,0x4a2793ad0a6c21ceL,0x3832878089cac3f5L,\n        0x29176f1bcba26d56L },\n      { 0x062961874f6f59ebL,0x86e9bca98bdc658eL,0x2ca9c4d357e30402L,\n        0x5438b216516a09bbL } },\n    /* 28 << 196 */\n    { { 0x0a6a063c7672765aL,0x37a3ce640547b9bfL,0x42c099c898b1a633L,\n        0xb5ab800d05ee6961L },\n      { 0xf1963f5911a5acd6L,0xbaee615746201063L,0x36d9a649a596210aL,\n        0xaed043631ba7138cL } },\n    /* 29 << 196 */\n    { { 0xcf817d1ca4a82b76L,0x5586960ef3806be9L,0x7ab67c8909dc6bb5L,\n        0x52ace7a0114fe7ebL },\n      { 0xcd987618cbbc9b70L,0x4f06fd5a604ca5e1L,0x90af14ca6dbde133L,\n        0x1afe4322948a3264L } },\n    /* 30 << 196 */\n    { { 0xa70d2ca6c44b2c6cL,0xab7267990ef87dfeL,0x310f64dc2e696377L,\n        0x49b42e684c8126a0L },\n      { 0x0ea444c3cea0b176L,0x53a8ddf7cb269182L,0xf3e674ebbbba9dcbL,\n        0x0d2878a8d8669d33L } },\n    /* 31 << 196 */\n    { { 0x04b935d5d019b6a3L,0xbb5cf88e406f1e46L,0xa1912d165b57c111L,\n        0x9803fc2119ebfd78L },\n      { 0x4f231c9ec07764a9L,0xd93286eeb75bd055L,0x83a9457d8ee6c9deL,\n        0x046959156087ec90L } },\n    /* 32 << 196 */\n    { { 0x14c6dd8a58d6cd46L,0x9cb633b58e6634d2L,0xc1305047f81bc328L,\n        0x12ede0e226a177e5L },\n      { 0x332cca62065a6f4fL,0xc3a47ecd67be487bL,0x741eb1870f47ed1cL,\n        0x99e66e58e7598b14L } },\n    /* 33 << 196 */\n    { { 0x6f0544ca63d0ff12L,0xe5efc784b610a05fL,0xf72917b17cad7b47L,\n        0x3ff6ea20f2cac0c0L },\n      { 0xcc23791bf21db8b7L,0x7dac70b1d7d93565L,0x682cda1d694bdaadL,\n        0xeb88bb8c1023516dL } },\n    /* 34 << 196 */\n    { { 0xc4c634b4dfdbeb1bL,0x22f5ca72b4ee4deaL,0x1045a368e6524821L,\n        0xed9e8a3f052b18b2L },\n      { 0x9b7f2cb1b961f49aL,0x7fee2ec17b009670L,0x350d875422507a6dL,\n        0x561bd7114db55f1dL } },\n    /* 35 << 196 */\n    { { 0x4c189ccc320bbcafL,0x568434cfdf1de48cL,0x6af1b00e0fa8f128L,\n        0xf0ba9d028907583cL },\n      { 0x735a400432ff9f60L,0x3dd8e4b6c25dcf33L,0xf2230f1642c74cefL,\n        0xd8117623013fa8adL } },\n    /* 36 << 196 */\n    { { 0x36822876f51fe76eL,0x8a6811cc11d62589L,0xc3fc7e6546225718L,\n        0xb7df2c9fc82fdbcdL },\n      { 0x3b1d4e52dd7b205bL,0xb695947847a2e414L,0x05e4d793efa91148L,\n        0xb47ed446fd2e9675L } },\n    /* 37 << 196 */\n    { { 0x1a7098b904c9d9bfL,0x661e28811b793048L,0xb1a16966b01ee461L,\n        0xbc5213082954746fL },\n      { 0xc909a0fc2477de50L,0xd80bb41c7dbd51efL,0xa85be7ec53294905L,\n        0x6d465b1883958f97L } },\n    /* 38 << 196 */\n    { { 0x16f6f330fb6840fdL,0xfaaeb2143401e6c8L,0xaf83d30fccb5b4f8L,\n        0x22885739266dec4bL },\n      { 0x51b4367c7bc467dfL,0x926562e3d842d27aL,0xdfcb66140fea14a6L,\n        0xeb394daef2734cd9L } },\n    /* 39 << 196 */\n    { { 0x3eeae5d211c0be98L,0xb1e6ed11814e8165L,0x191086bce52bce1cL,\n        0x14b74cc6a75a04daL },\n      { 0x63cf11868c060985L,0x071047de2dbd7f7cL,0x4e433b8bce0942caL,\n        0xecbac447d8fec61dL } },\n    /* 40 << 196 */\n    { { 0x8f0ed0e2ebf3232fL,0xfff80f9ec52a2eddL,0xad9ab43375b55fdbL,\n        0x73ca7820e42e0c11L },\n      { 0x6dace0a0e6251b46L,0x89bc6b5c4c0d932dL,0x3438cd77095da19aL,\n        0x2f24a9398d48bdfbL } },\n    /* 41 << 196 */\n    { { 0x99b47e46766561b7L,0x736600e60ed0322aL,0x06a47cb1638e1865L,\n        0x927c1c2dcb136000L },\n      { 0x295423370cc5df69L,0x99b37c0209d649a9L,0xc5f0043c6aefdb27L,\n        0x6cdd99871be95c27L } },\n    /* 42 << 196 */\n    { { 0x69850931390420d2L,0x299c40ac0983efa4L,0x3a05e778af39aeadL,\n        0x8427440843a45193L },\n      { 0x6bcd0fb991a711a0L,0x461592c89f52ab17L,0xb49302b4da3c6ed6L,\n        0xc51fddc7330d7067L } },\n    /* 43 << 196 */\n    { { 0x94babeb6da50d531L,0x521b840da6a7b9daL,0x5305151e404bdc89L,\n        0x1bcde201d0d07449L },\n      { 0xf427a78b3b76a59aL,0xf84841ce07791a1bL,0xebd314bebf91ed1cL,\n        0x8e61d34cbf172943L } },\n    /* 44 << 196 */\n    { { 0x1d5dc4515541b892L,0xb186ee41fc9d9e54L,0x9d9f345ed5bf610dL,\n        0x3e7ba65df6acca9fL },\n      { 0x9dda787aa8369486L,0x09f9dab78eb5ba53L,0x5afb2033d6481bc3L,\n        0x76f4ce30afa62104L } },\n    /* 45 << 196 */\n    { { 0xa8fa00cff4f066b5L,0x89ab5143461dafc2L,0x44339ed7a3389998L,\n        0x2ff862f1bc214903L },\n      { 0x2c88f985b05556e3L,0xcd96058e3467081eL,0x7d6a4176edc637eaL,\n        0xe1743d0936a5acdcL } },\n    /* 46 << 196 */\n    { { 0x66fd72e27eb37726L,0xf7fa264e1481a037L,0x9fbd3bde45f4aa79L,\n        0xed1e0147767c3e22L },\n      { 0x7621f97982e7abe2L,0x19eedc7245f633f8L,0xe69b155e6137bf3aL,\n        0xa0ad13ce414ee94eL } },\n    /* 47 << 196 */\n    { { 0x93e3d5241c0e651aL,0xab1a6e2a02ce227eL,0xe7af17974ab27ecaL,\n        0x245446debd444f39L },\n      { 0x59e22a2156c07613L,0x43deafcef4275498L,0x10834ccb67fd0946L,\n        0xa75841e547406edfL } },\n    /* 48 << 196 */\n    { { 0xebd6a6777b0ac93dL,0xa6e37b0d78f5e0d7L,0x2516c09676f5492bL,\n        0x1e4bf8889ac05f3aL },\n      { 0xcdb42ce04df0ba2bL,0x935d5cfd5062341bL,0x8a30333382acac20L,\n        0x429438c45198b00eL } },\n    /* 49 << 196 */\n    { { 0x1d083bc9049d33faL,0x58b82dda946f67ffL,0xac3e2db867a1d6a3L,\n        0x62e6bead1798aac8L },\n      { 0xfc85980fde46c58cL,0xa7f6937969c8d7beL,0x23557927837b35ecL,\n        0x06a933d8e0790c0cL } },\n    /* 50 << 196 */\n    { { 0x827c0e9b077ff55dL,0x53977798bb26e680L,0x595308741d9cb54fL,\n        0xcca3f4494aac53efL },\n      { 0x11dc5c87a07eda0fL,0xc138bccffd6400c8L,0x549680d313e5da72L,\n        0xc93eed824540617eL } },\n    /* 51 << 196 */\n    { { 0xfd3db1574d0b75c0L,0x9716eb426386075bL,0x0639605c817b2c16L,\n        0x09915109f1e4f201L },\n      { 0x35c9a9285cca6c3bL,0xb25f7d1a3505c900L,0xeb9f7d20630480c4L,\n        0xc3c7b8c62a1a501cL } },\n    /* 52 << 196 */\n    { { 0x3f99183c5a1f8e24L,0xfdb118fa9dd255f0L,0xb9b18b90c27f62a6L,\n        0xe8f732f7396ec191L },\n      { 0x524a2d910be786abL,0x5d32adef0ac5a0f5L,0x9b53d4d69725f694L,\n        0x032a76c60510ba89L } },\n    /* 53 << 196 */\n    { { 0x840391a3ebeb1544L,0x44b7b88c3ed73ac3L,0xd24bae7a256cb8b3L,\n        0x7ceb151ae394cb12L },\n      { 0xbd6b66d05bc1e6a8L,0xec70cecb090f07bfL,0x270644ed7d937589L,\n        0xee9e1a3d5f1dccfeL } },\n    /* 54 << 196 */\n    { { 0xb0d40a84745b98d2L,0xda429a212556ed40L,0xf676eced85148cb9L,\n        0x5a22d40cded18936L },\n      { 0x3bc4b9e570e8a4ceL,0xbfd1445b9eae0379L,0xf23f2c0c1a0bd47eL,\n        0xa9c0bb31e1845531L } },\n    /* 55 << 196 */\n    { { 0x9ddc4d600a4c3f6bL,0xbdfaad792c15ef44L,0xce55a2367f484accL,\n        0x08653ca7055b1f15L },\n      { 0x2efa8724538873a3L,0x09299e5dace1c7e7L,0x07afab66ade332baL,\n        0x9be1fdf692dd71b7L } },\n    /* 56 << 196 */\n    { { 0xa49b5d595758b11cL,0x0b852893c8654f40L,0xb63ef6f452379447L,\n        0xd4957d29105e690cL },\n      { 0x7d484363646559b0L,0xf4a8273c49788a8eL,0xee406cb834ce54a9L,\n        0x1e1c260ff86fda9bL } },\n    /* 57 << 196 */\n    { { 0xe150e228cf6a4a81L,0x1fa3b6a31b488772L,0x1e6ff110c5a9c15bL,\n        0xc6133b918ad6aa47L },\n      { 0x8ac5d55c9dffa978L,0xba1d1c1d5f3965f2L,0xf969f4e07732b52fL,\n        0xfceecdb5a5172a07L } },\n    /* 58 << 196 */\n    { { 0xb0120a5f10f2b8f5L,0xc83a6cdf5c4c2f63L,0x4d47a491f8f9c213L,\n        0xd9e1cce5d3f1bbd5L },\n      { 0x0d91bc7caba7e372L,0xfcdc74c8dfd1a2dbL,0x05efa800374618e5L,\n        0x1121696915a7925eL } },\n    /* 59 << 196 */\n    { { 0xd4c89823f6021c5dL,0x880d5e84eff14423L,0x6523bc5a6dcd1396L,\n        0xd1acfdfc113c978bL },\n      { 0xb0c164e8bbb66840L,0xf7f4301e72b58459L,0xc29ad4a6a638e8ecL,\n        0xf5ab896146b78699L } },\n    /* 60 << 196 */\n    { { 0x9dbd79740e954750L,0x0121de8864f9d2c6L,0x2e597b42d985232eL,\n        0x55b6c3c553451777L },\n      { 0xbb53e547519cb9fbL,0xf134019f8428600dL,0x5a473176e081791aL,\n        0x2f3e226335fb0c08L } },\n    /* 61 << 196 */\n    { { 0xb28c301773d273b0L,0xccd210767721ef9aL,0x054cc292b650dc39L,\n        0x662246de6188045eL },\n      { 0x904b52fa6b83c0d1L,0xa72df26797e9cd46L,0x886b43cd899725e4L,\n        0x2b651688d849ff22L } },\n    /* 62 << 196 */\n    { { 0x60479b7902f34533L,0x5e354c140c77c148L,0xb4bb7581a8537c78L,\n        0x188043d7efe1495fL },\n      { 0x9ba12f428c1d5026L,0x2e0c8a2693d4aaabL,0xbdba7b8baa57c450L,\n        0x140c9ad69bbdafefL } },\n    /* 63 << 196 */\n    { { 0x2067aa4225ac0f18L,0xf7b1295b04d1fbf3L,0x14829111a4b04824L,\n        0x2ce3f19233bd5e91L },\n      { 0x9c7a1d558f2e1b72L,0xfe932286302aa243L,0x497ca7b4d4be9554L,\n        0xb8e821b8e0547a6eL } },\n    /* 64 << 196 */\n    { { 0xfb2838be67e573e0L,0x05891db94084c44bL,0x9131137396c1c2c5L,\n        0x6aebfa3fd958444bL },\n      { 0xac9cdce9e56e55c1L,0x7148ced32caa46d0L,0x2e10c7efb61fe8ebL,\n        0x9fd835daff97cf4dL } },\n    /* 0 << 203 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 203 */\n    { { 0xa36da109081e9387L,0xfb9780d78c935828L,0xd5940332e540b015L,\n        0xc9d7b51be0f466faL },\n      { 0xfaadcd41d6d9f671L,0xba6c1e28b1a2ac17L,0x066a7833ed201e5fL,\n        0x19d99719f90f462bL } },\n    /* 2 << 203 */\n    { { 0xf431f462060b5f61L,0xa56f46b47bd057c2L,0x348dca6c47e1bf65L,\n        0x9a38783e41bcf1ffL },\n      { 0x7a5d33a9da710718L,0x5a7799872e0aeaf6L,0xca87314d2d29d187L,\n        0xfa0edc3ec687d733L } },\n    /* 3 << 203 */\n    { { 0x9df336216a31e09bL,0xde89e44dc1350e35L,0x292148714ca0cf52L,\n        0xdf3796720b88a538L },\n      { 0xc92a510a2591d61bL,0x79aa87d7585b447bL,0xf67db604e5287f77L,\n        0x1697c8bf5efe7a80L } },\n    /* 4 << 203 */\n    { { 0x1c894849cb198ac7L,0xa884a93d0f264665L,0x2da964ef9b200678L,\n        0x3c351b87009834e6L },\n      { 0xafb2ef9fe2c4b44bL,0x580f6c473326790cL,0xb84805210b02264aL,\n        0x8ba6f9e242a194e2L } },\n    /* 5 << 203 */\n    { { 0xfc87975f8fb54738L,0x3516078827c3ead3L,0x834116d2b74a085aL,\n        0x53c99a73a62fe996L },\n      { 0x87585be05b81c51bL,0x925bafa8be0852b7L,0x76a4fafda84d19a7L,\n        0x39a45982585206d4L } },\n    /* 6 << 203 */\n    { { 0x499b6ab65eb03c0eL,0xf19b795472bc3fdeL,0xa86b5b9c6e3a80d2L,\n        0xe43775086d42819fL },\n      { 0xc1663650bb3ee8a3L,0x75eb14fcb132075fL,0xa8ccc9067ad834f6L,\n        0xea6a2474e6e92ffdL } },\n    /* 7 << 203 */\n    { { 0x9d72fd950f8d6758L,0xcb84e101408c07ddL,0xb9114bfda5e23221L,\n        0x358b5fe2e94e742cL },\n      { 0x1c0577ec95f40e75L,0xf01554513d73f3d6L,0x9d55cd67bd1b9b66L,\n        0x63e86e78af8d63c7L } },\n    /* 8 << 203 */\n    { { 0x39d934abd3c095f1L,0x04b261bee4b76d71L,0x1d2e6970e73e6984L,\n        0x879fb23b5e5fcb11L },\n      { 0x11506c72dfd75490L,0x3a97d08561bcf1c1L,0x43201d82bf5e7007L,\n        0x7f0ac52f798232a7L } },\n    /* 9 << 203 */\n    { { 0x2715cbc46eb564d4L,0x8d6c752c9e570e29L,0xf80247c89ef5fd5dL,\n        0xc3c66b46d53eb514L },\n      { 0x9666b4010f87de56L,0xce62c06fc6c603b5L,0xae7b4c607e4fc942L,\n        0x38ac0b77663a9c19L } },\n    /* 10 << 203 */\n    { { 0xcb4d20ee4b049136L,0x8b63bf12356a4613L,0x1221aef670e08128L,\n        0xe62d8c514acb6b16L },\n      { 0x71f64a67379e7896L,0xb25237a2cafd7fa5L,0xf077bd983841ba6aL,\n        0xc4ac02443cd16e7eL } },\n    /* 11 << 203 */\n    { { 0x548ba86921fea4caL,0xd36d0817f3dfdac1L,0x09d8d71ff4685fafL,\n        0x8eff66bec52c459aL },\n      { 0x182faee70b57235eL,0xee3c39b10106712bL,0x5107331fc0fcdcb0L,\n        0x669fb9dca51054baL } },\n    /* 12 << 203 */\n    { { 0xb25101fb319d7682L,0xb02931290a982feeL,0x51c1c9b90261b344L,\n        0x0e008c5bbfd371faL },\n      { 0xd866dd1c0278ca33L,0x666f76a6e5aa53b1L,0xe5cfb7796013a2cfL,\n        0x1d3a1aada3521836L } },\n    /* 13 << 203 */\n    { { 0xcedd253173faa485L,0xc8ee6c4fc0a76878L,0xddbccfc92a11667dL,\n        0x1a418ea91c2f695aL },\n      { 0xdb11bd9251f73971L,0x3e4b3c82da2ed89fL,0x9a44f3f4e73e0319L,\n        0xd1e3de0f303431afL } },\n    /* 14 << 203 */\n    { { 0x3c5604ff50f75f9cL,0x1d8eddf37e752b22L,0x0ef074dd3c9a1118L,\n        0xd0ffc172ccb86d7bL },\n      { 0xabd1ece3037d90f2L,0xe3f307d66055856cL,0x422f93287e4c6dafL,\n        0x902aac66334879a0L } },\n    /* 15 << 203 */\n    { { 0xb6a1e7bf94cdfadeL,0x6c97e1ed7fc6d634L,0x662ad24da2fb63f8L,\n        0xf81be1b9a5928405L },\n      { 0x86d765e4d14b4206L,0xbecc2e0e8fa0db65L,0xa28838e0b17fc76cL,\n        0xe49a602ae37cf24eL } },\n    /* 16 << 203 */\n    { { 0x76b4131a567193ecL,0xaf3c305ae5f6e70bL,0x9587bd39031eebddL,\n        0x5709def871bbe831L },\n      { 0x570599830eb2b669L,0x4d80ce1b875b7029L,0x838a7da80364ac16L,\n        0x2f431d23be1c83abL } },\n    /* 17 << 203 */\n    { { 0xe56812a6f9294dd3L,0xb448d01f9b4b0d77L,0xf3ae606104e8305cL,\n        0x2bead64594d8c63eL },\n      { 0x0a85434d84fd8b07L,0x537b983ff7a9dee5L,0xedcc5f18ef55bd85L,\n        0x2041af6221c6cf8bL } },\n    /* 18 << 203 */\n    { { 0x8e52874cb940c71eL,0x211935a9db5f4b3aL,0x94350492301b1dc3L,\n        0x33d2646d29958620L },\n      { 0x16b0d64bef911404L,0x9d1f25ea9a3c5ef4L,0x20f200eb4a352c78L,\n        0x43929f2c4bd0b428L } },\n    /* 19 << 203 */\n    { { 0xa5656667c7196e29L,0x7992c2f09391be48L,0xaaa97cbd9ee0cd6eL,\n        0x51b0310c3dc8c9bfL },\n      { 0x237f8acfdd9f22cbL,0xbb1d81a1b585d584L,0x8d5d85f58c416388L,\n        0x0d6e5a5a42fe474fL } },\n    /* 20 << 203 */\n    { { 0xe781276638235d4eL,0x1c62bd67496e3298L,0x8378660c3f175bc8L,\n        0x4d04e18917afdd4dL },\n      { 0x32a8160185a8068cL,0xdb58e4e192b29a85L,0xe8a65b86c70d8a3bL,\n        0x5f0e6f4e98a0403bL } },\n    /* 21 << 203 */\n    { { 0x0812968469ed2370L,0x34dc30bd0871ee26L,0x3a5ce9487c9c5b05L,\n        0x7d487b8043a90c87L },\n      { 0x4089ba37dd0e7179L,0x45f80191b4041811L,0x1c3e105898747ba5L,\n        0x98c4e13a6e1ae592L } },\n    /* 22 << 203 */\n    { { 0xd44636e6e82c9f9eL,0x711db87cc33a1043L,0x6f431263aa8aec05L,\n        0x43ff120d2744a4aaL },\n      { 0xd3bd892fae77779bL,0xf0fe0cc98cdc9f82L,0xca5f7fe6f1c5b1bcL,\n        0xcc63a68244929a72L } },\n    /* 23 << 203 */\n    { { 0xc7eaba0c09dbe19aL,0x2f3585ad6b5c73c2L,0x8ab8924b0ae50c30L,\n        0x17fcd27a638b30baL },\n      { 0xaf414d3410b3d5a5L,0x09c107d22a9accf1L,0x15dac49f946a6242L,\n        0xaec3df2ad707d642L } },\n    /* 24 << 203 */\n    { { 0x2c2492b73f894ae0L,0xf59df3e5b75f18ceL,0x7cb740d28f53cad0L,\n        0x3eb585fbc4f01294L },\n      { 0x17da0c8632c7f717L,0xeb8c795baf943f4cL,0x4ee23fb5f67c51d2L,\n        0xef18757568889949L } },\n    /* 25 << 203 */\n    { { 0xa6b4bdb20389168bL,0xc4ecd258ea577d03L,0x3a63782b55743082L,\n        0x6f678f4cc72f08cdL },\n      { 0x553511cf65e58dd8L,0xd53b4e3ed402c0cdL,0x37de3e29a037c14cL,\n        0x86b6c516c05712aaL } },\n    /* 26 << 203 */\n    { { 0x2834da3eb38dff6fL,0xbe012c52ea636be8L,0x292d238c61dd37f8L,\n        0x0e54523f8f8142dbL },\n      { 0xe31eb436036a05d8L,0x83e3cdff1e93c0ffL,0x3fd2fe0f50821ddfL,\n        0xc8e19b0dff9eb33bL } },\n    /* 27 << 203 */\n    { { 0xc8cc943fb569a5feL,0xad0090d4d4342d75L,0x82090b4bcaeca000L,\n        0xca39687f1bd410ebL },\n      { 0xe7bb0df765959d77L,0x39d782189c964999L,0xd87f62e8b2415451L,\n        0xe5efb774bed76108L } },\n    /* 28 << 203 */\n    { { 0x3ea011a4e822f0d0L,0xbc647ad15a8704f8L,0xbb315b3550c6820fL,\n        0x863dec3db7e76becL },\n      { 0x01ff5d3af017bfc7L,0x20054439976b8229L,0x067fca370bbd0d3bL,\n        0xf63dde647f5e3d0fL } },\n    /* 29 << 203 */\n    { { 0x22dbefb32a4c94e9L,0xafbff0fe96f8278aL,0x80aea0b13503793dL,\n        0xb22380295f06cd29L },\n      { 0x65703e578ec3fecaL,0x06c38314393e7053L,0xa0b751eb7c6734c4L,\n        0xd2e8a435c59f0f1eL } },\n    /* 30 << 203 */\n    { { 0x147d90525e9ca895L,0x2f4dd31e972072dfL,0xa16fda8ee6c6755cL,\n        0xc66826ffcf196558L },\n      { 0x1f1a76a30cf43895L,0xa9d604e083c3097bL,0xe190830966390e0eL,\n        0xa50bf753b3c85effL } },\n    /* 31 << 203 */\n    { { 0x0696bddef6a70251L,0x548b801b3c6ab16aL,0x37fcf704a4d08762L,\n        0x090b3defdff76c4eL },\n      { 0x87e8cb8969cb9158L,0x44a90744995ece43L,0xf85395f40ad9fbf5L,\n        0x49b0f6c54fb0c82dL } },\n    /* 32 << 203 */\n    { { 0x75d9bc15adf7cccfL,0x81a3e5d6dfa1e1b0L,0x8c39e444249bc17eL,\n        0xf37dccb28ea7fd43L },\n      { 0xda654873907fba12L,0x35daa6da4a372904L,0x0564cfc66283a6c5L,\n        0xd09fa4f64a9395bfL } },\n    /* 33 << 203 */\n    { { 0x688e9ec9aeb19a36L,0xd913f1cec7bfbfb4L,0x797b9a3c61c2faa6L,\n        0x2f979bec6a0a9c12L },\n      { 0xb5969d0f359679ecL,0xebcf523d079b0460L,0xfd6b000810fab870L,\n        0x3f2edcda9373a39cL } },\n    /* 34 << 203 */\n    { { 0x0d64f9a76f568431L,0xf848c27c02f8898cL,0xf418ade1260b5bd5L,\n        0xc1f3e3236973dee8L },\n      { 0x46e9319c26c185ddL,0x6d85b7d8546f0ac4L,0x427965f2247f9d57L,\n        0xb519b636b0035f48L } },\n    /* 35 << 203 */\n    { { 0x6b6163a9ab87d59cL,0xff9f58c339caaa11L,0x4ac39cde3177387bL,\n        0x5f6557c2873e77f9L },\n      { 0x6750400636a83041L,0x9b1c96ca75ef196cL,0xf34283deb08c7940L,\n        0x7ea096441128c316L } },\n    /* 36 << 203 */\n    { { 0xb510b3b56aa39dffL,0x59b43da29f8e4d8cL,0xa8ce31fd9e4c4b9fL,\n        0x0e20be26c1303c01L },\n      { 0x18187182e8ee47c9L,0xd9687cdb7db98101L,0x7a520e4da1e14ff6L,\n        0x429808ba8836d572L } },\n    /* 37 << 203 */\n    { { 0xa37ca60d4944b663L,0xf901f7a9a3f91ae5L,0xe4e3e76e9e36e3b1L,\n        0x9aa219cf29d93250L },\n      { 0x347fe275056a2512L,0xa4d643d9de65d95cL,0x9669d396699fc3edL,\n        0xb598dee2cf8c6bbeL } },\n    /* 38 << 203 */\n    { { 0x682ac1e5dda9e5c6L,0x4e0d3c72caa9fc95L,0x17faaade772bea44L,\n        0x5ef8428cab0009c8L },\n      { 0xcc4ce47a460ff016L,0xda6d12bf725281cbL,0x44c678480223aad2L,\n        0x6e342afa36256e28L } },\n    /* 39 << 203 */\n    { { 0x1400bb0b93a37c04L,0x62b1bc9bdd10bd96L,0x7251adeb0dac46b7L,\n        0x7d33b92e7be4ef51L },\n      { 0x28b2a94be61fa29aL,0x4b2be13f06422233L,0x36d6d062330d8d37L,\n        0x5ef80e1eb28ca005L } },\n    /* 40 << 203 */\n    { { 0x174d46996d16768eL,0x9fc4ff6a628bf217L,0x77705a94154e490dL,\n        0x9d96dd288d2d997aL },\n      { 0x77e2d9d8ce5d72c4L,0x9d06c5a4c11c714fL,0x02aa513679e4a03eL,\n        0x1386b3c2030ff28bL } },\n    /* 41 << 203 */\n    { { 0xfe82e8a6fb283f61L,0x7df203e5f3abc3fbL,0xeec7c3513a4d3622L,\n        0xf7d17dbfdf762761L },\n      { 0xc3956e44522055f0L,0xde3012db8fa748dbL,0xca9fcb63bf1dcc14L,\n        0xa56d9dcfbe4e2f3aL } },\n    /* 42 << 203 */\n    { { 0xb86186b68bcec9c2L,0x7cf24df9680b9f06L,0xc46b45eac0d29281L,\n        0xfff42bc507b10e12L },\n      { 0x12263c404d289427L,0x3d5f1899b4848ec4L,0x11f97010d040800cL,\n        0xb4c5f529300feb20L } },\n    /* 43 << 203 */\n    { { 0xcc543f8fde94fdcbL,0xe96af739c7c2f05eL,0xaa5e0036882692e1L,\n        0x09c75b68950d4ae9L },\n      { 0x62f63df2b5932a7aL,0x2658252ede0979adL,0x2a19343fb5e69631L,\n        0x718c7501525b666bL } },\n    /* 44 << 203 */\n    { { 0x26a42d69ea40dc3aL,0xdc84ad22aecc018fL,0x25c36c7b3270f04aL,\n        0x46ba6d4750fa72edL },\n      { 0x6c37d1c593e58a8eL,0xa2394731120c088cL,0xc3be4263cb6e86daL,\n        0x2c417d367126d038L } },\n    /* 45 << 203 */\n    { { 0x5b70f9c58b6f8efaL,0x671a2faa37718536L,0xd3ced3c6b539c92bL,\n        0xe56f1bd9a31203c2L },\n      { 0x8b096ec49ff3c8ebL,0x2deae43243491ceaL,0x2465c6eb17943794L,\n        0x5d267e6620586843L } },\n    /* 46 << 203 */\n    { { 0x9d3d116db07159d0L,0xae07a67fc1896210L,0x8fc84d87bb961579L,\n        0x30009e491c1f8dd6L },\n      { 0x8a8caf22e3132819L,0xcffa197cf23ab4ffL,0x58103a44205dd687L,\n        0x57b796c30ded67a2L } },\n    /* 47 << 203 */\n    { { 0x0b9c3a6ca1779ad7L,0xa33cfe2e357c09c5L,0x2ea293153db4a57eL,\n        0x919596958ebeb52eL },\n      { 0x118db9a6e546c879L,0x8e996df46295c8d6L,0xdd99048455ec806bL,\n        0x24f291ca165c1035L } },\n    /* 48 << 203 */\n    { { 0xcca523bb440e2229L,0x324673a273ef4d04L,0xaf3adf343e11ec39L,\n        0x6136d7f1dc5968d3L },\n      { 0x7a7b2899b053a927L,0x3eaa2661ae067ecdL,0x8549b9c802779cd9L,\n        0x061d7940c53385eaL } },\n    /* 49 << 203 */\n    { { 0x3e0ba883f06d18bdL,0x4ba6de53b2700843L,0xb966b668591a9e4dL,\n        0x93f675677f4fa0edL },\n      { 0x5a02711b4347237bL,0xbc041e2fe794608eL,0x55af10f570f73d8cL,\n        0xd2d4d4f7bb7564f7L } },\n    /* 50 << 203 */\n    { { 0xd7d27a89b3e93ce7L,0xf7b5a8755d3a2c1bL,0xb29e68a0255b218aL,\n        0xb533837e8af76754L },\n      { 0xd1b05a73579fab2eL,0xb41055a1ecd74385L,0xb2369274445e9115L,\n        0x2972a7c4f520274eL } },\n    /* 51 << 203 */\n    { { 0x6c08334ef678e68aL,0x4e4160f099b057edL,0x3cfe11b852ccb69aL,\n        0x2fd1823a21c8f772L },\n      { 0xdf7f072f3298f055L,0x8c0566f9fec74a6eL,0xe549e0195bb4d041L,\n        0x7c3930ba9208d850L } },\n    /* 52 << 203 */\n    { { 0xe07141fcaaa2902bL,0x539ad799e4f69ad3L,0xa6453f94813f9ffdL,\n        0xc58d3c48375bc2f7L },\n      { 0xb3326fad5dc64e96L,0x3aafcaa9b240e354L,0x1d1b0903aca1e7a9L,\n        0x4ceb97671211b8a0L } },\n    /* 53 << 203 */\n    { { 0xeca83e49e32a858eL,0x4c32892eae907badL,0xd5b42ab62eb9b494L,\n        0x7fde3ee21eabae1bL },\n      { 0x13b5ab09caf54957L,0xbfb028bee5f5d5d5L,0x928a06502003e2c0L,\n        0x90793aac67476843L } },\n    /* 54 << 203 */\n    { { 0x5e942e79c81710a0L,0x557e4a3627ccadd4L,0x72a2bc564bcf6d0cL,\n        0x09ee5f4326d7b80cL },\n      { 0x6b70dbe9d4292f19L,0x56f74c2663f16b18L,0xc23db0f735fbb42aL,\n        0xb606bdf66ae10040L } },\n    /* 55 << 203 */\n    { { 0x1eb15d4d044573acL,0x7dc3cf86556b0ba4L,0x97af9a33c60df6f7L,\n        0x0b1ef85ca716ce8cL },\n      { 0x2922f884c96958beL,0x7c32fa9435690963L,0x2d7f667ceaa00061L,\n        0xeaaf7c173547365cL } },\n    /* 56 << 203 */\n    { { 0x1eb4de4687032d58L,0xc54f3d835e2c79e0L,0x07818df45d04ef23L,\n        0x55faa9c8673d41b4L },\n      { 0xced64f6f89b95355L,0x4860d2eab7415c84L,0x5fdb9bd2050ebad3L,\n        0xdb53e0cc6685a5bfL } },\n    /* 57 << 203 */\n    { { 0xb830c0319feb6593L,0xdd87f3106accff17L,0x2303ebab9f555c10L,\n        0x94603695287e7065L },\n      { 0xf88311c32e83358cL,0x508dd9b4eefb0178L,0x7ca237062dba8652L,\n        0x62aac5a30047abe5L } },\n    /* 58 << 203 */\n    { { 0x9a61d2a08b1ea7b3L,0xd495ab63ae8b1485L,0x38740f8487052f99L,\n        0x178ebe5bb2974eeaL },\n      { 0x030bbcca5b36d17fL,0xb5e4cce3aaf86eeaL,0xb51a022068f8e9e0L,\n        0xa434879609eb3e75L } },\n    /* 59 << 203 */\n    { { 0xbe592309eef1a752L,0x5d7162d76f2aa1edL,0xaebfb5ed0f007dd2L,\n        0x255e14b2c89edd22L },\n      { 0xba85e0720303b697L,0xc5d17e25f05720ffL,0x02b58d6e5128ebb6L,\n        0x2c80242dd754e113L } },\n    /* 60 << 203 */\n    { { 0x919fca5fabfae1caL,0x937afaac1a21459bL,0x9e0ca91c1f66a4d2L,\n        0x194cc7f323ec1331L },\n      { 0xad25143a8aa11690L,0xbe40ad8d09b59e08L,0x37d60d9be750860aL,\n        0x6c53b008c6bf434cL } },\n    /* 61 << 203 */\n    { { 0xb572415d1356eb80L,0xb8bf9da39578ded8L,0x22658e365e8fb38bL,\n        0x9b70ce225af8cb22L },\n      { 0x7c00018a829a8180L,0x84329f93b81ed295L,0x7c343ea25f3cea83L,\n        0x38f8655f67586536L } },\n    /* 62 << 203 */\n    { { 0xa661a0d01d3ec517L,0x98744652512321aeL,0x084ca591eca92598L,\n        0xa9bb9dc91dcb3febL },\n      { 0x14c5435578b4c240L,0x5ed62a3b610cafdcL,0x07512f371b38846bL,\n        0x571bb70ab0e38161L } },\n    /* 63 << 203 */\n    { { 0xb556b95b2da705d2L,0x3ef8ada6b1a08f98L,0x85302ca7ddecfbe5L,\n        0x0e530573943105cdL },\n      { 0x60554d5521a9255dL,0x63a32fa1f2f3802aL,0x35c8c5b0cd477875L,\n        0x97f458ea6ad42da1L } },\n    /* 64 << 203 */\n    { { 0x832d7080eb6b242dL,0xd30bd0233b71e246L,0x7027991bbe31139dL,\n        0x68797e91462e4e53L },\n      { 0x423fe20a6b4e185aL,0x82f2c67e42d9b707L,0x25c817684cf7811bL,\n        0xbd53005e045bb95dL } },\n    /* 0 << 210 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 210 */\n    { { 0xe5f649be9d8e68fdL,0xdb0f05331b044320L,0xf6fde9b3e0c33398L,\n        0x92f4209b66c8cfaeL },\n      { 0xe9d1afcc1a739d4bL,0x09aea75fa28ab8deL,0x14375fb5eac6f1d0L,\n        0x6420b560708f7aa5L } },\n    /* 2 << 210 */\n    { { 0x9eae499c6254dc41L,0x7e2939247a837e7eL,0x74aec08c090524a7L,\n        0xf82b92198d6f55f2L },\n      { 0x493c962e1402cec5L,0x9f17ca17fa2f30e7L,0xbcd783e8e9b879cbL,\n        0xea3d8c145a6f145fL } },\n    /* 3 << 210 */\n    { { 0xdede15e75e0dee6eL,0x74f24872dc628aa2L,0xd3e9c4fe7861bb93L,\n        0x56d4822a6187b2e0L },\n      { 0xb66417cfc59826f9L,0xca2609692408169eL,0xedf69d06c79ef885L,\n        0x00031f8adc7d138fL } },\n    /* 4 << 210 */\n    { { 0x103c46e60ebcf726L,0x4482b8316231470eL,0x6f6dfaca487c2109L,\n        0x2e0ace9762e666efL },\n      { 0x3246a9d31f8d1f42L,0x1b1e83f1574944d2L,0x13dfa63aa57f334bL,\n        0x0cf8daed9f025d81L } },\n    /* 5 << 210 */\n    { { 0x30d78ea800ee11c1L,0xeb053cd4b5e3dd75L,0x9b65b13ed58c43c5L,\n        0xc3ad49bdbd151663L },\n      { 0x99fd8e41b6427990L,0x12cf15bd707eae1eL,0x29ad4f1b1aabb71eL,\n        0x5143e74d07545d0eL } },\n    /* 6 << 210 */\n    { { 0x30266336c88bdee1L,0x25f293065876767cL,0x9c078571c6731996L,\n        0xc88690b2ed552951L },\n      { 0x274f2c2d852705b4L,0xb0bf8d444e09552dL,0x7628beeb986575d1L,\n        0x407be2387f864651L } },\n    /* 7 << 210 */\n    { { 0x0e5e3049a639fc6bL,0xe75c35d986003625L,0x0cf35bd85dcc1646L,\n        0x8bcaced26c26273aL },\n      { 0xe22ecf1db5536742L,0x013dd8971a9e068bL,0x17f411cb8a7909c5L,\n        0x5757ac98861dd506L } },\n    /* 8 << 210 */\n    { { 0x85de1f0d1e935abbL,0xdefd10b4154de37aL,0xb8d9e392369cebb5L,\n        0x54d5ef9b761324beL },\n      { 0x4d6341ba74f17e26L,0xc0a0e3c878c1dde4L,0xa6d7758187d918fdL,\n        0x6687601502ca3a13L } },\n    /* 9 << 210 */\n    { { 0xc7313e9cf36658f0L,0xc433ef1c71f8057eL,0x853262461b6a835aL,\n        0xc8f053987c86394cL },\n      { 0xff398cdfe983c4a1L,0xbf5e816203b7b931L,0x93193c46b7b9045bL,\n        0x1e4ebf5da4a6e46bL } },\n    /* 10 << 210 */\n    { { 0xf9942a6043a24fe7L,0x29c1191effb3492bL,0x9f662449902fde05L,\n        0xc792a7ac6713c32dL },\n      { 0x2fd88ad8b737982cL,0x7e3a0319a21e60e3L,0x09b0de447383591aL,\n        0x6df141ee8310a456L } },\n    /* 11 << 210 */\n    { { 0xaec1a039e6d6f471L,0x14b2ba0f1198d12eL,0xebc1a1603aeee5acL,\n        0x401f4836e0b964ceL },\n      { 0x2ee437964fd03f66L,0x3fdb4e49dd8f3f12L,0x6ef267f629380f18L,\n        0x3e8e96708da64d16L } },\n    /* 12 << 210 */\n    { { 0xbc19180c207674f1L,0x112e09a733ae8fdbL,0x996675546aaeb71eL,\n        0x79432af1e101b1c7L },\n      { 0xd5eb558fde2ddec6L,0x81392d1f5357753fL,0xa7a76b973ae1158aL,\n        0x416fbbff4a899991L } },\n    /* 13 << 210 */\n    { { 0x9e65fdfd0d4a9dcfL,0x7bc29e48944ddf12L,0xbc1a92d93c856866L,\n        0x273c69056e98dfe2L },\n      { 0x69fce418cdfaa6b8L,0x606bd8235061c69fL,0x42d495a06af75e27L,\n        0x8ed3d5056d873a1fL } },\n    /* 14 << 210 */\n    { { 0xaf5528416ab25b6aL,0xc6c0ffc72b1a4523L,0xab18827b21c99e03L,\n        0x060e86489034691bL },\n      { 0x5207f90f93c7f398L,0x9f4a96cb82f8d10bL,0xdd71cd793ad0f9e3L,\n        0x84f435d2fc3a54f5L } },\n    /* 15 << 210 */\n    { { 0x4b03c55b8e33787fL,0xef42f975a6384673L,0xff7304f75051b9f0L,\n        0x18aca1dc741c87c2L },\n      { 0x56f120a72d4bfe80L,0xfd823b3d053e732cL,0x11bccfe47537ca16L,\n        0xdf6c9c741b5a996bL } },\n    /* 16 << 210 */\n    { { 0xee7332c7904fc3faL,0x14a23f45c7e3636aL,0xc38659c3f091d9aaL,\n        0x4a995e5db12d8540L },\n      { 0x20a53becf3a5598aL,0x56534b17b1eaa995L,0x9ed3dca4bf04e03cL,\n        0x716c563ad8d56268L } },\n    /* 17 << 210 */\n    { { 0x27ba77a41d6178e7L,0xe4c80c4068a1ff8eL,0x750110990a13f63dL,\n        0x7bf33521a61d46f3L },\n      { 0x0aff218e10b365bbL,0x810218040fd7ea75L,0x05a3fd8aa4b3a925L,\n        0xb829e75f9b3db4e6L } },\n    /* 18 << 210 */\n    { { 0x6bdc75a54d53e5fbL,0x04a5dc02d52717e3L,0x86af502fe9a42ec2L,\n        0x8867e8fb2630e382L },\n      { 0xbf845c6ebec9889bL,0x54f491f2cb47c98dL,0xa3091fba790c2a12L,\n        0xd7f6fd78c20f708bL } },\n    /* 19 << 210 */\n    { { 0xa569ac30acde5e17L,0xd0f996d06852b4d7L,0xe51d4bb54609ae54L,\n        0x3fa37d170daed061L },\n      { 0x62a8868434b8fb41L,0x99a2acbd9efb64f1L,0xb75c1a5e6448e1f2L,\n        0xfa99951a42b5a069L } },\n    /* 20 << 210 */\n    { { 0x6d956e892f3b26e7L,0xf4709860da875247L,0x3ad151792482dda3L,\n        0xd64110e3017d82f0L },\n      { 0x14928d2cfad414e4L,0x2b155f582ed02b24L,0x481a141bcb821bf1L,\n        0x12e3c7704f81f5daL } },\n    /* 21 << 210 */\n    { { 0xe49c5de59fff8381L,0x110532325bbec894L,0xa0d051cc454d88c4L,\n        0x4f6db89c1f8e531bL },\n      { 0x34fe3fd6ca563a44L,0x7f5c221558da8ab9L,0x8445016d9474f0a1L,\n        0x17d34d61cb7d8a0aL } },\n    /* 22 << 210 */\n    { { 0x8e9d39101c474019L,0xcaff2629d52ceefbL,0xf9cf3e32c1622c2bL,\n        0xd4b95e3ce9071a05L },\n      { 0xfbbca61f1594438cL,0x1eb6e6a604aadedfL,0x853027f468e14940L,\n        0x221d322adfabda9cL } },\n    /* 23 << 210 */\n    { { 0xed8ea9f6b7cb179aL,0xdc7b764db7934dccL,0xfcb139405e09180dL,\n        0x6629a6bfb47dc2ddL },\n      { 0xbfc55e4e9f5a915eL,0xb1db9d376204441eL,0xf82d68cf930c5f53L,\n        0x17d3a142cbb605b1L } },\n    /* 24 << 210 */\n    { { 0xdd5944ea308780f2L,0xdc8de7613845f5e4L,0x6beaba7d7624d7a3L,\n        0x1e709afd304df11eL },\n      { 0x9536437602170456L,0xbf204b3ac8f94b64L,0x4e53af7c5680ca68L,\n        0x0526074ae0c67574L } },\n    /* 25 << 210 */\n    { { 0x95d8cef8ecd92af6L,0xe6b9fa7a6cd1745aL,0x3d546d3da325c3e4L,\n        0x1f57691d9ae93aaeL },\n      { 0xe891f3fe9d2e1a33L,0xd430093fac063d35L,0xeda59b125513a327L,\n        0xdc2134f35536f18fL } },\n    /* 26 << 210 */\n    { { 0xaa51fe2c5c210286L,0x3f68aaee1cab658cL,0x5a23a00bf9357292L,\n        0x9a626f397efdabedL },\n      { 0xfe2b3bf3199d78e3L,0xb7a2af7771bbc345L,0x3d19827a1e59802cL,\n        0x823bbc15b487a51cL } },\n    /* 27 << 210 */\n    { { 0x856139f299d0a422L,0x9ac3df65f456c6fbL,0xaddf65c6701f8bd6L,\n        0x149f321e3758df87L },\n      { 0xb1ecf714721b7ebaL,0xe17df09831a3312aL,0xdb2fd6ecd5c4d581L,\n        0xfd02996f8fcea1b3L } },\n    /* 28 << 210 */\n    { { 0xe29fa63e7882f14fL,0xc9f6dc3507c6cadcL,0x46f22d6fb882bed0L,\n        0x1a45755bd118e52cL },\n      { 0x9f2c7c277c4608cfL,0x7ccbdf32568012c2L,0xfcb0aedd61729b0eL,\n        0x7ca2ca9ef7d75dbfL } },\n    /* 29 << 210 */\n    { { 0xf58fecb16f640f62L,0xe274b92b39f51946L,0x7f4dfc046288af44L,\n        0x0a91f32aeac329e5L },\n      { 0x43ad274bd6aaba31L,0x719a16400f6884f9L,0x685d29f6daf91e20L,\n        0x5ec1cc3327e49d52L } },\n    /* 30 << 210 */\n    { { 0x38f4de963b54a059L,0x0e0015e5efbcfdb3L,0x177d23d94dbb8da6L,\n        0x98724aa297a617adL },\n      { 0x30f0885bfdb6558eL,0xf9f7a28ac7899a96L,0xd2ae8ac8872dc112L,\n        0xfa0642ca73c3c459L } },\n    /* 31 << 210 */\n    { { 0x15296981e7dfc8d6L,0x67cd44501fb5b94aL,0x0ec71cf10eddfd37L,\n        0xc7e5eeb39a8eddc7L },\n      { 0x02ac8e3d81d95028L,0x0088f17270b0e35dL,0xec041fabe1881fe3L,\n        0x62cf71b8d99e7faaL } },\n    /* 32 << 210 */\n    { { 0x5043dea7e0f222c2L,0x309d42ac72e65142L,0x94fe9ddd9216cd30L,\n        0xd6539c7d0f87feecL },\n      { 0x03c5a57c432ac7d7L,0x72692cf0327fda10L,0xec28c85f280698deL,\n        0x2331fb467ec283b1L } },\n    /* 33 << 210 */\n    { { 0xd34bfa322867e633L,0x78709a820a9cc815L,0xb7fe6964875e2fa5L,\n        0x25cc064f9e98bfb5L },\n      { 0x9eb0151c493a65c5L,0x5fb5d94153182464L,0x69e6f130f04618e2L,\n        0xa8ecec22f89c8ab6L } },\n    /* 34 << 210 */\n    { { 0xcd6ac88bb96209bdL,0x65fa8cdbb3e1c9e0L,0xa47d22f54a8d8eacL,\n        0x83895cdf8d33f963L },\n      { 0xa8adca59b56cd3d1L,0x10c8350bdaf38232L,0x2b161fb3a5080a9fL,\n        0xbe7f5c643af65b3aL } },\n    /* 35 << 210 */\n    { { 0x2c75403997403a11L,0x94626cf7121b96afL,0x431de7c46a983ec2L,\n        0x3780dd3a52cc3df7L },\n      { 0xe28a0e462baf8e3bL,0xabe68aad51d299aeL,0x603eb8f9647a2408L,\n        0x14c61ed65c750981L } },\n    /* 36 << 210 */\n    { { 0x88b34414c53352e7L,0x5a34889c1337d46eL,0x612c1560f95f2bc8L,\n        0x8a3f8441d4807a3aL },\n      { 0x680d9e975224da68L,0x60cd6e88c3eb00e9L,0x3875a98e9a6bc375L,\n        0xdc80f9244fd554c2L } },\n    /* 37 << 210 */\n    { { 0x6c4b34156ac77407L,0xa1e5ea8f25420681L,0x541bfa144607a458L,\n        0x5dbc7e7a96d7fbf9L },\n      { 0x646a851b31590a47L,0x039e85ba15ee6df8L,0xd19fa231d7b43fc0L,\n        0x84bc8be8299a0e04L } },\n    /* 38 << 210 */\n    { { 0x2b9d2936f20df03aL,0x240543828608d472L,0x76b6ba049149202aL,\n        0xb21c38313670e7b7L },\n      { 0xddd93059d6fdee10L,0x9da47ad378488e71L,0x99cc1dfda0fcfb25L,\n        0x42abde1064696954L } },\n    /* 39 << 210 */\n    { { 0x14cc15fc17eab9feL,0xd6e863e4d3e70972L,0x29a7765c6432112cL,\n        0x886600015b0774d8L },\n      { 0x3729175a2c088eaeL,0x13afbcae8230b8d4L,0x44768151915f4379L,\n        0xf086431ad8d22812L } },\n    /* 40 << 210 */\n    { { 0x37461955c298b974L,0x905fb5f0f8711e04L,0x787abf3afe969d18L,\n        0x392167c26f6a494eL },\n      { 0xfc7a0d2d28c511daL,0xf127c7dcb66a262dL,0xf9c4bb95fd63fdf0L,\n        0x900165893913ef46L } },\n    /* 41 << 210 */\n    { { 0x74d2a73c11aa600dL,0x2f5379bd9fb5ab52L,0xe49e53a47fb70068L,\n        0x68dd39e5404aa9a7L },\n      { 0xb9b0cf572ecaa9c3L,0xba0e103be824826bL,0x60c2198b4631a3c4L,\n        0xc5ff84abfa8966a2L } },\n    /* 42 << 210 */\n    { { 0x2d6ebe22ac95aff8L,0x1c9bb6dbb5a46d09L,0x419062da53ee4f8dL,\n        0x7b9042d0bb97efefL },\n      { 0x0f87f080830cf6bdL,0x4861d19a6ec8a6c6L,0xd3a0daa1202f01aaL,\n        0xb0111674f25afbd5L } },\n    /* 43 << 210 */\n    { { 0x6d00d6cf1afb20d9L,0x1369500040671bc5L,0x913ab0dc2485ea9bL,\n        0x1f2bed069eef61acL },\n      { 0x850c82176d799e20L,0x93415f373271c2deL,0x5afb06e96c4f5910L,\n        0x688a52dfc4e9e421L } },\n    /* 44 << 210 */\n    { { 0x30495ba3e2a9a6dbL,0x4601303d58f9268bL,0xbe3b0dad7eb0f04fL,\n        0x4ea472504456936dL },\n      { 0x8caf8798d33fd3e7L,0x1ccd8a89eb433708L,0x9effe3e887fd50adL,\n        0xbe240a566b29c4dfL } },\n    /* 45 << 210 */\n    { { 0xec4ffd98ca0e7ebdL,0xf586783ae748616eL,0xa5b00d8fc77baa99L,\n        0x0acada29b4f34c9cL },\n      { 0x36dad67d0fe723acL,0x1d8e53a539c36c1eL,0xe4dd342d1f4bea41L,\n        0x64fd5e35ebc9e4e0L } },\n    /* 46 << 210 */\n    { { 0x96f01f9057908805L,0xb5b9ea3d5ed480ddL,0x366c5dc23efd2dd0L,\n        0xed2fe3056e9dfa27L },\n      { 0x4575e8926e9197e2L,0x11719c09ab502a5dL,0x264c7bece81f213fL,\n        0x741b924155f5c457L } },\n    /* 47 << 210 */\n    { { 0x78ac7b6849a5f4f4L,0xf91d70a29fc45b7dL,0x39b05544b0f5f355L,\n        0x11f06bceeef930d9L },\n      { 0xdb84d25d038d05e1L,0x04838ee5bacc1d51L,0x9da3ce869e8ee00bL,\n        0xc3412057c36eda1fL } },\n    /* 48 << 210 */\n    { { 0xae80b91364d9c2f4L,0x7468bac3a010a8ffL,0xdfd2003737359d41L,\n        0x1a0f5ab815efeaccL },\n      { 0x7c25ad2f659d0ce0L,0x4011bcbb6785cff1L,0x128b99127e2192c7L,\n        0xa549d8e113ccb0e8L } },\n    /* 49 << 210 */\n    { { 0x805588d8c85438b1L,0x5680332dbc25cb27L,0xdcd1bc961a4bfdf4L,\n        0x779ff428706f6566L },\n      { 0x8bbee998f059987aL,0xf6ce8cf2cc686de7L,0xf8ad3c4a953cfdb2L,\n        0xd1d426d92205da36L } },\n    /* 50 << 210 */\n    { { 0xb3c0f13fc781a241L,0x3e89360ed75362a8L,0xccd05863c8a91184L,\n        0x9bd0c9b7efa8a7f4L },\n      { 0x97ee4d538a912a4bL,0xde5e15f8bcf518fdL,0x6a055bf8c467e1e0L,\n        0x10be4b4b1587e256L } },\n    /* 51 << 210 */\n    { { 0xd90c14f2668621c9L,0xd5518f51ab9c92c1L,0x8e6a0100d6d47b3cL,\n        0xcbe980dd66716175L },\n      { 0x500d3f10ddd83683L,0x3b6cb35d99cac73cL,0x53730c8b6083d550L,\n        0xcf159767df0a1987L } },\n    /* 52 << 210 */\n    { { 0x84bfcf5343ad73b3L,0x1b528c204f035a94L,0x4294edf733eeac69L,\n        0xb6283e83817f3240L },\n      { 0xc3fdc9590a5f25b1L,0xefaf8aa55844ee22L,0xde269ba5dbdde4deL,\n        0xe3347160c56133bfL } },\n    /* 53 << 210 */\n    { { 0xc11842198d9ea9f8L,0x090de5dbf3fc1ab5L,0x404c37b10bf22cdaL,\n        0x7de20ec8f5618894L },\n      { 0x754c588eecdaecabL,0x6ca4b0ed88342743L,0x76f08bddf4a938ecL,\n        0xd182de8991493ccbL } },\n    /* 54 << 210 */\n    { { 0xd652c53ec8a4186aL,0xb3e878db946d8e33L,0x088453c05f37663cL,\n        0x5cd9daaab407748bL },\n      { 0xa1f5197f586d5e72L,0x47500be8c443ca59L,0x78ef35b2e2652424L,\n        0x09c5d26f6dd7767dL } },\n    /* 55 << 210 */\n    { { 0x7175a79aa74d3f7bL,0x0428fd8dcf5ea459L,0x511cb97ca5d1746dL,\n        0x36363939e71d1278L },\n      { 0xcf2df95510350bf4L,0xb381743960aae782L,0xa748c0e43e688809L,\n        0x98021fbfd7a5a006L } },\n    /* 56 << 210 */\n    { { 0x9076a70c0e367a98L,0xbea1bc150f62b7c2L,0x2645a68c30fe0343L,\n        0xacaffa78699dc14fL },\n      { 0xf4469964457bf9c4L,0x0db6407b0d2ead83L,0x68d56cadb2c6f3ebL,\n        0x3b512e73f376356cL } },\n    /* 57 << 210 */\n    { { 0xe43b0e1ffce10408L,0x89ddc0035a5e257dL,0xb0ae0d120362e5b3L,\n        0x07f983c7b0519161L },\n      { 0xc2e94d155d5231e7L,0xcff22aed0b4f9513L,0xb02588dd6ad0b0b5L,\n        0xb967d1ac11d0dcd5L } },\n    /* 58 << 210 */\n    { { 0x8dac6bc6cf777b6cL,0x0062bdbd4c6d1959L,0x53da71b50ef5cc85L,\n        0x07012c7d4006f14fL },\n      { 0x4617f962ac47800dL,0x53365f2bc102ed75L,0xb422efcb4ab8c9d3L,\n        0x195cb26b34af31c9L } },\n    /* 59 << 210 */\n    { { 0x3a926e2905f2c4ceL,0xbd2bdecb9856966cL,0x5d16ab3a85527015L,\n        0x9f81609e4486c231L },\n      { 0xd8b96b2cda350002L,0xbd054690fa1b7d36L,0xdc90ebf5e71d79bcL,\n        0xf241b6f908964e4eL } },\n    /* 60 << 210 */\n    { { 0x7c8386432fe3cd4cL,0xe0f33acbb4bc633cL,0xb4a9ecec3d139f1fL,\n        0x05ce69cddc4a1f49L },\n      { 0xa19d1b16f5f98aafL,0x45bb71d66f23e0efL,0x33789fcd46cdfdd3L,\n        0x9b8e2978cee040caL } },\n    /* 61 << 210 */\n    { { 0x9c69b246ae0a6828L,0xba533d247078d5aaL,0x7a2e42c07bb4fbdbL,\n        0xcfb4879a7035385cL },\n      { 0x8c3dd30b3281705bL,0x7e361c6c404fe081L,0x7b21649c3f604edfL,\n        0x5dbf6a3fe52ffe47L } },\n    /* 62 << 210 */\n    { { 0xc41b7c234b54d9bfL,0x1374e6813511c3d9L,0x1863bf16c1b2b758L,\n        0x90e785071e9e6a96L },\n      { 0xab4bf98d5d86f174L,0xd74e0bd385e96fe4L,0x8afde39fcac5d344L,\n        0x90946dbcbd91b847L } },\n    /* 63 << 210 */\n    { { 0xf5b42358fe1a838cL,0x05aae6c5620ac9d8L,0x8e193bd8a1ce5a0bL,\n        0x8f7105714dabfd72L },\n      { 0x8d8fdd48182caaacL,0x8c4aeefa040745cfL,0x73c6c30af3b93e6dL,\n        0x991241f316f42011L } },\n    /* 64 << 210 */\n    { { 0xa0158eeae457a477L,0xd19857dbee6ddc05L,0xb326522418c41671L,\n        0x3ffdfc7e3c2c0d58L },\n      { 0x3a3a525426ee7cdaL,0x341b0869df02c3a8L,0xa023bf42723bbfc8L,\n        0x3d15002a14452691L } },\n    /* 0 << 217 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 217 */\n    { { 0x5ef7324c85edfa30L,0x2597655487d4f3daL,0x352f5bc0dcb50c86L,\n        0x8f6927b04832a96cL },\n      { 0xd08ee1ba55f2f94cL,0x6a996f99344b45faL,0xe133cb8da8aa455dL,\n        0x5d0721ec758dc1f7L } },\n    /* 2 << 217 */\n    { { 0x6ba7a92079e5fb67L,0xe1331feb70aa725eL,0x5080ccf57df5d837L,\n        0xe4cae01d7ff72e21L },\n      { 0xd9243ee60412a77dL,0x06ff7cacdf449025L,0xbe75f7cd23ef5a31L,\n        0xbc9578220ddef7a8L } },\n    /* 3 << 217 */\n    { { 0x8cf7230cb0ce1c55L,0x5b534d050bbfb607L,0xee1ef1130e16363bL,\n        0x27e0aa7ab4999e82L },\n      { 0xce1dac2d79362c41L,0x67920c9091bb6cb0L,0x1e648d632223df24L,\n        0x0f7d9eefe32e8f28L } },\n    /* 4 << 217 */\n    { { 0x6943f39afa833834L,0x22951722a6328562L,0x81d63dd54170fc10L,\n        0x9f5fa58faecc2e6dL },\n      { 0xb66c8725e77d9a3bL,0x11235cea6384ebe0L,0x06a8c1185845e24aL,\n        0x0137b286ebd093b1L } },\n    /* 5 << 217 */\n    { { 0xc589e1ce44ace150L,0xe0f8d3d94381e97cL,0x59e99b1162c5a4b8L,\n        0x90d262f7fd0ec9f9L },\n      { 0xfbc854c9283e13c9L,0x2d04fde7aedc7085L,0x057d776547dcbecbL,\n        0x8dbdf5919a76fa5fL } },\n    /* 6 << 217 */\n    { { 0xd01506950de1e578L,0x2e1463e7e9f72bc6L,0xffa684411b39eca5L,\n        0x673c85307c037f2fL },\n      { 0xd0d6a600747f91daL,0xb08d43e1c9cb78e9L,0x0fc0c64427b5cef5L,\n        0x5c1d160aa60a2fd6L } },\n    /* 7 << 217 */\n    { { 0xf98cae5328c8e13bL,0x375f10c4b2eddcd1L,0xd4eb8b7f5cce06adL,\n        0xb4669f4580a2e1efL },\n      { 0xd593f9d05bbd8699L,0x5528a4c9e7976d13L,0x3923e0951c7e28d3L,\n        0xb92937903f6bb577L } },\n    /* 8 << 217 */\n    { { 0xdb567d6ac42bd6d2L,0x6df86468bb1f96aeL,0x0efe5b1a4843b28eL,\n        0x961bbb056379b240L },\n      { 0xb6caf5f070a6a26bL,0x70686c0d328e6e39L,0x80da06cf895fc8d3L,\n        0x804d8810b363fdc9L } },\n    /* 9 << 217 */\n    { { 0xbe22877b207f1670L,0x9b0dd1884e615291L,0x625ae8dc97a3c2bfL,\n        0x08584ef7439b86e8L },\n      { 0xde7190a5dcd898ffL,0x26286c402058ee3dL,0x3db0b2175f87b1c1L,\n        0xcc334771102a6db5L } },\n    /* 10 << 217 */\n    { { 0xd99de9542f770fb1L,0x97c1c6204cd7535eL,0xd3b6c4483f09cefcL,\n        0xd725af155a63b4f8L },\n      { 0x0c95d24fc01e20ecL,0xdfd374949ae7121fL,0x7d6ddb72ec77b7ecL,\n        0xfe079d3b0353a4aeL } },\n    /* 11 << 217 */\n    { { 0x3066e70a2e6ac8d2L,0x9c6b5a43106e5c05L,0x52d3c6f5ede59b8cL,\n        0x30d6a5c3fccec9aeL },\n      { 0xedec7c224fc0a9efL,0x190ff08395c16cedL,0xbe12ec8f94de0fdeL,\n        0x0d131ab8852d3433L } },\n    /* 12 << 217 */\n    { { 0x42ace07e85701291L,0x94793ed9194061a8L,0x30e83ed6d7f4a485L,\n        0x9eec7269f9eeff4dL },\n      { 0x90acba590c9d8005L,0x5feca4581e79b9d1L,0x8fbe54271d506a1eL,\n        0xa32b2c8e2439cfa7L } },\n    /* 13 << 217 */\n    { { 0x1671c17373dd0b4eL,0x37a2821444a054c6L,0x81760a1b4e8b53f1L,\n        0xa6c04224f9f93b9eL },\n      { 0x18784b34cf671e3cL,0x81bbecd2cda9b994L,0x38831979b2ab3848L,\n        0xef54feb7f2e03c2dL } },\n    /* 14 << 217 */\n    { { 0xcf197ca7fb8088faL,0x014272474ddc96c5L,0xa2d2550a30777176L,\n        0x534698984d0cf71dL },\n      { 0x6ce937b83a2aaac6L,0xe9f91dc35af38d9bL,0x2598ad83c8bf2899L,\n        0x8e706ac9b5536c16L } },\n    /* 15 << 217 */\n    { { 0x40dc7495f688dc98L,0x26490cd7124c4afcL,0xe651ec841f18775cL,\n        0x393ea6c3b4fdaf4aL },\n      { 0x1e1f33437f338e0dL,0x39fb832b6053e7b5L,0x46e702da619e14d5L,\n        0x859cacd1cdeef6e0L } },\n    /* 16 << 217 */\n    { { 0x63b99ce74462007dL,0xb8ab48a54cb5f5b7L,0x9ec673d2f55edde7L,\n        0xd1567f748cfaefdaL },\n      { 0x46381b6b0887bcecL,0x694497cee178f3c2L,0x5e6525e31e6266cbL,\n        0x5931de26697d6413L } },\n    /* 17 << 217 */\n    { { 0x87f8df7c0e58d493L,0xb1ae5ed058b73f12L,0xc368f784dea0c34dL,\n        0x9bd0a120859a91a0L },\n      { 0xb00d88b7cc863c68L,0x3a1cc11e3d1f4d65L,0xea38e0e70aa85593L,\n        0x37f13e987dc4aee8L } },\n    /* 18 << 217 */\n    { { 0x10d38667bc947badL,0x738e07ce2a36ee2eL,0xc93470cdc577fcacL,\n        0xdee1b6162782470dL },\n      { 0x36a25e672e793d12L,0xd6aa6caee0f186daL,0x474d0fd980e07af7L,\n        0xf7cdc47dba8a5cd4L } },\n    /* 19 << 217 */\n    { { 0x28af6d9dab15247fL,0x7c789c10493a537fL,0x7ac9b11023a334e7L,\n        0x0236ac0912c9c277L },\n      { 0xa7e5bd251d7a5144L,0x098b9c2af13ec4ecL,0x3639dacad3f0abcaL,\n        0x642da81aa23960f9L } },\n    /* 20 << 217 */\n    { { 0x7d2e5c054f7269b1L,0xfcf30777e287c385L,0x10edc84ff2a46f21L,\n        0x354417574f43fa36L },\n      { 0xf1327899fd703431L,0xa438d7a616dd587aL,0x65c34c57e9c8352dL,\n        0xa728edab5cc5a24eL } },\n    /* 21 << 217 */\n    { { 0xaed78abc42531689L,0x0a51a0e8010963efL,0x5776fa0ad717d9b3L,\n        0xf356c2397dd3428bL },\n      { 0x29903fff8d3a3dacL,0x409597fa3d94491fL,0x4cd7a5ffbf4a56a4L,\n        0xe50964748adab462L } },\n    /* 22 << 217 */\n    { { 0xa97b51265c3427b0L,0x6401405cd282c9bdL,0x3629f8d7222c5c45L,\n        0xb1c02c16e8d50aedL },\n      { 0xbea2ed75d9635bc9L,0x226790c76e24552fL,0x3c33f2a365f1d066L,\n        0x2a43463e6dfccc2eL } },\n    /* 23 << 217 */\n    { { 0x8cc3453adb483761L,0xe7cc608565d5672bL,0x277ed6cbde3efc87L,\n        0x19f2f36869234eafL },\n      { 0x9aaf43175c0b800bL,0x1f1e7c898b6da6e2L,0x6cfb4715b94ec75eL,\n        0xd590dd5f453118c2L } },\n    /* 24 << 217 */\n    { { 0x14e49da11f17a34cL,0x5420ab39235a1456L,0xb76372412f50363bL,\n        0x7b15d623c3fabb6eL },\n      { 0xa0ef40b1e274e49cL,0x5cf5074496b1860aL,0xd6583fbf66afe5a4L,\n        0x44240510f47e3e9aL } },\n    /* 25 << 217 */\n    { { 0x9925434311b2d595L,0xf1367499eec8df57L,0x3cb12c613e73dd05L,\n        0xd248c0337dac102aL },\n      { 0xcf154f13a77739f5L,0xbf4288cb23d2af42L,0xaa64c9b632e4a1cfL,\n        0xee8c07a8c8a208f3L } },\n    /* 26 << 217 */\n    { { 0xe10d49996fe8393fL,0x0f809a3fe91f3a32L,0x61096d1c802f63c8L,\n        0x289e146257750d3dL },\n      { 0xed06167e9889feeaL,0xd5c9c0e2e0993909L,0x46fca0d856508ac6L,\n        0x918260474f1b8e83L } },\n    /* 27 << 217 */\n    { { 0x4f2c877a9a4a2751L,0x71bd0072cae6feadL,0x38df8dcc06aa1941L,\n        0x5a074b4c63beeaa8L },\n      { 0xd6d65934c1cec8edL,0xa6ecb49eaabc03bdL,0xaade91c2de8a8415L,\n        0xcfb0efdf691136e0L } },\n    /* 28 << 217 */\n    { { 0x11af45ee23ab3495L,0xa132df880b77463dL,0x8923c15c815d06f4L,\n        0xc3ceb3f50d61a436L },\n      { 0xaf52291de88fb1daL,0xea0579741da12179L,0xb0d7218cd2fef720L,\n        0x6c0899c98e1d8845L } },\n    /* 29 << 217 */\n    { { 0x98157504752ddad7L,0xd60bd74fa1a68a97L,0x7047a3a9f658fb99L,\n        0x1f5d86d65f8511e4L },\n      { 0xb8a4bc424b5a6d88L,0x69eb2c331abefa7dL,0x95bf39e813c9c510L,\n        0xf571960ad48aab43L } },\n    /* 30 << 217 */\n    { { 0x7e8cfbcf704e23c6L,0xc71b7d2228aaa65bL,0xa041b2bd245e3c83L,\n        0x69b98834d21854ffL },\n      { 0x89d227a3963bfeecL,0x99947aaade7da7cbL,0x1d9ee9dbee68a9b1L,\n        0x0a08f003698ec368L } },\n    /* 31 << 217 */\n    { { 0xe9ea409478ef2487L,0xc8d2d41502cfec26L,0xc52f9a6eb7dcf328L,\n        0x0ed489e385b6a937L },\n      { 0x9b94986bbef3366eL,0x0de59c70edddddb8L,0xffdb748ceadddbe2L,\n        0x9b9784bb8266ea40L } },\n    /* 32 << 217 */\n    { { 0x142b55021a93507aL,0xb4cd11878d3c06cfL,0xdf70e76a91ec3f40L,\n        0x484e81ad4e7553c2L },\n      { 0x830f87b5272e9d6eL,0xea1c93e5c6ff514aL,0x67cc2adcc4192a8eL,\n        0xc77e27e242f4535aL } },\n    /* 33 << 217 */\n    { { 0x9cdbab36d2b713c5L,0x86274ea0cf7b0cd3L,0x784680f309af826bL,\n        0xbfcc837a0c72dea3L },\n      { 0xa8bdfe9dd6529b73L,0x708aa22863a88002L,0x6c7a9a54c91d45b9L,\n        0xdf1a38bbfd004f56L } },\n    /* 34 << 217 */\n    { { 0x2e8c9a26b8bad853L,0x2d52cea33723eae7L,0x054d6d8156ca2830L,\n        0xa3317d149a8dc411L },\n      { 0xa08662fefd4ddedaL,0xed2a153ab55d792bL,0x7035c16abfc6e944L,\n        0xb6bc583400171cf3L } },\n    /* 35 << 217 */\n    { { 0xe27152b383d102b6L,0xfe695a470646b848L,0xa5bb09d8916e6d37L,\n        0xb4269d640d17015eL },\n      { 0x8d8156a10a1d2285L,0xfeef6c5146d26d72L,0x9dac57c84c5434a7L,\n        0x0282e5be59d39e31L } },\n    /* 36 << 217 */\n    { { 0xedfff181721c486dL,0x301baf10bc58824eL,0x8136a6aa00570031L,\n        0x55aaf78c1cddde68L },\n      { 0x2682937159c63952L,0x3a3bd2748bc25bafL,0xecdf8657b7e52dc3L,\n        0x2dd8c087fd78e6c8L } },\n    /* 37 << 217 */\n    { { 0x20553274f5531461L,0x8b4a12815d95499bL,0xe2c8763a1a80f9d2L,\n        0xd1dbe32b4ddec758L },\n      { 0xaf12210d30c34169L,0xba74a95378baa533L,0x3d133c6ea438f254L,\n        0xa431531a201bef5bL } },\n    /* 38 << 217 */\n    { { 0x15295e22f669d7ecL,0xca374f64357fb515L,0x8a8406ffeaa3fdb3L,\n        0x106ae448df3f2da8L },\n      { 0x8f9b0a9033c8e9a1L,0x234645e271ad5885L,0x3d0832241c0aed14L,\n        0xf10a7d3e7a942d46L } },\n    /* 39 << 217 */\n    { { 0x7c11deee40d5c9beL,0xb2bae7ffba84ed98L,0x93e97139aad58dddL,\n        0x3d8727963f6d1fa3L },\n      { 0x483aca818569ff13L,0x8b89a5fb9a600f72L,0x4cbc27c3c06f2b86L,\n        0x2213071363ad9c0bL } },\n    /* 40 << 217 */\n    { { 0xb5358b1e48ac2840L,0x18311294ecba9477L,0xda58f990a6946b43L,\n        0x3098baf99ab41819L },\n      { 0x66c4c1584198da52L,0xab4fc17c146bfd1bL,0x2f0a4c3cbf36a908L,\n        0x2ae9e34b58cf7838L } },\n    /* 41 << 217 */\n    { { 0xf411529e3fa11b1fL,0x21e43677974af2b4L,0x7c20958ec230793bL,\n        0x710ea88516e840f3L },\n      { 0xfc0b21fcc5dc67cfL,0x08d5164788405718L,0xd955c21fcfe49eb7L,\n        0x9722a5d556dd4a1fL } },\n    /* 42 << 217 */\n    { { 0xc9ef50e2c861baa5L,0xc0c21a5d9505ac3eL,0xaf6b9a338b7c063fL,\n        0xc63703392f4779c1L },\n      { 0x22df99c7638167c3L,0xfe6ffe76795db30cL,0x2b822d33a4854989L,\n        0xfef031dd30563aa5L } },\n    /* 43 << 217 */\n    { { 0x16b09f82d57c667fL,0xc70312cecc0b76f1L,0xbf04a9e6c9118aecL,\n        0x82fcb4193409d133L },\n      { 0x1a8ab385ab45d44dL,0xfba07222617b83a3L,0xb05f50dd58e81b52L,\n        0x1d8db55321ce5affL } },\n    /* 44 << 217 */\n    { { 0x3097b8d4e344a873L,0x7d8d116dfe36d53eL,0x6db22f587875e750L,\n        0x2dc5e37343e144eaL },\n      { 0xc05f32e6e799eb95L,0xe9e5f4df6899e6ecL,0xbdc3bd681fab23d5L,\n        0xb72b8ab773af60e6L } },\n    /* 45 << 217 */\n    { { 0x8db27ae02cecc84aL,0x600016d87bdb871cL,0x42a44b13d7c46f58L,\n        0xb8919727c3a77d39L },\n      { 0xcfc6bbbddafd6088L,0x1a7401466bd20d39L,0x8c747abd98c41072L,\n        0x4c91e765bdf68ea1L } },\n    /* 46 << 217 */\n    { { 0x7c95e5ca08819a78L,0xcf48b729c9587921L,0x091c7c5fdebbcc7dL,\n        0x6f287404f0e05149L },\n      { 0xf83b5ac226cd44ecL,0x88ae32a6cfea250eL,0x6ac5047a1d06ebc5L,\n        0xc7e550b4d434f781L } },\n    /* 47 << 217 */\n    { { 0x61ab1cf25c727bd2L,0x2e4badb11cf915b0L,0x1b4dadecf69d3920L,\n        0xe61b1ca6f14c1dfeL },\n      { 0x90b479ccbd6bd51fL,0x8024e4018045ec30L,0xcab29ca325ef0e62L,\n        0x4f2e941649e4ebc0L } },\n    /* 48 << 217 */\n    { { 0x45eb40ec0ccced58L,0x25cd4b9c0da44f98L,0x43e06458871812c6L,\n        0x99f80d5516cef651L },\n      { 0x571340c9ce6dc153L,0x138d5117d8665521L,0xacdb45bc4e07014dL,\n        0x2f34bb3884b60b91L } },\n    /* 49 << 217 */\n    { { 0xf44a4fd22ae8921eL,0xb039288e892ba1e2L,0x9da50174b1c180b2L,\n        0x6b70ab661693dc87L },\n      { 0x7e9babc9e7057481L,0x4581ddef9c80dc41L,0x0c890da951294682L,\n        0x0b5629d33f4736e5L } },\n    /* 50 << 217 */\n    { { 0x2340c79eb06f5b41L,0xa42e84ce4e243469L,0xf9a20135045a71a9L,\n        0xefbfb415d27b6fb6L },\n      { 0x25ebea239d33cd6fL,0x9caedb88aa6c0af8L,0x53dc7e9ad9ce6f96L,\n        0x3897f9fd51e0b15aL } },\n    /* 51 << 217 */\n    { { 0xf51cb1f88e5d788eL,0x1aec7ba8e1d490eeL,0x265991e0cc58cb3cL,\n        0x9f306e8c9fc3ad31L },\n      { 0x5fed006e5040a0acL,0xca9d5043fb476f2eL,0xa19c06e8beea7a23L,\n        0xd28658010edabb63L } },\n    /* 52 << 217 */\n    { { 0xdb92293f6967469aL,0x2894d8398d8a8ed8L,0x87c9e406bbc77122L,\n        0x8671c6f12ea3a26aL },\n      { 0xe42df8d6d7de9853L,0x2e3ce346b1f2bcc7L,0xda601dfc899d50cfL,\n        0xbfc913defb1b598fL } },\n    /* 53 << 217 */\n    { { 0x81c4909fe61f7908L,0x192e304f9bbc7b29L,0xc3ed8738c104b338L,\n        0xedbe9e47783f5d61L },\n      { 0x0c06e9be2db30660L,0xda3e613fc0eb7d8eL,0xd8fa3e97322e096eL,\n        0xfebd91e8d336e247L } },\n    /* 54 << 217 */\n    { { 0x8f13ccc4df655a49L,0xa9e00dfc5eb20210L,0x84631d0fc656b6eaL,\n        0x93a058cdd8c0d947L },\n      { 0x6846904a67bd3448L,0x4a3d4e1af394fd5cL,0xc102c1a5db225f52L,\n        0xe3455bbafc4f5e9aL } },\n    /* 55 << 217 */\n    { { 0x6b36985b4b9ad1ceL,0xa98185365bb7f793L,0x6c25e1d048b1a416L,\n        0x1381dd533c81bee7L },\n      { 0xd2a30d617a4a7620L,0xc841292639b8944cL,0x3c1c6fbe7a97c33aL,\n        0x941e541d938664e7L } },\n    /* 56 << 217 */\n    { { 0x417499e84a34f239L,0x15fdb83cb90402d5L,0xb75f46bf433aa832L,\n        0xb61e15af63215db1L },\n      { 0xaabe59d4a127f89aL,0x5d541e0c07e816daL,0xaaba0659a618b692L,\n        0x5532773317266026L } },\n    /* 57 << 217 */\n    { { 0xaf53a0fc95f57552L,0x329476506cacb0c9L,0x253ff58dc821be01L,\n        0xb0309531a06f1146L },\n      { 0x59bbbdf505c2e54dL,0x158f27ad26e8dd22L,0xcc5b7ffb397e1e53L,\n        0xae03f65b7fc1e50dL } },\n    /* 58 << 217 */\n    { { 0xa9784ebd9c95f0f9L,0x5ed9deb224640771L,0x31244af7035561c4L,\n        0x87332f3a7ee857deL },\n      { 0x09e16e9e2b9e0d88L,0x52d910f456a06049L,0x507ed477a9592f48L,\n        0x85cb917b2365d678L } },\n    /* 59 << 217 */\n    { { 0xf8511c934c8998d1L,0x2186a3f1730ea58fL,0x50189626b2029db0L,\n        0x9137a6d902ceb75aL },\n      { 0x2fe17f37748bc82cL,0x87c2e93180469f8cL,0x850f71cdbf891aa2L,\n        0x0ca1b89b75ec3d8dL } },\n    /* 60 << 217 */\n    { { 0x516c43aa5e1cd3cdL,0x893978089a887c28L,0x0059c699ddea1f9fL,\n        0x7737d6fa8e6868f7L },\n      { 0x6d93746a60f1524bL,0x36985e55ba052aa7L,0x41b1d322ed923ea5L,\n        0x3429759f25852a11L } },\n    /* 61 << 217 */\n    { { 0xbeca6ec3092e9f41L,0x3a238c6662256bbdL,0xd82958ea70ad487dL,\n        0x4ac8aaf965610d93L },\n      { 0x3fa101b15e4ccab0L,0x9bf430f29de14bfbL,0xa10f5cc66531899dL,\n        0x590005fbea8ce17dL } },\n    /* 62 << 217 */\n    { { 0xc437912f24544cb6L,0x9987b71ad79ac2e3L,0x13e3d9ddc058a212L,\n        0x00075aacd2de9606L },\n      { 0x80ab508b6cac8369L,0x87842be7f54f6c89L,0xa7ad663d6bc532a4L,\n        0x67813de778a91bc8L } },\n    /* 63 << 217 */\n    { { 0x5dcb61cec3427239L,0x5f3c7cf0c56934d9L,0xc079e0fbe3191591L,\n        0xe40896bdb01aada7L },\n      { 0x8d4667910492d25fL,0x8aeb30c9e7408276L,0xe94374959287aaccL,\n        0x23d4708d79fe03d4L } },\n    /* 64 << 217 */\n    { { 0x8cda9cf2d0c05199L,0x502fbc22fae78454L,0xc0bda9dff572a182L,\n        0x5f9b71b86158b372L },\n      { 0xe0f33a592b82dd07L,0x763027359523032eL,0x7fe1a721c4505a32L,\n        0x7b6e3e82f796409fL } },\n    /* 0 << 224 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 224 */\n    { { 0xe3417bc035d0b34aL,0x440b386b8327c0a7L,0x8fb7262dac0362d1L,\n        0x2c41114ce0cdf943L },\n      { 0x2ba5cef1ad95a0b1L,0xc09b37a867d54362L,0x26d6cdd201e486c9L,\n        0x20477abf42ff9297L } },\n    /* 2 << 224 */\n    { { 0xa004dcb3292a9287L,0xddc15cf677b092c7L,0x083a8464806c0605L,\n        0x4a68df703db997b0L },\n      { 0x9c134e4505bf7dd0L,0xa4e63d398ccf7f8cL,0xa6e6517f41b5f8afL,\n        0xaa8b9342ad7bc1ccL } },\n    /* 3 << 224 */\n    { { 0x126f35b51e706ad9L,0xb99cebb4c3a9ebdfL,0xa75389afbf608d90L,\n        0x76113c4fc6c89858L },\n      { 0x80de8eb097e2b5aaL,0x7e1022cc63b91304L,0x3bdab6056ccc066cL,\n        0x33cbb144b2edf900L } },\n    /* 4 << 224 */\n    { { 0xc41764717af715d2L,0xe2f7f594d0134a96L,0x2c1873efa41ec956L,\n        0xe4e7b4f677821304L },\n      { 0xe5c8ff9788d5374aL,0x2b915e6380823d5bL,0xea6bc755b2ee8fe2L,\n        0x6657624ce7112651L } },\n    /* 5 << 224 */\n    { { 0x157af101dace5acaL,0xc4fdbcf211a6a267L,0xdaddf340c49c8609L,\n        0x97e49f52e9604a65L },\n      { 0x9be8e790937e2ad5L,0x846e2508326e17f1L,0x3f38007a0bbbc0dcL,\n        0xcf03603fb11e16d6L } },\n    /* 6 << 224 */\n    { { 0xd6f800e07442f1d5L,0x475607d166e0e3abL,0x82807f16b7c64047L,\n        0x8858e1e3a749883dL },\n      { 0x5859120b8231ee10L,0x1b80e7eb638a1eceL,0xcb72525ac6aa73a4L,\n        0xa7cdea3d844423acL } },\n    /* 7 << 224 */\n    { { 0x5ed0c007f8ae7c38L,0x6db07a5c3d740192L,0xbe5e9c2a5fe36db3L,\n        0xd5b9d57a76e95046L },\n      { 0x54ac32e78eba20f2L,0xef11ca8f71b9a352L,0x305e373eff98a658L,\n        0xffe5a100823eb667L } },\n    /* 8 << 224 */\n    { { 0x57477b11e51732d2L,0xdfd6eb282538fc0eL,0x5c43b0cc3b39eec5L,\n        0x6af12778cb36cc57L },\n      { 0x70b0852d06c425aeL,0x6df92f8c5c221b9bL,0x6c8d4f9ece826d9cL,\n        0xf59aba7bb49359c3L } },\n    /* 9 << 224 */\n    { { 0x5c8ed8d5da64309dL,0x61a6de5691b30704L,0xd6b52f6a2f9b5808L,\n        0x0eee419498c958a7L },\n      { 0xcddd9aab771e4caaL,0x83965dfd78bc21beL,0x02affce3b3b504f5L,\n        0x30847a21561c8291L } },\n    /* 10 << 224 */\n    { { 0xd2eb2cf152bfda05L,0xe0e4c4e96197b98cL,0x1d35076cf8a1726fL,\n        0x6c06085b2db11e3dL },\n      { 0x15c0c4d74463ba14L,0x9d292f830030238cL,0x1311ee8b3727536dL,\n        0xfeea86efbeaedc1eL } },\n    /* 11 << 224 */\n    { { 0xb9d18cd366131e2eL,0xf31d974f80fe2682L,0xb6e49e0fe4160289L,\n        0x7c48ec0b08e92799L },\n      { 0x818111d8d1989aa7L,0xb34fa0aaebf926f9L,0xdb5fe2f5a245474aL,\n        0xf80a6ebb3c7ca756L } },\n    /* 12 << 224 */\n    { { 0xa7f96054afa05dd8L,0x26dfcf21fcaf119eL,0xe20ef2e30564bb59L,\n        0xef4dca5061cb02b8L },\n      { 0xcda7838a65d30672L,0x8b08d534fd657e86L,0x4c5b439546d595c8L,\n        0x39b58725425cb836L } },\n    /* 13 << 224 */\n    { { 0x8ea610593de9abe3L,0x404348819cdc03beL,0x9b261245cfedce8cL,\n        0x78c318b4cf5234a1L },\n      { 0x510bcf16fde24c99L,0x2a77cb75a2c2ff5dL,0x9c895c2b27960fb4L,\n        0xd30ce975b0eda42bL } },\n    /* 14 << 224 */\n    { { 0xfda853931a62cc26L,0x23c69b9650c0e052L,0xa227df15bfc633f3L,\n        0x2ac788481bae7d48L },\n      { 0x487878f9187d073dL,0x6c2be919967f807dL,0x765861d8336e6d8fL,\n        0x88b8974cce528a43L } },\n    /* 15 << 224 */\n    { { 0x09521177ff57d051L,0x2ff38037fb6a1961L,0xfc0aba74a3d76ad4L,\n        0x7c76480325a7ec17L },\n      { 0x7532d75f48879bc8L,0xea7eacc058ce6bc1L,0xc82176b48e896c16L,\n        0x9a30e0b22c750fedL } },\n    /* 16 << 224 */\n    { { 0xc37e2c2e421d3aa4L,0xf926407ce84fa840L,0x18abc03d1454e41cL,\n        0x26605ecd3f7af644L },\n      { 0x242341a6d6a5eabfL,0x1edb84f4216b668eL,0xd836edb804010102L,\n        0x5b337ce7945e1d8cL } },\n    /* 17 << 224 */\n    { { 0xd2075c77c055dc14L,0x2a0ffa2581d89cdfL,0x8ce815ea6ffdcbafL,\n        0xa3428878fb648867L },\n      { 0x277699cf884655fbL,0xfa5b5bd6364d3e41L,0x01f680c6441e1cb7L,\n        0x3fd61e66b70a7d67L } },\n    /* 18 << 224 */\n    { { 0x666ba2dccc78cf66L,0xb30181746fdbff77L,0x8d4dd0db168d4668L,\n        0x259455d01dab3a2aL },\n      { 0xf58564c5cde3acecL,0x7714192513adb276L,0x527d725d8a303f65L,\n        0x55deb6c9e6f38f7bL } },\n    /* 19 << 224 */\n    { { 0xfd5bb657b1fa70fbL,0xfa07f50fd8073a00L,0xf72e3aa7bca02500L,\n        0xf68f895d9975740dL },\n      { 0x301120605cae2a6aL,0x01bd721802874842L,0x3d4238917ce47bd3L,\n        0xa66663c1789544f6L } },\n    /* 20 << 224 */\n    { { 0x864d05d73272d838L,0xe22924f9fa6295c5L,0x8189593f6c2fda32L,\n        0x330d7189b184b544L },\n      { 0x79efa62cbde1f714L,0x35771c94e5cb1a63L,0x2f4826b8641c8332L,\n        0x00a894fbc8cee854L } },\n    /* 21 << 224 */\n    { { 0xb4b9a39b36194d40L,0xe857a7c577612601L,0xf4209dd24ecf2f58L,\n        0x82b9e66d5a033487L },\n      { 0xc1e36934e4e8b9ddL,0xd2372c9da42377d7L,0x51dc94c70e3ae43bL,\n        0x4c57761e04474f6fL } },\n    /* 22 << 224 */\n    { { 0xdcdacd0a1058a318L,0x369cf3f578053a9aL,0xc6c3de5031c68de2L,\n        0x4653a5763c4b6d9fL },\n      { 0x1688dd5aaa4e5c97L,0x5be80aa1b7ab3c74L,0x70cefe7cbc65c283L,\n        0x57f95f1306867091L } },\n    /* 23 << 224 */\n    { { 0xa39114e24415503bL,0xc08ff7c64cbb17e9L,0x1eff674dd7dec966L,\n        0x6d4690af53376f63L },\n      { 0xff6fe32eea74237bL,0xc436d17ecd57508eL,0x15aa28e1edcc40feL,\n        0x0d769c04581bbb44L } },\n    /* 24 << 224 */\n    { { 0xc240b6de34eaacdaL,0xd9e116e82ba0f1deL,0xcbe45ec779438e55L,\n        0x91787c9d96f752d7L },\n      { 0x897f532bf129ac2fL,0xd307b7c85a36e22cL,0x91940675749fb8f3L,\n        0xd14f95d0157fdb28L } },\n    /* 25 << 224 */\n    { { 0xfe51d0296ae55043L,0x8931e98f44a87de1L,0xe57f1cc609e4fee2L,\n        0x0d063b674e072d92L },\n      { 0x70a998b9ed0e4316L,0xe74a736b306aca46L,0xecf0fbf24fda97c7L,\n        0xa40f65cb3e178d93L } },\n    /* 26 << 224 */\n    { { 0x1625360416df4285L,0xb0c9babbd0c56ae2L,0x73032b19cfc5cfc3L,\n        0xe497e5c309752056L },\n      { 0x12096bb4164bda96L,0x1ee42419a0b74da1L,0x8fc36243403826baL,\n        0x0c8f0069dc09e660L } },\n    /* 27 << 224 */\n    { { 0x8667e981c27253c9L,0x05a6aefb92b36a45L,0xa62c4b369cb7bb46L,\n        0x8394f37511f7027bL },\n      { 0x747bc79c5f109d0fL,0xcad88a765b8cc60aL,0x80c5a66b58f09e68L,\n        0xe753d451f6127eacL } },\n    /* 28 << 224 */\n    { { 0xc44b74a15b0ec6f5L,0x47989fe45289b2b8L,0x745f848458d6fc73L,\n        0xec362a6ff61c70abL },\n      { 0x070c98a7b3a8ad41L,0x73a20fc07b63db51L,0xed2c2173f44c35f4L,\n        0x8a56149d9acc9dcaL } },\n    /* 29 << 224 */\n    { { 0x98f178819ac6e0f4L,0x360fdeafa413b5edL,0x0625b8f4a300b0fdL,\n        0xf1f4d76a5b3222d3L },\n      { 0x9d6f5109587f76b8L,0x8b4ee08d2317fdb5L,0x88089bb78c68b095L,\n        0x95570e9a5808d9b9L } },\n    /* 30 << 224 */\n    { { 0xa395c36f35d33ae7L,0x200ea12350bb5a94L,0x20c789bd0bafe84bL,\n        0x243ef52d0919276aL },\n      { 0x3934c577e23ae233L,0xb93807afa460d1ecL,0xb72a53b1f8fa76a4L,\n        0xd8914cb0c3ca4491L } },\n    /* 31 << 224 */\n    { { 0x2e1284943fb42622L,0x3b2700ac500907d5L,0xf370fb091a95ec63L,\n        0xf8f30be231b6dfbdL },\n      { 0xf2b2f8d269e55f15L,0x1fead851cc1323e9L,0xfa366010d9e5eef6L,\n        0x64d487b0e316107eL } },\n    /* 32 << 224 */\n    { { 0x4c076b86d23ddc82L,0x03fd344c7e0143f0L,0xa95362ff317af2c5L,\n        0x0add3db7e18b7a4fL },\n      { 0x9c673e3f8260e01bL,0xfbeb49e554a1cc91L,0x91351bf292f2e433L,\n        0xc755e7ec851141ebL } },\n    /* 33 << 224 */\n    { { 0xc9a9513929607745L,0x0ca07420a26f2b28L,0xcb2790e74bc6f9ddL,\n        0x345bbb58adcaffc0L },\n      { 0xc65ea38cbe0f27a2L,0x67c24d7c641fcb56L,0x2c25f0a7a9e2c757L,\n        0x93f5cdb016f16c49L } },\n    /* 34 << 224 */\n    { { 0x2ca5a9d7c5ee30a1L,0xd1593635b909b729L,0x804ce9f3dadeff48L,\n        0xec464751b07c30c3L },\n      { 0x89d65ff39e49af6aL,0xf2d6238a6f3d01bcL,0x1095561e0bced843L,\n        0x51789e12c8a13fd8L } },\n    /* 35 << 224 */\n    { { 0xd633f929763231dfL,0x46df9f7de7cbddefL,0x01c889c0cb265da8L,\n        0xfce1ad10af4336d2L },\n      { 0x8d110df6fc6a0a7eL,0xdd431b986da425dcL,0xcdc4aeab1834aabeL,\n        0x84deb1248439b7fcL } },\n    /* 36 << 224 */\n    { { 0x8796f1693c2a5998L,0x9b9247b47947190dL,0x55b9d9a511597014L,\n        0x7e9dd70d7b1566eeL },\n      { 0x94ad78f7cbcd5e64L,0x0359ac179bd4c032L,0x3b11baaf7cc222aeL,\n        0xa6a6e284ba78e812L } },\n    /* 37 << 224 */\n    { { 0x8392053f24cea1a0L,0xc97bce4a33621491L,0x7eb1db3435399ee9L,\n        0x473f78efece81ad1L },\n      { 0x41d72fe0f63d3d0dL,0xe620b880afab62fcL,0x92096bc993158383L,\n        0x41a213578f896f6cL } },\n    /* 38 << 224 */\n    { { 0x1b5ee2fac7dcfcabL,0x650acfde9546e007L,0xc081b749b1b02e07L,\n        0xda9e41a0f9eca03dL },\n      { 0x013ba727175a54abL,0xca0cd190ea5d8d10L,0x85ea52c095fd96a9L,\n        0x2c591b9fbc5c3940L } },\n    /* 39 << 224 */\n    { { 0x6fb4d4e42bad4d5fL,0xfa4c3590fef0059bL,0x6a10218af5122294L,\n        0x9a78a81aa85751d1L },\n      { 0x04f20579a98e84e7L,0xfe1242c04997e5b5L,0xe77a273bca21e1e4L,\n        0xfcc8b1ef9411939dL } },\n    /* 40 << 224 */\n    { { 0xe20ea30292d0487aL,0x1442dbec294b91feL,0x1f7a4afebb6b0e8fL,\n        0x1700ef746889c318L },\n      { 0xf5bbffc370f1fc62L,0x3b31d4b669c79ccaL,0xe8bc2aaba7f6340dL,\n        0xb0b08ab4a725e10aL } },\n    /* 41 << 224 */\n    { { 0x44f05701ae340050L,0xba4b30161cf0c569L,0x5aa29f83fbe19a51L,\n        0x1b9ed428b71d752eL },\n      { 0x1666e54eeb4819f5L,0x616cdfed9e18b75bL,0x112ed5be3ee27b0bL,\n        0xfbf2831944c7de4dL } },\n    /* 42 << 224 */\n    { { 0xd685ec85e0e60d84L,0x68037e301db7ee78L,0x5b65bdcd003c4d6eL,\n        0x33e7363a93e29a6aL },\n      { 0x995b3a6108d0756cL,0xd727f85c2faf134bL,0xfac6edf71d337823L,\n        0x99b9aa500439b8b4L } },\n    /* 43 << 224 */\n    { { 0x722eb104e2b4e075L,0x49987295437c4926L,0xb1e4c0e446a9b82dL,\n        0xd0cb319757a006f5L },\n      { 0xf3de0f7dd7808c56L,0xb5c54d8f51f89772L,0x500a114aadbd31aaL,\n        0x9afaaaa6295f6cabL } },\n    /* 44 << 224 */\n    { { 0x94705e2104cf667aL,0xfc2a811b9d3935d7L,0x560b02806d09267cL,\n        0xf19ed119f780e53bL },\n      { 0xf0227c09067b6269L,0x967b85335caef599L,0x155b924368efeebcL,\n        0xcd6d34f5c497bae6L } },\n    /* 45 << 224 */\n    { { 0x1dd8d5d36cceb370L,0x2aeac579a78d7bf9L,0x5d65017d70b67a62L,\n        0x70c8e44f17c53f67L },\n      { 0xd1fc095086a34d09L,0xe0fca256e7134907L,0xe24fa29c80fdd315L,\n        0x2c4acd03d87499adL } },\n    /* 46 << 224 */\n    { { 0xbaaf75173b5a9ba6L,0xb9cbe1f612e51a51L,0xd88edae35e154897L,\n        0xe4309c3c77b66ca0L },\n      { 0xf5555805f67f3746L,0x85fc37baa36401ffL,0xdf86e2cad9499a53L,\n        0x6270b2a3ecbc955bL } },\n    /* 47 << 224 */\n    { { 0xafae64f5974ad33bL,0x04d85977fe7b2df1L,0x2a3db3ff4ab03f73L,\n        0x0b87878a8702740aL },\n      { 0x6d263f015a061732L,0xc25430cea32a1901L,0xf7ebab3ddb155018L,\n        0x3a86f69363a9b78eL } },\n    /* 48 << 224 */\n    { { 0x349ae368da9f3804L,0x470f07fea164349cL,0xd52f4cc98562baa5L,\n        0xc74a9e862b290df3L },\n      { 0xd3a1aa3543471a24L,0x239446beb8194511L,0xbec2dd0081dcd44dL,\n        0xca3d7f0fc42ac82dL } },\n    /* 49 << 224 */\n    { { 0x1f3db085fdaf4520L,0xbb6d3e804549daf2L,0xf5969d8a19ad5c42L,\n        0x7052b13ddbfd1511L },\n      { 0x11890d1b682b9060L,0xa71d3883ac34452cL,0xa438055b783805b4L,\n        0x432412774725b23eL } },\n    /* 50 << 224 */\n    { { 0xf20cf96e4901bbedL,0x6419c710f432a2bbL,0x57a0fbb9dfa9cd7dL,\n        0x589111e400daa249L },\n      { 0x19809a337b60554eL,0xea5f8887ede283a4L,0x2d713802503bfd35L,\n        0x151bb0af585d2a53L } },\n    /* 51 << 224 */\n    { { 0x40b08f7443b30ca8L,0xe10b5bbad9934583L,0xe8a546d6b51110adL,\n        0x1dd50e6628e0b6c5L },\n      { 0x292e9d54cff2b821L,0x3882555d47281760L,0x134838f83724d6e3L,\n        0xf2c679e022ddcda1L } },\n    /* 52 << 224 */\n    { { 0x40ee88156d2a5768L,0x7f227bd21c1e7e2dL,0x487ba134d04ff443L,\n        0x76e2ff3dc614e54bL },\n      { 0x36b88d6fa3177ec7L,0xbf731d512328fff5L,0x758caea249ba158eL,\n        0x5ab8ff4c02938188L } },\n    /* 53 << 224 */\n    { { 0x33e1605635edc56dL,0x5a69d3497e940d79L,0x6c4fd00103866dcbL,\n        0x20a38f574893cdefL },\n      { 0xfbf3e790fac3a15bL,0x6ed7ea2e7a4f8e6bL,0xa663eb4fbc3aca86L,\n        0x22061ea5080d53f7L } },\n    /* 54 << 224 */\n    { { 0x2480dfe6f546783fL,0xd38bc6da5a0a641eL,0xfb093cd12ede8965L,\n        0x89654db4acb455cfL },\n      { 0x413cbf9a26e1adeeL,0x291f3764373294d4L,0x00797257648083feL,\n        0x25f504d3208cc341L } },\n    /* 55 << 224 */\n    { { 0x635a8e5ec3a0ee43L,0x70aaebca679898ffL,0x9ee9f5475dc63d56L,\n        0xce987966ffb34d00L },\n      { 0xf9f86b195e26310aL,0x9e435484382a8ca8L,0x253bcb81c2352fe4L,\n        0xa4eac8b04474b571L } },\n    /* 56 << 224 */\n    { { 0xc1b97512c1ad8cf8L,0x193b4e9e99e0b697L,0x939d271601e85df0L,\n        0x4fb265b3cd44eafdL },\n      { 0x321e7dcde51e1ae2L,0x8e3a8ca6e3d8b096L,0x8de46cb052604998L,\n        0x91099ad839072aa7L } },\n    /* 57 << 224 */\n    { { 0x2617f91c93aa96b8L,0x0fc8716b7fca2e13L,0xa7106f5e95328723L,\n        0xd1c9c40b262e6522L },\n      { 0xb9bafe8642b7c094L,0x1873439d1543c021L,0xe1baa5de5cbefd5dL,\n        0xa363fc5e521e8affL } },\n    /* 58 << 224 */\n    { { 0xefe6320df862eaacL,0x14419c6322c647dcL,0x0e06707c4e46d428L,\n        0xcb6c834f4a178f8fL },\n      { 0x0f993a45d30f917cL,0xd4c4b0499879afeeL,0xb6142a1e70500063L,\n        0x7c9b41c3a5d9d605L } },\n    /* 59 << 224 */\n    { { 0xbc00fc2f2f8ba2c7L,0x0966eb2f7c67aa28L,0x13f7b5165a786972L,\n        0x3bfb75578a2fbba0L },\n      { 0x131c4f235a2b9620L,0xbff3ed276faf46beL,0x9b4473d17e172323L,\n        0x421e8878339f6246L } },\n    /* 60 << 224 */\n    { { 0x0fa8587a25a41632L,0xc0814124a35b6c93L,0x2b18a9f559ebb8dbL,\n        0x264e335776edb29cL },\n      { 0xaf245ccdc87c51e2L,0x16b3015b501e6214L,0xbb31c5600a3882ceL,\n        0x6961bb94fec11e04L } },\n    /* 61 << 224 */\n    { { 0x3b825b8deff7a3a0L,0xbec33738b1df7326L,0x68ad747c99604a1fL,\n        0xd154c9349a3bd499L },\n      { 0xac33506f1cc7a906L,0x73bb53926c560e8fL,0x6428fcbe263e3944L,\n        0xc11828d51c387434L } },\n    /* 62 << 224 */\n    { { 0x3cd04be13e4b12ffL,0xc3aad9f92d88667cL,0xc52ddcf8248120cfL,\n        0x985a892e2a389532L },\n      { 0xfbb4b21b3bb85fa0L,0xf95375e08dfc6269L,0xfb4fb06c7ee2aceaL,\n        0x6785426e309c4d1fL } },\n    /* 63 << 224 */\n    { { 0x659b17c8d8ceb147L,0x9b649eeeb70a5554L,0x6b7fa0b5ac6bc634L,\n        0xd99fe2c71d6e732fL },\n      { 0x30e6e7628d3abba2L,0x18fee6e7a797b799L,0x5c9d360dc696464dL,\n        0xe3baeb4827bfde12L } },\n    /* 64 << 224 */\n    { { 0x2bf5db47f23206d5L,0x2f6d34201d260152L,0x17b876533f8ff89aL,\n        0x5157c30c378fa458L },\n      { 0x7517c5c52d4fb936L,0xef22f7ace6518cdcL,0xdeb483e6bf847a64L,\n        0xf508455892e0fa89L } },\n    /* 0 << 231 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 231 */\n    { { 0xab9659d8df7304d4L,0xb71bcf1bff210e8eL,0xa9a2438bd73fbd60L,\n        0x4595cd1f5d11b4deL },\n      { 0x9c0d329a4835859dL,0x4a0f0d2d7dbb6e56L,0xc6038e5edf928a4eL,\n        0xc94296218f5ad154L } },\n    /* 2 << 231 */\n    { { 0x91213462f23f2d92L,0x6cab71bd60b94078L,0x6bdd0a63176cde20L,\n        0x54c9b20cee4d54bcL },\n      { 0x3cd2d8aa9f2ac02fL,0x03f8e617206eedb0L,0xc7f68e1693086434L,\n        0x831469c592dd3db9L } },\n    /* 3 << 231 */\n    { { 0x8521df248f981354L,0x587e23ec3588a259L,0xcbedf281d7a0992cL,\n        0x06930a5538961407L },\n      { 0x09320debbe5bbe21L,0xa7ffa5b52491817fL,0xe6c8b4d909065160L,\n        0xac4f3992fff6d2a9L } },\n    /* 4 << 231 */\n    { { 0x7aa7a1583ae9c1bdL,0xe0af6d98e37ce240L,0xe54342d928ab38b4L,\n        0xe8b750070a1c98caL },\n      { 0xefce86afe02358f2L,0x31b8b856ea921228L,0x052a19120a1c67fcL,\n        0xb4069ea4e3aead59L } },\n    /* 5 << 231 */\n    { { 0x3232d6e27fa03cb3L,0xdb938e5b0fdd7d88L,0x04c1d2cd2ccbfc5dL,\n        0xd2f45c12af3a580fL },\n      { 0x592620b57883e614L,0x5fd27e68be7c5f26L,0x139e45a91567e1e3L,\n        0x2cc71d2d44d8aaafL } },\n    /* 6 << 231 */\n    { { 0x4a9090cde36d0757L,0xf722d7b1d9a29382L,0xfb7fb04c04b48ddfL,\n        0x628ad2a7ebe16f43L },\n      { 0xcd3fbfb520226040L,0x6c34ecb15104b6c4L,0x30c0754ec903c188L,\n        0xec336b082d23cab0L } },\n    /* 7 << 231 */\n    { { 0x473d62a21e206ee5L,0xf1e274808c49a633L,0x87ab956ce9f6b2c3L,\n        0x61830b4862b606eaL },\n      { 0x67cd6846e78e815fL,0xfe40139f4c02082aL,0x52bbbfcb952ec365L,\n        0x74c116426b9836abL } },\n    /* 8 << 231 */\n    { { 0x9f51439e558df019L,0x230da4baac712b27L,0x518919e355185a24L,\n        0x4dcefcdd84b78f50L },\n      { 0xa7d90fb2a47d4c5aL,0x55ac9abfb30e009eL,0xfd2fc35974eed273L,\n        0xb72d824cdbea8fafL } },\n    /* 9 << 231 */\n    { { 0xce721a744513e2caL,0x0b41861238240b2cL,0x05199968d5baa450L,\n        0xeb1757ed2b0e8c25L },\n      { 0x6ebc3e283dfac6d5L,0xb2431e2e48a237f5L,0x2acb5e2352f61499L,\n        0x5558a2a7e06c936bL } },\n    /* 10 << 231 */\n    { { 0xd213f923cbb13d1bL,0x98799f425bfb9bfeL,0x1ae8ddc9701144a9L,\n        0x0b8b3bb64c5595eeL },\n      { 0x0ea9ef2e3ecebb21L,0x17cb6c4b3671f9a7L,0x47ef464f726f1d1fL,\n        0x171b94846943a276L } },\n    /* 11 << 231 */\n    { { 0x51a4ae2d7ef0329cL,0x0850922291c4402aL,0x64a61d35afd45bbcL,\n        0x38f096fe3035a851L },\n      { 0xc7468b74a1dec027L,0xe8cf10e74fc7dcbaL,0xea35ff40f4a06353L,\n        0x0b4c0dfa8b77dd66L } },\n    /* 12 << 231 */\n    { { 0x779b8552de7e5c19L,0xfab28609c1c0256cL,0x64f58eeeabd4743dL,\n        0x4e8ef8387b6cc93bL },\n      { 0xee650d264cb1bf3dL,0x4c1f9d0973dedf61L,0xaef7c9d7bfb70cedL,\n        0x1ec0507e1641de1eL } },\n    /* 13 << 231 */\n    { { 0xcd7e5cc7cde45079L,0xde173c9a516ac9e4L,0x517a8494c170315cL,\n        0x438fd90591d8e8fbL },\n      { 0x5145c506c7d9630bL,0x6457a87bf47d4d75L,0xd31646bf0d9a80e8L,\n        0x453add2bcef3aabeL } },\n    /* 14 << 231 */\n    { { 0xc9941109a607419dL,0xfaa71e62bb6bca80L,0x34158c1307c431f3L,\n        0x594abebc992bc47aL },\n      { 0x6dfea691eb78399fL,0x48aafb353f42cba4L,0xedcd65af077c04f0L,\n        0x1a29a366e884491aL } },\n    /* 15 << 231 */\n    { { 0x023a40e51c21f2bfL,0xf99a513ca5057aeeL,0xa3fe7e25bcab072eL,\n        0x8568d2e140e32bcfL },\n      { 0x904594ebd3f69d9fL,0x181a973307affab1L,0xe4d68d76b6e330f4L,\n        0x87a6dafbc75a7fc1L } },\n    /* 16 << 231 */\n    { { 0x549db2b5ef7d9289L,0x2480d4a8197f015aL,0x61d5590bc40493b6L,\n        0x3a55b52e6f780331L },\n      { 0x40eb8115309eadb0L,0xdea7de5a92e5c625L,0x64d631f0cc6a3d5aL,\n        0x9d5e9d7c93e8dd61L } },\n    /* 17 << 231 */\n    { { 0xf297bef5206d3ffcL,0x23d5e0337d808bd4L,0x4a4f6912d24cf5baL,\n        0xe4d8163b09cdaa8aL },\n      { 0x0e0de9efd3082e8eL,0x4fe1246c0192f360L,0x1f9001504b8eee0aL,\n        0x5219da81f1da391bL } },\n    /* 18 << 231 */\n    { { 0x7bf6a5c1f7ea25aaL,0xd165e6bffbb07d5fL,0xe353936189e78671L,\n        0xa3fcac892bac4219L },\n      { 0xdfab6fd4f0baa8abL,0x5a4adac1e2c1c2e5L,0x6cd75e3140d85849L,\n        0xce263fea19b39181L } },\n    /* 19 << 231 */\n    { { 0xcb6803d307032c72L,0x7f40d5ce790968c8L,0xa6de86bddce978f0L,\n        0x25547c4f368f751cL },\n      { 0xb1e685fd65fb2a9eL,0xce69336f1eb9179cL,0xb15d1c2712504442L,\n        0xb7df465cb911a06bL } },\n    /* 20 << 231 */\n    { { 0xb8d804a3315980cdL,0x693bc492fa3bebf7L,0x3578aeee2253c504L,\n        0x158de498cd2474a2L },\n      { 0x1331f5c7cfda8368L,0xd2d7bbb378d7177eL,0xdf61133af3c1e46eL,\n        0x5836ce7dd30e7be8L } },\n    /* 21 << 231 */\n    { { 0x83084f1994f834cbL,0xd35653d4429ed782L,0xa542f16f59e58243L,\n        0xc2b52f650470a22dL },\n      { 0xe3b6221b18f23d96L,0xcb05abac3f5252b4L,0xca00938b87d61402L,\n        0x2f186cdd411933e4L } },\n    /* 22 << 231 */\n    { { 0xe042ece59a29a5c5L,0xb19b3c073b6c8402L,0xc97667c719d92684L,\n        0xb5624622ebc66372L },\n      { 0x0cb96e653c04fa02L,0x83a7176c8eaa39aaL,0x2033561deaa1633fL,\n        0x45a9d0864533df73L } },\n    /* 23 << 231 */\n    { { 0xe0542c1d3dc090bcL,0x82c996efaa59c167L,0xe3f735e80ee7fc4dL,\n        0x7b1793937c35db79L },\n      { 0xb6419e25f8c5dbfdL,0x4d9d7a1e1f327b04L,0x979f6f9b298dfca8L,\n        0xc7c5dff18de9366aL } },\n    /* 24 << 231 */\n    { { 0x1b7a588d04c82bddL,0x68005534f8319dfdL,0xde8a55b5d8eb9580L,\n        0x5ea886da8d5bca81L },\n      { 0xe8530a01252a0b4dL,0x1bffb4fe35eaa0a1L,0x2ad828b1d8e99563L,\n        0x7de96ef595f9cd87L } },\n    /* 25 << 231 */\n    { { 0x4abb2d0cd77d970cL,0x03cfb933d33ef9cbL,0xb0547c018b211fe9L,\n        0x2fe64809a56ed1c6L },\n      { 0xcb7d5624c2ac98ccL,0x2a1372c01a393e33L,0xc8d1ec1c29660521L,\n        0xf3d31b04b37ac3e9L } },\n    /* 26 << 231 */\n    { { 0xa29ae9df5ece6e7cL,0x0603ac8f0facfb55L,0xcfe85b7adda233a5L,\n        0xe618919fbd75f0b8L },\n      { 0xf555a3d299bf1603L,0x1f43afc9f184255aL,0xdcdaf341319a3e02L,\n        0xd3b117ef03903a39L } },\n    /* 27 << 231 */\n    { { 0xe095da1365d1d131L,0x86f16367c37ad03eL,0x5f37389e462cd8ddL,\n        0xc103fa04d67a60e6L },\n      { 0x57c34344f4b478f0L,0xce91edd8e117c98dL,0x001777b0231fc12eL,\n        0x11ae47f2b207bccbL } },\n    /* 28 << 231 */\n    { { 0xd983cf8d20f8a242L,0x7aff5b1df22e1ad8L,0x68fd11d07fc4feb3L,\n        0x5d53ae90b0f1c3e1L },\n      { 0x50fb7905ec041803L,0x85e3c97714404888L,0x0e67faedac628d8fL,\n        0x2e8651506668532cL } },\n    /* 29 << 231 */\n    { { 0x15acaaa46a67a6b0L,0xf4cdee25b25cec41L,0x49ee565ae4c6701eL,\n        0x2a04ca66fc7d63d8L },\n      { 0xeb105018ef0543fbL,0xf709a4f5d1b0d81dL,0x5b906ee62915d333L,\n        0xf4a8741296f1f0abL } },\n    /* 30 << 231 */\n    { { 0xb6b82fa74d82f4c2L,0x90725a606804efb3L,0xbc82ec46adc3425eL,\n        0xb7b805812787843eL },\n      { 0xdf46d91cdd1fc74cL,0xdc1c62cbe783a6c4L,0x59d1b9f31a04cbbaL,\n        0xd87f6f7295e40764L } },\n    /* 31 << 231 */\n    { { 0x02b4cfc1317f4a76L,0x8d2703eb91036bceL,0x98206cc6a5e72a56L,\n        0x57be9ed1cf53fb0fL },\n      { 0x09374571ef0b17acL,0x74b2655ed9181b38L,0xc8f80ea889935d0eL,\n        0xc0d9e94291529936L } },\n    /* 32 << 231 */\n    { { 0x196860411e84e0e5L,0xa5db84d3aea34c93L,0xf9d5bb197073a732L,\n        0xb8d2fe566bcfd7c0L },\n      { 0x45775f36f3eb82faL,0x8cb20cccfdff8b58L,0x1659b65f8374c110L,\n        0xb8b4a422330c789aL } },\n    /* 33 << 231 */\n    { { 0x75e3c3ea6fe8208bL,0xbd74b9e4286e78feL,0x0be2e81bd7d93a1aL,\n        0x7ed06e27dd0a5aaeL },\n      { 0x721f5a586be8b800L,0x428299d1d846db28L,0x95cb8e6b5be88ed3L,\n        0xc3186b231c034e11L } },\n    /* 34 << 231 */\n    { { 0xa6312c9e8977d99bL,0xbe94433183f531e7L,0x8232c0c218d3b1d4L,\n        0x617aae8be1247b73L },\n      { 0x40153fc4282aec3bL,0xc6063d2ff7b8f823L,0x68f10e583304f94cL,\n        0x31efae74ee676346L } },\n    /* 35 << 231 */\n    { { 0xbadb6c6d40a9b97cL,0x14702c634f666256L,0xdeb954f15184b2e3L,\n        0x5184a52694b6ca40L },\n      { 0xfff05337003c32eaL,0x5aa374dd205974c7L,0x9a7638544b0dd71aL,\n        0x459cd27fdeb947ecL } },\n    /* 36 << 231 */\n    { { 0xa6e28161459c2b92L,0x2f020fa875ee8ef5L,0xb132ec2d30b06310L,\n        0xc3e15899bc6a4530L },\n      { 0xdc5f53feaa3f451aL,0x3a3c7f23c2d9acacL,0x2ec2f8926b27e58bL,\n        0x68466ee7d742799fL } },\n    /* 37 << 231 */\n    { { 0x98324dd41fa26613L,0xa2dc6dabbdc29d63L,0xf9675faad712d657L,\n        0x813994be21fd8d15L },\n      { 0x5ccbb722fd4f7553L,0x5135ff8bf3a36b20L,0x44be28af69559df5L,\n        0x40b65bed9d41bf30L } },\n    /* 38 << 231 */\n    { { 0xd98bf2a43734e520L,0x5e3abbe3209bdcbaL,0x77c76553bc945b35L,\n        0x5331c093c6ef14aaL },\n      { 0x518ffe2976b60c80L,0x2285593b7ace16f8L,0xab1f64ccbe2b9784L,\n        0xe8f2c0d9ab2421b6L } },\n    /* 39 << 231 */\n    { { 0x617d7174c1df065cL,0xafeeb5ab5f6578faL,0x16ff1329263b54a8L,\n        0x45c55808c990dce3L },\n      { 0x42eab6c0ecc8c177L,0x799ea9b55982ecaaL,0xf65da244b607ef8eL,\n        0x8ab226ce32a3fc2cL } },\n    /* 40 << 231 */\n    { { 0x745741e57ea973dcL,0x5c00ca7020888f2eL,0x7cdce3cf45fd9cf1L,\n        0x8a741ef15507f872L },\n      { 0x47c51c2f196b4cecL,0x70d08e43c97ea618L,0x930da15c15b18a2bL,\n        0x33b6c6782f610514L } },\n    /* 41 << 231 */\n    { { 0xc662e4f807ac9794L,0x1eccf050ba06cb79L,0x1ff08623e7d954e5L,\n        0x6ef2c5fb24cf71c3L },\n      { 0xb2c063d267978453L,0xa0cf37961d654af8L,0x7cb242ea7ebdaa37L,\n        0x206e0b10b86747e0L } },\n    /* 42 << 231 */\n    { { 0x481dae5fd5ecfefcL,0x07084fd8c2bff8fcL,0x8040a01aea324596L,\n        0x4c646980d4de4036L },\n      { 0x9eb8ab4ed65abfc3L,0xe01cb91f13541ec7L,0x8f029adbfd695012L,\n        0x9ae284833c7569ecL } },\n    /* 43 << 231 */\n    { { 0xa5614c9ea66d80a1L,0x680a3e4475f5f911L,0x0c07b14dceba4fc1L,\n        0x891c285ba13071c1L },\n      { 0xcac67ceb799ece3cL,0x29b910a941e07e27L,0x66bdb409f2e43123L,\n        0x06f8b1377ac9ecbeL } },\n    /* 44 << 231 */\n    { { 0x5981fafd38547090L,0x19ab8b9f85e3415dL,0xfc28c194c7e31b27L,\n        0x843be0aa6fbcbb42L },\n      { 0xf3b1ed43a6db836cL,0x2a1330e401a45c05L,0x4f19f3c595c1a377L,\n        0xa85f39d044b5ee33L } },\n    /* 45 << 231 */\n    { { 0x3da18e6d4ae52834L,0x5a403b397423dcb0L,0xbb555e0af2374aefL,\n        0x2ad599c41e8ca111L },\n      { 0x1b3a2fb9014b3bf8L,0x73092684f66d5007L,0x079f1426c4340102L,\n        0x1827cf818fddf4deL } },\n    /* 46 << 231 */\n    { { 0xc83605f6f10ff927L,0xd387145123739fc6L,0x6d163450cac1c2ccL,\n        0x6b521296a2ec1ac5L },\n      { 0x0606c4f96e3cb4a5L,0xe47d3f41778abff7L,0x425a8d5ebe8e3a45L,\n        0x53ea9e97a6102160L } },\n    /* 47 << 231 */\n    { { 0x477a106e39cbb688L,0x532401d2f3386d32L,0x8e564f64b1b9b421L,\n        0xca9b838881dad33fL },\n      { 0xb1422b4e2093913eL,0x533d2f9269bc8112L,0x3fa017beebe7b2c7L,\n        0xb2767c4acaf197c6L } },\n    /* 48 << 231 */\n    { { 0xc925ff87aedbae9fL,0x7daf0eb936880a54L,0x9284ddf59c4d0e71L,\n        0x1581cf93316f8cf5L },\n      { 0x3eeca8873ac1f452L,0xb417fce9fb6aeffeL,0xa5918046eefb8dc3L,\n        0x73d318ac02209400L } },\n    /* 49 << 231 */\n    { { 0xe800400f728693e5L,0xe87d814b339927edL,0x93e94d3b57ea9910L,\n        0xff8a35b62245fb69L },\n      { 0x043853d77f200d34L,0x470f1e680f653ce1L,0x81ac05bd59a06379L,\n        0xa14052c203930c29L } },\n    /* 50 << 231 */\n    { { 0x6b72fab526bc2797L,0x13670d1699f16771L,0x001700521e3e48d1L,\n        0x978fe401b7adf678L },\n      { 0x55ecfb92d41c5dd4L,0x5ff8e247c7b27da5L,0xe7518272013fb606L,\n        0x5768d7e52f547a3cL } },\n    /* 51 << 231 */\n    { { 0xbb24eaa360017a5fL,0x6b18e6e49c64ce9bL,0xc225c655103dde07L,\n        0xfc3672ae7592f7eaL },\n      { 0x9606ad77d06283a1L,0x542fc650e4d59d99L,0xabb57c492a40e7c2L,\n        0xac948f13a8db9f55L } },\n    /* 52 << 231 */\n    { { 0x6d4c9682b04465c3L,0xe3d062fa6468bd15L,0xa51729ac5f318d7eL,\n        0x1fc87df69eb6fc95L },\n      { 0x63d146a80591f652L,0xa861b8f7589621aaL,0x59f5f15ace31348cL,\n        0x8f663391440da6daL } },\n    /* 53 << 231 */\n    { { 0xcfa778acb591ffa3L,0x027ca9c54cdfebceL,0xbe8e05a5444ea6b3L,\n        0x8aab4e69a78d8254L },\n      { 0x2437f04fb474d6b8L,0x6597ffd4045b3855L,0xbb0aea4eca47ecaaL,\n        0x568aae8385c7ebfcL } },\n    /* 54 << 231 */\n    { { 0x0e966e64c73b2383L,0x49eb3447d17d8762L,0xde1078218da05dabL,\n        0x443d8baa016b7236L },\n      { 0x163b63a5ea7610d6L,0xe47e4185ce1ca979L,0xae648b6580baa132L,\n        0xebf53de20e0d5b64L } },\n    /* 55 << 231 */\n    { { 0x8d3bfcb4d3c8c1caL,0x0d914ef35d04b309L,0x55ef64153de7d395L,\n        0xbde1666f26b850e8L },\n      { 0xdbe1ca6ed449ab19L,0x8902b322e89a2672L,0xb1674b7edacb7a53L,\n        0x8e9faf6ef52523ffL } },\n    /* 56 << 231 */\n    { { 0x6ba535da9a85788bL,0xd21f03aebd0626d4L,0x099f8c47e873dc64L,\n        0xcda8564d018ec97eL },\n      { 0x3e8d7a5cde92c68cL,0x78e035a173323cc4L,0x3ef26275f880ff7cL,\n        0xa4ee3dff273eedaaL } },\n    /* 57 << 231 */\n    { { 0x58823507af4e18f8L,0x967ec9b50672f328L,0x9ded19d9559d3186L,\n        0x5e2ab3de6cdce39cL },\n      { 0xabad6e4d11c226dfL,0xf9783f4387723014L,0x9a49a0cf1a885719L,\n        0xfc0c1a5a90da9dbfL } },\n    /* 58 << 231 */\n    { { 0x8bbaec49571d92acL,0x569e85fe4692517fL,0x8333b014a14ea4afL,\n        0x32f2a62f12e5c5adL },\n      { 0x98c2ce3a06d89b85L,0xb90741aa2ff77a08L,0x2530defc01f795a2L,\n        0xd6e5ba0b84b3c199L } },\n    /* 59 << 231 */\n    { { 0x7d8e845112e4c936L,0xae419f7dbd0be17bL,0xa583fc8c22262bc9L,\n        0x6b842ac791bfe2bdL },\n      { 0x33cef4e9440d6827L,0x5f69f4deef81fb14L,0xf16cf6f6234fbb92L,\n        0x76ae3fc3d9e7e158L } },\n    /* 60 << 231 */\n    { { 0x4e89f6c2e9740b33L,0x677bc85d4962d6a1L,0x6c6d8a7f68d10d15L,\n        0x5f9a72240257b1cdL },\n      { 0x7096b9164ad85961L,0x5f8c47f7e657ab4aL,0xde57d7d0f7461d7eL,\n        0x7eb6094d80ce5ee2L } },\n    /* 61 << 231 */\n    { { 0x0b1e1dfd34190547L,0x8a394f43f05dd150L,0x0a9eb24d97df44e6L,\n        0x78ca06bf87675719L },\n      { 0x6f0b34626ffeec22L,0x9d91bcea36cdd8fbL,0xac83363ca105be47L,\n        0x81ba76c1069710e3L } },\n    /* 62 << 231 */\n    { { 0x3d1b24cb28c682c6L,0x27f252288612575bL,0xb587c779e8e66e98L,\n        0x7b0c03e9405eb1feL },\n      { 0xfdf0d03015b548e7L,0xa8be76e038b36af7L,0x4cdab04a4f310c40L,\n        0x6287223ef47ecaecL } },\n    /* 63 << 231 */\n    { { 0x678e60558b399320L,0x61fe3fa6c01e4646L,0xc482866b03261a5eL,\n        0xdfcf45b85c2f244aL },\n      { 0x8fab9a512f684b43L,0xf796c654c7220a66L,0x1d90707ef5afa58fL,\n        0x2c421d974fdbe0deL } },\n    /* 64 << 231 */\n    { { 0xc4f4cda3af2ebc2fL,0xa0af843dcb4efe24L,0x53b857c19ccd10b1L,\n        0xddc9d1eb914d3e04L },\n      { 0x7bdec8bb62771debL,0x829277aa91c5aa81L,0x7af18dd6832391aeL,\n        0x1740f316c71a84caL } },\n    /* 0 << 238 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 238 */\n    { { 0x8928e99aeeaf8c49L,0xee7aa73d6e24d728L,0x4c5007c2e72b156cL,\n        0x5fcf57c5ed408a1dL },\n      { 0x9f719e39b6057604L,0x7d343c01c2868bbfL,0x2cca254b7e103e2dL,\n        0xe6eb38a9f131bea2L } },\n    /* 2 << 238 */\n    { { 0xb33e624f8be762b4L,0x2a9ee4d1058e3413L,0x968e636967d805faL,\n        0x9848949b7db8bfd7L },\n      { 0x5308d7e5d23a8417L,0x892f3b1df3e29da5L,0xc95c139e3dee471fL,\n        0x8631594dd757e089L } },\n    /* 3 << 238 */\n    { { 0xe0c82a3cde918dccL,0x2e7b599426fdcf4bL,0x82c5024932cb1b2dL,\n        0xea613a9d7657ae07L },\n      { 0xc2eb5f6cf1fdc9f7L,0xb6eae8b8879fe682L,0x253dfee0591cbc7fL,\n        0x000da7133e1290e6L } },\n    /* 4 << 238 */\n    { { 0x1083e2ea1f095615L,0x0a28ad7714e68c33L,0x6bfc02523d8818beL,\n        0xb585113af35850cdL },\n      { 0x7d935f0b30df8aa1L,0xaddda07c4ab7e3acL,0x92c34299552f00cbL,\n        0xc33ed1de2909df6cL } },\n    /* 5 << 238 */\n    { { 0x22c2195d80e87766L,0x9e99e6d89ddf4ac0L,0x09642e4e65e74934L,\n        0x2610ffa2ff1ff241L },\n      { 0x4d1d47d4751c8159L,0x697b4985af3a9363L,0x0318ca4687477c33L,\n        0xa90cb5659441eff3L } },\n    /* 6 << 238 */\n    { { 0x58bb384836f024cbL,0x85be1f7736016168L,0x6c59587cdc7e07f1L,\n        0x191be071af1d8f02L },\n      { 0xbf169fa5cca5e55cL,0x3864ba3cf7d04eacL,0x915e367f8d7d05dbL,\n        0xb48a876da6549e5dL } },\n    /* 7 << 238 */\n    { { 0xef89c656580e40a2L,0xf194ed8c728068bcL,0x74528045a47990c9L,\n        0xf53fc7d75e1a4649L },\n      { 0xbec5ae9b78593e7dL,0x2cac4ee341db65d7L,0xa8c1eb2404a3d39bL,\n        0x53b7d63403f8f3efL } },\n    /* 8 << 238 */\n    { { 0x2dc40d483e07113cL,0x6e4a5d397d8b63aeL,0x5582a94b79684c2bL,\n        0x932b33d4622da26cL },\n      { 0xf534f6510dbbf08dL,0x211d07c964c23a52L,0x0eeece0fee5bdc9bL,\n        0xdf178168f7015558L } },\n    /* 9 << 238 */\n    { { 0xd42946350a712229L,0x93cbe44809273f8cL,0x00b095ef8f13bc83L,\n        0xbb7419728798978cL },\n      { 0x9d7309a256dbe6e7L,0xe578ec565a5d39ecL,0x3961151b851f9a31L,\n        0x2da7715de5709eb4L } },\n    /* 10 << 238 */\n    { { 0x867f301753dfabf0L,0x728d2078b8e39259L,0x5c75a0cd815d9958L,\n        0xf84867a616603be1L },\n      { 0xc865b13d70e35b1cL,0x0241446819b03e2cL,0xe46041daac1f3121L,\n        0x7c9017ad6f028a7cL } },\n    /* 11 << 238 */\n    { { 0xabc96de90a482873L,0x4265d6b1b77e54d4L,0x68c38e79a57d88e7L,\n        0xd461d7669ce82de3L },\n      { 0x817a9ec564a7e489L,0xcc5675cda0def5f2L,0x9a00e785985d494eL,\n        0xc626833f1b03514aL } },\n    /* 12 << 238 */\n    { { 0xabe7905a83cdd60eL,0x50602fb5a1170184L,0x689886cdb023642aL,\n        0xd568d090a6e1fb00L },\n      { 0x5b1922c70259217fL,0x93831cd9c43141e4L,0xdfca35870c95f86eL,\n        0xdec2057a568ae828L } },\n    /* 13 << 238 */\n    { { 0xc44ea599f98a759aL,0x55a0a7a2f7c23c1dL,0xd5ffb6e694c4f687L,\n        0x3563cce212848478L },\n      { 0x812b3517e7b1fbe1L,0x8a7dc9794f7338e0L,0x211ecee952d048dbL,\n        0x2eea4056c86ea3b8L } },\n    /* 14 << 238 */\n    { { 0xd8cb68a7ba772b34L,0xe16ed3415f4e2541L,0x9b32f6a60fec14dbL,\n        0xeee376f7391698beL },\n      { 0xe9a7aa1783674c02L,0x65832f975843022aL,0x29f3a8da5ba4990fL,\n        0x79a59c3afb8e3216L } },\n    /* 15 << 238 */\n    { { 0x9cdc4d2ebd19bb16L,0xc6c7cfd0b3262d86L,0xd4ce14d0969c0b47L,\n        0x1fa352b713e56128L },\n      { 0x383d55b8973db6d3L,0x71836850e8e5b7bfL,0xc7714596e6bb571fL,\n        0x259df31f2d5b2dd2L } },\n    /* 16 << 238 */\n    { { 0x568f8925913cc16dL,0x18bc5b6de1a26f5aL,0xdfa413bef5f499aeL,\n        0xf8835decc3f0ae84L },\n      { 0xb6e60bd865a40ab0L,0x65596439194b377eL,0xbcd8562592084a69L,\n        0x5ce433b94f23ede0L } },\n    /* 17 << 238 */\n    { { 0xe8e8f04f6ad65143L,0x11511827d6e14af6L,0x3d390a108295c0c7L,\n        0x71e29ee4621eba16L },\n      { 0xa588fc0963717b46L,0x02be02fee06ad4a2L,0x931558c604c22b22L,\n        0xbb4d4bd612f3c849L } },\n    /* 18 << 238 */\n    { { 0x54a4f49620efd662L,0x92ba6d20c5952d14L,0x2db8ea1ecc9784c2L,\n        0x81cc10ca4b353644L },\n      { 0x40b570ad4b4d7f6cL,0x5c9f1d9684a1dcd2L,0x01379f813147e797L,\n        0xe5c6097b2bd499f5L } },\n    /* 19 << 238 */\n    { { 0x40dcafa6328e5e20L,0xf7b5244a54815550L,0xb9a4f11847bfc978L,\n        0x0ea0e79fd25825b1L },\n      { 0xa50f96eb646c7ecfL,0xeb811493446dea9dL,0x2af04677dfabcf69L,\n        0xbe3a068fc713f6e8L } },\n    /* 20 << 238 */\n    { { 0x860d523d42e06189L,0xbf0779414e3aff13L,0x0b616dcac1b20650L,\n        0xe66dd6d12131300dL },\n      { 0xd4a0fd67ff99abdeL,0xc9903550c7aac50dL,0x022ecf8b7c46b2d7L,\n        0x3333b1e83abf92afL } },\n    /* 21 << 238 */\n    { { 0x11cc113c6c491c14L,0x0597668880dd3f88L,0xf5b4d9e729d932edL,\n        0xe982aad8a2c38b6dL },\n      { 0x6f9253478be0dcf0L,0x700080ae65ca53f2L,0xd8131156443ca77fL,\n        0xe92d6942ec51f984L } },\n    /* 22 << 238 */\n    { { 0xd2a08af885dfe9aeL,0xd825d9a54d2a86caL,0x2c53988d39dff020L,\n        0xf38b135a430cdc40L },\n      { 0x0c918ae062a7150bL,0xf31fd8de0c340e9bL,0xafa0e7ae4dbbf02eL,\n        0x5847fb2a5eba6239L } },\n    /* 23 << 238 */\n    { { 0x6b1647dcdccbac8bL,0xb642aa7806f485c8L,0x873f37657038ecdfL,\n        0x2ce5e865fa49d3feL },\n      { 0xea223788c98c4400L,0x8104a8cdf1fa5279L,0xbcf7cc7a06becfd7L,\n        0x49424316c8f974aeL } },\n    /* 24 << 238 */\n    { { 0xc0da65e784d6365dL,0xbcb7443f8f759fb8L,0x35c712b17ae81930L,\n        0x80428dff4c6e08abL },\n      { 0xf19dafefa4faf843L,0xced8538dffa9855fL,0x20ac409cbe3ac7ceL,\n        0x358c1fb6882da71eL } },\n    /* 25 << 238 */\n    { { 0xafa9c0e5fd349961L,0x2b2cfa518421c2fcL,0x2a80db17f3a28d38L,\n        0xa8aba5395d138e7eL },\n      { 0x52012d1d6e96eb8dL,0x65d8dea0cbaf9622L,0x57735447b264f56cL,\n        0xbeebef3f1b6c8da2L } },\n    /* 26 << 238 */\n    { { 0xfc346d98ce785254L,0xd50e8d72bb64a161L,0xc03567c749794addL,\n        0x15a76065752c7ef6L },\n      { 0x59f3a222961f23d6L,0x378e443873ecc0b0L,0xc74be4345a82fde4L,\n        0xae509af2d8b9cf34L } },\n    /* 27 << 238 */\n    { { 0x4a61ee46577f44a1L,0xe09b748cb611deebL,0xc0481b2cf5f7b884L,\n        0x3562667861acfa6bL },\n      { 0x37f4c518bf8d21e6L,0x22d96531b205a76dL,0x37fb85e1954073c0L,\n        0xbceafe4f65b3a567L } },\n    /* 28 << 238 */\n    { { 0xefecdef7be42a582L,0xd3fc608065046be6L,0xc9af13c809e8dba9L,\n        0x1e6c9847641491ffL },\n      { 0x3b574925d30c31f7L,0xb7eb72baac2a2122L,0x776a0dacef0859e7L,\n        0x06fec31421900942L } },\n    /* 29 << 238 */\n    { { 0x2464bc10f8c22049L,0x9bfbcce7875ebf69L,0xd7a88e2a4336326bL,\n        0xda05261c5bc2acfaL },\n      { 0xc29f5bdceba7efc8L,0x471237ca25dbbf2eL,0xa72773f22975f127L,\n        0xdc744e8e04d0b326L } },\n    /* 30 << 238 */\n    { { 0x38a7ed16a56edb73L,0x64357e372c007e70L,0xa167d15b5080b400L,\n        0x07b4116423de4be1L },\n      { 0xb2d91e3274c89883L,0x3c1628212882e7edL,0xad6b36ba7503e482L,\n        0x48434e8e0ea34331L } },\n    /* 31 << 238 */\n    { { 0x79f4f24f2c7ae0b9L,0xc46fbf811939b44aL,0x76fefae856595eb1L,\n        0x417b66abcd5f29c7L },\n      { 0x5f2332b2c5ceec20L,0xd69661ffe1a1cae2L,0x5ede7e529b0286e6L,\n        0x9d062529e276b993L } },\n    /* 32 << 238 */\n    { { 0x324794b07e50122bL,0xdd744f8b4af07ca5L,0x30a12f08d63fc97bL,\n        0x39650f1a76626d9dL },\n      { 0x101b47f71fa38477L,0x3d815f19d4dc124fL,0x1569ae95b26eb58aL,\n        0xc3cde18895fb1887L } },\n    /* 33 << 238 */\n    { { 0x54e9f37bf9539a48L,0xb0100e067408c1a5L,0x821d9811ea580cbbL,\n        0x8af52d3586e50c56L },\n      { 0xdfbd9d47dbbf698bL,0x2961a1ea03dc1c73L,0x203d38f8e76a5df8L,\n        0x08a53a686def707aL } },\n    /* 34 << 238 */\n    { { 0x26eefb481bee45d4L,0xb3cee3463c688036L,0x463c5315c42f2469L,\n        0x19d84d2e81378162L },\n      { 0x22d7c3c51c4d349fL,0x65965844163d59c5L,0xcf198c56b8abceaeL,\n        0x6fb1fb1b628559d5L } },\n    /* 35 << 238 */\n    { { 0x8bbffd0607bf8fe3L,0x46259c583467734bL,0xd8953cea35f7f0d3L,\n        0x1f0bece2d65b0ff1L },\n      { 0xf7d5b4b3f3c72914L,0x29e8ea953cb53389L,0x4a365626836b6d46L,\n        0xe849f910ea174fdeL } },\n    /* 36 << 238 */\n    { { 0x7ec62fbbf4737f21L,0xd8dba5ab6209f5acL,0x24b5d7a9a5f9adbeL,\n        0x707d28f7a61dc768L },\n      { 0x7711460bcaa999eaL,0xba7b174d1c92e4ccL,0x3c4bab6618d4bf2dL,\n        0xb8f0c980eb8bd279L } },\n    /* 37 << 238 */\n    { { 0x024bea9a324b4737L,0xfba9e42332a83bcaL,0x6e635643a232dcedL,\n        0x996193672571c8baL },\n      { 0xe8c9f35754b7032bL,0xf936b3ba2442d54aL,0x2263f0f08290c65aL,\n        0x48989780ee2c7fdbL } },\n    /* 38 << 238 */\n    { { 0xadc5d55a13d4f95eL,0x737cff85ad9b8500L,0x271c557b8a73f43dL,\n        0xbed617a4e18bc476L },\n      { 0x662454017dfd8ab2L,0xae7b89ae3a2870aaL,0x1b555f5323a7e545L,\n        0x6791e247be057e4cL } },\n    /* 39 << 238 */\n    { { 0x860136ad324fa34dL,0xea1114474cbeae28L,0x023a4270bedd3299L,\n        0x3d5c3a7fc1c35c34L },\n      { 0xb0f6db678d0412d2L,0xd92625e2fcdc6b9aL,0x92ae5ccc4e28a982L,\n        0xea251c3647a3ce7eL } },\n    /* 40 << 238 */\n    { { 0x9d658932790691bfL,0xed61058906b736aeL,0x712c2f04c0d63b6eL,\n        0x5cf06fd5c63d488fL },\n      { 0x97363facd9588e41L,0x1f9bf7622b93257eL,0xa9d1ffc4667acaceL,\n        0x1cf4a1aa0a061ecfL } },\n    /* 41 << 238 */\n    { { 0x40e48a49dc1818d0L,0x0643ff39a3621ab0L,0x5768640ce39ef639L,\n        0x1fc099ea04d86854L },\n      { 0x9130b9c3eccd28fdL,0xd743cbd27eec54abL,0x052b146fe5b475b6L,\n        0x058d9a82900a7d1fL } },\n    /* 42 << 238 */\n    { { 0x65e0229291262b72L,0x96f924f9bb0edf03L,0x5cfa59c8fe206842L,\n        0xf60370045eafa720L },\n      { 0x5f30699e18d7dd96L,0x381e8782cbab2495L,0x91669b46dd8be949L,\n        0xb40606f526aae8efL } },\n    /* 43 << 238 */\n    { { 0x2812b839fc6751a4L,0x16196214fba800efL,0x4398d5ca4c1a2875L,\n        0x720c00ee653d8349L },\n      { 0xc2699eb0d820007cL,0x880ee660a39b5825L,0x70694694471f6984L,\n        0xf7d16ea8e3dda99aL } },\n    /* 44 << 238 */\n    { { 0x28d675b2c0519a23L,0x9ebf94fe4f6952e3L,0xf28bb767a2294a8aL,\n        0x85512b4dfe0af3f5L },\n      { 0x18958ba899b16a0dL,0x95c2430cba7548a7L,0xb30d1b10a16be615L,\n        0xe3ebbb9785bfb74cL } },\n    /* 45 << 238 */\n    { { 0xa3273cfe18549fdbL,0xf6e200bf4fcdb792L,0x54a76e1883aba56cL,\n        0x73ec66f689ef6aa2L },\n      { 0x8d17add7d1b9a305L,0xa959c5b9b7ae1b9dL,0x886435226bcc094aL,\n        0xcc5616c4d7d429b9L } },\n    /* 46 << 238 */\n    { { 0xa6dada01e6a33f7cL,0xc6217a079d4e70adL,0xd619a81809c15b7cL,\n        0xea06b3290e80c854L },\n      { 0x174811cea5f5e7b9L,0x66dfc310787c65f4L,0x4ea7bd693316ab54L,\n        0xc12c4acb1dcc0f70L } },\n    /* 47 << 238 */\n    { { 0xe4308d1a1e407dd9L,0xe8a3587c91afa997L,0xea296c12ab77b7a5L,\n        0xb5ad49e4673c0d52L },\n      { 0x40f9b2b27006085aL,0xa88ff34087bf6ec2L,0x978603b14e3066a6L,\n        0xb3f99fc2b5e486e2L } },\n    /* 48 << 238 */\n    { { 0x07b53f5eb2e63645L,0xbe57e54784c84232L,0xd779c2167214d5cfL,\n        0x617969cd029a3acaL },\n      { 0xd17668cd8a7017a0L,0x77b4d19abe9b7ee8L,0x58fd0e939c161776L,\n        0xa8c4f4efd5968a72L } },\n    /* 49 << 238 */\n    { { 0x296071cc67b3de77L,0xae3c0b8e634f7905L,0x67e440c28a7100c9L,\n        0xbb8c3c1beb4b9b42L },\n      { 0x6d71e8eac51b3583L,0x7591f5af9525e642L,0xf73a2f7b13f509f3L,\n        0x618487aa5619ac9bL } },\n    /* 50 << 238 */\n    { { 0x3a72e5f79d61718aL,0x00413bcc7592d28cL,0x7d9b11d3963c35cfL,\n        0x77623bcfb90a46edL },\n      { 0xdeef273bdcdd2a50L,0x4a741f9b0601846eL,0x33b89e510ec6e929L,\n        0xcb02319f8b7f22cdL } },\n    /* 51 << 238 */\n    { { 0xbbe1500d084bae24L,0x2f0ae8d7343d2693L,0xacffb5f27cdef811L,\n        0xaa0c030a263fb94fL },\n      { 0x6eef0d61a0f442deL,0xf92e181727b139d3L,0x1ae6deb70ad8bc28L,\n        0xa89e38dcc0514130L } },\n    /* 52 << 238 */\n    { { 0x81eeb865d2fdca23L,0x5a15ee08cc8ef895L,0x768fa10a01905614L,\n        0xeff5b8ef880ee19bL },\n      { 0xf0c0cabbcb1c8a0eL,0x2e1ee9cdb8c838f9L,0x0587d8b88a4a14c0L,\n        0xf6f278962ff698e5L } },\n    /* 53 << 238 */\n    { { 0xed38ef1c89ee6256L,0xf44ee1fe6b353b45L,0x9115c0c770e903b3L,\n        0xc78ec0a1818f31dfL },\n      { 0x6c003324b7dccbc6L,0xd96dd1f3163bbc25L,0x33aa82dd5cedd805L,\n        0x123aae4f7f7eb2f1L } },\n    /* 54 << 238 */\n    { { 0x1723fcf5a26262cdL,0x1f7f4d5d0060ebd5L,0xf19c5c01b2eaa3afL,\n        0x2ccb9b149790accfL },\n      { 0x1f9c1cad52324aa6L,0x632005267247df54L,0x5732fe42bac96f82L,\n        0x52fe771f01a1c384L } },\n    /* 55 << 238 */\n    { { 0x546ca13db1001684L,0xb56b4eeea1709f75L,0x266545a9d5db8672L,\n        0xed971c901e8f3cfbL },\n      { 0x4e7d8691e3a07b29L,0x7570d9ece4b696b9L,0xdc5fa0677bc7e9aeL,\n        0x68b44cafc82c4844L } },\n    /* 56 << 238 */\n    { { 0x519d34b3bf44da80L,0x283834f95ab32e66L,0x6e6087976278a000L,\n        0x1e62960e627312f6L },\n      { 0x9b87b27be6901c55L,0x80e7853824fdbc1fL,0xbbbc09512facc27dL,\n        0x06394239ac143b5aL } },\n    /* 57 << 238 */\n    { { 0x35bb4a40376c1944L,0x7cb6269463da1511L,0xafd29161b7148a3bL,\n        0xa6f9d9ed4e2ea2eeL },\n      { 0x15dc2ca2880dd212L,0x903c3813a61139a9L,0x2aa7b46d6c0f8785L,\n        0x36ce2871901c60ffL } },\n    /* 58 << 238 */\n    { { 0xc683b028e10d9c12L,0x7573baa2032f33d3L,0x87a9b1f667a31b58L,\n        0xfd3ed11af4ffae12L },\n      { 0x83dcaa9a0cb2748eL,0x8239f0185d6fdf16L,0xba67b49c72753941L,\n        0x2beec455c321cb36L } },\n    /* 59 << 238 */\n    { { 0x880156063f8b84ceL,0x764170838d38c86fL,0x054f1ca7598953ddL,\n        0xc939e1104e8e7429L },\n      { 0x9b1ac2b35a914f2fL,0x39e35ed3e74b8f9cL,0xd0debdb2781b2fb0L,\n        0x1585638f2d997ba2L } },\n    /* 60 << 238 */\n    { { 0x9c4b646e9e2fce99L,0x68a210811e80857fL,0x06d54e443643b52aL,\n        0xde8d6d630d8eb843L },\n      { 0x7032156342146a0aL,0x8ba826f25eaa3622L,0x227a58bd86138787L,\n        0x43b6c03c10281d37L } },\n    /* 61 << 238 */\n    { { 0x6326afbbb54dde39L,0x744e5e8adb6f2d5fL,0x48b2a99acff158e1L,\n        0xa93c8fa0ef87918fL },\n      { 0x2182f956de058c5cL,0x216235d2936f9e7aL,0xace0c0dbd2e31e67L,\n        0xc96449bff23ac3e7L } },\n    /* 62 << 238 */\n    { { 0x7e9a2874170693bdL,0xa28e14fda45e6335L,0x5757f6b356427344L,\n        0x822e4556acf8edf9L },\n      { 0x2b7a6ee2e6a285cdL,0x5866f211a9df3af0L,0x40dde2ddf845b844L,\n        0x986c3726110e5e49L } },\n    /* 63 << 238 */\n    { { 0x73680c2af7172277L,0x57b94f0f0cccb244L,0xbdff72672d438ca7L,\n        0xbad1ce11cf4663fdL },\n      { 0x9813ed9dd8f71caeL,0xf43272a6961fdaa6L,0xbeff0119bd6d1637L,\n        0xfebc4f9130361978L } },\n    /* 64 << 238 */\n    { { 0x02b37a952f41deffL,0x0e44a59ae63b89b7L,0x673257dc143ff951L,\n        0x19c02205d752baf4L },\n      { 0x46c23069c4b7d692L,0x2e6392c3fd1502acL,0x6057b1a21b220846L,\n        0xe51ff9460c1b5b63L } },\n    /* 0 << 245 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 245 */\n    { { 0x6e85cb51566c5c43L,0xcff9c9193597f046L,0x9354e90c4994d94aL,\n        0xe0a393322147927dL },\n      { 0x8427fac10dc1eb2bL,0x88cfd8c22ff319faL,0xe2d4e68401965274L,\n        0xfa2e067d67aaa746L } },\n    /* 2 << 245 */\n    { { 0xb6d92a7f3e5f9f11L,0x9afe153ad6cb3b8eL,0x4d1a6dd7ddf800bdL,\n        0xf6c13cc0caf17e19L },\n      { 0x15f6c58e325fc3eeL,0x71095400a31dc3b2L,0x168e7c07afa3d3e7L,\n        0x3f8417a194c7ae2dL } },\n    /* 3 << 245 */\n    { { 0xec234772813b230dL,0x634d0f5f17344427L,0x11548ab1d77fc56aL,\n        0x7fab1750ce06af77L },\n      { 0xb62c10a74f7c4f83L,0xa7d2edc4220a67d9L,0x1c404170921209a0L,\n        0x0b9815a0face59f0L } },\n    /* 4 << 245 */\n    { { 0x2842589b319540c3L,0x18490f59a283d6f8L,0xa2731f84daae9fcbL,\n        0x3db6d960c3683ba0L },\n      { 0xc85c63bb14611069L,0xb19436af0788bf05L,0x905459df347460d2L,\n        0x73f6e094e11a7db1L } },\n    /* 5 << 245 */\n    { { 0xdc7f938eb6357f37L,0xc5d00f792bd8aa62L,0xc878dcb92ca979fcL,\n        0x37e83ed9eb023a99L },\n      { 0x6b23e2731560bf3dL,0x1086e4591d0fae61L,0x782483169a9414bdL,\n        0x1b956bc0f0ea9ea1L } },\n    /* 6 << 245 */\n    { { 0x7b85bb91c31b9c38L,0x0c5aa90b48ef57b5L,0xdedeb169af3bab6fL,\n        0xe610ad732d373685L },\n      { 0xf13870df02ba8e15L,0x0337edb68ca7f771L,0xe4acf747b62c036cL,\n        0xd921d576b6b94e81L } },\n    /* 7 << 245 */\n    { { 0xdbc864392c422f7aL,0xfb635362ed348898L,0x83084668c45bfcd1L,\n        0xc357c9e32b315e11L },\n      { 0xb173b5405b2e5b8cL,0x7e946931e102b9a4L,0x17c890eb7b0fb199L,\n        0xec225a83d61b662bL } },\n    /* 8 << 245 */\n    { { 0xf306a3c8ee3c76cbL,0x3cf11623d32a1f6eL,0xe6d5ab646863e956L,\n        0x3b8a4cbe5c005c26L },\n      { 0xdcd529a59ce6bb27L,0xc4afaa5204d4b16fL,0xb0624a267923798dL,\n        0x85e56df66b307fabL } },\n    /* 9 << 245 */\n    { { 0x0281893c2bf29698L,0x91fc19a4d7ce7603L,0x75a5dca3ad9a558fL,\n        0x40ceb3fa4d50bf77L },\n      { 0x1baf6060bc9ba369L,0x927e1037597888c2L,0xd936bf1986a34c07L,\n        0xd4cf10c1c34ae980L } },\n    /* 10 << 245 */\n    { { 0x3a3e5334859dd614L,0x9c475b5b18d0c8eeL,0x63080d1f07cd51d5L,\n        0xc9c0d0a6b88b4326L },\n      { 0x1ac98691c234296fL,0x2a0a83a494887fb6L,0x565114270cea9cf2L,\n        0x5230a6e8a24802f5L } },\n    /* 11 << 245 */\n    { { 0xf7a2bf0f72e3d5c1L,0x377174464f21439eL,0xfedcbf259ce30334L,\n        0xe0030a787ce202f9L },\n      { 0x6f2d9ebf1202e9caL,0xe79dde6c75e6e591L,0xf52072aff1dac4f8L,\n        0x6c8d087ebb9b404dL } },\n    /* 12 << 245 */\n    { { 0xad0fc73dbce913afL,0x909e587b458a07cbL,0x1300da84d4f00c8aL,\n        0x425cd048b54466acL },\n      { 0xb59cb9be90e9d8bfL,0x991616db3e431b0eL,0xd3aa117a531aecffL,\n        0x91af92d359f4dc3bL } },\n    /* 13 << 245 */\n    { { 0x9b1ec292e93fda29L,0x76bb6c17e97d91bcL,0x7509d95faface1e6L,\n        0x3653fe47be855ae3L },\n      { 0x73180b280f680e75L,0x75eefd1beeb6c26cL,0xa4cdf29fb66d4236L,\n        0x2d70a9976b5821d8L } },\n    /* 14 << 245 */\n    { { 0x7a3ee20720445c36L,0x71d1ac8259877174L,0x0fc539f7949f73e9L,\n        0xd05cf3d7982e3081L },\n      { 0x8758e20b7b1c7129L,0xffadcc20569e61f2L,0xb05d3a2f59544c2dL,\n        0xbe16f5c19fff5e53L } },\n    /* 15 << 245 */\n    { { 0x73cf65b8aad58135L,0x622c2119037aa5beL,0x79373b3f646fd6a0L,\n        0x0e029db50d3978cfL },\n      { 0x8bdfc43794fba037L,0xaefbd687620797a6L,0x3fa5382bbd30d38eL,\n        0x7627cfbf585d7464L } },\n    /* 16 << 245 */\n    { { 0xb2330fef4e4ca463L,0xbcef72873566cc63L,0xd161d2cacf780900L,\n        0x135dc5395b54827dL },\n      { 0x638f052e27bf1bc6L,0x10a224f007dfa06cL,0xe973586d6d3321daL,\n        0x8b0c573826152c8fL } },\n    /* 17 << 245 */\n    { { 0x07ef4f2a34606074L,0x80fe7fe8a0f7047aL,0x3d1a8152e1a0e306L,\n        0x32cf43d888da5222L },\n      { 0xbf89a95f5f02ffe6L,0x3d9eb9a4806ad3eaL,0x012c17bb79c8e55eL,\n        0xfdcd1a7499c81dacL } },\n    /* 18 << 245 */\n    { { 0x7043178bb9556098L,0x4090a1df801c3886L,0x759800ff9b67b912L,\n        0x3e5c0304232620c8L },\n      { 0x4b9d3c4b70dceecaL,0xbb2d3c15181f648eL,0xf981d8376e33345cL,\n        0xb626289b0cf2297aL } },\n    /* 19 << 245 */\n    { { 0x766ac6598baebdcfL,0x1a28ae0975df01e5L,0xb71283da375876d8L,\n        0x4865a96d607b9800L },\n      { 0x25dd1bcd237936b2L,0x332f4f4b60417494L,0xd0923d68370a2147L,\n        0x497f5dfbdc842203L } },\n    /* 20 << 245 */\n    { { 0x9dc74cbd32be5e0fL,0x7475bcb717a01375L,0x438477c950d872b1L,\n        0xcec67879ffe1d63dL },\n      { 0x9b006014d8578c70L,0xc9ad99a878bb6b8bL,0x6799008e11fb3806L,\n        0xcfe81435cd44cab3L } },\n    /* 21 << 245 */\n    { { 0xa2ee15822f4fb344L,0xb8823450483fa6ebL,0x622d323d652c7749L,\n        0xd8474a98beb0a15bL },\n      { 0xe43c154d5d1c00d0L,0x7fd581d90e3e7aacL,0x2b44c6192525ddf8L,\n        0x67a033ebb8ae9739L } },\n    /* 22 << 245 */\n    { { 0x113ffec19ef2d2e4L,0x1bf6767ed5a0ea7fL,0x57fff75e03714c0aL,\n        0xa23c422e0a23e9eeL },\n      { 0xdd5f6b2d540f83afL,0xc2c2c27e55ea46a7L,0xeb6b4246672a1208L,\n        0xd13599f7ae634f7aL } },\n    /* 23 << 245 */\n    { { 0xcf914b5cd7b32c6eL,0x61a5a640eaf61814L,0x8dc3df8b208a1bbbL,\n        0xef627fd6b6d79aa5L },\n      { 0x44232ffcc4c86bc8L,0xe6f9231b061539feL,0x1d04f25a958b9533L,\n        0x180cf93449e8c885L } },\n    /* 24 << 245 */\n    { { 0x896895959884aaf7L,0xb1959be307b348a6L,0x96250e573c147c87L,\n        0xae0efb3add0c61f8L },\n      { 0xed00745eca8c325eL,0x3c911696ecff3f70L,0x73acbc65319ad41dL,\n        0x7b01a020f0b1c7efL } },\n    /* 25 << 245 */\n    { { 0xea32b29363a1483fL,0x89eabe717a248f96L,0x9c6231d3343157e5L,\n        0x93a375e5df3c546dL },\n      { 0xe76e93436a2afe69L,0xc4f89100e166c88eL,0x248efd0d4f872093L,\n        0xae0eb3ea8fe0ea61L } },\n    /* 26 << 245 */\n    { { 0xaf89790d9d79046eL,0x4d650f2d6cee0976L,0xa3935d9a43071ecaL,\n        0x66fcd2c9283b0bfeL },\n      { 0x0e665eb5696605f1L,0xe77e5d07a54cd38dL,0x90ee050a43d950cfL,\n        0x86ddebdad32e69b5L } },\n    /* 27 << 245 */\n    { { 0x6ad94a3dfddf7415L,0xf7fa13093f6e8d5aL,0xc4831d1de9957f75L,\n        0x7de28501d5817447L },\n      { 0x6f1d70789e2aeb6bL,0xba2b9ff4f67a53c2L,0x36963767df9defc3L,\n        0x479deed30d38022cL } },\n    /* 28 << 245 */\n    { { 0xd2edb89b3a8631e8L,0x8de855de7a213746L,0xb2056cb7b00c5f11L,\n        0xdeaefbd02c9b85e4L },\n      { 0x03f39a8dd150892dL,0x37b84686218b7985L,0x36296dd8b7375f1aL,\n        0x472cd4b1b78e898eL } },\n    /* 29 << 245 */\n    { { 0x15dff651e9f05de9L,0xd40450692ce98ba9L,0x8466a7ae9b38024cL,\n        0xb910e700e5a6b5efL },\n      { 0xae1c56eab3aa8f0dL,0xbab2a5077eee74a6L,0x0dca11e24b4c4620L,\n        0xfd896e2e4c47d1f4L } },\n    /* 30 << 245 */\n    { { 0xeb45ae53308fbd93L,0x46cd5a2e02c36fdaL,0x6a3d4e90baa48385L,\n        0xdd55e62e9dbe9960L },\n      { 0xa1406aa02a81ede7L,0x6860dd14f9274ea7L,0xcfdcb0c280414f86L,\n        0xff410b1022f94327L } },\n    /* 31 << 245 */\n    { { 0x5a33cc3849ad467bL,0xefb48b6c0a7335f1L,0x14fb54a4b153a360L,\n        0x604aa9d2b52469ccL },\n      { 0x5e9dc486754e48e9L,0x693cb45537471e8eL,0xfb2fd7cd8d3b37b6L,\n        0x63345e16cf09ff07L } },\n    /* 32 << 245 */\n    { { 0x9910ba6b23a5d896L,0x1fe19e357fe4364eL,0x6e1da8c39a33c677L,\n        0x15b4488b29fd9fd0L },\n      { 0x1f4392541a1f22bfL,0x920a8a70ab8163e8L,0x3fd1b24907e5658eL,\n        0xf2c4f79cb6ec839bL } },\n    /* 33 << 245 */\n    { { 0x1abbc3d04aa38d1bL,0x3b0db35cb5d9510eL,0x1754ac783e60dec0L,\n        0x53272fd7ea099b33L },\n      { 0x5fb0494f07a8e107L,0x4a89e1376a8191faL,0xa113b7f63c4ad544L,\n        0x88a2e9096cb9897bL } },\n    /* 34 << 245 */\n    { { 0x17d55de3b44a3f84L,0xacb2f34417c6c690L,0x3208816810232390L,\n        0xf2e8a61f6c733bf7L },\n      { 0xa774aab69c2d7652L,0xfb5307e3ed95c5bcL,0xa05c73c24981f110L,\n        0x1baae31ca39458c9L } },\n    /* 35 << 245 */\n    { { 0x1def185bcbea62e7L,0xe8ac9eaeeaf63059L,0x098a8cfd9921851cL,\n        0xd959c3f13abe2f5bL },\n      { 0xa4f1952520e40ae5L,0x320789e307a24aa1L,0x259e69277392b2bcL,\n        0x58f6c6671918668bL } },\n    /* 36 << 245 */\n    { { 0xce1db2bbc55d2d8bL,0x41d58bb7f4f6ca56L,0x7650b6808f877614L,\n        0x905e16baf4c349edL },\n      { 0xed415140f661acacL,0x3b8784f0cb2270afL,0x3bc280ac8a402cbaL,\n        0xd53f71460937921aL } },\n    /* 37 << 245 */\n    { { 0xc03c8ee5e5681e83L,0x62126105f6ac9e4aL,0x9503a53f936b1a38L,\n        0x3d45e2d4782fecbdL },\n      { 0x69a5c43976e8ae98L,0xb53b2eebbfb4b00eL,0xf167471272386c89L,\n        0x30ca34a24268bce4L } },\n    /* 38 << 245 */\n    { { 0x7f1ed86c78341730L,0x8ef5beb8b525e248L,0xbbc489fdb74fbf38L,\n        0x38a92a0e91a0b382L },\n      { 0x7a77ba3f22433ccfL,0xde8362d6a29f05a9L,0x7f6a30ea61189afcL,\n        0x693b550559ef114fL } },\n    /* 39 << 245 */\n    { { 0x50266bc0cd1797a1L,0xea17b47ef4b7af2dL,0xd6c4025c3df9483eL,\n        0x8cbb9d9fa37b18c9L },\n      { 0x91cbfd9c4d8424cfL,0xdb7048f1ab1c3506L,0x9eaf641f028206a3L,\n        0xf986f3f925bdf6ceL } },\n    /* 40 << 245 */\n    { { 0x262143b5224c08dcL,0x2bbb09b481b50c91L,0xc16ed709aca8c84fL,\n        0xa6210d9db2850ca8L },\n      { 0x6d8df67a09cb54d6L,0x91eef6e0500919a4L,0x90f613810f132857L,\n        0x9acede47f8d5028bL } },\n    /* 41 << 245 */\n    { { 0x844d1b7190b771c3L,0x563b71e4ba6426beL,0x2efa2e83bdb802ffL,\n        0x3410cbabab5b4a41L },\n      { 0x555b2d2630da84ddL,0xd0711ae9ee1cc29aL,0xcf3e8c602f547792L,\n        0x03d7d5dedc678b35L } },\n    /* 42 << 245 */\n    { { 0x071a2fa8ced806b8L,0x222e6134697f1478L,0xdc16fd5dabfcdbbfL,\n        0x44912ebf121b53b8L },\n      { 0xac9436742496c27cL,0x8ea3176c1ffc26b0L,0xb6e224ac13debf2cL,\n        0x524cc235f372a832L } },\n    /* 43 << 245 */\n    { { 0xd706e1d89f6f1b18L,0x2552f00544cce35bL,0x8c8326c2a88e31fcL,\n        0xb5468b2cf9552047L },\n      { 0xce683e883ff90f2bL,0x77947bdf2f0a5423L,0xd0a1b28bed56e328L,\n        0xaee35253c20134acL } },\n    /* 44 << 245 */\n    { { 0x7e98367d3567962fL,0x379ed61f8188bffbL,0x73bba348faf130a1L,\n        0x6c1f75e1904ed734L },\n      { 0x189566423b4a79fcL,0xf20bc83d54ef4493L,0x836d425d9111eca1L,\n        0xe5b5c318009a8dcfL } },\n    /* 45 << 245 */\n    { { 0x3360b25d13221bc5L,0x707baad26b3eeaf7L,0xd7279ed8743a95a1L,\n        0x7450a875969e809fL },\n      { 0x32b6bd53e5d0338fL,0x1e77f7af2b883bbcL,0x90da12cc1063ecd0L,\n        0xe2697b58c315be47L } },\n    /* 46 << 245 */\n    { { 0x2771a5bdda85d534L,0x53e78c1fff980eeaL,0xadf1cf84900385e7L,\n        0x7d3b14f6c9387b62L },\n      { 0x170e74b0cb8f2bd2L,0x2d50b486827fa993L,0xcdbe8c9af6f32babL,\n        0x55e906b0c3b93ab8L } },\n    /* 47 << 245 */\n    { { 0x747f22fc8fe280d1L,0xcd8e0de5b2e114abL,0x5ab7dbebe10b68b0L,\n        0x9dc63a9ca480d4b2L },\n      { 0x78d4bc3b4be1495fL,0x25eb3db89359122dL,0x3f8ac05b0809cbdcL,\n        0xbf4187bbd37c702fL } },\n    /* 48 << 245 */\n    { { 0x84cea0691416a6a5L,0x8f860c7943ef881cL,0x41311f8a38038a5dL,\n        0xe78c2ec0fc612067L },\n      { 0x494d2e815ad73581L,0xb4cc9e0059604097L,0xff558aecf3612cbaL,\n        0x35beef7a9e36c39eL } },\n    /* 49 << 245 */\n    { { 0x1845c7cfdbcf41b9L,0x5703662aaea997c0L,0x8b925afee402f6d8L,\n        0xd0a1b1ae4dd72162L },\n      { 0x9f47b37503c41c4bL,0xa023829b0391d042L,0x5f5045c3503b8b0aL,\n        0x123c268898c010e5L } },\n    /* 50 << 245 */\n    { { 0x324ec0cc36ba06eeL,0xface31153dd2cc0cL,0xb364f3bef333e91fL,\n        0xef8aff7328e832b0L },\n      { 0x1e9bad042d05841bL,0x42f0e3df356a21e2L,0xa3270bcb4add627eL,\n        0xb09a8158d322e711L } },\n    /* 51 << 245 */\n    { { 0x86e326a10fee104aL,0xad7788f83703f65dL,0x7e76543047bc4833L,\n        0x6cee582b2b9b893aL },\n      { 0x9cd2a167e8f55a7bL,0xefbee3c6d9e4190dL,0x33ee7185d40c2e9dL,\n        0x844cc9c5a380b548L } },\n    /* 52 << 245 */\n    { { 0x323f8ecd66926e04L,0x0001e38f8110c1baL,0x8dbcac12fc6a7f07L,\n        0xd65e1d580cec0827L },\n      { 0xd2cd4141be76ca2dL,0x7895cf5ce892f33aL,0x956d230d367139d2L,\n        0xa91abd3ed012c4c1L } },\n    /* 53 << 245 */\n    { { 0x34fa488387eb36bfL,0xc5f07102914b8fb4L,0x90f0e579adb9c95fL,\n        0xfe6ea8cb28888195L },\n      { 0x7b9b5065edfa9284L,0x6c510bd22b8c8d65L,0xd7b8ebefcbe8aafdL,\n        0xedb3af9896b1da07L } },\n    /* 54 << 245 */\n    { { 0x28ff779d6295d426L,0x0c4f6ac73fa3ad7bL,0xec44d0548b8e2604L,\n        0x9b32a66d8b0050e1L },\n      { 0x1f943366f0476ce2L,0x7554d953a602c7b4L,0xbe35aca6524f2809L,\n        0xb6881229fd4edbeaL } },\n    /* 55 << 245 */\n    { { 0xe8cd0c8f508efb63L,0x9eb5b5c86abcefc7L,0xf5621f5fb441ab4fL,\n        0x79e6c046b76a2b22L },\n      { 0x74a4792ce37a1f69L,0xcbd252cb03542b60L,0x785f65d5b3c20bd3L,\n        0x8dea61434fabc60cL } },\n    /* 56 << 245 */\n    { { 0x45e21446de673629L,0x57f7aa1e703c2d21L,0xa0e99b7f98c868c7L,\n        0x4e42f66d8b641676L },\n      { 0x602884dc91077896L,0xa0d690cfc2c9885bL,0xfeb4da333b9a5187L,\n        0x5f789598153c87eeL } },\n    /* 57 << 245 */\n    { { 0x2192dd4752b16dbaL,0xdeefc0e63524c1b1L,0x465ea76ee4383693L,\n        0x79401711361b8d98L },\n      { 0xa5f9ace9f21a15cbL,0x73d26163efee9aebL,0xcca844b3e677016cL,\n        0x6c122b0757eaee06L } },\n    /* 58 << 245 */\n    { { 0xb782dce715f09690L,0x508b9b122dfc0fc9L,0x9015ab4b65d89fc6L,\n        0x5e79dab7d6d5bb0fL },\n      { 0x64f021f06c775aa2L,0xdf09d8cc37c7eca1L,0x9a761367ef2fa506L,\n        0xed4ca4765b81eec6L } },\n    /* 59 << 245 */\n    { { 0x262ede3610bbb8b5L,0x0737ce830641ada3L,0x4c94288ae9831cccL,\n        0x487fc1ce8065e635L },\n      { 0xb13d7ab3b8bb3659L,0xdea5df3e855e4120L,0xb9a1857385eb0244L,\n        0x1a1b8ea3a7cfe0a3L } },\n    /* 60 << 245 */\n    { { 0x3b83711967b0867cL,0x8d5e0d089d364520L,0x52dccc1ed930f0e3L,\n        0xefbbcec7bf20bbafL },\n      { 0x99cffcab0263ad10L,0xd8199e6dfcd18f8aL,0x64e2773fe9f10617L,\n        0x0079e8e108704848L } },\n    /* 61 << 245 */\n    { { 0x1169989f8a342283L,0x8097799ca83012e6L,0xece966cb8a6a9001L,\n        0x93b3afef072ac7fcL },\n      { 0xe6893a2a2db3d5baL,0x263dc46289bf4fdcL,0x8852dfc9e0396673L,\n        0x7ac708953af362b6L } },\n    /* 62 << 245 */\n    { { 0xbb9cce4d5c2f342bL,0xbf80907ab52d7aaeL,0x97f3d3cd2161bcd0L,\n        0xb25b08340962744dL },\n      { 0xc5b18ea56c3a1ddaL,0xfe4ec7eb06c92317L,0xb787b890ad1c4afeL,\n        0xdccd9a920ede801aL } },\n    /* 63 << 245 */\n    { { 0x9ac6dddadb58da1fL,0x22bbc12fb8cae6eeL,0xc6f8bced815c4a43L,\n        0x8105a92cf96480c7L },\n      { 0x0dc3dbf37a859d51L,0xe3ec7ce63041196bL,0xd9f64b250d1067c9L,\n        0xf23213213d1f8dd8L } },\n    /* 64 << 245 */\n    { { 0x8b5c619c76497ee8L,0x5d2b0ac6c717370eL,0x98204cb64fcf68e1L,\n        0x0bdec21162bc6792L },\n      { 0x6973ccefa63b1011L,0xf9e3fa97e0de1ac5L,0x5efb693e3d0e0c8bL,\n        0x037248e9d2d4fcb4L } },\n    /* 0 << 252 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 252 */\n    { { 0x80802dc91ec34f9eL,0xd8772d3533810603L,0x3f06d66c530cb4f3L,\n        0x7be5ed0dc475c129L },\n      { 0xcb9e3c1931e82b10L,0xc63d2857c9ff6b4cL,0xb92118c692a1b45eL,\n        0x0aec44147285bbcaL } },\n    /* 2 << 252 */\n    { { 0xfc189ae71e29a3efL,0xcbe906f04c93302eL,0xd0107914ceaae10eL,\n        0xb7a23f34b68e19f8L },\n      { 0xe9d875c2efd2119dL,0x03198c6efcadc9c8L,0x65591bf64da17113L,\n        0x3cf0bbf83d443038L } },\n    /* 3 << 252 */\n    { { 0xae485bb72b724759L,0x945353e1b2d4c63aL,0x82159d07de7d6f2cL,\n        0x389caef34ec5b109L },\n      { 0x4a8ebb53db65ef14L,0x2dc2cb7edd99de43L,0x816fa3ed83f2405fL,\n        0x73429bb9c14208a3L } },\n    /* 4 << 252 */\n    { { 0xb618d590b01e6e27L,0x047e2ccde180b2dcL,0xd1b299b504aea4a9L,\n        0x412c9e1e9fa403a4L },\n      { 0x88d28a3679407552L,0x49c50136f332b8e3L,0x3a1b6fcce668de19L,\n        0x178851bc75122b97L } },\n    /* 5 << 252 */\n    { { 0xb1e13752fb85fa4cL,0xd61257ce383c8ce9L,0xd43da670d2f74daeL,\n        0xa35aa23fbf846bbbL },\n      { 0x5e74235d4421fc83L,0xf6df8ee0c363473bL,0x34d7f52a3c4aa158L,\n        0x50d05aab9bc6d22eL } },\n    /* 6 << 252 */\n    { { 0x8c56e735a64785f4L,0xbc56637b5f29cd07L,0x53b2bb803ee35067L,\n        0x50235a0fdc919270L },\n      { 0x191ab6d8f2c4aa65L,0xc34758318396023bL,0x80400ba5f0f805baL,\n        0x8881065b5ec0f80fL } },\n    /* 7 << 252 */\n    { { 0xc370e522cc1b5e83L,0xde2d4ad1860b8bfbL,0xad364df067b256dfL,\n        0x8f12502ee0138997L },\n      { 0x503fa0dc7783920aL,0xe80014adc0bc866aL,0x3f89b744d3064ba6L,\n        0x03511dcdcba5dba5L } },\n    /* 8 << 252 */\n    { { 0x197dd46d95a7b1a2L,0x9c4e7ad63c6341fbL,0x426eca29484c2eceL,\n        0x9211e489de7f4f8aL },\n      { 0x14997f6ec78ef1f4L,0x2b2c091006574586L,0x17286a6e1c3eede8L,\n        0x25f92e470f60e018L } },\n    /* 9 << 252 */\n    { { 0x805c564631890a36L,0x703ef60057feea5bL,0x389f747caf3c3030L,\n        0xe0e5daeb54dd3739L },\n      { 0xfe24a4c3c9c9f155L,0x7e4bf176b5393962L,0x37183de2af20bf29L,\n        0x4a1bd7b5f95a8c3bL } },\n    /* 10 << 252 */\n    { { 0xa83b969946191d3dL,0x281fc8dd7b87f257L,0xb18e2c1354107588L,\n        0x6372def79b2bafe8L },\n      { 0xdaf4bb480d8972caL,0x3f2dd4b756167a3fL,0x1eace32d84310cf4L,\n        0xe3bcefafe42700aaL } },\n    /* 11 << 252 */\n    { { 0x5fe5691ed785e73dL,0xa5db5ab62ea60467L,0x02e23d41dfc6514aL,\n        0x35e8048ee03c3665L },\n      { 0x3f8b118f1adaa0f8L,0x28ec3b4584ce1a5aL,0xe8cacc6e2c6646b8L,\n        0x1343d185dbd0e40fL } },\n    /* 12 << 252 */\n    { { 0xe5d7f844caaa358cL,0x1a1db7e49924182aL,0xd64cd42d9c875d9aL,\n        0xb37b515f042eeec8L },\n      { 0x4d4dd4097b165fbeL,0xfc322ed9e206eff3L,0x7dee410259b7e17eL,\n        0x55a481c08236ca00L } },\n    /* 13 << 252 */\n    { { 0x8c885312c23fc975L,0x1571580605d6297bL,0xa078868ef78edd39L,\n        0x956b31e003c45e52L },\n      { 0x470275d5ff7b33a6L,0xc8d5dc3a0c7e673fL,0x419227b47e2f2598L,\n        0x8b37b6344c14a975L } },\n    /* 14 << 252 */\n    { { 0xd0667ed68b11888cL,0x5e0e8c3e803e25dcL,0x34e5d0dcb987a24aL,\n        0x9f40ac3bae920323L },\n      { 0x5463de9534e0f63aL,0xa128bf926b6328f9L,0x491ccd7cda64f1b7L,\n        0x7ef1ec27c47bde35L } },\n    /* 15 << 252 */\n    { { 0xa857240fa36a2737L,0x35dc136663621bc1L,0x7a3a6453d4fb6897L,\n        0x80f1a439c929319dL },\n      { 0xfc18274bf8cb0ba0L,0xb0b537668078c5ebL,0xfb0d49241e01d0efL,\n        0x50d7c67d372ab09cL } },\n    /* 16 << 252 */\n    { { 0xb4e370af3aeac968L,0xe4f7fee9c4b63266L,0xb4acd4c2e3ac5664L,\n        0xf8910bd2ceb38cbfL },\n      { 0x1c3ae50cc9c0726eL,0x15309569d97b40bfL,0x70884b7ffd5a5a1bL,\n        0x3890896aef8314cdL } },\n    /* 17 << 252 */\n    { { 0x58e1515ca5618c93L,0xe665432b77d942d1L,0xb32181bfb6f767a8L,\n        0x753794e83a604110L },\n      { 0x09afeb7ce8c0dbccL,0x31e02613598673a3L,0x5d98e5577d46db00L,\n        0xfc21fb8c9d985b28L } },\n    /* 18 << 252 */\n    { { 0xc9040116b0843e0bL,0x53b1b3a869b04531L,0xdd1649f085d7d830L,\n        0xbb3bcc87cb7427e8L },\n      { 0x77261100c93dce83L,0x7e79da61a1922a2aL,0x587a2b02f3149ce8L,\n        0x147e1384de92ec83L } },\n    /* 19 << 252 */\n    { { 0x484c83d3af077f30L,0xea78f8440658b53aL,0x912076c2027aec53L,\n        0xf34714e393c8177dL },\n      { 0x37ef5d15c2376c84L,0x8315b6593d1aa783L,0x3a75c484ef852a90L,\n        0x0ba0c58a16086bd4L } },\n    /* 20 << 252 */\n    { { 0x29688d7a529a6d48L,0x9c7f250dc2f19203L,0x123042fb682e2df9L,\n        0x2b7587e7ad8121bcL },\n      { 0x30fc0233e0182a65L,0xb82ecf87e3e1128aL,0x7168286193fb098fL,\n        0x043e21ae85e9e6a7L } },\n    /* 21 << 252 */\n    { { 0xab5b49d666c834eaL,0x3be43e1847414287L,0xf40fb859219a2a47L,\n        0x0e6559e9cc58df3cL },\n      { 0xfe1dfe8e0c6615b4L,0x14abc8fd56459d70L,0x7be0fa8e05de0386L,\n        0x8e63ef68e9035c7cL } },\n    /* 22 << 252 */\n    { { 0x116401b453b31e91L,0x0cba7ad44436b4d8L,0x9151f9a0107afd66L,\n        0xafaca8d01f0ee4c4L },\n      { 0x75fe5c1d9ee9761cL,0x3497a16bf0c0588fL,0x3ee2bebd0304804cL,\n        0xa8fb9a60c2c990b9L } },\n    /* 23 << 252 */\n    { { 0xd14d32fe39251114L,0x36bf25bccac73366L,0xc9562c66dba7495cL,\n        0x324d301b46ad348bL },\n      { 0x9f46620cd670407eL,0x0ea8d4f1e3733a01L,0xd396d532b0c324e0L,\n        0x5b211a0e03c317cdL } },\n    /* 24 << 252 */\n    { { 0x090d7d205ffe7b37L,0x3b7f3efb1747d2daL,0xa2cb525fb54fc519L,\n        0x6e220932f66a971eL },\n      { 0xddc160dfb486d440L,0x7fcfec463fe13465L,0x83da7e4e76e4c151L,\n        0xd6fa48a1d8d302b5L } },\n    /* 25 << 252 */\n    { { 0xc6304f265872cd88L,0x806c1d3c278b90a1L,0x3553e725caf0bc1cL,\n        0xff59e603bb9d8d5cL },\n      { 0xa4550f327a0b85ddL,0xdec5720a93ecc217L,0x0b88b74169d62213L,\n        0x7212f2455b365955L } },\n    /* 26 << 252 */\n    { { 0x20764111b5cae787L,0x13cb7f581dfd3124L,0x2dca77da1175aefbL,\n        0xeb75466bffaae775L },\n      { 0x74d76f3bdb6cff32L,0x7440f37a61fcda9aL,0x1bb3ac92b525028bL,\n        0x20fbf8f7a1975f29L } },\n    /* 27 << 252 */\n    { { 0x982692e1df83097fL,0x28738f6c554b0800L,0xdc703717a2ce2f2fL,\n        0x7913b93c40814194L },\n      { 0x049245931fe89636L,0x7b98443ff78834a6L,0x11c6ab015114a5a1L,\n        0x60deb383ffba5f4cL } },\n    /* 28 << 252 */\n    { { 0x4caa54c601a982e6L,0x1dd35e113491cd26L,0x973c315f7cbd6b05L,\n        0xcab0077552494724L },\n      { 0x04659b1f6565e15aL,0xbf30f5298c8fb026L,0xfc21641ba8a0de37L,\n        0xe9c7a366fa5e5114L } },\n    /* 29 << 252 */\n    { { 0xdb849ca552f03ad8L,0xc7e8dbe9024e35c0L,0xa1a2bbaccfc3c789L,\n        0xbf733e7d9c26f262L },\n      { 0x882ffbf5b8444823L,0xb7224e886bf8483bL,0x53023b8b65bef640L,\n        0xaabfec91d4d5f8cdL } },\n    /* 30 << 252 */\n    { { 0xa40e1510079ea1bdL,0x1ad9addcd05d5d26L,0xdb3f2eab13e68d4fL,\n        0x1cff1ae2640f803fL },\n      { 0xe0e7b749d4cee117L,0x8e9f275b4036d909L,0xce34e31d8f4d4c38L,\n        0x22b37f69d75130fcL } },\n    /* 31 << 252 */\n    { { 0x83e0f1fdb4014604L,0xa8ce991989415078L,0x82375b7541792efeL,\n        0x4f59bf5c97d4515bL },\n      { 0xac4f324f923a277dL,0xd9bc9b7d650f3406L,0xc6fa87d18a39bc51L,\n        0x825885305ccc108fL } },\n    /* 32 << 252 */\n    { { 0x5ced3c9f82e4c634L,0x8efb83143a4464f8L,0xe706381b7a1dca25L,\n        0x6cd15a3c5a2a412bL },\n      { 0x9347a8fdbfcd8fb5L,0x31db2eef6e54cd22L,0xc4aeb11ef8d8932fL,\n        0x11e7c1ed344411afL } },\n    /* 33 << 252 */\n    { { 0x2653050cdc9a151eL,0x9edbfc083bb0a859L,0x926c81c7fd5691e7L,\n        0x9c1b23426f39019aL },\n      { 0x64a81c8b7f8474b9L,0x90657c0701761819L,0x390b333155e0375aL,\n        0xc676c626b6ebc47dL } },\n    /* 34 << 252 */\n    { { 0x51623247b7d6dee8L,0x0948d92779659313L,0x99700161e9ab35edL,\n        0x06cc32b48ddde408L },\n      { 0x6f2fd664061ef338L,0x1606fa02c202e9edL,0x55388bc1929ba99bL,\n        0xc4428c5e1e81df69L } },\n    /* 35 << 252 */\n    { { 0xce2028aef91b0b2aL,0xce870a23f03dfd3fL,0x66ec2c870affe8edL,\n        0xb205fb46284d0c00L },\n      { 0xbf5dffe744cefa48L,0xb6fc37a8a19876d7L,0xbecfa84c08b72863L,\n        0xd7205ff52576374fL } },\n    /* 36 << 252 */\n    { { 0x80330d328887de41L,0x5de0df0c869ea534L,0x13f427533c56ea17L,\n        0xeb1f6069452b1a78L },\n      { 0x50474396e30ea15cL,0x575816a1c1494125L,0xbe1ce55bfe6bb38fL,\n        0xb901a94896ae30f7L } },\n    /* 37 << 252 */\n    { { 0xe5af0f08d8fc3548L,0x5010b5d0d73bfd08L,0x993d288053fe655aL,\n        0x99f2630b1c1309fdL },\n      { 0xd8677bafb4e3b76fL,0x14e51ddcb840784bL,0x326c750cbf0092ceL,\n        0xc83d306bf528320fL } },\n    /* 38 << 252 */\n    { { 0xc445671577d4715cL,0xd30019f96b703235L,0x207ccb2ed669e986L,\n        0x57c824aff6dbfc28L },\n      { 0xf0eb532fd8f92a23L,0x4a557fd49bb98fd2L,0xa57acea7c1e6199aL,\n        0x0c6638208b94b1edL } },\n    /* 39 << 252 */\n    { { 0x9b42be8ff83a9266L,0xc7741c970101bd45L,0x95770c1107bd9cebL,\n        0x1f50250a8b2e0744L },\n      { 0xf762eec81477b654L,0xc65b900e15efe59aL,0x88c961489546a897L,\n        0x7e8025b3c30b4d7cL } },\n    /* 40 << 252 */\n    { { 0xae4065ef12045cf9L,0x6fcb2caf9ccce8bdL,0x1fa0ba4ef2cf6525L,\n        0xf683125dcb72c312L },\n      { 0xa01da4eae312410eL,0x67e286776cd8e830L,0xabd9575298fb3f07L,\n        0x05f11e11eef649a5L } },\n    /* 41 << 252 */\n    { { 0xba47faef9d3472c2L,0x3adff697c77d1345L,0x4761fa04dd15afeeL,\n        0x64f1f61ab9e69462L },\n      { 0xfa691fab9bfb9093L,0x3df8ae8fa1133dfeL,0xcd5f896758cc710dL,\n        0xfbb88d5016c7fe79L } },\n    /* 42 << 252 */\n    { { 0x8e011b4ce88c50d1L,0x7532e807a8771c4fL,0x64c78a48e2278ee4L,\n        0x0b283e833845072aL },\n      { 0x98a6f29149e69274L,0xb96e96681868b21cL,0x38f0adc2b1a8908eL,\n        0x90afcff71feb829dL } },\n    /* 43 << 252 */\n    { { 0x9915a383210b0856L,0xa5a80602def04889L,0x800e9af97c64d509L,\n        0x81382d0bb8996f6fL },\n      { 0x490eba5381927e27L,0x46c63b324af50182L,0x784c5fd9d3ad62ceL,\n        0xe4fa1870f8ae8736L } },\n    /* 44 << 252 */\n    { { 0x4ec9d0bcd7466b25L,0x84ddbe1adb235c65L,0x5e2645ee163c1688L,\n        0x570bd00e00eba747L },\n      { 0xfa51b629128bfa0fL,0x92fce1bd6c1d3b68L,0x3e7361dcb66778b1L,\n        0x9c7d249d5561d2bbL } },\n    /* 45 << 252 */\n    { { 0xa40b28bf0bbc6229L,0x1c83c05edfd91497L,0x5f9f5154f083df05L,\n        0xbac38b3ceee66c9dL },\n      { 0xf71db7e3ec0dfcfdL,0xf2ecda8e8b0a8416L,0x52fddd867812aa66L,\n        0x2896ef104e6f4272L } },\n    /* 46 << 252 */\n    { { 0xff27186a0fe9a745L,0x08249fcd49ca70dbL,0x7425a2e6441cac49L,\n        0xf4a0885aece5ff57L },\n      { 0x6e2cb7317d7ead58L,0xf96cf7d61898d104L,0xafe67c9d4f2c9a89L,\n        0x89895a501c7bf5bcL } },\n    /* 47 << 252 */\n    { { 0xdc7cb8e5573cecfaL,0x66497eaed15f03e6L,0x6bc0de693f084420L,\n        0x323b9b36acd532b0L },\n      { 0xcfed390a0115a3c1L,0x9414c40b2d65ca0eL,0x641406bd2f530c78L,\n        0x29369a44833438f2L } },\n    /* 48 << 252 */\n    { { 0x996884f5903fa271L,0xe6da0fd2b9da921eL,0xa6f2f2695db01e54L,\n        0x1ee3e9bd6876214eL },\n      { 0xa26e181ce27a9497L,0x36d254e48e215e04L,0x42f32a6c252cabcaL,\n        0x9948148780b57614L } },\n    /* 49 << 252 */\n    { { 0x4c4dfe6940d9cae1L,0x0586958011a10f09L,0xca287b573491b64bL,\n        0x77862d5d3fd4a53bL },\n      { 0xbf94856e50349126L,0x2be30bd171c5268fL,0x10393f19cbb650a6L,\n        0x639531fe778cf9fdL } },\n    /* 50 << 252 */\n    { { 0x02556a11b2935359L,0xda38aa96af8c126eL,0x47dbe6c20960167fL,\n        0x37bbabb6501901cdL },\n      { 0xb6e979e02c947778L,0xd69a51757a1a1dc6L,0xc3ed50959d9faf0cL,\n        0x4dd9c0961d5fa5f0L } },\n    /* 51 << 252 */\n    { { 0xa0c4304d64f16ea8L,0x8b1cac167e718623L,0x0b5765467c67f03eL,\n        0x559cf5adcbd88c01L },\n      { 0x074877bb0e2af19aL,0x1f717ec1a1228c92L,0x70bcb800326e8920L,\n        0xec6e2c5c4f312804L } },\n    /* 52 << 252 */\n    { { 0x426aea7d3fca4752L,0xf12c09492211f62aL,0x24beecd87be7b6b5L,\n        0xb77eaf4c36d7a27dL },\n      { 0x154c2781fda78fd3L,0x848a83b0264eeabeL,0x81287ef04ffe2bc4L,\n        0x7b6d88c6b6b6fc2aL } },\n    /* 53 << 252 */\n    { { 0x805fb947ce417d99L,0x4b93dcc38b916cc4L,0x72e65bb321273323L,\n        0xbcc1badd6ea9886eL },\n      { 0x0e2230114bc5ee85L,0xa561be74c18ee1e4L,0x762fd2d4a6bcf1f1L,\n        0x50e6a5a495231489L } },\n    /* 54 << 252 */\n    { { 0xca96001fa00b500bL,0x5c098cfc5d7dcdf5L,0xa64e2d2e8c446a85L,\n        0xbae9bcf1971f3c62L },\n      { 0x4ec226838435a2c5L,0x8ceaed6c4bad4643L,0xe9f8fb47ccccf4e3L,\n        0xbd4f3fa41ce3b21eL } },\n    /* 55 << 252 */\n    { { 0xd79fb110a3db3292L,0xe28a37dab536c66aL,0x279ce87b8e49e6a9L,\n        0x70ccfe8dfdcec8e3L },\n      { 0x2193e4e03ba464b2L,0x0f39d60eaca9a398L,0x7d7932aff82c12abL,\n        0xd8ff50ed91e7e0f7L } },\n    /* 56 << 252 */\n    { { 0xea961058fa28a7e0L,0xc726cf250bf5ec74L,0xe74d55c8db229666L,\n        0x0bd9abbfa57f5799L },\n      { 0x7479ef074dfc47b3L,0xd9c65fc30c52f91dL,0x8e0283fe36a8bde2L,\n        0xa32a8b5e7d4b7280L } },\n    /* 57 << 252 */\n    { { 0x6a677c6112e83233L,0x0fbb3512dcc9bf28L,0x562e8ea50d780f61L,\n        0x0db8b22b1dc4e89cL },\n      { 0x0a6fd1fb89be0144L,0x8c77d246ca57113bL,0x4639075dff09c91cL,\n        0x5b47b17f5060824cL } },\n    /* 58 << 252 */\n    { { 0x58aea2b016287b52L,0xa1343520d0cd8eb0L,0x6148b4d0c5d58573L,\n        0xdd2b6170291c68aeL },\n      { 0xa61b39291da3b3b7L,0x5f946d7908c4ac10L,0x4105d4a57217d583L,\n        0x5061da3d25e6de5eL } },\n    /* 59 << 252 */\n    { { 0x3113940dec1b4991L,0xf12195e136f485aeL,0xa7507fb2731a2ee0L,\n        0x95057a8e6e9e196eL },\n      { 0xa3c2c9112e130136L,0x97dfbb3633c60d15L,0xcaf3c581b300ee2bL,\n        0x77f25d90f4bac8b8L } },\n    /* 60 << 252 */\n    { { 0xdb1c4f986d840cd6L,0x471d62c0e634288cL,0x8ec2f85ecec8a161L,\n        0x41f37cbcfa6f4ae2L },\n      { 0x6793a20f4b709985L,0x7a7bd33befa8985bL,0x2c6a3fbd938e6446L,\n        0x190426192a8d47c1L } },\n    /* 61 << 252 */\n    { { 0x16848667cc36975fL,0x02acf1689d5f1dfbL,0x62d41ad4613baa94L,\n        0xb56fbb929f684670L },\n      { 0xce610d0de9e40569L,0x7b99c65f35489fefL,0x0c88ad1b3df18b97L,\n        0x81b7d9be5d0e9edbL } },\n    /* 62 << 252 */\n    { { 0xd85218c0c716cc0aL,0xf4b5ff9085691c49L,0xa4fd666bce356ac6L,\n        0x17c728954b327a7aL },\n      { 0xf93d5085da6be7deL,0xff71530e3301d34eL,0x4cd96442d8f448e8L,\n        0x9283d3312ed18ffaL } },\n    /* 63 << 252 */\n    { { 0x4d33dd992a849870L,0xa716964b41576335L,0xff5e3a9b179be0e5L,\n        0x5b9d6b1b83b13632L },\n      { 0x3b8bd7d4a52f313bL,0xc9dd95a0637a4660L,0x300359620b3e218fL,\n        0xce1481a3c7b28a3cL } },\n    /* 64 << 252 */\n    { { 0xab41b43a43228d83L,0x24ae1c304ad63f99L,0x8e525f1a46a51229L,\n        0x14af860fcd26d2b4L },\n      { 0xd6baef613f714aa1L,0xf51865adeb78795eL,0xd3e21fcee6a9d694L,\n        0x82ceb1dd8a37b527L } },\n};\n\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_add_only_4(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit tmpd[2 * 4 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* tmp;\n    sp_digit* negy;\n    int i;\n    ecc_recode v[37];\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY)\n        err = sp_ecc_point_new(heap, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, heap,\n                             DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n#else\n    tmp = tmpd;\n#endif\n    negy = tmp;\n\n    if (err == MP_OKAY) {\n        sp_256_ecc_recode_7_4(k, v);\n\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        i = 36;\n        XMEMCPY(rt->x, table[i * 65 + v[i].i].x, sizeof(table->x));\n        XMEMCPY(rt->y, table[i * 65 + v[i].i].y, sizeof(table->y));\n        rt->infinity = !v[i].i;\n        for (--i; i>=0; i--) {\n            XMEMCPY(p->x, table[i * 65 + v[i].i].x, sizeof(table->x));\n            XMEMCPY(p->y, table[i * 65 + v[i].i].y, sizeof(table->y));\n            p->infinity = !v[i].i;\n            sp_256_sub_4(negy, p256_mod, p->y);\n            sp_256_cond_copy_4(p->y, negy, 0 - v[i].neg);\n            sp_256_proj_point_add_qz1_4(rt, rt, p, tmp);\n        }\n        if (map != 0) {\n            sp_256_map_4(r, rt, tmp);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 4 * 5);\n        XFREE(tmp, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    ForceZero(tmp, sizeof(sp_digit) * 2 * 4 * 5);\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return MP_OKAY;\n}\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_4(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_add_only_4(r, NULL, p256_table,\n                                      k, map, heap);\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[4];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 4, km);\n\n            err = sp_256_ecc_mulmod_base_4(point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_4(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                                        defined(HAVE_ECC_VERIFY)\n/* Returns 1 if the number of zero.\n * Implementation is constant time.\n *\n * a  Number to check.\n * returns 1 if the number is zero and 0 otherwise.\n */\nstatic int sp_256_iszero_4(const sp_digit* a)\n{\n    return (a[0] | a[1] | a[2] | a[3]) == 0;\n}\n\n#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\n/* Add 1 to a. (a = a + 1)\n *\n * a  A single precision integer.\n */\nstatic void sp_256_add_one_4(sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"ldp\tx1, x2,  [%[a], 0]\\n\\t\"\n        \"ldp\tx3, x4,  [%[a], 16]\\n\\t\"\n        \"adds\tx1, x1, #1\\n\\t\"\n        \"adcs\tx2, x2, xzr\\n\\t\"\n        \"adcs\tx3, x3, xzr\\n\\t\"\n        \"adcs\tx4, x4, xzr\\n\\t\"\n        \"stp\tx1, x2, [%[a], 0]\\n\\t\"\n        \"stp\tx3, x4, [%[a], 16]\\n\\t\"\n        :\n        : [a] \"r\" (a)\n        : \"memory\", \"x1\", \"x2\", \"x3\", \"x4\"\n    );\n}\n\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 56U) {\n            r[j] &= 0xffffffffffffffffl;\n            s = 64U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Generates a scalar that is in the range 1..order-1.\n *\n * rng  Random number generator.\n * k    Scalar value.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nstatic int sp_256_ecc_gen_k_4(WC_RNG* rng, sp_digit* k)\n{\n    int err;\n    byte buf[32];\n\n    do {\n        err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));\n        if (err == 0) {\n            sp_256_from_bin(k, 4, buf, (int)sizeof(buf));\n            if (sp_256_cmp_4(k, p256_order2) < 0) {\n                sp_256_add_one_4(k);\n                break;\n            }\n        }\n    }\n    while (err == 0);\n\n    return err;\n}\n\n/* Makes a random EC key pair.\n *\n * rng   Random number generator.\n * priv  Generated private value.\n * pub   Generated public point.\n * heap  Heap to use for allocation.\n * returns ECC_INF_E when the point does not have the correct order, RNG\n * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[4];\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point inf;\n#endif\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point* infinity;\n#endif\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, inf, infinity);\n    }\n#endif\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_ecc_gen_k_4(rng, k);\n    }\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_base_4(point, k, 1, NULL);\n    }\n\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_4(infinity, point, p256_order, 1, NULL);\n    }\n    if (err == MP_OKAY) {\n        if ((sp_256_iszero_4(point->x) == 0) || (sp_256_iszero_4(point->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(k, priv);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_4(point, pub);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_ecc_point_free(infinity, 1, heap);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n\n#ifdef HAVE_ECC_DHE\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 32\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_256_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 256 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<4 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 64) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 64);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n/* Multiply the point by the scalar and serialize the X ordinate.\n * The number is 0 padded to maximum size on output.\n *\n * priv    Scalar to multiply the point by.\n * pub     Point to multiply.\n * out     Buffer to hold X ordinate.\n * outLen  On entry, size of the buffer in bytes.\n *         On exit, length of data in buffer in bytes.\n * heap    Heap to use for allocation.\n * returns BUFFER_E if the buffer is to small for output size,\n * MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out,\n                          word32* outLen, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[4];\n#endif\n    sp_point* point = NULL;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    if (*outLen < 32U) {\n        err = BUFFER_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p, point);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 4, priv);\n        sp_256_point_from_ecc_point_4(point, pub);\n            err = sp_256_ecc_mulmod_4(point, point, k, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        sp_256_to_bin(point->x, out);\n        *outLen = 32;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_DHE */\n\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic sp_digit sp_256_add_4(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx3, x4, [%[a], 0]\\n\\t\"\n        \"ldp\tx5, x6, [%[a], 16]\\n\\t\"\n        \"ldp\tx7, x8, [%[b], 0]\\n\\t\"\n        \"ldp\tx9, x10, [%[b], 16]\\n\\t\"\n        \"adds\tx3, x3, x7\\n\\t\"\n        \"adcs\tx4, x4, x8\\n\\t\"\n        \"adcs\tx5, x5, x9\\n\\t\"\n        \"adcs\tx6, x6, x10\\n\\t\"\n        \"stp\tx3, x4, [%[r], 0]\\n\\t\"\n        \"stp\tx5, x6, [%[r], 16]\\n\\t\"\n        \"cset\t%[c], cs\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\"\n    );\n\n    return c;\n}\n\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_256_mul_4(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_digit tmp[8];\n\n    __asm__ __volatile__ (\n        \"mov\tx5, 0\\n\\t\"\n        \"mov\tx6, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"mov\tx8, 0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tx3, x5, 24\\n\\t\"\n        \"csel\tx3, xzr, x3, cc\\n\\t\"\n        \"sub\tx4, x5, x3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"ldr\tx11, [%[b], x4]\\n\\t\"\n        \"mul\tx9, x10, x11\\n\\t\"\n        \"umulh\tx10, x10, x11\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"add\tx3, x3, #8\\n\\t\"\n        \"sub\tx4, x4, #8\\n\\t\"\n        \"cmp\tx3, 32\\n\\t\"\n        \"b.eq\t3f\\n\\t\"\n        \"cmp\tx3, x5\\n\\t\"\n        \"b.le\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        \"mov\tx6, x7\\n\\t\"\n        \"mov\tx7, x8\\n\\t\"\n        \"mov\tx8, #0\\n\\t\"\n        \"add\tx5, x5, #8\\n\\t\"\n        \"cmp\tx5, 48\\n\\t\"\n        \"b.le\t1b\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n#else\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nstatic void sp_256_mul_4(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_digit tmp[4];\n\n    __asm__ __volatile__ (\n        \"ldp\tx8, x9, [%[a], 0]\\n\\t\"\n        \"ldp\tx10, x11, [%[a], 16]\\n\\t\"\n        \"ldp\tx12, x13, [%[b], 0]\\n\\t\"\n        \"ldp\tx14, x15, [%[b], 16]\\n\\t\"\n        \"#  A[0] * B[0]\\n\\t\"\n        \"mul\tx3, x8, x12\\n\\t\"\n        \"umulh\tx4, x8, x12\\n\\t\"\n        \"str\tx3, [%[tmp]]\\n\\t\"\n        \"#  A[0] * B[1]\\n\\t\"\n        \"mul\tx6, x8, x13\\n\\t\"\n        \"umulh\tx7, x8, x13\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adc\tx5, xzr, x7\\n\\t\"\n        \"#  A[1] * B[0]\\n\\t\"\n        \"mul\tx6, x9, x12\\n\\t\"\n        \"umulh\tx7, x9, x12\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 8]\\n\\t\"\n        \"#  A[0] * B[2]\\n\\t\"\n        \"mul\tx6, x8, x14\\n\\t\"\n        \"umulh\tx7, x8, x14\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[1]\\n\\t\"\n        \"mul\tx6, x9, x13\\n\\t\"\n        \"umulh\tx7, x9, x13\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[2] * B[0]\\n\\t\"\n        \"mul\tx6, x10, x12\\n\\t\"\n        \"umulh\tx7, x10, x12\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[tmp], 16]\\n\\t\"\n        \"#  A[0] * B[3]\\n\\t\"\n        \"mul\tx6, x8, x15\\n\\t\"\n        \"umulh\tx7, x8, x15\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, xzr, xzr\\n\\t\"\n        \"#  A[1] * B[2]\\n\\t\"\n        \"mul\tx6, x9, x14\\n\\t\"\n        \"umulh\tx7, x9, x14\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[2] * B[1]\\n\\t\"\n        \"mul\tx6, x10, x13\\n\\t\"\n        \"umulh\tx7, x10, x13\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"#  A[3] * B[0]\\n\\t\"\n        \"mul\tx6, x11, x12\\n\\t\"\n        \"umulh\tx7, x11, x12\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adcs\tx4, x4, x7\\n\\t\"\n        \"adc\tx5, x5, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 24]\\n\\t\"\n        \"#  A[1] * B[3]\\n\\t\"\n        \"mul\tx6, x9, x15\\n\\t\"\n        \"umulh\tx7, x9, x15\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"#  A[2] * B[2]\\n\\t\"\n        \"mul\tx6, x10, x14\\n\\t\"\n        \"umulh\tx7, x10, x14\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[3] * B[1]\\n\\t\"\n        \"mul\tx6, x11, x13\\n\\t\"\n        \"umulh\tx7, x11, x13\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 32]\\n\\t\"\n        \"#  A[2] * B[3]\\n\\t\"\n        \"mul\tx6, x10, x15\\n\\t\"\n        \"umulh\tx7, x10, x15\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"#  A[3] * B[2]\\n\\t\"\n        \"mul\tx6, x11, x14\\n\\t\"\n        \"umulh\tx7, x11, x14\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx5, [%[r], 40]\\n\\t\"\n        \"#  A[3] * B[3]\\n\\t\"\n        \"mul\tx6, x11, x15\\n\\t\"\n        \"umulh\tx7, x11, x15\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"stp\tx3, x4, [%[r], 48]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [tmp] \"r\" (tmp)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x8\", \"x9\", \"x10\", \"x11\", \"x12\", \"x13\", \"x14\", \"x15\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer and result.\n * b  A single precision integer.\n */\nstatic sp_digit sp_256_sub_in_place_4(sp_digit* a, const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldp\tx2, x3, [%[a], 0]\\n\\t\"\n        \"ldp\tx4, x5, [%[a], 16]\\n\\t\"\n        \"ldp\tx6, x7, [%[b], 0]\\n\\t\"\n        \"ldp\tx8, x9, [%[b], 16]\\n\\t\"\n        \"subs\tx2, x2, x6\\n\\t\"\n        \"sbcs\tx3, x3, x7\\n\\t\"\n        \"sbcs\tx4, x4, x8\\n\\t\"\n        \"sbcs\tx5, x5, x9\\n\\t\"\n        \"stp\tx2, x3, [%[a], 0]\\n\\t\"\n        \"stp\tx4, x5, [%[a], 16]\\n\\t\"\n        \"csetm\t%[c], cc\\n\\t\"\n        : [c] \"+r\" (c)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\"\n    );\n\n    return c;\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nstatic void sp_256_mul_d_4(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n    __asm__ __volatile__ (\n        \"# A[0] * B\\n\\t\"\n        \"ldr\tx8, [%[a]]\\n\\t\"\n        \"mul\tx3, %[b], x8\\n\\t\"\n        \"umulh\tx4, %[b], x8\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"str\tx3, [%[r]]\\n\\t\"\n        \"# A[1] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 8]\\n\\t\"\n        \"mov\t\tx3, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx4, x4, x6\\n\\t\"\n        \"adcs\tx5, x5, x7\\n\\t\"\n        \"adc\t\tx3, xzr, xzr\\n\\t\"\n        \"str\t\tx4, [%[r], 8]\\n\\t\"\n        \"# A[2] * B\\n\\t\"\n        \"ldr\t\tx8, [%[a], 16]\\n\\t\"\n        \"mov\t\tx4, 0\\n\\t\"\n        \"mul\t\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx5, x5, x6\\n\\t\"\n        \"adcs\tx3, x3, x7\\n\\t\"\n        \"adc\t\tx4, xzr, xzr\\n\\t\"\n        \"str\t\tx5, [%[r], 16]\\n\\t\"\n        \"# A[3] * B\\n\\t\"\n        \"ldr\tx8, [%[a], 24]\\n\\t\"\n        \"mul\tx6, %[b], x8\\n\\t\"\n        \"umulh\tx7, %[b], x8\\n\\t\"\n        \"adds\tx3, x3, x6\\n\\t\"\n        \"adc\tx4, x4, x7\\n\\t\"\n        \"str\tx3, [%[r], 24]\\n\\t\"\n        \"str\tx4, [%[r], 32]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\"\n    );\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n */\nstatic sp_digit div_256_word_4(sp_digit d1, sp_digit d0, sp_digit div)\n{\n    sp_digit r;\n\n    __asm__ __volatile__ (\n        \"lsr\tx5, %[div], 32\\n\\t\"\n        \"add\tx5, x5, 1\\n\\t\"\n\n        \"udiv\tx3, %[d1], x5\\n\\t\"\n        \"lsl\tx6, x3, 32\\n\\t\"\n        \"mul\tx4, %[div], x6\\n\\t\"\n        \"umulh\tx3, %[div], x6\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"udiv\tx3, %[d1], x5\\n\\t\"\n        \"lsl\tx3, x3, 32\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"lsl\tx3, %[d1], 32\\n\\t\"\n        \"orr\tx3, x3, %[d0], lsr 32\\n\\t\"\n\n        \"udiv\tx3, x3, x5\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"lsl\tx3, %[d1], 32\\n\\t\"\n        \"orr\tx3, x3, %[d0], lsr 32\\n\\t\"\n\n        \"udiv\tx3, x3, x5\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx4, %[div], x3\\n\\t\"\n        \"umulh\tx3, %[div], x3\\n\\t\"\n        \"subs\t%[d0], %[d0], x4\\n\\t\"\n        \"sbc\t%[d1], %[d1], x3\\n\\t\"\n\n        \"udiv\tx3, %[d0], %[div]\\n\\t\"\n        \"add\tx6, x6, x3\\n\\t\"\n        \"mul\tx3, %[div], x3\\n\\t\"\n        \"sub\t%[d0], %[d0], x3\\n\\t\"\n        \"mov\t%[r], x6\\n\\t\"\n\n        : [r] \"=r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"x3\", \"x4\", \"x5\", \"x6\"\n    );\n\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_256_mask_4(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<4; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    r[0] = a[0] & m;\n    r[1] = a[1] & m;\n    r[2] = a[2] & m;\n    r[3] = a[3] & m;\n#endif\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_256_div_4(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[8], t2[5];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[3];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 4);\n    for (i=3; i>=0; i--) {\n        r1 = div_256_word_4(t1[4 + i], t1[4 + i - 1], div);\n\n        sp_256_mul_d_4(t2, d, r1);\n        t1[4 + i] += sp_256_sub_in_place_4(&t1[i], t2);\n        t1[4 + i] -= t2[4];\n        sp_256_mask_4(t2, d, t1[4 + i]);\n        t1[4 + i] += sp_256_add_4(&t1[i], &t1[i], t2);\n        sp_256_mask_4(t2, d, t1[4 + i]);\n        t1[4 + i] += sp_256_add_4(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_256_cmp_4(t1, d) >= 0;\n    sp_256_cond_sub_4(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_256_mod_4(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_256_div_4(a, m, NULL, r);\n}\n\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#ifdef WOLFSSL_SP_SMALL\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_256_sqr_4(sp_digit* r, const sp_digit* a)\n{\n    sp_digit tmp[8];\n\n    __asm__ __volatile__ (\n        \"mov\tx6, 0\\n\\t\"\n        \"mov\tx7, 0\\n\\t\"\n        \"mov\tx8, 0\\n\\t\"\n        \"mov\tx5, 0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"subs\tx3, x5, 24\\n\\t\"\n        \"csel\tx3, xzr, x3, cc\\n\\t\"\n        \"sub\tx4, x5, x3\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tx4, x3\\n\\t\"\n        \"b.eq\t4f\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"ldr\tx11, [%[a], x4]\\n\\t\"\n        \"mul\tx9, x10, x11\\n\\t\"\n        \"umulh\tx10, x10, x11\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"b.al\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tx10, [%[a], x3]\\n\\t\"\n        \"mul\tx9, x10, x10\\n\\t\"\n        \"umulh\tx10, x10, x10\\n\\t\"\n        \"adds\tx6, x6, x9\\n\\t\"\n        \"adcs\tx7, x7, x10\\n\\t\"\n        \"adc\tx8, x8, xzr\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\tx3, x3, #8\\n\\t\"\n        \"sub\tx4, x4, #8\\n\\t\"\n        \"cmp\tx3, 32\\n\\t\"\n        \"b.eq\t3f\\n\\t\"\n        \"cmp\tx3, x4\\n\\t\"\n        \"b.gt\t3f\\n\\t\"\n        \"cmp\tx3, x5\\n\\t\"\n        \"b.le\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        \"mov\tx6, x7\\n\\t\"\n        \"mov\tx7, x8\\n\\t\"\n        \"mov\tx8, #0\\n\\t\"\n        \"add\tx5, x5, #8\\n\\t\"\n        \"cmp\tx5, 48\\n\\t\"\n        \"b.le\t1b\\n\\t\"\n        \"str\tx6, [%[r], x5]\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a)\n        : \"memory\", \"x3\", \"x4\", \"x5\", \"x6\", \"x7\", \"x8\", \"x9\", \"x10\", \"x11\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n#else\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nstatic void sp_256_sqr_4(sp_digit* r, const sp_digit* a)\n{\n    sp_digit tmp[4];\n\n    __asm__ __volatile__ (\n        \"ldp\tx10, x11, [%[a], 0]\\n\\t\"\n        \"ldp\tx12, x13, [%[a], 16]\\n\\t\"\n        \"#  A[0] * A[0]\\n\\t\"\n        \"mul\tx2, x10, x10\\n\\t\"\n        \"umulh\tx3, x10, x10\\n\\t\"\n        \"str\tx2, [%[tmp]]\\n\\t\"\n        \"mov\tx4, 0\\n\\t\"\n        \"#  A[0] * A[1]\\n\\t\"\n        \"mul\tx8, x10, x11\\n\\t\"\n        \"umulh\tx9, x10, x11\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, xzr, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"str\tx3, [%[tmp], 8]\\n\\t\"\n        \"#  A[0] * A[2]\\n\\t\"\n        \"mul\tx8, x10, x12\\n\\t\"\n        \"umulh\tx9, x10, x12\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"#  A[1] * A[1]\\n\\t\"\n        \"mul\tx8, x11, x11\\n\\t\"\n        \"umulh\tx9, x11, x11\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[tmp], 16]\\n\\t\"\n        \"#  A[0] * A[3]\\n\\t\"\n        \"mul\tx8, x10, x13\\n\\t\"\n        \"umulh\tx9, x10, x13\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, xzr, xzr\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"#  A[1] * A[2]\\n\\t\"\n        \"mul\tx8, x11, x12\\n\\t\"\n        \"umulh\tx9, x11, x12\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adcs\tx3, x3, x9\\n\\t\"\n        \"adc\tx4, x4, xzr\\n\\t\"\n        \"str\tx2, [%[tmp], 24]\\n\\t\"\n        \"#  A[1] * A[3]\\n\\t\"\n        \"mul\tx8, x11, x13\\n\\t\"\n        \"umulh\tx9, x11, x13\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, xzr, xzr\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"#  A[2] * A[2]\\n\\t\"\n        \"mul\tx8, x12, x12\\n\\t\"\n        \"umulh\tx9, x12, x12\\n\\t\"\n        \"adds\tx3, x3, x8\\n\\t\"\n        \"adcs\tx4, x4, x9\\n\\t\"\n        \"adc\tx2, x2, xzr\\n\\t\"\n        \"str\tx3, [%[r], 32]\\n\\t\"\n        \"#  A[2] * A[3]\\n\\t\"\n        \"mul\tx8, x12, x13\\n\\t\"\n        \"umulh\tx9, x12, x13\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, xzr, xzr\\n\\t\"\n        \"adds\tx4, x4, x8\\n\\t\"\n        \"adcs\tx2, x2, x9\\n\\t\"\n        \"adc\tx3, x3, xzr\\n\\t\"\n        \"str\tx4, [%[r], 40]\\n\\t\"\n        \"#  A[3] * A[3]\\n\\t\"\n        \"mul\tx8, x13, x13\\n\\t\"\n        \"umulh\tx9, x13, x13\\n\\t\"\n        \"adds\tx2, x2, x8\\n\\t\"\n        \"adc\tx3, x3, x9\\n\\t\"\n        \"stp\tx2, x3, [%[r], 48]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [tmp] \"r\" (tmp)\n        : \"memory\", \"x2\", \"x3\", \"x4\", \"x8\", \"x9\", \"x10\", \"x5\", \"x6\", \"x7\", \"x10\", \"x11\", \"x12\", \"x13\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Order-2 for the P256 curve. */\nstatic const uint64_t p256_order_2[4] = {\n    0xf3b9cac2fc63254fU,0xbce6faada7179e84U,0xffffffffffffffffU,\n    0xffffffff00000000U\n};\n#else\n/* The low half of the order-2 of the P256 curve. */\nstatic const uint64_t p256_order_low[2] = {\n    0xf3b9cac2fc63254fU,0xbce6faada7179e84U\n};\n#endif /* WOLFSSL_SP_SMALL */\n\n/* Multiply two number mod the order of P256 curve. (r = a * b mod order)\n *\n * r  Result of the multiplication.\n * a  First operand of the multiplication.\n * b  Second operand of the multiplication.\n */\nstatic void sp_256_mont_mul_order_4(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_256_mul_4(r, a, b);\n    sp_256_mont_reduce_order_4(r, p256_order, p256_mp_order);\n}\n\n/* Square number mod the order of P256 curve. (r = a * a mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_order_4(sp_digit* r, const sp_digit* a)\n{\n    sp_256_sqr_4(r, a);\n    sp_256_mont_reduce_order_4(r, p256_order, p256_mp_order);\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Square number mod the order of P256 curve a number of times.\n * (r = a ^ n mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_n_order_4(sp_digit* r, const sp_digit* a, int n)\n{\n    int i;\n\n    sp_256_mont_sqr_order_4(r, a);\n    for (i=1; i<n; i++) {\n        sp_256_mont_sqr_order_4(r, r);\n    }\n}\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the order of the P256 curve.\n * (r = 1 / a mod order)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_order_4(sp_digit* r, const sp_digit* a,\n        sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 4);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_order_4(t, t);\n        if ((p256_order_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_4(t, t, a);\n        }\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 4U);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 4;\n    sp_digit* t3 = td + 4 * 4;\n    int i;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_order_4(t, a);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_order_4(t, t, a);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_order_4(t2, t, 2);\n    /* t3= a^f = t2 * t */\n    sp_256_mont_mul_order_4(t3, t2, t);\n    /* t2= a^f0 = t3 ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_order_4(t2, t3, 4);\n    /* t = a^ff = t2 * t3 */\n    sp_256_mont_mul_order_4(t, t2, t3);\n    /* t3= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_order_4(t2, t, 8);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_order_4(t, t2, t);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_order_4(t2, t, 16);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_order_4(t, t2, t);\n    /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64  */\n    sp_256_mont_sqr_n_order_4(t2, t, 64);\n    /* t2= a^ffffffff00000000ffffffff = t2 * t */\n    sp_256_mont_mul_order_4(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_order_4(t2, t2, 32);\n    /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_order_4(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6 */\n    for (i=127; i>=112; i--) {\n        sp_256_mont_sqr_order_4(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_4(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6f */\n    sp_256_mont_sqr_n_order_4(t2, t2, 4);\n    sp_256_mont_mul_order_4(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */\n    for (i=107; i>=64; i--) {\n        sp_256_mont_sqr_order_4(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_4(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */\n    sp_256_mont_sqr_n_order_4(t2, t2, 4);\n    sp_256_mont_mul_order_4(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */\n    for (i=59; i>=32; i--) {\n        sp_256_mont_sqr_order_4(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_4(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */\n    sp_256_mont_sqr_n_order_4(t2, t2, 4);\n    sp_256_mont_mul_order_4(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */\n    for (i=27; i>=0; i--) {\n        sp_256_mont_sqr_order_4(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_4(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */\n    sp_256_mont_sqr_n_order_4(t2, t2, 4);\n    /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */\n    sp_256_mont_mul_order_4(r, t2, t3);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\n#ifdef HAVE_ECC_SIGN\n#ifndef SP_ECC_MAX_SIG_GEN\n#define SP_ECC_MAX_SIG_GEN  64\n#endif\n\n/* Sign the hash using the private key.\n *   e = [hash, 256 bits] from binary\n *   r = (k.G)->x mod order\n *   s = (r * x + e) / k mod order\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,\n                    mp_int* rm, mp_int* sm, mp_int* km, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit ed[2*4];\n    sp_digit xd[2*4];\n    sp_digit kd[2*4];\n    sp_digit rd[2*4];\n    sp_digit td[3 * 2*4];\n    sp_point p;\n#endif\n    sp_digit* e = NULL;\n    sp_digit* x = NULL;\n    sp_digit* k = NULL;\n    sp_digit* r = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* point = NULL;\n    sp_digit carry;\n    sp_digit* s = NULL;\n    sp_digit* kInv = NULL;\n    int err = MP_OKAY;\n    int64_t c;\n    int i;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        e = d + 0 * 4;\n        x = d + 2 * 4;\n        k = d + 4 * 4;\n        r = d + 6 * 4;\n        tmp = d + 8 * 4;\n#else\n        e = ed;\n        x = xd;\n        k = kd;\n        r = rd;\n        tmp = td;\n#endif\n        s = e;\n        kInv = k;\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(e, 4, hash, (int)hashLen);\n    }\n\n    for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {\n        sp_256_from_mp(x, 4, priv);\n\n        /* New random point. */\n        if (km == NULL || mp_iszero(km)) {\n            err = sp_256_ecc_gen_k_4(rng, k);\n        }\n        else {\n            sp_256_from_mp(k, 4, km);\n            mp_zero(km);\n        }\n        if (err == MP_OKAY) {\n                err = sp_256_ecc_mulmod_base_4(point, k, 1, NULL);\n        }\n\n        if (err == MP_OKAY) {\n            /* r = point->x mod order */\n            XMEMCPY(r, point->x, sizeof(sp_digit) * 4U);\n            sp_256_norm_4(r);\n            c = sp_256_cmp_4(r, p256_order);\n            sp_256_cond_sub_4(r, r, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_4(r);\n\n            /* Conv k to Montgomery form (mod order) */\n                sp_256_mul_4(k, k, p256_norm_order);\n            err = sp_256_mod_4(k, k, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_4(k);\n            /* kInv = 1/k mod order */\n                sp_256_mont_inv_order_4(kInv, k, tmp);\n            sp_256_norm_4(kInv);\n\n            /* s = r * x + e */\n                sp_256_mul_4(x, x, r);\n            err = sp_256_mod_4(x, x, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_4(x);\n            carry = sp_256_add_4(s, e, x);\n            sp_256_cond_sub_4(s, s, p256_order, 0 - carry);\n            sp_256_norm_4(s);\n            c = sp_256_cmp_4(s, p256_order);\n            sp_256_cond_sub_4(s, s, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_4(s);\n\n            /* s = s * k^-1 mod order */\n                sp_256_mont_mul_order_4(s, s, kInv);\n            sp_256_norm_4(s);\n\n            /* Check that signature is usable. */\n            if (sp_256_iszero_4(s) == 0) {\n                break;\n            }\n        }\n    }\n\n    if (i == 0) {\n        err = RNG_FAILURE_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(r, rm);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(s, sm);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XMEMSET(d, 0, sizeof(sp_digit) * 8 * 4);\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    XMEMSET(e, 0, sizeof(sp_digit) * 2U * 4U);\n    XMEMSET(x, 0, sizeof(sp_digit) * 2U * 4U);\n    XMEMSET(k, 0, sizeof(sp_digit) * 2U * 4U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 4U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 4U);\n    XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 4U);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_SIGN */\n\n#ifdef HAVE_ECC_VERIFY\n/* Verify the signature values with the hash and public key.\n *   e = Truncate(hash, 256)\n *   u1 = e/s mod order\n *   u2 = r/s mod order\n *   r == (u1.G + u2.Q)->x mod order\n * Optimization: Leave point in projective form.\n *   (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')\n *   (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,\n    mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit u1d[2*4];\n    sp_digit u2d[2*4];\n    sp_digit sd[2*4];\n    sp_digit tmpd[2*4 * 5];\n    sp_point p1d;\n    sp_point p2d;\n#endif\n    sp_digit* u1 = NULL;\n    sp_digit* u2 = NULL;\n    sp_digit* s = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* p1;\n    sp_point* p2 = NULL;\n    sp_digit carry;\n    int64_t c;\n    int err;\n\n    err = sp_ecc_point_new(heap, p1d, p1);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p2d, p2);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        u1  = d + 0 * 4;\n        u2  = d + 2 * 4;\n        s   = d + 4 * 4;\n        tmp = d + 6 * 4;\n#else\n        u1 = u1d;\n        u2 = u2d;\n        s  = sd;\n        tmp = tmpd;\n#endif\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(u1, 4, hash, (int)hashLen);\n        sp_256_from_mp(u2, 4, r);\n        sp_256_from_mp(s, 4, sm);\n        sp_256_from_mp(p2->x, 4, pX);\n        sp_256_from_mp(p2->y, 4, pY);\n        sp_256_from_mp(p2->z, 4, pZ);\n\n        {\n            sp_256_mul_4(s, s, p256_norm_order);\n        }\n        err = sp_256_mod_4(s, s, p256_order);\n    }\n    if (err == MP_OKAY) {\n        sp_256_norm_4(s);\n        {\n            sp_256_mont_inv_order_4(s, s, tmp);\n            sp_256_mont_mul_order_4(u1, u1, s);\n            sp_256_mont_mul_order_4(u2, u2, s);\n        }\n\n            err = sp_256_ecc_mulmod_base_4(p1, u1, 0, heap);\n    }\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_4(p2, p2, u2, 0, heap);\n    }\n\n    if (err == MP_OKAY) {\n        {\n            sp_256_proj_point_add_4(p1, p1, p2, tmp);\n            if (sp_256_iszero_4(p1->z)) {\n                if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) {\n                    sp_256_proj_point_dbl_4(p1, p2, tmp);\n                }\n                else {\n                    /* Y ordinate is not used from here - don't set. */\n                    p1->x[0] = 0;\n                    p1->x[1] = 0;\n                    p1->x[2] = 0;\n                    p1->x[3] = 0;\n                    XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));\n                }\n            }\n        }\n\n        /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */\n        /* Reload r and convert to Montgomery form. */\n        sp_256_from_mp(u2, 4, r);\n        err = sp_256_mod_mul_norm_4(u2, u2, p256_mod);\n    }\n\n    if (err == MP_OKAY) {\n        /* u1 = r.z'.z' mod prime */\n        sp_256_mont_sqr_4(p1->z, p1->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(u1, u2, p1->z, p256_mod, p256_mp_mod);\n        *res = (int)(sp_256_cmp_4(p1->x, u1) == 0);\n        if (*res == 0) {\n            /* Reload r and add order. */\n            sp_256_from_mp(u2, 4, r);\n            carry = sp_256_add_4(u2, u2, p256_order);\n            /* Carry means result is greater than mod and is not valid. */\n            if (carry == 0) {\n                sp_256_norm_4(u2);\n\n                /* Compare with mod and if greater or equal then not valid. */\n                c = sp_256_cmp_4(u2, p256_mod);\n                if (c < 0) {\n                    /* Convert to Montogomery form */\n                    err = sp_256_mod_mul_norm_4(u2, u2, p256_mod);\n                    if (err == MP_OKAY) {\n                        /* u1 = (r + 1*order).z'.z' mod prime */\n                        sp_256_mont_mul_4(u1, u2, p1->z, p256_mod,\n                                                                  p256_mp_mod);\n                        *res = (int)(sp_256_cmp_4(p1->x, u1) == 0);\n                    }\n                }\n            }\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n#endif\n    sp_ecc_point_free(p1, 0, heap);\n    sp_ecc_point_free(p2, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_VERIFY */\n\n#ifdef HAVE_ECC_CHECK_KEY\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * point  EC point.\n * heap   Heap to use if dynamically allocating.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nstatic int sp_256_ecc_is_point_4(sp_point* point, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit t1d[2*4];\n    sp_digit t2d[2*4];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 4, heap, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 4;\n        t2 = d + 2 * 4;\n#else\n        (void)heap;\n\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        sp_256_sqr_4(t1, point->y);\n        (void)sp_256_mod_4(t1, t1, p256_mod);\n        sp_256_sqr_4(t2, point->x);\n        (void)sp_256_mod_4(t2, t2, p256_mod);\n        sp_256_mul_4(t2, t2, point->x);\n        (void)sp_256_mod_4(t2, t2, p256_mod);\n        (void)sp_256_sub_4(t2, p256_mod, t2);\n        sp_256_mont_add_4(t1, t1, t2, p256_mod);\n\n        sp_256_mont_add_4(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_4(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_4(t1, t1, point->x, p256_mod);\n\n        if (sp_256_cmp_4(t1, p256_b) != 0) {\n            err = MP_VAL;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * pX  X ordinate of EC point.\n * pY  Y ordinate of EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nint sp_ecc_is_point_256(mp_int* pX, mp_int* pY)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point pubd;\n#endif\n    sp_point* pub;\n    byte one[1] = { 1 };\n    int err;\n\n    err = sp_ecc_point_new(NULL, pubd, pub);\n    if (err == MP_OKAY) {\n        sp_256_from_mp(pub->x, 4, pX);\n        sp_256_from_mp(pub->y, 4, pY);\n        sp_256_from_bin(pub->z, 4, one, (int)sizeof(one));\n\n        err = sp_256_ecc_is_point_4(pub, NULL);\n    }\n\n    sp_ecc_point_free(pub, 0, NULL);\n\n    return err;\n}\n\n/* Check that the private scalar generates the EC point (px, py), the point is\n * on the curve and the point has the correct order.\n *\n * pX     X ordinate of EC point.\n * pY     Y ordinate of EC point.\n * privm  Private scalar that generates EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve, ECC_INF_E if the point does not have the correct order,\n * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and\n * MP_OKAY otherwise.\n */\nint sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit privd[4];\n    sp_point pubd;\n    sp_point pd;\n#endif\n    sp_digit* priv = NULL;\n    sp_point* pub;\n    sp_point* p = NULL;\n    byte one[1] = { 1 };\n    int err;\n\n    err = sp_ecc_point_new(heap, pubd, pub);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (priv == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK))\n        priv = privd;\n#endif\n\n        sp_256_from_mp(pub->x, 4, pX);\n        sp_256_from_mp(pub->y, 4, pY);\n        sp_256_from_bin(pub->z, 4, one, (int)sizeof(one));\n        sp_256_from_mp(priv, 4, privm);\n\n        /* Check point at infinitiy. */\n        if ((sp_256_iszero_4(pub->x) != 0) &&\n            (sp_256_iszero_4(pub->y) != 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check range of X and Y */\n        if (sp_256_cmp_4(pub->x, p256_mod) >= 0 ||\n            sp_256_cmp_4(pub->y, p256_mod) >= 0) {\n            err = ECC_OUT_OF_RANGE_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check point is on curve */\n        err = sp_256_ecc_is_point_4(pub, heap);\n    }\n\n    if (err == MP_OKAY) {\n        /* Point * order = infinity */\n            err = sp_256_ecc_mulmod_4(p, pub, p256_order, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is infinity */\n        if ((sp_256_iszero_4(p->x) == 0) ||\n            (sp_256_iszero_4(p->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Base * private = point */\n            err = sp_256_ecc_mulmod_base_4(p, priv, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is public key */\n        if (sp_256_cmp_4(p->x, pub->x) != 0 ||\n            sp_256_cmp_4(p->y, pub->y) != 0) {\n            err = ECC_PRIV_KEY_E;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (priv != NULL) {\n        XFREE(priv, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(pub, 0, heap);\n\n    return err;\n}\n#endif\n#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL\n/* Add two projective EC points together.\n * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)\n *\n * pX   First EC point's X ordinate.\n * pY   First EC point's Y ordinate.\n * pZ   First EC point's Z ordinate.\n * qX   Second EC point's X ordinate.\n * qY   Second EC point's Y ordinate.\n * qZ   Second EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* qX, mp_int* qY, mp_int* qZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 4 * 5];\n    sp_point pd;\n    sp_point qd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    sp_point* q = NULL;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(NULL, qd, q);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 4, pX);\n        sp_256_from_mp(p->y, 4, pY);\n        sp_256_from_mp(p->z, 4, pZ);\n        sp_256_from_mp(q->x, 4, qX);\n        sp_256_from_mp(q->y, 4, qY);\n        sp_256_from_mp(q->z, 4, qZ);\n\n            sp_256_proj_point_add_4(p, p, q, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(q, 0, NULL);\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Double a projective EC point.\n * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 4 * 2];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 2, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 4, pX);\n        sp_256_from_mp(p->y, 4, pY);\n        sp_256_from_mp(p->z, 4, pZ);\n\n            sp_256_proj_point_dbl_4(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Map a projective EC point to affine in place.\n * pZ will be one.\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 4 * 4];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 4, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 4, pX);\n        sp_256_from_mp(p->y, 4, pY);\n        sp_256_from_mp(p->z, 4, pZ);\n\n        sp_256_map_4(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, pX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */\n#ifdef HAVE_COMP_KEY\n/* Find the square root of a number mod the prime of the curve.\n *\n * y  The number to operate on and the result.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nstatic int sp_256_mont_sqrt_4(sp_digit* y)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit t1d[2 * 4];\n    sp_digit t2d[2 * 4];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 4, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 4;\n        t2 = d + 2 * 4;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        {\n            /* t2 = y ^ 0x2 */\n            sp_256_mont_sqr_4(t2, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0x3 */\n            sp_256_mont_mul_4(t1, t2, y, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xc */\n            sp_256_mont_sqr_n_4(t2, t1, 2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xf */\n            sp_256_mont_mul_4(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xf0 */\n            sp_256_mont_sqr_n_4(t2, t1, 4, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xff */\n            sp_256_mont_mul_4(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xff00 */\n            sp_256_mont_sqr_n_4(t2, t1, 8, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffff */\n            sp_256_mont_mul_4(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xffff0000 */\n            sp_256_mont_sqr_n_4(t2, t1, 16, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff */\n            sp_256_mont_mul_4(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000000 */\n            sp_256_mont_sqr_n_4(t1, t1, 32, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001 */\n            sp_256_mont_mul_4(t1, t1, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */\n            sp_256_mont_sqr_n_4(t1, t1, 96, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */\n            sp_256_mont_mul_4(t1, t1, y, p256_mod, p256_mp_mod);\n            sp_256_mont_sqr_n_4(y, t1, 94, p256_mod, p256_mp_mod);\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Uncompress the point given the X ordinate.\n *\n * xm    X ordinate.\n * odd   Whether the Y ordinate is odd.\n * ym    Calculated Y ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit xd[2 * 4];\n    sp_digit yd[2 * 4];\n#endif\n    sp_digit* x = NULL;\n    sp_digit* y = NULL;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 4, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        x = d + 0 * 4;\n        y = d + 2 * 4;\n#else\n        x = xd;\n        y = yd;\n#endif\n\n        sp_256_from_mp(x, 4, xm);\n        err = sp_256_mod_mul_norm_4(x, x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        /* y = x^3 */\n        {\n            sp_256_mont_sqr_4(y, x, p256_mod, p256_mp_mod);\n            sp_256_mont_mul_4(y, y, x, p256_mod, p256_mp_mod);\n        }\n        /* y = x^3 - 3x */\n        sp_256_mont_sub_4(y, y, x, p256_mod);\n        sp_256_mont_sub_4(y, y, x, p256_mod);\n        sp_256_mont_sub_4(y, y, x, p256_mod);\n        /* y = x^3 - 3x + b */\n        err = sp_256_mod_mul_norm_4(x, p256_b, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        sp_256_mont_add_4(y, y, x, p256_mod);\n        /* y = sqrt(x^3 - 3x + b) */\n        err = sp_256_mont_sqrt_4(y);\n    }\n    if (err == MP_OKAY) {\n        XMEMSET(y + 4, 0, 4U * sizeof(sp_digit));\n        sp_256_mont_reduce_4(y, p256_mod, p256_mp_mod);\n        if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {\n            sp_256_mont_sub_4(y, p256_mod, y, p256_mod);\n        }\n\n        err = sp_256_to_mp(y, ym);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n#endif\n#endif /* !WOLFSSL_SP_NO_256 */\n#endif /* WOLFSSL_HAVE_SP_ECC */\n#endif /* WOLFSSL_SP_ARM64_ASM */\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */\n"
  },
  {
    "path": "src/wolfcrypt/src/sp_armthumb.c",
    "content": "/* sp.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/* Implementation by Sean Parkinson. */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/cpuid.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \\\n                                    defined(WOLFSSL_HAVE_SP_ECC)\n\n#ifdef RSA_LOW_MEM\n#ifndef WOLFSSL_SP_SMALL\n#define WOLFSSL_SP_SMALL\n#endif\n#endif\n\n#include <wolfssl/wolfcrypt/sp.h>\n\n#ifdef WOLFSSL_SP_ARM_THUMB_ASM\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n#ifndef WOLFSSL_SP_NO_2048\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 24U) {\n            r[j] &= 0xffffffff;\n            s = 32U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 32\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 32\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffff;\n        s = 32U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 32U) <= (word32)DIGIT_BIT) {\n            s += 32U;\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 32) {\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 32 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 256\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_2048_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 2048 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<64 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 32) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 32);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[8 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #32\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #28\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\t%[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# Multiply Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply Done\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\t%[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #56\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #64\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #28\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\tr2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"# Multiply * 2: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply * 2: Done\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"# Square: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r6\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"mul\tr7, r7\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #15\\n\\t\"\n        \"lsl\tr6, r6, #17\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Square: Done\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\tr2, #4\\n\\t\"\n        \"mov\tr6, #32\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #56\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #60\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"sub\tr3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #64\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_add_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"add\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\"\n    );\n\n    return c;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_sub_in_place_16(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sub\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_add_16(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"add\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_8(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<8; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    r[0] = a[0] & m;\n    r[1] = a[1] & m;\n    r[2] = a[2] & m;\n    r[3] = a[3] & m;\n    r[4] = a[4] & m;\n    r[5] = a[5] & m;\n    r[6] = a[6] & m;\n    r[7] = a[7] & m;\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_16(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[16];\n    sp_digit a1[8];\n    sp_digit b1[8];\n    sp_digit z2[16];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_8(a1, a, &a[8]);\n    cb = sp_2048_add_8(b1, b, &b[8]);\n    u  = ca & cb;\n    sp_2048_mul_8(z1, a1, b1);\n    sp_2048_mul_8(z2, &a[8], &b[8]);\n    sp_2048_mul_8(z0, a, b);\n    sp_2048_mask_8(r + 16, a1, 0 - cb);\n    sp_2048_mask_8(b1, b1, 0 - ca);\n    u += sp_2048_add_8(r + 16, r + 16, b1);\n    u += sp_2048_sub_in_place_16(z1, z2);\n    u += sp_2048_sub_in_place_16(z1, z0);\n    u += sp_2048_add_16(r + 8, r + 8, z1);\n    r[24] = u;\n    XMEMSET(r + 24 + 1, 0, sizeof(sp_digit) * (8 - 1));\n    (void)sp_2048_add_16(r + 16, r + 16, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_16(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[16];\n    sp_digit z1[16];\n    sp_digit a1[8];\n    sp_digit u;\n\n    u = sp_2048_add_8(a1, a, &a[8]);\n    sp_2048_sqr_8(z1, a1);\n    sp_2048_sqr_8(z2, &a[8]);\n    sp_2048_sqr_8(z0, a);\n    sp_2048_mask_8(r + 16, a1, 0 - u);\n    u += sp_2048_add_8(r + 16, r + 16, r + 16);\n    u += sp_2048_sub_in_place_16(z1, z2);\n    u += sp_2048_sub_in_place_16(z1, z0);\n    u += sp_2048_add_16(r + 8, r + 8, z1);\n    r[24] = u;\n    XMEMSET(r + 24 + 1, 0, sizeof(sp_digit) * (8 - 1));\n    (void)sp_2048_add_16(r + 16, r + 16, z2);\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_sub_in_place_32(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sub\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr3, [%[a], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr6, [%[b], #68]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #64]\\n\\t\"\n        \"str\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr3, [%[a], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr6, [%[b], #76]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #72]\\n\\t\"\n        \"str\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr3, [%[a], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr6, [%[b], #84]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #80]\\n\\t\"\n        \"str\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr3, [%[a], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr6, [%[b], #92]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #88]\\n\\t\"\n        \"str\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr3, [%[a], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr6, [%[b], #100]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #96]\\n\\t\"\n        \"str\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr3, [%[a], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr6, [%[b], #108]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #104]\\n\\t\"\n        \"str\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr3, [%[a], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr6, [%[b], #116]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #112]\\n\\t\"\n        \"str\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr3, [%[a], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr6, [%[b], #124]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #120]\\n\\t\"\n        \"str\tr4, [%[a], #124]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"add\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #100]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #108]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #116]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #124]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_16(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<16; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 16; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[32];\n    sp_digit a1[16];\n    sp_digit b1[16];\n    sp_digit z2[32];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_16(a1, a, &a[16]);\n    cb = sp_2048_add_16(b1, b, &b[16]);\n    u  = ca & cb;\n    sp_2048_mul_16(z1, a1, b1);\n    sp_2048_mul_16(z2, &a[16], &b[16]);\n    sp_2048_mul_16(z0, a, b);\n    sp_2048_mask_16(r + 32, a1, 0 - cb);\n    sp_2048_mask_16(b1, b1, 0 - ca);\n    u += sp_2048_add_16(r + 32, r + 32, b1);\n    u += sp_2048_sub_in_place_32(z1, z2);\n    u += sp_2048_sub_in_place_32(z1, z0);\n    u += sp_2048_add_32(r + 16, r + 16, z1);\n    r[48] = u;\n    XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));\n    (void)sp_2048_add_32(r + 32, r + 32, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[32];\n    sp_digit z1[32];\n    sp_digit a1[16];\n    sp_digit u;\n\n    u = sp_2048_add_16(a1, a, &a[16]);\n    sp_2048_sqr_16(z1, a1);\n    sp_2048_sqr_16(z2, &a[16]);\n    sp_2048_sqr_16(z0, a);\n    sp_2048_mask_16(r + 32, a1, 0 - u);\n    u += sp_2048_add_16(r + 32, r + 32, r + 32);\n    u += sp_2048_sub_in_place_32(z1, z2);\n    u += sp_2048_sub_in_place_32(z1, z0);\n    u += sp_2048_add_32(r + 16, r + 16, z1);\n    r[48] = u;\n    XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));\n    (void)sp_2048_add_32(r + 32, r + 32, z2);\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_sub_in_place_64(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sub\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr3, [%[a], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr6, [%[b], #68]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #64]\\n\\t\"\n        \"str\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr3, [%[a], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr6, [%[b], #76]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #72]\\n\\t\"\n        \"str\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr3, [%[a], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr6, [%[b], #84]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #80]\\n\\t\"\n        \"str\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr3, [%[a], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr6, [%[b], #92]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #88]\\n\\t\"\n        \"str\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr3, [%[a], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr6, [%[b], #100]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #96]\\n\\t\"\n        \"str\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr3, [%[a], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr6, [%[b], #108]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #104]\\n\\t\"\n        \"str\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr3, [%[a], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr6, [%[b], #116]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #112]\\n\\t\"\n        \"str\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr3, [%[a], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr6, [%[b], #124]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #120]\\n\\t\"\n        \"str\tr4, [%[a], #124]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr3, [%[a], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr6, [%[b], #68]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #64]\\n\\t\"\n        \"str\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr3, [%[a], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr6, [%[b], #76]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #72]\\n\\t\"\n        \"str\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr3, [%[a], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr6, [%[b], #84]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #80]\\n\\t\"\n        \"str\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr3, [%[a], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr6, [%[b], #92]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #88]\\n\\t\"\n        \"str\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr3, [%[a], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr6, [%[b], #100]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #96]\\n\\t\"\n        \"str\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr3, [%[a], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr6, [%[b], #108]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #104]\\n\\t\"\n        \"str\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr3, [%[a], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr6, [%[b], #116]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #112]\\n\\t\"\n        \"str\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr3, [%[a], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr6, [%[b], #124]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #120]\\n\\t\"\n        \"str\tr4, [%[a], #124]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"add\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #100]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #108]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #116]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #124]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"add\t%[r], #0x80\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #100]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #108]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #116]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #124]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r7\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_32(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<32; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[64];\n    sp_digit a1[32];\n    sp_digit b1[32];\n    sp_digit z2[64];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_32(a1, a, &a[32]);\n    cb = sp_2048_add_32(b1, b, &b[32]);\n    u  = ca & cb;\n    sp_2048_mul_32(z1, a1, b1);\n    sp_2048_mul_32(z2, &a[32], &b[32]);\n    sp_2048_mul_32(z0, a, b);\n    sp_2048_mask_32(r + 64, a1, 0 - cb);\n    sp_2048_mask_32(b1, b1, 0 - ca);\n    u += sp_2048_add_32(r + 64, r + 64, b1);\n    u += sp_2048_sub_in_place_64(z1, z2);\n    u += sp_2048_sub_in_place_64(z1, z0);\n    u += sp_2048_add_64(r + 32, r + 32, z1);\n    r[96] = u;\n    XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));\n    (void)sp_2048_add_64(r + 64, r + 64, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_64(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[64];\n    sp_digit z1[64];\n    sp_digit a1[32];\n    sp_digit u;\n\n    u = sp_2048_add_32(a1, a, &a[32]);\n    sp_2048_sqr_32(z1, a1);\n    sp_2048_sqr_32(z2, &a[32]);\n    sp_2048_sqr_32(z0, a);\n    sp_2048_mask_32(r + 64, a1, 0 - u);\n    u += sp_2048_add_32(r + 64, r + 64, r + 64);\n    u += sp_2048_sub_in_place_64(z1, z2);\n    u += sp_2048_sub_in_place_64(z1, z0);\n    u += sp_2048_add_64(r + 32, r + 32, z1);\n    r[96] = u;\n    XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));\n    (void)sp_2048_add_64(r + 64, r + 64, z2);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr4, #1\\n\\t\"\n        \"lsl\tr4, #8\\n\\t\"\n        \"sub\tr7, #1\\n\\t\"\n        \"add\tr6, r4\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"add\t%[b], #4\\n\\t\"\n        \"add\t%[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_sub_in_place_64(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n    __asm__ __volatile__ (\n        \"mov\tr7, %[a]\\n\\t\"\n        \"mov\tr5, #1\\n\\t\"\n        \"lsl\tr5, #8\\n\\t\"\n        \"add\tr7, r5\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a]]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #8\\n\\t\"\n        \"add\t%[b], #8\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[64 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #252\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\t%[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# Multiply Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply Done\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\t%[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_64(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #252\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\tr2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"# Multiply * 2: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply * 2: Done\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"# Square: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r6\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"mul\tr7, r7\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #15\\n\\t\"\n        \"lsl\tr6, r6, #17\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Square: Done\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\tr2, #4\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #1\\n\\t\"\n        \"lsl\tr3, r3, #8\\n\\t\"\n        \"add\tr3, #252\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"sub\tr3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_32(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n    int i;\n\n    for (i=0; i<32; i++) {\n        r[i] = a[i] & m;\n    }\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\tr6, #128\\n\\t\"\n        \"sub\tr7, #1\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"add\t%[b], #4\\n\\t\"\n        \"add\t%[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_sub_in_place_32(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n    __asm__ __volatile__ (\n        \"mov\tr7, %[a]\\n\\t\"\n        \"add\tr7, #128\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a]]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #8\\n\\t\"\n        \"add\t%[b], #8\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[32 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #128\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #124\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\t%[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# Multiply Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply Done\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\t%[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #124\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\tr2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"# Multiply * 2: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply * 2: Done\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"# Square: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r6\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"mul\tr7, r7\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #15\\n\\t\"\n        \"lsl\tr6, r6, #17\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Square: Done\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\tr2, #4\\n\\t\"\n        \"mov\tr6, #128\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #252\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"sub\tr3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nSP_NOINLINE static void sp_2048_mul_d_64(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n    __asm__ __volatile__ (\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, %[a]\\n\\t\"\n        \"mov\tr8, %[r]\\n\\t\"\n        \"mov\tr9, r6\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"# A[] * B\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, %[b], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"lsr\tr7, %[b], #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, %[b], #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"lsl\tr7, %[b], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# A[] * B - Done\\n\\t\"\n        \"mov\t%[r], r8\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\t%[r], #4\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"mov\tr8, %[r]\\n\\t\"\n        \"cmp\t%[a], r9\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        : [r] \"+r\" (r), [a] \"+r\" (a)\n        : [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_32(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 32);\n\n    /* r = 2^n mod m */\n    sp_2048_sub_in_place_32(r, m);\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nSP_NOINLINE static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, sp_digit m)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr5, #128\\n\\t\"\n        \"mov\tr8, r5\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr6, [%[b], r7]\\n\\t\"\n        \"and\tr6, %[m]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr5, [%[a], r7]\\n\\t\"\n        \"sbc\tr5, r6\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"str\tr5, [%[r], r7]\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"cmp\tr7, r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n    return c;\n}\n\n/* Reduce the number back to 2048 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr8, %[mp]\\n\\t\"\n        \"mov\tr12, %[ca]\\n\\t\"\n        \"mov\tr14, %[m]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"# i = 0\\n\\t\"\n        \"mov\tr11, r4\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mov\t%[mp], r8\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mul\t%[mp], %[a]\\n\\t\"\n        \"mov\t%[m], r14\\n\\t\"\n        \"mov\tr10, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# a[i+j] += m[j] * mu\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"# Multiply m[j] and mu - Start\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr6, %[mp], #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\t%[a], r7\\n\\t\"\n        \"adc\tr5, %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\t%[a], r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr6, %[mp], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr5, r7\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\t%[a], r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"# Multiply m[j] and mu - Done\\n\\t\"\n        \"add\tr4, %[a]\\n\\t\"\n        \"adc\tr5, %[ca]\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"str\tr4, [%[a]]\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"add\t%[m], #4\\n\\t\"\n        \"add\tr10, r6\\n\\t\"\n        \"mov\tr4, #124\\n\\t\"\n        \"add\tr4, r9\\n\\t\"\n        \"cmp\tr10, r4\\n\\t\"\n        \"blt\t2b\\n\\t\"\n        \"# a[i+31] += m[31] * mu\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"mov\tr4, r12\\n\\t\"\n        \"mov\t%[a], #0\\n\\t\"\n        \"# Multiply m[31] and mu - Start\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr6, %[mp], #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr5, r7\\n\\t\"\n        \"adc\tr4, %[ca]\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr6, %[mp], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"# Multiply m[31] and mu - Done\\n\\t\"\n        \"mov\t%[ca], %[a]\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"ldr\tr7, [%[a], #4]\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"add\tr5, %[a]\\n\\t\"\n        \"adc\tr7, r4\\n\\t\"\n        \"adc\t%[ca], r6\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"str\tr5, [%[a]]\\n\\t\"\n        \"str\tr7, [%[a], #4]\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"add\tr9, r6\\n\\t\"\n        \"add\tr11, r6\\n\\t\"\n        \"mov\tr12, %[ca]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\tr4, #128\\n\\t\"\n        \"cmp\tr11, r4\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"mov\t%[m], r14\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n\n    sp_2048_cond_sub_32(a - 32, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_32(r, a, b);\n    sp_2048_mont_reduce_32(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_32(r, a);\n    sp_2048_mont_reduce_32(r, m, mp);\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nSP_NOINLINE static void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n    __asm__ __volatile__ (\n        \"mov\tr6, #128\\n\\t\"\n        \"add\tr6, %[a]\\n\\t\"\n        \"mov\tr8, %[r]\\n\\t\"\n        \"mov\tr9, r6\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"# A[] * B\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, %[b], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"lsr\tr7, %[b], #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, %[b], #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"lsl\tr7, %[b], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# A[] * B - Done\\n\\t\"\n        \"mov\t%[r], r8\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\t%[r], #4\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"mov\tr8, %[r]\\n\\t\"\n        \"cmp\t%[a], r9\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        : [r] \"+r\" (r), [a] \"+r\" (a)\n        : [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nSP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr5, %[div], #1\\n\\t\"\n        \"add\tr5, #1\\n\\t\"\n        \"mov\tr8, %[d0]\\n\\t\"\n        \"mov\tr9, %[d1]\\n\\t\"\n        \"# Do top 32\\n\\t\"\n        \"mov\tr6, r5\\n\\t\"\n        \"sub\tr6, %[d1]\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        \"and\tr6, r5\\n\\t\"\n        \"sub\t%[d1], r6\\n\\t\"\n        \"# Next 30 bits\\n\\t\"\n        \"mov\tr4, #29\\n\\t\"\n        \"1:\\n\\t\"\n        \"lsl\t%[d0], %[d0], #1\\n\\t\"\n        \"adc\t%[d1], %[d1]\\n\\t\"\n        \"mov\tr6, r5\\n\\t\"\n        \"sub\tr6, %[d1]\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        \"and\tr6, r5\\n\\t\"\n        \"sub\t%[d1], r6\\n\\t\"\n        \"sub\tr4, #1\\n\\t\"\n        \"bpl\t1b\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"add\t%[r], #1\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"sub\t%[d1], r4\\n\\t\"\n        \"mov\tr4, %[d1]\\n\\t\"\n        \"mov\t%[d1], r9\\n\\t\"\n        \"sbc\t%[d1], r5\\n\\t\"\n        \"mov\tr5, %[d1]\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sub\tr4, %[d1], r4\\n\\t\"\n        \"sbc\tr6, r5\\n\\t\"\n        \"mov\tr5, r6\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sub\tr4, %[d1], r4\\n\\t\"\n        \"sbc\tr6, r5\\n\\t\"\n        \"mov\tr5, r6\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"mov\tr6, %[div]\\n\\t\"\n        \"sub\tr6, r4\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r7\", \"r6\", \"r8\", \"r9\"\n    );\n    return r;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nSP_NOINLINE static int32_t sp_2048_cmp_32(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr6, #124\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr7, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr7, r3\\n\\t\"\n        \"and\tr5, r3\\n\\t\"\n        \"mov\tr4, r7\\n\\t\"\n        \"sub\tr7, r5\\n\\t\"\n        \"sbc\tr7, r7\\n\\t\"\n        \"add\t%[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r7\\n\\t\"\n        \"sub\tr5, r4\\n\\t\"\n        \"sbc\tr7, r7\\n\\t\"\n        \"sub\t%[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r7\\n\\t\"\n        \"sub\tr6, #4\\n\\t\"\n        \"cmp\tr6, #0\\n\\t\"\n        \"bge\t1b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_32(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[64], t2[33];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[31];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 32);\n    for (i=31; i>=0; i--) {\n        r1 = div_2048_word_32(t1[32 + i], t1[32 + i - 1], div);\n\n        sp_2048_mul_d_32(t2, d, r1);\n        t1[32 + i] += sp_2048_sub_in_place_32(&t1[i], t2);\n        t1[32 + i] -= t2[32];\n        sp_2048_mask_32(t2, d, t1[32 + i]);\n        t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], t2);\n        sp_2048_mask_32(t2, d, t1[32 + i]);\n        t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_2048_cmp_32(t1, d) >= 0;\n    sp_2048_cond_sub_32(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_32(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_32(a, m, NULL, r);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][64];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 64, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 64;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_32(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 32U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_32(t[1] + 32, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_32(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 32, a, sizeof(sp_digit) * 32);\n            err = sp_2048_mod_32(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_32(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_32(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_32(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_32(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_32(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_32(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_32(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_32(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_32(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_32(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_32(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_32(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_32(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_32(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 32);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n\n            sp_2048_mont_mul_32(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[32], 0, sizeof(sp_digit) * 32U);\n        sp_2048_mont_reduce_32(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_32(r, m) >= 0);\n        sp_2048_cond_sub_32(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][64];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 64, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 64;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_32(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 32U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_32(t[1] + 32, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_32(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 32, a, sizeof(sp_digit) * 32);\n            err = sp_2048_mod_32(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_32(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_32(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_32(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_32(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_32(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_32(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_32(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_32(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_32(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_32(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_32(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_32(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_32(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_32(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_32(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_32(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_32(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_32(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_32(t[20], t[10], m, mp);\n        sp_2048_mont_mul_32(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_32(t[22], t[11], m, mp);\n        sp_2048_mont_mul_32(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_32(t[24], t[12], m, mp);\n        sp_2048_mont_mul_32(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_32(t[26], t[13], m, mp);\n        sp_2048_mont_mul_32(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_32(t[28], t[14], m, mp);\n        sp_2048_mont_mul_32(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_32(t[30], t[15], m, mp);\n        sp_2048_mont_mul_32(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 32);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n\n            sp_2048_mont_mul_32(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[32], 0, sizeof(sp_digit) * 32U);\n        sp_2048_mont_reduce_32(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_32(r, m) >= 0);\n        sp_2048_cond_sub_32(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_64(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 64);\n\n    /* r = 2^n mod m */\n    sp_2048_sub_in_place_64(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nSP_NOINLINE static sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, sp_digit m)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr5, #1\\n\\t\"\n        \"lsl\tr5, r5, #8\\n\\t\"\n        \"mov\tr8, r5\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr6, [%[b], r7]\\n\\t\"\n        \"and\tr6, %[m]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr5, [%[a], r7]\\n\\t\"\n        \"sbc\tr5, r6\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"str\tr5, [%[r], r7]\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"cmp\tr7, r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n    return c;\n}\n\n/* Reduce the number back to 2048 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr8, %[mp]\\n\\t\"\n        \"mov\tr12, %[ca]\\n\\t\"\n        \"mov\tr14, %[m]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"# i = 0\\n\\t\"\n        \"mov\tr11, r4\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mov\t%[mp], r8\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mul\t%[mp], %[a]\\n\\t\"\n        \"mov\t%[m], r14\\n\\t\"\n        \"mov\tr10, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# a[i+j] += m[j] * mu\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"# Multiply m[j] and mu - Start\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr6, %[mp], #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\t%[a], r7\\n\\t\"\n        \"adc\tr5, %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\t%[a], r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr6, %[mp], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr5, r7\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\t%[a], r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"# Multiply m[j] and mu - Done\\n\\t\"\n        \"add\tr4, %[a]\\n\\t\"\n        \"adc\tr5, %[ca]\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"str\tr4, [%[a]]\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"add\t%[m], #4\\n\\t\"\n        \"add\tr10, r6\\n\\t\"\n        \"mov\tr4, #252\\n\\t\"\n        \"add\tr4, r9\\n\\t\"\n        \"cmp\tr10, r4\\n\\t\"\n        \"blt\t2b\\n\\t\"\n        \"# a[i+63] += m[63] * mu\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"mov\tr4, r12\\n\\t\"\n        \"mov\t%[a], #0\\n\\t\"\n        \"# Multiply m[63] and mu - Start\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr6, %[mp], #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr5, r7\\n\\t\"\n        \"adc\tr4, %[ca]\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr6, %[mp], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"# Multiply m[63] and mu - Done\\n\\t\"\n        \"mov\t%[ca], %[a]\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"ldr\tr7, [%[a], #4]\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"add\tr5, %[a]\\n\\t\"\n        \"adc\tr7, r4\\n\\t\"\n        \"adc\t%[ca], r6\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"str\tr5, [%[a]]\\n\\t\"\n        \"str\tr7, [%[a], #4]\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"add\tr9, r6\\n\\t\"\n        \"add\tr11, r6\\n\\t\"\n        \"mov\tr12, %[ca]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\tr4, #1\\n\\t\"\n        \"lsl\tr4, r4, #8\\n\\t\"\n        \"cmp\tr11, r4\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"mov\t%[m], r14\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n\n    sp_2048_cond_sub_64(a - 64, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_64(r, a, b);\n    sp_2048_mont_reduce_64(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_64(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_64(r, a);\n    sp_2048_mont_reduce_64(r, m, mp);\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nSP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr5, %[div], #1\\n\\t\"\n        \"add\tr5, #1\\n\\t\"\n        \"mov\tr8, %[d0]\\n\\t\"\n        \"mov\tr9, %[d1]\\n\\t\"\n        \"# Do top 32\\n\\t\"\n        \"mov\tr6, r5\\n\\t\"\n        \"sub\tr6, %[d1]\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        \"and\tr6, r5\\n\\t\"\n        \"sub\t%[d1], r6\\n\\t\"\n        \"# Next 30 bits\\n\\t\"\n        \"mov\tr4, #29\\n\\t\"\n        \"1:\\n\\t\"\n        \"lsl\t%[d0], %[d0], #1\\n\\t\"\n        \"adc\t%[d1], %[d1]\\n\\t\"\n        \"mov\tr6, r5\\n\\t\"\n        \"sub\tr6, %[d1]\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        \"and\tr6, r5\\n\\t\"\n        \"sub\t%[d1], r6\\n\\t\"\n        \"sub\tr4, #1\\n\\t\"\n        \"bpl\t1b\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"add\t%[r], #1\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"sub\t%[d1], r4\\n\\t\"\n        \"mov\tr4, %[d1]\\n\\t\"\n        \"mov\t%[d1], r9\\n\\t\"\n        \"sbc\t%[d1], r5\\n\\t\"\n        \"mov\tr5, %[d1]\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sub\tr4, %[d1], r4\\n\\t\"\n        \"sbc\tr6, r5\\n\\t\"\n        \"mov\tr5, r6\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sub\tr4, %[d1], r4\\n\\t\"\n        \"sbc\tr6, r5\\n\\t\"\n        \"mov\tr5, r6\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"mov\tr6, %[div]\\n\\t\"\n        \"sub\tr6, r4\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r7\", \"r6\", \"r8\", \"r9\"\n    );\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_64(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<64; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nSP_NOINLINE static int32_t sp_2048_cmp_64(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr6, #252\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr7, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr7, r3\\n\\t\"\n        \"and\tr5, r3\\n\\t\"\n        \"mov\tr4, r7\\n\\t\"\n        \"sub\tr7, r5\\n\\t\"\n        \"sbc\tr7, r7\\n\\t\"\n        \"add\t%[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r7\\n\\t\"\n        \"sub\tr5, r4\\n\\t\"\n        \"sbc\tr7, r7\\n\\t\"\n        \"sub\t%[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r7\\n\\t\"\n        \"sub\tr6, #4\\n\\t\"\n        \"cmp\tr6, #0\\n\\t\"\n        \"bge\t1b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_64(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[128], t2[65];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[63];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 64);\n    for (i=63; i>=0; i--) {\n        r1 = div_2048_word_64(t1[64 + i], t1[64 + i - 1], div);\n\n        sp_2048_mul_d_64(t2, d, r1);\n        t1[64 + i] += sp_2048_sub_in_place_64(&t1[i], t2);\n        t1[64 + i] -= t2[64];\n        sp_2048_mask_64(t2, d, t1[64 + i]);\n        t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], t2);\n        sp_2048_mask_64(t2, d, t1[64 + i]);\n        t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_2048_cmp_64(t1, d) >= 0;\n    sp_2048_cond_sub_64(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_64(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_64(a, m, NULL, r);\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_64_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[128], t2[65];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[63];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 64);\n    for (i=63; i>=0; i--) {\n        r1 = div_2048_word_64(t1[64 + i], t1[64 + i - 1], div);\n\n        sp_2048_mul_d_64(t2, d, r1);\n        t1[64 + i] += sp_2048_sub_in_place_64(&t1[i], t2);\n        t1[64 + i] -= t2[64];\n        if (t1[64 + i] != 0) {\n            t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], d);\n            if (t1[64 + i] != 0)\n                t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_2048_cmp_64(t1, d) >= 0;\n    sp_2048_cond_sub_64(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_64_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_64_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][128];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 128, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 128;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_64(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 64U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_64(t[1] + 64, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_64(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 64, a, sizeof(sp_digit) * 64);\n            err = sp_2048_mod_64(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_64(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_64(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_64(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_64(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_64(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_64(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_64(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_64(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_64(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_64(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_64(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_64(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_64(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_64(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 64);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n\n            sp_2048_mont_mul_64(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);\n        sp_2048_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_64(r, m) >= 0);\n        sp_2048_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][128];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 128, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 128;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_64(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 64U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_64(t[1] + 64, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_64(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 64, a, sizeof(sp_digit) * 64);\n            err = sp_2048_mod_64(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_64(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_64(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_64(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_64(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_64(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_64(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_64(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_64(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_64(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_64(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_64(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_64(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_64(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_64(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_64(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_64(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_64(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_64(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_64(t[20], t[10], m, mp);\n        sp_2048_mont_mul_64(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_64(t[22], t[11], m, mp);\n        sp_2048_mont_mul_64(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_64(t[24], t[12], m, mp);\n        sp_2048_mont_mul_64(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_64(t[26], t[13], m, mp);\n        sp_2048_mont_mul_64(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_64(t[28], t[14], m, mp);\n        sp_2048_mont_mul_64(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_64(t[30], t[15], m, mp);\n        sp_2048_mont_mul_64(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 64);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n\n            sp_2048_mont_mul_64(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);\n        sp_2048_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_64(r, m) >= 0);\n        sp_2048_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[128], md[64], rd[128];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1];\n    int err = MP_OKAY;\n\n    if (*outLen < 256)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 32 || inLen > 256 ||\n                                                     mp_count_bits(mm) != 2048))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 64 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 64 * 2;\n        m = r + 64 * 2;\n        ah = a + 64;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 64;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(ah, 64, in, inLen);\n#if DIGIT_BIT >= 32\n        e[0] = em->dp[0];\n#else\n        e[0] = em->dp[0];\n        if (em->used > 1)\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e[0] == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(m, 64, mm);\n\n        if (e[0] == 0x3) {\n            if (err == MP_OKAY) {\n                sp_2048_sqr_64(r, ah);\n                err = sp_2048_mod_64_cond(r, r, m);\n            }\n            if (err == MP_OKAY) {\n                sp_2048_mul_64(r, ah, r);\n                err = sp_2048_mod_64_cond(r, r, m);\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_2048_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 64);\n            err = sp_2048_mod_64_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=31; i>=0; i--)\n                    if (e[0] >> i)\n                        break;\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 64);\n                for (i--; i>=0; i--) {\n                    sp_2048_mont_sqr_64(r, r, m, mp);\n                    if (((e[0] >> i) & 1) == 1)\n                        sp_2048_mont_mul_64(r, r, a, m, mp);\n                }\n                XMEMSET(&r[64], 0, sizeof(sp_digit) * 64);\n                sp_2048_mont_reduce_64(r, m, mp);\n\n                for (i = 63; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_2048_sub_in_place_64(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[64 * 2];\n    sp_digit pd[32], qd[32], dpd[32];\n    sp_digit tmpad[64], tmpbd[64];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 256)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 256 || mp_count_bits(mm) != 2048))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 64 * 2;\n        q = p + 32;\n        qi = dq = dp = q + 32;\n        tmpa = qi + 32;\n        tmpb = tmpa + 64;\n\n        tmp = t;\n        r = tmp + 64;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 64;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(a, 64, in, inLen);\n        sp_2048_from_mp(p, 32, pm);\n        sp_2048_from_mp(q, 32, qm);\n        sp_2048_from_mp(dp, 32, dpm);\n\n        err = sp_2048_mod_exp_32(tmpa, a, dp, 1024, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(dq, 32, dqm);\n        err = sp_2048_mod_exp_32(tmpb, a, dq, 1024, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_2048_sub_in_place_32(tmpa, tmpb);\n        sp_2048_mask_32(tmp, p, c);\n        sp_2048_add_32(tmpa, tmpa, tmp);\n\n        sp_2048_from_mp(qi, 32, qim);\n        sp_2048_mul_32(tmpa, tmpa, qi);\n        err = sp_2048_mod_32(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mul_32(tmpa, q, tmpa);\n        XMEMSET(&tmpb[32], 0, sizeof(sp_digit) * 32);\n        sp_2048_add_64(r, tmpb, tmpa);\n\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 32 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_2048_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 32\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 64);\n        r->used = 64;\n        mp_clamp(r);\n#elif DIGIT_BIT < 32\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 64; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 32) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 32 - s;\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 64; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 32 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 32 - s;\n            }\n            else {\n                s += 32;\n            }\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[128], e[64], m[64];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 64, base);\n        sp_2048_from_mp(e, 64, exp);\n        sp_2048_from_mp(m, 64, mod);\n\n        err = sp_2048_mod_exp_64(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_2048_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_2048\nstatic void sp_2048_lshift_64(sp_digit* r, sp_digit* a, byte n)\n{\n    __asm__ __volatile__ (\n        \"mov\tr6, #31\\n\\t\"\n        \"sub\tr6, r6, %[n]\\n\\t\"\n        \"add\t%[a], %[a], #192\\n\\t\"\n        \"add\t%[r], %[r], #192\\n\\t\"\n        \"ldr\tr3, [%[a], #60]\\n\\t\"\n        \"lsr\tr4, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr4, r4, r6\\n\\t\"\n        \"ldr\tr2, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr2, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #44]\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr2, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr2, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #12]\\n\\t\"\n        \"str\tr2, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr2, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr2, [%[a], #60]\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr3, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr2, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"str\tr3, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr2, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #28]\\n\\t\"\n        \"str\tr2, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"str\tr3, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr2, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #12]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr2, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"str\tr3, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr2, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #52]\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"str\tr3, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #44]\\n\\t\"\n        \"str\tr2, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"str\tr3, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr2, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #28]\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr3, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr2, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"str\tr3, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr2, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr3, [%[a], #60]\\n\\t\"\n        \"str\tr2, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr2, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #44]\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr2, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr2, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #12]\\n\\t\"\n        \"str\tr2, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr2, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [n] \"r\" (n)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[128];\n    sp_digit td[65];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 193, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 128;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_64(norm, m);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        sp_2048_lshift_64(r, norm, y);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n\n            sp_2048_lshift_64(r, r, y);\n            sp_2048_mul_d_64(tmp, norm, r[64]);\n            r[64] = 0;\n            o = sp_2048_add_64(r, r, tmp);\n            sp_2048_cond_sub_64(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);\n        sp_2048_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_64(r, m) >= 0);\n        sp_2048_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* HAVE_FFDHE_2048 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 256 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[128], e[64], m[64];\n    sp_digit* r = b;\n    word32 i;\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 256) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 64, base);\n        sp_2048_from_bin(e, 64, exp, expLen);\n        sp_2048_from_mp(m, 64, mod);\n\n    #ifdef HAVE_FFDHE_2048\n        if (base->used == 1 && base->dp[0] == 2 && m[63] == (sp_digit)-1)\n            err = sp_2048_mod_exp_2_64(r, e, expLen * 8, m);\n        else\n    #endif\n            err = sp_2048_mod_exp_64(r, b, e, expLen * 8, m, 0);\n\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n        for (i=0; i<256 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[64], e[32], m[32];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1024) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 32, base);\n        sp_2048_from_mp(e, 32, exp);\n        sp_2048_from_mp(m, 32, mod);\n\n        err = sp_2048_mod_exp_32(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 32, 0, sizeof(*r) * 32U);\n        err = sp_2048_to_mp(r, res);\n        res->used = mod->used;\n        mp_clamp(res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_2048 */\n\n#ifndef WOLFSSL_SP_NO_3072\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 24U) {\n            r[j] &= 0xffffffff;\n            s = 32U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 32\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 32\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffff;\n        s = 32U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 32U) <= (word32)DIGIT_BIT) {\n            s += 32U;\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 32) {\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 32 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 384\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_3072_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 3072 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<96 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 32) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 32);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_12(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[12 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #48\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #44\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\t%[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# Multiply Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply Done\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\t%[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #88\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #96\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #44\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\tr2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"# Multiply * 2: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply * 2: Done\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"# Square: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r6\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"mul\tr7, r7\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #15\\n\\t\"\n        \"lsl\tr6, r6, #17\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Square: Done\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\tr2, #4\\n\\t\"\n        \"mov\tr6, #48\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #88\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #92\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"sub\tr3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #96\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_add_12(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"add\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\"\n    );\n\n    return c;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_sub_in_place_24(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sub\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr3, [%[a], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr6, [%[b], #68]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #64]\\n\\t\"\n        \"str\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr3, [%[a], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr6, [%[b], #76]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #72]\\n\\t\"\n        \"str\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr3, [%[a], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr6, [%[b], #84]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #80]\\n\\t\"\n        \"str\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr3, [%[a], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr6, [%[b], #92]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #88]\\n\\t\"\n        \"str\tr4, [%[a], #92]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_add_24(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"add\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_12(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<12; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    r[0] = a[0] & m;\n    r[1] = a[1] & m;\n    r[2] = a[2] & m;\n    r[3] = a[3] & m;\n    r[4] = a[4] & m;\n    r[5] = a[5] & m;\n    r[6] = a[6] & m;\n    r[7] = a[7] & m;\n    r[8] = a[8] & m;\n    r[9] = a[9] & m;\n    r[10] = a[10] & m;\n    r[11] = a[11] & m;\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_24(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[24];\n    sp_digit a1[12];\n    sp_digit b1[12];\n    sp_digit z2[24];\n    sp_digit u, ca, cb;\n\n    ca = sp_3072_add_12(a1, a, &a[12]);\n    cb = sp_3072_add_12(b1, b, &b[12]);\n    u  = ca & cb;\n    sp_3072_mul_12(z1, a1, b1);\n    sp_3072_mul_12(z2, &a[12], &b[12]);\n    sp_3072_mul_12(z0, a, b);\n    sp_3072_mask_12(r + 24, a1, 0 - cb);\n    sp_3072_mask_12(b1, b1, 0 - ca);\n    u += sp_3072_add_12(r + 24, r + 24, b1);\n    u += sp_3072_sub_in_place_24(z1, z2);\n    u += sp_3072_sub_in_place_24(z1, z0);\n    u += sp_3072_add_24(r + 12, r + 12, z1);\n    r[36] = u;\n    XMEMSET(r + 36 + 1, 0, sizeof(sp_digit) * (12 - 1));\n    (void)sp_3072_add_24(r + 24, r + 24, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_24(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[24];\n    sp_digit z1[24];\n    sp_digit a1[12];\n    sp_digit u;\n\n    u = sp_3072_add_12(a1, a, &a[12]);\n    sp_3072_sqr_12(z1, a1);\n    sp_3072_sqr_12(z2, &a[12]);\n    sp_3072_sqr_12(z0, a);\n    sp_3072_mask_12(r + 24, a1, 0 - u);\n    u += sp_3072_add_12(r + 24, r + 24, r + 24);\n    u += sp_3072_sub_in_place_24(z1, z2);\n    u += sp_3072_sub_in_place_24(z1, z0);\n    u += sp_3072_add_24(r + 12, r + 12, z1);\n    r[36] = u;\n    XMEMSET(r + 36 + 1, 0, sizeof(sp_digit) * (12 - 1));\n    (void)sp_3072_add_24(r + 24, r + 24, z2);\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_sub_in_place_48(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sub\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr3, [%[a], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr6, [%[b], #68]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #64]\\n\\t\"\n        \"str\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr3, [%[a], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr6, [%[b], #76]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #72]\\n\\t\"\n        \"str\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr3, [%[a], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr6, [%[b], #84]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #80]\\n\\t\"\n        \"str\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr3, [%[a], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr6, [%[b], #92]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #88]\\n\\t\"\n        \"str\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr3, [%[a], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr6, [%[b], #100]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #96]\\n\\t\"\n        \"str\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr3, [%[a], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr6, [%[b], #108]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #104]\\n\\t\"\n        \"str\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr3, [%[a], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr6, [%[b], #116]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #112]\\n\\t\"\n        \"str\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr3, [%[a], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr6, [%[b], #124]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #120]\\n\\t\"\n        \"str\tr4, [%[a], #124]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"add\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #100]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #108]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #116]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #124]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"add\t%[r], #0x80\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r7\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_24(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<24; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[48];\n    sp_digit a1[24];\n    sp_digit b1[24];\n    sp_digit z2[48];\n    sp_digit u, ca, cb;\n\n    ca = sp_3072_add_24(a1, a, &a[24]);\n    cb = sp_3072_add_24(b1, b, &b[24]);\n    u  = ca & cb;\n    sp_3072_mul_24(z1, a1, b1);\n    sp_3072_mul_24(z2, &a[24], &b[24]);\n    sp_3072_mul_24(z0, a, b);\n    sp_3072_mask_24(r + 48, a1, 0 - cb);\n    sp_3072_mask_24(b1, b1, 0 - ca);\n    u += sp_3072_add_24(r + 48, r + 48, b1);\n    u += sp_3072_sub_in_place_48(z1, z2);\n    u += sp_3072_sub_in_place_48(z1, z0);\n    u += sp_3072_add_48(r + 24, r + 24, z1);\n    r[72] = u;\n    XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));\n    (void)sp_3072_add_48(r + 48, r + 48, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[48];\n    sp_digit z1[48];\n    sp_digit a1[24];\n    sp_digit u;\n\n    u = sp_3072_add_24(a1, a, &a[24]);\n    sp_3072_sqr_24(z1, a1);\n    sp_3072_sqr_24(z2, &a[24]);\n    sp_3072_sqr_24(z0, a);\n    sp_3072_mask_24(r + 48, a1, 0 - u);\n    u += sp_3072_add_24(r + 48, r + 48, r + 48);\n    u += sp_3072_sub_in_place_48(z1, z2);\n    u += sp_3072_sub_in_place_48(z1, z0);\n    u += sp_3072_add_48(r + 24, r + 24, z1);\n    r[72] = u;\n    XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));\n    (void)sp_3072_add_48(r + 48, r + 48, z2);\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_sub_in_place_96(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sub\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr3, [%[a], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr6, [%[b], #68]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #64]\\n\\t\"\n        \"str\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr3, [%[a], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr6, [%[b], #76]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #72]\\n\\t\"\n        \"str\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr3, [%[a], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr6, [%[b], #84]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #80]\\n\\t\"\n        \"str\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr3, [%[a], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr6, [%[b], #92]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #88]\\n\\t\"\n        \"str\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr3, [%[a], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr6, [%[b], #100]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #96]\\n\\t\"\n        \"str\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr3, [%[a], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr6, [%[b], #108]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #104]\\n\\t\"\n        \"str\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr3, [%[a], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr6, [%[b], #116]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #112]\\n\\t\"\n        \"str\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr3, [%[a], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr6, [%[b], #124]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #120]\\n\\t\"\n        \"str\tr4, [%[a], #124]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr3, [%[a], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr6, [%[b], #68]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #64]\\n\\t\"\n        \"str\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr3, [%[a], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr6, [%[b], #76]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #72]\\n\\t\"\n        \"str\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr3, [%[a], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr6, [%[b], #84]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #80]\\n\\t\"\n        \"str\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr3, [%[a], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr6, [%[b], #92]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #88]\\n\\t\"\n        \"str\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr3, [%[a], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr6, [%[b], #100]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #96]\\n\\t\"\n        \"str\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr3, [%[a], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr6, [%[b], #108]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #104]\\n\\t\"\n        \"str\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr3, [%[a], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr6, [%[b], #116]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #112]\\n\\t\"\n        \"str\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr3, [%[a], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr6, [%[b], #124]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #120]\\n\\t\"\n        \"str\tr4, [%[a], #124]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr3, [%[a], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr6, [%[b], #68]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #64]\\n\\t\"\n        \"str\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr3, [%[a], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr6, [%[b], #76]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #72]\\n\\t\"\n        \"str\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr3, [%[a], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr6, [%[b], #84]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #80]\\n\\t\"\n        \"str\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr3, [%[a], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr6, [%[b], #92]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #88]\\n\\t\"\n        \"str\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr3, [%[a], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr6, [%[b], #100]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #96]\\n\\t\"\n        \"str\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr3, [%[a], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr6, [%[b], #108]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #104]\\n\\t\"\n        \"str\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr3, [%[a], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr6, [%[b], #116]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #112]\\n\\t\"\n        \"str\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr3, [%[a], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr6, [%[b], #124]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #120]\\n\\t\"\n        \"str\tr4, [%[a], #124]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"add\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #100]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #108]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #116]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #124]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"add\t%[r], #0x80\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #100]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #108]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #116]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #124]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"add\t%[r], #0x80\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #100]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #108]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #116]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #124]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r7\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_48(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<48; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 48; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_96(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[96];\n    sp_digit a1[48];\n    sp_digit b1[48];\n    sp_digit z2[96];\n    sp_digit u, ca, cb;\n\n    ca = sp_3072_add_48(a1, a, &a[48]);\n    cb = sp_3072_add_48(b1, b, &b[48]);\n    u  = ca & cb;\n    sp_3072_mul_48(z1, a1, b1);\n    sp_3072_mul_48(z2, &a[48], &b[48]);\n    sp_3072_mul_48(z0, a, b);\n    sp_3072_mask_48(r + 96, a1, 0 - cb);\n    sp_3072_mask_48(b1, b1, 0 - ca);\n    u += sp_3072_add_48(r + 96, r + 96, b1);\n    u += sp_3072_sub_in_place_96(z1, z2);\n    u += sp_3072_sub_in_place_96(z1, z0);\n    u += sp_3072_add_96(r + 48, r + 48, z1);\n    r[144] = u;\n    XMEMSET(r + 144 + 1, 0, sizeof(sp_digit) * (48 - 1));\n    (void)sp_3072_add_96(r + 96, r + 96, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_96(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[96];\n    sp_digit z1[96];\n    sp_digit a1[48];\n    sp_digit u;\n\n    u = sp_3072_add_48(a1, a, &a[48]);\n    sp_3072_sqr_48(z1, a1);\n    sp_3072_sqr_48(z2, &a[48]);\n    sp_3072_sqr_48(z0, a);\n    sp_3072_mask_48(r + 96, a1, 0 - u);\n    u += sp_3072_add_48(r + 96, r + 96, r + 96);\n    u += sp_3072_sub_in_place_96(z1, z2);\n    u += sp_3072_sub_in_place_96(z1, z0);\n    u += sp_3072_add_96(r + 48, r + 48, z1);\n    r[144] = u;\n    XMEMSET(r + 144 + 1, 0, sizeof(sp_digit) * (48 - 1));\n    (void)sp_3072_add_96(r + 96, r + 96, z2);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr4, #1\\n\\t\"\n        \"lsl\tr4, #8\\n\\t\"\n        \"add\tr4, #128\\n\\t\"\n        \"sub\tr7, #1\\n\\t\"\n        \"add\tr6, r4\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"add\t%[b], #4\\n\\t\"\n        \"add\t%[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_sub_in_place_96(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n    __asm__ __volatile__ (\n        \"mov\tr7, %[a]\\n\\t\"\n        \"mov\tr5, #1\\n\\t\"\n        \"lsl\tr5, #8\\n\\t\"\n        \"add\tr5, #128\\n\\t\"\n        \"add\tr7, r5\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a]]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #8\\n\\t\"\n        \"add\t%[b], #8\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_96(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[96 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #128\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #124\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\t%[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# Multiply Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply Done\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\t%[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_96(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #3\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #124\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\tr2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"# Multiply * 2: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply * 2: Done\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"# Square: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r6\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"mul\tr7, r7\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #15\\n\\t\"\n        \"lsl\tr6, r6, #17\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Square: Done\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\tr2, #4\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #128\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #2\\n\\t\"\n        \"lsl\tr3, r3, #8\\n\\t\"\n        \"add\tr3, #252\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"sub\tr3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #3\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_48(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n    int i;\n\n    for (i=0; i<48; i++) {\n        r[i] = a[i] & m;\n    }\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\tr6, #192\\n\\t\"\n        \"sub\tr7, #1\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"add\t%[b], #4\\n\\t\"\n        \"add\t%[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_sub_in_place_48(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n    __asm__ __volatile__ (\n        \"mov\tr7, %[a]\\n\\t\"\n        \"add\tr7, #192\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a]]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #8\\n\\t\"\n        \"add\t%[b], #8\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[48 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #192\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #188\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\t%[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# Multiply Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply Done\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\t%[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #120\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #128\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #188\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\tr2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"# Multiply * 2: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply * 2: Done\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"# Square: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r6\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"mul\tr7, r7\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #15\\n\\t\"\n        \"lsl\tr6, r6, #17\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Square: Done\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\tr2, #4\\n\\t\"\n        \"mov\tr6, #192\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #120\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #1\\n\\t\"\n        \"lsl\tr3, r3, #8\\n\\t\"\n        \"add\tr3, #124\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"sub\tr3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #128\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nSP_NOINLINE static void sp_3072_mul_d_96(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n    __asm__ __volatile__ (\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #128\\n\\t\"\n        \"add\tr6, %[a]\\n\\t\"\n        \"mov\tr8, %[r]\\n\\t\"\n        \"mov\tr9, r6\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"# A[] * B\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, %[b], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"lsr\tr7, %[b], #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, %[b], #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"lsl\tr7, %[b], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# A[] * B - Done\\n\\t\"\n        \"mov\t%[r], r8\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\t%[r], #4\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"mov\tr8, %[r]\\n\\t\"\n        \"cmp\t%[a], r9\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        : [r] \"+r\" (r), [a] \"+r\" (a)\n        : [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_48(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 48);\n\n    /* r = 2^n mod m */\n    sp_3072_sub_in_place_48(r, m);\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nSP_NOINLINE static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, sp_digit m)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr5, #192\\n\\t\"\n        \"mov\tr8, r5\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr6, [%[b], r7]\\n\\t\"\n        \"and\tr6, %[m]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr5, [%[a], r7]\\n\\t\"\n        \"sbc\tr5, r6\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"str\tr5, [%[r], r7]\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"cmp\tr7, r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n    return c;\n}\n\n/* Reduce the number back to 3072 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr8, %[mp]\\n\\t\"\n        \"mov\tr12, %[ca]\\n\\t\"\n        \"mov\tr14, %[m]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"# i = 0\\n\\t\"\n        \"mov\tr11, r4\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mov\t%[mp], r8\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mul\t%[mp], %[a]\\n\\t\"\n        \"mov\t%[m], r14\\n\\t\"\n        \"mov\tr10, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# a[i+j] += m[j] * mu\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"# Multiply m[j] and mu - Start\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr6, %[mp], #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\t%[a], r7\\n\\t\"\n        \"adc\tr5, %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\t%[a], r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr6, %[mp], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr5, r7\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\t%[a], r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"# Multiply m[j] and mu - Done\\n\\t\"\n        \"add\tr4, %[a]\\n\\t\"\n        \"adc\tr5, %[ca]\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"str\tr4, [%[a]]\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"add\t%[m], #4\\n\\t\"\n        \"add\tr10, r6\\n\\t\"\n        \"mov\tr4, #188\\n\\t\"\n        \"add\tr4, r9\\n\\t\"\n        \"cmp\tr10, r4\\n\\t\"\n        \"blt\t2b\\n\\t\"\n        \"# a[i+47] += m[47] * mu\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"mov\tr4, r12\\n\\t\"\n        \"mov\t%[a], #0\\n\\t\"\n        \"# Multiply m[47] and mu - Start\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr6, %[mp], #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr5, r7\\n\\t\"\n        \"adc\tr4, %[ca]\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr6, %[mp], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"# Multiply m[47] and mu - Done\\n\\t\"\n        \"mov\t%[ca], %[a]\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"ldr\tr7, [%[a], #4]\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"add\tr5, %[a]\\n\\t\"\n        \"adc\tr7, r4\\n\\t\"\n        \"adc\t%[ca], r6\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"str\tr5, [%[a]]\\n\\t\"\n        \"str\tr7, [%[a], #4]\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"add\tr9, r6\\n\\t\"\n        \"add\tr11, r6\\n\\t\"\n        \"mov\tr12, %[ca]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\tr4, #192\\n\\t\"\n        \"cmp\tr11, r4\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"mov\t%[m], r14\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n\n    sp_3072_cond_sub_48(a - 48, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_48(r, a, b);\n    sp_3072_mont_reduce_48(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_48(r, a);\n    sp_3072_mont_reduce_48(r, m, mp);\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nSP_NOINLINE static void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n    __asm__ __volatile__ (\n        \"mov\tr6, #192\\n\\t\"\n        \"add\tr6, %[a]\\n\\t\"\n        \"mov\tr8, %[r]\\n\\t\"\n        \"mov\tr9, r6\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"# A[] * B\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, %[b], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"lsr\tr7, %[b], #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, %[b], #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"lsl\tr7, %[b], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# A[] * B - Done\\n\\t\"\n        \"mov\t%[r], r8\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\t%[r], #4\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"mov\tr8, %[r]\\n\\t\"\n        \"cmp\t%[a], r9\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        : [r] \"+r\" (r), [a] \"+r\" (a)\n        : [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nSP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr5, %[div], #1\\n\\t\"\n        \"add\tr5, #1\\n\\t\"\n        \"mov\tr8, %[d0]\\n\\t\"\n        \"mov\tr9, %[d1]\\n\\t\"\n        \"# Do top 32\\n\\t\"\n        \"mov\tr6, r5\\n\\t\"\n        \"sub\tr6, %[d1]\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        \"and\tr6, r5\\n\\t\"\n        \"sub\t%[d1], r6\\n\\t\"\n        \"# Next 30 bits\\n\\t\"\n        \"mov\tr4, #29\\n\\t\"\n        \"1:\\n\\t\"\n        \"lsl\t%[d0], %[d0], #1\\n\\t\"\n        \"adc\t%[d1], %[d1]\\n\\t\"\n        \"mov\tr6, r5\\n\\t\"\n        \"sub\tr6, %[d1]\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        \"and\tr6, r5\\n\\t\"\n        \"sub\t%[d1], r6\\n\\t\"\n        \"sub\tr4, #1\\n\\t\"\n        \"bpl\t1b\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"add\t%[r], #1\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"sub\t%[d1], r4\\n\\t\"\n        \"mov\tr4, %[d1]\\n\\t\"\n        \"mov\t%[d1], r9\\n\\t\"\n        \"sbc\t%[d1], r5\\n\\t\"\n        \"mov\tr5, %[d1]\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sub\tr4, %[d1], r4\\n\\t\"\n        \"sbc\tr6, r5\\n\\t\"\n        \"mov\tr5, r6\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sub\tr4, %[d1], r4\\n\\t\"\n        \"sbc\tr6, r5\\n\\t\"\n        \"mov\tr5, r6\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"mov\tr6, %[div]\\n\\t\"\n        \"sub\tr6, r4\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r7\", \"r6\", \"r8\", \"r9\"\n    );\n    return r;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nSP_NOINLINE static int32_t sp_3072_cmp_48(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr6, #188\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr7, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr7, r3\\n\\t\"\n        \"and\tr5, r3\\n\\t\"\n        \"mov\tr4, r7\\n\\t\"\n        \"sub\tr7, r5\\n\\t\"\n        \"sbc\tr7, r7\\n\\t\"\n        \"add\t%[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r7\\n\\t\"\n        \"sub\tr5, r4\\n\\t\"\n        \"sbc\tr7, r7\\n\\t\"\n        \"sub\t%[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r7\\n\\t\"\n        \"sub\tr6, #4\\n\\t\"\n        \"cmp\tr6, #0\\n\\t\"\n        \"bge\t1b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_48(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[96], t2[49];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[47];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 48);\n    for (i=47; i>=0; i--) {\n        r1 = div_3072_word_48(t1[48 + i], t1[48 + i - 1], div);\n\n        sp_3072_mul_d_48(t2, d, r1);\n        t1[48 + i] += sp_3072_sub_in_place_48(&t1[i], t2);\n        t1[48 + i] -= t2[48];\n        sp_3072_mask_48(t2, d, t1[48 + i]);\n        t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], t2);\n        sp_3072_mask_48(t2, d, t1[48 + i]);\n        t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_3072_cmp_48(t1, d) >= 0;\n    sp_3072_cond_sub_48(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_48(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_48(a, m, NULL, r);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][96];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 96, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 96;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_48(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 48U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_48(t[1] + 48, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_48(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 48, a, sizeof(sp_digit) * 48);\n            err = sp_3072_mod_48(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_48(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_48(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_48(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_48(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_48(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_48(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_48(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_48(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_48(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_48(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_48(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_48(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_48(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_48(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 48);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n\n            sp_3072_mont_mul_48(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[48], 0, sizeof(sp_digit) * 48U);\n        sp_3072_mont_reduce_48(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_48(r, m) >= 0);\n        sp_3072_cond_sub_48(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][96];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 96, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 96;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_48(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 48U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_48(t[1] + 48, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_48(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 48, a, sizeof(sp_digit) * 48);\n            err = sp_3072_mod_48(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_48(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_48(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_48(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_48(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_48(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_48(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_48(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_48(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_48(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_48(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_48(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_48(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_48(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_48(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_48(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_48(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_48(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_48(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_48(t[20], t[10], m, mp);\n        sp_3072_mont_mul_48(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_48(t[22], t[11], m, mp);\n        sp_3072_mont_mul_48(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_48(t[24], t[12], m, mp);\n        sp_3072_mont_mul_48(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_48(t[26], t[13], m, mp);\n        sp_3072_mont_mul_48(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_48(t[28], t[14], m, mp);\n        sp_3072_mont_mul_48(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_48(t[30], t[15], m, mp);\n        sp_3072_mont_mul_48(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 48);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n\n            sp_3072_mont_mul_48(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[48], 0, sizeof(sp_digit) * 48U);\n        sp_3072_mont_reduce_48(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_48(r, m) >= 0);\n        sp_3072_cond_sub_48(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_96(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 96);\n\n    /* r = 2^n mod m */\n    sp_3072_sub_in_place_96(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nSP_NOINLINE static sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, sp_digit m)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr5, #1\\n\\t\"\n        \"lsl\tr5, r5, #8\\n\\t\"\n        \"add\tr5, #128\\n\\t\"\n        \"mov\tr8, r5\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr6, [%[b], r7]\\n\\t\"\n        \"and\tr6, %[m]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr5, [%[a], r7]\\n\\t\"\n        \"sbc\tr5, r6\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"str\tr5, [%[r], r7]\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"cmp\tr7, r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n    return c;\n}\n\n/* Reduce the number back to 3072 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr8, %[mp]\\n\\t\"\n        \"mov\tr12, %[ca]\\n\\t\"\n        \"mov\tr14, %[m]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"# i = 0\\n\\t\"\n        \"mov\tr11, r4\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mov\t%[mp], r8\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mul\t%[mp], %[a]\\n\\t\"\n        \"mov\t%[m], r14\\n\\t\"\n        \"mov\tr10, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# a[i+j] += m[j] * mu\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"# Multiply m[j] and mu - Start\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr6, %[mp], #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\t%[a], r7\\n\\t\"\n        \"adc\tr5, %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\t%[a], r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr6, %[mp], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr5, r7\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\t%[a], r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"# Multiply m[j] and mu - Done\\n\\t\"\n        \"add\tr4, %[a]\\n\\t\"\n        \"adc\tr5, %[ca]\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"str\tr4, [%[a]]\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"add\t%[m], #4\\n\\t\"\n        \"add\tr10, r6\\n\\t\"\n        \"mov\tr4, #1\\n\\t\"\n        \"lsl\tr4, r4, #8\\n\\t\"\n        \"add\tr4, #124\\n\\t\"\n        \"add\tr4, r9\\n\\t\"\n        \"cmp\tr10, r4\\n\\t\"\n        \"blt\t2b\\n\\t\"\n        \"# a[i+95] += m[95] * mu\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"mov\tr4, r12\\n\\t\"\n        \"mov\t%[a], #0\\n\\t\"\n        \"# Multiply m[95] and mu - Start\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr6, %[mp], #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr5, r7\\n\\t\"\n        \"adc\tr4, %[ca]\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr6, %[mp], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"# Multiply m[95] and mu - Done\\n\\t\"\n        \"mov\t%[ca], %[a]\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"ldr\tr7, [%[a], #4]\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"add\tr5, %[a]\\n\\t\"\n        \"adc\tr7, r4\\n\\t\"\n        \"adc\t%[ca], r6\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"str\tr5, [%[a]]\\n\\t\"\n        \"str\tr7, [%[a], #4]\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"add\tr9, r6\\n\\t\"\n        \"add\tr11, r6\\n\\t\"\n        \"mov\tr12, %[ca]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\tr4, #1\\n\\t\"\n        \"lsl\tr4, r4, #8\\n\\t\"\n        \"add\tr4, #128\\n\\t\"\n        \"cmp\tr11, r4\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"mov\t%[m], r14\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n\n    sp_3072_cond_sub_96(a - 96, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_96(r, a, b);\n    sp_3072_mont_reduce_96(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_96(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_96(r, a);\n    sp_3072_mont_reduce_96(r, m, mp);\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nSP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr5, %[div], #1\\n\\t\"\n        \"add\tr5, #1\\n\\t\"\n        \"mov\tr8, %[d0]\\n\\t\"\n        \"mov\tr9, %[d1]\\n\\t\"\n        \"# Do top 32\\n\\t\"\n        \"mov\tr6, r5\\n\\t\"\n        \"sub\tr6, %[d1]\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        \"and\tr6, r5\\n\\t\"\n        \"sub\t%[d1], r6\\n\\t\"\n        \"# Next 30 bits\\n\\t\"\n        \"mov\tr4, #29\\n\\t\"\n        \"1:\\n\\t\"\n        \"lsl\t%[d0], %[d0], #1\\n\\t\"\n        \"adc\t%[d1], %[d1]\\n\\t\"\n        \"mov\tr6, r5\\n\\t\"\n        \"sub\tr6, %[d1]\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        \"and\tr6, r5\\n\\t\"\n        \"sub\t%[d1], r6\\n\\t\"\n        \"sub\tr4, #1\\n\\t\"\n        \"bpl\t1b\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"add\t%[r], #1\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"sub\t%[d1], r4\\n\\t\"\n        \"mov\tr4, %[d1]\\n\\t\"\n        \"mov\t%[d1], r9\\n\\t\"\n        \"sbc\t%[d1], r5\\n\\t\"\n        \"mov\tr5, %[d1]\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sub\tr4, %[d1], r4\\n\\t\"\n        \"sbc\tr6, r5\\n\\t\"\n        \"mov\tr5, r6\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sub\tr4, %[d1], r4\\n\\t\"\n        \"sbc\tr6, r5\\n\\t\"\n        \"mov\tr5, r6\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"mov\tr6, %[div]\\n\\t\"\n        \"sub\tr6, r4\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r7\", \"r6\", \"r8\", \"r9\"\n    );\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_96(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<96; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 96; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nSP_NOINLINE static int32_t sp_3072_cmp_96(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #124\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr7, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr7, r3\\n\\t\"\n        \"and\tr5, r3\\n\\t\"\n        \"mov\tr4, r7\\n\\t\"\n        \"sub\tr7, r5\\n\\t\"\n        \"sbc\tr7, r7\\n\\t\"\n        \"add\t%[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r7\\n\\t\"\n        \"sub\tr5, r4\\n\\t\"\n        \"sbc\tr7, r7\\n\\t\"\n        \"sub\t%[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r7\\n\\t\"\n        \"sub\tr6, #4\\n\\t\"\n        \"cmp\tr6, #0\\n\\t\"\n        \"bge\t1b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_96(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[192], t2[97];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[95];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 96);\n    for (i=95; i>=0; i--) {\n        r1 = div_3072_word_96(t1[96 + i], t1[96 + i - 1], div);\n\n        sp_3072_mul_d_96(t2, d, r1);\n        t1[96 + i] += sp_3072_sub_in_place_96(&t1[i], t2);\n        t1[96 + i] -= t2[96];\n        sp_3072_mask_96(t2, d, t1[96 + i]);\n        t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], t2);\n        sp_3072_mask_96(t2, d, t1[96 + i]);\n        t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_3072_cmp_96(t1, d) >= 0;\n    sp_3072_cond_sub_96(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_96(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_96(a, m, NULL, r);\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_96_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[192], t2[97];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[95];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 96);\n    for (i=95; i>=0; i--) {\n        r1 = div_3072_word_96(t1[96 + i], t1[96 + i - 1], div);\n\n        sp_3072_mul_d_96(t2, d, r1);\n        t1[96 + i] += sp_3072_sub_in_place_96(&t1[i], t2);\n        t1[96 + i] -= t2[96];\n        if (t1[96 + i] != 0) {\n            t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], d);\n            if (t1[96 + i] != 0)\n                t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_3072_cmp_96(t1, d) >= 0;\n    sp_3072_cond_sub_96(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_96_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_96_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][192];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 192, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 192;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_96(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 96U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_96(t[1] + 96, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_96(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 96, a, sizeof(sp_digit) * 96);\n            err = sp_3072_mod_96(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_96(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_96(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_96(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_96(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_96(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_96(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_96(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_96(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_96(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_96(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_96(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_96(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_96(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_96(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 96);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n\n            sp_3072_mont_mul_96(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[96], 0, sizeof(sp_digit) * 96U);\n        sp_3072_mont_reduce_96(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_96(r, m) >= 0);\n        sp_3072_cond_sub_96(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][192];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 192, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 192;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_96(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 96U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_96(t[1] + 96, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_96(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 96, a, sizeof(sp_digit) * 96);\n            err = sp_3072_mod_96(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_96(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_96(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_96(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_96(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_96(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_96(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_96(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_96(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_96(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_96(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_96(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_96(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_96(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_96(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_96(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_96(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_96(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_96(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_96(t[20], t[10], m, mp);\n        sp_3072_mont_mul_96(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_96(t[22], t[11], m, mp);\n        sp_3072_mont_mul_96(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_96(t[24], t[12], m, mp);\n        sp_3072_mont_mul_96(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_96(t[26], t[13], m, mp);\n        sp_3072_mont_mul_96(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_96(t[28], t[14], m, mp);\n        sp_3072_mont_mul_96(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_96(t[30], t[15], m, mp);\n        sp_3072_mont_mul_96(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 96);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n\n            sp_3072_mont_mul_96(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[96], 0, sizeof(sp_digit) * 96U);\n        sp_3072_mont_reduce_96(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_96(r, m) >= 0);\n        sp_3072_cond_sub_96(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[192], md[96], rd[192];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1];\n    int err = MP_OKAY;\n\n    if (*outLen < 384)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 32 || inLen > 384 ||\n                                                     mp_count_bits(mm) != 3072))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 96 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 96 * 2;\n        m = r + 96 * 2;\n        ah = a + 96;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 96;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(ah, 96, in, inLen);\n#if DIGIT_BIT >= 32\n        e[0] = em->dp[0];\n#else\n        e[0] = em->dp[0];\n        if (em->used > 1)\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e[0] == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(m, 96, mm);\n\n        if (e[0] == 0x3) {\n            if (err == MP_OKAY) {\n                sp_3072_sqr_96(r, ah);\n                err = sp_3072_mod_96_cond(r, r, m);\n            }\n            if (err == MP_OKAY) {\n                sp_3072_mul_96(r, ah, r);\n                err = sp_3072_mod_96_cond(r, r, m);\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_3072_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 96);\n            err = sp_3072_mod_96_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=31; i>=0; i--)\n                    if (e[0] >> i)\n                        break;\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 96);\n                for (i--; i>=0; i--) {\n                    sp_3072_mont_sqr_96(r, r, m, mp);\n                    if (((e[0] >> i) & 1) == 1)\n                        sp_3072_mont_mul_96(r, r, a, m, mp);\n                }\n                XMEMSET(&r[96], 0, sizeof(sp_digit) * 96);\n                sp_3072_mont_reduce_96(r, m, mp);\n\n                for (i = 95; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_3072_sub_in_place_96(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[96 * 2];\n    sp_digit pd[48], qd[48], dpd[48];\n    sp_digit tmpad[96], tmpbd[96];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 384)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 384 || mp_count_bits(mm) != 3072))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 48 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 96 * 2;\n        q = p + 48;\n        qi = dq = dp = q + 48;\n        tmpa = qi + 48;\n        tmpb = tmpa + 96;\n\n        tmp = t;\n        r = tmp + 96;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 96;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(a, 96, in, inLen);\n        sp_3072_from_mp(p, 48, pm);\n        sp_3072_from_mp(q, 48, qm);\n        sp_3072_from_mp(dp, 48, dpm);\n\n        err = sp_3072_mod_exp_48(tmpa, a, dp, 1536, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(dq, 48, dqm);\n        err = sp_3072_mod_exp_48(tmpb, a, dq, 1536, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_3072_sub_in_place_48(tmpa, tmpb);\n        sp_3072_mask_48(tmp, p, c);\n        sp_3072_add_48(tmpa, tmpa, tmp);\n\n        sp_3072_from_mp(qi, 48, qim);\n        sp_3072_mul_48(tmpa, tmpa, qi);\n        err = sp_3072_mod_48(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mul_48(tmpa, q, tmpa);\n        XMEMSET(&tmpb[48], 0, sizeof(sp_digit) * 48);\n        sp_3072_add_96(r, tmpb, tmpa);\n\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 48 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_3072_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 32\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 96);\n        r->used = 96;\n        mp_clamp(r);\n#elif DIGIT_BIT < 32\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 96; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 32) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 32 - s;\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 96; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 32 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 32 - s;\n            }\n            else {\n                s += 32;\n            }\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[192], e[96], m[96];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 96, base);\n        sp_3072_from_mp(e, 96, exp);\n        sp_3072_from_mp(m, 96, mod);\n\n        err = sp_3072_mod_exp_96(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_3072_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_3072\nstatic void sp_3072_lshift_96(sp_digit* r, sp_digit* a, byte n)\n{\n    __asm__ __volatile__ (\n        \"mov\tr6, #31\\n\\t\"\n        \"sub\tr6, r6, %[n]\\n\\t\"\n        \"add\t%[a], %[a], #255\\n\\t\"\n        \"add\t%[r], %[r], #255\\n\\t\"\n        \"add\t%[a], %[a], #65\\n\\t\"\n        \"add\t%[r], %[r], #65\\n\\t\"\n        \"ldr\tr3, [%[a], #60]\\n\\t\"\n        \"lsr\tr4, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr4, r4, r6\\n\\t\"\n        \"ldr\tr2, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr2, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #44]\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr2, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr2, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #12]\\n\\t\"\n        \"str\tr2, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr2, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr2, [%[a], #60]\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr3, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr2, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"str\tr3, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr2, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #28]\\n\\t\"\n        \"str\tr2, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"str\tr3, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr2, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #12]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr2, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"str\tr3, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr2, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #52]\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"str\tr3, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #44]\\n\\t\"\n        \"str\tr2, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"str\tr3, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr2, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #28]\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr3, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr2, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"str\tr3, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr2, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr3, [%[a], #60]\\n\\t\"\n        \"str\tr2, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr2, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #44]\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr2, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr2, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #12]\\n\\t\"\n        \"str\tr2, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr2, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr2, [%[a], #60]\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr3, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr2, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"str\tr3, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr2, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #28]\\n\\t\"\n        \"str\tr2, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"str\tr3, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr2, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #12]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr2, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"str\tr3, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr2, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #52]\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"str\tr3, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #44]\\n\\t\"\n        \"str\tr2, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"str\tr3, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr2, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #28]\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr3, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr2, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"str\tr3, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr2, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"str\tr2, [%[r], #4]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [n] \"r\" (n)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[192];\n    sp_digit td[97];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 289, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 192;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_96(norm, m);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        sp_3072_lshift_96(r, norm, y);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n\n            sp_3072_lshift_96(r, r, y);\n            sp_3072_mul_d_96(tmp, norm, r[96]);\n            r[96] = 0;\n            o = sp_3072_add_96(r, r, tmp);\n            sp_3072_cond_sub_96(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[96], 0, sizeof(sp_digit) * 96U);\n        sp_3072_mont_reduce_96(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_96(r, m) >= 0);\n        sp_3072_cond_sub_96(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* HAVE_FFDHE_3072 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 384 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[192], e[96], m[96];\n    sp_digit* r = b;\n    word32 i;\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 384) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 96, base);\n        sp_3072_from_bin(e, 96, exp, expLen);\n        sp_3072_from_mp(m, 96, mod);\n\n    #ifdef HAVE_FFDHE_3072\n        if (base->used == 1 && base->dp[0] == 2 && m[95] == (sp_digit)-1)\n            err = sp_3072_mod_exp_2_96(r, e, expLen * 8, m);\n        else\n    #endif\n            err = sp_3072_mod_exp_96(r, b, e, expLen * 8, m, 0);\n\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n        for (i=0; i<384 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[96], e[48], m[48];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1536) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 48, base);\n        sp_3072_from_mp(e, 48, exp);\n        sp_3072_from_mp(m, 48, mod);\n\n        err = sp_3072_mod_exp_48(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 48, 0, sizeof(*r) * 48U);\n        err = sp_3072_to_mp(r, res);\n        res->used = mod->used;\n        mp_clamp(res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_3072 */\n\n#ifdef WOLFSSL_SP_4096\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 24U) {\n            r[j] &= 0xffffffff;\n            s = 32U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 32\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 32\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffff;\n        s = 32U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 32U) <= (word32)DIGIT_BIT) {\n            s += 32U;\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 32) {\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 32 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 512\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_4096_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 4096 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<128 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 32) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 32);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_4096_add_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"add\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #100]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #108]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #116]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #124]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"add\t%[r], #0x80\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #100]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #108]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #116]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #124]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r7\"\n    );\n\n    return c;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_4096_sub_in_place_128(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sub\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr3, [%[a], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr6, [%[b], #68]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #64]\\n\\t\"\n        \"str\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr3, [%[a], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr6, [%[b], #76]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #72]\\n\\t\"\n        \"str\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr3, [%[a], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr6, [%[b], #84]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #80]\\n\\t\"\n        \"str\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr3, [%[a], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr6, [%[b], #92]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #88]\\n\\t\"\n        \"str\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr3, [%[a], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr6, [%[b], #100]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #96]\\n\\t\"\n        \"str\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr3, [%[a], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr6, [%[b], #108]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #104]\\n\\t\"\n        \"str\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr3, [%[a], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr6, [%[b], #116]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #112]\\n\\t\"\n        \"str\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr3, [%[a], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr6, [%[b], #124]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #120]\\n\\t\"\n        \"str\tr4, [%[a], #124]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr3, [%[a], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr6, [%[b], #68]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #64]\\n\\t\"\n        \"str\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr3, [%[a], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr6, [%[b], #76]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #72]\\n\\t\"\n        \"str\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr3, [%[a], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr6, [%[b], #84]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #80]\\n\\t\"\n        \"str\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr3, [%[a], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr6, [%[b], #92]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #88]\\n\\t\"\n        \"str\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr3, [%[a], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr6, [%[b], #100]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #96]\\n\\t\"\n        \"str\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr3, [%[a], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr6, [%[b], #108]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #104]\\n\\t\"\n        \"str\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr3, [%[a], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr6, [%[b], #116]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #112]\\n\\t\"\n        \"str\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr3, [%[a], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr6, [%[b], #124]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #120]\\n\\t\"\n        \"str\tr4, [%[a], #124]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr3, [%[a], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr6, [%[b], #68]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #64]\\n\\t\"\n        \"str\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr3, [%[a], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr6, [%[b], #76]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #72]\\n\\t\"\n        \"str\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr3, [%[a], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr6, [%[b], #84]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #80]\\n\\t\"\n        \"str\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr3, [%[a], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr6, [%[b], #92]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #88]\\n\\t\"\n        \"str\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr3, [%[a], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr6, [%[b], #100]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #96]\\n\\t\"\n        \"str\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr3, [%[a], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr6, [%[b], #108]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #104]\\n\\t\"\n        \"str\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr3, [%[a], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr6, [%[b], #116]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #112]\\n\\t\"\n        \"str\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr3, [%[a], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr6, [%[b], #124]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #120]\\n\\t\"\n        \"str\tr4, [%[a], #124]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"ldr\tr6, [%[b], #36]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"ldr\tr6, [%[b], #44]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"ldr\tr6, [%[b], #52]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"ldr\tr6, [%[b], #60]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr3, [%[a], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"ldr\tr6, [%[b], #68]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #64]\\n\\t\"\n        \"str\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr3, [%[a], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"ldr\tr6, [%[b], #76]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #72]\\n\\t\"\n        \"str\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr3, [%[a], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"ldr\tr6, [%[b], #84]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #80]\\n\\t\"\n        \"str\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr3, [%[a], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"ldr\tr6, [%[b], #92]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #88]\\n\\t\"\n        \"str\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr3, [%[a], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"ldr\tr6, [%[b], #100]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #96]\\n\\t\"\n        \"str\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr3, [%[a], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"ldr\tr6, [%[b], #108]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #104]\\n\\t\"\n        \"str\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr3, [%[a], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"ldr\tr6, [%[b], #116]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #112]\\n\\t\"\n        \"str\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr3, [%[a], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"ldr\tr6, [%[b], #124]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #120]\\n\\t\"\n        \"str\tr4, [%[a], #124]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr7, #0\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"add\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #100]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #108]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #116]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #124]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"add\t%[r], #0x80\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #100]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #108]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #116]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #124]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"add\t%[r], #0x80\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #100]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #108]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #116]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #124]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #0x80\\n\\t\"\n        \"add\t%[b], #0x80\\n\\t\"\n        \"add\t%[r], #0x80\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"ldr\tr5, [%[b], #32]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"ldr\tr5, [%[b], #36]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"ldr\tr5, [%[b], #40]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"ldr\tr5, [%[b], #44]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"ldr\tr5, [%[b], #48]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"ldr\tr5, [%[b], #52]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"ldr\tr5, [%[b], #56]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"ldr\tr5, [%[b], #60]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"ldr\tr4, [%[a], #64]\\n\\t\"\n        \"ldr\tr5, [%[b], #64]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"ldr\tr4, [%[a], #68]\\n\\t\"\n        \"ldr\tr5, [%[b], #68]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"ldr\tr4, [%[a], #72]\\n\\t\"\n        \"ldr\tr5, [%[b], #72]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #72]\\n\\t\"\n        \"ldr\tr4, [%[a], #76]\\n\\t\"\n        \"ldr\tr5, [%[b], #76]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #76]\\n\\t\"\n        \"ldr\tr4, [%[a], #80]\\n\\t\"\n        \"ldr\tr5, [%[b], #80]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #80]\\n\\t\"\n        \"ldr\tr4, [%[a], #84]\\n\\t\"\n        \"ldr\tr5, [%[b], #84]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #84]\\n\\t\"\n        \"ldr\tr4, [%[a], #88]\\n\\t\"\n        \"ldr\tr5, [%[b], #88]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #88]\\n\\t\"\n        \"ldr\tr4, [%[a], #92]\\n\\t\"\n        \"ldr\tr5, [%[b], #92]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #92]\\n\\t\"\n        \"ldr\tr4, [%[a], #96]\\n\\t\"\n        \"ldr\tr5, [%[b], #96]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #96]\\n\\t\"\n        \"ldr\tr4, [%[a], #100]\\n\\t\"\n        \"ldr\tr5, [%[b], #100]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #100]\\n\\t\"\n        \"ldr\tr4, [%[a], #104]\\n\\t\"\n        \"ldr\tr5, [%[b], #104]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #104]\\n\\t\"\n        \"ldr\tr4, [%[a], #108]\\n\\t\"\n        \"ldr\tr5, [%[b], #108]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #108]\\n\\t\"\n        \"ldr\tr4, [%[a], #112]\\n\\t\"\n        \"ldr\tr5, [%[b], #112]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #112]\\n\\t\"\n        \"ldr\tr4, [%[a], #116]\\n\\t\"\n        \"ldr\tr5, [%[b], #116]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #116]\\n\\t\"\n        \"ldr\tr4, [%[a], #120]\\n\\t\"\n        \"ldr\tr5, [%[b], #120]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #120]\\n\\t\"\n        \"ldr\tr4, [%[a], #124]\\n\\t\"\n        \"ldr\tr5, [%[b], #124]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #124]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r7\"\n    );\n\n    return c;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[64 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #252\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\t%[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# Multiply Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply Done\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\t%[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_4096_mask_64(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<64; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_128(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[128];\n    sp_digit a1[64];\n    sp_digit b1[64];\n    sp_digit z2[128];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_64(a1, a, &a[64]);\n    cb = sp_2048_add_64(b1, b, &b[64]);\n    u  = ca & cb;\n    sp_2048_mul_64(z1, a1, b1);\n    sp_2048_mul_64(z2, &a[64], &b[64]);\n    sp_2048_mul_64(z0, a, b);\n    sp_2048_mask_64(r + 128, a1, 0 - cb);\n    sp_2048_mask_64(b1, b1, 0 - ca);\n    u += sp_2048_add_64(r + 128, r + 128, b1);\n    u += sp_4096_sub_in_place_128(z1, z2);\n    u += sp_4096_sub_in_place_128(z1, z0);\n    u += sp_4096_add_128(r + 64, r + 64, z1);\n    r[192] = u;\n    XMEMSET(r + 192 + 1, 0, sizeof(sp_digit) * (64 - 1));\n    (void)sp_4096_add_128(r + 128, r + 128, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_64(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #252\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\tr2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"# Multiply * 2: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply * 2: Done\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"# Square: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r6\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"mul\tr7, r7\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #15\\n\\t\"\n        \"lsl\tr6, r6, #17\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Square: Done\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\tr2, #4\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #1\\n\\t\"\n        \"lsl\tr3, r3, #8\\n\\t\"\n        \"add\tr3, #252\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"sub\tr3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[128];\n    sp_digit z1[128];\n    sp_digit a1[64];\n    sp_digit u;\n\n    u = sp_2048_add_64(a1, a, &a[64]);\n    sp_2048_sqr_64(z1, a1);\n    sp_2048_sqr_64(z2, &a[64]);\n    sp_2048_sqr_64(z0, a);\n    sp_2048_mask_64(r + 128, a1, 0 - u);\n    u += sp_2048_add_64(r + 128, r + 128, r + 128);\n    u += sp_4096_sub_in_place_128(z1, z2);\n    u += sp_4096_sub_in_place_128(z1, z0);\n    u += sp_4096_add_128(r + 64, r + 64, z1);\n    r[192] = u;\n    XMEMSET(r + 192 + 1, 0, sizeof(sp_digit) * (64 - 1));\n    (void)sp_4096_add_128(r + 128, r + 128, z2);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"mov\tr4, #2\\n\\t\"\n        \"lsl\tr4, #8\\n\\t\"\n        \"sub\tr7, #1\\n\\t\"\n        \"add\tr6, r4\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"add\t%[b], #4\\n\\t\"\n        \"add\t%[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_4096_sub_in_place_128(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n    __asm__ __volatile__ (\n        \"mov\tr7, %[a]\\n\\t\"\n        \"mov\tr5, #2\\n\\t\"\n        \"lsl\tr5, #8\\n\\t\"\n        \"add\tr7, r5\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a]]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #8\\n\\t\"\n        \"add\t%[b], #8\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_128(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[128 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #252\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\t%[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# Multiply Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply Done\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\t%[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #3\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #252\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\tr2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"# Multiply * 2: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply * 2: Done\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"# Square: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r6\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"mul\tr7, r7\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #15\\n\\t\"\n        \"lsl\tr6, r6, #17\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Square: Done\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\tr2, #4\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #3\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #3\\n\\t\"\n        \"lsl\tr3, r3, #8\\n\\t\"\n        \"add\tr3, #252\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"sub\tr3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nSP_NOINLINE static void sp_4096_mul_d_128(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n    __asm__ __volatile__ (\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, %[a]\\n\\t\"\n        \"mov\tr8, %[r]\\n\\t\"\n        \"mov\tr9, r6\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"# A[] * B\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, %[b], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"lsr\tr7, %[b], #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, %[b], #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"lsl\tr7, %[b], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# A[] * B - Done\\n\\t\"\n        \"mov\t%[r], r8\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\t%[r], #4\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"mov\tr8, %[r]\\n\\t\"\n        \"cmp\t%[a], r9\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        : [r] \"+r\" (r), [a] \"+r\" (a)\n        : [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n}\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 4096 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_4096_mont_norm_128(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 128);\n\n    /* r = 2^n mod m */\n    sp_4096_sub_in_place_128(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nSP_NOINLINE static sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, sp_digit m)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr5, #2\\n\\t\"\n        \"lsl\tr5, r5, #8\\n\\t\"\n        \"mov\tr8, r5\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr6, [%[b], r7]\\n\\t\"\n        \"and\tr6, %[m]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr5, [%[a], r7]\\n\\t\"\n        \"sbc\tr5, r6\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"str\tr5, [%[r], r7]\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"cmp\tr7, r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n    return c;\n}\n\n/* Reduce the number back to 4096 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr8, %[mp]\\n\\t\"\n        \"mov\tr12, %[ca]\\n\\t\"\n        \"mov\tr14, %[m]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"# i = 0\\n\\t\"\n        \"mov\tr11, r4\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mov\t%[mp], r8\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mul\t%[mp], %[a]\\n\\t\"\n        \"mov\t%[m], r14\\n\\t\"\n        \"mov\tr10, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# a[i+j] += m[j] * mu\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"# Multiply m[j] and mu - Start\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr6, %[mp], #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\t%[a], r7\\n\\t\"\n        \"adc\tr5, %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\t%[a], r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr6, %[mp], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr5, r7\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\t%[a], r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"# Multiply m[j] and mu - Done\\n\\t\"\n        \"add\tr4, %[a]\\n\\t\"\n        \"adc\tr5, %[ca]\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"str\tr4, [%[a]]\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"add\t%[m], #4\\n\\t\"\n        \"add\tr10, r6\\n\\t\"\n        \"mov\tr4, #1\\n\\t\"\n        \"lsl\tr4, r4, #8\\n\\t\"\n        \"add\tr4, #252\\n\\t\"\n        \"add\tr4, r9\\n\\t\"\n        \"cmp\tr10, r4\\n\\t\"\n        \"blt\t2b\\n\\t\"\n        \"# a[i+127] += m[127] * mu\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"mov\tr4, r12\\n\\t\"\n        \"mov\t%[a], #0\\n\\t\"\n        \"# Multiply m[127] and mu - Start\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr6, %[mp], #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr5, r7\\n\\t\"\n        \"adc\tr4, %[ca]\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr6, %[mp], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"# Multiply m[127] and mu - Done\\n\\t\"\n        \"mov\t%[ca], %[a]\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"ldr\tr7, [%[a], #4]\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"add\tr5, %[a]\\n\\t\"\n        \"adc\tr7, r4\\n\\t\"\n        \"adc\t%[ca], r6\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"str\tr5, [%[a]]\\n\\t\"\n        \"str\tr7, [%[a], #4]\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"add\tr9, r6\\n\\t\"\n        \"add\tr11, r6\\n\\t\"\n        \"mov\tr12, %[ca]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\tr4, #2\\n\\t\"\n        \"lsl\tr4, r4, #8\\n\\t\"\n        \"cmp\tr11, r4\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"mov\t%[m], r14\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n\n    sp_4096_cond_sub_128(a - 128, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_4096_mul_128(r, a, b);\n    sp_4096_mont_reduce_128(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_sqr_128(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_4096_sqr_128(r, a);\n    sp_4096_mont_reduce_128(r, m, mp);\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nSP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr5, %[div], #1\\n\\t\"\n        \"add\tr5, #1\\n\\t\"\n        \"mov\tr8, %[d0]\\n\\t\"\n        \"mov\tr9, %[d1]\\n\\t\"\n        \"# Do top 32\\n\\t\"\n        \"mov\tr6, r5\\n\\t\"\n        \"sub\tr6, %[d1]\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        \"and\tr6, r5\\n\\t\"\n        \"sub\t%[d1], r6\\n\\t\"\n        \"# Next 30 bits\\n\\t\"\n        \"mov\tr4, #29\\n\\t\"\n        \"1:\\n\\t\"\n        \"lsl\t%[d0], %[d0], #1\\n\\t\"\n        \"adc\t%[d1], %[d1]\\n\\t\"\n        \"mov\tr6, r5\\n\\t\"\n        \"sub\tr6, %[d1]\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        \"and\tr6, r5\\n\\t\"\n        \"sub\t%[d1], r6\\n\\t\"\n        \"sub\tr4, #1\\n\\t\"\n        \"bpl\t1b\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"add\t%[r], #1\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"sub\t%[d1], r4\\n\\t\"\n        \"mov\tr4, %[d1]\\n\\t\"\n        \"mov\t%[d1], r9\\n\\t\"\n        \"sbc\t%[d1], r5\\n\\t\"\n        \"mov\tr5, %[d1]\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sub\tr4, %[d1], r4\\n\\t\"\n        \"sbc\tr6, r5\\n\\t\"\n        \"mov\tr5, r6\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sub\tr4, %[d1], r4\\n\\t\"\n        \"sbc\tr6, r5\\n\\t\"\n        \"mov\tr5, r6\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"mov\tr6, %[div]\\n\\t\"\n        \"sub\tr6, r4\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r7\", \"r6\", \"r8\", \"r9\"\n    );\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_4096_mask_128(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<128; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 128; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nSP_NOINLINE static int32_t sp_4096_cmp_128(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, #252\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr7, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr7, r3\\n\\t\"\n        \"and\tr5, r3\\n\\t\"\n        \"mov\tr4, r7\\n\\t\"\n        \"sub\tr7, r5\\n\\t\"\n        \"sbc\tr7, r7\\n\\t\"\n        \"add\t%[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r7\\n\\t\"\n        \"sub\tr5, r4\\n\\t\"\n        \"sbc\tr7, r7\\n\\t\"\n        \"sub\t%[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r7\\n\\t\"\n        \"sub\tr6, #4\\n\\t\"\n        \"cmp\tr6, #0\\n\\t\"\n        \"bge\t1b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_div_128(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[256], t2[129];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[127];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 128);\n    for (i=127; i>=0; i--) {\n        r1 = div_4096_word_128(t1[128 + i], t1[128 + i - 1], div);\n\n        sp_4096_mul_d_128(t2, d, r1);\n        t1[128 + i] += sp_4096_sub_in_place_128(&t1[i], t2);\n        t1[128 + i] -= t2[128];\n        sp_4096_mask_128(t2, d, t1[128 + i]);\n        t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], t2);\n        sp_4096_mask_128(t2, d, t1[128 + i]);\n        t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_4096_cmp_128(t1, d) >= 0;\n    sp_4096_cond_sub_128(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_mod_128(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_128(a, m, NULL, r);\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_div_128_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[256], t2[129];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[127];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 128);\n    for (i=127; i>=0; i--) {\n        r1 = div_4096_word_128(t1[128 + i], t1[128 + i - 1], div);\n\n        sp_4096_mul_d_128(t2, d, r1);\n        t1[128 + i] += sp_4096_sub_in_place_128(&t1[i], t2);\n        t1[128 + i] -= t2[128];\n        if (t1[128 + i] != 0) {\n            t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], d);\n            if (t1[128 + i] != 0)\n                t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_4096_cmp_128(t1, d) >= 0;\n    sp_4096_cond_sub_128(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_mod_128_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_128_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][256];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 256, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 256;\n        }\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_128(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 128U);\n        if (reduceA != 0) {\n            err = sp_4096_mod_128(t[1] + 128, a, m);\n            if (err == MP_OKAY) {\n                err = sp_4096_mod_128(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 128, a, sizeof(sp_digit) * 128);\n            err = sp_4096_mod_128(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_128(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_128(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_128(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_128(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_128(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_128(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_128(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_128(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_128(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_128(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_128(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_128(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_128(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_128(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 128);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n\n            sp_4096_mont_mul_128(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[128], 0, sizeof(sp_digit) * 128U);\n        sp_4096_mont_reduce_128(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_128(r, m) >= 0);\n        sp_4096_cond_sub_128(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][256];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 256, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 256;\n        }\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_128(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 128U);\n        if (reduceA != 0) {\n            err = sp_4096_mod_128(t[1] + 128, a, m);\n            if (err == MP_OKAY) {\n                err = sp_4096_mod_128(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 128, a, sizeof(sp_digit) * 128);\n            err = sp_4096_mod_128(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_128(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_128(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_128(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_128(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_128(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_128(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_128(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_128(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_128(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_128(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_128(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_128(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_128(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_128(t[15], t[ 8], t[ 7], m, mp);\n        sp_4096_mont_sqr_128(t[16], t[ 8], m, mp);\n        sp_4096_mont_mul_128(t[17], t[ 9], t[ 8], m, mp);\n        sp_4096_mont_sqr_128(t[18], t[ 9], m, mp);\n        sp_4096_mont_mul_128(t[19], t[10], t[ 9], m, mp);\n        sp_4096_mont_sqr_128(t[20], t[10], m, mp);\n        sp_4096_mont_mul_128(t[21], t[11], t[10], m, mp);\n        sp_4096_mont_sqr_128(t[22], t[11], m, mp);\n        sp_4096_mont_mul_128(t[23], t[12], t[11], m, mp);\n        sp_4096_mont_sqr_128(t[24], t[12], m, mp);\n        sp_4096_mont_mul_128(t[25], t[13], t[12], m, mp);\n        sp_4096_mont_sqr_128(t[26], t[13], m, mp);\n        sp_4096_mont_mul_128(t[27], t[14], t[13], m, mp);\n        sp_4096_mont_sqr_128(t[28], t[14], m, mp);\n        sp_4096_mont_mul_128(t[29], t[15], t[14], m, mp);\n        sp_4096_mont_sqr_128(t[30], t[15], m, mp);\n        sp_4096_mont_mul_128(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 128);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n\n            sp_4096_mont_mul_128(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[128], 0, sizeof(sp_digit) * 128U);\n        sp_4096_mont_reduce_128(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_128(r, m) >= 0);\n        sp_4096_cond_sub_128(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[256], md[128], rd[256];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1];\n    int err = MP_OKAY;\n\n    if (*outLen < 512)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 32 || inLen > 512 ||\n                                                     mp_count_bits(mm) != 4096))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 128 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 128 * 2;\n        m = r + 128 * 2;\n        ah = a + 128;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 128;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(ah, 128, in, inLen);\n#if DIGIT_BIT >= 32\n        e[0] = em->dp[0];\n#else\n        e[0] = em->dp[0];\n        if (em->used > 1)\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e[0] == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(m, 128, mm);\n\n        if (e[0] == 0x3) {\n            if (err == MP_OKAY) {\n                sp_4096_sqr_128(r, ah);\n                err = sp_4096_mod_128_cond(r, r, m);\n            }\n            if (err == MP_OKAY) {\n                sp_4096_mul_128(r, ah, r);\n                err = sp_4096_mod_128_cond(r, r, m);\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_4096_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 128);\n            err = sp_4096_mod_128_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=31; i>=0; i--)\n                    if (e[0] >> i)\n                        break;\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 128);\n                for (i--; i>=0; i--) {\n                    sp_4096_mont_sqr_128(r, r, m, mp);\n                    if (((e[0] >> i) & 1) == 1)\n                        sp_4096_mont_mul_128(r, r, a, m, mp);\n                }\n                XMEMSET(&r[128], 0, sizeof(sp_digit) * 128);\n                sp_4096_mont_reduce_128(r, m, mp);\n\n                for (i = 127; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_4096_sub_in_place_128(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[128 * 2];\n    sp_digit pd[64], qd[64], dpd[64];\n    sp_digit tmpad[128], tmpbd[128];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 512)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 512 || mp_count_bits(mm) != 4096))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 64 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 128 * 2;\n        q = p + 64;\n        qi = dq = dp = q + 64;\n        tmpa = qi + 64;\n        tmpb = tmpa + 128;\n\n        tmp = t;\n        r = tmp + 128;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 128;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(a, 128, in, inLen);\n        sp_4096_from_mp(p, 64, pm);\n        sp_4096_from_mp(q, 64, qm);\n        sp_4096_from_mp(dp, 64, dpm);\n\n        err = sp_4096_mod_exp_64(tmpa, a, dp, 2048, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(dq, 64, dqm);\n        err = sp_4096_mod_exp_64(tmpb, a, dq, 2048, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_4096_sub_in_place_64(tmpa, tmpb);\n        sp_4096_mask_64(tmp, p, c);\n        sp_4096_add_64(tmpa, tmpa, tmp);\n\n        sp_4096_from_mp(qi, 64, qim);\n        sp_4096_mul_64(tmpa, tmpa, qi);\n        err = sp_4096_mod_64(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mul_64(tmpa, q, tmpa);\n        XMEMSET(&tmpb[64], 0, sizeof(sp_digit) * 64);\n        sp_4096_add_128(r, tmpb, tmpa);\n\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 64 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_4096_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (4096 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 32\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 128);\n        r->used = 128;\n        mp_clamp(r);\n#elif DIGIT_BIT < 32\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 128; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 32) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 32 - s;\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 128; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 32 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 32 - s;\n            }\n            else {\n                s += 32;\n            }\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[256], e[128], m[128];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 128, base);\n        sp_4096_from_mp(e, 128, exp);\n        sp_4096_from_mp(m, 128, mod);\n\n        err = sp_4096_mod_exp_128(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_4096_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_4096\nstatic void sp_4096_lshift_128(sp_digit* r, sp_digit* a, byte n)\n{\n    __asm__ __volatile__ (\n        \"mov\tr6, #31\\n\\t\"\n        \"sub\tr6, r6, %[n]\\n\\t\"\n        \"add\t%[a], %[a], #255\\n\\t\"\n        \"add\t%[r], %[r], #255\\n\\t\"\n        \"add\t%[a], %[a], #193\\n\\t\"\n        \"add\t%[r], %[r], #193\\n\\t\"\n        \"ldr\tr3, [%[a], #60]\\n\\t\"\n        \"lsr\tr4, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr4, r4, r6\\n\\t\"\n        \"ldr\tr2, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr2, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #44]\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr2, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr2, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #12]\\n\\t\"\n        \"str\tr2, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr2, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr2, [%[a], #60]\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr3, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr2, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"str\tr3, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr2, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #28]\\n\\t\"\n        \"str\tr2, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"str\tr3, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr2, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #12]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr2, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"str\tr3, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr2, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #52]\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"str\tr3, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #44]\\n\\t\"\n        \"str\tr2, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"str\tr3, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr2, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #28]\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr3, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr2, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"str\tr3, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr2, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr3, [%[a], #60]\\n\\t\"\n        \"str\tr2, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr2, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #44]\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr2, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr2, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #12]\\n\\t\"\n        \"str\tr2, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr2, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr2, [%[a], #60]\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr3, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr2, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"str\tr3, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr2, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #28]\\n\\t\"\n        \"str\tr2, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"str\tr3, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr2, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #12]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr2, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr4, [%[a], #60]\\n\\t\"\n        \"str\tr3, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #56]\\n\\t\"\n        \"str\tr2, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #52]\\n\\t\"\n        \"str\tr4, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #48]\\n\\t\"\n        \"str\tr3, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #44]\\n\\t\"\n        \"str\tr2, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #40]\\n\\t\"\n        \"str\tr4, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #36]\\n\\t\"\n        \"str\tr3, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #32]\\n\\t\"\n        \"str\tr2, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #28]\\n\\t\"\n        \"str\tr4, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"str\tr3, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #20]\\n\\t\"\n        \"str\tr2, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"str\tr3, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr2, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #4]\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"str\tr3, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr3, [%[a], #60]\\n\\t\"\n        \"str\tr2, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #56]\\n\\t\"\n        \"str\tr4, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #52]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #48]\\n\\t\"\n        \"str\tr2, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #44]\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #40]\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #36]\\n\\t\"\n        \"str\tr2, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #32]\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr2, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #20]\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"str\tr3, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #12]\\n\\t\"\n        \"str\tr2, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"str\tr3, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr2, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"sub\t%[a], %[a], #64\\n\\t\"\n        \"sub\t%[r], %[r], #64\\n\\t\"\n        \"ldr\tr2, [%[a], #60]\\n\\t\"\n        \"str\tr4, [%[r], #68]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #56]\\n\\t\"\n        \"str\tr3, [%[r], #64]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #52]\\n\\t\"\n        \"str\tr2, [%[r], #60]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #48]\\n\\t\"\n        \"str\tr4, [%[r], #56]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #44]\\n\\t\"\n        \"str\tr3, [%[r], #52]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #40]\\n\\t\"\n        \"str\tr2, [%[r], #48]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #36]\\n\\t\"\n        \"str\tr4, [%[r], #44]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #32]\\n\\t\"\n        \"str\tr3, [%[r], #40]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #28]\\n\\t\"\n        \"str\tr2, [%[r], #36]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[r], #32]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"str\tr3, [%[r], #28]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr2, [%[r], #24]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #12]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"lsr\tr5, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr2, r2, r5\\n\\t\"\n        \"ldr\tr3, [%[a], #4]\\n\\t\"\n        \"str\tr2, [%[r], #12]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr4, r4, r5\\n\\t\"\n        \"ldr\tr2, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"lsr\tr5, r2, #1\\n\\t\"\n        \"lsl\tr2, r2, %[n]\\n\\t\"\n        \"lsr\tr5, r5, r6\\n\\t\"\n        \"orr\tr3, r3, r5\\n\\t\"\n        \"str\tr2, [%[r]]\\n\\t\"\n        \"str\tr3, [%[r], #4]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [n] \"r\" (n)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[256];\n    sp_digit td[129];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 385, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 256;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_128(norm, m);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        sp_4096_lshift_128(r, norm, y);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n\n            sp_4096_lshift_128(r, r, y);\n            sp_4096_mul_d_128(tmp, norm, r[128]);\n            r[128] = 0;\n            o = sp_4096_add_128(r, r, tmp);\n            sp_4096_cond_sub_128(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[128], 0, sizeof(sp_digit) * 128U);\n        sp_4096_mont_reduce_128(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_128(r, m) >= 0);\n        sp_4096_cond_sub_128(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* HAVE_FFDHE_4096 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 512 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[256], e[128], m[128];\n    sp_digit* r = b;\n    word32 i;\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 512) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 128, base);\n        sp_4096_from_bin(e, 128, exp, expLen);\n        sp_4096_from_mp(m, 128, mod);\n\n    #ifdef HAVE_FFDHE_4096\n        if (base->used == 1 && base->dp[0] == 2 && m[127] == (sp_digit)-1)\n            err = sp_4096_mod_exp_2_128(r, e, expLen * 8, m);\n        else\n    #endif\n            err = sp_4096_mod_exp_128(r, b, e, expLen * 8, m, 0);\n\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n        for (i=0; i<512 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* WOLFSSL_SP_4096 */\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n#ifdef WOLFSSL_HAVE_SP_ECC\n#ifndef WOLFSSL_SP_NO_256\n\n/* Point structure to use. */\ntypedef struct sp_point {\n    sp_digit x[2 * 8];\n    sp_digit y[2 * 8];\n    sp_digit z[2 * 8];\n    int infinity;\n} sp_point;\n\n/* The modulus (prime) of the curve P256. */\nstatic const sp_digit p256_mod[8] = {\n    0xffffffff,0xffffffff,0xffffffff,0x00000000,0x00000000,0x00000000,\n    0x00000001,0xffffffff\n};\n/* The Montogmery normalizer for modulus of the curve P256. */\nstatic const sp_digit p256_norm_mod[8] = {\n    0x00000001,0x00000000,0x00000000,0xffffffff,0xffffffff,0xffffffff,\n    0xfffffffe,0x00000000\n};\n/* The Montogmery multiplier for modulus of the curve P256. */\nstatic const sp_digit p256_mp_mod = 0x00000001;\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                            defined(HAVE_ECC_VERIFY)\n/* The order of the curve P256. */\nstatic const sp_digit p256_order[8] = {\n    0xfc632551,0xf3b9cac2,0xa7179e84,0xbce6faad,0xffffffff,0xffffffff,\n    0x00000000,0xffffffff\n};\n#endif\n/* The order of the curve P256 minus 2. */\nstatic const sp_digit p256_order2[8] = {\n    0xfc63254f,0xf3b9cac2,0xa7179e84,0xbce6faad,0xffffffff,0xffffffff,\n    0x00000000,0xffffffff\n};\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery normalizer for order of the curve P256. */\nstatic const sp_digit p256_norm_order[8] = {\n    0x039cdaaf,0x0c46353d,0x58e8617b,0x43190552,0x00000000,0x00000000,\n    0xffffffff,0x00000000\n};\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery multiplier for order of the curve P256. */\nstatic const sp_digit p256_mp_order = 0xee00bc4f;\n#endif\n/* The base point of curve P256. */\nstatic const sp_point p256_base = {\n    /* X ordinate */\n    {\n        0xd898c296,0xf4a13945,0x2deb33a0,0x77037d81,0x63a440f2,0xf8bce6e5,\n        0xe12c4247,0x6b17d1f2, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L\n    },\n    /* Y ordinate */\n    {\n        0x37bf51f5,0xcbb64068,0x6b315ece,0x2bce3357,0x7c0f9e16,0x8ee7eb4a,\n        0xfe1a7f9b,0x4fe342e2, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L\n    },\n    /* Z ordinate */\n    {\n        0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,\n        0x00000000,0x00000000, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L\n    },\n    /* infinity */\n    0\n};\n#if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)\nstatic const sp_digit p256_b[8] = {\n    0x27d2604b,0x3bce3c3e,0xcc53b0f6,0x651d06b0,0x769886bc,0xb3ebbd55,\n    0xaa3a93e7,0x5ac635d8\n};\n#endif\n\nstatic int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p)\n{\n    int ret = MP_OKAY;\n    (void)heap;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    (void)sp;\n    *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC);\n#else\n    *p = sp;\n#endif\n    if (p == NULL) {\n        ret = MEMORY_E;\n    }\n    return ret;\n}\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* Allocate memory for point and return error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p))\n#else\n/* Set pointer to data and return no error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p))\n#endif\n\n\nstatic void sp_ecc_point_free(sp_point* p, int clear, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* If valid pointer then clear point data if requested and free data. */\n    if (p != NULL) {\n        if (clear != 0) {\n            XMEMSET(p, 0, sizeof(*p));\n        }\n        XFREE(p, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n/* Clear point data if requested. */\n    if (clear != 0) {\n        XMEMSET(p, 0, sizeof(*p));\n    }\n#endif\n    (void)heap;\n}\n\n/* Multiply a number by Montogmery normalizer mod modulus (prime).\n *\n * r  The resulting Montgomery form number.\n * a  The number to convert.\n * m  The modulus (prime).\n */\nstatic int sp_256_mod_mul_norm_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    int64_t t[8];\n    int64_t a64[8];\n    int64_t o;\n\n    (void)m;\n\n    a64[0] = a[0];\n    a64[1] = a[1];\n    a64[2] = a[2];\n    a64[3] = a[3];\n    a64[4] = a[4];\n    a64[5] = a[5];\n    a64[6] = a[6];\n    a64[7] = a[7];\n\n    /*  1  1  0 -1 -1 -1 -1  0 */\n    t[0] = 0 + a64[0] + a64[1] - a64[3] - a64[4] - a64[5] - a64[6];\n    /*  0  1  1  0 -1 -1 -1 -1 */\n    t[1] = 0 + a64[1] + a64[2] - a64[4] - a64[5] - a64[6] - a64[7];\n    /*  0  0  1  1  0 -1 -1 -1 */\n    t[2] = 0 + a64[2] + a64[3] - a64[5] - a64[6] - a64[7];\n    /* -1 -1  0  2  2  1  0 -1 */\n    t[3] = 0 - a64[0] - a64[1] + 2 * a64[3] + 2 * a64[4] + a64[5] - a64[7];\n    /*  0 -1 -1  0  2  2  1  0 */\n    t[4] = 0 - a64[1] - a64[2] + 2 * a64[4] + 2 * a64[5] + a64[6];\n    /*  0  0 -1 -1  0  2  2  1 */\n    t[5] = 0 - a64[2] - a64[3] + 2 * a64[5] + 2 * a64[6] + a64[7];\n    /* -1 -1  0  0  0  1  3  2 */\n    t[6] = 0 - a64[0] - a64[1] + a64[5] + 3 * a64[6] + 2 * a64[7];\n    /*  1  0 -1 -1 -1 -1  0  3 */\n    t[7] = 0 + a64[0] - a64[2] - a64[3] - a64[4] - a64[5] + 3 * a64[7];\n\n    t[1] += t[0] >> 32; t[0] &= 0xffffffff;\n    t[2] += t[1] >> 32; t[1] &= 0xffffffff;\n    t[3] += t[2] >> 32; t[2] &= 0xffffffff;\n    t[4] += t[3] >> 32; t[3] &= 0xffffffff;\n    t[5] += t[4] >> 32; t[4] &= 0xffffffff;\n    t[6] += t[5] >> 32; t[5] &= 0xffffffff;\n    t[7] += t[6] >> 32; t[6] &= 0xffffffff;\n    o     = t[7] >> 32; t[7] &= 0xffffffff;\n    t[0] += o;\n    t[3] -= o;\n    t[6] -= o;\n    t[7] += o;\n    t[1] += t[0] >> 32; t[0] &= 0xffffffff;\n    t[2] += t[1] >> 32; t[1] &= 0xffffffff;\n    t[3] += t[2] >> 32; t[2] &= 0xffffffff;\n    t[4] += t[3] >> 32; t[3] &= 0xffffffff;\n    t[5] += t[4] >> 32; t[4] &= 0xffffffff;\n    t[6] += t[5] >> 32; t[5] &= 0xffffffff;\n    t[7] += t[6] >> 32; t[6] &= 0xffffffff;\n    r[0] = t[0];\n    r[1] = t[1];\n    r[2] = t[2];\n    r[3] = t[3];\n    r[4] = t[4];\n    r[5] = t[5];\n    r[6] = t[6];\n    r[7] = t[7];\n\n    return MP_OKAY;\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_256_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 32\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 32\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffff;\n        s = 32U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 32U) <= (word32)DIGIT_BIT) {\n            s += 32U;\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 32) {\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 32 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Convert a point of type ecc_point to type sp_point.\n *\n * p   Point of type sp_point (result).\n * pm  Point of type ecc_point.\n */\nstatic void sp_256_point_from_ecc_point_8(sp_point* p, const ecc_point* pm)\n{\n    XMEMSET(p->x, 0, sizeof(p->x));\n    XMEMSET(p->y, 0, sizeof(p->y));\n    XMEMSET(p->z, 0, sizeof(p->z));\n    sp_256_from_mp(p->x, 8, pm->x);\n    sp_256_from_mp(p->y, 8, pm->y);\n    sp_256_from_mp(p->z, 8, pm->z);\n    p->infinity = 0;\n}\n\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_256_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 32\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 8);\n        r->used = 8;\n        mp_clamp(r);\n#elif DIGIT_BIT < 32\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 8; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 32) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 32 - s;\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 8; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 32 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 32 - s;\n            }\n            else {\n                s += 32;\n            }\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Convert a point of type sp_point to type ecc_point.\n *\n * p   Point of type sp_point.\n * pm  Point of type ecc_point (result).\n * returns MEMORY_E when allocation of memory in ecc_point fails otherwise\n * MP_OKAY.\n */\nstatic int sp_256_point_to_ecc_point_8(const sp_point* p, ecc_point* pm)\n{\n    int err;\n\n    err = sp_256_to_mp(p->x, pm->x);\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pm->y);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pm->z);\n    }\n\n    return err;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nSP_NOINLINE static int32_t sp_256_cmp_8(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr6, #28\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr7, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr7, r3\\n\\t\"\n        \"and\tr5, r3\\n\\t\"\n        \"mov\tr4, r7\\n\\t\"\n        \"sub\tr7, r5\\n\\t\"\n        \"sbc\tr7, r7\\n\\t\"\n        \"add\t%[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r7\\n\\t\"\n        \"sub\tr5, r4\\n\\t\"\n        \"sbc\tr7, r7\\n\\t\"\n        \"sub\t%[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r7\\n\\t\"\n        \"sub\tr6, #4\\n\\t\"\n        \"cmp\tr6, #0\\n\\t\"\n        \"bge\t1b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return r;\n}\n\n/* Normalize the values in each word to 32.\n *\n * a  Array of sp_digit to normalize.\n */\n#define sp_256_norm_8(a)\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nSP_NOINLINE static sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, sp_digit m)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr5, #32\\n\\t\"\n        \"mov\tr8, r5\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"ldr\tr6, [%[b], r7]\\n\\t\"\n        \"and\tr6, %[m]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr5, [%[a], r7]\\n\\t\"\n        \"sbc\tr5, r6\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"str\tr5, [%[r], r7]\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"cmp\tr7, r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n    return c;\n}\n\n/* Reduce the number back to 256 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    (void)mp;\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr1, #0\\n\\t\"\n        \"# i = 0\\n\\t\"\n        \"mov\tr8, r2\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"# mu = a[i] * 1 (mp) = a[i]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"# a[i+0] += -1 * mu\\n\\t\"\n        \"mov\tr5, r3\\n\\t\"\n        \"str\tr4, [%[a], #0]\\n\\t\"\n        \"# a[i+1] += -1 * mu\\n\\t\"\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"mov\tr4, r3\\n\\t\"\n        \"sub\tr5, r3\\n\\t\"\n        \"sbc\tr4, r2\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r2\\n\\t\"\n        \"str\tr5, [%[a], #4]\\n\\t\"\n        \"# a[i+2] += -1 * mu\\n\\t\"\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"mov\tr5, r3\\n\\t\"\n        \"sub\tr4, r3\\n\\t\"\n        \"sbc\tr5, r2\\n\\t\"\n        \"add\tr4, r6\\n\\t\"\n        \"adc\tr5, r2\\n\\t\"\n        \"str\tr4, [%[a], #8]\\n\\t\"\n        \"# a[i+3] += 0 * mu\\n\\t\"\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r2\\n\\t\"\n        \"str\tr5, [%[a], #12]\\n\\t\"\n        \"# a[i+4] += 0 * mu\\n\\t\"\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr4, r6\\n\\t\"\n        \"adc\tr5, r2\\n\\t\"\n        \"str\tr4, [%[a], #16]\\n\\t\"\n        \"# a[i+5] += 0 * mu\\n\\t\"\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r2\\n\\t\"\n        \"str\tr5, [%[a], #20]\\n\\t\"\n        \"# a[i+6] += 1 * mu\\n\\t\"\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr4, r3\\n\\t\"\n        \"adc\tr5, r2\\n\\t\"\n        \"add\tr4, r6\\n\\t\"\n        \"adc\tr5, r2\\n\\t\"\n        \"str\tr4, [%[a], #24]\\n\\t\"\n        \"# a[i+7] += -1 * mu\\n\\t\"\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[a], #32]\\n\\t\"\n        \"add\tr4, r1, r3\\n\\t\"\n        \"mov\tr1, #0\\n\\t\"\n        \"adc\tr1, r2\\n\\t\"\n        \"sub\tr5, r3\\n\\t\"\n        \"sbc\tr4, r2\\n\\t\"\n        \"sbc\tr1, r2\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr1, r2\\n\\t\"\n        \"str\tr5, [%[a],  #28]\\n\\t\"\n        \"str\tr4, [%[a], #32]\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"add\tr8, r6\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"mov\tr6, #32\\n\\t\"\n        \"cmp\tr8, r6\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"sub\t%[a], #32\\n\\t\"\n        \"mov\tr3, r1\\n\\t\"\n        \"sub\tr1, #1\\n\\t\"\n        \"mvn\tr1, r1\\n\\t\"\n        \"ldr\tr5, [%[a],#32]\\n\\t\"\n        \"ldr\tr4, [%[a],#36]\\n\\t\"\n        \"ldr\tr6, [%[a],#40]\\n\\t\"\n        \"ldr\tr7, [%[a],#44]\\n\\t\"\n        \"sub\tr5, r1\\n\\t\"\n        \"sbc\tr4, r1\\n\\t\"\n        \"sbc\tr6, r1\\n\\t\"\n        \"sbc\tr7, r2\\n\\t\"\n        \"str\tr5, [%[a],#0]\\n\\t\"\n        \"str\tr4, [%[a],#4]\\n\\t\"\n        \"str\tr6, [%[a],#8]\\n\\t\"\n        \"str\tr7, [%[a],#12]\\n\\t\"\n        \"ldr\tr5, [%[a],#48]\\n\\t\"\n        \"ldr\tr4, [%[a],#52]\\n\\t\"\n        \"ldr\tr6, [%[a],#56]\\n\\t\"\n        \"ldr\tr7, [%[a],#60]\\n\\t\"\n        \"sbc\tr5, r2\\n\\t\"\n        \"sbc\tr4, r2\\n\\t\"\n        \"sbc\tr6, r3\\n\\t\"\n        \"sbc\tr7, r1\\n\\t\"\n        \"str\tr5, [%[a],#16]\\n\\t\"\n        \"str\tr4, [%[a],#20]\\n\\t\"\n        \"str\tr6, [%[a],#24]\\n\\t\"\n        \"str\tr7, [%[a],#28]\\n\\t\"\n        : [a] \"+r\" (a)\n        :\n        : \"memory\", \"r1\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n\n    (void)m;\n    (void)mp;\n}\n\n/* Reduce the number back to 256 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr8, %[mp]\\n\\t\"\n        \"mov\tr12, %[ca]\\n\\t\"\n        \"mov\tr14, %[m]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"# i = 0\\n\\t\"\n        \"mov\tr11, r4\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"# mu = a[i] * mp\\n\\t\"\n        \"mov\t%[mp], r8\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mul\t%[mp], %[a]\\n\\t\"\n        \"mov\t%[m], r14\\n\\t\"\n        \"mov\tr10, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# a[i+j] += m[j] * mu\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"# Multiply m[j] and mu - Start\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr6, %[mp], #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\t%[a], r7\\n\\t\"\n        \"adc\tr5, %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\t%[a], r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr6, %[mp], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr5, r7\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\t%[a], r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"# Multiply m[j] and mu - Done\\n\\t\"\n        \"add\tr4, %[a]\\n\\t\"\n        \"adc\tr5, %[ca]\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"str\tr4, [%[a]]\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"add\t%[m], #4\\n\\t\"\n        \"add\tr10, r6\\n\\t\"\n        \"mov\tr4, #28\\n\\t\"\n        \"add\tr4, r9\\n\\t\"\n        \"cmp\tr10, r4\\n\\t\"\n        \"blt\t2b\\n\\t\"\n        \"# a[i+7] += m[7] * mu\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        \"mov\tr4, r12\\n\\t\"\n        \"mov\t%[a], #0\\n\\t\"\n        \"# Multiply m[7] and mu - Start\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr6, %[mp], #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr5, r7\\n\\t\"\n        \"adc\tr4, %[ca]\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsr\tr6, %[mp], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\t%[a], %[ca]\\n\\t\"\n        \"# Multiply m[7] and mu - Done\\n\\t\"\n        \"mov\t%[ca], %[a]\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"ldr\tr7, [%[a], #4]\\n\\t\"\n        \"ldr\t%[a], [%[a]]\\n\\t\"\n        \"mov\tr6, #0\\n\\t\"\n        \"add\tr5, %[a]\\n\\t\"\n        \"adc\tr7, r4\\n\\t\"\n        \"adc\t%[ca], r6\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"str\tr5, [%[a]]\\n\\t\"\n        \"str\tr7, [%[a], #4]\\n\\t\"\n        \"# i += 1\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"add\tr9, r6\\n\\t\"\n        \"add\tr11, r6\\n\\t\"\n        \"mov\tr12, %[ca]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\tr4, #32\\n\\t\"\n        \"cmp\tr11, r4\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"mov\t%[m], r14\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n\n    sp_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[8 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #32\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #28\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\t%[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"# Multiply Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply Done\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\t%[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #56\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_256_mul_8(r, a, b);\n    sp_256_mont_reduce_8(r, m, mp);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_256_sqr_8(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #64\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #28\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"sub\t%[a], r6\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, %[a]\\n\\t\"\n        \"add\t%[a], r9\\n\\t\"\n        \"add\tr2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        \"# Multiply * 2: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"lsl\tr7, r7, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Multiply * 2: Done\\n\\t\"\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"# Square: Start\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r6\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"mul\tr7, r7\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #15\\n\\t\"\n        \"lsl\tr6, r6, #17\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# Square: Done\\n\\t\"\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"sub\tr2, #4\\n\\t\"\n        \"mov\tr6, #32\\n\\t\"\n        \"add\tr6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #56\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #60\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"sub\tr3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #64\\n\\t\"\n        \"add\tsp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_256_sqr_8(r, a);\n    sp_256_mont_reduce_8(r, m, mp);\n}\n\n#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)\n/* Square the Montgomery form number a number of times. (r = a ^ n mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * n   Number of times to square.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_sqr_n_8(sp_digit* r, const sp_digit* a, int n,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_256_mont_sqr_8(r, a, m, mp);\n    for (; n > 1; n--) {\n        sp_256_mont_sqr_8(r, r, m, mp);\n    }\n}\n\n#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */\n#ifdef WOLFSSL_SP_SMALL\n/* Mod-2 for the P256 curve. */\nstatic const uint32_t p256_mod_2[8] = {\n    0xfffffffdU,0xffffffffU,0xffffffffU,0x00000000U,0x00000000U,0x00000000U,\n    0x00000001U,0xffffffffU\n};\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the modulus (prime) of the\n * P256 curve. (r = 1 / a mod m)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_8(sp_digit* r, const sp_digit* a, sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 8);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_8(t, t, p256_mod, p256_mp_mod);\n        if (p256_mod_2[i / 32] & ((sp_digit)1 << (i % 32)))\n            sp_256_mont_mul_8(t, t, a, p256_mod, p256_mp_mod);\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 8);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 8;\n    sp_digit* t3 = td + 4 * 8;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_8(t, a, p256_mod, p256_mp_mod);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_8(t, t, a, p256_mod, p256_mp_mod);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_8(t2, t, 2, p256_mod, p256_mp_mod);\n    /* t3= a^d = t2 * a */\n    sp_256_mont_mul_8(t3, t2, a, p256_mod, p256_mp_mod);\n    /* t = a^f = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^f0 = t ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_8(t2, t, 4, p256_mod, p256_mp_mod);\n    /* t3= a^fd = t2 * t3 */\n    sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ff = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_8(t2, t, 8, p256_mod, p256_mp_mod);\n    /* t3= a^fffd = t2 * t3 */\n    sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_8(t2, t, 16, p256_mod, p256_mp_mod);\n    /* t3= a^fffffffd = t2 * t3 */\n    sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff00000000 = t ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_8(t2, t, 32, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001 = t2 * a */\n    sp_256_mont_mul_8(t2, t2, a, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff000000010000000000000000000000000000000000000000\n     *   = t2 ^ 2 ^ 160 */\n    sp_256_mont_sqr_n_8(t2, t2, 160, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff\n     *   = t2 * t */\n    sp_256_mont_mul_8(t2, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000\n     *   = t2 ^ 2 ^ 32 */\n    sp_256_mont_sqr_n_8(t2, t2, 32, p256_mod, p256_mp_mod);\n    /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd\n     *   = t2 * t3 */\n    sp_256_mont_mul_8(r, t2, t3, p256_mod, p256_mp_mod);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Map the Montgomery form projective co-ordinate point to an affine point.\n *\n * r  Resulting affine co-ordinate point.\n * p  Montgomery form projective co-ordinate point.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_map_8(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*8;\n    int32_t n;\n\n    sp_256_mont_inv_8(t1, p->z, t + 2*8);\n\n    sp_256_mont_sqr_8(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_8(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    /* x /= z^2 */\n    sp_256_mont_mul_8(r->x, p->x, t2, p256_mod, p256_mp_mod);\n    XMEMSET(r->x + 8, 0, sizeof(r->x) / 2U);\n    sp_256_mont_reduce_8(r->x, p256_mod, p256_mp_mod);\n    /* Reduce x to less than modulus */\n    n = sp_256_cmp_8(r->x, p256_mod);\n    sp_256_cond_sub_8(r->x, r->x, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_8(r->x);\n\n    /* y /= z^3 */\n    sp_256_mont_mul_8(r->y, p->y, t1, p256_mod, p256_mp_mod);\n    XMEMSET(r->y + 8, 0, sizeof(r->y) / 2U);\n    sp_256_mont_reduce_8(r->y, p256_mod, p256_mp_mod);\n    /* Reduce y to less than modulus */\n    n = sp_256_cmp_8(r->y, p256_mod);\n    sp_256_cond_sub_8(r->y, r->y, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_8(r->y);\n\n    XMEMSET(r->z, 0, sizeof(r->z));\n    r->z[0] = 1;\n\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\tr6, #32\\n\\t\"\n        \"sub\tr7, #1\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"add\t%[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"add\t%[b], #4\\n\\t\"\n        \"add\t%[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#else\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"add\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #4]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #12]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #20]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #28]\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r], #28]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Add two Montgomery form numbers (r = a + b % m).\n *\n * r   Result of addition.\n * a   First number to add in Montogmery form.\n * b   Second number to add in Montogmery form.\n * m   Modulus (prime).\n */\nSP_NOINLINE static void sp_256_mont_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m)\n{\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"ldr\tr4, [%[a],#0]\\n\\t\"\n        \"ldr\tr5, [%[a],#4]\\n\\t\"\n        \"ldr\tr6, [%[b],#0]\\n\\t\"\n        \"ldr\tr7, [%[b],#4]\\n\\t\"\n        \"add\tr4, r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"ldr\tr4, [%[a],#8]\\n\\t\"\n        \"ldr\tr5, [%[a],#12]\\n\\t\"\n        \"ldr\tr6, [%[b],#8]\\n\\t\"\n        \"ldr\tr7, [%[b],#12]\\n\\t\"\n        \"adc\tr4, r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"str\tr4, [%[r],#8]\\n\\t\"\n        \"str\tr5, [%[r],#12]\\n\\t\"\n        \"ldr\tr4, [%[a],#16]\\n\\t\"\n        \"ldr\tr5, [%[a],#20]\\n\\t\"\n        \"ldr\tr6, [%[b],#16]\\n\\t\"\n        \"ldr\tr7, [%[b],#20]\\n\\t\"\n        \"adc\tr4, r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"mov\tr8, r4\\n\\t\"\n        \"mov\tr9, r5\\n\\t\"\n        \"ldr\tr4, [%[a],#24]\\n\\t\"\n        \"ldr\tr5, [%[a],#28]\\n\\t\"\n        \"ldr\tr6, [%[b],#24]\\n\\t\"\n        \"ldr\tr7, [%[b],#28]\\n\\t\"\n        \"adc\tr4, r6\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"mov\tr10, r4\\n\\t\"\n        \"mov\tr11, r5\\n\\t\"\n        \"adc\tr3, r3\\n\\t\"\n        \"mov\tr6, r3\\n\\t\"\n        \"sub\tr3, #1\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"ldr\tr4, [%[r],#0]\\n\\t\"\n        \"ldr\tr5, [%[r],#4]\\n\\t\"\n        \"sub\tr4, r3\\n\\t\"\n        \"sbc\tr5, r3\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"ldr\tr4, [%[r],#8]\\n\\t\"\n        \"ldr\tr5, [%[r],#12]\\n\\t\"\n        \"sbc\tr4, r3\\n\\t\"\n        \"sbc\tr5, r7\\n\\t\"\n        \"str\tr4, [%[r],#8]\\n\\t\"\n        \"str\tr5, [%[r],#12]\\n\\t\"\n        \"mov\tr4, r8\\n\\t\"\n        \"mov\tr5, r9\\n\\t\"\n        \"sbc\tr4, r7\\n\\t\"\n        \"sbc\tr5, r7\\n\\t\"\n        \"str\tr4, [%[r],#16]\\n\\t\"\n        \"str\tr5, [%[r],#20]\\n\\t\"\n        \"mov\tr4, r10\\n\\t\"\n        \"mov\tr5, r11\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"sbc\tr5, r3\\n\\t\"\n        \"str\tr4, [%[r],#24]\\n\\t\"\n        \"str\tr5, [%[r],#28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n/* Double a Montgomery form number (r = a + a % m).\n *\n * r   Result of doubling.\n * a   Number to double in Montogmery form.\n * m   Modulus (prime).\n */\nSP_NOINLINE static void sp_256_mont_dbl_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"ldr\tr4, [%[a],#0]\\n\\t\"\n        \"ldr\tr5, [%[a],#4]\\n\\t\"\n        \"ldr\tr6, [%[a],#8]\\n\\t\"\n        \"ldr\tr7, [%[a],#12]\\n\\t\"\n        \"add\tr4, r4\\n\\t\"\n        \"adc\tr5, r5\\n\\t\"\n        \"adc\tr6, r6\\n\\t\"\n        \"adc\tr7, r7\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"str\tr6, [%[r],#8]\\n\\t\"\n        \"str\tr7, [%[r],#12]\\n\\t\"\n        \"ldr\tr4, [%[a],#16]\\n\\t\"\n        \"ldr\tr5, [%[a],#20]\\n\\t\"\n        \"ldr\tr6, [%[a],#24]\\n\\t\"\n        \"ldr\tr7, [%[a],#28]\\n\\t\"\n        \"adc\tr4, r4\\n\\t\"\n        \"adc\tr5, r5\\n\\t\"\n        \"adc\tr6, r6\\n\\t\"\n        \"adc\tr7, r7\\n\\t\"\n        \"mov\tr8, r4\\n\\t\"\n        \"mov\tr9, r5\\n\\t\"\n        \"mov\tr10, r6\\n\\t\"\n        \"mov\tr11, r7\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"adc\tr3, r3\\n\\t\"\n        \"mov\tr2, r3\\n\\t\"\n        \"sub\tr3, #1\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"ldr\tr4, [%[r],#0]\\n\\t\"\n        \"ldr\tr5, [%[r],#4]\\n\\t\"\n        \"ldr\tr6, [%[r],#8]\\n\\t\"\n        \"sub\tr4, r3\\n\\t\"\n        \"sbc\tr5, r3\\n\\t\"\n        \"sbc\tr6, r3\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"str\tr6, [%[r],#8]\\n\\t\"\n        \"ldr\tr4, [%[r],#12]\\n\\t\"\n        \"mov\tr5, r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sbc\tr4, r7\\n\\t\"\n        \"sbc\tr5, r7\\n\\t\"\n        \"sbc\tr6, r7\\n\\t\"\n        \"str\tr4, [%[r],#12]\\n\\t\"\n        \"str\tr5, [%[r],#16]\\n\\t\"\n        \"str\tr6, [%[r],#20]\\n\\t\"\n        \"mov\tr4, r10\\n\\t\"\n        \"mov\tr5, r11\\n\\t\"\n        \"sbc\tr4, r2\\n\\t\"\n        \"sbc\tr5, r3\\n\\t\"\n        \"str\tr4, [%[r],#24]\\n\\t\"\n        \"str\tr5, [%[r],#28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r3\", \"r2\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n/* Triple a Montgomery form number (r = a + a + a % m).\n *\n * r   Result of Tripling.\n * a   Number to triple in Montogmery form.\n * m   Modulus (prime).\n */\nSP_NOINLINE static void sp_256_mont_tpl_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"ldr   r6, [%[a],#0]\\n\\t\"\n        \"ldr   r7, [%[a],#4]\\n\\t\"\n        \"ldr   r4, [%[a],#8]\\n\\t\"\n        \"ldr   r5, [%[a],#12]\\n\\t\"\n        \"add   r6, r6\\n\\t\"\n        \"adc   r7, r7\\n\\t\"\n        \"adc   r4, r4\\n\\t\"\n        \"adc   r5, r5\\n\\t\"\n        \"mov   r8, r4\\n\\t\"\n        \"mov   r9, r5\\n\\t\"\n        \"ldr   r2, [%[a],#16]\\n\\t\"\n        \"ldr   r3, [%[a],#20]\\n\\t\"\n        \"ldr   r4, [%[a],#24]\\n\\t\"\n        \"ldr   r5, [%[a],#28]\\n\\t\"\n        \"adc   r2, r2\\n\\t\"\n        \"adc   r3, r3\\n\\t\"\n        \"adc   r4, r4\\n\\t\"\n        \"adc   r5, r5\\n\\t\"\n        \"mov   r10, r2\\n\\t\"\n        \"mov   r11, r3\\n\\t\"\n        \"mov   r12, r4\\n\\t\"\n        \"mov   r14, r5\\n\\t\"\n        \"mov   r3, #0\\n\\t\"\n        \"mov   r5, #0\\n\\t\"\n        \"adc   r3, r3\\n\\t\"\n        \"mov   r4, r3\\n\\t\"\n        \"sub   r3, #1\\n\\t\"\n        \"mvn   r3, r3\\n\\t\"\n        \"sub   r6, r3\\n\\t\"\n        \"sbc   r7, r3\\n\\t\"\n        \"mov   r2, r8\\n\\t\"\n        \"sbc   r2, r3\\n\\t\"\n        \"mov   r8, r2\\n\\t\"\n        \"mov   r2, r9\\n\\t\"\n        \"sbc   r2, r5\\n\\t\"\n        \"mov   r9, r2\\n\\t\"\n        \"mov   r2, r10\\n\\t\"\n        \"sbc   r2, r5\\n\\t\"\n        \"mov   r10, r2\\n\\t\"\n        \"mov   r2, r11\\n\\t\"\n        \"sbc   r2, r5\\n\\t\"\n        \"mov   r11, r2\\n\\t\"\n        \"mov   r2, r12\\n\\t\"\n        \"sbc   r2, r4\\n\\t\"\n        \"mov   r12, r2\\n\\t\"\n        \"mov   r2, r14\\n\\t\"\n        \"sbc   r2, r3\\n\\t\"\n        \"mov   r14, r2\\n\\t\"\n        \"ldr\tr2, [%[a],#0]\\n\\t\"\n        \"ldr\tr3, [%[a],#4]\\n\\t\"\n        \"add\tr6, r2\\n\\t\"\n        \"adc\tr7, r3\\n\\t\"\n        \"ldr\tr2, [%[a],#8]\\n\\t\"\n        \"ldr\tr3, [%[a],#12]\\n\\t\"\n        \"mov\tr4, r8\\n\\t\"\n        \"mov\tr5, r9\\n\\t\"\n        \"adc\tr2, r4\\n\\t\"\n        \"adc\tr3, r5\\n\\t\"\n        \"mov   r8, r2\\n\\t\"\n        \"mov   r9, r3\\n\\t\"\n        \"ldr\tr2, [%[a],#16]\\n\\t\"\n        \"ldr\tr3, [%[a],#20]\\n\\t\"\n        \"mov\tr4, r10\\n\\t\"\n        \"mov\tr5, r11\\n\\t\"\n        \"adc\tr2, r4\\n\\t\"\n        \"adc\tr3, r5\\n\\t\"\n        \"mov\tr10, r2\\n\\t\"\n        \"mov\tr11, r3\\n\\t\"\n        \"ldr\tr2, [%[a],#24]\\n\\t\"\n        \"ldr\tr3, [%[a],#28]\\n\\t\"\n        \"mov\tr4, r12\\n\\t\"\n        \"mov\tr5, r14\\n\\t\"\n        \"adc\tr2, r4\\n\\t\"\n        \"adc\tr3, r5\\n\\t\"\n        \"mov\tr12, r2\\n\\t\"\n        \"mov\tr14, r3\\n\\t\"\n        \"mov   r3, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"adc\tr3, r3\\n\\t\"\n        \"mov\tr4, r3\\n\\t\"\n        \"sub\tr3, #1\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"sub\tr6, r3\\n\\t\"\n        \"str\tr6, [%[r],#0]\\n\\t\"\n        \"sbc\tr7, r3\\n\\t\"\n        \"str\tr7, [%[r],#4]\\n\\t\"\n        \"mov   r2, r8\\n\\t\"\n        \"sbc   r2, r3\\n\\t\"\n        \"str\tr2, [%[r],#8]\\n\\t\"\n        \"mov   r2, r9\\n\\t\"\n        \"sbc   r2, r5\\n\\t\"\n        \"str\tr2, [%[r],#12]\\n\\t\"\n        \"mov   r2, r10\\n\\t\"\n        \"sbc   r2, r5\\n\\t\"\n        \"str\tr2, [%[r],#16]\\n\\t\"\n        \"mov   r2, r11\\n\\t\"\n        \"sbc   r2, r5\\n\\t\"\n        \"str\tr2, [%[r],#20]\\n\\t\"\n        \"mov   r2, r12\\n\\t\"\n        \"sbc   r2, r4\\n\\t\"\n        \"str\tr2, [%[r],#24]\\n\\t\"\n        \"mov   r2, r14\\n\\t\"\n        \"sbc   r2, r3\\n\\t\"\n        \"str\tr2, [%[r],#28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n}\n\n/* Subtract two Montgomery form numbers (r = a - b % m).\n *\n * r   Result of subtration.\n * a   Number to subtract from in Montogmery form.\n * b   Number to subtract with in Montogmery form.\n * m   Modulus (prime).\n */\nSP_NOINLINE static void sp_256_mont_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m)\n{\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"ldr\tr4, [%[a],#0]\\n\\t\"\n        \"ldr\tr5, [%[a],#4]\\n\\t\"\n        \"ldr\tr6, [%[b],#0]\\n\\t\"\n        \"ldr\tr7, [%[b],#4]\\n\\t\"\n        \"sub\tr4, r6\\n\\t\"\n        \"sbc\tr5, r7\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"ldr\tr4, [%[a],#8]\\n\\t\"\n        \"ldr\tr5, [%[a],#12]\\n\\t\"\n        \"ldr\tr6, [%[b],#8]\\n\\t\"\n        \"ldr\tr7, [%[b],#12]\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"sbc\tr5, r7\\n\\t\"\n        \"str\tr4, [%[r],#8]\\n\\t\"\n        \"str\tr5, [%[r],#12]\\n\\t\"\n        \"ldr\tr4, [%[a],#16]\\n\\t\"\n        \"ldr\tr5, [%[a],#20]\\n\\t\"\n        \"ldr\tr6, [%[b],#16]\\n\\t\"\n        \"ldr\tr7, [%[b],#20]\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"sbc\tr5, r7\\n\\t\"\n        \"mov\tr8, r4\\n\\t\"\n        \"mov\tr9, r5\\n\\t\"\n        \"ldr\tr4, [%[a],#24]\\n\\t\"\n        \"ldr\tr5, [%[a],#28]\\n\\t\"\n        \"ldr\tr6, [%[b],#24]\\n\\t\"\n        \"ldr\tr7, [%[b],#28]\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"sbc\tr5, r7\\n\\t\"\n        \"mov\tr10, r4\\n\\t\"\n        \"mov\tr11, r5\\n\\t\"\n        \"sbc   r3, r3\\n\\t\"\n        \"lsr   r7, r3, #31\\n\\t\"\n        \"mov   r6, #0\\n\\t\"\n        \"ldr\tr4, [%[r],#0]\\n\\t\"\n        \"ldr\tr5, [%[r],#4]\\n\\t\"\n        \"add\tr4, r3\\n\\t\"\n        \"adc\tr5, r3\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"ldr\tr4, [%[r],#8]\\n\\t\"\n        \"ldr\tr5, [%[r],#12]\\n\\t\"\n        \"adc\tr4, r3\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"str\tr4, [%[r],#8]\\n\\t\"\n        \"str\tr5, [%[r],#12]\\n\\t\"\n        \"mov\tr4, r8\\n\\t\"\n        \"mov\tr5, r9\\n\\t\"\n        \"adc\tr4, r6\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"str\tr4, [%[r],#16]\\n\\t\"\n        \"str\tr5, [%[r],#20]\\n\\t\"\n        \"mov\tr4, r10\\n\\t\"\n        \"mov\tr5, r11\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, r3\\n\\t\"\n        \"str\tr4, [%[r],#24]\\n\\t\"\n        \"str\tr5, [%[r],#28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)\n *\n * r  Result of division by 2.\n * a  Number to divide.\n * m  Modulus (prime).\n */\nSP_NOINLINE static void sp_256_div2_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    __asm__ __volatile__ (\n        \"ldr\tr7, [%[a], #0]\\n\\t\"\n        \"lsl\tr7, r7, #31\\n\\t\"\n        \"lsr\tr7, r7, #31\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, r7\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"lsl\tr6, r5, #31\\n\\t\"\n        \"lsr\tr6, r6, #31\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"add\tr3, r5\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"adc\tr3, r5\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"str\tr3, [%[r], #8]\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"adc\tr3, r7\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"adc\tr3, r6\\n\\t\"\n        \"adc\tr4, r5\\n\\t\"\n        \"adc\tr7, r7\\n\\t\"\n        \"lsl\tr7, r7, #31\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, #31\\n\\t\"\n        \"lsr\tr6, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, #31\\n\\t\"\n        \"orr\tr5, r4\\n\\t\"\n        \"orr\tr6, r7\\n\\t\"\n        \"mov\tr7, r3\\n\\t\"\n        \"str\tr5, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, #31\\n\\t\"\n        \"lsr\tr6, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, #31\\n\\t\"\n        \"orr\tr5, r4\\n\\t\"\n        \"orr\tr6, r7\\n\\t\"\n        \"mov\tr7, r3\\n\\t\"\n        \"str\tr5, [%[r], #16]\\n\\t\"\n        \"str\tr6, [%[r], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, #31\\n\\t\"\n        \"lsr\tr6, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, #31\\n\\t\"\n        \"orr\tr5, r4\\n\\t\"\n        \"orr\tr6, r7\\n\\t\"\n        \"mov\tr7, r3\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[r], #4]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsr\tr6, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, #31\\n\\t\"\n        \"orr\tr5, r4\\n\\t\"\n        \"orr\tr6, r7\\n\\t\"\n        \"str\tr5, [%[r], #0]\\n\\t\"\n        \"str\tr6, [%[r], #4]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [m] \"r\" (m)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n}\n\n/* Double the Montgomery form projective point p.\n *\n * r  Result of doubling point.\n * p  Point to double.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_8(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*8;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* When infinity don't double point passed in - constant time. */\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    /* Put point to double into result - good for infinty. */\n    if (r != p) {\n        for (i=0; i<8; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<8; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<8; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* T1 = Z * Z */\n    sp_256_mont_sqr_8(t1, z, p256_mod, p256_mp_mod);\n    /* Z = Y * Z */\n    sp_256_mont_mul_8(z, y, z, p256_mod, p256_mp_mod);\n    /* Z = 2Z */\n    sp_256_mont_dbl_8(z, z, p256_mod);\n    /* T2 = X - T1 */\n    sp_256_mont_sub_8(t2, x, t1, p256_mod);\n    /* T1 = X + T1 */\n    sp_256_mont_add_8(t1, x, t1, p256_mod);\n    /* T2 = T1 * T2 */\n    sp_256_mont_mul_8(t2, t1, t2, p256_mod, p256_mp_mod);\n    /* T1 = 3T2 */\n    sp_256_mont_tpl_8(t1, t2, p256_mod);\n    /* Y = 2Y */\n    sp_256_mont_dbl_8(y, y, p256_mod);\n    /* Y = Y * Y */\n    sp_256_mont_sqr_8(y, y, p256_mod, p256_mp_mod);\n    /* T2 = Y * Y */\n    sp_256_mont_sqr_8(t2, y, p256_mod, p256_mp_mod);\n    /* T2 = T2/2 */\n    sp_256_div2_8(t2, t2, p256_mod);\n    /* Y = Y * X */\n    sp_256_mont_mul_8(y, y, x, p256_mod, p256_mp_mod);\n    /* X = T1 * T1 */\n    sp_256_mont_mul_8(x, t1, t1, p256_mod, p256_mp_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_8(x, x, y, p256_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_8(x, x, y, p256_mod);\n    /* Y = Y - X */\n    sp_256_mont_sub_8(y, y, x, p256_mod);\n    /* Y = Y * T1 */\n    sp_256_mont_mul_8(y, y, t1, p256_mod, p256_mp_mod);\n    /* Y = Y - T2 */\n    sp_256_mont_sub_8(y, y, t2, p256_mod);\n\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"add\tr6, #32\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"sbc\tr4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"add\t%[b], #4\\n\\t\"\n        \"add\t%[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n#else\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[a], #4]\\n\\t\"\n        \"ldr\tr6, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"sub\tr4, r6\\n\\t\"\n        \"sbc\tr5, r7\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr5, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr6, [%[b], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"sbc\tr5, r7\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"str\tr5, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[a], #20]\\n\\t\"\n        \"ldr\tr6, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"sbc\tr5, r7\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr6, [%[b], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"sbc\tr5, r7\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"str\tr5, [%[r], #28]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Compare two numbers to determine if they are equal.\n * Constant time implementation.\n *\n * a  First number to compare.\n * b  Second number to compare.\n * returns 1 when equal and 0 otherwise.\n */\nstatic int sp_256_cmp_equal_8(const sp_digit* a, const sp_digit* b)\n{\n    return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) |\n            (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7])) == 0;\n}\n\n/* Add two Montgomery form projective points.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_point* q,\n        sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*8;\n    sp_digit* t3 = t + 4*8;\n    sp_digit* t4 = t + 6*8;\n    sp_digit* t5 = t + 8*8;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Ensure only the first point is the same as the result. */\n    if (q == r) {\n        const sp_point* a = p;\n        p = q;\n        q = a;\n    }\n\n    /* Check double */\n    (void)sp_256_sub_8(t1, p256_mod, q->y);\n    sp_256_norm_8(t1);\n    if ((sp_256_cmp_equal_8(p->x, q->x) & sp_256_cmp_equal_8(p->z, q->z) &\n        (sp_256_cmp_equal_8(p->y, q->y) | sp_256_cmp_equal_8(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_8(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<8; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<8; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<8; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U1 = X1*Z2^2 */\n        sp_256_mont_sqr_8(t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t3, t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t1, t1, x, p256_mod, p256_mp_mod);\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_8(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S1 = Y1*Z2^3 */\n        sp_256_mont_mul_8(t3, t3, y, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_8(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - U1 */\n        sp_256_mont_sub_8(t2, t2, t1, p256_mod);\n        /* R = S2 - S1 */\n        sp_256_mont_sub_8(t4, t4, t3, p256_mod);\n        /* Z3 = H*Z1*Z2 */\n        sp_256_mont_mul_8(z, z, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*U1*H^2 */\n        sp_256_mont_sqr_8(x, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_8(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(y, t1, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(x, x, t5, p256_mod);\n        sp_256_mont_dbl_8(t1, y, p256_mod);\n        sp_256_mont_sub_8(x, x, t1, p256_mod);\n        /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */\n        sp_256_mont_sub_8(y, y, x, p256_mod);\n        sp_256_mont_mul_8(y, y, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t5, t5, t3, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(y, y, t5, p256_mod);\n    }\n}\n\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td[16];\n    sp_point rtd;\n    sp_digit tmpd[2 * 8 * 5];\n#endif\n    sp_point* t;\n    sp_point* rt;\n    sp_digit* tmp;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_point*)XMALLOC(sizeof(sp_point) * 16, heap, DYNAMIC_TYPE_ECC);\n    if (t == NULL)\n        err = MEMORY_E;\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap,\n                             DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n#else\n    t = td;\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        /* t[0] = {0, 0, 1} * norm */\n        XMEMSET(&t[0], 0, sizeof(t[0]));\n        t[0].infinity = 1;\n        /* t[1] = {g->x, g->y, g->z} * norm */\n        (void)sp_256_mod_mul_norm_8(t[1].x, g->x, p256_mod);\n        (void)sp_256_mod_mul_norm_8(t[1].y, g->y, p256_mod);\n        (void)sp_256_mod_mul_norm_8(t[1].z, g->z, p256_mod);\n        t[1].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[ 2], &t[ 1], tmp);\n        t[ 2].infinity = 0;\n        sp_256_proj_point_add_8(&t[ 3], &t[ 2], &t[ 1], tmp);\n        t[ 3].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[ 4], &t[ 2], tmp);\n        t[ 4].infinity = 0;\n        sp_256_proj_point_add_8(&t[ 5], &t[ 3], &t[ 2], tmp);\n        t[ 5].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[ 6], &t[ 3], tmp);\n        t[ 6].infinity = 0;\n        sp_256_proj_point_add_8(&t[ 7], &t[ 4], &t[ 3], tmp);\n        t[ 7].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[ 8], &t[ 4], tmp);\n        t[ 8].infinity = 0;\n        sp_256_proj_point_add_8(&t[ 9], &t[ 5], &t[ 4], tmp);\n        t[ 9].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[10], &t[ 5], tmp);\n        t[10].infinity = 0;\n        sp_256_proj_point_add_8(&t[11], &t[ 6], &t[ 5], tmp);\n        t[11].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[12], &t[ 6], tmp);\n        t[12].infinity = 0;\n        sp_256_proj_point_add_8(&t[13], &t[ 7], &t[ 6], tmp);\n        t[13].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[14], &t[ 7], tmp);\n        t[14].infinity = 0;\n        sp_256_proj_point_add_8(&t[15], &t[ 8], &t[ 7], tmp);\n        t[15].infinity = 0;\n\n        i = 6;\n        n = k[i+1] << 0;\n        c = 28;\n        y = n >> 28;\n        XMEMCPY(rt, &t[y], sizeof(sp_point));\n        n <<= 4;\n        for (; i>=0 || c>=4; ) {\n            if (c < 4) {\n                n |= k[i--] << (0 - c);\n                c += 32;\n            }\n            y = (n >> 28) & 0xf;\n            n <<= 4;\n            c -= 4;\n\n            sp_256_proj_point_dbl_8(rt, rt, tmp);\n            sp_256_proj_point_dbl_8(rt, rt, tmp);\n            sp_256_proj_point_dbl_8(rt, rt, tmp);\n            sp_256_proj_point_dbl_8(rt, rt, tmp);\n\n            sp_256_proj_point_add_8(rt, rt, &t[y], tmp);\n        }\n\n        if (map != 0) {\n            sp_256_map_8(r, rt, tmp);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 8 * 5);\n        XFREE(tmp, heap, DYNAMIC_TYPE_ECC);\n    }\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_point) * 16);\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    ForceZero(tmpd, sizeof(tmpd));\n    ForceZero(td, sizeof(td));\n#endif\n    sp_ecc_point_free(rt, 1, heap);\n\n    return err;\n}\n\n/* A table entry for pre-computed points. */\ntypedef struct sp_table_entry {\n    sp_digit x[8];\n    sp_digit y[8];\n} sp_table_entry;\n\n#ifdef FP_ECC\n/* Double the Montgomery form projective point p a number of times.\n *\n * r  Result of repeated doubling of point.\n * p  Point to double.\n * n  Number of times to double\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_n_8(sp_point* r, const sp_point* p, int n,\n        sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* w = t;\n    sp_digit* a = t + 2*8;\n    sp_digit* b = t + 4*8;\n    sp_digit* t1 = t + 6*8;\n    sp_digit* t2 = t + 8*8;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    if (r != p) {\n        for (i=0; i<8; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<8; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<8; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* Y = 2*Y */\n    sp_256_mont_dbl_8(y, y, p256_mod);\n    /* W = Z^4 */\n    sp_256_mont_sqr_8(w, z, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_8(w, w, p256_mod, p256_mp_mod);\n    while (n-- > 0) {\n        /* A = 3*(X^2 - W) */\n        sp_256_mont_sqr_8(t1, x, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(t1, t1, w, p256_mod);\n        sp_256_mont_tpl_8(a, t1, p256_mod);\n        /* B = X*Y^2 */\n        sp_256_mont_sqr_8(t2, y, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(b, t2, x, p256_mod, p256_mp_mod);\n        /* X = A^2 - 2B */\n        sp_256_mont_sqr_8(x, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_8(t1, b, p256_mod);\n        sp_256_mont_sub_8(x, x, t1, p256_mod);\n        /* Z = Z*Y */\n        sp_256_mont_mul_8(z, z, y, p256_mod, p256_mp_mod);\n        /* t2 = Y^4 */\n        sp_256_mont_sqr_8(t2, t2, p256_mod, p256_mp_mod);\n        if (n != 0) {\n            /* W = W*Y^4 */\n            sp_256_mont_mul_8(w, w, t2, p256_mod, p256_mp_mod);\n        }\n        /* y = 2*A*(B - X) - Y^4 */\n        sp_256_mont_sub_8(y, b, x, p256_mod);\n        sp_256_mont_mul_8(y, y, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_8(y, y, p256_mod);\n        sp_256_mont_sub_8(y, y, t2, p256_mod);\n    }\n    /* Y = Y/2 */\n    sp_256_div2_8(y, y, p256_mod);\n}\n\n#endif /* FP_ECC */\n/* Add two Montgomery form projective points. The second point has a q value of\n * one.\n * Only the first point can be the same pointer as the result point.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_qz1_8(sp_point* r, const sp_point* p,\n        const sp_point* q, sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*8;\n    sp_digit* t3 = t + 4*8;\n    sp_digit* t4 = t + 6*8;\n    sp_digit* t5 = t + 8*8;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Check double */\n    (void)sp_256_sub_8(t1, p256_mod, q->y);\n    sp_256_norm_8(t1);\n    if ((sp_256_cmp_equal_8(p->x, q->x) & sp_256_cmp_equal_8(p->z, q->z) &\n        (sp_256_cmp_equal_8(p->y, q->y) | sp_256_cmp_equal_8(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_8(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<8; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<8; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<8; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_8(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_8(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - X1 */\n        sp_256_mont_sub_8(t2, t2, x, p256_mod);\n        /* R = S2 - Y1 */\n        sp_256_mont_sub_8(t4, t4, y, p256_mod);\n        /* Z3 = H*Z1 */\n        sp_256_mont_mul_8(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*X1*H^2 */\n        sp_256_mont_sqr_8(t1, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_8(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t3, x, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(x, t1, t5, p256_mod);\n        sp_256_mont_dbl_8(t1, t3, p256_mod);\n        sp_256_mont_sub_8(x, x, t1, p256_mod);\n        /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */\n        sp_256_mont_sub_8(t3, t3, x, p256_mod);\n        sp_256_mont_mul_8(t3, t3, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t5, t5, y, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(y, t3, t5, p256_mod);\n    }\n}\n\n#ifdef WOLFSSL_SP_SMALL\n#ifdef FP_ECC\n/* Convert the projective point to affine.\n * Ordinates are in Montgomery form.\n *\n * a  Point to convert.\n * t  Temprorary data.\n */\nstatic void sp_256_proj_to_affine_8(sp_point* a, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2 * 8;\n    sp_digit* tmp = t + 4 * 8;\n\n    sp_256_mont_inv_8(t1, a->z, tmp);\n\n    sp_256_mont_sqr_8(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_8(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    sp_256_mont_mul_8(a->x, a->x, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_8(a->y, a->y, t1, p256_mod, p256_mp_mod);\n    XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod));\n}\n\n/* Generate the pre-computed table of points for the base point.\n *\n * a      The base point.\n * table  Place to store generated point data.\n * tmp    Temprorary data.\n * heap  Heap to use for allocation.\n */\nstatic int sp_256_gen_stripe_table_8(const sp_point* a,\n        sp_table_entry* table, sp_digit* tmp, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td, s1d, s2d;\n#endif\n    sp_point* t;\n    sp_point* s1 = NULL;\n    sp_point* s2 = NULL;\n    int i, j;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, td, t);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s1d, s1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s2d, s2);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->x, a->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->y, a->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->z, a->z, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        t->infinity = 0;\n        sp_256_proj_to_affine_8(t, tmp);\n\n        XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s1->infinity = 0;\n        XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s2->infinity = 0;\n\n        /* table[0] = {0, 0, infinity} */\n        XMEMSET(&table[0], 0, sizeof(sp_table_entry));\n        /* table[1] = Affine version of 'a' in Montgomery form */\n        XMEMCPY(table[1].x, t->x, sizeof(table->x));\n        XMEMCPY(table[1].y, t->y, sizeof(table->y));\n\n        for (i=1; i<4; i++) {\n            sp_256_proj_point_dbl_n_8(t, t, 64, tmp);\n            sp_256_proj_to_affine_8(t, tmp);\n            XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));\n            XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));\n        }\n\n        for (i=1; i<4; i++) {\n            XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));\n            XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));\n            for (j=(1<<i)+1; j<(1<<(i+1)); j++) {\n                XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));\n                XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));\n                sp_256_proj_point_add_qz1_8(t, s1, s2, tmp);\n                sp_256_proj_to_affine_8(t, tmp);\n                XMEMCPY(table[j].x, t->x, sizeof(table->x));\n                XMEMCPY(table[j].y, t->y, sizeof(table->y));\n            }\n        }\n    }\n\n    sp_ecc_point_free(s2, 0, heap);\n    sp_ecc_point_free(s1, 0, heap);\n    sp_ecc_point_free( t, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC */\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit td[2 * 8 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* t;\n    int i, j;\n    int y, x;\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap,\n                           DYNAMIC_TYPE_ECC);\n    if (t == NULL) {\n        err = MEMORY_E;\n    }\n#else\n    t = td;\n#endif\n\n    if (err == MP_OKAY) {\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        y = 0;\n        for (j=0,x=63; j<4; j++,x+=64) {\n            y |= ((k[x / 32] >> (x % 32)) & 1) << j;\n        }\n        XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));\n        XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));\n        rt->infinity = !y;\n        for (i=62; i>=0; i--) {\n            y = 0;\n            for (j=0,x=i; j<4; j++,x+=64) {\n                y |= ((k[x / 32] >> (x % 32)) & 1) << j;\n            }\n\n            sp_256_proj_point_dbl_8(rt, rt, t);\n            XMEMCPY(p->x, table[y].x, sizeof(table[y].x));\n            XMEMCPY(p->y, table[y].y, sizeof(table[y].y));\n            p->infinity = !y;\n            sp_256_proj_point_add_qz1_8(rt, rt, p, t);\n        }\n\n        if (map != 0) {\n            sp_256_map_8(r, rt, t);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n#ifdef FP_ECC\n#ifndef FP_ENTRIES\n    #define FP_ENTRIES 16\n#endif\n\ntypedef struct sp_cache_t {\n    sp_digit x[8];\n    sp_digit y[8];\n    sp_table_entry table[16];\n    uint32_t cnt;\n    int set;\n} sp_cache_t;\n\nstatic THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES];\nstatic THREAD_LS_T int sp_cache_last = -1;\nstatic THREAD_LS_T int sp_cache_inited = 0;\n\n#ifndef HAVE_THREAD_LS\n    static volatile int initCacheMutex = 0;\n    static wolfSSL_Mutex sp_cache_lock;\n#endif\n\nstatic void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache)\n{\n    int i, j;\n    uint32_t least;\n\n    if (sp_cache_inited == 0) {\n        for (i=0; i<FP_ENTRIES; i++) {\n            sp_cache[i].set = 0;\n        }\n        sp_cache_inited = 1;\n    }\n\n    /* Compare point with those in cache. */\n    for (i=0; i<FP_ENTRIES; i++) {\n        if (!sp_cache[i].set)\n            continue;\n\n        if (sp_256_cmp_equal_8(g->x, sp_cache[i].x) &\n                           sp_256_cmp_equal_8(g->y, sp_cache[i].y)) {\n            sp_cache[i].cnt++;\n            break;\n        }\n    }\n\n    /* No match. */\n    if (i == FP_ENTRIES) {\n        /* Find empty entry. */\n        i = (sp_cache_last + 1) % FP_ENTRIES;\n        for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) {\n            if (!sp_cache[i].set) {\n                break;\n            }\n        }\n\n        /* Evict least used. */\n        if (i == sp_cache_last) {\n            least = sp_cache[0].cnt;\n            for (j=1; j<FP_ENTRIES; j++) {\n                if (sp_cache[j].cnt < least) {\n                    i = j;\n                    least = sp_cache[i].cnt;\n                }\n            }\n        }\n\n        XMEMCPY(sp_cache[i].x, g->x, sizeof(sp_cache[i].x));\n        XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y));\n        sp_cache[i].set = 1;\n        sp_cache[i].cnt = 1;\n    }\n\n    *cache = &sp_cache[i];\n    sp_cache_last = i;\n}\n#endif /* FP_ECC */\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#ifndef FP_ECC\n    return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);\n#else\n    sp_digit tmp[2 * 8 * 5];\n    sp_cache_t* cache;\n    int err = MP_OKAY;\n\n#ifndef HAVE_THREAD_LS\n    if (initCacheMutex == 0) {\n         wc_InitMutex(&sp_cache_lock);\n         initCacheMutex = 1;\n    }\n    if (wc_LockMutex(&sp_cache_lock) != 0)\n       err = BAD_MUTEX_E;\n#endif /* HAVE_THREAD_LS */\n\n    if (err == MP_OKAY) {\n        sp_ecc_get_cache(g, &cache);\n        if (cache->cnt == 2)\n            sp_256_gen_stripe_table_8(g, cache->table, tmp, heap);\n\n#ifndef HAVE_THREAD_LS\n        wc_UnLockMutex(&sp_cache_lock);\n#endif /* HAVE_THREAD_LS */\n\n        if (cache->cnt < 2) {\n            err = sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);\n        }\n        else {\n            err = sp_256_ecc_mulmod_stripe_8(r, g, cache->table, k,\n                    map, heap);\n        }\n    }\n\n    return err;\n#endif\n}\n\n#else\n#ifdef FP_ECC\n/* Generate the pre-computed table of points for the base point.\n *\n * a      The base point.\n * table  Place to store generated point data.\n * tmp    Temprorary data.\n * heap  Heap to use for allocation.\n */\nstatic int sp_256_gen_stripe_table_8(const sp_point* a,\n        sp_table_entry* table, sp_digit* tmp, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td, s1d, s2d;\n#endif\n    sp_point* t;\n    sp_point* s1 = NULL;\n    sp_point* s2 = NULL;\n    int i, j;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, td, t);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s1d, s1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s2d, s2);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->x, a->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->y, a->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->z, a->z, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        t->infinity = 0;\n        sp_256_proj_to_affine_8(t, tmp);\n\n        XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s1->infinity = 0;\n        XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s2->infinity = 0;\n\n        /* table[0] = {0, 0, infinity} */\n        XMEMSET(&table[0], 0, sizeof(sp_table_entry));\n        /* table[1] = Affine version of 'a' in Montgomery form */\n        XMEMCPY(table[1].x, t->x, sizeof(table->x));\n        XMEMCPY(table[1].y, t->y, sizeof(table->y));\n\n        for (i=1; i<8; i++) {\n            sp_256_proj_point_dbl_n_8(t, t, 32, tmp);\n            sp_256_proj_to_affine_8(t, tmp);\n            XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));\n            XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));\n        }\n\n        for (i=1; i<8; i++) {\n            XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));\n            XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));\n            for (j=(1<<i)+1; j<(1<<(i+1)); j++) {\n                XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));\n                XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));\n                sp_256_proj_point_add_qz1_8(t, s1, s2, tmp);\n                sp_256_proj_to_affine_8(t, tmp);\n                XMEMCPY(table[j].x, t->x, sizeof(table->x));\n                XMEMCPY(table[j].y, t->y, sizeof(table->y));\n            }\n        }\n    }\n\n    sp_ecc_point_free(s2, 0, heap);\n    sp_ecc_point_free(s1, 0, heap);\n    sp_ecc_point_free( t, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC */\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit td[2 * 8 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* t;\n    int i, j;\n    int y, x;\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap,\n                           DYNAMIC_TYPE_ECC);\n    if (t == NULL) {\n        err = MEMORY_E;\n    }\n#else\n    t = td;\n#endif\n\n    if (err == MP_OKAY) {\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        y = 0;\n        for (j=0,x=31; j<8; j++,x+=32) {\n            y |= ((k[x / 32] >> (x % 32)) & 1) << j;\n        }\n        XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));\n        XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));\n        rt->infinity = !y;\n        for (i=30; i>=0; i--) {\n            y = 0;\n            for (j=0,x=i; j<8; j++,x+=32) {\n                y |= ((k[x / 32] >> (x % 32)) & 1) << j;\n            }\n\n            sp_256_proj_point_dbl_8(rt, rt, t);\n            XMEMCPY(p->x, table[y].x, sizeof(table[y].x));\n            XMEMCPY(p->y, table[y].y, sizeof(table[y].y));\n            p->infinity = !y;\n            sp_256_proj_point_add_qz1_8(rt, rt, p, t);\n        }\n\n        if (map != 0) {\n            sp_256_map_8(r, rt, t);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n#ifdef FP_ECC\n#ifndef FP_ENTRIES\n    #define FP_ENTRIES 16\n#endif\n\ntypedef struct sp_cache_t {\n    sp_digit x[8];\n    sp_digit y[8];\n    sp_table_entry table[256];\n    uint32_t cnt;\n    int set;\n} sp_cache_t;\n\nstatic THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES];\nstatic THREAD_LS_T int sp_cache_last = -1;\nstatic THREAD_LS_T int sp_cache_inited = 0;\n\n#ifndef HAVE_THREAD_LS\n    static volatile int initCacheMutex = 0;\n    static wolfSSL_Mutex sp_cache_lock;\n#endif\n\nstatic void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache)\n{\n    int i, j;\n    uint32_t least;\n\n    if (sp_cache_inited == 0) {\n        for (i=0; i<FP_ENTRIES; i++) {\n            sp_cache[i].set = 0;\n        }\n        sp_cache_inited = 1;\n    }\n\n    /* Compare point with those in cache. */\n    for (i=0; i<FP_ENTRIES; i++) {\n        if (!sp_cache[i].set)\n            continue;\n\n        if (sp_256_cmp_equal_8(g->x, sp_cache[i].x) &\n                           sp_256_cmp_equal_8(g->y, sp_cache[i].y)) {\n            sp_cache[i].cnt++;\n            break;\n        }\n    }\n\n    /* No match. */\n    if (i == FP_ENTRIES) {\n        /* Find empty entry. */\n        i = (sp_cache_last + 1) % FP_ENTRIES;\n        for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) {\n            if (!sp_cache[i].set) {\n                break;\n            }\n        }\n\n        /* Evict least used. */\n        if (i == sp_cache_last) {\n            least = sp_cache[0].cnt;\n            for (j=1; j<FP_ENTRIES; j++) {\n                if (sp_cache[j].cnt < least) {\n                    i = j;\n                    least = sp_cache[i].cnt;\n                }\n            }\n        }\n\n        XMEMCPY(sp_cache[i].x, g->x, sizeof(sp_cache[i].x));\n        XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y));\n        sp_cache[i].set = 1;\n        sp_cache[i].cnt = 1;\n    }\n\n    *cache = &sp_cache[i];\n    sp_cache_last = i;\n}\n#endif /* FP_ECC */\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#ifndef FP_ECC\n    return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);\n#else\n    sp_digit tmp[2 * 8 * 5];\n    sp_cache_t* cache;\n    int err = MP_OKAY;\n\n#ifndef HAVE_THREAD_LS\n    if (initCacheMutex == 0) {\n         wc_InitMutex(&sp_cache_lock);\n         initCacheMutex = 1;\n    }\n    if (wc_LockMutex(&sp_cache_lock) != 0)\n       err = BAD_MUTEX_E;\n#endif /* HAVE_THREAD_LS */\n\n    if (err == MP_OKAY) {\n        sp_ecc_get_cache(g, &cache);\n        if (cache->cnt == 2)\n            sp_256_gen_stripe_table_8(g, cache->table, tmp, heap);\n\n#ifndef HAVE_THREAD_LS\n        wc_UnLockMutex(&sp_cache_lock);\n#endif /* HAVE_THREAD_LS */\n\n        if (cache->cnt < 2) {\n            err = sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);\n        }\n        else {\n            err = sp_256_ecc_mulmod_stripe_8(r, g, cache->table, k,\n                    map, heap);\n        }\n    }\n\n    return err;\n#endif\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * p     Point to multiply.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map,\n        void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[8];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 8, km);\n        sp_256_point_from_ecc_point_8(point, gm);\n\n            err = sp_256_ecc_mulmod_8(point, point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_8(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#ifdef WOLFSSL_SP_SMALL\nstatic const sp_table_entry p256_table[16] = {\n    /* 0 */\n    { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 */\n    { { 0x18a9143c,0x79e730d4,0x5fedb601,0x75ba95fc,0x77622510,0x79fb732b,\n        0xa53755c6,0x18905f76 },\n      { 0xce95560a,0xddf25357,0xba19e45c,0x8b4ab8e4,0xdd21f325,0xd2e88688,\n        0x25885d85,0x8571ff18 } },\n    /* 2 */\n    { { 0x16a0d2bb,0x4f922fc5,0x1a623499,0x0d5cc16c,0x57c62c8b,0x9241cf3a,\n        0xfd1b667f,0x2f5e6961 },\n      { 0xf5a01797,0x5c15c70b,0x60956192,0x3d20b44d,0x071fdb52,0x04911b37,\n        0x8d6f0f7b,0xf648f916 } },\n    /* 3 */\n    { { 0xe137bbbc,0x9e566847,0x8a6a0bec,0xe434469e,0x79d73463,0xb1c42761,\n        0x133d0015,0x5abe0285 },\n      { 0xc04c7dab,0x92aa837c,0x43260c07,0x573d9f4c,0x78e6cc37,0x0c931562,\n        0x6b6f7383,0x94bb725b } },\n    /* 4 */\n    { { 0xbfe20925,0x62a8c244,0x8fdce867,0x91c19ac3,0xdd387063,0x5a96a5d5,\n        0x21d324f6,0x61d587d4 },\n      { 0xa37173ea,0xe87673a2,0x53778b65,0x23848008,0x05bab43e,0x10f8441e,\n        0x4621efbe,0xfa11fe12 } },\n    /* 5 */\n    { { 0x2cb19ffd,0x1c891f2b,0xb1923c23,0x01ba8d5b,0x8ac5ca8e,0xb6d03d67,\n        0x1f13bedc,0x586eb04c },\n      { 0x27e8ed09,0x0c35c6e5,0x1819ede2,0x1e81a33c,0x56c652fa,0x278fd6c0,\n        0x70864f11,0x19d5ac08 } },\n    /* 6 */\n    { { 0xd2b533d5,0x62577734,0xa1bdddc0,0x673b8af6,0xa79ec293,0x577e7c9a,\n        0xc3b266b1,0xbb6de651 },\n      { 0xb65259b3,0xe7e9303a,0xd03a7480,0xd6a0afd3,0x9b3cfc27,0xc5ac83d1,\n        0x5d18b99b,0x60b4619a } },\n    /* 7 */\n    { { 0x1ae5aa1c,0xbd6a38e1,0x49e73658,0xb8b7652b,0xee5f87ed,0x0b130014,\n        0xaeebffcd,0x9d0f27b2 },\n      { 0x7a730a55,0xca924631,0xddbbc83a,0x9c955b2f,0xac019a71,0x07c1dfe0,\n        0x356ec48d,0x244a566d } },\n    /* 8 */\n    { { 0xf4f8b16a,0x56f8410e,0xc47b266a,0x97241afe,0x6d9c87c1,0x0a406b8e,\n        0xcd42ab1b,0x803f3e02 },\n      { 0x04dbec69,0x7f0309a8,0x3bbad05f,0xa83b85f7,0xad8e197f,0xc6097273,\n        0x5067adc1,0xc097440e } },\n    /* 9 */\n    { { 0xc379ab34,0x846a56f2,0x841df8d1,0xa8ee068b,0x176c68ef,0x20314459,\n        0x915f1f30,0xf1af32d5 },\n      { 0x5d75bd50,0x99c37531,0xf72f67bc,0x837cffba,0x48d7723f,0x0613a418,\n        0xe2d41c8b,0x23d0f130 } },\n    /* 10 */\n    { { 0xd5be5a2b,0xed93e225,0x5934f3c6,0x6fe79983,0x22626ffc,0x43140926,\n        0x7990216a,0x50bbb4d9 },\n      { 0xe57ec63e,0x378191c6,0x181dcdb2,0x65422c40,0x0236e0f6,0x41a8099b,\n        0x01fe49c3,0x2b100118 } },\n    /* 11 */\n    { { 0x9b391593,0xfc68b5c5,0x598270fc,0xc385f5a2,0xd19adcbb,0x7144f3aa,\n        0x83fbae0c,0xdd558999 },\n      { 0x74b82ff4,0x93b88b8e,0x71e734c9,0xd2e03c40,0x43c0322a,0x9a7a9eaf,\n        0x149d6041,0xe6e4c551 } },\n    /* 12 */\n    { { 0x80ec21fe,0x5fe14bfe,0xc255be82,0xf6ce116a,0x2f4a5d67,0x98bc5a07,\n        0xdb7e63af,0xfad27148 },\n      { 0x29ab05b3,0x90c0b6ac,0x4e251ae6,0x37a9a83c,0xc2aade7d,0x0a7dc875,\n        0x9f0e1a84,0x77387de3 } },\n    /* 13 */\n    { { 0xa56c0dd7,0x1e9ecc49,0x46086c74,0xa5cffcd8,0xf505aece,0x8f7a1408,\n        0xbef0c47e,0xb37b85c0 },\n      { 0xcc0e6a8f,0x3596b6e4,0x6b388f23,0xfd6d4bbf,0xc39cef4e,0xaba453fa,\n        0xf9f628d5,0x9c135ac8 } },\n    /* 14 */\n    { { 0x95c8f8be,0x0a1c7294,0x3bf362bf,0x2961c480,0xdf63d4ac,0x9e418403,\n        0x91ece900,0xc109f9cb },\n      { 0x58945705,0xc2d095d0,0xddeb85c0,0xb9083d96,0x7a40449b,0x84692b8d,\n        0x2eee1ee1,0x9bc3344f } },\n    /* 15 */\n    { { 0x42913074,0x0d5ae356,0x48a542b1,0x55491b27,0xb310732a,0x469ca665,\n        0x5f1a4cc1,0x29591d52 },\n      { 0xb84f983f,0xe76f5b6b,0x9f5f84e1,0xbe7eef41,0x80baa189,0x1200d496,\n        0x18ef332c,0x6376551f } },\n};\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table,\n                                      k, map, heap);\n}\n\n#else\nstatic const sp_table_entry p256_table[256] = {\n    /* 0 */\n    { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 */\n    { { 0x18a9143c,0x79e730d4,0x5fedb601,0x75ba95fc,0x77622510,0x79fb732b,\n        0xa53755c6,0x18905f76 },\n      { 0xce95560a,0xddf25357,0xba19e45c,0x8b4ab8e4,0xdd21f325,0xd2e88688,\n        0x25885d85,0x8571ff18 } },\n    /* 2 */\n    { { 0x4147519a,0x20288602,0x26b372f0,0xd0981eac,0xa785ebc8,0xa9d4a7ca,\n        0xdbdf58e9,0xd953c50d },\n      { 0xfd590f8f,0x9d6361cc,0x44e6c917,0x72e9626b,0x22eb64cf,0x7fd96110,\n        0x9eb288f3,0x863ebb7e } },\n    /* 3 */\n    { { 0x5cdb6485,0x7856b623,0x2f0a2f97,0x808f0ea2,0x4f7e300b,0x3e68d954,\n        0xb5ff80a0,0x00076055 },\n      { 0x838d2010,0x7634eb9b,0x3243708a,0x54014fbb,0x842a6606,0xe0e47d39,\n        0x34373ee0,0x83087761 } },\n    /* 4 */\n    { { 0x16a0d2bb,0x4f922fc5,0x1a623499,0x0d5cc16c,0x57c62c8b,0x9241cf3a,\n        0xfd1b667f,0x2f5e6961 },\n      { 0xf5a01797,0x5c15c70b,0x60956192,0x3d20b44d,0x071fdb52,0x04911b37,\n        0x8d6f0f7b,0xf648f916 } },\n    /* 5 */\n    { { 0xe137bbbc,0x9e566847,0x8a6a0bec,0xe434469e,0x79d73463,0xb1c42761,\n        0x133d0015,0x5abe0285 },\n      { 0xc04c7dab,0x92aa837c,0x43260c07,0x573d9f4c,0x78e6cc37,0x0c931562,\n        0x6b6f7383,0x94bb725b } },\n    /* 6 */\n    { { 0x720f141c,0xbbf9b48f,0x2df5bc74,0x6199b3cd,0x411045c4,0xdc3f6129,\n        0x2f7dc4ef,0xcdd6bbcb },\n      { 0xeaf436fd,0xcca6700b,0xb99326be,0x6f647f6d,0x014f2522,0x0c0fa792,\n        0x4bdae5f6,0xa361bebd } },\n    /* 7 */\n    { { 0x597c13c7,0x28aa2558,0x50b7c3e1,0xc38d635f,0xf3c09d1d,0x07039aec,\n        0xc4b5292c,0xba12ca09 },\n      { 0x59f91dfd,0x9e408fa4,0xceea07fb,0x3af43b66,0x9d780b29,0x1eceb089,\n        0x701fef4b,0x53ebb99d } },\n    /* 8 */\n    { { 0xb0e63d34,0x4fe7ee31,0xa9e54fab,0xf4600572,0xd5e7b5a4,0xc0493334,\n        0x06d54831,0x8589fb92 },\n      { 0x6583553a,0xaa70f5cc,0xe25649e5,0x0879094a,0x10044652,0xcc904507,\n        0x02541c4f,0xebb0696d } },\n    /* 9 */\n    { { 0xac1647c5,0x4616ca15,0xc4cf5799,0xb8127d47,0x764dfbac,0xdc666aa3,\n        0xd1b27da3,0xeb2820cb },\n      { 0x6a87e008,0x9406f8d8,0x922378f3,0xd87dfa9d,0x80ccecb2,0x56ed2e42,\n        0x55a7da1d,0x1f28289b } },\n    /* 10 */\n    { { 0x3b89da99,0xabbaa0c0,0xb8284022,0xa6f2d79e,0xb81c05e8,0x27847862,\n        0x05e54d63,0x337a4b59 },\n      { 0x21f7794a,0x3c67500d,0x7d6d7f61,0x207005b7,0x04cfd6e8,0x0a5a3781,\n        0xf4c2fbd6,0x0d65e0d5 } },\n    /* 11 */\n    { { 0xb5275d38,0xd9d09bbe,0x0be0a358,0x4268a745,0x973eb265,0xf0762ff4,\n        0x52f4a232,0xc23da242 },\n      { 0x0b94520c,0x5da1b84f,0xb05bd78e,0x09666763,0x94d29ea1,0x3a4dcb86,\n        0xc790cff1,0x19de3b8c } },\n    /* 12 */\n    { { 0x26c5fe04,0x183a716c,0x3bba1bdb,0x3b28de0b,0xa4cb712c,0x7432c586,\n        0x91fccbfd,0xe34dcbd4 },\n      { 0xaaa58403,0xb408d46b,0x82e97a53,0x9a697486,0x36aaa8af,0x9e390127,\n        0x7b4e0f7f,0xe7641f44 } },\n    /* 13 */\n    { { 0xdf64ba59,0x7d753941,0x0b0242fc,0xd33f10ec,0xa1581859,0x4f06dfc6,\n        0x052a57bf,0x4a12df57 },\n      { 0x9439dbd0,0xbfa6338f,0xbde53e1f,0xd3c24bd4,0x21f1b314,0xfd5e4ffa,\n        0xbb5bea46,0x6af5aa93 } },\n    /* 14 */\n    { { 0x10c91999,0xda10b699,0x2a580491,0x0a24b440,0xb8cc2090,0x3e0094b4,\n        0x66a44013,0x5fe3475a },\n      { 0xf93e7b4b,0xb0f8cabd,0x7c23f91a,0x292b501a,0xcd1e6263,0x42e889ae,\n        0xecfea916,0xb544e308 } },\n    /* 15 */\n    { { 0x16ddfdce,0x6478c6e9,0xf89179e6,0x2c329166,0x4d4e67e1,0x4e8d6e76,\n        0xa6b0c20b,0xe0b6b2bd },\n      { 0xbb7efb57,0x0d312df2,0x790c4007,0x1aac0dde,0x679bc944,0xf90336ad,\n        0x25a63774,0x71c023de } },\n    /* 16 */\n    { { 0xbfe20925,0x62a8c244,0x8fdce867,0x91c19ac3,0xdd387063,0x5a96a5d5,\n        0x21d324f6,0x61d587d4 },\n      { 0xa37173ea,0xe87673a2,0x53778b65,0x23848008,0x05bab43e,0x10f8441e,\n        0x4621efbe,0xfa11fe12 } },\n    /* 17 */\n    { { 0x2cb19ffd,0x1c891f2b,0xb1923c23,0x01ba8d5b,0x8ac5ca8e,0xb6d03d67,\n        0x1f13bedc,0x586eb04c },\n      { 0x27e8ed09,0x0c35c6e5,0x1819ede2,0x1e81a33c,0x56c652fa,0x278fd6c0,\n        0x70864f11,0x19d5ac08 } },\n    /* 18 */\n    { { 0x309a4e1f,0x1e99f581,0xe9270074,0xab7de71b,0xefd28d20,0x26a5ef0b,\n        0x7f9c563f,0xe7c0073f },\n      { 0x0ef59f76,0x1f6d663a,0x20fcb050,0x669b3b54,0x7a6602d4,0xc08c1f7a,\n        0xc65b3c0a,0xe08504fe } },\n    /* 19 */\n    { { 0xa031b3ca,0xf098f68d,0xe6da6d66,0x6d1cab9e,0x94f246e8,0x5bfd81fa,\n        0x5b0996b4,0x78f01882 },\n      { 0x3a25787f,0xb7eefde4,0x1dccac9b,0x8016f80d,0xb35bfc36,0x0cea4877,\n        0x7e94747a,0x43a773b8 } },\n    /* 20 */\n    { { 0xd2b533d5,0x62577734,0xa1bdddc0,0x673b8af6,0xa79ec293,0x577e7c9a,\n        0xc3b266b1,0xbb6de651 },\n      { 0xb65259b3,0xe7e9303a,0xd03a7480,0xd6a0afd3,0x9b3cfc27,0xc5ac83d1,\n        0x5d18b99b,0x60b4619a } },\n    /* 21 */\n    { { 0x1ae5aa1c,0xbd6a38e1,0x49e73658,0xb8b7652b,0xee5f87ed,0x0b130014,\n        0xaeebffcd,0x9d0f27b2 },\n      { 0x7a730a55,0xca924631,0xddbbc83a,0x9c955b2f,0xac019a71,0x07c1dfe0,\n        0x356ec48d,0x244a566d } },\n    /* 22 */\n    { { 0xeacf1f96,0x6db0394a,0x024c271c,0x9f2122a9,0x82cbd3b9,0x2626ac1b,\n        0x3581ef69,0x45e58c87 },\n      { 0xa38f9dbc,0xd3ff479d,0xe888a040,0xa8aaf146,0x46e0bed7,0x945adfb2,\n        0xc1e4b7a4,0xc040e21c } },\n    /* 23 */\n    { { 0x6f8117b6,0x847af000,0x73a35433,0x651969ff,0x1d9475eb,0x482b3576,\n        0x682c6ec7,0x1cdf5c97 },\n      { 0x11f04839,0x7db775b4,0x48de1698,0x7dbeacf4,0xb70b3219,0xb2921dd1,\n        0xa92dff3d,0x046755f8 } },\n    /* 24 */\n    { { 0xbce8ffcd,0xcc8ac5d2,0x2fe61a82,0x0d53c48b,0x7202d6c7,0xf6f16172,\n        0x3b83a5f3,0x046e5e11 },\n      { 0xd8007f01,0xe7b8ff64,0x5af43183,0x7fb1ef12,0x35e1a03c,0x045c5ea6,\n        0x303d005b,0x6e0106c3 } },\n    /* 25 */\n    { { 0x88dd73b1,0x48c73584,0x995ed0d9,0x7670708f,0xc56a2ab7,0x38385ea8,\n        0xe901cf1f,0x442594ed },\n      { 0x12d4b65b,0xf8faa2c9,0x96c90c37,0x94c2343b,0x5e978d1f,0xd326e4a1,\n        0x4c2ee68e,0xa796fa51 } },\n    /* 26 */\n    { { 0x823addd7,0x359fb604,0xe56693b3,0x9e2a6183,0x3cbf3c80,0xf885b78e,\n        0xc69766e9,0xe4ad2da9 },\n      { 0x8e048a61,0x357f7f42,0xc092d9a0,0x082d198c,0xc03ed8ef,0xfc3a1af4,\n        0xc37b5143,0xc5e94046 } },\n    /* 27 */\n    { { 0x2be75f9e,0x476a538c,0xcb123a78,0x6fd1a9e8,0xb109c04b,0xd85e4df0,\n        0xdb464747,0x63283daf },\n      { 0xbaf2df15,0xce728cf7,0x0ad9a7f4,0xe592c455,0xe834bcc3,0xfab226ad,\n        0x1981a938,0x68bd19ab } },\n    /* 28 */\n    { { 0x1887d659,0xc08ead51,0xb359305a,0x3374d5f4,0xcfe74fe3,0x96986981,\n        0x3c6fdfd6,0x495292f5 },\n      { 0x1acec896,0x4a878c9e,0xec5b4484,0xd964b210,0x664d60a7,0x6696f7e2,\n        0x26036837,0x0ec7530d } },\n    /* 29 */\n    { { 0xad2687bb,0x2da13a05,0xf32e21fa,0xa1f83b6a,0x1dd4607b,0x390f5ef5,\n        0x64863f0b,0x0f6207a6 },\n      { 0x0f138233,0xbd67e3bb,0x272aa718,0xdd66b96c,0x26ec88ae,0x8ed00407,\n        0x08ed6dcf,0xff0db072 } },\n    /* 30 */\n    { { 0x4c95d553,0x749fa101,0x5d680a8a,0xa44052fd,0xff3b566f,0x183b4317,\n        0x88740ea3,0x313b513c },\n      { 0x08d11549,0xb402e2ac,0xb4dee21c,0x071ee10b,0x47f2320e,0x26b987dd,\n        0x86f19f81,0x2d3abcf9 } },\n    /* 31 */\n    { { 0x815581a2,0x4c288501,0x632211af,0x9a0a6d56,0x0cab2e99,0x19ba7a0f,\n        0xded98cdf,0xc036fa10 },\n      { 0xc1fbd009,0x29ae08ba,0x06d15816,0x0b68b190,0x9b9e0d8f,0xc2eb3277,\n        0xb6d40194,0xa6b2a2c4 } },\n    /* 32 */\n    { { 0x6d3549cf,0xd433e50f,0xfacd665e,0x6f33696f,0xce11fcb4,0x695bfdac,\n        0xaf7c9860,0x810ee252 },\n      { 0x7159bb2c,0x65450fe1,0x758b357b,0xf7dfbebe,0xd69fea72,0x2b057e74,\n        0x92731745,0xd485717a } },\n    /* 33 */\n    { { 0xf0cb5a98,0x11741a8a,0x1f3110bf,0xd3da8f93,0xab382adf,0x1994e2cb,\n        0x2f9a604e,0x6a6045a7 },\n      { 0xa2b2411d,0x170c0d3f,0x510e96e0,0xbe0eb83e,0x8865b3cc,0x3bcc9f73,\n        0xf9e15790,0xd3e45cfa } },\n    /* 34 */\n    { { 0xe83f7669,0xce1f69bb,0x72877d6b,0x09f8ae82,0x3244278d,0x9548ae54,\n        0xe3c2c19c,0x207755de },\n      { 0x6fef1945,0x87bd61d9,0xb12d28c3,0x18813cef,0x72df64aa,0x9fbcd1d6,\n        0x7154b00d,0x48dc5ee5 } },\n    /* 35 */\n    { { 0xf7e5a199,0x123790bf,0x989ccbb7,0xe0efb8cf,0x0a519c79,0xc27a2bfe,\n        0xdff6f445,0xf2fb0aed },\n      { 0xf0b5025f,0x41c09575,0x40fa9f22,0x550543d7,0x380bfbd0,0x8fa3c8ad,\n        0xdb28d525,0xa13e9015 } },\n    /* 36 */\n    { { 0xa2b65cbc,0xf9f7a350,0x2a464226,0x0b04b972,0xe23f07a1,0x265ce241,\n        0x1497526f,0x2bf0d6b0 },\n      { 0x4b216fb7,0xd3d4dd3f,0xfbdda26a,0xf7d7b867,0x6708505c,0xaeb7b83f,\n        0x162fe89f,0x42a94a5a } },\n    /* 37 */\n    { { 0xeaadf191,0x5846ad0b,0x25a268d7,0x0f8a4890,0x494dc1f6,0xe8603050,\n        0xc65ede3d,0x2c2dd969 },\n      { 0x93849c17,0x6d02171d,0x1da250dd,0x460488ba,0x3c3a5485,0x4810c706,\n        0x42c56dbc,0xf437fa1f } },\n    /* 38 */\n    { { 0x4a0f7dab,0x6aa0d714,0x1776e9ac,0x0f049793,0xf5f39786,0x52c0a050,\n        0x54707aa8,0xaaf45b33 },\n      { 0xc18d364a,0x85e37c33,0x3e497165,0xd40b9b06,0x15ec5444,0xf4171681,\n        0xf4f272bc,0xcdf6310d } },\n    /* 39 */\n    { { 0x8ea8b7ef,0x7473c623,0x85bc2287,0x08e93518,0x2bda8e34,0x41956772,\n        0xda9e2ff2,0xf0d008ba },\n      { 0x2414d3b1,0x2912671d,0xb019ea76,0xb3754985,0x453bcbdb,0x5c61b96d,\n        0xca887b8b,0x5bd5c2f5 } },\n    /* 40 */\n    { { 0xf49a3154,0xef0f469e,0x6e2b2e9a,0x3e85a595,0xaa924a9c,0x45aaec1e,\n        0xa09e4719,0xaa12dfc8 },\n      { 0x4df69f1d,0x26f27227,0xa2ff5e73,0xe0e4c82c,0xb7a9dd44,0xb9d8ce73,\n        0xe48ca901,0x6c036e73 } },\n    /* 41 */\n    { { 0x0f6e3138,0x5cfae12a,0x25ad345a,0x6966ef00,0x45672bc5,0x8993c64b,\n        0x96afbe24,0x292ff658 },\n      { 0x5e213402,0xd5250d44,0x4392c9fe,0xf6580e27,0xda1c72e8,0x097b397f,\n        0x311b7276,0x644e0c90 } },\n    /* 42 */\n    { { 0xa47153f0,0xe1e421e1,0x920418c9,0xb86c3b79,0x705d7672,0x93bdce87,\n        0xcab79a77,0xf25ae793 },\n      { 0x6d869d0c,0x1f3194a3,0x4986c264,0x9d55c882,0x096e945e,0x49fb5ea3,\n        0x13db0a3e,0x39b8e653 } },\n    /* 43 */\n    { { 0xb6fd2e59,0x37754200,0x9255c98f,0x35e2c066,0x0e2a5739,0xd9dab21a,\n        0x0f19db06,0x39122f2f },\n      { 0x03cad53c,0xcfbce1e0,0xe65c17e3,0x225b2c0f,0x9aa13877,0x72baf1d2,\n        0xce80ff8d,0x8de80af8 } },\n    /* 44 */\n    { { 0x207bbb76,0xafbea8d9,0x21782758,0x921c7e7c,0x1c0436b1,0xdfa2b74b,\n        0x2e368c04,0x87194906 },\n      { 0xa3993df5,0xb5f928bb,0xf3b3d26a,0x639d75b5,0x85b55050,0x011aa78a,\n        0x5b74fde1,0xfc315e6a } },\n    /* 45 */\n    { { 0xe8d6ecfa,0x561fd41a,0x1aec7f86,0x5f8c44f6,0x4924741d,0x98452a7b,\n        0xee389088,0xe6d4a7ad },\n      { 0x4593c75d,0x60552ed1,0xdd271162,0x70a70da4,0x7ba2c7db,0xd2aede93,\n        0x9be2ae57,0x35dfaf9a } },\n    /* 46 */\n    { { 0xaa736636,0x6b956fcd,0xae2cab7e,0x09f51d97,0x0f349966,0xfb10bf41,\n        0x1c830d2b,0x1da5c7d7 },\n      { 0x3cce6825,0x5c41e483,0xf9573c3b,0x15ad118f,0xf23036b8,0xa28552c7,\n        0xdbf4b9d6,0x7077c0fd } },\n    /* 47 */\n    { { 0x46b9661c,0xbf63ff8d,0x0d2cfd71,0xa1dfd36b,0xa847f8f7,0x0373e140,\n        0xe50efe44,0x53a8632e },\n      { 0x696d8051,0x0976ff68,0xc74f468a,0xdaec0c95,0x5e4e26bd,0x62994dc3,\n        0x34e1fcc1,0x028ca76d } },\n    /* 48 */\n    { { 0xfc9877ee,0xd11d47dc,0x801d0002,0xc8b36210,0x54c260b6,0xd002c117,\n        0x6962f046,0x04c17cd8 },\n      { 0xb0daddf5,0x6d9bd094,0x24ce55c0,0xbea23575,0x72da03b5,0x663356e6,\n        0xfed97474,0xf7ba4de9 } },\n    /* 49 */\n    { { 0xebe1263f,0xd0dbfa34,0x71ae7ce6,0x55763735,0x82a6f523,0xd2440553,\n        0x52131c41,0xe31f9600 },\n      { 0xea6b6ec6,0xd1bb9216,0x73c2fc44,0x37a1d12e,0x89d0a294,0xc10e7eac,\n        0xce34d47b,0xaa3a6259 } },\n    /* 50 */\n    { { 0x36f3dcd3,0xfbcf9df5,0xd2bf7360,0x6ceded50,0xdf504f5b,0x491710fa,\n        0x7e79daee,0x2398dd62 },\n      { 0x6d09569e,0xcf4705a3,0x5149f769,0xea0619bb,0x35f6034c,0xff9c0377,\n        0x1c046210,0x5717f5b2 } },\n    /* 51 */\n    { { 0x21dd895e,0x9fe229c9,0x40c28451,0x8e518500,0x1d637ecd,0xfa13d239,\n        0x0e3c28de,0x660a2c56 },\n      { 0xd67fcbd0,0x9cca88ae,0x0ea9f096,0xc8472478,0x72e92b4d,0x32b2f481,\n        0x4f522453,0x624ee54c } },\n    /* 52 */\n    { { 0xd897eccc,0x09549ce4,0x3f9880aa,0x4d49d1d9,0x043a7c20,0x723c2423,\n        0x92bdfbc0,0x4f392afb },\n      { 0x7de44fd9,0x6969f8fa,0x57b32156,0xb66cfbe4,0x368ebc3c,0xdb2fa803,\n        0xccdb399c,0x8a3e7977 } },\n    /* 53 */\n    { { 0x06c4b125,0xdde1881f,0xf6e3ca8c,0xae34e300,0x5c7a13e9,0xef6999de,\n        0x70c24404,0x3888d023 },\n      { 0x44f91081,0x76280356,0x5f015504,0x3d9fcf61,0x632cd36e,0x1827edc8,\n        0x18102336,0xa5e62e47 } },\n    /* 54 */\n    { { 0x2facd6c8,0x1a825ee3,0x54bcbc66,0x699c6354,0x98df9931,0x0ce3edf7,\n        0x466a5adc,0x2c4768e6 },\n      { 0x90a64bc9,0xb346ff8c,0xe4779f5c,0x630a6020,0xbc05e884,0xd949d064,\n        0xf9e652a0,0x7b5e6441 } },\n    /* 55 */\n    { { 0x1d28444a,0x2169422c,0xbe136a39,0xe996c5d8,0xfb0c7fce,0x2387afe5,\n        0x0c8d744a,0xb8af73cb },\n      { 0x338b86fd,0x5fde83aa,0xa58a5cff,0xfee3f158,0x20ac9433,0xc9ee8f6f,\n        0x7f3f0895,0xa036395f } },\n    /* 56 */\n    { { 0xa10f7770,0x8c73c6bb,0xa12a0e24,0xa6f16d81,0x51bc2b9f,0x100df682,\n        0x875fb533,0x4be36b01 },\n      { 0x9fb56dbb,0x9226086e,0x07e7a4f8,0x306fef8b,0x66d52f20,0xeeaccc05,\n        0x1bdc00c0,0x8cbc9a87 } },\n    /* 57 */\n    { { 0xc0dac4ab,0xe131895c,0x712ff112,0xa874a440,0x6a1cee57,0x6332ae7c,\n        0x0c0835f8,0x44e7553e },\n      { 0x7734002d,0x6d503fff,0x0b34425c,0x9d35cb8b,0x0e8738b5,0x95f70276,\n        0x5eb8fc18,0x470a683a } },\n    /* 58 */\n    { { 0x90513482,0x81b761dc,0x01e9276a,0x0287202a,0x0ce73083,0xcda441ee,\n        0xc63dc6ef,0x16410690 },\n      { 0x6d06a2ed,0xf5034a06,0x189b100b,0xdd4d7745,0xab8218c9,0xd914ae72,\n        0x7abcbb4f,0xd73479fd } },\n    /* 59 */\n    { { 0x5ad4c6e5,0x7edefb16,0x5b06d04d,0x262cf08f,0x8575cb14,0x12ed5bb1,\n        0x0771666b,0x816469e3 },\n      { 0x561e291e,0xd7ab9d79,0xc1de1661,0xeb9daf22,0x135e0513,0xf49827eb,\n        0xf0dd3f9c,0x0a36dd23 } },\n    /* 60 */\n    { { 0x41d5533c,0x098d32c7,0x8684628f,0x7c5f5a9e,0xe349bd11,0x39a228ad,\n        0xfdbab118,0xe331dfd6 },\n      { 0x6bcc6ed8,0x5100ab68,0xef7a260e,0x7160c3bd,0xbce850d7,0x9063d9a7,\n        0x492e3389,0xd3b4782a } },\n    /* 61 */\n    { { 0xf3821f90,0xa149b6e8,0x66eb7aad,0x92edd9ed,0x1a013116,0x0bb66953,\n        0x4c86a5bd,0x7281275a },\n      { 0xd3ff47e5,0x503858f7,0x61016441,0x5e1616bc,0x7dfd9bb1,0x62b0f11a,\n        0xce145059,0x2c062e7e } },\n    /* 62 */\n    { { 0x0159ac2e,0xa76f996f,0xcbdb2713,0x281e7736,0x08e46047,0x2ad6d288,\n        0x2c4e7ef1,0x282a35f9 },\n      { 0xc0ce5cd2,0x9c354b1e,0x1379c229,0xcf99efc9,0x3e82c11e,0x992caf38,\n        0x554d2abd,0xc71cd513 } },\n    /* 63 */\n    { { 0x09b578f4,0x4885de9c,0xe3affa7a,0x1884e258,0x59182f1f,0x8f76b1b7,\n        0xcf47f3a3,0xc50f6740 },\n      { 0x374b68ea,0xa9c4adf3,0x69965fe2,0xa406f323,0x85a53050,0x2f86a222,\n        0x212958dc,0xb9ecb3a7 } },\n    /* 64 */\n    { { 0xf4f8b16a,0x56f8410e,0xc47b266a,0x97241afe,0x6d9c87c1,0x0a406b8e,\n        0xcd42ab1b,0x803f3e02 },\n      { 0x04dbec69,0x7f0309a8,0x3bbad05f,0xa83b85f7,0xad8e197f,0xc6097273,\n        0x5067adc1,0xc097440e } },\n    /* 65 */\n    { { 0xc379ab34,0x846a56f2,0x841df8d1,0xa8ee068b,0x176c68ef,0x20314459,\n        0x915f1f30,0xf1af32d5 },\n      { 0x5d75bd50,0x99c37531,0xf72f67bc,0x837cffba,0x48d7723f,0x0613a418,\n        0xe2d41c8b,0x23d0f130 } },\n    /* 66 */\n    { { 0xf41500d9,0x857ab6ed,0xfcbeada8,0x0d890ae5,0x89725951,0x52fe8648,\n        0xc0a3fadd,0xb0288dd6 },\n      { 0x650bcb08,0x85320f30,0x695d6e16,0x71af6313,0xb989aa76,0x31f520a7,\n        0xf408c8d2,0xffd3724f } },\n    /* 67 */\n    { { 0xb458e6cb,0x53968e64,0x317a5d28,0x992dad20,0x7aa75f56,0x3814ae0b,\n        0xd78c26df,0xf5590f4a },\n      { 0xcf0ba55a,0x0fc24bd3,0x0c778bae,0x0fc4724a,0x683b674a,0x1ce9864f,\n        0xf6f74a20,0x18d6da54 } },\n    /* 68 */\n    { { 0xd5be5a2b,0xed93e225,0x5934f3c6,0x6fe79983,0x22626ffc,0x43140926,\n        0x7990216a,0x50bbb4d9 },\n      { 0xe57ec63e,0x378191c6,0x181dcdb2,0x65422c40,0x0236e0f6,0x41a8099b,\n        0x01fe49c3,0x2b100118 } },\n    /* 69 */\n    { { 0x9b391593,0xfc68b5c5,0x598270fc,0xc385f5a2,0xd19adcbb,0x7144f3aa,\n        0x83fbae0c,0xdd558999 },\n      { 0x74b82ff4,0x93b88b8e,0x71e734c9,0xd2e03c40,0x43c0322a,0x9a7a9eaf,\n        0x149d6041,0xe6e4c551 } },\n    /* 70 */\n    { { 0x1e9af288,0x55f655bb,0xf7ada931,0x647e1a64,0xcb2820e5,0x43697e4b,\n        0x07ed56ff,0x51e00db1 },\n      { 0x771c327e,0x43d169b8,0x4a96c2ad,0x29cdb20b,0x3deb4779,0xc07d51f5,\n        0x49829177,0xe22f4241 } },\n    /* 71 */\n    { { 0x635f1abb,0xcd45e8f4,0x68538874,0x7edc0cb5,0xb5a8034d,0xc9472c1f,\n        0x52dc48c9,0xf709373d },\n      { 0xa8af30d6,0x401966bb,0xf137b69c,0x95bf5f4a,0x9361c47e,0x3966162a,\n        0xe7275b11,0xbd52d288 } },\n    /* 72 */\n    { { 0x9c5fa877,0xab155c7a,0x7d3a3d48,0x17dad672,0x73d189d8,0x43f43f9e,\n        0xc8aa77a6,0xa0d0f8e4 },\n      { 0xcc94f92d,0x0bbeafd8,0x0c4ddb3a,0xd818c8be,0xb82eba14,0x22cc65f8,\n        0x946d6a00,0xa56c78c7 } },\n    /* 73 */\n    { { 0x0dd09529,0x2962391b,0x3daddfcf,0x803e0ea6,0x5b5bf481,0x2c77351f,\n        0x731a367a,0xd8befdf8 },\n      { 0xfc0157f4,0xab919d42,0xfec8e650,0xf51caed7,0x02d48b0a,0xcdf9cb40,\n        0xce9f6478,0x854a68a5 } },\n    /* 74 */\n    { { 0x63506ea5,0xdc35f67b,0xa4fe0d66,0x9286c489,0xfe95cd4d,0x3f101d3b,\n        0x98846a95,0x5cacea0b },\n      { 0x9ceac44d,0xa90df60c,0x354d1c3a,0x3db29af4,0xad5dbabe,0x08dd3de8,\n        0x35e4efa9,0xe4982d12 } },\n    /* 75 */\n    { { 0xc34cd55e,0x23104a22,0x2680d132,0x58695bb3,0x1fa1d943,0xfb345afa,\n        0x16b20499,0x8046b7f6 },\n      { 0x38e7d098,0xb533581e,0xf46f0b70,0xd7f61e8d,0x44cb78c4,0x30dea9ea,\n        0x9082af55,0xeb17ca7b } },\n    /* 76 */\n    { { 0x76a145b9,0x1751b598,0xc1bc71ec,0xa5cf6b0f,0x392715bb,0xd3e03565,\n        0xfab5e131,0x097b00ba },\n      { 0x565f69e1,0xaa66c8e9,0xb5be5199,0x77e8f75a,0xda4fd984,0x6033ba11,\n        0xafdbcc9e,0xf95c747b } },\n    /* 77 */\n    { { 0xbebae45e,0x558f01d3,0xc4bc6955,0xa8ebe9f0,0xdbc64fc6,0xaeb705b1,\n        0x566ed837,0x3512601e },\n      { 0xfa1161cd,0x9336f1e1,0x4c65ef87,0x328ab8d5,0x724f21e5,0x4757eee2,\n        0x6068ab6b,0x0ef97123 } },\n    /* 78 */\n    { { 0x54ca4226,0x02598cf7,0xf8642c8e,0x5eede138,0x468e1790,0x48963f74,\n        0x3b4fbc95,0xfc16d933 },\n      { 0xe7c800ca,0xbe96fb31,0x2678adaa,0x13806331,0x6ff3e8b5,0x3d624497,\n        0xb95d7a17,0x14ca4af1 } },\n    /* 79 */\n    { { 0xbd2f81d5,0x7a4771ba,0x01f7d196,0x1a5f9d69,0xcad9c907,0xd898bef7,\n        0xf59c231d,0x4057b063 },\n      { 0x89c05c0a,0xbffd82fe,0x1dc0df85,0xe4911c6f,0xa35a16db,0x3befccae,\n        0xf1330b13,0x1c3b5d64 } },\n    /* 80 */\n    { { 0x80ec21fe,0x5fe14bfe,0xc255be82,0xf6ce116a,0x2f4a5d67,0x98bc5a07,\n        0xdb7e63af,0xfad27148 },\n      { 0x29ab05b3,0x90c0b6ac,0x4e251ae6,0x37a9a83c,0xc2aade7d,0x0a7dc875,\n        0x9f0e1a84,0x77387de3 } },\n    /* 81 */\n    { { 0xa56c0dd7,0x1e9ecc49,0x46086c74,0xa5cffcd8,0xf505aece,0x8f7a1408,\n        0xbef0c47e,0xb37b85c0 },\n      { 0xcc0e6a8f,0x3596b6e4,0x6b388f23,0xfd6d4bbf,0xc39cef4e,0xaba453fa,\n        0xf9f628d5,0x9c135ac8 } },\n    /* 82 */\n    { { 0x84e35743,0x32aa3202,0x85a3cdef,0x320d6ab1,0x1df19819,0xb821b176,\n        0xc433851f,0x5721361f },\n      { 0x71fc9168,0x1f0db36a,0x5e5c403c,0x5f98ba73,0x37bcd8f5,0xf64ca87e,\n        0xe6bb11bd,0xdcbac3c9 } },\n    /* 83 */\n    { { 0x4518cbe2,0xf01d9968,0x9c9eb04e,0xd242fc18,0xe47feebf,0x727663c7,\n        0x2d626862,0xb8c1c89e },\n      { 0xc8e1d569,0x51a58bdd,0xb7d88cd0,0x563809c8,0xf11f31eb,0x26c27fd9,\n        0x2f9422d4,0x5d23bbda } },\n    /* 84 */\n    { { 0x95c8f8be,0x0a1c7294,0x3bf362bf,0x2961c480,0xdf63d4ac,0x9e418403,\n        0x91ece900,0xc109f9cb },\n      { 0x58945705,0xc2d095d0,0xddeb85c0,0xb9083d96,0x7a40449b,0x84692b8d,\n        0x2eee1ee1,0x9bc3344f } },\n    /* 85 */\n    { { 0x42913074,0x0d5ae356,0x48a542b1,0x55491b27,0xb310732a,0x469ca665,\n        0x5f1a4cc1,0x29591d52 },\n      { 0xb84f983f,0xe76f5b6b,0x9f5f84e1,0xbe7eef41,0x80baa189,0x1200d496,\n        0x18ef332c,0x6376551f } },\n    /* 86 */\n    { { 0x562976cc,0xbda5f14e,0x0ef12c38,0x22bca3e6,0x6cca9852,0xbbfa3064,\n        0x08e2987a,0xbdb79dc8 },\n      { 0xcb06a772,0xfd2cb5c9,0xfe536dce,0x38f475aa,0x7c2b5db8,0xc2a3e022,\n        0xadd3c14a,0x8ee86001 } },\n    /* 87 */\n    { { 0xa4ade873,0xcbe96981,0xc4fba48c,0x7ee9aa4d,0x5a054ba5,0x2cee2899,\n        0x6f77aa4b,0x92e51d7a },\n      { 0x7190a34d,0x948bafa8,0xf6bd1ed1,0xd698f75b,0x0caf1144,0xd00ee6e3,\n        0x0a56aaaa,0x5182f86f } },\n    /* 88 */\n    { { 0x7a4cc99c,0xfba6212c,0x3e6d9ca1,0xff609b68,0x5ac98c5a,0x5dbb27cb,\n        0x4073a6f2,0x91dcab5d },\n      { 0x5f575a70,0x01b6cc3d,0x6f8d87fa,0x0cb36139,0x89981736,0x165d4e8c,\n        0x97974f2b,0x17a0cedb } },\n    /* 89 */\n    { { 0x076c8d3a,0x38861e2a,0x210f924b,0x701aad39,0x13a835d9,0x94d0eae4,\n        0x7f4cdf41,0x2e8ce36c },\n      { 0x037a862b,0x91273dab,0x60e4c8fa,0x01ba9bb7,0x33baf2dd,0xf9645388,\n        0x34f668f3,0xf4ccc6cb } },\n    /* 90 */\n    { { 0xf1f79687,0x44ef525c,0x92efa815,0x7c595495,0xa5c78d29,0xe1231741,\n        0x9a0df3c9,0xac0db488 },\n      { 0xdf01747f,0x86bfc711,0xef17df13,0x592b9358,0x5ccb6bb5,0xe5880e4f,\n        0x94c974a2,0x95a64a61 } },\n    /* 91 */\n    { { 0xc15a4c93,0x72c1efda,0x82585141,0x40269b73,0x16cb0bad,0x6a8dfb1c,\n        0x29210677,0x231e54ba },\n      { 0x8ae6d2dc,0xa70df917,0x39112918,0x4d6aa63f,0x5e5b7223,0xf627726b,\n        0xd8a731e1,0xab0be032 } },\n    /* 92 */\n    { { 0x8d131f2d,0x097ad0e9,0x3b04f101,0x637f09e3,0xd5e9a748,0x1ac86196,\n        0x2cf6a679,0xf1bcc880 },\n      { 0xe8daacb4,0x25c69140,0x60f65009,0x3c4e4055,0x477937a6,0x591cc8fc,\n        0x5aebb271,0x85169469 } },\n    /* 93 */\n    { { 0xf1dcf593,0xde35c143,0xb018be3b,0x78202b29,0x9bdd9d3d,0xe9cdadc2,\n        0xdaad55d8,0x8f67d9d2 },\n      { 0x7481ea5f,0x84111656,0xe34c590c,0xe7d2dde9,0x05053fa8,0xffdd43f4,\n        0xc0728b5d,0xf84572b9 } },\n    /* 94 */\n    { { 0x97af71c9,0x5e1a7a71,0x7a736565,0xa1449444,0x0e1d5063,0xa1b4ae07,\n        0x616b2c19,0xedee2710 },\n      { 0x11734121,0xb2f034f5,0x4a25e9f0,0x1cac6e55,0xa40c2ecf,0x8dc148f3,\n        0x44ebd7f4,0x9fd27e9b } },\n    /* 95 */\n    { { 0xf6e2cb16,0x3cc7658a,0xfe5919b6,0xe3eb7d2c,0x168d5583,0x5a8c5816,\n        0x958ff387,0xa40c2fb6 },\n      { 0xfedcc158,0x8c9ec560,0x55f23056,0x7ad804c6,0x9a307e12,0xd9396704,\n        0x7dc6decf,0x99bc9bb8 } },\n    /* 96 */\n    { { 0x927dafc6,0x84a9521d,0x5c09cd19,0x52c1fb69,0xf9366dde,0x9d9581a0,\n        0xa16d7e64,0x9abe210b },\n      { 0x48915220,0x480af84a,0x4dd816c6,0xfa73176a,0x1681ca5a,0xc7d53987,\n        0x87f344b0,0x7881c257 } },\n    /* 97 */\n    { { 0xe0bcf3ff,0x93399b51,0x127f74f6,0x0d02cbc5,0xdd01d968,0x8fb465a2,\n        0xa30e8940,0x15e6e319 },\n      { 0x3e0e05f4,0x646d6e0d,0x43588404,0xfad7bddc,0xc4f850d3,0xbe61c7d1,\n        0x191172ce,0x0e55facf } },\n    /* 98 */\n    { { 0xf8787564,0x7e9d9806,0x31e85ce6,0x1a331721,0xb819e8d6,0x6b0158ca,\n        0x6fe96577,0xd73d0976 },\n      { 0x1eb7206e,0x42483425,0xc618bb42,0xa519290f,0x5e30a520,0x5dcbb859,\n        0x8f15a50b,0x9250a374 } },\n    /* 99 */\n    { { 0xbe577410,0xcaff08f8,0x5077a8c6,0xfd408a03,0xec0a63a4,0xf1f63289,\n        0xc1cc8c0b,0x77414082 },\n      { 0xeb0991cd,0x05a40fa6,0x49fdc296,0xc1ca0866,0xb324fd40,0x3a68a3c7,\n        0x12eb20b9,0x8cb04f4d } },\n    /* 100 */\n    { { 0x6906171c,0xb1c2d055,0xb0240c3f,0x9073e9cd,0xd8906841,0xdb8e6b4f,\n        0x47123b51,0xe4e429ef },\n      { 0x38ec36f4,0x0b8dd53c,0xff4b6a27,0xf9d2dc01,0x879a9a48,0x5d066e07,\n        0x3c6e6552,0x37bca2ff } },\n    /* 101 */\n    { { 0xdf562470,0x4cd2e3c7,0xc0964ac9,0x44f272a2,0x80c793be,0x7c6d5df9,\n        0x3002b22a,0x59913edc },\n      { 0x5750592a,0x7a139a83,0xe783de02,0x99e01d80,0xea05d64f,0xcf8c0375,\n        0xb013e226,0x43786e4a } },\n    /* 102 */\n    { { 0x9e56b5a6,0xff32b0ed,0xd9fc68f9,0x0750d9a6,0x597846a7,0xec15e845,\n        0xb7e79e7a,0x8638ca98 },\n      { 0x0afc24b2,0x2f5ae096,0x4dace8f2,0x05398eaf,0xaecba78f,0x3b765dd0,\n        0x7b3aa6f0,0x1ecdd36a } },\n    /* 103 */\n    { { 0x6c5ff2f3,0x5d3acd62,0x2873a978,0xa2d516c0,0xd2110d54,0xad94c9fa,\n        0xd459f32d,0xd85d0f85 },\n      { 0x10b11da3,0x9f700b8d,0xa78318c4,0xd2c22c30,0x9208decd,0x556988f4,\n        0xb4ed3c62,0xa04f19c3 } },\n    /* 104 */\n    { { 0xed7f93bd,0x087924c8,0x392f51f6,0xcb64ac5d,0x821b71af,0x7cae330a,\n        0x5c0950b0,0x92b2eeea },\n      { 0x85b6e235,0x85ac4c94,0x2936c0f0,0xab2ca4a9,0xe0508891,0x80faa6b3,\n        0x5834276c,0x1ee78221 } },\n    /* 105 */\n    { { 0xe63e79f7,0xa60a2e00,0xf399d906,0xf590e7b2,0x6607c09d,0x9021054a,\n        0x57a6e150,0xf3f2ced8 },\n      { 0xf10d9b55,0x200510f3,0xd8642648,0x9d2fcfac,0xe8bd0e7c,0xe5631aa7,\n        0x3da3e210,0x0f56a454 } },\n    /* 106 */\n    { { 0x1043e0df,0x5b21bffa,0x9c007e6d,0x6c74b6cc,0xd4a8517a,0x1a656ec0,\n        0x1969e263,0xbd8f1741 },\n      { 0xbeb7494a,0x8a9bbb86,0x45f3b838,0x1567d46f,0xa4e5a79a,0xdf7a12a7,\n        0x30ccfa09,0x2d1a1c35 } },\n    /* 107 */\n    { { 0x506508da,0x192e3813,0xa1d795a7,0x336180c4,0x7a9944b3,0xcddb5949,\n        0xb91fba46,0xa107a65e },\n      { 0x0f94d639,0xe6d1d1c5,0x8a58b7d7,0x8b4af375,0xbd37ca1c,0x1a7c5584,\n        0xf87a9af2,0x183d760a } },\n    /* 108 */\n    { { 0x0dde59a4,0x29d69711,0x0e8bef87,0xf1ad8d07,0x4f2ebe78,0x229b4963,\n        0xc269d754,0x1d44179d },\n      { 0x8390d30e,0xb32dc0cf,0x0de8110c,0x0a3b2753,0x2bc0339a,0x31af1dc5,\n        0x9606d262,0x771f9cc2 } },\n    /* 109 */\n    { { 0x85040739,0x99993e77,0x8026a939,0x44539db9,0xf5f8fc26,0xcf40f6f2,\n        0x0362718e,0x64427a31 },\n      { 0x85428aa8,0x4f4f2d87,0xebfb49a8,0x7b7adc3f,0xf23d01ac,0x201b2c6d,\n        0x6ae90d6d,0x49d9b749 } },\n    /* 110 */\n    { { 0x435d1099,0xcc78d8bc,0x8e8d1a08,0x2adbcd4e,0x2cb68a41,0x02c2e2a0,\n        0x3f605445,0x9037d81b },\n      { 0x074c7b61,0x7cdbac27,0x57bfd72e,0xfe2031ab,0x596d5352,0x61ccec96,\n        0x7cc0639c,0x08c3de6a } },\n    /* 111 */\n    { { 0xf6d552ab,0x20fdd020,0x05cd81f1,0x56baff98,0x91351291,0x06fb7c3e,\n        0x45796b2f,0xc6909442 },\n      { 0x41231bd1,0x17b3ae9c,0x5cc58205,0x1eac6e87,0xf9d6a122,0x208837ab,\n        0xcafe3ac0,0x3fa3db02 } },\n    /* 112 */\n    { { 0x05058880,0xd75a3e65,0x643943f2,0x7da365ef,0xfab24925,0x4147861c,\n        0xfdb808ff,0xc5c4bdb0 },\n      { 0xb272b56b,0x73513e34,0x11b9043a,0xc8327e95,0xf8844969,0xfd8ce37d,\n        0x46c2b6b5,0x2d56db94 } },\n    /* 113 */\n    { { 0xff46ac6b,0x2461782f,0x07a2e425,0xd19f7926,0x09a48de1,0xfafea3c4,\n        0xe503ba42,0x0f56bd9d },\n      { 0x345cda49,0x137d4ed1,0x816f299d,0x821158fc,0xaeb43402,0xe7c6a54a,\n        0x1173b5f1,0x4003bb9d } },\n    /* 114 */\n    { { 0xa0803387,0x3b8e8189,0x39cbd404,0xece115f5,0xd2877f21,0x4297208d,\n        0xa07f2f9e,0x53765522 },\n      { 0xa8a4182d,0xa4980a21,0x3219df79,0xa2bbd07a,0x1a19a2d4,0x674d0a2e,\n        0x6c5d4549,0x7a056f58 } },\n    /* 115 */\n    { { 0x9d8a2a47,0x646b2558,0xc3df2773,0x5b582948,0xabf0d539,0x51ec000e,\n        0x7a1a2675,0x77d482f1 },\n      { 0x87853948,0xb8a1bd95,0x6cfbffee,0xa6f817bd,0x80681e47,0xab6ec057,\n        0x2b38b0e4,0x4115012b } },\n    /* 116 */\n    { { 0x6de28ced,0x3c73f0f4,0x9b13ec47,0x1d5da760,0x6e5c6392,0x61b8ce9e,\n        0xfbea0946,0xcdf04572 },\n      { 0x6c53c3b0,0x1cb3c58b,0x447b843c,0x97fe3c10,0x2cb9780e,0xfb2b8ae1,\n        0x97383109,0xee703dda } },\n    /* 117 */\n    { { 0xff57e43a,0x34515140,0xb1b811b8,0xd44660d3,0x8f42b986,0x2b3b5dff,\n        0xa162ce21,0x2a0ad89d },\n      { 0x6bc277ba,0x64e4a694,0xc141c276,0xc788c954,0xcabf6274,0x141aa64c,\n        0xac2b4659,0xd62d0b67 } },\n    /* 118 */\n    { { 0x2c054ac4,0x39c5d87b,0xf27df788,0x57005859,0xb18128d6,0xedf7cbf3,\n        0x991c2426,0xb39a23f2 },\n      { 0xf0b16ae5,0x95284a15,0xa136f51b,0x0c6a05b1,0xf2700783,0x1d63c137,\n        0xc0674cc5,0x04ed0092 } },\n    /* 119 */\n    { { 0x9ae90393,0x1f4185d1,0x4a3d64e6,0x3047b429,0x9854fc14,0xae0001a6,\n        0x0177c387,0xa0a91fc1 },\n      { 0xae2c831e,0xff0a3f01,0x2b727e16,0xbb76ae82,0x5a3075b4,0x8f12c8a1,\n        0x9ed20c41,0x084cf988 } },\n    /* 120 */\n    { { 0xfca6becf,0xd98509de,0x7dffb328,0x2fceae80,0x4778e8b9,0x5d8a15c4,\n        0x73abf77e,0xd57955b2 },\n      { 0x31b5d4f1,0x210da79e,0x3cfa7a1c,0xaa52f04b,0xdc27c20b,0xd4d12089,\n        0x02d141f1,0x8e14ea42 } },\n    /* 121 */\n    { { 0xf2897042,0xeed50345,0x43402c4a,0x8d05331f,0xc8bdfb21,0xc8d9c194,\n        0x2aa4d158,0x597e1a37 },\n      { 0xcf0bd68c,0x0327ec1a,0xab024945,0x6d4be0dc,0xc9fe3e84,0x5b9c8d7a,\n        0x199b4dea,0xca3f0236 } },\n    /* 122 */\n    { { 0x6170bd20,0x592a10b5,0x6d3f5de7,0x0ea897f1,0x44b2ade2,0xa3363ff1,\n        0x309c07e4,0xbde7fd7e },\n      { 0xb8f5432c,0x516bb6d2,0xe043444b,0x210dc1cb,0xf8f95b5a,0x3db01e6f,\n        0x0a7dd198,0xb623ad0e } },\n    /* 123 */\n    { { 0x60c7b65b,0xa75bd675,0x23a4a289,0xab8c5590,0xd7b26795,0xf8220fd0,\n        0x58ec137b,0xd6aa2e46 },\n      { 0x5138bb85,0x10abc00b,0xd833a95c,0x8c31d121,0x1702a32e,0xb24ff00b,\n        0x2dcc513a,0x111662e0 } },\n    /* 124 */\n    { { 0xefb42b87,0x78114015,0x1b6c4dff,0xbd9f5d70,0xa7d7c129,0x66ecccd7,\n        0x94b750f8,0xdb3ee1cb },\n      { 0xf34837cf,0xb26f3db0,0xb9578d4f,0xe7eed18b,0x7c56657d,0x5d2cdf93,\n        0x52206a59,0x886a6442 } },\n    /* 125 */\n    { { 0x65b569ea,0x3c234cfb,0xf72119c1,0x20011141,0xa15a619e,0x8badc85d,\n        0x018a17bc,0xa70cf4eb },\n      { 0x8c4a6a65,0x224f97ae,0x0134378f,0x36e5cf27,0x4f7e0960,0xbe3a609e,\n        0xd1747b77,0xaa4772ab } },\n    /* 126 */\n    { { 0x7aa60cc0,0x67676131,0x0368115f,0xc7916361,0xbbc1bb5a,0xded98bb4,\n        0x30faf974,0x611a6ddc },\n      { 0xc15ee47a,0x30e78cbc,0x4e0d96a5,0x2e896282,0x3dd9ed88,0x36f35adf,\n        0x16429c88,0x5cfffaf8 } },\n    /* 127 */\n    { { 0x9b7a99cd,0xc0d54cff,0x843c45a1,0x7bf3b99d,0x62c739e1,0x038a908f,\n        0x7dc1994c,0x6e5a6b23 },\n      { 0x0ba5db77,0xef8b454e,0xacf60d63,0xb7b8807f,0x76608378,0xe591c0c6,\n        0x242dabcc,0x481a238d } },\n    /* 128 */\n    { { 0x35d0b34a,0xe3417bc0,0x8327c0a7,0x440b386b,0xac0362d1,0x8fb7262d,\n        0xe0cdf943,0x2c41114c },\n      { 0xad95a0b1,0x2ba5cef1,0x67d54362,0xc09b37a8,0x01e486c9,0x26d6cdd2,\n        0x42ff9297,0x20477abf } },\n    /* 129 */\n    { { 0x18d65dbf,0x2f75173c,0x339edad8,0x77bf940e,0xdcf1001c,0x7022d26b,\n        0xc77396b6,0xac66409a },\n      { 0xc6261cc3,0x8b0bb36f,0x190e7e90,0x213f7bc9,0xa45e6c10,0x6541ceba,\n        0xcc122f85,0xce8e6975 } },\n    /* 130 */\n    { { 0xbc0a67d2,0x0f121b41,0x444d248a,0x62d4760a,0x659b4737,0x0e044f1d,\n        0x250bb4a8,0x08fde365 },\n      { 0x848bf287,0xaceec3da,0xd3369d6e,0xc2a62182,0x92449482,0x3582dfdc,\n        0x565d6cd7,0x2f7e2fd2 } },\n    /* 131 */\n    { { 0xc3770fa7,0xae4b92db,0x379043f9,0x095e8d5c,0x17761171,0x54f34e9d,\n        0x907702ae,0xc65be92e },\n      { 0xf6fd0a40,0x2758a303,0xbcce784b,0xe7d822e3,0x4f9767bf,0x7ae4f585,\n        0xd1193b3a,0x4bff8e47 } },\n    /* 132 */\n    { { 0x00ff1480,0xcd41d21f,0x0754db16,0x2ab8fb7d,0xbbe0f3ea,0xac81d2ef,\n        0x5772967d,0x3e4e4ae6 },\n      { 0x3c5303e6,0x7e18f36d,0x92262397,0x3bd9994b,0x1324c3c0,0x9ed70e26,\n        0x58ec6028,0x5388aefd } },\n    /* 133 */\n    { { 0x5e5d7713,0xad1317eb,0x75de49da,0x09b985ee,0xc74fb261,0x32f5bc4f,\n        0x4f75be0e,0x5cf908d1 },\n      { 0x8e657b12,0x76043510,0xb96ed9e6,0xbfd421a5,0x8970ccc2,0x0e29f51f,\n        0x60f00ce2,0xa698ba40 } },\n    /* 134 */\n    { { 0xef748fec,0x73db1686,0x7e9d2cf9,0xe6e755a2,0xce265eff,0x630b6544,\n        0x7aebad8d,0xb142ef8a },\n      { 0x17d5770a,0xad31af9f,0x2cb3412f,0x66af3b67,0xdf3359de,0x6bd60d1b,\n        0x58515075,0xd1896a96 } },\n    /* 135 */\n    { { 0x33c41c08,0xec5957ab,0x5468e2e1,0x87de94ac,0xac472f6c,0x18816b73,\n        0x7981da39,0x267b0e0b },\n      { 0x8e62b988,0x6e554e5d,0x116d21e7,0xd8ddc755,0x3d2a6f99,0x4610faf0,\n        0xa1119393,0xb54e287a } },\n    /* 136 */\n    { { 0x178a876b,0x0a0122b5,0x085104b4,0x51ff96ff,0x14f29f76,0x050b31ab,\n        0x5f87d4e6,0x84abb28b },\n      { 0x8270790a,0xd5ed439f,0x85e3f46b,0x2d6cb59d,0x6c1e2212,0x75f55c1b,\n        0x17655640,0xe5436f67 } },\n    /* 137 */\n    { { 0x2286e8d5,0x53f9025e,0x864453be,0x353c95b4,0xe408e3a0,0xd832f5bd,\n        0x5b9ce99e,0x0404f68b },\n      { 0xa781e8e5,0xcad33bde,0x163c2f5b,0x3cdf5018,0x0119caa3,0x57576960,\n        0x0ac1c701,0x3a4263df } },\n    /* 138 */\n    { { 0x9aeb596d,0xc2965ecc,0x023c92b4,0x01ea03e7,0x2e013961,0x4704b4b6,\n        0x905ea367,0x0ca8fd3f },\n      { 0x551b2b61,0x92523a42,0x390fcd06,0x1eb7a89c,0x0392a63e,0xe7f1d2be,\n        0x4ddb0c33,0x96dca264 } },\n    /* 139 */\n    { { 0x387510af,0x203bb43a,0xa9a36a01,0x846feaa8,0x2f950378,0xd23a5770,\n        0x3aad59dc,0x4363e212 },\n      { 0x40246a47,0xca43a1c7,0xe55dd24d,0xb362b8d2,0x5d8faf96,0xf9b08604,\n        0xd8bb98c4,0x840e115c } },\n    /* 140 */\n    { { 0x1023e8a7,0xf12205e2,0xd8dc7a0b,0xc808a8cd,0x163a5ddf,0xe292a272,\n        0x30ded6d4,0x5e0d6abd },\n      { 0x7cfc0f64,0x07a721c2,0x0e55ed88,0x42eec01d,0x1d1f9db2,0x26a7bef9,\n        0x2945a25a,0x7dea48f4 } },\n    /* 141 */\n    { { 0xe5060a81,0xabdf6f1c,0xf8f95615,0xe79f9c72,0x06ac268b,0xcfd36c54,\n        0xebfd16d1,0xabc2a2be },\n      { 0xd3e2eac7,0x8ac66f91,0xd2dd0466,0x6f10ba63,0x0282d31b,0x6790e377,\n        0x6c7eefc1,0x4ea35394 } },\n    /* 142 */\n    { { 0x5266309d,0xed8a2f8d,0x81945a3e,0x0a51c6c0,0x578c5dc1,0xcecaf45a,\n        0x1c94ffc3,0x3a76e689 },\n      { 0x7d7b0d0f,0x9aace8a4,0x8f584a5f,0x963ace96,0x4e697fbe,0x51a30c72,\n        0x465e6464,0x8212a10a } },\n    /* 143 */\n    { { 0xcfab8caa,0xef7c61c3,0x0e142390,0x18eb8e84,0x7e9733ca,0xcd1dff67,\n        0x599cb164,0xaa7cab71 },\n      { 0xbc837bd1,0x02fc9273,0xc36af5d7,0xc06407d0,0xf423da49,0x17621292,\n        0xfe0617c3,0x40e38073 } },\n    /* 144 */\n    { { 0xa7bf9b7c,0xf4f80824,0x3fbe30d0,0x365d2320,0x97cf9ce3,0xbfbe5320,\n        0xb3055526,0xe3604700 },\n      { 0x6cc6c2c7,0x4dcb9911,0xba4cbee6,0x72683708,0x637ad9ec,0xdcded434,\n        0xa3dee15f,0x6542d677 } },\n    /* 145 */\n    { { 0x7b6c377a,0x3f32b6d0,0x903448be,0x6cb03847,0x20da8af7,0xd6fdd3a8,\n        0x09bb6f21,0xa6534aee },\n      { 0x1035facf,0x30a1780d,0x9dcb47e6,0x35e55a33,0xc447f393,0x6ea50fe1,\n        0xdc9aef22,0xf3cb672f } },\n    /* 146 */\n    { { 0x3b55fd83,0xeb3719fe,0x875ddd10,0xe0d7a46c,0x05cea784,0x33ac9fa9,\n        0xaae870e7,0x7cafaa2e },\n      { 0x1d53b338,0x9b814d04,0xef87e6c6,0xe0acc0a0,0x11672b0f,0xfb93d108,\n        0xb9bd522e,0x0aab13c1 } },\n    /* 147 */\n    { { 0xd2681297,0xddcce278,0xb509546a,0xcb350eb1,0x7661aaf2,0x2dc43173,\n        0x847012e9,0x4b91a602 },\n      { 0x72f8ddcf,0xdcff1095,0x9a911af4,0x08ebf61e,0xc372430e,0x48f4360a,\n        0x72321cab,0x49534c53 } },\n    /* 148 */\n    { { 0xf07b7e9d,0x83df7d71,0x13cd516f,0xa478efa3,0x6c047ee3,0x78ef264b,\n        0xd65ac5ee,0xcaf46c4f },\n      { 0x92aa8266,0xa04d0c77,0x913684bb,0xedf45466,0xae4b16b0,0x56e65168,\n        0x04c6770f,0x14ce9e57 } },\n    /* 149 */\n    { { 0x965e8f91,0x99445e3e,0xcb0f2492,0xd3aca1ba,0x90c8a0a0,0xd31cc70f,\n        0x3e4c9a71,0x1bb708a5 },\n      { 0x558bdd7a,0xd5ca9e69,0x018a26b1,0x734a0508,0x4c9cf1ec,0xb093aa71,\n        0xda300102,0xf9d126f2 } },\n    /* 150 */\n    { { 0xaff9563e,0x749bca7a,0xb49914a0,0xdd077afe,0xbf5f1671,0xe27a0311,\n        0x729ecc69,0x807afcb9 },\n      { 0xc9b08b77,0x7f8a9337,0x443c7e38,0x86c3a785,0x476fd8ba,0x85fafa59,\n        0x6568cd8c,0x751adcd1 } },\n    /* 151 */\n    { { 0x10715c0d,0x8aea38b4,0x8f7697f7,0xd113ea71,0x93fbf06d,0x665eab14,\n        0x2537743f,0x29ec4468 },\n      { 0xb50bebbc,0x3d94719c,0xe4505422,0x399ee5bf,0x8d2dedb1,0x90cd5b3a,\n        0x92a4077d,0xff9370e3 } },\n    /* 152 */\n    { { 0xc6b75b65,0x59a2d69b,0x266651c5,0x4188f8d5,0x3de9d7d2,0x28a9f33e,\n        0xa2a9d01a,0x9776478b },\n      { 0x929af2c7,0x8852622d,0x4e690923,0x334f5d6d,0xa89a51e9,0xce6cc7e5,\n        0xac2f82fa,0x74a6313f } },\n    /* 153 */\n    { { 0xb75f079c,0xb2f4dfdd,0x18e36fbb,0x85b07c95,0xe7cd36dd,0x1b6cfcf0,\n        0x0ff4863d,0xab75be15 },\n      { 0x173fc9b7,0x81b367c0,0xd2594fd0,0xb90a7420,0xc4091236,0x15fdbf03,\n        0x0b4459f6,0x4ebeac2e } },\n    /* 154 */\n    { { 0x5c9f2c53,0xeb6c5fe7,0x8eae9411,0xd2522011,0xf95ac5d8,0xc8887633,\n        0x2c1baffc,0xdf99887b },\n      { 0x850aaecb,0xbb78eed2,0x01d6a272,0x9d49181b,0xb1cdbcac,0x978dd511,\n        0x779f4058,0x27b040a7 } },\n    /* 155 */\n    { { 0xf73b2eb2,0x90405db7,0x8e1b2118,0xe0df8508,0x5962327e,0x501b7152,\n        0xe4cfa3f5,0xb393dd37 },\n      { 0x3fd75165,0xa1230e7b,0xbcd33554,0xd66344c2,0x0f7b5022,0x6c36f1be,\n        0xd0463419,0x09588c12 } },\n    /* 156 */\n    { { 0x02601c3b,0xe086093f,0xcf5c335f,0xfb0252f8,0x894aff28,0x955cf280,\n        0xdb9f648b,0x81c879a9 },\n      { 0xc6f56c51,0x040e687c,0x3f17618c,0xfed47169,0x9059353b,0x44f88a41,\n        0x5fc11bc4,0xfa0d48f5 } },\n    /* 157 */\n    { { 0xe1608e4d,0xbc6e1c9d,0x3582822c,0x010dda11,0x157ec2d7,0xf6b7ddc1,\n        0xb6a367d6,0x8ea0e156 },\n      { 0x2383b3b4,0xa354e02f,0x3f01f53c,0x69966b94,0x2de03ca5,0x4ff6632b,\n        0xfa00b5ac,0x3f5ab924 } },\n    /* 158 */\n    { { 0x59739efb,0x337bb0d9,0xe7ebec0d,0xc751b0f4,0x411a67d1,0x2da52dd6,\n        0x2b74256e,0x8bc76887 },\n      { 0x82d3d253,0xa5be3b72,0xf58d779f,0xa9f679a1,0xe16767bb,0xa1cac168,\n        0x60fcf34f,0xb386f190 } },\n    /* 159 */\n    { { 0x2fedcfc2,0x31f3c135,0x62f8af0d,0x5396bf62,0xe57288c2,0x9a02b4ea,\n        0x1b069c4d,0x4cb460f7 },\n      { 0x5b8095ea,0xae67b4d3,0x6fc07603,0x92bbf859,0xb614a165,0xe1475f66,\n        0x95ef5223,0x52c0d508 } },\n    /* 160 */\n    { { 0x15339848,0x231c210e,0x70778c8d,0xe87a28e8,0x6956e170,0x9d1de661,\n        0x2bb09c0b,0x4ac3c938 },\n      { 0x6998987d,0x19be0551,0xae09f4d6,0x8b2376c4,0x1a3f933d,0x1de0b765,\n        0xe39705f4,0x380d94c7 } },\n    /* 161 */\n    { { 0x81542e75,0x01a355aa,0xee01b9b7,0x96c724a1,0x624d7087,0x6b3a2977,\n        0xde2637af,0x2ce3e171 },\n      { 0xf5d5bc1a,0xcfefeb49,0x2777e2b5,0xa655607e,0x9513756c,0x4feaac2f,\n        0x0b624e4d,0x2e6cd852 } },\n    /* 162 */\n    { { 0x8c31c31d,0x3685954b,0x5bf21a0c,0x68533d00,0x75c79ec9,0x0bd7626e,\n        0x42c69d54,0xca177547 },\n      { 0xf6d2dbb2,0xcc6edaff,0x174a9d18,0xfd0d8cbd,0xaa4578e8,0x875e8793,\n        0x9cab2ce6,0xa976a713 } },\n    /* 163 */\n    { { 0x93fb353d,0x0a651f1b,0x57fcfa72,0xd75cab8b,0x31b15281,0xaa88cfa7,\n        0x0a1f4999,0x8720a717 },\n      { 0x693e1b90,0x8c3e8d37,0x16f6dfc3,0xd345dc0b,0xb52a8742,0x8ea8d00a,\n        0xc769893c,0x9719ef29 } },\n    /* 164 */\n    { { 0x58e35909,0x820eed8d,0x33ddc116,0x9366d8dc,0x6e205026,0xd7f999d0,\n        0xe15704c1,0xa5072976 },\n      { 0xc4e70b2e,0x002a37ea,0x6890aa8a,0x84dcf657,0x645b2a5c,0xcd71bf18,\n        0xf7b77725,0x99389c9d } },\n    /* 165 */\n    { { 0x7ada7a4b,0x238c08f2,0xfd389366,0x3abe9d03,0x766f512c,0x6b672e89,\n        0x202c82e4,0xa88806aa },\n      { 0xd380184e,0x6602044a,0x126a8b85,0xa8cb78c4,0xad844f17,0x79d670c0,\n        0x4738dcfe,0x0043bffb } },\n    /* 166 */\n    { { 0x36d5192e,0x8d59b5dc,0x4590b2af,0xacf885d3,0x11601781,0x83566d0a,\n        0xba6c4866,0x52f3ef01 },\n      { 0x0edcb64d,0x3986732a,0x8068379f,0x0a482c23,0x7040f309,0x16cbe5fa,\n        0x9ef27e75,0x3296bd89 } },\n    /* 167 */\n    { { 0x454d81d7,0x476aba89,0x51eb9b3c,0x9eade7ef,0x81c57986,0x619a21cd,\n        0xaee571e9,0x3b90febf },\n      { 0x5496f7cb,0x9393023e,0x7fb51bc4,0x55be41d8,0x99beb5ce,0x03f1dd48,\n        0x9f810b18,0x6e88069d } },\n    /* 168 */\n    { { 0xb43ea1db,0xce37ab11,0x5259d292,0x0a7ff1a9,0x8f84f186,0x851b0221,\n        0xdefaad13,0xa7222bea },\n      { 0x2b0a9144,0xa2ac78ec,0xf2fa59c5,0x5a024051,0x6147ce38,0x91d1eca5,\n        0xbc2ac690,0xbe94d523 } },\n    /* 169 */\n    { { 0x0b226ce7,0x72f4945e,0x967e8b70,0xb8afd747,0x85a6c63e,0xedea46f1,\n        0x9be8c766,0x7782defe },\n      { 0x3db38626,0x760d2aa4,0x76f67ad1,0x460ae787,0x54499cdb,0x341b86fc,\n        0xa2892e4b,0x03838567 } },\n    /* 170 */\n    { { 0x79ec1a0f,0x2d8daefd,0xceb39c97,0x3bbcd6fd,0x58f61a95,0xf5575ffc,\n        0xadf7b420,0xdbd986c4 },\n      { 0x15f39eb7,0x81aa8814,0xb98d976c,0x6ee2fcf5,0xcf2f717d,0x5465475d,\n        0x6860bbd0,0x8e24d3c4 } },\n    /* 171 */\n    { { 0x9a587390,0x749d8e54,0x0cbec588,0x12bb194f,0xb25983c6,0x46e07da4,\n        0x407bafc8,0x541a99c4 },\n      { 0x624c8842,0xdb241692,0xd86c05ff,0x6044c12a,0x4f7fcf62,0xc59d14b4,\n        0xf57d35d1,0xc0092c49 } },\n    /* 172 */\n    { { 0xdf2e61ef,0xd3cc75c3,0x2e1b35ca,0x7e8841c8,0x909f29f4,0xc62d30d1,\n        0x7286944d,0x75e40634 },\n      { 0xbbc237d0,0xe7d41fc5,0xec4f01c9,0xc9537bf0,0x282bd534,0x91c51a16,\n        0xc7848586,0x5b7cb658 } },\n    /* 173 */\n    { { 0x8a28ead1,0x964a7084,0xfd3b47f6,0x802dc508,0x767e5b39,0x9ae4bfd1,\n        0x8df097a1,0x7ae13eba },\n      { 0xeadd384e,0xfd216ef8,0xb6b2ff06,0x0361a2d9,0x4bcdb5f3,0x204b9878,\n        0xe2a8e3fd,0x787d8074 } },\n    /* 174 */\n    { { 0x757fbb1c,0xc5e25d6b,0xca201deb,0xe47bddb2,0x6d2233ff,0x4a55e9a3,\n        0x9ef28484,0x5c222819 },\n      { 0x88315250,0x773d4a85,0x827097c1,0x21b21a2b,0xdef5d33f,0xab7c4ea1,\n        0xbaf0f2b0,0xe45d37ab } },\n    /* 175 */\n    { { 0x28511c8a,0xd2df1e34,0xbdca6cd3,0xebb229c8,0x627c39a7,0x578a71a7,\n        0x84dfb9d3,0xed7bc122 },\n      { 0x93dea561,0xcf22a6df,0xd48f0ed1,0x5443f18d,0x5bad23e8,0xd8b86140,\n        0x45ca6d27,0xaac97cc9 } },\n    /* 176 */\n    { { 0xa16bd00a,0xeb54ea74,0xf5c0bcc1,0xd839e9ad,0x1f9bfc06,0x092bb7f1,\n        0x1163dc4e,0x318f97b3 },\n      { 0xc30d7138,0xecc0c5be,0xabc30220,0x44e8df23,0xb0223606,0x2bb7972f,\n        0x9a84ff4d,0xfa41faa1 } },\n    /* 177 */\n    { { 0xa6642269,0x4402d974,0x9bb783bd,0xc81814ce,0x7941e60b,0x398d38e4,\n        0x1d26e9e2,0x38bb6b2c },\n      { 0x6a577f87,0xc64e4a25,0xdc11fe1c,0x8b52d253,0x62280728,0xff336abf,\n        0xce7601a5,0x94dd0905 } },\n    /* 178 */\n    { { 0xde93f92a,0x156cf7dc,0x89b5f315,0xa01333cb,0xc995e750,0x02404df9,\n        0xd25c2ae9,0x92077867 },\n      { 0x0bf39d44,0xe2471e01,0x96bb53d7,0x5f2c9020,0x5c9c3d8f,0x4c44b7b3,\n        0xd29beb51,0x81e8428b } },\n    /* 179 */\n    { { 0xc477199f,0x6dd9c2ba,0x6b5ecdd9,0x8cb8eeee,0xee40fd0e,0x8af7db3f,\n        0xdbbfa4b1,0x1b94ab62 },\n      { 0xce47f143,0x44f0d8b3,0x63f46163,0x51e623fc,0xcc599383,0xf18f270f,\n        0x055590ee,0x06a38e28 } },\n    /* 180 */\n    { { 0xb3355b49,0x2e5b0139,0xb4ebf99b,0x20e26560,0xd269f3dc,0xc08ffa6b,\n        0x83d9d4f8,0xa7b36c20 },\n      { 0x1b3e8830,0x64d15c3a,0xa89f9c0b,0xd5fceae1,0xe2d16930,0xcfeee4a2,\n        0xa2822a20,0xbe54c6b4 } },\n    /* 181 */\n    { { 0x8d91167c,0xd6cdb3df,0xe7a6625e,0x517c3f79,0x346ac7f4,0x7105648f,\n        0xeae022bb,0xbf30a5ab },\n      { 0x93828a68,0x8e7785be,0x7f3ef036,0x5161c332,0x592146b2,0xe11b5feb,\n        0x2732d13a,0xd1c820de } },\n    /* 182 */\n    { { 0x9038b363,0x043e1347,0x6b05e519,0x58c11f54,0x6026cad1,0x4fe57abe,\n        0x68a18da3,0xb7d17bed },\n      { 0xe29c2559,0x44ca5891,0x5bfffd84,0x4f7a0376,0x74e46948,0x498de4af,\n        0x6412cc64,0x3997fd5e } },\n    /* 183 */\n    { { 0x8bd61507,0xf2074682,0x34a64d2a,0x29e132d5,0x8a8a15e3,0xffeddfb0,\n        0x3c6c13e8,0x0eeb8929 },\n      { 0xa7e259f8,0xe9b69a3e,0xd13e7e67,0xce1db7e6,0xad1fa685,0x277318f6,\n        0xc922b6ef,0x228916f8 } },\n    /* 184 */\n    { { 0x0a12ab5b,0x959ae25b,0x957bc136,0xcc11171f,0xd16e2b0c,0x8058429e,\n        0x6e93097e,0xec05ad1d },\n      { 0xac3f3708,0x157ba5be,0x30b59d77,0x31baf935,0x118234e5,0x47b55237,\n        0x7ff11b37,0x7d314156 } },\n    /* 185 */\n    { { 0xf6dfefab,0x7bd9c05c,0xdcb37707,0xbe2f2268,0x3a38bb95,0xe53ead97,\n        0x9bc1d7a3,0xe9ce66fc },\n      { 0x6f6a02a1,0x75aa1576,0x60e600ed,0x38c087df,0x68cdc1b9,0xf8947f34,\n        0x72280651,0xd9650b01 } },\n    /* 186 */\n    { { 0x5a057e60,0x504b4c4a,0x8def25e4,0xcbccc3be,0x17c1ccbd,0xa6353208,\n        0x804eb7a2,0x14d6699a },\n      { 0xdb1f411a,0x2c8a8415,0xf80d769c,0x09fbaf0b,0x1c2f77ad,0xb4deef90,\n        0x0d43598a,0x6f4c6841 } },\n    /* 187 */\n    { { 0x96c24a96,0x8726df4e,0xfcbd99a3,0x534dbc85,0x8b2ae30a,0x3c466ef2,\n        0x61189abb,0x4c4350fd },\n      { 0xf855b8da,0x2967f716,0x463c38a1,0x41a42394,0xeae93343,0xc37e1413,\n        0x5a3118b5,0xa726d242 } },\n    /* 188 */\n    { { 0x948c1086,0xdae6b3ee,0xcbd3a2e1,0xf1de503d,0x03d022f3,0x3f35ed3f,\n        0xcc6cf392,0x13639e82 },\n      { 0xcdafaa86,0x9ac938fb,0x2654a258,0xf45bc5fb,0x45051329,0x1963b26e,\n        0xc1a335a3,0xca9365e1 } },\n    /* 189 */\n    { { 0x4c3b2d20,0x3615ac75,0x904e241b,0x742a5417,0xcc9d071d,0xb08521c4,\n        0x970b72a5,0x9ce29c34 },\n      { 0x6d3e0ad6,0x8cc81f73,0xf2f8434c,0x8060da9e,0x6ce862d9,0x35ed1d1a,\n        0xab42af98,0x48c4abd7 } },\n    /* 190 */\n    { { 0x40c7485a,0xd221b0cc,0xe5274dbf,0xead455bb,0x9263d2e8,0x493c7698,\n        0xf67b33cb,0x78017c32 },\n      { 0x930cb5ee,0xb9d35769,0x0c408ed2,0xc0d14e94,0x272f1a4d,0xf8b7bf55,\n        0xde5c1c04,0x53cd0454 } },\n    /* 191 */\n    { { 0x5d28ccac,0xbcd585fa,0x005b746e,0x5f823e56,0xcd0123aa,0x7c79f0a1,\n        0xd3d7fa8f,0xeea465c1 },\n      { 0x0551803b,0x7810659f,0x7ce6af70,0x6c0b599f,0x29288e70,0x4195a770,\n        0x7ae69193,0x1b6e42a4 } },\n    /* 192 */\n    { { 0xf67d04c3,0x2e80937c,0x89eeb811,0x1e312be2,0x92594d60,0x56b5d887,\n        0x187fbd3d,0x0224da14 },\n      { 0x0c5fe36f,0x87abb863,0x4ef51f5f,0x580f3c60,0xb3b429ec,0x964fb1bf,\n        0x42bfff33,0x60838ef0 } },\n    /* 193 */\n    { { 0x7e0bbe99,0x432cb2f2,0x04aa39ee,0x7bda44f3,0x9fa93903,0x5f497c7a,\n        0x2d331643,0x636eb202 },\n      { 0x93ae00aa,0xfcfd0e61,0x31ae6d2f,0x875a00fe,0x9f93901c,0xf43658a2,\n        0x39218bac,0x8844eeb6 } },\n    /* 194 */\n    { { 0x6b3bae58,0x114171d2,0x17e39f3e,0x7db3df71,0x81a8eada,0xcd37bc7f,\n        0x51fb789e,0x27ba83dc },\n      { 0xfbf54de5,0xa7df439f,0xb5fe1a71,0x7277030b,0xdb297a48,0x42ee8e35,\n        0x87f3a4ab,0xadb62d34 } },\n    /* 195 */\n    { { 0xa175df2a,0x9b1168a2,0x618c32e9,0x082aa04f,0x146b0916,0xc9e4f2e7,\n        0x75e7c8b2,0xb990fd76 },\n      { 0x4df37313,0x0829d96b,0xd0b40789,0x1c205579,0x78087711,0x66c9ae4a,\n        0x4d10d18d,0x81707ef9 } },\n    /* 196 */\n    { { 0x03d6ff96,0x97d7cab2,0x0d843360,0x5b851bfc,0xd042db4b,0x268823c4,\n        0xd5a8aa5c,0x3792daea },\n      { 0x941afa0b,0x52818865,0x42d83671,0xf3e9e741,0x5be4e0a7,0x17c82527,\n        0x94b001ba,0x5abd635e } },\n    /* 197 */\n    { { 0x0ac4927c,0x727fa84e,0xa7c8cf23,0xe3886035,0x4adca0df,0xa4bcd5ea,\n        0x846ab610,0x5995bf21 },\n      { 0x829dfa33,0xe90f860b,0x958fc18b,0xcaafe2ae,0x78630366,0x9b3baf44,\n        0xd483411e,0x44c32ca2 } },\n    /* 198 */\n    { { 0xe40ed80c,0xa74a97f1,0x31d2ca82,0x5f938cb1,0x7c2d6ad9,0x53f2124b,\n        0x8082a54c,0x1f2162fb },\n      { 0x720b173e,0x7e467cc5,0x085f12f9,0x40e8a666,0x4c9d65dc,0x8cebc20e,\n        0xc3e907c9,0x8f1d402b } },\n    /* 199 */\n    { { 0xfbc4058a,0x4f592f9c,0x292f5670,0xb15e14b6,0xbc1d8c57,0xc55cfe37,\n        0x926edbf9,0xb1980f43 },\n      { 0x32c76b09,0x98c33e09,0x33b07f78,0x1df5279d,0x863bb461,0x6f08ead4,\n        0x37448e45,0x2828ad9b } },\n    /* 200 */\n    { { 0xc4cf4ac5,0x696722c4,0xdde64afb,0xf5ac1a3f,0xe0890832,0x0551baa2,\n        0x5a14b390,0x4973f127 },\n      { 0x322eac5d,0xe59d8335,0x0bd9b568,0x5e07eef5,0xa2588393,0xab36720f,\n        0xdb168ac7,0x6dac8ed0 } },\n    /* 201 */\n    { { 0xeda835ef,0xf7b545ae,0x1d10ed51,0x4aa113d2,0x13741b09,0x035a65e0,\n        0x20b9de4c,0x4b23ef59 },\n      { 0x3c4c7341,0xe82bb680,0x3f58bc37,0xd457706d,0xa51e3ee8,0x73527863,\n        0xddf49a4e,0x4dd71534 } },\n    /* 202 */\n    { { 0x95476cd9,0xbf944672,0xe31a725b,0x648d072f,0xfc4b67e0,0x1441c8b8,\n        0x2f4a4dbb,0xfd317000 },\n      { 0x8995d0e1,0x1cb43ff4,0x0ef729aa,0x76e695d1,0x41798982,0xe0d5f976,\n        0x9569f365,0x14fac58c } },\n    /* 203 */\n    { { 0xf312ae18,0xad9a0065,0xfcc93fc9,0x51958dc0,0x8a7d2846,0xd9a14240,\n        0x36abda50,0xed7c7651 },\n      { 0x25d4abbc,0x46270f1a,0xf1a113ea,0x9b5dd8f3,0x5b51952f,0xc609b075,\n        0x4d2e9f53,0xfefcb7f7 } },\n    /* 204 */\n    { { 0xba119185,0xbd09497a,0xaac45ba4,0xd54e8c30,0xaa521179,0x492479de,\n        0x87e0d80b,0x1801a57e },\n      { 0xfcafffb0,0x073d3f8d,0xae255240,0x6cf33c0b,0x5b5fdfbc,0x781d763b,\n        0x1ead1064,0x9f8fc11e } },\n    /* 205 */\n    { { 0x5e69544c,0x1583a171,0xf04b7813,0x0eaf8567,0x278a4c32,0x1e22a8fd,\n        0x3d3a69a9,0xa9d3809d },\n      { 0x59a2da3b,0x936c2c2c,0x1895c847,0x38ccbcf6,0x63d50869,0x5e65244e,\n        0xe1178ef7,0x3006b9ae } },\n    /* 206 */\n    { { 0xc9eead28,0x0bb1f2b0,0x89f4dfbc,0x7eef635d,0xb2ce8939,0x074757fd,\n        0x45f8f761,0x0ab85fd7 },\n      { 0x3e5b4549,0xecda7c93,0x97922f21,0x4be2bb5c,0xb43b8040,0x261a1274,\n        0x11e942c2,0xb122d675 } },\n    /* 207 */\n    { { 0x66a5ae7a,0x3be607be,0x76adcbe3,0x01e703fa,0x4eb6e5c5,0xaf904301,\n        0x097dbaec,0x9f599dc1 },\n      { 0x0ff250ed,0x6d75b718,0x349a20dc,0x8eb91574,0x10b227a3,0x425605a4,\n        0x8a294b78,0x7d5528e0 } },\n    /* 208 */\n    { { 0x20c26def,0xf0f58f66,0x582b2d1e,0x025585ea,0x01ce3881,0xfbe7d79b,\n        0x303f1730,0x28ccea01 },\n      { 0x79644ba5,0xd1dabcd1,0x06fff0b8,0x1fc643e8,0x66b3e17b,0xa60a76fc,\n        0xa1d013bf,0xc18baf48 } },\n    /* 209 */\n    { { 0x5dc4216d,0x34e638c8,0x206142ac,0x00c01067,0x95f5064a,0xd453a171,\n        0xb7a9596b,0x9def809d },\n      { 0x67ab8d2c,0x41e8642e,0x6237a2b6,0xb4240433,0x64c4218b,0x7d506a6d,\n        0x68808ce5,0x0357f8b0 } },\n    /* 210 */\n    { { 0x4cd2cc88,0x8e9dbe64,0xf0b8f39d,0xcc61c28d,0xcd30a0c8,0x4a309874,\n        0x1b489887,0xe4a01add },\n      { 0xf57cd8f9,0x2ed1eeac,0xbd594c48,0x1b767d3e,0x7bd2f787,0xa7295c71,\n        0xce10cc30,0x466d7d79 } },\n    /* 211 */\n    { { 0x9dada2c7,0x47d31892,0x8f9aa27d,0x4fa0a6c3,0x820a59e1,0x90e4fd28,\n        0x451ead1a,0xc672a522 },\n      { 0x5d86b655,0x30607cc8,0xf9ad4af1,0xf0235d3b,0x571172a6,0x99a08680,\n        0xf2a67513,0x5e3d64fa } },\n    /* 212 */\n    { { 0x9b3b4416,0xaa6410c7,0xeab26d99,0xcd8fcf85,0xdb656a74,0x5ebff74a,\n        0xeb8e42fc,0x6c8a7a95 },\n      { 0xb02a63bd,0x10c60ba7,0x8b8f0047,0x6b2f2303,0x312d90b0,0x8c6c3738,\n        0xad82ca91,0x348ae422 } },\n    /* 213 */\n    { { 0x5ccda2fb,0x7f474663,0x8e0726d2,0x22accaa1,0x492b1f20,0x85adf782,\n        0xd9ef2d2e,0xc1074de0 },\n      { 0xae9a65b3,0xfcf3ce44,0x05d7151b,0xfd71e4ac,0xce6a9788,0xd4711f50,\n        0xc9e54ffc,0xfbadfbdb } },\n    /* 214 */\n    { { 0x20a99363,0x1713f1cd,0x6cf22775,0xb915658f,0x24d359b2,0x968175cd,\n        0x83716fcd,0xb7f976b4 },\n      { 0x5d6dbf74,0x5758e24d,0x71c3af36,0x8d23bafd,0x0243dfe3,0x48f47760,\n        0xcafcc805,0xf4d41b2e } },\n    /* 215 */\n    { { 0xfdabd48d,0x51f1cf28,0x32c078a4,0xce81be36,0x117146e9,0x6ace2974,\n        0xe0160f10,0x180824ea },\n      { 0x66e58358,0x0387698b,0xce6ca358,0x63568752,0x5e41e6c5,0x82380e34,\n        0x83cf6d25,0x67e5f639 } },\n    /* 216 */\n    { { 0xcf4899ef,0xf89ccb8d,0x9ebb44c0,0x949015f0,0xb2598ec9,0x546f9276,\n        0x04c11fc6,0x9fef789a },\n      { 0x53d2a071,0x6d367ecf,0xa4519b09,0xb10e1a7f,0x611e2eef,0xca6b3fb0,\n        0xa99c4e20,0xbc80c181 } },\n    /* 217 */\n    { { 0xe5eb82e6,0x972536f8,0xf56cb920,0x1a484fc7,0x50b5da5e,0xc78e2171,\n        0x9f8cdf10,0x49270e62 },\n      { 0xea6b50ad,0x1a39b7bb,0xa2388ffc,0x9a0284c1,0x8107197b,0x5403eb17,\n        0x61372f7f,0xd2ee52f9 } },\n    /* 218 */\n    { { 0x88e0362a,0xd37cd285,0x8fa5d94d,0x442fa8a7,0xa434a526,0xaff836e5,\n        0xe5abb733,0xdfb478be },\n      { 0x673eede6,0xa91f1ce7,0x2b5b2f04,0xa5390ad4,0x5530da2f,0x5e66f7bf,\n        0x08df473a,0xd9a140b4 } },\n    /* 219 */\n    { { 0x6e8ea498,0x0e0221b5,0x3563ee09,0x62347829,0x335d2ade,0xe06b8391,\n        0x623f4b1a,0x760c058d },\n      { 0xc198aa79,0x0b89b58c,0xf07aba7f,0xf74890d2,0xfde2556a,0x4e204110,\n        0x8f190409,0x7141982d } },\n    /* 220 */\n    { { 0x4d4b0f45,0x6f0a0e33,0x392a94e1,0xd9280b38,0xb3c61d5e,0x3af324c6,\n        0x89d54e47,0x3af9d1ce },\n      { 0x20930371,0xfd8f7981,0x21c17097,0xeda2664c,0xdc42309b,0x0e9545dc,\n        0x73957dd6,0xb1f815c3 } },\n    /* 221 */\n    { { 0x89fec44a,0x84faa78e,0x3caa4caf,0xc8c2ae47,0xc1b6a624,0x691c807d,\n        0x1543f052,0xa41aed14 },\n      { 0x7d5ffe04,0x42435399,0x625b6e20,0x8bacb2df,0x87817775,0x85d660be,\n        0x86fb60ef,0xd6e9c1dd } },\n    /* 222 */\n    { { 0xc6853264,0x3aa2e97e,0xe2304a0b,0x771533b7,0xb8eae9be,0x1b912bb7,\n        0xae9bf8c2,0x9c9c6e10 },\n      { 0xe030b74c,0xa2309a59,0x6a631e90,0x4ed7494d,0xa49b79f2,0x89f44b23,\n        0x40fa61b6,0x566bd596 } },\n    /* 223 */\n    { { 0xc18061f3,0x066c0118,0x7c83fc70,0x190b25d3,0x27273245,0xf05fc8e0,\n        0xf525345e,0xcf2c7390 },\n      { 0x10eb30cf,0xa09bceb4,0x0d77703a,0xcfd2ebba,0x150ff255,0xe842c43a,\n        0x8aa20979,0x02f51755 } },\n    /* 224 */\n    { { 0xaddb7d07,0x396ef794,0x24455500,0x0b4fc742,0xc78aa3ce,0xfaff8eac,\n        0xe8d4d97d,0x14e9ada5 },\n      { 0x2f7079e2,0xdaa480a1,0xe4b0800e,0x45baa3cd,0x7838157d,0x01765e2d,\n        0x8e9d9ae8,0xa0ad4fab } },\n    /* 225 */\n    { { 0x4a653618,0x0bfb7621,0x31eaaa5f,0x1872813c,0x44949d5e,0x1553e737,\n        0x6e56ed1e,0xbcd530b8 },\n      { 0x32e9c47b,0x169be853,0xb50059ab,0xdc2776fe,0x192bfbb4,0xcdba9761,\n        0x6979341d,0x909283cf } },\n    /* 226 */\n    { { 0x76e81a13,0x67b00324,0x62171239,0x9bee1a99,0xd32e19d6,0x08ed361b,\n        0xace1549a,0x35eeb7c9 },\n      { 0x7e4e5bdc,0x1280ae5a,0xb6ceec6e,0x2dcd2cd3,0x6e266bc1,0x52e4224c,\n        0x448ae864,0x9a8b2cf4 } },\n    /* 227 */\n    { { 0x09d03b59,0xf6471bf2,0xb65af2ab,0xc90e62a3,0xebd5eec9,0xff7ff168,\n        0xd4491379,0x6bdb60f4 },\n      { 0x8a55bc30,0xdadafebc,0x10097fe0,0xc79ead16,0x4c1e3bdd,0x42e19741,\n        0x94ba08a9,0x01ec3cfd } },\n    /* 228 */\n    { { 0xdc9485c2,0xba6277eb,0x22fb10c7,0x48cc9a79,0x70a28d8a,0x4f61d60f,\n        0x475464f6,0xd1acb1c0 },\n      { 0x26f36612,0xd26902b1,0xe0618d8b,0x59c3a44e,0x308357ee,0x4df8a813,\n        0x405626c2,0x7dcd079d } },\n    /* 229 */\n    { { 0xf05a4b48,0x5ce7d4d3,0x37230772,0xadcd2952,0x812a915a,0xd18f7971,\n        0x377d19b8,0x0bf53589 },\n      { 0x6c68ea73,0x35ecd95a,0x823a584d,0xc7f3bbca,0xf473a723,0x9fb674c6,\n        0xe16686fc,0xd28be4d9 } },\n    /* 230 */\n    { { 0x38fa8e4b,0x5d2b9906,0x893fd8fc,0x559f186e,0x436fb6fc,0x3a6de2aa,\n        0x510f88ce,0xd76007aa },\n      { 0x523a4988,0x2d10aab6,0x74dd0273,0xb455cf44,0xa3407278,0x7f467082,\n        0xb303bb01,0xf2b52f68 } },\n    /* 231 */\n    { { 0x9835b4ca,0x0d57eafa,0xbb669cbc,0x2d2232fc,0xc6643198,0x8eeeb680,\n        0xcc5aed3a,0xd8dbe98e },\n      { 0xc5a02709,0xcba9be3f,0xf5ba1fa8,0x30be68e5,0xf10ea852,0xfebd43cd,\n        0xee559705,0xe01593a3 } },\n    /* 232 */\n    { { 0xea75a0a6,0xd3e5af50,0x57858033,0x512226ac,0xd0176406,0x6fe6d50f,\n        0xaeb8ef06,0xafec07b1 },\n      { 0x80bb0a31,0x7fb99567,0x37309aae,0x6f1af3cc,0x01abf389,0x9153a15a,\n        0x6e2dbfdd,0xa71b9354 } },\n    /* 233 */\n    { { 0x18f593d2,0xbf8e12e0,0xa078122b,0xd1a90428,0x0ba4f2ad,0x150505db,\n        0x628523d9,0x53a2005c },\n      { 0xe7f2b935,0x07c8b639,0xc182961a,0x2bff975a,0x7518ca2c,0x86bceea7,\n        0x3d588e3d,0xbf47d19b } },\n    /* 234 */\n    { { 0xdd7665d5,0x672967a7,0x2f2f4de5,0x4e303057,0x80d4903f,0x144005ae,\n        0x39c9a1b6,0x001c2c7f },\n      { 0x69efc6d6,0x143a8014,0x7bc7a724,0xc810bdaa,0xa78150a4,0x5f65670b,\n        0x86ffb99b,0xfdadf8e7 } },\n    /* 235 */\n    { { 0xffc00785,0xfd38cb88,0x3b48eb67,0x77fa7591,0xbf368fbc,0x0454d055,\n        0x5aa43c94,0x3a838e4d },\n      { 0x3e97bb9a,0x56166329,0x441d94d9,0x9eb93363,0x0adb2a83,0x515591a6,\n        0x873e1da3,0x3cdb8257 } },\n    /* 236 */\n    { { 0x7de77eab,0x137140a9,0x41648109,0xf7e1c50d,0xceb1d0df,0x762dcad2,\n        0xf1f57fba,0x5a60cc89 },\n      { 0x40d45673,0x80b36382,0x5913c655,0x1b82be19,0xdd64b741,0x057284b8,\n        0xdbfd8fc0,0x922ff56f } },\n    /* 237 */\n    { { 0xc9a129a1,0x1b265dee,0xcc284e04,0xa5b1ce57,0xcebfbe3c,0x04380c46,\n        0xf6c5cd62,0x72919a7d },\n      { 0x8fb90f9a,0x298f453a,0x88e4031b,0xd719c00b,0x796f1856,0xe32c0e77,\n        0x3624089a,0x5e791780 } },\n    /* 238 */\n    { { 0x7f63cdfb,0x5c16ec55,0xf1cae4fd,0x8e6a3571,0x560597ca,0xfce26bea,\n        0xe24c2fab,0x4e0a5371 },\n      { 0xa5765357,0x276a40d3,0x0d73a2b4,0x3c89af44,0x41d11a32,0xb8f370ae,\n        0xd56604ee,0xf5ff7818 } },\n    /* 239 */\n    { { 0x1a09df21,0xfbf3e3fe,0xe66e8e47,0x26d5d28e,0x29c89015,0x2096bd0a,\n        0x533f5e64,0xe41df0e9 },\n      { 0xb3ba9e3f,0x305fda40,0x2604d895,0xf2340ceb,0x7f0367c7,0x0866e192,\n        0xac4f155f,0x8edd7d6e } },\n    /* 240 */\n    { { 0x0bfc8ff3,0xc9a1dc0e,0xe936f42f,0x14efd82b,0xcca381ef,0x67016f7c,\n        0xed8aee96,0x1432c1ca },\n      { 0x70b23c26,0xec684829,0x0735b273,0xa64fe873,0xeaef0f5a,0xe389f6e5,\n        0x5ac8d2c6,0xcaef480b } },\n    /* 241 */\n    { { 0x75315922,0x5245c978,0x3063cca5,0xd8295171,0xb64ef2cb,0xf3ce60d0,\n        0x8efae236,0xd0ba177e },\n      { 0xb1b3af60,0x53a9ae8f,0x3d2da20e,0x1a796ae5,0xdf9eef28,0x01d63605,\n        0x1c54ae16,0xf31c957c } },\n    /* 242 */\n    { { 0x49cc4597,0xc0f58d52,0xbae0a028,0xdc5015b0,0x734a814a,0xefc5fc55,\n        0x96e17c3a,0x013404cb },\n      { 0xc9a824bf,0xb29e2585,0x001eaed7,0xd593185e,0x61ef68ac,0x8d6ee682,\n        0x91933e6c,0x6f377c4b } },\n    /* 243 */\n    { { 0xa8333fd2,0x9f93bad1,0x5a2a95b8,0xa8930202,0xeaf75ace,0x211e5037,\n        0xd2d09506,0x6dba3e4e },\n      { 0xd04399cd,0xa48ef98c,0xe6b73ade,0x1811c66e,0xc17ecaf3,0x72f60752,\n        0x3becf4a7,0xf13cf342 } },\n    /* 244 */\n    { { 0xa919e2eb,0xceeb9ec0,0xf62c0f68,0x83a9a195,0x7aba2299,0xcfba3bb6,\n        0x274bbad3,0xc83fa9a9 },\n      { 0x62fa1ce0,0x0d7d1b0b,0x3418efbf,0xe58b60f5,0x52706f04,0xbfa8ef9e,\n        0x5d702683,0xb49d70f4 } },\n    /* 245 */\n    { { 0xfad5513b,0x914c7510,0xb1751e2d,0x05f32eec,0xd9fb9d59,0x6d850418,\n        0x0c30f1cf,0x59cfadbb },\n      { 0x55cb7fd6,0xe167ac23,0x820426a3,0x249367b8,0x90a78864,0xeaeec58c,\n        0x354a4b67,0x5babf362 } },\n    /* 246 */\n    { { 0xee424865,0x37c981d1,0xf2e5577f,0x8b002878,0xb9e0c058,0x702970f1,\n        0x9026c8f0,0x6188c6a7 },\n      { 0xd0f244da,0x06f9a19b,0xfb080873,0x1ecced5c,0x9f213637,0x35470f9b,\n        0xdf50b9d9,0x993fe475 } },\n    /* 247 */\n    { { 0x9b2c3609,0x68e31cdf,0x2c46d4ea,0x84eb19c0,0x9a775101,0x7ac9ec1a,\n        0x4c80616b,0x81f76466 },\n      { 0x75fbe978,0x1d7c2a5a,0xf183b356,0x6743fed3,0x501dd2bf,0x838d1f04,\n        0x5fe9060d,0x564a812a } },\n    /* 248 */\n    { { 0xfa817d1d,0x7a5a64f4,0xbea82e0f,0x55f96844,0xcd57f9aa,0xb5ff5a0f,\n        0x00e51d6c,0x226bf3cf },\n      { 0x2f2833cf,0xd6d1a9f9,0x4f4f89a8,0x20a0a35a,0x8f3f7f77,0x11536c49,\n        0xff257836,0x68779f47 } },\n    /* 249 */\n    { { 0x73043d08,0x79b0c1c1,0x1fc020fa,0xa5446774,0x9a6d26d0,0xd3767e28,\n        0xeb092e0b,0x97bcb0d1 },\n      { 0xf32ed3c3,0x2ab6eaa8,0xb281bc48,0xc8a4f151,0xbfa178f3,0x4d1bf4f3,\n        0x0a784655,0xa872ffe8 } },\n    /* 250 */\n    { { 0xa32b2086,0xb1ab7935,0x8160f486,0xe1eb710e,0x3b6ae6be,0x9bd0cd91,\n        0xb732a36a,0x02812bfc },\n      { 0xcf605318,0xa63fd7ca,0xfdfd6d1d,0x646e5d50,0x2102d619,0xa1d68398,\n        0xfe5396af,0x07391cc9 } },\n    /* 251 */\n    { { 0x8b80d02b,0xc50157f0,0x62877f7f,0x6b8333d1,0x78d542ae,0x7aca1af8,\n        0x7e6d2a08,0x355d2adc },\n      { 0x287386e1,0xb41f335a,0xf8e43275,0xfd272a94,0xe79989ea,0x286ca2cd,\n        0x7c2a3a79,0x3dc2b1e3 } },\n    /* 252 */\n    { { 0x04581352,0xd689d21c,0x376782be,0x0a00c825,0x9fed701f,0x203bd590,\n        0x3ccd846b,0xc4786910 },\n      { 0x24c768ed,0x5dba7708,0x6841f657,0x72feea02,0x6accce0e,0x73313ed5,\n        0xd5bb4d32,0xccc42968 } },\n    /* 253 */\n    { { 0x3d7620b9,0x94e50de1,0x5992a56a,0xd89a5c8a,0x675487c9,0xdc007640,\n        0xaa4871cf,0xe147eb42 },\n      { 0xacf3ae46,0x274ab4ee,0x50350fbe,0xfd4936fb,0x48c840ea,0xdf2afe47,\n        0x080e96e3,0x239ac047 } },\n    /* 254 */\n    { { 0x2bfee8d4,0x481d1f35,0xfa7b0fec,0xce80b5cf,0x2ce9af3c,0x105c4c9e,\n        0xf5f7e59d,0xc55fa1a3 },\n      { 0x8257c227,0x3186f14e,0x342be00b,0xc5b1653f,0xaa904fb2,0x09afc998,\n        0xd4f4b699,0x094cd99c } },\n    /* 255 */\n    { { 0xd703beba,0x8a981c84,0x32ceb291,0x8631d150,0xe3bd49ec,0xa445f2c9,\n        0x42abad33,0xb90a30b6 },\n      { 0xb4a5abf9,0xb465404f,0x75db7603,0x004750c3,0xca35d89f,0x6f9a42cc,\n        0x1b7924f7,0x019f8b9a } },\n};\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table,\n                                      k, map, heap);\n}\n\n#endif\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[8];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 8, km);\n\n            err = sp_256_ecc_mulmod_base_8(point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_8(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                                        defined(HAVE_ECC_VERIFY)\n/* Returns 1 if the number of zero.\n * Implementation is constant time.\n *\n * a  Number to check.\n * returns 1 if the number is zero and 0 otherwise.\n */\nstatic int sp_256_iszero_8(const sp_digit* a)\n{\n    return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7]) == 0;\n}\n\n#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\n/* Add 1 to a. (a = a + 1)\n *\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_256_add_one_8(sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr2, #1\\n\\t\"\n        \"ldr\tr1, [%[a], #0]\\n\\t\"\n        \"add\tr1, r2\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"str\tr1, [%[a], #0]\\n\\t\"\n        \"ldr\tr1, [%[a], #4]\\n\\t\"\n        \"adc\tr1, r2\\n\\t\"\n        \"str\tr1, [%[a], #4]\\n\\t\"\n        \"ldr\tr1, [%[a], #8]\\n\\t\"\n        \"adc\tr1, r2\\n\\t\"\n        \"str\tr1, [%[a], #8]\\n\\t\"\n        \"ldr\tr1, [%[a], #12]\\n\\t\"\n        \"adc\tr1, r2\\n\\t\"\n        \"str\tr1, [%[a], #12]\\n\\t\"\n        \"ldr\tr1, [%[a], #16]\\n\\t\"\n        \"adc\tr1, r2\\n\\t\"\n        \"str\tr1, [%[a], #16]\\n\\t\"\n        \"ldr\tr1, [%[a], #20]\\n\\t\"\n        \"adc\tr1, r2\\n\\t\"\n        \"str\tr1, [%[a], #20]\\n\\t\"\n        \"ldr\tr1, [%[a], #24]\\n\\t\"\n        \"adc\tr1, r2\\n\\t\"\n        \"str\tr1, [%[a], #24]\\n\\t\"\n        \"ldr\tr1, [%[a], #28]\\n\\t\"\n        \"adc\tr1, r2\\n\\t\"\n        \"str\tr1, [%[a], #28]\\n\\t\"\n        :\n        : [a] \"r\" (a)\n        : \"memory\", \"r1\", \"r2\"\n    );\n}\n\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 24U) {\n            r[j] &= 0xffffffff;\n            s = 32U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Generates a scalar that is in the range 1..order-1.\n *\n * rng  Random number generator.\n * k    Scalar value.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nstatic int sp_256_ecc_gen_k_8(WC_RNG* rng, sp_digit* k)\n{\n    int err;\n    byte buf[32];\n\n    do {\n        err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));\n        if (err == 0) {\n            sp_256_from_bin(k, 8, buf, (int)sizeof(buf));\n            if (sp_256_cmp_8(k, p256_order2) < 0) {\n                sp_256_add_one_8(k);\n                break;\n            }\n        }\n    }\n    while (err == 0);\n\n    return err;\n}\n\n/* Makes a random EC key pair.\n *\n * rng   Random number generator.\n * priv  Generated private value.\n * pub   Generated public point.\n * heap  Heap to use for allocation.\n * returns ECC_INF_E when the point does not have the correct order, RNG\n * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[8];\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point inf;\n#endif\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point* infinity;\n#endif\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, inf, infinity);\n    }\n#endif\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_ecc_gen_k_8(rng, k);\n    }\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);\n    }\n\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_8(infinity, point, p256_order, 1, NULL);\n    }\n    if (err == MP_OKAY) {\n        if ((sp_256_iszero_8(point->x) == 0) || (sp_256_iszero_8(point->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(k, priv);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_8(point, pub);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_ecc_point_free(infinity, 1, heap);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n\n#ifdef HAVE_ECC_DHE\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 32\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_256_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 256 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<8 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 32) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 32);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n/* Multiply the point by the scalar and serialize the X ordinate.\n * The number is 0 padded to maximum size on output.\n *\n * priv    Scalar to multiply the point by.\n * pub     Point to multiply.\n * out     Buffer to hold X ordinate.\n * outLen  On entry, size of the buffer in bytes.\n *         On exit, length of data in buffer in bytes.\n * heap    Heap to use for allocation.\n * returns BUFFER_E if the buffer is to small for output size,\n * MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out,\n                          word32* outLen, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[8];\n#endif\n    sp_point* point = NULL;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    if (*outLen < 32U) {\n        err = BUFFER_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p, point);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 8, priv);\n        sp_256_point_from_ecc_point_8(point, pub);\n            err = sp_256_ecc_mulmod_8(point, point, k, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        sp_256_to_bin(point->x, out);\n        *outLen = 32;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_DHE */\n\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_256_sub_in_place_8(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n    __asm__ __volatile__ (\n        \"mov\tr7, %[a]\\n\\t\"\n        \"add\tr7, #32\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a]]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        \"add\t%[a], #8\\n\\t\"\n        \"add\t%[b], #8\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#else\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_256_sub_in_place_8(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b], #0]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sub\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #0]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr5, [%[b], #8]\\n\\t\"\n        \"ldr\tr6, [%[b], #12]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #8]\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr5, [%[b], #16]\\n\\t\"\n        \"ldr\tr6, [%[b], #20]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #16]\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"ldr\tr5, [%[b], #24]\\n\\t\"\n        \"ldr\tr6, [%[b], #28]\\n\\t\"\n        \"sbc\tr3, r5\\n\\t\"\n        \"sbc\tr4, r6\\n\\t\"\n        \"str\tr3, [%[a], #24]\\n\\t\"\n        \"str\tr4, [%[a], #28]\\n\\t\"\n        \"sbc\t%[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nSP_NOINLINE static void sp_256_mul_d_8(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n    __asm__ __volatile__ (\n        \"mov\tr6, #32\\n\\t\"\n        \"add\tr6, %[a]\\n\\t\"\n        \"mov\tr8, %[r]\\n\\t\"\n        \"mov\tr9, r6\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"# A[] * B\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"lsl\tr7, %[b], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr3, r7\\n\\t\"\n        \"adc\tr4, %[r]\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"lsr\tr7, %[b], #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"lsr\tr7, %[b], #16\\n\\t\"\n        \"mul\tr7, r6\\n\\t\"\n        \"add\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"lsl\tr7, %[b], #16\\n\\t\"\n        \"lsr\tr7, r7, #16\\n\\t\"\n        \"mul\tr6, r7\\n\\t\"\n        \"lsr\tr7, r6, #16\\n\\t\"\n        \"lsl\tr6, r6, #16\\n\\t\"\n        \"add\tr3, r6\\n\\t\"\n        \"adc\tr4, r7\\n\\t\"\n        \"adc\tr5, %[r]\\n\\t\"\n        \"# A[] * B - Done\\n\\t\"\n        \"mov\t%[r], r8\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\t%[r], #4\\n\\t\"\n        \"add\t%[a], #4\\n\\t\"\n        \"mov\tr8, %[r]\\n\\t\"\n        \"cmp\t%[a], r9\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        : [r] \"+r\" (r), [a] \"+r\" (a)\n        : [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\"\n    );\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nSP_NOINLINE static sp_digit div_256_word_8(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr5, %[div], #1\\n\\t\"\n        \"add\tr5, #1\\n\\t\"\n        \"mov\tr8, %[d0]\\n\\t\"\n        \"mov\tr9, %[d1]\\n\\t\"\n        \"# Do top 32\\n\\t\"\n        \"mov\tr6, r5\\n\\t\"\n        \"sub\tr6, %[d1]\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        \"and\tr6, r5\\n\\t\"\n        \"sub\t%[d1], r6\\n\\t\"\n        \"# Next 30 bits\\n\\t\"\n        \"mov\tr4, #29\\n\\t\"\n        \"1:\\n\\t\"\n        \"lsl\t%[d0], %[d0], #1\\n\\t\"\n        \"adc\t%[d1], %[d1]\\n\\t\"\n        \"mov\tr6, r5\\n\\t\"\n        \"sub\tr6, %[d1]\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        \"and\tr6, r5\\n\\t\"\n        \"sub\t%[d1], r6\\n\\t\"\n        \"sub\tr4, #1\\n\\t\"\n        \"bpl\t1b\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\t%[r], %[r]\\n\\t\"\n        \"add\t%[r], #1\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"sub\t%[d1], r4\\n\\t\"\n        \"mov\tr4, %[d1]\\n\\t\"\n        \"mov\t%[d1], r9\\n\\t\"\n        \"sbc\t%[d1], r5\\n\\t\"\n        \"mov\tr5, %[d1]\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sub\tr4, %[d1], r4\\n\\t\"\n        \"sbc\tr6, r5\\n\\t\"\n        \"mov\tr5, r6\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"# r * div - Start\\n\\t\"\n        \"lsl\t%[d1], %[r], #16\\n\\t\"\n        \"lsl\tr4, %[div], #16\\n\\t\"\n        \"lsr\t%[d1], %[d1], #16\\n\\t\"\n        \"lsr\tr4, r4, #16\\n\\t\"\n        \"mul\tr4, %[d1]\\n\\t\"\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr5, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r7\\n\\t\"\n        \"lsr\t%[d1], %[r], #16\\n\\t\"\n        \"mul\tr6, %[d1]\\n\\t\"\n        \"add\tr5, r6\\n\\t\"\n        \"lsl\tr6, %[div], #16\\n\\t\"\n        \"lsr\tr6, r6, #16\\n\\t\"\n        \"mul\t%[d1], r6\\n\\t\"\n        \"lsr\tr6, %[d1], #16\\n\\t\"\n        \"lsl\t%[d1], %[d1], #16\\n\\t\"\n        \"add\tr4, %[d1]\\n\\t\"\n        \"adc\tr5, r6\\n\\t\"\n        \"# r * div - Done\\n\\t\"\n        \"mov\t%[d1], r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sub\tr4, %[d1], r4\\n\\t\"\n        \"sbc\tr6, r5\\n\\t\"\n        \"mov\tr5, r6\\n\\t\"\n        \"add\t%[r], r5\\n\\t\"\n        \"mov\tr6, %[div]\\n\\t\"\n        \"sub\tr6, r4\\n\\t\"\n        \"sbc\tr6, r6\\n\\t\"\n        \"sub\t%[r], r6\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r7\", \"r6\", \"r8\", \"r9\"\n    );\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_256_mask_8(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<8; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    r[0] = a[0] & m;\n    r[1] = a[1] & m;\n    r[2] = a[2] & m;\n    r[3] = a[3] & m;\n    r[4] = a[4] & m;\n    r[5] = a[5] & m;\n    r[6] = a[6] & m;\n    r[7] = a[7] & m;\n#endif\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_256_div_8(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[16], t2[9];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[7];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 8);\n    for (i=7; i>=0; i--) {\n        r1 = div_256_word_8(t1[8 + i], t1[8 + i - 1], div);\n\n        sp_256_mul_d_8(t2, d, r1);\n        t1[8 + i] += sp_256_sub_in_place_8(&t1[i], t2);\n        t1[8 + i] -= t2[8];\n        sp_256_mask_8(t2, d, t1[8 + i]);\n        t1[8 + i] += sp_256_add_8(&t1[i], &t1[i], t2);\n        sp_256_mask_8(t2, d, t1[8 + i]);\n        t1[8 + i] += sp_256_add_8(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_256_cmp_8(t1, d) >= 0;\n    sp_256_cond_sub_8(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_256_mod_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_256_div_8(a, m, NULL, r);\n}\n\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#ifdef WOLFSSL_SP_SMALL\n/* Order-2 for the P256 curve. */\nstatic const uint32_t p256_order_2[8] = {\n    0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU,0xffffffffU,0xffffffffU,\n    0x00000000U,0xffffffffU\n};\n#else\n/* The low half of the order-2 of the P256 curve. */\nstatic const uint32_t p256_order_low[4] = {\n    0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU\n};\n#endif /* WOLFSSL_SP_SMALL */\n\n/* Multiply two number mod the order of P256 curve. (r = a * b mod order)\n *\n * r  Result of the multiplication.\n * a  First operand of the multiplication.\n * b  Second operand of the multiplication.\n */\nstatic void sp_256_mont_mul_order_8(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_256_mul_8(r, a, b);\n    sp_256_mont_reduce_order_8(r, p256_order, p256_mp_order);\n}\n\n/* Square number mod the order of P256 curve. (r = a * a mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_order_8(sp_digit* r, const sp_digit* a)\n{\n    sp_256_sqr_8(r, a);\n    sp_256_mont_reduce_order_8(r, p256_order, p256_mp_order);\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Square number mod the order of P256 curve a number of times.\n * (r = a ^ n mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_n_order_8(sp_digit* r, const sp_digit* a, int n)\n{\n    int i;\n\n    sp_256_mont_sqr_order_8(r, a);\n    for (i=1; i<n; i++) {\n        sp_256_mont_sqr_order_8(r, r);\n    }\n}\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the order of the P256 curve.\n * (r = 1 / a mod order)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a,\n        sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 8);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_order_8(t, t);\n        if ((p256_order_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t, t, a);\n        }\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 8U);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 8;\n    sp_digit* t3 = td + 4 * 8;\n    int i;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_order_8(t, a);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_order_8(t, t, a);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_order_8(t2, t, 2);\n    /* t3= a^f = t2 * t */\n    sp_256_mont_mul_order_8(t3, t2, t);\n    /* t2= a^f0 = t3 ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_order_8(t2, t3, 4);\n    /* t = a^ff = t2 * t3 */\n    sp_256_mont_mul_order_8(t, t2, t3);\n    /* t3= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_order_8(t2, t, 8);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_order_8(t, t2, t);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_order_8(t2, t, 16);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_order_8(t, t2, t);\n    /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64  */\n    sp_256_mont_sqr_n_order_8(t2, t, 64);\n    /* t2= a^ffffffff00000000ffffffff = t2 * t */\n    sp_256_mont_mul_order_8(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_order_8(t2, t2, 32);\n    /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_order_8(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6 */\n    for (i=127; i>=112; i--) {\n        sp_256_mont_sqr_order_8(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6f */\n    sp_256_mont_sqr_n_order_8(t2, t2, 4);\n    sp_256_mont_mul_order_8(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */\n    for (i=107; i>=64; i--) {\n        sp_256_mont_sqr_order_8(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */\n    sp_256_mont_sqr_n_order_8(t2, t2, 4);\n    sp_256_mont_mul_order_8(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */\n    for (i=59; i>=32; i--) {\n        sp_256_mont_sqr_order_8(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */\n    sp_256_mont_sqr_n_order_8(t2, t2, 4);\n    sp_256_mont_mul_order_8(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */\n    for (i=27; i>=0; i--) {\n        sp_256_mont_sqr_order_8(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */\n    sp_256_mont_sqr_n_order_8(t2, t2, 4);\n    /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */\n    sp_256_mont_mul_order_8(r, t2, t3);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\n#ifdef HAVE_ECC_SIGN\n#ifndef SP_ECC_MAX_SIG_GEN\n#define SP_ECC_MAX_SIG_GEN  64\n#endif\n\n/* Sign the hash using the private key.\n *   e = [hash, 256 bits] from binary\n *   r = (k.G)->x mod order\n *   s = (r * x + e) / k mod order\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,\n                    mp_int* rm, mp_int* sm, mp_int* km, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit ed[2*8];\n    sp_digit xd[2*8];\n    sp_digit kd[2*8];\n    sp_digit rd[2*8];\n    sp_digit td[3 * 2*8];\n    sp_point p;\n#endif\n    sp_digit* e = NULL;\n    sp_digit* x = NULL;\n    sp_digit* k = NULL;\n    sp_digit* r = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* point = NULL;\n    sp_digit carry;\n    sp_digit* s = NULL;\n    sp_digit* kInv = NULL;\n    int err = MP_OKAY;\n    int32_t c;\n    int i;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        e = d + 0 * 8;\n        x = d + 2 * 8;\n        k = d + 4 * 8;\n        r = d + 6 * 8;\n        tmp = d + 8 * 8;\n#else\n        e = ed;\n        x = xd;\n        k = kd;\n        r = rd;\n        tmp = td;\n#endif\n        s = e;\n        kInv = k;\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(e, 8, hash, (int)hashLen);\n    }\n\n    for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {\n        sp_256_from_mp(x, 8, priv);\n\n        /* New random point. */\n        if (km == NULL || mp_iszero(km)) {\n            err = sp_256_ecc_gen_k_8(rng, k);\n        }\n        else {\n            sp_256_from_mp(k, 8, km);\n            mp_zero(km);\n        }\n        if (err == MP_OKAY) {\n                err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);\n        }\n\n        if (err == MP_OKAY) {\n            /* r = point->x mod order */\n            XMEMCPY(r, point->x, sizeof(sp_digit) * 8U);\n            sp_256_norm_8(r);\n            c = sp_256_cmp_8(r, p256_order);\n            sp_256_cond_sub_8(r, r, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_8(r);\n\n            /* Conv k to Montgomery form (mod order) */\n                sp_256_mul_8(k, k, p256_norm_order);\n            err = sp_256_mod_8(k, k, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_8(k);\n            /* kInv = 1/k mod order */\n                sp_256_mont_inv_order_8(kInv, k, tmp);\n            sp_256_norm_8(kInv);\n\n            /* s = r * x + e */\n                sp_256_mul_8(x, x, r);\n            err = sp_256_mod_8(x, x, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_8(x);\n            carry = sp_256_add_8(s, e, x);\n            sp_256_cond_sub_8(s, s, p256_order, 0 - carry);\n            sp_256_norm_8(s);\n            c = sp_256_cmp_8(s, p256_order);\n            sp_256_cond_sub_8(s, s, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_8(s);\n\n            /* s = s * k^-1 mod order */\n                sp_256_mont_mul_order_8(s, s, kInv);\n            sp_256_norm_8(s);\n\n            /* Check that signature is usable. */\n            if (sp_256_iszero_8(s) == 0) {\n                break;\n            }\n        }\n    }\n\n    if (i == 0) {\n        err = RNG_FAILURE_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(r, rm);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(s, sm);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XMEMSET(d, 0, sizeof(sp_digit) * 8 * 8);\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    XMEMSET(e, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(x, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(k, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 8U);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_SIGN */\n\n#ifdef HAVE_ECC_VERIFY\n/* Verify the signature values with the hash and public key.\n *   e = Truncate(hash, 256)\n *   u1 = e/s mod order\n *   u2 = r/s mod order\n *   r == (u1.G + u2.Q)->x mod order\n * Optimization: Leave point in projective form.\n *   (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')\n *   (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,\n    mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit u1d[2*8];\n    sp_digit u2d[2*8];\n    sp_digit sd[2*8];\n    sp_digit tmpd[2*8 * 5];\n    sp_point p1d;\n    sp_point p2d;\n#endif\n    sp_digit* u1 = NULL;\n    sp_digit* u2 = NULL;\n    sp_digit* s = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* p1;\n    sp_point* p2 = NULL;\n    sp_digit carry;\n    int32_t c;\n    int err;\n\n    err = sp_ecc_point_new(heap, p1d, p1);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p2d, p2);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        u1  = d + 0 * 8;\n        u2  = d + 2 * 8;\n        s   = d + 4 * 8;\n        tmp = d + 6 * 8;\n#else\n        u1 = u1d;\n        u2 = u2d;\n        s  = sd;\n        tmp = tmpd;\n#endif\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(u1, 8, hash, (int)hashLen);\n        sp_256_from_mp(u2, 8, r);\n        sp_256_from_mp(s, 8, sm);\n        sp_256_from_mp(p2->x, 8, pX);\n        sp_256_from_mp(p2->y, 8, pY);\n        sp_256_from_mp(p2->z, 8, pZ);\n\n        {\n            sp_256_mul_8(s, s, p256_norm_order);\n        }\n        err = sp_256_mod_8(s, s, p256_order);\n    }\n    if (err == MP_OKAY) {\n        sp_256_norm_8(s);\n        {\n            sp_256_mont_inv_order_8(s, s, tmp);\n            sp_256_mont_mul_order_8(u1, u1, s);\n            sp_256_mont_mul_order_8(u2, u2, s);\n        }\n\n            err = sp_256_ecc_mulmod_base_8(p1, u1, 0, heap);\n    }\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_8(p2, p2, u2, 0, heap);\n    }\n\n    if (err == MP_OKAY) {\n        {\n            sp_256_proj_point_add_8(p1, p1, p2, tmp);\n            if (sp_256_iszero_8(p1->z)) {\n                if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) {\n                    sp_256_proj_point_dbl_8(p1, p2, tmp);\n                }\n                else {\n                    /* Y ordinate is not used from here - don't set. */\n                    p1->x[0] = 0;\n                    p1->x[1] = 0;\n                    p1->x[2] = 0;\n                    p1->x[3] = 0;\n                    p1->x[4] = 0;\n                    p1->x[5] = 0;\n                    p1->x[6] = 0;\n                    p1->x[7] = 0;\n                    XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));\n                }\n            }\n        }\n\n        /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */\n        /* Reload r and convert to Montgomery form. */\n        sp_256_from_mp(u2, 8, r);\n        err = sp_256_mod_mul_norm_8(u2, u2, p256_mod);\n    }\n\n    if (err == MP_OKAY) {\n        /* u1 = r.z'.z' mod prime */\n        sp_256_mont_sqr_8(p1->z, p1->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(u1, u2, p1->z, p256_mod, p256_mp_mod);\n        *res = (int)(sp_256_cmp_8(p1->x, u1) == 0);\n        if (*res == 0) {\n            /* Reload r and add order. */\n            sp_256_from_mp(u2, 8, r);\n            carry = sp_256_add_8(u2, u2, p256_order);\n            /* Carry means result is greater than mod and is not valid. */\n            if (carry == 0) {\n                sp_256_norm_8(u2);\n\n                /* Compare with mod and if greater or equal then not valid. */\n                c = sp_256_cmp_8(u2, p256_mod);\n                if (c < 0) {\n                    /* Convert to Montogomery form */\n                    err = sp_256_mod_mul_norm_8(u2, u2, p256_mod);\n                    if (err == MP_OKAY) {\n                        /* u1 = (r + 1*order).z'.z' mod prime */\n                        sp_256_mont_mul_8(u1, u2, p1->z, p256_mod,\n                                                                  p256_mp_mod);\n                        *res = (int)(sp_256_cmp_8(p1->x, u1) == 0);\n                    }\n                }\n            }\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n#endif\n    sp_ecc_point_free(p1, 0, heap);\n    sp_ecc_point_free(p2, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_VERIFY */\n\n#ifdef HAVE_ECC_CHECK_KEY\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * point  EC point.\n * heap   Heap to use if dynamically allocating.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nstatic int sp_256_ecc_is_point_8(sp_point* point, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit t1d[2*8];\n    sp_digit t2d[2*8];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8 * 4, heap, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 8;\n        t2 = d + 2 * 8;\n#else\n        (void)heap;\n\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        sp_256_sqr_8(t1, point->y);\n        (void)sp_256_mod_8(t1, t1, p256_mod);\n        sp_256_sqr_8(t2, point->x);\n        (void)sp_256_mod_8(t2, t2, p256_mod);\n        sp_256_mul_8(t2, t2, point->x);\n        (void)sp_256_mod_8(t2, t2, p256_mod);\n        (void)sp_256_sub_8(t2, p256_mod, t2);\n        sp_256_mont_add_8(t1, t1, t2, p256_mod);\n\n        sp_256_mont_add_8(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_8(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_8(t1, t1, point->x, p256_mod);\n\n        if (sp_256_cmp_8(t1, p256_b) != 0) {\n            err = MP_VAL;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * pX  X ordinate of EC point.\n * pY  Y ordinate of EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nint sp_ecc_is_point_256(mp_int* pX, mp_int* pY)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point pubd;\n#endif\n    sp_point* pub;\n    byte one[1] = { 1 };\n    int err;\n\n    err = sp_ecc_point_new(NULL, pubd, pub);\n    if (err == MP_OKAY) {\n        sp_256_from_mp(pub->x, 8, pX);\n        sp_256_from_mp(pub->y, 8, pY);\n        sp_256_from_bin(pub->z, 8, one, (int)sizeof(one));\n\n        err = sp_256_ecc_is_point_8(pub, NULL);\n    }\n\n    sp_ecc_point_free(pub, 0, NULL);\n\n    return err;\n}\n\n/* Check that the private scalar generates the EC point (px, py), the point is\n * on the curve and the point has the correct order.\n *\n * pX     X ordinate of EC point.\n * pY     Y ordinate of EC point.\n * privm  Private scalar that generates EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve, ECC_INF_E if the point does not have the correct order,\n * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and\n * MP_OKAY otherwise.\n */\nint sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit privd[8];\n    sp_point pubd;\n    sp_point pd;\n#endif\n    sp_digit* priv = NULL;\n    sp_point* pub;\n    sp_point* p = NULL;\n    byte one[1] = { 1 };\n    int err;\n\n    err = sp_ecc_point_new(heap, pubd, pub);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (priv == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK))\n        priv = privd;\n#endif\n\n        sp_256_from_mp(pub->x, 8, pX);\n        sp_256_from_mp(pub->y, 8, pY);\n        sp_256_from_bin(pub->z, 8, one, (int)sizeof(one));\n        sp_256_from_mp(priv, 8, privm);\n\n        /* Check point at infinitiy. */\n        if ((sp_256_iszero_8(pub->x) != 0) &&\n            (sp_256_iszero_8(pub->y) != 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check range of X and Y */\n        if (sp_256_cmp_8(pub->x, p256_mod) >= 0 ||\n            sp_256_cmp_8(pub->y, p256_mod) >= 0) {\n            err = ECC_OUT_OF_RANGE_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check point is on curve */\n        err = sp_256_ecc_is_point_8(pub, heap);\n    }\n\n    if (err == MP_OKAY) {\n        /* Point * order = infinity */\n            err = sp_256_ecc_mulmod_8(p, pub, p256_order, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is infinity */\n        if ((sp_256_iszero_8(p->x) == 0) ||\n            (sp_256_iszero_8(p->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Base * private = point */\n            err = sp_256_ecc_mulmod_base_8(p, priv, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is public key */\n        if (sp_256_cmp_8(p->x, pub->x) != 0 ||\n            sp_256_cmp_8(p->y, pub->y) != 0) {\n            err = ECC_PRIV_KEY_E;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (priv != NULL) {\n        XFREE(priv, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(pub, 0, heap);\n\n    return err;\n}\n#endif\n#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL\n/* Add two projective EC points together.\n * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)\n *\n * pX   First EC point's X ordinate.\n * pY   First EC point's Y ordinate.\n * pZ   First EC point's Z ordinate.\n * qX   Second EC point's X ordinate.\n * qY   Second EC point's Y ordinate.\n * qZ   Second EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* qX, mp_int* qY, mp_int* qZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 8 * 5];\n    sp_point pd;\n    sp_point qd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    sp_point* q = NULL;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(NULL, qd, q);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 8, pX);\n        sp_256_from_mp(p->y, 8, pY);\n        sp_256_from_mp(p->z, 8, pZ);\n        sp_256_from_mp(q->x, 8, qX);\n        sp_256_from_mp(q->y, 8, qY);\n        sp_256_from_mp(q->z, 8, qZ);\n\n            sp_256_proj_point_add_8(p, p, q, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(q, 0, NULL);\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Double a projective EC point.\n * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 8 * 2];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 2, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 8, pX);\n        sp_256_from_mp(p->y, 8, pY);\n        sp_256_from_mp(p->z, 8, pZ);\n\n            sp_256_proj_point_dbl_8(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Map a projective EC point to affine in place.\n * pZ will be one.\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 8 * 4];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 4, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 8, pX);\n        sp_256_from_mp(p->y, 8, pY);\n        sp_256_from_mp(p->z, 8, pZ);\n\n        sp_256_map_8(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, pX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */\n#ifdef HAVE_COMP_KEY\n/* Find the square root of a number mod the prime of the curve.\n *\n * y  The number to operate on and the result.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nstatic int sp_256_mont_sqrt_8(sp_digit* y)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit t1d[2 * 8];\n    sp_digit t2d[2 * 8];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 8, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 8;\n        t2 = d + 2 * 8;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        {\n            /* t2 = y ^ 0x2 */\n            sp_256_mont_sqr_8(t2, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0x3 */\n            sp_256_mont_mul_8(t1, t2, y, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xc */\n            sp_256_mont_sqr_n_8(t2, t1, 2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xf */\n            sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xf0 */\n            sp_256_mont_sqr_n_8(t2, t1, 4, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xff */\n            sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xff00 */\n            sp_256_mont_sqr_n_8(t2, t1, 8, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffff */\n            sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xffff0000 */\n            sp_256_mont_sqr_n_8(t2, t1, 16, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff */\n            sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000000 */\n            sp_256_mont_sqr_n_8(t1, t1, 32, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001 */\n            sp_256_mont_mul_8(t1, t1, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */\n            sp_256_mont_sqr_n_8(t1, t1, 96, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */\n            sp_256_mont_mul_8(t1, t1, y, p256_mod, p256_mp_mod);\n            sp_256_mont_sqr_n_8(y, t1, 94, p256_mod, p256_mp_mod);\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Uncompress the point given the X ordinate.\n *\n * xm    X ordinate.\n * odd   Whether the Y ordinate is odd.\n * ym    Calculated Y ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit xd[2 * 8];\n    sp_digit yd[2 * 8];\n#endif\n    sp_digit* x = NULL;\n    sp_digit* y = NULL;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 8, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        x = d + 0 * 8;\n        y = d + 2 * 8;\n#else\n        x = xd;\n        y = yd;\n#endif\n\n        sp_256_from_mp(x, 8, xm);\n        err = sp_256_mod_mul_norm_8(x, x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        /* y = x^3 */\n        {\n            sp_256_mont_sqr_8(y, x, p256_mod, p256_mp_mod);\n            sp_256_mont_mul_8(y, y, x, p256_mod, p256_mp_mod);\n        }\n        /* y = x^3 - 3x */\n        sp_256_mont_sub_8(y, y, x, p256_mod);\n        sp_256_mont_sub_8(y, y, x, p256_mod);\n        sp_256_mont_sub_8(y, y, x, p256_mod);\n        /* y = x^3 - 3x + b */\n        err = sp_256_mod_mul_norm_8(x, p256_b, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        sp_256_mont_add_8(y, y, x, p256_mod);\n        /* y = sqrt(x^3 - 3x + b) */\n        err = sp_256_mont_sqrt_8(y);\n    }\n    if (err == MP_OKAY) {\n        XMEMSET(y + 8, 0, 8U * sizeof(sp_digit));\n        sp_256_mont_reduce_8(y, p256_mod, p256_mp_mod);\n        if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {\n            sp_256_mont_sub_8(y, p256_mod, y, p256_mod);\n        }\n\n        err = sp_256_to_mp(y, ym);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n#endif\n#endif /* !WOLFSSL_SP_NO_256 */\n#endif /* WOLFSSL_HAVE_SP_ECC */\n#endif /* WOLFSSL_SP_ARM_THUMB_ASM */\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */\n"
  },
  {
    "path": "src/wolfcrypt/src/sp_c32.c",
    "content": "/* sp.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/* Implementation by Sean Parkinson. */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/cpuid.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \\\n                                    defined(WOLFSSL_HAVE_SP_ECC)\n\n#ifdef RSA_LOW_MEM\n#ifndef SP_RSA_PRIVATE_EXP_D\n#define SP_RSA_PRIVATE_EXP_D\n#endif\n\n#ifndef WOLFSSL_SP_SMALL\n#define WOLFSSL_SP_SMALL\n#endif\n#endif\n\n#include <wolfssl/wolfcrypt/sp.h>\n\n#ifndef WOLFSSL_SP_ASM\n#if SP_WORD_SIZE == 32\n#if (defined(WOLFSSL_SP_CACHE_RESISTANT) || defined(WOLFSSL_SP_SMALL)) &&              (defined(WOLFSSL_HAVE_SP_ECC) || !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Mask for address to obfuscate which of the two address will be used. */\nstatic const size_t addr_mask[2] = { 0, (size_t)-1 };\n#endif\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n#ifndef WOLFSSL_SP_NO_2048\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 15U) {\n            r[j] &= 0x7fffff;\n            s = 23U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 23\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 23\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0x7fffff;\n        s = 23U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 23U) <= (word32)DIGIT_BIT) {\n            s += 23U;\n            r[j] &= 0x7fffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 23) {\n            r[j] &= 0x7fffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 23 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 256\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_2048_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    for (i=0; i<89; i++) {\n        r[i+1] += r[i] >> 23;\n        r[i] &= 0x7fffff;\n    }\n    j = 2048 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<90 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 23) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 23);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_15(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int64_t t0   = ((int64_t)a[ 0]) * b[ 0];\n    int64_t t1   = ((int64_t)a[ 0]) * b[ 1]\n                 + ((int64_t)a[ 1]) * b[ 0];\n    int64_t t2   = ((int64_t)a[ 0]) * b[ 2]\n                 + ((int64_t)a[ 1]) * b[ 1]\n                 + ((int64_t)a[ 2]) * b[ 0];\n    int64_t t3   = ((int64_t)a[ 0]) * b[ 3]\n                 + ((int64_t)a[ 1]) * b[ 2]\n                 + ((int64_t)a[ 2]) * b[ 1]\n                 + ((int64_t)a[ 3]) * b[ 0];\n    int64_t t4   = ((int64_t)a[ 0]) * b[ 4]\n                 + ((int64_t)a[ 1]) * b[ 3]\n                 + ((int64_t)a[ 2]) * b[ 2]\n                 + ((int64_t)a[ 3]) * b[ 1]\n                 + ((int64_t)a[ 4]) * b[ 0];\n    int64_t t5   = ((int64_t)a[ 0]) * b[ 5]\n                 + ((int64_t)a[ 1]) * b[ 4]\n                 + ((int64_t)a[ 2]) * b[ 3]\n                 + ((int64_t)a[ 3]) * b[ 2]\n                 + ((int64_t)a[ 4]) * b[ 1]\n                 + ((int64_t)a[ 5]) * b[ 0];\n    int64_t t6   = ((int64_t)a[ 0]) * b[ 6]\n                 + ((int64_t)a[ 1]) * b[ 5]\n                 + ((int64_t)a[ 2]) * b[ 4]\n                 + ((int64_t)a[ 3]) * b[ 3]\n                 + ((int64_t)a[ 4]) * b[ 2]\n                 + ((int64_t)a[ 5]) * b[ 1]\n                 + ((int64_t)a[ 6]) * b[ 0];\n    int64_t t7   = ((int64_t)a[ 0]) * b[ 7]\n                 + ((int64_t)a[ 1]) * b[ 6]\n                 + ((int64_t)a[ 2]) * b[ 5]\n                 + ((int64_t)a[ 3]) * b[ 4]\n                 + ((int64_t)a[ 4]) * b[ 3]\n                 + ((int64_t)a[ 5]) * b[ 2]\n                 + ((int64_t)a[ 6]) * b[ 1]\n                 + ((int64_t)a[ 7]) * b[ 0];\n    int64_t t8   = ((int64_t)a[ 0]) * b[ 8]\n                 + ((int64_t)a[ 1]) * b[ 7]\n                 + ((int64_t)a[ 2]) * b[ 6]\n                 + ((int64_t)a[ 3]) * b[ 5]\n                 + ((int64_t)a[ 4]) * b[ 4]\n                 + ((int64_t)a[ 5]) * b[ 3]\n                 + ((int64_t)a[ 6]) * b[ 2]\n                 + ((int64_t)a[ 7]) * b[ 1]\n                 + ((int64_t)a[ 8]) * b[ 0];\n    int64_t t9   = ((int64_t)a[ 0]) * b[ 9]\n                 + ((int64_t)a[ 1]) * b[ 8]\n                 + ((int64_t)a[ 2]) * b[ 7]\n                 + ((int64_t)a[ 3]) * b[ 6]\n                 + ((int64_t)a[ 4]) * b[ 5]\n                 + ((int64_t)a[ 5]) * b[ 4]\n                 + ((int64_t)a[ 6]) * b[ 3]\n                 + ((int64_t)a[ 7]) * b[ 2]\n                 + ((int64_t)a[ 8]) * b[ 1]\n                 + ((int64_t)a[ 9]) * b[ 0];\n    int64_t t10  = ((int64_t)a[ 0]) * b[10]\n                 + ((int64_t)a[ 1]) * b[ 9]\n                 + ((int64_t)a[ 2]) * b[ 8]\n                 + ((int64_t)a[ 3]) * b[ 7]\n                 + ((int64_t)a[ 4]) * b[ 6]\n                 + ((int64_t)a[ 5]) * b[ 5]\n                 + ((int64_t)a[ 6]) * b[ 4]\n                 + ((int64_t)a[ 7]) * b[ 3]\n                 + ((int64_t)a[ 8]) * b[ 2]\n                 + ((int64_t)a[ 9]) * b[ 1]\n                 + ((int64_t)a[10]) * b[ 0];\n    int64_t t11  = ((int64_t)a[ 0]) * b[11]\n                 + ((int64_t)a[ 1]) * b[10]\n                 + ((int64_t)a[ 2]) * b[ 9]\n                 + ((int64_t)a[ 3]) * b[ 8]\n                 + ((int64_t)a[ 4]) * b[ 7]\n                 + ((int64_t)a[ 5]) * b[ 6]\n                 + ((int64_t)a[ 6]) * b[ 5]\n                 + ((int64_t)a[ 7]) * b[ 4]\n                 + ((int64_t)a[ 8]) * b[ 3]\n                 + ((int64_t)a[ 9]) * b[ 2]\n                 + ((int64_t)a[10]) * b[ 1]\n                 + ((int64_t)a[11]) * b[ 0];\n    int64_t t12  = ((int64_t)a[ 0]) * b[12]\n                 + ((int64_t)a[ 1]) * b[11]\n                 + ((int64_t)a[ 2]) * b[10]\n                 + ((int64_t)a[ 3]) * b[ 9]\n                 + ((int64_t)a[ 4]) * b[ 8]\n                 + ((int64_t)a[ 5]) * b[ 7]\n                 + ((int64_t)a[ 6]) * b[ 6]\n                 + ((int64_t)a[ 7]) * b[ 5]\n                 + ((int64_t)a[ 8]) * b[ 4]\n                 + ((int64_t)a[ 9]) * b[ 3]\n                 + ((int64_t)a[10]) * b[ 2]\n                 + ((int64_t)a[11]) * b[ 1]\n                 + ((int64_t)a[12]) * b[ 0];\n    int64_t t13  = ((int64_t)a[ 0]) * b[13]\n                 + ((int64_t)a[ 1]) * b[12]\n                 + ((int64_t)a[ 2]) * b[11]\n                 + ((int64_t)a[ 3]) * b[10]\n                 + ((int64_t)a[ 4]) * b[ 9]\n                 + ((int64_t)a[ 5]) * b[ 8]\n                 + ((int64_t)a[ 6]) * b[ 7]\n                 + ((int64_t)a[ 7]) * b[ 6]\n                 + ((int64_t)a[ 8]) * b[ 5]\n                 + ((int64_t)a[ 9]) * b[ 4]\n                 + ((int64_t)a[10]) * b[ 3]\n                 + ((int64_t)a[11]) * b[ 2]\n                 + ((int64_t)a[12]) * b[ 1]\n                 + ((int64_t)a[13]) * b[ 0];\n    int64_t t14  = ((int64_t)a[ 0]) * b[14]\n                 + ((int64_t)a[ 1]) * b[13]\n                 + ((int64_t)a[ 2]) * b[12]\n                 + ((int64_t)a[ 3]) * b[11]\n                 + ((int64_t)a[ 4]) * b[10]\n                 + ((int64_t)a[ 5]) * b[ 9]\n                 + ((int64_t)a[ 6]) * b[ 8]\n                 + ((int64_t)a[ 7]) * b[ 7]\n                 + ((int64_t)a[ 8]) * b[ 6]\n                 + ((int64_t)a[ 9]) * b[ 5]\n                 + ((int64_t)a[10]) * b[ 4]\n                 + ((int64_t)a[11]) * b[ 3]\n                 + ((int64_t)a[12]) * b[ 2]\n                 + ((int64_t)a[13]) * b[ 1]\n                 + ((int64_t)a[14]) * b[ 0];\n    int64_t t15  = ((int64_t)a[ 1]) * b[14]\n                 + ((int64_t)a[ 2]) * b[13]\n                 + ((int64_t)a[ 3]) * b[12]\n                 + ((int64_t)a[ 4]) * b[11]\n                 + ((int64_t)a[ 5]) * b[10]\n                 + ((int64_t)a[ 6]) * b[ 9]\n                 + ((int64_t)a[ 7]) * b[ 8]\n                 + ((int64_t)a[ 8]) * b[ 7]\n                 + ((int64_t)a[ 9]) * b[ 6]\n                 + ((int64_t)a[10]) * b[ 5]\n                 + ((int64_t)a[11]) * b[ 4]\n                 + ((int64_t)a[12]) * b[ 3]\n                 + ((int64_t)a[13]) * b[ 2]\n                 + ((int64_t)a[14]) * b[ 1];\n    int64_t t16  = ((int64_t)a[ 2]) * b[14]\n                 + ((int64_t)a[ 3]) * b[13]\n                 + ((int64_t)a[ 4]) * b[12]\n                 + ((int64_t)a[ 5]) * b[11]\n                 + ((int64_t)a[ 6]) * b[10]\n                 + ((int64_t)a[ 7]) * b[ 9]\n                 + ((int64_t)a[ 8]) * b[ 8]\n                 + ((int64_t)a[ 9]) * b[ 7]\n                 + ((int64_t)a[10]) * b[ 6]\n                 + ((int64_t)a[11]) * b[ 5]\n                 + ((int64_t)a[12]) * b[ 4]\n                 + ((int64_t)a[13]) * b[ 3]\n                 + ((int64_t)a[14]) * b[ 2];\n    int64_t t17  = ((int64_t)a[ 3]) * b[14]\n                 + ((int64_t)a[ 4]) * b[13]\n                 + ((int64_t)a[ 5]) * b[12]\n                 + ((int64_t)a[ 6]) * b[11]\n                 + ((int64_t)a[ 7]) * b[10]\n                 + ((int64_t)a[ 8]) * b[ 9]\n                 + ((int64_t)a[ 9]) * b[ 8]\n                 + ((int64_t)a[10]) * b[ 7]\n                 + ((int64_t)a[11]) * b[ 6]\n                 + ((int64_t)a[12]) * b[ 5]\n                 + ((int64_t)a[13]) * b[ 4]\n                 + ((int64_t)a[14]) * b[ 3];\n    int64_t t18  = ((int64_t)a[ 4]) * b[14]\n                 + ((int64_t)a[ 5]) * b[13]\n                 + ((int64_t)a[ 6]) * b[12]\n                 + ((int64_t)a[ 7]) * b[11]\n                 + ((int64_t)a[ 8]) * b[10]\n                 + ((int64_t)a[ 9]) * b[ 9]\n                 + ((int64_t)a[10]) * b[ 8]\n                 + ((int64_t)a[11]) * b[ 7]\n                 + ((int64_t)a[12]) * b[ 6]\n                 + ((int64_t)a[13]) * b[ 5]\n                 + ((int64_t)a[14]) * b[ 4];\n    int64_t t19  = ((int64_t)a[ 5]) * b[14]\n                 + ((int64_t)a[ 6]) * b[13]\n                 + ((int64_t)a[ 7]) * b[12]\n                 + ((int64_t)a[ 8]) * b[11]\n                 + ((int64_t)a[ 9]) * b[10]\n                 + ((int64_t)a[10]) * b[ 9]\n                 + ((int64_t)a[11]) * b[ 8]\n                 + ((int64_t)a[12]) * b[ 7]\n                 + ((int64_t)a[13]) * b[ 6]\n                 + ((int64_t)a[14]) * b[ 5];\n    int64_t t20  = ((int64_t)a[ 6]) * b[14]\n                 + ((int64_t)a[ 7]) * b[13]\n                 + ((int64_t)a[ 8]) * b[12]\n                 + ((int64_t)a[ 9]) * b[11]\n                 + ((int64_t)a[10]) * b[10]\n                 + ((int64_t)a[11]) * b[ 9]\n                 + ((int64_t)a[12]) * b[ 8]\n                 + ((int64_t)a[13]) * b[ 7]\n                 + ((int64_t)a[14]) * b[ 6];\n    int64_t t21  = ((int64_t)a[ 7]) * b[14]\n                 + ((int64_t)a[ 8]) * b[13]\n                 + ((int64_t)a[ 9]) * b[12]\n                 + ((int64_t)a[10]) * b[11]\n                 + ((int64_t)a[11]) * b[10]\n                 + ((int64_t)a[12]) * b[ 9]\n                 + ((int64_t)a[13]) * b[ 8]\n                 + ((int64_t)a[14]) * b[ 7];\n    int64_t t22  = ((int64_t)a[ 8]) * b[14]\n                 + ((int64_t)a[ 9]) * b[13]\n                 + ((int64_t)a[10]) * b[12]\n                 + ((int64_t)a[11]) * b[11]\n                 + ((int64_t)a[12]) * b[10]\n                 + ((int64_t)a[13]) * b[ 9]\n                 + ((int64_t)a[14]) * b[ 8];\n    int64_t t23  = ((int64_t)a[ 9]) * b[14]\n                 + ((int64_t)a[10]) * b[13]\n                 + ((int64_t)a[11]) * b[12]\n                 + ((int64_t)a[12]) * b[11]\n                 + ((int64_t)a[13]) * b[10]\n                 + ((int64_t)a[14]) * b[ 9];\n    int64_t t24  = ((int64_t)a[10]) * b[14]\n                 + ((int64_t)a[11]) * b[13]\n                 + ((int64_t)a[12]) * b[12]\n                 + ((int64_t)a[13]) * b[11]\n                 + ((int64_t)a[14]) * b[10];\n    int64_t t25  = ((int64_t)a[11]) * b[14]\n                 + ((int64_t)a[12]) * b[13]\n                 + ((int64_t)a[13]) * b[12]\n                 + ((int64_t)a[14]) * b[11];\n    int64_t t26  = ((int64_t)a[12]) * b[14]\n                 + ((int64_t)a[13]) * b[13]\n                 + ((int64_t)a[14]) * b[12];\n    int64_t t27  = ((int64_t)a[13]) * b[14]\n                 + ((int64_t)a[14]) * b[13];\n    int64_t t28  = ((int64_t)a[14]) * b[14];\n\n    t1   += t0  >> 23; r[ 0] = t0  & 0x7fffff;\n    t2   += t1  >> 23; r[ 1] = t1  & 0x7fffff;\n    t3   += t2  >> 23; r[ 2] = t2  & 0x7fffff;\n    t4   += t3  >> 23; r[ 3] = t3  & 0x7fffff;\n    t5   += t4  >> 23; r[ 4] = t4  & 0x7fffff;\n    t6   += t5  >> 23; r[ 5] = t5  & 0x7fffff;\n    t7   += t6  >> 23; r[ 6] = t6  & 0x7fffff;\n    t8   += t7  >> 23; r[ 7] = t7  & 0x7fffff;\n    t9   += t8  >> 23; r[ 8] = t8  & 0x7fffff;\n    t10  += t9  >> 23; r[ 9] = t9  & 0x7fffff;\n    t11  += t10 >> 23; r[10] = t10 & 0x7fffff;\n    t12  += t11 >> 23; r[11] = t11 & 0x7fffff;\n    t13  += t12 >> 23; r[12] = t12 & 0x7fffff;\n    t14  += t13 >> 23; r[13] = t13 & 0x7fffff;\n    t15  += t14 >> 23; r[14] = t14 & 0x7fffff;\n    t16  += t15 >> 23; r[15] = t15 & 0x7fffff;\n    t17  += t16 >> 23; r[16] = t16 & 0x7fffff;\n    t18  += t17 >> 23; r[17] = t17 & 0x7fffff;\n    t19  += t18 >> 23; r[18] = t18 & 0x7fffff;\n    t20  += t19 >> 23; r[19] = t19 & 0x7fffff;\n    t21  += t20 >> 23; r[20] = t20 & 0x7fffff;\n    t22  += t21 >> 23; r[21] = t21 & 0x7fffff;\n    t23  += t22 >> 23; r[22] = t22 & 0x7fffff;\n    t24  += t23 >> 23; r[23] = t23 & 0x7fffff;\n    t25  += t24 >> 23; r[24] = t24 & 0x7fffff;\n    t26  += t25 >> 23; r[25] = t25 & 0x7fffff;\n    t27  += t26 >> 23; r[26] = t26 & 0x7fffff;\n    t28  += t27 >> 23; r[27] = t27 & 0x7fffff;\n    r[29] = (sp_digit)(t28 >> 23);\n                       r[28] = t28 & 0x7fffff;\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_15(sp_digit* r, const sp_digit* a)\n{\n    int64_t t0   =  ((int64_t)a[ 0]) * a[ 0];\n    int64_t t1   = (((int64_t)a[ 0]) * a[ 1]) * 2;\n    int64_t t2   = (((int64_t)a[ 0]) * a[ 2]) * 2\n                 +  ((int64_t)a[ 1]) * a[ 1];\n    int64_t t3   = (((int64_t)a[ 0]) * a[ 3]\n                 +  ((int64_t)a[ 1]) * a[ 2]) * 2;\n    int64_t t4   = (((int64_t)a[ 0]) * a[ 4]\n                 +  ((int64_t)a[ 1]) * a[ 3]) * 2\n                 +  ((int64_t)a[ 2]) * a[ 2];\n    int64_t t5   = (((int64_t)a[ 0]) * a[ 5]\n                 +  ((int64_t)a[ 1]) * a[ 4]\n                 +  ((int64_t)a[ 2]) * a[ 3]) * 2;\n    int64_t t6   = (((int64_t)a[ 0]) * a[ 6]\n                 +  ((int64_t)a[ 1]) * a[ 5]\n                 +  ((int64_t)a[ 2]) * a[ 4]) * 2\n                 +  ((int64_t)a[ 3]) * a[ 3];\n    int64_t t7   = (((int64_t)a[ 0]) * a[ 7]\n                 +  ((int64_t)a[ 1]) * a[ 6]\n                 +  ((int64_t)a[ 2]) * a[ 5]\n                 +  ((int64_t)a[ 3]) * a[ 4]) * 2;\n    int64_t t8   = (((int64_t)a[ 0]) * a[ 8]\n                 +  ((int64_t)a[ 1]) * a[ 7]\n                 +  ((int64_t)a[ 2]) * a[ 6]\n                 +  ((int64_t)a[ 3]) * a[ 5]) * 2\n                 +  ((int64_t)a[ 4]) * a[ 4];\n    int64_t t9   = (((int64_t)a[ 0]) * a[ 9]\n                 +  ((int64_t)a[ 1]) * a[ 8]\n                 +  ((int64_t)a[ 2]) * a[ 7]\n                 +  ((int64_t)a[ 3]) * a[ 6]\n                 +  ((int64_t)a[ 4]) * a[ 5]) * 2;\n    int64_t t10  = (((int64_t)a[ 0]) * a[10]\n                 +  ((int64_t)a[ 1]) * a[ 9]\n                 +  ((int64_t)a[ 2]) * a[ 8]\n                 +  ((int64_t)a[ 3]) * a[ 7]\n                 +  ((int64_t)a[ 4]) * a[ 6]) * 2\n                 +  ((int64_t)a[ 5]) * a[ 5];\n    int64_t t11  = (((int64_t)a[ 0]) * a[11]\n                 +  ((int64_t)a[ 1]) * a[10]\n                 +  ((int64_t)a[ 2]) * a[ 9]\n                 +  ((int64_t)a[ 3]) * a[ 8]\n                 +  ((int64_t)a[ 4]) * a[ 7]\n                 +  ((int64_t)a[ 5]) * a[ 6]) * 2;\n    int64_t t12  = (((int64_t)a[ 0]) * a[12]\n                 +  ((int64_t)a[ 1]) * a[11]\n                 +  ((int64_t)a[ 2]) * a[10]\n                 +  ((int64_t)a[ 3]) * a[ 9]\n                 +  ((int64_t)a[ 4]) * a[ 8]\n                 +  ((int64_t)a[ 5]) * a[ 7]) * 2\n                 +  ((int64_t)a[ 6]) * a[ 6];\n    int64_t t13  = (((int64_t)a[ 0]) * a[13]\n                 +  ((int64_t)a[ 1]) * a[12]\n                 +  ((int64_t)a[ 2]) * a[11]\n                 +  ((int64_t)a[ 3]) * a[10]\n                 +  ((int64_t)a[ 4]) * a[ 9]\n                 +  ((int64_t)a[ 5]) * a[ 8]\n                 +  ((int64_t)a[ 6]) * a[ 7]) * 2;\n    int64_t t14  = (((int64_t)a[ 0]) * a[14]\n                 +  ((int64_t)a[ 1]) * a[13]\n                 +  ((int64_t)a[ 2]) * a[12]\n                 +  ((int64_t)a[ 3]) * a[11]\n                 +  ((int64_t)a[ 4]) * a[10]\n                 +  ((int64_t)a[ 5]) * a[ 9]\n                 +  ((int64_t)a[ 6]) * a[ 8]) * 2\n                 +  ((int64_t)a[ 7]) * a[ 7];\n    int64_t t15  = (((int64_t)a[ 1]) * a[14]\n                 +  ((int64_t)a[ 2]) * a[13]\n                 +  ((int64_t)a[ 3]) * a[12]\n                 +  ((int64_t)a[ 4]) * a[11]\n                 +  ((int64_t)a[ 5]) * a[10]\n                 +  ((int64_t)a[ 6]) * a[ 9]\n                 +  ((int64_t)a[ 7]) * a[ 8]) * 2;\n    int64_t t16  = (((int64_t)a[ 2]) * a[14]\n                 +  ((int64_t)a[ 3]) * a[13]\n                 +  ((int64_t)a[ 4]) * a[12]\n                 +  ((int64_t)a[ 5]) * a[11]\n                 +  ((int64_t)a[ 6]) * a[10]\n                 +  ((int64_t)a[ 7]) * a[ 9]) * 2\n                 +  ((int64_t)a[ 8]) * a[ 8];\n    int64_t t17  = (((int64_t)a[ 3]) * a[14]\n                 +  ((int64_t)a[ 4]) * a[13]\n                 +  ((int64_t)a[ 5]) * a[12]\n                 +  ((int64_t)a[ 6]) * a[11]\n                 +  ((int64_t)a[ 7]) * a[10]\n                 +  ((int64_t)a[ 8]) * a[ 9]) * 2;\n    int64_t t18  = (((int64_t)a[ 4]) * a[14]\n                 +  ((int64_t)a[ 5]) * a[13]\n                 +  ((int64_t)a[ 6]) * a[12]\n                 +  ((int64_t)a[ 7]) * a[11]\n                 +  ((int64_t)a[ 8]) * a[10]) * 2\n                 +  ((int64_t)a[ 9]) * a[ 9];\n    int64_t t19  = (((int64_t)a[ 5]) * a[14]\n                 +  ((int64_t)a[ 6]) * a[13]\n                 +  ((int64_t)a[ 7]) * a[12]\n                 +  ((int64_t)a[ 8]) * a[11]\n                 +  ((int64_t)a[ 9]) * a[10]) * 2;\n    int64_t t20  = (((int64_t)a[ 6]) * a[14]\n                 +  ((int64_t)a[ 7]) * a[13]\n                 +  ((int64_t)a[ 8]) * a[12]\n                 +  ((int64_t)a[ 9]) * a[11]) * 2\n                 +  ((int64_t)a[10]) * a[10];\n    int64_t t21  = (((int64_t)a[ 7]) * a[14]\n                 +  ((int64_t)a[ 8]) * a[13]\n                 +  ((int64_t)a[ 9]) * a[12]\n                 +  ((int64_t)a[10]) * a[11]) * 2;\n    int64_t t22  = (((int64_t)a[ 8]) * a[14]\n                 +  ((int64_t)a[ 9]) * a[13]\n                 +  ((int64_t)a[10]) * a[12]) * 2\n                 +  ((int64_t)a[11]) * a[11];\n    int64_t t23  = (((int64_t)a[ 9]) * a[14]\n                 +  ((int64_t)a[10]) * a[13]\n                 +  ((int64_t)a[11]) * a[12]) * 2;\n    int64_t t24  = (((int64_t)a[10]) * a[14]\n                 +  ((int64_t)a[11]) * a[13]) * 2\n                 +  ((int64_t)a[12]) * a[12];\n    int64_t t25  = (((int64_t)a[11]) * a[14]\n                 +  ((int64_t)a[12]) * a[13]) * 2;\n    int64_t t26  = (((int64_t)a[12]) * a[14]) * 2\n                 +  ((int64_t)a[13]) * a[13];\n    int64_t t27  = (((int64_t)a[13]) * a[14]) * 2;\n    int64_t t28  =  ((int64_t)a[14]) * a[14];\n\n    t1   += t0  >> 23; r[ 0] = t0  & 0x7fffff;\n    t2   += t1  >> 23; r[ 1] = t1  & 0x7fffff;\n    t3   += t2  >> 23; r[ 2] = t2  & 0x7fffff;\n    t4   += t3  >> 23; r[ 3] = t3  & 0x7fffff;\n    t5   += t4  >> 23; r[ 4] = t4  & 0x7fffff;\n    t6   += t5  >> 23; r[ 5] = t5  & 0x7fffff;\n    t7   += t6  >> 23; r[ 6] = t6  & 0x7fffff;\n    t8   += t7  >> 23; r[ 7] = t7  & 0x7fffff;\n    t9   += t8  >> 23; r[ 8] = t8  & 0x7fffff;\n    t10  += t9  >> 23; r[ 9] = t9  & 0x7fffff;\n    t11  += t10 >> 23; r[10] = t10 & 0x7fffff;\n    t12  += t11 >> 23; r[11] = t11 & 0x7fffff;\n    t13  += t12 >> 23; r[12] = t12 & 0x7fffff;\n    t14  += t13 >> 23; r[13] = t13 & 0x7fffff;\n    t15  += t14 >> 23; r[14] = t14 & 0x7fffff;\n    t16  += t15 >> 23; r[15] = t15 & 0x7fffff;\n    t17  += t16 >> 23; r[16] = t16 & 0x7fffff;\n    t18  += t17 >> 23; r[17] = t17 & 0x7fffff;\n    t19  += t18 >> 23; r[18] = t18 & 0x7fffff;\n    t20  += t19 >> 23; r[19] = t19 & 0x7fffff;\n    t21  += t20 >> 23; r[20] = t20 & 0x7fffff;\n    t22  += t21 >> 23; r[21] = t21 & 0x7fffff;\n    t23  += t22 >> 23; r[22] = t22 & 0x7fffff;\n    t24  += t23 >> 23; r[23] = t23 & 0x7fffff;\n    t25  += t24 >> 23; r[24] = t24 & 0x7fffff;\n    t26  += t25 >> 23; r[25] = t25 & 0x7fffff;\n    t27  += t26 >> 23; r[26] = t26 & 0x7fffff;\n    t28  += t27 >> 23; r[27] = t27 & 0x7fffff;\n    r[29] = (sp_digit)(t28 >> 23);\n                       r[28] = t28 & 0x7fffff;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_15(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    r[ 0] = a[ 0] + b[ 0];\n    r[ 1] = a[ 1] + b[ 1];\n    r[ 2] = a[ 2] + b[ 2];\n    r[ 3] = a[ 3] + b[ 3];\n    r[ 4] = a[ 4] + b[ 4];\n    r[ 5] = a[ 5] + b[ 5];\n    r[ 6] = a[ 6] + b[ 6];\n    r[ 7] = a[ 7] + b[ 7];\n    r[ 8] = a[ 8] + b[ 8];\n    r[ 9] = a[ 9] + b[ 9];\n    r[10] = a[10] + b[10];\n    r[11] = a[11] + b[11];\n    r[12] = a[12] + b[12];\n    r[13] = a[13] + b[13];\n    r[14] = a[14] + b[14];\n\n    return 0;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_sub_30(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[24] = a[24] - b[24];\n    r[25] = a[25] - b[25];\n    r[26] = a[26] - b[26];\n    r[27] = a[27] - b[27];\n    r[28] = a[28] - b[28];\n    r[29] = a[29] - b[29];\n\n    return 0;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_30(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[24] = a[24] + b[24];\n    r[25] = a[25] + b[25];\n    r[26] = a[26] + b[26];\n    r[27] = a[27] + b[27];\n    r[28] = a[28] + b[28];\n    r[29] = a[29] + b[29];\n\n    return 0;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_45(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    sp_digit p0[30];\n    sp_digit p1[30];\n    sp_digit p2[30];\n    sp_digit p3[30];\n    sp_digit p4[30];\n    sp_digit p5[30];\n    sp_digit t0[30];\n    sp_digit t1[30];\n    sp_digit t2[30];\n    sp_digit a0[15];\n    sp_digit a1[15];\n    sp_digit a2[15];\n    sp_digit b0[15];\n    sp_digit b1[15];\n    sp_digit b2[15];\n    (void)sp_2048_add_15(a0, a, &a[15]);\n    (void)sp_2048_add_15(b0, b, &b[15]);\n    (void)sp_2048_add_15(a1, &a[15], &a[30]);\n    (void)sp_2048_add_15(b1, &b[15], &b[30]);\n    (void)sp_2048_add_15(a2, a0, &a[30]);\n    (void)sp_2048_add_15(b2, b0, &b[30]);\n    sp_2048_mul_15(p0, a, b);\n    sp_2048_mul_15(p2, &a[15], &b[15]);\n    sp_2048_mul_15(p4, &a[30], &b[30]);\n    sp_2048_mul_15(p1, a0, b0);\n    sp_2048_mul_15(p3, a1, b1);\n    sp_2048_mul_15(p5, a2, b2);\n    XMEMSET(r, 0, sizeof(*r)*2U*45U);\n    (void)sp_2048_sub_30(t0, p3, p2);\n    (void)sp_2048_sub_30(t1, p1, p2);\n    (void)sp_2048_sub_30(t2, p5, t0);\n    (void)sp_2048_sub_30(t2, t2, t1);\n    (void)sp_2048_sub_30(t0, t0, p4);\n    (void)sp_2048_sub_30(t1, t1, p0);\n    (void)sp_2048_add_30(r, r, p0);\n    (void)sp_2048_add_30(&r[15], &r[15], t1);\n    (void)sp_2048_add_30(&r[30], &r[30], t2);\n    (void)sp_2048_add_30(&r[45], &r[45], t0);\n    (void)sp_2048_add_30(&r[60], &r[60], p4);\n}\n\n/* Square a into r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_45(sp_digit* r, const sp_digit* a)\n{\n    sp_digit p0[30];\n    sp_digit p1[30];\n    sp_digit p2[30];\n    sp_digit p3[30];\n    sp_digit p4[30];\n    sp_digit p5[30];\n    sp_digit t0[30];\n    sp_digit t1[30];\n    sp_digit t2[30];\n    sp_digit a0[15];\n    sp_digit a1[15];\n    sp_digit a2[15];\n    (void)sp_2048_add_15(a0, a, &a[15]);\n    (void)sp_2048_add_15(a1, &a[15], &a[30]);\n    (void)sp_2048_add_15(a2, a0, &a[30]);\n    sp_2048_sqr_15(p0, a);\n    sp_2048_sqr_15(p2, &a[15]);\n    sp_2048_sqr_15(p4, &a[30]);\n    sp_2048_sqr_15(p1, a0);\n    sp_2048_sqr_15(p3, a1);\n    sp_2048_sqr_15(p5, a2);\n    XMEMSET(r, 0, sizeof(*r)*2U*45U);\n    (void)sp_2048_sub_30(t0, p3, p2);\n    (void)sp_2048_sub_30(t1, p1, p2);\n    (void)sp_2048_sub_30(t2, p5, t0);\n    (void)sp_2048_sub_30(t2, t2, t1);\n    (void)sp_2048_sub_30(t0, t0, p4);\n    (void)sp_2048_sub_30(t1, t1, p0);\n    (void)sp_2048_add_30(r, r, p0);\n    (void)sp_2048_add_30(&r[15], &r[15], t1);\n    (void)sp_2048_add_30(&r[30], &r[30], t2);\n    (void)sp_2048_add_30(&r[45], &r[45], t0);\n    (void)sp_2048_add_30(&r[60], &r[60], p4);\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_45(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 40; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[40] = a[40] + b[40];\n    r[41] = a[41] + b[41];\n    r[42] = a[42] + b[42];\n    r[43] = a[43] + b[43];\n    r[44] = a[44] + b[44];\n\n    return 0;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_90(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 88; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[88] = a[88] + b[88];\n    r[89] = a[89] + b[89];\n\n    return 0;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_sub_90(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 88; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[88] = a[88] - b[88];\n    r[89] = a[89] - b[89];\n\n    return 0;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_90(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[90];\n    sp_digit* a1 = z1;\n    sp_digit b1[45];\n    sp_digit* z2 = r + 90;\n    (void)sp_2048_add_45(a1, a, &a[45]);\n    (void)sp_2048_add_45(b1, b, &b[45]);\n    sp_2048_mul_45(z2, &a[45], &b[45]);\n    sp_2048_mul_45(z0, a, b);\n    sp_2048_mul_45(z1, a1, b1);\n    (void)sp_2048_sub_90(z1, z1, z2);\n    (void)sp_2048_sub_90(z1, z1, z0);\n    (void)sp_2048_add_90(r + 45, r + 45, z1);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_90(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[90];\n    sp_digit* a1 = z1;\n    sp_digit* z2 = r + 90;\n    (void)sp_2048_add_45(a1, a, &a[45]);\n    sp_2048_sqr_45(z2, &a[45]);\n    sp_2048_sqr_45(z0, a);\n    sp_2048_sqr_45(z1, a1);\n    (void)sp_2048_sub_90(z1, z1, z2);\n    (void)sp_2048_sub_90(z1, z1, z0);\n    (void)sp_2048_add_90(r + 45, r + 45, z1);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_90(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 90; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_sub_90(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 90; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_90(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[89]) * b[89];\n    r[179] = (sp_digit)(c >> 23);\n    c = (c & 0x7fffff) << 23;\n    for (k = 177; k >= 0; k--) {\n        for (i = 89; i >= 0; i--) {\n            j = k - i;\n            if (j >= 90) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 46;\n        r[k + 1] = (c >> 23) & 0x7fffff;\n        c = (c & 0x7fffff) << 23;\n    }\n    r[0] = (sp_digit)(c >> 23);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_90(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[89]) * a[89];\n    r[179] = (sp_digit)(c >> 23);\n    c = (c & 0x7fffff) << 23;\n    for (k = 177; k >= 0; k--) {\n        for (i = 89; i >= 0; i--) {\n            j = k - i;\n            if (j >= 90 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int64_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 46;\n        r[k + 1] = (c >> 23) & 0x7fffff;\n        c = (c & 0x7fffff) << 23;\n    }\n    r[0] = (sp_digit)(c >> 23);\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_45(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 45; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_sub_45(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 45; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#else\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_sub_45(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 40; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[40] = a[40] - b[40];\n    r[41] = a[41] - b[41];\n    r[42] = a[42] - b[42];\n    r[43] = a[43] - b[43];\n    r[44] = a[44] - b[44];\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_45(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[44]) * b[44];\n    r[89] = (sp_digit)(c >> 23);\n    c = (c & 0x7fffff) << 23;\n    for (k = 87; k >= 0; k--) {\n        for (i = 44; i >= 0; i--) {\n            j = k - i;\n            if (j >= 45) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 46;\n        r[k + 1] = (c >> 23) & 0x7fffff;\n        c = (c & 0x7fffff) << 23;\n    }\n    r[0] = (sp_digit)(c >> 23);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_45(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[44]) * a[44];\n    r[89] = (sp_digit)(c >> 23);\n    c = (c & 0x7fffff) << 23;\n    for (k = 87; k >= 0; k--) {\n        for (i = 44; i >= 0; i--) {\n            j = k - i;\n            if (j >= 45 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int64_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 46;\n        r[k + 1] = (c >> 23) & 0x7fffff;\n        c = (c & 0x7fffff) << 23;\n    }\n    r[0] = (sp_digit)(c >> 23);\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n    x &= 0x7fffff;\n\n    /* rho = -1/m mod b */\n    *rho = (1L << 23) - x;\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_2048_mul_d_90(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 90; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x7fffff;\n        t >>= 23;\n    }\n    r[90] = (sp_digit)t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x7fffff;\n    for (i = 0; i < 88; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 23) + (t[5] & 0x7fffff);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 23) + (t[6] & 0x7fffff);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 23) + (t[7] & 0x7fffff);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 23) + (t[0] & 0x7fffff);\n    }\n    t[1] = tb * a[89];\n    r[89] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);\n    r[90] =  (sp_digit)(t[1] >> 23);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_45(sp_digit* r, const sp_digit* m)\n{\n    /* Set r = 2^n - 1. */\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<44; i++) {\n        r[i] = 0x7fffff;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 40; i += 8) {\n        r[i + 0] = 0x7fffff;\n        r[i + 1] = 0x7fffff;\n        r[i + 2] = 0x7fffff;\n        r[i + 3] = 0x7fffff;\n        r[i + 4] = 0x7fffff;\n        r[i + 5] = 0x7fffff;\n        r[i + 6] = 0x7fffff;\n        r[i + 7] = 0x7fffff;\n    }\n    r[40] = 0x7fffff;\n    r[41] = 0x7fffff;\n    r[42] = 0x7fffff;\n    r[43] = 0x7fffff;\n#endif\n    r[44] = 0xfffL;\n\n    /* r = (2^n - 1) mod n */\n    (void)sp_2048_sub_45(r, r, m);\n\n    /* Add one so r = 2^n mod m */\n    r[0] += 1;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_2048_cmp_45(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=44; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    int i;\n\n    r |= (a[44] - b[44]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[43] - b[43]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[42] - b[42]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[41] - b[41]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[40] - b[40]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    for (i = 32; i >= 0; i -= 8) {\n        r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_2048_cond_sub_45(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 45; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 40; i += 8) {\n        r[i + 0] = a[i + 0] - (b[i + 0] & m);\n        r[i + 1] = a[i + 1] - (b[i + 1] & m);\n        r[i + 2] = a[i + 2] - (b[i + 2] & m);\n        r[i + 3] = a[i + 3] - (b[i + 3] & m);\n        r[i + 4] = a[i + 4] - (b[i + 4] & m);\n        r[i + 5] = a[i + 5] - (b[i + 5] & m);\n        r[i + 6] = a[i + 6] - (b[i + 6] & m);\n        r[i + 7] = a[i + 7] - (b[i + 7] & m);\n    }\n    r[40] = a[40] - (b[40] & m);\n    r[41] = a[41] - (b[41] & m);\n    r[42] = a[42] - (b[42] & m);\n    r[43] = a[43] - (b[43] & m);\n    r[44] = a[44] - (b[44] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_2048_mul_add_45(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 45; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0x7fffff;\n        t >>= 23;\n    }\n    r[45] += t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x7fffff);\n    for (i = 0; i < 40; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] += (sp_digit)((t[0] >> 23) + (t[1] & 0x7fffff));\n        t[2] = tb * a[i+2];\n        r[i+2] += (sp_digit)((t[1] >> 23) + (t[2] & 0x7fffff));\n        t[3] = tb * a[i+3];\n        r[i+3] += (sp_digit)((t[2] >> 23) + (t[3] & 0x7fffff));\n        t[4] = tb * a[i+4];\n        r[i+4] += (sp_digit)((t[3] >> 23) + (t[4] & 0x7fffff));\n        t[5] = tb * a[i+5];\n        r[i+5] += (sp_digit)((t[4] >> 23) + (t[5] & 0x7fffff));\n        t[6] = tb * a[i+6];\n        r[i+6] += (sp_digit)((t[5] >> 23) + (t[6] & 0x7fffff));\n        t[7] = tb * a[i+7];\n        r[i+7] += (sp_digit)((t[6] >> 23) + (t[7] & 0x7fffff));\n        t[0] = tb * a[i+8];\n        r[i+8] += (sp_digit)((t[7] >> 23) + (t[0] & 0x7fffff));\n    }\n    t[1] = tb * a[41]; r[41] += (sp_digit)((t[0] >> 23) + (t[1] & 0x7fffff));\n    t[2] = tb * a[42]; r[42] += (sp_digit)((t[1] >> 23) + (t[2] & 0x7fffff));\n    t[3] = tb * a[43]; r[43] += (sp_digit)((t[2] >> 23) + (t[3] & 0x7fffff));\n    t[4] = tb * a[44]; r[44] += (sp_digit)((t[3] >> 23) + (t[4] & 0x7fffff));\n    r[45] +=  (sp_digit)(t[4] >> 23);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Normalize the values in each word to 23.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_2048_norm_45(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 44; i++) {\n        a[i+1] += a[i] >> 23;\n        a[i] &= 0x7fffff;\n    }\n#else\n    int i;\n    for (i = 0; i < 40; i += 8) {\n        a[i+1] += a[i+0] >> 23; a[i+0] &= 0x7fffff;\n        a[i+2] += a[i+1] >> 23; a[i+1] &= 0x7fffff;\n        a[i+3] += a[i+2] >> 23; a[i+2] &= 0x7fffff;\n        a[i+4] += a[i+3] >> 23; a[i+3] &= 0x7fffff;\n        a[i+5] += a[i+4] >> 23; a[i+4] &= 0x7fffff;\n        a[i+6] += a[i+5] >> 23; a[i+5] &= 0x7fffff;\n        a[i+7] += a[i+6] >> 23; a[i+6] &= 0x7fffff;\n        a[i+8] += a[i+7] >> 23; a[i+7] &= 0x7fffff;\n        a[i+9] += a[i+8] >> 23; a[i+8] &= 0x7fffff;\n    }\n    a[40+1] += a[40] >> 23;\n    a[40] &= 0x7fffff;\n    a[41+1] += a[41] >> 23;\n    a[41] &= 0x7fffff;\n    a[42+1] += a[42] >> 23;\n    a[42] &= 0x7fffff;\n    a[43+1] += a[43] >> 23;\n    a[43] &= 0x7fffff;\n#endif\n}\n\n/* Shift the result in the high 1024 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_2048_mont_shift_45(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    int64_t n = a[44] >> 12;\n    n += ((int64_t)a[45]) << 11;\n\n    for (i = 0; i < 44; i++) {\n        r[i] = n & 0x7fffff;\n        n >>= 23;\n        n += ((int64_t)a[46 + i]) << 11;\n    }\n    r[44] = (sp_digit)n;\n#else\n    int i;\n    int64_t n = a[44] >> 12;\n    n += ((int64_t)a[45]) << 11;\n    for (i = 0; i < 40; i += 8) {\n        r[i + 0] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 46]) << 11;\n        r[i + 1] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 47]) << 11;\n        r[i + 2] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 48]) << 11;\n        r[i + 3] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 49]) << 11;\n        r[i + 4] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 50]) << 11;\n        r[i + 5] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 51]) << 11;\n        r[i + 6] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 52]) << 11;\n        r[i + 7] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 53]) << 11;\n    }\n    r[40] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[86]) << 11;\n    r[41] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[87]) << 11;\n    r[42] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[88]) << 11;\n    r[43] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[89]) << 11;\n    r[44] = (sp_digit)n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[45], 0, sizeof(*r) * 45U);\n}\n\n/* Reduce the number back to 2048 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_2048_mont_reduce_45(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    sp_2048_norm_45(a + 45);\n\n    for (i=0; i<44; i++) {\n        mu = (a[i] * mp) & 0x7fffff;\n        sp_2048_mul_add_45(a+i, m, mu);\n        a[i+1] += a[i] >> 23;\n    }\n    mu = (a[i] * mp) & 0xfffL;\n    sp_2048_mul_add_45(a+i, m, mu);\n    a[i+1] += a[i] >> 23;\n    a[i] &= 0x7fffff;\n\n    sp_2048_mont_shift_45(a, a);\n    sp_2048_cond_sub_45(a, a, m, 0 - (((a[44] >> 12) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_2048_norm_45(a);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_45(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_45(r, a, b);\n    sp_2048_mont_reduce_45(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_45(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_45(r, a);\n    sp_2048_mont_reduce_45(r, m, mp);\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_2048_mul_d_45(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 45; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x7fffff;\n        t >>= 23;\n    }\n    r[45] = (sp_digit)t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x7fffff;\n    for (i = 0; i < 40; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 23) + (t[5] & 0x7fffff);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 23) + (t[6] & 0x7fffff);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 23) + (t[7] & 0x7fffff);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 23) + (t[0] & 0x7fffff);\n    }\n    t[1] = tb * a[41];\n    r[41] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);\n    t[2] = tb * a[42];\n    r[42] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);\n    t[3] = tb * a[43];\n    r[43] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);\n    t[4] = tb * a[44];\n    r[44] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);\n    r[45] =  (sp_digit)(t[4] >> 23);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_2048_cond_add_45(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 45; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 40; i += 8) {\n        r[i + 0] = a[i + 0] + (b[i + 0] & m);\n        r[i + 1] = a[i + 1] + (b[i + 1] & m);\n        r[i + 2] = a[i + 2] + (b[i + 2] & m);\n        r[i + 3] = a[i + 3] + (b[i + 3] & m);\n        r[i + 4] = a[i + 4] + (b[i + 4] & m);\n        r[i + 5] = a[i + 5] + (b[i + 5] & m);\n        r[i + 6] = a[i + 6] + (b[i + 6] & m);\n        r[i + 7] = a[i + 7] + (b[i + 7] & m);\n    }\n    r[40] = a[40] + (b[40] & m);\n    r[41] = a[41] + (b[41] & m);\n    r[42] = a[42] + (b[42] & m);\n    r[43] = a[43] + (b[43] & m);\n    r[44] = a[44] + (b[44] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_45(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 45; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif\nSP_NOINLINE static void sp_2048_rshift_45(sp_digit* r, sp_digit* a, byte n)\n{\n    int i;\n\n#ifdef WOLFSSL_SP_SMALL\n    for (i=0; i<44; i++) {\n        r[i] = ((a[i] >> n) | (a[i + 1] << (23 - n))) & 0x7fffff;\n    }\n#else\n    for (i=0; i<40; i += 8) {\n        r[i+0] = ((a[i+0] >> n) | (a[i+1] << (23 - n))) & 0x7fffff;\n        r[i+1] = ((a[i+1] >> n) | (a[i+2] << (23 - n))) & 0x7fffff;\n        r[i+2] = ((a[i+2] >> n) | (a[i+3] << (23 - n))) & 0x7fffff;\n        r[i+3] = ((a[i+3] >> n) | (a[i+4] << (23 - n))) & 0x7fffff;\n        r[i+4] = ((a[i+4] >> n) | (a[i+5] << (23 - n))) & 0x7fffff;\n        r[i+5] = ((a[i+5] >> n) | (a[i+6] << (23 - n))) & 0x7fffff;\n        r[i+6] = ((a[i+6] >> n) | (a[i+7] << (23 - n))) & 0x7fffff;\n        r[i+7] = ((a[i+7] >> n) | (a[i+8] << (23 - n))) & 0x7fffff;\n    }\n    r[40] = ((a[40] >> n) | (a[41] << (23 - n))) & 0x7fffff;\n    r[41] = ((a[41] >> n) | (a[42] << (23 - n))) & 0x7fffff;\n    r[42] = ((a[42] >> n) | (a[43] << (23 - n))) & 0x7fffff;\n    r[43] = ((a[43] >> n) | (a[44] << (23 - n))) & 0x7fffff;\n#endif\n    r[44] = a[44] >> n;\n}\n\n#ifdef WOLFSSL_SP_DIV_32\nstatic WC_INLINE sp_digit sp_2048_div_word_45(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t;\n\n    /* All 23 bits from d1 and top 8 bits from d0. */\n    d = (d1 << 8) | (d0 >> 15);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 9 bits in r */\n    /* Next 8 bits from d0. */\n    r <<= 8;\n    d <<= 8;\n    d |= (d0 >> 7) & ((1 << 8) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 17 bits in r */\n    /* Remaining 7 bits from d0. */\n    r <<= 7;\n    d <<= 7;\n    d |= d0 & ((1 << 7) - 1);\n    t = d / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_32 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_2048_div_45(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_32\n    int64_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[90 + 1], t2d[45 + 1], sdd[45 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    sp_digit* sd;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 45 + 3), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    (void)m;\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 90 + 1;\n        sd = t2 + 45 + 1;\n#else\n        t1 = t1d;\n        t2 = t2d;\n        sd = sdd;\n#endif\n\n        sp_2048_mul_d_45(sd, d, 1L << 11);\n        sp_2048_mul_d_90(t1, a, 1L << 11);\n        dv = sd[44];\n        for (i=45; i>=0; i--) {\n            t1[45 + i] += t1[45 + i - 1] >> 23;\n            t1[45 + i - 1] &= 0x7fffff;\n#ifndef WOLFSSL_SP_DIV_32\n            d1 = t1[45 + i];\n            d1 <<= 23;\n            d1 += t1[45 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_2048_div_word_45(t1[45 + i], t1[45 + i - 1], dv);\n#endif\n\n            sp_2048_mul_d_45(t2, sd, r1);\n            (void)sp_2048_sub_45(&t1[i], &t1[i], t2);\n            t1[45 + i] -= t2[45];\n            t1[45 + i] += t1[45 + i - 1] >> 23;\n            t1[45 + i - 1] &= 0x7fffff;\n            r1 = (((-t1[45 + i]) << 23) - t1[45 + i - 1]) / dv;\n            r1 -= t1[45 + i];\n            sp_2048_mul_d_45(t2, sd, r1);\n            (void)sp_2048_add_45(&t1[i], &t1[i], t2);\n            t1[45 + i] += t1[45 + i - 1] >> 23;\n            t1[45 + i - 1] &= 0x7fffff;\n        }\n        t1[45 - 1] += t1[45 - 2] >> 23;\n        t1[45 - 2] &= 0x7fffff;\n        d1 = t1[45 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_2048_mul_d_45(t2, sd, r1);\n        sp_2048_sub_45(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 45U);\n        for (i=0; i<43; i++) {\n            r[i+1] += r[i] >> 23;\n            r[i] &= 0x7fffff;\n        }\n        sp_2048_cond_add_45(r, r, sd, 0 - ((r[44] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n\n        sp_2048_norm_45(r);\n        sp_2048_rshift_45(r, r, 11);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_2048_mod_45(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_45(a, m, NULL, r);\n}\n\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_45(sp_digit* r, const sp_digit* a, const sp_digit* e, int bits,\n    const sp_digit* m, int reduceA)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* td;\n    sp_digit* t[3];\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 45 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3U * 45U * 2U);\n\n        norm = t[0] = td;\n        t[1] = &td[45 * 2];\n        t[2] = &td[2 * 45 * 2];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_45(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_2048_mod_45(t[1], a, m);\n        }\n        else {\n            XMEMCPY(t[1], a, sizeof(sp_digit) * 45U);\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_2048_mul_45(t[1], t[1], norm);\n        err = sp_2048_mod_45(t[1], t[1], m);\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 23;\n        c = bits % 23;\n        n = e[i--] << (23 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 23;\n            }\n\n            y = (n >> 22) & 1;\n            n <<= 1;\n\n            sp_2048_mont_mul_45(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(*t[2]) * 45 * 2);\n            sp_2048_mont_sqr_45(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(*t[2]) * 45 * 2);\n        }\n\n        sp_2048_mont_reduce_45(t[0], m, mp);\n        n = sp_2048_cmp_45(t[0], m);\n        sp_2048_cond_sub_45(t[0], t[0], m, ((n < 0) ?\n                    (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(*r) * 45 * 2);\n\n    }\n\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    return err;\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[3][90];\n#else\n    sp_digit* td;\n    sp_digit* t[3];\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 45 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        t[0] = td;\n        t[1] = &td[45 * 2];\n        t[2] = &td[2 * 45 * 2];\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_45(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_2048_mod_45(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_2048_mul_45(t[1], t[1], norm);\n                err = sp_2048_mod_45(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_2048_mul_45(t[1], a, norm);\n            err = sp_2048_mod_45(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 23;\n        c = bits % 23;\n        n = e[i--] << (23 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 23;\n            }\n\n            y = (n >> 22) & 1;\n            n <<= 1;\n\n            sp_2048_mont_mul_45(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_2048_mont_sqr_45(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                           ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));\n        }\n\n        sp_2048_mont_reduce_45(t[0], m, mp);\n        n = sp_2048_cmp_45(t[0], m);\n        sp_2048_cond_sub_45(t[0], t[0], m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(t[0]));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][90];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit rt[90];\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 90, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 90;\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_45(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_2048_mod_45(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_2048_mul_45(t[1], t[1], norm);\n                err = sp_2048_mod_45(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_2048_mul_45(t[1], a, norm);\n            err = sp_2048_mod_45(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_45(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_45(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_45(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_45(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_45(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_45(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_45(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_45(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_45(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_45(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_45(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_45(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_45(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_45(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_45(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_45(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_45(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_45(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_45(t[20], t[10], m, mp);\n        sp_2048_mont_mul_45(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_45(t[22], t[11], m, mp);\n        sp_2048_mont_mul_45(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_45(t[24], t[12], m, mp);\n        sp_2048_mont_mul_45(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_45(t[26], t[13], m, mp);\n        sp_2048_mont_mul_45(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_45(t[28], t[14], m, mp);\n        sp_2048_mont_mul_45(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_45(t[30], t[15], m, mp);\n        sp_2048_mont_mul_45(t[31], t[16], t[15], m, mp);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 22) / 23) - 1;\n        c = bits % 23;\n        if (c == 0) {\n            c = 23;\n        }\n        if (i < 45) {\n            n = e[i--] << (32 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (9 - c);\n            c += 23;\n        }\n        y = (n >> 27) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        XMEMCPY(rt, t[y], sizeof(rt));\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (9 - c);\n                c += 23;\n            }\n            y = (n >> 27) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_2048_mont_sqr_45(rt, rt, m, mp);\n            sp_2048_mont_sqr_45(rt, rt, m, mp);\n            sp_2048_mont_sqr_45(rt, rt, m, mp);\n            sp_2048_mont_sqr_45(rt, rt, m, mp);\n            sp_2048_mont_sqr_45(rt, rt, m, mp);\n\n            sp_2048_mont_mul_45(rt, rt, t[y], m, mp);\n        }\n\n        sp_2048_mont_reduce_45(rt, m, mp);\n        n = sp_2048_cmp_45(rt, m);\n        sp_2048_cond_sub_45(rt, rt, m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, rt, sizeof(rt));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#endif\n}\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_90(sp_digit* r, const sp_digit* m)\n{\n    /* Set r = 2^n - 1. */\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<89; i++) {\n        r[i] = 0x7fffff;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 88; i += 8) {\n        r[i + 0] = 0x7fffff;\n        r[i + 1] = 0x7fffff;\n        r[i + 2] = 0x7fffff;\n        r[i + 3] = 0x7fffff;\n        r[i + 4] = 0x7fffff;\n        r[i + 5] = 0x7fffff;\n        r[i + 6] = 0x7fffff;\n        r[i + 7] = 0x7fffff;\n    }\n    r[88] = 0x7fffff;\n#endif\n    r[89] = 0x1L;\n\n    /* r = (2^n - 1) mod n */\n    (void)sp_2048_sub_90(r, r, m);\n\n    /* Add one so r = 2^n mod m */\n    r[0] += 1;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_2048_cmp_90(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=89; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    int i;\n\n    r |= (a[89] - b[89]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[88] - b[88]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    for (i = 80; i >= 0; i -= 8) {\n        r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_2048_cond_sub_90(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 90; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 88; i += 8) {\n        r[i + 0] = a[i + 0] - (b[i + 0] & m);\n        r[i + 1] = a[i + 1] - (b[i + 1] & m);\n        r[i + 2] = a[i + 2] - (b[i + 2] & m);\n        r[i + 3] = a[i + 3] - (b[i + 3] & m);\n        r[i + 4] = a[i + 4] - (b[i + 4] & m);\n        r[i + 5] = a[i + 5] - (b[i + 5] & m);\n        r[i + 6] = a[i + 6] - (b[i + 6] & m);\n        r[i + 7] = a[i + 7] - (b[i + 7] & m);\n    }\n    r[88] = a[88] - (b[88] & m);\n    r[89] = a[89] - (b[89] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_2048_mul_add_90(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 90; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0x7fffff;\n        t >>= 23;\n    }\n    r[90] += t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x7fffff);\n    for (i = 0; i < 88; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] += (sp_digit)((t[0] >> 23) + (t[1] & 0x7fffff));\n        t[2] = tb * a[i+2];\n        r[i+2] += (sp_digit)((t[1] >> 23) + (t[2] & 0x7fffff));\n        t[3] = tb * a[i+3];\n        r[i+3] += (sp_digit)((t[2] >> 23) + (t[3] & 0x7fffff));\n        t[4] = tb * a[i+4];\n        r[i+4] += (sp_digit)((t[3] >> 23) + (t[4] & 0x7fffff));\n        t[5] = tb * a[i+5];\n        r[i+5] += (sp_digit)((t[4] >> 23) + (t[5] & 0x7fffff));\n        t[6] = tb * a[i+6];\n        r[i+6] += (sp_digit)((t[5] >> 23) + (t[6] & 0x7fffff));\n        t[7] = tb * a[i+7];\n        r[i+7] += (sp_digit)((t[6] >> 23) + (t[7] & 0x7fffff));\n        t[0] = tb * a[i+8];\n        r[i+8] += (sp_digit)((t[7] >> 23) + (t[0] & 0x7fffff));\n    }\n    t[1] = tb * a[89]; r[89] += (sp_digit)((t[0] >> 23) + (t[1] & 0x7fffff));\n    r[90] +=  (sp_digit)(t[1] >> 23);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Normalize the values in each word to 23.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_2048_norm_90(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 89; i++) {\n        a[i+1] += a[i] >> 23;\n        a[i] &= 0x7fffff;\n    }\n#else\n    int i;\n    for (i = 0; i < 88; i += 8) {\n        a[i+1] += a[i+0] >> 23; a[i+0] &= 0x7fffff;\n        a[i+2] += a[i+1] >> 23; a[i+1] &= 0x7fffff;\n        a[i+3] += a[i+2] >> 23; a[i+2] &= 0x7fffff;\n        a[i+4] += a[i+3] >> 23; a[i+3] &= 0x7fffff;\n        a[i+5] += a[i+4] >> 23; a[i+4] &= 0x7fffff;\n        a[i+6] += a[i+5] >> 23; a[i+5] &= 0x7fffff;\n        a[i+7] += a[i+6] >> 23; a[i+6] &= 0x7fffff;\n        a[i+8] += a[i+7] >> 23; a[i+7] &= 0x7fffff;\n        a[i+9] += a[i+8] >> 23; a[i+8] &= 0x7fffff;\n    }\n    a[88+1] += a[88] >> 23;\n    a[88] &= 0x7fffff;\n#endif\n}\n\n/* Shift the result in the high 2048 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_2048_mont_shift_90(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    int64_t n = a[89] >> 1;\n    n += ((int64_t)a[90]) << 22;\n\n    for (i = 0; i < 89; i++) {\n        r[i] = n & 0x7fffff;\n        n >>= 23;\n        n += ((int64_t)a[91 + i]) << 22;\n    }\n    r[89] = (sp_digit)n;\n#else\n    int i;\n    int64_t n = a[89] >> 1;\n    n += ((int64_t)a[90]) << 22;\n    for (i = 0; i < 88; i += 8) {\n        r[i + 0] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 91]) << 22;\n        r[i + 1] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 92]) << 22;\n        r[i + 2] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 93]) << 22;\n        r[i + 3] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 94]) << 22;\n        r[i + 4] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 95]) << 22;\n        r[i + 5] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 96]) << 22;\n        r[i + 6] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 97]) << 22;\n        r[i + 7] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 98]) << 22;\n    }\n    r[88] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[179]) << 22;\n    r[89] = (sp_digit)n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[90], 0, sizeof(*r) * 90U);\n}\n\n/* Reduce the number back to 2048 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_2048_mont_reduce_90(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    sp_2048_norm_90(a + 90);\n\n#ifdef WOLFSSL_SP_DH\n    if (mp != 1) {\n        for (i=0; i<89; i++) {\n            mu = (a[i] * mp) & 0x7fffff;\n            sp_2048_mul_add_90(a+i, m, mu);\n            a[i+1] += a[i] >> 23;\n        }\n        mu = (a[i] * mp) & 0x1L;\n        sp_2048_mul_add_90(a+i, m, mu);\n        a[i+1] += a[i] >> 23;\n        a[i] &= 0x7fffff;\n    }\n    else {\n        for (i=0; i<89; i++) {\n            mu = a[i] & 0x7fffff;\n            sp_2048_mul_add_90(a+i, m, mu);\n            a[i+1] += a[i] >> 23;\n        }\n        mu = a[i] & 0x1L;\n        sp_2048_mul_add_90(a+i, m, mu);\n        a[i+1] += a[i] >> 23;\n        a[i] &= 0x7fffff;\n    }\n#else\n    for (i=0; i<89; i++) {\n        mu = (a[i] * mp) & 0x7fffff;\n        sp_2048_mul_add_90(a+i, m, mu);\n        a[i+1] += a[i] >> 23;\n    }\n    mu = (a[i] * mp) & 0x1L;\n    sp_2048_mul_add_90(a+i, m, mu);\n    a[i+1] += a[i] >> 23;\n    a[i] &= 0x7fffff;\n#endif\n\n    sp_2048_mont_shift_90(a, a);\n    sp_2048_cond_sub_90(a, a, m, 0 - (((a[89] >> 1) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_2048_norm_90(a);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_90(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_90(r, a, b);\n    sp_2048_mont_reduce_90(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_90(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_90(r, a);\n    sp_2048_mont_reduce_90(r, m, mp);\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_2048_mul_d_180(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 180; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x7fffff;\n        t >>= 23;\n    }\n    r[180] = (sp_digit)t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x7fffff;\n    for (i = 0; i < 176; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 23) + (t[5] & 0x7fffff);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 23) + (t[6] & 0x7fffff);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 23) + (t[7] & 0x7fffff);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 23) + (t[0] & 0x7fffff);\n    }\n    t[1] = tb * a[177];\n    r[177] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);\n    t[2] = tb * a[178];\n    r[178] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);\n    t[3] = tb * a[179];\n    r[179] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);\n    r[180] =  (sp_digit)(t[3] >> 23);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_2048_cond_add_90(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 90; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 88; i += 8) {\n        r[i + 0] = a[i + 0] + (b[i + 0] & m);\n        r[i + 1] = a[i + 1] + (b[i + 1] & m);\n        r[i + 2] = a[i + 2] + (b[i + 2] & m);\n        r[i + 3] = a[i + 3] + (b[i + 3] & m);\n        r[i + 4] = a[i + 4] + (b[i + 4] & m);\n        r[i + 5] = a[i + 5] + (b[i + 5] & m);\n        r[i + 6] = a[i + 6] + (b[i + 6] & m);\n        r[i + 7] = a[i + 7] + (b[i + 7] & m);\n    }\n    r[88] = a[88] + (b[88] & m);\n    r[89] = a[89] + (b[89] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_sub_90(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 90; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif\n#ifdef WOLFSSL_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_90(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 90; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif\nSP_NOINLINE static void sp_2048_rshift_90(sp_digit* r, sp_digit* a, byte n)\n{\n    int i;\n\n#ifdef WOLFSSL_SP_SMALL\n    for (i=0; i<89; i++) {\n        r[i] = ((a[i] >> n) | (a[i + 1] << (23 - n))) & 0x7fffff;\n    }\n#else\n    for (i=0; i<88; i += 8) {\n        r[i+0] = ((a[i+0] >> n) | (a[i+1] << (23 - n))) & 0x7fffff;\n        r[i+1] = ((a[i+1] >> n) | (a[i+2] << (23 - n))) & 0x7fffff;\n        r[i+2] = ((a[i+2] >> n) | (a[i+3] << (23 - n))) & 0x7fffff;\n        r[i+3] = ((a[i+3] >> n) | (a[i+4] << (23 - n))) & 0x7fffff;\n        r[i+4] = ((a[i+4] >> n) | (a[i+5] << (23 - n))) & 0x7fffff;\n        r[i+5] = ((a[i+5] >> n) | (a[i+6] << (23 - n))) & 0x7fffff;\n        r[i+6] = ((a[i+6] >> n) | (a[i+7] << (23 - n))) & 0x7fffff;\n        r[i+7] = ((a[i+7] >> n) | (a[i+8] << (23 - n))) & 0x7fffff;\n    }\n    r[88] = ((a[88] >> n) | (a[89] << (23 - n))) & 0x7fffff;\n#endif\n    r[89] = a[89] >> n;\n}\n\n#ifdef WOLFSSL_SP_DIV_32\nstatic WC_INLINE sp_digit sp_2048_div_word_90(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t;\n\n    /* All 23 bits from d1 and top 8 bits from d0. */\n    d = (d1 << 8) | (d0 >> 15);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 9 bits in r */\n    /* Next 8 bits from d0. */\n    r <<= 8;\n    d <<= 8;\n    d |= (d0 >> 7) & ((1 << 8) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 17 bits in r */\n    /* Remaining 7 bits from d0. */\n    r <<= 7;\n    d <<= 7;\n    d |= d0 & ((1 << 7) - 1);\n    t = d / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_32 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_2048_div_90(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_32\n    int64_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[180 + 1], t2d[90 + 1], sdd[90 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    sp_digit* sd;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 90 + 3), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    (void)m;\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 180 + 1;\n        sd = t2 + 90 + 1;\n#else\n        t1 = t1d;\n        t2 = t2d;\n        sd = sdd;\n#endif\n\n        sp_2048_mul_d_90(sd, d, 1L << 22);\n        sp_2048_mul_d_180(t1, a, 1L << 22);\n        dv = sd[89];\n        for (i=90; i>=0; i--) {\n            t1[90 + i] += t1[90 + i - 1] >> 23;\n            t1[90 + i - 1] &= 0x7fffff;\n#ifndef WOLFSSL_SP_DIV_32\n            d1 = t1[90 + i];\n            d1 <<= 23;\n            d1 += t1[90 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_2048_div_word_90(t1[90 + i], t1[90 + i - 1], dv);\n#endif\n\n            sp_2048_mul_d_90(t2, sd, r1);\n            (void)sp_2048_sub_90(&t1[i], &t1[i], t2);\n            t1[90 + i] -= t2[90];\n            t1[90 + i] += t1[90 + i - 1] >> 23;\n            t1[90 + i - 1] &= 0x7fffff;\n            r1 = (((-t1[90 + i]) << 23) - t1[90 + i - 1]) / dv;\n            r1 -= t1[90 + i];\n            sp_2048_mul_d_90(t2, sd, r1);\n            (void)sp_2048_add_90(&t1[i], &t1[i], t2);\n            t1[90 + i] += t1[90 + i - 1] >> 23;\n            t1[90 + i - 1] &= 0x7fffff;\n        }\n        t1[90 - 1] += t1[90 - 2] >> 23;\n        t1[90 - 2] &= 0x7fffff;\n        d1 = t1[90 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_2048_mul_d_90(t2, sd, r1);\n        sp_2048_sub_90(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 90U);\n        for (i=0; i<88; i++) {\n            r[i+1] += r[i] >> 23;\n            r[i] &= 0x7fffff;\n        }\n        sp_2048_cond_add_90(r, r, sd, 0 - ((r[89] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n\n        sp_2048_norm_90(r);\n        sp_2048_rshift_90(r, r, 22);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_2048_mod_90(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_90(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_90(sp_digit* r, const sp_digit* a, const sp_digit* e, int bits,\n    const sp_digit* m, int reduceA)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* td;\n    sp_digit* t[3];\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 90 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3U * 90U * 2U);\n\n        norm = t[0] = td;\n        t[1] = &td[90 * 2];\n        t[2] = &td[2 * 90 * 2];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_90(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_2048_mod_90(t[1], a, m);\n        }\n        else {\n            XMEMCPY(t[1], a, sizeof(sp_digit) * 90U);\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_2048_mul_90(t[1], t[1], norm);\n        err = sp_2048_mod_90(t[1], t[1], m);\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 23;\n        c = bits % 23;\n        n = e[i--] << (23 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 23;\n            }\n\n            y = (n >> 22) & 1;\n            n <<= 1;\n\n            sp_2048_mont_mul_90(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(*t[2]) * 90 * 2);\n            sp_2048_mont_sqr_90(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(*t[2]) * 90 * 2);\n        }\n\n        sp_2048_mont_reduce_90(t[0], m, mp);\n        n = sp_2048_cmp_90(t[0], m);\n        sp_2048_cond_sub_90(t[0], t[0], m, ((n < 0) ?\n                    (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(*r) * 90 * 2);\n\n    }\n\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    return err;\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[3][180];\n#else\n    sp_digit* td;\n    sp_digit* t[3];\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 90 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        t[0] = td;\n        t[1] = &td[90 * 2];\n        t[2] = &td[2 * 90 * 2];\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_90(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_2048_mod_90(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_2048_mul_90(t[1], t[1], norm);\n                err = sp_2048_mod_90(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_2048_mul_90(t[1], a, norm);\n            err = sp_2048_mod_90(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 23;\n        c = bits % 23;\n        n = e[i--] << (23 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 23;\n            }\n\n            y = (n >> 22) & 1;\n            n <<= 1;\n\n            sp_2048_mont_mul_90(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_2048_mont_sqr_90(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                           ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));\n        }\n\n        sp_2048_mont_reduce_90(t[0], m, mp);\n        n = sp_2048_cmp_90(t[0], m);\n        sp_2048_cond_sub_90(t[0], t[0], m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(t[0]));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][180];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit rt[180];\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 180, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 180;\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_90(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_2048_mod_90(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_2048_mul_90(t[1], t[1], norm);\n                err = sp_2048_mod_90(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_2048_mul_90(t[1], a, norm);\n            err = sp_2048_mod_90(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_90(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_90(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_90(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_90(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_90(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_90(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_90(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_90(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_90(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_90(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_90(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_90(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_90(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_90(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_90(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_90(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_90(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_90(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_90(t[20], t[10], m, mp);\n        sp_2048_mont_mul_90(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_90(t[22], t[11], m, mp);\n        sp_2048_mont_mul_90(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_90(t[24], t[12], m, mp);\n        sp_2048_mont_mul_90(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_90(t[26], t[13], m, mp);\n        sp_2048_mont_mul_90(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_90(t[28], t[14], m, mp);\n        sp_2048_mont_mul_90(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_90(t[30], t[15], m, mp);\n        sp_2048_mont_mul_90(t[31], t[16], t[15], m, mp);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 22) / 23) - 1;\n        c = bits % 23;\n        if (c == 0) {\n            c = 23;\n        }\n        if (i < 90) {\n            n = e[i--] << (32 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (9 - c);\n            c += 23;\n        }\n        y = (n >> 27) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        XMEMCPY(rt, t[y], sizeof(rt));\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (9 - c);\n                c += 23;\n            }\n            y = (n >> 27) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_2048_mont_sqr_90(rt, rt, m, mp);\n            sp_2048_mont_sqr_90(rt, rt, m, mp);\n            sp_2048_mont_sqr_90(rt, rt, m, mp);\n            sp_2048_mont_sqr_90(rt, rt, m, mp);\n            sp_2048_mont_sqr_90(rt, rt, m, mp);\n\n            sp_2048_mont_mul_90(rt, rt, t[y], m, mp);\n        }\n\n        sp_2048_mont_reduce_90(rt, m, mp);\n        n = sp_2048_cmp_90(rt, m);\n        sp_2048_cond_sub_90(rt, rt, m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, rt, sizeof(rt));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#endif\n}\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */\n       /* WOLFSSL_HAVE_SP_DH */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \\\n           !defined(RSA_LOW_MEM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_45(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<45; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 40; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n    r[40] = a[40] & m;\n    r[41] = a[41] & m;\n    r[42] = a[42] & m;\n    r[43] = a[43] & m;\n    r[44] = a[44] & m;\n#endif\n}\n\n#endif\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* d = NULL;\n    sp_digit* a;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit* norm;\n    sp_digit e[1] = {0};\n    sp_digit mp;\n    int i;\n    int err = MP_OKAY;\n\n    if (*outLen < 256U) {\n        err = MP_TO_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(em) > 23) {\n            err = MP_READ_E;\n        }\n        if (inLen > 256U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 90 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 90 * 2;\n        m = r + 90 * 2;\n        norm = r;\n\n        sp_2048_from_bin(a, 90, in, inLen);\n#if DIGIT_BIT >= 23\n        e[0] = (sp_digit)em->dp[0];\n#else\n        e[0] = (sp_digit)em->dp[0];\n        if (em->used > 1) {\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n        }\n#endif\n        if (e[0] == 0) {\n            err = MP_EXPTMOD_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(m, 90, mm);\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_90(norm, m);\n    }\n    if (err == MP_OKAY) {\n        sp_2048_mul_90(a, a, norm);\n        err = sp_2048_mod_90(a, a, m);\n    }\n    if (err == MP_OKAY) {\n        for (i=22; i>=0; i--) {\n            if ((e[0] >> i) != 0) {\n                break;\n            }\n        }\n\n        XMEMCPY(r, a, sizeof(sp_digit) * 90 * 2);\n        for (i--; i>=0; i--) {\n            sp_2048_mont_sqr_90(r, r, m, mp);\n\n            if (((e[0] >> i) & 1) == 1) {\n                sp_2048_mont_mul_90(r, r, a, m, mp);\n            }\n        }\n        sp_2048_mont_reduce_90(r, m, mp);\n        mp = sp_2048_cmp_90(r, m);\n        sp_2048_cond_sub_90(r, r, m, ((mp < 0) ?\n                    (sp_digit)1 : (sp_digit)0)- 1);\n\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[180], md[90], rd[180];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1] = {0};\n    int err = MP_OKAY;\n\n    if (*outLen < 256U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(em) > 23) {\n            err = MP_READ_E;\n        }\n        if (inLen > 256U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 90 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 90 * 2;\n        m = r + 90 * 2;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(a, 90, in, inLen);\n#if DIGIT_BIT >= 23\n        e[0] = (sp_digit)em->dp[0];\n#else\n        e[0] = (sp_digit)em->dp[0];\n        if (em->used > 1) {\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n        }\n#endif\n        if (e[0] == 0) {\n            err = MP_EXPTMOD_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(m, 90, mm);\n\n        if (e[0] == 0x3) {\n            sp_2048_sqr_90(r, a);\n            err = sp_2048_mod_90(r, r, m);\n            if (err == MP_OKAY) {\n                sp_2048_mul_90(r, a, r);\n                err = sp_2048_mod_90(r, r, m);\n            }\n        }\n        else {\n            sp_digit* norm = r;\n            int i;\n            sp_digit mp;\n\n            sp_2048_mont_setup(m, &mp);\n            sp_2048_mont_norm_90(norm, m);\n\n            sp_2048_mul_90(a, a, norm);\n            err = sp_2048_mod_90(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=22; i>=0; i--) {\n                    if ((e[0] >> i) != 0) {\n                        break;\n                    }\n                }\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 180U);\n                for (i--; i>=0; i--) {\n                    sp_2048_mont_sqr_90(r, r, m, mp);\n\n                    if (((e[0] >> i) & 1) == 1) {\n                        sp_2048_mont_mul_90(r, r, a, m, mp);\n                    }\n                }\n                sp_2048_mont_reduce_90(r, m, mp);\n                mp = sp_2048_cmp_90(r, m);\n                sp_2048_cond_sub_90(r, r, m, ((mp < 0) ?\n                           (sp_digit)1 : (sp_digit)0) - 1);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n#endif\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* a;\n    sp_digit* d = NULL;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n\n    (void)pm;\n    (void)qm;\n    (void)dpm;\n    (void)dqm;\n    (void)qim;\n\n    if (*outLen < 256U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(dm) > 2048) {\n           err = MP_READ_E;\n        }\n        if (inLen > 256) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 90 * 4, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        a = d + 90;\n        m = a + 90;\n        r = a;\n\n        sp_2048_from_bin(a, 90, in, inLen);\n        sp_2048_from_mp(d, 90, dm);\n        sp_2048_from_mp(m, 90, mm);\n        err = sp_2048_mod_exp_90(r, a, d, 2048, m, 0);\n    }\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n    if (d != NULL) {\n        XMEMSET(d, 0, sizeof(sp_digit) * 90);\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n    sp_digit a[180], d[90], m[90];\n    sp_digit* r = a;\n    int err = MP_OKAY;\n\n    (void)pm;\n    (void)qm;\n    (void)dpm;\n    (void)dqm;\n    (void)qim;\n\n    if (*outLen < 256U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(dm) > 2048) {\n            err = MP_READ_E;\n        }\n        if (inLen > 256U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(a, 90, in, inLen);\n        sp_2048_from_mp(d, 90, dm);\n        sp_2048_from_mp(m, 90, mm);\n        err = sp_2048_mod_exp_90(r, a, d, 2048, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n    XMEMSET(d, 0, sizeof(sp_digit) * 90);\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */\n#else\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* t = NULL;\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 256U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (inLen > 256) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 45 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL) {\n            err = MEMORY_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 90 * 2;\n        q = p + 45;\n        qi = dq = dp = q + 45;\n        tmpa = qi + 45;\n        tmpb = tmpa + 90;\n\n        tmp = t;\n        r = tmp + 90;\n\n        sp_2048_from_bin(a, 90, in, inLen);\n        sp_2048_from_mp(p, 45, pm);\n        sp_2048_from_mp(q, 45, qm);\n        sp_2048_from_mp(dp, 45, dpm);\n        err = sp_2048_mod_exp_45(tmpa, a, dp, 1024, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(dq, 45, dqm);\n        err = sp_2048_mod_exp_45(tmpb, a, dq, 1024, q, 1);\n    }\n    if (err == MP_OKAY) {\n        (void)sp_2048_sub_45(tmpa, tmpa, tmpb);\n        sp_2048_mask_45(tmp, p, 0 - ((sp_int_digit)tmpa[44] >> 31));\n        (void)sp_2048_add_45(tmpa, tmpa, tmp);\n\n        sp_2048_from_mp(qi, 45, qim);\n        sp_2048_mul_45(tmpa, tmpa, qi);\n        err = sp_2048_mod_45(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mul_45(tmpa, q, tmpa);\n        (void)sp_2048_add_90(r, tmpb, tmpa);\n        sp_2048_norm_90(r);\n\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 45 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n    sp_digit a[90 * 2];\n    sp_digit p[45], q[45], dp[45], dq[45], qi[45];\n    sp_digit tmp[90], tmpa[90], tmpb[90];\n    sp_digit* r = a;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 256U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (inLen > 256U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(a, 90, in, inLen);\n        sp_2048_from_mp(p, 45, pm);\n        sp_2048_from_mp(q, 45, qm);\n        sp_2048_from_mp(dp, 45, dpm);\n        sp_2048_from_mp(dq, 45, dqm);\n        sp_2048_from_mp(qi, 45, qim);\n\n        err = sp_2048_mod_exp_45(tmpa, a, dp, 1024, p, 1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_2048_mod_exp_45(tmpb, a, dq, 1024, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        (void)sp_2048_sub_45(tmpa, tmpa, tmpb);\n        sp_2048_mask_45(tmp, p, 0 - ((sp_int_digit)tmpa[44] >> 31));\n        (void)sp_2048_add_45(tmpa, tmpa, tmp);\n        sp_2048_mul_45(tmpa, tmpa, qi);\n        err = sp_2048_mod_45(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mul_45(tmpa, tmpa, q);\n        (void)sp_2048_add_90(r, tmpb, tmpa);\n        sp_2048_norm_90(r);\n\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n    XMEMSET(tmpa, 0, sizeof(tmpa));\n    XMEMSET(tmpb, 0, sizeof(tmpb));\n    XMEMSET(p, 0, sizeof(p));\n    XMEMSET(q, 0, sizeof(q));\n    XMEMSET(dp, 0, sizeof(dp));\n    XMEMSET(dq, 0, sizeof(dq));\n    XMEMSET(qi, 0, sizeof(qi));\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */\n#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */\n}\n\n#endif /* !WOLFSSL_RSA_PUBLIC_ONLY */\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_2048_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 23\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 90);\n        r->used = 90;\n        mp_clamp(r);\n#elif DIGIT_BIT < 23\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 90; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 23) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 23 - s;\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 90; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 23 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 23 - s;\n            }\n            else {\n                s += 23;\n            }\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 90 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 90 * 2;\n        m = e + 90;\n        r = b;\n\n        sp_2048_from_mp(b, 90, base);\n        sp_2048_from_mp(e, 90, exp);\n        sp_2048_from_mp(m, 90, mod);\n\n        err = sp_2048_mod_exp_90(r, b, e, mp_count_bits(exp), m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_2048_to_mp(r, res);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 90U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[180], ed[90], md[90];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 2048) {\n            err = MP_READ_E;\n        }\n    }\n    \n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 90 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 90 * 2;\n        m = e + 90;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 90, base);\n        sp_2048_from_mp(e, 90, exp);\n        sp_2048_from_mp(m, 90, mod);\n\n        err = sp_2048_mod_exp_90(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_2048_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 90U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_2048\nSP_NOINLINE static void sp_2048_lshift_90(sp_digit* r, sp_digit* a, byte n)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    r[90] = a[89] >> (23 - n);\n    for (i=89; i>0; i--) {\n        r[i] = ((a[i] << n) | (a[i-1] >> (23 - n))) & 0x7fffff;\n    }\n#else\n    sp_int_digit s, t;\n\n    s = (sp_int_digit)a[89];\n    r[90] = s >> (23U - n);\n    s = (sp_int_digit)(a[89]); t = (sp_int_digit)(a[88]);\n    r[89] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[88]); t = (sp_int_digit)(a[87]);\n    r[88] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[87]); t = (sp_int_digit)(a[86]);\n    r[87] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[86]); t = (sp_int_digit)(a[85]);\n    r[86] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[85]); t = (sp_int_digit)(a[84]);\n    r[85] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[84]); t = (sp_int_digit)(a[83]);\n    r[84] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[83]); t = (sp_int_digit)(a[82]);\n    r[83] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[82]); t = (sp_int_digit)(a[81]);\n    r[82] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[81]); t = (sp_int_digit)(a[80]);\n    r[81] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[80]); t = (sp_int_digit)(a[79]);\n    r[80] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[79]); t = (sp_int_digit)(a[78]);\n    r[79] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[78]); t = (sp_int_digit)(a[77]);\n    r[78] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[77]); t = (sp_int_digit)(a[76]);\n    r[77] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[76]); t = (sp_int_digit)(a[75]);\n    r[76] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[75]); t = (sp_int_digit)(a[74]);\n    r[75] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[74]); t = (sp_int_digit)(a[73]);\n    r[74] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[73]); t = (sp_int_digit)(a[72]);\n    r[73] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[72]); t = (sp_int_digit)(a[71]);\n    r[72] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[71]); t = (sp_int_digit)(a[70]);\n    r[71] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[70]); t = (sp_int_digit)(a[69]);\n    r[70] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[69]); t = (sp_int_digit)(a[68]);\n    r[69] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[68]); t = (sp_int_digit)(a[67]);\n    r[68] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[67]); t = (sp_int_digit)(a[66]);\n    r[67] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[66]); t = (sp_int_digit)(a[65]);\n    r[66] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[65]); t = (sp_int_digit)(a[64]);\n    r[65] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[64]); t = (sp_int_digit)(a[63]);\n    r[64] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[63]); t = (sp_int_digit)(a[62]);\n    r[63] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[62]); t = (sp_int_digit)(a[61]);\n    r[62] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[61]); t = (sp_int_digit)(a[60]);\n    r[61] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[60]); t = (sp_int_digit)(a[59]);\n    r[60] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[59]); t = (sp_int_digit)(a[58]);\n    r[59] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[58]); t = (sp_int_digit)(a[57]);\n    r[58] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[57]); t = (sp_int_digit)(a[56]);\n    r[57] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[56]); t = (sp_int_digit)(a[55]);\n    r[56] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[55]); t = (sp_int_digit)(a[54]);\n    r[55] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[54]); t = (sp_int_digit)(a[53]);\n    r[54] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[53]); t = (sp_int_digit)(a[52]);\n    r[53] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[52]); t = (sp_int_digit)(a[51]);\n    r[52] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[51]); t = (sp_int_digit)(a[50]);\n    r[51] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[50]); t = (sp_int_digit)(a[49]);\n    r[50] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[49]); t = (sp_int_digit)(a[48]);\n    r[49] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[48]); t = (sp_int_digit)(a[47]);\n    r[48] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[47]); t = (sp_int_digit)(a[46]);\n    r[47] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[46]); t = (sp_int_digit)(a[45]);\n    r[46] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[45]); t = (sp_int_digit)(a[44]);\n    r[45] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[44]); t = (sp_int_digit)(a[43]);\n    r[44] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[43]); t = (sp_int_digit)(a[42]);\n    r[43] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[42]); t = (sp_int_digit)(a[41]);\n    r[42] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[41]); t = (sp_int_digit)(a[40]);\n    r[41] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[40]); t = (sp_int_digit)(a[39]);\n    r[40] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[39]); t = (sp_int_digit)(a[38]);\n    r[39] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[38]); t = (sp_int_digit)(a[37]);\n    r[38] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[37]); t = (sp_int_digit)(a[36]);\n    r[37] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[36]); t = (sp_int_digit)(a[35]);\n    r[36] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[35]); t = (sp_int_digit)(a[34]);\n    r[35] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[34]); t = (sp_int_digit)(a[33]);\n    r[34] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[33]); t = (sp_int_digit)(a[32]);\n    r[33] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[32]); t = (sp_int_digit)(a[31]);\n    r[32] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[31]); t = (sp_int_digit)(a[30]);\n    r[31] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[30]); t = (sp_int_digit)(a[29]);\n    r[30] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[29]); t = (sp_int_digit)(a[28]);\n    r[29] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[28]); t = (sp_int_digit)(a[27]);\n    r[28] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[27]); t = (sp_int_digit)(a[26]);\n    r[27] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[26]); t = (sp_int_digit)(a[25]);\n    r[26] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[25]); t = (sp_int_digit)(a[24]);\n    r[25] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[24]); t = (sp_int_digit)(a[23]);\n    r[24] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[23]); t = (sp_int_digit)(a[22]);\n    r[23] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[22]); t = (sp_int_digit)(a[21]);\n    r[22] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[21]); t = (sp_int_digit)(a[20]);\n    r[21] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[20]); t = (sp_int_digit)(a[19]);\n    r[20] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[19]); t = (sp_int_digit)(a[18]);\n    r[19] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[18]); t = (sp_int_digit)(a[17]);\n    r[18] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[17]); t = (sp_int_digit)(a[16]);\n    r[17] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[16]); t = (sp_int_digit)(a[15]);\n    r[16] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[15]); t = (sp_int_digit)(a[14]);\n    r[15] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[14]); t = (sp_int_digit)(a[13]);\n    r[14] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);\n    r[13] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);\n    r[12] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);\n    r[11] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);\n    r[10] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);\n    r[9] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);\n    r[8] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);\n    r[7] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);\n    r[6] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);\n    r[5] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);\n    r[4] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);\n    r[3] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);\n    r[2] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);\n    r[1] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n#endif\n    r[0] = (a[0] << n) & 0x7fffff;\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_2_90(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[180];\n    sp_digit td[91];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 271, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 180;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        XMEMSET(td, 0, sizeof(td));\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_90(norm, m);\n\n        bits = ((bits + 3) / 4) * 4;\n        i = ((bits + 22) / 23) - 1;\n        c = bits % 23;\n        if (c == 0) {\n            c = 23;\n        }\n        if (i < 90) {\n            n = e[i--] << (32 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 4) {\n            n |= e[i--] << (9 - c);\n            c += 23;\n        }\n        y = (n >> 28) & 0xf;\n        n <<= 4;\n        c -= 4;\n        sp_2048_lshift_90(r, norm, y);\n        for (; i>=0 || c>=4; ) {\n            if (c < 4) {\n                n |= e[i--] << (9 - c);\n                c += 23;\n            }\n            y = (n >> 28) & 0xf;\n            n <<= 4;\n            c -= 4;\n\n            sp_2048_mont_sqr_90(r, r, m, mp);\n            sp_2048_mont_sqr_90(r, r, m, mp);\n            sp_2048_mont_sqr_90(r, r, m, mp);\n            sp_2048_mont_sqr_90(r, r, m, mp);\n\n            sp_2048_lshift_90(r, r, y);\n            sp_2048_mul_d_90(tmp, norm, (r[90] << 22) + (r[89] >> 1));\n            r[90] = 0;\n            r[89] &= 0x1L;\n            (void)sp_2048_add_90(r, r, tmp);\n            sp_2048_norm_90(r);\n            o = sp_2048_cmp_90(r, m);\n            sp_2048_cond_sub_90(r, r, m, ((o < 0) ?\n                                          (sp_digit)1 : (sp_digit)0) - 1);\n        }\n\n        sp_2048_mont_reduce_90(r, m, mp);\n        n = sp_2048_cmp_90(r, m);\n        sp_2048_cond_sub_90(r, r, m, ((n < 0) ?\n                                                (sp_digit)1 : (sp_digit)0) - 1);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n#endif /* HAVE_FFDHE_2048 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 256 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    word32 i;\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 256) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 90 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 90 * 2;\n        m = e + 90;\n        r = b;\n\n        sp_2048_from_mp(b, 90, base);\n        sp_2048_from_bin(e, 90, exp, expLen);\n        sp_2048_from_mp(m, 90, mod);\n\n    #ifdef HAVE_FFDHE_2048\n        if (base->used == 1 && base->dp[0] == 2 &&\n                ((m[89] << 15) | (m[88] >> 8)) == 0xffffL) {\n            err = sp_2048_mod_exp_2_90(r, e, expLen * 8, m);\n        }\n        else\n    #endif\n            err = sp_2048_mod_exp_90(r, b, e, expLen * 8, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n        for (i=0; i<256 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 90U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[180], ed[90], md[90];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    word32 i;\n    int err = MP_OKAY;\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 256U) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 90 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 90 * 2;\n        m = e + 90;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 90, base);\n        sp_2048_from_bin(e, 90, exp, expLen);\n        sp_2048_from_mp(m, 90, mod);\n\n    #ifdef HAVE_FFDHE_2048\n        if (base->used == 1 && base->dp[0] == 2U &&\n                ((m[89] << 15) | (m[88] >> 8)) == 0xffffL) {\n            err = sp_2048_mod_exp_2_90(r, e, expLen * 8U, m);\n        }\n        else {\n    #endif\n            err = sp_2048_mod_exp_90(r, b, e, expLen * 8U, m, 0);\n    #ifdef HAVE_FFDHE_2048\n        }\n    #endif\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n        for (i=0; i<256U && out[i] == 0U; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 90U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1024) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 45 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 45 * 2;\n        m = e + 45;\n        r = b;\n\n        sp_2048_from_mp(b, 45, base);\n        sp_2048_from_mp(e, 45, exp);\n        sp_2048_from_mp(m, 45, mod);\n\n        err = sp_2048_mod_exp_45(r, b, e, mp_count_bits(exp), m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 45, 0, sizeof(*r) * 45U);\n        err = sp_2048_to_mp(r, res);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 45U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[90], ed[45], md[45];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1024) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1024) {\n            err = MP_READ_E;\n        }\n    }\n    \n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 45 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 45 * 2;\n        m = e + 45;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 45, base);\n        sp_2048_from_mp(e, 45, exp);\n        sp_2048_from_mp(m, 45, mod);\n\n        err = sp_2048_mod_exp_45(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 45, 0, sizeof(*r) * 45U);\n        err = sp_2048_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 45U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_2048 */\n\n#ifndef WOLFSSL_SP_NO_3072\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 15U) {\n            r[j] &= 0x7fffff;\n            s = 23U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 23\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 23\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0x7fffff;\n        s = 23U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 23U) <= (word32)DIGIT_BIT) {\n            s += 23U;\n            r[j] &= 0x7fffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 23) {\n            r[j] &= 0x7fffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 23 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 384\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_3072_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    for (i=0; i<133; i++) {\n        r[i+1] += r[i] >> 23;\n        r[i] &= 0x7fffff;\n    }\n    j = 3072 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<134 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 23) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 23);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_67(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j;\n    int64_t t[134];\n\n    XMEMSET(t, 0, sizeof(t));\n    for (i=0; i<67; i++) {\n        for (j=0; j<67; j++) {\n            t[i+j] += ((int64_t)a[i]) * b[j];\n        }\n    }\n    for (i=0; i<133; i++) {\n        r[i] = t[i] & 0x7fffff;\n        t[i+1] += t[i] >> 23;\n    }\n    r[133] = (sp_digit)t[133];\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_67(sp_digit* r, const sp_digit* a)\n{\n    int i, j;\n    int64_t t[134];\n\n    XMEMSET(t, 0, sizeof(t));\n    for (i=0; i<67; i++) {\n        for (j=0; j<i; j++) {\n            t[i+j] += (((int64_t)a[i]) * a[j]) * 2;\n        }\n        t[i+i] += ((int64_t)a[i]) * a[i];\n    }\n    for (i=0; i<133; i++) {\n        r[i] = t[i] & 0x7fffff;\n        t[i+1] += t[i] >> 23;\n    }\n    r[133] = (sp_digit)t[133];\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_add_67(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[64] = a[64] + b[64];\n    r[65] = a[65] + b[65];\n    r[66] = a[66] + b[66];\n\n    return 0;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_add_134(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 128; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[128] = a[128] + b[128];\n    r[129] = a[129] + b[129];\n    r[130] = a[130] + b[130];\n    r[131] = a[131] + b[131];\n    r[132] = a[132] + b[132];\n    r[133] = a[133] + b[133];\n\n    return 0;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_sub_134(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 128; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[128] = a[128] - b[128];\n    r[129] = a[129] - b[129];\n    r[130] = a[130] - b[130];\n    r[131] = a[131] - b[131];\n    r[132] = a[132] - b[132];\n    r[133] = a[133] - b[133];\n\n    return 0;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_134(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[134];\n    sp_digit* a1 = z1;\n    sp_digit b1[67];\n    sp_digit* z2 = r + 134;\n    (void)sp_3072_add_67(a1, a, &a[67]);\n    (void)sp_3072_add_67(b1, b, &b[67]);\n    sp_3072_mul_67(z2, &a[67], &b[67]);\n    sp_3072_mul_67(z0, a, b);\n    sp_3072_mul_67(z1, a1, b1);\n    (void)sp_3072_sub_134(z1, z1, z2);\n    (void)sp_3072_sub_134(z1, z1, z0);\n    (void)sp_3072_add_134(r + 67, r + 67, z1);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_134(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[134];\n    sp_digit* a1 = z1;\n    sp_digit* z2 = r + 134;\n    (void)sp_3072_add_67(a1, a, &a[67]);\n    sp_3072_sqr_67(z2, &a[67]);\n    sp_3072_sqr_67(z0, a);\n    sp_3072_sqr_67(z1, a1);\n    (void)sp_3072_sub_134(z1, z1, z2);\n    (void)sp_3072_sub_134(z1, z1, z0);\n    (void)sp_3072_add_134(r + 67, r + 67, z1);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_add_134(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 134; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_sub_134(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 134; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_134(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[133]) * b[133];\n    r[267] = (sp_digit)(c >> 23);\n    c = (c & 0x7fffff) << 23;\n    for (k = 265; k >= 0; k--) {\n        for (i = 133; i >= 0; i--) {\n            j = k - i;\n            if (j >= 134) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 46;\n        r[k + 1] = (c >> 23) & 0x7fffff;\n        c = (c & 0x7fffff) << 23;\n    }\n    r[0] = (sp_digit)(c >> 23);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_134(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[133]) * a[133];\n    r[267] = (sp_digit)(c >> 23);\n    c = (c & 0x7fffff) << 23;\n    for (k = 265; k >= 0; k--) {\n        for (i = 133; i >= 0; i--) {\n            j = k - i;\n            if (j >= 134 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int64_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 46;\n        r[k + 1] = (c >> 23) & 0x7fffff;\n        c = (c & 0x7fffff) << 23;\n    }\n    r[0] = (sp_digit)(c >> 23);\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_add_67(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 67; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_sub_67(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 67; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#else\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_sub_67(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[64] = a[64] - b[64];\n    r[65] = a[65] - b[65];\n    r[66] = a[66] - b[66];\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_67(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[66]) * b[66];\n    r[133] = (sp_digit)(c >> 23);\n    c = (c & 0x7fffff) << 23;\n    for (k = 131; k >= 0; k--) {\n        for (i = 66; i >= 0; i--) {\n            j = k - i;\n            if (j >= 67) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 46;\n        r[k + 1] = (c >> 23) & 0x7fffff;\n        c = (c & 0x7fffff) << 23;\n    }\n    r[0] = (sp_digit)(c >> 23);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_67(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[66]) * a[66];\n    r[133] = (sp_digit)(c >> 23);\n    c = (c & 0x7fffff) << 23;\n    for (k = 131; k >= 0; k--) {\n        for (i = 66; i >= 0; i--) {\n            j = k - i;\n            if (j >= 67 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int64_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 46;\n        r[k + 1] = (c >> 23) & 0x7fffff;\n        c = (c & 0x7fffff) << 23;\n    }\n    r[0] = (sp_digit)(c >> 23);\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n    x &= 0x7fffff;\n\n    /* rho = -1/m mod b */\n    *rho = (1L << 23) - x;\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_3072_mul_d_134(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 134; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x7fffff;\n        t >>= 23;\n    }\n    r[134] = (sp_digit)t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x7fffff;\n    for (i = 0; i < 128; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 23) + (t[5] & 0x7fffff);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 23) + (t[6] & 0x7fffff);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 23) + (t[7] & 0x7fffff);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 23) + (t[0] & 0x7fffff);\n    }\n    t[1] = tb * a[129];\n    r[129] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);\n    t[2] = tb * a[130];\n    r[130] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);\n    t[3] = tb * a[131];\n    r[131] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);\n    t[4] = tb * a[132];\n    r[132] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);\n    t[5] = tb * a[133];\n    r[133] = (sp_digit)(t[4] >> 23) + (t[5] & 0x7fffff);\n    r[134] =  (sp_digit)(t[5] >> 23);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_67(sp_digit* r, const sp_digit* m)\n{\n    /* Set r = 2^n - 1. */\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<66; i++) {\n        r[i] = 0x7fffff;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i + 0] = 0x7fffff;\n        r[i + 1] = 0x7fffff;\n        r[i + 2] = 0x7fffff;\n        r[i + 3] = 0x7fffff;\n        r[i + 4] = 0x7fffff;\n        r[i + 5] = 0x7fffff;\n        r[i + 6] = 0x7fffff;\n        r[i + 7] = 0x7fffff;\n    }\n    r[64] = 0x7fffff;\n    r[65] = 0x7fffff;\n#endif\n    r[66] = 0x3ffffL;\n\n    /* r = (2^n - 1) mod n */\n    (void)sp_3072_sub_67(r, r, m);\n\n    /* Add one so r = 2^n mod m */\n    r[0] += 1;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_3072_cmp_67(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=66; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    int i;\n\n    r |= (a[66] - b[66]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[65] - b[65]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[64] - b[64]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    for (i = 56; i >= 0; i -= 8) {\n        r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_3072_cond_sub_67(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 67; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i + 0] = a[i + 0] - (b[i + 0] & m);\n        r[i + 1] = a[i + 1] - (b[i + 1] & m);\n        r[i + 2] = a[i + 2] - (b[i + 2] & m);\n        r[i + 3] = a[i + 3] - (b[i + 3] & m);\n        r[i + 4] = a[i + 4] - (b[i + 4] & m);\n        r[i + 5] = a[i + 5] - (b[i + 5] & m);\n        r[i + 6] = a[i + 6] - (b[i + 6] & m);\n        r[i + 7] = a[i + 7] - (b[i + 7] & m);\n    }\n    r[64] = a[64] - (b[64] & m);\n    r[65] = a[65] - (b[65] & m);\n    r[66] = a[66] - (b[66] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_3072_mul_add_67(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 67; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0x7fffff;\n        t >>= 23;\n    }\n    r[67] += t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x7fffff);\n    for (i = 0; i < 64; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] += (sp_digit)((t[0] >> 23) + (t[1] & 0x7fffff));\n        t[2] = tb * a[i+2];\n        r[i+2] += (sp_digit)((t[1] >> 23) + (t[2] & 0x7fffff));\n        t[3] = tb * a[i+3];\n        r[i+3] += (sp_digit)((t[2] >> 23) + (t[3] & 0x7fffff));\n        t[4] = tb * a[i+4];\n        r[i+4] += (sp_digit)((t[3] >> 23) + (t[4] & 0x7fffff));\n        t[5] = tb * a[i+5];\n        r[i+5] += (sp_digit)((t[4] >> 23) + (t[5] & 0x7fffff));\n        t[6] = tb * a[i+6];\n        r[i+6] += (sp_digit)((t[5] >> 23) + (t[6] & 0x7fffff));\n        t[7] = tb * a[i+7];\n        r[i+7] += (sp_digit)((t[6] >> 23) + (t[7] & 0x7fffff));\n        t[0] = tb * a[i+8];\n        r[i+8] += (sp_digit)((t[7] >> 23) + (t[0] & 0x7fffff));\n    }\n    t[1] = tb * a[65]; r[65] += (sp_digit)((t[0] >> 23) + (t[1] & 0x7fffff));\n    t[2] = tb * a[66]; r[66] += (sp_digit)((t[1] >> 23) + (t[2] & 0x7fffff));\n    r[67] +=  (sp_digit)(t[2] >> 23);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Normalize the values in each word to 23.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_3072_norm_67(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 66; i++) {\n        a[i+1] += a[i] >> 23;\n        a[i] &= 0x7fffff;\n    }\n#else\n    int i;\n    for (i = 0; i < 64; i += 8) {\n        a[i+1] += a[i+0] >> 23; a[i+0] &= 0x7fffff;\n        a[i+2] += a[i+1] >> 23; a[i+1] &= 0x7fffff;\n        a[i+3] += a[i+2] >> 23; a[i+2] &= 0x7fffff;\n        a[i+4] += a[i+3] >> 23; a[i+3] &= 0x7fffff;\n        a[i+5] += a[i+4] >> 23; a[i+4] &= 0x7fffff;\n        a[i+6] += a[i+5] >> 23; a[i+5] &= 0x7fffff;\n        a[i+7] += a[i+6] >> 23; a[i+6] &= 0x7fffff;\n        a[i+8] += a[i+7] >> 23; a[i+7] &= 0x7fffff;\n        a[i+9] += a[i+8] >> 23; a[i+8] &= 0x7fffff;\n    }\n    a[64+1] += a[64] >> 23;\n    a[64] &= 0x7fffff;\n    a[65+1] += a[65] >> 23;\n    a[65] &= 0x7fffff;\n#endif\n}\n\n/* Shift the result in the high 1536 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_3072_mont_shift_67(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    sp_digit n, s;\n\n    s = a[67];\n    n = a[66] >> 18;\n    for (i = 0; i < 66; i++) {\n        n += (s & 0x7fffff) << 5;\n        r[i] = n & 0x7fffff;\n        n >>= 23;\n        s = a[68 + i] + (s >> 23);\n    }\n    n += s << 5;\n    r[66] = n;\n#else\n    sp_digit n, s;\n    int i;\n\n    s = a[67]; n = a[66] >> 18;\n    for (i = 0; i < 64; i += 8) {\n        n += (s & 0x7fffff) << 5; r[i+0] = n & 0x7fffff;\n        n >>= 23; s = a[i+68] + (s >> 23);\n        n += (s & 0x7fffff) << 5; r[i+1] = n & 0x7fffff;\n        n >>= 23; s = a[i+69] + (s >> 23);\n        n += (s & 0x7fffff) << 5; r[i+2] = n & 0x7fffff;\n        n >>= 23; s = a[i+70] + (s >> 23);\n        n += (s & 0x7fffff) << 5; r[i+3] = n & 0x7fffff;\n        n >>= 23; s = a[i+71] + (s >> 23);\n        n += (s & 0x7fffff) << 5; r[i+4] = n & 0x7fffff;\n        n >>= 23; s = a[i+72] + (s >> 23);\n        n += (s & 0x7fffff) << 5; r[i+5] = n & 0x7fffff;\n        n >>= 23; s = a[i+73] + (s >> 23);\n        n += (s & 0x7fffff) << 5; r[i+6] = n & 0x7fffff;\n        n >>= 23; s = a[i+74] + (s >> 23);\n        n += (s & 0x7fffff) << 5; r[i+7] = n & 0x7fffff;\n        n >>= 23; s = a[i+75] + (s >> 23);\n    }\n    n += (s & 0x7fffff) << 5; r[64] = n & 0x7fffff;\n    n >>= 23; s = a[132] + (s >> 23);\n    n += (s & 0x7fffff) << 5; r[65] = n & 0x7fffff;\n    n >>= 23; s = a[133] + (s >> 23);\n    n += s << 5;              r[66] = n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[67], 0, sizeof(*r) * 67U);\n}\n\n/* Reduce the number back to 3072 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_3072_mont_reduce_67(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    sp_3072_norm_67(a + 67);\n\n    for (i=0; i<66; i++) {\n        mu = (a[i] * mp) & 0x7fffff;\n        sp_3072_mul_add_67(a+i, m, mu);\n        a[i+1] += a[i] >> 23;\n    }\n    mu = (a[i] * mp) & 0x3ffffL;\n    sp_3072_mul_add_67(a+i, m, mu);\n    a[i+1] += a[i] >> 23;\n    a[i] &= 0x7fffff;\n\n    sp_3072_mont_shift_67(a, a);\n    sp_3072_cond_sub_67(a, a, m, 0 - (((a[66] >> 18) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_3072_norm_67(a);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_67(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_67(r, a, b);\n    sp_3072_mont_reduce_67(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_67(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_67(r, a);\n    sp_3072_mont_reduce_67(r, m, mp);\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_3072_mul_d_67(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 67; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x7fffff;\n        t >>= 23;\n    }\n    r[67] = (sp_digit)t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x7fffff;\n    for (i = 0; i < 64; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 23) + (t[5] & 0x7fffff);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 23) + (t[6] & 0x7fffff);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 23) + (t[7] & 0x7fffff);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 23) + (t[0] & 0x7fffff);\n    }\n    t[1] = tb * a[65];\n    r[65] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);\n    t[2] = tb * a[66];\n    r[66] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);\n    r[67] =  (sp_digit)(t[2] >> 23);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_3072_cond_add_67(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 67; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i + 0] = a[i + 0] + (b[i + 0] & m);\n        r[i + 1] = a[i + 1] + (b[i + 1] & m);\n        r[i + 2] = a[i + 2] + (b[i + 2] & m);\n        r[i + 3] = a[i + 3] + (b[i + 3] & m);\n        r[i + 4] = a[i + 4] + (b[i + 4] & m);\n        r[i + 5] = a[i + 5] + (b[i + 5] & m);\n        r[i + 6] = a[i + 6] + (b[i + 6] & m);\n        r[i + 7] = a[i + 7] + (b[i + 7] & m);\n    }\n    r[64] = a[64] + (b[64] & m);\n    r[65] = a[65] + (b[65] & m);\n    r[66] = a[66] + (b[66] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_add_67(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 67; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif\n#ifdef WOLFSSL_SP_DIV_32\nstatic WC_INLINE sp_digit sp_3072_div_word_67(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t;\n\n    /* All 23 bits from d1 and top 8 bits from d0. */\n    d = (d1 << 8) | (d0 >> 15);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 9 bits in r */\n    /* Next 8 bits from d0. */\n    r <<= 8;\n    d <<= 8;\n    d |= (d0 >> 7) & ((1 << 8) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 17 bits in r */\n    /* Remaining 7 bits from d0. */\n    r <<= 7;\n    d <<= 7;\n    d |= d0 & ((1 << 7) - 1);\n    t = d / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_32 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Number to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_3072_div_67(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_32\n    int64_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[134], t2d[67 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (3 * 67 + 1), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 2 * 67;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        dv = d[66];\n        XMEMCPY(t1, a, sizeof(*t1) * 2U * 67U);\n        for (i=66; i>=0; i--) {\n            t1[67 + i] += t1[67 + i - 1] >> 23;\n            t1[67 + i - 1] &= 0x7fffff;\n#ifndef WOLFSSL_SP_DIV_32\n            d1 = t1[67 + i];\n            d1 <<= 23;\n            d1 += t1[67 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_3072_div_word_67(t1[67 + i], t1[67 + i - 1], dv);\n#endif\n\n            sp_3072_mul_d_67(t2, d, r1);\n            (void)sp_3072_sub_67(&t1[i], &t1[i], t2);\n            t1[67 + i] -= t2[67];\n            t1[67 + i] += t1[67 + i - 1] >> 23;\n            t1[67 + i - 1] &= 0x7fffff;\n            r1 = (((-t1[67 + i]) << 23) - t1[67 + i - 1]) / dv;\n            r1++;\n            sp_3072_mul_d_67(t2, d, r1);\n            (void)sp_3072_add_67(&t1[i], &t1[i], t2);\n            t1[67 + i] += t1[67 + i - 1] >> 23;\n            t1[67 + i - 1] &= 0x7fffff;\n        }\n        t1[67 - 1] += t1[67 - 2] >> 23;\n        t1[67 - 2] &= 0x7fffff;\n        d1 = t1[67 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_3072_mul_d_67(t2, d, r1);\n        (void)sp_3072_sub_67(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 67U);\n        for (i=0; i<65; i++) {\n            r[i+1] += r[i] >> 23;\n            r[i] &= 0x7fffff;\n        }\n        sp_3072_cond_add_67(r, r, d, 0 - ((r[66] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_3072_mod_67(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_67(a, m, NULL, r);\n}\n\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_67(sp_digit* r, const sp_digit* a, const sp_digit* e, int bits,\n    const sp_digit* m, int reduceA)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* td;\n    sp_digit* t[3];\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 67 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3U * 67U * 2U);\n\n        norm = t[0] = td;\n        t[1] = &td[67 * 2];\n        t[2] = &td[2 * 67 * 2];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_67(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_3072_mod_67(t[1], a, m);\n        }\n        else {\n            XMEMCPY(t[1], a, sizeof(sp_digit) * 67U);\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_3072_mul_67(t[1], t[1], norm);\n        err = sp_3072_mod_67(t[1], t[1], m);\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 23;\n        c = bits % 23;\n        n = e[i--] << (23 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 23;\n            }\n\n            y = (n >> 22) & 1;\n            n <<= 1;\n\n            sp_3072_mont_mul_67(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(*t[2]) * 67 * 2);\n            sp_3072_mont_sqr_67(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(*t[2]) * 67 * 2);\n        }\n\n        sp_3072_mont_reduce_67(t[0], m, mp);\n        n = sp_3072_cmp_67(t[0], m);\n        sp_3072_cond_sub_67(t[0], t[0], m, ((n < 0) ?\n                    (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(*r) * 67 * 2);\n\n    }\n\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    return err;\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[3][134];\n#else\n    sp_digit* td;\n    sp_digit* t[3];\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 67 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        t[0] = td;\n        t[1] = &td[67 * 2];\n        t[2] = &td[2 * 67 * 2];\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_67(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_3072_mod_67(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_3072_mul_67(t[1], t[1], norm);\n                err = sp_3072_mod_67(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_3072_mul_67(t[1], a, norm);\n            err = sp_3072_mod_67(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 23;\n        c = bits % 23;\n        n = e[i--] << (23 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 23;\n            }\n\n            y = (n >> 22) & 1;\n            n <<= 1;\n\n            sp_3072_mont_mul_67(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_3072_mont_sqr_67(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                           ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));\n        }\n\n        sp_3072_mont_reduce_67(t[0], m, mp);\n        n = sp_3072_cmp_67(t[0], m);\n        sp_3072_cond_sub_67(t[0], t[0], m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(t[0]));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][134];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit rt[134];\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 134, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 134;\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_67(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_3072_mod_67(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_3072_mul_67(t[1], t[1], norm);\n                err = sp_3072_mod_67(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_3072_mul_67(t[1], a, norm);\n            err = sp_3072_mod_67(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_67(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_67(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_67(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_67(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_67(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_67(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_67(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_67(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_67(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_67(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_67(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_67(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_67(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_67(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_67(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_67(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_67(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_67(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_67(t[20], t[10], m, mp);\n        sp_3072_mont_mul_67(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_67(t[22], t[11], m, mp);\n        sp_3072_mont_mul_67(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_67(t[24], t[12], m, mp);\n        sp_3072_mont_mul_67(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_67(t[26], t[13], m, mp);\n        sp_3072_mont_mul_67(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_67(t[28], t[14], m, mp);\n        sp_3072_mont_mul_67(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_67(t[30], t[15], m, mp);\n        sp_3072_mont_mul_67(t[31], t[16], t[15], m, mp);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 22) / 23) - 1;\n        c = bits % 23;\n        if (c == 0) {\n            c = 23;\n        }\n        if (i < 67) {\n            n = e[i--] << (32 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (9 - c);\n            c += 23;\n        }\n        y = (n >> 27) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        XMEMCPY(rt, t[y], sizeof(rt));\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (9 - c);\n                c += 23;\n            }\n            y = (n >> 27) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_3072_mont_sqr_67(rt, rt, m, mp);\n            sp_3072_mont_sqr_67(rt, rt, m, mp);\n            sp_3072_mont_sqr_67(rt, rt, m, mp);\n            sp_3072_mont_sqr_67(rt, rt, m, mp);\n            sp_3072_mont_sqr_67(rt, rt, m, mp);\n\n            sp_3072_mont_mul_67(rt, rt, t[y], m, mp);\n        }\n\n        sp_3072_mont_reduce_67(rt, m, mp);\n        n = sp_3072_cmp_67(rt, m);\n        sp_3072_cond_sub_67(rt, rt, m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, rt, sizeof(rt));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#endif\n}\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_134(sp_digit* r, const sp_digit* m)\n{\n    /* Set r = 2^n - 1. */\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<133; i++) {\n        r[i] = 0x7fffff;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 128; i += 8) {\n        r[i + 0] = 0x7fffff;\n        r[i + 1] = 0x7fffff;\n        r[i + 2] = 0x7fffff;\n        r[i + 3] = 0x7fffff;\n        r[i + 4] = 0x7fffff;\n        r[i + 5] = 0x7fffff;\n        r[i + 6] = 0x7fffff;\n        r[i + 7] = 0x7fffff;\n    }\n    r[128] = 0x7fffff;\n    r[129] = 0x7fffff;\n    r[130] = 0x7fffff;\n    r[131] = 0x7fffff;\n    r[132] = 0x7fffff;\n#endif\n    r[133] = 0x1fffL;\n\n    /* r = (2^n - 1) mod n */\n    (void)sp_3072_sub_134(r, r, m);\n\n    /* Add one so r = 2^n mod m */\n    r[0] += 1;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_3072_cmp_134(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=133; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    int i;\n\n    r |= (a[133] - b[133]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[132] - b[132]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[131] - b[131]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[130] - b[130]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[129] - b[129]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[128] - b[128]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    for (i = 120; i >= 0; i -= 8) {\n        r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_3072_cond_sub_134(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 134; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 128; i += 8) {\n        r[i + 0] = a[i + 0] - (b[i + 0] & m);\n        r[i + 1] = a[i + 1] - (b[i + 1] & m);\n        r[i + 2] = a[i + 2] - (b[i + 2] & m);\n        r[i + 3] = a[i + 3] - (b[i + 3] & m);\n        r[i + 4] = a[i + 4] - (b[i + 4] & m);\n        r[i + 5] = a[i + 5] - (b[i + 5] & m);\n        r[i + 6] = a[i + 6] - (b[i + 6] & m);\n        r[i + 7] = a[i + 7] - (b[i + 7] & m);\n    }\n    r[128] = a[128] - (b[128] & m);\n    r[129] = a[129] - (b[129] & m);\n    r[130] = a[130] - (b[130] & m);\n    r[131] = a[131] - (b[131] & m);\n    r[132] = a[132] - (b[132] & m);\n    r[133] = a[133] - (b[133] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_3072_mul_add_134(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 134; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0x7fffff;\n        t >>= 23;\n    }\n    r[134] += t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x7fffff);\n    for (i = 0; i < 128; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] += (sp_digit)((t[0] >> 23) + (t[1] & 0x7fffff));\n        t[2] = tb * a[i+2];\n        r[i+2] += (sp_digit)((t[1] >> 23) + (t[2] & 0x7fffff));\n        t[3] = tb * a[i+3];\n        r[i+3] += (sp_digit)((t[2] >> 23) + (t[3] & 0x7fffff));\n        t[4] = tb * a[i+4];\n        r[i+4] += (sp_digit)((t[3] >> 23) + (t[4] & 0x7fffff));\n        t[5] = tb * a[i+5];\n        r[i+5] += (sp_digit)((t[4] >> 23) + (t[5] & 0x7fffff));\n        t[6] = tb * a[i+6];\n        r[i+6] += (sp_digit)((t[5] >> 23) + (t[6] & 0x7fffff));\n        t[7] = tb * a[i+7];\n        r[i+7] += (sp_digit)((t[6] >> 23) + (t[7] & 0x7fffff));\n        t[0] = tb * a[i+8];\n        r[i+8] += (sp_digit)((t[7] >> 23) + (t[0] & 0x7fffff));\n    }\n    t[1] = tb * a[129]; r[129] += (sp_digit)((t[0] >> 23) + (t[1] & 0x7fffff));\n    t[2] = tb * a[130]; r[130] += (sp_digit)((t[1] >> 23) + (t[2] & 0x7fffff));\n    t[3] = tb * a[131]; r[131] += (sp_digit)((t[2] >> 23) + (t[3] & 0x7fffff));\n    t[4] = tb * a[132]; r[132] += (sp_digit)((t[3] >> 23) + (t[4] & 0x7fffff));\n    t[5] = tb * a[133]; r[133] += (sp_digit)((t[4] >> 23) + (t[5] & 0x7fffff));\n    r[134] +=  (sp_digit)(t[5] >> 23);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Normalize the values in each word to 23.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_3072_norm_134(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 133; i++) {\n        a[i+1] += a[i] >> 23;\n        a[i] &= 0x7fffff;\n    }\n#else\n    int i;\n    for (i = 0; i < 128; i += 8) {\n        a[i+1] += a[i+0] >> 23; a[i+0] &= 0x7fffff;\n        a[i+2] += a[i+1] >> 23; a[i+1] &= 0x7fffff;\n        a[i+3] += a[i+2] >> 23; a[i+2] &= 0x7fffff;\n        a[i+4] += a[i+3] >> 23; a[i+3] &= 0x7fffff;\n        a[i+5] += a[i+4] >> 23; a[i+4] &= 0x7fffff;\n        a[i+6] += a[i+5] >> 23; a[i+5] &= 0x7fffff;\n        a[i+7] += a[i+6] >> 23; a[i+6] &= 0x7fffff;\n        a[i+8] += a[i+7] >> 23; a[i+7] &= 0x7fffff;\n        a[i+9] += a[i+8] >> 23; a[i+8] &= 0x7fffff;\n    }\n    a[128+1] += a[128] >> 23;\n    a[128] &= 0x7fffff;\n    a[129+1] += a[129] >> 23;\n    a[129] &= 0x7fffff;\n    a[130+1] += a[130] >> 23;\n    a[130] &= 0x7fffff;\n    a[131+1] += a[131] >> 23;\n    a[131] &= 0x7fffff;\n    a[132+1] += a[132] >> 23;\n    a[132] &= 0x7fffff;\n#endif\n}\n\n/* Shift the result in the high 3072 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_3072_mont_shift_134(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    int64_t n = a[133] >> 13;\n    n += ((int64_t)a[134]) << 10;\n\n    for (i = 0; i < 133; i++) {\n        r[i] = n & 0x7fffff;\n        n >>= 23;\n        n += ((int64_t)a[135 + i]) << 10;\n    }\n    r[133] = (sp_digit)n;\n#else\n    int i;\n    int64_t n = a[133] >> 13;\n    n += ((int64_t)a[134]) << 10;\n    for (i = 0; i < 128; i += 8) {\n        r[i + 0] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 135]) << 10;\n        r[i + 1] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 136]) << 10;\n        r[i + 2] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 137]) << 10;\n        r[i + 3] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 138]) << 10;\n        r[i + 4] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 139]) << 10;\n        r[i + 5] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 140]) << 10;\n        r[i + 6] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 141]) << 10;\n        r[i + 7] = n & 0x7fffff;\n        n >>= 23; n += ((int64_t)a[i + 142]) << 10;\n    }\n    r[128] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[263]) << 10;\n    r[129] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[264]) << 10;\n    r[130] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[265]) << 10;\n    r[131] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[266]) << 10;\n    r[132] = n & 0x7fffff; n >>= 23; n += ((int64_t)a[267]) << 10;\n    r[133] = (sp_digit)n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[134], 0, sizeof(*r) * 134U);\n}\n\n/* Reduce the number back to 3072 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_3072_mont_reduce_134(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    sp_3072_norm_134(a + 134);\n\n#ifdef WOLFSSL_SP_DH\n    if (mp != 1) {\n        for (i=0; i<133; i++) {\n            mu = (a[i] * mp) & 0x7fffff;\n            sp_3072_mul_add_134(a+i, m, mu);\n            a[i+1] += a[i] >> 23;\n        }\n        mu = (a[i] * mp) & 0x1fffL;\n        sp_3072_mul_add_134(a+i, m, mu);\n        a[i+1] += a[i] >> 23;\n        a[i] &= 0x7fffff;\n    }\n    else {\n        for (i=0; i<133; i++) {\n            mu = a[i] & 0x7fffff;\n            sp_3072_mul_add_134(a+i, m, mu);\n            a[i+1] += a[i] >> 23;\n        }\n        mu = a[i] & 0x1fffL;\n        sp_3072_mul_add_134(a+i, m, mu);\n        a[i+1] += a[i] >> 23;\n        a[i] &= 0x7fffff;\n    }\n#else\n    for (i=0; i<133; i++) {\n        mu = (a[i] * mp) & 0x7fffff;\n        sp_3072_mul_add_134(a+i, m, mu);\n        a[i+1] += a[i] >> 23;\n    }\n    mu = (a[i] * mp) & 0x1fffL;\n    sp_3072_mul_add_134(a+i, m, mu);\n    a[i+1] += a[i] >> 23;\n    a[i] &= 0x7fffff;\n#endif\n\n    sp_3072_mont_shift_134(a, a);\n    sp_3072_cond_sub_134(a, a, m, 0 - (((a[133] >> 13) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_3072_norm_134(a);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_134(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_134(r, a, b);\n    sp_3072_mont_reduce_134(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_134(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_134(r, a);\n    sp_3072_mont_reduce_134(r, m, mp);\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_3072_mul_d_268(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 268; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x7fffff;\n        t >>= 23;\n    }\n    r[268] = (sp_digit)t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x7fffff;\n    for (i = 0; i < 264; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 23) + (t[4] & 0x7fffff);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 23) + (t[5] & 0x7fffff);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 23) + (t[6] & 0x7fffff);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 23) + (t[7] & 0x7fffff);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 23) + (t[0] & 0x7fffff);\n    }\n    t[1] = tb * a[265];\n    r[265] = (sp_digit)(t[0] >> 23) + (t[1] & 0x7fffff);\n    t[2] = tb * a[266];\n    r[266] = (sp_digit)(t[1] >> 23) + (t[2] & 0x7fffff);\n    t[3] = tb * a[267];\n    r[267] = (sp_digit)(t[2] >> 23) + (t[3] & 0x7fffff);\n    r[268] =  (sp_digit)(t[3] >> 23);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_3072_cond_add_134(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 134; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 128; i += 8) {\n        r[i + 0] = a[i + 0] + (b[i + 0] & m);\n        r[i + 1] = a[i + 1] + (b[i + 1] & m);\n        r[i + 2] = a[i + 2] + (b[i + 2] & m);\n        r[i + 3] = a[i + 3] + (b[i + 3] & m);\n        r[i + 4] = a[i + 4] + (b[i + 4] & m);\n        r[i + 5] = a[i + 5] + (b[i + 5] & m);\n        r[i + 6] = a[i + 6] + (b[i + 6] & m);\n        r[i + 7] = a[i + 7] + (b[i + 7] & m);\n    }\n    r[128] = a[128] + (b[128] & m);\n    r[129] = a[129] + (b[129] & m);\n    r[130] = a[130] + (b[130] & m);\n    r[131] = a[131] + (b[131] & m);\n    r[132] = a[132] + (b[132] & m);\n    r[133] = a[133] + (b[133] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_sub_134(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 134; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif\n#ifdef WOLFSSL_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_add_134(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 134; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif\nSP_NOINLINE static void sp_3072_rshift_134(sp_digit* r, sp_digit* a, byte n)\n{\n    int i;\n\n#ifdef WOLFSSL_SP_SMALL\n    for (i=0; i<133; i++) {\n        r[i] = ((a[i] >> n) | (a[i + 1] << (23 - n))) & 0x7fffff;\n    }\n#else\n    for (i=0; i<128; i += 8) {\n        r[i+0] = ((a[i+0] >> n) | (a[i+1] << (23 - n))) & 0x7fffff;\n        r[i+1] = ((a[i+1] >> n) | (a[i+2] << (23 - n))) & 0x7fffff;\n        r[i+2] = ((a[i+2] >> n) | (a[i+3] << (23 - n))) & 0x7fffff;\n        r[i+3] = ((a[i+3] >> n) | (a[i+4] << (23 - n))) & 0x7fffff;\n        r[i+4] = ((a[i+4] >> n) | (a[i+5] << (23 - n))) & 0x7fffff;\n        r[i+5] = ((a[i+5] >> n) | (a[i+6] << (23 - n))) & 0x7fffff;\n        r[i+6] = ((a[i+6] >> n) | (a[i+7] << (23 - n))) & 0x7fffff;\n        r[i+7] = ((a[i+7] >> n) | (a[i+8] << (23 - n))) & 0x7fffff;\n    }\n    r[128] = ((a[128] >> n) | (a[129] << (23 - n))) & 0x7fffff;\n    r[129] = ((a[129] >> n) | (a[130] << (23 - n))) & 0x7fffff;\n    r[130] = ((a[130] >> n) | (a[131] << (23 - n))) & 0x7fffff;\n    r[131] = ((a[131] >> n) | (a[132] << (23 - n))) & 0x7fffff;\n    r[132] = ((a[132] >> n) | (a[133] << (23 - n))) & 0x7fffff;\n#endif\n    r[133] = a[133] >> n;\n}\n\n#ifdef WOLFSSL_SP_DIV_32\nstatic WC_INLINE sp_digit sp_3072_div_word_134(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t;\n\n    /* All 23 bits from d1 and top 8 bits from d0. */\n    d = (d1 << 8) | (d0 >> 15);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 9 bits in r */\n    /* Next 8 bits from d0. */\n    r <<= 8;\n    d <<= 8;\n    d |= (d0 >> 7) & ((1 << 8) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 17 bits in r */\n    /* Remaining 7 bits from d0. */\n    r <<= 7;\n    d <<= 7;\n    d |= d0 & ((1 << 7) - 1);\n    t = d / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_32 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_3072_div_134(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_32\n    int64_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[268 + 1], t2d[134 + 1], sdd[134 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    sp_digit* sd;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 134 + 3), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    (void)m;\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 268 + 1;\n        sd = t2 + 134 + 1;\n#else\n        t1 = t1d;\n        t2 = t2d;\n        sd = sdd;\n#endif\n\n        sp_3072_mul_d_134(sd, d, 1L << 10);\n        sp_3072_mul_d_268(t1, a, 1L << 10);\n        dv = sd[133];\n        for (i=134; i>=0; i--) {\n            t1[134 + i] += t1[134 + i - 1] >> 23;\n            t1[134 + i - 1] &= 0x7fffff;\n#ifndef WOLFSSL_SP_DIV_32\n            d1 = t1[134 + i];\n            d1 <<= 23;\n            d1 += t1[134 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_3072_div_word_134(t1[134 + i], t1[134 + i - 1], dv);\n#endif\n\n            sp_3072_mul_d_134(t2, sd, r1);\n            (void)sp_3072_sub_134(&t1[i], &t1[i], t2);\n            t1[134 + i] -= t2[134];\n            t1[134 + i] += t1[134 + i - 1] >> 23;\n            t1[134 + i - 1] &= 0x7fffff;\n            r1 = (((-t1[134 + i]) << 23) - t1[134 + i - 1]) / dv;\n            r1 -= t1[134 + i];\n            sp_3072_mul_d_134(t2, sd, r1);\n            (void)sp_3072_add_134(&t1[i], &t1[i], t2);\n            t1[134 + i] += t1[134 + i - 1] >> 23;\n            t1[134 + i - 1] &= 0x7fffff;\n        }\n        t1[134 - 1] += t1[134 - 2] >> 23;\n        t1[134 - 2] &= 0x7fffff;\n        d1 = t1[134 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_3072_mul_d_134(t2, sd, r1);\n        sp_3072_sub_134(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 134U);\n        for (i=0; i<132; i++) {\n            r[i+1] += r[i] >> 23;\n            r[i] &= 0x7fffff;\n        }\n        sp_3072_cond_add_134(r, r, sd, 0 - ((r[133] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n\n        sp_3072_norm_134(r);\n        sp_3072_rshift_134(r, r, 10);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_3072_mod_134(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_134(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_134(sp_digit* r, const sp_digit* a, const sp_digit* e, int bits,\n    const sp_digit* m, int reduceA)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* td;\n    sp_digit* t[3];\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 134 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3U * 134U * 2U);\n\n        norm = t[0] = td;\n        t[1] = &td[134 * 2];\n        t[2] = &td[2 * 134 * 2];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_134(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_3072_mod_134(t[1], a, m);\n        }\n        else {\n            XMEMCPY(t[1], a, sizeof(sp_digit) * 134U);\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_3072_mul_134(t[1], t[1], norm);\n        err = sp_3072_mod_134(t[1], t[1], m);\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 23;\n        c = bits % 23;\n        n = e[i--] << (23 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 23;\n            }\n\n            y = (n >> 22) & 1;\n            n <<= 1;\n\n            sp_3072_mont_mul_134(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(*t[2]) * 134 * 2);\n            sp_3072_mont_sqr_134(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(*t[2]) * 134 * 2);\n        }\n\n        sp_3072_mont_reduce_134(t[0], m, mp);\n        n = sp_3072_cmp_134(t[0], m);\n        sp_3072_cond_sub_134(t[0], t[0], m, ((n < 0) ?\n                    (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(*r) * 134 * 2);\n\n    }\n\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    return err;\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[3][268];\n#else\n    sp_digit* td;\n    sp_digit* t[3];\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 134 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        t[0] = td;\n        t[1] = &td[134 * 2];\n        t[2] = &td[2 * 134 * 2];\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_134(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_3072_mod_134(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_3072_mul_134(t[1], t[1], norm);\n                err = sp_3072_mod_134(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_3072_mul_134(t[1], a, norm);\n            err = sp_3072_mod_134(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 23;\n        c = bits % 23;\n        n = e[i--] << (23 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 23;\n            }\n\n            y = (n >> 22) & 1;\n            n <<= 1;\n\n            sp_3072_mont_mul_134(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_3072_mont_sqr_134(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                           ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));\n        }\n\n        sp_3072_mont_reduce_134(t[0], m, mp);\n        n = sp_3072_cmp_134(t[0], m);\n        sp_3072_cond_sub_134(t[0], t[0], m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(t[0]));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][268];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit rt[268];\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 268, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 268;\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_134(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_3072_mod_134(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_3072_mul_134(t[1], t[1], norm);\n                err = sp_3072_mod_134(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_3072_mul_134(t[1], a, norm);\n            err = sp_3072_mod_134(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_134(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_134(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_134(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_134(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_134(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_134(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_134(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_134(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_134(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_134(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_134(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_134(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_134(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_134(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_134(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_134(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_134(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_134(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_134(t[20], t[10], m, mp);\n        sp_3072_mont_mul_134(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_134(t[22], t[11], m, mp);\n        sp_3072_mont_mul_134(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_134(t[24], t[12], m, mp);\n        sp_3072_mont_mul_134(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_134(t[26], t[13], m, mp);\n        sp_3072_mont_mul_134(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_134(t[28], t[14], m, mp);\n        sp_3072_mont_mul_134(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_134(t[30], t[15], m, mp);\n        sp_3072_mont_mul_134(t[31], t[16], t[15], m, mp);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 22) / 23) - 1;\n        c = bits % 23;\n        if (c == 0) {\n            c = 23;\n        }\n        if (i < 134) {\n            n = e[i--] << (32 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (9 - c);\n            c += 23;\n        }\n        y = (n >> 27) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        XMEMCPY(rt, t[y], sizeof(rt));\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (9 - c);\n                c += 23;\n            }\n            y = (n >> 27) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_3072_mont_sqr_134(rt, rt, m, mp);\n            sp_3072_mont_sqr_134(rt, rt, m, mp);\n            sp_3072_mont_sqr_134(rt, rt, m, mp);\n            sp_3072_mont_sqr_134(rt, rt, m, mp);\n            sp_3072_mont_sqr_134(rt, rt, m, mp);\n\n            sp_3072_mont_mul_134(rt, rt, t[y], m, mp);\n        }\n\n        sp_3072_mont_reduce_134(rt, m, mp);\n        n = sp_3072_cmp_134(rt, m);\n        sp_3072_cond_sub_134(rt, rt, m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, rt, sizeof(rt));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#endif\n}\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */\n       /* WOLFSSL_HAVE_SP_DH */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \\\n           !defined(RSA_LOW_MEM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_67(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<67; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n    r[64] = a[64] & m;\n    r[65] = a[65] & m;\n    r[66] = a[66] & m;\n#endif\n}\n\n#endif\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* d = NULL;\n    sp_digit* a;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit* norm;\n    sp_digit e[1] = {0};\n    sp_digit mp;\n    int i;\n    int err = MP_OKAY;\n\n    if (*outLen < 384U) {\n        err = MP_TO_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(em) > 23) {\n            err = MP_READ_E;\n        }\n        if (inLen > 384U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 134 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 134 * 2;\n        m = r + 134 * 2;\n        norm = r;\n\n        sp_3072_from_bin(a, 134, in, inLen);\n#if DIGIT_BIT >= 23\n        e[0] = (sp_digit)em->dp[0];\n#else\n        e[0] = (sp_digit)em->dp[0];\n        if (em->used > 1) {\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n        }\n#endif\n        if (e[0] == 0) {\n            err = MP_EXPTMOD_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(m, 134, mm);\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_134(norm, m);\n    }\n    if (err == MP_OKAY) {\n        sp_3072_mul_134(a, a, norm);\n        err = sp_3072_mod_134(a, a, m);\n    }\n    if (err == MP_OKAY) {\n        for (i=22; i>=0; i--) {\n            if ((e[0] >> i) != 0) {\n                break;\n            }\n        }\n\n        XMEMCPY(r, a, sizeof(sp_digit) * 134 * 2);\n        for (i--; i>=0; i--) {\n            sp_3072_mont_sqr_134(r, r, m, mp);\n\n            if (((e[0] >> i) & 1) == 1) {\n                sp_3072_mont_mul_134(r, r, a, m, mp);\n            }\n        }\n        sp_3072_mont_reduce_134(r, m, mp);\n        mp = sp_3072_cmp_134(r, m);\n        sp_3072_cond_sub_134(r, r, m, ((mp < 0) ?\n                    (sp_digit)1 : (sp_digit)0)- 1);\n\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[268], md[134], rd[268];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1] = {0};\n    int err = MP_OKAY;\n\n    if (*outLen < 384U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(em) > 23) {\n            err = MP_READ_E;\n        }\n        if (inLen > 384U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 134 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 134 * 2;\n        m = r + 134 * 2;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(a, 134, in, inLen);\n#if DIGIT_BIT >= 23\n        e[0] = (sp_digit)em->dp[0];\n#else\n        e[0] = (sp_digit)em->dp[0];\n        if (em->used > 1) {\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n        }\n#endif\n        if (e[0] == 0) {\n            err = MP_EXPTMOD_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(m, 134, mm);\n\n        if (e[0] == 0x3) {\n            sp_3072_sqr_134(r, a);\n            err = sp_3072_mod_134(r, r, m);\n            if (err == MP_OKAY) {\n                sp_3072_mul_134(r, a, r);\n                err = sp_3072_mod_134(r, r, m);\n            }\n        }\n        else {\n            sp_digit* norm = r;\n            int i;\n            sp_digit mp;\n\n            sp_3072_mont_setup(m, &mp);\n            sp_3072_mont_norm_134(norm, m);\n\n            sp_3072_mul_134(a, a, norm);\n            err = sp_3072_mod_134(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=22; i>=0; i--) {\n                    if ((e[0] >> i) != 0) {\n                        break;\n                    }\n                }\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 268U);\n                for (i--; i>=0; i--) {\n                    sp_3072_mont_sqr_134(r, r, m, mp);\n\n                    if (((e[0] >> i) & 1) == 1) {\n                        sp_3072_mont_mul_134(r, r, a, m, mp);\n                    }\n                }\n                sp_3072_mont_reduce_134(r, m, mp);\n                mp = sp_3072_cmp_134(r, m);\n                sp_3072_cond_sub_134(r, r, m, ((mp < 0) ?\n                           (sp_digit)1 : (sp_digit)0) - 1);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n#endif\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* a;\n    sp_digit* d = NULL;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n\n    (void)pm;\n    (void)qm;\n    (void)dpm;\n    (void)dqm;\n    (void)qim;\n\n    if (*outLen < 384U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(dm) > 3072) {\n           err = MP_READ_E;\n        }\n        if (inLen > 384) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 134 * 4, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        a = d + 134;\n        m = a + 134;\n        r = a;\n\n        sp_3072_from_bin(a, 134, in, inLen);\n        sp_3072_from_mp(d, 134, dm);\n        sp_3072_from_mp(m, 134, mm);\n        err = sp_3072_mod_exp_134(r, a, d, 3072, m, 0);\n    }\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n    if (d != NULL) {\n        XMEMSET(d, 0, sizeof(sp_digit) * 134);\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n    sp_digit a[268], d[134], m[134];\n    sp_digit* r = a;\n    int err = MP_OKAY;\n\n    (void)pm;\n    (void)qm;\n    (void)dpm;\n    (void)dqm;\n    (void)qim;\n\n    if (*outLen < 384U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(dm) > 3072) {\n            err = MP_READ_E;\n        }\n        if (inLen > 384U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(a, 134, in, inLen);\n        sp_3072_from_mp(d, 134, dm);\n        sp_3072_from_mp(m, 134, mm);\n        err = sp_3072_mod_exp_134(r, a, d, 3072, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n    XMEMSET(d, 0, sizeof(sp_digit) * 134);\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */\n#else\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* t = NULL;\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 384U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (inLen > 384) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 67 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL) {\n            err = MEMORY_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 134 * 2;\n        q = p + 67;\n        qi = dq = dp = q + 67;\n        tmpa = qi + 67;\n        tmpb = tmpa + 134;\n\n        tmp = t;\n        r = tmp + 134;\n\n        sp_3072_from_bin(a, 134, in, inLen);\n        sp_3072_from_mp(p, 67, pm);\n        sp_3072_from_mp(q, 67, qm);\n        sp_3072_from_mp(dp, 67, dpm);\n        err = sp_3072_mod_exp_67(tmpa, a, dp, 1536, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(dq, 67, dqm);\n        err = sp_3072_mod_exp_67(tmpb, a, dq, 1536, q, 1);\n    }\n    if (err == MP_OKAY) {\n        (void)sp_3072_sub_67(tmpa, tmpa, tmpb);\n        sp_3072_mask_67(tmp, p, 0 - ((sp_int_digit)tmpa[66] >> 31));\n        (void)sp_3072_add_67(tmpa, tmpa, tmp);\n\n        sp_3072_from_mp(qi, 67, qim);\n        sp_3072_mul_67(tmpa, tmpa, qi);\n        err = sp_3072_mod_67(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mul_67(tmpa, q, tmpa);\n        (void)sp_3072_add_134(r, tmpb, tmpa);\n        sp_3072_norm_134(r);\n\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 67 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n    sp_digit a[134 * 2];\n    sp_digit p[67], q[67], dp[67], dq[67], qi[67];\n    sp_digit tmp[134], tmpa[134], tmpb[134];\n    sp_digit* r = a;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 384U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (inLen > 384U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(a, 134, in, inLen);\n        sp_3072_from_mp(p, 67, pm);\n        sp_3072_from_mp(q, 67, qm);\n        sp_3072_from_mp(dp, 67, dpm);\n        sp_3072_from_mp(dq, 67, dqm);\n        sp_3072_from_mp(qi, 67, qim);\n\n        err = sp_3072_mod_exp_67(tmpa, a, dp, 1536, p, 1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_3072_mod_exp_67(tmpb, a, dq, 1536, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        (void)sp_3072_sub_67(tmpa, tmpa, tmpb);\n        sp_3072_mask_67(tmp, p, 0 - ((sp_int_digit)tmpa[66] >> 31));\n        (void)sp_3072_add_67(tmpa, tmpa, tmp);\n        sp_3072_mul_67(tmpa, tmpa, qi);\n        err = sp_3072_mod_67(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mul_67(tmpa, tmpa, q);\n        (void)sp_3072_add_134(r, tmpb, tmpa);\n        sp_3072_norm_134(r);\n\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n    XMEMSET(tmpa, 0, sizeof(tmpa));\n    XMEMSET(tmpb, 0, sizeof(tmpb));\n    XMEMSET(p, 0, sizeof(p));\n    XMEMSET(q, 0, sizeof(q));\n    XMEMSET(dp, 0, sizeof(dp));\n    XMEMSET(dq, 0, sizeof(dq));\n    XMEMSET(qi, 0, sizeof(qi));\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */\n#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */\n}\n\n#endif /* !WOLFSSL_RSA_PUBLIC_ONLY */\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_3072_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 23\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 134);\n        r->used = 134;\n        mp_clamp(r);\n#elif DIGIT_BIT < 23\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 134; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 23) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 23 - s;\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 134; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 23 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 23 - s;\n            }\n            else {\n                s += 23;\n            }\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 134 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 134 * 2;\n        m = e + 134;\n        r = b;\n\n        sp_3072_from_mp(b, 134, base);\n        sp_3072_from_mp(e, 134, exp);\n        sp_3072_from_mp(m, 134, mod);\n\n        err = sp_3072_mod_exp_134(r, b, e, mp_count_bits(exp), m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_3072_to_mp(r, res);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 134U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[268], ed[134], md[134];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 3072) {\n            err = MP_READ_E;\n        }\n    }\n    \n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 134 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 134 * 2;\n        m = e + 134;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 134, base);\n        sp_3072_from_mp(e, 134, exp);\n        sp_3072_from_mp(m, 134, mod);\n\n        err = sp_3072_mod_exp_134(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_3072_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 134U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_3072\nSP_NOINLINE static void sp_3072_lshift_134(sp_digit* r, sp_digit* a, byte n)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    r[134] = a[133] >> (23 - n);\n    for (i=133; i>0; i--) {\n        r[i] = ((a[i] << n) | (a[i-1] >> (23 - n))) & 0x7fffff;\n    }\n#else\n    sp_int_digit s, t;\n\n    s = (sp_int_digit)a[133];\n    r[134] = s >> (23U - n);\n    s = (sp_int_digit)(a[133]); t = (sp_int_digit)(a[132]);\n    r[133] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[132]); t = (sp_int_digit)(a[131]);\n    r[132] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[131]); t = (sp_int_digit)(a[130]);\n    r[131] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[130]); t = (sp_int_digit)(a[129]);\n    r[130] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[129]); t = (sp_int_digit)(a[128]);\n    r[129] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[128]); t = (sp_int_digit)(a[127]);\n    r[128] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[127]); t = (sp_int_digit)(a[126]);\n    r[127] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[126]); t = (sp_int_digit)(a[125]);\n    r[126] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[125]); t = (sp_int_digit)(a[124]);\n    r[125] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[124]); t = (sp_int_digit)(a[123]);\n    r[124] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[123]); t = (sp_int_digit)(a[122]);\n    r[123] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[122]); t = (sp_int_digit)(a[121]);\n    r[122] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[121]); t = (sp_int_digit)(a[120]);\n    r[121] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[120]); t = (sp_int_digit)(a[119]);\n    r[120] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[119]); t = (sp_int_digit)(a[118]);\n    r[119] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[118]); t = (sp_int_digit)(a[117]);\n    r[118] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[117]); t = (sp_int_digit)(a[116]);\n    r[117] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[116]); t = (sp_int_digit)(a[115]);\n    r[116] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[115]); t = (sp_int_digit)(a[114]);\n    r[115] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[114]); t = (sp_int_digit)(a[113]);\n    r[114] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[113]); t = (sp_int_digit)(a[112]);\n    r[113] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[112]); t = (sp_int_digit)(a[111]);\n    r[112] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[111]); t = (sp_int_digit)(a[110]);\n    r[111] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[110]); t = (sp_int_digit)(a[109]);\n    r[110] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[109]); t = (sp_int_digit)(a[108]);\n    r[109] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[108]); t = (sp_int_digit)(a[107]);\n    r[108] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[107]); t = (sp_int_digit)(a[106]);\n    r[107] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[106]); t = (sp_int_digit)(a[105]);\n    r[106] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[105]); t = (sp_int_digit)(a[104]);\n    r[105] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[104]); t = (sp_int_digit)(a[103]);\n    r[104] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[103]); t = (sp_int_digit)(a[102]);\n    r[103] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[102]); t = (sp_int_digit)(a[101]);\n    r[102] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[101]); t = (sp_int_digit)(a[100]);\n    r[101] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[100]); t = (sp_int_digit)(a[99]);\n    r[100] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[99]); t = (sp_int_digit)(a[98]);\n    r[99] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[98]); t = (sp_int_digit)(a[97]);\n    r[98] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[97]); t = (sp_int_digit)(a[96]);\n    r[97] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[96]); t = (sp_int_digit)(a[95]);\n    r[96] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[95]); t = (sp_int_digit)(a[94]);\n    r[95] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[94]); t = (sp_int_digit)(a[93]);\n    r[94] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[93]); t = (sp_int_digit)(a[92]);\n    r[93] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[92]); t = (sp_int_digit)(a[91]);\n    r[92] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[91]); t = (sp_int_digit)(a[90]);\n    r[91] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[90]); t = (sp_int_digit)(a[89]);\n    r[90] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[89]); t = (sp_int_digit)(a[88]);\n    r[89] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[88]); t = (sp_int_digit)(a[87]);\n    r[88] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[87]); t = (sp_int_digit)(a[86]);\n    r[87] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[86]); t = (sp_int_digit)(a[85]);\n    r[86] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[85]); t = (sp_int_digit)(a[84]);\n    r[85] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[84]); t = (sp_int_digit)(a[83]);\n    r[84] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[83]); t = (sp_int_digit)(a[82]);\n    r[83] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[82]); t = (sp_int_digit)(a[81]);\n    r[82] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[81]); t = (sp_int_digit)(a[80]);\n    r[81] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[80]); t = (sp_int_digit)(a[79]);\n    r[80] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[79]); t = (sp_int_digit)(a[78]);\n    r[79] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[78]); t = (sp_int_digit)(a[77]);\n    r[78] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[77]); t = (sp_int_digit)(a[76]);\n    r[77] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[76]); t = (sp_int_digit)(a[75]);\n    r[76] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[75]); t = (sp_int_digit)(a[74]);\n    r[75] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[74]); t = (sp_int_digit)(a[73]);\n    r[74] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[73]); t = (sp_int_digit)(a[72]);\n    r[73] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[72]); t = (sp_int_digit)(a[71]);\n    r[72] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[71]); t = (sp_int_digit)(a[70]);\n    r[71] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[70]); t = (sp_int_digit)(a[69]);\n    r[70] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[69]); t = (sp_int_digit)(a[68]);\n    r[69] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[68]); t = (sp_int_digit)(a[67]);\n    r[68] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[67]); t = (sp_int_digit)(a[66]);\n    r[67] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[66]); t = (sp_int_digit)(a[65]);\n    r[66] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[65]); t = (sp_int_digit)(a[64]);\n    r[65] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[64]); t = (sp_int_digit)(a[63]);\n    r[64] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[63]); t = (sp_int_digit)(a[62]);\n    r[63] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[62]); t = (sp_int_digit)(a[61]);\n    r[62] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[61]); t = (sp_int_digit)(a[60]);\n    r[61] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[60]); t = (sp_int_digit)(a[59]);\n    r[60] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[59]); t = (sp_int_digit)(a[58]);\n    r[59] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[58]); t = (sp_int_digit)(a[57]);\n    r[58] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[57]); t = (sp_int_digit)(a[56]);\n    r[57] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[56]); t = (sp_int_digit)(a[55]);\n    r[56] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[55]); t = (sp_int_digit)(a[54]);\n    r[55] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[54]); t = (sp_int_digit)(a[53]);\n    r[54] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[53]); t = (sp_int_digit)(a[52]);\n    r[53] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[52]); t = (sp_int_digit)(a[51]);\n    r[52] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[51]); t = (sp_int_digit)(a[50]);\n    r[51] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[50]); t = (sp_int_digit)(a[49]);\n    r[50] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[49]); t = (sp_int_digit)(a[48]);\n    r[49] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[48]); t = (sp_int_digit)(a[47]);\n    r[48] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[47]); t = (sp_int_digit)(a[46]);\n    r[47] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[46]); t = (sp_int_digit)(a[45]);\n    r[46] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[45]); t = (sp_int_digit)(a[44]);\n    r[45] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[44]); t = (sp_int_digit)(a[43]);\n    r[44] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[43]); t = (sp_int_digit)(a[42]);\n    r[43] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[42]); t = (sp_int_digit)(a[41]);\n    r[42] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[41]); t = (sp_int_digit)(a[40]);\n    r[41] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[40]); t = (sp_int_digit)(a[39]);\n    r[40] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[39]); t = (sp_int_digit)(a[38]);\n    r[39] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[38]); t = (sp_int_digit)(a[37]);\n    r[38] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[37]); t = (sp_int_digit)(a[36]);\n    r[37] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[36]); t = (sp_int_digit)(a[35]);\n    r[36] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[35]); t = (sp_int_digit)(a[34]);\n    r[35] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[34]); t = (sp_int_digit)(a[33]);\n    r[34] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[33]); t = (sp_int_digit)(a[32]);\n    r[33] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[32]); t = (sp_int_digit)(a[31]);\n    r[32] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[31]); t = (sp_int_digit)(a[30]);\n    r[31] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[30]); t = (sp_int_digit)(a[29]);\n    r[30] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[29]); t = (sp_int_digit)(a[28]);\n    r[29] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[28]); t = (sp_int_digit)(a[27]);\n    r[28] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[27]); t = (sp_int_digit)(a[26]);\n    r[27] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[26]); t = (sp_int_digit)(a[25]);\n    r[26] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[25]); t = (sp_int_digit)(a[24]);\n    r[25] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[24]); t = (sp_int_digit)(a[23]);\n    r[24] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[23]); t = (sp_int_digit)(a[22]);\n    r[23] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[22]); t = (sp_int_digit)(a[21]);\n    r[22] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[21]); t = (sp_int_digit)(a[20]);\n    r[21] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[20]); t = (sp_int_digit)(a[19]);\n    r[20] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[19]); t = (sp_int_digit)(a[18]);\n    r[19] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[18]); t = (sp_int_digit)(a[17]);\n    r[18] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[17]); t = (sp_int_digit)(a[16]);\n    r[17] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[16]); t = (sp_int_digit)(a[15]);\n    r[16] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[15]); t = (sp_int_digit)(a[14]);\n    r[15] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[14]); t = (sp_int_digit)(a[13]);\n    r[14] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);\n    r[13] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);\n    r[12] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);\n    r[11] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);\n    r[10] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);\n    r[9] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);\n    r[8] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);\n    r[7] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);\n    r[6] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);\n    r[5] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);\n    r[4] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);\n    r[3] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);\n    r[2] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n    s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);\n    r[1] = ((s << n) | (t >> (23U - n))) & 0x7fffff;\n#endif\n    r[0] = (a[0] << n) & 0x7fffff;\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_2_134(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[268];\n    sp_digit td[135];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 403, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 268;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        XMEMSET(td, 0, sizeof(td));\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_134(norm, m);\n\n        bits = ((bits + 3) / 4) * 4;\n        i = ((bits + 22) / 23) - 1;\n        c = bits % 23;\n        if (c == 0) {\n            c = 23;\n        }\n        if (i < 134) {\n            n = e[i--] << (32 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 4) {\n            n |= e[i--] << (9 - c);\n            c += 23;\n        }\n        y = (n >> 28) & 0xf;\n        n <<= 4;\n        c -= 4;\n        sp_3072_lshift_134(r, norm, y);\n        for (; i>=0 || c>=4; ) {\n            if (c < 4) {\n                n |= e[i--] << (9 - c);\n                c += 23;\n            }\n            y = (n >> 28) & 0xf;\n            n <<= 4;\n            c -= 4;\n\n            sp_3072_mont_sqr_134(r, r, m, mp);\n            sp_3072_mont_sqr_134(r, r, m, mp);\n            sp_3072_mont_sqr_134(r, r, m, mp);\n            sp_3072_mont_sqr_134(r, r, m, mp);\n\n            sp_3072_lshift_134(r, r, y);\n            sp_3072_mul_d_134(tmp, norm, (r[134] << 10) + (r[133] >> 13));\n            r[134] = 0;\n            r[133] &= 0x1fffL;\n            (void)sp_3072_add_134(r, r, tmp);\n            sp_3072_norm_134(r);\n            o = sp_3072_cmp_134(r, m);\n            sp_3072_cond_sub_134(r, r, m, ((o < 0) ?\n                                          (sp_digit)1 : (sp_digit)0) - 1);\n        }\n\n        sp_3072_mont_reduce_134(r, m, mp);\n        n = sp_3072_cmp_134(r, m);\n        sp_3072_cond_sub_134(r, r, m, ((n < 0) ?\n                                                (sp_digit)1 : (sp_digit)0) - 1);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n#endif /* HAVE_FFDHE_3072 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 384 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    word32 i;\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 384) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 134 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 134 * 2;\n        m = e + 134;\n        r = b;\n\n        sp_3072_from_mp(b, 134, base);\n        sp_3072_from_bin(e, 134, exp, expLen);\n        sp_3072_from_mp(m, 134, mod);\n\n    #ifdef HAVE_FFDHE_3072\n        if (base->used == 1 && base->dp[0] == 2 &&\n                ((m[133] << 3) | (m[132] >> 20)) == 0xffffL) {\n            err = sp_3072_mod_exp_2_134(r, e, expLen * 8, m);\n        }\n        else\n    #endif\n            err = sp_3072_mod_exp_134(r, b, e, expLen * 8, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n        for (i=0; i<384 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 134U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[268], ed[134], md[134];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    word32 i;\n    int err = MP_OKAY;\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 384U) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 134 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 134 * 2;\n        m = e + 134;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 134, base);\n        sp_3072_from_bin(e, 134, exp, expLen);\n        sp_3072_from_mp(m, 134, mod);\n\n    #ifdef HAVE_FFDHE_3072\n        if (base->used == 1 && base->dp[0] == 2U &&\n                ((m[133] << 3) | (m[132] >> 20)) == 0xffffL) {\n            err = sp_3072_mod_exp_2_134(r, e, expLen * 8U, m);\n        }\n        else {\n    #endif\n            err = sp_3072_mod_exp_134(r, b, e, expLen * 8U, m, 0);\n    #ifdef HAVE_FFDHE_3072\n        }\n    #endif\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n        for (i=0; i<384U && out[i] == 0U; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 134U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1536) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 67 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 67 * 2;\n        m = e + 67;\n        r = b;\n\n        sp_3072_from_mp(b, 67, base);\n        sp_3072_from_mp(e, 67, exp);\n        sp_3072_from_mp(m, 67, mod);\n\n        err = sp_3072_mod_exp_67(r, b, e, mp_count_bits(exp), m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 67, 0, sizeof(*r) * 67U);\n        err = sp_3072_to_mp(r, res);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 67U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[134], ed[67], md[67];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1536) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1536) {\n            err = MP_READ_E;\n        }\n    }\n    \n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 67 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 67 * 2;\n        m = e + 67;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 67, base);\n        sp_3072_from_mp(e, 67, exp);\n        sp_3072_from_mp(m, 67, mod);\n\n        err = sp_3072_mod_exp_67(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 67, 0, sizeof(*r) * 67U);\n        err = sp_3072_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 67U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_3072 */\n\n#ifdef WOLFSSL_SP_4096\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 13U) {\n            r[j] &= 0x1fffff;\n            s = 21U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 21\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 21\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0x1fffff;\n        s = 21U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 21U) <= (word32)DIGIT_BIT) {\n            s += 21U;\n            r[j] &= 0x1fffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 21) {\n            r[j] &= 0x1fffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 21 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 512\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_4096_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    for (i=0; i<195; i++) {\n        r[i+1] += r[i] >> 21;\n        r[i] &= 0x1fffff;\n    }\n    j = 4096 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<196 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 21) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 21);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_49(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j;\n    int64_t t[98];\n\n    XMEMSET(t, 0, sizeof(t));\n    for (i=0; i<49; i++) {\n        for (j=0; j<49; j++) {\n            t[i+j] += ((int64_t)a[i]) * b[j];\n        }\n    }\n    for (i=0; i<97; i++) {\n        r[i] = t[i] & 0x1fffff;\n        t[i+1] += t[i] >> 21;\n    }\n    r[97] = (sp_digit)t[97];\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_49(sp_digit* r, const sp_digit* a)\n{\n    int i, j;\n    int64_t t[98];\n\n    XMEMSET(t, 0, sizeof(t));\n    for (i=0; i<49; i++) {\n        for (j=0; j<i; j++) {\n            t[i+j] += (((int64_t)a[i]) * a[j]) * 2;\n        }\n        t[i+i] += ((int64_t)a[i]) * a[i];\n    }\n    for (i=0; i<97; i++) {\n        r[i] = t[i] & 0x1fffff;\n        t[i+1] += t[i] >> 21;\n    }\n    r[97] = (sp_digit)t[97];\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_49(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 48; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[48] = a[48] + b[48];\n\n    return 0;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_98(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 96; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[96] = a[96] + b[96];\n    r[97] = a[97] + b[97];\n\n    return 0;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_sub_98(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 96; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[96] = a[96] - b[96];\n    r[97] = a[97] - b[97];\n\n    return 0;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_98(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[98];\n    sp_digit* a1 = z1;\n    sp_digit b1[49];\n    sp_digit* z2 = r + 98;\n    (void)sp_4096_add_49(a1, a, &a[49]);\n    (void)sp_4096_add_49(b1, b, &b[49]);\n    sp_4096_mul_49(z2, &a[49], &b[49]);\n    sp_4096_mul_49(z0, a, b);\n    sp_4096_mul_49(z1, a1, b1);\n    (void)sp_4096_sub_98(z1, z1, z2);\n    (void)sp_4096_sub_98(z1, z1, z0);\n    (void)sp_4096_add_98(r + 49, r + 49, z1);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_98(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[98];\n    sp_digit* a1 = z1;\n    sp_digit* z2 = r + 98;\n    (void)sp_4096_add_49(a1, a, &a[49]);\n    sp_4096_sqr_49(z2, &a[49]);\n    sp_4096_sqr_49(z0, a);\n    sp_4096_sqr_49(z1, a1);\n    (void)sp_4096_sub_98(z1, z1, z2);\n    (void)sp_4096_sub_98(z1, z1, z0);\n    (void)sp_4096_add_98(r + 49, r + 49, z1);\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_196(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 192; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[192] = a[192] + b[192];\n    r[193] = a[193] + b[193];\n    r[194] = a[194] + b[194];\n    r[195] = a[195] + b[195];\n\n    return 0;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_sub_196(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 192; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[192] = a[192] - b[192];\n    r[193] = a[193] - b[193];\n    r[194] = a[194] - b[194];\n    r[195] = a[195] - b[195];\n\n    return 0;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_196(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[196];\n    sp_digit* a1 = z1;\n    sp_digit b1[98];\n    sp_digit* z2 = r + 196;\n    (void)sp_4096_add_98(a1, a, &a[98]);\n    (void)sp_4096_add_98(b1, b, &b[98]);\n    sp_4096_mul_98(z2, &a[98], &b[98]);\n    sp_4096_mul_98(z0, a, b);\n    sp_4096_mul_98(z1, a1, b1);\n    (void)sp_4096_sub_196(z1, z1, z2);\n    (void)sp_4096_sub_196(z1, z1, z0);\n    (void)sp_4096_add_196(r + 98, r + 98, z1);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_196(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[196];\n    sp_digit* a1 = z1;\n    sp_digit* z2 = r + 196;\n    (void)sp_4096_add_98(a1, a, &a[98]);\n    sp_4096_sqr_98(z2, &a[98]);\n    sp_4096_sqr_98(z0, a);\n    sp_4096_sqr_98(z1, a1);\n    (void)sp_4096_sub_196(z1, z1, z2);\n    (void)sp_4096_sub_196(z1, z1, z0);\n    (void)sp_4096_add_196(r + 98, r + 98, z1);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_196(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 196; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_sub_196(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 196; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_196(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[195]) * b[195];\n    r[391] = (sp_digit)(c >> 21);\n    c = (c & 0x1fffff) << 21;\n    for (k = 389; k >= 0; k--) {\n        for (i = 195; i >= 0; i--) {\n            j = k - i;\n            if (j >= 196) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 42;\n        r[k + 1] = (c >> 21) & 0x1fffff;\n        c = (c & 0x1fffff) << 21;\n    }\n    r[0] = (sp_digit)(c >> 21);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_196(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[195]) * a[195];\n    r[391] = (sp_digit)(c >> 21);\n    c = (c & 0x1fffff) << 21;\n    for (k = 389; k >= 0; k--) {\n        for (i = 195; i >= 0; i--) {\n            j = k - i;\n            if (j >= 196 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int64_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 42;\n        r[k + 1] = (c >> 21) & 0x1fffff;\n        c = (c & 0x1fffff) << 21;\n    }\n    r[0] = (sp_digit)(c >> 21);\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_98(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 98; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_sub_98(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 98; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_98(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[97]) * b[97];\n    r[195] = (sp_digit)(c >> 21);\n    c = (c & 0x1fffff) << 21;\n    for (k = 193; k >= 0; k--) {\n        for (i = 97; i >= 0; i--) {\n            j = k - i;\n            if (j >= 98) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 42;\n        r[k + 1] = (c >> 21) & 0x1fffff;\n        c = (c & 0x1fffff) << 21;\n    }\n    r[0] = (sp_digit)(c >> 21);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_98(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[97]) * a[97];\n    r[195] = (sp_digit)(c >> 21);\n    c = (c & 0x1fffff) << 21;\n    for (k = 193; k >= 0; k--) {\n        for (i = 97; i >= 0; i--) {\n            j = k - i;\n            if (j >= 98 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int64_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 42;\n        r[k + 1] = (c >> 21) & 0x1fffff;\n        c = (c & 0x1fffff) << 21;\n    }\n    r[0] = (sp_digit)(c >> 21);\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n    x &= 0x1fffff;\n\n    /* rho = -1/m mod b */\n    *rho = (1L << 21) - x;\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_4096_mul_d_196(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 196; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x1fffff;\n        t >>= 21;\n    }\n    r[196] = (sp_digit)t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x1fffff;\n    for (i = 0; i < 192; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 21) + (t[1] & 0x1fffff);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 21) + (t[2] & 0x1fffff);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 21) + (t[3] & 0x1fffff);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 21) + (t[4] & 0x1fffff);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 21) + (t[5] & 0x1fffff);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 21) + (t[6] & 0x1fffff);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 21) + (t[7] & 0x1fffff);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 21) + (t[0] & 0x1fffff);\n    }\n    t[1] = tb * a[193];\n    r[193] = (sp_digit)(t[0] >> 21) + (t[1] & 0x1fffff);\n    t[2] = tb * a[194];\n    r[194] = (sp_digit)(t[1] >> 21) + (t[2] & 0x1fffff);\n    t[3] = tb * a[195];\n    r[195] = (sp_digit)(t[2] >> 21) + (t[3] & 0x1fffff);\n    r[196] =  (sp_digit)(t[3] >> 21);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 4096 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_4096_mont_norm_98(sp_digit* r, const sp_digit* m)\n{\n    /* Set r = 2^n - 1. */\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<97; i++) {\n        r[i] = 0x1fffff;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 96; i += 8) {\n        r[i + 0] = 0x1fffff;\n        r[i + 1] = 0x1fffff;\n        r[i + 2] = 0x1fffff;\n        r[i + 3] = 0x1fffff;\n        r[i + 4] = 0x1fffff;\n        r[i + 5] = 0x1fffff;\n        r[i + 6] = 0x1fffff;\n        r[i + 7] = 0x1fffff;\n    }\n    r[96] = 0x1fffff;\n#endif\n    r[97] = 0x7ffL;\n\n    /* r = (2^n - 1) mod n */\n    (void)sp_4096_sub_98(r, r, m);\n\n    /* Add one so r = 2^n mod m */\n    r[0] += 1;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_4096_cmp_98(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=97; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    int i;\n\n    r |= (a[97] - b[97]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[96] - b[96]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    for (i = 88; i >= 0; i -= 8) {\n        r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_4096_cond_sub_98(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 98; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 96; i += 8) {\n        r[i + 0] = a[i + 0] - (b[i + 0] & m);\n        r[i + 1] = a[i + 1] - (b[i + 1] & m);\n        r[i + 2] = a[i + 2] - (b[i + 2] & m);\n        r[i + 3] = a[i + 3] - (b[i + 3] & m);\n        r[i + 4] = a[i + 4] - (b[i + 4] & m);\n        r[i + 5] = a[i + 5] - (b[i + 5] & m);\n        r[i + 6] = a[i + 6] - (b[i + 6] & m);\n        r[i + 7] = a[i + 7] - (b[i + 7] & m);\n    }\n    r[96] = a[96] - (b[96] & m);\n    r[97] = a[97] - (b[97] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_4096_mul_add_98(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 98; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0x1fffff;\n        t >>= 21;\n    }\n    r[98] += t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1fffff);\n    for (i = 0; i < 96; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] += (sp_digit)((t[0] >> 21) + (t[1] & 0x1fffff));\n        t[2] = tb * a[i+2];\n        r[i+2] += (sp_digit)((t[1] >> 21) + (t[2] & 0x1fffff));\n        t[3] = tb * a[i+3];\n        r[i+3] += (sp_digit)((t[2] >> 21) + (t[3] & 0x1fffff));\n        t[4] = tb * a[i+4];\n        r[i+4] += (sp_digit)((t[3] >> 21) + (t[4] & 0x1fffff));\n        t[5] = tb * a[i+5];\n        r[i+5] += (sp_digit)((t[4] >> 21) + (t[5] & 0x1fffff));\n        t[6] = tb * a[i+6];\n        r[i+6] += (sp_digit)((t[5] >> 21) + (t[6] & 0x1fffff));\n        t[7] = tb * a[i+7];\n        r[i+7] += (sp_digit)((t[6] >> 21) + (t[7] & 0x1fffff));\n        t[0] = tb * a[i+8];\n        r[i+8] += (sp_digit)((t[7] >> 21) + (t[0] & 0x1fffff));\n    }\n    t[1] = tb * a[97]; r[97] += (sp_digit)((t[0] >> 21) + (t[1] & 0x1fffff));\n    r[98] +=  (sp_digit)(t[1] >> 21);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Normalize the values in each word to 21.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_4096_norm_98(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 97; i++) {\n        a[i+1] += a[i] >> 21;\n        a[i] &= 0x1fffff;\n    }\n#else\n    int i;\n    for (i = 0; i < 96; i += 8) {\n        a[i+1] += a[i+0] >> 21; a[i+0] &= 0x1fffff;\n        a[i+2] += a[i+1] >> 21; a[i+1] &= 0x1fffff;\n        a[i+3] += a[i+2] >> 21; a[i+2] &= 0x1fffff;\n        a[i+4] += a[i+3] >> 21; a[i+3] &= 0x1fffff;\n        a[i+5] += a[i+4] >> 21; a[i+4] &= 0x1fffff;\n        a[i+6] += a[i+5] >> 21; a[i+5] &= 0x1fffff;\n        a[i+7] += a[i+6] >> 21; a[i+6] &= 0x1fffff;\n        a[i+8] += a[i+7] >> 21; a[i+7] &= 0x1fffff;\n        a[i+9] += a[i+8] >> 21; a[i+8] &= 0x1fffff;\n    }\n    a[96+1] += a[96] >> 21;\n    a[96] &= 0x1fffff;\n#endif\n}\n\n/* Shift the result in the high 2048 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_4096_mont_shift_98(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    int64_t n = a[97] >> 11;\n    n += ((int64_t)a[98]) << 10;\n\n    for (i = 0; i < 97; i++) {\n        r[i] = n & 0x1fffff;\n        n >>= 21;\n        n += ((int64_t)a[99 + i]) << 10;\n    }\n    r[97] = (sp_digit)n;\n#else\n    int i;\n    int64_t n = a[97] >> 11;\n    n += ((int64_t)a[98]) << 10;\n    for (i = 0; i < 96; i += 8) {\n        r[i + 0] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 99]) << 10;\n        r[i + 1] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 100]) << 10;\n        r[i + 2] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 101]) << 10;\n        r[i + 3] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 102]) << 10;\n        r[i + 4] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 103]) << 10;\n        r[i + 5] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 104]) << 10;\n        r[i + 6] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 105]) << 10;\n        r[i + 7] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 106]) << 10;\n    }\n    r[96] = n & 0x1fffff; n >>= 21; n += ((int64_t)a[195]) << 10;\n    r[97] = (sp_digit)n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[98], 0, sizeof(*r) * 98U);\n}\n\n/* Reduce the number back to 4096 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_4096_mont_reduce_98(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    sp_4096_norm_98(a + 98);\n\n    for (i=0; i<97; i++) {\n        mu = (a[i] * mp) & 0x1fffff;\n        sp_4096_mul_add_98(a+i, m, mu);\n        a[i+1] += a[i] >> 21;\n    }\n    mu = (a[i] * mp) & 0x7ffL;\n    sp_4096_mul_add_98(a+i, m, mu);\n    a[i+1] += a[i] >> 21;\n    a[i] &= 0x1fffff;\n\n    sp_4096_mont_shift_98(a, a);\n    sp_4096_cond_sub_98(a, a, m, 0 - (((a[97] >> 11) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_4096_norm_98(a);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_mul_98(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_4096_mul_98(r, a, b);\n    sp_4096_mont_reduce_98(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_sqr_98(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_4096_sqr_98(r, a);\n    sp_4096_mont_reduce_98(r, m, mp);\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_4096_mul_d_98(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 98; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x1fffff;\n        t >>= 21;\n    }\n    r[98] = (sp_digit)t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x1fffff;\n    for (i = 0; i < 96; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 21) + (t[1] & 0x1fffff);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 21) + (t[2] & 0x1fffff);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 21) + (t[3] & 0x1fffff);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 21) + (t[4] & 0x1fffff);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 21) + (t[5] & 0x1fffff);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 21) + (t[6] & 0x1fffff);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 21) + (t[7] & 0x1fffff);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 21) + (t[0] & 0x1fffff);\n    }\n    t[1] = tb * a[97];\n    r[97] = (sp_digit)(t[0] >> 21) + (t[1] & 0x1fffff);\n    r[98] =  (sp_digit)(t[1] >> 21);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_4096_cond_add_98(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 98; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 96; i += 8) {\n        r[i + 0] = a[i + 0] + (b[i + 0] & m);\n        r[i + 1] = a[i + 1] + (b[i + 1] & m);\n        r[i + 2] = a[i + 2] + (b[i + 2] & m);\n        r[i + 3] = a[i + 3] + (b[i + 3] & m);\n        r[i + 4] = a[i + 4] + (b[i + 4] & m);\n        r[i + 5] = a[i + 5] + (b[i + 5] & m);\n        r[i + 6] = a[i + 6] + (b[i + 6] & m);\n        r[i + 7] = a[i + 7] + (b[i + 7] & m);\n    }\n    r[96] = a[96] + (b[96] & m);\n    r[97] = a[97] + (b[97] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_sub_98(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 98; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif\n#ifdef WOLFSSL_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_98(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 98; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif\nSP_NOINLINE static void sp_4096_rshift_98(sp_digit* r, sp_digit* a, byte n)\n{\n    int i;\n\n#ifdef WOLFSSL_SP_SMALL\n    for (i=0; i<97; i++) {\n        r[i] = ((a[i] >> n) | (a[i + 1] << (21 - n))) & 0x1fffff;\n    }\n#else\n    for (i=0; i<96; i += 8) {\n        r[i+0] = ((a[i+0] >> n) | (a[i+1] << (21 - n))) & 0x1fffff;\n        r[i+1] = ((a[i+1] >> n) | (a[i+2] << (21 - n))) & 0x1fffff;\n        r[i+2] = ((a[i+2] >> n) | (a[i+3] << (21 - n))) & 0x1fffff;\n        r[i+3] = ((a[i+3] >> n) | (a[i+4] << (21 - n))) & 0x1fffff;\n        r[i+4] = ((a[i+4] >> n) | (a[i+5] << (21 - n))) & 0x1fffff;\n        r[i+5] = ((a[i+5] >> n) | (a[i+6] << (21 - n))) & 0x1fffff;\n        r[i+6] = ((a[i+6] >> n) | (a[i+7] << (21 - n))) & 0x1fffff;\n        r[i+7] = ((a[i+7] >> n) | (a[i+8] << (21 - n))) & 0x1fffff;\n    }\n    r[96] = ((a[96] >> n) | (a[97] << (21 - n))) & 0x1fffff;\n#endif\n    r[97] = a[97] >> n;\n}\n\n#ifdef WOLFSSL_SP_DIV_32\nstatic WC_INLINE sp_digit sp_4096_div_word_98(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t;\n\n    /* All 21 bits from d1 and top 10 bits from d0. */\n    d = (d1 << 10) | (d0 >> 11);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 11 bits in r */\n    /* Next 10 bits from d0. */\n    r <<= 10;\n    d <<= 10;\n    d |= (d0 >> 1) & ((1 << 10) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 21 bits in r */\n    /* Remaining 1 bits from d0. */\n    r <<= 1;\n    d <<= 1;\n    d |= d0 & ((1 << 1) - 1);\n    t = d / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_32 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_4096_div_98(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_32\n    int64_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[196 + 1], t2d[98 + 1], sdd[98 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    sp_digit* sd;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 98 + 3), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    (void)m;\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 196 + 1;\n        sd = t2 + 98 + 1;\n#else\n        t1 = t1d;\n        t2 = t2d;\n        sd = sdd;\n#endif\n\n        sp_4096_mul_d_98(sd, d, 1L << 10);\n        sp_4096_mul_d_196(t1, a, 1L << 10);\n        dv = sd[97];\n        for (i=98; i>=0; i--) {\n            t1[98 + i] += t1[98 + i - 1] >> 21;\n            t1[98 + i - 1] &= 0x1fffff;\n#ifndef WOLFSSL_SP_DIV_32\n            d1 = t1[98 + i];\n            d1 <<= 21;\n            d1 += t1[98 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_4096_div_word_98(t1[98 + i], t1[98 + i - 1], dv);\n#endif\n\n            sp_4096_mul_d_98(t2, sd, r1);\n            (void)sp_4096_sub_98(&t1[i], &t1[i], t2);\n            t1[98 + i] -= t2[98];\n            t1[98 + i] += t1[98 + i - 1] >> 21;\n            t1[98 + i - 1] &= 0x1fffff;\n            r1 = (((-t1[98 + i]) << 21) - t1[98 + i - 1]) / dv;\n            r1 -= t1[98 + i];\n            sp_4096_mul_d_98(t2, sd, r1);\n            (void)sp_4096_add_98(&t1[i], &t1[i], t2);\n            t1[98 + i] += t1[98 + i - 1] >> 21;\n            t1[98 + i - 1] &= 0x1fffff;\n        }\n        t1[98 - 1] += t1[98 - 2] >> 21;\n        t1[98 - 2] &= 0x1fffff;\n        d1 = t1[98 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_4096_mul_d_98(t2, sd, r1);\n        sp_4096_sub_98(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 98U);\n        for (i=0; i<96; i++) {\n            r[i+1] += r[i] >> 21;\n            r[i] &= 0x1fffff;\n        }\n        sp_4096_cond_add_98(r, r, sd, 0 - ((r[97] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n\n        sp_4096_norm_98(r);\n        sp_4096_rshift_98(r, r, 10);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_4096_mod_98(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_98(a, m, NULL, r);\n}\n\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_98(sp_digit* r, const sp_digit* a, const sp_digit* e, int bits,\n    const sp_digit* m, int reduceA)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* td;\n    sp_digit* t[3];\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 98 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3U * 98U * 2U);\n\n        norm = t[0] = td;\n        t[1] = &td[98 * 2];\n        t[2] = &td[2 * 98 * 2];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_98(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_4096_mod_98(t[1], a, m);\n        }\n        else {\n            XMEMCPY(t[1], a, sizeof(sp_digit) * 98U);\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_4096_mul_98(t[1], t[1], norm);\n        err = sp_4096_mod_98(t[1], t[1], m);\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 21;\n        c = bits % 21;\n        n = e[i--] << (21 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 21;\n            }\n\n            y = (n >> 20) & 1;\n            n <<= 1;\n\n            sp_4096_mont_mul_98(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(*t[2]) * 98 * 2);\n            sp_4096_mont_sqr_98(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(*t[2]) * 98 * 2);\n        }\n\n        sp_4096_mont_reduce_98(t[0], m, mp);\n        n = sp_4096_cmp_98(t[0], m);\n        sp_4096_cond_sub_98(t[0], t[0], m, ((n < 0) ?\n                    (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(*r) * 98 * 2);\n\n    }\n\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    return err;\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[3][196];\n#else\n    sp_digit* td;\n    sp_digit* t[3];\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 98 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        t[0] = td;\n        t[1] = &td[98 * 2];\n        t[2] = &td[2 * 98 * 2];\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_98(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_4096_mod_98(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_4096_mul_98(t[1], t[1], norm);\n                err = sp_4096_mod_98(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_4096_mul_98(t[1], a, norm);\n            err = sp_4096_mod_98(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 21;\n        c = bits % 21;\n        n = e[i--] << (21 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 21;\n            }\n\n            y = (n >> 20) & 1;\n            n <<= 1;\n\n            sp_4096_mont_mul_98(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_4096_mont_sqr_98(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                           ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));\n        }\n\n        sp_4096_mont_reduce_98(t[0], m, mp);\n        n = sp_4096_cmp_98(t[0], m);\n        sp_4096_cond_sub_98(t[0], t[0], m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(t[0]));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][196];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit rt[196];\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 196, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 196;\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_98(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_4096_mod_98(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_4096_mul_98(t[1], t[1], norm);\n                err = sp_4096_mod_98(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_4096_mul_98(t[1], a, norm);\n            err = sp_4096_mod_98(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_98(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_98(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_98(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_98(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_98(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_98(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_98(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_98(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_98(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_98(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_98(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_98(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_98(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_98(t[15], t[ 8], t[ 7], m, mp);\n        sp_4096_mont_sqr_98(t[16], t[ 8], m, mp);\n        sp_4096_mont_mul_98(t[17], t[ 9], t[ 8], m, mp);\n        sp_4096_mont_sqr_98(t[18], t[ 9], m, mp);\n        sp_4096_mont_mul_98(t[19], t[10], t[ 9], m, mp);\n        sp_4096_mont_sqr_98(t[20], t[10], m, mp);\n        sp_4096_mont_mul_98(t[21], t[11], t[10], m, mp);\n        sp_4096_mont_sqr_98(t[22], t[11], m, mp);\n        sp_4096_mont_mul_98(t[23], t[12], t[11], m, mp);\n        sp_4096_mont_sqr_98(t[24], t[12], m, mp);\n        sp_4096_mont_mul_98(t[25], t[13], t[12], m, mp);\n        sp_4096_mont_sqr_98(t[26], t[13], m, mp);\n        sp_4096_mont_mul_98(t[27], t[14], t[13], m, mp);\n        sp_4096_mont_sqr_98(t[28], t[14], m, mp);\n        sp_4096_mont_mul_98(t[29], t[15], t[14], m, mp);\n        sp_4096_mont_sqr_98(t[30], t[15], m, mp);\n        sp_4096_mont_mul_98(t[31], t[16], t[15], m, mp);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 20) / 21) - 1;\n        c = bits % 21;\n        if (c == 0) {\n            c = 21;\n        }\n        if (i < 98) {\n            n = e[i--] << (32 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (11 - c);\n            c += 21;\n        }\n        y = (n >> 27) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        XMEMCPY(rt, t[y], sizeof(rt));\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (11 - c);\n                c += 21;\n            }\n            y = (n >> 27) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_4096_mont_sqr_98(rt, rt, m, mp);\n            sp_4096_mont_sqr_98(rt, rt, m, mp);\n            sp_4096_mont_sqr_98(rt, rt, m, mp);\n            sp_4096_mont_sqr_98(rt, rt, m, mp);\n            sp_4096_mont_sqr_98(rt, rt, m, mp);\n\n            sp_4096_mont_mul_98(rt, rt, t[y], m, mp);\n        }\n\n        sp_4096_mont_reduce_98(rt, m, mp);\n        n = sp_4096_cmp_98(rt, m);\n        sp_4096_cond_sub_98(rt, rt, m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, rt, sizeof(rt));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#endif\n}\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 4096 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_4096_mont_norm_196(sp_digit* r, const sp_digit* m)\n{\n    /* Set r = 2^n - 1. */\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<195; i++) {\n        r[i] = 0x1fffff;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 192; i += 8) {\n        r[i + 0] = 0x1fffff;\n        r[i + 1] = 0x1fffff;\n        r[i + 2] = 0x1fffff;\n        r[i + 3] = 0x1fffff;\n        r[i + 4] = 0x1fffff;\n        r[i + 5] = 0x1fffff;\n        r[i + 6] = 0x1fffff;\n        r[i + 7] = 0x1fffff;\n    }\n    r[192] = 0x1fffff;\n    r[193] = 0x1fffff;\n    r[194] = 0x1fffff;\n#endif\n    r[195] = 0x1L;\n\n    /* r = (2^n - 1) mod n */\n    (void)sp_4096_sub_196(r, r, m);\n\n    /* Add one so r = 2^n mod m */\n    r[0] += 1;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_4096_cmp_196(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=195; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    int i;\n\n    r |= (a[195] - b[195]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[194] - b[194]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[193] - b[193]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[192] - b[192]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    for (i = 184; i >= 0; i -= 8) {\n        r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_4096_cond_sub_196(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 196; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 192; i += 8) {\n        r[i + 0] = a[i + 0] - (b[i + 0] & m);\n        r[i + 1] = a[i + 1] - (b[i + 1] & m);\n        r[i + 2] = a[i + 2] - (b[i + 2] & m);\n        r[i + 3] = a[i + 3] - (b[i + 3] & m);\n        r[i + 4] = a[i + 4] - (b[i + 4] & m);\n        r[i + 5] = a[i + 5] - (b[i + 5] & m);\n        r[i + 6] = a[i + 6] - (b[i + 6] & m);\n        r[i + 7] = a[i + 7] - (b[i + 7] & m);\n    }\n    r[192] = a[192] - (b[192] & m);\n    r[193] = a[193] - (b[193] & m);\n    r[194] = a[194] - (b[194] & m);\n    r[195] = a[195] - (b[195] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_4096_mul_add_196(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 196; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0x1fffff;\n        t >>= 21;\n    }\n    r[196] += t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1fffff);\n    for (i = 0; i < 192; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] += (sp_digit)((t[0] >> 21) + (t[1] & 0x1fffff));\n        t[2] = tb * a[i+2];\n        r[i+2] += (sp_digit)((t[1] >> 21) + (t[2] & 0x1fffff));\n        t[3] = tb * a[i+3];\n        r[i+3] += (sp_digit)((t[2] >> 21) + (t[3] & 0x1fffff));\n        t[4] = tb * a[i+4];\n        r[i+4] += (sp_digit)((t[3] >> 21) + (t[4] & 0x1fffff));\n        t[5] = tb * a[i+5];\n        r[i+5] += (sp_digit)((t[4] >> 21) + (t[5] & 0x1fffff));\n        t[6] = tb * a[i+6];\n        r[i+6] += (sp_digit)((t[5] >> 21) + (t[6] & 0x1fffff));\n        t[7] = tb * a[i+7];\n        r[i+7] += (sp_digit)((t[6] >> 21) + (t[7] & 0x1fffff));\n        t[0] = tb * a[i+8];\n        r[i+8] += (sp_digit)((t[7] >> 21) + (t[0] & 0x1fffff));\n    }\n    t[1] = tb * a[193]; r[193] += (sp_digit)((t[0] >> 21) + (t[1] & 0x1fffff));\n    t[2] = tb * a[194]; r[194] += (sp_digit)((t[1] >> 21) + (t[2] & 0x1fffff));\n    t[3] = tb * a[195]; r[195] += (sp_digit)((t[2] >> 21) + (t[3] & 0x1fffff));\n    r[196] +=  (sp_digit)(t[3] >> 21);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Normalize the values in each word to 21.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_4096_norm_196(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 195; i++) {\n        a[i+1] += a[i] >> 21;\n        a[i] &= 0x1fffff;\n    }\n#else\n    int i;\n    for (i = 0; i < 192; i += 8) {\n        a[i+1] += a[i+0] >> 21; a[i+0] &= 0x1fffff;\n        a[i+2] += a[i+1] >> 21; a[i+1] &= 0x1fffff;\n        a[i+3] += a[i+2] >> 21; a[i+2] &= 0x1fffff;\n        a[i+4] += a[i+3] >> 21; a[i+3] &= 0x1fffff;\n        a[i+5] += a[i+4] >> 21; a[i+4] &= 0x1fffff;\n        a[i+6] += a[i+5] >> 21; a[i+5] &= 0x1fffff;\n        a[i+7] += a[i+6] >> 21; a[i+6] &= 0x1fffff;\n        a[i+8] += a[i+7] >> 21; a[i+7] &= 0x1fffff;\n        a[i+9] += a[i+8] >> 21; a[i+8] &= 0x1fffff;\n    }\n    a[192+1] += a[192] >> 21;\n    a[192] &= 0x1fffff;\n    a[193+1] += a[193] >> 21;\n    a[193] &= 0x1fffff;\n    a[194+1] += a[194] >> 21;\n    a[194] &= 0x1fffff;\n#endif\n}\n\n/* Shift the result in the high 4096 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_4096_mont_shift_196(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    int64_t n = a[195] >> 1;\n    n += ((int64_t)a[196]) << 20;\n\n    for (i = 0; i < 195; i++) {\n        r[i] = n & 0x1fffff;\n        n >>= 21;\n        n += ((int64_t)a[197 + i]) << 20;\n    }\n    r[195] = (sp_digit)n;\n#else\n    int i;\n    int64_t n = a[195] >> 1;\n    n += ((int64_t)a[196]) << 20;\n    for (i = 0; i < 192; i += 8) {\n        r[i + 0] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 197]) << 20;\n        r[i + 1] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 198]) << 20;\n        r[i + 2] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 199]) << 20;\n        r[i + 3] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 200]) << 20;\n        r[i + 4] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 201]) << 20;\n        r[i + 5] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 202]) << 20;\n        r[i + 6] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 203]) << 20;\n        r[i + 7] = n & 0x1fffff;\n        n >>= 21; n += ((int64_t)a[i + 204]) << 20;\n    }\n    r[192] = n & 0x1fffff; n >>= 21; n += ((int64_t)a[389]) << 20;\n    r[193] = n & 0x1fffff; n >>= 21; n += ((int64_t)a[390]) << 20;\n    r[194] = n & 0x1fffff; n >>= 21; n += ((int64_t)a[391]) << 20;\n    r[195] = (sp_digit)n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[196], 0, sizeof(*r) * 196U);\n}\n\n/* Reduce the number back to 4096 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_4096_mont_reduce_196(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    sp_4096_norm_196(a + 196);\n\n#ifdef WOLFSSL_SP_DH\n    if (mp != 1) {\n        for (i=0; i<195; i++) {\n            mu = (a[i] * mp) & 0x1fffff;\n            sp_4096_mul_add_196(a+i, m, mu);\n            a[i+1] += a[i] >> 21;\n        }\n        mu = (a[i] * mp) & 0x1L;\n        sp_4096_mul_add_196(a+i, m, mu);\n        a[i+1] += a[i] >> 21;\n        a[i] &= 0x1fffff;\n    }\n    else {\n        for (i=0; i<195; i++) {\n            mu = a[i] & 0x1fffff;\n            sp_4096_mul_add_196(a+i, m, mu);\n            a[i+1] += a[i] >> 21;\n        }\n        mu = a[i] & 0x1L;\n        sp_4096_mul_add_196(a+i, m, mu);\n        a[i+1] += a[i] >> 21;\n        a[i] &= 0x1fffff;\n    }\n#else\n    for (i=0; i<195; i++) {\n        mu = (a[i] * mp) & 0x1fffff;\n        sp_4096_mul_add_196(a+i, m, mu);\n        a[i+1] += a[i] >> 21;\n    }\n    mu = (a[i] * mp) & 0x1L;\n    sp_4096_mul_add_196(a+i, m, mu);\n    a[i+1] += a[i] >> 21;\n    a[i] &= 0x1fffff;\n#endif\n\n    sp_4096_mont_shift_196(a, a);\n    sp_4096_cond_sub_196(a, a, m, 0 - (((a[195] >> 1) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_4096_norm_196(a);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_mul_196(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_4096_mul_196(r, a, b);\n    sp_4096_mont_reduce_196(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_sqr_196(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_4096_sqr_196(r, a);\n    sp_4096_mont_reduce_196(r, m, mp);\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_4096_mul_d_392(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 392; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x1fffff;\n        t >>= 21;\n    }\n    r[392] = (sp_digit)t;\n#else\n    int64_t tb = b;\n    int64_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x1fffff;\n    for (i = 0; i < 392; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 21) + (t[1] & 0x1fffff);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 21) + (t[2] & 0x1fffff);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 21) + (t[3] & 0x1fffff);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 21) + (t[4] & 0x1fffff);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 21) + (t[5] & 0x1fffff);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 21) + (t[6] & 0x1fffff);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 21) + (t[7] & 0x1fffff);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 21) + (t[0] & 0x1fffff);\n    }\n    r[392] =  (sp_digit)(t[7] >> 21);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_4096_cond_add_196(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 196; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 192; i += 8) {\n        r[i + 0] = a[i + 0] + (b[i + 0] & m);\n        r[i + 1] = a[i + 1] + (b[i + 1] & m);\n        r[i + 2] = a[i + 2] + (b[i + 2] & m);\n        r[i + 3] = a[i + 3] + (b[i + 3] & m);\n        r[i + 4] = a[i + 4] + (b[i + 4] & m);\n        r[i + 5] = a[i + 5] + (b[i + 5] & m);\n        r[i + 6] = a[i + 6] + (b[i + 6] & m);\n        r[i + 7] = a[i + 7] + (b[i + 7] & m);\n    }\n    r[192] = a[192] + (b[192] & m);\n    r[193] = a[193] + (b[193] & m);\n    r[194] = a[194] + (b[194] & m);\n    r[195] = a[195] + (b[195] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_sub_196(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 196; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif\n#ifdef WOLFSSL_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_196(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 196; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif\nSP_NOINLINE static void sp_4096_rshift_196(sp_digit* r, sp_digit* a, byte n)\n{\n    int i;\n\n#ifdef WOLFSSL_SP_SMALL\n    for (i=0; i<195; i++) {\n        r[i] = ((a[i] >> n) | (a[i + 1] << (21 - n))) & 0x1fffff;\n    }\n#else\n    for (i=0; i<192; i += 8) {\n        r[i+0] = ((a[i+0] >> n) | (a[i+1] << (21 - n))) & 0x1fffff;\n        r[i+1] = ((a[i+1] >> n) | (a[i+2] << (21 - n))) & 0x1fffff;\n        r[i+2] = ((a[i+2] >> n) | (a[i+3] << (21 - n))) & 0x1fffff;\n        r[i+3] = ((a[i+3] >> n) | (a[i+4] << (21 - n))) & 0x1fffff;\n        r[i+4] = ((a[i+4] >> n) | (a[i+5] << (21 - n))) & 0x1fffff;\n        r[i+5] = ((a[i+5] >> n) | (a[i+6] << (21 - n))) & 0x1fffff;\n        r[i+6] = ((a[i+6] >> n) | (a[i+7] << (21 - n))) & 0x1fffff;\n        r[i+7] = ((a[i+7] >> n) | (a[i+8] << (21 - n))) & 0x1fffff;\n    }\n    r[192] = ((a[192] >> n) | (a[193] << (21 - n))) & 0x1fffff;\n    r[193] = ((a[193] >> n) | (a[194] << (21 - n))) & 0x1fffff;\n    r[194] = ((a[194] >> n) | (a[195] << (21 - n))) & 0x1fffff;\n#endif\n    r[195] = a[195] >> n;\n}\n\n#ifdef WOLFSSL_SP_DIV_32\nstatic WC_INLINE sp_digit sp_4096_div_word_196(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t;\n\n    /* All 21 bits from d1 and top 10 bits from d0. */\n    d = (d1 << 10) | (d0 >> 11);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 11 bits in r */\n    /* Next 10 bits from d0. */\n    r <<= 10;\n    d <<= 10;\n    d |= (d0 >> 1) & ((1 << 10) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 21 bits in r */\n    /* Remaining 1 bits from d0. */\n    r <<= 1;\n    d <<= 1;\n    d |= d0 & ((1 << 1) - 1);\n    t = d / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_32 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_4096_div_196(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_32\n    int64_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[392 + 1], t2d[196 + 1], sdd[196 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    sp_digit* sd;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 196 + 3), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    (void)m;\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 392 + 1;\n        sd = t2 + 196 + 1;\n#else\n        t1 = t1d;\n        t2 = t2d;\n        sd = sdd;\n#endif\n\n        sp_4096_mul_d_196(sd, d, 1L << 20);\n        sp_4096_mul_d_392(t1, a, 1L << 20);\n        dv = sd[195];\n        for (i=196; i>=0; i--) {\n            t1[196 + i] += t1[196 + i - 1] >> 21;\n            t1[196 + i - 1] &= 0x1fffff;\n#ifndef WOLFSSL_SP_DIV_32\n            d1 = t1[196 + i];\n            d1 <<= 21;\n            d1 += t1[196 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_4096_div_word_196(t1[196 + i], t1[196 + i - 1], dv);\n#endif\n\n            sp_4096_mul_d_196(t2, sd, r1);\n            (void)sp_4096_sub_196(&t1[i], &t1[i], t2);\n            t1[196 + i] -= t2[196];\n            t1[196 + i] += t1[196 + i - 1] >> 21;\n            t1[196 + i - 1] &= 0x1fffff;\n            r1 = (((-t1[196 + i]) << 21) - t1[196 + i - 1]) / dv;\n            r1 -= t1[196 + i];\n            sp_4096_mul_d_196(t2, sd, r1);\n            (void)sp_4096_add_196(&t1[i], &t1[i], t2);\n            t1[196 + i] += t1[196 + i - 1] >> 21;\n            t1[196 + i - 1] &= 0x1fffff;\n        }\n        t1[196 - 1] += t1[196 - 2] >> 21;\n        t1[196 - 2] &= 0x1fffff;\n        d1 = t1[196 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_4096_mul_d_196(t2, sd, r1);\n        sp_4096_sub_196(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 196U);\n        for (i=0; i<194; i++) {\n            r[i+1] += r[i] >> 21;\n            r[i] &= 0x1fffff;\n        }\n        sp_4096_cond_add_196(r, r, sd, 0 - ((r[195] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n\n        sp_4096_norm_196(r);\n        sp_4096_rshift_196(r, r, 20);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_4096_mod_196(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_196(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_196(sp_digit* r, const sp_digit* a, const sp_digit* e, int bits,\n    const sp_digit* m, int reduceA)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* td;\n    sp_digit* t[3];\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 196 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3U * 196U * 2U);\n\n        norm = t[0] = td;\n        t[1] = &td[196 * 2];\n        t[2] = &td[2 * 196 * 2];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_196(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_4096_mod_196(t[1], a, m);\n        }\n        else {\n            XMEMCPY(t[1], a, sizeof(sp_digit) * 196U);\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_4096_mul_196(t[1], t[1], norm);\n        err = sp_4096_mod_196(t[1], t[1], m);\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 21;\n        c = bits % 21;\n        n = e[i--] << (21 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 21;\n            }\n\n            y = (n >> 20) & 1;\n            n <<= 1;\n\n            sp_4096_mont_mul_196(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(*t[2]) * 196 * 2);\n            sp_4096_mont_sqr_196(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(*t[2]) * 196 * 2);\n        }\n\n        sp_4096_mont_reduce_196(t[0], m, mp);\n        n = sp_4096_cmp_196(t[0], m);\n        sp_4096_cond_sub_196(t[0], t[0], m, ((n < 0) ?\n                    (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(*r) * 196 * 2);\n\n    }\n\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    return err;\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[3][392];\n#else\n    sp_digit* td;\n    sp_digit* t[3];\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 196 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        t[0] = td;\n        t[1] = &td[196 * 2];\n        t[2] = &td[2 * 196 * 2];\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_196(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_4096_mod_196(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_4096_mul_196(t[1], t[1], norm);\n                err = sp_4096_mod_196(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_4096_mul_196(t[1], a, norm);\n            err = sp_4096_mod_196(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 21;\n        c = bits % 21;\n        n = e[i--] << (21 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 21;\n            }\n\n            y = (n >> 20) & 1;\n            n <<= 1;\n\n            sp_4096_mont_mul_196(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_4096_mont_sqr_196(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                           ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));\n        }\n\n        sp_4096_mont_reduce_196(t[0], m, mp);\n        n = sp_4096_cmp_196(t[0], m);\n        sp_4096_cond_sub_196(t[0], t[0], m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(t[0]));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][392];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit rt[392];\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 392, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 392;\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_196(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_4096_mod_196(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_4096_mul_196(t[1], t[1], norm);\n                err = sp_4096_mod_196(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_4096_mul_196(t[1], a, norm);\n            err = sp_4096_mod_196(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_196(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_196(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_196(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_196(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_196(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_196(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_196(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_196(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_196(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_196(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_196(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_196(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_196(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_196(t[15], t[ 8], t[ 7], m, mp);\n        sp_4096_mont_sqr_196(t[16], t[ 8], m, mp);\n        sp_4096_mont_mul_196(t[17], t[ 9], t[ 8], m, mp);\n        sp_4096_mont_sqr_196(t[18], t[ 9], m, mp);\n        sp_4096_mont_mul_196(t[19], t[10], t[ 9], m, mp);\n        sp_4096_mont_sqr_196(t[20], t[10], m, mp);\n        sp_4096_mont_mul_196(t[21], t[11], t[10], m, mp);\n        sp_4096_mont_sqr_196(t[22], t[11], m, mp);\n        sp_4096_mont_mul_196(t[23], t[12], t[11], m, mp);\n        sp_4096_mont_sqr_196(t[24], t[12], m, mp);\n        sp_4096_mont_mul_196(t[25], t[13], t[12], m, mp);\n        sp_4096_mont_sqr_196(t[26], t[13], m, mp);\n        sp_4096_mont_mul_196(t[27], t[14], t[13], m, mp);\n        sp_4096_mont_sqr_196(t[28], t[14], m, mp);\n        sp_4096_mont_mul_196(t[29], t[15], t[14], m, mp);\n        sp_4096_mont_sqr_196(t[30], t[15], m, mp);\n        sp_4096_mont_mul_196(t[31], t[16], t[15], m, mp);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 20) / 21) - 1;\n        c = bits % 21;\n        if (c == 0) {\n            c = 21;\n        }\n        if (i < 196) {\n            n = e[i--] << (32 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (11 - c);\n            c += 21;\n        }\n        y = (n >> 27) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        XMEMCPY(rt, t[y], sizeof(rt));\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (11 - c);\n                c += 21;\n            }\n            y = (n >> 27) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_4096_mont_sqr_196(rt, rt, m, mp);\n            sp_4096_mont_sqr_196(rt, rt, m, mp);\n            sp_4096_mont_sqr_196(rt, rt, m, mp);\n            sp_4096_mont_sqr_196(rt, rt, m, mp);\n            sp_4096_mont_sqr_196(rt, rt, m, mp);\n\n            sp_4096_mont_mul_196(rt, rt, t[y], m, mp);\n        }\n\n        sp_4096_mont_reduce_196(rt, m, mp);\n        n = sp_4096_cmp_196(rt, m);\n        sp_4096_cond_sub_196(rt, rt, m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, rt, sizeof(rt));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#endif\n}\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */\n       /* WOLFSSL_HAVE_SP_DH */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \\\n           !defined(RSA_LOW_MEM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_4096_mask_98(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<98; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 96; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n    r[96] = a[96] & m;\n    r[97] = a[97] & m;\n#endif\n}\n\n#endif\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* d = NULL;\n    sp_digit* a;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit* norm;\n    sp_digit e[1] = {0};\n    sp_digit mp;\n    int i;\n    int err = MP_OKAY;\n\n    if (*outLen < 512U) {\n        err = MP_TO_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(em) > 21) {\n            err = MP_READ_E;\n        }\n        if (inLen > 512U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 196 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 196 * 2;\n        m = r + 196 * 2;\n        norm = r;\n\n        sp_4096_from_bin(a, 196, in, inLen);\n#if DIGIT_BIT >= 21\n        e[0] = (sp_digit)em->dp[0];\n#else\n        e[0] = (sp_digit)em->dp[0];\n        if (em->used > 1) {\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n        }\n#endif\n        if (e[0] == 0) {\n            err = MP_EXPTMOD_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(m, 196, mm);\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_196(norm, m);\n    }\n    if (err == MP_OKAY) {\n        sp_4096_mul_196(a, a, norm);\n        err = sp_4096_mod_196(a, a, m);\n    }\n    if (err == MP_OKAY) {\n        for (i=20; i>=0; i--) {\n            if ((e[0] >> i) != 0) {\n                break;\n            }\n        }\n\n        XMEMCPY(r, a, sizeof(sp_digit) * 196 * 2);\n        for (i--; i>=0; i--) {\n            sp_4096_mont_sqr_196(r, r, m, mp);\n\n            if (((e[0] >> i) & 1) == 1) {\n                sp_4096_mont_mul_196(r, r, a, m, mp);\n            }\n        }\n        sp_4096_mont_reduce_196(r, m, mp);\n        mp = sp_4096_cmp_196(r, m);\n        sp_4096_cond_sub_196(r, r, m, ((mp < 0) ?\n                    (sp_digit)1 : (sp_digit)0)- 1);\n\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[392], md[196], rd[392];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1] = {0};\n    int err = MP_OKAY;\n\n    if (*outLen < 512U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(em) > 21) {\n            err = MP_READ_E;\n        }\n        if (inLen > 512U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 196 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 196 * 2;\n        m = r + 196 * 2;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(a, 196, in, inLen);\n#if DIGIT_BIT >= 21\n        e[0] = (sp_digit)em->dp[0];\n#else\n        e[0] = (sp_digit)em->dp[0];\n        if (em->used > 1) {\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n        }\n#endif\n        if (e[0] == 0) {\n            err = MP_EXPTMOD_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(m, 196, mm);\n\n        if (e[0] == 0x3) {\n            sp_4096_sqr_196(r, a);\n            err = sp_4096_mod_196(r, r, m);\n            if (err == MP_OKAY) {\n                sp_4096_mul_196(r, a, r);\n                err = sp_4096_mod_196(r, r, m);\n            }\n        }\n        else {\n            sp_digit* norm = r;\n            int i;\n            sp_digit mp;\n\n            sp_4096_mont_setup(m, &mp);\n            sp_4096_mont_norm_196(norm, m);\n\n            sp_4096_mul_196(a, a, norm);\n            err = sp_4096_mod_196(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=20; i>=0; i--) {\n                    if ((e[0] >> i) != 0) {\n                        break;\n                    }\n                }\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 392U);\n                for (i--; i>=0; i--) {\n                    sp_4096_mont_sqr_196(r, r, m, mp);\n\n                    if (((e[0] >> i) & 1) == 1) {\n                        sp_4096_mont_mul_196(r, r, a, m, mp);\n                    }\n                }\n                sp_4096_mont_reduce_196(r, m, mp);\n                mp = sp_4096_cmp_196(r, m);\n                sp_4096_cond_sub_196(r, r, m, ((mp < 0) ?\n                           (sp_digit)1 : (sp_digit)0) - 1);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n#endif\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* a;\n    sp_digit* d = NULL;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n\n    (void)pm;\n    (void)qm;\n    (void)dpm;\n    (void)dqm;\n    (void)qim;\n\n    if (*outLen < 512U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(dm) > 4096) {\n           err = MP_READ_E;\n        }\n        if (inLen > 512) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 196 * 4, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        a = d + 196;\n        m = a + 196;\n        r = a;\n\n        sp_4096_from_bin(a, 196, in, inLen);\n        sp_4096_from_mp(d, 196, dm);\n        sp_4096_from_mp(m, 196, mm);\n        err = sp_4096_mod_exp_196(r, a, d, 4096, m, 0);\n    }\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n    if (d != NULL) {\n        XMEMSET(d, 0, sizeof(sp_digit) * 196);\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n    sp_digit a[392], d[196], m[196];\n    sp_digit* r = a;\n    int err = MP_OKAY;\n\n    (void)pm;\n    (void)qm;\n    (void)dpm;\n    (void)dqm;\n    (void)qim;\n\n    if (*outLen < 512U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(dm) > 4096) {\n            err = MP_READ_E;\n        }\n        if (inLen > 512U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(a, 196, in, inLen);\n        sp_4096_from_mp(d, 196, dm);\n        sp_4096_from_mp(m, 196, mm);\n        err = sp_4096_mod_exp_196(r, a, d, 4096, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n    XMEMSET(d, 0, sizeof(sp_digit) * 196);\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */\n#else\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* t = NULL;\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 512U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (inLen > 512) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 98 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL) {\n            err = MEMORY_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 196 * 2;\n        q = p + 98;\n        qi = dq = dp = q + 98;\n        tmpa = qi + 98;\n        tmpb = tmpa + 196;\n\n        tmp = t;\n        r = tmp + 196;\n\n        sp_4096_from_bin(a, 196, in, inLen);\n        sp_4096_from_mp(p, 98, pm);\n        sp_4096_from_mp(q, 98, qm);\n        sp_4096_from_mp(dp, 98, dpm);\n        err = sp_4096_mod_exp_98(tmpa, a, dp, 2048, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(dq, 98, dqm);\n        err = sp_4096_mod_exp_98(tmpb, a, dq, 2048, q, 1);\n    }\n    if (err == MP_OKAY) {\n        (void)sp_4096_sub_98(tmpa, tmpa, tmpb);\n        sp_4096_mask_98(tmp, p, 0 - ((sp_int_digit)tmpa[97] >> 31));\n        (void)sp_4096_add_98(tmpa, tmpa, tmp);\n\n        sp_4096_from_mp(qi, 98, qim);\n        sp_4096_mul_98(tmpa, tmpa, qi);\n        err = sp_4096_mod_98(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mul_98(tmpa, q, tmpa);\n        (void)sp_4096_add_196(r, tmpb, tmpa);\n        sp_4096_norm_196(r);\n\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 98 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n    sp_digit a[196 * 2];\n    sp_digit p[98], q[98], dp[98], dq[98], qi[98];\n    sp_digit tmp[196], tmpa[196], tmpb[196];\n    sp_digit* r = a;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 512U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (inLen > 512U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(a, 196, in, inLen);\n        sp_4096_from_mp(p, 98, pm);\n        sp_4096_from_mp(q, 98, qm);\n        sp_4096_from_mp(dp, 98, dpm);\n        sp_4096_from_mp(dq, 98, dqm);\n        sp_4096_from_mp(qi, 98, qim);\n\n        err = sp_4096_mod_exp_98(tmpa, a, dp, 2048, p, 1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_4096_mod_exp_98(tmpb, a, dq, 2048, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        (void)sp_4096_sub_98(tmpa, tmpa, tmpb);\n        sp_4096_mask_98(tmp, p, 0 - ((sp_int_digit)tmpa[97] >> 31));\n        (void)sp_4096_add_98(tmpa, tmpa, tmp);\n        sp_4096_mul_98(tmpa, tmpa, qi);\n        err = sp_4096_mod_98(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mul_98(tmpa, tmpa, q);\n        (void)sp_4096_add_196(r, tmpb, tmpa);\n        sp_4096_norm_196(r);\n\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n    XMEMSET(tmpa, 0, sizeof(tmpa));\n    XMEMSET(tmpb, 0, sizeof(tmpb));\n    XMEMSET(p, 0, sizeof(p));\n    XMEMSET(q, 0, sizeof(q));\n    XMEMSET(dp, 0, sizeof(dp));\n    XMEMSET(dq, 0, sizeof(dq));\n    XMEMSET(qi, 0, sizeof(qi));\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */\n#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */\n}\n\n#endif /* !WOLFSSL_RSA_PUBLIC_ONLY */\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_4096_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (4096 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 21\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 196);\n        r->used = 196;\n        mp_clamp(r);\n#elif DIGIT_BIT < 21\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 196; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 21) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 21 - s;\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 196; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 21 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 21 - s;\n            }\n            else {\n                s += 21;\n            }\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 196 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 196 * 2;\n        m = e + 196;\n        r = b;\n\n        sp_4096_from_mp(b, 196, base);\n        sp_4096_from_mp(e, 196, exp);\n        sp_4096_from_mp(m, 196, mod);\n\n        err = sp_4096_mod_exp_196(r, b, e, mp_count_bits(exp), m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_4096_to_mp(r, res);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 196U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[392], ed[196], md[196];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 4096) {\n            err = MP_READ_E;\n        }\n    }\n    \n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 196 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 196 * 2;\n        m = e + 196;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 196, base);\n        sp_4096_from_mp(e, 196, exp);\n        sp_4096_from_mp(m, 196, mod);\n\n        err = sp_4096_mod_exp_196(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_4096_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 196U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_4096\nSP_NOINLINE static void sp_4096_lshift_196(sp_digit* r, sp_digit* a, byte n)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    r[196] = a[195] >> (21 - n);\n    for (i=195; i>0; i--) {\n        r[i] = ((a[i] << n) | (a[i-1] >> (21 - n))) & 0x1fffff;\n    }\n#else\n    sp_int_digit s, t;\n\n    s = (sp_int_digit)a[195];\n    r[196] = s >> (21U - n);\n    s = (sp_int_digit)(a[195]); t = (sp_int_digit)(a[194]);\n    r[195] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[194]); t = (sp_int_digit)(a[193]);\n    r[194] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[193]); t = (sp_int_digit)(a[192]);\n    r[193] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[192]); t = (sp_int_digit)(a[191]);\n    r[192] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[191]); t = (sp_int_digit)(a[190]);\n    r[191] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[190]); t = (sp_int_digit)(a[189]);\n    r[190] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[189]); t = (sp_int_digit)(a[188]);\n    r[189] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[188]); t = (sp_int_digit)(a[187]);\n    r[188] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[187]); t = (sp_int_digit)(a[186]);\n    r[187] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[186]); t = (sp_int_digit)(a[185]);\n    r[186] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[185]); t = (sp_int_digit)(a[184]);\n    r[185] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[184]); t = (sp_int_digit)(a[183]);\n    r[184] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[183]); t = (sp_int_digit)(a[182]);\n    r[183] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[182]); t = (sp_int_digit)(a[181]);\n    r[182] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[181]); t = (sp_int_digit)(a[180]);\n    r[181] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[180]); t = (sp_int_digit)(a[179]);\n    r[180] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[179]); t = (sp_int_digit)(a[178]);\n    r[179] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[178]); t = (sp_int_digit)(a[177]);\n    r[178] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[177]); t = (sp_int_digit)(a[176]);\n    r[177] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[176]); t = (sp_int_digit)(a[175]);\n    r[176] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[175]); t = (sp_int_digit)(a[174]);\n    r[175] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[174]); t = (sp_int_digit)(a[173]);\n    r[174] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[173]); t = (sp_int_digit)(a[172]);\n    r[173] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[172]); t = (sp_int_digit)(a[171]);\n    r[172] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[171]); t = (sp_int_digit)(a[170]);\n    r[171] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[170]); t = (sp_int_digit)(a[169]);\n    r[170] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[169]); t = (sp_int_digit)(a[168]);\n    r[169] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[168]); t = (sp_int_digit)(a[167]);\n    r[168] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[167]); t = (sp_int_digit)(a[166]);\n    r[167] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[166]); t = (sp_int_digit)(a[165]);\n    r[166] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[165]); t = (sp_int_digit)(a[164]);\n    r[165] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[164]); t = (sp_int_digit)(a[163]);\n    r[164] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[163]); t = (sp_int_digit)(a[162]);\n    r[163] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[162]); t = (sp_int_digit)(a[161]);\n    r[162] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[161]); t = (sp_int_digit)(a[160]);\n    r[161] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[160]); t = (sp_int_digit)(a[159]);\n    r[160] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[159]); t = (sp_int_digit)(a[158]);\n    r[159] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[158]); t = (sp_int_digit)(a[157]);\n    r[158] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[157]); t = (sp_int_digit)(a[156]);\n    r[157] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[156]); t = (sp_int_digit)(a[155]);\n    r[156] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[155]); t = (sp_int_digit)(a[154]);\n    r[155] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[154]); t = (sp_int_digit)(a[153]);\n    r[154] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[153]); t = (sp_int_digit)(a[152]);\n    r[153] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[152]); t = (sp_int_digit)(a[151]);\n    r[152] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[151]); t = (sp_int_digit)(a[150]);\n    r[151] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[150]); t = (sp_int_digit)(a[149]);\n    r[150] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[149]); t = (sp_int_digit)(a[148]);\n    r[149] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[148]); t = (sp_int_digit)(a[147]);\n    r[148] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[147]); t = (sp_int_digit)(a[146]);\n    r[147] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[146]); t = (sp_int_digit)(a[145]);\n    r[146] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[145]); t = (sp_int_digit)(a[144]);\n    r[145] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[144]); t = (sp_int_digit)(a[143]);\n    r[144] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[143]); t = (sp_int_digit)(a[142]);\n    r[143] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[142]); t = (sp_int_digit)(a[141]);\n    r[142] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[141]); t = (sp_int_digit)(a[140]);\n    r[141] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[140]); t = (sp_int_digit)(a[139]);\n    r[140] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[139]); t = (sp_int_digit)(a[138]);\n    r[139] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[138]); t = (sp_int_digit)(a[137]);\n    r[138] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[137]); t = (sp_int_digit)(a[136]);\n    r[137] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[136]); t = (sp_int_digit)(a[135]);\n    r[136] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[135]); t = (sp_int_digit)(a[134]);\n    r[135] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[134]); t = (sp_int_digit)(a[133]);\n    r[134] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[133]); t = (sp_int_digit)(a[132]);\n    r[133] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[132]); t = (sp_int_digit)(a[131]);\n    r[132] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[131]); t = (sp_int_digit)(a[130]);\n    r[131] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[130]); t = (sp_int_digit)(a[129]);\n    r[130] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[129]); t = (sp_int_digit)(a[128]);\n    r[129] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[128]); t = (sp_int_digit)(a[127]);\n    r[128] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[127]); t = (sp_int_digit)(a[126]);\n    r[127] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[126]); t = (sp_int_digit)(a[125]);\n    r[126] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[125]); t = (sp_int_digit)(a[124]);\n    r[125] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[124]); t = (sp_int_digit)(a[123]);\n    r[124] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[123]); t = (sp_int_digit)(a[122]);\n    r[123] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[122]); t = (sp_int_digit)(a[121]);\n    r[122] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[121]); t = (sp_int_digit)(a[120]);\n    r[121] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[120]); t = (sp_int_digit)(a[119]);\n    r[120] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[119]); t = (sp_int_digit)(a[118]);\n    r[119] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[118]); t = (sp_int_digit)(a[117]);\n    r[118] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[117]); t = (sp_int_digit)(a[116]);\n    r[117] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[116]); t = (sp_int_digit)(a[115]);\n    r[116] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[115]); t = (sp_int_digit)(a[114]);\n    r[115] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[114]); t = (sp_int_digit)(a[113]);\n    r[114] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[113]); t = (sp_int_digit)(a[112]);\n    r[113] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[112]); t = (sp_int_digit)(a[111]);\n    r[112] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[111]); t = (sp_int_digit)(a[110]);\n    r[111] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[110]); t = (sp_int_digit)(a[109]);\n    r[110] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[109]); t = (sp_int_digit)(a[108]);\n    r[109] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[108]); t = (sp_int_digit)(a[107]);\n    r[108] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[107]); t = (sp_int_digit)(a[106]);\n    r[107] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[106]); t = (sp_int_digit)(a[105]);\n    r[106] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[105]); t = (sp_int_digit)(a[104]);\n    r[105] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[104]); t = (sp_int_digit)(a[103]);\n    r[104] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[103]); t = (sp_int_digit)(a[102]);\n    r[103] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[102]); t = (sp_int_digit)(a[101]);\n    r[102] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[101]); t = (sp_int_digit)(a[100]);\n    r[101] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[100]); t = (sp_int_digit)(a[99]);\n    r[100] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[99]); t = (sp_int_digit)(a[98]);\n    r[99] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[98]); t = (sp_int_digit)(a[97]);\n    r[98] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[97]); t = (sp_int_digit)(a[96]);\n    r[97] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[96]); t = (sp_int_digit)(a[95]);\n    r[96] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[95]); t = (sp_int_digit)(a[94]);\n    r[95] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[94]); t = (sp_int_digit)(a[93]);\n    r[94] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[93]); t = (sp_int_digit)(a[92]);\n    r[93] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[92]); t = (sp_int_digit)(a[91]);\n    r[92] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[91]); t = (sp_int_digit)(a[90]);\n    r[91] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[90]); t = (sp_int_digit)(a[89]);\n    r[90] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[89]); t = (sp_int_digit)(a[88]);\n    r[89] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[88]); t = (sp_int_digit)(a[87]);\n    r[88] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[87]); t = (sp_int_digit)(a[86]);\n    r[87] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[86]); t = (sp_int_digit)(a[85]);\n    r[86] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[85]); t = (sp_int_digit)(a[84]);\n    r[85] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[84]); t = (sp_int_digit)(a[83]);\n    r[84] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[83]); t = (sp_int_digit)(a[82]);\n    r[83] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[82]); t = (sp_int_digit)(a[81]);\n    r[82] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[81]); t = (sp_int_digit)(a[80]);\n    r[81] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[80]); t = (sp_int_digit)(a[79]);\n    r[80] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[79]); t = (sp_int_digit)(a[78]);\n    r[79] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[78]); t = (sp_int_digit)(a[77]);\n    r[78] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[77]); t = (sp_int_digit)(a[76]);\n    r[77] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[76]); t = (sp_int_digit)(a[75]);\n    r[76] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[75]); t = (sp_int_digit)(a[74]);\n    r[75] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[74]); t = (sp_int_digit)(a[73]);\n    r[74] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[73]); t = (sp_int_digit)(a[72]);\n    r[73] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[72]); t = (sp_int_digit)(a[71]);\n    r[72] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[71]); t = (sp_int_digit)(a[70]);\n    r[71] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[70]); t = (sp_int_digit)(a[69]);\n    r[70] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[69]); t = (sp_int_digit)(a[68]);\n    r[69] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[68]); t = (sp_int_digit)(a[67]);\n    r[68] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[67]); t = (sp_int_digit)(a[66]);\n    r[67] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[66]); t = (sp_int_digit)(a[65]);\n    r[66] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[65]); t = (sp_int_digit)(a[64]);\n    r[65] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[64]); t = (sp_int_digit)(a[63]);\n    r[64] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[63]); t = (sp_int_digit)(a[62]);\n    r[63] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[62]); t = (sp_int_digit)(a[61]);\n    r[62] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[61]); t = (sp_int_digit)(a[60]);\n    r[61] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[60]); t = (sp_int_digit)(a[59]);\n    r[60] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[59]); t = (sp_int_digit)(a[58]);\n    r[59] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[58]); t = (sp_int_digit)(a[57]);\n    r[58] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[57]); t = (sp_int_digit)(a[56]);\n    r[57] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[56]); t = (sp_int_digit)(a[55]);\n    r[56] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[55]); t = (sp_int_digit)(a[54]);\n    r[55] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[54]); t = (sp_int_digit)(a[53]);\n    r[54] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[53]); t = (sp_int_digit)(a[52]);\n    r[53] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[52]); t = (sp_int_digit)(a[51]);\n    r[52] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[51]); t = (sp_int_digit)(a[50]);\n    r[51] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[50]); t = (sp_int_digit)(a[49]);\n    r[50] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[49]); t = (sp_int_digit)(a[48]);\n    r[49] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[48]); t = (sp_int_digit)(a[47]);\n    r[48] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[47]); t = (sp_int_digit)(a[46]);\n    r[47] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[46]); t = (sp_int_digit)(a[45]);\n    r[46] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[45]); t = (sp_int_digit)(a[44]);\n    r[45] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[44]); t = (sp_int_digit)(a[43]);\n    r[44] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[43]); t = (sp_int_digit)(a[42]);\n    r[43] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[42]); t = (sp_int_digit)(a[41]);\n    r[42] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[41]); t = (sp_int_digit)(a[40]);\n    r[41] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[40]); t = (sp_int_digit)(a[39]);\n    r[40] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[39]); t = (sp_int_digit)(a[38]);\n    r[39] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[38]); t = (sp_int_digit)(a[37]);\n    r[38] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[37]); t = (sp_int_digit)(a[36]);\n    r[37] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[36]); t = (sp_int_digit)(a[35]);\n    r[36] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[35]); t = (sp_int_digit)(a[34]);\n    r[35] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[34]); t = (sp_int_digit)(a[33]);\n    r[34] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[33]); t = (sp_int_digit)(a[32]);\n    r[33] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[32]); t = (sp_int_digit)(a[31]);\n    r[32] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[31]); t = (sp_int_digit)(a[30]);\n    r[31] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[30]); t = (sp_int_digit)(a[29]);\n    r[30] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[29]); t = (sp_int_digit)(a[28]);\n    r[29] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[28]); t = (sp_int_digit)(a[27]);\n    r[28] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[27]); t = (sp_int_digit)(a[26]);\n    r[27] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[26]); t = (sp_int_digit)(a[25]);\n    r[26] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[25]); t = (sp_int_digit)(a[24]);\n    r[25] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[24]); t = (sp_int_digit)(a[23]);\n    r[24] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[23]); t = (sp_int_digit)(a[22]);\n    r[23] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[22]); t = (sp_int_digit)(a[21]);\n    r[22] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[21]); t = (sp_int_digit)(a[20]);\n    r[21] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[20]); t = (sp_int_digit)(a[19]);\n    r[20] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[19]); t = (sp_int_digit)(a[18]);\n    r[19] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[18]); t = (sp_int_digit)(a[17]);\n    r[18] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[17]); t = (sp_int_digit)(a[16]);\n    r[17] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[16]); t = (sp_int_digit)(a[15]);\n    r[16] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[15]); t = (sp_int_digit)(a[14]);\n    r[15] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[14]); t = (sp_int_digit)(a[13]);\n    r[14] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);\n    r[13] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);\n    r[12] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);\n    r[11] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);\n    r[10] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);\n    r[9] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);\n    r[8] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);\n    r[7] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);\n    r[6] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);\n    r[5] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);\n    r[4] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);\n    r[3] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);\n    r[2] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n    s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);\n    r[1] = ((s << n) | (t >> (21U - n))) & 0x1fffff;\n#endif\n    r[0] = (a[0] << n) & 0x1fffff;\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_2_196(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[392];\n    sp_digit td[197];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 589, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 392;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        XMEMSET(td, 0, sizeof(td));\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_196(norm, m);\n\n        bits = ((bits + 3) / 4) * 4;\n        i = ((bits + 20) / 21) - 1;\n        c = bits % 21;\n        if (c == 0) {\n            c = 21;\n        }\n        if (i < 196) {\n            n = e[i--] << (32 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 4) {\n            n |= e[i--] << (11 - c);\n            c += 21;\n        }\n        y = (n >> 28) & 0xf;\n        n <<= 4;\n        c -= 4;\n        sp_4096_lshift_196(r, norm, y);\n        for (; i>=0 || c>=4; ) {\n            if (c < 4) {\n                n |= e[i--] << (11 - c);\n                c += 21;\n            }\n            y = (n >> 28) & 0xf;\n            n <<= 4;\n            c -= 4;\n\n            sp_4096_mont_sqr_196(r, r, m, mp);\n            sp_4096_mont_sqr_196(r, r, m, mp);\n            sp_4096_mont_sqr_196(r, r, m, mp);\n            sp_4096_mont_sqr_196(r, r, m, mp);\n\n            sp_4096_lshift_196(r, r, y);\n            sp_4096_mul_d_196(tmp, norm, (r[196] << 20) + (r[195] >> 1));\n            r[196] = 0;\n            r[195] &= 0x1L;\n            (void)sp_4096_add_196(r, r, tmp);\n            sp_4096_norm_196(r);\n            o = sp_4096_cmp_196(r, m);\n            sp_4096_cond_sub_196(r, r, m, ((o < 0) ?\n                                          (sp_digit)1 : (sp_digit)0) - 1);\n        }\n\n        sp_4096_mont_reduce_196(r, m, mp);\n        n = sp_4096_cmp_196(r, m);\n        sp_4096_cond_sub_196(r, r, m, ((n < 0) ?\n                                                (sp_digit)1 : (sp_digit)0) - 1);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n#endif /* HAVE_FFDHE_4096 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 512 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    word32 i;\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 512) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 196 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 196 * 2;\n        m = e + 196;\n        r = b;\n\n        sp_4096_from_mp(b, 196, base);\n        sp_4096_from_bin(e, 196, exp, expLen);\n        sp_4096_from_mp(m, 196, mod);\n\n    #ifdef HAVE_FFDHE_4096\n        if (base->used == 1 && base->dp[0] == 2 &&\n                ((m[195] << 15) | (m[194] >> 6)) == 0xffffL) {\n            err = sp_4096_mod_exp_2_196(r, e, expLen * 8, m);\n        }\n        else\n    #endif\n            err = sp_4096_mod_exp_196(r, b, e, expLen * 8, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n        for (i=0; i<512 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 196U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[392], ed[196], md[196];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    word32 i;\n    int err = MP_OKAY;\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 512U) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 196 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 196 * 2;\n        m = e + 196;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 196, base);\n        sp_4096_from_bin(e, 196, exp, expLen);\n        sp_4096_from_mp(m, 196, mod);\n\n    #ifdef HAVE_FFDHE_4096\n        if (base->used == 1 && base->dp[0] == 2U &&\n                ((m[195] << 15) | (m[194] >> 6)) == 0xffffL) {\n            err = sp_4096_mod_exp_2_196(r, e, expLen * 8U, m);\n        }\n        else {\n    #endif\n            err = sp_4096_mod_exp_196(r, b, e, expLen * 8U, m, 0);\n    #ifdef HAVE_FFDHE_4096\n        }\n    #endif\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n        for (i=0; i<512U && out[i] == 0U; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 196U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* WOLFSSL_SP_4096 */\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n#ifdef WOLFSSL_HAVE_SP_ECC\n#ifndef WOLFSSL_SP_NO_256\n\n/* Point structure to use. */\ntypedef struct sp_point {\n    sp_digit x[2 * 10];\n    sp_digit y[2 * 10];\n    sp_digit z[2 * 10];\n    int infinity;\n} sp_point;\n\n/* The modulus (prime) of the curve P256. */\nstatic const sp_digit p256_mod[10] = {\n    0x3ffffff,0x3ffffff,0x3ffffff,0x003ffff,0x0000000,0x0000000,0x0000000,\n    0x0000400,0x3ff0000,0x03fffff\n};\n/* The Montogmery normalizer for modulus of the curve P256. */\nstatic const sp_digit p256_norm_mod[10] = {\n    0x0000001,0x0000000,0x0000000,0x3fc0000,0x3ffffff,0x3ffffff,0x3ffffff,\n    0x3fffbff,0x000ffff,0x0000000\n};\n/* The Montogmery multiplier for modulus of the curve P256. */\nstatic const sp_digit p256_mp_mod = 0x000001;\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                            defined(HAVE_ECC_VERIFY)\n/* The order of the curve P256. */\nstatic const sp_digit p256_order[10] = {\n    0x0632551,0x272b0bf,0x1e84f3b,0x2b69c5e,0x3bce6fa,0x3ffffff,0x3ffffff,\n    0x00003ff,0x3ff0000,0x03fffff\n};\n#endif\n/* The order of the curve P256 minus 2. */\nstatic const sp_digit p256_order2[10] = {\n    0x063254f,0x272b0bf,0x1e84f3b,0x2b69c5e,0x3bce6fa,0x3ffffff,0x3ffffff,\n    0x00003ff,0x3ff0000,0x03fffff\n};\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery normalizer for order of the curve P256. */\nstatic const sp_digit p256_norm_order[10] = {\n    0x39cdaaf,0x18d4f40,0x217b0c4,0x14963a1,0x0431905,0x0000000,0x0000000,\n    0x3fffc00,0x000ffff,0x0000000\n};\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery multiplier for order of the curve P256. */\nstatic const sp_digit p256_mp_order = 0x200bc4f;\n#endif\n/* The base point of curve P256. */\nstatic const sp_point p256_base = {\n    /* X ordinate */\n    {\n        0x098c296,0x04e5176,0x33a0f4a,0x204b7ac,0x277037d,0x0e9103c,0x3ce6e56,\n        0x1091fe2,0x1f2e12c,0x01ac5f4, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L\n    },\n    /* Y ordinate */\n    {\n        0x3bf51f5,0x1901a0d,0x1ececbb,0x15dacc5,0x22bce33,0x303e785,0x27eb4a7,\n        0x1fe6e3b,0x2e2fe1a,0x013f8d0, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L\n    },\n    /* Z ordinate */\n    {\n        0x0000001,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,\n        0x0000000,0x0000000,0x0000000, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L\n    },\n    /* infinity */\n    0\n};\n#if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)\nstatic const sp_digit p256_b[10] = {\n    0x3d2604b,0x38f0f89,0x30f63bc,0x2c3314e,0x0651d06,0x1a621af,0x2bbd557,\n    0x24f9ecf,0x1d8aa3a,0x016b18d\n};\n#endif\n\nstatic int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p)\n{\n    int ret = MP_OKAY;\n    (void)heap;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    (void)sp;\n    *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC);\n#else\n    *p = sp;\n#endif\n    if (p == NULL) {\n        ret = MEMORY_E;\n    }\n    return ret;\n}\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* Allocate memory for point and return error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p))\n#else\n/* Set pointer to data and return no error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p))\n#endif\n\n\nstatic void sp_ecc_point_free(sp_point* p, int clear, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* If valid pointer then clear point data if requested and free data. */\n    if (p != NULL) {\n        if (clear != 0) {\n            XMEMSET(p, 0, sizeof(*p));\n        }\n        XFREE(p, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n/* Clear point data if requested. */\n    if (clear != 0) {\n        XMEMSET(p, 0, sizeof(*p));\n    }\n#endif\n    (void)heap;\n}\n\n/* Multiply a number by Montogmery normalizer mod modulus (prime).\n *\n * r  The resulting Montgomery form number.\n * a  The number to convert.\n * m  The modulus (prime).\n * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise.\n */\nstatic int sp_256_mod_mul_norm_10(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    int64_t* td;\n#else\n    int64_t td[8];\n    int64_t a32d[8];\n#endif\n    int64_t* t;\n    int64_t* a32;\n    int64_t o;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 8, NULL, DYNAMIC_TYPE_ECC);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t = td;\n        a32 = td + 8;\n#else\n        t = td;\n        a32 = a32d;\n#endif\n\n        a32[0] = a[0];\n        a32[0] |= a[1] << 26U;\n        a32[0] &= 0xffffffffL;\n        a32[1] = (sp_digit)(a[1] >> 6);\n        a32[1] |= a[2] << 20U;\n        a32[1] &= 0xffffffffL;\n        a32[2] = (sp_digit)(a[2] >> 12);\n        a32[2] |= a[3] << 14U;\n        a32[2] &= 0xffffffffL;\n        a32[3] = (sp_digit)(a[3] >> 18);\n        a32[3] |= a[4] << 8U;\n        a32[3] &= 0xffffffffL;\n        a32[4] = (sp_digit)(a[4] >> 24);\n        a32[4] |= a[5] << 2U;\n        a32[4] |= a[6] << 28U;\n        a32[4] &= 0xffffffffL;\n        a32[5] = (sp_digit)(a[6] >> 4);\n        a32[5] |= a[7] << 22U;\n        a32[5] &= 0xffffffffL;\n        a32[6] = (sp_digit)(a[7] >> 10);\n        a32[6] |= a[8] << 16U;\n        a32[6] &= 0xffffffffL;\n        a32[7] = (sp_digit)(a[8] >> 16);\n        a32[7] |= a[9] << 10U;\n        a32[7] &= 0xffffffffL;\n\n        /*  1  1  0 -1 -1 -1 -1  0 */\n        t[0] = 0 + a32[0] + a32[1] - a32[3] - a32[4] - a32[5] - a32[6];\n        /*  0  1  1  0 -1 -1 -1 -1 */\n        t[1] = 0 + a32[1] + a32[2] - a32[4] - a32[5] - a32[6] - a32[7];\n        /*  0  0  1  1  0 -1 -1 -1 */\n        t[2] = 0 + a32[2] + a32[3] - a32[5] - a32[6] - a32[7];\n        /* -1 -1  0  2  2  1  0 -1 */\n        t[3] = 0 - a32[0] - a32[1] + 2 * a32[3] + 2 * a32[4] + a32[5] - a32[7];\n        /*  0 -1 -1  0  2  2  1  0 */\n        t[4] = 0 - a32[1] - a32[2] + 2 * a32[4] + 2 * a32[5] + a32[6];\n        /*  0  0 -1 -1  0  2  2  1 */\n        t[5] = 0 - a32[2] - a32[3] + 2 * a32[5] + 2 * a32[6] + a32[7];\n        /* -1 -1  0  0  0  1  3  2 */\n        t[6] = 0 - a32[0] - a32[1] + a32[5] + 3 * a32[6] + 2 * a32[7];\n        /*  1  0 -1 -1 -1 -1  0  3 */\n        t[7] = 0 + a32[0] - a32[2] - a32[3] - a32[4] - a32[5] + 3 * a32[7];\n\n        t[1] += t[0] >> 32U; t[0] &= 0xffffffffL;\n        t[2] += t[1] >> 32U; t[1] &= 0xffffffffL;\n        t[3] += t[2] >> 32U; t[2] &= 0xffffffffL;\n        t[4] += t[3] >> 32U; t[3] &= 0xffffffffL;\n        t[5] += t[4] >> 32U; t[4] &= 0xffffffffL;\n        t[6] += t[5] >> 32U; t[5] &= 0xffffffffL;\n        t[7] += t[6] >> 32U; t[6] &= 0xffffffffL;\n        o     = t[7] >> 32U; t[7] &= 0xffffffffL;\n        t[0] += o;\n        t[3] -= o;\n        t[6] -= o;\n        t[7] += o;\n        t[1] += t[0] >> 32U; t[0] &= 0xffffffffL;\n        t[2] += t[1] >> 32U; t[1] &= 0xffffffffL;\n        t[3] += t[2] >> 32U; t[2] &= 0xffffffffL;\n        t[4] += t[3] >> 32U; t[3] &= 0xffffffffL;\n        t[5] += t[4] >> 32U; t[4] &= 0xffffffffL;\n        t[6] += t[5] >> 32U; t[5] &= 0xffffffffL;\n        t[7] += t[6] >> 32U; t[6] &= 0xffffffffL;\n\n        r[0] = (sp_digit)(t[0]) & 0x3ffffffL;\n        r[1] = (sp_digit)(t[0] >> 26U);\n        r[1] |= t[1] << 6U;\n        r[1] &= 0x3ffffffL;\n        r[2] = (sp_digit)(t[1] >> 20U);\n        r[2] |= t[2] << 12U;\n        r[2] &= 0x3ffffffL;\n        r[3] = (sp_digit)(t[2] >> 14U);\n        r[3] |= t[3] << 18U;\n        r[3] &= 0x3ffffffL;\n        r[4] = (sp_digit)(t[3] >> 8U);\n        r[4] |= t[4] << 24U;\n        r[4] &= 0x3ffffffL;\n        r[5] = (sp_digit)(t[4] >> 2U) & 0x3ffffffL;\n        r[6] = (sp_digit)(t[4] >> 28U);\n        r[6] |= t[5] << 4U;\n        r[6] &= 0x3ffffffL;\n        r[7] = (sp_digit)(t[5] >> 22U);\n        r[7] |= t[6] << 10U;\n        r[7] &= 0x3ffffffL;\n        r[8] = (sp_digit)(t[6] >> 16U);\n        r[8] |= t[7] << 16U;\n        r[8] &= 0x3ffffffL;\n        r[9] = (sp_digit)(t[7] >> 10U);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_256_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 26\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 26\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0x3ffffff;\n        s = 26U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 26U) <= (word32)DIGIT_BIT) {\n            s += 26U;\n            r[j] &= 0x3ffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 26) {\n            r[j] &= 0x3ffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 26 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Convert a point of type ecc_point to type sp_point.\n *\n * p   Point of type sp_point (result).\n * pm  Point of type ecc_point.\n */\nstatic void sp_256_point_from_ecc_point_10(sp_point* p, const ecc_point* pm)\n{\n    XMEMSET(p->x, 0, sizeof(p->x));\n    XMEMSET(p->y, 0, sizeof(p->y));\n    XMEMSET(p->z, 0, sizeof(p->z));\n    sp_256_from_mp(p->x, 10, pm->x);\n    sp_256_from_mp(p->y, 10, pm->y);\n    sp_256_from_mp(p->z, 10, pm->z);\n    p->infinity = 0;\n}\n\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_256_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 26\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 10);\n        r->used = 10;\n        mp_clamp(r);\n#elif DIGIT_BIT < 26\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 10; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 26) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 26 - s;\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 10; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 26 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 26 - s;\n            }\n            else {\n                s += 26;\n            }\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Convert a point of type sp_point to type ecc_point.\n *\n * p   Point of type sp_point.\n * pm  Point of type ecc_point (result).\n * returns MEMORY_E when allocation of memory in ecc_point fails otherwise\n * MP_OKAY.\n */\nstatic int sp_256_point_to_ecc_point_10(const sp_point* p, ecc_point* pm)\n{\n    int err;\n\n    err = sp_256_to_mp(p->x, pm->x);\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pm->y);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pm->z);\n    }\n\n    return err;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_256_cmp_10(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=9; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    r |= (a[ 9] - b[ 9]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[ 8] - b[ 8]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[ 7] - b[ 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[ 6] - b[ 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[ 5] - b[ 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[ 4] - b[ 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[ 3] - b[ 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[ 2] - b[ 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[ 1] - b[ 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[ 0] - b[ 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Normalize the values in each word to 26.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_256_norm_10(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 9; i++) {\n        a[i+1] += a[i] >> 26;\n        a[i] &= 0x3ffffff;\n    }\n#else\n    a[1] += a[0] >> 26; a[0] &= 0x3ffffff;\n    a[2] += a[1] >> 26; a[1] &= 0x3ffffff;\n    a[3] += a[2] >> 26; a[2] &= 0x3ffffff;\n    a[4] += a[3] >> 26; a[3] &= 0x3ffffff;\n    a[5] += a[4] >> 26; a[4] &= 0x3ffffff;\n    a[6] += a[5] >> 26; a[5] &= 0x3ffffff;\n    a[7] += a[6] >> 26; a[6] &= 0x3ffffff;\n    a[8] += a[7] >> 26; a[7] &= 0x3ffffff;\n    a[9] += a[8] >> 26; a[8] &= 0x3ffffff;\n#endif\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_256_cond_sub_10(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 10; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    r[ 0] = a[ 0] - (b[ 0] & m);\n    r[ 1] = a[ 1] - (b[ 1] & m);\n    r[ 2] = a[ 2] - (b[ 2] & m);\n    r[ 3] = a[ 3] - (b[ 3] & m);\n    r[ 4] = a[ 4] - (b[ 4] & m);\n    r[ 5] = a[ 5] - (b[ 5] & m);\n    r[ 6] = a[ 6] - (b[ 6] & m);\n    r[ 7] = a[ 7] - (b[ 7] & m);\n    r[ 8] = a[ 8] - (b[ 8] & m);\n    r[ 9] = a[ 9] - (b[ 9] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#define sp_256_mont_reduce_order_10         sp_256_mont_reduce_10\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_256_mul_add_10(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 10; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0x3ffffff;\n        t >>= 26;\n    }\n    r[10] += t;\n#else\n    int64_t tb = b;\n    int64_t t[10];\n\n    t[ 0] = tb * a[ 0];\n    t[ 1] = tb * a[ 1];\n    t[ 2] = tb * a[ 2];\n    t[ 3] = tb * a[ 3];\n    t[ 4] = tb * a[ 4];\n    t[ 5] = tb * a[ 5];\n    t[ 6] = tb * a[ 6];\n    t[ 7] = tb * a[ 7];\n    t[ 8] = tb * a[ 8];\n    t[ 9] = tb * a[ 9];\n    r[ 0] +=                 (sp_digit)(t[ 0] & 0x3ffffff);\n    r[ 1] += (sp_digit)((t[ 0] >> 26) + (t[ 1] & 0x3ffffff));\n    r[ 2] += (sp_digit)((t[ 1] >> 26) + (t[ 2] & 0x3ffffff));\n    r[ 3] += (sp_digit)((t[ 2] >> 26) + (t[ 3] & 0x3ffffff));\n    r[ 4] += (sp_digit)((t[ 3] >> 26) + (t[ 4] & 0x3ffffff));\n    r[ 5] += (sp_digit)((t[ 4] >> 26) + (t[ 5] & 0x3ffffff));\n    r[ 6] += (sp_digit)((t[ 5] >> 26) + (t[ 6] & 0x3ffffff));\n    r[ 7] += (sp_digit)((t[ 6] >> 26) + (t[ 7] & 0x3ffffff));\n    r[ 8] += (sp_digit)((t[ 7] >> 26) + (t[ 8] & 0x3ffffff));\n    r[ 9] += (sp_digit)((t[ 8] >> 26) + (t[ 9] & 0x3ffffff));\n    r[10] +=  t[ 9] >> 26;\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Shift the result in the high 256 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_256_mont_shift_10(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    sp_digit n, s;\n\n    s = a[10];\n    n = a[9] >> 22;\n    for (i = 0; i < 9; i++) {\n        n += (s & 0x3ffffff) << 4;\n        r[i] = n & 0x3ffffff;\n        n >>= 26;\n        s = a[11 + i] + (s >> 26);\n    }\n    n += s << 4;\n    r[9] = n;\n#else\n    sp_digit n, s;\n\n    s = a[10]; n = a[9] >> 22;\n    n += (s & 0x3ffffff) << 4; r[ 0] = n & 0x3ffffff;\n    n >>= 26; s = a[11] + (s >> 26);\n    n += (s & 0x3ffffff) << 4; r[ 1] = n & 0x3ffffff;\n    n >>= 26; s = a[12] + (s >> 26);\n    n += (s & 0x3ffffff) << 4; r[ 2] = n & 0x3ffffff;\n    n >>= 26; s = a[13] + (s >> 26);\n    n += (s & 0x3ffffff) << 4; r[ 3] = n & 0x3ffffff;\n    n >>= 26; s = a[14] + (s >> 26);\n    n += (s & 0x3ffffff) << 4; r[ 4] = n & 0x3ffffff;\n    n >>= 26; s = a[15] + (s >> 26);\n    n += (s & 0x3ffffff) << 4; r[ 5] = n & 0x3ffffff;\n    n >>= 26; s = a[16] + (s >> 26);\n    n += (s & 0x3ffffff) << 4; r[ 6] = n & 0x3ffffff;\n    n >>= 26; s = a[17] + (s >> 26);\n    n += (s & 0x3ffffff) << 4; r[ 7] = n & 0x3ffffff;\n    n >>= 26; s = a[18] + (s >> 26);\n    n += (s & 0x3ffffff) << 4; r[ 8] = n & 0x3ffffff;\n    n >>= 26; s = a[19] + (s >> 26);\n    n += s << 4;              r[ 9] = n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[10], 0, sizeof(*r) * 10U);\n}\n\n/* Reduce the number back to 256 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_256_mont_reduce_10(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    if (mp != 1) {\n        for (i=0; i<9; i++) {\n            mu = (a[i] * mp) & 0x3ffffff;\n            sp_256_mul_add_10(a+i, m, mu);\n            a[i+1] += a[i] >> 26;\n        }\n        mu = (a[i] * mp) & 0x3fffffL;\n        sp_256_mul_add_10(a+i, m, mu);\n        a[i+1] += a[i] >> 26;\n        a[i] &= 0x3ffffff;\n    }\n    else {\n        for (i=0; i<9; i++) {\n            mu = a[i] & 0x3ffffff;\n            sp_256_mul_add_10(a+i, p256_mod, mu);\n            a[i+1] += a[i] >> 26;\n        }\n        mu = a[i] & 0x3fffffL;\n        sp_256_mul_add_10(a+i, p256_mod, mu);\n        a[i+1] += a[i] >> 26;\n        a[i] &= 0x3ffffff;\n    }\n\n    sp_256_mont_shift_10(a, a);\n    sp_256_cond_sub_10(a, a, m, 0 - (((a[9] >> 22) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_10(a);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_256_mul_10(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[9]) * b[9];\n    r[19] = (sp_digit)(c >> 26);\n    c = (c & 0x3ffffff) << 26;\n    for (k = 17; k >= 0; k--) {\n        for (i = 9; i >= 0; i--) {\n            j = k - i;\n            if (j >= 10) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 52;\n        r[k + 1] = (c >> 26) & 0x3ffffff;\n        c = (c & 0x3ffffff) << 26;\n    }\n    r[0] = (sp_digit)(c >> 26);\n}\n\n#else\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_256_mul_10(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int64_t t0   = ((int64_t)a[ 0]) * b[ 0];\n    int64_t t1   = ((int64_t)a[ 0]) * b[ 1]\n                 + ((int64_t)a[ 1]) * b[ 0];\n    int64_t t2   = ((int64_t)a[ 0]) * b[ 2]\n                 + ((int64_t)a[ 1]) * b[ 1]\n                 + ((int64_t)a[ 2]) * b[ 0];\n    int64_t t3   = ((int64_t)a[ 0]) * b[ 3]\n                 + ((int64_t)a[ 1]) * b[ 2]\n                 + ((int64_t)a[ 2]) * b[ 1]\n                 + ((int64_t)a[ 3]) * b[ 0];\n    int64_t t4   = ((int64_t)a[ 0]) * b[ 4]\n                 + ((int64_t)a[ 1]) * b[ 3]\n                 + ((int64_t)a[ 2]) * b[ 2]\n                 + ((int64_t)a[ 3]) * b[ 1]\n                 + ((int64_t)a[ 4]) * b[ 0];\n    int64_t t5   = ((int64_t)a[ 0]) * b[ 5]\n                 + ((int64_t)a[ 1]) * b[ 4]\n                 + ((int64_t)a[ 2]) * b[ 3]\n                 + ((int64_t)a[ 3]) * b[ 2]\n                 + ((int64_t)a[ 4]) * b[ 1]\n                 + ((int64_t)a[ 5]) * b[ 0];\n    int64_t t6   = ((int64_t)a[ 0]) * b[ 6]\n                 + ((int64_t)a[ 1]) * b[ 5]\n                 + ((int64_t)a[ 2]) * b[ 4]\n                 + ((int64_t)a[ 3]) * b[ 3]\n                 + ((int64_t)a[ 4]) * b[ 2]\n                 + ((int64_t)a[ 5]) * b[ 1]\n                 + ((int64_t)a[ 6]) * b[ 0];\n    int64_t t7   = ((int64_t)a[ 0]) * b[ 7]\n                 + ((int64_t)a[ 1]) * b[ 6]\n                 + ((int64_t)a[ 2]) * b[ 5]\n                 + ((int64_t)a[ 3]) * b[ 4]\n                 + ((int64_t)a[ 4]) * b[ 3]\n                 + ((int64_t)a[ 5]) * b[ 2]\n                 + ((int64_t)a[ 6]) * b[ 1]\n                 + ((int64_t)a[ 7]) * b[ 0];\n    int64_t t8   = ((int64_t)a[ 0]) * b[ 8]\n                 + ((int64_t)a[ 1]) * b[ 7]\n                 + ((int64_t)a[ 2]) * b[ 6]\n                 + ((int64_t)a[ 3]) * b[ 5]\n                 + ((int64_t)a[ 4]) * b[ 4]\n                 + ((int64_t)a[ 5]) * b[ 3]\n                 + ((int64_t)a[ 6]) * b[ 2]\n                 + ((int64_t)a[ 7]) * b[ 1]\n                 + ((int64_t)a[ 8]) * b[ 0];\n    int64_t t9   = ((int64_t)a[ 0]) * b[ 9]\n                 + ((int64_t)a[ 1]) * b[ 8]\n                 + ((int64_t)a[ 2]) * b[ 7]\n                 + ((int64_t)a[ 3]) * b[ 6]\n                 + ((int64_t)a[ 4]) * b[ 5]\n                 + ((int64_t)a[ 5]) * b[ 4]\n                 + ((int64_t)a[ 6]) * b[ 3]\n                 + ((int64_t)a[ 7]) * b[ 2]\n                 + ((int64_t)a[ 8]) * b[ 1]\n                 + ((int64_t)a[ 9]) * b[ 0];\n    int64_t t10  = ((int64_t)a[ 1]) * b[ 9]\n                 + ((int64_t)a[ 2]) * b[ 8]\n                 + ((int64_t)a[ 3]) * b[ 7]\n                 + ((int64_t)a[ 4]) * b[ 6]\n                 + ((int64_t)a[ 5]) * b[ 5]\n                 + ((int64_t)a[ 6]) * b[ 4]\n                 + ((int64_t)a[ 7]) * b[ 3]\n                 + ((int64_t)a[ 8]) * b[ 2]\n                 + ((int64_t)a[ 9]) * b[ 1];\n    int64_t t11  = ((int64_t)a[ 2]) * b[ 9]\n                 + ((int64_t)a[ 3]) * b[ 8]\n                 + ((int64_t)a[ 4]) * b[ 7]\n                 + ((int64_t)a[ 5]) * b[ 6]\n                 + ((int64_t)a[ 6]) * b[ 5]\n                 + ((int64_t)a[ 7]) * b[ 4]\n                 + ((int64_t)a[ 8]) * b[ 3]\n                 + ((int64_t)a[ 9]) * b[ 2];\n    int64_t t12  = ((int64_t)a[ 3]) * b[ 9]\n                 + ((int64_t)a[ 4]) * b[ 8]\n                 + ((int64_t)a[ 5]) * b[ 7]\n                 + ((int64_t)a[ 6]) * b[ 6]\n                 + ((int64_t)a[ 7]) * b[ 5]\n                 + ((int64_t)a[ 8]) * b[ 4]\n                 + ((int64_t)a[ 9]) * b[ 3];\n    int64_t t13  = ((int64_t)a[ 4]) * b[ 9]\n                 + ((int64_t)a[ 5]) * b[ 8]\n                 + ((int64_t)a[ 6]) * b[ 7]\n                 + ((int64_t)a[ 7]) * b[ 6]\n                 + ((int64_t)a[ 8]) * b[ 5]\n                 + ((int64_t)a[ 9]) * b[ 4];\n    int64_t t14  = ((int64_t)a[ 5]) * b[ 9]\n                 + ((int64_t)a[ 6]) * b[ 8]\n                 + ((int64_t)a[ 7]) * b[ 7]\n                 + ((int64_t)a[ 8]) * b[ 6]\n                 + ((int64_t)a[ 9]) * b[ 5];\n    int64_t t15  = ((int64_t)a[ 6]) * b[ 9]\n                 + ((int64_t)a[ 7]) * b[ 8]\n                 + ((int64_t)a[ 8]) * b[ 7]\n                 + ((int64_t)a[ 9]) * b[ 6];\n    int64_t t16  = ((int64_t)a[ 7]) * b[ 9]\n                 + ((int64_t)a[ 8]) * b[ 8]\n                 + ((int64_t)a[ 9]) * b[ 7];\n    int64_t t17  = ((int64_t)a[ 8]) * b[ 9]\n                 + ((int64_t)a[ 9]) * b[ 8];\n    int64_t t18  = ((int64_t)a[ 9]) * b[ 9];\n\n    t1   += t0  >> 26; r[ 0] = t0  & 0x3ffffff;\n    t2   += t1  >> 26; r[ 1] = t1  & 0x3ffffff;\n    t3   += t2  >> 26; r[ 2] = t2  & 0x3ffffff;\n    t4   += t3  >> 26; r[ 3] = t3  & 0x3ffffff;\n    t5   += t4  >> 26; r[ 4] = t4  & 0x3ffffff;\n    t6   += t5  >> 26; r[ 5] = t5  & 0x3ffffff;\n    t7   += t6  >> 26; r[ 6] = t6  & 0x3ffffff;\n    t8   += t7  >> 26; r[ 7] = t7  & 0x3ffffff;\n    t9   += t8  >> 26; r[ 8] = t8  & 0x3ffffff;\n    t10  += t9  >> 26; r[ 9] = t9  & 0x3ffffff;\n    t11  += t10 >> 26; r[10] = t10 & 0x3ffffff;\n    t12  += t11 >> 26; r[11] = t11 & 0x3ffffff;\n    t13  += t12 >> 26; r[12] = t12 & 0x3ffffff;\n    t14  += t13 >> 26; r[13] = t13 & 0x3ffffff;\n    t15  += t14 >> 26; r[14] = t14 & 0x3ffffff;\n    t16  += t15 >> 26; r[15] = t15 & 0x3ffffff;\n    t17  += t16 >> 26; r[16] = t16 & 0x3ffffff;\n    t18  += t17 >> 26; r[17] = t17 & 0x3ffffff;\n    r[19] = (sp_digit)(t18 >> 26);\n                       r[18] = t18 & 0x3ffffff;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_mul_10(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_256_mul_10(r, a, b);\n    sp_256_mont_reduce_10(r, m, mp);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_256_sqr_10(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int64_t c;\n\n    c = ((int64_t)a[9]) * a[9];\n    r[19] = (sp_digit)(c >> 26);\n    c = (c & 0x3ffffff) << 26;\n    for (k = 17; k >= 0; k--) {\n        for (i = 9; i >= 0; i--) {\n            j = k - i;\n            if (j >= 10 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int64_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int64_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 52;\n        r[k + 1] = (c >> 26) & 0x3ffffff;\n        c = (c & 0x3ffffff) << 26;\n    }\n    r[0] = (sp_digit)(c >> 26);\n}\n\n#else\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_256_sqr_10(sp_digit* r, const sp_digit* a)\n{\n    int64_t t0   =  ((int64_t)a[ 0]) * a[ 0];\n    int64_t t1   = (((int64_t)a[ 0]) * a[ 1]) * 2;\n    int64_t t2   = (((int64_t)a[ 0]) * a[ 2]) * 2\n                 +  ((int64_t)a[ 1]) * a[ 1];\n    int64_t t3   = (((int64_t)a[ 0]) * a[ 3]\n                 +  ((int64_t)a[ 1]) * a[ 2]) * 2;\n    int64_t t4   = (((int64_t)a[ 0]) * a[ 4]\n                 +  ((int64_t)a[ 1]) * a[ 3]) * 2\n                 +  ((int64_t)a[ 2]) * a[ 2];\n    int64_t t5   = (((int64_t)a[ 0]) * a[ 5]\n                 +  ((int64_t)a[ 1]) * a[ 4]\n                 +  ((int64_t)a[ 2]) * a[ 3]) * 2;\n    int64_t t6   = (((int64_t)a[ 0]) * a[ 6]\n                 +  ((int64_t)a[ 1]) * a[ 5]\n                 +  ((int64_t)a[ 2]) * a[ 4]) * 2\n                 +  ((int64_t)a[ 3]) * a[ 3];\n    int64_t t7   = (((int64_t)a[ 0]) * a[ 7]\n                 +  ((int64_t)a[ 1]) * a[ 6]\n                 +  ((int64_t)a[ 2]) * a[ 5]\n                 +  ((int64_t)a[ 3]) * a[ 4]) * 2;\n    int64_t t8   = (((int64_t)a[ 0]) * a[ 8]\n                 +  ((int64_t)a[ 1]) * a[ 7]\n                 +  ((int64_t)a[ 2]) * a[ 6]\n                 +  ((int64_t)a[ 3]) * a[ 5]) * 2\n                 +  ((int64_t)a[ 4]) * a[ 4];\n    int64_t t9   = (((int64_t)a[ 0]) * a[ 9]\n                 +  ((int64_t)a[ 1]) * a[ 8]\n                 +  ((int64_t)a[ 2]) * a[ 7]\n                 +  ((int64_t)a[ 3]) * a[ 6]\n                 +  ((int64_t)a[ 4]) * a[ 5]) * 2;\n    int64_t t10  = (((int64_t)a[ 1]) * a[ 9]\n                 +  ((int64_t)a[ 2]) * a[ 8]\n                 +  ((int64_t)a[ 3]) * a[ 7]\n                 +  ((int64_t)a[ 4]) * a[ 6]) * 2\n                 +  ((int64_t)a[ 5]) * a[ 5];\n    int64_t t11  = (((int64_t)a[ 2]) * a[ 9]\n                 +  ((int64_t)a[ 3]) * a[ 8]\n                 +  ((int64_t)a[ 4]) * a[ 7]\n                 +  ((int64_t)a[ 5]) * a[ 6]) * 2;\n    int64_t t12  = (((int64_t)a[ 3]) * a[ 9]\n                 +  ((int64_t)a[ 4]) * a[ 8]\n                 +  ((int64_t)a[ 5]) * a[ 7]) * 2\n                 +  ((int64_t)a[ 6]) * a[ 6];\n    int64_t t13  = (((int64_t)a[ 4]) * a[ 9]\n                 +  ((int64_t)a[ 5]) * a[ 8]\n                 +  ((int64_t)a[ 6]) * a[ 7]) * 2;\n    int64_t t14  = (((int64_t)a[ 5]) * a[ 9]\n                 +  ((int64_t)a[ 6]) * a[ 8]) * 2\n                 +  ((int64_t)a[ 7]) * a[ 7];\n    int64_t t15  = (((int64_t)a[ 6]) * a[ 9]\n                 +  ((int64_t)a[ 7]) * a[ 8]) * 2;\n    int64_t t16  = (((int64_t)a[ 7]) * a[ 9]) * 2\n                 +  ((int64_t)a[ 8]) * a[ 8];\n    int64_t t17  = (((int64_t)a[ 8]) * a[ 9]) * 2;\n    int64_t t18  =  ((int64_t)a[ 9]) * a[ 9];\n\n    t1   += t0  >> 26; r[ 0] = t0  & 0x3ffffff;\n    t2   += t1  >> 26; r[ 1] = t1  & 0x3ffffff;\n    t3   += t2  >> 26; r[ 2] = t2  & 0x3ffffff;\n    t4   += t3  >> 26; r[ 3] = t3  & 0x3ffffff;\n    t5   += t4  >> 26; r[ 4] = t4  & 0x3ffffff;\n    t6   += t5  >> 26; r[ 5] = t5  & 0x3ffffff;\n    t7   += t6  >> 26; r[ 6] = t6  & 0x3ffffff;\n    t8   += t7  >> 26; r[ 7] = t7  & 0x3ffffff;\n    t9   += t8  >> 26; r[ 8] = t8  & 0x3ffffff;\n    t10  += t9  >> 26; r[ 9] = t9  & 0x3ffffff;\n    t11  += t10 >> 26; r[10] = t10 & 0x3ffffff;\n    t12  += t11 >> 26; r[11] = t11 & 0x3ffffff;\n    t13  += t12 >> 26; r[12] = t12 & 0x3ffffff;\n    t14  += t13 >> 26; r[13] = t13 & 0x3ffffff;\n    t15  += t14 >> 26; r[14] = t14 & 0x3ffffff;\n    t16  += t15 >> 26; r[15] = t15 & 0x3ffffff;\n    t17  += t16 >> 26; r[16] = t16 & 0x3ffffff;\n    t18  += t17 >> 26; r[17] = t17 & 0x3ffffff;\n    r[19] = (sp_digit)(t18 >> 26);\n                       r[18] = t18 & 0x3ffffff;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_sqr_10(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_256_sqr_10(r, a);\n    sp_256_mont_reduce_10(r, m, mp);\n}\n\n#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)\n/* Square the Montgomery form number a number of times. (r = a ^ n mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * n   Number of times to square.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_sqr_n_10(sp_digit* r, const sp_digit* a, int n,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_256_mont_sqr_10(r, a, m, mp);\n    for (; n > 1; n--) {\n        sp_256_mont_sqr_10(r, r, m, mp);\n    }\n}\n\n#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */\n#ifdef WOLFSSL_SP_SMALL\n/* Mod-2 for the P256 curve. */\nstatic const uint32_t p256_mod_2[8] = {\n    0xfffffffdU,0xffffffffU,0xffffffffU,0x00000000U,0x00000000U,0x00000000U,\n    0x00000001U,0xffffffffU\n};\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the modulus (prime) of the\n * P256 curve. (r = 1 / a mod m)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_10(sp_digit* r, const sp_digit* a, sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 10);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_10(t, t, p256_mod, p256_mp_mod);\n        if (p256_mod_2[i / 32] & ((sp_digit)1 << (i % 32)))\n            sp_256_mont_mul_10(t, t, a, p256_mod, p256_mp_mod);\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 10);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 10;\n    sp_digit* t3 = td + 4 * 10;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_10(t, a, p256_mod, p256_mp_mod);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_10(t, t, a, p256_mod, p256_mp_mod);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_10(t2, t, 2, p256_mod, p256_mp_mod);\n    /* t3= a^d = t2 * a */\n    sp_256_mont_mul_10(t3, t2, a, p256_mod, p256_mp_mod);\n    /* t = a^f = t2 * t */\n    sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^f0 = t ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_10(t2, t, 4, p256_mod, p256_mp_mod);\n    /* t3= a^fd = t2 * t3 */\n    sp_256_mont_mul_10(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ff = t2 * t */\n    sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_10(t2, t, 8, p256_mod, p256_mp_mod);\n    /* t3= a^fffd = t2 * t3 */\n    sp_256_mont_mul_10(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_10(t2, t, 16, p256_mod, p256_mp_mod);\n    /* t3= a^fffffffd = t2 * t3 */\n    sp_256_mont_mul_10(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff00000000 = t ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_10(t2, t, 32, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001 = t2 * a */\n    sp_256_mont_mul_10(t2, t2, a, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff000000010000000000000000000000000000000000000000\n     *   = t2 ^ 2 ^ 160 */\n    sp_256_mont_sqr_n_10(t2, t2, 160, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff\n     *   = t2 * t */\n    sp_256_mont_mul_10(t2, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000\n     *   = t2 ^ 2 ^ 32 */\n    sp_256_mont_sqr_n_10(t2, t2, 32, p256_mod, p256_mp_mod);\n    /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd\n     *   = t2 * t3 */\n    sp_256_mont_mul_10(r, t2, t3, p256_mod, p256_mp_mod);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Map the Montgomery form projective co-ordinate point to an affine point.\n *\n * r  Resulting affine co-ordinate point.\n * p  Montgomery form projective co-ordinate point.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_map_10(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*10;\n    int32_t n;\n\n    sp_256_mont_inv_10(t1, p->z, t + 2*10);\n\n    sp_256_mont_sqr_10(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_10(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    /* x /= z^2 */\n    sp_256_mont_mul_10(r->x, p->x, t2, p256_mod, p256_mp_mod);\n    XMEMSET(r->x + 10, 0, sizeof(r->x) / 2U);\n    sp_256_mont_reduce_10(r->x, p256_mod, p256_mp_mod);\n    /* Reduce x to less than modulus */\n    n = sp_256_cmp_10(r->x, p256_mod);\n    sp_256_cond_sub_10(r->x, r->x, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_10(r->x);\n\n    /* y /= z^3 */\n    sp_256_mont_mul_10(r->y, p->y, t1, p256_mod, p256_mp_mod);\n    XMEMSET(r->y + 10, 0, sizeof(r->y) / 2U);\n    sp_256_mont_reduce_10(r->y, p256_mod, p256_mp_mod);\n    /* Reduce y to less than modulus */\n    n = sp_256_cmp_10(r->y, p256_mod);\n    sp_256_cond_sub_10(r->y, r->y, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_10(r->y);\n\n    XMEMSET(r->z, 0, sizeof(r->z));\n    r->z[0] = 1;\n\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_256_add_10(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 10; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#else\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_256_add_10(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    r[ 0] = a[ 0] + b[ 0];\n    r[ 1] = a[ 1] + b[ 1];\n    r[ 2] = a[ 2] + b[ 2];\n    r[ 3] = a[ 3] + b[ 3];\n    r[ 4] = a[ 4] + b[ 4];\n    r[ 5] = a[ 5] + b[ 5];\n    r[ 6] = a[ 6] + b[ 6];\n    r[ 7] = a[ 7] + b[ 7];\n    r[ 8] = a[ 8] + b[ 8];\n    r[ 9] = a[ 9] + b[ 9];\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Add two Montgomery form numbers (r = a + b % m).\n *\n * r   Result of addition.\n * a   First number to add in Montogmery form.\n * b   Second number to add in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_add_10(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m)\n{\n    (void)sp_256_add_10(r, a, b);\n    sp_256_norm_10(r);\n    sp_256_cond_sub_10(r, r, m, 0 - (((r[9] >> 22) > 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_10(r);\n}\n\n/* Double a Montgomery form number (r = a + a % m).\n *\n * r   Result of doubling.\n * a   Number to double in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_dbl_10(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    (void)sp_256_add_10(r, a, a);\n    sp_256_norm_10(r);\n    sp_256_cond_sub_10(r, r, m, 0 - (((r[9] >> 22) > 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_10(r);\n}\n\n/* Triple a Montgomery form number (r = a + a + a % m).\n *\n * r   Result of Tripling.\n * a   Number to triple in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_tpl_10(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    (void)sp_256_add_10(r, a, a);\n    sp_256_norm_10(r);\n    sp_256_cond_sub_10(r, r, m, 0 - (((r[9] >> 22) > 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_10(r);\n    (void)sp_256_add_10(r, r, a);\n    sp_256_norm_10(r);\n    sp_256_cond_sub_10(r, r, m, 0 - (((r[9] >> 22) > 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_10(r);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_256_sub_10(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 10; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#else\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_256_sub_10(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    r[ 0] = a[ 0] - b[ 0];\n    r[ 1] = a[ 1] - b[ 1];\n    r[ 2] = a[ 2] - b[ 2];\n    r[ 3] = a[ 3] - b[ 3];\n    r[ 4] = a[ 4] - b[ 4];\n    r[ 5] = a[ 5] - b[ 5];\n    r[ 6] = a[ 6] - b[ 6];\n    r[ 7] = a[ 7] - b[ 7];\n    r[ 8] = a[ 8] - b[ 8];\n    r[ 9] = a[ 9] - b[ 9];\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_256_cond_add_10(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 10; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    r[ 0] = a[ 0] + (b[ 0] & m);\n    r[ 1] = a[ 1] + (b[ 1] & m);\n    r[ 2] = a[ 2] + (b[ 2] & m);\n    r[ 3] = a[ 3] + (b[ 3] & m);\n    r[ 4] = a[ 4] + (b[ 4] & m);\n    r[ 5] = a[ 5] + (b[ 5] & m);\n    r[ 6] = a[ 6] + (b[ 6] & m);\n    r[ 7] = a[ 7] + (b[ 7] & m);\n    r[ 8] = a[ 8] + (b[ 8] & m);\n    r[ 9] = a[ 9] + (b[ 9] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Subtract two Montgomery form numbers (r = a - b % m).\n *\n * r   Result of subtration.\n * a   Number to subtract from in Montogmery form.\n * b   Number to subtract with in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_sub_10(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m)\n{\n    (void)sp_256_sub_10(r, a, b);\n    sp_256_cond_add_10(r, r, m, r[9] >> 22);\n    sp_256_norm_10(r);\n}\n\n/* Shift number left one bit.\n * Bottom bit is lost.\n *\n * r  Result of shift.\n * a  Number to shift.\n */\nSP_NOINLINE static void sp_256_rshift1_10(sp_digit* r, sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<9; i++) {\n        r[i] = ((a[i] >> 1) | (a[i + 1] << 25)) & 0x3ffffff;\n    }\n#else\n    r[0] = ((a[0] >> 1) | (a[1] << 25)) & 0x3ffffff;\n    r[1] = ((a[1] >> 1) | (a[2] << 25)) & 0x3ffffff;\n    r[2] = ((a[2] >> 1) | (a[3] << 25)) & 0x3ffffff;\n    r[3] = ((a[3] >> 1) | (a[4] << 25)) & 0x3ffffff;\n    r[4] = ((a[4] >> 1) | (a[5] << 25)) & 0x3ffffff;\n    r[5] = ((a[5] >> 1) | (a[6] << 25)) & 0x3ffffff;\n    r[6] = ((a[6] >> 1) | (a[7] << 25)) & 0x3ffffff;\n    r[7] = ((a[7] >> 1) | (a[8] << 25)) & 0x3ffffff;\n    r[8] = ((a[8] >> 1) | (a[9] << 25)) & 0x3ffffff;\n#endif\n    r[9] = a[9] >> 1;\n}\n\n/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)\n *\n * r  Result of division by 2.\n * a  Number to divide.\n * m  Modulus (prime).\n */\nstatic void sp_256_div2_10(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    sp_256_cond_add_10(r, a, m, 0 - (a[0] & 1));\n    sp_256_norm_10(r);\n    sp_256_rshift1_10(r, r);\n}\n\n/* Double the Montgomery form projective point p.\n *\n * r  Result of doubling point.\n * p  Point to double.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_10(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*10;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* When infinity don't double point passed in - constant time. */\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    /* Put point to double into result - good for infinty. */\n    if (r != p) {\n        for (i=0; i<10; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<10; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<10; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* T1 = Z * Z */\n    sp_256_mont_sqr_10(t1, z, p256_mod, p256_mp_mod);\n    /* Z = Y * Z */\n    sp_256_mont_mul_10(z, y, z, p256_mod, p256_mp_mod);\n    /* Z = 2Z */\n    sp_256_mont_dbl_10(z, z, p256_mod);\n    /* T2 = X - T1 */\n    sp_256_mont_sub_10(t2, x, t1, p256_mod);\n    /* T1 = X + T1 */\n    sp_256_mont_add_10(t1, x, t1, p256_mod);\n    /* T2 = T1 * T2 */\n    sp_256_mont_mul_10(t2, t1, t2, p256_mod, p256_mp_mod);\n    /* T1 = 3T2 */\n    sp_256_mont_tpl_10(t1, t2, p256_mod);\n    /* Y = 2Y */\n    sp_256_mont_dbl_10(y, y, p256_mod);\n    /* Y = Y * Y */\n    sp_256_mont_sqr_10(y, y, p256_mod, p256_mp_mod);\n    /* T2 = Y * Y */\n    sp_256_mont_sqr_10(t2, y, p256_mod, p256_mp_mod);\n    /* T2 = T2/2 */\n    sp_256_div2_10(t2, t2, p256_mod);\n    /* Y = Y * X */\n    sp_256_mont_mul_10(y, y, x, p256_mod, p256_mp_mod);\n    /* X = T1 * T1 */\n    sp_256_mont_mul_10(x, t1, t1, p256_mod, p256_mp_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_10(x, x, y, p256_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_10(x, x, y, p256_mod);\n    /* Y = Y - X */\n    sp_256_mont_sub_10(y, y, x, p256_mod);\n    /* Y = Y * T1 */\n    sp_256_mont_mul_10(y, y, t1, p256_mod, p256_mp_mod);\n    /* Y = Y - T2 */\n    sp_256_mont_sub_10(y, y, t2, p256_mod);\n\n}\n\n/* Compare two numbers to determine if they are equal.\n * Constant time implementation.\n *\n * a  First number to compare.\n * b  Second number to compare.\n * returns 1 when equal and 0 otherwise.\n */\nstatic int sp_256_cmp_equal_10(const sp_digit* a, const sp_digit* b)\n{\n    return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) |\n            (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7]) |\n            (a[8] ^ b[8]) | (a[9] ^ b[9])) == 0;\n}\n\n/* Add two Montgomery form projective points.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_10(sp_point* r, const sp_point* p, const sp_point* q,\n        sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*10;\n    sp_digit* t3 = t + 4*10;\n    sp_digit* t4 = t + 6*10;\n    sp_digit* t5 = t + 8*10;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Ensure only the first point is the same as the result. */\n    if (q == r) {\n        const sp_point* a = p;\n        p = q;\n        q = a;\n    }\n\n    /* Check double */\n    (void)sp_256_sub_10(t1, p256_mod, q->y);\n    sp_256_norm_10(t1);\n    if ((sp_256_cmp_equal_10(p->x, q->x) & sp_256_cmp_equal_10(p->z, q->z) &\n        (sp_256_cmp_equal_10(p->y, q->y) | sp_256_cmp_equal_10(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_10(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<10; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<10; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<10; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U1 = X1*Z2^2 */\n        sp_256_mont_sqr_10(t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(t3, t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(t1, t1, x, p256_mod, p256_mp_mod);\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_10(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S1 = Y1*Z2^3 */\n        sp_256_mont_mul_10(t3, t3, y, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_10(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - U1 */\n        sp_256_mont_sub_10(t2, t2, t1, p256_mod);\n        /* R = S2 - S1 */\n        sp_256_mont_sub_10(t4, t4, t3, p256_mod);\n        /* Z3 = H*Z1*Z2 */\n        sp_256_mont_mul_10(z, z, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*U1*H^2 */\n        sp_256_mont_sqr_10(x, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_10(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(y, t1, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_10(x, x, t5, p256_mod);\n        sp_256_mont_dbl_10(t1, y, p256_mod);\n        sp_256_mont_sub_10(x, x, t1, p256_mod);\n        /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */\n        sp_256_mont_sub_10(y, y, x, p256_mod);\n        sp_256_mont_mul_10(y, y, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(t5, t5, t3, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_10(y, y, t5, p256_mod);\n    }\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n    sp_point* td;\n    sp_point* t[3];\n    sp_digit* tmp;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    (void)heap;\n\n    td = (sp_point*)XMALLOC(sizeof(sp_point) * 3, heap, DYNAMIC_TYPE_ECC);\n    if (td == NULL)\n        err = MEMORY_E;\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, heap,\n                                                              DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3);\n\n        t[0] = &td[0];\n        t[1] = &td[1];\n        t[2] = &td[2];\n\n        /* t[0] = {0, 0, 1} * norm */\n        t[0]->infinity = 1;\n        /* t[1] = {g->x, g->y, g->z} * norm */\n        err = sp_256_mod_mul_norm_10(t[1]->x, g->x, p256_mod);\n    }\n    if (err == MP_OKAY)\n        err = sp_256_mod_mul_norm_10(t[1]->y, g->y, p256_mod);\n    if (err == MP_OKAY)\n        err = sp_256_mod_mul_norm_10(t[1]->z, g->z, p256_mod);\n\n    if (err == MP_OKAY) {\n        i = 9;\n        c = 22;\n        n = k[i--] << (26 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1)\n                    break;\n\n                n = k[i--];\n                c = 26;\n            }\n\n            y = (n >> 25) & 1;\n            n <<= 1;\n\n            sp_256_proj_point_add_10(t[y^1], t[0], t[1], tmp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(sp_point));\n            sp_256_proj_point_dbl_10(t[2], t[2], tmp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(sp_point));\n        }\n\n        if (map != 0) {\n            sp_256_map_10(r, t[0], tmp);\n        }\n        else {\n            XMEMCPY(r, t[0], sizeof(sp_point));\n        }\n    }\n\n    if (tmp != NULL) {\n        XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 10 * 5);\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n    if (td != NULL) {\n        XMEMSET(td, 0, sizeof(sp_point) * 3);\n        XFREE(td, NULL, DYNAMIC_TYPE_ECC);\n    }\n\n    return err;\n}\n\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td[3];\n    sp_digit tmpd[2 * 10 * 5];\n#endif\n    sp_point* t;\n    sp_digit* tmp;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    (void)heap;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_point td[3];\n    t = (sp_point*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC);\n    if (t == NULL)\n        err = MEMORY_E;\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, heap,\n                             DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n#else\n    t = td;\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        t[0] = &td[0];\n        t[1] = &td[1];\n        t[2] = &td[2];\n\n        /* t[0] = {0, 0, 1} * norm */\n        XMEMSET(&t[0], 0, sizeof(t[0]));\n        t[0].infinity = 1;\n        /* t[1] = {g->x, g->y, g->z} * norm */\n        err = sp_256_mod_mul_norm_10(t[1].x, g->x, p256_mod);\n    }\n    if (err == MP_OKAY)\n        err = sp_256_mod_mul_norm_10(t[1].y, g->y, p256_mod);\n    if (err == MP_OKAY)\n        err = sp_256_mod_mul_norm_10(t[1].z, g->z, p256_mod);\n\n    if (err == MP_OKAY) {\n        i = 9;\n        c = 22;\n        n = k[i--] << (26 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1)\n                    break;\n\n                n = k[i--];\n                c = 26;\n            }\n\n            y = (n >> 25) & 1;\n            n <<= 1;\n\n            sp_256_proj_point_add_10(&t[y^1], &t[0], &t[1], tmp);\n\n            XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) +\n                                 ((size_t)&t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_256_proj_point_dbl_10(&t[2], &t[2], tmp);\n            XMEMCPY((void*)(((size_t)&t[0] & addr_mask[y^1]) +\n                          ((size_t)&t[1] & addr_mask[y])), &t[2], sizeof(t[2]));\n        }\n\n        if (map != 0) {\n            sp_256_map_10(r, &t[0], tmp);\n        }\n        else {\n            XMEMCPY(r, &t[0], sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 10 * 5);\n        XFREE(tmp, heap, DYNAMIC_TYPE_ECC);\n    }\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_point) * 3);\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    ForceZero(tmpd, sizeof(tmpd));\n    ForceZero(td, sizeof(td));\n#endif\n\n    return err;\n}\n\n#else\n/* A table entry for pre-computed points. */\ntypedef struct sp_table_entry {\n    sp_digit x[10];\n    sp_digit y[10];\n} sp_table_entry;\n\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_fast_10(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td[16];\n    sp_point rtd;\n    sp_digit tmpd[2 * 10 * 5];\n#endif\n    sp_point* t;\n    sp_point* rt;\n    sp_digit* tmp;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_point*)XMALLOC(sizeof(sp_point) * 16, heap, DYNAMIC_TYPE_ECC);\n    if (t == NULL)\n        err = MEMORY_E;\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, heap,\n                             DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n#else\n    t = td;\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        /* t[0] = {0, 0, 1} * norm */\n        XMEMSET(&t[0], 0, sizeof(t[0]));\n        t[0].infinity = 1;\n        /* t[1] = {g->x, g->y, g->z} * norm */\n        (void)sp_256_mod_mul_norm_10(t[1].x, g->x, p256_mod);\n        (void)sp_256_mod_mul_norm_10(t[1].y, g->y, p256_mod);\n        (void)sp_256_mod_mul_norm_10(t[1].z, g->z, p256_mod);\n        t[1].infinity = 0;\n        sp_256_proj_point_dbl_10(&t[ 2], &t[ 1], tmp);\n        t[ 2].infinity = 0;\n        sp_256_proj_point_add_10(&t[ 3], &t[ 2], &t[ 1], tmp);\n        t[ 3].infinity = 0;\n        sp_256_proj_point_dbl_10(&t[ 4], &t[ 2], tmp);\n        t[ 4].infinity = 0;\n        sp_256_proj_point_add_10(&t[ 5], &t[ 3], &t[ 2], tmp);\n        t[ 5].infinity = 0;\n        sp_256_proj_point_dbl_10(&t[ 6], &t[ 3], tmp);\n        t[ 6].infinity = 0;\n        sp_256_proj_point_add_10(&t[ 7], &t[ 4], &t[ 3], tmp);\n        t[ 7].infinity = 0;\n        sp_256_proj_point_dbl_10(&t[ 8], &t[ 4], tmp);\n        t[ 8].infinity = 0;\n        sp_256_proj_point_add_10(&t[ 9], &t[ 5], &t[ 4], tmp);\n        t[ 9].infinity = 0;\n        sp_256_proj_point_dbl_10(&t[10], &t[ 5], tmp);\n        t[10].infinity = 0;\n        sp_256_proj_point_add_10(&t[11], &t[ 6], &t[ 5], tmp);\n        t[11].infinity = 0;\n        sp_256_proj_point_dbl_10(&t[12], &t[ 6], tmp);\n        t[12].infinity = 0;\n        sp_256_proj_point_add_10(&t[13], &t[ 7], &t[ 6], tmp);\n        t[13].infinity = 0;\n        sp_256_proj_point_dbl_10(&t[14], &t[ 7], tmp);\n        t[14].infinity = 0;\n        sp_256_proj_point_add_10(&t[15], &t[ 8], &t[ 7], tmp);\n        t[15].infinity = 0;\n\n        i = 8;\n        n = k[i+1] << 6;\n        c = 18;\n        y = n >> 24;\n        XMEMCPY(rt, &t[y], sizeof(sp_point));\n        n <<= 8;\n        for (; i>=0 || c>=4; ) {\n            if (c < 4) {\n                n |= k[i--] << (6 - c);\n                c += 26;\n            }\n            y = (n >> 28) & 0xf;\n            n <<= 4;\n            c -= 4;\n\n            sp_256_proj_point_dbl_10(rt, rt, tmp);\n            sp_256_proj_point_dbl_10(rt, rt, tmp);\n            sp_256_proj_point_dbl_10(rt, rt, tmp);\n            sp_256_proj_point_dbl_10(rt, rt, tmp);\n\n            sp_256_proj_point_add_10(rt, rt, &t[y], tmp);\n        }\n\n        if (map != 0) {\n            sp_256_map_10(r, rt, tmp);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 10 * 5);\n        XFREE(tmp, heap, DYNAMIC_TYPE_ECC);\n    }\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_point) * 16);\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    ForceZero(tmpd, sizeof(tmpd));\n    ForceZero(td, sizeof(td));\n#endif\n    sp_ecc_point_free(rt, 1, heap);\n\n    return err;\n}\n\n#ifdef FP_ECC\n/* Double the Montgomery form projective point p a number of times.\n *\n * r  Result of repeated doubling of point.\n * p  Point to double.\n * n  Number of times to double\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_n_10(sp_point* r, const sp_point* p, int n,\n        sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* w = t;\n    sp_digit* a = t + 2*10;\n    sp_digit* b = t + 4*10;\n    sp_digit* t1 = t + 6*10;\n    sp_digit* t2 = t + 8*10;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    if (r != p) {\n        for (i=0; i<10; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<10; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<10; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* Y = 2*Y */\n    sp_256_mont_dbl_10(y, y, p256_mod);\n    /* W = Z^4 */\n    sp_256_mont_sqr_10(w, z, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_10(w, w, p256_mod, p256_mp_mod);\n    while (n-- > 0) {\n        /* A = 3*(X^2 - W) */\n        sp_256_mont_sqr_10(t1, x, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_10(t1, t1, w, p256_mod);\n        sp_256_mont_tpl_10(a, t1, p256_mod);\n        /* B = X*Y^2 */\n        sp_256_mont_sqr_10(t2, y, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(b, t2, x, p256_mod, p256_mp_mod);\n        /* X = A^2 - 2B */\n        sp_256_mont_sqr_10(x, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_10(t1, b, p256_mod);\n        sp_256_mont_sub_10(x, x, t1, p256_mod);\n        /* Z = Z*Y */\n        sp_256_mont_mul_10(z, z, y, p256_mod, p256_mp_mod);\n        /* t2 = Y^4 */\n        sp_256_mont_sqr_10(t2, t2, p256_mod, p256_mp_mod);\n        if (n != 0) {\n            /* W = W*Y^4 */\n            sp_256_mont_mul_10(w, w, t2, p256_mod, p256_mp_mod);\n        }\n        /* y = 2*A*(B - X) - Y^4 */\n        sp_256_mont_sub_10(y, b, x, p256_mod);\n        sp_256_mont_mul_10(y, y, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_10(y, y, p256_mod);\n        sp_256_mont_sub_10(y, y, t2, p256_mod);\n    }\n    /* Y = Y/2 */\n    sp_256_div2_10(y, y, p256_mod);\n}\n\n#endif /* FP_ECC */\n/* Add two Montgomery form projective points. The second point has a q value of\n * one.\n * Only the first point can be the same pointer as the result point.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_qz1_10(sp_point* r, const sp_point* p,\n        const sp_point* q, sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*10;\n    sp_digit* t3 = t + 4*10;\n    sp_digit* t4 = t + 6*10;\n    sp_digit* t5 = t + 8*10;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Check double */\n    (void)sp_256_sub_10(t1, p256_mod, q->y);\n    sp_256_norm_10(t1);\n    if ((sp_256_cmp_equal_10(p->x, q->x) & sp_256_cmp_equal_10(p->z, q->z) &\n        (sp_256_cmp_equal_10(p->y, q->y) | sp_256_cmp_equal_10(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_10(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<10; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<10; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<10; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_10(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_10(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - X1 */\n        sp_256_mont_sub_10(t2, t2, x, p256_mod);\n        /* R = S2 - Y1 */\n        sp_256_mont_sub_10(t4, t4, y, p256_mod);\n        /* Z3 = H*Z1 */\n        sp_256_mont_mul_10(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*X1*H^2 */\n        sp_256_mont_sqr_10(t1, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_10(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(t3, x, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_10(x, t1, t5, p256_mod);\n        sp_256_mont_dbl_10(t1, t3, p256_mod);\n        sp_256_mont_sub_10(x, x, t1, p256_mod);\n        /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */\n        sp_256_mont_sub_10(t3, t3, x, p256_mod);\n        sp_256_mont_mul_10(t3, t3, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(t5, t5, y, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_10(y, t3, t5, p256_mod);\n    }\n}\n\n#ifdef FP_ECC\n/* Convert the projective point to affine.\n * Ordinates are in Montgomery form.\n *\n * a  Point to convert.\n * t  Temprorary data.\n */\nstatic void sp_256_proj_to_affine_10(sp_point* a, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2 * 10;\n    sp_digit* tmp = t + 4 * 10;\n\n    sp_256_mont_inv_10(t1, a->z, tmp);\n\n    sp_256_mont_sqr_10(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_10(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    sp_256_mont_mul_10(a->x, a->x, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_10(a->y, a->y, t1, p256_mod, p256_mp_mod);\n    XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod));\n}\n\n/* Generate the pre-computed table of points for the base point.\n *\n * a      The base point.\n * table  Place to store generated point data.\n * tmp    Temprorary data.\n * heap  Heap to use for allocation.\n */\nstatic int sp_256_gen_stripe_table_10(const sp_point* a,\n        sp_table_entry* table, sp_digit* tmp, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td, s1d, s2d;\n#endif\n    sp_point* t;\n    sp_point* s1 = NULL;\n    sp_point* s2 = NULL;\n    int i, j;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, td, t);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s1d, s1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s2d, s2);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_10(t->x, a->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_10(t->y, a->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_10(t->z, a->z, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        t->infinity = 0;\n        sp_256_proj_to_affine_10(t, tmp);\n\n        XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s1->infinity = 0;\n        XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s2->infinity = 0;\n\n        /* table[0] = {0, 0, infinity} */\n        XMEMSET(&table[0], 0, sizeof(sp_table_entry));\n        /* table[1] = Affine version of 'a' in Montgomery form */\n        XMEMCPY(table[1].x, t->x, sizeof(table->x));\n        XMEMCPY(table[1].y, t->y, sizeof(table->y));\n\n        for (i=1; i<8; i++) {\n            sp_256_proj_point_dbl_n_10(t, t, 32, tmp);\n            sp_256_proj_to_affine_10(t, tmp);\n            XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));\n            XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));\n        }\n\n        for (i=1; i<8; i++) {\n            XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));\n            XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));\n            for (j=(1<<i)+1; j<(1<<(i+1)); j++) {\n                XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));\n                XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));\n                sp_256_proj_point_add_qz1_10(t, s1, s2, tmp);\n                sp_256_proj_to_affine_10(t, tmp);\n                XMEMCPY(table[j].x, t->x, sizeof(table->x));\n                XMEMCPY(table[j].y, t->y, sizeof(table->y));\n            }\n        }\n    }\n\n    sp_ecc_point_free(s2, 0, heap);\n    sp_ecc_point_free(s1, 0, heap);\n    sp_ecc_point_free( t, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC */\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_stripe_10(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit td[2 * 10 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* t;\n    int i, j;\n    int y, x;\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, heap,\n                           DYNAMIC_TYPE_ECC);\n    if (t == NULL) {\n        err = MEMORY_E;\n    }\n#else\n    t = td;\n#endif\n\n    if (err == MP_OKAY) {\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        y = 0;\n        for (j=0,x=31; j<8; j++,x+=32) {\n            y |= ((k[x / 26] >> (x % 26)) & 1) << j;\n        }\n        XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));\n        XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));\n        rt->infinity = !y;\n        for (i=30; i>=0; i--) {\n            y = 0;\n            for (j=0,x=i; j<8; j++,x+=32) {\n                y |= ((k[x / 26] >> (x % 26)) & 1) << j;\n            }\n\n            sp_256_proj_point_dbl_10(rt, rt, t);\n            XMEMCPY(p->x, table[y].x, sizeof(table[y].x));\n            XMEMCPY(p->y, table[y].y, sizeof(table[y].y));\n            p->infinity = !y;\n            sp_256_proj_point_add_qz1_10(rt, rt, p, t);\n        }\n\n        if (map != 0) {\n            sp_256_map_10(r, rt, t);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n#ifdef FP_ECC\n#ifndef FP_ENTRIES\n    #define FP_ENTRIES 16\n#endif\n\ntypedef struct sp_cache_t {\n    sp_digit x[10];\n    sp_digit y[10];\n    sp_table_entry table[256];\n    uint32_t cnt;\n    int set;\n} sp_cache_t;\n\nstatic THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES];\nstatic THREAD_LS_T int sp_cache_last = -1;\nstatic THREAD_LS_T int sp_cache_inited = 0;\n\n#ifndef HAVE_THREAD_LS\n    static volatile int initCacheMutex = 0;\n    static wolfSSL_Mutex sp_cache_lock;\n#endif\n\nstatic void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache)\n{\n    int i, j;\n    uint32_t least;\n\n    if (sp_cache_inited == 0) {\n        for (i=0; i<FP_ENTRIES; i++) {\n            sp_cache[i].set = 0;\n        }\n        sp_cache_inited = 1;\n    }\n\n    /* Compare point with those in cache. */\n    for (i=0; i<FP_ENTRIES; i++) {\n        if (!sp_cache[i].set)\n            continue;\n\n        if (sp_256_cmp_equal_10(g->x, sp_cache[i].x) &\n                           sp_256_cmp_equal_10(g->y, sp_cache[i].y)) {\n            sp_cache[i].cnt++;\n            break;\n        }\n    }\n\n    /* No match. */\n    if (i == FP_ENTRIES) {\n        /* Find empty entry. */\n        i = (sp_cache_last + 1) % FP_ENTRIES;\n        for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) {\n            if (!sp_cache[i].set) {\n                break;\n            }\n        }\n\n        /* Evict least used. */\n        if (i == sp_cache_last) {\n            least = sp_cache[0].cnt;\n            for (j=1; j<FP_ENTRIES; j++) {\n                if (sp_cache[j].cnt < least) {\n                    i = j;\n                    least = sp_cache[i].cnt;\n                }\n            }\n        }\n\n        XMEMCPY(sp_cache[i].x, g->x, sizeof(sp_cache[i].x));\n        XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y));\n        sp_cache[i].set = 1;\n        sp_cache[i].cnt = 1;\n    }\n\n    *cache = &sp_cache[i];\n    sp_cache_last = i;\n}\n#endif /* FP_ECC */\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#ifndef FP_ECC\n    return sp_256_ecc_mulmod_fast_10(r, g, k, map, heap);\n#else\n    sp_digit tmp[2 * 10 * 5];\n    sp_cache_t* cache;\n    int err = MP_OKAY;\n\n#ifndef HAVE_THREAD_LS\n    if (initCacheMutex == 0) {\n         wc_InitMutex(&sp_cache_lock);\n         initCacheMutex = 1;\n    }\n    if (wc_LockMutex(&sp_cache_lock) != 0)\n       err = BAD_MUTEX_E;\n#endif /* HAVE_THREAD_LS */\n\n    if (err == MP_OKAY) {\n        sp_ecc_get_cache(g, &cache);\n        if (cache->cnt == 2)\n            sp_256_gen_stripe_table_10(g, cache->table, tmp, heap);\n\n#ifndef HAVE_THREAD_LS\n        wc_UnLockMutex(&sp_cache_lock);\n#endif /* HAVE_THREAD_LS */\n\n        if (cache->cnt < 2) {\n            err = sp_256_ecc_mulmod_fast_10(r, g, k, map, heap);\n        }\n        else {\n            err = sp_256_ecc_mulmod_stripe_10(r, g, cache->table, k,\n                    map, heap);\n        }\n    }\n\n    return err;\n#endif\n}\n\n#endif\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * p     Point to multiply.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map,\n        void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[10];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 10, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 10, km);\n        sp_256_point_from_ecc_point_10(point, gm);\n\n            err = sp_256_ecc_mulmod_10(point, point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_10(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_10(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    /* No pre-computed values. */\n    return sp_256_ecc_mulmod_10(r, &p256_base, k, map, heap);\n}\n\n#else\nstatic const sp_table_entry p256_table[256] = {\n    /* 0 */\n    { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 */\n    { { 0x0a9143c,0x1cc3506,0x360179e,0x3f17fb6,0x075ba95,0x1d88944,\n        0x3b732b7,0x15719e7,0x376a537,0x0062417 },\n      { 0x295560a,0x094d5f3,0x245cddf,0x392e867,0x18b4ab8,0x3487cc9,\n        0x288688d,0x176174b,0x3182588,0x0215c7f } },\n    /* 2 */\n    { { 0x147519a,0x2218090,0x32f0202,0x2b09acd,0x0d0981e,0x1e17af2,\n        0x14a7caa,0x163a6a7,0x10ddbdf,0x03654f1 },\n      { 0x1590f8f,0x0d8733f,0x09179d6,0x1ad139b,0x372e962,0x0bad933,\n        0x1961102,0x223cdff,0x37e9eb2,0x0218fae } },\n    /* 3 */\n    { { 0x0db6485,0x1ad88d7,0x2f97785,0x288bc28,0x3808f0e,0x3df8c02,\n        0x28d9544,0x20280f9,0x055b5ff,0x00001d8 },\n      { 0x38d2010,0x13ae6e0,0x308a763,0x2ecc90d,0x254014f,0x10a9981,\n        0x247d398,0x0fb8383,0x3613437,0x020c21d } },\n    /* 4 */\n    { { 0x2a0d2bb,0x08bf145,0x34994f9,0x1b06988,0x30d5cc1,0x1f18b22,\n        0x01cf3a5,0x199fe49,0x161fd1b,0x00bd79a },\n      { 0x1a01797,0x171c2fd,0x21925c1,0x1358255,0x23d20b4,0x1c7f6d4,\n        0x111b370,0x03dec12,0x1168d6f,0x03d923e } },\n    /* 5 */\n    { { 0x137bbbc,0x19a11f8,0x0bec9e5,0x27a29a8,0x3e43446,0x275cd18,\n        0x0427617,0x00056c7,0x285133d,0x016af80 },\n      { 0x04c7dab,0x2a0df30,0x0c0792a,0x1310c98,0x3573d9f,0x239b30d,\n        0x1315627,0x1ce0c32,0x25b6b6f,0x0252edc } },\n    /* 6 */\n    { { 0x20f141c,0x26d23dc,0x3c74bbf,0x334b7d6,0x06199b3,0x0441171,\n        0x3f61294,0x313bf70,0x3cb2f7d,0x03375ae },\n      { 0x2f436fd,0x19c02fa,0x26becca,0x1b6e64c,0x26f647f,0x053c948,\n        0x0fa7920,0x397d830,0x2bd4bda,0x028d86f } },\n    /* 7 */\n    { { 0x17c13c7,0x2895616,0x03e128a,0x17d42df,0x1c38d63,0x0f02747,\n        0x039aecf,0x0a4b01c,0x209c4b5,0x02e84b2 },\n      { 0x1f91dfd,0x023e916,0x07fb9e4,0x19b3ba8,0x13af43b,0x35e02ca,\n        0x0eb0899,0x3bd2c7b,0x19d701f,0x014faee } },\n    /* 8 */\n    { { 0x0e63d34,0x1fb8c6c,0x0fab4fe,0x1caa795,0x0f46005,0x179ed69,\n        0x093334d,0x120c701,0x39206d5,0x021627e },\n      { 0x183553a,0x03d7319,0x09e5aa7,0x12b8959,0x2087909,0x0011194,\n        0x1045071,0x0713f32,0x16d0254,0x03aec1a } },\n    /* 9 */\n    { { 0x01647c5,0x1b2856b,0x1799461,0x11f133d,0x0b8127d,0x1937eeb,\n        0x266aa37,0x1f68f71,0x0cbd1b2,0x03aca08 },\n      { 0x287e008,0x1be361a,0x38f3940,0x276488d,0x2d87dfa,0x0333b2c,\n        0x2d2e428,0x368755b,0x09b55a7,0x007ca0a } },\n    /* 10 */\n    { { 0x389da99,0x2a8300e,0x0022abb,0x27ae0a1,0x0a6f2d7,0x207017a,\n        0x047862b,0x1358c9e,0x35905e5,0x00cde92 },\n      { 0x1f7794a,0x1d40348,0x3f613c6,0x2ddf5b5,0x0207005,0x133f5ba,\n        0x1a37810,0x3ef5829,0x0d5f4c2,0x0035978 } },\n    /* 11 */\n    { { 0x1275d38,0x026efad,0x2358d9d,0x1142f82,0x14268a7,0x1cfac99,\n        0x362ff49,0x288cbc1,0x24252f4,0x0308f68 },\n      { 0x394520c,0x06e13c2,0x178e5da,0x18ec16f,0x1096667,0x134a7a8,\n        0x0dcb869,0x33fc4e9,0x38cc790,0x006778e } },\n    /* 12 */\n    { { 0x2c5fe04,0x29c5b09,0x1bdb183,0x02ceee8,0x03b28de,0x132dc4b,\n        0x32c586a,0x32ff5d0,0x3d491fc,0x038d372 },\n      { 0x2a58403,0x2351aea,0x3a53b40,0x21a0ba5,0x39a6974,0x1aaaa2b,\n        0x3901273,0x03dfe78,0x3447b4e,0x039d907 } },\n    /* 13 */\n    { { 0x364ba59,0x14e5077,0x02fc7d7,0x3b02c09,0x1d33f10,0x0560616,\n        0x06dfc6a,0x15efd3c,0x357052a,0x01284b7 },\n      { 0x039dbd0,0x18ce3e5,0x3e1fbfa,0x352f794,0x0d3c24b,0x07c6cc5,\n        0x1e4ffa2,0x3a91bf5,0x293bb5b,0x01abd6a } },\n    /* 14 */\n    { { 0x0c91999,0x02da644,0x0491da1,0x100a960,0x00a24b4,0x2330824,\n        0x0094b4b,0x1004cf8,0x35a66a4,0x017f8d1 },\n      { 0x13e7b4b,0x232af7e,0x391ab0f,0x069f08f,0x3292b50,0x3479898,\n        0x2889aec,0x2a4590b,0x308ecfe,0x02d5138 } },\n    /* 15 */\n    { { 0x2ddfdce,0x231ba45,0x39e6647,0x19be245,0x12c3291,0x35399f8,\n        0x0d6e764,0x3082d3a,0x2bda6b0,0x0382dac },\n      { 0x37efb57,0x04b7cae,0x00070d3,0x379e431,0x01aac0d,0x1e6f251,\n        0x0336ad6,0x0ddd3e4,0x3de25a6,0x01c7008 } },\n    /* 16 */\n    { { 0x3e20925,0x230912f,0x286762a,0x30e3f73,0x391c19a,0x34e1c18,\n        0x16a5d5d,0x093d96a,0x3d421d3,0x0187561 },\n      { 0x37173ea,0x19ce8a8,0x0b65e87,0x0214dde,0x2238480,0x16ead0f,\n        0x38441e0,0x3bef843,0x2124621,0x03e847f } },\n    /* 17 */\n    { { 0x0b19ffd,0x247cacb,0x3c231c8,0x16ec648,0x201ba8d,0x2b172a3,\n        0x103d678,0x2fb72db,0x04c1f13,0x0161bac },\n      { 0x3e8ed09,0x171b949,0x2de20c3,0x0f06067,0x21e81a3,0x1b194be,\n        0x0fd6c05,0x13c449e,0x0087086,0x006756b } },\n    /* 18 */\n    { { 0x09a4e1f,0x27d604c,0x00741e9,0x06fa49c,0x0ab7de7,0x3f4a348,\n        0x25ef0be,0x158fc9a,0x33f7f9c,0x039f001 },\n      { 0x2f59f76,0x3598e83,0x30501f6,0x15083f2,0x0669b3b,0x29980b5,\n        0x0c1f7a7,0x0f02b02,0x0fec65b,0x0382141 } },\n    /* 19 */\n    { { 0x031b3ca,0x23da368,0x2d66f09,0x27b9b69,0x06d1cab,0x13c91ba,\n        0x3d81fa9,0x25ad16f,0x0825b09,0x01e3c06 },\n      { 0x225787f,0x3bf790e,0x2c9bb7e,0x0347732,0x28016f8,0x0d6ff0d,\n        0x2a4877b,0x1d1e833,0x3b87e94,0x010e9dc } },\n    /* 20 */\n    { { 0x2b533d5,0x1ddcd34,0x1dc0625,0x3da86f7,0x3673b8a,0x1e7b0a4,\n        0x3e7c9aa,0x19ac55d,0x251c3b2,0x02edb79 },\n      { 0x25259b3,0x24c0ead,0x3480e7e,0x34f40e9,0x3d6a0af,0x2cf3f09,\n        0x2c83d19,0x2e66f16,0x19a5d18,0x0182d18 } },\n    /* 21 */\n    { { 0x2e5aa1c,0x28e3846,0x3658bd6,0x0ad279c,0x1b8b765,0x397e1fb,\n        0x130014e,0x3ff342c,0x3b2aeeb,0x02743c9 },\n      { 0x2730a55,0x0918c5e,0x083aca9,0x0bf76ef,0x19c955b,0x300669c,\n        0x01dfe0a,0x312341f,0x26d356e,0x0091295 } },\n    /* 22 */\n    { { 0x2cf1f96,0x00e52ba,0x271c6db,0x2a40930,0x19f2122,0x0b2f4ee,\n        0x26ac1b8,0x3bda498,0x0873581,0x0117963 },\n      { 0x38f9dbc,0x3d1e768,0x2040d3f,0x11ba222,0x3a8aaf1,0x1b82fb5,\n        0x1adfb24,0x2de9251,0x21cc1e4,0x0301038 } },\n    /* 23 */\n    { { 0x38117b6,0x2bc001b,0x1433847,0x3fdce8d,0x3651969,0x3651d7a,\n        0x2b35761,0x1bb1d20,0x097682c,0x00737d7 },\n      { 0x1f04839,0x1dd6d04,0x16987db,0x3d12378,0x17dbeac,0x1c2cc86,\n        0x121dd1b,0x3fcf6ca,0x1f8a92d,0x00119d5 } },\n    /* 24 */\n    { { 0x0e8ffcd,0x2b174af,0x1a82cc8,0x22cbf98,0x30d53c4,0x080b5b1,\n        0x3161727,0x297cfdb,0x2113b83,0x0011b97 },\n      { 0x0007f01,0x23fd936,0x3183e7b,0x0496bd0,0x07fb1ef,0x178680f,\n        0x1c5ea63,0x0016c11,0x2c3303d,0x01b8041 } },\n    /* 25 */\n    { { 0x0dd73b1,0x1cd6122,0x10d948c,0x23e657b,0x3767070,0x15a8aad,\n        0x385ea8c,0x33c7ce0,0x0ede901,0x0110965 },\n      { 0x2d4b65b,0x2a8b244,0x0c37f8f,0x0ee5b24,0x394c234,0x3a5e347,\n        0x26e4a15,0x39a3b4c,0x2514c2e,0x029e5be } },\n    /* 26 */\n    { { 0x23addd7,0x3ed8120,0x13b3359,0x20f959a,0x09e2a61,0x32fcf20,\n        0x05b78e3,0x19ba7e2,0x1a9c697,0x0392b4b },\n      { 0x2048a61,0x3dfd0a3,0x19a0357,0x233024b,0x3082d19,0x00fb63b,\n        0x3a1af4c,0x1450ff0,0x046c37b,0x0317a50 } },\n    /* 27 */\n    { { 0x3e75f9e,0x294e30a,0x3a78476,0x3a32c48,0x36fd1a9,0x0427012,\n        0x1e4df0b,0x11d1f61,0x1afdb46,0x018ca0f },\n      { 0x2f2df15,0x0a33dee,0x27f4ce7,0x1542b66,0x3e592c4,0x20d2f30,\n        0x3226ade,0x2a4e3ea,0x1ab1981,0x01a2f46 } },\n    /* 28 */\n    { { 0x087d659,0x3ab5446,0x305ac08,0x3d2cd64,0x33374d5,0x3f9d3f8,\n        0x186981c,0x37f5a5a,0x2f53c6f,0x01254a4 },\n      { 0x2cec896,0x1e32786,0x04844a8,0x043b16d,0x3d964b2,0x1935829,\n        0x16f7e26,0x1a0dd9a,0x30d2603,0x003b1d4 } },\n    /* 29 */\n    { { 0x12687bb,0x04e816b,0x21fa2da,0x1abccb8,0x3a1f83b,0x375181e,\n        0x0f5ef51,0x0fc2ce4,0x3a66486,0x003d881 },\n      { 0x3138233,0x1f8eec3,0x2718bd6,0x1b09caa,0x2dd66b9,0x1bb222b,\n        0x1004072,0x1b73e3b,0x07208ed,0x03fc36c } },\n    /* 30 */\n    { { 0x095d553,0x3e84053,0x0a8a749,0x3f575a0,0x3a44052,0x3ced59b,\n        0x3b4317f,0x03a8c60,0x13c8874,0x00c4ed4 },\n      { 0x0d11549,0x0b8ab02,0x221cb40,0x02ed37b,0x2071ee1,0x1fc8c83,\n        0x3987dd4,0x27e049a,0x0f986f1,0x00b4eaf } },\n    /* 31 */\n    { { 0x15581a2,0x2214060,0x11af4c2,0x1598c88,0x19a0a6d,0x32acba6,\n        0x3a7a0f0,0x2337c66,0x210ded9,0x0300dbe },\n      { 0x1fbd009,0x3822eb0,0x181629a,0x2401b45,0x30b68b1,0x2e78363,\n        0x2b32779,0x006530b,0x2c4b6d4,0x029aca8 } },\n    /* 32 */\n    { { 0x13549cf,0x0f943db,0x265ed43,0x1bfeb35,0x06f3369,0x3847f2d,\n        0x1bfdacc,0x26181a5,0x252af7c,0x02043b8 },\n      { 0x159bb2c,0x143f85c,0x357b654,0x2f9d62c,0x2f7dfbe,0x1a7fa9c,\n        0x057e74d,0x05d14ac,0x17a9273,0x035215c } },\n    /* 33 */\n    { { 0x0cb5a98,0x106a2bc,0x10bf117,0x24c7cc4,0x3d3da8f,0x2ce0ab7,\n        0x14e2cba,0x1813866,0x1a72f9a,0x01a9811 },\n      { 0x2b2411d,0x3034fe8,0x16e0170,0x0f9443a,0x0be0eb8,0x2196cf3,\n        0x0c9f738,0x15e40ef,0x0faf9e1,0x034f917 } },\n    /* 34 */\n    { { 0x03f7669,0x3da6efa,0x3d6bce1,0x209ca1d,0x109f8ae,0x09109e3,\n        0x08ae543,0x3067255,0x1dee3c2,0x0081dd5 },\n      { 0x3ef1945,0x358765b,0x28c387b,0x3bec4b4,0x218813c,0x0b7d92a,\n        0x3cd1d67,0x2c0367e,0x2e57154,0x0123717 } },\n    /* 35 */\n    { { 0x3e5a199,0x1e42ffd,0x0bb7123,0x33e6273,0x1e0efb8,0x294671e,\n        0x3a2bfe0,0x3d11709,0x2eddff6,0x03cbec2 },\n      { 0x0b5025f,0x0255d7c,0x1f2241c,0x35d03ea,0x0550543,0x202fef4,\n        0x23c8ad3,0x354963e,0x015db28,0x0284fa4 } },\n    /* 36 */\n    { { 0x2b65cbc,0x1e8d428,0x0226f9f,0x1c8a919,0x10b04b9,0x08fc1e8,\n        0x1ce241e,0x149bc99,0x2b01497,0x00afc35 },\n      { 0x3216fb7,0x1374fd2,0x226ad3d,0x19fef76,0x0f7d7b8,0x1c21417,\n        0x37b83f6,0x3a27eba,0x25a162f,0x010aa52 } },\n    /* 37 */\n    { { 0x2adf191,0x1ab42fa,0x28d7584,0x2409689,0x20f8a48,0x253707d,\n        0x2030504,0x378f7a1,0x169c65e,0x00b0b76 },\n      { 0x3849c17,0x085c764,0x10dd6d0,0x2e87689,0x1460488,0x30e9521,\n        0x10c7063,0x1b6f120,0x21f42c5,0x03d0dfe } },\n    /* 38 */\n    { { 0x20f7dab,0x035c512,0x29ac6aa,0x24c5ddb,0x20f0497,0x17ce5e1,\n        0x00a050f,0x1eaa14b,0x3335470,0x02abd16 },\n      { 0x18d364a,0x0df0cf0,0x316585e,0x018f925,0x0d40b9b,0x17b1511,\n        0x1716811,0x1caf3d0,0x10df4f2,0x0337d8c } },\n    /* 39 */\n    { { 0x2a8b7ef,0x0f188e3,0x2287747,0x06216f0,0x008e935,0x2f6a38d,\n        0x1567722,0x0bfc906,0x0bada9e,0x03c3402 },\n      { 0x014d3b1,0x099c749,0x2a76291,0x216c067,0x3b37549,0x14ef2f6,\n        0x21b96d4,0x1ee2d71,0x2f5ca88,0x016f570 } },\n    /* 40 */\n    { { 0x09a3154,0x3d1a7bd,0x2e9aef0,0x255b8ac,0x03e85a5,0x2a492a7,\n        0x2aec1ea,0x11c6516,0x3c8a09e,0x02a84b7 },\n      { 0x1f69f1d,0x09c89d3,0x1e7326f,0x0b28bfd,0x0e0e4c8,0x1ea7751,\n        0x18ce73b,0x2a406e7,0x273e48c,0x01b00db } },\n    /* 41 */\n    { { 0x36e3138,0x2b84a83,0x345a5cf,0x00096b4,0x16966ef,0x159caf1,\n        0x13c64b4,0x2f89226,0x25896af,0x00a4bfd },\n      { 0x2213402,0x1435117,0x09fed52,0x09d0e4b,0x0f6580e,0x2871cba,\n        0x3b397fd,0x1c9d825,0x090311b,0x0191383 } },\n    /* 42 */\n    { { 0x07153f0,0x1087869,0x18c9e1e,0x1e64810,0x2b86c3b,0x0175d9c,\n        0x3dce877,0x269de4e,0x393cab7,0x03c96b9 },\n      { 0x1869d0c,0x06528db,0x02641f3,0x209261b,0x29d55c8,0x25ba517,\n        0x3b5ea30,0x028f927,0x25313db,0x00e6e39 } },\n    /* 43 */\n    { { 0x2fd2e59,0x150802d,0x098f377,0x19a4957,0x135e2c0,0x38a95ce,\n        0x1ab21a0,0x36c1b67,0x32f0f19,0x00e448b },\n      { 0x3cad53c,0x3387800,0x17e3cfb,0x03f9970,0x3225b2c,0x2a84e1d,\n        0x3af1d29,0x3fe35ca,0x2f8ce80,0x0237a02 } },\n    /* 44 */\n    { { 0x07bbb76,0x3aa3648,0x2758afb,0x1f085e0,0x1921c7e,0x3010dac,\n        0x22b74b1,0x230137e,0x1062e36,0x021c652 },\n      { 0x3993df5,0x24a2ee8,0x126ab5f,0x2d7cecf,0x0639d75,0x16d5414,\n        0x1aa78a8,0x3f78404,0x26a5b74,0x03f0c57 } },\n    /* 45 */\n    { { 0x0d6ecfa,0x3f506ba,0x3f86561,0x3d86bb1,0x15f8c44,0x2491d07,\n        0x052a7b4,0x2422261,0x3adee38,0x039b529 },\n      { 0x193c75d,0x14bb451,0x1162605,0x293749c,0x370a70d,0x2e8b1f6,\n        0x2ede937,0x2b95f4a,0x39a9be2,0x00d77eb } },\n    /* 46 */\n    { { 0x2736636,0x15bf36a,0x2b7e6b9,0x25eb8b2,0x209f51d,0x3cd2659,\n        0x10bf410,0x034afec,0x3d71c83,0x0076971 },\n      { 0x0ce6825,0x07920cf,0x3c3b5c4,0x23fe55c,0x015ad11,0x08c0dae,\n        0x0552c7f,0x2e75a8a,0x0fddbf4,0x01c1df0 } },\n    /* 47 */\n    { { 0x2b9661c,0x0ffe351,0x3d71bf6,0x1ac34b3,0x3a1dfd3,0x211fe3d,\n        0x33e140a,0x3f9100d,0x32ee50e,0x014ea18 },\n      { 0x16d8051,0x1bfda1a,0x068a097,0x2571d3d,0x1daec0c,0x39389af,\n        0x194dc35,0x3f3058a,0x36d34e1,0x000a329 } },\n    /* 48 */\n    { { 0x09877ee,0x351f73f,0x0002d11,0x0420074,0x2c8b362,0x130982d,\n        0x02c1175,0x3c11b40,0x0d86962,0x001305f },\n      { 0x0daddf5,0x2f4252c,0x15c06d9,0x1d49339,0x1bea235,0x0b680ed,\n        0x3356e67,0x1d1d198,0x1e9fed9,0x03dee93 } },\n    /* 49 */\n    { { 0x3e1263f,0x2fe8d3a,0x3ce6d0d,0x0d5c6b9,0x3557637,0x0a9bd48,\n        0x0405538,0x0710749,0x2005213,0x038c7e5 },\n      { 0x26b6ec6,0x2e485ba,0x3c44d1b,0x0b9cf0b,0x037a1d1,0x27428a5,\n        0x0e7eac8,0x351ef04,0x259ce34,0x02a8e98 } },\n    /* 50 */\n    { { 0x2f3dcd3,0x3e77d4d,0x3360fbc,0x1434afd,0x36ceded,0x3d413d6,\n        0x1710fad,0x36bb924,0x1627e79,0x008e637 },\n      { 0x109569e,0x1c168db,0x3769cf4,0x2ed4527,0x0ea0619,0x17d80d3,\n        0x1c03773,0x18843fe,0x1b21c04,0x015c5fd } },\n    /* 51 */\n    { { 0x1dd895e,0x08a7248,0x04519fe,0x001030a,0x18e5185,0x358dfb3,\n        0x13d2391,0x0a37be8,0x0560e3c,0x019828b },\n      { 0x27fcbd0,0x2a22bb5,0x30969cc,0x1e03aa7,0x1c84724,0x0ba4ad3,\n        0x32f4817,0x0914cca,0x14c4f52,0x01893b9 } },\n    /* 52 */\n    { { 0x097eccc,0x1273936,0x00aa095,0x364fe62,0x04d49d1,0x10e9f08,\n        0x3c24230,0x3ef01c8,0x2fb92bd,0x013ce4a },\n      { 0x1e44fd9,0x27e3e9f,0x2156696,0x3915ecc,0x0b66cfb,0x1a3af0f,\n        0x2fa8033,0x0e6736c,0x177ccdb,0x0228f9e } },\n    /* 53 */\n    { { 0x2c4b125,0x06207c1,0x0a8cdde,0x003db8f,0x1ae34e3,0x31e84fa,\n        0x2999de5,0x11013bd,0x02370c2,0x00e2234 },\n      { 0x0f91081,0x200d591,0x1504762,0x1857c05,0x23d9fcf,0x0cb34db,\n        0x27edc86,0x08cd860,0x2471810,0x029798b } },\n    /* 54 */\n    { { 0x3acd6c8,0x097b8cb,0x3c661a8,0x15152f2,0x1699c63,0x237e64c,\n        0x23edf79,0x16b7033,0x0e6466a,0x00b11da },\n      { 0x0a64bc9,0x1bfe324,0x1f5cb34,0x08391de,0x0630a60,0x3017a21,\n        0x09d064b,0x14a8365,0x041f9e6,0x01ed799 } },\n    /* 55 */\n    { { 0x128444a,0x2508b07,0x2a39216,0x362f84d,0x2e996c5,0x2c31ff3,\n        0x07afe5f,0x1d1288e,0x3cb0c8d,0x02e2bdc },\n      { 0x38b86fd,0x3a0ea8c,0x1cff5fd,0x1629629,0x3fee3f1,0x02b250c,\n        0x2e8f6f2,0x0225727,0x15f7f3f,0x0280d8e } },\n    /* 56 */\n    { { 0x10f7770,0x0f1aee8,0x0e248c7,0x20684a8,0x3a6f16d,0x06f0ae7,\n        0x0df6825,0x2d4cc40,0x301875f,0x012f8da },\n      { 0x3b56dbb,0x1821ba7,0x24f8922,0x22c1f9e,0x0306fef,0x1b54bc8,\n        0x2ccc056,0x00303ba,0x2871bdc,0x0232f26 } },\n    /* 57 */\n    { { 0x0dac4ab,0x0625730,0x3112e13,0x101c4bf,0x3a874a4,0x2873b95,\n        0x32ae7c6,0x0d7e18c,0x13e0c08,0x01139d5 },\n      { 0x334002d,0x00fffdd,0x025c6d5,0x22c2cd1,0x19d35cb,0x3a1ce2d,\n        0x3702760,0x3f06257,0x03a5eb8,0x011c29a } },\n    /* 58 */\n    { { 0x0513482,0x1d87724,0x276a81b,0x0a807a4,0x3028720,0x339cc20,\n        0x2441ee0,0x31bbf36,0x290c63d,0x0059041 },\n      { 0x106a2ed,0x0d2819b,0x100bf50,0x114626c,0x1dd4d77,0x2e08632,\n        0x14ae72a,0x2ed3f64,0x1fd7abc,0x035cd1e } },\n    /* 59 */\n    { { 0x2d4c6e5,0x3bec596,0x104d7ed,0x23d6c1b,0x0262cf0,0x15d72c5,\n        0x2d5bb18,0x199ac4b,0x1e30771,0x020591a },\n      { 0x21e291e,0x2e75e55,0x1661d7a,0x08b0778,0x3eb9daf,0x0d78144,\n        0x1827eb1,0x0fe73d2,0x123f0dd,0x0028db7 } },\n    /* 60 */\n    { { 0x1d5533c,0x34cb1d0,0x228f098,0x27a1a11,0x17c5f5a,0x0d26f44,\n        0x2228ade,0x2c460e6,0x3d6fdba,0x038cc77 },\n      { 0x3cc6ed8,0x02ada1a,0x260e510,0x2f7bde8,0x37160c3,0x33a1435,\n        0x23d9a7b,0x0ce2641,0x02a492e,0x034ed1e } },\n    /* 61 */\n    { { 0x3821f90,0x26dba3c,0x3aada14,0x3b59bad,0x292edd9,0x2804c45,\n        0x3669531,0x296f42e,0x35a4c86,0x01ca049 },\n      { 0x3ff47e5,0x2163df4,0x2441503,0x2f18405,0x15e1616,0x37f66ec,\n        0x30f11a7,0x141658a,0x27ece14,0x00b018b } },\n    /* 62 */\n    { { 0x159ac2e,0x3e65bc0,0x2713a76,0x0db2f6c,0x3281e77,0x2391811,\n        0x16d2880,0x1fbc4ab,0x1f92c4e,0x00a0a8d },\n      { 0x0ce5cd2,0x152c7b0,0x02299c3,0x3244de7,0x2cf99ef,0x3a0b047,\n        0x2caf383,0x0aaf664,0x113554d,0x031c735 } },\n    /* 63 */\n    { { 0x1b578f4,0x177a702,0x3a7a488,0x1638ebf,0x31884e2,0x2460bc7,\n        0x36b1b75,0x3ce8e3d,0x340cf47,0x03143d9 },\n      { 0x34b68ea,0x12b7ccd,0x1fe2a9c,0x08da659,0x0a406f3,0x1694c14,\n        0x06a2228,0x16370be,0x3a72129,0x02e7b2c } },\n    /* 64 */\n    { { 0x0f8b16a,0x21043bd,0x266a56f,0x3fb11ec,0x197241a,0x36721f0,\n        0x006b8e6,0x2ac6c29,0x202cd42,0x0200fcf },\n      { 0x0dbec69,0x0c26a01,0x105f7f0,0x3dceeeb,0x3a83b85,0x363865f,\n        0x097273a,0x2b70718,0x00e5067,0x03025d1 } },\n    /* 65 */\n    { { 0x379ab34,0x295bcb0,0x38d1846,0x22e1077,0x3a8ee06,0x1db1a3b,\n        0x3144591,0x07cc080,0x2d5915f,0x03c6bcc },\n      { 0x175bd50,0x0dd4c57,0x27bc99c,0x2ebdcbd,0x3837cff,0x235dc8f,\n        0x13a4184,0x0722c18,0x130e2d4,0x008f43c } },\n    /* 66 */\n    { { 0x01500d9,0x2adbb7d,0x2da8857,0x397f2fa,0x10d890a,0x25c9654,\n        0x3e86488,0x3eb754b,0x1d6c0a3,0x02c0a23 },\n      { 0x10bcb08,0x083cc19,0x2e16853,0x04da575,0x271af63,0x2626a9d,\n        0x3520a7b,0x32348c7,0x24ff408,0x03ff4dc } },\n    /* 67 */\n    { { 0x058e6cb,0x1a3992d,0x1d28539,0x080c5e9,0x2992dad,0x2a9d7d5,\n        0x14ae0b7,0x09b7ce0,0x34ad78c,0x03d5643 },\n      { 0x30ba55a,0x092f4f3,0x0bae0fc,0x12831de,0x20fc472,0x20ed9d2,\n        0x29864f6,0x1288073,0x254f6f7,0x00635b6 } },\n    /* 68 */\n    { { 0x1be5a2b,0x0f88975,0x33c6ed9,0x20d64d3,0x06fe799,0x0989bff,\n        0x1409262,0x085a90c,0x0d97990,0x0142eed },\n      { 0x17ec63e,0x06471b9,0x0db2378,0x1006077,0x265422c,0x08db83d,\n        0x28099b0,0x1270d06,0x11801fe,0x00ac400 } },\n    /* 69 */\n    { { 0x3391593,0x22d7166,0x30fcfc6,0x2896609,0x3c385f5,0x066b72e,\n        0x04f3aad,0x2b831c5,0x19983fb,0x0375562 },\n      { 0x0b82ff4,0x222e39d,0x34c993b,0x101c79c,0x2d2e03c,0x0f00c8a,\n        0x3a9eaf4,0x1810669,0x151149d,0x039b931 } },\n    /* 70 */\n    { { 0x29af288,0x1956ec7,0x293155f,0x193deb6,0x1647e1a,0x2ca0839,\n        0x297e4bc,0x15bfd0d,0x1b107ed,0x0147803 },\n      { 0x31c327e,0x05a6e1d,0x02ad43d,0x02d2a5b,0x129cdb2,0x37ad1de,\n        0x3d51f53,0x245df01,0x2414982,0x0388bd0 } },\n    /* 71 */\n    { { 0x35f1abb,0x17a3d18,0x0874cd4,0x2d5a14e,0x17edc0c,0x16a00d3,\n        0x072c1fb,0x1232725,0x33d52dc,0x03dc24d },\n      { 0x0af30d6,0x259aeea,0x369c401,0x12bc4de,0x295bf5f,0x0d8711f,\n        0x26162a9,0x16c44e5,0x288e727,0x02f54b4 } },\n    /* 72 */\n    { { 0x05fa877,0x1571ea7,0x3d48ab1,0x1c9f4e8,0x017dad6,0x0f46276,\n        0x343f9e7,0x1de990f,0x0e4c8aa,0x028343e },\n      { 0x094f92d,0x3abf633,0x1b3a0bb,0x2f83137,0x0d818c8,0x20bae85,\n        0x0c65f8b,0x1a8008b,0x0c7946d,0x0295b1e } },\n    /* 73 */\n    { { 0x1d09529,0x08e46c3,0x1fcf296,0x298f6b7,0x1803e0e,0x2d6fd20,\n        0x37351f5,0x0d9e8b1,0x1f8731a,0x0362fbf },\n      { 0x00157f4,0x06750bf,0x2650ab9,0x35ffb23,0x2f51cae,0x0b522c2,\n        0x39cb400,0x191e337,0x0a5ce9f,0x021529a } },\n    /* 74 */\n    { { 0x3506ea5,0x17d9ed8,0x0d66dc3,0x22693f8,0x19286c4,0x3a57353,\n        0x101d3bf,0x1aa54fc,0x20b9884,0x0172b3a },\n      { 0x0eac44d,0x37d8327,0x1c3aa90,0x3d0d534,0x23db29a,0x3576eaf,\n        0x1d3de8a,0x3bea423,0x11235e4,0x039260b } },\n    /* 75 */\n    { { 0x34cd55e,0x01288b0,0x1132231,0x2cc9a03,0x358695b,0x3e87650,\n        0x345afa1,0x01267ec,0x3f616b2,0x02011ad },\n      { 0x0e7d098,0x0d6078e,0x0b70b53,0x237d1bc,0x0d7f61e,0x132de31,\n        0x1ea9ea4,0x2bd54c3,0x27b9082,0x03ac5f2 } },\n    /* 76 */\n    { { 0x2a145b9,0x06d661d,0x31ec175,0x03f06f1,0x3a5cf6b,0x249c56e,\n        0x2035653,0x384c74f,0x0bafab5,0x0025ec0 },\n      { 0x25f69e1,0x1b23a55,0x1199aa6,0x16ad6f9,0x077e8f7,0x293f661,\n        0x33ba11d,0x3327980,0x07bafdb,0x03e571d } },\n    /* 77 */\n    { { 0x2bae45e,0x3c074ef,0x2955558,0x3c312f1,0x2a8ebe9,0x2f193f1,\n        0x3705b1d,0x360deba,0x01e566e,0x00d4498 },\n      { 0x21161cd,0x1bc787e,0x2f87933,0x3553197,0x1328ab8,0x093c879,\n        0x17eee27,0x2adad1d,0x1236068,0x003be5c } },\n    /* 78 */\n    { { 0x0ca4226,0x2633dd5,0x2c8e025,0x0e3e190,0x05eede1,0x1a385e4,\n        0x163f744,0x2f25522,0x1333b4f,0x03f05b6 },\n      { 0x3c800ca,0x1becc79,0x2daabe9,0x0c499e2,0x1138063,0x3fcfa2d,\n        0x2244976,0x1e85cf5,0x2f1b95d,0x0053292 } },\n    /* 79 */\n    { { 0x12f81d5,0x1dc6eaf,0x11967a4,0x1a407df,0x31a5f9d,0x2b67241,\n        0x18bef7c,0x08c7762,0x063f59c,0x01015ec },\n      { 0x1c05c0a,0x360bfa2,0x1f85bff,0x1bc7703,0x3e4911c,0x0d685b6,\n        0x2fccaea,0x02c4cef,0x164f133,0x0070ed7 } },\n    /* 80 */\n    { { 0x0ec21fe,0x052ffa0,0x3e825fe,0x1ab0956,0x3f6ce11,0x3d29759,\n        0x3c5a072,0x18ebe62,0x148db7e,0x03eb49c },\n      { 0x1ab05b3,0x02dab0a,0x1ae690c,0x0f13894,0x137a9a8,0x0aab79f,\n        0x3dc875c,0x06a1029,0x1e39f0e,0x01dce1f } },\n    /* 81 */\n    { { 0x16c0dd7,0x3b31269,0x2c741e9,0x3611821,0x2a5cffc,0x1416bb3,\n        0x3a1408f,0x311fa3d,0x1c0bef0,0x02cdee1 },\n      { 0x00e6a8f,0x1adb933,0x0f23359,0x2fdace2,0x2fd6d4b,0x0e73bd3,\n        0x2453fac,0x0a356ae,0x2c8f9f6,0x02704d6 } },\n    /* 82 */\n    { { 0x0e35743,0x28c80a1,0x0def32a,0x2c6168f,0x1320d6a,0x37c6606,\n        0x21b1761,0x2147ee0,0x21fc433,0x015c84d },\n      { 0x1fc9168,0x36cda9c,0x003c1f0,0x1cd7971,0x15f98ba,0x1ef363d,\n        0x0ca87e3,0x046f7d9,0x3c9e6bb,0x0372eb0 } },\n    /* 83 */\n    { { 0x118cbe2,0x3665a11,0x304ef01,0x062727a,0x3d242fc,0x11ffbaf,\n        0x3663c7e,0x1a189c9,0x09e2d62,0x02e3072 },\n      { 0x0e1d569,0x162f772,0x0cd051a,0x322df62,0x3563809,0x047cc7a,\n        0x027fd9f,0x08b509b,0x3da2f94,0x01748ee } },\n    /* 84 */\n    { { 0x1c8f8be,0x31ca525,0x22bf0a1,0x200efcd,0x02961c4,0x3d8f52b,\n        0x018403d,0x3a40279,0x1cb91ec,0x030427e },\n      { 0x0945705,0x0257416,0x05c0c2d,0x25b77ae,0x3b9083d,0x2901126,\n        0x292b8d7,0x07b8611,0x04f2eee,0x026f0cd } },\n    /* 85 */\n    { { 0x2913074,0x2b8d590,0x02b10d5,0x09d2295,0x255491b,0x0c41cca,\n        0x1ca665b,0x133051a,0x1525f1a,0x00a5647 },\n      { 0x04f983f,0x3d6daee,0x04e1e76,0x1067d7e,0x1be7eef,0x02ea862,\n        0x00d4968,0x0ccb048,0x11f18ef,0x018dd95 } },\n    /* 86 */\n    { { 0x22976cc,0x17c5395,0x2c38bda,0x3983bc4,0x222bca3,0x332a614,\n        0x3a30646,0x261eaef,0x1c808e2,0x02f6de7 },\n      { 0x306a772,0x32d7272,0x2dcefd2,0x2abf94d,0x038f475,0x30ad76e,\n        0x23e0227,0x3052b0a,0x001add3,0x023ba18 } },\n    /* 87 */\n    { { 0x0ade873,0x25a6069,0x248ccbe,0x13713ee,0x17ee9aa,0x28152e9,\n        0x2e28995,0x2a92cb3,0x17a6f77,0x024b947 },\n      { 0x190a34d,0x2ebea1c,0x1ed1948,0x16fdaf4,0x0d698f7,0x32bc451,\n        0x0ee6e30,0x2aaab40,0x06f0a56,0x01460be } },\n    /* 88 */\n    { { 0x24cc99c,0x1884b1e,0x1ca1fba,0x1a0f9b6,0x2ff609b,0x2b26316,\n        0x3b27cb5,0x29bc976,0x35d4073,0x024772a },\n      { 0x3575a70,0x1b30f57,0x07fa01b,0x0e5be36,0x20cb361,0x26605cd,\n        0x1d4e8c8,0x13cac59,0x2db9797,0x005e833 } },\n    /* 89 */\n    { { 0x36c8d3a,0x1878a81,0x124b388,0x0e4843e,0x1701aad,0x0ea0d76,\n        0x10eae41,0x37d0653,0x36c7f4c,0x00ba338 },\n      { 0x37a862b,0x1cf6ac0,0x08fa912,0x2dd8393,0x101ba9b,0x0eebcb7,\n        0x2453883,0x1a3cfe5,0x2cb34f6,0x03d3331 } },\n    /* 90 */\n    { { 0x1f79687,0x3d4973c,0x281544e,0x2564bbe,0x17c5954,0x171e34a,\n        0x231741a,0x3cf2784,0x0889a0d,0x02b036d },\n      { 0x301747f,0x3f1c477,0x1f1386b,0x163bc5f,0x1592b93,0x332daed,\n        0x080e4f5,0x1d28b96,0x26194c9,0x0256992 } },\n    /* 91 */\n    { { 0x15a4c93,0x07bf6b0,0x114172c,0x1ce0961,0x140269b,0x1b2c2eb,\n        0x0dfb1c1,0x019ddaa,0x0ba2921,0x008c795 },\n      { 0x2e6d2dc,0x37e45e2,0x2918a70,0x0fce444,0x34d6aa6,0x396dc88,\n        0x27726b5,0x0c787d8,0x032d8a7,0x02ac2f8 } },\n    /* 92 */\n    { { 0x1131f2d,0x2b43a63,0x3101097,0x38cec13,0x0637f09,0x17a69d2,\n        0x086196d,0x299e46b,0x0802cf6,0x03c6f32 },\n      { 0x0daacb4,0x1a4503a,0x100925c,0x15583d9,0x23c4e40,0x1de4de9,\n        0x1cc8fc4,0x2c9c564,0x0695aeb,0x02145a5 } },\n    /* 93 */\n    { { 0x1dcf593,0x17050fc,0x3e3bde3,0x0a6c062,0x178202b,0x2f7674f,\n        0x0dadc29,0x15763a7,0x1d2daad,0x023d9f6 },\n      { 0x081ea5f,0x045959d,0x190c841,0x3a78d31,0x0e7d2dd,0x1414fea,\n        0x1d43f40,0x22d77ff,0x2b9c072,0x03e115c } },\n    /* 94 */\n    { { 0x3af71c9,0x29e9c65,0x25655e1,0x111e9cd,0x3a14494,0x3875418,\n        0x34ae070,0x0b06686,0x310616b,0x03b7b89 },\n      { 0x1734121,0x00d3d44,0x29f0b2f,0x1552897,0x31cac6e,0x1030bb3,\n        0x0148f3a,0x35fd237,0x29b44eb,0x027f49f } },\n    /* 95 */\n    { { 0x2e2cb16,0x1d962bd,0x19b63cc,0x0b3f964,0x3e3eb7d,0x1a35560,\n        0x0c58161,0x3ce1d6a,0x3b6958f,0x029030b },\n      { 0x2dcc158,0x3b1583f,0x30568c9,0x31957c8,0x27ad804,0x28c1f84,\n        0x3967049,0x37b3f64,0x3b87dc6,0x0266f26 } },\n    /* 96 */\n    { { 0x27dafc6,0x2548764,0x0d1984a,0x1a57027,0x252c1fb,0x24d9b77,\n        0x1581a0f,0x1f99276,0x10ba16d,0x026af88 },\n      { 0x0915220,0x2be1292,0x16c6480,0x1a93760,0x2fa7317,0x1a07296,\n        0x1539871,0x112c31f,0x25787f3,0x01e2070 } },\n    /* 97 */\n    { { 0x0bcf3ff,0x266d478,0x34f6933,0x31449fd,0x00d02cb,0x340765a,\n        0x3465a2d,0x225023e,0x319a30e,0x00579b8 },\n      { 0x20e05f4,0x35b834f,0x0404646,0x3710d62,0x3fad7bd,0x13e1434,\n        0x21c7d1c,0x1cb3af9,0x2cf1911,0x003957e } },\n    /* 98 */\n    { { 0x0787564,0x36601be,0x1ce67e9,0x084c7a1,0x21a3317,0x2067a35,\n        0x0158cab,0x195ddac,0x1766fe9,0x035cf42 },\n      { 0x2b7206e,0x20d0947,0x3b42424,0x03f1862,0x0a51929,0x38c2948,\n        0x0bb8595,0x2942d77,0x3748f15,0x0249428 } },\n    /* 99 */\n    { { 0x2577410,0x3c23e2f,0x28c6caf,0x00d41de,0x0fd408a,0x30298e9,\n        0x363289e,0x2302fc7,0x082c1cc,0x01dd050 },\n      { 0x30991cd,0x103e9ba,0x029605a,0x19927f7,0x0c1ca08,0x0c93f50,\n        0x28a3c7b,0x082e4e9,0x34d12eb,0x0232c13 } },\n    /* 100 */\n    { { 0x106171c,0x0b4155a,0x0c3fb1c,0x336c090,0x19073e9,0x2241a10,\n        0x0e6b4fd,0x0ed476e,0x1ef4712,0x039390a },\n      { 0x0ec36f4,0x3754f0e,0x2a270b8,0x007fd2d,0x0f9d2dc,0x1e6a692,\n        0x066e078,0x1954974,0x2ff3c6e,0x00def28 } },\n    /* 101 */\n    { { 0x3562470,0x0b8f1f7,0x0ac94cd,0x28b0259,0x244f272,0x031e4ef,\n        0x2d5df98,0x2c8a9f1,0x2dc3002,0x016644f },\n      { 0x350592a,0x0e6a0d5,0x1e027a1,0x2039e0f,0x399e01d,0x2817593,\n        0x0c0375e,0x3889b3e,0x24ab013,0x010de1b } },\n    /* 102 */\n    { { 0x256b5a6,0x0ac3b67,0x28f9ff3,0x29b67f1,0x30750d9,0x25e11a9,\n        0x15e8455,0x279ebb0,0x298b7e7,0x0218e32 },\n      { 0x2fc24b2,0x2b82582,0x28f22f5,0x2bd36b3,0x305398e,0x3b2e9e3,\n        0x365dd0a,0x29bc0ed,0x36a7b3a,0x007b374 } },\n    /* 103 */\n    { { 0x05ff2f3,0x2b3589b,0x29785d3,0x300a1ce,0x0a2d516,0x0844355,\n        0x14c9fad,0x3ccb6b6,0x385d459,0x0361743 },\n      { 0x0b11da3,0x002e344,0x18c49f7,0x0c29e0c,0x1d2c22c,0x08237b3,\n        0x2988f49,0x0f18955,0x1c3b4ed,0x02813c6 } },\n    /* 104 */\n    { { 0x17f93bd,0x249323b,0x11f6087,0x174e4bd,0x3cb64ac,0x086dc6b,\n        0x2e330a8,0x142c1f2,0x2ea5c09,0x024acbb },\n      { 0x1b6e235,0x3132521,0x00f085a,0x2a4a4db,0x1ab2ca4,0x0142224,\n        0x3aa6b3e,0x09db203,0x2215834,0x007b9e0 } },\n    /* 105 */\n    { { 0x23e79f7,0x28b8039,0x1906a60,0x2cbce67,0x1f590e7,0x181f027,\n        0x21054a6,0x3854240,0x2d857a6,0x03cfcb3 },\n      { 0x10d9b55,0x1443cfc,0x2648200,0x2b36190,0x09d2fcf,0x22f439f,\n        0x231aa7e,0x3884395,0x0543da3,0x003d5a9 } },\n    /* 106 */\n    { { 0x043e0df,0x06ffe84,0x3e6d5b2,0x3327001,0x26c74b6,0x12a145e,\n        0x256ec0d,0x3898c69,0x3411969,0x02f63c5 },\n      { 0x2b7494a,0x2eee1af,0x38388a9,0x1bd17ce,0x21567d4,0x13969e6,\n        0x3a12a7a,0x3e8277d,0x03530cc,0x00b4687 } },\n    /* 107 */\n    { { 0x06508da,0x38e04d4,0x15a7192,0x312875e,0x3336180,0x2a6512c,\n        0x1b59497,0x2e91b37,0x25eb91f,0x02841e9 },\n      { 0x394d639,0x0747143,0x37d7e6d,0x1d62962,0x08b4af3,0x34df287,\n        0x3c5584b,0x26bc869,0x20af87a,0x0060f5d } },\n    /* 108 */\n    { { 0x1de59a4,0x1a5c443,0x2f8729d,0x01c3a2f,0x0f1ad8d,0x3cbaf9e,\n        0x1b49634,0x35d508a,0x39dc269,0x0075105 },\n      { 0x390d30e,0x37033e0,0x110cb32,0x14c37a0,0x20a3b27,0x2f00ce6,\n        0x2f1dc52,0x34988c6,0x0c29606,0x01dc7e7 } },\n    /* 109 */\n    { { 0x1040739,0x24f9de1,0x2939999,0x2e6009a,0x244539d,0x17e3f09,\n        0x00f6f2f,0x1c63b3d,0x2310362,0x019109e },\n      { 0x1428aa8,0x3cb61e1,0x09a84f4,0x0ffafed,0x07b7adc,0x08f406b,\n        0x1b2c6df,0x035b480,0x3496ae9,0x012766d } },\n    /* 110 */\n    { { 0x35d1099,0x2362f10,0x1a08cc7,0x13a3a34,0x12adbcd,0x32da290,\n        0x02e2a02,0x151140b,0x01b3f60,0x0240df6 },\n      { 0x34c7b61,0x2eb09c1,0x172e7cd,0x2ad5eff,0x2fe2031,0x25b54d4,\n        0x0cec965,0x18e7187,0x26a7cc0,0x00230f7 } },\n    /* 111 */\n    { { 0x2d552ab,0x374083d,0x01f120f,0x2601736,0x156baff,0x04d44a4,\n        0x3b7c3e9,0x1acbc1b,0x0424579,0x031a425 },\n      { 0x1231bd1,0x0eba710,0x020517b,0x21d7316,0x21eac6e,0x275a848,\n        0x0837abf,0x0eb0082,0x302cafe,0x00fe8f6 } },\n    /* 112 */\n    { { 0x1058880,0x28f9941,0x03f2d75,0x3bd90e5,0x17da365,0x2ac9249,\n        0x07861cf,0x023fd05,0x1b0fdb8,0x031712f },\n      { 0x272b56b,0x04f8d2c,0x043a735,0x25446e4,0x1c8327e,0x221125a,\n        0x0ce37df,0x2dad7f6,0x39446c2,0x00b55b6 } },\n    /* 113 */\n    { { 0x346ac6b,0x05e0bff,0x2425246,0x0981e8b,0x1d19f79,0x2692378,\n        0x3ea3c40,0x2e90beb,0x19de503,0x003d5af },\n      { 0x05cda49,0x353b44d,0x299d137,0x3f205bc,0x2821158,0x3ad0d00,\n        0x06a54aa,0x2d7c79f,0x39d1173,0x01000ee } },\n    /* 114 */\n    { { 0x0803387,0x3a06268,0x14043b8,0x3d4e72f,0x1ece115,0x0a1dfc8,\n        0x17208dd,0x0be790a,0x122a07f,0x014dd95 },\n      { 0x0a4182d,0x202886a,0x1f79a49,0x1e8c867,0x0a2bbd0,0x28668b5,\n        0x0d0a2e1,0x115259d,0x3586c5d,0x01e815b } },\n    /* 115 */\n    { { 0x18a2a47,0x2c95627,0x2773646,0x1230f7c,0x15b5829,0x2fc354e,\n        0x2c000ea,0x099d547,0x2f17a1a,0x01df520 },\n      { 0x3853948,0x06f6561,0x3feeb8a,0x2f5b3ef,0x3a6f817,0x01a0791,\n        0x2ec0578,0x2c392ad,0x12b2b38,0x0104540 } },\n    /* 116 */\n    { { 0x1e28ced,0x0fc3d1b,0x2c473c7,0x1826c4f,0x21d5da7,0x39718e4,\n        0x38ce9e6,0x0251986,0x172fbea,0x0337c11 },\n      { 0x053c3b0,0x0f162db,0x043c1cb,0x04111ee,0x297fe3c,0x32e5e03,\n        0x2b8ae12,0x0c427ec,0x1da9738,0x03b9c0f } },\n    /* 117 */\n    { { 0x357e43a,0x054503f,0x11b8345,0x34ec6e0,0x2d44660,0x3d0ae61,\n        0x3b5dff8,0x33884ac,0x09da162,0x00a82b6 },\n      { 0x3c277ba,0x129a51a,0x027664e,0x1530507,0x0c788c9,0x2afd89d,\n        0x1aa64cc,0x1196450,0x367ac2b,0x0358b42 } },\n    /* 118 */\n    { { 0x0054ac4,0x1761ecb,0x378839c,0x167c9f7,0x2570058,0x0604a35,\n        0x37cbf3b,0x0909bb7,0x3f2991c,0x02ce688 },\n      { 0x0b16ae5,0x212857c,0x351b952,0x2c684db,0x30c6a05,0x09c01e0,\n        0x23c137f,0x1331475,0x092c067,0x0013b40 } },\n    /* 119 */\n    { { 0x2e90393,0x0617466,0x24e61f4,0x0a528f5,0x03047b4,0x2153f05,\n        0x0001a69,0x30e1eb8,0x3c10177,0x0282a47 },\n      { 0x22c831e,0x28fc06b,0x3e16ff0,0x208adc9,0x0bb76ae,0x28c1d6d,\n        0x12c8a15,0x031063c,0x1889ed2,0x002133e } },\n    /* 120 */\n    { { 0x0a6becf,0x14277bf,0x3328d98,0x201f7fe,0x12fceae,0x1de3a2e,\n        0x0a15c44,0x3ddf976,0x1b273ab,0x0355e55 },\n      { 0x1b5d4f1,0x369e78c,0x3a1c210,0x12cf3e9,0x3aa52f0,0x309f082,\n        0x112089d,0x107c753,0x24202d1,0x023853a } },\n    /* 121 */\n    { { 0x2897042,0x140d17c,0x2c4aeed,0x07d0d00,0x18d0533,0x22f7ec8,\n        0x19c194c,0x3456323,0x2372aa4,0x0165f86 },\n      { 0x30bd68c,0x1fb06b3,0x0945032,0x372ac09,0x06d4be0,0x27f8fa1,\n        0x1c8d7ac,0x137a96e,0x236199b,0x0328fc0 } },\n    /* 122 */\n    { { 0x170bd20,0x2842d58,0x1de7592,0x3c5b4fd,0x20ea897,0x12cab78,\n        0x363ff14,0x01f928c,0x17e309c,0x02f79ff },\n      { 0x0f5432c,0x2edb4ae,0x044b516,0x32f810d,0x2210dc1,0x23e56d6,\n        0x301e6ff,0x34660f6,0x10e0a7d,0x02d88eb } },\n    /* 123 */\n    { { 0x0c7b65b,0x2f59d58,0x2289a75,0x2408e92,0x1ab8c55,0x1ec99e5,\n        0x220fd0d,0x04defe0,0x24658ec,0x035aa8b },\n      { 0x138bb85,0x2f002d4,0x295c10a,0x08760ce,0x28c31d1,0x1c0a8cb,\n        0x0ff00b1,0x144eac9,0x2e02dcc,0x0044598 } },\n    /* 124 */\n    { { 0x3b42b87,0x050057b,0x0dff781,0x1c06db1,0x1bd9f5d,0x1f5f04a,\n        0x2cccd7a,0x143e19b,0x1cb94b7,0x036cfb8 },\n      { 0x34837cf,0x3cf6c3c,0x0d4fb26,0x22ee55e,0x1e7eed1,0x315995f,\n        0x2cdf937,0x1a96574,0x0425220,0x0221a99 } },\n    /* 125 */\n    { { 0x1b569ea,0x0d33ed9,0x19c13c2,0x107dc84,0x2200111,0x0569867,\n        0x2dc85da,0x05ef22e,0x0eb018a,0x029c33d },\n      { 0x04a6a65,0x3e5eba3,0x378f224,0x09c04d0,0x036e5cf,0x3df8258,\n        0x3a609e4,0x1eddef8,0x2abd174,0x02a91dc } },\n    /* 126 */\n    { { 0x2a60cc0,0x1d84c5e,0x115f676,0x1840da0,0x2c79163,0x2f06ed6,\n        0x198bb4b,0x3e5d37b,0x1dc30fa,0x018469b },\n      { 0x15ee47a,0x1e32f30,0x16a530e,0x2093836,0x02e8962,0x3767b62,\n        0x335adf3,0x27220db,0x2f81642,0x0173ffe } },\n    /* 127 */\n    { { 0x37a99cd,0x1533fe6,0x05a1c0d,0x27610f1,0x17bf3b9,0x0b1ce78,\n        0x0a908f6,0x265300e,0x3237dc1,0x01b969a },\n      { 0x3a5db77,0x2d15382,0x0d63ef8,0x1feb3d8,0x0b7b880,0x19820de,\n        0x11c0c67,0x2af3396,0x38d242d,0x0120688 } },\n    /* 128 */\n    { { 0x1d0b34a,0x05ef00d,0x00a7e34,0x1ae0c9f,0x1440b38,0x300d8b4,\n        0x37262da,0x3e50e3e,0x14ce0cd,0x00b1044 },\n      { 0x195a0b1,0x173bc6b,0x03622ba,0x2a19f55,0x1c09b37,0x07921b2,\n        0x16cdd20,0x24a5c9b,0x2bf42ff,0x00811de } },\n    /* 129 */\n    { { 0x0d65dbf,0x145cf06,0x1ad82f7,0x038ce7b,0x077bf94,0x33c4007,\n        0x22d26bd,0x25ad9c0,0x09ac773,0x02b1990 },\n      { 0x2261cc3,0x2ecdbf1,0x3e908b0,0x3246439,0x0213f7b,0x1179b04,\n        0x01cebaa,0x0be1595,0x175cc12,0x033a39a } },\n    /* 130 */\n    { { 0x00a67d2,0x086d06f,0x248a0f1,0x0291134,0x362d476,0x166d1cd,\n        0x044f1d6,0x2d2a038,0x365250b,0x0023f78 },\n      { 0x08bf287,0x3b0f6a1,0x1d6eace,0x20b4cda,0x2c2a621,0x0912520,\n        0x02dfdc9,0x1b35cd6,0x3d2565d,0x00bdf8b } },\n    /* 131 */\n    { { 0x3770fa7,0x2e4b6f0,0x03f9ae4,0x170de41,0x1095e8d,0x1dd845c,\n        0x334e9d1,0x00ab953,0x12e9077,0x03196fa },\n      { 0x2fd0a40,0x228c0fd,0x384b275,0x38ef339,0x3e7d822,0x3e5d9ef,\n        0x24f5854,0x0ece9eb,0x247d119,0x012ffe3 } },\n    /* 132 */\n    { { 0x0ff1480,0x07487c0,0x1b16cd4,0x1f41d53,0x22ab8fb,0x2f83cfa,\n        0x01d2efb,0x259f6b2,0x2e65772,0x00f9392 },\n      { 0x05303e6,0x23cdb4f,0x23977e1,0x12e4898,0x03bd999,0x0c930f0,\n        0x170e261,0x180a27b,0x2fd58ec,0x014e22b } },\n    /* 133 */\n    { { 0x25d7713,0x0c5fad7,0x09daad1,0x3b9d779,0x109b985,0x1d3ec98,\n        0x35bc4fc,0x2f838cb,0x0d14f75,0x0173e42 },\n      { 0x2657b12,0x10d4423,0x19e6760,0x296e5bb,0x2bfd421,0x25c3330,\n        0x29f51f8,0x0338838,0x24060f0,0x029a62e } },\n    /* 134 */\n    { { 0x3748fec,0x2c5a1bb,0x2cf973d,0x289fa74,0x3e6e755,0x38997bf,\n        0x0b6544c,0x2b6358c,0x38a7aeb,0x02c50bb },\n      { 0x3d5770a,0x06be7c5,0x012fad3,0x19cb2cd,0x266af3b,0x3ccd677,\n        0x160d1bd,0x141d5af,0x2965851,0x034625a } },\n    /* 135 */\n    { { 0x3c41c08,0x255eacc,0x22e1ec5,0x2b151a3,0x087de94,0x311cbdb,\n        0x016b73a,0x368e462,0x20b7981,0x0099ec3 },\n      { 0x262b988,0x1539763,0x21e76e5,0x15445b4,0x1d8ddc7,0x34a9be6,\n        0x10faf03,0x24e4d18,0x07aa111,0x02d538a } },\n    /* 136 */\n    { { 0x38a876b,0x048ad45,0x04b40a0,0x3fc2144,0x251ff96,0x13ca7dd,\n        0x0b31ab1,0x3539814,0x28b5f87,0x0212aec },\n      { 0x270790a,0x350e7e0,0x346bd5e,0x276178f,0x22d6cb5,0x3078884,\n        0x355c1b6,0x15901d7,0x3671765,0x03950db } },\n    /* 137 */\n    { { 0x286e8d5,0x2409788,0x13be53f,0x2d21911,0x0353c95,0x10238e8,\n        0x32f5bde,0x3a67b60,0x28b5b9c,0x001013d },\n      { 0x381e8e5,0x0cef7a9,0x2f5bcad,0x06058f0,0x33cdf50,0x04672a8,\n        0x1769600,0x31c055d,0x3df0ac1,0x00e9098 } },\n    /* 138 */\n    { { 0x2eb596d,0x197b326,0x12b4c29,0x39c08f2,0x101ea03,0x3804e58,\n        0x04b4b62,0x28d9d1c,0x13f905e,0x0032a3f },\n      { 0x11b2b61,0x08e9095,0x0d06925,0x270e43f,0x21eb7a8,0x0e4a98f,\n        0x31d2be0,0x030cf9f,0x2644ddb,0x025b728 } },\n    /* 139 */\n    { { 0x07510af,0x2ed0e8e,0x2a01203,0x2a2a68d,0x0846fea,0x3e540de,\n        0x3a57702,0x1677348,0x2123aad,0x010d8f8 },\n      { 0x0246a47,0x0e871d0,0x124dca4,0x34b9577,0x2b362b8,0x363ebe5,\n        0x3086045,0x26313e6,0x15cd8bb,0x0210384 } },\n    /* 140 */\n    { { 0x023e8a7,0x0817884,0x3a0bf12,0x3376371,0x3c808a8,0x18e9777,\n        0x12a2721,0x35b538a,0x2bd30de,0x017835a },\n      { 0x0fc0f64,0x1c8709f,0x2d8807a,0x0743957,0x242eec0,0x347e76c,\n        0x27bef91,0x289689a,0x0f42945,0x01f7a92 } },\n    /* 141 */\n    { { 0x1060a81,0x3dbc739,0x1615abd,0x1cbe3e5,0x3e79f9c,0x1ab09a2,\n        0x136c540,0x05b473f,0x2beebfd,0x02af0a8 },\n      { 0x3e2eac7,0x19be474,0x04668ac,0x18f4b74,0x36f10ba,0x0a0b4c6,\n        0x10e3770,0x3bf059e,0x3946c7e,0x013a8d4 } },\n    /* 142 */\n    { { 0x266309d,0x28be354,0x1a3eed8,0x3020651,0x10a51c6,0x1e31770,\n        0x0af45a5,0x3ff0f3b,0x2891c94,0x00e9db9 },\n      { 0x17b0d0f,0x33a291f,0x0a5f9aa,0x25a3d61,0x2963ace,0x39a5fef,\n        0x230c724,0x1919146,0x10a465e,0x02084a8 } },\n    /* 143 */\n    { { 0x3ab8caa,0x31870f3,0x2390ef7,0x2103850,0x218eb8e,0x3a5ccf2,\n        0x1dff677,0x2c59334,0x371599c,0x02a9f2a },\n      { 0x0837bd1,0x3249cef,0x35d702f,0x3430dab,0x1c06407,0x108f692,\n        0x221292f,0x05f0c5d,0x073fe06,0x01038e0 } },\n    /* 144 */\n    { { 0x3bf9b7c,0x2020929,0x30d0f4f,0x080fef8,0x3365d23,0x1f3e738,\n        0x3e53209,0x1549afe,0x300b305,0x038d811 },\n      { 0x0c6c2c7,0x2e6445b,0x3ee64dc,0x022e932,0x0726837,0x0deb67b,\n        0x1ed4346,0x3857f73,0x277a3de,0x01950b5 } },\n    /* 145 */\n    { { 0x36c377a,0x0adb41e,0x08be3f3,0x11e40d1,0x36cb038,0x036a2bd,\n        0x3dd3a82,0x1bc875b,0x2ee09bb,0x02994d2 },\n      { 0x035facf,0x05e0344,0x07e630a,0x0ce772d,0x335e55a,0x111fce4,\n        0x250fe1c,0x3bc89ba,0x32fdc9a,0x03cf2d9 } },\n    /* 146 */\n    { { 0x355fd83,0x1c67f8e,0x1d10eb3,0x1b21d77,0x0e0d7a4,0x173a9e1,\n        0x2c9fa90,0x1c39cce,0x22eaae8,0x01f2bea },\n      { 0x153b338,0x0534107,0x26c69b8,0x283be1f,0x3e0acc0,0x059cac3,\n        0x13d1081,0x148bbee,0x3c1b9bd,0x002aac4 } },\n    /* 147 */\n    { { 0x2681297,0x3389e34,0x146addc,0x2c6d425,0x2cb350e,0x1986abc,\n        0x0431737,0x04ba4b7,0x2028470,0x012e469 },\n      { 0x2f8ddcf,0x3c4255c,0x1af4dcf,0x07a6a44,0x208ebf6,0x0dc90c3,\n        0x34360ac,0x072ad23,0x0537232,0x01254d3 } },\n    /* 148 */\n    { { 0x07b7e9d,0x3df5c7c,0x116f83d,0x28c4f35,0x3a478ef,0x3011fb8,\n        0x2f264b6,0x317b9e3,0x04fd65a,0x032bd1b },\n      { 0x2aa8266,0x3431de4,0x04bba04,0x19a44da,0x0edf454,0x392c5ac,\n        0x265168a,0x1dc3d5b,0x25704c6,0x00533a7 } },\n    /* 149 */\n    { { 0x25e8f91,0x1178fa5,0x2492994,0x2eb2c3c,0x0d3aca1,0x0322828,\n        0x1cc70f9,0x269c74c,0x0a53e4c,0x006edc2 },\n      { 0x18bdd7a,0x2a79a55,0x26b1d5c,0x0200628,0x0734a05,0x3273c7b,\n        0x13aa714,0x0040ac2,0x2f2da30,0x03e7449 } },\n    /* 150 */\n    { { 0x3f9563e,0x2f29eab,0x14a0749,0x3fad264,0x1dd077a,0x3d7c59c,\n        0x3a0311b,0x331a789,0x0b9729e,0x0201ebf },\n      { 0x1b08b77,0x2a4cdf2,0x3e387f8,0x21510f1,0x286c3a7,0x1dbf62e,\n        0x3afa594,0x3363217,0x0d16568,0x01d46b7 } },\n    /* 151 */\n    { { 0x0715c0d,0x28e2d04,0x17f78ae,0x1c63dda,0x1d113ea,0x0fefc1b,\n        0x1eab149,0x1d0fd99,0x0682537,0x00a7b11 },\n      { 0x10bebbc,0x11c672d,0x14223d9,0x2ff9141,0x1399ee5,0x34b7b6c,\n        0x0d5b3a8,0x01df643,0x0e392a4,0x03fe4dc } },\n    /* 152 */\n    { { 0x2b75b65,0x0b5a6f1,0x11c559a,0x3549999,0x24188f8,0x37a75f4,\n        0x29f33e3,0x34068a2,0x38ba2a9,0x025dd91 },\n      { 0x29af2c7,0x0988b64,0x0923885,0x1b539a4,0x1334f5d,0x226947a,\n        0x2cc7e5a,0x20beb39,0x13fac2f,0x01d298c } },\n    /* 153 */\n    { { 0x35f079c,0x137f76d,0x2fbbb2f,0x254638d,0x185b07c,0x1f34db7,\n        0x2cfcf0e,0x218f46d,0x2150ff4,0x02add6f },\n      { 0x33fc9b7,0x0d9f005,0x0fd081b,0x0834965,0x2b90a74,0x102448d,\n        0x3dbf03c,0x167d857,0x02e0b44,0x013afab } },\n    /* 154 */\n    { { 0x09f2c53,0x317f9d7,0x1411eb6,0x0463aba,0x0d25220,0x256b176,\n        0x087633f,0x2bff322,0x07b2c1b,0x037e662 },\n      { 0x10aaecb,0x23bb4a1,0x2272bb7,0x06c075a,0x09d4918,0x0736f2b,\n        0x0dd511b,0x101625e,0x0a7779f,0x009ec10 } },\n    /* 155 */\n    { { 0x33b2eb2,0x0176dfd,0x2118904,0x022386c,0x2e0df85,0x2588c9f,\n        0x1b71525,0x28fd540,0x137e4cf,0x02ce4f7 },\n      { 0x3d75165,0x0c39ecf,0x3554a12,0x30af34c,0x2d66344,0x3ded408,\n        0x36f1be0,0x0d065b0,0x012d046,0x0025623 } },\n    /* 156 */\n    { { 0x2601c3b,0x1824fc0,0x335fe08,0x3e33d70,0x0fb0252,0x252bfca,\n        0x1cf2808,0x1922e55,0x1a9db9f,0x020721e },\n      { 0x2f56c51,0x39a1f31,0x218c040,0x1a4fc5d,0x3fed471,0x0164d4e,\n        0x388a419,0x06f1113,0x0f55fc1,0x03e8352 } },\n    /* 157 */\n    { { 0x1608e4d,0x3872778,0x022cbc6,0x044d60a,0x3010dda,0x15fb0b5,\n        0x37ddc11,0x19f5bda,0x156b6a3,0x023a838 },\n      { 0x383b3b4,0x1380bc8,0x353ca35,0x250fc07,0x169966b,0x3780f29,\n        0x36632b2,0x2d6b13f,0x124fa00,0x00fd6ae } },\n    /* 158 */\n    { { 0x1739efb,0x2ec3656,0x2c0d337,0x3d39faf,0x1c751b0,0x04699f4,\n        0x252dd64,0x095b8b6,0x0872b74,0x022f1da },\n      { 0x2d3d253,0x38edca0,0x379fa5b,0x287d635,0x3a9f679,0x059d9ee,\n        0x0ac168e,0x3cd3e87,0x19060fc,0x02ce1bc } },\n    /* 159 */\n    { { 0x3edcfc2,0x0f04d4b,0x2f0d31f,0x1898be2,0x25396bf,0x15ca230,\n        0x02b4eae,0x2713668,0x0f71b06,0x0132d18 },\n      { 0x38095ea,0x1ed34d6,0x3603ae6,0x165bf01,0x192bbf8,0x1852859,\n        0x075f66b,0x1488f85,0x10895ef,0x014b035 } },\n    /* 160 */\n    { { 0x1339848,0x3084385,0x0c8d231,0x3a1c1de,0x0e87a28,0x255b85c,\n        0x1de6616,0x2702e74,0x1382bb0,0x012b0f2 },\n      { 0x198987d,0x381545a,0x34d619b,0x312b827,0x18b2376,0x28fe4cf,\n        0x20b7651,0x017d077,0x0c7e397,0x00e0365 } },\n    /* 161 */\n    { { 0x1542e75,0x0d56aa0,0x39b701a,0x287b806,0x396c724,0x0935c21,\n        0x3a29776,0x0debdac,0x171de26,0x00b38f8 },\n      { 0x1d5bc1a,0x3fad27d,0x22b5cfe,0x1f89ddf,0x0a65560,0x144dd5b,\n        0x2aac2f9,0x139353f,0x0520b62,0x00b9b36 } },\n    /* 162 */\n    { { 0x031c31d,0x16552e3,0x1a0c368,0x0016fc8,0x168533d,0x171e7b2,\n        0x17626e7,0x275502f,0x14742c6,0x03285dd },\n      { 0x2d2dbb2,0x3b6bffd,0x1d18cc6,0x2f45d2a,0x0fd0d8c,0x2915e3a,\n        0x1e8793a,0x0b39a1d,0x3139cab,0x02a5da9 } },\n    /* 163 */\n    { { 0x3fb353d,0x147c6e4,0x3a720a6,0x22d5ff3,0x1d75cab,0x06c54a0,\n        0x08cfa73,0x12666aa,0x3170a1f,0x021c829 },\n      { 0x13e1b90,0x3a34dda,0x1fc38c3,0x02c5bdb,0x2d345dc,0x14aa1d0,\n        0x28d00ab,0x224f23a,0x329c769,0x025c67b } },\n    /* 164 */\n    { { 0x0e35909,0x3bb6356,0x0116820,0x370cf77,0x29366d8,0x3881409,\n        0x3999d06,0x013075f,0x176e157,0x02941ca },\n      { 0x0e70b2e,0x28dfab1,0x2a8a002,0x15da242,0x084dcf6,0x116ca97,\n        0x31bf186,0x1dc9735,0x09df7b7,0x0264e27 } },\n    /* 165 */\n    { { 0x2da7a4b,0x3023c9e,0x1366238,0x00ff4e2,0x03abe9d,0x19bd44b,\n        0x272e897,0x20b91ad,0x2aa202c,0x02a2201 },\n      { 0x380184e,0x08112b4,0x0b85660,0x31049aa,0x3a8cb78,0x36113c5,\n        0x1670c0a,0x373f9e7,0x3fb4738,0x00010ef } },\n    /* 166 */\n    { { 0x2d5192e,0x26d770d,0x32af8d5,0x34d1642,0x1acf885,0x05805e0,\n        0x166d0a1,0x1219a0d,0x301ba6c,0x014bcfb },\n      { 0x2dcb64d,0x19cca83,0x379f398,0x08e01a0,0x10a482c,0x0103cc2,\n        0x0be5fa7,0x1f9d45b,0x1899ef2,0x00ca5af } },\n    /* 167 */\n    { { 0x14d81d7,0x2aea251,0x1b3c476,0x3bd47ae,0x29eade7,0x0715e61,\n        0x1a21cd8,0x1c7a586,0x2bfaee5,0x00ee43f },\n      { 0x096f7cb,0x0c08f95,0x1bc4939,0x361fed4,0x255be41,0x26fad73,\n        0x31dd489,0x02c600f,0x29d9f81,0x01ba201 } },\n    /* 168 */\n    { { 0x03ea1db,0x1eac46d,0x1292ce3,0x2a54967,0x20a7ff1,0x3e13c61,\n        0x1b02218,0x2b44e14,0x3eadefa,0x029c88a },\n      { 0x30a9144,0x31e3b0a,0x19c5a2a,0x147cbe9,0x05a0240,0x051f38e,\n        0x11eca56,0x31a4247,0x123bc2a,0x02fa535 } },\n    /* 169 */\n    { { 0x3226ce7,0x1251782,0x0b7072f,0x11e59fa,0x2b8afd7,0x169b18f,\n        0x2a46f18,0x31d9bb7,0x2fe9be8,0x01de0b7 },\n      { 0x1b38626,0x34aa90f,0x3ad1760,0x21ddbd9,0x3460ae7,0x1126736,\n        0x1b86fc5,0x0b92cd0,0x167a289,0x000e0e1 } },\n    /* 170 */\n    { { 0x1ec1a0f,0x36bbf5e,0x1c972d8,0x3f73ace,0x13bbcd6,0x23d86a5,\n        0x175ffc5,0x2d083d5,0x2c4adf7,0x036f661 },\n      { 0x1f39eb7,0x2a20505,0x176c81a,0x3d6e636,0x16ee2fc,0x3cbdc5f,\n        0x25475dc,0x2ef4151,0x3c46860,0x0238934 } },\n    /* 171 */\n    { { 0x2587390,0x3639526,0x0588749,0x13c32fb,0x212bb19,0x09660f1,\n        0x207da4b,0x2bf211b,0x1c4407b,0x01506a6 },\n      { 0x24c8842,0x105a498,0x05ffdb2,0x0ab61b0,0x26044c1,0x3dff3d8,\n        0x1d14b44,0x0d74716,0x049f57d,0x030024b } },\n    /* 172 */\n    { { 0x32e61ef,0x31d70f7,0x35cad3c,0x320b86c,0x07e8841,0x027ca7d,\n        0x2d30d19,0x2513718,0x2347286,0x01d7901 },\n      { 0x3c237d0,0x107f16e,0x01c9e7d,0x3c3b13c,0x0c9537b,0x20af54d,\n        0x051a162,0x2161a47,0x258c784,0x016df2d } },\n    /* 173 */\n    { { 0x228ead1,0x29c2122,0x07f6964,0x023f4ed,0x1802dc5,0x19f96ce,\n        0x24bfd17,0x25e866b,0x2ba8df0,0x01eb84f },\n      { 0x2dd384e,0x05bbe3a,0x3f06fd2,0x366dacb,0x30361a2,0x2f36d7c,\n        0x0b98784,0x38ff481,0x074e2a8,0x01e1f60 } },\n    /* 174 */\n    { { 0x17fbb1c,0x0975add,0x1debc5e,0x2cb2880,0x3e47bdd,0x3488cff,\n        0x15e9a36,0x2121129,0x0199ef2,0x017088a },\n      { 0x0315250,0x352a162,0x17c1773,0x0ae09c2,0x321b21a,0x3bd74cf,\n        0x3c4ea1d,0x3cac2ad,0x3abbaf0,0x039174d } },\n    /* 175 */\n    { { 0x0511c8a,0x3c78d0a,0x2cd3d2d,0x322f729,0x3ebb229,0x09f0e69,\n        0x0a71a76,0x2e74d5e,0x12284df,0x03b5ef0 },\n      { 0x3dea561,0x0a9b7e4,0x0ed1cf2,0x237523c,0x05443f1,0x2eb48fa,\n        0x3861405,0x1b49f62,0x0c945ca,0x02ab25f } },\n    /* 176 */\n    { { 0x16bd00a,0x13a9d28,0x3cc1eb5,0x2b7d702,0x2d839e9,0x3e6ff01,\n        0x2bb7f11,0x3713824,0x3b31163,0x00c63e5 },\n      { 0x30d7138,0x0316fb0,0x0220ecc,0x08eaf0c,0x244e8df,0x0088d81,\n        0x37972fb,0x3fd34ae,0x2a19a84,0x03e907e } },\n    /* 177 */\n    { { 0x2642269,0x0b65d29,0x03bd440,0x33a6ede,0x3c81814,0x2507982,\n        0x0d38e47,0x3a788e6,0x32c1d26,0x00e2eda },\n      { 0x2577f87,0x392895a,0x3e1cc64,0x14f7047,0x08b52d2,0x08a01ca,\n        0x336abf6,0x00697fc,0x105ce76,0x0253742 } },\n    /* 178 */\n    { { 0x293f92a,0x33df737,0x3315156,0x32e26d7,0x0a01333,0x26579d4,\n        0x004df9c,0x0aba409,0x067d25c,0x02481de },\n      { 0x3f39d44,0x1c78042,0x13d7e24,0x0825aed,0x35f2c90,0x3270f63,\n        0x04b7b35,0x3ad4531,0x28bd29b,0x0207a10 } },\n    /* 179 */\n    { { 0x077199f,0x270aeb1,0x0dd96dd,0x3b9ad7b,0x28cb8ee,0x3903f43,\n        0x37db3fe,0x292c62b,0x362dbbf,0x006e52a },\n      { 0x247f143,0x0362cf3,0x216344f,0x3f18fd1,0x351e623,0x31664e0,\n        0x0f270fc,0x243bbc6,0x2280555,0x001a8e3 } },\n    /* 180 */\n    { { 0x3355b49,0x2c04e6c,0x399b2e5,0x182d3af,0x020e265,0x09a7cf7,\n        0x0ffa6bd,0x353e302,0x02083d9,0x029ecdb },\n      { 0x33e8830,0x0570e86,0x1c0b64d,0x386a27e,0x0d5fcea,0x0b45a4c,\n        0x2ee4a2e,0x0a8833f,0x2b4a282,0x02f9531 } },\n    /* 181 */\n    { { 0x191167c,0x36cf7e3,0x225ed6c,0x1e79e99,0x0517c3f,0x11ab1fd,\n        0x05648f3,0x08aedc4,0x1abeae0,0x02fcc29 },\n      { 0x3828a68,0x1e16fa4,0x30368e7,0x0c9fcfb,0x25161c3,0x24851ac,\n        0x1b5feb5,0x344eb84,0x0de2732,0x0347208 } },\n    /* 182 */\n    { { 0x038b363,0x384d1e4,0x2519043,0x151ac17,0x158c11f,0x009b2b4,\n        0x257abe6,0x2368d3f,0x3ed68a1,0x02df45e },\n      { 0x29c2559,0x2962478,0x3d8444c,0x1d96fff,0x04f7a03,0x1391a52,\n        0x0de4af7,0x3319126,0x15e6412,0x00e65ff } },\n    /* 183 */\n    { { 0x3d61507,0x1d1a0a2,0x0d2af20,0x354d299,0x329e132,0x2a28578,\n        0x2ddfb08,0x04fa3ff,0x1293c6c,0x003bae2 },\n      { 0x3e259f8,0x1a68fa9,0x3e67e9b,0x39b44f9,0x1ce1db7,0x347e9a1,\n        0x3318f6a,0x2dbbc9d,0x2f8c922,0x008a245 } },\n    /* 184 */\n    { { 0x212ab5b,0x2b896c2,0x0136959,0x07e55ef,0x0cc1117,0x05b8ac3,\n        0x18429ed,0x025fa01,0x11d6e93,0x03b016b },\n      { 0x03f3708,0x2e96fab,0x1d77157,0x0d4c2d6,0x131baf9,0x0608d39,\n        0x3552371,0x06cdd1e,0x1567ff1,0x01f4c50 } },\n    /* 185 */\n    { { 0x2dfefab,0x270173d,0x37077bd,0x1a372cd,0x1be2f22,0x28e2ee5,\n        0x3ead973,0x35e8f94,0x2fc9bc1,0x03a7399 },\n      { 0x36a02a1,0x2855d9b,0x00ed75a,0x37d8398,0x138c087,0x233706e,\n        0x147f346,0x01947e2,0x3017228,0x0365942 } },\n    /* 186 */\n    { { 0x2057e60,0x2d31296,0x25e4504,0x2fa37bc,0x1cbccc3,0x1f0732f,\n        0x3532081,0x2de8a98,0x19a804e,0x005359a },\n      { 0x31f411a,0x2a10576,0x369c2c8,0x02fe035,0x109fbaf,0x30bddeb,\n        0x1eef901,0x1662ad3,0x0410d43,0x01bd31a } },\n    /* 187 */\n    { { 0x2c24a96,0x1b7d3a5,0x19a3872,0x217f2f6,0x2534dbc,0x2cab8c2,\n        0x066ef28,0x26aecf1,0x0fd6118,0x01310d4 },\n      { 0x055b8da,0x1fdc5be,0x38a1296,0x25118f0,0x341a423,0x2ba4cd0,\n        0x3e1413e,0x062d70d,0x2425a31,0x029c9b4 } },\n    /* 188 */\n    { { 0x08c1086,0x1acfba5,0x22e1dae,0x0f72f4e,0x3f1de50,0x0f408bc,\n        0x35ed3f0,0x3ce48fc,0x282cc6c,0x004d8e7 },\n      { 0x1afaa86,0x24e3ef3,0x22589ac,0x3ec9952,0x1f45bc5,0x14144ca,\n        0x23b26e4,0x0d68c65,0x1e1c1a3,0x032a4d9 } },\n    /* 189 */\n    { { 0x03b2d20,0x16b1d53,0x241b361,0x05e4138,0x1742a54,0x32741c7,\n        0x0521c4c,0x1ca96c2,0x034970b,0x02738a7 },\n      { 0x13e0ad6,0x207dcdb,0x034c8cc,0x27bcbe1,0x18060da,0x33a18b6,\n        0x2d1d1a6,0x2be60d7,0x3d7ab42,0x012312a } },\n    /* 190 */\n    { { 0x0c7485a,0x06c3310,0x0dbfd22,0x2ef949d,0x0ead455,0x098f4ba,\n        0x3c76989,0x0cf2d24,0x032f67b,0x01e005f },\n      { 0x30cb5ee,0x0d5da64,0x0ed2b9d,0x2503102,0x1c0d14e,0x1cbc693,\n        0x37bf552,0x07013e2,0x054de5c,0x014f341 } },\n    /* 191 */\n    { { 0x128ccac,0x1617e97,0x346ebcd,0x158016d,0x25f823e,0x34048ea,\n        0x39f0a1c,0x3ea3df1,0x1c1d3d7,0x03ba919 },\n      { 0x151803b,0x01967c1,0x2f70781,0x27df39a,0x06c0b59,0x24a239c,\n        0x15a7702,0x2464d06,0x2a47ae6,0x006db90 } },\n    /* 192 */\n    { { 0x27d04c3,0x024df3d,0x38112e8,0x38a27ba,0x01e312b,0x0965358,\n        0x35d8879,0x2f4f55a,0x214187f,0x0008936 },\n      { 0x05fe36f,0x2ee18c3,0x1f5f87a,0x1813bd4,0x0580f3c,0x0ed0a7b,\n        0x0fb1bfb,0x3fcce59,0x2f042bf,0x01820e3 } },\n    /* 193 */\n    { { 0x20bbe99,0x32cbc9f,0x39ee432,0x3cc12a8,0x37bda44,0x3ea4e40,\n        0x097c7a9,0x0590d7d,0x2022d33,0x018dbac },\n      { 0x3ae00aa,0x3439864,0x2d2ffcf,0x3f8c6b9,0x0875a00,0x3e4e407,\n        0x3658a29,0x22eb3d0,0x2b63921,0x022113b } },\n    /* 194 */\n    { { 0x33bae58,0x05c749a,0x1f3e114,0x1c45f8e,0x27db3df,0x06a3ab6,\n        0x37bc7f8,0x1e27b34,0x3dc51fb,0x009eea0 },\n      { 0x3f54de5,0x3d0e7fe,0x1a71a7d,0x02ed7f8,0x0727703,0x2ca5e92,\n        0x2e8e35d,0x292ad0b,0x13487f3,0x02b6d8b } },\n    /* 195 */\n    { { 0x175df2a,0x05a28a8,0x32e99b1,0x13d8630,0x2082aa0,0x11ac245,\n        0x24f2e71,0x322cb27,0x17675e7,0x02e643f },\n      { 0x1f37313,0x2765ad3,0x0789082,0x1e742d0,0x11c2055,0x2021dc4,\n        0x09ae4a7,0x346359b,0x2f94d10,0x0205c1f } },\n    /* 196 */\n    { { 0x3d6ff96,0x1f2ac80,0x336097d,0x3f03610,0x35b851b,0x010b6d2,\n        0x0823c4d,0x2a9709a,0x2ead5a8,0x00de4b6 },\n      { 0x01afa0b,0x0621965,0x3671528,0x1050b60,0x3f3e9e7,0x2f93829,\n        0x0825275,0x006e85f,0x35e94b0,0x016af58 } },\n    /* 197 */\n    { { 0x2c4927c,0x3ea1382,0x0f23727,0x0d69f23,0x3e38860,0x2b72837,\n        0x3cd5ea4,0x2d84292,0x321846a,0x016656f },\n      { 0x29dfa33,0x3e182e0,0x018be90,0x2ba563f,0x2caafe2,0x218c0d9,\n        0x3baf447,0x1047a6c,0x0a2d483,0x01130cb } },\n    /* 198 */\n    { { 0x00ed80c,0x2a5fc79,0x0a82a74,0x2c4c74b,0x15f938c,0x30b5ab6,\n        0x32124b7,0x295314f,0x2fb8082,0x007c858 },\n      { 0x20b173e,0x19f315c,0x12f97e4,0x198217c,0x040e8a6,0x3275977,\n        0x2bc20e4,0x01f2633,0x02bc3e9,0x023c750 } },\n    /* 199 */\n    { { 0x3c4058a,0x24be73e,0x16704f5,0x2d8a4bd,0x3b15e14,0x3076315,\n        0x1cfe37b,0x36fe715,0x343926e,0x02c6603 },\n      { 0x2c76b09,0x0cf824c,0x3f7898c,0x274cec1,0x11df527,0x18eed18,\n        0x08ead48,0x23915bc,0x19b3744,0x00a0a2b } },\n    /* 200 */\n    { { 0x0cf4ac5,0x1c8b131,0x0afb696,0x0ff7799,0x2f5ac1a,0x022420c,\n        0x11baa2e,0x2ce4015,0x1275a14,0x0125cfc },\n      { 0x22eac5d,0x360cd4c,0x3568e59,0x3d42f66,0x35e07ee,0x09620e4,\n        0x36720fa,0x22b1eac,0x2d0db16,0x01b6b23 } },\n    /* 201 */\n    { { 0x1a835ef,0x1516bbb,0x2d51f7b,0x3487443,0x14aa113,0x0dd06c2,\n        0x1a65e01,0x379300d,0x35920b9,0x012c8fb },\n      { 0x04c7341,0x2eda00f,0x3c37e82,0x1b4fd62,0x0d45770,0x1478fba,\n        0x127863a,0x26939cd,0x134ddf4,0x01375c5 } },\n    /* 202 */\n    { { 0x1476cd9,0x1119ca5,0x325bbf9,0x0bf8c69,0x0648d07,0x312d9f8,\n        0x01c8b8f,0x136ec51,0x0002f4a,0x03f4c5c },\n      { 0x195d0e1,0x10ffd22,0x29aa1cb,0x3443bdc,0x276e695,0x05e6260,\n        0x15f9764,0x3cd9783,0x18c9569,0x0053eb1 } },\n    /* 203 */\n    { { 0x312ae18,0x280197c,0x3fc9ad9,0x303f324,0x251958d,0x29f4a11,\n        0x2142408,0x3694366,0x25136ab,0x03b5f1d },\n      { 0x1d4abbc,0x1c3c689,0x13ea462,0x3cfc684,0x39b5dd8,0x2d4654b,\n        0x09b0755,0x27d4f18,0x3f74d2e,0x03fbf2d } },\n    /* 204 */\n    { { 0x2119185,0x2525eae,0x1ba4bd0,0x0c2ab11,0x1d54e8c,0x294845e,\n        0x2479dea,0x3602d24,0x17e87e0,0x0060069 },\n      { 0x0afffb0,0x34fe37f,0x1240073,0x02eb895,0x06cf33c,0x2d7f7ef,\n        0x1d763b5,0x04191e0,0x11e1ead,0x027e3f0 } },\n    /* 205 */\n    { { 0x269544c,0x0e85c57,0x3813158,0x19fc12d,0x20eaf85,0x1e2930c,\n        0x22a8fd2,0x1a6a478,0x09d3d3a,0x02a74e0 },\n      { 0x1a2da3b,0x30b0b16,0x0847936,0x3d86257,0x138ccbc,0x0f5421a,\n        0x25244e6,0x23bdd79,0x1aee117,0x00c01ae } },\n    /* 206 */\n    { { 0x1eead28,0x07cac32,0x1fbc0bb,0x17627d3,0x17eef63,0x0b3a24e,\n        0x0757fdb,0x3dd841d,0x3d745f8,0x002ae17 },\n      { 0x25b4549,0x29f24cf,0x2f21ecd,0x1725e48,0x04be2bb,0x10ee010,\n        0x1a1274b,0x10b0898,0x27511e9,0x02c48b5 } },\n    /* 207 */\n    { { 0x2a5ae7a,0x181ef99,0x0be33be,0x3e9dab7,0x101e703,0x3adb971,\n        0x1043014,0x2ebb2be,0x1c1097d,0x027d667 },\n      { 0x3f250ed,0x16dc603,0x20dc6d7,0x1d0d268,0x38eb915,0x02c89e8,\n        0x1605a41,0x12de109,0x0e08a29,0x01f554a } },\n    /* 208 */\n    { { 0x0c26def,0x163d988,0x2d1ef0f,0x3a960ac,0x1025585,0x0738e20,\n        0x27d79b0,0x05cc3ef,0x201303f,0x00a333a },\n      { 0x1644ba5,0x2af345e,0x30b8d1d,0x3a01bff,0x31fc643,0x1acf85e,\n        0x0a76fc6,0x04efe98,0x348a1d0,0x03062eb } },\n    /* 209 */\n    { { 0x1c4216d,0x18e3217,0x02ac34e,0x19c8185,0x200c010,0x17d4192,\n        0x13a1719,0x165af51,0x09db7a9,0x0277be0 },\n      { 0x3ab8d2c,0x2190b99,0x22b641e,0x0cd88de,0x3b42404,0x1310862,\n        0x106a6d6,0x23395f5,0x0b06880,0x000d5fe } },\n    /* 210 */\n    { { 0x0d2cc88,0x36f9913,0x339d8e9,0x237c2e3,0x0cc61c2,0x34c2832,\n        0x309874c,0x2621d28,0x2dd1b48,0x0392806 },\n      { 0x17cd8f9,0x07bab3d,0x0c482ed,0x0faf565,0x31b767d,0x2f4bde1,\n        0x295c717,0x330c29c,0x179ce10,0x0119b5f } },\n    /* 211 */\n    { { 0x1ada2c7,0x0c624a7,0x227d47d,0x30e3e6a,0x14fa0a6,0x0829678,\n        0x24fd288,0x2b46a43,0x122451e,0x0319ca9 },\n      { 0x186b655,0x01f3217,0x0af1306,0x0efe6b5,0x2f0235d,0x1c45ca9,\n        0x2086805,0x1d44e66,0x0faf2a6,0x0178f59 } },\n    /* 212 */\n    { { 0x33b4416,0x10431e6,0x2d99aa6,0x217aac9,0x0cd8fcf,0x2d95a9d,\n        0x3ff74ad,0x10bf17a,0x295eb8e,0x01b229e },\n      { 0x02a63bd,0x182e9ec,0x004710c,0x00e2e3c,0x06b2f23,0x04b642c,\n        0x2c37383,0x32a4631,0x022ad82,0x00d22b9 } },\n    /* 213 */\n    { { 0x0cda2fb,0x1d198d7,0x26d27f4,0x286381c,0x022acca,0x24ac7c8,\n        0x2df7824,0x0b4ba16,0x1e0d9ef,0x03041d3 },\n      { 0x29a65b3,0x0f3912b,0x151bfcf,0x2b0175c,0x0fd71e4,0x39aa5e2,\n        0x311f50c,0x13ff351,0x3dbc9e5,0x03eeb7e } },\n    /* 214 */\n    { { 0x0a99363,0x0fc7348,0x2775171,0x23db3c8,0x2b91565,0x134d66c,\n        0x0175cd2,0x1bf365a,0x2b48371,0x02dfe5d },\n      { 0x16dbf74,0x2389357,0x2f36575,0x3f5c70e,0x38d23ba,0x090f7f8,\n        0x3477600,0x3201523,0x32ecafc,0x03d3506 } },\n    /* 215 */\n    { { 0x1abd48d,0x073ca3f,0x38a451f,0x0d8cb01,0x1ce81be,0x05c51ba,\n        0x0e29741,0x03c41ab,0x0eae016,0x0060209 },\n      { 0x2e58358,0x1da62d9,0x2358038,0x14b39b2,0x1635687,0x39079b1,\n        0x380e345,0x1b49608,0x23983cf,0x019f97d } },\n    /* 216 */\n    { { 0x34899ef,0x332e373,0x04c0f89,0x3c27aed,0x1949015,0x09663b2,\n        0x2f9276b,0x07f1951,0x09a04c1,0x027fbde },\n      { 0x3d2a071,0x19fb3d4,0x1b096d3,0x1fe9146,0x3b10e1a,0x0478bbb,\n        0x2b3fb06,0x1388329,0x181a99c,0x02f2030 } },\n    /* 217 */\n    { { 0x1eb82e6,0x14dbe39,0x3920972,0x31fd5b2,0x21a484f,0x02d7697,\n        0x0e21715,0x37c431e,0x2629f8c,0x01249c3 },\n      { 0x26b50ad,0x26deefa,0x0ffc1a3,0x30688e2,0x39a0284,0x041c65e,\n        0x03eb178,0x0bdfd50,0x2f96137,0x034bb94 } },\n    /* 218 */\n    { { 0x0e0362a,0x334a162,0x194dd37,0x29e3e97,0x2442fa8,0x10d2949,\n        0x3836e5a,0x2dccebf,0x0bee5ab,0x037ed1e },\n      { 0x33eede6,0x3c739d9,0x2f04a91,0x350ad6c,0x3a5390a,0x14c368b,\n        0x26f7bf5,0x11ce979,0x0b408df,0x0366850 } },\n    /* 219 */\n    { { 0x28ea498,0x0886d5b,0x2e090e0,0x0a4d58f,0x2623478,0x0d74ab7,\n        0x2b83913,0x12c6b81,0x18d623f,0x01d8301 },\n      { 0x198aa79,0x26d6330,0x3a7f0b8,0x34bc1ea,0x2f74890,0x378955a,\n        0x204110f,0x0102538,0x02d8f19,0x01c5066 } },\n    /* 220 */\n    { { 0x14b0f45,0x2838cd3,0x14e16f0,0x0e0e4aa,0x2d9280b,0x0f18757,\n        0x3324c6b,0x1391ceb,0x1ce89d5,0x00ebe74 },\n      { 0x0930371,0x3de6048,0x3097fd8,0x1308705,0x3eda266,0x3108c26,\n        0x1545dcd,0x1f7583a,0x1c37395,0x02c7e05 } },\n    /* 221 */\n    { { 0x1fec44a,0x2a9e3a2,0x0caf84f,0x11cf2a9,0x0c8c2ae,0x06da989,\n        0x1c807dc,0x3c149a4,0x1141543,0x02906bb },\n      { 0x15ffe04,0x0d4e65f,0x2e20424,0x37d896d,0x18bacb2,0x1e05ddd,\n        0x1660be8,0x183be17,0x1dd86fb,0x035ba70 } },\n    /* 222 */\n    { { 0x2853264,0x0ba5fb1,0x0a0b3aa,0x2df88c1,0x2771533,0x23aba6f,\n        0x112bb7b,0x3e3086e,0x210ae9b,0x027271b },\n      { 0x030b74c,0x0269678,0x1e90a23,0x135a98c,0x24ed749,0x126de7c,\n        0x344b23a,0x186da27,0x19640fa,0x0159af5 } },\n    /* 223 */\n    { { 0x18061f3,0x3004630,0x3c70066,0x34df20f,0x1190b25,0x1c9cc91,\n        0x1fc8e02,0x0d17bc1,0x390f525,0x033cb1c },\n      { 0x0eb30cf,0x2f3ad04,0x303aa09,0x2e835dd,0x1cfd2eb,0x143fc95,\n        0x02c43a1,0x025e7a1,0x3558aa2,0x000bd45 } },\n    /* 224 */\n    { { 0x1db7d07,0x3bde52b,0x1500396,0x1089115,0x20b4fc7,0x1e2a8f3,\n        0x3f8eacc,0x365f7eb,0x1a5e8d4,0x0053a6b },\n      { 0x37079e2,0x120284b,0x000edaa,0x33792c2,0x145baa3,0x20e055f,\n        0x365e2d7,0x26ba005,0x3ab8e9d,0x0282b53 } },\n    /* 225 */\n    { { 0x2653618,0x2dd8852,0x2a5f0bf,0x0f0c7aa,0x2187281,0x1252757,\n        0x13e7374,0x3b47855,0x0b86e56,0x02f354c },\n      { 0x2e9c47b,0x2fa14cc,0x19ab169,0x3fad401,0x0dc2776,0x24afeed,\n        0x3a97611,0x0d07736,0x3cf6979,0x02424a0 } },\n    /* 226 */\n    { { 0x2e81a13,0x000c91d,0x123967b,0x265885c,0x29bee1a,0x0cb8675,\n        0x2d361bd,0x1526823,0x3c9ace1,0x00d7bad },\n      { 0x24e5bdc,0x02b969f,0x2c6e128,0x34edb3b,0x12dcd2c,0x3899af0,\n        0x24224c6,0x3a1914b,0x0f4448a,0x026a2cb } },\n    /* 227 */\n    { { 0x1d03b59,0x1c6fc82,0x32abf64,0x28ed96b,0x1c90e62,0x2f57bb2,\n        0x3ff168e,0x04de7fd,0x0f4d449,0x01af6d8 },\n      { 0x255bc30,0x2bfaf22,0x3fe0dad,0x0584025,0x1c79ead,0x3078ef7,\n        0x2197414,0x022a50b,0x0fd94ba,0x0007b0f } },\n    /* 228 */\n    { { 0x09485c2,0x09dfaf7,0x10c7ba6,0x1e48bec,0x248cc9a,0x028a362,\n        0x21d60f7,0x193d93d,0x1c04754,0x0346b2c },\n      { 0x2f36612,0x240ac49,0x0d8bd26,0x13b8186,0x259c3a4,0x020d5fb,\n        0x38a8133,0x09b0937,0x39d4056,0x01f7341 } },\n    /* 229 */\n    { { 0x05a4b48,0x1f534fc,0x07725ce,0x148dc8c,0x2adcd29,0x04aa456,\n        0x0f79718,0x066e346,0x189377d,0x002fd4d },\n      { 0x068ea73,0x336569b,0x184d35e,0x32a08e9,0x3c7f3bb,0x11ce9c8,\n        0x3674c6f,0x21bf27e,0x0d9e166,0x034a2f9 } },\n    /* 230 */\n    { { 0x0fa8e4b,0x2e6418e,0x18fc5d2,0x1ba24ff,0x0559f18,0x0dbedbf,\n        0x2de2aa4,0x22338e9,0x3aa510f,0x035d801 },\n      { 0x23a4988,0x02aad94,0x02732d1,0x111d374,0x0b455cf,0x0d01c9e,\n        0x067082a,0x2ec05fd,0x368b303,0x03cad4b } },\n    /* 231 */\n    { { 0x035b4ca,0x1fabea6,0x1cbc0d5,0x3f2ed9a,0x02d2232,0x1990c66,\n        0x2eb680c,0x3b4ea3b,0x18ecc5a,0x03636fa },\n      { 0x1a02709,0x26f8ff1,0x1fa8cba,0x397d6e8,0x230be68,0x043aa14,\n        0x3d43cdf,0x25c17fa,0x3a3ee55,0x0380564 } },\n    /* 232 */\n    { { 0x275a0a6,0x16bd43a,0x0033d3e,0x2b15e16,0x2512226,0x005d901,\n        0x26d50fd,0x3bc19bf,0x3b1aeb8,0x02bfb01 },\n      { 0x0bb0a31,0x26559e0,0x1aae7fb,0x330dcc2,0x16f1af3,0x06afce2,\n        0x13a15a0,0x2ff7645,0x3546e2d,0x029c6e4 } },\n    /* 233 */\n    { { 0x0f593d2,0x384b806,0x122bbf8,0x0a281e0,0x1d1a904,0x2e93cab,\n        0x0505db0,0x08f6454,0x05c6285,0x014e880 },\n      { 0x3f2b935,0x22d8e79,0x161a07c,0x16b060a,0x02bff97,0x146328b,\n        0x3ceea77,0x238f61a,0x19b3d58,0x02fd1f4 } },\n    /* 234 */\n    { { 0x17665d5,0x259e9f7,0x0de5672,0x15cbcbd,0x34e3030,0x035240f,\n        0x0005ae8,0x286d851,0x07f39c9,0x000070b },\n      { 0x1efc6d6,0x2a0051a,0x2724143,0x2a9ef1e,0x0c810bd,0x1e05429,\n        0x25670ba,0x2e66d7d,0x0e786ff,0x03f6b7e } },\n    /* 235 */\n    { { 0x3c00785,0x232e23f,0x2b67fd3,0x244ed23,0x077fa75,0x3cda3ef,\n        0x14d055b,0x0f25011,0x24d5aa4,0x00ea0e3 },\n      { 0x297bb9a,0x198ca4f,0x14d9561,0x18d1076,0x39eb933,0x2b6caa0,\n        0x1591a60,0x0768d45,0x257873e,0x00f36e0 } },\n    /* 236 */\n    { { 0x1e77eab,0x0502a5f,0x0109137,0x0350592,0x3f7e1c5,0x3ac7437,\n        0x2dcad2c,0x1fee9d8,0x089f1f5,0x0169833 },\n      { 0x0d45673,0x0d8e090,0x065580b,0x065644f,0x11b82be,0x3592dd0,\n        0x3284b8d,0x23f0015,0x16fdbfd,0x0248bfd } },\n    /* 237 */\n    { { 0x1a129a1,0x1977bb2,0x0e041b2,0x15f30a1,0x0a5b1ce,0x3afef8f,\n        0x380c46c,0x3358810,0x27df6c5,0x01ca466 },\n      { 0x3b90f9a,0x3d14ea3,0x031b298,0x02e2390,0x2d719c0,0x25bc615,\n        0x2c0e777,0x0226b8c,0x3803624,0x0179e45 } },\n    /* 238 */\n    { { 0x363cdfb,0x1bb155f,0x24fd5c1,0x1c7c72b,0x28e6a35,0x18165f2,\n        0x226bea5,0x0beaff3,0x371e24c,0x0138294 },\n      { 0x1765357,0x29034e9,0x22b4276,0x11035ce,0x23c89af,0x074468c,\n        0x3370ae4,0x013bae3,0x018d566,0x03d7fde } },\n    /* 239 */\n    { { 0x209df21,0x0f8ff86,0x0e47fbf,0x23b99ba,0x126d5d2,0x2722405,\n        0x16bd0a2,0x1799082,0x0e9533f,0x039077c },\n      { 0x3ba9e3f,0x3f6902c,0x1895305,0x3ac9813,0x3f2340c,0x3c0d9f1,\n        0x26e1927,0x0557c21,0x16eac4f,0x023b75f } },\n    /* 240 */\n    { { 0x3fc8ff3,0x0770382,0x342fc9a,0x0afa4db,0x314efd8,0x328e07b,\n        0x016f7cc,0x3ba599c,0x1caed8a,0x0050cb0 },\n      { 0x0b23c26,0x2120a5c,0x3273ec6,0x1cc1cd6,0x2a64fe8,0x2bbc3d6,\n        0x09f6e5e,0x34b1b8e,0x00b5ac8,0x032bbd2 } },\n    /* 241 */\n    { { 0x1315922,0x1725e1d,0x0ca5524,0x1c4c18f,0x3d82951,0x193bcb2,\n        0x0e60d0b,0x388dbcf,0x37e8efa,0x0342e85 },\n      { 0x1b3af60,0x26ba3ec,0x220e53a,0x394f4b6,0x01a796a,0x3e7bbca,\n        0x163605d,0x2b85807,0x17c1c54,0x03cc725 } },\n    /* 242 */\n    { { 0x1cc4597,0x1635492,0x2028c0f,0x2c2eb82,0x2dc5015,0x0d2a052,\n        0x05fc557,0x1f0ebbf,0x0cb96e1,0x0004d01 },\n      { 0x1a824bf,0x3896172,0x2ed7b29,0x178007a,0x0d59318,0x07bda2b,\n        0x2ee6826,0x0f9b235,0x04b9193,0x01bcddf } },\n    /* 243 */\n    { { 0x0333fd2,0x0eeb46a,0x15b89f9,0x00968aa,0x2a89302,0x2bdd6b3,\n        0x1e5037e,0x2541884,0x24ed2d0,0x01b6e8f },\n      { 0x04399cd,0x3be6334,0x3adea48,0x1bb9adc,0x31811c6,0x05fb2bc,\n        0x360752c,0x3d29dcb,0x3423bec,0x03c4f3c } },\n    /* 244 */\n    { { 0x119e2eb,0x2e7b02a,0x0f68cee,0x257d8b0,0x183a9a1,0x2ae88a6,\n        0x3a3bb67,0x2eb4f3e,0x1a9274b,0x0320fea },\n      { 0x2fa1ce0,0x346c2d8,0x2fbf0d7,0x3d4d063,0x0e58b60,0x09c1bc1,\n        0x28ef9e5,0x09a0efe,0x0f45d70,0x02d275c } },\n    /* 245 */\n    { { 0x2d5513b,0x31d443e,0x1e2d914,0x3b2c5d4,0x105f32e,0x27ee756,\n        0x050418d,0x3c73db6,0x1bb0c30,0x01673eb },\n      { 0x1cb7fd6,0x1eb08d5,0x26a3e16,0x2e20810,0x0249367,0x029e219,\n        0x2ec58c9,0x12d9fab,0x362354a,0x016eafc } },\n    /* 246 */\n    { { 0x2424865,0x260747b,0x177f37c,0x1e3cb95,0x08b0028,0x2783016,\n        0x2970f1b,0x323c1c0,0x2a79026,0x0186231 },\n      { 0x0f244da,0x26866f4,0x087306f,0x173ec20,0x31ecced,0x3c84d8d,\n        0x070f9b9,0x2e764d5,0x075df50,0x0264ff9 } },\n    /* 247 */\n    { { 0x32c3609,0x0c737e6,0x14ea68e,0x300b11b,0x184eb19,0x29dd440,\n        0x09ec1a9,0x185adeb,0x0664c80,0x0207dd9 },\n      { 0x1fbe978,0x30a969d,0x33561d7,0x34fc60e,0x36743fe,0x00774af,\n        0x0d1f045,0x018360e,0x12a5fe9,0x01592a0 } },\n    /* 248 */\n    { { 0x2817d1d,0x2993d3e,0x2e0f7a5,0x112faa0,0x255f968,0x355fe6a,\n        0x3f5a0fc,0x075b2d7,0x3cf00e5,0x0089afc },\n      { 0x32833cf,0x06a7e4b,0x09a8d6d,0x1693d3e,0x320a0a3,0x3cfdfdd,\n        0x136c498,0x1e0d845,0x347ff25,0x01a1de7 } },\n    /* 249 */\n    { { 0x3043d08,0x030705c,0x20fa79b,0x1d07f00,0x0a54467,0x29b49b4,\n        0x367e289,0x0b82f4d,0x0d1eb09,0x025ef2c },\n      { 0x32ed3c3,0x1baaa3c,0x3c482ab,0x146ca06,0x3c8a4f1,0x3e85e3c,\n        0x1bf4f3b,0x1195534,0x3e80a78,0x02a1cbf } },\n    /* 250 */\n    { { 0x32b2086,0x2de4d68,0x3486b1a,0x03a0583,0x2e1eb71,0x2dab9af,\n        0x10cd913,0x28daa6f,0x3fcb732,0x000a04a },\n      { 0x3605318,0x3f5f2b3,0x2d1da63,0x143f7f5,0x1646e5d,0x040b586,\n        0x1683982,0x25abe87,0x0c9fe53,0x001ce47 } },\n    /* 251 */\n    { { 0x380d02b,0x055fc22,0x3f7fc50,0x3458a1d,0x26b8333,0x23550ab,\n        0x0a1af87,0x0a821eb,0x2dc7e6d,0x00d574a },\n      { 0x07386e1,0x3ccd68a,0x3275b41,0x253e390,0x2fd272a,0x1e6627a,\n        0x2ca2cde,0x0e9e4a1,0x1e37c2a,0x00f70ac } },\n    /* 252 */\n    { { 0x0581352,0x2748701,0x02bed68,0x094dd9e,0x30a00c8,0x3fb5c07,\n        0x3bd5909,0x211ac80,0x1103ccd,0x0311e1a },\n      { 0x0c768ed,0x29dc209,0x36575db,0x009a107,0x272feea,0x2b33383,\n        0x313ed56,0x134c9cc,0x168d5bb,0x033310a } },\n    /* 253 */\n    { { 0x17620b9,0x143784f,0x256a94e,0x229664a,0x1d89a5c,0x1d521f2,\n        0x0076406,0x1c73f70,0x342aa48,0x03851fa },\n      { 0x0f3ae46,0x2ad3bab,0x0fbe274,0x3ed40d4,0x2fd4936,0x232103a,\n        0x2afe474,0x25b8f7c,0x047080e,0x008e6b0 } },\n    /* 254 */\n    { { 0x3fee8d4,0x347cd4a,0x0fec481,0x33fe9ec,0x0ce80b5,0x33a6bcf,\n        0x1c4c9e2,0x3967441,0x1a3f5f7,0x03157e8 },\n      { 0x257c227,0x1bc53a0,0x200b318,0x0fcd0af,0x2c5b165,0x2a413ec,\n        0x2fc998a,0x2da6426,0x19cd4f4,0x0025336 } },\n    /* 255 */\n    { { 0x303beba,0x2072135,0x32918a9,0x140cb3a,0x08631d1,0x0ef527b,\n        0x05f2c9e,0x2b4ce91,0x0b642ab,0x02e428c },\n      { 0x0a5abf9,0x15013ed,0x3603b46,0x30dd76d,0x3004750,0x28d7627,\n        0x1a42ccc,0x093ddbe,0x39a1b79,0x00067e2 } },\n};\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_10(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_stripe_10(r, &p256_base, p256_table,\n                                      k, map, heap);\n}\n\n#endif\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[10];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 10, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 10, km);\n\n            err = sp_256_ecc_mulmod_base_10(point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_10(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                                        defined(HAVE_ECC_VERIFY)\n/* Returns 1 if the number of zero.\n * Implementation is constant time.\n *\n * a  Number to check.\n * returns 1 if the number is zero and 0 otherwise.\n */\nstatic int sp_256_iszero_10(const sp_digit* a)\n{\n    return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] |\n            a[8] | a[9]) == 0;\n}\n\n#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\n/* Add 1 to a. (a = a + 1)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_256_add_one_10(sp_digit* a)\n{\n    a[0]++;\n    sp_256_norm_10(a);\n}\n\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 18U) {\n            r[j] &= 0x3ffffff;\n            s = 26U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Generates a scalar that is in the range 1..order-1.\n *\n * rng  Random number generator.\n * k    Scalar value.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nstatic int sp_256_ecc_gen_k_10(WC_RNG* rng, sp_digit* k)\n{\n    int err;\n    byte buf[32];\n\n    do {\n        err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));\n        if (err == 0) {\n            sp_256_from_bin(k, 10, buf, (int)sizeof(buf));\n            if (sp_256_cmp_10(k, p256_order2) < 0) {\n                sp_256_add_one_10(k);\n                break;\n            }\n        }\n    }\n    while (err == 0);\n\n    return err;\n}\n\n/* Makes a random EC key pair.\n *\n * rng   Random number generator.\n * priv  Generated private value.\n * pub   Generated public point.\n * heap  Heap to use for allocation.\n * returns ECC_INF_E when the point does not have the correct order, RNG\n * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[10];\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point inf;\n#endif\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point* infinity;\n#endif\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, inf, infinity);\n    }\n#endif\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 10, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_ecc_gen_k_10(rng, k);\n    }\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_base_10(point, k, 1, NULL);\n    }\n\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_10(infinity, point, p256_order, 1, NULL);\n    }\n    if (err == MP_OKAY) {\n        if ((sp_256_iszero_10(point->x) == 0) || (sp_256_iszero_10(point->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(k, priv);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_10(point, pub);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_ecc_point_free(infinity, 1, heap);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n\n#ifdef HAVE_ECC_DHE\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 32\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_256_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    for (i=0; i<9; i++) {\n        r[i+1] += r[i] >> 26;\n        r[i] &= 0x3ffffff;\n    }\n    j = 256 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<10 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 26) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 26);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n/* Multiply the point by the scalar and serialize the X ordinate.\n * The number is 0 padded to maximum size on output.\n *\n * priv    Scalar to multiply the point by.\n * pub     Point to multiply.\n * out     Buffer to hold X ordinate.\n * outLen  On entry, size of the buffer in bytes.\n *         On exit, length of data in buffer in bytes.\n * heap    Heap to use for allocation.\n * returns BUFFER_E if the buffer is to small for output size,\n * MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out,\n                          word32* outLen, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[10];\n#endif\n    sp_point* point = NULL;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    if (*outLen < 32U) {\n        err = BUFFER_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p, point);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 10, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 10, priv);\n        sp_256_point_from_ecc_point_10(point, pub);\n            err = sp_256_ecc_mulmod_10(point, point, k, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        sp_256_to_bin(point->x, out);\n        *outLen = 32;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_DHE */\n\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_256_mul_d_10(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int64_t tb = b;\n    int64_t t = 0;\n    int i;\n\n    for (i = 0; i < 10; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x3ffffff;\n        t >>= 26;\n    }\n    r[10] = (sp_digit)t;\n#else\n    int64_t tb = b;\n    int64_t t[10];\n\n    t[ 0] = tb * a[ 0];\n    t[ 1] = tb * a[ 1];\n    t[ 2] = tb * a[ 2];\n    t[ 3] = tb * a[ 3];\n    t[ 4] = tb * a[ 4];\n    t[ 5] = tb * a[ 5];\n    t[ 6] = tb * a[ 6];\n    t[ 7] = tb * a[ 7];\n    t[ 8] = tb * a[ 8];\n    t[ 9] = tb * a[ 9];\n    r[ 0] =                           (t[ 0] & 0x3ffffff);\n    r[ 1] = (sp_digit)(t[ 0] >> 26) + (t[ 1] & 0x3ffffff);\n    r[ 2] = (sp_digit)(t[ 1] >> 26) + (t[ 2] & 0x3ffffff);\n    r[ 3] = (sp_digit)(t[ 2] >> 26) + (t[ 3] & 0x3ffffff);\n    r[ 4] = (sp_digit)(t[ 3] >> 26) + (t[ 4] & 0x3ffffff);\n    r[ 5] = (sp_digit)(t[ 4] >> 26) + (t[ 5] & 0x3ffffff);\n    r[ 6] = (sp_digit)(t[ 5] >> 26) + (t[ 6] & 0x3ffffff);\n    r[ 7] = (sp_digit)(t[ 6] >> 26) + (t[ 7] & 0x3ffffff);\n    r[ 8] = (sp_digit)(t[ 7] >> 26) + (t[ 8] & 0x3ffffff);\n    r[ 9] = (sp_digit)(t[ 8] >> 26) + (t[ 9] & 0x3ffffff);\n    r[10] = (sp_digit)(t[ 9] >> 26);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SP_DIV_32\nstatic WC_INLINE sp_digit sp_256_div_word_10(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t, dv;\n    int64_t t0, t1;\n\n    /* dv has 14 bits. */\n    dv = (div >> 12) + 1;\n    /* All 26 bits from d1 and top 5 bits from d0. */\n    d = (d1 << 5) | (d0 >> 21);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 17 bits in r */\n    /* Next 9 bits from d0. */\n    d <<= 9;\n    r <<= 9;\n    d |= (d0 >> 12) & ((1 << 9) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 26 bits in r */\n\n    /* Handle rounding error with dv - top part */\n    t0 = ((int64_t)d1 << 26) + d0;\n    t1 = (int64_t)r * dv;\n    t1 = t0 - t1;\n    t = (sp_digit)(t1 >> 12) / dv;\n    r += t;\n\n    /* Handle rounding error with dv - bottom 32 bits */\n    t1 = (sp_digit)t0 - (r * dv);\n    t = (sp_digit)t1 / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_32 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Number to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_256_div_10(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_32\n    int64_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[20], t2d[10 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (3 * 10 + 1), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 2 * 10;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        dv = d[9];\n        XMEMCPY(t1, a, sizeof(*t1) * 2U * 10U);\n        for (i=9; i>=0; i--) {\n            t1[10 + i] += t1[10 + i - 1] >> 26;\n            t1[10 + i - 1] &= 0x3ffffff;\n#ifndef WOLFSSL_SP_DIV_32\n            d1 = t1[10 + i];\n            d1 <<= 26;\n            d1 += t1[10 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_256_div_word_10(t1[10 + i], t1[10 + i - 1], dv);\n#endif\n\n            sp_256_mul_d_10(t2, d, r1);\n            (void)sp_256_sub_10(&t1[i], &t1[i], t2);\n            t1[10 + i] -= t2[10];\n            t1[10 + i] += t1[10 + i - 1] >> 26;\n            t1[10 + i - 1] &= 0x3ffffff;\n            r1 = (((-t1[10 + i]) << 26) - t1[10 + i - 1]) / dv;\n            r1++;\n            sp_256_mul_d_10(t2, d, r1);\n            (void)sp_256_add_10(&t1[i], &t1[i], t2);\n            t1[10 + i] += t1[10 + i - 1] >> 26;\n            t1[10 + i - 1] &= 0x3ffffff;\n        }\n        t1[10 - 1] += t1[10 - 2] >> 26;\n        t1[10 - 2] &= 0x3ffffff;\n        d1 = t1[10 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_256_mul_d_10(t2, d, r1);\n        (void)sp_256_sub_10(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 10U);\n        for (i=0; i<8; i++) {\n            r[i+1] += r[i] >> 26;\n            r[i] &= 0x3ffffff;\n        }\n        sp_256_cond_add_10(r, r, d, 0 - ((r[9] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_256_mod_10(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_256_div_10(a, m, NULL, r);\n}\n\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#ifdef WOLFSSL_SP_SMALL\n/* Order-2 for the P256 curve. */\nstatic const uint32_t p256_order_2[8] = {\n    0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU,0xffffffffU,0xffffffffU,\n    0x00000000U,0xffffffffU\n};\n#else\n/* The low half of the order-2 of the P256 curve. */\nstatic const uint32_t p256_order_low[4] = {\n    0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU\n};\n#endif /* WOLFSSL_SP_SMALL */\n\n/* Multiply two number mod the order of P256 curve. (r = a * b mod order)\n *\n * r  Result of the multiplication.\n * a  First operand of the multiplication.\n * b  Second operand of the multiplication.\n */\nstatic void sp_256_mont_mul_order_10(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_256_mul_10(r, a, b);\n    sp_256_mont_reduce_order_10(r, p256_order, p256_mp_order);\n}\n\n/* Square number mod the order of P256 curve. (r = a * a mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_order_10(sp_digit* r, const sp_digit* a)\n{\n    sp_256_sqr_10(r, a);\n    sp_256_mont_reduce_order_10(r, p256_order, p256_mp_order);\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Square number mod the order of P256 curve a number of times.\n * (r = a ^ n mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_n_order_10(sp_digit* r, const sp_digit* a, int n)\n{\n    int i;\n\n    sp_256_mont_sqr_order_10(r, a);\n    for (i=1; i<n; i++) {\n        sp_256_mont_sqr_order_10(r, r);\n    }\n}\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the order of the P256 curve.\n * (r = 1 / a mod order)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_order_10(sp_digit* r, const sp_digit* a,\n        sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 10);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_order_10(t, t);\n        if ((p256_order_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_10(t, t, a);\n        }\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 10U);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 10;\n    sp_digit* t3 = td + 4 * 10;\n    int i;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_order_10(t, a);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_order_10(t, t, a);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_order_10(t2, t, 2);\n    /* t3= a^f = t2 * t */\n    sp_256_mont_mul_order_10(t3, t2, t);\n    /* t2= a^f0 = t3 ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_order_10(t2, t3, 4);\n    /* t = a^ff = t2 * t3 */\n    sp_256_mont_mul_order_10(t, t2, t3);\n    /* t3= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_order_10(t2, t, 8);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_order_10(t, t2, t);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_order_10(t2, t, 16);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_order_10(t, t2, t);\n    /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64  */\n    sp_256_mont_sqr_n_order_10(t2, t, 64);\n    /* t2= a^ffffffff00000000ffffffff = t2 * t */\n    sp_256_mont_mul_order_10(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_order_10(t2, t2, 32);\n    /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_order_10(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6 */\n    for (i=127; i>=112; i--) {\n        sp_256_mont_sqr_order_10(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_10(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6f */\n    sp_256_mont_sqr_n_order_10(t2, t2, 4);\n    sp_256_mont_mul_order_10(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */\n    for (i=107; i>=64; i--) {\n        sp_256_mont_sqr_order_10(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_10(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */\n    sp_256_mont_sqr_n_order_10(t2, t2, 4);\n    sp_256_mont_mul_order_10(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */\n    for (i=59; i>=32; i--) {\n        sp_256_mont_sqr_order_10(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_10(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */\n    sp_256_mont_sqr_n_order_10(t2, t2, 4);\n    sp_256_mont_mul_order_10(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */\n    for (i=27; i>=0; i--) {\n        sp_256_mont_sqr_order_10(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_10(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */\n    sp_256_mont_sqr_n_order_10(t2, t2, 4);\n    /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */\n    sp_256_mont_mul_order_10(r, t2, t3);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\n#ifdef HAVE_ECC_SIGN\n#ifndef SP_ECC_MAX_SIG_GEN\n#define SP_ECC_MAX_SIG_GEN  64\n#endif\n\n/* Sign the hash using the private key.\n *   e = [hash, 256 bits] from binary\n *   r = (k.G)->x mod order\n *   s = (r * x + e) / k mod order\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,\n                    mp_int* rm, mp_int* sm, mp_int* km, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit ed[2*10];\n    sp_digit xd[2*10];\n    sp_digit kd[2*10];\n    sp_digit rd[2*10];\n    sp_digit td[3 * 2*10];\n    sp_point p;\n#endif\n    sp_digit* e = NULL;\n    sp_digit* x = NULL;\n    sp_digit* k = NULL;\n    sp_digit* r = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* point = NULL;\n    sp_digit carry;\n    sp_digit* s = NULL;\n    sp_digit* kInv = NULL;\n    int err = MP_OKAY;\n    int32_t c;\n    int i;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 10, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        e = d + 0 * 10;\n        x = d + 2 * 10;\n        k = d + 4 * 10;\n        r = d + 6 * 10;\n        tmp = d + 8 * 10;\n#else\n        e = ed;\n        x = xd;\n        k = kd;\n        r = rd;\n        tmp = td;\n#endif\n        s = e;\n        kInv = k;\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(e, 10, hash, (int)hashLen);\n    }\n\n    for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {\n        sp_256_from_mp(x, 10, priv);\n\n        /* New random point. */\n        if (km == NULL || mp_iszero(km)) {\n            err = sp_256_ecc_gen_k_10(rng, k);\n        }\n        else {\n            sp_256_from_mp(k, 10, km);\n            mp_zero(km);\n        }\n        if (err == MP_OKAY) {\n                err = sp_256_ecc_mulmod_base_10(point, k, 1, NULL);\n        }\n\n        if (err == MP_OKAY) {\n            /* r = point->x mod order */\n            XMEMCPY(r, point->x, sizeof(sp_digit) * 10U);\n            sp_256_norm_10(r);\n            c = sp_256_cmp_10(r, p256_order);\n            sp_256_cond_sub_10(r, r, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_10(r);\n\n            /* Conv k to Montgomery form (mod order) */\n                sp_256_mul_10(k, k, p256_norm_order);\n            err = sp_256_mod_10(k, k, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_10(k);\n            /* kInv = 1/k mod order */\n                sp_256_mont_inv_order_10(kInv, k, tmp);\n            sp_256_norm_10(kInv);\n\n            /* s = r * x + e */\n                sp_256_mul_10(x, x, r);\n            err = sp_256_mod_10(x, x, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_10(x);\n            carry = sp_256_add_10(s, e, x);\n            sp_256_cond_sub_10(s, s, p256_order, 0 - carry);\n            sp_256_norm_10(s);\n            c = sp_256_cmp_10(s, p256_order);\n            sp_256_cond_sub_10(s, s, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_10(s);\n\n            /* s = s * k^-1 mod order */\n                sp_256_mont_mul_order_10(s, s, kInv);\n            sp_256_norm_10(s);\n\n            /* Check that signature is usable. */\n            if (sp_256_iszero_10(s) == 0) {\n                break;\n            }\n        }\n    }\n\n    if (i == 0) {\n        err = RNG_FAILURE_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(r, rm);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(s, sm);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XMEMSET(d, 0, sizeof(sp_digit) * 8 * 10);\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    XMEMSET(e, 0, sizeof(sp_digit) * 2U * 10U);\n    XMEMSET(x, 0, sizeof(sp_digit) * 2U * 10U);\n    XMEMSET(k, 0, sizeof(sp_digit) * 2U * 10U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 10U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 10U);\n    XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 10U);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_SIGN */\n\n#ifdef HAVE_ECC_VERIFY\n/* Verify the signature values with the hash and public key.\n *   e = Truncate(hash, 256)\n *   u1 = e/s mod order\n *   u2 = r/s mod order\n *   r == (u1.G + u2.Q)->x mod order\n * Optimization: Leave point in projective form.\n *   (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')\n *   (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,\n    mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit u1d[2*10];\n    sp_digit u2d[2*10];\n    sp_digit sd[2*10];\n    sp_digit tmpd[2*10 * 5];\n    sp_point p1d;\n    sp_point p2d;\n#endif\n    sp_digit* u1 = NULL;\n    sp_digit* u2 = NULL;\n    sp_digit* s = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* p1;\n    sp_point* p2 = NULL;\n    sp_digit carry;\n    int32_t c;\n    int err;\n\n    err = sp_ecc_point_new(heap, p1d, p1);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p2d, p2);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 10, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        u1  = d + 0 * 10;\n        u2  = d + 2 * 10;\n        s   = d + 4 * 10;\n        tmp = d + 6 * 10;\n#else\n        u1 = u1d;\n        u2 = u2d;\n        s  = sd;\n        tmp = tmpd;\n#endif\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(u1, 10, hash, (int)hashLen);\n        sp_256_from_mp(u2, 10, r);\n        sp_256_from_mp(s, 10, sm);\n        sp_256_from_mp(p2->x, 10, pX);\n        sp_256_from_mp(p2->y, 10, pY);\n        sp_256_from_mp(p2->z, 10, pZ);\n\n        {\n            sp_256_mul_10(s, s, p256_norm_order);\n        }\n        err = sp_256_mod_10(s, s, p256_order);\n    }\n    if (err == MP_OKAY) {\n        sp_256_norm_10(s);\n        {\n            sp_256_mont_inv_order_10(s, s, tmp);\n            sp_256_mont_mul_order_10(u1, u1, s);\n            sp_256_mont_mul_order_10(u2, u2, s);\n        }\n\n            err = sp_256_ecc_mulmod_base_10(p1, u1, 0, heap);\n    }\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_10(p2, p2, u2, 0, heap);\n    }\n\n    if (err == MP_OKAY) {\n        {\n            sp_256_proj_point_add_10(p1, p1, p2, tmp);\n            if (sp_256_iszero_10(p1->z)) {\n                if (sp_256_iszero_10(p1->x) && sp_256_iszero_10(p1->y)) {\n                    sp_256_proj_point_dbl_10(p1, p2, tmp);\n                }\n                else {\n                    /* Y ordinate is not used from here - don't set. */\n                    p1->x[0] = 0;\n                    p1->x[1] = 0;\n                    p1->x[2] = 0;\n                    p1->x[3] = 0;\n                    p1->x[4] = 0;\n                    p1->x[5] = 0;\n                    p1->x[6] = 0;\n                    p1->x[7] = 0;\n                    p1->x[8] = 0;\n                    p1->x[9] = 0;\n                    XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));\n                }\n            }\n        }\n\n        /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */\n        /* Reload r and convert to Montgomery form. */\n        sp_256_from_mp(u2, 10, r);\n        err = sp_256_mod_mul_norm_10(u2, u2, p256_mod);\n    }\n\n    if (err == MP_OKAY) {\n        /* u1 = r.z'.z' mod prime */\n        sp_256_mont_sqr_10(p1->z, p1->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_10(u1, u2, p1->z, p256_mod, p256_mp_mod);\n        *res = (int)(sp_256_cmp_10(p1->x, u1) == 0);\n        if (*res == 0) {\n            /* Reload r and add order. */\n            sp_256_from_mp(u2, 10, r);\n            carry = sp_256_add_10(u2, u2, p256_order);\n            /* Carry means result is greater than mod and is not valid. */\n            if (carry == 0) {\n                sp_256_norm_10(u2);\n\n                /* Compare with mod and if greater or equal then not valid. */\n                c = sp_256_cmp_10(u2, p256_mod);\n                if (c < 0) {\n                    /* Convert to Montogomery form */\n                    err = sp_256_mod_mul_norm_10(u2, u2, p256_mod);\n                    if (err == MP_OKAY) {\n                        /* u1 = (r + 1*order).z'.z' mod prime */\n                        sp_256_mont_mul_10(u1, u2, p1->z, p256_mod,\n                                                                  p256_mp_mod);\n                        *res = (int)(sp_256_cmp_10(p1->x, u1) == 0);\n                    }\n                }\n            }\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n#endif\n    sp_ecc_point_free(p1, 0, heap);\n    sp_ecc_point_free(p2, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_VERIFY */\n\n#ifdef HAVE_ECC_CHECK_KEY\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * point  EC point.\n * heap   Heap to use if dynamically allocating.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nstatic int sp_256_ecc_is_point_10(sp_point* point, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit t1d[2*10];\n    sp_digit t2d[2*10];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 10 * 4, heap, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 10;\n        t2 = d + 2 * 10;\n#else\n        (void)heap;\n\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        sp_256_sqr_10(t1, point->y);\n        (void)sp_256_mod_10(t1, t1, p256_mod);\n        sp_256_sqr_10(t2, point->x);\n        (void)sp_256_mod_10(t2, t2, p256_mod);\n        sp_256_mul_10(t2, t2, point->x);\n        (void)sp_256_mod_10(t2, t2, p256_mod);\n        (void)sp_256_sub_10(t2, p256_mod, t2);\n        sp_256_mont_add_10(t1, t1, t2, p256_mod);\n\n        sp_256_mont_add_10(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_10(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_10(t1, t1, point->x, p256_mod);\n\n        if (sp_256_cmp_10(t1, p256_b) != 0) {\n            err = MP_VAL;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * pX  X ordinate of EC point.\n * pY  Y ordinate of EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nint sp_ecc_is_point_256(mp_int* pX, mp_int* pY)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point pubd;\n#endif\n    sp_point* pub;\n    byte one[1] = { 1 };\n    int err;\n\n    err = sp_ecc_point_new(NULL, pubd, pub);\n    if (err == MP_OKAY) {\n        sp_256_from_mp(pub->x, 10, pX);\n        sp_256_from_mp(pub->y, 10, pY);\n        sp_256_from_bin(pub->z, 10, one, (int)sizeof(one));\n\n        err = sp_256_ecc_is_point_10(pub, NULL);\n    }\n\n    sp_ecc_point_free(pub, 0, NULL);\n\n    return err;\n}\n\n/* Check that the private scalar generates the EC point (px, py), the point is\n * on the curve and the point has the correct order.\n *\n * pX     X ordinate of EC point.\n * pY     Y ordinate of EC point.\n * privm  Private scalar that generates EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve, ECC_INF_E if the point does not have the correct order,\n * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and\n * MP_OKAY otherwise.\n */\nint sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit privd[10];\n    sp_point pubd;\n    sp_point pd;\n#endif\n    sp_digit* priv = NULL;\n    sp_point* pub;\n    sp_point* p = NULL;\n    byte one[1] = { 1 };\n    int err;\n\n    err = sp_ecc_point_new(heap, pubd, pub);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 10, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (priv == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK))\n        priv = privd;\n#endif\n\n        sp_256_from_mp(pub->x, 10, pX);\n        sp_256_from_mp(pub->y, 10, pY);\n        sp_256_from_bin(pub->z, 10, one, (int)sizeof(one));\n        sp_256_from_mp(priv, 10, privm);\n\n        /* Check point at infinitiy. */\n        if ((sp_256_iszero_10(pub->x) != 0) &&\n            (sp_256_iszero_10(pub->y) != 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check range of X and Y */\n        if (sp_256_cmp_10(pub->x, p256_mod) >= 0 ||\n            sp_256_cmp_10(pub->y, p256_mod) >= 0) {\n            err = ECC_OUT_OF_RANGE_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check point is on curve */\n        err = sp_256_ecc_is_point_10(pub, heap);\n    }\n\n    if (err == MP_OKAY) {\n        /* Point * order = infinity */\n            err = sp_256_ecc_mulmod_10(p, pub, p256_order, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is infinity */\n        if ((sp_256_iszero_10(p->x) == 0) ||\n            (sp_256_iszero_10(p->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Base * private = point */\n            err = sp_256_ecc_mulmod_base_10(p, priv, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is public key */\n        if (sp_256_cmp_10(p->x, pub->x) != 0 ||\n            sp_256_cmp_10(p->y, pub->y) != 0) {\n            err = ECC_PRIV_KEY_E;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (priv != NULL) {\n        XFREE(priv, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(pub, 0, heap);\n\n    return err;\n}\n#endif\n#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL\n/* Add two projective EC points together.\n * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)\n *\n * pX   First EC point's X ordinate.\n * pY   First EC point's Y ordinate.\n * pZ   First EC point's Z ordinate.\n * qX   Second EC point's X ordinate.\n * qY   Second EC point's Y ordinate.\n * qZ   Second EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* qX, mp_int* qY, mp_int* qZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 10 * 5];\n    sp_point pd;\n    sp_point qd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    sp_point* q = NULL;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(NULL, qd, q);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 10, pX);\n        sp_256_from_mp(p->y, 10, pY);\n        sp_256_from_mp(p->z, 10, pZ);\n        sp_256_from_mp(q->x, 10, qX);\n        sp_256_from_mp(q->y, 10, qY);\n        sp_256_from_mp(q->z, 10, qZ);\n\n            sp_256_proj_point_add_10(p, p, q, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(q, 0, NULL);\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Double a projective EC point.\n * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 10 * 2];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 2, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 10, pX);\n        sp_256_from_mp(p->y, 10, pY);\n        sp_256_from_mp(p->z, 10, pZ);\n\n            sp_256_proj_point_dbl_10(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Map a projective EC point to affine in place.\n * pZ will be one.\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 10 * 4];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 4, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 10, pX);\n        sp_256_from_mp(p->y, 10, pY);\n        sp_256_from_mp(p->z, 10, pZ);\n\n        sp_256_map_10(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, pX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */\n#ifdef HAVE_COMP_KEY\n/* Find the square root of a number mod the prime of the curve.\n *\n * y  The number to operate on and the result.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nstatic int sp_256_mont_sqrt_10(sp_digit* y)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit t1d[2 * 10];\n    sp_digit t2d[2 * 10];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 10, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 10;\n        t2 = d + 2 * 10;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        {\n            /* t2 = y ^ 0x2 */\n            sp_256_mont_sqr_10(t2, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0x3 */\n            sp_256_mont_mul_10(t1, t2, y, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xc */\n            sp_256_mont_sqr_n_10(t2, t1, 2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xf */\n            sp_256_mont_mul_10(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xf0 */\n            sp_256_mont_sqr_n_10(t2, t1, 4, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xff */\n            sp_256_mont_mul_10(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xff00 */\n            sp_256_mont_sqr_n_10(t2, t1, 8, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffff */\n            sp_256_mont_mul_10(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xffff0000 */\n            sp_256_mont_sqr_n_10(t2, t1, 16, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff */\n            sp_256_mont_mul_10(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000000 */\n            sp_256_mont_sqr_n_10(t1, t1, 32, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001 */\n            sp_256_mont_mul_10(t1, t1, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */\n            sp_256_mont_sqr_n_10(t1, t1, 96, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */\n            sp_256_mont_mul_10(t1, t1, y, p256_mod, p256_mp_mod);\n            sp_256_mont_sqr_n_10(y, t1, 94, p256_mod, p256_mp_mod);\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Uncompress the point given the X ordinate.\n *\n * xm    X ordinate.\n * odd   Whether the Y ordinate is odd.\n * ym    Calculated Y ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit xd[2 * 10];\n    sp_digit yd[2 * 10];\n#endif\n    sp_digit* x = NULL;\n    sp_digit* y = NULL;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 10, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        x = d + 0 * 10;\n        y = d + 2 * 10;\n#else\n        x = xd;\n        y = yd;\n#endif\n\n        sp_256_from_mp(x, 10, xm);\n        err = sp_256_mod_mul_norm_10(x, x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        /* y = x^3 */\n        {\n            sp_256_mont_sqr_10(y, x, p256_mod, p256_mp_mod);\n            sp_256_mont_mul_10(y, y, x, p256_mod, p256_mp_mod);\n        }\n        /* y = x^3 - 3x */\n        sp_256_mont_sub_10(y, y, x, p256_mod);\n        sp_256_mont_sub_10(y, y, x, p256_mod);\n        sp_256_mont_sub_10(y, y, x, p256_mod);\n        /* y = x^3 - 3x + b */\n        err = sp_256_mod_mul_norm_10(x, p256_b, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        sp_256_mont_add_10(y, y, x, p256_mod);\n        /* y = sqrt(x^3 - 3x + b) */\n        err = sp_256_mont_sqrt_10(y);\n    }\n    if (err == MP_OKAY) {\n        XMEMSET(y + 10, 0, 10U * sizeof(sp_digit));\n        sp_256_mont_reduce_10(y, p256_mod, p256_mp_mod);\n        if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {\n            sp_256_mont_sub_10(y, p256_mod, y, p256_mod);\n        }\n\n        err = sp_256_to_mp(y, ym);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n#endif\n#endif /* !WOLFSSL_SP_NO_256 */\n#endif /* WOLFSSL_HAVE_SP_ECC */\n#endif /* SP_WORD_SIZE == 32 */\n#endif /* !WOLFSSL_SP_ASM */\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */\n"
  },
  {
    "path": "src/wolfcrypt/src/sp_c64.c",
    "content": "/* sp.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/* Implementation by Sean Parkinson. */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/cpuid.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \\\n                                    defined(WOLFSSL_HAVE_SP_ECC)\n\n#ifdef RSA_LOW_MEM\n#ifndef SP_RSA_PRIVATE_EXP_D\n#define SP_RSA_PRIVATE_EXP_D\n#endif\n\n#ifndef WOLFSSL_SP_SMALL\n#define WOLFSSL_SP_SMALL\n#endif\n#endif\n\n#include <wolfssl/wolfcrypt/sp.h>\n\n#ifndef WOLFSSL_SP_ASM\n#if SP_WORD_SIZE == 64\n#if (defined(WOLFSSL_SP_CACHE_RESISTANT) || defined(WOLFSSL_SP_SMALL)) &&              (defined(WOLFSSL_HAVE_SP_ECC) || !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Mask for address to obfuscate which of the two address will be used. */\nstatic const size_t addr_mask[2] = { 0, (size_t)-1 };\n#endif\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n#ifndef WOLFSSL_SP_NO_2048\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 49U) {\n            r[j] &= 0x1ffffffffffffffL;\n            s = 57U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 57\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 57\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0x1ffffffffffffffL;\n        s = 57U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 57U) <= (word32)DIGIT_BIT) {\n            s += 57U;\n            r[j] &= 0x1ffffffffffffffL;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 57) {\n            r[j] &= 0x1ffffffffffffffL;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 57 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 256\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_2048_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    for (i=0; i<35; i++) {\n        r[i+1] += r[i] >> 57;\n        r[i] &= 0x1ffffffffffffffL;\n    }\n    j = 2048 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<36 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 57) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 57);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_9(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int128_t t0   = ((int128_t)a[ 0]) * b[ 0];\n    int128_t t1   = ((int128_t)a[ 0]) * b[ 1]\n                 + ((int128_t)a[ 1]) * b[ 0];\n    int128_t t2   = ((int128_t)a[ 0]) * b[ 2]\n                 + ((int128_t)a[ 1]) * b[ 1]\n                 + ((int128_t)a[ 2]) * b[ 0];\n    int128_t t3   = ((int128_t)a[ 0]) * b[ 3]\n                 + ((int128_t)a[ 1]) * b[ 2]\n                 + ((int128_t)a[ 2]) * b[ 1]\n                 + ((int128_t)a[ 3]) * b[ 0];\n    int128_t t4   = ((int128_t)a[ 0]) * b[ 4]\n                 + ((int128_t)a[ 1]) * b[ 3]\n                 + ((int128_t)a[ 2]) * b[ 2]\n                 + ((int128_t)a[ 3]) * b[ 1]\n                 + ((int128_t)a[ 4]) * b[ 0];\n    int128_t t5   = ((int128_t)a[ 0]) * b[ 5]\n                 + ((int128_t)a[ 1]) * b[ 4]\n                 + ((int128_t)a[ 2]) * b[ 3]\n                 + ((int128_t)a[ 3]) * b[ 2]\n                 + ((int128_t)a[ 4]) * b[ 1]\n                 + ((int128_t)a[ 5]) * b[ 0];\n    int128_t t6   = ((int128_t)a[ 0]) * b[ 6]\n                 + ((int128_t)a[ 1]) * b[ 5]\n                 + ((int128_t)a[ 2]) * b[ 4]\n                 + ((int128_t)a[ 3]) * b[ 3]\n                 + ((int128_t)a[ 4]) * b[ 2]\n                 + ((int128_t)a[ 5]) * b[ 1]\n                 + ((int128_t)a[ 6]) * b[ 0];\n    int128_t t7   = ((int128_t)a[ 0]) * b[ 7]\n                 + ((int128_t)a[ 1]) * b[ 6]\n                 + ((int128_t)a[ 2]) * b[ 5]\n                 + ((int128_t)a[ 3]) * b[ 4]\n                 + ((int128_t)a[ 4]) * b[ 3]\n                 + ((int128_t)a[ 5]) * b[ 2]\n                 + ((int128_t)a[ 6]) * b[ 1]\n                 + ((int128_t)a[ 7]) * b[ 0];\n    int128_t t8   = ((int128_t)a[ 0]) * b[ 8]\n                 + ((int128_t)a[ 1]) * b[ 7]\n                 + ((int128_t)a[ 2]) * b[ 6]\n                 + ((int128_t)a[ 3]) * b[ 5]\n                 + ((int128_t)a[ 4]) * b[ 4]\n                 + ((int128_t)a[ 5]) * b[ 3]\n                 + ((int128_t)a[ 6]) * b[ 2]\n                 + ((int128_t)a[ 7]) * b[ 1]\n                 + ((int128_t)a[ 8]) * b[ 0];\n    int128_t t9   = ((int128_t)a[ 1]) * b[ 8]\n                 + ((int128_t)a[ 2]) * b[ 7]\n                 + ((int128_t)a[ 3]) * b[ 6]\n                 + ((int128_t)a[ 4]) * b[ 5]\n                 + ((int128_t)a[ 5]) * b[ 4]\n                 + ((int128_t)a[ 6]) * b[ 3]\n                 + ((int128_t)a[ 7]) * b[ 2]\n                 + ((int128_t)a[ 8]) * b[ 1];\n    int128_t t10  = ((int128_t)a[ 2]) * b[ 8]\n                 + ((int128_t)a[ 3]) * b[ 7]\n                 + ((int128_t)a[ 4]) * b[ 6]\n                 + ((int128_t)a[ 5]) * b[ 5]\n                 + ((int128_t)a[ 6]) * b[ 4]\n                 + ((int128_t)a[ 7]) * b[ 3]\n                 + ((int128_t)a[ 8]) * b[ 2];\n    int128_t t11  = ((int128_t)a[ 3]) * b[ 8]\n                 + ((int128_t)a[ 4]) * b[ 7]\n                 + ((int128_t)a[ 5]) * b[ 6]\n                 + ((int128_t)a[ 6]) * b[ 5]\n                 + ((int128_t)a[ 7]) * b[ 4]\n                 + ((int128_t)a[ 8]) * b[ 3];\n    int128_t t12  = ((int128_t)a[ 4]) * b[ 8]\n                 + ((int128_t)a[ 5]) * b[ 7]\n                 + ((int128_t)a[ 6]) * b[ 6]\n                 + ((int128_t)a[ 7]) * b[ 5]\n                 + ((int128_t)a[ 8]) * b[ 4];\n    int128_t t13  = ((int128_t)a[ 5]) * b[ 8]\n                 + ((int128_t)a[ 6]) * b[ 7]\n                 + ((int128_t)a[ 7]) * b[ 6]\n                 + ((int128_t)a[ 8]) * b[ 5];\n    int128_t t14  = ((int128_t)a[ 6]) * b[ 8]\n                 + ((int128_t)a[ 7]) * b[ 7]\n                 + ((int128_t)a[ 8]) * b[ 6];\n    int128_t t15  = ((int128_t)a[ 7]) * b[ 8]\n                 + ((int128_t)a[ 8]) * b[ 7];\n    int128_t t16  = ((int128_t)a[ 8]) * b[ 8];\n\n    t1   += t0  >> 57; r[ 0] = t0  & 0x1ffffffffffffffL;\n    t2   += t1  >> 57; r[ 1] = t1  & 0x1ffffffffffffffL;\n    t3   += t2  >> 57; r[ 2] = t2  & 0x1ffffffffffffffL;\n    t4   += t3  >> 57; r[ 3] = t3  & 0x1ffffffffffffffL;\n    t5   += t4  >> 57; r[ 4] = t4  & 0x1ffffffffffffffL;\n    t6   += t5  >> 57; r[ 5] = t5  & 0x1ffffffffffffffL;\n    t7   += t6  >> 57; r[ 6] = t6  & 0x1ffffffffffffffL;\n    t8   += t7  >> 57; r[ 7] = t7  & 0x1ffffffffffffffL;\n    t9   += t8  >> 57; r[ 8] = t8  & 0x1ffffffffffffffL;\n    t10  += t9  >> 57; r[ 9] = t9  & 0x1ffffffffffffffL;\n    t11  += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffL;\n    t12  += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffL;\n    t13  += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffL;\n    t14  += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffL;\n    t15  += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffL;\n    t16  += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffL;\n    r[17] = (sp_digit)(t16 >> 57);\n                       r[16] = t16 & 0x1ffffffffffffffL;\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_9(sp_digit* r, const sp_digit* a)\n{\n    int128_t t0   =  ((int128_t)a[ 0]) * a[ 0];\n    int128_t t1   = (((int128_t)a[ 0]) * a[ 1]) * 2;\n    int128_t t2   = (((int128_t)a[ 0]) * a[ 2]) * 2\n                 +  ((int128_t)a[ 1]) * a[ 1];\n    int128_t t3   = (((int128_t)a[ 0]) * a[ 3]\n                 +  ((int128_t)a[ 1]) * a[ 2]) * 2;\n    int128_t t4   = (((int128_t)a[ 0]) * a[ 4]\n                 +  ((int128_t)a[ 1]) * a[ 3]) * 2\n                 +  ((int128_t)a[ 2]) * a[ 2];\n    int128_t t5   = (((int128_t)a[ 0]) * a[ 5]\n                 +  ((int128_t)a[ 1]) * a[ 4]\n                 +  ((int128_t)a[ 2]) * a[ 3]) * 2;\n    int128_t t6   = (((int128_t)a[ 0]) * a[ 6]\n                 +  ((int128_t)a[ 1]) * a[ 5]\n                 +  ((int128_t)a[ 2]) * a[ 4]) * 2\n                 +  ((int128_t)a[ 3]) * a[ 3];\n    int128_t t7   = (((int128_t)a[ 0]) * a[ 7]\n                 +  ((int128_t)a[ 1]) * a[ 6]\n                 +  ((int128_t)a[ 2]) * a[ 5]\n                 +  ((int128_t)a[ 3]) * a[ 4]) * 2;\n    int128_t t8   = (((int128_t)a[ 0]) * a[ 8]\n                 +  ((int128_t)a[ 1]) * a[ 7]\n                 +  ((int128_t)a[ 2]) * a[ 6]\n                 +  ((int128_t)a[ 3]) * a[ 5]) * 2\n                 +  ((int128_t)a[ 4]) * a[ 4];\n    int128_t t9   = (((int128_t)a[ 1]) * a[ 8]\n                 +  ((int128_t)a[ 2]) * a[ 7]\n                 +  ((int128_t)a[ 3]) * a[ 6]\n                 +  ((int128_t)a[ 4]) * a[ 5]) * 2;\n    int128_t t10  = (((int128_t)a[ 2]) * a[ 8]\n                 +  ((int128_t)a[ 3]) * a[ 7]\n                 +  ((int128_t)a[ 4]) * a[ 6]) * 2\n                 +  ((int128_t)a[ 5]) * a[ 5];\n    int128_t t11  = (((int128_t)a[ 3]) * a[ 8]\n                 +  ((int128_t)a[ 4]) * a[ 7]\n                 +  ((int128_t)a[ 5]) * a[ 6]) * 2;\n    int128_t t12  = (((int128_t)a[ 4]) * a[ 8]\n                 +  ((int128_t)a[ 5]) * a[ 7]) * 2\n                 +  ((int128_t)a[ 6]) * a[ 6];\n    int128_t t13  = (((int128_t)a[ 5]) * a[ 8]\n                 +  ((int128_t)a[ 6]) * a[ 7]) * 2;\n    int128_t t14  = (((int128_t)a[ 6]) * a[ 8]) * 2\n                 +  ((int128_t)a[ 7]) * a[ 7];\n    int128_t t15  = (((int128_t)a[ 7]) * a[ 8]) * 2;\n    int128_t t16  =  ((int128_t)a[ 8]) * a[ 8];\n\n    t1   += t0  >> 57; r[ 0] = t0  & 0x1ffffffffffffffL;\n    t2   += t1  >> 57; r[ 1] = t1  & 0x1ffffffffffffffL;\n    t3   += t2  >> 57; r[ 2] = t2  & 0x1ffffffffffffffL;\n    t4   += t3  >> 57; r[ 3] = t3  & 0x1ffffffffffffffL;\n    t5   += t4  >> 57; r[ 4] = t4  & 0x1ffffffffffffffL;\n    t6   += t5  >> 57; r[ 5] = t5  & 0x1ffffffffffffffL;\n    t7   += t6  >> 57; r[ 6] = t6  & 0x1ffffffffffffffL;\n    t8   += t7  >> 57; r[ 7] = t7  & 0x1ffffffffffffffL;\n    t9   += t8  >> 57; r[ 8] = t8  & 0x1ffffffffffffffL;\n    t10  += t9  >> 57; r[ 9] = t9  & 0x1ffffffffffffffL;\n    t11  += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffL;\n    t12  += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffL;\n    t13  += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffL;\n    t14  += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffL;\n    t15  += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffL;\n    t16  += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffL;\n    r[17] = (sp_digit)(t16 >> 57);\n                       r[16] = t16 & 0x1ffffffffffffffL;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_9(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    r[ 0] = a[ 0] + b[ 0];\n    r[ 1] = a[ 1] + b[ 1];\n    r[ 2] = a[ 2] + b[ 2];\n    r[ 3] = a[ 3] + b[ 3];\n    r[ 4] = a[ 4] + b[ 4];\n    r[ 5] = a[ 5] + b[ 5];\n    r[ 6] = a[ 6] + b[ 6];\n    r[ 7] = a[ 7] + b[ 7];\n    r[ 8] = a[ 8] + b[ 8];\n\n    return 0;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_18(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 16; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[16] = a[16] + b[16];\n    r[17] = a[17] + b[17];\n\n    return 0;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_sub_18(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 16; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[16] = a[16] - b[16];\n    r[17] = a[17] - b[17];\n\n    return 0;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_18(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[18];\n    sp_digit* a1 = z1;\n    sp_digit b1[9];\n    sp_digit* z2 = r + 18;\n    (void)sp_2048_add_9(a1, a, &a[9]);\n    (void)sp_2048_add_9(b1, b, &b[9]);\n    sp_2048_mul_9(z2, &a[9], &b[9]);\n    sp_2048_mul_9(z0, a, b);\n    sp_2048_mul_9(z1, a1, b1);\n    (void)sp_2048_sub_18(z1, z1, z2);\n    (void)sp_2048_sub_18(z1, z1, z0);\n    (void)sp_2048_add_18(r + 9, r + 9, z1);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_18(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[18];\n    sp_digit* a1 = z1;\n    sp_digit* z2 = r + 18;\n    (void)sp_2048_add_9(a1, a, &a[9]);\n    sp_2048_sqr_9(z2, &a[9]);\n    sp_2048_sqr_9(z0, a);\n    sp_2048_sqr_9(z1, a1);\n    (void)sp_2048_sub_18(z1, z1, z2);\n    (void)sp_2048_sub_18(z1, z1, z0);\n    (void)sp_2048_add_18(r + 9, r + 9, z1);\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_36(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[32] = a[32] + b[32];\n    r[33] = a[33] + b[33];\n    r[34] = a[34] + b[34];\n    r[35] = a[35] + b[35];\n\n    return 0;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_sub_36(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[32] = a[32] - b[32];\n    r[33] = a[33] - b[33];\n    r[34] = a[34] - b[34];\n    r[35] = a[35] - b[35];\n\n    return 0;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_36(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[36];\n    sp_digit* a1 = z1;\n    sp_digit b1[18];\n    sp_digit* z2 = r + 36;\n    (void)sp_2048_add_18(a1, a, &a[18]);\n    (void)sp_2048_add_18(b1, b, &b[18]);\n    sp_2048_mul_18(z2, &a[18], &b[18]);\n    sp_2048_mul_18(z0, a, b);\n    sp_2048_mul_18(z1, a1, b1);\n    (void)sp_2048_sub_36(z1, z1, z2);\n    (void)sp_2048_sub_36(z1, z1, z0);\n    (void)sp_2048_add_36(r + 18, r + 18, z1);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_36(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[36];\n    sp_digit* a1 = z1;\n    sp_digit* z2 = r + 36;\n    (void)sp_2048_add_18(a1, a, &a[18]);\n    sp_2048_sqr_18(z2, &a[18]);\n    sp_2048_sqr_18(z0, a);\n    sp_2048_sqr_18(z1, a1);\n    (void)sp_2048_sub_36(z1, z1, z2);\n    (void)sp_2048_sub_36(z1, z1, z0);\n    (void)sp_2048_add_36(r + 18, r + 18, z1);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_36(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 36; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_sub_36(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 36; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_36(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[35]) * b[35];\n    r[71] = (sp_digit)(c >> 57);\n    c = (c & 0x1ffffffffffffffL) << 57;\n    for (k = 69; k >= 0; k--) {\n        for (i = 35; i >= 0; i--) {\n            j = k - i;\n            if (j >= 36) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 114;\n        r[k + 1] = (c >> 57) & 0x1ffffffffffffffL;\n        c = (c & 0x1ffffffffffffffL) << 57;\n    }\n    r[0] = (sp_digit)(c >> 57);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_36(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[35]) * a[35];\n    r[71] = (sp_digit)(c >> 57);\n    c = (c & 0x1ffffffffffffffL) << 57;\n    for (k = 69; k >= 0; k--) {\n        for (i = 35; i >= 0; i--) {\n            j = k - i;\n            if (j >= 36 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int128_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 114;\n        r[k + 1] = (c >> 57) & 0x1ffffffffffffffL;\n        c = (c & 0x1ffffffffffffffL) << 57;\n    }\n    r[0] = (sp_digit)(c >> 57);\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_18(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 18; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_sub_18(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 18; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_18(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[17]) * b[17];\n    r[35] = (sp_digit)(c >> 57);\n    c = (c & 0x1ffffffffffffffL) << 57;\n    for (k = 33; k >= 0; k--) {\n        for (i = 17; i >= 0; i--) {\n            j = k - i;\n            if (j >= 18) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 114;\n        r[k + 1] = (c >> 57) & 0x1ffffffffffffffL;\n        c = (c & 0x1ffffffffffffffL) << 57;\n    }\n    r[0] = (sp_digit)(c >> 57);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_18(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[17]) * a[17];\n    r[35] = (sp_digit)(c >> 57);\n    c = (c & 0x1ffffffffffffffL) << 57;\n    for (k = 33; k >= 0; k--) {\n        for (i = 17; i >= 0; i--) {\n            j = k - i;\n            if (j >= 18 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int128_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 114;\n        r[k + 1] = (c >> 57) & 0x1ffffffffffffffL;\n        c = (c & 0x1ffffffffffffffL) << 57;\n    }\n    r[0] = (sp_digit)(c >> 57);\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**64 */\n    x &= 0x1ffffffffffffffL;\n\n    /* rho = -1/m mod b */\n    *rho = (1L << 57) - x;\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_2048_mul_d_36(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 36; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x1ffffffffffffffL;\n        t >>= 57;\n    }\n    r[36] = (sp_digit)t;\n#else\n    int128_t tb = b;\n    int128_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x1ffffffffffffffL;\n    for (i = 0; i < 32; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffL);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffL);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 57) + (t[3] & 0x1ffffffffffffffL);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 57) + (t[4] & 0x1ffffffffffffffL);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 57) + (t[5] & 0x1ffffffffffffffL);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 57) + (t[6] & 0x1ffffffffffffffL);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 57) + (t[7] & 0x1ffffffffffffffL);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 57) + (t[0] & 0x1ffffffffffffffL);\n    }\n    t[1] = tb * a[33];\n    r[33] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffL);\n    t[2] = tb * a[34];\n    r[34] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffL);\n    t[3] = tb * a[35];\n    r[35] = (sp_digit)(t[2] >> 57) + (t[3] & 0x1ffffffffffffffL);\n    r[36] =  (sp_digit)(t[3] >> 57);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_18(sp_digit* r, const sp_digit* m)\n{\n    /* Set r = 2^n - 1. */\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<17; i++) {\n        r[i] = 0x1ffffffffffffffL;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 16; i += 8) {\n        r[i + 0] = 0x1ffffffffffffffL;\n        r[i + 1] = 0x1ffffffffffffffL;\n        r[i + 2] = 0x1ffffffffffffffL;\n        r[i + 3] = 0x1ffffffffffffffL;\n        r[i + 4] = 0x1ffffffffffffffL;\n        r[i + 5] = 0x1ffffffffffffffL;\n        r[i + 6] = 0x1ffffffffffffffL;\n        r[i + 7] = 0x1ffffffffffffffL;\n    }\n    r[16] = 0x1ffffffffffffffL;\n#endif\n    r[17] = 0x7fffffffffffffL;\n\n    /* r = (2^n - 1) mod n */\n    (void)sp_2048_sub_18(r, r, m);\n\n    /* Add one so r = 2^n mod m */\n    r[0] += 1;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_2048_cmp_18(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=17; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    int i;\n\n    r |= (a[17] - b[17]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[16] - b[16]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    for (i = 8; i >= 0; i -= 8) {\n        r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_2048_cond_sub_18(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 18; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 16; i += 8) {\n        r[i + 0] = a[i + 0] - (b[i + 0] & m);\n        r[i + 1] = a[i + 1] - (b[i + 1] & m);\n        r[i + 2] = a[i + 2] - (b[i + 2] & m);\n        r[i + 3] = a[i + 3] - (b[i + 3] & m);\n        r[i + 4] = a[i + 4] - (b[i + 4] & m);\n        r[i + 5] = a[i + 5] - (b[i + 5] & m);\n        r[i + 6] = a[i + 6] - (b[i + 6] & m);\n        r[i + 7] = a[i + 7] - (b[i + 7] & m);\n    }\n    r[16] = a[16] - (b[16] & m);\n    r[17] = a[17] - (b[17] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_2048_mul_add_18(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 18; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0x1ffffffffffffffL;\n        t >>= 57;\n    }\n    r[18] += t;\n#else\n    int128_t tb = b;\n    int128_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);\n    for (i = 0; i < 16; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));\n        t[2] = tb * a[i+2];\n        r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));\n        t[3] = tb * a[i+3];\n        r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));\n        t[4] = tb * a[i+4];\n        r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));\n        t[5] = tb * a[i+5];\n        r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));\n        t[6] = tb * a[i+6];\n        r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));\n        t[7] = tb * a[i+7];\n        r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));\n        t[0] = tb * a[i+8];\n        r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));\n    }\n    t[1] = tb * a[17]; r[17] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));\n    r[18] +=  (sp_digit)(t[1] >> 57);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Normalize the values in each word to 57.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_2048_norm_18(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 17; i++) {\n        a[i+1] += a[i] >> 57;\n        a[i] &= 0x1ffffffffffffffL;\n    }\n#else\n    int i;\n    for (i = 0; i < 16; i += 8) {\n        a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;\n        a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;\n        a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;\n        a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;\n        a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;\n        a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;\n        a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;\n        a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;\n        a[i+9] += a[i+8] >> 57; a[i+8] &= 0x1ffffffffffffffL;\n    }\n    a[16+1] += a[16] >> 57;\n    a[16] &= 0x1ffffffffffffffL;\n#endif\n}\n\n/* Shift the result in the high 1024 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_2048_mont_shift_18(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    word64 n;\n\n    n = a[17] >> 55;\n    for (i = 0; i < 17; i++) {\n        n += (word64)a[18 + i] << 2;\n        r[i] = n & 0x1ffffffffffffffL;\n        n >>= 57;\n    }\n    n += (word64)a[35] << 2;\n    r[17] = n;\n#else\n    word64 n;\n    int i;\n\n    n  = (word64)a[17];\n    n  = n >> 55U;\n    for (i = 0; i < 16; i += 8) {\n        n += (word64)a[i+18] << 2U; r[i+0] = n & 0x1ffffffffffffffUL; n >>= 57U;\n        n += (word64)a[i+19] << 2U; r[i+1] = n & 0x1ffffffffffffffUL; n >>= 57U;\n        n += (word64)a[i+20] << 2U; r[i+2] = n & 0x1ffffffffffffffUL; n >>= 57U;\n        n += (word64)a[i+21] << 2U; r[i+3] = n & 0x1ffffffffffffffUL; n >>= 57U;\n        n += (word64)a[i+22] << 2U; r[i+4] = n & 0x1ffffffffffffffUL; n >>= 57U;\n        n += (word64)a[i+23] << 2U; r[i+5] = n & 0x1ffffffffffffffUL; n >>= 57U;\n        n += (word64)a[i+24] << 2U; r[i+6] = n & 0x1ffffffffffffffUL; n >>= 57U;\n        n += (word64)a[i+25] << 2U; r[i+7] = n & 0x1ffffffffffffffUL; n >>= 57U;\n    }\n    n += (word64)a[34] << 2U; r[16] = n & 0x1ffffffffffffffUL; n >>= 57U;\n    n += (word64)a[35] << 2U; r[17] = n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[18], 0, sizeof(*r) * 18U);\n}\n\n/* Reduce the number back to 2048 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_2048_mont_reduce_18(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    sp_2048_norm_18(a + 18);\n\n    for (i=0; i<17; i++) {\n        mu = (a[i] * mp) & 0x1ffffffffffffffL;\n        sp_2048_mul_add_18(a+i, m, mu);\n        a[i+1] += a[i] >> 57;\n    }\n    mu = (a[i] * mp) & 0x7fffffffffffffL;\n    sp_2048_mul_add_18(a+i, m, mu);\n    a[i+1] += a[i] >> 57;\n    a[i] &= 0x1ffffffffffffffL;\n\n    sp_2048_mont_shift_18(a, a);\n    sp_2048_cond_sub_18(a, a, m, 0 - (((a[17] >> 55) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_2048_norm_18(a);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_18(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_18(r, a, b);\n    sp_2048_mont_reduce_18(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_18(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_18(r, a);\n    sp_2048_mont_reduce_18(r, m, mp);\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_2048_mul_d_18(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 18; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x1ffffffffffffffL;\n        t >>= 57;\n    }\n    r[18] = (sp_digit)t;\n#else\n    int128_t tb = b;\n    int128_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x1ffffffffffffffL;\n    for (i = 0; i < 16; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffL);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffL);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 57) + (t[3] & 0x1ffffffffffffffL);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 57) + (t[4] & 0x1ffffffffffffffL);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 57) + (t[5] & 0x1ffffffffffffffL);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 57) + (t[6] & 0x1ffffffffffffffL);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 57) + (t[7] & 0x1ffffffffffffffL);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 57) + (t[0] & 0x1ffffffffffffffL);\n    }\n    t[1] = tb * a[17];\n    r[17] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffL);\n    r[18] =  (sp_digit)(t[1] >> 57);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_2048_cond_add_18(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 18; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 16; i += 8) {\n        r[i + 0] = a[i + 0] + (b[i + 0] & m);\n        r[i + 1] = a[i + 1] + (b[i + 1] & m);\n        r[i + 2] = a[i + 2] + (b[i + 2] & m);\n        r[i + 3] = a[i + 3] + (b[i + 3] & m);\n        r[i + 4] = a[i + 4] + (b[i + 4] & m);\n        r[i + 5] = a[i + 5] + (b[i + 5] & m);\n        r[i + 6] = a[i + 6] + (b[i + 6] & m);\n        r[i + 7] = a[i + 7] + (b[i + 7] & m);\n    }\n    r[16] = a[16] + (b[16] & m);\n    r[17] = a[17] + (b[17] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_sub_18(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 18; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif\n#ifdef WOLFSSL_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_18(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 18; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif\n#ifdef WOLFSSL_SP_DIV_64\nstatic WC_INLINE sp_digit sp_2048_div_word_18(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t, dv;\n    int128_t t0, t1;\n\n    /* dv has 29 bits. */\n    dv = (div >> 28) + 1;\n    /* All 57 bits from d1 and top 6 bits from d0. */\n    d = (d1 << 6) | (d0 >> 51);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 34 bits in r */\n    /* Next 23 bits from d0. */\n    d <<= 23;\n    r <<= 23;\n    d |= (d0 >> 28) & ((1 << 23) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 57 bits in r */\n\n    /* Handle rounding error with dv - top part */\n    t0 = ((int128_t)d1 << 57) + d0;\n    t1 = (int128_t)r * dv;\n    t1 = t0 - t1;\n    t = (sp_digit)(t1 >> 28) / dv;\n    r += t;\n\n    /* Handle rounding error with dv - bottom 64 bits */\n    t1 = (sp_digit)t0 - (r * dv);\n    t = (sp_digit)t1 / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_64 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Number to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_2048_div_18(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_64\n    int128_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[36], t2d[18 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (3 * 18 + 1), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 2 * 18;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        dv = d[17];\n        XMEMCPY(t1, a, sizeof(*t1) * 2U * 18U);\n        for (i=17; i>=0; i--) {\n            t1[18 + i] += t1[18 + i - 1] >> 57;\n            t1[18 + i - 1] &= 0x1ffffffffffffffL;\n#ifndef WOLFSSL_SP_DIV_64\n            d1 = t1[18 + i];\n            d1 <<= 57;\n            d1 += t1[18 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_2048_div_word_18(t1[18 + i], t1[18 + i - 1], dv);\n#endif\n\n            sp_2048_mul_d_18(t2, d, r1);\n            (void)sp_2048_sub_18(&t1[i], &t1[i], t2);\n            t1[18 + i] -= t2[18];\n            t1[18 + i] += t1[18 + i - 1] >> 57;\n            t1[18 + i - 1] &= 0x1ffffffffffffffL;\n            r1 = (((-t1[18 + i]) << 57) - t1[18 + i - 1]) / dv;\n            r1++;\n            sp_2048_mul_d_18(t2, d, r1);\n            (void)sp_2048_add_18(&t1[i], &t1[i], t2);\n            t1[18 + i] += t1[18 + i - 1] >> 57;\n            t1[18 + i - 1] &= 0x1ffffffffffffffL;\n        }\n        t1[18 - 1] += t1[18 - 2] >> 57;\n        t1[18 - 2] &= 0x1ffffffffffffffL;\n        d1 = t1[18 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_2048_mul_d_18(t2, d, r1);\n        (void)sp_2048_sub_18(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 18U);\n        for (i=0; i<16; i++) {\n            r[i+1] += r[i] >> 57;\n            r[i] &= 0x1ffffffffffffffL;\n        }\n        sp_2048_cond_add_18(r, r, d, 0 - ((r[17] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_2048_mod_18(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_18(a, m, NULL, r);\n}\n\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, const sp_digit* e, int bits,\n    const sp_digit* m, int reduceA)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* td;\n    sp_digit* t[3];\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 18 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3U * 18U * 2U);\n\n        norm = t[0] = td;\n        t[1] = &td[18 * 2];\n        t[2] = &td[2 * 18 * 2];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_18(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_2048_mod_18(t[1], a, m);\n        }\n        else {\n            XMEMCPY(t[1], a, sizeof(sp_digit) * 18U);\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_2048_mul_18(t[1], t[1], norm);\n        err = sp_2048_mod_18(t[1], t[1], m);\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 57;\n        c = bits % 57;\n        n = e[i--] << (57 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 57;\n            }\n\n            y = (n >> 56) & 1;\n            n <<= 1;\n\n            sp_2048_mont_mul_18(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(*t[2]) * 18 * 2);\n            sp_2048_mont_sqr_18(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(*t[2]) * 18 * 2);\n        }\n\n        sp_2048_mont_reduce_18(t[0], m, mp);\n        n = sp_2048_cmp_18(t[0], m);\n        sp_2048_cond_sub_18(t[0], t[0], m, ((n < 0) ?\n                    (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(*r) * 18 * 2);\n\n    }\n\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    return err;\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[3][36];\n#else\n    sp_digit* td;\n    sp_digit* t[3];\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 18 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        t[0] = td;\n        t[1] = &td[18 * 2];\n        t[2] = &td[2 * 18 * 2];\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_18(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_2048_mod_18(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_2048_mul_18(t[1], t[1], norm);\n                err = sp_2048_mod_18(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_2048_mul_18(t[1], a, norm);\n            err = sp_2048_mod_18(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 57;\n        c = bits % 57;\n        n = e[i--] << (57 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 57;\n            }\n\n            y = (n >> 56) & 1;\n            n <<= 1;\n\n            sp_2048_mont_mul_18(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_2048_mont_sqr_18(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                           ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));\n        }\n\n        sp_2048_mont_reduce_18(t[0], m, mp);\n        n = sp_2048_cmp_18(t[0], m);\n        sp_2048_cond_sub_18(t[0], t[0], m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(t[0]));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][36];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit rt[36];\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 36, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 36;\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_18(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_2048_mod_18(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_2048_mul_18(t[1], t[1], norm);\n                err = sp_2048_mod_18(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_2048_mul_18(t[1], a, norm);\n            err = sp_2048_mod_18(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_18(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_18(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_18(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_18(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_18(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_18(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_18(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_18(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_18(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_18(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_18(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_18(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_18(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_18(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_18(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_18(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_18(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_18(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_18(t[20], t[10], m, mp);\n        sp_2048_mont_mul_18(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_18(t[22], t[11], m, mp);\n        sp_2048_mont_mul_18(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_18(t[24], t[12], m, mp);\n        sp_2048_mont_mul_18(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_18(t[26], t[13], m, mp);\n        sp_2048_mont_mul_18(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_18(t[28], t[14], m, mp);\n        sp_2048_mont_mul_18(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_18(t[30], t[15], m, mp);\n        sp_2048_mont_mul_18(t[31], t[16], t[15], m, mp);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 56) / 57) - 1;\n        c = bits % 57;\n        if (c == 0) {\n            c = 57;\n        }\n        if (i < 18) {\n            n = e[i--] << (64 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (7 - c);\n            c += 57;\n        }\n        y = (n >> 59) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        XMEMCPY(rt, t[y], sizeof(rt));\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (7 - c);\n                c += 57;\n            }\n            y = (n >> 59) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_2048_mont_sqr_18(rt, rt, m, mp);\n            sp_2048_mont_sqr_18(rt, rt, m, mp);\n            sp_2048_mont_sqr_18(rt, rt, m, mp);\n            sp_2048_mont_sqr_18(rt, rt, m, mp);\n            sp_2048_mont_sqr_18(rt, rt, m, mp);\n\n            sp_2048_mont_mul_18(rt, rt, t[y], m, mp);\n        }\n\n        sp_2048_mont_reduce_18(rt, m, mp);\n        n = sp_2048_cmp_18(rt, m);\n        sp_2048_cond_sub_18(rt, rt, m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, rt, sizeof(rt));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#endif\n}\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_36(sp_digit* r, const sp_digit* m)\n{\n    /* Set r = 2^n - 1. */\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<35; i++) {\n        r[i] = 0x1ffffffffffffffL;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i + 0] = 0x1ffffffffffffffL;\n        r[i + 1] = 0x1ffffffffffffffL;\n        r[i + 2] = 0x1ffffffffffffffL;\n        r[i + 3] = 0x1ffffffffffffffL;\n        r[i + 4] = 0x1ffffffffffffffL;\n        r[i + 5] = 0x1ffffffffffffffL;\n        r[i + 6] = 0x1ffffffffffffffL;\n        r[i + 7] = 0x1ffffffffffffffL;\n    }\n    r[32] = 0x1ffffffffffffffL;\n    r[33] = 0x1ffffffffffffffL;\n    r[34] = 0x1ffffffffffffffL;\n#endif\n    r[35] = 0x1fffffffffffffL;\n\n    /* r = (2^n - 1) mod n */\n    (void)sp_2048_sub_36(r, r, m);\n\n    /* Add one so r = 2^n mod m */\n    r[0] += 1;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_2048_cmp_36(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=35; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    int i;\n\n    r |= (a[35] - b[35]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[34] - b[34]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[33] - b[33]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[32] - b[32]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    for (i = 24; i >= 0; i -= 8) {\n        r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_2048_cond_sub_36(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 36; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i + 0] = a[i + 0] - (b[i + 0] & m);\n        r[i + 1] = a[i + 1] - (b[i + 1] & m);\n        r[i + 2] = a[i + 2] - (b[i + 2] & m);\n        r[i + 3] = a[i + 3] - (b[i + 3] & m);\n        r[i + 4] = a[i + 4] - (b[i + 4] & m);\n        r[i + 5] = a[i + 5] - (b[i + 5] & m);\n        r[i + 6] = a[i + 6] - (b[i + 6] & m);\n        r[i + 7] = a[i + 7] - (b[i + 7] & m);\n    }\n    r[32] = a[32] - (b[32] & m);\n    r[33] = a[33] - (b[33] & m);\n    r[34] = a[34] - (b[34] & m);\n    r[35] = a[35] - (b[35] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_2048_mul_add_36(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 36; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0x1ffffffffffffffL;\n        t >>= 57;\n    }\n    r[36] += t;\n#else\n    int128_t tb = b;\n    int128_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);\n    for (i = 0; i < 32; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));\n        t[2] = tb * a[i+2];\n        r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));\n        t[3] = tb * a[i+3];\n        r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));\n        t[4] = tb * a[i+4];\n        r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));\n        t[5] = tb * a[i+5];\n        r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));\n        t[6] = tb * a[i+6];\n        r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));\n        t[7] = tb * a[i+7];\n        r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));\n        t[0] = tb * a[i+8];\n        r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));\n    }\n    t[1] = tb * a[33]; r[33] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));\n    t[2] = tb * a[34]; r[34] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));\n    t[3] = tb * a[35]; r[35] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));\n    r[36] +=  (sp_digit)(t[3] >> 57);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Normalize the values in each word to 57.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_2048_norm_36(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 35; i++) {\n        a[i+1] += a[i] >> 57;\n        a[i] &= 0x1ffffffffffffffL;\n    }\n#else\n    int i;\n    for (i = 0; i < 32; i += 8) {\n        a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;\n        a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;\n        a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;\n        a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;\n        a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;\n        a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;\n        a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;\n        a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;\n        a[i+9] += a[i+8] >> 57; a[i+8] &= 0x1ffffffffffffffL;\n    }\n    a[32+1] += a[32] >> 57;\n    a[32] &= 0x1ffffffffffffffL;\n    a[33+1] += a[33] >> 57;\n    a[33] &= 0x1ffffffffffffffL;\n    a[34+1] += a[34] >> 57;\n    a[34] &= 0x1ffffffffffffffL;\n#endif\n}\n\n/* Shift the result in the high 2048 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_2048_mont_shift_36(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    sp_digit n, s;\n\n    s = a[36];\n    n = a[35] >> 53;\n    for (i = 0; i < 35; i++) {\n        n += (s & 0x1ffffffffffffffL) << 4;\n        r[i] = n & 0x1ffffffffffffffL;\n        n >>= 57;\n        s = a[37 + i] + (s >> 57);\n    }\n    n += s << 4;\n    r[35] = n;\n#else\n    sp_digit n, s;\n    int i;\n\n    s = a[36]; n = a[35] >> 53;\n    for (i = 0; i < 32; i += 8) {\n        n += (s & 0x1ffffffffffffffL) << 4; r[i+0] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+37] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 4; r[i+1] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+38] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 4; r[i+2] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+39] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 4; r[i+3] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+40] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 4; r[i+4] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+41] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 4; r[i+5] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+42] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 4; r[i+6] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+43] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 4; r[i+7] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+44] + (s >> 57);\n    }\n    n += (s & 0x1ffffffffffffffL) << 4; r[32] = n & 0x1ffffffffffffffL;\n    n >>= 57; s = a[69] + (s >> 57);\n    n += (s & 0x1ffffffffffffffL) << 4; r[33] = n & 0x1ffffffffffffffL;\n    n >>= 57; s = a[70] + (s >> 57);\n    n += (s & 0x1ffffffffffffffL) << 4; r[34] = n & 0x1ffffffffffffffL;\n    n >>= 57; s = a[71] + (s >> 57);\n    n += s << 4;              r[35] = n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[36], 0, sizeof(*r) * 36U);\n}\n\n/* Reduce the number back to 2048 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_2048_mont_reduce_36(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    sp_2048_norm_36(a + 36);\n\n#ifdef WOLFSSL_SP_DH\n    if (mp != 1) {\n        for (i=0; i<35; i++) {\n            mu = (a[i] * mp) & 0x1ffffffffffffffL;\n            sp_2048_mul_add_36(a+i, m, mu);\n            a[i+1] += a[i] >> 57;\n        }\n        mu = (a[i] * mp) & 0x1fffffffffffffL;\n        sp_2048_mul_add_36(a+i, m, mu);\n        a[i+1] += a[i] >> 57;\n        a[i] &= 0x1ffffffffffffffL;\n    }\n    else {\n        for (i=0; i<35; i++) {\n            mu = a[i] & 0x1ffffffffffffffL;\n            sp_2048_mul_add_36(a+i, m, mu);\n            a[i+1] += a[i] >> 57;\n        }\n        mu = a[i] & 0x1fffffffffffffL;\n        sp_2048_mul_add_36(a+i, m, mu);\n        a[i+1] += a[i] >> 57;\n        a[i] &= 0x1ffffffffffffffL;\n    }\n#else\n    for (i=0; i<35; i++) {\n        mu = (a[i] * mp) & 0x1ffffffffffffffL;\n        sp_2048_mul_add_36(a+i, m, mu);\n        a[i+1] += a[i] >> 57;\n    }\n    mu = (a[i] * mp) & 0x1fffffffffffffL;\n    sp_2048_mul_add_36(a+i, m, mu);\n    a[i+1] += a[i] >> 57;\n    a[i] &= 0x1ffffffffffffffL;\n#endif\n\n    sp_2048_mont_shift_36(a, a);\n    sp_2048_cond_sub_36(a, a, m, 0 - (((a[35] >> 53) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_2048_norm_36(a);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_36(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_36(r, a, b);\n    sp_2048_mont_reduce_36(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_36(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_36(r, a);\n    sp_2048_mont_reduce_36(r, m, mp);\n}\n\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_2048_cond_add_36(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 36; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i + 0] = a[i + 0] + (b[i + 0] & m);\n        r[i + 1] = a[i + 1] + (b[i + 1] & m);\n        r[i + 2] = a[i + 2] + (b[i + 2] & m);\n        r[i + 3] = a[i + 3] + (b[i + 3] & m);\n        r[i + 4] = a[i + 4] + (b[i + 4] & m);\n        r[i + 5] = a[i + 5] + (b[i + 5] & m);\n        r[i + 6] = a[i + 6] + (b[i + 6] & m);\n        r[i + 7] = a[i + 7] + (b[i + 7] & m);\n    }\n    r[32] = a[32] + (b[32] & m);\n    r[33] = a[33] + (b[33] & m);\n    r[34] = a[34] + (b[34] & m);\n    r[35] = a[35] + (b[35] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_sub_36(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 36; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif\n#ifdef WOLFSSL_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_2048_add_36(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 36; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif\n#ifdef WOLFSSL_SP_DIV_64\nstatic WC_INLINE sp_digit sp_2048_div_word_36(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t, dv;\n    int128_t t0, t1;\n\n    /* dv has 29 bits. */\n    dv = (div >> 28) + 1;\n    /* All 57 bits from d1 and top 6 bits from d0. */\n    d = (d1 << 6) | (d0 >> 51);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 34 bits in r */\n    /* Next 23 bits from d0. */\n    d <<= 23;\n    r <<= 23;\n    d |= (d0 >> 28) & ((1 << 23) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 57 bits in r */\n\n    /* Handle rounding error with dv - top part */\n    t0 = ((int128_t)d1 << 57) + d0;\n    t1 = (int128_t)r * dv;\n    t1 = t0 - t1;\n    t = (sp_digit)(t1 >> 28) / dv;\n    r += t;\n\n    /* Handle rounding error with dv - bottom 64 bits */\n    t1 = (sp_digit)t0 - (r * dv);\n    t = (sp_digit)t1 / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_64 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Number to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_2048_div_36(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_64\n    int128_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[72], t2d[36 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (3 * 36 + 1), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 2 * 36;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        dv = d[35];\n        XMEMCPY(t1, a, sizeof(*t1) * 2U * 36U);\n        for (i=35; i>=0; i--) {\n            t1[36 + i] += t1[36 + i - 1] >> 57;\n            t1[36 + i - 1] &= 0x1ffffffffffffffL;\n#ifndef WOLFSSL_SP_DIV_64\n            d1 = t1[36 + i];\n            d1 <<= 57;\n            d1 += t1[36 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_2048_div_word_36(t1[36 + i], t1[36 + i - 1], dv);\n#endif\n\n            sp_2048_mul_d_36(t2, d, r1);\n            (void)sp_2048_sub_36(&t1[i], &t1[i], t2);\n            t1[36 + i] -= t2[36];\n            t1[36 + i] += t1[36 + i - 1] >> 57;\n            t1[36 + i - 1] &= 0x1ffffffffffffffL;\n            r1 = (((-t1[36 + i]) << 57) - t1[36 + i - 1]) / dv;\n            r1++;\n            sp_2048_mul_d_36(t2, d, r1);\n            (void)sp_2048_add_36(&t1[i], &t1[i], t2);\n            t1[36 + i] += t1[36 + i - 1] >> 57;\n            t1[36 + i - 1] &= 0x1ffffffffffffffL;\n        }\n        t1[36 - 1] += t1[36 - 2] >> 57;\n        t1[36 - 2] &= 0x1ffffffffffffffL;\n        d1 = t1[36 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_2048_mul_d_36(t2, d, r1);\n        (void)sp_2048_sub_36(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 36U);\n        for (i=0; i<34; i++) {\n            r[i+1] += r[i] >> 57;\n            r[i] &= 0x1ffffffffffffffL;\n        }\n        sp_2048_cond_add_36(r, r, d, 0 - ((r[35] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_2048_mod_36(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_36(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, const sp_digit* e, int bits,\n    const sp_digit* m, int reduceA)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* td;\n    sp_digit* t[3];\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 36 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3U * 36U * 2U);\n\n        norm = t[0] = td;\n        t[1] = &td[36 * 2];\n        t[2] = &td[2 * 36 * 2];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_36(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_2048_mod_36(t[1], a, m);\n        }\n        else {\n            XMEMCPY(t[1], a, sizeof(sp_digit) * 36U);\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_2048_mul_36(t[1], t[1], norm);\n        err = sp_2048_mod_36(t[1], t[1], m);\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 57;\n        c = bits % 57;\n        n = e[i--] << (57 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 57;\n            }\n\n            y = (n >> 56) & 1;\n            n <<= 1;\n\n            sp_2048_mont_mul_36(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(*t[2]) * 36 * 2);\n            sp_2048_mont_sqr_36(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(*t[2]) * 36 * 2);\n        }\n\n        sp_2048_mont_reduce_36(t[0], m, mp);\n        n = sp_2048_cmp_36(t[0], m);\n        sp_2048_cond_sub_36(t[0], t[0], m, ((n < 0) ?\n                    (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(*r) * 36 * 2);\n\n    }\n\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    return err;\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[3][72];\n#else\n    sp_digit* td;\n    sp_digit* t[3];\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 36 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        t[0] = td;\n        t[1] = &td[36 * 2];\n        t[2] = &td[2 * 36 * 2];\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_36(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_2048_mod_36(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_2048_mul_36(t[1], t[1], norm);\n                err = sp_2048_mod_36(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_2048_mul_36(t[1], a, norm);\n            err = sp_2048_mod_36(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 57;\n        c = bits % 57;\n        n = e[i--] << (57 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 57;\n            }\n\n            y = (n >> 56) & 1;\n            n <<= 1;\n\n            sp_2048_mont_mul_36(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_2048_mont_sqr_36(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                           ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));\n        }\n\n        sp_2048_mont_reduce_36(t[0], m, mp);\n        n = sp_2048_cmp_36(t[0], m);\n        sp_2048_cond_sub_36(t[0], t[0], m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(t[0]));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][72];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit rt[72];\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 72, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 72;\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_36(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_2048_mod_36(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_2048_mul_36(t[1], t[1], norm);\n                err = sp_2048_mod_36(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_2048_mul_36(t[1], a, norm);\n            err = sp_2048_mod_36(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_36(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_36(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_36(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_36(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_36(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_36(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_36(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_36(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_36(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_36(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_36(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_36(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_36(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_36(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_36(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_36(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_36(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_36(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_36(t[20], t[10], m, mp);\n        sp_2048_mont_mul_36(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_36(t[22], t[11], m, mp);\n        sp_2048_mont_mul_36(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_36(t[24], t[12], m, mp);\n        sp_2048_mont_mul_36(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_36(t[26], t[13], m, mp);\n        sp_2048_mont_mul_36(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_36(t[28], t[14], m, mp);\n        sp_2048_mont_mul_36(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_36(t[30], t[15], m, mp);\n        sp_2048_mont_mul_36(t[31], t[16], t[15], m, mp);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 56) / 57) - 1;\n        c = bits % 57;\n        if (c == 0) {\n            c = 57;\n        }\n        if (i < 36) {\n            n = e[i--] << (64 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (7 - c);\n            c += 57;\n        }\n        y = (n >> 59) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        XMEMCPY(rt, t[y], sizeof(rt));\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (7 - c);\n                c += 57;\n            }\n            y = (n >> 59) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_2048_mont_sqr_36(rt, rt, m, mp);\n            sp_2048_mont_sqr_36(rt, rt, m, mp);\n            sp_2048_mont_sqr_36(rt, rt, m, mp);\n            sp_2048_mont_sqr_36(rt, rt, m, mp);\n            sp_2048_mont_sqr_36(rt, rt, m, mp);\n\n            sp_2048_mont_mul_36(rt, rt, t[y], m, mp);\n        }\n\n        sp_2048_mont_reduce_36(rt, m, mp);\n        n = sp_2048_cmp_36(rt, m);\n        sp_2048_cond_sub_36(rt, rt, m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, rt, sizeof(rt));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#endif\n}\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */\n       /* WOLFSSL_HAVE_SP_DH */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \\\n           !defined(RSA_LOW_MEM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_18(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<18; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 16; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n    r[16] = a[16] & m;\n    r[17] = a[17] & m;\n#endif\n}\n\n#endif\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* d = NULL;\n    sp_digit* a;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit* norm;\n    sp_digit e[1] = {0};\n    sp_digit mp;\n    int i;\n    int err = MP_OKAY;\n\n    if (*outLen < 256U) {\n        err = MP_TO_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(em) > 57) {\n            err = MP_READ_E;\n        }\n        if (inLen > 256U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 36 * 2;\n        m = r + 36 * 2;\n        norm = r;\n\n        sp_2048_from_bin(a, 36, in, inLen);\n#if DIGIT_BIT >= 57\n        e[0] = (sp_digit)em->dp[0];\n#else\n        e[0] = (sp_digit)em->dp[0];\n        if (em->used > 1) {\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n        }\n#endif\n        if (e[0] == 0) {\n            err = MP_EXPTMOD_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(m, 36, mm);\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_36(norm, m);\n    }\n    if (err == MP_OKAY) {\n        sp_2048_mul_36(a, a, norm);\n        err = sp_2048_mod_36(a, a, m);\n    }\n    if (err == MP_OKAY) {\n        for (i=56; i>=0; i--) {\n            if ((e[0] >> i) != 0) {\n                break;\n            }\n        }\n\n        XMEMCPY(r, a, sizeof(sp_digit) * 36 * 2);\n        for (i--; i>=0; i--) {\n            sp_2048_mont_sqr_36(r, r, m, mp);\n\n            if (((e[0] >> i) & 1) == 1) {\n                sp_2048_mont_mul_36(r, r, a, m, mp);\n            }\n        }\n        sp_2048_mont_reduce_36(r, m, mp);\n        mp = sp_2048_cmp_36(r, m);\n        sp_2048_cond_sub_36(r, r, m, ((mp < 0) ?\n                    (sp_digit)1 : (sp_digit)0)- 1);\n\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[72], md[36], rd[72];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1] = {0};\n    int err = MP_OKAY;\n\n    if (*outLen < 256U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(em) > 57) {\n            err = MP_READ_E;\n        }\n        if (inLen > 256U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 36 * 2;\n        m = r + 36 * 2;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(a, 36, in, inLen);\n#if DIGIT_BIT >= 57\n        e[0] = (sp_digit)em->dp[0];\n#else\n        e[0] = (sp_digit)em->dp[0];\n        if (em->used > 1) {\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n        }\n#endif\n        if (e[0] == 0) {\n            err = MP_EXPTMOD_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(m, 36, mm);\n\n        if (e[0] == 0x3) {\n            sp_2048_sqr_36(r, a);\n            err = sp_2048_mod_36(r, r, m);\n            if (err == MP_OKAY) {\n                sp_2048_mul_36(r, a, r);\n                err = sp_2048_mod_36(r, r, m);\n            }\n        }\n        else {\n            sp_digit* norm = r;\n            int i;\n            sp_digit mp;\n\n            sp_2048_mont_setup(m, &mp);\n            sp_2048_mont_norm_36(norm, m);\n\n            sp_2048_mul_36(a, a, norm);\n            err = sp_2048_mod_36(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=56; i>=0; i--) {\n                    if ((e[0] >> i) != 0) {\n                        break;\n                    }\n                }\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 72U);\n                for (i--; i>=0; i--) {\n                    sp_2048_mont_sqr_36(r, r, m, mp);\n\n                    if (((e[0] >> i) & 1) == 1) {\n                        sp_2048_mont_mul_36(r, r, a, m, mp);\n                    }\n                }\n                sp_2048_mont_reduce_36(r, m, mp);\n                mp = sp_2048_cmp_36(r, m);\n                sp_2048_cond_sub_36(r, r, m, ((mp < 0) ?\n                           (sp_digit)1 : (sp_digit)0) - 1);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n#endif\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* a;\n    sp_digit* d = NULL;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n\n    (void)pm;\n    (void)qm;\n    (void)dpm;\n    (void)dqm;\n    (void)qim;\n\n    if (*outLen < 256U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(dm) > 2048) {\n           err = MP_READ_E;\n        }\n        if (inLen > 256) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 36 * 4, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        a = d + 36;\n        m = a + 36;\n        r = a;\n\n        sp_2048_from_bin(a, 36, in, inLen);\n        sp_2048_from_mp(d, 36, dm);\n        sp_2048_from_mp(m, 36, mm);\n        err = sp_2048_mod_exp_36(r, a, d, 2048, m, 0);\n    }\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n    if (d != NULL) {\n        XMEMSET(d, 0, sizeof(sp_digit) * 36);\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n    sp_digit a[72], d[36], m[36];\n    sp_digit* r = a;\n    int err = MP_OKAY;\n\n    (void)pm;\n    (void)qm;\n    (void)dpm;\n    (void)dqm;\n    (void)qim;\n\n    if (*outLen < 256U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(dm) > 2048) {\n            err = MP_READ_E;\n        }\n        if (inLen > 256U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(a, 36, in, inLen);\n        sp_2048_from_mp(d, 36, dm);\n        sp_2048_from_mp(m, 36, mm);\n        err = sp_2048_mod_exp_36(r, a, d, 2048, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n    XMEMSET(d, 0, sizeof(sp_digit) * 36);\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */\n#else\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* t = NULL;\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 256U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (inLen > 256) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 18 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL) {\n            err = MEMORY_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 36 * 2;\n        q = p + 18;\n        qi = dq = dp = q + 18;\n        tmpa = qi + 18;\n        tmpb = tmpa + 36;\n\n        tmp = t;\n        r = tmp + 36;\n\n        sp_2048_from_bin(a, 36, in, inLen);\n        sp_2048_from_mp(p, 18, pm);\n        sp_2048_from_mp(q, 18, qm);\n        sp_2048_from_mp(dp, 18, dpm);\n        err = sp_2048_mod_exp_18(tmpa, a, dp, 1024, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(dq, 18, dqm);\n        err = sp_2048_mod_exp_18(tmpb, a, dq, 1024, q, 1);\n    }\n    if (err == MP_OKAY) {\n        (void)sp_2048_sub_18(tmpa, tmpa, tmpb);\n        sp_2048_mask_18(tmp, p, 0 - ((sp_int_digit)tmpa[17] >> 63));\n        (void)sp_2048_add_18(tmpa, tmpa, tmp);\n\n        sp_2048_from_mp(qi, 18, qim);\n        sp_2048_mul_18(tmpa, tmpa, qi);\n        err = sp_2048_mod_18(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mul_18(tmpa, q, tmpa);\n        (void)sp_2048_add_36(r, tmpb, tmpa);\n        sp_2048_norm_36(r);\n\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 18 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n    sp_digit a[36 * 2];\n    sp_digit p[18], q[18], dp[18], dq[18], qi[18];\n    sp_digit tmp[36], tmpa[36], tmpb[36];\n    sp_digit* r = a;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 256U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (inLen > 256U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(a, 36, in, inLen);\n        sp_2048_from_mp(p, 18, pm);\n        sp_2048_from_mp(q, 18, qm);\n        sp_2048_from_mp(dp, 18, dpm);\n        sp_2048_from_mp(dq, 18, dqm);\n        sp_2048_from_mp(qi, 18, qim);\n\n        err = sp_2048_mod_exp_18(tmpa, a, dp, 1024, p, 1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_2048_mod_exp_18(tmpb, a, dq, 1024, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        (void)sp_2048_sub_18(tmpa, tmpa, tmpb);\n        sp_2048_mask_18(tmp, p, 0 - ((sp_int_digit)tmpa[17] >> 63));\n        (void)sp_2048_add_18(tmpa, tmpa, tmp);\n        sp_2048_mul_18(tmpa, tmpa, qi);\n        err = sp_2048_mod_18(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mul_18(tmpa, tmpa, q);\n        (void)sp_2048_add_36(r, tmpb, tmpa);\n        sp_2048_norm_36(r);\n\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n    XMEMSET(tmpa, 0, sizeof(tmpa));\n    XMEMSET(tmpb, 0, sizeof(tmpb));\n    XMEMSET(p, 0, sizeof(p));\n    XMEMSET(q, 0, sizeof(q));\n    XMEMSET(dp, 0, sizeof(dp));\n    XMEMSET(dq, 0, sizeof(dq));\n    XMEMSET(qi, 0, sizeof(qi));\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */\n#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */\n}\n\n#endif /* !WOLFSSL_RSA_PUBLIC_ONLY */\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_2048_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 57\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 36);\n        r->used = 36;\n        mp_clamp(r);\n#elif DIGIT_BIT < 57\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 36; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 57) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 57 - s;\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 36; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 57 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 57 - s;\n            }\n            else {\n                s += 57;\n            }\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 36 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 36 * 2;\n        m = e + 36;\n        r = b;\n\n        sp_2048_from_mp(b, 36, base);\n        sp_2048_from_mp(e, 36, exp);\n        sp_2048_from_mp(m, 36, mod);\n\n        err = sp_2048_mod_exp_36(r, b, e, mp_count_bits(exp), m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_2048_to_mp(r, res);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 36U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[72], ed[36], md[36];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 2048) {\n            err = MP_READ_E;\n        }\n    }\n    \n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 36 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 36 * 2;\n        m = e + 36;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 36, base);\n        sp_2048_from_mp(e, 36, exp);\n        sp_2048_from_mp(m, 36, mod);\n\n        err = sp_2048_mod_exp_36(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_2048_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 36U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_2048\nSP_NOINLINE static void sp_2048_lshift_36(sp_digit* r, sp_digit* a, byte n)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    r[36] = a[35] >> (57 - n);\n    for (i=35; i>0; i--) {\n        r[i] = ((a[i] << n) | (a[i-1] >> (57 - n))) & 0x1ffffffffffffffL;\n    }\n#else\n    sp_int_digit s, t;\n\n    s = (sp_int_digit)a[35];\n    r[36] = s >> (57U - n);\n    s = (sp_int_digit)(a[35]); t = (sp_int_digit)(a[34]);\n    r[35] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[34]); t = (sp_int_digit)(a[33]);\n    r[34] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[33]); t = (sp_int_digit)(a[32]);\n    r[33] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[32]); t = (sp_int_digit)(a[31]);\n    r[32] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[31]); t = (sp_int_digit)(a[30]);\n    r[31] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[30]); t = (sp_int_digit)(a[29]);\n    r[30] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[29]); t = (sp_int_digit)(a[28]);\n    r[29] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[28]); t = (sp_int_digit)(a[27]);\n    r[28] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[27]); t = (sp_int_digit)(a[26]);\n    r[27] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[26]); t = (sp_int_digit)(a[25]);\n    r[26] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[25]); t = (sp_int_digit)(a[24]);\n    r[25] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[24]); t = (sp_int_digit)(a[23]);\n    r[24] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[23]); t = (sp_int_digit)(a[22]);\n    r[23] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[22]); t = (sp_int_digit)(a[21]);\n    r[22] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[21]); t = (sp_int_digit)(a[20]);\n    r[21] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[20]); t = (sp_int_digit)(a[19]);\n    r[20] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[19]); t = (sp_int_digit)(a[18]);\n    r[19] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[18]); t = (sp_int_digit)(a[17]);\n    r[18] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[17]); t = (sp_int_digit)(a[16]);\n    r[17] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[16]); t = (sp_int_digit)(a[15]);\n    r[16] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[15]); t = (sp_int_digit)(a[14]);\n    r[15] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[14]); t = (sp_int_digit)(a[13]);\n    r[14] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);\n    r[13] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);\n    r[12] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);\n    r[11] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);\n    r[10] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);\n    r[9] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);\n    r[8] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);\n    r[7] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);\n    r[6] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);\n    r[5] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);\n    r[4] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);\n    r[3] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);\n    r[2] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);\n    r[1] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n#endif\n    r[0] = (a[0] << n) & 0x1ffffffffffffffL;\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_2_36(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[72];\n    sp_digit td[37];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 109, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 72;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        XMEMSET(td, 0, sizeof(td));\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_36(norm, m);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 56) / 57) - 1;\n        c = bits % 57;\n        if (c == 0) {\n            c = 57;\n        }\n        if (i < 36) {\n            n = e[i--] << (64 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (7 - c);\n            c += 57;\n        }\n        y = (n >> 59) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        sp_2048_lshift_36(r, norm, y);\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (7 - c);\n                c += 57;\n            }\n            y = (n >> 59) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_2048_mont_sqr_36(r, r, m, mp);\n            sp_2048_mont_sqr_36(r, r, m, mp);\n            sp_2048_mont_sqr_36(r, r, m, mp);\n            sp_2048_mont_sqr_36(r, r, m, mp);\n            sp_2048_mont_sqr_36(r, r, m, mp);\n\n            sp_2048_lshift_36(r, r, y);\n            sp_2048_mul_d_36(tmp, norm, (r[36] << 4) + (r[35] >> 53));\n            r[36] = 0;\n            r[35] &= 0x1fffffffffffffL;\n            (void)sp_2048_add_36(r, r, tmp);\n            sp_2048_norm_36(r);\n            o = sp_2048_cmp_36(r, m);\n            sp_2048_cond_sub_36(r, r, m, ((o < 0) ?\n                                          (sp_digit)1 : (sp_digit)0) - 1);\n        }\n\n        sp_2048_mont_reduce_36(r, m, mp);\n        n = sp_2048_cmp_36(r, m);\n        sp_2048_cond_sub_36(r, r, m, ((n < 0) ?\n                                                (sp_digit)1 : (sp_digit)0) - 1);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n#endif /* HAVE_FFDHE_2048 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 256 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    word32 i;\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 256) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 36 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 36 * 2;\n        m = e + 36;\n        r = b;\n\n        sp_2048_from_mp(b, 36, base);\n        sp_2048_from_bin(e, 36, exp, expLen);\n        sp_2048_from_mp(m, 36, mod);\n\n    #ifdef HAVE_FFDHE_2048\n        if (base->used == 1 && base->dp[0] == 2 &&\n                (m[35] >> 21) == 0xffffffffL) {\n            err = sp_2048_mod_exp_2_36(r, e, expLen * 8, m);\n        }\n        else\n    #endif\n            err = sp_2048_mod_exp_36(r, b, e, expLen * 8, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n        for (i=0; i<256 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 36U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[72], ed[36], md[36];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    word32 i;\n    int err = MP_OKAY;\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 256U) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 36 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 36 * 2;\n        m = e + 36;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 36, base);\n        sp_2048_from_bin(e, 36, exp, expLen);\n        sp_2048_from_mp(m, 36, mod);\n\n    #ifdef HAVE_FFDHE_2048\n        if (base->used == 1 && base->dp[0] == 2U &&\n                (m[35] >> 21) == 0xffffffffL) {\n            err = sp_2048_mod_exp_2_36(r, e, expLen * 8U, m);\n        }\n        else {\n    #endif\n            err = sp_2048_mod_exp_36(r, b, e, expLen * 8U, m, 0);\n    #ifdef HAVE_FFDHE_2048\n        }\n    #endif\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n        for (i=0; i<256U && out[i] == 0U; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 36U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1024) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 18 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 18 * 2;\n        m = e + 18;\n        r = b;\n\n        sp_2048_from_mp(b, 18, base);\n        sp_2048_from_mp(e, 18, exp);\n        sp_2048_from_mp(m, 18, mod);\n\n        err = sp_2048_mod_exp_18(r, b, e, mp_count_bits(exp), m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 18, 0, sizeof(*r) * 18U);\n        err = sp_2048_to_mp(r, res);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 18U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[36], ed[18], md[18];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1024) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1024) {\n            err = MP_READ_E;\n        }\n    }\n    \n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 18 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 18 * 2;\n        m = e + 18;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 18, base);\n        sp_2048_from_mp(e, 18, exp);\n        sp_2048_from_mp(m, 18, mod);\n\n        err = sp_2048_mod_exp_18(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 18, 0, sizeof(*r) * 18U);\n        err = sp_2048_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 18U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_2048 */\n\n#ifndef WOLFSSL_SP_NO_3072\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 49U) {\n            r[j] &= 0x1ffffffffffffffL;\n            s = 57U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 57\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 57\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0x1ffffffffffffffL;\n        s = 57U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 57U) <= (word32)DIGIT_BIT) {\n            s += 57U;\n            r[j] &= 0x1ffffffffffffffL;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 57) {\n            r[j] &= 0x1ffffffffffffffL;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 57 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 384\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_3072_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    for (i=0; i<53; i++) {\n        r[i+1] += r[i] >> 57;\n        r[i] &= 0x1ffffffffffffffL;\n    }\n    j = 3072 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<54 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 57) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 57);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_9(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int128_t t0   = ((int128_t)a[ 0]) * b[ 0];\n    int128_t t1   = ((int128_t)a[ 0]) * b[ 1]\n                 + ((int128_t)a[ 1]) * b[ 0];\n    int128_t t2   = ((int128_t)a[ 0]) * b[ 2]\n                 + ((int128_t)a[ 1]) * b[ 1]\n                 + ((int128_t)a[ 2]) * b[ 0];\n    int128_t t3   = ((int128_t)a[ 0]) * b[ 3]\n                 + ((int128_t)a[ 1]) * b[ 2]\n                 + ((int128_t)a[ 2]) * b[ 1]\n                 + ((int128_t)a[ 3]) * b[ 0];\n    int128_t t4   = ((int128_t)a[ 0]) * b[ 4]\n                 + ((int128_t)a[ 1]) * b[ 3]\n                 + ((int128_t)a[ 2]) * b[ 2]\n                 + ((int128_t)a[ 3]) * b[ 1]\n                 + ((int128_t)a[ 4]) * b[ 0];\n    int128_t t5   = ((int128_t)a[ 0]) * b[ 5]\n                 + ((int128_t)a[ 1]) * b[ 4]\n                 + ((int128_t)a[ 2]) * b[ 3]\n                 + ((int128_t)a[ 3]) * b[ 2]\n                 + ((int128_t)a[ 4]) * b[ 1]\n                 + ((int128_t)a[ 5]) * b[ 0];\n    int128_t t6   = ((int128_t)a[ 0]) * b[ 6]\n                 + ((int128_t)a[ 1]) * b[ 5]\n                 + ((int128_t)a[ 2]) * b[ 4]\n                 + ((int128_t)a[ 3]) * b[ 3]\n                 + ((int128_t)a[ 4]) * b[ 2]\n                 + ((int128_t)a[ 5]) * b[ 1]\n                 + ((int128_t)a[ 6]) * b[ 0];\n    int128_t t7   = ((int128_t)a[ 0]) * b[ 7]\n                 + ((int128_t)a[ 1]) * b[ 6]\n                 + ((int128_t)a[ 2]) * b[ 5]\n                 + ((int128_t)a[ 3]) * b[ 4]\n                 + ((int128_t)a[ 4]) * b[ 3]\n                 + ((int128_t)a[ 5]) * b[ 2]\n                 + ((int128_t)a[ 6]) * b[ 1]\n                 + ((int128_t)a[ 7]) * b[ 0];\n    int128_t t8   = ((int128_t)a[ 0]) * b[ 8]\n                 + ((int128_t)a[ 1]) * b[ 7]\n                 + ((int128_t)a[ 2]) * b[ 6]\n                 + ((int128_t)a[ 3]) * b[ 5]\n                 + ((int128_t)a[ 4]) * b[ 4]\n                 + ((int128_t)a[ 5]) * b[ 3]\n                 + ((int128_t)a[ 6]) * b[ 2]\n                 + ((int128_t)a[ 7]) * b[ 1]\n                 + ((int128_t)a[ 8]) * b[ 0];\n    int128_t t9   = ((int128_t)a[ 1]) * b[ 8]\n                 + ((int128_t)a[ 2]) * b[ 7]\n                 + ((int128_t)a[ 3]) * b[ 6]\n                 + ((int128_t)a[ 4]) * b[ 5]\n                 + ((int128_t)a[ 5]) * b[ 4]\n                 + ((int128_t)a[ 6]) * b[ 3]\n                 + ((int128_t)a[ 7]) * b[ 2]\n                 + ((int128_t)a[ 8]) * b[ 1];\n    int128_t t10  = ((int128_t)a[ 2]) * b[ 8]\n                 + ((int128_t)a[ 3]) * b[ 7]\n                 + ((int128_t)a[ 4]) * b[ 6]\n                 + ((int128_t)a[ 5]) * b[ 5]\n                 + ((int128_t)a[ 6]) * b[ 4]\n                 + ((int128_t)a[ 7]) * b[ 3]\n                 + ((int128_t)a[ 8]) * b[ 2];\n    int128_t t11  = ((int128_t)a[ 3]) * b[ 8]\n                 + ((int128_t)a[ 4]) * b[ 7]\n                 + ((int128_t)a[ 5]) * b[ 6]\n                 + ((int128_t)a[ 6]) * b[ 5]\n                 + ((int128_t)a[ 7]) * b[ 4]\n                 + ((int128_t)a[ 8]) * b[ 3];\n    int128_t t12  = ((int128_t)a[ 4]) * b[ 8]\n                 + ((int128_t)a[ 5]) * b[ 7]\n                 + ((int128_t)a[ 6]) * b[ 6]\n                 + ((int128_t)a[ 7]) * b[ 5]\n                 + ((int128_t)a[ 8]) * b[ 4];\n    int128_t t13  = ((int128_t)a[ 5]) * b[ 8]\n                 + ((int128_t)a[ 6]) * b[ 7]\n                 + ((int128_t)a[ 7]) * b[ 6]\n                 + ((int128_t)a[ 8]) * b[ 5];\n    int128_t t14  = ((int128_t)a[ 6]) * b[ 8]\n                 + ((int128_t)a[ 7]) * b[ 7]\n                 + ((int128_t)a[ 8]) * b[ 6];\n    int128_t t15  = ((int128_t)a[ 7]) * b[ 8]\n                 + ((int128_t)a[ 8]) * b[ 7];\n    int128_t t16  = ((int128_t)a[ 8]) * b[ 8];\n\n    t1   += t0  >> 57; r[ 0] = t0  & 0x1ffffffffffffffL;\n    t2   += t1  >> 57; r[ 1] = t1  & 0x1ffffffffffffffL;\n    t3   += t2  >> 57; r[ 2] = t2  & 0x1ffffffffffffffL;\n    t4   += t3  >> 57; r[ 3] = t3  & 0x1ffffffffffffffL;\n    t5   += t4  >> 57; r[ 4] = t4  & 0x1ffffffffffffffL;\n    t6   += t5  >> 57; r[ 5] = t5  & 0x1ffffffffffffffL;\n    t7   += t6  >> 57; r[ 6] = t6  & 0x1ffffffffffffffL;\n    t8   += t7  >> 57; r[ 7] = t7  & 0x1ffffffffffffffL;\n    t9   += t8  >> 57; r[ 8] = t8  & 0x1ffffffffffffffL;\n    t10  += t9  >> 57; r[ 9] = t9  & 0x1ffffffffffffffL;\n    t11  += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffL;\n    t12  += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffL;\n    t13  += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffL;\n    t14  += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffL;\n    t15  += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffL;\n    t16  += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffL;\n    r[17] = (sp_digit)(t16 >> 57);\n                       r[16] = t16 & 0x1ffffffffffffffL;\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_9(sp_digit* r, const sp_digit* a)\n{\n    int128_t t0   =  ((int128_t)a[ 0]) * a[ 0];\n    int128_t t1   = (((int128_t)a[ 0]) * a[ 1]) * 2;\n    int128_t t2   = (((int128_t)a[ 0]) * a[ 2]) * 2\n                 +  ((int128_t)a[ 1]) * a[ 1];\n    int128_t t3   = (((int128_t)a[ 0]) * a[ 3]\n                 +  ((int128_t)a[ 1]) * a[ 2]) * 2;\n    int128_t t4   = (((int128_t)a[ 0]) * a[ 4]\n                 +  ((int128_t)a[ 1]) * a[ 3]) * 2\n                 +  ((int128_t)a[ 2]) * a[ 2];\n    int128_t t5   = (((int128_t)a[ 0]) * a[ 5]\n                 +  ((int128_t)a[ 1]) * a[ 4]\n                 +  ((int128_t)a[ 2]) * a[ 3]) * 2;\n    int128_t t6   = (((int128_t)a[ 0]) * a[ 6]\n                 +  ((int128_t)a[ 1]) * a[ 5]\n                 +  ((int128_t)a[ 2]) * a[ 4]) * 2\n                 +  ((int128_t)a[ 3]) * a[ 3];\n    int128_t t7   = (((int128_t)a[ 0]) * a[ 7]\n                 +  ((int128_t)a[ 1]) * a[ 6]\n                 +  ((int128_t)a[ 2]) * a[ 5]\n                 +  ((int128_t)a[ 3]) * a[ 4]) * 2;\n    int128_t t8   = (((int128_t)a[ 0]) * a[ 8]\n                 +  ((int128_t)a[ 1]) * a[ 7]\n                 +  ((int128_t)a[ 2]) * a[ 6]\n                 +  ((int128_t)a[ 3]) * a[ 5]) * 2\n                 +  ((int128_t)a[ 4]) * a[ 4];\n    int128_t t9   = (((int128_t)a[ 1]) * a[ 8]\n                 +  ((int128_t)a[ 2]) * a[ 7]\n                 +  ((int128_t)a[ 3]) * a[ 6]\n                 +  ((int128_t)a[ 4]) * a[ 5]) * 2;\n    int128_t t10  = (((int128_t)a[ 2]) * a[ 8]\n                 +  ((int128_t)a[ 3]) * a[ 7]\n                 +  ((int128_t)a[ 4]) * a[ 6]) * 2\n                 +  ((int128_t)a[ 5]) * a[ 5];\n    int128_t t11  = (((int128_t)a[ 3]) * a[ 8]\n                 +  ((int128_t)a[ 4]) * a[ 7]\n                 +  ((int128_t)a[ 5]) * a[ 6]) * 2;\n    int128_t t12  = (((int128_t)a[ 4]) * a[ 8]\n                 +  ((int128_t)a[ 5]) * a[ 7]) * 2\n                 +  ((int128_t)a[ 6]) * a[ 6];\n    int128_t t13  = (((int128_t)a[ 5]) * a[ 8]\n                 +  ((int128_t)a[ 6]) * a[ 7]) * 2;\n    int128_t t14  = (((int128_t)a[ 6]) * a[ 8]) * 2\n                 +  ((int128_t)a[ 7]) * a[ 7];\n    int128_t t15  = (((int128_t)a[ 7]) * a[ 8]) * 2;\n    int128_t t16  =  ((int128_t)a[ 8]) * a[ 8];\n\n    t1   += t0  >> 57; r[ 0] = t0  & 0x1ffffffffffffffL;\n    t2   += t1  >> 57; r[ 1] = t1  & 0x1ffffffffffffffL;\n    t3   += t2  >> 57; r[ 2] = t2  & 0x1ffffffffffffffL;\n    t4   += t3  >> 57; r[ 3] = t3  & 0x1ffffffffffffffL;\n    t5   += t4  >> 57; r[ 4] = t4  & 0x1ffffffffffffffL;\n    t6   += t5  >> 57; r[ 5] = t5  & 0x1ffffffffffffffL;\n    t7   += t6  >> 57; r[ 6] = t6  & 0x1ffffffffffffffL;\n    t8   += t7  >> 57; r[ 7] = t7  & 0x1ffffffffffffffL;\n    t9   += t8  >> 57; r[ 8] = t8  & 0x1ffffffffffffffL;\n    t10  += t9  >> 57; r[ 9] = t9  & 0x1ffffffffffffffL;\n    t11  += t10 >> 57; r[10] = t10 & 0x1ffffffffffffffL;\n    t12  += t11 >> 57; r[11] = t11 & 0x1ffffffffffffffL;\n    t13  += t12 >> 57; r[12] = t12 & 0x1ffffffffffffffL;\n    t14  += t13 >> 57; r[13] = t13 & 0x1ffffffffffffffL;\n    t15  += t14 >> 57; r[14] = t14 & 0x1ffffffffffffffL;\n    t16  += t15 >> 57; r[15] = t15 & 0x1ffffffffffffffL;\n    r[17] = (sp_digit)(t16 >> 57);\n                       r[16] = t16 & 0x1ffffffffffffffL;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_add_9(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    r[ 0] = a[ 0] + b[ 0];\n    r[ 1] = a[ 1] + b[ 1];\n    r[ 2] = a[ 2] + b[ 2];\n    r[ 3] = a[ 3] + b[ 3];\n    r[ 4] = a[ 4] + b[ 4];\n    r[ 5] = a[ 5] + b[ 5];\n    r[ 6] = a[ 6] + b[ 6];\n    r[ 7] = a[ 7] + b[ 7];\n    r[ 8] = a[ 8] + b[ 8];\n\n    return 0;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_add_18(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 16; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[16] = a[16] + b[16];\n    r[17] = a[17] + b[17];\n\n    return 0;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_sub_18(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 16; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[16] = a[16] - b[16];\n    r[17] = a[17] - b[17];\n\n    return 0;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_18(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[18];\n    sp_digit* a1 = z1;\n    sp_digit b1[9];\n    sp_digit* z2 = r + 18;\n    (void)sp_3072_add_9(a1, a, &a[9]);\n    (void)sp_3072_add_9(b1, b, &b[9]);\n    sp_3072_mul_9(z2, &a[9], &b[9]);\n    sp_3072_mul_9(z0, a, b);\n    sp_3072_mul_9(z1, a1, b1);\n    (void)sp_3072_sub_18(z1, z1, z2);\n    (void)sp_3072_sub_18(z1, z1, z0);\n    (void)sp_3072_add_18(r + 9, r + 9, z1);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_18(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[18];\n    sp_digit* a1 = z1;\n    sp_digit* z2 = r + 18;\n    (void)sp_3072_add_9(a1, a, &a[9]);\n    sp_3072_sqr_9(z2, &a[9]);\n    sp_3072_sqr_9(z0, a);\n    sp_3072_sqr_9(z1, a1);\n    (void)sp_3072_sub_18(z1, z1, z2);\n    (void)sp_3072_sub_18(z1, z1, z0);\n    (void)sp_3072_add_18(r + 9, r + 9, z1);\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_sub_36(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[32] = a[32] - b[32];\n    r[33] = a[33] - b[33];\n    r[34] = a[34] - b[34];\n    r[35] = a[35] - b[35];\n\n    return 0;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_add_36(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[32] = a[32] + b[32];\n    r[33] = a[33] + b[33];\n    r[34] = a[34] + b[34];\n    r[35] = a[35] + b[35];\n\n    return 0;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_54(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    sp_digit p0[36];\n    sp_digit p1[36];\n    sp_digit p2[36];\n    sp_digit p3[36];\n    sp_digit p4[36];\n    sp_digit p5[36];\n    sp_digit t0[36];\n    sp_digit t1[36];\n    sp_digit t2[36];\n    sp_digit a0[18];\n    sp_digit a1[18];\n    sp_digit a2[18];\n    sp_digit b0[18];\n    sp_digit b1[18];\n    sp_digit b2[18];\n    (void)sp_3072_add_18(a0, a, &a[18]);\n    (void)sp_3072_add_18(b0, b, &b[18]);\n    (void)sp_3072_add_18(a1, &a[18], &a[36]);\n    (void)sp_3072_add_18(b1, &b[18], &b[36]);\n    (void)sp_3072_add_18(a2, a0, &a[36]);\n    (void)sp_3072_add_18(b2, b0, &b[36]);\n    sp_3072_mul_18(p0, a, b);\n    sp_3072_mul_18(p2, &a[18], &b[18]);\n    sp_3072_mul_18(p4, &a[36], &b[36]);\n    sp_3072_mul_18(p1, a0, b0);\n    sp_3072_mul_18(p3, a1, b1);\n    sp_3072_mul_18(p5, a2, b2);\n    XMEMSET(r, 0, sizeof(*r)*2U*54U);\n    (void)sp_3072_sub_36(t0, p3, p2);\n    (void)sp_3072_sub_36(t1, p1, p2);\n    (void)sp_3072_sub_36(t2, p5, t0);\n    (void)sp_3072_sub_36(t2, t2, t1);\n    (void)sp_3072_sub_36(t0, t0, p4);\n    (void)sp_3072_sub_36(t1, t1, p0);\n    (void)sp_3072_add_36(r, r, p0);\n    (void)sp_3072_add_36(&r[18], &r[18], t1);\n    (void)sp_3072_add_36(&r[36], &r[36], t2);\n    (void)sp_3072_add_36(&r[54], &r[54], t0);\n    (void)sp_3072_add_36(&r[72], &r[72], p4);\n}\n\n/* Square a into r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_54(sp_digit* r, const sp_digit* a)\n{\n    sp_digit p0[36];\n    sp_digit p1[36];\n    sp_digit p2[36];\n    sp_digit p3[36];\n    sp_digit p4[36];\n    sp_digit p5[36];\n    sp_digit t0[36];\n    sp_digit t1[36];\n    sp_digit t2[36];\n    sp_digit a0[18];\n    sp_digit a1[18];\n    sp_digit a2[18];\n    (void)sp_3072_add_18(a0, a, &a[18]);\n    (void)sp_3072_add_18(a1, &a[18], &a[36]);\n    (void)sp_3072_add_18(a2, a0, &a[36]);\n    sp_3072_sqr_18(p0, a);\n    sp_3072_sqr_18(p2, &a[18]);\n    sp_3072_sqr_18(p4, &a[36]);\n    sp_3072_sqr_18(p1, a0);\n    sp_3072_sqr_18(p3, a1);\n    sp_3072_sqr_18(p5, a2);\n    XMEMSET(r, 0, sizeof(*r)*2U*54U);\n    (void)sp_3072_sub_36(t0, p3, p2);\n    (void)sp_3072_sub_36(t1, p1, p2);\n    (void)sp_3072_sub_36(t2, p5, t0);\n    (void)sp_3072_sub_36(t2, t2, t1);\n    (void)sp_3072_sub_36(t0, t0, p4);\n    (void)sp_3072_sub_36(t1, t1, p0);\n    (void)sp_3072_add_36(r, r, p0);\n    (void)sp_3072_add_36(&r[18], &r[18], t1);\n    (void)sp_3072_add_36(&r[36], &r[36], t2);\n    (void)sp_3072_add_36(&r[54], &r[54], t0);\n    (void)sp_3072_add_36(&r[72], &r[72], p4);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_add_54(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 54; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#else\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_add_54(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 48; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[48] = a[48] + b[48];\n    r[49] = a[49] + b[49];\n    r[50] = a[50] + b[50];\n    r[51] = a[51] + b[51];\n    r[52] = a[52] + b[52];\n    r[53] = a[53] + b[53];\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_sub_54(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 54; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#else\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_sub_54(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 48; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[48] = a[48] - b[48];\n    r[49] = a[49] - b[49];\n    r[50] = a[50] - b[50];\n    r[51] = a[51] - b[51];\n    r[52] = a[52] - b[52];\n    r[53] = a[53] - b[53];\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_54(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[53]) * b[53];\n    r[107] = (sp_digit)(c >> 57);\n    c = (c & 0x1ffffffffffffffL) << 57;\n    for (k = 105; k >= 0; k--) {\n        for (i = 53; i >= 0; i--) {\n            j = k - i;\n            if (j >= 54) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 114;\n        r[k + 1] = (c >> 57) & 0x1ffffffffffffffL;\n        c = (c & 0x1ffffffffffffffL) << 57;\n    }\n    r[0] = (sp_digit)(c >> 57);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_54(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[53]) * a[53];\n    r[107] = (sp_digit)(c >> 57);\n    c = (c & 0x1ffffffffffffffL) << 57;\n    for (k = 105; k >= 0; k--) {\n        for (i = 53; i >= 0; i--) {\n            j = k - i;\n            if (j >= 54 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int128_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 114;\n        r[k + 1] = (c >> 57) & 0x1ffffffffffffffL;\n        c = (c & 0x1ffffffffffffffL) << 57;\n    }\n    r[0] = (sp_digit)(c >> 57);\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_add_27(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 27; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#else\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_add_27(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[24] = a[24] + b[24];\n    r[25] = a[25] + b[25];\n    r[26] = a[26] + b[26];\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_sub_27(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 27; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#else\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_3072_sub_27(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[24] = a[24] - b[24];\n    r[25] = a[25] - b[25];\n    r[26] = a[26] - b[26];\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_27(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[26]) * b[26];\n    r[53] = (sp_digit)(c >> 57);\n    c = (c & 0x1ffffffffffffffL) << 57;\n    for (k = 51; k >= 0; k--) {\n        for (i = 26; i >= 0; i--) {\n            j = k - i;\n            if (j >= 27) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 114;\n        r[k + 1] = (c >> 57) & 0x1ffffffffffffffL;\n        c = (c & 0x1ffffffffffffffL) << 57;\n    }\n    r[0] = (sp_digit)(c >> 57);\n}\n\n#else\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_27(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j;\n    int128_t t[54];\n\n    XMEMSET(t, 0, sizeof(t));\n    for (i=0; i<27; i++) {\n        for (j=0; j<27; j++) {\n            t[i+j] += ((int128_t)a[i]) * b[j];\n        }\n    }\n    for (i=0; i<53; i++) {\n        r[i] = t[i] & 0x1ffffffffffffffL;\n        t[i+1] += t[i] >> 57;\n    }\n    r[53] = (sp_digit)t[53];\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_27(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[26]) * a[26];\n    r[53] = (sp_digit)(c >> 57);\n    c = (c & 0x1ffffffffffffffL) << 57;\n    for (k = 51; k >= 0; k--) {\n        for (i = 26; i >= 0; i--) {\n            j = k - i;\n            if (j >= 27 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int128_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 114;\n        r[k + 1] = (c >> 57) & 0x1ffffffffffffffL;\n        c = (c & 0x1ffffffffffffffL) << 57;\n    }\n    r[0] = (sp_digit)(c >> 57);\n}\n\n#else\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_27(sp_digit* r, const sp_digit* a)\n{\n    int i, j;\n    int128_t t[54];\n\n    XMEMSET(t, 0, sizeof(t));\n    for (i=0; i<27; i++) {\n        for (j=0; j<i; j++) {\n            t[i+j] += (((int128_t)a[i]) * a[j]) * 2;\n        }\n        t[i+i] += ((int128_t)a[i]) * a[i];\n    }\n    for (i=0; i<53; i++) {\n        r[i] = t[i] & 0x1ffffffffffffffL;\n        t[i+1] += t[i] >> 57;\n    }\n    r[53] = (sp_digit)t[53];\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**64 */\n    x &= 0x1ffffffffffffffL;\n\n    /* rho = -1/m mod b */\n    *rho = (1L << 57) - x;\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_3072_mul_d_54(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 54; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x1ffffffffffffffL;\n        t >>= 57;\n    }\n    r[54] = (sp_digit)t;\n#else\n    int128_t tb = b;\n    int128_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x1ffffffffffffffL;\n    for (i = 0; i < 48; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffL);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffL);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 57) + (t[3] & 0x1ffffffffffffffL);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 57) + (t[4] & 0x1ffffffffffffffL);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 57) + (t[5] & 0x1ffffffffffffffL);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 57) + (t[6] & 0x1ffffffffffffffL);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 57) + (t[7] & 0x1ffffffffffffffL);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 57) + (t[0] & 0x1ffffffffffffffL);\n    }\n    t[1] = tb * a[49];\n    r[49] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffL);\n    t[2] = tb * a[50];\n    r[50] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffL);\n    t[3] = tb * a[51];\n    r[51] = (sp_digit)(t[2] >> 57) + (t[3] & 0x1ffffffffffffffL);\n    t[4] = tb * a[52];\n    r[52] = (sp_digit)(t[3] >> 57) + (t[4] & 0x1ffffffffffffffL);\n    t[5] = tb * a[53];\n    r[53] = (sp_digit)(t[4] >> 57) + (t[5] & 0x1ffffffffffffffL);\n    r[54] =  (sp_digit)(t[5] >> 57);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_27(sp_digit* r, const sp_digit* m)\n{\n    /* Set r = 2^n - 1. */\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<26; i++) {\n        r[i] = 0x1ffffffffffffffL;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i + 0] = 0x1ffffffffffffffL;\n        r[i + 1] = 0x1ffffffffffffffL;\n        r[i + 2] = 0x1ffffffffffffffL;\n        r[i + 3] = 0x1ffffffffffffffL;\n        r[i + 4] = 0x1ffffffffffffffL;\n        r[i + 5] = 0x1ffffffffffffffL;\n        r[i + 6] = 0x1ffffffffffffffL;\n        r[i + 7] = 0x1ffffffffffffffL;\n    }\n    r[24] = 0x1ffffffffffffffL;\n    r[25] = 0x1ffffffffffffffL;\n#endif\n    r[26] = 0x3fffffffffffffL;\n\n    /* r = (2^n - 1) mod n */\n    (void)sp_3072_sub_27(r, r, m);\n\n    /* Add one so r = 2^n mod m */\n    r[0] += 1;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_3072_cmp_27(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=26; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    int i;\n\n    r |= (a[26] - b[26]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[25] - b[25]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[24] - b[24]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    for (i = 16; i >= 0; i -= 8) {\n        r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_3072_cond_sub_27(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 27; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i + 0] = a[i + 0] - (b[i + 0] & m);\n        r[i + 1] = a[i + 1] - (b[i + 1] & m);\n        r[i + 2] = a[i + 2] - (b[i + 2] & m);\n        r[i + 3] = a[i + 3] - (b[i + 3] & m);\n        r[i + 4] = a[i + 4] - (b[i + 4] & m);\n        r[i + 5] = a[i + 5] - (b[i + 5] & m);\n        r[i + 6] = a[i + 6] - (b[i + 6] & m);\n        r[i + 7] = a[i + 7] - (b[i + 7] & m);\n    }\n    r[24] = a[24] - (b[24] & m);\n    r[25] = a[25] - (b[25] & m);\n    r[26] = a[26] - (b[26] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_3072_mul_add_27(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 27; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0x1ffffffffffffffL;\n        t >>= 57;\n    }\n    r[27] += t;\n#else\n    int128_t tb = b;\n    int128_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);\n    for (i = 0; i < 24; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));\n        t[2] = tb * a[i+2];\n        r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));\n        t[3] = tb * a[i+3];\n        r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));\n        t[4] = tb * a[i+4];\n        r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));\n        t[5] = tb * a[i+5];\n        r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));\n        t[6] = tb * a[i+6];\n        r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));\n        t[7] = tb * a[i+7];\n        r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));\n        t[0] = tb * a[i+8];\n        r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));\n    }\n    t[1] = tb * a[25]; r[25] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));\n    t[2] = tb * a[26]; r[26] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));\n    r[27] +=  (sp_digit)(t[2] >> 57);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Normalize the values in each word to 57.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_3072_norm_27(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 26; i++) {\n        a[i+1] += a[i] >> 57;\n        a[i] &= 0x1ffffffffffffffL;\n    }\n#else\n    int i;\n    for (i = 0; i < 24; i += 8) {\n        a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;\n        a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;\n        a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;\n        a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;\n        a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;\n        a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;\n        a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;\n        a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;\n        a[i+9] += a[i+8] >> 57; a[i+8] &= 0x1ffffffffffffffL;\n    }\n    a[24+1] += a[24] >> 57;\n    a[24] &= 0x1ffffffffffffffL;\n    a[25+1] += a[25] >> 57;\n    a[25] &= 0x1ffffffffffffffL;\n#endif\n}\n\n/* Shift the result in the high 1536 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_3072_mont_shift_27(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    sp_digit n, s;\n\n    s = a[27];\n    n = a[26] >> 54;\n    for (i = 0; i < 26; i++) {\n        n += (s & 0x1ffffffffffffffL) << 3;\n        r[i] = n & 0x1ffffffffffffffL;\n        n >>= 57;\n        s = a[28 + i] + (s >> 57);\n    }\n    n += s << 3;\n    r[26] = n;\n#else\n    sp_digit n, s;\n    int i;\n\n    s = a[27]; n = a[26] >> 54;\n    for (i = 0; i < 24; i += 8) {\n        n += (s & 0x1ffffffffffffffL) << 3; r[i+0] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+28] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 3; r[i+1] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+29] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 3; r[i+2] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+30] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 3; r[i+3] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+31] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 3; r[i+4] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+32] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 3; r[i+5] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+33] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 3; r[i+6] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+34] + (s >> 57);\n        n += (s & 0x1ffffffffffffffL) << 3; r[i+7] = n & 0x1ffffffffffffffL;\n        n >>= 57; s = a[i+35] + (s >> 57);\n    }\n    n += (s & 0x1ffffffffffffffL) << 3; r[24] = n & 0x1ffffffffffffffL;\n    n >>= 57; s = a[52] + (s >> 57);\n    n += (s & 0x1ffffffffffffffL) << 3; r[25] = n & 0x1ffffffffffffffL;\n    n >>= 57; s = a[53] + (s >> 57);\n    n += s << 3;              r[26] = n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[27], 0, sizeof(*r) * 27U);\n}\n\n/* Reduce the number back to 3072 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_3072_mont_reduce_27(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    sp_3072_norm_27(a + 27);\n\n    for (i=0; i<26; i++) {\n        mu = (a[i] * mp) & 0x1ffffffffffffffL;\n        sp_3072_mul_add_27(a+i, m, mu);\n        a[i+1] += a[i] >> 57;\n    }\n    mu = (a[i] * mp) & 0x3fffffffffffffL;\n    sp_3072_mul_add_27(a+i, m, mu);\n    a[i+1] += a[i] >> 57;\n    a[i] &= 0x1ffffffffffffffL;\n\n    sp_3072_mont_shift_27(a, a);\n    sp_3072_cond_sub_27(a, a, m, 0 - (((a[26] >> 54) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_3072_norm_27(a);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_27(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_27(r, a, b);\n    sp_3072_mont_reduce_27(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_27(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_27(r, a);\n    sp_3072_mont_reduce_27(r, m, mp);\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_3072_mul_d_27(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 27; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x1ffffffffffffffL;\n        t >>= 57;\n    }\n    r[27] = (sp_digit)t;\n#else\n    int128_t tb = b;\n    int128_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x1ffffffffffffffL;\n    for (i = 0; i < 24; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffL);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffL);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 57) + (t[3] & 0x1ffffffffffffffL);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 57) + (t[4] & 0x1ffffffffffffffL);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 57) + (t[5] & 0x1ffffffffffffffL);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 57) + (t[6] & 0x1ffffffffffffffL);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 57) + (t[7] & 0x1ffffffffffffffL);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 57) + (t[0] & 0x1ffffffffffffffL);\n    }\n    t[1] = tb * a[25];\n    r[25] = (sp_digit)(t[0] >> 57) + (t[1] & 0x1ffffffffffffffL);\n    t[2] = tb * a[26];\n    r[26] = (sp_digit)(t[1] >> 57) + (t[2] & 0x1ffffffffffffffL);\n    r[27] =  (sp_digit)(t[2] >> 57);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_3072_cond_add_27(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 27; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i + 0] = a[i + 0] + (b[i + 0] & m);\n        r[i + 1] = a[i + 1] + (b[i + 1] & m);\n        r[i + 2] = a[i + 2] + (b[i + 2] & m);\n        r[i + 3] = a[i + 3] + (b[i + 3] & m);\n        r[i + 4] = a[i + 4] + (b[i + 4] & m);\n        r[i + 5] = a[i + 5] + (b[i + 5] & m);\n        r[i + 6] = a[i + 6] + (b[i + 6] & m);\n        r[i + 7] = a[i + 7] + (b[i + 7] & m);\n    }\n    r[24] = a[24] + (b[24] & m);\n    r[25] = a[25] + (b[25] & m);\n    r[26] = a[26] + (b[26] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SP_DIV_64\nstatic WC_INLINE sp_digit sp_3072_div_word_27(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t, dv;\n    int128_t t0, t1;\n\n    /* dv has 29 bits. */\n    dv = (div >> 28) + 1;\n    /* All 57 bits from d1 and top 6 bits from d0. */\n    d = (d1 << 6) | (d0 >> 51);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 34 bits in r */\n    /* Next 23 bits from d0. */\n    d <<= 23;\n    r <<= 23;\n    d |= (d0 >> 28) & ((1 << 23) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 57 bits in r */\n\n    /* Handle rounding error with dv - top part */\n    t0 = ((int128_t)d1 << 57) + d0;\n    t1 = (int128_t)r * dv;\n    t1 = t0 - t1;\n    t = (sp_digit)(t1 >> 28) / dv;\n    r += t;\n\n    /* Handle rounding error with dv - bottom 64 bits */\n    t1 = (sp_digit)t0 - (r * dv);\n    t = (sp_digit)t1 / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_64 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Number to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_3072_div_27(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_64\n    int128_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[54], t2d[27 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (3 * 27 + 1), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 2 * 27;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        dv = d[26];\n        XMEMCPY(t1, a, sizeof(*t1) * 2U * 27U);\n        for (i=26; i>=0; i--) {\n            t1[27 + i] += t1[27 + i - 1] >> 57;\n            t1[27 + i - 1] &= 0x1ffffffffffffffL;\n#ifndef WOLFSSL_SP_DIV_64\n            d1 = t1[27 + i];\n            d1 <<= 57;\n            d1 += t1[27 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_3072_div_word_27(t1[27 + i], t1[27 + i - 1], dv);\n#endif\n\n            sp_3072_mul_d_27(t2, d, r1);\n            (void)sp_3072_sub_27(&t1[i], &t1[i], t2);\n            t1[27 + i] -= t2[27];\n            t1[27 + i] += t1[27 + i - 1] >> 57;\n            t1[27 + i - 1] &= 0x1ffffffffffffffL;\n            r1 = (((-t1[27 + i]) << 57) - t1[27 + i - 1]) / dv;\n            r1++;\n            sp_3072_mul_d_27(t2, d, r1);\n            (void)sp_3072_add_27(&t1[i], &t1[i], t2);\n            t1[27 + i] += t1[27 + i - 1] >> 57;\n            t1[27 + i - 1] &= 0x1ffffffffffffffL;\n        }\n        t1[27 - 1] += t1[27 - 2] >> 57;\n        t1[27 - 2] &= 0x1ffffffffffffffL;\n        d1 = t1[27 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_3072_mul_d_27(t2, d, r1);\n        (void)sp_3072_sub_27(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 27U);\n        for (i=0; i<25; i++) {\n            r[i+1] += r[i] >> 57;\n            r[i] &= 0x1ffffffffffffffL;\n        }\n        sp_3072_cond_add_27(r, r, d, 0 - ((r[26] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_3072_mod_27(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_27(a, m, NULL, r);\n}\n\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, const sp_digit* e, int bits,\n    const sp_digit* m, int reduceA)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* td;\n    sp_digit* t[3];\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 27 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3U * 27U * 2U);\n\n        norm = t[0] = td;\n        t[1] = &td[27 * 2];\n        t[2] = &td[2 * 27 * 2];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_27(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_3072_mod_27(t[1], a, m);\n        }\n        else {\n            XMEMCPY(t[1], a, sizeof(sp_digit) * 27U);\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_3072_mul_27(t[1], t[1], norm);\n        err = sp_3072_mod_27(t[1], t[1], m);\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 57;\n        c = bits % 57;\n        n = e[i--] << (57 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 57;\n            }\n\n            y = (n >> 56) & 1;\n            n <<= 1;\n\n            sp_3072_mont_mul_27(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(*t[2]) * 27 * 2);\n            sp_3072_mont_sqr_27(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(*t[2]) * 27 * 2);\n        }\n\n        sp_3072_mont_reduce_27(t[0], m, mp);\n        n = sp_3072_cmp_27(t[0], m);\n        sp_3072_cond_sub_27(t[0], t[0], m, ((n < 0) ?\n                    (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(*r) * 27 * 2);\n\n    }\n\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    return err;\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[3][54];\n#else\n    sp_digit* td;\n    sp_digit* t[3];\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 27 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        t[0] = td;\n        t[1] = &td[27 * 2];\n        t[2] = &td[2 * 27 * 2];\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_27(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_3072_mod_27(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_3072_mul_27(t[1], t[1], norm);\n                err = sp_3072_mod_27(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_3072_mul_27(t[1], a, norm);\n            err = sp_3072_mod_27(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 57;\n        c = bits % 57;\n        n = e[i--] << (57 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 57;\n            }\n\n            y = (n >> 56) & 1;\n            n <<= 1;\n\n            sp_3072_mont_mul_27(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_3072_mont_sqr_27(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                           ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));\n        }\n\n        sp_3072_mont_reduce_27(t[0], m, mp);\n        n = sp_3072_cmp_27(t[0], m);\n        sp_3072_cond_sub_27(t[0], t[0], m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(t[0]));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][54];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit rt[54];\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 54, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 54;\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_27(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_3072_mod_27(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_3072_mul_27(t[1], t[1], norm);\n                err = sp_3072_mod_27(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_3072_mul_27(t[1], a, norm);\n            err = sp_3072_mod_27(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_27(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_27(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_27(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_27(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_27(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_27(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_27(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_27(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_27(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_27(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_27(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_27(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_27(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_27(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_27(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_27(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_27(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_27(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_27(t[20], t[10], m, mp);\n        sp_3072_mont_mul_27(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_27(t[22], t[11], m, mp);\n        sp_3072_mont_mul_27(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_27(t[24], t[12], m, mp);\n        sp_3072_mont_mul_27(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_27(t[26], t[13], m, mp);\n        sp_3072_mont_mul_27(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_27(t[28], t[14], m, mp);\n        sp_3072_mont_mul_27(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_27(t[30], t[15], m, mp);\n        sp_3072_mont_mul_27(t[31], t[16], t[15], m, mp);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 56) / 57) - 1;\n        c = bits % 57;\n        if (c == 0) {\n            c = 57;\n        }\n        if (i < 27) {\n            n = e[i--] << (64 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (7 - c);\n            c += 57;\n        }\n        y = (n >> 59) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        XMEMCPY(rt, t[y], sizeof(rt));\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (7 - c);\n                c += 57;\n            }\n            y = (n >> 59) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_3072_mont_sqr_27(rt, rt, m, mp);\n            sp_3072_mont_sqr_27(rt, rt, m, mp);\n            sp_3072_mont_sqr_27(rt, rt, m, mp);\n            sp_3072_mont_sqr_27(rt, rt, m, mp);\n            sp_3072_mont_sqr_27(rt, rt, m, mp);\n\n            sp_3072_mont_mul_27(rt, rt, t[y], m, mp);\n        }\n\n        sp_3072_mont_reduce_27(rt, m, mp);\n        n = sp_3072_cmp_27(rt, m);\n        sp_3072_cond_sub_27(rt, rt, m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, rt, sizeof(rt));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#endif\n}\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_54(sp_digit* r, const sp_digit* m)\n{\n    /* Set r = 2^n - 1. */\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<53; i++) {\n        r[i] = 0x1ffffffffffffffL;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 48; i += 8) {\n        r[i + 0] = 0x1ffffffffffffffL;\n        r[i + 1] = 0x1ffffffffffffffL;\n        r[i + 2] = 0x1ffffffffffffffL;\n        r[i + 3] = 0x1ffffffffffffffL;\n        r[i + 4] = 0x1ffffffffffffffL;\n        r[i + 5] = 0x1ffffffffffffffL;\n        r[i + 6] = 0x1ffffffffffffffL;\n        r[i + 7] = 0x1ffffffffffffffL;\n    }\n    r[48] = 0x1ffffffffffffffL;\n    r[49] = 0x1ffffffffffffffL;\n    r[50] = 0x1ffffffffffffffL;\n    r[51] = 0x1ffffffffffffffL;\n    r[52] = 0x1ffffffffffffffL;\n#endif\n    r[53] = 0x7ffffffffffffL;\n\n    /* r = (2^n - 1) mod n */\n    (void)sp_3072_sub_54(r, r, m);\n\n    /* Add one so r = 2^n mod m */\n    r[0] += 1;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_3072_cmp_54(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=53; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    int i;\n\n    r |= (a[53] - b[53]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[52] - b[52]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[51] - b[51]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[50] - b[50]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[49] - b[49]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[48] - b[48]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    for (i = 40; i >= 0; i -= 8) {\n        r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_3072_cond_sub_54(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 54; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 48; i += 8) {\n        r[i + 0] = a[i + 0] - (b[i + 0] & m);\n        r[i + 1] = a[i + 1] - (b[i + 1] & m);\n        r[i + 2] = a[i + 2] - (b[i + 2] & m);\n        r[i + 3] = a[i + 3] - (b[i + 3] & m);\n        r[i + 4] = a[i + 4] - (b[i + 4] & m);\n        r[i + 5] = a[i + 5] - (b[i + 5] & m);\n        r[i + 6] = a[i + 6] - (b[i + 6] & m);\n        r[i + 7] = a[i + 7] - (b[i + 7] & m);\n    }\n    r[48] = a[48] - (b[48] & m);\n    r[49] = a[49] - (b[49] & m);\n    r[50] = a[50] - (b[50] & m);\n    r[51] = a[51] - (b[51] & m);\n    r[52] = a[52] - (b[52] & m);\n    r[53] = a[53] - (b[53] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_3072_mul_add_54(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 54; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0x1ffffffffffffffL;\n        t >>= 57;\n    }\n    r[54] += t;\n#else\n    int128_t tb = b;\n    int128_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1ffffffffffffffL);\n    for (i = 0; i < 48; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));\n        t[2] = tb * a[i+2];\n        r[i+2] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));\n        t[3] = tb * a[i+3];\n        r[i+3] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));\n        t[4] = tb * a[i+4];\n        r[i+4] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));\n        t[5] = tb * a[i+5];\n        r[i+5] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));\n        t[6] = tb * a[i+6];\n        r[i+6] += (sp_digit)((t[5] >> 57) + (t[6] & 0x1ffffffffffffffL));\n        t[7] = tb * a[i+7];\n        r[i+7] += (sp_digit)((t[6] >> 57) + (t[7] & 0x1ffffffffffffffL));\n        t[0] = tb * a[i+8];\n        r[i+8] += (sp_digit)((t[7] >> 57) + (t[0] & 0x1ffffffffffffffL));\n    }\n    t[1] = tb * a[49]; r[49] += (sp_digit)((t[0] >> 57) + (t[1] & 0x1ffffffffffffffL));\n    t[2] = tb * a[50]; r[50] += (sp_digit)((t[1] >> 57) + (t[2] & 0x1ffffffffffffffL));\n    t[3] = tb * a[51]; r[51] += (sp_digit)((t[2] >> 57) + (t[3] & 0x1ffffffffffffffL));\n    t[4] = tb * a[52]; r[52] += (sp_digit)((t[3] >> 57) + (t[4] & 0x1ffffffffffffffL));\n    t[5] = tb * a[53]; r[53] += (sp_digit)((t[4] >> 57) + (t[5] & 0x1ffffffffffffffL));\n    r[54] +=  (sp_digit)(t[5] >> 57);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Normalize the values in each word to 57.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_3072_norm_54(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 53; i++) {\n        a[i+1] += a[i] >> 57;\n        a[i] &= 0x1ffffffffffffffL;\n    }\n#else\n    int i;\n    for (i = 0; i < 48; i += 8) {\n        a[i+1] += a[i+0] >> 57; a[i+0] &= 0x1ffffffffffffffL;\n        a[i+2] += a[i+1] >> 57; a[i+1] &= 0x1ffffffffffffffL;\n        a[i+3] += a[i+2] >> 57; a[i+2] &= 0x1ffffffffffffffL;\n        a[i+4] += a[i+3] >> 57; a[i+3] &= 0x1ffffffffffffffL;\n        a[i+5] += a[i+4] >> 57; a[i+4] &= 0x1ffffffffffffffL;\n        a[i+6] += a[i+5] >> 57; a[i+5] &= 0x1ffffffffffffffL;\n        a[i+7] += a[i+6] >> 57; a[i+6] &= 0x1ffffffffffffffL;\n        a[i+8] += a[i+7] >> 57; a[i+7] &= 0x1ffffffffffffffL;\n        a[i+9] += a[i+8] >> 57; a[i+8] &= 0x1ffffffffffffffL;\n    }\n    a[48+1] += a[48] >> 57;\n    a[48] &= 0x1ffffffffffffffL;\n    a[49+1] += a[49] >> 57;\n    a[49] &= 0x1ffffffffffffffL;\n    a[50+1] += a[50] >> 57;\n    a[50] &= 0x1ffffffffffffffL;\n    a[51+1] += a[51] >> 57;\n    a[51] &= 0x1ffffffffffffffL;\n    a[52+1] += a[52] >> 57;\n    a[52] &= 0x1ffffffffffffffL;\n#endif\n}\n\n/* Shift the result in the high 3072 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_3072_mont_shift_54(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    int128_t n = a[53] >> 51;\n    n += ((int128_t)a[54]) << 6;\n\n    for (i = 0; i < 53; i++) {\n        r[i] = n & 0x1ffffffffffffffL;\n        n >>= 57;\n        n += ((int128_t)a[55 + i]) << 6;\n    }\n    r[53] = (sp_digit)n;\n#else\n    int i;\n    int128_t n = a[53] >> 51;\n    n += ((int128_t)a[54]) << 6;\n    for (i = 0; i < 48; i += 8) {\n        r[i + 0] = n & 0x1ffffffffffffffL;\n        n >>= 57; n += ((int128_t)a[i + 55]) << 6;\n        r[i + 1] = n & 0x1ffffffffffffffL;\n        n >>= 57; n += ((int128_t)a[i + 56]) << 6;\n        r[i + 2] = n & 0x1ffffffffffffffL;\n        n >>= 57; n += ((int128_t)a[i + 57]) << 6;\n        r[i + 3] = n & 0x1ffffffffffffffL;\n        n >>= 57; n += ((int128_t)a[i + 58]) << 6;\n        r[i + 4] = n & 0x1ffffffffffffffL;\n        n >>= 57; n += ((int128_t)a[i + 59]) << 6;\n        r[i + 5] = n & 0x1ffffffffffffffL;\n        n >>= 57; n += ((int128_t)a[i + 60]) << 6;\n        r[i + 6] = n & 0x1ffffffffffffffL;\n        n >>= 57; n += ((int128_t)a[i + 61]) << 6;\n        r[i + 7] = n & 0x1ffffffffffffffL;\n        n >>= 57; n += ((int128_t)a[i + 62]) << 6;\n    }\n    r[48] = n & 0x1ffffffffffffffL; n >>= 57; n += ((int128_t)a[103]) << 6;\n    r[49] = n & 0x1ffffffffffffffL; n >>= 57; n += ((int128_t)a[104]) << 6;\n    r[50] = n & 0x1ffffffffffffffL; n >>= 57; n += ((int128_t)a[105]) << 6;\n    r[51] = n & 0x1ffffffffffffffL; n >>= 57; n += ((int128_t)a[106]) << 6;\n    r[52] = n & 0x1ffffffffffffffL; n >>= 57; n += ((int128_t)a[107]) << 6;\n    r[53] = (sp_digit)n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[54], 0, sizeof(*r) * 54U);\n}\n\n/* Reduce the number back to 3072 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_3072_mont_reduce_54(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    sp_3072_norm_54(a + 54);\n\n#ifdef WOLFSSL_SP_DH\n    if (mp != 1) {\n        for (i=0; i<53; i++) {\n            mu = (a[i] * mp) & 0x1ffffffffffffffL;\n            sp_3072_mul_add_54(a+i, m, mu);\n            a[i+1] += a[i] >> 57;\n        }\n        mu = (a[i] * mp) & 0x7ffffffffffffL;\n        sp_3072_mul_add_54(a+i, m, mu);\n        a[i+1] += a[i] >> 57;\n        a[i] &= 0x1ffffffffffffffL;\n    }\n    else {\n        for (i=0; i<53; i++) {\n            mu = a[i] & 0x1ffffffffffffffL;\n            sp_3072_mul_add_54(a+i, m, mu);\n            a[i+1] += a[i] >> 57;\n        }\n        mu = a[i] & 0x7ffffffffffffL;\n        sp_3072_mul_add_54(a+i, m, mu);\n        a[i+1] += a[i] >> 57;\n        a[i] &= 0x1ffffffffffffffL;\n    }\n#else\n    for (i=0; i<53; i++) {\n        mu = (a[i] * mp) & 0x1ffffffffffffffL;\n        sp_3072_mul_add_54(a+i, m, mu);\n        a[i+1] += a[i] >> 57;\n    }\n    mu = (a[i] * mp) & 0x7ffffffffffffL;\n    sp_3072_mul_add_54(a+i, m, mu);\n    a[i+1] += a[i] >> 57;\n    a[i] &= 0x1ffffffffffffffL;\n#endif\n\n    sp_3072_mont_shift_54(a, a);\n    sp_3072_cond_sub_54(a, a, m, 0 - (((a[53] >> 51) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_3072_norm_54(a);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_54(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_54(r, a, b);\n    sp_3072_mont_reduce_54(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_54(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_54(r, a);\n    sp_3072_mont_reduce_54(r, m, mp);\n}\n\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_3072_cond_add_54(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 54; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 48; i += 8) {\n        r[i + 0] = a[i + 0] + (b[i + 0] & m);\n        r[i + 1] = a[i + 1] + (b[i + 1] & m);\n        r[i + 2] = a[i + 2] + (b[i + 2] & m);\n        r[i + 3] = a[i + 3] + (b[i + 3] & m);\n        r[i + 4] = a[i + 4] + (b[i + 4] & m);\n        r[i + 5] = a[i + 5] + (b[i + 5] & m);\n        r[i + 6] = a[i + 6] + (b[i + 6] & m);\n        r[i + 7] = a[i + 7] + (b[i + 7] & m);\n    }\n    r[48] = a[48] + (b[48] & m);\n    r[49] = a[49] + (b[49] & m);\n    r[50] = a[50] + (b[50] & m);\n    r[51] = a[51] + (b[51] & m);\n    r[52] = a[52] + (b[52] & m);\n    r[53] = a[53] + (b[53] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SP_DIV_64\nstatic WC_INLINE sp_digit sp_3072_div_word_54(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t, dv;\n    int128_t t0, t1;\n\n    /* dv has 29 bits. */\n    dv = (div >> 28) + 1;\n    /* All 57 bits from d1 and top 6 bits from d0. */\n    d = (d1 << 6) | (d0 >> 51);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 34 bits in r */\n    /* Next 23 bits from d0. */\n    d <<= 23;\n    r <<= 23;\n    d |= (d0 >> 28) & ((1 << 23) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 57 bits in r */\n\n    /* Handle rounding error with dv - top part */\n    t0 = ((int128_t)d1 << 57) + d0;\n    t1 = (int128_t)r * dv;\n    t1 = t0 - t1;\n    t = (sp_digit)(t1 >> 28) / dv;\n    r += t;\n\n    /* Handle rounding error with dv - bottom 64 bits */\n    t1 = (sp_digit)t0 - (r * dv);\n    t = (sp_digit)t1 / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_64 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Number to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_3072_div_54(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_64\n    int128_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[108], t2d[54 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (3 * 54 + 1), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 2 * 54;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        dv = d[53];\n        XMEMCPY(t1, a, sizeof(*t1) * 2U * 54U);\n        for (i=53; i>=0; i--) {\n            t1[54 + i] += t1[54 + i - 1] >> 57;\n            t1[54 + i - 1] &= 0x1ffffffffffffffL;\n#ifndef WOLFSSL_SP_DIV_64\n            d1 = t1[54 + i];\n            d1 <<= 57;\n            d1 += t1[54 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_3072_div_word_54(t1[54 + i], t1[54 + i - 1], dv);\n#endif\n\n            sp_3072_mul_d_54(t2, d, r1);\n            (void)sp_3072_sub_54(&t1[i], &t1[i], t2);\n            t1[54 + i] -= t2[54];\n            t1[54 + i] += t1[54 + i - 1] >> 57;\n            t1[54 + i - 1] &= 0x1ffffffffffffffL;\n            r1 = (((-t1[54 + i]) << 57) - t1[54 + i - 1]) / dv;\n            r1++;\n            sp_3072_mul_d_54(t2, d, r1);\n            (void)sp_3072_add_54(&t1[i], &t1[i], t2);\n            t1[54 + i] += t1[54 + i - 1] >> 57;\n            t1[54 + i - 1] &= 0x1ffffffffffffffL;\n        }\n        t1[54 - 1] += t1[54 - 2] >> 57;\n        t1[54 - 2] &= 0x1ffffffffffffffL;\n        d1 = t1[54 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_3072_mul_d_54(t2, d, r1);\n        (void)sp_3072_sub_54(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 54U);\n        for (i=0; i<52; i++) {\n            r[i+1] += r[i] >> 57;\n            r[i] &= 0x1ffffffffffffffL;\n        }\n        sp_3072_cond_add_54(r, r, d, 0 - ((r[53] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_3072_mod_54(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_54(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, const sp_digit* e, int bits,\n    const sp_digit* m, int reduceA)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* td;\n    sp_digit* t[3];\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 54 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3U * 54U * 2U);\n\n        norm = t[0] = td;\n        t[1] = &td[54 * 2];\n        t[2] = &td[2 * 54 * 2];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_54(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_3072_mod_54(t[1], a, m);\n        }\n        else {\n            XMEMCPY(t[1], a, sizeof(sp_digit) * 54U);\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_3072_mul_54(t[1], t[1], norm);\n        err = sp_3072_mod_54(t[1], t[1], m);\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 57;\n        c = bits % 57;\n        n = e[i--] << (57 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 57;\n            }\n\n            y = (n >> 56) & 1;\n            n <<= 1;\n\n            sp_3072_mont_mul_54(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(*t[2]) * 54 * 2);\n            sp_3072_mont_sqr_54(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(*t[2]) * 54 * 2);\n        }\n\n        sp_3072_mont_reduce_54(t[0], m, mp);\n        n = sp_3072_cmp_54(t[0], m);\n        sp_3072_cond_sub_54(t[0], t[0], m, ((n < 0) ?\n                    (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(*r) * 54 * 2);\n\n    }\n\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    return err;\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[3][108];\n#else\n    sp_digit* td;\n    sp_digit* t[3];\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 54 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        t[0] = td;\n        t[1] = &td[54 * 2];\n        t[2] = &td[2 * 54 * 2];\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_54(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_3072_mod_54(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_3072_mul_54(t[1], t[1], norm);\n                err = sp_3072_mod_54(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_3072_mul_54(t[1], a, norm);\n            err = sp_3072_mod_54(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 57;\n        c = bits % 57;\n        n = e[i--] << (57 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 57;\n            }\n\n            y = (n >> 56) & 1;\n            n <<= 1;\n\n            sp_3072_mont_mul_54(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_3072_mont_sqr_54(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                           ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));\n        }\n\n        sp_3072_mont_reduce_54(t[0], m, mp);\n        n = sp_3072_cmp_54(t[0], m);\n        sp_3072_cond_sub_54(t[0], t[0], m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(t[0]));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][108];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit rt[108];\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 108, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 108;\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_54(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_3072_mod_54(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_3072_mul_54(t[1], t[1], norm);\n                err = sp_3072_mod_54(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_3072_mul_54(t[1], a, norm);\n            err = sp_3072_mod_54(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_54(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_54(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_54(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_54(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_54(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_54(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_54(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_54(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_54(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_54(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_54(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_54(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_54(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_54(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_54(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_54(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_54(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_54(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_54(t[20], t[10], m, mp);\n        sp_3072_mont_mul_54(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_54(t[22], t[11], m, mp);\n        sp_3072_mont_mul_54(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_54(t[24], t[12], m, mp);\n        sp_3072_mont_mul_54(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_54(t[26], t[13], m, mp);\n        sp_3072_mont_mul_54(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_54(t[28], t[14], m, mp);\n        sp_3072_mont_mul_54(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_54(t[30], t[15], m, mp);\n        sp_3072_mont_mul_54(t[31], t[16], t[15], m, mp);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 56) / 57) - 1;\n        c = bits % 57;\n        if (c == 0) {\n            c = 57;\n        }\n        if (i < 54) {\n            n = e[i--] << (64 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (7 - c);\n            c += 57;\n        }\n        y = (n >> 59) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        XMEMCPY(rt, t[y], sizeof(rt));\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (7 - c);\n                c += 57;\n            }\n            y = (n >> 59) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_3072_mont_sqr_54(rt, rt, m, mp);\n            sp_3072_mont_sqr_54(rt, rt, m, mp);\n            sp_3072_mont_sqr_54(rt, rt, m, mp);\n            sp_3072_mont_sqr_54(rt, rt, m, mp);\n            sp_3072_mont_sqr_54(rt, rt, m, mp);\n\n            sp_3072_mont_mul_54(rt, rt, t[y], m, mp);\n        }\n\n        sp_3072_mont_reduce_54(rt, m, mp);\n        n = sp_3072_cmp_54(rt, m);\n        sp_3072_cond_sub_54(rt, rt, m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, rt, sizeof(rt));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#endif\n}\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */\n       /* WOLFSSL_HAVE_SP_DH */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \\\n           !defined(RSA_LOW_MEM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_27(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<27; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n    r[24] = a[24] & m;\n    r[25] = a[25] & m;\n    r[26] = a[26] & m;\n#endif\n}\n\n#endif\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* d = NULL;\n    sp_digit* a;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit* norm;\n    sp_digit e[1] = {0};\n    sp_digit mp;\n    int i;\n    int err = MP_OKAY;\n\n    if (*outLen < 384U) {\n        err = MP_TO_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(em) > 57) {\n            err = MP_READ_E;\n        }\n        if (inLen > 384U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 54 * 2;\n        m = r + 54 * 2;\n        norm = r;\n\n        sp_3072_from_bin(a, 54, in, inLen);\n#if DIGIT_BIT >= 57\n        e[0] = (sp_digit)em->dp[0];\n#else\n        e[0] = (sp_digit)em->dp[0];\n        if (em->used > 1) {\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n        }\n#endif\n        if (e[0] == 0) {\n            err = MP_EXPTMOD_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(m, 54, mm);\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_54(norm, m);\n    }\n    if (err == MP_OKAY) {\n        sp_3072_mul_54(a, a, norm);\n        err = sp_3072_mod_54(a, a, m);\n    }\n    if (err == MP_OKAY) {\n        for (i=56; i>=0; i--) {\n            if ((e[0] >> i) != 0) {\n                break;\n            }\n        }\n\n        XMEMCPY(r, a, sizeof(sp_digit) * 54 * 2);\n        for (i--; i>=0; i--) {\n            sp_3072_mont_sqr_54(r, r, m, mp);\n\n            if (((e[0] >> i) & 1) == 1) {\n                sp_3072_mont_mul_54(r, r, a, m, mp);\n            }\n        }\n        sp_3072_mont_reduce_54(r, m, mp);\n        mp = sp_3072_cmp_54(r, m);\n        sp_3072_cond_sub_54(r, r, m, ((mp < 0) ?\n                    (sp_digit)1 : (sp_digit)0)- 1);\n\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[108], md[54], rd[108];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1] = {0};\n    int err = MP_OKAY;\n\n    if (*outLen < 384U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(em) > 57) {\n            err = MP_READ_E;\n        }\n        if (inLen > 384U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 54 * 2;\n        m = r + 54 * 2;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(a, 54, in, inLen);\n#if DIGIT_BIT >= 57\n        e[0] = (sp_digit)em->dp[0];\n#else\n        e[0] = (sp_digit)em->dp[0];\n        if (em->used > 1) {\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n        }\n#endif\n        if (e[0] == 0) {\n            err = MP_EXPTMOD_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(m, 54, mm);\n\n        if (e[0] == 0x3) {\n            sp_3072_sqr_54(r, a);\n            err = sp_3072_mod_54(r, r, m);\n            if (err == MP_OKAY) {\n                sp_3072_mul_54(r, a, r);\n                err = sp_3072_mod_54(r, r, m);\n            }\n        }\n        else {\n            sp_digit* norm = r;\n            int i;\n            sp_digit mp;\n\n            sp_3072_mont_setup(m, &mp);\n            sp_3072_mont_norm_54(norm, m);\n\n            sp_3072_mul_54(a, a, norm);\n            err = sp_3072_mod_54(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=56; i>=0; i--) {\n                    if ((e[0] >> i) != 0) {\n                        break;\n                    }\n                }\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 108U);\n                for (i--; i>=0; i--) {\n                    sp_3072_mont_sqr_54(r, r, m, mp);\n\n                    if (((e[0] >> i) & 1) == 1) {\n                        sp_3072_mont_mul_54(r, r, a, m, mp);\n                    }\n                }\n                sp_3072_mont_reduce_54(r, m, mp);\n                mp = sp_3072_cmp_54(r, m);\n                sp_3072_cond_sub_54(r, r, m, ((mp < 0) ?\n                           (sp_digit)1 : (sp_digit)0) - 1);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n#endif\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* a;\n    sp_digit* d = NULL;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n\n    (void)pm;\n    (void)qm;\n    (void)dpm;\n    (void)dqm;\n    (void)qim;\n\n    if (*outLen < 384U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(dm) > 3072) {\n           err = MP_READ_E;\n        }\n        if (inLen > 384) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 54 * 4, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        a = d + 54;\n        m = a + 54;\n        r = a;\n\n        sp_3072_from_bin(a, 54, in, inLen);\n        sp_3072_from_mp(d, 54, dm);\n        sp_3072_from_mp(m, 54, mm);\n        err = sp_3072_mod_exp_54(r, a, d, 3072, m, 0);\n    }\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n    if (d != NULL) {\n        XMEMSET(d, 0, sizeof(sp_digit) * 54);\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n    sp_digit a[108], d[54], m[54];\n    sp_digit* r = a;\n    int err = MP_OKAY;\n\n    (void)pm;\n    (void)qm;\n    (void)dpm;\n    (void)dqm;\n    (void)qim;\n\n    if (*outLen < 384U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(dm) > 3072) {\n            err = MP_READ_E;\n        }\n        if (inLen > 384U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(a, 54, in, inLen);\n        sp_3072_from_mp(d, 54, dm);\n        sp_3072_from_mp(m, 54, mm);\n        err = sp_3072_mod_exp_54(r, a, d, 3072, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n    XMEMSET(d, 0, sizeof(sp_digit) * 54);\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */\n#else\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* t = NULL;\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 384U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (inLen > 384) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 27 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL) {\n            err = MEMORY_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 54 * 2;\n        q = p + 27;\n        qi = dq = dp = q + 27;\n        tmpa = qi + 27;\n        tmpb = tmpa + 54;\n\n        tmp = t;\n        r = tmp + 54;\n\n        sp_3072_from_bin(a, 54, in, inLen);\n        sp_3072_from_mp(p, 27, pm);\n        sp_3072_from_mp(q, 27, qm);\n        sp_3072_from_mp(dp, 27, dpm);\n        err = sp_3072_mod_exp_27(tmpa, a, dp, 1536, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(dq, 27, dqm);\n        err = sp_3072_mod_exp_27(tmpb, a, dq, 1536, q, 1);\n    }\n    if (err == MP_OKAY) {\n        (void)sp_3072_sub_27(tmpa, tmpa, tmpb);\n        sp_3072_mask_27(tmp, p, 0 - ((sp_int_digit)tmpa[26] >> 63));\n        (void)sp_3072_add_27(tmpa, tmpa, tmp);\n\n        sp_3072_from_mp(qi, 27, qim);\n        sp_3072_mul_27(tmpa, tmpa, qi);\n        err = sp_3072_mod_27(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mul_27(tmpa, q, tmpa);\n        (void)sp_3072_add_54(r, tmpb, tmpa);\n        sp_3072_norm_54(r);\n\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 27 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n    sp_digit a[54 * 2];\n    sp_digit p[27], q[27], dp[27], dq[27], qi[27];\n    sp_digit tmp[54], tmpa[54], tmpb[54];\n    sp_digit* r = a;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 384U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (inLen > 384U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(a, 54, in, inLen);\n        sp_3072_from_mp(p, 27, pm);\n        sp_3072_from_mp(q, 27, qm);\n        sp_3072_from_mp(dp, 27, dpm);\n        sp_3072_from_mp(dq, 27, dqm);\n        sp_3072_from_mp(qi, 27, qim);\n\n        err = sp_3072_mod_exp_27(tmpa, a, dp, 1536, p, 1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_3072_mod_exp_27(tmpb, a, dq, 1536, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        (void)sp_3072_sub_27(tmpa, tmpa, tmpb);\n        sp_3072_mask_27(tmp, p, 0 - ((sp_int_digit)tmpa[26] >> 63));\n        (void)sp_3072_add_27(tmpa, tmpa, tmp);\n        sp_3072_mul_27(tmpa, tmpa, qi);\n        err = sp_3072_mod_27(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mul_27(tmpa, tmpa, q);\n        (void)sp_3072_add_54(r, tmpb, tmpa);\n        sp_3072_norm_54(r);\n\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n    XMEMSET(tmpa, 0, sizeof(tmpa));\n    XMEMSET(tmpb, 0, sizeof(tmpb));\n    XMEMSET(p, 0, sizeof(p));\n    XMEMSET(q, 0, sizeof(q));\n    XMEMSET(dp, 0, sizeof(dp));\n    XMEMSET(dq, 0, sizeof(dq));\n    XMEMSET(qi, 0, sizeof(qi));\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */\n#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */\n}\n\n#endif /* !WOLFSSL_RSA_PUBLIC_ONLY */\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_3072_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 57\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 54);\n        r->used = 54;\n        mp_clamp(r);\n#elif DIGIT_BIT < 57\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 54; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 57) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 57 - s;\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 54; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 57 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 57 - s;\n            }\n            else {\n                s += 57;\n            }\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 54 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 54 * 2;\n        m = e + 54;\n        r = b;\n\n        sp_3072_from_mp(b, 54, base);\n        sp_3072_from_mp(e, 54, exp);\n        sp_3072_from_mp(m, 54, mod);\n\n        err = sp_3072_mod_exp_54(r, b, e, mp_count_bits(exp), m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_3072_to_mp(r, res);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 54U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[108], ed[54], md[54];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 3072) {\n            err = MP_READ_E;\n        }\n    }\n    \n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 54 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 54 * 2;\n        m = e + 54;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 54, base);\n        sp_3072_from_mp(e, 54, exp);\n        sp_3072_from_mp(m, 54, mod);\n\n        err = sp_3072_mod_exp_54(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_3072_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 54U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_3072\nSP_NOINLINE static void sp_3072_lshift_54(sp_digit* r, sp_digit* a, byte n)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    r[54] = a[53] >> (57 - n);\n    for (i=53; i>0; i--) {\n        r[i] = ((a[i] << n) | (a[i-1] >> (57 - n))) & 0x1ffffffffffffffL;\n    }\n#else\n    sp_int_digit s, t;\n\n    s = (sp_int_digit)a[53];\n    r[54] = s >> (57U - n);\n    s = (sp_int_digit)(a[53]); t = (sp_int_digit)(a[52]);\n    r[53] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[52]); t = (sp_int_digit)(a[51]);\n    r[52] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[51]); t = (sp_int_digit)(a[50]);\n    r[51] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[50]); t = (sp_int_digit)(a[49]);\n    r[50] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[49]); t = (sp_int_digit)(a[48]);\n    r[49] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[48]); t = (sp_int_digit)(a[47]);\n    r[48] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[47]); t = (sp_int_digit)(a[46]);\n    r[47] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[46]); t = (sp_int_digit)(a[45]);\n    r[46] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[45]); t = (sp_int_digit)(a[44]);\n    r[45] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[44]); t = (sp_int_digit)(a[43]);\n    r[44] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[43]); t = (sp_int_digit)(a[42]);\n    r[43] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[42]); t = (sp_int_digit)(a[41]);\n    r[42] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[41]); t = (sp_int_digit)(a[40]);\n    r[41] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[40]); t = (sp_int_digit)(a[39]);\n    r[40] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[39]); t = (sp_int_digit)(a[38]);\n    r[39] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[38]); t = (sp_int_digit)(a[37]);\n    r[38] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[37]); t = (sp_int_digit)(a[36]);\n    r[37] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[36]); t = (sp_int_digit)(a[35]);\n    r[36] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[35]); t = (sp_int_digit)(a[34]);\n    r[35] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[34]); t = (sp_int_digit)(a[33]);\n    r[34] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[33]); t = (sp_int_digit)(a[32]);\n    r[33] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[32]); t = (sp_int_digit)(a[31]);\n    r[32] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[31]); t = (sp_int_digit)(a[30]);\n    r[31] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[30]); t = (sp_int_digit)(a[29]);\n    r[30] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[29]); t = (sp_int_digit)(a[28]);\n    r[29] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[28]); t = (sp_int_digit)(a[27]);\n    r[28] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[27]); t = (sp_int_digit)(a[26]);\n    r[27] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[26]); t = (sp_int_digit)(a[25]);\n    r[26] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[25]); t = (sp_int_digit)(a[24]);\n    r[25] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[24]); t = (sp_int_digit)(a[23]);\n    r[24] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[23]); t = (sp_int_digit)(a[22]);\n    r[23] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[22]); t = (sp_int_digit)(a[21]);\n    r[22] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[21]); t = (sp_int_digit)(a[20]);\n    r[21] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[20]); t = (sp_int_digit)(a[19]);\n    r[20] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[19]); t = (sp_int_digit)(a[18]);\n    r[19] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[18]); t = (sp_int_digit)(a[17]);\n    r[18] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[17]); t = (sp_int_digit)(a[16]);\n    r[17] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[16]); t = (sp_int_digit)(a[15]);\n    r[16] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[15]); t = (sp_int_digit)(a[14]);\n    r[15] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[14]); t = (sp_int_digit)(a[13]);\n    r[14] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);\n    r[13] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);\n    r[12] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);\n    r[11] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);\n    r[10] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);\n    r[9] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);\n    r[8] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);\n    r[7] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);\n    r[6] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);\n    r[5] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);\n    r[4] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);\n    r[3] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);\n    r[2] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n    s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);\n    r[1] = ((s << n) | (t >> (57U - n))) & 0x1ffffffffffffffUL;\n#endif\n    r[0] = (a[0] << n) & 0x1ffffffffffffffL;\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_2_54(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[108];\n    sp_digit td[55];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 163, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 108;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        XMEMSET(td, 0, sizeof(td));\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_54(norm, m);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 56) / 57) - 1;\n        c = bits % 57;\n        if (c == 0) {\n            c = 57;\n        }\n        if (i < 54) {\n            n = e[i--] << (64 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (7 - c);\n            c += 57;\n        }\n        y = (n >> 59) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        sp_3072_lshift_54(r, norm, y);\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (7 - c);\n                c += 57;\n            }\n            y = (n >> 59) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_3072_mont_sqr_54(r, r, m, mp);\n            sp_3072_mont_sqr_54(r, r, m, mp);\n            sp_3072_mont_sqr_54(r, r, m, mp);\n            sp_3072_mont_sqr_54(r, r, m, mp);\n            sp_3072_mont_sqr_54(r, r, m, mp);\n\n            sp_3072_lshift_54(r, r, y);\n            sp_3072_mul_d_54(tmp, norm, (r[54] << 6) + (r[53] >> 51));\n            r[54] = 0;\n            r[53] &= 0x7ffffffffffffL;\n            (void)sp_3072_add_54(r, r, tmp);\n            sp_3072_norm_54(r);\n            o = sp_3072_cmp_54(r, m);\n            sp_3072_cond_sub_54(r, r, m, ((o < 0) ?\n                                          (sp_digit)1 : (sp_digit)0) - 1);\n        }\n\n        sp_3072_mont_reduce_54(r, m, mp);\n        n = sp_3072_cmp_54(r, m);\n        sp_3072_cond_sub_54(r, r, m, ((n < 0) ?\n                                                (sp_digit)1 : (sp_digit)0) - 1);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n#endif /* HAVE_FFDHE_3072 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 384 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    word32 i;\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 384) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 54 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 54 * 2;\n        m = e + 54;\n        r = b;\n\n        sp_3072_from_mp(b, 54, base);\n        sp_3072_from_bin(e, 54, exp, expLen);\n        sp_3072_from_mp(m, 54, mod);\n\n    #ifdef HAVE_FFDHE_3072\n        if (base->used == 1 && base->dp[0] == 2 &&\n                (m[53] >> 19) == 0xffffffffL) {\n            err = sp_3072_mod_exp_2_54(r, e, expLen * 8, m);\n        }\n        else\n    #endif\n            err = sp_3072_mod_exp_54(r, b, e, expLen * 8, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n        for (i=0; i<384 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 54U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[108], ed[54], md[54];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    word32 i;\n    int err = MP_OKAY;\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 384U) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 54 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 54 * 2;\n        m = e + 54;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 54, base);\n        sp_3072_from_bin(e, 54, exp, expLen);\n        sp_3072_from_mp(m, 54, mod);\n\n    #ifdef HAVE_FFDHE_3072\n        if (base->used == 1 && base->dp[0] == 2U &&\n                (m[53] >> 19) == 0xffffffffL) {\n            err = sp_3072_mod_exp_2_54(r, e, expLen * 8U, m);\n        }\n        else {\n    #endif\n            err = sp_3072_mod_exp_54(r, b, e, expLen * 8U, m, 0);\n    #ifdef HAVE_FFDHE_3072\n        }\n    #endif\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n        for (i=0; i<384U && out[i] == 0U; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 54U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1536) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 27 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 27 * 2;\n        m = e + 27;\n        r = b;\n\n        sp_3072_from_mp(b, 27, base);\n        sp_3072_from_mp(e, 27, exp);\n        sp_3072_from_mp(m, 27, mod);\n\n        err = sp_3072_mod_exp_27(r, b, e, mp_count_bits(exp), m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 27, 0, sizeof(*r) * 27U);\n        err = sp_3072_to_mp(r, res);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 27U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[54], ed[27], md[27];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1536) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1536) {\n            err = MP_READ_E;\n        }\n    }\n    \n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 27 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 27 * 2;\n        m = e + 27;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 27, base);\n        sp_3072_from_mp(e, 27, exp);\n        sp_3072_from_mp(m, 27, mod);\n\n        err = sp_3072_mod_exp_27(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 27, 0, sizeof(*r) * 27U);\n        err = sp_3072_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 27U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_3072 */\n\n#ifdef WOLFSSL_SP_4096\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 45U) {\n            r[j] &= 0x1fffffffffffffL;\n            s = 53U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 53\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 53\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0x1fffffffffffffL;\n        s = 53U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 53U) <= (word32)DIGIT_BIT) {\n            s += 53U;\n            r[j] &= 0x1fffffffffffffL;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 53) {\n            r[j] &= 0x1fffffffffffffL;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 53 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 512\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_4096_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    for (i=0; i<77; i++) {\n        r[i+1] += r[i] >> 53;\n        r[i] &= 0x1fffffffffffffL;\n    }\n    j = 4096 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<78 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 53) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 53);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_13(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int128_t t0   = ((int128_t)a[ 0]) * b[ 0];\n    int128_t t1   = ((int128_t)a[ 0]) * b[ 1]\n                 + ((int128_t)a[ 1]) * b[ 0];\n    int128_t t2   = ((int128_t)a[ 0]) * b[ 2]\n                 + ((int128_t)a[ 1]) * b[ 1]\n                 + ((int128_t)a[ 2]) * b[ 0];\n    int128_t t3   = ((int128_t)a[ 0]) * b[ 3]\n                 + ((int128_t)a[ 1]) * b[ 2]\n                 + ((int128_t)a[ 2]) * b[ 1]\n                 + ((int128_t)a[ 3]) * b[ 0];\n    int128_t t4   = ((int128_t)a[ 0]) * b[ 4]\n                 + ((int128_t)a[ 1]) * b[ 3]\n                 + ((int128_t)a[ 2]) * b[ 2]\n                 + ((int128_t)a[ 3]) * b[ 1]\n                 + ((int128_t)a[ 4]) * b[ 0];\n    int128_t t5   = ((int128_t)a[ 0]) * b[ 5]\n                 + ((int128_t)a[ 1]) * b[ 4]\n                 + ((int128_t)a[ 2]) * b[ 3]\n                 + ((int128_t)a[ 3]) * b[ 2]\n                 + ((int128_t)a[ 4]) * b[ 1]\n                 + ((int128_t)a[ 5]) * b[ 0];\n    int128_t t6   = ((int128_t)a[ 0]) * b[ 6]\n                 + ((int128_t)a[ 1]) * b[ 5]\n                 + ((int128_t)a[ 2]) * b[ 4]\n                 + ((int128_t)a[ 3]) * b[ 3]\n                 + ((int128_t)a[ 4]) * b[ 2]\n                 + ((int128_t)a[ 5]) * b[ 1]\n                 + ((int128_t)a[ 6]) * b[ 0];\n    int128_t t7   = ((int128_t)a[ 0]) * b[ 7]\n                 + ((int128_t)a[ 1]) * b[ 6]\n                 + ((int128_t)a[ 2]) * b[ 5]\n                 + ((int128_t)a[ 3]) * b[ 4]\n                 + ((int128_t)a[ 4]) * b[ 3]\n                 + ((int128_t)a[ 5]) * b[ 2]\n                 + ((int128_t)a[ 6]) * b[ 1]\n                 + ((int128_t)a[ 7]) * b[ 0];\n    int128_t t8   = ((int128_t)a[ 0]) * b[ 8]\n                 + ((int128_t)a[ 1]) * b[ 7]\n                 + ((int128_t)a[ 2]) * b[ 6]\n                 + ((int128_t)a[ 3]) * b[ 5]\n                 + ((int128_t)a[ 4]) * b[ 4]\n                 + ((int128_t)a[ 5]) * b[ 3]\n                 + ((int128_t)a[ 6]) * b[ 2]\n                 + ((int128_t)a[ 7]) * b[ 1]\n                 + ((int128_t)a[ 8]) * b[ 0];\n    int128_t t9   = ((int128_t)a[ 0]) * b[ 9]\n                 + ((int128_t)a[ 1]) * b[ 8]\n                 + ((int128_t)a[ 2]) * b[ 7]\n                 + ((int128_t)a[ 3]) * b[ 6]\n                 + ((int128_t)a[ 4]) * b[ 5]\n                 + ((int128_t)a[ 5]) * b[ 4]\n                 + ((int128_t)a[ 6]) * b[ 3]\n                 + ((int128_t)a[ 7]) * b[ 2]\n                 + ((int128_t)a[ 8]) * b[ 1]\n                 + ((int128_t)a[ 9]) * b[ 0];\n    int128_t t10  = ((int128_t)a[ 0]) * b[10]\n                 + ((int128_t)a[ 1]) * b[ 9]\n                 + ((int128_t)a[ 2]) * b[ 8]\n                 + ((int128_t)a[ 3]) * b[ 7]\n                 + ((int128_t)a[ 4]) * b[ 6]\n                 + ((int128_t)a[ 5]) * b[ 5]\n                 + ((int128_t)a[ 6]) * b[ 4]\n                 + ((int128_t)a[ 7]) * b[ 3]\n                 + ((int128_t)a[ 8]) * b[ 2]\n                 + ((int128_t)a[ 9]) * b[ 1]\n                 + ((int128_t)a[10]) * b[ 0];\n    int128_t t11  = ((int128_t)a[ 0]) * b[11]\n                 + ((int128_t)a[ 1]) * b[10]\n                 + ((int128_t)a[ 2]) * b[ 9]\n                 + ((int128_t)a[ 3]) * b[ 8]\n                 + ((int128_t)a[ 4]) * b[ 7]\n                 + ((int128_t)a[ 5]) * b[ 6]\n                 + ((int128_t)a[ 6]) * b[ 5]\n                 + ((int128_t)a[ 7]) * b[ 4]\n                 + ((int128_t)a[ 8]) * b[ 3]\n                 + ((int128_t)a[ 9]) * b[ 2]\n                 + ((int128_t)a[10]) * b[ 1]\n                 + ((int128_t)a[11]) * b[ 0];\n    int128_t t12  = ((int128_t)a[ 0]) * b[12]\n                 + ((int128_t)a[ 1]) * b[11]\n                 + ((int128_t)a[ 2]) * b[10]\n                 + ((int128_t)a[ 3]) * b[ 9]\n                 + ((int128_t)a[ 4]) * b[ 8]\n                 + ((int128_t)a[ 5]) * b[ 7]\n                 + ((int128_t)a[ 6]) * b[ 6]\n                 + ((int128_t)a[ 7]) * b[ 5]\n                 + ((int128_t)a[ 8]) * b[ 4]\n                 + ((int128_t)a[ 9]) * b[ 3]\n                 + ((int128_t)a[10]) * b[ 2]\n                 + ((int128_t)a[11]) * b[ 1]\n                 + ((int128_t)a[12]) * b[ 0];\n    int128_t t13  = ((int128_t)a[ 1]) * b[12]\n                 + ((int128_t)a[ 2]) * b[11]\n                 + ((int128_t)a[ 3]) * b[10]\n                 + ((int128_t)a[ 4]) * b[ 9]\n                 + ((int128_t)a[ 5]) * b[ 8]\n                 + ((int128_t)a[ 6]) * b[ 7]\n                 + ((int128_t)a[ 7]) * b[ 6]\n                 + ((int128_t)a[ 8]) * b[ 5]\n                 + ((int128_t)a[ 9]) * b[ 4]\n                 + ((int128_t)a[10]) * b[ 3]\n                 + ((int128_t)a[11]) * b[ 2]\n                 + ((int128_t)a[12]) * b[ 1];\n    int128_t t14  = ((int128_t)a[ 2]) * b[12]\n                 + ((int128_t)a[ 3]) * b[11]\n                 + ((int128_t)a[ 4]) * b[10]\n                 + ((int128_t)a[ 5]) * b[ 9]\n                 + ((int128_t)a[ 6]) * b[ 8]\n                 + ((int128_t)a[ 7]) * b[ 7]\n                 + ((int128_t)a[ 8]) * b[ 6]\n                 + ((int128_t)a[ 9]) * b[ 5]\n                 + ((int128_t)a[10]) * b[ 4]\n                 + ((int128_t)a[11]) * b[ 3]\n                 + ((int128_t)a[12]) * b[ 2];\n    int128_t t15  = ((int128_t)a[ 3]) * b[12]\n                 + ((int128_t)a[ 4]) * b[11]\n                 + ((int128_t)a[ 5]) * b[10]\n                 + ((int128_t)a[ 6]) * b[ 9]\n                 + ((int128_t)a[ 7]) * b[ 8]\n                 + ((int128_t)a[ 8]) * b[ 7]\n                 + ((int128_t)a[ 9]) * b[ 6]\n                 + ((int128_t)a[10]) * b[ 5]\n                 + ((int128_t)a[11]) * b[ 4]\n                 + ((int128_t)a[12]) * b[ 3];\n    int128_t t16  = ((int128_t)a[ 4]) * b[12]\n                 + ((int128_t)a[ 5]) * b[11]\n                 + ((int128_t)a[ 6]) * b[10]\n                 + ((int128_t)a[ 7]) * b[ 9]\n                 + ((int128_t)a[ 8]) * b[ 8]\n                 + ((int128_t)a[ 9]) * b[ 7]\n                 + ((int128_t)a[10]) * b[ 6]\n                 + ((int128_t)a[11]) * b[ 5]\n                 + ((int128_t)a[12]) * b[ 4];\n    int128_t t17  = ((int128_t)a[ 5]) * b[12]\n                 + ((int128_t)a[ 6]) * b[11]\n                 + ((int128_t)a[ 7]) * b[10]\n                 + ((int128_t)a[ 8]) * b[ 9]\n                 + ((int128_t)a[ 9]) * b[ 8]\n                 + ((int128_t)a[10]) * b[ 7]\n                 + ((int128_t)a[11]) * b[ 6]\n                 + ((int128_t)a[12]) * b[ 5];\n    int128_t t18  = ((int128_t)a[ 6]) * b[12]\n                 + ((int128_t)a[ 7]) * b[11]\n                 + ((int128_t)a[ 8]) * b[10]\n                 + ((int128_t)a[ 9]) * b[ 9]\n                 + ((int128_t)a[10]) * b[ 8]\n                 + ((int128_t)a[11]) * b[ 7]\n                 + ((int128_t)a[12]) * b[ 6];\n    int128_t t19  = ((int128_t)a[ 7]) * b[12]\n                 + ((int128_t)a[ 8]) * b[11]\n                 + ((int128_t)a[ 9]) * b[10]\n                 + ((int128_t)a[10]) * b[ 9]\n                 + ((int128_t)a[11]) * b[ 8]\n                 + ((int128_t)a[12]) * b[ 7];\n    int128_t t20  = ((int128_t)a[ 8]) * b[12]\n                 + ((int128_t)a[ 9]) * b[11]\n                 + ((int128_t)a[10]) * b[10]\n                 + ((int128_t)a[11]) * b[ 9]\n                 + ((int128_t)a[12]) * b[ 8];\n    int128_t t21  = ((int128_t)a[ 9]) * b[12]\n                 + ((int128_t)a[10]) * b[11]\n                 + ((int128_t)a[11]) * b[10]\n                 + ((int128_t)a[12]) * b[ 9];\n    int128_t t22  = ((int128_t)a[10]) * b[12]\n                 + ((int128_t)a[11]) * b[11]\n                 + ((int128_t)a[12]) * b[10];\n    int128_t t23  = ((int128_t)a[11]) * b[12]\n                 + ((int128_t)a[12]) * b[11];\n    int128_t t24  = ((int128_t)a[12]) * b[12];\n\n    t1   += t0  >> 53; r[ 0] = t0  & 0x1fffffffffffffL;\n    t2   += t1  >> 53; r[ 1] = t1  & 0x1fffffffffffffL;\n    t3   += t2  >> 53; r[ 2] = t2  & 0x1fffffffffffffL;\n    t4   += t3  >> 53; r[ 3] = t3  & 0x1fffffffffffffL;\n    t5   += t4  >> 53; r[ 4] = t4  & 0x1fffffffffffffL;\n    t6   += t5  >> 53; r[ 5] = t5  & 0x1fffffffffffffL;\n    t7   += t6  >> 53; r[ 6] = t6  & 0x1fffffffffffffL;\n    t8   += t7  >> 53; r[ 7] = t7  & 0x1fffffffffffffL;\n    t9   += t8  >> 53; r[ 8] = t8  & 0x1fffffffffffffL;\n    t10  += t9  >> 53; r[ 9] = t9  & 0x1fffffffffffffL;\n    t11  += t10 >> 53; r[10] = t10 & 0x1fffffffffffffL;\n    t12  += t11 >> 53; r[11] = t11 & 0x1fffffffffffffL;\n    t13  += t12 >> 53; r[12] = t12 & 0x1fffffffffffffL;\n    t14  += t13 >> 53; r[13] = t13 & 0x1fffffffffffffL;\n    t15  += t14 >> 53; r[14] = t14 & 0x1fffffffffffffL;\n    t16  += t15 >> 53; r[15] = t15 & 0x1fffffffffffffL;\n    t17  += t16 >> 53; r[16] = t16 & 0x1fffffffffffffL;\n    t18  += t17 >> 53; r[17] = t17 & 0x1fffffffffffffL;\n    t19  += t18 >> 53; r[18] = t18 & 0x1fffffffffffffL;\n    t20  += t19 >> 53; r[19] = t19 & 0x1fffffffffffffL;\n    t21  += t20 >> 53; r[20] = t20 & 0x1fffffffffffffL;\n    t22  += t21 >> 53; r[21] = t21 & 0x1fffffffffffffL;\n    t23  += t22 >> 53; r[22] = t22 & 0x1fffffffffffffL;\n    t24  += t23 >> 53; r[23] = t23 & 0x1fffffffffffffL;\n    r[25] = (sp_digit)(t24 >> 53);\n                       r[24] = t24 & 0x1fffffffffffffL;\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_13(sp_digit* r, const sp_digit* a)\n{\n    int128_t t0   =  ((int128_t)a[ 0]) * a[ 0];\n    int128_t t1   = (((int128_t)a[ 0]) * a[ 1]) * 2;\n    int128_t t2   = (((int128_t)a[ 0]) * a[ 2]) * 2\n                 +  ((int128_t)a[ 1]) * a[ 1];\n    int128_t t3   = (((int128_t)a[ 0]) * a[ 3]\n                 +  ((int128_t)a[ 1]) * a[ 2]) * 2;\n    int128_t t4   = (((int128_t)a[ 0]) * a[ 4]\n                 +  ((int128_t)a[ 1]) * a[ 3]) * 2\n                 +  ((int128_t)a[ 2]) * a[ 2];\n    int128_t t5   = (((int128_t)a[ 0]) * a[ 5]\n                 +  ((int128_t)a[ 1]) * a[ 4]\n                 +  ((int128_t)a[ 2]) * a[ 3]) * 2;\n    int128_t t6   = (((int128_t)a[ 0]) * a[ 6]\n                 +  ((int128_t)a[ 1]) * a[ 5]\n                 +  ((int128_t)a[ 2]) * a[ 4]) * 2\n                 +  ((int128_t)a[ 3]) * a[ 3];\n    int128_t t7   = (((int128_t)a[ 0]) * a[ 7]\n                 +  ((int128_t)a[ 1]) * a[ 6]\n                 +  ((int128_t)a[ 2]) * a[ 5]\n                 +  ((int128_t)a[ 3]) * a[ 4]) * 2;\n    int128_t t8   = (((int128_t)a[ 0]) * a[ 8]\n                 +  ((int128_t)a[ 1]) * a[ 7]\n                 +  ((int128_t)a[ 2]) * a[ 6]\n                 +  ((int128_t)a[ 3]) * a[ 5]) * 2\n                 +  ((int128_t)a[ 4]) * a[ 4];\n    int128_t t9   = (((int128_t)a[ 0]) * a[ 9]\n                 +  ((int128_t)a[ 1]) * a[ 8]\n                 +  ((int128_t)a[ 2]) * a[ 7]\n                 +  ((int128_t)a[ 3]) * a[ 6]\n                 +  ((int128_t)a[ 4]) * a[ 5]) * 2;\n    int128_t t10  = (((int128_t)a[ 0]) * a[10]\n                 +  ((int128_t)a[ 1]) * a[ 9]\n                 +  ((int128_t)a[ 2]) * a[ 8]\n                 +  ((int128_t)a[ 3]) * a[ 7]\n                 +  ((int128_t)a[ 4]) * a[ 6]) * 2\n                 +  ((int128_t)a[ 5]) * a[ 5];\n    int128_t t11  = (((int128_t)a[ 0]) * a[11]\n                 +  ((int128_t)a[ 1]) * a[10]\n                 +  ((int128_t)a[ 2]) * a[ 9]\n                 +  ((int128_t)a[ 3]) * a[ 8]\n                 +  ((int128_t)a[ 4]) * a[ 7]\n                 +  ((int128_t)a[ 5]) * a[ 6]) * 2;\n    int128_t t12  = (((int128_t)a[ 0]) * a[12]\n                 +  ((int128_t)a[ 1]) * a[11]\n                 +  ((int128_t)a[ 2]) * a[10]\n                 +  ((int128_t)a[ 3]) * a[ 9]\n                 +  ((int128_t)a[ 4]) * a[ 8]\n                 +  ((int128_t)a[ 5]) * a[ 7]) * 2\n                 +  ((int128_t)a[ 6]) * a[ 6];\n    int128_t t13  = (((int128_t)a[ 1]) * a[12]\n                 +  ((int128_t)a[ 2]) * a[11]\n                 +  ((int128_t)a[ 3]) * a[10]\n                 +  ((int128_t)a[ 4]) * a[ 9]\n                 +  ((int128_t)a[ 5]) * a[ 8]\n                 +  ((int128_t)a[ 6]) * a[ 7]) * 2;\n    int128_t t14  = (((int128_t)a[ 2]) * a[12]\n                 +  ((int128_t)a[ 3]) * a[11]\n                 +  ((int128_t)a[ 4]) * a[10]\n                 +  ((int128_t)a[ 5]) * a[ 9]\n                 +  ((int128_t)a[ 6]) * a[ 8]) * 2\n                 +  ((int128_t)a[ 7]) * a[ 7];\n    int128_t t15  = (((int128_t)a[ 3]) * a[12]\n                 +  ((int128_t)a[ 4]) * a[11]\n                 +  ((int128_t)a[ 5]) * a[10]\n                 +  ((int128_t)a[ 6]) * a[ 9]\n                 +  ((int128_t)a[ 7]) * a[ 8]) * 2;\n    int128_t t16  = (((int128_t)a[ 4]) * a[12]\n                 +  ((int128_t)a[ 5]) * a[11]\n                 +  ((int128_t)a[ 6]) * a[10]\n                 +  ((int128_t)a[ 7]) * a[ 9]) * 2\n                 +  ((int128_t)a[ 8]) * a[ 8];\n    int128_t t17  = (((int128_t)a[ 5]) * a[12]\n                 +  ((int128_t)a[ 6]) * a[11]\n                 +  ((int128_t)a[ 7]) * a[10]\n                 +  ((int128_t)a[ 8]) * a[ 9]) * 2;\n    int128_t t18  = (((int128_t)a[ 6]) * a[12]\n                 +  ((int128_t)a[ 7]) * a[11]\n                 +  ((int128_t)a[ 8]) * a[10]) * 2\n                 +  ((int128_t)a[ 9]) * a[ 9];\n    int128_t t19  = (((int128_t)a[ 7]) * a[12]\n                 +  ((int128_t)a[ 8]) * a[11]\n                 +  ((int128_t)a[ 9]) * a[10]) * 2;\n    int128_t t20  = (((int128_t)a[ 8]) * a[12]\n                 +  ((int128_t)a[ 9]) * a[11]) * 2\n                 +  ((int128_t)a[10]) * a[10];\n    int128_t t21  = (((int128_t)a[ 9]) * a[12]\n                 +  ((int128_t)a[10]) * a[11]) * 2;\n    int128_t t22  = (((int128_t)a[10]) * a[12]) * 2\n                 +  ((int128_t)a[11]) * a[11];\n    int128_t t23  = (((int128_t)a[11]) * a[12]) * 2;\n    int128_t t24  =  ((int128_t)a[12]) * a[12];\n\n    t1   += t0  >> 53; r[ 0] = t0  & 0x1fffffffffffffL;\n    t2   += t1  >> 53; r[ 1] = t1  & 0x1fffffffffffffL;\n    t3   += t2  >> 53; r[ 2] = t2  & 0x1fffffffffffffL;\n    t4   += t3  >> 53; r[ 3] = t3  & 0x1fffffffffffffL;\n    t5   += t4  >> 53; r[ 4] = t4  & 0x1fffffffffffffL;\n    t6   += t5  >> 53; r[ 5] = t5  & 0x1fffffffffffffL;\n    t7   += t6  >> 53; r[ 6] = t6  & 0x1fffffffffffffL;\n    t8   += t7  >> 53; r[ 7] = t7  & 0x1fffffffffffffL;\n    t9   += t8  >> 53; r[ 8] = t8  & 0x1fffffffffffffL;\n    t10  += t9  >> 53; r[ 9] = t9  & 0x1fffffffffffffL;\n    t11  += t10 >> 53; r[10] = t10 & 0x1fffffffffffffL;\n    t12  += t11 >> 53; r[11] = t11 & 0x1fffffffffffffL;\n    t13  += t12 >> 53; r[12] = t12 & 0x1fffffffffffffL;\n    t14  += t13 >> 53; r[13] = t13 & 0x1fffffffffffffL;\n    t15  += t14 >> 53; r[14] = t14 & 0x1fffffffffffffL;\n    t16  += t15 >> 53; r[15] = t15 & 0x1fffffffffffffL;\n    t17  += t16 >> 53; r[16] = t16 & 0x1fffffffffffffL;\n    t18  += t17 >> 53; r[17] = t17 & 0x1fffffffffffffL;\n    t19  += t18 >> 53; r[18] = t18 & 0x1fffffffffffffL;\n    t20  += t19 >> 53; r[19] = t19 & 0x1fffffffffffffL;\n    t21  += t20 >> 53; r[20] = t20 & 0x1fffffffffffffL;\n    t22  += t21 >> 53; r[21] = t21 & 0x1fffffffffffffL;\n    t23  += t22 >> 53; r[22] = t22 & 0x1fffffffffffffL;\n    t24  += t23 >> 53; r[23] = t23 & 0x1fffffffffffffL;\n    r[25] = (sp_digit)(t24 >> 53);\n                       r[24] = t24 & 0x1fffffffffffffL;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_13(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    r[ 0] = a[ 0] + b[ 0];\n    r[ 1] = a[ 1] + b[ 1];\n    r[ 2] = a[ 2] + b[ 2];\n    r[ 3] = a[ 3] + b[ 3];\n    r[ 4] = a[ 4] + b[ 4];\n    r[ 5] = a[ 5] + b[ 5];\n    r[ 6] = a[ 6] + b[ 6];\n    r[ 7] = a[ 7] + b[ 7];\n    r[ 8] = a[ 8] + b[ 8];\n    r[ 9] = a[ 9] + b[ 9];\n    r[10] = a[10] + b[10];\n    r[11] = a[11] + b[11];\n    r[12] = a[12] + b[12];\n\n    return 0;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_sub_26(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[24] = a[24] - b[24];\n    r[25] = a[25] - b[25];\n\n    return 0;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_26(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[24] = a[24] + b[24];\n    r[25] = a[25] + b[25];\n\n    return 0;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_39(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    sp_digit p0[26];\n    sp_digit p1[26];\n    sp_digit p2[26];\n    sp_digit p3[26];\n    sp_digit p4[26];\n    sp_digit p5[26];\n    sp_digit t0[26];\n    sp_digit t1[26];\n    sp_digit t2[26];\n    sp_digit a0[13];\n    sp_digit a1[13];\n    sp_digit a2[13];\n    sp_digit b0[13];\n    sp_digit b1[13];\n    sp_digit b2[13];\n    (void)sp_4096_add_13(a0, a, &a[13]);\n    (void)sp_4096_add_13(b0, b, &b[13]);\n    (void)sp_4096_add_13(a1, &a[13], &a[26]);\n    (void)sp_4096_add_13(b1, &b[13], &b[26]);\n    (void)sp_4096_add_13(a2, a0, &a[26]);\n    (void)sp_4096_add_13(b2, b0, &b[26]);\n    sp_4096_mul_13(p0, a, b);\n    sp_4096_mul_13(p2, &a[13], &b[13]);\n    sp_4096_mul_13(p4, &a[26], &b[26]);\n    sp_4096_mul_13(p1, a0, b0);\n    sp_4096_mul_13(p3, a1, b1);\n    sp_4096_mul_13(p5, a2, b2);\n    XMEMSET(r, 0, sizeof(*r)*2U*39U);\n    (void)sp_4096_sub_26(t0, p3, p2);\n    (void)sp_4096_sub_26(t1, p1, p2);\n    (void)sp_4096_sub_26(t2, p5, t0);\n    (void)sp_4096_sub_26(t2, t2, t1);\n    (void)sp_4096_sub_26(t0, t0, p4);\n    (void)sp_4096_sub_26(t1, t1, p0);\n    (void)sp_4096_add_26(r, r, p0);\n    (void)sp_4096_add_26(&r[13], &r[13], t1);\n    (void)sp_4096_add_26(&r[26], &r[26], t2);\n    (void)sp_4096_add_26(&r[39], &r[39], t0);\n    (void)sp_4096_add_26(&r[52], &r[52], p4);\n}\n\n/* Square a into r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_39(sp_digit* r, const sp_digit* a)\n{\n    sp_digit p0[26];\n    sp_digit p1[26];\n    sp_digit p2[26];\n    sp_digit p3[26];\n    sp_digit p4[26];\n    sp_digit p5[26];\n    sp_digit t0[26];\n    sp_digit t1[26];\n    sp_digit t2[26];\n    sp_digit a0[13];\n    sp_digit a1[13];\n    sp_digit a2[13];\n    (void)sp_4096_add_13(a0, a, &a[13]);\n    (void)sp_4096_add_13(a1, &a[13], &a[26]);\n    (void)sp_4096_add_13(a2, a0, &a[26]);\n    sp_4096_sqr_13(p0, a);\n    sp_4096_sqr_13(p2, &a[13]);\n    sp_4096_sqr_13(p4, &a[26]);\n    sp_4096_sqr_13(p1, a0);\n    sp_4096_sqr_13(p3, a1);\n    sp_4096_sqr_13(p5, a2);\n    XMEMSET(r, 0, sizeof(*r)*2U*39U);\n    (void)sp_4096_sub_26(t0, p3, p2);\n    (void)sp_4096_sub_26(t1, p1, p2);\n    (void)sp_4096_sub_26(t2, p5, t0);\n    (void)sp_4096_sub_26(t2, t2, t1);\n    (void)sp_4096_sub_26(t0, t0, p4);\n    (void)sp_4096_sub_26(t1, t1, p0);\n    (void)sp_4096_add_26(r, r, p0);\n    (void)sp_4096_add_26(&r[13], &r[13], t1);\n    (void)sp_4096_add_26(&r[26], &r[26], t2);\n    (void)sp_4096_add_26(&r[39], &r[39], t0);\n    (void)sp_4096_add_26(&r[52], &r[52], p4);\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_39(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[32] = a[32] + b[32];\n    r[33] = a[33] + b[33];\n    r[34] = a[34] + b[34];\n    r[35] = a[35] + b[35];\n    r[36] = a[36] + b[36];\n    r[37] = a[37] + b[37];\n    r[38] = a[38] + b[38];\n\n    return 0;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_78(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 72; i += 8) {\n        r[i + 0] = a[i + 0] + b[i + 0];\n        r[i + 1] = a[i + 1] + b[i + 1];\n        r[i + 2] = a[i + 2] + b[i + 2];\n        r[i + 3] = a[i + 3] + b[i + 3];\n        r[i + 4] = a[i + 4] + b[i + 4];\n        r[i + 5] = a[i + 5] + b[i + 5];\n        r[i + 6] = a[i + 6] + b[i + 6];\n        r[i + 7] = a[i + 7] + b[i + 7];\n    }\n    r[72] = a[72] + b[72];\n    r[73] = a[73] + b[73];\n    r[74] = a[74] + b[74];\n    r[75] = a[75] + b[75];\n    r[76] = a[76] + b[76];\n    r[77] = a[77] + b[77];\n\n    return 0;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_sub_78(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 72; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[72] = a[72] - b[72];\n    r[73] = a[73] - b[73];\n    r[74] = a[74] - b[74];\n    r[75] = a[75] - b[75];\n    r[76] = a[76] - b[76];\n    r[77] = a[77] - b[77];\n\n    return 0;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_78(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[78];\n    sp_digit* a1 = z1;\n    sp_digit b1[39];\n    sp_digit* z2 = r + 78;\n    (void)sp_4096_add_39(a1, a, &a[39]);\n    (void)sp_4096_add_39(b1, b, &b[39]);\n    sp_4096_mul_39(z2, &a[39], &b[39]);\n    sp_4096_mul_39(z0, a, b);\n    sp_4096_mul_39(z1, a1, b1);\n    (void)sp_4096_sub_78(z1, z1, z2);\n    (void)sp_4096_sub_78(z1, z1, z0);\n    (void)sp_4096_add_78(r + 39, r + 39, z1);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_78(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[78];\n    sp_digit* a1 = z1;\n    sp_digit* z2 = r + 78;\n    (void)sp_4096_add_39(a1, a, &a[39]);\n    sp_4096_sqr_39(z2, &a[39]);\n    sp_4096_sqr_39(z0, a);\n    sp_4096_sqr_39(z1, a1);\n    (void)sp_4096_sub_78(z1, z1, z2);\n    (void)sp_4096_sub_78(z1, z1, z0);\n    (void)sp_4096_add_78(r + 39, r + 39, z1);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_78(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 78; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_sub_78(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 78; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_78(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[77]) * b[77];\n    r[155] = (sp_digit)(c >> 53);\n    c = (c & 0x1fffffffffffffL) << 53;\n    for (k = 153; k >= 0; k--) {\n        for (i = 77; i >= 0; i--) {\n            j = k - i;\n            if (j >= 78) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 106;\n        r[k + 1] = (c >> 53) & 0x1fffffffffffffL;\n        c = (c & 0x1fffffffffffffL) << 53;\n    }\n    r[0] = (sp_digit)(c >> 53);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_78(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[77]) * a[77];\n    r[155] = (sp_digit)(c >> 53);\n    c = (c & 0x1fffffffffffffL) << 53;\n    for (k = 153; k >= 0; k--) {\n        for (i = 77; i >= 0; i--) {\n            j = k - i;\n            if (j >= 78 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int128_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 106;\n        r[k + 1] = (c >> 53) & 0x1fffffffffffffL;\n        c = (c & 0x1fffffffffffffL) << 53;\n    }\n    r[0] = (sp_digit)(c >> 53);\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_39(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 39; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_sub_39(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 39; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#else\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_sub_39(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i + 0] = a[i + 0] - b[i + 0];\n        r[i + 1] = a[i + 1] - b[i + 1];\n        r[i + 2] = a[i + 2] - b[i + 2];\n        r[i + 3] = a[i + 3] - b[i + 3];\n        r[i + 4] = a[i + 4] - b[i + 4];\n        r[i + 5] = a[i + 5] - b[i + 5];\n        r[i + 6] = a[i + 6] - b[i + 6];\n        r[i + 7] = a[i + 7] - b[i + 7];\n    }\n    r[32] = a[32] - b[32];\n    r[33] = a[33] - b[33];\n    r[34] = a[34] - b[34];\n    r[35] = a[35] - b[35];\n    r[36] = a[36] - b[36];\n    r[37] = a[37] - b[37];\n    r[38] = a[38] - b[38];\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_39(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[38]) * b[38];\n    r[77] = (sp_digit)(c >> 53);\n    c = (c & 0x1fffffffffffffL) << 53;\n    for (k = 75; k >= 0; k--) {\n        for (i = 38; i >= 0; i--) {\n            j = k - i;\n            if (j >= 39) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 106;\n        r[k + 1] = (c >> 53) & 0x1fffffffffffffL;\n        c = (c & 0x1fffffffffffffL) << 53;\n    }\n    r[0] = (sp_digit)(c >> 53);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_39(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[38]) * a[38];\n    r[77] = (sp_digit)(c >> 53);\n    c = (c & 0x1fffffffffffffL) << 53;\n    for (k = 75; k >= 0; k--) {\n        for (i = 38; i >= 0; i--) {\n            j = k - i;\n            if (j >= 39 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int128_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 106;\n        r[k + 1] = (c >> 53) & 0x1fffffffffffffL;\n        c = (c & 0x1fffffffffffffL) << 53;\n    }\n    r[0] = (sp_digit)(c >> 53);\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**64 */\n    x &= 0x1fffffffffffffL;\n\n    /* rho = -1/m mod b */\n    *rho = (1L << 53) - x;\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_4096_mul_d_78(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 78; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x1fffffffffffffL;\n        t >>= 53;\n    }\n    r[78] = (sp_digit)t;\n#else\n    int128_t tb = b;\n    int128_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x1fffffffffffffL;\n    for (i = 0; i < 72; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 53) + (t[1] & 0x1fffffffffffffL);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 53) + (t[2] & 0x1fffffffffffffL);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 53) + (t[3] & 0x1fffffffffffffL);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 53) + (t[4] & 0x1fffffffffffffL);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 53) + (t[5] & 0x1fffffffffffffL);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 53) + (t[6] & 0x1fffffffffffffL);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 53) + (t[7] & 0x1fffffffffffffL);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 53) + (t[0] & 0x1fffffffffffffL);\n    }\n    t[1] = tb * a[73];\n    r[73] = (sp_digit)(t[0] >> 53) + (t[1] & 0x1fffffffffffffL);\n    t[2] = tb * a[74];\n    r[74] = (sp_digit)(t[1] >> 53) + (t[2] & 0x1fffffffffffffL);\n    t[3] = tb * a[75];\n    r[75] = (sp_digit)(t[2] >> 53) + (t[3] & 0x1fffffffffffffL);\n    t[4] = tb * a[76];\n    r[76] = (sp_digit)(t[3] >> 53) + (t[4] & 0x1fffffffffffffL);\n    t[5] = tb * a[77];\n    r[77] = (sp_digit)(t[4] >> 53) + (t[5] & 0x1fffffffffffffL);\n    r[78] =  (sp_digit)(t[5] >> 53);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 4096 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_4096_mont_norm_39(sp_digit* r, const sp_digit* m)\n{\n    /* Set r = 2^n - 1. */\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<38; i++) {\n        r[i] = 0x1fffffffffffffL;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i + 0] = 0x1fffffffffffffL;\n        r[i + 1] = 0x1fffffffffffffL;\n        r[i + 2] = 0x1fffffffffffffL;\n        r[i + 3] = 0x1fffffffffffffL;\n        r[i + 4] = 0x1fffffffffffffL;\n        r[i + 5] = 0x1fffffffffffffL;\n        r[i + 6] = 0x1fffffffffffffL;\n        r[i + 7] = 0x1fffffffffffffL;\n    }\n    r[32] = 0x1fffffffffffffL;\n    r[33] = 0x1fffffffffffffL;\n    r[34] = 0x1fffffffffffffL;\n    r[35] = 0x1fffffffffffffL;\n    r[36] = 0x1fffffffffffffL;\n    r[37] = 0x1fffffffffffffL;\n#endif\n    r[38] = 0x3ffffffffL;\n\n    /* r = (2^n - 1) mod n */\n    (void)sp_4096_sub_39(r, r, m);\n\n    /* Add one so r = 2^n mod m */\n    r[0] += 1;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_4096_cmp_39(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=38; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    int i;\n\n    r |= (a[38] - b[38]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[37] - b[37]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[36] - b[36]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[35] - b[35]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[34] - b[34]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[33] - b[33]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[32] - b[32]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    for (i = 24; i >= 0; i -= 8) {\n        r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_4096_cond_sub_39(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 39; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i + 0] = a[i + 0] - (b[i + 0] & m);\n        r[i + 1] = a[i + 1] - (b[i + 1] & m);\n        r[i + 2] = a[i + 2] - (b[i + 2] & m);\n        r[i + 3] = a[i + 3] - (b[i + 3] & m);\n        r[i + 4] = a[i + 4] - (b[i + 4] & m);\n        r[i + 5] = a[i + 5] - (b[i + 5] & m);\n        r[i + 6] = a[i + 6] - (b[i + 6] & m);\n        r[i + 7] = a[i + 7] - (b[i + 7] & m);\n    }\n    r[32] = a[32] - (b[32] & m);\n    r[33] = a[33] - (b[33] & m);\n    r[34] = a[34] - (b[34] & m);\n    r[35] = a[35] - (b[35] & m);\n    r[36] = a[36] - (b[36] & m);\n    r[37] = a[37] - (b[37] & m);\n    r[38] = a[38] - (b[38] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_4096_mul_add_39(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 39; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0x1fffffffffffffL;\n        t >>= 53;\n    }\n    r[39] += t;\n#else\n    int128_t tb = b;\n    int128_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1fffffffffffffL);\n    for (i = 0; i < 32; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] += (sp_digit)((t[0] >> 53) + (t[1] & 0x1fffffffffffffL));\n        t[2] = tb * a[i+2];\n        r[i+2] += (sp_digit)((t[1] >> 53) + (t[2] & 0x1fffffffffffffL));\n        t[3] = tb * a[i+3];\n        r[i+3] += (sp_digit)((t[2] >> 53) + (t[3] & 0x1fffffffffffffL));\n        t[4] = tb * a[i+4];\n        r[i+4] += (sp_digit)((t[3] >> 53) + (t[4] & 0x1fffffffffffffL));\n        t[5] = tb * a[i+5];\n        r[i+5] += (sp_digit)((t[4] >> 53) + (t[5] & 0x1fffffffffffffL));\n        t[6] = tb * a[i+6];\n        r[i+6] += (sp_digit)((t[5] >> 53) + (t[6] & 0x1fffffffffffffL));\n        t[7] = tb * a[i+7];\n        r[i+7] += (sp_digit)((t[6] >> 53) + (t[7] & 0x1fffffffffffffL));\n        t[0] = tb * a[i+8];\n        r[i+8] += (sp_digit)((t[7] >> 53) + (t[0] & 0x1fffffffffffffL));\n    }\n    t[1] = tb * a[33]; r[33] += (sp_digit)((t[0] >> 53) + (t[1] & 0x1fffffffffffffL));\n    t[2] = tb * a[34]; r[34] += (sp_digit)((t[1] >> 53) + (t[2] & 0x1fffffffffffffL));\n    t[3] = tb * a[35]; r[35] += (sp_digit)((t[2] >> 53) + (t[3] & 0x1fffffffffffffL));\n    t[4] = tb * a[36]; r[36] += (sp_digit)((t[3] >> 53) + (t[4] & 0x1fffffffffffffL));\n    t[5] = tb * a[37]; r[37] += (sp_digit)((t[4] >> 53) + (t[5] & 0x1fffffffffffffL));\n    t[6] = tb * a[38]; r[38] += (sp_digit)((t[5] >> 53) + (t[6] & 0x1fffffffffffffL));\n    r[39] +=  (sp_digit)(t[6] >> 53);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Normalize the values in each word to 53.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_4096_norm_39(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 38; i++) {\n        a[i+1] += a[i] >> 53;\n        a[i] &= 0x1fffffffffffffL;\n    }\n#else\n    int i;\n    for (i = 0; i < 32; i += 8) {\n        a[i+1] += a[i+0] >> 53; a[i+0] &= 0x1fffffffffffffL;\n        a[i+2] += a[i+1] >> 53; a[i+1] &= 0x1fffffffffffffL;\n        a[i+3] += a[i+2] >> 53; a[i+2] &= 0x1fffffffffffffL;\n        a[i+4] += a[i+3] >> 53; a[i+3] &= 0x1fffffffffffffL;\n        a[i+5] += a[i+4] >> 53; a[i+4] &= 0x1fffffffffffffL;\n        a[i+6] += a[i+5] >> 53; a[i+5] &= 0x1fffffffffffffL;\n        a[i+7] += a[i+6] >> 53; a[i+6] &= 0x1fffffffffffffL;\n        a[i+8] += a[i+7] >> 53; a[i+7] &= 0x1fffffffffffffL;\n        a[i+9] += a[i+8] >> 53; a[i+8] &= 0x1fffffffffffffL;\n    }\n    a[32+1] += a[32] >> 53;\n    a[32] &= 0x1fffffffffffffL;\n    a[33+1] += a[33] >> 53;\n    a[33] &= 0x1fffffffffffffL;\n    a[34+1] += a[34] >> 53;\n    a[34] &= 0x1fffffffffffffL;\n    a[35+1] += a[35] >> 53;\n    a[35] &= 0x1fffffffffffffL;\n    a[36+1] += a[36] >> 53;\n    a[36] &= 0x1fffffffffffffL;\n    a[37+1] += a[37] >> 53;\n    a[37] &= 0x1fffffffffffffL;\n#endif\n}\n\n/* Shift the result in the high 2048 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_4096_mont_shift_39(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    int128_t n = a[38] >> 34;\n    n += ((int128_t)a[39]) << 19;\n\n    for (i = 0; i < 38; i++) {\n        r[i] = n & 0x1fffffffffffffL;\n        n >>= 53;\n        n += ((int128_t)a[40 + i]) << 19;\n    }\n    r[38] = (sp_digit)n;\n#else\n    int i;\n    int128_t n = a[38] >> 34;\n    n += ((int128_t)a[39]) << 19;\n    for (i = 0; i < 32; i += 8) {\n        r[i + 0] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 40]) << 19;\n        r[i + 1] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 41]) << 19;\n        r[i + 2] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 42]) << 19;\n        r[i + 3] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 43]) << 19;\n        r[i + 4] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 44]) << 19;\n        r[i + 5] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 45]) << 19;\n        r[i + 6] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 46]) << 19;\n        r[i + 7] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 47]) << 19;\n    }\n    r[32] = n & 0x1fffffffffffffL; n >>= 53; n += ((int128_t)a[72]) << 19;\n    r[33] = n & 0x1fffffffffffffL; n >>= 53; n += ((int128_t)a[73]) << 19;\n    r[34] = n & 0x1fffffffffffffL; n >>= 53; n += ((int128_t)a[74]) << 19;\n    r[35] = n & 0x1fffffffffffffL; n >>= 53; n += ((int128_t)a[75]) << 19;\n    r[36] = n & 0x1fffffffffffffL; n >>= 53; n += ((int128_t)a[76]) << 19;\n    r[37] = n & 0x1fffffffffffffL; n >>= 53; n += ((int128_t)a[77]) << 19;\n    r[38] = (sp_digit)n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[39], 0, sizeof(*r) * 39U);\n}\n\n/* Reduce the number back to 4096 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_4096_mont_reduce_39(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    sp_4096_norm_39(a + 39);\n\n    for (i=0; i<38; i++) {\n        mu = (a[i] * mp) & 0x1fffffffffffffL;\n        sp_4096_mul_add_39(a+i, m, mu);\n        a[i+1] += a[i] >> 53;\n    }\n    mu = (a[i] * mp) & 0x3ffffffffL;\n    sp_4096_mul_add_39(a+i, m, mu);\n    a[i+1] += a[i] >> 53;\n    a[i] &= 0x1fffffffffffffL;\n\n    sp_4096_mont_shift_39(a, a);\n    sp_4096_cond_sub_39(a, a, m, 0 - (((a[38] >> 34) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_4096_norm_39(a);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_mul_39(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_4096_mul_39(r, a, b);\n    sp_4096_mont_reduce_39(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_sqr_39(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_4096_sqr_39(r, a);\n    sp_4096_mont_reduce_39(r, m, mp);\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_4096_mul_d_39(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 39; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x1fffffffffffffL;\n        t >>= 53;\n    }\n    r[39] = (sp_digit)t;\n#else\n    int128_t tb = b;\n    int128_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x1fffffffffffffL;\n    for (i = 0; i < 32; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 53) + (t[1] & 0x1fffffffffffffL);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 53) + (t[2] & 0x1fffffffffffffL);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 53) + (t[3] & 0x1fffffffffffffL);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 53) + (t[4] & 0x1fffffffffffffL);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 53) + (t[5] & 0x1fffffffffffffL);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 53) + (t[6] & 0x1fffffffffffffL);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 53) + (t[7] & 0x1fffffffffffffL);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 53) + (t[0] & 0x1fffffffffffffL);\n    }\n    t[1] = tb * a[33];\n    r[33] = (sp_digit)(t[0] >> 53) + (t[1] & 0x1fffffffffffffL);\n    t[2] = tb * a[34];\n    r[34] = (sp_digit)(t[1] >> 53) + (t[2] & 0x1fffffffffffffL);\n    t[3] = tb * a[35];\n    r[35] = (sp_digit)(t[2] >> 53) + (t[3] & 0x1fffffffffffffL);\n    t[4] = tb * a[36];\n    r[36] = (sp_digit)(t[3] >> 53) + (t[4] & 0x1fffffffffffffL);\n    t[5] = tb * a[37];\n    r[37] = (sp_digit)(t[4] >> 53) + (t[5] & 0x1fffffffffffffL);\n    t[6] = tb * a[38];\n    r[38] = (sp_digit)(t[5] >> 53) + (t[6] & 0x1fffffffffffffL);\n    r[39] =  (sp_digit)(t[6] >> 53);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_4096_cond_add_39(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 39; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i + 0] = a[i + 0] + (b[i + 0] & m);\n        r[i + 1] = a[i + 1] + (b[i + 1] & m);\n        r[i + 2] = a[i + 2] + (b[i + 2] & m);\n        r[i + 3] = a[i + 3] + (b[i + 3] & m);\n        r[i + 4] = a[i + 4] + (b[i + 4] & m);\n        r[i + 5] = a[i + 5] + (b[i + 5] & m);\n        r[i + 6] = a[i + 6] + (b[i + 6] & m);\n        r[i + 7] = a[i + 7] + (b[i + 7] & m);\n    }\n    r[32] = a[32] + (b[32] & m);\n    r[33] = a[33] + (b[33] & m);\n    r[34] = a[34] + (b[34] & m);\n    r[35] = a[35] + (b[35] & m);\n    r[36] = a[36] + (b[36] & m);\n    r[37] = a[37] + (b[37] & m);\n    r[38] = a[38] + (b[38] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_39(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 39; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif\nSP_NOINLINE static void sp_4096_rshift_39(sp_digit* r, sp_digit* a, byte n)\n{\n    int i;\n\n#ifdef WOLFSSL_SP_SMALL\n    for (i=0; i<38; i++) {\n        r[i] = ((a[i] >> n) | (a[i + 1] << (53 - n))) & 0x1fffffffffffffL;\n    }\n#else\n    for (i=0; i<32; i += 8) {\n        r[i+0] = ((a[i+0] >> n) | (a[i+1] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+1] = ((a[i+1] >> n) | (a[i+2] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+2] = ((a[i+2] >> n) | (a[i+3] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+3] = ((a[i+3] >> n) | (a[i+4] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+4] = ((a[i+4] >> n) | (a[i+5] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+5] = ((a[i+5] >> n) | (a[i+6] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+6] = ((a[i+6] >> n) | (a[i+7] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+7] = ((a[i+7] >> n) | (a[i+8] << (53 - n))) & 0x1fffffffffffffL;\n    }\n    r[32] = ((a[32] >> n) | (a[33] << (53 - n))) & 0x1fffffffffffffL;\n    r[33] = ((a[33] >> n) | (a[34] << (53 - n))) & 0x1fffffffffffffL;\n    r[34] = ((a[34] >> n) | (a[35] << (53 - n))) & 0x1fffffffffffffL;\n    r[35] = ((a[35] >> n) | (a[36] << (53 - n))) & 0x1fffffffffffffL;\n    r[36] = ((a[36] >> n) | (a[37] << (53 - n))) & 0x1fffffffffffffL;\n    r[37] = ((a[37] >> n) | (a[38] << (53 - n))) & 0x1fffffffffffffL;\n#endif\n    r[38] = a[38] >> n;\n}\n\n#ifdef WOLFSSL_SP_DIV_64\nstatic WC_INLINE sp_digit sp_4096_div_word_39(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t, dv;\n    int128_t t0, t1;\n\n    /* dv has 27 bits. */\n    dv = (div >> 26) + 1;\n    /* All 53 bits from d1 and top 10 bits from d0. */\n    d = (d1 << 10) | (d0 >> 43);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 36 bits in r */\n    /* Next 17 bits from d0. */\n    d <<= 17;\n    r <<= 17;\n    d |= (d0 >> 26) & ((1 << 17) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 53 bits in r */\n\n    /* Handle rounding error with dv - top part */\n    t0 = ((int128_t)d1 << 53) + d0;\n    t1 = (int128_t)r * dv;\n    t1 = t0 - t1;\n    t = (sp_digit)(t1 >> 26) / dv;\n    r += t;\n\n    /* Handle rounding error with dv - bottom 64 bits */\n    t1 = (sp_digit)t0 - (r * dv);\n    t = (sp_digit)t1 / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_64 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_4096_div_39(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_64\n    int128_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[78 + 1], t2d[39 + 1], sdd[39 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    sp_digit* sd;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 39 + 3), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    (void)m;\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 78 + 1;\n        sd = t2 + 39 + 1;\n#else\n        t1 = t1d;\n        t2 = t2d;\n        sd = sdd;\n#endif\n\n        sp_4096_mul_d_39(sd, d, 1L << 19);\n        sp_4096_mul_d_78(t1, a, 1L << 19);\n        dv = sd[38];\n        for (i=39; i>=0; i--) {\n            t1[39 + i] += t1[39 + i - 1] >> 53;\n            t1[39 + i - 1] &= 0x1fffffffffffffL;\n#ifndef WOLFSSL_SP_DIV_64\n            d1 = t1[39 + i];\n            d1 <<= 53;\n            d1 += t1[39 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_4096_div_word_39(t1[39 + i], t1[39 + i - 1], dv);\n#endif\n\n            sp_4096_mul_d_39(t2, sd, r1);\n            (void)sp_4096_sub_39(&t1[i], &t1[i], t2);\n            t1[39 + i] -= t2[39];\n            t1[39 + i] += t1[39 + i - 1] >> 53;\n            t1[39 + i - 1] &= 0x1fffffffffffffL;\n            r1 = (((-t1[39 + i]) << 53) - t1[39 + i - 1]) / dv;\n            r1 -= t1[39 + i];\n            sp_4096_mul_d_39(t2, sd, r1);\n            (void)sp_4096_add_39(&t1[i], &t1[i], t2);\n            t1[39 + i] += t1[39 + i - 1] >> 53;\n            t1[39 + i - 1] &= 0x1fffffffffffffL;\n        }\n        t1[39 - 1] += t1[39 - 2] >> 53;\n        t1[39 - 2] &= 0x1fffffffffffffL;\n        d1 = t1[39 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_4096_mul_d_39(t2, sd, r1);\n        sp_4096_sub_39(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 39U);\n        for (i=0; i<37; i++) {\n            r[i+1] += r[i] >> 53;\n            r[i] &= 0x1fffffffffffffL;\n        }\n        sp_4096_cond_add_39(r, r, sd, 0 - ((r[38] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n\n        sp_4096_norm_39(r);\n        sp_4096_rshift_39(r, r, 19);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_4096_mod_39(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_39(a, m, NULL, r);\n}\n\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, const sp_digit* e, int bits,\n    const sp_digit* m, int reduceA)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* td;\n    sp_digit* t[3];\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 39 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3U * 39U * 2U);\n\n        norm = t[0] = td;\n        t[1] = &td[39 * 2];\n        t[2] = &td[2 * 39 * 2];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_39(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_4096_mod_39(t[1], a, m);\n        }\n        else {\n            XMEMCPY(t[1], a, sizeof(sp_digit) * 39U);\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_4096_mul_39(t[1], t[1], norm);\n        err = sp_4096_mod_39(t[1], t[1], m);\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 53;\n        c = bits % 53;\n        n = e[i--] << (53 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 53;\n            }\n\n            y = (n >> 52) & 1;\n            n <<= 1;\n\n            sp_4096_mont_mul_39(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(*t[2]) * 39 * 2);\n            sp_4096_mont_sqr_39(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(*t[2]) * 39 * 2);\n        }\n\n        sp_4096_mont_reduce_39(t[0], m, mp);\n        n = sp_4096_cmp_39(t[0], m);\n        sp_4096_cond_sub_39(t[0], t[0], m, ((n < 0) ?\n                    (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(*r) * 39 * 2);\n\n    }\n\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    return err;\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[3][78];\n#else\n    sp_digit* td;\n    sp_digit* t[3];\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 39 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        t[0] = td;\n        t[1] = &td[39 * 2];\n        t[2] = &td[2 * 39 * 2];\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_39(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_4096_mod_39(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_4096_mul_39(t[1], t[1], norm);\n                err = sp_4096_mod_39(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_4096_mul_39(t[1], a, norm);\n            err = sp_4096_mod_39(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 53;\n        c = bits % 53;\n        n = e[i--] << (53 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 53;\n            }\n\n            y = (n >> 52) & 1;\n            n <<= 1;\n\n            sp_4096_mont_mul_39(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_4096_mont_sqr_39(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                           ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));\n        }\n\n        sp_4096_mont_reduce_39(t[0], m, mp);\n        n = sp_4096_cmp_39(t[0], m);\n        sp_4096_cond_sub_39(t[0], t[0], m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(t[0]));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][78];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit rt[78];\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 78, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 78;\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_39(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_4096_mod_39(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_4096_mul_39(t[1], t[1], norm);\n                err = sp_4096_mod_39(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_4096_mul_39(t[1], a, norm);\n            err = sp_4096_mod_39(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_39(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_39(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_39(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_39(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_39(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_39(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_39(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_39(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_39(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_39(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_39(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_39(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_39(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_39(t[15], t[ 8], t[ 7], m, mp);\n        sp_4096_mont_sqr_39(t[16], t[ 8], m, mp);\n        sp_4096_mont_mul_39(t[17], t[ 9], t[ 8], m, mp);\n        sp_4096_mont_sqr_39(t[18], t[ 9], m, mp);\n        sp_4096_mont_mul_39(t[19], t[10], t[ 9], m, mp);\n        sp_4096_mont_sqr_39(t[20], t[10], m, mp);\n        sp_4096_mont_mul_39(t[21], t[11], t[10], m, mp);\n        sp_4096_mont_sqr_39(t[22], t[11], m, mp);\n        sp_4096_mont_mul_39(t[23], t[12], t[11], m, mp);\n        sp_4096_mont_sqr_39(t[24], t[12], m, mp);\n        sp_4096_mont_mul_39(t[25], t[13], t[12], m, mp);\n        sp_4096_mont_sqr_39(t[26], t[13], m, mp);\n        sp_4096_mont_mul_39(t[27], t[14], t[13], m, mp);\n        sp_4096_mont_sqr_39(t[28], t[14], m, mp);\n        sp_4096_mont_mul_39(t[29], t[15], t[14], m, mp);\n        sp_4096_mont_sqr_39(t[30], t[15], m, mp);\n        sp_4096_mont_mul_39(t[31], t[16], t[15], m, mp);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 52) / 53) - 1;\n        c = bits % 53;\n        if (c == 0) {\n            c = 53;\n        }\n        if (i < 39) {\n            n = e[i--] << (64 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (11 - c);\n            c += 53;\n        }\n        y = (n >> 59) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        XMEMCPY(rt, t[y], sizeof(rt));\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (11 - c);\n                c += 53;\n            }\n            y = (n >> 59) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_4096_mont_sqr_39(rt, rt, m, mp);\n            sp_4096_mont_sqr_39(rt, rt, m, mp);\n            sp_4096_mont_sqr_39(rt, rt, m, mp);\n            sp_4096_mont_sqr_39(rt, rt, m, mp);\n            sp_4096_mont_sqr_39(rt, rt, m, mp);\n\n            sp_4096_mont_mul_39(rt, rt, t[y], m, mp);\n        }\n\n        sp_4096_mont_reduce_39(rt, m, mp);\n        n = sp_4096_cmp_39(rt, m);\n        sp_4096_cond_sub_39(rt, rt, m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, rt, sizeof(rt));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#endif\n}\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 4096 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_4096_mont_norm_78(sp_digit* r, const sp_digit* m)\n{\n    /* Set r = 2^n - 1. */\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<77; i++) {\n        r[i] = 0x1fffffffffffffL;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 72; i += 8) {\n        r[i + 0] = 0x1fffffffffffffL;\n        r[i + 1] = 0x1fffffffffffffL;\n        r[i + 2] = 0x1fffffffffffffL;\n        r[i + 3] = 0x1fffffffffffffL;\n        r[i + 4] = 0x1fffffffffffffL;\n        r[i + 5] = 0x1fffffffffffffL;\n        r[i + 6] = 0x1fffffffffffffL;\n        r[i + 7] = 0x1fffffffffffffL;\n    }\n    r[72] = 0x1fffffffffffffL;\n    r[73] = 0x1fffffffffffffL;\n    r[74] = 0x1fffffffffffffL;\n    r[75] = 0x1fffffffffffffL;\n    r[76] = 0x1fffffffffffffL;\n#endif\n    r[77] = 0x7fffL;\n\n    /* r = (2^n - 1) mod n */\n    (void)sp_4096_sub_78(r, r, m);\n\n    /* Add one so r = 2^n mod m */\n    r[0] += 1;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_4096_cmp_78(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=77; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    int i;\n\n    r |= (a[77] - b[77]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[76] - b[76]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[75] - b[75]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[74] - b[74]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[73] - b[73]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[72] - b[72]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    for (i = 64; i >= 0; i -= 8) {\n        r |= (a[i + 7] - b[i + 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 6] - b[i + 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 5] - b[i + 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 4] - b[i + 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 3] - b[i + 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 2] - b[i + 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 1] - b[i + 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n        r |= (a[i + 0] - b[i + 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_4096_cond_sub_78(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 78; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 72; i += 8) {\n        r[i + 0] = a[i + 0] - (b[i + 0] & m);\n        r[i + 1] = a[i + 1] - (b[i + 1] & m);\n        r[i + 2] = a[i + 2] - (b[i + 2] & m);\n        r[i + 3] = a[i + 3] - (b[i + 3] & m);\n        r[i + 4] = a[i + 4] - (b[i + 4] & m);\n        r[i + 5] = a[i + 5] - (b[i + 5] & m);\n        r[i + 6] = a[i + 6] - (b[i + 6] & m);\n        r[i + 7] = a[i + 7] - (b[i + 7] & m);\n    }\n    r[72] = a[72] - (b[72] & m);\n    r[73] = a[73] - (b[73] & m);\n    r[74] = a[74] - (b[74] & m);\n    r[75] = a[75] - (b[75] & m);\n    r[76] = a[76] - (b[76] & m);\n    r[77] = a[77] - (b[77] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_4096_mul_add_78(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 78; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0x1fffffffffffffL;\n        t >>= 53;\n    }\n    r[78] += t;\n#else\n    int128_t tb = b;\n    int128_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] += (sp_digit)(t[0] & 0x1fffffffffffffL);\n    for (i = 0; i < 72; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] += (sp_digit)((t[0] >> 53) + (t[1] & 0x1fffffffffffffL));\n        t[2] = tb * a[i+2];\n        r[i+2] += (sp_digit)((t[1] >> 53) + (t[2] & 0x1fffffffffffffL));\n        t[3] = tb * a[i+3];\n        r[i+3] += (sp_digit)((t[2] >> 53) + (t[3] & 0x1fffffffffffffL));\n        t[4] = tb * a[i+4];\n        r[i+4] += (sp_digit)((t[3] >> 53) + (t[4] & 0x1fffffffffffffL));\n        t[5] = tb * a[i+5];\n        r[i+5] += (sp_digit)((t[4] >> 53) + (t[5] & 0x1fffffffffffffL));\n        t[6] = tb * a[i+6];\n        r[i+6] += (sp_digit)((t[5] >> 53) + (t[6] & 0x1fffffffffffffL));\n        t[7] = tb * a[i+7];\n        r[i+7] += (sp_digit)((t[6] >> 53) + (t[7] & 0x1fffffffffffffL));\n        t[0] = tb * a[i+8];\n        r[i+8] += (sp_digit)((t[7] >> 53) + (t[0] & 0x1fffffffffffffL));\n    }\n    t[1] = tb * a[73]; r[73] += (sp_digit)((t[0] >> 53) + (t[1] & 0x1fffffffffffffL));\n    t[2] = tb * a[74]; r[74] += (sp_digit)((t[1] >> 53) + (t[2] & 0x1fffffffffffffL));\n    t[3] = tb * a[75]; r[75] += (sp_digit)((t[2] >> 53) + (t[3] & 0x1fffffffffffffL));\n    t[4] = tb * a[76]; r[76] += (sp_digit)((t[3] >> 53) + (t[4] & 0x1fffffffffffffL));\n    t[5] = tb * a[77]; r[77] += (sp_digit)((t[4] >> 53) + (t[5] & 0x1fffffffffffffL));\n    r[78] +=  (sp_digit)(t[5] >> 53);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Normalize the values in each word to 53.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_4096_norm_78(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 77; i++) {\n        a[i+1] += a[i] >> 53;\n        a[i] &= 0x1fffffffffffffL;\n    }\n#else\n    int i;\n    for (i = 0; i < 72; i += 8) {\n        a[i+1] += a[i+0] >> 53; a[i+0] &= 0x1fffffffffffffL;\n        a[i+2] += a[i+1] >> 53; a[i+1] &= 0x1fffffffffffffL;\n        a[i+3] += a[i+2] >> 53; a[i+2] &= 0x1fffffffffffffL;\n        a[i+4] += a[i+3] >> 53; a[i+3] &= 0x1fffffffffffffL;\n        a[i+5] += a[i+4] >> 53; a[i+4] &= 0x1fffffffffffffL;\n        a[i+6] += a[i+5] >> 53; a[i+5] &= 0x1fffffffffffffL;\n        a[i+7] += a[i+6] >> 53; a[i+6] &= 0x1fffffffffffffL;\n        a[i+8] += a[i+7] >> 53; a[i+7] &= 0x1fffffffffffffL;\n        a[i+9] += a[i+8] >> 53; a[i+8] &= 0x1fffffffffffffL;\n    }\n    a[72+1] += a[72] >> 53;\n    a[72] &= 0x1fffffffffffffL;\n    a[73+1] += a[73] >> 53;\n    a[73] &= 0x1fffffffffffffL;\n    a[74+1] += a[74] >> 53;\n    a[74] &= 0x1fffffffffffffL;\n    a[75+1] += a[75] >> 53;\n    a[75] &= 0x1fffffffffffffL;\n    a[76+1] += a[76] >> 53;\n    a[76] &= 0x1fffffffffffffL;\n#endif\n}\n\n/* Shift the result in the high 4096 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_4096_mont_shift_78(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    int128_t n = a[77] >> 15;\n    n += ((int128_t)a[78]) << 38;\n\n    for (i = 0; i < 77; i++) {\n        r[i] = n & 0x1fffffffffffffL;\n        n >>= 53;\n        n += ((int128_t)a[79 + i]) << 38;\n    }\n    r[77] = (sp_digit)n;\n#else\n    int i;\n    int128_t n = a[77] >> 15;\n    n += ((int128_t)a[78]) << 38;\n    for (i = 0; i < 72; i += 8) {\n        r[i + 0] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 79]) << 38;\n        r[i + 1] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 80]) << 38;\n        r[i + 2] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 81]) << 38;\n        r[i + 3] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 82]) << 38;\n        r[i + 4] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 83]) << 38;\n        r[i + 5] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 84]) << 38;\n        r[i + 6] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 85]) << 38;\n        r[i + 7] = n & 0x1fffffffffffffL;\n        n >>= 53; n += ((int128_t)a[i + 86]) << 38;\n    }\n    r[72] = n & 0x1fffffffffffffL; n >>= 53; n += ((int128_t)a[151]) << 38;\n    r[73] = n & 0x1fffffffffffffL; n >>= 53; n += ((int128_t)a[152]) << 38;\n    r[74] = n & 0x1fffffffffffffL; n >>= 53; n += ((int128_t)a[153]) << 38;\n    r[75] = n & 0x1fffffffffffffL; n >>= 53; n += ((int128_t)a[154]) << 38;\n    r[76] = n & 0x1fffffffffffffL; n >>= 53; n += ((int128_t)a[155]) << 38;\n    r[77] = (sp_digit)n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[78], 0, sizeof(*r) * 78U);\n}\n\n/* Reduce the number back to 4096 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_4096_mont_reduce_78(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    sp_4096_norm_78(a + 78);\n\n#ifdef WOLFSSL_SP_DH\n    if (mp != 1) {\n        for (i=0; i<77; i++) {\n            mu = (a[i] * mp) & 0x1fffffffffffffL;\n            sp_4096_mul_add_78(a+i, m, mu);\n            a[i+1] += a[i] >> 53;\n        }\n        mu = (a[i] * mp) & 0x7fffL;\n        sp_4096_mul_add_78(a+i, m, mu);\n        a[i+1] += a[i] >> 53;\n        a[i] &= 0x1fffffffffffffL;\n    }\n    else {\n        for (i=0; i<77; i++) {\n            mu = a[i] & 0x1fffffffffffffL;\n            sp_4096_mul_add_78(a+i, m, mu);\n            a[i+1] += a[i] >> 53;\n        }\n        mu = a[i] & 0x7fffL;\n        sp_4096_mul_add_78(a+i, m, mu);\n        a[i+1] += a[i] >> 53;\n        a[i] &= 0x1fffffffffffffL;\n    }\n#else\n    for (i=0; i<77; i++) {\n        mu = (a[i] * mp) & 0x1fffffffffffffL;\n        sp_4096_mul_add_78(a+i, m, mu);\n        a[i+1] += a[i] >> 53;\n    }\n    mu = (a[i] * mp) & 0x7fffL;\n    sp_4096_mul_add_78(a+i, m, mu);\n    a[i+1] += a[i] >> 53;\n    a[i] &= 0x1fffffffffffffL;\n#endif\n\n    sp_4096_mont_shift_78(a, a);\n    sp_4096_cond_sub_78(a, a, m, 0 - (((a[77] >> 15) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_4096_norm_78(a);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_mul_78(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_4096_mul_78(r, a, b);\n    sp_4096_mont_reduce_78(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_sqr_78(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_4096_sqr_78(r, a);\n    sp_4096_mont_reduce_78(r, m, mp);\n}\n\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_4096_mul_d_156(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 156; i++) {\n        t += tb * a[i];\n        r[i] = t & 0x1fffffffffffffL;\n        t >>= 53;\n    }\n    r[156] = (sp_digit)t;\n#else\n    int128_t tb = b;\n    int128_t t[8];\n    int i;\n\n    t[0] = tb * a[0]; r[0] = t[0] & 0x1fffffffffffffL;\n    for (i = 0; i < 152; i += 8) {\n        t[1] = tb * a[i+1];\n        r[i+1] = (sp_digit)(t[0] >> 53) + (t[1] & 0x1fffffffffffffL);\n        t[2] = tb * a[i+2];\n        r[i+2] = (sp_digit)(t[1] >> 53) + (t[2] & 0x1fffffffffffffL);\n        t[3] = tb * a[i+3];\n        r[i+3] = (sp_digit)(t[2] >> 53) + (t[3] & 0x1fffffffffffffL);\n        t[4] = tb * a[i+4];\n        r[i+4] = (sp_digit)(t[3] >> 53) + (t[4] & 0x1fffffffffffffL);\n        t[5] = tb * a[i+5];\n        r[i+5] = (sp_digit)(t[4] >> 53) + (t[5] & 0x1fffffffffffffL);\n        t[6] = tb * a[i+6];\n        r[i+6] = (sp_digit)(t[5] >> 53) + (t[6] & 0x1fffffffffffffL);\n        t[7] = tb * a[i+7];\n        r[i+7] = (sp_digit)(t[6] >> 53) + (t[7] & 0x1fffffffffffffL);\n        t[0] = tb * a[i+8];\n        r[i+8] = (sp_digit)(t[7] >> 53) + (t[0] & 0x1fffffffffffffL);\n    }\n    t[1] = tb * a[153];\n    r[153] = (sp_digit)(t[0] >> 53) + (t[1] & 0x1fffffffffffffL);\n    t[2] = tb * a[154];\n    r[154] = (sp_digit)(t[1] >> 53) + (t[2] & 0x1fffffffffffffL);\n    t[3] = tb * a[155];\n    r[155] = (sp_digit)(t[2] >> 53) + (t[3] & 0x1fffffffffffffL);\n    r[156] =  (sp_digit)(t[3] >> 53);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_4096_cond_add_78(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 78; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    int i;\n\n    for (i = 0; i < 72; i += 8) {\n        r[i + 0] = a[i + 0] + (b[i + 0] & m);\n        r[i + 1] = a[i + 1] + (b[i + 1] & m);\n        r[i + 2] = a[i + 2] + (b[i + 2] & m);\n        r[i + 3] = a[i + 3] + (b[i + 3] & m);\n        r[i + 4] = a[i + 4] + (b[i + 4] & m);\n        r[i + 5] = a[i + 5] + (b[i + 5] & m);\n        r[i + 6] = a[i + 6] + (b[i + 6] & m);\n        r[i + 7] = a[i + 7] + (b[i + 7] & m);\n    }\n    r[72] = a[72] + (b[72] & m);\n    r[73] = a[73] + (b[73] & m);\n    r[74] = a[74] + (b[74] & m);\n    r[75] = a[75] + (b[75] & m);\n    r[76] = a[76] + (b[76] & m);\n    r[77] = a[77] + (b[77] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_sub_78(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 78; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#endif\n#ifdef WOLFSSL_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_4096_add_78(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 78; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#endif\nSP_NOINLINE static void sp_4096_rshift_78(sp_digit* r, sp_digit* a, byte n)\n{\n    int i;\n\n#ifdef WOLFSSL_SP_SMALL\n    for (i=0; i<77; i++) {\n        r[i] = ((a[i] >> n) | (a[i + 1] << (53 - n))) & 0x1fffffffffffffL;\n    }\n#else\n    for (i=0; i<72; i += 8) {\n        r[i+0] = ((a[i+0] >> n) | (a[i+1] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+1] = ((a[i+1] >> n) | (a[i+2] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+2] = ((a[i+2] >> n) | (a[i+3] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+3] = ((a[i+3] >> n) | (a[i+4] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+4] = ((a[i+4] >> n) | (a[i+5] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+5] = ((a[i+5] >> n) | (a[i+6] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+6] = ((a[i+6] >> n) | (a[i+7] << (53 - n))) & 0x1fffffffffffffL;\n        r[i+7] = ((a[i+7] >> n) | (a[i+8] << (53 - n))) & 0x1fffffffffffffL;\n    }\n    r[72] = ((a[72] >> n) | (a[73] << (53 - n))) & 0x1fffffffffffffL;\n    r[73] = ((a[73] >> n) | (a[74] << (53 - n))) & 0x1fffffffffffffL;\n    r[74] = ((a[74] >> n) | (a[75] << (53 - n))) & 0x1fffffffffffffL;\n    r[75] = ((a[75] >> n) | (a[76] << (53 - n))) & 0x1fffffffffffffL;\n    r[76] = ((a[76] >> n) | (a[77] << (53 - n))) & 0x1fffffffffffffL;\n#endif\n    r[77] = a[77] >> n;\n}\n\n#ifdef WOLFSSL_SP_DIV_64\nstatic WC_INLINE sp_digit sp_4096_div_word_78(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t, dv;\n    int128_t t0, t1;\n\n    /* dv has 27 bits. */\n    dv = (div >> 26) + 1;\n    /* All 53 bits from d1 and top 10 bits from d0. */\n    d = (d1 << 10) | (d0 >> 43);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 36 bits in r */\n    /* Next 17 bits from d0. */\n    d <<= 17;\n    r <<= 17;\n    d |= (d0 >> 26) & ((1 << 17) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 53 bits in r */\n\n    /* Handle rounding error with dv - top part */\n    t0 = ((int128_t)d1 << 53) + d0;\n    t1 = (int128_t)r * dv;\n    t1 = t0 - t1;\n    t = (sp_digit)(t1 >> 26) / dv;\n    r += t;\n\n    /* Handle rounding error with dv - bottom 64 bits */\n    t1 = (sp_digit)t0 - (r * dv);\n    t = (sp_digit)t1 / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_64 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_4096_div_78(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_64\n    int128_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[156 + 1], t2d[78 + 1], sdd[78 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    sp_digit* sd;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (4 * 78 + 3), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    (void)m;\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 156 + 1;\n        sd = t2 + 78 + 1;\n#else\n        t1 = t1d;\n        t2 = t2d;\n        sd = sdd;\n#endif\n\n        sp_4096_mul_d_78(sd, d, 1L << 38);\n        sp_4096_mul_d_156(t1, a, 1L << 38);\n        dv = sd[77];\n        for (i=78; i>=0; i--) {\n            t1[78 + i] += t1[78 + i - 1] >> 53;\n            t1[78 + i - 1] &= 0x1fffffffffffffL;\n#ifndef WOLFSSL_SP_DIV_64\n            d1 = t1[78 + i];\n            d1 <<= 53;\n            d1 += t1[78 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_4096_div_word_78(t1[78 + i], t1[78 + i - 1], dv);\n#endif\n\n            sp_4096_mul_d_78(t2, sd, r1);\n            (void)sp_4096_sub_78(&t1[i], &t1[i], t2);\n            t1[78 + i] -= t2[78];\n            t1[78 + i] += t1[78 + i - 1] >> 53;\n            t1[78 + i - 1] &= 0x1fffffffffffffL;\n            r1 = (((-t1[78 + i]) << 53) - t1[78 + i - 1]) / dv;\n            r1 -= t1[78 + i];\n            sp_4096_mul_d_78(t2, sd, r1);\n            (void)sp_4096_add_78(&t1[i], &t1[i], t2);\n            t1[78 + i] += t1[78 + i - 1] >> 53;\n            t1[78 + i - 1] &= 0x1fffffffffffffL;\n        }\n        t1[78 - 1] += t1[78 - 2] >> 53;\n        t1[78 - 2] &= 0x1fffffffffffffL;\n        d1 = t1[78 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_4096_mul_d_78(t2, sd, r1);\n        sp_4096_sub_78(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 78U);\n        for (i=0; i<76; i++) {\n            r[i+1] += r[i] >> 53;\n            r[i] &= 0x1fffffffffffffL;\n        }\n        sp_4096_cond_add_78(r, r, sd, 0 - ((r[77] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n\n        sp_4096_norm_78(r);\n        sp_4096_rshift_78(r, r, 38);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_4096_mod_78(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_78(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, const sp_digit* e, int bits,\n    const sp_digit* m, int reduceA)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* td;\n    sp_digit* t[3];\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 78 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3U * 78U * 2U);\n\n        norm = t[0] = td;\n        t[1] = &td[78 * 2];\n        t[2] = &td[2 * 78 * 2];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_78(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_4096_mod_78(t[1], a, m);\n        }\n        else {\n            XMEMCPY(t[1], a, sizeof(sp_digit) * 78U);\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_4096_mul_78(t[1], t[1], norm);\n        err = sp_4096_mod_78(t[1], t[1], m);\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 53;\n        c = bits % 53;\n        n = e[i--] << (53 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 53;\n            }\n\n            y = (n >> 52) & 1;\n            n <<= 1;\n\n            sp_4096_mont_mul_78(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(*t[2]) * 78 * 2);\n            sp_4096_mont_sqr_78(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(*t[2]) * 78 * 2);\n        }\n\n        sp_4096_mont_reduce_78(t[0], m, mp);\n        n = sp_4096_cmp_78(t[0], m);\n        sp_4096_cond_sub_78(t[0], t[0], m, ((n < 0) ?\n                    (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(*r) * 78 * 2);\n\n    }\n\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n\n    return err;\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[3][156];\n#else\n    sp_digit* td;\n    sp_digit* t[3];\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(*td) * 3 * 78 * 2, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        t[0] = td;\n        t[1] = &td[78 * 2];\n        t[2] = &td[2 * 78 * 2];\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_78(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_4096_mod_78(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_4096_mul_78(t[1], t[1], norm);\n                err = sp_4096_mod_78(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_4096_mul_78(t[1], a, norm);\n            err = sp_4096_mod_78(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        i = bits / 53;\n        c = bits % 53;\n        n = e[i--] << (53 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1) {\n                    break;\n                }\n\n                n = e[i--];\n                c = 53;\n            }\n\n            y = (n >> 52) & 1;\n            n <<= 1;\n\n            sp_4096_mont_mul_78(t[y^1], t[0], t[1], m, mp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                 ((size_t)t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_4096_mont_sqr_78(t[2], t[2], m, mp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                           ((size_t)t[1] & addr_mask[y])), t[2], sizeof(t[2]));\n        }\n\n        sp_4096_mont_reduce_78(t[0], m, mp);\n        n = sp_4096_cmp_78(t[0], m);\n        sp_4096_cond_sub_78(t[0], t[0], m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, t[0], sizeof(t[0]));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][156];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit rt[156];\n    sp_digit mp = 1;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 156, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 156;\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_78(norm, m);\n\n        if (reduceA != 0) {\n            err = sp_4096_mod_78(t[1], a, m);\n            if (err == MP_OKAY) {\n                sp_4096_mul_78(t[1], t[1], norm);\n                err = sp_4096_mod_78(t[1], t[1], m);\n            }\n        }\n        else {\n            sp_4096_mul_78(t[1], a, norm);\n            err = sp_4096_mod_78(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_78(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_78(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_78(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_78(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_78(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_78(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_78(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_78(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_78(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_78(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_78(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_78(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_78(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_78(t[15], t[ 8], t[ 7], m, mp);\n        sp_4096_mont_sqr_78(t[16], t[ 8], m, mp);\n        sp_4096_mont_mul_78(t[17], t[ 9], t[ 8], m, mp);\n        sp_4096_mont_sqr_78(t[18], t[ 9], m, mp);\n        sp_4096_mont_mul_78(t[19], t[10], t[ 9], m, mp);\n        sp_4096_mont_sqr_78(t[20], t[10], m, mp);\n        sp_4096_mont_mul_78(t[21], t[11], t[10], m, mp);\n        sp_4096_mont_sqr_78(t[22], t[11], m, mp);\n        sp_4096_mont_mul_78(t[23], t[12], t[11], m, mp);\n        sp_4096_mont_sqr_78(t[24], t[12], m, mp);\n        sp_4096_mont_mul_78(t[25], t[13], t[12], m, mp);\n        sp_4096_mont_sqr_78(t[26], t[13], m, mp);\n        sp_4096_mont_mul_78(t[27], t[14], t[13], m, mp);\n        sp_4096_mont_sqr_78(t[28], t[14], m, mp);\n        sp_4096_mont_mul_78(t[29], t[15], t[14], m, mp);\n        sp_4096_mont_sqr_78(t[30], t[15], m, mp);\n        sp_4096_mont_mul_78(t[31], t[16], t[15], m, mp);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 52) / 53) - 1;\n        c = bits % 53;\n        if (c == 0) {\n            c = 53;\n        }\n        if (i < 78) {\n            n = e[i--] << (64 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (11 - c);\n            c += 53;\n        }\n        y = (n >> 59) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        XMEMCPY(rt, t[y], sizeof(rt));\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (11 - c);\n                c += 53;\n            }\n            y = (n >> 59) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_4096_mont_sqr_78(rt, rt, m, mp);\n            sp_4096_mont_sqr_78(rt, rt, m, mp);\n            sp_4096_mont_sqr_78(rt, rt, m, mp);\n            sp_4096_mont_sqr_78(rt, rt, m, mp);\n            sp_4096_mont_sqr_78(rt, rt, m, mp);\n\n            sp_4096_mont_mul_78(rt, rt, t[y], m, mp);\n        }\n\n        sp_4096_mont_reduce_78(rt, m, mp);\n        n = sp_4096_cmp_78(rt, m);\n        sp_4096_cond_sub_78(rt, rt, m, ((n < 0) ?\n                   (sp_digit)1 : (sp_digit)0) - 1);\n        XMEMCPY(r, rt, sizeof(rt));\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n#endif\n}\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */\n       /* WOLFSSL_HAVE_SP_DH */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \\\n           !defined(RSA_LOW_MEM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_4096_mask_39(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<39; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n    r[32] = a[32] & m;\n    r[33] = a[33] & m;\n    r[34] = a[34] & m;\n    r[35] = a[35] & m;\n    r[36] = a[36] & m;\n    r[37] = a[37] & m;\n    r[38] = a[38] & m;\n#endif\n}\n\n#endif\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* d = NULL;\n    sp_digit* a;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit* norm;\n    sp_digit e[1] = {0};\n    sp_digit mp;\n    int i;\n    int err = MP_OKAY;\n\n    if (*outLen < 512U) {\n        err = MP_TO_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(em) > 53) {\n            err = MP_READ_E;\n        }\n        if (inLen > 512U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 78 * 2;\n        m = r + 78 * 2;\n        norm = r;\n\n        sp_4096_from_bin(a, 78, in, inLen);\n#if DIGIT_BIT >= 53\n        e[0] = (sp_digit)em->dp[0];\n#else\n        e[0] = (sp_digit)em->dp[0];\n        if (em->used > 1) {\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n        }\n#endif\n        if (e[0] == 0) {\n            err = MP_EXPTMOD_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(m, 78, mm);\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_78(norm, m);\n    }\n    if (err == MP_OKAY) {\n        sp_4096_mul_78(a, a, norm);\n        err = sp_4096_mod_78(a, a, m);\n    }\n    if (err == MP_OKAY) {\n        for (i=52; i>=0; i--) {\n            if ((e[0] >> i) != 0) {\n                break;\n            }\n        }\n\n        XMEMCPY(r, a, sizeof(sp_digit) * 78 * 2);\n        for (i--; i>=0; i--) {\n            sp_4096_mont_sqr_78(r, r, m, mp);\n\n            if (((e[0] >> i) & 1) == 1) {\n                sp_4096_mont_mul_78(r, r, a, m, mp);\n            }\n        }\n        sp_4096_mont_reduce_78(r, m, mp);\n        mp = sp_4096_cmp_78(r, m);\n        sp_4096_cond_sub_78(r, r, m, ((mp < 0) ?\n                    (sp_digit)1 : (sp_digit)0)- 1);\n\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[156], md[78], rd[156];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1] = {0};\n    int err = MP_OKAY;\n\n    if (*outLen < 512U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(em) > 53) {\n            err = MP_READ_E;\n        }\n        if (inLen > 512U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 78 * 2;\n        m = r + 78 * 2;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(a, 78, in, inLen);\n#if DIGIT_BIT >= 53\n        e[0] = (sp_digit)em->dp[0];\n#else\n        e[0] = (sp_digit)em->dp[0];\n        if (em->used > 1) {\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n        }\n#endif\n        if (e[0] == 0) {\n            err = MP_EXPTMOD_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(m, 78, mm);\n\n        if (e[0] == 0x3) {\n            sp_4096_sqr_78(r, a);\n            err = sp_4096_mod_78(r, r, m);\n            if (err == MP_OKAY) {\n                sp_4096_mul_78(r, a, r);\n                err = sp_4096_mod_78(r, r, m);\n            }\n        }\n        else {\n            sp_digit* norm = r;\n            int i;\n            sp_digit mp;\n\n            sp_4096_mont_setup(m, &mp);\n            sp_4096_mont_norm_78(norm, m);\n\n            sp_4096_mul_78(a, a, norm);\n            err = sp_4096_mod_78(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=52; i>=0; i--) {\n                    if ((e[0] >> i) != 0) {\n                        break;\n                    }\n                }\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 156U);\n                for (i--; i>=0; i--) {\n                    sp_4096_mont_sqr_78(r, r, m, mp);\n\n                    if (((e[0] >> i) & 1) == 1) {\n                        sp_4096_mont_mul_78(r, r, a, m, mp);\n                    }\n                }\n                sp_4096_mont_reduce_78(r, m, mp);\n                mp = sp_4096_cmp_78(r, m);\n                sp_4096_cond_sub_78(r, r, m, ((mp < 0) ?\n                           (sp_digit)1 : (sp_digit)0) - 1);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n#endif\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if defined(SP_RSA_PRIVATE_EXP_D) || defined(RSA_LOW_MEM)\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* a;\n    sp_digit* d = NULL;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n\n    (void)pm;\n    (void)qm;\n    (void)dpm;\n    (void)dqm;\n    (void)qim;\n\n    if (*outLen < 512U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(dm) > 4096) {\n           err = MP_READ_E;\n        }\n        if (inLen > 512) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 78 * 4, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        a = d + 78;\n        m = a + 78;\n        r = a;\n\n        sp_4096_from_bin(a, 78, in, inLen);\n        sp_4096_from_mp(d, 78, dm);\n        sp_4096_from_mp(m, 78, mm);\n        err = sp_4096_mod_exp_78(r, a, d, 4096, m, 0);\n    }\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n    if (d != NULL) {\n        XMEMSET(d, 0, sizeof(sp_digit) * 78);\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n    sp_digit a[156], d[78], m[78];\n    sp_digit* r = a;\n    int err = MP_OKAY;\n\n    (void)pm;\n    (void)qm;\n    (void)dpm;\n    (void)dqm;\n    (void)qim;\n\n    if (*outLen < 512U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (mp_count_bits(dm) > 4096) {\n            err = MP_READ_E;\n        }\n        if (inLen > 512U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(a, 78, in, inLen);\n        sp_4096_from_mp(d, 78, dm);\n        sp_4096_from_mp(m, 78, mm);\n        err = sp_4096_mod_exp_78(r, a, d, 4096, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n    XMEMSET(d, 0, sizeof(sp_digit) * 78);\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */\n#else\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* t = NULL;\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 512U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (inLen > 512) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 39 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL) {\n            err = MEMORY_E;\n        }\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 78 * 2;\n        q = p + 39;\n        qi = dq = dp = q + 39;\n        tmpa = qi + 39;\n        tmpb = tmpa + 78;\n\n        tmp = t;\n        r = tmp + 78;\n\n        sp_4096_from_bin(a, 78, in, inLen);\n        sp_4096_from_mp(p, 39, pm);\n        sp_4096_from_mp(q, 39, qm);\n        sp_4096_from_mp(dp, 39, dpm);\n        err = sp_4096_mod_exp_39(tmpa, a, dp, 2048, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(dq, 39, dqm);\n        err = sp_4096_mod_exp_39(tmpb, a, dq, 2048, q, 1);\n    }\n    if (err == MP_OKAY) {\n        (void)sp_4096_sub_39(tmpa, tmpa, tmpb);\n        sp_4096_mask_39(tmp, p, 0 - ((sp_int_digit)tmpa[38] >> 63));\n        (void)sp_4096_add_39(tmpa, tmpa, tmp);\n\n        sp_4096_from_mp(qi, 39, qim);\n        sp_4096_mul_39(tmpa, tmpa, qi);\n        err = sp_4096_mod_39(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mul_39(tmpa, q, tmpa);\n        (void)sp_4096_add_78(r, tmpb, tmpa);\n        sp_4096_norm_78(r);\n\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 39 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n\n    return err;\n#else\n    sp_digit a[78 * 2];\n    sp_digit p[39], q[39], dp[39], dq[39], qi[39];\n    sp_digit tmp[78], tmpa[78], tmpb[78];\n    sp_digit* r = a;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 512U) {\n        err = MP_TO_E;\n    }\n    if (err == MP_OKAY) {\n        if (inLen > 512U) {\n            err = MP_READ_E;\n        }\n        if (mp_count_bits(mm) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(a, 78, in, inLen);\n        sp_4096_from_mp(p, 39, pm);\n        sp_4096_from_mp(q, 39, qm);\n        sp_4096_from_mp(dp, 39, dpm);\n        sp_4096_from_mp(dq, 39, dqm);\n        sp_4096_from_mp(qi, 39, qim);\n\n        err = sp_4096_mod_exp_39(tmpa, a, dp, 2048, p, 1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_4096_mod_exp_39(tmpb, a, dq, 2048, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        (void)sp_4096_sub_39(tmpa, tmpa, tmpb);\n        sp_4096_mask_39(tmp, p, 0 - ((sp_int_digit)tmpa[38] >> 63));\n        (void)sp_4096_add_39(tmpa, tmpa, tmp);\n        sp_4096_mul_39(tmpa, tmpa, qi);\n        err = sp_4096_mod_39(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mul_39(tmpa, tmpa, q);\n        (void)sp_4096_add_78(r, tmpb, tmpa);\n        sp_4096_norm_78(r);\n\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n    XMEMSET(tmpa, 0, sizeof(tmpa));\n    XMEMSET(tmpb, 0, sizeof(tmpb));\n    XMEMSET(p, 0, sizeof(p));\n    XMEMSET(q, 0, sizeof(q));\n    XMEMSET(dp, 0, sizeof(dp));\n    XMEMSET(dq, 0, sizeof(dq));\n    XMEMSET(qi, 0, sizeof(qi));\n\n    return err;\n#endif /* WOLFSSL_SP_SMALL || defined(WOLFSSL_SMALL_STACK) */\n#endif /* SP_RSA_PRIVATE_EXP_D || RSA_LOW_MEM */\n}\n\n#endif /* !WOLFSSL_RSA_PUBLIC_ONLY */\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_4096_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (4096 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 53\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 78);\n        r->used = 78;\n        mp_clamp(r);\n#elif DIGIT_BIT < 53\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 78; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 53) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 53 - s;\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 78; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 53 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 53 - s;\n            }\n            else {\n                s += 53;\n            }\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 78 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 78 * 2;\n        m = e + 78;\n        r = b;\n\n        sp_4096_from_mp(b, 78, base);\n        sp_4096_from_mp(e, 78, exp);\n        sp_4096_from_mp(m, 78, mod);\n\n        err = sp_4096_mod_exp_78(r, b, e, mp_count_bits(exp), m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_4096_to_mp(r, res);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 78U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[156], ed[78], md[78];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    int err = MP_OKAY;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 4096) {\n            err = MP_READ_E;\n        }\n    }\n    \n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 78 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 78 * 2;\n        m = e + 78;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 78, base);\n        sp_4096_from_mp(e, 78, exp);\n        sp_4096_from_mp(m, 78, mod);\n\n        err = sp_4096_mod_exp_78(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_4096_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 78U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_4096\nSP_NOINLINE static void sp_4096_lshift_78(sp_digit* r, sp_digit* a, byte n)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    r[78] = a[77] >> (53 - n);\n    for (i=77; i>0; i--) {\n        r[i] = ((a[i] << n) | (a[i-1] >> (53 - n))) & 0x1fffffffffffffL;\n    }\n#else\n    sp_int_digit s, t;\n\n    s = (sp_int_digit)a[77];\n    r[78] = s >> (53U - n);\n    s = (sp_int_digit)(a[77]); t = (sp_int_digit)(a[76]);\n    r[77] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[76]); t = (sp_int_digit)(a[75]);\n    r[76] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[75]); t = (sp_int_digit)(a[74]);\n    r[75] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[74]); t = (sp_int_digit)(a[73]);\n    r[74] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[73]); t = (sp_int_digit)(a[72]);\n    r[73] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[72]); t = (sp_int_digit)(a[71]);\n    r[72] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[71]); t = (sp_int_digit)(a[70]);\n    r[71] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[70]); t = (sp_int_digit)(a[69]);\n    r[70] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[69]); t = (sp_int_digit)(a[68]);\n    r[69] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[68]); t = (sp_int_digit)(a[67]);\n    r[68] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[67]); t = (sp_int_digit)(a[66]);\n    r[67] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[66]); t = (sp_int_digit)(a[65]);\n    r[66] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[65]); t = (sp_int_digit)(a[64]);\n    r[65] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[64]); t = (sp_int_digit)(a[63]);\n    r[64] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[63]); t = (sp_int_digit)(a[62]);\n    r[63] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[62]); t = (sp_int_digit)(a[61]);\n    r[62] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[61]); t = (sp_int_digit)(a[60]);\n    r[61] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[60]); t = (sp_int_digit)(a[59]);\n    r[60] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[59]); t = (sp_int_digit)(a[58]);\n    r[59] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[58]); t = (sp_int_digit)(a[57]);\n    r[58] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[57]); t = (sp_int_digit)(a[56]);\n    r[57] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[56]); t = (sp_int_digit)(a[55]);\n    r[56] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[55]); t = (sp_int_digit)(a[54]);\n    r[55] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[54]); t = (sp_int_digit)(a[53]);\n    r[54] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[53]); t = (sp_int_digit)(a[52]);\n    r[53] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[52]); t = (sp_int_digit)(a[51]);\n    r[52] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[51]); t = (sp_int_digit)(a[50]);\n    r[51] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[50]); t = (sp_int_digit)(a[49]);\n    r[50] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[49]); t = (sp_int_digit)(a[48]);\n    r[49] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[48]); t = (sp_int_digit)(a[47]);\n    r[48] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[47]); t = (sp_int_digit)(a[46]);\n    r[47] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[46]); t = (sp_int_digit)(a[45]);\n    r[46] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[45]); t = (sp_int_digit)(a[44]);\n    r[45] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[44]); t = (sp_int_digit)(a[43]);\n    r[44] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[43]); t = (sp_int_digit)(a[42]);\n    r[43] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[42]); t = (sp_int_digit)(a[41]);\n    r[42] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[41]); t = (sp_int_digit)(a[40]);\n    r[41] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[40]); t = (sp_int_digit)(a[39]);\n    r[40] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[39]); t = (sp_int_digit)(a[38]);\n    r[39] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[38]); t = (sp_int_digit)(a[37]);\n    r[38] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[37]); t = (sp_int_digit)(a[36]);\n    r[37] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[36]); t = (sp_int_digit)(a[35]);\n    r[36] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[35]); t = (sp_int_digit)(a[34]);\n    r[35] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[34]); t = (sp_int_digit)(a[33]);\n    r[34] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[33]); t = (sp_int_digit)(a[32]);\n    r[33] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[32]); t = (sp_int_digit)(a[31]);\n    r[32] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[31]); t = (sp_int_digit)(a[30]);\n    r[31] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[30]); t = (sp_int_digit)(a[29]);\n    r[30] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[29]); t = (sp_int_digit)(a[28]);\n    r[29] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[28]); t = (sp_int_digit)(a[27]);\n    r[28] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[27]); t = (sp_int_digit)(a[26]);\n    r[27] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[26]); t = (sp_int_digit)(a[25]);\n    r[26] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[25]); t = (sp_int_digit)(a[24]);\n    r[25] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[24]); t = (sp_int_digit)(a[23]);\n    r[24] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[23]); t = (sp_int_digit)(a[22]);\n    r[23] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[22]); t = (sp_int_digit)(a[21]);\n    r[22] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[21]); t = (sp_int_digit)(a[20]);\n    r[21] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[20]); t = (sp_int_digit)(a[19]);\n    r[20] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[19]); t = (sp_int_digit)(a[18]);\n    r[19] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[18]); t = (sp_int_digit)(a[17]);\n    r[18] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[17]); t = (sp_int_digit)(a[16]);\n    r[17] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[16]); t = (sp_int_digit)(a[15]);\n    r[16] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[15]); t = (sp_int_digit)(a[14]);\n    r[15] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[14]); t = (sp_int_digit)(a[13]);\n    r[14] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[13]); t = (sp_int_digit)(a[12]);\n    r[13] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[12]); t = (sp_int_digit)(a[11]);\n    r[12] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[11]); t = (sp_int_digit)(a[10]);\n    r[11] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[10]); t = (sp_int_digit)(a[9]);\n    r[10] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[9]); t = (sp_int_digit)(a[8]);\n    r[9] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[8]); t = (sp_int_digit)(a[7]);\n    r[8] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[7]); t = (sp_int_digit)(a[6]);\n    r[7] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[6]); t = (sp_int_digit)(a[5]);\n    r[6] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[5]); t = (sp_int_digit)(a[4]);\n    r[5] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[4]); t = (sp_int_digit)(a[3]);\n    r[4] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[3]); t = (sp_int_digit)(a[2]);\n    r[3] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[2]); t = (sp_int_digit)(a[1]);\n    r[2] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n    s = (sp_int_digit)(a[1]); t = (sp_int_digit)(a[0]);\n    r[1] = ((s << n) | (t >> (53U - n))) & 0x1fffffffffffffUL;\n#endif\n    r[0] = (a[0] << n) & 0x1fffffffffffffL;\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_2_78(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[156];\n    sp_digit td[79];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 235, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 156;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        XMEMSET(td, 0, sizeof(td));\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_78(norm, m);\n\n        bits = ((bits + 4) / 5) * 5;\n        i = ((bits + 52) / 53) - 1;\n        c = bits % 53;\n        if (c == 0) {\n            c = 53;\n        }\n        if (i < 78) {\n            n = e[i--] << (64 - c);\n        }\n        else {\n            n = 0;\n            i--;\n        }\n        if (c < 5) {\n            n |= e[i--] << (11 - c);\n            c += 53;\n        }\n        y = (n >> 59) & 0x1f;\n        n <<= 5;\n        c -= 5;\n        sp_4096_lshift_78(r, norm, y);\n        for (; i>=0 || c>=5; ) {\n            if (c < 5) {\n                n |= e[i--] << (11 - c);\n                c += 53;\n            }\n            y = (n >> 59) & 0x1f;\n            n <<= 5;\n            c -= 5;\n\n            sp_4096_mont_sqr_78(r, r, m, mp);\n            sp_4096_mont_sqr_78(r, r, m, mp);\n            sp_4096_mont_sqr_78(r, r, m, mp);\n            sp_4096_mont_sqr_78(r, r, m, mp);\n            sp_4096_mont_sqr_78(r, r, m, mp);\n\n            sp_4096_lshift_78(r, r, y);\n            sp_4096_mul_d_78(tmp, norm, (r[78] << 38) + (r[77] >> 15));\n            r[78] = 0;\n            r[77] &= 0x7fffL;\n            (void)sp_4096_add_78(r, r, tmp);\n            sp_4096_norm_78(r);\n            o = sp_4096_cmp_78(r, m);\n            sp_4096_cond_sub_78(r, r, m, ((o < 0) ?\n                                          (sp_digit)1 : (sp_digit)0) - 1);\n        }\n\n        sp_4096_mont_reduce_78(r, m, mp);\n        n = sp_4096_cmp_78(r, m);\n        sp_4096_cond_sub_78(r, r, m, ((n < 0) ?\n                                                (sp_digit)1 : (sp_digit)0) - 1);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n#endif /* HAVE_FFDHE_4096 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 512 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int err = MP_OKAY;\n    sp_digit* d = NULL;\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    word32 i;\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 512) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 78 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 78 * 2;\n        m = e + 78;\n        r = b;\n\n        sp_4096_from_mp(b, 78, base);\n        sp_4096_from_bin(e, 78, exp, expLen);\n        sp_4096_from_mp(m, 78, mod);\n\n    #ifdef HAVE_FFDHE_4096\n        if (base->used == 1 && base->dp[0] == 2 &&\n                ((m[77] << 17) | (m[76] >> 36)) == 0xffffffffL) {\n            err = sp_4096_mod_exp_2_78(r, e, expLen * 8, m);\n        }\n        else\n    #endif\n            err = sp_4096_mod_exp_78(r, b, e, expLen * 8, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n        for (i=0; i<512 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    if (d != NULL) {\n        XMEMSET(e, 0, sizeof(sp_digit) * 78U);\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n    }\n    return err;\n#else\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit bd[156], ed[78], md[78];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* b;\n    sp_digit* e;\n    sp_digit* m;\n    sp_digit* r;\n    word32 i;\n    int err = MP_OKAY;\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 512U) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(*d) * 78 * 4, NULL, DYNAMIC_TYPE_DH);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        b = d;\n        e = b + 78 * 2;\n        m = e + 78;\n        r = b;\n    }\n#else\n    r = b = bd;\n    e = ed;\n    m = md;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 78, base);\n        sp_4096_from_bin(e, 78, exp, expLen);\n        sp_4096_from_mp(m, 78, mod);\n\n    #ifdef HAVE_FFDHE_4096\n        if (base->used == 1 && base->dp[0] == 2U &&\n                ((m[77] << 17) | (m[76] >> 36)) == 0xffffffffL) {\n            err = sp_4096_mod_exp_2_78(r, e, expLen * 8U, m);\n        }\n        else {\n    #endif\n            err = sp_4096_mod_exp_78(r, b, e, expLen * 8U, m, 0);\n    #ifdef HAVE_FFDHE_4096\n        }\n    #endif\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n        for (i=0; i<512U && out[i] == 0U; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    XMEMSET(e, 0, sizeof(sp_digit) * 78U);\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_DH);\n#endif\n\n    return err;\n#endif\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* WOLFSSL_SP_4096 */\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n#ifdef WOLFSSL_HAVE_SP_ECC\n#ifndef WOLFSSL_SP_NO_256\n\n/* Point structure to use. */\ntypedef struct sp_point {\n    sp_digit x[2 * 5];\n    sp_digit y[2 * 5];\n    sp_digit z[2 * 5];\n    int infinity;\n} sp_point;\n\n/* The modulus (prime) of the curve P256. */\nstatic const sp_digit p256_mod[5] = {\n    0xfffffffffffffL,0x00fffffffffffL,0x0000000000000L,0x0001000000000L,\n    0x0ffffffff0000L\n};\n/* The Montogmery normalizer for modulus of the curve P256. */\nstatic const sp_digit p256_norm_mod[5] = {\n    0x0000000000001L,0xff00000000000L,0xfffffffffffffL,0xfffefffffffffL,\n    0x000000000ffffL\n};\n/* The Montogmery multiplier for modulus of the curve P256. */\nstatic const sp_digit p256_mp_mod = 0x0000000000001;\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                            defined(HAVE_ECC_VERIFY)\n/* The order of the curve P256. */\nstatic const sp_digit p256_order[5] = {\n    0x9cac2fc632551L,0xada7179e84f3bL,0xfffffffbce6faL,0x0000fffffffffL,\n    0x0ffffffff0000L\n};\n#endif\n/* The order of the curve P256 minus 2. */\nstatic const sp_digit p256_order2[5] = {\n    0x9cac2fc63254fL,0xada7179e84f3bL,0xfffffffbce6faL,0x0000fffffffffL,\n    0x0ffffffff0000L\n};\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery normalizer for order of the curve P256. */\nstatic const sp_digit p256_norm_order[5] = {\n    0x6353d039cdaafL,0x5258e8617b0c4L,0x0000000431905L,0xffff000000000L,\n    0x000000000ffffL\n};\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery multiplier for order of the curve P256. */\nstatic const sp_digit p256_mp_order = 0x1c8aaee00bc4fL;\n#endif\n/* The base point of curve P256. */\nstatic const sp_point p256_base = {\n    /* X ordinate */\n    {\n        0x13945d898c296L,0x812deb33a0f4aL,0x3a440f277037dL,0x4247f8bce6e56L,\n        0x06b17d1f2e12cL, 0L, 0L, 0L, 0L, 0L\n    },\n    /* Y ordinate */\n    {\n        0x6406837bf51f5L,0x576b315ececbbL,0xc0f9e162bce33L,0x7f9b8ee7eb4a7L,\n        0x04fe342e2fe1aL, 0L, 0L, 0L, 0L, 0L\n    },\n    /* Z ordinate */\n    {\n        0x0000000000001L,0x0000000000000L,0x0000000000000L,0x0000000000000L,\n        0x0000000000000L, 0L, 0L, 0L, 0L, 0L\n    },\n    /* infinity */\n    0\n};\n#if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)\nstatic const sp_digit p256_b[5] = {\n    0xe3c3e27d2604bL,0xb0cc53b0f63bcL,0x69886bc651d06L,0x93e7b3ebbd557L,\n    0x05ac635d8aa3aL\n};\n#endif\n\nstatic int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p)\n{\n    int ret = MP_OKAY;\n    (void)heap;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    (void)sp;\n    *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC);\n#else\n    *p = sp;\n#endif\n    if (p == NULL) {\n        ret = MEMORY_E;\n    }\n    return ret;\n}\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* Allocate memory for point and return error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p))\n#else\n/* Set pointer to data and return no error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p))\n#endif\n\n\nstatic void sp_ecc_point_free(sp_point* p, int clear, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* If valid pointer then clear point data if requested and free data. */\n    if (p != NULL) {\n        if (clear != 0) {\n            XMEMSET(p, 0, sizeof(*p));\n        }\n        XFREE(p, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n/* Clear point data if requested. */\n    if (clear != 0) {\n        XMEMSET(p, 0, sizeof(*p));\n    }\n#endif\n    (void)heap;\n}\n\n/* Multiply a number by Montogmery normalizer mod modulus (prime).\n *\n * r  The resulting Montgomery form number.\n * a  The number to convert.\n * m  The modulus (prime).\n * returns MEMORY_E when memory allocation fails and MP_OKAY otherwise.\n */\nstatic int sp_256_mod_mul_norm_5(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    int64_t* td;\n#else\n    int64_t td[8];\n    int64_t a32d[8];\n#endif\n    int64_t* t;\n    int64_t* a32;\n    int64_t o;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 8, NULL, DYNAMIC_TYPE_ECC);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t = td;\n        a32 = td + 8;\n#else\n        t = td;\n        a32 = a32d;\n#endif\n\n        a32[0] = (sp_digit)(a[0]) & 0xffffffffL;\n        a32[1] = (sp_digit)(a[0] >> 32U);\n        a32[1] |= a[1] << 20U;\n        a32[1] &= 0xffffffffL;\n        a32[2] = (sp_digit)(a[1] >> 12U) & 0xffffffffL;\n        a32[3] = (sp_digit)(a[1] >> 44U);\n        a32[3] |= a[2] << 8U;\n        a32[3] &= 0xffffffffL;\n        a32[4] = (sp_digit)(a[2] >> 24U);\n        a32[4] |= a[3] << 28U;\n        a32[4] &= 0xffffffffL;\n        a32[5] = (sp_digit)(a[3] >> 4U) & 0xffffffffL;\n        a32[6] = (sp_digit)(a[3] >> 36U);\n        a32[6] |= a[4] << 16U;\n        a32[6] &= 0xffffffffL;\n        a32[7] = (sp_digit)(a[4] >> 16U) & 0xffffffffL;\n\n        /*  1  1  0 -1 -1 -1 -1  0 */\n        t[0] = 0 + a32[0] + a32[1] - a32[3] - a32[4] - a32[5] - a32[6];\n        /*  0  1  1  0 -1 -1 -1 -1 */\n        t[1] = 0 + a32[1] + a32[2] - a32[4] - a32[5] - a32[6] - a32[7];\n        /*  0  0  1  1  0 -1 -1 -1 */\n        t[2] = 0 + a32[2] + a32[3] - a32[5] - a32[6] - a32[7];\n        /* -1 -1  0  2  2  1  0 -1 */\n        t[3] = 0 - a32[0] - a32[1] + 2 * a32[3] + 2 * a32[4] + a32[5] - a32[7];\n        /*  0 -1 -1  0  2  2  1  0 */\n        t[4] = 0 - a32[1] - a32[2] + 2 * a32[4] + 2 * a32[5] + a32[6];\n        /*  0  0 -1 -1  0  2  2  1 */\n        t[5] = 0 - a32[2] - a32[3] + 2 * a32[5] + 2 * a32[6] + a32[7];\n        /* -1 -1  0  0  0  1  3  2 */\n        t[6] = 0 - a32[0] - a32[1] + a32[5] + 3 * a32[6] + 2 * a32[7];\n        /*  1  0 -1 -1 -1 -1  0  3 */\n        t[7] = 0 + a32[0] - a32[2] - a32[3] - a32[4] - a32[5] + 3 * a32[7];\n\n        t[1] += t[0] >> 32U; t[0] &= 0xffffffffL;\n        t[2] += t[1] >> 32U; t[1] &= 0xffffffffL;\n        t[3] += t[2] >> 32U; t[2] &= 0xffffffffL;\n        t[4] += t[3] >> 32U; t[3] &= 0xffffffffL;\n        t[5] += t[4] >> 32U; t[4] &= 0xffffffffL;\n        t[6] += t[5] >> 32U; t[5] &= 0xffffffffL;\n        t[7] += t[6] >> 32U; t[6] &= 0xffffffffL;\n        o     = t[7] >> 32U; t[7] &= 0xffffffffL;\n        t[0] += o;\n        t[3] -= o;\n        t[6] -= o;\n        t[7] += o;\n        t[1] += t[0] >> 32U; t[0] &= 0xffffffffL;\n        t[2] += t[1] >> 32U; t[1] &= 0xffffffffL;\n        t[3] += t[2] >> 32U; t[2] &= 0xffffffffL;\n        t[4] += t[3] >> 32U; t[3] &= 0xffffffffL;\n        t[5] += t[4] >> 32U; t[4] &= 0xffffffffL;\n        t[6] += t[5] >> 32U; t[5] &= 0xffffffffL;\n        t[7] += t[6] >> 32U; t[6] &= 0xffffffffL;\n\n        r[0] = t[0];\n        r[0] |= t[1] << 32U;\n        r[0] &= 0xfffffffffffffLL;\n        r[1] = (sp_digit)(t[1] >> 20);\n        r[1] |= t[2] << 12U;\n        r[1] |= t[3] << 44U;\n        r[1] &= 0xfffffffffffffLL;\n        r[2] = (sp_digit)(t[3] >> 8);\n        r[2] |= t[4] << 24U;\n        r[2] &= 0xfffffffffffffLL;\n        r[3] = (sp_digit)(t[4] >> 28);\n        r[3] |= t[5] << 4U;\n        r[3] |= t[6] << 36U;\n        r[3] &= 0xfffffffffffffLL;\n        r[4] = (sp_digit)(t[6] >> 16);\n        r[4] |= t[7] << 16U;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_256_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 52\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 52\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xfffffffffffffL;\n        s = 52U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 52U) <= (word32)DIGIT_BIT) {\n            s += 52U;\n            r[j] &= 0xfffffffffffffL;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 52) {\n            r[j] &= 0xfffffffffffffL;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 52 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Convert a point of type ecc_point to type sp_point.\n *\n * p   Point of type sp_point (result).\n * pm  Point of type ecc_point.\n */\nstatic void sp_256_point_from_ecc_point_5(sp_point* p, const ecc_point* pm)\n{\n    XMEMSET(p->x, 0, sizeof(p->x));\n    XMEMSET(p->y, 0, sizeof(p->y));\n    XMEMSET(p->z, 0, sizeof(p->z));\n    sp_256_from_mp(p->x, 5, pm->x);\n    sp_256_from_mp(p->y, 5, pm->y);\n    sp_256_from_mp(p->z, 5, pm->z);\n    p->infinity = 0;\n}\n\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_256_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 52\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 5);\n        r->used = 5;\n        mp_clamp(r);\n#elif DIGIT_BIT < 52\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 5; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 52) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 52 - s;\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 5; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 52 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 52 - s;\n            }\n            else {\n                s += 52;\n            }\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Convert a point of type sp_point to type ecc_point.\n *\n * p   Point of type sp_point.\n * pm  Point of type ecc_point (result).\n * returns MEMORY_E when allocation of memory in ecc_point fails otherwise\n * MP_OKAY.\n */\nstatic int sp_256_point_to_ecc_point_5(const sp_point* p, ecc_point* pm)\n{\n    int err;\n\n    err = sp_256_to_mp(p->x, pm->x);\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pm->y);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pm->z);\n    }\n\n    return err;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nstatic sp_digit sp_256_cmp_5(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=4; i>=0; i--) {\n        r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    }\n#else\n    r |= (a[ 4] - b[ 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[ 3] - b[ 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[ 2] - b[ 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[ 1] - b[ 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n    r |= (a[ 0] - b[ 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0));\n#endif /* WOLFSSL_SP_SMALL */\n\n    return r;\n}\n\n/* Normalize the values in each word to 52.\n *\n * a  Array of sp_digit to normalize.\n */\nstatic void sp_256_norm_5(sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    for (i = 0; i < 4; i++) {\n        a[i+1] += a[i] >> 52;\n        a[i] &= 0xfffffffffffffL;\n    }\n#else\n    a[1] += a[0] >> 52; a[0] &= 0xfffffffffffffL;\n    a[2] += a[1] >> 52; a[1] &= 0xfffffffffffffL;\n    a[3] += a[2] >> 52; a[2] &= 0xfffffffffffffL;\n    a[4] += a[3] >> 52; a[3] &= 0xfffffffffffffL;\n#endif\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nstatic void sp_256_cond_sub_5(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 5; i++) {\n        r[i] = a[i] - (b[i] & m);\n    }\n#else\n    r[ 0] = a[ 0] - (b[ 0] & m);\n    r[ 1] = a[ 1] - (b[ 1] & m);\n    r[ 2] = a[ 2] - (b[ 2] & m);\n    r[ 3] = a[ 3] - (b[ 3] & m);\n    r[ 4] = a[ 4] - (b[ 4] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#define sp_256_mont_reduce_order_5         sp_256_mont_reduce_5\n\n/* Mul a by scalar b and add into r. (r += a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_256_mul_add_5(sp_digit* r, const sp_digit* a,\n        const sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 5; i++) {\n        t += (tb * a[i]) + r[i];\n        r[i] = t & 0xfffffffffffffL;\n        t >>= 52;\n    }\n    r[5] += t;\n#else\n    int128_t tb = b;\n    int128_t t[5];\n\n    t[ 0] = tb * a[ 0];\n    t[ 1] = tb * a[ 1];\n    t[ 2] = tb * a[ 2];\n    t[ 3] = tb * a[ 3];\n    t[ 4] = tb * a[ 4];\n    r[ 0] +=                 (sp_digit)(t[ 0] & 0xfffffffffffffL);\n    r[ 1] += (sp_digit)((t[ 0] >> 52) + (t[ 1] & 0xfffffffffffffL));\n    r[ 2] += (sp_digit)((t[ 1] >> 52) + (t[ 2] & 0xfffffffffffffL));\n    r[ 3] += (sp_digit)((t[ 2] >> 52) + (t[ 3] & 0xfffffffffffffL));\n    r[ 4] += (sp_digit)((t[ 3] >> 52) + (t[ 4] & 0xfffffffffffffL));\n    r[ 5] +=  t[ 4] >> 52;\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Shift the result in the high 256 bits down to the bottom.\n *\n * r  A single precision number.\n * a  A single precision number.\n */\nstatic void sp_256_mont_shift_5(sp_digit* r, const sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n    word64 n;\n\n    n = a[4] >> 48;\n    for (i = 0; i < 4; i++) {\n        n += (word64)a[5 + i] << 4;\n        r[i] = n & 0xfffffffffffffL;\n        n >>= 52;\n    }\n    n += (word64)a[9] << 4;\n    r[4] = n;\n#else\n    word64 n;\n\n    n  = a[4] >> 48;\n    n += (word64)a[ 5] << 4U; r[ 0] = n & 0xfffffffffffffUL; n >>= 52U;\n    n += (word64)a[ 6] << 4U; r[ 1] = n & 0xfffffffffffffUL; n >>= 52U;\n    n += (word64)a[ 7] << 4U; r[ 2] = n & 0xfffffffffffffUL; n >>= 52U;\n    n += (word64)a[ 8] << 4U; r[ 3] = n & 0xfffffffffffffUL; n >>= 52U;\n    n += (word64)a[ 9] << 4U; r[ 4] = n;\n#endif /* WOLFSSL_SP_SMALL */\n    XMEMSET(&r[5], 0, sizeof(*r) * 5U);\n}\n\n/* Reduce the number back to 256 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nstatic void sp_256_mont_reduce_5(sp_digit* a, const sp_digit* m, sp_digit mp)\n{\n    int i;\n    sp_digit mu;\n\n    if (mp != 1) {\n        for (i=0; i<4; i++) {\n            mu = (a[i] * mp) & 0xfffffffffffffL;\n            sp_256_mul_add_5(a+i, m, mu);\n            a[i+1] += a[i] >> 52;\n        }\n        mu = (a[i] * mp) & 0xffffffffffffL;\n        sp_256_mul_add_5(a+i, m, mu);\n        a[i+1] += a[i] >> 52;\n        a[i] &= 0xfffffffffffffL;\n    }\n    else {\n        for (i=0; i<4; i++) {\n            mu = a[i] & 0xfffffffffffffL;\n            sp_256_mul_add_5(a+i, p256_mod, mu);\n            a[i+1] += a[i] >> 52;\n        }\n        mu = a[i] & 0xffffffffffffL;\n        sp_256_mul_add_5(a+i, p256_mod, mu);\n        a[i+1] += a[i] >> 52;\n        a[i] &= 0xfffffffffffffL;\n    }\n\n    sp_256_mont_shift_5(a, a);\n    sp_256_cond_sub_5(a, a, m, 0 - (((a[4] >> 48) > 0) ?\n            (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_5(a);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_256_mul_5(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[4]) * b[4];\n    r[9] = (sp_digit)(c >> 52);\n    c = (c & 0xfffffffffffffL) << 52;\n    for (k = 7; k >= 0; k--) {\n        for (i = 4; i >= 0; i--) {\n            j = k - i;\n            if (j >= 5) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * b[j];\n        }\n        r[k + 2] += c >> 104;\n        r[k + 1] = (c >> 52) & 0xfffffffffffffL;\n        c = (c & 0xfffffffffffffL) << 52;\n    }\n    r[0] = (sp_digit)(c >> 52);\n}\n\n#else\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_256_mul_5(sp_digit* r, const sp_digit* a,\n    const sp_digit* b)\n{\n    int128_t t0   = ((int128_t)a[ 0]) * b[ 0];\n    int128_t t1   = ((int128_t)a[ 0]) * b[ 1]\n                 + ((int128_t)a[ 1]) * b[ 0];\n    int128_t t2   = ((int128_t)a[ 0]) * b[ 2]\n                 + ((int128_t)a[ 1]) * b[ 1]\n                 + ((int128_t)a[ 2]) * b[ 0];\n    int128_t t3   = ((int128_t)a[ 0]) * b[ 3]\n                 + ((int128_t)a[ 1]) * b[ 2]\n                 + ((int128_t)a[ 2]) * b[ 1]\n                 + ((int128_t)a[ 3]) * b[ 0];\n    int128_t t4   = ((int128_t)a[ 0]) * b[ 4]\n                 + ((int128_t)a[ 1]) * b[ 3]\n                 + ((int128_t)a[ 2]) * b[ 2]\n                 + ((int128_t)a[ 3]) * b[ 1]\n                 + ((int128_t)a[ 4]) * b[ 0];\n    int128_t t5   = ((int128_t)a[ 1]) * b[ 4]\n                 + ((int128_t)a[ 2]) * b[ 3]\n                 + ((int128_t)a[ 3]) * b[ 2]\n                 + ((int128_t)a[ 4]) * b[ 1];\n    int128_t t6   = ((int128_t)a[ 2]) * b[ 4]\n                 + ((int128_t)a[ 3]) * b[ 3]\n                 + ((int128_t)a[ 4]) * b[ 2];\n    int128_t t7   = ((int128_t)a[ 3]) * b[ 4]\n                 + ((int128_t)a[ 4]) * b[ 3];\n    int128_t t8   = ((int128_t)a[ 4]) * b[ 4];\n\n    t1   += t0  >> 52; r[ 0] = t0  & 0xfffffffffffffL;\n    t2   += t1  >> 52; r[ 1] = t1  & 0xfffffffffffffL;\n    t3   += t2  >> 52; r[ 2] = t2  & 0xfffffffffffffL;\n    t4   += t3  >> 52; r[ 3] = t3  & 0xfffffffffffffL;\n    t5   += t4  >> 52; r[ 4] = t4  & 0xfffffffffffffL;\n    t6   += t5  >> 52; r[ 5] = t5  & 0xfffffffffffffL;\n    t7   += t6  >> 52; r[ 6] = t6  & 0xfffffffffffffL;\n    t8   += t7  >> 52; r[ 7] = t7  & 0xfffffffffffffL;\n    r[9] = (sp_digit)(t8 >> 52);\n                       r[8] = t8 & 0xfffffffffffffL;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_mul_5(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_256_mul_5(r, a, b);\n    sp_256_mont_reduce_5(r, m, mp);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_256_sqr_5(sp_digit* r, const sp_digit* a)\n{\n    int i, j, k;\n    int128_t c;\n\n    c = ((int128_t)a[4]) * a[4];\n    r[9] = (sp_digit)(c >> 52);\n    c = (c & 0xfffffffffffffL) << 52;\n    for (k = 7; k >= 0; k--) {\n        for (i = 4; i >= 0; i--) {\n            j = k - i;\n            if (j >= 5 || i <= j) {\n                break;\n            }\n            if (j < 0) {\n                continue;\n            }\n\n            c += ((int128_t)a[i]) * a[j] * 2;\n        }\n        if (i == j) {\n           c += ((int128_t)a[i]) * a[i];\n        }\n\n        r[k + 2] += c >> 104;\n        r[k + 1] = (c >> 52) & 0xfffffffffffffL;\n        c = (c & 0xfffffffffffffL) << 52;\n    }\n    r[0] = (sp_digit)(c >> 52);\n}\n\n#else\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_256_sqr_5(sp_digit* r, const sp_digit* a)\n{\n    int128_t t0   =  ((int128_t)a[ 0]) * a[ 0];\n    int128_t t1   = (((int128_t)a[ 0]) * a[ 1]) * 2;\n    int128_t t2   = (((int128_t)a[ 0]) * a[ 2]) * 2\n                 +  ((int128_t)a[ 1]) * a[ 1];\n    int128_t t3   = (((int128_t)a[ 0]) * a[ 3]\n                 +  ((int128_t)a[ 1]) * a[ 2]) * 2;\n    int128_t t4   = (((int128_t)a[ 0]) * a[ 4]\n                 +  ((int128_t)a[ 1]) * a[ 3]) * 2\n                 +  ((int128_t)a[ 2]) * a[ 2];\n    int128_t t5   = (((int128_t)a[ 1]) * a[ 4]\n                 +  ((int128_t)a[ 2]) * a[ 3]) * 2;\n    int128_t t6   = (((int128_t)a[ 2]) * a[ 4]) * 2\n                 +  ((int128_t)a[ 3]) * a[ 3];\n    int128_t t7   = (((int128_t)a[ 3]) * a[ 4]) * 2;\n    int128_t t8   =  ((int128_t)a[ 4]) * a[ 4];\n\n    t1   += t0  >> 52; r[ 0] = t0  & 0xfffffffffffffL;\n    t2   += t1  >> 52; r[ 1] = t1  & 0xfffffffffffffL;\n    t3   += t2  >> 52; r[ 2] = t2  & 0xfffffffffffffL;\n    t4   += t3  >> 52; r[ 3] = t3  & 0xfffffffffffffL;\n    t5   += t4  >> 52; r[ 4] = t4  & 0xfffffffffffffL;\n    t6   += t5  >> 52; r[ 5] = t5  & 0xfffffffffffffL;\n    t7   += t6  >> 52; r[ 6] = t6  & 0xfffffffffffffL;\n    t8   += t7  >> 52; r[ 7] = t7  & 0xfffffffffffffL;\n    r[9] = (sp_digit)(t8 >> 52);\n                       r[8] = t8 & 0xfffffffffffffL;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_sqr_5(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_256_sqr_5(r, a);\n    sp_256_mont_reduce_5(r, m, mp);\n}\n\n#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)\n/* Square the Montgomery form number a number of times. (r = a ^ n mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * n   Number of times to square.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_sqr_n_5(sp_digit* r, const sp_digit* a, int n,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_256_mont_sqr_5(r, a, m, mp);\n    for (; n > 1; n--) {\n        sp_256_mont_sqr_5(r, r, m, mp);\n    }\n}\n\n#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */\n#ifdef WOLFSSL_SP_SMALL\n/* Mod-2 for the P256 curve. */\nstatic const uint64_t p256_mod_2[4] = {\n    0xfffffffffffffffdU,0x00000000ffffffffU,0x0000000000000000U,\n    0xffffffff00000001U\n};\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the modulus (prime) of the\n * P256 curve. (r = 1 / a mod m)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_5(sp_digit* r, const sp_digit* a, sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 5);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_5(t, t, p256_mod, p256_mp_mod);\n        if (p256_mod_2[i / 64] & ((sp_digit)1 << (i % 64)))\n            sp_256_mont_mul_5(t, t, a, p256_mod, p256_mp_mod);\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 5);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 5;\n    sp_digit* t3 = td + 4 * 5;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_5(t, a, p256_mod, p256_mp_mod);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_5(t, t, a, p256_mod, p256_mp_mod);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_5(t2, t, 2, p256_mod, p256_mp_mod);\n    /* t3= a^d = t2 * a */\n    sp_256_mont_mul_5(t3, t2, a, p256_mod, p256_mp_mod);\n    /* t = a^f = t2 * t */\n    sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^f0 = t ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_5(t2, t, 4, p256_mod, p256_mp_mod);\n    /* t3= a^fd = t2 * t3 */\n    sp_256_mont_mul_5(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ff = t2 * t */\n    sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_5(t2, t, 8, p256_mod, p256_mp_mod);\n    /* t3= a^fffd = t2 * t3 */\n    sp_256_mont_mul_5(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_5(t2, t, 16, p256_mod, p256_mp_mod);\n    /* t3= a^fffffffd = t2 * t3 */\n    sp_256_mont_mul_5(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff00000000 = t ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_5(t2, t, 32, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001 = t2 * a */\n    sp_256_mont_mul_5(t2, t2, a, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff000000010000000000000000000000000000000000000000\n     *   = t2 ^ 2 ^ 160 */\n    sp_256_mont_sqr_n_5(t2, t2, 160, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff\n     *   = t2 * t */\n    sp_256_mont_mul_5(t2, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000\n     *   = t2 ^ 2 ^ 32 */\n    sp_256_mont_sqr_n_5(t2, t2, 32, p256_mod, p256_mp_mod);\n    /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd\n     *   = t2 * t3 */\n    sp_256_mont_mul_5(r, t2, t3, p256_mod, p256_mp_mod);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Map the Montgomery form projective co-ordinate point to an affine point.\n *\n * r  Resulting affine co-ordinate point.\n * p  Montgomery form projective co-ordinate point.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_map_5(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*5;\n    int64_t n;\n\n    sp_256_mont_inv_5(t1, p->z, t + 2*5);\n\n    sp_256_mont_sqr_5(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_5(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    /* x /= z^2 */\n    sp_256_mont_mul_5(r->x, p->x, t2, p256_mod, p256_mp_mod);\n    XMEMSET(r->x + 5, 0, sizeof(r->x) / 2U);\n    sp_256_mont_reduce_5(r->x, p256_mod, p256_mp_mod);\n    /* Reduce x to less than modulus */\n    n = sp_256_cmp_5(r->x, p256_mod);\n    sp_256_cond_sub_5(r->x, r->x, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_5(r->x);\n\n    /* y /= z^3 */\n    sp_256_mont_mul_5(r->y, p->y, t1, p256_mod, p256_mp_mod);\n    XMEMSET(r->y + 5, 0, sizeof(r->y) / 2U);\n    sp_256_mont_reduce_5(r->y, p256_mod, p256_mp_mod);\n    /* Reduce y to less than modulus */\n    n = sp_256_cmp_5(r->y, p256_mod);\n    sp_256_cond_sub_5(r->y, r->y, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_5(r->y);\n\n    XMEMSET(r->z, 0, sizeof(r->z));\n    r->z[0] = 1;\n\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_256_add_5(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 5; i++) {\n        r[i] = a[i] + b[i];\n    }\n\n    return 0;\n}\n#else\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_256_add_5(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    r[ 0] = a[ 0] + b[ 0];\n    r[ 1] = a[ 1] + b[ 1];\n    r[ 2] = a[ 2] + b[ 2];\n    r[ 3] = a[ 3] + b[ 3];\n    r[ 4] = a[ 4] + b[ 4];\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Add two Montgomery form numbers (r = a + b % m).\n *\n * r   Result of addition.\n * a   First number to add in Montogmery form.\n * b   Second number to add in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_add_5(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m)\n{\n    (void)sp_256_add_5(r, a, b);\n    sp_256_norm_5(r);\n    sp_256_cond_sub_5(r, r, m, 0 - (((r[4] >> 48) > 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_5(r);\n}\n\n/* Double a Montgomery form number (r = a + a % m).\n *\n * r   Result of doubling.\n * a   Number to double in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_dbl_5(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    (void)sp_256_add_5(r, a, a);\n    sp_256_norm_5(r);\n    sp_256_cond_sub_5(r, r, m, 0 - (((r[4] >> 48) > 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_5(r);\n}\n\n/* Triple a Montgomery form number (r = a + a + a % m).\n *\n * r   Result of Tripling.\n * a   Number to triple in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_tpl_5(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    (void)sp_256_add_5(r, a, a);\n    sp_256_norm_5(r);\n    sp_256_cond_sub_5(r, r, m, 0 - (((r[4] >> 48) > 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_5(r);\n    (void)sp_256_add_5(r, r, a);\n    sp_256_norm_5(r);\n    sp_256_cond_sub_5(r, r, m, 0 - (((r[4] >> 48) > 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_5(r);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_256_sub_5(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    int i;\n\n    for (i = 0; i < 5; i++) {\n        r[i] = a[i] - b[i];\n    }\n\n    return 0;\n}\n\n#else\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static int sp_256_sub_5(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    r[ 0] = a[ 0] - b[ 0];\n    r[ 1] = a[ 1] - b[ 1];\n    r[ 2] = a[ 2] - b[ 2];\n    r[ 3] = a[ 3] - b[ 3];\n    r[ 4] = a[ 4] - b[ 4];\n\n    return 0;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Conditionally add a and b using the mask m.\n * m is -1 to add and 0 when not.\n *\n * r  A single precision number representing conditional add result.\n * a  A single precision number to add with.\n * b  A single precision number to add.\n * m  Mask value to apply.\n */\nstatic void sp_256_cond_add_5(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, const sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i = 0; i < 5; i++) {\n        r[i] = a[i] + (b[i] & m);\n    }\n#else\n    r[ 0] = a[ 0] + (b[ 0] & m);\n    r[ 1] = a[ 1] + (b[ 1] & m);\n    r[ 2] = a[ 2] + (b[ 2] & m);\n    r[ 3] = a[ 3] + (b[ 3] & m);\n    r[ 4] = a[ 4] + (b[ 4] & m);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Subtract two Montgomery form numbers (r = a - b % m).\n *\n * r   Result of subtration.\n * a   Number to subtract from in Montogmery form.\n * b   Number to subtract with in Montogmery form.\n * m   Modulus (prime).\n */\nstatic void sp_256_mont_sub_5(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m)\n{\n    (void)sp_256_sub_5(r, a, b);\n    sp_256_cond_add_5(r, r, m, r[4] >> 48);\n    sp_256_norm_5(r);\n}\n\n/* Shift number left one bit.\n * Bottom bit is lost.\n *\n * r  Result of shift.\n * a  Number to shift.\n */\nSP_NOINLINE static void sp_256_rshift1_5(sp_digit* r, sp_digit* a)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<4; i++) {\n        r[i] = ((a[i] >> 1) | (a[i + 1] << 51)) & 0xfffffffffffffL;\n    }\n#else\n    r[0] = ((a[0] >> 1) | (a[1] << 51)) & 0xfffffffffffffL;\n    r[1] = ((a[1] >> 1) | (a[2] << 51)) & 0xfffffffffffffL;\n    r[2] = ((a[2] >> 1) | (a[3] << 51)) & 0xfffffffffffffL;\n    r[3] = ((a[3] >> 1) | (a[4] << 51)) & 0xfffffffffffffL;\n#endif\n    r[4] = a[4] >> 1;\n}\n\n/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)\n *\n * r  Result of division by 2.\n * a  Number to divide.\n * m  Modulus (prime).\n */\nstatic void sp_256_div2_5(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    sp_256_cond_add_5(r, a, m, 0 - (a[0] & 1));\n    sp_256_norm_5(r);\n    sp_256_rshift1_5(r, r);\n}\n\n/* Double the Montgomery form projective point p.\n *\n * r  Result of doubling point.\n * p  Point to double.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_5(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*5;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* When infinity don't double point passed in - constant time. */\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    /* Put point to double into result - good for infinty. */\n    if (r != p) {\n        for (i=0; i<5; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<5; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<5; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* T1 = Z * Z */\n    sp_256_mont_sqr_5(t1, z, p256_mod, p256_mp_mod);\n    /* Z = Y * Z */\n    sp_256_mont_mul_5(z, y, z, p256_mod, p256_mp_mod);\n    /* Z = 2Z */\n    sp_256_mont_dbl_5(z, z, p256_mod);\n    /* T2 = X - T1 */\n    sp_256_mont_sub_5(t2, x, t1, p256_mod);\n    /* T1 = X + T1 */\n    sp_256_mont_add_5(t1, x, t1, p256_mod);\n    /* T2 = T1 * T2 */\n    sp_256_mont_mul_5(t2, t1, t2, p256_mod, p256_mp_mod);\n    /* T1 = 3T2 */\n    sp_256_mont_tpl_5(t1, t2, p256_mod);\n    /* Y = 2Y */\n    sp_256_mont_dbl_5(y, y, p256_mod);\n    /* Y = Y * Y */\n    sp_256_mont_sqr_5(y, y, p256_mod, p256_mp_mod);\n    /* T2 = Y * Y */\n    sp_256_mont_sqr_5(t2, y, p256_mod, p256_mp_mod);\n    /* T2 = T2/2 */\n    sp_256_div2_5(t2, t2, p256_mod);\n    /* Y = Y * X */\n    sp_256_mont_mul_5(y, y, x, p256_mod, p256_mp_mod);\n    /* X = T1 * T1 */\n    sp_256_mont_mul_5(x, t1, t1, p256_mod, p256_mp_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_5(x, x, y, p256_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_5(x, x, y, p256_mod);\n    /* Y = Y - X */\n    sp_256_mont_sub_5(y, y, x, p256_mod);\n    /* Y = Y * T1 */\n    sp_256_mont_mul_5(y, y, t1, p256_mod, p256_mp_mod);\n    /* Y = Y - T2 */\n    sp_256_mont_sub_5(y, y, t2, p256_mod);\n\n}\n\n/* Compare two numbers to determine if they are equal.\n * Constant time implementation.\n *\n * a  First number to compare.\n * b  Second number to compare.\n * returns 1 when equal and 0 otherwise.\n */\nstatic int sp_256_cmp_equal_5(const sp_digit* a, const sp_digit* b)\n{\n    return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) |\n            (a[4] ^ b[4])) == 0;\n}\n\n/* Add two Montgomery form projective points.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_5(sp_point* r, const sp_point* p, const sp_point* q,\n        sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*5;\n    sp_digit* t3 = t + 4*5;\n    sp_digit* t4 = t + 6*5;\n    sp_digit* t5 = t + 8*5;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Ensure only the first point is the same as the result. */\n    if (q == r) {\n        const sp_point* a = p;\n        p = q;\n        q = a;\n    }\n\n    /* Check double */\n    (void)sp_256_sub_5(t1, p256_mod, q->y);\n    sp_256_norm_5(t1);\n    if ((sp_256_cmp_equal_5(p->x, q->x) & sp_256_cmp_equal_5(p->z, q->z) &\n        (sp_256_cmp_equal_5(p->y, q->y) | sp_256_cmp_equal_5(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_5(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<5; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<5; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<5; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U1 = X1*Z2^2 */\n        sp_256_mont_sqr_5(t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(t3, t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(t1, t1, x, p256_mod, p256_mp_mod);\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_5(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S1 = Y1*Z2^3 */\n        sp_256_mont_mul_5(t3, t3, y, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_5(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - U1 */\n        sp_256_mont_sub_5(t2, t2, t1, p256_mod);\n        /* R = S2 - S1 */\n        sp_256_mont_sub_5(t4, t4, t3, p256_mod);\n        /* Z3 = H*Z1*Z2 */\n        sp_256_mont_mul_5(z, z, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*U1*H^2 */\n        sp_256_mont_sqr_5(x, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_5(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(y, t1, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_5(x, x, t5, p256_mod);\n        sp_256_mont_dbl_5(t1, y, p256_mod);\n        sp_256_mont_sub_5(x, x, t1, p256_mod);\n        /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */\n        sp_256_mont_sub_5(y, y, x, p256_mod);\n        sp_256_mont_mul_5(y, y, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(t5, t5, t3, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_5(y, y, t5, p256_mod);\n    }\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n    sp_point* td;\n    sp_point* t[3];\n    sp_digit* tmp;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    (void)heap;\n\n    td = (sp_point*)XMALLOC(sizeof(sp_point) * 3, heap, DYNAMIC_TYPE_ECC);\n    if (td == NULL)\n        err = MEMORY_E;\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap,\n                                                              DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n\n    if (err == MP_OKAY) {\n        XMEMSET(td, 0, sizeof(*td) * 3);\n\n        t[0] = &td[0];\n        t[1] = &td[1];\n        t[2] = &td[2];\n\n        /* t[0] = {0, 0, 1} * norm */\n        t[0]->infinity = 1;\n        /* t[1] = {g->x, g->y, g->z} * norm */\n        err = sp_256_mod_mul_norm_5(t[1]->x, g->x, p256_mod);\n    }\n    if (err == MP_OKAY)\n        err = sp_256_mod_mul_norm_5(t[1]->y, g->y, p256_mod);\n    if (err == MP_OKAY)\n        err = sp_256_mod_mul_norm_5(t[1]->z, g->z, p256_mod);\n\n    if (err == MP_OKAY) {\n        i = 4;\n        c = 48;\n        n = k[i--] << (52 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1)\n                    break;\n\n                n = k[i--];\n                c = 52;\n            }\n\n            y = (n >> 51) & 1;\n            n <<= 1;\n\n            sp_256_proj_point_add_5(t[y^1], t[0], t[1], tmp);\n\n            XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) +\n                                  ((size_t)t[1] & addr_mask[y])),\n                    sizeof(sp_point));\n            sp_256_proj_point_dbl_5(t[2], t[2], tmp);\n            XMEMCPY((void*)(((size_t)t[0] & addr_mask[y^1]) +\n                            ((size_t)t[1] & addr_mask[y])), t[2],\n                    sizeof(sp_point));\n        }\n\n        if (map != 0) {\n            sp_256_map_5(r, t[0], tmp);\n        }\n        else {\n            XMEMCPY(r, t[0], sizeof(sp_point));\n        }\n    }\n\n    if (tmp != NULL) {\n        XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 5 * 5);\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n    if (td != NULL) {\n        XMEMSET(td, 0, sizeof(sp_point) * 3);\n        XFREE(td, NULL, DYNAMIC_TYPE_ECC);\n    }\n\n    return err;\n}\n\n#elif defined(WOLFSSL_SP_CACHE_RESISTANT)\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td[3];\n    sp_digit tmpd[2 * 5 * 5];\n#endif\n    sp_point* t;\n    sp_digit* tmp;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n    (void)heap;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_point td[3];\n    t = (sp_point*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC);\n    if (t == NULL)\n        err = MEMORY_E;\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap,\n                             DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n#else\n    t = td;\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        t[0] = &td[0];\n        t[1] = &td[1];\n        t[2] = &td[2];\n\n        /* t[0] = {0, 0, 1} * norm */\n        XMEMSET(&t[0], 0, sizeof(t[0]));\n        t[0].infinity = 1;\n        /* t[1] = {g->x, g->y, g->z} * norm */\n        err = sp_256_mod_mul_norm_5(t[1].x, g->x, p256_mod);\n    }\n    if (err == MP_OKAY)\n        err = sp_256_mod_mul_norm_5(t[1].y, g->y, p256_mod);\n    if (err == MP_OKAY)\n        err = sp_256_mod_mul_norm_5(t[1].z, g->z, p256_mod);\n\n    if (err == MP_OKAY) {\n        i = 4;\n        c = 48;\n        n = k[i--] << (52 - c);\n        for (; ; c--) {\n            if (c == 0) {\n                if (i == -1)\n                    break;\n\n                n = k[i--];\n                c = 52;\n            }\n\n            y = (n >> 51) & 1;\n            n <<= 1;\n\n            sp_256_proj_point_add_5(&t[y^1], &t[0], &t[1], tmp);\n\n            XMEMCPY(&t[2], (void*)(((size_t)&t[0] & addr_mask[y^1]) +\n                                 ((size_t)&t[1] & addr_mask[y])), sizeof(t[2]));\n            sp_256_proj_point_dbl_5(&t[2], &t[2], tmp);\n            XMEMCPY((void*)(((size_t)&t[0] & addr_mask[y^1]) +\n                          ((size_t)&t[1] & addr_mask[y])), &t[2], sizeof(t[2]));\n        }\n\n        if (map != 0) {\n            sp_256_map_5(r, &t[0], tmp);\n        }\n        else {\n            XMEMCPY(r, &t[0], sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 5 * 5);\n        XFREE(tmp, heap, DYNAMIC_TYPE_ECC);\n    }\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_point) * 3);\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    ForceZero(tmpd, sizeof(tmpd));\n    ForceZero(td, sizeof(td));\n#endif\n\n    return err;\n}\n\n#else\n/* A table entry for pre-computed points. */\ntypedef struct sp_table_entry {\n    sp_digit x[5];\n    sp_digit y[5];\n} sp_table_entry;\n\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_fast_5(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td[16];\n    sp_point rtd;\n    sp_digit tmpd[2 * 5 * 5];\n#endif\n    sp_point* t;\n    sp_point* rt;\n    sp_digit* tmp;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_point*)XMALLOC(sizeof(sp_point) * 16, heap, DYNAMIC_TYPE_ECC);\n    if (t == NULL)\n        err = MEMORY_E;\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap,\n                             DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n#else\n    t = td;\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        /* t[0] = {0, 0, 1} * norm */\n        XMEMSET(&t[0], 0, sizeof(t[0]));\n        t[0].infinity = 1;\n        /* t[1] = {g->x, g->y, g->z} * norm */\n        (void)sp_256_mod_mul_norm_5(t[1].x, g->x, p256_mod);\n        (void)sp_256_mod_mul_norm_5(t[1].y, g->y, p256_mod);\n        (void)sp_256_mod_mul_norm_5(t[1].z, g->z, p256_mod);\n        t[1].infinity = 0;\n        sp_256_proj_point_dbl_5(&t[ 2], &t[ 1], tmp);\n        t[ 2].infinity = 0;\n        sp_256_proj_point_add_5(&t[ 3], &t[ 2], &t[ 1], tmp);\n        t[ 3].infinity = 0;\n        sp_256_proj_point_dbl_5(&t[ 4], &t[ 2], tmp);\n        t[ 4].infinity = 0;\n        sp_256_proj_point_add_5(&t[ 5], &t[ 3], &t[ 2], tmp);\n        t[ 5].infinity = 0;\n        sp_256_proj_point_dbl_5(&t[ 6], &t[ 3], tmp);\n        t[ 6].infinity = 0;\n        sp_256_proj_point_add_5(&t[ 7], &t[ 4], &t[ 3], tmp);\n        t[ 7].infinity = 0;\n        sp_256_proj_point_dbl_5(&t[ 8], &t[ 4], tmp);\n        t[ 8].infinity = 0;\n        sp_256_proj_point_add_5(&t[ 9], &t[ 5], &t[ 4], tmp);\n        t[ 9].infinity = 0;\n        sp_256_proj_point_dbl_5(&t[10], &t[ 5], tmp);\n        t[10].infinity = 0;\n        sp_256_proj_point_add_5(&t[11], &t[ 6], &t[ 5], tmp);\n        t[11].infinity = 0;\n        sp_256_proj_point_dbl_5(&t[12], &t[ 6], tmp);\n        t[12].infinity = 0;\n        sp_256_proj_point_add_5(&t[13], &t[ 7], &t[ 6], tmp);\n        t[13].infinity = 0;\n        sp_256_proj_point_dbl_5(&t[14], &t[ 7], tmp);\n        t[14].infinity = 0;\n        sp_256_proj_point_add_5(&t[15], &t[ 8], &t[ 7], tmp);\n        t[15].infinity = 0;\n\n        i = 3;\n        n = k[i+1] << 12;\n        c = 44;\n        y = n >> 56;\n        XMEMCPY(rt, &t[y], sizeof(sp_point));\n        n <<= 8;\n        for (; i>=0 || c>=4; ) {\n            if (c < 4) {\n                n |= k[i--] << (12 - c);\n                c += 52;\n            }\n            y = (n >> 60) & 0xf;\n            n <<= 4;\n            c -= 4;\n\n            sp_256_proj_point_dbl_5(rt, rt, tmp);\n            sp_256_proj_point_dbl_5(rt, rt, tmp);\n            sp_256_proj_point_dbl_5(rt, rt, tmp);\n            sp_256_proj_point_dbl_5(rt, rt, tmp);\n\n            sp_256_proj_point_add_5(rt, rt, &t[y], tmp);\n        }\n\n        if (map != 0) {\n            sp_256_map_5(r, rt, tmp);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 5 * 5);\n        XFREE(tmp, heap, DYNAMIC_TYPE_ECC);\n    }\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_point) * 16);\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    ForceZero(tmpd, sizeof(tmpd));\n    ForceZero(td, sizeof(td));\n#endif\n    sp_ecc_point_free(rt, 1, heap);\n\n    return err;\n}\n\n#ifdef FP_ECC\n/* Double the Montgomery form projective point p a number of times.\n *\n * r  Result of repeated doubling of point.\n * p  Point to double.\n * n  Number of times to double\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_n_5(sp_point* r, const sp_point* p, int n,\n        sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* w = t;\n    sp_digit* a = t + 2*5;\n    sp_digit* b = t + 4*5;\n    sp_digit* t1 = t + 6*5;\n    sp_digit* t2 = t + 8*5;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    if (r != p) {\n        for (i=0; i<5; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<5; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<5; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* Y = 2*Y */\n    sp_256_mont_dbl_5(y, y, p256_mod);\n    /* W = Z^4 */\n    sp_256_mont_sqr_5(w, z, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_5(w, w, p256_mod, p256_mp_mod);\n    while (n-- > 0) {\n        /* A = 3*(X^2 - W) */\n        sp_256_mont_sqr_5(t1, x, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_5(t1, t1, w, p256_mod);\n        sp_256_mont_tpl_5(a, t1, p256_mod);\n        /* B = X*Y^2 */\n        sp_256_mont_sqr_5(t2, y, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(b, t2, x, p256_mod, p256_mp_mod);\n        /* X = A^2 - 2B */\n        sp_256_mont_sqr_5(x, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_5(t1, b, p256_mod);\n        sp_256_mont_sub_5(x, x, t1, p256_mod);\n        /* Z = Z*Y */\n        sp_256_mont_mul_5(z, z, y, p256_mod, p256_mp_mod);\n        /* t2 = Y^4 */\n        sp_256_mont_sqr_5(t2, t2, p256_mod, p256_mp_mod);\n        if (n != 0) {\n            /* W = W*Y^4 */\n            sp_256_mont_mul_5(w, w, t2, p256_mod, p256_mp_mod);\n        }\n        /* y = 2*A*(B - X) - Y^4 */\n        sp_256_mont_sub_5(y, b, x, p256_mod);\n        sp_256_mont_mul_5(y, y, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_5(y, y, p256_mod);\n        sp_256_mont_sub_5(y, y, t2, p256_mod);\n    }\n    /* Y = Y/2 */\n    sp_256_div2_5(y, y, p256_mod);\n}\n\n#endif /* FP_ECC */\n/* Add two Montgomery form projective points. The second point has a q value of\n * one.\n * Only the first point can be the same pointer as the result point.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_qz1_5(sp_point* r, const sp_point* p,\n        const sp_point* q, sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*5;\n    sp_digit* t3 = t + 4*5;\n    sp_digit* t4 = t + 6*5;\n    sp_digit* t5 = t + 8*5;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Check double */\n    (void)sp_256_sub_5(t1, p256_mod, q->y);\n    sp_256_norm_5(t1);\n    if ((sp_256_cmp_equal_5(p->x, q->x) & sp_256_cmp_equal_5(p->z, q->z) &\n        (sp_256_cmp_equal_5(p->y, q->y) | sp_256_cmp_equal_5(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_5(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<5; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<5; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<5; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_5(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_5(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - X1 */\n        sp_256_mont_sub_5(t2, t2, x, p256_mod);\n        /* R = S2 - Y1 */\n        sp_256_mont_sub_5(t4, t4, y, p256_mod);\n        /* Z3 = H*Z1 */\n        sp_256_mont_mul_5(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*X1*H^2 */\n        sp_256_mont_sqr_5(t1, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_5(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(t3, x, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_5(x, t1, t5, p256_mod);\n        sp_256_mont_dbl_5(t1, t3, p256_mod);\n        sp_256_mont_sub_5(x, x, t1, p256_mod);\n        /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */\n        sp_256_mont_sub_5(t3, t3, x, p256_mod);\n        sp_256_mont_mul_5(t3, t3, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(t5, t5, y, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_5(y, t3, t5, p256_mod);\n    }\n}\n\n#ifdef FP_ECC\n/* Convert the projective point to affine.\n * Ordinates are in Montgomery form.\n *\n * a  Point to convert.\n * t  Temprorary data.\n */\nstatic void sp_256_proj_to_affine_5(sp_point* a, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2 * 5;\n    sp_digit* tmp = t + 4 * 5;\n\n    sp_256_mont_inv_5(t1, a->z, tmp);\n\n    sp_256_mont_sqr_5(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_5(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    sp_256_mont_mul_5(a->x, a->x, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_5(a->y, a->y, t1, p256_mod, p256_mp_mod);\n    XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod));\n}\n\n/* Generate the pre-computed table of points for the base point.\n *\n * a      The base point.\n * table  Place to store generated point data.\n * tmp    Temprorary data.\n * heap  Heap to use for allocation.\n */\nstatic int sp_256_gen_stripe_table_5(const sp_point* a,\n        sp_table_entry* table, sp_digit* tmp, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td, s1d, s2d;\n#endif\n    sp_point* t;\n    sp_point* s1 = NULL;\n    sp_point* s2 = NULL;\n    int i, j;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, td, t);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s1d, s1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s2d, s2);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_5(t->x, a->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_5(t->y, a->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_5(t->z, a->z, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        t->infinity = 0;\n        sp_256_proj_to_affine_5(t, tmp);\n\n        XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s1->infinity = 0;\n        XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s2->infinity = 0;\n\n        /* table[0] = {0, 0, infinity} */\n        XMEMSET(&table[0], 0, sizeof(sp_table_entry));\n        /* table[1] = Affine version of 'a' in Montgomery form */\n        XMEMCPY(table[1].x, t->x, sizeof(table->x));\n        XMEMCPY(table[1].y, t->y, sizeof(table->y));\n\n        for (i=1; i<8; i++) {\n            sp_256_proj_point_dbl_n_5(t, t, 32, tmp);\n            sp_256_proj_to_affine_5(t, tmp);\n            XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));\n            XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));\n        }\n\n        for (i=1; i<8; i++) {\n            XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));\n            XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));\n            for (j=(1<<i)+1; j<(1<<(i+1)); j++) {\n                XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));\n                XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));\n                sp_256_proj_point_add_qz1_5(t, s1, s2, tmp);\n                sp_256_proj_to_affine_5(t, tmp);\n                XMEMCPY(table[j].x, t->x, sizeof(table->x));\n                XMEMCPY(table[j].y, t->y, sizeof(table->y));\n            }\n        }\n    }\n\n    sp_ecc_point_free(s2, 0, heap);\n    sp_ecc_point_free(s1, 0, heap);\n    sp_ecc_point_free( t, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC */\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_stripe_5(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit td[2 * 5 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* t;\n    int i, j;\n    int y, x;\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap,\n                           DYNAMIC_TYPE_ECC);\n    if (t == NULL) {\n        err = MEMORY_E;\n    }\n#else\n    t = td;\n#endif\n\n    if (err == MP_OKAY) {\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        y = 0;\n        for (j=0,x=31; j<8; j++,x+=32) {\n            y |= ((k[x / 52] >> (x % 52)) & 1) << j;\n        }\n        XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));\n        XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));\n        rt->infinity = !y;\n        for (i=30; i>=0; i--) {\n            y = 0;\n            for (j=0,x=i; j<8; j++,x+=32) {\n                y |= ((k[x / 52] >> (x % 52)) & 1) << j;\n            }\n\n            sp_256_proj_point_dbl_5(rt, rt, t);\n            XMEMCPY(p->x, table[y].x, sizeof(table[y].x));\n            XMEMCPY(p->y, table[y].y, sizeof(table[y].y));\n            p->infinity = !y;\n            sp_256_proj_point_add_qz1_5(rt, rt, p, t);\n        }\n\n        if (map != 0) {\n            sp_256_map_5(r, rt, t);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n#ifdef FP_ECC\n#ifndef FP_ENTRIES\n    #define FP_ENTRIES 16\n#endif\n\ntypedef struct sp_cache_t {\n    sp_digit x[5];\n    sp_digit y[5];\n    sp_table_entry table[256];\n    uint32_t cnt;\n    int set;\n} sp_cache_t;\n\nstatic THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES];\nstatic THREAD_LS_T int sp_cache_last = -1;\nstatic THREAD_LS_T int sp_cache_inited = 0;\n\n#ifndef HAVE_THREAD_LS\n    static volatile int initCacheMutex = 0;\n    static wolfSSL_Mutex sp_cache_lock;\n#endif\n\nstatic void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache)\n{\n    int i, j;\n    uint32_t least;\n\n    if (sp_cache_inited == 0) {\n        for (i=0; i<FP_ENTRIES; i++) {\n            sp_cache[i].set = 0;\n        }\n        sp_cache_inited = 1;\n    }\n\n    /* Compare point with those in cache. */\n    for (i=0; i<FP_ENTRIES; i++) {\n        if (!sp_cache[i].set)\n            continue;\n\n        if (sp_256_cmp_equal_5(g->x, sp_cache[i].x) &\n                           sp_256_cmp_equal_5(g->y, sp_cache[i].y)) {\n            sp_cache[i].cnt++;\n            break;\n        }\n    }\n\n    /* No match. */\n    if (i == FP_ENTRIES) {\n        /* Find empty entry. */\n        i = (sp_cache_last + 1) % FP_ENTRIES;\n        for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) {\n            if (!sp_cache[i].set) {\n                break;\n            }\n        }\n\n        /* Evict least used. */\n        if (i == sp_cache_last) {\n            least = sp_cache[0].cnt;\n            for (j=1; j<FP_ENTRIES; j++) {\n                if (sp_cache[j].cnt < least) {\n                    i = j;\n                    least = sp_cache[i].cnt;\n                }\n            }\n        }\n\n        XMEMCPY(sp_cache[i].x, g->x, sizeof(sp_cache[i].x));\n        XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y));\n        sp_cache[i].set = 1;\n        sp_cache[i].cnt = 1;\n    }\n\n    *cache = &sp_cache[i];\n    sp_cache_last = i;\n}\n#endif /* FP_ECC */\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#ifndef FP_ECC\n    return sp_256_ecc_mulmod_fast_5(r, g, k, map, heap);\n#else\n    sp_digit tmp[2 * 5 * 5];\n    sp_cache_t* cache;\n    int err = MP_OKAY;\n\n#ifndef HAVE_THREAD_LS\n    if (initCacheMutex == 0) {\n         wc_InitMutex(&sp_cache_lock);\n         initCacheMutex = 1;\n    }\n    if (wc_LockMutex(&sp_cache_lock) != 0)\n       err = BAD_MUTEX_E;\n#endif /* HAVE_THREAD_LS */\n\n    if (err == MP_OKAY) {\n        sp_ecc_get_cache(g, &cache);\n        if (cache->cnt == 2)\n            sp_256_gen_stripe_table_5(g, cache->table, tmp, heap);\n\n#ifndef HAVE_THREAD_LS\n        wc_UnLockMutex(&sp_cache_lock);\n#endif /* HAVE_THREAD_LS */\n\n        if (cache->cnt < 2) {\n            err = sp_256_ecc_mulmod_fast_5(r, g, k, map, heap);\n        }\n        else {\n            err = sp_256_ecc_mulmod_stripe_5(r, g, cache->table, k,\n                    map, heap);\n        }\n    }\n\n    return err;\n#endif\n}\n\n#endif\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * p     Point to multiply.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map,\n        void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[5];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 5, km);\n        sp_256_point_from_ecc_point_5(point, gm);\n\n            err = sp_256_ecc_mulmod_5(point, point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_5(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_5(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    /* No pre-computed values. */\n    return sp_256_ecc_mulmod_5(r, &p256_base, k, map, heap);\n}\n\n#else\nstatic const sp_table_entry p256_table[256] = {\n    /* 0 */\n    { { 0x00, 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 */\n    { { 0x730d418a9143cL,0xfc5fedb60179eL,0x762251075ba95L,0x55c679fb732b7L,\n        0x018905f76a537L },\n      { 0x25357ce95560aL,0xe4ba19e45cddfL,0xd21f3258b4ab8L,0x5d85d2e88688dL,\n        0x08571ff182588L } },\n    /* 2 */\n    { { 0x886024147519aL,0xac26b372f0202L,0x785ebc8d0981eL,0x58e9a9d4a7caaL,\n        0x0d953c50ddbdfL },\n      { 0x361ccfd590f8fL,0x6b44e6c9179d6L,0x2eb64cf72e962L,0x88f37fd961102L,\n        0x0863ebb7e9eb2L } },\n    /* 3 */\n    { { 0x6b6235cdb6485L,0xa22f0a2f97785L,0xf7e300b808f0eL,0x80a03e68d9544L,\n        0x000076055b5ffL },\n      { 0x4eb9b838d2010L,0xbb3243708a763L,0x42a660654014fL,0x3ee0e0e47d398L,\n        0x0830877613437L } },\n    /* 4 */\n    { { 0x22fc516a0d2bbL,0x6c1a6234994f9L,0x7c62c8b0d5cc1L,0x667f9241cf3a5L,\n        0x02f5e6961fd1bL },\n      { 0x5c70bf5a01797L,0x4d609561925c1L,0x71fdb523d20b4L,0x0f7b04911b370L,\n        0x0f648f9168d6fL } },\n    /* 5 */\n    { { 0x66847e137bbbcL,0x9e8a6a0bec9e5L,0x9d73463e43446L,0x0015b1c427617L,\n        0x05abe0285133dL },\n      { 0xa837cc04c7dabL,0x4c43260c0792aL,0x8e6cc37573d9fL,0x73830c9315627L,\n        0x094bb725b6b6fL } },\n    /* 6 */\n    { { 0x9b48f720f141cL,0xcd2df5bc74bbfL,0x11045c46199b3L,0xc4efdc3f61294L,\n        0x0cdd6bbcb2f7dL },\n      { 0x6700beaf436fdL,0x6db99326beccaL,0x14f25226f647fL,0xe5f60c0fa7920L,\n        0x0a361bebd4bdaL } },\n    /* 7 */\n    { { 0xa2558597c13c7L,0x5f50b7c3e128aL,0x3c09d1dc38d63L,0x292c07039aecfL,\n        0x0ba12ca09c4b5L },\n      { 0x08fa459f91dfdL,0x66ceea07fb9e4L,0xd780b293af43bL,0xef4b1eceb0899L,\n        0x053ebb99d701fL } },\n    /* 8 */\n    { { 0x7ee31b0e63d34L,0x72a9e54fab4feL,0x5e7b5a4f46005L,0x4831c0493334dL,\n        0x08589fb9206d5L },\n      { 0x0f5cc6583553aL,0x4ae25649e5aa7L,0x0044652087909L,0x1c4fcc9045071L,\n        0x0ebb0696d0254L } },\n    /* 9 */\n    { { 0x6ca15ac1647c5L,0x47c4cf5799461L,0x64dfbacb8127dL,0x7da3dc666aa37L,\n        0x0eb2820cbd1b2L },\n      { 0x6f8d86a87e008L,0x9d922378f3940L,0x0ccecb2d87dfaL,0xda1d56ed2e428L,\n        0x01f28289b55a7L } },\n    /* 10 */\n    { { 0xaa0c03b89da99L,0x9eb8284022abbL,0x81c05e8a6f2d7L,0x4d6327847862bL,\n        0x0337a4b5905e5L },\n      { 0x7500d21f7794aL,0xb77d6d7f613c6L,0x4cfd6e8207005L,0xfbd60a5a37810L,\n        0x00d65e0d5f4c2L } },\n    /* 11 */\n    { { 0x09bbeb5275d38L,0x450be0a358d9dL,0x73eb2654268a7L,0xa232f0762ff49L,\n        0x0c23da24252f4L },\n      { 0x1b84f0b94520cL,0x63b05bd78e5daL,0x4d29ea1096667L,0xcff13a4dcb869L,\n        0x019de3b8cc790L } },\n    /* 12 */\n    { { 0xa716c26c5fe04L,0x0b3bba1bdb183L,0x4cb712c3b28deL,0xcbfd7432c586aL,\n        0x0e34dcbd491fcL },\n      { 0x8d46baaa58403L,0x8682e97a53b40L,0x6aaa8af9a6974L,0x0f7f9e3901273L,\n        0x0e7641f447b4eL } },\n    /* 13 */\n    { { 0x53941df64ba59L,0xec0b0242fc7d7L,0x1581859d33f10L,0x57bf4f06dfc6aL,\n        0x04a12df57052aL },\n      { 0x6338f9439dbd0L,0xd4bde53e1fbfaL,0x1f1b314d3c24bL,0xea46fd5e4ffa2L,\n        0x06af5aa93bb5bL } },\n    /* 14 */\n    { { 0x0b69910c91999L,0x402a580491da1L,0x8cc20900a24b4L,0x40133e0094b4bL,\n        0x05fe3475a66a4L },\n      { 0x8cabdf93e7b4bL,0x1a7c23f91ab0fL,0xd1e6263292b50L,0xa91642e889aecL,\n        0x0b544e308ecfeL } },\n    /* 15 */\n    { { 0x8c6e916ddfdceL,0x66f89179e6647L,0xd4e67e12c3291L,0xc20b4e8d6e764L,\n        0x0e0b6b2bda6b0L },\n      { 0x12df2bb7efb57L,0xde790c40070d3L,0x79bc9441aac0dL,0x3774f90336ad6L,\n        0x071c023de25a6L } },\n    /* 16 */\n    { { 0x8c244bfe20925L,0xc38fdce86762aL,0xd38706391c19aL,0x24f65a96a5d5dL,\n        0x061d587d421d3L },\n      { 0x673a2a37173eaL,0x0853778b65e87L,0x5bab43e238480L,0xefbe10f8441e0L,\n        0x0fa11fe124621L } },\n    /* 17 */\n    { { 0x91f2b2cb19ffdL,0x5bb1923c231c8L,0xac5ca8e01ba8dL,0xbedcb6d03d678L,\n        0x0586eb04c1f13L },\n      { 0x5c6e527e8ed09L,0x3c1819ede20c3L,0x6c652fa1e81a3L,0x4f11278fd6c05L,\n        0x019d5ac087086L } },\n    /* 18 */\n    { { 0x9f581309a4e1fL,0x1be92700741e9L,0xfd28d20ab7de7L,0x563f26a5ef0beL,\n        0x0e7c0073f7f9cL },\n      { 0xd663a0ef59f76L,0x5420fcb0501f6L,0xa6602d4669b3bL,0x3c0ac08c1f7a7L,\n        0x0e08504fec65bL } },\n    /* 19 */\n    { { 0x8f68da031b3caL,0x9ee6da6d66f09L,0x4f246e86d1cabL,0x96b45bfd81fa9L,\n        0x078f018825b09L },\n      { 0xefde43a25787fL,0x0d1dccac9bb7eL,0x35bfc368016f8L,0x747a0cea4877bL,\n        0x043a773b87e94L } },\n    /* 20 */\n    { { 0x77734d2b533d5L,0xf6a1bdddc0625L,0x79ec293673b8aL,0x66b1577e7c9aaL,\n        0x0bb6de651c3b2L },\n      { 0x9303ab65259b3L,0xd3d03a7480e7eL,0xb3cfc27d6a0afL,0xb99bc5ac83d19L,\n        0x060b4619a5d18L } },\n    /* 21 */\n    { { 0xa38e11ae5aa1cL,0x2b49e73658bd6L,0xe5f87edb8b765L,0xffcd0b130014eL,\n        0x09d0f27b2aeebL },\n      { 0x246317a730a55L,0x2fddbbc83aca9L,0xc019a719c955bL,0xc48d07c1dfe0aL,\n        0x0244a566d356eL } },\n    /* 22 */\n    { { 0x0394aeacf1f96L,0xa9024c271c6dbL,0x2cbd3b99f2122L,0xef692626ac1b8L,\n        0x045e58c873581L },\n      { 0xf479da38f9dbcL,0x46e888a040d3fL,0x6e0bed7a8aaf1L,0xb7a4945adfb24L,\n        0x0c040e21cc1e4L } },\n    /* 23 */\n    { { 0xaf0006f8117b6L,0xff73a35433847L,0xd9475eb651969L,0x6ec7482b35761L,\n        0x01cdf5c97682cL },\n      { 0x775b411f04839L,0xf448de16987dbL,0x70b32197dbeacL,0xff3db2921dd1bL,\n        0x0046755f8a92dL } },\n    /* 24 */\n    { { 0xac5d2bce8ffcdL,0x8b2fe61a82cc8L,0x202d6c70d53c4L,0xa5f3f6f161727L,\n        0x0046e5e113b83L },\n      { 0x8ff64d8007f01L,0x125af43183e7bL,0x5e1a03c7fb1efL,0x005b045c5ea63L,\n        0x06e0106c3303dL } },\n    /* 25 */\n    { { 0x7358488dd73b1L,0x8f995ed0d948cL,0x56a2ab7767070L,0xcf1f38385ea8cL,\n        0x0442594ede901L },\n      { 0xaa2c912d4b65bL,0x3b96c90c37f8fL,0xe978d1f94c234L,0xe68ed326e4a15L,\n        0x0a796fa514c2eL } },\n    /* 26 */\n    { { 0xfb604823addd7L,0x83e56693b3359L,0xcbf3c809e2a61L,0x66e9f885b78e3L,\n        0x0e4ad2da9c697L },\n      { 0xf7f428e048a61L,0x8cc092d9a0357L,0x03ed8ef082d19L,0x5143fc3a1af4cL,\n        0x0c5e94046c37bL } },\n    /* 27 */\n    { { 0xa538c2be75f9eL,0xe8cb123a78476L,0x109c04b6fd1a9L,0x4747d85e4df0bL,\n        0x063283dafdb46L },\n      { 0x28cf7baf2df15L,0x550ad9a7f4ce7L,0x834bcc3e592c4L,0xa938fab226adeL,\n        0x068bd19ab1981L } },\n    /* 28 */\n    { { 0xead511887d659L,0xf4b359305ac08L,0xfe74fe33374d5L,0xdfd696986981cL,\n        0x0495292f53c6fL },\n      { 0x78c9e1acec896L,0x10ec5b44844a8L,0x64d60a7d964b2L,0x68376696f7e26L,\n        0x00ec7530d2603L } },\n    /* 29 */\n    { { 0x13a05ad2687bbL,0x6af32e21fa2daL,0xdd4607ba1f83bL,0x3f0b390f5ef51L,\n        0x00f6207a66486L },\n      { 0x7e3bb0f138233L,0x6c272aa718bd6L,0x6ec88aedd66b9L,0x6dcf8ed004072L,\n        0x0ff0db07208edL } },\n    /* 30 */\n    { { 0xfa1014c95d553L,0xfd5d680a8a749L,0xf3b566fa44052L,0x0ea3183b4317fL,\n        0x0313b513c8874L },\n      { 0x2e2ac08d11549L,0x0bb4dee21cb40L,0x7f2320e071ee1L,0x9f8126b987dd4L,\n        0x02d3abcf986f1L } },\n    /* 31 */\n    { { 0x88501815581a2L,0x56632211af4c2L,0xcab2e999a0a6dL,0x8cdf19ba7a0f0L,\n        0x0c036fa10ded9L },\n      { 0xe08bac1fbd009L,0x9006d1581629aL,0xb9e0d8f0b68b1L,0x0194c2eb32779L,\n        0x0a6b2a2c4b6d4L } },\n    /* 32 */\n    { { 0x3e50f6d3549cfL,0x6ffacd665ed43L,0xe11fcb46f3369L,0x9860695bfdaccL,\n        0x0810ee252af7cL },\n      { 0x50fe17159bb2cL,0xbe758b357b654L,0x69fea72f7dfbeL,0x17452b057e74dL,\n        0x0d485717a9273L } },\n    /* 33 */\n    { { 0x41a8af0cb5a98L,0x931f3110bf117L,0xb382adfd3da8fL,0x604e1994e2cbaL,\n        0x06a6045a72f9aL },\n      { 0xc0d3fa2b2411dL,0x3e510e96e0170L,0x865b3ccbe0eb8L,0x57903bcc9f738L,\n        0x0d3e45cfaf9e1L } },\n    /* 34 */\n    { { 0xf69bbe83f7669L,0x8272877d6bce1L,0x244278d09f8aeL,0xc19c9548ae543L,\n        0x0207755dee3c2L },\n      { 0xd61d96fef1945L,0xefb12d28c387bL,0x2df64aa18813cL,0xb00d9fbcd1d67L,\n        0x048dc5ee57154L } },\n    /* 35 */\n    { { 0x790bff7e5a199L,0xcf989ccbb7123L,0xa519c79e0efb8L,0xf445c27a2bfe0L,\n        0x0f2fb0aeddff6L },\n      { 0x09575f0b5025fL,0xd740fa9f2241cL,0x80bfbd0550543L,0xd5258fa3c8ad3L,\n        0x0a13e9015db28L } },\n    /* 36 */\n    { { 0x7a350a2b65cbcL,0x722a464226f9fL,0x23f07a10b04b9L,0x526f265ce241eL,\n        0x02bf0d6b01497L },\n      { 0x4dd3f4b216fb7L,0x67fbdda26ad3dL,0x708505cf7d7b8L,0xe89faeb7b83f6L,\n        0x042a94a5a162fL } },\n    /* 37 */\n    { { 0x6ad0beaadf191L,0x9025a268d7584L,0x94dc1f60f8a48L,0xde3de86030504L,\n        0x02c2dd969c65eL },\n      { 0x2171d93849c17L,0xba1da250dd6d0L,0xc3a5485460488L,0x6dbc4810c7063L,\n        0x0f437fa1f42c5L } },\n    /* 38 */\n    { { 0x0d7144a0f7dabL,0x931776e9ac6aaL,0x5f397860f0497L,0x7aa852c0a050fL,\n        0x0aaf45b335470L },\n      { 0x37c33c18d364aL,0x063e49716585eL,0x5ec5444d40b9bL,0x72bcf41716811L,\n        0x0cdf6310df4f2L } },\n    /* 39 */\n    { { 0x3c6238ea8b7efL,0x1885bc2287747L,0xbda8e3408e935L,0x2ff2419567722L,\n        0x0f0d008bada9eL },\n      { 0x2671d2414d3b1L,0x85b019ea76291L,0x53bcbdbb37549L,0x7b8b5c61b96d4L,\n        0x05bd5c2f5ca88L } },\n    /* 40 */\n    { { 0xf469ef49a3154L,0x956e2b2e9aef0L,0xa924a9c3e85a5L,0x471945aaec1eaL,\n        0x0aa12dfc8a09eL },\n      { 0x272274df69f1dL,0x2ca2ff5e7326fL,0x7a9dd44e0e4c8L,0xa901b9d8ce73bL,\n        0x06c036e73e48cL } },\n    /* 41 */\n    { { 0xae12a0f6e3138L,0x0025ad345a5cfL,0x5672bc56966efL,0xbe248993c64b4L,\n        0x0292ff65896afL },\n      { 0x50d445e213402L,0x274392c9fed52L,0xa1c72e8f6580eL,0x7276097b397fdL,\n        0x0644e0c90311bL } },\n    /* 42 */\n    { { 0x421e1a47153f0L,0x79920418c9e1eL,0x05d7672b86c3bL,0x9a7793bdce877L,\n        0x0f25ae793cab7L },\n      { 0x194a36d869d0cL,0x824986c2641f3L,0x96e945e9d55c8L,0x0a3e49fb5ea30L,\n        0x039b8e65313dbL } },\n    /* 43 */\n    { { 0x54200b6fd2e59L,0x669255c98f377L,0xe2a573935e2c0L,0xdb06d9dab21a0L,\n        0x039122f2f0f19L },\n      { 0xce1e003cad53cL,0x0fe65c17e3cfbL,0xaa13877225b2cL,0xff8d72baf1d29L,\n        0x08de80af8ce80L } },\n    /* 44 */\n    { { 0xea8d9207bbb76L,0x7c21782758afbL,0xc0436b1921c7eL,0x8c04dfa2b74b1L,\n        0x0871949062e36L },\n      { 0x928bba3993df5L,0xb5f3b3d26ab5fL,0x5b55050639d75L,0xfde1011aa78a8L,\n        0x0fc315e6a5b74L } },\n    /* 45 */\n    { { 0xfd41ae8d6ecfaL,0xf61aec7f86561L,0x924741d5f8c44L,0x908898452a7b4L,\n        0x0e6d4a7adee38L },\n      { 0x52ed14593c75dL,0xa4dd271162605L,0xba2c7db70a70dL,0xae57d2aede937L,\n        0x035dfaf9a9be2L } },\n    /* 46 */\n    { { 0x56fcdaa736636L,0x97ae2cab7e6b9L,0xf34996609f51dL,0x0d2bfb10bf410L,\n        0x01da5c7d71c83L },\n      { 0x1e4833cce6825L,0x8ff9573c3b5c4L,0x23036b815ad11L,0xb9d6a28552c7fL,\n        0x07077c0fddbf4L } },\n    /* 47 */\n    { { 0x3ff8d46b9661cL,0x6b0d2cfd71bf6L,0x847f8f7a1dfd3L,0xfe440373e140aL,\n        0x053a8632ee50eL },\n      { 0x6ff68696d8051L,0x95c74f468a097L,0xe4e26bddaec0cL,0xfcc162994dc35L,\n        0x0028ca76d34e1L } },\n    /* 48 */\n    { { 0xd47dcfc9877eeL,0x10801d0002d11L,0x4c260b6c8b362L,0xf046d002c1175L,\n        0x004c17cd86962L },\n      { 0xbd094b0daddf5L,0x7524ce55c06d9L,0x2da03b5bea235L,0x7474663356e67L,\n        0x0f7ba4de9fed9L } },\n    /* 49 */\n    { { 0xbfa34ebe1263fL,0x3571ae7ce6d0dL,0x2a6f523557637L,0x1c41d24405538L,\n        0x0e31f96005213L },\n      { 0xb9216ea6b6ec6L,0x2e73c2fc44d1bL,0x9d0a29437a1d1L,0xd47bc10e7eac8L,\n        0x0aa3a6259ce34L } },\n    /* 50 */\n    { { 0xf9df536f3dcd3L,0x50d2bf7360fbcL,0xf504f5b6cededL,0xdaee491710fadL,\n        0x02398dd627e79L },\n      { 0x705a36d09569eL,0xbb5149f769cf4L,0x5f6034cea0619L,0x6210ff9c03773L,\n        0x05717f5b21c04L } },\n    /* 51 */\n    { { 0x229c921dd895eL,0x0040c284519feL,0xd637ecd8e5185L,0x28defa13d2391L,\n        0x0660a2c560e3cL },\n      { 0xa88aed67fcbd0L,0x780ea9f0969ccL,0x2e92b4dc84724L,0x245332b2f4817L,\n        0x0624ee54c4f52L } },\n    /* 52 */\n    { { 0x49ce4d897ecccL,0xd93f9880aa095L,0x43a7c204d49d1L,0xfbc0723c24230L,\n        0x04f392afb92bdL },\n      { 0x9f8fa7de44fd9L,0xe457b32156696L,0x68ebc3cb66cfbL,0x399cdb2fa8033L,\n        0x08a3e7977ccdbL } },\n    /* 53 */\n    { { 0x1881f06c4b125L,0x00f6e3ca8cddeL,0xc7a13e9ae34e3L,0x4404ef6999de5L,\n        0x03888d02370c2L },\n      { 0x8035644f91081L,0x615f015504762L,0x32cd36e3d9fcfL,0x23361827edc86L,\n        0x0a5e62e471810L } },\n    /* 54 */\n    { { 0x25ee32facd6c8L,0x5454bcbc661a8L,0x8df9931699c63L,0x5adc0ce3edf79L,\n        0x02c4768e6466aL },\n      { 0x6ff8c90a64bc9L,0x20e4779f5cb34L,0xc05e884630a60L,0x52a0d949d064bL,\n        0x07b5e6441f9e6L } },\n    /* 55 */\n    { { 0x9422c1d28444aL,0xd8be136a39216L,0xb0c7fcee996c5L,0x744a2387afe5fL,\n        0x0b8af73cb0c8dL },\n      { 0xe83aa338b86fdL,0x58a58a5cff5fdL,0x0ac9433fee3f1L,0x0895c9ee8f6f2L,\n        0x0a036395f7f3fL } },\n    /* 56 */\n    { { 0x3c6bba10f7770L,0x81a12a0e248c7L,0x1bc2b9fa6f16dL,0xb533100df6825L,\n        0x04be36b01875fL },\n      { 0x6086e9fb56dbbL,0x8b07e7a4f8922L,0x6d52f20306fefL,0x00c0eeaccc056L,\n        0x08cbc9a871bdcL } },\n    /* 57 */\n    { { 0x1895cc0dac4abL,0x40712ff112e13L,0xa1cee57a874a4L,0x35f86332ae7c6L,\n        0x044e7553e0c08L },\n      { 0x03fff7734002dL,0x8b0b34425c6d5L,0xe8738b59d35cbL,0xfc1895f702760L,\n        0x0470a683a5eb8L } },\n    /* 58 */\n    { { 0x761dc90513482L,0x2a01e9276a81bL,0xce73083028720L,0xc6efcda441ee0L,\n        0x016410690c63dL },\n      { 0x34a066d06a2edL,0x45189b100bf50L,0xb8218c9dd4d77L,0xbb4fd914ae72aL,\n        0x0d73479fd7abcL } },\n    /* 59 */\n    { { 0xefb165ad4c6e5L,0x8f5b06d04d7edL,0x575cb14262cf0L,0x666b12ed5bb18L,\n        0x0816469e30771L },\n      { 0xb9d79561e291eL,0x22c1de1661d7aL,0x35e0513eb9dafL,0x3f9cf49827eb1L,\n        0x00a36dd23f0ddL } },\n    /* 60 */\n    { { 0xd32c741d5533cL,0x9e8684628f098L,0x349bd117c5f5aL,0xb11839a228adeL,\n        0x0e331dfd6fdbaL },\n      { 0x0ab686bcc6ed8L,0xbdef7a260e510L,0xce850d77160c3L,0x33899063d9a7bL,\n        0x0d3b4782a492eL } },\n    /* 61 */\n    { { 0x9b6e8f3821f90L,0xed66eb7aada14L,0xa01311692edd9L,0xa5bd0bb669531L,\n        0x07281275a4c86L },\n      { 0x858f7d3ff47e5L,0xbc61016441503L,0xdfd9bb15e1616L,0x505962b0f11a7L,\n        0x02c062e7ece14L } },\n    /* 62 */\n    { { 0xf996f0159ac2eL,0x36cbdb2713a76L,0x8e46047281e77L,0x7ef12ad6d2880L,\n        0x0282a35f92c4eL },\n      { 0x54b1ec0ce5cd2L,0xc91379c2299c3L,0xe82c11ecf99efL,0x2abd992caf383L,\n        0x0c71cd513554dL } },\n    /* 63 */\n    { { 0x5de9c09b578f4L,0x58e3affa7a488L,0x9182f1f1884e2L,0xf3a38f76b1b75L,\n        0x0c50f6740cf47L },\n      { 0x4adf3374b68eaL,0x2369965fe2a9cL,0x5a53050a406f3L,0x58dc2f86a2228L,\n        0x0b9ecb3a72129L } },\n    /* 64 */\n    { { 0x8410ef4f8b16aL,0xfec47b266a56fL,0xd9c87c197241aL,0xab1b0a406b8e6L,\n        0x0803f3e02cd42L },\n      { 0x309a804dbec69L,0xf73bbad05f7f0L,0xd8e197fa83b85L,0xadc1c6097273aL,\n        0x0c097440e5067L } },\n    /* 65 */\n    { { 0xa56f2c379ab34L,0x8b841df8d1846L,0x76c68efa8ee06L,0x1f30203144591L,\n        0x0f1af32d5915fL },\n      { 0x375315d75bd50L,0xbaf72f67bc99cL,0x8d7723f837cffL,0x1c8b0613a4184L,\n        0x023d0f130e2d4L } },\n    /* 66 */\n    { { 0xab6edf41500d9L,0xe5fcbeada8857L,0x97259510d890aL,0xfadd52fe86488L,\n        0x0b0288dd6c0a3L },\n      { 0x20f30650bcb08L,0x13695d6e16853L,0x989aa7671af63L,0xc8d231f520a7bL,\n        0x0ffd3724ff408L } },\n    /* 67 */\n    { { 0x68e64b458e6cbL,0x20317a5d28539L,0xaa75f56992dadL,0x26df3814ae0b7L,\n        0x0f5590f4ad78cL },\n      { 0x24bd3cf0ba55aL,0x4a0c778bae0fcL,0x83b674a0fc472L,0x4a201ce9864f6L,\n        0x018d6da54f6f7L } },\n    /* 68 */\n    { { 0x3e225d5be5a2bL,0x835934f3c6ed9L,0x2626ffc6fe799L,0x216a431409262L,\n        0x050bbb4d97990L },\n      { 0x191c6e57ec63eL,0x40181dcdb2378L,0x236e0f665422cL,0x49c341a8099b0L,\n        0x02b10011801feL } },\n    /* 69 */\n    { { 0x8b5c59b391593L,0xa2598270fcfc6L,0x19adcbbc385f5L,0xae0c7144f3aadL,\n        0x0dd55899983fbL },\n      { 0x88b8e74b82ff4L,0x4071e734c993bL,0x3c0322ad2e03cL,0x60419a7a9eaf4L,\n        0x0e6e4c551149dL } },\n    /* 70 */\n    { { 0x655bb1e9af288L,0x64f7ada93155fL,0xb2820e5647e1aL,0x56ff43697e4bcL,\n        0x051e00db107edL },\n      { 0x169b8771c327eL,0x0b4a96c2ad43dL,0xdeb477929cdb2L,0x9177c07d51f53L,\n        0x0e22f42414982L } },\n    /* 71 */\n    { { 0x5e8f4635f1abbL,0xb568538874cd4L,0x5a8034d7edc0cL,0x48c9c9472c1fbL,\n        0x0f709373d52dcL },\n      { 0x966bba8af30d6L,0x4af137b69c401L,0x361c47e95bf5fL,0x5b113966162a9L,\n        0x0bd52d288e727L } },\n    /* 72 */\n    { { 0x55c7a9c5fa877L,0x727d3a3d48ab1L,0x3d189d817dad6L,0x77a643f43f9e7L,\n        0x0a0d0f8e4c8aaL },\n      { 0xeafd8cc94f92dL,0xbe0c4ddb3a0bbL,0x82eba14d818c8L,0x6a0022cc65f8bL,\n        0x0a56c78c7946dL } },\n    /* 73 */\n    { { 0x2391b0dd09529L,0xa63daddfcf296L,0xb5bf481803e0eL,0x367a2c77351f5L,\n        0x0d8befdf8731aL },\n      { 0x19d42fc0157f4L,0xd7fec8e650ab9L,0x2d48b0af51caeL,0x6478cdf9cb400L,\n        0x0854a68a5ce9fL } },\n    /* 74 */\n    { { 0x5f67b63506ea5L,0x89a4fe0d66dc3L,0xe95cd4d9286c4L,0x6a953f101d3bfL,\n        0x05cacea0b9884L },\n      { 0xdf60c9ceac44dL,0xf4354d1c3aa90L,0xd5dbabe3db29aL,0xefa908dd3de8aL,\n        0x0e4982d1235e4L } },\n    /* 75 */\n    { { 0x04a22c34cd55eL,0xb32680d132231L,0xfa1d94358695bL,0x0499fb345afa1L,\n        0x08046b7f616b2L },\n      { 0x3581e38e7d098L,0x8df46f0b70b53L,0x4cb78c4d7f61eL,0xaf5530dea9ea4L,\n        0x0eb17ca7b9082L } },\n    /* 76 */\n    { { 0x1b59876a145b9L,0x0fc1bc71ec175L,0x92715bba5cf6bL,0xe131d3e035653L,\n        0x0097b00bafab5L },\n      { 0x6c8e9565f69e1L,0x5ab5be5199aa6L,0xa4fd98477e8f7L,0xcc9e6033ba11dL,\n        0x0f95c747bafdbL } },\n    /* 77 */\n    { { 0xf01d3bebae45eL,0xf0c4bc6955558L,0xbc64fc6a8ebe9L,0xd837aeb705b1dL,\n        0x03512601e566eL },\n      { 0x6f1e1fa1161cdL,0xd54c65ef87933L,0x24f21e5328ab8L,0xab6b4757eee27L,\n        0x00ef971236068L } },\n    /* 78 */\n    { { 0x98cf754ca4226L,0x38f8642c8e025L,0x68e17905eede1L,0xbc9548963f744L,\n        0x0fc16d9333b4fL },\n      { 0x6fb31e7c800caL,0x312678adaabe9L,0xff3e8b5138063L,0x7a173d6244976L,\n        0x014ca4af1b95dL } },\n    /* 79 */\n    { { 0x771babd2f81d5L,0x6901f7d1967a4L,0xad9c9071a5f9dL,0x231dd898bef7cL,\n        0x04057b063f59cL },\n      { 0xd82fe89c05c0aL,0x6f1dc0df85bffL,0x35a16dbe4911cL,0x0b133befccaeaL,\n        0x01c3b5d64f133L } },\n    /* 80 */\n    { { 0x14bfe80ec21feL,0x6ac255be825feL,0xf4a5d67f6ce11L,0x63af98bc5a072L,\n        0x0fad27148db7eL },\n      { 0x0b6ac29ab05b3L,0x3c4e251ae690cL,0x2aade7d37a9a8L,0x1a840a7dc875cL,\n        0x077387de39f0eL } },\n    /* 81 */\n    { { 0xecc49a56c0dd7L,0xd846086c741e9L,0x505aecea5cffcL,0xc47e8f7a1408fL,\n        0x0b37b85c0bef0L },\n      { 0x6b6e4cc0e6a8fL,0xbf6b388f23359L,0x39cef4efd6d4bL,0x28d5aba453facL,\n        0x09c135ac8f9f6L } },\n    /* 82 */\n    { { 0xa320284e35743L,0xb185a3cdef32aL,0xdf19819320d6aL,0x851fb821b1761L,\n        0x05721361fc433L },\n      { 0xdb36a71fc9168L,0x735e5c403c1f0L,0x7bcd8f55f98baL,0x11bdf64ca87e3L,\n        0x0dcbac3c9e6bbL } },\n    /* 83 */\n    { { 0xd99684518cbe2L,0x189c9eb04ef01L,0x47feebfd242fcL,0x6862727663c7eL,\n        0x0b8c1c89e2d62L },\n      { 0x58bddc8e1d569L,0xc8b7d88cd051aL,0x11f31eb563809L,0x22d426c27fd9fL,\n        0x05d23bbda2f94L } },\n    /* 84 */\n    { { 0xc729495c8f8beL,0x803bf362bf0a1L,0xf63d4ac2961c4L,0xe9009e418403dL,\n        0x0c109f9cb91ecL },\n      { 0x095d058945705L,0x96ddeb85c0c2dL,0xa40449bb9083dL,0x1ee184692b8d7L,\n        0x09bc3344f2eeeL } },\n    /* 85 */\n    { { 0xae35642913074L,0x2748a542b10d5L,0x310732a55491bL,0x4cc1469ca665bL,\n        0x029591d525f1aL },\n      { 0xf5b6bb84f983fL,0x419f5f84e1e76L,0x0baa189be7eefL,0x332c1200d4968L,\n        0x06376551f18efL } },\n    /* 86 */\n    { { 0x5f14e562976ccL,0xe60ef12c38bdaL,0xcca985222bca3L,0x987abbfa30646L,\n        0x0bdb79dc808e2L },\n      { 0xcb5c9cb06a772L,0xaafe536dcefd2L,0xc2b5db838f475L,0xc14ac2a3e0227L,\n        0x08ee86001add3L } },\n    /* 87 */\n    { { 0x96981a4ade873L,0x4dc4fba48ccbeL,0xa054ba57ee9aaL,0xaa4b2cee28995L,\n        0x092e51d7a6f77L },\n      { 0xbafa87190a34dL,0x5bf6bd1ed1948L,0xcaf1144d698f7L,0xaaaad00ee6e30L,\n        0x05182f86f0a56L } },\n    /* 88 */\n    { { 0x6212c7a4cc99cL,0x683e6d9ca1fbaL,0xac98c5aff609bL,0xa6f25dbb27cb5L,\n        0x091dcab5d4073L },\n      { 0x6cc3d5f575a70L,0x396f8d87fa01bL,0x99817360cb361L,0x4f2b165d4e8c8L,\n        0x017a0cedb9797L } },\n    /* 89 */\n    { { 0x61e2a076c8d3aL,0x39210f924b388L,0x3a835d9701aadL,0xdf4194d0eae41L,\n        0x02e8ce36c7f4cL },\n      { 0x73dab037a862bL,0xb760e4c8fa912L,0x3baf2dd01ba9bL,0x68f3f96453883L,\n        0x0f4ccc6cb34f6L } },\n    /* 90 */\n    { { 0xf525cf1f79687L,0x9592efa81544eL,0x5c78d297c5954L,0xf3c9e1231741aL,\n        0x0ac0db4889a0dL },\n      { 0xfc711df01747fL,0x58ef17df1386bL,0xccb6bb5592b93L,0x74a2e5880e4f5L,\n        0x095a64a6194c9L } },\n    /* 91 */\n    { { 0x1efdac15a4c93L,0x738258514172cL,0x6cb0bad40269bL,0x06776a8dfb1c1L,\n        0x0231e54ba2921L },\n      { 0xdf9178ae6d2dcL,0x3f39112918a70L,0xe5b72234d6aa6L,0x31e1f627726b5L,\n        0x0ab0be032d8a7L } },\n    /* 92 */\n    { { 0xad0e98d131f2dL,0xe33b04f101097L,0x5e9a748637f09L,0xa6791ac86196dL,\n        0x0f1bcc8802cf6L },\n      { 0x69140e8daacb4L,0x5560f6500925cL,0x77937a63c4e40L,0xb271591cc8fc4L,\n        0x0851694695aebL } },\n    /* 93 */\n    { { 0x5c143f1dcf593L,0x29b018be3bde3L,0xbdd9d3d78202bL,0x55d8e9cdadc29L,\n        0x08f67d9d2daadL },\n      { 0x116567481ea5fL,0xe9e34c590c841L,0x5053fa8e7d2ddL,0x8b5dffdd43f40L,\n        0x0f84572b9c072L } },\n    /* 94 */\n    { { 0xa7a7197af71c9L,0x447a7365655e1L,0xe1d5063a14494L,0x2c19a1b4ae070L,\n        0x0edee2710616bL },\n      { 0x034f511734121L,0x554a25e9f0b2fL,0x40c2ecf1cac6eL,0xd7f48dc148f3aL,\n        0x09fd27e9b44ebL } },\n    /* 95 */\n    { { 0x7658af6e2cb16L,0x2cfe5919b63ccL,0x68d5583e3eb7dL,0xf3875a8c58161L,\n        0x0a40c2fb6958fL },\n      { 0xec560fedcc158L,0xc655f230568c9L,0xa307e127ad804L,0xdecfd93967049L,\n        0x099bc9bb87dc6L } },\n    /* 96 */\n    { { 0x9521d927dafc6L,0x695c09cd1984aL,0x9366dde52c1fbL,0x7e649d9581a0fL,\n        0x09abe210ba16dL },\n      { 0xaf84a48915220L,0x6a4dd816c6480L,0x681ca5afa7317L,0x44b0c7d539871L,\n        0x07881c25787f3L } },\n    /* 97 */\n    { { 0x99b51e0bcf3ffL,0xc5127f74f6933L,0xd01d9680d02cbL,0x89408fb465a2dL,\n        0x015e6e319a30eL },\n      { 0xd6e0d3e0e05f4L,0xdc43588404646L,0x4f850d3fad7bdL,0x72cebe61c7d1cL,\n        0x00e55facf1911L } },\n    /* 98 */\n    { { 0xd9806f8787564L,0x2131e85ce67e9L,0x819e8d61a3317L,0x65776b0158cabL,\n        0x0d73d09766fe9L },\n      { 0x834251eb7206eL,0x0fc618bb42424L,0xe30a520a51929L,0xa50b5dcbb8595L,\n        0x09250a3748f15L } },\n    /* 99 */\n    { { 0xf08f8be577410L,0x035077a8c6cafL,0xc0a63a4fd408aL,0x8c0bf1f63289eL,\n        0x077414082c1ccL },\n      { 0x40fa6eb0991cdL,0x6649fdc29605aL,0x324fd40c1ca08L,0x20b93a68a3c7bL,\n        0x08cb04f4d12ebL } },\n    /* 100 */\n    { { 0x2d0556906171cL,0xcdb0240c3fb1cL,0x89068419073e9L,0x3b51db8e6b4fdL,\n        0x0e4e429ef4712L },\n      { 0xdd53c38ec36f4L,0x01ff4b6a270b8L,0x79a9a48f9d2dcL,0x65525d066e078L,\n        0x037bca2ff3c6eL } },\n    /* 101 */\n    { { 0x2e3c7df562470L,0xa2c0964ac94cdL,0x0c793be44f272L,0xb22a7c6d5df98L,\n        0x059913edc3002L },\n      { 0x39a835750592aL,0x80e783de027a1L,0xa05d64f99e01dL,0xe226cf8c0375eL,\n        0x043786e4ab013L } },\n    /* 102 */\n    { { 0x2b0ed9e56b5a6L,0xa6d9fc68f9ff3L,0x97846a70750d9L,0x9e7aec15e8455L,\n        0x08638ca98b7e7L },\n      { 0xae0960afc24b2L,0xaf4dace8f22f5L,0xecba78f05398eL,0xa6f03b765dd0aL,\n        0x01ecdd36a7b3aL } },\n    /* 103 */\n    { { 0xacd626c5ff2f3L,0xc02873a9785d3L,0x2110d54a2d516L,0xf32dad94c9fadL,\n        0x0d85d0f85d459L },\n      { 0x00b8d10b11da3L,0x30a78318c49f7L,0x208decdd2c22cL,0x3c62556988f49L,\n        0x0a04f19c3b4edL } },\n    /* 104 */\n    { { 0x924c8ed7f93bdL,0x5d392f51f6087L,0x21b71afcb64acL,0x50b07cae330a8L,\n        0x092b2eeea5c09L },\n      { 0xc4c9485b6e235L,0xa92936c0f085aL,0x0508891ab2ca4L,0x276c80faa6b3eL,\n        0x01ee782215834L } },\n    /* 105 */\n    { { 0xa2e00e63e79f7L,0xb2f399d906a60L,0x607c09df590e7L,0xe1509021054a6L,\n        0x0f3f2ced857a6L },\n      { 0x510f3f10d9b55L,0xacd8642648200L,0x8bd0e7c9d2fcfL,0xe210e5631aa7eL,\n        0x00f56a4543da3L } },\n    /* 106 */\n    { { 0x1bffa1043e0dfL,0xcc9c007e6d5b2L,0x4a8517a6c74b6L,0xe2631a656ec0dL,\n        0x0bd8f17411969L },\n      { 0xbbb86beb7494aL,0x6f45f3b8388a9L,0x4e5a79a1567d4L,0xfa09df7a12a7aL,\n        0x02d1a1c3530ccL } },\n    /* 107 */\n    { { 0xe3813506508daL,0xc4a1d795a7192L,0xa9944b3336180L,0xba46cddb59497L,\n        0x0a107a65eb91fL },\n      { 0x1d1c50f94d639L,0x758a58b7d7e6dL,0xd37ca1c8b4af3L,0x9af21a7c5584bL,\n        0x0183d760af87aL } },\n    /* 108 */\n    { { 0x697110dde59a4L,0x070e8bef8729dL,0xf2ebe78f1ad8dL,0xd754229b49634L,\n        0x01d44179dc269L },\n      { 0xdc0cf8390d30eL,0x530de8110cb32L,0xbc0339a0a3b27L,0xd26231af1dc52L,\n        0x0771f9cc29606L } },\n    /* 109 */\n    { { 0x93e7785040739L,0xb98026a939999L,0x5f8fc2644539dL,0x718ecf40f6f2fL,\n        0x064427a310362L },\n      { 0xf2d8785428aa8L,0x3febfb49a84f4L,0x23d01ac7b7adcL,0x0d6d201b2c6dfL,\n        0x049d9b7496ae9L } },\n    /* 110 */\n    { { 0x8d8bc435d1099L,0x4e8e8d1a08cc7L,0xcb68a412adbcdL,0x544502c2e2a02L,\n        0x09037d81b3f60L },\n      { 0xbac27074c7b61L,0xab57bfd72e7cdL,0x96d5352fe2031L,0x639c61ccec965L,\n        0x008c3de6a7cc0L } },\n    /* 111 */\n    { { 0xdd020f6d552abL,0x9805cd81f120fL,0x135129156baffL,0x6b2f06fb7c3e9L,\n        0x0c69094424579L },\n      { 0x3ae9c41231bd1L,0x875cc5820517bL,0x9d6a1221eac6eL,0x3ac0208837abfL,\n        0x03fa3db02cafeL } },\n    /* 112 */\n    { { 0xa3e6505058880L,0xef643943f2d75L,0xab249257da365L,0x08ff4147861cfL,\n        0x0c5c4bdb0fdb8L },\n      { 0x13e34b272b56bL,0x9511b9043a735L,0x8844969c8327eL,0xb6b5fd8ce37dfL,\n        0x02d56db9446c2L } },\n    /* 113 */\n    { { 0x1782fff46ac6bL,0x2607a2e425246L,0x9a48de1d19f79L,0xba42fafea3c40L,\n        0x00f56bd9de503L },\n      { 0xd4ed1345cda49L,0xfc816f299d137L,0xeb43402821158L,0xb5f1e7c6a54aaL,\n        0x04003bb9d1173L } },\n    /* 114 */\n    { { 0xe8189a0803387L,0xf539cbd4043b8L,0x2877f21ece115L,0x2f9e4297208ddL,\n        0x053765522a07fL },\n      { 0x80a21a8a4182dL,0x7a3219df79a49L,0xa19a2d4a2bbd0L,0x4549674d0a2e1L,\n        0x07a056f586c5dL } },\n    /* 115 */\n    { { 0xb25589d8a2a47L,0x48c3df2773646L,0xbf0d5395b5829L,0x267551ec000eaL,\n        0x077d482f17a1aL },\n      { 0x1bd9587853948L,0xbd6cfbffeeb8aL,0x0681e47a6f817L,0xb0e4ab6ec0578L,\n        0x04115012b2b38L } },\n    /* 116 */\n    { { 0x3f0f46de28cedL,0x609b13ec473c7L,0xe5c63921d5da7L,0x094661b8ce9e6L,\n        0x0cdf04572fbeaL },\n      { 0x3c58b6c53c3b0L,0x10447b843c1cbL,0xcb9780e97fe3cL,0x3109fb2b8ae12L,\n        0x0ee703dda9738L } },\n    /* 117 */\n    { { 0x15140ff57e43aL,0xd3b1b811b8345L,0xf42b986d44660L,0xce212b3b5dff8L,\n        0x02a0ad89da162L },\n      { 0x4a6946bc277baL,0x54c141c27664eL,0xabf6274c788c9L,0x4659141aa64ccL,\n        0x0d62d0b67ac2bL } },\n    /* 118 */\n    { { 0x5d87b2c054ac4L,0x59f27df78839cL,0x18128d6570058L,0x2426edf7cbf3bL,\n        0x0b39a23f2991cL },\n      { 0x84a15f0b16ae5L,0xb1a136f51b952L,0x27007830c6a05L,0x4cc51d63c137fL,\n        0x004ed0092c067L } },\n    /* 119 */\n    { { 0x185d19ae90393L,0x294a3d64e61f4L,0x854fc143047b4L,0xc387ae0001a69L,\n        0x0a0a91fc10177L },\n      { 0xa3f01ae2c831eL,0x822b727e16ff0L,0xa3075b4bb76aeL,0x0c418f12c8a15L,\n        0x0084cf9889ed2L } },\n    /* 120 */\n    { { 0x509defca6becfL,0x807dffb328d98L,0x778e8b92fceaeL,0xf77e5d8a15c44L,\n        0x0d57955b273abL },\n      { 0xda79e31b5d4f1L,0x4b3cfa7a1c210L,0xc27c20baa52f0L,0x41f1d4d12089dL,\n        0x08e14ea4202d1L } },\n    /* 121 */\n    { { 0x50345f2897042L,0x1f43402c4aeedL,0x8bdfb218d0533L,0xd158c8d9c194cL,\n        0x0597e1a372aa4L },\n      { 0x7ec1acf0bd68cL,0xdcab024945032L,0x9fe3e846d4be0L,0x4dea5b9c8d7acL,\n        0x0ca3f0236199bL } },\n    /* 122 */\n    { { 0xa10b56170bd20L,0xf16d3f5de7592L,0x4b2ade20ea897L,0x07e4a3363ff14L,\n        0x0bde7fd7e309cL },\n      { 0xbb6d2b8f5432cL,0xcbe043444b516L,0x8f95b5a210dc1L,0xd1983db01e6ffL,\n        0x0b623ad0e0a7dL } },\n    /* 123 */\n    { { 0xbd67560c7b65bL,0x9023a4a289a75L,0x7b26795ab8c55L,0x137bf8220fd0dL,\n        0x0d6aa2e4658ecL },\n      { 0xbc00b5138bb85L,0x21d833a95c10aL,0x702a32e8c31d1L,0x513ab24ff00b1L,\n        0x0111662e02dccL } },\n    /* 124 */\n    { { 0x14015efb42b87L,0x701b6c4dff781L,0x7d7c129bd9f5dL,0x50f866ecccd7aL,\n        0x0db3ee1cb94b7L },\n      { 0xf3db0f34837cfL,0x8bb9578d4fb26L,0xc56657de7eed1L,0x6a595d2cdf937L,\n        0x0886a64425220L } },\n    /* 125 */\n    { { 0x34cfb65b569eaL,0x41f72119c13c2L,0x15a619e200111L,0x17bc8badc85daL,\n        0x0a70cf4eb018aL },\n      { 0xf97ae8c4a6a65L,0x270134378f224L,0xf7e096036e5cfL,0x7b77be3a609e4L,\n        0x0aa4772abd174L } },\n    /* 126 */\n    { { 0x761317aa60cc0L,0x610368115f676L,0xbc1bb5ac79163L,0xf974ded98bb4bL,\n        0x0611a6ddc30faL },\n      { 0x78cbcc15ee47aL,0x824e0d96a530eL,0xdd9ed882e8962L,0x9c8836f35adf3L,\n        0x05cfffaf81642L } },\n    /* 127 */\n    { { 0x54cff9b7a99cdL,0x9d843c45a1c0dL,0x2c739e17bf3b9L,0x994c038a908f6L,\n        0x06e5a6b237dc1L },\n      { 0xb454e0ba5db77L,0x7facf60d63ef8L,0x6608378b7b880L,0xabcce591c0c67L,\n        0x0481a238d242dL } },\n    /* 128 */\n    { { 0x17bc035d0b34aL,0x6b8327c0a7e34L,0xc0362d1440b38L,0xf9438fb7262daL,\n        0x02c41114ce0cdL },\n      { 0x5cef1ad95a0b1L,0xa867d543622baL,0x1e486c9c09b37L,0x929726d6cdd20L,\n        0x020477abf42ffL } },\n    /* 129 */\n    { { 0x5173c18d65dbfL,0x0e339edad82f7L,0xcf1001c77bf94L,0x96b67022d26bdL,\n        0x0ac66409ac773L },\n      { 0xbb36fc6261cc3L,0xc9190e7e908b0L,0x45e6c10213f7bL,0x2f856541cebaaL,\n        0x0ce8e6975cc12L } },\n    /* 130 */\n    { { 0x21b41bc0a67d2L,0x0a444d248a0f1L,0x59b473762d476L,0xb4a80e044f1d6L,\n        0x008fde365250bL },\n      { 0xec3da848bf287L,0x82d3369d6eaceL,0x2449482c2a621L,0x6cd73582dfdc9L,\n        0x02f7e2fd2565dL } },\n    /* 131 */\n    { { 0xb92dbc3770fa7L,0x5c379043f9ae4L,0x7761171095e8dL,0x02ae54f34e9d1L,\n        0x0c65be92e9077L },\n      { 0x8a303f6fd0a40L,0xe3bcce784b275L,0xf9767bfe7d822L,0x3b3a7ae4f5854L,\n        0x04bff8e47d119L } },\n    /* 132 */\n    { { 0x1d21f00ff1480L,0x7d0754db16cd4L,0xbe0f3ea2ab8fbL,0x967dac81d2efbL,\n        0x03e4e4ae65772L },\n      { 0x8f36d3c5303e6L,0x4b922623977e1L,0x324c3c03bd999L,0x60289ed70e261L,\n        0x05388aefd58ecL } },\n    /* 133 */\n    { { 0x317eb5e5d7713L,0xee75de49daad1L,0x74fb26109b985L,0xbe0e32f5bc4fcL,\n        0x05cf908d14f75L },\n      { 0x435108e657b12L,0xa5b96ed9e6760L,0x970ccc2bfd421L,0x0ce20e29f51f8L,\n        0x0a698ba4060f0L } },\n    /* 134 */\n    { { 0xb1686ef748fecL,0xa27e9d2cf973dL,0xe265effe6e755L,0xad8d630b6544cL,\n        0x0b142ef8a7aebL },\n      { 0x1af9f17d5770aL,0x672cb3412fad3L,0xf3359de66af3bL,0x50756bd60d1bdL,\n        0x0d1896a965851L } },\n    /* 135 */\n    { { 0x957ab33c41c08L,0xac5468e2e1ec5L,0xc472f6c87de94L,0xda3918816b73aL,\n        0x0267b0e0b7981L },\n      { 0x54e5d8e62b988L,0x55116d21e76e5L,0xd2a6f99d8ddc7L,0x93934610faf03L,\n        0x0b54e287aa111L } },\n    /* 136 */\n    { { 0x122b5178a876bL,0xff085104b40a0L,0x4f29f7651ff96L,0xd4e6050b31ab1L,\n        0x084abb28b5f87L },\n      { 0xd439f8270790aL,0x9d85e3f46bd5eL,0xc1e22122d6cb5L,0x564075f55c1b6L,\n        0x0e5436f671765L } },\n    /* 137 */\n    { { 0x9025e2286e8d5L,0xb4864453be53fL,0x408e3a0353c95L,0xe99ed832f5bdeL,\n        0x00404f68b5b9cL },\n      { 0x33bdea781e8e5L,0x18163c2f5bcadL,0x119caa33cdf50L,0xc701575769600L,\n        0x03a4263df0ac1L } },\n    /* 138 */\n    { { 0x65ecc9aeb596dL,0xe7023c92b4c29L,0xe01396101ea03L,0xa3674704b4b62L,\n        0x00ca8fd3f905eL },\n      { 0x23a42551b2b61L,0x9c390fcd06925L,0x392a63e1eb7a8L,0x0c33e7f1d2be0L,\n        0x096dca2644ddbL } },\n    /* 139 */\n    { { 0xbb43a387510afL,0xa8a9a36a01203L,0xf950378846feaL,0x59dcd23a57702L,\n        0x04363e2123aadL },\n      { 0x3a1c740246a47L,0xd2e55dd24dca4L,0xd8faf96b362b8L,0x98c4f9b086045L,\n        0x0840e115cd8bbL } },\n    /* 140 */\n    { { 0x205e21023e8a7L,0xcdd8dc7a0bf12L,0x63a5ddfc808a8L,0xd6d4e292a2721L,\n        0x05e0d6abd30deL },\n      { 0x721c27cfc0f64L,0x1d0e55ed8807aL,0xd1f9db242eec0L,0xa25a26a7bef91L,\n        0x07dea48f42945L } },\n    /* 141 */\n    { { 0xf6f1ce5060a81L,0x72f8f95615abdL,0x6ac268be79f9cL,0x16d1cfd36c540L,\n        0x0abc2a2beebfdL },\n      { 0x66f91d3e2eac7L,0x63d2dd04668acL,0x282d31b6f10baL,0xefc16790e3770L,\n        0x04ea353946c7eL } },\n    /* 142 */\n    { { 0xa2f8d5266309dL,0xc081945a3eed8L,0x78c5dc10a51c6L,0xffc3cecaf45a5L,\n        0x03a76e6891c94L },\n      { 0xce8a47d7b0d0fL,0x968f584a5f9aaL,0xe697fbe963aceL,0x646451a30c724L,\n        0x08212a10a465eL } },\n    /* 143 */\n    { { 0xc61c3cfab8caaL,0x840e142390ef7L,0xe9733ca18eb8eL,0xb164cd1dff677L,\n        0x0aa7cab71599cL },\n      { 0xc9273bc837bd1L,0xd0c36af5d702fL,0x423da49c06407L,0x17c317621292fL,\n        0x040e38073fe06L } },\n    /* 144 */\n    { { 0x80824a7bf9b7cL,0x203fbe30d0f4fL,0x7cf9ce3365d23L,0x5526bfbe53209L,\n        0x0e3604700b305L },\n      { 0xb99116cc6c2c7L,0x08ba4cbee64dcL,0x37ad9ec726837L,0xe15fdcded4346L,\n        0x06542d677a3deL } },\n    /* 145 */\n    { { 0x2b6d07b6c377aL,0x47903448be3f3L,0x0da8af76cb038L,0x6f21d6fdd3a82L,\n        0x0a6534aee09bbL },\n      { 0x1780d1035facfL,0x339dcb47e630aL,0x447f39335e55aL,0xef226ea50fe1cL,\n        0x0f3cb672fdc9aL } },\n    /* 146 */\n    { { 0x719fe3b55fd83L,0x6c875ddd10eb3L,0x5cea784e0d7a4L,0x70e733ac9fa90L,\n        0x07cafaa2eaae8L },\n      { 0x14d041d53b338L,0xa0ef87e6c69b8L,0x1672b0fe0acc0L,0x522efb93d1081L,\n        0x00aab13c1b9bdL } },\n    /* 147 */\n    { { 0xce278d2681297L,0xb1b509546addcL,0x661aaf2cb350eL,0x12e92dc431737L,\n        0x04b91a6028470L },\n      { 0xf109572f8ddcfL,0x1e9a911af4dcfL,0x372430e08ebf6L,0x1cab48f4360acL,\n        0x049534c537232L } },\n    /* 148 */\n    { { 0xf7d71f07b7e9dL,0xa313cd516f83dL,0xc047ee3a478efL,0xc5ee78ef264b6L,\n        0x0caf46c4fd65aL },\n      { 0xd0c7792aa8266L,0x66913684bba04L,0xe4b16b0edf454L,0x770f56e65168aL,\n        0x014ce9e5704c6L } },\n    /* 149 */\n    { { 0x45e3e965e8f91L,0xbacb0f2492994L,0x0c8a0a0d3aca1L,0x9a71d31cc70f9L,\n        0x01bb708a53e4cL },\n      { 0xa9e69558bdd7aL,0x08018a26b1d5cL,0xc9cf1ec734a05L,0x0102b093aa714L,\n        0x0f9d126f2da30L } },\n    /* 150 */\n    { { 0xbca7aaff9563eL,0xfeb49914a0749L,0xf5f1671dd077aL,0xcc69e27a0311bL,\n        0x0807afcb9729eL },\n      { 0xa9337c9b08b77L,0x85443c7e387f8L,0x76fd8ba86c3a7L,0xcd8c85fafa594L,\n        0x0751adcd16568L } },\n    /* 151 */\n    { { 0xa38b410715c0dL,0x718f7697f78aeL,0x3fbf06dd113eaL,0x743f665eab149L,\n        0x029ec44682537L },\n      { 0x4719cb50bebbcL,0xbfe45054223d9L,0xd2dedb1399ee5L,0x077d90cd5b3a8L,\n        0x0ff9370e392a4L } },\n    /* 152 */\n    { { 0x2d69bc6b75b65L,0xd5266651c559aL,0xde9d7d24188f8L,0xd01a28a9f33e3L,\n        0x09776478ba2a9L },\n      { 0x2622d929af2c7L,0x6d4e690923885L,0x89a51e9334f5dL,0x82face6cc7e5aL,\n        0x074a6313fac2fL } },\n    /* 153 */\n    { { 0x4dfddb75f079cL,0x9518e36fbbb2fL,0x7cd36dd85b07cL,0x863d1b6cfcf0eL,\n        0x0ab75be150ff4L },\n      { 0x367c0173fc9b7L,0x20d2594fd081bL,0x4091236b90a74L,0x59f615fdbf03cL,\n        0x04ebeac2e0b44L } },\n    /* 154 */\n    { { 0xc5fe75c9f2c53L,0x118eae9411eb6L,0x95ac5d8d25220L,0xaffcc8887633fL,\n        0x0df99887b2c1bL },\n      { 0x8eed2850aaecbL,0x1b01d6a272bb7L,0x1cdbcac9d4918L,0x4058978dd511bL,\n        0x027b040a7779fL } },\n    /* 155 */\n    { { 0x05db7f73b2eb2L,0x088e1b2118904L,0x962327ee0df85L,0xa3f5501b71525L,\n        0x0b393dd37e4cfL },\n      { 0x30e7b3fd75165L,0xc2bcd33554a12L,0xf7b5022d66344L,0x34196c36f1be0L,\n        0x009588c12d046L } },\n    /* 156 */\n    { { 0x6093f02601c3bL,0xf8cf5c335fe08L,0x94aff28fb0252L,0x648b955cf2808L,\n        0x081c879a9db9fL },\n      { 0xe687cc6f56c51L,0x693f17618c040L,0x059353bfed471L,0x1bc444f88a419L,\n        0x0fa0d48f55fc1L } },\n    /* 157 */\n    { { 0xe1c9de1608e4dL,0x113582822cbc6L,0x57ec2d7010ddaL,0x67d6f6b7ddc11L,\n        0x08ea0e156b6a3L },\n      { 0x4e02f2383b3b4L,0x943f01f53ca35L,0xde03ca569966bL,0xb5ac4ff6632b2L,\n        0x03f5ab924fa00L } },\n    /* 158 */\n    { { 0xbb0d959739efbL,0xf4e7ebec0d337L,0x11a67d1c751b0L,0x256e2da52dd64L,\n        0x08bc768872b74L },\n      { 0xe3b7282d3d253L,0xa1f58d779fa5bL,0x16767bba9f679L,0xf34fa1cac168eL,\n        0x0b386f19060fcL } },\n    /* 159 */\n    { { 0x3c1352fedcfc2L,0x6262f8af0d31fL,0x57288c25396bfL,0x9c4d9a02b4eaeL,\n        0x04cb460f71b06L },\n      { 0x7b4d35b8095eaL,0x596fc07603ae6L,0x614a16592bbf8L,0x5223e1475f66bL,\n        0x052c0d50895efL } },\n    /* 160 */\n    { { 0xc210e15339848L,0xe870778c8d231L,0x956e170e87a28L,0x9c0b9d1de6616L,\n        0x04ac3c9382bb0L },\n      { 0xe05516998987dL,0xc4ae09f4d619bL,0xa3f933d8b2376L,0x05f41de0b7651L,\n        0x0380d94c7e397L } },\n    /* 161 */\n    { { 0x355aa81542e75L,0xa1ee01b9b701aL,0x24d708796c724L,0x37af6b3a29776L,\n        0x02ce3e171de26L },\n      { 0xfeb49f5d5bc1aL,0x7e2777e2b5cfeL,0x513756ca65560L,0x4e4d4feaac2f9L,\n        0x02e6cd8520b62L } },\n    /* 162 */\n    { { 0x5954b8c31c31dL,0x005bf21a0c368L,0x5c79ec968533dL,0x9d540bd7626e7L,\n        0x0ca17754742c6L },\n      { 0xedafff6d2dbb2L,0xbd174a9d18cc6L,0xa4578e8fd0d8cL,0x2ce6875e8793aL,\n        0x0a976a7139cabL } },\n    /* 163 */\n    { { 0x51f1b93fb353dL,0x8b57fcfa720a6L,0x1b15281d75cabL,0x4999aa88cfa73L,\n        0x08720a7170a1fL },\n      { 0xe8d37693e1b90L,0x0b16f6dfc38c3L,0x52a8742d345dcL,0x893c8ea8d00abL,\n        0x09719ef29c769L } },\n    /* 164 */\n    { { 0xeed8d58e35909L,0xdc33ddc116820L,0xe2050269366d8L,0x04c1d7f999d06L,\n        0x0a5072976e157L },\n      { 0xa37eac4e70b2eL,0x576890aa8a002L,0x45b2a5c84dcf6L,0x7725cd71bf186L,\n        0x099389c9df7b7L } },\n    /* 165 */\n    { { 0xc08f27ada7a4bL,0x03fd389366238L,0x66f512c3abe9dL,0x82e46b672e897L,\n        0x0a88806aa202cL },\n      { 0x2044ad380184eL,0xc4126a8b85660L,0xd844f17a8cb78L,0xdcfe79d670c0aL,\n        0x00043bffb4738L } },\n    /* 166 */\n    { { 0x9b5dc36d5192eL,0xd34590b2af8d5L,0x1601781acf885L,0x486683566d0a1L,\n        0x052f3ef01ba6cL },\n      { 0x6732a0edcb64dL,0x238068379f398L,0x040f3090a482cL,0x7e7516cbe5fa7L,\n        0x03296bd899ef2L } },\n    /* 167 */\n    { { 0xaba89454d81d7L,0xef51eb9b3c476L,0x1c579869eade7L,0x71e9619a21cd8L,\n        0x03b90febfaee5L },\n      { 0x3023e5496f7cbL,0xd87fb51bc4939L,0x9beb5ce55be41L,0x0b1803f1dd489L,\n        0x06e88069d9f81L } },\n    /* 168 */\n    { { 0x7ab11b43ea1dbL,0xa95259d292ce3L,0xf84f1860a7ff1L,0xad13851b02218L,\n        0x0a7222beadefaL },\n      { 0xc78ec2b0a9144L,0x51f2fa59c5a2aL,0x147ce385a0240L,0xc69091d1eca56L,\n        0x0be94d523bc2aL } },\n    /* 169 */\n    { { 0x4945e0b226ce7L,0x47967e8b7072fL,0x5a6c63eb8afd7L,0xc766edea46f18L,\n        0x07782defe9be8L },\n      { 0xd2aa43db38626L,0x8776f67ad1760L,0x4499cdb460ae7L,0x2e4b341b86fc5L,\n        0x003838567a289L } },\n    /* 170 */\n    { { 0xdaefd79ec1a0fL,0xfdceb39c972d8L,0x8f61a953bbcd6L,0xb420f5575ffc5L,\n        0x0dbd986c4adf7L },\n      { 0xa881415f39eb7L,0xf5b98d976c81aL,0xf2f717d6ee2fcL,0xbbd05465475dcL,\n        0x08e24d3c46860L } },\n    /* 171 */\n    { { 0xd8e549a587390L,0x4f0cbec588749L,0x25983c612bb19L,0xafc846e07da4bL,\n        0x0541a99c4407bL },\n      { 0x41692624c8842L,0x2ad86c05ffdb2L,0xf7fcf626044c1L,0x35d1c59d14b44L,\n        0x0c0092c49f57dL } },\n    /* 172 */\n    { { 0xc75c3df2e61efL,0xc82e1b35cad3cL,0x09f29f47e8841L,0x944dc62d30d19L,\n        0x075e406347286L },\n      { 0x41fc5bbc237d0L,0xf0ec4f01c9e7dL,0x82bd534c9537bL,0x858691c51a162L,\n        0x05b7cb658c784L } },\n    /* 173 */\n    { { 0xa70848a28ead1L,0x08fd3b47f6964L,0x67e5b39802dc5L,0x97a19ae4bfd17L,\n        0x07ae13eba8df0L },\n      { 0x16ef8eadd384eL,0xd9b6b2ff06fd2L,0xbcdb5f30361a2L,0xe3fd204b98784L,\n        0x0787d8074e2a8L } },\n    /* 174 */\n    { { 0x25d6b757fbb1cL,0xb2ca201debc5eL,0xd2233ffe47bddL,0x84844a55e9a36L,\n        0x05c2228199ef2L },\n      { 0xd4a8588315250L,0x2b827097c1773L,0xef5d33f21b21aL,0xf2b0ab7c4ea1dL,\n        0x0e45d37abbaf0L } },\n    /* 175 */\n    { { 0xf1e3428511c8aL,0xc8bdca6cd3d2dL,0x27c39a7ebb229L,0xb9d3578a71a76L,\n        0x0ed7bc12284dfL },\n      { 0x2a6df93dea561L,0x8dd48f0ed1cf2L,0xbad23e85443f1L,0x6d27d8b861405L,\n        0x0aac97cc945caL } },\n    /* 176 */\n    { { 0x4ea74a16bd00aL,0xadf5c0bcc1eb5L,0xf9bfc06d839e9L,0xdc4e092bb7f11L,\n        0x0318f97b31163L },\n      { 0x0c5bec30d7138L,0x23abc30220eccL,0x022360644e8dfL,0xff4d2bb7972fbL,\n        0x0fa41faa19a84L } },\n    /* 177 */\n    { { 0x2d974a6642269L,0xce9bb783bd440L,0x941e60bc81814L,0xe9e2398d38e47L,\n        0x038bb6b2c1d26L },\n      { 0xe4a256a577f87L,0x53dc11fe1cc64L,0x22807288b52d2L,0x01a5ff336abf6L,\n        0x094dd0905ce76L } },\n    /* 178 */\n    { { 0xcf7dcde93f92aL,0xcb89b5f315156L,0x995e750a01333L,0x2ae902404df9cL,\n        0x092077867d25cL },\n      { 0x71e010bf39d44L,0x2096bb53d7e24L,0xc9c3d8f5f2c90L,0xeb514c44b7b35L,\n        0x081e8428bd29bL } },\n    /* 179 */\n    { { 0x9c2bac477199fL,0xee6b5ecdd96ddL,0xe40fd0e8cb8eeL,0xa4b18af7db3feL,\n        0x01b94ab62dbbfL },\n      { 0x0d8b3ce47f143L,0xfc63f4616344fL,0xc59938351e623L,0x90eef18f270fcL,\n        0x006a38e280555L } },\n    /* 180 */\n    { { 0xb0139b3355b49L,0x60b4ebf99b2e5L,0x269f3dc20e265L,0xd4f8c08ffa6bdL,\n        0x0a7b36c2083d9L },\n      { 0x15c3a1b3e8830L,0xe1a89f9c0b64dL,0x2d16930d5fceaL,0x2a20cfeee4a2eL,\n        0x0be54c6b4a282L } },\n    /* 181 */\n    { { 0xdb3df8d91167cL,0x79e7a6625ed6cL,0x46ac7f4517c3fL,0x22bb7105648f3L,\n        0x0bf30a5abeae0L },\n      { 0x785be93828a68L,0x327f3ef0368e7L,0x92146b25161c3L,0xd13ae11b5feb5L,\n        0x0d1c820de2732L } },\n    /* 182 */\n    { { 0xe13479038b363L,0x546b05e519043L,0x026cad158c11fL,0x8da34fe57abe6L,\n        0x0b7d17bed68a1L },\n      { 0xa5891e29c2559L,0x765bfffd8444cL,0x4e469484f7a03L,0xcc64498de4af7L,\n        0x03997fd5e6412L } },\n    /* 183 */\n    { { 0x746828bd61507L,0xd534a64d2af20L,0xa8a15e329e132L,0x13e8ffeddfb08L,\n        0x00eeb89293c6cL },\n      { 0x69a3ea7e259f8L,0xe6d13e7e67e9bL,0xd1fa685ce1db7L,0xb6ef277318f6aL,\n        0x0228916f8c922L } },\n    /* 184 */\n    { { 0xae25b0a12ab5bL,0x1f957bc136959L,0x16e2b0ccc1117L,0x097e8058429edL,\n        0x0ec05ad1d6e93L },\n      { 0xba5beac3f3708L,0x3530b59d77157L,0x18234e531baf9L,0x1b3747b552371L,\n        0x07d3141567ff1L } },\n    /* 185 */\n    { { 0x9c05cf6dfefabL,0x68dcb377077bdL,0xa38bb95be2f22L,0xd7a3e53ead973L,\n        0x0e9ce66fc9bc1L },\n      { 0xa15766f6a02a1L,0xdf60e600ed75aL,0x8cdc1b938c087L,0x0651f8947f346L,\n        0x0d9650b017228L } },\n    /* 186 */\n    { { 0xb4c4a5a057e60L,0xbe8def25e4504L,0x7c1ccbdcbccc3L,0xb7a2a63532081L,\n        0x014d6699a804eL },\n      { 0xa8415db1f411aL,0x0bf80d769c2c8L,0xc2f77ad09fbafL,0x598ab4deef901L,\n        0x06f4c68410d43L } },\n    /* 187 */\n    { { 0x6df4e96c24a96L,0x85fcbd99a3872L,0xb2ae30a534dbcL,0x9abb3c466ef28L,\n        0x04c4350fd6118L },\n      { 0x7f716f855b8daL,0x94463c38a1296L,0xae9334341a423L,0x18b5c37e1413eL,\n        0x0a726d2425a31L } },\n    /* 188 */\n    { { 0x6b3ee948c1086L,0x3dcbd3a2e1daeL,0x3d022f3f1de50L,0xf3923f35ed3f0L,\n        0x013639e82cc6cL },\n      { 0x938fbcdafaa86L,0xfb2654a2589acL,0x5051329f45bc5L,0x35a31963b26e4L,\n        0x0ca9365e1c1a3L } },\n    /* 189 */\n    { { 0x5ac754c3b2d20L,0x17904e241b361L,0xc9d071d742a54L,0x72a5b08521c4cL,\n        0x09ce29c34970bL },\n      { 0x81f736d3e0ad6L,0x9ef2f8434c8ccL,0xce862d98060daL,0xaf9835ed1d1a6L,\n        0x048c4abd7ab42L } },\n    /* 190 */\n    { { 0x1b0cc40c7485aL,0xbbe5274dbfd22L,0x263d2e8ead455L,0x33cb493c76989L,\n        0x078017c32f67bL },\n      { 0x35769930cb5eeL,0x940c408ed2b9dL,0x72f1a4dc0d14eL,0x1c04f8b7bf552L,\n        0x053cd0454de5cL } },\n    /* 191 */\n    { { 0x585fa5d28ccacL,0x56005b746ebcdL,0xd0123aa5f823eL,0xfa8f7c79f0a1cL,\n        0x0eea465c1d3d7L },\n      { 0x0659f0551803bL,0x9f7ce6af70781L,0x9288e706c0b59L,0x91934195a7702L,\n        0x01b6e42a47ae6L } },\n    /* 192 */\n    { { 0x0937cf67d04c3L,0xe289eeb8112e8L,0x2594d601e312bL,0xbd3d56b5d8879L,\n        0x00224da14187fL },\n      { 0xbb8630c5fe36fL,0x604ef51f5f87aL,0x3b429ec580f3cL,0xff33964fb1bfbL,\n        0x060838ef042bfL } },\n    /* 193 */\n    { { 0xcb2f27e0bbe99L,0xf304aa39ee432L,0xfa939037bda44L,0x16435f497c7a9L,\n        0x0636eb2022d33L },\n      { 0xd0e6193ae00aaL,0xfe31ae6d2ffcfL,0xf93901c875a00L,0x8bacf43658a29L,\n        0x08844eeb63921L } },\n    /* 194 */\n    { { 0x171d26b3bae58L,0x7117e39f3e114L,0x1a8eada7db3dfL,0x789ecd37bc7f8L,\n        0x027ba83dc51fbL },\n      { 0xf439ffbf54de5L,0x0bb5fe1a71a7dL,0xb297a48727703L,0xa4ab42ee8e35dL,\n        0x0adb62d3487f3L } },\n    /* 195 */\n    { { 0x168a2a175df2aL,0x4f618c32e99b1L,0x46b0916082aa0L,0xc8b2c9e4f2e71L,\n        0x0b990fd7675e7L },\n      { 0x9d96b4df37313L,0x79d0b40789082L,0x80877111c2055L,0xd18d66c9ae4a7L,\n        0x081707ef94d10L } },\n    /* 196 */\n    { { 0x7cab203d6ff96L,0xfc0d84336097dL,0x042db4b5b851bL,0xaa5c268823c4dL,\n        0x03792daead5a8L },\n      { 0x18865941afa0bL,0x4142d83671528L,0xbe4e0a7f3e9e7L,0x01ba17c825275L,\n        0x05abd635e94b0L } },\n    /* 197 */\n    { { 0xfa84e0ac4927cL,0x35a7c8cf23727L,0xadca0dfe38860L,0xb610a4bcd5ea4L,\n        0x05995bf21846aL },\n      { 0xf860b829dfa33L,0xae958fc18be90L,0x8630366caafe2L,0x411e9b3baf447L,\n        0x044c32ca2d483L } },\n    /* 198 */\n    { { 0xa97f1e40ed80cL,0xb131d2ca82a74L,0xc2d6ad95f938cL,0xa54c53f2124b7L,\n        0x01f2162fb8082L },\n      { 0x67cc5720b173eL,0x66085f12f97e4L,0xc9d65dc40e8a6L,0x07c98cebc20e4L,\n        0x08f1d402bc3e9L } },\n    /* 199 */\n    { { 0x92f9cfbc4058aL,0xb6292f56704f5L,0xc1d8c57b15e14L,0xdbf9c55cfe37bL,\n        0x0b1980f43926eL },\n      { 0x33e0932c76b09L,0x9d33b07f7898cL,0x63bb4611df527L,0x8e456f08ead48L,\n        0x02828ad9b3744L } },\n    /* 200 */\n    { { 0x722c4c4cf4ac5L,0x3fdde64afb696L,0x0890832f5ac1aL,0xb3900551baa2eL,\n        0x04973f1275a14L },\n      { 0xd8335322eac5dL,0xf50bd9b568e59L,0x25883935e07eeL,0x8ac7ab36720faL,\n        0x06dac8ed0db16L } },\n    /* 201 */\n    { { 0x545aeeda835efL,0xd21d10ed51f7bL,0x3741b094aa113L,0xde4c035a65e01L,\n        0x04b23ef5920b9L },\n      { 0xbb6803c4c7341L,0x6d3f58bc37e82L,0x51e3ee8d45770L,0x9a4e73527863aL,\n        0x04dd71534ddf4L } },\n    /* 202 */\n    { { 0x4467295476cd9L,0x2fe31a725bbf9L,0xc4b67e0648d07L,0x4dbb1441c8b8fL,\n        0x0fd3170002f4aL },\n      { 0x43ff48995d0e1L,0xd10ef729aa1cbL,0x179898276e695L,0xf365e0d5f9764L,\n        0x014fac58c9569L } },\n    /* 203 */\n    { { 0xa0065f312ae18L,0xc0fcc93fc9ad9L,0xa7d284651958dL,0xda50d9a142408L,\n        0x0ed7c765136abL },\n      { 0x70f1a25d4abbcL,0xf3f1a113ea462L,0xb51952f9b5dd8L,0x9f53c609b0755L,\n        0x0fefcb7f74d2eL } },\n    /* 204 */\n    { { 0x9497aba119185L,0x30aac45ba4bd0L,0xa521179d54e8cL,0xd80b492479deaL,\n        0x01801a57e87e0L },\n      { 0xd3f8dfcafffb0L,0x0bae255240073L,0xb5fdfbc6cf33cL,0x1064781d763b5L,\n        0x09f8fc11e1eadL } },\n    /* 205 */\n    { { 0x3a1715e69544cL,0x67f04b7813158L,0x78a4c320eaf85L,0x69a91e22a8fd2L,\n        0x0a9d3809d3d3aL },\n      { 0xc2c2c59a2da3bL,0xf61895c847936L,0x3d5086938ccbcL,0x8ef75e65244e6L,\n        0x03006b9aee117L } },\n    /* 206 */\n    { { 0x1f2b0c9eead28L,0x5d89f4dfbc0bbL,0x2ce89397eef63L,0xf761074757fdbL,\n        0x00ab85fd745f8L },\n      { 0xa7c933e5b4549L,0x5c97922f21ecdL,0x43b80404be2bbL,0x42c2261a1274bL,\n        0x0b122d67511e9L } },\n    /* 207 */\n    { { 0x607be66a5ae7aL,0xfa76adcbe33beL,0xeb6e5c501e703L,0xbaecaf9043014L,\n        0x09f599dc1097dL },\n      { 0x5b7180ff250edL,0x74349a20dc6d7L,0x0b227a38eb915L,0x4b78425605a41L,\n        0x07d5528e08a29L } },\n    /* 208 */\n    { { 0x58f6620c26defL,0xea582b2d1ef0fL,0x1ce3881025585L,0x1730fbe7d79b0L,\n        0x028ccea01303fL },\n      { 0xabcd179644ba5L,0xe806fff0b8d1dL,0x6b3e17b1fc643L,0x13bfa60a76fc6L,\n        0x0c18baf48a1d0L } },\n    /* 209 */\n    { { 0x638c85dc4216dL,0x67206142ac34eL,0x5f5064a00c010L,0x596bd453a1719L,\n        0x09def809db7a9L },\n      { 0x8642e67ab8d2cL,0x336237a2b641eL,0x4c4218bb42404L,0x8ce57d506a6d6L,\n        0x00357f8b06880L } },\n    /* 210 */\n    { { 0xdbe644cd2cc88L,0x8df0b8f39d8e9L,0xd30a0c8cc61c2L,0x98874a309874cL,\n        0x0e4a01add1b48L },\n      { 0x1eeacf57cd8f9L,0x3ebd594c482edL,0xbd2f7871b767dL,0xcc30a7295c717L,\n        0x0466d7d79ce10L } },\n    /* 211 */\n    { { 0x318929dada2c7L,0xc38f9aa27d47dL,0x20a59e14fa0a6L,0xad1a90e4fd288L,\n        0x0c672a522451eL },\n      { 0x07cc85d86b655L,0x3bf9ad4af1306L,0x71172a6f0235dL,0x751399a086805L,\n        0x05e3d64faf2a6L } },\n    /* 212 */\n    { { 0x410c79b3b4416L,0x85eab26d99aa6L,0xb656a74cd8fcfL,0x42fc5ebff74adL,\n        0x06c8a7a95eb8eL },\n      { 0x60ba7b02a63bdL,0x038b8f004710cL,0x12d90b06b2f23L,0xca918c6c37383L,\n        0x0348ae422ad82L } },\n    /* 213 */\n    { { 0x746635ccda2fbL,0xa18e0726d27f4L,0x92b1f2022accaL,0x2d2e85adf7824L,\n        0x0c1074de0d9efL },\n      { 0x3ce44ae9a65b3L,0xac05d7151bfcfL,0xe6a9788fd71e4L,0x4ffcd4711f50cL,\n        0x0fbadfbdbc9e5L } },\n    /* 214 */\n    { { 0x3f1cd20a99363L,0x8f6cf22775171L,0x4d359b2b91565L,0x6fcd968175cd2L,\n        0x0b7f976b48371L },\n      { 0x8e24d5d6dbf74L,0xfd71c3af36575L,0x243dfe38d23baL,0xc80548f477600L,\n        0x0f4d41b2ecafcL } },\n    /* 215 */\n    { { 0x1cf28fdabd48dL,0x3632c078a451fL,0x17146e9ce81beL,0x0f106ace29741L,\n        0x0180824eae016L },\n      { 0x7698b66e58358L,0x52ce6ca358038L,0xe41e6c5635687L,0x6d2582380e345L,\n        0x067e5f63983cfL } },\n    /* 216 */\n    { { 0xccb8dcf4899efL,0xf09ebb44c0f89L,0x2598ec9949015L,0x1fc6546f9276bL,\n        0x09fef789a04c1L },\n      { 0x67ecf53d2a071L,0x7fa4519b096d3L,0x11e2eefb10e1aL,0x4e20ca6b3fb06L,\n        0x0bc80c181a99cL } },\n    /* 217 */\n    { { 0x536f8e5eb82e6L,0xc7f56cb920972L,0x0b5da5e1a484fL,0xdf10c78e21715L,\n        0x049270e629f8cL },\n      { 0x9b7bbea6b50adL,0xc1a2388ffc1a3L,0x107197b9a0284L,0x2f7f5403eb178L,\n        0x0d2ee52f96137L } },\n    /* 218 */\n    { { 0xcd28588e0362aL,0xa78fa5d94dd37L,0x434a526442fa8L,0xb733aff836e5aL,\n        0x0dfb478bee5abL },\n      { 0xf1ce7673eede6L,0xd42b5b2f04a91L,0x530da2fa5390aL,0x473a5e66f7bf5L,\n        0x0d9a140b408dfL } },\n    /* 219 */\n    { { 0x221b56e8ea498L,0x293563ee090e0L,0x35d2ade623478L,0x4b1ae06b83913L,\n        0x0760c058d623fL },\n      { 0x9b58cc198aa79L,0xd2f07aba7f0b8L,0xde2556af74890L,0x04094e204110fL,\n        0x07141982d8f19L } },\n    /* 220 */\n    { { 0xa0e334d4b0f45L,0x38392a94e16f0L,0x3c61d5ed9280bL,0x4e473af324c6bL,\n        0x03af9d1ce89d5L },\n      { 0xf798120930371L,0x4c21c17097fd8L,0xc42309beda266L,0x7dd60e9545dcdL,\n        0x0b1f815c37395L } },\n    /* 221 */\n    { { 0xaa78e89fec44aL,0x473caa4caf84fL,0x1b6a624c8c2aeL,0xf052691c807dcL,\n        0x0a41aed141543L },\n      { 0x353997d5ffe04L,0xdf625b6e20424L,0x78177758bacb2L,0x60ef85d660be8L,\n        0x0d6e9c1dd86fbL } },\n    /* 222 */\n    { { 0x2e97ec6853264L,0xb7e2304a0b3aaL,0x8eae9be771533L,0xf8c21b912bb7bL,\n        0x09c9c6e10ae9bL },\n      { 0x09a59e030b74cL,0x4d6a631e90a23L,0x49b79f24ed749L,0x61b689f44b23aL,\n        0x0566bd59640faL } },\n    /* 223 */\n    { { 0xc0118c18061f3L,0xd37c83fc70066L,0x7273245190b25L,0x345ef05fc8e02L,\n        0x0cf2c7390f525L },\n      { 0xbceb410eb30cfL,0xba0d77703aa09L,0x50ff255cfd2ebL,0x0979e842c43a1L,\n        0x002f517558aa2L } },\n    /* 224 */\n    { { 0xef794addb7d07L,0x4224455500396L,0x78aa3ce0b4fc7L,0xd97dfaff8eaccL,\n        0x014e9ada5e8d4L },\n      { 0x480a12f7079e2L,0xcde4b0800edaaL,0x838157d45baa3L,0x9ae801765e2d7L,\n        0x0a0ad4fab8e9dL } },\n    /* 225 */\n    { { 0xb76214a653618L,0x3c31eaaa5f0bfL,0x4949d5e187281L,0xed1e1553e7374L,\n        0x0bcd530b86e56L },\n      { 0xbe85332e9c47bL,0xfeb50059ab169L,0x92bfbb4dc2776L,0x341dcdba97611L,\n        0x0909283cf6979L } },\n    /* 226 */\n    { { 0x0032476e81a13L,0x996217123967bL,0x32e19d69bee1aL,0x549a08ed361bdL,\n        0x035eeb7c9ace1L },\n      { 0x0ae5a7e4e5bdcL,0xd3b6ceec6e128L,0xe266bc12dcd2cL,0xe86452e4224c6L,\n        0x09a8b2cf4448aL } },\n    /* 227 */\n    { { 0x71bf209d03b59L,0xa3b65af2abf64L,0xbd5eec9c90e62L,0x1379ff7ff168eL,\n        0x06bdb60f4d449L },\n      { 0xafebc8a55bc30L,0x1610097fe0dadL,0xc1e3bddc79eadL,0x08a942e197414L,\n        0x001ec3cfd94baL } },\n    /* 228 */\n    { { 0x277ebdc9485c2L,0x7922fb10c7ba6L,0x0a28d8a48cc9aL,0x64f64f61d60f7L,\n        0x0d1acb1c04754L },\n      { 0x902b126f36612L,0x4ee0618d8bd26L,0x08357ee59c3a4L,0x26c24df8a8133L,\n        0x07dcd079d4056L } },\n    /* 229 */\n    { { 0x7d4d3f05a4b48L,0x52372307725ceL,0x12a915aadcd29L,0x19b8d18f79718L,\n        0x00bf53589377dL },\n      { 0xcd95a6c68ea73L,0xca823a584d35eL,0x473a723c7f3bbL,0x86fc9fb674c6fL,\n        0x0d28be4d9e166L } },\n    /* 230 */\n    { { 0xb990638fa8e4bL,0x6e893fd8fc5d2L,0x36fb6fc559f18L,0x88ce3a6de2aa4L,\n        0x0d76007aa510fL },\n      { 0x0aab6523a4988L,0x4474dd02732d1L,0x3407278b455cfL,0xbb017f467082aL,\n        0x0f2b52f68b303L } },\n    /* 231 */\n    { { 0x7eafa9835b4caL,0xfcbb669cbc0d5L,0x66431982d2232L,0xed3a8eeeb680cL,\n        0x0d8dbe98ecc5aL },\n      { 0x9be3fc5a02709L,0xe5f5ba1fa8cbaL,0x10ea85230be68L,0x9705febd43cdfL,\n        0x0e01593a3ee55L } },\n    /* 232 */\n    { { 0x5af50ea75a0a6L,0xac57858033d3eL,0x0176406512226L,0xef066fe6d50fdL,\n        0x0afec07b1aeb8L },\n      { 0x9956780bb0a31L,0xcc37309aae7fbL,0x1abf3896f1af3L,0xbfdd9153a15a0L,\n        0x0a71b93546e2dL } },\n    /* 233 */\n    { { 0xe12e018f593d2L,0x28a078122bbf8L,0xba4f2add1a904L,0x23d9150505db0L,\n        0x053a2005c6285L },\n      { 0x8b639e7f2b935L,0x5ac182961a07cL,0x518ca2c2bff97L,0x8e3d86bceea77L,\n        0x0bf47d19b3d58L } },\n    /* 234 */\n    { { 0x967a7dd7665d5L,0x572f2f4de5672L,0x0d4903f4e3030L,0xa1b6144005ae8L,\n        0x0001c2c7f39c9L },\n      { 0xa801469efc6d6L,0xaa7bc7a724143L,0x78150a4c810bdL,0xb99b5f65670baL,\n        0x0fdadf8e786ffL } },\n    /* 235 */\n    { { 0x8cb88ffc00785L,0x913b48eb67fd3L,0xf368fbc77fa75L,0x3c940454d055bL,\n        0x03a838e4d5aa4L },\n      { 0x663293e97bb9aL,0x63441d94d9561L,0xadb2a839eb933L,0x1da3515591a60L,\n        0x03cdb8257873eL } },\n    /* 236 */\n    { { 0x140a97de77eabL,0x0d41648109137L,0xeb1d0dff7e1c5L,0x7fba762dcad2cL,\n        0x05a60cc89f1f5L },\n      { 0x3638240d45673L,0x195913c65580bL,0xd64b7411b82beL,0x8fc0057284b8dL,\n        0x0922ff56fdbfdL } },\n    /* 237 */\n    { { 0x65deec9a129a1L,0x57cc284e041b2L,0xebfbe3ca5b1ceL,0xcd6204380c46cL,\n        0x072919a7df6c5L },\n      { 0xf453a8fb90f9aL,0x0b88e4031b298L,0x96f1856d719c0L,0x089ae32c0e777L,\n        0x05e7917803624L } },\n    /* 238 */\n    { { 0x6ec557f63cdfbL,0x71f1cae4fd5c1L,0x60597ca8e6a35L,0x2fabfce26bea5L,\n        0x04e0a5371e24cL },\n      { 0xa40d3a5765357L,0x440d73a2b4276L,0x1d11a323c89afL,0x04eeb8f370ae4L,\n        0x0f5ff7818d566L } },\n    /* 239 */\n    { { 0x3e3fe1a09df21L,0x8ee66e8e47fbfL,0x9c8901526d5d2L,0x5e642096bd0a2L,\n        0x0e41df0e9533fL },\n      { 0xfda40b3ba9e3fL,0xeb2604d895305L,0xf0367c7f2340cL,0x155f0866e1927L,\n        0x08edd7d6eac4fL } },\n    /* 240 */\n    { { 0x1dc0e0bfc8ff3L,0x2be936f42fc9aL,0xca381ef14efd8L,0xee9667016f7ccL,\n        0x01432c1caed8aL },\n      { 0x8482970b23c26L,0x730735b273ec6L,0xaef0f5aa64fe8L,0xd2c6e389f6e5eL,\n        0x0caef480b5ac8L } },\n    /* 241 */\n    { { 0x5c97875315922L,0x713063cca5524L,0x64ef2cbd82951L,0xe236f3ce60d0bL,\n        0x0d0ba177e8efaL },\n      { 0x9ae8fb1b3af60L,0xe53d2da20e53aL,0xf9eef281a796aL,0xae1601d63605dL,\n        0x0f31c957c1c54L } },\n    /* 242 */\n    { { 0x58d5249cc4597L,0xb0bae0a028c0fL,0x34a814adc5015L,0x7c3aefc5fc557L,\n        0x0013404cb96e1L },\n      { 0xe2585c9a824bfL,0x5e001eaed7b29L,0x1ef68acd59318L,0x3e6c8d6ee6826L,\n        0x06f377c4b9193L } },\n    /* 243 */\n    { { 0x3bad1a8333fd2L,0x025a2a95b89f9L,0xaf75acea89302L,0x9506211e5037eL,\n        0x06dba3e4ed2d0L },\n      { 0xef98cd04399cdL,0x6ee6b73adea48L,0x17ecaf31811c6L,0xf4a772f60752cL,\n        0x0f13cf3423becL } },\n    /* 244 */\n    { { 0xb9ec0a919e2ebL,0x95f62c0f68ceeL,0xaba229983a9a1L,0xbad3cfba3bb67L,\n        0x0c83fa9a9274bL },\n      { 0xd1b0b62fa1ce0L,0xf53418efbf0d7L,0x2706f04e58b60L,0x2683bfa8ef9e5L,\n        0x0b49d70f45d70L } },\n    /* 245 */\n    { { 0xc7510fad5513bL,0xecb1751e2d914L,0x9fb9d5905f32eL,0xf1cf6d850418dL,\n        0x059cfadbb0c30L },\n      { 0x7ac2355cb7fd6L,0xb8820426a3e16L,0x0a78864249367L,0x4b67eaeec58c9L,\n        0x05babf362354aL } },\n    /* 246 */\n    { { 0x981d1ee424865L,0x78f2e5577f37cL,0x9e0c0588b0028L,0xc8f0702970f1bL,\n        0x06188c6a79026L },\n      { 0x9a19bd0f244daL,0x5cfb08087306fL,0xf2136371eccedL,0xb9d935470f9b9L,\n        0x0993fe475df50L } },\n    /* 247 */\n    { { 0x31cdf9b2c3609L,0xc02c46d4ea68eL,0xa77510184eb19L,0x616b7ac9ec1a9L,\n        0x081f764664c80L },\n      { 0xc2a5a75fbe978L,0xd3f183b3561d7L,0x01dd2bf6743feL,0x060d838d1f045L,\n        0x0564a812a5fe9L } },\n    /* 248 */\n    { { 0xa64f4fa817d1dL,0x44bea82e0f7a5L,0xd57f9aa55f968L,0x1d6cb5ff5a0fcL,\n        0x0226bf3cf00e5L },\n      { 0x1a9f92f2833cfL,0x5a4f4f89a8d6dL,0xf3f7f7720a0a3L,0x783611536c498L,\n        0x068779f47ff25L } },\n    /* 249 */\n    { { 0x0c1c173043d08L,0x741fc020fa79bL,0xa6d26d0a54467L,0x2e0bd3767e289L,\n        0x097bcb0d1eb09L },\n      { 0x6eaa8f32ed3c3L,0x51b281bc482abL,0xfa178f3c8a4f1L,0x46554d1bf4f3bL,\n        0x0a872ffe80a78L } },\n    /* 250 */\n    { { 0xb7935a32b2086L,0x0e8160f486b1aL,0xb6ae6bee1eb71L,0xa36a9bd0cd913L,\n        0x002812bfcb732L },\n      { 0xfd7cacf605318L,0x50fdfd6d1da63L,0x102d619646e5dL,0x96afa1d683982L,\n        0x007391cc9fe53L } },\n    /* 251 */\n    { { 0x157f08b80d02bL,0xd162877f7fc50L,0x8d542ae6b8333L,0x2a087aca1af87L,\n        0x0355d2adc7e6dL },\n      { 0xf335a287386e1L,0x94f8e43275b41L,0x79989eafd272aL,0x3a79286ca2cdeL,\n        0x03dc2b1e37c2aL } },\n    /* 252 */\n    { { 0x9d21c04581352L,0x25376782bed68L,0xfed701f0a00c8L,0x846b203bd5909L,\n        0x0c47869103ccdL },\n      { 0xa770824c768edL,0x026841f6575dbL,0xaccce0e72feeaL,0x4d3273313ed56L,\n        0x0ccc42968d5bbL } },\n    /* 253 */\n    { { 0x50de13d7620b9L,0x8a5992a56a94eL,0x75487c9d89a5cL,0x71cfdc0076406L,\n        0x0e147eb42aa48L },\n      { 0xab4eeacf3ae46L,0xfb50350fbe274L,0x8c840eafd4936L,0x96e3df2afe474L,\n        0x0239ac047080eL } },\n    /* 254 */\n    { { 0xd1f352bfee8d4L,0xcffa7b0fec481L,0xce9af3cce80b5L,0xe59d105c4c9e2L,\n        0x0c55fa1a3f5f7L },\n      { 0x6f14e8257c227L,0x3f342be00b318L,0xa904fb2c5b165L,0xb69909afc998aL,\n        0x0094cd99cd4f4L } },\n    /* 255 */\n    { { 0x81c84d703bebaL,0x5032ceb2918a9L,0x3bd49ec8631d1L,0xad33a445f2c9eL,\n        0x0b90a30b642abL },\n      { 0x5404fb4a5abf9L,0xc375db7603b46L,0xa35d89f004750L,0x24f76f9a42cccL,\n        0x0019f8b9a1b79L } },\n};\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_5(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_stripe_5(r, &p256_base, p256_table,\n                                      k, map, heap);\n}\n\n#endif\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[5];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 5, km);\n\n            err = sp_256_ecc_mulmod_base_5(point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_5(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                                        defined(HAVE_ECC_VERIFY)\n/* Returns 1 if the number of zero.\n * Implementation is constant time.\n *\n * a  Number to check.\n * returns 1 if the number is zero and 0 otherwise.\n */\nstatic int sp_256_iszero_5(const sp_digit* a)\n{\n    return (a[0] | a[1] | a[2] | a[3] | a[4]) == 0;\n}\n\n#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\n/* Add 1 to a. (a = a + 1)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_256_add_one_5(sp_digit* a)\n{\n    a[0]++;\n    sp_256_norm_5(a);\n}\n\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 44U) {\n            r[j] &= 0xfffffffffffffL;\n            s = 52U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Generates a scalar that is in the range 1..order-1.\n *\n * rng  Random number generator.\n * k    Scalar value.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nstatic int sp_256_ecc_gen_k_5(WC_RNG* rng, sp_digit* k)\n{\n    int err;\n    byte buf[32];\n\n    do {\n        err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));\n        if (err == 0) {\n            sp_256_from_bin(k, 5, buf, (int)sizeof(buf));\n            if (sp_256_cmp_5(k, p256_order2) < 0) {\n                sp_256_add_one_5(k);\n                break;\n            }\n        }\n    }\n    while (err == 0);\n\n    return err;\n}\n\n/* Makes a random EC key pair.\n *\n * rng   Random number generator.\n * priv  Generated private value.\n * pub   Generated public point.\n * heap  Heap to use for allocation.\n * returns ECC_INF_E when the point does not have the correct order, RNG\n * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[5];\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point inf;\n#endif\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point* infinity;\n#endif\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, inf, infinity);\n    }\n#endif\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_ecc_gen_k_5(rng, k);\n    }\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_base_5(point, k, 1, NULL);\n    }\n\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_5(infinity, point, p256_order, 1, NULL);\n    }\n    if (err == MP_OKAY) {\n        if ((sp_256_iszero_5(point->x) == 0) || (sp_256_iszero_5(point->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(k, priv);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_5(point, pub);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_ecc_point_free(infinity, 1, heap);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n\n#ifdef HAVE_ECC_DHE\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 32\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_256_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    for (i=0; i<4; i++) {\n        r[i+1] += r[i] >> 52;\n        r[i] &= 0xfffffffffffffL;\n    }\n    j = 256 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<5 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 52) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 52);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n/* Multiply the point by the scalar and serialize the X ordinate.\n * The number is 0 padded to maximum size on output.\n *\n * priv    Scalar to multiply the point by.\n * pub     Point to multiply.\n * out     Buffer to hold X ordinate.\n * outLen  On entry, size of the buffer in bytes.\n *         On exit, length of data in buffer in bytes.\n * heap    Heap to use for allocation.\n * returns BUFFER_E if the buffer is to small for output size,\n * MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out,\n                          word32* outLen, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[5];\n#endif\n    sp_point* point = NULL;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    if (*outLen < 32U) {\n        err = BUFFER_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p, point);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 5, priv);\n        sp_256_point_from_ecc_point_5(point, pub);\n            err = sp_256_ecc_mulmod_5(point, point, k, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        sp_256_to_bin(point->x, out);\n        *outLen = 32;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_DHE */\n\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* Multiply a by scalar b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A scalar.\n */\nSP_NOINLINE static void sp_256_mul_d_5(sp_digit* r, const sp_digit* a,\n    sp_digit b)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int128_t tb = b;\n    int128_t t = 0;\n    int i;\n\n    for (i = 0; i < 5; i++) {\n        t += tb * a[i];\n        r[i] = t & 0xfffffffffffffL;\n        t >>= 52;\n    }\n    r[5] = (sp_digit)t;\n#else\n    int128_t tb = b;\n    int128_t t[5];\n\n    t[ 0] = tb * a[ 0];\n    t[ 1] = tb * a[ 1];\n    t[ 2] = tb * a[ 2];\n    t[ 3] = tb * a[ 3];\n    t[ 4] = tb * a[ 4];\n    r[ 0] =                           (t[ 0] & 0xfffffffffffffL);\n    r[ 1] = (sp_digit)(t[ 0] >> 52) + (t[ 1] & 0xfffffffffffffL);\n    r[ 2] = (sp_digit)(t[ 1] >> 52) + (t[ 2] & 0xfffffffffffffL);\n    r[ 3] = (sp_digit)(t[ 2] >> 52) + (t[ 3] & 0xfffffffffffffL);\n    r[ 4] = (sp_digit)(t[ 3] >> 52) + (t[ 4] & 0xfffffffffffffL);\n    r[ 5] = (sp_digit)(t[ 4] >> 52);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef WOLFSSL_SP_DIV_64\nstatic WC_INLINE sp_digit sp_256_div_word_5(sp_digit d1, sp_digit d0,\n    sp_digit dv)\n{\n    sp_digit d, r, t, dv;\n    int128_t t0, t1;\n\n    /* dv has 27 bits. */\n    dv = (div >> 25) + 1;\n    /* All 52 bits from d1 and top 11 bits from d0. */\n    d = (d1 << 11) | (d0 >> 41);\n    r = d / dv;\n    d -= r * dv;\n    /* Up to 36 bits in r */\n    /* Next 16 bits from d0. */\n    d <<= 16;\n    r <<= 16;\n    d |= (d0 >> 25) & ((1 << 16) - 1);\n    t = d / dv;\n    d -= t * dv;\n    r += t;\n    /* Up to 52 bits in r */\n\n    /* Handle rounding error with dv - top part */\n    t0 = ((int128_t)d1 << 52) + d0;\n    t1 = (int128_t)r * dv;\n    t1 = t0 - t1;\n    t = (sp_digit)(t1 >> 25) / dv;\n    r += t;\n\n    /* Handle rounding error with dv - bottom 64 bits */\n    t1 = (sp_digit)t0 - (r * dv);\n    t = (sp_digit)t1 / dv;\n    r += t;\n\n    return r;\n}\n#endif /* WOLFSSL_SP_DIV_64 */\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Number to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_256_div_5(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    int i;\n#ifndef WOLFSSL_SP_DIV_64\n    int128_t d1;\n#endif\n    sp_digit dv, r1;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* td;\n#else\n    sp_digit t1d[10], t2d[5 + 1];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n    (void)m;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (3 * 5 + 1), NULL,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = td;\n        t2 = td + 2 * 5;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        dv = d[4];\n        XMEMCPY(t1, a, sizeof(*t1) * 2U * 5U);\n        for (i=4; i>=0; i--) {\n            t1[5 + i] += t1[5 + i - 1] >> 52;\n            t1[5 + i - 1] &= 0xfffffffffffffL;\n#ifndef WOLFSSL_SP_DIV_64\n            d1 = t1[5 + i];\n            d1 <<= 52;\n            d1 += t1[5 + i - 1];\n            r1 = (sp_digit)(d1 / dv);\n#else\n            r1 = sp_256_div_word_5(t1[5 + i], t1[5 + i - 1], dv);\n#endif\n\n            sp_256_mul_d_5(t2, d, r1);\n            (void)sp_256_sub_5(&t1[i], &t1[i], t2);\n            t1[5 + i] -= t2[5];\n            t1[5 + i] += t1[5 + i - 1] >> 52;\n            t1[5 + i - 1] &= 0xfffffffffffffL;\n            r1 = (((-t1[5 + i]) << 52) - t1[5 + i - 1]) / dv;\n            r1++;\n            sp_256_mul_d_5(t2, d, r1);\n            (void)sp_256_add_5(&t1[i], &t1[i], t2);\n            t1[5 + i] += t1[5 + i - 1] >> 52;\n            t1[5 + i - 1] &= 0xfffffffffffffL;\n        }\n        t1[5 - 1] += t1[5 - 2] >> 52;\n        t1[5 - 2] &= 0xfffffffffffffL;\n        d1 = t1[5 - 1];\n        r1 = (sp_digit)(d1 / dv);\n\n        sp_256_mul_d_5(t2, d, r1);\n        (void)sp_256_sub_5(t1, t1, t2);\n        XMEMCPY(r, t1, sizeof(*r) * 2U * 5U);\n        for (i=0; i<3; i++) {\n            r[i+1] += r[i] >> 52;\n            r[i] &= 0xfffffffffffffL;\n        }\n        sp_256_cond_add_5(r, r, d, 0 - ((r[4] < 0) ?\n                    (sp_digit)1 : (sp_digit)0));\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MEMORY_E when unable to allocate memory and MP_OKAY otherwise.\n */\nstatic int sp_256_mod_5(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_256_div_5(a, m, NULL, r);\n}\n\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#ifdef WOLFSSL_SP_SMALL\n/* Order-2 for the P256 curve. */\nstatic const uint64_t p256_order_2[4] = {\n    0xf3b9cac2fc63254fU,0xbce6faada7179e84U,0xffffffffffffffffU,\n    0xffffffff00000000U\n};\n#else\n/* The low half of the order-2 of the P256 curve. */\nstatic const uint64_t p256_order_low[2] = {\n    0xf3b9cac2fc63254fU,0xbce6faada7179e84U\n};\n#endif /* WOLFSSL_SP_SMALL */\n\n/* Multiply two number mod the order of P256 curve. (r = a * b mod order)\n *\n * r  Result of the multiplication.\n * a  First operand of the multiplication.\n * b  Second operand of the multiplication.\n */\nstatic void sp_256_mont_mul_order_5(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_256_mul_5(r, a, b);\n    sp_256_mont_reduce_order_5(r, p256_order, p256_mp_order);\n}\n\n/* Square number mod the order of P256 curve. (r = a * a mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_order_5(sp_digit* r, const sp_digit* a)\n{\n    sp_256_sqr_5(r, a);\n    sp_256_mont_reduce_order_5(r, p256_order, p256_mp_order);\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Square number mod the order of P256 curve a number of times.\n * (r = a ^ n mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_n_order_5(sp_digit* r, const sp_digit* a, int n)\n{\n    int i;\n\n    sp_256_mont_sqr_order_5(r, a);\n    for (i=1; i<n; i++) {\n        sp_256_mont_sqr_order_5(r, r);\n    }\n}\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the order of the P256 curve.\n * (r = 1 / a mod order)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_order_5(sp_digit* r, const sp_digit* a,\n        sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 5);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_order_5(t, t);\n        if ((p256_order_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_5(t, t, a);\n        }\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 5U);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 5;\n    sp_digit* t3 = td + 4 * 5;\n    int i;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_order_5(t, a);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_order_5(t, t, a);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_order_5(t2, t, 2);\n    /* t3= a^f = t2 * t */\n    sp_256_mont_mul_order_5(t3, t2, t);\n    /* t2= a^f0 = t3 ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_order_5(t2, t3, 4);\n    /* t = a^ff = t2 * t3 */\n    sp_256_mont_mul_order_5(t, t2, t3);\n    /* t3= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_order_5(t2, t, 8);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_order_5(t, t2, t);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_order_5(t2, t, 16);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_order_5(t, t2, t);\n    /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64  */\n    sp_256_mont_sqr_n_order_5(t2, t, 64);\n    /* t2= a^ffffffff00000000ffffffff = t2 * t */\n    sp_256_mont_mul_order_5(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_order_5(t2, t2, 32);\n    /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_order_5(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6 */\n    for (i=127; i>=112; i--) {\n        sp_256_mont_sqr_order_5(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_5(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6f */\n    sp_256_mont_sqr_n_order_5(t2, t2, 4);\n    sp_256_mont_mul_order_5(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */\n    for (i=107; i>=64; i--) {\n        sp_256_mont_sqr_order_5(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_5(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */\n    sp_256_mont_sqr_n_order_5(t2, t2, 4);\n    sp_256_mont_mul_order_5(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */\n    for (i=59; i>=32; i--) {\n        sp_256_mont_sqr_order_5(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_5(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */\n    sp_256_mont_sqr_n_order_5(t2, t2, 4);\n    sp_256_mont_mul_order_5(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */\n    for (i=27; i>=0; i--) {\n        sp_256_mont_sqr_order_5(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_5(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */\n    sp_256_mont_sqr_n_order_5(t2, t2, 4);\n    /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */\n    sp_256_mont_mul_order_5(r, t2, t3);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\n#ifdef HAVE_ECC_SIGN\n#ifndef SP_ECC_MAX_SIG_GEN\n#define SP_ECC_MAX_SIG_GEN  64\n#endif\n\n/* Sign the hash using the private key.\n *   e = [hash, 256 bits] from binary\n *   r = (k.G)->x mod order\n *   s = (r * x + e) / k mod order\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,\n                    mp_int* rm, mp_int* sm, mp_int* km, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit ed[2*5];\n    sp_digit xd[2*5];\n    sp_digit kd[2*5];\n    sp_digit rd[2*5];\n    sp_digit td[3 * 2*5];\n    sp_point p;\n#endif\n    sp_digit* e = NULL;\n    sp_digit* x = NULL;\n    sp_digit* k = NULL;\n    sp_digit* r = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* point = NULL;\n    sp_digit carry;\n    sp_digit* s = NULL;\n    sp_digit* kInv = NULL;\n    int err = MP_OKAY;\n    int64_t c;\n    int i;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 5, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        e = d + 0 * 5;\n        x = d + 2 * 5;\n        k = d + 4 * 5;\n        r = d + 6 * 5;\n        tmp = d + 8 * 5;\n#else\n        e = ed;\n        x = xd;\n        k = kd;\n        r = rd;\n        tmp = td;\n#endif\n        s = e;\n        kInv = k;\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(e, 5, hash, (int)hashLen);\n    }\n\n    for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {\n        sp_256_from_mp(x, 5, priv);\n\n        /* New random point. */\n        if (km == NULL || mp_iszero(km)) {\n            err = sp_256_ecc_gen_k_5(rng, k);\n        }\n        else {\n            sp_256_from_mp(k, 5, km);\n            mp_zero(km);\n        }\n        if (err == MP_OKAY) {\n                err = sp_256_ecc_mulmod_base_5(point, k, 1, NULL);\n        }\n\n        if (err == MP_OKAY) {\n            /* r = point->x mod order */\n            XMEMCPY(r, point->x, sizeof(sp_digit) * 5U);\n            sp_256_norm_5(r);\n            c = sp_256_cmp_5(r, p256_order);\n            sp_256_cond_sub_5(r, r, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_5(r);\n\n            /* Conv k to Montgomery form (mod order) */\n                sp_256_mul_5(k, k, p256_norm_order);\n            err = sp_256_mod_5(k, k, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_5(k);\n            /* kInv = 1/k mod order */\n                sp_256_mont_inv_order_5(kInv, k, tmp);\n            sp_256_norm_5(kInv);\n\n            /* s = r * x + e */\n                sp_256_mul_5(x, x, r);\n            err = sp_256_mod_5(x, x, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_5(x);\n            carry = sp_256_add_5(s, e, x);\n            sp_256_cond_sub_5(s, s, p256_order, 0 - carry);\n            sp_256_norm_5(s);\n            c = sp_256_cmp_5(s, p256_order);\n            sp_256_cond_sub_5(s, s, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_5(s);\n\n            /* s = s * k^-1 mod order */\n                sp_256_mont_mul_order_5(s, s, kInv);\n            sp_256_norm_5(s);\n\n            /* Check that signature is usable. */\n            if (sp_256_iszero_5(s) == 0) {\n                break;\n            }\n        }\n    }\n\n    if (i == 0) {\n        err = RNG_FAILURE_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(r, rm);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(s, sm);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XMEMSET(d, 0, sizeof(sp_digit) * 8 * 5);\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    XMEMSET(e, 0, sizeof(sp_digit) * 2U * 5U);\n    XMEMSET(x, 0, sizeof(sp_digit) * 2U * 5U);\n    XMEMSET(k, 0, sizeof(sp_digit) * 2U * 5U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 5U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 5U);\n    XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 5U);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_SIGN */\n\n#ifdef HAVE_ECC_VERIFY\n/* Verify the signature values with the hash and public key.\n *   e = Truncate(hash, 256)\n *   u1 = e/s mod order\n *   u2 = r/s mod order\n *   r == (u1.G + u2.Q)->x mod order\n * Optimization: Leave point in projective form.\n *   (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')\n *   (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,\n    mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit u1d[2*5];\n    sp_digit u2d[2*5];\n    sp_digit sd[2*5];\n    sp_digit tmpd[2*5 * 5];\n    sp_point p1d;\n    sp_point p2d;\n#endif\n    sp_digit* u1 = NULL;\n    sp_digit* u2 = NULL;\n    sp_digit* s = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* p1;\n    sp_point* p2 = NULL;\n    sp_digit carry;\n    int64_t c;\n    int err;\n\n    err = sp_ecc_point_new(heap, p1d, p1);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p2d, p2);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 5, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        u1  = d + 0 * 5;\n        u2  = d + 2 * 5;\n        s   = d + 4 * 5;\n        tmp = d + 6 * 5;\n#else\n        u1 = u1d;\n        u2 = u2d;\n        s  = sd;\n        tmp = tmpd;\n#endif\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(u1, 5, hash, (int)hashLen);\n        sp_256_from_mp(u2, 5, r);\n        sp_256_from_mp(s, 5, sm);\n        sp_256_from_mp(p2->x, 5, pX);\n        sp_256_from_mp(p2->y, 5, pY);\n        sp_256_from_mp(p2->z, 5, pZ);\n\n        {\n            sp_256_mul_5(s, s, p256_norm_order);\n        }\n        err = sp_256_mod_5(s, s, p256_order);\n    }\n    if (err == MP_OKAY) {\n        sp_256_norm_5(s);\n        {\n            sp_256_mont_inv_order_5(s, s, tmp);\n            sp_256_mont_mul_order_5(u1, u1, s);\n            sp_256_mont_mul_order_5(u2, u2, s);\n        }\n\n            err = sp_256_ecc_mulmod_base_5(p1, u1, 0, heap);\n    }\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_5(p2, p2, u2, 0, heap);\n    }\n\n    if (err == MP_OKAY) {\n        {\n            sp_256_proj_point_add_5(p1, p1, p2, tmp);\n            if (sp_256_iszero_5(p1->z)) {\n                if (sp_256_iszero_5(p1->x) && sp_256_iszero_5(p1->y)) {\n                    sp_256_proj_point_dbl_5(p1, p2, tmp);\n                }\n                else {\n                    /* Y ordinate is not used from here - don't set. */\n                    p1->x[0] = 0;\n                    p1->x[1] = 0;\n                    p1->x[2] = 0;\n                    p1->x[3] = 0;\n                    p1->x[4] = 0;\n                    XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));\n                }\n            }\n        }\n\n        /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */\n        /* Reload r and convert to Montgomery form. */\n        sp_256_from_mp(u2, 5, r);\n        err = sp_256_mod_mul_norm_5(u2, u2, p256_mod);\n    }\n\n    if (err == MP_OKAY) {\n        /* u1 = r.z'.z' mod prime */\n        sp_256_mont_sqr_5(p1->z, p1->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_5(u1, u2, p1->z, p256_mod, p256_mp_mod);\n        *res = (int)(sp_256_cmp_5(p1->x, u1) == 0);\n        if (*res == 0) {\n            /* Reload r and add order. */\n            sp_256_from_mp(u2, 5, r);\n            carry = sp_256_add_5(u2, u2, p256_order);\n            /* Carry means result is greater than mod and is not valid. */\n            if (carry == 0) {\n                sp_256_norm_5(u2);\n\n                /* Compare with mod and if greater or equal then not valid. */\n                c = sp_256_cmp_5(u2, p256_mod);\n                if (c < 0) {\n                    /* Convert to Montogomery form */\n                    err = sp_256_mod_mul_norm_5(u2, u2, p256_mod);\n                    if (err == MP_OKAY) {\n                        /* u1 = (r + 1*order).z'.z' mod prime */\n                        sp_256_mont_mul_5(u1, u2, p1->z, p256_mod,\n                                                                  p256_mp_mod);\n                        *res = (int)(sp_256_cmp_5(p1->x, u1) == 0);\n                    }\n                }\n            }\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n#endif\n    sp_ecc_point_free(p1, 0, heap);\n    sp_ecc_point_free(p2, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_VERIFY */\n\n#ifdef HAVE_ECC_CHECK_KEY\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * point  EC point.\n * heap   Heap to use if dynamically allocating.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nstatic int sp_256_ecc_is_point_5(sp_point* point, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit t1d[2*5];\n    sp_digit t2d[2*5];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 4, heap, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 5;\n        t2 = d + 2 * 5;\n#else\n        (void)heap;\n\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        sp_256_sqr_5(t1, point->y);\n        (void)sp_256_mod_5(t1, t1, p256_mod);\n        sp_256_sqr_5(t2, point->x);\n        (void)sp_256_mod_5(t2, t2, p256_mod);\n        sp_256_mul_5(t2, t2, point->x);\n        (void)sp_256_mod_5(t2, t2, p256_mod);\n        (void)sp_256_sub_5(t2, p256_mod, t2);\n        sp_256_mont_add_5(t1, t1, t2, p256_mod);\n\n        sp_256_mont_add_5(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_5(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_5(t1, t1, point->x, p256_mod);\n\n        if (sp_256_cmp_5(t1, p256_b) != 0) {\n            err = MP_VAL;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * pX  X ordinate of EC point.\n * pY  Y ordinate of EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nint sp_ecc_is_point_256(mp_int* pX, mp_int* pY)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point pubd;\n#endif\n    sp_point* pub;\n    byte one[1] = { 1 };\n    int err;\n\n    err = sp_ecc_point_new(NULL, pubd, pub);\n    if (err == MP_OKAY) {\n        sp_256_from_mp(pub->x, 5, pX);\n        sp_256_from_mp(pub->y, 5, pY);\n        sp_256_from_bin(pub->z, 5, one, (int)sizeof(one));\n\n        err = sp_256_ecc_is_point_5(pub, NULL);\n    }\n\n    sp_ecc_point_free(pub, 0, NULL);\n\n    return err;\n}\n\n/* Check that the private scalar generates the EC point (px, py), the point is\n * on the curve and the point has the correct order.\n *\n * pX     X ordinate of EC point.\n * pY     Y ordinate of EC point.\n * privm  Private scalar that generates EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve, ECC_INF_E if the point does not have the correct order,\n * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and\n * MP_OKAY otherwise.\n */\nint sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit privd[5];\n    sp_point pubd;\n    sp_point pd;\n#endif\n    sp_digit* priv = NULL;\n    sp_point* pub;\n    sp_point* p = NULL;\n    byte one[1] = { 1 };\n    int err;\n\n    err = sp_ecc_point_new(heap, pubd, pub);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (priv == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK))\n        priv = privd;\n#endif\n\n        sp_256_from_mp(pub->x, 5, pX);\n        sp_256_from_mp(pub->y, 5, pY);\n        sp_256_from_bin(pub->z, 5, one, (int)sizeof(one));\n        sp_256_from_mp(priv, 5, privm);\n\n        /* Check point at infinitiy. */\n        if ((sp_256_iszero_5(pub->x) != 0) &&\n            (sp_256_iszero_5(pub->y) != 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check range of X and Y */\n        if (sp_256_cmp_5(pub->x, p256_mod) >= 0 ||\n            sp_256_cmp_5(pub->y, p256_mod) >= 0) {\n            err = ECC_OUT_OF_RANGE_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check point is on curve */\n        err = sp_256_ecc_is_point_5(pub, heap);\n    }\n\n    if (err == MP_OKAY) {\n        /* Point * order = infinity */\n            err = sp_256_ecc_mulmod_5(p, pub, p256_order, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is infinity */\n        if ((sp_256_iszero_5(p->x) == 0) ||\n            (sp_256_iszero_5(p->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Base * private = point */\n            err = sp_256_ecc_mulmod_base_5(p, priv, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is public key */\n        if (sp_256_cmp_5(p->x, pub->x) != 0 ||\n            sp_256_cmp_5(p->y, pub->y) != 0) {\n            err = ECC_PRIV_KEY_E;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (priv != NULL) {\n        XFREE(priv, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(pub, 0, heap);\n\n    return err;\n}\n#endif\n#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL\n/* Add two projective EC points together.\n * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)\n *\n * pX   First EC point's X ordinate.\n * pY   First EC point's Y ordinate.\n * pZ   First EC point's Z ordinate.\n * qX   Second EC point's X ordinate.\n * qY   Second EC point's Y ordinate.\n * qZ   Second EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* qX, mp_int* qY, mp_int* qZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 5 * 5];\n    sp_point pd;\n    sp_point qd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    sp_point* q = NULL;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(NULL, qd, q);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 5, pX);\n        sp_256_from_mp(p->y, 5, pY);\n        sp_256_from_mp(p->z, 5, pZ);\n        sp_256_from_mp(q->x, 5, qX);\n        sp_256_from_mp(q->y, 5, qY);\n        sp_256_from_mp(q->z, 5, qZ);\n\n            sp_256_proj_point_add_5(p, p, q, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(q, 0, NULL);\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Double a projective EC point.\n * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 5 * 2];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 2, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 5, pX);\n        sp_256_from_mp(p->y, 5, pY);\n        sp_256_from_mp(p->z, 5, pZ);\n\n            sp_256_proj_point_dbl_5(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Map a projective EC point to affine in place.\n * pZ will be one.\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 5 * 4];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 4, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 5, pX);\n        sp_256_from_mp(p->y, 5, pY);\n        sp_256_from_mp(p->z, 5, pZ);\n\n        sp_256_map_5(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, pX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */\n#ifdef HAVE_COMP_KEY\n/* Find the square root of a number mod the prime of the curve.\n *\n * y  The number to operate on and the result.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nstatic int sp_256_mont_sqrt_5(sp_digit* y)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit t1d[2 * 5];\n    sp_digit t2d[2 * 5];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 5, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 5;\n        t2 = d + 2 * 5;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        {\n            /* t2 = y ^ 0x2 */\n            sp_256_mont_sqr_5(t2, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0x3 */\n            sp_256_mont_mul_5(t1, t2, y, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xc */\n            sp_256_mont_sqr_n_5(t2, t1, 2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xf */\n            sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xf0 */\n            sp_256_mont_sqr_n_5(t2, t1, 4, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xff */\n            sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xff00 */\n            sp_256_mont_sqr_n_5(t2, t1, 8, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffff */\n            sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xffff0000 */\n            sp_256_mont_sqr_n_5(t2, t1, 16, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff */\n            sp_256_mont_mul_5(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000000 */\n            sp_256_mont_sqr_n_5(t1, t1, 32, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001 */\n            sp_256_mont_mul_5(t1, t1, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */\n            sp_256_mont_sqr_n_5(t1, t1, 96, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */\n            sp_256_mont_mul_5(t1, t1, y, p256_mod, p256_mp_mod);\n            sp_256_mont_sqr_n_5(y, t1, 94, p256_mod, p256_mp_mod);\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Uncompress the point given the X ordinate.\n *\n * xm    X ordinate.\n * odd   Whether the Y ordinate is odd.\n * ym    Calculated Y ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit xd[2 * 5];\n    sp_digit yd[2 * 5];\n#endif\n    sp_digit* x = NULL;\n    sp_digit* y = NULL;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 5, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        x = d + 0 * 5;\n        y = d + 2 * 5;\n#else\n        x = xd;\n        y = yd;\n#endif\n\n        sp_256_from_mp(x, 5, xm);\n        err = sp_256_mod_mul_norm_5(x, x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        /* y = x^3 */\n        {\n            sp_256_mont_sqr_5(y, x, p256_mod, p256_mp_mod);\n            sp_256_mont_mul_5(y, y, x, p256_mod, p256_mp_mod);\n        }\n        /* y = x^3 - 3x */\n        sp_256_mont_sub_5(y, y, x, p256_mod);\n        sp_256_mont_sub_5(y, y, x, p256_mod);\n        sp_256_mont_sub_5(y, y, x, p256_mod);\n        /* y = x^3 - 3x + b */\n        err = sp_256_mod_mul_norm_5(x, p256_b, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        sp_256_mont_add_5(y, y, x, p256_mod);\n        /* y = sqrt(x^3 - 3x + b) */\n        err = sp_256_mont_sqrt_5(y);\n    }\n    if (err == MP_OKAY) {\n        XMEMSET(y + 5, 0, 5U * sizeof(sp_digit));\n        sp_256_mont_reduce_5(y, p256_mod, p256_mp_mod);\n        if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {\n            sp_256_mont_sub_5(y, p256_mod, y, p256_mod);\n        }\n\n        err = sp_256_to_mp(y, ym);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n#endif\n#endif /* !WOLFSSL_SP_NO_256 */\n#endif /* WOLFSSL_HAVE_SP_ECC */\n#endif /* SP_WORD_SIZE == 64 */\n#endif /* !WOLFSSL_SP_ASM */\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */\n"
  },
  {
    "path": "src/wolfcrypt/src/sp_cortexm.c",
    "content": "/* sp.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/* Implementation by Sean Parkinson. */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/cpuid.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \\\n                                    defined(WOLFSSL_HAVE_SP_ECC)\n\n#ifdef RSA_LOW_MEM\n#ifndef WOLFSSL_SP_SMALL\n#define WOLFSSL_SP_SMALL\n#endif\n#endif\n\n#include <wolfssl/wolfcrypt/sp.h>\n\n#ifdef __IAR_SYSTEMS_ICC__\n#define __asm__        asm\n#define __volatile__   volatile\n#endif /* __IAR_SYSTEMS_ICC__ */\n#ifdef __KEIL__\n#define __asm__        __asm\n#define __volatile__   volatile\n#endif\n\n#ifdef WOLFSSL_SP_ARM_CORTEX_M_ASM\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n#ifndef WOLFSSL_SP_NO_2048\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 24U) {\n            r[j] &= 0xffffffff;\n            s = 32U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 32\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 32\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffff;\n        s = 32U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 32U) <= (word32)DIGIT_BIT) {\n            s += 32U;\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 32) {\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 32 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 256\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_2048_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 2048 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<64 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 32) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 32);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[8];\n\n    __asm__ __volatile__ (\n        /* A[0] * B[0] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [%[tmp], #0]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[0] * B[1] */\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* A[1] * B[0] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[tmp], #4]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[0] * B[2] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[1] * B[1] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[2] * B[0] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [%[tmp], #8]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[0] * B[3] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[1] * B[2] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[2] * B[1] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[3] * B[0] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr3, [%[tmp], #12]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[0] * B[4] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[1] * B[3] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[2] * B[2] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[3] * B[1] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[4] * B[0] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[tmp], #16]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[0] * B[5] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[1] * B[4] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[2] * B[3] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[3] * B[2] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[4] * B[1] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[5] * B[0] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [%[tmp], #20]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[0] * B[6] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[1] * B[5] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[2] * B[4] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[3] * B[3] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[4] * B[2] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[5] * B[1] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[6] * B[0] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr3, [%[tmp], #24]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[0] * B[7] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[1] * B[6] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[2] * B[5] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[3] * B[4] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[4] * B[3] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[5] * B[2] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[6] * B[1] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[7] * B[0] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[tmp], #28]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[1] * B[7] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[2] * B[6] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[3] * B[5] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[4] * B[4] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[5] * B[3] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[6] * B[2] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[7] * B[1] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [%[r], #32]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[2] * B[7] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[3] * B[6] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[4] * B[5] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[5] * B[4] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[6] * B[3] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[7] * B[2] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[3] * B[7] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[4] * B[6] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[5] * B[5] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[6] * B[4] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[7] * B[3] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[4] * B[7] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[5] * B[6] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[6] * B[5] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[7] * B[4] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [%[r], #44]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[5] * B[7] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[6] * B[6] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[7] * B[5] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[6] * B[7] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[7] * B[6] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[7] * B[7] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr5, [%[r], #56]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        /* Transfer tmp to r */\n        \"ldr\tr3, [%[tmp], #0]\\n\\t\"\n        \"ldr\tr4, [%[tmp], #4]\\n\\t\"\n        \"ldr\tr5, [%[tmp], #8]\\n\\t\"\n        \"ldr\tr6, [%[tmp], #12]\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [%[tmp], #16]\\n\\t\"\n        \"ldr\tr4, [%[tmp], #20]\\n\\t\"\n        \"ldr\tr5, [%[tmp], #24]\\n\\t\"\n        \"ldr\tr6, [%[tmp], #28]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"str\tr5, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [tmp] \"r\" (tmp)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a)\n{\n    sp_digit tmp[8];\n    __asm__ __volatile__ (\n        /* A[0] * A[0] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"umull\tr3, r4, r6, r6\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [%[tmp], #0]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[0] * A[1] */\n        \"ldr\tr7, [%[a], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[tmp], #4]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[0] * A[2] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[1] * A[1] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [%[tmp], #8]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[0] * A[3] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[1] * A[2] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[tmp], #12]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[0] * A[4] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[1] * A[3] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[2] * A[2] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[tmp], #16]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[0] * A[5] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[1] * A[4] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[2] * A[3] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[tmp], #20]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[0] * A[6] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[1] * A[5] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[2] * A[4] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[3] * A[3] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[tmp], #24]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[0] * A[7] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[1] * A[6] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[2] * A[5] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[3] * A[4] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[tmp], #28]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[1] * A[7] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[2] * A[6] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[3] * A[5] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[4] * A[4] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #32]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[2] * A[7] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[3] * A[6] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[4] * A[5] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[3] * A[7] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[4] * A[6] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[5] * A[5] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[4] * A[7] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[5] * A[6] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [%[r], #44]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[5] * A[7] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[6] * A[6] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[6] * A[7] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[7] * A[7] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr5, [%[r], #56]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        /* Transfer tmp to r */\n        \"ldr\tr3, [%[tmp], #0]\\n\\t\"\n        \"ldr\tr4, [%[tmp], #4]\\n\\t\"\n        \"ldr\tr5, [%[tmp], #8]\\n\\t\"\n        \"ldr\tr6, [%[tmp], #12]\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [%[tmp], #16]\\n\\t\"\n        \"ldr\tr4, [%[tmp], #20]\\n\\t\"\n        \"ldr\tr5, [%[tmp], #24]\\n\\t\"\n        \"ldr\tr6, [%[tmp], #28]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"str\tr5, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [tmp] \"r\" (tmp)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_add_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_sub_in_place_16(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"subs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_add_16(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_8(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<8; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    r[0] = a[0] & m;\n    r[1] = a[1] & m;\n    r[2] = a[2] & m;\n    r[3] = a[3] & m;\n    r[4] = a[4] & m;\n    r[5] = a[5] & m;\n    r[6] = a[6] & m;\n    r[7] = a[7] & m;\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_16(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[16];\n    sp_digit a1[8];\n    sp_digit b1[8];\n    sp_digit z2[16];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_8(a1, a, &a[8]);\n    cb = sp_2048_add_8(b1, b, &b[8]);\n    u  = ca & cb;\n    sp_2048_mul_8(z1, a1, b1);\n    sp_2048_mul_8(z2, &a[8], &b[8]);\n    sp_2048_mul_8(z0, a, b);\n    sp_2048_mask_8(r + 16, a1, 0 - cb);\n    sp_2048_mask_8(b1, b1, 0 - ca);\n    u += sp_2048_add_8(r + 16, r + 16, b1);\n    u += sp_2048_sub_in_place_16(z1, z2);\n    u += sp_2048_sub_in_place_16(z1, z0);\n    u += sp_2048_add_16(r + 8, r + 8, z1);\n    r[24] = u;\n    XMEMSET(r + 24 + 1, 0, sizeof(sp_digit) * (8 - 1));\n    (void)sp_2048_add_16(r + 16, r + 16, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_16(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[16];\n    sp_digit z1[16];\n    sp_digit a1[8];\n    sp_digit u;\n\n    u = sp_2048_add_8(a1, a, &a[8]);\n    sp_2048_sqr_8(z1, a1);\n    sp_2048_sqr_8(z2, &a[8]);\n    sp_2048_sqr_8(z0, a);\n    sp_2048_mask_8(r + 16, a1, 0 - u);\n    u += sp_2048_add_8(r + 16, r + 16, r + 16);\n    u += sp_2048_sub_in_place_16(z1, z2);\n    u += sp_2048_sub_in_place_16(z1, z0);\n    u += sp_2048_add_16(r + 8, r + 8, z1);\n    r[24] = u;\n    XMEMSET(r + 24 + 1, 0, sizeof(sp_digit) * (8 - 1));\n    (void)sp_2048_add_16(r + 16, r + 16, z2);\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_sub_in_place_32(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"subs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_16(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<16; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 16; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[32];\n    sp_digit a1[16];\n    sp_digit b1[16];\n    sp_digit z2[32];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_16(a1, a, &a[16]);\n    cb = sp_2048_add_16(b1, b, &b[16]);\n    u  = ca & cb;\n    sp_2048_mul_16(z1, a1, b1);\n    sp_2048_mul_16(z2, &a[16], &b[16]);\n    sp_2048_mul_16(z0, a, b);\n    sp_2048_mask_16(r + 32, a1, 0 - cb);\n    sp_2048_mask_16(b1, b1, 0 - ca);\n    u += sp_2048_add_16(r + 32, r + 32, b1);\n    u += sp_2048_sub_in_place_32(z1, z2);\n    u += sp_2048_sub_in_place_32(z1, z0);\n    u += sp_2048_add_32(r + 16, r + 16, z1);\n    r[48] = u;\n    XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));\n    (void)sp_2048_add_32(r + 32, r + 32, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[32];\n    sp_digit z1[32];\n    sp_digit a1[16];\n    sp_digit u;\n\n    u = sp_2048_add_16(a1, a, &a[16]);\n    sp_2048_sqr_16(z1, a1);\n    sp_2048_sqr_16(z2, &a[16]);\n    sp_2048_sqr_16(z0, a);\n    sp_2048_mask_16(r + 32, a1, 0 - u);\n    u += sp_2048_add_16(r + 32, r + 32, r + 32);\n    u += sp_2048_sub_in_place_32(z1, z2);\n    u += sp_2048_sub_in_place_32(z1, z0);\n    u += sp_2048_add_32(r + 16, r + 16, z1);\n    r[48] = u;\n    XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));\n    (void)sp_2048_add_32(r + 32, r + 32, z2);\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_sub_in_place_64(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"subs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_32(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<32; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[64];\n    sp_digit a1[32];\n    sp_digit b1[32];\n    sp_digit z2[64];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_32(a1, a, &a[32]);\n    cb = sp_2048_add_32(b1, b, &b[32]);\n    u  = ca & cb;\n    sp_2048_mul_32(z1, a1, b1);\n    sp_2048_mul_32(z2, &a[32], &b[32]);\n    sp_2048_mul_32(z0, a, b);\n    sp_2048_mask_32(r + 64, a1, 0 - cb);\n    sp_2048_mask_32(b1, b1, 0 - ca);\n    u += sp_2048_add_32(r + 64, r + 64, b1);\n    u += sp_2048_sub_in_place_64(z1, z2);\n    u += sp_2048_sub_in_place_64(z1, z0);\n    u += sp_2048_add_64(r + 32, r + 32, z1);\n    r[96] = u;\n    XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));\n    (void)sp_2048_add_64(r + 64, r + 64, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_64(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[64];\n    sp_digit z1[64];\n    sp_digit a1[32];\n    sp_digit u;\n\n    u = sp_2048_add_32(a1, a, &a[32]);\n    sp_2048_sqr_32(z1, a1);\n    sp_2048_sqr_32(z2, &a[32]);\n    sp_2048_sqr_32(z0, a);\n    sp_2048_mask_32(r + 64, a1, 0 - u);\n    u += sp_2048_add_32(r + 64, r + 64, r + 64);\n    u += sp_2048_sub_in_place_64(z1, z2);\n    u += sp_2048_sub_in_place_64(z1, z0);\n    u += sp_2048_add_64(r + 32, r + 32, z1);\n    r[96] = u;\n    XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));\n    (void)sp_2048_add_64(r + 64, r + 64, z2);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\tr6, r6, #256\\n\\t\"\n        \"sub\tr7, r7, #1\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"adcs\tr4, r4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"add\t%[b], %[b], #4\\n\\t\"\n        \"add\t%[r], %[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_sub_in_place_64(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n    __asm__ __volatile__ (\n        \"mov\tr7, %[a]\\n\\t\"\n        \"add\tr7, r7, #256\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"subs\tr5, r5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"str\tr3, [%[a]]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        \"add\t%[a], %[a], #8\\n\\t\"\n        \"add\t%[b], %[b], #8\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[64 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #252\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[b], %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\t%[b], %[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        /* Multiply Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply Done */\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\t%[b], %[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_64(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #252\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, r2, %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\tr2, r2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        /* Multiply * 2: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply * 2: Done */\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        /* Square: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Square: Done */\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\tr2, r2, #4\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #1\\n\\t\"\n        \"lsl\tr3, r3, #8\\n\\t\"\n        \"add\tr3, r3, #252\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"subs\tr3, r3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_32(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n    int i;\n\n    for (i=0; i<32; i++) {\n        r[i] = a[i] & m;\n    }\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\tr6, r6, #128\\n\\t\"\n        \"sub\tr7, r7, #1\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"adcs\tr4, r4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"add\t%[b], %[b], #4\\n\\t\"\n        \"add\t%[r], %[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_2048_sub_in_place_32(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n    __asm__ __volatile__ (\n        \"mov\tr7, %[a]\\n\\t\"\n        \"add\tr7, r7, #128\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"subs\tr5, r5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"str\tr3, [%[a]]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        \"add\t%[a], %[a], #8\\n\\t\"\n        \"add\t%[b], %[b], #8\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[32 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #128\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #124\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[b], %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\t%[b], %[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        /* Multiply Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply Done */\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\t%[b], %[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #124\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, r2, %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\tr2, r2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        /* Multiply * 2: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply * 2: Done */\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        /* Square: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Square: Done */\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\tr2, r2, #4\\n\\t\"\n        \"mov\tr6, #128\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #252\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"subs\tr3, r3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nSP_NOINLINE static void sp_2048_mul_d_64(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n    __asm__ __volatile__ (\n        \"add\tr8, %[a], #256\\n\\t\"\n        /* A[0] * B */\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"umull\tr5, r3, r6, %[b]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr5, [%[r]], #4\\n\\t\"\n        /* A[0] * B - Done */\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[] * B */\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"umull\tr6, r7, r6, %[b]\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[] * B - Done */\n        \"str\tr3, [%[r]], #4\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"cmp\t%[a], r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        : [r] \"+r\" (r), [a] \"+r\" (a)\n        : [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_32(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 32);\n\n    /* r = 2^n mod m */\n    sp_2048_sub_in_place_32(r, m);\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nSP_NOINLINE static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, sp_digit m)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr5, #128\\n\\t\"\n        \"mov\tr8, r5\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"ldr\tr6, [%[b], r7]\\n\\t\"\n        \"and\tr6, r6, %[m]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"subs\tr5, r5, %[c]\\n\\t\"\n        \"ldr\tr5, [%[a], r7]\\n\\t\"\n        \"sbcs\tr5, r5, r6\\n\\t\"\n        \"sbcs\t%[c], %[c], %[c]\\n\\t\"\n        \"str\tr5, [%[r], r7]\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"cmp\tr7, r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n    return c;\n}\n\n/* Reduce the number back to 2048 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr8, %[mp]\\n\\t\"\n        \"mov\tr12, %[m]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"add\tr11, r9, #128\\n\\t\"\n        \"\\n1:\\n\\t\"\n        /* mu = a[i] * mp */\n        \"mov\t%[mp], r8\\n\\t\"\n        \"ldr\t%[a], [r9]\\n\\t\"\n        \"mul\t%[mp], %[mp], %[a]\\n\\t\"\n        \"mov\t%[m], r12\\n\\t\"\n        \"mov\tr10, r9\\n\\t\"\n        \"add\tr14, r9, #120\\n\\t\"\n        \"\\n2:\\n\\t\"\n        /* a[i+j] += m[j] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr4, r4, %[a]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr4, [r10], #4\\n\\t\"\n        /* a[i+j+1] += m[j+1] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr5, r5, %[a]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [r10], #4\\n\\t\"\n        \"cmp\tr10, r14\\n\\t\"\n        \"blt\t2b\\n\\t\"\n        /* a[i+30] += m[30] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr4, r4, %[a]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr4, [r10], #4\\n\\t\"\n        /* a[i+31] += m[31] * mu */\n        \"mov\tr4, %[ca]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        /* Multiply m[31] and mu - Start */\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        /* Multiply m[31] and mu - Done */\n        \"ldr\tr6, [r10]\\n\\t\"\n        \"ldr\tr7, [r10, #4]\\n\\t\"\n        \"adds\tr6, r6, r5\\n\\t\"\n        \"adcs\tr7, r7, r4\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        \"str\tr6, [r10]\\n\\t\"\n        \"str\tr7, [r10, #4]\\n\\t\"\n        /* Next word in a */\n        \"add\tr9, r9, #4\\n\\t\"\n        \"cmp\tr9, r11\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[m], r12\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n\n    sp_2048_cond_sub_32(a - 32, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_32(r, a, b);\n    sp_2048_mont_reduce_32(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_32(r, a);\n    sp_2048_mont_reduce_32(r, m, mp);\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nSP_NOINLINE static void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n    __asm__ __volatile__ (\n        \"add\tr8, %[a], #128\\n\\t\"\n        /* A[0] * B */\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"umull\tr5, r3, r6, %[b]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr5, [%[r]], #4\\n\\t\"\n        /* A[0] * B - Done */\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[] * B */\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"umull\tr6, r7, r6, %[b]\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[] * B - Done */\n        \"str\tr3, [%[r]], #4\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"cmp\t%[a], r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        : [r] \"+r\" (r), [a] \"+r\" (a)\n        : [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nSP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"add\tr6, r6, #1\\n\\t\"\n        \"udiv\tr4, %[d1], r6\\n\\t\"\n        \"lsl\tr7, r4, #16\\n\\t\"\n        \"umull\tr4, r5, %[div], r7\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"udiv\tr5, %[d1], r6\\n\\t\"\n        \"lsl\tr4, r5, #16\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"lsl\tr4, %[d1], #16\\n\\t\"\n        \"orr\tr4, r4, %[d0], lsr #16\\n\\t\"\n        \"udiv\tr4, r4, r6\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"lsl\tr4, %[d1], #16\\n\\t\"\n        \"orr\tr4, r4, %[d0], lsr #16\\n\\t\"\n        \"udiv\tr4, r4, r6\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"udiv\tr4, %[d0], %[div]\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"mov\t%[r], r7\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n    return r;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nSP_NOINLINE static int32_t sp_2048_cmp_32(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr6, #124\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"ldr\tr7, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr7, r7, r3\\n\\t\"\n        \"and\tr5, r5, r3\\n\\t\"\n        \"mov\tr4, r7\\n\\t\"\n        \"subs\tr7, r7, r5\\n\\t\"\n        \"sbc\tr7, r7, r7\\n\\t\"\n        \"add\t%[r], %[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r3, r7\\n\\t\"\n        \"subs\tr5, r5, r4\\n\\t\"\n        \"sbc\tr7, r7, r7\\n\\t\"\n        \"sub\t%[r], %[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r3, r7\\n\\t\"\n        \"sub\tr6, r6, #4\\n\\t\"\n        \"cmp\tr6, #0\\n\\t\"\n        \"bge\t1b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_32(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[64], t2[33];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[31];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 32);\n    for (i=31; i>=0; i--) {\n        r1 = div_2048_word_32(t1[32 + i], t1[32 + i - 1], div);\n\n        sp_2048_mul_d_32(t2, d, r1);\n        t1[32 + i] += sp_2048_sub_in_place_32(&t1[i], t2);\n        t1[32 + i] -= t2[32];\n        sp_2048_mask_32(t2, d, t1[32 + i]);\n        t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], t2);\n        sp_2048_mask_32(t2, d, t1[32 + i]);\n        t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_2048_cmp_32(t1, d) >= 0;\n    sp_2048_cond_sub_32(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_32(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_32(a, m, NULL, r);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][64];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 64, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 64;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_32(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 32U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_32(t[1] + 32, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_32(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 32, a, sizeof(sp_digit) * 32);\n            err = sp_2048_mod_32(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_32(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_32(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_32(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_32(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_32(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_32(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_32(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_32(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_32(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_32(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_32(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_32(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_32(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_32(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 32);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n\n            sp_2048_mont_mul_32(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[32], 0, sizeof(sp_digit) * 32U);\n        sp_2048_mont_reduce_32(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_32(r, m) >= 0);\n        sp_2048_cond_sub_32(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][64];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 64, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 64;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_32(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 32U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_32(t[1] + 32, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_32(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 32, a, sizeof(sp_digit) * 32);\n            err = sp_2048_mod_32(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_32(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_32(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_32(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_32(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_32(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_32(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_32(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_32(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_32(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_32(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_32(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_32(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_32(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_32(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_32(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_32(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_32(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_32(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_32(t[20], t[10], m, mp);\n        sp_2048_mont_mul_32(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_32(t[22], t[11], m, mp);\n        sp_2048_mont_mul_32(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_32(t[24], t[12], m, mp);\n        sp_2048_mont_mul_32(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_32(t[26], t[13], m, mp);\n        sp_2048_mont_mul_32(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_32(t[28], t[14], m, mp);\n        sp_2048_mont_mul_32(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_32(t[30], t[15], m, mp);\n        sp_2048_mont_mul_32(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 32);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n\n            sp_2048_mont_mul_32(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[32], 0, sizeof(sp_digit) * 32U);\n        sp_2048_mont_reduce_32(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_32(r, m) >= 0);\n        sp_2048_cond_sub_32(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_64(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 64);\n\n    /* r = 2^n mod m */\n    sp_2048_sub_in_place_64(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nSP_NOINLINE static sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, sp_digit m)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr5, #1\\n\\t\"\n        \"lsl\tr5, r5, #8\\n\\t\"\n        \"mov\tr8, r5\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"ldr\tr6, [%[b], r7]\\n\\t\"\n        \"and\tr6, r6, %[m]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"subs\tr5, r5, %[c]\\n\\t\"\n        \"ldr\tr5, [%[a], r7]\\n\\t\"\n        \"sbcs\tr5, r5, r6\\n\\t\"\n        \"sbcs\t%[c], %[c], %[c]\\n\\t\"\n        \"str\tr5, [%[r], r7]\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"cmp\tr7, r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n    return c;\n}\n\n/* Reduce the number back to 2048 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr8, %[mp]\\n\\t\"\n        \"mov\tr12, %[m]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"add\tr11, r9, #256\\n\\t\"\n        \"\\n1:\\n\\t\"\n        /* mu = a[i] * mp */\n        \"mov\t%[mp], r8\\n\\t\"\n        \"ldr\t%[a], [r9]\\n\\t\"\n        \"mul\t%[mp], %[mp], %[a]\\n\\t\"\n        \"mov\t%[m], r12\\n\\t\"\n        \"mov\tr10, r9\\n\\t\"\n        \"add\tr14, r9, #248\\n\\t\"\n        \"\\n2:\\n\\t\"\n        /* a[i+j] += m[j] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr4, r4, %[a]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr4, [r10], #4\\n\\t\"\n        /* a[i+j+1] += m[j+1] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr5, r5, %[a]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [r10], #4\\n\\t\"\n        \"cmp\tr10, r14\\n\\t\"\n        \"blt\t2b\\n\\t\"\n        /* a[i+62] += m[62] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr4, r4, %[a]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr4, [r10], #4\\n\\t\"\n        /* a[i+63] += m[63] * mu */\n        \"mov\tr4, %[ca]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        /* Multiply m[63] and mu - Start */\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        /* Multiply m[63] and mu - Done */\n        \"ldr\tr6, [r10]\\n\\t\"\n        \"ldr\tr7, [r10, #4]\\n\\t\"\n        \"adds\tr6, r6, r5\\n\\t\"\n        \"adcs\tr7, r7, r4\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        \"str\tr6, [r10]\\n\\t\"\n        \"str\tr7, [r10, #4]\\n\\t\"\n        /* Next word in a */\n        \"add\tr9, r9, #4\\n\\t\"\n        \"cmp\tr9, r11\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[m], r12\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n\n    sp_2048_cond_sub_64(a - 64, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_64(r, a, b);\n    sp_2048_mont_reduce_64(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_64(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_64(r, a);\n    sp_2048_mont_reduce_64(r, m, mp);\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nSP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"add\tr6, r6, #1\\n\\t\"\n        \"udiv\tr4, %[d1], r6\\n\\t\"\n        \"lsl\tr7, r4, #16\\n\\t\"\n        \"umull\tr4, r5, %[div], r7\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"udiv\tr5, %[d1], r6\\n\\t\"\n        \"lsl\tr4, r5, #16\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"lsl\tr4, %[d1], #16\\n\\t\"\n        \"orr\tr4, r4, %[d0], lsr #16\\n\\t\"\n        \"udiv\tr4, r4, r6\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"lsl\tr4, %[d1], #16\\n\\t\"\n        \"orr\tr4, r4, %[d0], lsr #16\\n\\t\"\n        \"udiv\tr4, r4, r6\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"udiv\tr4, %[d0], %[div]\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"mov\t%[r], r7\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_64(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<64; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nSP_NOINLINE static int32_t sp_2048_cmp_64(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr6, #252\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"ldr\tr7, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr7, r7, r3\\n\\t\"\n        \"and\tr5, r5, r3\\n\\t\"\n        \"mov\tr4, r7\\n\\t\"\n        \"subs\tr7, r7, r5\\n\\t\"\n        \"sbc\tr7, r7, r7\\n\\t\"\n        \"add\t%[r], %[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r3, r7\\n\\t\"\n        \"subs\tr5, r5, r4\\n\\t\"\n        \"sbc\tr7, r7, r7\\n\\t\"\n        \"sub\t%[r], %[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r3, r7\\n\\t\"\n        \"sub\tr6, r6, #4\\n\\t\"\n        \"cmp\tr6, #0\\n\\t\"\n        \"bge\t1b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_64(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[128], t2[65];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[63];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 64);\n    for (i=63; i>=0; i--) {\n        r1 = div_2048_word_64(t1[64 + i], t1[64 + i - 1], div);\n\n        sp_2048_mul_d_64(t2, d, r1);\n        t1[64 + i] += sp_2048_sub_in_place_64(&t1[i], t2);\n        t1[64 + i] -= t2[64];\n        sp_2048_mask_64(t2, d, t1[64 + i]);\n        t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], t2);\n        sp_2048_mask_64(t2, d, t1[64 + i]);\n        t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_2048_cmp_64(t1, d) >= 0;\n    sp_2048_cond_sub_64(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_64(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_64(a, m, NULL, r);\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_64_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[128], t2[65];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[63];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 64);\n    for (i=63; i>=0; i--) {\n        r1 = div_2048_word_64(t1[64 + i], t1[64 + i - 1], div);\n\n        sp_2048_mul_d_64(t2, d, r1);\n        t1[64 + i] += sp_2048_sub_in_place_64(&t1[i], t2);\n        t1[64 + i] -= t2[64];\n        if (t1[64 + i] != 0) {\n            t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], d);\n            if (t1[64 + i] != 0)\n                t1[64 + i] += sp_2048_add_64(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_2048_cmp_64(t1, d) >= 0;\n    sp_2048_cond_sub_64(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_64_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_64_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][128];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 128, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 128;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_64(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 64U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_64(t[1] + 64, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_64(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 64, a, sizeof(sp_digit) * 64);\n            err = sp_2048_mod_64(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_64(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_64(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_64(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_64(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_64(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_64(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_64(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_64(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_64(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_64(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_64(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_64(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_64(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_64(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 64);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n\n            sp_2048_mont_mul_64(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);\n        sp_2048_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_64(r, m) >= 0);\n        sp_2048_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][128];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 128, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 128;\n        }\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_64(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 64U);\n        if (reduceA != 0) {\n            err = sp_2048_mod_64(t[1] + 64, a, m);\n            if (err == MP_OKAY) {\n                err = sp_2048_mod_64(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 64, a, sizeof(sp_digit) * 64);\n            err = sp_2048_mod_64(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_64(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_64(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_64(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_64(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_64(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_64(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_64(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_64(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_64(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_64(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_64(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_64(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_64(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_64(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_64(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_64(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_64(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_64(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_64(t[20], t[10], m, mp);\n        sp_2048_mont_mul_64(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_64(t[22], t[11], m, mp);\n        sp_2048_mont_mul_64(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_64(t[24], t[12], m, mp);\n        sp_2048_mont_mul_64(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_64(t[26], t[13], m, mp);\n        sp_2048_mont_mul_64(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_64(t[28], t[14], m, mp);\n        sp_2048_mont_mul_64(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_64(t[30], t[15], m, mp);\n        sp_2048_mont_mul_64(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 64);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n\n            sp_2048_mont_mul_64(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);\n        sp_2048_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_64(r, m) >= 0);\n        sp_2048_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[128], md[64], rd[128];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1];\n    int err = MP_OKAY;\n\n    if (*outLen < 256)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 32 || inLen > 256 ||\n                                                     mp_count_bits(mm) != 2048))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 64 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 64 * 2;\n        m = r + 64 * 2;\n        ah = a + 64;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 64;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(ah, 64, in, inLen);\n#if DIGIT_BIT >= 32\n        e[0] = em->dp[0];\n#else\n        e[0] = em->dp[0];\n        if (em->used > 1)\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e[0] == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(m, 64, mm);\n\n        if (e[0] == 0x3) {\n            if (err == MP_OKAY) {\n                sp_2048_sqr_64(r, ah);\n                err = sp_2048_mod_64_cond(r, r, m);\n            }\n            if (err == MP_OKAY) {\n                sp_2048_mul_64(r, ah, r);\n                err = sp_2048_mod_64_cond(r, r, m);\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_2048_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 64);\n            err = sp_2048_mod_64_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=31; i>=0; i--)\n                    if (e[0] >> i)\n                        break;\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 64);\n                for (i--; i>=0; i--) {\n                    sp_2048_mont_sqr_64(r, r, m, mp);\n                    if (((e[0] >> i) & 1) == 1)\n                        sp_2048_mont_mul_64(r, r, a, m, mp);\n                }\n                XMEMSET(&r[64], 0, sizeof(sp_digit) * 64);\n                sp_2048_mont_reduce_64(r, m, mp);\n\n                for (i = 63; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_2048_sub_in_place_64(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[64 * 2];\n    sp_digit pd[32], qd[32], dpd[32];\n    sp_digit tmpad[64], tmpbd[64];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 256)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 256 || mp_count_bits(mm) != 2048))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 64 * 2;\n        q = p + 32;\n        qi = dq = dp = q + 32;\n        tmpa = qi + 32;\n        tmpb = tmpa + 64;\n\n        tmp = t;\n        r = tmp + 64;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 64;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(a, 64, in, inLen);\n        sp_2048_from_mp(p, 32, pm);\n        sp_2048_from_mp(q, 32, qm);\n        sp_2048_from_mp(dp, 32, dpm);\n\n        err = sp_2048_mod_exp_32(tmpa, a, dp, 1024, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(dq, 32, dqm);\n        err = sp_2048_mod_exp_32(tmpb, a, dq, 1024, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_2048_sub_in_place_32(tmpa, tmpb);\n        sp_2048_mask_32(tmp, p, c);\n        sp_2048_add_32(tmpa, tmpa, tmp);\n\n        sp_2048_from_mp(qi, 32, qim);\n        sp_2048_mul_32(tmpa, tmpa, qi);\n        err = sp_2048_mod_32(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mul_32(tmpa, q, tmpa);\n        XMEMSET(&tmpb[32], 0, sizeof(sp_digit) * 32);\n        sp_2048_add_64(r, tmpb, tmpa);\n\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 32 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_2048_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 32\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 64);\n        r->used = 64;\n        mp_clamp(r);\n#elif DIGIT_BIT < 32\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 64; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 32) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 32 - s;\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 64; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 32 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 32 - s;\n            }\n            else {\n                s += 32;\n            }\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[128], e[64], m[64];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 64, base);\n        sp_2048_from_mp(e, 64, exp);\n        sp_2048_from_mp(m, 64, mod);\n\n        err = sp_2048_mod_exp_64(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_2048_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_2048\nstatic void sp_2048_lshift_64(sp_digit* r, sp_digit* a, byte n)\n{\n    __asm__ __volatile__ (\n        \"mov r6, #31\\n\\t\"\n        \"sub r6, r6, %[n]\\n\\t\"\n        \"add       %[a], %[a], #192\\n\\t\"\n        \"add       %[r], %[r], #192\\n\\t\"\n        \"ldr r3, [%[a], #60]\\n\\t\"\n        \"lsr r4, r3, #1\\n\\t\"\n        \"lsl r3, r3, %[n]\\n\\t\"\n        \"lsr r4, r4, r6\\n\\t\"\n        \"ldr       r2, [%[a], #56]\\n\\t\"\n        \"str       r4, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #52]\\n\\t\"\n        \"str       r3, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #48]\\n\\t\"\n        \"str       r2, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #44]\\n\\t\"\n        \"str       r4, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #40]\\n\\t\"\n        \"str       r3, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #36]\\n\\t\"\n        \"str       r2, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #32]\\n\\t\"\n        \"str       r4, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #28]\\n\\t\"\n        \"str       r3, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #24]\\n\\t\"\n        \"str       r2, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #20]\\n\\t\"\n        \"str       r4, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #16]\\n\\t\"\n        \"str       r3, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #12]\\n\\t\"\n        \"str       r2, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #8]\\n\\t\"\n        \"str       r4, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #4]\\n\\t\"\n        \"str       r3, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #0]\\n\\t\"\n        \"str       r2, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r2, [%[a], #60]\\n\\t\"\n        \"str       r4, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #56]\\n\\t\"\n        \"str       r3, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #52]\\n\\t\"\n        \"str       r2, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #48]\\n\\t\"\n        \"str       r4, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #44]\\n\\t\"\n        \"str       r3, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #40]\\n\\t\"\n        \"str       r2, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #36]\\n\\t\"\n        \"str       r4, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #32]\\n\\t\"\n        \"str       r3, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #28]\\n\\t\"\n        \"str       r2, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #24]\\n\\t\"\n        \"str       r4, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #20]\\n\\t\"\n        \"str       r3, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #16]\\n\\t\"\n        \"str       r2, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #12]\\n\\t\"\n        \"str       r4, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #8]\\n\\t\"\n        \"str       r3, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #4]\\n\\t\"\n        \"str       r2, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #0]\\n\\t\"\n        \"str       r4, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r4, [%[a], #60]\\n\\t\"\n        \"str       r3, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #56]\\n\\t\"\n        \"str       r2, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #52]\\n\\t\"\n        \"str       r4, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #48]\\n\\t\"\n        \"str       r3, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #44]\\n\\t\"\n        \"str       r2, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #40]\\n\\t\"\n        \"str       r4, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #36]\\n\\t\"\n        \"str       r3, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #32]\\n\\t\"\n        \"str       r2, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #28]\\n\\t\"\n        \"str       r4, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #24]\\n\\t\"\n        \"str       r3, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #20]\\n\\t\"\n        \"str       r2, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #16]\\n\\t\"\n        \"str       r4, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #12]\\n\\t\"\n        \"str       r3, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #8]\\n\\t\"\n        \"str       r2, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #4]\\n\\t\"\n        \"str       r4, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #0]\\n\\t\"\n        \"str       r3, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r3, [%[a], #60]\\n\\t\"\n        \"str       r2, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #56]\\n\\t\"\n        \"str       r4, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #52]\\n\\t\"\n        \"str       r3, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #48]\\n\\t\"\n        \"str       r2, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #44]\\n\\t\"\n        \"str       r4, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #40]\\n\\t\"\n        \"str       r3, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #36]\\n\\t\"\n        \"str       r2, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #32]\\n\\t\"\n        \"str       r4, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #28]\\n\\t\"\n        \"str       r3, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #24]\\n\\t\"\n        \"str       r2, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #20]\\n\\t\"\n        \"str       r4, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #16]\\n\\t\"\n        \"str       r3, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #12]\\n\\t\"\n        \"str       r2, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #8]\\n\\t\"\n        \"str       r4, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #4]\\n\\t\"\n        \"str       r3, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #0]\\n\\t\"\n        \"str       r2, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"str r3, [%[r]]\\n\\t\"\n        \"str r4, [%[r], #4]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [n] \"r\" (n)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[128];\n    sp_digit td[65];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 193, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 128;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_64(norm, m);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        sp_2048_lshift_64(r, norm, y);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n            sp_2048_mont_sqr_64(r, r, m, mp);\n\n            sp_2048_lshift_64(r, r, y);\n            sp_2048_mul_d_64(tmp, norm, r[64]);\n            r[64] = 0;\n            o = sp_2048_add_64(r, r, tmp);\n            sp_2048_cond_sub_64(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64U);\n        sp_2048_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_64(r, m) >= 0);\n        sp_2048_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* HAVE_FFDHE_2048 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 256 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[128], e[64], m[64];\n    sp_digit* r = b;\n    word32 i;\n\n    if (mp_count_bits(base) > 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 256) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 2048) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 64, base);\n        sp_2048_from_bin(e, 64, exp, expLen);\n        sp_2048_from_mp(m, 64, mod);\n\n    #ifdef HAVE_FFDHE_2048\n        if (base->used == 1 && base->dp[0] == 2 && m[63] == (sp_digit)-1)\n            err = sp_2048_mod_exp_2_64(r, e, expLen * 8, m);\n        else\n    #endif\n            err = sp_2048_mod_exp_64(r, b, e, expLen * 8, m, 0);\n\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n        for (i=0; i<256 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[64], e[32], m[32];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1024) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1024) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 32, base);\n        sp_2048_from_mp(e, 32, exp);\n        sp_2048_from_mp(m, 32, mod);\n\n        err = sp_2048_mod_exp_32(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 32, 0, sizeof(*r) * 32U);\n        err = sp_2048_to_mp(r, res);\n        res->used = mod->used;\n        mp_clamp(res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_2048 */\n\n#ifndef WOLFSSL_SP_NO_3072\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 24U) {\n            r[j] &= 0xffffffff;\n            s = 32U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 32\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 32\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffff;\n        s = 32U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 32U) <= (word32)DIGIT_BIT) {\n            s += 32U;\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 32) {\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 32 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 384\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_3072_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 3072 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<96 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 32) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 32);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_12(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[12 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #48\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #44\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[b], %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\t%[b], %[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        /* Multiply Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply Done */\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\t%[b], %[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #88\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #96\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #44\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, r2, %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\tr2, r2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        /* Multiply * 2: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply * 2: Done */\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        /* Square: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Square: Done */\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\tr2, r2, #4\\n\\t\"\n        \"mov\tr6, #48\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #88\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #92\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"subs\tr3, r3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #96\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_add_12(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_sub_in_place_24(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"subs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_add_24(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_12(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<12; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    r[0] = a[0] & m;\n    r[1] = a[1] & m;\n    r[2] = a[2] & m;\n    r[3] = a[3] & m;\n    r[4] = a[4] & m;\n    r[5] = a[5] & m;\n    r[6] = a[6] & m;\n    r[7] = a[7] & m;\n    r[8] = a[8] & m;\n    r[9] = a[9] & m;\n    r[10] = a[10] & m;\n    r[11] = a[11] & m;\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_24(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[24];\n    sp_digit a1[12];\n    sp_digit b1[12];\n    sp_digit z2[24];\n    sp_digit u, ca, cb;\n\n    ca = sp_3072_add_12(a1, a, &a[12]);\n    cb = sp_3072_add_12(b1, b, &b[12]);\n    u  = ca & cb;\n    sp_3072_mul_12(z1, a1, b1);\n    sp_3072_mul_12(z2, &a[12], &b[12]);\n    sp_3072_mul_12(z0, a, b);\n    sp_3072_mask_12(r + 24, a1, 0 - cb);\n    sp_3072_mask_12(b1, b1, 0 - ca);\n    u += sp_3072_add_12(r + 24, r + 24, b1);\n    u += sp_3072_sub_in_place_24(z1, z2);\n    u += sp_3072_sub_in_place_24(z1, z0);\n    u += sp_3072_add_24(r + 12, r + 12, z1);\n    r[36] = u;\n    XMEMSET(r + 36 + 1, 0, sizeof(sp_digit) * (12 - 1));\n    (void)sp_3072_add_24(r + 24, r + 24, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_24(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[24];\n    sp_digit z1[24];\n    sp_digit a1[12];\n    sp_digit u;\n\n    u = sp_3072_add_12(a1, a, &a[12]);\n    sp_3072_sqr_12(z1, a1);\n    sp_3072_sqr_12(z2, &a[12]);\n    sp_3072_sqr_12(z0, a);\n    sp_3072_mask_12(r + 24, a1, 0 - u);\n    u += sp_3072_add_12(r + 24, r + 24, r + 24);\n    u += sp_3072_sub_in_place_24(z1, z2);\n    u += sp_3072_sub_in_place_24(z1, z0);\n    u += sp_3072_add_24(r + 12, r + 12, z1);\n    r[36] = u;\n    XMEMSET(r + 36 + 1, 0, sizeof(sp_digit) * (12 - 1));\n    (void)sp_3072_add_24(r + 24, r + 24, z2);\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_sub_in_place_48(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"subs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_24(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<24; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[48];\n    sp_digit a1[24];\n    sp_digit b1[24];\n    sp_digit z2[48];\n    sp_digit u, ca, cb;\n\n    ca = sp_3072_add_24(a1, a, &a[24]);\n    cb = sp_3072_add_24(b1, b, &b[24]);\n    u  = ca & cb;\n    sp_3072_mul_24(z1, a1, b1);\n    sp_3072_mul_24(z2, &a[24], &b[24]);\n    sp_3072_mul_24(z0, a, b);\n    sp_3072_mask_24(r + 48, a1, 0 - cb);\n    sp_3072_mask_24(b1, b1, 0 - ca);\n    u += sp_3072_add_24(r + 48, r + 48, b1);\n    u += sp_3072_sub_in_place_48(z1, z2);\n    u += sp_3072_sub_in_place_48(z1, z0);\n    u += sp_3072_add_48(r + 24, r + 24, z1);\n    r[72] = u;\n    XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));\n    (void)sp_3072_add_48(r + 48, r + 48, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[48];\n    sp_digit z1[48];\n    sp_digit a1[24];\n    sp_digit u;\n\n    u = sp_3072_add_24(a1, a, &a[24]);\n    sp_3072_sqr_24(z1, a1);\n    sp_3072_sqr_24(z2, &a[24]);\n    sp_3072_sqr_24(z0, a);\n    sp_3072_mask_24(r + 48, a1, 0 - u);\n    u += sp_3072_add_24(r + 48, r + 48, r + 48);\n    u += sp_3072_sub_in_place_48(z1, z2);\n    u += sp_3072_sub_in_place_48(z1, z0);\n    u += sp_3072_add_48(r + 24, r + 24, z1);\n    r[72] = u;\n    XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));\n    (void)sp_3072_add_48(r + 48, r + 48, z2);\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_sub_in_place_96(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"subs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_48(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<48; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 48; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_96(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[96];\n    sp_digit a1[48];\n    sp_digit b1[48];\n    sp_digit z2[96];\n    sp_digit u, ca, cb;\n\n    ca = sp_3072_add_48(a1, a, &a[48]);\n    cb = sp_3072_add_48(b1, b, &b[48]);\n    u  = ca & cb;\n    sp_3072_mul_48(z1, a1, b1);\n    sp_3072_mul_48(z2, &a[48], &b[48]);\n    sp_3072_mul_48(z0, a, b);\n    sp_3072_mask_48(r + 96, a1, 0 - cb);\n    sp_3072_mask_48(b1, b1, 0 - ca);\n    u += sp_3072_add_48(r + 96, r + 96, b1);\n    u += sp_3072_sub_in_place_96(z1, z2);\n    u += sp_3072_sub_in_place_96(z1, z0);\n    u += sp_3072_add_96(r + 48, r + 48, z1);\n    r[144] = u;\n    XMEMSET(r + 144 + 1, 0, sizeof(sp_digit) * (48 - 1));\n    (void)sp_3072_add_96(r + 96, r + 96, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_96(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[96];\n    sp_digit z1[96];\n    sp_digit a1[48];\n    sp_digit u;\n\n    u = sp_3072_add_48(a1, a, &a[48]);\n    sp_3072_sqr_48(z1, a1);\n    sp_3072_sqr_48(z2, &a[48]);\n    sp_3072_sqr_48(z0, a);\n    sp_3072_mask_48(r + 96, a1, 0 - u);\n    u += sp_3072_add_48(r + 96, r + 96, r + 96);\n    u += sp_3072_sub_in_place_96(z1, z2);\n    u += sp_3072_sub_in_place_96(z1, z0);\n    u += sp_3072_add_96(r + 48, r + 48, z1);\n    r[144] = u;\n    XMEMSET(r + 144 + 1, 0, sizeof(sp_digit) * (48 - 1));\n    (void)sp_3072_add_96(r + 96, r + 96, z2);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\tr6, r6, #384\\n\\t\"\n        \"sub\tr7, r7, #1\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"adcs\tr4, r4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"add\t%[b], %[b], #4\\n\\t\"\n        \"add\t%[r], %[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_sub_in_place_96(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n    __asm__ __volatile__ (\n        \"mov\tr7, %[a]\\n\\t\"\n        \"add\tr7, r7, #384\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"subs\tr5, r5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"str\tr3, [%[a]]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        \"add\t%[a], %[a], #8\\n\\t\"\n        \"add\t%[b], %[b], #8\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_96(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[96 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #128\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #124\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[b], %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\t%[b], %[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        /* Multiply Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply Done */\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\t%[b], %[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_96(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #3\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #124\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, r2, %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\tr2, r2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        /* Multiply * 2: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply * 2: Done */\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        /* Square: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Square: Done */\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\tr2, r2, #4\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #128\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #2\\n\\t\"\n        \"lsl\tr3, r3, #8\\n\\t\"\n        \"add\tr3, r3, #252\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"subs\tr3, r3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #3\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#ifdef WOLFSSL_SP_SMALL\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_48(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n    int i;\n\n    for (i=0; i<48; i++) {\n        r[i] = a[i] & m;\n    }\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\tr6, r6, #192\\n\\t\"\n        \"sub\tr7, r7, #1\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"adcs\tr4, r4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"add\t%[b], %[b], #4\\n\\t\"\n        \"add\t%[r], %[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_3072_sub_in_place_48(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n    __asm__ __volatile__ (\n        \"mov\tr7, %[a]\\n\\t\"\n        \"add\tr7, r7, #192\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"subs\tr5, r5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"str\tr3, [%[a]]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        \"add\t%[a], %[a], #8\\n\\t\"\n        \"add\t%[b], %[b], #8\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[48 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #192\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #188\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[b], %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\t%[b], %[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        /* Multiply Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply Done */\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\t%[b], %[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #120\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #128\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #188\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, r2, %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\tr2, r2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        /* Multiply * 2: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply * 2: Done */\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        /* Square: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Square: Done */\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\tr2, r2, #4\\n\\t\"\n        \"mov\tr6, #192\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #120\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #1\\n\\t\"\n        \"lsl\tr3, r3, #8\\n\\t\"\n        \"add\tr3, r3, #124\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"subs\tr3, r3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #128\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nSP_NOINLINE static void sp_3072_mul_d_96(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n    __asm__ __volatile__ (\n        \"add\tr8, %[a], #384\\n\\t\"\n        /* A[0] * B */\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"umull\tr5, r3, r6, %[b]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr5, [%[r]], #4\\n\\t\"\n        /* A[0] * B - Done */\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[] * B */\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"umull\tr6, r7, r6, %[b]\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[] * B - Done */\n        \"str\tr3, [%[r]], #4\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"cmp\t%[a], r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        : [r] \"+r\" (r), [a] \"+r\" (a)\n        : [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_48(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 48);\n\n    /* r = 2^n mod m */\n    sp_3072_sub_in_place_48(r, m);\n}\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nSP_NOINLINE static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, sp_digit m)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr5, #192\\n\\t\"\n        \"mov\tr8, r5\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"ldr\tr6, [%[b], r7]\\n\\t\"\n        \"and\tr6, r6, %[m]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"subs\tr5, r5, %[c]\\n\\t\"\n        \"ldr\tr5, [%[a], r7]\\n\\t\"\n        \"sbcs\tr5, r5, r6\\n\\t\"\n        \"sbcs\t%[c], %[c], %[c]\\n\\t\"\n        \"str\tr5, [%[r], r7]\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"cmp\tr7, r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n    return c;\n}\n\n/* Reduce the number back to 3072 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr8, %[mp]\\n\\t\"\n        \"mov\tr12, %[m]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"add\tr11, r9, #192\\n\\t\"\n        \"\\n1:\\n\\t\"\n        /* mu = a[i] * mp */\n        \"mov\t%[mp], r8\\n\\t\"\n        \"ldr\t%[a], [r9]\\n\\t\"\n        \"mul\t%[mp], %[mp], %[a]\\n\\t\"\n        \"mov\t%[m], r12\\n\\t\"\n        \"mov\tr10, r9\\n\\t\"\n        \"add\tr14, r9, #184\\n\\t\"\n        \"\\n2:\\n\\t\"\n        /* a[i+j] += m[j] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr4, r4, %[a]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr4, [r10], #4\\n\\t\"\n        /* a[i+j+1] += m[j+1] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr5, r5, %[a]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [r10], #4\\n\\t\"\n        \"cmp\tr10, r14\\n\\t\"\n        \"blt\t2b\\n\\t\"\n        /* a[i+46] += m[46] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr4, r4, %[a]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr4, [r10], #4\\n\\t\"\n        /* a[i+47] += m[47] * mu */\n        \"mov\tr4, %[ca]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        /* Multiply m[47] and mu - Start */\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        /* Multiply m[47] and mu - Done */\n        \"ldr\tr6, [r10]\\n\\t\"\n        \"ldr\tr7, [r10, #4]\\n\\t\"\n        \"adds\tr6, r6, r5\\n\\t\"\n        \"adcs\tr7, r7, r4\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        \"str\tr6, [r10]\\n\\t\"\n        \"str\tr7, [r10, #4]\\n\\t\"\n        /* Next word in a */\n        \"add\tr9, r9, #4\\n\\t\"\n        \"cmp\tr9, r11\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[m], r12\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n\n    sp_3072_cond_sub_48(a - 48, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_48(r, a, b);\n    sp_3072_mont_reduce_48(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_48(r, a);\n    sp_3072_mont_reduce_48(r, m, mp);\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nSP_NOINLINE static void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n    __asm__ __volatile__ (\n        \"add\tr8, %[a], #192\\n\\t\"\n        /* A[0] * B */\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"umull\tr5, r3, r6, %[b]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr5, [%[r]], #4\\n\\t\"\n        /* A[0] * B - Done */\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[] * B */\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"umull\tr6, r7, r6, %[b]\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[] * B - Done */\n        \"str\tr3, [%[r]], #4\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"cmp\t%[a], r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        : [r] \"+r\" (r), [a] \"+r\" (a)\n        : [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nSP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"add\tr6, r6, #1\\n\\t\"\n        \"udiv\tr4, %[d1], r6\\n\\t\"\n        \"lsl\tr7, r4, #16\\n\\t\"\n        \"umull\tr4, r5, %[div], r7\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"udiv\tr5, %[d1], r6\\n\\t\"\n        \"lsl\tr4, r5, #16\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"lsl\tr4, %[d1], #16\\n\\t\"\n        \"orr\tr4, r4, %[d0], lsr #16\\n\\t\"\n        \"udiv\tr4, r4, r6\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"lsl\tr4, %[d1], #16\\n\\t\"\n        \"orr\tr4, r4, %[d0], lsr #16\\n\\t\"\n        \"udiv\tr4, r4, r6\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"udiv\tr4, %[d0], %[div]\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"mov\t%[r], r7\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n    return r;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nSP_NOINLINE static int32_t sp_3072_cmp_48(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr6, #188\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"ldr\tr7, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr7, r7, r3\\n\\t\"\n        \"and\tr5, r5, r3\\n\\t\"\n        \"mov\tr4, r7\\n\\t\"\n        \"subs\tr7, r7, r5\\n\\t\"\n        \"sbc\tr7, r7, r7\\n\\t\"\n        \"add\t%[r], %[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r3, r7\\n\\t\"\n        \"subs\tr5, r5, r4\\n\\t\"\n        \"sbc\tr7, r7, r7\\n\\t\"\n        \"sub\t%[r], %[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r3, r7\\n\\t\"\n        \"sub\tr6, r6, #4\\n\\t\"\n        \"cmp\tr6, #0\\n\\t\"\n        \"bge\t1b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_48(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[96], t2[49];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[47];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 48);\n    for (i=47; i>=0; i--) {\n        r1 = div_3072_word_48(t1[48 + i], t1[48 + i - 1], div);\n\n        sp_3072_mul_d_48(t2, d, r1);\n        t1[48 + i] += sp_3072_sub_in_place_48(&t1[i], t2);\n        t1[48 + i] -= t2[48];\n        sp_3072_mask_48(t2, d, t1[48 + i]);\n        t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], t2);\n        sp_3072_mask_48(t2, d, t1[48 + i]);\n        t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_3072_cmp_48(t1, d) >= 0;\n    sp_3072_cond_sub_48(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_48(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_48(a, m, NULL, r);\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][96];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 96, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 96;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_48(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 48U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_48(t[1] + 48, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_48(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 48, a, sizeof(sp_digit) * 48);\n            err = sp_3072_mod_48(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_48(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_48(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_48(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_48(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_48(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_48(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_48(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_48(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_48(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_48(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_48(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_48(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_48(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_48(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 48);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n\n            sp_3072_mont_mul_48(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[48], 0, sizeof(sp_digit) * 48U);\n        sp_3072_mont_reduce_48(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_48(r, m) >= 0);\n        sp_3072_cond_sub_48(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][96];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 96, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 96;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_48(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 48U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_48(t[1] + 48, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_48(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 48, a, sizeof(sp_digit) * 48);\n            err = sp_3072_mod_48(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_48(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_48(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_48(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_48(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_48(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_48(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_48(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_48(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_48(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_48(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_48(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_48(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_48(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_48(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_48(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_48(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_48(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_48(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_48(t[20], t[10], m, mp);\n        sp_3072_mont_mul_48(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_48(t[22], t[11], m, mp);\n        sp_3072_mont_mul_48(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_48(t[24], t[12], m, mp);\n        sp_3072_mont_mul_48(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_48(t[26], t[13], m, mp);\n        sp_3072_mont_mul_48(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_48(t[28], t[14], m, mp);\n        sp_3072_mont_mul_48(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_48(t[30], t[15], m, mp);\n        sp_3072_mont_mul_48(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 48);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n\n            sp_3072_mont_mul_48(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[48], 0, sizeof(sp_digit) * 48U);\n        sp_3072_mont_reduce_48(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_48(r, m) >= 0);\n        sp_3072_cond_sub_48(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_96(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 96);\n\n    /* r = 2^n mod m */\n    sp_3072_sub_in_place_96(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nSP_NOINLINE static sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, sp_digit m)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr5, #1\\n\\t\"\n        \"lsl\tr5, r5, #8\\n\\t\"\n        \"add\tr5, r5, #128\\n\\t\"\n        \"mov\tr8, r5\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"ldr\tr6, [%[b], r7]\\n\\t\"\n        \"and\tr6, r6, %[m]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"subs\tr5, r5, %[c]\\n\\t\"\n        \"ldr\tr5, [%[a], r7]\\n\\t\"\n        \"sbcs\tr5, r5, r6\\n\\t\"\n        \"sbcs\t%[c], %[c], %[c]\\n\\t\"\n        \"str\tr5, [%[r], r7]\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"cmp\tr7, r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n    return c;\n}\n\n/* Reduce the number back to 3072 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr8, %[mp]\\n\\t\"\n        \"mov\tr12, %[m]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"add\tr11, r9, #384\\n\\t\"\n        \"\\n1:\\n\\t\"\n        /* mu = a[i] * mp */\n        \"mov\t%[mp], r8\\n\\t\"\n        \"ldr\t%[a], [r9]\\n\\t\"\n        \"mul\t%[mp], %[mp], %[a]\\n\\t\"\n        \"mov\t%[m], r12\\n\\t\"\n        \"mov\tr10, r9\\n\\t\"\n        \"add\tr14, r9, #376\\n\\t\"\n        \"\\n2:\\n\\t\"\n        /* a[i+j] += m[j] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr4, r4, %[a]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr4, [r10], #4\\n\\t\"\n        /* a[i+j+1] += m[j+1] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr5, r5, %[a]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [r10], #4\\n\\t\"\n        \"cmp\tr10, r14\\n\\t\"\n        \"blt\t2b\\n\\t\"\n        /* a[i+94] += m[94] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr4, r4, %[a]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr4, [r10], #4\\n\\t\"\n        /* a[i+95] += m[95] * mu */\n        \"mov\tr4, %[ca]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        /* Multiply m[95] and mu - Start */\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        /* Multiply m[95] and mu - Done */\n        \"ldr\tr6, [r10]\\n\\t\"\n        \"ldr\tr7, [r10, #4]\\n\\t\"\n        \"adds\tr6, r6, r5\\n\\t\"\n        \"adcs\tr7, r7, r4\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        \"str\tr6, [r10]\\n\\t\"\n        \"str\tr7, [r10, #4]\\n\\t\"\n        /* Next word in a */\n        \"add\tr9, r9, #4\\n\\t\"\n        \"cmp\tr9, r11\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[m], r12\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n\n    sp_3072_cond_sub_96(a - 96, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_96(r, a, b);\n    sp_3072_mont_reduce_96(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_96(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_96(r, a);\n    sp_3072_mont_reduce_96(r, m, mp);\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nSP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"add\tr6, r6, #1\\n\\t\"\n        \"udiv\tr4, %[d1], r6\\n\\t\"\n        \"lsl\tr7, r4, #16\\n\\t\"\n        \"umull\tr4, r5, %[div], r7\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"udiv\tr5, %[d1], r6\\n\\t\"\n        \"lsl\tr4, r5, #16\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"lsl\tr4, %[d1], #16\\n\\t\"\n        \"orr\tr4, r4, %[d0], lsr #16\\n\\t\"\n        \"udiv\tr4, r4, r6\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"lsl\tr4, %[d1], #16\\n\\t\"\n        \"orr\tr4, r4, %[d0], lsr #16\\n\\t\"\n        \"udiv\tr4, r4, r6\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"udiv\tr4, %[d0], %[div]\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"mov\t%[r], r7\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_96(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<96; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 96; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nSP_NOINLINE static int32_t sp_3072_cmp_96(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #124\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"ldr\tr7, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr7, r7, r3\\n\\t\"\n        \"and\tr5, r5, r3\\n\\t\"\n        \"mov\tr4, r7\\n\\t\"\n        \"subs\tr7, r7, r5\\n\\t\"\n        \"sbc\tr7, r7, r7\\n\\t\"\n        \"add\t%[r], %[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r3, r7\\n\\t\"\n        \"subs\tr5, r5, r4\\n\\t\"\n        \"sbc\tr7, r7, r7\\n\\t\"\n        \"sub\t%[r], %[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r3, r7\\n\\t\"\n        \"sub\tr6, r6, #4\\n\\t\"\n        \"cmp\tr6, #0\\n\\t\"\n        \"bge\t1b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_96(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[192], t2[97];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[95];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 96);\n    for (i=95; i>=0; i--) {\n        r1 = div_3072_word_96(t1[96 + i], t1[96 + i - 1], div);\n\n        sp_3072_mul_d_96(t2, d, r1);\n        t1[96 + i] += sp_3072_sub_in_place_96(&t1[i], t2);\n        t1[96 + i] -= t2[96];\n        sp_3072_mask_96(t2, d, t1[96 + i]);\n        t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], t2);\n        sp_3072_mask_96(t2, d, t1[96 + i]);\n        t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_3072_cmp_96(t1, d) >= 0;\n    sp_3072_cond_sub_96(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_96(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_96(a, m, NULL, r);\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_96_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[192], t2[97];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[95];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 96);\n    for (i=95; i>=0; i--) {\n        r1 = div_3072_word_96(t1[96 + i], t1[96 + i - 1], div);\n\n        sp_3072_mul_d_96(t2, d, r1);\n        t1[96 + i] += sp_3072_sub_in_place_96(&t1[i], t2);\n        t1[96 + i] -= t2[96];\n        if (t1[96 + i] != 0) {\n            t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], d);\n            if (t1[96 + i] != 0)\n                t1[96 + i] += sp_3072_add_96(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_3072_cmp_96(t1, d) >= 0;\n    sp_3072_cond_sub_96(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_96_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_96_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][192];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 192, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 192;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_96(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 96U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_96(t[1] + 96, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_96(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 96, a, sizeof(sp_digit) * 96);\n            err = sp_3072_mod_96(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_96(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_96(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_96(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_96(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_96(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_96(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_96(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_96(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_96(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_96(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_96(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_96(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_96(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_96(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 96);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n\n            sp_3072_mont_mul_96(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[96], 0, sizeof(sp_digit) * 96U);\n        sp_3072_mont_reduce_96(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_96(r, m) >= 0);\n        sp_3072_cond_sub_96(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_96(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][192];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 192, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 192;\n        }\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_96(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 96U);\n        if (reduceA != 0) {\n            err = sp_3072_mod_96(t[1] + 96, a, m);\n            if (err == MP_OKAY) {\n                err = sp_3072_mod_96(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 96, a, sizeof(sp_digit) * 96);\n            err = sp_3072_mod_96(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_96(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_96(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_96(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_96(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_96(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_96(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_96(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_96(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_96(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_96(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_96(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_96(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_96(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_96(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_96(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_96(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_96(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_96(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_96(t[20], t[10], m, mp);\n        sp_3072_mont_mul_96(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_96(t[22], t[11], m, mp);\n        sp_3072_mont_mul_96(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_96(t[24], t[12], m, mp);\n        sp_3072_mont_mul_96(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_96(t[26], t[13], m, mp);\n        sp_3072_mont_mul_96(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_96(t[28], t[14], m, mp);\n        sp_3072_mont_mul_96(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_96(t[30], t[15], m, mp);\n        sp_3072_mont_mul_96(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 96);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n\n            sp_3072_mont_mul_96(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[96], 0, sizeof(sp_digit) * 96U);\n        sp_3072_mont_reduce_96(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_96(r, m) >= 0);\n        sp_3072_cond_sub_96(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[192], md[96], rd[192];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1];\n    int err = MP_OKAY;\n\n    if (*outLen < 384)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 32 || inLen > 384 ||\n                                                     mp_count_bits(mm) != 3072))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 96 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 96 * 2;\n        m = r + 96 * 2;\n        ah = a + 96;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 96;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(ah, 96, in, inLen);\n#if DIGIT_BIT >= 32\n        e[0] = em->dp[0];\n#else\n        e[0] = em->dp[0];\n        if (em->used > 1)\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e[0] == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(m, 96, mm);\n\n        if (e[0] == 0x3) {\n            if (err == MP_OKAY) {\n                sp_3072_sqr_96(r, ah);\n                err = sp_3072_mod_96_cond(r, r, m);\n            }\n            if (err == MP_OKAY) {\n                sp_3072_mul_96(r, ah, r);\n                err = sp_3072_mod_96_cond(r, r, m);\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_3072_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 96);\n            err = sp_3072_mod_96_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=31; i>=0; i--)\n                    if (e[0] >> i)\n                        break;\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 96);\n                for (i--; i>=0; i--) {\n                    sp_3072_mont_sqr_96(r, r, m, mp);\n                    if (((e[0] >> i) & 1) == 1)\n                        sp_3072_mont_mul_96(r, r, a, m, mp);\n                }\n                XMEMSET(&r[96], 0, sizeof(sp_digit) * 96);\n                sp_3072_mont_reduce_96(r, m, mp);\n\n                for (i = 95; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_3072_sub_in_place_96(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[96 * 2];\n    sp_digit pd[48], qd[48], dpd[48];\n    sp_digit tmpad[96], tmpbd[96];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 384)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 384 || mp_count_bits(mm) != 3072))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 48 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 96 * 2;\n        q = p + 48;\n        qi = dq = dp = q + 48;\n        tmpa = qi + 48;\n        tmpb = tmpa + 96;\n\n        tmp = t;\n        r = tmp + 96;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 96;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(a, 96, in, inLen);\n        sp_3072_from_mp(p, 48, pm);\n        sp_3072_from_mp(q, 48, qm);\n        sp_3072_from_mp(dp, 48, dpm);\n\n        err = sp_3072_mod_exp_48(tmpa, a, dp, 1536, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(dq, 48, dqm);\n        err = sp_3072_mod_exp_48(tmpb, a, dq, 1536, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_3072_sub_in_place_48(tmpa, tmpb);\n        sp_3072_mask_48(tmp, p, c);\n        sp_3072_add_48(tmpa, tmpa, tmp);\n\n        sp_3072_from_mp(qi, 48, qim);\n        sp_3072_mul_48(tmpa, tmpa, qi);\n        err = sp_3072_mod_48(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mul_48(tmpa, q, tmpa);\n        XMEMSET(&tmpb[48], 0, sizeof(sp_digit) * 48);\n        sp_3072_add_96(r, tmpb, tmpa);\n\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 48 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_3072_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 32\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 96);\n        r->used = 96;\n        mp_clamp(r);\n#elif DIGIT_BIT < 32\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 96; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 32) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 32 - s;\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 96; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 32 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 32 - s;\n            }\n            else {\n                s += 32;\n            }\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[192], e[96], m[96];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 96, base);\n        sp_3072_from_mp(e, 96, exp);\n        sp_3072_from_mp(m, 96, mod);\n\n        err = sp_3072_mod_exp_96(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_3072_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_3072\nstatic void sp_3072_lshift_96(sp_digit* r, sp_digit* a, byte n)\n{\n    __asm__ __volatile__ (\n        \"mov r6, #31\\n\\t\"\n        \"sub r6, r6, %[n]\\n\\t\"\n        \"add       %[a], %[a], #320\\n\\t\"\n        \"add       %[r], %[r], #320\\n\\t\"\n        \"ldr r3, [%[a], #60]\\n\\t\"\n        \"lsr r4, r3, #1\\n\\t\"\n        \"lsl r3, r3, %[n]\\n\\t\"\n        \"lsr r4, r4, r6\\n\\t\"\n        \"ldr       r2, [%[a], #56]\\n\\t\"\n        \"str       r4, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #52]\\n\\t\"\n        \"str       r3, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #48]\\n\\t\"\n        \"str       r2, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #44]\\n\\t\"\n        \"str       r4, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #40]\\n\\t\"\n        \"str       r3, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #36]\\n\\t\"\n        \"str       r2, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #32]\\n\\t\"\n        \"str       r4, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #28]\\n\\t\"\n        \"str       r3, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #24]\\n\\t\"\n        \"str       r2, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #20]\\n\\t\"\n        \"str       r4, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #16]\\n\\t\"\n        \"str       r3, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #12]\\n\\t\"\n        \"str       r2, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #8]\\n\\t\"\n        \"str       r4, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #4]\\n\\t\"\n        \"str       r3, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #0]\\n\\t\"\n        \"str       r2, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r2, [%[a], #60]\\n\\t\"\n        \"str       r4, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #56]\\n\\t\"\n        \"str       r3, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #52]\\n\\t\"\n        \"str       r2, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #48]\\n\\t\"\n        \"str       r4, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #44]\\n\\t\"\n        \"str       r3, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #40]\\n\\t\"\n        \"str       r2, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #36]\\n\\t\"\n        \"str       r4, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #32]\\n\\t\"\n        \"str       r3, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #28]\\n\\t\"\n        \"str       r2, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #24]\\n\\t\"\n        \"str       r4, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #20]\\n\\t\"\n        \"str       r3, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #16]\\n\\t\"\n        \"str       r2, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #12]\\n\\t\"\n        \"str       r4, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #8]\\n\\t\"\n        \"str       r3, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #4]\\n\\t\"\n        \"str       r2, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #0]\\n\\t\"\n        \"str       r4, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r4, [%[a], #60]\\n\\t\"\n        \"str       r3, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #56]\\n\\t\"\n        \"str       r2, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #52]\\n\\t\"\n        \"str       r4, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #48]\\n\\t\"\n        \"str       r3, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #44]\\n\\t\"\n        \"str       r2, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #40]\\n\\t\"\n        \"str       r4, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #36]\\n\\t\"\n        \"str       r3, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #32]\\n\\t\"\n        \"str       r2, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #28]\\n\\t\"\n        \"str       r4, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #24]\\n\\t\"\n        \"str       r3, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #20]\\n\\t\"\n        \"str       r2, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #16]\\n\\t\"\n        \"str       r4, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #12]\\n\\t\"\n        \"str       r3, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #8]\\n\\t\"\n        \"str       r2, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #4]\\n\\t\"\n        \"str       r4, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #0]\\n\\t\"\n        \"str       r3, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r3, [%[a], #60]\\n\\t\"\n        \"str       r2, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #56]\\n\\t\"\n        \"str       r4, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #52]\\n\\t\"\n        \"str       r3, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #48]\\n\\t\"\n        \"str       r2, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #44]\\n\\t\"\n        \"str       r4, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #40]\\n\\t\"\n        \"str       r3, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #36]\\n\\t\"\n        \"str       r2, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #32]\\n\\t\"\n        \"str       r4, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #28]\\n\\t\"\n        \"str       r3, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #24]\\n\\t\"\n        \"str       r2, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #20]\\n\\t\"\n        \"str       r4, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #16]\\n\\t\"\n        \"str       r3, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #12]\\n\\t\"\n        \"str       r2, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #8]\\n\\t\"\n        \"str       r4, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #4]\\n\\t\"\n        \"str       r3, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #0]\\n\\t\"\n        \"str       r2, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r2, [%[a], #60]\\n\\t\"\n        \"str       r4, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #56]\\n\\t\"\n        \"str       r3, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #52]\\n\\t\"\n        \"str       r2, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #48]\\n\\t\"\n        \"str       r4, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #44]\\n\\t\"\n        \"str       r3, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #40]\\n\\t\"\n        \"str       r2, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #36]\\n\\t\"\n        \"str       r4, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #32]\\n\\t\"\n        \"str       r3, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #28]\\n\\t\"\n        \"str       r2, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #24]\\n\\t\"\n        \"str       r4, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #20]\\n\\t\"\n        \"str       r3, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #16]\\n\\t\"\n        \"str       r2, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #12]\\n\\t\"\n        \"str       r4, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #8]\\n\\t\"\n        \"str       r3, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #4]\\n\\t\"\n        \"str       r2, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #0]\\n\\t\"\n        \"str       r4, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r4, [%[a], #60]\\n\\t\"\n        \"str       r3, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #56]\\n\\t\"\n        \"str       r2, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #52]\\n\\t\"\n        \"str       r4, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #48]\\n\\t\"\n        \"str       r3, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #44]\\n\\t\"\n        \"str       r2, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #40]\\n\\t\"\n        \"str       r4, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #36]\\n\\t\"\n        \"str       r3, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #32]\\n\\t\"\n        \"str       r2, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #28]\\n\\t\"\n        \"str       r4, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #24]\\n\\t\"\n        \"str       r3, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #20]\\n\\t\"\n        \"str       r2, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #16]\\n\\t\"\n        \"str       r4, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #12]\\n\\t\"\n        \"str       r3, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #8]\\n\\t\"\n        \"str       r2, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #4]\\n\\t\"\n        \"str       r4, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #0]\\n\\t\"\n        \"str       r3, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"str r4, [%[r]]\\n\\t\"\n        \"str r2, [%[r], #4]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [n] \"r\" (n)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_2_96(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[192];\n    sp_digit td[97];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 289, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 192;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_96(norm, m);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        sp_3072_lshift_96(r, norm, y);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n            sp_3072_mont_sqr_96(r, r, m, mp);\n\n            sp_3072_lshift_96(r, r, y);\n            sp_3072_mul_d_96(tmp, norm, r[96]);\n            r[96] = 0;\n            o = sp_3072_add_96(r, r, tmp);\n            sp_3072_cond_sub_96(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[96], 0, sizeof(sp_digit) * 96U);\n        sp_3072_mont_reduce_96(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_96(r, m) >= 0);\n        sp_3072_cond_sub_96(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* HAVE_FFDHE_3072 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 384 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[192], e[96], m[96];\n    sp_digit* r = b;\n    word32 i;\n\n    if (mp_count_bits(base) > 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 384) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 3072) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 96, base);\n        sp_3072_from_bin(e, 96, exp, expLen);\n        sp_3072_from_mp(m, 96, mod);\n\n    #ifdef HAVE_FFDHE_3072\n        if (base->used == 1 && base->dp[0] == 2 && m[95] == (sp_digit)-1)\n            err = sp_3072_mod_exp_2_96(r, e, expLen * 8, m);\n        else\n    #endif\n            err = sp_3072_mod_exp_96(r, b, e, expLen * 8, m, 0);\n\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n        for (i=0; i<384 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[96], e[48], m[48];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1536) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 1536) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 48, base);\n        sp_3072_from_mp(e, 48, exp);\n        sp_3072_from_mp(m, 48, mod);\n\n        err = sp_3072_mod_exp_48(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 48, 0, sizeof(*r) * 48U);\n        err = sp_3072_to_mp(r, res);\n        res->used = mod->used;\n        mp_clamp(res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_3072 */\n\n#ifdef WOLFSSL_SP_4096\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 24U) {\n            r[j] &= 0xffffffff;\n            s = 32U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 32\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 32\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffff;\n        s = 32U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 32U) <= (word32)DIGIT_BIT) {\n            s += 32U;\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 32) {\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 32 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 512\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_4096_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 4096 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<128 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 32) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 32);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_4096_add_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_4096_sub_in_place_128(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"subs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[64 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #252\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[b], %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\t%[b], %[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        /* Multiply Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply Done */\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\t%[b], %[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_4096_mask_64(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<64; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_128(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[128];\n    sp_digit a1[64];\n    sp_digit b1[64];\n    sp_digit z2[128];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_64(a1, a, &a[64]);\n    cb = sp_2048_add_64(b1, b, &b[64]);\n    u  = ca & cb;\n    sp_2048_mul_64(z1, a1, b1);\n    sp_2048_mul_64(z2, &a[64], &b[64]);\n    sp_2048_mul_64(z0, a, b);\n    sp_2048_mask_64(r + 128, a1, 0 - cb);\n    sp_2048_mask_64(b1, b1, 0 - ca);\n    u += sp_2048_add_64(r + 128, r + 128, b1);\n    u += sp_4096_sub_in_place_128(z1, z2);\n    u += sp_4096_sub_in_place_128(z1, z0);\n    u += sp_4096_add_128(r + 64, r + 64, z1);\n    r[192] = u;\n    XMEMSET(r + 192 + 1, 0, sizeof(sp_digit) * (64 - 1));\n    (void)sp_4096_add_128(r + 128, r + 128, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_64(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #252\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, r2, %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\tr2, r2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        /* Multiply * 2: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply * 2: Done */\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        /* Square: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Square: Done */\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\tr2, r2, #4\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #1\\n\\t\"\n        \"lsl\tr3, r3, #8\\n\\t\"\n        \"add\tr3, r3, #252\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"subs\tr3, r3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[128];\n    sp_digit z1[128];\n    sp_digit a1[64];\n    sp_digit u;\n\n    u = sp_2048_add_64(a1, a, &a[64]);\n    sp_2048_sqr_64(z1, a1);\n    sp_2048_sqr_64(z2, &a[64]);\n    sp_2048_sqr_64(z0, a);\n    sp_2048_mask_64(r + 128, a1, 0 - u);\n    u += sp_2048_add_64(r + 128, r + 128, r + 128);\n    u += sp_4096_sub_in_place_128(z1, z2);\n    u += sp_4096_sub_in_place_128(z1, z0);\n    u += sp_4096_add_128(r + 64, r + 64, z1);\n    r[192] = u;\n    XMEMSET(r + 192 + 1, 0, sizeof(sp_digit) * (64 - 1));\n    (void)sp_4096_add_128(r + 128, r + 128, z2);\n}\n\n#endif /* !WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\tr6, r6, #512\\n\\t\"\n        \"sub\tr7, r7, #1\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"adcs\tr4, r4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"add\t%[b], %[b], #4\\n\\t\"\n        \"add\t%[r], %[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_4096_sub_in_place_128(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n    __asm__ __volatile__ (\n        \"mov\tr7, %[a]\\n\\t\"\n        \"add\tr7, r7, #512\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"subs\tr5, r5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"str\tr3, [%[a]]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        \"add\t%[a], %[a], #8\\n\\t\"\n        \"add\t%[b], %[b], #8\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n#ifdef WOLFSSL_SP_SMALL\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_128(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[128 * 2];\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr10, %[b]\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"mov\tr12, r6\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #252\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\t%[b], r8\\n\\t\"\n        \"sub\t%[b], %[b], %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\t%[b], %[b], r10\\n\\t\"\n        \"\\n2:\\n\\t\"\n        /* Multiply Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [%[b]]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply Done */\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\t%[b], %[b], #4\\n\\t\"\n        \"cmp\t%[a], r12\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"mov\tr6, r8\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #3\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[b], r10\\n\\t\"\n        :\n        : [r] \"r\" (tmp), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\"\n    );\n\n    XMEMCPY(r, tmp, sizeof(tmp));\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"mov\tr8, r3\\n\\t\"\n        \"mov\tr11, %[r]\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"neg\tr6, r6\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        \"mov\tr10, sp\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\t%[r], #0\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #252\\n\\t\"\n        \"mov\t%[a], r8\\n\\t\"\n        \"subs\t%[a], %[a], r6\\n\\t\"\n        \"sbc\tr6, r6, r6\\n\\t\"\n        \"mvn\tr6, r6\\n\\t\"\n        \"and\t%[a], %[a], r6\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sub\tr2, r2, %[a]\\n\\t\"\n        \"add\t%[a], %[a], r9\\n\\t\"\n        \"add\tr2, r2, r9\\n\\t\"\n        \"\\n2:\\n\\t\"\n        \"cmp\tr2, %[a]\\n\\t\"\n        \"beq\t4f\\n\\t\"\n        /* Multiply * 2: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"ldr\tr7, [r2]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Multiply * 2: Done */\n        \"bal\t5f\\n\\t\"\n        \"\\n4:\\n\\t\"\n        /* Square: Start */\n        \"ldr\tr6, [%[a]]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, %[r]\\n\\t\"\n        /* Square: Done */\n        \"\\n5:\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"sub\tr2, r2, #4\\n\\t\"\n        \"mov\tr6, #2\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, r9\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"beq\t3f\\n\\t\"\n        \"cmp\t%[a], r2\\n\\t\"\n        \"bgt\t3f\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"add\tr7, r7, r9\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"ble\t2b\\n\\t\"\n        \"\\n3:\\n\\t\"\n        \"mov\t%[r], r10\\n\\t\"\n        \"mov\tr7, r8\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"mov\tr8, r7\\n\\t\"\n        \"mov\tr6, #3\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #248\\n\\t\"\n        \"cmp\tr7, r6\\n\\t\"\n        \"ble\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"str\tr3, [%[r], r7]\\n\\t\"\n        \"mov\t%[r], r11\\n\\t\"\n        \"mov\t%[a], r10\\n\\t\"\n        \"mov\tr3, #3\\n\\t\"\n        \"lsl\tr3, r3, #8\\n\\t\"\n        \"add\tr3, r3, #252\\n\\t\"\n        \"\\n4:\\n\\t\"\n        \"ldr\tr6, [%[a], r3]\\n\\t\"\n        \"str\tr6, [%[r], r3]\\n\\t\"\n        \"subs\tr3, r3, #4\\n\\t\"\n        \"bge\t4b\\n\\t\"\n        \"mov\tr6, #4\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tsp, sp, r6\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nSP_NOINLINE static void sp_4096_mul_d_128(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n    __asm__ __volatile__ (\n        \"add\tr8, %[a], #512\\n\\t\"\n        /* A[0] * B */\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"umull\tr5, r3, r6, %[b]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr5, [%[r]], #4\\n\\t\"\n        /* A[0] * B - Done */\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[] * B */\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"umull\tr6, r7, r6, %[b]\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[] * B - Done */\n        \"str\tr3, [%[r]], #4\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"cmp\t%[a], r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        : [r] \"+r\" (r), [a] \"+r\" (a)\n        : [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n}\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 4096 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_4096_mont_norm_128(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 128);\n\n    /* r = 2^n mod m */\n    sp_4096_sub_in_place_128(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nSP_NOINLINE static sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, sp_digit m)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr5, #2\\n\\t\"\n        \"lsl\tr5, r5, #8\\n\\t\"\n        \"mov\tr8, r5\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"ldr\tr6, [%[b], r7]\\n\\t\"\n        \"and\tr6, r6, %[m]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"subs\tr5, r5, %[c]\\n\\t\"\n        \"ldr\tr5, [%[a], r7]\\n\\t\"\n        \"sbcs\tr5, r5, r6\\n\\t\"\n        \"sbcs\t%[c], %[c], %[c]\\n\\t\"\n        \"str\tr5, [%[r], r7]\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"cmp\tr7, r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n    return c;\n}\n\n/* Reduce the number back to 4096 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr8, %[mp]\\n\\t\"\n        \"mov\tr12, %[m]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"add\tr11, r9, #512\\n\\t\"\n        \"\\n1:\\n\\t\"\n        /* mu = a[i] * mp */\n        \"mov\t%[mp], r8\\n\\t\"\n        \"ldr\t%[a], [r9]\\n\\t\"\n        \"mul\t%[mp], %[mp], %[a]\\n\\t\"\n        \"mov\t%[m], r12\\n\\t\"\n        \"mov\tr10, r9\\n\\t\"\n        \"add\tr14, r9, #504\\n\\t\"\n        \"\\n2:\\n\\t\"\n        /* a[i+j] += m[j] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr4, r4, %[a]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr4, [r10], #4\\n\\t\"\n        /* a[i+j+1] += m[j+1] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr5, r5, %[a]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [r10], #4\\n\\t\"\n        \"cmp\tr10, r14\\n\\t\"\n        \"blt\t2b\\n\\t\"\n        /* a[i+126] += m[126] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr4, r4, %[a]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr4, [r10], #4\\n\\t\"\n        /* a[i+127] += m[127] * mu */\n        \"mov\tr4, %[ca]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        /* Multiply m[127] and mu - Start */\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        /* Multiply m[127] and mu - Done */\n        \"ldr\tr6, [r10]\\n\\t\"\n        \"ldr\tr7, [r10, #4]\\n\\t\"\n        \"adds\tr6, r6, r5\\n\\t\"\n        \"adcs\tr7, r7, r4\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        \"str\tr6, [r10]\\n\\t\"\n        \"str\tr7, [r10, #4]\\n\\t\"\n        /* Next word in a */\n        \"add\tr9, r9, #4\\n\\t\"\n        \"cmp\tr9, r11\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[m], r12\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n\n    sp_4096_cond_sub_128(a - 128, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_4096_mul_128(r, a, b);\n    sp_4096_mont_reduce_128(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_sqr_128(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_4096_sqr_128(r, a);\n    sp_4096_mont_reduce_128(r, m, mp);\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nSP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"add\tr6, r6, #1\\n\\t\"\n        \"udiv\tr4, %[d1], r6\\n\\t\"\n        \"lsl\tr7, r4, #16\\n\\t\"\n        \"umull\tr4, r5, %[div], r7\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"udiv\tr5, %[d1], r6\\n\\t\"\n        \"lsl\tr4, r5, #16\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"lsl\tr4, %[d1], #16\\n\\t\"\n        \"orr\tr4, r4, %[d0], lsr #16\\n\\t\"\n        \"udiv\tr4, r4, r6\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"lsl\tr4, %[d1], #16\\n\\t\"\n        \"orr\tr4, r4, %[d0], lsr #16\\n\\t\"\n        \"udiv\tr4, r4, r6\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"udiv\tr4, %[d0], %[div]\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"mov\t%[r], r7\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_4096_mask_128(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<128; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 128; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nSP_NOINLINE static int32_t sp_4096_cmp_128(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr6, #1\\n\\t\"\n        \"lsl\tr6, r6, #8\\n\\t\"\n        \"add\tr6, r6, #252\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"ldr\tr7, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr7, r7, r3\\n\\t\"\n        \"and\tr5, r5, r3\\n\\t\"\n        \"mov\tr4, r7\\n\\t\"\n        \"subs\tr7, r7, r5\\n\\t\"\n        \"sbc\tr7, r7, r7\\n\\t\"\n        \"add\t%[r], %[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r3, r7\\n\\t\"\n        \"subs\tr5, r5, r4\\n\\t\"\n        \"sbc\tr7, r7, r7\\n\\t\"\n        \"sub\t%[r], %[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r3, r7\\n\\t\"\n        \"sub\tr6, r6, #4\\n\\t\"\n        \"cmp\tr6, #0\\n\\t\"\n        \"bge\t1b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return r;\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_div_128(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[256], t2[129];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[127];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 128);\n    for (i=127; i>=0; i--) {\n        r1 = div_4096_word_128(t1[128 + i], t1[128 + i - 1], div);\n\n        sp_4096_mul_d_128(t2, d, r1);\n        t1[128 + i] += sp_4096_sub_in_place_128(&t1[i], t2);\n        t1[128 + i] -= t2[128];\n        sp_4096_mask_128(t2, d, t1[128 + i]);\n        t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], t2);\n        sp_4096_mask_128(t2, d, t1[128 + i]);\n        t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_4096_cmp_128(t1, d) >= 0;\n    sp_4096_cond_sub_128(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_mod_128(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_128(a, m, NULL, r);\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_div_128_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[256], t2[129];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[127];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 128);\n    for (i=127; i>=0; i--) {\n        r1 = div_4096_word_128(t1[128 + i], t1[128 + i - 1], div);\n\n        sp_4096_mul_d_128(t2, d, r1);\n        t1[128 + i] += sp_4096_sub_in_place_128(&t1[i], t2);\n        t1[128 + i] -= t2[128];\n        if (t1[128 + i] != 0) {\n            t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], d);\n            if (t1[128 + i] != 0)\n                t1[128 + i] += sp_4096_add_128(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_4096_cmp_128(t1, d) >= 0;\n    sp_4096_cond_sub_128(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_mod_128_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_128_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n#ifdef WOLFSSL_SP_SMALL\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[16][256];\n#else\n    sp_digit* t[16];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 256, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<16; i++) {\n            t[i] = td + i * 256;\n        }\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_128(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 128U);\n        if (reduceA != 0) {\n            err = sp_4096_mod_128(t[1] + 128, a, m);\n            if (err == MP_OKAY) {\n                err = sp_4096_mod_128(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 128, a, sizeof(sp_digit) * 128);\n            err = sp_4096_mod_128(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_128(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_128(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_128(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_128(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_128(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_128(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_128(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_128(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_128(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_128(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_128(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_128(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_128(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_128(t[15], t[ 8], t[ 7], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 4;\n        if (c == 32) {\n            c = 28;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 128);\n        for (; i>=0 || c>=4; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 28;\n                n <<= 4;\n                c = 28;\n            }\n            else if (c < 4) {\n                y = n >> 28;\n                n = e[i--];\n                c = 4 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 28) & 0xf;\n                n <<= 4;\n                c -= 4;\n            }\n\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n\n            sp_4096_mont_mul_128(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[128], 0, sizeof(sp_digit) * 128U);\n        sp_4096_mont_reduce_128(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_128(r, m) >= 0);\n        sp_4096_cond_sub_128(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#else\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_128(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][256];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 256, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++) {\n            t[i] = td + i * 256;\n        }\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_128(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 128U);\n        if (reduceA != 0) {\n            err = sp_4096_mod_128(t[1] + 128, a, m);\n            if (err == MP_OKAY) {\n                err = sp_4096_mod_128(t[1], t[1], m);\n            }\n        }\n        else {\n            XMEMCPY(t[1] + 128, a, sizeof(sp_digit) * 128);\n            err = sp_4096_mod_128(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_128(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_128(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_128(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_128(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_128(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_128(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_128(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_128(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_128(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_128(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_128(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_128(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_128(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_128(t[15], t[ 8], t[ 7], m, mp);\n        sp_4096_mont_sqr_128(t[16], t[ 8], m, mp);\n        sp_4096_mont_mul_128(t[17], t[ 9], t[ 8], m, mp);\n        sp_4096_mont_sqr_128(t[18], t[ 9], m, mp);\n        sp_4096_mont_mul_128(t[19], t[10], t[ 9], m, mp);\n        sp_4096_mont_sqr_128(t[20], t[10], m, mp);\n        sp_4096_mont_mul_128(t[21], t[11], t[10], m, mp);\n        sp_4096_mont_sqr_128(t[22], t[11], m, mp);\n        sp_4096_mont_mul_128(t[23], t[12], t[11], m, mp);\n        sp_4096_mont_sqr_128(t[24], t[12], m, mp);\n        sp_4096_mont_mul_128(t[25], t[13], t[12], m, mp);\n        sp_4096_mont_sqr_128(t[26], t[13], m, mp);\n        sp_4096_mont_mul_128(t[27], t[14], t[13], m, mp);\n        sp_4096_mont_sqr_128(t[28], t[14], m, mp);\n        sp_4096_mont_mul_128(t[29], t[15], t[14], m, mp);\n        sp_4096_mont_sqr_128(t[30], t[15], m, mp);\n        sp_4096_mont_mul_128(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 128);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n\n            sp_4096_mont_mul_128(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[128], 0, sizeof(sp_digit) * 128U);\n        sp_4096_mont_reduce_128(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_128(r, m) >= 0);\n        sp_4096_cond_sub_128(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_SP_SMALL */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[256], md[128], rd[256];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit e[1];\n    int err = MP_OKAY;\n\n    if (*outLen < 512)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 32 || inLen > 512 ||\n                                                     mp_count_bits(mm) != 4096))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 128 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 128 * 2;\n        m = r + 128 * 2;\n        ah = a + 128;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 128;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(ah, 128, in, inLen);\n#if DIGIT_BIT >= 32\n        e[0] = em->dp[0];\n#else\n        e[0] = em->dp[0];\n        if (em->used > 1)\n            e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e[0] == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(m, 128, mm);\n\n        if (e[0] == 0x3) {\n            if (err == MP_OKAY) {\n                sp_4096_sqr_128(r, ah);\n                err = sp_4096_mod_128_cond(r, r, m);\n            }\n            if (err == MP_OKAY) {\n                sp_4096_mul_128(r, ah, r);\n                err = sp_4096_mod_128_cond(r, r, m);\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_4096_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 128);\n            err = sp_4096_mod_128_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=31; i>=0; i--)\n                    if (e[0] >> i)\n                        break;\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 128);\n                for (i--; i>=0; i--) {\n                    sp_4096_mont_sqr_128(r, r, m, mp);\n                    if (((e[0] >> i) & 1) == 1)\n                        sp_4096_mont_mul_128(r, r, a, m, mp);\n                }\n                XMEMSET(&r[128], 0, sizeof(sp_digit) * 128);\n                sp_4096_mont_reduce_128(r, m, mp);\n\n                for (i = 127; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_4096_sub_in_place_128(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[128 * 2];\n    sp_digit pd[64], qd[64], dpd[64];\n    sp_digit tmpad[128], tmpbd[128];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 512)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 512 || mp_count_bits(mm) != 4096))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 64 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 128 * 2;\n        q = p + 64;\n        qi = dq = dp = q + 64;\n        tmpa = qi + 64;\n        tmpb = tmpa + 128;\n\n        tmp = t;\n        r = tmp + 128;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 128;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(a, 128, in, inLen);\n        sp_4096_from_mp(p, 64, pm);\n        sp_4096_from_mp(q, 64, qm);\n        sp_4096_from_mp(dp, 64, dpm);\n\n        err = sp_4096_mod_exp_64(tmpa, a, dp, 2048, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(dq, 64, dqm);\n        err = sp_4096_mod_exp_64(tmpb, a, dq, 2048, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_4096_sub_in_place_64(tmpa, tmpb);\n        sp_4096_mask_64(tmp, p, c);\n        sp_4096_add_64(tmpa, tmpa, tmp);\n\n        sp_4096_from_mp(qi, 64, qim);\n        sp_4096_mul_64(tmpa, tmpa, qi);\n        err = sp_4096_mod_64(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mul_64(tmpa, q, tmpa);\n        XMEMSET(&tmpb[64], 0, sizeof(sp_digit) * 64);\n        sp_4096_add_128(r, tmpb, tmpa);\n\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 64 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_4096_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (4096 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 32\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 128);\n        r->used = 128;\n        mp_clamp(r);\n#elif DIGIT_BIT < 32\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 128; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 32) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 32 - s;\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 128; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 32 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 32 - s;\n            }\n            else {\n                s += 32;\n            }\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[256], e[128], m[128];\n    sp_digit* r = b;\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expBits > 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 128, base);\n        sp_4096_from_mp(e, 128, exp);\n        sp_4096_from_mp(m, 128, mod);\n\n        err = sp_4096_mod_exp_128(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_4096_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\n#ifdef HAVE_FFDHE_4096\nstatic void sp_4096_lshift_128(sp_digit* r, sp_digit* a, byte n)\n{\n    __asm__ __volatile__ (\n        \"mov r6, #31\\n\\t\"\n        \"sub r6, r6, %[n]\\n\\t\"\n        \"add       %[a], %[a], #448\\n\\t\"\n        \"add       %[r], %[r], #448\\n\\t\"\n        \"ldr r3, [%[a], #60]\\n\\t\"\n        \"lsr r4, r3, #1\\n\\t\"\n        \"lsl r3, r3, %[n]\\n\\t\"\n        \"lsr r4, r4, r6\\n\\t\"\n        \"ldr       r2, [%[a], #56]\\n\\t\"\n        \"str       r4, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #52]\\n\\t\"\n        \"str       r3, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #48]\\n\\t\"\n        \"str       r2, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #44]\\n\\t\"\n        \"str       r4, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #40]\\n\\t\"\n        \"str       r3, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #36]\\n\\t\"\n        \"str       r2, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #32]\\n\\t\"\n        \"str       r4, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #28]\\n\\t\"\n        \"str       r3, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #24]\\n\\t\"\n        \"str       r2, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #20]\\n\\t\"\n        \"str       r4, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #16]\\n\\t\"\n        \"str       r3, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #12]\\n\\t\"\n        \"str       r2, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #8]\\n\\t\"\n        \"str       r4, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #4]\\n\\t\"\n        \"str       r3, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #0]\\n\\t\"\n        \"str       r2, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r2, [%[a], #60]\\n\\t\"\n        \"str       r4, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #56]\\n\\t\"\n        \"str       r3, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #52]\\n\\t\"\n        \"str       r2, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #48]\\n\\t\"\n        \"str       r4, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #44]\\n\\t\"\n        \"str       r3, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #40]\\n\\t\"\n        \"str       r2, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #36]\\n\\t\"\n        \"str       r4, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #32]\\n\\t\"\n        \"str       r3, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #28]\\n\\t\"\n        \"str       r2, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #24]\\n\\t\"\n        \"str       r4, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #20]\\n\\t\"\n        \"str       r3, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #16]\\n\\t\"\n        \"str       r2, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #12]\\n\\t\"\n        \"str       r4, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #8]\\n\\t\"\n        \"str       r3, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #4]\\n\\t\"\n        \"str       r2, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #0]\\n\\t\"\n        \"str       r4, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r4, [%[a], #60]\\n\\t\"\n        \"str       r3, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #56]\\n\\t\"\n        \"str       r2, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #52]\\n\\t\"\n        \"str       r4, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #48]\\n\\t\"\n        \"str       r3, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #44]\\n\\t\"\n        \"str       r2, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #40]\\n\\t\"\n        \"str       r4, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #36]\\n\\t\"\n        \"str       r3, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #32]\\n\\t\"\n        \"str       r2, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #28]\\n\\t\"\n        \"str       r4, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #24]\\n\\t\"\n        \"str       r3, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #20]\\n\\t\"\n        \"str       r2, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #16]\\n\\t\"\n        \"str       r4, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #12]\\n\\t\"\n        \"str       r3, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #8]\\n\\t\"\n        \"str       r2, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #4]\\n\\t\"\n        \"str       r4, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #0]\\n\\t\"\n        \"str       r3, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r3, [%[a], #60]\\n\\t\"\n        \"str       r2, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #56]\\n\\t\"\n        \"str       r4, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #52]\\n\\t\"\n        \"str       r3, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #48]\\n\\t\"\n        \"str       r2, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #44]\\n\\t\"\n        \"str       r4, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #40]\\n\\t\"\n        \"str       r3, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #36]\\n\\t\"\n        \"str       r2, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #32]\\n\\t\"\n        \"str       r4, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #28]\\n\\t\"\n        \"str       r3, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #24]\\n\\t\"\n        \"str       r2, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #20]\\n\\t\"\n        \"str       r4, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #16]\\n\\t\"\n        \"str       r3, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #12]\\n\\t\"\n        \"str       r2, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #8]\\n\\t\"\n        \"str       r4, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #4]\\n\\t\"\n        \"str       r3, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #0]\\n\\t\"\n        \"str       r2, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r2, [%[a], #60]\\n\\t\"\n        \"str       r4, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #56]\\n\\t\"\n        \"str       r3, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #52]\\n\\t\"\n        \"str       r2, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #48]\\n\\t\"\n        \"str       r4, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #44]\\n\\t\"\n        \"str       r3, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #40]\\n\\t\"\n        \"str       r2, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #36]\\n\\t\"\n        \"str       r4, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #32]\\n\\t\"\n        \"str       r3, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #28]\\n\\t\"\n        \"str       r2, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #24]\\n\\t\"\n        \"str       r4, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #20]\\n\\t\"\n        \"str       r3, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #16]\\n\\t\"\n        \"str       r2, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #12]\\n\\t\"\n        \"str       r4, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #8]\\n\\t\"\n        \"str       r3, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #4]\\n\\t\"\n        \"str       r2, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #0]\\n\\t\"\n        \"str       r4, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r4, [%[a], #60]\\n\\t\"\n        \"str       r3, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #56]\\n\\t\"\n        \"str       r2, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #52]\\n\\t\"\n        \"str       r4, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #48]\\n\\t\"\n        \"str       r3, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #44]\\n\\t\"\n        \"str       r2, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #40]\\n\\t\"\n        \"str       r4, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #36]\\n\\t\"\n        \"str       r3, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #32]\\n\\t\"\n        \"str       r2, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #28]\\n\\t\"\n        \"str       r4, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #24]\\n\\t\"\n        \"str       r3, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #20]\\n\\t\"\n        \"str       r2, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #16]\\n\\t\"\n        \"str       r4, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #12]\\n\\t\"\n        \"str       r3, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #8]\\n\\t\"\n        \"str       r2, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #4]\\n\\t\"\n        \"str       r4, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #0]\\n\\t\"\n        \"str       r3, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r3, [%[a], #60]\\n\\t\"\n        \"str       r2, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #56]\\n\\t\"\n        \"str       r4, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #52]\\n\\t\"\n        \"str       r3, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #48]\\n\\t\"\n        \"str       r2, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #44]\\n\\t\"\n        \"str       r4, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #40]\\n\\t\"\n        \"str       r3, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #36]\\n\\t\"\n        \"str       r2, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #32]\\n\\t\"\n        \"str       r4, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #28]\\n\\t\"\n        \"str       r3, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #24]\\n\\t\"\n        \"str       r2, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #20]\\n\\t\"\n        \"str       r4, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #16]\\n\\t\"\n        \"str       r3, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #12]\\n\\t\"\n        \"str       r2, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #8]\\n\\t\"\n        \"str       r4, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #4]\\n\\t\"\n        \"str       r3, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #0]\\n\\t\"\n        \"str       r2, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"sub     %[a], %[a], #64\\n\\t\"\n        \"sub     %[r], %[r], #64\\n\\t\"\n        \"ldr       r2, [%[a], #60]\\n\\t\"\n        \"str       r4, [%[r], #68]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #56]\\n\\t\"\n        \"str       r3, [%[r], #64]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #52]\\n\\t\"\n        \"str       r2, [%[r], #60]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #48]\\n\\t\"\n        \"str       r4, [%[r], #56]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #44]\\n\\t\"\n        \"str       r3, [%[r], #52]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #40]\\n\\t\"\n        \"str       r2, [%[r], #48]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #36]\\n\\t\"\n        \"str       r4, [%[r], #44]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #32]\\n\\t\"\n        \"str       r3, [%[r], #40]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #28]\\n\\t\"\n        \"str       r2, [%[r], #36]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #24]\\n\\t\"\n        \"str       r4, [%[r], #32]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #20]\\n\\t\"\n        \"str       r3, [%[r], #28]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #16]\\n\\t\"\n        \"str       r2, [%[r], #24]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #12]\\n\\t\"\n        \"str       r4, [%[r], #20]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"ldr       r4, [%[a], #8]\\n\\t\"\n        \"str       r3, [%[r], #16]\\n\\t\"\n        \"lsr       r5, r4, #1\\n\\t\"\n        \"lsl       r4, r4, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r2, r2, r5\\n\\t\"\n        \"ldr       r3, [%[a], #4]\\n\\t\"\n        \"str       r2, [%[r], #12]\\n\\t\"\n        \"lsr       r5, r3, #1\\n\\t\"\n        \"lsl       r3, r3, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r4, r4, r5\\n\\t\"\n        \"ldr       r2, [%[a], #0]\\n\\t\"\n        \"str       r4, [%[r], #8]\\n\\t\"\n        \"lsr       r5, r2, #1\\n\\t\"\n        \"lsl       r2, r2, %[n]\\n\\t\"\n        \"lsr       r5, r5, r6\\n\\t\"\n        \"orr       r3, r3, r5\\n\\t\"\n        \"str r2, [%[r]]\\n\\t\"\n        \"str r3, [%[r], #4]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [n] \"r\" (n)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n}\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_2_128(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[256];\n    sp_digit td[129];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 385, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 256;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_128(norm, m);\n\n        i = (bits - 1) / 32;\n        n = e[i--];\n        c = bits & 31;\n        if (c == 0) {\n            c = 32;\n        }\n        c -= bits % 5;\n        if (c == 32) {\n            c = 27;\n        }\n        y = (int)(n >> c);\n        n <<= 32 - c;\n        sp_4096_lshift_128(r, norm, y);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = n >> 27;\n                n <<= 5;\n                c = 27;\n            }\n            else if (c < 5) {\n                y = n >> 27;\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (32 - c);\n                n <<= c;\n                c = 32 - c;\n            }\n            else {\n                y = (n >> 27) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n            sp_4096_mont_sqr_128(r, r, m, mp);\n\n            sp_4096_lshift_128(r, r, y);\n            sp_4096_mul_d_128(tmp, norm, r[128]);\n            r[128] = 0;\n            o = sp_4096_add_128(r, r, tmp);\n            sp_4096_cond_sub_128(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[128], 0, sizeof(sp_digit) * 128U);\n        sp_4096_mont_reduce_128(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_128(r, m) >= 0);\n        sp_4096_cond_sub_128(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL) {\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    }\n#endif\n\n    return err;\n}\n#endif /* HAVE_FFDHE_4096 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 512 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[256], e[128], m[128];\n    sp_digit* r = b;\n    word32 i;\n\n    if (mp_count_bits(base) > 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        if (expLen > 512) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        if (mp_count_bits(mod) != 4096) {\n            err = MP_READ_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 128, base);\n        sp_4096_from_bin(e, 128, exp, expLen);\n        sp_4096_from_mp(m, 128, mod);\n\n    #ifdef HAVE_FFDHE_4096\n        if (base->used == 1 && base->dp[0] == 2 && m[127] == (sp_digit)-1)\n            err = sp_4096_mod_exp_2_128(r, e, expLen * 8, m);\n        else\n    #endif\n            err = sp_4096_mod_exp_128(r, b, e, expLen * 8, m, 0);\n\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n        for (i=0; i<512 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* WOLFSSL_SP_4096 */\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n#ifdef WOLFSSL_HAVE_SP_ECC\n#ifndef WOLFSSL_SP_NO_256\n\n/* Point structure to use. */\ntypedef struct sp_point {\n    sp_digit x[2 * 8];\n    sp_digit y[2 * 8];\n    sp_digit z[2 * 8];\n    int infinity;\n} sp_point;\n\n/* The modulus (prime) of the curve P256. */\nstatic const sp_digit p256_mod[8] = {\n    0xffffffff,0xffffffff,0xffffffff,0x00000000,0x00000000,0x00000000,\n    0x00000001,0xffffffff\n};\n/* The Montogmery normalizer for modulus of the curve P256. */\nstatic const sp_digit p256_norm_mod[8] = {\n    0x00000001,0x00000000,0x00000000,0xffffffff,0xffffffff,0xffffffff,\n    0xfffffffe,0x00000000\n};\n/* The Montogmery multiplier for modulus of the curve P256. */\nstatic const sp_digit p256_mp_mod = 0x00000001;\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                            defined(HAVE_ECC_VERIFY)\n/* The order of the curve P256. */\nstatic const sp_digit p256_order[8] = {\n    0xfc632551,0xf3b9cac2,0xa7179e84,0xbce6faad,0xffffffff,0xffffffff,\n    0x00000000,0xffffffff\n};\n#endif\n/* The order of the curve P256 minus 2. */\nstatic const sp_digit p256_order2[8] = {\n    0xfc63254f,0xf3b9cac2,0xa7179e84,0xbce6faad,0xffffffff,0xffffffff,\n    0x00000000,0xffffffff\n};\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery normalizer for order of the curve P256. */\nstatic const sp_digit p256_norm_order[8] = {\n    0x039cdaaf,0x0c46353d,0x58e8617b,0x43190552,0x00000000,0x00000000,\n    0xffffffff,0x00000000\n};\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery multiplier for order of the curve P256. */\nstatic const sp_digit p256_mp_order = 0xee00bc4f;\n#endif\n/* The base point of curve P256. */\nstatic const sp_point p256_base = {\n    /* X ordinate */\n    {\n        0xd898c296,0xf4a13945,0x2deb33a0,0x77037d81,0x63a440f2,0xf8bce6e5,\n        0xe12c4247,0x6b17d1f2, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L\n    },\n    /* Y ordinate */\n    {\n        0x37bf51f5,0xcbb64068,0x6b315ece,0x2bce3357,0x7c0f9e16,0x8ee7eb4a,\n        0xfe1a7f9b,0x4fe342e2, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L\n    },\n    /* Z ordinate */\n    {\n        0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,\n        0x00000000,0x00000000, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L\n    },\n    /* infinity */\n    0\n};\n#if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)\nstatic const sp_digit p256_b[8] = {\n    0x27d2604b,0x3bce3c3e,0xcc53b0f6,0x651d06b0,0x769886bc,0xb3ebbd55,\n    0xaa3a93e7,0x5ac635d8\n};\n#endif\n\nstatic int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p)\n{\n    int ret = MP_OKAY;\n    (void)heap;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    (void)sp;\n    *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC);\n#else\n    *p = sp;\n#endif\n    if (p == NULL) {\n        ret = MEMORY_E;\n    }\n    return ret;\n}\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* Allocate memory for point and return error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p))\n#else\n/* Set pointer to data and return no error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p))\n#endif\n\n\nstatic void sp_ecc_point_free(sp_point* p, int clear, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* If valid pointer then clear point data if requested and free data. */\n    if (p != NULL) {\n        if (clear != 0) {\n            XMEMSET(p, 0, sizeof(*p));\n        }\n        XFREE(p, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n/* Clear point data if requested. */\n    if (clear != 0) {\n        XMEMSET(p, 0, sizeof(*p));\n    }\n#endif\n    (void)heap;\n}\n\n/* Multiply a number by Montogmery normalizer mod modulus (prime).\n *\n * r  The resulting Montgomery form number.\n * a  The number to convert.\n * m  The modulus (prime).\n */\nstatic int sp_256_mod_mul_norm_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    int64_t t[8];\n    int64_t a64[8];\n    int64_t o;\n\n    (void)m;\n\n    a64[0] = a[0];\n    a64[1] = a[1];\n    a64[2] = a[2];\n    a64[3] = a[3];\n    a64[4] = a[4];\n    a64[5] = a[5];\n    a64[6] = a[6];\n    a64[7] = a[7];\n\n    /*  1  1  0 -1 -1 -1 -1  0 */\n    t[0] = 0 + a64[0] + a64[1] - a64[3] - a64[4] - a64[5] - a64[6];\n    /*  0  1  1  0 -1 -1 -1 -1 */\n    t[1] = 0 + a64[1] + a64[2] - a64[4] - a64[5] - a64[6] - a64[7];\n    /*  0  0  1  1  0 -1 -1 -1 */\n    t[2] = 0 + a64[2] + a64[3] - a64[5] - a64[6] - a64[7];\n    /* -1 -1  0  2  2  1  0 -1 */\n    t[3] = 0 - a64[0] - a64[1] + 2 * a64[3] + 2 * a64[4] + a64[5] - a64[7];\n    /*  0 -1 -1  0  2  2  1  0 */\n    t[4] = 0 - a64[1] - a64[2] + 2 * a64[4] + 2 * a64[5] + a64[6];\n    /*  0  0 -1 -1  0  2  2  1 */\n    t[5] = 0 - a64[2] - a64[3] + 2 * a64[5] + 2 * a64[6] + a64[7];\n    /* -1 -1  0  0  0  1  3  2 */\n    t[6] = 0 - a64[0] - a64[1] + a64[5] + 3 * a64[6] + 2 * a64[7];\n    /*  1  0 -1 -1 -1 -1  0  3 */\n    t[7] = 0 + a64[0] - a64[2] - a64[3] - a64[4] - a64[5] + 3 * a64[7];\n\n    t[1] += t[0] >> 32; t[0] &= 0xffffffff;\n    t[2] += t[1] >> 32; t[1] &= 0xffffffff;\n    t[3] += t[2] >> 32; t[2] &= 0xffffffff;\n    t[4] += t[3] >> 32; t[3] &= 0xffffffff;\n    t[5] += t[4] >> 32; t[4] &= 0xffffffff;\n    t[6] += t[5] >> 32; t[5] &= 0xffffffff;\n    t[7] += t[6] >> 32; t[6] &= 0xffffffff;\n    o     = t[7] >> 32; t[7] &= 0xffffffff;\n    t[0] += o;\n    t[3] -= o;\n    t[6] -= o;\n    t[7] += o;\n    t[1] += t[0] >> 32; t[0] &= 0xffffffff;\n    t[2] += t[1] >> 32; t[1] &= 0xffffffff;\n    t[3] += t[2] >> 32; t[2] &= 0xffffffff;\n    t[4] += t[3] >> 32; t[3] &= 0xffffffff;\n    t[5] += t[4] >> 32; t[4] &= 0xffffffff;\n    t[6] += t[5] >> 32; t[5] &= 0xffffffff;\n    t[7] += t[6] >> 32; t[6] &= 0xffffffff;\n    r[0] = t[0];\n    r[1] = t[1];\n    r[2] = t[2];\n    r[3] = t[3];\n    r[4] = t[4];\n    r[5] = t[5];\n    r[6] = t[6];\n    r[7] = t[7];\n\n    return MP_OKAY;\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_256_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 32\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 32\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffff;\n        s = 32U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 32U) <= (word32)DIGIT_BIT) {\n            s += 32U;\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 32) {\n            r[j] &= 0xffffffff;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 32 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Convert a point of type ecc_point to type sp_point.\n *\n * p   Point of type sp_point (result).\n * pm  Point of type ecc_point.\n */\nstatic void sp_256_point_from_ecc_point_8(sp_point* p, const ecc_point* pm)\n{\n    XMEMSET(p->x, 0, sizeof(p->x));\n    XMEMSET(p->y, 0, sizeof(p->y));\n    XMEMSET(p->z, 0, sizeof(p->z));\n    sp_256_from_mp(p->x, 8, pm->x);\n    sp_256_from_mp(p->y, 8, pm->y);\n    sp_256_from_mp(p->z, 8, pm->z);\n    p->infinity = 0;\n}\n\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_256_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 32\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 8);\n        r->used = 8;\n        mp_clamp(r);\n#elif DIGIT_BIT < 32\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 8; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 32) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 32 - s;\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 8; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 32 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 32 - s;\n            }\n            else {\n                s += 32;\n            }\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Convert a point of type sp_point to type ecc_point.\n *\n * p   Point of type sp_point.\n * pm  Point of type ecc_point (result).\n * returns MEMORY_E when allocation of memory in ecc_point fails otherwise\n * MP_OKAY.\n */\nstatic int sp_256_point_to_ecc_point_8(const sp_point* p, ecc_point* pm)\n{\n    int err;\n\n    err = sp_256_to_mp(p->x, pm->x);\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pm->y);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pm->z);\n    }\n\n    return err;\n}\n\n/* Compare a with b in constant time.\n *\n * a  A single precision integer.\n * b  A single precision integer.\n * return -ve, 0 or +ve if a is less than, equal to or greater than b\n * respectively.\n */\nSP_NOINLINE static int32_t sp_256_cmp_8(const sp_digit* a, const sp_digit* b)\n{\n    sp_digit r = 0;\n\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr6, #28\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"ldr\tr7, [%[a], r6]\\n\\t\"\n        \"ldr\tr5, [%[b], r6]\\n\\t\"\n        \"and\tr7, r7, r3\\n\\t\"\n        \"and\tr5, r5, r3\\n\\t\"\n        \"mov\tr4, r7\\n\\t\"\n        \"subs\tr7, r7, r5\\n\\t\"\n        \"sbc\tr7, r7, r7\\n\\t\"\n        \"add\t%[r], %[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r3, r7\\n\\t\"\n        \"subs\tr5, r5, r4\\n\\t\"\n        \"sbc\tr7, r7, r7\\n\\t\"\n        \"sub\t%[r], %[r], r7\\n\\t\"\n        \"mvn\tr7, r7\\n\\t\"\n        \"and\tr3, r3, r7\\n\\t\"\n        \"sub\tr6, r6, #4\\n\\t\"\n        \"cmp\tr6, #0\\n\\t\"\n        \"bge\t1b\\n\\t\"\n        : [r] \"+r\" (r)\n        : [a] \"r\" (a), [b] \"r\" (b)\n        : \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return r;\n}\n\n/* Normalize the values in each word to 32.\n *\n * a  Array of sp_digit to normalize.\n */\n#define sp_256_norm_8(a)\n\n/* Conditionally subtract b from a using the mask m.\n * m is -1 to subtract and 0 when not copying.\n *\n * r  A single precision number representing condition subtract result.\n * a  A single precision number to subtract from.\n * b  A single precision number to subtract.\n * m  Mask value to apply.\n */\nSP_NOINLINE static sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b, sp_digit m)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr5, #32\\n\\t\"\n        \"mov\tr8, r5\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"ldr\tr6, [%[b], r7]\\n\\t\"\n        \"and\tr6, r6, %[m]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"subs\tr5, r5, %[c]\\n\\t\"\n        \"ldr\tr5, [%[a], r7]\\n\\t\"\n        \"sbcs\tr5, r5, r6\\n\\t\"\n        \"sbcs\t%[c], %[c], %[c]\\n\\t\"\n        \"str\tr5, [%[r], r7]\\n\\t\"\n        \"add\tr7, r7, #4\\n\\t\"\n        \"cmp\tr7, r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        : [c] \"+r\" (c)\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [m] \"r\" (m)\n        : \"memory\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n    return c;\n}\n\n/* Reduce the number back to 256 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    (void)mp;\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"mov\tr2, #0\\n\\t\"\n        \"mov\tr1, #0\\n\\t\"\n        /* i = 0 */\n        \"mov\tr8, r2\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* mu = a[i] * 1 (mp) = a[i] */\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        /* a[i] += -1 * mu = -1 * a[i] => a[i] = 0 no carry */\n        /* a[i+1] += -1 * mu */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adc\tr5, r5, r2\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        /* a[i+2] += -1 * mu */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adc\tr4, r4, r2\\n\\t\"\n        \"str\tr5, [%[a], #8]\\n\\t\"\n        /* a[i+3] += 0 * mu */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"adds\tr4, r4, r3\\n\\t\"\n        \"adc\tr5, r5, r2\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adc\tr5, r5, r2\\n\\t\"\n        \"str\tr4, [%[a], #12]\\n\\t\"\n        /* a[i+4] += 0 * mu */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adc\tr4, r4, r2\\n\\t\"\n        \"str\tr5, [%[a], #16]\\n\\t\"\n        /* a[i+5] += 0 * mu */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adc\tr5, r5, r2\\n\\t\"\n        \"str\tr4, [%[a], #20]\\n\\t\"\n        /* a[i+6] += 1 * mu */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"adds\tr5, r5, r3\\n\\t\"\n        \"adc\tr4, r4, r2\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adc\tr4, r4, r2\\n\\t\"\n        \"str\tr5, [%[a], #24]\\n\\t\"\n        /* a[i+7] += -1 * mu */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[a], #32]\\n\\t\"\n        \"adds\tr5, r1, r3\\n\\t\"\n        \"mov\tr1, #0\\n\\t\"\n        \"adc\tr1, r1, r2\\n\\t\"\n        \"subs\tr4, r4, r3\\n\\t\"\n        \"sbcs\tr5, r5, r2\\n\\t\"\n        \"sbc\tr1, r1, r2\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr1, r1, r2\\n\\t\"\n        \"str\tr4, [%[a],  #28]\\n\\t\"\n        \"str\tr5, [%[a], #32]\\n\\t\"\n        /* i += 1 */\n        \"add\tr8, r8, #1\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"mov\tr6, #8\\n\\t\"\n        \"cmp\tr8, r6\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"sub\t%[a], %[a], #32\\n\\t\"\n        \"mov\tr3, r1\\n\\t\"\n        \"sub\tr1, r1, #1\\n\\t\"\n        \"mvn\tr1, r1\\n\\t\"\n        \"ldr\tr4, [%[a],#32]\\n\\t\"\n        \"ldr\tr5, [%[a],#36]\\n\\t\"\n        \"ldr\tr6, [%[a],#40]\\n\\t\"\n        \"ldr\tr7, [%[a],#44]\\n\\t\"\n        \"subs\tr4, r4, r1\\n\\t\"\n        \"sbcs\tr5, r5, r1\\n\\t\"\n        \"sbcs\tr6, r6, r1\\n\\t\"\n        \"sbcs\tr7, r7, r2\\n\\t\"\n        \"str\tr4, [%[a],#0]\\n\\t\"\n        \"str\tr5, [%[a],#4]\\n\\t\"\n        \"str\tr6, [%[a],#8]\\n\\t\"\n        \"str\tr7, [%[a],#12]\\n\\t\"\n        \"ldr\tr4, [%[a],#48]\\n\\t\"\n        \"ldr\tr5, [%[a],#52]\\n\\t\"\n        \"ldr\tr6, [%[a],#56]\\n\\t\"\n        \"ldr\tr7, [%[a],#60]\\n\\t\"\n        \"sbcs\tr4, r4, r2\\n\\t\"\n        \"sbcs\tr5, r5, r2\\n\\t\"\n        \"sbcs\tr6, r6, r3\\n\\t\"\n        \"sbc\tr7, r7, r1\\n\\t\"\n        \"str\tr4, [%[a],#16]\\n\\t\"\n        \"str\tr5, [%[a],#20]\\n\\t\"\n        \"str\tr6, [%[a],#24]\\n\\t\"\n        \"str\tr7, [%[a],#28]\\n\\t\"\n        : [a] \"+r\" (a)\n        :\n        : \"memory\", \"r1\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n\n\n    (void)m;\n    (void)mp;\n}\n\n/* Reduce the number back to 256 bits using Montgomery reduction.\n *\n * a   A single precision number to reduce in place.\n * m   The single precision number representing the modulus.\n * mp  The digit representing the negative inverse of m mod 2^n.\n */\nSP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_digit ca = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr8, %[mp]\\n\\t\"\n        \"mov\tr12, %[m]\\n\\t\"\n        \"mov\tr9, %[a]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"add\tr11, r9, #32\\n\\t\"\n        \"\\n1:\\n\\t\"\n        /* mu = a[i] * mp */\n        \"mov\t%[mp], r8\\n\\t\"\n        \"ldr\t%[a], [r9]\\n\\t\"\n        \"mul\t%[mp], %[mp], %[a]\\n\\t\"\n        \"mov\t%[m], r12\\n\\t\"\n        \"mov\tr10, r9\\n\\t\"\n        \"add\tr14, r9, #24\\n\\t\"\n        \"\\n2:\\n\\t\"\n        /* a[i+j] += m[j] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr4, r4, %[a]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr4, [r10], #4\\n\\t\"\n        /* a[i+j+1] += m[j+1] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr4, r4, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr5, r5, %[a]\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [r10], #4\\n\\t\"\n        \"cmp\tr10, r14\\n\\t\"\n        \"blt\t2b\\n\\t\"\n        /* a[i+6] += m[6] * mu */\n        \"ldr\t%[a], [r10]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* Multiply m[j] and mu - Start */\n        \"ldr\tr7, [%[m]], #4\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\t%[a], %[a], r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* Multiply m[j] and mu - Done */\n        \"adds\tr4, r4, %[a]\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr4, [r10], #4\\n\\t\"\n        /* a[i+7] += m[7] * mu */\n        \"mov\tr4, %[ca]\\n\\t\"\n        \"mov\t%[ca], #0\\n\\t\"\n        /* Multiply m[7] and mu - Start */\n        \"ldr\tr7, [%[m]]\\n\\t\"\n        \"umull\tr6, r7, %[mp], r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        /* Multiply m[7] and mu - Done */\n        \"ldr\tr6, [r10]\\n\\t\"\n        \"ldr\tr7, [r10, #4]\\n\\t\"\n        \"adds\tr6, r6, r5\\n\\t\"\n        \"adcs\tr7, r7, r4\\n\\t\"\n        \"adc\t%[ca], %[ca], #0\\n\\t\"\n        \"str\tr6, [r10]\\n\\t\"\n        \"str\tr7, [r10, #4]\\n\\t\"\n        /* Next word in a */\n        \"add\tr9, r9, #4\\n\\t\"\n        \"cmp\tr9, r11\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"mov\t%[a], r9\\n\\t\"\n        \"mov\t%[m], r12\\n\\t\"\n        : [ca] \"+r\" (ca), [a] \"+r\" (a)\n        : [m] \"r\" (m), [mp] \"r\" (mp)\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n\n    sp_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - ca);\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit tmp[8];\n\n    __asm__ __volatile__ (\n        /* A[0] * B[0] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr3, r4, r6, r7\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [%[tmp], #0]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[0] * B[1] */\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        /* A[1] * B[0] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[tmp], #4]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[0] * B[2] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[1] * B[1] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[2] * B[0] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [%[tmp], #8]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[0] * B[3] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[1] * B[2] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[2] * B[1] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[3] * B[0] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr3, [%[tmp], #12]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[0] * B[4] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[1] * B[3] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[2] * B[2] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[3] * B[1] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[4] * B[0] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[tmp], #16]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[0] * B[5] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[1] * B[4] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[2] * B[3] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[3] * B[2] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[4] * B[1] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[5] * B[0] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [%[tmp], #20]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[0] * B[6] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[1] * B[5] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[2] * B[4] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[3] * B[3] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[4] * B[2] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[5] * B[1] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[6] * B[0] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr3, [%[tmp], #24]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[0] * B[7] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[1] * B[6] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[2] * B[5] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[3] * B[4] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[4] * B[3] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[5] * B[2] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[6] * B[1] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[7] * B[0] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #0]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[tmp], #28]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[1] * B[7] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[2] * B[6] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[3] * B[5] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[4] * B[4] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[5] * B[3] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[6] * B[2] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[7] * B[1] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [%[r], #32]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[2] * B[7] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[3] * B[6] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[4] * B[5] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[5] * B[4] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[6] * B[3] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[7] * B[2] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[3] * B[7] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[4] * B[6] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[5] * B[5] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[6] * B[4] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[7] * B[3] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[4] * B[7] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[5] * B[6] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[6] * B[5] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[7] * B[4] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [%[r], #44]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[5] * B[7] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[6] * B[6] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[7] * B[5] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[6] * B[7] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        /* A[7] * B[6] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[7] * B[7] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr5, [%[r], #56]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        /* Transfer tmp to r */\n        \"ldr\tr3, [%[tmp], #0]\\n\\t\"\n        \"ldr\tr4, [%[tmp], #4]\\n\\t\"\n        \"ldr\tr5, [%[tmp], #8]\\n\\t\"\n        \"ldr\tr6, [%[tmp], #12]\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [%[tmp], #16]\\n\\t\"\n        \"ldr\tr4, [%[tmp], #20]\\n\\t\"\n        \"ldr\tr5, [%[tmp], #24]\\n\\t\"\n        \"ldr\tr6, [%[tmp], #28]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"str\tr5, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b), [tmp] \"r\" (tmp)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n}\n\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_256_mul_8(r, a, b);\n    sp_256_mont_reduce_8(r, m, mp);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_256_sqr_8(sp_digit* r, const sp_digit* a)\n{\n    sp_digit tmp[8];\n    __asm__ __volatile__ (\n        /* A[0] * A[0] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"umull\tr3, r4, r6, r6\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"str\tr3, [%[tmp], #0]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[0] * A[1] */\n        \"ldr\tr7, [%[a], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adc\tr5, r5, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[tmp], #4]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[0] * A[2] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[1] * A[1] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [%[tmp], #8]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[0] * A[3] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[1] * A[2] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[tmp], #12]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[0] * A[4] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #16]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[1] * A[3] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[2] * A[2] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[tmp], #16]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[0] * A[5] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[1] * A[4] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[2] * A[3] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[tmp], #20]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[0] * A[6] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[1] * A[5] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[2] * A[4] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[3] * A[3] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[tmp], #24]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[0] * A[7] */\n        \"ldr\tr6, [%[a], #0]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[1] * A[6] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[2] * A[5] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[3] * A[4] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[tmp], #28]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[1] * A[7] */\n        \"ldr\tr6, [%[a], #4]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[2] * A[6] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[3] * A[5] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[4] * A[4] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr5, r5, r8\\n\\t\"\n        \"adcs\tr3, r3, r9\\n\\t\"\n        \"adc\tr4, r4, r10\\n\\t\"\n        \"str\tr5, [%[r], #32]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[2] * A[7] */\n        \"ldr\tr6, [%[a], #8]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[3] * A[6] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[4] * A[5] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr3, r3, r8\\n\\t\"\n        \"adcs\tr4, r4, r9\\n\\t\"\n        \"adc\tr5, r5, r10\\n\\t\"\n        \"str\tr3, [%[r], #36]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[3] * A[7] */\n        \"ldr\tr6, [%[a], #12]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr8, r9, r6, r7\\n\\t\"\n        \"mov\tr10, #0\\n\\t\"\n        /* A[4] * A[6] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr8, r8, r6\\n\\t\"\n        \"adcs \tr9, r9, r7\\n\\t\"\n        \"adc\tr10, r10, #0\\n\\t\"\n        /* A[5] * A[5] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"adds\tr8, r8, r8\\n\\t\"\n        \"adcs\tr9, r9, r9\\n\\t\"\n        \"adc\tr10, r10, r10\\n\\t\"\n        \"adds\tr4, r4, r8\\n\\t\"\n        \"adcs\tr5, r5, r9\\n\\t\"\n        \"adc\tr3, r3, r10\\n\\t\"\n        \"str\tr4, [%[r], #40]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[4] * A[7] */\n        \"ldr\tr6, [%[a], #16]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        /* A[5] * A[6] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adcs \tr3, r3, r7\\n\\t\"\n        \"adc\tr4, r4, #0\\n\\t\"\n        \"str\tr5, [%[r], #44]\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[5] * A[7] */\n        \"ldr\tr6, [%[a], #20]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[6] * A[6] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        \"str\tr3, [%[r], #48]\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        /* A[6] * A[7] */\n        \"ldr\tr6, [%[a], #24]\\n\\t\"\n        \"ldr\tr7, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r7\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs \tr5, r5, r7\\n\\t\"\n        \"adc\tr3, r3, #0\\n\\t\"\n        \"str\tr4, [%[r], #52]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        /* A[7] * A[7] */\n        \"ldr\tr6, [%[a], #28]\\n\\t\"\n        \"umull\tr6, r7, r6, r6\\n\\t\"\n        \"adds\tr5, r5, r6\\n\\t\"\n        \"adc\tr3, r3, r7\\n\\t\"\n        \"str\tr5, [%[r], #56]\\n\\t\"\n        \"str\tr3, [%[r], #60]\\n\\t\"\n        /* Transfer tmp to r */\n        \"ldr\tr3, [%[tmp], #0]\\n\\t\"\n        \"ldr\tr4, [%[tmp], #4]\\n\\t\"\n        \"ldr\tr5, [%[tmp], #8]\\n\\t\"\n        \"ldr\tr6, [%[tmp], #12]\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [%[tmp], #16]\\n\\t\"\n        \"ldr\tr4, [%[tmp], #20]\\n\\t\"\n        \"ldr\tr5, [%[tmp], #24]\\n\\t\"\n        \"ldr\tr6, [%[tmp], #28]\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"str\tr5, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [tmp] \"r\" (tmp)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\"\n    );\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_256_sqr_8(r, a);\n    sp_256_mont_reduce_8(r, m, mp);\n}\n\n#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)\n/* Square the Montgomery form number a number of times. (r = a ^ n mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * n   Number of times to square.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_sqr_n_8(sp_digit* r, const sp_digit* a, int n,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_256_mont_sqr_8(r, a, m, mp);\n    for (; n > 1; n--) {\n        sp_256_mont_sqr_8(r, r, m, mp);\n    }\n}\n\n#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */\n#ifdef WOLFSSL_SP_SMALL\n/* Mod-2 for the P256 curve. */\nstatic const uint32_t p256_mod_2[8] = {\n    0xfffffffdU,0xffffffffU,0xffffffffU,0x00000000U,0x00000000U,0x00000000U,\n    0x00000001U,0xffffffffU\n};\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the modulus (prime) of the\n * P256 curve. (r = 1 / a mod m)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_8(sp_digit* r, const sp_digit* a, sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 8);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_8(t, t, p256_mod, p256_mp_mod);\n        if (p256_mod_2[i / 32] & ((sp_digit)1 << (i % 32)))\n            sp_256_mont_mul_8(t, t, a, p256_mod, p256_mp_mod);\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 8);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 8;\n    sp_digit* t3 = td + 4 * 8;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_8(t, a, p256_mod, p256_mp_mod);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_8(t, t, a, p256_mod, p256_mp_mod);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_8(t2, t, 2, p256_mod, p256_mp_mod);\n    /* t3= a^d = t2 * a */\n    sp_256_mont_mul_8(t3, t2, a, p256_mod, p256_mp_mod);\n    /* t = a^f = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^f0 = t ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_8(t2, t, 4, p256_mod, p256_mp_mod);\n    /* t3= a^fd = t2 * t3 */\n    sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ff = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_8(t2, t, 8, p256_mod, p256_mp_mod);\n    /* t3= a^fffd = t2 * t3 */\n    sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_8(t2, t, 16, p256_mod, p256_mp_mod);\n    /* t3= a^fffffffd = t2 * t3 */\n    sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff00000000 = t ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_8(t2, t, 32, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001 = t2 * a */\n    sp_256_mont_mul_8(t2, t2, a, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff000000010000000000000000000000000000000000000000\n     *   = t2 ^ 2 ^ 160 */\n    sp_256_mont_sqr_n_8(t2, t2, 160, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff\n     *   = t2 * t */\n    sp_256_mont_mul_8(t2, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000\n     *   = t2 ^ 2 ^ 32 */\n    sp_256_mont_sqr_n_8(t2, t2, 32, p256_mod, p256_mp_mod);\n    /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd\n     *   = t2 * t3 */\n    sp_256_mont_mul_8(r, t2, t3, p256_mod, p256_mp_mod);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Map the Montgomery form projective co-ordinate point to an affine point.\n *\n * r  Resulting affine co-ordinate point.\n * p  Montgomery form projective co-ordinate point.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_map_8(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*8;\n    int32_t n;\n\n    sp_256_mont_inv_8(t1, p->z, t + 2*8);\n\n    sp_256_mont_sqr_8(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_8(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    /* x /= z^2 */\n    sp_256_mont_mul_8(r->x, p->x, t2, p256_mod, p256_mp_mod);\n    XMEMSET(r->x + 8, 0, sizeof(r->x) / 2U);\n    sp_256_mont_reduce_8(r->x, p256_mod, p256_mp_mod);\n    /* Reduce x to less than modulus */\n    n = sp_256_cmp_8(r->x, p256_mod);\n    sp_256_cond_sub_8(r->x, r->x, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_8(r->x);\n\n    /* y /= z^3 */\n    sp_256_mont_mul_8(r->y, p->y, t1, p256_mod, p256_mp_mod);\n    XMEMSET(r->y + 8, 0, sizeof(r->y) / 2U);\n    sp_256_mont_reduce_8(r->y, p256_mod, p256_mp_mod);\n    /* Reduce y to less than modulus */\n    n = sp_256_cmp_8(r->y, p256_mod);\n    sp_256_cond_sub_8(r->y, r->y, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_8(r->y);\n\n    XMEMSET(r->z, 0, sizeof(r->z));\n    r->z[0] = 1;\n\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"add\tr6, r6, #32\\n\\t\"\n        \"sub\tr7, r7, #1\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"adds\t%[c], %[c], r7\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"adcs\tr4, r4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"add\t%[b], %[b], #4\\n\\t\"\n        \"add\t%[r], %[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#else\n/* Add b to a into r. (r = a + b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[a]!, {r4, r5}\\n\\t\"\n        \"ldm\t%[b]!, {r6, r7}\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"stm\t%[r]!, {r4, r5}\\n\\t\"\n        \"mov\t%[c], #0\\n\\t\"\n        \"adc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Add two Montgomery form numbers (r = a + b % m).\n *\n * r   Result of addition.\n * a   First number to add in Montogmery form.\n * b   Second number to add in Montogmery form.\n * m   Modulus (prime).\n */\nSP_NOINLINE static void sp_256_mont_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m)\n{\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"mov\tr3, #0\\n\\t\"\n        \"ldr\tr4, [%[a],#0]\\n\\t\"\n        \"ldr\tr5, [%[a],#4]\\n\\t\"\n        \"ldr\tr6, [%[b],#0]\\n\\t\"\n        \"ldr\tr7, [%[b],#4]\\n\\t\"\n        \"adds\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"ldr\tr4, [%[a],#8]\\n\\t\"\n        \"ldr\tr5, [%[a],#12]\\n\\t\"\n        \"ldr\tr6, [%[b],#8]\\n\\t\"\n        \"ldr\tr7, [%[b],#12]\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r],#8]\\n\\t\"\n        \"str\tr5, [%[r],#12]\\n\\t\"\n        \"ldr\tr4, [%[a],#16]\\n\\t\"\n        \"ldr\tr5, [%[a],#20]\\n\\t\"\n        \"ldr\tr6, [%[b],#16]\\n\\t\"\n        \"ldr\tr7, [%[b],#20]\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"mov\tr8, r4\\n\\t\"\n        \"mov\tr9, r5\\n\\t\"\n        \"ldr\tr4, [%[a],#24]\\n\\t\"\n        \"ldr\tr5, [%[a],#28]\\n\\t\"\n        \"ldr\tr6, [%[b],#24]\\n\\t\"\n        \"ldr\tr7, [%[b],#28]\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r7\\n\\t\"\n        \"mov\tr10, r4\\n\\t\"\n        \"mov\tr11, r5\\n\\t\"\n        \"adc\tr3, r3, r3\\n\\t\"\n        \"mov\tr6, r3\\n\\t\"\n        \"sub\tr3, r3, #1\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"ldr\tr4, [%[r],#0]\\n\\t\"\n        \"ldr\tr5, [%[r],#4]\\n\\t\"\n        \"subs\tr4, r4, r3\\n\\t\"\n        \"sbcs\tr5, r5, r3\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"ldr\tr4, [%[r],#8]\\n\\t\"\n        \"ldr\tr5, [%[r],#12]\\n\\t\"\n        \"sbcs\tr4, r4, r3\\n\\t\"\n        \"sbcs\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r],#8]\\n\\t\"\n        \"str\tr5, [%[r],#12]\\n\\t\"\n        \"mov\tr4, r8\\n\\t\"\n        \"mov\tr5, r9\\n\\t\"\n        \"sbcs\tr4, r4, r7\\n\\t\"\n        \"sbcs\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r],#16]\\n\\t\"\n        \"str\tr5, [%[r],#20]\\n\\t\"\n        \"mov\tr4, r10\\n\\t\"\n        \"mov\tr5, r11\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"sbc\tr5, r5, r3\\n\\t\"\n        \"str\tr4, [%[r],#24]\\n\\t\"\n        \"str\tr5, [%[r],#28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n/* Double a Montgomery form number (r = a + a % m).\n *\n * r   Result of doubling.\n * a   Number to double in Montogmery form.\n * m   Modulus (prime).\n */\nSP_NOINLINE static void sp_256_mont_dbl_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"ldr\tr4, [%[a],#0]\\n\\t\"\n        \"ldr\tr5, [%[a],#4]\\n\\t\"\n        \"ldr\tr6, [%[a],#8]\\n\\t\"\n        \"ldr\tr7, [%[a],#12]\\n\\t\"\n        \"adds\tr4, r4, r4\\n\\t\"\n        \"adcs\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adcs\tr7, r7, r7\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"str\tr6, [%[r],#8]\\n\\t\"\n        \"str\tr7, [%[r],#12]\\n\\t\"\n        \"ldr\tr4, [%[a],#16]\\n\\t\"\n        \"ldr\tr5, [%[a],#20]\\n\\t\"\n        \"ldr\tr6, [%[a],#24]\\n\\t\"\n        \"ldr\tr7, [%[a],#28]\\n\\t\"\n        \"adcs\tr4, r4, r4\\n\\t\"\n        \"adcs\tr5, r5, r5\\n\\t\"\n        \"adcs\tr6, r6, r6\\n\\t\"\n        \"adcs\tr7, r7, r7\\n\\t\"\n        \"mov\tr8, r4\\n\\t\"\n        \"mov\tr9, r5\\n\\t\"\n        \"mov\tr10, r6\\n\\t\"\n        \"mov\tr11, r7\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"adc\tr3, r3, r3\\n\\t\"\n        \"mov\tr2, r3\\n\\t\"\n        \"sub\tr3, r3, #1\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"ldr\tr4, [%[r],#0]\\n\\t\"\n        \"ldr\tr5, [%[r],#4]\\n\\t\"\n        \"ldr\tr6, [%[r],#8]\\n\\t\"\n        \"subs\tr4, r4, r3\\n\\t\"\n        \"sbcs\tr5, r5, r3\\n\\t\"\n        \"sbcs\tr6, r6, r3\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"str\tr6, [%[r],#8]\\n\\t\"\n        \"ldr\tr4, [%[r],#12]\\n\\t\"\n        \"mov\tr5, r8\\n\\t\"\n        \"mov\tr6, r9\\n\\t\"\n        \"sbcs\tr4, r4, r7\\n\\t\"\n        \"sbcs\tr5, r5, r7\\n\\t\"\n        \"sbcs\tr6, r6, r7\\n\\t\"\n        \"str\tr4, [%[r],#12]\\n\\t\"\n        \"str\tr5, [%[r],#16]\\n\\t\"\n        \"str\tr6, [%[r],#20]\\n\\t\"\n        \"mov\tr4, r10\\n\\t\"\n        \"mov\tr5, r11\\n\\t\"\n        \"sbcs\tr4, r4, r2\\n\\t\"\n        \"sbc\tr5, r5, r3\\n\\t\"\n        \"str\tr4, [%[r],#24]\\n\\t\"\n        \"str\tr5, [%[r],#28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r3\", \"r2\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n/* Triple a Montgomery form number (r = a + a + a % m).\n *\n * r   Result of Tripling.\n * a   Number to triple in Montogmery form.\n * m   Modulus (prime).\n */\nSP_NOINLINE static void sp_256_mont_tpl_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"ldr\tr6, [%[a],#0]\\n\\t\"\n        \"ldr\tr7, [%[a],#4]\\n\\t\"\n        \"ldr\tr4, [%[a],#8]\\n\\t\"\n        \"ldr\tr5, [%[a],#12]\\n\\t\"\n        \"adds\tr6, r6, r6\\n\\t\"\n        \"adcs\tr7, r7, r7\\n\\t\"\n        \"adcs\tr4, r4, r4\\n\\t\"\n        \"adcs\tr5, r5, r5\\n\\t\"\n        \"mov\tr8, r4\\n\\t\"\n        \"mov\tr9, r5\\n\\t\"\n        \"ldr\tr2, [%[a],#16]\\n\\t\"\n        \"ldr\tr3, [%[a],#20]\\n\\t\"\n        \"ldr\tr4, [%[a],#24]\\n\\t\"\n        \"ldr\tr5, [%[a],#28]\\n\\t\"\n        \"adcs\tr2, r2, r2\\n\\t\"\n        \"adcs\tr3, r3, r3\\n\\t\"\n        \"adcs\tr4, r4, r4\\n\\t\"\n        \"adcs\tr5, r5, r5\\n\\t\"\n        \"mov\tr10, r2\\n\\t\"\n        \"mov\tr11, r3\\n\\t\"\n        \"mov\tr12, r4\\n\\t\"\n        \"mov\tr14, r5\\n\\t\"\n        \"mov\tr3, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"adc\tr3, r3, r3\\n\\t\"\n        \"mov\tr4, r3\\n\\t\"\n        \"sub\tr3, r3, #1\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"subs\tr6, r6, r3\\n\\t\"\n        \"sbcs\tr7, r7, r3\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sbcs\tr2, r2, r3\\n\\t\"\n        \"mov\tr8, r2\\n\\t\"\n        \"mov\tr2, r9\\n\\t\"\n        \"sbcs\tr2, r2, r5\\n\\t\"\n        \"mov\tr9, r2\\n\\t\"\n        \"mov\tr2, r10\\n\\t\"\n        \"sbcs\tr2, r2, r5\\n\\t\"\n        \"mov\tr10, r2\\n\\t\"\n        \"mov\tr2, r11\\n\\t\"\n        \"sbcs\tr2, r2, r5\\n\\t\"\n        \"mov\tr11, r2\\n\\t\"\n        \"mov\tr2, r12\\n\\t\"\n        \"sbcs\tr2, r2, r4\\n\\t\"\n        \"mov\tr12, r2\\n\\t\"\n        \"mov\tr2, r14\\n\\t\"\n        \"sbc\tr2, r2, r3\\n\\t\"\n        \"mov\tr14, r2\\n\\t\"\n        \"ldr\tr2, [%[a],#0]\\n\\t\"\n        \"ldr\tr3, [%[a],#4]\\n\\t\"\n        \"adds\tr6, r6, r2\\n\\t\"\n        \"adcs\tr7, r7, r3\\n\\t\"\n        \"ldr\tr2, [%[a],#8]\\n\\t\"\n        \"ldr\tr3, [%[a],#12]\\n\\t\"\n        \"mov\tr4, r8\\n\\t\"\n        \"mov\tr5, r9\\n\\t\"\n        \"adcs\tr2, r2, r4\\n\\t\"\n        \"adcs\tr3, r3, r5\\n\\t\"\n        \"mov   r8, r2\\n\\t\"\n        \"mov   r9, r3\\n\\t\"\n        \"ldr\tr2, [%[a],#16]\\n\\t\"\n        \"ldr\tr3, [%[a],#20]\\n\\t\"\n        \"mov\tr4, r10\\n\\t\"\n        \"mov\tr5, r11\\n\\t\"\n        \"adcs\tr2, r2, r4\\n\\t\"\n        \"adcs\tr3, r3, r5\\n\\t\"\n        \"mov\tr10, r2\\n\\t\"\n        \"mov\tr11, r3\\n\\t\"\n        \"ldr\tr2, [%[a],#24]\\n\\t\"\n        \"ldr\tr3, [%[a],#28]\\n\\t\"\n        \"mov\tr4, r12\\n\\t\"\n        \"mov\tr5, r14\\n\\t\"\n        \"adcs\tr2, r2, r4\\n\\t\"\n        \"adcs\tr3, r3, r5\\n\\t\"\n        \"mov\tr12, r2\\n\\t\"\n        \"mov\tr14, r3\\n\\t\"\n        \"mov   r3, #0\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"adc\tr3, r3, r3\\n\\t\"\n        \"mov\tr4, r3\\n\\t\"\n        \"sub\tr3, r3, #1\\n\\t\"\n        \"mvn\tr3, r3\\n\\t\"\n        \"subs\tr6, r6, r3\\n\\t\"\n        \"str\tr6, [%[r],#0]\\n\\t\"\n        \"sbcs\tr7, r7, r3\\n\\t\"\n        \"str\tr7, [%[r],#4]\\n\\t\"\n        \"mov\tr2, r8\\n\\t\"\n        \"sbcs\tr2, r2, r3\\n\\t\"\n        \"str\tr2, [%[r],#8]\\n\\t\"\n        \"mov\tr2, r9\\n\\t\"\n        \"sbcs\tr2, r2, r5\\n\\t\"\n        \"str\tr2, [%[r],#12]\\n\\t\"\n        \"mov\tr2, r10\\n\\t\"\n        \"sbcs\tr2, r2, r5\\n\\t\"\n        \"str\tr2, [%[r],#16]\\n\\t\"\n        \"mov\tr2, r11\\n\\t\"\n        \"sbcs\tr2, r2, r5\\n\\t\"\n        \"str\tr2, [%[r],#20]\\n\\t\"\n        \"mov\tr2, r12\\n\\t\"\n        \"sbcs\tr2, r2, r4\\n\\t\"\n        \"str\tr2, [%[r],#24]\\n\\t\"\n        \"mov\tr2, r14\\n\\t\"\n        \"sbc\tr2, r2, r3\\n\\t\"\n        \"str\tr2, [%[r],#28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a)\n        : \"memory\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r14\"\n    );\n}\n\n/* Subtract two Montgomery form numbers (r = a - b % m).\n *\n * r   Result of subtration.\n * a   Number to subtract from in Montogmery form.\n * b   Number to subtract with in Montogmery form.\n * m   Modulus (prime).\n */\nSP_NOINLINE static void sp_256_mont_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m)\n{\n    (void)m;\n\n    __asm__ __volatile__ (\n        \"ldr\tr4, [%[a],#0]\\n\\t\"\n        \"ldr\tr5, [%[a],#4]\\n\\t\"\n        \"ldr\tr6, [%[b],#0]\\n\\t\"\n        \"ldr\tr7, [%[b],#4]\\n\\t\"\n        \"subs\tr4, r4, r6\\n\\t\"\n        \"sbcs\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"ldr\tr4, [%[a],#8]\\n\\t\"\n        \"ldr\tr5, [%[a],#12]\\n\\t\"\n        \"ldr\tr6, [%[b],#8]\\n\\t\"\n        \"ldr\tr7, [%[b],#12]\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"sbcs\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r],#8]\\n\\t\"\n        \"str\tr5, [%[r],#12]\\n\\t\"\n        \"ldr\tr4, [%[a],#16]\\n\\t\"\n        \"ldr\tr5, [%[a],#20]\\n\\t\"\n        \"ldr\tr6, [%[b],#16]\\n\\t\"\n        \"ldr\tr7, [%[b],#20]\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"sbcs\tr5, r5, r7\\n\\t\"\n        \"mov\tr8, r4\\n\\t\"\n        \"mov\tr9, r5\\n\\t\"\n        \"ldr\tr4, [%[a],#24]\\n\\t\"\n        \"ldr\tr5, [%[a],#28]\\n\\t\"\n        \"ldr\tr6, [%[b],#24]\\n\\t\"\n        \"ldr\tr7, [%[b],#28]\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"sbcs\tr5, r5, r7\\n\\t\"\n        \"mov\tr10, r4\\n\\t\"\n        \"mov\tr11, r5\\n\\t\"\n        \"sbc   r3, r3, r3\\n\\t\"\n        \"lsr   r7, r3, #31\\n\\t\"\n        \"mov   r6, #0\\n\\t\"\n        \"ldr\tr4, [%[r],#0]\\n\\t\"\n        \"ldr\tr5, [%[r],#4]\\n\\t\"\n        \"adds\tr4, r4, r3\\n\\t\"\n        \"adcs\tr5, r5, r3\\n\\t\"\n        \"str\tr4, [%[r],#0]\\n\\t\"\n        \"str\tr5, [%[r],#4]\\n\\t\"\n        \"ldr\tr4, [%[r],#8]\\n\\t\"\n        \"ldr\tr5, [%[r],#12]\\n\\t\"\n        \"adcs\tr4, r4, r3\\n\\t\"\n        \"adcs\tr5, r5, r6\\n\\t\"\n        \"str\tr4, [%[r],#8]\\n\\t\"\n        \"str\tr5, [%[r],#12]\\n\\t\"\n        \"mov\tr4, r8\\n\\t\"\n        \"mov\tr5, r9\\n\\t\"\n        \"adcs\tr4, r4, r6\\n\\t\"\n        \"adcs\tr5, r5, r6\\n\\t\"\n        \"str\tr4, [%[r],#16]\\n\\t\"\n        \"str\tr5, [%[r],#20]\\n\\t\"\n        \"mov\tr4, r10\\n\\t\"\n        \"mov\tr5, r11\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, r3\\n\\t\"\n        \"str\tr4, [%[r],#24]\\n\\t\"\n        \"str\tr5, [%[r],#28]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\", \"r11\"\n    );\n}\n\n/* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m)\n *\n * r  Result of division by 2.\n * a  Number to divide.\n * m  Modulus (prime).\n */\nSP_NOINLINE static void sp_256_div2_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    __asm__ __volatile__ (\n        \"ldr\tr7, [%[a], #0]\\n\\t\"\n        \"lsl\tr7, r7, #31\\n\\t\"\n        \"lsr\tr7, r7, #31\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"sub\tr5, r5, r7\\n\\t\"\n        \"mov\tr7, #0\\n\\t\"\n        \"lsl\tr6, r5, #31\\n\\t\"\n        \"lsr\tr6, r6, #31\\n\\t\"\n        \"ldr\tr3, [%[a], #0]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"adds\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r5\\n\\t\"\n        \"str\tr3, [%[r], #0]\\n\\t\"\n        \"str\tr4, [%[r], #4]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"adcs\tr3, r3, r5\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"str\tr3, [%[r], #8]\\n\\t\"\n        \"str\tr4, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"adcs\tr3, r3, r7\\n\\t\"\n        \"adcs\tr4, r4, r7\\n\\t\"\n        \"str\tr3, [%[r], #16]\\n\\t\"\n        \"str\tr4, [%[r], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #24]\\n\\t\"\n        \"ldr\tr4, [%[a], #28]\\n\\t\"\n        \"adcs\tr3, r3, r6\\n\\t\"\n        \"adcs\tr4, r4, r5\\n\\t\"\n        \"adc\tr7, r7, r7\\n\\t\"\n        \"lsl\tr7, r7, #31\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, #31\\n\\t\"\n        \"lsr\tr6, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, #31\\n\\t\"\n        \"orr\tr5, r5, r4\\n\\t\"\n        \"orr\tr6, r6, r7\\n\\t\"\n        \"mov\tr7, r3\\n\\t\"\n        \"str\tr5, [%[r], #24]\\n\\t\"\n        \"str\tr6, [%[r], #28]\\n\\t\"\n        \"ldr\tr3, [%[a], #16]\\n\\t\"\n        \"ldr\tr4, [%[a], #20]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, #31\\n\\t\"\n        \"lsr\tr6, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, #31\\n\\t\"\n        \"orr\tr5, r5, r4\\n\\t\"\n        \"orr\tr6, r6, r7\\n\\t\"\n        \"mov\tr7, r3\\n\\t\"\n        \"str\tr5, [%[r], #16]\\n\\t\"\n        \"str\tr6, [%[r], #20]\\n\\t\"\n        \"ldr\tr3, [%[a], #8]\\n\\t\"\n        \"ldr\tr4, [%[a], #12]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsl\tr3, r3, #31\\n\\t\"\n        \"lsr\tr6, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, #31\\n\\t\"\n        \"orr\tr5, r5, r4\\n\\t\"\n        \"orr\tr6, r6, r7\\n\\t\"\n        \"mov\tr7, r3\\n\\t\"\n        \"str\tr5, [%[r], #8]\\n\\t\"\n        \"str\tr6, [%[r], #12]\\n\\t\"\n        \"ldr\tr3, [%[r], #0]\\n\\t\"\n        \"ldr\tr4, [%[r], #4]\\n\\t\"\n        \"lsr\tr5, r3, #1\\n\\t\"\n        \"lsr\tr6, r4, #1\\n\\t\"\n        \"lsl\tr4, r4, #31\\n\\t\"\n        \"orr\tr5, r5, r4\\n\\t\"\n        \"orr\tr6, r6, r7\\n\\t\"\n        \"str\tr5, [%[r], #0]\\n\\t\"\n        \"str\tr6, [%[r], #4]\\n\\t\"\n        :\n        : [r] \"r\" (r), [a] \"r\" (a), [m] \"r\" (m)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n}\n\n/* Double the Montgomery form projective point p.\n *\n * r  Result of doubling point.\n * p  Point to double.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_8(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*8;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* When infinity don't double point passed in - constant time. */\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    /* Put point to double into result - good for infinty. */\n    if (r != p) {\n        for (i=0; i<8; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<8; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<8; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* T1 = Z * Z */\n    sp_256_mont_sqr_8(t1, z, p256_mod, p256_mp_mod);\n    /* Z = Y * Z */\n    sp_256_mont_mul_8(z, y, z, p256_mod, p256_mp_mod);\n    /* Z = 2Z */\n    sp_256_mont_dbl_8(z, z, p256_mod);\n    /* T2 = X - T1 */\n    sp_256_mont_sub_8(t2, x, t1, p256_mod);\n    /* T1 = X + T1 */\n    sp_256_mont_add_8(t1, x, t1, p256_mod);\n    /* T2 = T1 * T2 */\n    sp_256_mont_mul_8(t2, t1, t2, p256_mod, p256_mp_mod);\n    /* T1 = 3T2 */\n    sp_256_mont_tpl_8(t1, t2, p256_mod);\n    /* Y = 2Y */\n    sp_256_mont_dbl_8(y, y, p256_mod);\n    /* Y = Y * Y */\n    sp_256_mont_sqr_8(y, y, p256_mod, p256_mp_mod);\n    /* T2 = Y * Y */\n    sp_256_mont_sqr_8(t2, y, p256_mod, p256_mp_mod);\n    /* T2 = T2/2 */\n    sp_256_div2_8(t2, t2, p256_mod);\n    /* Y = Y * X */\n    sp_256_mont_mul_8(y, y, x, p256_mod, p256_mp_mod);\n    /* X = T1 * T1 */\n    sp_256_mont_mul_8(x, t1, t1, p256_mod, p256_mp_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_8(x, x, y, p256_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_8(x, x, y, p256_mod);\n    /* Y = Y - X */\n    sp_256_mont_sub_8(y, y, x, p256_mod);\n    /* Y = Y * T1 */\n    sp_256_mont_mul_8(y, y, t1, p256_mod, p256_mp_mod);\n    /* Y = Y - T2 */\n    sp_256_mont_sub_8(y, y, t2, p256_mod);\n\n}\n\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"mov\tr6, %[a]\\n\\t\"\n        \"add\tr6, r6, #32\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"subs\tr5, r5, %[c]\\n\\t\"\n        \"ldr\tr4, [%[a]]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"sbcs\tr4, r4, r5\\n\\t\"\n        \"str\tr4, [%[r]]\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        \"add\t%[a], %[a], #4\\n\\t\"\n        \"add\t%[b], %[b], #4\\n\\t\"\n        \"add\t%[r], %[r], #4\\n\\t\"\n        \"cmp\t%[a], r6\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n#else\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldr\tr4, [%[a], #0]\\n\\t\"\n        \"ldr\tr5, [%[a], #4]\\n\\t\"\n        \"ldr\tr6, [%[b], #0]\\n\\t\"\n        \"ldr\tr7, [%[b], #4]\\n\\t\"\n        \"subs\tr4, r4, r6\\n\\t\"\n        \"sbcs\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r], #0]\\n\\t\"\n        \"str\tr5, [%[r], #4]\\n\\t\"\n        \"ldr\tr4, [%[a], #8]\\n\\t\"\n        \"ldr\tr5, [%[a], #12]\\n\\t\"\n        \"ldr\tr6, [%[b], #8]\\n\\t\"\n        \"ldr\tr7, [%[b], #12]\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"sbcs\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r], #8]\\n\\t\"\n        \"str\tr5, [%[r], #12]\\n\\t\"\n        \"ldr\tr4, [%[a], #16]\\n\\t\"\n        \"ldr\tr5, [%[a], #20]\\n\\t\"\n        \"ldr\tr6, [%[b], #16]\\n\\t\"\n        \"ldr\tr7, [%[b], #20]\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"sbcs\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r], #16]\\n\\t\"\n        \"str\tr5, [%[r], #20]\\n\\t\"\n        \"ldr\tr4, [%[a], #24]\\n\\t\"\n        \"ldr\tr5, [%[a], #28]\\n\\t\"\n        \"ldr\tr6, [%[b], #24]\\n\\t\"\n        \"ldr\tr7, [%[b], #28]\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"sbcs\tr5, r5, r7\\n\\t\"\n        \"str\tr4, [%[r], #24]\\n\\t\"\n        \"str\tr5, [%[r], #28]\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [r] \"+r\" (r), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Compare two numbers to determine if they are equal.\n * Constant time implementation.\n *\n * a  First number to compare.\n * b  Second number to compare.\n * returns 1 when equal and 0 otherwise.\n */\nstatic int sp_256_cmp_equal_8(const sp_digit* a, const sp_digit* b)\n{\n    return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) |\n            (a[4] ^ b[4]) | (a[5] ^ b[5]) | (a[6] ^ b[6]) | (a[7] ^ b[7])) == 0;\n}\n\n/* Add two Montgomery form projective points.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_point* q,\n        sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*8;\n    sp_digit* t3 = t + 4*8;\n    sp_digit* t4 = t + 6*8;\n    sp_digit* t5 = t + 8*8;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Ensure only the first point is the same as the result. */\n    if (q == r) {\n        const sp_point* a = p;\n        p = q;\n        q = a;\n    }\n\n    /* Check double */\n    (void)sp_256_sub_8(t1, p256_mod, q->y);\n    sp_256_norm_8(t1);\n    if ((sp_256_cmp_equal_8(p->x, q->x) & sp_256_cmp_equal_8(p->z, q->z) &\n        (sp_256_cmp_equal_8(p->y, q->y) | sp_256_cmp_equal_8(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_8(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<8; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<8; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<8; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U1 = X1*Z2^2 */\n        sp_256_mont_sqr_8(t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t3, t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t1, t1, x, p256_mod, p256_mp_mod);\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_8(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S1 = Y1*Z2^3 */\n        sp_256_mont_mul_8(t3, t3, y, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_8(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - U1 */\n        sp_256_mont_sub_8(t2, t2, t1, p256_mod);\n        /* R = S2 - S1 */\n        sp_256_mont_sub_8(t4, t4, t3, p256_mod);\n        /* Z3 = H*Z1*Z2 */\n        sp_256_mont_mul_8(z, z, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*U1*H^2 */\n        sp_256_mont_sqr_8(x, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_8(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(y, t1, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(x, x, t5, p256_mod);\n        sp_256_mont_dbl_8(t1, y, p256_mod);\n        sp_256_mont_sub_8(x, x, t1, p256_mod);\n        /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */\n        sp_256_mont_sub_8(y, y, x, p256_mod);\n        sp_256_mont_mul_8(y, y, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t5, t5, t3, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(y, y, t5, p256_mod);\n    }\n}\n\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td[16];\n    sp_point rtd;\n    sp_digit tmpd[2 * 8 * 5];\n#endif\n    sp_point* t;\n    sp_point* rt;\n    sp_digit* tmp;\n    sp_digit n;\n    int i;\n    int c, y;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_point*)XMALLOC(sizeof(sp_point) * 16, heap, DYNAMIC_TYPE_ECC);\n    if (t == NULL)\n        err = MEMORY_E;\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap,\n                             DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n#else\n    t = td;\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        /* t[0] = {0, 0, 1} * norm */\n        XMEMSET(&t[0], 0, sizeof(t[0]));\n        t[0].infinity = 1;\n        /* t[1] = {g->x, g->y, g->z} * norm */\n        (void)sp_256_mod_mul_norm_8(t[1].x, g->x, p256_mod);\n        (void)sp_256_mod_mul_norm_8(t[1].y, g->y, p256_mod);\n        (void)sp_256_mod_mul_norm_8(t[1].z, g->z, p256_mod);\n        t[1].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[ 2], &t[ 1], tmp);\n        t[ 2].infinity = 0;\n        sp_256_proj_point_add_8(&t[ 3], &t[ 2], &t[ 1], tmp);\n        t[ 3].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[ 4], &t[ 2], tmp);\n        t[ 4].infinity = 0;\n        sp_256_proj_point_add_8(&t[ 5], &t[ 3], &t[ 2], tmp);\n        t[ 5].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[ 6], &t[ 3], tmp);\n        t[ 6].infinity = 0;\n        sp_256_proj_point_add_8(&t[ 7], &t[ 4], &t[ 3], tmp);\n        t[ 7].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[ 8], &t[ 4], tmp);\n        t[ 8].infinity = 0;\n        sp_256_proj_point_add_8(&t[ 9], &t[ 5], &t[ 4], tmp);\n        t[ 9].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[10], &t[ 5], tmp);\n        t[10].infinity = 0;\n        sp_256_proj_point_add_8(&t[11], &t[ 6], &t[ 5], tmp);\n        t[11].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[12], &t[ 6], tmp);\n        t[12].infinity = 0;\n        sp_256_proj_point_add_8(&t[13], &t[ 7], &t[ 6], tmp);\n        t[13].infinity = 0;\n        sp_256_proj_point_dbl_8(&t[14], &t[ 7], tmp);\n        t[14].infinity = 0;\n        sp_256_proj_point_add_8(&t[15], &t[ 8], &t[ 7], tmp);\n        t[15].infinity = 0;\n\n        i = 6;\n        n = k[i+1] << 0;\n        c = 28;\n        y = n >> 28;\n        XMEMCPY(rt, &t[y], sizeof(sp_point));\n        n <<= 4;\n        for (; i>=0 || c>=4; ) {\n            if (c < 4) {\n                n |= k[i--] << (0 - c);\n                c += 32;\n            }\n            y = (n >> 28) & 0xf;\n            n <<= 4;\n            c -= 4;\n\n            sp_256_proj_point_dbl_8(rt, rt, tmp);\n            sp_256_proj_point_dbl_8(rt, rt, tmp);\n            sp_256_proj_point_dbl_8(rt, rt, tmp);\n            sp_256_proj_point_dbl_8(rt, rt, tmp);\n\n            sp_256_proj_point_add_8(rt, rt, &t[y], tmp);\n        }\n\n        if (map != 0) {\n            sp_256_map_8(r, rt, tmp);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 8 * 5);\n        XFREE(tmp, heap, DYNAMIC_TYPE_ECC);\n    }\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_point) * 16);\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    ForceZero(tmpd, sizeof(tmpd));\n    ForceZero(td, sizeof(td));\n#endif\n    sp_ecc_point_free(rt, 1, heap);\n\n    return err;\n}\n\n/* A table entry for pre-computed points. */\ntypedef struct sp_table_entry {\n    sp_digit x[8];\n    sp_digit y[8];\n} sp_table_entry;\n\n#ifdef FP_ECC\n/* Double the Montgomery form projective point p a number of times.\n *\n * r  Result of repeated doubling of point.\n * p  Point to double.\n * n  Number of times to double\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_n_8(sp_point* r, const sp_point* p, int n,\n        sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* w = t;\n    sp_digit* a = t + 2*8;\n    sp_digit* b = t + 4*8;\n    sp_digit* t1 = t + 6*8;\n    sp_digit* t2 = t + 8*8;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    if (r != p) {\n        for (i=0; i<8; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<8; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<8; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* Y = 2*Y */\n    sp_256_mont_dbl_8(y, y, p256_mod);\n    /* W = Z^4 */\n    sp_256_mont_sqr_8(w, z, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_8(w, w, p256_mod, p256_mp_mod);\n    while (n-- > 0) {\n        /* A = 3*(X^2 - W) */\n        sp_256_mont_sqr_8(t1, x, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(t1, t1, w, p256_mod);\n        sp_256_mont_tpl_8(a, t1, p256_mod);\n        /* B = X*Y^2 */\n        sp_256_mont_sqr_8(t2, y, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(b, t2, x, p256_mod, p256_mp_mod);\n        /* X = A^2 - 2B */\n        sp_256_mont_sqr_8(x, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_8(t1, b, p256_mod);\n        sp_256_mont_sub_8(x, x, t1, p256_mod);\n        /* Z = Z*Y */\n        sp_256_mont_mul_8(z, z, y, p256_mod, p256_mp_mod);\n        /* t2 = Y^4 */\n        sp_256_mont_sqr_8(t2, t2, p256_mod, p256_mp_mod);\n        if (n != 0) {\n            /* W = W*Y^4 */\n            sp_256_mont_mul_8(w, w, t2, p256_mod, p256_mp_mod);\n        }\n        /* y = 2*A*(B - X) - Y^4 */\n        sp_256_mont_sub_8(y, b, x, p256_mod);\n        sp_256_mont_mul_8(y, y, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_8(y, y, p256_mod);\n        sp_256_mont_sub_8(y, y, t2, p256_mod);\n    }\n    /* Y = Y/2 */\n    sp_256_div2_8(y, y, p256_mod);\n}\n\n/* Convert the projective point to affine.\n * Ordinates are in Montgomery form.\n *\n * a  Point to convert.\n * t  Temprorary data.\n */\nstatic void sp_256_proj_to_affine_8(sp_point* a, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2 * 8;\n    sp_digit* tmp = t + 4 * 8;\n\n    sp_256_mont_inv_8(t1, a->z, tmp);\n\n    sp_256_mont_sqr_8(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_8(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    sp_256_mont_mul_8(a->x, a->x, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_8(a->y, a->y, t1, p256_mod, p256_mp_mod);\n    XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod));\n}\n\n#endif /* FP_ECC */\n/* Add two Montgomery form projective points. The second point has a q value of\n * one.\n * Only the first point can be the same pointer as the result point.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_qz1_8(sp_point* r, const sp_point* p,\n        const sp_point* q, sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*8;\n    sp_digit* t3 = t + 4*8;\n    sp_digit* t4 = t + 6*8;\n    sp_digit* t5 = t + 8*8;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Check double */\n    (void)sp_256_sub_8(t1, p256_mod, q->y);\n    sp_256_norm_8(t1);\n    if ((sp_256_cmp_equal_8(p->x, q->x) & sp_256_cmp_equal_8(p->z, q->z) &\n        (sp_256_cmp_equal_8(p->y, q->y) | sp_256_cmp_equal_8(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_8(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<8; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<8; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<8; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_8(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_8(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - X1 */\n        sp_256_mont_sub_8(t2, t2, x, p256_mod);\n        /* R = S2 - Y1 */\n        sp_256_mont_sub_8(t4, t4, y, p256_mod);\n        /* Z3 = H*Z1 */\n        sp_256_mont_mul_8(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*X1*H^2 */\n        sp_256_mont_sqr_8(t1, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_8(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t3, x, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(x, t1, t5, p256_mod);\n        sp_256_mont_dbl_8(t1, t3, p256_mod);\n        sp_256_mont_sub_8(x, x, t1, p256_mod);\n        /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */\n        sp_256_mont_sub_8(t3, t3, x, p256_mod);\n        sp_256_mont_mul_8(t3, t3, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(t5, t5, y, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_8(y, t3, t5, p256_mod);\n    }\n}\n\n#ifdef WOLFSSL_SP_SMALL\n#ifdef FP_ECC\n/* Generate the pre-computed table of points for the base point.\n *\n * a      The base point.\n * table  Place to store generated point data.\n * tmp    Temprorary data.\n * heap  Heap to use for allocation.\n */\nstatic int sp_256_gen_stripe_table_8(const sp_point* a,\n        sp_table_entry* table, sp_digit* tmp, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td, s1d, s2d;\n#endif\n    sp_point* t;\n    sp_point* s1 = NULL;\n    sp_point* s2 = NULL;\n    int i, j;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, td, t);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s1d, s1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s2d, s2);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->x, a->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->y, a->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->z, a->z, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        t->infinity = 0;\n        sp_256_proj_to_affine_8(t, tmp);\n\n        XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s1->infinity = 0;\n        XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s2->infinity = 0;\n\n        /* table[0] = {0, 0, infinity} */\n        XMEMSET(&table[0], 0, sizeof(sp_table_entry));\n        /* table[1] = Affine version of 'a' in Montgomery form */\n        XMEMCPY(table[1].x, t->x, sizeof(table->x));\n        XMEMCPY(table[1].y, t->y, sizeof(table->y));\n\n        for (i=1; i<4; i++) {\n            sp_256_proj_point_dbl_n_8(t, t, 64, tmp);\n            sp_256_proj_to_affine_8(t, tmp);\n            XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));\n            XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));\n        }\n\n        for (i=1; i<4; i++) {\n            XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));\n            XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));\n            for (j=(1<<i)+1; j<(1<<(i+1)); j++) {\n                XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));\n                XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));\n                sp_256_proj_point_add_qz1_8(t, s1, s2, tmp);\n                sp_256_proj_to_affine_8(t, tmp);\n                XMEMCPY(table[j].x, t->x, sizeof(table->x));\n                XMEMCPY(table[j].y, t->y, sizeof(table->y));\n            }\n        }\n    }\n\n    sp_ecc_point_free(s2, 0, heap);\n    sp_ecc_point_free(s1, 0, heap);\n    sp_ecc_point_free( t, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC */\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit td[2 * 8 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* t;\n    int i, j;\n    int y, x;\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap,\n                           DYNAMIC_TYPE_ECC);\n    if (t == NULL) {\n        err = MEMORY_E;\n    }\n#else\n    t = td;\n#endif\n\n    if (err == MP_OKAY) {\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        y = 0;\n        for (j=0,x=63; j<4; j++,x+=64) {\n            y |= ((k[x / 32] >> (x % 32)) & 1) << j;\n        }\n        XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));\n        XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));\n        rt->infinity = !y;\n        for (i=62; i>=0; i--) {\n            y = 0;\n            for (j=0,x=i; j<4; j++,x+=64) {\n                y |= ((k[x / 32] >> (x % 32)) & 1) << j;\n            }\n\n            sp_256_proj_point_dbl_8(rt, rt, t);\n            XMEMCPY(p->x, table[y].x, sizeof(table[y].x));\n            XMEMCPY(p->y, table[y].y, sizeof(table[y].y));\n            p->infinity = !y;\n            sp_256_proj_point_add_qz1_8(rt, rt, p, t);\n        }\n\n        if (map != 0) {\n            sp_256_map_8(r, rt, t);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n#ifdef FP_ECC\n#ifndef FP_ENTRIES\n    #define FP_ENTRIES 16\n#endif\n\ntypedef struct sp_cache_t {\n    sp_digit x[8];\n    sp_digit y[8];\n    sp_table_entry table[16];\n    uint32_t cnt;\n    int set;\n} sp_cache_t;\n\nstatic THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES];\nstatic THREAD_LS_T int sp_cache_last = -1;\nstatic THREAD_LS_T int sp_cache_inited = 0;\n\n#ifndef HAVE_THREAD_LS\n    static volatile int initCacheMutex = 0;\n    static wolfSSL_Mutex sp_cache_lock;\n#endif\n\nstatic void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache)\n{\n    int i, j;\n    uint32_t least;\n\n    if (sp_cache_inited == 0) {\n        for (i=0; i<FP_ENTRIES; i++) {\n            sp_cache[i].set = 0;\n        }\n        sp_cache_inited = 1;\n    }\n\n    /* Compare point with those in cache. */\n    for (i=0; i<FP_ENTRIES; i++) {\n        if (!sp_cache[i].set)\n            continue;\n\n        if (sp_256_cmp_equal_8(g->x, sp_cache[i].x) &\n                           sp_256_cmp_equal_8(g->y, sp_cache[i].y)) {\n            sp_cache[i].cnt++;\n            break;\n        }\n    }\n\n    /* No match. */\n    if (i == FP_ENTRIES) {\n        /* Find empty entry. */\n        i = (sp_cache_last + 1) % FP_ENTRIES;\n        for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) {\n            if (!sp_cache[i].set) {\n                break;\n            }\n        }\n\n        /* Evict least used. */\n        if (i == sp_cache_last) {\n            least = sp_cache[0].cnt;\n            for (j=1; j<FP_ENTRIES; j++) {\n                if (sp_cache[j].cnt < least) {\n                    i = j;\n                    least = sp_cache[i].cnt;\n                }\n            }\n        }\n\n        XMEMCPY(sp_cache[i].x, g->x, sizeof(sp_cache[i].x));\n        XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y));\n        sp_cache[i].set = 1;\n        sp_cache[i].cnt = 1;\n    }\n\n    *cache = &sp_cache[i];\n    sp_cache_last = i;\n}\n#endif /* FP_ECC */\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#ifndef FP_ECC\n    return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);\n#else\n    sp_digit tmp[2 * 8 * 5];\n    sp_cache_t* cache;\n    int err = MP_OKAY;\n\n#ifndef HAVE_THREAD_LS\n    if (initCacheMutex == 0) {\n         wc_InitMutex(&sp_cache_lock);\n         initCacheMutex = 1;\n    }\n    if (wc_LockMutex(&sp_cache_lock) != 0)\n       err = BAD_MUTEX_E;\n#endif /* HAVE_THREAD_LS */\n\n    if (err == MP_OKAY) {\n        sp_ecc_get_cache(g, &cache);\n        if (cache->cnt == 2)\n            sp_256_gen_stripe_table_8(g, cache->table, tmp, heap);\n\n#ifndef HAVE_THREAD_LS\n        wc_UnLockMutex(&sp_cache_lock);\n#endif /* HAVE_THREAD_LS */\n\n        if (cache->cnt < 2) {\n            err = sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);\n        }\n        else {\n            err = sp_256_ecc_mulmod_stripe_8(r, g, cache->table, k,\n                    map, heap);\n        }\n    }\n\n    return err;\n#endif\n}\n\n#else\n#ifdef FP_ECC\n/* Generate the pre-computed table of points for the base point.\n *\n * a      The base point.\n * table  Place to store generated point data.\n * tmp    Temprorary data.\n * heap  Heap to use for allocation.\n */\nstatic int sp_256_gen_stripe_table_8(const sp_point* a,\n        sp_table_entry* table, sp_digit* tmp, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td, s1d, s2d;\n#endif\n    sp_point* t;\n    sp_point* s1 = NULL;\n    sp_point* s2 = NULL;\n    int i, j;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, td, t);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s1d, s1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s2d, s2);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->x, a->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->y, a->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_8(t->z, a->z, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        t->infinity = 0;\n        sp_256_proj_to_affine_8(t, tmp);\n\n        XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s1->infinity = 0;\n        XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s2->infinity = 0;\n\n        /* table[0] = {0, 0, infinity} */\n        XMEMSET(&table[0], 0, sizeof(sp_table_entry));\n        /* table[1] = Affine version of 'a' in Montgomery form */\n        XMEMCPY(table[1].x, t->x, sizeof(table->x));\n        XMEMCPY(table[1].y, t->y, sizeof(table->y));\n\n        for (i=1; i<8; i++) {\n            sp_256_proj_point_dbl_n_8(t, t, 32, tmp);\n            sp_256_proj_to_affine_8(t, tmp);\n            XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));\n            XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));\n        }\n\n        for (i=1; i<8; i++) {\n            XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));\n            XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));\n            for (j=(1<<i)+1; j<(1<<(i+1)); j++) {\n                XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));\n                XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));\n                sp_256_proj_point_add_qz1_8(t, s1, s2, tmp);\n                sp_256_proj_to_affine_8(t, tmp);\n                XMEMCPY(table[j].x, t->x, sizeof(table->x));\n                XMEMCPY(table[j].y, t->y, sizeof(table->y));\n            }\n        }\n    }\n\n    sp_ecc_point_free(s2, 0, heap);\n    sp_ecc_point_free(s1, 0, heap);\n    sp_ecc_point_free( t, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC */\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit td[2 * 8 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* t;\n    int i, j;\n    int y, x;\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap,\n                           DYNAMIC_TYPE_ECC);\n    if (t == NULL) {\n        err = MEMORY_E;\n    }\n#else\n    t = td;\n#endif\n\n    if (err == MP_OKAY) {\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        y = 0;\n        for (j=0,x=31; j<8; j++,x+=32) {\n            y |= ((k[x / 32] >> (x % 32)) & 1) << j;\n        }\n        XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));\n        XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));\n        rt->infinity = !y;\n        for (i=30; i>=0; i--) {\n            y = 0;\n            for (j=0,x=i; j<8; j++,x+=32) {\n                y |= ((k[x / 32] >> (x % 32)) & 1) << j;\n            }\n\n            sp_256_proj_point_dbl_8(rt, rt, t);\n            XMEMCPY(p->x, table[y].x, sizeof(table[y].x));\n            XMEMCPY(p->y, table[y].y, sizeof(table[y].y));\n            p->infinity = !y;\n            sp_256_proj_point_add_qz1_8(rt, rt, p, t);\n        }\n\n        if (map != 0) {\n            sp_256_map_8(r, rt, t);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n#ifdef FP_ECC\n#ifndef FP_ENTRIES\n    #define FP_ENTRIES 16\n#endif\n\ntypedef struct sp_cache_t {\n    sp_digit x[8];\n    sp_digit y[8];\n    sp_table_entry table[256];\n    uint32_t cnt;\n    int set;\n} sp_cache_t;\n\nstatic THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES];\nstatic THREAD_LS_T int sp_cache_last = -1;\nstatic THREAD_LS_T int sp_cache_inited = 0;\n\n#ifndef HAVE_THREAD_LS\n    static volatile int initCacheMutex = 0;\n    static wolfSSL_Mutex sp_cache_lock;\n#endif\n\nstatic void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache)\n{\n    int i, j;\n    uint32_t least;\n\n    if (sp_cache_inited == 0) {\n        for (i=0; i<FP_ENTRIES; i++) {\n            sp_cache[i].set = 0;\n        }\n        sp_cache_inited = 1;\n    }\n\n    /* Compare point with those in cache. */\n    for (i=0; i<FP_ENTRIES; i++) {\n        if (!sp_cache[i].set)\n            continue;\n\n        if (sp_256_cmp_equal_8(g->x, sp_cache[i].x) &\n                           sp_256_cmp_equal_8(g->y, sp_cache[i].y)) {\n            sp_cache[i].cnt++;\n            break;\n        }\n    }\n\n    /* No match. */\n    if (i == FP_ENTRIES) {\n        /* Find empty entry. */\n        i = (sp_cache_last + 1) % FP_ENTRIES;\n        for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) {\n            if (!sp_cache[i].set) {\n                break;\n            }\n        }\n\n        /* Evict least used. */\n        if (i == sp_cache_last) {\n            least = sp_cache[0].cnt;\n            for (j=1; j<FP_ENTRIES; j++) {\n                if (sp_cache[j].cnt < least) {\n                    i = j;\n                    least = sp_cache[i].cnt;\n                }\n            }\n        }\n\n        XMEMCPY(sp_cache[i].x, g->x, sizeof(sp_cache[i].x));\n        XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y));\n        sp_cache[i].set = 1;\n        sp_cache[i].cnt = 1;\n    }\n\n    *cache = &sp_cache[i];\n    sp_cache_last = i;\n}\n#endif /* FP_ECC */\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#ifndef FP_ECC\n    return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);\n#else\n    sp_digit tmp[2 * 8 * 5];\n    sp_cache_t* cache;\n    int err = MP_OKAY;\n\n#ifndef HAVE_THREAD_LS\n    if (initCacheMutex == 0) {\n         wc_InitMutex(&sp_cache_lock);\n         initCacheMutex = 1;\n    }\n    if (wc_LockMutex(&sp_cache_lock) != 0)\n       err = BAD_MUTEX_E;\n#endif /* HAVE_THREAD_LS */\n\n    if (err == MP_OKAY) {\n        sp_ecc_get_cache(g, &cache);\n        if (cache->cnt == 2)\n            sp_256_gen_stripe_table_8(g, cache->table, tmp, heap);\n\n#ifndef HAVE_THREAD_LS\n        wc_UnLockMutex(&sp_cache_lock);\n#endif /* HAVE_THREAD_LS */\n\n        if (cache->cnt < 2) {\n            err = sp_256_ecc_mulmod_fast_8(r, g, k, map, heap);\n        }\n        else {\n            err = sp_256_ecc_mulmod_stripe_8(r, g, cache->table, k,\n                    map, heap);\n        }\n    }\n\n    return err;\n#endif\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * p     Point to multiply.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map,\n        void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[8];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 8, km);\n        sp_256_point_from_ecc_point_8(point, gm);\n\n            err = sp_256_ecc_mulmod_8(point, point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_8(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#ifdef WOLFSSL_SP_SMALL\nstatic const sp_table_entry p256_table[16] = {\n    /* 0 */\n    { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 */\n    { { 0x18a9143c,0x79e730d4,0x5fedb601,0x75ba95fc,0x77622510,0x79fb732b,\n        0xa53755c6,0x18905f76 },\n      { 0xce95560a,0xddf25357,0xba19e45c,0x8b4ab8e4,0xdd21f325,0xd2e88688,\n        0x25885d85,0x8571ff18 } },\n    /* 2 */\n    { { 0x16a0d2bb,0x4f922fc5,0x1a623499,0x0d5cc16c,0x57c62c8b,0x9241cf3a,\n        0xfd1b667f,0x2f5e6961 },\n      { 0xf5a01797,0x5c15c70b,0x60956192,0x3d20b44d,0x071fdb52,0x04911b37,\n        0x8d6f0f7b,0xf648f916 } },\n    /* 3 */\n    { { 0xe137bbbc,0x9e566847,0x8a6a0bec,0xe434469e,0x79d73463,0xb1c42761,\n        0x133d0015,0x5abe0285 },\n      { 0xc04c7dab,0x92aa837c,0x43260c07,0x573d9f4c,0x78e6cc37,0x0c931562,\n        0x6b6f7383,0x94bb725b } },\n    /* 4 */\n    { { 0xbfe20925,0x62a8c244,0x8fdce867,0x91c19ac3,0xdd387063,0x5a96a5d5,\n        0x21d324f6,0x61d587d4 },\n      { 0xa37173ea,0xe87673a2,0x53778b65,0x23848008,0x05bab43e,0x10f8441e,\n        0x4621efbe,0xfa11fe12 } },\n    /* 5 */\n    { { 0x2cb19ffd,0x1c891f2b,0xb1923c23,0x01ba8d5b,0x8ac5ca8e,0xb6d03d67,\n        0x1f13bedc,0x586eb04c },\n      { 0x27e8ed09,0x0c35c6e5,0x1819ede2,0x1e81a33c,0x56c652fa,0x278fd6c0,\n        0x70864f11,0x19d5ac08 } },\n    /* 6 */\n    { { 0xd2b533d5,0x62577734,0xa1bdddc0,0x673b8af6,0xa79ec293,0x577e7c9a,\n        0xc3b266b1,0xbb6de651 },\n      { 0xb65259b3,0xe7e9303a,0xd03a7480,0xd6a0afd3,0x9b3cfc27,0xc5ac83d1,\n        0x5d18b99b,0x60b4619a } },\n    /* 7 */\n    { { 0x1ae5aa1c,0xbd6a38e1,0x49e73658,0xb8b7652b,0xee5f87ed,0x0b130014,\n        0xaeebffcd,0x9d0f27b2 },\n      { 0x7a730a55,0xca924631,0xddbbc83a,0x9c955b2f,0xac019a71,0x07c1dfe0,\n        0x356ec48d,0x244a566d } },\n    /* 8 */\n    { { 0xf4f8b16a,0x56f8410e,0xc47b266a,0x97241afe,0x6d9c87c1,0x0a406b8e,\n        0xcd42ab1b,0x803f3e02 },\n      { 0x04dbec69,0x7f0309a8,0x3bbad05f,0xa83b85f7,0xad8e197f,0xc6097273,\n        0x5067adc1,0xc097440e } },\n    /* 9 */\n    { { 0xc379ab34,0x846a56f2,0x841df8d1,0xa8ee068b,0x176c68ef,0x20314459,\n        0x915f1f30,0xf1af32d5 },\n      { 0x5d75bd50,0x99c37531,0xf72f67bc,0x837cffba,0x48d7723f,0x0613a418,\n        0xe2d41c8b,0x23d0f130 } },\n    /* 10 */\n    { { 0xd5be5a2b,0xed93e225,0x5934f3c6,0x6fe79983,0x22626ffc,0x43140926,\n        0x7990216a,0x50bbb4d9 },\n      { 0xe57ec63e,0x378191c6,0x181dcdb2,0x65422c40,0x0236e0f6,0x41a8099b,\n        0x01fe49c3,0x2b100118 } },\n    /* 11 */\n    { { 0x9b391593,0xfc68b5c5,0x598270fc,0xc385f5a2,0xd19adcbb,0x7144f3aa,\n        0x83fbae0c,0xdd558999 },\n      { 0x74b82ff4,0x93b88b8e,0x71e734c9,0xd2e03c40,0x43c0322a,0x9a7a9eaf,\n        0x149d6041,0xe6e4c551 } },\n    /* 12 */\n    { { 0x80ec21fe,0x5fe14bfe,0xc255be82,0xf6ce116a,0x2f4a5d67,0x98bc5a07,\n        0xdb7e63af,0xfad27148 },\n      { 0x29ab05b3,0x90c0b6ac,0x4e251ae6,0x37a9a83c,0xc2aade7d,0x0a7dc875,\n        0x9f0e1a84,0x77387de3 } },\n    /* 13 */\n    { { 0xa56c0dd7,0x1e9ecc49,0x46086c74,0xa5cffcd8,0xf505aece,0x8f7a1408,\n        0xbef0c47e,0xb37b85c0 },\n      { 0xcc0e6a8f,0x3596b6e4,0x6b388f23,0xfd6d4bbf,0xc39cef4e,0xaba453fa,\n        0xf9f628d5,0x9c135ac8 } },\n    /* 14 */\n    { { 0x95c8f8be,0x0a1c7294,0x3bf362bf,0x2961c480,0xdf63d4ac,0x9e418403,\n        0x91ece900,0xc109f9cb },\n      { 0x58945705,0xc2d095d0,0xddeb85c0,0xb9083d96,0x7a40449b,0x84692b8d,\n        0x2eee1ee1,0x9bc3344f } },\n    /* 15 */\n    { { 0x42913074,0x0d5ae356,0x48a542b1,0x55491b27,0xb310732a,0x469ca665,\n        0x5f1a4cc1,0x29591d52 },\n      { 0xb84f983f,0xe76f5b6b,0x9f5f84e1,0xbe7eef41,0x80baa189,0x1200d496,\n        0x18ef332c,0x6376551f } },\n};\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table,\n                                      k, map, heap);\n}\n\n#else\nstatic const sp_table_entry p256_table[256] = {\n    /* 0 */\n    { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 */\n    { { 0x18a9143c,0x79e730d4,0x5fedb601,0x75ba95fc,0x77622510,0x79fb732b,\n        0xa53755c6,0x18905f76 },\n      { 0xce95560a,0xddf25357,0xba19e45c,0x8b4ab8e4,0xdd21f325,0xd2e88688,\n        0x25885d85,0x8571ff18 } },\n    /* 2 */\n    { { 0x4147519a,0x20288602,0x26b372f0,0xd0981eac,0xa785ebc8,0xa9d4a7ca,\n        0xdbdf58e9,0xd953c50d },\n      { 0xfd590f8f,0x9d6361cc,0x44e6c917,0x72e9626b,0x22eb64cf,0x7fd96110,\n        0x9eb288f3,0x863ebb7e } },\n    /* 3 */\n    { { 0x5cdb6485,0x7856b623,0x2f0a2f97,0x808f0ea2,0x4f7e300b,0x3e68d954,\n        0xb5ff80a0,0x00076055 },\n      { 0x838d2010,0x7634eb9b,0x3243708a,0x54014fbb,0x842a6606,0xe0e47d39,\n        0x34373ee0,0x83087761 } },\n    /* 4 */\n    { { 0x16a0d2bb,0x4f922fc5,0x1a623499,0x0d5cc16c,0x57c62c8b,0x9241cf3a,\n        0xfd1b667f,0x2f5e6961 },\n      { 0xf5a01797,0x5c15c70b,0x60956192,0x3d20b44d,0x071fdb52,0x04911b37,\n        0x8d6f0f7b,0xf648f916 } },\n    /* 5 */\n    { { 0xe137bbbc,0x9e566847,0x8a6a0bec,0xe434469e,0x79d73463,0xb1c42761,\n        0x133d0015,0x5abe0285 },\n      { 0xc04c7dab,0x92aa837c,0x43260c07,0x573d9f4c,0x78e6cc37,0x0c931562,\n        0x6b6f7383,0x94bb725b } },\n    /* 6 */\n    { { 0x720f141c,0xbbf9b48f,0x2df5bc74,0x6199b3cd,0x411045c4,0xdc3f6129,\n        0x2f7dc4ef,0xcdd6bbcb },\n      { 0xeaf436fd,0xcca6700b,0xb99326be,0x6f647f6d,0x014f2522,0x0c0fa792,\n        0x4bdae5f6,0xa361bebd } },\n    /* 7 */\n    { { 0x597c13c7,0x28aa2558,0x50b7c3e1,0xc38d635f,0xf3c09d1d,0x07039aec,\n        0xc4b5292c,0xba12ca09 },\n      { 0x59f91dfd,0x9e408fa4,0xceea07fb,0x3af43b66,0x9d780b29,0x1eceb089,\n        0x701fef4b,0x53ebb99d } },\n    /* 8 */\n    { { 0xb0e63d34,0x4fe7ee31,0xa9e54fab,0xf4600572,0xd5e7b5a4,0xc0493334,\n        0x06d54831,0x8589fb92 },\n      { 0x6583553a,0xaa70f5cc,0xe25649e5,0x0879094a,0x10044652,0xcc904507,\n        0x02541c4f,0xebb0696d } },\n    /* 9 */\n    { { 0xac1647c5,0x4616ca15,0xc4cf5799,0xb8127d47,0x764dfbac,0xdc666aa3,\n        0xd1b27da3,0xeb2820cb },\n      { 0x6a87e008,0x9406f8d8,0x922378f3,0xd87dfa9d,0x80ccecb2,0x56ed2e42,\n        0x55a7da1d,0x1f28289b } },\n    /* 10 */\n    { { 0x3b89da99,0xabbaa0c0,0xb8284022,0xa6f2d79e,0xb81c05e8,0x27847862,\n        0x05e54d63,0x337a4b59 },\n      { 0x21f7794a,0x3c67500d,0x7d6d7f61,0x207005b7,0x04cfd6e8,0x0a5a3781,\n        0xf4c2fbd6,0x0d65e0d5 } },\n    /* 11 */\n    { { 0xb5275d38,0xd9d09bbe,0x0be0a358,0x4268a745,0x973eb265,0xf0762ff4,\n        0x52f4a232,0xc23da242 },\n      { 0x0b94520c,0x5da1b84f,0xb05bd78e,0x09666763,0x94d29ea1,0x3a4dcb86,\n        0xc790cff1,0x19de3b8c } },\n    /* 12 */\n    { { 0x26c5fe04,0x183a716c,0x3bba1bdb,0x3b28de0b,0xa4cb712c,0x7432c586,\n        0x91fccbfd,0xe34dcbd4 },\n      { 0xaaa58403,0xb408d46b,0x82e97a53,0x9a697486,0x36aaa8af,0x9e390127,\n        0x7b4e0f7f,0xe7641f44 } },\n    /* 13 */\n    { { 0xdf64ba59,0x7d753941,0x0b0242fc,0xd33f10ec,0xa1581859,0x4f06dfc6,\n        0x052a57bf,0x4a12df57 },\n      { 0x9439dbd0,0xbfa6338f,0xbde53e1f,0xd3c24bd4,0x21f1b314,0xfd5e4ffa,\n        0xbb5bea46,0x6af5aa93 } },\n    /* 14 */\n    { { 0x10c91999,0xda10b699,0x2a580491,0x0a24b440,0xb8cc2090,0x3e0094b4,\n        0x66a44013,0x5fe3475a },\n      { 0xf93e7b4b,0xb0f8cabd,0x7c23f91a,0x292b501a,0xcd1e6263,0x42e889ae,\n        0xecfea916,0xb544e308 } },\n    /* 15 */\n    { { 0x16ddfdce,0x6478c6e9,0xf89179e6,0x2c329166,0x4d4e67e1,0x4e8d6e76,\n        0xa6b0c20b,0xe0b6b2bd },\n      { 0xbb7efb57,0x0d312df2,0x790c4007,0x1aac0dde,0x679bc944,0xf90336ad,\n        0x25a63774,0x71c023de } },\n    /* 16 */\n    { { 0xbfe20925,0x62a8c244,0x8fdce867,0x91c19ac3,0xdd387063,0x5a96a5d5,\n        0x21d324f6,0x61d587d4 },\n      { 0xa37173ea,0xe87673a2,0x53778b65,0x23848008,0x05bab43e,0x10f8441e,\n        0x4621efbe,0xfa11fe12 } },\n    /* 17 */\n    { { 0x2cb19ffd,0x1c891f2b,0xb1923c23,0x01ba8d5b,0x8ac5ca8e,0xb6d03d67,\n        0x1f13bedc,0x586eb04c },\n      { 0x27e8ed09,0x0c35c6e5,0x1819ede2,0x1e81a33c,0x56c652fa,0x278fd6c0,\n        0x70864f11,0x19d5ac08 } },\n    /* 18 */\n    { { 0x309a4e1f,0x1e99f581,0xe9270074,0xab7de71b,0xefd28d20,0x26a5ef0b,\n        0x7f9c563f,0xe7c0073f },\n      { 0x0ef59f76,0x1f6d663a,0x20fcb050,0x669b3b54,0x7a6602d4,0xc08c1f7a,\n        0xc65b3c0a,0xe08504fe } },\n    /* 19 */\n    { { 0xa031b3ca,0xf098f68d,0xe6da6d66,0x6d1cab9e,0x94f246e8,0x5bfd81fa,\n        0x5b0996b4,0x78f01882 },\n      { 0x3a25787f,0xb7eefde4,0x1dccac9b,0x8016f80d,0xb35bfc36,0x0cea4877,\n        0x7e94747a,0x43a773b8 } },\n    /* 20 */\n    { { 0xd2b533d5,0x62577734,0xa1bdddc0,0x673b8af6,0xa79ec293,0x577e7c9a,\n        0xc3b266b1,0xbb6de651 },\n      { 0xb65259b3,0xe7e9303a,0xd03a7480,0xd6a0afd3,0x9b3cfc27,0xc5ac83d1,\n        0x5d18b99b,0x60b4619a } },\n    /* 21 */\n    { { 0x1ae5aa1c,0xbd6a38e1,0x49e73658,0xb8b7652b,0xee5f87ed,0x0b130014,\n        0xaeebffcd,0x9d0f27b2 },\n      { 0x7a730a55,0xca924631,0xddbbc83a,0x9c955b2f,0xac019a71,0x07c1dfe0,\n        0x356ec48d,0x244a566d } },\n    /* 22 */\n    { { 0xeacf1f96,0x6db0394a,0x024c271c,0x9f2122a9,0x82cbd3b9,0x2626ac1b,\n        0x3581ef69,0x45e58c87 },\n      { 0xa38f9dbc,0xd3ff479d,0xe888a040,0xa8aaf146,0x46e0bed7,0x945adfb2,\n        0xc1e4b7a4,0xc040e21c } },\n    /* 23 */\n    { { 0x6f8117b6,0x847af000,0x73a35433,0x651969ff,0x1d9475eb,0x482b3576,\n        0x682c6ec7,0x1cdf5c97 },\n      { 0x11f04839,0x7db775b4,0x48de1698,0x7dbeacf4,0xb70b3219,0xb2921dd1,\n        0xa92dff3d,0x046755f8 } },\n    /* 24 */\n    { { 0xbce8ffcd,0xcc8ac5d2,0x2fe61a82,0x0d53c48b,0x7202d6c7,0xf6f16172,\n        0x3b83a5f3,0x046e5e11 },\n      { 0xd8007f01,0xe7b8ff64,0x5af43183,0x7fb1ef12,0x35e1a03c,0x045c5ea6,\n        0x303d005b,0x6e0106c3 } },\n    /* 25 */\n    { { 0x88dd73b1,0x48c73584,0x995ed0d9,0x7670708f,0xc56a2ab7,0x38385ea8,\n        0xe901cf1f,0x442594ed },\n      { 0x12d4b65b,0xf8faa2c9,0x96c90c37,0x94c2343b,0x5e978d1f,0xd326e4a1,\n        0x4c2ee68e,0xa796fa51 } },\n    /* 26 */\n    { { 0x823addd7,0x359fb604,0xe56693b3,0x9e2a6183,0x3cbf3c80,0xf885b78e,\n        0xc69766e9,0xe4ad2da9 },\n      { 0x8e048a61,0x357f7f42,0xc092d9a0,0x082d198c,0xc03ed8ef,0xfc3a1af4,\n        0xc37b5143,0xc5e94046 } },\n    /* 27 */\n    { { 0x2be75f9e,0x476a538c,0xcb123a78,0x6fd1a9e8,0xb109c04b,0xd85e4df0,\n        0xdb464747,0x63283daf },\n      { 0xbaf2df15,0xce728cf7,0x0ad9a7f4,0xe592c455,0xe834bcc3,0xfab226ad,\n        0x1981a938,0x68bd19ab } },\n    /* 28 */\n    { { 0x1887d659,0xc08ead51,0xb359305a,0x3374d5f4,0xcfe74fe3,0x96986981,\n        0x3c6fdfd6,0x495292f5 },\n      { 0x1acec896,0x4a878c9e,0xec5b4484,0xd964b210,0x664d60a7,0x6696f7e2,\n        0x26036837,0x0ec7530d } },\n    /* 29 */\n    { { 0xad2687bb,0x2da13a05,0xf32e21fa,0xa1f83b6a,0x1dd4607b,0x390f5ef5,\n        0x64863f0b,0x0f6207a6 },\n      { 0x0f138233,0xbd67e3bb,0x272aa718,0xdd66b96c,0x26ec88ae,0x8ed00407,\n        0x08ed6dcf,0xff0db072 } },\n    /* 30 */\n    { { 0x4c95d553,0x749fa101,0x5d680a8a,0xa44052fd,0xff3b566f,0x183b4317,\n        0x88740ea3,0x313b513c },\n      { 0x08d11549,0xb402e2ac,0xb4dee21c,0x071ee10b,0x47f2320e,0x26b987dd,\n        0x86f19f81,0x2d3abcf9 } },\n    /* 31 */\n    { { 0x815581a2,0x4c288501,0x632211af,0x9a0a6d56,0x0cab2e99,0x19ba7a0f,\n        0xded98cdf,0xc036fa10 },\n      { 0xc1fbd009,0x29ae08ba,0x06d15816,0x0b68b190,0x9b9e0d8f,0xc2eb3277,\n        0xb6d40194,0xa6b2a2c4 } },\n    /* 32 */\n    { { 0x6d3549cf,0xd433e50f,0xfacd665e,0x6f33696f,0xce11fcb4,0x695bfdac,\n        0xaf7c9860,0x810ee252 },\n      { 0x7159bb2c,0x65450fe1,0x758b357b,0xf7dfbebe,0xd69fea72,0x2b057e74,\n        0x92731745,0xd485717a } },\n    /* 33 */\n    { { 0xf0cb5a98,0x11741a8a,0x1f3110bf,0xd3da8f93,0xab382adf,0x1994e2cb,\n        0x2f9a604e,0x6a6045a7 },\n      { 0xa2b2411d,0x170c0d3f,0x510e96e0,0xbe0eb83e,0x8865b3cc,0x3bcc9f73,\n        0xf9e15790,0xd3e45cfa } },\n    /* 34 */\n    { { 0xe83f7669,0xce1f69bb,0x72877d6b,0x09f8ae82,0x3244278d,0x9548ae54,\n        0xe3c2c19c,0x207755de },\n      { 0x6fef1945,0x87bd61d9,0xb12d28c3,0x18813cef,0x72df64aa,0x9fbcd1d6,\n        0x7154b00d,0x48dc5ee5 } },\n    /* 35 */\n    { { 0xf7e5a199,0x123790bf,0x989ccbb7,0xe0efb8cf,0x0a519c79,0xc27a2bfe,\n        0xdff6f445,0xf2fb0aed },\n      { 0xf0b5025f,0x41c09575,0x40fa9f22,0x550543d7,0x380bfbd0,0x8fa3c8ad,\n        0xdb28d525,0xa13e9015 } },\n    /* 36 */\n    { { 0xa2b65cbc,0xf9f7a350,0x2a464226,0x0b04b972,0xe23f07a1,0x265ce241,\n        0x1497526f,0x2bf0d6b0 },\n      { 0x4b216fb7,0xd3d4dd3f,0xfbdda26a,0xf7d7b867,0x6708505c,0xaeb7b83f,\n        0x162fe89f,0x42a94a5a } },\n    /* 37 */\n    { { 0xeaadf191,0x5846ad0b,0x25a268d7,0x0f8a4890,0x494dc1f6,0xe8603050,\n        0xc65ede3d,0x2c2dd969 },\n      { 0x93849c17,0x6d02171d,0x1da250dd,0x460488ba,0x3c3a5485,0x4810c706,\n        0x42c56dbc,0xf437fa1f } },\n    /* 38 */\n    { { 0x4a0f7dab,0x6aa0d714,0x1776e9ac,0x0f049793,0xf5f39786,0x52c0a050,\n        0x54707aa8,0xaaf45b33 },\n      { 0xc18d364a,0x85e37c33,0x3e497165,0xd40b9b06,0x15ec5444,0xf4171681,\n        0xf4f272bc,0xcdf6310d } },\n    /* 39 */\n    { { 0x8ea8b7ef,0x7473c623,0x85bc2287,0x08e93518,0x2bda8e34,0x41956772,\n        0xda9e2ff2,0xf0d008ba },\n      { 0x2414d3b1,0x2912671d,0xb019ea76,0xb3754985,0x453bcbdb,0x5c61b96d,\n        0xca887b8b,0x5bd5c2f5 } },\n    /* 40 */\n    { { 0xf49a3154,0xef0f469e,0x6e2b2e9a,0x3e85a595,0xaa924a9c,0x45aaec1e,\n        0xa09e4719,0xaa12dfc8 },\n      { 0x4df69f1d,0x26f27227,0xa2ff5e73,0xe0e4c82c,0xb7a9dd44,0xb9d8ce73,\n        0xe48ca901,0x6c036e73 } },\n    /* 41 */\n    { { 0x0f6e3138,0x5cfae12a,0x25ad345a,0x6966ef00,0x45672bc5,0x8993c64b,\n        0x96afbe24,0x292ff658 },\n      { 0x5e213402,0xd5250d44,0x4392c9fe,0xf6580e27,0xda1c72e8,0x097b397f,\n        0x311b7276,0x644e0c90 } },\n    /* 42 */\n    { { 0xa47153f0,0xe1e421e1,0x920418c9,0xb86c3b79,0x705d7672,0x93bdce87,\n        0xcab79a77,0xf25ae793 },\n      { 0x6d869d0c,0x1f3194a3,0x4986c264,0x9d55c882,0x096e945e,0x49fb5ea3,\n        0x13db0a3e,0x39b8e653 } },\n    /* 43 */\n    { { 0xb6fd2e59,0x37754200,0x9255c98f,0x35e2c066,0x0e2a5739,0xd9dab21a,\n        0x0f19db06,0x39122f2f },\n      { 0x03cad53c,0xcfbce1e0,0xe65c17e3,0x225b2c0f,0x9aa13877,0x72baf1d2,\n        0xce80ff8d,0x8de80af8 } },\n    /* 44 */\n    { { 0x207bbb76,0xafbea8d9,0x21782758,0x921c7e7c,0x1c0436b1,0xdfa2b74b,\n        0x2e368c04,0x87194906 },\n      { 0xa3993df5,0xb5f928bb,0xf3b3d26a,0x639d75b5,0x85b55050,0x011aa78a,\n        0x5b74fde1,0xfc315e6a } },\n    /* 45 */\n    { { 0xe8d6ecfa,0x561fd41a,0x1aec7f86,0x5f8c44f6,0x4924741d,0x98452a7b,\n        0xee389088,0xe6d4a7ad },\n      { 0x4593c75d,0x60552ed1,0xdd271162,0x70a70da4,0x7ba2c7db,0xd2aede93,\n        0x9be2ae57,0x35dfaf9a } },\n    /* 46 */\n    { { 0xaa736636,0x6b956fcd,0xae2cab7e,0x09f51d97,0x0f349966,0xfb10bf41,\n        0x1c830d2b,0x1da5c7d7 },\n      { 0x3cce6825,0x5c41e483,0xf9573c3b,0x15ad118f,0xf23036b8,0xa28552c7,\n        0xdbf4b9d6,0x7077c0fd } },\n    /* 47 */\n    { { 0x46b9661c,0xbf63ff8d,0x0d2cfd71,0xa1dfd36b,0xa847f8f7,0x0373e140,\n        0xe50efe44,0x53a8632e },\n      { 0x696d8051,0x0976ff68,0xc74f468a,0xdaec0c95,0x5e4e26bd,0x62994dc3,\n        0x34e1fcc1,0x028ca76d } },\n    /* 48 */\n    { { 0xfc9877ee,0xd11d47dc,0x801d0002,0xc8b36210,0x54c260b6,0xd002c117,\n        0x6962f046,0x04c17cd8 },\n      { 0xb0daddf5,0x6d9bd094,0x24ce55c0,0xbea23575,0x72da03b5,0x663356e6,\n        0xfed97474,0xf7ba4de9 } },\n    /* 49 */\n    { { 0xebe1263f,0xd0dbfa34,0x71ae7ce6,0x55763735,0x82a6f523,0xd2440553,\n        0x52131c41,0xe31f9600 },\n      { 0xea6b6ec6,0xd1bb9216,0x73c2fc44,0x37a1d12e,0x89d0a294,0xc10e7eac,\n        0xce34d47b,0xaa3a6259 } },\n    /* 50 */\n    { { 0x36f3dcd3,0xfbcf9df5,0xd2bf7360,0x6ceded50,0xdf504f5b,0x491710fa,\n        0x7e79daee,0x2398dd62 },\n      { 0x6d09569e,0xcf4705a3,0x5149f769,0xea0619bb,0x35f6034c,0xff9c0377,\n        0x1c046210,0x5717f5b2 } },\n    /* 51 */\n    { { 0x21dd895e,0x9fe229c9,0x40c28451,0x8e518500,0x1d637ecd,0xfa13d239,\n        0x0e3c28de,0x660a2c56 },\n      { 0xd67fcbd0,0x9cca88ae,0x0ea9f096,0xc8472478,0x72e92b4d,0x32b2f481,\n        0x4f522453,0x624ee54c } },\n    /* 52 */\n    { { 0xd897eccc,0x09549ce4,0x3f9880aa,0x4d49d1d9,0x043a7c20,0x723c2423,\n        0x92bdfbc0,0x4f392afb },\n      { 0x7de44fd9,0x6969f8fa,0x57b32156,0xb66cfbe4,0x368ebc3c,0xdb2fa803,\n        0xccdb399c,0x8a3e7977 } },\n    /* 53 */\n    { { 0x06c4b125,0xdde1881f,0xf6e3ca8c,0xae34e300,0x5c7a13e9,0xef6999de,\n        0x70c24404,0x3888d023 },\n      { 0x44f91081,0x76280356,0x5f015504,0x3d9fcf61,0x632cd36e,0x1827edc8,\n        0x18102336,0xa5e62e47 } },\n    /* 54 */\n    { { 0x2facd6c8,0x1a825ee3,0x54bcbc66,0x699c6354,0x98df9931,0x0ce3edf7,\n        0x466a5adc,0x2c4768e6 },\n      { 0x90a64bc9,0xb346ff8c,0xe4779f5c,0x630a6020,0xbc05e884,0xd949d064,\n        0xf9e652a0,0x7b5e6441 } },\n    /* 55 */\n    { { 0x1d28444a,0x2169422c,0xbe136a39,0xe996c5d8,0xfb0c7fce,0x2387afe5,\n        0x0c8d744a,0xb8af73cb },\n      { 0x338b86fd,0x5fde83aa,0xa58a5cff,0xfee3f158,0x20ac9433,0xc9ee8f6f,\n        0x7f3f0895,0xa036395f } },\n    /* 56 */\n    { { 0xa10f7770,0x8c73c6bb,0xa12a0e24,0xa6f16d81,0x51bc2b9f,0x100df682,\n        0x875fb533,0x4be36b01 },\n      { 0x9fb56dbb,0x9226086e,0x07e7a4f8,0x306fef8b,0x66d52f20,0xeeaccc05,\n        0x1bdc00c0,0x8cbc9a87 } },\n    /* 57 */\n    { { 0xc0dac4ab,0xe131895c,0x712ff112,0xa874a440,0x6a1cee57,0x6332ae7c,\n        0x0c0835f8,0x44e7553e },\n      { 0x7734002d,0x6d503fff,0x0b34425c,0x9d35cb8b,0x0e8738b5,0x95f70276,\n        0x5eb8fc18,0x470a683a } },\n    /* 58 */\n    { { 0x90513482,0x81b761dc,0x01e9276a,0x0287202a,0x0ce73083,0xcda441ee,\n        0xc63dc6ef,0x16410690 },\n      { 0x6d06a2ed,0xf5034a06,0x189b100b,0xdd4d7745,0xab8218c9,0xd914ae72,\n        0x7abcbb4f,0xd73479fd } },\n    /* 59 */\n    { { 0x5ad4c6e5,0x7edefb16,0x5b06d04d,0x262cf08f,0x8575cb14,0x12ed5bb1,\n        0x0771666b,0x816469e3 },\n      { 0x561e291e,0xd7ab9d79,0xc1de1661,0xeb9daf22,0x135e0513,0xf49827eb,\n        0xf0dd3f9c,0x0a36dd23 } },\n    /* 60 */\n    { { 0x41d5533c,0x098d32c7,0x8684628f,0x7c5f5a9e,0xe349bd11,0x39a228ad,\n        0xfdbab118,0xe331dfd6 },\n      { 0x6bcc6ed8,0x5100ab68,0xef7a260e,0x7160c3bd,0xbce850d7,0x9063d9a7,\n        0x492e3389,0xd3b4782a } },\n    /* 61 */\n    { { 0xf3821f90,0xa149b6e8,0x66eb7aad,0x92edd9ed,0x1a013116,0x0bb66953,\n        0x4c86a5bd,0x7281275a },\n      { 0xd3ff47e5,0x503858f7,0x61016441,0x5e1616bc,0x7dfd9bb1,0x62b0f11a,\n        0xce145059,0x2c062e7e } },\n    /* 62 */\n    { { 0x0159ac2e,0xa76f996f,0xcbdb2713,0x281e7736,0x08e46047,0x2ad6d288,\n        0x2c4e7ef1,0x282a35f9 },\n      { 0xc0ce5cd2,0x9c354b1e,0x1379c229,0xcf99efc9,0x3e82c11e,0x992caf38,\n        0x554d2abd,0xc71cd513 } },\n    /* 63 */\n    { { 0x09b578f4,0x4885de9c,0xe3affa7a,0x1884e258,0x59182f1f,0x8f76b1b7,\n        0xcf47f3a3,0xc50f6740 },\n      { 0x374b68ea,0xa9c4adf3,0x69965fe2,0xa406f323,0x85a53050,0x2f86a222,\n        0x212958dc,0xb9ecb3a7 } },\n    /* 64 */\n    { { 0xf4f8b16a,0x56f8410e,0xc47b266a,0x97241afe,0x6d9c87c1,0x0a406b8e,\n        0xcd42ab1b,0x803f3e02 },\n      { 0x04dbec69,0x7f0309a8,0x3bbad05f,0xa83b85f7,0xad8e197f,0xc6097273,\n        0x5067adc1,0xc097440e } },\n    /* 65 */\n    { { 0xc379ab34,0x846a56f2,0x841df8d1,0xa8ee068b,0x176c68ef,0x20314459,\n        0x915f1f30,0xf1af32d5 },\n      { 0x5d75bd50,0x99c37531,0xf72f67bc,0x837cffba,0x48d7723f,0x0613a418,\n        0xe2d41c8b,0x23d0f130 } },\n    /* 66 */\n    { { 0xf41500d9,0x857ab6ed,0xfcbeada8,0x0d890ae5,0x89725951,0x52fe8648,\n        0xc0a3fadd,0xb0288dd6 },\n      { 0x650bcb08,0x85320f30,0x695d6e16,0x71af6313,0xb989aa76,0x31f520a7,\n        0xf408c8d2,0xffd3724f } },\n    /* 67 */\n    { { 0xb458e6cb,0x53968e64,0x317a5d28,0x992dad20,0x7aa75f56,0x3814ae0b,\n        0xd78c26df,0xf5590f4a },\n      { 0xcf0ba55a,0x0fc24bd3,0x0c778bae,0x0fc4724a,0x683b674a,0x1ce9864f,\n        0xf6f74a20,0x18d6da54 } },\n    /* 68 */\n    { { 0xd5be5a2b,0xed93e225,0x5934f3c6,0x6fe79983,0x22626ffc,0x43140926,\n        0x7990216a,0x50bbb4d9 },\n      { 0xe57ec63e,0x378191c6,0x181dcdb2,0x65422c40,0x0236e0f6,0x41a8099b,\n        0x01fe49c3,0x2b100118 } },\n    /* 69 */\n    { { 0x9b391593,0xfc68b5c5,0x598270fc,0xc385f5a2,0xd19adcbb,0x7144f3aa,\n        0x83fbae0c,0xdd558999 },\n      { 0x74b82ff4,0x93b88b8e,0x71e734c9,0xd2e03c40,0x43c0322a,0x9a7a9eaf,\n        0x149d6041,0xe6e4c551 } },\n    /* 70 */\n    { { 0x1e9af288,0x55f655bb,0xf7ada931,0x647e1a64,0xcb2820e5,0x43697e4b,\n        0x07ed56ff,0x51e00db1 },\n      { 0x771c327e,0x43d169b8,0x4a96c2ad,0x29cdb20b,0x3deb4779,0xc07d51f5,\n        0x49829177,0xe22f4241 } },\n    /* 71 */\n    { { 0x635f1abb,0xcd45e8f4,0x68538874,0x7edc0cb5,0xb5a8034d,0xc9472c1f,\n        0x52dc48c9,0xf709373d },\n      { 0xa8af30d6,0x401966bb,0xf137b69c,0x95bf5f4a,0x9361c47e,0x3966162a,\n        0xe7275b11,0xbd52d288 } },\n    /* 72 */\n    { { 0x9c5fa877,0xab155c7a,0x7d3a3d48,0x17dad672,0x73d189d8,0x43f43f9e,\n        0xc8aa77a6,0xa0d0f8e4 },\n      { 0xcc94f92d,0x0bbeafd8,0x0c4ddb3a,0xd818c8be,0xb82eba14,0x22cc65f8,\n        0x946d6a00,0xa56c78c7 } },\n    /* 73 */\n    { { 0x0dd09529,0x2962391b,0x3daddfcf,0x803e0ea6,0x5b5bf481,0x2c77351f,\n        0x731a367a,0xd8befdf8 },\n      { 0xfc0157f4,0xab919d42,0xfec8e650,0xf51caed7,0x02d48b0a,0xcdf9cb40,\n        0xce9f6478,0x854a68a5 } },\n    /* 74 */\n    { { 0x63506ea5,0xdc35f67b,0xa4fe0d66,0x9286c489,0xfe95cd4d,0x3f101d3b,\n        0x98846a95,0x5cacea0b },\n      { 0x9ceac44d,0xa90df60c,0x354d1c3a,0x3db29af4,0xad5dbabe,0x08dd3de8,\n        0x35e4efa9,0xe4982d12 } },\n    /* 75 */\n    { { 0xc34cd55e,0x23104a22,0x2680d132,0x58695bb3,0x1fa1d943,0xfb345afa,\n        0x16b20499,0x8046b7f6 },\n      { 0x38e7d098,0xb533581e,0xf46f0b70,0xd7f61e8d,0x44cb78c4,0x30dea9ea,\n        0x9082af55,0xeb17ca7b } },\n    /* 76 */\n    { { 0x76a145b9,0x1751b598,0xc1bc71ec,0xa5cf6b0f,0x392715bb,0xd3e03565,\n        0xfab5e131,0x097b00ba },\n      { 0x565f69e1,0xaa66c8e9,0xb5be5199,0x77e8f75a,0xda4fd984,0x6033ba11,\n        0xafdbcc9e,0xf95c747b } },\n    /* 77 */\n    { { 0xbebae45e,0x558f01d3,0xc4bc6955,0xa8ebe9f0,0xdbc64fc6,0xaeb705b1,\n        0x566ed837,0x3512601e },\n      { 0xfa1161cd,0x9336f1e1,0x4c65ef87,0x328ab8d5,0x724f21e5,0x4757eee2,\n        0x6068ab6b,0x0ef97123 } },\n    /* 78 */\n    { { 0x54ca4226,0x02598cf7,0xf8642c8e,0x5eede138,0x468e1790,0x48963f74,\n        0x3b4fbc95,0xfc16d933 },\n      { 0xe7c800ca,0xbe96fb31,0x2678adaa,0x13806331,0x6ff3e8b5,0x3d624497,\n        0xb95d7a17,0x14ca4af1 } },\n    /* 79 */\n    { { 0xbd2f81d5,0x7a4771ba,0x01f7d196,0x1a5f9d69,0xcad9c907,0xd898bef7,\n        0xf59c231d,0x4057b063 },\n      { 0x89c05c0a,0xbffd82fe,0x1dc0df85,0xe4911c6f,0xa35a16db,0x3befccae,\n        0xf1330b13,0x1c3b5d64 } },\n    /* 80 */\n    { { 0x80ec21fe,0x5fe14bfe,0xc255be82,0xf6ce116a,0x2f4a5d67,0x98bc5a07,\n        0xdb7e63af,0xfad27148 },\n      { 0x29ab05b3,0x90c0b6ac,0x4e251ae6,0x37a9a83c,0xc2aade7d,0x0a7dc875,\n        0x9f0e1a84,0x77387de3 } },\n    /* 81 */\n    { { 0xa56c0dd7,0x1e9ecc49,0x46086c74,0xa5cffcd8,0xf505aece,0x8f7a1408,\n        0xbef0c47e,0xb37b85c0 },\n      { 0xcc0e6a8f,0x3596b6e4,0x6b388f23,0xfd6d4bbf,0xc39cef4e,0xaba453fa,\n        0xf9f628d5,0x9c135ac8 } },\n    /* 82 */\n    { { 0x84e35743,0x32aa3202,0x85a3cdef,0x320d6ab1,0x1df19819,0xb821b176,\n        0xc433851f,0x5721361f },\n      { 0x71fc9168,0x1f0db36a,0x5e5c403c,0x5f98ba73,0x37bcd8f5,0xf64ca87e,\n        0xe6bb11bd,0xdcbac3c9 } },\n    /* 83 */\n    { { 0x4518cbe2,0xf01d9968,0x9c9eb04e,0xd242fc18,0xe47feebf,0x727663c7,\n        0x2d626862,0xb8c1c89e },\n      { 0xc8e1d569,0x51a58bdd,0xb7d88cd0,0x563809c8,0xf11f31eb,0x26c27fd9,\n        0x2f9422d4,0x5d23bbda } },\n    /* 84 */\n    { { 0x95c8f8be,0x0a1c7294,0x3bf362bf,0x2961c480,0xdf63d4ac,0x9e418403,\n        0x91ece900,0xc109f9cb },\n      { 0x58945705,0xc2d095d0,0xddeb85c0,0xb9083d96,0x7a40449b,0x84692b8d,\n        0x2eee1ee1,0x9bc3344f } },\n    /* 85 */\n    { { 0x42913074,0x0d5ae356,0x48a542b1,0x55491b27,0xb310732a,0x469ca665,\n        0x5f1a4cc1,0x29591d52 },\n      { 0xb84f983f,0xe76f5b6b,0x9f5f84e1,0xbe7eef41,0x80baa189,0x1200d496,\n        0x18ef332c,0x6376551f } },\n    /* 86 */\n    { { 0x562976cc,0xbda5f14e,0x0ef12c38,0x22bca3e6,0x6cca9852,0xbbfa3064,\n        0x08e2987a,0xbdb79dc8 },\n      { 0xcb06a772,0xfd2cb5c9,0xfe536dce,0x38f475aa,0x7c2b5db8,0xc2a3e022,\n        0xadd3c14a,0x8ee86001 } },\n    /* 87 */\n    { { 0xa4ade873,0xcbe96981,0xc4fba48c,0x7ee9aa4d,0x5a054ba5,0x2cee2899,\n        0x6f77aa4b,0x92e51d7a },\n      { 0x7190a34d,0x948bafa8,0xf6bd1ed1,0xd698f75b,0x0caf1144,0xd00ee6e3,\n        0x0a56aaaa,0x5182f86f } },\n    /* 88 */\n    { { 0x7a4cc99c,0xfba6212c,0x3e6d9ca1,0xff609b68,0x5ac98c5a,0x5dbb27cb,\n        0x4073a6f2,0x91dcab5d },\n      { 0x5f575a70,0x01b6cc3d,0x6f8d87fa,0x0cb36139,0x89981736,0x165d4e8c,\n        0x97974f2b,0x17a0cedb } },\n    /* 89 */\n    { { 0x076c8d3a,0x38861e2a,0x210f924b,0x701aad39,0x13a835d9,0x94d0eae4,\n        0x7f4cdf41,0x2e8ce36c },\n      { 0x037a862b,0x91273dab,0x60e4c8fa,0x01ba9bb7,0x33baf2dd,0xf9645388,\n        0x34f668f3,0xf4ccc6cb } },\n    /* 90 */\n    { { 0xf1f79687,0x44ef525c,0x92efa815,0x7c595495,0xa5c78d29,0xe1231741,\n        0x9a0df3c9,0xac0db488 },\n      { 0xdf01747f,0x86bfc711,0xef17df13,0x592b9358,0x5ccb6bb5,0xe5880e4f,\n        0x94c974a2,0x95a64a61 } },\n    /* 91 */\n    { { 0xc15a4c93,0x72c1efda,0x82585141,0x40269b73,0x16cb0bad,0x6a8dfb1c,\n        0x29210677,0x231e54ba },\n      { 0x8ae6d2dc,0xa70df917,0x39112918,0x4d6aa63f,0x5e5b7223,0xf627726b,\n        0xd8a731e1,0xab0be032 } },\n    /* 92 */\n    { { 0x8d131f2d,0x097ad0e9,0x3b04f101,0x637f09e3,0xd5e9a748,0x1ac86196,\n        0x2cf6a679,0xf1bcc880 },\n      { 0xe8daacb4,0x25c69140,0x60f65009,0x3c4e4055,0x477937a6,0x591cc8fc,\n        0x5aebb271,0x85169469 } },\n    /* 93 */\n    { { 0xf1dcf593,0xde35c143,0xb018be3b,0x78202b29,0x9bdd9d3d,0xe9cdadc2,\n        0xdaad55d8,0x8f67d9d2 },\n      { 0x7481ea5f,0x84111656,0xe34c590c,0xe7d2dde9,0x05053fa8,0xffdd43f4,\n        0xc0728b5d,0xf84572b9 } },\n    /* 94 */\n    { { 0x97af71c9,0x5e1a7a71,0x7a736565,0xa1449444,0x0e1d5063,0xa1b4ae07,\n        0x616b2c19,0xedee2710 },\n      { 0x11734121,0xb2f034f5,0x4a25e9f0,0x1cac6e55,0xa40c2ecf,0x8dc148f3,\n        0x44ebd7f4,0x9fd27e9b } },\n    /* 95 */\n    { { 0xf6e2cb16,0x3cc7658a,0xfe5919b6,0xe3eb7d2c,0x168d5583,0x5a8c5816,\n        0x958ff387,0xa40c2fb6 },\n      { 0xfedcc158,0x8c9ec560,0x55f23056,0x7ad804c6,0x9a307e12,0xd9396704,\n        0x7dc6decf,0x99bc9bb8 } },\n    /* 96 */\n    { { 0x927dafc6,0x84a9521d,0x5c09cd19,0x52c1fb69,0xf9366dde,0x9d9581a0,\n        0xa16d7e64,0x9abe210b },\n      { 0x48915220,0x480af84a,0x4dd816c6,0xfa73176a,0x1681ca5a,0xc7d53987,\n        0x87f344b0,0x7881c257 } },\n    /* 97 */\n    { { 0xe0bcf3ff,0x93399b51,0x127f74f6,0x0d02cbc5,0xdd01d968,0x8fb465a2,\n        0xa30e8940,0x15e6e319 },\n      { 0x3e0e05f4,0x646d6e0d,0x43588404,0xfad7bddc,0xc4f850d3,0xbe61c7d1,\n        0x191172ce,0x0e55facf } },\n    /* 98 */\n    { { 0xf8787564,0x7e9d9806,0x31e85ce6,0x1a331721,0xb819e8d6,0x6b0158ca,\n        0x6fe96577,0xd73d0976 },\n      { 0x1eb7206e,0x42483425,0xc618bb42,0xa519290f,0x5e30a520,0x5dcbb859,\n        0x8f15a50b,0x9250a374 } },\n    /* 99 */\n    { { 0xbe577410,0xcaff08f8,0x5077a8c6,0xfd408a03,0xec0a63a4,0xf1f63289,\n        0xc1cc8c0b,0x77414082 },\n      { 0xeb0991cd,0x05a40fa6,0x49fdc296,0xc1ca0866,0xb324fd40,0x3a68a3c7,\n        0x12eb20b9,0x8cb04f4d } },\n    /* 100 */\n    { { 0x6906171c,0xb1c2d055,0xb0240c3f,0x9073e9cd,0xd8906841,0xdb8e6b4f,\n        0x47123b51,0xe4e429ef },\n      { 0x38ec36f4,0x0b8dd53c,0xff4b6a27,0xf9d2dc01,0x879a9a48,0x5d066e07,\n        0x3c6e6552,0x37bca2ff } },\n    /* 101 */\n    { { 0xdf562470,0x4cd2e3c7,0xc0964ac9,0x44f272a2,0x80c793be,0x7c6d5df9,\n        0x3002b22a,0x59913edc },\n      { 0x5750592a,0x7a139a83,0xe783de02,0x99e01d80,0xea05d64f,0xcf8c0375,\n        0xb013e226,0x43786e4a } },\n    /* 102 */\n    { { 0x9e56b5a6,0xff32b0ed,0xd9fc68f9,0x0750d9a6,0x597846a7,0xec15e845,\n        0xb7e79e7a,0x8638ca98 },\n      { 0x0afc24b2,0x2f5ae096,0x4dace8f2,0x05398eaf,0xaecba78f,0x3b765dd0,\n        0x7b3aa6f0,0x1ecdd36a } },\n    /* 103 */\n    { { 0x6c5ff2f3,0x5d3acd62,0x2873a978,0xa2d516c0,0xd2110d54,0xad94c9fa,\n        0xd459f32d,0xd85d0f85 },\n      { 0x10b11da3,0x9f700b8d,0xa78318c4,0xd2c22c30,0x9208decd,0x556988f4,\n        0xb4ed3c62,0xa04f19c3 } },\n    /* 104 */\n    { { 0xed7f93bd,0x087924c8,0x392f51f6,0xcb64ac5d,0x821b71af,0x7cae330a,\n        0x5c0950b0,0x92b2eeea },\n      { 0x85b6e235,0x85ac4c94,0x2936c0f0,0xab2ca4a9,0xe0508891,0x80faa6b3,\n        0x5834276c,0x1ee78221 } },\n    /* 105 */\n    { { 0xe63e79f7,0xa60a2e00,0xf399d906,0xf590e7b2,0x6607c09d,0x9021054a,\n        0x57a6e150,0xf3f2ced8 },\n      { 0xf10d9b55,0x200510f3,0xd8642648,0x9d2fcfac,0xe8bd0e7c,0xe5631aa7,\n        0x3da3e210,0x0f56a454 } },\n    /* 106 */\n    { { 0x1043e0df,0x5b21bffa,0x9c007e6d,0x6c74b6cc,0xd4a8517a,0x1a656ec0,\n        0x1969e263,0xbd8f1741 },\n      { 0xbeb7494a,0x8a9bbb86,0x45f3b838,0x1567d46f,0xa4e5a79a,0xdf7a12a7,\n        0x30ccfa09,0x2d1a1c35 } },\n    /* 107 */\n    { { 0x506508da,0x192e3813,0xa1d795a7,0x336180c4,0x7a9944b3,0xcddb5949,\n        0xb91fba46,0xa107a65e },\n      { 0x0f94d639,0xe6d1d1c5,0x8a58b7d7,0x8b4af375,0xbd37ca1c,0x1a7c5584,\n        0xf87a9af2,0x183d760a } },\n    /* 108 */\n    { { 0x0dde59a4,0x29d69711,0x0e8bef87,0xf1ad8d07,0x4f2ebe78,0x229b4963,\n        0xc269d754,0x1d44179d },\n      { 0x8390d30e,0xb32dc0cf,0x0de8110c,0x0a3b2753,0x2bc0339a,0x31af1dc5,\n        0x9606d262,0x771f9cc2 } },\n    /* 109 */\n    { { 0x85040739,0x99993e77,0x8026a939,0x44539db9,0xf5f8fc26,0xcf40f6f2,\n        0x0362718e,0x64427a31 },\n      { 0x85428aa8,0x4f4f2d87,0xebfb49a8,0x7b7adc3f,0xf23d01ac,0x201b2c6d,\n        0x6ae90d6d,0x49d9b749 } },\n    /* 110 */\n    { { 0x435d1099,0xcc78d8bc,0x8e8d1a08,0x2adbcd4e,0x2cb68a41,0x02c2e2a0,\n        0x3f605445,0x9037d81b },\n      { 0x074c7b61,0x7cdbac27,0x57bfd72e,0xfe2031ab,0x596d5352,0x61ccec96,\n        0x7cc0639c,0x08c3de6a } },\n    /* 111 */\n    { { 0xf6d552ab,0x20fdd020,0x05cd81f1,0x56baff98,0x91351291,0x06fb7c3e,\n        0x45796b2f,0xc6909442 },\n      { 0x41231bd1,0x17b3ae9c,0x5cc58205,0x1eac6e87,0xf9d6a122,0x208837ab,\n        0xcafe3ac0,0x3fa3db02 } },\n    /* 112 */\n    { { 0x05058880,0xd75a3e65,0x643943f2,0x7da365ef,0xfab24925,0x4147861c,\n        0xfdb808ff,0xc5c4bdb0 },\n      { 0xb272b56b,0x73513e34,0x11b9043a,0xc8327e95,0xf8844969,0xfd8ce37d,\n        0x46c2b6b5,0x2d56db94 } },\n    /* 113 */\n    { { 0xff46ac6b,0x2461782f,0x07a2e425,0xd19f7926,0x09a48de1,0xfafea3c4,\n        0xe503ba42,0x0f56bd9d },\n      { 0x345cda49,0x137d4ed1,0x816f299d,0x821158fc,0xaeb43402,0xe7c6a54a,\n        0x1173b5f1,0x4003bb9d } },\n    /* 114 */\n    { { 0xa0803387,0x3b8e8189,0x39cbd404,0xece115f5,0xd2877f21,0x4297208d,\n        0xa07f2f9e,0x53765522 },\n      { 0xa8a4182d,0xa4980a21,0x3219df79,0xa2bbd07a,0x1a19a2d4,0x674d0a2e,\n        0x6c5d4549,0x7a056f58 } },\n    /* 115 */\n    { { 0x9d8a2a47,0x646b2558,0xc3df2773,0x5b582948,0xabf0d539,0x51ec000e,\n        0x7a1a2675,0x77d482f1 },\n      { 0x87853948,0xb8a1bd95,0x6cfbffee,0xa6f817bd,0x80681e47,0xab6ec057,\n        0x2b38b0e4,0x4115012b } },\n    /* 116 */\n    { { 0x6de28ced,0x3c73f0f4,0x9b13ec47,0x1d5da760,0x6e5c6392,0x61b8ce9e,\n        0xfbea0946,0xcdf04572 },\n      { 0x6c53c3b0,0x1cb3c58b,0x447b843c,0x97fe3c10,0x2cb9780e,0xfb2b8ae1,\n        0x97383109,0xee703dda } },\n    /* 117 */\n    { { 0xff57e43a,0x34515140,0xb1b811b8,0xd44660d3,0x8f42b986,0x2b3b5dff,\n        0xa162ce21,0x2a0ad89d },\n      { 0x6bc277ba,0x64e4a694,0xc141c276,0xc788c954,0xcabf6274,0x141aa64c,\n        0xac2b4659,0xd62d0b67 } },\n    /* 118 */\n    { { 0x2c054ac4,0x39c5d87b,0xf27df788,0x57005859,0xb18128d6,0xedf7cbf3,\n        0x991c2426,0xb39a23f2 },\n      { 0xf0b16ae5,0x95284a15,0xa136f51b,0x0c6a05b1,0xf2700783,0x1d63c137,\n        0xc0674cc5,0x04ed0092 } },\n    /* 119 */\n    { { 0x9ae90393,0x1f4185d1,0x4a3d64e6,0x3047b429,0x9854fc14,0xae0001a6,\n        0x0177c387,0xa0a91fc1 },\n      { 0xae2c831e,0xff0a3f01,0x2b727e16,0xbb76ae82,0x5a3075b4,0x8f12c8a1,\n        0x9ed20c41,0x084cf988 } },\n    /* 120 */\n    { { 0xfca6becf,0xd98509de,0x7dffb328,0x2fceae80,0x4778e8b9,0x5d8a15c4,\n        0x73abf77e,0xd57955b2 },\n      { 0x31b5d4f1,0x210da79e,0x3cfa7a1c,0xaa52f04b,0xdc27c20b,0xd4d12089,\n        0x02d141f1,0x8e14ea42 } },\n    /* 121 */\n    { { 0xf2897042,0xeed50345,0x43402c4a,0x8d05331f,0xc8bdfb21,0xc8d9c194,\n        0x2aa4d158,0x597e1a37 },\n      { 0xcf0bd68c,0x0327ec1a,0xab024945,0x6d4be0dc,0xc9fe3e84,0x5b9c8d7a,\n        0x199b4dea,0xca3f0236 } },\n    /* 122 */\n    { { 0x6170bd20,0x592a10b5,0x6d3f5de7,0x0ea897f1,0x44b2ade2,0xa3363ff1,\n        0x309c07e4,0xbde7fd7e },\n      { 0xb8f5432c,0x516bb6d2,0xe043444b,0x210dc1cb,0xf8f95b5a,0x3db01e6f,\n        0x0a7dd198,0xb623ad0e } },\n    /* 123 */\n    { { 0x60c7b65b,0xa75bd675,0x23a4a289,0xab8c5590,0xd7b26795,0xf8220fd0,\n        0x58ec137b,0xd6aa2e46 },\n      { 0x5138bb85,0x10abc00b,0xd833a95c,0x8c31d121,0x1702a32e,0xb24ff00b,\n        0x2dcc513a,0x111662e0 } },\n    /* 124 */\n    { { 0xefb42b87,0x78114015,0x1b6c4dff,0xbd9f5d70,0xa7d7c129,0x66ecccd7,\n        0x94b750f8,0xdb3ee1cb },\n      { 0xf34837cf,0xb26f3db0,0xb9578d4f,0xe7eed18b,0x7c56657d,0x5d2cdf93,\n        0x52206a59,0x886a6442 } },\n    /* 125 */\n    { { 0x65b569ea,0x3c234cfb,0xf72119c1,0x20011141,0xa15a619e,0x8badc85d,\n        0x018a17bc,0xa70cf4eb },\n      { 0x8c4a6a65,0x224f97ae,0x0134378f,0x36e5cf27,0x4f7e0960,0xbe3a609e,\n        0xd1747b77,0xaa4772ab } },\n    /* 126 */\n    { { 0x7aa60cc0,0x67676131,0x0368115f,0xc7916361,0xbbc1bb5a,0xded98bb4,\n        0x30faf974,0x611a6ddc },\n      { 0xc15ee47a,0x30e78cbc,0x4e0d96a5,0x2e896282,0x3dd9ed88,0x36f35adf,\n        0x16429c88,0x5cfffaf8 } },\n    /* 127 */\n    { { 0x9b7a99cd,0xc0d54cff,0x843c45a1,0x7bf3b99d,0x62c739e1,0x038a908f,\n        0x7dc1994c,0x6e5a6b23 },\n      { 0x0ba5db77,0xef8b454e,0xacf60d63,0xb7b8807f,0x76608378,0xe591c0c6,\n        0x242dabcc,0x481a238d } },\n    /* 128 */\n    { { 0x35d0b34a,0xe3417bc0,0x8327c0a7,0x440b386b,0xac0362d1,0x8fb7262d,\n        0xe0cdf943,0x2c41114c },\n      { 0xad95a0b1,0x2ba5cef1,0x67d54362,0xc09b37a8,0x01e486c9,0x26d6cdd2,\n        0x42ff9297,0x20477abf } },\n    /* 129 */\n    { { 0x18d65dbf,0x2f75173c,0x339edad8,0x77bf940e,0xdcf1001c,0x7022d26b,\n        0xc77396b6,0xac66409a },\n      { 0xc6261cc3,0x8b0bb36f,0x190e7e90,0x213f7bc9,0xa45e6c10,0x6541ceba,\n        0xcc122f85,0xce8e6975 } },\n    /* 130 */\n    { { 0xbc0a67d2,0x0f121b41,0x444d248a,0x62d4760a,0x659b4737,0x0e044f1d,\n        0x250bb4a8,0x08fde365 },\n      { 0x848bf287,0xaceec3da,0xd3369d6e,0xc2a62182,0x92449482,0x3582dfdc,\n        0x565d6cd7,0x2f7e2fd2 } },\n    /* 131 */\n    { { 0xc3770fa7,0xae4b92db,0x379043f9,0x095e8d5c,0x17761171,0x54f34e9d,\n        0x907702ae,0xc65be92e },\n      { 0xf6fd0a40,0x2758a303,0xbcce784b,0xe7d822e3,0x4f9767bf,0x7ae4f585,\n        0xd1193b3a,0x4bff8e47 } },\n    /* 132 */\n    { { 0x00ff1480,0xcd41d21f,0x0754db16,0x2ab8fb7d,0xbbe0f3ea,0xac81d2ef,\n        0x5772967d,0x3e4e4ae6 },\n      { 0x3c5303e6,0x7e18f36d,0x92262397,0x3bd9994b,0x1324c3c0,0x9ed70e26,\n        0x58ec6028,0x5388aefd } },\n    /* 133 */\n    { { 0x5e5d7713,0xad1317eb,0x75de49da,0x09b985ee,0xc74fb261,0x32f5bc4f,\n        0x4f75be0e,0x5cf908d1 },\n      { 0x8e657b12,0x76043510,0xb96ed9e6,0xbfd421a5,0x8970ccc2,0x0e29f51f,\n        0x60f00ce2,0xa698ba40 } },\n    /* 134 */\n    { { 0xef748fec,0x73db1686,0x7e9d2cf9,0xe6e755a2,0xce265eff,0x630b6544,\n        0x7aebad8d,0xb142ef8a },\n      { 0x17d5770a,0xad31af9f,0x2cb3412f,0x66af3b67,0xdf3359de,0x6bd60d1b,\n        0x58515075,0xd1896a96 } },\n    /* 135 */\n    { { 0x33c41c08,0xec5957ab,0x5468e2e1,0x87de94ac,0xac472f6c,0x18816b73,\n        0x7981da39,0x267b0e0b },\n      { 0x8e62b988,0x6e554e5d,0x116d21e7,0xd8ddc755,0x3d2a6f99,0x4610faf0,\n        0xa1119393,0xb54e287a } },\n    /* 136 */\n    { { 0x178a876b,0x0a0122b5,0x085104b4,0x51ff96ff,0x14f29f76,0x050b31ab,\n        0x5f87d4e6,0x84abb28b },\n      { 0x8270790a,0xd5ed439f,0x85e3f46b,0x2d6cb59d,0x6c1e2212,0x75f55c1b,\n        0x17655640,0xe5436f67 } },\n    /* 137 */\n    { { 0x2286e8d5,0x53f9025e,0x864453be,0x353c95b4,0xe408e3a0,0xd832f5bd,\n        0x5b9ce99e,0x0404f68b },\n      { 0xa781e8e5,0xcad33bde,0x163c2f5b,0x3cdf5018,0x0119caa3,0x57576960,\n        0x0ac1c701,0x3a4263df } },\n    /* 138 */\n    { { 0x9aeb596d,0xc2965ecc,0x023c92b4,0x01ea03e7,0x2e013961,0x4704b4b6,\n        0x905ea367,0x0ca8fd3f },\n      { 0x551b2b61,0x92523a42,0x390fcd06,0x1eb7a89c,0x0392a63e,0xe7f1d2be,\n        0x4ddb0c33,0x96dca264 } },\n    /* 139 */\n    { { 0x387510af,0x203bb43a,0xa9a36a01,0x846feaa8,0x2f950378,0xd23a5770,\n        0x3aad59dc,0x4363e212 },\n      { 0x40246a47,0xca43a1c7,0xe55dd24d,0xb362b8d2,0x5d8faf96,0xf9b08604,\n        0xd8bb98c4,0x840e115c } },\n    /* 140 */\n    { { 0x1023e8a7,0xf12205e2,0xd8dc7a0b,0xc808a8cd,0x163a5ddf,0xe292a272,\n        0x30ded6d4,0x5e0d6abd },\n      { 0x7cfc0f64,0x07a721c2,0x0e55ed88,0x42eec01d,0x1d1f9db2,0x26a7bef9,\n        0x2945a25a,0x7dea48f4 } },\n    /* 141 */\n    { { 0xe5060a81,0xabdf6f1c,0xf8f95615,0xe79f9c72,0x06ac268b,0xcfd36c54,\n        0xebfd16d1,0xabc2a2be },\n      { 0xd3e2eac7,0x8ac66f91,0xd2dd0466,0x6f10ba63,0x0282d31b,0x6790e377,\n        0x6c7eefc1,0x4ea35394 } },\n    /* 142 */\n    { { 0x5266309d,0xed8a2f8d,0x81945a3e,0x0a51c6c0,0x578c5dc1,0xcecaf45a,\n        0x1c94ffc3,0x3a76e689 },\n      { 0x7d7b0d0f,0x9aace8a4,0x8f584a5f,0x963ace96,0x4e697fbe,0x51a30c72,\n        0x465e6464,0x8212a10a } },\n    /* 143 */\n    { { 0xcfab8caa,0xef7c61c3,0x0e142390,0x18eb8e84,0x7e9733ca,0xcd1dff67,\n        0x599cb164,0xaa7cab71 },\n      { 0xbc837bd1,0x02fc9273,0xc36af5d7,0xc06407d0,0xf423da49,0x17621292,\n        0xfe0617c3,0x40e38073 } },\n    /* 144 */\n    { { 0xa7bf9b7c,0xf4f80824,0x3fbe30d0,0x365d2320,0x97cf9ce3,0xbfbe5320,\n        0xb3055526,0xe3604700 },\n      { 0x6cc6c2c7,0x4dcb9911,0xba4cbee6,0x72683708,0x637ad9ec,0xdcded434,\n        0xa3dee15f,0x6542d677 } },\n    /* 145 */\n    { { 0x7b6c377a,0x3f32b6d0,0x903448be,0x6cb03847,0x20da8af7,0xd6fdd3a8,\n        0x09bb6f21,0xa6534aee },\n      { 0x1035facf,0x30a1780d,0x9dcb47e6,0x35e55a33,0xc447f393,0x6ea50fe1,\n        0xdc9aef22,0xf3cb672f } },\n    /* 146 */\n    { { 0x3b55fd83,0xeb3719fe,0x875ddd10,0xe0d7a46c,0x05cea784,0x33ac9fa9,\n        0xaae870e7,0x7cafaa2e },\n      { 0x1d53b338,0x9b814d04,0xef87e6c6,0xe0acc0a0,0x11672b0f,0xfb93d108,\n        0xb9bd522e,0x0aab13c1 } },\n    /* 147 */\n    { { 0xd2681297,0xddcce278,0xb509546a,0xcb350eb1,0x7661aaf2,0x2dc43173,\n        0x847012e9,0x4b91a602 },\n      { 0x72f8ddcf,0xdcff1095,0x9a911af4,0x08ebf61e,0xc372430e,0x48f4360a,\n        0x72321cab,0x49534c53 } },\n    /* 148 */\n    { { 0xf07b7e9d,0x83df7d71,0x13cd516f,0xa478efa3,0x6c047ee3,0x78ef264b,\n        0xd65ac5ee,0xcaf46c4f },\n      { 0x92aa8266,0xa04d0c77,0x913684bb,0xedf45466,0xae4b16b0,0x56e65168,\n        0x04c6770f,0x14ce9e57 } },\n    /* 149 */\n    { { 0x965e8f91,0x99445e3e,0xcb0f2492,0xd3aca1ba,0x90c8a0a0,0xd31cc70f,\n        0x3e4c9a71,0x1bb708a5 },\n      { 0x558bdd7a,0xd5ca9e69,0x018a26b1,0x734a0508,0x4c9cf1ec,0xb093aa71,\n        0xda300102,0xf9d126f2 } },\n    /* 150 */\n    { { 0xaff9563e,0x749bca7a,0xb49914a0,0xdd077afe,0xbf5f1671,0xe27a0311,\n        0x729ecc69,0x807afcb9 },\n      { 0xc9b08b77,0x7f8a9337,0x443c7e38,0x86c3a785,0x476fd8ba,0x85fafa59,\n        0x6568cd8c,0x751adcd1 } },\n    /* 151 */\n    { { 0x10715c0d,0x8aea38b4,0x8f7697f7,0xd113ea71,0x93fbf06d,0x665eab14,\n        0x2537743f,0x29ec4468 },\n      { 0xb50bebbc,0x3d94719c,0xe4505422,0x399ee5bf,0x8d2dedb1,0x90cd5b3a,\n        0x92a4077d,0xff9370e3 } },\n    /* 152 */\n    { { 0xc6b75b65,0x59a2d69b,0x266651c5,0x4188f8d5,0x3de9d7d2,0x28a9f33e,\n        0xa2a9d01a,0x9776478b },\n      { 0x929af2c7,0x8852622d,0x4e690923,0x334f5d6d,0xa89a51e9,0xce6cc7e5,\n        0xac2f82fa,0x74a6313f } },\n    /* 153 */\n    { { 0xb75f079c,0xb2f4dfdd,0x18e36fbb,0x85b07c95,0xe7cd36dd,0x1b6cfcf0,\n        0x0ff4863d,0xab75be15 },\n      { 0x173fc9b7,0x81b367c0,0xd2594fd0,0xb90a7420,0xc4091236,0x15fdbf03,\n        0x0b4459f6,0x4ebeac2e } },\n    /* 154 */\n    { { 0x5c9f2c53,0xeb6c5fe7,0x8eae9411,0xd2522011,0xf95ac5d8,0xc8887633,\n        0x2c1baffc,0xdf99887b },\n      { 0x850aaecb,0xbb78eed2,0x01d6a272,0x9d49181b,0xb1cdbcac,0x978dd511,\n        0x779f4058,0x27b040a7 } },\n    /* 155 */\n    { { 0xf73b2eb2,0x90405db7,0x8e1b2118,0xe0df8508,0x5962327e,0x501b7152,\n        0xe4cfa3f5,0xb393dd37 },\n      { 0x3fd75165,0xa1230e7b,0xbcd33554,0xd66344c2,0x0f7b5022,0x6c36f1be,\n        0xd0463419,0x09588c12 } },\n    /* 156 */\n    { { 0x02601c3b,0xe086093f,0xcf5c335f,0xfb0252f8,0x894aff28,0x955cf280,\n        0xdb9f648b,0x81c879a9 },\n      { 0xc6f56c51,0x040e687c,0x3f17618c,0xfed47169,0x9059353b,0x44f88a41,\n        0x5fc11bc4,0xfa0d48f5 } },\n    /* 157 */\n    { { 0xe1608e4d,0xbc6e1c9d,0x3582822c,0x010dda11,0x157ec2d7,0xf6b7ddc1,\n        0xb6a367d6,0x8ea0e156 },\n      { 0x2383b3b4,0xa354e02f,0x3f01f53c,0x69966b94,0x2de03ca5,0x4ff6632b,\n        0xfa00b5ac,0x3f5ab924 } },\n    /* 158 */\n    { { 0x59739efb,0x337bb0d9,0xe7ebec0d,0xc751b0f4,0x411a67d1,0x2da52dd6,\n        0x2b74256e,0x8bc76887 },\n      { 0x82d3d253,0xa5be3b72,0xf58d779f,0xa9f679a1,0xe16767bb,0xa1cac168,\n        0x60fcf34f,0xb386f190 } },\n    /* 159 */\n    { { 0x2fedcfc2,0x31f3c135,0x62f8af0d,0x5396bf62,0xe57288c2,0x9a02b4ea,\n        0x1b069c4d,0x4cb460f7 },\n      { 0x5b8095ea,0xae67b4d3,0x6fc07603,0x92bbf859,0xb614a165,0xe1475f66,\n        0x95ef5223,0x52c0d508 } },\n    /* 160 */\n    { { 0x15339848,0x231c210e,0x70778c8d,0xe87a28e8,0x6956e170,0x9d1de661,\n        0x2bb09c0b,0x4ac3c938 },\n      { 0x6998987d,0x19be0551,0xae09f4d6,0x8b2376c4,0x1a3f933d,0x1de0b765,\n        0xe39705f4,0x380d94c7 } },\n    /* 161 */\n    { { 0x81542e75,0x01a355aa,0xee01b9b7,0x96c724a1,0x624d7087,0x6b3a2977,\n        0xde2637af,0x2ce3e171 },\n      { 0xf5d5bc1a,0xcfefeb49,0x2777e2b5,0xa655607e,0x9513756c,0x4feaac2f,\n        0x0b624e4d,0x2e6cd852 } },\n    /* 162 */\n    { { 0x8c31c31d,0x3685954b,0x5bf21a0c,0x68533d00,0x75c79ec9,0x0bd7626e,\n        0x42c69d54,0xca177547 },\n      { 0xf6d2dbb2,0xcc6edaff,0x174a9d18,0xfd0d8cbd,0xaa4578e8,0x875e8793,\n        0x9cab2ce6,0xa976a713 } },\n    /* 163 */\n    { { 0x93fb353d,0x0a651f1b,0x57fcfa72,0xd75cab8b,0x31b15281,0xaa88cfa7,\n        0x0a1f4999,0x8720a717 },\n      { 0x693e1b90,0x8c3e8d37,0x16f6dfc3,0xd345dc0b,0xb52a8742,0x8ea8d00a,\n        0xc769893c,0x9719ef29 } },\n    /* 164 */\n    { { 0x58e35909,0x820eed8d,0x33ddc116,0x9366d8dc,0x6e205026,0xd7f999d0,\n        0xe15704c1,0xa5072976 },\n      { 0xc4e70b2e,0x002a37ea,0x6890aa8a,0x84dcf657,0x645b2a5c,0xcd71bf18,\n        0xf7b77725,0x99389c9d } },\n    /* 165 */\n    { { 0x7ada7a4b,0x238c08f2,0xfd389366,0x3abe9d03,0x766f512c,0x6b672e89,\n        0x202c82e4,0xa88806aa },\n      { 0xd380184e,0x6602044a,0x126a8b85,0xa8cb78c4,0xad844f17,0x79d670c0,\n        0x4738dcfe,0x0043bffb } },\n    /* 166 */\n    { { 0x36d5192e,0x8d59b5dc,0x4590b2af,0xacf885d3,0x11601781,0x83566d0a,\n        0xba6c4866,0x52f3ef01 },\n      { 0x0edcb64d,0x3986732a,0x8068379f,0x0a482c23,0x7040f309,0x16cbe5fa,\n        0x9ef27e75,0x3296bd89 } },\n    /* 167 */\n    { { 0x454d81d7,0x476aba89,0x51eb9b3c,0x9eade7ef,0x81c57986,0x619a21cd,\n        0xaee571e9,0x3b90febf },\n      { 0x5496f7cb,0x9393023e,0x7fb51bc4,0x55be41d8,0x99beb5ce,0x03f1dd48,\n        0x9f810b18,0x6e88069d } },\n    /* 168 */\n    { { 0xb43ea1db,0xce37ab11,0x5259d292,0x0a7ff1a9,0x8f84f186,0x851b0221,\n        0xdefaad13,0xa7222bea },\n      { 0x2b0a9144,0xa2ac78ec,0xf2fa59c5,0x5a024051,0x6147ce38,0x91d1eca5,\n        0xbc2ac690,0xbe94d523 } },\n    /* 169 */\n    { { 0x0b226ce7,0x72f4945e,0x967e8b70,0xb8afd747,0x85a6c63e,0xedea46f1,\n        0x9be8c766,0x7782defe },\n      { 0x3db38626,0x760d2aa4,0x76f67ad1,0x460ae787,0x54499cdb,0x341b86fc,\n        0xa2892e4b,0x03838567 } },\n    /* 170 */\n    { { 0x79ec1a0f,0x2d8daefd,0xceb39c97,0x3bbcd6fd,0x58f61a95,0xf5575ffc,\n        0xadf7b420,0xdbd986c4 },\n      { 0x15f39eb7,0x81aa8814,0xb98d976c,0x6ee2fcf5,0xcf2f717d,0x5465475d,\n        0x6860bbd0,0x8e24d3c4 } },\n    /* 171 */\n    { { 0x9a587390,0x749d8e54,0x0cbec588,0x12bb194f,0xb25983c6,0x46e07da4,\n        0x407bafc8,0x541a99c4 },\n      { 0x624c8842,0xdb241692,0xd86c05ff,0x6044c12a,0x4f7fcf62,0xc59d14b4,\n        0xf57d35d1,0xc0092c49 } },\n    /* 172 */\n    { { 0xdf2e61ef,0xd3cc75c3,0x2e1b35ca,0x7e8841c8,0x909f29f4,0xc62d30d1,\n        0x7286944d,0x75e40634 },\n      { 0xbbc237d0,0xe7d41fc5,0xec4f01c9,0xc9537bf0,0x282bd534,0x91c51a16,\n        0xc7848586,0x5b7cb658 } },\n    /* 173 */\n    { { 0x8a28ead1,0x964a7084,0xfd3b47f6,0x802dc508,0x767e5b39,0x9ae4bfd1,\n        0x8df097a1,0x7ae13eba },\n      { 0xeadd384e,0xfd216ef8,0xb6b2ff06,0x0361a2d9,0x4bcdb5f3,0x204b9878,\n        0xe2a8e3fd,0x787d8074 } },\n    /* 174 */\n    { { 0x757fbb1c,0xc5e25d6b,0xca201deb,0xe47bddb2,0x6d2233ff,0x4a55e9a3,\n        0x9ef28484,0x5c222819 },\n      { 0x88315250,0x773d4a85,0x827097c1,0x21b21a2b,0xdef5d33f,0xab7c4ea1,\n        0xbaf0f2b0,0xe45d37ab } },\n    /* 175 */\n    { { 0x28511c8a,0xd2df1e34,0xbdca6cd3,0xebb229c8,0x627c39a7,0x578a71a7,\n        0x84dfb9d3,0xed7bc122 },\n      { 0x93dea561,0xcf22a6df,0xd48f0ed1,0x5443f18d,0x5bad23e8,0xd8b86140,\n        0x45ca6d27,0xaac97cc9 } },\n    /* 176 */\n    { { 0xa16bd00a,0xeb54ea74,0xf5c0bcc1,0xd839e9ad,0x1f9bfc06,0x092bb7f1,\n        0x1163dc4e,0x318f97b3 },\n      { 0xc30d7138,0xecc0c5be,0xabc30220,0x44e8df23,0xb0223606,0x2bb7972f,\n        0x9a84ff4d,0xfa41faa1 } },\n    /* 177 */\n    { { 0xa6642269,0x4402d974,0x9bb783bd,0xc81814ce,0x7941e60b,0x398d38e4,\n        0x1d26e9e2,0x38bb6b2c },\n      { 0x6a577f87,0xc64e4a25,0xdc11fe1c,0x8b52d253,0x62280728,0xff336abf,\n        0xce7601a5,0x94dd0905 } },\n    /* 178 */\n    { { 0xde93f92a,0x156cf7dc,0x89b5f315,0xa01333cb,0xc995e750,0x02404df9,\n        0xd25c2ae9,0x92077867 },\n      { 0x0bf39d44,0xe2471e01,0x96bb53d7,0x5f2c9020,0x5c9c3d8f,0x4c44b7b3,\n        0xd29beb51,0x81e8428b } },\n    /* 179 */\n    { { 0xc477199f,0x6dd9c2ba,0x6b5ecdd9,0x8cb8eeee,0xee40fd0e,0x8af7db3f,\n        0xdbbfa4b1,0x1b94ab62 },\n      { 0xce47f143,0x44f0d8b3,0x63f46163,0x51e623fc,0xcc599383,0xf18f270f,\n        0x055590ee,0x06a38e28 } },\n    /* 180 */\n    { { 0xb3355b49,0x2e5b0139,0xb4ebf99b,0x20e26560,0xd269f3dc,0xc08ffa6b,\n        0x83d9d4f8,0xa7b36c20 },\n      { 0x1b3e8830,0x64d15c3a,0xa89f9c0b,0xd5fceae1,0xe2d16930,0xcfeee4a2,\n        0xa2822a20,0xbe54c6b4 } },\n    /* 181 */\n    { { 0x8d91167c,0xd6cdb3df,0xe7a6625e,0x517c3f79,0x346ac7f4,0x7105648f,\n        0xeae022bb,0xbf30a5ab },\n      { 0x93828a68,0x8e7785be,0x7f3ef036,0x5161c332,0x592146b2,0xe11b5feb,\n        0x2732d13a,0xd1c820de } },\n    /* 182 */\n    { { 0x9038b363,0x043e1347,0x6b05e519,0x58c11f54,0x6026cad1,0x4fe57abe,\n        0x68a18da3,0xb7d17bed },\n      { 0xe29c2559,0x44ca5891,0x5bfffd84,0x4f7a0376,0x74e46948,0x498de4af,\n        0x6412cc64,0x3997fd5e } },\n    /* 183 */\n    { { 0x8bd61507,0xf2074682,0x34a64d2a,0x29e132d5,0x8a8a15e3,0xffeddfb0,\n        0x3c6c13e8,0x0eeb8929 },\n      { 0xa7e259f8,0xe9b69a3e,0xd13e7e67,0xce1db7e6,0xad1fa685,0x277318f6,\n        0xc922b6ef,0x228916f8 } },\n    /* 184 */\n    { { 0x0a12ab5b,0x959ae25b,0x957bc136,0xcc11171f,0xd16e2b0c,0x8058429e,\n        0x6e93097e,0xec05ad1d },\n      { 0xac3f3708,0x157ba5be,0x30b59d77,0x31baf935,0x118234e5,0x47b55237,\n        0x7ff11b37,0x7d314156 } },\n    /* 185 */\n    { { 0xf6dfefab,0x7bd9c05c,0xdcb37707,0xbe2f2268,0x3a38bb95,0xe53ead97,\n        0x9bc1d7a3,0xe9ce66fc },\n      { 0x6f6a02a1,0x75aa1576,0x60e600ed,0x38c087df,0x68cdc1b9,0xf8947f34,\n        0x72280651,0xd9650b01 } },\n    /* 186 */\n    { { 0x5a057e60,0x504b4c4a,0x8def25e4,0xcbccc3be,0x17c1ccbd,0xa6353208,\n        0x804eb7a2,0x14d6699a },\n      { 0xdb1f411a,0x2c8a8415,0xf80d769c,0x09fbaf0b,0x1c2f77ad,0xb4deef90,\n        0x0d43598a,0x6f4c6841 } },\n    /* 187 */\n    { { 0x96c24a96,0x8726df4e,0xfcbd99a3,0x534dbc85,0x8b2ae30a,0x3c466ef2,\n        0x61189abb,0x4c4350fd },\n      { 0xf855b8da,0x2967f716,0x463c38a1,0x41a42394,0xeae93343,0xc37e1413,\n        0x5a3118b5,0xa726d242 } },\n    /* 188 */\n    { { 0x948c1086,0xdae6b3ee,0xcbd3a2e1,0xf1de503d,0x03d022f3,0x3f35ed3f,\n        0xcc6cf392,0x13639e82 },\n      { 0xcdafaa86,0x9ac938fb,0x2654a258,0xf45bc5fb,0x45051329,0x1963b26e,\n        0xc1a335a3,0xca9365e1 } },\n    /* 189 */\n    { { 0x4c3b2d20,0x3615ac75,0x904e241b,0x742a5417,0xcc9d071d,0xb08521c4,\n        0x970b72a5,0x9ce29c34 },\n      { 0x6d3e0ad6,0x8cc81f73,0xf2f8434c,0x8060da9e,0x6ce862d9,0x35ed1d1a,\n        0xab42af98,0x48c4abd7 } },\n    /* 190 */\n    { { 0x40c7485a,0xd221b0cc,0xe5274dbf,0xead455bb,0x9263d2e8,0x493c7698,\n        0xf67b33cb,0x78017c32 },\n      { 0x930cb5ee,0xb9d35769,0x0c408ed2,0xc0d14e94,0x272f1a4d,0xf8b7bf55,\n        0xde5c1c04,0x53cd0454 } },\n    /* 191 */\n    { { 0x5d28ccac,0xbcd585fa,0x005b746e,0x5f823e56,0xcd0123aa,0x7c79f0a1,\n        0xd3d7fa8f,0xeea465c1 },\n      { 0x0551803b,0x7810659f,0x7ce6af70,0x6c0b599f,0x29288e70,0x4195a770,\n        0x7ae69193,0x1b6e42a4 } },\n    /* 192 */\n    { { 0xf67d04c3,0x2e80937c,0x89eeb811,0x1e312be2,0x92594d60,0x56b5d887,\n        0x187fbd3d,0x0224da14 },\n      { 0x0c5fe36f,0x87abb863,0x4ef51f5f,0x580f3c60,0xb3b429ec,0x964fb1bf,\n        0x42bfff33,0x60838ef0 } },\n    /* 193 */\n    { { 0x7e0bbe99,0x432cb2f2,0x04aa39ee,0x7bda44f3,0x9fa93903,0x5f497c7a,\n        0x2d331643,0x636eb202 },\n      { 0x93ae00aa,0xfcfd0e61,0x31ae6d2f,0x875a00fe,0x9f93901c,0xf43658a2,\n        0x39218bac,0x8844eeb6 } },\n    /* 194 */\n    { { 0x6b3bae58,0x114171d2,0x17e39f3e,0x7db3df71,0x81a8eada,0xcd37bc7f,\n        0x51fb789e,0x27ba83dc },\n      { 0xfbf54de5,0xa7df439f,0xb5fe1a71,0x7277030b,0xdb297a48,0x42ee8e35,\n        0x87f3a4ab,0xadb62d34 } },\n    /* 195 */\n    { { 0xa175df2a,0x9b1168a2,0x618c32e9,0x082aa04f,0x146b0916,0xc9e4f2e7,\n        0x75e7c8b2,0xb990fd76 },\n      { 0x4df37313,0x0829d96b,0xd0b40789,0x1c205579,0x78087711,0x66c9ae4a,\n        0x4d10d18d,0x81707ef9 } },\n    /* 196 */\n    { { 0x03d6ff96,0x97d7cab2,0x0d843360,0x5b851bfc,0xd042db4b,0x268823c4,\n        0xd5a8aa5c,0x3792daea },\n      { 0x941afa0b,0x52818865,0x42d83671,0xf3e9e741,0x5be4e0a7,0x17c82527,\n        0x94b001ba,0x5abd635e } },\n    /* 197 */\n    { { 0x0ac4927c,0x727fa84e,0xa7c8cf23,0xe3886035,0x4adca0df,0xa4bcd5ea,\n        0x846ab610,0x5995bf21 },\n      { 0x829dfa33,0xe90f860b,0x958fc18b,0xcaafe2ae,0x78630366,0x9b3baf44,\n        0xd483411e,0x44c32ca2 } },\n    /* 198 */\n    { { 0xe40ed80c,0xa74a97f1,0x31d2ca82,0x5f938cb1,0x7c2d6ad9,0x53f2124b,\n        0x8082a54c,0x1f2162fb },\n      { 0x720b173e,0x7e467cc5,0x085f12f9,0x40e8a666,0x4c9d65dc,0x8cebc20e,\n        0xc3e907c9,0x8f1d402b } },\n    /* 199 */\n    { { 0xfbc4058a,0x4f592f9c,0x292f5670,0xb15e14b6,0xbc1d8c57,0xc55cfe37,\n        0x926edbf9,0xb1980f43 },\n      { 0x32c76b09,0x98c33e09,0x33b07f78,0x1df5279d,0x863bb461,0x6f08ead4,\n        0x37448e45,0x2828ad9b } },\n    /* 200 */\n    { { 0xc4cf4ac5,0x696722c4,0xdde64afb,0xf5ac1a3f,0xe0890832,0x0551baa2,\n        0x5a14b390,0x4973f127 },\n      { 0x322eac5d,0xe59d8335,0x0bd9b568,0x5e07eef5,0xa2588393,0xab36720f,\n        0xdb168ac7,0x6dac8ed0 } },\n    /* 201 */\n    { { 0xeda835ef,0xf7b545ae,0x1d10ed51,0x4aa113d2,0x13741b09,0x035a65e0,\n        0x20b9de4c,0x4b23ef59 },\n      { 0x3c4c7341,0xe82bb680,0x3f58bc37,0xd457706d,0xa51e3ee8,0x73527863,\n        0xddf49a4e,0x4dd71534 } },\n    /* 202 */\n    { { 0x95476cd9,0xbf944672,0xe31a725b,0x648d072f,0xfc4b67e0,0x1441c8b8,\n        0x2f4a4dbb,0xfd317000 },\n      { 0x8995d0e1,0x1cb43ff4,0x0ef729aa,0x76e695d1,0x41798982,0xe0d5f976,\n        0x9569f365,0x14fac58c } },\n    /* 203 */\n    { { 0xf312ae18,0xad9a0065,0xfcc93fc9,0x51958dc0,0x8a7d2846,0xd9a14240,\n        0x36abda50,0xed7c7651 },\n      { 0x25d4abbc,0x46270f1a,0xf1a113ea,0x9b5dd8f3,0x5b51952f,0xc609b075,\n        0x4d2e9f53,0xfefcb7f7 } },\n    /* 204 */\n    { { 0xba119185,0xbd09497a,0xaac45ba4,0xd54e8c30,0xaa521179,0x492479de,\n        0x87e0d80b,0x1801a57e },\n      { 0xfcafffb0,0x073d3f8d,0xae255240,0x6cf33c0b,0x5b5fdfbc,0x781d763b,\n        0x1ead1064,0x9f8fc11e } },\n    /* 205 */\n    { { 0x5e69544c,0x1583a171,0xf04b7813,0x0eaf8567,0x278a4c32,0x1e22a8fd,\n        0x3d3a69a9,0xa9d3809d },\n      { 0x59a2da3b,0x936c2c2c,0x1895c847,0x38ccbcf6,0x63d50869,0x5e65244e,\n        0xe1178ef7,0x3006b9ae } },\n    /* 206 */\n    { { 0xc9eead28,0x0bb1f2b0,0x89f4dfbc,0x7eef635d,0xb2ce8939,0x074757fd,\n        0x45f8f761,0x0ab85fd7 },\n      { 0x3e5b4549,0xecda7c93,0x97922f21,0x4be2bb5c,0xb43b8040,0x261a1274,\n        0x11e942c2,0xb122d675 } },\n    /* 207 */\n    { { 0x66a5ae7a,0x3be607be,0x76adcbe3,0x01e703fa,0x4eb6e5c5,0xaf904301,\n        0x097dbaec,0x9f599dc1 },\n      { 0x0ff250ed,0x6d75b718,0x349a20dc,0x8eb91574,0x10b227a3,0x425605a4,\n        0x8a294b78,0x7d5528e0 } },\n    /* 208 */\n    { { 0x20c26def,0xf0f58f66,0x582b2d1e,0x025585ea,0x01ce3881,0xfbe7d79b,\n        0x303f1730,0x28ccea01 },\n      { 0x79644ba5,0xd1dabcd1,0x06fff0b8,0x1fc643e8,0x66b3e17b,0xa60a76fc,\n        0xa1d013bf,0xc18baf48 } },\n    /* 209 */\n    { { 0x5dc4216d,0x34e638c8,0x206142ac,0x00c01067,0x95f5064a,0xd453a171,\n        0xb7a9596b,0x9def809d },\n      { 0x67ab8d2c,0x41e8642e,0x6237a2b6,0xb4240433,0x64c4218b,0x7d506a6d,\n        0x68808ce5,0x0357f8b0 } },\n    /* 210 */\n    { { 0x4cd2cc88,0x8e9dbe64,0xf0b8f39d,0xcc61c28d,0xcd30a0c8,0x4a309874,\n        0x1b489887,0xe4a01add },\n      { 0xf57cd8f9,0x2ed1eeac,0xbd594c48,0x1b767d3e,0x7bd2f787,0xa7295c71,\n        0xce10cc30,0x466d7d79 } },\n    /* 211 */\n    { { 0x9dada2c7,0x47d31892,0x8f9aa27d,0x4fa0a6c3,0x820a59e1,0x90e4fd28,\n        0x451ead1a,0xc672a522 },\n      { 0x5d86b655,0x30607cc8,0xf9ad4af1,0xf0235d3b,0x571172a6,0x99a08680,\n        0xf2a67513,0x5e3d64fa } },\n    /* 212 */\n    { { 0x9b3b4416,0xaa6410c7,0xeab26d99,0xcd8fcf85,0xdb656a74,0x5ebff74a,\n        0xeb8e42fc,0x6c8a7a95 },\n      { 0xb02a63bd,0x10c60ba7,0x8b8f0047,0x6b2f2303,0x312d90b0,0x8c6c3738,\n        0xad82ca91,0x348ae422 } },\n    /* 213 */\n    { { 0x5ccda2fb,0x7f474663,0x8e0726d2,0x22accaa1,0x492b1f20,0x85adf782,\n        0xd9ef2d2e,0xc1074de0 },\n      { 0xae9a65b3,0xfcf3ce44,0x05d7151b,0xfd71e4ac,0xce6a9788,0xd4711f50,\n        0xc9e54ffc,0xfbadfbdb } },\n    /* 214 */\n    { { 0x20a99363,0x1713f1cd,0x6cf22775,0xb915658f,0x24d359b2,0x968175cd,\n        0x83716fcd,0xb7f976b4 },\n      { 0x5d6dbf74,0x5758e24d,0x71c3af36,0x8d23bafd,0x0243dfe3,0x48f47760,\n        0xcafcc805,0xf4d41b2e } },\n    /* 215 */\n    { { 0xfdabd48d,0x51f1cf28,0x32c078a4,0xce81be36,0x117146e9,0x6ace2974,\n        0xe0160f10,0x180824ea },\n      { 0x66e58358,0x0387698b,0xce6ca358,0x63568752,0x5e41e6c5,0x82380e34,\n        0x83cf6d25,0x67e5f639 } },\n    /* 216 */\n    { { 0xcf4899ef,0xf89ccb8d,0x9ebb44c0,0x949015f0,0xb2598ec9,0x546f9276,\n        0x04c11fc6,0x9fef789a },\n      { 0x53d2a071,0x6d367ecf,0xa4519b09,0xb10e1a7f,0x611e2eef,0xca6b3fb0,\n        0xa99c4e20,0xbc80c181 } },\n    /* 217 */\n    { { 0xe5eb82e6,0x972536f8,0xf56cb920,0x1a484fc7,0x50b5da5e,0xc78e2171,\n        0x9f8cdf10,0x49270e62 },\n      { 0xea6b50ad,0x1a39b7bb,0xa2388ffc,0x9a0284c1,0x8107197b,0x5403eb17,\n        0x61372f7f,0xd2ee52f9 } },\n    /* 218 */\n    { { 0x88e0362a,0xd37cd285,0x8fa5d94d,0x442fa8a7,0xa434a526,0xaff836e5,\n        0xe5abb733,0xdfb478be },\n      { 0x673eede6,0xa91f1ce7,0x2b5b2f04,0xa5390ad4,0x5530da2f,0x5e66f7bf,\n        0x08df473a,0xd9a140b4 } },\n    /* 219 */\n    { { 0x6e8ea498,0x0e0221b5,0x3563ee09,0x62347829,0x335d2ade,0xe06b8391,\n        0x623f4b1a,0x760c058d },\n      { 0xc198aa79,0x0b89b58c,0xf07aba7f,0xf74890d2,0xfde2556a,0x4e204110,\n        0x8f190409,0x7141982d } },\n    /* 220 */\n    { { 0x4d4b0f45,0x6f0a0e33,0x392a94e1,0xd9280b38,0xb3c61d5e,0x3af324c6,\n        0x89d54e47,0x3af9d1ce },\n      { 0x20930371,0xfd8f7981,0x21c17097,0xeda2664c,0xdc42309b,0x0e9545dc,\n        0x73957dd6,0xb1f815c3 } },\n    /* 221 */\n    { { 0x89fec44a,0x84faa78e,0x3caa4caf,0xc8c2ae47,0xc1b6a624,0x691c807d,\n        0x1543f052,0xa41aed14 },\n      { 0x7d5ffe04,0x42435399,0x625b6e20,0x8bacb2df,0x87817775,0x85d660be,\n        0x86fb60ef,0xd6e9c1dd } },\n    /* 222 */\n    { { 0xc6853264,0x3aa2e97e,0xe2304a0b,0x771533b7,0xb8eae9be,0x1b912bb7,\n        0xae9bf8c2,0x9c9c6e10 },\n      { 0xe030b74c,0xa2309a59,0x6a631e90,0x4ed7494d,0xa49b79f2,0x89f44b23,\n        0x40fa61b6,0x566bd596 } },\n    /* 223 */\n    { { 0xc18061f3,0x066c0118,0x7c83fc70,0x190b25d3,0x27273245,0xf05fc8e0,\n        0xf525345e,0xcf2c7390 },\n      { 0x10eb30cf,0xa09bceb4,0x0d77703a,0xcfd2ebba,0x150ff255,0xe842c43a,\n        0x8aa20979,0x02f51755 } },\n    /* 224 */\n    { { 0xaddb7d07,0x396ef794,0x24455500,0x0b4fc742,0xc78aa3ce,0xfaff8eac,\n        0xe8d4d97d,0x14e9ada5 },\n      { 0x2f7079e2,0xdaa480a1,0xe4b0800e,0x45baa3cd,0x7838157d,0x01765e2d,\n        0x8e9d9ae8,0xa0ad4fab } },\n    /* 225 */\n    { { 0x4a653618,0x0bfb7621,0x31eaaa5f,0x1872813c,0x44949d5e,0x1553e737,\n        0x6e56ed1e,0xbcd530b8 },\n      { 0x32e9c47b,0x169be853,0xb50059ab,0xdc2776fe,0x192bfbb4,0xcdba9761,\n        0x6979341d,0x909283cf } },\n    /* 226 */\n    { { 0x76e81a13,0x67b00324,0x62171239,0x9bee1a99,0xd32e19d6,0x08ed361b,\n        0xace1549a,0x35eeb7c9 },\n      { 0x7e4e5bdc,0x1280ae5a,0xb6ceec6e,0x2dcd2cd3,0x6e266bc1,0x52e4224c,\n        0x448ae864,0x9a8b2cf4 } },\n    /* 227 */\n    { { 0x09d03b59,0xf6471bf2,0xb65af2ab,0xc90e62a3,0xebd5eec9,0xff7ff168,\n        0xd4491379,0x6bdb60f4 },\n      { 0x8a55bc30,0xdadafebc,0x10097fe0,0xc79ead16,0x4c1e3bdd,0x42e19741,\n        0x94ba08a9,0x01ec3cfd } },\n    /* 228 */\n    { { 0xdc9485c2,0xba6277eb,0x22fb10c7,0x48cc9a79,0x70a28d8a,0x4f61d60f,\n        0x475464f6,0xd1acb1c0 },\n      { 0x26f36612,0xd26902b1,0xe0618d8b,0x59c3a44e,0x308357ee,0x4df8a813,\n        0x405626c2,0x7dcd079d } },\n    /* 229 */\n    { { 0xf05a4b48,0x5ce7d4d3,0x37230772,0xadcd2952,0x812a915a,0xd18f7971,\n        0x377d19b8,0x0bf53589 },\n      { 0x6c68ea73,0x35ecd95a,0x823a584d,0xc7f3bbca,0xf473a723,0x9fb674c6,\n        0xe16686fc,0xd28be4d9 } },\n    /* 230 */\n    { { 0x38fa8e4b,0x5d2b9906,0x893fd8fc,0x559f186e,0x436fb6fc,0x3a6de2aa,\n        0x510f88ce,0xd76007aa },\n      { 0x523a4988,0x2d10aab6,0x74dd0273,0xb455cf44,0xa3407278,0x7f467082,\n        0xb303bb01,0xf2b52f68 } },\n    /* 231 */\n    { { 0x9835b4ca,0x0d57eafa,0xbb669cbc,0x2d2232fc,0xc6643198,0x8eeeb680,\n        0xcc5aed3a,0xd8dbe98e },\n      { 0xc5a02709,0xcba9be3f,0xf5ba1fa8,0x30be68e5,0xf10ea852,0xfebd43cd,\n        0xee559705,0xe01593a3 } },\n    /* 232 */\n    { { 0xea75a0a6,0xd3e5af50,0x57858033,0x512226ac,0xd0176406,0x6fe6d50f,\n        0xaeb8ef06,0xafec07b1 },\n      { 0x80bb0a31,0x7fb99567,0x37309aae,0x6f1af3cc,0x01abf389,0x9153a15a,\n        0x6e2dbfdd,0xa71b9354 } },\n    /* 233 */\n    { { 0x18f593d2,0xbf8e12e0,0xa078122b,0xd1a90428,0x0ba4f2ad,0x150505db,\n        0x628523d9,0x53a2005c },\n      { 0xe7f2b935,0x07c8b639,0xc182961a,0x2bff975a,0x7518ca2c,0x86bceea7,\n        0x3d588e3d,0xbf47d19b } },\n    /* 234 */\n    { { 0xdd7665d5,0x672967a7,0x2f2f4de5,0x4e303057,0x80d4903f,0x144005ae,\n        0x39c9a1b6,0x001c2c7f },\n      { 0x69efc6d6,0x143a8014,0x7bc7a724,0xc810bdaa,0xa78150a4,0x5f65670b,\n        0x86ffb99b,0xfdadf8e7 } },\n    /* 235 */\n    { { 0xffc00785,0xfd38cb88,0x3b48eb67,0x77fa7591,0xbf368fbc,0x0454d055,\n        0x5aa43c94,0x3a838e4d },\n      { 0x3e97bb9a,0x56166329,0x441d94d9,0x9eb93363,0x0adb2a83,0x515591a6,\n        0x873e1da3,0x3cdb8257 } },\n    /* 236 */\n    { { 0x7de77eab,0x137140a9,0x41648109,0xf7e1c50d,0xceb1d0df,0x762dcad2,\n        0xf1f57fba,0x5a60cc89 },\n      { 0x40d45673,0x80b36382,0x5913c655,0x1b82be19,0xdd64b741,0x057284b8,\n        0xdbfd8fc0,0x922ff56f } },\n    /* 237 */\n    { { 0xc9a129a1,0x1b265dee,0xcc284e04,0xa5b1ce57,0xcebfbe3c,0x04380c46,\n        0xf6c5cd62,0x72919a7d },\n      { 0x8fb90f9a,0x298f453a,0x88e4031b,0xd719c00b,0x796f1856,0xe32c0e77,\n        0x3624089a,0x5e791780 } },\n    /* 238 */\n    { { 0x7f63cdfb,0x5c16ec55,0xf1cae4fd,0x8e6a3571,0x560597ca,0xfce26bea,\n        0xe24c2fab,0x4e0a5371 },\n      { 0xa5765357,0x276a40d3,0x0d73a2b4,0x3c89af44,0x41d11a32,0xb8f370ae,\n        0xd56604ee,0xf5ff7818 } },\n    /* 239 */\n    { { 0x1a09df21,0xfbf3e3fe,0xe66e8e47,0x26d5d28e,0x29c89015,0x2096bd0a,\n        0x533f5e64,0xe41df0e9 },\n      { 0xb3ba9e3f,0x305fda40,0x2604d895,0xf2340ceb,0x7f0367c7,0x0866e192,\n        0xac4f155f,0x8edd7d6e } },\n    /* 240 */\n    { { 0x0bfc8ff3,0xc9a1dc0e,0xe936f42f,0x14efd82b,0xcca381ef,0x67016f7c,\n        0xed8aee96,0x1432c1ca },\n      { 0x70b23c26,0xec684829,0x0735b273,0xa64fe873,0xeaef0f5a,0xe389f6e5,\n        0x5ac8d2c6,0xcaef480b } },\n    /* 241 */\n    { { 0x75315922,0x5245c978,0x3063cca5,0xd8295171,0xb64ef2cb,0xf3ce60d0,\n        0x8efae236,0xd0ba177e },\n      { 0xb1b3af60,0x53a9ae8f,0x3d2da20e,0x1a796ae5,0xdf9eef28,0x01d63605,\n        0x1c54ae16,0xf31c957c } },\n    /* 242 */\n    { { 0x49cc4597,0xc0f58d52,0xbae0a028,0xdc5015b0,0x734a814a,0xefc5fc55,\n        0x96e17c3a,0x013404cb },\n      { 0xc9a824bf,0xb29e2585,0x001eaed7,0xd593185e,0x61ef68ac,0x8d6ee682,\n        0x91933e6c,0x6f377c4b } },\n    /* 243 */\n    { { 0xa8333fd2,0x9f93bad1,0x5a2a95b8,0xa8930202,0xeaf75ace,0x211e5037,\n        0xd2d09506,0x6dba3e4e },\n      { 0xd04399cd,0xa48ef98c,0xe6b73ade,0x1811c66e,0xc17ecaf3,0x72f60752,\n        0x3becf4a7,0xf13cf342 } },\n    /* 244 */\n    { { 0xa919e2eb,0xceeb9ec0,0xf62c0f68,0x83a9a195,0x7aba2299,0xcfba3bb6,\n        0x274bbad3,0xc83fa9a9 },\n      { 0x62fa1ce0,0x0d7d1b0b,0x3418efbf,0xe58b60f5,0x52706f04,0xbfa8ef9e,\n        0x5d702683,0xb49d70f4 } },\n    /* 245 */\n    { { 0xfad5513b,0x914c7510,0xb1751e2d,0x05f32eec,0xd9fb9d59,0x6d850418,\n        0x0c30f1cf,0x59cfadbb },\n      { 0x55cb7fd6,0xe167ac23,0x820426a3,0x249367b8,0x90a78864,0xeaeec58c,\n        0x354a4b67,0x5babf362 } },\n    /* 246 */\n    { { 0xee424865,0x37c981d1,0xf2e5577f,0x8b002878,0xb9e0c058,0x702970f1,\n        0x9026c8f0,0x6188c6a7 },\n      { 0xd0f244da,0x06f9a19b,0xfb080873,0x1ecced5c,0x9f213637,0x35470f9b,\n        0xdf50b9d9,0x993fe475 } },\n    /* 247 */\n    { { 0x9b2c3609,0x68e31cdf,0x2c46d4ea,0x84eb19c0,0x9a775101,0x7ac9ec1a,\n        0x4c80616b,0x81f76466 },\n      { 0x75fbe978,0x1d7c2a5a,0xf183b356,0x6743fed3,0x501dd2bf,0x838d1f04,\n        0x5fe9060d,0x564a812a } },\n    /* 248 */\n    { { 0xfa817d1d,0x7a5a64f4,0xbea82e0f,0x55f96844,0xcd57f9aa,0xb5ff5a0f,\n        0x00e51d6c,0x226bf3cf },\n      { 0x2f2833cf,0xd6d1a9f9,0x4f4f89a8,0x20a0a35a,0x8f3f7f77,0x11536c49,\n        0xff257836,0x68779f47 } },\n    /* 249 */\n    { { 0x73043d08,0x79b0c1c1,0x1fc020fa,0xa5446774,0x9a6d26d0,0xd3767e28,\n        0xeb092e0b,0x97bcb0d1 },\n      { 0xf32ed3c3,0x2ab6eaa8,0xb281bc48,0xc8a4f151,0xbfa178f3,0x4d1bf4f3,\n        0x0a784655,0xa872ffe8 } },\n    /* 250 */\n    { { 0xa32b2086,0xb1ab7935,0x8160f486,0xe1eb710e,0x3b6ae6be,0x9bd0cd91,\n        0xb732a36a,0x02812bfc },\n      { 0xcf605318,0xa63fd7ca,0xfdfd6d1d,0x646e5d50,0x2102d619,0xa1d68398,\n        0xfe5396af,0x07391cc9 } },\n    /* 251 */\n    { { 0x8b80d02b,0xc50157f0,0x62877f7f,0x6b8333d1,0x78d542ae,0x7aca1af8,\n        0x7e6d2a08,0x355d2adc },\n      { 0x287386e1,0xb41f335a,0xf8e43275,0xfd272a94,0xe79989ea,0x286ca2cd,\n        0x7c2a3a79,0x3dc2b1e3 } },\n    /* 252 */\n    { { 0x04581352,0xd689d21c,0x376782be,0x0a00c825,0x9fed701f,0x203bd590,\n        0x3ccd846b,0xc4786910 },\n      { 0x24c768ed,0x5dba7708,0x6841f657,0x72feea02,0x6accce0e,0x73313ed5,\n        0xd5bb4d32,0xccc42968 } },\n    /* 253 */\n    { { 0x3d7620b9,0x94e50de1,0x5992a56a,0xd89a5c8a,0x675487c9,0xdc007640,\n        0xaa4871cf,0xe147eb42 },\n      { 0xacf3ae46,0x274ab4ee,0x50350fbe,0xfd4936fb,0x48c840ea,0xdf2afe47,\n        0x080e96e3,0x239ac047 } },\n    /* 254 */\n    { { 0x2bfee8d4,0x481d1f35,0xfa7b0fec,0xce80b5cf,0x2ce9af3c,0x105c4c9e,\n        0xf5f7e59d,0xc55fa1a3 },\n      { 0x8257c227,0x3186f14e,0x342be00b,0xc5b1653f,0xaa904fb2,0x09afc998,\n        0xd4f4b699,0x094cd99c } },\n    /* 255 */\n    { { 0xd703beba,0x8a981c84,0x32ceb291,0x8631d150,0xe3bd49ec,0xa445f2c9,\n        0x42abad33,0xb90a30b6 },\n      { 0xb4a5abf9,0xb465404f,0x75db7603,0x004750c3,0xca35d89f,0x6f9a42cc,\n        0x1b7924f7,0x019f8b9a } },\n};\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table,\n                                      k, map, heap);\n}\n\n#endif\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[8];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 8, km);\n\n            err = sp_256_ecc_mulmod_base_8(point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_8(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                                        defined(HAVE_ECC_VERIFY)\n/* Returns 1 if the number of zero.\n * Implementation is constant time.\n *\n * a  Number to check.\n * returns 1 if the number is zero and 0 otherwise.\n */\nstatic int sp_256_iszero_8(const sp_digit* a)\n{\n    return (a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7]) == 0;\n}\n\n#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\n/* Add 1 to a. (a = a + 1)\n *\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_256_add_one_8(sp_digit* a)\n{\n    __asm__ __volatile__ (\n        \"mov\tr2, #1\\n\\t\"\n        \"ldr\tr1, [%[a], #0]\\n\\t\"\n        \"adds\tr1, r1, r2\\n\\t\"\n        \"mov\tr2, #0\\n\\t\"\n        \"str\tr1, [%[a], #0]\\n\\t\"\n        \"ldr\tr1, [%[a], #4]\\n\\t\"\n        \"adcs\tr1, r1, r2\\n\\t\"\n        \"str\tr1, [%[a], #4]\\n\\t\"\n        \"ldr\tr1, [%[a], #8]\\n\\t\"\n        \"adcs\tr1, r1, r2\\n\\t\"\n        \"str\tr1, [%[a], #8]\\n\\t\"\n        \"ldr\tr1, [%[a], #12]\\n\\t\"\n        \"adcs\tr1, r1, r2\\n\\t\"\n        \"str\tr1, [%[a], #12]\\n\\t\"\n        \"ldr\tr1, [%[a], #16]\\n\\t\"\n        \"adcs\tr1, r1, r2\\n\\t\"\n        \"str\tr1, [%[a], #16]\\n\\t\"\n        \"ldr\tr1, [%[a], #20]\\n\\t\"\n        \"adcs\tr1, r1, r2\\n\\t\"\n        \"str\tr1, [%[a], #20]\\n\\t\"\n        \"ldr\tr1, [%[a], #24]\\n\\t\"\n        \"adcs\tr1, r1, r2\\n\\t\"\n        \"str\tr1, [%[a], #24]\\n\\t\"\n        \"ldr\tr1, [%[a], #28]\\n\\t\"\n        \"adcs\tr1, r1, r2\\n\\t\"\n        \"str\tr1, [%[a], #28]\\n\\t\"\n        :\n        : [a] \"r\" (a)\n        : \"memory\", \"r1\", \"r2\"\n    );\n}\n\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 24U) {\n            r[j] &= 0xffffffff;\n            s = 32U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Generates a scalar that is in the range 1..order-1.\n *\n * rng  Random number generator.\n * k    Scalar value.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nstatic int sp_256_ecc_gen_k_8(WC_RNG* rng, sp_digit* k)\n{\n    int err;\n    byte buf[32];\n\n    do {\n        err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));\n        if (err == 0) {\n            sp_256_from_bin(k, 8, buf, (int)sizeof(buf));\n            if (sp_256_cmp_8(k, p256_order2) < 0) {\n                sp_256_add_one_8(k);\n                break;\n            }\n        }\n    }\n    while (err == 0);\n\n    return err;\n}\n\n/* Makes a random EC key pair.\n *\n * rng   Random number generator.\n * priv  Generated private value.\n * pub   Generated public point.\n * heap  Heap to use for allocation.\n * returns ECC_INF_E when the point does not have the correct order, RNG\n * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[8];\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point inf;\n#endif\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point* infinity;\n#endif\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, inf, infinity);\n    }\n#endif\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_ecc_gen_k_8(rng, k);\n    }\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);\n    }\n\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_8(infinity, point, p256_order, 1, NULL);\n    }\n    if (err == MP_OKAY) {\n        if ((sp_256_iszero_8(point->x) == 0) || (sp_256_iszero_8(point->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(k, priv);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_8(point, pub);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_ecc_point_free(infinity, 1, heap);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n\n#ifdef HAVE_ECC_DHE\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 32\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_256_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 256 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<8 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 32) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 32);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n/* Multiply the point by the scalar and serialize the X ordinate.\n * The number is 0 padded to maximum size on output.\n *\n * priv    Scalar to multiply the point by.\n * pub     Point to multiply.\n * out     Buffer to hold X ordinate.\n * outLen  On entry, size of the buffer in bytes.\n *         On exit, length of data in buffer in bytes.\n * heap    Heap to use for allocation.\n * returns BUFFER_E if the buffer is to small for output size,\n * MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out,\n                          word32* outLen, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[8];\n#endif\n    sp_point* point = NULL;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n\n    if (*outLen < 32U) {\n        err = BUFFER_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p, point);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 8, priv);\n        sp_256_point_from_ecc_point_8(point, pub);\n            err = sp_256_ecc_mulmod_8(point, point, k, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        sp_256_to_bin(point->x, out);\n        *outLen = 32;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_DHE */\n\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#ifdef WOLFSSL_SP_SMALL\n/* Sub b from a into a. (a -= b)\n *\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_256_sub_in_place_8(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n    __asm__ __volatile__ (\n        \"mov\tr7, %[a]\\n\\t\"\n        \"add\tr7, r7, #32\\n\\t\"\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        \"subs\tr5, r5, %[c]\\n\\t\"\n        \"ldr\tr3, [%[a]]\\n\\t\"\n        \"ldr\tr4, [%[a], #4]\\n\\t\"\n        \"ldr\tr5, [%[b]]\\n\\t\"\n        \"ldr\tr6, [%[b], #4]\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"str\tr3, [%[a]]\\n\\t\"\n        \"str\tr4, [%[a], #4]\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        \"add\t%[a], %[a], #8\\n\\t\"\n        \"add\t%[b], %[b], #8\\n\\t\"\n        \"cmp\t%[a], r7\\n\\t\"\n        \"bne\t1b\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n\n    return c;\n}\n\n#else\n/* Sub b from a into r. (r = a - b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static sp_digit sp_256_sub_in_place_8(sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit c = 0;\n\n    __asm__ __volatile__ (\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"subs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"ldm\t%[a], {r3, r4}\\n\\t\"\n        \"ldm\t%[b]!, {r5, r6}\\n\\t\"\n        \"sbcs\tr3, r3, r5\\n\\t\"\n        \"sbcs\tr4, r4, r6\\n\\t\"\n        \"stm\t%[a]!, {r3, r4}\\n\\t\"\n        \"sbc\t%[c], %[c], %[c]\\n\\t\"\n        : [c] \"+r\" (c), [a] \"+r\" (a), [b] \"+r\" (b)\n        :\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\"\n    );\n\n    return c;\n}\n\n#endif /* WOLFSSL_SP_SMALL */\n/* Mul a by digit b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision digit.\n */\nSP_NOINLINE static void sp_256_mul_d_8(sp_digit* r, const sp_digit* a,\n        sp_digit b)\n{\n    __asm__ __volatile__ (\n        \"add\tr8, %[a], #32\\n\\t\"\n        /* A[0] * B */\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"umull\tr5, r3, r6, %[b]\\n\\t\"\n        \"mov\tr4, #0\\n\\t\"\n        \"str\tr5, [%[r]], #4\\n\\t\"\n        /* A[0] * B - Done */\n        \"\\n1:\\n\\t\"\n        \"mov\tr5, #0\\n\\t\"\n        /* A[] * B */\n        \"ldr\tr6, [%[a]], #4\\n\\t\"\n        \"umull\tr6, r7, r6, %[b]\\n\\t\"\n        \"adds\tr3, r3, r6\\n\\t\"\n        \"adcs \tr4, r4, r7\\n\\t\"\n        \"adc\tr5, r5, #0\\n\\t\"\n        /* A[] * B - Done */\n        \"str\tr3, [%[r]], #4\\n\\t\"\n        \"mov\tr3, r4\\n\\t\"\n        \"mov\tr4, r5\\n\\t\"\n        \"cmp\t%[a], r8\\n\\t\"\n        \"blt\t1b\\n\\t\"\n        \"str\tr3, [%[r]]\\n\\t\"\n        : [r] \"+r\" (r), [a] \"+r\" (a)\n        : [b] \"r\" (b)\n        : \"memory\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\"\n    );\n}\n\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n *\n * Note that this is an approximate div. It may give an answer 1 larger.\n */\nSP_NOINLINE static sp_digit div_256_word_8(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    sp_digit r = 0;\n\n    __asm__ __volatile__ (\n        \"lsr\tr6, %[div], #16\\n\\t\"\n        \"add\tr6, r6, #1\\n\\t\"\n        \"udiv\tr4, %[d1], r6\\n\\t\"\n        \"lsl\tr7, r4, #16\\n\\t\"\n        \"umull\tr4, r5, %[div], r7\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"udiv\tr5, %[d1], r6\\n\\t\"\n        \"lsl\tr4, r5, #16\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"lsl\tr4, %[d1], #16\\n\\t\"\n        \"orr\tr4, r4, %[d0], lsr #16\\n\\t\"\n        \"udiv\tr4, r4, r6\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"lsl\tr4, %[d1], #16\\n\\t\"\n        \"orr\tr4, r4, %[d0], lsr #16\\n\\t\"\n        \"udiv\tr4, r4, r6\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"umull\tr4, r5, %[div], r4\\n\\t\"\n        \"subs\t%[d0], %[d0], r4\\n\\t\"\n        \"sbc\t%[d1], %[d1], r5\\n\\t\"\n        \"udiv\tr4, %[d0], %[div]\\n\\t\"\n        \"add\tr7, r7, r4\\n\\t\"\n        \"mov\t%[r], r7\\n\\t\"\n        : [r] \"+r\" (r)\n        : [d1] \"r\" (d1), [d0] \"r\" (d0), [div] \"r\" (div)\n        : \"r4\", \"r5\", \"r6\", \"r7\"\n    );\n    return r;\n}\n\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_256_mask_8(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<8; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    r[0] = a[0] & m;\n    r[1] = a[1] & m;\n    r[2] = a[2] & m;\n    r[3] = a[3] & m;\n    r[4] = a[4] & m;\n    r[5] = a[5] & m;\n    r[6] = a[6] & m;\n    r[7] = a[7] & m;\n#endif\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_256_div_8(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[16], t2[9];\n    sp_digit div, r1;\n    int i;\n\n    (void)m;\n\n    div = d[7];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 8);\n    for (i=7; i>=0; i--) {\n        r1 = div_256_word_8(t1[8 + i], t1[8 + i - 1], div);\n\n        sp_256_mul_d_8(t2, d, r1);\n        t1[8 + i] += sp_256_sub_in_place_8(&t1[i], t2);\n        t1[8 + i] -= t2[8];\n        sp_256_mask_8(t2, d, t1[8 + i]);\n        t1[8 + i] += sp_256_add_8(&t1[i], &t1[i], t2);\n        sp_256_mask_8(t2, d, t1[8 + i]);\n        t1[8 + i] += sp_256_add_8(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_256_cmp_8(t1, d) >= 0;\n    sp_256_cond_sub_8(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_256_mod_8(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_256_div_8(a, m, NULL, r);\n}\n\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n#ifdef WOLFSSL_SP_SMALL\n/* Order-2 for the P256 curve. */\nstatic const uint32_t p256_order_2[8] = {\n    0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU,0xffffffffU,0xffffffffU,\n    0x00000000U,0xffffffffU\n};\n#else\n/* The low half of the order-2 of the P256 curve. */\nstatic const uint32_t p256_order_low[4] = {\n    0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU\n};\n#endif /* WOLFSSL_SP_SMALL */\n\n/* Multiply two number mod the order of P256 curve. (r = a * b mod order)\n *\n * r  Result of the multiplication.\n * a  First operand of the multiplication.\n * b  Second operand of the multiplication.\n */\nstatic void sp_256_mont_mul_order_8(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_256_mul_8(r, a, b);\n    sp_256_mont_reduce_order_8(r, p256_order, p256_mp_order);\n}\n\n/* Square number mod the order of P256 curve. (r = a * a mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_order_8(sp_digit* r, const sp_digit* a)\n{\n    sp_256_sqr_8(r, a);\n    sp_256_mont_reduce_order_8(r, p256_order, p256_mp_order);\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Square number mod the order of P256 curve a number of times.\n * (r = a ^ n mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_n_order_8(sp_digit* r, const sp_digit* a, int n)\n{\n    int i;\n\n    sp_256_mont_sqr_order_8(r, a);\n    for (i=1; i<n; i++) {\n        sp_256_mont_sqr_order_8(r, r);\n    }\n}\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the order of the P256 curve.\n * (r = 1 / a mod order)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a,\n        sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 8);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_order_8(t, t);\n        if ((p256_order_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t, t, a);\n        }\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 8U);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 8;\n    sp_digit* t3 = td + 4 * 8;\n    int i;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_order_8(t, a);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_order_8(t, t, a);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_order_8(t2, t, 2);\n    /* t3= a^f = t2 * t */\n    sp_256_mont_mul_order_8(t3, t2, t);\n    /* t2= a^f0 = t3 ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_order_8(t2, t3, 4);\n    /* t = a^ff = t2 * t3 */\n    sp_256_mont_mul_order_8(t, t2, t3);\n    /* t3= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_order_8(t2, t, 8);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_order_8(t, t2, t);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_order_8(t2, t, 16);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_order_8(t, t2, t);\n    /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64  */\n    sp_256_mont_sqr_n_order_8(t2, t, 64);\n    /* t2= a^ffffffff00000000ffffffff = t2 * t */\n    sp_256_mont_mul_order_8(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_order_8(t2, t2, 32);\n    /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_order_8(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6 */\n    for (i=127; i>=112; i--) {\n        sp_256_mont_sqr_order_8(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6f */\n    sp_256_mont_sqr_n_order_8(t2, t2, 4);\n    sp_256_mont_mul_order_8(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */\n    for (i=107; i>=64; i--) {\n        sp_256_mont_sqr_order_8(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */\n    sp_256_mont_sqr_n_order_8(t2, t2, 4);\n    sp_256_mont_mul_order_8(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */\n    for (i=59; i>=32; i--) {\n        sp_256_mont_sqr_order_8(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */\n    sp_256_mont_sqr_n_order_8(t2, t2, 4);\n    sp_256_mont_mul_order_8(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */\n    for (i=27; i>=0; i--) {\n        sp_256_mont_sqr_order_8(t2, t2);\n        if (((sp_digit)p256_order_low[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) {\n            sp_256_mont_mul_order_8(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */\n    sp_256_mont_sqr_n_order_8(t2, t2, 4);\n    /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */\n    sp_256_mont_mul_order_8(r, t2, t3);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\n#ifdef HAVE_ECC_SIGN\n#ifndef SP_ECC_MAX_SIG_GEN\n#define SP_ECC_MAX_SIG_GEN  64\n#endif\n\n/* Sign the hash using the private key.\n *   e = [hash, 256 bits] from binary\n *   r = (k.G)->x mod order\n *   s = (r * x + e) / k mod order\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,\n                    mp_int* rm, mp_int* sm, mp_int* km, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit ed[2*8];\n    sp_digit xd[2*8];\n    sp_digit kd[2*8];\n    sp_digit rd[2*8];\n    sp_digit td[3 * 2*8];\n    sp_point p;\n#endif\n    sp_digit* e = NULL;\n    sp_digit* x = NULL;\n    sp_digit* k = NULL;\n    sp_digit* r = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* point = NULL;\n    sp_digit carry;\n    sp_digit* s = NULL;\n    sp_digit* kInv = NULL;\n    int err = MP_OKAY;\n    int32_t c;\n    int i;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        e = d + 0 * 8;\n        x = d + 2 * 8;\n        k = d + 4 * 8;\n        r = d + 6 * 8;\n        tmp = d + 8 * 8;\n#else\n        e = ed;\n        x = xd;\n        k = kd;\n        r = rd;\n        tmp = td;\n#endif\n        s = e;\n        kInv = k;\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(e, 8, hash, (int)hashLen);\n    }\n\n    for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {\n        sp_256_from_mp(x, 8, priv);\n\n        /* New random point. */\n        if (km == NULL || mp_iszero(km)) {\n            err = sp_256_ecc_gen_k_8(rng, k);\n        }\n        else {\n            sp_256_from_mp(k, 8, km);\n            mp_zero(km);\n        }\n        if (err == MP_OKAY) {\n                err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);\n        }\n\n        if (err == MP_OKAY) {\n            /* r = point->x mod order */\n            XMEMCPY(r, point->x, sizeof(sp_digit) * 8U);\n            sp_256_norm_8(r);\n            c = sp_256_cmp_8(r, p256_order);\n            sp_256_cond_sub_8(r, r, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_8(r);\n\n            /* Conv k to Montgomery form (mod order) */\n                sp_256_mul_8(k, k, p256_norm_order);\n            err = sp_256_mod_8(k, k, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_8(k);\n            /* kInv = 1/k mod order */\n                sp_256_mont_inv_order_8(kInv, k, tmp);\n            sp_256_norm_8(kInv);\n\n            /* s = r * x + e */\n                sp_256_mul_8(x, x, r);\n            err = sp_256_mod_8(x, x, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_8(x);\n            carry = sp_256_add_8(s, e, x);\n            sp_256_cond_sub_8(s, s, p256_order, 0 - carry);\n            sp_256_norm_8(s);\n            c = sp_256_cmp_8(s, p256_order);\n            sp_256_cond_sub_8(s, s, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_8(s);\n\n            /* s = s * k^-1 mod order */\n                sp_256_mont_mul_order_8(s, s, kInv);\n            sp_256_norm_8(s);\n\n            /* Check that signature is usable. */\n            if (sp_256_iszero_8(s) == 0) {\n                break;\n            }\n        }\n    }\n\n    if (i == 0) {\n        err = RNG_FAILURE_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(r, rm);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(s, sm);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XMEMSET(d, 0, sizeof(sp_digit) * 8 * 8);\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    XMEMSET(e, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(x, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(k, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U);\n    XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 8U);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_SIGN */\n\n#ifdef HAVE_ECC_VERIFY\n/* Verify the signature values with the hash and public key.\n *   e = Truncate(hash, 256)\n *   u1 = e/s mod order\n *   u2 = r/s mod order\n *   r == (u1.G + u2.Q)->x mod order\n * Optimization: Leave point in projective form.\n *   (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')\n *   (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,\n    mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit u1d[2*8];\n    sp_digit u2d[2*8];\n    sp_digit sd[2*8];\n    sp_digit tmpd[2*8 * 5];\n    sp_point p1d;\n    sp_point p2d;\n#endif\n    sp_digit* u1 = NULL;\n    sp_digit* u2 = NULL;\n    sp_digit* s = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* p1;\n    sp_point* p2 = NULL;\n    sp_digit carry;\n    int32_t c;\n    int err;\n\n    err = sp_ecc_point_new(heap, p1d, p1);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p2d, p2);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        u1  = d + 0 * 8;\n        u2  = d + 2 * 8;\n        s   = d + 4 * 8;\n        tmp = d + 6 * 8;\n#else\n        u1 = u1d;\n        u2 = u2d;\n        s  = sd;\n        tmp = tmpd;\n#endif\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(u1, 8, hash, (int)hashLen);\n        sp_256_from_mp(u2, 8, r);\n        sp_256_from_mp(s, 8, sm);\n        sp_256_from_mp(p2->x, 8, pX);\n        sp_256_from_mp(p2->y, 8, pY);\n        sp_256_from_mp(p2->z, 8, pZ);\n\n        {\n            sp_256_mul_8(s, s, p256_norm_order);\n        }\n        err = sp_256_mod_8(s, s, p256_order);\n    }\n    if (err == MP_OKAY) {\n        sp_256_norm_8(s);\n        {\n            sp_256_mont_inv_order_8(s, s, tmp);\n            sp_256_mont_mul_order_8(u1, u1, s);\n            sp_256_mont_mul_order_8(u2, u2, s);\n        }\n\n            err = sp_256_ecc_mulmod_base_8(p1, u1, 0, heap);\n    }\n    if (err == MP_OKAY) {\n            err = sp_256_ecc_mulmod_8(p2, p2, u2, 0, heap);\n    }\n\n    if (err == MP_OKAY) {\n        {\n            sp_256_proj_point_add_8(p1, p1, p2, tmp);\n            if (sp_256_iszero_8(p1->z)) {\n                if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) {\n                    sp_256_proj_point_dbl_8(p1, p2, tmp);\n                }\n                else {\n                    /* Y ordinate is not used from here - don't set. */\n                    p1->x[0] = 0;\n                    p1->x[1] = 0;\n                    p1->x[2] = 0;\n                    p1->x[3] = 0;\n                    p1->x[4] = 0;\n                    p1->x[5] = 0;\n                    p1->x[6] = 0;\n                    p1->x[7] = 0;\n                    XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));\n                }\n            }\n        }\n\n        /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */\n        /* Reload r and convert to Montgomery form. */\n        sp_256_from_mp(u2, 8, r);\n        err = sp_256_mod_mul_norm_8(u2, u2, p256_mod);\n    }\n\n    if (err == MP_OKAY) {\n        /* u1 = r.z'.z' mod prime */\n        sp_256_mont_sqr_8(p1->z, p1->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_8(u1, u2, p1->z, p256_mod, p256_mp_mod);\n        *res = (int)(sp_256_cmp_8(p1->x, u1) == 0);\n        if (*res == 0) {\n            /* Reload r and add order. */\n            sp_256_from_mp(u2, 8, r);\n            carry = sp_256_add_8(u2, u2, p256_order);\n            /* Carry means result is greater than mod and is not valid. */\n            if (carry == 0) {\n                sp_256_norm_8(u2);\n\n                /* Compare with mod and if greater or equal then not valid. */\n                c = sp_256_cmp_8(u2, p256_mod);\n                if (c < 0) {\n                    /* Convert to Montogomery form */\n                    err = sp_256_mod_mul_norm_8(u2, u2, p256_mod);\n                    if (err == MP_OKAY) {\n                        /* u1 = (r + 1*order).z'.z' mod prime */\n                        sp_256_mont_mul_8(u1, u2, p1->z, p256_mod,\n                                                                  p256_mp_mod);\n                        *res = (int)(sp_256_cmp_8(p1->x, u1) == 0);\n                    }\n                }\n            }\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n#endif\n    sp_ecc_point_free(p1, 0, heap);\n    sp_ecc_point_free(p2, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_VERIFY */\n\n#ifdef HAVE_ECC_CHECK_KEY\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * point  EC point.\n * heap   Heap to use if dynamically allocating.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nstatic int sp_256_ecc_is_point_8(sp_point* point, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit t1d[2*8];\n    sp_digit t2d[2*8];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8 * 4, heap, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 8;\n        t2 = d + 2 * 8;\n#else\n        (void)heap;\n\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        sp_256_sqr_8(t1, point->y);\n        (void)sp_256_mod_8(t1, t1, p256_mod);\n        sp_256_sqr_8(t2, point->x);\n        (void)sp_256_mod_8(t2, t2, p256_mod);\n        sp_256_mul_8(t2, t2, point->x);\n        (void)sp_256_mod_8(t2, t2, p256_mod);\n        (void)sp_256_sub_8(t2, p256_mod, t2);\n        sp_256_mont_add_8(t1, t1, t2, p256_mod);\n\n        sp_256_mont_add_8(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_8(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_8(t1, t1, point->x, p256_mod);\n\n        if (sp_256_cmp_8(t1, p256_b) != 0) {\n            err = MP_VAL;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * pX  X ordinate of EC point.\n * pY  Y ordinate of EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nint sp_ecc_is_point_256(mp_int* pX, mp_int* pY)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point pubd;\n#endif\n    sp_point* pub;\n    byte one[1] = { 1 };\n    int err;\n\n    err = sp_ecc_point_new(NULL, pubd, pub);\n    if (err == MP_OKAY) {\n        sp_256_from_mp(pub->x, 8, pX);\n        sp_256_from_mp(pub->y, 8, pY);\n        sp_256_from_bin(pub->z, 8, one, (int)sizeof(one));\n\n        err = sp_256_ecc_is_point_8(pub, NULL);\n    }\n\n    sp_ecc_point_free(pub, 0, NULL);\n\n    return err;\n}\n\n/* Check that the private scalar generates the EC point (px, py), the point is\n * on the curve and the point has the correct order.\n *\n * pX     X ordinate of EC point.\n * pY     Y ordinate of EC point.\n * privm  Private scalar that generates EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve, ECC_INF_E if the point does not have the correct order,\n * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and\n * MP_OKAY otherwise.\n */\nint sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit privd[8];\n    sp_point pubd;\n    sp_point pd;\n#endif\n    sp_digit* priv = NULL;\n    sp_point* pub;\n    sp_point* p = NULL;\n    byte one[1] = { 1 };\n    int err;\n\n    err = sp_ecc_point_new(heap, pubd, pub);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (priv == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK))\n        priv = privd;\n#endif\n\n        sp_256_from_mp(pub->x, 8, pX);\n        sp_256_from_mp(pub->y, 8, pY);\n        sp_256_from_bin(pub->z, 8, one, (int)sizeof(one));\n        sp_256_from_mp(priv, 8, privm);\n\n        /* Check point at infinitiy. */\n        if ((sp_256_iszero_8(pub->x) != 0) &&\n            (sp_256_iszero_8(pub->y) != 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check range of X and Y */\n        if (sp_256_cmp_8(pub->x, p256_mod) >= 0 ||\n            sp_256_cmp_8(pub->y, p256_mod) >= 0) {\n            err = ECC_OUT_OF_RANGE_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check point is on curve */\n        err = sp_256_ecc_is_point_8(pub, heap);\n    }\n\n    if (err == MP_OKAY) {\n        /* Point * order = infinity */\n            err = sp_256_ecc_mulmod_8(p, pub, p256_order, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is infinity */\n        if ((sp_256_iszero_8(p->x) == 0) ||\n            (sp_256_iszero_8(p->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Base * private = point */\n            err = sp_256_ecc_mulmod_base_8(p, priv, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is public key */\n        if (sp_256_cmp_8(p->x, pub->x) != 0 ||\n            sp_256_cmp_8(p->y, pub->y) != 0) {\n            err = ECC_PRIV_KEY_E;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (priv != NULL) {\n        XFREE(priv, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(pub, 0, heap);\n\n    return err;\n}\n#endif\n#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL\n/* Add two projective EC points together.\n * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)\n *\n * pX   First EC point's X ordinate.\n * pY   First EC point's Y ordinate.\n * pZ   First EC point's Z ordinate.\n * qX   Second EC point's X ordinate.\n * qY   Second EC point's Y ordinate.\n * qZ   Second EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* qX, mp_int* qY, mp_int* qZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 8 * 5];\n    sp_point pd;\n    sp_point qd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    sp_point* q = NULL;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(NULL, qd, q);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 8, pX);\n        sp_256_from_mp(p->y, 8, pY);\n        sp_256_from_mp(p->z, 8, pZ);\n        sp_256_from_mp(q->x, 8, qX);\n        sp_256_from_mp(q->y, 8, qY);\n        sp_256_from_mp(q->z, 8, qZ);\n\n            sp_256_proj_point_add_8(p, p, q, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(q, 0, NULL);\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Double a projective EC point.\n * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 8 * 2];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 2, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 8, pX);\n        sp_256_from_mp(p->y, 8, pY);\n        sp_256_from_mp(p->z, 8, pZ);\n\n            sp_256_proj_point_dbl_8(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Map a projective EC point to affine in place.\n * pZ will be one.\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 8 * 4];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 4, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 8, pX);\n        sp_256_from_mp(p->y, 8, pY);\n        sp_256_from_mp(p->z, 8, pZ);\n\n        sp_256_map_8(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, pX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */\n#ifdef HAVE_COMP_KEY\n/* Find the square root of a number mod the prime of the curve.\n *\n * y  The number to operate on and the result.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nstatic int sp_256_mont_sqrt_8(sp_digit* y)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit t1d[2 * 8];\n    sp_digit t2d[2 * 8];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 8, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 8;\n        t2 = d + 2 * 8;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        {\n            /* t2 = y ^ 0x2 */\n            sp_256_mont_sqr_8(t2, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0x3 */\n            sp_256_mont_mul_8(t1, t2, y, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xc */\n            sp_256_mont_sqr_n_8(t2, t1, 2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xf */\n            sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xf0 */\n            sp_256_mont_sqr_n_8(t2, t1, 4, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xff */\n            sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xff00 */\n            sp_256_mont_sqr_n_8(t2, t1, 8, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffff */\n            sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xffff0000 */\n            sp_256_mont_sqr_n_8(t2, t1, 16, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff */\n            sp_256_mont_mul_8(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000000 */\n            sp_256_mont_sqr_n_8(t1, t1, 32, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001 */\n            sp_256_mont_mul_8(t1, t1, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */\n            sp_256_mont_sqr_n_8(t1, t1, 96, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */\n            sp_256_mont_mul_8(t1, t1, y, p256_mod, p256_mp_mod);\n            sp_256_mont_sqr_n_8(y, t1, 94, p256_mod, p256_mp_mod);\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Uncompress the point given the X ordinate.\n *\n * xm    X ordinate.\n * odd   Whether the Y ordinate is odd.\n * ym    Calculated Y ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit xd[2 * 8];\n    sp_digit yd[2 * 8];\n#endif\n    sp_digit* x = NULL;\n    sp_digit* y = NULL;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 8, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        x = d + 0 * 8;\n        y = d + 2 * 8;\n#else\n        x = xd;\n        y = yd;\n#endif\n\n        sp_256_from_mp(x, 8, xm);\n        err = sp_256_mod_mul_norm_8(x, x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        /* y = x^3 */\n        {\n            sp_256_mont_sqr_8(y, x, p256_mod, p256_mp_mod);\n            sp_256_mont_mul_8(y, y, x, p256_mod, p256_mp_mod);\n        }\n        /* y = x^3 - 3x */\n        sp_256_mont_sub_8(y, y, x, p256_mod);\n        sp_256_mont_sub_8(y, y, x, p256_mod);\n        sp_256_mont_sub_8(y, y, x, p256_mod);\n        /* y = x^3 - 3x + b */\n        err = sp_256_mod_mul_norm_8(x, p256_b, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        sp_256_mont_add_8(y, y, x, p256_mod);\n        /* y = sqrt(x^3 - 3x + b) */\n        err = sp_256_mont_sqrt_8(y);\n    }\n    if (err == MP_OKAY) {\n        XMEMSET(y + 8, 0, 8U * sizeof(sp_digit));\n        sp_256_mont_reduce_8(y, p256_mod, p256_mp_mod);\n        if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {\n            sp_256_mont_sub_8(y, p256_mod, y, p256_mod);\n        }\n\n        err = sp_256_to_mp(y, ym);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n#endif\n#endif /* !WOLFSSL_SP_NO_256 */\n#endif /* WOLFSSL_HAVE_SP_ECC */\n#endif /* WOLFSSL_SP_ARM_CORTEX_M_ASM */\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */\n"
  },
  {
    "path": "src/wolfcrypt/src/sp_int.c",
    "content": "/* sp_int.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/* Implementation by Sean Parkinson. */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\n#ifdef WOLFSSL_SP_MATH\n\n#include <wolfssl/wolfcrypt/sp_int.h>\n\n#if defined(WOLFSSL_HAVE_SP_DH) || defined(WOLFSSL_HAVE_SP_RSA)\n\nWOLFSSL_LOCAL int sp_ModExp_1024(sp_int* base, sp_int* exp, sp_int* mod,\n    sp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_1536(sp_int* base, sp_int* exp, sp_int* mod,\n    sp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_2048(sp_int* base, sp_int* exp, sp_int* mod,\n    sp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_3072(sp_int* base, sp_int* exp, sp_int* mod,\n    sp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_4096(sp_int* base, sp_int* exp, sp_int* mod,\n    sp_int* res);\n\n#endif\n\nint sp_get_digit_count(sp_int *a)\n{\n    int ret;\n    if (!a)\n        ret = 0;\n    else\n        ret = a->used;\n    return ret;\n}\n\n/* Initialize the big number to be zero.\n *\n * a  SP integer.\n * returns MP_OKAY always.\n */\nint sp_init(sp_int* a)\n{\n    a->used = 0;\n    a->size = SP_INT_DIGITS;\n\n    return MP_OKAY;\n}\n\n#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || (!defined(NO_DH) || defined(HAVE_ECC))\n/* Initialize up to six big numbers to be zero.\n *\n * a  SP integer.\n * b  SP integer.\n * c  SP integer.\n * d  SP integer.\n * e  SP integer.\n * f  SP integer.\n * returns MP_OKAY always.\n */\nint sp_init_multi(sp_int* a, sp_int* b, sp_int* c, sp_int* d, sp_int* e,\n                  sp_int* f)\n{\n    if (a != NULL) {\n        a->used = 0;\n        a->size = SP_INT_DIGITS;\n    }\n    if (b != NULL) {\n        b->used = 0;\n        b->size = SP_INT_DIGITS;\n    }\n    if (c != NULL) {\n        c->used = 0;\n        c->size = SP_INT_DIGITS;\n    }\n    if (d != NULL) {\n        d->used = 0;\n        d->size = SP_INT_DIGITS;\n    }\n    if (e != NULL) {\n        e->used = 0;\n        e->size = SP_INT_DIGITS;\n    }\n    if (f != NULL) {\n        f->used = 0;\n        f->size = SP_INT_DIGITS;\n    }\n\n    return MP_OKAY;\n}\n#endif\n\n/* Clear the data from the big number and set to zero.\n *\n * a  SP integer.\n */\nvoid sp_clear(sp_int* a)\n{\n    if (a != NULL) {\n        int i;\n\n        for (i=0; i<a->used; i++)\n            a->dp[i] = 0;\n        a->used = 0;\n    }\n}\n\n/* Calculate the number of 8-bit values required to represent the big number.\n *\n * a  SP integer.\n * returns the count.\n */\nint sp_unsigned_bin_size(sp_int* a)\n{\n    int size = sp_count_bits(a);\n    return (size + 7) / 8;\n}\n\n/* Convert a number as an array of bytes in big-endian format to a big number.\n *\n * a     SP integer.\n * in    Array of bytes.\n * inSz  Number of data bytes in array.\n * returns BAD_FUNC_ARG when the number is too big to fit in an SP and\n           MP_OKAY otherwise.\n */\nint sp_read_unsigned_bin(sp_int* a, const byte* in, int inSz)\n{\n    int err = MP_OKAY;\n    int i, j = 0, s = 0;\n\n    if (inSz > SP_INT_DIGITS * (int)sizeof(a->dp[0])) {\n        err = MP_VAL;\n    }\n\n    if (err == MP_OKAY) {\n        a->dp[0] = 0;\n        for (i = inSz-1; i >= 0; i--) {\n            a->dp[j] |= ((sp_int_digit)in[i]) << s;\n            if (s == DIGIT_BIT - 8) {\n                a->dp[++j] = 0;\n                s = 0;\n            }\n            else if (s > DIGIT_BIT - 8) {\n                s = DIGIT_BIT - s;\n                if (j + 1 >= a->size)\n                    break;\n                a->dp[++j] = in[i] >> s;\n                s = 8 - s;\n            }\n            else\n                s += 8;\n        }\n\n        a->used = j + 1;\n        sp_clamp(a);\n        for (j++; j < a->size; j++)\n            a->dp[j] = 0;\n    }\n\n    return err;\n}\n\n#ifdef HAVE_ECC\n/* Convert a number as string in big-endian format to a big number.\n * Only supports base-16 (hexadecimal).\n * Negative values not supported.\n *\n * a      SP integer.\n * in     NUL terminated string.\n * radix  Number of values in a digit.\n * returns BAD_FUNC_ARG when radix not supported or value is negative, MP_VAL\n * when a character is not valid and MP_OKAY otherwise.\n */\nint sp_read_radix(sp_int* a, const char* in, int radix)\n{\n    int  err = MP_OKAY;\n    int  i, j = 0, k = 0;\n    char ch;\n\n    if ((radix != 16) || (*in == '-')) {\n        err = BAD_FUNC_ARG;\n    }\n\n    while (*in == '0') {\n        in++;\n    }\n\n    if (err == MP_OKAY) {\n        a->dp[0] = 0;\n        for (i = (int)(XSTRLEN(in) - 1); i >= 0; i--) {\n            ch = in[i];\n            if (ch >= '0' && ch <= '9')\n                ch -= '0';\n            else if (ch >= 'A' && ch <= 'F')\n                ch -= 'A' - 10;\n            else if (ch >= 'a' && ch <= 'f')\n                ch -= 'a' - 10;\n            else {\n                err = MP_VAL;\n                break;\n            }\n\n            a->dp[k] |= ((sp_int_digit)ch) << j;\n            j += 4;\n            if (k >= SP_INT_DIGITS - 1) {\n                err = MP_VAL;\n                break;\n            }\n            if (j == DIGIT_BIT)\n                a->dp[++k] = 0;\n            j &= DIGIT_BIT - 1;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        a->used = k + 1;\n        if (a->dp[k] == 0)\n            a->used--;\n\n        for (k++; k < a->size; k++)\n            a->dp[k] = 0;\n\n        sp_clamp(a);\n    }\n\n    return err;\n}\n#endif\n\n/* Compare two big numbers.\n *\n * a  SP integer.\n * b  SP integer.\n * returns MP_GT if a is greater than b, MP_LT if a is less than b and MP_EQ\n * when a equals b.\n */\nint sp_cmp(sp_int* a, sp_int* b)\n{\n    int ret = MP_EQ;\n    int i;\n\n    if (a->used > b->used)\n        ret = MP_GT;\n    else if (a->used < b->used)\n        ret = MP_LT;\n    else {\n        for (i = a->used - 1; i >= 0; i--) {\n            if (a->dp[i] > b->dp[i]) {\n                ret = MP_GT;\n                break;\n            }\n            else if (a->dp[i] < b->dp[i]) {\n                ret = MP_LT;\n                break;\n            }\n        }\n    }\n    return ret;\n}\n\n/* Count the number of bits in the big number.\n *\n * a  SP integer.\n * returns the number of bits.\n */\nint sp_count_bits(sp_int* a)\n{\n    int r = 0;\n    sp_int_digit d;\n\n    r = a->used - 1;\n    while (r >= 0 && a->dp[r] == 0)\n        r--;\n    if (r < 0)\n        r = 0;\n    else {\n        d = a->dp[r];\n        r *= DIGIT_BIT;\n        while (d != 0) {\n            r++;\n            d >>= 1;\n        }\n    }\n\n    return r;\n}\n\n/* Determine if the most significant byte of the encoded big number as the top\n * bit set.\n *\n * a  SP integer.\n * returns 1 when the top bit is set and 0 otherwise.\n */\nint sp_leading_bit(sp_int* a)\n{\n    int bit = 0;\n    sp_int_digit d;\n\n    if (a->used > 0) {\n        d = a->dp[a->used - 1];\n        while (d > (sp_int_digit)0xff)\n            d >>= 8;\n        bit = (int)(d >> 7);\n    }\n\n    return bit;\n}\n\n#if !defined(NO_DH) || defined(HAVE_ECC) || defined(WC_RSA_BLINDING) || \\\n    !defined(WOLFSSL_RSA_VERIFY_ONLY)\n/* Convert the big number to an array of bytes in big-endian format.\n * The array must be large enough for encoded number - use mp_unsigned_bin_size\n * to calculate the number of bytes required.\n *\n * a    SP integer.\n * out  Array to put encoding into.\n * returns MP_OKAY always.\n */\nint sp_to_unsigned_bin(sp_int* a, byte* out)\n{\n    int i, j, b;\n\n    j = sp_unsigned_bin_size(a) - 1;\n    for (i=0; j>=0; i++) {\n        for (b = 0; b < SP_WORD_SIZE; b += 8) {\n            out[j--] = a->dp[i] >> b;\n            if (j < 0)\n                break;\n        }\n    }\n\n    return MP_OKAY;\n}\n#endif\n\n/* Convert the big number to an array of bytes in big-endian format.\n * The array must be large enough for encoded number - use mp_unsigned_bin_size\n * to calculate the number of bytes required.\n * Front-pads the output array with zeros make number the size of the array.\n *\n * a      SP integer.\n * out    Array to put encoding into.\n * outSz  Size of the array.\n * returns MP_OKAY always.\n */\nint sp_to_unsigned_bin_len(sp_int* a, byte* out, int outSz)\n{\n    int i, j, b;\n\n    j = outSz - 1;\n    for (i=0; j>=0; i++) {\n        for (b = 0; b < SP_WORD_SIZE; b += 8) {\n            out[j--] = a->dp[i] >> b;\n            if (j < 0)\n                break;\n        }\n    }\n\n    return MP_OKAY;\n}\n\n#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || (!defined(NO_DH) || defined(HAVE_ECC))\n/* Ensure the data in the big number is zeroed.\n *\n * a  SP integer.\n */\nvoid sp_forcezero(sp_int* a)\n{\n    ForceZero(a->dp, a->used * sizeof(sp_int_digit));\n    a->used = 0;\n}\n#endif\n\n#if !defined(WOLFSSL_RSA_VERIFY_ONLY) || (!defined(NO_DH) || defined(HAVE_ECC))\n/* Copy value of big number a into r.\n *\n * a  SP integer.\n * r  SP integer.\n * returns MP_OKAY always.\n */\nint sp_copy(sp_int* a, sp_int* r)\n{\n    if (a != r) {\n        XMEMCPY(r->dp, a->dp, a->used * sizeof(sp_int_digit));\n        r->used = a->used;\n    }\n    return MP_OKAY;\n}\n\n/* creates \"a\" then copies b into it */\nint sp_init_copy (sp_int * a, sp_int * b)\n{\n  int err;\n  if ((err = sp_init(a)) == MP_OKAY) {\n      if((err = sp_copy (b, a)) != MP_OKAY) {\n          sp_clear(a);\n      }\n  }\n  return err;\n}\n#endif\n\n/* Set the big number to be the value of the digit.\n *\n * a  SP integer.\n * d  Digit to be set.\n * returns MP_OKAY always.\n */\nint sp_set(sp_int* a, sp_int_digit d)\n{\n    if (d == 0) {\n      a->dp[0] = d;\n      a->used = 0;\n    }\n    else {\n      a->dp[0] = d;\n      a->used = 1;\n    }\n    return MP_OKAY;\n}\n\n#if !defined(WOLFSSL_RSA_VERIFY_ONLY) || (!defined(NO_DH) || defined(HAVE_ECC))\n/* Recalculate the number of digits used.\n *\n * a  SP integer.\n */\nvoid sp_clamp(sp_int* a)\n{\n    int i;\n\n    for (i = a->used - 1; i >= 0 && a->dp[i] == 0; i--) {\n    }\n    a->used = i + 1;\n}\n\n/* Grow big number to be able to hold l digits.\n * This function does nothing as the number of digits is fixed.\n *\n * a  SP integer.\n * l  Number of digits.\n * returns MP_MEM if the number of digits requested is more than available and\n * MP_OKAY otherwise.\n */\nint sp_grow(sp_int* a, int l)\n{\n    int err = MP_OKAY;\n\n    if (l > a->size)\n        err = MP_MEM;\n\n    return err;\n}\n\n/* Sub a one digit number from the big number.\n *\n * a  SP integer.\n * d  Digit to subtract.\n * r  SP integer - result.\n * returns MP_OKAY always.\n */\nint sp_sub_d(sp_int* a, sp_int_digit d, sp_int* r)\n{\n    int i = 0;\n    sp_int_digit t;\n\n    r->used = a->used;\n    t = a->dp[0] - d;\n    if (t > a->dp[0]) {\n        for (++i; i < a->used; i++) {\n            r->dp[i] = a->dp[i] - 1;\n            if (r->dp[i] != (sp_int_digit)-1)\n               break;\n        }\n    }\n    r->dp[0] = t;\n    if (r != a) {\n        for (++i; i < a->used; i++)\n            r->dp[i] = a->dp[i];\n    }\n    sp_clamp(r);\n\n    return MP_OKAY;\n}\n#endif\n\n/* Compare a one digit number with a big number.\n *\n * a  SP integer.\n * d  Digit to compare with.\n * returns MP_GT if a is greater than d, MP_LT if a is less than d and MP_EQ\n * when a equals d.\n */\nint sp_cmp_d(sp_int *a, sp_int_digit d)\n{\n    int ret = MP_EQ;\n\n    /* special case for zero*/\n    if (a->used == 0) {\n        if (d == 0)\n            ret = MP_EQ;\n        else\n            ret = MP_LT;\n    }\n    else if (a->used > 1)\n        ret = MP_GT;\n    else {\n        /* compare the only digit of a to d */\n        if (a->dp[0] > d)\n            ret = MP_GT;\n        else if (a->dp[0] < d)\n            ret = MP_LT;\n    }\n\n    return ret;\n}\n\n#if !defined(NO_DH) || defined(HAVE_ECC) || !defined(WOLFSSL_RSA_VERIFY_ONLY)\n/* Left shift the number by number of bits.\n * Bits may be larger than the word size.\n *\n * a  SP integer.\n * n  Number of bits to shift.\n * returns MP_OKAY always.\n */\nstatic int sp_lshb(sp_int* a, int n)\n{\n    int i;\n\n    if (n >= SP_WORD_SIZE) {\n        sp_lshd(a, n / SP_WORD_SIZE);\n        n %= SP_WORD_SIZE;\n    }\n\n    if (n != 0) {\n        a->dp[a->used] = 0;\n        for (i = a->used - 1; i >= 0; i--) {\n            a->dp[i+1] |= a->dp[i] >> (SP_WORD_SIZE - n);\n            a->dp[i] = a->dp[i] << n;\n        }\n        if (a->dp[a->used] != 0)\n            a->used++;\n    }\n\n    return MP_OKAY;\n}\n\n/* Subtract two large numbers into result: r = a - b\n * a must be greater than b.\n *\n * a  SP integer.\n * b  SP integer.\n * r  SP integer.\n * returns MP_OKAY always.\n */\nint sp_sub(sp_int* a, sp_int* b, sp_int* r)\n{\n    int i;\n    sp_int_digit c = 0;\n    sp_int_digit t;\n\n    for (i = 0; i < a->used && i < b->used; i++) {\n        t = a->dp[i] - b->dp[i] - c;\n        if (c == 0)\n            c = t > a->dp[i];\n        else\n            c = t >= a->dp[i];\n        r->dp[i] = t;\n    }\n    for (; i < a->used; i++) {\n        r->dp[i] = a->dp[i] - c;\n        c &= (r->dp[i] == (sp_int_digit)-1);\n    }\n    r->used = i;\n    sp_clamp(r);\n\n    return MP_OKAY;\n}\n\n/* Shift a right by n bits into r: r = a >> n\n *\n * a    SP integer operand.\n * n    Number of bits to shift.\n * r    SP integer result.\n */\nvoid sp_rshb(sp_int* a, int n, sp_int* r)\n{\n    int i;\n    int j;\n\n    for (i = n / SP_WORD_SIZE, j = 0; i < a->used-1; i++, j++)\n        r->dp[i] = (a->dp[j] >> n) | (a->dp[j+1] << (SP_WORD_SIZE - n));\n    r->dp[i] = a->dp[j] >> n;\n    r->used = j + 1;\n    sp_clamp(r);\n}\n\n/* Multiply a by digit n and put result into r shifting up o digits.\n *   r = (a * n) << (o * SP_WORD_SIZE)\n *\n * a  SP integer to be multiplied.\n * n  Number to multiply by.\n * r  SP integer result.\n * o  Number of digits to move result up by.\n */\nstatic void _sp_mul_d(sp_int* a, sp_int_digit n, sp_int* r, int o)\n{\n    int i;\n    sp_int_word t = 0;\n\n    for (i = 0; i < o; i++)\n        r->dp[i] = 0;\n\n    for (i = 0; i < a->used; i++) {\n        t += (sp_int_word)n * a->dp[i];\n        r->dp[i + o] = (sp_int_digit)t;\n        t >>= SP_WORD_SIZE;\n    }\n\n    r->dp[i+o] = (sp_int_digit)t;\n    r->used = i+o+1;\n    sp_clamp(r);\n}\n\n/* Divide a by d and return the quotient in r and the remainder in rem.\n *   r = a / d; rem = a % d\n *\n * a    SP integer to be divided.\n * d    SP integer to divide by.\n * r    SP integer of quotient.\n * rem  SP integer of remainder.\n * returns MP_VAL when d is 0, MP_MEM when dynamic memory allocation fails and\n *         MP_OKAY otherwise.\n */\nstatic int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem)\n{\n    int err = MP_OKAY;\n    int ret;\n    int done = 0;\n    int i;\n    int s;\n    sp_int_word w = 0;\n    sp_int_digit dt;\n    sp_int_digit t;\n#ifdef WOLFSSL_SMALL_STACK\n    sp_int* sa = NULL;\n    sp_int* sd;\n    sp_int* tr;\n    sp_int* trial;\n#else\n    sp_int sa[1];\n    sp_int sd[1];\n    sp_int tr[1];\n    sp_int trial[1];\n#endif\n\n    if (sp_iszero(d))\n        err = MP_VAL;\n\n    ret = sp_cmp(a, d);\n    if (ret == MP_LT) {\n        if (rem != NULL) {\n            sp_copy(a, rem);\n        }\n        if (r != NULL) {\n            sp_set(r, 0);\n        }\n        done = 1;\n    }\n    else if (ret == MP_EQ) {\n        if (rem != NULL) {\n            sp_set(rem, 0);\n        }\n        if (r != NULL) {\n            sp_set(r, 1);\n        }\n        done = 1;\n    }\n    else if (sp_count_bits(a) == sp_count_bits(d)) {\n        /* a is greater than d but same bit length */\n        if (rem != NULL) {\n            sp_sub(a, d, rem);\n        }\n        if (r != NULL) {\n            sp_set(r, 1);\n        }\n        done = 1;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (!done && err == MP_OKAY) {\n        sa = (sp_int*)XMALLOC(sizeof(sp_int) * 4, NULL, DYNAMIC_TYPE_BIGINT);\n        if (sa == NULL) {\n            err = MP_MEM;\n        }\n    }\n#endif\n\n    if (!done && err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        sd    = &sa[1];\n        tr    = &sa[2];\n        trial = &sa[3];\n#endif\n\n        sp_init(sa);\n        sp_init(sd);\n        sp_init(tr);\n        sp_init(trial);\n\n        s = sp_count_bits(d);\n        s = SP_WORD_SIZE - (s % SP_WORD_SIZE);\n        sp_copy(a, sa);\n        if (s != SP_WORD_SIZE) {\n            sp_lshb(sa, s);\n            sp_copy(d, sd);\n            sp_lshb(sd, s);\n            d = sd;\n        }\n\n        tr->used = sa->used - d->used + 1;\n        sp_clear(tr);\n        tr->used = sa->used - d->used + 1;\n        dt = d->dp[d->used-1];\n        for (i = sa->used - 1; i >= d->used; i--) {\n            w = ((sp_int_word)sa->dp[i] << SP_WORD_SIZE) | sa->dp[i-1];\n            w /= dt;\n            if (w > (sp_int_digit)-1) {\n                t = (sp_int_digit)-1;\n            }\n            else {\n                t = (sp_int_digit)w;\n            }\n            if (t > 0) {\n                _sp_mul_d(d, t, trial, i - d->used);\n                while (sp_cmp(trial, sa) == MP_GT) {\n                    t--;\n                    _sp_mul_d(d, t, trial, i - d->used);\n                }\n                sp_sub(sa, trial, sa);\n                tr->dp[i - d->used] += t;\n                if (tr->dp[i - d->used] < t)\n                    tr->dp[i + 1 - d->used]++;\n                if (w > (sp_int_digit)-1) {\n                    i++;\n                }\n            }\n        }\n\n        sp_clamp(tr);\n\n        if (rem != NULL) {\n            if (s != SP_WORD_SIZE)\n                sp_rshb(sa, s, sa);\n            sp_copy(sa, rem);\n        }\n        if (r != NULL)\n            sp_copy(tr, r);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (sa != NULL)\n        XFREE(sa, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n    return err;\n}\n\n\n#ifndef FREESCALE_LTC_TFM\n/* Calculate the remainder of dividing a by m: r = a mod m.\n *\n * a  SP integer.\n * m  SP integer.\n * r  SP integer.\n * returns MP_VAL when m is 0 and MP_OKAY otherwise.\n */\nint sp_mod(sp_int* a, sp_int* m, sp_int* r)\n{\n    return sp_div(a, m, NULL, r);\n}\n#endif\n#endif\n\n/* Clear all data in the big number and sets value to zero.\n *\n * a  SP integer.\n */\nvoid sp_zero(sp_int* a)\n{\n    XMEMSET(a->dp, 0, a->size * sizeof(*a->dp));\n    a->used = 0;\n}\n\n/* Add a one digit number to the big number.\n *\n * a  SP integer.\n * d  Digit to add.\n * r  SP integer - result.\n * returns MP_OKAY always.\n */\nint sp_add_d(sp_int* a, sp_int_digit d, sp_int* r)\n{\n    int i = 0;\n\n    r->used = a->used;\n    if (a->used == 0) {\n        r->used = 1;\n    }\n    r->dp[0] = a->dp[0] + d;\n    if (r->dp[i] < a->dp[i]) {\n        for (; i < a->used; i++) {\n            r->dp[i] = a->dp[i] + 1;\n            if (r->dp[i] != 0)\n               break;\n        }\n\n        if (i == a->used) {\n            r->used++;\n            r->dp[i] = 1;\n        }\n    }\n    for (; i < a->used; i++)\n        r->dp[i] = a->dp[i];\n\n    return MP_OKAY;\n}\n\n#if !defined(NO_DH) || defined(HAVE_ECC) || defined(WC_RSA_BLINDING) || \\\n    !defined(WOLFSSL_RSA_VERIFY_ONLY)\n/* Left shift the big number by a number of digits.\n * WIll chop off digits overflowing maximum size.\n *\n * a  SP integer.\n * s  Number of digits to shift.\n * returns MP_OKAY always.\n */\nint sp_lshd(sp_int* a, int s)\n{\n    if (a->used + s > a->size)\n        a->used = a->size - s;\n\n    XMEMMOVE(a->dp + s, a->dp, a->used * sizeof(sp_int_digit));\n    a->used += s;\n    XMEMSET(a->dp, 0, s * sizeof(sp_int_digit));\n    sp_clamp(a);\n\n    return MP_OKAY;\n}\n#endif\n\n#if !defined(NO_PWDBASED) || defined(WOLFSSL_KEY_GEN) || !defined(NO_DH)\n/* Add two large numbers into result: r = a + b\n *\n * a  SP integer.\n * b  SP integer.\n * r  SP integer.\n * returns MP_OKAY always.\n */\nint sp_add(sp_int* a, sp_int* b, sp_int* r)\n{\n    int i;\n    sp_int_digit c = 0;\n    sp_int_digit t;\n\n    for (i = 0; i < a->used && i < b->used; i++) {\n        t = a->dp[i] + b->dp[i] + c;\n        if (c == 0)\n            c = t < a->dp[i];\n        else\n            c = t <= a->dp[i];\n        r->dp[i] = t;\n    }\n    for (; i < a->used; i++) {\n        r->dp[i] = a->dp[i] + c;\n        c = (a->dp[i] != 0) && (r->dp[i] == 0);\n    }\n    for (; i < b->used; i++) {\n        r->dp[i] = b->dp[i] + c;\n        c = (b->dp[i] != 0) && (r->dp[i] == 0);\n    }\n    r->dp[i] = c;\n    r->used = (int)(i + c);\n\n    return MP_OKAY;\n}\n#endif /* !NO_PWDBASED || WOLFSSL_KEY_GEN || !NO_DH */\n\n#ifndef NO_RSA\n/* Set a number into the big number.\n *\n * a  SP integer.\n * b  Value to set.\n * returns MP_OKAY always.\n */\nint sp_set_int(sp_int* a, unsigned long b)\n{\n    if (b == 0) {\n        a->used = 0;\n        a->dp[0] = 0;\n    }\n    else {\n        a->used = 1;\n        a->dp[0] = b;\n    }\n\n    return MP_OKAY;\n}\n#endif /* !NO_RSA */\n\n#ifdef WC_MP_TO_RADIX\n/* Hex string characters. */\nstatic const char sp_hex_char[16] = {\n    '0', '1', '2', '3', '4', '5', '6', '7',\n    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'\n};\n\n/* Put the hex string version, big-endian, of a in str.\n *\n * a    SP integer.\n * str  Hex string is stored here.\n * returns MP_OKAY always.\n */\nint sp_tohex(sp_int* a, char* str)\n{\n    int i, j;\n\n    /* quick out if its zero */\n    if (sp_iszero(a) == MP_YES) {\n        *str++ = '0';\n        *str = '\\0';\n    }\n    else {\n        i = a->used - 1;\n        for (j = SP_WORD_SIZE - 4; j >= 0; j -= 4) {\n            if (((a->dp[i] >> j) & 0xf) != 0)\n                break;\n        }\n        for (; j >= 0; j -= 4)\n            *(str++) = sp_hex_char[(a->dp[i] >> j) & 0xf];\n        for (--i; i >= 0; i--) {\n            for (j = SP_WORD_SIZE - 4; j >= 0; j -= 4)\n                *(str++) = sp_hex_char[(a->dp[i] >> j) & 0xf];\n        }\n        *str = '\\0';\n    }\n\n    return MP_OKAY;\n}\n#endif /* WC_MP_TO_RADIX */\n\n#if defined(WOLFSSL_KEY_GEN) || !defined(NO_DH)\n/* Set a bit of a: a |= 1 << i\n * The field 'used' is updated in a.\n *\n * a  SP integer to modify.\n * i  Index of bit to set.\n * returns MP_OKAY always.\n */\nstatic int sp_set_bit(sp_int* a, int i)\n{\n    if (i / SP_WORD_SIZE < SP_INT_DIGITS) {\n        a->dp[i/SP_WORD_SIZE] |= (sp_int_digit)1 << (i % SP_WORD_SIZE);\n        if (a->used <= i / SP_WORD_SIZE)\n            a->used = (i / SP_WORD_SIZE) + 1;\n    }\n    return MP_OKAY;\n}\n\n/* Exponentiate 2 to the power of e: a = 2^e\n * This is done by setting the 'e'th bit.\n *\n * a  SP integer.\n * e  Exponent.\n * returns MP_OKAY always.\n */\nint sp_2expt(sp_int* a, int e)\n{\n    sp_zero(a);\n    return sp_set_bit(a, e);\n}\n\n/* Generate a random prime for RSA only.\n *\n * r     SP integer\n * len   Number of bytes to prime.\n * rng   Random number generator.\n * heap  Unused\n * returns MP_OKAY on success and MP_VAL when length is not supported or random\n *         number genrator fails.\n */\nint sp_rand_prime(sp_int* r, int len, WC_RNG* rng, void* heap)\n{\n    static const int USE_BBS = 1;\n    int   err = 0, type;\n    int   isPrime = MP_NO;\n\n    (void)heap;\n\n    /* get type */\n    if (len < 0) {\n        type = USE_BBS;\n        len = -len;\n    }\n    else {\n        type = 0;\n    }\n\n#if defined(WOLFSSL_HAVE_SP_DH) && defined(WOLFSSL_KEY_GEN)\n    if (len == 32) {\n    }\n    else\n#endif\n    /* Generate RSA primes that are half the modulus length. */\n#ifndef WOLFSSL_SP_NO_3072\n    if (len != 128 && len != 192)\n#else\n    if (len != 128)\n#endif\n    {\n        err = MP_VAL;\n    }\n\n    r->used = len / (SP_WORD_SIZE / 8);\n\n    /* Assume the candidate is probably prime and then test until\n     * it is proven composite. */\n    while (err == 0 && isPrime == MP_NO) {\n#ifdef SHOW_GEN\n        printf(\".\");\n        fflush(stdout);\n#endif\n        /* generate value */\n        err = wc_RNG_GenerateBlock(rng, (byte*)r->dp, len);\n        if (err != 0) {\n            err = MP_VAL;\n            break;\n        }\n\n        /* munge bits */\n        ((byte*)r->dp)[len-1] |= 0x80 | 0x40;\n        r->dp[0]              |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);\n\n        /* test */\n        /* Running Miller-Rabin up to 3 times gives us a 2^{-80} chance\n         * of a 1024-bit candidate being a false positive, when it is our\n         * prime candidate. (Note 4.49 of Handbook of Applied Cryptography.)\n         * Using 8 because we've always used 8 */\n        sp_prime_is_prime_ex(r, 8, &isPrime, rng);\n    }\n\n    return err;\n}\n\n/* Multiply a by b and store in r: r = a * b\n *\n * a  SP integer to multiply.\n * b  SP integer to multiply.\n * r  SP integer result.\n * returns MP_OKAY always.\n */\nint sp_mul(sp_int* a, sp_int* b, sp_int* r)\n{\n    int err = MP_OKAY;\n    int i;\n#ifdef WOLFSSL_SMALL_STACK\n    sp_int* t = NULL;\n    sp_int* tr;\n#else\n    sp_int t[1];\n    sp_int tr[1];\n#endif\n\n    if (a->used + b->used > SP_INT_DIGITS)\n        err = MP_VAL;\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        t = (sp_int*)XMALLOC(sizeof(sp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT);\n        if (t == NULL)\n            err = MP_MEM;\n        else\n            tr = &t[1];\n    }\n#endif\n\n    if (err == MP_OKAY) {\n        sp_init(t);\n        sp_init(tr);\n\n        for (i = 0; i < b->used; i++) {\n            _sp_mul_d(a, b->dp[i], t, i);\n            sp_add(tr, t, tr);\n        }\n        sp_copy(tr, r);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (t != NULL)\n        XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n    return err;\n}\n\n/* Square a mod m and store in r: r = (a * a) mod m\n *\n * a  SP integer to square.\n * m  SP integer modulus.\n * r  SP integer result.\n * returns MP_VAL when m is 0, MP_MEM when dynamic memory allocation fails,\n *         BAD_FUNC_ARG when a is to big and MP_OKAY otherwise.\n */\nstatic int sp_sqrmod(sp_int* a, sp_int* m, sp_int* r)\n{\n    int err = MP_OKAY;\n\n    if (a->used * 2 > SP_INT_DIGITS)\n        err = MP_VAL;\n\n    if (err == MP_OKAY)\n        err = sp_mul(a, a, r);\n    if (err == MP_OKAY)\n        err = sp_mod(r, m, r);\n\n    return err;\n}\n\n#if defined(WOLFSSL_HAVE_SP_DH) || defined(WOLFSSL_KEY_GEN)\n/* Multiply a by b mod m and store in r: r = (a * b) mod m\n *\n * a  SP integer to multiply.\n * b  SP integer to multiply.\n * m  SP integer modulus.\n * r  SP integer result.\n * returns MP_VAL when m is 0, MP_MEM when dynamic memory allocation fails and\n *         MP_OKAY otherwise.\n */\nint sp_mulmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r)\n{\n    int err = MP_OKAY;\n#ifdef WOLFSSL_SMALL_STACK\n    sp_int* t = NULL;\n#else\n    sp_int t[1];\n#endif\n\n    if (a->used + b->used > SP_INT_DIGITS)\n        err = MP_VAL;\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY) {\n        t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT);\n        if (t == NULL) {\n            err = MP_MEM;\n        }\n    }\n#endif\n    if (err == MP_OKAY) {\n        err = sp_mul(a, b, t);\n    }\n    if (err == MP_OKAY) {\n        err = sp_mod(t, m, r);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (t != NULL)\n        XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n    return err;\n}\n#endif\n\n/* Calculate a modulo the digit d into r: r = a mod d\n *\n * a  SP integer to square.\n * d  SP integer digit, modulus.\n * r  SP integer digit, result.\n * returns MP_VAL when d is 0 and MP_OKAY otherwise.\n */\nstatic int sp_mod_d(sp_int* a, const sp_int_digit d, sp_int_digit* r)\n{\n    int err = MP_OKAY;\n    int i;\n    sp_int_word w = 0;\n    sp_int_digit t;\n\n    if (d == 0)\n        err = MP_VAL;\n\n    if (err == MP_OKAY) {\n        for (i = a->used - 1; i >= 0; i--) {\n            w = (w << SP_WORD_SIZE) | a->dp[i];\n            t = (sp_int_digit)(w / d);\n            w -= (sp_int_word)t * d;\n        }\n\n        *r = (sp_int_digit)w;\n    }\n\n    return err;\n}\n\n/* Calculates the Greatest Common Denominator (GCD) of a and b into r.\n *\n * a  SP integer operand.\n * b  SP integer operand.\n * r  SP integer result.\n * returns MP_MEM when dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_gcd(sp_int* a, sp_int* b, sp_int* r)\n{\n    int err = MP_OKAY;\n#ifdef WOLFSSL_SMALL_STACK\n    sp_int* u = NULL;\n    sp_int* v;\n    sp_int* t;\n#else\n    sp_int u[1], v[1], t[1];\n#endif\n\n    if (sp_iszero(a))\n        sp_copy(b, r);\n    else if (sp_iszero(b))\n        sp_copy(a, r);\n    else {\n#ifdef WOLFSSL_SMALL_STACK\n        u = (sp_int*)XMALLOC(sizeof(sp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT);\n        if (u == NULL)\n            err = MP_MEM;\n        else {\n            v = &u[1];\n            t = &u[2];\n        }\n#endif\n\n        if (err == MP_OKAY) {\n            sp_init(u);\n            sp_init(v);\n            sp_init(t);\n\n            if (sp_cmp(a, b) != MP_LT) {\n                sp_copy(b, u);\n                /* First iteration - u = a, v = b */\n                if (b->used == 1) {\n                    err = sp_mod_d(a, b->dp[0], &v->dp[0]);\n                    if (err == MP_OKAY)\n                        v->used = (v->dp[0] != 0);\n                }\n                else\n                    err = sp_mod(a, b, v);\n            }\n            else {\n                sp_copy(a, u);\n                /* First iteration - u = b, v = a */\n                if (a->used == 1) {\n                    err = sp_mod_d(b, a->dp[0], &v->dp[0]);\n                    if (err == MP_OKAY)\n                        v->used = (v->dp[0] != 0);\n                }\n                else\n                    err = sp_mod(b, a, v);\n            }\n        }\n\n        if (err == MP_OKAY) {\n            while (!sp_iszero(v)) {\n                if (v->used == 1) {\n                    sp_mod_d(u, v->dp[0], &t->dp[0]);\n                    t->used = (t->dp[0] != 0);\n                }\n                else\n                    sp_mod(u, v, t);\n                sp_copy(v, u);\n                sp_copy(t, v);\n            }\n            sp_copy(u, r);\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (u != NULL)\n        XFREE(u, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n    return err;\n}\n\n/* Divides a by 2 and stores in r: r = a >> 1\n *\n * a  SP integer to divide.\n * r  SP integer result.\n * returns MP_OKAY always.\n */\nstatic int sp_div_2(sp_int* a, sp_int* r)\n{\n    int i;\n\n    for (i = 0; i < a->used-1; i++)\n        r->dp[i] = (a->dp[i] >> 1) | (a->dp[i+1] << (SP_WORD_SIZE - 1));\n    r->dp[i] = a->dp[i] >> 1;\n    r->used = i + 1;\n    sp_clamp(r);\n\n    return MP_OKAY;\n}\n\n\n/* Calculates the multiplicative inverse in the field.\n *\n * a  SP integer to invert.\n * m  SP integer that is the modulus of the field.\n * r  SP integer result.\n * returns MP_VAL when a or m is 0, MP_MEM when dynamic memory allocation fails\n *         and MP_OKAY otherwise.\n */\nint sp_invmod(sp_int* a, sp_int* m, sp_int* r)\n{\n    int err = MP_OKAY;\n#ifdef WOLFSSL_SMALL_STACK\n    sp_int* u = NULL;\n    sp_int* v;\n    sp_int* b;\n    sp_int* c;\n#else\n    sp_int u[1], v[1], b[1], c[1];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    u = (sp_int*)XMALLOC(sizeof(sp_int) * 4, NULL, DYNAMIC_TYPE_BIGINT);\n    if (u == NULL) {\n        err = MP_MEM;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        v = &u[1];\n        b = &u[2];\n        c = &u[3];\n#endif\n        sp_init(v);\n\n        if (sp_cmp(a, m) != MP_LT) {\n            err = sp_mod(a, m, v);\n            a = v;\n        }\n    }\n\n    /* 0 != n*m + 1 (+ve m), r*a mod 0 is always 0 (never 1)  */\n    if ((err == MP_OKAY) && (sp_iszero(a) || sp_iszero(m))) {\n        err = MP_VAL;\n    }\n    /* r*2*x != n*2*y + 1  */\n    if ((err == MP_OKAY) && sp_iseven(a) && sp_iseven(m)) {\n        err = MP_VAL;\n    }\n\n    /* 1*1 = 0*m + 1  */\n    if ((err == MP_OKAY) && sp_isone(a)) {\n        sp_set(r, 1);\n    }\n    else if (err != MP_OKAY) {\n    }\n    else if (sp_iseven(m)) {\n        /* a^-1 mod m = m + (1 - m*(m^-1 % a)) / a\n         *            = m - (m*(m^-1 % a) - 1) / a\n         */\n        err = sp_invmod(m, a, r);\n        if (err == MP_OKAY) {\n            err = sp_mul(r, m, r);\n        }\n        if (err == MP_OKAY) {\n            sp_sub_d(r, 1, r);\n            sp_div(r, a, r, NULL);\n            sp_sub(m, r, r);\n        }\n    }\n    else {\n        if (err == MP_OKAY) {\n            sp_init(u);\n            sp_init(b);\n            sp_init(c);\n\n            sp_copy(m, u);\n            sp_copy(a, v);\n            sp_zero(b);\n            sp_set(c, 1);\n\n            while (!sp_isone(v) && !sp_iszero(u)) {\n                if (sp_iseven(u)) {\n                    sp_div_2(u, u);\n                    if (sp_isodd(b)) {\n                        sp_add(b, m, b);\n                    }\n                    sp_div_2(b, b);\n                }\n                else if (sp_iseven(v)) {\n                    sp_div_2(v, v);\n                    if (sp_isodd(c)) {\n                        sp_add(c, m, c);\n                    }\n                    sp_div_2(c, c);\n                }\n                else if (sp_cmp(u, v) != MP_LT) {\n                    sp_sub(u, v, u);\n                    if (sp_cmp(b, c) == MP_LT) {\n                        sp_add(b, m, b);\n                    }\n                    sp_sub(b, c, b);\n                }\n                else {\n                    sp_sub(v, u, v);\n                    if (sp_cmp(c, b) == MP_LT) {\n                        sp_add(c, m, c);\n                    }\n                    sp_sub(c, b, c);\n                }\n            }\n            if  (sp_iszero(u)) {\n                err = MP_VAL;\n            }\n            else {\n                sp_copy(c, r);\n            }\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (u != NULL) {\n        XFREE(u, NULL, DYNAMIC_TYPE_BIGINT);\n    }\n#endif\n\n    return err;\n}\n\n/* Calculates the Lowest Common Multiple (LCM) of a and b and stores in r.\n *\n * a  SP integer operand.\n * b  SP integer operand.\n * r  SP integer result.\n * returns MP_MEM when dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_lcm(sp_int* a, sp_int* b, sp_int* r)\n{\n    int     err = MP_OKAY;\n#ifndef WOLFSSL_SMALL_STACK\n    sp_int  t[2];\n#else\n    sp_int  *t = NULL;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    t = (sp_int*)XMALLOC(sizeof(sp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT);\n    if (t == NULL) {\n        err = MP_MEM;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n        sp_init(&t[0]);\n        sp_init(&t[1]);\n        err = sp_gcd(a, b, &t[0]);\n        if (err == MP_OKAY) {\n            if (sp_cmp(a, b) == MP_GT) {\n                err = sp_div(a, &t[0], &t[1], NULL);\n                if (err == MP_OKAY)\n                    err = sp_mul(b, &t[1], r);\n            }\n            else {\n                err = sp_div(b, &t[0], &t[1], NULL);\n                if (err == MP_OKAY)\n                    err = sp_mul(a, &t[1], r);\n            }\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (t != NULL)\n        XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n    return err;\n}\n\n/* Exponentiates b to the power of e modulo m into r: r = b ^ e mod m\n *\n * b  SP integer base.\n * e  SP integer exponent.\n * m  SP integer modulus.\n * r  SP integer result.\n * returns MP_VAL when m is not 1024, 2048, 1536 or 3072 bits and otherwise\n *         MP_OKAY.\n */\nint sp_exptmod(sp_int* b, sp_int* e, sp_int* m, sp_int* r)\n{\n    int err = MP_OKAY;\n    int done = 0;\n    int mBits = sp_count_bits(m);\n    int bBits = sp_count_bits(b);\n    int eBits = sp_count_bits(e);\n\n    if (sp_iszero(m)) {\n        err = MP_VAL;\n    }\n    else if (sp_isone(m)) {\n        sp_set(r, 0);\n        done = 1;\n    }\n    else if (sp_iszero(e)) {\n        sp_set(r, 1);\n        done = 1;\n    }\n    else if (sp_iszero(b)) {\n        sp_set(r, 0);\n        done = 1;\n    }\n    else if (m->used * 2 > SP_INT_DIGITS) {\n        err = BAD_FUNC_ARG;\n    }\n\n    if (!done && (err == MP_OKAY)) {\n#ifndef WOLFSSL_SP_NO_2048\n        if ((mBits == 1024) && sp_isodd(m) && (bBits <= 1024) &&\n            (eBits <= 1024)) {\n            err = sp_ModExp_1024(b, e, m, r);\n            done = 1;\n        }\n        else if ((mBits == 2048) && sp_isodd(m) && (bBits <= 2048) &&\n                 (eBits <= 2048)) {\n            err = sp_ModExp_2048(b, e, m, r);\n            done = 1;\n        }\n        else\n#endif\n#ifndef WOLFSSL_SP_NO_3072\n        if ((mBits == 1536) && sp_isodd(m) && (bBits <= 1536) &&\n            (eBits <= 1536)) {\n            err = sp_ModExp_1536(b, e, m, r);\n            done = 1;\n        }\n        else if ((mBits == 3072) && sp_isodd(m) && (bBits <= 3072) &&\n                 (eBits <= 3072)) {\n            err = sp_ModExp_3072(b, e, m, r);\n            done = 1;\n        }\n        else\n#endif\n#ifdef WOLFSSL_SP_NO_4096\n        if ((mBits == 4096) && sp_isodd(m) && (bBits <= 4096) &&\n            (eBits <= 4096)) {\n            err = sp_ModExp_4096(b, e, m, r);\n            done = 1;\n        }\n        else\n#endif\n        {\n        }\n    }\n#if defined(WOLFSSL_HAVE_SP_DH) && defined(WOLFSSL_KEY_GEN)\n    if (!done && (err == MP_OKAY)) {\n        int i;\n\n    #ifdef WOLFSSL_SMALL_STACK\n        sp_int* t = NULL;\n    #else\n        sp_int t[1];\n    #endif\n\n    #ifdef WOLFSSL_SMALL_STACK\n        if (!done && (err == MP_OKAY)) {\n            t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT);\n            if (t == NULL) {\n                err = MP_MEM;\n            }\n        }\n    #endif\n        if (!done && (err == MP_OKAY)) {\n            sp_init(t);\n\n            if (sp_cmp(b, m) != MP_LT) {\n                err = sp_mod(b, m, t);\n                if (err == MP_OKAY && sp_iszero(t)) {\n                    sp_set(r, 0);\n                    done = 1;\n                }\n            }\n            else {\n                sp_copy(b, t);\n            }\n\n            if (!done && (err == MP_OKAY)) {\n                for (i = eBits-2; err == MP_OKAY && i >= 0; i--) {\n                     err = sp_sqrmod(t, m, t);\n                     if (err == MP_OKAY && (e->dp[i / SP_WORD_SIZE] >>\n                                                      (i % SP_WORD_SIZE)) & 1) {\n                         err = sp_mulmod(t, b, m, t);\n                     }\n                 }\n             }\n        }\n        if (!done && (err == MP_OKAY)) {\n            sp_copy(t, r);\n        }\n\n    #ifdef WOLFSSL_SMALL_STACK\n        if (t != NULL) {\n            XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n        }\n    #endif\n    }\n#else\n    if (!done && (err == MP_OKAY)) {\n        err = MP_VAL;\n    }\n#endif\n\n    (void)mBits;\n    (void)bBits;\n    (void)eBits;\n\n    return err;\n}\n\n\n/* Number of entries in array of number of least significant zero bits. */\n#define SP_LNZ_CNT      16\n/* Number of bits the array checks. */\n#define SP_LNZ_BITS     4\n/* Mask to apply to check with array. */\n#define SP_LNZ_MASK     0xf\n/* Number of least significant zero bits in first SP_LNZ_CNT numbers. */\nstatic const int lnz[SP_LNZ_CNT] = {\n   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0\n};\n\n/* Count the number of least significant zero bits.\n *\n * a  Number to check\n * retuns the count of least significant zero bits.\n */\nstatic int sp_cnt_lsb(sp_int* a)\n{\n    int i, j;\n    int cnt = 0;\n    int bc = 0;\n\n    if (!sp_iszero(a)) {\n        for (i = 0; i < a->used && a->dp[i] == 0; i++, cnt += SP_WORD_SIZE) {\n        }\n\n        for (j = 0; j < SP_WORD_SIZE; j += SP_LNZ_BITS) {\n            bc = lnz[(a->dp[i] >> j) & SP_LNZ_MASK];\n            if (bc != 4) {\n                bc += cnt + j;\n                break;\n            }\n        }\n    }\n\n    return bc;\n}\n\n/* Miller-Rabin test of \"a\" to the base of \"b\" as described in\n * HAC pp. 139 Algorithm 4.24\n *\n * Sets result to 0 if definitely composite or 1 if probably prime.\n * Randomly the chance of error is no more than 1/4 and often\n * very much lower.\n *\n * a       SP integer to check.\n * b       SP integer small prime.\n * result  Whether a is likely prime: MP_YES or MP_NO.\n * n1      SP integer operand.\n * y       SP integer operand.\n * r       SP integer operand.\n * returns MP_VAL when a is not 1024, 2048, 1536 or 3072 and MP_OKAY otherwise.\n */\nstatic int sp_prime_miller_rabin_ex(sp_int * a, sp_int * b, int *result,\n  sp_int *n1, sp_int *y, sp_int *r)\n{\n    int s, j;\n    int err = MP_OKAY;\n\n    /* default */\n    *result = MP_NO;\n\n    /* ensure b > 1 */\n    if (sp_cmp_d(b, 1) == MP_GT) {\n        /* get n1 = a - 1 */\n        sp_copy(a, n1);\n        sp_sub_d(n1, 1, n1);\n        /* set 2**s * r = n1 */\n        sp_copy(n1, r);\n\n        /* count the number of least significant bits\n         * which are zero\n         */\n        s = sp_cnt_lsb(r);\n\n        /* now divide n - 1 by 2**s */\n        sp_rshb(r, s, r);\n\n        /* compute y = b**r mod a */\n        sp_zero(y);\n\n        err = sp_exptmod(b, r, a, y);\n\n        if (err == MP_OKAY) {\n            /* probably prime until shown otherwise */\n            *result = MP_YES;\n\n            /* if y != 1 and y != n1 do */\n            if (sp_cmp_d(y, 1) != MP_EQ && sp_cmp(y, n1) != MP_EQ) {\n                j = 1;\n                /* while j <= s-1 and y != n1 */\n                while ((j <= (s - 1)) && sp_cmp(y, n1) != MP_EQ) {\n                    sp_sqrmod(y, a, y);\n\n                    /* if y == 1 then composite */\n                    if (sp_cmp_d(y, 1) == MP_EQ) {\n                        *result = MP_NO;\n                        break;\n                    }\n                    ++j;\n                }\n\n                /* if y != n1 then composite */\n                if (*result == MP_YES && sp_cmp(y, n1) != MP_EQ)\n                    *result = MP_NO;\n            }\n        }\n    }\n\n    return err;\n}\n\n/* Miller-Rabin test of \"a\" to the base of \"b\" as described in\n * HAC pp. 139 Algorithm 4.24\n *\n * Sets result to 0 if definitely composite or 1 if probably prime.\n * Randomly the chance of error is no more than 1/4 and often\n * very much lower.\n *\n * a       SP integer to check.\n * b       SP integer small prime.\n * result  Whether a is likely prime: MP_YES or MP_NO.\n * returns MP_MEM when dynamic memory allocation fails, MP_VAL when a is not\n *         1024, 2048, 1536 or 3072 and MP_OKAY otherwise.\n */\nstatic int sp_prime_miller_rabin(sp_int * a, sp_int * b, int *result)\n{\n    int err = MP_OKAY;\n#ifndef WOLFSSL_SMALL_STACK\n    sp_int  n1[1], y[1], r[1];\n#else\n    sp_int *n1 = NULL, *y, *r;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    n1 = (sp_int*)XMALLOC(sizeof(sp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT);\n    if (n1 == NULL)\n        err = MP_MEM;\n    else {\n        y = &n1[1];\n        r = &n1[2];\n    }\n#endif\n\n    if (err == MP_OKAY) {\n        sp_init(n1);\n        sp_init(y);\n        sp_init(r);\n\n        err = sp_prime_miller_rabin_ex(a, b, result, n1, y, r);\n\n        sp_clear(n1);\n        sp_clear(y);\n        sp_clear(r);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (n1 != NULL)\n        XFREE(n1, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n    return err;\n}\n\n/* Number of pre-computed primes. First n primes. */\n#define SP_PRIME_SIZE      256\n\n/* a few primes */\nstatic const sp_int_digit primes[SP_PRIME_SIZE] = {\n    0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,\n    0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,\n    0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,\n    0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083,\n    0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,\n    0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,\n    0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,\n    0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,\n\n    0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,\n    0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,\n    0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,\n    0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,\n    0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,\n    0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,\n    0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,\n    0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,\n\n    0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,\n    0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,\n    0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,\n    0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,\n    0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,\n    0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,\n    0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,\n    0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,\n\n    0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,\n    0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,\n    0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,\n    0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,\n    0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,\n    0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,\n    0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,\n    0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653\n};\n\n\n/* Check whether a is prime.\n * Checks against a number of small primes and does t iterations of\n * Miller-Rabin.\n *\n * a       SP integer to check.\n * t       Number of iterations of Muller-Rabin to perform.\n * result  MP_YES when prime.\n *         MP_NO when not prime.\n * returns MP_VAL when t is out of range, MP_MEM when dynamic memory allocation\n *         failes and otherwiese MP_OKAY.\n */\nint sp_prime_is_prime(sp_int *a, int t, int* result)\n{\n    int         err = MP_OKAY;\n    int         i;\n    int         haveRes = 0;\n#ifndef WOLFSSL_SMALL_STACK\n    sp_int      b[1];\n#else\n    sp_int      *b = NULL;\n#endif\n    sp_int_digit d;\n\n    if (t <= 0 || t > SP_PRIME_SIZE) {\n        *result = MP_NO;\n        err = MP_VAL;\n    }\n\n    if (sp_isone(a)) {\n        *result = MP_NO;\n        return MP_OKAY;\n    }\n\n    if (err == MP_OKAY && a->used == 1) {\n        /* check against primes table */\n        for (i = 0; i < SP_PRIME_SIZE; i++) {\n            if (sp_cmp_d(a, primes[i]) == MP_EQ) {\n                *result = MP_YES;\n                haveRes = 1;\n                break;\n            }\n        }\n    }\n\n    if (err == MP_OKAY && !haveRes) {\n        /* do trial division */\n        for (i = 0; i < SP_PRIME_SIZE; i++) {\n            err = sp_mod_d(a, primes[i], &d);\n            if (err != MP_OKAY || d == 0) {\n                *result = MP_NO;\n                haveRes = 1;\n                break;\n            }\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY && !haveRes) {\n        b = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT);\n        if (b == NULL)\n            err = MP_MEM;\n    }\n#endif\n\n    if (err == MP_OKAY && !haveRes) {\n        /* now do 't' miller rabins */\n        sp_init(b);\n        for (i = 0; i < t; i++) {\n            sp_set(b, primes[i]);\n            err = sp_prime_miller_rabin(a, b, result);\n            if (err != MP_OKAY || *result == MP_NO)\n                break;\n        }\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n     if (b != NULL)\n         XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n     return err;\n}\n\n/* Check whether a is prime.\n * Checks against a number of small primes and does t iterations of\n * Miller-Rabin.\n *\n * a       SP integer to check.\n * t       Number of iterations of Muller-Rabin to perform.\n * result  MP_YES when prime.\n *         MP_NO when not prime.\n * rng     Random number generator.\n * returns MP_VAL when t is out of range, MP_MEM when dynamic memory allocation\n *         failes and otherwiese MP_OKAY.\n */\nint sp_prime_is_prime_ex(sp_int* a, int t, int* result, WC_RNG* rng)\n{\n    int err = MP_OKAY;\n    int ret = MP_YES;\n    int haveRes = 0;\n    int i;\n#ifndef WC_NO_RNG\n    #ifndef WOLFSSL_SMALL_STACK\n        sp_int b[1], c[1], n1[1], y[1], r[1];\n    #else\n        sp_int *b = NULL, *c = NULL, *n1 = NULL, *y = NULL, *r = NULL;\n    #endif\n    word32 baseSz;\n#endif\n\n    if (a == NULL || result == NULL || rng == NULL)\n        err = MP_VAL;\n\n    if (sp_isone(a)) {\n        *result = MP_NO;\n        return MP_OKAY;\n    }\n\n    if (err == MP_OKAY && a->used == 1) {\n        /* check against primes table */\n        for (i = 0; i < SP_PRIME_SIZE; i++) {\n            if (sp_cmp_d(a, primes[i]) == MP_EQ) {\n                ret = MP_YES;\n                haveRes = 1;\n                break;\n            }\n        }\n    }\n\n    if (err == MP_OKAY && !haveRes) {\n        sp_int_digit d;\n\n        /* do trial division */\n        for (i = 0; i < SP_PRIME_SIZE; i++) {\n            err = sp_mod_d(a, primes[i], &d);\n            if (err != MP_OKAY || d == 0) {\n                ret = MP_NO;\n                haveRes = 1;\n                break;\n            }\n        }\n    }\n\n#ifndef WC_NO_RNG\n    /* now do a miller rabin with up to t random numbers, this should\n     * give a (1/4)^t chance of a false prime. */\n    #ifdef WOLFSSL_SMALL_STACK\n    if (err == MP_OKAY && !haveRes) {\n        b = (sp_int*)XMALLOC(sizeof(sp_int) * 5, NULL, DYNAMIC_TYPE_BIGINT);\n        if (b == NULL) {\n            err = MP_MEM;\n        }\n        else {\n            c = &b[1]; n1 = &b[2]; y= &b[3]; r = &b[4];\n        }\n    }\n    #endif\n\n    if (err == MP_OKAY && !haveRes) {\n        sp_init(b);\n        sp_init(c);\n        sp_init(n1);\n        sp_init(y);\n        sp_init(r);\n\n        err = sp_sub_d(a, 2, c);\n    }\n\n    if (err == MP_OKAY && !haveRes) {\n        baseSz = (sp_count_bits(a) + 7) / 8;\n\n        while (t > 0) {\n            err = wc_RNG_GenerateBlock(rng, (byte*)b->dp, baseSz);\n            if (err != MP_OKAY)\n                break;\n            b->used = a->used;\n\n            if (sp_cmp_d(b, 2) != MP_GT || sp_cmp(b, c) != MP_LT)\n                continue;\n\n            err = sp_prime_miller_rabin_ex(a, b, &ret, n1, y, r);\n            if (err != MP_OKAY || ret == MP_NO)\n                break;\n\n            t--;\n        }\n\n        sp_clear(n1);\n        sp_clear(y);\n        sp_clear(r);\n        sp_clear(b);\n        sp_clear(c);\n    }\n\n    #ifdef WOLFSSL_SMALL_STACK\n    if (b != NULL)\n        XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);\n    #endif\n#else\n    (void)t;\n#endif /* !WC_NO_RNG */\n\n    *result = ret;\n    return err;\n}\n\n#ifndef NO_DH\nint sp_exch(sp_int* a, sp_int* b)\n{\n    int err = MP_OKAY;\n#ifndef WOLFSSL_SMALL_STACK\n    sp_int  t[1];\n#else\n    sp_int *t = NULL;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT);\n   if (t == NULL)\n       err = MP_MEM;\n#endif\n\n    if (err == MP_OKAY) {\n        *t = *a;\n        *a = *b;\n        *b = *t;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (t != NULL)\n        XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n    return MP_OKAY;\n}\n#endif\n#endif\n\n/* Returns the run time settings.\n *\n * returns the settings value.\n */\nword32 CheckRunTimeSettings(void)\n{\n    return CTC_SETTINGS;\n}\n\n#endif /* WOLFSSL_SP_MATH */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/sp_x86_64.c",
    "content": "/* sp.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/* Implementation by Sean Parkinson. */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/cpuid.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \\\n                                    defined(WOLFSSL_HAVE_SP_ECC)\n\n#ifdef RSA_LOW_MEM\n#ifndef WOLFSSL_SP_SMALL\n#define WOLFSSL_SP_SMALL\n#endif\n#endif\n\n#include <wolfssl/wolfcrypt/sp.h>\n\n#ifdef WOLFSSL_SP_X86_64_ASM\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n#ifndef WOLFSSL_SP_NO_2048\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 56U) {\n            r[j] &= 0xffffffffffffffffl;\n            s = 64U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 64\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 64\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffffffffffffl;\n        s = 64U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 64U) <= (word32)DIGIT_BIT) {\n            s += 64U;\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 64) {\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 64 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 256\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_2048_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 2048 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<32 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 64) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 64);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\nextern void sp_2048_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* b);\nextern void sp_2048_sqr_16(sp_digit* r, const sp_digit* a);\nextern void sp_2048_mul_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* b);\nextern void sp_2048_sqr_avx2_16(sp_digit* r, const sp_digit* a);\nextern sp_digit sp_2048_add_16(sp_digit* r, const sp_digit* a, const sp_digit* b);\nextern sp_digit sp_2048_sub_in_place_32(sp_digit* a, const sp_digit* b);\nextern sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b);\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_16(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<16; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 16; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[32];\n    sp_digit a1[16];\n    sp_digit b1[16];\n    sp_digit z2[32];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_16(a1, a, &a[16]);\n    cb = sp_2048_add_16(b1, b, &b[16]);\n    u  = ca & cb;\n    sp_2048_mul_16(z1, a1, b1);\n    sp_2048_mul_16(z2, &a[16], &b[16]);\n    sp_2048_mul_16(z0, a, b);\n    sp_2048_mask_16(r + 32, a1, 0 - cb);\n    sp_2048_mask_16(b1, b1, 0 - ca);\n    u += sp_2048_add_16(r + 32, r + 32, b1);\n    u += sp_2048_sub_in_place_32(z1, z2);\n    u += sp_2048_sub_in_place_32(z1, z0);\n    u += sp_2048_add_32(r + 16, r + 16, z1);\n    r[48] = u;\n    XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));\n    sp_2048_add_32(r + 32, r + 32, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[32];\n    sp_digit z1[32];\n    sp_digit a1[16];\n    sp_digit u;\n\n    u = sp_2048_add_16(a1, a, &a[16]);\n    sp_2048_sqr_16(z1, a1);\n    sp_2048_sqr_16(z2, &a[16]);\n    sp_2048_sqr_16(z0, a);\n    sp_2048_mask_16(r + 32, a1, 0 - u);\n    u += sp_2048_add_16(r + 32, r + 32, r + 32);\n    u += sp_2048_sub_in_place_32(z1, z2);\n    u += sp_2048_sub_in_place_32(z1, z0);\n    u += sp_2048_add_32(r + 16, r + 16, z1);\n    r[48] = u;\n    XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));\n    sp_2048_add_32(r + 32, r + 32, z2);\n}\n\n#ifdef HAVE_INTEL_AVX2\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_mul_avx2_32(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[32];\n    sp_digit a1[16];\n    sp_digit b1[16];\n    sp_digit z2[32];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_16(a1, a, &a[16]);\n    cb = sp_2048_add_16(b1, b, &b[16]);\n    u  = ca & cb;\n    sp_2048_mul_avx2_16(z1, a1, b1);\n    sp_2048_mul_avx2_16(z2, &a[16], &b[16]);\n    sp_2048_mul_avx2_16(z0, a, b);\n    sp_2048_mask_16(r + 32, a1, 0 - cb);\n    sp_2048_mask_16(b1, b1, 0 - ca);\n    u += sp_2048_add_16(r + 32, r + 32, b1);\n    u += sp_2048_sub_in_place_32(z1, z2);\n    u += sp_2048_sub_in_place_32(z1, z0);\n    u += sp_2048_add_32(r + 16, r + 16, z1);\n    r[48] = u;\n    XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));\n    sp_2048_add_32(r + 32, r + 32, z2);\n}\n#endif /* HAVE_INTEL_AVX2 */\n\n#ifdef HAVE_INTEL_AVX2\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_2048_sqr_avx2_32(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[32];\n    sp_digit z1[32];\n    sp_digit a1[16];\n    sp_digit u;\n\n    u = sp_2048_add_16(a1, a, &a[16]);\n    sp_2048_sqr_avx2_16(z1, a1);\n    sp_2048_sqr_avx2_16(z2, &a[16]);\n    sp_2048_sqr_avx2_16(z0, a);\n    sp_2048_mask_16(r + 32, a1, 0 - u);\n    u += sp_2048_add_16(r + 32, r + 32, r + 32);\n    u += sp_2048_sub_in_place_32(z1, z2);\n    u += sp_2048_sub_in_place_32(z1, z0);\n    u += sp_2048_add_32(r + 16, r + 16, z1);\n    r[48] = u;\n    XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1));\n    sp_2048_add_32(r + 32, r + 32, z2);\n}\n#endif /* HAVE_INTEL_AVX2 */\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**64 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\nextern void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a, sp_digit b);\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\nextern sp_digit sp_2048_sub_in_place_16(sp_digit* a, const sp_digit* b);\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_16(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 16);\n\n    /* r = 2^n mod m */\n    sp_2048_sub_in_place_16(r, m);\n}\n\nextern sp_digit sp_2048_cond_sub_16(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m);\nextern void sp_2048_mont_reduce_16(sp_digit* a, const sp_digit* m, sp_digit mp);\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_16(r, a, b);\n    sp_2048_mont_reduce_16(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_16(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_16(r, a);\n    sp_2048_mont_reduce_16(r, m, mp);\n}\n\nextern void sp_2048_mul_d_16(sp_digit* r, const sp_digit* a, sp_digit b);\nextern void sp_2048_mul_d_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit b);\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n */\nstatic WC_INLINE sp_digit div_2048_word_16(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    register sp_digit r asm(\"rax\");\n    __asm__ __volatile__ (\n        \"divq %3\"\n        : \"=a\" (r)\n        : \"d\" (d1), \"a\" (d0), \"r\" (div)\n        :\n    );\n    return r;\n}\nextern int64_t sp_2048_cmp_16(const sp_digit* a, const sp_digit* b);\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_16(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[32], t2[17];\n    sp_digit div, r1;\n    int i;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)m;\n\n    div = d[15];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 16);\n    for (i=15; i>=0; i--) {\n        r1 = div_2048_word_16(t1[16 + i], t1[16 + i - 1], div);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            sp_2048_mul_d_avx2_16(t2, d, r1);\n        else\n#endif\n            sp_2048_mul_d_16(t2, d, r1);\n        t1[16 + i] += sp_2048_sub_in_place_16(&t1[i], t2);\n        t1[16 + i] -= t2[16];\n        sp_2048_mask_16(t2, d, t1[16 + i]);\n        t1[16 + i] += sp_2048_add_16(&t1[i], &t1[i], t2);\n        sp_2048_mask_16(t2, d, t1[16 + i]);\n        t1[16 + i] += sp_2048_add_16(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_2048_cmp_16(t1, d) >= 0;\n    sp_2048_cond_sub_16(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_16(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_16(a, m, NULL, r);\n}\n\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][32];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 32, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 32;\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_16(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 16);\n        if (reduceA) {\n            err = sp_2048_mod_16(t[1] + 16, a, m);\n            if (err == MP_OKAY)\n                err = sp_2048_mod_16(t[1], t[1], m);\n        }\n        else {\n            XMEMCPY(t[1] + 16, a, sizeof(sp_digit) * 16);\n            err = sp_2048_mod_16(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_16(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_16(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_16(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_16(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_16(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_16(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_16(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_16(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_16(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_16(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_16(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_16(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_16(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_16(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_16(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_16(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_16(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_16(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_16(t[20], t[10], m, mp);\n        sp_2048_mont_mul_16(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_16(t[22], t[11], m, mp);\n        sp_2048_mont_mul_16(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_16(t[24], t[12], m, mp);\n        sp_2048_mont_mul_16(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_16(t[26], t[13], m, mp);\n        sp_2048_mont_mul_16(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_16(t[28], t[14], m, mp);\n        sp_2048_mont_mul_16(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_16(t[30], t[15], m, mp);\n        sp_2048_mont_mul_16(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 5;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 16);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 59);\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = (int)(n >> 59);\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_16(r, r, m, mp);\n            sp_2048_mont_sqr_16(r, r, m, mp);\n            sp_2048_mont_sqr_16(r, r, m, mp);\n            sp_2048_mont_sqr_16(r, r, m, mp);\n            sp_2048_mont_sqr_16(r, r, m, mp);\n\n            sp_2048_mont_mul_16(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[16], 0, sizeof(sp_digit) * 16);\n        sp_2048_mont_reduce_16(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_16(r, m) >= 0);\n        sp_2048_cond_sub_16(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n\nextern void sp_2048_mont_reduce_avx2_16(sp_digit* a, const sp_digit* m, sp_digit mp);\n#ifdef HAVE_INTEL_AVX2\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_avx2_16(r, a, b);\n    sp_2048_mont_reduce_avx2_16(r, m, mp);\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n#ifdef HAVE_INTEL_AVX2\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_avx2_16(r, a);\n    sp_2048_mont_reduce_avx2_16(r, m, mp);\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n#ifdef HAVE_INTEL_AVX2\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][32];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 32, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 32;\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_16(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 16);\n        if (reduceA) {\n            err = sp_2048_mod_16(t[1] + 16, a, m);\n            if (err == MP_OKAY)\n                err = sp_2048_mod_16(t[1], t[1], m);\n        }\n        else {\n            XMEMCPY(t[1] + 16, a, sizeof(sp_digit) * 16);\n            err = sp_2048_mod_16(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_avx2_16(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_avx2_16(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_avx2_16(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_avx2_16(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_avx2_16(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_avx2_16(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_avx2_16(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_avx2_16(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_avx2_16(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_avx2_16(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[20], t[10], m, mp);\n        sp_2048_mont_mul_avx2_16(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[22], t[11], m, mp);\n        sp_2048_mont_mul_avx2_16(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[24], t[12], m, mp);\n        sp_2048_mont_mul_avx2_16(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[26], t[13], m, mp);\n        sp_2048_mont_mul_avx2_16(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[28], t[14], m, mp);\n        sp_2048_mont_mul_avx2_16(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_avx2_16(t[30], t[15], m, mp);\n        sp_2048_mont_mul_avx2_16(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 5;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 16);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 59);\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = (int)(n >> 59);\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_avx2_16(r, r, m, mp);\n            sp_2048_mont_sqr_avx2_16(r, r, m, mp);\n            sp_2048_mont_sqr_avx2_16(r, r, m, mp);\n            sp_2048_mont_sqr_avx2_16(r, r, m, mp);\n            sp_2048_mont_sqr_avx2_16(r, r, m, mp);\n\n            sp_2048_mont_mul_avx2_16(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[16], 0, sizeof(sp_digit) * 16);\n        sp_2048_mont_reduce_avx2_16(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_16(r, m) >= 0);\n        sp_2048_cond_sub_16(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n#endif /* HAVE_INTEL_AVX2 */\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 2048 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_2048_mont_norm_32(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 32);\n\n    /* r = 2^n mod m */\n    sp_2048_sub_in_place_32(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\nextern sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m);\nextern void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, sp_digit mp);\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_32(r, a, b);\n    sp_2048_mont_reduce_32(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_32(r, a);\n    sp_2048_mont_reduce_32(r, m, mp);\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\nextern void sp_2048_mul_d_avx2_32(sp_digit* r, const sp_digit* a, const sp_digit b);\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n */\nstatic WC_INLINE sp_digit div_2048_word_32(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    register sp_digit r asm(\"rax\");\n    __asm__ __volatile__ (\n        \"divq %3\"\n        : \"=a\" (r)\n        : \"d\" (d1), \"a\" (d0), \"r\" (div)\n        :\n    );\n    return r;\n}\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_2048_mask_32(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<32; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 32; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\nextern int64_t sp_2048_cmp_32(const sp_digit* a, const sp_digit* b);\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_32(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[64], t2[33];\n    sp_digit div, r1;\n    int i;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)m;\n\n    div = d[31];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 32);\n    for (i=31; i>=0; i--) {\n        r1 = div_2048_word_32(t1[32 + i], t1[32 + i - 1], div);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            sp_2048_mul_d_avx2_32(t2, d, r1);\n        else\n#endif\n            sp_2048_mul_d_32(t2, d, r1);\n        t1[32 + i] += sp_2048_sub_in_place_32(&t1[i], t2);\n        t1[32 + i] -= t2[32];\n        sp_2048_mask_32(t2, d, t1[32 + i]);\n        t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], t2);\n        sp_2048_mask_32(t2, d, t1[32 + i]);\n        t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_2048_cmp_32(t1, d) >= 0;\n    sp_2048_cond_sub_32(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_32(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_32(a, m, NULL, r);\n}\n\n#endif /* WOLFSSL_RSA_PUBLIC_ONLY */\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_div_32_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[64], t2[33];\n    sp_digit div, r1;\n    int i;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)m;\n\n    div = d[31];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 32);\n    for (i=31; i>=0; i--) {\n        r1 = div_2048_word_32(t1[32 + i], t1[32 + i - 1], div);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            sp_2048_mul_d_avx2_32(t2, d, r1);\n        else\n#endif\n            sp_2048_mul_d_32(t2, d, r1);\n        t1[32 + i] += sp_2048_sub_in_place_32(&t1[i], t2);\n        t1[32 + i] -= t2[32];\n        if (t1[32 + i] != 0) {\n            t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], d);\n            if (t1[32 + i] != 0)\n                t1[32 + i] += sp_2048_add_32(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_2048_cmp_32(t1, d) >= 0;\n    sp_2048_cond_sub_32(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_2048_mod_32_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_2048_div_32_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][64];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 64, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 64;\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_32(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 32);\n        if (reduceA) {\n            err = sp_2048_mod_32(t[1] + 32, a, m);\n            if (err == MP_OKAY)\n                err = sp_2048_mod_32(t[1], t[1], m);\n        }\n        else {\n            XMEMCPY(t[1] + 32, a, sizeof(sp_digit) * 32);\n            err = sp_2048_mod_32(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_32(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_32(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_32(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_32(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_32(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_32(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_32(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_32(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_32(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_32(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_32(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_32(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_32(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_32(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_32(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_32(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_32(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_32(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_32(t[20], t[10], m, mp);\n        sp_2048_mont_mul_32(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_32(t[22], t[11], m, mp);\n        sp_2048_mont_mul_32(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_32(t[24], t[12], m, mp);\n        sp_2048_mont_mul_32(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_32(t[26], t[13], m, mp);\n        sp_2048_mont_mul_32(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_32(t[28], t[14], m, mp);\n        sp_2048_mont_mul_32(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_32(t[30], t[15], m, mp);\n        sp_2048_mont_mul_32(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 5;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 32);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 59);\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = (int)(n >> 59);\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n\n            sp_2048_mont_mul_32(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[32], 0, sizeof(sp_digit) * 32);\n        sp_2048_mont_reduce_32(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_32(r, m) >= 0);\n        sp_2048_cond_sub_32(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\nextern void sp_2048_mont_reduce_avx2_32(sp_digit* a, const sp_digit* m, sp_digit mp);\n#ifdef HAVE_INTEL_AVX2\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_mul_avx2_32(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_2048_mul_avx2_32(r, a, b);\n    sp_2048_mont_reduce_avx2_32(r, m, mp);\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n#ifdef HAVE_INTEL_AVX2\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_2048_mont_sqr_avx2_32(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_2048_sqr_avx2_32(r, a);\n    sp_2048_mont_reduce_avx2_32(r, m, mp);\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)\n#ifdef HAVE_INTEL_AVX2\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_avx2_32(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][64];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 64, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 64;\n#endif\n        norm = t[0];\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_32(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 32);\n        if (reduceA) {\n            err = sp_2048_mod_32(t[1] + 32, a, m);\n            if (err == MP_OKAY)\n                err = sp_2048_mod_32(t[1], t[1], m);\n        }\n        else {\n            XMEMCPY(t[1] + 32, a, sizeof(sp_digit) * 32);\n            err = sp_2048_mod_32(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_mont_sqr_avx2_32(t[ 2], t[ 1], m, mp);\n        sp_2048_mont_mul_avx2_32(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[ 4], t[ 2], m, mp);\n        sp_2048_mont_mul_avx2_32(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[ 6], t[ 3], m, mp);\n        sp_2048_mont_mul_avx2_32(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[ 8], t[ 4], m, mp);\n        sp_2048_mont_mul_avx2_32(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[10], t[ 5], m, mp);\n        sp_2048_mont_mul_avx2_32(t[11], t[ 6], t[ 5], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[12], t[ 6], m, mp);\n        sp_2048_mont_mul_avx2_32(t[13], t[ 7], t[ 6], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[14], t[ 7], m, mp);\n        sp_2048_mont_mul_avx2_32(t[15], t[ 8], t[ 7], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[16], t[ 8], m, mp);\n        sp_2048_mont_mul_avx2_32(t[17], t[ 9], t[ 8], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[18], t[ 9], m, mp);\n        sp_2048_mont_mul_avx2_32(t[19], t[10], t[ 9], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[20], t[10], m, mp);\n        sp_2048_mont_mul_avx2_32(t[21], t[11], t[10], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[22], t[11], m, mp);\n        sp_2048_mont_mul_avx2_32(t[23], t[12], t[11], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[24], t[12], m, mp);\n        sp_2048_mont_mul_avx2_32(t[25], t[13], t[12], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[26], t[13], m, mp);\n        sp_2048_mont_mul_avx2_32(t[27], t[14], t[13], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[28], t[14], m, mp);\n        sp_2048_mont_mul_avx2_32(t[29], t[15], t[14], m, mp);\n        sp_2048_mont_sqr_avx2_32(t[30], t[15], m, mp);\n        sp_2048_mont_mul_avx2_32(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 5;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 32);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 59);\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = (int)(n >> 59);\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_2048_mont_sqr_avx2_32(r, r, m, mp);\n            sp_2048_mont_sqr_avx2_32(r, r, m, mp);\n            sp_2048_mont_sqr_avx2_32(r, r, m, mp);\n            sp_2048_mont_sqr_avx2_32(r, r, m, mp);\n            sp_2048_mont_sqr_avx2_32(r, r, m, mp);\n\n            sp_2048_mont_mul_avx2_32(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[32], 0, sizeof(sp_digit) * 32);\n        sp_2048_mont_reduce_avx2_32(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_32(r, m) >= 0);\n        sp_2048_cond_sub_32(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n#endif /* HAVE_INTEL_AVX2 */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[64], md[32], rd[64];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit  e = 0;\n    int err = MP_OKAY;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    if (*outLen < 256)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 64 || inLen > 256 ||\n                                                     mp_count_bits(mm) != 2048))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 32 * 2;\n        m = r + 32 * 2;\n        ah = a + 32;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 32;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(ah, 32, in, inLen);\n#if DIGIT_BIT >= 64\n        e = em->dp[0];\n#else\n        e = em->dp[0];\n        if (em->used > 1)\n            e |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(m, 32, mm);\n\n        if (e == 0x3) {\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n                if (err == MP_OKAY) {\n                    sp_2048_sqr_avx2_32(r, ah);\n                    err = sp_2048_mod_32_cond(r, r, m);\n                }\n                if (err == MP_OKAY) {\n                    sp_2048_mul_avx2_32(r, ah, r);\n                    err = sp_2048_mod_32_cond(r, r, m);\n                }\n            }\n            else\n#endif\n            {\n                if (err == MP_OKAY) {\n                    sp_2048_sqr_32(r, ah);\n                    err = sp_2048_mod_32_cond(r, r, m);\n                }\n                if (err == MP_OKAY) {\n                    sp_2048_mul_32(r, ah, r);\n                    err = sp_2048_mod_32_cond(r, r, m);\n                }\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_2048_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 32);\n            err = sp_2048_mod_32_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=63; i>=0; i--) {\n                    if (e >> i) {\n                        break;\n                    }\n                }\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 32);\n#ifdef HAVE_INTEL_AVX2\n                if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n                    for (i--; i>=0; i--) {\n                        sp_2048_mont_sqr_avx2_32(r, r, m, mp);\n                        if (((e >> i) & 1) == 1) {\n                            sp_2048_mont_mul_avx2_32(r, r, a, m, mp);\n                        }\n                    }\n                    XMEMSET(&r[32], 0, sizeof(sp_digit) * 32);\n                    sp_2048_mont_reduce_avx2_32(r, m, mp);\n                }\n                else\n#endif\n                {\n                    for (i--; i>=0; i--) {\n                        sp_2048_mont_sqr_32(r, r, m, mp);\n                        if (((e >> i) & 1) == 1) {\n                            sp_2048_mont_mul_32(r, r, a, m, mp);\n                        }\n                    }\n                    XMEMSET(&r[32], 0, sizeof(sp_digit) * 32);\n                    sp_2048_mont_reduce_32(r, m, mp);\n                }\n\n                for (i = 31; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_2048_sub_in_place_32(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 256 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[32 * 2];\n    sp_digit pd[16], qd[16], dpd[16];\n    sp_digit tmpad[32], tmpbd[32];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 256)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 256 || mp_count_bits(mm) != 2048))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 32 * 2;\n        q = p + 16;\n        qi = dq = dp = q + 16;\n        tmpa = qi + 16;\n        tmpb = tmpa + 32;\n\n        tmp = t;\n        r = tmp + 32;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 32;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_2048_from_bin(a, 32, in, inLen);\n        sp_2048_from_mp(p, 16, pm);\n        sp_2048_from_mp(q, 16, qm);\n        sp_2048_from_mp(dp, 16, dpm);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_2048_mod_exp_avx2_16(tmpa, a, dp, 1024, p, 1);\n        else\n#endif\n            err = sp_2048_mod_exp_16(tmpa, a, dp, 1024, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(dq, 16, dqm);\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_2048_mod_exp_avx2_16(tmpb, a, dq, 1024, q, 1);\n       else\n#endif\n            err = sp_2048_mod_exp_16(tmpb, a, dq, 1024, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_2048_sub_in_place_16(tmpa, tmpb);\n        sp_2048_mask_16(tmp, p, c);\n        sp_2048_add_16(tmpa, tmpa, tmp);\n\n        sp_2048_from_mp(qi, 16, qim);\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n            sp_2048_mul_avx2_16(tmpa, tmpa, qi);\n        }\n        else\n#endif\n        {\n            sp_2048_mul_16(tmpa, tmpa, qi);\n        }\n        err = sp_2048_mod_16(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n            sp_2048_mul_avx2_16(tmpa, q, tmpa);\n        }\n        else\n#endif\n        {\n            sp_2048_mul_16(tmpa, q, tmpa);\n        }\n        XMEMSET(&tmpb[16], 0, sizeof(sp_digit) * 16);\n        sp_2048_add_32(r, tmpb, tmpa);\n\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 16 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_2048_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (2048 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 64\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 32);\n        r->used = 32;\n        mp_clamp(r);\n#elif DIGIT_BIT < 64\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 32; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 64) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 64 - s;\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 32; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 64 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 64 - s;\n            }\n            else {\n                s += 64;\n            }\n        }\n        r->used = (2048 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[64], e[32], m[32];\n    sp_digit* r = b;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 2048 || expBits > 2048 ||\n                                                   mp_count_bits(mod) != 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 32, base);\n        sp_2048_from_mp(e, 32, exp);\n        sp_2048_from_mp(m, 32, mod);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_2048_mod_exp_avx2_32(r, b, e, expBits, m, 0);\n        else\n#endif\n            err = sp_2048_mod_exp_32(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_2048_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n#ifdef HAVE_FFDHE_2048\nextern void sp_2048_lshift_32(sp_digit* r, const sp_digit* a, int n);\n#ifdef HAVE_INTEL_AVX2\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_2_avx2_32(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[64];\n    sp_digit td[33];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 97, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 64;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_32(norm, m);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 6;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        sp_2048_lshift_32(r, norm, y);\n        for (; i>=0 || c>=6; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 58);\n                n <<= 6;\n                c = 58;\n            }\n            else if (c < 6) {\n                y = (int)(n >> 58);\n                n = e[i--];\n                c = 6 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 58) & 0x3f;\n                n <<= 6;\n                c -= 6;\n            }\n\n            sp_2048_mont_sqr_avx2_32(r, r, m, mp);\n            sp_2048_mont_sqr_avx2_32(r, r, m, mp);\n            sp_2048_mont_sqr_avx2_32(r, r, m, mp);\n            sp_2048_mont_sqr_avx2_32(r, r, m, mp);\n            sp_2048_mont_sqr_avx2_32(r, r, m, mp);\n            sp_2048_mont_sqr_avx2_32(r, r, m, mp);\n\n            sp_2048_lshift_32(r, r, y);\n            sp_2048_mul_d_avx2_32(tmp, norm, r[32]);\n            r[32] = 0;\n            o = sp_2048_add_32(r, r, tmp);\n            sp_2048_cond_sub_32(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[32], 0, sizeof(sp_digit) * 32);\n        sp_2048_mont_reduce_avx2_32(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_32(r, m) >= 0);\n        sp_2048_cond_sub_32(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n#endif /* HAVE_INTEL_AVX2 */\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_2048_mod_exp_2_32(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[64];\n    sp_digit td[33];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 97, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 64;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_2048_mont_setup(m, &mp);\n        sp_2048_mont_norm_32(norm, m);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 6;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        sp_2048_lshift_32(r, norm, y);\n        for (; i>=0 || c>=6; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 58);\n                n <<= 6;\n                c = 58;\n            }\n            else if (c < 6) {\n                y = (int)(n >> 58);\n                n = e[i--];\n                c = 6 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 58) & 0x3f;\n                n <<= 6;\n                c -= 6;\n            }\n\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n            sp_2048_mont_sqr_32(r, r, m, mp);\n\n            sp_2048_lshift_32(r, r, y);\n            sp_2048_mul_d_32(tmp, norm, r[32]);\n            r[32] = 0;\n            o = sp_2048_add_32(r, r, tmp);\n            sp_2048_cond_sub_32(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[32], 0, sizeof(sp_digit) * 32);\n        sp_2048_mont_reduce_32(r, m, mp);\n\n        mask = 0 - (sp_2048_cmp_32(r, m) >= 0);\n        sp_2048_cond_sub_32(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n\n#endif /* HAVE_FFDHE_2048 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 256 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[64], e[32], m[32];\n    sp_digit* r = b;\n    word32 i;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    if (mp_count_bits(base) > 2048 || expLen > 256 ||\n                                                   mp_count_bits(mod) != 2048) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 32, base);\n        sp_2048_from_bin(e, 32, exp, expLen);\n        sp_2048_from_mp(m, 32, mod);\n\n    #ifdef HAVE_FFDHE_2048\n        if (base->used == 1 && base->dp[0] == 2 && m[31] == (sp_digit)-1) {\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n                err = sp_2048_mod_exp_2_avx2_32(r, e, expLen * 8, m);\n            else\n#endif\n                err = sp_2048_mod_exp_2_32(r, e, expLen * 8, m);\n        }\n        else\n    #endif\n        {\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n                err = sp_2048_mod_exp_avx2_32(r, b, e, expLen * 8, m, 0);\n            else\n#endif\n                err = sp_2048_mod_exp_32(r, b, e, expLen * 8, m, 0);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_to_bin(r, out);\n        *outLen = 256;\n        for (i=0; i<256 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[32], e[16], m[16];\n    sp_digit* r = b;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1024 || expBits > 1024 ||\n                                                   mp_count_bits(mod) != 1024) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        sp_2048_from_mp(b, 16, base);\n        sp_2048_from_mp(e, 16, exp);\n        sp_2048_from_mp(m, 16, mod);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_2048_mod_exp_avx2_16(r, b, e, expBits, m, 0);\n        else\n#endif\n            err = sp_2048_mod_exp_16(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 16, 0, sizeof(*r) * 16);\n        err = sp_2048_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_2048 */\n\n#ifndef WOLFSSL_SP_NO_3072\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 56U) {\n            r[j] &= 0xffffffffffffffffl;\n            s = 64U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 64\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 64\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffffffffffffl;\n        s = 64U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 64U) <= (word32)DIGIT_BIT) {\n            s += 64U;\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 64) {\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 64 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 384\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_3072_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 3072 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<48 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 64) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 64);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\nextern void sp_3072_mul_24(sp_digit* r, const sp_digit* a, const sp_digit* b);\nextern void sp_3072_sqr_24(sp_digit* r, const sp_digit* a);\nextern void sp_3072_mul_avx2_24(sp_digit* r, const sp_digit* a, const sp_digit* b);\nextern void sp_3072_sqr_avx2_24(sp_digit* r, const sp_digit* a);\nextern sp_digit sp_3072_add_24(sp_digit* r, const sp_digit* a, const sp_digit* b);\nextern sp_digit sp_3072_sub_in_place_48(sp_digit* a, const sp_digit* b);\nextern sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a, const sp_digit* b);\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_24(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<24; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 24; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[48];\n    sp_digit a1[24];\n    sp_digit b1[24];\n    sp_digit z2[48];\n    sp_digit u, ca, cb;\n\n    ca = sp_3072_add_24(a1, a, &a[24]);\n    cb = sp_3072_add_24(b1, b, &b[24]);\n    u  = ca & cb;\n    sp_3072_mul_24(z1, a1, b1);\n    sp_3072_mul_24(z2, &a[24], &b[24]);\n    sp_3072_mul_24(z0, a, b);\n    sp_3072_mask_24(r + 48, a1, 0 - cb);\n    sp_3072_mask_24(b1, b1, 0 - ca);\n    u += sp_3072_add_24(r + 48, r + 48, b1);\n    u += sp_3072_sub_in_place_48(z1, z2);\n    u += sp_3072_sub_in_place_48(z1, z0);\n    u += sp_3072_add_48(r + 24, r + 24, z1);\n    r[72] = u;\n    XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));\n    sp_3072_add_48(r + 48, r + 48, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[48];\n    sp_digit z1[48];\n    sp_digit a1[24];\n    sp_digit u;\n\n    u = sp_3072_add_24(a1, a, &a[24]);\n    sp_3072_sqr_24(z1, a1);\n    sp_3072_sqr_24(z2, &a[24]);\n    sp_3072_sqr_24(z0, a);\n    sp_3072_mask_24(r + 48, a1, 0 - u);\n    u += sp_3072_add_24(r + 48, r + 48, r + 48);\n    u += sp_3072_sub_in_place_48(z1, z2);\n    u += sp_3072_sub_in_place_48(z1, z0);\n    u += sp_3072_add_48(r + 24, r + 24, z1);\n    r[72] = u;\n    XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));\n    sp_3072_add_48(r + 48, r + 48, z2);\n}\n\n#ifdef HAVE_INTEL_AVX2\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_mul_avx2_48(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[48];\n    sp_digit a1[24];\n    sp_digit b1[24];\n    sp_digit z2[48];\n    sp_digit u, ca, cb;\n\n    ca = sp_3072_add_24(a1, a, &a[24]);\n    cb = sp_3072_add_24(b1, b, &b[24]);\n    u  = ca & cb;\n    sp_3072_mul_avx2_24(z1, a1, b1);\n    sp_3072_mul_avx2_24(z2, &a[24], &b[24]);\n    sp_3072_mul_avx2_24(z0, a, b);\n    sp_3072_mask_24(r + 48, a1, 0 - cb);\n    sp_3072_mask_24(b1, b1, 0 - ca);\n    u += sp_3072_add_24(r + 48, r + 48, b1);\n    u += sp_3072_sub_in_place_48(z1, z2);\n    u += sp_3072_sub_in_place_48(z1, z0);\n    u += sp_3072_add_48(r + 24, r + 24, z1);\n    r[72] = u;\n    XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));\n    sp_3072_add_48(r + 48, r + 48, z2);\n}\n#endif /* HAVE_INTEL_AVX2 */\n\n#ifdef HAVE_INTEL_AVX2\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_3072_sqr_avx2_48(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[48];\n    sp_digit z1[48];\n    sp_digit a1[24];\n    sp_digit u;\n\n    u = sp_3072_add_24(a1, a, &a[24]);\n    sp_3072_sqr_avx2_24(z1, a1);\n    sp_3072_sqr_avx2_24(z2, &a[24]);\n    sp_3072_sqr_avx2_24(z0, a);\n    sp_3072_mask_24(r + 48, a1, 0 - u);\n    u += sp_3072_add_24(r + 48, r + 48, r + 48);\n    u += sp_3072_sub_in_place_48(z1, z2);\n    u += sp_3072_sub_in_place_48(z1, z0);\n    u += sp_3072_add_48(r + 24, r + 24, z1);\n    r[72] = u;\n    XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1));\n    sp_3072_add_48(r + 48, r + 48, z2);\n}\n#endif /* HAVE_INTEL_AVX2 */\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**64 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\nextern void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a, sp_digit b);\n#if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)\nextern sp_digit sp_3072_sub_in_place_24(sp_digit* a, const sp_digit* b);\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_24(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 24);\n\n    /* r = 2^n mod m */\n    sp_3072_sub_in_place_24(r, m);\n}\n\nextern sp_digit sp_3072_cond_sub_24(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m);\nextern void sp_3072_mont_reduce_24(sp_digit* a, const sp_digit* m, sp_digit mp);\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_24(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_24(r, a, b);\n    sp_3072_mont_reduce_24(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_24(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_24(r, a);\n    sp_3072_mont_reduce_24(r, m, mp);\n}\n\nextern void sp_3072_mul_d_24(sp_digit* r, const sp_digit* a, sp_digit b);\nextern void sp_3072_mul_d_avx2_24(sp_digit* r, const sp_digit* a, const sp_digit b);\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n */\nstatic WC_INLINE sp_digit div_3072_word_24(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    register sp_digit r asm(\"rax\");\n    __asm__ __volatile__ (\n        \"divq %3\"\n        : \"=a\" (r)\n        : \"d\" (d1), \"a\" (d0), \"r\" (div)\n        :\n    );\n    return r;\n}\nextern int64_t sp_3072_cmp_24(const sp_digit* a, const sp_digit* b);\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_24(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[48], t2[25];\n    sp_digit div, r1;\n    int i;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)m;\n\n    div = d[23];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 24);\n    for (i=23; i>=0; i--) {\n        r1 = div_3072_word_24(t1[24 + i], t1[24 + i - 1], div);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            sp_3072_mul_d_avx2_24(t2, d, r1);\n        else\n#endif\n            sp_3072_mul_d_24(t2, d, r1);\n        t1[24 + i] += sp_3072_sub_in_place_24(&t1[i], t2);\n        t1[24 + i] -= t2[24];\n        sp_3072_mask_24(t2, d, t1[24 + i]);\n        t1[24 + i] += sp_3072_add_24(&t1[i], &t1[i], t2);\n        sp_3072_mask_24(t2, d, t1[24 + i]);\n        t1[24 + i] += sp_3072_add_24(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_3072_cmp_24(t1, d) >= 0;\n    sp_3072_cond_sub_24(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_24(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_24(a, m, NULL, r);\n}\n\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][48];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 48, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 48;\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_24(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 24);\n        if (reduceA) {\n            err = sp_3072_mod_24(t[1] + 24, a, m);\n            if (err == MP_OKAY)\n                err = sp_3072_mod_24(t[1], t[1], m);\n        }\n        else {\n            XMEMCPY(t[1] + 24, a, sizeof(sp_digit) * 24);\n            err = sp_3072_mod_24(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_24(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_24(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_24(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_24(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_24(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_24(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_24(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_24(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_24(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_24(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_24(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_24(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_24(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_24(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_24(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_24(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_24(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_24(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_24(t[20], t[10], m, mp);\n        sp_3072_mont_mul_24(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_24(t[22], t[11], m, mp);\n        sp_3072_mont_mul_24(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_24(t[24], t[12], m, mp);\n        sp_3072_mont_mul_24(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_24(t[26], t[13], m, mp);\n        sp_3072_mont_mul_24(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_24(t[28], t[14], m, mp);\n        sp_3072_mont_mul_24(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_24(t[30], t[15], m, mp);\n        sp_3072_mont_mul_24(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 5;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 24);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 59);\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = (int)(n >> 59);\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_24(r, r, m, mp);\n            sp_3072_mont_sqr_24(r, r, m, mp);\n            sp_3072_mont_sqr_24(r, r, m, mp);\n            sp_3072_mont_sqr_24(r, r, m, mp);\n            sp_3072_mont_sqr_24(r, r, m, mp);\n\n            sp_3072_mont_mul_24(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[24], 0, sizeof(sp_digit) * 24);\n        sp_3072_mont_reduce_24(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_24(r, m) >= 0);\n        sp_3072_cond_sub_24(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n\nextern void sp_3072_mont_reduce_avx2_24(sp_digit* a, const sp_digit* m, sp_digit mp);\n#ifdef HAVE_INTEL_AVX2\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_avx2_24(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_avx2_24(r, a, b);\n    sp_3072_mont_reduce_avx2_24(r, m, mp);\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n#ifdef HAVE_INTEL_AVX2\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_avx2_24(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_avx2_24(r, a);\n    sp_3072_mont_reduce_avx2_24(r, m, mp);\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n#ifdef HAVE_INTEL_AVX2\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_avx2_24(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][48];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 48, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 48;\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_24(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 24);\n        if (reduceA) {\n            err = sp_3072_mod_24(t[1] + 24, a, m);\n            if (err == MP_OKAY)\n                err = sp_3072_mod_24(t[1], t[1], m);\n        }\n        else {\n            XMEMCPY(t[1] + 24, a, sizeof(sp_digit) * 24);\n            err = sp_3072_mod_24(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_avx2_24(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_avx2_24(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_avx2_24(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_avx2_24(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_avx2_24(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_avx2_24(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_avx2_24(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_avx2_24(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_avx2_24(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_avx2_24(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[20], t[10], m, mp);\n        sp_3072_mont_mul_avx2_24(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[22], t[11], m, mp);\n        sp_3072_mont_mul_avx2_24(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[24], t[12], m, mp);\n        sp_3072_mont_mul_avx2_24(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[26], t[13], m, mp);\n        sp_3072_mont_mul_avx2_24(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[28], t[14], m, mp);\n        sp_3072_mont_mul_avx2_24(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_avx2_24(t[30], t[15], m, mp);\n        sp_3072_mont_mul_avx2_24(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 5;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 24);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 59);\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = (int)(n >> 59);\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_avx2_24(r, r, m, mp);\n            sp_3072_mont_sqr_avx2_24(r, r, m, mp);\n            sp_3072_mont_sqr_avx2_24(r, r, m, mp);\n            sp_3072_mont_sqr_avx2_24(r, r, m, mp);\n            sp_3072_mont_sqr_avx2_24(r, r, m, mp);\n\n            sp_3072_mont_mul_avx2_24(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[24], 0, sizeof(sp_digit) * 24);\n        sp_3072_mont_reduce_avx2_24(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_24(r, m) >= 0);\n        sp_3072_cond_sub_24(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n#endif /* HAVE_INTEL_AVX2 */\n\n#endif /* (WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH) && !WOLFSSL_RSA_PUBLIC_ONLY */\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 3072 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_3072_mont_norm_48(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 48);\n\n    /* r = 2^n mod m */\n    sp_3072_sub_in_place_48(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\nextern sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m);\nextern void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, sp_digit mp);\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_48(r, a, b);\n    sp_3072_mont_reduce_48(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_48(r, a);\n    sp_3072_mont_reduce_48(r, m, mp);\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\nextern void sp_3072_mul_d_avx2_48(sp_digit* r, const sp_digit* a, const sp_digit b);\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n */\nstatic WC_INLINE sp_digit div_3072_word_48(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    register sp_digit r asm(\"rax\");\n    __asm__ __volatile__ (\n        \"divq %3\"\n        : \"=a\" (r)\n        : \"d\" (d1), \"a\" (d0), \"r\" (div)\n        :\n    );\n    return r;\n}\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_3072_mask_48(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<48; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 48; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\nextern int64_t sp_3072_cmp_48(const sp_digit* a, const sp_digit* b);\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_48(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[96], t2[49];\n    sp_digit div, r1;\n    int i;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)m;\n\n    div = d[47];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 48);\n    for (i=47; i>=0; i--) {\n        r1 = div_3072_word_48(t1[48 + i], t1[48 + i - 1], div);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            sp_3072_mul_d_avx2_48(t2, d, r1);\n        else\n#endif\n            sp_3072_mul_d_48(t2, d, r1);\n        t1[48 + i] += sp_3072_sub_in_place_48(&t1[i], t2);\n        t1[48 + i] -= t2[48];\n        sp_3072_mask_48(t2, d, t1[48 + i]);\n        t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], t2);\n        sp_3072_mask_48(t2, d, t1[48 + i]);\n        t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_3072_cmp_48(t1, d) >= 0;\n    sp_3072_cond_sub_48(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_48(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_48(a, m, NULL, r);\n}\n\n#endif /* WOLFSSL_RSA_PUBLIC_ONLY */\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_div_48_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[96], t2[49];\n    sp_digit div, r1;\n    int i;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)m;\n\n    div = d[47];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 48);\n    for (i=47; i>=0; i--) {\n        r1 = div_3072_word_48(t1[48 + i], t1[48 + i - 1], div);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            sp_3072_mul_d_avx2_48(t2, d, r1);\n        else\n#endif\n            sp_3072_mul_d_48(t2, d, r1);\n        t1[48 + i] += sp_3072_sub_in_place_48(&t1[i], t2);\n        t1[48 + i] -= t2[48];\n        if (t1[48 + i] != 0) {\n            t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], d);\n            if (t1[48 + i] != 0)\n                t1[48 + i] += sp_3072_add_48(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_3072_cmp_48(t1, d) >= 0;\n    sp_3072_cond_sub_48(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_3072_mod_48_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_3072_div_48_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][96];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 96, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 96;\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_48(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 48);\n        if (reduceA) {\n            err = sp_3072_mod_48(t[1] + 48, a, m);\n            if (err == MP_OKAY)\n                err = sp_3072_mod_48(t[1], t[1], m);\n        }\n        else {\n            XMEMCPY(t[1] + 48, a, sizeof(sp_digit) * 48);\n            err = sp_3072_mod_48(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_48(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_48(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_48(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_48(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_48(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_48(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_48(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_48(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_48(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_48(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_48(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_48(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_48(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_48(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_48(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_48(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_48(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_48(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_48(t[20], t[10], m, mp);\n        sp_3072_mont_mul_48(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_48(t[22], t[11], m, mp);\n        sp_3072_mont_mul_48(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_48(t[24], t[12], m, mp);\n        sp_3072_mont_mul_48(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_48(t[26], t[13], m, mp);\n        sp_3072_mont_mul_48(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_48(t[28], t[14], m, mp);\n        sp_3072_mont_mul_48(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_48(t[30], t[15], m, mp);\n        sp_3072_mont_mul_48(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 5;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 48);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 59);\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = (int)(n >> 59);\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n\n            sp_3072_mont_mul_48(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[48], 0, sizeof(sp_digit) * 48);\n        sp_3072_mont_reduce_48(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_48(r, m) >= 0);\n        sp_3072_cond_sub_48(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\nextern void sp_3072_mont_reduce_avx2_48(sp_digit* a, const sp_digit* m, sp_digit mp);\n#ifdef HAVE_INTEL_AVX2\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_mul_avx2_48(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_3072_mul_avx2_48(r, a, b);\n    sp_3072_mont_reduce_avx2_48(r, m, mp);\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n#ifdef HAVE_INTEL_AVX2\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_3072_mont_sqr_avx2_48(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_3072_sqr_avx2_48(r, a);\n    sp_3072_mont_reduce_avx2_48(r, m, mp);\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)\n#ifdef HAVE_INTEL_AVX2\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_avx2_48(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][96];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 96, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 96;\n#endif\n        norm = t[0];\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_48(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 48);\n        if (reduceA) {\n            err = sp_3072_mod_48(t[1] + 48, a, m);\n            if (err == MP_OKAY)\n                err = sp_3072_mod_48(t[1], t[1], m);\n        }\n        else {\n            XMEMCPY(t[1] + 48, a, sizeof(sp_digit) * 48);\n            err = sp_3072_mod_48(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_mont_sqr_avx2_48(t[ 2], t[ 1], m, mp);\n        sp_3072_mont_mul_avx2_48(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[ 4], t[ 2], m, mp);\n        sp_3072_mont_mul_avx2_48(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[ 6], t[ 3], m, mp);\n        sp_3072_mont_mul_avx2_48(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[ 8], t[ 4], m, mp);\n        sp_3072_mont_mul_avx2_48(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[10], t[ 5], m, mp);\n        sp_3072_mont_mul_avx2_48(t[11], t[ 6], t[ 5], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[12], t[ 6], m, mp);\n        sp_3072_mont_mul_avx2_48(t[13], t[ 7], t[ 6], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[14], t[ 7], m, mp);\n        sp_3072_mont_mul_avx2_48(t[15], t[ 8], t[ 7], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[16], t[ 8], m, mp);\n        sp_3072_mont_mul_avx2_48(t[17], t[ 9], t[ 8], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[18], t[ 9], m, mp);\n        sp_3072_mont_mul_avx2_48(t[19], t[10], t[ 9], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[20], t[10], m, mp);\n        sp_3072_mont_mul_avx2_48(t[21], t[11], t[10], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[22], t[11], m, mp);\n        sp_3072_mont_mul_avx2_48(t[23], t[12], t[11], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[24], t[12], m, mp);\n        sp_3072_mont_mul_avx2_48(t[25], t[13], t[12], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[26], t[13], m, mp);\n        sp_3072_mont_mul_avx2_48(t[27], t[14], t[13], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[28], t[14], m, mp);\n        sp_3072_mont_mul_avx2_48(t[29], t[15], t[14], m, mp);\n        sp_3072_mont_sqr_avx2_48(t[30], t[15], m, mp);\n        sp_3072_mont_mul_avx2_48(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 5;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 48);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 59);\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = (int)(n >> 59);\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_3072_mont_sqr_avx2_48(r, r, m, mp);\n            sp_3072_mont_sqr_avx2_48(r, r, m, mp);\n            sp_3072_mont_sqr_avx2_48(r, r, m, mp);\n            sp_3072_mont_sqr_avx2_48(r, r, m, mp);\n            sp_3072_mont_sqr_avx2_48(r, r, m, mp);\n\n            sp_3072_mont_mul_avx2_48(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[48], 0, sizeof(sp_digit) * 48);\n        sp_3072_mont_reduce_avx2_48(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_48(r, m) >= 0);\n        sp_3072_cond_sub_48(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n#endif /* HAVE_INTEL_AVX2 */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[96], md[48], rd[96];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit  e = 0;\n    int err = MP_OKAY;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    if (*outLen < 384)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 64 || inLen > 384 ||\n                                                     mp_count_bits(mm) != 3072))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 48 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 48 * 2;\n        m = r + 48 * 2;\n        ah = a + 48;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 48;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(ah, 48, in, inLen);\n#if DIGIT_BIT >= 64\n        e = em->dp[0];\n#else\n        e = em->dp[0];\n        if (em->used > 1)\n            e |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(m, 48, mm);\n\n        if (e == 0x3) {\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n                if (err == MP_OKAY) {\n                    sp_3072_sqr_avx2_48(r, ah);\n                    err = sp_3072_mod_48_cond(r, r, m);\n                }\n                if (err == MP_OKAY) {\n                    sp_3072_mul_avx2_48(r, ah, r);\n                    err = sp_3072_mod_48_cond(r, r, m);\n                }\n            }\n            else\n#endif\n            {\n                if (err == MP_OKAY) {\n                    sp_3072_sqr_48(r, ah);\n                    err = sp_3072_mod_48_cond(r, r, m);\n                }\n                if (err == MP_OKAY) {\n                    sp_3072_mul_48(r, ah, r);\n                    err = sp_3072_mod_48_cond(r, r, m);\n                }\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_3072_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 48);\n            err = sp_3072_mod_48_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=63; i>=0; i--) {\n                    if (e >> i) {\n                        break;\n                    }\n                }\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 48);\n#ifdef HAVE_INTEL_AVX2\n                if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n                    for (i--; i>=0; i--) {\n                        sp_3072_mont_sqr_avx2_48(r, r, m, mp);\n                        if (((e >> i) & 1) == 1) {\n                            sp_3072_mont_mul_avx2_48(r, r, a, m, mp);\n                        }\n                    }\n                    XMEMSET(&r[48], 0, sizeof(sp_digit) * 48);\n                    sp_3072_mont_reduce_avx2_48(r, m, mp);\n                }\n                else\n#endif\n                {\n                    for (i--; i>=0; i--) {\n                        sp_3072_mont_sqr_48(r, r, m, mp);\n                        if (((e >> i) & 1) == 1) {\n                            sp_3072_mont_mul_48(r, r, a, m, mp);\n                        }\n                    }\n                    XMEMSET(&r[48], 0, sizeof(sp_digit) * 48);\n                    sp_3072_mont_reduce_48(r, m, mp);\n                }\n\n                for (i = 47; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_3072_sub_in_place_48(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 384 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[48 * 2];\n    sp_digit pd[24], qd[24], dpd[24];\n    sp_digit tmpad[48], tmpbd[48];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 384)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 384 || mp_count_bits(mm) != 3072))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 24 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 48 * 2;\n        q = p + 24;\n        qi = dq = dp = q + 24;\n        tmpa = qi + 24;\n        tmpb = tmpa + 48;\n\n        tmp = t;\n        r = tmp + 48;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 48;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_3072_from_bin(a, 48, in, inLen);\n        sp_3072_from_mp(p, 24, pm);\n        sp_3072_from_mp(q, 24, qm);\n        sp_3072_from_mp(dp, 24, dpm);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_3072_mod_exp_avx2_24(tmpa, a, dp, 1536, p, 1);\n        else\n#endif\n            err = sp_3072_mod_exp_24(tmpa, a, dp, 1536, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(dq, 24, dqm);\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_3072_mod_exp_avx2_24(tmpb, a, dq, 1536, q, 1);\n       else\n#endif\n            err = sp_3072_mod_exp_24(tmpb, a, dq, 1536, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_3072_sub_in_place_24(tmpa, tmpb);\n        sp_3072_mask_24(tmp, p, c);\n        sp_3072_add_24(tmpa, tmpa, tmp);\n\n        sp_3072_from_mp(qi, 24, qim);\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n            sp_3072_mul_avx2_24(tmpa, tmpa, qi);\n        }\n        else\n#endif\n        {\n            sp_3072_mul_24(tmpa, tmpa, qi);\n        }\n        err = sp_3072_mod_24(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n            sp_3072_mul_avx2_24(tmpa, q, tmpa);\n        }\n        else\n#endif\n        {\n            sp_3072_mul_24(tmpa, q, tmpa);\n        }\n        XMEMSET(&tmpb[24], 0, sizeof(sp_digit) * 24);\n        sp_3072_add_48(r, tmpb, tmpa);\n\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 24 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_3072_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (3072 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 64\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 48);\n        r->used = 48;\n        mp_clamp(r);\n#elif DIGIT_BIT < 64\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 48; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 64) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 64 - s;\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 48; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 64 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 64 - s;\n            }\n            else {\n                s += 64;\n            }\n        }\n        r->used = (3072 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[96], e[48], m[48];\n    sp_digit* r = b;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 3072 || expBits > 3072 ||\n                                                   mp_count_bits(mod) != 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 48, base);\n        sp_3072_from_mp(e, 48, exp);\n        sp_3072_from_mp(m, 48, mod);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_3072_mod_exp_avx2_48(r, b, e, expBits, m, 0);\n        else\n#endif\n            err = sp_3072_mod_exp_48(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_3072_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n#ifdef HAVE_FFDHE_3072\nextern void sp_3072_lshift_48(sp_digit* r, const sp_digit* a, int n);\n#ifdef HAVE_INTEL_AVX2\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_2_avx2_48(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[96];\n    sp_digit td[49];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 145, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 96;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_48(norm, m);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 6;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        sp_3072_lshift_48(r, norm, y);\n        for (; i>=0 || c>=6; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 58);\n                n <<= 6;\n                c = 58;\n            }\n            else if (c < 6) {\n                y = (int)(n >> 58);\n                n = e[i--];\n                c = 6 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 58) & 0x3f;\n                n <<= 6;\n                c -= 6;\n            }\n\n            sp_3072_mont_sqr_avx2_48(r, r, m, mp);\n            sp_3072_mont_sqr_avx2_48(r, r, m, mp);\n            sp_3072_mont_sqr_avx2_48(r, r, m, mp);\n            sp_3072_mont_sqr_avx2_48(r, r, m, mp);\n            sp_3072_mont_sqr_avx2_48(r, r, m, mp);\n            sp_3072_mont_sqr_avx2_48(r, r, m, mp);\n\n            sp_3072_lshift_48(r, r, y);\n            sp_3072_mul_d_avx2_48(tmp, norm, r[48]);\n            r[48] = 0;\n            o = sp_3072_add_48(r, r, tmp);\n            sp_3072_cond_sub_48(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[48], 0, sizeof(sp_digit) * 48);\n        sp_3072_mont_reduce_avx2_48(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_48(r, m) >= 0);\n        sp_3072_cond_sub_48(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n#endif /* HAVE_INTEL_AVX2 */\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_3072_mod_exp_2_48(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[96];\n    sp_digit td[49];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 145, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 96;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_3072_mont_setup(m, &mp);\n        sp_3072_mont_norm_48(norm, m);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 6;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        sp_3072_lshift_48(r, norm, y);\n        for (; i>=0 || c>=6; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 58);\n                n <<= 6;\n                c = 58;\n            }\n            else if (c < 6) {\n                y = (int)(n >> 58);\n                n = e[i--];\n                c = 6 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 58) & 0x3f;\n                n <<= 6;\n                c -= 6;\n            }\n\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n            sp_3072_mont_sqr_48(r, r, m, mp);\n\n            sp_3072_lshift_48(r, r, y);\n            sp_3072_mul_d_48(tmp, norm, r[48]);\n            r[48] = 0;\n            o = sp_3072_add_48(r, r, tmp);\n            sp_3072_cond_sub_48(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[48], 0, sizeof(sp_digit) * 48);\n        sp_3072_mont_reduce_48(r, m, mp);\n\n        mask = 0 - (sp_3072_cmp_48(r, m) >= 0);\n        sp_3072_cond_sub_48(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n\n#endif /* HAVE_FFDHE_3072 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 384 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[96], e[48], m[48];\n    sp_digit* r = b;\n    word32 i;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    if (mp_count_bits(base) > 3072 || expLen > 384 ||\n                                                   mp_count_bits(mod) != 3072) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 48, base);\n        sp_3072_from_bin(e, 48, exp, expLen);\n        sp_3072_from_mp(m, 48, mod);\n\n    #ifdef HAVE_FFDHE_3072\n        if (base->used == 1 && base->dp[0] == 2 && m[47] == (sp_digit)-1) {\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n                err = sp_3072_mod_exp_2_avx2_48(r, e, expLen * 8, m);\n            else\n#endif\n                err = sp_3072_mod_exp_2_48(r, e, expLen * 8, m);\n        }\n        else\n    #endif\n        {\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n                err = sp_3072_mod_exp_avx2_48(r, b, e, expLen * 8, m, 0);\n            else\n#endif\n                err = sp_3072_mod_exp_48(r, b, e, expLen * 8, m, 0);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_to_bin(r, out);\n        *outLen = 384;\n        for (i=0; i<384 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[48], e[24], m[24];\n    sp_digit* r = b;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 1536 || expBits > 1536 ||\n                                                   mp_count_bits(mod) != 1536) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        sp_3072_from_mp(b, 24, base);\n        sp_3072_from_mp(e, 24, exp);\n        sp_3072_from_mp(m, 24, mod);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_3072_mod_exp_avx2_24(r, b, e, expBits, m, 0);\n        else\n#endif\n            err = sp_3072_mod_exp_24(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        XMEMSET(r + 24, 0, sizeof(*r) * 24);\n        err = sp_3072_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* !WOLFSSL_SP_NO_3072 */\n\n#ifdef WOLFSSL_SP_4096\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 56U) {\n            r[j] &= 0xffffffffffffffffl;\n            s = 64U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 64\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 64\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffffffffffffl;\n        s = 64U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 64U) <= (word32)DIGIT_BIT) {\n            s += 64U;\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 64) {\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 64 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 512\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_4096_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 4096 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<64 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 64) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 64);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\nextern sp_digit sp_4096_sub_in_place_64(sp_digit* a, const sp_digit* b);\nextern sp_digit sp_4096_add_64(sp_digit* r, const sp_digit* a, const sp_digit* b);\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[64];\n    sp_digit a1[32];\n    sp_digit b1[32];\n    sp_digit z2[64];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_32(a1, a, &a[32]);\n    cb = sp_2048_add_32(b1, b, &b[32]);\n    u  = ca & cb;\n    sp_2048_mul_32(z1, a1, b1);\n    sp_2048_mul_32(z2, &a[32], &b[32]);\n    sp_2048_mul_32(z0, a, b);\n    sp_2048_mask_32(r + 64, a1, 0 - cb);\n    sp_2048_mask_32(b1, b1, 0 - ca);\n    u += sp_2048_add_32(r + 64, r + 64, b1);\n    u += sp_4096_sub_in_place_64(z1, z2);\n    u += sp_4096_sub_in_place_64(z1, z0);\n    u += sp_4096_add_64(r + 32, r + 32, z1);\n    r[96] = u;\n    XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));\n    sp_4096_add_64(r + 64, r + 64, z2);\n}\n\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_64(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[64];\n    sp_digit z1[64];\n    sp_digit a1[32];\n    sp_digit u;\n\n    u = sp_2048_add_32(a1, a, &a[32]);\n    sp_2048_sqr_32(z1, a1);\n    sp_2048_sqr_32(z2, &a[32]);\n    sp_2048_sqr_32(z0, a);\n    sp_2048_mask_32(r + 64, a1, 0 - u);\n    u += sp_2048_add_32(r + 64, r + 64, r + 64);\n    u += sp_4096_sub_in_place_64(z1, z2);\n    u += sp_4096_sub_in_place_64(z1, z0);\n    u += sp_4096_add_64(r + 32, r + 32, z1);\n    r[96] = u;\n    XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));\n    sp_4096_add_64(r + 64, r + 64, z2);\n}\n\n#ifdef HAVE_INTEL_AVX2\n/* Multiply a and b into r. (r = a * b)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * b  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_mul_avx2_64(sp_digit* r, const sp_digit* a,\n        const sp_digit* b)\n{\n    sp_digit* z0 = r;\n    sp_digit z1[64];\n    sp_digit a1[32];\n    sp_digit b1[32];\n    sp_digit z2[64];\n    sp_digit u, ca, cb;\n\n    ca = sp_2048_add_32(a1, a, &a[32]);\n    cb = sp_2048_add_32(b1, b, &b[32]);\n    u  = ca & cb;\n    sp_2048_mul_avx2_32(z1, a1, b1);\n    sp_2048_mul_avx2_32(z2, &a[32], &b[32]);\n    sp_2048_mul_avx2_32(z0, a, b);\n    sp_2048_mask_32(r + 64, a1, 0 - cb);\n    sp_2048_mask_32(b1, b1, 0 - ca);\n    u += sp_2048_add_32(r + 64, r + 64, b1);\n    u += sp_4096_sub_in_place_64(z1, z2);\n    u += sp_4096_sub_in_place_64(z1, z0);\n    u += sp_4096_add_64(r + 32, r + 32, z1);\n    r[96] = u;\n    XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));\n    sp_4096_add_64(r + 64, r + 64, z2);\n}\n#endif /* HAVE_INTEL_AVX2 */\n\n#ifdef HAVE_INTEL_AVX2\n/* Square a and put result in r. (r = a * a)\n *\n * r  A single precision integer.\n * a  A single precision integer.\n */\nSP_NOINLINE static void sp_4096_sqr_avx2_64(sp_digit* r, const sp_digit* a)\n{\n    sp_digit* z0 = r;\n    sp_digit z2[64];\n    sp_digit z1[64];\n    sp_digit a1[32];\n    sp_digit u;\n\n    u = sp_2048_add_32(a1, a, &a[32]);\n    sp_2048_sqr_avx2_32(z1, a1);\n    sp_2048_sqr_avx2_32(z2, &a[32]);\n    sp_2048_sqr_avx2_32(z0, a);\n    sp_2048_mask_32(r + 64, a1, 0 - u);\n    u += sp_2048_add_32(r + 64, r + 64, r + 64);\n    u += sp_4096_sub_in_place_64(z1, z2);\n    u += sp_4096_sub_in_place_64(z1, z0);\n    u += sp_4096_add_64(r + 32, r + 32, z1);\n    r[96] = u;\n    XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1));\n    sp_4096_add_64(r + 64, r + 64, z2);\n}\n#endif /* HAVE_INTEL_AVX2 */\n\n/* Caclulate the bottom digit of -1/a mod 2^n.\n *\n * a    A single precision number.\n * rho  Bottom word of inverse.\n */\nstatic void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho)\n{\n    sp_digit x, b;\n\n    b = a[0];\n    x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n    x *= 2 - b * x;               /* here x*a==1 mod 2**64 */\n\n    /* rho = -1/m mod b */\n    *rho = -x;\n}\n\nextern void sp_4096_mul_d_64(sp_digit* r, const sp_digit* a, sp_digit b);\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n/* r = 2^n mod m where n is the number of bits to reduce by.\n * Given m must be 4096 bits, just need to subtract.\n *\n * r  A single precision number.\n * m  A signle precision number.\n */\nstatic void sp_4096_mont_norm_64(sp_digit* r, const sp_digit* m)\n{\n    XMEMSET(r, 0, sizeof(sp_digit) * 64);\n\n    /* r = 2^n mod m */\n    sp_4096_sub_in_place_64(r, m);\n}\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\nextern sp_digit sp_4096_cond_sub_64(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m);\nextern void sp_4096_mont_reduce_64(sp_digit* a, const sp_digit* m, sp_digit mp);\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_4096_mul_64(r, a, b);\n    sp_4096_mont_reduce_64(r, m, mp);\n}\n\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_sqr_64(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_4096_sqr_64(r, a);\n    sp_4096_mont_reduce_64(r, m, mp);\n}\n\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\nextern void sp_4096_mul_d_avx2_64(sp_digit* r, const sp_digit* a, const sp_digit b);\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n */\nstatic WC_INLINE sp_digit div_4096_word_64(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    register sp_digit r asm(\"rax\");\n    __asm__ __volatile__ (\n        \"divq %3\"\n        : \"=a\" (r)\n        : \"d\" (d1), \"a\" (d0), \"r\" (div)\n        :\n    );\n    return r;\n}\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_4096_mask_64(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<64; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    int i;\n\n    for (i = 0; i < 64; i += 8) {\n        r[i+0] = a[i+0] & m;\n        r[i+1] = a[i+1] & m;\n        r[i+2] = a[i+2] & m;\n        r[i+3] = a[i+3] & m;\n        r[i+4] = a[i+4] & m;\n        r[i+5] = a[i+5] & m;\n        r[i+6] = a[i+6] & m;\n        r[i+7] = a[i+7] & m;\n    }\n#endif\n}\n\nextern int64_t sp_4096_cmp_64(const sp_digit* a, const sp_digit* b);\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_div_64(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[128], t2[65];\n    sp_digit div, r1;\n    int i;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)m;\n\n    div = d[63];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 64);\n    for (i=63; i>=0; i--) {\n        r1 = div_4096_word_64(t1[64 + i], t1[64 + i - 1], div);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            sp_4096_mul_d_avx2_64(t2, d, r1);\n        else\n#endif\n            sp_4096_mul_d_64(t2, d, r1);\n        t1[64 + i] += sp_4096_sub_in_place_64(&t1[i], t2);\n        t1[64 + i] -= t2[64];\n        sp_4096_mask_64(t2, d, t1[64 + i]);\n        t1[64 + i] += sp_4096_add_64(&t1[i], &t1[i], t2);\n        sp_4096_mask_64(t2, d, t1[64 + i]);\n        t1[64 + i] += sp_4096_add_64(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_4096_cmp_64(t1, d) >= 0;\n    sp_4096_cond_sub_64(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_mod_64(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_64(a, m, NULL, r);\n}\n\n#endif /* WOLFSSL_RSA_PUBLIC_ONLY */\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_div_64_cond(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[128], t2[65];\n    sp_digit div, r1;\n    int i;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)m;\n\n    div = d[63];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 64);\n    for (i=63; i>=0; i--) {\n        r1 = div_4096_word_64(t1[64 + i], t1[64 + i - 1], div);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            sp_4096_mul_d_avx2_64(t2, d, r1);\n        else\n#endif\n            sp_4096_mul_d_64(t2, d, r1);\n        t1[64 + i] += sp_4096_sub_in_place_64(&t1[i], t2);\n        t1[64 + i] -= t2[64];\n        if (t1[64 + i] != 0) {\n            t1[64 + i] += sp_4096_add_64(&t1[i], &t1[i], d);\n            if (t1[64 + i] != 0)\n                t1[64 + i] += sp_4096_add_64(&t1[i], &t1[i], d);\n        }\n    }\n\n    r1 = sp_4096_cmp_64(t1, d) >= 0;\n    sp_4096_cond_sub_64(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_4096_mod_64_cond(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_4096_div_64_cond(a, m, NULL, r);\n}\n\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][128];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 128, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 128;\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_64(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 64);\n        if (reduceA) {\n            err = sp_4096_mod_64(t[1] + 64, a, m);\n            if (err == MP_OKAY)\n                err = sp_4096_mod_64(t[1], t[1], m);\n        }\n        else {\n            XMEMCPY(t[1] + 64, a, sizeof(sp_digit) * 64);\n            err = sp_4096_mod_64(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_64(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_64(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_64(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_64(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_64(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_64(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_64(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_64(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_64(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_64(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_64(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_64(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_64(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_64(t[15], t[ 8], t[ 7], m, mp);\n        sp_4096_mont_sqr_64(t[16], t[ 8], m, mp);\n        sp_4096_mont_mul_64(t[17], t[ 9], t[ 8], m, mp);\n        sp_4096_mont_sqr_64(t[18], t[ 9], m, mp);\n        sp_4096_mont_mul_64(t[19], t[10], t[ 9], m, mp);\n        sp_4096_mont_sqr_64(t[20], t[10], m, mp);\n        sp_4096_mont_mul_64(t[21], t[11], t[10], m, mp);\n        sp_4096_mont_sqr_64(t[22], t[11], m, mp);\n        sp_4096_mont_mul_64(t[23], t[12], t[11], m, mp);\n        sp_4096_mont_sqr_64(t[24], t[12], m, mp);\n        sp_4096_mont_mul_64(t[25], t[13], t[12], m, mp);\n        sp_4096_mont_sqr_64(t[26], t[13], m, mp);\n        sp_4096_mont_mul_64(t[27], t[14], t[13], m, mp);\n        sp_4096_mont_sqr_64(t[28], t[14], m, mp);\n        sp_4096_mont_mul_64(t[29], t[15], t[14], m, mp);\n        sp_4096_mont_sqr_64(t[30], t[15], m, mp);\n        sp_4096_mont_mul_64(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 5;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 64);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 59);\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = (int)(n >> 59);\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n\n            sp_4096_mont_mul_64(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64);\n        sp_4096_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_64(r, m) >= 0);\n        sp_4096_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\nextern void sp_4096_mont_reduce_avx2_64(sp_digit* a, const sp_digit* m, sp_digit mp);\n#ifdef HAVE_INTEL_AVX2\n/* Multiply two Montogmery form numbers mod the modulus (prime).\n * (r = a * b mod m)\n *\n * r   Result of multiplication.\n * a   First number to multiply in Montogmery form.\n * b   Second number to multiply in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_mul_avx2_64(sp_digit* r, const sp_digit* a, const sp_digit* b,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_4096_mul_avx2_64(r, a, b);\n    sp_4096_mont_reduce_avx2_64(r, m, mp);\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n#ifdef HAVE_INTEL_AVX2\n/* Square the Montgomery form number. (r = a * a mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_4096_mont_sqr_avx2_64(sp_digit* r, const sp_digit* a, const sp_digit* m,\n        sp_digit mp)\n{\n    sp_4096_sqr_avx2_64(r, a);\n    sp_4096_mont_reduce_avx2_64(r, m, mp);\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH)\n#ifdef HAVE_INTEL_AVX2\n/* Modular exponentiate a to the e mod m. (r = a^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * a     A single precision number being exponentiated.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_avx2_64(sp_digit* r, const sp_digit* a, const sp_digit* e,\n        int bits, const sp_digit* m, int reduceA)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit t[32][128];\n#else\n    sp_digit* t[32];\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit mp = 1;\n    sp_digit n;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 128, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        for (i=0; i<32; i++)\n            t[i] = td + i * 128;\n#endif\n        norm = t[0];\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_64(norm, m);\n\n        XMEMSET(t[1], 0, sizeof(sp_digit) * 64);\n        if (reduceA) {\n            err = sp_4096_mod_64(t[1] + 64, a, m);\n            if (err == MP_OKAY)\n                err = sp_4096_mod_64(t[1], t[1], m);\n        }\n        else {\n            XMEMCPY(t[1] + 64, a, sizeof(sp_digit) * 64);\n            err = sp_4096_mod_64(t[1], t[1], m);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_mont_sqr_avx2_64(t[ 2], t[ 1], m, mp);\n        sp_4096_mont_mul_avx2_64(t[ 3], t[ 2], t[ 1], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[ 4], t[ 2], m, mp);\n        sp_4096_mont_mul_avx2_64(t[ 5], t[ 3], t[ 2], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[ 6], t[ 3], m, mp);\n        sp_4096_mont_mul_avx2_64(t[ 7], t[ 4], t[ 3], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[ 8], t[ 4], m, mp);\n        sp_4096_mont_mul_avx2_64(t[ 9], t[ 5], t[ 4], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[10], t[ 5], m, mp);\n        sp_4096_mont_mul_avx2_64(t[11], t[ 6], t[ 5], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[12], t[ 6], m, mp);\n        sp_4096_mont_mul_avx2_64(t[13], t[ 7], t[ 6], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[14], t[ 7], m, mp);\n        sp_4096_mont_mul_avx2_64(t[15], t[ 8], t[ 7], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[16], t[ 8], m, mp);\n        sp_4096_mont_mul_avx2_64(t[17], t[ 9], t[ 8], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[18], t[ 9], m, mp);\n        sp_4096_mont_mul_avx2_64(t[19], t[10], t[ 9], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[20], t[10], m, mp);\n        sp_4096_mont_mul_avx2_64(t[21], t[11], t[10], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[22], t[11], m, mp);\n        sp_4096_mont_mul_avx2_64(t[23], t[12], t[11], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[24], t[12], m, mp);\n        sp_4096_mont_mul_avx2_64(t[25], t[13], t[12], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[26], t[13], m, mp);\n        sp_4096_mont_mul_avx2_64(t[27], t[14], t[13], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[28], t[14], m, mp);\n        sp_4096_mont_mul_avx2_64(t[29], t[15], t[14], m, mp);\n        sp_4096_mont_sqr_avx2_64(t[30], t[15], m, mp);\n        sp_4096_mont_mul_avx2_64(t[31], t[16], t[15], m, mp);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 5;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        XMEMCPY(r, t[y], sizeof(sp_digit) * 64);\n        for (; i>=0 || c>=5; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 59);\n                n <<= 5;\n                c = 59;\n            }\n            else if (c < 5) {\n                y = (int)(n >> 59);\n                n = e[i--];\n                c = 5 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 59) & 0x1f;\n                n <<= 5;\n                c -= 5;\n            }\n\n            sp_4096_mont_sqr_avx2_64(r, r, m, mp);\n            sp_4096_mont_sqr_avx2_64(r, r, m, mp);\n            sp_4096_mont_sqr_avx2_64(r, r, m, mp);\n            sp_4096_mont_sqr_avx2_64(r, r, m, mp);\n            sp_4096_mont_sqr_avx2_64(r, r, m, mp);\n\n            sp_4096_mont_mul_avx2_64(r, r, t[y], m, mp);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64);\n        sp_4096_mont_reduce_avx2_64(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_64(r, m) >= 0);\n        sp_4096_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n#endif /* HAVE_INTEL_AVX2 */\n#endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n/* RSA public key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * em      Public exponent.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[128], md[64], rd[128];\n#else\n    sp_digit* d = NULL;\n#endif\n    sp_digit* a;\n    sp_digit *ah;\n    sp_digit* m;\n    sp_digit* r;\n    sp_digit  e = 0;\n    int err = MP_OKAY;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    if (*outLen < 512)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (mp_count_bits(em) > 64 || inLen > 512 ||\n                                                     mp_count_bits(mm) != 4096))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 64 * 5, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (d == NULL)\n            err = MEMORY_E;\n    }\n\n    if (err == MP_OKAY) {\n        a = d;\n        r = a + 64 * 2;\n        m = r + 64 * 2;\n        ah = a + 64;\n    }\n#else\n    a = ad;\n    m = md;\n    r = rd;\n    ah = a + 64;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(ah, 64, in, inLen);\n#if DIGIT_BIT >= 64\n        e = em->dp[0];\n#else\n        e = em->dp[0];\n        if (em->used > 1)\n            e |= ((sp_digit)em->dp[1]) << DIGIT_BIT;\n#endif\n        if (e == 0)\n            err = MP_EXPTMOD_E;\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(m, 64, mm);\n\n        if (e == 0x3) {\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n                if (err == MP_OKAY) {\n                    sp_4096_sqr_avx2_64(r, ah);\n                    err = sp_4096_mod_64_cond(r, r, m);\n                }\n                if (err == MP_OKAY) {\n                    sp_4096_mul_avx2_64(r, ah, r);\n                    err = sp_4096_mod_64_cond(r, r, m);\n                }\n            }\n            else\n#endif\n            {\n                if (err == MP_OKAY) {\n                    sp_4096_sqr_64(r, ah);\n                    err = sp_4096_mod_64_cond(r, r, m);\n                }\n                if (err == MP_OKAY) {\n                    sp_4096_mul_64(r, ah, r);\n                    err = sp_4096_mod_64_cond(r, r, m);\n                }\n            }\n        }\n        else {\n            int i;\n            sp_digit mp;\n\n            sp_4096_mont_setup(m, &mp);\n\n            /* Convert to Montgomery form. */\n            XMEMSET(a, 0, sizeof(sp_digit) * 64);\n            err = sp_4096_mod_64_cond(a, a, m);\n\n            if (err == MP_OKAY) {\n                for (i=63; i>=0; i--) {\n                    if (e >> i) {\n                        break;\n                    }\n                }\n\n                XMEMCPY(r, a, sizeof(sp_digit) * 64);\n#ifdef HAVE_INTEL_AVX2\n                if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n                    for (i--; i>=0; i--) {\n                        sp_4096_mont_sqr_avx2_64(r, r, m, mp);\n                        if (((e >> i) & 1) == 1) {\n                            sp_4096_mont_mul_avx2_64(r, r, a, m, mp);\n                        }\n                    }\n                    XMEMSET(&r[64], 0, sizeof(sp_digit) * 64);\n                    sp_4096_mont_reduce_avx2_64(r, m, mp);\n                }\n                else\n#endif\n                {\n                    for (i--; i>=0; i--) {\n                        sp_4096_mont_sqr_64(r, r, m, mp);\n                        if (((e >> i) & 1) == 1) {\n                            sp_4096_mont_mul_64(r, r, a, m, mp);\n                        }\n                    }\n                    XMEMSET(&r[64], 0, sizeof(sp_digit) * 64);\n                    sp_4096_mont_reduce_64(r, m, mp);\n                }\n\n                for (i = 63; i > 0; i--) {\n                    if (r[i] != m[i])\n                        break;\n                }\n                if (r[i] >= m[i])\n                    sp_4096_sub_in_place_64(r, m);\n            }\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, NULL, DYNAMIC_TYPE_RSA);\n#endif\n\n    return err;\n}\n\n/* RSA private key operation.\n *\n * in      Array of bytes representing the number to exponentiate, base.\n * inLen   Number of bytes in base.\n * dm      Private exponent.\n * pm      First prime.\n * qm      Second prime.\n * dpm     First prime's CRT exponent.\n * dqm     Second prime's CRT exponent.\n * qim     Inverse of second prime mod p.\n * mm      Modulus.\n * out     Buffer to hold big-endian bytes of exponentiation result.\n *         Must be at least 512 bytes long.\n * outLen  Number of bytes in result.\n * returns 0 on success, MP_TO_E when the outLen is too small, MP_READ_E when\n * an array is too long and MEMORY_E when dynamic memory allocation fails.\n */\nint sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm,\n    mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim, mp_int* mm,\n    byte* out, word32* outLen)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit ad[64 * 2];\n    sp_digit pd[32], qd[32], dpd[32];\n    sp_digit tmpad[64], tmpbd[64];\n#else\n    sp_digit* t = NULL;\n#endif\n    sp_digit* a;\n    sp_digit* p;\n    sp_digit* q;\n    sp_digit* dp;\n    sp_digit* dq;\n    sp_digit* qi;\n    sp_digit* tmp;\n    sp_digit* tmpa;\n    sp_digit* tmpb;\n    sp_digit* r;\n    sp_digit c;\n    int err = MP_OKAY;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)dm;\n    (void)mm;\n\n    if (*outLen < 512)\n        err = MP_TO_E;\n    if (err == MP_OKAY && (inLen > 512 || mp_count_bits(mm) != 4096))\n        err = MP_READ_E;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 11, NULL,\n                                                              DYNAMIC_TYPE_RSA);\n        if (t == NULL)\n            err = MEMORY_E;\n    }\n    if (err == MP_OKAY) {\n        a = t;\n        p = a + 64 * 2;\n        q = p + 32;\n        qi = dq = dp = q + 32;\n        tmpa = qi + 32;\n        tmpb = tmpa + 64;\n\n        tmp = t;\n        r = tmp + 64;\n    }\n#else\n    r = a = ad;\n    p = pd;\n    q = qd;\n    qi = dq = dp = dpd;\n    tmpa = tmpad;\n    tmpb = tmpbd;\n    tmp = a + 64;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_4096_from_bin(a, 64, in, inLen);\n        sp_4096_from_mp(p, 32, pm);\n        sp_4096_from_mp(q, 32, qm);\n        sp_4096_from_mp(dp, 32, dpm);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_2048_mod_exp_avx2_32(tmpa, a, dp, 2048, p, 1);\n        else\n#endif\n            err = sp_2048_mod_exp_32(tmpa, a, dp, 2048, p, 1);\n    }\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(dq, 32, dqm);\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_2048_mod_exp_avx2_32(tmpb, a, dq, 2048, q, 1);\n       else\n#endif\n            err = sp_2048_mod_exp_32(tmpb, a, dq, 2048, q, 1);\n    }\n\n    if (err == MP_OKAY) {\n        c = sp_2048_sub_in_place_32(tmpa, tmpb);\n        sp_2048_mask_32(tmp, p, c);\n        sp_2048_add_32(tmpa, tmpa, tmp);\n\n        sp_2048_from_mp(qi, 32, qim);\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n            sp_2048_mul_avx2_32(tmpa, tmpa, qi);\n        }\n        else\n#endif\n        {\n            sp_2048_mul_32(tmpa, tmpa, qi);\n        }\n        err = sp_2048_mod_32(tmpa, tmpa, p);\n    }\n\n    if (err == MP_OKAY) {\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n            sp_2048_mul_avx2_32(tmpa, q, tmpa);\n        }\n        else\n#endif\n        {\n            sp_2048_mul_32(tmpa, q, tmpa);\n        }\n        XMEMSET(&tmpb[32], 0, sizeof(sp_digit) * 32);\n        sp_4096_add_64(r, tmpb, tmpa);\n\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XMEMSET(t, 0, sizeof(sp_digit) * 32 * 11);\n        XFREE(t, NULL, DYNAMIC_TYPE_RSA);\n    }\n#else\n    XMEMSET(tmpad, 0, sizeof(tmpad));\n    XMEMSET(tmpbd, 0, sizeof(tmpbd));\n    XMEMSET(pd, 0, sizeof(pd));\n    XMEMSET(qd, 0, sizeof(qd));\n    XMEMSET(dpd, 0, sizeof(dpd));\n#endif\n\n    return err;\n}\n#endif /* WOLFSSL_HAVE_SP_RSA */\n#if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \\\n                                              !defined(WOLFSSL_RSA_PUBLIC_ONLY))\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_4096_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (4096 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 64\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 64);\n        r->used = 64;\n        mp_clamp(r);\n#elif DIGIT_BIT < 64\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 64; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 64) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 64 - s;\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 64; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 64 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 64 - s;\n            }\n            else {\n                s += 64;\n            }\n        }\n        r->used = (4096 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base  Base. MP integer.\n * exp   Exponent. MP integer.\n * mod   Modulus. MP integer.\n * res   Result. MP integer.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res)\n{\n    int err = MP_OKAY;\n    sp_digit b[128], e[64], m[64];\n    sp_digit* r = b;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n    int expBits = mp_count_bits(exp);\n\n    if (mp_count_bits(base) > 4096 || expBits > 4096 ||\n                                                   mp_count_bits(mod) != 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 64, base);\n        sp_4096_from_mp(e, 64, exp);\n        sp_4096_from_mp(m, 64, mod);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_4096_mod_exp_avx2_64(r, b, e, expBits, m, 0);\n        else\n#endif\n            err = sp_4096_mod_exp_64(r, b, e, expBits, m, 0);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_4096_to_mp(r, res);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n\n#ifdef WOLFSSL_HAVE_SP_DH\n#ifdef HAVE_FFDHE_4096\nextern void sp_4096_lshift_64(sp_digit* r, const sp_digit* a, int n);\n#ifdef HAVE_INTEL_AVX2\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_2_avx2_64(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[128];\n    sp_digit td[65];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 193, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 128;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_64(norm, m);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 6;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        sp_4096_lshift_64(r, norm, y);\n        for (; i>=0 || c>=6; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 58);\n                n <<= 6;\n                c = 58;\n            }\n            else if (c < 6) {\n                y = (int)(n >> 58);\n                n = e[i--];\n                c = 6 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 58) & 0x3f;\n                n <<= 6;\n                c -= 6;\n            }\n\n            sp_4096_mont_sqr_avx2_64(r, r, m, mp);\n            sp_4096_mont_sqr_avx2_64(r, r, m, mp);\n            sp_4096_mont_sqr_avx2_64(r, r, m, mp);\n            sp_4096_mont_sqr_avx2_64(r, r, m, mp);\n            sp_4096_mont_sqr_avx2_64(r, r, m, mp);\n            sp_4096_mont_sqr_avx2_64(r, r, m, mp);\n\n            sp_4096_lshift_64(r, r, y);\n            sp_4096_mul_d_avx2_64(tmp, norm, r[64]);\n            r[64] = 0;\n            o = sp_4096_add_64(r, r, tmp);\n            sp_4096_cond_sub_64(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64);\n        sp_4096_mont_reduce_avx2_64(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_64(r, m) >= 0);\n        sp_4096_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n#endif /* HAVE_INTEL_AVX2 */\n\n/* Modular exponentiate 2 to the e mod m. (r = 2^e mod m)\n *\n * r     A single precision number that is the result of the operation.\n * e     A single precision number that is the exponent.\n * bits  The number of bits in the exponent.\n * m     A single precision number that is the modulus.\n * returns 0 on success and MEMORY_E on dynamic memory allocation failure.\n */\nstatic int sp_4096_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits,\n        const sp_digit* m)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    sp_digit nd[128];\n    sp_digit td[65];\n#else\n    sp_digit* td;\n#endif\n    sp_digit* norm;\n    sp_digit* tmp;\n    sp_digit mp = 1;\n    sp_digit n, o;\n    sp_digit mask;\n    int i;\n    int c, y;\n    int err = MP_OKAY;\n\n#ifdef WOLFSSL_SMALL_STACK\n    td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 193, NULL,\n                            DYNAMIC_TYPE_TMP_BUFFER);\n    if (td == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n        norm = td;\n        tmp  = td + 128;\n#else\n        norm = nd;\n        tmp  = td;\n#endif\n\n        sp_4096_mont_setup(m, &mp);\n        sp_4096_mont_norm_64(norm, m);\n\n        i = (bits - 1) / 64;\n        n = e[i--];\n        c = bits & 63;\n        if (c == 0)\n            c = 64;\n        c -= bits % 6;\n        y = (int)(n >> c);\n        n <<= 64 - c;\n        sp_4096_lshift_64(r, norm, y);\n        for (; i>=0 || c>=6; ) {\n            if (c == 0) {\n                n = e[i--];\n                y = (int)(n >> 58);\n                n <<= 6;\n                c = 58;\n            }\n            else if (c < 6) {\n                y = (int)(n >> 58);\n                n = e[i--];\n                c = 6 - c;\n                y |= n >> (64 - c);\n                n <<= c;\n                c = 64 - c;\n            }\n            else {\n                y = (n >> 58) & 0x3f;\n                n <<= 6;\n                c -= 6;\n            }\n\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n            sp_4096_mont_sqr_64(r, r, m, mp);\n\n            sp_4096_lshift_64(r, r, y);\n            sp_4096_mul_d_64(tmp, norm, r[64]);\n            r[64] = 0;\n            o = sp_4096_add_64(r, r, tmp);\n            sp_4096_cond_sub_64(r, r, m, (sp_digit)0 - o);\n        }\n\n        XMEMSET(&r[64], 0, sizeof(sp_digit) * 64);\n        sp_4096_mont_reduce_64(r, m, mp);\n\n        mask = 0 - (sp_4096_cmp_64(r, m) >= 0);\n        sp_4096_cond_sub_64(r, r, m, mask);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    if (td != NULL)\n        XFREE(td, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return err;\n}\n\n#endif /* HAVE_FFDHE_4096 */\n\n/* Perform the modular exponentiation for Diffie-Hellman.\n *\n * base     Base.\n * exp      Array of bytes that is the exponent.\n * expLen   Length of data, in bytes, in exponent.\n * mod      Modulus.\n * out      Buffer to hold big-endian bytes of exponentiation result.\n *          Must be at least 512 bytes long.\n * outLen   Length, in bytes, of exponentiation result.\n * returs 0 on success, MP_READ_E if there are too many bytes in an array\n * and MEMORY_E if memory allocation fails.\n */\nint sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen)\n{\n    int err = MP_OKAY;\n    sp_digit b[128], e[64], m[64];\n    sp_digit* r = b;\n    word32 i;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    if (mp_count_bits(base) > 4096 || expLen > 512 ||\n                                                   mp_count_bits(mod) != 4096) {\n        err = MP_READ_E;\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_from_mp(b, 64, base);\n        sp_4096_from_bin(e, 64, exp, expLen);\n        sp_4096_from_mp(m, 64, mod);\n\n    #ifdef HAVE_FFDHE_4096\n        if (base->used == 1 && base->dp[0] == 2 && m[63] == (sp_digit)-1) {\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n                err = sp_4096_mod_exp_2_avx2_64(r, e, expLen * 8, m);\n            else\n#endif\n                err = sp_4096_mod_exp_2_64(r, e, expLen * 8, m);\n        }\n        else\n    #endif\n        {\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n                err = sp_4096_mod_exp_avx2_64(r, b, e, expLen * 8, m, 0);\n            else\n#endif\n                err = sp_4096_mod_exp_64(r, b, e, expLen * 8, m, 0);\n        }\n    }\n\n    if (err == MP_OKAY) {\n        sp_4096_to_bin(r, out);\n        *outLen = 512;\n        for (i=0; i<512 && out[i] == 0; i++) {\n        }\n        *outLen -= i;\n        XMEMMOVE(out, out + i, *outLen);\n    }\n\n    XMEMSET(e, 0, sizeof(e));\n\n    return err;\n}\n#endif\n#endif /* WOLFSSL_HAVE_SP_DH || (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) */\n\n#endif /* WOLFSSL_SP_4096 */\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH */\n#ifdef WOLFSSL_HAVE_SP_ECC\n#ifndef WOLFSSL_SP_NO_256\n\n/* Point structure to use. */\ntypedef struct sp_point {\n    sp_digit x[2 * 4];\n    sp_digit y[2 * 4];\n    sp_digit z[2 * 4];\n    int infinity;\n} sp_point;\n\n/* The modulus (prime) of the curve P256. */\nstatic const sp_digit p256_mod[4] = {\n    0xffffffffffffffffL,0x00000000ffffffffL,0x0000000000000000L,\n    0xffffffff00000001L\n};\n/* The Montogmery normalizer for modulus of the curve P256. */\nstatic const sp_digit p256_norm_mod[4] = {\n    0x0000000000000001L,0xffffffff00000000L,0xffffffffffffffffL,\n    0x00000000fffffffeL\n};\n/* The Montogmery multiplier for modulus of the curve P256. */\nstatic const sp_digit p256_mp_mod = 0x0000000000000001;\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                            defined(HAVE_ECC_VERIFY)\n/* The order of the curve P256. */\nstatic const sp_digit p256_order[4] = {\n    0xf3b9cac2fc632551L,0xbce6faada7179e84L,0xffffffffffffffffL,\n    0xffffffff00000000L\n};\n#endif\n/* The order of the curve P256 minus 2. */\nstatic const sp_digit p256_order2[4] = {\n    0xf3b9cac2fc63254fL,0xbce6faada7179e84L,0xffffffffffffffffL,\n    0xffffffff00000000L\n};\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery normalizer for order of the curve P256. */\nstatic const sp_digit p256_norm_order[4] = {\n    0x0c46353d039cdaafL,0x4319055258e8617bL,0x0000000000000000L,\n    0x00000000ffffffffL\n};\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\n/* The Montogmery multiplier for order of the curve P256. */\nstatic const sp_digit p256_mp_order = 0xccd1c8aaee00bc4fL;\n#endif\n#ifdef WOLFSSL_SP_SMALL\n/* The base point of curve P256. */\nstatic const sp_point p256_base = {\n    /* X ordinate */\n    {\n        0xf4a13945d898c296L,0x77037d812deb33a0L,0xf8bce6e563a440f2L,\n        0x6b17d1f2e12c4247L, 0L, 0L, 0L, 0L\n    },\n    /* Y ordinate */\n    {\n        0xcbb6406837bf51f5L,0x2bce33576b315eceL,0x8ee7eb4a7c0f9e16L,\n        0x4fe342e2fe1a7f9bL, 0L, 0L, 0L, 0L\n    },\n    /* Z ordinate */\n    {\n        0x0000000000000001L,0x0000000000000000L,0x0000000000000000L,\n        0x0000000000000000L, 0L, 0L, 0L, 0L\n    },\n    /* infinity */\n    0\n};\n#endif /* WOLFSSL_SP_SMALL */\n#if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY)\nstatic const sp_digit p256_b[4] = {\n    0x3bce3c3e27d2604bL,0x651d06b0cc53b0f6L,0xb3ebbd55769886bcL,\n    0x5ac635d8aa3a93e7L\n};\n#endif\n\nstatic int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p)\n{\n    int ret = MP_OKAY;\n    (void)heap;\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    (void)sp;\n    *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC);\n#else\n    *p = sp;\n#endif\n    if (p == NULL) {\n        ret = MEMORY_E;\n    }\n    return ret;\n}\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* Allocate memory for point and return error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p))\n#else\n/* Set pointer to data and return no error. */\n#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p))\n#endif\n\n\nstatic void sp_ecc_point_free(sp_point* p, int clear, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n/* If valid pointer then clear point data if requested and free data. */\n    if (p != NULL) {\n        if (clear != 0) {\n            XMEMSET(p, 0, sizeof(*p));\n        }\n        XFREE(p, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n/* Clear point data if requested. */\n    if (clear != 0) {\n        XMEMSET(p, 0, sizeof(*p));\n    }\n#endif\n    (void)heap;\n}\n\n/* Multiply a number by Montogmery normalizer mod modulus (prime).\n *\n * r  The resulting Montgomery form number.\n * a  The number to convert.\n * m  The modulus (prime).\n */\nstatic int sp_256_mod_mul_norm_4(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    int64_t t[8];\n    int64_t a32[8];\n    int64_t o;\n\n    (void)m;\n\n    a32[0] = a[0] & 0xffffffff;\n    a32[1] = a[0] >> 32;\n    a32[2] = a[1] & 0xffffffff;\n    a32[3] = a[1] >> 32;\n    a32[4] = a[2] & 0xffffffff;\n    a32[5] = a[2] >> 32;\n    a32[6] = a[3] & 0xffffffff;\n    a32[7] = a[3] >> 32;\n\n    /*  1  1  0 -1 -1 -1 -1  0 */\n    t[0] = 0 + a32[0] + a32[1] - a32[3] - a32[4] - a32[5] - a32[6];\n    /*  0  1  1  0 -1 -1 -1 -1 */\n    t[1] = 0 + a32[1] + a32[2] - a32[4] - a32[5] - a32[6] - a32[7];\n    /*  0  0  1  1  0 -1 -1 -1 */\n    t[2] = 0 + a32[2] + a32[3] - a32[5] - a32[6] - a32[7];\n    /* -1 -1  0  2  2  1  0 -1 */\n    t[3] = 0 - a32[0] - a32[1] + 2 * a32[3] + 2 * a32[4] + a32[5] - a32[7];\n    /*  0 -1 -1  0  2  2  1  0 */\n    t[4] = 0 - a32[1] - a32[2] + 2 * a32[4] + 2 * a32[5] + a32[6];\n    /*  0  0 -1 -1  0  2  2  1 */\n    t[5] = 0 - a32[2] - a32[3] + 2 * a32[5] + 2 * a32[6] + a32[7];\n    /* -1 -1  0  0  0  1  3  2 */\n    t[6] = 0 - a32[0] - a32[1] + a32[5] + 3 * a32[6] + 2 * a32[7];\n    /*  1  0 -1 -1 -1 -1  0  3 */\n    t[7] = 0 + a32[0] - a32[2] - a32[3] - a32[4] - a32[5] + 3 * a32[7];\n\n    t[1] += t[0] >> 32; t[0] &= 0xffffffff;\n    t[2] += t[1] >> 32; t[1] &= 0xffffffff;\n    t[3] += t[2] >> 32; t[2] &= 0xffffffff;\n    t[4] += t[3] >> 32; t[3] &= 0xffffffff;\n    t[5] += t[4] >> 32; t[4] &= 0xffffffff;\n    t[6] += t[5] >> 32; t[5] &= 0xffffffff;\n    t[7] += t[6] >> 32; t[6] &= 0xffffffff;\n    o     = t[7] >> 32; t[7] &= 0xffffffff;\n    t[0] += o;\n    t[3] -= o;\n    t[6] -= o;\n    t[7] += o;\n    t[1] += t[0] >> 32; t[0] &= 0xffffffff;\n    t[2] += t[1] >> 32; t[1] &= 0xffffffff;\n    t[3] += t[2] >> 32; t[2] &= 0xffffffff;\n    t[4] += t[3] >> 32; t[3] &= 0xffffffff;\n    t[5] += t[4] >> 32; t[4] &= 0xffffffff;\n    t[6] += t[5] >> 32; t[5] &= 0xffffffff;\n    t[7] += t[6] >> 32; t[6] &= 0xffffffff;\n    r[0] = (t[1] << 32) | t[0];\n    r[1] = (t[3] << 32) | t[2];\n    r[2] = (t[5] << 32) | t[4];\n    r[3] = (t[7] << 32) | t[6];\n\n    return MP_OKAY;\n}\n\n/* Convert an mp_int to an array of sp_digit.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  A multi-precision integer.\n */\nstatic void sp_256_from_mp(sp_digit* r, int size, const mp_int* a)\n{\n#if DIGIT_BIT == 64\n    int j;\n\n    XMEMCPY(r, a->dp, sizeof(sp_digit) * a->used);\n\n    for (j = a->used; j < size; j++) {\n        r[j] = 0;\n    }\n#elif DIGIT_BIT > 64\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i] << s);\n        r[j] &= 0xffffffffffffffffl;\n        s = 64U - s;\n        if (j + 1 >= size) {\n            break;\n        }\n        /* lint allow cast of mismatch word32 and mp_digit */\n        r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n        while ((s + 64U) <= (word32)DIGIT_BIT) {\n            s += 64U;\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            if (s < (word32)DIGIT_BIT) {\n                /* lint allow cast of mismatch word32 and mp_digit */\n                r[++j] = (sp_digit)(a->dp[i] >> s); /*lint !e9033*/\n            }\n            else {\n                r[++j] = 0L;\n            }\n        }\n        s = (word32)DIGIT_BIT - s;\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#else\n    int i, j = 0, s = 0;\n\n    r[0] = 0;\n    for (i = 0; i < a->used && j < size; i++) {\n        r[j] |= ((sp_digit)a->dp[i]) << s;\n        if (s + DIGIT_BIT >= 64) {\n            r[j] &= 0xffffffffffffffffl;\n            if (j + 1 >= size) {\n                break;\n            }\n            s = 64 - s;\n            if (s == DIGIT_BIT) {\n                r[++j] = 0;\n                s = 0;\n            }\n            else {\n                r[++j] = a->dp[i] >> s;\n                s = DIGIT_BIT - s;\n            }\n        }\n        else {\n            s += DIGIT_BIT;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n#endif\n}\n\n/* Convert a point of type ecc_point to type sp_point.\n *\n * p   Point of type sp_point (result).\n * pm  Point of type ecc_point.\n */\nstatic void sp_256_point_from_ecc_point_4(sp_point* p, const ecc_point* pm)\n{\n    XMEMSET(p->x, 0, sizeof(p->x));\n    XMEMSET(p->y, 0, sizeof(p->y));\n    XMEMSET(p->z, 0, sizeof(p->z));\n    sp_256_from_mp(p->x, 4, pm->x);\n    sp_256_from_mp(p->y, 4, pm->y);\n    sp_256_from_mp(p->z, 4, pm->z);\n    p->infinity = 0;\n}\n\n/* Convert an array of sp_digit to an mp_int.\n *\n * a  A single precision integer.\n * r  A multi-precision integer.\n */\nstatic int sp_256_to_mp(const sp_digit* a, mp_int* r)\n{\n    int err;\n\n    err = mp_grow(r, (256 + DIGIT_BIT - 1) / DIGIT_BIT);\n    if (err == MP_OKAY) { /*lint !e774 case where err is always MP_OKAY*/\n#if DIGIT_BIT == 64\n        XMEMCPY(r->dp, a, sizeof(sp_digit) * 4);\n        r->used = 4;\n        mp_clamp(r);\n#elif DIGIT_BIT < 64\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 4; i++) {\n            r->dp[j] |= a[i] << s;\n            r->dp[j] &= (1L << DIGIT_BIT) - 1;\n            s = DIGIT_BIT - s;\n            r->dp[++j] = a[i] >> s;\n            while (s + DIGIT_BIT <= 64) {\n                s += DIGIT_BIT;\n                r->dp[j++] &= (1L << DIGIT_BIT) - 1;\n                if (s == SP_WORD_SIZE) {\n                    r->dp[j] = 0;\n                }\n                else {\n                    r->dp[j] = a[i] >> s;\n                }\n            }\n            s = 64 - s;\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#else\n        int i, j = 0, s = 0;\n\n        r->dp[0] = 0;\n        for (i = 0; i < 4; i++) {\n            r->dp[j] |= ((mp_digit)a[i]) << s;\n            if (s + 64 >= DIGIT_BIT) {\n    #if DIGIT_BIT != 32 && DIGIT_BIT != 64\n                r->dp[j] &= (1L << DIGIT_BIT) - 1;\n    #endif\n                s = DIGIT_BIT - s;\n                r->dp[++j] = a[i] >> s;\n                s = 64 - s;\n            }\n            else {\n                s += 64;\n            }\n        }\n        r->used = (256 + DIGIT_BIT - 1) / DIGIT_BIT;\n        mp_clamp(r);\n#endif\n    }\n\n    return err;\n}\n\n/* Convert a point of type sp_point to type ecc_point.\n *\n * p   Point of type sp_point.\n * pm  Point of type ecc_point (result).\n * returns MEMORY_E when allocation of memory in ecc_point fails otherwise\n * MP_OKAY.\n */\nstatic int sp_256_point_to_ecc_point_4(const sp_point* p, ecc_point* pm)\n{\n    int err;\n\n    err = sp_256_to_mp(p->x, pm->x);\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pm->y);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pm->z);\n    }\n\n    return err;\n}\n\nextern void sp_256_cond_copy_4(sp_digit* r, const sp_digit* a, sp_digit m);\nextern int64_t sp_256_cmp_4(const sp_digit* a, const sp_digit* b);\n/* Normalize the values in each word to 64.\n *\n * a  Array of sp_digit to normalize.\n */\n#define sp_256_norm_4(a)\n\nextern sp_digit sp_256_cond_sub_4(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m);\nextern sp_digit sp_256_sub_4(sp_digit* r, const sp_digit* a, const sp_digit* b);\n#define sp_256_mont_reduce_order_4         sp_256_mont_reduce_4\n\nextern void sp_256_mont_reduce_4(sp_digit* a, const sp_digit* m, sp_digit mp);\nextern void sp_256_mont_mul_4(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m, sp_digit mp);\nextern void sp_256_mont_sqr_4(sp_digit* r, const sp_digit* a, const sp_digit* m, sp_digit mp);\n#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)\n/* Square the Montgomery form number a number of times. (r = a ^ n mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * n   Number of times to square.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_sqr_n_4(sp_digit* r, const sp_digit* a, int n,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_256_mont_sqr_4(r, a, m, mp);\n    for (; n > 1; n--) {\n        sp_256_mont_sqr_4(r, r, m, mp);\n    }\n}\n\n#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */\n#ifdef WOLFSSL_SP_SMALL\n/* Mod-2 for the P256 curve. */\nstatic const uint64_t p256_mod_2[4] = {\n    0xfffffffffffffffdU,0x00000000ffffffffU,0x0000000000000000U,\n    0xffffffff00000001U\n};\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the modulus (prime) of the\n * P256 curve. (r = 1 / a mod m)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_4(sp_digit* r, const sp_digit* a, sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 4);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_4(t, t, p256_mod, p256_mp_mod);\n        if (p256_mod_2[i / 64] & ((sp_digit)1 << (i % 64)))\n            sp_256_mont_mul_4(t, t, a, p256_mod, p256_mp_mod);\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 4);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 4;\n    sp_digit* t3 = td + 4 * 4;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_4(t, a, p256_mod, p256_mp_mod);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_4(t, t, a, p256_mod, p256_mp_mod);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_4(t2, t, 2, p256_mod, p256_mp_mod);\n    /* t3= a^d = t2 * a */\n    sp_256_mont_mul_4(t3, t2, a, p256_mod, p256_mp_mod);\n    /* t = a^f = t2 * t */\n    sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^f0 = t ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_4(t2, t, 4, p256_mod, p256_mp_mod);\n    /* t3= a^fd = t2 * t3 */\n    sp_256_mont_mul_4(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ff = t2 * t */\n    sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_4(t2, t, 8, p256_mod, p256_mp_mod);\n    /* t3= a^fffd = t2 * t3 */\n    sp_256_mont_mul_4(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_4(t2, t, 16, p256_mod, p256_mp_mod);\n    /* t3= a^fffffffd = t2 * t3 */\n    sp_256_mont_mul_4(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff00000000 = t ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_4(t2, t, 32, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001 = t2 * a */\n    sp_256_mont_mul_4(t2, t2, a, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff000000010000000000000000000000000000000000000000\n     *   = t2 ^ 2 ^ 160 */\n    sp_256_mont_sqr_n_4(t2, t2, 160, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff\n     *   = t2 * t */\n    sp_256_mont_mul_4(t2, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000\n     *   = t2 ^ 2 ^ 32 */\n    sp_256_mont_sqr_n_4(t2, t2, 32, p256_mod, p256_mp_mod);\n    /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd\n     *   = t2 * t3 */\n    sp_256_mont_mul_4(r, t2, t3, p256_mod, p256_mp_mod);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Map the Montgomery form projective co-ordinate point to an affine point.\n *\n * r  Resulting affine co-ordinate point.\n * p  Montgomery form projective co-ordinate point.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_map_4(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    int64_t n;\n\n    sp_256_mont_inv_4(t1, p->z, t + 2*4);\n\n    sp_256_mont_sqr_4(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    /* x /= z^2 */\n    sp_256_mont_mul_4(r->x, p->x, t2, p256_mod, p256_mp_mod);\n    XMEMSET(r->x + 4, 0, sizeof(r->x) / 2U);\n    sp_256_mont_reduce_4(r->x, p256_mod, p256_mp_mod);\n    /* Reduce x to less than modulus */\n    n = sp_256_cmp_4(r->x, p256_mod);\n    sp_256_cond_sub_4(r->x, r->x, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_4(r->x);\n\n    /* y /= z^3 */\n    sp_256_mont_mul_4(r->y, p->y, t1, p256_mod, p256_mp_mod);\n    XMEMSET(r->y + 4, 0, sizeof(r->y) / 2U);\n    sp_256_mont_reduce_4(r->y, p256_mod, p256_mp_mod);\n    /* Reduce y to less than modulus */\n    n = sp_256_cmp_4(r->y, p256_mod);\n    sp_256_cond_sub_4(r->y, r->y, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_4(r->y);\n\n    XMEMSET(r->z, 0, sizeof(r->z));\n    r->z[0] = 1;\n\n}\n\nextern void sp_256_mont_add_4(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m);\nextern void sp_256_mont_dbl_4(const sp_digit* r, const sp_digit* a, const sp_digit* m);\nextern void sp_256_mont_tpl_4(sp_digit* r, const sp_digit* a, const sp_digit* m);\nextern void sp_256_mont_sub_4(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m);\nextern void sp_256_div2_4(sp_digit* r, const sp_digit* a, const sp_digit* m);\n/* Double the Montgomery form projective point p.\n *\n * r  Result of doubling point.\n * p  Point to double.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_4(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* When infinity don't double point passed in - constant time. */\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    /* Put point to double into result - good for infinty. */\n    if (r != p) {\n        for (i=0; i<4; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<4; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<4; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* T1 = Z * Z */\n    sp_256_mont_sqr_4(t1, z, p256_mod, p256_mp_mod);\n    /* Z = Y * Z */\n    sp_256_mont_mul_4(z, y, z, p256_mod, p256_mp_mod);\n    /* Z = 2Z */\n    sp_256_mont_dbl_4(z, z, p256_mod);\n    /* T2 = X - T1 */\n    sp_256_mont_sub_4(t2, x, t1, p256_mod);\n    /* T1 = X + T1 */\n    sp_256_mont_add_4(t1, x, t1, p256_mod);\n    /* T2 = T1 * T2 */\n    sp_256_mont_mul_4(t2, t1, t2, p256_mod, p256_mp_mod);\n    /* T1 = 3T2 */\n    sp_256_mont_tpl_4(t1, t2, p256_mod);\n    /* Y = 2Y */\n    sp_256_mont_dbl_4(y, y, p256_mod);\n    /* Y = Y * Y */\n    sp_256_mont_sqr_4(y, y, p256_mod, p256_mp_mod);\n    /* T2 = Y * Y */\n    sp_256_mont_sqr_4(t2, y, p256_mod, p256_mp_mod);\n    /* T2 = T2/2 */\n    sp_256_div2_4(t2, t2, p256_mod);\n    /* Y = Y * X */\n    sp_256_mont_mul_4(y, y, x, p256_mod, p256_mp_mod);\n    /* X = T1 * T1 */\n    sp_256_mont_mul_4(x, t1, t1, p256_mod, p256_mp_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_4(x, x, y, p256_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_4(x, x, y, p256_mod);\n    /* Y = Y - X */\n    sp_256_mont_sub_4(y, y, x, p256_mod);\n    /* Y = Y * T1 */\n    sp_256_mont_mul_4(y, y, t1, p256_mod, p256_mp_mod);\n    /* Y = Y - T2 */\n    sp_256_mont_sub_4(y, y, t2, p256_mod);\n\n}\n\n/* Double the Montgomery form projective point p a number of times.\n *\n * r  Result of repeated doubling of point.\n * p  Point to double.\n * n  Number of times to double\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_n_4(sp_point* r, const sp_point* p, int n,\n        sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* w = t;\n    sp_digit* a = t + 2*4;\n    sp_digit* b = t + 4*4;\n    sp_digit* t1 = t + 6*4;\n    sp_digit* t2 = t + 8*4;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    if (r != p) {\n        for (i=0; i<4; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<4; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<4; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* Y = 2*Y */\n    sp_256_mont_dbl_4(y, y, p256_mod);\n    /* W = Z^4 */\n    sp_256_mont_sqr_4(w, z, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_4(w, w, p256_mod, p256_mp_mod);\n    while (n-- > 0) {\n        /* A = 3*(X^2 - W) */\n        sp_256_mont_sqr_4(t1, x, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(t1, t1, w, p256_mod);\n        sp_256_mont_tpl_4(a, t1, p256_mod);\n        /* B = X*Y^2 */\n        sp_256_mont_sqr_4(t2, y, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(b, t2, x, p256_mod, p256_mp_mod);\n        /* X = A^2 - 2B */\n        sp_256_mont_sqr_4(x, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_4(t1, b, p256_mod);\n        sp_256_mont_sub_4(x, x, t1, p256_mod);\n        /* Z = Z*Y */\n        sp_256_mont_mul_4(z, z, y, p256_mod, p256_mp_mod);\n        /* t2 = Y^4 */\n        sp_256_mont_sqr_4(t2, t2, p256_mod, p256_mp_mod);\n        if (n != 0) {\n            /* W = W*Y^4 */\n            sp_256_mont_mul_4(w, w, t2, p256_mod, p256_mp_mod);\n        }\n        /* y = 2*A*(B - X) - Y^4 */\n        sp_256_mont_sub_4(y, b, x, p256_mod);\n        sp_256_mont_mul_4(y, y, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_4(y, y, p256_mod);\n        sp_256_mont_sub_4(y, y, t2, p256_mod);\n    }\n    /* Y = Y/2 */\n    sp_256_div2_4(y, y, p256_mod);\n}\n\n/* Compare two numbers to determine if they are equal.\n * Constant time implementation.\n *\n * a  First number to compare.\n * b  Second number to compare.\n * returns 1 when equal and 0 otherwise.\n */\nstatic int sp_256_cmp_equal_4(const sp_digit* a, const sp_digit* b)\n{\n    return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3])) == 0;\n}\n\n/* Add two Montgomery form projective points.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_4(sp_point* r, const sp_point* p, const sp_point* q,\n        sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    sp_digit* t3 = t + 4*4;\n    sp_digit* t4 = t + 6*4;\n    sp_digit* t5 = t + 8*4;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Ensure only the first point is the same as the result. */\n    if (q == r) {\n        const sp_point* a = p;\n        p = q;\n        q = a;\n    }\n\n    /* Check double */\n    (void)sp_256_sub_4(t1, p256_mod, q->y);\n    sp_256_norm_4(t1);\n    if ((sp_256_cmp_equal_4(p->x, q->x) & sp_256_cmp_equal_4(p->z, q->z) &\n        (sp_256_cmp_equal_4(p->y, q->y) | sp_256_cmp_equal_4(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_4(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<4; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<4; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<4; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U1 = X1*Z2^2 */\n        sp_256_mont_sqr_4(t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t3, t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t1, t1, x, p256_mod, p256_mp_mod);\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_4(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S1 = Y1*Z2^3 */\n        sp_256_mont_mul_4(t3, t3, y, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_4(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - U1 */\n        sp_256_mont_sub_4(t2, t2, t1, p256_mod);\n        /* R = S2 - S1 */\n        sp_256_mont_sub_4(t4, t4, t3, p256_mod);\n        /* Z3 = H*Z1*Z2 */\n        sp_256_mont_mul_4(z, z, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*U1*H^2 */\n        sp_256_mont_sqr_4(x, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_4(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(y, t1, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(x, x, t5, p256_mod);\n        sp_256_mont_dbl_4(t1, y, p256_mod);\n        sp_256_mont_sub_4(x, x, t1, p256_mod);\n        /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */\n        sp_256_mont_sub_4(y, y, x, p256_mod);\n        sp_256_mont_mul_4(y, y, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t5, t5, t3, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(y, y, t5, p256_mod);\n    }\n}\n\n/* Double the Montgomery form projective point p a number of times.\n *\n * r  Result of repeated doubling of point.\n * p  Point to double.\n * n  Number of times to double\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_n_store_4(sp_point* r, const sp_point* p,\n        int n, int m, sp_digit* t)\n{\n    sp_digit* w = t;\n    sp_digit* a = t + 2*4;\n    sp_digit* b = t + 4*4;\n    sp_digit* t1 = t + 6*4;\n    sp_digit* t2 = t + 8*4;\n    sp_digit* x = r[2*m].x;\n    sp_digit* y = r[(1<<n)*m].y;\n    sp_digit* z = r[2*m].z;\n    int i;\n\n    for (i=0; i<4; i++) {\n        x[i] = p->x[i];\n    }\n    for (i=0; i<4; i++) {\n        y[i] = p->y[i];\n    }\n    for (i=0; i<4; i++) {\n        z[i] = p->z[i];\n    }\n\n    /* Y = 2*Y */\n    sp_256_mont_dbl_4(y, y, p256_mod);\n    /* W = Z^4 */\n    sp_256_mont_sqr_4(w, z, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_4(w, w, p256_mod, p256_mp_mod);\n    for (i=1; i<=n; i++) {\n        /* A = 3*(X^2 - W) */\n        sp_256_mont_sqr_4(t1, x, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(t1, t1, w, p256_mod);\n        sp_256_mont_tpl_4(a, t1, p256_mod);\n        /* B = X*Y^2 */\n        sp_256_mont_sqr_4(t2, y, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(b, t2, x, p256_mod, p256_mp_mod);\n        x = r[(1<<i)*m].x;\n        /* X = A^2 - 2B */\n        sp_256_mont_sqr_4(x, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_4(t1, b, p256_mod);\n        sp_256_mont_sub_4(x, x, t1, p256_mod);\n        /* Z = Z*Y */\n        sp_256_mont_mul_4(r[(1<<i)*m].z, z, y, p256_mod, p256_mp_mod);\n        z = r[(1<<i)*m].z;\n        /* t2 = Y^4 */\n        sp_256_mont_sqr_4(t2, t2, p256_mod, p256_mp_mod);\n        if (i != n) {\n            /* W = W*Y^4 */\n            sp_256_mont_mul_4(w, w, t2, p256_mod, p256_mp_mod);\n        }\n        /* y = 2*A*(B - X) - Y^4 */\n        sp_256_mont_sub_4(y, b, x, p256_mod);\n        sp_256_mont_mul_4(y, y, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_4(y, y, p256_mod);\n        sp_256_mont_sub_4(y, y, t2, p256_mod);\n\n        /* Y = Y/2 */\n        sp_256_div2_4(r[(1<<i)*m].y, y, p256_mod);\n        r[(1<<i)*m].infinity = 0;\n    }\n}\n\n/* Add two Montgomery form projective points.\n *\n * ra  Result of addition.\n * rs  Result of subtraction.\n * p   Frist point to add.\n * q   Second point to add.\n * t   Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_sub_4(sp_point* ra, sp_point* rs,\n        const sp_point* p, const sp_point* q, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    sp_digit* t3 = t + 4*4;\n    sp_digit* t4 = t + 6*4;\n    sp_digit* t5 = t + 8*4;\n    sp_digit* t6 = t + 10*4;\n    sp_digit* x = ra->x;\n    sp_digit* y = ra->y;\n    sp_digit* z = ra->z;\n    sp_digit* xs = rs->x;\n    sp_digit* ys = rs->y;\n    sp_digit* zs = rs->z;\n\n\n    XMEMCPY(x, p->x, sizeof(p->x) / 2);\n    XMEMCPY(y, p->y, sizeof(p->y) / 2);\n    XMEMCPY(z, p->z, sizeof(p->z) / 2);\n    ra->infinity = 0;\n    rs->infinity = 0;\n\n    /* U1 = X1*Z2^2 */\n    sp_256_mont_sqr_4(t1, q->z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t3, t1, q->z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t1, t1, x, p256_mod, p256_mp_mod);\n    /* U2 = X2*Z1^2 */\n    sp_256_mont_sqr_4(t2, z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t4, t2, z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t2, t2, q->x, p256_mod, p256_mp_mod);\n    /* S1 = Y1*Z2^3 */\n    sp_256_mont_mul_4(t3, t3, y, p256_mod, p256_mp_mod);\n    /* S2 = Y2*Z1^3 */\n    sp_256_mont_mul_4(t4, t4, q->y, p256_mod, p256_mp_mod);\n    /* H = U2 - U1 */\n    sp_256_mont_sub_4(t2, t2, t1, p256_mod);\n    /* RS = S2 + S1 */\n    sp_256_mont_add_4(t6, t4, t3, p256_mod);\n    /* R = S2 - S1 */\n    sp_256_mont_sub_4(t4, t4, t3, p256_mod);\n    /* Z3 = H*Z1*Z2 */\n    /* ZS = H*Z1*Z2 */\n    sp_256_mont_mul_4(z, z, q->z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(z, z, t2, p256_mod, p256_mp_mod);\n    XMEMCPY(zs, z, sizeof(p->z)/2);\n    /* X3 = R^2 - H^3 - 2*U1*H^2 */\n    /* XS = RS^2 - H^3 - 2*U1*H^2 */\n    sp_256_mont_sqr_4(x, t4, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_4(xs, t6, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_4(t5, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(y, t1, t5, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t5, t5, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_sub_4(x, x, t5, p256_mod);\n    sp_256_mont_sub_4(xs, xs, t5, p256_mod);\n    sp_256_mont_dbl_4(t1, y, p256_mod);\n    sp_256_mont_sub_4(x, x, t1, p256_mod);\n    sp_256_mont_sub_4(xs, xs, t1, p256_mod);\n    /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */\n    /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */\n    sp_256_mont_sub_4(ys, y, xs, p256_mod);\n    sp_256_mont_sub_4(y, y, x, p256_mod);\n    sp_256_mont_mul_4(y, y, t4, p256_mod, p256_mp_mod);\n    sp_256_sub_4(t6, p256_mod, t6);\n    sp_256_mont_mul_4(ys, ys, t6, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t5, t5, t3, p256_mod, p256_mp_mod);\n    sp_256_mont_sub_4(y, y, t5, p256_mod);\n    sp_256_mont_sub_4(ys, ys, t5, p256_mod);\n}\n\n/* Structure used to describe recoding of scalar multiplication. */\ntypedef struct ecc_recode {\n    /* Index into pre-computation table. */\n    uint8_t i;\n    /* Use the negative of the point. */\n    uint8_t neg;\n} ecc_recode;\n\n/* The index into pre-computation table to use. */\nstatic const uint8_t recode_index_4_6[66] = {\n     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n    32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,\n    16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,\n     0,  1,\n};\n\n/* Whether to negate y-ordinate. */\nstatic const uint8_t recode_neg_4_6[66] = {\n     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n     0,  0,\n};\n\n/* Recode the scalar for multiplication using pre-computed values and\n * subtraction.\n *\n * k  Scalar to multiply by.\n * v  Vector of operations to peform.\n */\nstatic void sp_256_ecc_recode_6_4(const sp_digit* k, ecc_recode* v)\n{\n    int i, j;\n    uint8_t y;\n    int carry = 0;\n    int o;\n    sp_digit n;\n\n    j = 0;\n    n = k[j];\n    o = 0;\n    for (i=0; i<43; i++) {\n        y = n;\n        if (o + 6 < 64) {\n            y &= 0x3f;\n            n >>= 6;\n            o += 6;\n        }\n        else if (o + 6 == 64) {\n            n >>= 6;\n            if (++j < 4)\n                n = k[j];\n            o = 0;\n        }\n        else if (++j < 4) {\n            n = k[j];\n            y |= (n << (64 - o)) & 0x3f;\n            o -= 58;\n            n >>= o;\n        }\n\n        y += carry;\n        v[i].i = recode_index_4_6[y];\n        v[i].neg = recode_neg_4_6[y];\n        carry = (y >> 6) + v[i].neg;\n    }\n}\n\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_win_add_sub_4(sp_point* r, const sp_point* g,\n        const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td[33];\n    sp_point rtd, pd;\n    sp_digit tmpd[2 * 4 * 6];\n#endif\n    sp_point* t;\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* tmp;\n    sp_digit* negy;\n    int i;\n    ecc_recode v[43];\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY)\n        err = sp_ecc_point_new(heap, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_point*)XMALLOC(sizeof(sp_point) * 33, heap, DYNAMIC_TYPE_ECC);\n    if (t == NULL)\n        err = MEMORY_E;\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 6, heap,\n                             DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n#else\n    t = td;\n    tmp = tmpd;\n#endif\n\n\n    if (err == MP_OKAY) {\n        /* t[0] = {0, 0, 1} * norm */\n        XMEMSET(&t[0], 0, sizeof(t[0]));\n        t[0].infinity = 1;\n        /* t[1] = {g->x, g->y, g->z} * norm */\n        err = sp_256_mod_mul_norm_4(t[1].x, g->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t[1].y, g->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t[1].z, g->z, p256_mod);\n    }\n\n    if (err == MP_OKAY) {\n        t[1].infinity = 0;\n        /* t[2] ... t[32]  */\n    sp_256_proj_point_dbl_n_store_4(t, &t[ 1], 5, 1, tmp);\n    sp_256_proj_point_add_4(&t[ 3], &t[ 2], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[ 6], &t[ 3], tmp);\n    sp_256_proj_point_add_sub_4(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[10], &t[ 5], tmp);\n    sp_256_proj_point_add_sub_4(&t[11], &t[ 9], &t[10], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[12], &t[ 6], tmp);\n    sp_256_proj_point_dbl_4(&t[14], &t[ 7], tmp);\n    sp_256_proj_point_add_sub_4(&t[15], &t[13], &t[14], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[18], &t[ 9], tmp);\n    sp_256_proj_point_add_sub_4(&t[19], &t[17], &t[18], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[20], &t[10], tmp);\n    sp_256_proj_point_dbl_4(&t[22], &t[11], tmp);\n    sp_256_proj_point_add_sub_4(&t[23], &t[21], &t[22], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[24], &t[12], tmp);\n    sp_256_proj_point_dbl_4(&t[26], &t[13], tmp);\n    sp_256_proj_point_add_sub_4(&t[27], &t[25], &t[26], &t[ 1], tmp);\n    sp_256_proj_point_dbl_4(&t[28], &t[14], tmp);\n    sp_256_proj_point_dbl_4(&t[30], &t[15], tmp);\n    sp_256_proj_point_add_sub_4(&t[31], &t[29], &t[30], &t[ 1], tmp);\n\n        negy = t[0].y;\n\n        sp_256_ecc_recode_6_4(k, v);\n\n        i = 42;\n        XMEMCPY(rt, &t[v[i].i], sizeof(sp_point));\n        for (--i; i>=0; i--) {\n            sp_256_proj_point_dbl_n_4(rt, rt, 6, tmp);\n\n            XMEMCPY(p, &t[v[i].i], sizeof(sp_point));\n            sp_256_sub_4(negy, p256_mod, p->y);\n            sp_256_cond_copy_4(p->y, negy, (sp_digit)0 - v[i].neg);\n            sp_256_proj_point_add_4(rt, rt, p, tmp);\n        }\n\n        if (map != 0) {\n            sp_256_map_4(r, rt, tmp);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL)\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    if (tmp != NULL)\n        XFREE(tmp, heap, DYNAMIC_TYPE_ECC);\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n#ifdef HAVE_INTEL_AVX2\nextern void sp_256_mont_mul_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m, sp_digit mp);\nextern void sp_256_mont_sqr_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit* m, sp_digit mp);\n#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY)\n/* Square the Montgomery form number a number of times. (r = a ^ n mod m)\n *\n * r   Result of squaring.\n * a   Number to square in Montogmery form.\n * n   Number of times to square.\n * m   Modulus (prime).\n * mp  Montogmery mulitplier.\n */\nstatic void sp_256_mont_sqr_n_avx2_4(sp_digit* r, const sp_digit* a, int n,\n        const sp_digit* m, sp_digit mp)\n{\n    sp_256_mont_sqr_avx2_4(r, a, m, mp);\n    for (; n > 1; n--) {\n        sp_256_mont_sqr_avx2_4(r, r, m, mp);\n    }\n}\n\n#endif /* !WOLFSSL_SP_SMALL || HAVE_COMP_KEY */\n\n/* Invert the number, in Montgomery form, modulo the modulus (prime) of the\n * P256 curve. (r = 1 / a mod m)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_avx2_4(sp_digit* r, const sp_digit* a, sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 4);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_avx2_4(t, t, p256_mod, p256_mp_mod);\n        if (p256_mod_2[i / 64] & ((sp_digit)1 << (i % 64)))\n            sp_256_mont_mul_avx2_4(t, t, a, p256_mod, p256_mp_mod);\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 4);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 4;\n    sp_digit* t3 = td + 4 * 4;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_avx2_4(t, a, p256_mod, p256_mp_mod);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_avx2_4(t, t, a, p256_mod, p256_mp_mod);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_avx2_4(t2, t, 2, p256_mod, p256_mp_mod);\n    /* t3= a^d = t2 * a */\n    sp_256_mont_mul_avx2_4(t3, t2, a, p256_mod, p256_mp_mod);\n    /* t = a^f = t2 * t */\n    sp_256_mont_mul_avx2_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^f0 = t ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_avx2_4(t2, t, 4, p256_mod, p256_mp_mod);\n    /* t3= a^fd = t2 * t3 */\n    sp_256_mont_mul_avx2_4(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ff = t2 * t */\n    sp_256_mont_mul_avx2_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_avx2_4(t2, t, 8, p256_mod, p256_mp_mod);\n    /* t3= a^fffd = t2 * t3 */\n    sp_256_mont_mul_avx2_4(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_avx2_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_avx2_4(t2, t, 16, p256_mod, p256_mp_mod);\n    /* t3= a^fffffffd = t2 * t3 */\n    sp_256_mont_mul_avx2_4(t3, t2, t3, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_avx2_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t = a^ffffffff00000000 = t ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_avx2_4(t2, t, 32, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_avx2_4(t, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001 = t2 * a */\n    sp_256_mont_mul_avx2_4(t2, t2, a, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff000000010000000000000000000000000000000000000000\n     *   = t2 ^ 2 ^ 160 */\n    sp_256_mont_sqr_n_avx2_4(t2, t2, 160, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff\n     *   = t2 * t */\n    sp_256_mont_mul_avx2_4(t2, t2, t, p256_mod, p256_mp_mod);\n    /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000\n     *   = t2 ^ 2 ^ 32 */\n    sp_256_mont_sqr_n_avx2_4(t2, t2, 32, p256_mod, p256_mp_mod);\n    /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd\n     *   = t2 * t3 */\n    sp_256_mont_mul_avx2_4(r, t2, t3, p256_mod, p256_mp_mod);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n/* Map the Montgomery form projective co-ordinate point to an affine point.\n *\n * r  Resulting affine co-ordinate point.\n * p  Montgomery form projective co-ordinate point.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_map_avx2_4(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    int64_t n;\n\n    sp_256_mont_inv_avx2_4(t1, p->z, t + 2*4);\n\n    sp_256_mont_sqr_avx2_4(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_avx2_4(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    /* x /= z^2 */\n    sp_256_mont_mul_avx2_4(r->x, p->x, t2, p256_mod, p256_mp_mod);\n    XMEMSET(r->x + 4, 0, sizeof(r->x) / 2U);\n    sp_256_mont_reduce_4(r->x, p256_mod, p256_mp_mod);\n    /* Reduce x to less than modulus */\n    n = sp_256_cmp_4(r->x, p256_mod);\n    sp_256_cond_sub_4(r->x, r->x, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_4(r->x);\n\n    /* y /= z^3 */\n    sp_256_mont_mul_avx2_4(r->y, p->y, t1, p256_mod, p256_mp_mod);\n    XMEMSET(r->y + 4, 0, sizeof(r->y) / 2U);\n    sp_256_mont_reduce_4(r->y, p256_mod, p256_mp_mod);\n    /* Reduce y to less than modulus */\n    n = sp_256_cmp_4(r->y, p256_mod);\n    sp_256_cond_sub_4(r->y, r->y, p256_mod, 0 - ((n >= 0) ?\n                (sp_digit)1 : (sp_digit)0));\n    sp_256_norm_4(r->y);\n\n    XMEMSET(r->z, 0, sizeof(r->z));\n    r->z[0] = 1;\n\n}\n\n/* Double the Montgomery form projective point p.\n *\n * r  Result of doubling point.\n * p  Point to double.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_avx2_4(sp_point* r, const sp_point* p, sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* When infinity don't double point passed in - constant time. */\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    /* Put point to double into result - good for infinty. */\n    if (r != p) {\n        for (i=0; i<4; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<4; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<4; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* T1 = Z * Z */\n    sp_256_mont_sqr_avx2_4(t1, z, p256_mod, p256_mp_mod);\n    /* Z = Y * Z */\n    sp_256_mont_mul_avx2_4(z, y, z, p256_mod, p256_mp_mod);\n    /* Z = 2Z */\n    sp_256_mont_dbl_4(z, z, p256_mod);\n    /* T2 = X - T1 */\n    sp_256_mont_sub_4(t2, x, t1, p256_mod);\n    /* T1 = X + T1 */\n    sp_256_mont_add_4(t1, x, t1, p256_mod);\n    /* T2 = T1 * T2 */\n    sp_256_mont_mul_avx2_4(t2, t1, t2, p256_mod, p256_mp_mod);\n    /* T1 = 3T2 */\n    sp_256_mont_tpl_4(t1, t2, p256_mod);\n    /* Y = 2Y */\n    sp_256_mont_dbl_4(y, y, p256_mod);\n    /* Y = Y * Y */\n    sp_256_mont_sqr_avx2_4(y, y, p256_mod, p256_mp_mod);\n    /* T2 = Y * Y */\n    sp_256_mont_sqr_avx2_4(t2, y, p256_mod, p256_mp_mod);\n    /* T2 = T2/2 */\n    sp_256_div2_4(t2, t2, p256_mod);\n    /* Y = Y * X */\n    sp_256_mont_mul_avx2_4(y, y, x, p256_mod, p256_mp_mod);\n    /* X = T1 * T1 */\n    sp_256_mont_mul_avx2_4(x, t1, t1, p256_mod, p256_mp_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_4(x, x, y, p256_mod);\n    /* X = X - Y */\n    sp_256_mont_sub_4(x, x, y, p256_mod);\n    /* Y = Y - X */\n    sp_256_mont_sub_4(y, y, x, p256_mod);\n    /* Y = Y * T1 */\n    sp_256_mont_mul_avx2_4(y, y, t1, p256_mod, p256_mp_mod);\n    /* Y = Y - T2 */\n    sp_256_mont_sub_4(y, y, t2, p256_mod);\n\n}\n\n/* Double the Montgomery form projective point p a number of times.\n *\n * r  Result of repeated doubling of point.\n * p  Point to double.\n * n  Number of times to double\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_n_avx2_4(sp_point* r, const sp_point* p, int n,\n        sp_digit* t)\n{\n    sp_point* rp[2];\n    sp_digit* w = t;\n    sp_digit* a = t + 2*4;\n    sp_digit* b = t + 4*4;\n    sp_digit* t1 = t + 6*4;\n    sp_digit* t2 = t + 8*4;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    rp[0] = r;\n\n    /*lint allow cast to different type of pointer*/\n    rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n    XMEMSET(rp[1], 0, sizeof(sp_point));\n    x = rp[p->infinity]->x;\n    y = rp[p->infinity]->y;\n    z = rp[p->infinity]->z;\n    if (r != p) {\n        for (i=0; i<4; i++) {\n            r->x[i] = p->x[i];\n        }\n        for (i=0; i<4; i++) {\n            r->y[i] = p->y[i];\n        }\n        for (i=0; i<4; i++) {\n            r->z[i] = p->z[i];\n        }\n        r->infinity = p->infinity;\n    }\n\n    /* Y = 2*Y */\n    sp_256_mont_dbl_4(y, y, p256_mod);\n    /* W = Z^4 */\n    sp_256_mont_sqr_avx2_4(w, z, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_avx2_4(w, w, p256_mod, p256_mp_mod);\n    while (n-- > 0) {\n        /* A = 3*(X^2 - W) */\n        sp_256_mont_sqr_avx2_4(t1, x, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(t1, t1, w, p256_mod);\n        sp_256_mont_tpl_4(a, t1, p256_mod);\n        /* B = X*Y^2 */\n        sp_256_mont_sqr_avx2_4(t2, y, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(b, t2, x, p256_mod, p256_mp_mod);\n        /* X = A^2 - 2B */\n        sp_256_mont_sqr_avx2_4(x, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_4(t1, b, p256_mod);\n        sp_256_mont_sub_4(x, x, t1, p256_mod);\n        /* Z = Z*Y */\n        sp_256_mont_mul_avx2_4(z, z, y, p256_mod, p256_mp_mod);\n        /* t2 = Y^4 */\n        sp_256_mont_sqr_avx2_4(t2, t2, p256_mod, p256_mp_mod);\n        if (n != 0) {\n            /* W = W*Y^4 */\n            sp_256_mont_mul_avx2_4(w, w, t2, p256_mod, p256_mp_mod);\n        }\n        /* y = 2*A*(B - X) - Y^4 */\n        sp_256_mont_sub_4(y, b, x, p256_mod);\n        sp_256_mont_mul_avx2_4(y, y, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_4(y, y, p256_mod);\n        sp_256_mont_sub_4(y, y, t2, p256_mod);\n    }\n    /* Y = Y/2 */\n    sp_256_div2_4(y, y, p256_mod);\n}\n\n/* Add two Montgomery form projective points.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_avx2_4(sp_point* r, const sp_point* p, const sp_point* q,\n        sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    sp_digit* t3 = t + 4*4;\n    sp_digit* t4 = t + 6*4;\n    sp_digit* t5 = t + 8*4;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Ensure only the first point is the same as the result. */\n    if (q == r) {\n        const sp_point* a = p;\n        p = q;\n        q = a;\n    }\n\n    /* Check double */\n    (void)sp_256_sub_4(t1, p256_mod, q->y);\n    sp_256_norm_4(t1);\n    if ((sp_256_cmp_equal_4(p->x, q->x) & sp_256_cmp_equal_4(p->z, q->z) &\n        (sp_256_cmp_equal_4(p->y, q->y) | sp_256_cmp_equal_4(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_4(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<4; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<4; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<4; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U1 = X1*Z2^2 */\n        sp_256_mont_sqr_avx2_4(t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(t3, t1, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(t1, t1, x, p256_mod, p256_mp_mod);\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_avx2_4(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S1 = Y1*Z2^3 */\n        sp_256_mont_mul_avx2_4(t3, t3, y, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_avx2_4(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - U1 */\n        sp_256_mont_sub_4(t2, t2, t1, p256_mod);\n        /* R = S2 - S1 */\n        sp_256_mont_sub_4(t4, t4, t3, p256_mod);\n        /* Z3 = H*Z1*Z2 */\n        sp_256_mont_mul_avx2_4(z, z, q->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*U1*H^2 */\n        sp_256_mont_sqr_avx2_4(x, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_avx2_4(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(y, t1, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(x, x, t5, p256_mod);\n        sp_256_mont_dbl_4(t1, y, p256_mod);\n        sp_256_mont_sub_4(x, x, t1, p256_mod);\n        /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */\n        sp_256_mont_sub_4(y, y, x, p256_mod);\n        sp_256_mont_mul_avx2_4(y, y, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(t5, t5, t3, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(y, y, t5, p256_mod);\n    }\n}\n\n/* Double the Montgomery form projective point p a number of times.\n *\n * r  Result of repeated doubling of point.\n * p  Point to double.\n * n  Number of times to double\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_dbl_n_store_avx2_4(sp_point* r, const sp_point* p,\n        int n, int m, sp_digit* t)\n{\n    sp_digit* w = t;\n    sp_digit* a = t + 2*4;\n    sp_digit* b = t + 4*4;\n    sp_digit* t1 = t + 6*4;\n    sp_digit* t2 = t + 8*4;\n    sp_digit* x = r[2*m].x;\n    sp_digit* y = r[(1<<n)*m].y;\n    sp_digit* z = r[2*m].z;\n    int i;\n\n    for (i=0; i<4; i++) {\n        x[i] = p->x[i];\n    }\n    for (i=0; i<4; i++) {\n        y[i] = p->y[i];\n    }\n    for (i=0; i<4; i++) {\n        z[i] = p->z[i];\n    }\n\n    /* Y = 2*Y */\n    sp_256_mont_dbl_4(y, y, p256_mod);\n    /* W = Z^4 */\n    sp_256_mont_sqr_avx2_4(w, z, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_avx2_4(w, w, p256_mod, p256_mp_mod);\n    for (i=1; i<=n; i++) {\n        /* A = 3*(X^2 - W) */\n        sp_256_mont_sqr_avx2_4(t1, x, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(t1, t1, w, p256_mod);\n        sp_256_mont_tpl_4(a, t1, p256_mod);\n        /* B = X*Y^2 */\n        sp_256_mont_sqr_avx2_4(t2, y, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(b, t2, x, p256_mod, p256_mp_mod);\n        x = r[(1<<i)*m].x;\n        /* X = A^2 - 2B */\n        sp_256_mont_sqr_avx2_4(x, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_4(t1, b, p256_mod);\n        sp_256_mont_sub_4(x, x, t1, p256_mod);\n        /* Z = Z*Y */\n        sp_256_mont_mul_avx2_4(r[(1<<i)*m].z, z, y, p256_mod, p256_mp_mod);\n        z = r[(1<<i)*m].z;\n        /* t2 = Y^4 */\n        sp_256_mont_sqr_avx2_4(t2, t2, p256_mod, p256_mp_mod);\n        if (i != n) {\n            /* W = W*Y^4 */\n            sp_256_mont_mul_avx2_4(w, w, t2, p256_mod, p256_mp_mod);\n        }\n        /* y = 2*A*(B - X) - Y^4 */\n        sp_256_mont_sub_4(y, b, x, p256_mod);\n        sp_256_mont_mul_avx2_4(y, y, a, p256_mod, p256_mp_mod);\n        sp_256_mont_dbl_4(y, y, p256_mod);\n        sp_256_mont_sub_4(y, y, t2, p256_mod);\n\n        /* Y = Y/2 */\n        sp_256_div2_4(r[(1<<i)*m].y, y, p256_mod);\n        r[(1<<i)*m].infinity = 0;\n    }\n}\n\n/* Add two Montgomery form projective points.\n *\n * ra  Result of addition.\n * rs  Result of subtraction.\n * p   Frist point to add.\n * q   Second point to add.\n * t   Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_sub_avx2_4(sp_point* ra, sp_point* rs,\n        const sp_point* p, const sp_point* q, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    sp_digit* t3 = t + 4*4;\n    sp_digit* t4 = t + 6*4;\n    sp_digit* t5 = t + 8*4;\n    sp_digit* t6 = t + 10*4;\n    sp_digit* x = ra->x;\n    sp_digit* y = ra->y;\n    sp_digit* z = ra->z;\n    sp_digit* xs = rs->x;\n    sp_digit* ys = rs->y;\n    sp_digit* zs = rs->z;\n\n\n    XMEMCPY(x, p->x, sizeof(p->x) / 2);\n    XMEMCPY(y, p->y, sizeof(p->y) / 2);\n    XMEMCPY(z, p->z, sizeof(p->z) / 2);\n    ra->infinity = 0;\n    rs->infinity = 0;\n\n    /* U1 = X1*Z2^2 */\n    sp_256_mont_sqr_avx2_4(t1, q->z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_avx2_4(t3, t1, q->z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_avx2_4(t1, t1, x, p256_mod, p256_mp_mod);\n    /* U2 = X2*Z1^2 */\n    sp_256_mont_sqr_avx2_4(t2, z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_avx2_4(t4, t2, z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_avx2_4(t2, t2, q->x, p256_mod, p256_mp_mod);\n    /* S1 = Y1*Z2^3 */\n    sp_256_mont_mul_avx2_4(t3, t3, y, p256_mod, p256_mp_mod);\n    /* S2 = Y2*Z1^3 */\n    sp_256_mont_mul_avx2_4(t4, t4, q->y, p256_mod, p256_mp_mod);\n    /* H = U2 - U1 */\n    sp_256_mont_sub_4(t2, t2, t1, p256_mod);\n    /* RS = S2 + S1 */\n    sp_256_mont_add_4(t6, t4, t3, p256_mod);\n    /* R = S2 - S1 */\n    sp_256_mont_sub_4(t4, t4, t3, p256_mod);\n    /* Z3 = H*Z1*Z2 */\n    /* ZS = H*Z1*Z2 */\n    sp_256_mont_mul_avx2_4(z, z, q->z, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_avx2_4(z, z, t2, p256_mod, p256_mp_mod);\n    XMEMCPY(zs, z, sizeof(p->z)/2);\n    /* X3 = R^2 - H^3 - 2*U1*H^2 */\n    /* XS = RS^2 - H^3 - 2*U1*H^2 */\n    sp_256_mont_sqr_avx2_4(x, t4, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_avx2_4(xs, t6, p256_mod, p256_mp_mod);\n    sp_256_mont_sqr_avx2_4(t5, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_avx2_4(y, t1, t5, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_avx2_4(t5, t5, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_sub_4(x, x, t5, p256_mod);\n    sp_256_mont_sub_4(xs, xs, t5, p256_mod);\n    sp_256_mont_dbl_4(t1, y, p256_mod);\n    sp_256_mont_sub_4(x, x, t1, p256_mod);\n    sp_256_mont_sub_4(xs, xs, t1, p256_mod);\n    /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */\n    /* YS = -RS*(U1*H^2 - XS) - S1*H^3 */\n    sp_256_mont_sub_4(ys, y, xs, p256_mod);\n    sp_256_mont_sub_4(y, y, x, p256_mod);\n    sp_256_mont_mul_avx2_4(y, y, t4, p256_mod, p256_mp_mod);\n    sp_256_sub_4(t6, p256_mod, t6);\n    sp_256_mont_mul_avx2_4(ys, ys, t6, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_avx2_4(t5, t5, t3, p256_mod, p256_mp_mod);\n    sp_256_mont_sub_4(y, y, t5, p256_mod);\n    sp_256_mont_sub_4(ys, ys, t5, p256_mod);\n}\n\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_win_add_sub_avx2_4(sp_point* r, const sp_point* g,\n        const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td[33];\n    sp_point rtd, pd;\n    sp_digit tmpd[2 * 4 * 6];\n#endif\n    sp_point* t;\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* tmp;\n    sp_digit* negy;\n    int i;\n    ecc_recode v[43];\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY)\n        err = sp_ecc_point_new(heap, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_point*)XMALLOC(sizeof(sp_point) * 33, heap, DYNAMIC_TYPE_ECC);\n    if (t == NULL)\n        err = MEMORY_E;\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 6, heap,\n                             DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n#else\n    t = td;\n    tmp = tmpd;\n#endif\n\n\n    if (err == MP_OKAY) {\n        /* t[0] = {0, 0, 1} * norm */\n        XMEMSET(&t[0], 0, sizeof(t[0]));\n        t[0].infinity = 1;\n        /* t[1] = {g->x, g->y, g->z} * norm */\n        err = sp_256_mod_mul_norm_4(t[1].x, g->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t[1].y, g->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t[1].z, g->z, p256_mod);\n    }\n\n    if (err == MP_OKAY) {\n        t[1].infinity = 0;\n        /* t[2] ... t[32]  */\n    sp_256_proj_point_dbl_n_store_avx2_4(t, &t[ 1], 5, 1, tmp);\n    sp_256_proj_point_add_avx2_4(&t[ 3], &t[ 2], &t[ 1], tmp);\n    sp_256_proj_point_dbl_avx2_4(&t[ 6], &t[ 3], tmp);\n    sp_256_proj_point_add_sub_avx2_4(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp);\n    sp_256_proj_point_dbl_avx2_4(&t[10], &t[ 5], tmp);\n    sp_256_proj_point_add_sub_avx2_4(&t[11], &t[ 9], &t[10], &t[ 1], tmp);\n    sp_256_proj_point_dbl_avx2_4(&t[12], &t[ 6], tmp);\n    sp_256_proj_point_dbl_avx2_4(&t[14], &t[ 7], tmp);\n    sp_256_proj_point_add_sub_avx2_4(&t[15], &t[13], &t[14], &t[ 1], tmp);\n    sp_256_proj_point_dbl_avx2_4(&t[18], &t[ 9], tmp);\n    sp_256_proj_point_add_sub_avx2_4(&t[19], &t[17], &t[18], &t[ 1], tmp);\n    sp_256_proj_point_dbl_avx2_4(&t[20], &t[10], tmp);\n    sp_256_proj_point_dbl_avx2_4(&t[22], &t[11], tmp);\n    sp_256_proj_point_add_sub_avx2_4(&t[23], &t[21], &t[22], &t[ 1], tmp);\n    sp_256_proj_point_dbl_avx2_4(&t[24], &t[12], tmp);\n    sp_256_proj_point_dbl_avx2_4(&t[26], &t[13], tmp);\n    sp_256_proj_point_add_sub_avx2_4(&t[27], &t[25], &t[26], &t[ 1], tmp);\n    sp_256_proj_point_dbl_avx2_4(&t[28], &t[14], tmp);\n    sp_256_proj_point_dbl_avx2_4(&t[30], &t[15], tmp);\n    sp_256_proj_point_add_sub_avx2_4(&t[31], &t[29], &t[30], &t[ 1], tmp);\n\n        negy = t[0].y;\n\n        sp_256_ecc_recode_6_4(k, v);\n\n        i = 42;\n        XMEMCPY(rt, &t[v[i].i], sizeof(sp_point));\n        for (--i; i>=0; i--) {\n            sp_256_proj_point_dbl_n_avx2_4(rt, rt, 6, tmp);\n\n            XMEMCPY(p, &t[v[i].i], sizeof(sp_point));\n            sp_256_sub_4(negy, p256_mod, p->y);\n            sp_256_cond_copy_4(p->y, negy, (sp_digit)0 - v[i].neg);\n            sp_256_proj_point_add_avx2_4(rt, rt, p, tmp);\n        }\n\n        if (map != 0) {\n            sp_256_map_avx2_4(r, rt, tmp);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL)\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    if (tmp != NULL)\n        XFREE(tmp, heap, DYNAMIC_TYPE_ECC);\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n/* A table entry for pre-computed points. */\ntypedef struct sp_table_entry {\n    sp_digit x[4];\n    sp_digit y[4];\n} sp_table_entry;\n\n#if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL)\n#endif /* FP_ECC || WOLFSSL_SP_SMALL */\n/* Add two Montgomery form projective points. The second point has a q value of\n * one.\n * Only the first point can be the same pointer as the result point.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_qz1_4(sp_point* r, const sp_point* p,\n        const sp_point* q, sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    sp_digit* t3 = t + 4*4;\n    sp_digit* t4 = t + 6*4;\n    sp_digit* t5 = t + 8*4;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Check double */\n    (void)sp_256_sub_4(t1, p256_mod, q->y);\n    sp_256_norm_4(t1);\n    if ((sp_256_cmp_equal_4(p->x, q->x) & sp_256_cmp_equal_4(p->z, q->z) &\n        (sp_256_cmp_equal_4(p->y, q->y) | sp_256_cmp_equal_4(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_4(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<4; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<4; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<4; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_4(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_4(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - X1 */\n        sp_256_mont_sub_4(t2, t2, x, p256_mod);\n        /* R = S2 - Y1 */\n        sp_256_mont_sub_4(t4, t4, y, p256_mod);\n        /* Z3 = H*Z1 */\n        sp_256_mont_mul_4(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*X1*H^2 */\n        sp_256_mont_sqr_4(t1, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_4(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t3, x, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(x, t1, t5, p256_mod);\n        sp_256_mont_dbl_4(t1, t3, p256_mod);\n        sp_256_mont_sub_4(x, x, t1, p256_mod);\n        /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */\n        sp_256_mont_sub_4(t3, t3, x, p256_mod);\n        sp_256_mont_mul_4(t3, t3, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(t5, t5, y, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(y, t3, t5, p256_mod);\n    }\n}\n\n#ifdef FP_ECC\n/* Convert the projective point to affine.\n * Ordinates are in Montgomery form.\n *\n * a  Point to convert.\n * t  Temprorary data.\n */\nstatic void sp_256_proj_to_affine_4(sp_point* a, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2 * 4;\n    sp_digit* tmp = t + 4 * 4;\n\n    sp_256_mont_inv_4(t1, a->z, tmp);\n\n    sp_256_mont_sqr_4(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    sp_256_mont_mul_4(a->x, a->x, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_4(a->y, a->y, t1, p256_mod, p256_mp_mod);\n    XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod));\n}\n\n/* Generate the pre-computed table of points for the base point.\n *\n * a      The base point.\n * table  Place to store generated point data.\n * tmp    Temprorary data.\n * heap  Heap to use for allocation.\n */\nstatic int sp_256_gen_stripe_table_4(const sp_point* a,\n        sp_table_entry* table, sp_digit* tmp, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td, s1d, s2d;\n#endif\n    sp_point* t;\n    sp_point* s1 = NULL;\n    sp_point* s2 = NULL;\n    int i, j;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, td, t);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s1d, s1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s2d, s2);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t->x, a->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t->y, a->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t->z, a->z, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        t->infinity = 0;\n        sp_256_proj_to_affine_4(t, tmp);\n\n        XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s1->infinity = 0;\n        XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s2->infinity = 0;\n\n        /* table[0] = {0, 0, infinity} */\n        XMEMSET(&table[0], 0, sizeof(sp_table_entry));\n        /* table[1] = Affine version of 'a' in Montgomery form */\n        XMEMCPY(table[1].x, t->x, sizeof(table->x));\n        XMEMCPY(table[1].y, t->y, sizeof(table->y));\n\n        for (i=1; i<8; i++) {\n            sp_256_proj_point_dbl_n_4(t, t, 32, tmp);\n            sp_256_proj_to_affine_4(t, tmp);\n            XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));\n            XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));\n        }\n\n        for (i=1; i<8; i++) {\n            XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));\n            XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));\n            for (j=(1<<i)+1; j<(1<<(i+1)); j++) {\n                XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));\n                XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));\n                sp_256_proj_point_add_qz1_4(t, s1, s2, tmp);\n                sp_256_proj_to_affine_4(t, tmp);\n                XMEMCPY(table[j].x, t->x, sizeof(table->x));\n                XMEMCPY(table[j].y, t->y, sizeof(table->y));\n            }\n        }\n    }\n\n    sp_ecc_point_free(s2, 0, heap);\n    sp_ecc_point_free(s1, 0, heap);\n    sp_ecc_point_free( t, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC */\n#if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL)\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_stripe_4(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit td[2 * 4 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* t;\n    int i, j;\n    int y, x;\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, heap,\n                           DYNAMIC_TYPE_ECC);\n    if (t == NULL) {\n        err = MEMORY_E;\n    }\n#else\n    t = td;\n#endif\n\n    if (err == MP_OKAY) {\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        y = 0;\n        for (j=0,x=31; j<8; j++,x+=32) {\n            y |= ((k[x / 64] >> (x % 64)) & 1) << j;\n        }\n        XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));\n        XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));\n        rt->infinity = !y;\n        for (i=30; i>=0; i--) {\n            y = 0;\n            for (j=0,x=i; j<8; j++,x+=32) {\n                y |= ((k[x / 64] >> (x % 64)) & 1) << j;\n            }\n\n            sp_256_proj_point_dbl_4(rt, rt, t);\n            XMEMCPY(p->x, table[y].x, sizeof(table[y].x));\n            XMEMCPY(p->y, table[y].y, sizeof(table[y].y));\n            p->infinity = !y;\n            sp_256_proj_point_add_qz1_4(rt, rt, p, t);\n        }\n\n        if (map != 0) {\n            sp_256_map_4(r, rt, t);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC || WOLFSSL_SP_SMALL */\n#ifdef FP_ECC\n#ifndef FP_ENTRIES\n    #define FP_ENTRIES 16\n#endif\n\ntypedef struct sp_cache_t {\n    sp_digit x[4];\n    sp_digit y[4];\n    sp_table_entry table[256];\n    uint32_t cnt;\n    int set;\n} sp_cache_t;\n\nstatic THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES];\nstatic THREAD_LS_T int sp_cache_last = -1;\nstatic THREAD_LS_T int sp_cache_inited = 0;\n\n#ifndef HAVE_THREAD_LS\n    static volatile int initCacheMutex = 0;\n    static wolfSSL_Mutex sp_cache_lock;\n#endif\n\nstatic void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache)\n{\n    int i, j;\n    uint32_t least;\n\n    if (sp_cache_inited == 0) {\n        for (i=0; i<FP_ENTRIES; i++) {\n            sp_cache[i].set = 0;\n        }\n        sp_cache_inited = 1;\n    }\n\n    /* Compare point with those in cache. */\n    for (i=0; i<FP_ENTRIES; i++) {\n        if (!sp_cache[i].set)\n            continue;\n\n        if (sp_256_cmp_equal_4(g->x, sp_cache[i].x) &\n                           sp_256_cmp_equal_4(g->y, sp_cache[i].y)) {\n            sp_cache[i].cnt++;\n            break;\n        }\n    }\n\n    /* No match. */\n    if (i == FP_ENTRIES) {\n        /* Find empty entry. */\n        i = (sp_cache_last + 1) % FP_ENTRIES;\n        for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) {\n            if (!sp_cache[i].set) {\n                break;\n            }\n        }\n\n        /* Evict least used. */\n        if (i == sp_cache_last) {\n            least = sp_cache[0].cnt;\n            for (j=1; j<FP_ENTRIES; j++) {\n                if (sp_cache[j].cnt < least) {\n                    i = j;\n                    least = sp_cache[i].cnt;\n                }\n            }\n        }\n\n        XMEMCPY(sp_cache[i].x, g->x, sizeof(sp_cache[i].x));\n        XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y));\n        sp_cache[i].set = 1;\n        sp_cache[i].cnt = 1;\n    }\n\n    *cache = &sp_cache[i];\n    sp_cache_last = i;\n}\n#endif /* FP_ECC */\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_4(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#ifndef FP_ECC\n    return sp_256_ecc_mulmod_win_add_sub_4(r, g, k, map, heap);\n#else\n    sp_digit tmp[2 * 4 * 5];\n    sp_cache_t* cache;\n    int err = MP_OKAY;\n\n#ifndef HAVE_THREAD_LS\n    if (initCacheMutex == 0) {\n         wc_InitMutex(&sp_cache_lock);\n         initCacheMutex = 1;\n    }\n    if (wc_LockMutex(&sp_cache_lock) != 0)\n       err = BAD_MUTEX_E;\n#endif /* HAVE_THREAD_LS */\n\n    if (err == MP_OKAY) {\n        sp_ecc_get_cache(g, &cache);\n        if (cache->cnt == 2)\n            sp_256_gen_stripe_table_4(g, cache->table, tmp, heap);\n\n#ifndef HAVE_THREAD_LS\n        wc_UnLockMutex(&sp_cache_lock);\n#endif /* HAVE_THREAD_LS */\n\n        if (cache->cnt < 2) {\n            err = sp_256_ecc_mulmod_win_add_sub_4(r, g, k, map, heap);\n        }\n        else {\n            err = sp_256_ecc_mulmod_stripe_4(r, g, cache->table, k,\n                    map, heap);\n        }\n    }\n\n    return err;\n#endif\n}\n\n#ifdef HAVE_INTEL_AVX2\n#if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL)\n#endif /* FP_ECC || WOLFSSL_SP_SMALL */\n/* Add two Montgomery form projective points. The second point has a q value of\n * one.\n * Only the first point can be the same pointer as the result point.\n *\n * r  Result of addition.\n * p  Frist point to add.\n * q  Second point to add.\n * t  Temporary ordinate data.\n */\nstatic void sp_256_proj_point_add_qz1_avx2_4(sp_point* r, const sp_point* p,\n        const sp_point* q, sp_digit* t)\n{\n    const sp_point* ap[2];\n    sp_point* rp[2];\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2*4;\n    sp_digit* t3 = t + 4*4;\n    sp_digit* t4 = t + 6*4;\n    sp_digit* t5 = t + 8*4;\n    sp_digit* x;\n    sp_digit* y;\n    sp_digit* z;\n    int i;\n\n    /* Check double */\n    (void)sp_256_sub_4(t1, p256_mod, q->y);\n    sp_256_norm_4(t1);\n    if ((sp_256_cmp_equal_4(p->x, q->x) & sp_256_cmp_equal_4(p->z, q->z) &\n        (sp_256_cmp_equal_4(p->y, q->y) | sp_256_cmp_equal_4(p->y, t1))) != 0) {\n        sp_256_proj_point_dbl_4(r, p, t);\n    }\n    else {\n        rp[0] = r;\n\n        /*lint allow cast to different type of pointer*/\n        rp[1] = (sp_point*)t; /*lint !e9087 !e740*/\n        XMEMSET(rp[1], 0, sizeof(sp_point));\n        x = rp[p->infinity | q->infinity]->x;\n        y = rp[p->infinity | q->infinity]->y;\n        z = rp[p->infinity | q->infinity]->z;\n\n        ap[0] = p;\n        ap[1] = q;\n        for (i=0; i<4; i++) {\n            r->x[i] = ap[p->infinity]->x[i];\n        }\n        for (i=0; i<4; i++) {\n            r->y[i] = ap[p->infinity]->y[i];\n        }\n        for (i=0; i<4; i++) {\n            r->z[i] = ap[p->infinity]->z[i];\n        }\n        r->infinity = ap[p->infinity]->infinity;\n\n        /* U2 = X2*Z1^2 */\n        sp_256_mont_sqr_avx2_4(t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(t4, t2, z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(t2, t2, q->x, p256_mod, p256_mp_mod);\n        /* S2 = Y2*Z1^3 */\n        sp_256_mont_mul_avx2_4(t4, t4, q->y, p256_mod, p256_mp_mod);\n        /* H = U2 - X1 */\n        sp_256_mont_sub_4(t2, t2, x, p256_mod);\n        /* R = S2 - Y1 */\n        sp_256_mont_sub_4(t4, t4, y, p256_mod);\n        /* Z3 = H*Z1 */\n        sp_256_mont_mul_avx2_4(z, z, t2, p256_mod, p256_mp_mod);\n        /* X3 = R^2 - H^3 - 2*X1*H^2 */\n        sp_256_mont_sqr_avx2_4(t1, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_sqr_avx2_4(t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(t3, x, t5, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(t5, t5, t2, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(x, t1, t5, p256_mod);\n        sp_256_mont_dbl_4(t1, t3, p256_mod);\n        sp_256_mont_sub_4(x, x, t1, p256_mod);\n        /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */\n        sp_256_mont_sub_4(t3, t3, x, p256_mod);\n        sp_256_mont_mul_avx2_4(t3, t3, t4, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_avx2_4(t5, t5, y, p256_mod, p256_mp_mod);\n        sp_256_mont_sub_4(y, t3, t5, p256_mod);\n    }\n}\n\n#ifdef FP_ECC\n/* Convert the projective point to affine.\n * Ordinates are in Montgomery form.\n *\n * a  Point to convert.\n * t  Temprorary data.\n */\nstatic void sp_256_proj_to_affine_avx2_4(sp_point* a, sp_digit* t)\n{\n    sp_digit* t1 = t;\n    sp_digit* t2 = t + 2 * 4;\n    sp_digit* tmp = t + 4 * 4;\n\n    sp_256_mont_inv_avx2_4(t1, a->z, tmp);\n\n    sp_256_mont_sqr_avx2_4(t2, t1, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_avx2_4(t1, t2, t1, p256_mod, p256_mp_mod);\n\n    sp_256_mont_mul_avx2_4(a->x, a->x, t2, p256_mod, p256_mp_mod);\n    sp_256_mont_mul_avx2_4(a->y, a->y, t1, p256_mod, p256_mp_mod);\n    XMEMCPY(a->z, p256_norm_mod, sizeof(p256_norm_mod));\n}\n\n/* Generate the pre-computed table of points for the base point.\n *\n * a      The base point.\n * table  Place to store generated point data.\n * tmp    Temprorary data.\n * heap  Heap to use for allocation.\n */\nstatic int sp_256_gen_stripe_table_avx2_4(const sp_point* a,\n        sp_table_entry* table, sp_digit* tmp, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point td, s1d, s2d;\n#endif\n    sp_point* t;\n    sp_point* s1 = NULL;\n    sp_point* s2 = NULL;\n    int i, j;\n    int err;\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, td, t);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s1d, s1);\n    }\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, s2d, s2);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t->x, a->x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t->y, a->y, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_mod_mul_norm_4(t->z, a->z, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        t->infinity = 0;\n        sp_256_proj_to_affine_avx2_4(t, tmp);\n\n        XMEMCPY(s1->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s1->infinity = 0;\n        XMEMCPY(s2->z, p256_norm_mod, sizeof(p256_norm_mod));\n        s2->infinity = 0;\n\n        /* table[0] = {0, 0, infinity} */\n        XMEMSET(&table[0], 0, sizeof(sp_table_entry));\n        /* table[1] = Affine version of 'a' in Montgomery form */\n        XMEMCPY(table[1].x, t->x, sizeof(table->x));\n        XMEMCPY(table[1].y, t->y, sizeof(table->y));\n\n        for (i=1; i<8; i++) {\n            sp_256_proj_point_dbl_n_avx2_4(t, t, 32, tmp);\n            sp_256_proj_to_affine_avx2_4(t, tmp);\n            XMEMCPY(table[1<<i].x, t->x, sizeof(table->x));\n            XMEMCPY(table[1<<i].y, t->y, sizeof(table->y));\n        }\n\n        for (i=1; i<8; i++) {\n            XMEMCPY(s1->x, table[1<<i].x, sizeof(table->x));\n            XMEMCPY(s1->y, table[1<<i].y, sizeof(table->y));\n            for (j=(1<<i)+1; j<(1<<(i+1)); j++) {\n                XMEMCPY(s2->x, table[j-(1<<i)].x, sizeof(table->x));\n                XMEMCPY(s2->y, table[j-(1<<i)].y, sizeof(table->y));\n                sp_256_proj_point_add_qz1_avx2_4(t, s1, s2, tmp);\n                sp_256_proj_to_affine_avx2_4(t, tmp);\n                XMEMCPY(table[j].x, t->x, sizeof(table->x));\n                XMEMCPY(table[j].y, t->y, sizeof(table->y));\n            }\n        }\n    }\n\n    sp_ecc_point_free(s2, 0, heap);\n    sp_ecc_point_free(s1, 0, heap);\n    sp_ecc_point_free( t, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC */\n#if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL)\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_stripe_avx2_4(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit td[2 * 4 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* t;\n    int i, j;\n    int y, x;\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, heap,\n                           DYNAMIC_TYPE_ECC);\n    if (t == NULL) {\n        err = MEMORY_E;\n    }\n#else\n    t = td;\n#endif\n\n    if (err == MP_OKAY) {\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        y = 0;\n        for (j=0,x=31; j<8; j++,x+=32) {\n            y |= ((k[x / 64] >> (x % 64)) & 1) << j;\n        }\n        XMEMCPY(rt->x, table[y].x, sizeof(table[y].x));\n        XMEMCPY(rt->y, table[y].y, sizeof(table[y].y));\n        rt->infinity = !y;\n        for (i=30; i>=0; i--) {\n            y = 0;\n            for (j=0,x=i; j<8; j++,x+=32) {\n                y |= ((k[x / 64] >> (x % 64)) & 1) << j;\n            }\n\n            sp_256_proj_point_dbl_avx2_4(rt, rt, t);\n            XMEMCPY(p->x, table[y].x, sizeof(table[y].x));\n            XMEMCPY(p->y, table[y].y, sizeof(table[y].y));\n            p->infinity = !y;\n            sp_256_proj_point_add_qz1_avx2_4(rt, rt, p, t);\n        }\n\n        if (map != 0) {\n            sp_256_map_avx2_4(r, rt, t);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (t != NULL) {\n        XFREE(t, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return err;\n}\n\n#endif /* FP_ECC || WOLFSSL_SP_SMALL */\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * g     Point to multiply.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_avx2_4(sp_point* r, const sp_point* g, const sp_digit* k,\n        int map, void* heap)\n{\n#ifndef FP_ECC\n    return sp_256_ecc_mulmod_win_add_sub_avx2_4(r, g, k, map, heap);\n#else\n    sp_digit tmp[2 * 4 * 5];\n    sp_cache_t* cache;\n    int err = MP_OKAY;\n\n#ifndef HAVE_THREAD_LS\n    if (initCacheMutex == 0) {\n         wc_InitMutex(&sp_cache_lock);\n         initCacheMutex = 1;\n    }\n    if (wc_LockMutex(&sp_cache_lock) != 0)\n       err = BAD_MUTEX_E;\n#endif /* HAVE_THREAD_LS */\n\n    if (err == MP_OKAY) {\n        sp_ecc_get_cache(g, &cache);\n        if (cache->cnt == 2)\n            sp_256_gen_stripe_table_avx2_4(g, cache->table, tmp, heap);\n\n#ifndef HAVE_THREAD_LS\n        wc_UnLockMutex(&sp_cache_lock);\n#endif /* HAVE_THREAD_LS */\n\n        if (cache->cnt < 2) {\n            err = sp_256_ecc_mulmod_win_add_sub_avx2_4(r, g, k, map, heap);\n        }\n        else {\n            err = sp_256_ecc_mulmod_stripe_avx2_4(r, g, cache->table, k,\n                    map, heap);\n        }\n    }\n\n    return err;\n#endif\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * p     Point to multiply.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map,\n        void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[4];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 4, km);\n        sp_256_point_from_ecc_point_4(point, gm);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_256_ecc_mulmod_avx2_4(point, point, k, map, heap);\n        else\n#endif\n            err = sp_256_ecc_mulmod_4(point, point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_4(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#ifdef WOLFSSL_SP_SMALL\nstatic const sp_table_entry p256_table[256] = {\n    /* 0 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 */\n    { { 0x79e730d418a9143cL,0x75ba95fc5fedb601L,0x79fb732b77622510L,\n        0x18905f76a53755c6L },\n      { 0xddf25357ce95560aL,0x8b4ab8e4ba19e45cL,0xd2e88688dd21f325L,\n        0x8571ff1825885d85L } },\n    /* 2 */\n    { { 0x202886024147519aL,0xd0981eac26b372f0L,0xa9d4a7caa785ebc8L,\n        0xd953c50ddbdf58e9L },\n      { 0x9d6361ccfd590f8fL,0x72e9626b44e6c917L,0x7fd9611022eb64cfL,\n        0x863ebb7e9eb288f3L } },\n    /* 3 */\n    { { 0x7856b6235cdb6485L,0x808f0ea22f0a2f97L,0x3e68d9544f7e300bL,\n        0x00076055b5ff80a0L },\n      { 0x7634eb9b838d2010L,0x54014fbb3243708aL,0xe0e47d39842a6606L,\n        0x8308776134373ee0L } },\n    /* 4 */\n    { { 0x4f922fc516a0d2bbL,0x0d5cc16c1a623499L,0x9241cf3a57c62c8bL,\n        0x2f5e6961fd1b667fL },\n      { 0x5c15c70bf5a01797L,0x3d20b44d60956192L,0x04911b37071fdb52L,\n        0xf648f9168d6f0f7bL } },\n    /* 5 */\n    { { 0x9e566847e137bbbcL,0xe434469e8a6a0becL,0xb1c4276179d73463L,\n        0x5abe0285133d0015L },\n      { 0x92aa837cc04c7dabL,0x573d9f4c43260c07L,0x0c93156278e6cc37L,\n        0x94bb725b6b6f7383L } },\n    /* 6 */\n    { { 0xbbf9b48f720f141cL,0x6199b3cd2df5bc74L,0xdc3f6129411045c4L,\n        0xcdd6bbcb2f7dc4efL },\n      { 0xcca6700beaf436fdL,0x6f647f6db99326beL,0x0c0fa792014f2522L,\n        0xa361bebd4bdae5f6L } },\n    /* 7 */\n    { { 0x28aa2558597c13c7L,0xc38d635f50b7c3e1L,0x07039aecf3c09d1dL,\n        0xba12ca09c4b5292cL },\n      { 0x9e408fa459f91dfdL,0x3af43b66ceea07fbL,0x1eceb0899d780b29L,\n        0x53ebb99d701fef4bL } },\n    /* 8 */\n    { { 0x4fe7ee31b0e63d34L,0xf4600572a9e54fabL,0xc0493334d5e7b5a4L,\n        0x8589fb9206d54831L },\n      { 0xaa70f5cc6583553aL,0x0879094ae25649e5L,0xcc90450710044652L,\n        0xebb0696d02541c4fL } },\n    /* 9 */\n    { { 0x4616ca15ac1647c5L,0xb8127d47c4cf5799L,0xdc666aa3764dfbacL,\n        0xeb2820cbd1b27da3L },\n      { 0x9406f8d86a87e008L,0xd87dfa9d922378f3L,0x56ed2e4280ccecb2L,\n        0x1f28289b55a7da1dL } },\n    /* 10 */\n    { { 0xabbaa0c03b89da99L,0xa6f2d79eb8284022L,0x27847862b81c05e8L,\n        0x337a4b5905e54d63L },\n      { 0x3c67500d21f7794aL,0x207005b77d6d7f61L,0x0a5a378104cfd6e8L,\n        0x0d65e0d5f4c2fbd6L } },\n    /* 11 */\n    { { 0xd9d09bbeb5275d38L,0x4268a7450be0a358L,0xf0762ff4973eb265L,\n        0xc23da24252f4a232L },\n      { 0x5da1b84f0b94520cL,0x09666763b05bd78eL,0x3a4dcb8694d29ea1L,\n        0x19de3b8cc790cff1L } },\n    /* 12 */\n    { { 0x183a716c26c5fe04L,0x3b28de0b3bba1bdbL,0x7432c586a4cb712cL,\n        0xe34dcbd491fccbfdL },\n      { 0xb408d46baaa58403L,0x9a69748682e97a53L,0x9e39012736aaa8afL,\n        0xe7641f447b4e0f7fL } },\n    /* 13 */\n    { { 0x7d753941df64ba59L,0xd33f10ec0b0242fcL,0x4f06dfc6a1581859L,\n        0x4a12df57052a57bfL },\n      { 0xbfa6338f9439dbd0L,0xd3c24bd4bde53e1fL,0xfd5e4ffa21f1b314L,\n        0x6af5aa93bb5bea46L } },\n    /* 14 */\n    { { 0xda10b69910c91999L,0x0a24b4402a580491L,0x3e0094b4b8cc2090L,\n        0x5fe3475a66a44013L },\n      { 0xb0f8cabdf93e7b4bL,0x292b501a7c23f91aL,0x42e889aecd1e6263L,\n        0xb544e308ecfea916L } },\n    /* 15 */\n    { { 0x6478c6e916ddfdceL,0x2c329166f89179e6L,0x4e8d6e764d4e67e1L,\n        0xe0b6b2bda6b0c20bL },\n      { 0x0d312df2bb7efb57L,0x1aac0dde790c4007L,0xf90336ad679bc944L,\n        0x71c023de25a63774L } },\n    /* 16 */\n    { { 0x62a8c244bfe20925L,0x91c19ac38fdce867L,0x5a96a5d5dd387063L,\n        0x61d587d421d324f6L },\n      { 0xe87673a2a37173eaL,0x2384800853778b65L,0x10f8441e05bab43eL,\n        0xfa11fe124621efbeL } },\n    /* 17 */\n    { { 0x1c891f2b2cb19ffdL,0x01ba8d5bb1923c23L,0xb6d03d678ac5ca8eL,\n        0x586eb04c1f13bedcL },\n      { 0x0c35c6e527e8ed09L,0x1e81a33c1819ede2L,0x278fd6c056c652faL,\n        0x19d5ac0870864f11L } },\n    /* 18 */\n    { { 0x1e99f581309a4e1fL,0xab7de71be9270074L,0x26a5ef0befd28d20L,\n        0xe7c0073f7f9c563fL },\n      { 0x1f6d663a0ef59f76L,0x669b3b5420fcb050L,0xc08c1f7a7a6602d4L,\n        0xe08504fec65b3c0aL } },\n    /* 19 */\n    { { 0xf098f68da031b3caL,0x6d1cab9ee6da6d66L,0x5bfd81fa94f246e8L,\n        0x78f018825b0996b4L },\n      { 0xb7eefde43a25787fL,0x8016f80d1dccac9bL,0x0cea4877b35bfc36L,\n        0x43a773b87e94747aL } },\n    /* 20 */\n    { { 0x62577734d2b533d5L,0x673b8af6a1bdddc0L,0x577e7c9aa79ec293L,\n        0xbb6de651c3b266b1L },\n      { 0xe7e9303ab65259b3L,0xd6a0afd3d03a7480L,0xc5ac83d19b3cfc27L,\n        0x60b4619a5d18b99bL } },\n    /* 21 */\n    { { 0xbd6a38e11ae5aa1cL,0xb8b7652b49e73658L,0x0b130014ee5f87edL,\n        0x9d0f27b2aeebffcdL },\n      { 0xca9246317a730a55L,0x9c955b2fddbbc83aL,0x07c1dfe0ac019a71L,\n        0x244a566d356ec48dL } },\n    /* 22 */\n    { { 0x6db0394aeacf1f96L,0x9f2122a9024c271cL,0x2626ac1b82cbd3b9L,\n        0x45e58c873581ef69L },\n      { 0xd3ff479da38f9dbcL,0xa8aaf146e888a040L,0x945adfb246e0bed7L,\n        0xc040e21cc1e4b7a4L } },\n    /* 23 */\n    { { 0x847af0006f8117b6L,0x651969ff73a35433L,0x482b35761d9475ebL,\n        0x1cdf5c97682c6ec7L },\n      { 0x7db775b411f04839L,0x7dbeacf448de1698L,0xb2921dd1b70b3219L,\n        0x046755f8a92dff3dL } },\n    /* 24 */\n    { { 0xcc8ac5d2bce8ffcdL,0x0d53c48b2fe61a82L,0xf6f161727202d6c7L,\n        0x046e5e113b83a5f3L },\n      { 0xe7b8ff64d8007f01L,0x7fb1ef125af43183L,0x045c5ea635e1a03cL,\n        0x6e0106c3303d005bL } },\n    /* 25 */\n    { { 0x48c7358488dd73b1L,0x7670708f995ed0d9L,0x38385ea8c56a2ab7L,\n        0x442594ede901cf1fL },\n      { 0xf8faa2c912d4b65bL,0x94c2343b96c90c37L,0xd326e4a15e978d1fL,\n        0xa796fa514c2ee68eL } },\n    /* 26 */\n    { { 0x359fb604823addd7L,0x9e2a6183e56693b3L,0xf885b78e3cbf3c80L,\n        0xe4ad2da9c69766e9L },\n      { 0x357f7f428e048a61L,0x082d198cc092d9a0L,0xfc3a1af4c03ed8efL,\n        0xc5e94046c37b5143L } },\n    /* 27 */\n    { { 0x476a538c2be75f9eL,0x6fd1a9e8cb123a78L,0xd85e4df0b109c04bL,\n        0x63283dafdb464747L },\n      { 0xce728cf7baf2df15L,0xe592c4550ad9a7f4L,0xfab226ade834bcc3L,\n        0x68bd19ab1981a938L } },\n    /* 28 */\n    { { 0xc08ead511887d659L,0x3374d5f4b359305aL,0x96986981cfe74fe3L,\n        0x495292f53c6fdfd6L },\n      { 0x4a878c9e1acec896L,0xd964b210ec5b4484L,0x6696f7e2664d60a7L,\n        0x0ec7530d26036837L } },\n    /* 29 */\n    { { 0x2da13a05ad2687bbL,0xa1f83b6af32e21faL,0x390f5ef51dd4607bL,\n        0x0f6207a664863f0bL },\n      { 0xbd67e3bb0f138233L,0xdd66b96c272aa718L,0x8ed0040726ec88aeL,\n        0xff0db07208ed6dcfL } },\n    /* 30 */\n    { { 0x749fa1014c95d553L,0xa44052fd5d680a8aL,0x183b4317ff3b566fL,\n        0x313b513c88740ea3L },\n      { 0xb402e2ac08d11549L,0x071ee10bb4dee21cL,0x26b987dd47f2320eL,\n        0x2d3abcf986f19f81L } },\n    /* 31 */\n    { { 0x4c288501815581a2L,0x9a0a6d56632211afL,0x19ba7a0f0cab2e99L,\n        0xc036fa10ded98cdfL },\n      { 0x29ae08bac1fbd009L,0x0b68b19006d15816L,0xc2eb32779b9e0d8fL,\n        0xa6b2a2c4b6d40194L } },\n    /* 32 */\n    { { 0xd433e50f6d3549cfL,0x6f33696ffacd665eL,0x695bfdacce11fcb4L,\n        0x810ee252af7c9860L },\n      { 0x65450fe17159bb2cL,0xf7dfbebe758b357bL,0x2b057e74d69fea72L,\n        0xd485717a92731745L } },\n    /* 33 */\n    { { 0x11741a8af0cb5a98L,0xd3da8f931f3110bfL,0x1994e2cbab382adfL,\n        0x6a6045a72f9a604eL },\n      { 0x170c0d3fa2b2411dL,0xbe0eb83e510e96e0L,0x3bcc9f738865b3ccL,\n        0xd3e45cfaf9e15790L } },\n    /* 34 */\n    { { 0xce1f69bbe83f7669L,0x09f8ae8272877d6bL,0x9548ae543244278dL,\n        0x207755dee3c2c19cL },\n      { 0x87bd61d96fef1945L,0x18813cefb12d28c3L,0x9fbcd1d672df64aaL,\n        0x48dc5ee57154b00dL } },\n    /* 35 */\n    { { 0x123790bff7e5a199L,0xe0efb8cf989ccbb7L,0xc27a2bfe0a519c79L,\n        0xf2fb0aeddff6f445L },\n      { 0x41c09575f0b5025fL,0x550543d740fa9f22L,0x8fa3c8ad380bfbd0L,\n        0xa13e9015db28d525L } },\n    /* 36 */\n    { { 0xf9f7a350a2b65cbcL,0x0b04b9722a464226L,0x265ce241e23f07a1L,\n        0x2bf0d6b01497526fL },\n      { 0xd3d4dd3f4b216fb7L,0xf7d7b867fbdda26aL,0xaeb7b83f6708505cL,\n        0x42a94a5a162fe89fL } },\n    /* 37 */\n    { { 0x5846ad0beaadf191L,0x0f8a489025a268d7L,0xe8603050494dc1f6L,\n        0x2c2dd969c65ede3dL },\n      { 0x6d02171d93849c17L,0x460488ba1da250ddL,0x4810c7063c3a5485L,\n        0xf437fa1f42c56dbcL } },\n    /* 38 */\n    { { 0x6aa0d7144a0f7dabL,0x0f0497931776e9acL,0x52c0a050f5f39786L,\n        0xaaf45b3354707aa8L },\n      { 0x85e37c33c18d364aL,0xd40b9b063e497165L,0xf417168115ec5444L,\n        0xcdf6310df4f272bcL } },\n    /* 39 */\n    { { 0x7473c6238ea8b7efL,0x08e9351885bc2287L,0x419567722bda8e34L,\n        0xf0d008bada9e2ff2L },\n      { 0x2912671d2414d3b1L,0xb3754985b019ea76L,0x5c61b96d453bcbdbL,\n        0x5bd5c2f5ca887b8bL } },\n    /* 40 */\n    { { 0xef0f469ef49a3154L,0x3e85a5956e2b2e9aL,0x45aaec1eaa924a9cL,\n        0xaa12dfc8a09e4719L },\n      { 0x26f272274df69f1dL,0xe0e4c82ca2ff5e73L,0xb9d8ce73b7a9dd44L,\n        0x6c036e73e48ca901L } },\n    /* 41 */\n    { { 0x5cfae12a0f6e3138L,0x6966ef0025ad345aL,0x8993c64b45672bc5L,\n        0x292ff65896afbe24L },\n      { 0xd5250d445e213402L,0xf6580e274392c9feL,0x097b397fda1c72e8L,\n        0x644e0c90311b7276L } },\n    /* 42 */\n    { { 0xe1e421e1a47153f0L,0xb86c3b79920418c9L,0x93bdce87705d7672L,\n        0xf25ae793cab79a77L },\n      { 0x1f3194a36d869d0cL,0x9d55c8824986c264L,0x49fb5ea3096e945eL,\n        0x39b8e65313db0a3eL } },\n    /* 43 */\n    { { 0x37754200b6fd2e59L,0x35e2c0669255c98fL,0xd9dab21a0e2a5739L,\n        0x39122f2f0f19db06L },\n      { 0xcfbce1e003cad53cL,0x225b2c0fe65c17e3L,0x72baf1d29aa13877L,\n        0x8de80af8ce80ff8dL } },\n    /* 44 */\n    { { 0xafbea8d9207bbb76L,0x921c7e7c21782758L,0xdfa2b74b1c0436b1L,\n        0x871949062e368c04L },\n      { 0xb5f928bba3993df5L,0x639d75b5f3b3d26aL,0x011aa78a85b55050L,\n        0xfc315e6a5b74fde1L } },\n    /* 45 */\n    { { 0x561fd41ae8d6ecfaL,0x5f8c44f61aec7f86L,0x98452a7b4924741dL,\n        0xe6d4a7adee389088L },\n      { 0x60552ed14593c75dL,0x70a70da4dd271162L,0xd2aede937ba2c7dbL,\n        0x35dfaf9a9be2ae57L } },\n    /* 46 */\n    { { 0x6b956fcdaa736636L,0x09f51d97ae2cab7eL,0xfb10bf410f349966L,\n        0x1da5c7d71c830d2bL },\n      { 0x5c41e4833cce6825L,0x15ad118ff9573c3bL,0xa28552c7f23036b8L,\n        0x7077c0fddbf4b9d6L } },\n    /* 47 */\n    { { 0xbf63ff8d46b9661cL,0xa1dfd36b0d2cfd71L,0x0373e140a847f8f7L,\n        0x53a8632ee50efe44L },\n      { 0x0976ff68696d8051L,0xdaec0c95c74f468aL,0x62994dc35e4e26bdL,\n        0x028ca76d34e1fcc1L } },\n    /* 48 */\n    { { 0xd11d47dcfc9877eeL,0xc8b36210801d0002L,0xd002c11754c260b6L,\n        0x04c17cd86962f046L },\n      { 0x6d9bd094b0daddf5L,0xbea2357524ce55c0L,0x663356e672da03b5L,\n        0xf7ba4de9fed97474L } },\n    /* 49 */\n    { { 0xd0dbfa34ebe1263fL,0x5576373571ae7ce6L,0xd244055382a6f523L,\n        0xe31f960052131c41L },\n      { 0xd1bb9216ea6b6ec6L,0x37a1d12e73c2fc44L,0xc10e7eac89d0a294L,\n        0xaa3a6259ce34d47bL } },\n    /* 50 */\n    { { 0xfbcf9df536f3dcd3L,0x6ceded50d2bf7360L,0x491710fadf504f5bL,\n        0x2398dd627e79daeeL },\n      { 0xcf4705a36d09569eL,0xea0619bb5149f769L,0xff9c037735f6034cL,\n        0x5717f5b21c046210L } },\n    /* 51 */\n    { { 0x9fe229c921dd895eL,0x8e51850040c28451L,0xfa13d2391d637ecdL,\n        0x660a2c560e3c28deL },\n      { 0x9cca88aed67fcbd0L,0xc84724780ea9f096L,0x32b2f48172e92b4dL,\n        0x624ee54c4f522453L } },\n    /* 52 */\n    { { 0x09549ce4d897ecccL,0x4d49d1d93f9880aaL,0x723c2423043a7c20L,\n        0x4f392afb92bdfbc0L },\n      { 0x6969f8fa7de44fd9L,0xb66cfbe457b32156L,0xdb2fa803368ebc3cL,\n        0x8a3e7977ccdb399cL } },\n    /* 53 */\n    { { 0xdde1881f06c4b125L,0xae34e300f6e3ca8cL,0xef6999de5c7a13e9L,\n        0x3888d02370c24404L },\n      { 0x7628035644f91081L,0x3d9fcf615f015504L,0x1827edc8632cd36eL,\n        0xa5e62e4718102336L } },\n    /* 54 */\n    { { 0x1a825ee32facd6c8L,0x699c635454bcbc66L,0x0ce3edf798df9931L,\n        0x2c4768e6466a5adcL },\n      { 0xb346ff8c90a64bc9L,0x630a6020e4779f5cL,0xd949d064bc05e884L,\n        0x7b5e6441f9e652a0L } },\n    /* 55 */\n    { { 0x2169422c1d28444aL,0xe996c5d8be136a39L,0x2387afe5fb0c7fceL,\n        0xb8af73cb0c8d744aL },\n      { 0x5fde83aa338b86fdL,0xfee3f158a58a5cffL,0xc9ee8f6f20ac9433L,\n        0xa036395f7f3f0895L } },\n    /* 56 */\n    { { 0x8c73c6bba10f7770L,0xa6f16d81a12a0e24L,0x100df68251bc2b9fL,\n        0x4be36b01875fb533L },\n      { 0x9226086e9fb56dbbL,0x306fef8b07e7a4f8L,0xeeaccc0566d52f20L,\n        0x8cbc9a871bdc00c0L } },\n    /* 57 */\n    { { 0xe131895cc0dac4abL,0xa874a440712ff112L,0x6332ae7c6a1cee57L,\n        0x44e7553e0c0835f8L },\n      { 0x6d503fff7734002dL,0x9d35cb8b0b34425cL,0x95f702760e8738b5L,\n        0x470a683a5eb8fc18L } },\n    /* 58 */\n    { { 0x81b761dc90513482L,0x0287202a01e9276aL,0xcda441ee0ce73083L,\n        0x16410690c63dc6efL },\n      { 0xf5034a066d06a2edL,0xdd4d7745189b100bL,0xd914ae72ab8218c9L,\n        0xd73479fd7abcbb4fL } },\n    /* 59 */\n    { { 0x7edefb165ad4c6e5L,0x262cf08f5b06d04dL,0x12ed5bb18575cb14L,\n        0x816469e30771666bL },\n      { 0xd7ab9d79561e291eL,0xeb9daf22c1de1661L,0xf49827eb135e0513L,\n        0x0a36dd23f0dd3f9cL } },\n    /* 60 */\n    { { 0x098d32c741d5533cL,0x7c5f5a9e8684628fL,0x39a228ade349bd11L,\n        0xe331dfd6fdbab118L },\n      { 0x5100ab686bcc6ed8L,0x7160c3bdef7a260eL,0x9063d9a7bce850d7L,\n        0xd3b4782a492e3389L } },\n    /* 61 */\n    { { 0xa149b6e8f3821f90L,0x92edd9ed66eb7aadL,0x0bb669531a013116L,\n        0x7281275a4c86a5bdL },\n      { 0x503858f7d3ff47e5L,0x5e1616bc61016441L,0x62b0f11a7dfd9bb1L,\n        0x2c062e7ece145059L } },\n    /* 62 */\n    { { 0xa76f996f0159ac2eL,0x281e7736cbdb2713L,0x2ad6d28808e46047L,\n        0x282a35f92c4e7ef1L },\n      { 0x9c354b1ec0ce5cd2L,0xcf99efc91379c229L,0x992caf383e82c11eL,\n        0xc71cd513554d2abdL } },\n    /* 63 */\n    { { 0x4885de9c09b578f4L,0x1884e258e3affa7aL,0x8f76b1b759182f1fL,\n        0xc50f6740cf47f3a3L },\n      { 0xa9c4adf3374b68eaL,0xa406f32369965fe2L,0x2f86a22285a53050L,\n        0xb9ecb3a7212958dcL } },\n    /* 64 */\n    { { 0x56f8410ef4f8b16aL,0x97241afec47b266aL,0x0a406b8e6d9c87c1L,\n        0x803f3e02cd42ab1bL },\n      { 0x7f0309a804dbec69L,0xa83b85f73bbad05fL,0xc6097273ad8e197fL,\n        0xc097440e5067adc1L } },\n    /* 65 */\n    { { 0x846a56f2c379ab34L,0xa8ee068b841df8d1L,0x20314459176c68efL,\n        0xf1af32d5915f1f30L },\n      { 0x99c375315d75bd50L,0x837cffbaf72f67bcL,0x0613a41848d7723fL,\n        0x23d0f130e2d41c8bL } },\n    /* 66 */\n    { { 0x857ab6edf41500d9L,0x0d890ae5fcbeada8L,0x52fe864889725951L,\n        0xb0288dd6c0a3faddL },\n      { 0x85320f30650bcb08L,0x71af6313695d6e16L,0x31f520a7b989aa76L,\n        0xffd3724ff408c8d2L } },\n    /* 67 */\n    { { 0x53968e64b458e6cbL,0x992dad20317a5d28L,0x3814ae0b7aa75f56L,\n        0xf5590f4ad78c26dfL },\n      { 0x0fc24bd3cf0ba55aL,0x0fc4724a0c778baeL,0x1ce9864f683b674aL,\n        0x18d6da54f6f74a20L } },\n    /* 68 */\n    { { 0xed93e225d5be5a2bL,0x6fe799835934f3c6L,0x4314092622626ffcL,\n        0x50bbb4d97990216aL },\n      { 0x378191c6e57ec63eL,0x65422c40181dcdb2L,0x41a8099b0236e0f6L,\n        0x2b10011801fe49c3L } },\n    /* 69 */\n    { { 0xfc68b5c59b391593L,0xc385f5a2598270fcL,0x7144f3aad19adcbbL,\n        0xdd55899983fbae0cL },\n      { 0x93b88b8e74b82ff4L,0xd2e03c4071e734c9L,0x9a7a9eaf43c0322aL,\n        0xe6e4c551149d6041L } },\n    /* 70 */\n    { { 0x55f655bb1e9af288L,0x647e1a64f7ada931L,0x43697e4bcb2820e5L,\n        0x51e00db107ed56ffL },\n      { 0x43d169b8771c327eL,0x29cdb20b4a96c2adL,0xc07d51f53deb4779L,\n        0xe22f424149829177L } },\n    /* 71 */\n    { { 0xcd45e8f4635f1abbL,0x7edc0cb568538874L,0xc9472c1fb5a8034dL,\n        0xf709373d52dc48c9L },\n      { 0x401966bba8af30d6L,0x95bf5f4af137b69cL,0x3966162a9361c47eL,\n        0xbd52d288e7275b11L } },\n    /* 72 */\n    { { 0xab155c7a9c5fa877L,0x17dad6727d3a3d48L,0x43f43f9e73d189d8L,\n        0xa0d0f8e4c8aa77a6L },\n      { 0x0bbeafd8cc94f92dL,0xd818c8be0c4ddb3aL,0x22cc65f8b82eba14L,\n        0xa56c78c7946d6a00L } },\n    /* 73 */\n    { { 0x2962391b0dd09529L,0x803e0ea63daddfcfL,0x2c77351f5b5bf481L,\n        0xd8befdf8731a367aL },\n      { 0xab919d42fc0157f4L,0xf51caed7fec8e650L,0xcdf9cb4002d48b0aL,\n        0x854a68a5ce9f6478L } },\n    /* 74 */\n    { { 0xdc35f67b63506ea5L,0x9286c489a4fe0d66L,0x3f101d3bfe95cd4dL,\n        0x5cacea0b98846a95L },\n      { 0xa90df60c9ceac44dL,0x3db29af4354d1c3aL,0x08dd3de8ad5dbabeL,\n        0xe4982d1235e4efa9L } },\n    /* 75 */\n    { { 0x23104a22c34cd55eL,0x58695bb32680d132L,0xfb345afa1fa1d943L,\n        0x8046b7f616b20499L },\n      { 0xb533581e38e7d098L,0xd7f61e8df46f0b70L,0x30dea9ea44cb78c4L,\n        0xeb17ca7b9082af55L } },\n    /* 76 */\n    { { 0x1751b59876a145b9L,0xa5cf6b0fc1bc71ecL,0xd3e03565392715bbL,\n        0x097b00bafab5e131L },\n      { 0xaa66c8e9565f69e1L,0x77e8f75ab5be5199L,0x6033ba11da4fd984L,\n        0xf95c747bafdbcc9eL } },\n    /* 77 */\n    { { 0x558f01d3bebae45eL,0xa8ebe9f0c4bc6955L,0xaeb705b1dbc64fc6L,\n        0x3512601e566ed837L },\n      { 0x9336f1e1fa1161cdL,0x328ab8d54c65ef87L,0x4757eee2724f21e5L,\n        0x0ef971236068ab6bL } },\n    /* 78 */\n    { { 0x02598cf754ca4226L,0x5eede138f8642c8eL,0x48963f74468e1790L,\n        0xfc16d9333b4fbc95L },\n      { 0xbe96fb31e7c800caL,0x138063312678adaaL,0x3d6244976ff3e8b5L,\n        0x14ca4af1b95d7a17L } },\n    /* 79 */\n    { { 0x7a4771babd2f81d5L,0x1a5f9d6901f7d196L,0xd898bef7cad9c907L,\n        0x4057b063f59c231dL },\n      { 0xbffd82fe89c05c0aL,0xe4911c6f1dc0df85L,0x3befccaea35a16dbL,\n        0x1c3b5d64f1330b13L } },\n    /* 80 */\n    { { 0x5fe14bfe80ec21feL,0xf6ce116ac255be82L,0x98bc5a072f4a5d67L,\n        0xfad27148db7e63afL },\n      { 0x90c0b6ac29ab05b3L,0x37a9a83c4e251ae6L,0x0a7dc875c2aade7dL,\n        0x77387de39f0e1a84L } },\n    /* 81 */\n    { { 0x1e9ecc49a56c0dd7L,0xa5cffcd846086c74L,0x8f7a1408f505aeceL,\n        0xb37b85c0bef0c47eL },\n      { 0x3596b6e4cc0e6a8fL,0xfd6d4bbf6b388f23L,0xaba453fac39cef4eL,\n        0x9c135ac8f9f628d5L } },\n    /* 82 */\n    { { 0x32aa320284e35743L,0x320d6ab185a3cdefL,0xb821b1761df19819L,\n        0x5721361fc433851fL },\n      { 0x1f0db36a71fc9168L,0x5f98ba735e5c403cL,0xf64ca87e37bcd8f5L,\n        0xdcbac3c9e6bb11bdL } },\n    /* 83 */\n    { { 0xf01d99684518cbe2L,0xd242fc189c9eb04eL,0x727663c7e47feebfL,\n        0xb8c1c89e2d626862L },\n      { 0x51a58bddc8e1d569L,0x563809c8b7d88cd0L,0x26c27fd9f11f31ebL,\n        0x5d23bbda2f9422d4L } },\n    /* 84 */\n    { { 0x0a1c729495c8f8beL,0x2961c4803bf362bfL,0x9e418403df63d4acL,\n        0xc109f9cb91ece900L },\n      { 0xc2d095d058945705L,0xb9083d96ddeb85c0L,0x84692b8d7a40449bL,\n        0x9bc3344f2eee1ee1L } },\n    /* 85 */\n    { { 0x0d5ae35642913074L,0x55491b2748a542b1L,0x469ca665b310732aL,\n        0x29591d525f1a4cc1L },\n      { 0xe76f5b6bb84f983fL,0xbe7eef419f5f84e1L,0x1200d49680baa189L,\n        0x6376551f18ef332cL } },\n    /* 86 */\n    { { 0xbda5f14e562976ccL,0x22bca3e60ef12c38L,0xbbfa30646cca9852L,\n        0xbdb79dc808e2987aL },\n      { 0xfd2cb5c9cb06a772L,0x38f475aafe536dceL,0xc2a3e0227c2b5db8L,\n        0x8ee86001add3c14aL } },\n    /* 87 */\n    { { 0xcbe96981a4ade873L,0x7ee9aa4dc4fba48cL,0x2cee28995a054ba5L,\n        0x92e51d7a6f77aa4bL },\n      { 0x948bafa87190a34dL,0xd698f75bf6bd1ed1L,0xd00ee6e30caf1144L,\n        0x5182f86f0a56aaaaL } },\n    /* 88 */\n    { { 0xfba6212c7a4cc99cL,0xff609b683e6d9ca1L,0x5dbb27cb5ac98c5aL,\n        0x91dcab5d4073a6f2L },\n      { 0x01b6cc3d5f575a70L,0x0cb361396f8d87faL,0x165d4e8c89981736L,\n        0x17a0cedb97974f2bL } },\n    /* 89 */\n    { { 0x38861e2a076c8d3aL,0x701aad39210f924bL,0x94d0eae413a835d9L,\n        0x2e8ce36c7f4cdf41L },\n      { 0x91273dab037a862bL,0x01ba9bb760e4c8faL,0xf964538833baf2ddL,\n        0xf4ccc6cb34f668f3L } },\n    /* 90 */\n    { { 0x44ef525cf1f79687L,0x7c59549592efa815L,0xe1231741a5c78d29L,\n        0xac0db4889a0df3c9L },\n      { 0x86bfc711df01747fL,0x592b9358ef17df13L,0xe5880e4f5ccb6bb5L,\n        0x95a64a6194c974a2L } },\n    /* 91 */\n    { { 0x72c1efdac15a4c93L,0x40269b7382585141L,0x6a8dfb1c16cb0badL,\n        0x231e54ba29210677L },\n      { 0xa70df9178ae6d2dcL,0x4d6aa63f39112918L,0xf627726b5e5b7223L,\n        0xab0be032d8a731e1L } },\n    /* 92 */\n    { { 0x097ad0e98d131f2dL,0x637f09e33b04f101L,0x1ac86196d5e9a748L,\n        0xf1bcc8802cf6a679L },\n      { 0x25c69140e8daacb4L,0x3c4e405560f65009L,0x591cc8fc477937a6L,\n        0x851694695aebb271L } },\n    /* 93 */\n    { { 0xde35c143f1dcf593L,0x78202b29b018be3bL,0xe9cdadc29bdd9d3dL,\n        0x8f67d9d2daad55d8L },\n      { 0x841116567481ea5fL,0xe7d2dde9e34c590cL,0xffdd43f405053fa8L,\n        0xf84572b9c0728b5dL } },\n    /* 94 */\n    { { 0x5e1a7a7197af71c9L,0xa14494447a736565L,0xa1b4ae070e1d5063L,\n        0xedee2710616b2c19L },\n      { 0xb2f034f511734121L,0x1cac6e554a25e9f0L,0x8dc148f3a40c2ecfL,\n        0x9fd27e9b44ebd7f4L } },\n    /* 95 */\n    { { 0x3cc7658af6e2cb16L,0xe3eb7d2cfe5919b6L,0x5a8c5816168d5583L,\n        0xa40c2fb6958ff387L },\n      { 0x8c9ec560fedcc158L,0x7ad804c655f23056L,0xd93967049a307e12L,\n        0x99bc9bb87dc6decfL } },\n    /* 96 */\n    { { 0x84a9521d927dafc6L,0x52c1fb695c09cd19L,0x9d9581a0f9366ddeL,\n        0x9abe210ba16d7e64L },\n      { 0x480af84a48915220L,0xfa73176a4dd816c6L,0xc7d539871681ca5aL,\n        0x7881c25787f344b0L } },\n    /* 97 */\n    { { 0x93399b51e0bcf3ffL,0x0d02cbc5127f74f6L,0x8fb465a2dd01d968L,\n        0x15e6e319a30e8940L },\n      { 0x646d6e0d3e0e05f4L,0xfad7bddc43588404L,0xbe61c7d1c4f850d3L,\n        0x0e55facf191172ceL } },\n    /* 98 */\n    { { 0x7e9d9806f8787564L,0x1a33172131e85ce6L,0x6b0158cab819e8d6L,\n        0xd73d09766fe96577L },\n      { 0x424834251eb7206eL,0xa519290fc618bb42L,0x5dcbb8595e30a520L,\n        0x9250a3748f15a50bL } },\n    /* 99 */\n    { { 0xcaff08f8be577410L,0xfd408a035077a8c6L,0xf1f63289ec0a63a4L,\n        0x77414082c1cc8c0bL },\n      { 0x05a40fa6eb0991cdL,0xc1ca086649fdc296L,0x3a68a3c7b324fd40L,\n        0x8cb04f4d12eb20b9L } },\n    /* 100 */\n    { { 0xb1c2d0556906171cL,0x9073e9cdb0240c3fL,0xdb8e6b4fd8906841L,\n        0xe4e429ef47123b51L },\n      { 0x0b8dd53c38ec36f4L,0xf9d2dc01ff4b6a27L,0x5d066e07879a9a48L,\n        0x37bca2ff3c6e6552L } },\n    /* 101 */\n    { { 0x4cd2e3c7df562470L,0x44f272a2c0964ac9L,0x7c6d5df980c793beL,\n        0x59913edc3002b22aL },\n      { 0x7a139a835750592aL,0x99e01d80e783de02L,0xcf8c0375ea05d64fL,\n        0x43786e4ab013e226L } },\n    /* 102 */\n    { { 0xff32b0ed9e56b5a6L,0x0750d9a6d9fc68f9L,0xec15e845597846a7L,\n        0x8638ca98b7e79e7aL },\n      { 0x2f5ae0960afc24b2L,0x05398eaf4dace8f2L,0x3b765dd0aecba78fL,\n        0x1ecdd36a7b3aa6f0L } },\n    /* 103 */\n    { { 0x5d3acd626c5ff2f3L,0xa2d516c02873a978L,0xad94c9fad2110d54L,\n        0xd85d0f85d459f32dL },\n      { 0x9f700b8d10b11da3L,0xd2c22c30a78318c4L,0x556988f49208decdL,\n        0xa04f19c3b4ed3c62L } },\n    /* 104 */\n    { { 0x087924c8ed7f93bdL,0xcb64ac5d392f51f6L,0x7cae330a821b71afL,\n        0x92b2eeea5c0950b0L },\n      { 0x85ac4c9485b6e235L,0xab2ca4a92936c0f0L,0x80faa6b3e0508891L,\n        0x1ee782215834276cL } },\n    /* 105 */\n    { { 0xa60a2e00e63e79f7L,0xf590e7b2f399d906L,0x9021054a6607c09dL,\n        0xf3f2ced857a6e150L },\n      { 0x200510f3f10d9b55L,0x9d2fcfacd8642648L,0xe5631aa7e8bd0e7cL,\n        0x0f56a4543da3e210L } },\n    /* 106 */\n    { { 0x5b21bffa1043e0dfL,0x6c74b6cc9c007e6dL,0x1a656ec0d4a8517aL,\n        0xbd8f17411969e263L },\n      { 0x8a9bbb86beb7494aL,0x1567d46f45f3b838L,0xdf7a12a7a4e5a79aL,\n        0x2d1a1c3530ccfa09L } },\n    /* 107 */\n    { { 0x192e3813506508daL,0x336180c4a1d795a7L,0xcddb59497a9944b3L,\n        0xa107a65eb91fba46L },\n      { 0xe6d1d1c50f94d639L,0x8b4af3758a58b7d7L,0x1a7c5584bd37ca1cL,\n        0x183d760af87a9af2L } },\n    /* 108 */\n    { { 0x29d697110dde59a4L,0xf1ad8d070e8bef87L,0x229b49634f2ebe78L,\n        0x1d44179dc269d754L },\n      { 0xb32dc0cf8390d30eL,0x0a3b27530de8110cL,0x31af1dc52bc0339aL,\n        0x771f9cc29606d262L } },\n    /* 109 */\n    { { 0x99993e7785040739L,0x44539db98026a939L,0xcf40f6f2f5f8fc26L,\n        0x64427a310362718eL },\n      { 0x4f4f2d8785428aa8L,0x7b7adc3febfb49a8L,0x201b2c6df23d01acL,\n        0x49d9b7496ae90d6dL } },\n    /* 110 */\n    { { 0xcc78d8bc435d1099L,0x2adbcd4e8e8d1a08L,0x02c2e2a02cb68a41L,\n        0x9037d81b3f605445L },\n      { 0x7cdbac27074c7b61L,0xfe2031ab57bfd72eL,0x61ccec96596d5352L,\n        0x08c3de6a7cc0639cL } },\n    /* 111 */\n    { { 0x20fdd020f6d552abL,0x56baff9805cd81f1L,0x06fb7c3e91351291L,\n        0xc690944245796b2fL },\n      { 0x17b3ae9c41231bd1L,0x1eac6e875cc58205L,0x208837abf9d6a122L,\n        0x3fa3db02cafe3ac0L } },\n    /* 112 */\n    { { 0xd75a3e6505058880L,0x7da365ef643943f2L,0x4147861cfab24925L,\n        0xc5c4bdb0fdb808ffL },\n      { 0x73513e34b272b56bL,0xc8327e9511b9043aL,0xfd8ce37df8844969L,\n        0x2d56db9446c2b6b5L } },\n    /* 113 */\n    { { 0x2461782fff46ac6bL,0xd19f792607a2e425L,0xfafea3c409a48de1L,\n        0x0f56bd9de503ba42L },\n      { 0x137d4ed1345cda49L,0x821158fc816f299dL,0xe7c6a54aaeb43402L,\n        0x4003bb9d1173b5f1L } },\n    /* 114 */\n    { { 0x3b8e8189a0803387L,0xece115f539cbd404L,0x4297208dd2877f21L,\n        0x53765522a07f2f9eL },\n      { 0xa4980a21a8a4182dL,0xa2bbd07a3219df79L,0x674d0a2e1a19a2d4L,\n        0x7a056f586c5d4549L } },\n    /* 115 */\n    { { 0x646b25589d8a2a47L,0x5b582948c3df2773L,0x51ec000eabf0d539L,\n        0x77d482f17a1a2675L },\n      { 0xb8a1bd9587853948L,0xa6f817bd6cfbffeeL,0xab6ec05780681e47L,\n        0x4115012b2b38b0e4L } },\n    /* 116 */\n    { { 0x3c73f0f46de28cedL,0x1d5da7609b13ec47L,0x61b8ce9e6e5c6392L,\n        0xcdf04572fbea0946L },\n      { 0x1cb3c58b6c53c3b0L,0x97fe3c10447b843cL,0xfb2b8ae12cb9780eL,\n        0xee703dda97383109L } },\n    /* 117 */\n    { { 0x34515140ff57e43aL,0xd44660d3b1b811b8L,0x2b3b5dff8f42b986L,\n        0x2a0ad89da162ce21L },\n      { 0x64e4a6946bc277baL,0xc788c954c141c276L,0x141aa64ccabf6274L,\n        0xd62d0b67ac2b4659L } },\n    /* 118 */\n    { { 0x39c5d87b2c054ac4L,0x57005859f27df788L,0xedf7cbf3b18128d6L,\n        0xb39a23f2991c2426L },\n      { 0x95284a15f0b16ae5L,0x0c6a05b1a136f51bL,0x1d63c137f2700783L,\n        0x04ed0092c0674cc5L } },\n    /* 119 */\n    { { 0x1f4185d19ae90393L,0x3047b4294a3d64e6L,0xae0001a69854fc14L,\n        0xa0a91fc10177c387L },\n      { 0xff0a3f01ae2c831eL,0xbb76ae822b727e16L,0x8f12c8a15a3075b4L,\n        0x084cf9889ed20c41L } },\n    /* 120 */\n    { { 0xd98509defca6becfL,0x2fceae807dffb328L,0x5d8a15c44778e8b9L,\n        0xd57955b273abf77eL },\n      { 0x210da79e31b5d4f1L,0xaa52f04b3cfa7a1cL,0xd4d12089dc27c20bL,\n        0x8e14ea4202d141f1L } },\n    /* 121 */\n    { { 0xeed50345f2897042L,0x8d05331f43402c4aL,0xc8d9c194c8bdfb21L,\n        0x597e1a372aa4d158L },\n      { 0x0327ec1acf0bd68cL,0x6d4be0dcab024945L,0x5b9c8d7ac9fe3e84L,\n        0xca3f0236199b4deaL } },\n    /* 122 */\n    { { 0x592a10b56170bd20L,0x0ea897f16d3f5de7L,0xa3363ff144b2ade2L,\n        0xbde7fd7e309c07e4L },\n      { 0x516bb6d2b8f5432cL,0x210dc1cbe043444bL,0x3db01e6ff8f95b5aL,\n        0xb623ad0e0a7dd198L } },\n    /* 123 */\n    { { 0xa75bd67560c7b65bL,0xab8c559023a4a289L,0xf8220fd0d7b26795L,\n        0xd6aa2e4658ec137bL },\n      { 0x10abc00b5138bb85L,0x8c31d121d833a95cL,0xb24ff00b1702a32eL,\n        0x111662e02dcc513aL } },\n    /* 124 */\n    { { 0x78114015efb42b87L,0xbd9f5d701b6c4dffL,0x66ecccd7a7d7c129L,\n        0xdb3ee1cb94b750f8L },\n      { 0xb26f3db0f34837cfL,0xe7eed18bb9578d4fL,0x5d2cdf937c56657dL,\n        0x886a644252206a59L } },\n    /* 125 */\n    { { 0x3c234cfb65b569eaL,0x20011141f72119c1L,0x8badc85da15a619eL,\n        0xa70cf4eb018a17bcL },\n      { 0x224f97ae8c4a6a65L,0x36e5cf270134378fL,0xbe3a609e4f7e0960L,\n        0xaa4772abd1747b77L } },\n    /* 126 */\n    { { 0x676761317aa60cc0L,0xc79163610368115fL,0xded98bb4bbc1bb5aL,\n        0x611a6ddc30faf974L },\n      { 0x30e78cbcc15ee47aL,0x2e8962824e0d96a5L,0x36f35adf3dd9ed88L,\n        0x5cfffaf816429c88L } },\n    /* 127 */\n    { { 0xc0d54cff9b7a99cdL,0x7bf3b99d843c45a1L,0x038a908f62c739e1L,\n        0x6e5a6b237dc1994cL },\n      { 0xef8b454e0ba5db77L,0xb7b8807facf60d63L,0xe591c0c676608378L,\n        0x481a238d242dabccL } },\n    /* 128 */\n    { { 0xe3417bc035d0b34aL,0x440b386b8327c0a7L,0x8fb7262dac0362d1L,\n        0x2c41114ce0cdf943L },\n      { 0x2ba5cef1ad95a0b1L,0xc09b37a867d54362L,0x26d6cdd201e486c9L,\n        0x20477abf42ff9297L } },\n    /* 129 */\n    { { 0x2f75173c18d65dbfL,0x77bf940e339edad8L,0x7022d26bdcf1001cL,\n        0xac66409ac77396b6L },\n      { 0x8b0bb36fc6261cc3L,0x213f7bc9190e7e90L,0x6541cebaa45e6c10L,\n        0xce8e6975cc122f85L } },\n    /* 130 */\n    { { 0x0f121b41bc0a67d2L,0x62d4760a444d248aL,0x0e044f1d659b4737L,\n        0x08fde365250bb4a8L },\n      { 0xaceec3da848bf287L,0xc2a62182d3369d6eL,0x3582dfdc92449482L,\n        0x2f7e2fd2565d6cd7L } },\n    /* 131 */\n    { { 0xae4b92dbc3770fa7L,0x095e8d5c379043f9L,0x54f34e9d17761171L,\n        0xc65be92e907702aeL },\n      { 0x2758a303f6fd0a40L,0xe7d822e3bcce784bL,0x7ae4f5854f9767bfL,\n        0x4bff8e47d1193b3aL } },\n    /* 132 */\n    { { 0xcd41d21f00ff1480L,0x2ab8fb7d0754db16L,0xac81d2efbbe0f3eaL,\n        0x3e4e4ae65772967dL },\n      { 0x7e18f36d3c5303e6L,0x3bd9994b92262397L,0x9ed70e261324c3c0L,\n        0x5388aefd58ec6028L } },\n    /* 133 */\n    { { 0xad1317eb5e5d7713L,0x09b985ee75de49daL,0x32f5bc4fc74fb261L,\n        0x5cf908d14f75be0eL },\n      { 0x760435108e657b12L,0xbfd421a5b96ed9e6L,0x0e29f51f8970ccc2L,\n        0xa698ba4060f00ce2L } },\n    /* 134 */\n    { { 0x73db1686ef748fecL,0xe6e755a27e9d2cf9L,0x630b6544ce265effL,\n        0xb142ef8a7aebad8dL },\n      { 0xad31af9f17d5770aL,0x66af3b672cb3412fL,0x6bd60d1bdf3359deL,\n        0xd1896a9658515075L } },\n    /* 135 */\n    { { 0xec5957ab33c41c08L,0x87de94ac5468e2e1L,0x18816b73ac472f6cL,\n        0x267b0e0b7981da39L },\n      { 0x6e554e5d8e62b988L,0xd8ddc755116d21e7L,0x4610faf03d2a6f99L,\n        0xb54e287aa1119393L } },\n    /* 136 */\n    { { 0x0a0122b5178a876bL,0x51ff96ff085104b4L,0x050b31ab14f29f76L,\n        0x84abb28b5f87d4e6L },\n      { 0xd5ed439f8270790aL,0x2d6cb59d85e3f46bL,0x75f55c1b6c1e2212L,\n        0xe5436f6717655640L } },\n    /* 137 */\n    { { 0x53f9025e2286e8d5L,0x353c95b4864453beL,0xd832f5bde408e3a0L,\n        0x0404f68b5b9ce99eL },\n      { 0xcad33bdea781e8e5L,0x3cdf5018163c2f5bL,0x575769600119caa3L,\n        0x3a4263df0ac1c701L } },\n    /* 138 */\n    { { 0xc2965ecc9aeb596dL,0x01ea03e7023c92b4L,0x4704b4b62e013961L,\n        0x0ca8fd3f905ea367L },\n      { 0x92523a42551b2b61L,0x1eb7a89c390fcd06L,0xe7f1d2be0392a63eL,\n        0x96dca2644ddb0c33L } },\n    /* 139 */\n    { { 0x203bb43a387510afL,0x846feaa8a9a36a01L,0xd23a57702f950378L,\n        0x4363e2123aad59dcL },\n      { 0xca43a1c740246a47L,0xb362b8d2e55dd24dL,0xf9b086045d8faf96L,\n        0x840e115cd8bb98c4L } },\n    /* 140 */\n    { { 0xf12205e21023e8a7L,0xc808a8cdd8dc7a0bL,0xe292a272163a5ddfL,\n        0x5e0d6abd30ded6d4L },\n      { 0x07a721c27cfc0f64L,0x42eec01d0e55ed88L,0x26a7bef91d1f9db2L,\n        0x7dea48f42945a25aL } },\n    /* 141 */\n    { { 0xabdf6f1ce5060a81L,0xe79f9c72f8f95615L,0xcfd36c5406ac268bL,\n        0xabc2a2beebfd16d1L },\n      { 0x8ac66f91d3e2eac7L,0x6f10ba63d2dd0466L,0x6790e3770282d31bL,\n        0x4ea353946c7eefc1L } },\n    /* 142 */\n    { { 0xed8a2f8d5266309dL,0x0a51c6c081945a3eL,0xcecaf45a578c5dc1L,\n        0x3a76e6891c94ffc3L },\n      { 0x9aace8a47d7b0d0fL,0x963ace968f584a5fL,0x51a30c724e697fbeL,\n        0x8212a10a465e6464L } },\n    /* 143 */\n    { { 0xef7c61c3cfab8caaL,0x18eb8e840e142390L,0xcd1dff677e9733caL,\n        0xaa7cab71599cb164L },\n      { 0x02fc9273bc837bd1L,0xc06407d0c36af5d7L,0x17621292f423da49L,\n        0x40e38073fe0617c3L } },\n    /* 144 */\n    { { 0xf4f80824a7bf9b7cL,0x365d23203fbe30d0L,0xbfbe532097cf9ce3L,\n        0xe3604700b3055526L },\n      { 0x4dcb99116cc6c2c7L,0x72683708ba4cbee6L,0xdcded434637ad9ecL,\n        0x6542d677a3dee15fL } },\n    /* 145 */\n    { { 0x3f32b6d07b6c377aL,0x6cb03847903448beL,0xd6fdd3a820da8af7L,\n        0xa6534aee09bb6f21L },\n      { 0x30a1780d1035facfL,0x35e55a339dcb47e6L,0x6ea50fe1c447f393L,\n        0xf3cb672fdc9aef22L } },\n    /* 146 */\n    { { 0xeb3719fe3b55fd83L,0xe0d7a46c875ddd10L,0x33ac9fa905cea784L,\n        0x7cafaa2eaae870e7L },\n      { 0x9b814d041d53b338L,0xe0acc0a0ef87e6c6L,0xfb93d10811672b0fL,\n        0x0aab13c1b9bd522eL } },\n    /* 147 */\n    { { 0xddcce278d2681297L,0xcb350eb1b509546aL,0x2dc431737661aaf2L,\n        0x4b91a602847012e9L },\n      { 0xdcff109572f8ddcfL,0x08ebf61e9a911af4L,0x48f4360ac372430eL,\n        0x49534c5372321cabL } },\n    /* 148 */\n    { { 0x83df7d71f07b7e9dL,0xa478efa313cd516fL,0x78ef264b6c047ee3L,\n        0xcaf46c4fd65ac5eeL },\n      { 0xa04d0c7792aa8266L,0xedf45466913684bbL,0x56e65168ae4b16b0L,\n        0x14ce9e5704c6770fL } },\n    /* 149 */\n    { { 0x99445e3e965e8f91L,0xd3aca1bacb0f2492L,0xd31cc70f90c8a0a0L,\n        0x1bb708a53e4c9a71L },\n      { 0xd5ca9e69558bdd7aL,0x734a0508018a26b1L,0xb093aa714c9cf1ecL,\n        0xf9d126f2da300102L } },\n    /* 150 */\n    { { 0x749bca7aaff9563eL,0xdd077afeb49914a0L,0xe27a0311bf5f1671L,\n        0x807afcb9729ecc69L },\n      { 0x7f8a9337c9b08b77L,0x86c3a785443c7e38L,0x85fafa59476fd8baL,\n        0x751adcd16568cd8cL } },\n    /* 151 */\n    { { 0x8aea38b410715c0dL,0xd113ea718f7697f7L,0x665eab1493fbf06dL,\n        0x29ec44682537743fL },\n      { 0x3d94719cb50bebbcL,0x399ee5bfe4505422L,0x90cd5b3a8d2dedb1L,\n        0xff9370e392a4077dL } },\n    /* 152 */\n    { { 0x59a2d69bc6b75b65L,0x4188f8d5266651c5L,0x28a9f33e3de9d7d2L,\n        0x9776478ba2a9d01aL },\n      { 0x8852622d929af2c7L,0x334f5d6d4e690923L,0xce6cc7e5a89a51e9L,\n        0x74a6313fac2f82faL } },\n    /* 153 */\n    { { 0xb2f4dfddb75f079cL,0x85b07c9518e36fbbL,0x1b6cfcf0e7cd36ddL,\n        0xab75be150ff4863dL },\n      { 0x81b367c0173fc9b7L,0xb90a7420d2594fd0L,0x15fdbf03c4091236L,\n        0x4ebeac2e0b4459f6L } },\n    /* 154 */\n    { { 0xeb6c5fe75c9f2c53L,0xd25220118eae9411L,0xc8887633f95ac5d8L,\n        0xdf99887b2c1baffcL },\n      { 0xbb78eed2850aaecbL,0x9d49181b01d6a272L,0x978dd511b1cdbcacL,\n        0x27b040a7779f4058L } },\n    /* 155 */\n    { { 0x90405db7f73b2eb2L,0xe0df85088e1b2118L,0x501b71525962327eL,\n        0xb393dd37e4cfa3f5L },\n      { 0xa1230e7b3fd75165L,0xd66344c2bcd33554L,0x6c36f1be0f7b5022L,\n        0x09588c12d0463419L } },\n    /* 156 */\n    { { 0xe086093f02601c3bL,0xfb0252f8cf5c335fL,0x955cf280894aff28L,\n        0x81c879a9db9f648bL },\n      { 0x040e687cc6f56c51L,0xfed471693f17618cL,0x44f88a419059353bL,\n        0xfa0d48f55fc11bc4L } },\n    /* 157 */\n    { { 0xbc6e1c9de1608e4dL,0x010dda113582822cL,0xf6b7ddc1157ec2d7L,\n        0x8ea0e156b6a367d6L },\n      { 0xa354e02f2383b3b4L,0x69966b943f01f53cL,0x4ff6632b2de03ca5L,\n        0x3f5ab924fa00b5acL } },\n    /* 158 */\n    { { 0x337bb0d959739efbL,0xc751b0f4e7ebec0dL,0x2da52dd6411a67d1L,\n        0x8bc768872b74256eL },\n      { 0xa5be3b7282d3d253L,0xa9f679a1f58d779fL,0xa1cac168e16767bbL,\n        0xb386f19060fcf34fL } },\n    /* 159 */\n    { { 0x31f3c1352fedcfc2L,0x5396bf6262f8af0dL,0x9a02b4eae57288c2L,\n        0x4cb460f71b069c4dL },\n      { 0xae67b4d35b8095eaL,0x92bbf8596fc07603L,0xe1475f66b614a165L,\n        0x52c0d50895ef5223L } },\n    /* 160 */\n    { { 0x231c210e15339848L,0xe87a28e870778c8dL,0x9d1de6616956e170L,\n        0x4ac3c9382bb09c0bL },\n      { 0x19be05516998987dL,0x8b2376c4ae09f4d6L,0x1de0b7651a3f933dL,\n        0x380d94c7e39705f4L } },\n    /* 161 */\n    { { 0x01a355aa81542e75L,0x96c724a1ee01b9b7L,0x6b3a2977624d7087L,\n        0x2ce3e171de2637afL },\n      { 0xcfefeb49f5d5bc1aL,0xa655607e2777e2b5L,0x4feaac2f9513756cL,\n        0x2e6cd8520b624e4dL } },\n    /* 162 */\n    { { 0x3685954b8c31c31dL,0x68533d005bf21a0cL,0x0bd7626e75c79ec9L,\n        0xca17754742c69d54L },\n      { 0xcc6edafff6d2dbb2L,0xfd0d8cbd174a9d18L,0x875e8793aa4578e8L,\n        0xa976a7139cab2ce6L } },\n    /* 163 */\n    { { 0x0a651f1b93fb353dL,0xd75cab8b57fcfa72L,0xaa88cfa731b15281L,\n        0x8720a7170a1f4999L },\n      { 0x8c3e8d37693e1b90L,0xd345dc0b16f6dfc3L,0x8ea8d00ab52a8742L,\n        0x9719ef29c769893cL } },\n    /* 164 */\n    { { 0x820eed8d58e35909L,0x9366d8dc33ddc116L,0xd7f999d06e205026L,\n        0xa5072976e15704c1L },\n      { 0x002a37eac4e70b2eL,0x84dcf6576890aa8aL,0xcd71bf18645b2a5cL,\n        0x99389c9df7b77725L } },\n    /* 165 */\n    { { 0x238c08f27ada7a4bL,0x3abe9d03fd389366L,0x6b672e89766f512cL,\n        0xa88806aa202c82e4L },\n      { 0x6602044ad380184eL,0xa8cb78c4126a8b85L,0x79d670c0ad844f17L,\n        0x0043bffb4738dcfeL } },\n    /* 166 */\n    { { 0x8d59b5dc36d5192eL,0xacf885d34590b2afL,0x83566d0a11601781L,\n        0x52f3ef01ba6c4866L },\n      { 0x3986732a0edcb64dL,0x0a482c238068379fL,0x16cbe5fa7040f309L,\n        0x3296bd899ef27e75L } },\n    /* 167 */\n    { { 0x476aba89454d81d7L,0x9eade7ef51eb9b3cL,0x619a21cd81c57986L,\n        0x3b90febfaee571e9L },\n      { 0x9393023e5496f7cbL,0x55be41d87fb51bc4L,0x03f1dd4899beb5ceL,\n        0x6e88069d9f810b18L } },\n    /* 168 */\n    { { 0xce37ab11b43ea1dbL,0x0a7ff1a95259d292L,0x851b02218f84f186L,\n        0xa7222beadefaad13L },\n      { 0xa2ac78ec2b0a9144L,0x5a024051f2fa59c5L,0x91d1eca56147ce38L,\n        0xbe94d523bc2ac690L } },\n    /* 169 */\n    { { 0x72f4945e0b226ce7L,0xb8afd747967e8b70L,0xedea46f185a6c63eL,\n        0x7782defe9be8c766L },\n      { 0x760d2aa43db38626L,0x460ae78776f67ad1L,0x341b86fc54499cdbL,\n        0x03838567a2892e4bL } },\n    /* 170 */\n    { { 0x2d8daefd79ec1a0fL,0x3bbcd6fdceb39c97L,0xf5575ffc58f61a95L,\n        0xdbd986c4adf7b420L },\n      { 0x81aa881415f39eb7L,0x6ee2fcf5b98d976cL,0x5465475dcf2f717dL,\n        0x8e24d3c46860bbd0L } },\n    /* 171 */\n    { { 0x749d8e549a587390L,0x12bb194f0cbec588L,0x46e07da4b25983c6L,\n        0x541a99c4407bafc8L },\n      { 0xdb241692624c8842L,0x6044c12ad86c05ffL,0xc59d14b44f7fcf62L,\n        0xc0092c49f57d35d1L } },\n    /* 172 */\n    { { 0xd3cc75c3df2e61efL,0x7e8841c82e1b35caL,0xc62d30d1909f29f4L,\n        0x75e406347286944dL },\n      { 0xe7d41fc5bbc237d0L,0xc9537bf0ec4f01c9L,0x91c51a16282bd534L,\n        0x5b7cb658c7848586L } },\n    /* 173 */\n    { { 0x964a70848a28ead1L,0x802dc508fd3b47f6L,0x9ae4bfd1767e5b39L,\n        0x7ae13eba8df097a1L },\n      { 0xfd216ef8eadd384eL,0x0361a2d9b6b2ff06L,0x204b98784bcdb5f3L,\n        0x787d8074e2a8e3fdL } },\n    /* 174 */\n    { { 0xc5e25d6b757fbb1cL,0xe47bddb2ca201debL,0x4a55e9a36d2233ffL,\n        0x5c2228199ef28484L },\n      { 0x773d4a8588315250L,0x21b21a2b827097c1L,0xab7c4ea1def5d33fL,\n        0xe45d37abbaf0f2b0L } },\n    /* 175 */\n    { { 0xd2df1e3428511c8aL,0xebb229c8bdca6cd3L,0x578a71a7627c39a7L,\n        0xed7bc12284dfb9d3L },\n      { 0xcf22a6df93dea561L,0x5443f18dd48f0ed1L,0xd8b861405bad23e8L,\n        0xaac97cc945ca6d27L } },\n    /* 176 */\n    { { 0xeb54ea74a16bd00aL,0xd839e9adf5c0bcc1L,0x092bb7f11f9bfc06L,\n        0x318f97b31163dc4eL },\n      { 0xecc0c5bec30d7138L,0x44e8df23abc30220L,0x2bb7972fb0223606L,\n        0xfa41faa19a84ff4dL } },\n    /* 177 */\n    { { 0x4402d974a6642269L,0xc81814ce9bb783bdL,0x398d38e47941e60bL,\n        0x38bb6b2c1d26e9e2L },\n      { 0xc64e4a256a577f87L,0x8b52d253dc11fe1cL,0xff336abf62280728L,\n        0x94dd0905ce7601a5L } },\n    /* 178 */\n    { { 0x156cf7dcde93f92aL,0xa01333cb89b5f315L,0x02404df9c995e750L,\n        0x92077867d25c2ae9L },\n      { 0xe2471e010bf39d44L,0x5f2c902096bb53d7L,0x4c44b7b35c9c3d8fL,\n        0x81e8428bd29beb51L } },\n    /* 179 */\n    { { 0x6dd9c2bac477199fL,0x8cb8eeee6b5ecdd9L,0x8af7db3fee40fd0eL,\n        0x1b94ab62dbbfa4b1L },\n      { 0x44f0d8b3ce47f143L,0x51e623fc63f46163L,0xf18f270fcc599383L,\n        0x06a38e28055590eeL } },\n    /* 180 */\n    { { 0x2e5b0139b3355b49L,0x20e26560b4ebf99bL,0xc08ffa6bd269f3dcL,\n        0xa7b36c2083d9d4f8L },\n      { 0x64d15c3a1b3e8830L,0xd5fceae1a89f9c0bL,0xcfeee4a2e2d16930L,\n        0xbe54c6b4a2822a20L } },\n    /* 181 */\n    { { 0xd6cdb3df8d91167cL,0x517c3f79e7a6625eL,0x7105648f346ac7f4L,\n        0xbf30a5abeae022bbL },\n      { 0x8e7785be93828a68L,0x5161c3327f3ef036L,0xe11b5feb592146b2L,\n        0xd1c820de2732d13aL } },\n    /* 182 */\n    { { 0x043e13479038b363L,0x58c11f546b05e519L,0x4fe57abe6026cad1L,\n        0xb7d17bed68a18da3L },\n      { 0x44ca5891e29c2559L,0x4f7a03765bfffd84L,0x498de4af74e46948L,\n        0x3997fd5e6412cc64L } },\n    /* 183 */\n    { { 0xf20746828bd61507L,0x29e132d534a64d2aL,0xffeddfb08a8a15e3L,\n        0x0eeb89293c6c13e8L },\n      { 0xe9b69a3ea7e259f8L,0xce1db7e6d13e7e67L,0x277318f6ad1fa685L,\n        0x228916f8c922b6efL } },\n    /* 184 */\n    { { 0x959ae25b0a12ab5bL,0xcc11171f957bc136L,0x8058429ed16e2b0cL,\n        0xec05ad1d6e93097eL },\n      { 0x157ba5beac3f3708L,0x31baf93530b59d77L,0x47b55237118234e5L,\n        0x7d3141567ff11b37L } },\n    /* 185 */\n    { { 0x7bd9c05cf6dfefabL,0xbe2f2268dcb37707L,0xe53ead973a38bb95L,\n        0xe9ce66fc9bc1d7a3L },\n      { 0x75aa15766f6a02a1L,0x38c087df60e600edL,0xf8947f3468cdc1b9L,\n        0xd9650b0172280651L } },\n    /* 186 */\n    { { 0x504b4c4a5a057e60L,0xcbccc3be8def25e4L,0xa635320817c1ccbdL,\n        0x14d6699a804eb7a2L },\n      { 0x2c8a8415db1f411aL,0x09fbaf0bf80d769cL,0xb4deef901c2f77adL,\n        0x6f4c68410d43598aL } },\n    /* 187 */\n    { { 0x8726df4e96c24a96L,0x534dbc85fcbd99a3L,0x3c466ef28b2ae30aL,\n        0x4c4350fd61189abbL },\n      { 0x2967f716f855b8daL,0x41a42394463c38a1L,0xc37e1413eae93343L,\n        0xa726d2425a3118b5L } },\n    /* 188 */\n    { { 0xdae6b3ee948c1086L,0xf1de503dcbd3a2e1L,0x3f35ed3f03d022f3L,\n        0x13639e82cc6cf392L },\n      { 0x9ac938fbcdafaa86L,0xf45bc5fb2654a258L,0x1963b26e45051329L,\n        0xca9365e1c1a335a3L } },\n    /* 189 */\n    { { 0x3615ac754c3b2d20L,0x742a5417904e241bL,0xb08521c4cc9d071dL,\n        0x9ce29c34970b72a5L },\n      { 0x8cc81f736d3e0ad6L,0x8060da9ef2f8434cL,0x35ed1d1a6ce862d9L,\n        0x48c4abd7ab42af98L } },\n    /* 190 */\n    { { 0xd221b0cc40c7485aL,0xead455bbe5274dbfL,0x493c76989263d2e8L,\n        0x78017c32f67b33cbL },\n      { 0xb9d35769930cb5eeL,0xc0d14e940c408ed2L,0xf8b7bf55272f1a4dL,\n        0x53cd0454de5c1c04L } },\n    /* 191 */\n    { { 0xbcd585fa5d28ccacL,0x5f823e56005b746eL,0x7c79f0a1cd0123aaL,\n        0xeea465c1d3d7fa8fL },\n      { 0x7810659f0551803bL,0x6c0b599f7ce6af70L,0x4195a77029288e70L,\n        0x1b6e42a47ae69193L } },\n    /* 192 */\n    { { 0x2e80937cf67d04c3L,0x1e312be289eeb811L,0x56b5d88792594d60L,\n        0x0224da14187fbd3dL },\n      { 0x87abb8630c5fe36fL,0x580f3c604ef51f5fL,0x964fb1bfb3b429ecL,\n        0x60838ef042bfff33L } },\n    /* 193 */\n    { { 0x432cb2f27e0bbe99L,0x7bda44f304aa39eeL,0x5f497c7a9fa93903L,\n        0x636eb2022d331643L },\n      { 0xfcfd0e6193ae00aaL,0x875a00fe31ae6d2fL,0xf43658a29f93901cL,\n        0x8844eeb639218bacL } },\n    /* 194 */\n    { { 0x114171d26b3bae58L,0x7db3df7117e39f3eL,0xcd37bc7f81a8eadaL,\n        0x27ba83dc51fb789eL },\n      { 0xa7df439ffbf54de5L,0x7277030bb5fe1a71L,0x42ee8e35db297a48L,\n        0xadb62d3487f3a4abL } },\n    /* 195 */\n    { { 0x9b1168a2a175df2aL,0x082aa04f618c32e9L,0xc9e4f2e7146b0916L,\n        0xb990fd7675e7c8b2L },\n      { 0x0829d96b4df37313L,0x1c205579d0b40789L,0x66c9ae4a78087711L,\n        0x81707ef94d10d18dL } },\n    /* 196 */\n    { { 0x97d7cab203d6ff96L,0x5b851bfc0d843360L,0x268823c4d042db4bL,\n        0x3792daead5a8aa5cL },\n      { 0x52818865941afa0bL,0xf3e9e74142d83671L,0x17c825275be4e0a7L,\n        0x5abd635e94b001baL } },\n    /* 197 */\n    { { 0x727fa84e0ac4927cL,0xe3886035a7c8cf23L,0xa4bcd5ea4adca0dfL,\n        0x5995bf21846ab610L },\n      { 0xe90f860b829dfa33L,0xcaafe2ae958fc18bL,0x9b3baf4478630366L,\n        0x44c32ca2d483411eL } },\n    /* 198 */\n    { { 0xa74a97f1e40ed80cL,0x5f938cb131d2ca82L,0x53f2124b7c2d6ad9L,\n        0x1f2162fb8082a54cL },\n      { 0x7e467cc5720b173eL,0x40e8a666085f12f9L,0x8cebc20e4c9d65dcL,\n        0x8f1d402bc3e907c9L } },\n    /* 199 */\n    { { 0x4f592f9cfbc4058aL,0xb15e14b6292f5670L,0xc55cfe37bc1d8c57L,\n        0xb1980f43926edbf9L },\n      { 0x98c33e0932c76b09L,0x1df5279d33b07f78L,0x6f08ead4863bb461L,\n        0x2828ad9b37448e45L } },\n    /* 200 */\n    { { 0x696722c4c4cf4ac5L,0xf5ac1a3fdde64afbL,0x0551baa2e0890832L,\n        0x4973f1275a14b390L },\n      { 0xe59d8335322eac5dL,0x5e07eef50bd9b568L,0xab36720fa2588393L,\n        0x6dac8ed0db168ac7L } },\n    /* 201 */\n    { { 0xf7b545aeeda835efL,0x4aa113d21d10ed51L,0x035a65e013741b09L,\n        0x4b23ef5920b9de4cL },\n      { 0xe82bb6803c4c7341L,0xd457706d3f58bc37L,0x73527863a51e3ee8L,\n        0x4dd71534ddf49a4eL } },\n    /* 202 */\n    { { 0xbf94467295476cd9L,0x648d072fe31a725bL,0x1441c8b8fc4b67e0L,\n        0xfd3170002f4a4dbbL },\n      { 0x1cb43ff48995d0e1L,0x76e695d10ef729aaL,0xe0d5f97641798982L,\n        0x14fac58c9569f365L } },\n    /* 203 */\n    { { 0xad9a0065f312ae18L,0x51958dc0fcc93fc9L,0xd9a142408a7d2846L,\n        0xed7c765136abda50L },\n      { 0x46270f1a25d4abbcL,0x9b5dd8f3f1a113eaL,0xc609b0755b51952fL,\n        0xfefcb7f74d2e9f53L } },\n    /* 204 */\n    { { 0xbd09497aba119185L,0xd54e8c30aac45ba4L,0x492479deaa521179L,\n        0x1801a57e87e0d80bL },\n      { 0x073d3f8dfcafffb0L,0x6cf33c0bae255240L,0x781d763b5b5fdfbcL,\n        0x9f8fc11e1ead1064L } },\n    /* 205 */\n    { { 0x1583a1715e69544cL,0x0eaf8567f04b7813L,0x1e22a8fd278a4c32L,\n        0xa9d3809d3d3a69a9L },\n      { 0x936c2c2c59a2da3bL,0x38ccbcf61895c847L,0x5e65244e63d50869L,\n        0x3006b9aee1178ef7L } },\n    /* 206 */\n    { { 0x0bb1f2b0c9eead28L,0x7eef635d89f4dfbcL,0x074757fdb2ce8939L,\n        0x0ab85fd745f8f761L },\n      { 0xecda7c933e5b4549L,0x4be2bb5c97922f21L,0x261a1274b43b8040L,\n        0xb122d67511e942c2L } },\n    /* 207 */\n    { { 0x3be607be66a5ae7aL,0x01e703fa76adcbe3L,0xaf9043014eb6e5c5L,\n        0x9f599dc1097dbaecL },\n      { 0x6d75b7180ff250edL,0x8eb91574349a20dcL,0x425605a410b227a3L,\n        0x7d5528e08a294b78L } },\n    /* 208 */\n    { { 0xf0f58f6620c26defL,0x025585ea582b2d1eL,0xfbe7d79b01ce3881L,\n        0x28ccea01303f1730L },\n      { 0xd1dabcd179644ba5L,0x1fc643e806fff0b8L,0xa60a76fc66b3e17bL,\n        0xc18baf48a1d013bfL } },\n    /* 209 */\n    { { 0x34e638c85dc4216dL,0x00c01067206142acL,0xd453a17195f5064aL,\n        0x9def809db7a9596bL },\n      { 0x41e8642e67ab8d2cL,0xb42404336237a2b6L,0x7d506a6d64c4218bL,\n        0x0357f8b068808ce5L } },\n    /* 210 */\n    { { 0x8e9dbe644cd2cc88L,0xcc61c28df0b8f39dL,0x4a309874cd30a0c8L,\n        0xe4a01add1b489887L },\n      { 0x2ed1eeacf57cd8f9L,0x1b767d3ebd594c48L,0xa7295c717bd2f787L,\n        0x466d7d79ce10cc30L } },\n    /* 211 */\n    { { 0x47d318929dada2c7L,0x4fa0a6c38f9aa27dL,0x90e4fd28820a59e1L,\n        0xc672a522451ead1aL },\n      { 0x30607cc85d86b655L,0xf0235d3bf9ad4af1L,0x99a08680571172a6L,\n        0x5e3d64faf2a67513L } },\n    /* 212 */\n    { { 0xaa6410c79b3b4416L,0xcd8fcf85eab26d99L,0x5ebff74adb656a74L,\n        0x6c8a7a95eb8e42fcL },\n      { 0x10c60ba7b02a63bdL,0x6b2f23038b8f0047L,0x8c6c3738312d90b0L,\n        0x348ae422ad82ca91L } },\n    /* 213 */\n    { { 0x7f4746635ccda2fbL,0x22accaa18e0726d2L,0x85adf782492b1f20L,\n        0xc1074de0d9ef2d2eL },\n      { 0xfcf3ce44ae9a65b3L,0xfd71e4ac05d7151bL,0xd4711f50ce6a9788L,\n        0xfbadfbdbc9e54ffcL } },\n    /* 214 */\n    { { 0x1713f1cd20a99363L,0xb915658f6cf22775L,0x968175cd24d359b2L,\n        0xb7f976b483716fcdL },\n      { 0x5758e24d5d6dbf74L,0x8d23bafd71c3af36L,0x48f477600243dfe3L,\n        0xf4d41b2ecafcc805L } },\n    /* 215 */\n    { { 0x51f1cf28fdabd48dL,0xce81be3632c078a4L,0x6ace2974117146e9L,\n        0x180824eae0160f10L },\n      { 0x0387698b66e58358L,0x63568752ce6ca358L,0x82380e345e41e6c5L,\n        0x67e5f63983cf6d25L } },\n    /* 216 */\n    { { 0xf89ccb8dcf4899efL,0x949015f09ebb44c0L,0x546f9276b2598ec9L,\n        0x9fef789a04c11fc6L },\n      { 0x6d367ecf53d2a071L,0xb10e1a7fa4519b09L,0xca6b3fb0611e2eefL,\n        0xbc80c181a99c4e20L } },\n    /* 217 */\n    { { 0x972536f8e5eb82e6L,0x1a484fc7f56cb920L,0xc78e217150b5da5eL,\n        0x49270e629f8cdf10L },\n      { 0x1a39b7bbea6b50adL,0x9a0284c1a2388ffcL,0x5403eb178107197bL,\n        0xd2ee52f961372f7fL } },\n    /* 218 */\n    { { 0xd37cd28588e0362aL,0x442fa8a78fa5d94dL,0xaff836e5a434a526L,\n        0xdfb478bee5abb733L },\n      { 0xa91f1ce7673eede6L,0xa5390ad42b5b2f04L,0x5e66f7bf5530da2fL,\n        0xd9a140b408df473aL } },\n    /* 219 */\n    { { 0x0e0221b56e8ea498L,0x623478293563ee09L,0xe06b8391335d2adeL,\n        0x760c058d623f4b1aL },\n      { 0x0b89b58cc198aa79L,0xf74890d2f07aba7fL,0x4e204110fde2556aL,\n        0x7141982d8f190409L } },\n    /* 220 */\n    { { 0x6f0a0e334d4b0f45L,0xd9280b38392a94e1L,0x3af324c6b3c61d5eL,\n        0x3af9d1ce89d54e47L },\n      { 0xfd8f798120930371L,0xeda2664c21c17097L,0x0e9545dcdc42309bL,\n        0xb1f815c373957dd6L } },\n    /* 221 */\n    { { 0x84faa78e89fec44aL,0xc8c2ae473caa4cafL,0x691c807dc1b6a624L,\n        0xa41aed141543f052L },\n      { 0x424353997d5ffe04L,0x8bacb2df625b6e20L,0x85d660be87817775L,\n        0xd6e9c1dd86fb60efL } },\n    /* 222 */\n    { { 0x3aa2e97ec6853264L,0x771533b7e2304a0bL,0x1b912bb7b8eae9beL,\n        0x9c9c6e10ae9bf8c2L },\n      { 0xa2309a59e030b74cL,0x4ed7494d6a631e90L,0x89f44b23a49b79f2L,\n        0x566bd59640fa61b6L } },\n    /* 223 */\n    { { 0x066c0118c18061f3L,0x190b25d37c83fc70L,0xf05fc8e027273245L,\n        0xcf2c7390f525345eL },\n      { 0xa09bceb410eb30cfL,0xcfd2ebba0d77703aL,0xe842c43a150ff255L,\n        0x02f517558aa20979L } },\n    /* 224 */\n    { { 0x396ef794addb7d07L,0x0b4fc74224455500L,0xfaff8eacc78aa3ceL,\n        0x14e9ada5e8d4d97dL },\n      { 0xdaa480a12f7079e2L,0x45baa3cde4b0800eL,0x01765e2d7838157dL,\n        0xa0ad4fab8e9d9ae8L } },\n    /* 225 */\n    { { 0x0bfb76214a653618L,0x1872813c31eaaa5fL,0x1553e73744949d5eL,\n        0xbcd530b86e56ed1eL },\n      { 0x169be85332e9c47bL,0xdc2776feb50059abL,0xcdba9761192bfbb4L,\n        0x909283cf6979341dL } },\n    /* 226 */\n    { { 0x67b0032476e81a13L,0x9bee1a9962171239L,0x08ed361bd32e19d6L,\n        0x35eeb7c9ace1549aL },\n      { 0x1280ae5a7e4e5bdcL,0x2dcd2cd3b6ceec6eL,0x52e4224c6e266bc1L,\n        0x9a8b2cf4448ae864L } },\n    /* 227 */\n    { { 0xf6471bf209d03b59L,0xc90e62a3b65af2abL,0xff7ff168ebd5eec9L,\n        0x6bdb60f4d4491379L },\n      { 0xdadafebc8a55bc30L,0xc79ead1610097fe0L,0x42e197414c1e3bddL,\n        0x01ec3cfd94ba08a9L } },\n    /* 228 */\n    { { 0xba6277ebdc9485c2L,0x48cc9a7922fb10c7L,0x4f61d60f70a28d8aL,\n        0xd1acb1c0475464f6L },\n      { 0xd26902b126f36612L,0x59c3a44ee0618d8bL,0x4df8a813308357eeL,\n        0x7dcd079d405626c2L } },\n    /* 229 */\n    { { 0x5ce7d4d3f05a4b48L,0xadcd295237230772L,0xd18f7971812a915aL,\n        0x0bf53589377d19b8L },\n      { 0x35ecd95a6c68ea73L,0xc7f3bbca823a584dL,0x9fb674c6f473a723L,\n        0xd28be4d9e16686fcL } },\n    /* 230 */\n    { { 0x5d2b990638fa8e4bL,0x559f186e893fd8fcL,0x3a6de2aa436fb6fcL,\n        0xd76007aa510f88ceL },\n      { 0x2d10aab6523a4988L,0xb455cf4474dd0273L,0x7f467082a3407278L,\n        0xf2b52f68b303bb01L } },\n    /* 231 */\n    { { 0x0d57eafa9835b4caL,0x2d2232fcbb669cbcL,0x8eeeb680c6643198L,\n        0xd8dbe98ecc5aed3aL },\n      { 0xcba9be3fc5a02709L,0x30be68e5f5ba1fa8L,0xfebd43cdf10ea852L,\n        0xe01593a3ee559705L } },\n    /* 232 */\n    { { 0xd3e5af50ea75a0a6L,0x512226ac57858033L,0x6fe6d50fd0176406L,\n        0xafec07b1aeb8ef06L },\n      { 0x7fb9956780bb0a31L,0x6f1af3cc37309aaeL,0x9153a15a01abf389L,\n        0xa71b93546e2dbfddL } },\n    /* 233 */\n    { { 0xbf8e12e018f593d2L,0xd1a90428a078122bL,0x150505db0ba4f2adL,\n        0x53a2005c628523d9L },\n      { 0x07c8b639e7f2b935L,0x2bff975ac182961aL,0x86bceea77518ca2cL,\n        0xbf47d19b3d588e3dL } },\n    /* 234 */\n    { { 0x672967a7dd7665d5L,0x4e3030572f2f4de5L,0x144005ae80d4903fL,\n        0x001c2c7f39c9a1b6L },\n      { 0x143a801469efc6d6L,0xc810bdaa7bc7a724L,0x5f65670ba78150a4L,\n        0xfdadf8e786ffb99bL } },\n    /* 235 */\n    { { 0xfd38cb88ffc00785L,0x77fa75913b48eb67L,0x0454d055bf368fbcL,\n        0x3a838e4d5aa43c94L },\n      { 0x561663293e97bb9aL,0x9eb93363441d94d9L,0x515591a60adb2a83L,\n        0x3cdb8257873e1da3L } },\n    /* 236 */\n    { { 0x137140a97de77eabL,0xf7e1c50d41648109L,0x762dcad2ceb1d0dfL,\n        0x5a60cc89f1f57fbaL },\n      { 0x80b3638240d45673L,0x1b82be195913c655L,0x057284b8dd64b741L,\n        0x922ff56fdbfd8fc0L } },\n    /* 237 */\n    { { 0x1b265deec9a129a1L,0xa5b1ce57cc284e04L,0x04380c46cebfbe3cL,\n        0x72919a7df6c5cd62L },\n      { 0x298f453a8fb90f9aL,0xd719c00b88e4031bL,0xe32c0e77796f1856L,\n        0x5e7917803624089aL } },\n    /* 238 */\n    { { 0x5c16ec557f63cdfbL,0x8e6a3571f1cae4fdL,0xfce26bea560597caL,\n        0x4e0a5371e24c2fabL },\n      { 0x276a40d3a5765357L,0x3c89af440d73a2b4L,0xb8f370ae41d11a32L,\n        0xf5ff7818d56604eeL } },\n    /* 239 */\n    { { 0xfbf3e3fe1a09df21L,0x26d5d28ee66e8e47L,0x2096bd0a29c89015L,\n        0xe41df0e9533f5e64L },\n      { 0x305fda40b3ba9e3fL,0xf2340ceb2604d895L,0x0866e1927f0367c7L,\n        0x8edd7d6eac4f155fL } },\n    /* 240 */\n    { { 0xc9a1dc0e0bfc8ff3L,0x14efd82be936f42fL,0x67016f7ccca381efL,\n        0x1432c1caed8aee96L },\n      { 0xec68482970b23c26L,0xa64fe8730735b273L,0xe389f6e5eaef0f5aL,\n        0xcaef480b5ac8d2c6L } },\n    /* 241 */\n    { { 0x5245c97875315922L,0xd82951713063cca5L,0xf3ce60d0b64ef2cbL,\n        0xd0ba177e8efae236L },\n      { 0x53a9ae8fb1b3af60L,0x1a796ae53d2da20eL,0x01d63605df9eef28L,\n        0xf31c957c1c54ae16L } },\n    /* 242 */\n    { { 0xc0f58d5249cc4597L,0xdc5015b0bae0a028L,0xefc5fc55734a814aL,\n        0x013404cb96e17c3aL },\n      { 0xb29e2585c9a824bfL,0xd593185e001eaed7L,0x8d6ee68261ef68acL,\n        0x6f377c4b91933e6cL } },\n    /* 243 */\n    { { 0x9f93bad1a8333fd2L,0xa89302025a2a95b8L,0x211e5037eaf75aceL,\n        0x6dba3e4ed2d09506L },\n      { 0xa48ef98cd04399cdL,0x1811c66ee6b73adeL,0x72f60752c17ecaf3L,\n        0xf13cf3423becf4a7L } },\n    /* 244 */\n    { { 0xceeb9ec0a919e2ebL,0x83a9a195f62c0f68L,0xcfba3bb67aba2299L,\n        0xc83fa9a9274bbad3L },\n      { 0x0d7d1b0b62fa1ce0L,0xe58b60f53418efbfL,0xbfa8ef9e52706f04L,\n        0xb49d70f45d702683L } },\n    /* 245 */\n    { { 0x914c7510fad5513bL,0x05f32eecb1751e2dL,0x6d850418d9fb9d59L,\n        0x59cfadbb0c30f1cfL },\n      { 0xe167ac2355cb7fd6L,0x249367b8820426a3L,0xeaeec58c90a78864L,\n        0x5babf362354a4b67L } },\n    /* 246 */\n    { { 0x37c981d1ee424865L,0x8b002878f2e5577fL,0x702970f1b9e0c058L,\n        0x6188c6a79026c8f0L },\n      { 0x06f9a19bd0f244daL,0x1ecced5cfb080873L,0x35470f9b9f213637L,\n        0x993fe475df50b9d9L } },\n    /* 247 */\n    { { 0x68e31cdf9b2c3609L,0x84eb19c02c46d4eaL,0x7ac9ec1a9a775101L,\n        0x81f764664c80616bL },\n      { 0x1d7c2a5a75fbe978L,0x6743fed3f183b356L,0x838d1f04501dd2bfL,\n        0x564a812a5fe9060dL } },\n    /* 248 */\n    { { 0x7a5a64f4fa817d1dL,0x55f96844bea82e0fL,0xb5ff5a0fcd57f9aaL,\n        0x226bf3cf00e51d6cL },\n      { 0xd6d1a9f92f2833cfL,0x20a0a35a4f4f89a8L,0x11536c498f3f7f77L,\n        0x68779f47ff257836L } },\n    /* 249 */\n    { { 0x79b0c1c173043d08L,0xa54467741fc020faL,0xd3767e289a6d26d0L,\n        0x97bcb0d1eb092e0bL },\n      { 0x2ab6eaa8f32ed3c3L,0xc8a4f151b281bc48L,0x4d1bf4f3bfa178f3L,\n        0xa872ffe80a784655L } },\n    /* 250 */\n    { { 0xb1ab7935a32b2086L,0xe1eb710e8160f486L,0x9bd0cd913b6ae6beL,\n        0x02812bfcb732a36aL },\n      { 0xa63fd7cacf605318L,0x646e5d50fdfd6d1dL,0xa1d683982102d619L,\n        0x07391cc9fe5396afL } },\n    /* 251 */\n    { { 0xc50157f08b80d02bL,0x6b8333d162877f7fL,0x7aca1af878d542aeL,\n        0x355d2adc7e6d2a08L },\n      { 0xb41f335a287386e1L,0xfd272a94f8e43275L,0x286ca2cde79989eaL,\n        0x3dc2b1e37c2a3a79L } },\n    /* 252 */\n    { { 0xd689d21c04581352L,0x0a00c825376782beL,0x203bd5909fed701fL,\n        0xc47869103ccd846bL },\n      { 0x5dba770824c768edL,0x72feea026841f657L,0x73313ed56accce0eL,\n        0xccc42968d5bb4d32L } },\n    /* 253 */\n    { { 0x94e50de13d7620b9L,0xd89a5c8a5992a56aL,0xdc007640675487c9L,\n        0xe147eb42aa4871cfL },\n      { 0x274ab4eeacf3ae46L,0xfd4936fb50350fbeL,0xdf2afe4748c840eaL,\n        0x239ac047080e96e3L } },\n    /* 254 */\n    { { 0x481d1f352bfee8d4L,0xce80b5cffa7b0fecL,0x105c4c9e2ce9af3cL,\n        0xc55fa1a3f5f7e59dL },\n      { 0x3186f14e8257c227L,0xc5b1653f342be00bL,0x09afc998aa904fb2L,\n        0x094cd99cd4f4b699L } },\n    /* 255 */\n    { { 0x8a981c84d703bebaL,0x8631d15032ceb291L,0xa445f2c9e3bd49ecL,\n        0xb90a30b642abad33L },\n      { 0xb465404fb4a5abf9L,0x004750c375db7603L,0x6f9a42ccca35d89fL,\n        0x019f8b9a1b7924f7L } },\n};\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_4(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_stripe_4(r, &p256_base, p256_table,\n                                      k, map, heap);\n}\n\n#ifdef HAVE_INTEL_AVX2\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_avx2_4(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_stripe_avx2_4(r, &p256_base, p256_table,\n                                      k, map, heap);\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n#else /* WOLFSSL_SP_SMALL */\n/* The index into pre-computation table to use. */\nstatic const uint8_t recode_index_4_7[130] = {\n     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,\n    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\n    64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,\n    48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,\n    32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,\n    16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,\n     0,  1,\n};\n\n/* Whether to negate y-ordinate. */\nstatic const uint8_t recode_neg_4_7[130] = {\n     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n     0,  0,\n};\n\n/* Recode the scalar for multiplication using pre-computed values and\n * subtraction.\n *\n * k  Scalar to multiply by.\n * v  Vector of operations to peform.\n */\nstatic void sp_256_ecc_recode_7_4(const sp_digit* k, ecc_recode* v)\n{\n    int i, j;\n    uint8_t y;\n    int carry = 0;\n    int o;\n    sp_digit n;\n\n    j = 0;\n    n = k[j];\n    o = 0;\n    for (i=0; i<37; i++) {\n        y = n;\n        if (o + 7 < 64) {\n            y &= 0x7f;\n            n >>= 7;\n            o += 7;\n        }\n        else if (o + 7 == 64) {\n            n >>= 7;\n            if (++j < 4)\n                n = k[j];\n            o = 0;\n        }\n        else if (++j < 4) {\n            n = k[j];\n            y |= (n << (64 - o)) & 0x7f;\n            o -= 57;\n            n >>= o;\n        }\n\n        y += carry;\n        v[i].i = recode_index_4_7[y];\n        v[i].neg = recode_neg_4_7[y];\n        carry = (y >> 7) + v[i].neg;\n    }\n}\n\nstatic const sp_table_entry p256_table[2405] = {\n    /* 0 << 0 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 0 */\n    { { 0x79e730d418a9143cL,0x75ba95fc5fedb601L,0x79fb732b77622510L,\n        0x18905f76a53755c6L },\n      { 0xddf25357ce95560aL,0x8b4ab8e4ba19e45cL,0xd2e88688dd21f325L,\n        0x8571ff1825885d85L } },\n    /* 2 << 0 */\n    { { 0x850046d410ddd64dL,0xaa6ae3c1a433827dL,0x732205038d1490d9L,\n        0xf6bb32e43dcf3a3bL },\n      { 0x2f3648d361bee1a5L,0x152cd7cbeb236ff8L,0x19a8fb0e92042dbeL,\n        0x78c577510a5b8a3bL } },\n    /* 3 << 0 */\n    { { 0xffac3f904eebc127L,0xb027f84a087d81fbL,0x66ad77dd87cbbc98L,\n        0x26936a3fb6ff747eL },\n      { 0xb04c5c1fc983a7ebL,0x583e47ad0861fe1aL,0x788208311a2ee98eL,\n        0xd5f06a29e587cc07L } },\n    /* 4 << 0 */\n    { { 0x74b0b50d46918dccL,0x4650a6edc623c173L,0x0cdaacace8100af2L,\n        0x577362f541b0176bL },\n      { 0x2d96f24ce4cbaba6L,0x17628471fad6f447L,0x6b6c36dee5ddd22eL,\n        0x84b14c394c5ab863L } },\n    /* 5 << 0 */\n    { { 0xbe1b8aaec45c61f5L,0x90ec649a94b9537dL,0x941cb5aad076c20cL,\n        0xc9079605890523c8L },\n      { 0xeb309b4ae7ba4f10L,0x73c568efe5eb882bL,0x3540a9877e7a1f68L,\n        0x73a076bb2dd1e916L } },\n    /* 6 << 0 */\n    { { 0x403947373e77664aL,0x55ae744f346cee3eL,0xd50a961a5b17a3adL,\n        0x13074b5954213673L },\n      { 0x93d36220d377e44bL,0x299c2b53adff14b5L,0xf424d44cef639f11L,\n        0xa4c9916d4a07f75fL } },\n    /* 7 << 0 */\n    { { 0x0746354ea0173b4fL,0x2bd20213d23c00f7L,0xf43eaab50c23bb08L,\n        0x13ba5119c3123e03L },\n      { 0x2847d0303f5b9d4dL,0x6742f2f25da67bddL,0xef933bdc77c94195L,\n        0xeaedd9156e240867L } },\n    /* 8 << 0 */\n    { { 0x27f14cd19499a78fL,0x462ab5c56f9b3455L,0x8f90f02af02cfc6bL,\n        0xb763891eb265230dL },\n      { 0xf59da3a9532d4977L,0x21e3327dcf9eba15L,0x123c7b84be60bbf0L,\n        0x56ec12f27706df76L } },\n    /* 9 << 0 */\n    { { 0x75c96e8f264e20e8L,0xabe6bfed59a7a841L,0x2cc09c0444c8eb00L,\n        0xe05b3080f0c4e16bL },\n      { 0x1eb7777aa45f3314L,0x56af7bedce5d45e3L,0x2b6e019a88b12f1aL,\n        0x086659cdfd835f9bL } },\n    /* 10 << 0 */\n    { { 0x2c18dbd19dc21ec8L,0x98f9868a0fcf8139L,0x737d2cd648250b49L,\n        0xcc61c94724b3428fL },\n      { 0x0c2b407880dd9e76L,0xc43a8991383fbe08L,0x5f7d2d65779be5d2L,\n        0x78719a54eb3b4ab5L } },\n    /* 11 << 0 */\n    { { 0xea7d260a6245e404L,0x9de407956e7fdfe0L,0x1ff3a4158dac1ab5L,\n        0x3e7090f1649c9073L },\n      { 0x1a7685612b944e88L,0x250f939ee57f61c8L,0x0c0daa891ead643dL,\n        0x68930023e125b88eL } },\n    /* 12 << 0 */\n    { { 0x04b71aa7d2697768L,0xabdedef5ca345a33L,0x2409d29dee37385eL,\n        0x4ee1df77cb83e156L },\n      { 0x0cac12d91cbb5b43L,0x170ed2f6ca895637L,0x28228cfa8ade6d66L,\n        0x7ff57c9553238acaL } },\n    /* 13 << 0 */\n    { { 0xccc425634b2ed709L,0x0e356769856fd30dL,0xbcbcd43f559e9811L,\n        0x738477ac5395b759L },\n      { 0x35752b90c00ee17fL,0x68748390742ed2e3L,0x7cd06422bd1f5bc1L,\n        0xfbc08769c9e7b797L } },\n    /* 14 << 0 */\n    { { 0xa242a35bb0cf664aL,0x126e48f77f9707e3L,0x1717bf54c6832660L,\n        0xfaae7332fd12c72eL },\n      { 0x27b52db7995d586bL,0xbe29569e832237c2L,0xe8e4193e2a65e7dbL,\n        0x152706dc2eaa1bbbL } },\n    /* 15 << 0 */\n    { { 0x72bcd8b7bc60055bL,0x03cc23ee56e27e4bL,0xee337424e4819370L,\n        0xe2aa0e430ad3da09L },\n      { 0x40b8524f6383c45dL,0xd766355442a41b25L,0x64efa6de778a4797L,\n        0x2042170a7079adf4L } },\n    /* 16 << 0 */\n    { { 0x808b0b650bc6fb80L,0x5882e0753ffe2e6bL,0xd5ef2f7c2c83f549L,\n        0x54d63c809103b723L },\n      { 0xf2f11bd652a23f9bL,0x3670c3194b0b6587L,0x55c4623bb1580e9eL,\n        0x64edf7b201efe220L } },\n    /* 17 << 0 */\n    { { 0x97091dcbd53c5c9dL,0xf17624b6ac0a177bL,0xb0f139752cfe2dffL,\n        0xc1a35c0a6c7a574eL },\n      { 0x227d314693e79987L,0x0575bf30e89cb80eL,0x2f4e247f0d1883bbL,\n        0xebd512263274c3d0L } },\n    /* 18 << 0 */\n    { { 0x5f3e51c856ada97aL,0x4afc964d8f8b403eL,0xa6f247ab412e2979L,\n        0x675abd1b6f80ebdaL },\n      { 0x66a2bd725e485a1dL,0x4b2a5caf8f4f0b3cL,0x2626927f1b847bbaL,\n        0x6c6fc7d90502394dL } },\n    /* 19 << 0 */\n    { { 0xfea912baa5659ae8L,0x68363aba25e1a16eL,0xb8842277752c41acL,\n        0xfe545c282897c3fcL },\n      { 0x2d36e9e7dc4c696bL,0x5806244afba977c5L,0x85665e9be39508c1L,\n        0xf720ee256d12597bL } },\n    /* 20 << 0 */\n    { { 0x8a979129d2337a31L,0x5916868f0f862bdcL,0x048099d95dd283baL,\n        0xe2d1eeb6fe5bfb4eL },\n      { 0x82ef1c417884005dL,0xa2d4ec17ffffcbaeL,0x9161c53f8aa95e66L,\n        0x5ee104e1c5fee0d0L } },\n    /* 21 << 0 */\n    { { 0x562e4cecc135b208L,0x74e1b2654783f47dL,0x6d2a506c5a3f3b30L,\n        0xecead9f4c16762fcL },\n      { 0xf29dd4b2e286e5b9L,0x1b0fadc083bb3c61L,0x7a75023e7fac29a4L,\n        0xc086d5f1c9477fa3L } },\n    /* 22 << 0 */\n    { { 0x0fc611352f6f3076L,0xc99ffa23e3912a9aL,0x6a0b0685d2f8ba3dL,\n        0xfdc777e8e93358a4L },\n      { 0x94a787bb35415f04L,0x640c2d6a4d23fea4L,0x9de917da153a35b5L,\n        0x793e8d075d5cd074L } },\n    /* 23 << 0 */\n    { { 0xf4f876532de45068L,0x37c7a7e89e2e1f6eL,0xd0825fa2a3584069L,\n        0xaf2cea7c1727bf42L },\n      { 0x0360a4fb9e4785a9L,0xe5fda49c27299f4aL,0x48068e1371ac2f71L,\n        0x83d0687b9077666fL } },\n    /* 24 << 0 */\n    { { 0x6d3883b215d02819L,0x6d0d755040dd9a35L,0x61d7cbf91d2b469fL,\n        0xf97b232f2efc3115L },\n      { 0xa551d750b24bcbc7L,0x11ea494988a1e356L,0x7669f03193cb7501L,\n        0x595dc55eca737b8aL } },\n    /* 25 << 0 */\n    { { 0xa4a319acd837879fL,0x6fc1b49eed6b67b0L,0xe395993332f1f3afL,\n        0x966742eb65432a2eL },\n      { 0x4b8dc9feb4966228L,0x96cc631243f43950L,0x12068859c9b731eeL,\n        0x7b948dc356f79968L } },\n    /* 26 << 0 */\n    { { 0x61e4ad32ed1f8008L,0xe6c9267ad8b17538L,0x1ac7c5eb857ff6fbL,\n        0x994baaa855f2fb10L },\n      { 0x84cf14e11d248018L,0x5a39898b628ac508L,0x14fde97b5fa944f5L,\n        0xed178030d12e5ac7L } },\n    /* 27 << 0 */\n    { { 0x042c2af497e2feb4L,0xd36a42d7aebf7313L,0x49d2c9eb084ffdd7L,\n        0x9f8aa54b2ef7c76aL },\n      { 0x9200b7ba09895e70L,0x3bd0c66fddb7fb58L,0x2d97d10878eb4cbbL,\n        0x2d431068d84bde31L } },\n    /* 28 << 0 */\n    { { 0x4b523eb7172ccd1fL,0x7323cb2830a6a892L,0x97082ec0cfe153ebL,\n        0xe97f6b6af2aadb97L },\n      { 0x1d3d393ed1a83da1L,0xa6a7f9c7804b2a68L,0x4a688b482d0cb71eL,\n        0xa9b4cc5f40585278L } },\n    /* 29 << 0 */\n    { { 0x5e5db46acb66e132L,0xf1be963a0d925880L,0x944a70270317b9e2L,\n        0xe266f95948603d48L },\n      { 0x98db66735c208899L,0x90472447a2fb18a3L,0x8a966939777c619fL,\n        0x3798142a2a3be21bL } },\n    /* 30 << 0 */\n    { { 0xb4241cb13298b343L,0xa3a14e49b44f65a1L,0xc5f4d6cd3ac77acdL,\n        0xd0288cb552b6fc3cL },\n      { 0xd5cc8c2f1c040abcL,0xb675511e06bf9b4aL,0xd667da379b3aa441L,\n        0x460d45ce51601f72L } },\n    /* 31 << 0 */\n    { { 0xe2f73c696755ff89L,0xdd3cf7e7473017e6L,0x8ef5689d3cf7600dL,\n        0x948dc4f8b1fc87b4L },\n      { 0xd9e9fe814ea53299L,0x2d921ca298eb6028L,0xfaecedfd0c9803fcL,\n        0xf38ae8914d7b4745L } },\n    /* 32 << 0 */\n    { { 0xd8c5fccfc5e3a3d8L,0xbefd904c4079dfbfL,0xbc6d6a58fead0197L,\n        0x39227077695532a4L },\n      { 0x09e23e6ddbef42f5L,0x7e449b64480a9908L,0x7b969c1aad9a2e40L,\n        0x6231d7929591c2a4L } },\n    /* 33 << 0 */\n    { { 0x871514560f664534L,0x85ceae7c4b68f103L,0xac09c4ae65578ab9L,\n        0x33ec6868f044b10cL },\n      { 0x6ac4832b3a8ec1f1L,0x5509d1285847d5efL,0xf909604f763f1574L,\n        0xb16c4303c32f63c4L } },\n    /* 34 << 0 */\n    { { 0xb6ab20147ca23cd3L,0xcaa7a5c6a391849dL,0x5b0673a375678d94L,\n        0xc982ddd4dd303e64L },\n      { 0xfd7b000b5db6f971L,0xbba2cb1f6f876f92L,0xc77332a33c569426L,\n        0xa159100c570d74f8L } },\n    /* 35 << 0 */\n    { { 0xfd16847fdec67ef5L,0x742ee464233e76b7L,0x0b8e4134efc2b4c8L,\n        0xca640b8642a3e521L },\n      { 0x653a01908ceb6aa9L,0x313c300c547852d5L,0x24e4ab126b237af7L,\n        0x2ba901628bb47af8L } },\n    /* 36 << 0 */\n    { { 0x3d5e58d6a8219bb7L,0xc691d0bd1b06c57fL,0x0ae4cb10d257576eL,\n        0x3569656cd54a3dc3L },\n      { 0xe5ebaebd94cda03aL,0x934e82d3162bfe13L,0x450ac0bae251a0c6L,\n        0x480b9e11dd6da526L } },\n    /* 37 << 0 */\n    { { 0x00467bc58cce08b5L,0xb636458c7f178d55L,0xc5748baea677d806L,\n        0x2763a387dfa394ebL },\n      { 0xa12b448a7d3cebb6L,0xe7adda3e6f20d850L,0xf63ebce51558462cL,\n        0x58b36143620088a8L } },\n    /* 38 << 0 */\n    { { 0x8a2cc3ca4d63c0eeL,0x512331170fe948ceL,0x7463fd85222ef33bL,\n        0xadf0c7dc7c603d6cL },\n      { 0x0ec32d3bfe7765e5L,0xccaab359bf380409L,0xbdaa84d68e59319cL,\n        0xd9a4c2809c80c34dL } },\n    /* 39 << 0 */\n    { { 0xa9d89488a059c142L,0x6f5ae714ff0b9346L,0x068f237d16fb3664L,\n        0x5853e4c4363186acL },\n      { 0xe2d87d2363c52f98L,0x2ec4a76681828876L,0x47b864fae14e7b1cL,\n        0x0c0bc0e569192408L } },\n    /* 40 << 0 */\n    { { 0xe4d7681db82e9f3eL,0x83200f0bdf25e13cL,0x8909984c66f27280L,\n        0x462d7b0075f73227L },\n      { 0xd90ba188f2651798L,0x74c6e18c36ab1c34L,0xab256ea35ef54359L,\n        0x03466612d1aa702fL } },\n    /* 41 << 0 */\n    { { 0x624d60492ed22e91L,0x6fdfe0b56f072822L,0xeeca111539ce2271L,\n        0x98100a4fdb01614fL },\n      { 0xb6b0daa2a35c628fL,0xb6f94d2ec87e9a47L,0xc67732591d57d9ceL,\n        0xf70bfeec03884a7bL } },\n    /* 42 << 0 */\n    { { 0x5fb35ccfed2bad01L,0xa155cbe31da6a5c7L,0xc2e2594c30a92f8fL,\n        0x649c89ce5bfafe43L },\n      { 0xd158667de9ff257aL,0x9b359611f32c50aeL,0x4b00b20b906014cfL,\n        0xf3a8cfe389bc7d3dL } },\n    /* 43 << 0 */\n    { { 0x4ff23ffd248a7d06L,0x80c5bfb4878873faL,0xb7d9ad9005745981L,\n        0x179c85db3db01994L },\n      { 0xba41b06261a6966cL,0x4d82d052eadce5a8L,0x9e91cd3ba5e6a318L,\n        0x47795f4f95b2dda0L } },\n    /* 44 << 0 */\n    { { 0xecfd7c1fd55a897cL,0x009194abb29110fbL,0x5f0e2046e381d3b0L,\n        0x5f3425f6a98dd291L },\n      { 0xbfa06687730d50daL,0x0423446c4b083b7fL,0x397a247dd69d3417L,\n        0xeb629f90387ba42aL } },\n    /* 45 << 0 */\n    { { 0x1ee426ccd5cd79bfL,0x0032940b946c6e18L,0x1b1e8ae057477f58L,\n        0xe94f7d346d823278L },\n      { 0xc747cb96782ba21aL,0xc5254469f72b33a5L,0x772ef6dec7f80c81L,\n        0xd73acbfe2cd9e6b5L } },\n    /* 46 << 0 */\n    { { 0x4075b5b149ee90d9L,0x785c339aa06e9ebaL,0xa1030d5babf825e0L,\n        0xcec684c3a42931dcL },\n      { 0x42ab62c9c1586e63L,0x45431d665ab43f2bL,0x57c8b2c055f7835dL,\n        0x033da338c1b7f865L } },\n    /* 47 << 0 */\n    { { 0x283c7513caa76097L,0x0a624fa936c83906L,0x6b20afec715af2c7L,\n        0x4b969974eba78bfdL },\n      { 0x220755ccd921d60eL,0x9b944e107baeca13L,0x04819d515ded93d4L,\n        0x9bbff86e6dddfd27L } },\n    /* 48 << 0 */\n    { { 0x6b34413077adc612L,0xa7496529bbd803a0L,0x1a1baaa76d8805bdL,\n        0xc8403902470343adL },\n      { 0x39f59f66175adff1L,0x0b26d7fbb7d8c5b7L,0xa875f5ce529d75e3L,\n        0x85efc7e941325cc2L } },\n    /* 49 << 0 */\n    { { 0x21950b421ff6acd3L,0xffe7048453dc6909L,0xff4cd0b228766127L,\n        0xabdbe6084fb7db2bL },\n      { 0x837c92285e1109e8L,0x26147d27f4645b5aL,0x4d78f592f7818ed8L,\n        0xd394077ef247fa36L } },\n    /* 50 << 0 */\n    { { 0x0fb9c2d0488c171aL,0xa78bfbaa13685278L,0xedfbe268d5b1fa6aL,\n        0x0dceb8db2b7eaba7L },\n      { 0xbf9e80899ae2b710L,0xefde7ae6a4449c96L,0x43b7716bcc143a46L,\n        0xd7d34194c3628c13L } },\n    /* 51 << 0 */\n    { { 0x508cec1c3b3f64c9L,0xe20bc0ba1e5edf3fL,0xda1deb852f4318d4L,\n        0xd20ebe0d5c3fa443L },\n      { 0x370b4ea773241ea3L,0x61f1511c5e1a5f65L,0x99a5e23d82681c62L,\n        0xd731e383a2f54c2dL } },\n    /* 52 << 0 */\n    { { 0x2692f36e83445904L,0x2e0ec469af45f9c0L,0x905a3201c67528b7L,\n        0x88f77f34d0e5e542L },\n      { 0xf67a8d295864687cL,0x23b92eae22df3562L,0x5c27014b9bbec39eL,\n        0x7ef2f2269c0f0f8dL } },\n    /* 53 << 0 */\n    { { 0x97359638546c4d8dL,0x5f9c3fc492f24679L,0x912e8beda8c8acd9L,\n        0xec3a318d306634b0L },\n      { 0x80167f41c31cb264L,0x3db82f6f522113f2L,0xb155bcd2dcafe197L,\n        0xfba1da5943465283L } },\n    /* 54 << 0 */\n    { { 0xa0425b8eb212cf53L,0x4f2e512ef8557c5fL,0xc1286ff925c4d56cL,\n        0xbb8a0feaee26c851L },\n      { 0xc28f70d2e7d6107eL,0x7ee0c444e76265aaL,0x3df277a41d1936b1L,\n        0x1a556e3fea9595ebL } },\n    /* 55 << 0 */\n    { { 0x258bbbf9e7305683L,0x31eea5bf07ef5be6L,0x0deb0e4a46c814c1L,\n        0x5cee8449a7b730ddL },\n      { 0xeab495c5a0182bdeL,0xee759f879e27a6b4L,0xc2cf6a6880e518caL,\n        0x25e8013ff14cf3f4L } },\n    /* 56 << 0 */\n    { { 0x8fc441407e8d7a14L,0xbb1ff3ca9556f36aL,0x6a84438514600044L,\n        0xba3f0c4a7451ae63L },\n      { 0xdfcac25b1f9af32aL,0x01e0db86b1f2214bL,0x4e9a5bc2a4b596acL,\n        0x83927681026c2c08L } },\n    /* 57 << 0 */\n    { { 0x3ec832e77acaca28L,0x1bfeea57c7385b29L,0x068212e3fd1eaf38L,\n        0xc13298306acf8cccL },\n      { 0xb909f2db2aac9e59L,0x5748060db661782aL,0xc5ab2632c79b7a01L,\n        0xda44c6c600017626L } },\n    /* 58 << 0 */\n    { { 0xf26c00e8a7ea82f0L,0x99cac80de4299aafL,0xd66fe3b67ed78be1L,\n        0x305f725f648d02cdL },\n      { 0x33ed1bc4623fb21bL,0xfa70533e7a6319adL,0x17ab562dbe5ffb3eL,\n        0x0637499456674741L } },\n    /* 59 << 0 */\n    { { 0x69d44ed65c46aa8eL,0x2100d5d3a8d063d1L,0xcb9727eaa2d17c36L,\n        0x4c2bab1b8add53b7L },\n      { 0xa084e90c15426704L,0x778afcd3a837ebeaL,0x6651f7017ce477f8L,\n        0xa062499846fb7a8bL } },\n    /* 60 << 0 */\n    { { 0xdc1e6828ed8a6e19L,0x33fc23364189d9c7L,0x026f8fe2671c39bcL,\n        0xd40c4ccdbc6f9915L },\n      { 0xafa135bbf80e75caL,0x12c651a022adff2cL,0xc40a04bd4f51ad96L,\n        0x04820109bbe4e832L } },\n    /* 61 << 0 */\n    { { 0x3667eb1a7f4c04ccL,0x59556621a9404f84L,0x71cdf6537eceb50aL,\n        0x994a44a69b8335faL },\n      { 0xd7faf819dbeb9b69L,0x473c5680eed4350dL,0xb6658466da44bba2L,\n        0x0d1bc780872bdbf3L } },\n    /* 62 << 0 */\n    { { 0xe535f175a1962f91L,0x6ed7e061ed58f5a7L,0x177aa4c02089a233L,\n        0x0dbcb03ae539b413L },\n      { 0xe3dc424ebb32e38eL,0x6472e5ef6806701eL,0xdd47ff98814be9eeL,\n        0x6b60cfff35ace009L } },\n    /* 63 << 0 */\n    { { 0xb8d3d9319ff91fe5L,0x039c4800f0518eedL,0x95c376329182cb26L,\n        0x0763a43482fc568dL },\n      { 0x707c04d5383e76baL,0xac98b930824e8197L,0x92bf7c8f91230de0L,\n        0x90876a0140959b70L } },\n    /* 64 << 0 */\n    { { 0xdb6d96f305968b80L,0x380a0913089f73b9L,0x7da70b83c2c61e01L,\n        0x95fb8394569b38c7L },\n      { 0x9a3c651280edfe2fL,0x8f726bb98faeaf82L,0x8010a4a078424bf8L,\n        0x296720440e844970L } },\n    /* 0 << 7 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 7 */\n    { { 0x63c5cb817a2ad62aL,0x7ef2b6b9ac62ff54L,0x3749bba4b3ad9db5L,\n        0xad311f2c46d5a617L },\n      { 0xb77a8087c2ff3b6dL,0xb46feaf3367834ffL,0xf8aa266d75d6b138L,\n        0xfa38d320ec008188L } },\n    /* 2 << 7 */\n    { { 0x486d8ffa696946fcL,0x50fbc6d8b9cba56dL,0x7e3d423e90f35a15L,\n        0x7c3da195c0dd962cL },\n      { 0xe673fdb03cfd5d8bL,0x0704b7c2889dfca5L,0xf6ce581ff52305aaL,\n        0x399d49eb914d5e53L } },\n    /* 3 << 7 */\n    { { 0x380a496d6ec293cdL,0x733dbda78e7051f5L,0x037e388db849140aL,\n        0xee4b32b05946dbf6L },\n      { 0xb1c4fda9cae368d1L,0x5001a7b0fdb0b2f3L,0x6df593742e3ac46eL,\n        0x4af675f239b3e656L } },\n    /* 4 << 7 */\n    { { 0x44e3811039949296L,0x5b63827b361db1b5L,0x3e5323ed206eaff5L,\n        0x942370d2c21f4290L },\n      { 0xf2caaf2ee0d985a1L,0x192cc64b7239846dL,0x7c0b8f47ae6312f8L,\n        0x7dc61f9196620108L } },\n    /* 5 << 7 */\n    { { 0xb830fb5bc2da7de9L,0xd0e643df0ff8d3beL,0x31ee77ba188a9641L,\n        0x4e8aa3aabcf6d502L },\n      { 0xf9fb65329a49110fL,0xd18317f62dd6b220L,0x7e3ced4152c3ea5aL,\n        0x0d296a147d579c4aL } },\n    /* 6 << 7 */\n    { { 0x35d6a53eed4c3717L,0x9f8240cf3d0ed2a3L,0x8c0d4d05e5543aa5L,\n        0x45d5bbfbdd33b4b4L },\n      { 0xfa04cc73137fd28eL,0x862ac6efc73b3ffdL,0x403ff9f531f51ef2L,\n        0x34d5e0fcbc73f5a2L } },\n    /* 7 << 7 */\n    { { 0xf252682008913f4fL,0xea20ed61eac93d95L,0x51ed38b46ca6b26cL,\n        0x8662dcbcea4327b0L },\n      { 0x6daf295c725d2aaaL,0xbad2752f8e52dcdaL,0x2210e7210b17daccL,\n        0xa37f7912d51e8232L } },\n    /* 8 << 7 */\n    { { 0x4f7081e144cc3addL,0xd5ffa1d687be82cfL,0x89890b6c0edd6472L,\n        0xada26e1a3ed17863L },\n      { 0x276f271563483caaL,0xe6924cd92f6077fdL,0x05a7fe980a466e3cL,\n        0xf1c794b0b1902d1fL } },\n    /* 9 << 7 */\n    { { 0xe521368882a8042cL,0xd931cfafcd278298L,0x069a0ae0f597a740L,\n        0x0adbb3f3eb59107cL },\n      { 0x983e951e5eaa8eb8L,0xe663a8b511b48e78L,0x1631cc0d8a03f2c5L,\n        0x7577c11e11e271e2L } },\n    /* 10 << 7 */\n    { { 0x33b2385c08369a90L,0x2990c59b190eb4f8L,0x819a6145c68eac80L,\n        0x7a786d622ec4a014L },\n      { 0x33faadbe20ac3a8dL,0x31a217815aba2d30L,0x209d2742dba4f565L,\n        0xdb2ce9e355aa0fbbL } },\n    /* 11 << 7 */\n    { { 0x8cef334b168984dfL,0xe81dce1733879638L,0xf6e6949c263720f0L,\n        0x5c56feaff593cbecL },\n      { 0x8bff5601fde58c84L,0x74e241172eccb314L,0xbcf01b614c9a8a78L,\n        0xa233e35e544c9868L } },\n    /* 12 << 7 */\n    { { 0xb3156bf38bd7aff1L,0x1b5ee4cb1d81b146L,0x7ba1ac41d628a915L,\n        0x8f3a8f9cfd89699eL },\n      { 0x7329b9c9a0748be7L,0x1d391c95a92e621fL,0xe51e6b214d10a837L,\n        0xd255f53a4947b435L } },\n    /* 13 << 7 */\n    { { 0x07669e04f1788ee3L,0xc14f27afa86938a2L,0x8b47a334e93a01c0L,\n        0xff627438d9366808L },\n      { 0x7a0985d8ca2a5965L,0x3d9a5542d6e9b9b3L,0xc23eb80b4cf972e8L,\n        0x5c1c33bb4fdf72fdL } },\n    /* 14 << 7 */\n    { { 0x0c4a58d474a86108L,0xf8048a8fee4c5d90L,0xe3c7c924e86d4c80L,\n        0x28c889de056a1e60L },\n      { 0x57e2662eb214a040L,0xe8c48e9837e10347L,0x8774286280ac748aL,\n        0xf1c24022186b06f2L } },\n    /* 15 << 7 */\n    { { 0xac2dd4c35f74040aL,0x409aeb71fceac957L,0x4fbad78255c4ec23L,\n        0xb359ed618a7b76ecL },\n      { 0x12744926ed6f4a60L,0xe21e8d7f4b912de3L,0xe2575a59fc705a59L,\n        0x72f1d4deed2dbc0eL } },\n    /* 16 << 7 */\n    { { 0x3d2b24b9eb7926b8L,0xbff88cb3cdbe5509L,0xd0f399afe4dd640bL,\n        0x3c5fe1302f76ed45L },\n      { 0x6f3562f43764fb3dL,0x7b5af3183151b62dL,0xd5bd0bc7d79ce5f3L,\n        0xfdaf6b20ec66890fL } },\n    /* 17 << 7 */\n    { { 0x735c67ec6063540cL,0x50b259c2e5f9cb8fL,0xb8734f9a3f99c6abL,\n        0xf8cc13d5a3a7bc85L },\n      { 0x80c1b305c5217659L,0xfe5364d44ec12a54L,0xbd87045e681345feL,\n        0x7f8efeb1582f897fL } },\n    /* 18 << 7 */\n    { { 0xe8cbf1e5d5923359L,0xdb0cea9d539b9fb0L,0x0c5b34cf49859b98L,\n        0x5e583c56a4403cc6L },\n      { 0x11fc1a2dd48185b7L,0xc93fbc7e6e521787L,0x47e7a05805105b8bL,\n        0x7b4d4d58db8260c8L } },\n    /* 19 << 7 */\n    { { 0xe33930b046eb842aL,0x8e844a9a7bdae56dL,0x34ef3a9e13f7fdfcL,\n        0xb3768f82636ca176L },\n      { 0x2821f4e04e09e61cL,0x414dc3a1a0c7cddcL,0xd537943754945fcdL,\n        0x151b6eefb3555ff1L } },\n    /* 20 << 7 */\n    { { 0xb31bd6136339c083L,0x39ff8155dfb64701L,0x7c3388d2e29604abL,\n        0x1e19084ba6b10442L },\n      { 0x17cf54c0eccd47efL,0x896933854a5dfb30L,0x69d023fb47daf9f6L,\n        0x9222840b7d91d959L } },\n    /* 21 << 7 */\n    { { 0x439108f5803bac62L,0x0b7dd91d379bd45fL,0xd651e827ca63c581L,\n        0x5c5d75f6509c104fL },\n      { 0x7d5fc7381f2dc308L,0x20faa7bfd98454beL,0x95374beea517b031L,\n        0xf036b9b1642692acL } },\n    /* 22 << 7 */\n    { { 0xc510610939842194L,0xb7e2353e49d05295L,0xfc8c1d5cefb42ee0L,\n        0xe04884eb08ce811cL },\n      { 0xf1f75d817419f40eL,0x5b0ac162a995c241L,0x120921bbc4c55646L,\n        0x713520c28d33cf97L } },\n    /* 23 << 7 */\n    { { 0xb4a65a5ce98c5100L,0x6cec871d2ddd0f5aL,0x251f0b7f9ba2e78bL,\n        0x224a8434ce3a2a5fL },\n      { 0x26827f6125f5c46fL,0x6a22bedc48545ec0L,0x25ae5fa0b1bb5cdcL,\n        0xd693682ffcb9b98fL } },\n    /* 24 << 7 */\n    { { 0x32027fe891e5d7d3L,0xf14b7d1773a07678L,0xf88497b3c0dfdd61L,\n        0xf7c2eec02a8c4f48L },\n      { 0xaa5573f43756e621L,0xc013a2401825b948L,0x1c03b34563878572L,\n        0xa0472bea653a4184L } },\n    /* 25 << 7 */\n    { { 0xf4222e270ac69a80L,0x34096d25f51e54f6L,0x00a648cb8fffa591L,\n        0x4e87acdc69b6527fL },\n      { 0x0575e037e285ccb4L,0x188089e450ddcf52L,0xaa96c9a8870ff719L,\n        0x74a56cd81fc7e369L } },\n    /* 26 << 7 */\n    { { 0x41d04ee21726931aL,0x0bbbb2c83660ecfdL,0xa6ef6de524818e18L,\n        0xe421cc51e7d57887L },\n      { 0xf127d208bea87be6L,0x16a475d3b1cdd682L,0x9db1b684439b63f7L,\n        0x5359b3dbf0f113b6L } },\n    /* 27 << 7 */\n    { { 0xdfccf1de8bf06e31L,0x1fdf8f44dd383901L,0x10775cad5017e7d2L,\n        0xdfc3a59758d11eefL },\n      { 0x6ec9c8a0b1ecff10L,0xee6ed6cc28400549L,0xb5ad7bae1b4f8d73L,\n        0x61b4f11de00aaab9L } },\n    /* 28 << 7 */\n    { { 0x7b32d69bd4eff2d7L,0x88ae67714288b60fL,0x159461b437a1e723L,\n        0x1f3d4789570aae8cL },\n      { 0x869118c07f9871daL,0x35fbda78f635e278L,0x738f3641e1541dacL,\n        0x6794b13ac0dae45fL } },\n    /* 29 << 7 */\n    { { 0x065064ac09cc0917L,0x27c53729c68540fdL,0x0d2d4c8eef227671L,\n        0xd23a9f80a1785a04L },\n      { 0x98c5952852650359L,0xfa09ad0174a1acadL,0x082d5a290b55bf5cL,\n        0xa40f1c67419b8084L } },\n    /* 30 << 7 */\n    { { 0x3a5c752edcc18770L,0x4baf1f2f8825c3a5L,0xebd63f7421b153edL,\n        0xa2383e47b2f64723L },\n      { 0xe7bf620a2646d19aL,0x56cb44ec03c83ffdL,0xaf7267c94f6be9f1L,\n        0x8b2dfd7bc06bb5e9L } },\n    /* 31 << 7 */\n    { { 0xb87072f2a672c5c7L,0xeacb11c80d53c5e2L,0x22dac29dff435932L,\n        0x37bdb99d4408693cL },\n      { 0xf6e62fb62899c20fL,0x3535d512447ece24L,0xfbdc6b88ff577ce3L,\n        0x726693bd190575f2L } },\n    /* 32 << 7 */\n    { { 0x6772b0e5ab4b35a2L,0x1d8b6001f5eeaacfL,0x728f7ce4795b9580L,\n        0x4a20ed2a41fb81daL },\n      { 0x9f685cd44fec01e6L,0x3ed7ddcca7ff50adL,0x460fd2640c2d97fdL,\n        0x3a241426eb82f4f9L } },\n    /* 33 << 7 */\n    { { 0x17d1df2c6a8ea820L,0xb2b50d3bf22cc254L,0x03856cbab7291426L,\n        0x87fd26ae04f5ee39L },\n      { 0x9cb696cc02bee4baL,0x5312180406820fd6L,0xa5dfc2690212e985L,\n        0x666f7ffa160f9a09L } },\n    /* 34 << 7 */\n    { { 0xc503cd33bccd9617L,0x365dede4ba7730a3L,0x798c63555ddb0786L,\n        0xa6c3200efc9cd3bcL },\n      { 0x060ffb2ce5e35efdL,0x99a4e25b5555a1c1L,0x11d95375f70b3751L,\n        0x0a57354a160e1bf6L } },\n    /* 35 << 7 */\n    { { 0xecb3ae4bf8e4b065L,0x07a834c42e53022bL,0x1cd300b38692ed96L,\n        0x16a6f79261ee14ecL },\n      { 0x8f1063c66a8649edL,0xfbcdfcfe869f3e14L,0x2cfb97c100a7b3ecL,\n        0xcea49b3c7130c2f1L } },\n    /* 36 << 7 */\n    { { 0x462d044fe9d96488L,0x4b53d52e8182a0c1L,0x84b6ddd30391e9e9L,\n        0x80ab7b48b1741a09L },\n      { 0xec0e15d427d3317fL,0x8dfc1ddb1a64671eL,0x93cc5d5fd49c5b92L,\n        0xc995d53d3674a331L } },\n    /* 37 << 7 */\n    { { 0x302e41ec090090aeL,0x2278a0ccedb06830L,0x1d025932fbc99690L,\n        0x0c32fbd2b80d68daL },\n      { 0xd79146daf341a6c1L,0xae0ba1391bef68a0L,0xc6b8a5638d774b3aL,\n        0x1cf307bd880ba4d7L } },\n    /* 38 << 7 */\n    { { 0xc033bdc719803511L,0xa9f97b3b8888c3beL,0x3d68aebc85c6d05eL,\n        0xc3b88a9d193919ebL },\n      { 0x2d300748c48b0ee3L,0x7506bc7c07a746c1L,0xfc48437c6e6d57f3L,\n        0x5bd71587cfeaa91aL } },\n    /* 39 << 7 */\n    { { 0xa4ed0408c1bc5225L,0xd0b946db2719226dL,0x109ecd62758d2d43L,\n        0x75c8485a2751759bL },\n      { 0xb0b75f499ce4177aL,0x4fa61a1e79c10c3dL,0xc062d300a167fcd7L,\n        0x4df3874c750f0fa8L } },\n    /* 40 << 7 */\n    { { 0x29ae2cf983dfedc9L,0xf84371348d87631aL,0xaf5717117429c8d2L,\n        0x18d15867146d9272L },\n      { 0x83053ecf69769bb7L,0xc55eb856c479ab82L,0x5ef7791c21b0f4b2L,\n        0xaa5956ba3d491525L } },\n    /* 41 << 7 */\n    { { 0x407a96c29fe20ebaL,0xf27168bbe52a5ad3L,0x43b60ab3bf1d9d89L,\n        0xe45c51ef710e727aL },\n      { 0xdfca5276099b4221L,0x8dc6407c2557a159L,0x0ead833591035895L,\n        0x0a9db9579c55dc32L } },\n    /* 42 << 7 */\n    { { 0xe40736d3df61bc76L,0x13a619c03f778cdbL,0x6dd921a4c56ea28fL,\n        0x76a524332fa647b4L },\n      { 0x23591891ac5bdc5dL,0xff4a1a72bac7dc01L,0x9905e26162df8453L,\n        0x3ac045dfe63b265fL } },\n    /* 43 << 7 */\n    { { 0x8a3f341bad53dba7L,0x8ec269cc837b625aL,0xd71a27823ae31189L,\n        0x8fb4f9a355e96120L },\n      { 0x804af823ff9875cfL,0x23224f575d442a9bL,0x1c4d3b9eecc62679L,\n        0x91da22fba0e7ddb1L } },\n    /* 44 << 7 */\n    { { 0xa370324d6c04a661L,0x9710d3b65e376d17L,0xed8c98f03044e357L,\n        0xc364ebbe6422701cL },\n      { 0x347f5d517733d61cL,0xd55644b9cea826c3L,0x80c6e0ad55a25548L,\n        0x0aa7641d844220a7L } },\n    /* 45 << 7 */\n    { { 0x1438ec8131810660L,0x9dfa6507de4b4043L,0x10b515d8cc3e0273L,\n        0x1b6066dd28d8cfb2L },\n      { 0xd3b045919c9efebdL,0x425d4bdfa21c1ff4L,0x5fe5af19d57607d3L,\n        0xbbf773f754481084L } },\n    /* 46 << 7 */\n    { { 0x8435bd6994b03ed1L,0xd9ad1de3634cc546L,0x2cf423fc00e420caL,\n        0xeed26d80a03096ddL },\n      { 0xd7f60be7a4db09d2L,0xf47f569d960622f7L,0xe5925fd77296c729L,\n        0xeff2db2626ca2715L } },\n    /* 47 << 7 */\n    { { 0xa6fcd014b913e759L,0x53da47868ff4de93L,0x14616d79c32068e1L,\n        0xb187d664ccdf352eL },\n      { 0xf7afb6501dc90b59L,0x8170e9437daa1b26L,0xc8e3bdd8700c0a84L,\n        0x6e8d345f6482bdfaL } },\n    /* 48 << 7 */\n    { { 0x84cfbfa1c5c5ea50L,0xd3baf14c67960681L,0x263984030dd50942L,\n        0xe4b7839c4716a663L },\n      { 0xd5f1f794e7de6dc0L,0x5cd0f4d4622aa7ceL,0x5295f3f159acfeecL,\n        0x8d933552953e0607L } },\n    /* 49 << 7 */\n    { { 0xc7db8ec5776c5722L,0xdc467e622b5f290cL,0xd4297e704ff425a9L,\n        0x4be924c10cf7bb72L },\n      { 0x0d5dc5aea1892131L,0x8bf8a8e3a705c992L,0x73a0b0647a305ac5L,\n        0x00c9ca4e9a8c77a8L } },\n    /* 50 << 7 */\n    { { 0x5dfee80f83774bddL,0x6313160285734485L,0xa1b524ae914a69a9L,\n        0xebc2ffafd4e300d7L },\n      { 0x52c93db77cfa46a5L,0x71e6161f21653b50L,0x3574fc57a4bc580aL,\n        0xc09015dde1bc1253L } },\n    /* 51 << 7 */\n    { { 0x4b7b47b2d174d7aaL,0x4072d8e8f3a15d04L,0xeeb7d47fd6fa07edL,\n        0x6f2b9ff9edbdafb1L },\n      { 0x18c516153760fe8aL,0x7a96e6bff06c6c13L,0x4d7a04100ea2d071L,\n        0xa1914e9b0be2a5ceL } },\n    /* 52 << 7 */\n    { { 0x5726e357d8a3c5cfL,0x1197ecc32abb2b13L,0x6c0d7f7f31ae88ddL,\n        0x15b20d1afdbb3efeL },\n      { 0xcd06aa2670584039L,0x2277c969a7dc9747L,0xbca695877855d815L,\n        0x899ea2385188b32aL } },\n    /* 53 << 7 */\n    { { 0x37d9228b760c1c9dL,0xc7efbb119b5c18daL,0x7f0d1bc819f6dbc5L,\n        0x4875384b07e6905bL },\n      { 0xc7c50baa3ba8cd86L,0xb0ce40fbc2905de0L,0x708406737a231952L,\n        0xa912a262cf43de26L } },\n    /* 54 << 7 */\n    { { 0x9c38ddcceb5b76c1L,0x746f528526fc0ab4L,0x52a63a50d62c269fL,\n        0x60049c5599458621L },\n      { 0xe7f48f823c2f7c9eL,0x6bd99043917d5cf3L,0xeb1317a88701f469L,\n        0xbd3fe2ed9a449fe0L } },\n    /* 55 << 7 */\n    { { 0x421e79ca12ef3d36L,0x9ee3c36c3e7ea5deL,0xe48198b5cdff36f7L,\n        0xaff4f967c6b82228L },\n      { 0x15e19dd0c47adb7eL,0x45699b23032e7dfaL,0x40680c8b1fae026aL,\n        0x5a347a48550dbf4dL } },\n    /* 56 << 7 */\n    { { 0xe652533b3cef0d7dL,0xd94f7b182bbb4381L,0x838752be0e80f500L,\n        0x8e6e24889e9c9bfbL },\n      { 0xc975169716caca6aL,0x866c49d838531ad9L,0xc917e2397151ade1L,\n        0x2d016ec16037c407L } },\n    /* 57 << 7 */\n    { { 0xa407ccc900eac3f9L,0x835f6280e2ed4748L,0xcc54c3471cc98e0dL,\n        0x0e969937dcb572ebL },\n      { 0x1b16c8e88f30c9cbL,0xa606ae75373c4661L,0x47aa689b35502cabL,\n        0xf89014ae4d9bb64fL } },\n    /* 58 << 7 */\n    { { 0x202f6a9c31c71f7bL,0x01f95aa3296ffe5cL,0x5fc0601453cec3a3L,\n        0xeb9912375f498a45L },\n      { 0xae9a935e5d91ba87L,0xc6ac62810b564a19L,0x8a8fe81c3bd44e69L,\n        0x7c8b467f9dd11d45L } },\n    /* 59 << 7 */\n    { { 0xf772251fea5b8e69L,0xaeecb3bdc5b75fbcL,0x1aca3331887ff0e5L,\n        0xbe5d49ff19f0a131L },\n      { 0x582c13aae5c8646fL,0xdbaa12e820e19980L,0x8f40f31af7abbd94L,\n        0x1f13f5a81dfc7663L } },\n    /* 60 << 7 */\n    { { 0x5d81f1eeaceb4fc0L,0x362560025e6f0f42L,0x4b67d6d7751370c8L,\n        0x2608b69803e80589L },\n      { 0xcfc0d2fc05268301L,0xa6943d3940309212L,0x192a90c21fd0e1c2L,\n        0xb209f11337f1dc76L } },\n    /* 61 << 7 */\n    { { 0xefcc5e0697bf1298L,0xcbdb6730219d639eL,0xd009c116b81e8c6fL,\n        0xa3ffdde31a7ce2e5L },\n      { 0xc53fbaaaa914d3baL,0x836d500f88df85eeL,0xd98dc71b66ee0751L,\n        0x5a3d7005714516fdL } },\n    /* 62 << 7 */\n    { { 0x21d3634d39eedbbaL,0x35cd2e680455a46dL,0xc8cafe65f9d7eb0cL,\n        0xbda3ce9e00cefb3eL },\n      { 0xddc17a602c9cf7a4L,0x01572ee47bcb8773L,0xa92b2b018c7548dfL,\n        0x732fd309a84600e3L } },\n    /* 63 << 7 */\n    { { 0xe22109c716543a40L,0x9acafd36fede3c6cL,0xfb2068526824e614L,\n        0x2a4544a9da25dca0L },\n      { 0x2598526291d60b06L,0x281b7be928753545L,0xec667b1a90f13b27L,\n        0x33a83aff940e2eb4L } },\n    /* 64 << 7 */\n    { { 0x80009862d5d721d5L,0x0c3357a35bd3a182L,0x27f3a83b7aa2cda4L,\n        0xb58ae74ef6f83085L },\n      { 0x2a911a812e6dad6bL,0xde286051f43d6c5bL,0x4bdccc41f996c4d8L,\n        0xe7312ec00ae1e24eL } },\n    /* 0 << 14 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 14 */\n    { { 0xf8d112e76e6485b3L,0x4d3e24db771c52f8L,0x48e3ee41684a2f6dL,\n        0x7161957d21d95551L },\n      { 0x19631283cdb12a6cL,0xbf3fa8822e50e164L,0xf6254b633166cc73L,\n        0x3aefa7aeaee8cc38L } },\n    /* 2 << 14 */\n    { { 0x79b0fe623b36f9fdL,0x26543b23fde19fc0L,0x136e64a0958482efL,\n        0x23f637719b095825L },\n      { 0x14cfd596b6a1142eL,0x5ea6aac6335aac0bL,0x86a0e8bdf3081dd5L,\n        0x5fb89d79003dc12aL } },\n    /* 3 << 14 */\n    { { 0xf615c33af72e34d4L,0x0bd9ea40110eec35L,0x1c12bc5bc1dea34eL,\n        0x686584c949ae4699L },\n      { 0x13ad95d38c97b942L,0x4609561a4e5c7562L,0x9e94a4aef2737f89L,\n        0xf57594c6371c78b6L } },\n    /* 4 << 14 */\n    { { 0x0f0165fce3779ee3L,0xe00e7f9dbd495d9eL,0x1fa4efa220284e7aL,\n        0x4564bade47ac6219L },\n      { 0x90e6312ac4708e8eL,0x4f5725fba71e9adfL,0xe95f55ae3d684b9fL,\n        0x47f7ccb11e94b415L } },\n    /* 5 << 14 */\n    { { 0x7322851b8d946581L,0xf0d13133bdf4a012L,0xa3510f696584dae0L,\n        0x03a7c1713c9f6c6dL },\n      { 0x5be97f38e475381aL,0xca1ba42285823334L,0xf83cc5c70be17ddaL,\n        0x158b14940b918c0fL } },\n    /* 6 << 14 */\n    { { 0xda3a77e5522e6b69L,0x69c908c3bbcd6c18L,0x1f1b9e48d924fd56L,\n        0x37c64e36aa4bb3f7L },\n      { 0x5a4fdbdfee478d7dL,0xba75c8bc0193f7a0L,0x84bc1e8456cd16dfL,\n        0x1fb08f0846fad151L } },\n    /* 7 << 14 */\n    { { 0x8a7cabf9842e9f30L,0xa331d4bf5eab83afL,0xd272cfba017f2a6aL,\n        0x27560abc83aba0e3L },\n      { 0x94b833870e3a6b75L,0x25c6aea26b9f50f5L,0x803d691db5fdf6d0L,\n        0x03b77509e6333514L } },\n    /* 8 << 14 */\n    { { 0x3617890361a341c1L,0x3604dc600cfd6142L,0x022295eb8533316cL,\n        0x3dbde4ac44af2922L },\n      { 0x898afc5d1c7eef69L,0x58896805d14f4fa1L,0x05002160203c21caL,\n        0x6f0d1f3040ef730bL } },\n    /* 9 << 14 */\n    { { 0x8e8c44d4196224f8L,0x75a4ab95374d079dL,0x79085ecc7d48f123L,\n        0x56f04d311bf65ad8L },\n      { 0xe220bf1cbda602b2L,0x73ee1742f9612c69L,0x76008fc8084fd06bL,\n        0x4000ef9ff11380d1L } },\n    /* 10 << 14 */\n    { { 0x48201b4b12cfe297L,0x3eee129c292f74e5L,0xe1fe114ec9e874e8L,\n        0x899b055c92c5fc41L },\n      { 0x4e477a643a39c8cfL,0x82f09efe78963cc9L,0x6fd3fd8fd333f863L,\n        0x85132b2adc949c63L } },\n    /* 11 << 14 */\n    { { 0x7e06a3ab516eb17bL,0x73bec06fd2c7372bL,0xe4f74f55ba896da6L,\n        0xbb4afef88e9eb40fL },\n      { 0x2d75bec8e61d66b0L,0x02bda4b4ef29300bL,0x8bbaa8de026baa5aL,\n        0xff54befda07f4440L } },\n    /* 12 << 14 */\n    { { 0xbd9b8b1dbe7a2af3L,0xec51caa94fb74a72L,0xb9937a4b63879697L,\n        0x7c9a9d20ec2687d5L },\n      { 0x1773e44f6ef5f014L,0x8abcf412e90c6900L,0x387bd0228142161eL,\n        0x50393755fcb6ff2aL } },\n    /* 13 << 14 */\n    { { 0x9813fd56ed6def63L,0x53cf64827d53106cL,0x991a35bd431f7ac1L,\n        0xf1e274dd63e65fafL },\n      { 0xf63ffa3c44cc7880L,0x411a426b7c256981L,0xb698b9fd93a420e0L,\n        0x89fdddc0ae53f8feL } },\n    /* 14 << 14 */\n    { { 0x766e072232398baaL,0x205fee425cfca031L,0xa49f53417a029cf2L,\n        0xa88c68b84023890dL },\n      { 0xbc2750417337aaa8L,0x9ed364ad0eb384f4L,0xe0816f8529aba92fL,\n        0x2e9e194104e38a88L } },\n    /* 15 << 14 */\n    { { 0x57eef44a3dafd2d5L,0x35d1fae597ed98d8L,0x50628c092307f9b1L,\n        0x09d84aaed6cba5c6L },\n      { 0x67071bc788aaa691L,0x2dea57a9afe6cb03L,0xdfe11bb43d78ac01L,\n        0x7286418c7fd7aa51L } },\n    /* 16 << 14 */\n    { { 0xfabf770977f7195aL,0x8ec86167adeb838fL,0xea1285a8bb4f012dL,\n        0xd68835039a3eab3fL },\n      { 0xee5d24f8309004c2L,0xa96e4b7613ffe95eL,0x0cdffe12bd223ea4L,\n        0x8f5c2ee5b6739a53L } },\n    /* 17 << 14 */\n    { { 0x5cb4aaa5dd968198L,0xfa131c5272413a6cL,0x53d46a909536d903L,\n        0xb270f0d348606d8eL },\n      { 0x518c7564a053a3bcL,0x088254b71a86caefL,0xb3ba8cb40ab5efd0L,\n        0x5c59900e4605945dL } },\n    /* 18 << 14 */\n    { { 0xecace1dda1887395L,0x40960f36932a65deL,0x9611ff5c3aa95529L,\n        0xc58215b07c1e5a36L },\n      { 0xd48c9b58f0e1a524L,0xb406856bf590dfb8L,0xc7605e049cd95662L,\n        0x0dd036eea33ecf82L } },\n    /* 19 << 14 */\n    { { 0xa50171acc33156b3L,0xf09d24ea4a80172eL,0x4e1f72c676dc8eefL,\n        0xe60caadc5e3d44eeL },\n      { 0x006ef8a6979b1d8fL,0x60908a1c97788d26L,0x6e08f95b266feec0L,\n        0x618427c222e8c94eL } },\n    /* 20 << 14 */\n    { { 0x3d61333959145a65L,0xcd9bc368fa406337L,0x82d11be32d8a52a0L,\n        0xf6877b2797a1c590L },\n      { 0x837a819bf5cbdb25L,0x2a4fd1d8de090249L,0x622a7de774990e5fL,\n        0x840fa5a07945511bL } },\n    /* 21 << 14 */\n    { { 0x30b974be6558842dL,0x70df8c6417f3d0a6L,0x7c8035207542e46dL,\n        0x7251fe7fe4ecc823L },\n      { 0xe59134cb5e9aac9aL,0x11bb0934f0045d71L,0x53e5d9b5dbcb1d4eL,\n        0x8d97a90592defc91L } },\n    /* 22 << 14 */\n    { { 0xfe2893277946d3f9L,0xe132bd2407472273L,0xeeeb510c1eb6ae86L,\n        0x777708c5f0595067L },\n      { 0x18e2c8cd1297029eL,0x2c61095cbbf9305eL,0xe466c2586b85d6d9L,\n        0x8ac06c36da1ea530L } },\n    /* 23 << 14 */\n    { { 0xa365dc39a1304668L,0xe4a9c88507f89606L,0x65a4898facc7228dL,\n        0x3e2347ff84ca8303L },\n      { 0xa5f6fb77ea7d23a3L,0x2fac257d672a71cdL,0x6908bef87e6a44d3L,\n        0x8ff87566891d3d7aL } },\n    /* 24 << 14 */\n    { { 0xe58e90b36b0cf82eL,0x6438d2462615b5e7L,0x07b1f8fc669c145aL,\n        0xb0d8b2da36f1e1cbL },\n      { 0x54d5dadbd9184c4dL,0x3dbb18d5f93d9976L,0x0a3e0f56d1147d47L,\n        0x2afa8c8da0a48609L } },\n    /* 25 << 14 */\n    { { 0x275353e8bc36742cL,0x898f427eeea0ed90L,0x26f4947e3e477b00L,\n        0x8ad8848a308741e3L },\n      { 0x6c703c38d74a2a46L,0x5e3e05a99ba17ba2L,0xc1fa6f664ab9a9e4L,\n        0x474a2d9a3841d6ecL } },\n    /* 26 << 14 */\n    { { 0x871239ad653ae326L,0x14bcf72aa74cbb43L,0x8737650e20d4c083L,\n        0x3df86536110ed4afL },\n      { 0xd2d86fe7b53ca555L,0x688cb00dabd5d538L,0xcf81bda31ad38468L,\n        0x7ccfe3ccf01167b6L } },\n    /* 27 << 14 */\n    { { 0xcf4f47e06c4c1fe6L,0x557e1f1a298bbb79L,0xf93b974f30d45a14L,\n        0x174a1d2d0baf97c4L },\n      { 0x7a003b30c51fbf53L,0xd8940991ee68b225L,0x5b0aa7b71c0f4173L,\n        0x975797c9a20a7153L } },\n    /* 28 << 14 */\n    { { 0x26e08c07e3533d77L,0xd7222e6a2e341c99L,0x9d60ec3d8d2dc4edL,\n        0xbdfe0d8f7c476cf8L },\n      { 0x1fe59ab61d056605L,0xa9ea9df686a8551fL,0x8489941e47fb8d8cL,\n        0xfeb874eb4a7f1b10L } },\n    /* 29 << 14 */\n    { { 0xfe5fea867ee0d98fL,0x201ad34bdbf61864L,0x45d8fe4737c031d4L,\n        0xd5f49fae795f0822L },\n      { 0xdb0fb291c7f4a40cL,0x2e69d9c1730ddd92L,0x754e105449d76987L,\n        0x8a24911d7662db87L } },\n    /* 30 << 14 */\n    { { 0x61fc181060a71676L,0xe852d1a8f66a8ad1L,0x172bbd656417231eL,\n        0x0d6de7bd3babb11fL },\n      { 0x6fde6f88c8e347f8L,0x1c5875479bd99cc3L,0x78e54ed034076950L,\n        0x97f0f334796e83baL } },\n    /* 31 << 14 */\n    { { 0xe4dbe1ce4924867aL,0xbd5f51b060b84917L,0x375300403cb09a79L,\n        0xdb3fe0f8ff1743d8L },\n      { 0xed7894d8556fa9dbL,0xfa26216923412fbfL,0x563be0dbba7b9291L,\n        0x6ca8b8c00c9fb234L } },\n    /* 32 << 14 */\n    { { 0xed406aa9bd763802L,0xc21486a065303da1L,0x61ae291ec7e62ec4L,\n        0x622a0492df99333eL },\n      { 0x7fd80c9dbb7a8ee0L,0xdc2ed3bc6c01aedbL,0x35c35a1208be74ecL,\n        0xd540cb1a469f671fL } },\n    /* 33 << 14 */\n    { { 0xd16ced4ecf84f6c7L,0x8561fb9c2d090f43L,0x7e693d796f239db4L,\n        0xa736f92877bd0d94L },\n      { 0x07b4d9292c1950eeL,0xda17754356dc11b3L,0xa5dfbbaa7a6a878eL,\n        0x1c70cb294decb08aL } },\n    /* 34 << 14 */\n    { { 0xfba28c8b6f0f7c50L,0xa8eba2b8854dcc6dL,0x5ff8e89a36b78642L,\n        0x070c1c8ef6873adfL },\n      { 0xbbd3c3716484d2e4L,0xfb78318f0d414129L,0x2621a39c6ad93b0bL,\n        0x979d74c2a9e917f7L } },\n    /* 35 << 14 */\n    { { 0xfc19564761fb0428L,0x4d78954abee624d4L,0xb94896e0b8ae86fdL,\n        0x6667ac0cc91c8b13L },\n      { 0x9f18051243bcf832L,0xfbadf8b7a0010137L,0xc69b4089b3ba8aa7L,\n        0xfac4bacde687ce85L } },\n    /* 36 << 14 */\n    { { 0x9164088d977eab40L,0x51f4c5b62760b390L,0xd238238f340dd553L,\n        0x358566c3db1d31c9L },\n      { 0x3a5ad69e5068f5ffL,0xf31435fcdaff6b06L,0xae549a5bd6debff0L,\n        0x59e5f0b775e01331L } },\n    /* 37 << 14 */\n    { { 0x5d492fb898559acfL,0x96018c2e4db79b50L,0x55f4a48f609f66aaL,\n        0x1943b3af4900a14fL },\n      { 0xc22496df15a40d39L,0xb2a446844c20f7c5L,0x76a35afa3b98404cL,\n        0xbec75725ff5d1b77L } },\n    /* 38 << 14 */\n    { { 0xb67aa163bea06444L,0x27e95bb2f724b6f2L,0x3c20e3e9d238c8abL,\n        0x1213754eddd6ae17L },\n      { 0x8c431020716e0f74L,0x6679c82effc095c2L,0x2eb3adf4d0ac2932L,\n        0x2cc970d301bb7a76L } },\n    /* 39 << 14 */\n    { { 0x70c71f2f740f0e66L,0x545c616b2b6b23ccL,0x4528cfcbb40a8bd7L,\n        0xff8396332ab27722L },\n      { 0x049127d9025ac99aL,0xd314d4a02b63e33bL,0xc8c310e728d84519L,\n        0x0fcb8983b3bc84baL } },\n    /* 40 << 14 */\n    { { 0x2cc5226138634818L,0x501814f4b44c2e0bL,0xf7e181aa54dfdba3L,\n        0xcfd58ff0e759718cL },\n      { 0xf90cdb14d3b507a8L,0x57bd478ec50bdad8L,0x29c197e250e5f9aaL,\n        0x4db6eef8e40bc855L } },\n    /* 41 << 14 */\n    { { 0x2cc8f21ad1fc0654L,0xc71cc96381269d73L,0xecfbb204077f49f9L,\n        0xdde92571ca56b793L },\n      { 0x9abed6a3f97ad8f7L,0xe6c19d3f924de3bdL,0x8dce92f4a140a800L,\n        0x85f44d1e1337af07L } },\n    /* 42 << 14 */\n    { { 0x5953c08b09d64c52L,0xa1b5e49ff5df9749L,0x336a8fb852735f7dL,\n        0xb332b6db9add676bL },\n      { 0x558b88a0b4511aa4L,0x09788752dbd5cc55L,0x16b43b9cd8cd52bdL,\n        0x7f0bc5a0c2a2696bL } },\n    /* 43 << 14 */\n    { { 0x146e12d4c11f61efL,0x9ce107543a83e79eL,0x08ec73d96cbfca15L,\n        0x09ff29ad5b49653fL },\n      { 0xe31b72bde7da946eL,0xebf9eb3bee80a4f2L,0xd1aabd0817598ce4L,\n        0x18b5fef453f37e80L } },\n    /* 44 << 14 */\n    { { 0xd5d5cdd35958cd79L,0x3580a1b51d373114L,0xa36e4c91fa935726L,\n        0xa38c534def20d760L },\n      { 0x7088e40a2ff5845bL,0xe5bb40bdbd78177fL,0x4f06a7a8857f9920L,\n        0xe3cc3e50e968f05dL } },\n    /* 45 << 14 */\n    { { 0x1d68b7fee5682d26L,0x5206f76faec7f87cL,0x41110530041951abL,\n        0x58ec52c1d4b5a71aL },\n      { 0xf3488f990f75cf9aL,0xf411951fba82d0d5L,0x27ee75be618895abL,\n        0xeae060d46d8aab14L } },\n    /* 46 << 14 */\n    { { 0x9ae1df737fb54dc2L,0x1f3e391b25963649L,0x242ec32afe055081L,\n        0x5bd450ef8491c9bdL },\n      { 0x367efc67981eb389L,0xed7e19283a0550d5L,0x362e776bab3ce75cL,\n        0xe890e3081f24c523L } },\n    /* 47 << 14 */\n    { { 0xb961b682feccef76L,0x8b8e11f58bba6d92L,0x8f2ccc4c2b2375c4L,\n        0x0d7f7a52e2f86cfaL },\n      { 0xfd94d30a9efe5633L,0x2d8d246b5451f934L,0x2234c6e3244e6a00L,\n        0xde2b5b0dddec8c50L } },\n    /* 48 << 14 */\n    { { 0x2ce53c5abf776f5bL,0x6f72407160357b05L,0xb259371771bf3f7aL,\n        0x87d2501c440c4a9fL },\n      { 0x440552e187b05340L,0xb7bf7cc821624c32L,0x4155a6ce22facddbL,\n        0x5a4228cb889837efL } },\n    /* 49 << 14 */\n    { { 0xef87d6d6fd4fd671L,0xa233687ec2daa10eL,0x7562224403c0eb96L,\n        0x7632d1848bf19be6L },\n      { 0x05d0f8e940735ff4L,0x3a3e6e13c00931f1L,0x31ccde6adafe3f18L,\n        0xf381366acfe51207L } },\n    /* 50 << 14 */\n    { { 0x24c222a960167d92L,0x62f9d6f87529f18cL,0x412397c00353b114L,\n        0x334d89dcef808043L },\n      { 0xd9ec63ba2a4383ceL,0xcec8e9375cf92ba0L,0xfb8b4288c8be74c0L,\n        0x67d6912f105d4391L } },\n    /* 51 << 14 */\n    { { 0x7b996c461b913149L,0x36aae2ef3a4e02daL,0xb68aa003972de594L,\n        0x284ec70d4ec6d545L },\n      { 0xf3d2b2d061391d54L,0x69c5d5d6fe114e92L,0xbe0f00b5b4482dffL,\n        0xe1596fa5f5bf33c5L } },\n    /* 52 << 14 */\n    { { 0x10595b5696a71cbaL,0x944938b2fdcadeb7L,0xa282da4cfccd8471L,\n        0x98ec05f30d37bfe1L },\n      { 0xe171ce1b0698304aL,0x2d69144421bdf79bL,0xd0cd3b741b21dec1L,\n        0x712ecd8b16a15f71L } },\n    /* 53 << 14 */\n    { { 0x8d4c00a700fd56e1L,0x02ec9692f9527c18L,0x21c449374a3e42e1L,\n        0x9176fbab1392ae0aL },\n      { 0x8726f1ba44b7b618L,0xb4d7aae9f1de491cL,0xf91df7b907b582c0L,\n        0x7e116c30ef60aa3aL } },\n    /* 54 << 14 */\n    { { 0x99270f81466265d7L,0xb15b6fe24df7adf0L,0xfe33b2d3f9738f7fL,\n        0x48553ab9d6d70f95L },\n      { 0x2cc72ac8c21e94dbL,0x795ac38dbdc0bbeeL,0x0a1be4492e40478fL,\n        0x81bd3394052bde55L } },\n    /* 55 << 14 */\n    { { 0x63c8dbe956b3c4f2L,0x017a99cf904177ccL,0x947bbddb4d010fc1L,\n        0xacf9b00bbb2c9b21L },\n      { 0x2970bc8d47173611L,0x1a4cbe08ac7d756fL,0x06d9f4aa67d541a2L,\n        0xa3e8b68959c2cf44L } },\n    /* 56 << 14 */\n    { { 0xaad066da4d88f1ddL,0xc604f1657ad35deaL,0x7edc07204478ca67L,\n        0xa10dfae0ba02ce06L },\n      { 0xeceb1c76af36f4e4L,0x994b2292af3f8f48L,0xbf9ed77b77c8a68cL,\n        0x74f544ea51744c9dL } },\n    /* 57 << 14 */\n    { { 0x82d05bb98113a757L,0x4ef2d2b48a9885e4L,0x1e332be51aa7865fL,\n        0x22b76b18290d1a52L },\n      { 0x308a231044351683L,0x9d861896a3f22840L,0x5959ddcd841ed947L,\n        0x0def0c94154b73bfL } },\n    /* 58 << 14 */\n    { { 0xf01054174c7c15e0L,0x539bfb023a277c32L,0xe699268ef9dccf5fL,\n        0x9f5796a50247a3bdL },\n      { 0x8b839de84f157269L,0xc825c1e57a30196bL,0x6ef0aabcdc8a5a91L,\n        0xf4a8ce6c498b7fe6L } },\n    /* 59 << 14 */\n    { { 0x1cce35a770cbac78L,0x83488e9bf6b23958L,0x0341a070d76cb011L,\n        0xda6c9d06ae1b2658L },\n      { 0xb701fb30dd648c52L,0x994ca02c52fb9fd1L,0x069331176f563086L,\n        0x3d2b810017856babL } },\n    /* 60 << 14 */\n    { { 0xe89f48c85963a46eL,0x658ab875a99e61c7L,0x6e296f874b8517b4L,\n        0x36c4fcdcfc1bc656L },\n      { 0xde5227a1a3906defL,0x9fe95f5762418945L,0x20c91e81fdd96cdeL,\n        0x5adbe47eda4480deL } },\n    /* 61 << 14 */\n    { { 0xa009370f396de2b6L,0x98583d4bf0ecc7bdL,0xf44f6b57e51d0672L,\n        0x03d6b078556b1984L },\n      { 0x27dbdd93b0b64912L,0x9b3a343415687b09L,0x0dba646151ec20a9L,\n        0xec93db7fff28187cL } },\n    /* 62 << 14 */\n    { { 0x00ff8c2466e48bddL,0x2514f2f911ccd78eL,0xeba11f4fe1250603L,\n        0x8a22cd41243fa156L },\n      { 0xa4e58df4b283e4c6L,0x78c298598b39783fL,0x5235aee2a5259809L,\n        0xc16284b50e0227ddL } },\n    /* 63 << 14 */\n    { { 0xa5f579161338830dL,0x6d4b8a6bd2123fcaL,0x236ea68af9c546f8L,\n        0xc1d36873fa608d36L },\n      { 0xcd76e4958d436d13L,0xd4d9c2218fb080afL,0x665c1728e8ad3fb5L,\n        0xcf1ebe4db3d572e0L } },\n    /* 64 << 14 */\n    { { 0xa7a8746a584c5e20L,0x267e4ea1b9dc7035L,0x593a15cfb9548c9bL,\n        0x5e6e21354bd012f3L },\n      { 0xdf31cc6a8c8f936eL,0x8af84d04b5c241dcL,0x63990a6f345efb86L,\n        0x6fef4e61b9b962cbL } },\n    /* 0 << 21 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 21 */\n    { { 0xf6368f0925722608L,0x131260db131cf5c6L,0x40eb353bfab4f7acL,\n        0x85c7888037eee829L },\n      { 0x4c1581ffc3bdf24eL,0x5bff75cbf5c3c5a8L,0x35e8c83fa14e6f40L,\n        0xb81d1c0f0295e0caL } },\n    /* 2 << 21 */\n    { { 0xfcde7cc8f43a730fL,0xe89b6f3c33ab590eL,0xc823f529ad03240bL,\n        0x82b79afe98bea5dbL },\n      { 0x568f2856962fe5deL,0x0c590adb60c591f3L,0x1fc74a144a28a858L,\n        0x3b662498b3203f4cL } },\n    /* 3 << 21 */\n    { { 0x91e3cf0d6c39765aL,0xa2db3acdac3cca0bL,0x288f2f08cb953b50L,\n        0x2414582ccf43cf1aL },\n      { 0x8dec8bbc60eee9a8L,0x54c79f02729aa042L,0xd81cd5ec6532f5d5L,\n        0xa672303acf82e15fL } },\n    /* 4 << 21 */\n    { { 0x376aafa8719c0563L,0xcd8ad2dcbc5fc79fL,0x303fdb9fcb750cd3L,\n        0x14ff052f4418b08eL },\n      { 0xf75084cf3e2d6520L,0x7ebdf0f8144ed509L,0xf43bf0f2d3f25b98L,\n        0x86ad71cfa354d837L } },\n    /* 5 << 21 */\n    { { 0xb827fe9226f43572L,0xdfd3ab5b5d824758L,0x315dd23a539094c1L,\n        0x85c0e37a66623d68L },\n      { 0x575c79727be19ae0L,0x616a3396df0d36b5L,0xa1ebb3c826b1ff7eL,\n        0x635b9485140ad453L } },\n    /* 6 << 21 */\n    { { 0x92bf3cdada430c0bL,0x4702850e3a96dac6L,0xc91cf0a515ac326aL,\n        0x95de4f49ab8c25e4L },\n      { 0xb01bad09e265c17cL,0x24e45464087b3881L,0xd43e583ce1fac5caL,\n        0xe17cb3186ead97a6L } },\n    /* 7 << 21 */\n    { { 0x6cc3924374dcec46L,0x33cfc02d54c2b73fL,0x82917844f26cd99cL,\n        0x8819dd95d1773f89L },\n      { 0x09572aa60871f427L,0x8e0cf365f6f01c34L,0x7fa52988bff1f5afL,\n        0x4eb357eae75e8e50L } },\n    /* 8 << 21 */\n    { { 0xd9d0c8c4868af75dL,0xd7325cff45c8c7eaL,0xab471996cc81ecb0L,\n        0xff5d55f3611824edL },\n      { 0xbe3145411977a0eeL,0x5085c4c5722038c6L,0x2d5335bff94bb495L,\n        0x894ad8a6c8e2a082L } },\n    /* 9 << 21 */\n    { { 0x5c3e2341ada35438L,0xf4a9fc89049b8c4eL,0xbeeb355a9f17cf34L,\n        0x3f311e0e6c91fe10L },\n      { 0xc2d2003892ab9891L,0x257bdcc13e8ce9a9L,0x1b2d978988c53beeL,\n        0x927ce89acdba143aL } },\n    /* 10 << 21 */\n    { { 0xb0a32cca523db280L,0x5c889f8a50d43783L,0x503e04b34897d16fL,\n        0x8cdb6e7808f5f2e8L },\n      { 0x6ab91cf0179c8e74L,0xd8874e5248211d60L,0xf948d4d5ea851200L,\n        0x4076d41ee6f9840aL } },\n    /* 11 << 21 */\n    { { 0xc20e263c47b517eaL,0x79a448fd30685e5eL,0xe55f6f78f90631a0L,\n        0x88a790b1a79e6346L },\n      { 0x62160c7d80969fe8L,0x54f92fd441491bb9L,0xa6645c235c957526L,\n        0xf44cc5aebea3ce7bL } },\n    /* 12 << 21 */\n    { { 0xf76283278b1e68b7L,0xc731ad7a303f29d3L,0xfe5a9ca957d03ecbL,\n        0x96c0d50c41bc97a7L },\n      { 0xc4669fe79b4f7f24L,0xfdd781d83d9967efL,0x7892c7c35d2c208dL,\n        0x8bf64f7cae545cb3L } },\n    /* 13 << 21 */\n    { { 0xc01f862c467be912L,0xf4c85ee9c73d30ccL,0x1fa6f4be6ab83ec7L,\n        0xa07a3c1c4e3e3cf9L },\n      { 0x87f8ef450c00beb3L,0x30e2c2b3000d4c3eL,0x1aa00b94fe08bf5bL,\n        0x32c133aa9224ef52L } },\n    /* 14 << 21 */\n    { { 0x38df16bb32e5685dL,0x68a9e06958e6f544L,0x495aaff7cdc5ebc6L,\n        0xf894a645378b135fL },\n      { 0xf316350a09e27ecfL,0xeced201e58f7179dL,0x2eec273ce97861baL,\n        0x47ec2caed693be2eL } },\n    /* 15 << 21 */\n    { { 0xfa4c97c4f68367ceL,0xe4f47d0bbe5a5755L,0x17de815db298a979L,\n        0xd7eca659c177dc7dL },\n      { 0x20fdbb7149ded0a3L,0x4cb2aad4fb34d3c5L,0x2cf31d2860858a33L,\n        0x3b6873efa24aa40fL } },\n    /* 16 << 21 */\n    { { 0x540234b22c11bb37L,0x2d0366dded4c74a3L,0xf9a968daeec5f25dL,\n        0x3660106867b63142L },\n      { 0x07cd6d2c68d7b6d4L,0xa8f74f090c842942L,0xe27514047768b1eeL,\n        0x4b5f7e89fe62aee4L } },\n    /* 17 << 21 */\n    { { 0xc6a7717789070d26L,0xa1f28e4edd1c8bc7L,0xea5f4f06469e1f17L,\n        0x78fc242afbdb78e0L },\n      { 0xc9c7c5928b0588f1L,0xb6b7a0fd1535921eL,0xcc5bdb91bde5ae35L,\n        0xb42c485e12ff1864L } },\n    /* 18 << 21 */\n    { { 0xa1113e13dbab98aaL,0xde9d469ba17b1024L,0x23f48b37c0462d3aL,\n        0x3752e5377c5c078dL },\n      { 0xe3a86add15544eb9L,0xf013aea780fba279L,0x8b5bb76cf22001b5L,\n        0xe617ba14f02891abL } },\n    /* 19 << 21 */\n    { { 0xd39182a6936219d3L,0x5ce1f194ae51cb19L,0xc78f8598bf07a74cL,\n        0x6d7158f222cbf1bcL },\n      { 0x3b846b21e300ce18L,0x35fba6302d11275dL,0x5fe25c36a0239b9bL,\n        0xd8beb35ddf05d940L } },\n    /* 20 << 21 */\n    { { 0x4db02bb01f7e320dL,0x0641c3646da320eaL,0x6d95fa5d821389a3L,\n        0x926997488fcd8e3dL },\n      { 0x316fef17ceb6c143L,0x67fcb841d933762bL,0xbb837e35118b17f8L,\n        0x4b92552f9fd24821L } },\n    /* 21 << 21 */\n    { { 0xae6bc70e46aca793L,0x1cf0b0e4e579311bL,0x8dc631be5802f716L,\n        0x099bdc6fbddbee4dL },\n      { 0xcc352bb20caf8b05L,0xf74d505a72d63df2L,0xb9876d4b91c4f408L,\n        0x1ce184739e229b2dL } },\n    /* 22 << 21 */\n    { { 0x4950759783abdb4aL,0x850fbcb6dee84b18L,0x6325236e609e67dcL,\n        0x04d831d99336c6d8L },\n      { 0x8deaae3bfa12d45dL,0xe425f8ce4746e246L,0x8004c17524f5f31eL,\n        0xaca16d8fad62c3b7L } },\n    /* 23 << 21 */\n    { { 0x0dc15a6a9152f934L,0xf1235e5ded0e12c1L,0xc33c06ecda477dacL,\n        0x76be8732b2ea0006L },\n      { 0xcf3f78310c0cd313L,0x3c524553a614260dL,0x31a756f8cab22d15L,\n        0x03ee10d177827a20L } },\n    /* 24 << 21 */\n    { { 0xd1e059b21994ef20L,0x2a653b69638ae318L,0x70d5eb582f699010L,\n        0x279739f709f5f84aL },\n      { 0x5da4663c8b799336L,0xfdfdf14d203c37ebL,0x32d8a9dca1dbfb2dL,\n        0xab40cff077d48f9bL } },\n    /* 25 << 21 */\n    { { 0xc018b383d20b42d5L,0xf9a810ef9f78845fL,0x40af3753bdba9df0L,\n        0xb90bdcfc131dfdf9L },\n      { 0x18720591f01ab782L,0xc823f2116af12a88L,0xa51b80f30dc14401L,\n        0xde248f77fb2dfbe3L } },\n    /* 26 << 21 */\n    { { 0xef5a44e50cafe751L,0x73997c9cd4dcd221L,0x32fd86d1de854024L,\n        0xd5b53adca09b84bbL },\n      { 0x008d7a11dcedd8d1L,0x406bd1c874b32c84L,0x5d4472ff05dde8b1L,\n        0x2e25f2cdfce2b32fL } },\n    /* 27 << 21 */\n    { { 0xbec0dd5e29dfc254L,0x4455fcf62b98b267L,0x0b4d43a5c72df2adL,\n        0xea70e6be48a75397L },\n      { 0x2aad61695820f3bfL,0xf410d2dd9e37f68fL,0x70fb7dba7be5ac83L,\n        0x636bb64536ec3eecL } },\n    /* 28 << 21 */\n    { { 0x27104ea39754e21cL,0xbc87a3e68d63c373L,0x483351d74109db9aL,\n        0x0fa724e360134da7L },\n      { 0x9ff44c29b0720b16L,0x2dd0cf1306aceeadL,0x5942758ce26929a6L,\n        0x96c5db92b766a92bL } },\n    /* 29 << 21 */\n    { { 0xcec7d4c05f18395eL,0xd3f227441f80d032L,0x7a68b37acb86075bL,\n        0x074764ddafef92dbL },\n      { 0xded1e9507bc7f389L,0xc580c850b9756460L,0xaeeec2a47da48157L,\n        0x3f0b4e7f82c587b3L } },\n    /* 30 << 21 */\n    { { 0x231c6de8a9f19c53L,0x5717bd736974e34eL,0xd9e1d216f1508fa9L,\n        0x9f112361dadaa124L },\n      { 0x80145e31823b7348L,0x4dd8f0d5ac634069L,0xe3d82fc72297c258L,\n        0x276fcfee9cee7431L } },\n    /* 31 << 21 */\n    { { 0x8eb61b5e2bc0aea9L,0x4f668fd5de329431L,0x03a32ab138e4b87eL,\n        0xe137451773d0ef0bL },\n      { 0x1a46f7e6853ac983L,0xc3bdf42e68e78a57L,0xacf207852ea96dd1L,\n        0xa10649b9f1638460L } },\n    /* 32 << 21 */\n    { { 0xf2369f0b879fbbedL,0x0ff0ae86da9d1869L,0x5251d75956766f45L,\n        0x4984d8c02be8d0fcL },\n      { 0x7ecc95a6d21008f0L,0x29bd54a03a1a1c49L,0xab9828c5d26c50f3L,\n        0x32c0087c51d0d251L } },\n    /* 33 << 21 */\n    { { 0x9bac3ce60c1cdb26L,0xcd94d947557ca205L,0x1b1bd5989db1fdcdL,\n        0x0eda0108a3d8b149L },\n      { 0x9506661056152fccL,0xc2f037e6e7192b33L,0xdeffb41ac92e05a4L,\n        0x1105f6c2c2f6c62eL } },\n    /* 34 << 21 */\n    { { 0x68e735008733913cL,0xcce861633f3adc40L,0xf407a94238a278e9L,\n        0xd13c1b9d2ab21292L },\n      { 0x93ed7ec71c74cf5cL,0x8887dc48f1a4c1b4L,0x3830ff304b3a11f1L,\n        0x358c5a3c58937cb6L } },\n    /* 35 << 21 */\n    { { 0x027dc40489022829L,0x40e939773b798f79L,0x90ad333738be6eadL,\n        0x9c23f6bcf34c0a5dL },\n      { 0xd1711a35fbffd8bbL,0x60fcfb491949d3ddL,0x09c8ef4b7825d93aL,\n        0x24233cffa0a8c968L } },\n    /* 36 << 21 */\n    { { 0x67ade46ce6d982afL,0xebb6bf3ee7544d7cL,0xd6b9ba763d8bd087L,\n        0x46fe382d4dc61280L },\n      { 0xbd39a7e8b5bdbd75L,0xab381331b8f228feL,0x0709a77cce1c4300L,\n        0x6a247e56f337ceacL } },\n    /* 37 << 21 */\n    { { 0x8f34f21b636288beL,0x9dfdca74c8a7c305L,0x6decfd1bea919e04L,\n        0xcdf2688d8e1991f8L },\n      { 0xe607df44d0f8a67eL,0xd985df4b0b58d010L,0x57f834c50c24f8f4L,\n        0xe976ef56a0bf01aeL } },\n    /* 38 << 21 */\n    { { 0x536395aca1c32373L,0x351027aa734c0a13L,0xd2f1b5d65e6bd5bcL,\n        0x2b539e24223debedL },\n      { 0xd4994cec0eaa1d71L,0x2a83381d661dcf65L,0x5f1aed2f7b54c740L,\n        0x0bea3fa5d6dda5eeL } },\n    /* 39 << 21 */\n    { { 0x9d4fb68436cc6134L,0x8eb9bbf3c0a443ddL,0xfc500e2e383b7d2aL,\n        0x7aad621c5b775257L },\n      { 0x69284d740a8f7cc0L,0xe820c2ce07562d65L,0xbf9531b9499758eeL,\n        0x73e95ca56ee0cc2dL } },\n    /* 40 << 21 */\n    { { 0xf61790abfbaf50a5L,0xdf55e76b684e0750L,0xec516da7f176b005L,\n        0x575553bb7a2dddc7L },\n      { 0x37c87ca3553afa73L,0x315f3ffc4d55c251L,0xe846442aaf3e5d35L,\n        0x61b911496495ff28L } },\n    /* 41 << 21 */\n    { { 0x23cc95d3fa326dc3L,0x1df4da1f18fc2ceaL,0x24bf9adcd0a37d59L,\n        0xb6710053320d6e1eL },\n      { 0x96f9667e618344d1L,0xcc7ce042a06445afL,0xa02d8514d68dbc3aL,\n        0x4ea109e4280b5a5bL } },\n    /* 42 << 21 */\n    { { 0x5741a7acb40961bfL,0x4ada59376aa56bfaL,0x7feb914502b765d1L,\n        0x561e97bee6ad1582L },\n      { 0xbbc4a5b6da3982f5L,0x0c2659edb546f468L,0xb8e7e6aa59612d20L,\n        0xd83dfe20ac19e8e0L } },\n    /* 43 << 21 */\n    { { 0x8530c45fb835398cL,0x6106a8bfb38a41c2L,0x21e8f9a635f5dcdbL,\n        0x39707137cae498edL },\n      { 0x70c23834d8249f00L,0x9f14b58fab2537a0L,0xd043c3655f61c0c2L,\n        0xdc5926d609a194a7L } },\n    /* 44 << 21 */\n    { { 0xddec03398e77738aL,0xd07a63effba46426L,0x2e58e79cee7f6e86L,\n        0xe59b0459ff32d241L },\n      { 0xc5ec84e520fa0338L,0x97939ac8eaff5aceL,0x0310a4e3b4a38313L,\n        0x9115fba28f9d9885L } },\n    /* 45 << 21 */\n    { { 0x8dd710c25fadf8c3L,0x66be38a2ce19c0e2L,0xd42a279c4cfe5022L,\n        0x597bb5300e24e1b8L },\n      { 0x3cde86b7c153ca7fL,0xa8d30fb3707d63bdL,0xac905f92bd60d21eL,\n        0x98e7ffb67b9a54abL } },\n    /* 46 << 21 */\n    { { 0xd7147df8e9726a30L,0xb5e216ffafce3533L,0xb550b7992ff1ec40L,\n        0x6b613b87a1e953fdL },\n      { 0x87b88dba792d5610L,0x2ee1270aa190fbe1L,0x02f4e2dc2ef581daL,\n        0x016530e4eff82a95L } },\n    /* 47 << 21 */\n    { { 0xcbb93dfd8fd6ee89L,0x16d3d98646848fffL,0x600eff241da47adfL,\n        0x1b9754a00ad47a71L },\n      { 0x8f9266df70c33b98L,0xaadc87aedf34186eL,0x0d2ce8e14ad24132L,\n        0x8a47cbfc19946ebaL } },\n    /* 48 << 21 */\n    { { 0x47feeb6662b5f3afL,0xcefab5610abb3734L,0x449de60e19f35cb1L,\n        0x39f8db14157f0eb9L },\n      { 0xffaecc5b3c61bfd6L,0xa5a4d41d41216703L,0x7f8fabed224e1cc2L,\n        0x0d5a8186871ad953L } },\n    /* 49 << 21 */\n    { { 0xf10774f7d22da9a9L,0x45b8a678cc8a9b0dL,0xd9c2e722bdc32cffL,\n        0xbf71b5f5337202a5L },\n      { 0x95c57f2f69fc4db9L,0xb6dad34c765d01e1L,0x7e0bd13fcb904635L,\n        0x61751253763a588cL } },\n    /* 50 << 21 */\n    { { 0xd85c299781af2c2dL,0xc0f7d9c481b9d7daL,0x838a34ae08533e8dL,\n        0x15c4cb08311d8311L },\n      { 0x97f832858e121e14L,0xeea7dc1e85000a5fL,0x0c6059b65d256274L,\n        0xec9beaceb95075c0L } },\n    /* 51 << 21 */\n    { { 0x173daad71df97828L,0xbf851cb5a8937877L,0xb083c59401646f3cL,\n        0x3bad30cf50c6d352L },\n      { 0xfeb2b202496bbceaL,0x3cf9fd4f18a1e8baL,0xd26de7ff1c066029L,\n        0x39c81e9e4e9ed4f8L } },\n    /* 52 << 21 */\n    { { 0xd8be0cb97b390d35L,0x01df2bbd964aab27L,0x3e8c1a65c3ef64f8L,\n        0x567291d1716ed1ddL },\n      { 0x95499c6c5f5406d3L,0x71fdda395ba8e23fL,0xcfeb320ed5096eceL,\n        0xbe7ba92bca66dd16L } },\n    /* 53 << 21 */\n    { { 0x4608d36bc6fb5a7dL,0xe3eea15a6d2dd0e0L,0x75b0a3eb8f97a36aL,\n        0xf59814cc1c83de1eL },\n      { 0x56c9c5b01c33c23fL,0xa96c1da46faa4136L,0x46bf2074de316551L,\n        0x3b866e7b1f756c8fL } },\n    /* 54 << 21 */\n    { { 0x727727d81495ed6bL,0xb2394243b682dce7L,0x8ab8454e758610f3L,\n        0xc243ce84857d72a4L },\n      { 0x7b320d71dbbf370fL,0xff9afa3778e0f7caL,0x0119d1e0ea7b523fL,\n        0xb997f8cb058c7d42L } },\n    /* 55 << 21 */\n    { { 0x285bcd2a37bbb184L,0x51dcec49a45d1fa6L,0x6ade3b64e29634cbL,\n        0x080c94a726b86ef1L },\n      { 0xba583db12283fbe3L,0x902bddc85a9315edL,0x07c1ccb386964becL,\n        0x78f4eacfb6258301L } },\n    /* 56 << 21 */\n    { { 0x4bdf3a4956f90823L,0xba0f5080741d777bL,0x091d71c3f38bf760L,\n        0x9633d50f9b625b02L },\n      { 0x03ecb743b8c9de61L,0xb47512545de74720L,0x9f9defc974ce1cb2L,\n        0x774a4f6a00bd32efL } },\n    /* 57 << 21 */\n    { { 0xaca385f773848f22L,0x53dad716f3f8558eL,0xab7b34b093c471f9L,\n        0xf530e06919644bc7L },\n      { 0x3d9fb1ffdd59d31aL,0x4382e0df08daa795L,0x165c6f4bd5cc88d7L,\n        0xeaa392d54a18c900L } },\n    /* 58 << 21 */\n    { { 0x94203c67648024eeL,0x188763f28c2fabcdL,0xa80f87acbbaec835L,\n        0x632c96e0f29d8d54L },\n      { 0x29b0a60e4c00a95eL,0x2ef17f40e011e9faL,0xf6c0e1d115b77223L,\n        0xaaec2c6214b04e32L } },\n    /* 59 << 21 */\n    { { 0xd35688d83d84e58cL,0x2af5094c958571dbL,0x4fff7e19760682a6L,\n        0x4cb27077e39a407cL },\n      { 0x0f59c5474ff0e321L,0x169f34a61b34c8ffL,0x2bff109652bc1ba7L,\n        0xa25423b783583544L } },\n    /* 60 << 21 */\n    { { 0x5d55d5d50ac8b782L,0xff6622ec2db3c892L,0x48fce7416b8bb642L,\n        0x31d6998c69d7e3dcL },\n      { 0xdbaf8004cadcaed0L,0x801b0142d81d053cL,0x94b189fc59630ec6L,\n        0x120e9934af762c8eL } },\n    /* 61 << 21 */\n    { { 0x53a29aa4fdc6a404L,0x19d8e01ea1909948L,0x3cfcabf1d7e89681L,\n        0x3321a50d4e132d37L },\n      { 0xd0496863e9a86111L,0x8c0cde6106a3bc65L,0xaf866c49fc9f8eefL,\n        0x2066350eff7f5141L } },\n    /* 62 << 21 */\n    { { 0x4f8a4689e56ddfbdL,0xea1b0c07fe32983aL,0x2b317462873cb8cbL,\n        0x658deddc2d93229fL },\n      { 0x65efaf4d0f64ef58L,0xfe43287d730cc7a8L,0xaebc0c723d047d70L,\n        0x92efa539d92d26c9L } },\n    /* 63 << 21 */\n    { { 0x06e7845794b56526L,0x415cb80f0961002dL,0x89e5c56576dcb10fL,\n        0x8bbb6982ff9259feL },\n      { 0x4fe8795b9abc2668L,0xb5d4f5341e678fb1L,0x6601f3be7b7da2b9L,\n        0x98da59e2a13d6805L } },\n    /* 64 << 21 */\n    { { 0x190d8ea601799a52L,0xa20cec41b86d2952L,0x3062ffb27fff2a7cL,\n        0x741b32e579f19d37L },\n      { 0xf80d81814eb57d47L,0x7a2d0ed416aef06bL,0x09735fb01cecb588L,\n        0x1641caaac6061f5bL } },\n    /* 0 << 28 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 28 */\n    { { 0x7f99824f20151427L,0x206828b692430206L,0xaa9097d7e1112357L,\n        0xacf9a2f209e414ecL },\n      { 0xdbdac9da27915356L,0x7e0734b7001efee3L,0x54fab5bbd2b288e2L,\n        0x4c630fc4f62dd09cL } },\n    /* 2 << 28 */\n    { { 0x8537107a1ac2703bL,0xb49258d86bc857b5L,0x57df14debcdaccd1L,\n        0x24ab68d7c4ae8529L },\n      { 0x7ed8b5d4734e59d0L,0x5f8740c8c495cc80L,0x84aedd5a291db9b3L,\n        0x80b360f84fb995beL } },\n    /* 3 << 28 */\n    { { 0xae915f5d5fa067d1L,0x4134b57f9668960cL,0xbd3656d6a48edaacL,\n        0xdac1e3e4fc1d7436L },\n      { 0x674ff869d81fbb26L,0x449ed3ecb26c33d4L,0x85138705d94203e8L,\n        0xccde538bbeeb6f4aL } },\n    /* 4 << 28 */\n    { { 0x55d5c68da61a76faL,0x598b441dca1554dcL,0xd39923b9773b279cL,\n        0x33331d3c36bf9efcL },\n      { 0x2d4c848e298de399L,0xcfdb8e77a1a27f56L,0x94c855ea57b8ab70L,\n        0xdcdb9dae6f7879baL } },\n    /* 5 << 28 */\n    { { 0x7bdff8c2019f2a59L,0xb3ce5bb3cb4fbc74L,0xea907f688a9173ddL,\n        0x6cd3d0d395a75439L },\n      { 0x92ecc4d6efed021cL,0x09a9f9b06a77339aL,0x87ca6b157188c64aL,\n        0x10c2996844899158L } },\n    /* 6 << 28 */\n    { { 0x5859a229ed6e82efL,0x16f338e365ebaf4eL,0x0cd313875ead67aeL,\n        0x1c73d22854ef0bb4L },\n      { 0x4cb5513174a5c8c7L,0x01cd29707f69ad6aL,0xa04d00dde966f87eL,\n        0xd96fe4470b7b0321L } },\n    /* 7 << 28 */\n    { { 0x342ac06e88fbd381L,0x02cd4a845c35a493L,0xe8fa89de54f1bbcdL,\n        0x341d63672575ed4cL },\n      { 0xebe357fbd238202bL,0x600b4d1aa984ead9L,0xc35c9f4452436ea0L,\n        0x96fe0a39a370751bL } },\n    /* 8 << 28 */\n    { { 0x4c4f07367f636a38L,0x9f943fb70e76d5cbL,0xb03510baa8b68b8bL,\n        0xc246780a9ed07a1fL },\n      { 0x3c0514156d549fc2L,0xc2953f31607781caL,0x955e2c69d8d95413L,\n        0xb300fadc7bd282e3L } },\n    /* 9 << 28 */\n    { { 0x81fe7b5087e9189fL,0xdb17375cf42dda27L,0x22f7d896cf0a5904L,\n        0xa0e57c5aebe348e6L },\n      { 0xa61011d3f40e3c80L,0xb11893218db705c5L,0x4ed9309e50fedec3L,\n        0xdcf14a104d6d5c1dL } },\n    /* 10 << 28 */\n    { { 0x056c265b55691342L,0xe8e0850491049dc7L,0x131329f5c9bae20aL,\n        0x96c8b3e8d9dccdb4L },\n      { 0x8c5ff838fb4ee6b4L,0xfc5a9aeb41e8ccf0L,0x7417b764fae050c6L,\n        0x0953c3d700452080L } },\n    /* 11 << 28 */\n    { { 0x2137268238dfe7e8L,0xea417e152bb79d4bL,0x59641f1c76e7cf2dL,\n        0x271e3059ea0bcfccL },\n      { 0x624c7dfd7253ecbdL,0x2f552e254fca6186L,0xcbf84ecd4d866e9cL,\n        0x73967709f68d4610L } },\n    /* 12 << 28 */\n    { { 0xa14b1163c27901b4L,0xfd9236e0899b8bf3L,0x42b091eccbc6da0aL,\n        0xbb1dac6f5ad1d297L },\n      { 0x80e61d53a91cf76eL,0x4110a412d31f1ee7L,0x2d87c3ba13efcf77L,\n        0x1f374bb4df450d76L } },\n    /* 13 << 28 */\n    { { 0x5e78e2f20d188dabL,0xe3968ed0f4b885efL,0x46c0568e7314570fL,\n        0x3161633801170521L },\n      { 0x18e1e7e24f0c8afeL,0x4caa75ffdeea78daL,0x82db67f27c5d8a51L,\n        0x36a44d866f505370L } },\n    /* 14 << 28 */\n    { { 0xd72c5bda0333974fL,0x5db516ae27a70146L,0x34705281210ef921L,\n        0xbff17a8f0c9c38e5L },\n      { 0x78f4814e12476da1L,0xc1e1661333c16980L,0x9e5b386f424d4bcaL,\n        0x4c274e87c85740deL } },\n    /* 15 << 28 */\n    { { 0xb6a9b88d6c2f5226L,0x14d1b944550d7ca8L,0x580c85fc1fc41709L,\n        0xc1da368b54c6d519L },\n      { 0x2b0785ced5113cf7L,0x0670f6335a34708fL,0x46e2376715cc3f88L,\n        0x1b480cfa50c72c8fL } },\n    /* 16 << 28 */\n    { { 0x202886024147519aL,0xd0981eac26b372f0L,0xa9d4a7caa785ebc8L,\n        0xd953c50ddbdf58e9L },\n      { 0x9d6361ccfd590f8fL,0x72e9626b44e6c917L,0x7fd9611022eb64cfL,\n        0x863ebb7e9eb288f3L } },\n    /* 17 << 28 */\n    { { 0x6e6ab7616aca8ee7L,0x97d10b39d7b40358L,0x1687d3771e5feb0dL,\n        0xc83e50e48265a27aL },\n      { 0x8f75a9fec954b313L,0xcc2e8f47310d1f61L,0xf5ba81c56557d0e0L,\n        0x25f9680c3eaf6207L } },\n    /* 18 << 28 */\n    { { 0xf95c66094354080bL,0x5225bfa57bf2fe1cL,0xc5c004e25c7d98faL,\n        0x3561bf1c019aaf60L },\n      { 0x5e6f9f17ba151474L,0xdec2f934b04f6ecaL,0x64e368a1269acb1eL,\n        0x1332d9e40cdda493L } },\n    /* 19 << 28 */\n    { { 0x60d6cf69df23de05L,0x66d17da2009339a0L,0x9fcac9850a693923L,\n        0xbcf057fced7c6a6dL },\n      { 0xc3c5c8c5f0b5662cL,0x25318dd8dcba4f24L,0x60e8cb75082b69ffL,\n        0x7c23b3ee1e728c01L } },\n    /* 20 << 28 */\n    { { 0x15e10a0a097e4403L,0xcb3d0a8619854665L,0x88d8e211d67d4826L,\n        0xb39af66e0b9d2839L },\n      { 0xa5f94588bd475ca8L,0xe06b7966c077b80bL,0xfedb1485da27c26cL,\n        0xd290d33afe0fd5e0L } },\n    /* 21 << 28 */\n    { { 0xa40bcc47f34fb0faL,0xb4760cc81fb1ab09L,0x8fca0993a273bfe3L,\n        0x13e4fe07f70b213cL },\n      { 0x3bcdb992fdb05163L,0x8c484b110c2b19b6L,0x1acb815faaf2e3e2L,\n        0xc6905935b89ff1b4L } },\n    /* 22 << 28 */\n    { { 0xb2ad6f9d586e74e1L,0x488883ad67b80484L,0x758aa2c7369c3ddbL,\n        0x8ab74e699f9afd31L },\n      { 0x10fc2d285e21beb1L,0x3484518a318c42f9L,0x377427dc53cf40c3L,\n        0x9de0781a391bc1d9L } },\n    /* 23 << 28 */\n    { { 0x8faee858693807e1L,0xa38653274e81ccc7L,0x02c30ff26f835b84L,\n        0xb604437b0d3d38d4L },\n      { 0xb3fc8a985ca1823dL,0xb82f7ec903be0324L,0xee36d761cf684a33L,\n        0x5a01df0e9f29bf7dL } },\n    /* 24 << 28 */\n    { { 0x686202f31306583dL,0x05b10da0437c622eL,0xbf9aaa0f076a7bc8L,\n        0x25e94efb8f8f4e43L },\n      { 0x8a35c9b7fa3dc26dL,0xe0e5fb9396ff03c5L,0xa77e3843ebc394ceL,\n        0xcede65958361de60L } },\n    /* 25 << 28 */\n    { { 0xd27c22f6a1993545L,0xab01cc3624d671baL,0x63fa2877a169c28eL,\n        0x925ef9042eb08376L },\n      { 0x3b2fa3cf53aa0b32L,0xb27beb5b71c49d7aL,0xb60e1834d105e27fL,\n        0xd60897884f68570dL } },\n    /* 26 << 28 */\n    { { 0x23094ce0d6fbc2acL,0x738037a1815ff551L,0xda73b1bb6bef119cL,\n        0xdcf6c430eef506baL },\n      { 0x00e4fe7be3ef104aL,0xebdd9a2c0a065628L,0x853a81c38792043eL,\n        0x22ad6eceb3b59108L } },\n    /* 27 << 28 */\n    { { 0x9fb813c039cd297dL,0x8ec7e16e05bda5d9L,0x2834797c0d104b96L,\n        0xcc11a2e77c511510L },\n      { 0x96ca5a5396ee6380L,0x054c8655cea38742L,0xb5946852d54dfa7dL,\n        0x97c422e71f4ab207L } },\n    /* 28 << 28 */\n    { { 0xbf9075090c22b540L,0x2cde42aab7c267d4L,0xba18f9ed5ab0d693L,\n        0x3ba62aa66e4660d9L },\n      { 0xb24bf97bab9ea96aL,0x5d039642e3b60e32L,0x4e6a45067c4d9bd5L,\n        0x666c5b9e7ed4a6a4L } },\n    /* 29 << 28 */\n    { { 0xfa3fdcd98edbd7ccL,0x4660bb87c6ccd753L,0x9ae9082021e6b64fL,\n        0x8a56a713b36bfb3fL },\n      { 0xabfce0965726d47fL,0x9eed01b20b1a9a7fL,0x30e9cad44eb74a37L,\n        0x7b2524cc53e9666dL } },\n    /* 30 << 28 */\n    { { 0x6a29683b8f4b002fL,0xc2200d7a41f4fc20L,0xcf3af47a3a338accL,\n        0x6539a4fbe7128975L },\n      { 0xcec31c14c33c7fcfL,0x7eb6799bc7be322bL,0x119ef4e96646f623L,\n        0x7b7a26a554d7299bL } },\n    /* 31 << 28 */\n    { { 0xcb37f08d403f46f2L,0x94b8fc431a0ec0c7L,0xbb8514e3c332142fL,\n        0xf3ed2c33e80d2a7aL },\n      { 0x8d2080afb639126cL,0xf7b6be60e3553adeL,0x3950aa9f1c7e2b09L,\n        0x847ff9586410f02bL } },\n    /* 32 << 28 */\n    { { 0x877b7cf5678a31b0L,0xd50301ae3998b620L,0x734257c5c00fb396L,\n        0xf9fb18a004e672a6L },\n      { 0xff8bd8ebe8758851L,0x1e64e4c65d99ba44L,0x4b8eaedf7dfd93b7L,\n        0xba2f2a9804e76b8cL } },\n    /* 33 << 28 */\n    { { 0x7d790cbae8053433L,0xc8e725a03d2c9585L,0x58c5c476cdd8f5edL,\n        0xd106b952efa9fe1dL },\n      { 0x3c5c775b0eff13a9L,0x242442bae057b930L,0xe9f458d4c9b70cbdL,\n        0x69b71448a3cdb89aL } },\n    /* 34 << 28 */\n    { { 0x41ee46f60e2ed742L,0x573f104540067493L,0xb1e154ff9d54c304L,\n        0x2ad0436a8d3a7502L },\n      { 0xee4aaa2d431a8121L,0xcd38b3ab886f11edL,0x57d49ea6034a0eb7L,\n        0xd2b773bdf7e85e58L } },\n    /* 35 << 28 */\n    { { 0x4a559ac49b5c1f14L,0xc444be1a3e54df2bL,0x13aad704eda41891L,\n        0xcd927bec5eb5c788L },\n      { 0xeb3c8516e48c8a34L,0x1b7ac8124b546669L,0x1815f896594df8ecL,\n        0x87c6a79c79227865L } },\n    /* 36 << 28 */\n    { { 0xae02a2f09b56ddbdL,0x1339b5ac8a2f1cf3L,0xf2b569c7839dff0dL,\n        0xb0b9e864fee9a43dL },\n      { 0x4ff8ca4177bb064eL,0x145a2812fd249f63L,0x3ab7beacf86f689aL,\n        0x9bafec2701d35f5eL } },\n    /* 37 << 28 */\n    { { 0x28054c654265aa91L,0xa4b18304035efe42L,0x6887b0e69639dec7L,\n        0xf4b8f6ad3d52aea5L },\n      { 0xfb9293cc971a8a13L,0x3f159e5d4c934d07L,0x2c50e9b109acbc29L,\n        0x08eb65e67154d129L } },\n    /* 38 << 28 */\n    { { 0x4feff58930b75c3eL,0x0bb82fe294491c93L,0xd8ac377a89af62bbL,\n        0xd7b514909685e49fL },\n      { 0xabca9a7b04497f19L,0x1b35ed0a1a7ad13fL,0x6b601e213ec86ed6L,\n        0xda91fcb9ce0c76f1L } },\n    /* 39 << 28 */\n    { { 0x9e28507bd7ab27e1L,0x7c19a55563945b7bL,0x6b43f0a1aafc9827L,\n        0x443b4fbd3aa55b91L },\n      { 0x962b2e656962c88fL,0x139da8d4ce0db0caL,0xb93f05dd1b8d6c4fL,\n        0x779cdff7180b9824L } },\n    /* 40 << 28 */\n    { { 0xbba23fddae57c7b7L,0x345342f21b932522L,0xfd9c80fe556d4aa3L,\n        0xa03907ba6525bb61L },\n      { 0x38b010e1ff218933L,0xc066b654aa52117bL,0x8e14192094f2e6eaL,\n        0x66a27dca0d32f2b2L } },\n    /* 41 << 28 */\n    { { 0x69c7f993048b3717L,0xbf5a989ab178ae1cL,0x49fa9058564f1d6bL,\n        0x27ec6e15d31fde4eL },\n      { 0x4cce03737276e7fcL,0x64086d7989d6bf02L,0x5a72f0464ccdd979L,\n        0x909c356647775631L } },\n    /* 42 << 28 */\n    { { 0x1c07bc6b75dd7125L,0xb4c6bc9787a0428dL,0x507ece52fdeb6b9dL,\n        0xfca56512b2c95432L },\n      { 0x15d97181d0e8bd06L,0x384dd317c6bb46eaL,0x5441ea203952b624L,\n        0xbcf70dee4e7dc2fbL } },\n    /* 43 << 28 */\n    { { 0x372b016e6628e8c3L,0x07a0d667b60a7522L,0xcf05751b0a344ee2L,\n        0x0ec09a48118bdeecL },\n      { 0x6e4b3d4ed83dce46L,0x43a6316d99d2fc6eL,0xa99d898956cf044cL,\n        0x7c7f4454ae3e5fb7L } },\n    /* 44 << 28 */\n    { { 0xb2e6b121fbabbe92L,0x281850fbe1330076L,0x093581ec97890015L,\n        0x69b1dded75ff77f5L },\n      { 0x7cf0b18fab105105L,0x953ced31a89ccfefL,0x3151f85feb914009L,\n        0x3c9f1b8788ed48adL } },\n    /* 45 << 28 */\n    { { 0xc9aba1a14a7eadcbL,0x928e7501522e71cfL,0xeaede7273a2e4f83L,\n        0x467e10d11ce3bbd3L },\n      { 0xf3442ac3b955dcf0L,0xba96307dd3d5e527L,0xf763a10efd77f474L,\n        0x5d744bd06a6e1ff0L } },\n    /* 46 << 28 */\n    { { 0xd287282aa777899eL,0xe20eda8fd03f3cdeL,0x6a7e75bb50b07d31L,\n        0x0b7e2a946f379de4L },\n      { 0x31cb64ad19f593cfL,0x7b1a9e4f1e76ef1dL,0xe18c9c9db62d609cL,\n        0x439bad6de779a650L } },\n    /* 47 << 28 */\n    { { 0x219d9066e032f144L,0x1db632b8e8b2ec6aL,0xff0d0fd4fda12f78L,\n        0x56fb4c2d2a25d265L },\n      { 0x5f4e2ee1255a03f1L,0x61cd6af2e96af176L,0xe0317ba8d068bc97L,\n        0x927d6bab264b988eL } },\n    /* 48 << 28 */\n    { { 0xa18f07e0e90fb21eL,0x00fd2b80bba7fca1L,0x20387f2795cd67b5L,\n        0x5b89a4e7d39707f7L },\n      { 0x8f83ad3f894407ceL,0xa0025b946c226132L,0xc79563c7f906c13bL,\n        0x5f548f314e7bb025L } },\n    /* 49 << 28 */\n    { { 0x2b4c6b8feac6d113L,0xa67e3f9c0e813c76L,0x3982717c3fe1f4b9L,\n        0x5886581926d8050eL },\n      { 0x99f3640cf7f06f20L,0xdc6102162a66ebc2L,0x52f2c175767a1e08L,\n        0x05660e1a5999871bL } },\n    /* 50 << 28 */\n    { { 0x6b0f17626d3c4693L,0xf0e7d62737ed7beaL,0xc51758c7b75b226dL,\n        0x40a886281f91613bL },\n      { 0x889dbaa7bbb38ce0L,0xe0404b65bddcad81L,0xfebccd3a8bc9671fL,\n        0xfbf9a357ee1f5375L } },\n    /* 51 << 28 */\n    { { 0x5dc169b028f33398L,0xb07ec11d72e90f65L,0xae7f3b4afaab1eb1L,\n        0xd970195e5f17538aL },\n      { 0x52b05cbe0181e640L,0xf5debd622643313dL,0x761481545df31f82L,\n        0x23e03b333a9e13c5L } },\n    /* 52 << 28 */\n    { { 0xff7589494fde0c1fL,0xbf8a1abee5b6ec20L,0x702278fb87e1db6cL,\n        0xc447ad7a35ed658fL },\n      { 0x48d4aa3803d0ccf2L,0x80acb338819a7c03L,0x9bc7c89e6e17ceccL,\n        0x46736b8b03be1d82L } },\n    /* 53 << 28 */\n    { { 0xd65d7b60c0432f96L,0xddebe7a3deb5442fL,0x79a253077dff69a2L,\n        0x37a56d9402cf3122L },\n      { 0x8bab8aedf2350d0aL,0x13c3f276037b0d9aL,0xc664957c44c65caeL,\n        0x88b44089c2e71a88L } },\n    /* 54 << 28 */\n    { { 0xdb88e5a35cb02664L,0x5d4c0bf18686c72eL,0xea3d9b62a682d53eL,\n        0x9b605ef40b2ad431L },\n      { 0x71bac202c69645d0L,0xa115f03a6a1b66e7L,0xfe2c563a158f4dc4L,\n        0xf715b3a04d12a78cL } },\n    /* 55 << 28 */\n    { { 0x8f7f0a48d413213aL,0x2035806dc04becdbL,0xecd34a995d8587f5L,\n        0x4d8c30799f6d3a71L },\n      { 0x1b2a2a678d95a8f6L,0xc58c9d7df2110d0dL,0xdeee81d5cf8fba3fL,\n        0xa42be3c00c7cdf68L } },\n    /* 56 << 28 */\n    { { 0x2126f742d43b5eaaL,0x054a0766dfa59b85L,0x9d0d5e36126bfd45L,\n        0xa1f8fbd7384f8a8fL },\n      { 0x317680f5d563fcccL,0x48ca5055f280a928L,0xe00b81b227b578cfL,\n        0x10aad9182994a514L } },\n    /* 57 << 28 */\n    { { 0xd9e07b62b7bdc953L,0x9f0f6ff25bc086ddL,0x09d1ccff655eee77L,\n        0x45475f795bef7df1L },\n      { 0x3faa28fa86f702ccL,0x92e609050f021f07L,0xe9e629687f8fa8c6L,\n        0xbd71419af036ea2cL } },\n    /* 58 << 28 */\n    { { 0x171ee1cc6028da9aL,0x5352fe1ac251f573L,0xf8ff236e3fa997f4L,\n        0xd831b6c9a5749d5fL },\n      { 0x7c872e1de350e2c2L,0xc56240d91e0ce403L,0xf9deb0776974f5cbL,\n        0x7d50ba87961c3728L } },\n    /* 59 << 28 */\n    { { 0xd6f894265a3a2518L,0xcf817799c6303d43L,0x510a0471619e5696L,\n        0xab049ff63a5e307bL },\n      { 0xe4cdf9b0feb13ec7L,0xd5e971179d8ff90cL,0xf6f64d069afa96afL,\n        0x00d0bf5e9d2012a2L } },\n    /* 60 << 28 */\n    { { 0xe63f301f358bcdc0L,0x07689e990a9d47f8L,0x1f689e2f4f43d43aL,\n        0x4d542a1690920904L },\n      { 0xaea293d59ca0a707L,0xd061fe458ac68065L,0x1033bf1b0090008cL,\n        0x29749558c08a6db6L } },\n    /* 61 << 28 */\n    { { 0x74b5fc59c1d5d034L,0xf712e9f667e215e0L,0xfd520cbd860200e6L,\n        0x0229acb43ea22588L },\n      { 0x9cd1e14cfff0c82eL,0x87684b6259c69e73L,0xda85e61c96ccb989L,\n        0x2d5dbb02a3d06493L } },\n    /* 62 << 28 */\n    { { 0xf22ad33ae86b173cL,0xe8e41ea5a79ff0e3L,0x01d2d725dd0d0c10L,\n        0x31f39088032d28f9L },\n      { 0x7b3f71e17829839eL,0x0cf691b44502ae58L,0xef658dbdbefc6115L,\n        0xa5cd6ee5b3ab5314L } },\n    /* 63 << 28 */\n    { { 0x206c8d7b5f1d2347L,0x794645ba4cc2253aL,0xd517d8ff58389e08L,\n        0x4fa20dee9f847288L },\n      { 0xeba072d8d797770aL,0x7360c91dbf429e26L,0x7200a3b380af8279L,\n        0x6a1c915082dadce3L } },\n    /* 64 << 28 */\n    { { 0x0ee6d3a7c35d8794L,0x042e65580356bae5L,0x9f59698d643322fdL,\n        0x9379ae1550a61967L },\n      { 0x64b9ae62fcc9981eL,0xaed3d6316d2934c6L,0x2454b3025e4e65ebL,\n        0xab09f647f9950428L } },\n    /* 0 << 35 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 35 */\n    { { 0xb2083a1222248accL,0x1f6ec0ef3264e366L,0x5659b7045afdee28L,\n        0x7a823a40e6430bb5L },\n      { 0x24592a04e1900a79L,0xcde09d4ac9ee6576L,0x52b6463f4b5ea54aL,\n        0x1efe9ed3d3ca65a7L } },\n    /* 2 << 35 */\n    { { 0xe27a6dbe305406ddL,0x8eb7dc7fdd5d1957L,0xf54a6876387d4d8fL,\n        0x9c479409c7762de4L },\n      { 0xbe4d5b5d99b30778L,0x25380c566e793682L,0x602d37f3dac740e3L,\n        0x140deabe1566e4aeL } },\n    /* 3 << 35 */\n    { { 0x4481d067afd32acfL,0xd8f0fccae1f71ccfL,0xd208dd0cb596f2daL,\n        0xd049d7309aad93f9L },\n      { 0xc79f263d42ab580eL,0x09411bb123f707b4L,0x8cfde1ff835e0edaL,\n        0x7270749090f03402L } },\n    /* 4 << 35 */\n    { { 0xeaee6126c49a861eL,0x024f3b65e14f0d06L,0x51a3f1e8c69bfc17L,\n        0xc3c3a8e9a7686381L },\n      { 0x3400752cb103d4c8L,0x02bc46139218b36bL,0xc67f75eb7651504aL,\n        0xd6848b56d02aebfaL } },\n    /* 5 << 35 */\n    { { 0xbd9802e6c30fa92bL,0x5a70d96d9a552784L,0x9085c4ea3f83169bL,\n        0xfa9423bb06908228L },\n      { 0x2ffebe12fe97a5b9L,0x85da604971b99118L,0x9cbc2f7f63178846L,\n        0xfd96bc709153218eL } },\n    /* 6 << 35 */\n    { { 0x958381db1782269bL,0xae34bf792597e550L,0xbb5c60645f385153L,\n        0x6f0e96afe3088048L },\n      { 0xbf6a021577884456L,0xb3b5688c69310ea7L,0x17c9429504fad2deL,\n        0xe020f0e517896d4dL } },\n    /* 7 << 35 */\n    { { 0x730ba0ab0976505fL,0x567f6813095e2ec5L,0x470620106331ab71L,\n        0x72cfa97741d22b9fL },\n      { 0x33e55ead8a2373daL,0xa8d0d5f47ba45a68L,0xba1d8f9c03029d15L,\n        0x8f34f1ccfc55b9f3L } },\n    /* 8 << 35 */\n    { { 0xcca4428dbbe5a1a9L,0x8187fd5f3126bd67L,0x0036973a48105826L,\n        0xa39b6663b8bd61a0L },\n      { 0x6d42deef2d65a808L,0x4969044f94636b19L,0xf611ee47dd5d564cL,\n        0x7b2f3a49d2873077L } },\n    /* 9 << 35 */\n    { { 0x94157d45300eb294L,0x2b2a656e169c1494L,0xc000dd76d3a47aa9L,\n        0xa2864e4fa6243ea4L },\n      { 0x82716c47db89842eL,0x12dfd7d761479fb7L,0x3b9a2c56e0b2f6dcL,\n        0x46be862ad7f85d67L } },\n    /* 10 << 35 */\n    { { 0x03b0d8dd0f82b214L,0x460c34f9f103cbc6L,0xf32e5c0318d79e19L,\n        0x8b8888baa84117f8L },\n      { 0x8f3c37dcc0722677L,0x10d21be91c1c0f27L,0xd47c8468e0f7a0c6L,\n        0x9bf02213adecc0e0L } },\n    /* 11 << 35 */\n    { { 0x0baa7d1242b48b99L,0x1bcb665d48424096L,0x8b847cd6ebfb5cfbL,\n        0x87c2ae569ad4d10dL },\n      { 0xf1cbb1220de36726L,0xe7043c683fdfbd21L,0x4bd0826a4e79d460L,\n        0x11f5e5984bd1a2cbL } },\n    /* 12 << 35 */\n    { { 0x97554160b7fe7b6eL,0x7d16189a400a3fb2L,0xd73e9beae328ca1eL,\n        0x0dd04b97e793d8ccL },\n      { 0xa9c83c9b506db8ccL,0x5cd47aaecf38814cL,0x26fc430db64b45e6L,\n        0x079b5499d818ea84L } },\n    /* 13 << 35 */\n    { { 0xebb01102c1c24a3bL,0xca24e5681c161c1aL,0x103eea6936f00a4aL,\n        0x9ad76ee876176c7bL },\n      { 0x97451fc2538e0ff7L,0x94f898096604b3b0L,0x6311436e3249cfd7L,\n        0x27b4a7bd41224f69L } },\n    /* 14 << 35 */\n    { { 0x03b5d21ae0ac2941L,0x279b0254c2d31937L,0x3307c052cac992d0L,\n        0x6aa7cb92efa8b1f3L },\n      { 0x5a1825800d37c7a5L,0x13380c37342d5422L,0x92ac2d66d5d2ef92L,\n        0x035a70c9030c63c6L } },\n    /* 15 << 35 */\n    { { 0xc16025dd4ce4f152L,0x1f419a71f9df7c06L,0x6d5b221491e4bb14L,\n        0xfc43c6cc839fb4ceL },\n      { 0x49f06591925d6b2dL,0x4b37d9d362186598L,0x8c54a971d01b1629L,\n        0xe1a9c29f51d50e05L } },\n    /* 16 << 35 */\n    { { 0x5109b78571ba1861L,0x48b22d5cd0c8f93dL,0xe8fa84a78633bb93L,\n        0x53fba6ba5aebbd08L },\n      { 0x7ff27df3e5eea7d8L,0x521c879668ca7158L,0xb9d5133bce6f1a05L,\n        0x2d50cd53fd0ebee4L } },\n    /* 17 << 35 */\n    { { 0xc82115d6c5a3ef16L,0x993eff9dba079221L,0xe4da2c5e4b5da81cL,\n        0x9a89dbdb8033fd85L },\n      { 0x60819ebf2b892891L,0x53902b215d14a4d5L,0x6ac35051d7fda421L,\n        0xcc6ab88561c83284L } },\n    /* 18 << 35 */\n    { { 0x14eba133f74cff17L,0x240aaa03ecb813f2L,0xcfbb65406f665beeL,\n        0x084b1fe4a425ad73L },\n      { 0x009d5d16d081f6a6L,0x35304fe8eef82c90L,0xf20346d5aa9eaa22L,\n        0x0ada9f07ac1c91e3L } },\n    /* 19 << 35 */\n    { { 0xa6e21678968a6144L,0x54c1f77c07b31a1eL,0xd6bb787e5781fbe1L,\n        0x61bd2ee0e31f1c4aL },\n      { 0xf25aa1e9781105fcL,0x9cf2971f7b2f8e80L,0x26d15412cdff919bL,\n        0x01db4ebe34bc896eL } },\n    /* 20 << 35 */\n    { { 0x7d9b3e23b40df1cfL,0x5933737394e971b4L,0xbf57bd14669cf921L,\n        0x865daedf0c1a1064L },\n      { 0x3eb70bd383279125L,0xbc3d5b9f34ecdaabL,0x91e3ed7e5f755cafL,\n        0x49699f54d41e6f02L } },\n    /* 21 << 35 */\n    { { 0x185770e1d4a7a15bL,0x08f3587aeaac87e7L,0x352018db473133eaL,\n        0x674ce71904fd30fcL },\n      { 0x7b8d9835088b3e0eL,0x7a0356a95d0d47a1L,0x9d9e76596474a3c4L,\n        0x61ea48a7ff66966cL } },\n    /* 22 << 35 */\n    { { 0x304177580f3e4834L,0xfdbb21c217a9afcbL,0x756fa17f2f9a67b3L,\n        0x2a6b2421a245c1a8L },\n      { 0x64be27944af02291L,0xade465c62a5804feL,0x8dffbd39a6f08fd7L,\n        0xc4efa84caa14403bL } },\n    /* 23 << 35 */\n    { { 0xa1b91b2a442b0f5cL,0xb748e317cf997736L,0x8d1b62bfcee90e16L,\n        0x907ae2710b2078c0L },\n      { 0xdf31534b0c9bcdddL,0x043fb05439adce83L,0x99031043d826846aL,\n        0x61a9c0d6b144f393L } },\n    /* 24 << 35 */\n    { { 0xdab4804647718427L,0xdf17ff9b6e830f8bL,0x408d7ee8e49a1347L,\n        0x6ac71e2391c1d4aeL },\n      { 0xc8cbb9fd1defd73cL,0x19840657bbbbfec5L,0x39db1cb59e7ef8eaL,\n        0x78aa829664105f30L } },\n    /* 25 << 35 */\n    { { 0xa3d9b7f0a3738c29L,0x0a2f235abc3250a3L,0x55e506f6445e4cafL,\n        0x0974f73d33475f7aL },\n      { 0xd37dbba35ba2f5a8L,0x542c6e636af40066L,0x26d99b53c5d73e2cL,\n        0x06060d7d6c3ca33eL } },\n    /* 26 << 35 */\n    { { 0xcdbef1c2065fef4aL,0x77e60f7dfd5b92e3L,0xd7c549f026708350L,\n        0x201b3ad034f121bfL },\n      { 0x5fcac2a10334fc14L,0x8a9a9e09344552f6L,0x7dd8a1d397653082L,\n        0x5fc0738f79d4f289L } },\n    /* 27 << 35 */\n    { { 0x787d244d17d2d8c3L,0xeffc634570830684L,0x5ddb96dde4f73ae5L,\n        0x8efb14b1172549a5L },\n      { 0x6eb73eee2245ae7aL,0xbca4061eea11f13eL,0xb577421d30b01f5dL,\n        0xaa688b24782e152cL } },\n    /* 28 << 35 */\n    { { 0x67608e71bd3502baL,0x4ef41f24b4de75a0L,0xb08dde5efd6125e5L,\n        0xde484825a409543fL },\n      { 0x1f198d9865cc2295L,0x428a37716e0edfa2L,0x4f9697a2adf35fc7L,\n        0x01a43c79f7cac3c7L } },\n    /* 29 << 35 */\n    { { 0xb05d70590fd3659aL,0x8927f30cbb7f2d9aL,0x4023d1ac8cf984d3L,\n        0x32125ed302897a45L },\n      { 0xfb572dad3d414205L,0x73000ef2e3fa82a9L,0x4c0868e9f10a5581L,\n        0x5b61fc676b0b3ca5L } },\n    /* 30 << 35 */\n    { { 0xc1258d5b7cae440cL,0x21c08b41402b7531L,0xf61a8955de932321L,\n        0x3568faf82d1408afL },\n      { 0x71b15e999ecf965bL,0xf14ed248e917276fL,0xc6f4caa1820cf9e2L,\n        0x681b20b218d83c7eL } },\n    /* 31 << 35 */\n    { { 0x6cde738dc6c01120L,0x71db0813ae70e0dbL,0x95fc064474afe18cL,\n        0x34619053129e2be7L },\n      { 0x80615ceadb2a3b15L,0x0a49a19edb4c7073L,0x0e1b84c88fd2d367L,\n        0xd74bf462033fb8aaL } },\n    /* 32 << 35 */\n    { { 0x889f6d65533ef217L,0x7158c7e4c3ca2e87L,0xfb670dfbdc2b4167L,\n        0x75910a01844c257fL },\n      { 0xf336bf07cf88577dL,0x22245250e45e2aceL,0x2ed92e8d7ca23d85L,\n        0x29f8be4c2b812f58L } },\n    /* 33 << 35 */\n    { { 0xdd9ebaa7076fe12bL,0x3f2400cbae1537f9L,0x1aa9352817bdfb46L,\n        0xc0f9843067883b41L },\n      { 0x5590ede10170911dL,0x7562f5bb34d4b17fL,0xe1fa1df21826b8d2L,\n        0xb40b796a6bd80d59L } },\n    /* 34 << 35 */\n    { { 0xd65bf1973467ba92L,0x8c9b46dbf70954b0L,0x97c8a0f30e78f15dL,\n        0xa8f3a69a85a4c961L },\n      { 0x4242660f61e4ce9bL,0xbf06aab36ea6790cL,0xc6706f8eec986416L,\n        0x9e56dec19a9fc225L } },\n    /* 35 << 35 */\n    { { 0x527c46f49a9898d9L,0xd799e77b5633cdefL,0x24eacc167d9e4297L,\n        0xabb61cea6b1cb734L },\n      { 0xbee2e8a7f778443cL,0x3bb42bf129de2fe6L,0xcbed86a13003bb6fL,\n        0xd3918e6cd781cdf6L } },\n    /* 36 << 35 */\n    { { 0x4bee32719a5103f1L,0x5243efc6f50eac06L,0xb8e122cb6adcc119L,\n        0x1b7faa84c0b80a08L },\n      { 0x32c3d1bd6dfcd08cL,0x129dec4e0be427deL,0x98ab679c1d263c83L,\n        0xafc83cb7cef64effL } },\n    /* 37 << 35 */\n    { { 0x85eb60882fa6be76L,0x892585fb1328cbfeL,0xc154d3edcf618ddaL,\n        0xc44f601b3abaf26eL },\n      { 0x7bf57d0b2be1fdfdL,0xa833bd2d21137feeL,0x9353af362db591a8L,\n        0xc76f26dc5562a056L } },\n    /* 38 << 35 */\n    { { 0x1d87e47d3fdf5a51L,0x7afb5f9355c9cab0L,0x91bbf58f89e0586eL,\n        0x7c72c0180d843709L },\n      { 0xa9a5aafb99b5c3dcL,0xa48a0f1d3844aeb0L,0x7178b7ddb667e482L,\n        0x453985e96e23a59aL } },\n    /* 39 << 35 */\n    { { 0x4a54c86001b25dd8L,0x0dd37f48fb897c8aL,0x5f8aa6100ea90cd9L,\n        0xc8892c6816d5830dL },\n      { 0xeb4befc0ef514ca5L,0x478eb679e72c9ee6L,0x9bca20dadbc40d5fL,\n        0xf015de21dde4f64aL } },\n    /* 40 << 35 */\n    { { 0xaa6a4de0eaf4b8a5L,0x68cfd9ca4bc60e32L,0x668a4b017fd15e70L,\n        0xd9f0694af27dc09dL },\n      { 0xf6c3cad5ba708bcdL,0x5cd2ba695bb95c2aL,0xaa28c1d333c0a58fL,\n        0x23e274e3abc77870L } },\n    /* 41 << 35 */\n    { { 0x44c3692ddfd20a4aL,0x091c5fd381a66653L,0x6c0bb69109a0757dL,\n        0x9072e8b9667343eaL },\n      { 0x31d40eb080848becL,0x95bd480a79fd36ccL,0x01a77c6165ed43f5L,\n        0xafccd1272e0d40bfL } },\n    /* 42 << 35 */\n    { { 0xeccfc82d1cc1884bL,0xc85ac2015d4753b4L,0xc7a6caac658e099fL,\n        0xcf46369e04b27390L },\n      { 0xe2e7d049506467eaL,0x481b63a237cdecccL,0x4029abd8ed80143aL,\n        0x28bfe3c7bcb00b88L } },\n    /* 43 << 35 */\n    { { 0x3bec10090643d84aL,0x885f3668abd11041L,0xdb02432cf83a34d6L,\n        0x32f7b360719ceebeL },\n      { 0xf06c7837dad1fe7aL,0x60a157a95441a0b0L,0x704970e9e2d47550L,\n        0xcd2bd553271b9020L } },\n    /* 44 << 35 */\n    { { 0xff57f82f33e24a0bL,0x9cbee23ff2565079L,0x16353427eb5f5825L,\n        0x276feec4e948d662L },\n      { 0xd1b62bc6da10032bL,0x718351ddf0e72a53L,0x934520762420e7baL,\n        0x96368fff3a00118dL } },\n    /* 45 << 35 */\n    { { 0x00ce2d26150a49e4L,0x0c28b6363f04706bL,0xbad65a4658b196d0L,\n        0x6c8455fcec9f8b7cL },\n      { 0xe90c895f2d71867eL,0x5c0be31bedf9f38cL,0x2a37a15ed8f6ec04L,\n        0x239639e78cd85251L } },\n    /* 46 << 35 */\n    { { 0xd89753159c7c4c6bL,0x603aa3c0d7409af7L,0xb8d53d0c007132fbL,\n        0x68d12af7a6849238L },\n      { 0xbe0607e7bf5d9279L,0x9aa50055aada74ceL,0xe81079cbba7e8ccbL,\n        0x610c71d1a5f4ff5eL } },\n    /* 47 << 35 */\n    { { 0x9e2ee1a75aa07093L,0xca84004ba75da47cL,0x074d39513de75401L,\n        0xf938f756bb311592L },\n      { 0x9619761800a43421L,0x39a2536207bc78c8L,0x278f710a0a171276L,\n        0xb28446ea8d1a8f08L } },\n    /* 48 << 35 */\n    { { 0x184781bfe3b6a661L,0x7751cb1de6d279f7L,0xf8ff95d6c59eb662L,\n        0x186d90b758d3dea7L },\n      { 0x0e4bb6c1dfb4f754L,0x5c5cf56b2b2801dcL,0xc561e4521f54564dL,\n        0xb4fb8c60f0dd7f13L } },\n    /* 49 << 35 */\n    { { 0xf884963033ff98c7L,0x9619fffacf17769cL,0xf8090bf61bfdd80aL,\n        0x14d9a149422cfe63L },\n      { 0xb354c3606f6df9eaL,0xdbcf770d218f17eaL,0x207db7c879eb3480L,\n        0x213dbda8559b6a26L } },\n    /* 50 << 35 */\n    { { 0xac4c200b29fc81b3L,0xebc3e09f171d87c1L,0x917995301481aa9eL,\n        0x051b92e192e114faL },\n      { 0xdf8f92e9ecb5537fL,0x44b1b2cc290c7483L,0xa711455a2adeb016L,\n        0x964b685681a10c2cL } },\n    /* 51 << 35 */\n    { { 0x4f159d99cec03623L,0x05532225ef3271eaL,0xb231bea3c5ee4849L,\n        0x57a54f507094f103L },\n      { 0x3e2d421d9598b352L,0xe865a49c67412ab4L,0xd2998a251cc3a912L,\n        0x5d0928080c74d65dL } },\n    /* 52 << 35 */\n    { { 0x73f459084088567aL,0xeb6b280e1f214a61L,0x8c9adc34caf0c13dL,\n        0x39d12938f561fb80L },\n      { 0xb2dc3a5ebc6edfb4L,0x7485b1b1fe4d210eL,0x062e0400e186ae72L,\n        0x91e32d5c6eeb3b88L } },\n    /* 53 << 35 */\n    { { 0x6df574d74be59224L,0xebc88ccc716d55f3L,0x26c2e6d0cad6ed33L,\n        0xc6e21e7d0d3e8b10L },\n      { 0x2cc5840e5bcc36bbL,0x9292445e7da74f69L,0x8be8d3214e5193a8L,\n        0x3ec236298df06413L } },\n    /* 54 << 35 */\n    { { 0xc7e9ae85b134defaL,0x6073b1d01bb2d475L,0xb9ad615e2863c00dL,\n        0x9e29493d525f4ac4L },\n      { 0xc32b1dea4e9acf4fL,0x3e1f01c8a50db88dL,0xb05d70ea04da916cL,\n        0x714b0d0ad865803eL } },\n    /* 55 << 35 */\n    { { 0x4bd493fc9920cb5eL,0x5b44b1f792c7a3acL,0xa2a77293bcec9235L,\n        0x5ee06e87cd378553L },\n      { 0xceff8173da621607L,0x2bb03e4c99f5d290L,0x2945106aa6f734acL,\n        0xb5056604d25c4732L } },\n    /* 56 << 35 */\n    { { 0x5945920ce079afeeL,0x686e17a06789831fL,0x5966bee8b74a5ae5L,\n        0x38a673a21e258d46L },\n      { 0xbd1cc1f283141c95L,0x3b2ecf4f0e96e486L,0xcd3aa89674e5fc78L,\n        0x415ec10c2482fa7aL } },\n    /* 57 << 35 */\n    { { 0x1523441980503380L,0x513d917ad314b392L,0xb0b52f4e63caecaeL,\n        0x07bf22ad2dc7780bL },\n      { 0xe761e8a1e4306839L,0x1b3be9625dd7feaaL,0x4fe728de74c778f1L,\n        0xf1fa0bda5e0070f6L } },\n    /* 58 << 35 */\n    { { 0x85205a316ec3f510L,0x2c7e4a14d2980475L,0xde3c19c06f30ebfdL,\n        0xdb1c1f38d4b7e644L },\n      { 0xfe291a755dce364aL,0xb7b22a3c058f5be3L,0x2cd2c30237fea38cL,\n        0x2930967a2e17be17L } },\n    /* 59 << 35 */\n    { { 0x87f009de0c061c65L,0xcb014aacedc6ed44L,0x49bd1cb43bafb1ebL,\n        0x81bd8b5c282d3688L },\n      { 0x1cdab87ef01a17afL,0x21f37ac4e710063bL,0x5a6c567642fc8193L,\n        0xf4753e7056a6015cL } },\n    /* 60 << 35 */\n    { { 0x020f795ea15b0a44L,0x8f37c8d78958a958L,0x63b7e89ba4b675b5L,\n        0xb4fb0c0c0fc31aeaL },\n      { 0xed95e639a7ff1f2eL,0x9880f5a3619614fbL,0xdeb6ff02947151abL,\n        0x5bc5118ca868dcdbL } },\n    /* 61 << 35 */\n    { { 0xd8da20554c20cea5L,0xcac2776e14c4d69aL,0xcccb22c1622d599bL,\n        0xa4ddb65368a9bb50L },\n      { 0x2c4ff1511b4941b4L,0xe1ff19b46efba588L,0x35034363c48345e0L,\n        0x45542e3d1e29dfc4L } },\n    /* 62 << 35 */\n    { { 0xf197cb91349f7aedL,0x3b2b5a008fca8420L,0x7c175ee823aaf6d8L,\n        0x54dcf42135af32b6L },\n      { 0x0ba1430727d6561eL,0x879d5ee4d175b1e2L,0xc7c4367399807db5L,\n        0x77a544559cd55bcdL } },\n    /* 63 << 35 */\n    { { 0xe6c2ff130105c072L,0x18f7a99f8dda7da4L,0x4c3018200e2d35c1L,\n        0x06a53ca0d9cc6c82L },\n      { 0xaa21cc1ef1aa1d9eL,0x324143344a75b1e8L,0x2a6d13280ebe9fdcL,\n        0x16bd173f98a4755aL } },\n    /* 64 << 35 */\n    { { 0xfbb9b2452133ffd9L,0x39a8b2f1830f1a20L,0x484bc97dd5a1f52aL,\n        0xd6aebf56a40eddf8L },\n      { 0x32257acb76ccdac6L,0xaf4d36ec1586ff27L,0x8eaa8863f8de7dd1L,\n        0x0045d5cf88647c16L } },\n    /* 0 << 42 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 42 */\n    { { 0xa6f3d574c005979dL,0xc2072b426a40e350L,0xfca5c1568de2ecf9L,\n        0xa8c8bf5ba515344eL },\n      { 0x97aee555114df14aL,0xd4374a4dfdc5ec6bL,0x754cc28f2ca85418L,\n        0x71cb9e27d3c41f78L } },\n    /* 2 << 42 */\n    { { 0x8910507903605c39L,0xf0843d9ea142c96cL,0xf374493416923684L,\n        0x732caa2ffa0a2893L },\n      { 0xb2e8c27061160170L,0xc32788cc437fbaa3L,0x39cd818ea6eda3acL,\n        0xe2e942399e2b2e07L } },\n    /* 3 << 42 */\n    { { 0x6967d39b0260e52aL,0xd42585cc90653325L,0x0d9bd60521ca7954L,\n        0x4fa2087781ed57b3L },\n      { 0x60c1eff8e34a0bbeL,0x56b0040c84f6ef64L,0x28be2b24b1af8483L,\n        0xb2278163f5531614L } },\n    /* 4 << 42 */\n    { { 0x8df275455922ac1cL,0xa7b3ef5ca52b3f63L,0x8e77b21471de57c4L,\n        0x31682c10834c008bL },\n      { 0xc76824f04bd55d31L,0xb6d1c08617b61c71L,0x31db0903c2a5089dL,\n        0x9c092172184e5d3fL } },\n    /* 5 << 42 */\n    { { 0xdd7ced5bc00cc638L,0x1a2015eb61278fc2L,0x2e8e52886a37f8d6L,\n        0xc457786fe79933adL },\n      { 0xb3fe4cce2c51211aL,0xad9b10b224c20498L,0x90d87a4fd28db5e5L,\n        0x698cd1053aca2fc3L } },\n    /* 6 << 42 */\n    { { 0x4f112d07e91b536dL,0xceb982f29eba09d6L,0x3c157b2c197c396fL,\n        0xe23c2d417b66eb24L },\n      { 0x480c57d93f330d37L,0xb3a4c8a179108debL,0x702388decb199ce5L,\n        0x0b019211b944a8d4L } },\n    /* 7 << 42 */\n    { { 0x24f2a692840bb336L,0x7c353bdca669fa7bL,0xda20d6fcdec9c300L,\n        0x625fbe2fa13a4f17L },\n      { 0xa2b1b61adbc17328L,0x008965bfa9515621L,0x49690939c620ff46L,\n        0x182dd27d8717e91cL } },\n    /* 8 << 42 */\n    { { 0x5ace5035ea6c3997L,0x54259aaac2610befL,0xef18bb3f3c80dd39L,\n        0x6910b95b5fc3fa39L },\n      { 0xfce2f51043e09aeeL,0xced56c9fa7675665L,0x10e265acd872db61L,\n        0x6982812eae9fce69L } },\n    /* 9 << 42 */\n    { { 0x29be11c6ce800998L,0x72bb1752b90360d9L,0x2c1931975a4ad590L,\n        0x2ba2f5489fc1dbc0L },\n      { 0x7fe4eebbe490ebe0L,0x12a0a4cd7fae11c0L,0x7197cf81e903ba37L,\n        0xcf7d4aa8de1c6dd8L } },\n    /* 10 << 42 */\n    { { 0x92af6bf43fd5684cL,0x2b26eecf80360aa1L,0xbd960f3000546a82L,\n        0x407b3c43f59ad8feL },\n      { 0x86cae5fe249c82baL,0x9e0faec72463744cL,0x87f551e894916272L,\n        0x033f93446ceb0615L } },\n    /* 11 << 42 */\n    { { 0x1e5eb0d18be82e84L,0x89967f0e7a582fefL,0xbcf687d5a6e921faL,\n        0xdfee4cf3d37a09baL },\n      { 0x94f06965b493c465L,0x638b9a1c7635c030L,0x7666786466f05e9fL,\n        0xccaf6808c04da725L } },\n    /* 12 << 42 */\n    { { 0xca2eb690768fccfcL,0xf402d37db835b362L,0x0efac0d0e2fdfcceL,\n        0xefc9cdefb638d990L },\n      { 0x2af12b72d1669a8bL,0x33c536bc5774ccbdL,0x30b21909fb34870eL,\n        0xc38fa2f77df25acaL } },\n    /* 13 << 42 */\n    { { 0x74c5f02bbf81f3f5L,0x0525a5aeaf7e4581L,0x88d2aaba433c54aeL,\n        0xed9775db806a56c5L },\n      { 0xd320738ac0edb37dL,0x25fdb6ee66cc1f51L,0xac661d1710600d76L,\n        0x931ec1f3bdd1ed76L } },\n    /* 14 << 42 */\n    { { 0x65c11d6219ee43f1L,0x5cd57c3e60829d97L,0xd26c91a3984be6e8L,\n        0xf08d93098b0c53bdL },\n      { 0x94bc9e5bc016e4eaL,0xd391683911d43d2bL,0x886c5ad773701155L,\n        0xe037762620b00715L } },\n    /* 15 << 42 */\n    { { 0x7f01c9ecaa80ba59L,0x3083411a68538e51L,0x970370f1e88128afL,\n        0x625cc3db91dec14bL },\n      { 0xfef9666c01ac3107L,0xb2a8d577d5057ac3L,0xb0f2629992be5df7L,\n        0xf579c8e500353924L } },\n    /* 16 << 42 */\n    { { 0xb8fa3d931341ed7aL,0x4223272ca7b59d49L,0x3dcb194783b8c4a4L,\n        0x4e413c01ed1302e4L },\n      { 0x6d999127e17e44ceL,0xee86bf7533b3adfbL,0xf6902fe625aa96caL,\n        0xb73540e4e5aae47dL } },\n    /* 17 << 42 */\n    { { 0x32801d7b1b4a158cL,0xe571c99e27e2a369L,0x40cb76c010d9f197L,\n        0xc308c2893167c0aeL },\n      { 0xa6ef9dd3eb7958f2L,0xa7226dfc300879b1L,0x6cd0b3627edf0636L,\n        0x4efbce6c7bc37eedL } },\n    /* 18 << 42 */\n    { { 0x75f92a058d699021L,0x586d4c79772566e3L,0x378ca5f1761ad23aL,\n        0x650d86fc1465a8acL },\n      { 0x7a4ed457842ba251L,0x6b65e3e642234933L,0xaf1543b731aad657L,\n        0xa4cefe98cbfec369L } },\n    /* 19 << 42 */\n    { { 0xb587da909f47befbL,0x6562e9fb41312d13L,0xa691ea59eff1cefeL,\n        0xcc30477a05fc4cf6L },\n      { 0xa16324610b0ffd3dL,0xa1f16f3b5b355956L,0x5b148d534224ec24L,\n        0xdc834e7bf977012aL } },\n    /* 20 << 42 */\n    { { 0x7bfc5e75b2c69dbcL,0x3aa77a2903c3da6cL,0xde0df03cca910271L,\n        0xcbd5ca4a7806dc55L },\n      { 0xe1ca58076db476cbL,0xfde15d625f37a31eL,0xf49af520f41af416L,\n        0x96c5c5b17d342db5L } },\n    /* 21 << 42 */\n    { { 0x155c43b7eb4ceb9bL,0x2e9930104e77371aL,0x1d2987da675d43afL,\n        0xef2bc1c08599fd72L },\n      { 0x96894b7b9342f6b2L,0x201eadf27c8e71f0L,0xf3479d9f4a1f3efcL,\n        0xe0f8a742702a9704L } },\n    /* 22 << 42 */\n    { { 0xeafd44b6b3eba40cL,0xf9739f29c1c1e0d0L,0x0091471a619d505eL,\n        0xc15f9c969d7c263eL },\n      { 0x5be4728583afbe33L,0xa3b6d6af04f1e092L,0xe76526b9751a9d11L,\n        0x2ec5b26d9a4ae4d2L } },\n    /* 23 << 42 */\n    { { 0xeb66f4d902f6fb8dL,0x4063c56196912164L,0xeb7050c180ef3000L,\n        0x288d1c33eaa5b3f0L },\n      { 0xe87c68d607806fd8L,0xb2f7f9d54bbbf50fL,0x25972f3aac8d6627L,\n        0xf854777410e8c13bL } },\n    /* 24 << 42 */\n    { { 0xcc50ef6c872b4a60L,0xab2a34a44613521bL,0x39c5c190983e15d1L,\n        0x61dde5df59905512L },\n      { 0xe417f6219f2275f3L,0x0750c8b6451d894bL,0x75b04ab978b0bdaaL,\n        0x3bfd9fd4458589bdL } },\n    /* 25 << 42 */\n    { { 0xf1013e30ee9120b6L,0x2b51af9323a4743eL,0xea96ffae48d14d9eL,\n        0x71dc0dbe698a1d32L },\n      { 0x914962d20180cca4L,0x1ae60677c3568963L,0x8cf227b1437bc444L,\n        0xc650c83bc9962c7aL } },\n    /* 26 << 42 */\n    { { 0x23c2c7ddfe7ccfc4L,0xf925c89d1b929d48L,0x4460f74b06783c33L,\n        0xac2c8d49a590475aL },\n      { 0xfb40b407b807bba0L,0x9d1e362d69ff8f3aL,0xa33e9681cbef64a4L,\n        0x67ece5fa332fb4b2L } },\n    /* 27 << 42 */\n    { { 0x6900a99b739f10e3L,0xc3341ca9ff525925L,0xee18a626a9e2d041L,\n        0xa5a8368529580dddL },\n      { 0xf3470c819d7de3cdL,0xedf025862062cf9cL,0xf43522fac010edb0L,\n        0x3031413513a4b1aeL } },\n    /* 28 << 42 */\n    { { 0xc792e02adb22b94bL,0x993d8ae9a1eaa45bL,0x8aad6cd3cd1e1c63L,\n        0x89529ca7c5ce688aL },\n      { 0x2ccee3aae572a253L,0xe02b643802a21efbL,0xa7091b6ec9430358L,\n        0x06d1b1fa9d7db504L } },\n    /* 29 << 42 */\n    { { 0x58846d32c4744733L,0x40517c71379f9e34L,0x2f65655f130ef6caL,\n        0x526e4488f1f3503fL },\n      { 0x8467bd177ee4a976L,0x1d9dc913921363d1L,0xd8d24c33b069e041L,\n        0x5eb5da0a2cdf7f51L } },\n    /* 30 << 42 */\n    { { 0x1c0f3cb1197b994fL,0x3c95a6c52843eae9L,0x7766ffc9a6097ea5L,\n        0x7bea4093d723b867L },\n      { 0xb48e1f734db378f9L,0x70025b00e37b77acL,0x943dc8e7af24ad46L,\n        0xb98a15ac16d00a85L } },\n    /* 31 << 42 */\n    { { 0x3adc38ba2743b004L,0xb1c7f4f7334415eeL,0xea43df8f1e62d05aL,\n        0x326189059d76a3b6L },\n      { 0x2fbd0bb5a23a0f46L,0x5bc971db6a01918cL,0x7801d94ab4743f94L,\n        0xb94df65e676ae22bL } },\n    /* 32 << 42 */\n    { { 0xaafcbfabaf95894cL,0x7b9bdc07276b2241L,0xeaf983625bdda48bL,\n        0x5977faf2a3fcb4dfL },\n      { 0xbed042ef052c4b5bL,0x9fe87f71067591f0L,0xc89c73ca22f24ec7L,\n        0x7d37fa9ee64a9f1bL } },\n    /* 33 << 42 */\n    { { 0x2710841a15562627L,0x2c01a613c243b034L,0x1d135c562bc68609L,\n        0xc2ca17158b03f1f6L },\n      { 0xc9966c2d3eb81d82L,0xc02abf4a8f6df13eL,0x77b34bd78f72b43bL,\n        0xaff6218f360c82b0L } },\n    /* 34 << 42 */\n    { { 0x0aa5726c8d55b9d2L,0xdc0adbe999e9bffbL,0x9097549cefb9e72aL,\n        0x167557129dfb3111L },\n      { 0xdd8bf984f26847f9L,0xbcb8e387dfb30cb7L,0xc1fd32a75171ef9cL,\n        0x977f3fc7389b363fL } },\n    /* 35 << 42 */\n    { { 0x116eaf2bf4babda0L,0xfeab68bdf7113c8eL,0xd1e3f064b7def526L,\n        0x1ac30885e0b3fa02L },\n      { 0x1c5a6e7b40142d9dL,0x839b560330921c0bL,0x48f301fa36a116a3L,\n        0x380e1107cfd9ee6dL } },\n    /* 36 << 42 */\n    { { 0x7945ead858854be1L,0x4111c12ecbd4d49dL,0xece3b1ec3a29c2efL,\n        0x6356d4048d3616f5L },\n      { 0x9f0d6a8f594d320eL,0x0989316df651ccd2L,0x6c32117a0f8fdde4L,\n        0x9abe5cc5a26a9bbcL } },\n    /* 37 << 42 */\n    { { 0xcff560fb9723f671L,0x21b2a12d7f3d593cL,0xe4cb18da24ba0696L,\n        0x186e2220c3543384L },\n      { 0x722f64e088312c29L,0x94282a9917dc7752L,0x62467bbf5a85ee89L,\n        0xf435c650f10076a0L } },\n    /* 38 << 42 */\n    { { 0xc9ff153943b3a50bL,0x7132130c1a53efbcL,0x31bfe063f7b0c5b7L,\n        0xb0179a7d4ea994ccL },\n      { 0x12d064b3c85f455bL,0x472593288f6e0062L,0xf64e590bb875d6d9L,\n        0x22dd6225ad92bcc7L } },\n    /* 39 << 42 */\n    { { 0xb658038eb9c3bd6dL,0x00cdb0d6fbba27c8L,0x0c6813371062c45dL,\n        0xd8515b8c2d33407dL },\n      { 0xcb8f699e8cbb5ecfL,0x8c4347f8c608d7d8L,0x2c11850abb3e00dbL,\n        0x20a8dafdecb49d19L } },\n    /* 40 << 42 */\n    { { 0xbd78148045ee2f40L,0x75e354af416b60cfL,0xde0b58a18d49a8c4L,\n        0xe40e94e2fa359536L },\n      { 0xbd4fa59f62accd76L,0x05cf466a8c762837L,0xb5abda99448c277bL,\n        0x5a9e01bf48b13740L } },\n    /* 41 << 42 */\n    { { 0x9d457798326aad8dL,0xbdef4954c396f7e7L,0x6fb274a2c253e292L,\n        0x2800bf0a1cfe53e7L },\n      { 0x22426d3144438fd4L,0xef2339235e259f9aL,0x4188503c03f66264L,\n        0x9e5e7f137f9fdfabL } },\n    /* 42 << 42 */\n    { { 0x565eb76c5fcc1abaL,0xea63254859b5bff8L,0x5587c087aab6d3faL,\n        0x92b639ea6ce39c1bL },\n      { 0x0706e782953b135cL,0x7308912e425268efL,0x599e92c7090e7469L,\n        0x83b90f529bc35e75L } },\n    /* 43 << 42 */\n    { { 0x4750b3d0244975b3L,0xf3a4435811965d72L,0x179c67749c8dc751L,\n        0xff18cdfed23d9ff0L },\n      { 0xc40138332028e247L,0x96e280e2f3bfbc79L,0xf60417bdd0880a84L,\n        0x263c9f3d2a568151L } },\n    /* 44 << 42 */\n    { { 0x36be15b32d2ce811L,0x846dc0c2f8291d21L,0x5cfa0ecb789fcfdbL,\n        0x45a0beedd7535b9aL },\n      { 0xec8e9f0796d69af1L,0x31a7c5b8599ab6dcL,0xd36d45eff9e2e09fL,\n        0x3cf49ef1dcee954bL } },\n    /* 45 << 42 */\n    { { 0x6be34cf3086cff9bL,0x88dbd49139a3360fL,0x1e96b8cc0dbfbd1dL,\n        0xc1e5f7bfcb7e2552L },\n      { 0x0547b21428819d98L,0xc770dd9c7aea9dcbL,0xaef0d4c7041d68c8L,\n        0xcc2b981813cb9ba8L } },\n    /* 46 << 42 */\n    { { 0x7fc7bc76fe86c607L,0x6b7b9337502a9a95L,0x1948dc27d14dab63L,\n        0x249dd198dae047beL },\n      { 0xe8356584a981a202L,0x3531dd183a893387L,0x1be11f90c85c7209L,\n        0x93d2fe1ee2a52b5aL } },\n    /* 47 << 42 */\n    { { 0x8225bfe2ec6d6b97L,0x9cf6d6f4bd0aa5deL,0x911459cb54779f5fL,\n        0x5649cddb86aeb1f3L },\n      { 0x321335793f26ce5aL,0xc289a102550f431eL,0x559dcfda73b84c6fL,\n        0x84973819ee3ac4d7L } },\n    /* 48 << 42 */\n    { { 0xb51e55e6f2606a82L,0xe25f706190f2fb57L,0xacef6c2ab1a4e37cL,\n        0x864e359d5dcf2706L },\n      { 0x479e6b187ce57316L,0x2cab25003a96b23dL,0xed4898628ef16df7L,\n        0x2056538cef3758b5L } },\n    /* 49 << 42 */\n    { { 0xa7df865ef15d3101L,0x80c5533a61b553d7L,0x366e19974ed14294L,\n        0x6620741fb3c0bcd6L },\n      { 0x21d1d9c4edc45418L,0x005b859ec1cc4a9dL,0xdf01f630a1c462f0L,\n        0x15d06cf3f26820c7L } },\n    /* 50 << 42 */\n    { { 0x9f7f24ee3484be47L,0x2ff33e964a0c902fL,0x00bdf4575a0bc453L,\n        0x2378dfaf1aa238dbL },\n      { 0x272420ec856720f2L,0x2ad9d95b96797291L,0xd1242cc6768a1558L,\n        0x2e287f8b5cc86aa8L } },\n    /* 51 << 42 */\n    { { 0x796873d0990cecaaL,0xade55f81675d4080L,0x2645eea321f0cd84L,\n        0x7a1efa0fb4e17d02L },\n      { 0xf6858420037cc061L,0x682e05f0d5d43e12L,0x59c3699427218710L,\n        0x85cbba4d3f7cd2fcL } },\n    /* 52 << 42 */\n    { { 0x726f97297a3cd22aL,0x9f8cd5dc4a628397L,0x17b93ab9c23165edL,\n        0xff5f5dbf122823d4L },\n      { 0xc1e4e4b5654a446dL,0xd1a9496f677257baL,0x6387ba94de766a56L,\n        0x23608bc8521ec74aL } },\n    /* 53 << 42 */\n    { { 0x16a522d76688c4d4L,0x9d6b428207373abdL,0xa62f07acb42efaa3L,\n        0xf73e00f7e3b90180L },\n      { 0x36175fec49421c3eL,0xc4e44f9b3dcf2678L,0x76df436b7220f09fL,\n        0x172755fb3aa8b6cfL } },\n    /* 54 << 42 */\n    { { 0xbab89d57446139ccL,0x0a0a6e025fe0208fL,0xcdbb63e211e5d399L,\n        0x33ecaa12a8977f0bL },\n      { 0x59598b21f7c42664L,0xb3e91b32ab65d08aL,0x035822eef4502526L,\n        0x1dcf0176720a82a9L } },\n    /* 55 << 42 */\n    { { 0x50f8598f3d589e02L,0xdf0478ffb1d63d2cL,0x8b8068bd1571cd07L,\n        0x30c3aa4fd79670cdL },\n      { 0x25e8fd4b941ade7fL,0x3d1debdc32790011L,0x65b6dcbd3a3f9ff0L,\n        0x282736a4793de69cL } },\n    /* 56 << 42 */\n    { { 0xef69a0c3d41d3bd3L,0xb533b8c907a26bdeL,0xe2801d97db2edf9fL,\n        0xdc4a8269e1877af0L },\n      { 0x6c1c58513d590dbeL,0x84632f6bee4e9357L,0xd36d36b779b33374L,\n        0xb46833e39bbca2e6L } },\n    /* 57 << 42 */\n    { { 0x37893913f7fc0586L,0x385315f766bf4719L,0x72c56293b31855dcL,\n        0xd1416d4e849061feL },\n      { 0xbeb3ab7851047213L,0x447f6e61f040c996L,0xd06d310d638b1d0cL,\n        0xe28a413fbad1522eL } },\n    /* 58 << 42 */\n    { { 0x685a76cb82003f86L,0x610d07f70bcdbca3L,0x6ff660219ca4c455L,\n        0x7df39b87cea10eecL },\n      { 0xb9255f96e22db218L,0x8cc6d9eb08a34c44L,0xcd4ffb86859f9276L,\n        0x8fa15eb250d07335L } },\n    /* 59 << 42 */\n    { { 0xdf553845cf2c24b5L,0x89f66a9f52f9c3baL,0x8f22b5b9e4a7ceb3L,\n        0xaffef8090e134686L },\n      { 0x3e53e1c68eb8fac2L,0x93c1e4eb28aec98eL,0xb6b91ec532a43bcbL,\n        0x2dbfa947b2d74a51L } },\n    /* 60 << 42 */\n    { { 0xe065d190ca84bad7L,0xfb13919fad58e65cL,0x3c41718bf1cb6e31L,\n        0x688969f006d05c3fL },\n      { 0xd4f94ce721264d45L,0xfdfb65e97367532bL,0x5b1be8b10945a39dL,\n        0x229f789c2b8baf3bL } },\n    /* 61 << 42 */\n    { { 0xd8f41f3e6f49f15dL,0x678ce828907f0792L,0xc69ace82fca6e867L,\n        0x106451aed01dcc89L },\n      { 0x1bb4f7f019fc32d2L,0x64633dfcb00c52d2L,0x8f13549aad9ea445L,\n        0x99a3bf50fb323705L } },\n    /* 62 << 42 */\n    { { 0x0c9625a2534d4dbcL,0x45b8f1d1c2a2fea3L,0x76ec21a1a530fc1aL,\n        0x4bac9c2a9e5bd734L },\n      { 0x5996d76a7b4e3587L,0x0045cdee1182d9e3L,0x1aee24b91207f13dL,\n        0x66452e9797345a41L } },\n    /* 63 << 42 */\n    { { 0x16e5b0549f950cd0L,0x9cc72fb1d7fdd075L,0x6edd61e766249663L,\n        0xde4caa4df043cccbL },\n      { 0x11b1f57a55c7ac17L,0x779cbd441a85e24dL,0x78030f86e46081e7L,\n        0xfd4a60328e20f643L } },\n    /* 64 << 42 */\n    { { 0xcc7a64880a750c0fL,0x39bacfe34e548e83L,0x3d418c760c110f05L,\n        0x3e4daa4cb1f11588L },\n      { 0x2733e7b55ffc69ffL,0x46f147bc92053127L,0x885b2434d722df94L,\n        0x6a444f65e6fc6b7cL } },\n    /* 0 << 49 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 49 */\n    { { 0x7a1a465ac3f16ea8L,0x115a461db2f1d11cL,0x4767dd956c68a172L,\n        0x3392f2ebd13a4698L },\n      { 0xc7a99ccde526cdc7L,0x8e537fdc22292b81L,0x76d8cf69a6d39198L,\n        0xffc5ff432446852dL } },\n    /* 2 << 49 */\n    { { 0x97b14f7ea90567e6L,0x513257b7b6ae5cb7L,0x85454a3c9f10903dL,\n        0xd8d2c9ad69bc3724L },\n      { 0x38da93246b29cb44L,0xb540a21d77c8cbacL,0x9bbfe43501918e42L,\n        0xfffa707a56c3614eL } },\n    /* 3 << 49 */\n    { { 0x0ce4e3f1d4e353b7L,0x062d8a14ef46b0a0L,0x6408d5ab574b73fdL,\n        0xbc41d1c9d3273ffdL },\n      { 0x3538e1e76be77800L,0x71fe8b37c5655031L,0x1cd916216b9b331aL,\n        0xad825d0bbb388f73L } },\n    /* 4 << 49 */\n    { { 0x56c2e05b1cb76219L,0x0ec0bf9171567e7eL,0xe7076f8661c4c910L,\n        0xd67b085bbabc04d9L },\n      { 0x9fb904595e93a96aL,0x7526c1eafbdc249aL,0x0d44d367ecdd0bb7L,\n        0x953999179dc0d695L } },\n    /* 5 << 49 */\n    { { 0x61360ee99e240d18L,0x057cdcacb4b94466L,0xe7667cd12fe5325cL,\n        0x1fa297b521974e3bL },\n      { 0xfa4081e7db083d76L,0x31993be6f206bd15L,0x8949269b14c19f8cL,\n        0x21468d72a9d92357L } },\n    /* 6 << 49 */\n    { { 0x2ccbc583a4c506ecL,0x957ed188d1acfe97L,0x8baed83312f1aea2L,\n        0xef2a6cb48325362dL },\n      { 0x130dde428e195c43L,0xc842025a0e6050c6L,0x2da972a708686a5dL,\n        0xb52999a1e508b4a8L } },\n    /* 7 << 49 */\n    { { 0xd9f090b910a5a8bdL,0xca91d249096864daL,0x8e6a93be3f67dbc1L,\n        0xacae6fbaf5f4764cL },\n      { 0x1563c6e0d21411a0L,0x28fa787fda0a4ad8L,0xd524491c908c8030L,\n        0x1257ba0e4c795f07L } },\n    /* 8 << 49 */\n    { { 0x83f49167ceca9754L,0x426d2cf64b7939a0L,0x2555e355723fd0bfL,\n        0xa96e6d06c4f144e2L },\n      { 0x4768a8dd87880e61L,0x15543815e508e4d5L,0x09d7e772b1b65e15L,\n        0x63439dd6ac302fa0L } },\n    /* 9 << 49 */\n    { { 0xb93f802fc14e35c2L,0x71735b7c4341333cL,0x03a2510416d4f362L,\n        0x3f4d069bbf433c8eL },\n      { 0x0d83ae01f78f5a7cL,0x50a8ffbe7c4eed07L,0xc74f890676e10f83L,\n        0x7d0809669ddaf8e1L } },\n    /* 10 << 49 */\n    { { 0xb11df8e1698e04ccL,0x877be203169005c8L,0x32749e8c4f3c6179L,\n        0x2dbc9d0a7853fc05L },\n      { 0x187d4f939454d937L,0xe682ce9db4800e1bL,0xa9129ad8165e68e8L,\n        0x0fe29735be7f785bL } },\n    /* 11 << 49 */\n    { { 0x5303f40c5b9e02b7L,0xa37c969235ee04e8L,0x5f46cc2034d6632bL,\n        0x55ef72b296ac545bL },\n      { 0xabec5c1f7b91b062L,0x0a79e1c7bb33e821L,0xbb04b4283a9f4117L,\n        0x0de1f28ffd2a475aL } },\n    /* 12 << 49 */\n    { { 0x31019ccf3a4434b4L,0xa34581111a7954dcL,0xa9dac80de34972a7L,\n        0xb043d05474f6b8ddL },\n      { 0x021c319e11137b1aL,0x00a754ceed5cc03fL,0x0aa2c794cbea5ad4L,\n        0x093e67f470c015b6L } },\n    /* 13 << 49 */\n    { { 0x72cdfee9c97e3f6bL,0xc10bcab4b6da7461L,0x3b02d2fcb59806b9L,\n        0x85185e89a1de6f47L },\n      { 0x39e6931f0eb6c4d4L,0x4d4440bdd4fa5b04L,0x5418786e34be7eb8L,\n        0x6380e5219d7259bcL } },\n    /* 14 << 49 */\n    { { 0x20ac0351d598d710L,0x272c4166cb3a4da4L,0xdb82fe1aca71de1fL,\n        0x746e79f2d8f54b0fL },\n      { 0x6e7fc7364b573e9bL,0x75d03f46fd4b5040L,0x5c1cc36d0b98d87bL,\n        0x513ba3f11f472da1L } },\n    /* 15 << 49 */\n    { { 0x79d0af26abb177ddL,0xf82ab5687891d564L,0x2b6768a972232173L,\n        0xefbb3bb08c1f6619L },\n      { 0xb29c11dba6d18358L,0x519e2797b0916d3aL,0xd4dc18f09188e290L,\n        0x648e86e398b0ca7fL } },\n    /* 16 << 49 */\n    { { 0x859d3145983c38b5L,0xb14f176c637abc8bL,0x2793fb9dcaff7be6L,\n        0xebe5a55f35a66a5aL },\n      { 0x7cec1dcd9f87dc59L,0x7c595cd3fbdbf560L,0x5b543b2226eb3257L,\n        0x69080646c4c935fdL } },\n    /* 17 << 49 */\n    { { 0x7f2e440381e9ede3L,0x243c3894caf6df0aL,0x7c605bb11c073b11L,\n        0xcd06a541ba6a4a62L },\n      { 0x2916894949d4e2e5L,0x33649d074af66880L,0xbfc0c885e9a85035L,\n        0xb4e52113fc410f4bL } },\n    /* 18 << 49 */\n    { { 0xdca3b70678a6513bL,0x92ea4a2a9edb1943L,0x02642216db6e2dd8L,\n        0x9b45d0b49fd57894L },\n      { 0x114e70dbc69d11aeL,0x1477dd194c57595fL,0xbc2208b4ec77c272L,\n        0x95c5b4d7db68f59cL } },\n    /* 19 << 49 */\n    { { 0xb8c4fc6342e532b7L,0x386ba4229ae35290L,0xfb5dda42d201ecbcL,\n        0x2353dc8ba0e38fd6L },\n      { 0x9a0b85ea68f7e978L,0x96ec56822ad6d11fL,0x5e279d6ce5f6886dL,\n        0xd3fe03cd3cb1914dL } },\n    /* 20 << 49 */\n    { { 0xfe541fa47ea67c77L,0x952bd2afe3ea810cL,0x791fef568d01d374L,\n        0xa3a1c6210f11336eL },\n      { 0x5ad0d5a9c7ec6d79L,0xff7038af3225c342L,0x003c6689bc69601bL,\n        0x25059bc745e8747dL } },\n    /* 21 << 49 */\n    { { 0xfa4965b2f2086fbfL,0xf6840ea686916078L,0xd7ac762070081d6cL,\n        0xe600da31b5328645L },\n      { 0x01916f63529b8a80L,0xe80e48582d7d6f3eL,0x29eb0fe8d664ca7cL,\n        0xf017637be7b43b0cL } },\n    /* 22 << 49 */\n    { { 0x9a75c80676cb2566L,0x8f76acb1b24892d9L,0x7ae7b9cc1f08fe45L,\n        0x19ef73296a4907d8L },\n      { 0x2db4ab715f228bf0L,0xf3cdea39817032d7L,0x0b1f482edcabe3c0L,\n        0x3baf76b4bb86325cL } },\n    /* 23 << 49 */\n    { { 0xd49065e010089465L,0x3bab5d298e77c596L,0x7636c3a6193dbd95L,\n        0xdef5d294b246e499L },\n      { 0xb22c58b9286b2475L,0xa0b93939cd80862bL,0x3002c83af0992388L,\n        0x6de01f9beacbe14cL } },\n    /* 24 << 49 */\n    { { 0x6aac688eadd70482L,0x708de92a7b4a4e8aL,0x75b6dd73758a6eefL,\n        0xea4bf352725b3c43L },\n      { 0x10041f2c87912868L,0xb1b1be95ef09297aL,0x19ae23c5a9f3860aL,\n        0xc4f0f839515dcf4bL } },\n    /* 25 << 49 */\n    { { 0x3c7ecca397f6306aL,0x744c44ae68a3a4b0L,0x69cd13a0b3a1d8a2L,\n        0x7cad0a1e5256b578L },\n      { 0xea653fcd33791d9eL,0x9cc2a05d74b2e05fL,0x73b391dcfd7affa2L,\n        0xddb7091eb6b05442L } },\n    /* 26 << 49 */\n    { { 0xc71e27bf8538a5c6L,0x195c63dd89abff17L,0xfd3152851b71e3daL,\n        0x9cbdfda7fa680fa0L },\n      { 0x9db876ca849d7eabL,0xebe2764b3c273271L,0x663357e3f208dceaL,\n        0x8c5bd833565b1b70L } },\n    /* 27 << 49 */\n    { { 0xccc3b4f59837fc0dL,0x9b641ba8a79cf00fL,0x7428243ddfdf3990L,\n        0x83a594c4020786b1L },\n      { 0xb712451a526c4502L,0x9d39438e6adb3f93L,0xfdb261e3e9ff0ccdL,\n        0x80344e3ce07af4c3L } },\n    /* 28 << 49 */\n    { { 0x75900d7c2fa4f126L,0x08a3b8655c99a232L,0x2478b6bfdb25e0c3L,\n        0x482cc2c271db2edfL },\n      { 0x37df7e645f321bb8L,0x8a93821b9a8005b4L,0x3fa2f10ccc8c1958L,\n        0x0d3322182c269d0aL } },\n    /* 29 << 49 */\n    { { 0x20ab8119e246b0e6L,0xb39781e4d349fd17L,0xd293231eb31aa100L,\n        0x4b779c97bb032168L },\n      { 0x4b3f19e1c8470500L,0x45b7efe90c4c869dL,0xdb84f38aa1a6bbccL,\n        0x3b59cb15b2fddbc1L } },\n    /* 30 << 49 */\n    { { 0xba5514df3fd165e8L,0x499fd6a9061f8811L,0x72cd1fe0bfef9f00L,\n        0x120a4bb979ad7e8aL },\n      { 0xf2ffd0955f4a5ac5L,0xcfd174f195a7a2f0L,0xd42301ba9d17baf1L,\n        0xd2fa487a77f22089L } },\n    /* 31 << 49 */\n    { { 0x9cb09efeb1dc77e1L,0xe956693921c99682L,0x8c5469016c6067bbL,\n        0xfd37857461c24456L },\n      { 0x2b6a6cbe81796b33L,0x62d550f658e87f8bL,0x1b763e1c7f1b01b4L,\n        0x4b93cfea1b1b5e12L } },\n    /* 32 << 49 */\n    { { 0xb93452381d531696L,0x57201c0088cdde69L,0xdde922519a86afc7L,\n        0xe3043895bd35cea8L },\n      { 0x7608c1e18555970dL,0x8267dfa92535935eL,0xd4c60a57322ea38bL,\n        0xe0bf7977804ef8b5L } },\n    /* 33 << 49 */\n    { { 0x1a0dab28c06fece4L,0xd405991e94e7b49dL,0xc542b6d2706dab28L,\n        0xcb228da3a91618fbL },\n      { 0x224e4164107d1ceaL,0xeb9fdab3d0f5d8f1L,0xc02ba3860d6e41cdL,\n        0x676a72c59b1f7146L } },\n    /* 34 << 49 */\n    { { 0xffd6dd984d6cb00bL,0xcef9c5cade2e8d7cL,0xa1bbf5d7641c7936L,\n        0x1b95b230ee8f772eL },\n      { 0xf765a92ee8ac25b1L,0xceb04cfc3a18b7c6L,0x27944cef0acc8966L,\n        0xcbb3c957434c1004L } },\n    /* 35 << 49 */\n    { { 0x9c9971a1a43ff93cL,0x5bc2db17a1e358a9L,0x45b4862ea8d9bc82L,\n        0x70ebfbfb2201e052L },\n      { 0xafdf64c792871591L,0xea5bcae6b42d0219L,0xde536c552ad8f03cL,\n        0xcd6c3f4da76aa33cL } },\n    /* 36 << 49 */\n    { { 0xbeb5f6230bca6de3L,0xdd20dd99b1e706fdL,0x90b3ff9dac9059d4L,\n        0x2d7b29027ccccc4eL },\n      { 0x8a090a59ce98840fL,0xa5d947e08410680aL,0x49ae346a923379a5L,\n        0x7dbc84f9b28a3156L } },\n    /* 37 << 49 */\n    { { 0xfd40d91654a1aff2L,0xabf318ba3a78fb9bL,0x50152ed83029f95eL,\n        0x9fc1dd77c58ad7faL },\n      { 0x5fa5791513595c17L,0xb95046688f62b3a9L,0x907b5b24ff3055b0L,\n        0x2e995e359a84f125L } },\n    /* 38 << 49 */\n    { { 0x87dacf697e9bbcfbL,0x95d0c1d6e86d96e3L,0x65726e3c2d95a75cL,\n        0x2c3c9001acd27f21L },\n      { 0x1deab5616c973f57L,0x108b7e2ca5221643L,0x5fee9859c4ef79d4L,\n        0xbd62b88a40d4b8c6L } },\n    /* 39 << 49 */\n    { { 0xb4dd29c4197c75d6L,0x266a6df2b7076febL,0x9512d0ea4bf2df11L,\n        0x1320c24f6b0cc9ecL },\n      { 0x6bb1e0e101a59596L,0x8317c5bbeff9aaacL,0x65bb405e385aa6c9L,\n        0x613439c18f07988fL } },\n    /* 40 << 49 */\n    { { 0xd730049f16a66e91L,0xe97f2820fa1b0e0dL,0x4131e003304c28eaL,\n        0x820ab732526bac62L },\n      { 0xb2ac9ef928714423L,0x54ecfffaadb10cb2L,0x8781476ef886a4ccL,\n        0x4b2c87b5db2f8d49L } },\n    /* 41 << 49 */\n    { { 0xe857cd200a44295dL,0x707d7d2158c6b044L,0xae8521f9f596757cL,\n        0x87448f0367b2b714L },\n      { 0x13a9bc455ebcd58dL,0x79bcced99122d3c1L,0x3c6442479e076642L,\n        0x0cf227782df4767dL } },\n    /* 42 << 49 */\n    { { 0x5e61aee471d444b6L,0x211236bfc5084a1dL,0x7e15bc9a4fd3eaf6L,\n        0x68df2c34ab622bf5L },\n      { 0x9e674f0f59bf4f36L,0xf883669bd7f34d73L,0xc48ac1b831497b1dL,\n        0x323b925d5106703bL } },\n    /* 43 << 49 */\n    { { 0x22156f4274082008L,0xeffc521ac8482bcbL,0x5c6831bf12173479L,\n        0xcaa2528fc4739490L },\n      { 0x84d2102a8f1b3c4dL,0xcf64dfc12d9bec0dL,0x433febad78a546efL,\n        0x1f621ec37b73cef1L } },\n    /* 44 << 49 */\n    { { 0x6aecd62737338615L,0x162082ab01d8edf6L,0x833a811919e86b66L,\n        0x6023a251d299b5dbL },\n      { 0xf5bb0c3abbf04b89L,0x6735eb69ae749a44L,0xd0e058c54713de3bL,\n        0xfdf2593e2c3d4ccdL } },\n    /* 45 << 49 */\n    { { 0x1b8f414efdd23667L,0xdd52aacafa2015eeL,0x3e31b517bd9625ffL,\n        0x5ec9322d8db5918cL },\n      { 0xbc73ac85a96f5294L,0x82aa5bf361a0666aL,0x49755810bf08ac42L,\n        0xd21cdfd5891cedfcL } },\n    /* 46 << 49 */\n    { { 0x918cb57b67f8be10L,0x365d1a7c56ffa726L,0x2435c5046532de93L,\n        0xc0fc5e102674cd02L },\n      { 0x6e51fcf89cbbb142L,0x1d436e5aafc50692L,0x766bffff3fbcae22L,\n        0x3148c2fdfd55d3b8L } },\n    /* 47 << 49 */\n    { { 0x52c7fdc9233222faL,0x89ff1092e419fb6bL,0x3cd6db9925254977L,\n        0x2e85a1611cf12ca7L },\n      { 0xadd2547cdc810bc9L,0xea3f458f9d257c22L,0x642c1fbe27d6b19bL,\n        0xed07e6b5140481a6L } },\n    /* 48 << 49 */\n    { { 0x6ada1d4286d2e0f8L,0xe59201220e8a9fd5L,0x02c936af708c1b49L,\n        0x60f30fee2b4bfaffL },\n      { 0x6637ad06858e6a61L,0xce4c77673fd374d0L,0x39d54b2d7188defbL,\n        0xa8c9d250f56a6b66L } },\n    /* 49 << 49 */\n    { { 0x58fc0f5eb24fe1dcL,0x9eaf9dee6b73f24cL,0xa90d588b33650705L,\n        0xde5b62c5af2ec729L },\n      { 0x5c72cfaed3c2b36eL,0x868c19d5034435daL,0x88605f93e17ee145L,\n        0xaa60c4ee77a5d5b1L } },\n    /* 50 << 49 */\n    { { 0xbcf5bfd23b60c472L,0xaf4ef13ceb1d3049L,0x373f44fce13895c9L,\n        0xf29b382f0cbc9822L },\n      { 0x1bfcb85373efaef6L,0xcf56ac9ca8c96f40L,0xd7adf1097a191e24L,\n        0x98035f44bf8a8dc2L } },\n    /* 51 << 49 */\n    { { 0xf40a71b91e750c84L,0xc57f7b0c5dc6c469L,0x49a0e79c6fbc19c1L,\n        0x6b0f5889a48ebdb8L },\n      { 0x5d3fd084a07c4e9fL,0xc3830111ab27de14L,0x0e4929fe33e08dccL,\n        0xf4a5ad2440bb73a3L } },\n    /* 52 << 49 */\n    { { 0xde86c2bf490f97caL,0x288f09c667a1ce18L,0x364bb8861844478dL,\n        0x7840fa42ceedb040L },\n      { 0x1269fdd25a631b37L,0x94761f1ea47c8b7dL,0xfc0c2e17481c6266L,\n        0x85e16ea23daa5fa7L } },\n    /* 53 << 49 */\n    { { 0xccd8603392491048L,0x0c2f6963f4d402d7L,0x6336f7dfdf6a865cL,\n        0x0a2a463cb5c02a87L },\n      { 0xb0e29be7bf2f12eeL,0xf0a2200266bad988L,0x27f87e039123c1d7L,\n        0x21669c55328a8c98L } },\n    /* 54 << 49 */\n    { { 0x186b980392f14529L,0xd3d056cc63954df3L,0x2f03fd58175a46f6L,\n        0x63e34ebe11558558L },\n      { 0xe13fedee5b80cfa5L,0xe872a120d401dbd1L,0x52657616e8a9d667L,\n        0xbc8da4b6e08d6693L } },\n    /* 55 << 49 */\n    { { 0x370fb9bb1b703e75L,0x6773b186d4338363L,0x18dad378ecef7bffL,\n        0xaac787ed995677daL },\n      { 0x4801ea8b0437164bL,0xf430ad2073fe795eL,0xb164154d8ee5eb73L,\n        0x0884ecd8108f7c0eL } },\n    /* 56 << 49 */\n    { { 0x0e6ec0965f520698L,0x640631fe44f7b8d9L,0x92fd34fca35a68b9L,\n        0x9c5a4b664d40cf4eL },\n      { 0x949454bf80b6783dL,0x80e701fe3a320a10L,0x8d1a564a1a0a39b2L,\n        0x1436d53d320587dbL } },\n    /* 57 << 49 */\n    { { 0xf5096e6d6556c362L,0xbc23a3c0e2455d7eL,0x3a7aee54807230f9L,\n        0x9ba1cfa622ae82fdL },\n      { 0x833a057a99c5d706L,0x8be85f4b842315c9L,0xd083179a66a72f12L,\n        0x2fc77d5dcdcc73cdL } },\n    /* 58 << 49 */\n    { { 0x22b88a805616ee30L,0xfb09548fe7ab1083L,0x8ad6ab0d511270cdL,\n        0x61f6c57a6924d9abL },\n      { 0xa0f7bf7290aecb08L,0x849f87c90df784a4L,0x27c79c15cfaf1d03L,\n        0xbbf9f675c463faceL } },\n    /* 59 << 49 */\n    { { 0x91502c65765ba543L,0x18ce3cac42ea60ddL,0xe5cee6ac6e43ecb3L,\n        0x63e4e91068f2aeebL },\n      { 0x26234fa3c85932eeL,0x96883e8b4c90c44dL,0x29b9e738a18a50f6L,\n        0xbfc62b2a3f0420dfL } },\n    /* 60 << 49 */\n    { { 0xd22a7d906d3e1fa9L,0x17115618fe05b8a3L,0x2a0c9926bb2b9c01L,\n        0xc739fcc6e07e76a2L },\n      { 0x540e9157165e439aL,0x06353a626a9063d8L,0x84d9559461e927a3L,\n        0x013b9b26e2e0be7fL } },\n    /* 61 << 49 */\n    { { 0x4feaec3b973497f1L,0x15c0f94e093ebc2dL,0x6af5f22733af0583L,\n        0x0c2af206c61f3340L },\n      { 0xd25dbdf14457397cL,0x2e8ed017cabcbae0L,0xe3010938c2815306L,\n        0xbaa99337e8c6cd68L } },\n    /* 62 << 49 */\n    { { 0x085131823b0ec7deL,0x1e1b822b58df05dfL,0x5c14842fa5c3b683L,\n        0x98fe977e3eba34ceL },\n      { 0xfd2316c20d5e8873L,0xe48d839abd0d427dL,0x495b2218623fc961L,\n        0x24ee56e7b46fba5eL } },\n    /* 63 << 49 */\n    { { 0x9184a55b91e4de58L,0xa7488ca5dfdea288L,0xa723862ea8dcc943L,\n        0x92d762b2849dc0fcL },\n      { 0x3c444a12091ff4a9L,0x581113fa0cada274L,0xb9de0a4530d8eae2L,\n        0x5e0fcd85df6b41eaL } },\n    /* 64 << 49 */\n    { { 0x6233ea68c094dbb5L,0xb77d062ed968d410L,0x3e719bbc58b3002dL,\n        0x68e7dd3d3dc49d58L },\n      { 0x8d825740013a5e58L,0x213117473c9e3c1bL,0x0cb0a2a77c99b6abL,\n        0x5c48a3b3c2f888f2L } },\n    /* 0 << 56 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 56 */\n    { { 0xc7913e91991724f3L,0x5eda799c39cbd686L,0xddb595c763d4fc1eL,\n        0x6b63b80bac4fed54L },\n      { 0x6ea0fc697e5fb516L,0x737708bad0f1c964L,0x9628745f11a92ca5L,\n        0x61f379589a86967aL } },\n    /* 2 << 56 */\n    { { 0x9af39b2caa665072L,0x78322fa4efd324efL,0x3d153394c327bd31L,\n        0x81d5f2713129dab0L },\n      { 0xc72e0c42f48027f5L,0xaa40cdbc8536e717L,0xf45a657a2d369d0fL,\n        0xb03bbfc4ea7f74e6L } },\n    /* 3 << 56 */\n    { { 0x46a8c4180d738dedL,0x6f1a5bb0e0de5729L,0xf10230b98ba81675L,\n        0x32c6f30c112b33d4L },\n      { 0x7559129dd8fffb62L,0x6a281b47b459bf05L,0x77c1bd3afa3b6776L,\n        0x0709b3807829973aL } },\n    /* 4 << 56 */\n    { { 0x8c26b232a3326505L,0x38d69272ee1d41bfL,0x0459453effe32afaL,\n        0xce8143ad7cb3ea87L },\n      { 0x932ec1fa7e6ab666L,0x6cd2d23022286264L,0x459a46fe6736f8edL,\n        0x50bf0d009eca85bbL } },\n    /* 5 << 56 */\n    { { 0x0b825852877a21ecL,0x300414a70f537a94L,0x3f1cba4021a9a6a2L,\n        0x50824eee76943c00L },\n      { 0xa0dbfcecf83cba5dL,0xf953814893b4f3c0L,0x6174416248f24dd7L,\n        0x5322d64de4fb09ddL } },\n    /* 6 << 56 */\n    { { 0x574473843d9325f3L,0xa9bef2d0f371cb84L,0x77d2188ba61e36c5L,\n        0xbbd6a7d7c602df72L },\n      { 0xba3aa9028f61bc0bL,0xf49085ed6ed0b6a1L,0x8bc625d6ae6e8298L,\n        0x832b0b1da2e9c01dL } },\n    /* 7 << 56 */\n    { { 0xa337c447f1f0ced1L,0x800cc7939492dd2bL,0x4b93151dbea08efaL,\n        0x820cf3f8de0a741eL },\n      { 0xff1982dc1c0f7d13L,0xef92196084dde6caL,0x1ad7d97245f96ee3L,\n        0x319c8dbe29dea0c7L } },\n    /* 8 << 56 */\n    { { 0xd3ea38717b82b99bL,0x75922d4d470eb624L,0x8f66ec543b95d466L,\n        0x66e673ccbee1e346L },\n      { 0x6afe67c4b5f2b89aL,0x3de9c1e6290e5cd3L,0x8c278bb6310a2adaL,\n        0x420fa3840bdb323bL } },\n    /* 9 << 56 */\n    { { 0x0ae1d63b0eb919b0L,0xd74ee51da74b9620L,0x395458d0a674290cL,\n        0x324c930f4620a510L },\n      { 0x2d1f4d19fbac27d4L,0x4086e8ca9bedeeacL,0x0cdd211b9b679ab8L,\n        0x5970167d7090fec4L } },\n    /* 10 << 56 */\n    { { 0x3420f2c9faf1fc63L,0x616d333a328c8bb4L,0x7d65364c57f1fe4aL,\n        0x9343e87755e5c73aL },\n      { 0x5795176be970e78cL,0xa36ccebf60533627L,0xfc7c738009cdfc1bL,\n        0xb39a2afeb3fec326L } },\n    /* 11 << 56 */\n    { { 0xb7ff1ba16224408aL,0xcc856e92247cfc5eL,0x01f102e7c18bc493L,\n        0x4613ab742091c727L },\n      { 0xaa25e89cc420bf2bL,0x00a5317690337ec2L,0xd2be9f437d025fc7L,\n        0x3316fb856e6fe3dcL } },\n    /* 12 << 56 */\n    { { 0x27520af59ac50814L,0xfdf95e789a8e4223L,0xb7e7df2a56bec5a0L,\n        0xf7022f7ddf159e5dL },\n      { 0x93eeeab1cac1fe8fL,0x8040188c37451168L,0x7ee8aa8ad967dce6L,\n        0xfa0e79e73abc9299L } },\n    /* 13 << 56 */\n    { { 0x67332cfc2064cfd1L,0x339c31deb0651934L,0x719b28d52a3bcbeaL,\n        0xee74c82b9d6ae5c6L },\n      { 0x0927d05ebaf28ee6L,0x82cecf2c9d719028L,0x0b0d353eddb30289L,\n        0xfe4bb977fddb2e29L } },\n    /* 14 << 56 */\n    { { 0xbb5bb990640bfd9eL,0xd226e27782f62108L,0x4bf0098502ffdd56L,\n        0x7756758a2ca1b1b5L },\n      { 0xc32b62a35285fe91L,0xedbc546a8c9cd140L,0x1e47a013af5cb008L,\n        0xbca7e720073ce8f2L } },\n    /* 15 << 56 */\n    { { 0xe10b2ab817a91caeL,0xb89aab6508e27f63L,0x7b3074a7dba3ddf9L,\n        0x1c20ce09330c2972L },\n      { 0x6b9917b45fcf7e33L,0xe6793743945ceb42L,0x18fc22155c633d19L,\n        0xad1adb3cc7485474L } },\n    /* 16 << 56 */\n    { { 0x646f96796424c49bL,0xf888dfe867c241c9L,0xe12d4b9324f68b49L,\n        0x9a6b62d8a571df20L },\n      { 0x81b4b26d179483cbL,0x666f96329511fae2L,0xd281b3e4d53aa51fL,\n        0x7f96a7657f3dbd16L } },\n    /* 17 << 56 */\n    { { 0xa7f8b5bf074a30ceL,0xd7f52107005a32e6L,0x6f9e090750237ed4L,\n        0x2f21da478096fa2bL },\n      { 0xf3e19cb4eec863a0L,0xd18f77fd9527620aL,0x9505c81c407c1cf8L,\n        0x9998db4e1b6ec284L } },\n    /* 18 << 56 */\n    { { 0x7e3389e5c247d44dL,0x125071413f4f3d80L,0xd4ba01104a78a6c7L,\n        0x312874a0767720beL },\n      { 0xded059a675944370L,0xd6123d903b2c0bddL,0xa56b717b51c108e3L,\n        0x9bb7940e070623e9L } },\n    /* 19 << 56 */\n    { { 0x794e2d5984ac066cL,0xf5954a92e68c69a0L,0x28c524584fd99dccL,\n        0x60e639fcb1012517L },\n      { 0xc2e601257de79248L,0xe9ef6404f12fc6d7L,0x4c4f28082a3b5d32L,\n        0x865ad32ec768eb8aL } },\n    /* 20 << 56 */\n    { { 0xac02331b13fb70b6L,0x037b44c195599b27L,0x1a860fc460bd082cL,\n        0xa2e25745c980cd01L },\n      { 0xee3387a81da0263eL,0x931bfb952d10f3d6L,0x5b687270a1f24a32L,\n        0xf140e65dca494b86L } },\n    /* 21 << 56 */\n    { { 0x4f4ddf91b2f1ac7aL,0xf99eaabb760fee27L,0x57f4008a49c228e5L,\n        0x090be4401cf713bbL },\n      { 0xac91fbe45004f022L,0xd838c2c2569e1af6L,0xd6c7d20b0f1daaa5L,\n        0xaa063ac11bbb02c0L } },\n    /* 22 << 56 */\n    { { 0x0938a42259558a78L,0x5343c6698435da2fL,0x96f67b18034410dcL,\n        0x7cc1e42484510804L },\n      { 0x86a1543f16dfbb7dL,0x921fa9425b5bd592L,0x9dcccb6eb33dd03cL,\n        0x8581ddd9b843f51eL } },\n    /* 23 << 56 */\n    { { 0x54935fcb81d73c9eL,0x6d07e9790a5e97abL,0x4dc7b30acf3a6babL,\n        0x147ab1f3170bee11L },\n      { 0x0aaf8e3d9fafdee4L,0xfab3dbcb538a8b95L,0x405df4b36ef13871L,\n        0xf1f4e9cb088d5a49L } },\n    /* 24 << 56 */\n    { { 0x9bcd24d366b33f1dL,0x3b97b8205ce445c0L,0xe2926549ba93ff61L,\n        0xd9c341ce4dafe616L },\n      { 0xfb30a76e16efb6f3L,0xdf24b8ca605b953cL,0x8bd52afec2fffb9fL,\n        0xbbac5ff7e19d0b96L } },\n    /* 25 << 56 */\n    { { 0x43c01b87459afccdL,0x6bd45143b7432652L,0x8473453055b5d78eL,\n        0x81088fdb1554ba7dL },\n      { 0xada0a52c1e269375L,0xf9f037c42dc5ec10L,0xc066060794bfbc11L,\n        0xc0a630bbc9c40d2fL } },\n    /* 26 << 56 */\n    { { 0x5efc797eab64c31eL,0xffdb1dab74507144L,0xf61242871ca6790cL,\n        0xe9609d81e69bf1bfL },\n      { 0xdb89859500d24fc9L,0x9c750333e51fb417L,0x51830a91fef7bbdeL,\n        0x0ce67dc8945f585cL } },\n    /* 27 << 56 */\n    { { 0x9a730ed44763eb50L,0x24a0e221c1ab0d66L,0x643b6393648748f3L,\n        0x1982daa16d3c6291L },\n      { 0x6f00a9f78bbc5549L,0x7a1783e17f36384eL,0xe8346323de977f50L,\n        0x91ab688db245502aL } },\n    /* 28 << 56 */\n    { { 0x331ab6b56d0bdd66L,0x0a6ef32e64b71229L,0x1028150efe7c352fL,\n        0x27e04350ce7b39d3L },\n      { 0x2a3c8acdc1070c82L,0xfb2034d380c9feefL,0x2d729621709f3729L,\n        0x8df290bf62cb4549L } },\n    /* 29 << 56 */\n    { { 0x02f99f33fc2e4326L,0x3b30076d5eddf032L,0xbb21f8cf0c652fb5L,\n        0x314fb49eed91cf7bL },\n      { 0xa013eca52f700750L,0x2b9e3c23712a4575L,0xe5355557af30fbb0L,\n        0x1ada35167c77e771L } },\n    /* 30 << 56 */\n    { { 0x45f6ecb27b135670L,0xe85d19df7cfc202eL,0x0f1b50c758d1be9fL,\n        0x5ebf2c0aead2e344L },\n      { 0x1531fe4eabc199c9L,0xc703259256bab0aeL,0x16ab2e486c1fec54L,\n        0x0f87fda804280188L } },\n    /* 31 << 56 */\n    { { 0xdc9f46fc609e4a74L,0x2a44a143ba667f91L,0xbc3d8b95b4d83436L,\n        0xa01e4bd0c7bd2958L },\n      { 0x7b18293273483c90L,0xa79c6aa1a7c7b598L,0xbf3983c6eaaac07eL,\n        0x8f18181e96e0d4e6L } },\n    /* 32 << 56 */\n    { { 0x8553d37c051af62bL,0xe9a998eb0bf94496L,0xe0844f9fb0d59aa1L,\n        0x983fd558e6afb813L },\n      { 0x9670c0ca65d69804L,0x732b22de6ea5ff2dL,0xd7640ba95fd8623bL,\n        0x9f619163a6351782L } },\n    /* 33 << 56 */\n    { { 0x0bfc27eeacee5043L,0xae419e732eb10f02L,0x19c028d18943fb05L,\n        0x71f01cf7ff13aa2aL },\n      { 0x7790737e8887a132L,0x6751330966318410L,0x9819e8a37ddb795eL,\n        0xfecb8ef5dad100b2L } },\n    /* 34 << 56 */\n    { { 0x59f74a223021926aL,0xb7c28a496f9b4c1cL,0xed1a733f912ad0abL,\n        0x42a910af01a5659cL },\n      { 0x3842c6e07bd68cabL,0x2b57fa3876d70ac8L,0x8a6707a83c53aaebL,\n        0x62c1c51065b4db18L } },\n    /* 35 << 56 */\n    { { 0x8de2c1fbb2d09dc7L,0xc3dfed12266bd23bL,0x927d039bd5b27db6L,\n        0x2fb2f0f1103243daL },\n      { 0xf855a07b80be7399L,0xed9327ce1f9f27a8L,0xa0bd99c7729bdef7L,\n        0x2b67125e28250d88L } },\n    /* 36 << 56 */\n    { { 0x784b26e88670ced7L,0xe3dfe41fc31bd3b4L,0x9e353a06bcc85cbcL,\n        0x302e290960178a9dL },\n      { 0x860abf11a6eac16eL,0x76447000aa2b3aacL,0x46ff9d19850afdabL,\n        0x35bdd6a5fdb2d4c1L } },\n    /* 37 << 56 */\n    { { 0xe82594b07e5c9ce9L,0x0f379e5320af346eL,0x608b31e3bc65ad4aL,\n        0x710c6b12267c4826L },\n      { 0x51c966f971954cf1L,0xb1cec7930d0aa215L,0x1f15598986bd23a8L,\n        0xae2ff99cf9452e86L } },\n    /* 38 << 56 */\n    { { 0xd8dd953c340ceaa2L,0x263552752e2e9333L,0x15d4e5f98586f06dL,\n        0xd6bf94a8f7cab546L },\n      { 0x33c59a0ab76a9af0L,0x52740ab3ba095af7L,0xc444de8a24389ca0L,\n        0xcc6f9863706da0cbL } },\n    /* 39 << 56 */\n    { { 0xb5a741a76b2515cfL,0x71c416019585c749L,0x78350d4fe683de97L,\n        0x31d6152463d0b5f5L },\n      { 0x7a0cc5e1fbce090bL,0xaac927edfbcb2a5bL,0xe920de4920d84c35L,\n        0x8c06a0b622b4de26L } },\n    /* 40 << 56 */\n    { { 0xd34dd58bafe7ddf3L,0x55851fedc1e6e55bL,0xd1395616960696e7L,\n        0x940304b25f22705fL },\n      { 0x6f43f861b0a2a860L,0xcf1212820e7cc981L,0x121862120ab64a96L,\n        0x09215b9ab789383cL } },\n    /* 41 << 56 */\n    { { 0x311eb30537387c09L,0xc5832fcef03ee760L,0x30358f5832f7ea19L,\n        0xe01d3c3491d53551L },\n      { 0x1ca5ee41da48ea80L,0x34e71e8ecf4fa4c1L,0x312abd257af1e1c7L,\n        0xe3afcdeb2153f4a5L } },\n    /* 42 << 56 */\n    { { 0x9d5c84d700235e9aL,0x0308d3f48c4c836fL,0xc0a66b0489332de5L,\n        0x610dd39989e566efL },\n      { 0xf8eea460d1ac1635L,0x84cbb3fb20a2c0dfL,0x40afb488e74a48c5L,\n        0x29738198d326b150L } },\n    /* 43 << 56 */\n    { { 0x2a17747fa6d74081L,0x60ea4c0555a26214L,0x53514bb41f88c5feL,\n        0xedd645677e83426cL },\n      { 0xd5d6cbec96460b25L,0xa12fd0ce68dc115eL,0xc5bc3ed2697840eaL,\n        0x969876a8a6331e31L } },\n    /* 44 << 56 */\n    { { 0x60c36217472ff580L,0xf42297054ad41393L,0x4bd99ef0a03b8b92L,\n        0x501c7317c144f4f6L },\n      { 0x159009b318464945L,0x6d5e594c74c5c6beL,0x2d587011321a3660L,\n        0xd1e184b13898d022L } },\n    /* 45 << 56 */\n    { { 0x5ba047524c6a7e04L,0x47fa1e2b45550b65L,0x9419daf048c0a9a5L,\n        0x663629537c243236L },\n      { 0xcd0744b15cb12a88L,0x561b6f9a2b646188L,0x599415a566c2c0c0L,\n        0xbe3f08590f83f09aL } },\n    /* 46 << 56 */\n    { { 0x9141c5beb92041b8L,0x01ae38c726477d0dL,0xca8b71f3d12c7a94L,\n        0xfab5b31f765c70dbL },\n      { 0x76ae7492487443e9L,0x8595a310990d1349L,0xf8dbeda87d460a37L,\n        0x7f7ad0821e45a38fL } },\n    /* 47 << 56 */\n    { { 0xed1d4db61059705aL,0xa3dd492ae6b9c697L,0x4b92ee3a6eb38bd5L,\n        0xbab2609d67cc0bb7L },\n      { 0x7fc4fe896e70ee82L,0xeff2c56e13e6b7e3L,0x9b18959e34d26fcaL,\n        0x2517ab66889d6b45L } },\n    /* 48 << 56 */\n    { { 0xf167b4e0bdefdd4fL,0x69958465f366e401L,0x5aa368aba73bbec0L,\n        0x121487097b240c21L },\n      { 0x378c323318969006L,0xcb4d73cee1fe53d1L,0x5f50a80e130c4361L,\n        0xd67f59517ef5212bL } },\n    /* 49 << 56 */\n    { { 0xf145e21e9e70c72eL,0xb2e52e295566d2fbL,0x44eaba4a032397f5L,\n        0x5e56937b7e31a7deL },\n      { 0x68dcf517456c61e1L,0xbc2e954aa8b0a388L,0xe3552fa760a8b755L,\n        0x03442dae73ad0cdeL } },\n    /* 50 << 56 */\n    { { 0x37ffe747ceb26210L,0x983545e8787baef9L,0x8b8c853586a3de31L,\n        0xc621dbcbfacd46dbL },\n      { 0x82e442e959266fbbL,0xa3514c37339d471cL,0x3a11b77162cdad96L,\n        0xf0cb3b3cecf9bdf0L } },\n    /* 51 << 56 */\n    { { 0x3fcbdbce478e2135L,0x7547b5cfbda35342L,0xa97e81f18a677af6L,\n        0xc8c2bf8328817987L },\n      { 0xdf07eaaf45580985L,0xc68d1f05c93b45cbL,0x106aa2fec77b4cacL,\n        0x4c1d8afc04a7ae86L } },\n    /* 52 << 56 */\n    { { 0xdb41c3fd9eb45ab2L,0x5b234b5bd4b22e74L,0xda253decf215958aL,\n        0x67e0606ea04edfa0L },\n      { 0xabbbf070ef751b11L,0xf352f175f6f06dceL,0xdfc4b6af6839f6b4L,\n        0x53ddf9a89959848eL } },\n    /* 53 << 56 */\n    { { 0xda49c379c21520b0L,0x90864ff0dbd5d1b6L,0x2f055d235f49c7f7L,\n        0xe51e4e6aa796b2d8L },\n      { 0xc361a67f5c9dc340L,0x5ad53c37bca7c620L,0xda1d658832c756d0L,\n        0xad60d9118bb67e13L } },\n    /* 54 << 56 */\n    { { 0xd6c47bdf0eeec8c6L,0x4a27fec1078a1821L,0x081f7415c3099524L,\n        0x8effdf0b82cd8060L },\n      { 0xdb70ec1c65842df8L,0x8821b358d319a901L,0x72ee56eede42b529L,\n        0x5bb39592236e4286L } },\n    /* 55 << 56 */\n    { { 0xd1183316fd6f7140L,0xf9fadb5bbd8e81f7L,0x701d5e0c5a02d962L,\n        0xfdee4dbf1b601324L },\n      { 0xbed1740735d7620eL,0x04e3c2c3f48c0012L,0x9ee29da73455449aL,\n        0x562cdef491a836c4L } },\n    /* 56 << 56 */\n    { { 0x8f682a5f47701097L,0x617125d8ff88d0c2L,0x948fda2457bb86ddL,\n        0x348abb8f289f7286L },\n      { 0xeb10eab599d94bbdL,0xd51ba28e4684d160L,0xabe0e51c30c8f41aL,\n        0x66588b4513254f4aL } },\n    /* 57 << 56 */\n    { { 0x147ebf01fad097a5L,0x49883ea8610e815dL,0xe44d60ba8a11de56L,\n        0xa970de6e827a7a6dL },\n      { 0x2be414245e17fc19L,0xd833c65701214057L,0x1375813b363e723fL,\n        0x6820bb88e6a52e9bL } },\n    /* 58 << 56 */\n    { { 0x7e7f6970d875d56aL,0xd6a0a9ac51fbf6bfL,0x54ba8790a3083c12L,\n        0xebaeb23d6ae7eb64L },\n      { 0xa8685c3ab99a907aL,0xf1e74550026bf40bL,0x7b73a027c802cd9eL,\n        0x9a8a927c4fef4635L } },\n    /* 59 << 56 */\n    { { 0xe1b6f60c08191224L,0xc4126ebbde4ec091L,0xe1dff4dc4ae38d84L,\n        0xde3f57db4f2ef985L },\n      { 0x34964337d446a1ddL,0x7bf217a0859e77f6L,0x8ff105278e1d13f5L,\n        0xa304ef0374eeae27L } },\n    /* 60 << 56 */\n    { { 0xfc6f5e47d19dfa5aL,0xdb007de37fad982bL,0x28205ad1613715f5L,\n        0x251e67297889529eL },\n      { 0x727051841ae98e78L,0xf818537d271cac32L,0xc8a15b7eb7f410f5L,\n        0xc474356f81f62393L } },\n    /* 61 << 56 */\n    { { 0x92dbdc5ac242316bL,0xabe060acdbf4aff5L,0x6e8c38fe909a8ec6L,\n        0x43e514e56116cb94L },\n      { 0x2078fa3807d784f9L,0x1161a880f4b5b357L,0x5283ce7913adea3dL,\n        0x0756c3e6cc6a910bL } },\n    /* 62 << 56 */\n    { { 0x60bcfe01aaa79697L,0x04a73b2956391db1L,0xdd8dad47189b45a0L,\n        0xbfac0dd048d5b8d9L },\n      { 0x34ab3af57d3d2ec2L,0x6fa2fc2d207bd3afL,0x9ff4009266550dedL,\n        0x719b3e871fd5b913L } },\n    /* 63 << 56 */\n    { { 0xa573a4966d17fbc7L,0x0cd1a70a73d2b24eL,0x34e2c5cab2676937L,\n        0xe7050b06bf669f21L },\n      { 0xfbe948b61ede9046L,0xa053005197662659L,0x58cbd4edf10124c5L,\n        0xde2646e4dd6c06c8L } },\n    /* 64 << 56 */\n    { { 0x332f81088cad38c0L,0x471b7e906bd68ae2L,0x56ac3fb20d8e27a3L,\n        0xb54660db136b4b0dL },\n      { 0x123a1e11a6fd8de4L,0x44dbffeaa37799efL,0x4540b977ce6ac17cL,\n        0x495173a8af60acefL } },\n    /* 0 << 63 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 63 */\n    { { 0x9ebb284d391c2a82L,0xbcdd4863158308e8L,0x006f16ec83f1edcaL,\n        0xa13e2c37695dc6c8L },\n      { 0x2ab756f04a057a87L,0xa8765500a6b48f98L,0x4252face68651c44L,\n        0xa52b540be1765e02L } },\n    /* 2 << 63 */\n    { { 0x4f922fc516a0d2bbL,0x0d5cc16c1a623499L,0x9241cf3a57c62c8bL,\n        0x2f5e6961fd1b667fL },\n      { 0x5c15c70bf5a01797L,0x3d20b44d60956192L,0x04911b37071fdb52L,\n        0xf648f9168d6f0f7bL } },\n    /* 3 << 63 */\n    { { 0x6dc1acafe60b7cf7L,0x25860a5084a9d869L,0x56fc6f09e7ba8ac4L,\n        0x828c5bd06148d29eL },\n      { 0xac6b435edc55ae5fL,0xa527f56cc0117411L,0x94d5045efd24342cL,\n        0x2c4c0a3570b67c0dL } },\n    /* 4 << 63 */\n    { { 0x027cc8b8fac61d9aL,0x7d25e062e3c6fe8aL,0xe08805bfe5bff503L,\n        0x13271e6c6ff632f7L },\n      { 0x55dca6c0232f76a5L,0x8957c32d701ef426L,0xee728bcba10a5178L,\n        0x5ea60411b62c5173L } },\n    /* 5 << 63 */\n    { { 0xfc4e964ed0b8892bL,0x9ea176839301bb74L,0x6265c5aefcc48626L,\n        0xe60cf82ebb3e9102L },\n      { 0x57adf797d4df5531L,0x235b59a18deeefe2L,0x60adcf583f306eb1L,\n        0x105c27533d09492dL } },\n    /* 6 << 63 */\n    { { 0x4090914bb5def996L,0x1cb69c83233dd1e7L,0xc1e9c1d39b3d5e76L,\n        0x1f3338edfccf6012L },\n      { 0xb1e95d0d2f5378a8L,0xacf4c2c72f00cd21L,0x6e984240eb5fe290L,\n        0xd66c038d248088aeL } },\n    /* 7 << 63 */\n    { { 0x804d264af94d70cfL,0xbdb802ef7314bf7eL,0x8fb54de24333ed02L,\n        0x740461e0285635d9L },\n      { 0x4113b2c8365e9383L,0xea762c833fdef652L,0x4eec6e2e47b956c1L,\n        0xa3d814be65620fa4L } },\n    /* 8 << 63 */\n    { { 0x9ad5462bb4d8bc50L,0x181c0b16a9195770L,0xebd4fe1c78412a68L,\n        0xae0341bcc0dff48cL },\n      { 0xb6bc45cf7003e866L,0xf11a6dea8a24a41bL,0x5407151ad04c24c2L,\n        0x62c9d27dda5b7b68L } },\n    /* 9 << 63 */\n    { { 0x2e96423588cceff6L,0x8594c54f8b07ed69L,0x1578e73cc84d0d0dL,\n        0x7b4e1055ff532868L },\n      { 0xa348c0d5b5ec995aL,0xbf4b9d5514289a54L,0x9ba155a658fbd777L,\n        0x186ed7a81a84491dL } },\n    /* 10 << 63 */\n    { { 0xd4992b30614c0900L,0xda98d121bd00c24bL,0x7f534dc87ec4bfa1L,\n        0x4a5ff67437dc34bcL },\n      { 0x68c196b81d7ea1d7L,0x38cf289380a6d208L,0xfd56cd09e3cbbd6eL,\n        0xec72e27e4205a5b6L } },\n    /* 11 << 63 */\n    { { 0x15ea68f5a44f77f7L,0x7aa5f9fdb43c52bcL,0x86ff676f94f0e609L,\n        0xa4cde9632e2d432bL },\n      { 0x8cafa0c0eee470afL,0x84137d0e8a3f5ec8L,0xebb40411faa31231L,\n        0xa239c13f6f7f7ccfL } },\n    /* 12 << 63 */\n    { { 0x32865719a8afd30bL,0x867983288a826dceL,0xdf04e891c4a8fbe0L,\n        0xbb6b6e1bebf56ad3L },\n      { 0x0a695b11471f1ff0L,0xd76c3389be15baf0L,0x018edb95be96c43eL,\n        0xf2beaaf490794158L } },\n    /* 13 << 63 */\n    { { 0x152db09ec3076a27L,0x5e82908ee416545dL,0xa2c41272356d6f2eL,\n        0xdc9c964231fd74e1L },\n      { 0x66ceb88d519bf615L,0xe29ecd7605a2274eL,0x3a0473c4bf5e2fa0L,\n        0x6b6eb67164284e67L } },\n    /* 14 << 63 */\n    { { 0xe8b97932b88756ddL,0xed4e8652f17e3e61L,0xc2dd14993ee1c4a4L,\n        0xc0aaee17597f8c0eL },\n      { 0x15c4edb96c168af3L,0x6563c7bfb39ae875L,0xadfadb6f20adb436L,\n        0xad55e8c99a042ac0L } },\n    /* 15 << 63 */\n    { { 0x975a1ed8b76da1f5L,0x10dfa466a58acb94L,0x8dd7f7e3ac060282L,\n        0x6813e66a572a051eL },\n      { 0xb4ccae1e350cb901L,0xb653d65650cb7822L,0x42484710dfab3b87L,\n        0xcd7ee5379b670fd0L } },\n    /* 16 << 63 */\n    { { 0x0a50b12e523b8bf6L,0x8009eb5b8f910c1bL,0xf535af824a167588L,\n        0x0f835f9cfb2a2abdL },\n      { 0xf59b29312afceb62L,0xc797df2a169d383fL,0xeb3f5fb066ac02b0L,\n        0x029d4c6fdaa2d0caL } },\n    /* 17 << 63 */\n    { { 0xd4059bc1afab4bc5L,0x833f5c6f56783247L,0xb53466308d2d3605L,\n        0x83387891d34d8433L },\n      { 0xd973b30fadd9419aL,0xbcca1099afe3fce8L,0x081783150809aac6L,\n        0x01b7f21a540f0f11L } },\n    /* 18 << 63 */\n    { { 0x65c29219909523c8L,0xa62f648fa3a1c741L,0x88598d4f60c9e55aL,\n        0xbce9141b0e4f347aL },\n      { 0x9af97d8435f9b988L,0x0210da62320475b6L,0x3c076e229191476cL,\n        0x7520dbd944fc7834L } },\n    /* 19 << 63 */\n    { { 0x6a6b2cfec1ab1bbdL,0xef8a65bedc650938L,0x72855540805d7bc4L,\n        0xda389396ed11fdfdL },\n      { 0xa9d5bd3674660876L,0x11d67c54b45dff35L,0x6af7d148a4f5da94L,\n        0xbb8d4c3fc0bbeb31L } },\n    /* 20 << 63 */\n    { { 0x87a7ebd1e0a1b12aL,0x1e4ef88d770ba95fL,0x8c33345cdc2ae9cbL,\n        0xcecf127601cc8403L },\n      { 0x687c012e1b39b80fL,0xfd90d0ad35c33ba4L,0xa3ef5a675c9661c2L,\n        0x368fc88ee017429eL } },\n    /* 21 << 63 */\n    { { 0xd30c6761196a2fa2L,0x931b9817bd5b312eL,0xba01000c72f54a31L,\n        0xa203d2c866eaa541L },\n      { 0xf2abdee098939db3L,0xe37d6c2c3e606c02L,0xf2921574521ff643L,\n        0x2781b3c4d7e2fca3L } },\n    /* 22 << 63 */\n    { { 0x664300b07850ec06L,0xac5a38b97d3a10cfL,0x9233188de34ab39dL,\n        0xe77057e45072cbb9L },\n      { 0xbcf0c042b59e78dfL,0x4cfc91e81d97de52L,0x4661a26c3ee0ca4aL,\n        0x5620a4c1fb8507bcL } },\n    /* 23 << 63 */\n    { { 0x4b44d4aa049f842cL,0xceabc5d51540e82bL,0x306710fd15c6f156L,\n        0xbe5ae52b63db1d72L },\n      { 0x06f1e7e6334957f1L,0x57e388f031144a70L,0xfb69bb2fdf96447bL,\n        0x0f78ebd373e38a12L } },\n    /* 24 << 63 */\n    { { 0xb82226052b7ce542L,0xe6d4ce997472bde1L,0x53e16ebe09d2f4daL,\n        0x180ff42e53b92b2eL },\n      { 0xc59bcc022c34a1c6L,0x3803d6f9422c46c2L,0x18aff74f5c14a8a2L,\n        0x55aebf8010a08b28L } },\n    /* 25 << 63 */\n    { { 0x66097d587135593fL,0x32e6eff72be570cdL,0x584e6a102a8c860dL,\n        0xcd185890a2eb4163L },\n      { 0x7ceae99d6d97e134L,0xd42c6b70dd8447ceL,0x59ddbb4ab8c50273L,\n        0x03c612df3cf34e1eL } },\n    /* 26 << 63 */\n    { { 0x84b9ca1504b6c5a0L,0x35216f3918f0e3a3L,0x3ec2d2bcbd986c00L,\n        0x8bf546d9d19228feL },\n      { 0xd1c655a44cd623c3L,0x366ce718502b8e5aL,0x2cfc84b4eea0bfe7L,\n        0xe01d5ceecf443e8eL } },\n    /* 27 << 63 */\n    { { 0x8ec045d9036520f8L,0xdfb3c3d192d40e98L,0x0bac4ccecc559a04L,\n        0x35eccae5240ea6b1L },\n      { 0x180b32dbf8a5a0acL,0x547972a5eb699700L,0xa3765801ca26bca0L,\n        0x57e09d0ea647f25aL } },\n    /* 28 << 63 */\n    { { 0xb956970e2fdd23ccL,0xb80288bc5682e971L,0xe6e6d91e9ae86ebcL,\n        0x0564c83f8c9f1939L },\n      { 0x551932a239560368L,0xe893752b049c28e2L,0x0b03cee5a6a158c3L,\n        0xe12d656b04964263L } },\n    /* 29 << 63 */\n    { { 0x4b47554e63e3bc1dL,0xc719b6a245044ff7L,0x4f24d30ae48daa07L,\n        0xa3f37556c8c1edc3L },\n      { 0x9a47bf760700d360L,0xbb1a1824822ae4e2L,0x22e275a389f1fb4cL,\n        0x72b1aa239968c5f5L } },\n    /* 30 << 63 */\n    { { 0xa75feacabe063f64L,0x9b392f43bce47a09L,0xd42415091ad07acaL,\n        0x4b0c591b8d26cd0fL },\n      { 0x2d42ddfd92f1169aL,0x63aeb1ac4cbf2392L,0x1de9e8770691a2afL,\n        0xebe79af7d98021daL } },\n    /* 31 << 63 */\n    { { 0xcfdf2a4e40e50acfL,0xf0a98ad7af01d665L,0xefb640bf1831be1fL,\n        0x6fe8bd2f80e9ada0L },\n      { 0x94c103a16cafbc91L,0x170f87598308e08cL,0x5de2d2ab9780ff4fL,\n        0x666466bc45b201f2L } },\n    /* 32 << 63 */\n    { { 0x58af2010f5b343bcL,0x0f2e400af2f142feL,0x3483bfdea85f4bdfL,\n        0xf0b1d09303bfeaa9L },\n      { 0x2ea01b95c7081603L,0xe943e4c93dba1097L,0x47be92adb438f3a6L,\n        0x00bb7742e5bf6636L } },\n    /* 33 << 63 */\n    { { 0x136b7083824297b4L,0x9d0e55805584455fL,0xab48cedcf1c7d69eL,\n        0x53a9e4812a256e76L },\n      { 0x0402b0e065eb2413L,0xdadbbb848fc407a7L,0xa65cd5a48d7f5492L,\n        0x21d4429374bae294L } },\n    /* 34 << 63 */\n    { { 0x66917ce63b5f1cc4L,0x37ae52eace872e62L,0xbb087b722905f244L,\n        0x120770861e6af74fL },\n      { 0x4b644e491058edeaL,0x827510e3b638ca1dL,0x8cf2b7046038591cL,\n        0xffc8b47afe635063L } },\n    /* 35 << 63 */\n    { { 0x3ae220e61b4d5e63L,0xbd8647429d961b4bL,0x610c107e9bd16bedL,\n        0x4270352a1127147bL },\n      { 0x7d17ffe664cfc50eL,0x50dee01a1e36cb42L,0x068a762235dc5f9aL,\n        0x9a08d536df53f62cL } },\n    /* 36 << 63 */\n    { { 0x4ed714576be5f7deL,0xd93006f8c2263c9eL,0xe073694ccacacb36L,\n        0x2ff7a5b43ae118abL },\n      { 0x3cce53f1cd871236L,0xf156a39dc2aa6d52L,0x9cc5f271b198d76dL,\n        0xbc615b6f81383d39L } },\n    /* 37 << 63 */\n    { { 0xa54538e8de3eee6bL,0x58c77538ab910d91L,0x31e5bdbc58d278bdL,\n        0x3cde4adfb963acaeL },\n      { 0xb1881fd25302169cL,0x8ca60fa0a989ed8bL,0xa1999458ff96a0eeL,\n        0xc1141f03ac6c283dL } },\n    /* 38 << 63 */\n    { { 0x7677408d6dfafed3L,0x33a0165339661588L,0x3c9c15ec0b726fa0L,\n        0x090cfd936c9b56daL },\n      { 0xe34f4baea3c40af5L,0x3469eadbd21129f1L,0xcc51674a1e207ce8L,\n        0x1e293b24c83b1ef9L } },\n    /* 39 << 63 */\n    { { 0x17173d131e6c0bb4L,0x1900469590776d35L,0xe7980e346de6f922L,\n        0x873554cbf4dd9a22L },\n      { 0x0316c627cbf18a51L,0x4d93651b3032c081L,0x207f27713946834dL,\n        0x2c08d7b430cdbf80L } },\n    /* 40 << 63 */\n    { { 0x137a4fb486df2a61L,0xa1ed9c07ecf7b4a2L,0xb2e460e27bd042ffL,\n        0xb7f5e2fa5f62f5ecL },\n      { 0x7aa6ec6bcc2423b7L,0x75ce0a7fba63eea7L,0x67a45fb1f250a6e1L,\n        0x93bc919ce53cdc9fL } },\n    /* 41 << 63 */\n    { { 0x9271f56f871942dfL,0x2372ff6f7859ad66L,0x5f4c2b9633cb1a78L,\n        0xe3e291015838aa83L },\n      { 0xa7ed1611e4e8110cL,0x2a2d70d5330198ceL,0xbdf132e86720efe0L,\n        0xe61a896266a471bfL } },\n    /* 42 << 63 */\n    { { 0x796d3a85825808bdL,0x51dc3cb73fd6e902L,0x643c768a916219d1L,\n        0x36cd7685a2ad7d32L },\n      { 0xe3db9d05b22922a4L,0x6494c87edba29660L,0xf0ac91dfbcd2ebc7L,\n        0x4deb57a045107f8dL } },\n    /* 43 << 63 */\n    { { 0x42271f59c3d12a73L,0x5f71687ca5c2c51dL,0xcb1f50c605797bcbL,\n        0x29ed0ed9d6d34eb0L },\n      { 0xe5fe5b474683c2ebL,0x4956eeb597447c46L,0x5b163a4371207167L,\n        0x93fa2fed0248c5efL } },\n    /* 44 << 63 */\n    { { 0x67930af231f63950L,0xa77797c114caa2c9L,0x526e80ee27ac7e62L,\n        0xe1e6e62658b28aecL },\n      { 0x636178b0b3c9fef0L,0xaf7752e06d5f90beL,0x94ecaf18eece51cfL,\n        0x2864d0edca806e1fL } },\n    /* 45 << 63 */\n    { { 0x6de2e38397c69134L,0x5a42c316eb291293L,0xc77792196a60bae0L,\n        0xa24de3466b7599d1L },\n      { 0x49d374aab75d4941L,0x989005862d501ff0L,0x9f16d40eeb7974cfL,\n        0x1033860bcdd8c115L } },\n    /* 46 << 63 */\n    { { 0xb6c69ac82094cec3L,0x9976fb88403b770cL,0x1dea026c4859590dL,\n        0xb6acbb468562d1fdL },\n      { 0x7cd6c46144569d85L,0xc3190a3697f0891dL,0xc6f5319548d5a17dL,\n        0x7d919966d749abc8L } },\n    /* 47 << 63 */\n    { { 0x65104837dd1c8a20L,0x7e5410c82f683419L,0x958c3ca8be94022eL,\n        0x605c31976145dac2L },\n      { 0x3fc0750101683d54L,0x1d7127c5595b1234L,0x10b8f87c9481277fL,\n        0x677db2a8e65a1adbL } },\n    /* 48 << 63 */\n    { { 0xec2fccaaddce3345L,0x2a6811b7012a4350L,0x96760ff1ac598bdcL,\n        0x054d652ad1bf4128L },\n      { 0x0a1151d492a21005L,0xad7f397133110fdfL,0x8c95928c1960100fL,\n        0x6c91c8257bf03362L } },\n    /* 49 << 63 */\n    { { 0xc8c8b2a2ce309f06L,0xfdb27b59ca27204bL,0xd223eaa50848e32eL,\n        0xb93e4b2ee7bfaf1eL },\n      { 0xc5308ae644aa3dedL,0x317a666ac015d573L,0xc888ce231a979707L,\n        0xf141c1e60d5c4958L } },\n    /* 50 << 63 */\n    { { 0xb53b7de561906373L,0x858dbadeeb999595L,0x8cbb47b2a59e5c36L,\n        0x660318b3dcf4e842L },\n      { 0xbd161ccd12ba4b7aL,0xf399daabf8c8282aL,0x1587633aeeb2130dL,\n        0xa465311ada38dd7dL } },\n    /* 51 << 63 */\n    { { 0x5f75eec864d3779bL,0x3c5d0476ad64c171L,0x874103712a914428L,\n        0x8096a89190e2fc29L },\n      { 0xd3d2ae9d23b3ebc2L,0x90bdd6dba580cfd6L,0x52dbb7f3c5b01f6cL,\n        0xe68eded4e102a2dcL } },\n    /* 52 << 63 */\n    { { 0x17785b7799eb6df0L,0x26c3cc517386b779L,0x345ed9886417a48eL,\n        0xe990b4e407d6ef31L },\n      { 0x0f456b7e2586abbaL,0x239ca6a559c96e9aL,0xe327459ce2eb4206L,\n        0x3a4c3313a002b90aL } },\n    /* 53 << 63 */\n    { { 0x2a114806f6a3f6fbL,0xad5cad2f85c251ddL,0x92c1f613f5a784d3L,\n        0xec7bfacf349766d5L },\n      { 0x04b3cd333e23cb3bL,0x3979fe84c5a64b2dL,0x192e27207e589106L,\n        0xa60c43d1a15b527fL } },\n    /* 54 << 63 */\n    { { 0x2dae9082be7cf3a6L,0xcc86ba92bc967274L,0xf28a2ce8aea0a8a9L,\n        0x404ca6d96ee988b3L },\n      { 0xfd7e9c5d005921b8L,0xf56297f144e79bf9L,0xa163b4600d75ddc2L,\n        0x30b23616a1f2be87L } },\n    /* 55 << 63 */\n    { { 0x4b070d21bfe50e2bL,0x7ef8cfd0e1bfede1L,0xadba00112aac4ae0L,\n        0x2a3e7d01b9ebd033L },\n      { 0x995277ece38d9d1cL,0xb500249e9c5d2de3L,0x8912b820f13ca8c9L,\n        0xc8798114877793afL } },\n    /* 56 << 63 */\n    { { 0x19e6125dec3f1decL,0x07b1f040911178daL,0xd93ededa904a6738L,\n        0x55187a5a0bebedcdL },\n      { 0xf7d04722eb329d41L,0xf449099ef170b391L,0xfd317a69ca99f828L,\n        0x50c3db2b34a4976dL } },\n    /* 57 << 63 */\n    { { 0xe9ba77843757b392L,0x326caefdaa3ca05aL,0x78e5293bf1e593d4L,\n        0x7842a9370d98fd13L },\n      { 0xe694bf965f96b10dL,0x373a9df606a8cd05L,0x997d1e51e8f0c7fcL,\n        0x1d01979063fd972eL } },\n    /* 58 << 63 */\n    { { 0x0064d8585499fb32L,0x7b67bad977a8aeb7L,0x1d3eb9772d08eec5L,\n        0x5fc047a6cbabae1dL },\n      { 0x0577d159e54a64bbL,0x8862201bc43497e4L,0xad6b4e282ce0608dL,\n        0x8b687b7d0b167aacL } },\n    /* 59 << 63 */\n    { { 0x6ed4d3678b2ecfa9L,0x24dfe62da90c3c38L,0xa1862e103fe5c42bL,\n        0x1ca73dcad5732a9fL },\n      { 0x35f038b776bb87adL,0x674976abf242b81fL,0x4f2bde7eb0fd90cdL,\n        0x6efc172ea7fdf092L } },\n    /* 60 << 63 */\n    { { 0x3806b69b92222f1fL,0x5a2459ca6cf7ae70L,0x6789f69ca85217eeL,\n        0x5f232b5ee3dc85acL },\n      { 0x660e3ec548e9e516L,0x124b4e473197eb31L,0x10a0cb13aafcca23L,\n        0x7bd63ba48213224fL } },\n    /* 61 << 63 */\n    { { 0xaffad7cc290a7f4fL,0x6b409c9e0286b461L,0x58ab809fffa407afL,\n        0xc3122eedc68ac073L },\n      { 0x17bf9e504ef24d7eL,0x5d9297943e2a5811L,0x519bc86702902e01L,\n        0x76bba5da39c8a851L } },\n    /* 62 << 63 */\n    { { 0xe9f9669cda94951eL,0x4b6af58d66b8d418L,0xfa32107417d426a4L,\n        0xc78e66a99dde6027L },\n      { 0x0516c0834a53b964L,0xfc659d38ff602330L,0x0ab55e5c58c5c897L,\n        0x985099b2838bc5dfL } },\n    /* 63 << 63 */\n    { { 0x061d9efcc52fc238L,0x712b27286ac1da3fL,0xfb6581499283fe08L,\n        0x4954ac94b8aaa2f7L },\n      { 0x85c0ada47fb2e74fL,0xee8ba98eb89926b0L,0xe4f9d37d23d1af5bL,\n        0x14ccdbf9ba9b015eL } },\n    /* 64 << 63 */\n    { { 0xb674481b7bfe7178L,0x4e1debae65405868L,0x061b2821c48c867dL,\n        0x69c15b35513b30eaL },\n      { 0x3b4a166636871088L,0xe5e29f5d1220b1ffL,0x4b82bb35233d9f4dL,\n        0x4e07633318cdc675L } },\n    /* 0 << 70 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 70 */\n    { { 0x0d53f5c7a3e6fcedL,0xe8cbbdd5f45fbdebL,0xf85c01df13339a70L,\n        0x0ff71880142ceb81L },\n      { 0x4c4e8774bd70437aL,0x5fb32891ba0bda6aL,0x1cdbebd2f18bd26eL,\n        0x2f9526f103a9d522L } },\n    /* 2 << 70 */\n    { { 0x40ce305192c4d684L,0x8b04d7257612efcdL,0xb9dcda366f9cae20L,\n        0x0edc4d24f058856cL },\n      { 0x64f2e6bf85427900L,0x3de81295dc09dfeaL,0xd41b4487379bf26cL,\n        0x50b62c6d6df135a9L } },\n    /* 3 << 70 */\n    { { 0xd4f8e3b4c72dfe67L,0xc416b0f690e19fdfL,0x18b9098d4c13bd35L,\n        0xac11118a15b8cb9eL },\n      { 0xf598a318f0062841L,0xbfe0602f89f356f4L,0x7ae3637e30177a0cL,\n        0x3409774761136537L } },\n    /* 4 << 70 */\n    { { 0x0db2fb5ed005832aL,0x5f5efd3b91042e4fL,0x8c4ffdc6ed70f8caL,\n        0xe4645d0bb52da9ccL },\n      { 0x9596f58bc9001d1fL,0x52c8f0bc4e117205L,0xfd4aa0d2e398a084L,\n        0x815bfe3a104f49deL } },\n    /* 5 << 70 */\n    { { 0x97e5443f23885e5fL,0xf72f8f99e8433aabL,0xbd00b154e4d4e604L,\n        0xd0b35e6ae5e173ffL },\n      { 0x57b2a0489164722dL,0x3e3c665b88761ec8L,0x6bdd13973da83832L,\n        0x3c8b1a1e73dafe3bL } },\n    /* 6 << 70 */\n    { { 0x4497ace654317cacL,0xbe600ab9521771b3L,0xb42e409eb0dfe8b8L,\n        0x386a67d73942310fL },\n      { 0x25548d8d4431cc28L,0xa7cff142985dc524L,0x4d60f5a193c4be32L,\n        0x83ebd5c8d071c6e1L } },\n    /* 7 << 70 */\n    { { 0xba3a80a7b1fd2b0bL,0x9b3ad3965bec33e8L,0xb3868d6179743fb3L,\n        0xcfd169fcfdb462faL },\n      { 0xd3b499d79ce0a6afL,0x55dc1cf1e42d3ff8L,0x04fb9e6cc6c3e1b2L,\n        0x47e6961d6f69a474L } },\n    /* 8 << 70 */\n    { { 0x54eb3acce548b37bL,0xb38e754284d40549L,0x8c3daa517b341b4fL,\n        0x2f6928ec690bf7faL },\n      { 0x0496b32386ce6c41L,0x01be1c5510adadcdL,0xc04e67e74bb5faf9L,\n        0x3cbaf678e15c9985L } },\n    /* 9 << 70 */\n    { { 0x8cd1214550ca4247L,0xba1aa47ae7dd30aaL,0x2f81ddf1e58fee24L,\n        0x03452936eec9b0e8L },\n      { 0x8bdc3b81243aea96L,0x9a2919af15c3d0e5L,0x9ea640ec10948361L,\n        0x5ac86d5b6e0bcccfL } },\n    /* 10 << 70 */\n    { { 0xf892d918c36cf440L,0xaed3e837c939719cL,0xb07b08d2c0218b64L,\n        0x6f1bcbbace9790ddL },\n      { 0x4a84d6ed60919b8eL,0xd89007918ac1f9ebL,0xf84941aa0dd5daefL,\n        0xb22fe40a67fd62c5L } },\n    /* 11 << 70 */\n    { { 0x97e15ba2157f2db3L,0xbda2fc8f8e28ca9cL,0x5d050da437b9f454L,\n        0x3d57eb572379d72eL },\n      { 0xe9b5eba2fb5ee997L,0x01648ca2e11538caL,0x32bb76f6f6327974L,\n        0x338f14b8ff3f4bb7L } },\n    /* 12 << 70 */\n    { { 0x524d226ad7ab9a2dL,0x9c00090d7dfae958L,0x0ba5f5398751d8c2L,\n        0x8afcbcdd3ab8262dL },\n      { 0x57392729e99d043bL,0xef51263baebc943aL,0x9feace9320862935L,\n        0x639efc03b06c817bL } },\n    /* 13 << 70 */\n    { { 0x1fe054b366b4be7aL,0x3f25a9de84a37a1eL,0xf39ef1ad78d75cd9L,\n        0xd7b58f495062c1b5L },\n      { 0x6f74f9a9ff563436L,0xf718ff29e8af51e7L,0x5234d31315e97fecL,\n        0xb6a8e2b1292f1c0aL } },\n    /* 14 << 70 */\n    { { 0xa7f53aa8327720c1L,0x956ca322ba092cc8L,0x8f03d64a28746c4dL,\n        0x51fe178266d0d392L },\n      { 0xd19b34db3c832c80L,0x60dccc5c6da2e3b4L,0x245dd62e0a104cccL,\n        0xa7ab1de1620b21fdL } },\n    /* 15 << 70 */\n    { { 0xb293ae0b3893d123L,0xf7b75783b15ee71cL,0x5aa3c61442a9468bL,\n        0xd686123cdb15d744L },\n      { 0x8c616891a7ab4116L,0x6fcd72c8a4e6a459L,0xac21911077e5fad7L,\n        0xfb6a20e7704fa46bL } },\n    /* 16 << 70 */\n    { { 0xe839be7d341d81dcL,0xcddb688932148379L,0xda6211a1f7026eadL,\n        0xf3b2575ff4d1cc5eL },\n      { 0x40cfc8f6a7a73ae6L,0x83879a5e61d5b483L,0xc5acb1ed41a50ebcL,\n        0x59a60cc83c07d8faL } },\n    /* 17 << 70 */\n    { { 0x1b73bdceb1876262L,0x2b0d79f012af4ee9L,0x8bcf3b0bd46e1d07L,\n        0x17d6af9de45d152fL },\n      { 0x735204616d736451L,0x43cbbd9756b0bf5aL,0xb0833a5bd5999b9dL,\n        0x702614f0eb72e398L } },\n    /* 18 << 70 */\n    { { 0x0aadf01a59c3e9f8L,0x40200e77ce6b3d16L,0xda22bdd3deddafadL,\n        0x76dedaf4310d72e1L },\n      { 0x49ef807c4bc2e88fL,0x6ba81291146dd5a5L,0xa1a4077a7d8d59e9L,\n        0x87b6a2e7802db349L } },\n    /* 19 << 70 */\n    { { 0xd56799971b4e598eL,0xf499ef1f06fe4b1dL,0x3978d3aefcb267c5L,\n        0xb582b557235786d0L },\n      { 0x32b3b2ca1715cb07L,0x4c3de6a28480241dL,0x63b5ffedcb571ecdL,\n        0xeaf53900ed2fe9a9L } },\n    /* 20 << 70 */\n    { { 0xdec98d4ac3b81990L,0x1cb837229e0cc8feL,0xfe0b0491d2b427b9L,\n        0x0f2386ace983a66cL },\n      { 0x930c4d1eb3291213L,0xa2f82b2e59a62ae4L,0x77233853f93e89e3L,\n        0x7f8063ac11777c7fL } },\n    /* 21 << 70 */\n    { { 0xff0eb56759ad2877L,0x6f4546429865c754L,0xe6fe701a236e9a84L,\n        0xc586ef1606e40fc3L },\n      { 0x3f62b6e024bafad9L,0xc8b42bd264da906aL,0xc98e1eb4da3276a0L,\n        0x30d0e5fc06cbf852L } },\n    /* 22 << 70 */\n    { { 0x1b6b2ae1e8b4dfd4L,0xd754d5c78301cbacL,0x66097629112a39acL,\n        0xf86b599993ba4ab9L },\n      { 0x26c9dea799f9d581L,0x0473b1a8c2fafeaaL,0x1469af553b2505a5L,\n        0x227d16d7d6a43323L } },\n    /* 23 << 70 */\n    { { 0x3316f73cad3d97f9L,0x52bf3bb51f137455L,0x953eafeb09954e7cL,\n        0xa721dfeddd732411L },\n      { 0xb4929821141d4579L,0x3411321caa3bd435L,0xafb355aa17fa6015L,\n        0xb4e7ef4a18e42f0eL } },\n    /* 24 << 70 */\n    { { 0x604ac97c59371000L,0xe1c48c707f759c18L,0x3f62ecc5a5db6b65L,\n        0x0a78b17338a21495L },\n      { 0x6be1819dbcc8ad94L,0x70dc04f6d89c3400L,0x462557b4a6b4840aL,\n        0x544c6ade60bd21c0L } },\n    /* 25 << 70 */\n    { { 0x6a00f24e907a544bL,0xa7520dcb313da210L,0xfe939b7511e4994bL,\n        0x918b6ba6bc275d70L },\n      { 0xd3e5e0fc644be892L,0x707a9816fdaf6c42L,0x60145567f15c13feL,\n        0x4818ebaae130a54aL } },\n    /* 26 << 70 */\n    { { 0x28aad3ad58d2f767L,0xdc5267fdd7e7c773L,0x4919cc88c3afcc98L,\n        0xaa2e6ab02db8cd4bL },\n      { 0xd46fec04d0c63eaaL,0xa1cb92c519ffa832L,0x678dd178e43a631fL,\n        0xfb5ae1cd3dc788b3L } },\n    /* 27 << 70 */\n    { { 0x68b4fb906e77de04L,0x7992bcf0f06dbb97L,0x896e6a13c417c01dL,\n        0x8d96332cb956be01L },\n      { 0x902fc93a413aa2b9L,0x99a4d915fc98c8a5L,0x52c29407565f1137L,\n        0x4072690f21e4f281L } },\n    /* 28 << 70 */\n    { { 0x36e607cf02ff6072L,0xa47d2ca98ad98cdcL,0xbf471d1ef5f56609L,\n        0xbcf86623f264ada0L },\n      { 0xb70c0687aa9e5cb6L,0xc98124f217401c6cL,0x8189635fd4a61435L,\n        0xd28fb8afa9d98ea6L } },\n    /* 29 << 70 */\n    { { 0xb9a67c2a40c251f8L,0x88cd5d87a2da44beL,0x437deb96e09b5423L,\n        0x150467db64287dc1L },\n      { 0xe161debbcdabb839L,0xa79e9742f1839a3eL,0xbb8dd3c2652d202bL,\n        0x7b3e67f7e9f97d96L } },\n    /* 30 << 70 */\n    { { 0x5aa5d78fb1cb6ac9L,0xffa13e8eca1d0d45L,0x369295dd2ba5bf95L,\n        0xd68bd1f839aff05eL },\n      { 0xaf0d86f926d783f2L,0x543a59b3fc3aafc1L,0x3fcf81d27b7da97cL,\n        0xc990a056d25dee46L } },\n    /* 31 << 70 */\n    { { 0x3e6775b8519cce2cL,0xfc9af71fae13d863L,0x774a4a6f47c1605cL,\n        0x46ba42452fd205e8L },\n      { 0xa06feea4d3fd524dL,0x1e7246416de1acc2L,0xf53816f1334e2b42L,\n        0x49e5918e922f0024L } },\n    /* 32 << 70 */\n    { { 0x439530b665c7322dL,0xcf12cc01b3c1b3fbL,0xc70b01860172f685L,\n        0xb915ee221b58391dL },\n      { 0x9afdf03ba317db24L,0x87dec65917b8ffc4L,0x7f46597be4d3d050L,\n        0x80a1c1ed006500e7L } },\n    /* 33 << 70 */\n    { { 0x84902a9678bf030eL,0xfb5e9c9a50560148L,0x6dae0a9263362426L,\n        0xdcaeecf4a9e30c40L },\n      { 0xc0d887bb518d0c6bL,0x99181152cb985b9dL,0xad186898ef7bc381L,\n        0x18168ffb9ee46201L } },\n    /* 34 << 70 */\n    { { 0x9a04cdaa2502753cL,0xbb279e2651407c41L,0xeacb03aaf23564e5L,\n        0x1833658271e61016L },\n      { 0x8684b8c4eb809877L,0xb336e18dea0e672eL,0xefb601f034ee5867L,\n        0x2733edbe1341cfd1L } },\n    /* 35 << 70 */\n    { { 0xb15e809a26025c3cL,0xe6e981a69350df88L,0x923762378502fd8eL,\n        0x4791f2160c12be9bL },\n      { 0xb725678925f02425L,0xec8631947a974443L,0x7c0ce882fb41cc52L,\n        0xc266ff7ef25c07f2L } },\n    /* 36 << 70 */\n    { { 0x3d4da8c3017025f3L,0xefcf628cfb9579b4L,0x5c4d00161f3716ecL,\n        0x9c27ebc46801116eL },\n      { 0x5eba0ea11da1767eL,0xfe15145247004c57L,0x3ace6df68c2373b7L,\n        0x75c3dffe5dbc37acL } },\n    /* 37 << 70 */\n    { { 0x3dc32a73ddc925fcL,0xb679c8412f65ee0bL,0x715a3295451cbfebL,\n        0xd9889768f76e9a29L },\n      { 0xec20ce7fb28ad247L,0xe99146c400894d79L,0x71457d7c9f5e3ea7L,\n        0x097b266238030031L } },\n    /* 38 << 70 */\n    { { 0xdb7f6ae6cf9f82a8L,0x319decb9438f473aL,0xa63ab386283856c3L,\n        0x13e3172fb06a361bL },\n      { 0x2959f8dc7d5a006cL,0x2dbc27c675fba752L,0xc1227ab287c22c9eL,\n        0x06f61f7571a268b2L } },\n    /* 39 << 70 */\n    { { 0x1b6bb97104779ce2L,0xaca838120aadcb1dL,0x297ae0bcaeaab2d5L,\n        0xa5c14ee75bfb9f13L },\n      { 0xaa00c583f17a62c7L,0x39eb962c173759f6L,0x1eeba1d486c9a88fL,\n        0x0ab6c37adf016c5eL } },\n    /* 40 << 70 */\n    { { 0xa2a147dba28a0749L,0x246c20d6ee519165L,0x5068d1b1d3810715L,\n        0xb1e7018c748160b9L },\n      { 0x03f5b1faf380ff62L,0xef7fb1ddf3cb2c1eL,0xeab539a8fc91a7daL,\n        0x83ddb707f3f9b561L } },\n    /* 41 << 70 */\n    { { 0xc550e211fe7df7a4L,0xa7cd07f2063f6f40L,0xb0de36352976879cL,\n        0xb5f83f85e55741daL },\n      { 0x4ea9d25ef3d8ac3dL,0x6fe2066f62819f02L,0x4ab2b9c2cef4a564L,\n        0x1e155d965ffa2de3L } },\n    /* 42 << 70 */\n    { { 0x0eb0a19bc3a72d00L,0x4037665b8513c31bL,0x2fb2b6bf04c64637L,\n        0x45c34d6e08cdc639L },\n      { 0x56f1e10ff01fd796L,0x4dfb8101fe3667b8L,0xe0eda2539021d0c0L,\n        0x7a94e9ff8a06c6abL } },\n    /* 43 << 70 */\n    { { 0x2d3bb0d9bb9aa882L,0xea20e4e5ec05fd10L,0xed7eeb5f1a1ca64eL,\n        0x2fa6b43cc6327cbdL },\n      { 0xb577e3cf3aa91121L,0x8c6bd5ea3a34079bL,0xd7e5ba3960e02fc0L,\n        0xf16dd2c390141bf8L } },\n    /* 44 << 70 */\n    { { 0xb57276d980101b98L,0x760883fdb82f0f66L,0x89d7de754bc3eff3L,\n        0x03b606435dc2ab40L },\n      { 0xcd6e53dfe05beeacL,0xf2f1e862bc3325cdL,0xdd0f7921774f03c3L,\n        0x97ca72214552cc1bL } },\n    /* 45 << 70 */\n    { { 0x5a0d6afe1cd19f72L,0xa20915dcf183fbebL,0x9fda4b40832c403cL,\n        0x32738eddbe425442L },\n      { 0x469a1df6b5eccf1aL,0x4b5aff4228bbe1f0L,0x31359d7f570dfc93L,\n        0xa18be235f0088628L } },\n    /* 46 << 70 */\n    { { 0xa5b30fbab00ed3a9L,0x34c6137473cdf8beL,0x2c5c5f46abc56797L,\n        0x5cecf93db82a8ae2L },\n      { 0x7d3dbe41a968fbf0L,0xd23d45831a5c7f3dL,0xf28f69a0c087a9c7L,\n        0xc2d75471474471caL } },\n    /* 47 << 70 */\n    { { 0x36ec9f4a4eb732ecL,0x6c943bbdb1ca6bedL,0xd64535e1f2457892L,\n        0x8b84a8eaf7e2ac06L },\n      { 0xe0936cd32499dd5fL,0x12053d7e0ed04e57L,0x4bdd0076e4305d9dL,\n        0x34a527b91f67f0a2L } },\n    /* 48 << 70 */\n    { { 0xe79a4af09cec46eaL,0xb15347a1658b9bc7L,0x6bd2796f35af2f75L,\n        0xac9579904051c435L },\n      { 0x2669dda3c33a655dL,0x5d503c2e88514aa3L,0xdfa113373753dd41L,\n        0x3f0546730b754f78L } },\n    /* 49 << 70 */\n    { { 0xbf185677496125bdL,0xfb0023c83775006cL,0xfa0f072f3a037899L,\n        0x4222b6eb0e4aea57L },\n      { 0x3dde5e767866d25aL,0xb6eb04f84837aa6fL,0x5315591a2cf1cdb8L,\n        0x6dfb4f412d4e683cL } },\n    /* 50 << 70 */\n    { { 0x7e923ea448ee1f3aL,0x9604d9f705a2afd5L,0xbe1d4a3340ea4948L,\n        0x5b45f1f4b44cbd2fL },\n      { 0x5faf83764acc757eL,0xa7cf9ab863d68ff7L,0x8ad62f69df0e404bL,\n        0xd65f33c212bdafdfL } },\n    /* 51 << 70 */\n    { { 0xc365de15a377b14eL,0x6bf5463b8e39f60cL,0x62030d2d2ce68148L,\n        0xd95867efe6f843a8L },\n      { 0xd39a0244ef5ab017L,0x0bd2d8c14ab55d12L,0xc9503db341639169L,\n        0x2d4e25b0f7660c8aL } },\n    /* 52 << 70 */\n    { { 0x760cb3b5e224c5d7L,0xfa3baf8c68616919L,0x9fbca1138d142552L,\n        0x1ab18bf17669ebf5L },\n      { 0x55e6f53e9bdf25ddL,0x04cc0bf3cb6cd154L,0x595bef4995e89080L,\n        0xfe9459a8104a9ac1L } },\n    /* 53 << 70 */\n    { { 0xad2d89cacce9bb32L,0xddea65e1f7de8285L,0x62ed8c35b351bd4bL,\n        0x4150ff360c0e19a7L },\n      { 0x86e3c801345f4e47L,0x3bf21f71203a266cL,0x7ae110d4855b1f13L,\n        0x5d6aaf6a07262517L } },\n    /* 54 << 70 */\n    { { 0x1e0f12e1813d28f1L,0x6000e11d7ad7a523L,0xc7d8deefc744a17bL,\n        0x1e990b4814c05a00L },\n      { 0x68fddaee93e976d5L,0x696241d146610d63L,0xb204e7c3893dda88L,\n        0x8bccfa656a3a6946L } },\n    /* 55 << 70 */\n    { { 0xb59425b4c5cd1411L,0x701b4042ff3658b1L,0xe3e56bca4784cf93L,\n        0x27de5f158fe68d60L },\n      { 0x4ab9cfcef8d53f19L,0xddb10311a40a730dL,0x6fa73cd14eee0a8aL,\n        0xfd5487485249719dL } },\n    /* 56 << 70 */\n    { { 0x49d66316a8123ef0L,0x73c32db4e7f95438L,0x2e2ed2090d9e7854L,\n        0xf98a93299d9f0507L },\n      { 0xc5d33cf60c6aa20aL,0x9a32ba1475279bb2L,0x7e3202cb774a7307L,\n        0x64ed4bc4e8c42dbdL } },\n    /* 57 << 70 */\n    { { 0xc20f1a06d4caed0dL,0xb8021407171d22b3L,0xd426ca04d13268d7L,\n        0x9237700725f4d126L },\n      { 0x4204cbc371f21a85L,0x18461b7af82369baL,0xc0c07d313fc858f9L,\n        0x5deb5a50e2bab569L } },\n    /* 58 << 70 */\n    { { 0xd5959d46d5eea89eL,0xfdff842408437f4bL,0xf21071e43cfe254fL,\n        0x7241769695468321L },\n      { 0x5d8288b9102cae3eL,0x2d143e3df1965dffL,0x00c9a376a078d847L,\n        0x6fc0da3126028731L } },\n    /* 59 << 70 */\n    { { 0xa2baeadfe45083a2L,0x66bc72185e5b4bcdL,0x2c826442d04b8e7fL,\n        0xc19f54516c4b586bL },\n      { 0x60182c495b7eeed5L,0xd9954ecd7aa9dfa1L,0xa403a8ecc73884adL,\n        0x7fb17de29bb39041L } },\n    /* 60 << 70 */\n    { { 0x694b64c5abb020e8L,0x3d18c18419c4eec7L,0x9c4673ef1c4793e5L,\n        0xc7b8aeb5056092e6L },\n      { 0x3aa1ca43f0f8c16bL,0x224ed5ecd679b2f6L,0x0d56eeaf55a205c9L,\n        0xbfe115ba4b8e028bL } },\n    /* 61 << 70 */\n    { { 0x97e608493927f4feL,0xf91fbf94759aa7c5L,0x985af7696be90a51L,\n        0xc1277b7878ccb823L },\n      { 0x395b656ee7a75952L,0x00df7de0928da5f5L,0x09c231754ca4454fL,\n        0x4ec971f47aa2d3c1L } },\n    /* 62 << 70 */\n    { { 0x45c3c507e75d9cccL,0x63b7be8a3dc90306L,0x37e09c665db44bdcL,\n        0x50d60da16841c6a2L },\n      { 0x6f9b65ee08df1b12L,0x387348797ff089dfL,0x9c331a663fe8013dL,\n        0x017f5de95f42fcc8L } },\n    /* 63 << 70 */\n    { { 0x43077866e8e57567L,0xc9f781cef9fcdb18L,0x38131dda9b12e174L,\n        0x25d84aa38a03752aL },\n      { 0x45e09e094d0c0ce2L,0x1564008b92bebba5L,0xf7e8ad31a87284c7L,\n        0xb7c4b46c97e7bbaaL } },\n    /* 64 << 70 */\n    { { 0x3e22a7b397acf4ecL,0x0426c4005ea8b640L,0x5e3295a64e969285L,\n        0x22aabc59a6a45670L },\n      { 0xb929714c5f5942bcL,0x9a6168bdfa3182edL,0x2216a665104152baL,\n        0x46908d03b6926368L } },\n    /* 0 << 77 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 77 */\n    { { 0xa9f5d8745a1251fbL,0x967747a8c72725c7L,0x195c33e531ffe89eL,\n        0x609d210fe964935eL },\n      { 0xcafd6ca82fe12227L,0xaf9b5b960426469dL,0x2e9ee04c5693183cL,\n        0x1084a333c8146fefL } },\n    /* 2 << 77 */\n    { { 0x96649933aed1d1f7L,0x566eaff350563090L,0x345057f0ad2e39cfL,\n        0x148ff65b1f832124L },\n      { 0x042e89d4cf94cf0dL,0x319bec84520c58b3L,0x2a2676265361aa0dL,\n        0xc86fa3028fbc87adL } },\n    /* 3 << 77 */\n    { { 0xfc83d2ab5c8b06d5L,0xb1a785a2fe4eac46L,0xb99315bc846f7779L,\n        0xcf31d816ef9ea505L },\n      { 0x2391fe6a15d7dc85L,0x2f132b04b4016b33L,0x29547fe3181cb4c7L,\n        0xdb66d8a6650155a1L } },\n    /* 4 << 77 */\n    { { 0x6b66d7e1adc1696fL,0x98ebe5930acd72d0L,0x65f24550cc1b7435L,\n        0xce231393b4b9a5ecL },\n      { 0x234a22d4db067df9L,0x98dda095caff9b00L,0x1bbc75a06100c9c1L,\n        0x1560a9c8939cf695L } },\n    /* 5 << 77 */\n    { { 0xcf006d3e99e0925fL,0x2dd74a966322375aL,0xc58b446ab56af5baL,\n        0x50292683e0b9b4f1L },\n      { 0xe2c34cb41aeaffa3L,0x8b17203f9b9587c1L,0x6d559207ead1350cL,\n        0x2b66a215fb7f9604L } },\n    /* 6 << 77 */\n    { { 0x0850325efe51bf74L,0x9c4f579e5e460094L,0x5c87b92a76da2f25L,\n        0x889de4e06febef33L },\n      { 0x6900ec06646083ceL,0xbe2a0335bfe12773L,0xadd1da35c5344110L,\n        0x757568b7b802cd20L } },\n    /* 7 << 77 */\n    { { 0x7555977900f7e6c8L,0x38e8b94f0facd2f0L,0xfea1f3af03fde375L,\n        0x5e11a1d875881dfcL },\n      { 0xb3a6b02ec1e2f2efL,0x193d2bbbc605a6c5L,0x325ffeee339a0b2dL,\n        0x27b6a7249e0c8846L } },\n    /* 8 << 77 */\n    { { 0xe4050f1cf1c367caL,0x9bc85a9bc90fbc7dL,0xa373c4a2e1a11032L,\n        0xb64232b7ad0393a9L },\n      { 0xf5577eb0167dad29L,0x1604f30194b78ab2L,0x0baa94afe829348bL,\n        0x77fbd8dd41654342L } },\n    /* 9 << 77 */\n    { { 0xdab50ea5b964e39aL,0xd4c29e3cd0d3c76eL,0x80dae67c56d11964L,\n        0x7307a8bfe5ffcc2fL },\n      { 0x65bbc1aa91708c3bL,0xa151e62c28bf0eebL,0x6cb533816fa34db7L,\n        0x5139e05ca29403a8L } },\n    /* 10 << 77 */\n    { { 0x6ff651b494a7cd2eL,0x5671ffd10699336cL,0x6f5fd2cc979a896aL,\n        0x11e893a8d8148cefL },\n      { 0x988906a165cf7b10L,0x81b67178c50d8485L,0x7c0deb358a35b3deL,\n        0x423ac855c1d29799L } },\n    /* 11 << 77 */\n    { { 0xaf580d87dac50b74L,0x28b2b89f5869734cL,0x99a3b936874e28fbL,\n        0xbb2c919025f3f73aL },\n      { 0x199f691884a9d5b7L,0x7ebe23257e770374L,0xf442e1070738efe2L,\n        0xcf9f3f56cf9082d2L } },\n    /* 12 << 77 */\n    { { 0x719f69e109618708L,0xcc9e8364c183f9b1L,0xec203a95366a21afL,\n        0x6aec5d6d068b141fL },\n      { 0xee2df78a994f04e9L,0xb39ccae8271245b0L,0xb875a4a997e43f4fL,\n        0x507dfe11db2cea98L } },\n    /* 13 << 77 */\n    { { 0x4fbf81cb489b03e9L,0xdb86ec5b6ec414faL,0xfad444f9f51b3ae5L,\n        0xca7d33d61914e3feL },\n      { 0xa9c32f5c0ae6c4d0L,0xa9ca1d1e73969568L,0x98043c311aa7467eL,\n        0xe832e75ce21b5ac6L } },\n    /* 14 << 77 */\n    { { 0x314b7aea5232123dL,0x08307c8c65ae86dbL,0x06e7165caa4668edL,\n        0xb170458bb4d3ec39L },\n      { 0x4d2e3ec6c19bb986L,0xc5f34846ae0304edL,0x917695a06c9f9722L,\n        0x6c7f73174cab1c0aL } },\n    /* 15 << 77 */\n    { { 0x6295940e9d6d2e8bL,0xd318b8c1549f7c97L,0x2245320497713885L,\n        0x468d834ba8a440feL },\n      { 0xd81fe5b2bfba796eL,0x152364db6d71f116L,0xbb8c7c59b5b66e53L,\n        0x0b12c61b2641a192L } },\n    /* 16 << 77 */\n    { { 0x31f14802fcf0a7fdL,0x42fd07895488b01eL,0x71d78d6d9952b498L,\n        0x8eb572d907ac5201L },\n      { 0xe0a2a44c4d194a88L,0xd2b63fd9ba017e66L,0x78efc6c8f888aefcL,\n        0xb76f6bda4a881a11L } },\n    /* 17 << 77 */\n    { { 0x187f314bb46c2397L,0x004cf5665ded2819L,0xa9ea570438764d34L,\n        0xbba4521778084709L },\n      { 0x064745711171121eL,0xad7b7eb1e7c9b671L,0xdacfbc40730f7507L,\n        0x178cd8c6c7ad7bd1L } },\n    /* 18 << 77 */\n    { { 0xbf0be101b2a67238L,0x3556d367af9c14f2L,0x104b7831a5662075L,\n        0x58ca59bb79d9e60aL },\n      { 0x4bc45392a569a73bL,0x517a52e85698f6c9L,0x85643da5aeadd755L,\n        0x1aed0cd52a581b84L } },\n    /* 19 << 77 */\n    { { 0xb9b4ff8480af1372L,0x244c3113f1ba5d1fL,0x2a5dacbef5f98d31L,\n        0x2c3323e84375bc2aL },\n      { 0x17a3ab4a5594b1ddL,0xa1928bfbceb4797eL,0xe83af245e4886a19L,\n        0x8979d54672b5a74aL } },\n    /* 20 << 77 */\n    { { 0xa0f726bc19f9e967L,0xd9d03152e8fbbf4eL,0xcfd6f51db7707d40L,\n        0x633084d963f6e6e0L },\n      { 0xedcd9cdc55667eafL,0x73b7f92b2e44d56fL,0xfb2e39b64e962b14L,\n        0x7d408f6ef671fcbfL } },\n    /* 21 << 77 */\n    { { 0xcc634ddc164a89bbL,0x74a42bb23ef3bd05L,0x1280dbb2428decbbL,\n        0x6103f6bb402c8596L },\n      { 0xfa2bf581355a5752L,0x562f96a800946674L,0x4e4ca16d6da0223bL,\n        0xfe47819f28d3aa25L } },\n    /* 22 << 77 */\n    { { 0x9eea3075f8dfcf8aL,0xa284f0aa95669825L,0xb3fca250867d3fd8L,\n        0x20757b5f269d691eL },\n      { 0xf2c2402093b8a5deL,0xd3f93359ebc06da6L,0x1178293eb2739c33L,\n        0xd2a3e770bcd686e5L } },\n    /* 23 << 77 */\n    { { 0xa76f49f4cd941534L,0x0d37406be3c71c0eL,0x172d93973b97f7e3L,\n        0xec17e239bd7fd0deL },\n      { 0xe32905516f496ba2L,0x6a69317236ad50e7L,0xc4e539a283e7eff5L,\n        0x752737e718e1b4cfL } },\n    /* 24 << 77 */\n    { { 0xa2f7932c68af43eeL,0x5502468e703d00bdL,0xe5dc978f2fb061f5L,\n        0xc9a1904a28c815adL },\n      { 0xd3af538d470c56a4L,0x159abc5f193d8cedL,0x2a37245f20108ef3L,\n        0xfa17081e223f7178L } },\n    /* 25 << 77 */\n    { { 0x27b0fb2b10c8c0f5L,0x2102c3ea40650547L,0x594564df8ac3bfa7L,\n        0x98102033509dad96L },\n      { 0x6989643ff1d18a13L,0x35eebd91d7fc5af0L,0x078d096afaeaafd8L,\n        0xb7a89341def3de98L } },\n    /* 26 << 77 */\n    { { 0x2a206e8decf2a73aL,0x066a63978e551994L,0x3a6a088ab98d53a2L,\n        0x0ce7c67c2d1124aaL },\n      { 0x48cec671759a113cL,0xe3b373d34f6f67faL,0x5455d479fd36727bL,\n        0xe5a428eea13c0d81L } },\n    /* 27 << 77 */\n    { { 0xb853dbc81c86682bL,0xb78d2727b8d02b2aL,0xaaf69bed8ebc329aL,\n        0xdb6b40b3293b2148L },\n      { 0xe42ea77db8c4961fL,0xb1a12f7c20e5e0abL,0xa0ec527479e8b05eL,\n        0x68027391fab60a80L } },\n    /* 28 << 77 */\n    { { 0x6bfeea5f16b1bd5eL,0xf957e4204de30ad3L,0xcbaf664e6a353b9eL,\n        0x5c87331226d14febL },\n      { 0x4e87f98cb65f57cbL,0xdb60a6215e0cdd41L,0x67c16865a6881440L,\n        0x1093ef1a46ab52aaL } },\n    /* 29 << 77 */\n    { { 0xc095afb53f4ece64L,0x6a6bb02e7604551aL,0x55d44b4e0b26b8cdL,\n        0xe5f9a999f971268aL },\n      { 0xc08ec42511a7de84L,0x83568095fda469ddL,0x737bfba16c6c90a2L,\n        0x1cb9c4a0be229831L } },\n    /* 30 << 77 */\n    { { 0x93bccbbabb2eec64L,0xa0c23b64da03adbeL,0x5f7aa00ae0e86ac4L,\n        0x470b941efc1401e6L },\n      { 0x5ad8d6799df43574L,0x4ccfb8a90f65d810L,0x1bce80e3aa7fbd81L,\n        0x273291ad9508d20aL } },\n    /* 31 << 77 */\n    { { 0xf5c4b46b42a92806L,0x810684eca86ab44aL,0x4591640bca0bc9f8L,\n        0xb5efcdfc5c4b6054L },\n      { 0x16fc89076e9edd12L,0xe29d0b50d4d792f9L,0xa45fd01c9b03116dL,\n        0x85035235c81765a4L } },\n    /* 32 << 77 */\n    { { 0x1fe2a9b2b4b4b67cL,0xc1d10df0e8020604L,0x9d64abfcbc8058d8L,\n        0x8943b9b2712a0fbbL },\n      { 0x90eed9143b3def04L,0x85ab3aa24ce775ffL,0x605fd4ca7bbc9040L,\n        0x8b34a564e2c75dfbL } },\n    /* 33 << 77 */\n    { { 0x41ffc94a10358560L,0x2d8a50729e5c28aaL,0xe915a0fc4cc7eb15L,\n        0xe9efab058f6d0f5dL },\n      { 0xdbab47a9d19e9b91L,0x8cfed7450276154cL,0x154357ae2cfede0dL,\n        0x520630df19f5a4efL } },\n    /* 34 << 77 */\n    { { 0x25759f7ce382360fL,0xb6db05c988bf5857L,0x2917d61d6c58d46cL,\n        0x14f8e491fd20cb7aL },\n      { 0xb68a727a11c20340L,0x0386f86faf7ccbb6L,0x5c8bc6ccfee09a20L,\n        0x7d76ff4abb7eea35L } },\n    /* 35 << 77 */\n    { { 0xa7bdebe7db15be7aL,0x67a08054d89f0302L,0x56bf0ea9c1193364L,\n        0xc824446762837ebeL },\n      { 0x32bd8e8b20d841b8L,0x127a0548dbb8a54fL,0x83dd4ca663b20236L,\n        0x87714718203491faL } },\n    /* 36 << 77 */\n    { { 0x4dabcaaaaa8a5288L,0x91cc0c8aaf23a1c9L,0x34c72c6a3f220e0cL,\n        0xbcc20bdf1232144aL },\n      { 0x6e2f42daa20ede1bL,0xc441f00c74a00515L,0xbf46a5b6734b8c4bL,\n        0x574095037b56c9a4L } },\n    /* 37 << 77 */\n    { { 0x9f735261e4585d45L,0x9231faed6734e642L,0x1158a176be70ee6cL,\n        0x35f1068d7c3501bfL },\n      { 0x6beef900a2d26115L,0x649406f2ef0afee3L,0x3f43a60abc2420a1L,\n        0x509002a7d5aee4acL } },\n    /* 38 << 77 */\n    { { 0xb46836a53ff3571bL,0x24f98b78837927c1L,0x6254256a4533c716L,\n        0xf27abb0bd07ee196L },\n      { 0xd7cf64fc5c6d5bfdL,0x6915c751f0cd7a77L,0xd9f590128798f534L,\n        0x772b0da8f81d8b5fL } },\n    /* 39 << 77 */\n    { { 0x1244260c2e03fa69L,0x36cf0e3a3be1a374L,0x6e7c1633ef06b960L,\n        0xa71a4c55671f90f6L },\n      { 0x7a94125133c673dbL,0xc0bea51073e8c131L,0x61a8a699d4f6c734L,\n        0x25e78c88341ed001L } },\n    /* 40 << 77 */\n    { { 0x5c18acf88e2f7d90L,0xfdbf33d777be32cdL,0x0a085cd7d2eb5ee9L,\n        0x2d702cfbb3201115L },\n      { 0xb6e0ebdb85c88ce8L,0x23a3ce3c1e01d617L,0x3041618e567333acL,\n        0x9dd0fd8f157edb6bL } },\n    /* 41 << 77 */\n    { { 0x27f74702b57872b8L,0x2ef26b4f657d5fe1L,0x95426f0a57cf3d40L,\n        0x847e2ad165a6067aL },\n      { 0xd474d9a009996a74L,0x16a56acd2a26115cL,0x02a615c3d16f4d43L,\n        0xcc3fc965aadb85b7L } },\n    /* 42 << 77 */\n    { { 0x386bda73ce07d1b0L,0xd82910c258ad4178L,0x124f82cfcd2617f4L,\n        0xcc2f5e8def691770L },\n      { 0x82702550b8c30cccL,0x7b856aea1a8e575aL,0xbb822fefb1ab9459L,\n        0x085928bcec24e38eL } },\n    /* 43 << 77 */\n    { { 0x5d0402ecba8f4b4dL,0xc07cd4ba00b4d58bL,0x5d8dffd529227e7aL,\n        0x61d44d0c31bf386fL },\n      { 0xe486dc2b135e6f4dL,0x680962ebe79410efL,0xa61bd343f10088b5L,\n        0x6aa76076e2e28686L } },\n    /* 44 << 77 */\n    { { 0x80463d118fb98871L,0xcb26f5c3bbc76affL,0xd4ab8eddfbe03614L,\n        0xc8eb579bc0cf2deeL },\n      { 0xcc004c15c93bae41L,0x46fbae5d3aeca3b2L,0x671235cf0f1e9ab1L,\n        0xadfba9349ec285c1L } },\n    /* 45 << 77 */\n    { { 0x88ded013f216c980L,0xc8ac4fb8f79e0bc1L,0xa29b89c6fb97a237L,\n        0xb697b7809922d8e7L },\n      { 0x3142c639ddb945b5L,0x447b06c7e094c3a9L,0xcdcb364272266c90L,\n        0x633aad08a9385046L } },\n    /* 46 << 77 */\n    { { 0xa36c936bb57c6477L,0x871f8b64e94dbcc6L,0x28d0fb62a591a67bL,\n        0x9d40e081c1d926f5L },\n      { 0x3111eaf6f2d84b5aL,0x228993f9a565b644L,0x0ccbf5922c83188bL,\n        0xf87b30ab3df3e197L } },\n    /* 47 << 77 */\n    { { 0xb8658b317642bca8L,0x1a032d7f52800f17L,0x051dcae579bf9445L,\n        0xeba6b8ee54a2e253L },\n      { 0x5c8b9cadd4485692L,0x84bda40e8986e9beL,0xd16d16a42f0db448L,\n        0x8ec80050a14d4188L } },\n    /* 48 << 77 */\n    { { 0xb2b2610798fa7aaaL,0x41209ee4f073aa4eL,0xf1570359f2d6b19bL,\n        0xcbe6868cfc577cafL },\n      { 0x186c4bdc32c04dd3L,0xa6c35faecfeee397L,0xb4a1b312f086c0cfL,\n        0xe0a5ccc6d9461fe2L } },\n    /* 49 << 77 */\n    { { 0xc32278aa1536189fL,0x1126c55fba6df571L,0x0f71a602b194560eL,\n        0x8b2d7405324bd6e1L },\n      { 0x8481939e3738be71L,0xb5090b1a1a4d97a9L,0x116c65a3f05ba915L,\n        0x21863ad3aae448aaL } },\n    /* 50 << 77 */\n    { { 0xd24e2679a7aae5d3L,0x7076013d0de5c1c4L,0x2d50f8babb05b629L,\n        0x73c1abe26e66efbbL },\n      { 0xefd4b422f2488af7L,0xe4105d02663ba575L,0x7eb60a8b53a69457L,\n        0x62210008c945973bL } },\n    /* 51 << 77 */\n    { { 0xfb25547877a50ec6L,0xbf0392f70a37a72cL,0xa0a7a19c4be18e7aL,\n        0x90d8ea1625b1e0afL },\n      { 0x7582a293ef953f57L,0x90a64d05bdc5465aL,0xca79c497e2510717L,\n        0x560dbb7c18cb641fL } },\n    /* 52 << 77 */\n    { { 0x1d8e32864b66abfbL,0xd26f52e559030900L,0x1ee3f6435584941aL,\n        0x6d3b3730569f5958L },\n      { 0x9ff2a62f4789dba5L,0x91fcb81572b5c9b7L,0xf446cb7d6c8f9a0eL,\n        0x48f625c139b7ecb5L } },\n    /* 53 << 77 */\n    { { 0xbabae8011c6219b8L,0xe7a562d928ac2f23L,0xe1b4873226e20588L,\n        0x06ee1cad775af051L },\n      { 0xda29ae43faff79f7L,0xc141a412652ee9e0L,0x1e127f6f195f4bd0L,\n        0x29c6ab4f072f34f8L } },\n    /* 54 << 77 */\n    { { 0x7b7c147730448112L,0x82b51af1e4a38656L,0x2bf2028a2f315010L,\n        0xc9a4a01f6ea88cd4L },\n      { 0xf63e95d8257e5818L,0xdd8efa10b4519b16L,0xed8973e00da910bfL,\n        0xed49d0775c0fe4a9L } },\n    /* 55 << 77 */\n    { { 0xac3aac5eb7caee1eL,0x1033898da7f4da57L,0x42145c0e5c6669b9L,\n        0x42daa688c1aa2aa0L },\n      { 0x629cc15c1a1d885aL,0x25572ec0f4b76817L,0x8312e4359c8f8f28L,\n        0x8107f8cd81965490L } },\n    /* 56 << 77 */\n    { { 0x516ff3a36fa6110cL,0x74fb1eb1fb93561fL,0x6c0c90478457522bL,\n        0xcfd321046bb8bdc6L },\n      { 0x2d6884a2cc80ad57L,0x7c27fc3586a9b637L,0x3461baedadf4e8cdL,\n        0x1d56251a617242f0L } },\n    /* 57 << 77 */\n    { { 0x0b80d209c955bef4L,0xdf02cad206adb047L,0xf0d7cb915ec74feeL,\n        0xd25033751111ba44L },\n      { 0x9671755edf53cb36L,0x54dcb6123368551bL,0x66d69aacc8a025a4L,\n        0x6be946c6e77ef445L } },\n    /* 58 << 77 */\n    { { 0x719946d1a995e094L,0x65e848f6e51e04d8L,0xe62f33006a1e3113L,\n        0x1541c7c1501de503L },\n      { 0x4daac9faf4acfadeL,0x0e58589744cd0b71L,0x544fd8690a51cd77L,\n        0x60fc20ed0031016dL } },\n    /* 59 << 77 */\n    { { 0x58b404eca4276867L,0x46f6c3cc34f34993L,0x477ca007c636e5bdL,\n        0x8018f5e57c458b47L },\n      { 0xa1202270e47b668fL,0xcef48ccdee14f203L,0x23f98bae62ff9b4dL,\n        0x55acc035c589edddL } },\n    /* 60 << 77 */\n    { { 0x3fe712af64db4444L,0x19e9d634becdd480L,0xe08bc047a930978aL,\n        0x2dbf24eca1280733L },\n      { 0x3c0ae38c2cd706b2L,0x5b012a5b359017b9L,0x3943c38c72e0f5aeL,\n        0x786167ea57176fa3L } },\n    /* 61 << 77 */\n    { { 0xe5f9897d594881dcL,0x6b5efad8cfb820c1L,0xb2179093d55018deL,\n        0x39ad7d320bac56ceL },\n      { 0xb55122e02cfc0e81L,0x117c4661f6d89daaL,0x362d01e1cb64fa09L,\n        0x6a309b4e3e9c4dddL } },\n    /* 62 << 77 */\n    { { 0xfa979fb7abea49b1L,0xb4b1d27d10e2c6c5L,0xbd61c2c423afde7aL,\n        0xeb6614f89786d358L },\n      { 0x4a5d816b7f6f7459L,0xe431a44f09360e7bL,0x8c27a032c309914cL,\n        0xcea5d68acaede3d8L } },\n    /* 63 << 77 */\n    { { 0x3668f6653a0a3f95L,0x893694167ceba27bL,0x89981fade4728fe9L,\n        0x7102c8a08a093562L },\n      { 0xbb80310e235d21c8L,0x505e55d1befb7f7bL,0xa0a9081112958a67L,\n        0xd67e106a4d851fefL } },\n    /* 64 << 77 */\n    { { 0xb84011a9431dd80eL,0xeb7c7cca73306cd9L,0x20fadd29d1b3b730L,\n        0x83858b5bfe37b3d3L },\n      { 0xbf4cd193b6251d5cL,0x1cca1fd31352d952L,0xc66157a490fbc051L,\n        0x7990a63889b98636L } },\n    /* 0 << 84 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 84 */\n    { { 0xe5aa692a87dec0e1L,0x010ded8df7b39d00L,0x7b1b80c854cfa0b5L,\n        0x66beb876a0f8ea28L },\n      { 0x50d7f5313476cd0eL,0xa63d0e65b08d3949L,0x1a09eea953479fc6L,\n        0x82ae9891f499e742L } },\n    /* 2 << 84 */\n    { { 0xab58b9105ca7d866L,0x582967e23adb3b34L,0x89ae4447cceac0bcL,\n        0x919c667c7bf56af5L },\n      { 0x9aec17b160f5dcd7L,0xec697b9fddcaadbcL,0x0b98f341463467f5L,\n        0xb187f1f7a967132fL } },\n    /* 3 << 84 */\n    { { 0x90fe7a1d214aeb18L,0x1506af3c741432f7L,0xbb5565f9e591a0c4L,\n        0x10d41a77b44f1bc3L },\n      { 0xa09d65e4a84bde96L,0x42f060d8f20a6a1cL,0x652a3bfdf27f9ce7L,\n        0xb6bdb65c3b3d739fL } },\n    /* 4 << 84 */\n    { { 0xeb5ddcb6ec7fae9fL,0x995f2714efb66e5aL,0xdee95d8e69445d52L,\n        0x1b6c2d4609e27620L },\n      { 0x32621c318129d716L,0xb03909f10958c1aaL,0x8c468ef91af4af63L,\n        0x162c429ffba5cdf6L } },\n    /* 5 << 84 */\n    { { 0x2f682343753b9371L,0x29cab45a5f1f9cd7L,0x571623abb245db96L,\n        0xc507db093fd79999L },\n      { 0x4e2ef652af036c32L,0x86f0cc7805018e5cL,0xc10a73d4ab8be350L,\n        0x6519b3977e826327L } },\n    /* 6 << 84 */\n    { { 0xe8cb5eef9c053df7L,0x8de25b37b300ea6fL,0xdb03fa92c849cffbL,\n        0x242e43a7e84169bbL },\n      { 0xe4fa51f4dd6f958eL,0x6925a77ff4445a8dL,0xe6e72a50e90d8949L,\n        0xc66648e32b1f6390L } },\n    /* 7 << 84 */\n    { { 0xb2ab1957173e460cL,0x1bbbce7530704590L,0xc0a90dbddb1c7162L,\n        0x505e399e15cdd65dL },\n      { 0x68434dcb57797ab7L,0x60ad35ba6a2ca8e8L,0x4bfdb1e0de3336c1L,\n        0xbbef99ebd8b39015L } },\n    /* 8 << 84 */\n    { { 0x6c3b96f31711ebecL,0x2da40f1fce98fdc4L,0xb99774d357b4411fL,\n        0x87c8bdf415b65bb6L },\n      { 0xda3a89e3c2eef12dL,0xde95bb9b3c7471f3L,0x600f225bd812c594L,\n        0x54907c5d2b75a56bL } },\n    /* 9 << 84 */\n    { { 0xa93cc5f08db60e35L,0x743e3cd6fa833319L,0x7dad5c41f81683c9L,\n        0x70c1e7d99c34107eL },\n      { 0x0edc4a39a6be0907L,0x36d4703586d0b7d3L,0x8c76da03272bfa60L,\n        0x0b4a07ea0f08a414L } },\n    /* 10 << 84 */\n    { { 0x699e4d2945c1dd53L,0xcadc5898231debb5L,0xdf49fcc7a77f00e0L,\n        0x93057bbfa73e5a0eL },\n      { 0x2f8b7ecd027a4cd1L,0x114734b3c614011aL,0xe7a01db767677c68L,\n        0x89d9be5e7e273f4fL } },\n    /* 11 << 84 */\n    { { 0xd225cb2e089808efL,0xf1f7a27dd59e4107L,0x53afc7618211b9c9L,\n        0x0361bc67e6819159L },\n      { 0x2a865d0b7f071426L,0x6a3c1810e7072567L,0x3e3bca1e0d6bcabdL,\n        0xa1b02bc1408591bcL } },\n    /* 12 << 84 */\n    { { 0xe0deee5931fba239L,0xf47424d398bd91d1L,0x0f8886f4071a3c1dL,\n        0x3f7d41e8a819233bL },\n      { 0x708623c2cf6eb998L,0x86bb49af609a287fL,0x942bb24963c90762L,\n        0x0ef6eea555a9654bL } },\n    /* 13 << 84 */\n    { { 0x5f6d2d7236f5defeL,0xfa9922dc56f99176L,0x6c8c5ecef78ce0c7L,\n        0x7b44589dbe09b55eL },\n      { 0xe11b3bca9ea83770L,0xd7fa2c7f2ab71547L,0x2a3dd6fa2a1ddcc0L,\n        0x09acb4305a7b7707L } },\n    /* 14 << 84 */\n    { { 0x4add4a2e649d4e57L,0xcd53a2b01917526eL,0xc526233020b44ac4L,\n        0x4028746abaa2c31dL },\n      { 0x5131839064291d4cL,0xbf48f151ee5ad909L,0xcce57f597b185681L,\n        0x7c3ac1b04854d442L } },\n    /* 15 << 84 */\n    { { 0x65587dc3c093c171L,0xae7acb2424f42b65L,0x5a338adb955996cbL,\n        0xc8e656756051f91bL },\n      { 0x66711fba28b8d0b1L,0x15d74137b6c10a90L,0x70cdd7eb3a232a80L,\n        0xc9e2f07f6191ed24L } },\n    /* 16 << 84 */\n    { { 0xa80d1db6f79588c0L,0xfa52fc69b55768ccL,0x0b4df1ae7f54438aL,\n        0x0cadd1a7f9b46a4fL },\n      { 0xb40ea6b31803dd6fL,0x488e4fa555eaae35L,0x9f047d55382e4e16L,\n        0xc9b5b7e02f6e0c98L } },\n    /* 17 << 84 */\n    { { 0x6b1bd2d395762649L,0xa9604ee7c7aea3f6L,0x3646ff276dc6f896L,\n        0x9bf0e7f52860bad1L },\n      { 0x2d92c8217cb44b92L,0xa2f5ce63aea9c182L,0xd0a2afb19154a5fdL,\n        0x482e474c95801da6L } },\n    /* 18 << 84 */\n    { { 0xc19972d0b611c24bL,0x1d468e6560a8f351L,0xeb7580697bcf6421L,\n        0xec9dd0ee88fbc491L },\n      { 0x5b59d2bf956c2e32L,0x73dc6864dcddf94eL,0xfd5e2321bcee7665L,\n        0xa7b4f8ef5e9a06c4L } },\n    /* 19 << 84 */\n    { { 0xfba918dd7280f855L,0xbbaac2608baec688L,0xa3b3f00f33400f42L,\n        0x3d2dba2966f2e6e4L },\n      { 0xb6f71a9498509375L,0x8f33031fcea423ccL,0x009b8dd04807e6fbL,\n        0x5163cfe55cdb954cL } },\n    /* 20 << 84 */\n    { { 0x03cc8f17cf41c6e8L,0xf1f03c2a037b925cL,0xc39c19cc66d2427cL,\n        0x823d24ba7b6c18e4L },\n      { 0x32ef9013901f0b4fL,0x684360f1f8941c2eL,0x0ebaff522c28092eL,\n        0x7891e4e3256c932fL } },\n    /* 21 << 84 */\n    { { 0x51264319ac445e3dL,0x553432e78ea74381L,0xe6eeaa6967e9c50aL,\n        0x27ced28462e628c7L },\n      { 0x3f96d3757a4afa57L,0xde0a14c3e484c150L,0x364a24eb38bd9923L,\n        0x1df18da0e5177422L } },\n    /* 22 << 84 */\n    { { 0x174e8f82d8d38a9bL,0x2e97c600e7de1391L,0xc5709850a1c175ddL,\n        0x969041a032ae5035L },\n      { 0xcbfd533b76a2086bL,0xd6bba71bd7c2e8feL,0xb2d58ee6099dfb67L,\n        0x3a8b342d064a85d9L } },\n    /* 23 << 84 */\n    { { 0x3bc07649522f9be3L,0x690c075bdf1f49a8L,0x80e1aee83854ec42L,\n        0x2a7dbf4417689dc7L },\n      { 0xc004fc0e3faf4078L,0xb2f02e9edf11862cL,0xf10a5e0fa0a1b7b3L,\n        0x30aca6238936ec80L } },\n    /* 24 << 84 */\n    { { 0xf83cbf0502f40d9aL,0x4681c4682c318a4dL,0x985756180e9c2674L,\n        0xbe79d0461847092eL },\n      { 0xaf1e480a78bd01e0L,0x6dd359e472a51db9L,0x62ce3821e3afbab6L,\n        0xc5cee5b617733199L } },\n    /* 25 << 84 */\n    { { 0xe08b30d46ffd9fbbL,0x6e5bc69936c610b7L,0xf343cff29ce262cfL,\n        0xca2e4e3568b914c1L },\n      { 0x011d64c016de36c5L,0xe0b10fdd42e2b829L,0x789429816685aaf8L,\n        0xe7511708230ede97L } },\n    /* 26 << 84 */\n    { { 0x671ed8fc3b922bf8L,0xe4d8c0a04c29b133L,0x87eb12393b6e99c4L,\n        0xaff3974c8793bebaL },\n      { 0x037494052c18df9bL,0xc5c3a29391007139L,0x6a77234fe37a0b95L,\n        0x02c29a21b661c96bL } },\n    /* 27 << 84 */\n    { { 0xc3aaf1d6141ecf61L,0x9195509e3bb22f53L,0x2959740422d51357L,\n        0x1b083822537bed60L },\n      { 0xcd7d6e35e07289f0L,0x1f94c48c6dd86effL,0xc8bb1f82eb0f9cfaL,\n        0x9ee0b7e61b2eb97dL } },\n    /* 28 << 84 */\n    { { 0x5a52fe2e34d74e31L,0xa352c3103bf79ab6L,0x97ff6c5aabfeeb8fL,\n        0xbfbe8feff5c97305L },\n      { 0xd6081ce6a7904608L,0x1f812f3ac4fca249L,0x9b24bc9ab9e5e200L,\n        0x91022c6738012ee8L } },\n    /* 29 << 84 */\n    { { 0xe83d9c5d30a713a1L,0x4876e3f084ef0f93L,0xc9777029c1fbf928L,\n        0xef7a6bb3bce7d2a4L },\n      { 0xb8067228dfa2a659L,0xd5cd3398d877a48fL,0xbea4fd8f025d0f3fL,\n        0xd67d2e352eae7c2bL } },\n    /* 30 << 84 */\n    { { 0x184de7d7cc5f4394L,0xb5551b5c4536e142L,0x2e89b212d34aa60aL,\n        0x14a96feaf50051d5L },\n      { 0x4e21ef740d12bb0bL,0xc522f02060b9677eL,0x8b12e4672df7731dL,\n        0x39f803827b326d31L } },\n    /* 31 << 84 */\n    { { 0xdfb8630c39024a94L,0xaacb96a897319452L,0xd68a3961eda3867cL,\n        0x0c58e2b077c4ffcaL },\n      { 0x3d545d634da919faL,0xef79b69af15e2289L,0x54bc3d3d808bab10L,\n        0xc8ab300745f82c37L } },\n    /* 32 << 84 */\n    { { 0xc12738b67c4a658aL,0xb3c4763940e72182L,0x3b77be468798e44fL,\n        0xdc047df217a7f85fL },\n      { 0x2439d4c55e59d92dL,0xcedca475e8e64d8dL,0xa724cd0d87ca9b16L,\n        0x35e4fd59a5540dfeL } },\n    /* 33 << 84 */\n    { { 0xf8c1ff18e4bcf6b1L,0x856d6285295018faL,0x433f665c3263c949L,\n        0xa6a76dd6a1f21409L },\n      { 0x17d32334cc7b4f79L,0xa1d0312206720e4aL,0xadb6661d81d9bed5L,\n        0xf0d6fb0211db15d1L } },\n    /* 34 << 84 */\n    { { 0x7fd11ad51fb747d2L,0xab50f9593033762bL,0x2a7e711bfbefaf5aL,\n        0xc73932783fef2bbfL },\n      { 0xe29fa2440df6f9beL,0x9092757b71efd215L,0xee60e3114f3d6fd9L,\n        0x338542d40acfb78bL } },\n    /* 35 << 84 */\n    { { 0x44a23f0838961a0fL,0x1426eade986987caL,0x36e6ee2e4a863cc6L,\n        0x48059420628b8b79L },\n      { 0x30303ad87396e1deL,0x5c8bdc4838c5aad1L,0x3e40e11f5c8f5066L,\n        0xabd6e7688d246bbdL } },\n    /* 36 << 84 */\n    { { 0x68aa40bb23330a01L,0xd23f5ee4c34eafa0L,0x3bbee3155de02c21L,\n        0x18dd4397d1d8dd06L },\n      { 0x3ba1939a122d7b44L,0xe6d3b40aa33870d6L,0x8e620f701c4fe3f8L,\n        0xf6bba1a5d3a50cbfL } },\n    /* 37 << 84 */\n    { { 0x4a78bde5cfc0aee0L,0x847edc46c08c50bdL,0xbaa2439cad63c9b2L,\n        0xceb4a72810fc2acbL },\n      { 0xa419e40e26da033dL,0x6cc3889d03e02683L,0x1cd28559fdccf725L,\n        0x0fd7e0f18d13d208L } },\n    /* 38 << 84 */\n    { { 0x01b9733b1f0df9d4L,0x8cc2c5f3a2b5e4f3L,0x43053bfa3a304fd4L,\n        0x8e87665c0a9f1aa7L },\n      { 0x087f29ecd73dc965L,0x15ace4553e9023dbL,0x2370e3092bce28b4L,\n        0xf9723442b6b1e84aL } },\n    /* 39 << 84 */\n    { { 0xbeee662eb72d9f26L,0xb19396def0e47109L,0x85b1fa73e13289d0L,\n        0x436cf77e54e58e32L },\n      { 0x0ec833b3e990ef77L,0x7373e3ed1b11fc25L,0xbe0eda870fc332ceL,\n        0xced049708d7ea856L } },\n    /* 40 << 84 */\n    { { 0xf85ff7857e977ca0L,0xb66ee8dadfdd5d2bL,0xf5e37950905af461L,\n        0x587b9090966d487cL },\n      { 0x6a198a1b32ba0127L,0xa7720e07141615acL,0xa23f3499996ef2f2L,\n        0xef5f64b4470bcb3dL } },\n    /* 41 << 84 */\n    { { 0xa526a96292b8c559L,0x0c14aac069740a0fL,0x0d41a9e3a6bdc0a5L,\n        0x97d521069c48aef4L },\n      { 0xcf16bd303e7c253bL,0xcc834b1a47fdedc1L,0x7362c6e5373aab2eL,\n        0x264ed85ec5f590ffL } },\n    /* 42 << 84 */\n    { { 0x7a46d9c066d41870L,0xa50c20b14787ba09L,0x185e7e51e3d44635L,\n        0xb3b3e08031e2d8dcL },\n      { 0xbed1e558a179e9d9L,0x2daa3f7974a76781L,0x4372baf23a40864fL,\n        0x46900c544fe75cb5L } },\n    /* 43 << 84 */\n    { { 0xb95f171ef76765d0L,0x4ad726d295c87502L,0x2ec769da4d7c99bdL,\n        0x5e2ddd19c36cdfa8L },\n      { 0xc22117fca93e6deaL,0xe8a2583b93771123L,0xbe2f6089fa08a3a2L,\n        0x4809d5ed8f0e1112L } },\n    /* 44 << 84 */\n    { { 0x3b414aa3da7a095eL,0x9049acf126f5aaddL,0x78d46a4d6be8b84aL,\n        0xd66b1963b732b9b3L },\n      { 0x5c2ac2a0de6e9555L,0xcf52d098b5bd8770L,0x15a15fa60fd28921L,\n        0x56ccb81e8b27536dL } },\n    /* 45 << 84 */\n    { { 0x0f0d8ab89f4ccbb8L,0xed5f44d2db221729L,0x4314198800bed10cL,\n        0xc94348a41d735b8bL },\n      { 0x79f3e9c429ef8479L,0x4c13a4e3614c693fL,0x32c9af568e143a14L,\n        0xbc517799e29ac5c4L } },\n    /* 46 << 84 */\n    { { 0x05e179922774856fL,0x6e52fb056c1bf55fL,0xaeda4225e4f19e16L,\n        0x70f4728aaf5ccb26L },\n      { 0x5d2118d1b2947f22L,0xc827ea16281d6fb9L,0x8412328d8cf0eabdL,\n        0x45ee9fb203ef9dcfL } },\n    /* 47 << 84 */\n    { { 0x8e700421bb937d63L,0xdf8ff2d5cc4b37a6L,0xa4c0d5b25ced7b68L,\n        0x6537c1efc7308f59L },\n      { 0x25ce6a263b37f8e8L,0x170e9a9bdeebc6ceL,0xdd0379528728d72cL,\n        0x445b0e55850154bcL } },\n    /* 48 << 84 */\n    { { 0x4b7d0e0683a7337bL,0x1e3416d4ffecf249L,0x24840eff66a2b71fL,\n        0xd0d9a50ab37cc26dL },\n      { 0xe21981506fe28ef7L,0x3cc5ef1623324c7fL,0x220f3455769b5263L,\n        0xe2ade2f1a10bf475L } },\n    /* 49 << 84 */\n    { { 0x28cd20fa458d3671L,0x1549722c2dc4847bL,0x6dd01e55591941e3L,\n        0x0e6fbcea27128ccbL },\n      { 0xae1a1e6b3bef0262L,0xfa8c472c8f54e103L,0x7539c0a872c052ecL,\n        0xd7b273695a3490e9L } },\n    /* 50 << 84 */\n    { { 0x143fe1f171684349L,0x36b4722e32e19b97L,0xdc05922790980affL,\n        0x175c9c889e13d674L },\n      { 0xa7de5b226e6bfdb1L,0x5ea5b7b2bedb4b46L,0xd5570191d34a6e44L,\n        0xfcf60d2ea24ff7e6L } },\n    /* 51 << 84 */\n    { { 0x614a392d677819e1L,0x7be74c7eaa5a29e8L,0xab50fece63c85f3fL,\n        0xaca2e2a946cab337L },\n      { 0x7f700388122a6fe3L,0xdb69f703882a04a8L,0x9a77935dcf7aed57L,\n        0xdf16207c8d91c86fL } },\n    /* 52 << 84 */\n    { { 0x2fca49ab63ed9998L,0xa3125c44a77ddf96L,0x05dd8a8624344072L,\n        0xa023dda2fec3fb56L },\n      { 0x421b41fc0c743032L,0x4f2120c15e438639L,0xfb7cae51c83c1b07L,\n        0xb2370caacac2171aL } },\n    /* 53 << 84 */\n    { { 0x2eb2d9626cc820fbL,0x59feee5cb85a44bfL,0x94620fca5b6598f0L,\n        0x6b922cae7e314051L },\n      { 0xff8745ad106bed4eL,0x546e71f5dfa1e9abL,0x935c1e481ec29487L,\n        0x9509216c4d936530L } },\n    /* 54 << 84 */\n    { { 0xc7ca306785c9a2dbL,0xd6ae51526be8606fL,0x09dbcae6e14c651dL,\n        0xc9536e239bc32f96L },\n      { 0xa90535a934521b03L,0xf39c526c878756ffL,0x383172ec8aedf03cL,\n        0x20a8075eefe0c034L } },\n    /* 55 << 84 */\n    { { 0xf22f9c6264026422L,0x8dd1078024b9d076L,0x944c742a3bef2950L,\n        0x55b9502e88a2b00bL },\n      { 0xa59e14b486a09817L,0xa39dd3ac47bb4071L,0x55137f663be0592fL,\n        0x07fcafd4c9e63f5bL } },\n    /* 56 << 84 */\n    { { 0x963652ee346eb226L,0x7dfab085ec2facb7L,0x273bf2b8691add26L,\n        0x30d74540f2b46c44L },\n      { 0x05e8e73ef2c2d065L,0xff9b8a00d42eeac9L,0x2fcbd20597209d22L,\n        0xeb740ffade14ea2cL } },\n    /* 57 << 84 */\n    { { 0xc71ff913a8aef518L,0x7bfc74bbfff4cfa2L,0x1716680cb6b36048L,\n        0x121b2cce9ef79af1L },\n      { 0xbff3c836a01eb3d3L,0x50eb1c6a5f79077bL,0xa48c32d6a004bbcfL,\n        0x47a593167d64f61dL } },\n    /* 58 << 84 */\n    { { 0x6068147f93102016L,0x12c5f65494d12576L,0xefb071a7c9bc6b91L,\n        0x7c2da0c56e23ea95L },\n      { 0xf4fd45b6d4a1dd5dL,0x3e7ad9b69122b13cL,0x342ca118e6f57a48L,\n        0x1c2e94a706f8288fL } },\n    /* 59 << 84 */\n    { { 0x99e68f075a97d231L,0x7c80de974d838758L,0xbce0f5d005872727L,\n        0xbe5d95c219c4d016L },\n      { 0x921d5cb19c2492eeL,0x42192dc1404d6fb3L,0x4c84dcd132f988d3L,\n        0xde26d61fa17b8e85L } },\n    /* 60 << 84 */\n    { { 0xc466dcb6137c7408L,0x9a38d7b636a266daL,0x7ef5cb0683bebf1bL,\n        0xe5cdcbbf0fd014e3L },\n      { 0x30aa376df65965a0L,0x60fe88c2ebb3e95eL,0x33fd0b6166ee6f20L,\n        0x8827dcdb3f41f0a0L } },\n    /* 61 << 84 */\n    { { 0xbf8a9d240c56c690L,0x40265dadddb7641dL,0x522b05bf3a6b662bL,\n        0x466d1dfeb1478c9bL },\n      { 0xaa6169621484469bL,0x0db6054902df8f9fL,0xc37bca023cb8bf51L,\n        0x5effe34621371ce8L } },\n    /* 62 << 84 */\n    { { 0xe8f65264ff112c32L,0x8a9c736d7b971fb2L,0xa4f194707b75080dL,\n        0xfc3f2c5a8839c59bL },\n      { 0x1d6c777e5aeb49c2L,0xf3db034dda1addfeL,0xd76fee5a5535affcL,\n        0x0853ac70b92251fdL } },\n    /* 63 << 84 */\n    { { 0x37e3d5948b2a29d5L,0x28f1f4574de00ddbL,0x8083c1b5f42c328bL,\n        0xd8ef1d8fe493c73bL },\n      { 0x96fb626041dc61bdL,0xf74e8a9d27ee2f8aL,0x7c605a802c946a5dL,\n        0xeed48d653839ccfdL } },\n    /* 64 << 84 */\n    { { 0x9894344f3a29467aL,0xde81e949c51eba6dL,0xdaea066ba5e5c2f2L,\n        0x3fc8a61408c8c7b3L },\n      { 0x7adff88f06d0de9fL,0xbbc11cf53b75ce0aL,0x9fbb7accfbbc87d5L,\n        0xa1458e267badfde2L } },\n    /* 0 << 91 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 91 */\n    { { 0x1cb43668e039c256L,0x5f26fb8b7c17fd5dL,0xeee426af79aa062bL,\n        0x072002d0d78fbf04L },\n      { 0x4c9ca237e84fb7e3L,0xb401d8a10c82133dL,0xaaa525926d7e4181L,\n        0xe943083373dbb152L } },\n    /* 2 << 91 */\n    { { 0xf92dda31be24319aL,0x03f7d28be095a8e7L,0xa52fe84098782185L,\n        0x276ddafe29c24dbcL },\n      { 0x80cd54961d7a64ebL,0xe43608897f1dbe42L,0x2f81a8778438d2d5L,\n        0x7e4d52a885169036L } },\n    /* 3 << 91 */\n    { { 0x19e3d5b11d59715dL,0xc7eaa762d788983eL,0xe5a730b0abf1f248L,\n        0xfbab8084fae3fd83L },\n      { 0x65e50d2153765b2fL,0xbdd4e083fa127f3dL,0x9cf3c074397b1b10L,\n        0x59f8090cb1b59fd3L } },\n    /* 4 << 91 */\n    { { 0x7b15fd9d615faa8fL,0x8fa1eb40968554edL,0x7bb4447e7aa44882L,\n        0x2bb2d0d1029fff32L },\n      { 0x075e2a646caa6d2fL,0x8eb879de22e7351bL,0xbcd5624e9a506c62L,\n        0x218eaef0a87e24dcL } },\n    /* 5 << 91 */\n    { { 0x37e5684744ddfa35L,0x9ccfc5c5dab3f747L,0x9ac1df3f1ee96cf4L,\n        0x0c0571a13b480b8fL },\n      { 0x2fbeb3d54b3a7b3cL,0x35c036695dcdbb99L,0x52a0f5dcb2415b3aL,\n        0xd57759b44413ed9aL } },\n    /* 6 << 91 */\n    { { 0x1fe647d83d30a2c5L,0x0857f77ef78a81dcL,0x11d5a334131a4a9bL,\n        0xc0a94af929d393f5L },\n      { 0xbc3a5c0bdaa6ec1aL,0xba9fe49388d2d7edL,0xbb4335b4bb614797L,\n        0x991c4d6872f83533L } },\n    /* 7 << 91 */\n    { { 0x53258c28d2f01cb3L,0x93d6eaa3d75db0b1L,0x419a2b0de87d0db4L,\n        0xa1e48f03d8fe8493L },\n      { 0xf747faf6c508b23aL,0xf137571a35d53549L,0x9f5e58e2fcf9b838L,\n        0xc7186ceea7fd3cf5L } },\n    /* 8 << 91 */\n    { { 0x77b868cee978a1d3L,0xe3a68b337ab92d04L,0x5102979487a5b862L,\n        0x5f0606c33a61d41dL },\n      { 0x2814be276f9326f1L,0x2f521c14c6fe3c2eL,0x17464d7dacdf7351L,\n        0x10f5f9d3777f7e44L } },\n    /* 9 << 91 */\n    { { 0xce8e616b269fb37dL,0xaaf738047de62de5L,0xaba111754fdd4153L,\n        0x515759ba3770b49bL },\n      { 0x8b09ebf8aa423a61L,0x592245a1cd41fb92L,0x1cba8ec19b4c8936L,\n        0xa87e91e3af36710eL } },\n    /* 10 << 91 */\n    { { 0x1fd84ce43d34a2e3L,0xee3759ceb43b5d61L,0x895bc78c619186c7L,\n        0xf19c3809cbb9725aL },\n      { 0xc0be21aade744b1fL,0xa7d222b060f8056bL,0x74be6157b23efe11L,\n        0x6fab2b4f0cd68253L } },\n    /* 11 << 91 */\n    { { 0xad33ea5f4bf1d725L,0x9c1d8ee24f6c950fL,0x544ee78aa377af06L,\n        0x54f489bb94a113e1L },\n      { 0x8f11d634992fb7e8L,0x0169a7aaa2a44347L,0x1d49d4af95020e00L,\n        0x95945722e08e120bL } },\n    /* 12 << 91 */\n    { { 0xb6e33878a4d32282L,0xe36e029d48020ae7L,0xe05847fb37a9b750L,\n        0xf876812cb29e3819L },\n      { 0x84ad138ed23a17f0L,0x6d7b4480f0b3950eL,0xdfa8aef42fd67ae0L,\n        0x8d3eea2452333af6L } },\n    /* 13 << 91 */\n    { { 0x0d052075b15d5accL,0xc6d9c79fbd815bc4L,0x8dcafd88dfa36cf2L,\n        0x908ccbe238aa9070L },\n      { 0x638722c4ba35afceL,0x5a3da8b0fd6abf0bL,0x2dce252cc9c335c1L,\n        0x84e7f0de65aa799bL } },\n    /* 14 << 91 */\n    { { 0x2101a522b99a72cbL,0x06de6e6787618016L,0x5ff8c7cde6f3653eL,\n        0x0a821ab5c7a6754aL },\n      { 0x7e3fa52b7cb0b5a2L,0xa7fb121cc9048790L,0x1a72502006ce053aL,\n        0xb490a31f04e929b0L } },\n    /* 15 << 91 */\n    { { 0xe17be47d62dd61adL,0x781a961c6be01371L,0x1063bfd3dae3cbbaL,\n        0x356474067f73c9baL },\n      { 0xf50e957b2736a129L,0xa6313702ed13f256L,0x9436ee653a19fcc5L,\n        0xcf2bdb29e7a4c8b6L } },\n    /* 16 << 91 */\n    { { 0xb06b1244c5f95cd8L,0xda8c8af0f4ab95f4L,0x1bae59c2b9e5836dL,\n        0x07d51e7e3acffffcL },\n      { 0x01e15e6ac2ccbcdaL,0x3bc1923f8528c3e0L,0x43324577a49fead4L,\n        0x61a1b8842aa7a711L } },\n    /* 17 << 91 */\n    { { 0xf9a86e08700230efL,0x0af585a1bd19adf8L,0x7645f361f55ad8f2L,\n        0x6e67622346c3614cL },\n      { 0x23cb257c4e774d3fL,0x82a38513ac102d1bL,0x9bcddd887b126aa5L,\n        0xe716998beefd3ee4L } },\n    /* 18 << 91 */\n    { { 0x4239d571fb167583L,0xdd011c78d16c8f8aL,0x271c289569a27519L,\n        0x9ce0a3b7d2d64b6aL },\n      { 0x8c977289d5ec6738L,0xa3b49f9a8840ef6bL,0x808c14c99a453419L,\n        0x5c00295b0cf0a2d5L } },\n    /* 19 << 91 */\n    { { 0x524414fb1d4bcc76L,0xb07691d2459a88f1L,0x77f43263f70d110fL,\n        0x64ada5e0b7abf9f3L },\n      { 0xafd0f94e5b544cf5L,0xb4a13a15fd2713feL,0xb99b7d6e250c74f4L,\n        0x097f2f7320324e45L } },\n    /* 20 << 91 */\n    { { 0x994b37d8affa8208L,0xc3c31b0bdc29aafcL,0x3da746517a3a607fL,\n        0xd8e1b8c1fe6955d6L },\n      { 0x716e1815c8418682L,0x541d487f7dc91d97L,0x48a04669c6996982L,\n        0xf39cab1583a6502eL } },\n    /* 21 << 91 */\n    { { 0x025801a0e68db055L,0xf3569758ba3338d5L,0xb0c8c0aaee2afa84L,\n        0x4f6985d3fb6562d1L },\n      { 0x351f1f15132ed17aL,0x510ed0b4c04365feL,0xa3f98138e5b1f066L,\n        0xbc9d95d632df03dcL } },\n    /* 22 << 91 */\n    { { 0xa83ccf6e19abd09eL,0x0b4097c14ff17edbL,0x58a5c478d64a06ceL,\n        0x2ddcc3fd544a58fdL },\n      { 0xd449503d9e8153b8L,0x3324fd027774179bL,0xaf5d47c8dbd9120cL,\n        0xeb86016234fa94dbL } },\n    /* 23 << 91 */\n    { { 0x5817bdd1972f07f4L,0xe5579e2ed27bbcebL,0x86847a1f5f11e5a6L,\n        0xb39ed2557c3cf048L },\n      { 0xe1076417a2f62e55L,0x6b9ab38f1bcf82a2L,0x4bb7c3197aeb29f9L,\n        0xf6d17da317227a46L } },\n    /* 24 << 91 */\n    { { 0xab53ddbd0f968c00L,0xa03da7ec000c880bL,0x7b2396246a9ad24dL,\n        0x612c040101ec60d0L },\n      { 0x70d10493109f5df1L,0xfbda403080af7550L,0x30b93f95c6b9a9b3L,\n        0x0c74ec71007d9418L } },\n    /* 25 << 91 */\n    { { 0x941755646edb951fL,0x5f4a9d787f22c282L,0xb7870895b38d1196L,\n        0xbc593df3a228ce7cL },\n      { 0xc78c5bd46af3641aL,0x7802200b3d9b3dccL,0x0dc73f328be33304L,\n        0x847ed87d61ffb79aL } },\n    /* 26 << 91 */\n    { { 0xf85c974e6d671192L,0x1e14100ade16f60fL,0x45cb0d5a95c38797L,\n        0x18923bba9b022da4L },\n      { 0xef2be899bbe7e86eL,0x4a1510ee216067bfL,0xd98c815484d5ce3eL,\n        0x1af777f0f92a2b90L } },\n    /* 27 << 91 */\n    { { 0x9fbcb4004ef65724L,0x3e04a4c93c0ca6feL,0xfb3e2cb555002994L,\n        0x1f3a93c55363ecabL },\n      { 0x1fe00efe3923555bL,0x744bedd91e1751eaL,0x3fb2db596ab69357L,\n        0x8dbd7365f5e6618bL } },\n    /* 28 << 91 */\n    { { 0x99d53099df1ea40eL,0xb3f24a0b57d61e64L,0xd088a198596eb812L,\n        0x22c8361b5762940bL },\n      { 0x66f01f97f9c0d95cL,0x884611728e43cdaeL,0x11599a7fb72b15c3L,\n        0x135a7536420d95ccL } },\n    /* 29 << 91 */\n    { { 0x2dcdf0f75f7ae2f6L,0x15fc6e1dd7fa6da2L,0x81ca829ad1d441b6L,\n        0x84c10cf804a106b6L },\n      { 0xa9b26c95a73fbbd0L,0x7f24e0cb4d8f6ee8L,0x48b459371e25a043L,\n        0xf8a74fca036f3dfeL } },\n    /* 30 << 91 */\n    { { 0x1ed46585c9f84296L,0x7fbaa8fb3bc278b0L,0xa8e96cd46c4fcbd0L,\n        0x940a120273b60a5fL },\n      { 0x34aae12055a4aec8L,0x550e9a74dbd742f0L,0x794456d7228c68abL,\n        0x492f8868a4e25ec6L } },\n    /* 31 << 91 */\n    { { 0x682915adb2d8f398L,0xf13b51cc5b84c953L,0xcda90ab85bb917d6L,\n        0x4b6155604ea3dee1L },\n      { 0x578b4e850a52c1c8L,0xeab1a69520b75fc4L,0x60c14f3caa0bb3c6L,\n        0x220f448ab8216094L } },\n    /* 32 << 91 */\n    { { 0x4fe7ee31b0e63d34L,0xf4600572a9e54fabL,0xc0493334d5e7b5a4L,\n        0x8589fb9206d54831L },\n      { 0xaa70f5cc6583553aL,0x0879094ae25649e5L,0xcc90450710044652L,\n        0xebb0696d02541c4fL } },\n    /* 33 << 91 */\n    { { 0x5a171fdeb9718710L,0x38f1bed8f374a9f5L,0xc8c582e1ba39bdc1L,\n        0xfc457b0a908cc0ceL },\n      { 0x9a187fd4883841e2L,0x8ec25b3938725381L,0x2553ed0596f84395L,\n        0x095c76616f6c6897L } },\n    /* 34 << 91 */\n    { { 0x917ac85c4bdc5610L,0xb2885fe4179eb301L,0x5fc655478b78bdccL,\n        0x4a9fc893e59e4699L },\n      { 0xbb7ff0cd3ce299afL,0x195be9b3adf38b20L,0x6a929c87d38ddb8fL,\n        0x55fcc99cb21a51b9L } },\n    /* 35 << 91 */\n    { { 0x2b695b4c721a4593L,0xed1e9a15768eaac2L,0xfb63d71c7489f914L,\n        0xf98ba31c78118910L },\n      { 0x802913739b128eb4L,0x7801214ed448af4aL,0xdbd2e22b55418dd3L,\n        0xeffb3c0dd3998242L } },\n    /* 36 << 91 */\n    { { 0xdfa6077cc7bf3827L,0xf2165bcb47f8238fL,0xfe37cf688564d554L,\n        0xe5f825c40a81fb98L },\n      { 0x43cc4f67ffed4d6fL,0xbc609578b50a34b0L,0x8aa8fcf95041faf1L,\n        0x5659f053651773b6L } },\n    /* 37 << 91 */\n    { { 0xe87582c36044d63bL,0xa60894090cdb0ca0L,0x8c993e0fbfb2bcf6L,\n        0xfc64a71945985cfcL },\n      { 0x15c4da8083dbedbaL,0x804ae1122be67df7L,0xda4c9658a23defdeL,\n        0x12002ddd5156e0d3L } },\n    /* 38 << 91 */\n    { { 0xe68eae895dd21b96L,0x8b99f28bcf44624dL,0x0ae008081ec8897aL,\n        0xdd0a93036712f76eL },\n      { 0x962375224e233de4L,0x192445b12b36a8a5L,0xabf9ff74023993d9L,\n        0x21f37bf42aad4a8fL } },\n    /* 39 << 91 */\n    { { 0x340a4349f8bd2bbdL,0x1d902cd94868195dL,0x3d27bbf1e5fdb6f1L,\n        0x7a5ab088124f9f1cL },\n      { 0xc466ab06f7a09e03L,0x2f8a197731f2c123L,0xda355dc7041b6657L,\n        0xcb840d128ece2a7cL } },\n    /* 40 << 91 */\n    { { 0xb600ad9f7db32675L,0x78fea13307a06f1bL,0x5d032269b31f6094L,\n        0x07753ef583ec37aaL },\n      { 0x03485aed9c0bea78L,0x41bb3989bc3f4524L,0x09403761697f726dL,\n        0x6109beb3df394820L } },\n    /* 41 << 91 */\n    { { 0x804111ea3b6d1145L,0xb6271ea9a8582654L,0x619615e624e66562L,\n        0xa2554945d7b6ad9cL },\n      { 0xd9c4985e99bfe35fL,0x9770ccc07b51cdf6L,0x7c32701392881832L,\n        0x8777d45f286b26d1L } },\n    /* 42 << 91 */\n    { { 0x9bbeda22d847999dL,0x03aa33b6c3525d32L,0x4b7b96d428a959a1L,\n        0xbb3786e531e5d234L },\n      { 0xaeb5d3ce6961f247L,0x20aa85af02f93d3fL,0x9cd1ad3dd7a7ae4fL,\n        0xbf6688f0781adaa8L } },\n    /* 43 << 91 */\n    { { 0xb1b40e867469ceadL,0x1904c524309fca48L,0x9b7312af4b54bbc7L,\n        0xbe24bf8f593affa2L },\n      { 0xbe5e0790bd98764bL,0xa0f45f17a26e299eL,0x4af0d2c26b8fe4c7L,\n        0xef170db18ae8a3e6L } },\n    /* 44 << 91 */\n    { { 0x0e8d61a029e0ccc1L,0xcd53e87e60ad36caL,0x328c6623c8173822L,\n        0x7ee1767da496be55L },\n      { 0x89f13259648945afL,0x9e45a5fd25c8009cL,0xaf2febd91f61ab8cL,\n        0x43f6bc868a275385L } },\n    /* 45 << 91 */\n    { { 0x87792348f2142e79L,0x17d89259c6e6238aL,0x7536d2f64a839d9bL,\n        0x1f428fce76a1fbdcL },\n      { 0x1c1096010db06dfeL,0xbfc16bc150a3a3ccL,0xf9cbd9ec9b30f41bL,\n        0x5b5da0d600138cceL } },\n    /* 46 << 91 */\n    { { 0xec1d0a4856ef96a7L,0xb47eb848982bf842L,0x66deae32ec3f700dL,\n        0x4e43c42caa1181e0L },\n      { 0xa1d72a31d1a4aa2aL,0x440d4668c004f3ceL,0x0d6a2d3b45fe8a7aL,\n        0x820e52e2fb128365L } },\n    /* 47 << 91 */\n    { { 0x29ac5fcf25e51b09L,0x180cd2bf2023d159L,0xa9892171a1ebf90eL,\n        0xf97c4c877c132181L },\n      { 0x9f1dc724c03dbb7eL,0xae043765018cbbe4L,0xfb0b2a360767d153L,\n        0xa8e2f4d6249cbaebL } },\n    /* 48 << 91 */\n    { { 0x172a5247d95ea168L,0x1758fada2970764aL,0xac803a511d978169L,\n        0x299cfe2ede77e01bL },\n      { 0x652a1e17b0a98927L,0x2e26e1d120014495L,0x7ae0af9f7175b56aL,\n        0xc2e22a80d64b9f95L } },\n    /* 49 << 91 */\n    { { 0x4d0ff9fbd90a060aL,0x496a27dbbaf38085L,0x32305401da776bcfL,\n        0xb8cdcef6725f209eL },\n      { 0x61ba0f37436a0bbaL,0x263fa10876860049L,0x92beb98eda3542cfL,\n        0xa2d4d14ad5849538L } },\n    /* 50 << 91 */\n    { { 0x989b9d6812e9a1bcL,0x61d9075c5f6e3268L,0x352c6aa999ace638L,\n        0xde4e4a55920f43ffL },\n      { 0xe5e4144ad673c017L,0x667417ae6f6e05eaL,0x613416aedcd1bd56L,\n        0x5eb3620186693711L } },\n    /* 51 << 91 */\n    { { 0x2d7bc5043a1aa914L,0x175a129976dc5975L,0xe900e0f23fc8125cL,\n        0x569ef68c11198875L },\n      { 0x9012db6363a113b4L,0xe3bd3f5698835766L,0xa5c94a5276412deaL,\n        0xad9e2a09aa735e5cL } },\n    /* 52 << 91 */\n    { { 0x405a984c508b65e9L,0xbde4a1d16df1a0d1L,0x1a9433a1dfba80daL,\n        0xe9192ff99440ad2eL },\n      { 0x9f6496965099fe92L,0x25ddb65c0b27a54aL,0x178279ddc590da61L,\n        0x5479a999fbde681aL } },\n    /* 53 << 91 */\n    { { 0xd0e84e05013fe162L,0xbe11dc92632d471bL,0xdf0b0c45fc0e089fL,\n        0x04fb15b04c144025L },\n      { 0xa61d5fc213c99927L,0xa033e9e03de2eb35L,0xf8185d5cb8dacbb4L,\n        0x9a88e2658644549dL } },\n    /* 54 << 91 */\n    { { 0xf717af6254671ff6L,0x4bd4241b5fa58603L,0x06fba40be67773c0L,\n        0xc1d933d26a2847e9L },\n      { 0xf4f5acf3689e2c70L,0x92aab0e746bafd31L,0x798d76aa3473f6e5L,\n        0xcc6641db93141934L } },\n    /* 55 << 91 */\n    { { 0xcae27757d31e535eL,0x04cc43b687c2ee11L,0x8d1f96752e029ffaL,\n        0xc2150672e4cc7a2cL },\n      { 0x3b03c1e08d68b013L,0xa9d6816fedf298f3L,0x1bfbb529a2804464L,\n        0x95a52fae5db22125L } },\n    /* 56 << 91 */\n    { { 0x55b321600e1cb64eL,0x004828f67e7fc9feL,0x13394b821bb0fb93L,\n        0xb6293a2d35f1a920L },\n      { 0xde35ef21d145d2d9L,0xbe6225b3bb8fa603L,0x00fc8f6b32cf252dL,\n        0xa28e52e6117cf8c2L } },\n    /* 57 << 91 */\n    { { 0x9d1dc89b4c371e6dL,0xcebe067536ef0f28L,0x5de05d09a4292f81L,\n        0xa8303593353e3083L },\n      { 0xa1715b0a7e37a9bbL,0x8c56f61e2b8faec3L,0x5250743133c9b102L,\n        0x0130cefca44431f0L } },\n    /* 58 << 91 */\n    { { 0x56039fa0bd865cfbL,0x4b03e578bc5f1dd7L,0x40edf2e4babe7224L,\n        0xc752496d3a1988f6L },\n      { 0xd1572d3b564beb6bL,0x0db1d11039a1c608L,0x568d193416f60126L,\n        0x05ae9668f354af33L } },\n    /* 59 << 91 */\n    { { 0x19de6d37c92544f2L,0xcc084353a35837d5L,0xcbb6869c1a514eceL,\n        0xb633e7282e1d1066L },\n      { 0xf15dd69f936c581cL,0x96e7b8ce7439c4f9L,0x5e676f482e448a5bL,\n        0xb2ca7d5bfd916bbbL } },\n    /* 60 << 91 */\n    { { 0xd55a2541f5024025L,0x47bc5769e4c2d937L,0x7d31b92a0362189fL,\n        0x83f3086eef7816f9L },\n      { 0xf9f46d94b587579aL,0xec2d22d830e76c5fL,0x27d57461b000ffcfL,\n        0xbb7e65f9364ffc2cL } },\n    /* 61 << 91 */\n    { { 0x7c7c94776652a220L,0x61618f89d696c981L,0x5021701d89effff3L,\n        0xf2c8ff8e7c314163L },\n      { 0x2da413ad8efb4d3eL,0x937b5adfce176d95L,0x22867d342a67d51cL,\n        0x262b9b1018eb3ac9L } },\n    /* 62 << 91 */\n    { { 0x4e314fe4c43ff28bL,0x764766276a664e7aL,0x3e90e40bb7a565c2L,\n        0x8588993ac1acf831L },\n      { 0xd7b501d68f938829L,0x996627ee3edd7d4cL,0x37d44a6290cd34c7L,\n        0xa8327499f3833e8dL } },\n    /* 63 << 91 */\n    { { 0x2e18917d4bf50353L,0x85dd726b556765fbL,0x54fe65d693d5ab66L,\n        0x3ddbaced915c25feL },\n      { 0xa799d9a412f22e85L,0xe2a248676d06f6bcL,0xf4f1ee5643ca1637L,\n        0xfda2828b61ece30aL } },\n    /* 64 << 91 */\n    { { 0x758c1a3ea2dee7a6L,0xdcde2f3c734b2284L,0xaba445d24eaba6adL,\n        0x35aaf66876cee0a7L },\n      { 0x7e0b04a9e5aa049aL,0xe74083ad91103e84L,0xbeb183ce40afecc3L,\n        0x6b89de9fea043f7aL } },\n    /* 0 << 98 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 98 */\n    { { 0x0e299d23fe67ba66L,0x9145076093cf2f34L,0xf45b5ea997fcf913L,\n        0x5be008438bd7dddaL },\n      { 0x358c3e05d53ff04dL,0xbf7ccdc35de91ef7L,0xad684dbfb69ec1a0L,\n        0x367e7cf2801fd997L } },\n    /* 2 << 98 */\n    { { 0x0ca1f3b7b0dc8595L,0x27de46089f1d9f2eL,0x1af3bf39badd82a7L,\n        0x79356a7965862448L },\n      { 0xc0602345f5f9a052L,0x1a8b0f89139a42f9L,0xb53eee42844d40fcL,\n        0x93b0bfe54e5b6368L } },\n    /* 3 << 98 */\n    { { 0x5434dd02c024789cL,0x90dca9ea41b57bfcL,0x8aa898e2243398dfL,\n        0xf607c834894a94bbL },\n      { 0xbb07be97c2c99b76L,0x6576ba6718c29302L,0x3d79efcce703a88cL,\n        0xf259ced7b6a0d106L } },\n    /* 4 << 98 */\n    { { 0x0f893a5dc8de610bL,0xe8c515fb67e223ceL,0x7774bfa64ead6dc5L,\n        0x89d20f95925c728fL },\n      { 0x7a1e0966098583ceL,0xa2eedb9493f2a7d7L,0x1b2820974c304d4aL,\n        0x0842e3dac077282dL } },\n    /* 5 << 98 */\n    { { 0xe4d972a33b9e2d7bL,0x7cc60b27c48218ffL,0x8fc7083884149d91L,\n        0x5c04346f2f461eccL },\n      { 0xebe9fdf2614650a9L,0x5e35b537c1f666acL,0x645613d188babc83L,\n        0x88cace3ac5e1c93eL } },\n    /* 6 << 98 */\n    { { 0x209ca3753de92e23L,0xccb03cc85fbbb6e3L,0xccb90f03d7b1487eL,\n        0xfa9c2a38c710941fL },\n      { 0x756c38236724ceedL,0x3a902258192d0323L,0xb150e519ea5e038eL,\n        0xdcba2865c7427591L } },\n    /* 7 << 98 */\n    { { 0xe549237f78890732L,0xc443bef953fcb4d9L,0x9884d8a6eb3480d6L,\n        0x8a35b6a13048b186L },\n      { 0xb4e4471665e9a90aL,0x45bf380d653006c0L,0x8f3f820d4fe9ae3bL,\n        0x244a35a0979a3b71L } },\n    /* 8 << 98 */\n    { { 0xa1010e9d74cd06ffL,0x9c17c7dfaca3eeacL,0x74c86cd38063aa2bL,\n        0x8595c4b3734614ffL },\n      { 0xa3de00ca990f62ccL,0xd9bed213ca0c3be5L,0x7886078adf8ce9f5L,\n        0xddb27ce35cd44444L } },\n    /* 9 << 98 */\n    { { 0xed374a6658926dddL,0x138b2d49908015b8L,0x886c6579de1f7ab8L,\n        0x888b9aa0c3020b7aL },\n      { 0xd3ec034e3a96e355L,0xba65b0b8f30fbe9aL,0x064c8e50ff21367aL,\n        0x1f508ea40b04b46eL } },\n    /* 10 << 98 */\n    { { 0x98561a49747c866cL,0xbbb1e5fe0518a062L,0x20ff4e8becdc3608L,\n        0x7f55cded20184027L },\n      { 0x8d73ec95f38c85f0L,0x5b589fdf8bc3b8c3L,0xbe95dd980f12b66fL,\n        0xf5bd1a090e338e01L } },\n    /* 11 << 98 */\n    { { 0x65163ae55e915918L,0x6158d6d986f8a46bL,0x8466b538eeebf99cL,\n        0xca8761f6bca477efL },\n      { 0xaf3449c29ebbc601L,0xef3b0f41e0c3ae2fL,0xaa6c577d5de63752L,\n        0xe916660164682a51L } },\n    /* 12 << 98 */\n    { { 0x5a3097befc15aa1eL,0x40d12548b54b0745L,0x5bad4706519a5f12L,\n        0xed03f717a439dee6L },\n      { 0x0794bb6c4a02c499L,0xf725083dcffe71d2L,0x2cad75190f3adcafL,\n        0x7f68ea1c43729310L } },\n    /* 13 << 98 */\n    { { 0xe747c8c7b7ffd977L,0xec104c3580761a22L,0x8395ebaf5a3ffb83L,\n        0xfb3261f4e4b63db7L },\n      { 0x53544960d883e544L,0x13520d708cc2eeb8L,0x08f6337bd3d65f99L,\n        0x83997db2781cf95bL } },\n    /* 14 << 98 */\n    { { 0xce6ff1060dbd2c01L,0x4f8eea6b1f9ce934L,0x546f7c4b0e993921L,\n        0x6236a3245e753fc7L },\n      { 0x65a41f84a16022e9L,0x0c18d87843d1dbb2L,0x73c556402d4cef9cL,\n        0xa042810870444c74L } },\n    /* 15 << 98 */\n    { { 0x68e4f15e9afdfb3cL,0x49a561435bdfb6dfL,0xa9bc1bd45f823d97L,\n        0xbceb5970ea111c2aL },\n      { 0x366b455fb269bbc4L,0x7cd85e1ee9bc5d62L,0xc743c41c4f18b086L,\n        0xa4b4099095294fb9L } },\n    /* 16 << 98 */\n    { { 0x9c7c581d26ee8382L,0xcf17dcc5359d638eL,0xee8273abb728ae3dL,\n        0x1d112926f821f047L },\n      { 0x1149847750491a74L,0x687fa761fde0dfb9L,0x2c2580227ea435abL,\n        0x6b8bdb9491ce7e3fL } },\n    /* 17 << 98 */\n    { { 0x4c5b5dc93bf834aaL,0x043718194f6c7e4bL,0xc284e00a3736bcadL,\n        0x0d88111821ae8f8dL },\n      { 0xf9cf0f82f48c8e33L,0xa11fd075a1bf40dbL,0xdceab0dedc2733e5L,\n        0xc560a8b58e986bd7L } },\n    /* 18 << 98 */\n    { { 0x48dd1fe23929d097L,0x3885b29092f188f1L,0x0f2ae613da6fcdacL,\n        0x9054303eb662a46cL },\n      { 0xb6871e440738042aL,0x98e6a977bdaf6449L,0xd8bc0650d1c9df1bL,\n        0xef3d645136e098f9L } },\n    /* 19 << 98 */\n    { { 0x03fbae82b6d72d28L,0x77ca9db1f5d84080L,0x8a112cffa58efc1cL,\n        0x518d761cc564cb4aL },\n      { 0x69b5740ef0d1b5ceL,0x717039cce9eb1785L,0x3fe29f9022f53382L,\n        0x8e54ba566bc7c95cL } },\n    /* 20 << 98 */\n    { { 0x9c806d8af7f91d0fL,0x3b61b0f1a82a5728L,0x4640032d94d76754L,\n        0x273eb5de47d834c6L },\n      { 0x2988abf77b4e4d53L,0xb7ce66bfde401777L,0x9fba6b32715071b3L,\n        0x82413c24ad3a1a98L } },\n    /* 21 << 98 */\n    { { 0x5b7fc8c4e0e8ad93L,0xb5679aee5fab868dL,0xb1f9d2fa2b3946f3L,\n        0x458897dc5685b50aL },\n      { 0x1e98c93089d0caf3L,0x39564c5f78642e92L,0x1b77729a0dbdaf18L,\n        0xf9170722579e82e6L } },\n    /* 22 << 98 */\n    { { 0x680c0317e4515fa5L,0xf85cff84fb0c790fL,0xc7a82aab6d2e0765L,\n        0x7446bca935c82b32L },\n      { 0x5de607aa6d63184fL,0x7c1a46a8262803a6L,0xd218313daebe8035L,\n        0x92113ffdc73c51f8L } },\n    /* 23 << 98 */\n    { { 0x4b38e08312e7e46cL,0x69d0a37a56126bd5L,0xfb3f324b73c07e04L,\n        0xa0c22f678fda7267L },\n      { 0x8f2c00514d2c7d8fL,0xbc45ced3cbe2cae5L,0xe1c6cf07a8f0f277L,\n        0xbc3923121eb99a98L } },\n    /* 24 << 98 */\n    { { 0x75537b7e3cc8ac85L,0x8d725f57dd02753bL,0xfd05ff64b737df2fL,\n        0x55fe8712f6d2531dL },\n      { 0x57ce04a96ab6b01cL,0x69a02a897cd93724L,0x4f82ac35cf86699bL,\n        0x8242d3ad9cb4b232L } },\n    /* 25 << 98 */\n    { { 0x713d0f65d62105e5L,0xbb222bfa2d29be61L,0xf2f9a79e6cfbef09L,\n        0xfc24d8d3d5d6782fL },\n      { 0x5db77085d4129967L,0xdb81c3ccdc3c2a43L,0x9d655fc005d8d9a3L,\n        0x3f5d057a54298026L } },\n    /* 26 << 98 */\n    { { 0x1157f56d88c54694L,0xb26baba59b09573eL,0x2cab03b022adffd1L,\n        0x60a412c8dd69f383L },\n      { 0xed76e98b54b25039L,0xd4ee67d3687e714dL,0x877396487b00b594L,\n        0xce419775c9ef709bL } },\n    /* 27 << 98 */\n    { { 0x40f76f851c203a40L,0x30d352d6eafd8f91L,0xaf196d3d95578dd2L,\n        0xea4bb3d777cc3f3dL },\n      { 0x42a5bd03b98e782bL,0xac958c400624920dL,0xb838134cfc56fcc8L,\n        0x86ec4ccf89572e5eL } },\n    /* 28 << 98 */\n    { { 0x69c435269be47be0L,0x323b7dd8cb28fea1L,0xfa5538ba3a6c67e5L,\n        0xef921d701d378e46L },\n      { 0xf92961fc3c4b880eL,0x3f6f914e98940a67L,0xa990eb0afef0ff39L,\n        0xa6c2920ff0eeff9cL } },\n    /* 29 << 98 */\n    { { 0xca80416651b8d9a3L,0x42531bc90ffb0db1L,0x72ce4718aa82e7ceL,\n        0x6e199913df574741L },\n      { 0xd5f1b13dd5d36946L,0x8255dc65f68f0194L,0xdc9df4cd8710d230L,\n        0x3453c20f138c1988L } },\n    /* 30 << 98 */\n    { { 0x9af98dc089a6ef01L,0x4dbcc3f09857df85L,0x348056015c1ad924L,\n        0x40448da5d0493046L },\n      { 0xf629926d4ee343e2L,0x6343f1bd90e8a301L,0xefc9349140815b3fL,\n        0xf882a423de8f66fbL } },\n    /* 31 << 98 */\n    { { 0x3a12d5f4e7db9f57L,0x7dfba38a3c384c27L,0x7a904bfd6fc660b1L,\n        0xeb6c5db32773b21cL },\n      { 0xc350ee661cdfe049L,0x9baac0ce44540f29L,0xbc57b6aba5ec6aadL,\n        0x167ce8c30a7c1baaL } },\n    /* 32 << 98 */\n    { { 0xb23a03a553fb2b56L,0x6ce141e74e057f78L,0x796525c389e490d9L,\n        0x0bc95725a31a7e75L },\n      { 0x1ec567911220fd06L,0x716e3a3c408b0bd6L,0x31cd6bf7e8ebeba9L,\n        0xa7326ca6bee6b670L } },\n    /* 33 << 98 */\n    { { 0x3d9f851ccd090c43L,0x561e8f13f12c3988L,0x50490b6a904b7be4L,\n        0x61690ce10410737bL },\n      { 0x299e9a370f009052L,0x258758f0f026092eL,0x9fa255f3fdfcdc0fL,\n        0xdbc9fb1fc0e1bcd2L } },\n    /* 34 << 98 */\n    { { 0x35f9dd6e24651840L,0xdca45a84a5c59abcL,0x103d396fecca4938L,\n        0x4532da0ab97b3f29L },\n      { 0xc4135ea51999a6bfL,0x3aa9505a5e6bf2eeL,0xf77cef063f5be093L,\n        0x97d1a0f8a943152eL } },\n    /* 35 << 98 */\n    { { 0x2cb0ebba2e1c21ddL,0xf41b29fc2c6797c4L,0xc6e17321b300101fL,\n        0x4422b0e9d0d79a89L },\n      { 0x49e4901c92f1bfc4L,0x06ab1f8fe1e10ed9L,0x84d35577db2926b8L,\n        0xca349d39356e8ec2L } },\n    /* 36 << 98 */\n    { { 0x70b63d32343bf1a9L,0x8fd3bd2837d1a6b1L,0x0454879c316865b4L,\n        0xee959ff6c458efa2L },\n      { 0x0461dcf89706dc3fL,0x737db0e2164e4b2eL,0x092626802f8843c8L,\n        0x54498bbc7745e6f6L } },\n    /* 37 << 98 */\n    { { 0x359473faa29e24afL,0xfcc3c45470aa87a1L,0xfd2c4bf500573aceL,\n        0xb65b514e28dd1965L },\n      { 0xe46ae7cf2193e393L,0x60e9a4e1f5444d97L,0xe7594e9600ff38edL,\n        0x43d84d2f0a0e0f02L } },\n    /* 38 << 98 */\n    { { 0x8b6db141ee398a21L,0xb88a56aee3bcc5beL,0x0a1aa52f373460eaL,\n        0x20da1a56160bb19bL },\n      { 0xfb54999d65bf0384L,0x71a14d245d5a180eL,0xbc44db7b21737b04L,\n        0xd84fcb1801dd8e92L } },\n    /* 39 << 98 */\n    { { 0x80de937bfa44b479L,0x535054995c98fd4fL,0x1edb12ab28f08727L,\n        0x4c58b582a5f3ef53L },\n      { 0xbfb236d88327f246L,0xc3a3bfaa4d7df320L,0xecd96c59b96024f2L,\n        0xfc293a537f4e0433L } },\n    /* 40 << 98 */\n    { { 0x5341352b5acf6e10L,0xc50343fdafe652c3L,0x4af3792d18577a7fL,\n        0xe1a4c617af16823dL },\n      { 0x9b26d0cd33425d0aL,0x306399ed9b7bc47fL,0x2a792f33706bb20bL,\n        0x3121961498111055L } },\n    /* 41 << 98 */\n    { { 0x864ec06487f5d28bL,0x11392d91962277fdL,0xb5aa7942bb6aed5fL,\n        0x080094dc47e799d9L },\n      { 0x4afa588c208ba19bL,0xd3e7570f8512f284L,0xcbae64e602f5799aL,\n        0xdeebe7ef514b9492L } },\n    /* 42 << 98 */\n    { { 0x30300f98e5c298ffL,0x17f561be3678361fL,0xf52ff31298cb9a16L,\n        0x6233c3bc5562d490L },\n      { 0x7bfa15a192e3a2cbL,0x961bcfd1e6365119L,0x3bdd29bf2c8c53b1L,\n        0x739704df822844baL } },\n    /* 43 << 98 */\n    { { 0x7dacfb587e7b754bL,0x23360791a806c9b9L,0xe7eb88c923504452L,\n        0x2983e996852c1783L },\n      { 0xdd4ae529958d881dL,0x026bae03262c7b3cL,0x3a6f9193960b52d1L,\n        0xd0980f9092696cfbL } },\n    /* 44 << 98 */\n    { { 0x4c1f428cd5f30851L,0x94dfed272a4f6630L,0x4df53772fc5d48a4L,\n        0xdd2d5a2f933260ceL },\n      { 0x574115bdd44cc7a5L,0x4ba6b20dbd12533aL,0x30e93cb8243057c9L,\n        0x794c486a14de320eL } },\n    /* 45 << 98 */\n    { { 0xe925d4cef21496e4L,0xf951d198ec696331L,0x9810e2de3e8d812fL,\n        0xd0a47259389294abL },\n      { 0x513ba2b50e3bab66L,0x462caff5abad306fL,0xe2dc6d59af04c49eL,\n        0x1aeb8750e0b84b0bL } },\n    /* 46 << 98 */\n    { { 0xc034f12f2f7d0ca2L,0x6d2e8128e06acf2fL,0x801f4f8321facc2fL,\n        0xa1170c03f40ef607L },\n      { 0xfe0a1d4f7805a99cL,0xbde56a36cc26aba5L,0x5b1629d035531f40L,\n        0xac212c2b9afa6108L } },\n    /* 47 << 98 */\n    { { 0x30a06bf315697be5L,0x6f0545dc2c63c7c1L,0x5d8cb8427ccdadafL,\n        0xd52e379bac7015bbL },\n      { 0xc4f56147f462c23eL,0xd44a429846bc24b0L,0xbc73d23ae2856d4fL,\n        0x61cedd8c0832bcdfL } },\n    /* 48 << 98 */\n    { { 0x6095355699f241d7L,0xee4adbd7001a349dL,0x0b35bf6aaa89e491L,\n        0x7f0076f4136f7546L },\n      { 0xd19a18ba9264da3dL,0x6eb2d2cd62a7a28bL,0xcdba941f8761c971L,\n        0x1550518ba3be4a5dL } },\n    /* 49 << 98 */\n    { { 0xd0e8e2f057d0b70cL,0xeea8612ecd133ba3L,0x814670f044416aecL,\n        0x424db6c330775061L },\n      { 0xd96039d116213fd1L,0xc61e7fa518a3478fL,0xa805bdcccb0c5021L,\n        0xbdd6f3a80cc616ddL } },\n    /* 50 << 98 */\n    { { 0x060096675d97f7e2L,0x31db0fc1af0bf4b6L,0x23680ed45491627aL,\n        0xb99a3c667d741fb1L },\n      { 0xe9bb5f5536b1ff92L,0x29738577512b388dL,0xdb8a2ce750fcf263L,\n        0x385346d46c4f7b47L } },\n    /* 51 << 98 */\n    { { 0xbe86c5ef31631f9eL,0xbf91da2103a57a29L,0xc3b1f7967b23f821L,\n        0x0f7d00d2770db354L },\n      { 0x8ffc6c3bd8fe79daL,0xcc5e8c40d525c996L,0x4640991dcfff632aL,\n        0x64d97e8c67112528L } },\n    /* 52 << 98 */\n    { { 0xc232d97302f1cd1eL,0xce87eacb1dd212a4L,0x6e4c8c73e69802f7L,\n        0x12ef02901fffddbdL },\n      { 0x941ec74e1bcea6e2L,0xd0b540243cb92cbbL,0x809fb9d47e8f9d05L,\n        0x3bf16159f2992aaeL } },\n    /* 53 << 98 */\n    { { 0xad40f279f8a7a838L,0x11aea63105615660L,0xbf52e6f1a01f6fa1L,\n        0xef0469953dc2aec9L },\n      { 0x785dbec9d8080711L,0xe1aec60a9fdedf76L,0xece797b5fa21c126L,\n        0xc66e898f05e52732L } },\n    /* 54 << 98 */\n    { { 0x39bb69c408811fdbL,0x8bfe1ef82fc7f082L,0xc8e7a393174f4138L,\n        0xfba8ad1dd58d1f98L },\n      { 0xbc21d0cebfd2fd5bL,0x0b839a826ee60d61L,0xaacf7658afd22253L,\n        0xb526bed8aae396b3L } },\n    /* 55 << 98 */\n    { { 0xccc1bbc238564464L,0x9e3ff9478c45bc73L,0xcde9bca358188a78L,\n        0x138b8ee0d73bf8f7L },\n      { 0x5c7e234c4123c489L,0x66e69368fa643297L,0x0629eeee39a15fa3L,\n        0x95fab881a9e2a927L } },\n    /* 56 << 98 */\n    { { 0xb2497007eafbb1e1L,0xd75c9ce6e75b7a93L,0x3558352defb68d78L,\n        0xa2f26699223f6396L },\n      { 0xeb911ecfe469b17aL,0x62545779e72d3ec2L,0x8ea47de782cb113fL,\n        0xebe4b0864e1fa98dL } },\n    /* 57 << 98 */\n    { { 0xec2d5ed78cdfedb1L,0xa535c077fe211a74L,0x9678109b11d244c5L,\n        0xf17c8bfbbe299a76L },\n      { 0xb651412efb11fbc4L,0xea0b548294ab3f65L,0xd8dffd950cf78243L,\n        0x2e719e57ce0361d4L } },\n    /* 58 << 98 */\n    { { 0x9007f085304ddc5bL,0x095e8c6d4daba2eaL,0x5a33cdb43f9d28a9L,\n        0x85b95cd8e2283003L },\n      { 0xbcd6c819b9744733L,0x29c5f538fc7f5783L,0x6c49b2fad59038e4L,\n        0x68349cc13bbe1018L } },\n    /* 59 << 98 */\n    { { 0xcc490c1d21830ee5L,0x36f9c4eee9bfa297L,0x58fd729448de1a94L,\n        0xaadb13a84e8f2cdcL },\n      { 0x515eaaa081313dbaL,0xc76bb468c2152dd8L,0x357f8d75a653dbf8L,\n        0xe4d8c4d1b14ac143L } },\n    /* 60 << 98 */\n    { { 0xbdb8e675b055cb40L,0x898f8e7b977b5167L,0xecc65651b82fb863L,\n        0x565448146d88f01fL },\n      { 0xb0928e95263a75a9L,0xcfb6836f1a22fcdaL,0x651d14db3f3bd37cL,\n        0x1d3837fbb6ad4664L } },\n    /* 61 << 98 */\n    { { 0x7c5fb538ff4f94abL,0x7243c7126d7fb8f2L,0xef13d60ca85c5287L,\n        0x18cfb7c74bb8dd1bL },\n      { 0x82f9bfe672908219L,0x35c4592b9d5144abL,0x52734f379cf4b42fL,\n        0x6bac55e78c60ddc4L } },\n    /* 62 << 98 */\n    { { 0xb5cd811e94dea0f6L,0x259ecae4e18cc1a3L,0x6a0e836e15e660f8L,\n        0x6c639ea60e02bff2L },\n      { 0x8721b8cb7e1026fdL,0x9e73b50b63261942L,0xb8c7097477f01da3L,\n        0x1839e6a68268f57fL } },\n    /* 63 << 98 */\n    { { 0x571b94155150b805L,0x1892389ef92c7097L,0x8d69c18e4a084b95L,\n        0x7014c512be5b495cL },\n      { 0x4780db361b07523cL,0x2f6219ce2c1c64faL,0xc38b81b0602c105aL,\n        0xab4f4f205dc8e360L } },\n    /* 64 << 98 */\n    { { 0x20d3c982cf7d62d2L,0x1f36e29d23ba8150L,0x48ae0bf092763f9eL,\n        0x7a527e6b1d3a7007L },\n      { 0xb4a89097581a85e3L,0x1f1a520fdc158be5L,0xf98db37d167d726eL,\n        0x8802786e1113e862L } },\n    /* 0 << 105 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 105 */\n    { { 0xefb2149e36f09ab0L,0x03f163ca4a10bb5bL,0xd029704506e20998L,\n        0x56f0af001b5a3babL },\n      { 0x7af4cfec70880e0dL,0x7332a66fbe3d913fL,0x32e6c84a7eceb4bdL,\n        0xedc4a79a9c228f55L } },\n    /* 2 << 105 */\n    { { 0xc37c7dd0c55c4496L,0xa6a9635725bbabd2L,0x5b7e63f2add7f363L,\n        0x9dce37822e73f1dfL },\n      { 0xe1e5a16ab2b91f71L,0xe44898235ba0163cL,0xf2759c32f6e515adL,\n        0xa5e2f1f88615eecfL } },\n    /* 3 << 105 */\n    { { 0x74519be7abded551L,0x03d358b8c8b74410L,0x4d00b10b0e10d9a9L,\n        0x6392b0b128da52b7L },\n      { 0x6744a2980b75c904L,0xc305b0aea8f7f96cL,0x042e421d182cf932L,\n        0xf6fc5d509e4636caL } },\n    /* 4 << 105 */\n    { { 0x795847c9d64cc78cL,0x6c50621b9b6cb27bL,0x07099bf8df8022abL,\n        0x48f862ebc04eda1dL },\n      { 0xd12732ede1603c16L,0x19a80e0f5c9a9450L,0xe2257f54b429b4fcL,\n        0x66d3b2c645460515L } },\n    /* 5 << 105 */\n    { { 0x6ca4f87e822e37beL,0x73f237b4253bda4eL,0xf747f3a241190aebL,\n        0xf06fa36f804cf284L },\n      { 0x0a6bbb6efc621c12L,0x5d624b6440b80ec6L,0x4b0724257ba556f3L,\n        0x7fa0c3543e2d20a8L } },\n    /* 6 << 105 */\n    { { 0xe921fa31e3229d41L,0xa929c65294531bd4L,0x84156027a6d38209L,\n        0xf3d69f736bdb97bdL },\n      { 0x8906d19a16833631L,0x68a34c2e03d51be3L,0xcb59583b0e511cd8L,\n        0x99ce6bfdfdc132a8L } },\n    /* 7 << 105 */\n    { { 0x3facdaaaffcdb463L,0x658bbc1a34a38b08L,0x12a801f8f1a9078dL,\n        0x1567bcf96ab855deL },\n      { 0xe08498e03572359bL,0xcf0353e58659e68bL,0xbb86e9c87d23807cL,\n        0xbc08728d2198e8a2L } },\n    /* 8 << 105 */\n    { { 0x8de2b7bc453cadd6L,0x203900a7bc0bc1f8L,0xbcd86e47a6abd3afL,\n        0x911cac128502effbL },\n      { 0x2d550242ec965469L,0x0e9f769229e0017eL,0x633f078f65979885L,\n        0xfb87d4494cf751efL } },\n    /* 9 << 105 */\n    { { 0xe1790e4bfc25419aL,0x364672034bff3cfdL,0xc8db638625b6e83fL,\n        0x6cc69f236cad6fd2L },\n      { 0x0219e45a6bc68bb9L,0xe43d79b6297f7334L,0x7d445368465dc97cL,\n        0x4b9eea322a0b949aL } },\n    /* 10 << 105 */\n    { { 0x1b96c6ba6102d021L,0xeaafac782f4461eaL,0xd4b85c41c49f19a8L,\n        0x275c28e4cf538875L },\n      { 0x35451a9ddd2e54e0L,0x6991adb50605618bL,0x5b8b4bcd7b36cd24L,\n        0x372a4f8c56f37216L } },\n    /* 11 << 105 */\n    { { 0xc890bd73a6a5da60L,0x6f083da0dc4c9ff0L,0xf4e14d94f0536e57L,\n        0xf9ee1edaaaec8243L },\n      { 0x571241ec8bdcf8e7L,0xa5db82710b041e26L,0x9a0b9a99e3fff040L,\n        0xcaaf21dd7c271202L } },\n    /* 12 << 105 */\n    { { 0xb4e2b2e14f0dd2e8L,0xe77e7c4f0a377ac7L,0x69202c3f0d7a2198L,\n        0xf759b7ff28200eb8L },\n      { 0xc87526eddcfe314eL,0xeb84c52453d5cf99L,0xb1b52ace515138b6L,\n        0x5aa7ff8c23fca3f4L } },\n    /* 13 << 105 */\n    { { 0xff0b13c3b9791a26L,0x960022dacdd58b16L,0xdbd55c9257aad2deL,\n        0x3baaaaa3f30fe619L },\n      { 0x9a4b23460d881efdL,0x506416c046325e2aL,0x91381e76035c18d4L,\n        0xb3bb68bef27817b0L } },\n    /* 14 << 105 */\n    { { 0x15bfb8bf5116f937L,0x7c64a586c1268943L,0x71e25cc38419a2c8L,\n        0x9fd6b0c48335f463L },\n      { 0x4bf0ba3ce8ee0e0eL,0x6f6fba60298c21faL,0x57d57b39ae66bee0L,\n        0x292d513022672544L } },\n    /* 15 << 105 */\n    { { 0xf451105dbab093b3L,0x012f59b902839986L,0x8a9158023474a89cL,\n        0x048c919c2de03e97L },\n      { 0xc476a2b591071cd5L,0x791ed89a034970a5L,0x89bd9042e1b7994bL,\n        0x8eaf5179a1057ffdL } },\n    /* 16 << 105 */\n    { { 0x6066e2a2d551ee10L,0x87a8f1d8727e09a6L,0x00d08bab2c01148dL,\n        0x6da8e4f1424f33feL },\n      { 0x466d17f0cf9a4e71L,0xff5020103bf5cb19L,0xdccf97d8d062ecc0L,\n        0x80c0d9af81d80ac4L } },\n    /* 17 << 105 */\n    { { 0xe87771d8033f2876L,0xb0186ec67d5cc3dbL,0x58e8bb803bc9bc1dL,\n        0x4d1395cc6f6ef60eL },\n      { 0xa73c62d6186244a0L,0x918e5f23110a5b53L,0xed4878ca741b7eabL,\n        0x3038d71adbe03e51L } },\n    /* 18 << 105 */\n    { { 0x840204b7a93c3246L,0x21ab6069a0b9b4cdL,0xf5fa6e2bb1d64218L,\n        0x1de6ad0ef3d56191L },\n      { 0x570aaa88ff1929c7L,0xc6df4c6b640e87b5L,0xde8a74f2c65f0cccL,\n        0x8b972fd5e6f6cc01L } },\n    /* 19 << 105 */\n    { { 0x3fff36b60b846531L,0xba7e45e610a5e475L,0x84a1d10e4145b6c5L,\n        0xf1f7f91a5e046d9dL },\n      { 0x0317a69244de90d7L,0x951a1d4af199c15eL,0x91f78046c9d73debL,\n        0x74c82828fab8224fL } },\n    /* 20 << 105 */\n    { { 0xaa6778fce7560b90L,0xb4073e61a7e824ceL,0xff0d693cd642eba8L,\n        0x7ce2e57a5dccef38L },\n      { 0x89c2c7891df1ad46L,0x83a06922098346fdL,0x2d715d72da2fc177L,\n        0x7b6dd71d85b6cf1dL } },\n    /* 21 << 105 */\n    { { 0xc60a6d0a73fa9cb0L,0xedd3992e328bf5a9L,0xc380ddd0832c8c82L,\n        0xd182d410a2a0bf50L },\n      { 0x7d9d7438d9a528dbL,0xe8b1a0e9caf53994L,0xddd6e5fe0e19987cL,\n        0xacb8df03190b059dL } },\n    /* 22 << 105 */\n    { { 0x53703a328300129fL,0x1f63766268c43bfdL,0xbcbd191300e54051L,\n        0x812fcc627bf5a8c5L },\n      { 0x3f969d5f29fb85daL,0x72f4e00a694759e8L,0x426b6e52790726b7L,\n        0x617bbc873bdbb209L } },\n    /* 23 << 105 */\n    { { 0x511f8bb997aee317L,0x812a4096e81536a8L,0x137dfe593ac09b9bL,\n        0x0682238fba8c9a7aL },\n      { 0x7072ead6aeccb4bdL,0x6a34e9aa692ba633L,0xc82eaec26fff9d33L,\n        0xfb7535121d4d2b62L } },\n    /* 24 << 105 */\n    { { 0x1a0445ff1d7aadabL,0x65d38260d5f6a67cL,0x6e62fb0891cfb26fL,\n        0xef1e0fa55c7d91d6L },\n      { 0x47e7c7ba33db72cdL,0x017cbc09fa7c74b2L,0x3c931590f50a503cL,\n        0xcac54f60616baa42L } },\n    /* 25 << 105 */\n    { { 0x9b6cd380b2369f0fL,0x97d3a70d23c76151L,0x5f9dd6fc9862a9c6L,\n        0x044c4ab212312f51L },\n      { 0x035ea0fd834a2ddcL,0x49e6b862cc7b826dL,0xb03d688362fce490L,\n        0x62f2497ab37e36e9L } },\n    /* 26 << 105 */\n    { { 0x04b005b6c6458293L,0x36bb5276e8d10af7L,0xacf2dc138ee617b8L,\n        0x470d2d35b004b3d4L },\n      { 0x06790832feeb1b77L,0x2bb75c3985657f9cL,0xd70bd4edc0f60004L,\n        0xfe797ecc219b018bL } },\n    /* 27 << 105 */\n    { { 0x9b5bec2a753aebccL,0xdaf9f3dcc939eca5L,0xd6bc6833d095ad09L,\n        0x98abdd51daa4d2fcL },\n      { 0xd9840a318d168be5L,0xcf7c10e02325a23cL,0xa5c02aa07e6ecfafL,\n        0x2462e7e6b5bfdf18L } },\n    /* 28 << 105 */\n    { { 0xab2d8a8ba0cc3f12L,0x68dd485dbc672a29L,0x72039752596f2cd3L,\n        0x5d3eea67a0cf3d8dL },\n      { 0x810a1a81e6602671L,0x8f144a4014026c0cL,0xbc753a6d76b50f85L,\n        0xc4dc21e8645cd4a4L } },\n    /* 29 << 105 */\n    { { 0xc5262dea521d0378L,0x802b8e0e05011c6fL,0x1ba19cbb0b4c19eaL,\n        0x21db64b5ebf0aaecL },\n      { 0x1f394ee970342f9dL,0x93a10aee1bc44a14L,0xa7eed31b3efd0baaL,\n        0x6e7c824e1d154e65L } },\n    /* 30 << 105 */\n    { { 0xee23fa819966e7eeL,0x64ec4aa805b7920dL,0x2d44462d2d90aad4L,\n        0xf44dd195df277ad5L },\n      { 0x8d6471f1bb46b6a1L,0x1e65d313fd885090L,0x33a800f513a977b4L,\n        0xaca9d7210797e1efL } },\n    /* 31 << 105 */\n    { { 0x9a5a85a0fcff6a17L,0x9970a3f31eca7ceeL,0xbb9f0d6bc9504be3L,\n        0xe0c504beadd24ee2L },\n      { 0x7e09d95677fcc2f4L,0xef1a522765bb5fc4L,0x145d4fb18b9286aaL,\n        0x66fd0c5d6649028bL } },\n    /* 32 << 105 */\n    { { 0x98857ceb1bf4581cL,0xe635e186aca7b166L,0x278ddd22659722acL,\n        0xa0903c4c1db68007L },\n      { 0x366e458948f21402L,0x31b49c14b96abda2L,0x329c4b09e0403190L,\n        0x97197ca3d29f43feL } },\n    /* 33 << 105 */\n    { { 0x8073dd1e274983d8L,0xda1a3bde55717c8fL,0xfd3d4da20361f9d1L,\n        0x1332d0814c7de1ceL },\n      { 0x9b7ef7a3aa6d0e10L,0x17db2e73f54f1c4aL,0xaf3dffae4cd35567L,\n        0xaaa2f406e56f4e71L } },\n    /* 34 << 105 */\n    { { 0x8966759e7ace3fc7L,0x9594eacf45a8d8c6L,0x8de3bd8b91834e0eL,\n        0xafe4ca53548c0421L },\n      { 0xfdd7e856e6ee81c6L,0x8f671beb6b891a3aL,0xf7a58f2bfae63829L,\n        0x9ab186fb9c11ac9fL } },\n    /* 35 << 105 */\n    { { 0x8d6eb36910b5be76L,0x046b7739fb040bcdL,0xccb4529fcb73de88L,\n        0x1df0fefccf26be03L },\n      { 0xad7757a6bcfcd027L,0xa8786c75bb3165caL,0xe9db1e347e99a4d9L,\n        0x99ee86dfb06c504bL } },\n    /* 36 << 105 */\n    { { 0x5b7c2dddc15c9f0aL,0xdf87a7344295989eL,0x59ece47c03d08fdaL,\n        0xb074d3ddad5fc702L },\n      { 0x2040790351a03776L,0x2bb1f77b2a608007L,0x25c58f4fe1153185L,\n        0xe6df62f6766e6447L } },\n    /* 37 << 105 */\n    { { 0xefb3d1beed51275aL,0x5de47dc72f0f483fL,0x7932d98e97c2bedfL,\n        0xd5c119270219f8a1L },\n      { 0x9d751200a73a294eL,0x5f88434a9dc20172L,0xd28d9fd3a26f506aL,\n        0xa890cd319d1dcd48L } },\n    /* 38 << 105 */\n    { { 0x0aebaec170f4d3b4L,0xfd1a13690ffc8d00L,0xb9d9c24057d57838L,\n        0x45929d2668bac361L },\n      { 0x5a2cd06025b15ca6L,0x4b3c83e16e474446L,0x1aac7578ee1e5134L,\n        0xa418f5d6c91e2f41L } },\n    /* 39 << 105 */\n    { { 0x6936fc8a213ed68bL,0x860ae7ed510a5224L,0x63660335def09b53L,\n        0x641b2897cd79c98dL },\n      { 0x29bd38e101110f35L,0x79c26f42648b1937L,0x64dae5199d9164f4L,\n        0xd85a23100265c273L } },\n    /* 40 << 105 */\n    { { 0x7173dd5d4b07e2b1L,0xd144c4cb8d9ea221L,0xe8b04ea41105ab14L,\n        0x92dda542fe80d8f1L },\n      { 0xe9982fa8cf03dce6L,0x8b5ea9651a22cffcL,0xf7f4ea7f3fad88c4L,\n        0x62db773e6a5ba95cL } },\n    /* 41 << 105 */\n    { { 0xd20f02fb93f24567L,0xfd46c69a315257caL,0x0ac74cc78bcab987L,\n        0x46f31c015ceca2f5L },\n      { 0x40aedb59888b219eL,0xe50ecc37e1fccd02L,0x1bcd9dad911f816cL,\n        0x583cc1ec8db9b00cL } },\n    /* 42 << 105 */\n    { { 0xf3cd2e66a483bf11L,0xfa08a6f5b1b2c169L,0xf375e2454be9fa28L,\n        0x99a7ffec5b6d011fL },\n      { 0x6a3ebddbc4ae62daL,0x6cea00ae374aef5dL,0xab5fb98d9d4d05bcL,\n        0x7cba1423d560f252L } },\n    /* 43 << 105 */\n    { { 0x49b2cc21208490deL,0x1ca66ec3bcfb2879L,0x7f1166b71b6fb16fL,\n        0xfff63e0865fe5db3L },\n      { 0xb8345abe8b2610beL,0xb732ed8039de3df4L,0x0e24ed50211c32b4L,\n        0xd10d8a69848ff27dL } },\n    /* 44 << 105 */\n    { { 0xc1074398ed4de248L,0xd7cedace10488927L,0xa4aa6bf885673e13L,\n        0xb46bae916daf30afL },\n      { 0x07088472fcef7ad8L,0x61151608d4b35e97L,0xbcfe8f26dde29986L,\n        0xeb84c4c7d5a34c79L } },\n    /* 45 << 105 */\n    { { 0xc1eec55c164e1214L,0x891be86da147bb03L,0x9fab4d100ba96835L,\n        0xbf01e9b8a5c1ae9fL },\n      { 0x6b4de139b186ebc0L,0xd5c74c2685b91bcaL,0x5086a99cc2d93854L,\n        0xeed62a7ba7a9dfbcL } },\n    /* 46 << 105 */\n    { { 0x8778ed6f76b7618aL,0xbff750a503b66062L,0x4cb7be22b65186dbL,\n        0x369dfbf0cc3a6d13L },\n      { 0xc7dab26c7191a321L,0x9edac3f940ed718eL,0xbc142b36d0cfd183L,\n        0xc8af82f67c991693L } },\n    /* 47 << 105 */\n    { { 0xb3d1e4d897ce0b2aL,0xe6d7c87fc3a55cdfL,0x35846b9568b81afeL,\n        0x018d12afd3c239d8L },\n      { 0x2b2c620801206e15L,0xe0e42453a3b882c6L,0x854470a3a50162d5L,\n        0x081574787017a62aL } },\n    /* 48 << 105 */\n    { { 0x18bd3fb4820357c7L,0x992039ae6f1458adL,0x9a1df3c525b44aa1L,\n        0x2d780357ed3d5281L },\n      { 0x58cf7e4dc77ad4d4L,0xd49a7998f9df4fc4L,0x4465a8b51d71205eL,\n        0xa0ee0ea6649254aaL } },\n    /* 49 << 105 */\n    { { 0x4b5eeecfab7bd771L,0x6c87307335c262b9L,0xdc5bd6483c9d61e7L,\n        0x233d6d54321460d2L },\n      { 0xd20c5626fc195bccL,0x2544595804d78b63L,0xe03fcb3d17ec8ef3L,\n        0x54b690d146b8f781L } },\n    /* 50 << 105 */\n    { { 0x82fa2c8a21230646L,0xf51aabb9084f418cL,0xff4fbec11a30ba43L,\n        0x6a5acf73743c9df7L },\n      { 0x1da2b357d635b4d5L,0xc3de68ddecd5c1daL,0xa689080bd61af0ddL,\n        0xdea5938ad665bf99L } },\n    /* 51 << 105 */\n    { { 0x0231d71afe637294L,0x01968aa6a5a81cd8L,0x11252d50048e63b5L,\n        0xc446bc526ca007e9L },\n      { 0xef8c50a696d6134bL,0x9361fbf59e09a05cL,0xf17f85a6dca3291aL,\n        0xb178d548ff251a21L } },\n    /* 52 << 105 */\n    { { 0x87f6374ba4df3915L,0x566ce1bf2fd5d608L,0x425cba4d7de35102L,\n        0x6b745f8f58c5d5e2L },\n      { 0x88402af663122edfL,0x3190f9ed3b989a89L,0x4ad3d387ebba3156L,\n        0xef385ad9c7c469a5L } },\n    /* 53 << 105 */\n    { { 0xb08281de3f642c29L,0x20be0888910ffb88L,0xf353dd4ad5292546L,\n        0x3f1627de8377a262L },\n      { 0xa5faa013eefcd638L,0x8f3bf62674cc77c3L,0x32618f65a348f55eL,\n        0x5787c0dc9fefeb9eL } },\n    /* 54 << 105 */\n    { { 0xf1673aa2d9a23e44L,0x88dfa9934e10690dL,0x1ced1b362bf91108L,\n        0x9193ceca3af48649L },\n      { 0xfb34327d2d738fc5L,0x6697b037975fee6cL,0x2f485da0c04079a5L,\n        0x2cdf57352feaa1acL } },\n    /* 55 << 105 */\n    { { 0x76944420bd55659eL,0x7973e32b4376090cL,0x86bb4fe1163b591aL,\n        0x10441aedc196f0caL },\n      { 0x3b431f4a045ad915L,0x6c11b437a4afacb1L,0x30b0c7db71fdbbd8L,\n        0xb642931feda65acdL } },\n    /* 56 << 105 */\n    { { 0x4baae6e89c92b235L,0xa73bbd0e6b3993a1L,0xd06d60ec693dd031L,\n        0x03cab91b7156881cL },\n      { 0xd615862f1db3574bL,0x485b018564bb061aL,0x27434988a0181e06L,\n        0x2cd61ad4c1c0c757L } },\n    /* 57 << 105 */\n    { { 0x3effed5a2ff9f403L,0x8dc98d8b62239029L,0x2206021e1f17b70dL,\n        0xafbec0cabf510015L },\n      { 0x9fed716480130dfaL,0x306dc2b58a02dcf5L,0x48f06620feb10fc0L,\n        0x78d1e1d55a57cf51L } },\n    /* 58 << 105 */\n    { { 0xadef8c5a192ef710L,0x88afbd4b3b7431f9L,0x7e1f740764250c9eL,\n        0x6e31318db58bec07L },\n      { 0xfd4fc4b824f89b4eL,0x65a5dd8848c36a2aL,0x4f1eccfff024baa7L,\n        0x22a21cf2cba94650L } },\n    /* 59 << 105 */\n    { { 0x95d29dee42a554f7L,0x828983a5002ec4baL,0x8112a1f78badb73dL,\n        0x79ea8897a27c1839L },\n      { 0x8969a5a7d065fd83L,0xf49af791b262a0bcL,0xfcdea8b6af2b5127L,\n        0x10e913e1564c2dbcL } },\n    /* 60 << 105 */\n    { { 0x51239d14bc21ef51L,0xe51c3ceb4ce57292L,0x795ff06847bbcc3bL,\n        0x86b46e1ebd7e11e6L },\n      { 0x0ea6ba2380041ef4L,0xd72fe5056262342eL,0x8abc6dfd31d294d4L,\n        0xbbe017a21278c2c9L } },\n    /* 61 << 105 */\n    { { 0xb1fcfa09b389328aL,0x322fbc62d01771b5L,0x04c0d06360b045bfL,\n        0xdb652edc10e52d01L },\n      { 0x50ef932c03ec6627L,0xde1b3b2dc1ee50e3L,0x5ab7bdc5dc37a90dL,\n        0xfea6721331e33a96L } },\n    /* 62 << 105 */\n    { { 0x6482b5cb4f2999aaL,0x38476cc6b8cbf0ddL,0x93ebfacb173405bbL,\n        0x15cdafe7e52369ecL },\n      { 0xd42d5ba4d935b7dbL,0x648b60041c99a4cdL,0x785101bda3b5545bL,\n        0x4bf2c38a9dd67fafL } },\n    /* 63 << 105 */\n    { { 0xb1aadc634442449cL,0xe0e9921a33ad4fb8L,0x5c552313aa686d82L,\n        0xdee635fa465d866cL },\n      { 0xbc3c224a18ee6e8aL,0xeed748a6ed42e02fL,0xe70f930ad474cd08L,\n        0x774ea6ecfff24adfL } },\n    /* 64 << 105 */\n    { { 0x03e2de1cf3480d4aL,0xf0d8edc7bc8acf1aL,0xf23e330368295a9cL,\n        0xfadd5f68c546a97dL },\n      { 0x895597ad96f8acb1L,0xbddd49d5671bdae2L,0x16fcd52821dd43f4L,\n        0xa5a454126619141aL } },\n    /* 0 << 112 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 112 */\n    { { 0x8ce9b6bfc360e25aL,0xe6425195075a1a78L,0x9dc756a8481732f4L,\n        0x83c0440f5432b57aL },\n      { 0xc670b3f1d720281fL,0x2205910ed135e051L,0xded14b0edb052be7L,\n        0x697b3d27c568ea39L } },\n    /* 2 << 112 */\n    { { 0x2e599b9afb3ff9edL,0x28c2e0ab17f6515cL,0x1cbee4fd474da449L,\n        0x071279a44f364452L },\n      { 0x97abff6601fbe855L,0x3ee394e85fda51c4L,0x190385f667597c0bL,\n        0x6e9fccc6a27ee34bL } },\n    /* 3 << 112 */\n    { { 0x0b89de9314092ebbL,0xf17256bd428e240cL,0xcf89a7f393d2f064L,\n        0x4f57841ee1ed3b14L },\n      { 0x4ee14405e708d855L,0x856aae7203f1c3d0L,0xc8e5424fbdd7eed5L,\n        0x3333e4ef73ab4270L } },\n    /* 4 << 112 */\n    { { 0x3bc77adedda492f8L,0xc11a3aea78297205L,0x5e89a3e734931b4cL,\n        0x17512e2e9f5694bbL },\n      { 0x5dc349f3177bf8b6L,0x232ea4ba08c7ff3eL,0x9c4f9d16f511145dL,\n        0xccf109a333b379c3L } },\n    /* 5 << 112 */\n    { { 0xe75e7a88a1f25897L,0x7ac6961fa1b5d4d8L,0xe3e1077308f3ed5cL,\n        0x208a54ec0a892dfbL },\n      { 0xbe826e1978660710L,0x0cf70a97237df2c8L,0x418a7340ed704da5L,\n        0xa3eeb9a908ca33fdL } },\n    /* 6 << 112 */\n    { { 0x49d96233169bca96L,0x04d286d42da6aafbL,0xc09606eca0c2fa94L,\n        0x8869d0d523ff0fb3L },\n      { 0xa99937e5d0150d65L,0xa92e2503240c14c9L,0x656bf945108e2d49L,\n        0x152a733aa2f59e2bL } },\n    /* 7 << 112 */\n    { { 0xb4323d588434a920L,0xc0af8e93622103c5L,0x667518ef938dbf9aL,\n        0xa184307383a9cdf2L },\n      { 0x350a94aa5447ab80L,0xe5e5a325c75a3d61L,0x74ba507f68411a9eL,\n        0x10581fc1594f70c5L } },\n    /* 8 << 112 */\n    { { 0x60e2857080eb24a9L,0x7bedfb4d488e0cfdL,0x721ebbd7c259cdb8L,\n        0x0b0da855bc6390a9L },\n      { 0x2b4d04dbde314c70L,0xcdbf1fbc6c32e846L,0x33833eabb162fc9eL,\n        0x9939b48bb0dd3ab7L } },\n    /* 9 << 112 */\n    { { 0x5aaa98a7cb0c9c8cL,0x75105f3081c4375cL,0xceee50575ef1c90fL,\n        0xb31e065fc23a17bfL },\n      { 0x5364d275d4b6d45aL,0xd363f3ad62ec8996L,0xb5d212394391c65bL,\n        0x84564765ebb41b47L } },\n    /* 10 << 112 */\n    { { 0x20d18ecc37107c78L,0xacff3b6b570c2a66L,0x22f975d99bd0d845L,\n        0xef0a0c46ba178fa0L },\n      { 0x1a41965176b6028eL,0xc49ec674248612d4L,0x5b6ac4f27338af55L,\n        0x06145e627bee5a36L } },\n    /* 11 << 112 */\n    { { 0x33e95d07e75746b5L,0x1c1e1f6dc40c78beL,0x967833ef222ff8e2L,\n        0x4bedcf6ab49180adL },\n      { 0x6b37e9c13d7a4c8aL,0x2748887c6ddfe760L,0xf7055123aa3a5bbcL,\n        0x954ff2257bbb8e74L } },\n    /* 12 << 112 */\n    { { 0xc42b8ab197c3dfb9L,0x55a549b0cf168154L,0xad6748e7c1b50692L,\n        0x2775780f6fc5cbcbL },\n      { 0x4eab80b8e1c9d7c8L,0x8c69dae13fdbcd56L,0x47e6b4fb9969eaceL,\n        0x002f1085a705cb5aL } },\n    /* 13 << 112 */\n    { { 0x4e23ca446d3fea55L,0xb4ae9c86f4810568L,0x47bfb91b2a62f27dL,\n        0x60deb4c9d9bac28cL },\n      { 0xa892d8947de6c34cL,0x4ee682594494587dL,0x914ee14e1a3f8a5bL,\n        0xbb113eaa28700385L } },\n    /* 14 << 112 */\n    { { 0x81ca03b92115b4c9L,0x7c163d388908cad1L,0xc912a118aa18179aL,\n        0xe09ed750886e3081L },\n      { 0xa676e3fa26f516caL,0x753cacf78e732f91L,0x51592aea833da8b4L,\n        0xc626f42f4cbea8aaL } },\n    /* 15 << 112 */\n    { { 0xef9dc899a7b56eafL,0x00c0e52c34ef7316L,0x5b1e4e24fe818a86L,\n        0x9d31e20dc538be47L },\n      { 0x22eb932d3ed68974L,0xe44bbc087c4e87c4L,0x4121086e0dde9aefL,\n        0x8e6b9cff134f4345L } },\n    /* 16 << 112 */\n    { { 0x96892c1f711b0eb9L,0xb905f2c8780ab954L,0xace26309a20792dbL,\n        0xec8ac9b30684e126L },\n      { 0x486ad8b6b40a2447L,0x60121fc19fe3fb24L,0x5626fccf1a8e3b3fL,\n        0x4e5686226ad1f394L } },\n    /* 17 << 112 */\n    { { 0xda7aae0d196aa5a1L,0xe0df8c771041b5fbL,0x451465d926b318b7L,\n        0xc29b6e557ab136e9L },\n      { 0x2c2ab48b71148463L,0xb5738de364454a76L,0x54ccf9a05a03abe4L,\n        0x377c02960427d58eL } },\n    /* 18 << 112 */\n    { { 0x73f5f0b92bb39c1fL,0x14373f2ce608d8c5L,0xdcbfd31400fbb805L,\n        0xdf18fb2083afdcfbL },\n      { 0x81a57f4242b3523fL,0xe958532d87f650fbL,0xaa8dc8b68b0a7d7cL,\n        0x1b75dfb7150166beL } },\n    /* 19 << 112 */\n    { { 0x90e4f7c92d7d1413L,0x67e2d6b59834f597L,0x4fd4f4f9a808c3e8L,\n        0xaf8237e0d5281ec1L },\n      { 0x25ab5fdc84687ceeL,0xc5ded6b1a5b26c09L,0x8e4a5aecc8ea7650L,\n        0x23b73e5c14cc417fL } },\n    /* 20 << 112 */\n    { { 0x2bfb43183037bf52L,0xb61e6db578c725d7L,0x8efd4060bbb3e5d7L,\n        0x2e014701dbac488eL },\n      { 0xac75cf9a360aa449L,0xb70cfd0579634d08L,0xa591536dfffb15efL,\n        0xb2c37582d07c106cL } },\n    /* 21 << 112 */\n    { { 0xb4293fdcf50225f9L,0xc52e175cb0e12b03L,0xf649c3bad0a8bf64L,\n        0x745a8fefeb8ae3c6L },\n      { 0x30d7e5a358321bc3L,0xb1732be70bc4df48L,0x1f217993e9ea5058L,\n        0xf7a71cde3e4fd745L } },\n    /* 22 << 112 */\n    { { 0x86cc533e894c5bbbL,0x6915c7d969d83082L,0xa6aa2d055815c244L,\n        0xaeeee59249b22ce5L },\n      { 0x89e39d1378135486L,0x3a275c1f16b76f2fL,0xdb6bcc1be036e8f5L,\n        0x4df69b215e4709f5L } },\n    /* 23 << 112 */\n    { { 0xa188b2502d0f39aaL,0x622118bb15a85947L,0x2ebf520ffde0f4faL,\n        0xa40e9f294860e539L },\n      { 0x7b6a51eb22b57f0fL,0x849a33b97e80644aL,0x50e5d16f1cf095feL,\n        0xd754b54eec55f002L } },\n    /* 24 << 112 */\n    { { 0x5cfbbb22236f4a98L,0x0b0c59e9066800bbL,0x4ac69a8f5a9a7774L,\n        0x2b33f804d6bec948L },\n      { 0xb372929532e6c466L,0x68956d0f4e599c73L,0xa47a249f155c31ccL,\n        0x24d80f0de1ce284eL } },\n    /* 25 << 112 */\n    { { 0xcd821dfb988baf01L,0xe6331a7ddbb16647L,0x1eb8ad33094cb960L,\n        0x593cca38c91bbca5L },\n      { 0x384aac8d26567456L,0x40fa0309c04b6490L,0x97834cd6dab6c8f6L,\n        0x68a7318d3f91e55fL } },\n    /* 26 << 112 */\n    { { 0xa00fd04efc4d3157L,0xb56f8ab22bf3bdeaL,0x014f56484fa57172L,\n        0x948c5860450abdb3L },\n      { 0x342b5df00ebd4f08L,0x3e5168cd0e82938eL,0x7aedc1ceb0df5dd0L,\n        0x6bbbc6d9e5732516L } },\n    /* 27 << 112 */\n    { { 0xc7bfd486605daaa6L,0x46fd72b7bb9a6c9eL,0xe4847fb1a124fb89L,\n        0x75959cbda2d8ffbcL },\n      { 0x42579f65c8a588eeL,0x368c92e6b80b499dL,0xea4ef6cd999a5df1L,\n        0xaa73bb7f936fe604L } },\n    /* 28 << 112 */\n    { { 0xf347a70d6457d188L,0x86eda86b8b7a388bL,0xb7cdff060ccd6013L,\n        0xbeb1b6c7d0053fb2L },\n      { 0x0b02238799240a9fL,0x1bbb384f776189b2L,0x8695e71e9066193aL,\n        0x2eb5009706ffac7eL } },\n    /* 29 << 112 */\n    { { 0x0654a9c04a7d2caaL,0x6f3fb3d1a5aaa290L,0x835db041ff476e8fL,\n        0x540b8b0bc42295e4L },\n      { 0xa5c73ac905e214f5L,0x9a74075a56a0b638L,0x2e4b1090ce9e680bL,\n        0x57a5b4796b8d9afaL } },\n    /* 30 << 112 */\n    { { 0x0dca48e726bfe65cL,0x097e391c7290c307L,0x683c462e6669e72eL,\n        0xf505be1e062559acL },\n      { 0x5fbe3ea1e3a3035aL,0x6431ebf69cd50da8L,0xfd169d5c1f6407f2L,\n        0x8d838a9560fce6b8L } },\n    /* 31 << 112 */\n    { { 0x2a2bfa7f650006f0L,0xdfd7dad350c0fbb2L,0x92452495ccf9ad96L,\n        0x183bf494d95635f9L },\n      { 0x02d5df434a7bd989L,0x505385cca5431095L,0xdd98e67dfd43f53eL,\n        0xd61e1a6c500c34a9L } },\n    /* 32 << 112 */\n    { { 0x5a4b46c64a8a3d62L,0x8469c4d0247743d2L,0x2bb3a13d88f7e433L,\n        0x62b23a1001be5849L },\n      { 0xe83596b4a63d1a4cL,0x454e7fea7d183f3eL,0x643fce6117afb01cL,\n        0x4e65e5e61c4c3638L } },\n    /* 33 << 112 */\n    { { 0x41d85ea1ef74c45bL,0x2cfbfa66ae328506L,0x98b078f53ada7da9L,\n        0xd985fe37ec752fbbL },\n      { 0xeece68fe5a0148b4L,0x6f9a55c72d78136dL,0x232dccc4d2b729ceL,\n        0xa27e0dfd90aafbc4L } },\n    /* 34 << 112 */\n    { { 0x9647445212b4603eL,0xa876c5516b706d14L,0xdf145fcf69a9d412L,\n        0xe2ab75b72d479c34L },\n      { 0x12df9a761a23ff97L,0xc61389925d359d10L,0x6e51c7aefa835f22L,\n        0x69a79cb1c0fcc4d9L } },\n    /* 35 << 112 */\n    { { 0xf57f350d594cc7e1L,0x3079ca633350ab79L,0x226fb6149aff594aL,\n        0x35afec026d59a62bL },\n      { 0x9bee46f406ed2c6eL,0x58da17357d939a57L,0x44c504028fd1797eL,\n        0xd8853e7c5ccea6caL } },\n    /* 36 << 112 */\n    { { 0x4065508da35fcd5fL,0x8965df8c495ccaebL,0x0f2da85012e1a962L,\n        0xee471b94c1cf1cc4L },\n      { 0xcef19bc80a08fb75L,0x704958f581de3591L,0x2867f8b23aef4f88L,\n        0x8d749384ea9f9a5fL } },\n    /* 37 << 112 */\n    { { 0x1b3855378c9049f4L,0x5be948f37b92d8b6L,0xd96f725db6e2bd6bL,\n        0x37a222bc958c454dL },\n      { 0xe7c61abb8809bf61L,0x46f07fbc1346f18dL,0xfb567a7ae87c0d1cL,\n        0x84a461c87ef3d07aL } },\n    /* 38 << 112 */\n    { { 0x0a5adce6d9278d98L,0x24d948139dfc73e1L,0x4f3528b6054321c3L,\n        0x2e03fdde692ea706L },\n      { 0x10e6061947b533c0L,0x1a8bc73f2ca3c055L,0xae58d4b21bb62b8fL,\n        0xb2045a73584a24e3L } },\n    /* 39 << 112 */\n    { { 0x3ab3d5afbd76e195L,0x478dd1ad6938a810L,0x6ffab3936ee3d5cbL,\n        0xdfb693db22b361e4L },\n      { 0xf969449651dbf1a7L,0xcab4b4ef08a2e762L,0xe8c92f25d39bba9aL,\n        0x850e61bcf1464d96L } },\n    /* 40 << 112 */\n    { { 0xb7e830e3dc09508bL,0xfaf6d2cf74317655L,0x72606cebdf690355L,\n        0x48bb92b3d0c3ded6L },\n      { 0x65b754845c7cf892L,0xf6cd7ac9d5d5f01fL,0xc2c30a5996401d69L,\n        0x91268650ed921878L } },\n    /* 41 << 112 */\n    { { 0x380bf913b78c558fL,0x43c0baebc8afdaa9L,0x377f61d554f169d3L,\n        0xf8da07e3ae5ff20bL },\n      { 0xb676c49da8a90ea8L,0x81c1ff2b83a29b21L,0x383297ac2ad8d276L,\n        0x3001122fba89f982L } },\n    /* 42 << 112 */\n    { { 0xe1d794be6718e448L,0x246c14827c3e6e13L,0x56646ef85d26b5efL,\n        0x80f5091e88069cddL },\n      { 0xc5992e2f724bdd38L,0x02e915b48471e8c7L,0x96ff320a0d0ff2a9L,\n        0xbf8864874384d1a0L } },\n    /* 43 << 112 */\n    { { 0xbbe1e6a6c93f72d6L,0xd5f75d12cad800eaL,0xfa40a09fe7acf117L,\n        0x32c8cdd57581a355L },\n      { 0x742219927023c499L,0xa8afe5d738ec3901L,0x5691afcba90e83f0L,\n        0x41bcaa030b8f8eacL } },\n    /* 44 << 112 */\n    { { 0xe38b5ff98d2668d5L,0x0715281a7ad81965L,0x1bc8fc7c03c6ce11L,\n        0xcbbee6e28b650436L },\n      { 0x06b00fe80cdb9808L,0x17d6e066fe3ed315L,0x2e9d38c64d0b5018L,\n        0xab8bfd56844dcaefL } },\n    /* 45 << 112 */\n    { { 0x42894a59513aed8bL,0xf77f3b6d314bd07aL,0xbbdecb8f8e42b582L,\n        0xf10e2fa8d2390fe6L },\n      { 0xefb9502262a2f201L,0x4d59ea5050ee32b0L,0xd87f77286da789a8L,\n        0xcf98a2cff79492c4L } },\n    /* 46 << 112 */\n    { { 0xf9577239720943c2L,0xba044cf53990b9d0L,0x5aa8e82395f2884aL,\n        0x834de6ed0278a0afL },\n      { 0xc8e1ee9a5f25bd12L,0x9259ceaa6f7ab271L,0x7e6d97a277d00b76L,\n        0x5c0c6eeaa437832aL } },\n    /* 47 << 112 */\n    { { 0x5232c20f5606b81dL,0xabd7b3750d991ee5L,0x4d2bfe358632d951L,\n        0x78f8514698ed9364L },\n      { 0x951873f0f30c3282L,0x0da8ac80a789230bL,0x3ac7789c5398967fL,\n        0xa69b8f7fbdda0fb5L } },\n    /* 48 << 112 */\n    { { 0xe5db77176add8545L,0x1b71cb6672c49b66L,0xd856073968421d77L,\n        0x03840fe883e3afeaL },\n      { 0xb391dad51ec69977L,0xae243fb9307f6726L,0xc88ac87be8ca160cL,\n        0x5174cced4ce355f4L } },\n    /* 49 << 112 */\n    { { 0x98a35966e58ba37dL,0xfdcc8da27817335dL,0x5b75283083fbc7bfL,\n        0x68e419d4d9c96984L },\n      { 0x409a39f402a40380L,0x88940faf1fe977bcL,0xc640a94b8f8edea6L,\n        0x1e22cd17ed11547dL } },\n    /* 50 << 112 */\n    { { 0xe28568ce59ffc3e2L,0x60aa1b55c1dee4e7L,0xc67497c8837cb363L,\n        0x06fb438a105a2bf2L },\n      { 0x30357ec4500d8e20L,0x1ad9095d0670db10L,0x7f589a05c73b7cfdL,\n        0xf544607d880d6d28L } },\n    /* 51 << 112 */\n    { { 0x17ba93b1a20ef103L,0xad8591306ba6577bL,0x65c91cf66fa214a0L,\n        0xd7d49c6c27990da5L },\n      { 0xecd9ec8d20bb569dL,0xbd4b2502eeffbc33L,0x2056ca5a6bed0467L,\n        0x7916a1f75b63728cL } },\n    /* 52 << 112 */\n    { { 0xd4f9497d53a4f566L,0x8973466497b56810L,0xf8e1da740494a621L,\n        0x82546a938d011c68L },\n      { 0x1f3acb19c61ac162L,0x52f8fa9cabad0d3eL,0x15356523b4b7ea43L,\n        0x5a16ad61ae608125L } },\n    /* 53 << 112 */\n    { { 0xb0bcb87f4faed184L,0x5f236b1d5029f45fL,0xd42c76070bc6b1fcL,\n        0xc644324e68aefce3L },\n      { 0x8e191d595c5d8446L,0xc020807713ae1979L,0xadcaee553ba59cc7L,\n        0x20ed6d6ba2cb81baL } },\n    /* 54 << 112 */\n    { { 0x0952ba19b6efcffcL,0x60f12d6897c0b87cL,0x4ee2c7c49caa30bcL,\n        0x767238b797fbff4eL },\n      { 0xebc73921501b5d92L,0x3279e3dfc2a37737L,0x9fc12bc86d197543L,\n        0xfa94dc6f0a40db4eL } },\n    /* 55 << 112 */\n    { { 0x7392b41a530ccbbdL,0x87c82146ea823525L,0xa52f984c05d98d0cL,\n        0x2ae57d735ef6974cL },\n      { 0x9377f7bf3042a6ddL,0xb1a007c019647a64L,0xfaa9079a0cca9767L,\n        0x3d81a25bf68f72d5L } },\n    /* 56 << 112 */\n    { { 0x752067f8ff81578eL,0x786221509045447dL,0xc0c22fcf0505aa6fL,\n        0x1030f0a66bed1c77L },\n      { 0x31f29f151f0bd739L,0x2d7989c7e6debe85L,0x5c070e728e677e98L,\n        0x0a817bd306e81fd5L } },\n    /* 57 << 112 */\n    { { 0xc110d830b0f2ac95L,0x48d0995aab20e64eL,0x0f3e00e17729cd9aL,\n        0x2a570c20dd556946L },\n      { 0x912dbcfd4e86214dL,0x2d014ee2cf615498L,0x55e2b1e63530d76eL,\n        0xc5135ae4fd0fd6d1L } },\n    /* 58 << 112 */\n    { { 0x0066273ad4f3049fL,0xbb8e9893e7087477L,0x2dba1ddb14c6e5fdL,\n        0xdba3788651f57e6cL },\n      { 0x5aaee0a65a72f2cfL,0x1208bfbf7bea5642L,0xf5c6aa3b67872c37L,\n        0xd726e08343f93224L } },\n    /* 59 << 112 */\n    { { 0x1854daa5061f1658L,0xc0016df1df0cd2b3L,0xc2a3f23e833d50deL,\n        0x73b681d2bbbd3017L },\n      { 0x2f046dc43ac343c0L,0x9c847e7d85716421L,0xe1e13c910917eed4L,\n        0x3fc9eebd63a1b9c6L } },\n    /* 60 << 112 */\n    { { 0x0f816a727fe02299L,0x6335ccc2294f3319L,0x3820179f4745c5beL,\n        0xe647b782922f066eL },\n      { 0xc22e49de02cafb8aL,0x299bc2fffcc2ecccL,0x9a8feea26e0e8282L,\n        0xa627278bfe893205L } },\n    /* 61 << 112 */\n    { { 0xa7e197337933e47bL,0xf4ff6b132e766402L,0xa4d8be0a98440d9fL,\n        0x658f5c2f38938808L },\n      { 0x90b75677c95b3b3eL,0xfa0442693137b6ffL,0x077b039b43c47c29L,\n        0xcca95dd38a6445b2L } },\n    /* 62 << 112 */\n    { { 0x0b498ba42333fc4cL,0x274f8e68f736a1b1L,0x6ca348fd5f1d4b2eL,\n        0x24d3be78a8f10199L },\n      { 0x8535f858ca14f530L,0xa6e7f1635b982e51L,0x847c851236e1bf62L,\n        0xf6a7c58e03448418L } },\n    /* 63 << 112 */\n    { { 0x583f3703f9374ab6L,0x864f91956e564145L,0x33bc3f4822526d50L,\n        0x9f323c801262a496L },\n      { 0xaa97a7ae3f046a9aL,0x70da183edf8a039aL,0x5b68f71c52aa0ba6L,\n        0x9be0fe5121459c2dL } },\n    /* 64 << 112 */\n    { { 0xc1e17eb6cbc613e5L,0x33131d55497ea61cL,0x2f69d39eaf7eded5L,\n        0x73c2f434de6af11bL },\n      { 0x4ca52493a4a375faL,0x5f06787cb833c5c2L,0x814e091f3e6e71cfL,\n        0x76451f578b746666L } },\n    /* 0 << 119 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 119 */\n    { { 0x80f9bdef694db7e0L,0xedca8787b9fcddc6L,0x51981c3403b8dce1L,\n        0x4274dcf170e10ba1L },\n      { 0xf72743b86def6d1aL,0xd25b1670ebdb1866L,0xc4491e8c050c6f58L,\n        0x2be2b2ab87fbd7f5L } },\n    /* 2 << 119 */\n    { { 0x3e0e5c9dd111f8ecL,0xbcc33f8db7c4e760L,0x702f9a91bd392a51L,\n        0x7da4a795c132e92dL },\n      { 0x1a0b0ae30bb1151bL,0x54febac802e32251L,0xea3a5082694e9e78L,\n        0xe58ffec1e4fe40b8L } },\n    /* 3 << 119 */\n    { { 0xf85592fcd1e0cf9eL,0xdea75f0dc0e7b2e8L,0xc04215cfc135584eL,\n        0x174fc7272f57092aL },\n      { 0xe7277877eb930beaL,0x504caccb5eb02a5aL,0xf9fe08f7f5241b9bL,\n        0xe7fb62f48d5ca954L } },\n    /* 4 << 119 */\n    { { 0xfbb8349d29c4120bL,0x9f94391fc0d0d915L,0xc4074fa75410ba51L,\n        0xa66adbf6150a5911L },\n      { 0xc164543c34bfca38L,0xe0f27560b9e1ccfcL,0x99da0f53e820219cL,\n        0xe8234498c6b4997aL } },\n    /* 5 << 119 */\n    { { 0xcfb88b769d4c5423L,0x9e56eb10b0521c49L,0x418e0b5ebe8700a1L,\n        0x00cbaad6f93cb58aL },\n      { 0xe923fbded92a5e67L,0xca4979ac1f347f11L,0x89162d856bc0585bL,\n        0xdd6254afac3c70e3L } },\n    /* 6 << 119 */\n    { { 0x7b23c513516e19e4L,0x56e2e847c5c4d593L,0x9f727d735ce71ef6L,\n        0x5b6304a6f79a44c5L },\n      { 0x6638a7363ab7e433L,0x1adea470fe742f83L,0xe054b8545b7fc19fL,\n        0xf935381aba1d0698L } },\n    /* 7 << 119 */\n    { { 0x546eab2d799e9a74L,0x96239e0ea949f729L,0xca274c6b7090055aL,\n        0x835142c39020c9b0L },\n      { 0xa405667aa2e8807fL,0x29f2c0851aa3d39eL,0xcc555d6442fc72f5L,\n        0xe856e0e7fbeacb3cL } },\n    /* 8 << 119 */\n    { { 0xb5504f9d918e4936L,0x65035ef6b2513982L,0x0553a0c26f4d9cb9L,\n        0x6cb10d56bea85509L },\n      { 0x48d957b7a242da11L,0x16a4d3dd672b7268L,0x3d7e637c8502a96bL,\n        0x27c7032b730d463bL } },\n    /* 9 << 119 */\n    { { 0xbdc02b18e4136a14L,0xbacf969d678e32bfL,0xc98d89a3dd9c3c03L,\n        0x7b92420a23becc4fL },\n      { 0xd4b41f78c64d565cL,0x9f969d0010f28295L,0xec7f7f76b13d051aL,\n        0x08945e1ea92da585L } },\n    /* 10 << 119 */\n    { { 0x55366b7d5846426fL,0xe7d09e89247d441dL,0x510b404d736fbf48L,\n        0x7fa003d0e784bd7dL },\n      { 0x25f7614f17fd9596L,0x49e0e0a135cb98dbL,0x2c65957b2e83a76aL,\n        0x5d40da8dcddbe0f8L } },\n    /* 11 << 119 */\n    { { 0xf2b8c405050bad24L,0x8918426dc2aa4823L,0x2aeab3dda38365a7L,\n        0x720317177c91b690L },\n      { 0x8b00d69960a94120L,0x478a255de99eaeecL,0xbf656a5f6f60aafdL,\n        0xdfd7cb755dee77b3L } },\n    /* 12 << 119 */\n    { { 0x37f68bb4a595939dL,0x0355647928740217L,0x8e740e7c84ad7612L,\n        0xd89bc8439044695fL },\n      { 0xf7f3da5d85a9184dL,0x562563bb9fc0b074L,0x06d2e6aaf88a888eL,\n        0x612d8643161fbe7cL } },\n    /* 13 << 119 */\n    { { 0x465edba7f64085e7L,0xb230f30429aa8511L,0x53388426cda2d188L,\n        0x908857354b666649L },\n      { 0x6f02ff9a652f54f6L,0x65c822945fae2bf0L,0x7816ade062f5eee3L,\n        0xdcdbdf43fcc56d70L } },\n    /* 14 << 119 */\n    { { 0x9fb3bba354530bb2L,0xbde3ef77cb0869eaL,0x89bc90460b431163L,\n        0x4d03d7d2e4819a35L },\n      { 0x33ae4f9e43b6a782L,0x216db3079c88a686L,0x91dd88e000ffedd9L,\n        0xb280da9f12bd4840L } },\n    /* 15 << 119 */\n    { { 0x32a7cb8a1635e741L,0xfe14008a78be02a7L,0x3fafb3341b7ae030L,\n        0x7fd508e75add0ce9L },\n      { 0x72c83219d607ad51L,0x0f229c0a8d40964aL,0x1be2c3361c878da2L,\n        0xe0c96742eab2ab86L } },\n    /* 16 << 119 */\n    { { 0x458f86913e538cd7L,0xa7001f6c8e08ad53L,0x52b8c6e6bf5d15ffL,\n        0x548234a4011215ddL },\n      { 0xff5a9d2d3d5b4045L,0xb0ffeeb64a904190L,0x55a3aca448607f8bL,\n        0x8cbd665c30a0672aL } },\n    /* 17 << 119 */\n    { { 0x87f834e042583068L,0x02da2aebf3f6e683L,0x6b763e5d05c12248L,\n        0x7230378f65a8aefcL },\n      { 0x93bd80b571e8e5caL,0x53ab041cb3b62524L,0x1b8605136c9c552eL,\n        0xe84d402cd5524e66L } },\n    /* 18 << 119 */\n    { { 0xa37f3573f37f5937L,0xeb0f6c7dd1e4fca5L,0x2965a554ac8ab0fcL,\n        0x17fbf56c274676acL },\n      { 0x2e2f6bd9acf7d720L,0x41fc8f8810224766L,0x517a14b385d53befL,\n        0xdae327a57d76a7d1L } },\n    /* 19 << 119 */\n    { { 0x6ad0a065c4818267L,0x33aa189b37c1bbc1L,0x64970b5227392a92L,\n        0x21699a1c2d1535eaL },\n      { 0xcd20779cc2d7a7fdL,0xe318605999c83cf2L,0x9b69440b72c0b8c7L,\n        0xa81497d77b9e0e4dL } },\n    /* 20 << 119 */\n    { { 0x515d5c891f5f82dcL,0x9a7f67d76361079eL,0xa8da81e311a35330L,\n        0xe44990c44b18be1bL },\n      { 0xc7d5ed95af103e59L,0xece8aba78dac9261L,0xbe82b0999394b8d3L,\n        0x6830f09a16adfe83L } },\n    /* 21 << 119 */\n    { { 0x250a29b488172d01L,0x8b20bd65caff9e02L,0xb8a7661ee8a6329aL,\n        0x4520304dd3fce920L },\n      { 0xae45da1f2b47f7efL,0xe07f52885bffc540L,0xf79970093464f874L,\n        0x2244c2cda6fa1f38L } },\n    /* 22 << 119 */\n    { { 0x43c41ac194d7d9b1L,0x5bafdd82c82e7f17L,0xdf0614c15fda0fcaL,\n        0x74b043a7a8ae37adL },\n      { 0x3ba6afa19e71734cL,0x15d5437e9c450f2eL,0x4a5883fe67e242b1L,\n        0x5143bdc22c1953c2L } },\n    /* 23 << 119 */\n    { { 0x542b8b53fc5e8920L,0x363bf9a89a9cee08L,0x02375f10c3486e08L,\n        0x2037543b8c5e70d2L },\n      { 0x7109bccc625640b4L,0xcbc1051e8bc62c3bL,0xf8455fed803f26eaL,\n        0x6badceabeb372424L } },\n    /* 24 << 119 */\n    { { 0xa2a9ce7c6b53f5f9L,0x642465951b176d99L,0xb1298d36b95c081bL,\n        0x53505bb81d9a9ee6L },\n      { 0x3f6f9e61f2ba70b0L,0xd07e16c98afad453L,0x9f1694bbe7eb4a6aL,\n        0xdfebced93cb0bc8eL } },\n    /* 25 << 119 */\n    { { 0x92d3dcdc53868c8bL,0x174311a2386107a6L,0x4109e07c689b4e64L,\n        0x30e4587f2df3dcb6L },\n      { 0x841aea310811b3b2L,0x6144d41d0cce43eaL,0x464c45812a9a7803L,\n        0xd03d371f3e158930L } },\n    /* 26 << 119 */\n    { { 0xc676d7f2b1f3390bL,0x9f7a1b8ca5b61272L,0x4ebebfc9c2e127a9L,\n        0x4602500c5dd997bfL },\n      { 0x7f09771c4711230fL,0x058eb37c020f09c1L,0xab693d4bfee5e38bL,\n        0x9289eb1f4653cbc0L } },\n    /* 27 << 119 */\n    { { 0xbecf46abd51b9cf5L,0xd2aa9c029f0121afL,0x36aaf7d2e90dc274L,\n        0x909e4ea048b95a3cL },\n      { 0xe6b704966f32dbdbL,0x672188a08b030b3eL,0xeeffe5b3cfb617e2L,\n        0x87e947de7c82709eL } },\n    /* 28 << 119 */\n    { { 0xa44d2b391770f5a7L,0xe4d4d7910e44eb82L,0x42e69d1e3f69712aL,\n        0xbf11c4d6ac6a820eL },\n      { 0xb5e7f3e542c4224cL,0xd6b4e81c449d941cL,0x5d72bd165450e878L,\n        0x6a61e28aee25ac54L } },\n    /* 29 << 119 */\n    { { 0x33272094e6f1cd95L,0x7512f30d0d18673fL,0x32f7a4ca5afc1464L,\n        0x2f0956566bbb977bL },\n      { 0x586f47caa8226200L,0x02c868ad1ac07369L,0x4ef2b845c613acbeL,\n        0x43d7563e0386054cL } },\n    /* 30 << 119 */\n    { { 0x54da9dc7ab952578L,0xb5423df226e84d0bL,0xa8b64eeb9b872042L,\n        0xac2057825990f6dfL },\n      { 0x4ff696eb21f4c77aL,0x1a79c3e4aab273afL,0x29bc922e9436b3f1L,\n        0xff807ef8d6d9a27aL } },\n    /* 31 << 119 */\n    { { 0x82acea3d778f22a0L,0xfb10b2e85b5e7469L,0xc0b169802818ee7dL,\n        0x011afff4c91c1a2fL },\n      { 0x95a6d126ad124418L,0x31c081a5e72e295fL,0x36bb283af2f4db75L,\n        0xd115540f7acef462L } },\n    /* 32 << 119 */\n    { { 0xc7f3a8f833f6746cL,0x21e46f65fea990caL,0x915fd5c5caddb0a9L,\n        0xbd41f01678614555L },\n      { 0x346f4434426ffb58L,0x8055943614dbc204L,0xf3dd20fe5a969b7fL,\n        0x9d59e956e899a39aL } },\n    /* 33 << 119 */\n    { { 0xf1b0971c8ad4cf4bL,0x034488602ffb8fb8L,0xf071ac3c65340ba4L,\n        0x408d0596b27fd758L },\n      { 0xe7c78ea498c364b0L,0xa4aac4a5051e8ab5L,0xb9e1d560485d9002L,\n        0x9acd518a88844455L } },\n    /* 34 << 119 */\n    { { 0xe4ca688fd06f56c0L,0xa48af70ddf027972L,0x691f0f045e9a609dL,\n        0xa9dd82cdee61270eL },\n      { 0x8903ca63a0ef18d3L,0x9fb7ee353d6ca3bdL,0xa7b4a09cabf47d03L,\n        0x4cdada011c67de8eL } },\n    /* 35 << 119 */\n    { { 0x520037499355a244L,0xe77fd2b64f2151a9L,0x695d6cf666b4efcbL,\n        0xc5a0cacfda2cfe25L },\n      { 0x104efe5cef811865L,0xf52813e89ea5cc3dL,0x855683dc40b58dbcL,\n        0x0338ecde175fcb11L } },\n    /* 36 << 119 */\n    { { 0xf9a0563774921592L,0xb4f1261db9bb9d31L,0x551429b74e9c5459L,\n        0xbe182e6f6ea71f53L },\n      { 0xd3a3b07cdfc50573L,0x9ba1afda62be8d44L,0x9bcfd2cb52ab65d3L,\n        0xdf11d547a9571802L } },\n    /* 37 << 119 */\n    { { 0x099403ee02a2404aL,0x497406f421088a71L,0x994794095004ae71L,\n        0xbdb42078a812c362L },\n      { 0x2b72a30fd8828442L,0x283add27fcb5ed1cL,0xf7c0e20066a40015L,\n        0x3e3be64108b295efL } },\n    /* 38 << 119 */\n    { { 0xac127dc1e038a675L,0x729deff38c5c6320L,0xb7df8fd4a90d2c53L,\n        0x9b74b0ec681e7cd3L },\n      { 0x5cb5a623dab407e5L,0xcdbd361576b340c6L,0xa184415a7d28392cL,\n        0xc184c1d8e96f7830L } },\n    /* 39 << 119 */\n    { { 0xc3204f1981d3a80fL,0xfde0c841c8e02432L,0x78203b3e8149e0c1L,\n        0x5904bdbb08053a73L },\n      { 0x30fc1dd1101b6805L,0x43c223bc49aa6d49L,0x9ed671417a174087L,\n        0x311469a0d5997008L } },\n    /* 40 << 119 */\n    { { 0xb189b6845e43fc61L,0xf3282375e0d3ab57L,0x4fa34b67b1181da8L,\n        0x621ed0b299ee52b8L },\n      { 0x9b178de1ad990676L,0xd51de67b56d54065L,0x2a2c27c47538c201L,\n        0x33856ec838a40f5cL } },\n    /* 41 << 119 */\n    { { 0x2522fc15be6cdcdeL,0x1e603f339f0c6f89L,0x7994edc3103e30a6L,\n        0x033a00db220c853eL },\n      { 0xd3cfa409f7bb7fd7L,0x70f8781e462d18f6L,0xbbd82980687fe295L,\n        0x6eef4c32595669f3L } },\n    /* 42 << 119 */\n    { { 0x86a9303b2f7e85c3L,0x5fce462171988f9bL,0x5b935bf6c138acb5L,\n        0x30ea7d6725661212L },\n      { 0xef1eb5f4e51ab9a2L,0x0587c98aae067c78L,0xb3ce1b3c77ca9ca6L,\n        0x2a553d4d54b5f057L } },\n    /* 43 << 119 */\n    { { 0xc78982364da29ec2L,0xdbdd5d13b9c57316L,0xc57d6e6b2cd80d47L,\n        0x80b460cffe9e7391L },\n      { 0x98648cabf963c31eL,0x67f9f633cc4d32fdL,0x0af42a9dfdf7c687L,\n        0x55f292a30b015ea7L } },\n    /* 44 << 119 */\n    { { 0x89e468b2cd21ab3dL,0xe504f022c393d392L,0xab21e1d4a5013af9L,\n        0xe3283f78c2c28acbL },\n      { 0xf38b35f6226bf99fL,0xe83542740e291e69L,0x61673a15b20c162dL,\n        0xc101dc75b04fbdbeL } },\n    /* 45 << 119 */\n    { { 0x8323b4c2255bd617L,0x6c9696936c2a9154L,0xc6e6586062679387L,\n        0x8e01db0cb8c88e23L },\n      { 0x33c42873893a5559L,0x7630f04b47a3e149L,0xb5d80805ddcf35f8L,\n        0x582ca08077dfe732L } },\n    /* 46 << 119 */\n    { { 0x2c7156e10b1894a0L,0x92034001d81c68c0L,0xed225d00c8b115b5L,\n        0x237f9c2283b907f2L },\n      { 0x0ea2f32f4470e2c0L,0xb725f7c158be4e95L,0x0f1dcafab1ae5463L,\n        0x59ed51871ba2fc04L } },\n    /* 47 << 119 */\n    { { 0xf6e0f316d0115d4dL,0x5180b12fd3691599L,0x157e32c9527f0a41L,\n        0x7b0b081da8e0ecc0L },\n      { 0x6dbaaa8abf4f0dd0L,0x99b289c74d252696L,0x79b7755edbf864feL,\n        0x6974e2b176cad3abL } },\n    /* 48 << 119 */\n    { { 0x35dbbee206ddd657L,0xe7cbdd112ff3a96dL,0x88381968076be758L,\n        0x2d737e7208c91f5dL },\n      { 0x5f83ab6286ec3776L,0x98aa649d945fa7a1L,0xf477ec3772ef0933L,\n        0x66f52b1e098c17b1L } },\n    /* 49 << 119 */\n    { { 0x9eec58fbd803738bL,0x91aaade7e4e86aa4L,0x6b1ae617a5b51492L,\n        0x63272121bbc45974L },\n      { 0x7e0e28f0862c5129L,0x0a8f79a93321a4a0L,0xe26d16645041c88fL,\n        0x0571b80553233e3aL } },\n    /* 50 << 119 */\n    { { 0xd1b0ccdec9520711L,0x55a9e4ed3c8b84bfL,0x9426bd39a1fef314L,\n        0x4f5f638e6eb93f2bL },\n      { 0xba2a1ed32bf9341bL,0xd63c13214d42d5a9L,0xd2964a89316dc7c5L,\n        0xd1759606ca511851L } },\n    /* 51 << 119 */\n    { { 0xd8a9201ff9e6ed35L,0xb7b5ee456736925aL,0x0a83fbbc99581af7L,\n        0x3076bc4064eeb051L },\n      { 0x5511c98c02dec312L,0x270de898238dcb78L,0x2cf4cf9c539c08c9L,\n        0xa70cb65e38d3b06eL } },\n    /* 52 << 119 */\n    { { 0xb12ec10ecfe57bbdL,0x82c7b65635a0c2b5L,0xddc7d5cd161c67bdL,\n        0xe32e8985ae3a32ccL },\n      { 0x7aba9444d11a5529L,0xe964ed022427fa1aL,0x1528392d24a1770aL,\n        0xa152ce2c12c72fcdL } },\n    /* 53 << 119 */\n    { { 0x714553a48ec07649L,0x18b4c290459dd453L,0xea32b7147b64b110L,\n        0xb871bfa52e6f07a2L },\n      { 0xb67112e59e2e3c9bL,0xfbf250e544aa90f6L,0xf77aedb8bd539006L,\n        0x3b0cdf9ad172a66fL } },\n    /* 54 << 119 */\n    { { 0xedf69feaf8c51187L,0x05bb67ec741e4da7L,0x47df0f3208114345L,\n        0x56facb07bb9792b1L },\n      { 0xf3e007e98f6229e4L,0x62d103f4526fba0fL,0x4f33bef7b0339d79L,\n        0x9841357bb59bfec1L } },\n    /* 55 << 119 */\n    { { 0xfa8dbb59c34e6705L,0xc3c7180b7fdaa84cL,0xf95872fca4108537L,\n        0x8750cc3b932a3e5aL },\n      { 0xb61cc69db7275d7dL,0xffa0168b2e59b2e9L,0xca032abc6ecbb493L,\n        0x1d86dbd32c9082d8L } },\n    /* 56 << 119 */\n    { { 0xae1e0b67e28ef5baL,0x2c9a4699cb18e169L,0x0ecd0e331e6bbd20L,\n        0x571b360eaf5e81d2L },\n      { 0xcd9fea58101c1d45L,0x6651788e18880452L,0xa99726351f8dd446L,\n        0x44bed022e37281d0L } },\n    /* 57 << 119 */\n    { { 0x094b2b2d33da525dL,0xf193678e13144fd8L,0xb8ab5ba4f4c1061dL,\n        0x4343b5fadccbe0f4L },\n      { 0xa870237163812713L,0x47bf6d2df7611d93L,0x46729b8cbd21e1d7L,\n        0x7484d4e0d629e77dL } },\n    /* 58 << 119 */\n    { { 0x830e6eea60dbac1fL,0x23d8c484da06a2f7L,0x896714b050ca535bL,\n        0xdc8d3644ebd97a9bL },\n      { 0x106ef9fab12177b4L,0xf79bf464534d5d9cL,0x2537a349a6ab360bL,\n        0xc7c54253a00c744fL } },\n    /* 59 << 119 */\n    { { 0xb3c7a047e5911a76L,0x61ffa5c8647f1ee7L,0x15aed36f8f56ab42L,\n        0x6a0d41b0a3ff9ac9L },\n      { 0x68f469f5cc30d357L,0xbe9adf816b72be96L,0x1cd926fe903ad461L,\n        0x7e89e38fcaca441bL } },\n    /* 60 << 119 */\n    { { 0xf0f82de5facf69d4L,0x363b7e764775344cL,0x6894f312b2e36d04L,\n        0x3c6cb4fe11d1c9a5L },\n      { 0x85d9c3394008e1f2L,0x5e9a85ea249f326cL,0xdc35c60a678c5e06L,\n        0xc08b944f9f86fba9L } },\n    /* 61 << 119 */\n    { { 0xde40c02c89f71f0fL,0xad8f3e31ff3da3c0L,0x3ea5096b42125dedL,\n        0x13879cbfa7379183L },\n      { 0x6f4714a56b306a0bL,0x359c2ea667646c5eL,0xfacf894307726368L,\n        0x07a5893565ff431eL } },\n    /* 62 << 119 */\n    { { 0x24d661d168754ab0L,0x801fce1d6f429a76L,0xc068a85fa58ce769L,\n        0xedc35c545d5eca2bL },\n      { 0xea31276fa3f660d1L,0xa0184ebeb8fc7167L,0x0f20f21a1d8db0aeL,\n        0xd96d095f56c35e12L } },\n    /* 63 << 119 */\n    { { 0xedf402b5f8c2a25bL,0x1bb772b9059204b6L,0x50cbeae219b4e34cL,\n        0x93109d803fa0845aL },\n      { 0x54f7ccf78ef59fb5L,0x3b438fe288070963L,0x9e28c65931f3ba9bL,\n        0x9cc31b46ead9da92L } },\n    /* 64 << 119 */\n    { { 0x3c2f0ba9b733aa5fL,0xdece47cbf05af235L,0xf8e3f715a2ac82a5L,\n        0xc97ba6412203f18aL },\n      { 0xc3af550409c11060L,0x56ea2c0546af512dL,0xfac28daff3f28146L,\n        0x87fab43a959ef494L } },\n    /* 0 << 126 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 126 */\n    { { 0x09891641d4c5105fL,0x1ae80f8e6d7fbd65L,0x9d67225fbee6bdb0L,\n        0x3b433b597fc4d860L },\n      { 0x44e66db693e85638L,0xf7b59252e3e9862fL,0xdb785157665c32ecL,\n        0x702fefd7ae362f50L } },\n    /* 2 << 126 */\n    { { 0x3754475d0fefb0c3L,0xd48fb56b46d7c35dL,0xa070b633363798a4L,\n        0xae89f3d28fdb98e6L },\n      { 0x970b89c86363d14cL,0x8981752167abd27dL,0x9bf7d47444d5a021L,\n        0xb3083bafcac72aeeL } },\n    /* 3 << 126 */\n    { { 0x389741debe949a44L,0x638e9388546a4fa5L,0x3fe6419ca0047bdcL,\n        0x7047f648aaea57caL },\n      { 0x54e48a9041fbab17L,0xda8e0b28576bdba2L,0xe807eebcc72afddcL,\n        0x07d3336df42577bfL } },\n    /* 4 << 126 */\n    { { 0x62a8c244bfe20925L,0x91c19ac38fdce867L,0x5a96a5d5dd387063L,\n        0x61d587d421d324f6L },\n      { 0xe87673a2a37173eaL,0x2384800853778b65L,0x10f8441e05bab43eL,\n        0xfa11fe124621efbeL } },\n    /* 5 << 126 */\n    { { 0x047b772e81685d7bL,0x23f27d81bf34a976L,0xc27608e2915f48efL,\n        0x3b0b43faa521d5c3L },\n      { 0x7613fb2663ca7284L,0x7f5729b41d4db837L,0x87b14898583b526bL,\n        0x00b732a6bbadd3d1L } },\n    /* 6 << 126 */\n    { { 0x8e02f4262048e396L,0x436b50b6383d9de4L,0xf78d3481471e85adL,\n        0x8b01ea6ad005c8d6L },\n      { 0xd3c7afee97015c07L,0x46cdf1a94e3ba2aeL,0x7a42e50183d3a1d2L,\n        0xd54b5268b541dff4L } },\n    /* 7 << 126 */\n    { { 0x3f24cf304e23e9bcL,0x4387f816126e3624L,0x26a46a033b0b6d61L,\n        0xaf1bc8458b2d777cL },\n      { 0x25c401ba527de79cL,0x0e1346d44261bbb6L,0x4b96c44b287b4bc7L,\n        0x658493c75254562fL } },\n    /* 8 << 126 */\n    { { 0x23f949feb8a24a20L,0x17ebfed1f52ca53fL,0x9b691bbebcfb4853L,\n        0x5617ff6b6278a05dL },\n      { 0x241b34c5e3c99ebdL,0xfc64242e1784156aL,0x4206482f695d67dfL,\n        0xb967ce0eee27c011L } },\n    /* 9 << 126 */\n    { { 0x65db375121c80b5dL,0x2e7a563ca31ecca0L,0xe56ffc4e5238a07eL,\n        0x3d6c296632ced854L },\n      { 0xe99d7d1aaf70b885L,0xafc3bad92d686459L,0x9c78bf460cc8ba5bL,\n        0x5a43951918955aa3L } },\n    /* 10 << 126 */\n    { { 0xf8b517a85fe4e314L,0xe60234d0fcb8906fL,0xffe542acf2061b23L,\n        0x287e191f6b4cb59cL },\n      { 0x21857ddc09d877d8L,0x1c23478c14678941L,0xbbf0c056b6e05ea4L,\n        0x82da4b53b01594feL } },\n    /* 11 << 126 */\n    { { 0xf7526791fadb8608L,0x049e832d7b74cdf6L,0xa43581ccc2b90a34L,\n        0x73639eb89360b10cL },\n      { 0x4fba331fe1e4a71bL,0x6ffd6b938072f919L,0x6e53271c65679032L,\n        0x67206444f14272ceL } },\n    /* 12 << 126 */\n    { { 0xc0f734a3b2335834L,0x9526205a90ef6860L,0xcb8be71704e2bb0dL,\n        0x2418871e02f383faL },\n      { 0xd71776814082c157L,0xcc914ad029c20073L,0xf186c1ebe587e728L,\n        0x6fdb3c2261bcd5fdL } },\n    /* 13 << 126 */\n    { { 0x30d014a6f2f9f8e9L,0x963ece234fec49d2L,0x862025c59605a8d9L,\n        0x3987444519f8929aL },\n      { 0x01b6ff6512bf476aL,0x598a64d809cf7d91L,0xd7ec774993be56caL,\n        0x10899785cbb33615L } },\n    /* 14 << 126 */\n    { { 0xb8a092fd02eee3adL,0xa86b3d3530145270L,0x323d98c68512b675L,\n        0x4b8bc78562ebb40fL },\n      { 0x7d301f54413f9cdeL,0xa5e4fb4f2bab5664L,0x1d2b252d1cbfec23L,\n        0xfcd576bbe177120dL } },\n    /* 15 << 126 */\n    { { 0x04427d3e83731a34L,0x2bb9028eed836e8eL,0xb36acff8b612ca7cL,\n        0xb88fe5efd3d9c73aL },\n      { 0xbe2a6bc6edea4eb3L,0x43b93133488eec77L,0xf41ff566b17106e1L,\n        0x469e9172654efa32L } },\n    /* 16 << 126 */\n    { { 0xb4480f0441c23fa3L,0xb4712eb0c1989a2eL,0x3ccbba0f93a29ca7L,\n        0x6e205c14d619428cL },\n      { 0x90db7957b3641686L,0x0432691d45ac8b4eL,0x07a759acf64e0350L,\n        0x0514d89c9c972517L } },\n    /* 17 << 126 */\n    { { 0x1701147fa8e67fc3L,0x9e2e0b8bab2085beL,0xd5651824ac284e57L,\n        0x890d432574893664L },\n      { 0x8a7c5e6ec55e68a3L,0xbf12e90b4339c85aL,0x31846b85f922b655L,\n        0x9a54ce4d0bf4d700L } },\n    /* 18 << 126 */\n    { { 0xd7f4e83af1a14295L,0x916f955cb285d4f9L,0xe57bb0e099ffdabaL,\n        0x28a43034eab0d152L },\n      { 0x0a36ffa2b8a9cef8L,0x5517407eb9ec051aL,0x9c796096ea68e672L,\n        0x853db5fbfb3c77fbL } },\n    /* 19 << 126 */\n    { { 0x21474ba9e864a51aL,0x6c2676996e8a1b8bL,0x7c82362694120a28L,\n        0xe61e9a488383a5dbL },\n      { 0x7dd750039f84216dL,0xab020d07ad43cd85L,0x9437ae48da12c659L,\n        0x6449c2ebe65452adL } },\n    /* 20 << 126 */\n    { { 0xcc7c4c1c2cf9d7c1L,0x1320886aee95e5abL,0xbb7b9056beae170cL,\n        0xc8a5b250dbc0d662L },\n      { 0x4ed81432c11d2303L,0x7da669121f03769fL,0x3ac7a5fd84539828L,\n        0x14dada943bccdd02L } },\n    /* 21 << 126 */\n    { { 0x8b84c3217ef6b0d1L,0x52a9477a7c933f22L,0x5ef6728afd440b82L,\n        0x5c3bd8596ce4bd5eL },\n      { 0x918b80f5f22c2d3eL,0x368d5040b7bb6cc5L,0xb66142a12695a11cL,\n        0x60ac583aeb19ea70L } },\n    /* 22 << 126 */\n    { { 0x317cbb980eab2437L,0x8cc08c555e2654c8L,0xfe2d6520e6d8307fL,\n        0xe9f147f357428993L },\n      { 0x5f9c7d14d2fd6cf1L,0xa3ecd0642d4fcbb0L,0xad83fef08e7341f7L,\n        0x643f23a03a63115cL } },\n    /* 23 << 126 */\n    { { 0xd38a78abe65ab743L,0xbf7c75b135edc89cL,0x3dd8752e530df568L,\n        0xf85c4a76e308c682L },\n      { 0x4c9955b2e68acf37L,0xa544df3dab32af85L,0x4b8ec3f5a25cf493L,\n        0x4d8f27641a622febL } },\n    /* 24 << 126 */\n    { { 0x7bb4f7aaf0dcbc49L,0x7de551f970bbb45bL,0xcfd0f3e49f2ca2e5L,\n        0xece587091f5c76efL },\n      { 0x32920edd167d79aeL,0x039df8a2fa7d7ec1L,0xf46206c0bb30af91L,\n        0x1ff5e2f522676b59L } },\n    /* 25 << 126 */\n    { { 0x11f4a0396ea51d66L,0x506c1445807d7a26L,0x60da5705755a9b24L,\n        0x8fc8cc321f1a319eL },\n      { 0x83642d4d9433d67dL,0x7fa5cb8f6a7dd296L,0x576591db9b7bde07L,\n        0x13173d25419716fbL } },\n    /* 26 << 126 */\n    { { 0xea30599dd5b340ffL,0xfc6b5297b0fe76c5L,0x1c6968c8ab8f5adcL,\n        0xf723c7f5901c928dL },\n      { 0x4203c3219773d402L,0xdf7c6aa31b51dd47L,0x3d49e37a552be23cL,\n        0x57febee80b5a6e87L } },\n    /* 27 << 126 */\n    { { 0xc5ecbee47bd8e739L,0x79d44994ae63bf75L,0x168bd00f38fb8923L,\n        0x75d48ee4d0533130L },\n      { 0x554f77aadb5cdf33L,0x3396e8963c696769L,0x2fdddbf2d3fd674eL,\n        0xbbb8f6ee99d0e3e5L } },\n    /* 28 << 126 */\n    { { 0x51b90651cbae2f70L,0xefc4bc0593aaa8ebL,0x8ecd8689dd1df499L,\n        0x1aee99a822f367a5L },\n      { 0x95d485b9ae8274c5L,0x6c14d4457d30b39cL,0xbafea90bbcc1ef81L,\n        0x7c5f317aa459a2edL } },\n    /* 29 << 126 */\n    { { 0x012110754ef44227L,0xa17bed6edc20f496L,0x0cdfe424819853cdL,\n        0x13793298f71e2ce7L },\n      { 0x3c1f3078dbbe307bL,0x6dd1c20e76ee9936L,0x23ee4b57423caa20L,\n        0x4ac3793b8efb840eL } },\n    /* 30 << 126 */\n    { { 0x934438ebed1f8ca0L,0x3e5466584ebb25a2L,0xc415af0ec069896fL,\n        0xc13eddb09a5aa43dL },\n      { 0x7a04204fd49eb8f6L,0xd0d5bdfcd74f1670L,0x3697e28656fc0558L,\n        0x1020737101cebadeL } },\n    /* 31 << 126 */\n    { { 0x5f87e6900647a82bL,0x908e0ed48f40054fL,0xa9f633d479853803L,\n        0x8ed13c9a4a28b252L },\n      { 0x3e2ef6761f460f64L,0x53930b9b36d06336L,0x347073ac8fc4979bL,\n        0x84380e0e5ecd5597L } },\n    /* 32 << 126 */\n    { { 0xe3b22c6bc4fe3c39L,0xba4a81536c7bebdfL,0xf23ab6b725693459L,\n        0x53bc377014922b11L },\n      { 0x4645c8ab5afc60dbL,0xaa02235520b9f2a3L,0x52a2954cce0fc507L,\n        0x8c2731bb7ce1c2e7L } },\n    /* 33 << 126 */\n    { { 0xf39608ab18a0339dL,0xac7a658d3735436cL,0xb22c2b07cd992b4fL,\n        0x4e83daecf40dcfd4L },\n      { 0x8a34c7be2f39ea3eL,0xef0c005fb0a56d2eL,0x62731f6a6edd8038L,\n        0x5721d7404e3cb075L } },\n    /* 34 << 126 */\n    { { 0x1ea41511fbeeee1bL,0xd1ef5e73ef1d0c05L,0x42feefd173c07d35L,\n        0xe530a00a8a329493L },\n      { 0x5d55b7fef15ebfb0L,0x549de03cd322491aL,0xf7b5f602745b3237L,\n        0x3632a3a21ab6e2b6L } },\n    /* 35 << 126 */\n    { { 0x0d3bba890ef59f78L,0x0dfc6443c9e52b9aL,0x1dc7969972631447L,\n        0xef033917b3be20b1L },\n      { 0x0c92735db1383948L,0xc1fc29a2c0dd7d7dL,0x6485b697403ed068L,\n        0x13bfaab3aac93bdcL } },\n    /* 36 << 126 */\n    { { 0x410dc6a90deeaf52L,0xb003fb024c641c15L,0x1384978c5bc504c4L,\n        0x37640487864a6a77L },\n      { 0x05991bc6222a77daL,0x62260a575e47eb11L,0xc7af6613f21b432cL,\n        0x22f3acc9ab4953e9L } },\n    /* 37 << 126 */\n    { { 0x529349228e41d155L,0x4d0245683ac059efL,0xb02017554d884411L,\n        0xce8055cfa59a178fL },\n      { 0xcd77d1aff6204549L,0xa0a00a3ec7066759L,0x471071ef0272c229L,\n        0x009bcf6bd3c4b6b0L } },\n    /* 38 << 126 */\n    { { 0x2a2638a822305177L,0xd51d59df41645bbfL,0xa81142fdc0a7a3c0L,\n        0xa17eca6d4c7063eeL },\n      { 0x0bb887ed60d9dcecL,0xd6d28e5120ad2455L,0xebed6308a67102baL,\n        0x042c31148bffa408L } },\n    /* 39 << 126 */\n    { { 0xfd099ac58aa68e30L,0x7a6a3d7c1483513eL,0xffcc6b75ba2d8f0cL,\n        0x54dacf961e78b954L },\n      { 0xf645696fa4a9af89L,0x3a41194006ac98ecL,0x41b8b3f622a67a20L,\n        0x2d0b1e0f99dec626L } },\n    /* 40 << 126 */\n    { { 0x27c8919240be34e8L,0xc7162b3791907f35L,0x90188ec1a956702bL,\n        0xca132f7ddf93769cL },\n      { 0x3ece44f90e2025b4L,0x67aaec690c62f14cL,0xad74141822e3cc11L,\n        0xcf9b75c37ff9a50eL } },\n    /* 41 << 126 */\n    { { 0x02fa2b164d348272L,0xbd99d61a9959d56dL,0xbc4f19db18762916L,\n        0xcc7cce5049c1ac80L },\n      { 0x4d59ebaad846bd83L,0x8775a9dca9202849L,0x07ec4ae16e1f4ca9L,\n        0x27eb5875ba893f11L } },\n    /* 42 << 126 */\n    { { 0x00284d51662cc565L,0x82353a6b0db4138dL,0xd9c7aaaaaa32a594L,\n        0xf5528b5ea5669c47L },\n      { 0xf32202312f23c5ffL,0xe3e8147a6affa3a1L,0xfb423d5c202ddda0L,\n        0x3d6414ac6b871bd4L } },\n    /* 43 << 126 */\n    { { 0x586f82e1a51a168aL,0xb712c67148ae5448L,0x9a2e4bd176233eb8L,\n        0x0188223a78811ca9L },\n      { 0x553c5e21f7c18de1L,0x7682e451b27bb286L,0x3ed036b30e51e929L,\n        0xf487211bec9cb34fL } },\n    /* 44 << 126 */\n    { { 0x0d0942770c24efc8L,0x0349fd04bef737a4L,0x6d1c9dd2514cdd28L,\n        0x29c135ff30da9521L },\n      { 0xea6e4508f78b0b6fL,0x176f5dd2678c143cL,0x081484184be21e65L,\n        0x27f7525ce7df38c4L } },\n    /* 45 << 126 */\n    { { 0x1fb70e09748ab1a4L,0x9cba50a05efe4433L,0x7846c7a615f75af2L,\n        0x2a7c2c575ee73ea8L },\n      { 0x42e566a43f0a449aL,0x45474c3bad90fc3dL,0x7447be3d8b61d057L,\n        0x3e9d1cf13a4ec092L } },\n    /* 46 << 126 */\n    { { 0x1603e453f380a6e6L,0x0b86e4319b1437c2L,0x7a4173f2ef29610aL,\n        0x8fa729a7f03d57f7L },\n      { 0x3e186f6e6c9c217eL,0xbe1d307991919524L,0x92a62a70153d4fb1L,\n        0x32ed3e34d68c2f71L } },\n    /* 47 << 126 */\n    { { 0xd785027f9eb1a8b7L,0xbc37eb77c5b22fe8L,0x466b34f0b9d6a191L,\n        0x008a89af9a05f816L },\n      { 0x19b028fb7d42c10aL,0x7fe8c92f49b3f6b8L,0x58907cc0a5a0ade3L,\n        0xb3154f51559d1a7cL } },\n    /* 48 << 126 */\n    { { 0x5066efb6d9790ed6L,0xa77a0cbca6aa793bL,0x1a915f3c223e042eL,\n        0x1c5def0469c5874bL },\n      { 0x0e83007873b6c1daL,0x55cf85d2fcd8557aL,0x0f7c7c760460f3b1L,\n        0x87052acb46e58063L } },\n    /* 49 << 126 */\n    { { 0x09212b80907eae66L,0x3cb068e04d721c89L,0xa87941aedd45ac1cL,\n        0xde8d5c0d0daa0dbbL },\n      { 0xda421fdce3502e6eL,0xc89442014d89a084L,0x7307ba5ef0c24bfbL,\n        0xda212beb20bde0efL } },\n    /* 50 << 126 */\n    { { 0xea2da24bf82ce682L,0x058d381607f71fe4L,0x35a024625ffad8deL,\n        0xcd7b05dcaadcefabL },\n      { 0xd442f8ed1d9f54ecL,0x8be3d618b2d3b5caL,0xe2220ed0e06b2ce2L,\n        0x82699a5f1b0da4c0L } },\n    /* 51 << 126 */\n    { { 0x3ff106f571c0c3a7L,0x8f580f5a0d34180cL,0x4ebb120e22d7d375L,\n        0x5e5782cce9513675L },\n      { 0x2275580c99c82a70L,0xe8359fbf15ea8c4cL,0x53b48db87b415e70L,\n        0xaacf2240100c6014L } },\n    /* 52 << 126 */\n    { { 0x9faaccf5e4652f1dL,0xbd6fdd2ad56157b2L,0xa4f4fb1f6261ec50L,\n        0x244e55ad476bcd52L },\n      { 0x881c9305047d320bL,0x1ca983d56181263fL,0x354e9a44278fb8eeL,\n        0xad2dbc0f396e4964L } },\n    /* 53 << 126 */\n    { { 0x723f3aa29268b3deL,0x0d1ca29ae6e0609aL,0x794866aa6cf44252L,\n        0x0b59f3e301af87edL },\n      { 0xe234e5ff7f4a6c51L,0xa8768fd261dc2f7eL,0xdafc73320a94d81fL,\n        0xd7f8428206938ce1L } },\n    /* 54 << 126 */\n    { { 0xae0b3c0e0546063eL,0x7fbadcb25d61abc6L,0xd5d7a2c9369ac400L,\n        0xa5978d09ae67d10cL },\n      { 0x290f211e4f85eaacL,0xe61e2ad1facac681L,0xae125225388384cdL,\n        0xa7fb68e9ccfde30fL } },\n    /* 55 << 126 */\n    { { 0x7a59b9363daed4c2L,0x80a9aa402606f789L,0xb40c1ea5f6a6d90aL,\n        0x948364d3514d5885L },\n      { 0x062ebc6070985182L,0xa6db5b0e33310895L,0x64a12175e329c2f5L,\n        0xc5f25bd290ea237eL } },\n    /* 56 << 126 */\n    { { 0x7915c5242d0a4c23L,0xeb5d26e46bb3cc52L,0x369a9116c09e2c92L,\n        0x0c527f92cf182cf8L },\n      { 0x9e5919382aede0acL,0xb29222086cc34939L,0x3c9d896299a34361L,\n        0x3c81836dc1905fe6L } },\n    /* 57 << 126 */\n    { { 0x4bfeb57fa001ec5aL,0xe993f5bba0dc5dbaL,0x47884109724a1380L,\n        0x8a0369ab32fe9a04L },\n      { 0xea068d608c927db8L,0xbf5f37cf94655741L,0x47d402a204b6c7eaL,\n        0x4551c2956af259cbL } },\n    /* 58 << 126 */\n    { { 0x698b71e7ed77ee8bL,0xbddf7bd0f309d5c7L,0x6201c22c34e780caL,\n        0xab04f7d84c295ef4L },\n      { 0x1c9472944313a8ceL,0xe532e4ac92ca4cfeL,0x89738f80d0a7a97aL,\n        0xec088c88a580fd5bL } },\n    /* 59 << 126 */\n    { { 0x612b1ecc42ce9e51L,0x8f9840fdb25fdd2aL,0x3cda78c001e7f839L,\n        0x546b3d3aece05480L },\n      { 0x271719a980d30916L,0x45497107584c20c4L,0xaf8f94785bc78608L,\n        0x28c7d484277e2a4cL } },\n    /* 60 << 126 */\n    { { 0xfce0176788a2ffe4L,0xdc506a3528e169a5L,0x0ea108617af9c93aL,\n        0x1ed2436103fa0e08L },\n      { 0x96eaaa92a3d694e7L,0xc0f43b4def50bc74L,0xce6aa58c64114db4L,\n        0x8218e8ea7c000fd4L } },\n    /* 61 << 126 */\n    { { 0xac815dfb185f8844L,0xcd7e90cb1557abfbL,0x23d16655afbfecdfL,\n        0x80f3271f085cac4aL },\n      { 0x7fc39aa7d0e62f47L,0x88d519d1460a48e5L,0x59559ac4d28f101eL,\n        0x7981d9e9ca9ae816L } },\n    /* 62 << 126 */\n    { { 0x5c38652c9ac38203L,0x86eaf87f57657fe5L,0x568fc472e21f5416L,\n        0x2afff39ce7e597b5L },\n      { 0x3adbbb07256d4eabL,0x225986928285ab89L,0x35f8112a041caefeL,\n        0x95df02e3a5064c8bL } },\n    /* 63 << 126 */\n    { { 0x4d63356ec7004bf3L,0x230a08f4db83c7deL,0xca27b2708709a7b7L,\n        0x0d1c4cc4cb9abd2dL },\n      { 0x8a0bc66e7550fee8L,0x369cd4c79cf7247eL,0x75562e8492b5b7e7L,\n        0x8fed0da05802af7bL } },\n    /* 64 << 126 */\n    { { 0x6a7091c2e48fb889L,0x26882c137b8a9d06L,0xa24986631b82a0e2L,\n        0x844ed7363518152dL },\n      { 0x282f476fd86e27c7L,0xa04edaca04afefdcL,0x8b256ebc6119e34dL,\n        0x56a413e90787d78bL } },\n    /* 0 << 133 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 133 */\n    { { 0x82ee061d5a74be50L,0xe41781c4dea16ff5L,0xe0b0c81e99bfc8a2L,\n        0x624f4d690b547e2dL },\n      { 0x3a83545dbdcc9ae4L,0x2573dbb6409b1e8eL,0x482960c4a6c93539L,\n        0xf01059ad5ae18798L } },\n    /* 2 << 133 */\n    { { 0x715c9f973112795fL,0xe8244437984e6ee1L,0x55cb4858ecb66bcdL,\n        0x7c136735abaffbeeL },\n      { 0x546615955dbec38eL,0x51c0782c388ad153L,0x9ba4c53ac6e0952fL,\n        0x27e6782a1b21dfa8L } },\n    /* 3 << 133 */\n    { { 0x682f903d4ed2dbc2L,0x0eba59c87c3b2d83L,0x8e9dc84d9c7e9335L,\n        0x5f9b21b00eb226d7L },\n      { 0xe33bd394af267baeL,0xaa86cc25be2e15aeL,0x4f0bf67d6a8ec500L,\n        0x5846aa44f9630658L } },\n    /* 4 << 133 */\n    { { 0xfeb09740e2c2bf15L,0x627a2205a9e99704L,0xec8d73d0c2fbc565L,\n        0x223eed8fc20c8de8L },\n      { 0x1ee32583a8363b49L,0x1a0b6cb9c9c2b0a6L,0x49f7c3d290dbc85cL,\n        0xa8dfbb971ef4c1acL } },\n    /* 5 << 133 */\n    { { 0xafb34d4c65c7c2abL,0x1d4610e7e2c5ea84L,0x893f6d1b973c4ab5L,\n        0xa3cdd7e9945ba5c4L },\n      { 0x60514983064417eeL,0x1459b23cad6bdf2bL,0x23b2c3415cf726c3L,\n        0x3a82963532d6354aL } },\n    /* 6 << 133 */\n    { { 0x294f901fab192c18L,0xec5fcbfe7030164fL,0xe2e2fcb7e2246ba6L,\n        0x1e7c88b3221a1a0cL },\n      { 0x72c7dd93c92d88c5L,0x41c2148e1106fb59L,0x547dd4f5a0f60f14L,\n        0xed9b52b263960f31L } },\n    /* 7 << 133 */\n    { { 0x6c8349ebb0a5b358L,0xb154c5c29e7e2ed6L,0xcad5eccfeda462dbL,\n        0xf2d6dbe42de66b69L },\n      { 0x426aedf38665e5b2L,0x488a85137b7f5723L,0x15cc43b38bcbb386L,\n        0x27ad0af3d791d879L } },\n    /* 8 << 133 */\n    { { 0xc16c236e846e364fL,0x7f33527cdea50ca0L,0xc48107750926b86dL,\n        0x6c2a36090598e70cL },\n      { 0xa6755e52f024e924L,0xe0fa07a49db4afcaL,0x15c3ce7d66831790L,\n        0x5b4ef350a6cbb0d6L } },\n    /* 9 << 133 */\n    { { 0x2c4aafc4b6205969L,0x42563f02f6c7854fL,0x016aced51d983b48L,\n        0xfeb356d899949755L },\n      { 0x8c2a2c81d1a39bd7L,0x8f44340fe6934ae9L,0x148cf91c447904daL,\n        0x7340185f0f51a926L } },\n    /* 10 << 133 */\n    { { 0x2f8f00fb7409ab46L,0x057e78e680e289b2L,0x03e5022ca888e5d1L,\n        0x3c87111a9dede4e2L },\n      { 0x5b9b0e1c7809460bL,0xe751c85271c9abc7L,0x8b944e28c7cc1dc9L,\n        0x4f201ffa1d3cfa08L } },\n    /* 11 << 133 */\n    { { 0x02fc905c3e6721ceL,0xd52d70dad0b3674cL,0x5dc2e5ca18810da4L,\n        0xa984b2735c69dd99L },\n      { 0x63b9252784de5ca4L,0x2f1c9872c852dec4L,0x18b03593c2e3de09L,\n        0x19d70b019813dc2fL } },\n    /* 12 << 133 */\n    { { 0x42806b2da6dc1d29L,0xd3030009f871e144L,0xa1feb333aaf49276L,\n        0xb5583b9ec70bc04bL },\n      { 0x1db0be7895695f20L,0xfc84181189d012b5L,0x6409f27205f61643L,\n        0x40d34174d5883128L } },\n    /* 13 << 133 */\n    { { 0xd79196f567419833L,0x6059e252863b7b08L,0x84da18171c56700cL,\n        0x5758ee56b28d3ec4L },\n      { 0x7da2771d013b0ea6L,0xfddf524b54c5e9b9L,0x7df4faf824305d80L,\n        0x58f5c1bf3a97763fL } },\n    /* 14 << 133 */\n    { { 0xa5af37f17c696042L,0xd4cba22c4a2538deL,0x211cb9959ea42600L,\n        0xcd105f417b069889L },\n      { 0xb1e1cf19ddb81e74L,0x472f2d895157b8caL,0x086fb008ee9db885L,\n        0x365cd5700f26d131L } },\n    /* 15 << 133 */\n    { { 0x284b02bba2be7053L,0xdcbbf7c67ab9a6d6L,0x4425559c20f7a530L,\n        0x961f2dfa188767c8L },\n      { 0xe2fd943570dc80c4L,0x104d6b63f0784120L,0x7f592bc153567122L,\n        0xf6bc1246f688ad77L } },\n    /* 16 << 133 */\n    { { 0x05214c050f15dde9L,0xa47a76a80d5f2b82L,0xbb254d3062e82b62L,\n        0x11a05fe03ec955eeL },\n      { 0x7eaff46e9d529b36L,0x55ab13018f9e3df6L,0xc463e37199317698L,\n        0xfd251438ccda47adL } },\n    /* 17 << 133 */\n    { { 0xca9c354723d695eaL,0x48ce626e16e589b5L,0x6b5b64c7b187d086L,\n        0xd02e1794b2207948L },\n      { 0x8b58e98f7198111dL,0x90ca6305dcf9c3ccL,0x5691fe72f34089b0L,\n        0x60941af1fc7c80ffL } },\n    /* 18 << 133 */\n    { { 0xa09bc0a222eb51e5L,0xc0bb7244aa9cf09aL,0x36a8077f80159f06L,\n        0x8b5c989edddc560eL },\n      { 0x19d2f316512e1f43L,0x02eac554ad08ff62L,0x012ab84c07d20b4eL,\n        0x37d1e115d6d4e4e1L } },\n    /* 19 << 133 */\n    { { 0xb6443e1aab7b19a8L,0xf08d067edef8cd45L,0x63adf3e9685e03daL,\n        0xcf15a10e4792b916L },\n      { 0xf44bcce5b738a425L,0xebe131d59636b2fdL,0x940688417850d605L,\n        0x09684eaab40d749dL } },\n    /* 20 << 133 */\n    { { 0x8c3c669c72ba075bL,0x89f78b55ba469015L,0x5706aade3e9f8ba8L,\n        0x6d8bd565b32d7ed7L },\n      { 0x25f4e63b805f08d6L,0x7f48200dc3bcc1b5L,0x4e801968b025d847L,\n        0x74afac0487cbe0a8L } },\n    /* 21 << 133 */\n    { { 0x43ed2c2b7e63d690L,0xefb6bbf00223cdb8L,0x4fec3cae2884d3feL,\n        0x065ecce6d75e25a4L },\n      { 0x6c2294ce69f79071L,0x0d9a8e5f044b8666L,0x5009f23817b69d8fL,\n        0x3c29f8fec5dfdaf7L } },\n    /* 22 << 133 */\n    { { 0x9067528febae68c4L,0x5b38563230c5ba21L,0x540df1191fdd1aecL,\n        0xcf37825bcfba4c78L },\n      { 0x77eff980beb11454L,0x40a1a99160c1b066L,0xe8018980f889a1c7L,\n        0xb9c52ae976c24be0L } },\n    /* 23 << 133 */\n    { { 0x05fbbcce45650ef4L,0xae000f108aa29ac7L,0x884b71724f04c470L,\n        0x7cd4fde219bb5c25L },\n      { 0x6477b22ae8840869L,0xa88688595fbd0686L,0xf23cc02e1116dfbaL,\n        0x76cd563fd87d7776L } },\n    /* 24 << 133 */\n    { { 0xe2a37598a9d82abfL,0x5f188ccbe6c170f5L,0x816822005066b087L,\n        0xda22c212c7155adaL },\n      { 0x151e5d3afbddb479L,0x4b606b846d715b99L,0x4a73b54bf997cb2eL,\n        0x9a1bfe433ecd8b66L } },\n    /* 25 << 133 */\n    { { 0x1c3128092a67d48aL,0xcd6a671e031fa9e2L,0xbec3312a0e43a34aL,\n        0x1d93563955ef47d3L },\n      { 0x5ea024898fea73eaL,0x8247b364a035afb2L,0xb58300a65265b54cL,\n        0x3286662f722c7148L } },\n    /* 26 << 133 */\n    { { 0xb77fd76bb4ec4c20L,0xf0a12fa70f3fe3fdL,0xf845bbf541d8c7e8L,\n        0xe4d969ca5ec10aa8L },\n      { 0x4c0053b743e232a3L,0xdc7a3fac37f8a45aL,0x3c4261c520d81c8fL,\n        0xfd4b3453b00eab00L } },\n    /* 27 << 133 */\n    { { 0x76d48f86d36e3062L,0x626c5277a143ff02L,0x538174deaf76f42eL,\n        0x2267aa866407ceacL },\n      { 0xfad7635172e572d5L,0xab861af7ba7330ebL,0xa0a1c8c7418d8657L,\n        0x988821cb20289a52L } },\n    /* 28 << 133 */\n    { { 0x79732522cccc18adL,0xaadf3f8df1a6e027L,0xf7382c9317c2354dL,\n        0x5ce1680cd818b689L },\n      { 0x359ebbfcd9ecbee9L,0x4330689c1cae62acL,0xb55ce5b4c51ac38aL,\n        0x7921dfeafe238ee8L } },\n    /* 29 << 133 */\n    { { 0x3972bef8271d1ca5L,0x3e423bc7e8aabd18L,0x57b09f3f44a3e5e3L,\n        0x5da886ae7b444d66L },\n      { 0x68206634a9964375L,0x356a2fa3699cd0ffL,0xaf0faa24dba515e9L,\n        0x536e1f5cb321d79aL } },\n    /* 30 << 133 */\n    { { 0xd3b9913a5c04e4eaL,0xd549dcfed6f11513L,0xee227bf579fd1d94L,\n        0x9f35afeeb43f2c67L },\n      { 0xd2638d24f1314f53L,0x62baf948cabcd822L,0x5542de294ef48db0L,\n        0xb3eb6a04fc5f6bb2L } },\n    /* 31 << 133 */\n    { { 0x23c110ae1208e16aL,0x1a4d15b5f8363e24L,0x30716844164be00bL,\n        0xa8e24824f6f4690dL },\n      { 0x548773a290b170cfL,0xa1bef33142f191f4L,0x70f418d09247aa97L,\n        0xea06028e48be9147L } },\n    /* 32 << 133 */\n    { { 0xe13122f3dbfb894eL,0xbe9b79f6ce274b18L,0x85a49de5ca58aadfL,\n        0x2495775811487351L },\n      { 0x111def61bb939099L,0x1d6a974a26d13694L,0x4474b4ced3fc253bL,\n        0x3a1485e64c5db15eL } },\n    /* 33 << 133 */\n    { { 0xe79667b4147c15b4L,0xe34f553b7bc61301L,0x032b80f817094381L,\n        0x55d8bafd723eaa21L },\n      { 0x5a987995f1c0e74eL,0x5a9b292eebba289cL,0x413cd4b2eb4c8251L,\n        0x98b5d243d162db0aL } },\n    /* 34 << 133 */\n    { { 0xbb47bf6668342520L,0x08d68949baa862d1L,0x11f349c7e906abcdL,\n        0x454ce985ed7bf00eL },\n      { 0xacab5c9eb55b803bL,0xb03468ea31e3c16dL,0x5c24213dd273bf12L,\n        0x211538eb71587887L } },\n    /* 35 << 133 */\n    { { 0x198e4a2f731dea2dL,0xd5856cf274ed7b2aL,0x86a632eb13a664feL,\n        0x932cd909bda41291L },\n      { 0x850e95d4c0c4ddc0L,0xc0f422f8347fc2c9L,0xe68cbec486076bcbL,\n        0xf9e7c0c0cd6cd286L } },\n    /* 36 << 133 */\n    { { 0x65994ddb0f5f27caL,0xe85461fba80d59ffL,0xff05481a66601023L,\n        0xc665427afc9ebbfbL },\n      { 0xb0571a697587fd52L,0x935289f88d49efceL,0x61becc60ea420688L,\n        0xb22639d913a786afL } },\n    /* 37 << 133 */\n    { { 0x1a8e6220361ecf90L,0x001f23e025506463L,0xe4ae9b5d0a5c2b79L,\n        0xebc9cdadd8149db5L },\n      { 0xb33164a1934aa728L,0x750eb00eae9b60f3L,0x5a91615b9b9cfbfdL,\n        0x97015cbfef45f7f6L } },\n    /* 38 << 133 */\n    { { 0xb462c4a5bf5151dfL,0x21adcc41b07118f2L,0xd60c545b043fa42cL,\n        0xfc21aa54e96be1abL },\n      { 0xe84bc32f4e51ea80L,0x3dae45f0259b5d8dL,0xbb73c7ebc38f1b5eL,\n        0xe405a74ae8ae617dL } },\n    /* 39 << 133 */\n    { { 0xbb1ae9c69f1c56bdL,0x8c176b9849f196a4L,0xc448f3116875092bL,\n        0xb5afe3de9f976033L },\n      { 0xa8dafd49145813e5L,0x687fc4d9e2b34226L,0xf2dfc92d4c7ff57fL,\n        0x004e3fc1401f1b46L } },\n    /* 40 << 133 */\n    { { 0x5afddab61430c9abL,0x0bdd41d32238e997L,0xf0947430418042aeL,\n        0x71f9addacdddc4cbL },\n      { 0x7090c016c52dd907L,0xd9bdf44d29e2047fL,0xe6f1fe801b1011a6L,\n        0xb63accbcd9acdc78L } },\n    /* 41 << 133 */\n    { { 0xcfc7e2351272a95bL,0x0c667717a6276ac8L,0x3c0d3709e2d7eef7L,\n        0x5add2b069a685b3eL },\n      { 0x363ad32d14ea5d65L,0xf8e01f068d7dd506L,0xc9ea221375b4aac6L,\n        0xed2a2bf90d353466L } },\n    /* 42 << 133 */\n    { { 0x439d79b5e9d3a7c3L,0x8e0ee5a681b7f34bL,0xcf3dacf51dc4ba75L,\n        0x1d3d1773eb3310c7L },\n      { 0xa8e671127747ae83L,0x31f43160197d6b40L,0x0521cceecd961400L,\n        0x67246f11f6535768L } },\n    /* 43 << 133 */\n    { { 0x702fcc5aef0c3133L,0x247cc45d7e16693bL,0xfd484e49c729b749L,\n        0x522cef7db218320fL },\n      { 0xe56ef40559ab93b3L,0x225fba119f181071L,0x33bd659515330ed0L,\n        0xc4be69d51ddb32f7L } },\n    /* 44 << 133 */\n    { { 0x264c76680448087cL,0xac30903f71432daeL,0x3851b26600f9bf47L,\n        0x400ed3116cdd6d03L },\n      { 0x045e79fef8fd2424L,0xfdfd974afa6da98bL,0x45c9f6410c1e673aL,\n        0x76f2e7335b2c5168L } },\n    /* 45 << 133 */\n    { { 0x1adaebb52a601753L,0xb286514cc57c2d49L,0xd87696701e0bfd24L,\n        0x950c547e04478922L },\n      { 0xd1d41969e5d32bfeL,0x30bc1472750d6c3eL,0x8f3679fee0e27f3aL,\n        0x8f64a7dca4a6ee0cL } },\n    /* 46 << 133 */\n    { { 0x2fe59937633dfb1fL,0xea82c395977f2547L,0xcbdfdf1a661ea646L,\n        0xc7ccc591b9085451L },\n      { 0x8217796281761e13L,0xda57596f9196885cL,0xbc17e84928ffbd70L,\n        0x1e6e0a412671d36fL } },\n    /* 47 << 133 */\n    { { 0x61ae872c4152fcf5L,0x441c87b09e77e754L,0xd0799dd5a34dff09L,\n        0x766b4e4488a6b171L },\n      { 0xdc06a51211f1c792L,0xea02ae934be35c3eL,0xe5ca4d6de90c469eL,\n        0x4df4368e56e4ff5cL } },\n    /* 48 << 133 */\n    { { 0x7817acab4baef62eL,0x9f5a2202a85b91e8L,0x9666ebe66ce57610L,\n        0x32ad31f3f73bfe03L },\n      { 0x628330a425bcf4d6L,0xea950593515056e6L,0x59811c89e1332156L,\n        0xc89cf1fe8c11b2d7L } },\n    /* 49 << 133 */\n    { { 0x75b6391304e60cc0L,0xce811e8d4625d375L,0x030e43fc2d26e562L,\n        0xfbb30b4b608d36a0L },\n      { 0x634ff82c48528118L,0x7c6fe085cd285911L,0x7f2830c099358f28L,\n        0x2e60a95e665e6c09L } },\n    /* 50 << 133 */\n    { { 0x08407d3d9b785dbfL,0x530889aba759bce7L,0xf228e0e652f61239L,\n        0x2b6d14616879be3cL },\n      { 0xe6902c0451a7bbf7L,0x30ad99f076f24a64L,0x66d9317a98bc6da0L,\n        0xf4f877f3cb596ac0L } },\n    /* 51 << 133 */\n    { { 0xb05ff62d4c44f119L,0x4555f536e9b77416L,0xc7c0d0598caed63bL,\n        0x0cd2b7cec358b2a9L },\n      { 0x3f33287b46945fa3L,0xf8785b20d67c8791L,0xc54a7a619637bd08L,\n        0x54d4598c18be79d7L } },\n    /* 52 << 133 */\n    { { 0x889e5acbc46d7ce1L,0x9a515bb78b085877L,0xfac1a03d0b7a5050L,\n        0x7d3e738af2926035L },\n      { 0x861cc2ce2a6cb0ebL,0x6f2e29558f7adc79L,0x61c4d45133016376L,\n        0xd9fd2c805ad59090L } },\n    /* 53 << 133 */\n    { { 0xe5a83738b2b836a1L,0x855b41a07c0d6622L,0x186fe3177cc19af1L,\n        0x6465c1fffdd99acbL },\n      { 0x46e5c23f6974b99eL,0x75a7cf8ba2717cbeL,0x4d2ebc3f062be658L,\n        0x094b44475f209c98L } },\n    /* 54 << 133 */\n    { { 0x4af285edb940cb5aL,0x6706d7927cc82f10L,0xc8c8776c030526faL,\n        0xfa8e6f76a0da9140L },\n      { 0x77ea9d34591ee4f0L,0x5f46e33740274166L,0x1bdf98bbea671457L,\n        0xd7c08b46862a1fe2L } },\n    /* 55 << 133 */\n    { { 0x46cc303c1c08ad63L,0x995434404c845e7bL,0x1b8fbdb548f36bf7L,\n        0x5b82c3928c8273a7L },\n      { 0x08f712c4928435d5L,0x071cf0f179330380L,0xc74c2d24a8da054aL,\n        0xcb0e720143c46b5cL } },\n    /* 56 << 133 */\n    { { 0x0ad7337ac0b7eff3L,0x8552225ec5e48b3cL,0xe6f78b0c73f13a5fL,\n        0x5e70062e82349cbeL },\n      { 0x6b8d5048e7073969L,0x392d2a29c33cb3d2L,0xee4f727c4ecaa20fL,\n        0xa068c99e2ccde707L } },\n    /* 57 << 133 */\n    { { 0xfcd5651fb87a2913L,0xea3e3c153cc252f0L,0x777d92df3b6cd3e4L,\n        0x7a414143c5a732e7L },\n      { 0xa895951aa71ff493L,0xfe980c92bbd37cf6L,0x45bd5e64decfeeffL,\n        0x910dc2a9a44c43e9L } },\n    /* 58 << 133 */\n    { { 0xcb403f26cca9f54dL,0x928bbdfb9303f6dbL,0x3c37951ea9eee67cL,\n        0x3bd61a52f79961c3L },\n      { 0x09a238e6395c9a79L,0x6940ca2d61eb352dL,0x7d1e5c5ec1875631L,\n        0x1e19742c1e1b20d1L } },\n    /* 59 << 133 */\n    { { 0x4633d90823fc2e6eL,0xa76e29a908959149L,0x61069d9c84ed7da5L,\n        0x0baa11cf5dbcad51L },\n      { 0xd01eec64961849daL,0x93b75f1faf3d8c28L,0x57bc4f9f1ca2ee44L,\n        0x5a26322d00e00558L } },\n    /* 60 << 133 */\n    { { 0x1888d65861a023efL,0x1d72aab4b9e5246eL,0xa9a26348e5563ec0L,\n        0xa0971963c3439a43L },\n      { 0x567dd54badb9b5b7L,0x73fac1a1c45a524bL,0x8fe97ef7fe38e608L,\n        0x608748d23f384f48L } },\n    /* 61 << 133 */\n    { { 0xb0571794c486094fL,0x869254a38bf3a8d6L,0x148a8dd1310b0e25L,\n        0x99ab9f3f9aa3f7d8L },\n      { 0x0927c68a6706c02eL,0x22b5e76c69790e6cL,0x6c3252606c71376cL,\n        0x53a5769009ef6657L } },\n    /* 62 << 133 */\n    { { 0x8d63f852edffcf3aL,0xb4d2ed043c0a6f55L,0xdb3aa8de12519b9eL,\n        0x5d38e9c41e0a569aL },\n      { 0x871528bf303747e2L,0xa208e77cf5b5c18dL,0x9d129c88ca6bf923L,\n        0xbcbf197fbf02839fL } },\n    /* 63 << 133 */\n    { { 0x9b9bf03027323194L,0x3b055a8b339ca59dL,0xb46b23120f669520L,\n        0x19789f1f497e5f24L },\n      { 0x9c499468aaf01801L,0x72ee11908b69d59cL,0x8bd39595acf4c079L,\n        0x3ee11ece8e0cd048L } },\n    /* 64 << 133 */\n    { { 0xebde86ec1ed66f18L,0x225d906bd61fce43L,0x5cab07d6e8bed74dL,\n        0x16e4617f27855ab7L },\n      { 0x6568aaddb2fbc3ddL,0xedb5484f8aeddf5bL,0x878f20e86dcf2fadL,\n        0x3516497c615f5699L } },\n    /* 0 << 140 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 140 */\n    { { 0xef0a3fecfa181e69L,0x9ea02f8130d69a98L,0xb2e9cf8e66eab95dL,\n        0x520f2beb24720021L },\n      { 0x621c540a1df84361L,0x1203772171fa6d5dL,0x6e3c7b510ff5f6ffL,\n        0x817a069babb2bef3L } },\n    /* 2 << 140 */\n    { { 0x83572fb6b294cda6L,0x6ce9bf75b9039f34L,0x20e012f0095cbb21L,\n        0xa0aecc1bd063f0daL },\n      { 0x57c21c3af02909e5L,0xc7d59ecf48ce9cdcL,0x2732b8448ae336f8L,\n        0x056e37233f4f85f4L } },\n    /* 3 << 140 */\n    { { 0x8a10b53189e800caL,0x50fe0c17145208fdL,0x9e43c0d3b714ba37L,\n        0x427d200e34189accL },\n      { 0x05dee24fe616e2c0L,0x9c25f4c8ee1854c1L,0x4d3222a58f342a73L,\n        0x0807804fa027c952L } },\n    /* 4 << 140 */\n    { { 0xc222653a4f0d56f3L,0x961e4047ca28b805L,0x2c03f8b04a73434bL,\n        0x4c966787ab712a19L },\n      { 0xcc196c42864fee42L,0xc1be93da5b0ece5cL,0xa87d9f22c131c159L,\n        0x2bb6d593dce45655L } },\n    /* 5 << 140 */\n    { { 0x22c49ec9b809b7ceL,0x8a41486be2c72c2cL,0x813b9420fea0bf36L,\n        0xb3d36ee9a66dac69L },\n      { 0x6fddc08a328cc987L,0x0a3bcd2c3a326461L,0x7103c49dd810dbbaL,\n        0xf9d81a284b78a4c4L } },\n    /* 6 << 140 */\n    { { 0x3de865ade4d55941L,0xdedafa5e30384087L,0x6f414abb4ef18b9bL,\n        0x9ee9ea42faee5268L },\n      { 0x260faa1637a55a4aL,0xeb19a514015f93b9L,0x51d7ebd29e9c3598L,\n        0x523fc56d1932178eL } },\n    /* 7 << 140 */\n    { { 0x501d070cb98fe684L,0xd60fbe9a124a1458L,0xa45761c892bc6b3fL,\n        0xf5384858fe6f27cbL },\n      { 0x4b0271f7b59e763bL,0x3d4606a95b5a8e5eL,0x1eda5d9b05a48292L,\n        0xda7731d0e6fec446L } },\n    /* 8 << 140 */\n    { { 0xa3e3369390d45871L,0xe976404006166d8dL,0xb5c3368289a90403L,\n        0x4bd1798372f1d637L },\n      { 0xa616679ed5d2c53aL,0x5ec4bcd8fdcf3b87L,0xae6d7613b66a694eL,\n        0x7460fc76e3fc27e5L } },\n    /* 9 << 140 */\n    { { 0x70469b8295caabeeL,0xde024ca5889501e3L,0x6bdadc06076ed265L,\n        0x0cb1236b5a0ef8b2L },\n      { 0x4065ddbf0972ebf9L,0xf1dd387522aca432L,0xa88b97cf744aff76L,\n        0xd1359afdfe8e3d24L } },\n    /* 10 << 140 */\n    { { 0x52a3ba2b91502cf3L,0x2c3832a8084db75dL,0x04a12dddde30b1c9L,\n        0x7802eabce31fd60cL },\n      { 0x33707327a37fddabL,0x65d6f2abfaafa973L,0x3525c5b811e6f91aL,\n        0x76aeb0c95f46530bL } },\n    /* 11 << 140 */\n    { { 0xe8815ff62f93a675L,0xa6ec968405f48679L,0x6dcbb556358ae884L,\n        0x0af61472e19e3873L },\n      { 0x72334372a5f696beL,0xc65e57ea6f22fb70L,0x268da30c946cea90L,\n        0x136a8a8765681b2aL } },\n    /* 12 << 140 */\n    { { 0xad5e81dc0f9f44d4L,0xf09a69602c46585aL,0xd1649164c447d1b1L,\n        0x3b4b36c8879dc8b1L },\n      { 0x20d4177b3b6b234cL,0x096a25051730d9d0L,0x0611b9b8ef80531dL,\n        0xba904b3b64bb495dL } },\n    /* 13 << 140 */\n    { { 0x1192d9d493a3147aL,0x9f30a5dc9a565545L,0x90b1f9cb6ef07212L,\n        0x299585460d87fc13L },\n      { 0xd3323effc17db9baL,0xcb18548ccb1644a8L,0x18a306d44f49ffbcL,\n        0x28d658f14c2e8684L } },\n    /* 14 << 140 */\n    { { 0x44ba60cda99f8c71L,0x67b7abdb4bf742ffL,0x66310f9c914b3f99L,\n        0xae430a32f412c161L },\n      { 0x1e6776d388ace52fL,0x4bc0fa2452d7067dL,0x03c286aa8f07cd1bL,\n        0x4cb8f38ca985b2c1L } },\n    /* 15 << 140 */\n    { { 0x83ccbe808c3bff36L,0x005a0bd25263e575L,0x460d7dda259bdcd1L,\n        0x4a1c5642fa5cab6bL },\n      { 0x2b7bdbb99fe4fc88L,0x09418e28cc97bbb5L,0xd8274fb4a12321aeL,\n        0xb137007d5c87b64eL } },\n    /* 16 << 140 */\n    { { 0x80531fe1c63c4962L,0x50541e89981fdb25L,0xdc1291a1fd4c2b6bL,\n        0xc0693a17a6df4fcaL },\n      { 0xb2c4604e0117f203L,0x245f19630a99b8d0L,0xaedc20aac6212c44L,\n        0xb1ed4e56520f52a8L } },\n    /* 17 << 140 */\n    { { 0xfe48f575f8547be3L,0x0a7033cda9e45f98L,0x4b45d3a918c50100L,\n        0xb2a6cd6aa61d41daL },\n      { 0x60bbb4f557933c6bL,0xa7538ebd2b0d7ffcL,0x9ea3ab8d8cd626b6L,\n        0x8273a4843601625aL } },\n    /* 18 << 140 */\n    { { 0x888598450168e508L,0x8cbc9bb299a94abdL,0x713ac792fab0a671L,\n        0xa3995b196c9ebffcL },\n      { 0xe711668e1239e152L,0x56892558bbb8dff4L,0x8bfc7dabdbf17963L,\n        0x5b59fe5ab3de1253L } },\n    /* 19 << 140 */\n    { { 0x7e3320eb34a9f7aeL,0xe5e8cf72d751efe4L,0x7ea003bcd9be2f37L,\n        0xc0f551a0b6c08ef7L },\n      { 0x56606268038f6725L,0x1dd38e356d92d3b6L,0x07dfce7cc3cbd686L,\n        0x4e549e04651c5da8L } },\n    /* 20 << 140 */\n    { { 0x4058f93b08b19340L,0xc2fae6f4cac6d89dL,0x4bad8a8c8f159cc7L,\n        0x0ddba4b3cb0b601cL },\n      { 0xda4fc7b51dd95f8cL,0x1d163cd7cea5c255L,0x30707d06274a8c4cL,\n        0x79d9e0082802e9ceL } },\n    /* 21 << 140 */\n    { { 0x02a29ebfe6ddd505L,0x37064e74b50bed1aL,0x3f6bae65a7327d57L,\n        0x3846f5f1f83920bcL },\n      { 0x87c3749160df1b9bL,0x4cfb28952d1da29fL,0x10a478ca4ed1743cL,\n        0x390c60303edd47c6L } },\n    /* 22 << 140 */\n    { { 0x8f3e53128c0a78deL,0xccd02bda1e85df70L,0xd6c75c03a61b6582L,\n        0x0762921cfc0eebd1L },\n      { 0xd34d0823d85010c0L,0xd73aaacb0044cf1fL,0xfb4159bba3b5e78aL,\n        0x2287c7f7e5826f3fL } },\n    /* 23 << 140 */\n    { { 0x4aeaf742580b1a01L,0xf080415d60423b79L,0xe12622cda7dea144L,\n        0x49ea499659d62472L },\n      { 0xb42991ef571f3913L,0x0610f214f5b25a8aL,0x47adc58530b79e8fL,\n        0xf90e3df607a065a2L } },\n    /* 24 << 140 */\n    { { 0x5d0a5deb43e2e034L,0x53fb5a34444024aaL,0xa8628c686b0c9f7fL,\n        0x9c69c29cac563656L },\n      { 0x5a231febbace47b6L,0xbdce02899ea5a2ecL,0x05da1fac9463853eL,\n        0x96812c52509e78aaL } },\n    /* 25 << 140 */\n    { { 0xd3fb577157151692L,0xeb2721f8d98e1c44L,0xc050608732399be1L,\n        0xda5a5511d979d8b8L },\n      { 0x737ed55dc6f56780L,0xe20d30040dc7a7f4L,0x02ce7301f5941a03L,\n        0x91ef5215ed30f83aL } },\n    /* 26 << 140 */\n    { { 0x28727fc14092d85fL,0x72d223c65c49e41aL,0xa7cf30a2ba6a4d81L,\n        0x7c086209b030d87dL },\n      { 0x04844c7dfc588b09L,0x728cd4995874bbb0L,0xcc1281eee84c0495L,\n        0x0769b5baec31958fL } },\n    /* 27 << 140 */\n    { { 0x665c228bf99c2471L,0xf2d8a11b191eb110L,0x4594f494d36d7024L,\n        0x482ded8bcdcb25a1L },\n      { 0xc958a9d8dadd4885L,0x7004477ef1d2b547L,0x0a45f6ef2a0af550L,\n        0x4fc739d62f8d6351L } },\n    /* 28 << 140 */\n    { { 0x75cdaf27786f08a9L,0x8700bb2642c2737fL,0x855a71411c4e2670L,\n        0x810188c115076fefL },\n      { 0xc251d0c9abcd3297L,0xae4c8967f48108ebL,0xbd146de718ceed30L,\n        0xf9d4f07ac986bcedL } },\n    /* 29 << 140 */\n    { { 0x5ad98ed583fa1e08L,0x7780d33ebeabd1fbL,0xe330513c903b1196L,\n        0xba11de9ea47bc8c4L },\n      { 0x684334da02c2d064L,0x7ecf360da48de23bL,0x57a1b4740a9089d8L,\n        0xf28fa439ff36734cL } },\n    /* 30 << 140 */\n    { { 0xf2a482cbea4570b3L,0xee65d68ba5ebcee9L,0x988d0036b9694cd5L,\n        0x53edd0e937885d32L },\n      { 0xe37e3307beb9bc6dL,0xe9abb9079f5c6768L,0x4396ccd551f2160fL,\n        0x2500888c47336da6L } },\n    /* 31 << 140 */\n    { { 0x383f9ed9926fce43L,0x809dd1c704da2930L,0x30f6f5968a4cb227L,\n        0x0d700c7f73a56b38L },\n      { 0x1825ea33ab64a065L,0xaab9b7351338df80L,0x1516100d9b63f57fL,\n        0x2574395a27a6a634L } },\n    /* 32 << 140 */\n    { { 0xb5560fb6700a1acdL,0xe823fd73fd999681L,0xda915d1f6cb4e1baL,\n        0x0d0301186ebe00a3L },\n      { 0x744fb0c989fca8cdL,0x970d01dbf9da0e0bL,0x0ad8c5647931d76fL,\n        0xb15737bff659b96aL } },\n    /* 33 << 140 */\n    { { 0xdc9933e8a8b484e7L,0xb2fdbdf97a26dec7L,0x2349e9a49f1f0136L,\n        0x7860368e70fddddbL },\n      { 0xd93d2c1cf9ad3e18L,0x6d6c5f17689f4e79L,0x7a544d91b24ff1b6L,\n        0x3e12a5ebfe16cd8cL } },\n    /* 34 << 140 */\n    { { 0x543574e9a56b872fL,0xa1ad550cfcf68ea2L,0x689e37d23f560ef7L,\n        0x8c54b9cac9d47a8bL },\n      { 0x46d40a4a088ac342L,0xec450c7c1576c6d0L,0xb589e31c1f9689e9L,\n        0xdacf2602b8781718L } },\n    /* 35 << 140 */\n    { { 0xa89237c6c8cb6b42L,0x1326fc93b96ef381L,0x55d56c6db5f07825L,\n        0xacba2eea7449e22dL },\n      { 0x74e0887a633c3000L,0xcb6cd172d7cbcf71L,0x309e81dec36cf1beL,\n        0x07a18a6d60ae399bL } },\n    /* 36 << 140 */\n    { { 0xb36c26799edce57eL,0x52b892f4df001d41L,0xd884ae5d16a1f2c6L,\n        0x9b329424efcc370aL },\n      { 0x3120daf2bd2e21dfL,0x55298d2d02470a99L,0x0b78af6ca05db32eL,\n        0x5c76a331601f5636L } },\n    /* 37 << 140 */\n    { { 0xaae861fff8a4f29cL,0x70dc9240d68f8d49L,0x960e649f81b1321cL,\n        0x3d2c801b8792e4ceL },\n      { 0xf479f77242521876L,0x0bed93bc416c79b1L,0xa67fbc05263e5bc9L,\n        0x01e8e630521db049L } },\n    /* 38 << 140 */\n    { { 0x76f26738c6f3431eL,0xe609cb02e3267541L,0xb10cff2d818c877cL,\n        0x1f0e75ce786a13cbL },\n      { 0xf4fdca641158544dL,0x5d777e896cb71ed0L,0x3c233737a9aa4755L,\n        0x7b453192e527ab40L } },\n    /* 39 << 140 */\n    { { 0xdb59f68839f05ffeL,0x8f4f4be06d82574eL,0xcce3450cee292d1bL,\n        0xaa448a1261ccd086L },\n      { 0xabce91b3f7914967L,0x4537f09b1908a5edL,0xa812421ef51042e7L,\n        0xfaf5cebcec0b3a34L } },\n    /* 40 << 140 */\n    { { 0x730ffd874ca6b39aL,0x70fb72ed02efd342L,0xeb4735f9d75c8edbL,\n        0xc11f2157c278aa51L },\n      { 0xc459f635bf3bfebfL,0x3a1ff0b46bd9601fL,0xc9d12823c420cb73L,\n        0x3e9af3e23c2915a3L } },\n    /* 41 << 140 */\n    { { 0xe0c82c72b41c3440L,0x175239e5e3039a5fL,0xe1084b8a558795a3L,\n        0x328d0a1dd01e5c60L },\n      { 0x0a495f2ed3788a04L,0x25d8ff1666c11a9fL,0xf5155f059ed692d6L,\n        0x954fa1074f425fe4L } },\n    /* 42 << 140 */\n    { { 0xd16aabf2e98aaa99L,0x90cd8ba096b0f88aL,0x957f4782c154026aL,\n        0x54ee073452af56d2L },\n      { 0xbcf89e5445b4147aL,0x3d102f219a52816cL,0x6808517e39b62e77L,\n        0x92e2542169169ad8L } },\n    /* 43 << 140 */\n    { { 0xd721d871bb608558L,0x60e4ebaef6d4ff9bL,0x0ba1081941f2763eL,\n        0xca2e45be51ee3247L },\n      { 0x66d172ec2bfd7a5fL,0x528a8f2f74d0b12dL,0xe17f1e38dabe70dcL,\n        0x1d5d73169f93983cL } },\n    /* 44 << 140 */\n    { { 0x51b2184adf423e31L,0xcb417291aedb1a10L,0x2054ca93625bcab9L,\n        0x54396860a98998f0L },\n      { 0x4e53f6c4a54ae57eL,0x0ffeb590ee648e9dL,0xfbbdaadc6afaf6bcL,\n        0xf88ae796aa3bfb8aL } },\n    /* 45 << 140 */\n    { { 0x209f1d44d2359ed9L,0xac68dd03f3544ce2L,0xf378da47fd51e569L,\n        0xe1abd8602cc80097L },\n      { 0x23ca18d9343b6e3aL,0x480797e8b40a1baeL,0xd1f0c717533f3e67L,\n        0x4489697006e6cdfcL } },\n    /* 46 << 140 */\n    { { 0x8ca2105552a82e8dL,0xb2caf78578460cdcL,0x4c1b7b62e9037178L,\n        0xefc09d2cdb514b58L },\n      { 0x5f2df9ee9113be5cL,0x2fbda78fb3f9271cL,0xe09a81af8f83fc54L,\n        0x06b138668afb5141L } },\n    /* 47 << 140 */\n    { { 0x38f6480f43e3865dL,0x72dd77a81ddf47d9L,0xf2a8e9714c205ff7L,\n        0x46d449d89d088ad8L },\n      { 0x926619ea185d706fL,0xe47e02ebc7dd7f62L,0xe7f120a78cbc2031L,\n        0xc18bef00998d4ac9L } },\n    /* 48 << 140 */\n    { { 0x18f37a9c6bdf22daL,0xefbc432f90dc82dfL,0xc52cef8e5d703651L,\n        0x82887ba0d99881a5L },\n      { 0x7cec9ddab920ec1dL,0xd0d7e8c3ec3e8d3bL,0x445bc3954ca88747L,\n        0xedeaa2e09fd53535L } },\n    /* 49 << 140 */\n    { { 0x461b1d936cc87475L,0xd92a52e26d2383bdL,0xfabccb59d7903546L,\n        0x6111a7613d14b112L },\n      { 0x0ae584feb3d5f612L,0x5ea69b8d60e828ecL,0x6c07898554087030L,\n        0x649cab04ac4821feL } },\n    /* 50 << 140 */\n    { { 0x25ecedcf8bdce214L,0xb5622f7286af7361L,0x0e1227aa7038b9e2L,\n        0xd0efb273ac20fa77L },\n      { 0x817ff88b79df975bL,0x856bf2861999503eL,0xb4d5351f5038ec46L,\n        0x740a52c5fc42af6eL } },\n    /* 51 << 140 */\n    { { 0x2e38bb152cbb1a3fL,0xc3eb99fe17a83429L,0xca4fcbf1dd66bb74L,\n        0x880784d6cde5e8fcL },\n      { 0xddc84c1cb4e7a0beL,0x8780510dbd15a72fL,0x44bcf1af81ec30e1L,\n        0x141e50a80a61073eL } },\n    /* 52 << 140 */\n    { { 0x0d95571847be87aeL,0x68a61417f76a4372L,0xf57e7e87c607c3d3L,\n        0x043afaf85252f332L },\n      { 0xcc14e1211552a4d2L,0xb6dee692bb4d4ab4L,0xb6ab74c8a03816a4L,\n        0x84001ae46f394a29L } },\n    /* 53 << 140 */\n    { { 0x5bed8344d795fb45L,0x57326e7db79f55a5L,0xc9533ce04accdffcL,\n        0x53473caf3993fa04L },\n      { 0x7906eb93a13df4c8L,0xa73e51f697cbe46fL,0xd1ab3ae10ae4ccf8L,\n        0x256145088a5b3dbcL } },\n    /* 54 << 140 */\n    { { 0x61eff96211a71b27L,0xdf71412b6bb7fa39L,0xb31ba6b82bd7f3efL,\n        0xb0b9c41569180d29L },\n      { 0xeec14552014cdde5L,0x702c624b227b4bbbL,0x2b15e8c2d3e988f3L,\n        0xee3bcc6da4f7fd04L } },\n    /* 55 << 140 */\n    { { 0x9d00822a42ac6c85L,0x2db0cea61df9f2b7L,0xd7cad2ab42de1e58L,\n        0x346ed5262d6fbb61L },\n      { 0xb39629951a2faf09L,0x2fa8a5807c25612eL,0x30ae04da7cf56490L,\n        0x756629080eea3961L } },\n    /* 56 << 140 */\n    { { 0x3609f5c53d080847L,0xcb081d395241d4f6L,0xb4fb381077961a63L,\n        0xc20c59842abb66fcL },\n      { 0x3d40aa7cf902f245L,0x9cb127364e536b1eL,0x5eda24da99b3134fL,\n        0xafbd9c695cd011afL } },\n    /* 57 << 140 */\n    { { 0x9a16e30ac7088c7dL,0x5ab657103207389fL,0x1b09547fe7407a53L,\n        0x2322f9d74fdc6eabL },\n      { 0xc0f2f22d7430de4dL,0x19382696e68ca9a9L,0x17f1eff1918e5868L,\n        0xe3b5b635586f4204L } },\n    /* 58 << 140 */\n    { { 0x146ef9803fbc4341L,0x359f2c805b5eed4eL,0x9f35744e7482e41dL,\n        0x9a9ac3ecf3b224c2L },\n      { 0x9161a6fe91fc50aeL,0x89ccc66bc613fa7cL,0x89268b14c732f15aL,\n        0x7cd6f4e2b467ed03L } },\n    /* 59 << 140 */\n    { { 0xfbf79869ce56b40eL,0xf93e094cc02dde98L,0xefe0c3a8edee2cd7L,\n        0x90f3ffc0b268fd42L },\n      { 0x81a7fd5608241aedL,0x95ab7ad800b1afe8L,0x401270563e310d52L,\n        0xd3ffdeb109d9fc43L } },\n    /* 60 << 140 */\n    { { 0xc8f85c91d11a8594L,0x2e74d25831cf6db8L,0x829c7ca302b5dfd0L,\n        0xe389cfbe69143c86L },\n      { 0xd01b6405941768d8L,0x4510399503bf825dL,0xcc4ee16656cd17e2L,\n        0xbea3c283ba037e79L } },\n    /* 61 << 140 */\n    { { 0x4e1ac06ed9a47520L,0xfbfe18aaaf852404L,0x5615f8e28087648aL,\n        0x7301e47eb9d150d9L },\n      { 0x79f9f9ddb299b977L,0x76697a7ba5b78314L,0x10d674687d7c90e7L,\n        0x7afffe03937210b5L } },\n    /* 62 << 140 */\n    { { 0x5aef3e4b28c22ceeL,0xefb0ecd809fd55aeL,0x4cea71320d2a5d6aL,\n        0x9cfb5fa101db6357L },\n      { 0x395e0b57f36e1ac5L,0x008fa9ad36cafb7dL,0x8f6cdf705308c4dbL,\n        0x51527a3795ed2477L } },\n    /* 63 << 140 */\n    { { 0xba0dee305bd21311L,0x6ed41b22909c90d7L,0xc5f6b7587c8696d3L,\n        0x0db8eaa83ce83a80L },\n      { 0xd297fe37b24b4b6fL,0xfe58afe8522d1f0dL,0x973587368c98dbd9L,\n        0x6bc226ca9454a527L } },\n    /* 64 << 140 */\n    { { 0xa12b384ece53c2d0L,0x779d897d5e4606daL,0xa53e47b073ec12b0L,\n        0x462dbbba5756f1adL },\n      { 0x69fe09f2cafe37b6L,0x273d1ebfecce2e17L,0x8ac1d5383cf607fdL,\n        0x8035f7ff12e10c25L } },\n    /* 0 << 147 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 147 */\n    { { 0x854d34c77e6c5520L,0xc27df9efdcb9ea58L,0x405f2369d686666dL,\n        0x29d1febf0417aa85L },\n      { 0x9846819e93470afeL,0x3e6a9669e2a27f9eL,0x24d008a2e31e6504L,\n        0xdba7cecf9cb7680aL } },\n    /* 2 << 147 */\n    { { 0xecaff541338d6e43L,0x56f7dd734541d5ccL,0xb5d426de96bc88caL,\n        0x48d94f6b9ed3a2c3L },\n      { 0x6354a3bb2ef8279cL,0xd575465b0b1867f2L,0xef99b0ff95225151L,\n        0xf3e19d88f94500d8L } },\n    /* 3 << 147 */\n    { { 0x92a83268e32dd620L,0x913ec99f627849a2L,0xedd8fdfa2c378882L,\n        0xaf96f33eee6f8cfeL },\n      { 0xc06737e5dc3fa8a5L,0x236bb531b0b03a1dL,0x33e59f2989f037b0L,\n        0x13f9b5a7d9a12a53L } },\n    /* 4 << 147 */\n    { { 0x0d0df6ce51efb310L,0xcb5b2eb4958df5beL,0xd6459e2936158e59L,\n        0x82aae2b91466e336L },\n      { 0xfb658a39411aa636L,0x7152ecc5d4c0a933L,0xf10c758a49f026b7L,\n        0xf4837f97cb09311fL } },\n    /* 5 << 147 */\n    { { 0xddfb02c4c753c45fL,0x18ca81b6f9c840feL,0x846fd09ab0f8a3e6L,\n        0xb1162adde7733dbcL },\n      { 0x7070ad20236e3ab6L,0xf88cdaf5b2a56326L,0x05fc8719997cbc7aL,\n        0x442cd4524b665272L } },\n    /* 6 << 147 */\n    { { 0x7807f364b71698f5L,0x6ba418d29f7b605eL,0xfd20b00fa03b2cbbL,\n        0x883eca37da54386fL },\n      { 0xff0be43ff3437f24L,0xe910b432a48bb33cL,0x4963a128329df765L,\n        0xac1dd556be2fe6f7L } },\n    /* 7 << 147 */\n    { { 0x557610f924a0a3fcL,0x38e17bf4e881c3f9L,0x6ba84fafed0dac99L,\n        0xd4a222c359eeb918L },\n      { 0xc79c1dbe13f542b6L,0x1fc65e0de425d457L,0xeffb754f1debb779L,\n        0x638d8fd09e08af60L } },\n    /* 8 << 147 */\n    { { 0x994f523a626332d5L,0x7bc388335561bb44L,0x005ed4b03d845ea2L,\n        0xd39d3ee1c2a1f08aL },\n      { 0x6561fdd3e7676b0dL,0x620e35fffb706017L,0x36ce424ff264f9a8L,\n        0xc4c3419fda2681f7L } },\n    /* 9 << 147 */\n    { { 0xfb6afd2f69beb6e8L,0x3a50b9936d700d03L,0xc840b2ad0c83a14fL,\n        0x573207be54085befL },\n      { 0x5af882e309fe7e5bL,0x957678a43b40a7e1L,0x172d4bdd543056e2L,\n        0x9c1b26b40df13c0aL } },\n    /* 10 << 147 */\n    { { 0x1c30861cf405ff06L,0xebac86bd486e828bL,0xe791a971636933fcL,\n        0x50e7c2be7aeee947L },\n      { 0xc3d4a095fa90d767L,0xae60eb7be670ab7bL,0x17633a64397b056dL,\n        0x93a21f33105012aaL } },\n    /* 11 << 147 */\n    { { 0x663c370babb88643L,0x91df36d722e21599L,0x183ba8358b761671L,\n        0x381eea1d728f3bf1L },\n      { 0xb9b2f1ba39966e6cL,0x7c464a28e7295492L,0x0fd5f70a09b26b7fL,\n        0xa9aba1f9fbe009dfL } },\n    /* 12 << 147 */\n    { { 0x857c1f22369b87adL,0x3c00e5d932fca556L,0x1ad74cab90b06466L,\n        0xa7112386550faaf2L },\n      { 0x7435e1986d9bd5f5L,0x2dcc7e3859c3463fL,0xdc7df748ca7bd4b2L,\n        0x13cd4c089dec2f31L } },\n    /* 13 << 147 */\n    { { 0x0d3b5df8e3237710L,0x0dadb26ecbd2f7b0L,0x9f5966abe4aa082bL,\n        0x666ec8de350e966eL },\n      { 0x1bfd1ed5ee524216L,0xcd93c59b41dab0b6L,0x658a8435d186d6baL,\n        0x1b7d34d2159d1195L } },\n    /* 14 << 147 */\n    { { 0x5936e46022caf46bL,0x6a45dd8f9a96fe4fL,0xf7925434b98f474eL,\n        0x414104120053ef15L },\n      { 0x71cf8d1241de97bfL,0xb8547b61bd80bef4L,0xb47d3970c4db0037L,\n        0xf1bcd328fef20dffL } },\n    /* 15 << 147 */\n    { { 0x31a92e0910caad67L,0x1f5919605531a1e1L,0x3bb852e05f4fc840L,\n        0x63e297ca93a72c6cL },\n      { 0x3c2b0b2e49abad67L,0x6ec405fced3db0d9L,0xdc14a5307fef1d40L,\n        0xccd19846280896fcL } },\n    /* 16 << 147 */\n    { { 0x00f831769bb81648L,0xd69eb485653120d0L,0xd17d75f44ccabc62L,\n        0x34a07f82b749fcb1L },\n      { 0x2c3af787bbfb5554L,0xb06ed4d062e283f8L,0x5722889fa19213a0L,\n        0x162b085edcf3c7b4L } },\n    /* 17 << 147 */\n    { { 0xbcaecb31e0dd3ecaL,0xc6237fbce52f13a5L,0xcc2b6b0327bac297L,\n        0x2ae1cac5b917f54aL },\n      { 0x474807d47845ae4fL,0xfec7dd92ce5972e0L,0xc3bd25411d7915bbL,\n        0x66f85dc4d94907caL } },\n    /* 18 << 147 */\n    { { 0xd981b888bdbcf0caL,0xd75f5da6df279e9fL,0x128bbf247054e934L,\n        0x3c6ff6e581db134bL },\n      { 0x795b7cf4047d26e4L,0xf370f7b85049ec37L,0xc6712d4dced945afL,\n        0xdf30b5ec095642bcL } },\n    /* 19 << 147 */\n    { { 0x9b034c624896246eL,0x5652c016ee90bbd1L,0xeb38636f87fedb73L,\n        0x5e32f8470135a613L },\n      { 0x0703b312cf933c83L,0xd05bb76e1a7f47e6L,0x825e4f0c949c2415L,\n        0x569e56227250d6f8L } },\n    /* 20 << 147 */\n    { { 0xbbe9eb3a6568013eL,0x8dbd203f22f243fcL,0x9dbd7694b342734aL,\n        0x8f6d12f846afa984L },\n      { 0xb98610a2c9eade29L,0xbab4f32347dd0f18L,0x5779737b671c0d46L,\n        0x10b6a7c6d3e0a42aL } },\n    /* 21 << 147 */\n    { { 0xfb19ddf33035b41cL,0xd336343f99c45895L,0x61fe493854c857e5L,\n        0xc4d506beae4e57d5L },\n      { 0x3cd8c8cbbbc33f75L,0x7281f08a9262c77dL,0x083f4ea6f11a2823L,\n        0x8895041e9fba2e33L } },\n    /* 22 << 147 */\n    { { 0xfcdfea499c438edfL,0x7678dcc391edba44L,0xf07b3b87e2ba50f0L,\n        0xc13888ef43948c1bL },\n      { 0xc2135ad41140af42L,0x8e5104f3926ed1a7L,0xf24430cb88f6695fL,\n        0x0ce0637b6d73c120L } },\n    /* 23 << 147 */\n    { { 0xb2db01e6fe631e8fL,0x1c5563d7d7bdd24bL,0x8daea3ba369ad44fL,\n        0x000c81b68187a9f9L },\n      { 0x5f48a951aae1fd9aL,0xe35626c78d5aed8aL,0x209527630498c622L,\n        0x76d17634773aa504L } },\n    /* 24 << 147 */\n    { { 0x36d90ddaeb300f7aL,0x9dcf7dfcedb5e801L,0x645cb26874d5244cL,\n        0xa127ee79348e3aa2L },\n      { 0x488acc53575f1dbbL,0x95037e8580e6161eL,0x57e59283292650d0L,\n        0xabe67d9914938216L } },\n    /* 25 << 147 */\n    { { 0x3c7f944b3f8e1065L,0xed908cb6330e8924L,0x08ee8fd56f530136L,\n        0x2227b7d5d7ffc169L },\n      { 0x4f55c893b5cd6dd5L,0x82225e11a62796e8L,0x5c6cead1cb18e12cL,\n        0x4381ae0c84f5a51aL } },\n    /* 26 << 147 */\n    { { 0x345913d37fafa4c8L,0x3d9180820491aac0L,0x9347871f3e69264cL,\n        0xbea9dd3cb4f4f0cdL },\n      { 0xbda5d0673eadd3e7L,0x0033c1b80573bcd8L,0x255893795da2486cL,\n        0xcb89ee5b86abbee7L } },\n    /* 27 << 147 */\n    { { 0x8fe0a8f322532e5dL,0xb6410ff0727dfc4cL,0x619b9d58226726dbL,\n        0x5ec256697a2b2dc7L },\n      { 0xaf4d2e064c3beb01L,0x852123d07acea556L,0x0e9470faf783487aL,\n        0x75a7ea045664b3ebL } },\n    /* 28 << 147 */\n    { { 0x4ad78f356798e4baL,0x9214e6e5c7d0e091L,0xc420b488b1290403L,\n        0x64049e0afc295749L },\n      { 0x03ef5af13ae9841fL,0xdbe4ca19b0b662a6L,0x46845c5ffa453458L,\n        0xf8dabf1910b66722L } },\n    /* 29 << 147 */\n    { { 0xb650f0aacce2793bL,0x71db851ec5ec47c1L,0x3eb78f3e3b234fa9L,\n        0xb0c60f35fc0106ceL },\n      { 0x05427121774eadbdL,0x25367fafce323863L,0x7541b5c9cd086976L,\n        0x4ff069e2dc507ad1L } },\n    /* 30 << 147 */\n    { { 0x741452568776e667L,0x6e76142cb23c6bb5L,0xdbf307121b3a8a87L,\n        0x60e7363e98450836L },\n      { 0x5741450eb7366d80L,0xe4ee14ca4837dbdfL,0xa765eb9b69d4316fL,\n        0x04548dca8ef43825L } },\n    /* 31 << 147 */\n    { { 0x9c9f4e4c5ae888ebL,0x733abb5156e9ac99L,0xdaad3c20ba6ac029L,\n        0x9b8dd3d32ba3e38eL },\n      { 0xa9bb4c920bc5d11aL,0xf20127a79c5f88a3L,0x4f52b06e161d3cb8L,\n        0x26c1ff096afaf0a6L } },\n    /* 32 << 147 */\n    { { 0x32670d2f7189e71fL,0xc64387485ecf91e7L,0x15758e57db757a21L,\n        0x427d09f8290a9ce5L },\n      { 0x846a308f38384a7aL,0xaac3acb4b0732b99L,0x9e94100917845819L,\n        0x95cba111a7ce5e03L } },\n    /* 33 << 147 */\n    { { 0x6f3d4f7fb00009c4L,0xb8396c278ff28b5fL,0xb1a9ae431c97975dL,\n        0x9d7ba8afe5d9fed5L },\n      { 0x338cf09f34f485b6L,0xbc0ddacc64122516L,0xa450da1205d471feL,\n        0x4c3a6250628dd8c9L } },\n    /* 34 << 147 */\n    { { 0x69c7d103d1295837L,0xa2893e503807eb2fL,0xd6e1e1debdb41491L,\n        0xc630745b5e138235L },\n      { 0xc892109e48661ae1L,0x8d17e7ebea2b2674L,0x00ec0f87c328d6b5L,\n        0x6d858645f079ff9eL } },\n    /* 35 << 147 */\n    { { 0x6cdf243e19115eadL,0x1ce1393e4bac4fcfL,0x2c960ed09c29f25bL,\n        0x59be4d8e9d388a05L },\n      { 0x0d46e06cd0def72bL,0xb923db5de0342748L,0xf7d3aacd936d4a3dL,\n        0x558519cc0b0b099eL } },\n    /* 36 << 147 */\n    { { 0x3ea8ebf8827097efL,0x259353dbd054f55dL,0x84c89abc6d2ed089L,\n        0x5c548b698e096a7cL },\n      { 0xd587f616994b995dL,0x4d1531f6a5845601L,0x792ab31e451fd9f0L,\n        0xc8b57bb265adf6caL } },\n    /* 37 << 147 */\n    { { 0x68440fcb1cd5ad73L,0xb9c860e66144da4fL,0x2ab286aa8462beb8L,\n        0xcc6b8fffef46797fL },\n      { 0xac820da420c8a471L,0x69ae05a177ff7fafL,0xb9163f39bfb5da77L,\n        0xbd03e5902c73ab7aL } },\n    /* 38 << 147 */\n    { { 0x7e862b5eb2940d9eL,0x3c663d864b9af564L,0xd8309031bde3033dL,\n        0x298231b2d42c5bc6L },\n      { 0x42090d2c552ad093L,0xa4799d1cff854695L,0x0a88b5d6d31f0d00L,\n        0xf8b40825a2f26b46L } },\n    /* 39 << 147 */\n    { { 0xec29b1edf1bd7218L,0xd491c53b4b24c86eL,0xd2fe588f3395ea65L,\n        0x6f3764f74456ef15L },\n      { 0xdb43116dcdc34800L,0xcdbcd456c1e33955L,0xefdb554074ab286bL,\n        0x948c7a51d18c5d7cL } },\n    /* 40 << 147 */\n    { { 0xeb81aa377378058eL,0x41c746a104411154L,0xa10c73bcfb828ac7L,\n        0x6439be919d972b29L },\n      { 0x4bf3b4b043a2fbadL,0x39e6dadf82b5e840L,0x4f7164086397bd4cL,\n        0x0f7de5687f1eeccbL } },\n    /* 41 << 147 */\n    { { 0x5865c5a1d2ffbfc1L,0xf74211fa4ccb6451L,0x66368a88c0b32558L,\n        0x5b539dc29ad7812eL },\n      { 0x579483d02f3af6f6L,0x5213207899934eceL,0x50b9650fdcc9e983L,\n        0xca989ec9aee42b8aL } },\n    /* 42 << 147 */\n    { { 0x6a44c829d6f62f99L,0x8f06a3094c2a7c0cL,0x4ea2b3a098a0cb0aL,\n        0x5c547b70beee8364L },\n      { 0x461d40e1682afe11L,0x9e0fc77a7b41c0a8L,0x79e4aefde20d5d36L,\n        0x2916e52032dd9f63L } },\n    /* 43 << 147 */\n    { { 0xf59e52e83f883fafL,0x396f96392b868d35L,0xc902a9df4ca19881L,\n        0x0fc96822db2401a6L },\n      { 0x4123758766f1c68dL,0x10fc6de3fb476c0dL,0xf8b6b579841f5d90L,\n        0x2ba8446cfa24f44aL } },\n    /* 44 << 147 */\n    { { 0xa237b920ef4a9975L,0x60bb60042330435fL,0xd6f4ab5acfb7e7b5L,\n        0xb2ac509783435391L },\n      { 0xf036ee2fb0d1ea67L,0xae779a6a74c56230L,0x59bff8c8ab838ae6L,\n        0xcd83ca999b38e6f0L } },\n    /* 45 << 147 */\n    { { 0xbb27bef5e33deed3L,0xe6356f6f001892a8L,0xbf3be6cc7adfbd3eL,\n        0xaecbc81c33d1ac9dL },\n      { 0xe4feb909e6e861dcL,0x90a247a453f5f801L,0x01c50acb27346e57L,\n        0xce29242e461acc1bL } },\n    /* 46 << 147 */\n    { { 0x04dd214a2f998a91L,0x271ee9b1d4baf27bL,0x7e3027d1e8c26722L,\n        0x21d1645c1820dce5L },\n      { 0x086f242c7501779cL,0xf0061407fa0e8009L,0xf23ce47760187129L,\n        0x05bbdedb0fde9bd0L } },\n    /* 47 << 147 */\n    { { 0x682f483225d98473L,0xf207fe855c658427L,0xb6fdd7ba4166ffa1L,\n        0x0c3140569eed799dL },\n      { 0x0db8048f4107e28fL,0x74ed387141216840L,0x74489f8f56a3c06eL,\n        0x1e1c005b12777134L } },\n    /* 48 << 147 */\n    { { 0xdb332a73f37ec3c3L,0xc65259bddd59eba0L,0x2291709cdb4d3257L,\n        0x9a793b25bd389390L },\n      { 0xf39fe34be43756f0L,0x2f76bdce9afb56c9L,0x9f37867a61208b27L,\n        0xea1d4307089972c3L } },\n    /* 49 << 147 */\n    { { 0x8c5953308bdf623aL,0x5f5accda8441fb7dL,0xfafa941832ddfd95L,\n        0x6ad40c5a0fde9be7L },\n      { 0x43faba89aeca8709L,0xc64a7cf12c248a9dL,0x1662025272637a76L,\n        0xaee1c79122b8d1bbL } },\n    /* 50 << 147 */\n    { { 0xf0f798fd21a843b2L,0x56e4ed4d8d005cb1L,0x355f77801f0d8abeL,\n        0x197b04cf34522326L },\n      { 0x41f9b31ffd42c13fL,0x5ef7feb2b40f933dL,0x27326f425d60bad4L,\n        0x027ecdb28c92cf89L } },\n    /* 51 << 147 */\n    { { 0x04aae4d14e3352feL,0x08414d2f73591b90L,0x5ed6124eb7da7d60L,\n        0xb985b9314d13d4ecL },\n      { 0xa592d3ab96bf36f9L,0x012dbed5bbdf51dfL,0xa57963c0df6c177dL,\n        0x010ec86987ca29cfL } },\n    /* 52 << 147 */\n    { { 0xba1700f6bf926dffL,0x7c9fdbd1f4bf6bc2L,0xdc18dc8f64da11f5L,\n        0xa6074b7ad938ae75L },\n      { 0x14270066e84f44a4L,0x99998d38d27b954eL,0xc1be8ab2b4f38e9aL,\n        0x8bb55bbf15c01016L } },\n    /* 53 << 147 */\n    { { 0xf73472b40ea2ab30L,0xd365a340f73d68ddL,0xc01a716819c2e1ebL,\n        0x32f49e3734061719L },\n      { 0xb73c57f101d8b4d6L,0x03c8423c26b47700L,0x321d0bc8a4d8826aL,\n        0x6004213c4bc0e638L } },\n    /* 54 << 147 */\n    { { 0xf78c64a1c1c06681L,0x16e0a16fef018e50L,0x31cbdf91db42b2b3L,\n        0xf8f4ffcee0d36f58L },\n      { 0xcdcc71cd4cc5e3e0L,0xd55c7cfaa129e3e0L,0xccdb6ba00fb2cbf1L,\n        0x6aba0005c4bce3cbL } },\n    /* 55 << 147 */\n    { { 0x501cdb30d232cfc4L,0x9ddcf12ed58a3cefL,0x02d2cf9c87e09149L,\n        0xdc5d7ec72c976257L },\n      { 0x6447986e0b50d7ddL,0x88fdbaf7807f112aL,0x58c9822ab00ae9f6L,\n        0x6abfb9506d3d27e0L } },\n    /* 56 << 147 */\n    { { 0xd0a744878a429f4fL,0x0649712bdb516609L,0xb826ba57e769b5dfL,\n        0x82335df21fc7aaf2L },\n      { 0x2389f0675c93d995L,0x59ac367a68677be6L,0xa77985ff21d9951bL,\n        0x038956fb85011cceL } },\n    /* 57 << 147 */\n    { { 0x608e48cbbb734e37L,0xc08c0bf22be5b26fL,0x17bbdd3bf9b1a0d9L,\n        0xeac7d89810483319L },\n      { 0xc95c4bafbc1a6deaL,0xfdd0e2bf172aafdbL,0x40373cbc8235c41aL,\n        0x14303f21fb6f41d5L } },\n    /* 58 << 147 */\n    { { 0xba0636210408f237L,0xcad3b09aecd2d1edL,0x4667855a52abb6a2L,\n        0xba9157dcaa8b417bL },\n      { 0xfe7f35074f013efbL,0x1b112c4baa38c4a2L,0xa1406a609ba64345L,\n        0xe53cba336993c80bL } },\n    /* 59 << 147 */\n    { { 0x45466063ded40d23L,0x3d5f1f4d54908e25L,0x9ebefe62403c3c31L,\n        0x274ea0b50672a624L },\n      { 0xff818d99451d1b71L,0x80e826438f79cf79L,0xa165df1373ce37f5L,\n        0xa744ef4ffe3a21fdL } },\n    /* 60 << 147 */\n    { { 0x73f1e7f5cf551396L,0xc616898e868c676bL,0x671c28c78c442c36L,\n        0xcfe5e5585e0a317dL },\n      { 0x1242d8187051f476L,0x56fad2a614f03442L,0x262068bc0a44d0f6L,\n        0xdfa2cd6ece6edf4eL } },\n    /* 61 << 147 */\n    { { 0x0f43813ad15d1517L,0x61214cb2377d44f5L,0xd399aa29c639b35fL,\n        0x42136d7154c51c19L },\n      { 0x9774711b08417221L,0x0a5546b352545a57L,0x80624c411150582dL,\n        0x9ec5c418fbc555bcL } },\n    /* 62 << 147 */\n    { { 0x2c87dcad771849f1L,0xb0c932c501d7bf6fL,0x6aa5cd3e89116eb2L,\n        0xd378c25a51ca7bd3L },\n      { 0xc612a0da9e6e3e31L,0x0417a54db68ad5d0L,0x00451e4a22c6edb8L,\n        0x9fbfe019b42827ceL } },\n    /* 63 << 147 */\n    { { 0x2fa92505ba9384a2L,0x21b8596e64ad69c1L,0x8f4fcc49983b35a6L,\n        0xde09376072754672L },\n      { 0x2f14ccc8f7bffe6dL,0x27566bff5d94263dL,0xb5b4e9c62df3ec30L,\n        0x94f1d7d53e6ea6baL } },\n    /* 64 << 147 */\n    { { 0x97b7851aaaca5e9bL,0x518aa52156713b97L,0x3357e8c7150a61f6L,\n        0x7842e7e2ec2c2b69L },\n      { 0x8dffaf656868a548L,0xd963bd82e068fc81L,0x64da5c8b65917733L,\n        0x927090ff7b247328L } },\n    /* 0 << 154 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 154 */\n    { { 0x214bc9a7d298c241L,0xe3b697ba56807cfdL,0xef1c78024564eadbL,\n        0xdde8cdcfb48149c5L },\n      { 0x946bf0a75a4d2604L,0x27154d7f6c1538afL,0x95cc9230de5b1fccL,\n        0xd88519e966864f82L } },\n    /* 2 << 154 */\n    { { 0xb828dd1a7cb1282cL,0xa08d7626be46973aL,0x6baf8d40e708d6b2L,\n        0x72571fa14daeb3f3L },\n      { 0x85b1732ff22dfd98L,0x87ab01a70087108dL,0xaaaafea85988207aL,\n        0xccc832f869f00755L } },\n    /* 3 << 154 */\n    { { 0x964d950e36ff3bf0L,0x8ad20f6ff0b34638L,0x4d9177b3b5d7585fL,\n        0xcf839760ef3f019fL },\n      { 0x582fc5b38288c545L,0x2f8e4e9b13116bd1L,0xf91e1b2f332120efL,\n        0xcf5687242a17dd23L } },\n    /* 4 << 154 */\n    { { 0x488f1185ca8d9d1aL,0xadf2c77dd987ded2L,0x5f3039f060c46124L,\n        0xe5d70b7571e095f4L },\n      { 0x82d586506260e70fL,0x39d75ea7f750d105L,0x8cf3d0b175bac364L,\n        0xf3a7564d21d01329L } },\n    /* 5 << 154 */\n    { { 0x182f04cd2f52d2a7L,0x4fde149ae2df565aL,0xb80c5eeca79fb2f7L,\n        0xab491d7b22ddc897L },\n      { 0x99d76c18c6312c7fL,0xca0d5f3d6aa41a57L,0x71207325d15363a0L,\n        0xe82aa265beb252c2L } },\n    /* 6 << 154 */\n    { { 0x94ab4700ec3128c2L,0x6c76d8628e383f49L,0xdc36b150c03024ebL,\n        0xfb43947753daac69L },\n      { 0xfc68764a8dc79623L,0x5b86995db440fbb2L,0xd66879bfccc5ee0dL,\n        0x0522894295aa8bd3L } },\n    /* 7 << 154 */\n    { { 0xb51a40a51e6a75c1L,0x24327c760ea7d817L,0x0663018207774597L,\n        0xd6fdbec397fa7164L },\n      { 0x20c99dfb13c90f48L,0xd6ac5273686ef263L,0xc6a50bdcfef64eebL,\n        0xcd87b28186fdfc32L } },\n    /* 8 << 154 */\n    { { 0xb24aa43e3fcd3efcL,0xdd26c034b8088e9aL,0xa5ef4dc9bd3d46eaL,\n        0xa2f99d588a4c6a6fL },\n      { 0xddabd3552f1da46cL,0x72c3f8ce1afacdd1L,0xd90c4eee92d40578L,\n        0xd28bb41fca623b94L } },\n    /* 9 << 154 */\n    { { 0x50fc0711745edc11L,0x9dd9ad7d3dc87558L,0xce6931fbb49d1e64L,\n        0x6c77a0a2c98bd0f9L },\n      { 0x62b9a6296baf7cb1L,0xcf065f91ccf72d22L,0x7203cce979639071L,\n        0x09ae4885f9cb732fL } },\n    /* 10 << 154 */\n    { { 0x5e7c3becee8314f3L,0x1c068aeddbea298fL,0x08d381f17c80acecL,\n        0x03b56be8e330495bL },\n      { 0xaeffb8f29222882dL,0x95ff38f6c4af8bf7L,0x50e32d351fc57d8cL,\n        0x6635be5217b444f0L } },\n    /* 11 << 154 */\n    { { 0x04d15276a5177900L,0x4e1dbb47f6858752L,0x5b475622c615796cL,\n        0xa6fa0387691867bfL },\n      { 0xed7f5d562844c6d0L,0xc633cf9b03a2477dL,0xf6be5c402d3721d6L,\n        0xaf312eb7e9fd68e6L } },\n    /* 12 << 154 */\n    { { 0x242792d2e7417ce1L,0xff42bc71970ee7f5L,0x1ff4dc6d5c67a41eL,\n        0x77709b7b20882a58L },\n      { 0x3554731dbe217f2cL,0x2af2a8cd5bb72177L,0x58eee769591dd059L,\n        0xbb2930c94bba6477L } },\n    /* 13 << 154 */\n    { { 0x863ee0477d930cfcL,0x4c262ad1396fd1f4L,0xf4765bc8039af7e1L,\n        0x2519834b5ba104f6L },\n      { 0x7cd61b4cd105f961L,0xa5415da5d63bca54L,0x778280a088a1f17cL,\n        0xc49689492329512cL } },\n    /* 14 << 154 */\n    { { 0x174a9126cecdaa7aL,0xfc8c7e0e0b13247bL,0x29c110d23484c1c4L,\n        0xf8eb8757831dfc3bL },\n      { 0x022f0212c0067452L,0x3f6f69ee7b9b926cL,0x09032da0ef42daf4L,\n        0x79f00ade83f80de4L } },\n    /* 15 << 154 */\n    { { 0x6210db7181236c97L,0x74f7685b3ee0781fL,0x4df7da7ba3e41372L,\n        0x2aae38b1b1a1553eL },\n      { 0x1688e222f6dd9d1bL,0x576954485b8b6487L,0x478d21274b2edeaaL,\n        0xb2818fa51e85956aL } },\n    /* 16 << 154 */\n    { { 0x1e6adddaf176f2c0L,0x01ca4604e2572658L,0x0a404ded85342ffbL,\n        0x8cf60f96441838d6L },\n      { 0x9bbc691cc9071c4aL,0xfd58874434442803L,0x97101c85809c0d81L,\n        0xa7fb754c8c456f7fL } },\n    /* 17 << 154 */\n    { { 0xc95f3c5cd51805e1L,0xab4ccd39b299dca8L,0x3e03d20b47eaf500L,\n        0xfa3165c1d7b80893L },\n      { 0x005e8b54e160e552L,0xdc4972ba9019d11fL,0x21a6972e0c9a4a7aL,\n        0xa52c258f37840fd7L } },\n    /* 18 << 154 */\n    { { 0xf8559ff4c1e99d81L,0x08e1a7d6a3c617c0L,0xb398fd43248c6ba7L,\n        0x6ffedd91d1283794L },\n      { 0x8a6a59d2d629d208L,0xa9d141d53490530eL,0x42f6fc1838505989L,\n        0x09bf250d479d94eeL } },\n    /* 19 << 154 */\n    { { 0x223ad3b1b3822790L,0x6c5926c093b8971cL,0x609efc7e75f7fa62L,\n        0x45d66a6d1ec2d989L },\n      { 0x4422d663987d2792L,0x4a73caad3eb31d2bL,0xf06c2ac1a32cb9e6L,\n        0xd9445c5f91aeba84L } },\n    /* 20 << 154 */\n    { { 0x6af7a1d5af71013fL,0xe68216e50bedc946L,0xf4cba30bd27370a0L,\n        0x7981afbf870421ccL },\n      { 0x02496a679449f0e1L,0x86cfc4be0a47edaeL,0x3073c936b1feca22L,\n        0xf569461203f8f8fbL } },\n    /* 21 << 154 */\n    { { 0xd063b723901515eaL,0x4c6c77a5749cf038L,0x6361e360ab9e5059L,\n        0x596cf171a76a37c0L },\n      { 0x800f53fa6530ae7aL,0x0f5e631e0792a7a6L,0x5cc29c24efdb81c9L,\n        0xa269e8683f9c40baL } },\n    /* 22 << 154 */\n    { { 0xec14f9e12cb7191eL,0x78ea1bd8e5b08ea6L,0x3c65aa9b46332bb9L,\n        0x84cc22b3bf80ce25L },\n      { 0x0098e9e9d49d5bf1L,0xcd4ec1c619087da4L,0x3c9d07c5aef6e357L,\n        0x839a02689f8f64b8L } },\n    /* 23 << 154 */\n    { { 0xc5e9eb62c6d8607fL,0x759689f56aa995e4L,0x70464669bbb48317L,\n        0x921474bfe402417dL },\n      { 0xcabe135b2a354c8cL,0xd51e52d2812fa4b5L,0xec74109653311fe8L,\n        0x4f774535b864514bL } },\n    /* 24 << 154 */\n    { { 0xbcadd6715bde48f8L,0xc97038732189bc7dL,0x5d45299ec709ee8aL,\n        0xd1287ee2845aaff8L },\n      { 0x7d1f8874db1dbf1fL,0xea46588b990c88d6L,0x60ba649a84368313L,\n        0xd5fdcbce60d543aeL } },\n    /* 25 << 154 */\n    { { 0x90b46d43810d5ab0L,0x6739d8f904d7e5ccL,0x021c1a580d337c33L,\n        0x00a6116268e67c40L },\n      { 0x95ef413b379f0a1fL,0xfe126605e9e2ab95L,0x67578b852f5f199cL,\n        0xf5c003292cb84913L } },\n    /* 26 << 154 */\n    { { 0xf795643037577dd8L,0x83b82af429c5fe88L,0x9c1bea26cdbdc132L,\n        0x589fa0869c04339eL },\n      { 0x033e9538b13799dfL,0x85fa8b21d295d034L,0xdf17f73fbd9ddccaL,\n        0xf32bd122ddb66334L } },\n    /* 27 << 154 */\n    { { 0x55ef88a7858b044cL,0x1f0d69c25aa9e397L,0x55fd9cc340d85559L,\n        0xc774df727785ddb2L },\n      { 0x5dcce9f6d3bd2e1cL,0xeb30da20a85dfed0L,0x5ed7f5bbd3ed09c4L,\n        0x7d42a35c82a9c1bdL } },\n    /* 28 << 154 */\n    { { 0xcf3de9959890272dL,0x75f3432a3e713a10L,0x5e13479fe28227b8L,\n        0xb8561ea9fefacdc8L },\n      { 0xa6a297a08332aafdL,0x9b0d8bb573809b62L,0xd2fa1cfd0c63036fL,\n        0x7a16eb55bd64bda8L } },\n    /* 29 << 154 */\n    { { 0x3f5cf5f678e62ddcL,0x2267c45407fd752bL,0x5e361b6b5e437bbeL,\n        0x95c595018354e075L },\n      { 0xec725f85f2b254d9L,0x844b617d2cb52b4eL,0xed8554f5cf425fb5L,\n        0xab67703e2af9f312L } },\n    /* 30 << 154 */\n    { { 0x4cc34ec13cf48283L,0xb09daa259c8a705eL,0xd1e9d0d05b7d4f84L,\n        0x4df6ef64db38929dL },\n      { 0xe16b0763aa21ba46L,0xc6b1d178a293f8fbL,0x0ff5b602d520aabfL,\n        0x94d671bdc339397aL } },\n    /* 31 << 154 */\n    { { 0x7c7d98cf4f5792faL,0x7c5e0d6711215261L,0x9b19a631a7c5a6d4L,\n        0xc8511a627a45274dL },\n      { 0x0c16621ca5a60d99L,0xf7fbab88cf5e48cbL,0xab1e6ca2f7ddee08L,\n        0x83bd08cee7867f3cL } },\n    /* 32 << 154 */\n    { { 0xf7e48e8a2ac13e27L,0x4494f6df4eb1a9f5L,0xedbf84eb981f0a62L,\n        0x49badc32536438f0L },\n      { 0x50bea541004f7571L,0xbac67d10df1c94eeL,0x253d73a1b727bc31L,\n        0xb3d01cf230686e28L } },\n    /* 33 << 154 */\n    { { 0x51b77b1b55fd0b8bL,0xa099d183feec3173L,0x202b1fb7670e72b7L,\n        0xadc88b33a8e1635fL },\n      { 0x34e8216af989d905L,0xc2e68d2029b58d01L,0x11f81c926fe55a93L,\n        0x15f1462a8f296f40L } },\n    /* 34 << 154 */\n    { { 0x1915d375ea3d62f2L,0xa17765a301c8977dL,0x7559710ae47b26f6L,\n        0xe0bd29c8535077a5L },\n      { 0x615f976d08d84858L,0x370dfe8569ced5c1L,0xbbc7503ca734fa56L,\n        0xfbb9f1ec91ac4574L } },\n    /* 35 << 154 */\n    { { 0x95d7ec53060dd7efL,0xeef2dacd6e657979L,0x54511af3e2a08235L,\n        0x1e324aa41f4aea3dL },\n      { 0x550e7e71e6e67671L,0xbccd5190bf52faf7L,0xf880d316223cc62aL,\n        0x0d402c7e2b32eb5dL } },\n    /* 36 << 154 */\n    { { 0xa40bc039306a5a3bL,0x4e0a41fd96783a1bL,0xa1e8d39a0253cdd4L,\n        0x6480be26c7388638L },\n      { 0xee365e1d2285f382L,0x188d8d8fec0b5c36L,0x34ef1a481f0f4d82L,\n        0x1a8f43e1a487d29aL } },\n    /* 37 << 154 */\n    { { 0x8168226d77aefb3aL,0xf69a751e1e72c253L,0x8e04359ae9594df1L,\n        0x475ffd7dd14c0467L },\n      { 0xb5a2c2b13844e95cL,0x85caf647dd12ef94L,0x1ecd2a9ff1063d00L,\n        0x1dd2e22923843311L } },\n    /* 38 << 154 */\n    { { 0x38f0e09d73d17244L,0x3ede77468fc653f1L,0xae4459f5dc20e21cL,\n        0x00db2ffa6a8599eaL },\n      { 0x11682c3930cfd905L,0x4934d074a5c112a6L,0xbdf063c5568bfe95L,\n        0x779a440a016c441aL } },\n    /* 39 << 154 */\n    { { 0x0c23f21897d6fbdcL,0xd3a5cd87e0776aacL,0xcee37f72d712e8dbL,\n        0xfb28c70d26f74e8dL },\n      { 0xffe0c728b61301a0L,0xa6282168d3724354L,0x7ff4cb00768ffedcL,\n        0xc51b308803b02de9L } },\n    /* 40 << 154 */\n    { { 0xa5a8147c3902dda5L,0x35d2f706fe6973b4L,0x5ac2efcfc257457eL,\n        0x933f48d48700611bL },\n      { 0xc365af884912beb2L,0x7f5a4de6162edf94L,0xc646ba7c0c32f34bL,\n        0x632c6af3b2091074L } },\n    /* 41 << 154 */\n    { { 0x58d4f2e3753e43a9L,0x70e1d21724d4e23fL,0xb24bf729afede6a6L,\n        0x7f4a94d8710c8b60L },\n      { 0xaad90a968d4faa6aL,0xd9ed0b32b066b690L,0x52fcd37b78b6dbfdL,\n        0x0b64615e8bd2b431L } },\n    /* 42 << 154 */\n    { { 0x228e2048cfb9fad5L,0xbeaa386d240b76bdL,0x2d6681c890dad7bcL,\n        0x3e553fc306d38f5eL },\n      { 0xf27cdb9b9d5f9750L,0x3e85c52ad28c5b0eL,0x190795af5247c39bL,\n        0x547831ebbddd6828L } },\n    /* 43 << 154 */\n    { { 0xf327a2274a82f424L,0x36919c787e47f89dL,0xe478391943c7392cL,\n        0xf101b9aa2316fefeL },\n      { 0xbcdc9e9c1c5009d2L,0xfb55ea139cd18345L,0xf5b5e231a3ce77c7L,\n        0xde6b4527d2f2cb3dL } },\n    /* 44 << 154 */\n    { { 0x10f6a3339bb26f5fL,0x1e85db8e044d85b6L,0xc3697a0894197e54L,\n        0x65e18cc0a7cb4ea8L },\n      { 0xa38c4f50a471fe6eL,0xf031747a2f13439cL,0x53c4a6bac007318bL,\n        0xa8da3ee51deccb3dL } },\n    /* 45 << 154 */\n    { { 0x0555b31c558216b1L,0x90c7810c2f79e6c2L,0x9b669f4dfe8eed3cL,\n        0x70398ec8e0fac126L },\n      { 0xa96a449ef701b235L,0x0ceecdb3eb94f395L,0x285fc368d0cb7431L,\n        0x0d37bb5216a18c64L } },\n    /* 46 << 154 */\n    { { 0x05110d38b880d2ddL,0xa60f177b65930d57L,0x7da34a67f36235f5L,\n        0x47f5e17c183816b9L },\n      { 0xc7664b57db394af4L,0x39ba215d7036f789L,0x46d2ca0e2f27b472L,\n        0xc42647eef73a84b7L } },\n    /* 47 << 154 */\n    { { 0x44bc754564488f1dL,0xaa922708f4cf85d5L,0x721a01d553e4df63L,\n        0x649c0c515db46cedL },\n      { 0x6bf0d64e3cffcb6cL,0xe3bf93fe50f71d96L,0x75044558bcc194a0L,\n        0x16ae33726afdc554L } },\n    /* 48 << 154 */\n    { { 0xbfc01adf5ca48f3fL,0x64352f06e22a9b84L,0xcee54da1c1099e4aL,\n        0xbbda54e8fa1b89c0L },\n      { 0x166a3df56f6e55fbL,0x1ca44a2420176f88L,0x936afd88dfb7b5ffL,\n        0xe34c24378611d4a0L } },\n    /* 49 << 154 */\n    { { 0x7effbb7586142103L,0x6704ba1b1f34fc4dL,0x7c2a468f10c1b122L,\n        0x36b3a6108c6aace9L },\n      { 0xabfcc0a775a0d050L,0x066f91973ce33e32L,0xce905ef429fe09beL,\n        0x89ee25baa8376351L } },\n    /* 50 << 154 */\n    { { 0x2a3ede22fd29dc76L,0x7fd32ed936f17260L,0x0cadcf68284b4126L,\n        0x63422f08a7951fc8L },\n      { 0x562b24f40807e199L,0xfe9ce5d122ad4490L,0xc2f51b100db2b1b4L,\n        0xeb3613ffe4541d0dL } },\n    /* 51 << 154 */\n    { { 0xbd2c4a052680813bL,0x527aa55d561b08d6L,0xa9f8a40ea7205558L,\n        0xe3eea56f243d0becL },\n      { 0x7b853817a0ff58b3L,0xb67d3f651a69e627L,0x0b76bbb9a869b5d6L,\n        0xa3afeb82546723edL } },\n    /* 52 << 154 */\n    { { 0x5f24416d3e554892L,0x8413b53d430e2a45L,0x99c56aee9032a2a0L,\n        0x09432bf6eec367b1L },\n      { 0x552850c6daf0ecc1L,0x49ebce555bc92048L,0xdfb66ba654811307L,\n        0x1b84f7976f298597L } },\n    /* 53 << 154 */\n    { { 0x795904818d1d7a0dL,0xd9fabe033a6fa556L,0xa40f9c59ba9e5d35L,\n        0xcb1771c1f6247577L },\n      { 0x542a47cae9a6312bL,0xa34b3560552dd8c5L,0xfdf94de00d794716L,\n        0xd46124a99c623094L } },\n    /* 54 << 154 */\n    { { 0x56b7435d68afe8b4L,0x27f205406c0d8ea1L,0x12b77e1473186898L,\n        0xdbc3dd467479490fL },\n      { 0x951a9842c03b0c05L,0x8b1b3bb37921bc96L,0xa573b3462b202e0aL,\n        0x77e4665d47254d56L } },\n    /* 55 << 154 */\n    { { 0x08b70dfcd23e3984L,0xab86e8bcebd14236L,0xaa3e07f857114ba7L,\n        0x5ac71689ab0ef4f2L },\n      { 0x88fca3840139d9afL,0x72733f8876644af0L,0xf122f72a65d74f4aL,\n        0x13931577a5626c7aL } },\n    /* 56 << 154 */\n    { { 0xd5b5d9eb70f8d5a4L,0x375adde7d7bbb228L,0x31e88b860c1c0b32L,\n        0xd1f568c4173edbaaL },\n      { 0x1592fc835459df02L,0x2beac0fb0fcd9a7eL,0xb0a6fdb81b473b0aL,\n        0xe3224c6f0fe8fc48L } },\n    /* 57 << 154 */\n    { { 0x680bd00ee87edf5bL,0x30385f0220e77cf5L,0xe9ab98c04d42d1b2L,\n        0x72d191d2d3816d77L },\n      { 0x1564daca0917d9e5L,0x394eab591f8fed7fL,0xa209aa8d7fbb3896L,\n        0x5564f3b9be6ac98eL } },\n    /* 58 << 154 */\n    { { 0xead21d05d73654efL,0x68d1a9c413d78d74L,0x61e017086d4973a0L,\n        0x83da350046e6d32aL },\n      { 0x6a3dfca468ae0118L,0xa1b9a4c9d02da069L,0x0b2ff9c7ebab8302L,\n        0x98af07c3944ba436L } },\n    /* 59 << 154 */\n    { { 0x85997326995f0f9fL,0x467fade071b58bc6L,0x47e4495abd625a2bL,\n        0xfdd2d01d33c3b8cdL },\n      { 0x2c38ae28c693f9faL,0x48622329348f7999L,0x97bf738e2161f583L,\n        0x15ee2fa7565e8cc9L } },\n    /* 60 << 154 */\n    { { 0xa1a5c8455777e189L,0xcc10bee0456f2829L,0x8ad95c56da762bd5L,\n        0x152e2214e9d91da8L },\n      { 0x975b0e727cb23c74L,0xfd5d7670a90c66dfL,0xb5b5b8ad225ffc53L,\n        0xab6dff73faded2aeL } },\n    /* 61 << 154 */\n    { { 0xebd567816f4cbe9dL,0x0ed8b2496a574bd7L,0x41c246fe81a881faL,\n        0x91564805c3db9c70L },\n      { 0xd7c12b085b862809L,0x1facd1f155858d7bL,0x7693747caf09e92aL,\n        0x3b69dcba189a425fL } },\n    /* 62 << 154 */\n    { { 0x0be28e9f967365efL,0x57300eb2e801f5c9L,0x93b8ac6ad583352fL,\n        0xa2cf1f89cd05b2b7L },\n      { 0x7c0c9b744dcc40ccL,0xfee38c45ada523fbL,0xb49a4dec1099cc4dL,\n        0x325c377f69f069c6L } },\n    /* 63 << 154 */\n    { { 0xe12458ce476cc9ffL,0x580e0b6cc6d4cb63L,0xd561c8b79072289bL,\n        0x0377f264a619e6daL },\n      { 0x2668536288e591a5L,0xa453a7bd7523ca2bL,0x8a9536d2c1df4533L,\n        0xc8e50f2fbe972f79L } },\n    /* 64 << 154 */\n    { { 0xd433e50f6d3549cfL,0x6f33696ffacd665eL,0x695bfdacce11fcb4L,\n        0x810ee252af7c9860L },\n      { 0x65450fe17159bb2cL,0xf7dfbebe758b357bL,0x2b057e74d69fea72L,\n        0xd485717a92731745L } },\n    /* 0 << 161 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 161 */\n    { { 0x896c42e8ee36860cL,0xdaf04dfd4113c22dL,0x1adbb7b744104213L,\n        0xe5fd5fa11fd394eaL },\n      { 0x68235d941a4e0551L,0x6772cfbe18d10151L,0x276071e309984523L,\n        0xe4e879de5a56ba98L } },\n    /* 2 << 161 */\n    { { 0xaaafafb0285b9491L,0x01a0be881e4c705eL,0xff1d4f5d2ad9caabL,\n        0x6e349a4ac37a233fL },\n      { 0xcf1c12464a1c6a16L,0xd99e6b6629383260L,0xea3d43665f6d5471L,\n        0x36974d04ff8cc89bL } },\n    /* 3 << 161 */\n    { { 0xc26c49a1cfe89d80L,0xb42c026dda9c8371L,0xca6c013adad066d2L,\n        0xfb8f722856a4f3eeL },\n      { 0x08b579ecd850935bL,0x34c1a74cd631e1b3L,0xcb5fe596ac198534L,\n        0x39ff21f6e1f24f25L } },\n    /* 4 << 161 */\n    { { 0x27f29e148f929057L,0x7a64ae06c0c853dfL,0x256cd18358e9c5ceL,\n        0x9d9cce82ded092a5L },\n      { 0xcc6e59796e93b7c7L,0xe1e4709231bb9e27L,0xb70b3083aa9e29a0L,\n        0xbf181a753785e644L } },\n    /* 5 << 161 */\n    { { 0xf53f2c658ead09f7L,0x1335e1d59780d14dL,0x69cc20e0cd1b66bcL,\n        0x9b670a37bbe0bfc8L },\n      { 0xce53dc8128efbeedL,0x0c74e77c8326a6e5L,0x3604e0d2b88e9a63L,\n        0xbab38fca13dc2248L } },\n    /* 6 << 161 */\n    { { 0x8ed6e8c85c0a3f1eL,0xbcad24927c87c37fL,0xfdfb62bb9ee3b78dL,\n        0xeba8e477cbceba46L },\n      { 0x37d38cb0eeaede4bL,0x0bc498e87976deb6L,0xb2944c046b6147fbL,\n        0x8b123f35f71f9609L } },\n    /* 7 << 161 */\n    { { 0xa155dcc7de79dc24L,0xf1168a32558f69cdL,0xbac215950d1850dfL,\n        0x15c8295bb204c848L },\n      { 0xf661aa367d8184ffL,0xc396228e30447bdbL,0x11cd5143bde4a59eL,\n        0xe3a26e3b6beab5e6L } },\n    /* 8 << 161 */\n    { { 0xd3b3a13f1402b9d0L,0x573441c32c7bc863L,0x4b301ec4578c3e6eL,\n        0xc26fc9c40adaf57eL },\n      { 0x96e71bfd7493cea3L,0xd05d4b3f1af81456L,0xdaca2a8a6a8c608fL,\n        0x53ef07f60725b276L } },\n    /* 9 << 161 */\n    { { 0x07a5fbd27824fc56L,0x3467521813289077L,0x5bf69fd5e0c48349L,\n        0xa613ddd3b6aa7875L },\n      { 0x7f78c19c5450d866L,0x46f4409c8f84a481L,0x9f1d192890fce239L,\n        0x016c4168b2ce44b9L } },\n    /* 10 << 161 */\n    { { 0xbae023f0c7435978L,0xb152c88820e30e19L,0x9c241645e3fa6fafL,\n        0x735d95c184823e60L },\n      { 0x0319757303955317L,0x0b4b02a9f03b4995L,0x076bf55970274600L,\n        0x32c5cc53aaf57508L } },\n    /* 11 << 161 */\n    { { 0xe8af6d1f60624129L,0xb7bc5d649a5e2b5eL,0x3814b0485f082d72L,\n        0x76f267f2ce19677aL },\n      { 0x626c630fb36eed93L,0x55230cd73bf56803L,0x78837949ce2736a0L,\n        0x0d792d60aa6c55f1L } },\n    /* 12 << 161 */\n    { { 0x0318dbfdd5c7c5d2L,0xb38f8da7072b342dL,0x3569bddc7b8de38aL,\n        0xf25b5887a1c94842L },\n      { 0xb2d5b2842946ad60L,0x854f29ade9d1707eL,0xaa5159dc2c6a4509L,\n        0x899f94c057189837L } },\n    /* 13 << 161 */\n    { { 0xcf6adc51f4a55b03L,0x261762de35e3b2d5L,0x4cc4301204827b51L,\n        0xcd22a113c6021442L },\n      { 0xce2fd61a247c9569L,0x59a50973d152becaL,0x6c835a1163a716d4L,\n        0xc26455ed187dedcfL } },\n    /* 14 << 161 */\n    { { 0x27f536e049ce89e7L,0x18908539cc890cb5L,0x308909abd83c2aa1L,\n        0xecd3142b1ab73bd3L },\n      { 0x6a85bf59b3f5ab84L,0x3c320a68f2bea4c6L,0xad8dc5386da4541fL,\n        0xeaf34eb0b7c41186L } },\n    /* 15 << 161 */\n    { { 0x1c780129977c97c4L,0x5ff9beebc57eb9faL,0xa24d0524c822c478L,\n        0xfd8eec2a461cd415L },\n      { 0xfbde194ef027458cL,0xb4ff53191d1be115L,0x63f874d94866d6f4L,\n        0x35c75015b21ad0c9L } },\n    /* 16 << 161 */\n    { { 0xa6b5c9d646ac49d2L,0x42c77c0b83137aa9L,0x24d000fc68225a38L,\n        0x0f63cfc82fe1e907L },\n      { 0x22d1b01bc6441f95L,0x7d38f719ec8e448fL,0x9b33fa5f787fb1baL,\n        0x94dcfda1190158dfL } },\n    /* 17 << 161 */\n    { { 0xc47cb3395f6d4a09L,0x6b4f355cee52b826L,0x3d100f5df51b930aL,\n        0xf4512fac9f668f69L },\n      { 0x546781d5206c4c74L,0xd021d4d4cb4d2e48L,0x494a54c2ca085c2dL,\n        0xf1dbaca4520850a8L } },\n    /* 18 << 161 */\n    { { 0x63c79326490a1acaL,0xcb64dd9c41526b02L,0xbb772591a2979258L,\n        0x3f58297048d97846L },\n      { 0xd66b70d17c213ba7L,0xc28febb5e8a0ced4L,0x6b911831c10338c1L,\n        0x0d54e389bf0126f3L } },\n    /* 19 << 161 */\n    { { 0x7048d4604af206eeL,0x786c88f677e97cb9L,0xd4375ae1ac64802eL,\n        0x469bcfe1d53ec11cL },\n      { 0xfc9b340d47062230L,0xe743bb57c5b4a3acL,0xfe00b4aa59ef45acL,\n        0x29a4ef2359edf188L } },\n    /* 20 << 161 */\n    { { 0x40242efeb483689bL,0x2575d3f6513ac262L,0xf30037c80ca6db72L,\n        0xc9fcce8298864be2L },\n      { 0x84a112ff0149362dL,0x95e575821c4ae971L,0x1fa4b1a8945cf86cL,\n        0x4525a7340b024a2fL } },\n    /* 21 << 161 */\n    { { 0xe76c8b628f338360L,0x483ff59328edf32bL,0x67e8e90a298b1aecL,\n        0x9caab338736d9a21L },\n      { 0x5c09d2fd66892709L,0x2496b4dcb55a1d41L,0x93f5fb1ae24a4394L,\n        0x08c750496fa8f6c1L } },\n    /* 22 << 161 */\n    { { 0xcaead1c2c905d85fL,0xe9d7f7900733ae57L,0x24c9a65cf07cdd94L,\n        0x7389359ca4b55931L },\n      { 0xf58709b7367e45f7L,0x1f203067cb7e7adcL,0x82444bffc7b72818L,\n        0x07303b35baac8033L } },\n    /* 23 << 161 */\n    { { 0x1e1ee4e4d13b7ea1L,0xe6489b24e0e74180L,0xa5f2c6107e70ef70L,\n        0xa1655412bdd10894L },\n      { 0x555ebefb7af4194eL,0x533c1c3c8e89bd9cL,0x735b9b5789895856L,\n        0x15fb3cd2567f5c15L } },\n    /* 24 << 161 */\n    { { 0x057fed45526f09fdL,0xe8a4f10c8128240aL,0x9332efc4ff2bfd8dL,\n        0x214e77a0bd35aa31L },\n      { 0x32896d7314faa40eL,0x767867ec01e5f186L,0xc9adf8f117a1813eL,\n        0xcb6cda7854741795L } },\n    /* 25 << 161 */\n    { { 0xb7521b6d349d51aaL,0xf56b5a9ee3c7b8e9L,0xc6f1e5c932a096dfL,\n        0x083667c4a3635024L },\n      { 0x365ea13518087f2fL,0xf1b8eaacd136e45dL,0xc8a0e48473aec989L,\n        0xd75a324b142c9259L } },\n    /* 26 << 161 */\n    { { 0xb7b4d00101dae185L,0x45434e0b9b7a94bcL,0xf54339affbd8cb0bL,\n        0xdcc4569ee98ef49eL },\n      { 0x7789318a09a51299L,0x81b4d206b2b025d8L,0xf64aa418fae85792L,\n        0x3e50258facd7baf7L } },\n    /* 27 << 161 */\n    { { 0xdce84cdb2996864bL,0xa2e670891f485fa4L,0xb28b2bb6534c6a5aL,\n        0x31a7ec6bc94b9d39L },\n      { 0x1d217766d6bc20daL,0x4acdb5ec86761190L,0x6872632873701063L,\n        0x4d24ee7c2128c29bL } },\n    /* 28 << 161 */\n    { { 0xc072ebd3a19fd868L,0x612e481cdb8ddd3bL,0xb4e1d7541a64d852L,\n        0x00ef95acc4c6c4abL },\n      { 0x1536d2edaa0a6c46L,0x6129408643774790L,0x54af25e8343fda10L,\n        0x9ff9d98dfd25d6f2L } },\n    /* 29 << 161 */\n    { { 0x0746af7c468b8835L,0x977a31cb730ecea7L,0xa5096b80c2cf4a81L,\n        0xaa9868336458c37aL },\n      { 0x6af29bf3a6bd9d34L,0x6a62fe9b33c5d854L,0x50e6c304b7133b5eL,\n        0x04b601597d6e6848L } },\n    /* 30 << 161 */\n    { { 0x4cd296df5579bea4L,0x10e35ac85ceedaf1L,0x04c4c5fde3bcc5b1L,\n        0x95f9ee8a89412cf9L },\n      { 0x2c9459ee82b6eb0fL,0x2e84576595c2aaddL,0x774a84aed327fcfeL,\n        0xd8c937220368d476L } },\n    /* 31 << 161 */\n    { { 0x0dbd5748f83e8a3bL,0xa579aa968d2495f3L,0x535996a0ae496e9bL,\n        0x07afbfe9b7f9bcc2L },\n      { 0x3ac1dc6d5b7bd293L,0x3b592cff7022323dL,0xba0deb989c0a3e76L,\n        0x18e78e9f4b197acbL } },\n    /* 32 << 161 */\n    { { 0x211cde10296c36efL,0x7ee8967282c4da77L,0xb617d270a57836daL,\n        0xf0cd9c319cb7560bL },\n      { 0x01fdcbf7e455fe90L,0x3fb53cbb7e7334f3L,0x781e2ea44e7de4ecL,\n        0x8adab3ad0b384fd0L } },\n    /* 33 << 161 */\n    { { 0x129eee2f53d64829L,0x7a471e17a261492bL,0xe4f9adb9e4cb4a2cL,\n        0x3d359f6f97ba2c2dL },\n      { 0x346c67860aacd697L,0x92b444c375c2f8a8L,0xc79fa117d85df44eL,\n        0x56782372398ddf31L } },\n    /* 34 << 161 */\n    { { 0x60e690f2bbbab3b8L,0x4851f8ae8b04816bL,0xc72046ab9c92e4d2L,\n        0x518c74a17cf3136bL },\n      { 0xff4eb50af9877d4cL,0x14578d90a919cabbL,0x8218f8c4ac5eb2b6L,\n        0xa3ccc547542016e4L } },\n    /* 35 << 161 */\n    { { 0x025bf48e327f8349L,0xf3e97346f43cb641L,0xdc2bafdf500f1085L,\n        0x571678762f063055L },\n      { 0x5bd914b9411925a6L,0x7c078d48a1123de5L,0xee6bf835182b165dL,\n        0xb11b5e5bba519727L } },\n    /* 36 << 161 */\n    { { 0xe33ea76c1eea7b85L,0x2352b46192d4f85eL,0xf101d334afe115bbL,\n        0xfabc1294889175a3L },\n      { 0x7f6bcdc05233f925L,0xe0a802dbe77fec55L,0xbdb47b758069b659L,\n        0x1c5e12def98fbd74L } },\n    /* 37 << 161 */\n    { { 0x869c58c64b8457eeL,0xa5360f694f7ea9f7L,0xe576c09ff460b38fL,\n        0x6b70d54822b7fb36L },\n      { 0x3fd237f13bfae315L,0x33797852cbdff369L,0x97df25f525b516f9L,\n        0x46f388f2ba38ad2dL } },\n    /* 38 << 161 */\n    { { 0x656c465889d8ddbbL,0x8830b26e70f38ee8L,0x4320fd5cde1212b0L,\n        0xc34f30cfe4a2edb2L },\n      { 0xabb131a356ab64b8L,0x7f77f0ccd99c5d26L,0x66856a37bf981d94L,\n        0x19e76d09738bd76eL } },\n    /* 39 << 161 */\n    { { 0xe76c8ac396238f39L,0xc0a482bea830b366L,0xb7b8eaff0b4eb499L,\n        0x8ecd83bc4bfb4865L },\n      { 0x971b2cb7a2f3776fL,0xb42176a4f4b88adfL,0xb9617df5be1fa446L,\n        0x8b32d508cd031bd2L } },\n    /* 40 << 161 */\n    { { 0x1c6bd47d53b618c0L,0xc424f46c6a227923L,0x7303ffdedd92d964L,\n        0xe971287871b5abf2L },\n      { 0x8f48a632f815561dL,0x85f48ff5d3c055d1L,0x222a14277525684fL,\n        0xd0d841a067360cc3L } },\n    /* 41 << 161 */\n    { { 0x4245a9260b9267c6L,0xc78913f1cf07f863L,0xaa844c8e4d0d9e24L,\n        0xa42ad5223d5f9017L },\n      { 0xbd371749a2c989d5L,0x928292dfe1f5e78eL,0x493b383e0a1ea6daL,\n        0x5136fd8d13aee529L } },\n    /* 42 << 161 */\n    { { 0x860c44b1f2c34a99L,0x3b00aca4bf5855acL,0xabf6aaa0faaf37beL,\n        0x65f436822a53ec08L },\n      { 0x1d9a5801a11b12e1L,0x78a7ab2ce20ed475L,0x0de1067e9a41e0d5L,\n        0x30473f5f305023eaL } },\n    /* 43 << 161 */\n    { { 0xdd3ae09d169c7d97L,0x5cd5baa4cfaef9cdL,0x5cd7440b65a44803L,\n        0xdc13966a47f364deL },\n      { 0x077b2be82b8357c1L,0x0cb1b4c5e9d57c2aL,0x7a4ceb3205ff363eL,\n        0xf310fa4dca35a9efL } },\n    /* 44 << 161 */\n    { { 0xdbb7b352f97f68c6L,0x0c773b500b02cf58L,0xea2e48213c1f96d9L,\n        0xffb357b0eee01815L },\n      { 0xb9c924cde0f28039L,0x0b36c95a46a3fbe4L,0x1faaaea45e46db6cL,\n        0xcae575c31928aaffL } },\n    /* 45 << 161 */\n    { { 0x7f671302a70dab86L,0xfcbd12a971c58cfcL,0xcbef9acfbee0cb92L,\n        0x573da0b9f8c1b583L },\n      { 0x4752fcfe0d41d550L,0xe7eec0e32155cffeL,0x0fc39fcb545ae248L,\n        0x522cb8d18065f44eL } },\n    /* 46 << 161 */\n    { { 0x263c962a70cbb96cL,0xe034362abcd124a9L,0xf120db283c2ae58dL,\n        0xb9a38d49fef6d507L },\n      { 0xb1fd2a821ff140fdL,0xbd162f3020aee7e0L,0x4e17a5d4cb251949L,\n        0x2aebcb834f7e1c3dL } },\n    /* 47 << 161 */\n    { { 0x608eb25f937b0527L,0xf42e1e47eb7d9997L,0xeba699c4b8a53a29L,\n        0x1f921c71e091b536L },\n      { 0xcce29e7b5b26bbd5L,0x7a8ef5ed3b61a680L,0xe5ef8043ba1f1c7eL,\n        0x16ea821718158ddaL } },\n    /* 48 << 161 */\n    { { 0x01778a2b599ff0f9L,0x68a923d78104fc6bL,0x5bfa44dfda694ff3L,\n        0x4f7199dbf7667f12L },\n      { 0xc06d8ff6e46f2a79L,0x08b5deade9f8131dL,0x02519a59abb4ce7cL,\n        0xc4f710bcb42aec3eL } },\n    /* 49 << 161 */\n    { { 0x3d77b05778bde41aL,0x6474bf80b4186b5aL,0x048b3f6788c65741L,\n        0xc64519de03c7c154L },\n      { 0xdf0738460edfcc4fL,0x319aa73748f1aa6bL,0x8b9f8a02ca909f77L,\n        0x902581397580bfefL } },\n    /* 50 << 161 */\n    { { 0xd8bfd3cac0c22719L,0xc60209e4c9ca151eL,0x7a744ab5d9a1a69cL,\n        0x6de5048b14937f8fL },\n      { 0x171938d8e115ac04L,0x7df709401c6b16d2L,0xa6aeb6637f8e94e7L,\n        0xc130388e2a2cf094L } },\n    /* 51 << 161 */\n    { { 0x1850be8477f54e6eL,0x9f258a7265d60fe5L,0xff7ff0c06c9146d6L,\n        0x039aaf90e63a830bL },\n      { 0x38f27a739460342fL,0x4703148c3f795f8aL,0x1bb5467b9681a97eL,\n        0x00931ba5ecaeb594L } },\n    /* 52 << 161 */\n    { { 0xcdb6719d786f337cL,0xd9c01cd2e704397dL,0x0f4a3f20555c2fefL,\n        0x004525097c0af223L },\n      { 0x54a5804784db8e76L,0x3bacf1aa93c8aa06L,0x11ca957cf7919422L,\n        0x5064105378cdaa40L } },\n    /* 53 << 161 */\n    { { 0x7a3038749f7144aeL,0x170c963f43d4acfdL,0x5e14814958ddd3efL,\n        0xa7bde5829e72dba8L },\n      { 0x0769da8b6fa68750L,0xfa64e532572e0249L,0xfcaadf9d2619ad31L,\n        0x87882daaa7b349cdL } },\n    /* 54 << 161 */\n    { { 0x9f6eb7316c67a775L,0xcb10471aefc5d0b1L,0xb433750ce1b806b2L,\n        0x19c5714d57b1ae7eL },\n      { 0xc0dc8b7bed03fd3fL,0xdd03344f31bc194eL,0xa66c52a78c6320b5L,\n        0x8bc82ce3d0b6fd93L } },\n    /* 55 << 161 */\n    { { 0xf8e13501b35f1341L,0xe53156dd25a43e42L,0xd3adf27e4daeb85cL,\n        0xb81d8379bbeddeb5L },\n      { 0x1b0b546e2e435867L,0x9020eb94eba5dd60L,0x37d911618210cb9dL,\n        0x4c596b315c91f1cfL } },\n    /* 56 << 161 */\n    { { 0xb228a90f0e0b040dL,0xbaf02d8245ff897fL,0x2aac79e600fa6122L,\n        0x248288178e36f557L },\n      { 0xb9521d31113ec356L,0x9e48861e15eff1f8L,0x2aa1d412e0d41715L,\n        0x71f8620353f131b8L } },\n    /* 57 << 161 */\n    { { 0xf60da8da3fd19408L,0x4aa716dc278d9d99L,0x394531f7a8c51c90L,\n        0xb560b0e8f59db51cL },\n      { 0xa28fc992fa34bdadL,0xf024fa149cd4f8bdL,0x5cf530f723a9d0d3L,\n        0x615ca193e28c9b56L } },\n    /* 58 << 161 */\n    { { 0x6d2a483d6f73c51eL,0xa4cb2412ea0dc2ddL,0x50663c411eb917ffL,\n        0x3d3a74cfeade299eL },\n      { 0x29b3990f4a7a9202L,0xa9bccf59a7b15c3dL,0x66a3ccdca5df9208L,\n        0x48027c1443f2f929L } },\n    /* 59 << 161 */\n    { { 0xd385377c40b557f0L,0xe001c366cd684660L,0x1b18ed6be2183a27L,\n        0x879738d863210329L },\n      { 0xa687c74bbda94882L,0xd1bbcc48a684b299L,0xaf6f1112863b3724L,\n        0x6943d1b42c8ce9f8L } },\n    /* 60 << 161 */\n    { { 0xe044a3bb098cafb4L,0x27ed231060d48cafL,0x542b56753a31b84dL,\n        0xcbf3dd50fcddbed7L },\n      { 0x25031f1641b1d830L,0xa7ec851dcb0c1e27L,0xac1c8fe0b5ae75dbL,\n        0xb24c755708c52120L } },\n    /* 61 << 161 */\n    { { 0x57f811dc1d4636c3L,0xf8436526681a9939L,0x1f6bc6d99c81adb3L,\n        0x840f8ac35b7d80d4L },\n      { 0x731a9811f4387f1aL,0x7c501cd3b5156880L,0xa5ca4a07dfe68867L,\n        0xf123d8f05fcea120L } },\n    /* 62 << 161 */\n    { { 0x1fbb0e71d607039eL,0x2b70e215cd3a4546L,0x32d2f01d53324091L,\n        0xb796ff08180ab19bL },\n      { 0x32d87a863c57c4aaL,0x2aed9cafb7c49a27L,0x9fb35eac31630d98L,\n        0x338e8cdf5c3e20a3L } },\n    /* 63 << 161 */\n    { { 0x80f1618266cde8dbL,0x4e1599802d72fd36L,0xd7b8f13b9b6e5072L,\n        0xf52139073b7b5dc1L },\n      { 0x4d431f1d8ce4396eL,0x37a1a680a7ed2142L,0xbf375696d01aaf6bL,\n        0xaa1c0c54e63aab66L } },\n    /* 64 << 161 */\n    { { 0x3014368b4ed80940L,0x67e6d0567a6fceddL,0x7c208c49ca97579fL,\n        0xfe3d7a81a23597f6L },\n      { 0x5e2032027e096ae2L,0xb1f3e1e724b39366L,0x26da26f32fdcdffcL,\n        0x79422f1d6097be83L } },\n    /* 0 << 168 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 168 */\n    { { 0x263a2cfb9db3b381L,0x9c3a2deed4df0a4bL,0x728d06e97d04e61fL,\n        0x8b1adfbc42449325L },\n      { 0x6ec1d9397e053a1bL,0xee2be5c766daf707L,0x80ba1e14810ac7abL,\n        0xdd2ae778f530f174L } },\n    /* 2 << 168 */\n    { { 0x0435d97a205b9d8bL,0x6eb8f064056756d4L,0xd5e88a8bb6f8210eL,\n        0x070ef12dec9fd9eaL },\n      { 0x4d8495053bcc876aL,0x12a75338a7404ce3L,0xd22b49e1b8a1db5eL,\n        0xec1f205114bfa5adL } },\n    /* 3 << 168 */\n    { { 0xadbaeb79b6828f36L,0x9d7a025801bd5b9eL,0xeda01e0d1e844b0cL,\n        0x4b625175887edfc9L },\n      { 0x14109fdd9669b621L,0x88a2ca56f6f87b98L,0xfe2eb788170df6bcL,\n        0x0cea06f4ffa473f9L } },\n    /* 4 << 168 */\n    { { 0x43ed81b5c4e83d33L,0xd9f358795efd488bL,0x164a620f9deb4d0fL,\n        0xc6927bdbac6a7394L },\n      { 0x45c28df79f9e0f03L,0x2868661efcd7e1a9L,0x7cf4e8d0ffa348f1L,\n        0x6bd4c284398538e0L } },\n    /* 5 << 168 */\n    { { 0x2618a091289a8619L,0xef796e606671b173L,0x664e46e59090c632L,\n        0xa38062d41e66f8fbL },\n      { 0x6c744a200573274eL,0xd07b67e4a9271394L,0x391223b26bdc0e20L,\n        0xbe2d93f1eb0a05a7L } },\n    /* 6 << 168 */\n    { { 0xf23e2e533f36d141L,0xe84bb3d44dfca442L,0xb804a48d6b7c023aL,\n        0x1e16a8fa76431c3bL },\n      { 0x1b5452adddd472e0L,0x7d405ee70d1ee127L,0x50fc6f1dffa27599L,\n        0x351ac53cbf391b35L } },\n    /* 7 << 168 */\n    { { 0x7efa14b84444896bL,0x64974d2ff94027fbL,0xefdcd0e8de84487dL,\n        0x8c45b2602b48989bL },\n      { 0xa8fcbbc2d8463487L,0xd1b2b3f73fbc476cL,0x21d005b7c8f443c0L,\n        0x518f2e6740c0139cL } },\n    /* 8 << 168 */\n    { { 0x56036e8c06d75fc1L,0x2dcf7bb73249a89fL,0x81dd1d3de245e7ddL,\n        0xf578dc4bebd6e2a7L },\n      { 0x4c028903df2ce7a0L,0xaee362889c39afacL,0xdc847c31146404abL,\n        0x6304c0d8a4e97818L } },\n    /* 9 << 168 */\n    { { 0xae51dca2a91f6791L,0x2abe41909baa9efcL,0xd9d2e2f4559c7ac1L,\n        0xe82f4b51fc9f773aL },\n      { 0xa77130274073e81cL,0xc0276facfbb596fcL,0x1d819fc9a684f70cL,\n        0x29b47fddc9f7b1e0L } },\n    /* 10 << 168 */\n    { { 0x358de103459b1940L,0xec881c595b013e93L,0x51574c9349532ad3L,\n        0x2db1d445b37b46deL },\n      { 0xc6445b87df239fd8L,0xc718af75151d24eeL,0xaea1c4a4f43c6259L,\n        0x40c0e5d770be02f7L } },\n    /* 11 << 168 */\n    { { 0x6a4590f4721b33f2L,0x2124f1fbfedf04eaL,0xf8e53cde9745efe7L,\n        0xe7e1043265f046d9L },\n      { 0xc3fca28ee4d0c7e6L,0x847e339a87253b1bL,0x9b5953483743e643L,\n        0xcb6a0a0b4fd12fc5L } },\n    /* 12 << 168 */\n    { { 0xfb6836c327d02dccL,0x5ad009827a68bcc2L,0x1b24b44c005e912dL,\n        0xcc83d20f811fdcfeL },\n      { 0x36527ec1666fba0cL,0x6994819714754635L,0xfcdcb1a8556da9c2L,\n        0xa593426781a732b2L } },\n    /* 13 << 168 */\n    { { 0xec1214eda714181dL,0x609ac13b6067b341L,0xff4b4c97a545df1fL,\n        0xa124050134d2076bL },\n      { 0x6efa0c231409ca97L,0x254cc1a820638c43L,0xd4e363afdcfb46cdL,\n        0x62c2adc303942a27L } },\n    /* 14 << 168 */\n    { { 0xc67b9df056e46483L,0xa55abb2063736356L,0xab93c098c551bc52L,\n        0x382b49f9b15fe64bL },\n      { 0x9ec221ad4dff8d47L,0x79caf615437df4d6L,0x5f13dc64bb456509L,\n        0xe4c589d9191f0714L } },\n    /* 15 << 168 */\n    { { 0x27b6a8ab3fd40e09L,0xe455842e77313ea9L,0x8b51d1e21f55988bL,\n        0x5716dd73062bbbfcL },\n      { 0x633c11e54e8bf3deL,0x9a0e77b61b85be3bL,0x565107290911cca6L,\n        0x27e76495efa6590fL } },\n    /* 16 << 168 */\n    { { 0xe4ac8b33070d3aabL,0x2643672b9a2cd5e5L,0x52eff79b1cfc9173L,\n        0x665ca49b90a7c13fL },\n      { 0x5a8dda59b3efb998L,0x8a5b922d052f1341L,0xae9ebbab3cf9a530L,\n        0x35986e7bf56da4d7L } },\n    /* 17 << 168 */\n    { { 0x3a636b5cff3513ccL,0xbb0cf8ba3198f7ddL,0xb8d4052241f16f86L,\n        0x760575d8de13a7bfL },\n      { 0x36f74e169f7aa181L,0x163a3ecff509ed1cL,0x6aead61f3c40a491L,\n        0x158c95fcdfe8fcaaL } },\n    /* 18 << 168 */\n    { { 0xa3991b6e13cda46fL,0x79482415342faed0L,0xf3ba5bde666b5970L,\n        0x1d52e6bcb26ab6ddL },\n      { 0x768ba1e78608dd3dL,0x4930db2aea076586L,0xd9575714e7dc1afaL,\n        0x1fc7bf7df7c58817L } },\n    /* 19 << 168 */\n    { { 0x6b47accdd9eee96cL,0x0ca277fbe58cec37L,0x113fe413e702c42aL,\n        0xdd1764eec47cbe51L },\n      { 0x041e7cde7b3ed739L,0x50cb74595ce9e1c0L,0x355685132925b212L,\n        0x7cff95c4001b081cL } },\n    /* 20 << 168 */\n    { { 0x63ee4cbd8088b454L,0xdb7f32f79a9e0c8aL,0xb377d4186b2447cbL,\n        0xe3e982aad370219bL },\n      { 0x06ccc1e4c2a2a593L,0x72c368650773f24fL,0xa13b4da795859423L,\n        0x8bbf1d3375040c8fL } },\n    /* 21 << 168 */\n    { { 0x726f0973da50c991L,0x48afcd5b822d6ee2L,0xe5fc718b20fd7771L,\n        0xb9e8e77dfd0807a1L },\n      { 0x7f5e0f4499a7703dL,0x6972930e618e36f3L,0x2b7c77b823807bbeL,\n        0xe5b82405cb27ff50L } },\n    /* 22 << 168 */\n    { { 0xba8b8be3bd379062L,0xd64b7a1d2dce4a92L,0x040a73c5b2952e37L,\n        0x0a9e252ed438aecaL },\n      { 0xdd43956bc39d3bcbL,0x1a31ca00b32b2d63L,0xd67133b85c417a18L,\n        0xd08e47902ef442c8L } },\n    /* 23 << 168 */\n    { { 0x98cb1ae9255c0980L,0x4bd863812b4a739fL,0x5a5c31e11e4a45a1L,\n        0x1e5d55fe9cb0db2fL },\n      { 0x74661b068ff5cc29L,0x026b389f0eb8a4f4L,0x536b21a458848c24L,\n        0x2e5bf8ec81dc72b0L } },\n    /* 24 << 168 */\n    { { 0x03c187d0ad886aacL,0x5c16878ab771b645L,0xb07dfc6fc74045abL,\n        0x2c6360bf7800caedL },\n      { 0x24295bb5b9c972a3L,0xc9e6f88e7c9a6dbaL,0x90ffbf2492a79aa6L,\n        0xde29d50a41c26ac2L } },\n    /* 25 << 168 */\n    { { 0x9f0af483d309cbe6L,0x5b020d8ae0bced4fL,0x606e986db38023e3L,\n        0xad8f2c9d1abc6933L },\n      { 0x19292e1de7400e93L,0xfe3e18a952be5e4dL,0xe8e9771d2e0680bfL,\n        0x8c5bec98c54db063L } },\n    /* 26 << 168 */\n    { { 0x2af9662a74a55d1fL,0xe3fbf28f046f66d8L,0xa3a72ab4d4dc4794L,\n        0x09779f455c7c2dd8L },\n      { 0xd893bdafc3d19d8dL,0xd5a7509457d6a6dfL,0x8cf8fef9952e6255L,\n        0x3da67cfbda9a8affL } },\n    /* 27 << 168 */\n    { { 0x4c23f62a2c160dcdL,0x34e6c5e38f90eaefL,0x35865519a9a65d5aL,\n        0x07c48aae8fd38a3dL },\n      { 0xb7e7aeda50068527L,0x2c09ef231c90936aL,0x31ecfeb6e879324cL,\n        0xa0871f6bfb0ec938L } },\n    /* 28 << 168 */\n    { { 0xb1f0fb68d84d835dL,0xc90caf39861dc1e6L,0x12e5b0467594f8d7L,\n        0x26897ae265012b92L },\n      { 0xbcf68a08a4d6755dL,0x403ee41c0991fbdaL,0x733e343e3bbf17e8L,\n        0xd2c7980d679b3d65L } },\n    /* 29 << 168 */\n    { { 0x33056232d2e11305L,0x966be492f3c07a6fL,0x6a8878ffbb15509dL,\n        0xff2211010a9b59a4L },\n      { 0x6c9f564aabe30129L,0xc6f2c940336e64cfL,0x0fe752628b0c8022L,\n        0xbe0267e96ae8db87L } },\n    /* 30 << 168 */\n    { { 0x22e192f193bc042bL,0xf085b534b237c458L,0xa0d192bd832c4168L,\n        0x7a76e9e3bdf6271dL },\n      { 0x52a882fab88911b5L,0xc85345e4b4db0eb5L,0xa3be02a681a7c3ffL,\n        0x51889c8cf0ec0469L } },\n    /* 31 << 168 */\n    { { 0x9d031369a5e829e5L,0xcbb4c6fc1607aa41L,0x75ac59a6241d84c1L,\n        0xc043f2bf8829e0eeL },\n      { 0x82a38f758ea5e185L,0x8bda40b9d87cbd9fL,0x9e65e75e2d8fc601L,\n        0x3d515f74a35690b3L } },\n    /* 32 << 168 */\n    { { 0x534acf4fda79e5acL,0x68b83b3a8630215fL,0x5c748b2ed085756eL,\n        0xb0317258e5d37cb2L },\n      { 0x6735841ac5ccc2c4L,0x7d7dc96b3d9d5069L,0xa147e410fd1754bdL,\n        0x65296e94d399ddd5L } },\n    /* 33 << 168 */\n    { { 0xf6b5b2d0bc8fa5bcL,0x8a5ead67500c277bL,0x214625e6dfa08a5dL,\n        0x51fdfedc959cf047L },\n      { 0x6bc9430b289fca32L,0xe36ff0cf9d9bdc3fL,0x2fe187cb58ea0edeL,\n        0xed66af205a900b3fL } },\n    /* 34 << 168 */\n    { { 0x00e0968b5fa9f4d6L,0x2d4066ce37a362e7L,0xa99a9748bd07e772L,\n        0x710989c006a4f1d0L },\n      { 0xd5dedf35ce40cbd8L,0xab55c5f01743293dL,0x766f11448aa24e2cL,\n        0x94d874f8605fbcb4L } },\n    /* 35 << 168 */\n    { { 0xa365f0e8a518001bL,0xee605eb69d04ef0fL,0x5a3915cdba8d4d25L,\n        0x44c0e1b8b5113472L },\n      { 0xcbb024e88b6740dcL,0x89087a53ee1d4f0cL,0xa88fa05c1fc4e372L,\n        0x8bf395cbaf8b3af2L } },\n    /* 36 << 168 */\n    { { 0x1e71c9a1deb8568bL,0xa35daea080fb3d32L,0xe8b6f2662cf8fb81L,\n        0x6d51afe89490696aL },\n      { 0x81beac6e51803a19L,0xe3d24b7f86219080L,0x727cfd9ddf6f463cL,\n        0x8c6865ca72284ee8L } },\n    /* 37 << 168 */\n    { { 0x32c88b7db743f4efL,0x3793909be7d11dceL,0xd398f9222ff2ebe8L,\n        0x2c70ca44e5e49796L },\n      { 0xdf4d9929cb1131b1L,0x7826f29825888e79L,0x4d3a112cf1d8740aL,\n        0x00384cb6270afa8bL } },\n    /* 38 << 168 */\n    { { 0xcb64125b3ab48095L,0x3451c25662d05106L,0xd73d577da4955845L,\n        0x39570c16bf9f4433L },\n      { 0xd7dfaad3adecf263L,0xf1c3d8d1dc76e102L,0x5e774a5854c6a836L,\n        0xdad4b6723e92d47bL } },\n    /* 39 << 168 */\n    { { 0xbe7e990ff0d796a0L,0x5fc62478df0e8b02L,0x8aae8bf4030c00adL,\n        0x3d2db93b9004ba0fL },\n      { 0xe48c8a79d85d5ddcL,0xe907caa76bb07f34L,0x58db343aa39eaed5L,\n        0x0ea6e007adaf5724L } },\n    /* 40 << 168 */\n    { { 0xe00df169d23233f3L,0x3e32279677cb637fL,0x1f897c0e1da0cf6cL,\n        0xa651f5d831d6bbddL },\n      { 0xdd61af191a230c76L,0xbd527272cdaa5e4aL,0xca753636d0abcd7eL,\n        0x78bdd37c370bd8dcL } },\n    /* 41 << 168 */\n    { { 0xc23916c217cd93feL,0x65b97a4ddadce6e2L,0xe04ed4eb174e42f8L,\n        0x1491ccaabb21480aL },\n      { 0x145a828023196332L,0x3c3862d7587b479aL,0x9f4a88a301dcd0edL,\n        0x4da2b7ef3ea12f1fL } },\n    /* 42 << 168 */\n    { { 0xf8e7ae33b126e48eL,0x404a0b32f494e237L,0x9beac474c55acadbL,\n        0x4ee5cf3bcbec9fd9L },\n      { 0x336b33b97df3c8c3L,0xbd905fe3b76808fdL,0x8f436981aa45c16aL,\n        0x255c5bfa3dd27b62L } },\n    /* 43 << 168 */\n    { { 0x71965cbfc3dd9b4dL,0xce23edbffc068a87L,0xb78d4725745b029bL,\n        0x74610713cefdd9bdL },\n      { 0x7116f75f1266bf52L,0x0204672218e49bb6L,0xdf43df9f3d6f19e3L,\n        0xef1bc7d0e685cb2fL } },\n    /* 44 << 168 */\n    { { 0xcddb27c17078c432L,0xe1961b9cb77fedb7L,0x1edc2f5cc2290570L,\n        0x2c3fefca19cbd886L },\n      { 0xcf880a36c2af389aL,0x96c610fdbda71ceaL,0xf03977a932aa8463L,\n        0x8eb7763f8586d90aL } },\n    /* 45 << 168 */\n    { { 0x3f3424542a296e77L,0xc871868342837a35L,0x7dc710906a09c731L,\n        0x54778ffb51b816dbL },\n      { 0x6b33bfecaf06defdL,0xfe3c105f8592b70bL,0xf937fda461da6114L,\n        0x3c13e6514c266ad7L } },\n    /* 46 << 168 */\n    { { 0xe363a829855938e8L,0x2eeb5d9e9de54b72L,0xbeb93b0e20ccfab9L,\n        0x3dffbb5f25e61a25L },\n      { 0x7f655e431acc093dL,0x0cb6cc3d3964ce61L,0x6ab283a1e5e9b460L,\n        0x55d787c5a1c7e72dL } },\n    /* 47 << 168 */\n    { { 0x4d2efd47deadbf02L,0x11e80219ac459068L,0x810c762671f311f0L,\n        0xfa17ef8d4ab6ef53L },\n      { 0xaf47fd2593e43bffL,0x5cb5ff3f0be40632L,0x546871068ee61da3L,\n        0x7764196eb08afd0fL } },\n    /* 48 << 168 */\n    { { 0x831ab3edf0290a8fL,0xcae81966cb47c387L,0xaad7dece184efb4fL,\n        0xdcfc53b34749110eL },\n      { 0x6698f23c4cb632f9L,0xc42a1ad6b91f8067L,0xb116a81d6284180aL,\n        0xebedf5f8e901326fL } },\n    /* 49 << 168 */\n    { { 0xf2274c9f97e3e044L,0x4201852011d09fc9L,0x56a65f17d18e6e23L,\n        0x2ea61e2a352b683cL },\n      { 0x27d291bc575eaa94L,0x9e7bc721b8ff522dL,0x5f7268bfa7f04d6fL,\n        0x5868c73faba41748L } },\n    /* 50 << 168 */\n    { { 0x9f85c2db7be0eeadL,0x511e7842ff719135L,0x5a06b1e9c5ea90d7L,\n        0x0c19e28326fab631L },\n      { 0x8af8f0cfe9206c55L,0x89389cb43553c06aL,0x39dbed97f65f8004L,\n        0x0621b037c508991dL } },\n    /* 51 << 168 */\n    { { 0x1c52e63596e78cc4L,0x5385c8b20c06b4a8L,0xd84ddfdbb0e87d03L,\n        0xc49dfb66934bafadL },\n      { 0x7071e17059f70772L,0x3a073a843a1db56bL,0x034949033b8af190L,\n        0x7d882de3d32920f0L } },\n    /* 52 << 168 */\n    { { 0x91633f0ab2cf8940L,0x72b0b1786f948f51L,0x2d28dc30782653c8L,\n        0x88829849db903a05L },\n      { 0xb8095d0c6a19d2bbL,0x4b9e7f0c86f782cbL,0x7af739882d907064L,\n        0xd12be0fe8b32643cL } },\n    /* 53 << 168 */\n    { { 0x358ed23d0e165dc3L,0x3d47ce624e2378ceL,0x7e2bb0b9feb8a087L,\n        0x3246e8aee29e10b9L },\n      { 0x459f4ec703ce2b4dL,0xe9b4ca1bbbc077cfL,0x2613b4f20e9940c1L,\n        0xfc598bb9047d1eb1L } },\n    /* 54 << 168 */\n    { { 0x9744c62b45036099L,0xa9dee742167c65d8L,0x0c511525dabe1943L,\n        0xda11055493c6c624L },\n      { 0xae00a52c651a3be2L,0xcda5111d884449a6L,0x063c06f4ff33bed1L,\n        0x73baaf9a0d3d76b4L } },\n    /* 55 << 168 */\n    { { 0x52fb0c9d7fc63668L,0x6886c9dd0c039cdeL,0x602bd59955b22351L,\n        0xb00cab02360c7c13L },\n      { 0x8cb616bc81b69442L,0x41486700b55c3ceeL,0x71093281f49ba278L,\n        0xad956d9c64a50710L } },\n    /* 56 << 168 */\n    { { 0x9561f28b638a7e81L,0x54155cdf5980ddc3L,0xb2db4a96d26f247aL,\n        0x9d774e4e4787d100L },\n      { 0x1a9e6e2e078637d2L,0x1c363e2d5e0ae06aL,0x7493483ee9cfa354L,\n        0x76843cb37f74b98dL } },\n    /* 57 << 168 */\n    { { 0xbaca6591d4b66947L,0xb452ce9804460a8cL,0x6830d24643768f55L,\n        0xf4197ed87dff12dfL },\n      { 0x6521b472400dd0f7L,0x59f5ca8f4b1e7093L,0x6feff11b080338aeL,\n        0x0ada31f6a29ca3c6L } },\n    /* 58 << 168 */\n    { { 0x24794eb694a2c215L,0xd83a43ab05a57ab4L,0x264a543a2a6f89feL,\n        0x2c2a3868dd5ec7c2L },\n      { 0xd33739408439d9b2L,0x715ea6720acd1f11L,0x42c1d235e7e6cc19L,\n        0x81ce6e96b990585cL } },\n    /* 59 << 168 */\n    { { 0x04e5dfe0d809c7bdL,0xd7b2580c8f1050abL,0x6d91ad78d8a4176fL,\n        0x0af556ee4e2e897cL },\n      { 0x162a8b73921de0acL,0x52ac9c227ea78400L,0xee2a4eeaefce2174L,\n        0xbe61844e6d637f79L } },\n    /* 60 << 168 */\n    { { 0x0491f1bc789a283bL,0x72d3ac3d880836f4L,0xaa1c5ea388e5402dL,\n        0x1b192421d5cc473dL },\n      { 0x5c0b99989dc84cacL,0xb0a8482d9c6e75b8L,0x639961d03a191ce2L,\n        0xda3bc8656d837930L } },\n    /* 61 << 168 */\n    { { 0xca990653056e6f8fL,0x84861c4164d133a7L,0x8b403276746abe40L,\n        0xb7b4d51aebf8e303L },\n      { 0x05b43211220a255dL,0xc997152c02419e6eL,0x76ff47b6630c2feaL,\n        0x50518677281fdadeL } },\n    /* 62 << 168 */\n    { { 0x3283b8bacf902b0bL,0x8d4b4eb537db303bL,0xcc89f42d755011bcL,\n        0xb43d74bbdd09d19bL },\n      { 0x65746bc98adba350L,0x364eaf8cb51c1927L,0x13c7659610ad72ecL,\n        0x30045121f8d40c20L } },\n    /* 63 << 168 */\n    { { 0x6d2d99b7ea7b979bL,0xcd78cd74e6fb3bcdL,0x11e45a9e86cffbfeL,\n        0x78a61cf4637024f6L },\n      { 0xd06bc8723d502295L,0xf1376854458cb288L,0xb9db26a1342f8586L,\n        0xf33effcf4beee09eL } },\n    /* 64 << 168 */\n    { { 0xd7e0c4cdb30cfb3aL,0x6d09b8c16c9db4c8L,0x40ba1a4207c8d9dfL,\n        0x6fd495f71c52c66dL },\n      { 0xfb0e169f275264daL,0x80c2b746e57d8362L,0xedd987f749ad7222L,\n        0xfdc229af4398ec7bL } },\n    /* 0 << 175 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 175 */\n    { { 0xb0d1ed8452666a58L,0x4bcb6e00e6a9c3c2L,0x3c57411c26906408L,\n        0xcfc2075513556400L },\n      { 0xa08b1c505294dba3L,0xa30ba2868b7dd31eL,0xd70ba90e991eca74L,\n        0x094e142ce762c2b9L } },\n    /* 2 << 175 */\n    { { 0xb81d783e979f3925L,0x1efd130aaf4c89a7L,0x525c2144fd1bf7faL,\n        0x4b2969041b265a9eL },\n      { 0xed8e9634b9db65b6L,0x35c82e3203599d8aL,0xdaa7a54f403563f3L,\n        0x9df088ad022c38abL } },\n    /* 3 << 175 */\n    { { 0xe5cfb066bb3fd30aL,0x429169daeff0354eL,0x809cf8523524e36cL,\n        0x136f4fb30155be1dL },\n      { 0x4826af011fbba712L,0x6ef0f0b4506ba1a1L,0xd9928b3177aea73eL,\n        0xe2bf6af25eaa244eL } },\n    /* 4 << 175 */\n    { { 0x8d084f124237b64bL,0x688ebe99e3ecfd07L,0x57b8a70cf6845dd8L,\n        0x808fc59c5da4a325L },\n      { 0xa9032b2ba3585862L,0xb66825d5edf29386L,0xb5a5a8db431ec29bL,\n        0xbb143a983a1e8dc8L } },\n    /* 5 << 175 */\n    { { 0x35ee94ce12ae381bL,0x3a7f176c86ccda90L,0xc63a657e4606eacaL,\n        0x9ae5a38043cd04dfL },\n      { 0x9bec8d15ed251b46L,0x1f5d6d30caca5e64L,0x347b3b359ff20f07L,\n        0x4d65f034f7e4b286L } },\n    /* 6 << 175 */\n    { { 0x9e93ba24f111661eL,0xedced484b105eb04L,0x96dc9ba1f424b578L,\n        0xbf8f66b7e83e9069L },\n      { 0x872d4df4d7ed8216L,0xbf07f3778e2cbecfL,0x4281d89998e73754L,\n        0xfec85fbb8aab8708L } },\n    /* 7 << 175 */\n    { { 0x9a3c0deea5ba5b0bL,0xe6a116ce42d05299L,0xae9775fee9b02d42L,\n        0x72b05200a1545cb6L },\n      { 0xbc506f7d31a3b4eaL,0xe58930788bbd9b32L,0xc8bc5f37e4b12a97L,\n        0x6b000c064a73b671L } },\n    /* 8 << 175 */\n    { { 0x13b5bf22765fa7d0L,0x59805bf01d6a5370L,0x67a5e29d4280db98L,\n        0x4f53916f776b1ce3L },\n      { 0x714ff61f33ddf626L,0x4206238ea085d103L,0x1c50d4b7e5809ee3L,\n        0x999f450d85f8eb1dL } },\n    /* 9 << 175 */\n    { { 0x658a6051e4c79e9bL,0x1394cb73c66a9feaL,0x27f31ed5c6be7b23L,\n        0xf4c88f365aa6f8feL },\n      { 0x0fb0721f4aaa499eL,0x68b3a7d5e3fb2a6bL,0xa788097d3a92851dL,\n        0x060e7f8ae96f4913L } },\n    /* 10 << 175 */\n    { { 0x82eebe731a3a93bcL,0x42bbf465a21adc1aL,0xc10b6fa4ef030efdL,\n        0x247aa4c787b097bbL },\n      { 0x8b8dc632f60c77daL,0x6ffbc26ac223523eL,0xa4f6ff11344579cfL,\n        0x5825653c980250f6L } },\n    /* 11 << 175 */\n    { { 0xb2dd097ebc1aa2b9L,0x0788939337a0333aL,0x1cf55e7137a0db38L,\n        0x2648487f792c1613L },\n      { 0xdad013363fcef261L,0x6239c81d0eabf129L,0x8ee761de9d276be2L,\n        0x406a7a341eda6ad3L } },\n    /* 12 << 175 */\n    { { 0x4bf367ba4a493b31L,0x54f20a529bf7f026L,0xb696e0629795914bL,\n        0xcddab96d8bf236acL },\n      { 0x4ff2c70aed25ea13L,0xfa1d09eb81cbbbe7L,0x88fc8c87468544c5L,\n        0x847a670d696b3317L } },\n    /* 13 << 175 */\n    { { 0xf133421e64bcb626L,0xaea638c826dee0b5L,0xd6e7680bb310346cL,\n        0xe06f4097d5d4ced3L },\n      { 0x099614527512a30bL,0xf3d867fde589a59aL,0x2e73254f52d0c180L,\n        0x9063d8a3333c74acL } },\n    /* 14 << 175 */\n    { { 0xeda6c595d314e7bcL,0x2ee7464b467899edL,0x1cef423c0a1ed5d3L,\n        0x217e76ea69cc7613L },\n      { 0x27ccce1fe7cda917L,0x12d8016b8a893f16L,0xbcd6de849fc74f6bL,\n        0xfa5817e2f3144e61L } },\n    /* 15 << 175 */\n    { { 0x1f3541640821ee4cL,0x1583eab40bc61992L,0x7490caf61d72879fL,\n        0x998ad9f3f76ae7b2L },\n      { 0x1e181950a41157f7L,0xa9d7e1e6e8da3a7eL,0x963784eb8426b95fL,\n        0x0ee4ed6e542e2a10L } },\n    /* 16 << 175 */\n    { { 0xb79d4cc5ac751e7bL,0x93f96472fd4211bdL,0x8c72d3d2c8de4fc6L,\n        0x7b69cbf5df44f064L },\n      { 0x3da90ca2f4bf94e1L,0x1a5325f8f12894e2L,0x0a437f6c7917d60bL,\n        0x9be7048696c9cb5dL } },\n    /* 17 << 175 */\n    { { 0xb4d880bfe1dc5c05L,0xd738addaeebeeb57L,0x6f0119d3df0fe6a3L,\n        0x5c686e5566eaaf5aL },\n      { 0x9cb10b50dfd0b7ecL,0xbdd0264b6a497c21L,0xfc0935148c546c96L,\n        0x58a947fa79dbf42aL } },\n    /* 18 << 175 */\n    { { 0xc0b48d4e49ccd6d7L,0xff8fb02c88bd5580L,0xc75235e907d473b2L,\n        0x4fab1ac5a2188af3L },\n      { 0x030fa3bc97576ec0L,0xe8c946e80b7e7d2fL,0x40a5c9cc70305600L,\n        0x6d8260a9c8b013b4L } },\n    /* 19 << 175 */\n    { { 0x0368304f70bba85cL,0xad090da1a4a0d311L,0x7170e8702415eec1L,\n        0xbfba35fe8461ea47L },\n      { 0x6279019ac1e91938L,0xa47638f31afc415fL,0x36c65cbbbcba0e0fL,\n        0x02160efb034e2c48L } },\n    /* 20 << 175 */\n    { { 0xe6c51073615cd9e4L,0x498ec047f1243c06L,0x3e5a8809b17b3d8cL,\n        0x5cd99e610cc565f1L },\n      { 0x81e312df7851dafeL,0xf156f5baa79061e2L,0x80d62b71880c590eL,\n        0xbec9746f0a39faa1L } },\n    /* 21 << 175 */\n    { { 0x1d98a9c1c8ed1f7aL,0x09e43bb5a81d5ff2L,0xd5f00f680da0794aL,\n        0x412050d9661aa836L },\n      { 0xa89f7c4e90747e40L,0x6dc05ebbb62a3686L,0xdf4de847308e3353L,\n        0x53868fbb9fb53bb9L } },\n    /* 22 << 175 */\n    { { 0x2b09d2c3cfdcf7ddL,0x41a9fce3723fcab4L,0x73d905f707f57ca3L,\n        0x080f9fb1ac8e1555L },\n      { 0x7c088e849ba7a531L,0x07d35586ed9a147fL,0x602846abaf48c336L,\n        0x7320fd320ccf0e79L } },\n    /* 23 << 175 */\n    { { 0xaa780798b18bd1ffL,0x52c2e300afdd2905L,0xf27ea3d6434267cdL,\n        0x8b96d16d15605b5fL },\n      { 0x7bb310494b45706bL,0xe7f58b8e743d25f8L,0xe9b5e45b87f30076L,\n        0xd19448d65d053d5aL } },\n    /* 24 << 175 */\n    { { 0x1ecc8cb9d3210a04L,0x6bc7d463dafb5269L,0x3e59b10a67c3489fL,\n        0x1769788c65641e1bL },\n      { 0x8a53b82dbd6cb838L,0x7066d6e6236d5f22L,0x03aa1c616908536eL,\n        0xc971da0d66ae9809L } },\n    /* 25 << 175 */\n    { { 0x01b3a86bc49a2facL,0x3b8420c03092e77aL,0x020573007d6fb556L,\n        0x6941b2a1bff40a87L },\n      { 0x140b63080658ff2aL,0x878043633424ab36L,0x0253bd515751e299L,\n        0xc75bcd76449c3e3aL } },\n    /* 26 << 175 */\n    { { 0x92eb40907f8f875dL,0x9c9d754e56c26bbfL,0x158cea618110bbe7L,\n        0x62a6b802745f91eaL },\n      { 0xa79c41aac6e7394bL,0x445b6a83ad57ef10L,0x0c5277eb6ea6f40cL,\n        0x319fe96b88633365L } },\n    /* 27 << 175 */\n    { { 0x0b0fc61f385f63cbL,0x41250c8422bdd127L,0x67d153f109e942c2L,\n        0x60920d08c021ad5dL },\n      { 0x229f5746724d81a5L,0xb7ffb8925bba3299L,0x518c51a1de413032L,\n        0x2a9bfe773c2fd94cL } },\n    /* 28 << 175 */\n    { { 0xcbcde2393191f4fdL,0x43093e16d3d6ada1L,0x184579f358769606L,\n        0x2c94a8b3d236625cL },\n      { 0x6922b9c05c437d8eL,0x3d4ae423d8d9f3c8L,0xf72c31c12e7090a2L,\n        0x4ac3f5f3d76a55bdL } },\n    /* 29 << 175 */\n    { { 0x342508fc6b6af991L,0x0d5271001b5cebbdL,0xb84740d0dd440dd7L,\n        0x748ef841780162fdL },\n      { 0xa8dbfe0edfc6fafbL,0xeadfdf05f7300f27L,0x7d06555ffeba4ec9L,\n        0x12c56f839e25fa97L } },\n    /* 30 << 175 */\n    { { 0x77f84203d39b8c34L,0xed8b1be63125eddbL,0x5bbf2441f6e39dc5L,\n        0xb00f6ee66a5d678aL },\n      { 0xba456ecf57d0ea99L,0xdcae0f5817e06c43L,0x01643de40f5b4baaL,\n        0x2c324341d161b9beL } },\n    /* 31 << 175 */\n    { { 0x80177f55e126d468L,0xed325f1f76748e09L,0x6116004acfa9bdc2L,\n        0x2d8607e63a9fb468L },\n      { 0x0e573e276009d660L,0x3a525d2e8d10c5a1L,0xd26cb45c3b9009a0L,\n        0xb6b0cdc0de9d7448L } },\n    /* 32 << 175 */\n    { { 0x949c9976e1337c26L,0x6faadebdd73d68e5L,0x9e158614f1b768d9L,\n        0x22dfa5579cc4f069L },\n      { 0xccd6da17be93c6d6L,0x24866c61a504f5b9L,0x2121353c8d694da1L,\n        0x1c6ca5800140b8c6L } },\n    /* 33 << 175 */\n    { { 0xc245ad8ce964021eL,0xb83bffba032b82b3L,0xfaa220c647ef9898L,\n        0x7e8d3ac6982c948aL },\n      { 0x1faa2091bc2d124aL,0xbd54c3dd05b15ff4L,0x386bf3abc87c6fb7L,\n        0xfb2b0563fdeb6f66L } },\n    /* 34 << 175 */\n    { { 0x4e77c5575b45afb4L,0xe9ded649efb8912dL,0x7ec9bbf542f6e557L,\n        0x2570dfff62671f00L },\n      { 0x2b3bfb7888e084bdL,0xa024b238f37fe5b4L,0x44e7dc0495649aeeL,\n        0x498ca2555e7ec1d8L } },\n    /* 35 << 175 */\n    { { 0x3bc766eaaaa07e86L,0x0db6facbf3608586L,0xbadd2549bdc259c8L,\n        0x95af3c6e041c649fL },\n      { 0xb36a928c02e30afbL,0x9b5356ad008a88b8L,0x4b67a5f1cf1d9e9dL,\n        0xc6542e47a5d8d8ceL } },\n    /* 36 << 175 */\n    { { 0x73061fe87adfb6ccL,0xcc826fd398678141L,0x00e758b13c80515aL,\n        0x6afe324741485083L },\n      { 0x0fcb08b9b6ae8a75L,0xb8cf388d4acf51e1L,0x344a55606961b9d6L,\n        0x1a6778b86a97fd0cL } },\n    /* 37 << 175 */\n    { { 0xd840fdc1ecc4c7e3L,0xde9fe47d16db68ccL,0xe95f89dea3e216aaL,\n        0x84f1a6a49594a8beL },\n      { 0x7ddc7d725a7b162bL,0xc5cfda19adc817a3L,0x80a5d35078b58d46L,\n        0x93365b1382978f19L } },\n    /* 38 << 175 */\n    { { 0x2e44d22526a1fc90L,0x0d6d10d24d70705dL,0xd94b6b10d70c45f4L,\n        0x0f201022b216c079L },\n      { 0xcec966c5658fde41L,0xa8d2bc7d7e27601dL,0xbfcce3e1ff230be7L,\n        0x3394ff6b0033ffb5L } },\n    /* 39 << 175 */\n    { { 0xd890c5098132c9afL,0xaac4b0eb361e7868L,0x5194ded3e82d15aaL,\n        0x4550bd2e23ae6b7dL },\n      { 0x3fda318eea5399d4L,0xd989bffa91638b80L,0x5ea124d0a14aa12dL,\n        0x1fb1b8993667b944L } },\n    /* 40 << 175 */\n    { { 0x95ec796944c44d6aL,0x91df144a57e86137L,0x915fd62073adac44L,\n        0x8f01732d59a83801L },\n      { 0xec579d253aa0a633L,0x06de5e7cc9d6d59cL,0xc132f958b1ef8010L,\n        0x29476f96e65c1a02L } },\n    /* 41 << 175 */\n    { { 0x336a77c0d34c3565L,0xef1105b21b9f1e9eL,0x63e6d08bf9e08002L,\n        0x9aff2f21c613809eL },\n      { 0xb5754f853a80e75dL,0xde71853e6bbda681L,0x86f041df8197fd7aL,\n        0x8b332e08127817faL } },\n    /* 42 << 175 */\n    { { 0x05d99be8b9c20cdaL,0x89f7aad5d5cd0c98L,0x7ef936fe5bb94183L,\n        0x92ca0753b05cd7f2L },\n      { 0x9d65db1174a1e035L,0x02628cc813eaea92L,0xf2d9e24249e4fbf2L,\n        0x94fdfd9be384f8b7L } },\n    /* 43 << 175 */\n    { { 0x65f5605463428c6bL,0x2f7205b290b409a5L,0xf778bb78ff45ae11L,\n        0xa13045bec5ee53b2L },\n      { 0xe00a14ff03ef77feL,0x689cd59fffef8befL,0x3578f0ed1e9ade22L,\n        0xe99f3ec06268b6a8L } },\n    /* 44 << 175 */\n    { { 0xa2057d91ea1b3c3eL,0x2d1a7053b8823a4aL,0xabbb336a2cca451eL,\n        0xcd2466e32218bb5dL },\n      { 0x3ac1f42fc8cb762dL,0x7e312aae7690211fL,0xebb9bd7345d07450L,\n        0x207c4b8246c2213fL } },\n    /* 45 << 175 */\n    { { 0x99d425c1375913ecL,0x94e45e9667908220L,0xc08f3087cd67dbf6L,\n        0xa5670fbec0887056L },\n      { 0x6717b64a66f5b8fcL,0xd5a56aea786fec28L,0xa8c3f55fc0ff4952L,\n        0xa77fefae457ac49bL } },\n    /* 46 << 175 */\n    { { 0x29882d7c98379d44L,0xd000bdfb509edc8aL,0xc6f95979e66fe464L,\n        0x504a6115fa61bde0L },\n      { 0x56b3b871effea31aL,0x2d3de26df0c21a54L,0x21dbff31834753bfL,\n        0xe67ecf4969269d86L } },\n    /* 47 << 175 */\n    { { 0x7a176952151fe690L,0x035158047f2adb5fL,0xee794b15d1b62a8dL,\n        0xf004ceecaae454e6L },\n      { 0x0897ea7cf0386facL,0x3b62ff12d1fca751L,0x154181df1b7a04ecL,\n        0x2008e04afb5847ecL } },\n    /* 48 << 175 */\n    { { 0xd147148e41dbd772L,0x2b419f7322942654L,0x669f30d3e9c544f7L,\n        0x52a2c223c8540149L },\n      { 0x5da9ee14634dfb02L,0x5f074ff0f47869f3L,0x74ee878da3933accL,\n        0xe65106514fe35ed1L } },\n    /* 49 << 175 */\n    { { 0xb3eb9482f1012e7aL,0x51013cc0a8a566aeL,0xdd5e924347c00d3bL,\n        0x7fde089d946bb0e5L },\n      { 0x030754fec731b4b3L,0x12a136a499fda062L,0x7c1064b85a1a35bcL,\n        0xbf1f5763446c84efL } },\n    /* 50 << 175 */\n    { { 0xed29a56da16d4b34L,0x7fba9d09dca21c4fL,0x66d7ac006d8de486L,\n        0x6006198773a2a5e1L },\n      { 0x8b400f869da28ff0L,0x3133f70843c4599cL,0x9911c9b8ee28cb0dL,\n        0xcd7e28748e0af61dL } },\n    /* 51 << 175 */\n    { { 0x5a85f0f272ed91fcL,0x85214f319cd4a373L,0x881fe5be1925253cL,\n        0xd8dc98e091e8bc76L },\n      { 0x7120affe585cc3a2L,0x724952ed735bf97aL,0x5581e7dc3eb34581L,\n        0x5cbff4f2e52ee57dL } },\n    /* 52 << 175 */\n    { { 0x8d320a0e87d8cc7bL,0x9beaa7f3f1d280d0L,0x7a0b95719beec704L,\n        0x9126332e5b7f0057L },\n      { 0x01fbc1b48ed3bd6dL,0x35bb2c12d945eb24L,0x6404694e9a8ae255L,\n        0xb6092eec8d6abfb3L } },\n    /* 53 << 175 */\n    { { 0x4d76143fcc058865L,0x7b0a5af26e249922L,0x8aef94406a50d353L,\n        0xe11e4bcc64f0e07aL },\n      { 0x4472993aa14a90faL,0x7706e20cba0c51d4L,0xf403292f1532672dL,\n        0x52573bfa21829382L } },\n    /* 54 << 175 */\n    { { 0x6a7bb6a93b5bdb83L,0x08da65c0a4a72318L,0xc58d22aa63eb065fL,\n        0x1717596c1b15d685L },\n      { 0x112df0d0b266d88bL,0xf688ae975941945aL,0x487386e37c292cacL,\n        0x42f3b50d57d6985cL } },\n    /* 55 << 175 */\n    { { 0x6da4f9986a90fc34L,0xc8f257d365ca8a8dL,0xc2feabca6951f762L,\n        0xe1bc81d074c323acL },\n      { 0x1bc68f67251a2a12L,0x10d86587be8a70dcL,0xd648af7ff0f84d2eL,\n        0xf0aa9ebc6a43ac92L } },\n    /* 56 << 175 */\n    { { 0x69e3be0427596893L,0xb6bb02a645bf452bL,0x0875c11af4c698c8L,\n        0x6652b5c7bece3794L },\n      { 0x7b3755fd4f5c0499L,0x6ea16558b5532b38L,0xd1c69889a2e96ef7L,\n        0x9c773c3a61ed8f48L } },\n    /* 57 << 175 */\n    { { 0x2b653a409b323abcL,0xe26605e1f0e1d791L,0x45d410644a87157aL,\n        0x8f9a78b7cbbce616L },\n      { 0xcf1e44aac407edddL,0x81ddd1d8a35b964fL,0x473e339efd083999L,\n        0x6c94bdde8e796802L } },\n    /* 58 << 175 */\n    { { 0x5a304ada8545d185L,0x82ae44ea738bb8cbL,0x628a35e3df87e10eL,\n        0xd3624f3da15b9fe3L },\n      { 0xcc44209b14be4254L,0x7d0efcbcbdbc2ea5L,0x1f60336204c37bbeL,\n        0x21f363f556a5852cL } },\n    /* 59 << 175 */\n    { { 0xa1503d1ca8501550L,0x2251e0e1d8ab10bbL,0xde129c966961c51cL,\n        0x1f7246a481910f68L },\n      { 0x2eb744ee5f2591f2L,0x3c47d33f5e627157L,0x4d6d62c922f3bd68L,\n        0x6120a64bcb8df856L } },\n    /* 60 << 175 */\n    { { 0x3a9ac6c07b5d07dfL,0xa92b95587ef39783L,0xe128a134ab3a9b4fL,\n        0x41c18807b1252f05L },\n      { 0xfc7ed08980ba9b1cL,0xac8dc6dec532a9ddL,0xbf829cef55246809L,\n        0x101b784f5b4ee80fL } },\n    /* 61 << 175 */\n    { { 0xc09945bbb6f11603L,0x57b09dbe41d2801eL,0xfba5202fa97534a8L,\n        0x7fd8ae5fc17b9614L },\n      { 0xa50ba66678308435L,0x9572f77cd3868c4dL,0x0cef7bfd2dd7aab0L,\n        0xe7958e082c7c79ffL } },\n    /* 62 << 175 */\n    { { 0x81262e4225346689L,0x716da290b07c7004L,0x35f911eab7950ee3L,\n        0x6fd72969261d21b5L },\n      { 0x5238980308b640d3L,0x5b0026ee887f12a1L,0x20e21660742e9311L,\n        0x0ef6d5415ff77ff7L } },\n    /* 63 << 175 */\n    { { 0x969127f0f9c41135L,0xf21d60c968a64993L,0x656e5d0ce541875cL,\n        0xf1e0f84ea1d3c233L },\n      { 0x9bcca35906002d60L,0xbe2da60c06191552L,0x5da8bbae61181ec3L,\n        0x9f04b82365806f19L } },\n    /* 64 << 175 */\n    { { 0xf1604a7dd4b79bb8L,0xaee806fb52c878c8L,0x34144f118d47b8e8L,\n        0x72edf52b949f9054L },\n      { 0xebfca84e2127015aL,0x9051d0c09cb7cef3L,0x86e8fe58296deec8L,\n        0x33b2818841010d74L } },\n    /* 0 << 182 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 182 */\n    { { 0x01079383171b445fL,0x9bcf21e38131ad4cL,0x8cdfe205c93987e8L,\n        0xe63f4152c92e8c8fL },\n      { 0x729462a930add43dL,0x62ebb143c980f05aL,0x4f3954e53b06e968L,\n        0xfe1d75ad242cf6b1L } },\n    /* 2 << 182 */\n    { { 0x5f95c6c7af8685c8L,0xd4c1c8ce2f8f01aaL,0xc44bbe322574692aL,\n        0xb8003478d4a4a068L },\n      { 0x7c8fc6e52eca3cdbL,0xea1db16bec04d399L,0xb05bc82e8f2bc5cfL,\n        0x763d517ff44793d2L } },\n    /* 3 << 182 */\n    { { 0x4451c1b808bd98d0L,0x644b1cd46575f240L,0x6907eb337375d270L,\n        0x56c8bebdfa2286bdL },\n      { 0xc713d2acc4632b46L,0x17da427aafd60242L,0x313065b7c95c7546L,\n        0xf8239898bf17a3deL } },\n    /* 4 << 182 */\n    { { 0xf3b7963f4c830320L,0x842c7aa0903203e3L,0xaf22ca0ae7327afbL,\n        0x38e13092967609b6L },\n      { 0x73b8fb62757558f1L,0x3cc3e831f7eca8c1L,0xe4174474f6331627L,\n        0xa77989cac3c40234L } },\n    /* 5 << 182 */\n    { { 0xe5fd17a144a081e0L,0xd797fb7db70e296aL,0x2b472b30481f719cL,\n        0x0e632a98fe6f8c52L },\n      { 0x89ccd116c5f0c284L,0xf51088af2d987c62L,0x2a2bccda4c2de6cfL,\n        0x810f9efef679f0f9L } },\n    /* 6 << 182 */\n    { { 0xb0f394b97ffe4b3eL,0x0b691d21e5fa5d21L,0xb0bd77479dfbbc75L,\n        0xd2830fdafaf78b00L },\n      { 0xf78c249c52434f57L,0x4b1f754598096dabL,0x73bf6f948ff8c0b3L,\n        0x34aef03d454e134cL } },\n    /* 7 << 182 */\n    { { 0xf8d151f4b7ac7ec5L,0xd6ceb95ae50da7d5L,0xa1b492b0dc3a0eb8L,\n        0x75157b69b3dd2863L },\n      { 0xe2c4c74ec5413d62L,0xbe329ff7bc5fc4c7L,0x835a2aea60fa9ddaL,\n        0xf117f5ad7445cb87L } },\n    /* 8 << 182 */\n    { { 0xae8317f4b0166f7aL,0xfbd3e3f7ceec74e6L,0xfdb516ace0874bfdL,\n        0x3d846019c681f3a3L },\n      { 0x0b12ee5c7c1620b0L,0xba68b4dd2b63c501L,0xac03cd326668c51eL,\n        0x2a6279f74e0bcb5bL } },\n    /* 9 << 182 */\n    { { 0x17bd69b06ae85c10L,0x729469791dfdd3a6L,0xd9a032682c078becL,\n        0x41c6a658bfd68a52L },\n      { 0xcdea10240e023900L,0xbaeec121b10d144dL,0x5a600e74058ab8dcL,\n        0x1333af21bb89ccddL } },\n    /* 10 << 182 */\n    { { 0xdf25eae03aaba1f1L,0x2cada16e3b7144cfL,0x657ee27d71ab98bcL,\n        0x99088b4c7a6fc96eL },\n      { 0x05d5c0a03549dbd4L,0x42cbdf8ff158c3acL,0x3fb6b3b087edd685L,\n        0x22071cf686f064d0L } },\n    /* 11 << 182 */\n    { { 0xd2d6721fff2811e5L,0xdb81b703fe7fae8cL,0x3cfb74efd3f1f7bbL,\n        0x0cdbcd7616cdeb5dL },\n      { 0x4f39642a566a808cL,0x02b74454340064d6L,0xfabbadca0528fa6fL,\n        0xe4c3074cd3fc0bb6L } },\n    /* 12 << 182 */\n    { { 0xb32cb8b0b796d219L,0xc3e95f4f34741dd9L,0x8721212568edf6f5L,\n        0x7a03aee4a2b9cb8eL },\n      { 0x0cd3c376f53a89aaL,0x0d8af9b1948a28dcL,0xcf86a3f4902ab04fL,\n        0x8aacb62a7f42002dL } },\n    /* 13 << 182 */\n    { { 0x106985ebf62ffd52L,0xe670b54e5797bf10L,0x4b405209c5e30aefL,\n        0x12c97a204365b5e9L },\n      { 0x104646ce1fe32093L,0x13cb4ff63907a8c9L,0x8b9f30d1d46e726bL,\n        0xe1985e21aba0f499L } },\n    /* 14 << 182 */\n    { { 0xc573dea910a230cdL,0x24f46a93cd30f947L,0xf2623fcfabe2010aL,\n        0x3f278cb273f00e4fL },\n      { 0xed55c67d50b920ebL,0xf1cb9a2d8e760571L,0x7c50d1090895b709L,\n        0x4207cf07190d4369L } },\n    /* 15 << 182 */\n    { { 0x3b027e81c4127fe1L,0xa9f8b9ad3ae9c566L,0x5ab10851acbfbba5L,\n        0xa747d648569556f5L },\n      { 0xcc172b5c2ba97bf7L,0x15e0f77dbcfa3324L,0xa345b7977686279dL,\n        0x5a723480e38003d3L } },\n    /* 16 << 182 */\n    { { 0xfd8e139f8f5fcda8L,0xf3e558c4bdee5bfdL,0xd76cbaf4e33f9f77L,\n        0x3a4c97a471771969L },\n      { 0xda27e84bf6dce6a7L,0xff373d9613e6c2d1L,0xf115193cd759a6e9L,\n        0x3f9b702563d2262cL } },\n    /* 17 << 182 */\n    { { 0xd9764a31317cd062L,0x30779d8e199f8332L,0xd807410616b11b0bL,\n        0x7917ab9f78aeaed8L },\n      { 0xb67a9cbe28fb1d8eL,0x2e313563136eda33L,0x010b7069a371a86cL,\n        0x44d90fa26744e6b7L } },\n    /* 18 << 182 */\n    { { 0x68190867d6b3e243L,0x9fe6cd9d59048c48L,0xb900b02895731538L,\n        0xa012062f32cae04fL },\n      { 0x8107c8bc9399d082L,0x47e8c54a41df12e2L,0x14ba5117b6ef3f73L,\n        0x22260bea81362f0bL } },\n    /* 19 << 182 */\n    { { 0x90ea261e1a18cc20L,0x2192999f2321d636L,0xef64d314e311b6a0L,\n        0xd7401e4c3b54a1f5L },\n      { 0x190199836fbca2baL,0x46ad32938fbffc4bL,0xa142d3f63786bf40L,\n        0xeb5cbc26b67039fcL } },\n    /* 20 << 182 */\n    { { 0x9cb0ae6c252bd479L,0x05e0f88a12b5848fL,0x78f6d2b2a5c97663L,\n        0x6f6e149bc162225cL },\n      { 0xe602235cde601a89L,0xd17bbe98f373be1fL,0xcaf49a5ba8471827L,\n        0x7e1a0a8518aaa116L } },\n    /* 21 << 182 */\n    { { 0x6c833196270580c3L,0x1e233839f1c98a14L,0x67b2f7b4ae34e0a5L,\n        0x47ac8745d8ce7289L },\n      { 0x2b74779a100dd467L,0x274a43374ee50d09L,0x603dcf1383608bc9L,\n        0xcd9da6c3c89e8388L } },\n    /* 22 << 182 */\n    { { 0x2660199f355116acL,0xcc38bb59b6d18eedL,0x3075f31f2f4bc071L,\n        0x9774457f265dc57eL },\n      { 0x06a6a9c8c6db88bbL,0x6429d07f4ec98e04L,0x8d05e57b05ecaa8bL,\n        0x20f140b17872ea7bL } },\n    /* 23 << 182 */\n    { { 0xdf8c0f09ca494693L,0x48d3a020f252e909L,0x4c5c29af57b14b12L,\n        0x7e6fa37dbf47ad1cL },\n      { 0x66e7b50649a0c938L,0xb72c0d486be5f41fL,0x6a6242b8b2359412L,\n        0xcd35c7748e859480L } },\n    /* 24 << 182 */\n    { { 0x12536fea87baa627L,0x58c1fec1f72aa680L,0x6c29b637601e5dc9L,\n        0x9e3c3c1cde9e01b9L },\n      { 0xefc8127b2bcfe0b0L,0x351071022a12f50dL,0x6ccd6cb14879b397L,\n        0xf792f804f8a82f21L } },\n    /* 25 << 182 */\n    { { 0x509d4804a9b46402L,0xedddf85dc10f0850L,0x928410dc4b6208aaL,\n        0xf6229c46391012dcL },\n      { 0xc5a7c41e7727b9b6L,0x289e4e4baa444842L,0x049ba1d9e9a947eaL,\n        0x44f9e47f83c8debcL } },\n    /* 26 << 182 */\n    { { 0xfa77a1fe611f8b8eL,0xfd2e416af518f427L,0xc5fffa70114ebac3L,\n        0xfe57c4e95d89697bL },\n      { 0xfdd053acb1aaf613L,0x31df210fea585a45L,0x318cc10e24985034L,\n        0x1a38efd15f1d6130L } },\n    /* 27 << 182 */\n    { { 0xbf86f2370b1e9e21L,0xb258514d1dbe88aaL,0x1e38a58890c1baf9L,\n        0x2936a01ebdb9b692L },\n      { 0xd576de986dd5b20cL,0xb586bf7170f98ecfL,0xcccf0f12c42d2fd7L,\n        0x8717e61cfb35bd7bL } },\n    /* 28 << 182 */\n    { { 0x8b1e572235e6fc06L,0x3477728f0b3e13d5L,0x150c294daa8a7372L,\n        0xc0291d433bfa528aL },\n      { 0xc6c8bc67cec5a196L,0xdeeb31e45c2e8a7cL,0xba93e244fb6e1c51L,\n        0xb9f8b71b2e28e156L } },\n    /* 29 << 182 */\n    { { 0xce65a287968a2ab9L,0xe3c5ce6946bbcb1fL,0xf8c835b9e7ae3f30L,\n        0x16bbee26ff72b82bL },\n      { 0x665e2017fd42cd22L,0x1e139970f8b1d2a0L,0x125cda2979204932L,\n        0x7aee94a549c3bee5L } },\n    /* 30 << 182 */\n    { { 0x68c7016089821a66L,0xf7c376788f981669L,0xd90829fc48cc3645L,\n        0x346af049d70addfcL },\n      { 0x2057b232370bf29cL,0xf90c73ce42e650eeL,0xe03386eaa126ab90L,\n        0x0e266e7e975a087bL } },\n    /* 31 << 182 */\n    { { 0x80578eb90fca65d9L,0x7e2989ea16af45b8L,0x7438212dcac75a4eL,\n        0x38c7ca394fef36b8L },\n      { 0x8650c494d402676aL,0x26ab5a66f72c7c48L,0x4e6cb426ce3a464eL,\n        0xf8f998962b72f841L } },\n    /* 32 << 182 */\n    { { 0x8c3184911a335cc8L,0x563459ba6a5913e4L,0x1b920d61c7b32919L,\n        0x805ab8b6a02425adL },\n      { 0x2ac512da8d006086L,0x6ca4846abcf5c0fdL,0xafea51d8ac2138d7L,\n        0xcb647545344cd443L } },\n    /* 33 << 182 */\n    { { 0x0429ee8fbd7d9040L,0xee66a2de819b9c96L,0x54f9ec25dea7d744L,\n        0x2ffea642671721bbL },\n      { 0x4f19dbd1114344eaL,0x04304536fd0dbc8bL,0x014b50aa29ec7f91L,\n        0xb5fc22febb06014dL } },\n    /* 34 << 182 */\n    { { 0x60d963a91ee682e0L,0xdf48abc0fe85c727L,0x0cadba132e707c2dL,\n        0xde608d3aa645aeffL },\n      { 0x05f1c28bedafd883L,0x3c362edebd94de1fL,0x8dd0629d13593e41L,\n        0x0a5e736f766d6eafL } },\n    /* 35 << 182 */\n    { { 0xbfa92311f68cf9d1L,0xa4f9ef87c1797556L,0x10d75a1f5601c209L,\n        0x651c374c09b07361L },\n      { 0x49950b5888b5ceadL,0x0ef000586fa9dbaaL,0xf51ddc264e15f33aL,\n        0x1f8b5ca62ef46140L } },\n    /* 36 << 182 */\n    { { 0x343ac0a3ee9523f0L,0xbb75eab2975ea978L,0x1bccf332107387f4L,\n        0x790f92599ab0062eL },\n      { 0xf1a363ad1e4f6a5fL,0x06e08b8462519a50L,0x609151877265f1eeL,\n        0x6a80ca3493ae985eL } },\n    /* 37 << 182 */\n    { { 0x81b29768aaba4864L,0xb13cabf28d52a7d6L,0xb5c363488ead03f1L,\n        0xc932ad9581c7c1c0L },\n      { 0x5452708ecae1e27bL,0x9dac42691b0df648L,0x233e3f0cdfcdb8bcL,\n        0xe6ceccdfec540174L } },\n    /* 38 << 182 */\n    { { 0xbd0d845e95081181L,0xcc8a7920699355d5L,0x111c0f6dc3b375a8L,\n        0xfd95bc6bfd51e0dcL },\n      { 0x4a106a266888523aL,0x4d142bd6cb01a06dL,0x79bfd289adb9b397L,\n        0x0bdbfb94e9863914L } },\n    /* 39 << 182 */\n    { { 0x29d8a2291660f6a6L,0x7f6abcd6551c042dL,0x13039deb0ac3ffe8L,\n        0xa01be628ec8523fbL },\n      { 0x6ea341030ca1c328L,0xc74114bdb903928eL,0x8aa4ff4e9e9144b0L,\n        0x7064091f7f9a4b17L } },\n    /* 40 << 182 */\n    { { 0xa3f4f521e447f2c4L,0x81b8da7a604291f0L,0xd680bc467d5926deL,\n        0x84f21fd534a1202fL },\n      { 0x1d1e31814e9df3d8L,0x1ca4861a39ab8d34L,0x809ddeec5b19aa4aL,\n        0x59f72f7e4d329366L } },\n    /* 41 << 182 */\n    { { 0xa2f93f41386d5087L,0x40bf739cdd67d64fL,0xb449420566702158L,\n        0xc33c65be73b1e178L },\n      { 0xcdcd657c38ca6153L,0x97f4519adc791976L,0xcc7c7f29cd6e1f39L,\n        0x38de9cfb7e3c3932L } },\n    /* 42 << 182 */\n    { { 0xe448eba37b793f85L,0xe9f8dbf9f067e914L,0xc0390266f114ae87L,\n        0x39ed75a7cd6a8e2aL },\n      { 0xadb148487ffba390L,0x67f8cb8b6af9bc09L,0x322c38489c7476dbL,\n        0xa320fecf52a538d6L } },\n    /* 43 << 182 */\n    { { 0xe0493002b2aced2bL,0xdfba1809616bd430L,0x531c4644c331be70L,\n        0xbc04d32e90d2e450L },\n      { 0x1805a0d10f9f142dL,0x2c44a0c547ee5a23L,0x31875a433989b4e3L,\n        0x6b1949fd0c063481L } },\n    /* 44 << 182 */\n    { { 0x2dfb9e08be0f4492L,0x3ff0da03e9d5e517L,0x03dbe9a1f79466a8L,\n        0x0b87bcd015ea9932L },\n      { 0xeb64fc83ab1f58abL,0x6d9598da817edc8aL,0x699cff661d3b67e5L,\n        0x645c0f2992635853L } },\n    /* 45 << 182 */\n    { { 0x253cdd82eabaf21cL,0x82b9602a2241659eL,0x2cae07ec2d9f7091L,\n        0xbe4c720c8b48cd9bL },\n      { 0x6ce5bc036f08d6c9L,0x36e8a997af10bf40L,0x83422d213e10ff12L,\n        0x7b26d3ebbcc12494L } },\n    /* 46 << 182 */\n    { { 0xb240d2d0c9469ad6L,0xc4a11b4d30afa05bL,0x4b604acedd6ba286L,\n        0x184866003ee2864cL },\n      { 0x5869d6ba8d9ce5beL,0x0d8f68c5ff4bfb0dL,0xb69f210b5700cf73L,\n        0x61f6653a6d37c135L } },\n    /* 47 << 182 */\n    { { 0xff3d432b5aff5a48L,0x0d81c4b972ba3a69L,0xee879ae9fa1899efL,\n        0xbac7e2a02d6acafdL },\n      { 0xd6d93f6c1c664399L,0x4c288de15bcb135dL,0x83031dab9dab7cbfL,\n        0xfe23feb03abbf5f0L } },\n    /* 48 << 182 */\n    { { 0x9f1b2466cdedca85L,0x140bb7101a09538cL,0xac8ae8515e11115dL,\n        0x0d63ff676f03f59eL },\n      { 0x755e55517d234afbL,0x61c2db4e7e208fc1L,0xaa9859cef28a4b5dL,\n        0xbdd6d4fc34af030fL } },\n    /* 49 << 182 */\n    { { 0xd1c4a26d3be01cb1L,0x9ba14ffc243aa07cL,0xf95cd3a9b2503502L,\n        0xe379bc067d2a93abL },\n      { 0x3efc18e9d4ca8d68L,0x083558ec80bb412aL,0xd903b9409645a968L,\n        0xa499f0b69ba6054fL } },\n    /* 50 << 182 */\n    { { 0x208b573cb8349abeL,0x3baab3e530b4fc1cL,0x87e978bacb524990L,\n        0x3524194eccdf0e80L },\n      { 0x627117257d4bcc42L,0xe90a3d9bb90109baL,0x3b1bdd571323e1e0L,\n        0xb78e9bd55eae1599L } },\n    /* 51 << 182 */\n    { { 0x0794b7469e03d278L,0x80178605d70e6297L,0x171792f899c97855L,\n        0x11b393eef5a86b5cL },\n      { 0x48ef6582d8884f27L,0xbd44737abf19ba5fL,0x8698de4ca42062c6L,\n        0x8975eb8061ce9c54L } },\n    /* 52 << 182 */\n    { { 0xd50e57c7d7fe71f3L,0x15342190bc97ce38L,0x51bda2de4df07b63L,\n        0xba12aeae200eb87dL },\n      { 0xabe135d2a9b4f8f6L,0x04619d65fad6d99cL,0x4a6683a77994937cL,\n        0x7a778c8b6f94f09aL } },\n    /* 53 << 182 */\n    { { 0x8c50862320a71b89L,0x241a2aed1c229165L,0x352be595aaf83a99L,\n        0x9fbfee7f1562bac8L },\n      { 0xeaf658b95c4017e3L,0x1dc7f9e015120b86L,0xd84f13dd4c034d6fL,\n        0x283dd737eaea3038L } },\n    /* 54 << 182 */\n    { { 0x197f2609cd85d6a2L,0x6ebbc345fae60177L,0xb80f031b4e12fedeL,\n        0xde55d0c207a2186bL },\n      { 0x1fb3e37f24dcdd5aL,0x8d602da57ed191fbL,0x108fb05676023e0dL,\n        0x70178c71459c20c0L } },\n    /* 55 << 182 */\n    { { 0xfad5a3863fe54cf0L,0xa4a3ec4f02bbb475L,0x1aa5ec20919d94d7L,\n        0x5d3b63b5a81e4ab3L },\n      { 0x7fa733d85ad3d2afL,0xfbc586ddd1ac7a37L,0x282925de40779614L,\n        0xfe0ffffbe74a242aL } },\n    /* 56 << 182 */\n    { { 0x3f39e67f906151e5L,0xcea27f5f55e10649L,0xdca1d4e1c17cf7b7L,\n        0x0c326d122fe2362dL },\n      { 0x05f7ac337dd35df3L,0x0c3b7639c396dbdfL,0x0912f5ac03b7db1cL,\n        0x9dea4b705c9ed4a9L } },\n    /* 57 << 182 */\n    { { 0x475e6e53aae3f639L,0xfaba0e7cfc278bacL,0x16f9e2219490375fL,\n        0xaebf9746a5a7ed0aL },\n      { 0x45f9af3ff41ad5d6L,0x03c4623cb2e99224L,0x82c5bb5cb3cf56aaL,\n        0x6431181934567ed3L } },\n    /* 58 << 182 */\n    { { 0xec57f2118be489acL,0x2821895db9a1104bL,0x610dc8756064e007L,\n        0x8e526f3f5b20d0feL },\n      { 0x6e71ca775b645aeeL,0x3d1dcb9f800e10ffL,0x36b51162189cf6deL,\n        0x2c5a3e306bb17353L } },\n    /* 59 << 182 */\n    { { 0xc186cd3e2a6c6fbfL,0xa74516fa4bf97906L,0x5b4b8f4b279d6901L,\n        0x0c4e57b42b573743L },\n      { 0x75fdb229b6e386b6L,0xb46793fd99deac27L,0xeeec47eacf712629L,\n        0xe965f3c4cbc3b2ddL } },\n    /* 60 << 182 */\n    { { 0x8dd1fb83425c6559L,0x7fc00ee60af06fdaL,0xe98c922533d956dfL,\n        0x0f1ef3354fbdc8a2L },\n      { 0x2abb5145b79b8ea2L,0x40fd2945bdbff288L,0x6a814ac4d7185db7L,\n        0xc4329d6fc084609aL } },\n    /* 61 << 182 */\n    { { 0xc9ba7b52ed1be45dL,0x891dd20de4cd2c74L,0x5a4d4a7f824139b1L,\n        0x66c17716b873c710L },\n      { 0x5e5bc1412843c4e0L,0xd5ac4817b97eb5bfL,0xc0f8af54450c95c7L,\n        0xc91b3fa0318406c5L } },\n    /* 62 << 182 */\n    { { 0x360c340aab9d97f8L,0xfb57bd0790a2d611L,0x4339ae3ca6a6f7e5L,\n        0x9c1fcd2a2feb8a10L },\n      { 0x972bcca9c7ea7432L,0x1b0b924c308076f6L,0x80b2814a2a5b4ca5L,\n        0x2f78f55b61ef3b29L } },\n    /* 63 << 182 */\n    { { 0xf838744ac18a414fL,0xc611eaae903d0a86L,0x94dabc162a453f55L,\n        0xe6f2e3da14efb279L },\n      { 0x5b7a60179320dc3cL,0x692e382f8df6b5a4L,0x3f5e15e02d40fa90L,\n        0xc87883ae643dd318L } },\n    /* 64 << 182 */\n    { { 0x511053e453544774L,0x834d0ecc3adba2bcL,0x4215d7f7bae371f5L,\n        0xfcfd57bf6c8663bcL },\n      { 0xded2383dd6901b1dL,0x3b49fbb4b5587dc3L,0xfd44a08d07625f62L,\n        0x3ee4d65b9de9b762L } },\n    /* 0 << 189 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 189 */\n    { { 0x64e5137d0d63d1faL,0x658fc05202a9d89fL,0x4889487450436309L,\n        0xe9ae30f8d598da61L },\n      { 0x2ed710d1818baf91L,0xe27e9e068b6a0c20L,0x1e28dcfb1c1a6b44L,\n        0x883acb64d6ac57dcL } },\n    /* 2 << 189 */\n    { { 0x8735728dc2c6ff70L,0x79d6122fc5dc2235L,0x23f5d00319e277f9L,\n        0x7ee84e25dded8cc7L },\n      { 0x91a8afb063cd880aL,0x3f3ea7c63574af60L,0x0cfcdc8402de7f42L,\n        0x62d0792fb31aa152L } },\n    /* 3 << 189 */\n    { { 0x8e1b4e438a5807ceL,0xad283893e4109a7eL,0xc30cc9cbafd59ddaL,\n        0xf65f36c63d8d8093L },\n      { 0xdf31469ea60d32b2L,0xee93df4b3e8191c8L,0x9c1017c5355bdeb5L,\n        0xd26231858616aa28L } },\n    /* 4 << 189 */\n    { { 0xb02c83f9dec31a21L,0x988c8b236ad9d573L,0x53e983aea57be365L,\n        0xe968734d646f834eL },\n      { 0x9137ea8f5da6309bL,0x10f3a624c1f1ce16L,0x782a9ea2ca440921L,\n        0xdf94739e5b46f1b5L } },\n    /* 5 << 189 */\n    { { 0x9f9be006cce85c9bL,0x360e70d6a4c7c2d3L,0x2cd5beeaaefa1e60L,\n        0x64cf63c08c3d2b6dL },\n      { 0xfb107fa3e1cf6f90L,0xb7e937c6d5e044e6L,0x74e8ca78ce34db9fL,\n        0x4f8b36c13e210bd0L } },\n    /* 6 << 189 */\n    { { 0x1df165a434a35ea8L,0x3418e0f74d4412f6L,0x5af1f8af518836c3L,\n        0x42ceef4d130e1965L },\n      { 0x5560ca0b543a1957L,0xc33761e5886cb123L,0x66624b1ffe98ed30L,\n        0xf772f4bf1090997dL } },\n    /* 7 << 189 */\n    { { 0xf4e540bb4885d410L,0x7287f8109ba5f8d7L,0x22d0d865de98dfb1L,\n        0x49ff51a1bcfbb8a3L },\n      { 0xb6b6fa536bc3012eL,0x3d31fd72170d541dL,0x8018724f4b0f4966L,\n        0x79e7399f87dbde07L } },\n    /* 8 << 189 */\n    { { 0x56f8410ef4f8b16aL,0x97241afec47b266aL,0x0a406b8e6d9c87c1L,\n        0x803f3e02cd42ab1bL },\n      { 0x7f0309a804dbec69L,0xa83b85f73bbad05fL,0xc6097273ad8e197fL,\n        0xc097440e5067adc1L } },\n    /* 9 << 189 */\n    { { 0x730eafb63524ff16L,0xd7f9b51e823fc6ceL,0x27bd0d32443e4ac0L,\n        0x40c59ad94d66f217L },\n      { 0x6c33136f17c387a4L,0x5043b8d5eb86804dL,0x74970312675a73c9L,\n        0x838fdb31f16669b6L } },\n    /* 10 << 189 */\n    { { 0xc507b6dd418e7dddL,0x39888d93472f19d6L,0x7eae26be0c27eb4dL,\n        0x17b53ed3fbabb884L },\n      { 0xfc27021b2b01ae4fL,0x88462e87cf488682L,0xbee096ec215e2d87L,\n        0xeb2fea9ad242e29bL } },\n    /* 11 << 189 */\n    { { 0x5d985b5fb821fc28L,0x89d2e197dc1e2ad2L,0x55b566b89030ba62L,\n        0xe3fd41b54f41b1c6L },\n      { 0xb738ac2eb9a96d61L,0x7f8567ca369443f4L,0x8698622df803a440L,\n        0x2b5862368fe2f4dcL } },\n    /* 12 << 189 */\n    { { 0xbbcc00c756b95bceL,0x5ec03906616da680L,0x79162ee672214252L,\n        0x43132b6386a892d2L },\n      { 0x4bdd3ff22f3263bfL,0xd5b3733c9cd0a142L,0x592eaa8244415ccbL,\n        0x663e89248d5474eaL } },\n    /* 13 << 189 */\n    { { 0x8058a25e5236344eL,0x82e8df9dbda76ee6L,0xdcf6efd811cc3d22L,\n        0x00089cda3b4ab529L },\n      { 0x91d3a071bd38a3dbL,0x4ea97fc0ef72b925L,0x0c9fc15bea3edf75L,\n        0x5a6297cda4348ed3L } },\n    /* 14 << 189 */\n    { { 0x0d38ab35ce7c42d4L,0x9fd493ef82feab10L,0x46056b6d82111b45L,\n        0xda11dae173efc5c3L },\n      { 0xdc7402785545a7fbL,0xbdb2601c40d507e6L,0x121dfeeb7066fa58L,\n        0x214369a839ae8c2aL } },\n    /* 15 << 189 */\n    { { 0x195709cb06e0956cL,0x4c9d254f010cd34bL,0xf51e13f70471a532L,\n        0xe19d67911e73054dL },\n      { 0xf702a628db5c7be3L,0xc7141218b24dde05L,0xdc18233cf29b2e2eL,\n        0x3a6bd1e885342dbaL } },\n    /* 16 << 189 */\n    { { 0x3f747fa0b311898cL,0xe2a272e4cd0eac65L,0x4bba5851f914d0bcL,\n        0x7a1a9660c4a43ee3L },\n      { 0xe5a367cea1c8cde9L,0x9d958ba97271abe3L,0xf3ff7eb63d1615cdL,\n        0xa2280dcef5ae20b0L } },\n    /* 17 << 189 */\n    { { 0x56dba5c1cf640147L,0xea5a2e3d5e83d118L,0x04cd6b6dda24c511L,\n        0x1c0f4671e854d214L },\n      { 0x91a6b7a969565381L,0xdc966240decf1f5bL,0x1b22d21cfcf5d009L,\n        0x2a05f6419021dbd5L } },\n    /* 18 << 189 */\n    { { 0x8c0ed566d4312483L,0x5179a95d643e216fL,0xcc185fec17044493L,\n        0xb306333954991a21L },\n      { 0xd801ecdb0081a726L,0x0149b0c64fa89bbbL,0xafe9065a4391b6b9L,\n        0xedc92786d633f3a3L } },\n    /* 19 << 189 */\n    { { 0xe408c24aae6a8e13L,0x85833fde9f3897abL,0x43800e7ed81a0715L,\n        0xde08e346b44ffc5fL },\n      { 0x7094184ccdeff2e0L,0x49f9387b165eaed1L,0x635d6129777c468aL,\n        0x8c0dcfd1538c2dd8L } },\n    /* 20 << 189 */\n    { { 0xd6d9d9e37a6a308bL,0x623758304c2767d3L,0x874a8bc6f38cbeb6L,\n        0xd94d3f1accb6fd9eL },\n      { 0x92a9735bba21f248L,0x272ad0e56cd1efb0L,0x7437b69c05b03284L,\n        0xe7f047026948c225L } },\n    /* 21 << 189 */\n    { { 0x8a56c04acba2ececL,0x0c181270e3a73e41L,0x6cb34e9d03e93725L,\n        0xf77c8713496521a9L },\n      { 0x94569183fa7f9f90L,0xf2e7aa4c8c9707adL,0xced2c9ba26c1c9a3L,\n        0x9109fe9640197507L } },\n    /* 22 << 189 */\n    { { 0x9ae868a9e9adfe1cL,0x3984403d314e39bbL,0xb5875720f2fe378fL,\n        0x33f901e0ba44a628L },\n      { 0xea1125fe3652438cL,0xae9ec4e69dd1f20bL,0x1e740d9ebebf7fbdL,\n        0x6dbd3ddc42dbe79cL } },\n    /* 23 << 189 */\n    { { 0x62082aecedd36776L,0xf612c478e9859039L,0xa493b201032f7065L,\n        0xebd4d8f24ff9b211L },\n      { 0x3f23a0aaaac4cb32L,0xea3aadb715ed4005L,0xacf17ea4afa27e63L,\n        0x56125c1ac11fd66cL } },\n    /* 24 << 189 */\n    { { 0x266344a43794f8dcL,0xdcca923a483c5c36L,0x2d6b6bbf3f9d10a0L,\n        0xb320c5ca81d9bdf3L },\n      { 0x620e28ff47b50a95L,0x933e3b01cef03371L,0xf081bf8599100153L,\n        0x183be9a0c3a8c8d6L } },\n    /* 25 << 189 */\n    { { 0x4e3ddc5ad6bbe24dL,0xc6c7463053843795L,0x78193dd765ec2d4cL,\n        0xb8df26cccd3c89b2L },\n      { 0x98dbe3995a483f8dL,0x72d8a9577dd3313aL,0x65087294ab0bd375L,\n        0xfcd892487c259d16L } },\n    /* 26 << 189 */\n    { { 0x8a9443d77613aa81L,0x8010080085fe6584L,0x70fc4dbc7fb10288L,\n        0xf58280d3e86beee8L },\n      { 0x14fdd82f7c978c38L,0xdf1204c10de44d7bL,0xa08a1c844160252fL,\n        0x591554cac17646a5L } },\n    /* 27 << 189 */\n    { { 0x214a37d6a05bd525L,0x48d5f09b07957b3cL,0x0247cdcbd7109bc9L,\n        0x40f9e4bb30599ce7L },\n      { 0xc325fa03f46ad2ecL,0x00f766cfc3e3f9eeL,0xab556668d43a4577L,\n        0x68d30a613ee03b93L } },\n    /* 28 << 189 */\n    { { 0x7ddc81ea77b46a08L,0xcf5a6477c7480699L,0x43a8cb346633f683L,\n        0x1b867e6b92363c60L },\n      { 0x439211141f60558eL,0xcdbcdd632f41450eL,0x7fc04601cc630e8bL,\n        0xea7c66d597038b43L } },\n    /* 29 << 189 */\n    { { 0x7259b8a504e99fd8L,0x98a8dd124785549aL,0x0e459a7c840552e1L,\n        0xcdfcf4d04bb0909eL },\n      { 0x34a86db253758da7L,0xe643bb83eac997e1L,0x96400bd7530c5b7eL,\n        0x9f97af87b41c8b52L } },\n    /* 30 << 189 */\n    { { 0x34fc8820fbeee3f9L,0x93e5349049091afdL,0x764b9be59a31f35cL,\n        0x71f3786457e3d924L },\n      { 0x02fb34e0943aa75eL,0xa18c9c58ab8ff6e4L,0x080f31b133cf0d19L,\n        0x5c9682db083518a7L } },\n    /* 31 << 189 */\n    { { 0x873d4ca6b709c3deL,0x64a842623575b8f0L,0x6275da1f020154bbL,\n        0x97678caad17cf1abL },\n      { 0x8779795f951a95c3L,0xdd35b16350fccc08L,0x3270962733d8f031L,\n        0x3c5ab10a498dd85cL } },\n    /* 32 << 189 */\n    { { 0xb6c185c341dca566L,0x7de7fedad8622aa3L,0x99e84d92901b6dfbL,\n        0x30a02b0e7c4ad288L },\n      { 0xc7c81daa2fd3cf36L,0xd1319547df89e59fL,0xb2be8184cd496733L,\n        0xd5f449eb93d3412bL } },\n    /* 33 << 189 */\n    { { 0x7ea41b1b25fe531dL,0xf97974326a1d5646L,0x86067f722bde501aL,\n        0xf91481c00c85e89cL },\n      { 0xca8ee465f8b05bc6L,0x1844e1cf02e83cdaL,0xca82114ab4dbe33bL,\n        0x0f9f87694eabfde2L } },\n    /* 34 << 189 */\n    { { 0x4936b1c038b27fe2L,0x63b6359baba402dfL,0x40c0ea2f656bdbabL,\n        0x9c992a896580c39cL },\n      { 0x600e8f152a60aed1L,0xeb089ca4e0bf49dfL,0x9c233d7d2d42d99aL,\n        0x648d3f954c6bc2faL } },\n    /* 35 << 189 */\n    { { 0xdcc383a8e1add3f3L,0xf42c0c6a4f64a348L,0x2abd176f0030dbdbL,\n        0x4de501a37d6c215eL },\n      { 0x4a107c1f4b9a64bcL,0xa77f0ad32496cd59L,0xfb78ac627688dffbL,\n        0x7025a2ca67937d8eL } },\n    /* 36 << 189 */\n    { { 0xfde8b2d1d1a8f4e7L,0xf5b3da477354927cL,0xe48606a3d9205735L,\n        0xac477cc6e177b917L },\n      { 0xfb1f73d2a883239aL,0xe12572f6cc8b8357L,0x9d355e9cfb1f4f86L,\n        0x89b795f8d9f3ec6eL } },\n    /* 37 << 189 */\n    { { 0x27be56f1b54398dcL,0x1890efd73fedeed5L,0x62f77f1f9c6d0140L,\n        0x7ef0e314596f0ee4L },\n      { 0x50ca6631cc61dab3L,0x4a39801df4866e4fL,0x66c8d032ae363b39L,\n        0x22c591e52ead66aaL } },\n    /* 38 << 189 */\n    { { 0x954ba308de02a53eL,0x2a6c060fd389f357L,0xe6cfcde8fbf40b66L,\n        0x8e02fc56c6340ce1L },\n      { 0xe495779573adb4baL,0x7b86122ca7b03805L,0x63f835120c8e6fa6L,\n        0x83660ea0057d7804L } },\n    /* 39 << 189 */\n    { { 0xbad7910521ba473cL,0xb6c50beeded5389dL,0xee2caf4daa7c9bc0L,\n        0xd97b8de48c4e98a7L },\n      { 0xa9f63e70ab3bbddbL,0x3898aabf2597815aL,0x7659af89ac15b3d9L,\n        0xedf7725b703ce784L } },\n    /* 40 << 189 */\n    { { 0x25470fabe085116bL,0x04a4337587285310L,0x4e39187ee2bfd52fL,\n        0x36166b447d9ebc74L },\n      { 0x92ad433cfd4b322cL,0x726aa817ba79ab51L,0xf96eacd8c1db15ebL,\n        0xfaf71e910476be63L } },\n    /* 41 << 189 */\n    { { 0xdd69a640641fad98L,0xb799591829622559L,0x03c6daa5de4199dcL,\n        0x92cadc97ad545eb4L },\n      { 0x1028238b256534e4L,0x73e80ce68595409aL,0x690d4c66d05dc59bL,\n        0xc95f7b8f981dee80L } },\n    /* 42 << 189 */\n    { { 0xf4337014d856ac25L,0x441bd9ddac524dcaL,0x640b3d855f0499f5L,\n        0x39cf84a9d5fda182L },\n      { 0x04e7b055b2aa95a0L,0x29e33f0a0ddf1860L,0x082e74b5423f6b43L,\n        0x217edeb90aaa2b0fL } },\n    /* 43 << 189 */\n    { { 0x58b83f3583cbea55L,0xc485ee4dbc185d70L,0x833ff03b1e5f6992L,\n        0xb5b9b9cccf0c0dd5L },\n      { 0x7caaee8e4e9e8a50L,0x462e907b6269dafdL,0x6ed5cee9fbe791c6L,\n        0x68ca3259ed430790L } },\n    /* 44 << 189 */\n    { { 0x2b72bdf213b5ba88L,0x60294c8a35ef0ac4L,0x9c3230ed19b99b08L,\n        0x560fff176c2589aaL },\n      { 0x552b8487d6770374L,0xa373202d9a56f685L,0xd3e7f90745f175d9L,\n        0x3c2f315fd080d810L } },\n    /* 45 << 189 */\n    { { 0x1130e9dd7b9520e8L,0xc078f9e20af037b5L,0x38cd2ec71e9c104cL,\n        0x0f684368c472fe92L },\n      { 0xd3f1b5ed6247e7efL,0xb32d33a9396dfe21L,0x46f59cf44a9aa2c2L,\n        0x69cd5168ff0f7e41L } },\n    /* 46 << 189 */\n    { { 0x3f59da0f4b3234daL,0xcf0b0235b4579ebeL,0x6d1cbb256d2476c7L,\n        0x4f0837e69dc30f08L },\n      { 0x9a4075bb906f6e98L,0x253bb434c761e7d1L,0xde2e645f6e73af10L,\n        0xb89a40600c5f131cL } },\n    /* 47 << 189 */\n    { { 0xd12840c5b8cc037fL,0x3d093a5b7405bb47L,0x6202c253206348b8L,\n        0xbf5d57fcc55a3ca7L },\n      { 0x89f6c90c8c3bef48L,0x23ac76235a0a960aL,0xdfbd3d6b552b42abL,\n        0x3ef22458132061f6L } },\n    /* 48 << 189 */\n    { { 0xd74e9bdac97e6516L,0x88779360c230f49eL,0xa6ec1de31e74ea49L,\n        0x581dcee53fb645a2L },\n      { 0xbaef23918f483f14L,0x6d2dddfcd137d13bL,0x54cde50ed2743a42L,\n        0x89a34fc5e4d97e67L } },\n    /* 49 << 189 */\n    { { 0x13f1f5b312e08ce5L,0xa80540b8a7f0b2caL,0x854bcf7701982805L,\n        0xb8653ffd233bea04L },\n      { 0x8e7b878702b0b4c9L,0x2675261f9acb170aL,0x061a9d90930c14e5L,\n        0xb59b30e0def0abeaL } },\n    /* 50 << 189 */\n    { { 0x1dc19ea60200ec7dL,0xb6f4a3f90bce132bL,0xb8d5de90f13e27e0L,\n        0xbaee5ef01fade16fL },\n      { 0x6f406aaae4c6cf38L,0xab4cfe06d1369815L,0x0dcffe87efd550c6L,\n        0x9d4f59c775ff7d39L } },\n    /* 51 << 189 */\n    { { 0xb02553b151deb6adL,0x812399a4b1877749L,0xce90f71fca6006e1L,\n        0xc32363a6b02b6e77L },\n      { 0x02284fbedc36c64dL,0x86c81e31a7e1ae61L,0x2576c7e5b909d94aL,\n        0x8b6f7d02818b2bb0L } },\n    /* 52 << 189 */\n    { { 0xeca3ed0756faa38aL,0xa3790e6c9305bb54L,0xd784eeda7bc73061L,\n        0xbd56d3696dd50614L },\n      { 0xd6575949229a8aa9L,0xdcca8f474595ec28L,0x814305c106ab4fe6L,\n        0xc8c3976824f43f16L } },\n    /* 53 << 189 */\n    { { 0xe2a45f36523f2b36L,0x995c6493920d93bbL,0xf8afdab790f1632bL,\n        0x79ebbecd1c295954L },\n      { 0xc7bb3ddb79592f48L,0x67216a7b5f88e998L,0xd91f098bbc01193eL,\n        0xf7d928a5b1db83fcL } },\n    /* 54 << 189 */\n    { { 0x55e38417e991f600L,0x2a91113e2981a934L,0xcbc9d64806b13bdeL,\n        0xb011b6ac0755ff44L },\n      { 0x6f4cb518045ec613L,0x522d2d31c2f5930aL,0x5acae1af382e65deL,\n        0x5764306727bc966fL } },\n    /* 55 << 189 */\n    { { 0x5e12705d1c7193f0L,0xf0f32f473be8858eL,0x785c3d7d96c6dfc7L,\n        0xd75b4a20bf31795dL },\n      { 0x91acf17b342659d4L,0xe596ea3444f0378fL,0x4515708fce52129dL,\n        0x17387e1e79f2f585L } },\n    /* 56 << 189 */\n    { { 0x72cfd2e949dee168L,0x1ae052233e2af239L,0x009e75be1d94066aL,\n        0x6cca31c738abf413L },\n      { 0xb50bd61d9bc49908L,0x4a9b4a8cf5e2bc1eL,0xeb6cc5f7946f83acL,\n        0x27da93fcebffab28L } },\n    /* 57 << 189 */\n    { { 0xea314c964821c8c5L,0x8de49deda83c15f4L,0x7a64cf207af33004L,\n        0x45f1bfebc9627e10L },\n      { 0x878b062654b9df60L,0x5e4fdc3ca95c0b33L,0xe54a37cac2035d8eL,\n        0x9087cda980f20b8cL } },\n    /* 58 << 189 */\n    { { 0x36f61c238319ade4L,0x766f287ade8cfdf8L,0x48821948346f3705L,\n        0x49a7b85316e4f4a2L },\n      { 0xb9b3f8a75cedadfdL,0x8f5628158db2a815L,0xc0b7d55401f68f95L,\n        0x12971e27688a208eL } },\n    /* 59 << 189 */\n    { { 0xc9f8b696d0ff34fcL,0x20824de21222718cL,0x7213cf9f0c95284dL,\n        0xe2ad741bdc158240L },\n      { 0x0ee3a6df54043ccfL,0x16ff479bd84412b3L,0xf6c74ee0dfc98af0L,\n        0xa78a169f52fcd2fbL } },\n    /* 60 << 189 */\n    { { 0xd8ae874699c930e9L,0x1d33e85849e117a5L,0x7581fcb46624759fL,\n        0xde50644f5bedc01dL },\n      { 0xbeec5d00caf3155eL,0x672d66acbc73e75fL,0x86b9d8c6270b01dbL,\n        0xd249ef8350f55b79L } },\n    /* 61 << 189 */\n    { { 0x6131d6d473978fe3L,0xcc4e4542754b00a1L,0x4e05df0557dfcfe9L,\n        0x94b29cdd51ef6bf0L },\n      { 0xe4530cff9bc7edf2L,0x8ac236fdd3da65f3L,0x0faf7d5fc8eb0b48L,\n        0x4d2de14c660eb039L } },\n    /* 62 << 189 */\n    { { 0xc006bba760430e54L,0x10a2d0d6da3289abL,0x9c037a5dd7979c59L,\n        0x04d1f3d3a116d944L },\n      { 0x9ff224738a0983cdL,0x28e25b38c883cabbL,0xe968dba547a58995L,\n        0x2c80b505774eebdfL } },\n    /* 63 << 189 */\n    { { 0xee763b714a953bebL,0x502e223f1642e7f6L,0x6fe4b64161d5e722L,\n        0x9d37c5b0dbef5316L },\n      { 0x0115ed70f8330bc7L,0x139850e675a72789L,0x27d7faecffceccc2L,\n        0x3016a8604fd9f7f6L } },\n    /* 64 << 189 */\n    { { 0xc492ec644cd8f64cL,0x58a2d790279d7b51L,0x0ced1fc51fc75256L,\n        0x3e658aed8f433017L },\n      { 0x0b61942e05da59ebL,0xba3d60a30ddc3722L,0x7c311cd1742e7f87L,\n        0x6473ffeef6b01b6eL } },\n    /* 0 << 196 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 196 */\n    { { 0x8303604f692ac542L,0xf079ffe1227b91d3L,0x19f63e6315aaf9bdL,\n        0xf99ee565f1f344fbL },\n      { 0x8a1d661fd6219199L,0x8c883bc6d48ce41cL,0x1065118f3c74d904L,\n        0x713889ee0faf8b1bL } },\n    /* 2 << 196 */\n    { { 0x972b3f8f81a1b3beL,0x4f3ce145ce2764a0L,0xe2d0f1cc28c4f5f7L,\n        0xdeee0c0dc7f3985bL },\n      { 0x7df4adc0d39e25c3L,0x40619820c467a080L,0x440ebc9361cf5a58L,\n        0x527729a6422ad600L } },\n    /* 3 << 196 */\n    { { 0xca6c0937b1b76ba6L,0x1a2eab854d2026dcL,0xb1715e1519d9ae0aL,\n        0xf1ad9199bac4a026L },\n      { 0x35b3dfb807ea7b0eL,0xedf5496f3ed9eb89L,0x8932e5ff2d6d08abL,\n        0xf314874e25bd2731L } },\n    /* 4 << 196 */\n    { { 0xefb26a753f73f449L,0x1d1c94f88d44fc79L,0x49f0fbc53bc0dc4dL,\n        0xb747ea0b3698a0d0L },\n      { 0x5218c3fe228d291eL,0x35b804b543c129d6L,0xfac859b8d1acc516L,\n        0x6c10697d95d6e668L } },\n    /* 5 << 196 */\n    { { 0xc38e438f0876fd4eL,0x45f0c30783d2f383L,0x203cc2ecb10934cbL,\n        0x6a8f24392c9d46eeL },\n      { 0xf16b431b65ccde7bL,0x41e2cd1827e76a6fL,0xb9c8cf8f4e3484d7L,\n        0x64426efd8315244aL } },\n    /* 6 << 196 */\n    { { 0x1c0a8e44fc94dea3L,0x34c8cdbfdad6a0b0L,0x919c384004113cefL,\n        0xfd32fba415490ffaL },\n      { 0x58d190f6795dcfb7L,0xfef01b0383588bafL,0x9e6d1d63ca1fc1c0L,\n        0x53173f96f0a41ac9L } },\n    /* 7 << 196 */\n    { { 0x2b1d402aba16f73bL,0x2fb310148cf9b9fcL,0x2d51e60e446ef7bfL,\n        0xc731021bb91e1745L },\n      { 0x9d3b47244fee99d4L,0x4bca48b6fac5c1eaL,0x70f5f514bbea9af7L,\n        0x751f55a5974c283aL } },\n    /* 8 << 196 */\n    { { 0x6e30251acb452fdbL,0x31ee696550f30650L,0xb0b3e508933548d9L,\n        0xb8949a4ff4b0ef5bL },\n      { 0x208b83263c88f3bdL,0xab147c30db1d9989L,0xed6515fd44d4df03L,\n        0x17a12f75e72eb0c5L } },\n    /* 9 << 196 */\n    { { 0x3b59796d36cf69dbL,0x1219eee956670c18L,0xfe3341f77a070d8eL,\n        0x9b70130ba327f90cL },\n      { 0x36a324620ae18e0eL,0x2021a62346c0a638L,0x251b5817c62eb0d4L,\n        0x87bfbcdf4c762293L } },\n    /* 10 << 196 */\n    { { 0xf78ab505cdd61d64L,0x8c7a53fcc8c18857L,0xa653ce6f16147515L,\n        0x9c923aa5ea7d52d5L },\n      { 0xc24709cb5c18871fL,0x7d53bec873b3cc74L,0x59264afffdd1d4c4L,\n        0x5555917e240da582L } },\n    /* 11 << 196 */\n    { { 0xcae8bbda548f5a0eL,0x1910eaba3bbfbbe1L,0xae5796857677afc3L,\n        0x49ea61f173ff0b5cL },\n      { 0x786554784f7c3922L,0x95d337cd20c68eefL,0x68f1e1e5df779ab9L,\n        0x14b491b0b5cf69a8L } },\n    /* 12 << 196 */\n    { { 0x7a6cbbe028e3fe89L,0xe7e1fee4c5aac0ebL,0x7f47eda5697e5140L,\n        0x4f450137b454921fL },\n      { 0xdb625f8495cd8185L,0x74be0ba1cdb2e583L,0xaee4fd7cdd5e6de4L,\n        0x4251437de8101739L } },\n    /* 13 << 196 */\n    { { 0x686d72a0ac620366L,0x4be3fb9cb6d59344L,0x6e8b44e7a1eb75b9L,\n        0x84e39da391a5c10cL },\n      { 0x37cc1490b38f0409L,0x029519432c2ade82L,0x9b6887831190a2d8L,\n        0x25627d14231182baL } },\n    /* 14 << 196 */\n    { { 0x6eb550aa658a6d87L,0x1405aaa7cf9c7325L,0xd147142e5c8748c9L,\n        0x7f637e4f53ede0e0L },\n      { 0xf8ca277614ffad2cL,0xe58fb1bdbafb6791L,0x17158c23bf8f93fcL,\n        0x7f15b3730a4a4655L } },\n    /* 15 << 196 */\n    { { 0x39d4add2d842ca72L,0xa71e43913ed96305L,0x5bb09cbe6700be14L,\n        0x68d69d54d8befcf6L },\n      { 0xa45f536737183bcfL,0x7152b7bb3370dff7L,0xcf887baabf12525bL,\n        0xe7ac7bddd6d1e3cdL } },\n    /* 16 << 196 */\n    { { 0x25914f7881fdad90L,0xcf638f560d2cf6abL,0xb90bc03fcc054de5L,\n        0x932811a718b06350L },\n      { 0x2f00b3309bbd11ffL,0x76108a6fb4044974L,0x801bb9e0a851d266L,\n        0x0dd099bebf8990c1L } },\n    /* 17 << 196 */\n    { { 0x58c5aaaaabe32986L,0x0fe9dd2a50d59c27L,0x84951ff48d307305L,\n        0x6c23f82986529b78L },\n      { 0x50bb22180b136a79L,0x7e2174de77a20996L,0x6f00a4b9c0bb4da6L,\n        0x89a25a17efdde8daL } },\n    /* 18 << 196 */\n    { { 0xf728a27ec11ee01dL,0xf900553ae5f10dfbL,0x189a83c802ec893cL,\n        0x3ca5bdc123f66d77L },\n      { 0x9878153797eada9fL,0x59c50ab310256230L,0x346042d9323c69b3L,\n        0x1b715a6d2c460449L } },\n    /* 19 << 196 */\n    { { 0xa41dd4766ae06e0bL,0xcdd7888e9d42e25fL,0x0f395f7456b25a20L,\n        0xeadfe0ae8700e27eL },\n      { 0xb09d52a969950093L,0x3525d9cb327f8d40L,0xb8235a9467df886aL,\n        0x77e4b0dd035faec2L } },\n    /* 20 << 196 */\n    { { 0x115eb20a517d7061L,0x77fe34336c2df683L,0x6870ddc7cdc6fc67L,\n        0xb16105880b87de83L },\n      { 0x343584cad9c4ddbeL,0xb3164f1c3d754be2L,0x0731ed3ac1e6c894L,\n        0x26327dec4f6b904cL } },\n    /* 21 << 196 */\n    { { 0x9d49c6de97b5cd32L,0x40835daeb5eceecdL,0xc66350edd9ded7feL,\n        0x8aeebb5c7a678804L },\n      { 0x51d42fb75b8ee9ecL,0xd7a17bdd8e3ca118L,0x40d7511a2ef4400eL,\n        0xc48990ac875a66f4L } },\n    /* 22 << 196 */\n    { { 0x8de07d2a2199e347L,0xbee755562a39e051L,0x56918786916e51dcL,\n        0xeb1913134a2d89ecL },\n      { 0x6679610d37d341edL,0x434fbb4156d51c2bL,0xe54b7ee7d7492dbaL,\n        0xaa33a79a59021493L } },\n    /* 23 << 196 */\n    { { 0x49fc5054e4bd6d3dL,0x09540f045ab551d0L,0x8acc90854942d3a6L,\n        0x231af02f2d28323bL },\n      { 0x93458cac0992c163L,0x1fef8e71888e3bb4L,0x27578da5be8c268cL,\n        0xcc8be792e805ec00L } },\n    /* 24 << 196 */\n    { { 0x29267baec61c3855L,0xebff429d58c1fd3bL,0x22d886c08c0b93b8L,\n        0xca5e00b22ddb8953L },\n      { 0xcf330117c3fed8b7L,0xd49ac6fa819c01f6L,0x6ddaa6bd3c0fbd54L,\n        0x917430688049a2cfL } },\n    /* 25 << 196 */\n    { { 0xd67f981eaff2ef81L,0xc3654d352818ae80L,0x81d050441b2aa892L,\n        0x2db067bf3d099328L },\n      { 0xe7c79e86703dcc97L,0xe66f9b37e133e215L,0xcdf119a6e39a7a5cL,\n        0x47c60de3876f1b61L } },\n    /* 26 << 196 */\n    { { 0x6e405939d860f1b2L,0x3e9a1dbcf5ed4d4aL,0x3f23619ec9b6bcbdL,\n        0x5ee790cf734e4497L },\n      { 0xf0a834b15bdaf9bbL,0x02cedda74ca295f0L,0x4619aa2bcb8e378cL,\n        0xe5613244cc987ea4L } },\n    /* 27 << 196 */\n    { { 0x0bc022cc76b23a50L,0x4a2793ad0a6c21ceL,0x3832878089cac3f5L,\n        0x29176f1bcba26d56L },\n      { 0x062961874f6f59ebL,0x86e9bca98bdc658eL,0x2ca9c4d357e30402L,\n        0x5438b216516a09bbL } },\n    /* 28 << 196 */\n    { { 0x0a6a063c7672765aL,0x37a3ce640547b9bfL,0x42c099c898b1a633L,\n        0xb5ab800d05ee6961L },\n      { 0xf1963f5911a5acd6L,0xbaee615746201063L,0x36d9a649a596210aL,\n        0xaed043631ba7138cL } },\n    /* 29 << 196 */\n    { { 0xcf817d1ca4a82b76L,0x5586960ef3806be9L,0x7ab67c8909dc6bb5L,\n        0x52ace7a0114fe7ebL },\n      { 0xcd987618cbbc9b70L,0x4f06fd5a604ca5e1L,0x90af14ca6dbde133L,\n        0x1afe4322948a3264L } },\n    /* 30 << 196 */\n    { { 0xa70d2ca6c44b2c6cL,0xab7267990ef87dfeL,0x310f64dc2e696377L,\n        0x49b42e684c8126a0L },\n      { 0x0ea444c3cea0b176L,0x53a8ddf7cb269182L,0xf3e674ebbbba9dcbL,\n        0x0d2878a8d8669d33L } },\n    /* 31 << 196 */\n    { { 0x04b935d5d019b6a3L,0xbb5cf88e406f1e46L,0xa1912d165b57c111L,\n        0x9803fc2119ebfd78L },\n      { 0x4f231c9ec07764a9L,0xd93286eeb75bd055L,0x83a9457d8ee6c9deL,\n        0x046959156087ec90L } },\n    /* 32 << 196 */\n    { { 0x14c6dd8a58d6cd46L,0x9cb633b58e6634d2L,0xc1305047f81bc328L,\n        0x12ede0e226a177e5L },\n      { 0x332cca62065a6f4fL,0xc3a47ecd67be487bL,0x741eb1870f47ed1cL,\n        0x99e66e58e7598b14L } },\n    /* 33 << 196 */\n    { { 0x6f0544ca63d0ff12L,0xe5efc784b610a05fL,0xf72917b17cad7b47L,\n        0x3ff6ea20f2cac0c0L },\n      { 0xcc23791bf21db8b7L,0x7dac70b1d7d93565L,0x682cda1d694bdaadL,\n        0xeb88bb8c1023516dL } },\n    /* 34 << 196 */\n    { { 0xc4c634b4dfdbeb1bL,0x22f5ca72b4ee4deaL,0x1045a368e6524821L,\n        0xed9e8a3f052b18b2L },\n      { 0x9b7f2cb1b961f49aL,0x7fee2ec17b009670L,0x350d875422507a6dL,\n        0x561bd7114db55f1dL } },\n    /* 35 << 196 */\n    { { 0x4c189ccc320bbcafL,0x568434cfdf1de48cL,0x6af1b00e0fa8f128L,\n        0xf0ba9d028907583cL },\n      { 0x735a400432ff9f60L,0x3dd8e4b6c25dcf33L,0xf2230f1642c74cefL,\n        0xd8117623013fa8adL } },\n    /* 36 << 196 */\n    { { 0x36822876f51fe76eL,0x8a6811cc11d62589L,0xc3fc7e6546225718L,\n        0xb7df2c9fc82fdbcdL },\n      { 0x3b1d4e52dd7b205bL,0xb695947847a2e414L,0x05e4d793efa91148L,\n        0xb47ed446fd2e9675L } },\n    /* 37 << 196 */\n    { { 0x1a7098b904c9d9bfL,0x661e28811b793048L,0xb1a16966b01ee461L,\n        0xbc5213082954746fL },\n      { 0xc909a0fc2477de50L,0xd80bb41c7dbd51efL,0xa85be7ec53294905L,\n        0x6d465b1883958f97L } },\n    /* 38 << 196 */\n    { { 0x16f6f330fb6840fdL,0xfaaeb2143401e6c8L,0xaf83d30fccb5b4f8L,\n        0x22885739266dec4bL },\n      { 0x51b4367c7bc467dfL,0x926562e3d842d27aL,0xdfcb66140fea14a6L,\n        0xeb394daef2734cd9L } },\n    /* 39 << 196 */\n    { { 0x3eeae5d211c0be98L,0xb1e6ed11814e8165L,0x191086bce52bce1cL,\n        0x14b74cc6a75a04daL },\n      { 0x63cf11868c060985L,0x071047de2dbd7f7cL,0x4e433b8bce0942caL,\n        0xecbac447d8fec61dL } },\n    /* 40 << 196 */\n    { { 0x8f0ed0e2ebf3232fL,0xfff80f9ec52a2eddL,0xad9ab43375b55fdbL,\n        0x73ca7820e42e0c11L },\n      { 0x6dace0a0e6251b46L,0x89bc6b5c4c0d932dL,0x3438cd77095da19aL,\n        0x2f24a9398d48bdfbL } },\n    /* 41 << 196 */\n    { { 0x99b47e46766561b7L,0x736600e60ed0322aL,0x06a47cb1638e1865L,\n        0x927c1c2dcb136000L },\n      { 0x295423370cc5df69L,0x99b37c0209d649a9L,0xc5f0043c6aefdb27L,\n        0x6cdd99871be95c27L } },\n    /* 42 << 196 */\n    { { 0x69850931390420d2L,0x299c40ac0983efa4L,0x3a05e778af39aeadL,\n        0x8427440843a45193L },\n      { 0x6bcd0fb991a711a0L,0x461592c89f52ab17L,0xb49302b4da3c6ed6L,\n        0xc51fddc7330d7067L } },\n    /* 43 << 196 */\n    { { 0x94babeb6da50d531L,0x521b840da6a7b9daL,0x5305151e404bdc89L,\n        0x1bcde201d0d07449L },\n      { 0xf427a78b3b76a59aL,0xf84841ce07791a1bL,0xebd314bebf91ed1cL,\n        0x8e61d34cbf172943L } },\n    /* 44 << 196 */\n    { { 0x1d5dc4515541b892L,0xb186ee41fc9d9e54L,0x9d9f345ed5bf610dL,\n        0x3e7ba65df6acca9fL },\n      { 0x9dda787aa8369486L,0x09f9dab78eb5ba53L,0x5afb2033d6481bc3L,\n        0x76f4ce30afa62104L } },\n    /* 45 << 196 */\n    { { 0xa8fa00cff4f066b5L,0x89ab5143461dafc2L,0x44339ed7a3389998L,\n        0x2ff862f1bc214903L },\n      { 0x2c88f985b05556e3L,0xcd96058e3467081eL,0x7d6a4176edc637eaL,\n        0xe1743d0936a5acdcL } },\n    /* 46 << 196 */\n    { { 0x66fd72e27eb37726L,0xf7fa264e1481a037L,0x9fbd3bde45f4aa79L,\n        0xed1e0147767c3e22L },\n      { 0x7621f97982e7abe2L,0x19eedc7245f633f8L,0xe69b155e6137bf3aL,\n        0xa0ad13ce414ee94eL } },\n    /* 47 << 196 */\n    { { 0x93e3d5241c0e651aL,0xab1a6e2a02ce227eL,0xe7af17974ab27ecaL,\n        0x245446debd444f39L },\n      { 0x59e22a2156c07613L,0x43deafcef4275498L,0x10834ccb67fd0946L,\n        0xa75841e547406edfL } },\n    /* 48 << 196 */\n    { { 0xebd6a6777b0ac93dL,0xa6e37b0d78f5e0d7L,0x2516c09676f5492bL,\n        0x1e4bf8889ac05f3aL },\n      { 0xcdb42ce04df0ba2bL,0x935d5cfd5062341bL,0x8a30333382acac20L,\n        0x429438c45198b00eL } },\n    /* 49 << 196 */\n    { { 0x1d083bc9049d33faL,0x58b82dda946f67ffL,0xac3e2db867a1d6a3L,\n        0x62e6bead1798aac8L },\n      { 0xfc85980fde46c58cL,0xa7f6937969c8d7beL,0x23557927837b35ecL,\n        0x06a933d8e0790c0cL } },\n    /* 50 << 196 */\n    { { 0x827c0e9b077ff55dL,0x53977798bb26e680L,0x595308741d9cb54fL,\n        0xcca3f4494aac53efL },\n      { 0x11dc5c87a07eda0fL,0xc138bccffd6400c8L,0x549680d313e5da72L,\n        0xc93eed824540617eL } },\n    /* 51 << 196 */\n    { { 0xfd3db1574d0b75c0L,0x9716eb426386075bL,0x0639605c817b2c16L,\n        0x09915109f1e4f201L },\n      { 0x35c9a9285cca6c3bL,0xb25f7d1a3505c900L,0xeb9f7d20630480c4L,\n        0xc3c7b8c62a1a501cL } },\n    /* 52 << 196 */\n    { { 0x3f99183c5a1f8e24L,0xfdb118fa9dd255f0L,0xb9b18b90c27f62a6L,\n        0xe8f732f7396ec191L },\n      { 0x524a2d910be786abL,0x5d32adef0ac5a0f5L,0x9b53d4d69725f694L,\n        0x032a76c60510ba89L } },\n    /* 53 << 196 */\n    { { 0x840391a3ebeb1544L,0x44b7b88c3ed73ac3L,0xd24bae7a256cb8b3L,\n        0x7ceb151ae394cb12L },\n      { 0xbd6b66d05bc1e6a8L,0xec70cecb090f07bfL,0x270644ed7d937589L,\n        0xee9e1a3d5f1dccfeL } },\n    /* 54 << 196 */\n    { { 0xb0d40a84745b98d2L,0xda429a212556ed40L,0xf676eced85148cb9L,\n        0x5a22d40cded18936L },\n      { 0x3bc4b9e570e8a4ceL,0xbfd1445b9eae0379L,0xf23f2c0c1a0bd47eL,\n        0xa9c0bb31e1845531L } },\n    /* 55 << 196 */\n    { { 0x9ddc4d600a4c3f6bL,0xbdfaad792c15ef44L,0xce55a2367f484accL,\n        0x08653ca7055b1f15L },\n      { 0x2efa8724538873a3L,0x09299e5dace1c7e7L,0x07afab66ade332baL,\n        0x9be1fdf692dd71b7L } },\n    /* 56 << 196 */\n    { { 0xa49b5d595758b11cL,0x0b852893c8654f40L,0xb63ef6f452379447L,\n        0xd4957d29105e690cL },\n      { 0x7d484363646559b0L,0xf4a8273c49788a8eL,0xee406cb834ce54a9L,\n        0x1e1c260ff86fda9bL } },\n    /* 57 << 196 */\n    { { 0xe150e228cf6a4a81L,0x1fa3b6a31b488772L,0x1e6ff110c5a9c15bL,\n        0xc6133b918ad6aa47L },\n      { 0x8ac5d55c9dffa978L,0xba1d1c1d5f3965f2L,0xf969f4e07732b52fL,\n        0xfceecdb5a5172a07L } },\n    /* 58 << 196 */\n    { { 0xb0120a5f10f2b8f5L,0xc83a6cdf5c4c2f63L,0x4d47a491f8f9c213L,\n        0xd9e1cce5d3f1bbd5L },\n      { 0x0d91bc7caba7e372L,0xfcdc74c8dfd1a2dbL,0x05efa800374618e5L,\n        0x1121696915a7925eL } },\n    /* 59 << 196 */\n    { { 0xd4c89823f6021c5dL,0x880d5e84eff14423L,0x6523bc5a6dcd1396L,\n        0xd1acfdfc113c978bL },\n      { 0xb0c164e8bbb66840L,0xf7f4301e72b58459L,0xc29ad4a6a638e8ecL,\n        0xf5ab896146b78699L } },\n    /* 60 << 196 */\n    { { 0x9dbd79740e954750L,0x0121de8864f9d2c6L,0x2e597b42d985232eL,\n        0x55b6c3c553451777L },\n      { 0xbb53e547519cb9fbL,0xf134019f8428600dL,0x5a473176e081791aL,\n        0x2f3e226335fb0c08L } },\n    /* 61 << 196 */\n    { { 0xb28c301773d273b0L,0xccd210767721ef9aL,0x054cc292b650dc39L,\n        0x662246de6188045eL },\n      { 0x904b52fa6b83c0d1L,0xa72df26797e9cd46L,0x886b43cd899725e4L,\n        0x2b651688d849ff22L } },\n    /* 62 << 196 */\n    { { 0x60479b7902f34533L,0x5e354c140c77c148L,0xb4bb7581a8537c78L,\n        0x188043d7efe1495fL },\n      { 0x9ba12f428c1d5026L,0x2e0c8a2693d4aaabL,0xbdba7b8baa57c450L,\n        0x140c9ad69bbdafefL } },\n    /* 63 << 196 */\n    { { 0x2067aa4225ac0f18L,0xf7b1295b04d1fbf3L,0x14829111a4b04824L,\n        0x2ce3f19233bd5e91L },\n      { 0x9c7a1d558f2e1b72L,0xfe932286302aa243L,0x497ca7b4d4be9554L,\n        0xb8e821b8e0547a6eL } },\n    /* 64 << 196 */\n    { { 0xfb2838be67e573e0L,0x05891db94084c44bL,0x9131137396c1c2c5L,\n        0x6aebfa3fd958444bL },\n      { 0xac9cdce9e56e55c1L,0x7148ced32caa46d0L,0x2e10c7efb61fe8ebL,\n        0x9fd835daff97cf4dL } },\n    /* 0 << 203 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 203 */\n    { { 0xa36da109081e9387L,0xfb9780d78c935828L,0xd5940332e540b015L,\n        0xc9d7b51be0f466faL },\n      { 0xfaadcd41d6d9f671L,0xba6c1e28b1a2ac17L,0x066a7833ed201e5fL,\n        0x19d99719f90f462bL } },\n    /* 2 << 203 */\n    { { 0xf431f462060b5f61L,0xa56f46b47bd057c2L,0x348dca6c47e1bf65L,\n        0x9a38783e41bcf1ffL },\n      { 0x7a5d33a9da710718L,0x5a7799872e0aeaf6L,0xca87314d2d29d187L,\n        0xfa0edc3ec687d733L } },\n    /* 3 << 203 */\n    { { 0x9df336216a31e09bL,0xde89e44dc1350e35L,0x292148714ca0cf52L,\n        0xdf3796720b88a538L },\n      { 0xc92a510a2591d61bL,0x79aa87d7585b447bL,0xf67db604e5287f77L,\n        0x1697c8bf5efe7a80L } },\n    /* 4 << 203 */\n    { { 0x1c894849cb198ac7L,0xa884a93d0f264665L,0x2da964ef9b200678L,\n        0x3c351b87009834e6L },\n      { 0xafb2ef9fe2c4b44bL,0x580f6c473326790cL,0xb84805210b02264aL,\n        0x8ba6f9e242a194e2L } },\n    /* 5 << 203 */\n    { { 0xfc87975f8fb54738L,0x3516078827c3ead3L,0x834116d2b74a085aL,\n        0x53c99a73a62fe996L },\n      { 0x87585be05b81c51bL,0x925bafa8be0852b7L,0x76a4fafda84d19a7L,\n        0x39a45982585206d4L } },\n    /* 6 << 203 */\n    { { 0x499b6ab65eb03c0eL,0xf19b795472bc3fdeL,0xa86b5b9c6e3a80d2L,\n        0xe43775086d42819fL },\n      { 0xc1663650bb3ee8a3L,0x75eb14fcb132075fL,0xa8ccc9067ad834f6L,\n        0xea6a2474e6e92ffdL } },\n    /* 7 << 203 */\n    { { 0x9d72fd950f8d6758L,0xcb84e101408c07ddL,0xb9114bfda5e23221L,\n        0x358b5fe2e94e742cL },\n      { 0x1c0577ec95f40e75L,0xf01554513d73f3d6L,0x9d55cd67bd1b9b66L,\n        0x63e86e78af8d63c7L } },\n    /* 8 << 203 */\n    { { 0x39d934abd3c095f1L,0x04b261bee4b76d71L,0x1d2e6970e73e6984L,\n        0x879fb23b5e5fcb11L },\n      { 0x11506c72dfd75490L,0x3a97d08561bcf1c1L,0x43201d82bf5e7007L,\n        0x7f0ac52f798232a7L } },\n    /* 9 << 203 */\n    { { 0x2715cbc46eb564d4L,0x8d6c752c9e570e29L,0xf80247c89ef5fd5dL,\n        0xc3c66b46d53eb514L },\n      { 0x9666b4010f87de56L,0xce62c06fc6c603b5L,0xae7b4c607e4fc942L,\n        0x38ac0b77663a9c19L } },\n    /* 10 << 203 */\n    { { 0xcb4d20ee4b049136L,0x8b63bf12356a4613L,0x1221aef670e08128L,\n        0xe62d8c514acb6b16L },\n      { 0x71f64a67379e7896L,0xb25237a2cafd7fa5L,0xf077bd983841ba6aL,\n        0xc4ac02443cd16e7eL } },\n    /* 11 << 203 */\n    { { 0x548ba86921fea4caL,0xd36d0817f3dfdac1L,0x09d8d71ff4685fafL,\n        0x8eff66bec52c459aL },\n      { 0x182faee70b57235eL,0xee3c39b10106712bL,0x5107331fc0fcdcb0L,\n        0x669fb9dca51054baL } },\n    /* 12 << 203 */\n    { { 0xb25101fb319d7682L,0xb02931290a982feeL,0x51c1c9b90261b344L,\n        0x0e008c5bbfd371faL },\n      { 0xd866dd1c0278ca33L,0x666f76a6e5aa53b1L,0xe5cfb7796013a2cfL,\n        0x1d3a1aada3521836L } },\n    /* 13 << 203 */\n    { { 0xcedd253173faa485L,0xc8ee6c4fc0a76878L,0xddbccfc92a11667dL,\n        0x1a418ea91c2f695aL },\n      { 0xdb11bd9251f73971L,0x3e4b3c82da2ed89fL,0x9a44f3f4e73e0319L,\n        0xd1e3de0f303431afL } },\n    /* 14 << 203 */\n    { { 0x3c5604ff50f75f9cL,0x1d8eddf37e752b22L,0x0ef074dd3c9a1118L,\n        0xd0ffc172ccb86d7bL },\n      { 0xabd1ece3037d90f2L,0xe3f307d66055856cL,0x422f93287e4c6dafL,\n        0x902aac66334879a0L } },\n    /* 15 << 203 */\n    { { 0xb6a1e7bf94cdfadeL,0x6c97e1ed7fc6d634L,0x662ad24da2fb63f8L,\n        0xf81be1b9a5928405L },\n      { 0x86d765e4d14b4206L,0xbecc2e0e8fa0db65L,0xa28838e0b17fc76cL,\n        0xe49a602ae37cf24eL } },\n    /* 16 << 203 */\n    { { 0x76b4131a567193ecL,0xaf3c305ae5f6e70bL,0x9587bd39031eebddL,\n        0x5709def871bbe831L },\n      { 0x570599830eb2b669L,0x4d80ce1b875b7029L,0x838a7da80364ac16L,\n        0x2f431d23be1c83abL } },\n    /* 17 << 203 */\n    { { 0xe56812a6f9294dd3L,0xb448d01f9b4b0d77L,0xf3ae606104e8305cL,\n        0x2bead64594d8c63eL },\n      { 0x0a85434d84fd8b07L,0x537b983ff7a9dee5L,0xedcc5f18ef55bd85L,\n        0x2041af6221c6cf8bL } },\n    /* 18 << 203 */\n    { { 0x8e52874cb940c71eL,0x211935a9db5f4b3aL,0x94350492301b1dc3L,\n        0x33d2646d29958620L },\n      { 0x16b0d64bef911404L,0x9d1f25ea9a3c5ef4L,0x20f200eb4a352c78L,\n        0x43929f2c4bd0b428L } },\n    /* 19 << 203 */\n    { { 0xa5656667c7196e29L,0x7992c2f09391be48L,0xaaa97cbd9ee0cd6eL,\n        0x51b0310c3dc8c9bfL },\n      { 0x237f8acfdd9f22cbL,0xbb1d81a1b585d584L,0x8d5d85f58c416388L,\n        0x0d6e5a5a42fe474fL } },\n    /* 20 << 203 */\n    { { 0xe781276638235d4eL,0x1c62bd67496e3298L,0x8378660c3f175bc8L,\n        0x4d04e18917afdd4dL },\n      { 0x32a8160185a8068cL,0xdb58e4e192b29a85L,0xe8a65b86c70d8a3bL,\n        0x5f0e6f4e98a0403bL } },\n    /* 21 << 203 */\n    { { 0x0812968469ed2370L,0x34dc30bd0871ee26L,0x3a5ce9487c9c5b05L,\n        0x7d487b8043a90c87L },\n      { 0x4089ba37dd0e7179L,0x45f80191b4041811L,0x1c3e105898747ba5L,\n        0x98c4e13a6e1ae592L } },\n    /* 22 << 203 */\n    { { 0xd44636e6e82c9f9eL,0x711db87cc33a1043L,0x6f431263aa8aec05L,\n        0x43ff120d2744a4aaL },\n      { 0xd3bd892fae77779bL,0xf0fe0cc98cdc9f82L,0xca5f7fe6f1c5b1bcL,\n        0xcc63a68244929a72L } },\n    /* 23 << 203 */\n    { { 0xc7eaba0c09dbe19aL,0x2f3585ad6b5c73c2L,0x8ab8924b0ae50c30L,\n        0x17fcd27a638b30baL },\n      { 0xaf414d3410b3d5a5L,0x09c107d22a9accf1L,0x15dac49f946a6242L,\n        0xaec3df2ad707d642L } },\n    /* 24 << 203 */\n    { { 0x2c2492b73f894ae0L,0xf59df3e5b75f18ceL,0x7cb740d28f53cad0L,\n        0x3eb585fbc4f01294L },\n      { 0x17da0c8632c7f717L,0xeb8c795baf943f4cL,0x4ee23fb5f67c51d2L,\n        0xef18757568889949L } },\n    /* 25 << 203 */\n    { { 0xa6b4bdb20389168bL,0xc4ecd258ea577d03L,0x3a63782b55743082L,\n        0x6f678f4cc72f08cdL },\n      { 0x553511cf65e58dd8L,0xd53b4e3ed402c0cdL,0x37de3e29a037c14cL,\n        0x86b6c516c05712aaL } },\n    /* 26 << 203 */\n    { { 0x2834da3eb38dff6fL,0xbe012c52ea636be8L,0x292d238c61dd37f8L,\n        0x0e54523f8f8142dbL },\n      { 0xe31eb436036a05d8L,0x83e3cdff1e93c0ffL,0x3fd2fe0f50821ddfL,\n        0xc8e19b0dff9eb33bL } },\n    /* 27 << 203 */\n    { { 0xc8cc943fb569a5feL,0xad0090d4d4342d75L,0x82090b4bcaeca000L,\n        0xca39687f1bd410ebL },\n      { 0xe7bb0df765959d77L,0x39d782189c964999L,0xd87f62e8b2415451L,\n        0xe5efb774bed76108L } },\n    /* 28 << 203 */\n    { { 0x3ea011a4e822f0d0L,0xbc647ad15a8704f8L,0xbb315b3550c6820fL,\n        0x863dec3db7e76becL },\n      { 0x01ff5d3af017bfc7L,0x20054439976b8229L,0x067fca370bbd0d3bL,\n        0xf63dde647f5e3d0fL } },\n    /* 29 << 203 */\n    { { 0x22dbefb32a4c94e9L,0xafbff0fe96f8278aL,0x80aea0b13503793dL,\n        0xb22380295f06cd29L },\n      { 0x65703e578ec3fecaL,0x06c38314393e7053L,0xa0b751eb7c6734c4L,\n        0xd2e8a435c59f0f1eL } },\n    /* 30 << 203 */\n    { { 0x147d90525e9ca895L,0x2f4dd31e972072dfL,0xa16fda8ee6c6755cL,\n        0xc66826ffcf196558L },\n      { 0x1f1a76a30cf43895L,0xa9d604e083c3097bL,0xe190830966390e0eL,\n        0xa50bf753b3c85effL } },\n    /* 31 << 203 */\n    { { 0x0696bddef6a70251L,0x548b801b3c6ab16aL,0x37fcf704a4d08762L,\n        0x090b3defdff76c4eL },\n      { 0x87e8cb8969cb9158L,0x44a90744995ece43L,0xf85395f40ad9fbf5L,\n        0x49b0f6c54fb0c82dL } },\n    /* 32 << 203 */\n    { { 0x75d9bc15adf7cccfL,0x81a3e5d6dfa1e1b0L,0x8c39e444249bc17eL,\n        0xf37dccb28ea7fd43L },\n      { 0xda654873907fba12L,0x35daa6da4a372904L,0x0564cfc66283a6c5L,\n        0xd09fa4f64a9395bfL } },\n    /* 33 << 203 */\n    { { 0x688e9ec9aeb19a36L,0xd913f1cec7bfbfb4L,0x797b9a3c61c2faa6L,\n        0x2f979bec6a0a9c12L },\n      { 0xb5969d0f359679ecL,0xebcf523d079b0460L,0xfd6b000810fab870L,\n        0x3f2edcda9373a39cL } },\n    /* 34 << 203 */\n    { { 0x0d64f9a76f568431L,0xf848c27c02f8898cL,0xf418ade1260b5bd5L,\n        0xc1f3e3236973dee8L },\n      { 0x46e9319c26c185ddL,0x6d85b7d8546f0ac4L,0x427965f2247f9d57L,\n        0xb519b636b0035f48L } },\n    /* 35 << 203 */\n    { { 0x6b6163a9ab87d59cL,0xff9f58c339caaa11L,0x4ac39cde3177387bL,\n        0x5f6557c2873e77f9L },\n      { 0x6750400636a83041L,0x9b1c96ca75ef196cL,0xf34283deb08c7940L,\n        0x7ea096441128c316L } },\n    /* 36 << 203 */\n    { { 0xb510b3b56aa39dffL,0x59b43da29f8e4d8cL,0xa8ce31fd9e4c4b9fL,\n        0x0e20be26c1303c01L },\n      { 0x18187182e8ee47c9L,0xd9687cdb7db98101L,0x7a520e4da1e14ff6L,\n        0x429808ba8836d572L } },\n    /* 37 << 203 */\n    { { 0xa37ca60d4944b663L,0xf901f7a9a3f91ae5L,0xe4e3e76e9e36e3b1L,\n        0x9aa219cf29d93250L },\n      { 0x347fe275056a2512L,0xa4d643d9de65d95cL,0x9669d396699fc3edL,\n        0xb598dee2cf8c6bbeL } },\n    /* 38 << 203 */\n    { { 0x682ac1e5dda9e5c6L,0x4e0d3c72caa9fc95L,0x17faaade772bea44L,\n        0x5ef8428cab0009c8L },\n      { 0xcc4ce47a460ff016L,0xda6d12bf725281cbL,0x44c678480223aad2L,\n        0x6e342afa36256e28L } },\n    /* 39 << 203 */\n    { { 0x1400bb0b93a37c04L,0x62b1bc9bdd10bd96L,0x7251adeb0dac46b7L,\n        0x7d33b92e7be4ef51L },\n      { 0x28b2a94be61fa29aL,0x4b2be13f06422233L,0x36d6d062330d8d37L,\n        0x5ef80e1eb28ca005L } },\n    /* 40 << 203 */\n    { { 0x174d46996d16768eL,0x9fc4ff6a628bf217L,0x77705a94154e490dL,\n        0x9d96dd288d2d997aL },\n      { 0x77e2d9d8ce5d72c4L,0x9d06c5a4c11c714fL,0x02aa513679e4a03eL,\n        0x1386b3c2030ff28bL } },\n    /* 41 << 203 */\n    { { 0xfe82e8a6fb283f61L,0x7df203e5f3abc3fbL,0xeec7c3513a4d3622L,\n        0xf7d17dbfdf762761L },\n      { 0xc3956e44522055f0L,0xde3012db8fa748dbL,0xca9fcb63bf1dcc14L,\n        0xa56d9dcfbe4e2f3aL } },\n    /* 42 << 203 */\n    { { 0xb86186b68bcec9c2L,0x7cf24df9680b9f06L,0xc46b45eac0d29281L,\n        0xfff42bc507b10e12L },\n      { 0x12263c404d289427L,0x3d5f1899b4848ec4L,0x11f97010d040800cL,\n        0xb4c5f529300feb20L } },\n    /* 43 << 203 */\n    { { 0xcc543f8fde94fdcbL,0xe96af739c7c2f05eL,0xaa5e0036882692e1L,\n        0x09c75b68950d4ae9L },\n      { 0x62f63df2b5932a7aL,0x2658252ede0979adL,0x2a19343fb5e69631L,\n        0x718c7501525b666bL } },\n    /* 44 << 203 */\n    { { 0x26a42d69ea40dc3aL,0xdc84ad22aecc018fL,0x25c36c7b3270f04aL,\n        0x46ba6d4750fa72edL },\n      { 0x6c37d1c593e58a8eL,0xa2394731120c088cL,0xc3be4263cb6e86daL,\n        0x2c417d367126d038L } },\n    /* 45 << 203 */\n    { { 0x5b70f9c58b6f8efaL,0x671a2faa37718536L,0xd3ced3c6b539c92bL,\n        0xe56f1bd9a31203c2L },\n      { 0x8b096ec49ff3c8ebL,0x2deae43243491ceaL,0x2465c6eb17943794L,\n        0x5d267e6620586843L } },\n    /* 46 << 203 */\n    { { 0x9d3d116db07159d0L,0xae07a67fc1896210L,0x8fc84d87bb961579L,\n        0x30009e491c1f8dd6L },\n      { 0x8a8caf22e3132819L,0xcffa197cf23ab4ffL,0x58103a44205dd687L,\n        0x57b796c30ded67a2L } },\n    /* 47 << 203 */\n    { { 0x0b9c3a6ca1779ad7L,0xa33cfe2e357c09c5L,0x2ea293153db4a57eL,\n        0x919596958ebeb52eL },\n      { 0x118db9a6e546c879L,0x8e996df46295c8d6L,0xdd99048455ec806bL,\n        0x24f291ca165c1035L } },\n    /* 48 << 203 */\n    { { 0xcca523bb440e2229L,0x324673a273ef4d04L,0xaf3adf343e11ec39L,\n        0x6136d7f1dc5968d3L },\n      { 0x7a7b2899b053a927L,0x3eaa2661ae067ecdL,0x8549b9c802779cd9L,\n        0x061d7940c53385eaL } },\n    /* 49 << 203 */\n    { { 0x3e0ba883f06d18bdL,0x4ba6de53b2700843L,0xb966b668591a9e4dL,\n        0x93f675677f4fa0edL },\n      { 0x5a02711b4347237bL,0xbc041e2fe794608eL,0x55af10f570f73d8cL,\n        0xd2d4d4f7bb7564f7L } },\n    /* 50 << 203 */\n    { { 0xd7d27a89b3e93ce7L,0xf7b5a8755d3a2c1bL,0xb29e68a0255b218aL,\n        0xb533837e8af76754L },\n      { 0xd1b05a73579fab2eL,0xb41055a1ecd74385L,0xb2369274445e9115L,\n        0x2972a7c4f520274eL } },\n    /* 51 << 203 */\n    { { 0x6c08334ef678e68aL,0x4e4160f099b057edL,0x3cfe11b852ccb69aL,\n        0x2fd1823a21c8f772L },\n      { 0xdf7f072f3298f055L,0x8c0566f9fec74a6eL,0xe549e0195bb4d041L,\n        0x7c3930ba9208d850L } },\n    /* 52 << 203 */\n    { { 0xe07141fcaaa2902bL,0x539ad799e4f69ad3L,0xa6453f94813f9ffdL,\n        0xc58d3c48375bc2f7L },\n      { 0xb3326fad5dc64e96L,0x3aafcaa9b240e354L,0x1d1b0903aca1e7a9L,\n        0x4ceb97671211b8a0L } },\n    /* 53 << 203 */\n    { { 0xeca83e49e32a858eL,0x4c32892eae907badL,0xd5b42ab62eb9b494L,\n        0x7fde3ee21eabae1bL },\n      { 0x13b5ab09caf54957L,0xbfb028bee5f5d5d5L,0x928a06502003e2c0L,\n        0x90793aac67476843L } },\n    /* 54 << 203 */\n    { { 0x5e942e79c81710a0L,0x557e4a3627ccadd4L,0x72a2bc564bcf6d0cL,\n        0x09ee5f4326d7b80cL },\n      { 0x6b70dbe9d4292f19L,0x56f74c2663f16b18L,0xc23db0f735fbb42aL,\n        0xb606bdf66ae10040L } },\n    /* 55 << 203 */\n    { { 0x1eb15d4d044573acL,0x7dc3cf86556b0ba4L,0x97af9a33c60df6f7L,\n        0x0b1ef85ca716ce8cL },\n      { 0x2922f884c96958beL,0x7c32fa9435690963L,0x2d7f667ceaa00061L,\n        0xeaaf7c173547365cL } },\n    /* 56 << 203 */\n    { { 0x1eb4de4687032d58L,0xc54f3d835e2c79e0L,0x07818df45d04ef23L,\n        0x55faa9c8673d41b4L },\n      { 0xced64f6f89b95355L,0x4860d2eab7415c84L,0x5fdb9bd2050ebad3L,\n        0xdb53e0cc6685a5bfL } },\n    /* 57 << 203 */\n    { { 0xb830c0319feb6593L,0xdd87f3106accff17L,0x2303ebab9f555c10L,\n        0x94603695287e7065L },\n      { 0xf88311c32e83358cL,0x508dd9b4eefb0178L,0x7ca237062dba8652L,\n        0x62aac5a30047abe5L } },\n    /* 58 << 203 */\n    { { 0x9a61d2a08b1ea7b3L,0xd495ab63ae8b1485L,0x38740f8487052f99L,\n        0x178ebe5bb2974eeaL },\n      { 0x030bbcca5b36d17fL,0xb5e4cce3aaf86eeaL,0xb51a022068f8e9e0L,\n        0xa434879609eb3e75L } },\n    /* 59 << 203 */\n    { { 0xbe592309eef1a752L,0x5d7162d76f2aa1edL,0xaebfb5ed0f007dd2L,\n        0x255e14b2c89edd22L },\n      { 0xba85e0720303b697L,0xc5d17e25f05720ffL,0x02b58d6e5128ebb6L,\n        0x2c80242dd754e113L } },\n    /* 60 << 203 */\n    { { 0x919fca5fabfae1caL,0x937afaac1a21459bL,0x9e0ca91c1f66a4d2L,\n        0x194cc7f323ec1331L },\n      { 0xad25143a8aa11690L,0xbe40ad8d09b59e08L,0x37d60d9be750860aL,\n        0x6c53b008c6bf434cL } },\n    /* 61 << 203 */\n    { { 0xb572415d1356eb80L,0xb8bf9da39578ded8L,0x22658e365e8fb38bL,\n        0x9b70ce225af8cb22L },\n      { 0x7c00018a829a8180L,0x84329f93b81ed295L,0x7c343ea25f3cea83L,\n        0x38f8655f67586536L } },\n    /* 62 << 203 */\n    { { 0xa661a0d01d3ec517L,0x98744652512321aeL,0x084ca591eca92598L,\n        0xa9bb9dc91dcb3febL },\n      { 0x14c5435578b4c240L,0x5ed62a3b610cafdcL,0x07512f371b38846bL,\n        0x571bb70ab0e38161L } },\n    /* 63 << 203 */\n    { { 0xb556b95b2da705d2L,0x3ef8ada6b1a08f98L,0x85302ca7ddecfbe5L,\n        0x0e530573943105cdL },\n      { 0x60554d5521a9255dL,0x63a32fa1f2f3802aL,0x35c8c5b0cd477875L,\n        0x97f458ea6ad42da1L } },\n    /* 64 << 203 */\n    { { 0x832d7080eb6b242dL,0xd30bd0233b71e246L,0x7027991bbe31139dL,\n        0x68797e91462e4e53L },\n      { 0x423fe20a6b4e185aL,0x82f2c67e42d9b707L,0x25c817684cf7811bL,\n        0xbd53005e045bb95dL } },\n    /* 0 << 210 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 210 */\n    { { 0xe5f649be9d8e68fdL,0xdb0f05331b044320L,0xf6fde9b3e0c33398L,\n        0x92f4209b66c8cfaeL },\n      { 0xe9d1afcc1a739d4bL,0x09aea75fa28ab8deL,0x14375fb5eac6f1d0L,\n        0x6420b560708f7aa5L } },\n    /* 2 << 210 */\n    { { 0x9eae499c6254dc41L,0x7e2939247a837e7eL,0x74aec08c090524a7L,\n        0xf82b92198d6f55f2L },\n      { 0x493c962e1402cec5L,0x9f17ca17fa2f30e7L,0xbcd783e8e9b879cbL,\n        0xea3d8c145a6f145fL } },\n    /* 3 << 210 */\n    { { 0xdede15e75e0dee6eL,0x74f24872dc628aa2L,0xd3e9c4fe7861bb93L,\n        0x56d4822a6187b2e0L },\n      { 0xb66417cfc59826f9L,0xca2609692408169eL,0xedf69d06c79ef885L,\n        0x00031f8adc7d138fL } },\n    /* 4 << 210 */\n    { { 0x103c46e60ebcf726L,0x4482b8316231470eL,0x6f6dfaca487c2109L,\n        0x2e0ace9762e666efL },\n      { 0x3246a9d31f8d1f42L,0x1b1e83f1574944d2L,0x13dfa63aa57f334bL,\n        0x0cf8daed9f025d81L } },\n    /* 5 << 210 */\n    { { 0x30d78ea800ee11c1L,0xeb053cd4b5e3dd75L,0x9b65b13ed58c43c5L,\n        0xc3ad49bdbd151663L },\n      { 0x99fd8e41b6427990L,0x12cf15bd707eae1eL,0x29ad4f1b1aabb71eL,\n        0x5143e74d07545d0eL } },\n    /* 6 << 210 */\n    { { 0x30266336c88bdee1L,0x25f293065876767cL,0x9c078571c6731996L,\n        0xc88690b2ed552951L },\n      { 0x274f2c2d852705b4L,0xb0bf8d444e09552dL,0x7628beeb986575d1L,\n        0x407be2387f864651L } },\n    /* 7 << 210 */\n    { { 0x0e5e3049a639fc6bL,0xe75c35d986003625L,0x0cf35bd85dcc1646L,\n        0x8bcaced26c26273aL },\n      { 0xe22ecf1db5536742L,0x013dd8971a9e068bL,0x17f411cb8a7909c5L,\n        0x5757ac98861dd506L } },\n    /* 8 << 210 */\n    { { 0x85de1f0d1e935abbL,0xdefd10b4154de37aL,0xb8d9e392369cebb5L,\n        0x54d5ef9b761324beL },\n      { 0x4d6341ba74f17e26L,0xc0a0e3c878c1dde4L,0xa6d7758187d918fdL,\n        0x6687601502ca3a13L } },\n    /* 9 << 210 */\n    { { 0xc7313e9cf36658f0L,0xc433ef1c71f8057eL,0x853262461b6a835aL,\n        0xc8f053987c86394cL },\n      { 0xff398cdfe983c4a1L,0xbf5e816203b7b931L,0x93193c46b7b9045bL,\n        0x1e4ebf5da4a6e46bL } },\n    /* 10 << 210 */\n    { { 0xf9942a6043a24fe7L,0x29c1191effb3492bL,0x9f662449902fde05L,\n        0xc792a7ac6713c32dL },\n      { 0x2fd88ad8b737982cL,0x7e3a0319a21e60e3L,0x09b0de447383591aL,\n        0x6df141ee8310a456L } },\n    /* 11 << 210 */\n    { { 0xaec1a039e6d6f471L,0x14b2ba0f1198d12eL,0xebc1a1603aeee5acL,\n        0x401f4836e0b964ceL },\n      { 0x2ee437964fd03f66L,0x3fdb4e49dd8f3f12L,0x6ef267f629380f18L,\n        0x3e8e96708da64d16L } },\n    /* 12 << 210 */\n    { { 0xbc19180c207674f1L,0x112e09a733ae8fdbL,0x996675546aaeb71eL,\n        0x79432af1e101b1c7L },\n      { 0xd5eb558fde2ddec6L,0x81392d1f5357753fL,0xa7a76b973ae1158aL,\n        0x416fbbff4a899991L } },\n    /* 13 << 210 */\n    { { 0x9e65fdfd0d4a9dcfL,0x7bc29e48944ddf12L,0xbc1a92d93c856866L,\n        0x273c69056e98dfe2L },\n      { 0x69fce418cdfaa6b8L,0x606bd8235061c69fL,0x42d495a06af75e27L,\n        0x8ed3d5056d873a1fL } },\n    /* 14 << 210 */\n    { { 0xaf5528416ab25b6aL,0xc6c0ffc72b1a4523L,0xab18827b21c99e03L,\n        0x060e86489034691bL },\n      { 0x5207f90f93c7f398L,0x9f4a96cb82f8d10bL,0xdd71cd793ad0f9e3L,\n        0x84f435d2fc3a54f5L } },\n    /* 15 << 210 */\n    { { 0x4b03c55b8e33787fL,0xef42f975a6384673L,0xff7304f75051b9f0L,\n        0x18aca1dc741c87c2L },\n      { 0x56f120a72d4bfe80L,0xfd823b3d053e732cL,0x11bccfe47537ca16L,\n        0xdf6c9c741b5a996bL } },\n    /* 16 << 210 */\n    { { 0xee7332c7904fc3faL,0x14a23f45c7e3636aL,0xc38659c3f091d9aaL,\n        0x4a995e5db12d8540L },\n      { 0x20a53becf3a5598aL,0x56534b17b1eaa995L,0x9ed3dca4bf04e03cL,\n        0x716c563ad8d56268L } },\n    /* 17 << 210 */\n    { { 0x27ba77a41d6178e7L,0xe4c80c4068a1ff8eL,0x750110990a13f63dL,\n        0x7bf33521a61d46f3L },\n      { 0x0aff218e10b365bbL,0x810218040fd7ea75L,0x05a3fd8aa4b3a925L,\n        0xb829e75f9b3db4e6L } },\n    /* 18 << 210 */\n    { { 0x6bdc75a54d53e5fbL,0x04a5dc02d52717e3L,0x86af502fe9a42ec2L,\n        0x8867e8fb2630e382L },\n      { 0xbf845c6ebec9889bL,0x54f491f2cb47c98dL,0xa3091fba790c2a12L,\n        0xd7f6fd78c20f708bL } },\n    /* 19 << 210 */\n    { { 0xa569ac30acde5e17L,0xd0f996d06852b4d7L,0xe51d4bb54609ae54L,\n        0x3fa37d170daed061L },\n      { 0x62a8868434b8fb41L,0x99a2acbd9efb64f1L,0xb75c1a5e6448e1f2L,\n        0xfa99951a42b5a069L } },\n    /* 20 << 210 */\n    { { 0x6d956e892f3b26e7L,0xf4709860da875247L,0x3ad151792482dda3L,\n        0xd64110e3017d82f0L },\n      { 0x14928d2cfad414e4L,0x2b155f582ed02b24L,0x481a141bcb821bf1L,\n        0x12e3c7704f81f5daL } },\n    /* 21 << 210 */\n    { { 0xe49c5de59fff8381L,0x110532325bbec894L,0xa0d051cc454d88c4L,\n        0x4f6db89c1f8e531bL },\n      { 0x34fe3fd6ca563a44L,0x7f5c221558da8ab9L,0x8445016d9474f0a1L,\n        0x17d34d61cb7d8a0aL } },\n    /* 22 << 210 */\n    { { 0x8e9d39101c474019L,0xcaff2629d52ceefbL,0xf9cf3e32c1622c2bL,\n        0xd4b95e3ce9071a05L },\n      { 0xfbbca61f1594438cL,0x1eb6e6a604aadedfL,0x853027f468e14940L,\n        0x221d322adfabda9cL } },\n    /* 23 << 210 */\n    { { 0xed8ea9f6b7cb179aL,0xdc7b764db7934dccL,0xfcb139405e09180dL,\n        0x6629a6bfb47dc2ddL },\n      { 0xbfc55e4e9f5a915eL,0xb1db9d376204441eL,0xf82d68cf930c5f53L,\n        0x17d3a142cbb605b1L } },\n    /* 24 << 210 */\n    { { 0xdd5944ea308780f2L,0xdc8de7613845f5e4L,0x6beaba7d7624d7a3L,\n        0x1e709afd304df11eL },\n      { 0x9536437602170456L,0xbf204b3ac8f94b64L,0x4e53af7c5680ca68L,\n        0x0526074ae0c67574L } },\n    /* 25 << 210 */\n    { { 0x95d8cef8ecd92af6L,0xe6b9fa7a6cd1745aL,0x3d546d3da325c3e4L,\n        0x1f57691d9ae93aaeL },\n      { 0xe891f3fe9d2e1a33L,0xd430093fac063d35L,0xeda59b125513a327L,\n        0xdc2134f35536f18fL } },\n    /* 26 << 210 */\n    { { 0xaa51fe2c5c210286L,0x3f68aaee1cab658cL,0x5a23a00bf9357292L,\n        0x9a626f397efdabedL },\n      { 0xfe2b3bf3199d78e3L,0xb7a2af7771bbc345L,0x3d19827a1e59802cL,\n        0x823bbc15b487a51cL } },\n    /* 27 << 210 */\n    { { 0x856139f299d0a422L,0x9ac3df65f456c6fbL,0xaddf65c6701f8bd6L,\n        0x149f321e3758df87L },\n      { 0xb1ecf714721b7ebaL,0xe17df09831a3312aL,0xdb2fd6ecd5c4d581L,\n        0xfd02996f8fcea1b3L } },\n    /* 28 << 210 */\n    { { 0xe29fa63e7882f14fL,0xc9f6dc3507c6cadcL,0x46f22d6fb882bed0L,\n        0x1a45755bd118e52cL },\n      { 0x9f2c7c277c4608cfL,0x7ccbdf32568012c2L,0xfcb0aedd61729b0eL,\n        0x7ca2ca9ef7d75dbfL } },\n    /* 29 << 210 */\n    { { 0xf58fecb16f640f62L,0xe274b92b39f51946L,0x7f4dfc046288af44L,\n        0x0a91f32aeac329e5L },\n      { 0x43ad274bd6aaba31L,0x719a16400f6884f9L,0x685d29f6daf91e20L,\n        0x5ec1cc3327e49d52L } },\n    /* 30 << 210 */\n    { { 0x38f4de963b54a059L,0x0e0015e5efbcfdb3L,0x177d23d94dbb8da6L,\n        0x98724aa297a617adL },\n      { 0x30f0885bfdb6558eL,0xf9f7a28ac7899a96L,0xd2ae8ac8872dc112L,\n        0xfa0642ca73c3c459L } },\n    /* 31 << 210 */\n    { { 0x15296981e7dfc8d6L,0x67cd44501fb5b94aL,0x0ec71cf10eddfd37L,\n        0xc7e5eeb39a8eddc7L },\n      { 0x02ac8e3d81d95028L,0x0088f17270b0e35dL,0xec041fabe1881fe3L,\n        0x62cf71b8d99e7faaL } },\n    /* 32 << 210 */\n    { { 0x5043dea7e0f222c2L,0x309d42ac72e65142L,0x94fe9ddd9216cd30L,\n        0xd6539c7d0f87feecL },\n      { 0x03c5a57c432ac7d7L,0x72692cf0327fda10L,0xec28c85f280698deL,\n        0x2331fb467ec283b1L } },\n    /* 33 << 210 */\n    { { 0xd34bfa322867e633L,0x78709a820a9cc815L,0xb7fe6964875e2fa5L,\n        0x25cc064f9e98bfb5L },\n      { 0x9eb0151c493a65c5L,0x5fb5d94153182464L,0x69e6f130f04618e2L,\n        0xa8ecec22f89c8ab6L } },\n    /* 34 << 210 */\n    { { 0xcd6ac88bb96209bdL,0x65fa8cdbb3e1c9e0L,0xa47d22f54a8d8eacL,\n        0x83895cdf8d33f963L },\n      { 0xa8adca59b56cd3d1L,0x10c8350bdaf38232L,0x2b161fb3a5080a9fL,\n        0xbe7f5c643af65b3aL } },\n    /* 35 << 210 */\n    { { 0x2c75403997403a11L,0x94626cf7121b96afL,0x431de7c46a983ec2L,\n        0x3780dd3a52cc3df7L },\n      { 0xe28a0e462baf8e3bL,0xabe68aad51d299aeL,0x603eb8f9647a2408L,\n        0x14c61ed65c750981L } },\n    /* 36 << 210 */\n    { { 0x88b34414c53352e7L,0x5a34889c1337d46eL,0x612c1560f95f2bc8L,\n        0x8a3f8441d4807a3aL },\n      { 0x680d9e975224da68L,0x60cd6e88c3eb00e9L,0x3875a98e9a6bc375L,\n        0xdc80f9244fd554c2L } },\n    /* 37 << 210 */\n    { { 0x6c4b34156ac77407L,0xa1e5ea8f25420681L,0x541bfa144607a458L,\n        0x5dbc7e7a96d7fbf9L },\n      { 0x646a851b31590a47L,0x039e85ba15ee6df8L,0xd19fa231d7b43fc0L,\n        0x84bc8be8299a0e04L } },\n    /* 38 << 210 */\n    { { 0x2b9d2936f20df03aL,0x240543828608d472L,0x76b6ba049149202aL,\n        0xb21c38313670e7b7L },\n      { 0xddd93059d6fdee10L,0x9da47ad378488e71L,0x99cc1dfda0fcfb25L,\n        0x42abde1064696954L } },\n    /* 39 << 210 */\n    { { 0x14cc15fc17eab9feL,0xd6e863e4d3e70972L,0x29a7765c6432112cL,\n        0x886600015b0774d8L },\n      { 0x3729175a2c088eaeL,0x13afbcae8230b8d4L,0x44768151915f4379L,\n        0xf086431ad8d22812L } },\n    /* 40 << 210 */\n    { { 0x37461955c298b974L,0x905fb5f0f8711e04L,0x787abf3afe969d18L,\n        0x392167c26f6a494eL },\n      { 0xfc7a0d2d28c511daL,0xf127c7dcb66a262dL,0xf9c4bb95fd63fdf0L,\n        0x900165893913ef46L } },\n    /* 41 << 210 */\n    { { 0x74d2a73c11aa600dL,0x2f5379bd9fb5ab52L,0xe49e53a47fb70068L,\n        0x68dd39e5404aa9a7L },\n      { 0xb9b0cf572ecaa9c3L,0xba0e103be824826bL,0x60c2198b4631a3c4L,\n        0xc5ff84abfa8966a2L } },\n    /* 42 << 210 */\n    { { 0x2d6ebe22ac95aff8L,0x1c9bb6dbb5a46d09L,0x419062da53ee4f8dL,\n        0x7b9042d0bb97efefL },\n      { 0x0f87f080830cf6bdL,0x4861d19a6ec8a6c6L,0xd3a0daa1202f01aaL,\n        0xb0111674f25afbd5L } },\n    /* 43 << 210 */\n    { { 0x6d00d6cf1afb20d9L,0x1369500040671bc5L,0x913ab0dc2485ea9bL,\n        0x1f2bed069eef61acL },\n      { 0x850c82176d799e20L,0x93415f373271c2deL,0x5afb06e96c4f5910L,\n        0x688a52dfc4e9e421L } },\n    /* 44 << 210 */\n    { { 0x30495ba3e2a9a6dbL,0x4601303d58f9268bL,0xbe3b0dad7eb0f04fL,\n        0x4ea472504456936dL },\n      { 0x8caf8798d33fd3e7L,0x1ccd8a89eb433708L,0x9effe3e887fd50adL,\n        0xbe240a566b29c4dfL } },\n    /* 45 << 210 */\n    { { 0xec4ffd98ca0e7ebdL,0xf586783ae748616eL,0xa5b00d8fc77baa99L,\n        0x0acada29b4f34c9cL },\n      { 0x36dad67d0fe723acL,0x1d8e53a539c36c1eL,0xe4dd342d1f4bea41L,\n        0x64fd5e35ebc9e4e0L } },\n    /* 46 << 210 */\n    { { 0x96f01f9057908805L,0xb5b9ea3d5ed480ddL,0x366c5dc23efd2dd0L,\n        0xed2fe3056e9dfa27L },\n      { 0x4575e8926e9197e2L,0x11719c09ab502a5dL,0x264c7bece81f213fL,\n        0x741b924155f5c457L } },\n    /* 47 << 210 */\n    { { 0x78ac7b6849a5f4f4L,0xf91d70a29fc45b7dL,0x39b05544b0f5f355L,\n        0x11f06bceeef930d9L },\n      { 0xdb84d25d038d05e1L,0x04838ee5bacc1d51L,0x9da3ce869e8ee00bL,\n        0xc3412057c36eda1fL } },\n    /* 48 << 210 */\n    { { 0xae80b91364d9c2f4L,0x7468bac3a010a8ffL,0xdfd2003737359d41L,\n        0x1a0f5ab815efeaccL },\n      { 0x7c25ad2f659d0ce0L,0x4011bcbb6785cff1L,0x128b99127e2192c7L,\n        0xa549d8e113ccb0e8L } },\n    /* 49 << 210 */\n    { { 0x805588d8c85438b1L,0x5680332dbc25cb27L,0xdcd1bc961a4bfdf4L,\n        0x779ff428706f6566L },\n      { 0x8bbee998f059987aL,0xf6ce8cf2cc686de7L,0xf8ad3c4a953cfdb2L,\n        0xd1d426d92205da36L } },\n    /* 50 << 210 */\n    { { 0xb3c0f13fc781a241L,0x3e89360ed75362a8L,0xccd05863c8a91184L,\n        0x9bd0c9b7efa8a7f4L },\n      { 0x97ee4d538a912a4bL,0xde5e15f8bcf518fdL,0x6a055bf8c467e1e0L,\n        0x10be4b4b1587e256L } },\n    /* 51 << 210 */\n    { { 0xd90c14f2668621c9L,0xd5518f51ab9c92c1L,0x8e6a0100d6d47b3cL,\n        0xcbe980dd66716175L },\n      { 0x500d3f10ddd83683L,0x3b6cb35d99cac73cL,0x53730c8b6083d550L,\n        0xcf159767df0a1987L } },\n    /* 52 << 210 */\n    { { 0x84bfcf5343ad73b3L,0x1b528c204f035a94L,0x4294edf733eeac69L,\n        0xb6283e83817f3240L },\n      { 0xc3fdc9590a5f25b1L,0xefaf8aa55844ee22L,0xde269ba5dbdde4deL,\n        0xe3347160c56133bfL } },\n    /* 53 << 210 */\n    { { 0xc11842198d9ea9f8L,0x090de5dbf3fc1ab5L,0x404c37b10bf22cdaL,\n        0x7de20ec8f5618894L },\n      { 0x754c588eecdaecabL,0x6ca4b0ed88342743L,0x76f08bddf4a938ecL,\n        0xd182de8991493ccbL } },\n    /* 54 << 210 */\n    { { 0xd652c53ec8a4186aL,0xb3e878db946d8e33L,0x088453c05f37663cL,\n        0x5cd9daaab407748bL },\n      { 0xa1f5197f586d5e72L,0x47500be8c443ca59L,0x78ef35b2e2652424L,\n        0x09c5d26f6dd7767dL } },\n    /* 55 << 210 */\n    { { 0x7175a79aa74d3f7bL,0x0428fd8dcf5ea459L,0x511cb97ca5d1746dL,\n        0x36363939e71d1278L },\n      { 0xcf2df95510350bf4L,0xb381743960aae782L,0xa748c0e43e688809L,\n        0x98021fbfd7a5a006L } },\n    /* 56 << 210 */\n    { { 0x9076a70c0e367a98L,0xbea1bc150f62b7c2L,0x2645a68c30fe0343L,\n        0xacaffa78699dc14fL },\n      { 0xf4469964457bf9c4L,0x0db6407b0d2ead83L,0x68d56cadb2c6f3ebL,\n        0x3b512e73f376356cL } },\n    /* 57 << 210 */\n    { { 0xe43b0e1ffce10408L,0x89ddc0035a5e257dL,0xb0ae0d120362e5b3L,\n        0x07f983c7b0519161L },\n      { 0xc2e94d155d5231e7L,0xcff22aed0b4f9513L,0xb02588dd6ad0b0b5L,\n        0xb967d1ac11d0dcd5L } },\n    /* 58 << 210 */\n    { { 0x8dac6bc6cf777b6cL,0x0062bdbd4c6d1959L,0x53da71b50ef5cc85L,\n        0x07012c7d4006f14fL },\n      { 0x4617f962ac47800dL,0x53365f2bc102ed75L,0xb422efcb4ab8c9d3L,\n        0x195cb26b34af31c9L } },\n    /* 59 << 210 */\n    { { 0x3a926e2905f2c4ceL,0xbd2bdecb9856966cL,0x5d16ab3a85527015L,\n        0x9f81609e4486c231L },\n      { 0xd8b96b2cda350002L,0xbd054690fa1b7d36L,0xdc90ebf5e71d79bcL,\n        0xf241b6f908964e4eL } },\n    /* 60 << 210 */\n    { { 0x7c8386432fe3cd4cL,0xe0f33acbb4bc633cL,0xb4a9ecec3d139f1fL,\n        0x05ce69cddc4a1f49L },\n      { 0xa19d1b16f5f98aafL,0x45bb71d66f23e0efL,0x33789fcd46cdfdd3L,\n        0x9b8e2978cee040caL } },\n    /* 61 << 210 */\n    { { 0x9c69b246ae0a6828L,0xba533d247078d5aaL,0x7a2e42c07bb4fbdbL,\n        0xcfb4879a7035385cL },\n      { 0x8c3dd30b3281705bL,0x7e361c6c404fe081L,0x7b21649c3f604edfL,\n        0x5dbf6a3fe52ffe47L } },\n    /* 62 << 210 */\n    { { 0xc41b7c234b54d9bfL,0x1374e6813511c3d9L,0x1863bf16c1b2b758L,\n        0x90e785071e9e6a96L },\n      { 0xab4bf98d5d86f174L,0xd74e0bd385e96fe4L,0x8afde39fcac5d344L,\n        0x90946dbcbd91b847L } },\n    /* 63 << 210 */\n    { { 0xf5b42358fe1a838cL,0x05aae6c5620ac9d8L,0x8e193bd8a1ce5a0bL,\n        0x8f7105714dabfd72L },\n      { 0x8d8fdd48182caaacL,0x8c4aeefa040745cfL,0x73c6c30af3b93e6dL,\n        0x991241f316f42011L } },\n    /* 64 << 210 */\n    { { 0xa0158eeae457a477L,0xd19857dbee6ddc05L,0xb326522418c41671L,\n        0x3ffdfc7e3c2c0d58L },\n      { 0x3a3a525426ee7cdaL,0x341b0869df02c3a8L,0xa023bf42723bbfc8L,\n        0x3d15002a14452691L } },\n    /* 0 << 217 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 217 */\n    { { 0x5ef7324c85edfa30L,0x2597655487d4f3daL,0x352f5bc0dcb50c86L,\n        0x8f6927b04832a96cL },\n      { 0xd08ee1ba55f2f94cL,0x6a996f99344b45faL,0xe133cb8da8aa455dL,\n        0x5d0721ec758dc1f7L } },\n    /* 2 << 217 */\n    { { 0x6ba7a92079e5fb67L,0xe1331feb70aa725eL,0x5080ccf57df5d837L,\n        0xe4cae01d7ff72e21L },\n      { 0xd9243ee60412a77dL,0x06ff7cacdf449025L,0xbe75f7cd23ef5a31L,\n        0xbc9578220ddef7a8L } },\n    /* 3 << 217 */\n    { { 0x8cf7230cb0ce1c55L,0x5b534d050bbfb607L,0xee1ef1130e16363bL,\n        0x27e0aa7ab4999e82L },\n      { 0xce1dac2d79362c41L,0x67920c9091bb6cb0L,0x1e648d632223df24L,\n        0x0f7d9eefe32e8f28L } },\n    /* 4 << 217 */\n    { { 0x6943f39afa833834L,0x22951722a6328562L,0x81d63dd54170fc10L,\n        0x9f5fa58faecc2e6dL },\n      { 0xb66c8725e77d9a3bL,0x11235cea6384ebe0L,0x06a8c1185845e24aL,\n        0x0137b286ebd093b1L } },\n    /* 5 << 217 */\n    { { 0xc589e1ce44ace150L,0xe0f8d3d94381e97cL,0x59e99b1162c5a4b8L,\n        0x90d262f7fd0ec9f9L },\n      { 0xfbc854c9283e13c9L,0x2d04fde7aedc7085L,0x057d776547dcbecbL,\n        0x8dbdf5919a76fa5fL } },\n    /* 6 << 217 */\n    { { 0xd01506950de1e578L,0x2e1463e7e9f72bc6L,0xffa684411b39eca5L,\n        0x673c85307c037f2fL },\n      { 0xd0d6a600747f91daL,0xb08d43e1c9cb78e9L,0x0fc0c64427b5cef5L,\n        0x5c1d160aa60a2fd6L } },\n    /* 7 << 217 */\n    { { 0xf98cae5328c8e13bL,0x375f10c4b2eddcd1L,0xd4eb8b7f5cce06adL,\n        0xb4669f4580a2e1efL },\n      { 0xd593f9d05bbd8699L,0x5528a4c9e7976d13L,0x3923e0951c7e28d3L,\n        0xb92937903f6bb577L } },\n    /* 8 << 217 */\n    { { 0xdb567d6ac42bd6d2L,0x6df86468bb1f96aeL,0x0efe5b1a4843b28eL,\n        0x961bbb056379b240L },\n      { 0xb6caf5f070a6a26bL,0x70686c0d328e6e39L,0x80da06cf895fc8d3L,\n        0x804d8810b363fdc9L } },\n    /* 9 << 217 */\n    { { 0xbe22877b207f1670L,0x9b0dd1884e615291L,0x625ae8dc97a3c2bfL,\n        0x08584ef7439b86e8L },\n      { 0xde7190a5dcd898ffL,0x26286c402058ee3dL,0x3db0b2175f87b1c1L,\n        0xcc334771102a6db5L } },\n    /* 10 << 217 */\n    { { 0xd99de9542f770fb1L,0x97c1c6204cd7535eL,0xd3b6c4483f09cefcL,\n        0xd725af155a63b4f8L },\n      { 0x0c95d24fc01e20ecL,0xdfd374949ae7121fL,0x7d6ddb72ec77b7ecL,\n        0xfe079d3b0353a4aeL } },\n    /* 11 << 217 */\n    { { 0x3066e70a2e6ac8d2L,0x9c6b5a43106e5c05L,0x52d3c6f5ede59b8cL,\n        0x30d6a5c3fccec9aeL },\n      { 0xedec7c224fc0a9efL,0x190ff08395c16cedL,0xbe12ec8f94de0fdeL,\n        0x0d131ab8852d3433L } },\n    /* 12 << 217 */\n    { { 0x42ace07e85701291L,0x94793ed9194061a8L,0x30e83ed6d7f4a485L,\n        0x9eec7269f9eeff4dL },\n      { 0x90acba590c9d8005L,0x5feca4581e79b9d1L,0x8fbe54271d506a1eL,\n        0xa32b2c8e2439cfa7L } },\n    /* 13 << 217 */\n    { { 0x1671c17373dd0b4eL,0x37a2821444a054c6L,0x81760a1b4e8b53f1L,\n        0xa6c04224f9f93b9eL },\n      { 0x18784b34cf671e3cL,0x81bbecd2cda9b994L,0x38831979b2ab3848L,\n        0xef54feb7f2e03c2dL } },\n    /* 14 << 217 */\n    { { 0xcf197ca7fb8088faL,0x014272474ddc96c5L,0xa2d2550a30777176L,\n        0x534698984d0cf71dL },\n      { 0x6ce937b83a2aaac6L,0xe9f91dc35af38d9bL,0x2598ad83c8bf2899L,\n        0x8e706ac9b5536c16L } },\n    /* 15 << 217 */\n    { { 0x40dc7495f688dc98L,0x26490cd7124c4afcL,0xe651ec841f18775cL,\n        0x393ea6c3b4fdaf4aL },\n      { 0x1e1f33437f338e0dL,0x39fb832b6053e7b5L,0x46e702da619e14d5L,\n        0x859cacd1cdeef6e0L } },\n    /* 16 << 217 */\n    { { 0x63b99ce74462007dL,0xb8ab48a54cb5f5b7L,0x9ec673d2f55edde7L,\n        0xd1567f748cfaefdaL },\n      { 0x46381b6b0887bcecL,0x694497cee178f3c2L,0x5e6525e31e6266cbL,\n        0x5931de26697d6413L } },\n    /* 17 << 217 */\n    { { 0x87f8df7c0e58d493L,0xb1ae5ed058b73f12L,0xc368f784dea0c34dL,\n        0x9bd0a120859a91a0L },\n      { 0xb00d88b7cc863c68L,0x3a1cc11e3d1f4d65L,0xea38e0e70aa85593L,\n        0x37f13e987dc4aee8L } },\n    /* 18 << 217 */\n    { { 0x10d38667bc947badL,0x738e07ce2a36ee2eL,0xc93470cdc577fcacL,\n        0xdee1b6162782470dL },\n      { 0x36a25e672e793d12L,0xd6aa6caee0f186daL,0x474d0fd980e07af7L,\n        0xf7cdc47dba8a5cd4L } },\n    /* 19 << 217 */\n    { { 0x28af6d9dab15247fL,0x7c789c10493a537fL,0x7ac9b11023a334e7L,\n        0x0236ac0912c9c277L },\n      { 0xa7e5bd251d7a5144L,0x098b9c2af13ec4ecL,0x3639dacad3f0abcaL,\n        0x642da81aa23960f9L } },\n    /* 20 << 217 */\n    { { 0x7d2e5c054f7269b1L,0xfcf30777e287c385L,0x10edc84ff2a46f21L,\n        0x354417574f43fa36L },\n      { 0xf1327899fd703431L,0xa438d7a616dd587aL,0x65c34c57e9c8352dL,\n        0xa728edab5cc5a24eL } },\n    /* 21 << 217 */\n    { { 0xaed78abc42531689L,0x0a51a0e8010963efL,0x5776fa0ad717d9b3L,\n        0xf356c2397dd3428bL },\n      { 0x29903fff8d3a3dacL,0x409597fa3d94491fL,0x4cd7a5ffbf4a56a4L,\n        0xe50964748adab462L } },\n    /* 22 << 217 */\n    { { 0xa97b51265c3427b0L,0x6401405cd282c9bdL,0x3629f8d7222c5c45L,\n        0xb1c02c16e8d50aedL },\n      { 0xbea2ed75d9635bc9L,0x226790c76e24552fL,0x3c33f2a365f1d066L,\n        0x2a43463e6dfccc2eL } },\n    /* 23 << 217 */\n    { { 0x8cc3453adb483761L,0xe7cc608565d5672bL,0x277ed6cbde3efc87L,\n        0x19f2f36869234eafL },\n      { 0x9aaf43175c0b800bL,0x1f1e7c898b6da6e2L,0x6cfb4715b94ec75eL,\n        0xd590dd5f453118c2L } },\n    /* 24 << 217 */\n    { { 0x14e49da11f17a34cL,0x5420ab39235a1456L,0xb76372412f50363bL,\n        0x7b15d623c3fabb6eL },\n      { 0xa0ef40b1e274e49cL,0x5cf5074496b1860aL,0xd6583fbf66afe5a4L,\n        0x44240510f47e3e9aL } },\n    /* 25 << 217 */\n    { { 0x9925434311b2d595L,0xf1367499eec8df57L,0x3cb12c613e73dd05L,\n        0xd248c0337dac102aL },\n      { 0xcf154f13a77739f5L,0xbf4288cb23d2af42L,0xaa64c9b632e4a1cfL,\n        0xee8c07a8c8a208f3L } },\n    /* 26 << 217 */\n    { { 0xe10d49996fe8393fL,0x0f809a3fe91f3a32L,0x61096d1c802f63c8L,\n        0x289e146257750d3dL },\n      { 0xed06167e9889feeaL,0xd5c9c0e2e0993909L,0x46fca0d856508ac6L,\n        0x918260474f1b8e83L } },\n    /* 27 << 217 */\n    { { 0x4f2c877a9a4a2751L,0x71bd0072cae6feadL,0x38df8dcc06aa1941L,\n        0x5a074b4c63beeaa8L },\n      { 0xd6d65934c1cec8edL,0xa6ecb49eaabc03bdL,0xaade91c2de8a8415L,\n        0xcfb0efdf691136e0L } },\n    /* 28 << 217 */\n    { { 0x11af45ee23ab3495L,0xa132df880b77463dL,0x8923c15c815d06f4L,\n        0xc3ceb3f50d61a436L },\n      { 0xaf52291de88fb1daL,0xea0579741da12179L,0xb0d7218cd2fef720L,\n        0x6c0899c98e1d8845L } },\n    /* 29 << 217 */\n    { { 0x98157504752ddad7L,0xd60bd74fa1a68a97L,0x7047a3a9f658fb99L,\n        0x1f5d86d65f8511e4L },\n      { 0xb8a4bc424b5a6d88L,0x69eb2c331abefa7dL,0x95bf39e813c9c510L,\n        0xf571960ad48aab43L } },\n    /* 30 << 217 */\n    { { 0x7e8cfbcf704e23c6L,0xc71b7d2228aaa65bL,0xa041b2bd245e3c83L,\n        0x69b98834d21854ffL },\n      { 0x89d227a3963bfeecL,0x99947aaade7da7cbL,0x1d9ee9dbee68a9b1L,\n        0x0a08f003698ec368L } },\n    /* 31 << 217 */\n    { { 0xe9ea409478ef2487L,0xc8d2d41502cfec26L,0xc52f9a6eb7dcf328L,\n        0x0ed489e385b6a937L },\n      { 0x9b94986bbef3366eL,0x0de59c70edddddb8L,0xffdb748ceadddbe2L,\n        0x9b9784bb8266ea40L } },\n    /* 32 << 217 */\n    { { 0x142b55021a93507aL,0xb4cd11878d3c06cfL,0xdf70e76a91ec3f40L,\n        0x484e81ad4e7553c2L },\n      { 0x830f87b5272e9d6eL,0xea1c93e5c6ff514aL,0x67cc2adcc4192a8eL,\n        0xc77e27e242f4535aL } },\n    /* 33 << 217 */\n    { { 0x9cdbab36d2b713c5L,0x86274ea0cf7b0cd3L,0x784680f309af826bL,\n        0xbfcc837a0c72dea3L },\n      { 0xa8bdfe9dd6529b73L,0x708aa22863a88002L,0x6c7a9a54c91d45b9L,\n        0xdf1a38bbfd004f56L } },\n    /* 34 << 217 */\n    { { 0x2e8c9a26b8bad853L,0x2d52cea33723eae7L,0x054d6d8156ca2830L,\n        0xa3317d149a8dc411L },\n      { 0xa08662fefd4ddedaL,0xed2a153ab55d792bL,0x7035c16abfc6e944L,\n        0xb6bc583400171cf3L } },\n    /* 35 << 217 */\n    { { 0xe27152b383d102b6L,0xfe695a470646b848L,0xa5bb09d8916e6d37L,\n        0xb4269d640d17015eL },\n      { 0x8d8156a10a1d2285L,0xfeef6c5146d26d72L,0x9dac57c84c5434a7L,\n        0x0282e5be59d39e31L } },\n    /* 36 << 217 */\n    { { 0xedfff181721c486dL,0x301baf10bc58824eL,0x8136a6aa00570031L,\n        0x55aaf78c1cddde68L },\n      { 0x2682937159c63952L,0x3a3bd2748bc25bafL,0xecdf8657b7e52dc3L,\n        0x2dd8c087fd78e6c8L } },\n    /* 37 << 217 */\n    { { 0x20553274f5531461L,0x8b4a12815d95499bL,0xe2c8763a1a80f9d2L,\n        0xd1dbe32b4ddec758L },\n      { 0xaf12210d30c34169L,0xba74a95378baa533L,0x3d133c6ea438f254L,\n        0xa431531a201bef5bL } },\n    /* 38 << 217 */\n    { { 0x15295e22f669d7ecL,0xca374f64357fb515L,0x8a8406ffeaa3fdb3L,\n        0x106ae448df3f2da8L },\n      { 0x8f9b0a9033c8e9a1L,0x234645e271ad5885L,0x3d0832241c0aed14L,\n        0xf10a7d3e7a942d46L } },\n    /* 39 << 217 */\n    { { 0x7c11deee40d5c9beL,0xb2bae7ffba84ed98L,0x93e97139aad58dddL,\n        0x3d8727963f6d1fa3L },\n      { 0x483aca818569ff13L,0x8b89a5fb9a600f72L,0x4cbc27c3c06f2b86L,\n        0x2213071363ad9c0bL } },\n    /* 40 << 217 */\n    { { 0xb5358b1e48ac2840L,0x18311294ecba9477L,0xda58f990a6946b43L,\n        0x3098baf99ab41819L },\n      { 0x66c4c1584198da52L,0xab4fc17c146bfd1bL,0x2f0a4c3cbf36a908L,\n        0x2ae9e34b58cf7838L } },\n    /* 41 << 217 */\n    { { 0xf411529e3fa11b1fL,0x21e43677974af2b4L,0x7c20958ec230793bL,\n        0x710ea88516e840f3L },\n      { 0xfc0b21fcc5dc67cfL,0x08d5164788405718L,0xd955c21fcfe49eb7L,\n        0x9722a5d556dd4a1fL } },\n    /* 42 << 217 */\n    { { 0xc9ef50e2c861baa5L,0xc0c21a5d9505ac3eL,0xaf6b9a338b7c063fL,\n        0xc63703392f4779c1L },\n      { 0x22df99c7638167c3L,0xfe6ffe76795db30cL,0x2b822d33a4854989L,\n        0xfef031dd30563aa5L } },\n    /* 43 << 217 */\n    { { 0x16b09f82d57c667fL,0xc70312cecc0b76f1L,0xbf04a9e6c9118aecL,\n        0x82fcb4193409d133L },\n      { 0x1a8ab385ab45d44dL,0xfba07222617b83a3L,0xb05f50dd58e81b52L,\n        0x1d8db55321ce5affL } },\n    /* 44 << 217 */\n    { { 0x3097b8d4e344a873L,0x7d8d116dfe36d53eL,0x6db22f587875e750L,\n        0x2dc5e37343e144eaL },\n      { 0xc05f32e6e799eb95L,0xe9e5f4df6899e6ecL,0xbdc3bd681fab23d5L,\n        0xb72b8ab773af60e6L } },\n    /* 45 << 217 */\n    { { 0x8db27ae02cecc84aL,0x600016d87bdb871cL,0x42a44b13d7c46f58L,\n        0xb8919727c3a77d39L },\n      { 0xcfc6bbbddafd6088L,0x1a7401466bd20d39L,0x8c747abd98c41072L,\n        0x4c91e765bdf68ea1L } },\n    /* 46 << 217 */\n    { { 0x7c95e5ca08819a78L,0xcf48b729c9587921L,0x091c7c5fdebbcc7dL,\n        0x6f287404f0e05149L },\n      { 0xf83b5ac226cd44ecL,0x88ae32a6cfea250eL,0x6ac5047a1d06ebc5L,\n        0xc7e550b4d434f781L } },\n    /* 47 << 217 */\n    { { 0x61ab1cf25c727bd2L,0x2e4badb11cf915b0L,0x1b4dadecf69d3920L,\n        0xe61b1ca6f14c1dfeL },\n      { 0x90b479ccbd6bd51fL,0x8024e4018045ec30L,0xcab29ca325ef0e62L,\n        0x4f2e941649e4ebc0L } },\n    /* 48 << 217 */\n    { { 0x45eb40ec0ccced58L,0x25cd4b9c0da44f98L,0x43e06458871812c6L,\n        0x99f80d5516cef651L },\n      { 0x571340c9ce6dc153L,0x138d5117d8665521L,0xacdb45bc4e07014dL,\n        0x2f34bb3884b60b91L } },\n    /* 49 << 217 */\n    { { 0xf44a4fd22ae8921eL,0xb039288e892ba1e2L,0x9da50174b1c180b2L,\n        0x6b70ab661693dc87L },\n      { 0x7e9babc9e7057481L,0x4581ddef9c80dc41L,0x0c890da951294682L,\n        0x0b5629d33f4736e5L } },\n    /* 50 << 217 */\n    { { 0x2340c79eb06f5b41L,0xa42e84ce4e243469L,0xf9a20135045a71a9L,\n        0xefbfb415d27b6fb6L },\n      { 0x25ebea239d33cd6fL,0x9caedb88aa6c0af8L,0x53dc7e9ad9ce6f96L,\n        0x3897f9fd51e0b15aL } },\n    /* 51 << 217 */\n    { { 0xf51cb1f88e5d788eL,0x1aec7ba8e1d490eeL,0x265991e0cc58cb3cL,\n        0x9f306e8c9fc3ad31L },\n      { 0x5fed006e5040a0acL,0xca9d5043fb476f2eL,0xa19c06e8beea7a23L,\n        0xd28658010edabb63L } },\n    /* 52 << 217 */\n    { { 0xdb92293f6967469aL,0x2894d8398d8a8ed8L,0x87c9e406bbc77122L,\n        0x8671c6f12ea3a26aL },\n      { 0xe42df8d6d7de9853L,0x2e3ce346b1f2bcc7L,0xda601dfc899d50cfL,\n        0xbfc913defb1b598fL } },\n    /* 53 << 217 */\n    { { 0x81c4909fe61f7908L,0x192e304f9bbc7b29L,0xc3ed8738c104b338L,\n        0xedbe9e47783f5d61L },\n      { 0x0c06e9be2db30660L,0xda3e613fc0eb7d8eL,0xd8fa3e97322e096eL,\n        0xfebd91e8d336e247L } },\n    /* 54 << 217 */\n    { { 0x8f13ccc4df655a49L,0xa9e00dfc5eb20210L,0x84631d0fc656b6eaL,\n        0x93a058cdd8c0d947L },\n      { 0x6846904a67bd3448L,0x4a3d4e1af394fd5cL,0xc102c1a5db225f52L,\n        0xe3455bbafc4f5e9aL } },\n    /* 55 << 217 */\n    { { 0x6b36985b4b9ad1ceL,0xa98185365bb7f793L,0x6c25e1d048b1a416L,\n        0x1381dd533c81bee7L },\n      { 0xd2a30d617a4a7620L,0xc841292639b8944cL,0x3c1c6fbe7a97c33aL,\n        0x941e541d938664e7L } },\n    /* 56 << 217 */\n    { { 0x417499e84a34f239L,0x15fdb83cb90402d5L,0xb75f46bf433aa832L,\n        0xb61e15af63215db1L },\n      { 0xaabe59d4a127f89aL,0x5d541e0c07e816daL,0xaaba0659a618b692L,\n        0x5532773317266026L } },\n    /* 57 << 217 */\n    { { 0xaf53a0fc95f57552L,0x329476506cacb0c9L,0x253ff58dc821be01L,\n        0xb0309531a06f1146L },\n      { 0x59bbbdf505c2e54dL,0x158f27ad26e8dd22L,0xcc5b7ffb397e1e53L,\n        0xae03f65b7fc1e50dL } },\n    /* 58 << 217 */\n    { { 0xa9784ebd9c95f0f9L,0x5ed9deb224640771L,0x31244af7035561c4L,\n        0x87332f3a7ee857deL },\n      { 0x09e16e9e2b9e0d88L,0x52d910f456a06049L,0x507ed477a9592f48L,\n        0x85cb917b2365d678L } },\n    /* 59 << 217 */\n    { { 0xf8511c934c8998d1L,0x2186a3f1730ea58fL,0x50189626b2029db0L,\n        0x9137a6d902ceb75aL },\n      { 0x2fe17f37748bc82cL,0x87c2e93180469f8cL,0x850f71cdbf891aa2L,\n        0x0ca1b89b75ec3d8dL } },\n    /* 60 << 217 */\n    { { 0x516c43aa5e1cd3cdL,0x893978089a887c28L,0x0059c699ddea1f9fL,\n        0x7737d6fa8e6868f7L },\n      { 0x6d93746a60f1524bL,0x36985e55ba052aa7L,0x41b1d322ed923ea5L,\n        0x3429759f25852a11L } },\n    /* 61 << 217 */\n    { { 0xbeca6ec3092e9f41L,0x3a238c6662256bbdL,0xd82958ea70ad487dL,\n        0x4ac8aaf965610d93L },\n      { 0x3fa101b15e4ccab0L,0x9bf430f29de14bfbL,0xa10f5cc66531899dL,\n        0x590005fbea8ce17dL } },\n    /* 62 << 217 */\n    { { 0xc437912f24544cb6L,0x9987b71ad79ac2e3L,0x13e3d9ddc058a212L,\n        0x00075aacd2de9606L },\n      { 0x80ab508b6cac8369L,0x87842be7f54f6c89L,0xa7ad663d6bc532a4L,\n        0x67813de778a91bc8L } },\n    /* 63 << 217 */\n    { { 0x5dcb61cec3427239L,0x5f3c7cf0c56934d9L,0xc079e0fbe3191591L,\n        0xe40896bdb01aada7L },\n      { 0x8d4667910492d25fL,0x8aeb30c9e7408276L,0xe94374959287aaccL,\n        0x23d4708d79fe03d4L } },\n    /* 64 << 217 */\n    { { 0x8cda9cf2d0c05199L,0x502fbc22fae78454L,0xc0bda9dff572a182L,\n        0x5f9b71b86158b372L },\n      { 0xe0f33a592b82dd07L,0x763027359523032eL,0x7fe1a721c4505a32L,\n        0x7b6e3e82f796409fL } },\n    /* 0 << 224 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 224 */\n    { { 0xe3417bc035d0b34aL,0x440b386b8327c0a7L,0x8fb7262dac0362d1L,\n        0x2c41114ce0cdf943L },\n      { 0x2ba5cef1ad95a0b1L,0xc09b37a867d54362L,0x26d6cdd201e486c9L,\n        0x20477abf42ff9297L } },\n    /* 2 << 224 */\n    { { 0xa004dcb3292a9287L,0xddc15cf677b092c7L,0x083a8464806c0605L,\n        0x4a68df703db997b0L },\n      { 0x9c134e4505bf7dd0L,0xa4e63d398ccf7f8cL,0xa6e6517f41b5f8afL,\n        0xaa8b9342ad7bc1ccL } },\n    /* 3 << 224 */\n    { { 0x126f35b51e706ad9L,0xb99cebb4c3a9ebdfL,0xa75389afbf608d90L,\n        0x76113c4fc6c89858L },\n      { 0x80de8eb097e2b5aaL,0x7e1022cc63b91304L,0x3bdab6056ccc066cL,\n        0x33cbb144b2edf900L } },\n    /* 4 << 224 */\n    { { 0xc41764717af715d2L,0xe2f7f594d0134a96L,0x2c1873efa41ec956L,\n        0xe4e7b4f677821304L },\n      { 0xe5c8ff9788d5374aL,0x2b915e6380823d5bL,0xea6bc755b2ee8fe2L,\n        0x6657624ce7112651L } },\n    /* 5 << 224 */\n    { { 0x157af101dace5acaL,0xc4fdbcf211a6a267L,0xdaddf340c49c8609L,\n        0x97e49f52e9604a65L },\n      { 0x9be8e790937e2ad5L,0x846e2508326e17f1L,0x3f38007a0bbbc0dcL,\n        0xcf03603fb11e16d6L } },\n    /* 6 << 224 */\n    { { 0xd6f800e07442f1d5L,0x475607d166e0e3abL,0x82807f16b7c64047L,\n        0x8858e1e3a749883dL },\n      { 0x5859120b8231ee10L,0x1b80e7eb638a1eceL,0xcb72525ac6aa73a4L,\n        0xa7cdea3d844423acL } },\n    /* 7 << 224 */\n    { { 0x5ed0c007f8ae7c38L,0x6db07a5c3d740192L,0xbe5e9c2a5fe36db3L,\n        0xd5b9d57a76e95046L },\n      { 0x54ac32e78eba20f2L,0xef11ca8f71b9a352L,0x305e373eff98a658L,\n        0xffe5a100823eb667L } },\n    /* 8 << 224 */\n    { { 0x57477b11e51732d2L,0xdfd6eb282538fc0eL,0x5c43b0cc3b39eec5L,\n        0x6af12778cb36cc57L },\n      { 0x70b0852d06c425aeL,0x6df92f8c5c221b9bL,0x6c8d4f9ece826d9cL,\n        0xf59aba7bb49359c3L } },\n    /* 9 << 224 */\n    { { 0x5c8ed8d5da64309dL,0x61a6de5691b30704L,0xd6b52f6a2f9b5808L,\n        0x0eee419498c958a7L },\n      { 0xcddd9aab771e4caaL,0x83965dfd78bc21beL,0x02affce3b3b504f5L,\n        0x30847a21561c8291L } },\n    /* 10 << 224 */\n    { { 0xd2eb2cf152bfda05L,0xe0e4c4e96197b98cL,0x1d35076cf8a1726fL,\n        0x6c06085b2db11e3dL },\n      { 0x15c0c4d74463ba14L,0x9d292f830030238cL,0x1311ee8b3727536dL,\n        0xfeea86efbeaedc1eL } },\n    /* 11 << 224 */\n    { { 0xb9d18cd366131e2eL,0xf31d974f80fe2682L,0xb6e49e0fe4160289L,\n        0x7c48ec0b08e92799L },\n      { 0x818111d8d1989aa7L,0xb34fa0aaebf926f9L,0xdb5fe2f5a245474aL,\n        0xf80a6ebb3c7ca756L } },\n    /* 12 << 224 */\n    { { 0xa7f96054afa05dd8L,0x26dfcf21fcaf119eL,0xe20ef2e30564bb59L,\n        0xef4dca5061cb02b8L },\n      { 0xcda7838a65d30672L,0x8b08d534fd657e86L,0x4c5b439546d595c8L,\n        0x39b58725425cb836L } },\n    /* 13 << 224 */\n    { { 0x8ea610593de9abe3L,0x404348819cdc03beL,0x9b261245cfedce8cL,\n        0x78c318b4cf5234a1L },\n      { 0x510bcf16fde24c99L,0x2a77cb75a2c2ff5dL,0x9c895c2b27960fb4L,\n        0xd30ce975b0eda42bL } },\n    /* 14 << 224 */\n    { { 0xfda853931a62cc26L,0x23c69b9650c0e052L,0xa227df15bfc633f3L,\n        0x2ac788481bae7d48L },\n      { 0x487878f9187d073dL,0x6c2be919967f807dL,0x765861d8336e6d8fL,\n        0x88b8974cce528a43L } },\n    /* 15 << 224 */\n    { { 0x09521177ff57d051L,0x2ff38037fb6a1961L,0xfc0aba74a3d76ad4L,\n        0x7c76480325a7ec17L },\n      { 0x7532d75f48879bc8L,0xea7eacc058ce6bc1L,0xc82176b48e896c16L,\n        0x9a30e0b22c750fedL } },\n    /* 16 << 224 */\n    { { 0xc37e2c2e421d3aa4L,0xf926407ce84fa840L,0x18abc03d1454e41cL,\n        0x26605ecd3f7af644L },\n      { 0x242341a6d6a5eabfL,0x1edb84f4216b668eL,0xd836edb804010102L,\n        0x5b337ce7945e1d8cL } },\n    /* 17 << 224 */\n    { { 0xd2075c77c055dc14L,0x2a0ffa2581d89cdfL,0x8ce815ea6ffdcbafL,\n        0xa3428878fb648867L },\n      { 0x277699cf884655fbL,0xfa5b5bd6364d3e41L,0x01f680c6441e1cb7L,\n        0x3fd61e66b70a7d67L } },\n    /* 18 << 224 */\n    { { 0x666ba2dccc78cf66L,0xb30181746fdbff77L,0x8d4dd0db168d4668L,\n        0x259455d01dab3a2aL },\n      { 0xf58564c5cde3acecL,0x7714192513adb276L,0x527d725d8a303f65L,\n        0x55deb6c9e6f38f7bL } },\n    /* 19 << 224 */\n    { { 0xfd5bb657b1fa70fbL,0xfa07f50fd8073a00L,0xf72e3aa7bca02500L,\n        0xf68f895d9975740dL },\n      { 0x301120605cae2a6aL,0x01bd721802874842L,0x3d4238917ce47bd3L,\n        0xa66663c1789544f6L } },\n    /* 20 << 224 */\n    { { 0x864d05d73272d838L,0xe22924f9fa6295c5L,0x8189593f6c2fda32L,\n        0x330d7189b184b544L },\n      { 0x79efa62cbde1f714L,0x35771c94e5cb1a63L,0x2f4826b8641c8332L,\n        0x00a894fbc8cee854L } },\n    /* 21 << 224 */\n    { { 0xb4b9a39b36194d40L,0xe857a7c577612601L,0xf4209dd24ecf2f58L,\n        0x82b9e66d5a033487L },\n      { 0xc1e36934e4e8b9ddL,0xd2372c9da42377d7L,0x51dc94c70e3ae43bL,\n        0x4c57761e04474f6fL } },\n    /* 22 << 224 */\n    { { 0xdcdacd0a1058a318L,0x369cf3f578053a9aL,0xc6c3de5031c68de2L,\n        0x4653a5763c4b6d9fL },\n      { 0x1688dd5aaa4e5c97L,0x5be80aa1b7ab3c74L,0x70cefe7cbc65c283L,\n        0x57f95f1306867091L } },\n    /* 23 << 224 */\n    { { 0xa39114e24415503bL,0xc08ff7c64cbb17e9L,0x1eff674dd7dec966L,\n        0x6d4690af53376f63L },\n      { 0xff6fe32eea74237bL,0xc436d17ecd57508eL,0x15aa28e1edcc40feL,\n        0x0d769c04581bbb44L } },\n    /* 24 << 224 */\n    { { 0xc240b6de34eaacdaL,0xd9e116e82ba0f1deL,0xcbe45ec779438e55L,\n        0x91787c9d96f752d7L },\n      { 0x897f532bf129ac2fL,0xd307b7c85a36e22cL,0x91940675749fb8f3L,\n        0xd14f95d0157fdb28L } },\n    /* 25 << 224 */\n    { { 0xfe51d0296ae55043L,0x8931e98f44a87de1L,0xe57f1cc609e4fee2L,\n        0x0d063b674e072d92L },\n      { 0x70a998b9ed0e4316L,0xe74a736b306aca46L,0xecf0fbf24fda97c7L,\n        0xa40f65cb3e178d93L } },\n    /* 26 << 224 */\n    { { 0x1625360416df4285L,0xb0c9babbd0c56ae2L,0x73032b19cfc5cfc3L,\n        0xe497e5c309752056L },\n      { 0x12096bb4164bda96L,0x1ee42419a0b74da1L,0x8fc36243403826baL,\n        0x0c8f0069dc09e660L } },\n    /* 27 << 224 */\n    { { 0x8667e981c27253c9L,0x05a6aefb92b36a45L,0xa62c4b369cb7bb46L,\n        0x8394f37511f7027bL },\n      { 0x747bc79c5f109d0fL,0xcad88a765b8cc60aL,0x80c5a66b58f09e68L,\n        0xe753d451f6127eacL } },\n    /* 28 << 224 */\n    { { 0xc44b74a15b0ec6f5L,0x47989fe45289b2b8L,0x745f848458d6fc73L,\n        0xec362a6ff61c70abL },\n      { 0x070c98a7b3a8ad41L,0x73a20fc07b63db51L,0xed2c2173f44c35f4L,\n        0x8a56149d9acc9dcaL } },\n    /* 29 << 224 */\n    { { 0x98f178819ac6e0f4L,0x360fdeafa413b5edL,0x0625b8f4a300b0fdL,\n        0xf1f4d76a5b3222d3L },\n      { 0x9d6f5109587f76b8L,0x8b4ee08d2317fdb5L,0x88089bb78c68b095L,\n        0x95570e9a5808d9b9L } },\n    /* 30 << 224 */\n    { { 0xa395c36f35d33ae7L,0x200ea12350bb5a94L,0x20c789bd0bafe84bL,\n        0x243ef52d0919276aL },\n      { 0x3934c577e23ae233L,0xb93807afa460d1ecL,0xb72a53b1f8fa76a4L,\n        0xd8914cb0c3ca4491L } },\n    /* 31 << 224 */\n    { { 0x2e1284943fb42622L,0x3b2700ac500907d5L,0xf370fb091a95ec63L,\n        0xf8f30be231b6dfbdL },\n      { 0xf2b2f8d269e55f15L,0x1fead851cc1323e9L,0xfa366010d9e5eef6L,\n        0x64d487b0e316107eL } },\n    /* 32 << 224 */\n    { { 0x4c076b86d23ddc82L,0x03fd344c7e0143f0L,0xa95362ff317af2c5L,\n        0x0add3db7e18b7a4fL },\n      { 0x9c673e3f8260e01bL,0xfbeb49e554a1cc91L,0x91351bf292f2e433L,\n        0xc755e7ec851141ebL } },\n    /* 33 << 224 */\n    { { 0xc9a9513929607745L,0x0ca07420a26f2b28L,0xcb2790e74bc6f9ddL,\n        0x345bbb58adcaffc0L },\n      { 0xc65ea38cbe0f27a2L,0x67c24d7c641fcb56L,0x2c25f0a7a9e2c757L,\n        0x93f5cdb016f16c49L } },\n    /* 34 << 224 */\n    { { 0x2ca5a9d7c5ee30a1L,0xd1593635b909b729L,0x804ce9f3dadeff48L,\n        0xec464751b07c30c3L },\n      { 0x89d65ff39e49af6aL,0xf2d6238a6f3d01bcL,0x1095561e0bced843L,\n        0x51789e12c8a13fd8L } },\n    /* 35 << 224 */\n    { { 0xd633f929763231dfL,0x46df9f7de7cbddefL,0x01c889c0cb265da8L,\n        0xfce1ad10af4336d2L },\n      { 0x8d110df6fc6a0a7eL,0xdd431b986da425dcL,0xcdc4aeab1834aabeL,\n        0x84deb1248439b7fcL } },\n    /* 36 << 224 */\n    { { 0x8796f1693c2a5998L,0x9b9247b47947190dL,0x55b9d9a511597014L,\n        0x7e9dd70d7b1566eeL },\n      { 0x94ad78f7cbcd5e64L,0x0359ac179bd4c032L,0x3b11baaf7cc222aeL,\n        0xa6a6e284ba78e812L } },\n    /* 37 << 224 */\n    { { 0x8392053f24cea1a0L,0xc97bce4a33621491L,0x7eb1db3435399ee9L,\n        0x473f78efece81ad1L },\n      { 0x41d72fe0f63d3d0dL,0xe620b880afab62fcL,0x92096bc993158383L,\n        0x41a213578f896f6cL } },\n    /* 38 << 224 */\n    { { 0x1b5ee2fac7dcfcabL,0x650acfde9546e007L,0xc081b749b1b02e07L,\n        0xda9e41a0f9eca03dL },\n      { 0x013ba727175a54abL,0xca0cd190ea5d8d10L,0x85ea52c095fd96a9L,\n        0x2c591b9fbc5c3940L } },\n    /* 39 << 224 */\n    { { 0x6fb4d4e42bad4d5fL,0xfa4c3590fef0059bL,0x6a10218af5122294L,\n        0x9a78a81aa85751d1L },\n      { 0x04f20579a98e84e7L,0xfe1242c04997e5b5L,0xe77a273bca21e1e4L,\n        0xfcc8b1ef9411939dL } },\n    /* 40 << 224 */\n    { { 0xe20ea30292d0487aL,0x1442dbec294b91feL,0x1f7a4afebb6b0e8fL,\n        0x1700ef746889c318L },\n      { 0xf5bbffc370f1fc62L,0x3b31d4b669c79ccaL,0xe8bc2aaba7f6340dL,\n        0xb0b08ab4a725e10aL } },\n    /* 41 << 224 */\n    { { 0x44f05701ae340050L,0xba4b30161cf0c569L,0x5aa29f83fbe19a51L,\n        0x1b9ed428b71d752eL },\n      { 0x1666e54eeb4819f5L,0x616cdfed9e18b75bL,0x112ed5be3ee27b0bL,\n        0xfbf2831944c7de4dL } },\n    /* 42 << 224 */\n    { { 0xd685ec85e0e60d84L,0x68037e301db7ee78L,0x5b65bdcd003c4d6eL,\n        0x33e7363a93e29a6aL },\n      { 0x995b3a6108d0756cL,0xd727f85c2faf134bL,0xfac6edf71d337823L,\n        0x99b9aa500439b8b4L } },\n    /* 43 << 224 */\n    { { 0x722eb104e2b4e075L,0x49987295437c4926L,0xb1e4c0e446a9b82dL,\n        0xd0cb319757a006f5L },\n      { 0xf3de0f7dd7808c56L,0xb5c54d8f51f89772L,0x500a114aadbd31aaL,\n        0x9afaaaa6295f6cabL } },\n    /* 44 << 224 */\n    { { 0x94705e2104cf667aL,0xfc2a811b9d3935d7L,0x560b02806d09267cL,\n        0xf19ed119f780e53bL },\n      { 0xf0227c09067b6269L,0x967b85335caef599L,0x155b924368efeebcL,\n        0xcd6d34f5c497bae6L } },\n    /* 45 << 224 */\n    { { 0x1dd8d5d36cceb370L,0x2aeac579a78d7bf9L,0x5d65017d70b67a62L,\n        0x70c8e44f17c53f67L },\n      { 0xd1fc095086a34d09L,0xe0fca256e7134907L,0xe24fa29c80fdd315L,\n        0x2c4acd03d87499adL } },\n    /* 46 << 224 */\n    { { 0xbaaf75173b5a9ba6L,0xb9cbe1f612e51a51L,0xd88edae35e154897L,\n        0xe4309c3c77b66ca0L },\n      { 0xf5555805f67f3746L,0x85fc37baa36401ffL,0xdf86e2cad9499a53L,\n        0x6270b2a3ecbc955bL } },\n    /* 47 << 224 */\n    { { 0xafae64f5974ad33bL,0x04d85977fe7b2df1L,0x2a3db3ff4ab03f73L,\n        0x0b87878a8702740aL },\n      { 0x6d263f015a061732L,0xc25430cea32a1901L,0xf7ebab3ddb155018L,\n        0x3a86f69363a9b78eL } },\n    /* 48 << 224 */\n    { { 0x349ae368da9f3804L,0x470f07fea164349cL,0xd52f4cc98562baa5L,\n        0xc74a9e862b290df3L },\n      { 0xd3a1aa3543471a24L,0x239446beb8194511L,0xbec2dd0081dcd44dL,\n        0xca3d7f0fc42ac82dL } },\n    /* 49 << 224 */\n    { { 0x1f3db085fdaf4520L,0xbb6d3e804549daf2L,0xf5969d8a19ad5c42L,\n        0x7052b13ddbfd1511L },\n      { 0x11890d1b682b9060L,0xa71d3883ac34452cL,0xa438055b783805b4L,\n        0x432412774725b23eL } },\n    /* 50 << 224 */\n    { { 0xf20cf96e4901bbedL,0x6419c710f432a2bbL,0x57a0fbb9dfa9cd7dL,\n        0x589111e400daa249L },\n      { 0x19809a337b60554eL,0xea5f8887ede283a4L,0x2d713802503bfd35L,\n        0x151bb0af585d2a53L } },\n    /* 51 << 224 */\n    { { 0x40b08f7443b30ca8L,0xe10b5bbad9934583L,0xe8a546d6b51110adL,\n        0x1dd50e6628e0b6c5L },\n      { 0x292e9d54cff2b821L,0x3882555d47281760L,0x134838f83724d6e3L,\n        0xf2c679e022ddcda1L } },\n    /* 52 << 224 */\n    { { 0x40ee88156d2a5768L,0x7f227bd21c1e7e2dL,0x487ba134d04ff443L,\n        0x76e2ff3dc614e54bL },\n      { 0x36b88d6fa3177ec7L,0xbf731d512328fff5L,0x758caea249ba158eL,\n        0x5ab8ff4c02938188L } },\n    /* 53 << 224 */\n    { { 0x33e1605635edc56dL,0x5a69d3497e940d79L,0x6c4fd00103866dcbL,\n        0x20a38f574893cdefL },\n      { 0xfbf3e790fac3a15bL,0x6ed7ea2e7a4f8e6bL,0xa663eb4fbc3aca86L,\n        0x22061ea5080d53f7L } },\n    /* 54 << 224 */\n    { { 0x2480dfe6f546783fL,0xd38bc6da5a0a641eL,0xfb093cd12ede8965L,\n        0x89654db4acb455cfL },\n      { 0x413cbf9a26e1adeeL,0x291f3764373294d4L,0x00797257648083feL,\n        0x25f504d3208cc341L } },\n    /* 55 << 224 */\n    { { 0x635a8e5ec3a0ee43L,0x70aaebca679898ffL,0x9ee9f5475dc63d56L,\n        0xce987966ffb34d00L },\n      { 0xf9f86b195e26310aL,0x9e435484382a8ca8L,0x253bcb81c2352fe4L,\n        0xa4eac8b04474b571L } },\n    /* 56 << 224 */\n    { { 0xc1b97512c1ad8cf8L,0x193b4e9e99e0b697L,0x939d271601e85df0L,\n        0x4fb265b3cd44eafdL },\n      { 0x321e7dcde51e1ae2L,0x8e3a8ca6e3d8b096L,0x8de46cb052604998L,\n        0x91099ad839072aa7L } },\n    /* 57 << 224 */\n    { { 0x2617f91c93aa96b8L,0x0fc8716b7fca2e13L,0xa7106f5e95328723L,\n        0xd1c9c40b262e6522L },\n      { 0xb9bafe8642b7c094L,0x1873439d1543c021L,0xe1baa5de5cbefd5dL,\n        0xa363fc5e521e8affL } },\n    /* 58 << 224 */\n    { { 0xefe6320df862eaacL,0x14419c6322c647dcL,0x0e06707c4e46d428L,\n        0xcb6c834f4a178f8fL },\n      { 0x0f993a45d30f917cL,0xd4c4b0499879afeeL,0xb6142a1e70500063L,\n        0x7c9b41c3a5d9d605L } },\n    /* 59 << 224 */\n    { { 0xbc00fc2f2f8ba2c7L,0x0966eb2f7c67aa28L,0x13f7b5165a786972L,\n        0x3bfb75578a2fbba0L },\n      { 0x131c4f235a2b9620L,0xbff3ed276faf46beL,0x9b4473d17e172323L,\n        0x421e8878339f6246L } },\n    /* 60 << 224 */\n    { { 0x0fa8587a25a41632L,0xc0814124a35b6c93L,0x2b18a9f559ebb8dbL,\n        0x264e335776edb29cL },\n      { 0xaf245ccdc87c51e2L,0x16b3015b501e6214L,0xbb31c5600a3882ceL,\n        0x6961bb94fec11e04L } },\n    /* 61 << 224 */\n    { { 0x3b825b8deff7a3a0L,0xbec33738b1df7326L,0x68ad747c99604a1fL,\n        0xd154c9349a3bd499L },\n      { 0xac33506f1cc7a906L,0x73bb53926c560e8fL,0x6428fcbe263e3944L,\n        0xc11828d51c387434L } },\n    /* 62 << 224 */\n    { { 0x3cd04be13e4b12ffL,0xc3aad9f92d88667cL,0xc52ddcf8248120cfL,\n        0x985a892e2a389532L },\n      { 0xfbb4b21b3bb85fa0L,0xf95375e08dfc6269L,0xfb4fb06c7ee2aceaL,\n        0x6785426e309c4d1fL } },\n    /* 63 << 224 */\n    { { 0x659b17c8d8ceb147L,0x9b649eeeb70a5554L,0x6b7fa0b5ac6bc634L,\n        0xd99fe2c71d6e732fL },\n      { 0x30e6e7628d3abba2L,0x18fee6e7a797b799L,0x5c9d360dc696464dL,\n        0xe3baeb4827bfde12L } },\n    /* 64 << 224 */\n    { { 0x2bf5db47f23206d5L,0x2f6d34201d260152L,0x17b876533f8ff89aL,\n        0x5157c30c378fa458L },\n      { 0x7517c5c52d4fb936L,0xef22f7ace6518cdcL,0xdeb483e6bf847a64L,\n        0xf508455892e0fa89L } },\n    /* 0 << 231 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 231 */\n    { { 0xab9659d8df7304d4L,0xb71bcf1bff210e8eL,0xa9a2438bd73fbd60L,\n        0x4595cd1f5d11b4deL },\n      { 0x9c0d329a4835859dL,0x4a0f0d2d7dbb6e56L,0xc6038e5edf928a4eL,\n        0xc94296218f5ad154L } },\n    /* 2 << 231 */\n    { { 0x91213462f23f2d92L,0x6cab71bd60b94078L,0x6bdd0a63176cde20L,\n        0x54c9b20cee4d54bcL },\n      { 0x3cd2d8aa9f2ac02fL,0x03f8e617206eedb0L,0xc7f68e1693086434L,\n        0x831469c592dd3db9L } },\n    /* 3 << 231 */\n    { { 0x8521df248f981354L,0x587e23ec3588a259L,0xcbedf281d7a0992cL,\n        0x06930a5538961407L },\n      { 0x09320debbe5bbe21L,0xa7ffa5b52491817fL,0xe6c8b4d909065160L,\n        0xac4f3992fff6d2a9L } },\n    /* 4 << 231 */\n    { { 0x7aa7a1583ae9c1bdL,0xe0af6d98e37ce240L,0xe54342d928ab38b4L,\n        0xe8b750070a1c98caL },\n      { 0xefce86afe02358f2L,0x31b8b856ea921228L,0x052a19120a1c67fcL,\n        0xb4069ea4e3aead59L } },\n    /* 5 << 231 */\n    { { 0x3232d6e27fa03cb3L,0xdb938e5b0fdd7d88L,0x04c1d2cd2ccbfc5dL,\n        0xd2f45c12af3a580fL },\n      { 0x592620b57883e614L,0x5fd27e68be7c5f26L,0x139e45a91567e1e3L,\n        0x2cc71d2d44d8aaafL } },\n    /* 6 << 231 */\n    { { 0x4a9090cde36d0757L,0xf722d7b1d9a29382L,0xfb7fb04c04b48ddfL,\n        0x628ad2a7ebe16f43L },\n      { 0xcd3fbfb520226040L,0x6c34ecb15104b6c4L,0x30c0754ec903c188L,\n        0xec336b082d23cab0L } },\n    /* 7 << 231 */\n    { { 0x473d62a21e206ee5L,0xf1e274808c49a633L,0x87ab956ce9f6b2c3L,\n        0x61830b4862b606eaL },\n      { 0x67cd6846e78e815fL,0xfe40139f4c02082aL,0x52bbbfcb952ec365L,\n        0x74c116426b9836abL } },\n    /* 8 << 231 */\n    { { 0x9f51439e558df019L,0x230da4baac712b27L,0x518919e355185a24L,\n        0x4dcefcdd84b78f50L },\n      { 0xa7d90fb2a47d4c5aL,0x55ac9abfb30e009eL,0xfd2fc35974eed273L,\n        0xb72d824cdbea8fafL } },\n    /* 9 << 231 */\n    { { 0xce721a744513e2caL,0x0b41861238240b2cL,0x05199968d5baa450L,\n        0xeb1757ed2b0e8c25L },\n      { 0x6ebc3e283dfac6d5L,0xb2431e2e48a237f5L,0x2acb5e2352f61499L,\n        0x5558a2a7e06c936bL } },\n    /* 10 << 231 */\n    { { 0xd213f923cbb13d1bL,0x98799f425bfb9bfeL,0x1ae8ddc9701144a9L,\n        0x0b8b3bb64c5595eeL },\n      { 0x0ea9ef2e3ecebb21L,0x17cb6c4b3671f9a7L,0x47ef464f726f1d1fL,\n        0x171b94846943a276L } },\n    /* 11 << 231 */\n    { { 0x51a4ae2d7ef0329cL,0x0850922291c4402aL,0x64a61d35afd45bbcL,\n        0x38f096fe3035a851L },\n      { 0xc7468b74a1dec027L,0xe8cf10e74fc7dcbaL,0xea35ff40f4a06353L,\n        0x0b4c0dfa8b77dd66L } },\n    /* 12 << 231 */\n    { { 0x779b8552de7e5c19L,0xfab28609c1c0256cL,0x64f58eeeabd4743dL,\n        0x4e8ef8387b6cc93bL },\n      { 0xee650d264cb1bf3dL,0x4c1f9d0973dedf61L,0xaef7c9d7bfb70cedL,\n        0x1ec0507e1641de1eL } },\n    /* 13 << 231 */\n    { { 0xcd7e5cc7cde45079L,0xde173c9a516ac9e4L,0x517a8494c170315cL,\n        0x438fd90591d8e8fbL },\n      { 0x5145c506c7d9630bL,0x6457a87bf47d4d75L,0xd31646bf0d9a80e8L,\n        0x453add2bcef3aabeL } },\n    /* 14 << 231 */\n    { { 0xc9941109a607419dL,0xfaa71e62bb6bca80L,0x34158c1307c431f3L,\n        0x594abebc992bc47aL },\n      { 0x6dfea691eb78399fL,0x48aafb353f42cba4L,0xedcd65af077c04f0L,\n        0x1a29a366e884491aL } },\n    /* 15 << 231 */\n    { { 0x023a40e51c21f2bfL,0xf99a513ca5057aeeL,0xa3fe7e25bcab072eL,\n        0x8568d2e140e32bcfL },\n      { 0x904594ebd3f69d9fL,0x181a973307affab1L,0xe4d68d76b6e330f4L,\n        0x87a6dafbc75a7fc1L } },\n    /* 16 << 231 */\n    { { 0x549db2b5ef7d9289L,0x2480d4a8197f015aL,0x61d5590bc40493b6L,\n        0x3a55b52e6f780331L },\n      { 0x40eb8115309eadb0L,0xdea7de5a92e5c625L,0x64d631f0cc6a3d5aL,\n        0x9d5e9d7c93e8dd61L } },\n    /* 17 << 231 */\n    { { 0xf297bef5206d3ffcL,0x23d5e0337d808bd4L,0x4a4f6912d24cf5baL,\n        0xe4d8163b09cdaa8aL },\n      { 0x0e0de9efd3082e8eL,0x4fe1246c0192f360L,0x1f9001504b8eee0aL,\n        0x5219da81f1da391bL } },\n    /* 18 << 231 */\n    { { 0x7bf6a5c1f7ea25aaL,0xd165e6bffbb07d5fL,0xe353936189e78671L,\n        0xa3fcac892bac4219L },\n      { 0xdfab6fd4f0baa8abL,0x5a4adac1e2c1c2e5L,0x6cd75e3140d85849L,\n        0xce263fea19b39181L } },\n    /* 19 << 231 */\n    { { 0xcb6803d307032c72L,0x7f40d5ce790968c8L,0xa6de86bddce978f0L,\n        0x25547c4f368f751cL },\n      { 0xb1e685fd65fb2a9eL,0xce69336f1eb9179cL,0xb15d1c2712504442L,\n        0xb7df465cb911a06bL } },\n    /* 20 << 231 */\n    { { 0xb8d804a3315980cdL,0x693bc492fa3bebf7L,0x3578aeee2253c504L,\n        0x158de498cd2474a2L },\n      { 0x1331f5c7cfda8368L,0xd2d7bbb378d7177eL,0xdf61133af3c1e46eL,\n        0x5836ce7dd30e7be8L } },\n    /* 21 << 231 */\n    { { 0x83084f1994f834cbL,0xd35653d4429ed782L,0xa542f16f59e58243L,\n        0xc2b52f650470a22dL },\n      { 0xe3b6221b18f23d96L,0xcb05abac3f5252b4L,0xca00938b87d61402L,\n        0x2f186cdd411933e4L } },\n    /* 22 << 231 */\n    { { 0xe042ece59a29a5c5L,0xb19b3c073b6c8402L,0xc97667c719d92684L,\n        0xb5624622ebc66372L },\n      { 0x0cb96e653c04fa02L,0x83a7176c8eaa39aaL,0x2033561deaa1633fL,\n        0x45a9d0864533df73L } },\n    /* 23 << 231 */\n    { { 0xe0542c1d3dc090bcL,0x82c996efaa59c167L,0xe3f735e80ee7fc4dL,\n        0x7b1793937c35db79L },\n      { 0xb6419e25f8c5dbfdL,0x4d9d7a1e1f327b04L,0x979f6f9b298dfca8L,\n        0xc7c5dff18de9366aL } },\n    /* 24 << 231 */\n    { { 0x1b7a588d04c82bddL,0x68005534f8319dfdL,0xde8a55b5d8eb9580L,\n        0x5ea886da8d5bca81L },\n      { 0xe8530a01252a0b4dL,0x1bffb4fe35eaa0a1L,0x2ad828b1d8e99563L,\n        0x7de96ef595f9cd87L } },\n    /* 25 << 231 */\n    { { 0x4abb2d0cd77d970cL,0x03cfb933d33ef9cbL,0xb0547c018b211fe9L,\n        0x2fe64809a56ed1c6L },\n      { 0xcb7d5624c2ac98ccL,0x2a1372c01a393e33L,0xc8d1ec1c29660521L,\n        0xf3d31b04b37ac3e9L } },\n    /* 26 << 231 */\n    { { 0xa29ae9df5ece6e7cL,0x0603ac8f0facfb55L,0xcfe85b7adda233a5L,\n        0xe618919fbd75f0b8L },\n      { 0xf555a3d299bf1603L,0x1f43afc9f184255aL,0xdcdaf341319a3e02L,\n        0xd3b117ef03903a39L } },\n    /* 27 << 231 */\n    { { 0xe095da1365d1d131L,0x86f16367c37ad03eL,0x5f37389e462cd8ddL,\n        0xc103fa04d67a60e6L },\n      { 0x57c34344f4b478f0L,0xce91edd8e117c98dL,0x001777b0231fc12eL,\n        0x11ae47f2b207bccbL } },\n    /* 28 << 231 */\n    { { 0xd983cf8d20f8a242L,0x7aff5b1df22e1ad8L,0x68fd11d07fc4feb3L,\n        0x5d53ae90b0f1c3e1L },\n      { 0x50fb7905ec041803L,0x85e3c97714404888L,0x0e67faedac628d8fL,\n        0x2e8651506668532cL } },\n    /* 29 << 231 */\n    { { 0x15acaaa46a67a6b0L,0xf4cdee25b25cec41L,0x49ee565ae4c6701eL,\n        0x2a04ca66fc7d63d8L },\n      { 0xeb105018ef0543fbL,0xf709a4f5d1b0d81dL,0x5b906ee62915d333L,\n        0xf4a8741296f1f0abL } },\n    /* 30 << 231 */\n    { { 0xb6b82fa74d82f4c2L,0x90725a606804efb3L,0xbc82ec46adc3425eL,\n        0xb7b805812787843eL },\n      { 0xdf46d91cdd1fc74cL,0xdc1c62cbe783a6c4L,0x59d1b9f31a04cbbaL,\n        0xd87f6f7295e40764L } },\n    /* 31 << 231 */\n    { { 0x02b4cfc1317f4a76L,0x8d2703eb91036bceL,0x98206cc6a5e72a56L,\n        0x57be9ed1cf53fb0fL },\n      { 0x09374571ef0b17acL,0x74b2655ed9181b38L,0xc8f80ea889935d0eL,\n        0xc0d9e94291529936L } },\n    /* 32 << 231 */\n    { { 0x196860411e84e0e5L,0xa5db84d3aea34c93L,0xf9d5bb197073a732L,\n        0xb8d2fe566bcfd7c0L },\n      { 0x45775f36f3eb82faL,0x8cb20cccfdff8b58L,0x1659b65f8374c110L,\n        0xb8b4a422330c789aL } },\n    /* 33 << 231 */\n    { { 0x75e3c3ea6fe8208bL,0xbd74b9e4286e78feL,0x0be2e81bd7d93a1aL,\n        0x7ed06e27dd0a5aaeL },\n      { 0x721f5a586be8b800L,0x428299d1d846db28L,0x95cb8e6b5be88ed3L,\n        0xc3186b231c034e11L } },\n    /* 34 << 231 */\n    { { 0xa6312c9e8977d99bL,0xbe94433183f531e7L,0x8232c0c218d3b1d4L,\n        0x617aae8be1247b73L },\n      { 0x40153fc4282aec3bL,0xc6063d2ff7b8f823L,0x68f10e583304f94cL,\n        0x31efae74ee676346L } },\n    /* 35 << 231 */\n    { { 0xbadb6c6d40a9b97cL,0x14702c634f666256L,0xdeb954f15184b2e3L,\n        0x5184a52694b6ca40L },\n      { 0xfff05337003c32eaL,0x5aa374dd205974c7L,0x9a7638544b0dd71aL,\n        0x459cd27fdeb947ecL } },\n    /* 36 << 231 */\n    { { 0xa6e28161459c2b92L,0x2f020fa875ee8ef5L,0xb132ec2d30b06310L,\n        0xc3e15899bc6a4530L },\n      { 0xdc5f53feaa3f451aL,0x3a3c7f23c2d9acacL,0x2ec2f8926b27e58bL,\n        0x68466ee7d742799fL } },\n    /* 37 << 231 */\n    { { 0x98324dd41fa26613L,0xa2dc6dabbdc29d63L,0xf9675faad712d657L,\n        0x813994be21fd8d15L },\n      { 0x5ccbb722fd4f7553L,0x5135ff8bf3a36b20L,0x44be28af69559df5L,\n        0x40b65bed9d41bf30L } },\n    /* 38 << 231 */\n    { { 0xd98bf2a43734e520L,0x5e3abbe3209bdcbaL,0x77c76553bc945b35L,\n        0x5331c093c6ef14aaL },\n      { 0x518ffe2976b60c80L,0x2285593b7ace16f8L,0xab1f64ccbe2b9784L,\n        0xe8f2c0d9ab2421b6L } },\n    /* 39 << 231 */\n    { { 0x617d7174c1df065cL,0xafeeb5ab5f6578faL,0x16ff1329263b54a8L,\n        0x45c55808c990dce3L },\n      { 0x42eab6c0ecc8c177L,0x799ea9b55982ecaaL,0xf65da244b607ef8eL,\n        0x8ab226ce32a3fc2cL } },\n    /* 40 << 231 */\n    { { 0x745741e57ea973dcL,0x5c00ca7020888f2eL,0x7cdce3cf45fd9cf1L,\n        0x8a741ef15507f872L },\n      { 0x47c51c2f196b4cecL,0x70d08e43c97ea618L,0x930da15c15b18a2bL,\n        0x33b6c6782f610514L } },\n    /* 41 << 231 */\n    { { 0xc662e4f807ac9794L,0x1eccf050ba06cb79L,0x1ff08623e7d954e5L,\n        0x6ef2c5fb24cf71c3L },\n      { 0xb2c063d267978453L,0xa0cf37961d654af8L,0x7cb242ea7ebdaa37L,\n        0x206e0b10b86747e0L } },\n    /* 42 << 231 */\n    { { 0x481dae5fd5ecfefcL,0x07084fd8c2bff8fcL,0x8040a01aea324596L,\n        0x4c646980d4de4036L },\n      { 0x9eb8ab4ed65abfc3L,0xe01cb91f13541ec7L,0x8f029adbfd695012L,\n        0x9ae284833c7569ecL } },\n    /* 43 << 231 */\n    { { 0xa5614c9ea66d80a1L,0x680a3e4475f5f911L,0x0c07b14dceba4fc1L,\n        0x891c285ba13071c1L },\n      { 0xcac67ceb799ece3cL,0x29b910a941e07e27L,0x66bdb409f2e43123L,\n        0x06f8b1377ac9ecbeL } },\n    /* 44 << 231 */\n    { { 0x5981fafd38547090L,0x19ab8b9f85e3415dL,0xfc28c194c7e31b27L,\n        0x843be0aa6fbcbb42L },\n      { 0xf3b1ed43a6db836cL,0x2a1330e401a45c05L,0x4f19f3c595c1a377L,\n        0xa85f39d044b5ee33L } },\n    /* 45 << 231 */\n    { { 0x3da18e6d4ae52834L,0x5a403b397423dcb0L,0xbb555e0af2374aefL,\n        0x2ad599c41e8ca111L },\n      { 0x1b3a2fb9014b3bf8L,0x73092684f66d5007L,0x079f1426c4340102L,\n        0x1827cf818fddf4deL } },\n    /* 46 << 231 */\n    { { 0xc83605f6f10ff927L,0xd387145123739fc6L,0x6d163450cac1c2ccL,\n        0x6b521296a2ec1ac5L },\n      { 0x0606c4f96e3cb4a5L,0xe47d3f41778abff7L,0x425a8d5ebe8e3a45L,\n        0x53ea9e97a6102160L } },\n    /* 47 << 231 */\n    { { 0x477a106e39cbb688L,0x532401d2f3386d32L,0x8e564f64b1b9b421L,\n        0xca9b838881dad33fL },\n      { 0xb1422b4e2093913eL,0x533d2f9269bc8112L,0x3fa017beebe7b2c7L,\n        0xb2767c4acaf197c6L } },\n    /* 48 << 231 */\n    { { 0xc925ff87aedbae9fL,0x7daf0eb936880a54L,0x9284ddf59c4d0e71L,\n        0x1581cf93316f8cf5L },\n      { 0x3eeca8873ac1f452L,0xb417fce9fb6aeffeL,0xa5918046eefb8dc3L,\n        0x73d318ac02209400L } },\n    /* 49 << 231 */\n    { { 0xe800400f728693e5L,0xe87d814b339927edL,0x93e94d3b57ea9910L,\n        0xff8a35b62245fb69L },\n      { 0x043853d77f200d34L,0x470f1e680f653ce1L,0x81ac05bd59a06379L,\n        0xa14052c203930c29L } },\n    /* 50 << 231 */\n    { { 0x6b72fab526bc2797L,0x13670d1699f16771L,0x001700521e3e48d1L,\n        0x978fe401b7adf678L },\n      { 0x55ecfb92d41c5dd4L,0x5ff8e247c7b27da5L,0xe7518272013fb606L,\n        0x5768d7e52f547a3cL } },\n    /* 51 << 231 */\n    { { 0xbb24eaa360017a5fL,0x6b18e6e49c64ce9bL,0xc225c655103dde07L,\n        0xfc3672ae7592f7eaL },\n      { 0x9606ad77d06283a1L,0x542fc650e4d59d99L,0xabb57c492a40e7c2L,\n        0xac948f13a8db9f55L } },\n    /* 52 << 231 */\n    { { 0x6d4c9682b04465c3L,0xe3d062fa6468bd15L,0xa51729ac5f318d7eL,\n        0x1fc87df69eb6fc95L },\n      { 0x63d146a80591f652L,0xa861b8f7589621aaL,0x59f5f15ace31348cL,\n        0x8f663391440da6daL } },\n    /* 53 << 231 */\n    { { 0xcfa778acb591ffa3L,0x027ca9c54cdfebceL,0xbe8e05a5444ea6b3L,\n        0x8aab4e69a78d8254L },\n      { 0x2437f04fb474d6b8L,0x6597ffd4045b3855L,0xbb0aea4eca47ecaaL,\n        0x568aae8385c7ebfcL } },\n    /* 54 << 231 */\n    { { 0x0e966e64c73b2383L,0x49eb3447d17d8762L,0xde1078218da05dabL,\n        0x443d8baa016b7236L },\n      { 0x163b63a5ea7610d6L,0xe47e4185ce1ca979L,0xae648b6580baa132L,\n        0xebf53de20e0d5b64L } },\n    /* 55 << 231 */\n    { { 0x8d3bfcb4d3c8c1caL,0x0d914ef35d04b309L,0x55ef64153de7d395L,\n        0xbde1666f26b850e8L },\n      { 0xdbe1ca6ed449ab19L,0x8902b322e89a2672L,0xb1674b7edacb7a53L,\n        0x8e9faf6ef52523ffL } },\n    /* 56 << 231 */\n    { { 0x6ba535da9a85788bL,0xd21f03aebd0626d4L,0x099f8c47e873dc64L,\n        0xcda8564d018ec97eL },\n      { 0x3e8d7a5cde92c68cL,0x78e035a173323cc4L,0x3ef26275f880ff7cL,\n        0xa4ee3dff273eedaaL } },\n    /* 57 << 231 */\n    { { 0x58823507af4e18f8L,0x967ec9b50672f328L,0x9ded19d9559d3186L,\n        0x5e2ab3de6cdce39cL },\n      { 0xabad6e4d11c226dfL,0xf9783f4387723014L,0x9a49a0cf1a885719L,\n        0xfc0c1a5a90da9dbfL } },\n    /* 58 << 231 */\n    { { 0x8bbaec49571d92acL,0x569e85fe4692517fL,0x8333b014a14ea4afL,\n        0x32f2a62f12e5c5adL },\n      { 0x98c2ce3a06d89b85L,0xb90741aa2ff77a08L,0x2530defc01f795a2L,\n        0xd6e5ba0b84b3c199L } },\n    /* 59 << 231 */\n    { { 0x7d8e845112e4c936L,0xae419f7dbd0be17bL,0xa583fc8c22262bc9L,\n        0x6b842ac791bfe2bdL },\n      { 0x33cef4e9440d6827L,0x5f69f4deef81fb14L,0xf16cf6f6234fbb92L,\n        0x76ae3fc3d9e7e158L } },\n    /* 60 << 231 */\n    { { 0x4e89f6c2e9740b33L,0x677bc85d4962d6a1L,0x6c6d8a7f68d10d15L,\n        0x5f9a72240257b1cdL },\n      { 0x7096b9164ad85961L,0x5f8c47f7e657ab4aL,0xde57d7d0f7461d7eL,\n        0x7eb6094d80ce5ee2L } },\n    /* 61 << 231 */\n    { { 0x0b1e1dfd34190547L,0x8a394f43f05dd150L,0x0a9eb24d97df44e6L,\n        0x78ca06bf87675719L },\n      { 0x6f0b34626ffeec22L,0x9d91bcea36cdd8fbL,0xac83363ca105be47L,\n        0x81ba76c1069710e3L } },\n    /* 62 << 231 */\n    { { 0x3d1b24cb28c682c6L,0x27f252288612575bL,0xb587c779e8e66e98L,\n        0x7b0c03e9405eb1feL },\n      { 0xfdf0d03015b548e7L,0xa8be76e038b36af7L,0x4cdab04a4f310c40L,\n        0x6287223ef47ecaecL } },\n    /* 63 << 231 */\n    { { 0x678e60558b399320L,0x61fe3fa6c01e4646L,0xc482866b03261a5eL,\n        0xdfcf45b85c2f244aL },\n      { 0x8fab9a512f684b43L,0xf796c654c7220a66L,0x1d90707ef5afa58fL,\n        0x2c421d974fdbe0deL } },\n    /* 64 << 231 */\n    { { 0xc4f4cda3af2ebc2fL,0xa0af843dcb4efe24L,0x53b857c19ccd10b1L,\n        0xddc9d1eb914d3e04L },\n      { 0x7bdec8bb62771debL,0x829277aa91c5aa81L,0x7af18dd6832391aeL,\n        0x1740f316c71a84caL } },\n    /* 0 << 238 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 238 */\n    { { 0x8928e99aeeaf8c49L,0xee7aa73d6e24d728L,0x4c5007c2e72b156cL,\n        0x5fcf57c5ed408a1dL },\n      { 0x9f719e39b6057604L,0x7d343c01c2868bbfL,0x2cca254b7e103e2dL,\n        0xe6eb38a9f131bea2L } },\n    /* 2 << 238 */\n    { { 0xb33e624f8be762b4L,0x2a9ee4d1058e3413L,0x968e636967d805faL,\n        0x9848949b7db8bfd7L },\n      { 0x5308d7e5d23a8417L,0x892f3b1df3e29da5L,0xc95c139e3dee471fL,\n        0x8631594dd757e089L } },\n    /* 3 << 238 */\n    { { 0xe0c82a3cde918dccL,0x2e7b599426fdcf4bL,0x82c5024932cb1b2dL,\n        0xea613a9d7657ae07L },\n      { 0xc2eb5f6cf1fdc9f7L,0xb6eae8b8879fe682L,0x253dfee0591cbc7fL,\n        0x000da7133e1290e6L } },\n    /* 4 << 238 */\n    { { 0x1083e2ea1f095615L,0x0a28ad7714e68c33L,0x6bfc02523d8818beL,\n        0xb585113af35850cdL },\n      { 0x7d935f0b30df8aa1L,0xaddda07c4ab7e3acL,0x92c34299552f00cbL,\n        0xc33ed1de2909df6cL } },\n    /* 5 << 238 */\n    { { 0x22c2195d80e87766L,0x9e99e6d89ddf4ac0L,0x09642e4e65e74934L,\n        0x2610ffa2ff1ff241L },\n      { 0x4d1d47d4751c8159L,0x697b4985af3a9363L,0x0318ca4687477c33L,\n        0xa90cb5659441eff3L } },\n    /* 6 << 238 */\n    { { 0x58bb384836f024cbL,0x85be1f7736016168L,0x6c59587cdc7e07f1L,\n        0x191be071af1d8f02L },\n      { 0xbf169fa5cca5e55cL,0x3864ba3cf7d04eacL,0x915e367f8d7d05dbL,\n        0xb48a876da6549e5dL } },\n    /* 7 << 238 */\n    { { 0xef89c656580e40a2L,0xf194ed8c728068bcL,0x74528045a47990c9L,\n        0xf53fc7d75e1a4649L },\n      { 0xbec5ae9b78593e7dL,0x2cac4ee341db65d7L,0xa8c1eb2404a3d39bL,\n        0x53b7d63403f8f3efL } },\n    /* 8 << 238 */\n    { { 0x2dc40d483e07113cL,0x6e4a5d397d8b63aeL,0x5582a94b79684c2bL,\n        0x932b33d4622da26cL },\n      { 0xf534f6510dbbf08dL,0x211d07c964c23a52L,0x0eeece0fee5bdc9bL,\n        0xdf178168f7015558L } },\n    /* 9 << 238 */\n    { { 0xd42946350a712229L,0x93cbe44809273f8cL,0x00b095ef8f13bc83L,\n        0xbb7419728798978cL },\n      { 0x9d7309a256dbe6e7L,0xe578ec565a5d39ecL,0x3961151b851f9a31L,\n        0x2da7715de5709eb4L } },\n    /* 10 << 238 */\n    { { 0x867f301753dfabf0L,0x728d2078b8e39259L,0x5c75a0cd815d9958L,\n        0xf84867a616603be1L },\n      { 0xc865b13d70e35b1cL,0x0241446819b03e2cL,0xe46041daac1f3121L,\n        0x7c9017ad6f028a7cL } },\n    /* 11 << 238 */\n    { { 0xabc96de90a482873L,0x4265d6b1b77e54d4L,0x68c38e79a57d88e7L,\n        0xd461d7669ce82de3L },\n      { 0x817a9ec564a7e489L,0xcc5675cda0def5f2L,0x9a00e785985d494eL,\n        0xc626833f1b03514aL } },\n    /* 12 << 238 */\n    { { 0xabe7905a83cdd60eL,0x50602fb5a1170184L,0x689886cdb023642aL,\n        0xd568d090a6e1fb00L },\n      { 0x5b1922c70259217fL,0x93831cd9c43141e4L,0xdfca35870c95f86eL,\n        0xdec2057a568ae828L } },\n    /* 13 << 238 */\n    { { 0xc44ea599f98a759aL,0x55a0a7a2f7c23c1dL,0xd5ffb6e694c4f687L,\n        0x3563cce212848478L },\n      { 0x812b3517e7b1fbe1L,0x8a7dc9794f7338e0L,0x211ecee952d048dbL,\n        0x2eea4056c86ea3b8L } },\n    /* 14 << 238 */\n    { { 0xd8cb68a7ba772b34L,0xe16ed3415f4e2541L,0x9b32f6a60fec14dbL,\n        0xeee376f7391698beL },\n      { 0xe9a7aa1783674c02L,0x65832f975843022aL,0x29f3a8da5ba4990fL,\n        0x79a59c3afb8e3216L } },\n    /* 15 << 238 */\n    { { 0x9cdc4d2ebd19bb16L,0xc6c7cfd0b3262d86L,0xd4ce14d0969c0b47L,\n        0x1fa352b713e56128L },\n      { 0x383d55b8973db6d3L,0x71836850e8e5b7bfL,0xc7714596e6bb571fL,\n        0x259df31f2d5b2dd2L } },\n    /* 16 << 238 */\n    { { 0x568f8925913cc16dL,0x18bc5b6de1a26f5aL,0xdfa413bef5f499aeL,\n        0xf8835decc3f0ae84L },\n      { 0xb6e60bd865a40ab0L,0x65596439194b377eL,0xbcd8562592084a69L,\n        0x5ce433b94f23ede0L } },\n    /* 17 << 238 */\n    { { 0xe8e8f04f6ad65143L,0x11511827d6e14af6L,0x3d390a108295c0c7L,\n        0x71e29ee4621eba16L },\n      { 0xa588fc0963717b46L,0x02be02fee06ad4a2L,0x931558c604c22b22L,\n        0xbb4d4bd612f3c849L } },\n    /* 18 << 238 */\n    { { 0x54a4f49620efd662L,0x92ba6d20c5952d14L,0x2db8ea1ecc9784c2L,\n        0x81cc10ca4b353644L },\n      { 0x40b570ad4b4d7f6cL,0x5c9f1d9684a1dcd2L,0x01379f813147e797L,\n        0xe5c6097b2bd499f5L } },\n    /* 19 << 238 */\n    { { 0x40dcafa6328e5e20L,0xf7b5244a54815550L,0xb9a4f11847bfc978L,\n        0x0ea0e79fd25825b1L },\n      { 0xa50f96eb646c7ecfL,0xeb811493446dea9dL,0x2af04677dfabcf69L,\n        0xbe3a068fc713f6e8L } },\n    /* 20 << 238 */\n    { { 0x860d523d42e06189L,0xbf0779414e3aff13L,0x0b616dcac1b20650L,\n        0xe66dd6d12131300dL },\n      { 0xd4a0fd67ff99abdeL,0xc9903550c7aac50dL,0x022ecf8b7c46b2d7L,\n        0x3333b1e83abf92afL } },\n    /* 21 << 238 */\n    { { 0x11cc113c6c491c14L,0x0597668880dd3f88L,0xf5b4d9e729d932edL,\n        0xe982aad8a2c38b6dL },\n      { 0x6f9253478be0dcf0L,0x700080ae65ca53f2L,0xd8131156443ca77fL,\n        0xe92d6942ec51f984L } },\n    /* 22 << 238 */\n    { { 0xd2a08af885dfe9aeL,0xd825d9a54d2a86caL,0x2c53988d39dff020L,\n        0xf38b135a430cdc40L },\n      { 0x0c918ae062a7150bL,0xf31fd8de0c340e9bL,0xafa0e7ae4dbbf02eL,\n        0x5847fb2a5eba6239L } },\n    /* 23 << 238 */\n    { { 0x6b1647dcdccbac8bL,0xb642aa7806f485c8L,0x873f37657038ecdfL,\n        0x2ce5e865fa49d3feL },\n      { 0xea223788c98c4400L,0x8104a8cdf1fa5279L,0xbcf7cc7a06becfd7L,\n        0x49424316c8f974aeL } },\n    /* 24 << 238 */\n    { { 0xc0da65e784d6365dL,0xbcb7443f8f759fb8L,0x35c712b17ae81930L,\n        0x80428dff4c6e08abL },\n      { 0xf19dafefa4faf843L,0xced8538dffa9855fL,0x20ac409cbe3ac7ceL,\n        0x358c1fb6882da71eL } },\n    /* 25 << 238 */\n    { { 0xafa9c0e5fd349961L,0x2b2cfa518421c2fcL,0x2a80db17f3a28d38L,\n        0xa8aba5395d138e7eL },\n      { 0x52012d1d6e96eb8dL,0x65d8dea0cbaf9622L,0x57735447b264f56cL,\n        0xbeebef3f1b6c8da2L } },\n    /* 26 << 238 */\n    { { 0xfc346d98ce785254L,0xd50e8d72bb64a161L,0xc03567c749794addL,\n        0x15a76065752c7ef6L },\n      { 0x59f3a222961f23d6L,0x378e443873ecc0b0L,0xc74be4345a82fde4L,\n        0xae509af2d8b9cf34L } },\n    /* 27 << 238 */\n    { { 0x4a61ee46577f44a1L,0xe09b748cb611deebL,0xc0481b2cf5f7b884L,\n        0x3562667861acfa6bL },\n      { 0x37f4c518bf8d21e6L,0x22d96531b205a76dL,0x37fb85e1954073c0L,\n        0xbceafe4f65b3a567L } },\n    /* 28 << 238 */\n    { { 0xefecdef7be42a582L,0xd3fc608065046be6L,0xc9af13c809e8dba9L,\n        0x1e6c9847641491ffL },\n      { 0x3b574925d30c31f7L,0xb7eb72baac2a2122L,0x776a0dacef0859e7L,\n        0x06fec31421900942L } },\n    /* 29 << 238 */\n    { { 0x2464bc10f8c22049L,0x9bfbcce7875ebf69L,0xd7a88e2a4336326bL,\n        0xda05261c5bc2acfaL },\n      { 0xc29f5bdceba7efc8L,0x471237ca25dbbf2eL,0xa72773f22975f127L,\n        0xdc744e8e04d0b326L } },\n    /* 30 << 238 */\n    { { 0x38a7ed16a56edb73L,0x64357e372c007e70L,0xa167d15b5080b400L,\n        0x07b4116423de4be1L },\n      { 0xb2d91e3274c89883L,0x3c1628212882e7edL,0xad6b36ba7503e482L,\n        0x48434e8e0ea34331L } },\n    /* 31 << 238 */\n    { { 0x79f4f24f2c7ae0b9L,0xc46fbf811939b44aL,0x76fefae856595eb1L,\n        0x417b66abcd5f29c7L },\n      { 0x5f2332b2c5ceec20L,0xd69661ffe1a1cae2L,0x5ede7e529b0286e6L,\n        0x9d062529e276b993L } },\n    /* 32 << 238 */\n    { { 0x324794b07e50122bL,0xdd744f8b4af07ca5L,0x30a12f08d63fc97bL,\n        0x39650f1a76626d9dL },\n      { 0x101b47f71fa38477L,0x3d815f19d4dc124fL,0x1569ae95b26eb58aL,\n        0xc3cde18895fb1887L } },\n    /* 33 << 238 */\n    { { 0x54e9f37bf9539a48L,0xb0100e067408c1a5L,0x821d9811ea580cbbL,\n        0x8af52d3586e50c56L },\n      { 0xdfbd9d47dbbf698bL,0x2961a1ea03dc1c73L,0x203d38f8e76a5df8L,\n        0x08a53a686def707aL } },\n    /* 34 << 238 */\n    { { 0x26eefb481bee45d4L,0xb3cee3463c688036L,0x463c5315c42f2469L,\n        0x19d84d2e81378162L },\n      { 0x22d7c3c51c4d349fL,0x65965844163d59c5L,0xcf198c56b8abceaeL,\n        0x6fb1fb1b628559d5L } },\n    /* 35 << 238 */\n    { { 0x8bbffd0607bf8fe3L,0x46259c583467734bL,0xd8953cea35f7f0d3L,\n        0x1f0bece2d65b0ff1L },\n      { 0xf7d5b4b3f3c72914L,0x29e8ea953cb53389L,0x4a365626836b6d46L,\n        0xe849f910ea174fdeL } },\n    /* 36 << 238 */\n    { { 0x7ec62fbbf4737f21L,0xd8dba5ab6209f5acL,0x24b5d7a9a5f9adbeL,\n        0x707d28f7a61dc768L },\n      { 0x7711460bcaa999eaL,0xba7b174d1c92e4ccL,0x3c4bab6618d4bf2dL,\n        0xb8f0c980eb8bd279L } },\n    /* 37 << 238 */\n    { { 0x024bea9a324b4737L,0xfba9e42332a83bcaL,0x6e635643a232dcedL,\n        0x996193672571c8baL },\n      { 0xe8c9f35754b7032bL,0xf936b3ba2442d54aL,0x2263f0f08290c65aL,\n        0x48989780ee2c7fdbL } },\n    /* 38 << 238 */\n    { { 0xadc5d55a13d4f95eL,0x737cff85ad9b8500L,0x271c557b8a73f43dL,\n        0xbed617a4e18bc476L },\n      { 0x662454017dfd8ab2L,0xae7b89ae3a2870aaL,0x1b555f5323a7e545L,\n        0x6791e247be057e4cL } },\n    /* 39 << 238 */\n    { { 0x860136ad324fa34dL,0xea1114474cbeae28L,0x023a4270bedd3299L,\n        0x3d5c3a7fc1c35c34L },\n      { 0xb0f6db678d0412d2L,0xd92625e2fcdc6b9aL,0x92ae5ccc4e28a982L,\n        0xea251c3647a3ce7eL } },\n    /* 40 << 238 */\n    { { 0x9d658932790691bfL,0xed61058906b736aeL,0x712c2f04c0d63b6eL,\n        0x5cf06fd5c63d488fL },\n      { 0x97363facd9588e41L,0x1f9bf7622b93257eL,0xa9d1ffc4667acaceL,\n        0x1cf4a1aa0a061ecfL } },\n    /* 41 << 238 */\n    { { 0x40e48a49dc1818d0L,0x0643ff39a3621ab0L,0x5768640ce39ef639L,\n        0x1fc099ea04d86854L },\n      { 0x9130b9c3eccd28fdL,0xd743cbd27eec54abL,0x052b146fe5b475b6L,\n        0x058d9a82900a7d1fL } },\n    /* 42 << 238 */\n    { { 0x65e0229291262b72L,0x96f924f9bb0edf03L,0x5cfa59c8fe206842L,\n        0xf60370045eafa720L },\n      { 0x5f30699e18d7dd96L,0x381e8782cbab2495L,0x91669b46dd8be949L,\n        0xb40606f526aae8efL } },\n    /* 43 << 238 */\n    { { 0x2812b839fc6751a4L,0x16196214fba800efL,0x4398d5ca4c1a2875L,\n        0x720c00ee653d8349L },\n      { 0xc2699eb0d820007cL,0x880ee660a39b5825L,0x70694694471f6984L,\n        0xf7d16ea8e3dda99aL } },\n    /* 44 << 238 */\n    { { 0x28d675b2c0519a23L,0x9ebf94fe4f6952e3L,0xf28bb767a2294a8aL,\n        0x85512b4dfe0af3f5L },\n      { 0x18958ba899b16a0dL,0x95c2430cba7548a7L,0xb30d1b10a16be615L,\n        0xe3ebbb9785bfb74cL } },\n    /* 45 << 238 */\n    { { 0xa3273cfe18549fdbL,0xf6e200bf4fcdb792L,0x54a76e1883aba56cL,\n        0x73ec66f689ef6aa2L },\n      { 0x8d17add7d1b9a305L,0xa959c5b9b7ae1b9dL,0x886435226bcc094aL,\n        0xcc5616c4d7d429b9L } },\n    /* 46 << 238 */\n    { { 0xa6dada01e6a33f7cL,0xc6217a079d4e70adL,0xd619a81809c15b7cL,\n        0xea06b3290e80c854L },\n      { 0x174811cea5f5e7b9L,0x66dfc310787c65f4L,0x4ea7bd693316ab54L,\n        0xc12c4acb1dcc0f70L } },\n    /* 47 << 238 */\n    { { 0xe4308d1a1e407dd9L,0xe8a3587c91afa997L,0xea296c12ab77b7a5L,\n        0xb5ad49e4673c0d52L },\n      { 0x40f9b2b27006085aL,0xa88ff34087bf6ec2L,0x978603b14e3066a6L,\n        0xb3f99fc2b5e486e2L } },\n    /* 48 << 238 */\n    { { 0x07b53f5eb2e63645L,0xbe57e54784c84232L,0xd779c2167214d5cfL,\n        0x617969cd029a3acaL },\n      { 0xd17668cd8a7017a0L,0x77b4d19abe9b7ee8L,0x58fd0e939c161776L,\n        0xa8c4f4efd5968a72L } },\n    /* 49 << 238 */\n    { { 0x296071cc67b3de77L,0xae3c0b8e634f7905L,0x67e440c28a7100c9L,\n        0xbb8c3c1beb4b9b42L },\n      { 0x6d71e8eac51b3583L,0x7591f5af9525e642L,0xf73a2f7b13f509f3L,\n        0x618487aa5619ac9bL } },\n    /* 50 << 238 */\n    { { 0x3a72e5f79d61718aL,0x00413bcc7592d28cL,0x7d9b11d3963c35cfL,\n        0x77623bcfb90a46edL },\n      { 0xdeef273bdcdd2a50L,0x4a741f9b0601846eL,0x33b89e510ec6e929L,\n        0xcb02319f8b7f22cdL } },\n    /* 51 << 238 */\n    { { 0xbbe1500d084bae24L,0x2f0ae8d7343d2693L,0xacffb5f27cdef811L,\n        0xaa0c030a263fb94fL },\n      { 0x6eef0d61a0f442deL,0xf92e181727b139d3L,0x1ae6deb70ad8bc28L,\n        0xa89e38dcc0514130L } },\n    /* 52 << 238 */\n    { { 0x81eeb865d2fdca23L,0x5a15ee08cc8ef895L,0x768fa10a01905614L,\n        0xeff5b8ef880ee19bL },\n      { 0xf0c0cabbcb1c8a0eL,0x2e1ee9cdb8c838f9L,0x0587d8b88a4a14c0L,\n        0xf6f278962ff698e5L } },\n    /* 53 << 238 */\n    { { 0xed38ef1c89ee6256L,0xf44ee1fe6b353b45L,0x9115c0c770e903b3L,\n        0xc78ec0a1818f31dfL },\n      { 0x6c003324b7dccbc6L,0xd96dd1f3163bbc25L,0x33aa82dd5cedd805L,\n        0x123aae4f7f7eb2f1L } },\n    /* 54 << 238 */\n    { { 0x1723fcf5a26262cdL,0x1f7f4d5d0060ebd5L,0xf19c5c01b2eaa3afL,\n        0x2ccb9b149790accfL },\n      { 0x1f9c1cad52324aa6L,0x632005267247df54L,0x5732fe42bac96f82L,\n        0x52fe771f01a1c384L } },\n    /* 55 << 238 */\n    { { 0x546ca13db1001684L,0xb56b4eeea1709f75L,0x266545a9d5db8672L,\n        0xed971c901e8f3cfbL },\n      { 0x4e7d8691e3a07b29L,0x7570d9ece4b696b9L,0xdc5fa0677bc7e9aeL,\n        0x68b44cafc82c4844L } },\n    /* 56 << 238 */\n    { { 0x519d34b3bf44da80L,0x283834f95ab32e66L,0x6e6087976278a000L,\n        0x1e62960e627312f6L },\n      { 0x9b87b27be6901c55L,0x80e7853824fdbc1fL,0xbbbc09512facc27dL,\n        0x06394239ac143b5aL } },\n    /* 57 << 238 */\n    { { 0x35bb4a40376c1944L,0x7cb6269463da1511L,0xafd29161b7148a3bL,\n        0xa6f9d9ed4e2ea2eeL },\n      { 0x15dc2ca2880dd212L,0x903c3813a61139a9L,0x2aa7b46d6c0f8785L,\n        0x36ce2871901c60ffL } },\n    /* 58 << 238 */\n    { { 0xc683b028e10d9c12L,0x7573baa2032f33d3L,0x87a9b1f667a31b58L,\n        0xfd3ed11af4ffae12L },\n      { 0x83dcaa9a0cb2748eL,0x8239f0185d6fdf16L,0xba67b49c72753941L,\n        0x2beec455c321cb36L } },\n    /* 59 << 238 */\n    { { 0x880156063f8b84ceL,0x764170838d38c86fL,0x054f1ca7598953ddL,\n        0xc939e1104e8e7429L },\n      { 0x9b1ac2b35a914f2fL,0x39e35ed3e74b8f9cL,0xd0debdb2781b2fb0L,\n        0x1585638f2d997ba2L } },\n    /* 60 << 238 */\n    { { 0x9c4b646e9e2fce99L,0x68a210811e80857fL,0x06d54e443643b52aL,\n        0xde8d6d630d8eb843L },\n      { 0x7032156342146a0aL,0x8ba826f25eaa3622L,0x227a58bd86138787L,\n        0x43b6c03c10281d37L } },\n    /* 61 << 238 */\n    { { 0x6326afbbb54dde39L,0x744e5e8adb6f2d5fL,0x48b2a99acff158e1L,\n        0xa93c8fa0ef87918fL },\n      { 0x2182f956de058c5cL,0x216235d2936f9e7aL,0xace0c0dbd2e31e67L,\n        0xc96449bff23ac3e7L } },\n    /* 62 << 238 */\n    { { 0x7e9a2874170693bdL,0xa28e14fda45e6335L,0x5757f6b356427344L,\n        0x822e4556acf8edf9L },\n      { 0x2b7a6ee2e6a285cdL,0x5866f211a9df3af0L,0x40dde2ddf845b844L,\n        0x986c3726110e5e49L } },\n    /* 63 << 238 */\n    { { 0x73680c2af7172277L,0x57b94f0f0cccb244L,0xbdff72672d438ca7L,\n        0xbad1ce11cf4663fdL },\n      { 0x9813ed9dd8f71caeL,0xf43272a6961fdaa6L,0xbeff0119bd6d1637L,\n        0xfebc4f9130361978L } },\n    /* 64 << 238 */\n    { { 0x02b37a952f41deffL,0x0e44a59ae63b89b7L,0x673257dc143ff951L,\n        0x19c02205d752baf4L },\n      { 0x46c23069c4b7d692L,0x2e6392c3fd1502acL,0x6057b1a21b220846L,\n        0xe51ff9460c1b5b63L } },\n    /* 0 << 245 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 245 */\n    { { 0x6e85cb51566c5c43L,0xcff9c9193597f046L,0x9354e90c4994d94aL,\n        0xe0a393322147927dL },\n      { 0x8427fac10dc1eb2bL,0x88cfd8c22ff319faL,0xe2d4e68401965274L,\n        0xfa2e067d67aaa746L } },\n    /* 2 << 245 */\n    { { 0xb6d92a7f3e5f9f11L,0x9afe153ad6cb3b8eL,0x4d1a6dd7ddf800bdL,\n        0xf6c13cc0caf17e19L },\n      { 0x15f6c58e325fc3eeL,0x71095400a31dc3b2L,0x168e7c07afa3d3e7L,\n        0x3f8417a194c7ae2dL } },\n    /* 3 << 245 */\n    { { 0xec234772813b230dL,0x634d0f5f17344427L,0x11548ab1d77fc56aL,\n        0x7fab1750ce06af77L },\n      { 0xb62c10a74f7c4f83L,0xa7d2edc4220a67d9L,0x1c404170921209a0L,\n        0x0b9815a0face59f0L } },\n    /* 4 << 245 */\n    { { 0x2842589b319540c3L,0x18490f59a283d6f8L,0xa2731f84daae9fcbL,\n        0x3db6d960c3683ba0L },\n      { 0xc85c63bb14611069L,0xb19436af0788bf05L,0x905459df347460d2L,\n        0x73f6e094e11a7db1L } },\n    /* 5 << 245 */\n    { { 0xdc7f938eb6357f37L,0xc5d00f792bd8aa62L,0xc878dcb92ca979fcL,\n        0x37e83ed9eb023a99L },\n      { 0x6b23e2731560bf3dL,0x1086e4591d0fae61L,0x782483169a9414bdL,\n        0x1b956bc0f0ea9ea1L } },\n    /* 6 << 245 */\n    { { 0x7b85bb91c31b9c38L,0x0c5aa90b48ef57b5L,0xdedeb169af3bab6fL,\n        0xe610ad732d373685L },\n      { 0xf13870df02ba8e15L,0x0337edb68ca7f771L,0xe4acf747b62c036cL,\n        0xd921d576b6b94e81L } },\n    /* 7 << 245 */\n    { { 0xdbc864392c422f7aL,0xfb635362ed348898L,0x83084668c45bfcd1L,\n        0xc357c9e32b315e11L },\n      { 0xb173b5405b2e5b8cL,0x7e946931e102b9a4L,0x17c890eb7b0fb199L,\n        0xec225a83d61b662bL } },\n    /* 8 << 245 */\n    { { 0xf306a3c8ee3c76cbL,0x3cf11623d32a1f6eL,0xe6d5ab646863e956L,\n        0x3b8a4cbe5c005c26L },\n      { 0xdcd529a59ce6bb27L,0xc4afaa5204d4b16fL,0xb0624a267923798dL,\n        0x85e56df66b307fabL } },\n    /* 9 << 245 */\n    { { 0x0281893c2bf29698L,0x91fc19a4d7ce7603L,0x75a5dca3ad9a558fL,\n        0x40ceb3fa4d50bf77L },\n      { 0x1baf6060bc9ba369L,0x927e1037597888c2L,0xd936bf1986a34c07L,\n        0xd4cf10c1c34ae980L } },\n    /* 10 << 245 */\n    { { 0x3a3e5334859dd614L,0x9c475b5b18d0c8eeL,0x63080d1f07cd51d5L,\n        0xc9c0d0a6b88b4326L },\n      { 0x1ac98691c234296fL,0x2a0a83a494887fb6L,0x565114270cea9cf2L,\n        0x5230a6e8a24802f5L } },\n    /* 11 << 245 */\n    { { 0xf7a2bf0f72e3d5c1L,0x377174464f21439eL,0xfedcbf259ce30334L,\n        0xe0030a787ce202f9L },\n      { 0x6f2d9ebf1202e9caL,0xe79dde6c75e6e591L,0xf52072aff1dac4f8L,\n        0x6c8d087ebb9b404dL } },\n    /* 12 << 245 */\n    { { 0xad0fc73dbce913afL,0x909e587b458a07cbL,0x1300da84d4f00c8aL,\n        0x425cd048b54466acL },\n      { 0xb59cb9be90e9d8bfL,0x991616db3e431b0eL,0xd3aa117a531aecffL,\n        0x91af92d359f4dc3bL } },\n    /* 13 << 245 */\n    { { 0x9b1ec292e93fda29L,0x76bb6c17e97d91bcL,0x7509d95faface1e6L,\n        0x3653fe47be855ae3L },\n      { 0x73180b280f680e75L,0x75eefd1beeb6c26cL,0xa4cdf29fb66d4236L,\n        0x2d70a9976b5821d8L } },\n    /* 14 << 245 */\n    { { 0x7a3ee20720445c36L,0x71d1ac8259877174L,0x0fc539f7949f73e9L,\n        0xd05cf3d7982e3081L },\n      { 0x8758e20b7b1c7129L,0xffadcc20569e61f2L,0xb05d3a2f59544c2dL,\n        0xbe16f5c19fff5e53L } },\n    /* 15 << 245 */\n    { { 0x73cf65b8aad58135L,0x622c2119037aa5beL,0x79373b3f646fd6a0L,\n        0x0e029db50d3978cfL },\n      { 0x8bdfc43794fba037L,0xaefbd687620797a6L,0x3fa5382bbd30d38eL,\n        0x7627cfbf585d7464L } },\n    /* 16 << 245 */\n    { { 0xb2330fef4e4ca463L,0xbcef72873566cc63L,0xd161d2cacf780900L,\n        0x135dc5395b54827dL },\n      { 0x638f052e27bf1bc6L,0x10a224f007dfa06cL,0xe973586d6d3321daL,\n        0x8b0c573826152c8fL } },\n    /* 17 << 245 */\n    { { 0x07ef4f2a34606074L,0x80fe7fe8a0f7047aL,0x3d1a8152e1a0e306L,\n        0x32cf43d888da5222L },\n      { 0xbf89a95f5f02ffe6L,0x3d9eb9a4806ad3eaL,0x012c17bb79c8e55eL,\n        0xfdcd1a7499c81dacL } },\n    /* 18 << 245 */\n    { { 0x7043178bb9556098L,0x4090a1df801c3886L,0x759800ff9b67b912L,\n        0x3e5c0304232620c8L },\n      { 0x4b9d3c4b70dceecaL,0xbb2d3c15181f648eL,0xf981d8376e33345cL,\n        0xb626289b0cf2297aL } },\n    /* 19 << 245 */\n    { { 0x766ac6598baebdcfL,0x1a28ae0975df01e5L,0xb71283da375876d8L,\n        0x4865a96d607b9800L },\n      { 0x25dd1bcd237936b2L,0x332f4f4b60417494L,0xd0923d68370a2147L,\n        0x497f5dfbdc842203L } },\n    /* 20 << 245 */\n    { { 0x9dc74cbd32be5e0fL,0x7475bcb717a01375L,0x438477c950d872b1L,\n        0xcec67879ffe1d63dL },\n      { 0x9b006014d8578c70L,0xc9ad99a878bb6b8bL,0x6799008e11fb3806L,\n        0xcfe81435cd44cab3L } },\n    /* 21 << 245 */\n    { { 0xa2ee15822f4fb344L,0xb8823450483fa6ebL,0x622d323d652c7749L,\n        0xd8474a98beb0a15bL },\n      { 0xe43c154d5d1c00d0L,0x7fd581d90e3e7aacL,0x2b44c6192525ddf8L,\n        0x67a033ebb8ae9739L } },\n    /* 22 << 245 */\n    { { 0x113ffec19ef2d2e4L,0x1bf6767ed5a0ea7fL,0x57fff75e03714c0aL,\n        0xa23c422e0a23e9eeL },\n      { 0xdd5f6b2d540f83afL,0xc2c2c27e55ea46a7L,0xeb6b4246672a1208L,\n        0xd13599f7ae634f7aL } },\n    /* 23 << 245 */\n    { { 0xcf914b5cd7b32c6eL,0x61a5a640eaf61814L,0x8dc3df8b208a1bbbL,\n        0xef627fd6b6d79aa5L },\n      { 0x44232ffcc4c86bc8L,0xe6f9231b061539feL,0x1d04f25a958b9533L,\n        0x180cf93449e8c885L } },\n    /* 24 << 245 */\n    { { 0x896895959884aaf7L,0xb1959be307b348a6L,0x96250e573c147c87L,\n        0xae0efb3add0c61f8L },\n      { 0xed00745eca8c325eL,0x3c911696ecff3f70L,0x73acbc65319ad41dL,\n        0x7b01a020f0b1c7efL } },\n    /* 25 << 245 */\n    { { 0xea32b29363a1483fL,0x89eabe717a248f96L,0x9c6231d3343157e5L,\n        0x93a375e5df3c546dL },\n      { 0xe76e93436a2afe69L,0xc4f89100e166c88eL,0x248efd0d4f872093L,\n        0xae0eb3ea8fe0ea61L } },\n    /* 26 << 245 */\n    { { 0xaf89790d9d79046eL,0x4d650f2d6cee0976L,0xa3935d9a43071ecaL,\n        0x66fcd2c9283b0bfeL },\n      { 0x0e665eb5696605f1L,0xe77e5d07a54cd38dL,0x90ee050a43d950cfL,\n        0x86ddebdad32e69b5L } },\n    /* 27 << 245 */\n    { { 0x6ad94a3dfddf7415L,0xf7fa13093f6e8d5aL,0xc4831d1de9957f75L,\n        0x7de28501d5817447L },\n      { 0x6f1d70789e2aeb6bL,0xba2b9ff4f67a53c2L,0x36963767df9defc3L,\n        0x479deed30d38022cL } },\n    /* 28 << 245 */\n    { { 0xd2edb89b3a8631e8L,0x8de855de7a213746L,0xb2056cb7b00c5f11L,\n        0xdeaefbd02c9b85e4L },\n      { 0x03f39a8dd150892dL,0x37b84686218b7985L,0x36296dd8b7375f1aL,\n        0x472cd4b1b78e898eL } },\n    /* 29 << 245 */\n    { { 0x15dff651e9f05de9L,0xd40450692ce98ba9L,0x8466a7ae9b38024cL,\n        0xb910e700e5a6b5efL },\n      { 0xae1c56eab3aa8f0dL,0xbab2a5077eee74a6L,0x0dca11e24b4c4620L,\n        0xfd896e2e4c47d1f4L } },\n    /* 30 << 245 */\n    { { 0xeb45ae53308fbd93L,0x46cd5a2e02c36fdaL,0x6a3d4e90baa48385L,\n        0xdd55e62e9dbe9960L },\n      { 0xa1406aa02a81ede7L,0x6860dd14f9274ea7L,0xcfdcb0c280414f86L,\n        0xff410b1022f94327L } },\n    /* 31 << 245 */\n    { { 0x5a33cc3849ad467bL,0xefb48b6c0a7335f1L,0x14fb54a4b153a360L,\n        0x604aa9d2b52469ccL },\n      { 0x5e9dc486754e48e9L,0x693cb45537471e8eL,0xfb2fd7cd8d3b37b6L,\n        0x63345e16cf09ff07L } },\n    /* 32 << 245 */\n    { { 0x9910ba6b23a5d896L,0x1fe19e357fe4364eL,0x6e1da8c39a33c677L,\n        0x15b4488b29fd9fd0L },\n      { 0x1f4392541a1f22bfL,0x920a8a70ab8163e8L,0x3fd1b24907e5658eL,\n        0xf2c4f79cb6ec839bL } },\n    /* 33 << 245 */\n    { { 0x1abbc3d04aa38d1bL,0x3b0db35cb5d9510eL,0x1754ac783e60dec0L,\n        0x53272fd7ea099b33L },\n      { 0x5fb0494f07a8e107L,0x4a89e1376a8191faL,0xa113b7f63c4ad544L,\n        0x88a2e9096cb9897bL } },\n    /* 34 << 245 */\n    { { 0x17d55de3b44a3f84L,0xacb2f34417c6c690L,0x3208816810232390L,\n        0xf2e8a61f6c733bf7L },\n      { 0xa774aab69c2d7652L,0xfb5307e3ed95c5bcL,0xa05c73c24981f110L,\n        0x1baae31ca39458c9L } },\n    /* 35 << 245 */\n    { { 0x1def185bcbea62e7L,0xe8ac9eaeeaf63059L,0x098a8cfd9921851cL,\n        0xd959c3f13abe2f5bL },\n      { 0xa4f1952520e40ae5L,0x320789e307a24aa1L,0x259e69277392b2bcL,\n        0x58f6c6671918668bL } },\n    /* 36 << 245 */\n    { { 0xce1db2bbc55d2d8bL,0x41d58bb7f4f6ca56L,0x7650b6808f877614L,\n        0x905e16baf4c349edL },\n      { 0xed415140f661acacL,0x3b8784f0cb2270afL,0x3bc280ac8a402cbaL,\n        0xd53f71460937921aL } },\n    /* 37 << 245 */\n    { { 0xc03c8ee5e5681e83L,0x62126105f6ac9e4aL,0x9503a53f936b1a38L,\n        0x3d45e2d4782fecbdL },\n      { 0x69a5c43976e8ae98L,0xb53b2eebbfb4b00eL,0xf167471272386c89L,\n        0x30ca34a24268bce4L } },\n    /* 38 << 245 */\n    { { 0x7f1ed86c78341730L,0x8ef5beb8b525e248L,0xbbc489fdb74fbf38L,\n        0x38a92a0e91a0b382L },\n      { 0x7a77ba3f22433ccfL,0xde8362d6a29f05a9L,0x7f6a30ea61189afcL,\n        0x693b550559ef114fL } },\n    /* 39 << 245 */\n    { { 0x50266bc0cd1797a1L,0xea17b47ef4b7af2dL,0xd6c4025c3df9483eL,\n        0x8cbb9d9fa37b18c9L },\n      { 0x91cbfd9c4d8424cfL,0xdb7048f1ab1c3506L,0x9eaf641f028206a3L,\n        0xf986f3f925bdf6ceL } },\n    /* 40 << 245 */\n    { { 0x262143b5224c08dcL,0x2bbb09b481b50c91L,0xc16ed709aca8c84fL,\n        0xa6210d9db2850ca8L },\n      { 0x6d8df67a09cb54d6L,0x91eef6e0500919a4L,0x90f613810f132857L,\n        0x9acede47f8d5028bL } },\n    /* 41 << 245 */\n    { { 0x844d1b7190b771c3L,0x563b71e4ba6426beL,0x2efa2e83bdb802ffL,\n        0x3410cbabab5b4a41L },\n      { 0x555b2d2630da84ddL,0xd0711ae9ee1cc29aL,0xcf3e8c602f547792L,\n        0x03d7d5dedc678b35L } },\n    /* 42 << 245 */\n    { { 0x071a2fa8ced806b8L,0x222e6134697f1478L,0xdc16fd5dabfcdbbfL,\n        0x44912ebf121b53b8L },\n      { 0xac9436742496c27cL,0x8ea3176c1ffc26b0L,0xb6e224ac13debf2cL,\n        0x524cc235f372a832L } },\n    /* 43 << 245 */\n    { { 0xd706e1d89f6f1b18L,0x2552f00544cce35bL,0x8c8326c2a88e31fcL,\n        0xb5468b2cf9552047L },\n      { 0xce683e883ff90f2bL,0x77947bdf2f0a5423L,0xd0a1b28bed56e328L,\n        0xaee35253c20134acL } },\n    /* 44 << 245 */\n    { { 0x7e98367d3567962fL,0x379ed61f8188bffbL,0x73bba348faf130a1L,\n        0x6c1f75e1904ed734L },\n      { 0x189566423b4a79fcL,0xf20bc83d54ef4493L,0x836d425d9111eca1L,\n        0xe5b5c318009a8dcfL } },\n    /* 45 << 245 */\n    { { 0x3360b25d13221bc5L,0x707baad26b3eeaf7L,0xd7279ed8743a95a1L,\n        0x7450a875969e809fL },\n      { 0x32b6bd53e5d0338fL,0x1e77f7af2b883bbcL,0x90da12cc1063ecd0L,\n        0xe2697b58c315be47L } },\n    /* 46 << 245 */\n    { { 0x2771a5bdda85d534L,0x53e78c1fff980eeaL,0xadf1cf84900385e7L,\n        0x7d3b14f6c9387b62L },\n      { 0x170e74b0cb8f2bd2L,0x2d50b486827fa993L,0xcdbe8c9af6f32babL,\n        0x55e906b0c3b93ab8L } },\n    /* 47 << 245 */\n    { { 0x747f22fc8fe280d1L,0xcd8e0de5b2e114abL,0x5ab7dbebe10b68b0L,\n        0x9dc63a9ca480d4b2L },\n      { 0x78d4bc3b4be1495fL,0x25eb3db89359122dL,0x3f8ac05b0809cbdcL,\n        0xbf4187bbd37c702fL } },\n    /* 48 << 245 */\n    { { 0x84cea0691416a6a5L,0x8f860c7943ef881cL,0x41311f8a38038a5dL,\n        0xe78c2ec0fc612067L },\n      { 0x494d2e815ad73581L,0xb4cc9e0059604097L,0xff558aecf3612cbaL,\n        0x35beef7a9e36c39eL } },\n    /* 49 << 245 */\n    { { 0x1845c7cfdbcf41b9L,0x5703662aaea997c0L,0x8b925afee402f6d8L,\n        0xd0a1b1ae4dd72162L },\n      { 0x9f47b37503c41c4bL,0xa023829b0391d042L,0x5f5045c3503b8b0aL,\n        0x123c268898c010e5L } },\n    /* 50 << 245 */\n    { { 0x324ec0cc36ba06eeL,0xface31153dd2cc0cL,0xb364f3bef333e91fL,\n        0xef8aff7328e832b0L },\n      { 0x1e9bad042d05841bL,0x42f0e3df356a21e2L,0xa3270bcb4add627eL,\n        0xb09a8158d322e711L } },\n    /* 51 << 245 */\n    { { 0x86e326a10fee104aL,0xad7788f83703f65dL,0x7e76543047bc4833L,\n        0x6cee582b2b9b893aL },\n      { 0x9cd2a167e8f55a7bL,0xefbee3c6d9e4190dL,0x33ee7185d40c2e9dL,\n        0x844cc9c5a380b548L } },\n    /* 52 << 245 */\n    { { 0x323f8ecd66926e04L,0x0001e38f8110c1baL,0x8dbcac12fc6a7f07L,\n        0xd65e1d580cec0827L },\n      { 0xd2cd4141be76ca2dL,0x7895cf5ce892f33aL,0x956d230d367139d2L,\n        0xa91abd3ed012c4c1L } },\n    /* 53 << 245 */\n    { { 0x34fa488387eb36bfL,0xc5f07102914b8fb4L,0x90f0e579adb9c95fL,\n        0xfe6ea8cb28888195L },\n      { 0x7b9b5065edfa9284L,0x6c510bd22b8c8d65L,0xd7b8ebefcbe8aafdL,\n        0xedb3af9896b1da07L } },\n    /* 54 << 245 */\n    { { 0x28ff779d6295d426L,0x0c4f6ac73fa3ad7bL,0xec44d0548b8e2604L,\n        0x9b32a66d8b0050e1L },\n      { 0x1f943366f0476ce2L,0x7554d953a602c7b4L,0xbe35aca6524f2809L,\n        0xb6881229fd4edbeaL } },\n    /* 55 << 245 */\n    { { 0xe8cd0c8f508efb63L,0x9eb5b5c86abcefc7L,0xf5621f5fb441ab4fL,\n        0x79e6c046b76a2b22L },\n      { 0x74a4792ce37a1f69L,0xcbd252cb03542b60L,0x785f65d5b3c20bd3L,\n        0x8dea61434fabc60cL } },\n    /* 56 << 245 */\n    { { 0x45e21446de673629L,0x57f7aa1e703c2d21L,0xa0e99b7f98c868c7L,\n        0x4e42f66d8b641676L },\n      { 0x602884dc91077896L,0xa0d690cfc2c9885bL,0xfeb4da333b9a5187L,\n        0x5f789598153c87eeL } },\n    /* 57 << 245 */\n    { { 0x2192dd4752b16dbaL,0xdeefc0e63524c1b1L,0x465ea76ee4383693L,\n        0x79401711361b8d98L },\n      { 0xa5f9ace9f21a15cbL,0x73d26163efee9aebL,0xcca844b3e677016cL,\n        0x6c122b0757eaee06L } },\n    /* 58 << 245 */\n    { { 0xb782dce715f09690L,0x508b9b122dfc0fc9L,0x9015ab4b65d89fc6L,\n        0x5e79dab7d6d5bb0fL },\n      { 0x64f021f06c775aa2L,0xdf09d8cc37c7eca1L,0x9a761367ef2fa506L,\n        0xed4ca4765b81eec6L } },\n    /* 59 << 245 */\n    { { 0x262ede3610bbb8b5L,0x0737ce830641ada3L,0x4c94288ae9831cccL,\n        0x487fc1ce8065e635L },\n      { 0xb13d7ab3b8bb3659L,0xdea5df3e855e4120L,0xb9a1857385eb0244L,\n        0x1a1b8ea3a7cfe0a3L } },\n    /* 60 << 245 */\n    { { 0x3b83711967b0867cL,0x8d5e0d089d364520L,0x52dccc1ed930f0e3L,\n        0xefbbcec7bf20bbafL },\n      { 0x99cffcab0263ad10L,0xd8199e6dfcd18f8aL,0x64e2773fe9f10617L,\n        0x0079e8e108704848L } },\n    /* 61 << 245 */\n    { { 0x1169989f8a342283L,0x8097799ca83012e6L,0xece966cb8a6a9001L,\n        0x93b3afef072ac7fcL },\n      { 0xe6893a2a2db3d5baL,0x263dc46289bf4fdcL,0x8852dfc9e0396673L,\n        0x7ac708953af362b6L } },\n    /* 62 << 245 */\n    { { 0xbb9cce4d5c2f342bL,0xbf80907ab52d7aaeL,0x97f3d3cd2161bcd0L,\n        0xb25b08340962744dL },\n      { 0xc5b18ea56c3a1ddaL,0xfe4ec7eb06c92317L,0xb787b890ad1c4afeL,\n        0xdccd9a920ede801aL } },\n    /* 63 << 245 */\n    { { 0x9ac6dddadb58da1fL,0x22bbc12fb8cae6eeL,0xc6f8bced815c4a43L,\n        0x8105a92cf96480c7L },\n      { 0x0dc3dbf37a859d51L,0xe3ec7ce63041196bL,0xd9f64b250d1067c9L,\n        0xf23213213d1f8dd8L } },\n    /* 64 << 245 */\n    { { 0x8b5c619c76497ee8L,0x5d2b0ac6c717370eL,0x98204cb64fcf68e1L,\n        0x0bdec21162bc6792L },\n      { 0x6973ccefa63b1011L,0xf9e3fa97e0de1ac5L,0x5efb693e3d0e0c8bL,\n        0x037248e9d2d4fcb4L } },\n    /* 0 << 252 */\n    { { 0x00, 0x00, 0x00, 0x00 },\n      { 0x00, 0x00, 0x00, 0x00 } },\n    /* 1 << 252 */\n    { { 0x80802dc91ec34f9eL,0xd8772d3533810603L,0x3f06d66c530cb4f3L,\n        0x7be5ed0dc475c129L },\n      { 0xcb9e3c1931e82b10L,0xc63d2857c9ff6b4cL,0xb92118c692a1b45eL,\n        0x0aec44147285bbcaL } },\n    /* 2 << 252 */\n    { { 0xfc189ae71e29a3efL,0xcbe906f04c93302eL,0xd0107914ceaae10eL,\n        0xb7a23f34b68e19f8L },\n      { 0xe9d875c2efd2119dL,0x03198c6efcadc9c8L,0x65591bf64da17113L,\n        0x3cf0bbf83d443038L } },\n    /* 3 << 252 */\n    { { 0xae485bb72b724759L,0x945353e1b2d4c63aL,0x82159d07de7d6f2cL,\n        0x389caef34ec5b109L },\n      { 0x4a8ebb53db65ef14L,0x2dc2cb7edd99de43L,0x816fa3ed83f2405fL,\n        0x73429bb9c14208a3L } },\n    /* 4 << 252 */\n    { { 0xb618d590b01e6e27L,0x047e2ccde180b2dcL,0xd1b299b504aea4a9L,\n        0x412c9e1e9fa403a4L },\n      { 0x88d28a3679407552L,0x49c50136f332b8e3L,0x3a1b6fcce668de19L,\n        0x178851bc75122b97L } },\n    /* 5 << 252 */\n    { { 0xb1e13752fb85fa4cL,0xd61257ce383c8ce9L,0xd43da670d2f74daeL,\n        0xa35aa23fbf846bbbL },\n      { 0x5e74235d4421fc83L,0xf6df8ee0c363473bL,0x34d7f52a3c4aa158L,\n        0x50d05aab9bc6d22eL } },\n    /* 6 << 252 */\n    { { 0x8c56e735a64785f4L,0xbc56637b5f29cd07L,0x53b2bb803ee35067L,\n        0x50235a0fdc919270L },\n      { 0x191ab6d8f2c4aa65L,0xc34758318396023bL,0x80400ba5f0f805baL,\n        0x8881065b5ec0f80fL } },\n    /* 7 << 252 */\n    { { 0xc370e522cc1b5e83L,0xde2d4ad1860b8bfbL,0xad364df067b256dfL,\n        0x8f12502ee0138997L },\n      { 0x503fa0dc7783920aL,0xe80014adc0bc866aL,0x3f89b744d3064ba6L,\n        0x03511dcdcba5dba5L } },\n    /* 8 << 252 */\n    { { 0x197dd46d95a7b1a2L,0x9c4e7ad63c6341fbL,0x426eca29484c2eceL,\n        0x9211e489de7f4f8aL },\n      { 0x14997f6ec78ef1f4L,0x2b2c091006574586L,0x17286a6e1c3eede8L,\n        0x25f92e470f60e018L } },\n    /* 9 << 252 */\n    { { 0x805c564631890a36L,0x703ef60057feea5bL,0x389f747caf3c3030L,\n        0xe0e5daeb54dd3739L },\n      { 0xfe24a4c3c9c9f155L,0x7e4bf176b5393962L,0x37183de2af20bf29L,\n        0x4a1bd7b5f95a8c3bL } },\n    /* 10 << 252 */\n    { { 0xa83b969946191d3dL,0x281fc8dd7b87f257L,0xb18e2c1354107588L,\n        0x6372def79b2bafe8L },\n      { 0xdaf4bb480d8972caL,0x3f2dd4b756167a3fL,0x1eace32d84310cf4L,\n        0xe3bcefafe42700aaL } },\n    /* 11 << 252 */\n    { { 0x5fe5691ed785e73dL,0xa5db5ab62ea60467L,0x02e23d41dfc6514aL,\n        0x35e8048ee03c3665L },\n      { 0x3f8b118f1adaa0f8L,0x28ec3b4584ce1a5aL,0xe8cacc6e2c6646b8L,\n        0x1343d185dbd0e40fL } },\n    /* 12 << 252 */\n    { { 0xe5d7f844caaa358cL,0x1a1db7e49924182aL,0xd64cd42d9c875d9aL,\n        0xb37b515f042eeec8L },\n      { 0x4d4dd4097b165fbeL,0xfc322ed9e206eff3L,0x7dee410259b7e17eL,\n        0x55a481c08236ca00L } },\n    /* 13 << 252 */\n    { { 0x8c885312c23fc975L,0x1571580605d6297bL,0xa078868ef78edd39L,\n        0x956b31e003c45e52L },\n      { 0x470275d5ff7b33a6L,0xc8d5dc3a0c7e673fL,0x419227b47e2f2598L,\n        0x8b37b6344c14a975L } },\n    /* 14 << 252 */\n    { { 0xd0667ed68b11888cL,0x5e0e8c3e803e25dcL,0x34e5d0dcb987a24aL,\n        0x9f40ac3bae920323L },\n      { 0x5463de9534e0f63aL,0xa128bf926b6328f9L,0x491ccd7cda64f1b7L,\n        0x7ef1ec27c47bde35L } },\n    /* 15 << 252 */\n    { { 0xa857240fa36a2737L,0x35dc136663621bc1L,0x7a3a6453d4fb6897L,\n        0x80f1a439c929319dL },\n      { 0xfc18274bf8cb0ba0L,0xb0b537668078c5ebL,0xfb0d49241e01d0efL,\n        0x50d7c67d372ab09cL } },\n    /* 16 << 252 */\n    { { 0xb4e370af3aeac968L,0xe4f7fee9c4b63266L,0xb4acd4c2e3ac5664L,\n        0xf8910bd2ceb38cbfL },\n      { 0x1c3ae50cc9c0726eL,0x15309569d97b40bfL,0x70884b7ffd5a5a1bL,\n        0x3890896aef8314cdL } },\n    /* 17 << 252 */\n    { { 0x58e1515ca5618c93L,0xe665432b77d942d1L,0xb32181bfb6f767a8L,\n        0x753794e83a604110L },\n      { 0x09afeb7ce8c0dbccL,0x31e02613598673a3L,0x5d98e5577d46db00L,\n        0xfc21fb8c9d985b28L } },\n    /* 18 << 252 */\n    { { 0xc9040116b0843e0bL,0x53b1b3a869b04531L,0xdd1649f085d7d830L,\n        0xbb3bcc87cb7427e8L },\n      { 0x77261100c93dce83L,0x7e79da61a1922a2aL,0x587a2b02f3149ce8L,\n        0x147e1384de92ec83L } },\n    /* 19 << 252 */\n    { { 0x484c83d3af077f30L,0xea78f8440658b53aL,0x912076c2027aec53L,\n        0xf34714e393c8177dL },\n      { 0x37ef5d15c2376c84L,0x8315b6593d1aa783L,0x3a75c484ef852a90L,\n        0x0ba0c58a16086bd4L } },\n    /* 20 << 252 */\n    { { 0x29688d7a529a6d48L,0x9c7f250dc2f19203L,0x123042fb682e2df9L,\n        0x2b7587e7ad8121bcL },\n      { 0x30fc0233e0182a65L,0xb82ecf87e3e1128aL,0x7168286193fb098fL,\n        0x043e21ae85e9e6a7L } },\n    /* 21 << 252 */\n    { { 0xab5b49d666c834eaL,0x3be43e1847414287L,0xf40fb859219a2a47L,\n        0x0e6559e9cc58df3cL },\n      { 0xfe1dfe8e0c6615b4L,0x14abc8fd56459d70L,0x7be0fa8e05de0386L,\n        0x8e63ef68e9035c7cL } },\n    /* 22 << 252 */\n    { { 0x116401b453b31e91L,0x0cba7ad44436b4d8L,0x9151f9a0107afd66L,\n        0xafaca8d01f0ee4c4L },\n      { 0x75fe5c1d9ee9761cL,0x3497a16bf0c0588fL,0x3ee2bebd0304804cL,\n        0xa8fb9a60c2c990b9L } },\n    /* 23 << 252 */\n    { { 0xd14d32fe39251114L,0x36bf25bccac73366L,0xc9562c66dba7495cL,\n        0x324d301b46ad348bL },\n      { 0x9f46620cd670407eL,0x0ea8d4f1e3733a01L,0xd396d532b0c324e0L,\n        0x5b211a0e03c317cdL } },\n    /* 24 << 252 */\n    { { 0x090d7d205ffe7b37L,0x3b7f3efb1747d2daL,0xa2cb525fb54fc519L,\n        0x6e220932f66a971eL },\n      { 0xddc160dfb486d440L,0x7fcfec463fe13465L,0x83da7e4e76e4c151L,\n        0xd6fa48a1d8d302b5L } },\n    /* 25 << 252 */\n    { { 0xc6304f265872cd88L,0x806c1d3c278b90a1L,0x3553e725caf0bc1cL,\n        0xff59e603bb9d8d5cL },\n      { 0xa4550f327a0b85ddL,0xdec5720a93ecc217L,0x0b88b74169d62213L,\n        0x7212f2455b365955L } },\n    /* 26 << 252 */\n    { { 0x20764111b5cae787L,0x13cb7f581dfd3124L,0x2dca77da1175aefbL,\n        0xeb75466bffaae775L },\n      { 0x74d76f3bdb6cff32L,0x7440f37a61fcda9aL,0x1bb3ac92b525028bL,\n        0x20fbf8f7a1975f29L } },\n    /* 27 << 252 */\n    { { 0x982692e1df83097fL,0x28738f6c554b0800L,0xdc703717a2ce2f2fL,\n        0x7913b93c40814194L },\n      { 0x049245931fe89636L,0x7b98443ff78834a6L,0x11c6ab015114a5a1L,\n        0x60deb383ffba5f4cL } },\n    /* 28 << 252 */\n    { { 0x4caa54c601a982e6L,0x1dd35e113491cd26L,0x973c315f7cbd6b05L,\n        0xcab0077552494724L },\n      { 0x04659b1f6565e15aL,0xbf30f5298c8fb026L,0xfc21641ba8a0de37L,\n        0xe9c7a366fa5e5114L } },\n    /* 29 << 252 */\n    { { 0xdb849ca552f03ad8L,0xc7e8dbe9024e35c0L,0xa1a2bbaccfc3c789L,\n        0xbf733e7d9c26f262L },\n      { 0x882ffbf5b8444823L,0xb7224e886bf8483bL,0x53023b8b65bef640L,\n        0xaabfec91d4d5f8cdL } },\n    /* 30 << 252 */\n    { { 0xa40e1510079ea1bdL,0x1ad9addcd05d5d26L,0xdb3f2eab13e68d4fL,\n        0x1cff1ae2640f803fL },\n      { 0xe0e7b749d4cee117L,0x8e9f275b4036d909L,0xce34e31d8f4d4c38L,\n        0x22b37f69d75130fcL } },\n    /* 31 << 252 */\n    { { 0x83e0f1fdb4014604L,0xa8ce991989415078L,0x82375b7541792efeL,\n        0x4f59bf5c97d4515bL },\n      { 0xac4f324f923a277dL,0xd9bc9b7d650f3406L,0xc6fa87d18a39bc51L,\n        0x825885305ccc108fL } },\n    /* 32 << 252 */\n    { { 0x5ced3c9f82e4c634L,0x8efb83143a4464f8L,0xe706381b7a1dca25L,\n        0x6cd15a3c5a2a412bL },\n      { 0x9347a8fdbfcd8fb5L,0x31db2eef6e54cd22L,0xc4aeb11ef8d8932fL,\n        0x11e7c1ed344411afL } },\n    /* 33 << 252 */\n    { { 0x2653050cdc9a151eL,0x9edbfc083bb0a859L,0x926c81c7fd5691e7L,\n        0x9c1b23426f39019aL },\n      { 0x64a81c8b7f8474b9L,0x90657c0701761819L,0x390b333155e0375aL,\n        0xc676c626b6ebc47dL } },\n    /* 34 << 252 */\n    { { 0x51623247b7d6dee8L,0x0948d92779659313L,0x99700161e9ab35edL,\n        0x06cc32b48ddde408L },\n      { 0x6f2fd664061ef338L,0x1606fa02c202e9edL,0x55388bc1929ba99bL,\n        0xc4428c5e1e81df69L } },\n    /* 35 << 252 */\n    { { 0xce2028aef91b0b2aL,0xce870a23f03dfd3fL,0x66ec2c870affe8edL,\n        0xb205fb46284d0c00L },\n      { 0xbf5dffe744cefa48L,0xb6fc37a8a19876d7L,0xbecfa84c08b72863L,\n        0xd7205ff52576374fL } },\n    /* 36 << 252 */\n    { { 0x80330d328887de41L,0x5de0df0c869ea534L,0x13f427533c56ea17L,\n        0xeb1f6069452b1a78L },\n      { 0x50474396e30ea15cL,0x575816a1c1494125L,0xbe1ce55bfe6bb38fL,\n        0xb901a94896ae30f7L } },\n    /* 37 << 252 */\n    { { 0xe5af0f08d8fc3548L,0x5010b5d0d73bfd08L,0x993d288053fe655aL,\n        0x99f2630b1c1309fdL },\n      { 0xd8677bafb4e3b76fL,0x14e51ddcb840784bL,0x326c750cbf0092ceL,\n        0xc83d306bf528320fL } },\n    /* 38 << 252 */\n    { { 0xc445671577d4715cL,0xd30019f96b703235L,0x207ccb2ed669e986L,\n        0x57c824aff6dbfc28L },\n      { 0xf0eb532fd8f92a23L,0x4a557fd49bb98fd2L,0xa57acea7c1e6199aL,\n        0x0c6638208b94b1edL } },\n    /* 39 << 252 */\n    { { 0x9b42be8ff83a9266L,0xc7741c970101bd45L,0x95770c1107bd9cebL,\n        0x1f50250a8b2e0744L },\n      { 0xf762eec81477b654L,0xc65b900e15efe59aL,0x88c961489546a897L,\n        0x7e8025b3c30b4d7cL } },\n    /* 40 << 252 */\n    { { 0xae4065ef12045cf9L,0x6fcb2caf9ccce8bdL,0x1fa0ba4ef2cf6525L,\n        0xf683125dcb72c312L },\n      { 0xa01da4eae312410eL,0x67e286776cd8e830L,0xabd9575298fb3f07L,\n        0x05f11e11eef649a5L } },\n    /* 41 << 252 */\n    { { 0xba47faef9d3472c2L,0x3adff697c77d1345L,0x4761fa04dd15afeeL,\n        0x64f1f61ab9e69462L },\n      { 0xfa691fab9bfb9093L,0x3df8ae8fa1133dfeL,0xcd5f896758cc710dL,\n        0xfbb88d5016c7fe79L } },\n    /* 42 << 252 */\n    { { 0x8e011b4ce88c50d1L,0x7532e807a8771c4fL,0x64c78a48e2278ee4L,\n        0x0b283e833845072aL },\n      { 0x98a6f29149e69274L,0xb96e96681868b21cL,0x38f0adc2b1a8908eL,\n        0x90afcff71feb829dL } },\n    /* 43 << 252 */\n    { { 0x9915a383210b0856L,0xa5a80602def04889L,0x800e9af97c64d509L,\n        0x81382d0bb8996f6fL },\n      { 0x490eba5381927e27L,0x46c63b324af50182L,0x784c5fd9d3ad62ceL,\n        0xe4fa1870f8ae8736L } },\n    /* 44 << 252 */\n    { { 0x4ec9d0bcd7466b25L,0x84ddbe1adb235c65L,0x5e2645ee163c1688L,\n        0x570bd00e00eba747L },\n      { 0xfa51b629128bfa0fL,0x92fce1bd6c1d3b68L,0x3e7361dcb66778b1L,\n        0x9c7d249d5561d2bbL } },\n    /* 45 << 252 */\n    { { 0xa40b28bf0bbc6229L,0x1c83c05edfd91497L,0x5f9f5154f083df05L,\n        0xbac38b3ceee66c9dL },\n      { 0xf71db7e3ec0dfcfdL,0xf2ecda8e8b0a8416L,0x52fddd867812aa66L,\n        0x2896ef104e6f4272L } },\n    /* 46 << 252 */\n    { { 0xff27186a0fe9a745L,0x08249fcd49ca70dbL,0x7425a2e6441cac49L,\n        0xf4a0885aece5ff57L },\n      { 0x6e2cb7317d7ead58L,0xf96cf7d61898d104L,0xafe67c9d4f2c9a89L,\n        0x89895a501c7bf5bcL } },\n    /* 47 << 252 */\n    { { 0xdc7cb8e5573cecfaL,0x66497eaed15f03e6L,0x6bc0de693f084420L,\n        0x323b9b36acd532b0L },\n      { 0xcfed390a0115a3c1L,0x9414c40b2d65ca0eL,0x641406bd2f530c78L,\n        0x29369a44833438f2L } },\n    /* 48 << 252 */\n    { { 0x996884f5903fa271L,0xe6da0fd2b9da921eL,0xa6f2f2695db01e54L,\n        0x1ee3e9bd6876214eL },\n      { 0xa26e181ce27a9497L,0x36d254e48e215e04L,0x42f32a6c252cabcaL,\n        0x9948148780b57614L } },\n    /* 49 << 252 */\n    { { 0x4c4dfe6940d9cae1L,0x0586958011a10f09L,0xca287b573491b64bL,\n        0x77862d5d3fd4a53bL },\n      { 0xbf94856e50349126L,0x2be30bd171c5268fL,0x10393f19cbb650a6L,\n        0x639531fe778cf9fdL } },\n    /* 50 << 252 */\n    { { 0x02556a11b2935359L,0xda38aa96af8c126eL,0x47dbe6c20960167fL,\n        0x37bbabb6501901cdL },\n      { 0xb6e979e02c947778L,0xd69a51757a1a1dc6L,0xc3ed50959d9faf0cL,\n        0x4dd9c0961d5fa5f0L } },\n    /* 51 << 252 */\n    { { 0xa0c4304d64f16ea8L,0x8b1cac167e718623L,0x0b5765467c67f03eL,\n        0x559cf5adcbd88c01L },\n      { 0x074877bb0e2af19aL,0x1f717ec1a1228c92L,0x70bcb800326e8920L,\n        0xec6e2c5c4f312804L } },\n    /* 52 << 252 */\n    { { 0x426aea7d3fca4752L,0xf12c09492211f62aL,0x24beecd87be7b6b5L,\n        0xb77eaf4c36d7a27dL },\n      { 0x154c2781fda78fd3L,0x848a83b0264eeabeL,0x81287ef04ffe2bc4L,\n        0x7b6d88c6b6b6fc2aL } },\n    /* 53 << 252 */\n    { { 0x805fb947ce417d99L,0x4b93dcc38b916cc4L,0x72e65bb321273323L,\n        0xbcc1badd6ea9886eL },\n      { 0x0e2230114bc5ee85L,0xa561be74c18ee1e4L,0x762fd2d4a6bcf1f1L,\n        0x50e6a5a495231489L } },\n    /* 54 << 252 */\n    { { 0xca96001fa00b500bL,0x5c098cfc5d7dcdf5L,0xa64e2d2e8c446a85L,\n        0xbae9bcf1971f3c62L },\n      { 0x4ec226838435a2c5L,0x8ceaed6c4bad4643L,0xe9f8fb47ccccf4e3L,\n        0xbd4f3fa41ce3b21eL } },\n    /* 55 << 252 */\n    { { 0xd79fb110a3db3292L,0xe28a37dab536c66aL,0x279ce87b8e49e6a9L,\n        0x70ccfe8dfdcec8e3L },\n      { 0x2193e4e03ba464b2L,0x0f39d60eaca9a398L,0x7d7932aff82c12abL,\n        0xd8ff50ed91e7e0f7L } },\n    /* 56 << 252 */\n    { { 0xea961058fa28a7e0L,0xc726cf250bf5ec74L,0xe74d55c8db229666L,\n        0x0bd9abbfa57f5799L },\n      { 0x7479ef074dfc47b3L,0xd9c65fc30c52f91dL,0x8e0283fe36a8bde2L,\n        0xa32a8b5e7d4b7280L } },\n    /* 57 << 252 */\n    { { 0x6a677c6112e83233L,0x0fbb3512dcc9bf28L,0x562e8ea50d780f61L,\n        0x0db8b22b1dc4e89cL },\n      { 0x0a6fd1fb89be0144L,0x8c77d246ca57113bL,0x4639075dff09c91cL,\n        0x5b47b17f5060824cL } },\n    /* 58 << 252 */\n    { { 0x58aea2b016287b52L,0xa1343520d0cd8eb0L,0x6148b4d0c5d58573L,\n        0xdd2b6170291c68aeL },\n      { 0xa61b39291da3b3b7L,0x5f946d7908c4ac10L,0x4105d4a57217d583L,\n        0x5061da3d25e6de5eL } },\n    /* 59 << 252 */\n    { { 0x3113940dec1b4991L,0xf12195e136f485aeL,0xa7507fb2731a2ee0L,\n        0x95057a8e6e9e196eL },\n      { 0xa3c2c9112e130136L,0x97dfbb3633c60d15L,0xcaf3c581b300ee2bL,\n        0x77f25d90f4bac8b8L } },\n    /* 60 << 252 */\n    { { 0xdb1c4f986d840cd6L,0x471d62c0e634288cL,0x8ec2f85ecec8a161L,\n        0x41f37cbcfa6f4ae2L },\n      { 0x6793a20f4b709985L,0x7a7bd33befa8985bL,0x2c6a3fbd938e6446L,\n        0x190426192a8d47c1L } },\n    /* 61 << 252 */\n    { { 0x16848667cc36975fL,0x02acf1689d5f1dfbL,0x62d41ad4613baa94L,\n        0xb56fbb929f684670L },\n      { 0xce610d0de9e40569L,0x7b99c65f35489fefL,0x0c88ad1b3df18b97L,\n        0x81b7d9be5d0e9edbL } },\n    /* 62 << 252 */\n    { { 0xd85218c0c716cc0aL,0xf4b5ff9085691c49L,0xa4fd666bce356ac6L,\n        0x17c728954b327a7aL },\n      { 0xf93d5085da6be7deL,0xff71530e3301d34eL,0x4cd96442d8f448e8L,\n        0x9283d3312ed18ffaL } },\n    /* 63 << 252 */\n    { { 0x4d33dd992a849870L,0xa716964b41576335L,0xff5e3a9b179be0e5L,\n        0x5b9d6b1b83b13632L },\n      { 0x3b8bd7d4a52f313bL,0xc9dd95a0637a4660L,0x300359620b3e218fL,\n        0xce1481a3c7b28a3cL } },\n    /* 64 << 252 */\n    { { 0xab41b43a43228d83L,0x24ae1c304ad63f99L,0x8e525f1a46a51229L,\n        0x14af860fcd26d2b4L },\n      { 0xd6baef613f714aa1L,0xf51865adeb78795eL,0xd3e21fcee6a9d694L,\n        0x82ceb1dd8a37b527L } },\n};\n\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_add_only_4(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit tmpd[2 * 4 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* tmp;\n    sp_digit* negy;\n    int i;\n    ecc_recode v[37];\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY)\n        err = sp_ecc_point_new(heap, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, heap,\n                             DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n#else\n    tmp = tmpd;\n#endif\n    negy = tmp;\n\n    if (err == MP_OKAY) {\n        sp_256_ecc_recode_7_4(k, v);\n\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        i = 36;\n        XMEMCPY(rt->x, table[i * 65 + v[i].i].x, sizeof(table->x));\n        XMEMCPY(rt->y, table[i * 65 + v[i].i].y, sizeof(table->y));\n        rt->infinity = !v[i].i;\n        for (--i; i>=0; i--) {\n            XMEMCPY(p->x, table[i * 65 + v[i].i].x, sizeof(table->x));\n            XMEMCPY(p->y, table[i * 65 + v[i].i].y, sizeof(table->y));\n            p->infinity = !v[i].i;\n            sp_256_sub_4(negy, p256_mod, p->y);\n            sp_256_cond_copy_4(p->y, negy, 0 - v[i].neg);\n            sp_256_proj_point_add_qz1_4(rt, rt, p, tmp);\n        }\n        if (map != 0) {\n            sp_256_map_4(r, rt, tmp);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 4 * 5);\n        XFREE(tmp, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    ForceZero(tmp, sizeof(sp_digit) * 2 * 4 * 5);\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return MP_OKAY;\n}\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_4(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_add_only_4(r, NULL, p256_table,\n                                      k, map, heap);\n}\n\n#ifdef HAVE_INTEL_AVX2\n/* Multiply the point by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_add_only_avx2_4(sp_point* r, const sp_point* g,\n        const sp_table_entry* table, const sp_digit* k, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point rtd;\n    sp_point pd;\n    sp_digit tmpd[2 * 4 * 5];\n#endif\n    sp_point* rt;\n    sp_point* p = NULL;\n    sp_digit* tmp;\n    sp_digit* negy;\n    int i;\n    ecc_recode v[37];\n    int err;\n\n    (void)g;\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, rtd, rt);\n    if (err == MP_OKAY)\n        err = sp_ecc_point_new(heap, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, heap,\n                             DYNAMIC_TYPE_ECC);\n    if (tmp == NULL)\n        err = MEMORY_E;\n#else\n    tmp = tmpd;\n#endif\n    negy = tmp;\n\n    if (err == MP_OKAY) {\n        sp_256_ecc_recode_7_4(k, v);\n\n        XMEMCPY(p->z, p256_norm_mod, sizeof(p256_norm_mod));\n        XMEMCPY(rt->z, p256_norm_mod, sizeof(p256_norm_mod));\n\n        i = 36;\n        XMEMCPY(rt->x, table[i * 65 + v[i].i].x, sizeof(table->x));\n        XMEMCPY(rt->y, table[i * 65 + v[i].i].y, sizeof(table->y));\n        rt->infinity = !v[i].i;\n        for (--i; i>=0; i--) {\n            XMEMCPY(p->x, table[i * 65 + v[i].i].x, sizeof(table->x));\n            XMEMCPY(p->y, table[i * 65 + v[i].i].y, sizeof(table->y));\n            p->infinity = !v[i].i;\n            sp_256_sub_4(negy, p256_mod, p->y);\n            sp_256_cond_copy_4(p->y, negy, 0 - v[i].neg);\n            sp_256_proj_point_add_qz1_avx2_4(rt, rt, p, tmp);\n        }\n        if (map != 0) {\n            sp_256_map_avx2_4(r, rt, tmp);\n        }\n        else {\n            XMEMCPY(r, rt, sizeof(sp_point));\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 4 * 5);\n        XFREE(tmp, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    ForceZero(tmp, sizeof(sp_digit) * 2 * 4 * 5);\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(rt, 0, heap);\n\n    return MP_OKAY;\n}\n\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * r     Resulting point.\n * k     Scalar to multiply by.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nstatic int sp_256_ecc_mulmod_base_avx2_4(sp_point* r, const sp_digit* k,\n        int map, void* heap)\n{\n    return sp_256_ecc_mulmod_add_only_avx2_4(r, NULL, p256_table,\n                                      k, map, heap);\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n#endif /* WOLFSSL_SP_SMALL */\n/* Multiply the base point of P256 by the scalar and return the result.\n * If map is true then convert result to affine co-ordinates.\n *\n * km    Scalar to multiply by.\n * r     Resulting point.\n * map   Indicates whether to convert result to affine.\n * heap  Heap to use for allocation.\n * returns MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[4];\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 4, km);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_256_ecc_mulmod_base_avx2_4(point, k, map, heap);\n        else\n#endif\n            err = sp_256_ecc_mulmod_base_4(point, k, map, heap);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_4(point, r);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n\n#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \\\n                                                        defined(HAVE_ECC_VERIFY)\n/* Returns 1 if the number of zero.\n * Implementation is constant time.\n *\n * a  Number to check.\n * returns 1 if the number is zero and 0 otherwise.\n */\nstatic int sp_256_iszero_4(const sp_digit* a)\n{\n    return (a[0] | a[1] | a[2] | a[3]) == 0;\n}\n\n#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\nextern void sp_256_add_one_4(sp_digit* a);\n/* Read big endian unsigned byte array into r.\n *\n * r  A single precision integer.\n * size  Maximum number of bytes to convert\n * a  Byte array.\n * n  Number of bytes in array to read.\n */\nstatic void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n)\n{\n    int i, j = 0;\n    word32 s = 0;\n\n    r[0] = 0;\n    for (i = n-1; i >= 0; i--) {\n        r[j] |= (((sp_digit)a[i]) << s);\n        if (s >= 56U) {\n            r[j] &= 0xffffffffffffffffl;\n            s = 64U - s;\n            if (j + 1 >= size) {\n                break;\n            }\n            r[++j] = (sp_digit)a[i] >> s;\n            s = 8U - s;\n        }\n        else {\n            s += 8U;\n        }\n    }\n\n    for (j++; j < size; j++) {\n        r[j] = 0;\n    }\n}\n\n/* Generates a scalar that is in the range 1..order-1.\n *\n * rng  Random number generator.\n * k    Scalar value.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nstatic int sp_256_ecc_gen_k_4(WC_RNG* rng, sp_digit* k)\n{\n    int err;\n    byte buf[32];\n\n    do {\n        err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf));\n        if (err == 0) {\n            sp_256_from_bin(k, 4, buf, (int)sizeof(buf));\n            if (sp_256_cmp_4(k, p256_order2) < 0) {\n                sp_256_add_one_4(k);\n                break;\n            }\n        }\n    }\n    while (err == 0);\n\n    return err;\n}\n\n/* Makes a random EC key pair.\n *\n * rng   Random number generator.\n * priv  Generated private value.\n * pub   Generated public point.\n * heap  Heap to use for allocation.\n * returns ECC_INF_E when the point does not have the correct order, RNG\n * failures, MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[4];\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point inf;\n#endif\n#endif\n    sp_point* point;\n    sp_digit* k = NULL;\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_point* infinity;\n#endif\n    int err;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, inf, infinity);\n    }\n#endif\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_ecc_gen_k_4(rng, k);\n    }\n    if (err == MP_OKAY) {\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_256_ecc_mulmod_base_avx2_4(point, k, 1, NULL);\n        else\n#endif\n            err = sp_256_ecc_mulmod_base_4(point, k, 1, NULL);\n    }\n\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    if (err == MP_OKAY) {\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n            err = sp_256_ecc_mulmod_avx2_4(infinity, point, p256_order, 1,\n                                                                          NULL);\n        }\n        else\n#endif\n            err = sp_256_ecc_mulmod_4(infinity, point, p256_order, 1, NULL);\n    }\n    if (err == MP_OKAY) {\n        if ((sp_256_iszero_4(point->x) == 0) || (sp_256_iszero_4(point->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(k, priv);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_point_to_ecc_point_4(point, pub);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN\n    sp_ecc_point_free(infinity, 1, heap);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n\n#ifdef HAVE_ECC_DHE\n/* Write r as big endian to byte array.\n * Fixed length number of bytes written: 32\n *\n * r  A single precision integer.\n * a  Byte array.\n */\nstatic void sp_256_to_bin(sp_digit* r, byte* a)\n{\n    int i, j, s = 0, b;\n\n    j = 256 / 8 - 1;\n    a[j] = 0;\n    for (i=0; i<4 && j>=0; i++) {\n        b = 0;\n        /* lint allow cast of mismatch sp_digit and int */\n        a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/\n        if (j < 0) {\n            break;\n        }\n        while (b < 64) {\n            a[j--] = r[i] >> b; b += 8;\n            if (j < 0) {\n                break;\n            }\n        }\n        s = 8 - (b - 64);\n        if (j >= 0) {\n            a[j] = 0;\n        }\n        if (s != 0) {\n            j++;\n        }\n    }\n}\n\n/* Multiply the point by the scalar and serialize the X ordinate.\n * The number is 0 padded to maximum size on output.\n *\n * priv    Scalar to multiply the point by.\n * pub     Point to multiply.\n * out     Buffer to hold X ordinate.\n * outLen  On entry, size of the buffer in bytes.\n *         On exit, length of data in buffer in bytes.\n * heap    Heap to use for allocation.\n * returns BUFFER_E if the buffer is to small for output size,\n * MEMORY_E when memory allocation fails and MP_OKAY on success.\n */\nint sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out,\n                          word32* outLen, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point p;\n    sp_digit kd[4];\n#endif\n    sp_point* point = NULL;\n    sp_digit* k = NULL;\n    int err = MP_OKAY;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    if (*outLen < 32U) {\n        err = BUFFER_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p, point);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (k == NULL)\n            err = MEMORY_E;\n    }\n#else\n    k = kd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(k, 4, priv);\n        sp_256_point_from_ecc_point_4(point, pub);\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_256_ecc_mulmod_avx2_4(point, point, k, 1, heap);\n        else\n#endif\n            err = sp_256_ecc_mulmod_4(point, point, k, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        sp_256_to_bin(point->x, out);\n        *outLen = 32;\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (k != NULL) {\n        XFREE(k, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(point, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_DHE */\n\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\nextern sp_digit sp_256_add_4(sp_digit* r, const sp_digit* a, const sp_digit* b);\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\nextern void sp_256_mul_4(sp_digit* r, const sp_digit* a, const sp_digit* b);\n#ifdef HAVE_INTEL_AVX2\nextern void sp_256_mul_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit* b);\n#endif /* HAVE_INTEL_AVX2 */\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\nextern sp_digit sp_256_sub_in_place_4(sp_digit* a, const sp_digit* b);\nextern void sp_256_mul_d_4(sp_digit* r, const sp_digit* a, sp_digit b);\nextern void sp_256_mul_d_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit b);\n/* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div)\n *\n * d1   The high order half of the number to divide.\n * d0   The low order half of the number to divide.\n * div  The dividend.\n * returns the result of the division.\n */\nstatic WC_INLINE sp_digit div_256_word_4(sp_digit d1, sp_digit d0,\n        sp_digit div)\n{\n    register sp_digit r asm(\"rax\");\n    __asm__ __volatile__ (\n        \"divq %3\"\n        : \"=a\" (r)\n        : \"d\" (d1), \"a\" (d0), \"r\" (div)\n        :\n    );\n    return r;\n}\n/* AND m into each word of a and store in r.\n *\n * r  A single precision integer.\n * a  A single precision integer.\n * m  Mask to AND against each digit.\n */\nstatic void sp_256_mask_4(sp_digit* r, const sp_digit* a, sp_digit m)\n{\n#ifdef WOLFSSL_SP_SMALL\n    int i;\n\n    for (i=0; i<4; i++) {\n        r[i] = a[i] & m;\n    }\n#else\n    r[0] = a[0] & m;\n    r[1] = a[1] & m;\n    r[2] = a[2] & m;\n    r[3] = a[3] & m;\n#endif\n}\n\n/* Divide d in a and put remainder into r (m*d + r = a)\n * m is not calculated as it is not needed at this time.\n *\n * a  Nmber to be divided.\n * d  Number to divide with.\n * m  Multiplier result.\n * r  Remainder from the division.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_256_div_4(const sp_digit* a, const sp_digit* d, sp_digit* m,\n        sp_digit* r)\n{\n    sp_digit t1[8], t2[5];\n    sp_digit div, r1;\n    int i;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)m;\n\n    div = d[3];\n    XMEMCPY(t1, a, sizeof(*t1) * 2 * 4);\n    for (i=3; i>=0; i--) {\n        r1 = div_256_word_4(t1[4 + i], t1[4 + i - 1], div);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            sp_256_mul_d_avx2_4(t2, d, r1);\n        else\n#endif\n            sp_256_mul_d_4(t2, d, r1);\n        t1[4 + i] += sp_256_sub_in_place_4(&t1[i], t2);\n        t1[4 + i] -= t2[4];\n        sp_256_mask_4(t2, d, t1[4 + i]);\n        t1[4 + i] += sp_256_add_4(&t1[i], &t1[i], t2);\n        sp_256_mask_4(t2, d, t1[4 + i]);\n        t1[4 + i] += sp_256_add_4(&t1[i], &t1[i], t2);\n    }\n\n    r1 = sp_256_cmp_4(t1, d) >= 0;\n    sp_256_cond_sub_4(r, t1, d, (sp_digit)0 - r1);\n\n    return MP_OKAY;\n}\n\n/* Reduce a modulo m into r. (r = a mod m)\n *\n * r  A single precision number that is the reduced result.\n * a  A single precision number that is to be reduced.\n * m  A single precision number that is the modulus to reduce with.\n * returns MP_OKAY indicating success.\n */\nstatic WC_INLINE int sp_256_mod_4(sp_digit* r, const sp_digit* a, const sp_digit* m)\n{\n    return sp_256_div_4(a, m, NULL, r);\n}\n\n#endif\n#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)\nextern void sp_256_sqr_4(sp_digit* r, const sp_digit* a);\n#ifdef WOLFSSL_SP_SMALL\n/* Order-2 for the P256 curve. */\nstatic const uint64_t p256_order_2[4] = {\n    0xf3b9cac2fc63254fU,0xbce6faada7179e84U,0xffffffffffffffffU,\n    0xffffffff00000000U\n};\n#else\n/* The low half of the order-2 of the P256 curve. */\nstatic const uint64_t p256_order_low[2] = {\n    0xf3b9cac2fc63254fU,0xbce6faada7179e84U\n};\n#endif /* WOLFSSL_SP_SMALL */\n\n/* Multiply two number mod the order of P256 curve. (r = a * b mod order)\n *\n * r  Result of the multiplication.\n * a  First operand of the multiplication.\n * b  Second operand of the multiplication.\n */\nstatic void sp_256_mont_mul_order_4(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_256_mul_4(r, a, b);\n    sp_256_mont_reduce_order_4(r, p256_order, p256_mp_order);\n}\n\n/* Square number mod the order of P256 curve. (r = a * a mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_order_4(sp_digit* r, const sp_digit* a)\n{\n    sp_256_sqr_4(r, a);\n    sp_256_mont_reduce_order_4(r, p256_order, p256_mp_order);\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Square number mod the order of P256 curve a number of times.\n * (r = a ^ n mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_n_order_4(sp_digit* r, const sp_digit* a, int n)\n{\n    int i;\n\n    sp_256_mont_sqr_order_4(r, a);\n    for (i=1; i<n; i++) {\n        sp_256_mont_sqr_order_4(r, r);\n    }\n}\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the order of the P256 curve.\n * (r = 1 / a mod order)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_order_4(sp_digit* r, const sp_digit* a,\n        sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 4);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_order_4(t, t);\n        if ((p256_order_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_4(t, t, a);\n        }\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 4U);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 4;\n    sp_digit* t3 = td + 4 * 4;\n    int i;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_order_4(t, a);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_order_4(t, t, a);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_order_4(t2, t, 2);\n    /* t3= a^f = t2 * t */\n    sp_256_mont_mul_order_4(t3, t2, t);\n    /* t2= a^f0 = t3 ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_order_4(t2, t3, 4);\n    /* t = a^ff = t2 * t3 */\n    sp_256_mont_mul_order_4(t, t2, t3);\n    /* t3= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_order_4(t2, t, 8);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_order_4(t, t2, t);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_order_4(t2, t, 16);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_order_4(t, t2, t);\n    /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64  */\n    sp_256_mont_sqr_n_order_4(t2, t, 64);\n    /* t2= a^ffffffff00000000ffffffff = t2 * t */\n    sp_256_mont_mul_order_4(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_order_4(t2, t2, 32);\n    /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_order_4(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6 */\n    for (i=127; i>=112; i--) {\n        sp_256_mont_sqr_order_4(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_4(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6f */\n    sp_256_mont_sqr_n_order_4(t2, t2, 4);\n    sp_256_mont_mul_order_4(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */\n    for (i=107; i>=64; i--) {\n        sp_256_mont_sqr_order_4(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_4(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */\n    sp_256_mont_sqr_n_order_4(t2, t2, 4);\n    sp_256_mont_mul_order_4(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */\n    for (i=59; i>=32; i--) {\n        sp_256_mont_sqr_order_4(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_4(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */\n    sp_256_mont_sqr_n_order_4(t2, t2, 4);\n    sp_256_mont_mul_order_4(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */\n    for (i=27; i>=0; i--) {\n        sp_256_mont_sqr_order_4(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_4(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */\n    sp_256_mont_sqr_n_order_4(t2, t2, 4);\n    /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */\n    sp_256_mont_mul_order_4(r, t2, t3);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#ifdef HAVE_INTEL_AVX2\nextern void sp_256_sqr_avx2_4(sp_digit* r, const sp_digit* a);\n#define sp_256_mont_reduce_order_avx2_4    sp_256_mont_reduce_avx2_4\n\nextern void sp_256_mont_reduce_avx2_4(sp_digit* a, const sp_digit* m, sp_digit mp);\n/* Multiply two number mod the order of P256 curve. (r = a * b mod order)\n *\n * r  Result of the multiplication.\n * a  First operand of the multiplication.\n * b  Second operand of the multiplication.\n */\nstatic void sp_256_mont_mul_order_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit* b)\n{\n    sp_256_mul_avx2_4(r, a, b);\n    sp_256_mont_reduce_order_avx2_4(r, p256_order, p256_mp_order);\n}\n\n/* Square number mod the order of P256 curve. (r = a * a mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_order_avx2_4(sp_digit* r, const sp_digit* a)\n{\n    sp_256_sqr_avx2_4(r, a);\n    sp_256_mont_reduce_order_avx2_4(r, p256_order, p256_mp_order);\n}\n\n#ifndef WOLFSSL_SP_SMALL\n/* Square number mod the order of P256 curve a number of times.\n * (r = a ^ n mod order)\n *\n * r  Result of the squaring.\n * a  Number to square.\n */\nstatic void sp_256_mont_sqr_n_order_avx2_4(sp_digit* r, const sp_digit* a, int n)\n{\n    int i;\n\n    sp_256_mont_sqr_order_avx2_4(r, a);\n    for (i=1; i<n; i++) {\n        sp_256_mont_sqr_order_avx2_4(r, r);\n    }\n}\n#endif /* !WOLFSSL_SP_SMALL */\n\n/* Invert the number, in Montgomery form, modulo the order of the P256 curve.\n * (r = 1 / a mod order)\n *\n * r   Inverse result.\n * a   Number to invert.\n * td  Temporary data.\n */\nstatic void sp_256_mont_inv_order_avx2_4(sp_digit* r, const sp_digit* a,\n        sp_digit* td)\n{\n#ifdef WOLFSSL_SP_SMALL\n    sp_digit* t = td;\n    int i;\n\n    XMEMCPY(t, a, sizeof(sp_digit) * 4);\n    for (i=254; i>=0; i--) {\n        sp_256_mont_sqr_order_avx2_4(t, t);\n        if ((p256_order_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_avx2_4(t, t, a);\n        }\n    }\n    XMEMCPY(r, t, sizeof(sp_digit) * 4U);\n#else\n    sp_digit* t = td;\n    sp_digit* t2 = td + 2 * 4;\n    sp_digit* t3 = td + 4 * 4;\n    int i;\n\n    /* t = a^2 */\n    sp_256_mont_sqr_order_avx2_4(t, a);\n    /* t = a^3 = t * a */\n    sp_256_mont_mul_order_avx2_4(t, t, a);\n    /* t2= a^c = t ^ 2 ^ 2 */\n    sp_256_mont_sqr_n_order_avx2_4(t2, t, 2);\n    /* t3= a^f = t2 * t */\n    sp_256_mont_mul_order_avx2_4(t3, t2, t);\n    /* t2= a^f0 = t3 ^ 2 ^ 4 */\n    sp_256_mont_sqr_n_order_avx2_4(t2, t3, 4);\n    /* t = a^ff = t2 * t3 */\n    sp_256_mont_mul_order_avx2_4(t, t2, t3);\n    /* t3= a^ff00 = t ^ 2 ^ 8 */\n    sp_256_mont_sqr_n_order_avx2_4(t2, t, 8);\n    /* t = a^ffff = t2 * t */\n    sp_256_mont_mul_order_avx2_4(t, t2, t);\n    /* t2= a^ffff0000 = t ^ 2 ^ 16 */\n    sp_256_mont_sqr_n_order_avx2_4(t2, t, 16);\n    /* t = a^ffffffff = t2 * t */\n    sp_256_mont_mul_order_avx2_4(t, t2, t);\n    /* t2= a^ffffffff0000000000000000 = t ^ 2 ^ 64  */\n    sp_256_mont_sqr_n_order_avx2_4(t2, t, 64);\n    /* t2= a^ffffffff00000000ffffffff = t2 * t */\n    sp_256_mont_mul_order_avx2_4(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffff00000000 = t2 ^ 2 ^ 32  */\n    sp_256_mont_sqr_n_order_avx2_4(t2, t2, 32);\n    /* t2= a^ffffffff00000000ffffffffffffffff = t2 * t */\n    sp_256_mont_mul_order_avx2_4(t2, t2, t);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6 */\n    for (i=127; i>=112; i--) {\n        sp_256_mont_sqr_order_avx2_4(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_avx2_4(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6f */\n    sp_256_mont_sqr_n_order_avx2_4(t2, t2, 4);\n    sp_256_mont_mul_order_avx2_4(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84 */\n    for (i=107; i>=64; i--) {\n        sp_256_mont_sqr_order_avx2_4(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_avx2_4(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f */\n    sp_256_mont_sqr_n_order_avx2_4(t2, t2, 4);\n    sp_256_mont_mul_order_avx2_4(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2 */\n    for (i=59; i>=32; i--) {\n        sp_256_mont_sqr_order_avx2_4(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_avx2_4(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2f */\n    sp_256_mont_sqr_n_order_avx2_4(t2, t2, 4);\n    sp_256_mont_mul_order_avx2_4(t2, t2, t3);\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254 */\n    for (i=27; i>=0; i--) {\n        sp_256_mont_sqr_order_avx2_4(t2, t2);\n        if (((sp_digit)p256_order_low[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) {\n            sp_256_mont_mul_order_avx2_4(t2, t2, a);\n        }\n    }\n    /* t2= a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540 */\n    sp_256_mont_sqr_n_order_avx2_4(t2, t2, 4);\n    /* r = a^ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f */\n    sp_256_mont_mul_order_avx2_4(r, t2, t3);\n#endif /* WOLFSSL_SP_SMALL */\n}\n\n#endif /* HAVE_INTEL_AVX2 */\n#endif /* HAVE_ECC_SIGN || HAVE_ECC_VERIFY */\n#ifdef HAVE_ECC_SIGN\n#ifndef SP_ECC_MAX_SIG_GEN\n#define SP_ECC_MAX_SIG_GEN  64\n#endif\n\n/* Sign the hash using the private key.\n *   e = [hash, 256 bits] from binary\n *   r = (k.G)->x mod order\n *   s = (r * x + e) / k mod order\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,\n                    mp_int* rm, mp_int* sm, mp_int* km, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit ed[2*4];\n    sp_digit xd[2*4];\n    sp_digit kd[2*4];\n    sp_digit rd[2*4];\n    sp_digit td[3 * 2*4];\n    sp_point p;\n#endif\n    sp_digit* e = NULL;\n    sp_digit* x = NULL;\n    sp_digit* k = NULL;\n    sp_digit* r = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* point = NULL;\n    sp_digit carry;\n    sp_digit* s = NULL;\n    sp_digit* kInv = NULL;\n    int err = MP_OKAY;\n    int64_t c;\n    int i;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    (void)heap;\n\n    err = sp_ecc_point_new(heap, p, point);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        e = d + 0 * 4;\n        x = d + 2 * 4;\n        k = d + 4 * 4;\n        r = d + 6 * 4;\n        tmp = d + 8 * 4;\n#else\n        e = ed;\n        x = xd;\n        k = kd;\n        r = rd;\n        tmp = td;\n#endif\n        s = e;\n        kInv = k;\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(e, 4, hash, (int)hashLen);\n    }\n\n    for (i = SP_ECC_MAX_SIG_GEN; err == MP_OKAY && i > 0; i--) {\n        sp_256_from_mp(x, 4, priv);\n\n        /* New random point. */\n        if (km == NULL || mp_iszero(km)) {\n            err = sp_256_ecc_gen_k_4(rng, k);\n        }\n        else {\n            sp_256_from_mp(k, 4, km);\n            mp_zero(km);\n        }\n        if (err == MP_OKAY) {\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n                err = sp_256_ecc_mulmod_base_avx2_4(point, k, 1, heap);\n            else\n#endif\n                err = sp_256_ecc_mulmod_base_4(point, k, 1, NULL);\n        }\n\n        if (err == MP_OKAY) {\n            /* r = point->x mod order */\n            XMEMCPY(r, point->x, sizeof(sp_digit) * 4U);\n            sp_256_norm_4(r);\n            c = sp_256_cmp_4(r, p256_order);\n            sp_256_cond_sub_4(r, r, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_4(r);\n\n            /* Conv k to Montgomery form (mod order) */\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n                sp_256_mul_avx2_4(k, k, p256_norm_order);\n            else\n#endif\n                sp_256_mul_4(k, k, p256_norm_order);\n            err = sp_256_mod_4(k, k, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_4(k);\n            /* kInv = 1/k mod order */\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n                sp_256_mont_inv_order_avx2_4(kInv, k, tmp);\n            else\n#endif\n                sp_256_mont_inv_order_4(kInv, k, tmp);\n            sp_256_norm_4(kInv);\n\n            /* s = r * x + e */\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n                sp_256_mul_avx2_4(x, x, r);\n            else\n#endif\n                sp_256_mul_4(x, x, r);\n            err = sp_256_mod_4(x, x, p256_order);\n        }\n        if (err == MP_OKAY) {\n            sp_256_norm_4(x);\n            carry = sp_256_add_4(s, e, x);\n            sp_256_cond_sub_4(s, s, p256_order, 0 - carry);\n            sp_256_norm_4(s);\n            c = sp_256_cmp_4(s, p256_order);\n            sp_256_cond_sub_4(s, s, p256_order, 0L - (sp_digit)(c >= 0));\n            sp_256_norm_4(s);\n\n            /* s = s * k^-1 mod order */\n#ifdef HAVE_INTEL_AVX2\n            if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n                sp_256_mont_mul_order_avx2_4(s, s, kInv);\n            else\n#endif\n                sp_256_mont_mul_order_4(s, s, kInv);\n            sp_256_norm_4(s);\n\n            /* Check that signature is usable. */\n            if (sp_256_iszero_4(s) == 0) {\n                break;\n            }\n        }\n    }\n\n    if (i == 0) {\n        err = RNG_FAILURE_E;\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(r, rm);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(s, sm);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XMEMSET(d, 0, sizeof(sp_digit) * 8 * 4);\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#else\n    XMEMSET(e, 0, sizeof(sp_digit) * 2U * 4U);\n    XMEMSET(x, 0, sizeof(sp_digit) * 2U * 4U);\n    XMEMSET(k, 0, sizeof(sp_digit) * 2U * 4U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 4U);\n    XMEMSET(r, 0, sizeof(sp_digit) * 2U * 4U);\n    XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 4U);\n#endif\n    sp_ecc_point_free(point, 1, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_SIGN */\n\n#ifdef HAVE_ECC_VERIFY\n/* Verify the signature values with the hash and public key.\n *   e = Truncate(hash, 256)\n *   u1 = e/s mod order\n *   u2 = r/s mod order\n *   r == (u1.G + u2.Q)->x mod order\n * Optimization: Leave point in projective form.\n *   (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z')\n *   (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x'\n * The hash is truncated to the first 256 bits.\n *\n * hash     Hash to sign.\n * hashLen  Length of the hash data.\n * rng      Random number generator.\n * priv     Private part of key - scalar.\n * rm       First part of result as an mp_int.\n * sm       Sirst part of result as an mp_int.\n * heap     Heap to use for allocation.\n * returns RNG failures, MEMORY_E when memory allocation fails and\n * MP_OKAY on success.\n */\nint sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,\n    mp_int* pY, mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit u1d[2*4];\n    sp_digit u2d[2*4];\n    sp_digit sd[2*4];\n    sp_digit tmpd[2*4 * 5];\n    sp_point p1d;\n    sp_point p2d;\n#endif\n    sp_digit* u1 = NULL;\n    sp_digit* u2 = NULL;\n    sp_digit* s = NULL;\n    sp_digit* tmp = NULL;\n    sp_point* p1;\n    sp_point* p2 = NULL;\n    sp_digit carry;\n    int64_t c;\n    int err;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    err = sp_ecc_point_new(heap, p1d, p1);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, p2d, p2);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (d == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        u1  = d + 0 * 4;\n        u2  = d + 2 * 4;\n        s   = d + 4 * 4;\n        tmp = d + 6 * 4;\n#else\n        u1 = u1d;\n        u2 = u2d;\n        s  = sd;\n        tmp = tmpd;\n#endif\n\n        if (hashLen > 32U) {\n            hashLen = 32U;\n        }\n\n        sp_256_from_bin(u1, 4, hash, (int)hashLen);\n        sp_256_from_mp(u2, 4, r);\n        sp_256_from_mp(s, 4, sm);\n        sp_256_from_mp(p2->x, 4, pX);\n        sp_256_from_mp(p2->y, 4, pY);\n        sp_256_from_mp(p2->z, 4, pZ);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n            sp_256_mul_avx2_4(s, s, p256_norm_order);\n        }\n        else\n#endif\n        {\n            sp_256_mul_4(s, s, p256_norm_order);\n        }\n        err = sp_256_mod_4(s, s, p256_order);\n    }\n    if (err == MP_OKAY) {\n        sp_256_norm_4(s);\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n            sp_256_mont_inv_order_avx2_4(s, s, tmp);\n            sp_256_mont_mul_order_avx2_4(u1, u1, s);\n            sp_256_mont_mul_order_avx2_4(u2, u2, s);\n        }\n        else\n#endif\n        {\n            sp_256_mont_inv_order_4(s, s, tmp);\n            sp_256_mont_mul_order_4(u1, u1, s);\n            sp_256_mont_mul_order_4(u2, u2, s);\n        }\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_256_ecc_mulmod_base_avx2_4(p1, u1, 0, heap);\n        else\n#endif\n            err = sp_256_ecc_mulmod_base_4(p1, u1, 0, heap);\n    }\n    if (err == MP_OKAY) {\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_256_ecc_mulmod_avx2_4(p2, p2, u2, 0, heap);\n        else\n#endif\n            err = sp_256_ecc_mulmod_4(p2, p2, u2, 0, heap);\n    }\n\n    if (err == MP_OKAY) {\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n            sp_256_proj_point_add_avx2_4(p1, p1, p2, tmp);\n            if (sp_256_iszero_4(p1->z)) {\n                if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) {\n                    sp_256_proj_point_dbl_avx2_4(p1, p2, tmp);\n                }\n                else {\n                    /* Y ordinate is not used from here - don't set. */\n                    p1->x[0] = 0;\n                    p1->x[1] = 0;\n                    p1->x[2] = 0;\n                    p1->x[3] = 0;\n                    XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));\n                }\n            }\n        }\n        else\n#endif\n        {\n            sp_256_proj_point_add_4(p1, p1, p2, tmp);\n            if (sp_256_iszero_4(p1->z)) {\n                if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) {\n                    sp_256_proj_point_dbl_4(p1, p2, tmp);\n                }\n                else {\n                    /* Y ordinate is not used from here - don't set. */\n                    p1->x[0] = 0;\n                    p1->x[1] = 0;\n                    p1->x[2] = 0;\n                    p1->x[3] = 0;\n                    XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));\n                }\n            }\n        }\n\n        /* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */\n        /* Reload r and convert to Montgomery form. */\n        sp_256_from_mp(u2, 4, r);\n        err = sp_256_mod_mul_norm_4(u2, u2, p256_mod);\n    }\n\n    if (err == MP_OKAY) {\n        /* u1 = r.z'.z' mod prime */\n        sp_256_mont_sqr_4(p1->z, p1->z, p256_mod, p256_mp_mod);\n        sp_256_mont_mul_4(u1, u2, p1->z, p256_mod, p256_mp_mod);\n        *res = (int)(sp_256_cmp_4(p1->x, u1) == 0);\n        if (*res == 0) {\n            /* Reload r and add order. */\n            sp_256_from_mp(u2, 4, r);\n            carry = sp_256_add_4(u2, u2, p256_order);\n            /* Carry means result is greater than mod and is not valid. */\n            if (carry == 0) {\n                sp_256_norm_4(u2);\n\n                /* Compare with mod and if greater or equal then not valid. */\n                c = sp_256_cmp_4(u2, p256_mod);\n                if (c < 0) {\n                    /* Convert to Montogomery form */\n                    err = sp_256_mod_mul_norm_4(u2, u2, p256_mod);\n                    if (err == MP_OKAY) {\n                        /* u1 = (r + 1*order).z'.z' mod prime */\n                        sp_256_mont_mul_4(u1, u2, p1->z, p256_mod,\n                                                                  p256_mp_mod);\n                        *res = (int)(sp_256_cmp_4(p1->x, u1) == 0);\n                    }\n                }\n            }\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL)\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n#endif\n    sp_ecc_point_free(p1, 0, heap);\n    sp_ecc_point_free(p2, 0, heap);\n\n    return err;\n}\n#endif /* HAVE_ECC_VERIFY */\n\n#ifdef HAVE_ECC_CHECK_KEY\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * point  EC point.\n * heap   Heap to use if dynamically allocating.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nstatic int sp_256_ecc_is_point_4(sp_point* point, void* heap)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d = NULL;\n#else\n    sp_digit t1d[2*4];\n    sp_digit t2d[2*4];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 4, heap, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 4;\n        t2 = d + 2 * 4;\n#else\n        (void)heap;\n\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n        sp_256_sqr_4(t1, point->y);\n        (void)sp_256_mod_4(t1, t1, p256_mod);\n        sp_256_sqr_4(t2, point->x);\n        (void)sp_256_mod_4(t2, t2, p256_mod);\n        sp_256_mul_4(t2, t2, point->x);\n        (void)sp_256_mod_4(t2, t2, p256_mod);\n        (void)sp_256_sub_4(t2, p256_mod, t2);\n        sp_256_mont_add_4(t1, t1, t2, p256_mod);\n\n        sp_256_mont_add_4(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_4(t1, t1, point->x, p256_mod);\n        sp_256_mont_add_4(t1, t1, point->x, p256_mod);\n\n        if (sp_256_cmp_4(t1, p256_b) != 0) {\n            err = MP_VAL;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Check that the x and y oridinates are a valid point on the curve.\n *\n * pX  X ordinate of EC point.\n * pY  Y ordinate of EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve and MP_OKAY otherwise.\n */\nint sp_ecc_is_point_256(mp_int* pX, mp_int* pY)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_point pubd;\n#endif\n    sp_point* pub;\n    byte one[1] = { 1 };\n    int err;\n\n    err = sp_ecc_point_new(NULL, pubd, pub);\n    if (err == MP_OKAY) {\n        sp_256_from_mp(pub->x, 4, pX);\n        sp_256_from_mp(pub->y, 4, pY);\n        sp_256_from_bin(pub->z, 4, one, (int)sizeof(one));\n\n        err = sp_256_ecc_is_point_4(pub, NULL);\n    }\n\n    sp_ecc_point_free(pub, 0, NULL);\n\n    return err;\n}\n\n/* Check that the private scalar generates the EC point (px, py), the point is\n * on the curve and the point has the correct order.\n *\n * pX     X ordinate of EC point.\n * pY     Y ordinate of EC point.\n * privm  Private scalar that generates EC point.\n * returns MEMORY_E if dynamic memory allocation fails, MP_VAL if the point is\n * not on the curve, ECC_INF_E if the point does not have the correct order,\n * ECC_PRIV_KEY_E when the private scalar doesn't generate the EC point and\n * MP_OKAY otherwise.\n */\nint sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit privd[4];\n    sp_point pubd;\n    sp_point pd;\n#endif\n    sp_digit* priv = NULL;\n    sp_point* pub;\n    sp_point* p = NULL;\n    byte one[1] = { 1 };\n    int err;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    err = sp_ecc_point_new(heap, pubd, pub);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(heap, pd, p);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (priv == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK))\n        priv = privd;\n#endif\n\n        sp_256_from_mp(pub->x, 4, pX);\n        sp_256_from_mp(pub->y, 4, pY);\n        sp_256_from_bin(pub->z, 4, one, (int)sizeof(one));\n        sp_256_from_mp(priv, 4, privm);\n\n        /* Check point at infinitiy. */\n        if ((sp_256_iszero_4(pub->x) != 0) &&\n            (sp_256_iszero_4(pub->y) != 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check range of X and Y */\n        if (sp_256_cmp_4(pub->x, p256_mod) >= 0 ||\n            sp_256_cmp_4(pub->y, p256_mod) >= 0) {\n            err = ECC_OUT_OF_RANGE_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Check point is on curve */\n        err = sp_256_ecc_is_point_4(pub, heap);\n    }\n\n    if (err == MP_OKAY) {\n        /* Point * order = infinity */\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_256_ecc_mulmod_avx2_4(p, pub, p256_order, 1, heap);\n        else\n#endif\n            err = sp_256_ecc_mulmod_4(p, pub, p256_order, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is infinity */\n        if ((sp_256_iszero_4(p->x) == 0) ||\n            (sp_256_iszero_4(p->y) == 0)) {\n            err = ECC_INF_E;\n        }\n    }\n\n    if (err == MP_OKAY) {\n        /* Base * private = point */\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            err = sp_256_ecc_mulmod_base_avx2_4(p, priv, 1, heap);\n        else\n#endif\n            err = sp_256_ecc_mulmod_base_4(p, priv, 1, heap);\n    }\n    if (err == MP_OKAY) {\n        /* Check result is public key */\n        if (sp_256_cmp_4(p->x, pub->x) != 0 ||\n            sp_256_cmp_4(p->y, pub->y) != 0) {\n            err = ECC_PRIV_KEY_E;\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (priv != NULL) {\n        XFREE(priv, heap, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, heap);\n    sp_ecc_point_free(pub, 0, heap);\n\n    return err;\n}\n#endif\n#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL\n/* Add two projective EC points together.\n * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ)\n *\n * pX   First EC point's X ordinate.\n * pY   First EC point's Y ordinate.\n * pZ   First EC point's Z ordinate.\n * qX   Second EC point's X ordinate.\n * qY   Second EC point's Y ordinate.\n * qZ   Second EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* qX, mp_int* qY, mp_int* qZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 4 * 5];\n    sp_point pd;\n    sp_point qd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    sp_point* q = NULL;\n    int err;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    err = sp_ecc_point_new(NULL, pd, p);\n    if (err == MP_OKAY) {\n        err = sp_ecc_point_new(NULL, qd, q);\n    }\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 4, pX);\n        sp_256_from_mp(p->y, 4, pY);\n        sp_256_from_mp(p->z, 4, pZ);\n        sp_256_from_mp(q->x, 4, qX);\n        sp_256_from_mp(q->y, 4, qY);\n        sp_256_from_mp(q->z, 4, qZ);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            sp_256_proj_point_add_avx2_4(p, p, q, tmp);\n        else\n#endif\n            sp_256_proj_point_add_4(p, p, q, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(q, 0, NULL);\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Double a projective EC point.\n * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ)\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * rX   Resultant EC point's X ordinate.\n * rY   Resultant EC point's Y ordinate.\n * rZ   Resultant EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 4 * 2];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 2, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 4, pX);\n        sp_256_from_mp(p->y, 4, pY);\n        sp_256_from_mp(p->z, 4, pZ);\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))\n            sp_256_proj_point_dbl_avx2_4(p, p, tmp);\n        else\n#endif\n            sp_256_proj_point_dbl_4(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, rX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, rY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, rZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n\n/* Map a projective EC point to affine in place.\n * pZ will be one.\n *\n * pX   EC point's X ordinate.\n * pY   EC point's Y ordinate.\n * pZ   EC point's Z ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ)\n{\n#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK)\n    sp_digit tmpd[2 * 4 * 4];\n    sp_point pd;\n#endif\n    sp_digit* tmp;\n    sp_point* p;\n    int err;\n\n    err = sp_ecc_point_new(NULL, pd, p);\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (err == MP_OKAY) {\n        tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 4, NULL,\n                                                              DYNAMIC_TYPE_ECC);\n        if (tmp == NULL) {\n            err = MEMORY_E;\n        }\n    }\n#else\n    tmp = tmpd;\n#endif\n    if (err == MP_OKAY) {\n        sp_256_from_mp(p->x, 4, pX);\n        sp_256_from_mp(p->y, 4, pY);\n        sp_256_from_mp(p->z, 4, pZ);\n\n        sp_256_map_4(p, p, tmp);\n    }\n\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->x, pX);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->y, pY);\n    }\n    if (err == MP_OKAY) {\n        err = sp_256_to_mp(p->z, pZ);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (tmp != NULL) {\n        XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n    sp_ecc_point_free(p, 0, NULL);\n\n    return err;\n}\n#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */\n#ifdef HAVE_COMP_KEY\n/* Find the square root of a number mod the prime of the curve.\n *\n * y  The number to operate on and the result.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nstatic int sp_256_mont_sqrt_4(sp_digit* y)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit t1d[2 * 4];\n    sp_digit t2d[2 * 4];\n#endif\n    sp_digit* t1;\n    sp_digit* t2;\n    int err = MP_OKAY;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 4, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        t1 = d + 0 * 4;\n        t2 = d + 2 * 4;\n#else\n        t1 = t1d;\n        t2 = t2d;\n#endif\n\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n            /* t2 = y ^ 0x2 */\n            sp_256_mont_sqr_avx2_4(t2, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0x3 */\n            sp_256_mont_mul_avx2_4(t1, t2, y, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xc */\n            sp_256_mont_sqr_n_avx2_4(t2, t1, 2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xf */\n            sp_256_mont_mul_avx2_4(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xf0 */\n            sp_256_mont_sqr_n_avx2_4(t2, t1, 4, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xff */\n            sp_256_mont_mul_avx2_4(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xff00 */\n            sp_256_mont_sqr_n_avx2_4(t2, t1, 8, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffff */\n            sp_256_mont_mul_avx2_4(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xffff0000 */\n            sp_256_mont_sqr_n_avx2_4(t2, t1, 16, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff */\n            sp_256_mont_mul_avx2_4(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000000 */\n            sp_256_mont_sqr_n_avx2_4(t1, t1, 32, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001 */\n            sp_256_mont_mul_avx2_4(t1, t1, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */\n            sp_256_mont_sqr_n_avx2_4(t1, t1, 96, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */\n            sp_256_mont_mul_avx2_4(t1, t1, y, p256_mod, p256_mp_mod);\n            sp_256_mont_sqr_n_avx2_4(y, t1, 94, p256_mod, p256_mp_mod);\n        }\n        else\n#endif\n        {\n            /* t2 = y ^ 0x2 */\n            sp_256_mont_sqr_4(t2, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0x3 */\n            sp_256_mont_mul_4(t1, t2, y, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xc */\n            sp_256_mont_sqr_n_4(t2, t1, 2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xf */\n            sp_256_mont_mul_4(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xf0 */\n            sp_256_mont_sqr_n_4(t2, t1, 4, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xff */\n            sp_256_mont_mul_4(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xff00 */\n            sp_256_mont_sqr_n_4(t2, t1, 8, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffff */\n            sp_256_mont_mul_4(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t2 = y ^ 0xffff0000 */\n            sp_256_mont_sqr_n_4(t2, t1, 16, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff */\n            sp_256_mont_mul_4(t1, t1, t2, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000000 */\n            sp_256_mont_sqr_n_4(t1, t1, 32, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001 */\n            sp_256_mont_mul_4(t1, t1, y, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000000 */\n            sp_256_mont_sqr_n_4(t1, t1, 96, p256_mod, p256_mp_mod);\n            /* t1 = y ^ 0xffffffff00000001000000000000000000000001 */\n            sp_256_mont_mul_4(t1, t1, y, p256_mod, p256_mp_mod);\n            sp_256_mont_sqr_n_4(y, t1, 94, p256_mod, p256_mp_mod);\n        }\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n\n/* Uncompress the point given the X ordinate.\n *\n * xm    X ordinate.\n * odd   Whether the Y ordinate is odd.\n * ym    Calculated Y ordinate.\n * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise.\n */\nint sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym)\n{\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    sp_digit* d;\n#else\n    sp_digit xd[2 * 4];\n    sp_digit yd[2 * 4];\n#endif\n    sp_digit* x = NULL;\n    sp_digit* y = NULL;\n    int err = MP_OKAY;\n#ifdef HAVE_INTEL_AVX2\n    word32 cpuid_flags = cpuid_get_flags();\n#endif\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 4, NULL, DYNAMIC_TYPE_ECC);\n    if (d == NULL) {\n        err = MEMORY_E;\n    }\n#endif\n\n    if (err == MP_OKAY) {\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n        x = d + 0 * 4;\n        y = d + 2 * 4;\n#else\n        x = xd;\n        y = yd;\n#endif\n\n        sp_256_from_mp(x, 4, xm);\n        err = sp_256_mod_mul_norm_4(x, x, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        /* y = x^3 */\n#ifdef HAVE_INTEL_AVX2\n        if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {\n            sp_256_mont_sqr_avx2_4(y, x, p256_mod, p256_mp_mod);\n            sp_256_mont_mul_avx2_4(y, y, x, p256_mod, p256_mp_mod);\n        }\n        else\n#endif\n        {\n            sp_256_mont_sqr_4(y, x, p256_mod, p256_mp_mod);\n            sp_256_mont_mul_4(y, y, x, p256_mod, p256_mp_mod);\n        }\n        /* y = x^3 - 3x */\n        sp_256_mont_sub_4(y, y, x, p256_mod);\n        sp_256_mont_sub_4(y, y, x, p256_mod);\n        sp_256_mont_sub_4(y, y, x, p256_mod);\n        /* y = x^3 - 3x + b */\n        err = sp_256_mod_mul_norm_4(x, p256_b, p256_mod);\n    }\n    if (err == MP_OKAY) {\n        sp_256_mont_add_4(y, y, x, p256_mod);\n        /* y = sqrt(x^3 - 3x + b) */\n        err = sp_256_mont_sqrt_4(y);\n    }\n    if (err == MP_OKAY) {\n        XMEMSET(y + 4, 0, 4U * sizeof(sp_digit));\n        sp_256_mont_reduce_4(y, p256_mod, p256_mp_mod);\n        if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) {\n            sp_256_mont_sub_4(y, p256_mod, y, p256_mod);\n        }\n\n        err = sp_256_to_mp(y, ym);\n    }\n\n#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)\n    if (d != NULL) {\n        XFREE(d, NULL, DYNAMIC_TYPE_ECC);\n    }\n#endif\n\n    return err;\n}\n#endif\n#endif /* !WOLFSSL_SP_NO_256 */\n#endif /* WOLFSSL_HAVE_SP_ECC */\n#endif /* WOLFSSL_SP_X86_64_ASM */\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */\n"
  },
  {
    "path": "src/wolfcrypt/src/srp.c",
    "content": "/* srp.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef WOLFCRYPT_HAVE_SRP\n\n#include <wolfssl/wolfcrypt/srp.h>\n#include <wolfssl/wolfcrypt/random.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n/** Computes the session key using the Mask Generation Function 1. */\nstatic int wc_SrpSetKey(Srp* srp, byte* secret, word32 size);\n\nstatic int SrpHashInit(SrpHash* hash, SrpType type)\n{\n    hash->type = type;\n\n    switch (type) {\n        case SRP_TYPE_SHA:\n            #ifndef NO_SHA\n                return wc_InitSha(&hash->data.sha);\n            #else\n                return BAD_FUNC_ARG;\n            #endif\n\n        case SRP_TYPE_SHA256:\n            #ifndef NO_SHA256\n                return wc_InitSha256(&hash->data.sha256);\n            #else\n                return BAD_FUNC_ARG;\n            #endif\n\n        case SRP_TYPE_SHA384:\n            #ifdef WOLFSSL_SHA384\n                return wc_InitSha384(&hash->data.sha384);\n            #else\n                return BAD_FUNC_ARG;\n            #endif\n\n        case SRP_TYPE_SHA512:\n            #ifdef WOLFSSL_SHA512\n                return wc_InitSha512(&hash->data.sha512);\n            #else\n                return BAD_FUNC_ARG;\n            #endif\n\n        default:\n            return BAD_FUNC_ARG;\n    }\n}\n\nstatic int SrpHashUpdate(SrpHash* hash, const byte* data, word32 size)\n{\n    switch (hash->type) {\n        case SRP_TYPE_SHA:\n            #ifndef NO_SHA\n                return wc_ShaUpdate(&hash->data.sha, data, size);\n            #else\n                return BAD_FUNC_ARG;\n            #endif\n\n        case SRP_TYPE_SHA256:\n            #ifndef NO_SHA256\n                return wc_Sha256Update(&hash->data.sha256, data, size);\n            #else\n                return BAD_FUNC_ARG;\n            #endif\n\n        case SRP_TYPE_SHA384:\n            #ifdef WOLFSSL_SHA384\n                return wc_Sha384Update(&hash->data.sha384, data, size);\n            #else\n                return BAD_FUNC_ARG;\n            #endif\n\n        case SRP_TYPE_SHA512:\n            #ifdef WOLFSSL_SHA512\n                return wc_Sha512Update(&hash->data.sha512, data, size);\n            #else\n                return BAD_FUNC_ARG;\n            #endif\n\n        default:\n            return BAD_FUNC_ARG;\n    }\n}\n\nstatic int SrpHashFinal(SrpHash* hash, byte* digest)\n{\n    switch (hash->type) {\n        case SRP_TYPE_SHA:\n            #ifndef NO_SHA\n                return wc_ShaFinal(&hash->data.sha, digest);\n            #else\n                return BAD_FUNC_ARG;\n            #endif\n\n        case SRP_TYPE_SHA256:\n            #ifndef NO_SHA256\n                return wc_Sha256Final(&hash->data.sha256, digest);\n            #else\n                return BAD_FUNC_ARG;\n            #endif\n\n        case SRP_TYPE_SHA384:\n            #ifdef WOLFSSL_SHA384\n                return wc_Sha384Final(&hash->data.sha384, digest);\n            #else\n                return BAD_FUNC_ARG;\n            #endif\n\n        case SRP_TYPE_SHA512:\n            #ifdef WOLFSSL_SHA512\n                return wc_Sha512Final(&hash->data.sha512, digest);\n            #else\n                return BAD_FUNC_ARG;\n            #endif\n\n        default:\n            return BAD_FUNC_ARG;\n    }\n}\n\nstatic word32 SrpHashSize(SrpType type)\n{\n    switch (type) {\n        case SRP_TYPE_SHA:\n            #ifndef NO_SHA\n                return WC_SHA_DIGEST_SIZE;\n            #else\n                return 0;\n            #endif\n\n        case SRP_TYPE_SHA256:\n            #ifndef NO_SHA256\n                return WC_SHA256_DIGEST_SIZE;\n            #else\n                return 0;\n            #endif\n\n        case SRP_TYPE_SHA384:\n            #ifdef WOLFSSL_SHA384\n                return WC_SHA384_DIGEST_SIZE;\n            #else\n                return 0;\n            #endif\n\n        case SRP_TYPE_SHA512:\n            #ifdef WOLFSSL_SHA512\n                return WC_SHA512_DIGEST_SIZE;\n            #else\n                return 0;\n            #endif\n\n        default:\n            return 0;\n    }\n}\n\nint wc_SrpInit(Srp* srp, SrpType type, SrpSide side)\n{\n    int r;\n\n    /* validating params */\n\n    if (!srp)\n        return BAD_FUNC_ARG;\n\n    if (side != SRP_CLIENT_SIDE && side != SRP_SERVER_SIDE)\n        return BAD_FUNC_ARG;\n\n    switch (type) {\n        case SRP_TYPE_SHA:\n            #ifdef NO_SHA\n                return NOT_COMPILED_IN;\n            #else\n                break; /* OK */\n            #endif\n\n        case SRP_TYPE_SHA256:\n            #ifdef NO_SHA256\n                return NOT_COMPILED_IN;\n            #else\n                break; /* OK */\n            #endif\n\n        case SRP_TYPE_SHA384:\n            #ifndef WOLFSSL_SHA384\n                return NOT_COMPILED_IN;\n            #else\n                break; /* OK */\n            #endif\n\n        case SRP_TYPE_SHA512:\n            #ifndef WOLFSSL_SHA512\n                return NOT_COMPILED_IN;\n            #else\n                break; /* OK */\n            #endif\n\n        default:\n            return BAD_FUNC_ARG;\n    }\n\n    /* initializing variables */\n\n    XMEMSET(srp, 0, sizeof(Srp));\n\n    if ((r = SrpHashInit(&srp->client_proof, type)) != 0)\n        return r;\n\n    if ((r = SrpHashInit(&srp->server_proof, type)) != 0)\n        return r;\n\n    if ((r = mp_init_multi(&srp->N,    &srp->g, &srp->auth,\n                           &srp->priv, 0, 0)) != 0)\n        return r;\n\n    srp->side = side;    srp->type   = type;\n    srp->salt = NULL;    srp->saltSz = 0;\n    srp->user = NULL;    srp->userSz = 0;\n    srp->key  = NULL;    srp->keySz  = 0;\n\n    srp->keyGenFunc_cb = wc_SrpSetKey;\n\n    /* default heap hint to NULL or test value */\n#ifdef WOLFSSL_HEAP_TEST\n    srp->heap = (void*)WOLFSSL_HEAP_TEST;\n#else\n    srp->heap = NULL;\n#endif\n\n    return 0;\n}\n\nvoid wc_SrpTerm(Srp* srp)\n{\n    if (srp) {\n        mp_clear(&srp->N);    mp_clear(&srp->g);\n        mp_clear(&srp->auth); mp_clear(&srp->priv);\n        if (srp->salt) {\n            ForceZero(srp->salt, srp->saltSz);\n            XFREE(srp->salt, srp->heap, DYNAMIC_TYPE_SRP);\n        }\n        if (srp->user) {\n            ForceZero(srp->user, srp->userSz);\n            XFREE(srp->user, srp->heap, DYNAMIC_TYPE_SRP);\n        }\n        if (srp->key) {\n            ForceZero(srp->key, srp->keySz);\n            XFREE(srp->key, srp->heap, DYNAMIC_TYPE_SRP);\n        }\n\n        ForceZero(srp, sizeof(Srp));\n    }\n}\n\nint wc_SrpSetUsername(Srp* srp, const byte* username, word32 size)\n{\n    if (!srp || !username)\n        return BAD_FUNC_ARG;\n\n    srp->user = (byte*)XMALLOC(size, srp->heap, DYNAMIC_TYPE_SRP);\n    if (srp->user == NULL)\n        return MEMORY_E;\n\n    srp->userSz = size;\n    XMEMCPY(srp->user, username, srp->userSz);\n\n    return 0;\n}\n\nint wc_SrpSetParams(Srp* srp, const byte* N,    word32 nSz,\n                              const byte* g,    word32 gSz,\n                              const byte* salt, word32 saltSz)\n{\n    SrpHash hash;\n    byte digest1[SRP_MAX_DIGEST_SIZE];\n    byte digest2[SRP_MAX_DIGEST_SIZE];\n    byte pad = 0;\n    int i, r;\n    int j = 0;\n\n    if (!srp || !N || !g || !salt || nSz < gSz)\n        return BAD_FUNC_ARG;\n\n    if (!srp->user)\n        return SRP_CALL_ORDER_E;\n\n    /* Set N */\n    if (mp_read_unsigned_bin(&srp->N, N, nSz) != MP_OKAY)\n        return MP_READ_E;\n\n    if (mp_count_bits(&srp->N) < SRP_MODULUS_MIN_BITS)\n        return BAD_FUNC_ARG;\n\n    /* Set g */\n    if (mp_read_unsigned_bin(&srp->g, g, gSz) != MP_OKAY)\n        return MP_READ_E;\n\n    if (mp_cmp(&srp->N, &srp->g) != MP_GT)\n        return BAD_FUNC_ARG;\n\n    /* Set salt */\n    if (srp->salt) {\n        ForceZero(srp->salt, srp->saltSz);\n        XFREE(srp->salt, srp->heap, DYNAMIC_TYPE_SRP);\n    }\n\n    srp->salt = (byte*)XMALLOC(saltSz, srp->heap, DYNAMIC_TYPE_SRP);\n    if (srp->salt == NULL)\n        return MEMORY_E;\n\n    XMEMCPY(srp->salt, salt, saltSz);\n    srp->saltSz = saltSz;\n\n    /* Set k = H(N, g) */\n            r = SrpHashInit(&hash, srp->type);\n    if (!r) r = SrpHashUpdate(&hash, (byte*) N, nSz);\n    for (i = 0; (word32)i < nSz - gSz; i++) {\n        if (!r) r = SrpHashUpdate(&hash, &pad, 1);\n    }\n    if (!r) r = SrpHashUpdate(&hash, (byte*) g, gSz);\n    if (!r) r = SrpHashFinal(&hash, srp->k);\n\n    /* update client proof */\n\n    /* digest1 = H(N) */\n    if (!r) r = SrpHashInit(&hash, srp->type);\n    if (!r) r = SrpHashUpdate(&hash, (byte*) N, nSz);\n    if (!r) r = SrpHashFinal(&hash, digest1);\n\n    /* digest2 = H(g) */\n    if (!r) r = SrpHashInit(&hash, srp->type);\n    if (!r) r = SrpHashUpdate(&hash, (byte*) g, gSz);\n    if (!r) r = SrpHashFinal(&hash, digest2);\n\n    /* digest1 = H(N) ^ H(g) */\n    if (r == 0) {\n        for (i = 0, j = SrpHashSize(srp->type); i < j; i++)\n            digest1[i] ^= digest2[i];\n    }\n\n    /* digest2 = H(user) */\n    if (!r) r = SrpHashInit(&hash, srp->type);\n    if (!r) r = SrpHashUpdate(&hash, srp->user, srp->userSz);\n    if (!r) r = SrpHashFinal(&hash, digest2);\n\n    /* client proof = H( H(N) ^ H(g) | H(user) | salt) */\n    if (!r) r = SrpHashUpdate(&srp->client_proof, digest1, j);\n    if (!r) r = SrpHashUpdate(&srp->client_proof, digest2, j);\n    if (!r) r = SrpHashUpdate(&srp->client_proof, salt, saltSz);\n\n    return r;\n}\n\nint wc_SrpSetPassword(Srp* srp, const byte* password, word32 size)\n{\n    SrpHash hash;\n    byte digest[SRP_MAX_DIGEST_SIZE];\n    word32 digestSz;\n    int r;\n\n    if (!srp || !password || srp->side != SRP_CLIENT_SIDE)\n        return BAD_FUNC_ARG;\n\n    if (!srp->salt)\n        return SRP_CALL_ORDER_E;\n\n    digestSz = SrpHashSize(srp->type);\n\n    /* digest = H(username | ':' | password) */\n            r = SrpHashInit(&hash, srp->type);\n    if (!r) r = SrpHashUpdate(&hash, srp->user, srp->userSz);\n    if (!r) r = SrpHashUpdate(&hash, (const byte*) \":\", 1);\n    if (!r) r = SrpHashUpdate(&hash, password, size);\n    if (!r) r = SrpHashFinal(&hash, digest);\n\n    /* digest = H(salt | H(username | ':' | password)) */\n    if (!r) r = SrpHashInit(&hash, srp->type);\n    if (!r) r = SrpHashUpdate(&hash, srp->salt, srp->saltSz);\n    if (!r) r = SrpHashUpdate(&hash, digest, digestSz);\n    if (!r) r = SrpHashFinal(&hash, digest);\n\n    /* Set x (private key) */\n    if (!r) r = mp_read_unsigned_bin(&srp->auth, digest, digestSz);\n\n    ForceZero(digest, SRP_MAX_DIGEST_SIZE);\n\n    return r;\n}\n\nint wc_SrpGetVerifier(Srp* srp, byte* verifier, word32* size)\n{\n    mp_int v;\n    int r;\n\n    if (!srp || !verifier || !size || srp->side != SRP_CLIENT_SIDE)\n        return BAD_FUNC_ARG;\n\n    if (mp_iszero(&srp->auth) == MP_YES)\n        return SRP_CALL_ORDER_E;\n\n    r = mp_init(&v);\n    if (r != MP_OKAY)\n        return MP_INIT_E;\n\n    /* v = g ^ x % N */\n    if (!r) r = mp_exptmod(&srp->g, &srp->auth, &srp->N, &v);\n    if (!r) r = *size < (word32)mp_unsigned_bin_size(&v) ? BUFFER_E : MP_OKAY;\n    if (!r) r = mp_to_unsigned_bin(&v, verifier);\n    if (!r) *size = mp_unsigned_bin_size(&v);\n\n    mp_clear(&v);\n\n    return r;\n}\n\nint wc_SrpSetVerifier(Srp* srp, const byte* verifier, word32 size)\n{\n    if (!srp || !verifier || srp->side != SRP_SERVER_SIDE)\n        return BAD_FUNC_ARG;\n\n    return mp_read_unsigned_bin(&srp->auth, verifier, size);\n}\n\nint wc_SrpSetPrivate(Srp* srp, const byte* priv, word32 size)\n{\n    mp_int p;\n    int r;\n\n    if (!srp || !priv || !size)\n        return BAD_FUNC_ARG;\n\n    if (mp_iszero(&srp->auth) == MP_YES)\n        return SRP_CALL_ORDER_E;\n\n    r = mp_init(&p);\n    if (r != MP_OKAY)\n        return MP_INIT_E;\n    if (!r) r = mp_read_unsigned_bin(&p, priv, size);\n    if (!r) r = mp_mod(&p, &srp->N, &srp->priv);\n    if (!r) r = mp_iszero(&srp->priv) == MP_YES ? SRP_BAD_KEY_E : 0;\n\n    mp_clear(&p);\n\n    return r;\n}\n\n/** Generates random data using wolfcrypt RNG. */\nstatic int wc_SrpGenPrivate(Srp* srp, byte* priv, word32 size)\n{\n    WC_RNG rng;\n    int r = wc_InitRng(&rng);\n\n    if (!r) r = wc_RNG_GenerateBlock(&rng, priv, size);\n    if (!r) r = wc_SrpSetPrivate(srp, priv, size);\n    if (!r) wc_FreeRng(&rng);\n\n    return r;\n}\n\nint wc_SrpGetPublic(Srp* srp, byte* pub, word32* size)\n{\n    mp_int pubkey;\n    word32 modulusSz;\n    int r;\n\n    if (!srp || !pub || !size)\n        return BAD_FUNC_ARG;\n\n    if (mp_iszero(&srp->auth) == MP_YES)\n        return SRP_CALL_ORDER_E;\n\n    modulusSz = mp_unsigned_bin_size(&srp->N);\n    if (*size < modulusSz)\n        return BUFFER_E;\n\n    r = mp_init(&pubkey);\n    if (r != MP_OKAY)\n        return MP_INIT_E;\n\n    /* priv = random() */\n    if (mp_iszero(&srp->priv) == MP_YES)\n        r = wc_SrpGenPrivate(srp, pub, SRP_PRIVATE_KEY_MIN_BITS / 8);\n\n    /* client side: A = g ^ a % N */\n    if (srp->side == SRP_CLIENT_SIDE) {\n        if (!r) r = mp_exptmod(&srp->g, &srp->priv, &srp->N, &pubkey);\n\n    /* server side: B = (k * v + (g ^ b % N)) % N */\n    } else {\n        mp_int i, j;\n\n        if (mp_init_multi(&i, &j, 0, 0, 0, 0) == MP_OKAY) {\n            if (!r) r = mp_read_unsigned_bin(&i, srp->k,SrpHashSize(srp->type));\n            if (!r) r = mp_iszero(&i) == MP_YES ? SRP_BAD_KEY_E : 0;\n            if (!r) r = mp_exptmod(&srp->g, &srp->priv, &srp->N, &pubkey);\n            if (!r) r = mp_mulmod(&i, &srp->auth, &srp->N, &j);\n            if (!r) r = mp_add(&j, &pubkey, &i);\n            if (!r) r = mp_mod(&i, &srp->N, &pubkey);\n\n            mp_clear(&i); mp_clear(&j);\n        }\n    }\n\n    /* extract public key to buffer */\n    XMEMSET(pub, 0, modulusSz);\n    if (!r) r = mp_to_unsigned_bin(&pubkey, pub);\n    if (!r) *size = mp_unsigned_bin_size(&pubkey);\n    mp_clear(&pubkey);\n\n    return r;\n}\n\nstatic int wc_SrpSetKey(Srp* srp, byte* secret, word32 size)\n{\n    SrpHash hash;\n    byte digest[SRP_MAX_DIGEST_SIZE];\n    word32 i, j, digestSz = SrpHashSize(srp->type);\n    byte counter[4];\n    int r = BAD_FUNC_ARG;\n\n    XMEMSET(digest, 0, SRP_MAX_DIGEST_SIZE);\n\n    srp->key = (byte*)XMALLOC(2 * digestSz, srp->heap, DYNAMIC_TYPE_SRP);\n    if (srp->key == NULL)\n        return MEMORY_E;\n\n    srp->keySz = 2 * digestSz;\n\n    for (i = j = 0; j < srp->keySz; i++) {\n        counter[0] = (i >> 24) & 0xFF;\n        counter[1] = (i >> 16) & 0xFF;\n        counter[2] = (i >>  8) & 0xFF;\n        counter[3] =  i        & 0xFF;\n\n        r = SrpHashInit(&hash, srp->type);\n        if (!r) r = SrpHashUpdate(&hash, secret, size);\n        if (!r) r = SrpHashUpdate(&hash, counter, 4);\n\n        if (j + digestSz > srp->keySz) {\n            if (!r) r = SrpHashFinal(&hash, digest);\n            XMEMCPY(srp->key + j, digest, srp->keySz - j);\n            j = srp->keySz;\n        }\n        else {\n            if (!r) r = SrpHashFinal(&hash, srp->key + j);\n            j += digestSz;\n        }\n    }\n\n    ForceZero(digest, sizeof(digest));\n    ForceZero(&hash, sizeof(SrpHash));\n\n    return r;\n}\n\nint wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz,\n                               byte* serverPubKey, word32 serverPubKeySz)\n{\n    SrpHash hash;\n    byte *secret;\n    byte digest[SRP_MAX_DIGEST_SIZE];\n    word32 i, secretSz, digestSz;\n    mp_int u, s, temp1, temp2;\n    byte pad = 0;\n    int r;\n\n    /* validating params */\n\n    if (!srp || !clientPubKey || clientPubKeySz == 0\n             || !serverPubKey || serverPubKeySz == 0)\n        return BAD_FUNC_ARG;\n\n    if (mp_iszero(&srp->priv) == MP_YES)\n        return SRP_CALL_ORDER_E;\n\n    /* initializing variables */\n\n    if ((r = SrpHashInit(&hash, srp->type)) != 0)\n        return r;\n\n    digestSz = SrpHashSize(srp->type);\n    secretSz = mp_unsigned_bin_size(&srp->N);\n\n    if ((secret = (byte*)XMALLOC(secretSz, srp->heap, DYNAMIC_TYPE_SRP)) ==NULL)\n        return MEMORY_E;\n\n    if ((r = mp_init_multi(&u, &s, &temp1, &temp2, 0, 0)) != MP_OKAY) {\n        XFREE(secret, srp->heap, DYNAMIC_TYPE_SRP);\n        return r;\n    }\n\n    /* building u (random scrambling parameter) */\n\n    /* H(A) */\n    for (i = 0; !r && i < secretSz - clientPubKeySz; i++)\n        r = SrpHashUpdate(&hash, &pad, 1);\n    if (!r) r = SrpHashUpdate(&hash, clientPubKey, clientPubKeySz);\n\n    /* H(A | B) */\n    for (i = 0; !r && i < secretSz - serverPubKeySz; i++)\n        r = SrpHashUpdate(&hash, &pad, 1);\n    if (!r) r = SrpHashUpdate(&hash, serverPubKey, serverPubKeySz);\n\n    /* set u */\n    if (!r) r = SrpHashFinal(&hash, digest);\n    if (!r) r = mp_read_unsigned_bin(&u, digest, SrpHashSize(srp->type));\n\n    /* building s (secret) */\n\n    if (!r && srp->side == SRP_CLIENT_SIDE) {\n\n        /* temp1 = B - k * v; rejects k == 0, B == 0 and B >= N. */\n        r = mp_read_unsigned_bin(&temp1, srp->k, digestSz);\n        if (!r) r = mp_iszero(&temp1) == MP_YES ? SRP_BAD_KEY_E : 0;\n        if (!r) r = mp_exptmod(&srp->g, &srp->auth, &srp->N, &temp2);\n        if (!r) r = mp_mulmod(&temp1, &temp2, &srp->N, &s);\n        if (!r) r = mp_read_unsigned_bin(&temp2, serverPubKey, serverPubKeySz);\n        if (!r) r = mp_iszero(&temp2) == MP_YES ? SRP_BAD_KEY_E : 0;\n        if (!r) r = mp_cmp(&temp2, &srp->N) != MP_LT ? SRP_BAD_KEY_E : 0;\n        if (!r) r = mp_sub(&temp2, &s, &temp1);\n\n        /* temp2 = a + u * x */\n        if (!r) r = mp_mulmod(&u, &srp->auth, &srp->N, &s);\n        if (!r) r = mp_add(&srp->priv, &s, &temp2);\n\n        /* secret = temp1 ^ temp2 % N */\n        if (!r) r = mp_exptmod(&temp1, &temp2, &srp->N, &s);\n\n    } else if (!r && srp->side == SRP_SERVER_SIDE) {\n        /* temp1 = v ^ u % N */\n        r = mp_exptmod(&srp->auth, &u, &srp->N, &temp1);\n\n        /* temp2 = A * temp1 % N; rejects A == 0, A >= N */\n        if (!r) r = mp_read_unsigned_bin(&s, clientPubKey, clientPubKeySz);\n        if (!r) r = mp_iszero(&s) == MP_YES ? SRP_BAD_KEY_E : 0;\n        if (!r) r = mp_cmp(&s, &srp->N) != MP_LT ? SRP_BAD_KEY_E : 0;\n        if (!r) r = mp_mulmod(&s, &temp1, &srp->N, &temp2);\n\n        /* rejects A * v ^ u % N >= 1, A * v ^ u % N == -1 % N */\n        if (!r) r = mp_read_unsigned_bin(&temp1, (const byte*)\"\\001\", 1);\n        if (!r) r = mp_cmp(&temp2, &temp1) != MP_GT ? SRP_BAD_KEY_E : 0;\n        if (!r) r = mp_sub(&srp->N, &temp1, &s);\n        if (!r) r = mp_cmp(&temp2, &s) == MP_EQ ? SRP_BAD_KEY_E : 0;\n\n        /* secret = temp2 * b % N */\n        if (!r) r = mp_exptmod(&temp2, &srp->priv, &srp->N, &s);\n    }\n\n    /* building session key from secret */\n\n    if (!r) r = mp_to_unsigned_bin(&s, secret);\n    if (!r) r = srp->keyGenFunc_cb(srp, secret, mp_unsigned_bin_size(&s));\n\n    /* updating client proof = H( H(N) ^ H(g) | H(user) | salt | A | B | K) */\n\n    if (!r) r = SrpHashUpdate(&srp->client_proof, clientPubKey, clientPubKeySz);\n    if (!r) r = SrpHashUpdate(&srp->client_proof, serverPubKey, serverPubKeySz);\n    if (!r) r = SrpHashUpdate(&srp->client_proof, srp->key,     srp->keySz);\n\n    /* updating server proof = H(A) */\n\n    if (!r) r = SrpHashUpdate(&srp->server_proof, clientPubKey, clientPubKeySz);\n\n    XFREE(secret, srp->heap, DYNAMIC_TYPE_SRP);\n    mp_clear(&u); mp_clear(&s); mp_clear(&temp1); mp_clear(&temp2);\n\n    return r;\n}\n\nint wc_SrpGetProof(Srp* srp, byte* proof, word32* size)\n{\n    int r;\n\n    if (!srp || !proof || !size)\n        return BAD_FUNC_ARG;\n\n    if (*size < SrpHashSize(srp->type))\n        return BUFFER_E;\n\n    if ((r = SrpHashFinal(srp->side == SRP_CLIENT_SIDE\n                          ? &srp->client_proof\n                          : &srp->server_proof, proof)) != 0)\n        return r;\n\n    *size = SrpHashSize(srp->type);\n\n    if (srp->side == SRP_CLIENT_SIDE) {\n        /* server proof = H( A | client proof | K) */\n        if (!r) r = SrpHashUpdate(&srp->server_proof, proof, *size);\n        if (!r) r = SrpHashUpdate(&srp->server_proof, srp->key, srp->keySz);\n    }\n\n    return r;\n}\n\nint wc_SrpVerifyPeersProof(Srp* srp, byte* proof, word32 size)\n{\n    byte digest[SRP_MAX_DIGEST_SIZE];\n    int r;\n\n    if (!srp || !proof)\n        return BAD_FUNC_ARG;\n\n    if (size != SrpHashSize(srp->type))\n        return BUFFER_E;\n\n    r = SrpHashFinal(srp->side == SRP_CLIENT_SIDE ? &srp->server_proof\n                                                  : &srp->client_proof, digest);\n\n    if (srp->side == SRP_SERVER_SIDE) {\n        /* server proof = H( A | client proof | K) */\n        if (!r) r = SrpHashUpdate(&srp->server_proof, proof, size);\n        if (!r) r = SrpHashUpdate(&srp->server_proof, srp->key, srp->keySz);\n    }\n\n    if (!r && XMEMCMP(proof, digest, size) != 0)\n        r = SRP_VERIFY_E;\n\n    return r;\n}\n\n#endif /* WOLFCRYPT_HAVE_SRP */\n"
  },
  {
    "path": "src/wolfcrypt/src/tfm.c",
    "content": "/* tfm.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n/*\n * Based on public domain TomsFastMath 0.10 by Tom St Denis, tomstdenis@iahu.ca,\n * http://math.libtomcrypt.com\n */\n\n/**\n *  Edited by Moises Guimaraes (moises@wolfssl.com)\n *  to fit wolfSSL's needs.\n */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n/* in case user set USE_FAST_MATH there */\n#include <wolfssl/wolfcrypt/settings.h>\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#ifdef USE_FAST_MATH\n\n#include <wolfssl/wolfcrypt/random.h>\n#include <wolfssl/wolfcrypt/tfm.h>\n#include <wolfcrypt/src/asm.c>  /* will define asm MACROS or C ones */\n#include <wolfssl/wolfcrypt/wolfmath.h> /* common functions */\n\n// ===== add lines begin\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \\\n   !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)\n\t#include \"wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h\"\n#endif\n// ===== add lines end\n\n#if defined(FREESCALE_LTC_TFM)\n    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>\n#endif\n#ifdef WOLFSSL_DEBUG_MATH\n    #include <stdio.h>\n#endif\n\n#ifdef USE_WINDOWS_API\n    #pragma warning(disable:4127)\n    /* Disables the warning:\n     *   4127: conditional expression is constant\n     * in this file.\n     */\n#endif\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\nWOLFSSL_LOCAL int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n#endif\n\n\n\n/* math settings check */\nword32 CheckRunTimeSettings(void)\n{\n    return CTC_SETTINGS;\n}\n\n\n/* math settings size check */\nword32 CheckRunTimeFastMath(void)\n{\n    return FP_SIZE;\n}\n\n\n/* Functions */\n\nvoid fp_add(fp_int *a, fp_int *b, fp_int *c)\n{\n  int     sa, sb;\n\n  /* get sign of both inputs */\n  sa = a->sign;\n  sb = b->sign;\n\n  /* handle two cases, not four */\n  if (sa == sb) {\n    /* both positive or both negative */\n    /* add their magnitudes, copy the sign */\n    c->sign = sa;\n    s_fp_add (a, b, c);\n  } else {\n    /* one positive, the other negative */\n    /* subtract the one with the greater magnitude from */\n    /* the one of the lesser magnitude.  The result gets */\n    /* the sign of the one with the greater magnitude. */\n    if (fp_cmp_mag (a, b) == FP_LT) {\n      c->sign = sb;\n      s_fp_sub (b, a, c);\n    } else {\n      c->sign = sa;\n      s_fp_sub (a, b, c);\n    }\n  }\n}\n\n/* unsigned addition */\nvoid s_fp_add(fp_int *a, fp_int *b, fp_int *c)\n{\n  int      x, y, oldused;\n  fp_word  t;\n\n  y       = MAX(a->used, b->used);\n  oldused = MIN(c->used, FP_SIZE);   /* help static analysis w/ largest size */\n  c->used = y;\n\n  t = 0;\n  for (x = 0; x < y; x++) {\n      t         += ((fp_word)a->dp[x]) + ((fp_word)b->dp[x]);\n      c->dp[x]   = (fp_digit)t;\n      t        >>= DIGIT_BIT;\n  }\n  if (t != 0 && x < FP_SIZE) {\n     c->dp[c->used++] = (fp_digit)t;\n     ++x;\n  }\n\n  c->used = x;\n\n  /* zero any excess digits on the destination that we didn't write to */\n  for (; x < oldused; x++) {\n     c->dp[x] = 0;\n  }\n  fp_clamp(c);\n}\n\n/* c = a - b */\nvoid fp_sub(fp_int *a, fp_int *b, fp_int *c)\n{\n  int     sa, sb;\n\n  sa = a->sign;\n  sb = b->sign;\n\n  if (sa != sb) {\n    /* subtract a negative from a positive, OR */\n    /* subtract a positive from a negative. */\n    /* In either case, ADD their magnitudes, */\n    /* and use the sign of the first number. */\n    c->sign = sa;\n    s_fp_add (a, b, c);\n  } else {\n    /* subtract a positive from a positive, OR */\n    /* subtract a negative from a negative. */\n    /* First, take the difference between their */\n    /* magnitudes, then... */\n    if (fp_cmp_mag (a, b) != FP_LT) {\n      /* Copy the sign from the first */\n      c->sign = sa;\n      /* The first has a larger or equal magnitude */\n      s_fp_sub (a, b, c);\n    } else {\n      /* The result has the *opposite* sign from */\n      /* the first number. */\n      c->sign = (sa == FP_ZPOS) ? FP_NEG : FP_ZPOS;\n      /* The second has a larger magnitude */\n      s_fp_sub (b, a, c);\n    }\n  }\n}\n\n/* unsigned subtraction ||a|| >= ||b|| ALWAYS! */\nvoid s_fp_sub(fp_int *a, fp_int *b, fp_int *c)\n{\n  int      x, oldbused, oldused;\n  fp_word  t;\n\n  oldused  = c->used;\n  oldbused = b->used;\n  c->used  = a->used;\n  t       = 0;\n  for (x = 0; x < oldbused; x++) {\n     t         = ((fp_word)a->dp[x]) - (((fp_word)b->dp[x]) + t);\n     c->dp[x]  = (fp_digit)t;\n     t         = (t >> DIGIT_BIT)&1;\n  }\n  for (; x < a->used; x++) {\n     t         = ((fp_word)a->dp[x]) - t;\n     c->dp[x]  = (fp_digit)t;\n     t         = (t >> DIGIT_BIT)&1;\n   }\n\n  /* zero any excess digits on the destination that we didn't write to */\n  for (; x < oldused; x++) {\n     c->dp[x] = 0;\n  }\n  fp_clamp(c);\n}\n\n/* c = a * b */\nint fp_mul(fp_int *A, fp_int *B, fp_int *C)\n{\n    int   ret = 0;\n    int   y, yy, oldused;\n\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \\\n   !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)\n  ret = esp_mp_mul(A, B, C);\n  if(ret != -2) return ret;\n#endif\n\n    oldused = C->used;\n\n    y  = MAX(A->used, B->used);\n    yy = MIN(A->used, B->used);\n\n    /* call generic if we're out of range */\n    if (y + yy > FP_SIZE) {\n       ret = fp_mul_comba(A, B, C);\n       goto clean;\n    }\n\n    /* pick a comba (unrolled 4/8/16/32 x or rolled) based on the size\n       of the largest input.  We also want to avoid doing excess mults if the\n       inputs are not close to the next power of two.  That is, for example,\n       if say y=17 then we would do (32-17)^2 = 225 unneeded multiplications\n    */\n\n#if defined(TFM_MUL3) && FP_SIZE >= 6\n        if (y <= 3) {\n           ret = fp_mul_comba3(A,B,C);\n           goto clean;\n        }\n#endif\n#if defined(TFM_MUL4) && FP_SIZE >= 8\n        if (y == 4) {\n           ret = fp_mul_comba4(A,B,C);\n           goto clean;\n        }\n#endif\n#if defined(TFM_MUL6) && FP_SIZE >= 12\n        if (y <= 6) {\n           ret = fp_mul_comba6(A,B,C);\n           goto clean;\n        }\n#endif\n#if defined(TFM_MUL7) && FP_SIZE >= 14\n        if (y == 7) {\n           ret = fp_mul_comba7(A,B,C);\n           goto clean;\n        }\n#endif\n#if defined(TFM_MUL8) && FP_SIZE >= 16\n        if (y == 8) {\n           ret = fp_mul_comba8(A,B,C);\n           goto clean;\n        }\n#endif\n#if defined(TFM_MUL9) && FP_SIZE >= 18\n        if (y == 9) {\n           ret = fp_mul_comba9(A,B,C);\n           goto clean;\n        }\n#endif\n#if defined(TFM_MUL12) && FP_SIZE >= 24\n        if (y <= 12) {\n           ret = fp_mul_comba12(A,B,C);\n           goto clean;\n        }\n#endif\n#if defined(TFM_MUL17) && FP_SIZE >= 34\n        if (y <= 17) {\n           ret = fp_mul_comba17(A,B,C);\n           goto clean;\n        }\n#endif\n\n#if defined(TFM_SMALL_SET) && FP_SIZE >= 32\n        if (y <= 16) {\n           ret = fp_mul_comba_small(A,B,C);\n           goto clean;\n        }\n#endif\n#if defined(TFM_MUL20) && FP_SIZE >= 40\n        if (y <= 20) {\n           ret = fp_mul_comba20(A,B,C);\n           goto clean;\n        }\n#endif\n#if defined(TFM_MUL24) && FP_SIZE >= 48\n        if (yy >= 16 && y <= 24) {\n           ret = fp_mul_comba24(A,B,C);\n           goto clean;\n        }\n#endif\n#if defined(TFM_MUL28) && FP_SIZE >= 56\n        if (yy >= 20 && y <= 28) {\n           ret = fp_mul_comba28(A,B,C);\n           goto clean;\n        }\n#endif\n#if defined(TFM_MUL32) && FP_SIZE >= 64\n        if (yy >= 24 && y <= 32) {\n           ret = fp_mul_comba32(A,B,C);\n           goto clean;\n        }\n#endif\n#if defined(TFM_MUL48) && FP_SIZE >= 96\n        if (yy >= 40 && y <= 48) {\n          ret = fp_mul_comba48(A,B,C);\n          goto clean;\n        }\n#endif\n#if defined(TFM_MUL64) && FP_SIZE >= 128\n        if (yy >= 56 && y <= 64) {\n           ret = fp_mul_comba64(A,B,C);\n           goto clean;\n        }\n#endif\n        ret = fp_mul_comba(A,B,C);\n\nclean:\n    /* zero any excess digits on the destination that we didn't write to */\n    for (y = C->used; y >= 0 && y < oldused; y++) {\n        C->dp[y] = 0;\n    }\n\n    return ret;\n}\n\nvoid fp_mul_2(fp_int * a, fp_int * b)\n{\n  int     x, oldused;\n\n  oldused = b->used;\n  b->used = a->used;\n\n  {\n    fp_digit r, rr, *tmpa, *tmpb;\n\n    /* alias for source */\n    tmpa = a->dp;\n\n    /* alias for dest */\n    tmpb = b->dp;\n\n    /* carry */\n    r = 0;\n    for (x = 0; x < a->used; x++) {\n\n      /* get what will be the *next* carry bit from the\n       * MSB of the current digit\n       */\n      rr = *tmpa >> ((fp_digit)(DIGIT_BIT - 1));\n\n      /* now shift up this digit, add in the carry [from the previous] */\n      *tmpb++ = ((*tmpa++ << ((fp_digit)1)) | r);\n\n      /* copy the carry that would be from the source\n       * digit into the next iteration\n       */\n      r = rr;\n    }\n\n    /* new leading digit? */\n    if (r != 0 && b->used != (FP_SIZE-1)) {\n      /* add a MSB which is always 1 at this point */\n      *tmpb = 1;\n      ++(b->used);\n    }\n\n    /* zero any excess digits on the destination that we didn't write to */\n    tmpb = b->dp + b->used;\n    for (x = b->used; x < oldused; x++) {\n      *tmpb++ = 0;\n    }\n  }\n  b->sign = a->sign;\n}\n\n/* c = a * b */\nvoid fp_mul_d(fp_int *a, fp_digit b, fp_int *c)\n{\n   fp_word  w;\n   int      x, oldused;\n\n   oldused = c->used;\n   c->used = a->used;\n   c->sign = a->sign;\n   w       = 0;\n   for (x = 0; x < a->used; x++) {\n       w         = ((fp_word)a->dp[x]) * ((fp_word)b) + w;\n       c->dp[x]  = (fp_digit)w;\n       w         = w >> DIGIT_BIT;\n   }\n   if (w != 0 && (a->used != FP_SIZE)) {\n      c->dp[c->used++] = (fp_digit) w;\n      ++x;\n   }\n\n   /* zero any excess digits on the destination that we didn't write to */\n   /* also checking FP_SIZE here for static analysis */\n   for (; x < oldused && x < FP_SIZE; x++) {\n      c->dp[x] = 0;\n   }\n   fp_clamp(c);\n}\n\n/* c = a * 2**d */\nvoid fp_mul_2d(fp_int *a, int b, fp_int *c)\n{\n   fp_digit carry, carrytmp, shift;\n   int x;\n\n   /* copy it */\n   fp_copy(a, c);\n\n   /* handle whole digits */\n   if (b >= DIGIT_BIT) {\n      fp_lshd(c, b/DIGIT_BIT);\n   }\n   b %= DIGIT_BIT;\n\n   /* shift the digits */\n   if (b != 0) {\n      carry = 0;\n      shift = DIGIT_BIT - b;\n      for (x = 0; x < c->used; x++) {\n          carrytmp = c->dp[x] >> shift;\n          c->dp[x] = (c->dp[x] << b) + carry;\n          carry = carrytmp;\n      }\n      /* store last carry if room */\n      if (carry && x < FP_SIZE) {\n         c->dp[c->used++] = carry;\n      }\n   }\n   fp_clamp(c);\n}\n\n/* generic PxQ multiplier */\n#if defined(HAVE_INTEL_MULX)\n\nWC_INLINE static int fp_mul_comba_mulx(fp_int *A, fp_int *B, fp_int *C)\n\n{\n   int       ix, iy, iz, pa;\n   fp_int    *dst;\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int    tmp[1];\n#else\n   fp_int    *tmp;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n   if (tmp == NULL)\n       return FP_MEM;\n#endif\n\n   /* get size of output and trim */\n   pa = A->used + B->used;\n   if (pa >= FP_SIZE) {\n      pa = FP_SIZE-1;\n   }\n\n   /* Always take branch to use tmp variable. This avoids a cache attack for\n    * determining if C equals A */\n   if (1) {\n      fp_init(tmp);\n      dst = tmp;\n   }\n\n   TFM_INTEL_MUL_COMBA(A, B, dst) ;\n\n  dst->used = pa;\n  dst->sign = A->sign ^ B->sign;\n  fp_clamp(dst);\n  fp_copy(dst, C);\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n  return FP_OKAY;\n}\n#endif\n\nint fp_mul_comba(fp_int *A, fp_int *B, fp_int *C)\n{\n   int       ret = 0;\n   int       ix, iy, iz, tx, ty, pa;\n   fp_digit  c0, c1, c2, *tmpx, *tmpy;\n   fp_int    *dst;\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int    tmp[1];\n#else\n   fp_int    *tmp;\n#endif\n\n   IF_HAVE_INTEL_MULX(ret = fp_mul_comba_mulx(A, B, C), return ret) ;\n\n#ifdef WOLFSSL_SMALL_STACK\n   tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n   if (tmp == NULL)\n       return FP_MEM;\n#endif\n\n   COMBA_START;\n   COMBA_CLEAR;\n\n   /* get size of output and trim */\n   pa = A->used + B->used;\n   if (pa >= FP_SIZE) {\n      pa = FP_SIZE-1;\n   }\n\n   /* Always take branch to use tmp variable. This avoids a cache attack for\n    * determining if C equals A */\n   if (1) {\n      fp_init(tmp);\n      dst = tmp;\n   }\n\n   for (ix = 0; ix < pa; ix++) {\n      /* get offsets into the two bignums */\n      ty = MIN(ix, (B->used > 0 ? B->used - 1 : 0));\n      tx = ix - ty;\n\n      /* setup temp aliases */\n      tmpx = A->dp + tx;\n      tmpy = B->dp + ty;\n\n      /* this is the number of times the loop will iterate, essentially its\n         while (tx++ < a->used && ty-- >= 0) { ... }\n       */\n      iy = MIN(A->used-tx, ty+1);\n\n      /* execute loop */\n      COMBA_FORWARD;\n      for (iz = 0; iz < iy; ++iz) {\n          fp_digit _tmpx = *tmpx++;\n          fp_digit _tmpy = *tmpy--;\n          MULADD(_tmpx, _tmpy);\n      }\n\n      /* store term */\n      COMBA_STORE(dst->dp[ix]);\n  }\n  COMBA_FINI;\n\n  dst->used = pa;\n  dst->sign = A->sign ^ B->sign;\n  fp_clamp(dst);\n  fp_copy(dst, C);\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return ret;\n}\n\n/* a/b => cb + d == a */\nint fp_div(fp_int *a, fp_int *b, fp_int *c, fp_int *d)\n{\n  int     n, t, i, norm, neg;\n#ifndef WOLFSSL_SMALL_STACK\n  fp_int  q[1], x[1], y[1], t1[1], t2[1];\n#else\n  fp_int  *q, *x, *y, *t1, *t2;\n#endif\n\n  /* is divisor zero ? */\n  if (fp_iszero (b) == FP_YES) {\n    return FP_VAL;\n  }\n\n  /* if a < b then q=0, r = a */\n  if (fp_cmp_mag (a, b) == FP_LT) {\n    if (d != NULL) {\n      fp_copy (a, d);\n    }\n    if (c != NULL) {\n      fp_zero (c);\n    }\n    return FP_OKAY;\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  q = (fp_int*)XMALLOC(sizeof(fp_int) * 5, NULL, DYNAMIC_TYPE_BIGINT);\n  if (q == NULL) {\n      return FP_MEM;\n  }\n  x = &q[1]; y = &q[2]; t1 = &q[3]; t2 = &q[4];\n#endif\n\n  fp_init(q);\n  q->used = a->used + 2;\n\n  fp_init(t1);\n  fp_init(t2);\n  fp_init_copy(x, a);\n  fp_init_copy(y, b);\n\n  /* fix the sign */\n  neg = (a->sign == b->sign) ? FP_ZPOS : FP_NEG;\n  x->sign = y->sign = FP_ZPOS;\n\n  /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */\n  norm = fp_count_bits(y) % DIGIT_BIT;\n  if (norm < (int)(DIGIT_BIT-1)) {\n     norm = (DIGIT_BIT-1) - norm;\n     fp_mul_2d (x, norm, x);\n     fp_mul_2d (y, norm, y);\n  } else {\n     norm = 0;\n  }\n\n  /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */\n  n = x->used - 1;\n  t = y->used - 1;\n\n  /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */\n  fp_lshd (y, n - t); /* y = y*b**{n-t} */\n\n  while (fp_cmp (x, y) != FP_LT) {\n    ++(q->dp[n - t]);\n    fp_sub (x, y, x);\n  }\n\n  /* reset y by shifting it back down */\n  fp_rshd (y, n - t);\n\n  /* step 3. for i from n down to (t + 1) */\n  for (i = n; i >= (t + 1); i--) {\n    if (i > x->used) {\n      continue;\n    }\n\n    /* step 3.1 if xi == yt then set q{i-t-1} to b-1,\n     * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */\n    if (x->dp[i] == y->dp[t]) {\n      q->dp[i - t - 1] = (fp_digit) ((((fp_word)1) << DIGIT_BIT) - 1);\n    } else {\n      fp_word tmp;\n      tmp = ((fp_word) x->dp[i]) << ((fp_word) DIGIT_BIT);\n      tmp |= ((fp_word) x->dp[i - 1]);\n      tmp /= ((fp_word)y->dp[t]);\n      q->dp[i - t - 1] = (fp_digit) (tmp);\n    }\n\n    /* while (q{i-t-1} * (yt * b + y{t-1})) >\n             xi * b**2 + xi-1 * b + xi-2\n\n       do q{i-t-1} -= 1;\n    */\n    q->dp[i - t - 1] = (q->dp[i - t - 1] + 1);\n    do {\n      q->dp[i - t - 1] = (q->dp[i - t - 1] - 1);\n\n      /* find left hand */\n      fp_zero (t1);\n      t1->dp[0] = (t - 1 < 0) ? 0 : y->dp[t - 1];\n      t1->dp[1] = y->dp[t];\n      t1->used = 2;\n      fp_mul_d (t1, q->dp[i - t - 1], t1);\n\n      /* find right hand */\n      t2->dp[0] = (i - 2 < 0) ? 0 : x->dp[i - 2];\n      t2->dp[1] = (i - 1 < 0) ? 0 : x->dp[i - 1];\n      t2->dp[2] = x->dp[i];\n      t2->used = 3;\n    } while (fp_cmp_mag(t1, t2) == FP_GT);\n\n    /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */\n    fp_mul_d (y, q->dp[i - t - 1], t1);\n    fp_lshd  (t1, i - t - 1);\n    fp_sub   (x, t1, x);\n\n    /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */\n    if (x->sign == FP_NEG) {\n      fp_copy (y, t1);\n      fp_lshd (t1, i - t - 1);\n      fp_add (x, t1, x);\n      q->dp[i - t - 1] = q->dp[i - t - 1] - 1;\n    }\n  }\n\n  /* now q is the quotient and x is the remainder\n   * [which we have to normalize]\n   */\n\n  /* get sign before writing to c */\n  x->sign = x->used == 0 ? FP_ZPOS : a->sign;\n\n  if (c != NULL) {\n    fp_clamp (q);\n    fp_copy (q, c);\n    c->sign = neg;\n  }\n\n  if (d != NULL) {\n    fp_div_2d (x, norm, x, NULL);\n\n    /* zero any excess digits on the destination that we didn't write to */\n    for (i = b->used; i < x->used; i++) {\n        x->dp[i] = 0;\n    }\n    fp_clamp(x);\n    fp_copy (x, d);\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return FP_OKAY;\n}\n\n/* b = a/2 */\nvoid fp_div_2(fp_int * a, fp_int * b)\n{\n  int     x, oldused;\n\n  oldused = b->used;\n  b->used = a->used;\n  {\n    fp_digit r, rr, *tmpa, *tmpb;\n\n    /* source alias */\n    tmpa = a->dp + b->used - 1;\n\n    /* dest alias */\n    tmpb = b->dp + b->used - 1;\n\n    /* carry */\n    r = 0;\n    for (x = b->used - 1; x >= 0; x--) {\n      /* get the carry for the next iteration */\n      rr = *tmpa & 1;\n\n      /* shift the current digit, add in carry and store */\n      *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));\n\n      /* forward carry to next iteration */\n      r = rr;\n    }\n\n    /* zero any excess digits on the destination that we didn't write to */\n    tmpb = b->dp + b->used;\n    for (x = b->used; x < oldused; x++) {\n      *tmpb++ = 0;\n    }\n  }\n  b->sign = a->sign;\n  fp_clamp (b);\n}\n\n/* c = a / 2**b */\nvoid fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d)\n{\n  int      D;\n\n  /* if the shift count is <= 0 then we do no work */\n  if (b <= 0) {\n    fp_copy (a, c);\n    if (d != NULL) {\n      fp_zero (d);\n    }\n    return;\n  }\n\n  /* get the remainder before a is changed in calculating c */\n  if (a == c && d != NULL) {\n    fp_mod_2d (a, b, d);\n  }\n\n  /* copy */\n  fp_copy(a, c);\n\n  /* shift by as many digits in the bit count */\n  if (b >= (int)DIGIT_BIT) {\n    fp_rshd (c, b / DIGIT_BIT);\n  }\n\n  /* shift any bit count < DIGIT_BIT */\n  D = (b % DIGIT_BIT);\n  if (D != 0) {\n    fp_rshb(c, D);\n  }\n\n  /* get the remainder if a is not changed in calculating c */\n  if (a != c && d != NULL) {\n    fp_mod_2d (a, b, d);\n  }\n\n  fp_clamp (c);\n}\n\n/* c = a mod b, 0 <= c < b  */\nint fp_mod(fp_int *a, fp_int *b, fp_int *c)\n{\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int t[1];\n#else\n   fp_int *t;\n#endif\n   int    err;\n\n#ifdef WOLFSSL_SMALL_STACK\n   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n   if (t == NULL)\n       return FP_MEM;\n#endif\n\n   fp_init(t);\n   err = fp_div(a, b, NULL, t);\n   if (err == FP_OKAY) {\n      if (t->sign != b->sign) {\n         fp_add(t, b, c);\n      } else {\n         fp_copy(t, c);\n     }\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return err;\n}\n\n/* c = a mod 2**d */\nvoid fp_mod_2d(fp_int *a, int b, fp_int *c)\n{\n   int x;\n\n   /* zero if count less than or equal to zero */\n   if (b <= 0) {\n      fp_zero(c);\n      return;\n   }\n\n   /* get copy of input */\n   fp_copy(a, c);\n\n   /* if 2**d is larger than we just return */\n   if (b >= (DIGIT_BIT * a->used)) {\n      return;\n   }\n\n  /* zero digits above the last digit of the modulus */\n  for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {\n    c->dp[x] = 0;\n  }\n  /* clear the digit that is not completely outside/inside the modulus */\n  c->dp[b / DIGIT_BIT] &= ~((fp_digit)0) >> (DIGIT_BIT - b);\n  fp_clamp (c);\n}\n\nstatic int fp_invmod_slow (fp_int * a, fp_int * b, fp_int * c)\n{\n#ifndef WOLFSSL_SMALL_STACK\n  fp_int  x[1], y[1], u[1], v[1], A[1], B[1], C[1], D[1];\n#else\n  fp_int  *x, *y, *u, *v, *A, *B, *C, *D;\n#endif\n  int     err;\n\n  /* b cannot be negative */\n  if (b->sign == FP_NEG || fp_iszero(b) == FP_YES) {\n    return FP_VAL;\n  }\n  if (fp_iszero(a) == FP_YES) {\n    return FP_VAL;\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  x = (fp_int*)XMALLOC(sizeof(fp_int) * 8, NULL, DYNAMIC_TYPE_BIGINT);\n  if (x == NULL) {\n      return FP_MEM;\n  }\n  y = &x[1]; u = &x[2]; v = &x[3]; A = &x[4]; B = &x[5]; C = &x[6]; D = &x[7];\n#endif\n\n  /* init temps */\n  fp_init(x);    fp_init(y);\n  fp_init(u);    fp_init(v);\n  fp_init(A);    fp_init(B);\n  fp_init(C);    fp_init(D);\n\n  /* x = a, y = b */\n  if ((err = fp_mod(a, b, x)) != FP_OKAY) {\n  #ifdef WOLFSSL_SMALL_STACK\n    XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);\n  #endif\n    return err;\n  }\n  fp_copy(b, y);\n\n  /* 2. [modified] if x,y are both even then return an error! */\n  if (fp_iseven(x) == FP_YES && fp_iseven(y) == FP_YES) {\n  #ifdef WOLFSSL_SMALL_STACK\n    XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);\n  #endif\n    return FP_VAL;\n  }\n\n  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */\n  fp_copy (x, u);\n  fp_copy (y, v);\n  fp_set (A, 1);\n  fp_set (D, 1);\n\ntop:\n  /* 4.  while u is even do */\n  while (fp_iseven (u) == FP_YES) {\n    /* 4.1 u = u/2 */\n    fp_div_2 (u, u);\n\n    /* 4.2 if A or B is odd then */\n    if (fp_isodd (A) == FP_YES || fp_isodd (B) == FP_YES) {\n      /* A = (A+y)/2, B = (B-x)/2 */\n      fp_add (A, y, A);\n      fp_sub (B, x, B);\n    }\n    /* A = A/2, B = B/2 */\n    fp_div_2 (A, A);\n    fp_div_2 (B, B);\n  }\n\n  /* 5.  while v is even do */\n  while (fp_iseven (v) == FP_YES) {\n    /* 5.1 v = v/2 */\n    fp_div_2 (v, v);\n\n    /* 5.2 if C or D is odd then */\n    if (fp_isodd (C) == FP_YES || fp_isodd (D) == FP_YES) {\n      /* C = (C+y)/2, D = (D-x)/2 */\n      fp_add (C, y, C);\n      fp_sub (D, x, D);\n    }\n    /* C = C/2, D = D/2 */\n    fp_div_2 (C, C);\n    fp_div_2 (D, D);\n  }\n\n  /* 6.  if u >= v then */\n  if (fp_cmp (u, v) != FP_LT) {\n    /* u = u - v, A = A - C, B = B - D */\n    fp_sub (u, v, u);\n    fp_sub (A, C, A);\n    fp_sub (B, D, B);\n  } else {\n    /* v - v - u, C = C - A, D = D - B */\n    fp_sub (v, u, v);\n    fp_sub (C, A, C);\n    fp_sub (D, B, D);\n  }\n\n  /* if not zero goto step 4 */\n  if (fp_iszero (u) == FP_NO)\n    goto top;\n\n  /* now a = C, b = D, gcd == g*v */\n\n  /* if v != 1 then there is no inverse */\n  if (fp_cmp_d (v, 1) != FP_EQ) {\n  #ifdef WOLFSSL_SMALL_STACK\n    XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);\n  #endif\n    return FP_VAL;\n  }\n\n  /* if its too low */\n  while (fp_cmp_d(C, 0) == FP_LT) {\n      fp_add(C, b, C);\n  }\n\n  /* too big */\n  while (fp_cmp_mag(C, b) != FP_LT) {\n      fp_sub(C, b, C);\n  }\n\n  /* C is now the inverse */\n  fp_copy(C, c);\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return FP_OKAY;\n}\n\n/* c = 1/a (mod b) for odd b only */\nint fp_invmod(fp_int *a, fp_int *b, fp_int *c)\n{\n#ifndef WOLFSSL_SMALL_STACK\n  fp_int  x[1], y[1], u[1], v[1], B[1], D[1];\n#else\n  fp_int  *x, *y, *u, *v, *B, *D;\n#endif\n  int     neg;\n  int     err;\n\n  if (b->sign == FP_NEG || fp_iszero(b) == FP_YES) {\n    return FP_VAL;\n  }\n\n  /* [modified] sanity check on \"a\" */\n  if (fp_iszero(a) == FP_YES) {\n    return FP_VAL; /* can not divide by 0 here */\n  }\n\n  /* 2. [modified] b must be odd   */\n  if (fp_iseven(b) == FP_YES) {\n    return fp_invmod_slow(a,b,c);\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  x = (fp_int*)XMALLOC(sizeof(fp_int) * 6, NULL, DYNAMIC_TYPE_BIGINT);\n  if (x == NULL) {\n      return FP_MEM;\n  }\n  y = &x[1]; u = &x[2]; v = &x[3]; B = &x[4]; D = &x[5];\n#endif\n\n  /* init all our temps */\n  fp_init(x);  fp_init(y);\n  fp_init(u);  fp_init(v);\n  fp_init(B);  fp_init(D);\n\n  if (fp_cmp(a, b) != MP_LT) {\n    err = mp_mod(a, b, y);\n    if (err != FP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);\n    #endif\n      return err;\n    }\n    a = y;\n  }\n\n  if (fp_iszero(a) == FP_YES) {\n  #ifdef WOLFSSL_SMALL_STACK\n    XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);\n  #endif\n    return FP_VAL;\n  }\n\n  /* x == modulus, y == value to invert */\n  fp_copy(b, x);\n\n  /* we need y = |a| */\n  fp_abs(a, y);\n\n  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */\n  fp_copy(x, u);\n  fp_copy(y, v);\n  fp_set (D, 1);\n\ntop:\n  /* 4.  while u is even do */\n  while (fp_iseven (u) == FP_YES) {\n    /* 4.1 u = u/2 */\n    fp_div_2 (u, u);\n\n    /* 4.2 if B is odd then */\n    if (fp_isodd (B) == FP_YES) {\n      fp_sub (B, x, B);\n    }\n    /* B = B/2 */\n    fp_div_2 (B, B);\n  }\n\n  /* 5.  while v is even do */\n  while (fp_iseven (v) == FP_YES) {\n    /* 5.1 v = v/2 */\n    fp_div_2 (v, v);\n\n    /* 5.2 if D is odd then */\n    if (fp_isodd (D) == FP_YES) {\n      /* D = (D-x)/2 */\n      fp_sub (D, x, D);\n    }\n    /* D = D/2 */\n    fp_div_2 (D, D);\n  }\n\n  /* 6.  if u >= v then */\n  if (fp_cmp (u, v) != FP_LT) {\n    /* u = u - v, B = B - D */\n    fp_sub (u, v, u);\n    fp_sub (B, D, B);\n  } else {\n    /* v - v - u, D = D - B */\n    fp_sub (v, u, v);\n    fp_sub (D, B, D);\n  }\n\n  /* if not zero goto step 4 */\n  if (fp_iszero (u) == FP_NO) {\n    goto top;\n  }\n\n  /* now a = C, b = D, gcd == g*v */\n\n  /* if v != 1 then there is no inverse */\n  if (fp_cmp_d (v, 1) != FP_EQ) {\n  #ifdef WOLFSSL_SMALL_STACK\n    XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);\n  #endif\n    return FP_VAL;\n  }\n\n  /* b is now the inverse */\n  neg = a->sign;\n  while (D->sign == FP_NEG) {\n    fp_add (D, b, D);\n  }\n  /* too big */\n  while (fp_cmp_mag(D, b) != FP_LT) {\n    fp_sub(D, b, D);\n  }\n  fp_copy (D, c);\n  c->sign = neg;\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return FP_OKAY;\n}\n\n/* d = a * b (mod c) */\nint fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)\n{\n  int err;\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int t[1];\n#else\n   fp_int *t;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n   if (t == NULL)\n       return FP_MEM;\n#endif\n\n  fp_init(t);\n  err = fp_mul(a, b, t);\n  if (err == FP_OKAY) {\n  #if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)\n    if (d->size < FP_SIZE) {\n      err = fp_mod(t, c, t);\n      fp_copy(t, d);\n    } else\n  #endif\n    {\n      err = fp_mod(t, c, d);\n    }\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return err;\n}\n\n/* d = a - b (mod c) */\nint fp_submod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)\n{\n  int err;\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int t[1];\n#else\n   fp_int *t;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n   if (t == NULL)\n       return FP_MEM;\n#endif\n\n  fp_init(t);\n  fp_sub(a, b, t);\n#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)\n  if (d->size < FP_SIZE) {\n    err = fp_mod(t, c, t);\n    fp_copy(t, d);\n  } else\n#endif\n  {\n    err = fp_mod(t, c, d);\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return err;\n}\n\n/* d = a + b (mod c) */\nint fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)\n{\n  int err;\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int t[1];\n#else\n   fp_int *t;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n   if (t == NULL)\n       return FP_MEM;\n#endif\n\n  fp_init(t);\n  fp_add(a, b, t);\n#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)\n  if (d->size < FP_SIZE) {\n    err = fp_mod(t, c, t);\n    fp_copy(t, d);\n  } else\n#endif\n  {\n    err = fp_mod(t, c, d);\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return err;\n}\n\n#ifdef TFM_TIMING_RESISTANT\n\n#ifdef WC_RSA_NONBLOCK\n\n#ifdef WC_RSA_NONBLOCK_TIME\n  /* User can override the check-time at build-time using the\n   * FP_EXPTMOD_NB_CHECKTIME macro to define your own function */\n  #ifndef FP_EXPTMOD_NB_CHECKTIME\n    /* instruction count for each type of operation */\n    /* array lookup is using TFM_EXPTMOD_NB_* states */\n    static const word32 exptModNbInst[TFM_EXPTMOD_NB_COUNT] = {\n    #ifdef TFM_PPC32\n      #ifdef _DEBUG\n        11098, 8701, 3971, 178394, 858093, 1040, 822, 178056, 181574, 90883, 184339, 236813\n      #else\n        7050,  2554, 3187, 43178,  200422, 384,  275, 43024,  43550,  30450, 46270,  61376\n      #endif\n    #elif defined(TFM_X86_64)\n      #ifdef _DEBUG\n        954, 2377, 858, 19027, 90840, 287, 407, 20140, 7874,  11385, 8005,  6151\n      #else\n        765, 1007, 771, 5216,  34993, 248, 193, 4975,  4201,  3947,  4275,  3811\n      #endif\n    #else /* software only fast math */\n      #ifdef _DEBUG\n        798, 2245, 802, 16657, 66920, 352, 186, 16997, 16145, 12789, 16742, 15006\n      #else\n        775, 1084, 783, 4692,  37510, 207, 183, 4374,  4392,  3097,  4442,  4079\n      #endif\n    #endif\n    };\n\n    static int fp_exptmod_nb_checktime(exptModNb_t* nb)\n    {\n      word32 totalInst;\n\n      /* if no max time has been set then stop (do not block) */\n      if (nb->maxBlockInst == 0 || nb->state >= TFM_EXPTMOD_NB_COUNT) {\n        return TFM_EXPTMOD_NB_STOP;\n      }\n\n      /* if instruction table not set then use maxBlockInst as simple counter */\n      if (exptModNbInst[nb->state] == 0) {\n        if (++nb->totalInst < nb->maxBlockInst)\n          return TFM_EXPTMOD_NB_CONTINUE;\n\n        nb->totalInst = 0; /* reset counter */\n        return TFM_EXPTMOD_NB_STOP;\n      }\n\n      /* get total instruction count including next operation */\n      totalInst = nb->totalInst + exptModNbInst[nb->state];\n      /* if the next operation can completed within the maximum then continue */\n      if (totalInst <= nb->maxBlockInst) {\n        return TFM_EXPTMOD_NB_CONTINUE;\n      }\n\n      return TFM_EXPTMOD_NB_STOP;\n    }\n    #define FP_EXPTMOD_NB_CHECKTIME(nb) fp_exptmod_nb_checktime((nb))\n  #endif /* !FP_EXPTMOD_NB_CHECKTIME */\n#endif /* WC_RSA_NONBLOCK_TIME */\n\n/* non-blocking version of timing resistant fp_exptmod function */\n/* supports cache resistance */\nint fp_exptmod_nb(exptModNb_t* nb, fp_int* G, fp_int* X, fp_int* P, fp_int* Y)\n{\n  int err, ret = FP_WOULDBLOCK;\n\n  if (nb == NULL)\n    return FP_VAL;\n\n#ifdef WC_RSA_NONBLOCK_TIME\n  nb->totalInst = 0;\n  do {\n    nb->totalInst += exptModNbInst[nb->state];\n#endif\n\n  switch (nb->state) {\n  case TFM_EXPTMOD_NB_INIT:\n    /* now setup montgomery */\n    if ((err = fp_montgomery_setup(P, &nb->mp)) != FP_OKAY) {\n      nb->state = TFM_EXPTMOD_NB_INIT;\n      return err;\n    }\n\n    /* init ints */\n    fp_init(&nb->R[0]);\n    fp_init(&nb->R[1]);\n  #ifndef WC_NO_CACHE_RESISTANT\n    fp_init(&nb->R[2]);\n  #endif\n    nb->state = TFM_EXPTMOD_NB_MONT;\n    break;\n\n  case TFM_EXPTMOD_NB_MONT:\n    /* mod m -> R[0] */\n    fp_montgomery_calc_normalization(&nb->R[0], P);\n\n    nb->state = TFM_EXPTMOD_NB_MONT_RED;\n    break;\n\n  case TFM_EXPTMOD_NB_MONT_RED:\n    /* reduce G -> R[1] */\n    if (fp_cmp_mag(P, G) != FP_GT) {\n       /* G > P so we reduce it first */\n       fp_mod(G, P, &nb->R[1]);\n    } else {\n       fp_copy(G, &nb->R[1]);\n    }\n\n    nb->state = TFM_EXPTMOD_NB_MONT_MUL;\n    break;\n\n  case TFM_EXPTMOD_NB_MONT_MUL:\n    /* G (R[1]) * m (R[0]) */\n    err = fp_mul(&nb->R[1], &nb->R[0], &nb->R[1]);\n    if (err != FP_OKAY) {\n      nb->state = TFM_EXPTMOD_NB_INIT;\n      return err;\n    }\n\n    nb->state = TFM_EXPTMOD_NB_MONT_MOD;\n    break;\n\n  case TFM_EXPTMOD_NB_MONT_MOD:\n    /* mod m */\n    err = fp_div(&nb->R[1], P, NULL, &nb->R[1]);\n    if (err != FP_OKAY) {\n      nb->state = TFM_EXPTMOD_NB_INIT;\n      return err;\n    }\n\n    nb->state = TFM_EXPTMOD_NB_MONT_MODCHK;\n    break;\n\n  case TFM_EXPTMOD_NB_MONT_MODCHK:\n    /* m matches sign of (G * R mod m) */\n    if (nb->R[1].sign != P->sign) {\n       fp_add(&nb->R[1], P, &nb->R[1]);\n    }\n\n    /* set initial mode and bit cnt */\n    nb->bitcnt = 1;\n    nb->buf    = 0;\n    nb->digidx = X->used - 1;\n\n    nb->state = TFM_EXPTMOD_NB_NEXT;\n    break;\n\n  case TFM_EXPTMOD_NB_NEXT:\n    /* grab next digit as required */\n    if (--nb->bitcnt == 0) {\n      /* if nb->digidx == -1 we are out of digits so break */\n      if (nb->digidx == -1) {\n        nb->state = TFM_EXPTMOD_NB_RED;\n        break;\n      }\n      /* read next digit and reset nb->bitcnt */\n      nb->buf    = X->dp[nb->digidx--];\n      nb->bitcnt = (int)DIGIT_BIT;\n    }\n\n    /* grab the next msb from the exponent */\n    nb->y     = (int)(nb->buf >> (DIGIT_BIT - 1)) & 1;\n    nb->buf <<= (fp_digit)1;\n    nb->state = TFM_EXPTMOD_NB_MUL;\n    FALL_THROUGH;\n\n  case TFM_EXPTMOD_NB_MUL:\n    fp_mul(&nb->R[0], &nb->R[1], &nb->R[nb->y^1]);\n    nb->state = TFM_EXPTMOD_NB_MUL_RED;\n    break;\n\n  case TFM_EXPTMOD_NB_MUL_RED:\n    fp_montgomery_reduce(&nb->R[nb->y^1], P, nb->mp);\n    nb->state = TFM_EXPTMOD_NB_SQR;\n    break;\n\n  case TFM_EXPTMOD_NB_SQR:\n  #ifdef WC_NO_CACHE_RESISTANT\n    fp_sqr(&nb->R[nb->y], &nb->R[nb->y]);\n  #else\n    fp_copy((fp_int*) ( ((wolfssl_word)&nb->R[0] & wc_off_on_addr[nb->y^1]) +\n                        ((wolfssl_word)&nb->R[1] & wc_off_on_addr[nb->y]) ),\n            &nb->R[2]);\n    fp_sqr(&nb->R[2], &nb->R[2]);\n  #endif /* WC_NO_CACHE_RESISTANT */\n\n    nb->state = TFM_EXPTMOD_NB_SQR_RED;\n    break;\n\n  case TFM_EXPTMOD_NB_SQR_RED:\n  #ifdef WC_NO_CACHE_RESISTANT\n    fp_montgomery_reduce(&nb->R[nb->y], P, nb->mp);\n  #else\n    fp_montgomery_reduce(&nb->R[2], P, nb->mp);\n    fp_copy(&nb->R[2],\n            (fp_int*) ( ((wolfssl_word)&nb->R[0] & wc_off_on_addr[nb->y^1]) +\n                        ((wolfssl_word)&nb->R[1] & wc_off_on_addr[nb->y]) ) );\n  #endif /* WC_NO_CACHE_RESISTANT */\n\n    nb->state = TFM_EXPTMOD_NB_NEXT;\n    break;\n\n  case TFM_EXPTMOD_NB_RED:\n    /* final reduce */\n    fp_montgomery_reduce(&nb->R[0], P, nb->mp);\n    fp_copy(&nb->R[0], Y);\n\n    nb->state = TFM_EXPTMOD_NB_INIT;\n    ret = FP_OKAY;\n    break;\n  } /* switch */\n\n#ifdef WC_RSA_NONBLOCK_TIME\n  /* determine if maximum blocking time has been reached */\n  } while (ret == FP_WOULDBLOCK &&\n    FP_EXPTMOD_NB_CHECKTIME(nb) == TFM_EXPTMOD_NB_CONTINUE);\n#endif\n\n  return ret;\n}\n\n#endif /* WC_RSA_NONBLOCK */\n\n\n/* timing resistant montgomery ladder based exptmod\n   Based on work by Marc Joye, Sung-Ming Yen, \"The Montgomery Powering Ladder\",\n   Cryptographic Hardware and Embedded Systems, CHES 2002\n*/\nstatic int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y)\n{\n#ifndef WOLFSSL_SMALL_STACK\n#ifdef WC_NO_CACHE_RESISTANT\n  fp_int   R[2];\n#else\n  fp_int   R[3];   /* need a temp for cache resistance */\n#endif\n#else\n   fp_int  *R;\n#endif\n  fp_digit buf, mp;\n  int      err, bitcnt, digidx, y;\n\n  /* now setup montgomery  */\n  if ((err = fp_montgomery_setup (P, &mp)) != FP_OKAY) {\n     return err;\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n#ifndef WC_NO_CACHE_RESISTANT\n   R = (fp_int*)XMALLOC(sizeof(fp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT);\n#else\n   R = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n   if (R == NULL)\n       return FP_MEM;\n#endif\n  fp_init(&R[0]);\n  fp_init(&R[1]);\n#ifndef WC_NO_CACHE_RESISTANT\n  fp_init(&R[2]);\n#endif\n\n  /* now we need R mod m */\n  fp_montgomery_calc_normalization (&R[0], P);\n\n  /* now set R[0][1] to G * R mod m */\n  if (fp_cmp_mag(P, G) != FP_GT) {\n     /* G > P so we reduce it first */\n     fp_mod(G, P, &R[1]);\n  } else {\n     fp_copy(G, &R[1]);\n  }\n  fp_mulmod (&R[1], &R[0], P, &R[1]);\n\n  /* for j = t-1 downto 0 do\n        r_!k = R0*R1; r_k = r_k^2\n  */\n\n  /* set initial mode and bit cnt */\n  bitcnt = 1;\n  buf    = 0;\n  digidx = digits - 1;\n\n  for (;;) {\n    /* grab next digit as required */\n    if (--bitcnt == 0) {\n      /* if digidx == -1 we are out of digits so break */\n      if (digidx == -1) {\n        break;\n      }\n      /* read next digit and reset bitcnt */\n      buf    = X->dp[digidx--];\n      bitcnt = (int)DIGIT_BIT;\n    }\n\n    /* grab the next msb from the exponent */\n    y     = (int)(buf >> (DIGIT_BIT - 1)) & 1;\n    buf <<= (fp_digit)1;\n\n    /* do ops */\n    err = fp_mul(&R[0], &R[1], &R[y^1]);\n    if (err != FP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);\n    #endif\n      return err;\n    }\n    err = fp_montgomery_reduce(&R[y^1], P, mp);\n    if (err != FP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);\n    #endif\n      return err;\n    }\n\n#ifdef WC_NO_CACHE_RESISTANT\n    err = fp_sqr(&R[y], &R[y]);\n    if (err != FP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);\n    #endif\n      return err;\n    }\n    err = fp_montgomery_reduce(&R[y], P, mp);\n    if (err != FP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);\n    #endif\n      return err;\n    }\n#else\n    /* instead of using R[y] for sqr, which leaks key bit to cache monitor,\n     * use R[2] as temp, make sure address calc is constant, keep\n     * &R[0] and &R[1] in cache */\n    fp_copy((fp_int*) ( ((wolfssl_word)&R[0] & wc_off_on_addr[y^1]) +\n                        ((wolfssl_word)&R[1] & wc_off_on_addr[y]) ),\n            &R[2]);\n    err = fp_sqr(&R[2], &R[2]);\n    if (err != FP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);\n    #endif\n      return err;\n    }\n    err = fp_montgomery_reduce(&R[2], P, mp);\n    if (err != FP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);\n    #endif\n      return err;\n    }\n    fp_copy(&R[2],\n            (fp_int*) ( ((wolfssl_word)&R[0] & wc_off_on_addr[y^1]) +\n                        ((wolfssl_word)&R[1] & wc_off_on_addr[y]) ) );\n#endif /* WC_NO_CACHE_RESISTANT */\n  }\n\n   err = fp_montgomery_reduce(&R[0], P, mp);\n   fp_copy(&R[0], Y);\n#ifdef WOLFSSL_SMALL_STACK\n   XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n   return err;\n}\n\n#else /* TFM_TIMING_RESISTANT */\n\n/* y = g**x (mod b)\n * Some restrictions... x must be positive and < b\n */\nstatic int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P,\n                       fp_int * Y)\n{\n  fp_digit buf, mp;\n  int      err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;\n#ifdef WOLFSSL_SMALL_STACK\n  fp_int  *res;\n  fp_int  *M;\n#else\n  fp_int   res[1];\n  fp_int   M[64];\n#endif\n\n  (void)digits;\n\n  /* find window size */\n  x = fp_count_bits (X);\n  if (x <= 21) {\n    winsize = 1;\n  } else if (x <= 36) {\n    winsize = 3;\n  } else if (x <= 140) {\n    winsize = 4;\n  } else if (x <= 450) {\n    winsize = 5;\n  } else {\n    winsize = 6;\n  }\n\n  /* now setup montgomery  */\n  if ((err = fp_montgomery_setup (P, &mp)) != FP_OKAY) {\n     return err;\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  /* only allocate space for what's needed for window plus res */\n  M = (fp_int*)XMALLOC(sizeof(fp_int)*((1 << winsize) + 1), NULL, DYNAMIC_TYPE_BIGINT);\n  if (M == NULL) {\n     return FP_MEM;\n  }\n  res = &M[1 << winsize];\n#endif\n\n  /* init M array */\n  for(x = 0; x < (1 << winsize); x++)\n    fp_init(&M[x]);\n\n  /* setup result */\n  fp_init(res);\n\n  /* create M table\n   *\n   * The M table contains powers of the input base, e.g. M[x] = G^x mod P\n   *\n   * The first half of the table is not computed though except for M[0] and M[1]\n   */\n\n   /* now we need R mod m */\n   fp_montgomery_calc_normalization (res, P);\n\n   /* now set M[1] to G * R mod m */\n   if (fp_cmp_mag(P, G) != FP_GT) {\n      /* G > P so we reduce it first */\n      fp_mod(G, P, &M[1]);\n   } else {\n      fp_copy(G, &M[1]);\n   }\n   fp_mulmod (&M[1], res, P, &M[1]);\n\n  /* compute the value at M[1<<(winsize-1)] by\n   * squaring M[1] (winsize-1) times */\n  fp_copy (&M[1], &M[1 << (winsize - 1)]);\n  for (x = 0; x < (winsize - 1); x++) {\n    fp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)]);\n    err = fp_montgomery_reduce (&M[1 << (winsize - 1)], P, mp);\n    if (err != FP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n      XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n    #endif\n      return err;\n    }\n  }\n\n  /* create upper table */\n  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {\n    err = fp_mul(&M[x - 1], &M[1], &M[x]);\n    if (err != FP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n      XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n    #endif\n      return err;\n    }\n    err = fp_montgomery_reduce(&M[x], P, mp);\n    if (err != FP_OKAY) {\n    #ifdef WOLFSSL_SMALL_STACK\n      XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n    #endif\n      return err;\n    }\n  }\n\n  /* set initial mode and bit cnt */\n  mode   = 0;\n  bitcnt = 1;\n  buf    = 0;\n  digidx = X->used - 1;\n  bitcpy = 0;\n  bitbuf = 0;\n\n  for (;;) {\n    /* grab next digit as required */\n    if (--bitcnt == 0) {\n      /* if digidx == -1 we are out of digits so break */\n      if (digidx == -1) {\n        break;\n      }\n      /* read next digit and reset bitcnt */\n      buf    = X->dp[digidx--];\n      bitcnt = (int)DIGIT_BIT;\n    }\n\n    /* grab the next msb from the exponent */\n    y     = (int)(buf >> (DIGIT_BIT - 1)) & 1;\n    buf <<= (fp_digit)1;\n\n    /* if the bit is zero and mode == 0 then we ignore it\n     * These represent the leading zero bits before the first 1 bit\n     * in the exponent.  Technically this opt is not required but it\n     * does lower the # of trivial squaring/reductions used\n     */\n    if (mode == 0 && y == 0) {\n      continue;\n    }\n\n    /* if the bit is zero and mode == 1 then we square */\n    if (mode == 1 && y == 0) {\n      err = fp_sqr(res, res);\n      if (err != FP_OKAY) {\n      #ifdef WOLFSSL_SMALL_STACK\n        XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n      #endif\n        return err;\n      }\n      fp_montgomery_reduce(res, P, mp);\n      if (err != FP_OKAY) {\n      #ifdef WOLFSSL_SMALL_STACK\n        XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n      #endif\n        return err;\n      }\n      continue;\n    }\n\n    /* else we add it to the window */\n    bitbuf |= (y << (winsize - ++bitcpy));\n    mode    = 2;\n\n    if (bitcpy == winsize) {\n      /* ok window is filled so square as required and multiply  */\n      /* square first */\n      for (x = 0; x < winsize; x++) {\n        err = fp_sqr(res, res);\n        if (err != FP_OKAY) {\n        #ifdef WOLFSSL_SMALL_STACK\n          XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n        #endif\n          return err;\n        }\n        err = fp_montgomery_reduce(res, P, mp);\n        if (err != FP_OKAY) {\n        #ifdef WOLFSSL_SMALL_STACK\n          XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n        #endif\n          return err;\n        }\n      }\n\n      /* then multiply */\n      err = fp_mul(res, &M[bitbuf], res);\n      if (err != FP_OKAY) {\n      #ifdef WOLFSSL_SMALL_STACK\n        XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n      #endif\n        return err;\n      }\n      err = fp_montgomery_reduce(res, P, mp);\n      if (err != FP_OKAY) {\n      #ifdef WOLFSSL_SMALL_STACK\n        XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n      #endif\n        return err;\n      }\n\n      /* empty window and reset */\n      bitcpy = 0;\n      bitbuf = 0;\n      mode   = 1;\n    }\n  }\n\n  /* if bits remain then square/multiply */\n  if (mode == 2 && bitcpy > 0) {\n    /* square then multiply if the bit is set */\n    for (x = 0; x < bitcpy; x++) {\n      err = fp_sqr(res, res);\n      if (err != FP_OKAY) {\n      #ifdef WOLFSSL_SMALL_STACK\n        XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n      #endif\n        return err;\n      }\n      err = fp_montgomery_reduce(res, P, mp);\n      if (err != FP_OKAY) {\n      #ifdef WOLFSSL_SMALL_STACK\n        XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n      #endif\n        return err;\n      }\n\n      /* get next bit of the window */\n      bitbuf <<= 1;\n      if ((bitbuf & (1 << winsize)) != 0) {\n        /* then multiply */\n        err = fp_mul(res, &M[1], res);\n        if (err != FP_OKAY) {\n        #ifdef WOLFSSL_SMALL_STACK\n          XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n        #endif\n          return err;\n        }\n        err = fp_montgomery_reduce(res, P, mp);\n        if (err != FP_OKAY) {\n        #ifdef WOLFSSL_SMALL_STACK\n          XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n        #endif\n          return err;\n        }\n      }\n    }\n  }\n\n  /* fixup result if Montgomery reduction is used\n   * recall that any value in a Montgomery system is\n   * actually multiplied by R mod n.  So we have\n   * to reduce one more time to cancel out the factor\n   * of R.\n   */\n  err = fp_montgomery_reduce(res, P, mp);\n\n  /* swap res with Y */\n  fp_copy (res, Y);\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return err;\n}\n\n#endif /* TFM_TIMING_RESISTANT */\n\n\n#ifdef TFM_TIMING_RESISTANT\n#if DIGIT_BIT <= 16\n    #define WINSIZE    2\n#elif DIGIT_BIT <= 32\n    #define WINSIZE    3\n#elif DIGIT_BIT <= 64\n    #define WINSIZE    4\n#elif DIGIT_BIT <= 128\n    #define WINSIZE    5\n#endif\n\n/* y = 2**x (mod b)\n * Some restrictions... x must be positive and < b\n */\nstatic int _fp_exptmod_base_2(fp_int * X, int digits, fp_int * P,\n                              fp_int * Y)\n{\n  fp_digit buf, mp;\n  int      err, bitbuf, bitcpy, bitcnt, digidx, x, y;\n#ifdef WOLFSSL_SMALL_STACK\n  fp_int  *res;\n  fp_int  *tmp;\n#else\n  fp_int   res[1];\n  fp_int   tmp[1];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n  res = (fp_int*)XMALLOC(2*sizeof(fp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER);\n  if (res == NULL) {\n     return FP_MEM;\n  }\n  tmp = &res[1];\n#endif\n\n  /* now setup montgomery  */\n  if ((err = fp_montgomery_setup(P, &mp)) != FP_OKAY) {\n#ifdef WOLFSSL_SMALL_STACK\n     XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n     return err;\n  }\n\n  /* setup result */\n  fp_init(res);\n  fp_init(tmp);\n\n  fp_mul_2d(P, 1 << WINSIZE, tmp);\n\n  /* now we need R mod m */\n  fp_montgomery_calc_normalization(res, P);\n\n  /* Get the top bits left over after taking WINSIZE bits starting at the\n   * least-significant.\n   */\n  digidx = digits - 1;\n  bitcpy = (digits * DIGIT_BIT) % WINSIZE;\n  if (bitcpy > 0) {\n      bitcnt = (int)DIGIT_BIT - bitcpy;\n      buf    = X->dp[digidx--];\n      bitbuf = (int)(buf >> bitcnt);\n      /* Multiply montgomery representation of 1 by 2 ^ top */\n      fp_mul_2d(res, bitbuf, res);\n      fp_add(res, tmp, res);\n      err = fp_mod(res, P, res);\n      if (err != FP_OKAY) {\n      #ifdef WOLFSSL_SMALL_STACK\n        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n      #endif\n        return err;\n      }\n      /* Move out bits used */\n      buf  <<= bitcpy;\n      bitcnt++;\n  }\n  else {\n      bitcnt = 1;\n      buf    = 0;\n  }\n\n  /* empty window and reset  */\n  bitbuf = 0;\n  bitcpy = 0;\n\n  for (;;) {\n    /* grab next digit as required */\n    if (--bitcnt == 0) {\n      /* if digidx == -1 we are out of digits so break */\n      if (digidx == -1) {\n        break;\n      }\n      /* read next digit and reset bitcnt */\n      buf    = X->dp[digidx--];\n      bitcnt = (int)DIGIT_BIT;\n    }\n\n    /* grab the next msb from the exponent */\n    y       = (int)(buf >> (DIGIT_BIT - 1)) & 1;\n    buf   <<= (fp_digit)1;\n    /* add bit to the window */\n    bitbuf |= (y << (WINSIZE - ++bitcpy));\n\n    if (bitcpy == WINSIZE) {\n      /* ok window is filled so square as required and multiply  */\n      /* square first */\n      for (x = 0; x < WINSIZE; x++) {\n        err = fp_sqr(res, res);\n        if (err != FP_OKAY) {\n        #ifdef WOLFSSL_SMALL_STACK\n          XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n          return err;\n        }\n        err = fp_montgomery_reduce(res, P, mp);\n        if (err != FP_OKAY) {\n        #ifdef WOLFSSL_SMALL_STACK\n          XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n          return err;\n        }\n      }\n\n      /* then multiply by 2^bitbuf */\n      fp_mul_2d(res, bitbuf, res);\n      /* Add in value to make mod operation take same time */\n      fp_add(res, tmp, res);\n      err = fp_mod(res, P, res);\n      if (err != FP_OKAY) {\n      #ifdef WOLFSSL_SMALL_STACK\n        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n      #endif\n        return err;\n      }\n\n      /* empty window and reset */\n      bitcpy = 0;\n      bitbuf = 0;\n    }\n  }\n\n  /* fixup result if Montgomery reduction is used\n   * recall that any value in a Montgomery system is\n   * actually multiplied by R mod n.  So we have\n   * to reduce one more time to cancel out the factor\n   * of R.\n   */\n  err = fp_montgomery_reduce(res, P, mp);\n\n  /* swap res with Y */\n  fp_copy(res, Y);\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n  return err;\n}\n\n#undef WINSIZE\n#else\n#if DIGIT_BIT < 16\n    #define WINSIZE    3\n#elif DIGIT_BIT < 32\n    #define WINSIZE    4\n#elif DIGIT_BIT < 64\n    #define WINSIZE    5\n#elif DIGIT_BIT < 128\n    #define WINSIZE    6\n#elif DIGIT_BIT == 128\n    #define WINSIZE    7\n#endif\n\n/* y = 2**x (mod b)\n * Some restrictions... x must be positive and < b\n */\nstatic int _fp_exptmod_base_2(fp_int * X, int digits, fp_int * P,\n                              fp_int * Y)\n{\n  fp_digit buf, mp;\n  int      err, bitbuf, bitcpy, bitcnt, digidx, x, y;\n#ifdef WOLFSSL_SMALL_STACK\n  fp_int  *res;\n#else\n  fp_int   res[1];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n  res = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER);\n  if (res == NULL) {\n     return FP_MEM;\n  }\n#endif\n\n  /* now setup montgomery  */\n  if ((err = fp_montgomery_setup(P, &mp)) != FP_OKAY) {\n     return err;\n  }\n\n  /* setup result */\n  fp_init(res);\n\n  /* now we need R mod m */\n  fp_montgomery_calc_normalization(res, P);\n\n  /* Get the top bits left over after taking WINSIZE bits starting at the\n   * least-significant.\n   */\n  digidx = digits - 1;\n  bitcpy = (digits * DIGIT_BIT) % WINSIZE;\n  if (bitcpy > 0) {\n      bitcnt = (int)DIGIT_BIT - bitcpy;\n      buf    = X->dp[digidx--];\n      bitbuf = (int)(buf >> bitcnt);\n      /* Multiply montgomery representation of 1 by 2 ^ top */\n      fp_mul_2d(res, bitbuf, res);\n      err = fp_mod(res, P, res);\n      if (err != FP_OKAY) {\n      #ifdef WOLFSSL_SMALL_STACK\n        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n      #endif\n        return err;\n      }\n      /* Move out bits used */\n      buf  <<= bitcpy;\n      bitcnt++;\n  }\n  else {\n      bitcnt = 1;\n      buf    = 0;\n  }\n\n  /* empty window and reset  */\n  bitbuf = 0;\n  bitcpy = 0;\n\n  for (;;) {\n    /* grab next digit as required */\n    if (--bitcnt == 0) {\n      /* if digidx == -1 we are out of digits so break */\n      if (digidx == -1) {\n        break;\n      }\n      /* read next digit and reset bitcnt */\n      buf    = X->dp[digidx--];\n      bitcnt = (int)DIGIT_BIT;\n    }\n\n    /* grab the next msb from the exponent */\n    y       = (int)(buf >> (DIGIT_BIT - 1)) & 1;\n    buf   <<= (fp_digit)1;\n    /* add bit to the window */\n    bitbuf |= (y << (WINSIZE - ++bitcpy));\n\n    if (bitcpy == WINSIZE) {\n      /* ok window is filled so square as required and multiply  */\n      /* square first */\n      for (x = 0; x < WINSIZE; x++) {\n        err = fp_sqr(res, res);\n        if (err != FP_OKAY) {\n        #ifdef WOLFSSL_SMALL_STACK\n          XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n          return err;\n        }\n        err = fp_montgomery_reduce(res, P, mp);\n        if (err != FP_OKAY) {\n        #ifdef WOLFSSL_SMALL_STACK\n          XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n          return err;\n        }\n      }\n\n      /* then multiply by 2^bitbuf */\n      fp_mul_2d(res, bitbuf, res);\n      err = fp_mod(res, P, res);\n      if (err != FP_OKAY) {\n      #ifdef WOLFSSL_SMALL_STACK\n        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n      #endif\n        return err;\n      }\n\n      /* empty window and reset */\n      bitcpy = 0;\n      bitbuf = 0;\n    }\n  }\n\n  /* fixup result if Montgomery reduction is used\n   * recall that any value in a Montgomery system is\n   * actually multiplied by R mod n.  So we have\n   * to reduce one more time to cancel out the factor\n   * of R.\n   */\n  err = fp_montgomery_reduce(res, P, mp);\n\n  /* swap res with Y */\n  fp_copy(res, Y);\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n  return err;\n}\n\n#undef WINSIZE\n#endif\n\n\nint fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)\n{\n\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \\\n   !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)\n   int x = fp_count_bits (X);\n#endif\n\n   /* handle modulus of zero and prevent overflows */\n   if (fp_iszero(P) || (P->used > (FP_SIZE/2))) {\n      return FP_VAL;\n   }\n   if (fp_isone(P)) {\n      fp_set(Y, 0);\n      return FP_OKAY;\n   }\n   if (fp_iszero(X)) {\n      fp_set(Y, 1);\n      return FP_OKAY;\n   }\n   if (fp_iszero(G)) {\n      fp_set(Y, 0);\n      return FP_OKAY;\n   }\n\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \\\n   !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)\n   if(x > EPS_RSA_EXPT_XBTIS) {\n      return esp_mp_exptmod(G, X, x, P, Y);\n   }\n#endif\n\n   if (X->sign == FP_NEG) {\n#ifndef POSITIVE_EXP_ONLY  /* reduce stack if assume no negatives */\n      int    err;\n   #ifndef WOLFSSL_SMALL_STACK\n      fp_int tmp[2];\n   #else\n      fp_int *tmp;\n   #endif\n\n   #ifdef WOLFSSL_SMALL_STACK\n      tmp = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT);\n      if (tmp == NULL)\n          return FP_MEM;\n   #endif\n\n      /* yes, copy G and invmod it */\n      fp_init_copy(&tmp[0], G);\n      fp_init_copy(&tmp[1], P);\n      tmp[1].sign = FP_ZPOS;\n      err = fp_invmod(&tmp[0], &tmp[1], &tmp[0]);\n      if (err == FP_OKAY) {\n         fp_copy(X, &tmp[1]);\n         tmp[1].sign = FP_ZPOS;\n         err =  _fp_exptmod(&tmp[0], &tmp[1], tmp[1].used, P, Y);\n         if (P->sign == FP_NEG) {\n            fp_add(Y, P, Y);\n         }\n      }\n   #ifdef WOLFSSL_SMALL_STACK\n      XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n   #endif\n      return err;\n#else\n      return FP_VAL;\n#endif\n   }\n   else if (G->used == 1 && G->dp[0] == 2) {\n      return _fp_exptmod_base_2(X, X->used, P, Y);\n   }\n   else {\n      /* Positive exponent so just exptmod */\n      return _fp_exptmod(G, X, X->used, P, Y);\n   }\n}\n\nint fp_exptmod_ex(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y)\n{\n\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \\\n   !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)\n   int x = fp_count_bits (X);\n#endif\n\n   if (fp_iszero(G)) {\n      fp_set(G, 0);\n      return FP_OKAY;\n   }\n\n   /* prevent overflows */\n   if (P->used > (FP_SIZE/2)) {\n      return FP_VAL;\n   }\n\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \\\n   !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)\n   if(x > EPS_RSA_EXPT_XBTIS) {\n      return esp_mp_exptmod(G, X, x, P, Y);\n   }\n#endif\n\n   if (X->sign == FP_NEG) {\n#ifndef POSITIVE_EXP_ONLY  /* reduce stack if assume no negatives */\n      int    err;\n   #ifndef WOLFSSL_SMALL_STACK\n      fp_int tmp[2];\n   #else\n      fp_int *tmp;\n   #endif\n\n   #ifdef WOLFSSL_SMALL_STACK\n      tmp = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n      if (tmp == NULL)\n          return FP_MEM;\n   #endif\n\n      /* yes, copy G and invmod it */\n      fp_init_copy(&tmp[0], G);\n      fp_init_copy(&tmp[1], P);\n      tmp[1].sign = FP_ZPOS;\n      err = fp_invmod(&tmp[0], &tmp[1], &tmp[0]);\n      if (err == FP_OKAY) {\n         X->sign = FP_ZPOS;\n         err =  _fp_exptmod(&tmp[0], X, digits, P, Y);\n         if (X != Y) {\n            X->sign = FP_NEG;\n         }\n         if (P->sign == FP_NEG) {\n            fp_add(Y, P, Y);\n         }\n      }\n   #ifdef WOLFSSL_SMALL_STACK\n      XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);\n   #endif\n      return err;\n#else\n      return FP_VAL;\n#endif\n   }\n   else {\n      /* Positive exponent so just exptmod */\n      return _fp_exptmod(G, X, digits, P, Y);\n   }\n}\n\n\n/* computes a = 2**b */\nvoid fp_2expt(fp_int *a, int b)\n{\n   int     z;\n\n   /* zero a as per default */\n   fp_zero (a);\n\n   if (b < 0) {\n      return;\n   }\n\n   z = b / DIGIT_BIT;\n   if (z >= FP_SIZE) {\n      return;\n   }\n\n  /* set the used count of where the bit will go */\n  a->used = z + 1;\n\n  /* put the single bit in its place */\n  a->dp[z] = ((fp_digit)1) << (b % DIGIT_BIT);\n}\n\n/* b = a*a  */\nint fp_sqr(fp_int *A, fp_int *B)\n{\n    int err;\n    int y, oldused;\n\n    oldused = B->used;\n    y = A->used;\n\n    /* call generic if we're out of range */\n    if (y + y > FP_SIZE) {\n       err = fp_sqr_comba(A, B);\n       goto clean;\n    }\n\n#if defined(TFM_SQR3) && FP_SIZE >= 6\n        if (y <= 3) {\n           err = fp_sqr_comba3(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SQR4) && FP_SIZE >= 8\n        if (y == 4) {\n           err = fp_sqr_comba4(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SQR6) && FP_SIZE >= 12\n        if (y <= 6) {\n           err = fp_sqr_comba6(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SQR7) && FP_SIZE >= 14\n        if (y == 7) {\n           err = fp_sqr_comba7(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SQR8) && FP_SIZE >= 16\n        if (y == 8) {\n           err = fp_sqr_comba8(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SQR9) && FP_SIZE >= 18\n        if (y == 9) {\n           err = fp_sqr_comba9(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SQR12) && FP_SIZE >= 24\n        if (y <= 12) {\n           err = fp_sqr_comba12(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SQR17) && FP_SIZE >= 34\n        if (y <= 17) {\n           err = fp_sqr_comba17(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SMALL_SET)\n        if (y <= 16) {\n           err = fp_sqr_comba_small(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SQR20) && FP_SIZE >= 40\n        if (y <= 20) {\n           err = fp_sqr_comba20(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SQR24) && FP_SIZE >= 48\n        if (y <= 24) {\n           err = fp_sqr_comba24(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SQR28) && FP_SIZE >= 56\n        if (y <= 28) {\n           err = fp_sqr_comba28(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SQR32) && FP_SIZE >= 64\n        if (y <= 32) {\n           err = fp_sqr_comba32(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SQR48) && FP_SIZE >= 96\n        if (y <= 48) {\n           err = fp_sqr_comba48(A,B);\n           goto clean;\n        }\n#endif\n#if defined(TFM_SQR64) && FP_SIZE >= 128\n        if (y <= 64) {\n           err = fp_sqr_comba64(A,B);\n           goto clean;\n        }\n#endif\n       err = fp_sqr_comba(A, B);\n\nclean:\n  /* zero any excess digits on the destination that we didn't write to */\n  for (y = B->used; y >= 0 && y < oldused; y++) {\n    B->dp[y] = 0;\n  }\n\n  return err;\n}\n\n/* generic comba squarer */\nint fp_sqr_comba(fp_int *A, fp_int *B)\n{\n  int       pa, ix, iz;\n  fp_digit  c0, c1, c2;\n#ifdef TFM_ISO\n  fp_word   tt;\n#endif\n   fp_int    *dst;\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int    tmp[1];\n#else\n   fp_int    *tmp;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n   if (tmp == NULL)\n       return FP_MEM;\n#endif\n\n  /* get size of output and trim */\n  pa = A->used + A->used;\n  if (pa >= FP_SIZE) {\n     pa = FP_SIZE-1;\n  }\n\n  /* number of output digits to produce */\n  COMBA_START;\n  COMBA_CLEAR;\n\n  if (A == B) {\n     fp_init(tmp);\n     dst = tmp;\n  } else {\n     fp_zero(B);\n     dst = B;\n  }\n\n  for (ix = 0; ix < pa; ix++) {\n      int      tx, ty, iy;\n      fp_digit *tmpy, *tmpx;\n\n      /* get offsets into the two bignums */\n      ty = MIN(A->used-1, ix);\n      tx = ix - ty;\n\n      /* setup temp aliases */\n      tmpx = A->dp + tx;\n      tmpy = A->dp + ty;\n\n      /* this is the number of times the loop will iterate,\n         while (tx++ < a->used && ty-- >= 0) { ... }\n       */\n      iy = MIN(A->used-tx, ty+1);\n\n      /* now for squaring tx can never equal ty\n       * we halve the distance since they approach\n       * at a rate of 2x and we have to round because\n       * odd cases need to be executed\n       */\n      iy = MIN(iy, (ty-tx+1)>>1);\n\n      /* forward carries */\n      COMBA_FORWARD;\n\n      /* execute loop */\n      for (iz = 0; iz < iy; iz++) {\n          SQRADD2(*tmpx++, *tmpy--);\n      }\n\n      /* even columns have the square term in them */\n      if ((ix&1) == 0) {\n          /* TAO change COMBA_ADD back to SQRADD */\n          SQRADD(A->dp[ix>>1], A->dp[ix>>1]);\n      }\n\n      /* store it */\n      COMBA_STORE(dst->dp[ix]);\n  }\n\n  COMBA_FINI;\n\n  /* setup dest */\n  dst->used = pa;\n  fp_clamp (dst);\n  if (dst != B) {\n     fp_copy(dst, B);\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return FP_OKAY;\n}\n\nint fp_cmp(fp_int *a, fp_int *b)\n{\n   if (a->sign == FP_NEG && b->sign == FP_ZPOS) {\n      return FP_LT;\n   } else if (a->sign == FP_ZPOS && b->sign == FP_NEG) {\n      return FP_GT;\n   } else {\n      /* compare digits */\n      if (a->sign == FP_NEG) {\n         /* if negative compare opposite direction */\n         return fp_cmp_mag(b, a);\n      } else {\n         return fp_cmp_mag(a, b);\n      }\n   }\n}\n\n/* compare against a single digit */\nint fp_cmp_d(fp_int *a, fp_digit b)\n{\n  /* special case for zero*/\n  if (a->used == 0 && b == 0)\n    return FP_EQ;\n\n  /* compare based on sign */\n  if ((b && a->used == 0) || a->sign == FP_NEG) {\n    return FP_LT;\n  }\n\n  /* compare based on magnitude */\n  if (a->used > 1) {\n    return FP_GT;\n  }\n\n  /* compare the only digit of a to b */\n  if (a->dp[0] > b) {\n    return FP_GT;\n  } else if (a->dp[0] < b) {\n    return FP_LT;\n  } else {\n    return FP_EQ;\n  }\n\n}\n\nint fp_cmp_mag(fp_int *a, fp_int *b)\n{\n   int x;\n\n   if (a->used > b->used) {\n      return FP_GT;\n   } else if (a->used < b->used) {\n      return FP_LT;\n   } else {\n      for (x = a->used - 1; x >= 0; x--) {\n          if (a->dp[x] > b->dp[x]) {\n             return FP_GT;\n          } else if (a->dp[x] < b->dp[x]) {\n             return FP_LT;\n          }\n      }\n   }\n   return FP_EQ;\n}\n\n/* sets up the montgomery reduction */\nint fp_montgomery_setup(fp_int *a, fp_digit *rho)\n{\n  fp_digit x, b;\n\n/* fast inversion mod 2**k\n *\n * Based on the fact that\n *\n * XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)\n *                    =>  2*X*A - X*X*A*A = 1\n *                    =>  2*(1) - (1)     = 1\n */\n  b = a->dp[0];\n\n  if ((b & 1) == 0) {\n    return FP_VAL;\n  }\n\n  x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */\n  x *= 2 - b * x;               /* here x*a==1 mod 2**8 */\n  x *= 2 - b * x;               /* here x*a==1 mod 2**16 */\n  x *= 2 - b * x;               /* here x*a==1 mod 2**32 */\n#ifdef FP_64BIT\n  x *= 2 - b * x;               /* here x*a==1 mod 2**64 */\n#endif\n\n  /* rho = -1/m mod b */\n  *rho = (fp_digit) (((fp_word) 1 << ((fp_word) DIGIT_BIT)) - ((fp_word)x));\n\n  return FP_OKAY;\n}\n\n/* computes a = B**n mod b without division or multiplication useful for\n * normalizing numbers in a Montgomery system.\n */\nvoid fp_montgomery_calc_normalization(fp_int *a, fp_int *b)\n{\n  int     x, bits;\n\n  /* how many bits of last digit does b use */\n  bits = fp_count_bits (b) % DIGIT_BIT;\n  if (!bits) bits = DIGIT_BIT;\n\n  /* compute A = B^(n-1) * 2^(bits-1) */\n  if (b->used > 1) {\n     fp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1);\n  } else {\n     fp_set(a, 1);\n     bits = 1;\n  }\n\n  /* now compute C = A * B mod b */\n  for (x = bits - 1; x < (int)DIGIT_BIT; x++) {\n    fp_mul_2 (a, a);\n    if (fp_cmp_mag (a, b) != FP_LT) {\n      s_fp_sub (a, b, a);\n    }\n  }\n}\n\n\n#ifdef TFM_SMALL_MONT_SET\n    #include \"fp_mont_small.i\"\n#endif\n\n#ifdef HAVE_INTEL_MULX\nstatic WC_INLINE void innermul8_mulx(fp_digit *c_mulx, fp_digit *cy_mulx, fp_digit *tmpm, fp_digit mu)\n{\n    fp_digit cy = *cy_mulx ;\n    INNERMUL8_MULX ;\n    *cy_mulx = cy ;\n}\n\n/* computes x/R == x (mod N) via Montgomery Reduction */\nstatic int fp_montgomery_reduce_mulx(fp_int *a, fp_int *m, fp_digit mp)\n{\n#ifndef WOLFSSL_SMALL_STACK\n   fp_digit c[FP_SIZE+1];\n#else\n   fp_digit *c;\n#endif\n   fp_digit *_c, *tmpm, mu = 0;\n   int      oldused, x, y, pa;\n\n   /* bail if too large */\n   if (m->used > (FP_SIZE/2)) {\n      (void)mu;                     /* shut up compiler */\n      return FP_OKAY;\n   }\n\n#ifdef TFM_SMALL_MONT_SET\n   if (m->used <= 16) {\n      return fp_montgomery_reduce_small(a, m, mp);\n   }\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   /* only allocate space for what's needed for window plus res */\n   c = (fp_digit*)XMALLOC(sizeof(fp_digit)*(FP_SIZE + 1), NULL, DYNAMIC_TYPE_BIGINT);\n   if (c == NULL) {\n      return FP_MEM;\n   }\n#endif\n\n   /* now zero the buff */\n   XMEMSET(c, 0, sizeof(fp_digit)*(FP_SIZE + 1));\n   pa = m->used;\n\n   /* copy the input */\n   oldused = a->used;\n   for (x = 0; x < oldused; x++) {\n       c[x] = a->dp[x];\n   }\n   MONT_START;\n\n   for (x = 0; x < pa; x++) {\n       fp_digit cy = 0;\n       /* get Mu for this round */\n       LOOP_START;\n       _c   = c + x;\n       tmpm = m->dp;\n       y = 0;\n        for (; y < (pa & ~7); y += 8) {\n              innermul8_mulx(_c, &cy, tmpm, mu) ;\n              _c   += 8;\n              tmpm += 8;\n           }\n       for (; y < pa; y++) {\n          INNERMUL;\n          ++_c;\n       }\n       LOOP_END;\n       while (cy) {\n           PROPCARRY;\n           ++_c;\n       }\n  }\n\n  /* now copy out */\n  _c   = c + pa;\n  tmpm = a->dp;\n  for (x = 0; x < pa+1; x++) {\n     *tmpm++ = *_c++;\n  }\n\n  /* zero any excess digits on the destination that we didn't write to */\n  for (; x < oldused; x++) {\n     *tmpm++ = 0;\n  }\n\n  MONT_FINI;\n\n  a->used = pa+1;\n  fp_clamp(a);\n\n  /* if A >= m then A = A - m */\n  if (fp_cmp_mag (a, m) != FP_LT) {\n    s_fp_sub (a, m, a);\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(c, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return FP_OKAY;\n}\n#endif\n\n/* computes x/R == x (mod N) via Montgomery Reduction */\nint fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp)\n{\n#ifndef WOLFSSL_SMALL_STACK\n   fp_digit c[FP_SIZE+1];\n#else\n   fp_digit *c;\n#endif\n   fp_digit *_c, *tmpm, mu = 0;\n   int      oldused, x, y, pa, err = 0;\n\n   IF_HAVE_INTEL_MULX(err = fp_montgomery_reduce_mulx(a, m, mp), return err) ;\n   (void)err;\n\n   /* bail if too large */\n   if (m->used > (FP_SIZE/2)) {\n      (void)mu;                     /* shut up compiler */\n      return FP_OKAY;\n   }\n\n#ifdef TFM_SMALL_MONT_SET\n   if (m->used <= 16) {\n      return fp_montgomery_reduce_small(a, m, mp);\n   }\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   /* only allocate space for what's needed for window plus res */\n   c = (fp_digit*)XMALLOC(sizeof(fp_digit)*(FP_SIZE + 1), NULL, DYNAMIC_TYPE_BIGINT);\n   if (c == NULL) {\n      return FP_MEM;\n   }\n#endif\n\n   /* now zero the buff */\n   XMEMSET(c, 0, sizeof(fp_digit)*(FP_SIZE + 1));\n   pa = m->used;\n\n   /* copy the input */\n   oldused = a->used;\n   for (x = 0; x < oldused; x++) {\n       c[x] = a->dp[x];\n   }\n   MONT_START;\n\n   for (x = 0; x < pa; x++) {\n       fp_digit cy = 0;\n       /* get Mu for this round */\n       LOOP_START;\n       _c   = c + x;\n       tmpm = m->dp;\n       y = 0;\n#if defined(INNERMUL8)\n        for (; y < (pa & ~7); y += 8) {\n              INNERMUL8 ;\n              _c   += 8;\n              tmpm += 8;\n           }\n#endif\n       for (; y < pa; y++) {\n          INNERMUL;\n          ++_c;\n       }\n       LOOP_END;\n       while (cy) {\n           PROPCARRY;\n           ++_c;\n       }\n  }\n\n  /* now copy out */\n  _c   = c + pa;\n  tmpm = a->dp;\n  for (x = 0; x < pa+1; x++) {\n     *tmpm++ = *_c++;\n  }\n\n  /* zero any excess digits on the destination that we didn't write to */\n  for (; x < oldused; x++) {\n     *tmpm++ = 0;\n  }\n\n  MONT_FINI;\n\n  a->used = pa+1;\n  fp_clamp(a);\n\n  /* if A >= m then A = A - m */\n  if (fp_cmp_mag (a, m) != FP_LT) {\n    s_fp_sub (a, m, a);\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(c, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return FP_OKAY;\n}\n\nvoid fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c)\n{\n#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)\n  const word32 maxC = (a->size * sizeof(fp_digit));\n#else\n  const word32 maxC = (FP_SIZE * sizeof(fp_digit));\n#endif\n\n  /* zero the int */\n  fp_zero (a);\n\n  /* if input b excess max, then truncate */\n  if (c > 0 && (word32)c > maxC) {\n     int excess = (c - maxC);\n     c -= excess;\n     b += excess;\n  }\n\n  /* If we know the endianness of this architecture, and we're using\n     32-bit fp_digits, we can optimize this */\n#if (defined(LITTLE_ENDIAN_ORDER) || defined(BIG_ENDIAN_ORDER)) && \\\n    defined(FP_32BIT)\n  /* But not for both simultaneously */\n#if defined(LITTLE_ENDIAN_ORDER) && defined(BIG_ENDIAN_ORDER)\n#error Both LITTLE_ENDIAN_ORDER and BIG_ENDIAN_ORDER defined.\n#endif\n  {\n     unsigned char *pd = (unsigned char *)a->dp;\n\n     a->used = (c + sizeof(fp_digit) - 1)/sizeof(fp_digit);\n     /* read the bytes in */\n#ifdef BIG_ENDIAN_ORDER\n     {\n       /* Use Duff's device to unroll the loop. */\n       int idx = (c - 1) & ~3;\n       switch (c % 4) {\n       case 0:    do { pd[idx+0] = *b++; // fallthrough\n       case 3:         pd[idx+1] = *b++; // fallthrough\n       case 2:         pd[idx+2] = *b++; // fallthrough\n       case 1:         pd[idx+3] = *b++; // fallthrough\n                     idx -= 4;\n                 } while ((c -= 4) > 0);\n       }\n     }\n#else\n     for (c -= 1; c >= 0; c -= 1) {\n       pd[c] = *b++;\n     }\n#endif\n  }\n#else\n  /* read the bytes in */\n  for (; c > 0; c--) {\n     fp_mul_2d (a, 8, a);\n     a->dp[0] |= *b++;\n\n     if (a->used == 0) {\n         a->used = 1;\n     }\n  }\n#endif\n  fp_clamp (a);\n}\n\nint fp_to_unsigned_bin_at_pos(int x, fp_int *t, unsigned char *b)\n{\n#if DIGIT_BIT == 64 || DIGIT_BIT == 32\n   int i, j;\n   fp_digit n;\n\n   for (j=0,i=0; i<t->used-1; ) {\n       b[x++] = (unsigned char)(t->dp[i] >> j);\n       j += 8;\n       i += j == DIGIT_BIT;\n       j &= DIGIT_BIT - 1;\n   }\n   n = t->dp[i];\n   while (n != 0) {\n       b[x++] = (unsigned char)n;\n       n >>= 8;\n   }\n   return x;\n#else\n   while (fp_iszero (t) == FP_NO) {\n      b[x++] = (unsigned char) (t->dp[0] & 255);\n      fp_div_2d (t, 8, t, NULL);\n  }\n  return x;\n#endif\n}\n\nint fp_to_unsigned_bin(fp_int *a, unsigned char *b)\n{\n  int     x;\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int t[1];\n#else\n   fp_int *t;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n   if (t == NULL)\n       return FP_MEM;\n#endif\n\n  fp_init_copy(t, a);\n\n  x = fp_to_unsigned_bin_at_pos(0, t, b);\n  fp_reverse (b, x);\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return FP_OKAY;\n}\n\nint fp_to_unsigned_bin_len(fp_int *a, unsigned char *b, int c)\n{\n#if DIGIT_BIT == 64 || DIGIT_BIT == 32\n  int i, j, x;\n\n  for (x=c-1,j=0,i=0; x >= 0; x--) {\n     b[x] = (unsigned char)(a->dp[i] >> j);\n     j += 8;\n     i += j == DIGIT_BIT;\n     j &= DIGIT_BIT - 1;\n  }\n\n  return FP_OKAY;\n#else\n  int     x;\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int t[1];\n#else\n   fp_int *t;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n   if (t == NULL)\n       return FP_MEM;\n#endif\n\n  fp_init_copy(t, a);\n\n  for (x = 0; x < c; x++) {\n      b[x] = (unsigned char) (t->dp[0] & 255);\n      fp_div_2d (t, 8, t, NULL);\n  }\n  fp_reverse (b, x);\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return FP_OKAY;\n#endif\n}\n\nint fp_unsigned_bin_size(fp_int *a)\n{\n  int     size = fp_count_bits (a);\n  return (size / 8 + ((size & 7) != 0 ? 1 : 0));\n}\n\nvoid fp_set(fp_int *a, fp_digit b)\n{\n   fp_zero(a);\n   a->dp[0] = b;\n   a->used  = a->dp[0] ? 1 : 0;\n}\n\n\n#ifndef MP_SET_CHUNK_BITS\n    #define MP_SET_CHUNK_BITS 4\n#endif\nvoid fp_set_int(fp_int *a, unsigned long b)\n{\n  int x;\n\n  /* use direct fp_set if b is less than fp_digit max */\n  if (b < FP_DIGIT_MAX) {\n    fp_set (a, (fp_digit)b);\n    return;\n  }\n\n  fp_zero (a);\n\n  /* set chunk bits at a time */\n  for (x = 0; x < (int)(sizeof(b) * 8) / MP_SET_CHUNK_BITS; x++) {\n    fp_mul_2d (a, MP_SET_CHUNK_BITS, a);\n\n    /* OR in the top bits of the source */\n    a->dp[0] |= (b >> ((sizeof(b) * 8) - MP_SET_CHUNK_BITS)) &\n                                  ((1 << MP_SET_CHUNK_BITS) - 1);\n\n    /* shift the source up to the next chunk bits */\n    b <<= MP_SET_CHUNK_BITS;\n\n    /* ensure that digits are not clamped off */\n    a->used += 1;\n  }\n\n  /* clamp digits */\n  fp_clamp(a);\n}\n\n/* check if a bit is set */\nint fp_is_bit_set (fp_int *a, fp_digit b)\n{\n    fp_digit i;\n\n    if (b > FP_MAX_BITS)\n        return 0;\n    else\n        i = b/DIGIT_BIT;\n\n    if ((fp_digit)a->used < i)\n        return 0;\n\n    return (int)((a->dp[i] >> b%DIGIT_BIT) & (fp_digit)1);\n}\n\n/* set the b bit of a */\nint fp_set_bit (fp_int * a, fp_digit b)\n{\n    fp_digit i;\n\n    if (b > FP_MAX_BITS)\n        return 0;\n    else\n        i = b/DIGIT_BIT;\n\n    /* set the used count of where the bit will go if required */\n    if (a->used < (int)(i+1))\n        a->used = (int)(i+1);\n\n    /* put the single bit in its place */\n    a->dp[i] |= ((fp_digit)1) << (b % DIGIT_BIT);\n\n    return MP_OKAY;\n}\n\nint fp_count_bits (fp_int * a)\n{\n  int     r;\n  fp_digit q;\n\n  /* shortcut */\n  if (a->used == 0) {\n    return 0;\n  }\n\n  /* get number of digits and add that */\n  r = (a->used - 1) * DIGIT_BIT;\n\n  /* take the last digit and count the bits in it */\n  q = a->dp[a->used - 1];\n  while (q > ((fp_digit) 0)) {\n    ++r;\n    q >>= ((fp_digit) 1);\n  }\n\n  return r;\n}\n\nint fp_leading_bit(fp_int *a)\n{\n    int bit = 0;\n\n    if (a->used != 0) {\n        fp_digit q = a->dp[a->used - 1];\n        int qSz = sizeof(fp_digit);\n\n        while (qSz > 0) {\n            if ((unsigned char)q != 0)\n                bit = (q & 0x80) != 0;\n            q >>= 8;\n            qSz--;\n        }\n    }\n\n    return bit;\n}\n\nvoid fp_lshd(fp_int *a, int x)\n{\n    int y;\n\n    /* move up and truncate as required */\n    y = MIN(a->used + x - 1, (int)(FP_SIZE-1));\n\n    /* store new size */\n    a->used = y + 1;\n\n    /* move digits */\n    for (; y >= x; y--) {\n        a->dp[y] = a->dp[y-x];\n    }\n\n    /* zero lower digits */\n    for (; y >= 0; y--) {\n        a->dp[y] = 0;\n    }\n\n    /* clamp digits */\n    fp_clamp(a);\n}\n\n\n/* right shift by bit count */\nvoid fp_rshb(fp_int *c, int x)\n{\n    fp_digit *tmpc, mask, shift;\n    fp_digit r, rr;\n    fp_digit D = x;\n\n    if (fp_iszero(c)) return;\n\n    /* mask */\n    mask = (((fp_digit)1) << D) - 1;\n\n    /* shift for lsb */\n    shift = DIGIT_BIT - D;\n\n    /* alias */\n    tmpc = c->dp + (c->used - 1);\n\n    /* carry */\n    r = 0;\n    for (x = c->used - 1; x >= 0; x--) {\n      /* get the lower  bits of this word in a temp */\n      rr = *tmpc & mask;\n\n      /* shift the current word and mix in the carry bits from previous word */\n      *tmpc = (*tmpc >> D) | (r << shift);\n      --tmpc;\n\n      /* set the carry to the carry bits of the current word found above */\n      r = rr;\n    }\n\n    /* clamp digits */\n    fp_clamp(c);\n}\n\n\nvoid fp_rshd(fp_int *a, int x)\n{\n  int y;\n\n  /* too many digits just zero and return */\n  if (x >= a->used) {\n     fp_zero(a);\n     return;\n  }\n\n   /* shift */\n   for (y = 0; y < a->used - x; y++) {\n      a->dp[y] = a->dp[y+x];\n   }\n\n   /* zero rest */\n   for (; y < a->used; y++) {\n      a->dp[y] = 0;\n   }\n\n   /* decrement count */\n   a->used -= x;\n   fp_clamp(a);\n}\n\n/* reverse an array, used for radix code */\nvoid fp_reverse (unsigned char *s, int len)\n{\n  int     ix, iy;\n  unsigned char t;\n\n  ix = 0;\n  iy = len - 1;\n  while (ix < iy) {\n    t     = s[ix];\n    s[ix] = s[iy];\n    s[iy] = t;\n    ++ix;\n    --iy;\n  }\n}\n\n\n/* c = a - b */\nint fp_sub_d(fp_int *a, fp_digit b, fp_int *c)\n{\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int    tmp[1];\n#else\n   fp_int    *tmp;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n   if (tmp == NULL)\n       return FP_MEM;\n#endif\n\n   fp_init(tmp);\n   fp_set(tmp, b);\n#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)\n   if (c->size < FP_SIZE) {\n     fp_sub(a, tmp, tmp);\n     fp_copy(tmp, c);\n   } else\n#endif\n   {\n     fp_sub(a, tmp, c);\n   }\n\n#ifdef WOLFSSL_SMALL_STACK\n   XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n   return FP_OKAY;\n}\n\n\n/* wolfSSL callers from normal lib */\n\n/* init a new mp_int */\nint mp_init (mp_int * a)\n{\n  if (a)\n    fp_init(a);\n  return MP_OKAY;\n}\n\nvoid fp_init(fp_int *a)\n{\n#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)\n    a->size = FP_SIZE;\n#endif\n#ifdef HAVE_WOLF_BIGINT\n    wc_bigint_init(&a->raw);\n#endif\n    fp_zero(a);\n}\n\nvoid fp_zero(fp_int *a)\n{\n    int size = FP_SIZE;\n    a->used = 0;\n    a->sign = FP_ZPOS;\n#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)\n    size = a->size;\n#endif\n    XMEMSET(a->dp, 0, size * sizeof(fp_digit));\n}\n\nvoid fp_clear(fp_int *a)\n{\n    int size = FP_SIZE;\n    a->used = 0;\n    a->sign = FP_ZPOS;\n#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)\n    size = a->size;\n#endif\n    XMEMSET(a->dp, 0, size * sizeof(fp_digit));\n    fp_free(a);\n}\n\nvoid fp_forcezero (mp_int * a)\n{\n    int size = FP_SIZE;\n    a->used = 0;\n    a->sign = FP_ZPOS;\n#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)\n    size = a->size;\n#endif\n    ForceZero(a->dp, size * sizeof(fp_digit));\n#ifdef HAVE_WOLF_BIGINT\n    wc_bigint_zero(&a->raw);\n#endif\n    fp_free(a);\n}\n\nvoid mp_forcezero (mp_int * a)\n{\n    fp_forcezero(a);\n}\n\nvoid fp_free(fp_int* a)\n{\n#ifdef HAVE_WOLF_BIGINT\n    wc_bigint_free(&a->raw);\n#else\n    (void)a;\n#endif\n}\n\n\n/* clear one (frees)  */\nvoid mp_clear (mp_int * a)\n{\n    if (a == NULL)\n        return;\n    fp_clear(a);\n}\n\nvoid mp_free(mp_int* a)\n{\n    fp_free(a);\n}\n\n/* handle up to 6 inits */\nint mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d,\n                  mp_int* e, mp_int* f)\n{\n    if (a)\n        fp_init(a);\n    if (b)\n        fp_init(b);\n    if (c)\n        fp_init(c);\n    if (d)\n        fp_init(d);\n    if (e)\n        fp_init(e);\n    if (f)\n        fp_init(f);\n\n    return MP_OKAY;\n}\n\n/* high level addition (handles signs) */\nint mp_add (mp_int * a, mp_int * b, mp_int * c)\n{\n  fp_add(a, b, c);\n  return MP_OKAY;\n}\n\n/* high level subtraction (handles signs) */\nint mp_sub (mp_int * a, mp_int * b, mp_int * c)\n{\n  fp_sub(a, b, c);\n  return MP_OKAY;\n}\n\n/* high level multiplication (handles sign) */\n#if defined(FREESCALE_LTC_TFM)\nint wolfcrypt_mp_mul(mp_int * a, mp_int * b, mp_int * c)\n#else\nint mp_mul (mp_int * a, mp_int * b, mp_int * c)\n#endif\n{\n  return fp_mul(a, b, c);\n}\n\nint mp_mul_d (mp_int * a, mp_digit b, mp_int * c)\n{\n  fp_mul_d(a, b, c);\n  return MP_OKAY;\n}\n\n/* d = a * b (mod c) */\n#if defined(FREESCALE_LTC_TFM)\nint wolfcrypt_mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)\n#else\nint mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)\n#endif\n{\n #if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)\n    int A = fp_count_bits (a);\n    int B = fp_count_bits (b);\n\n    if( A >= ESP_RSA_MULM_BITS && B >= ESP_RSA_MULM_BITS)\n        return esp_mp_mulmod(a, b, c, d);\n    else\n #endif\n   return fp_mulmod(a, b, c, d);\n}\n\n/* d = a - b (mod c) */\nint mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d)\n{\n  return fp_submod(a, b, c, d);\n}\n\n/* d = a + b (mod c) */\nint mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d)\n{\n  return fp_addmod(a, b, c, d);\n}\n\n/* c = a mod b, 0 <= c < b */\n#if defined(FREESCALE_LTC_TFM)\nint wolfcrypt_mp_mod (mp_int * a, mp_int * b, mp_int * c)\n#else\nint mp_mod (mp_int * a, mp_int * b, mp_int * c)\n#endif\n{\n  return fp_mod (a, b, c);\n}\n\n/* hac 14.61, pp608 */\n#if defined(FREESCALE_LTC_TFM)\nint wolfcrypt_mp_invmod (mp_int * a, mp_int * b, mp_int * c)\n#else\nint mp_invmod (mp_int * a, mp_int * b, mp_int * c)\n#endif\n{\n  return fp_invmod(a, b, c);\n}\n\n/* this is a shell function that calls either the normal or Montgomery\n * exptmod functions.  Originally the call to the montgomery code was\n * embedded in the normal function but that wasted alot of stack space\n * for nothing (since 99% of the time the Montgomery code would be called)\n */\n#if defined(FREESCALE_LTC_TFM)\nint wolfcrypt_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)\n#else\nint mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)\n#endif\n{\n  return fp_exptmod(G, X, P, Y);\n}\n\nint mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P, mp_int * Y)\n{\n  return fp_exptmod_ex(G, X, digits, P, Y);\n}\n\n/* compare two ints (signed)*/\nint mp_cmp (mp_int * a, mp_int * b)\n{\n  return fp_cmp(a, b);\n}\n\n/* compare a digit */\nint mp_cmp_d(mp_int * a, mp_digit b)\n{\n  return fp_cmp_d(a, b);\n}\n\n/* get the size for an unsigned equivalent */\nint mp_unsigned_bin_size (mp_int * a)\n{\n  return fp_unsigned_bin_size(a);\n}\n\nint mp_to_unsigned_bin_at_pos(int x, fp_int *t, unsigned char *b)\n{\n    return fp_to_unsigned_bin_at_pos(x, t, b);\n}\n\n/* store in unsigned [big endian] format */\nint mp_to_unsigned_bin (mp_int * a, unsigned char *b)\n{\n  return fp_to_unsigned_bin(a,b);\n}\n\nint mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c)\n{\n  return fp_to_unsigned_bin_len(a, b, c);\n}\n/* reads a unsigned char array, assumes the msb is stored first [big endian] */\nint mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)\n{\n  fp_read_unsigned_bin(a, b, c);\n  return MP_OKAY;\n}\n\n\nint mp_sub_d(fp_int *a, fp_digit b, fp_int *c)\n{\n    return fp_sub_d(a, b, c);\n}\n\nint mp_mul_2d(fp_int *a, int b, fp_int *c)\n{\n    fp_mul_2d(a, b, c);\n\treturn MP_OKAY;\n}\n\nint mp_2expt(fp_int* a, int b)\n{\n    fp_2expt(a, b);\n    return MP_OKAY;\n}\n\nint mp_div(fp_int * a, fp_int * b, fp_int * c, fp_int * d)\n{\n    return fp_div(a, b, c, d);\n}\n\nint mp_div_2d(fp_int* a, int b, fp_int* c, fp_int* d)\n{\n    fp_div_2d(a, b, c, d);\n    return MP_OKAY;\n}\n\nvoid fp_copy(fp_int *a, fp_int *b)\n{\n    /* if source and destination are different */\n    if (a != b) {\n#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)\n        /* verify a will fit in b */\n        if (b->size >= a->used) {\n            int x, oldused;\n            oldused = b->used;\n            b->used = a->used;\n            b->sign = a->sign;\n\n            XMEMCPY(b->dp, a->dp, a->used * sizeof(fp_digit));\n\n            /* zero any excess digits on the destination that we didn't write to */\n            for (x = b->used; x >= 0 && x < oldused; x++) {\n                b->dp[x] = 0;\n            }\n        }\n        else {\n            /* TODO: Handle error case */\n        }\n#else\n        /* all dp's are same size, so do straight copy */\n        b->used = a->used;\n        b->sign = a->sign;\n        XMEMCPY(b->dp, a->dp, FP_SIZE * sizeof(fp_digit));\n#endif\n    }\n}\n\nvoid fp_init_copy(fp_int *a, fp_int* b)\n{\n    if (a != b) {\n        fp_init(a);\n        fp_copy(b, a);\n    }\n}\n\n/* fast math wrappers */\nint mp_copy(fp_int* a, fp_int* b)\n{\n    fp_copy(a, b);\n    return MP_OKAY;\n}\n\nint mp_isodd(mp_int* a)\n{\n    return fp_isodd(a);\n}\n\nint mp_iszero(mp_int* a)\n{\n    return fp_iszero(a);\n}\n\nint mp_count_bits (mp_int* a)\n{\n    return fp_count_bits(a);\n}\n\nint mp_leading_bit (mp_int* a)\n{\n    return fp_leading_bit(a);\n}\n\nvoid mp_rshb (mp_int* a, int x)\n{\n    fp_rshb(a, x);\n}\n\nvoid mp_rshd (mp_int* a, int x)\n{\n    fp_rshd(a, x);\n}\n\nint mp_set_int(mp_int *a, unsigned long b)\n{\n    fp_set_int(a, b);\n    return MP_OKAY;\n}\n\nint mp_is_bit_set (mp_int *a, mp_digit b)\n{\n    return fp_is_bit_set(a, b);\n}\n\nint mp_set_bit(mp_int *a, mp_digit b)\n{\n    return fp_set_bit(a, b);\n}\n\n#if defined(WOLFSSL_KEY_GEN) || defined (HAVE_ECC) || !defined(NO_DH) || \\\n    !defined(NO_DSA) || !defined(NO_RSA)\n\n/* c = a * a (mod b) */\nint fp_sqrmod(fp_int *a, fp_int *b, fp_int *c)\n{\n  int err;\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int t[1];\n#else\n   fp_int *t;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n   if (t == NULL)\n       return FP_MEM;\n#endif\n\n  fp_init(t);\n  err = fp_sqr(a, t);\n  if (err == FP_OKAY) {\n  #if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)\n    if (c->size < FP_SIZE) {\n      err = fp_mod(t, b, t);\n      fp_copy(t, c);\n    }\n    else\n  #endif\n    {\n      err = fp_mod(t, b, c);\n    }\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return err;\n}\n\n/* fast math conversion */\nint mp_sqrmod(mp_int *a, mp_int *b, mp_int *c)\n{\n    return fp_sqrmod(a, b, c);\n}\n\n/* fast math conversion */\nint mp_montgomery_calc_normalization(mp_int *a, mp_int *b)\n{\n    fp_montgomery_calc_normalization(a, b);\n    return MP_OKAY;\n}\n\n#endif /* WOLFSSL_KEYGEN || HAVE_ECC */\n\n\n#if defined(WC_MP_TO_RADIX) || !defined(NO_DH) || !defined(NO_DSA) || \\\n    !defined(NO_RSA)\n\n#ifdef WOLFSSL_KEY_GEN\n/* swap the elements of two integers, for cases where you can't simply swap the\n * mp_int pointers around\n */\nstatic int fp_exch (fp_int * a, fp_int * b)\n{\n#ifndef WOLFSSL_SMALL_STACK\n    fp_int  t[1];\n#else\n    fp_int *t;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n   if (t == NULL)\n       return FP_MEM;\n#endif\n\n    *t = *a;\n    *a = *b;\n    *b = *t;\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n    return FP_OKAY;\n}\n#endif\n\nstatic const int lnz[16] = {\n   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0\n};\n\n/* Counts the number of lsbs which are zero before the first zero bit */\nint fp_cnt_lsb(fp_int *a)\n{\n   int x;\n   fp_digit q, qq;\n\n   /* easy out */\n   if (fp_iszero(a) == FP_YES) {\n      return 0;\n   }\n\n   /* scan lower digits until non-zero */\n   for (x = 0; x < a->used && a->dp[x] == 0; x++) {}\n   q = a->dp[x];\n   x *= DIGIT_BIT;\n\n   /* now scan this digit until a 1 is found */\n   if ((q & 1) == 0) {\n      do {\n         qq  = q & 15;\n         x  += lnz[qq];\n         q >>= 4;\n      } while (qq == 0);\n   }\n   return x;\n}\n\n\nstatic int s_is_power_of_two(fp_digit b, int *p)\n{\n   int x;\n\n   /* fast return if no power of two */\n   if ((b==0) || (b & (b-1))) {\n      return FP_NO;\n   }\n\n   for (x = 0; x < DIGIT_BIT; x++) {\n      if (b == (((fp_digit)1)<<x)) {\n         *p = x;\n         return FP_YES;\n      }\n   }\n   return FP_NO;\n}\n\n/* a/b => cb + d == a */\nstatic int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d)\n{\n#ifndef WOLFSSL_SMALL_STACK\n  fp_int   q[1];\n#else\n  fp_int   *q;\n#endif\n  fp_word  w;\n  fp_digit t;\n  int      ix;\n\n  /* cannot divide by zero */\n  if (b == 0) {\n     return FP_VAL;\n  }\n\n  /* quick outs */\n  if (b == 1 || fp_iszero(a) == FP_YES) {\n     if (d != NULL) {\n        *d = 0;\n     }\n     if (c != NULL) {\n        fp_copy(a, c);\n     }\n     return FP_OKAY;\n  }\n\n  /* power of two ? */\n  if (s_is_power_of_two(b, &ix) == FP_YES) {\n     if (d != NULL) {\n        *d = a->dp[0] & ((((fp_digit)1)<<ix) - 1);\n     }\n     if (c != NULL) {\n        fp_div_2d(a, ix, c, NULL);\n     }\n     return FP_OKAY;\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  q = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n  if (q == NULL)\n      return FP_MEM;\n#endif\n\n  fp_init(q);\n\n  if (c != NULL) {\n    q->used = a->used;\n    q->sign = a->sign;\n  }\n\n  w = 0;\n  for (ix = a->used - 1; ix >= 0; ix--) {\n     w = (w << ((fp_word)DIGIT_BIT)) | ((fp_word)a->dp[ix]);\n\n     if (w >= b) {\n        t = (fp_digit)(w / b);\n        w -= ((fp_word)t) * ((fp_word)b);\n      } else {\n        t = 0;\n      }\n      if (c != NULL)\n        q->dp[ix] = (fp_digit)t;\n  }\n\n  if (d != NULL) {\n     *d = (fp_digit)w;\n  }\n\n  if (c != NULL) {\n     fp_clamp(q);\n     fp_copy(q, c);\n  }\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n  return FP_OKAY;\n}\n\n\n/* c = a mod b, 0 <= c < b  */\nstatic int fp_mod_d(fp_int *a, fp_digit b, fp_digit *c)\n{\n   return fp_div_d(a, b, NULL, c);\n}\n\nint mp_mod_d(fp_int *a, fp_digit b, fp_digit *c)\n{\n   return fp_mod_d(a, b, c);\n}\n\n#endif /* WC_MP_TO_RADIX || !NO_DH || !NO_DSA || !NO_RSA */\n\n\n#if !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA) || \\\n    defined(WOLFSSL_KEY_GEN)\n\nstatic int  fp_isprime_ex(fp_int *a, int t, int* result);\n\n\nint mp_prime_is_prime(mp_int* a, int t, int* result)\n{\n    return fp_isprime_ex(a, t, result);\n}\n\n/* Miller-Rabin test of \"a\" to the base of \"b\" as described in\n * HAC pp. 139 Algorithm 4.24\n *\n * Sets result to 0 if definitely composite or 1 if probably prime.\n * Randomly the chance of error is no more than 1/4 and often\n * very much lower.\n */\nstatic int fp_prime_miller_rabin_ex(fp_int * a, fp_int * b, int *result,\n  fp_int *n1, fp_int *y, fp_int *r)\n{\n  int s, j;\n  int err;\n\n  /* default */\n  *result = FP_NO;\n\n  /* ensure b > 1 */\n  if (fp_cmp_d(b, 1) != FP_GT) {\n     return FP_OKAY;\n  }\n\n  /* get n1 = a - 1 */\n  fp_copy(a, n1);\n  err = fp_sub_d(n1, 1, n1);\n  if (err != FP_OKAY) {\n     return err;\n  }\n\n  /* set 2**s * r = n1 */\n  fp_copy(n1, r);\n\n  /* count the number of least significant bits\n   * which are zero\n   */\n  s = fp_cnt_lsb(r);\n\n  /* now divide n - 1 by 2**s */\n  fp_div_2d (r, s, r, NULL);\n\n  /* compute y = b**r mod a */\n  fp_zero(y);\n#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \\\n                                                     defined(WOLFSSL_HAVE_SP_DH)\n#ifndef WOLFSSL_SP_NO_2048\n  if (fp_count_bits(a) == 1024)\n      sp_ModExp_1024(b, r, a, y);\n  else if (fp_count_bits(a) == 2048)\n      sp_ModExp_2048(b, r, a, y);\n  else\n#endif\n#ifndef WOLFSSL_SP_NO_3072\n  if (fp_count_bits(a) == 1536)\n      sp_ModExp_1536(b, r, a, y);\n  else if (fp_count_bits(a) == 3072)\n      sp_ModExp_3072(b, r, a, y);\n  else\n#endif\n#ifdef WOLFSSL_SP_4096\n  if (fp_count_bits(a) == 4096)\n      sp_ModExp_4096(b, r, a, y);\n  else\n#endif\n#endif\n      fp_exptmod(b, r, a, y);\n\n  /* if y != 1 and y != n1 do */\n  if (fp_cmp_d (y, 1) != FP_EQ && fp_cmp (y, n1) != FP_EQ) {\n    j = 1;\n    /* while j <= s-1 and y != n1 */\n    while ((j <= (s - 1)) && fp_cmp (y, n1) != FP_EQ) {\n      fp_sqrmod (y, a, y);\n\n      /* if y == 1 then composite */\n      if (fp_cmp_d (y, 1) == FP_EQ) {\n         return FP_OKAY;\n      }\n      ++j;\n    }\n\n    /* if y != n1 then composite */\n    if (fp_cmp (y, n1) != FP_EQ) {\n       return FP_OKAY;\n    }\n  }\n\n  /* probably prime now */\n  *result = FP_YES;\n\n  return FP_OKAY;\n}\n\nstatic int fp_prime_miller_rabin(fp_int * a, fp_int * b, int *result)\n{\n  int err;\n#ifndef WOLFSSL_SMALL_STACK\n  fp_int  n1[1], y[1], r[1];\n#else\n  fp_int *n1, *y, *r;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n  n1 = (fp_int*)XMALLOC(sizeof(fp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT);\n  if (n1 == NULL) {\n      return FP_MEM;\n  }\n  y = &n1[1]; r = &n1[2];\n#endif\n\n  fp_init(n1);\n  fp_init(y);\n  fp_init(r);\n\n  err = fp_prime_miller_rabin_ex(a, b, result, n1, y, r);\n\n  fp_clear(n1);\n  fp_clear(y);\n  fp_clear(r);\n\n#ifdef WOLFSSL_SMALL_STACK\n  XFREE(n1, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n\n  return err;\n}\n\n\n/* a few primes */\nstatic const fp_digit primes[FP_PRIME_SIZE] = {\n  0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,\n  0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,\n  0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,\n  0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083,\n  0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,\n  0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,\n  0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,\n  0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,\n\n  0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,\n  0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,\n  0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,\n  0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,\n  0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,\n  0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,\n  0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,\n  0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,\n\n  0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,\n  0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,\n  0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,\n  0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,\n  0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,\n  0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,\n  0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,\n  0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,\n\n  0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,\n  0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,\n  0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,\n  0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,\n  0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,\n  0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,\n  0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,\n  0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653\n};\n\nint fp_isprime_ex(fp_int *a, int t, int* result)\n{\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int   b[1];\n#else\n   fp_int   *b;\n#endif\n   fp_digit d;\n   int      r, res;\n\n   if (t <= 0 || t > FP_PRIME_SIZE) {\n     *result = FP_NO;\n     return FP_VAL;\n   }\n\n   if (fp_isone(a)) {\n       *result = FP_NO;\n       return FP_OKAY;\n   }\n\n   /* check against primes table */\n   for (r = 0; r < FP_PRIME_SIZE; r++) {\n       if (fp_cmp_d(a, primes[r]) == FP_EQ) {\n           *result = FP_YES;\n           return FP_OKAY;\n       }\n   }\n\n   /* do trial division */\n   for (r = 0; r < FP_PRIME_SIZE; r++) {\n       res = fp_mod_d(a, primes[r], &d);\n       if (res != MP_OKAY || d == 0) {\n           *result = FP_NO;\n           return FP_OKAY;\n       }\n   }\n\n#ifdef WOLFSSL_SMALL_STACK\n  b = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n  if (b == NULL)\n      return FP_MEM;\n#endif\n   /* now do 't' miller rabins */\n   fp_init(b);\n   for (r = 0; r < t; r++) {\n       fp_set(b, primes[r]);\n       fp_prime_miller_rabin(a, b, &res);\n       if (res == FP_NO) {\n          *result = FP_NO;\n       #ifdef WOLFSSL_SMALL_STACK\n          XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);\n       #endif\n          return FP_OKAY;\n       }\n   }\n   *result = FP_YES;\n#ifdef WOLFSSL_SMALL_STACK\n   XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n   return FP_OKAY;\n}\n\n\nint mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng)\n{\n    int ret = FP_YES;\n\n    if (a == NULL || result == NULL || rng == NULL)\n        return FP_VAL;\n\n    if (fp_isone(a)) {\n        *result = FP_NO;\n        return FP_OKAY;\n    }\n\n    if (ret == FP_YES) {\n        fp_digit d;\n        int r;\n\n        /* check against primes table */\n        for (r = 0; r < FP_PRIME_SIZE; r++) {\n            if (fp_cmp_d(a, primes[r]) == FP_EQ) {\n                *result = FP_YES;\n                return FP_OKAY;\n            }\n        }\n\n        /* do trial division */\n        for (r = 0; r < FP_PRIME_SIZE; r++) {\n            if (fp_mod_d(a, primes[r], &d) == MP_OKAY) {\n                if (d == 0) {\n                    *result = FP_NO;\n                    return FP_OKAY;\n                }\n            }\n            else\n                return FP_VAL;\n        }\n    }\n\n#ifndef WC_NO_RNG\n    /* now do a miller rabin with up to t random numbers, this should\n     * give a (1/4)^t chance of a false prime. */\n    if (ret == FP_YES) {\n    #ifndef WOLFSSL_SMALL_STACK\n        fp_int b[1], c[1], n1[1], y[1], r[1];\n        byte   base[FP_MAX_PRIME_SIZE];\n    #else\n        fp_int *b, *c, *n1, *y, *r;\n        byte*  base;\n    #endif\n        word32 baseSz;\n        int    err;\n\n        baseSz = fp_count_bits(a);\n        /* The base size is the number of bits / 8. One is added if the number\n         * of bits isn't an even 8. */\n        baseSz = (baseSz / 8) + ((baseSz % 8) ? 1 : 0);\n\n    #ifndef WOLFSSL_SMALL_STACK\n        if (baseSz > sizeof(base))\n            return FP_MEM;\n    #else\n        base = (byte*)XMALLOC(baseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        if (base == NULL)\n            return FP_MEM;\n\n        b = (fp_int*)XMALLOC(sizeof(fp_int) * 5, NULL, DYNAMIC_TYPE_BIGINT);\n        if (b == NULL) {\n            return FP_MEM;\n        }\n        c = &b[1]; n1 = &b[2]; y= &b[3]; r = &b[4];\n    #endif\n\n        fp_init(b);\n        fp_init(c);\n        fp_init(n1);\n        fp_init(y);\n        fp_init(r);\n\n        err = fp_sub_d(a, 2, c);\n        if (err != FP_OKAY) {\n        #ifdef WOLFSSL_SMALL_STACK\n           XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);\n           XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n        #endif\n           return err;\n        }\n        while (t > 0) {\n            if ((err = wc_RNG_GenerateBlock(rng, base, baseSz)) != 0) {\n            #ifdef WOLFSSL_SMALL_STACK\n               XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);\n               XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n            #endif\n               return err;\n            }\n\n            fp_read_unsigned_bin(b, base, baseSz);\n            if (fp_cmp_d(b, 2) != FP_GT || fp_cmp(b, c) != FP_LT) {\n                continue;\n            }\n\n            fp_prime_miller_rabin_ex(a, b, &ret, n1, y, r);\n            if (ret == FP_NO)\n                break;\n            fp_zero(b);\n            t--;\n        }\n\n        fp_clear(n1);\n        fp_clear(y);\n        fp_clear(r);\n        fp_clear(b);\n        fp_clear(c);\n     #ifdef WOLFSSL_SMALL_STACK\n        XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);\n        XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n     #endif\n    }\n#else\n    (void)t;\n#endif /* !WC_NO_RNG */\n\n    *result = ret;\n    return FP_OKAY;\n}\n#endif /* !NO_RSA || !NO_DSA || !NO_DH || WOLFSSL_KEY_GEN */\n\n\n#ifdef WOLFSSL_KEY_GEN\n\nstatic int  fp_gcd(fp_int *a, fp_int *b, fp_int *c);\nstatic int  fp_lcm(fp_int *a, fp_int *b, fp_int *c);\nstatic int  fp_randprime(fp_int* N, int len, WC_RNG* rng, void* heap);\n\nint mp_gcd(fp_int *a, fp_int *b, fp_int *c)\n{\n    return fp_gcd(a, b, c);\n}\n\n\nint mp_lcm(fp_int *a, fp_int *b, fp_int *c)\n{\n    return fp_lcm(a, b, c);\n}\n\nint mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap)\n{\n    int err;\n\n    err = fp_randprime(N, len, rng, heap);\n    switch(err) {\n        case FP_VAL:\n            return MP_VAL;\n        case FP_MEM:\n            return MP_MEM;\n        default:\n            break;\n    }\n\n    return MP_OKAY;\n}\n\nint mp_exch (mp_int * a, mp_int * b)\n{\n    return fp_exch(a, b);\n}\n\n\n\nint fp_randprime(fp_int* N, int len, WC_RNG* rng, void* heap)\n{\n    static const int USE_BBS = 1;\n    int   err, type;\n    int   isPrime = FP_YES;\n        /* Assume the candidate is probably prime and then test until\n         * it is proven composite. */\n    byte* buf;\n\n    (void)heap;\n\n    /* get type */\n    if (len < 0) {\n        type = USE_BBS;\n        len = -len;\n    } else {\n        type = 0;\n    }\n\n    /* allow sizes between 2 and 512 bytes for a prime size */\n    if (len < 2 || len > 512) {\n        return FP_VAL;\n    }\n\n    /* allocate buffer to work with */\n    buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (buf == NULL) {\n        return FP_MEM;\n    }\n    XMEMSET(buf, 0, len);\n\n    do {\n#ifdef SHOW_GEN\n        printf(\".\");\n        fflush(stdout);\n#endif\n        /* generate value */\n        err = wc_RNG_GenerateBlock(rng, buf, len);\n        if (err != 0) {\n            XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER);\n            return FP_VAL;\n        }\n\n        /* munge bits */\n        buf[0]     |= 0x80 | 0x40;\n        buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);\n\n        /* load value */\n        fp_read_unsigned_bin(N, buf, len);\n\n        /* test */\n        /* Running Miller-Rabin up to 3 times gives us a 2^{-80} chance\n         * of a 1024-bit candidate being a false positive, when it is our\n         * prime candidate. (Note 4.49 of Handbook of Applied Cryptography.)\n         * Using 8 because we've always used 8 */\n        mp_prime_is_prime_ex(N, 8, &isPrime, rng);\n    } while (isPrime == FP_NO);\n\n    XMEMSET(buf, 0, len);\n    XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    return FP_OKAY;\n}\n\n/* c = [a, b] */\nint fp_lcm(fp_int *a, fp_int *b, fp_int *c)\n{\n   int     err;\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int  t[2];\n#else\n   fp_int  *t;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n   t = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT);\n   if (t == NULL) {\n       return FP_MEM;\n   }\n#endif\n\n   fp_init(&t[0]);\n   fp_init(&t[1]);\n   err = fp_gcd(a, b, &t[0]);\n   if (err == FP_OKAY) {\n      if (fp_cmp_mag(a, b) == FP_GT) {\n        err = fp_div(a, &t[0], &t[1], NULL);\n        if (err == FP_OKAY)\n          err = fp_mul(b, &t[1], c);\n     } else {\n        err = fp_div(b, &t[0], &t[1], NULL);\n        if (err == FP_OKAY)\n          err = fp_mul(a, &t[1], c);\n     }\n   }\n\n#ifdef WOLFSSL_SMALL_STACK\n   XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n   return err;\n}\n\n\n\n/* c = (a, b) */\nint fp_gcd(fp_int *a, fp_int *b, fp_int *c)\n{\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int u[1], v[1], r[1];\n#else\n   fp_int *u, *v, *r;\n#endif\n\n   /* either zero than gcd is the largest */\n   if (fp_iszero (a) == FP_YES && fp_iszero (b) == FP_NO) {\n     fp_abs (b, c);\n     return FP_OKAY;\n   }\n   if (fp_iszero (a) == FP_NO && fp_iszero (b) == FP_YES) {\n     fp_abs (a, c);\n     return FP_OKAY;\n   }\n\n   /* optimized.  At this point if a == 0 then\n    * b must equal zero too\n    */\n   if (fp_iszero (a) == FP_YES) {\n     fp_zero(c);\n     return FP_OKAY;\n   }\n\n#ifdef WOLFSSL_SMALL_STACK\n   u = (fp_int*)XMALLOC(sizeof(fp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT);\n   if (u == NULL) {\n       return FP_MEM;\n   }\n   v = &u[1]; r = &u[2];\n#endif\n\n   /* sort inputs */\n   if (fp_cmp_mag(a, b) != FP_LT) {\n      fp_init_copy(u, a);\n      fp_init_copy(v, b);\n   } else {\n      fp_init_copy(u, b);\n      fp_init_copy(v, a);\n   }\n\n   u->sign = FP_ZPOS;\n   v->sign = FP_ZPOS;\n\n   fp_init(r);\n   while (fp_iszero(v) == FP_NO) {\n      fp_mod(u, v, r);\n      fp_copy(v, u);\n      fp_copy(r, v);\n   }\n   fp_copy(u, c);\n\n#ifdef WOLFSSL_SMALL_STACK\n   XFREE(u, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n   return FP_OKAY;\n}\n\n#endif /* WOLFSSL_KEY_GEN */\n\n\n#if defined(HAVE_ECC) || !defined(NO_PWDBASED) || defined(OPENSSL_EXTRA) || \\\n    defined(WC_RSA_BLINDING) || !defined(NO_DSA) || \\\n    (!defined(NO_RSA) && !defined(NO_RSA_BOUNDS_CHECK))\n/* c = a + b */\nvoid fp_add_d(fp_int *a, fp_digit b, fp_int *c)\n{\n#ifndef WOLFSSL_SMALL_STACK\n   fp_int tmp;\n   fp_init(&tmp);\n   fp_set(&tmp, b);\n   fp_add(a, &tmp, c);\n#else\n   int i;\n   fp_word t = b;\n\n   fp_copy(a, c);\n   for (i = 0; t != 0 && i < FP_SIZE && i < c->used; i++) {\n     t += c->dp[i];\n     c->dp[i] = (fp_digit)t;\n     t >>= DIGIT_BIT;\n   }\n   if (i == c->used && i < FP_SIZE && t != 0) {\n       c->dp[i] = t;\n       c->used++;\n   }\n#endif\n}\n\n/* external compatibility */\nint mp_add_d(fp_int *a, fp_digit b, fp_int *c)\n{\n    fp_add_d(a, b, c);\n    return MP_OKAY;\n}\n\n#endif  /* HAVE_ECC || !NO_PWDBASED || OPENSSL_EXTRA || WC_RSA_BLINDING ||\n  !NO_DSA || (!NO_RSA && !NO_RSA_BOUNDS_CHECK) */\n\n\n#if !defined(NO_DSA) || defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || \\\n    defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) || \\\n    defined(DEBUG_WOLFSSL) || defined(OPENSSL_EXTRA) || defined(WC_MP_TO_RADIX)\n\n/* chars used in radix conversions */\nstatic const char* const fp_s_rmap = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n                                     \"abcdefghijklmnopqrstuvwxyz+/\";\n#endif\n\n#if !defined(NO_DSA) || defined(HAVE_ECC)\n#if DIGIT_BIT == 64 || DIGIT_BIT == 32\nstatic int fp_read_radix_16(fp_int *a, const char *str)\n{\n  int     i, j, k, neg;\n  char    ch;\n\n  /* if the leading digit is a\n   * minus set the sign to negative.\n   */\n  if (*str == '-') {\n    ++str;\n    neg = FP_NEG;\n  } else {\n    neg = FP_ZPOS;\n  }\n\n  j = 0;\n  k = 0;\n  for (i = (int)(XSTRLEN(str) - 1); i >= 0; i--) {\n      ch = str[i];\n      if (ch >= '0' && ch <= '9')\n          ch -= '0';\n      else if (ch >= 'A' && ch <= 'F')\n          ch -= 'A' - 10;\n      else if (ch >= 'a' && ch <= 'f')\n          ch -= 'a' - 10;\n      else\n          return FP_VAL;\n\n      a->dp[k] |= ((fp_digit)ch) << j;\n      j += 4;\n      k += j == DIGIT_BIT;\n      j &= DIGIT_BIT - 1;\n  }\n\n  a->used = k + 1;\n  fp_clamp(a);\n  /* set the sign only if a != 0 */\n  if (fp_iszero(a) != FP_YES) {\n     a->sign = neg;\n  }\n  return FP_OKAY;\n}\n#endif\n\nstatic int fp_read_radix(fp_int *a, const char *str, int radix)\n{\n  int     y, neg;\n  char    ch;\n\n  /* set the integer to the default of zero */\n  fp_zero (a);\n\n#if DIGIT_BIT == 64 || DIGIT_BIT == 32\n  if (radix == 16)\n      return fp_read_radix_16(a, str);\n#endif\n\n  /* make sure the radix is ok */\n  if (radix < 2 || radix > 64) {\n    return FP_VAL;\n  }\n\n  /* if the leading digit is a\n   * minus set the sign to negative.\n   */\n  if (*str == '-') {\n    ++str;\n    neg = FP_NEG;\n  } else {\n    neg = FP_ZPOS;\n  }\n\n  /* process each digit of the string */\n  while (*str) {\n    /* if the radix <= 36 the conversion is case insensitive\n     * this allows numbers like 1AB and 1ab to represent the same  value\n     * [e.g. in hex]\n     */\n    ch = (char)((radix <= 36) ? XTOUPPER((unsigned char)*str) : *str);\n    for (y = 0; y < 64; y++) {\n      if (ch == fp_s_rmap[y]) {\n         break;\n      }\n    }\n\n    /* if the char was found in the map\n     * and is less than the given radix add it\n     * to the number, otherwise exit the loop.\n     */\n    if (y < radix) {\n      fp_mul_d (a, (fp_digit) radix, a);\n      fp_add_d (a, (fp_digit) y, a);\n    } else {\n      break;\n    }\n    ++str;\n  }\n\n  /* set the sign only if a != 0 */\n  if (fp_iszero(a) != FP_YES) {\n     a->sign = neg;\n  }\n  return FP_OKAY;\n}\n\n/* fast math conversion */\nint mp_read_radix(mp_int *a, const char *str, int radix)\n{\n    return fp_read_radix(a, str, radix);\n}\n\n#endif /* !defined(NO_DSA) || defined(HAVE_ECC) */\n\n#ifdef HAVE_ECC\n\n/* fast math conversion */\nint mp_sqr(fp_int *A, fp_int *B)\n{\n    return fp_sqr(A, B);\n}\n\n/* fast math conversion */\nint mp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp)\n{\n    return fp_montgomery_reduce(a, m, mp);\n}\n\n\n/* fast math conversion */\nint mp_montgomery_setup(fp_int *a, fp_digit *rho)\n{\n    return fp_montgomery_setup(a, rho);\n}\n\nint mp_div_2(fp_int * a, fp_int * b)\n{\n    fp_div_2(a, b);\n    return MP_OKAY;\n}\n\n\nint mp_init_copy(fp_int * a, fp_int * b)\n{\n    fp_init_copy(a, b);\n    return MP_OKAY;\n}\n\n#ifdef HAVE_COMP_KEY\n\nint mp_cnt_lsb(fp_int* a)\n{\n    return fp_cnt_lsb(a);\n}\n\n#endif /* HAVE_COMP_KEY */\n\n#endif /* HAVE_ECC */\n\n#if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DSA) || \\\n    defined(WOLFSSL_KEY_GEN)\n/* fast math conversion */\nint mp_set(fp_int *a, fp_digit b)\n{\n    fp_set(a,b);\n    return MP_OKAY;\n}\n#endif\n\n#ifdef WC_MP_TO_RADIX\n\n/* returns size of ASCII representation */\nint mp_radix_size (mp_int *a, int radix, int *size)\n{\n    int      res, digs;\n    fp_digit d;\n#ifndef WOLFSSL_SMALL_STACK\n    fp_int   t[1];\n#else\n    fp_int   *t;\n#endif\n\n    *size = 0;\n\n    /* special case for binary */\n    if (radix == 2) {\n        *size = fp_count_bits (a) + (a->sign == FP_NEG ? 1 : 0) + 1;\n        return FP_YES;\n    }\n\n    /* make sure the radix is in range */\n    if (radix < 2 || radix > 64) {\n        return FP_VAL;\n    }\n\n    if (fp_iszero(a) == MP_YES) {\n        *size = 2;\n        return FP_OKAY;\n    }\n\n    /* digs is the digit count */\n    digs = 0;\n\n    /* if it's negative add one for the sign */\n    if (a->sign == FP_NEG) {\n        ++digs;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n    if (t == NULL)\n        return FP_MEM;\n#endif\n\n    /* init a copy of the input */\n    fp_init_copy (t, a);\n\n    /* force temp to positive */\n    t->sign = FP_ZPOS;\n\n    /* fetch out all of the digits */\n    while (fp_iszero (t) == FP_NO) {\n        if ((res = fp_div_d (t, (mp_digit) radix, t, &d)) != FP_OKAY) {\n            fp_zero (t);\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n        #endif\n            return res;\n        }\n        ++digs;\n    }\n    fp_zero (t);\n\n    /* return digs + 1, the 1 is for the NULL byte that would be required. */\n    *size = digs + 1;\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n    return FP_OKAY;\n}\n\n/* stores a bignum as a ASCII string in a given radix (2..64) */\nint mp_toradix (mp_int *a, char *str, int radix)\n{\n    int      res, digs;\n    fp_digit d;\n    char     *_s = str;\n#ifndef WOLFSSL_SMALL_STACK\n    fp_int   t[1];\n#else\n    fp_int   *t;\n#endif\n\n    /* check range of the radix */\n    if (radix < 2 || radix > 64) {\n        return FP_VAL;\n    }\n\n    /* quick out if its zero */\n    if (fp_iszero(a) == FP_YES) {\n        *str++ = '0';\n        *str = '\\0';\n        return FP_OKAY;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);\n    if (t == NULL)\n        return FP_MEM;\n#endif\n\n    /* init a copy of the input */\n    fp_init_copy (t, a);\n\n    /* if it is negative output a - */\n    if (t->sign == FP_NEG) {\n        ++_s;\n        *str++ = '-';\n        t->sign = FP_ZPOS;\n    }\n\n    digs = 0;\n    while (fp_iszero (t) == FP_NO) {\n        if ((res = fp_div_d (t, (fp_digit) radix, t, &d)) != FP_OKAY) {\n            fp_zero (t);\n        #ifdef WOLFSSL_SMALL_STACK\n            XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n        #endif\n            return res;\n        }\n        *str++ = fp_s_rmap[d];\n        ++digs;\n    }\n#ifndef WC_DISABLE_RADIX_ZERO_PAD\n    /* For hexadecimal output, add zero padding when number of digits is odd */\n    if ((digs & 1) && (radix == 16)) {\n        *str++ = fp_s_rmap[0];\n        ++digs;\n    }\n#endif\n    /* reverse the digits of the string.  In this case _s points\n     * to the first digit [excluding the sign] of the number]\n     */\n    fp_reverse ((unsigned char *)_s, digs);\n\n    /* append a NULL so the string is properly terminated */\n    *str = '\\0';\n\n    fp_zero (t);\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);\n#endif\n    return FP_OKAY;\n}\n\n#ifdef WOLFSSL_DEBUG_MATH\nvoid mp_dump(const char* desc, mp_int* a, byte verbose)\n{\n  char buffer[FP_SIZE * sizeof(fp_digit) * 2];\n  int size = FP_SIZE;\n\n#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)\n  size = a->size;\n#endif\n\n  printf(\"%s: ptr=%p, used=%d, sign=%d, size=%d, fpd=%d\\n\",\n    desc, a, a->used, a->sign, size, (int)sizeof(fp_digit));\n\n  mp_tohex(a, buffer);\n  printf(\"  %s\\n  \", buffer);\n\n  if (verbose) {\n    int i;\n    for(i=0; i<size * (int)sizeof(fp_digit); i++) {\n      printf(\"%x \", *(((byte*)a->dp) + i));\n    }\n    printf(\"\\n\");\n  }\n}\n#endif /* WOLFSSL_DEBUG_MATH */\n\n#endif /* WC_MP_TO_RADIX */\n\n\nint mp_abs(mp_int* a, mp_int* b)\n{\n    fp_abs(a, b);\n    return FP_OKAY;\n}\n\n\nint mp_lshd (mp_int * a, int b)\n{\n    fp_lshd(a, b);\n    return FP_OKAY;\n}\n\n#endif /* USE_FAST_MATH */\n"
  },
  {
    "path": "src/wolfcrypt/src/wc_encrypt.c",
    "content": "/* wc_encrypt.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/aes.h>\n#include <wolfssl/wolfcrypt/des3.h>\n#include <wolfssl/wolfcrypt/hash.h>\n#include <wolfssl/wolfcrypt/arc4.h>\n#include <wolfssl/wolfcrypt/wc_encrypt.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/asn.h>\n#include <wolfssl/wolfcrypt/coding.h>\n#include <wolfssl/wolfcrypt/pwdbased.h>\n#include <wolfssl/wolfcrypt/logging.h>\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#if !defined(NO_AES) && defined(HAVE_AES_CBC)\n#ifdef HAVE_AES_DECRYPT\nint wc_AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz,\n                                  const byte* key, word32 keySz, const byte* iv)\n{\n    int  ret = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    Aes* aes = NULL;\n#else\n    Aes  aes[1];\n#endif\n\n    if (out == NULL || in == NULL || key == NULL || iv == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (aes == NULL)\n        return MEMORY_E;\n#endif\n\n    ret = wc_AesInit(aes, NULL, INVALID_DEVID);\n    if (ret == 0) {\n        ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);\n        if (ret == 0)\n            ret = wc_AesCbcDecrypt(aes, out, in, inSz);\n\n        wc_AesFree(aes);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(aes, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n#endif /* HAVE_AES_DECRYPT */\n\nint wc_AesCbcEncryptWithKey(byte* out, const byte* in, word32 inSz,\n                            const byte* key, word32 keySz, const byte* iv)\n{\n    int  ret = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    Aes* aes = NULL;\n#else\n    Aes  aes[1];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (aes == NULL)\n        return MEMORY_E;\n#endif\n\n    ret = wc_AesInit(aes, NULL, INVALID_DEVID);\n    if (ret == 0) {\n        ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);\n        if (ret == 0)\n            ret = wc_AesCbcEncrypt(aes, out, in, inSz);\n\n        wc_AesFree(aes);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(aes, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n#endif /* !NO_AES && HAVE_AES_CBC */\n\n\n#if !defined(NO_DES3) && !defined(WOLFSSL_TI_CRYPT)\nint wc_Des_CbcEncryptWithKey(byte* out, const byte* in, word32 sz,\n                             const byte* key, const byte* iv)\n{\n    int ret  = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    Des* des = NULL;\n#else\n    Des  des[1];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    des = (Des*)XMALLOC(sizeof(Des), NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (des == NULL)\n        return MEMORY_E;\n#endif\n\n    ret = wc_Des_SetKey(des, key, iv, DES_ENCRYPTION);\n    if (ret == 0)\n        ret = wc_Des_CbcEncrypt(des, out, in, sz);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(des, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\nint wc_Des_CbcDecryptWithKey(byte* out, const byte* in, word32 sz,\n                             const byte* key, const byte* iv)\n{\n    int ret  = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    Des* des = NULL;\n#else\n    Des  des[1];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    des = (Des*)XMALLOC(sizeof(Des), NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (des == NULL)\n        return MEMORY_E;\n#endif\n\n    ret = wc_Des_SetKey(des, key, iv, DES_DECRYPTION);\n    if (ret == 0)\n        ret = wc_Des_CbcDecrypt(des, out, in, sz);\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(des, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n\nint wc_Des3_CbcEncryptWithKey(byte* out, const byte* in, word32 sz,\n                              const byte* key, const byte* iv)\n{\n    int ret    = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    Des3* des3 = NULL;\n#else\n    Des3  des3[1];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    des3 = (Des3*)XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (des3 == NULL)\n        return MEMORY_E;\n#endif\n\n    ret = wc_Des3Init(des3, NULL, INVALID_DEVID);\n    if (ret == 0) {\n        ret = wc_Des3_SetKey(des3, key, iv, DES_ENCRYPTION);\n        if (ret == 0)\n            ret = wc_Des3_CbcEncrypt(des3, out, in, sz);\n        wc_Des3Free(des3);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(des3, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n\nint wc_Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz,\n                              const byte* key, const byte* iv)\n{\n    int ret    = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    Des3* des3 = NULL;\n#else\n    Des3  des3[1];\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK\n    des3 = (Des3*)XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (des3 == NULL)\n        return MEMORY_E;\n#endif\n\n    ret = wc_Des3Init(des3, NULL, INVALID_DEVID);\n    if (ret == 0) {\n        ret = wc_Des3_SetKey(des3, key, iv, DES_DECRYPTION);\n        if (ret == 0)\n            ret = wc_Des3_CbcDecrypt(des3, out, in, sz);\n        wc_Des3Free(des3);\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(des3, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n#endif /* !NO_DES3 */\n\n\n#ifdef WOLFSSL_ENCRYPTED_KEYS\n\nint wc_BufferKeyDecrypt(EncryptedInfo* info, byte* der, word32 derSz,\n    const byte* password, int passwordSz, int hashType)\n{\n    int ret = NOT_COMPILED_IN;\n#ifdef WOLFSSL_SMALL_STACK\n    byte* key      = NULL;\n#else\n    byte  key[WC_MAX_SYM_KEY_SIZE];\n#endif\n\n    (void)derSz;\n    (void)passwordSz;\n    (void)hashType;\n\n    if (der == NULL || password == NULL || info == NULL || info->keySz == 0) {\n        return BAD_FUNC_ARG;\n    }\n\n    /* use file's salt for key derivation, hex decode first */\n    if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz) != 0) {\n        return BUFFER_E;\n    }\n    if (info->ivSz < PKCS5_SALT_SZ)\n        return BUFFER_E;\n\n#ifdef WOLFSSL_SMALL_STACK\n    key = (byte*)XMALLOC(WC_MAX_SYM_KEY_SIZE, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);\n    if (key == NULL) {\n        return MEMORY_E;\n    }\n#endif\n\n    (void)XMEMSET(key, 0, WC_MAX_SYM_KEY_SIZE);\n\n#ifndef NO_PWDBASED\n    if ((ret = wc_PBKDF1(key, password, passwordSz, info->iv, PKCS5_SALT_SZ, 1,\n                                        info->keySz, hashType)) != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);\n#endif\n        return ret;\n    }\n#endif\n\n#ifndef NO_DES3\n    if (info->cipherType == WC_CIPHER_DES)\n        ret = wc_Des_CbcDecryptWithKey(der, der, derSz, key, info->iv);\n    if (info->cipherType == WC_CIPHER_DES3)\n        ret = wc_Des3_CbcDecryptWithKey(der, der, derSz, key, info->iv);\n#endif /* NO_DES3 */\n#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(HAVE_AES_DECRYPT)\n    if (info->cipherType == WC_CIPHER_AES_CBC)\n        ret = wc_AesCbcDecryptWithKey(der, der, derSz, key, info->keySz,\n            info->iv);\n#endif /* !NO_AES && HAVE_AES_CBC && HAVE_AES_DECRYPT */\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);\n#endif\n\n    return ret;\n}\n\nint wc_BufferKeyEncrypt(EncryptedInfo* info, byte* der, word32 derSz,\n    const byte* password, int passwordSz, int hashType)\n{\n    int ret = NOT_COMPILED_IN;\n#ifdef WOLFSSL_SMALL_STACK\n    byte* key      = NULL;\n#else\n    byte  key[WC_MAX_SYM_KEY_SIZE];\n#endif\n\n    (void)derSz;\n    (void)passwordSz;\n    (void)hashType;\n\n    if (der == NULL || password == NULL || info == NULL || info->keySz == 0 ||\n            info->ivSz < PKCS5_SALT_SZ) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    key = (byte*)XMALLOC(WC_MAX_SYM_KEY_SIZE, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);\n    if (key == NULL) {\n        return MEMORY_E;\n    }\n#endif /* WOLFSSL_SMALL_STACK */\n\n    (void)XMEMSET(key, 0, WC_MAX_SYM_KEY_SIZE);\n\n#ifndef NO_PWDBASED\n    if ((ret = wc_PBKDF1(key, password, passwordSz, info->iv, PKCS5_SALT_SZ, 1,\n                                        info->keySz, hashType)) != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);\n#endif\n        return ret;\n    }\n#endif\n\n#ifndef NO_DES3\n    if (info->cipherType == WC_CIPHER_DES)\n        ret = wc_Des_CbcEncryptWithKey(der, der, derSz, key, info->iv);\n    if (info->cipherType == WC_CIPHER_DES3)\n        ret = wc_Des3_CbcEncryptWithKey(der, der, derSz, key, info->iv);\n#endif /* NO_DES3 */\n#if !defined(NO_AES) && defined(HAVE_AES_CBC)\n    if (info->cipherType == WC_CIPHER_AES_CBC)\n        ret = wc_AesCbcEncryptWithKey(der, der, derSz, key, info->keySz,\n            info->iv);\n#endif /* !NO_AES && HAVE_AES_CBC */\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY);\n#endif\n\n    return ret;\n}\n\n#endif /* WOLFSSL_ENCRYPTED_KEYS */\n\n\n#ifndef NO_PWDBASED\n\n#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)\n/* Decrypt/Encrypt input in place from parameters based on id\n *\n * returns a negative value on fail case\n */\nint wc_CryptKey(const char* password, int passwordSz, byte* salt,\n                      int saltSz, int iterations, int id, byte* input,\n                      int length, int version, byte* cbcIv, int enc)\n{\n    int typeH;\n    int derivedLen;\n    int ret = 0;\n#ifdef WOLFSSL_SMALL_STACK\n    byte* key;\n#else\n    byte key[MAX_KEY_SIZE];\n#endif\n\n    (void)input;\n    (void)length;\n    (void)enc;\n\n    WOLFSSL_ENTER(\"wc_CryptKey\");\n\n    switch (id) {\n    #ifndef NO_DES3\n        #ifndef NO_MD5\n        case PBE_MD5_DES:\n            typeH = WC_MD5;\n            derivedLen = 16;           /* may need iv for v1.5 */\n            break;\n        #endif\n        #ifndef NO_SHA\n        case PBE_SHA1_DES:\n            typeH = WC_SHA;\n            derivedLen = 16;           /* may need iv for v1.5 */\n            break;\n\n        case PBE_SHA1_DES3:\n            typeH = WC_SHA;\n            derivedLen = 32;           /* may need iv for v1.5 */\n            break;\n        #endif /* !NO_SHA */\n    #endif /* !NO_DES3 */\n    #if !defined(NO_SHA) && !defined(NO_RC4)\n        case PBE_SHA1_RC4_128:\n            typeH = WC_SHA;\n            derivedLen = 16;\n            break;\n    #endif\n    #ifdef WOLFSSL_AES_256\n        case PBE_AES256_CBC:\n            typeH = WC_SHA256;\n            derivedLen = 32;\n            break;\n    #endif\n        default:\n            WOLFSSL_MSG(\"Unknown/Unsupported encrypt/decrypt id\");\n            return ALGO_ID_E;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    key = (byte*)XMALLOC(MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n    if (key == NULL)\n        return MEMORY_E;\n#endif\n\n    if (version == PKCS5v2)\n        ret = wc_PBKDF2(key, (byte*)password, passwordSz,\n                        salt, saltSz, iterations, derivedLen, typeH);\n#ifndef NO_SHA\n    else if (version == PKCS5)\n        ret = wc_PBKDF1(key, (byte*)password, passwordSz,\n                        salt, saltSz, iterations, derivedLen, typeH);\n#endif\n#ifdef HAVE_PKCS12\n    else if (version == PKCS12v1) {\n        int  i, idx = 0;\n        byte unicodePasswd[MAX_UNICODE_SZ];\n\n        if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) {\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n            return UNICODE_SIZE_E;\n        }\n\n        for (i = 0; i < passwordSz; i++) {\n            unicodePasswd[idx++] = 0x00;\n            unicodePasswd[idx++] = (byte)password[i];\n        }\n        /* add trailing NULL */\n        unicodePasswd[idx++] = 0x00;\n        unicodePasswd[idx++] = 0x00;\n\n        ret =  wc_PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz,\n                            iterations, derivedLen, typeH, 1);\n        if (id != PBE_SHA1_RC4_128)\n            ret += wc_PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz,\n                                iterations, 8, typeH, 2);\n    }\n#endif /* HAVE_PKCS12 */\n    else {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        WOLFSSL_MSG(\"Unknown/Unsupported PKCS version\");\n        return ALGO_ID_E;\n    }\n\n    if (ret != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n        XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n        return ret;\n    }\n\n    switch (id) {\n#ifndef NO_DES3\n    #if !defined(NO_SHA) || !defined(NO_MD5)\n        case PBE_MD5_DES:\n        case PBE_SHA1_DES:\n        {\n            Des    des;\n            byte*  desIv = key + 8;\n\n            if (version == PKCS5v2 || version == PKCS12v1)\n                desIv = cbcIv;\n\n            if (enc) {\n                ret = wc_Des_SetKey(&des, key, desIv, DES_ENCRYPTION);\n            }\n            else {\n                ret = wc_Des_SetKey(&des, key, desIv, DES_DECRYPTION);\n            }\n            if (ret != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n                XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n                return ret;\n            }\n\n            if (enc) {\n                wc_Des_CbcEncrypt(&des, input, input, length);\n            }\n            else {\n                wc_Des_CbcDecrypt(&des, input, input, length);\n            }\n            break;\n        }\n    #endif /* !NO_SHA || !NO_MD5 */\n\n    #ifndef NO_SHA\n        case PBE_SHA1_DES3:\n        {\n            Des3   des;\n            byte*  desIv = key + 24;\n\n            if (version == PKCS5v2 || version == PKCS12v1)\n                desIv = cbcIv;\n\n            ret = wc_Des3Init(&des, NULL, INVALID_DEVID);\n            if (ret != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n                XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n                return ret;\n            }\n            if (enc) {\n                ret = wc_Des3_SetKey(&des, key, desIv, DES_ENCRYPTION);\n            }\n            else {\n                ret = wc_Des3_SetKey(&des, key, desIv, DES_DECRYPTION);\n            }\n            if (ret != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n                XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n                return ret;\n            }\n            if (enc) {\n                ret = wc_Des3_CbcEncrypt(&des, input, input, length);\n            }\n            else {\n                ret = wc_Des3_CbcDecrypt(&des, input, input, length);\n            }\n            if (ret != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n                XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n                return ret;\n            }\n            break;\n        }\n    #endif /* !NO_SHA */\n#endif\n#if !defined(NO_RC4) && !defined(NO_SHA)\n        case PBE_SHA1_RC4_128:\n        {\n            Arc4    dec;\n\n            wc_Arc4SetKey(&dec, key, derivedLen);\n            wc_Arc4Process(&dec, input, input, length);\n            break;\n        }\n#endif\n#if !defined(NO_AES) && defined(HAVE_AES_CBC)\n    #ifdef WOLFSSL_AES_256\n        case PBE_AES256_CBC:\n        {\n            Aes aes;\n            ret = wc_AesInit(&aes, NULL, INVALID_DEVID);\n            if (ret == 0) {\n                if (enc) {\n                    ret = wc_AesSetKey(&aes, key, derivedLen, cbcIv,\n                                                                AES_ENCRYPTION);\n                }\n                else {\n                    ret = wc_AesSetKey(&aes, key, derivedLen, cbcIv,\n                                                                AES_DECRYPTION);\n                }\n            }\n            if (ret == 0) {\n                if (enc)\n                    ret = wc_AesCbcEncrypt(&aes, input, input, length);\n                else\n                    ret = wc_AesCbcDecrypt(&aes, input, input, length);\n            }\n            if (ret != 0) {\n#ifdef WOLFSSL_SMALL_STACK\n                XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n                return ret;\n            }\n            ForceZero(&aes, sizeof(Aes));\n            break;\n        }\n    #endif /* WOLFSSL_AES_256 */\n#endif /* !NO_AES && HAVE_AES_CBC */\n\n        default:\n#ifdef WOLFSSL_SMALL_STACK\n            XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n            WOLFSSL_MSG(\"Unknown/Unsupported encrypt/decryption algorithm\");\n            return ALGO_ID_E;\n    }\n\n#ifdef WOLFSSL_SMALL_STACK\n    XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);\n#endif\n\n    return ret;\n}\n\n#endif /* HAVE_PKCS8 || HAVE_PKCS12 */\n#endif /* !NO_PWDBASED */\n"
  },
  {
    "path": "src/wolfcrypt/src/wc_pkcs11.c",
    "content": "/* wc_pkcs11.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_PKCS11\n\n#include <dlfcn.h>\n\n#include <wolfssl/wolfcrypt/wc_pkcs11.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/asn.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#ifndef NO_RSA\n    #include <wolfssl/wolfcrypt/rsa.h>\n#endif\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n#define MAX_EC_PARAM_LEN   16\n\n#if defined(NO_PKCS11_RSA) && !defined(NO_RSA)\n    #define NO_RSA\n#endif\n#if defined(NO_PKCS11_ECC) && defined(HAVE_ECC)\n    #undef HAVE_ECC\n#endif\n#if defined(NO_PKCS11_AES) && !defined(NO_AES)\n    #define NO_AES\n#endif\n#if defined(NO_PKCS11_AESGCM) && defined(HAVE_AESGCM)\n    #undef HAVE_AESGCM\n#endif\n#if defined(NO_PKCS11_AESCBC) && defined(HAVE_AES_CBC)\n    #undef HAVE_AES_CBC\n#endif\n#if defined(NO_PKCS11_HMAC) && !defined(NO_HMAC)\n    #define NO_HMAC\n#endif\n#if defined(NO_PKCS11_RNG) && !defined(WC_NO_RNG)\n    #define WC_NO_RNG\n#endif\n\n\n#if defined(HAVE_ECC) && !defined(NO_PKCS11_ECDH)\nstatic CK_BBOOL ckFalse = CK_FALSE;\n#endif\n#if !defined(NO_RSA) || defined(HAVE_ECC) || (!defined(NO_AES) && \\\n           (defined(HAVE_AESGCM) || defined(HAVE_AES_CBC))) || !defined(NO_HMAC)\nstatic CK_BBOOL ckTrue  = CK_TRUE;\n#endif\n\n#ifndef NO_RSA\nstatic CK_KEY_TYPE rsaKeyType  = CKK_RSA;\n#endif\n#ifdef HAVE_ECC\nstatic CK_KEY_TYPE ecKeyType   = CKK_EC;\n#endif\n#if !defined(NO_RSA) || defined(HAVE_ECC)\nstatic CK_OBJECT_CLASS pubKeyClass     = CKO_PUBLIC_KEY;\nstatic CK_OBJECT_CLASS privKeyClass    = CKO_PRIVATE_KEY;\n#endif\n#if (!defined(NO_AES) && (defined(HAVE_AESGCM) || defined(HAVE_AES_CBC))) || \\\n            !defined(NO_HMAC) || (defined(HAVE_ECC) && !defined(NO_PKCS11_ECDH))\nstatic CK_OBJECT_CLASS secretKeyClass  = CKO_SECRET_KEY;\n#endif\n\n/**\n * Load library, get function list and initialize PKCS#11.\n *\n * @param  dev     [in]  Device object.\n * @param  library [in]  Library name including path.\n * @return  BAD_FUNC_ARG when dev or library are NULL pointers.\n *          BAD_PATH_ERROR when dynamic library cannot be opened.\n *          WC_INIT_E when the initialization PKCS#11 fails.\n *          WC_HW_E when unable to get PKCS#11 function list.\n *          0 on success.\n */\nint wc_Pkcs11_Initialize(Pkcs11Dev* dev, const char* library, void* heap)\n{\n    int                  ret = 0;\n    void*                func;\n    CK_C_INITIALIZE_ARGS args;\n\n    if (dev == NULL || library == NULL)\n        ret = BAD_FUNC_ARG;\n\n    if (ret == 0) {\n        dev->heap = heap;\n        dev->dlHandle = dlopen(library, RTLD_NOW | RTLD_LOCAL);\n        if (dev->dlHandle == NULL) {\n            WOLFSSL_MSG(dlerror());\n            ret = BAD_PATH_ERROR;\n        }\n    }\n\n    if (ret == 0) {\n        dev->func = NULL;\n        func = dlsym(dev->dlHandle, \"C_GetFunctionList\");\n        if (func == NULL)\n            ret = WC_HW_E;\n    }\n    if (ret == 0) {\n        if (((CK_C_GetFunctionList)func)(&dev->func) != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    if (ret == 0) {\n        XMEMSET(&args, 0x00, sizeof(args));\n        args.flags = CKF_OS_LOCKING_OK;\n        if (dev->func->C_Initialize(&args) != CKR_OK)\n            ret = WC_INIT_E;\n    }\n\n    if (ret != 0)\n        wc_Pkcs11_Finalize(dev);\n\n    return ret;\n}\n\n/**\n * Close the Pkcs#11 library.\n *\n * @param  dev  [in]  Device object.\n */\nvoid wc_Pkcs11_Finalize(Pkcs11Dev* dev)\n{\n    if (dev != NULL && dev->dlHandle != NULL) {\n        if (dev->func != NULL) {\n            dev->func->C_Finalize(NULL);\n            dev->func = NULL;\n        }\n        dlclose(dev->dlHandle);\n        dev->dlHandle = NULL;\n    }\n}\n\n/**\n * Set up a token for use.\n *\n * @param  token      [in]  Token object.\n * @param  dev        [in]  PKCS#11 device object.\n * @param  slotId     [in]  Slot number of the token.<br>\n *                          Passing -1 uses the first available slot.\n * @param  tokenName  [in]  Name of token to initialize.\n * @param  userPin    [in]  PIN to use to login as user.\n * @param  userPinSz  [in]  Number of bytes in PIN.\n * @return  BAD_FUNC_ARG when token, dev and/or tokenName is NULL.\n *          WC_INIT_E when initializing token fails.\n *          WC_HW_E when another PKCS#11 library call fails.\n *          -1 when no slot available.\n *          0 on success.\n */\nint wc_Pkcs11Token_Init(Pkcs11Token* token, Pkcs11Dev* dev, int slotId,\n    const char* tokenName, const unsigned char* userPin, int userPinSz)\n{\n    int         ret = 0;\n    CK_RV       rv;\n    CK_SLOT_ID* slot = NULL;\n    CK_ULONG    slotCnt = 0;\n\n    if (token == NULL || dev == NULL || tokenName == NULL)\n        ret = BAD_FUNC_ARG;\n\n    if (ret == 0) {\n        if (slotId < 0) {\n            /* Use first available slot with a token. */\n            rv = dev->func->C_GetSlotList(CK_TRUE, NULL, &slotCnt);\n            if (rv != CKR_OK)\n                ret = WC_HW_E;\n            if (ret == 0) {\n                slot = (CK_SLOT_ID*)XMALLOC(slotCnt * sizeof(*slot), dev->heap,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n                if (slot == NULL)\n                    ret = MEMORY_E;\n            }\n            if (ret == 0) {\n                rv = dev->func->C_GetSlotList(CK_TRUE, slot, &slotCnt);\n                if (rv != CKR_OK)\n                    ret = WC_HW_E;\n            }\n            if (ret == 0) {\n                if (slotCnt > 0)\n                    slotId = (int)slot[0];\n                else\n                    ret = WC_HW_E;\n            }\n        }\n    }\n    if (ret == 0) {\n        token->func = dev->func;\n        token->slotId = (CK_SLOT_ID)slotId;\n        token->handle = NULL_PTR;\n        token->userPin = (CK_UTF8CHAR_PTR)userPin;\n        token->userPinSz = (CK_ULONG)userPinSz;\n    }\n\n    if (slot != NULL)\n        XFREE(slot, dev->heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    return ret;\n}\n\n/**\n * Finalize token.\n * Closes all sessions on token.\n *\n * @param  token  [in]  Token object.\n */\nvoid wc_Pkcs11Token_Final(Pkcs11Token* token)\n{\n    if (token != NULL && token->func != NULL) {\n        token->func->C_CloseAllSessions(token->slotId);\n        token->handle = NULL_PTR;\n        ForceZero(token->userPin, (word32)token->userPinSz);\n    }\n}\n\n/**\n * Open a session on a token.\n *\n * @param  token      [in]  Token object.\n * @param  session    [in]  Session object.\n * @param  readWrite  [in]  Boolean indicating to open session for Read/Write.\n * @return  BAD_FUNC_ARG when token or session is NULL.\n *          WC_HW_E when opening the session fails.\n *          0 on success.\n */\nstatic int Pkcs11OpenSession(Pkcs11Token* token, Pkcs11Session* session,\n                             int readWrite)\n{\n    int   ret = 0;\n    CK_RV rv;\n\n    if (token == NULL || session == NULL)\n        ret = BAD_FUNC_ARG;\n\n    if (ret == 0) {\n        if (token->handle != NULL_PTR)\n            session->handle = token->handle;\n        else {\n            /* Create a new session. */\n            CK_FLAGS flags = CKF_SERIAL_SESSION;\n\n            if (readWrite)\n                flags |= CKF_RW_SESSION;\n\n            rv = token->func->C_OpenSession(token->slotId, flags,\n                                            (CK_VOID_PTR)NULL, (CK_NOTIFY)NULL,\n                                            &session->handle);\n            if (rv != CKR_OK)\n                ret = WC_HW_E;\n            if (ret == 0 && token->userPin != NULL) {\n                rv = token->func->C_Login(session->handle, CKU_USER,\n                                              token->userPin, token->userPinSz);\n                if (rv != CKR_OK)\n                    ret = WC_HW_E;\n            }\n        }\n    }\n    if (ret == 0) {\n        session->func = token->func;\n        session->slotId = token->slotId;\n    }\n\n    return ret;\n}\n\n/**\n * Close a session on a token.\n * Won't close a session created externally.\n *\n * @param  token    [in]  Token object.\n * @param  session  [in]  Session object.\n */\nstatic void Pkcs11CloseSession(Pkcs11Token* token, Pkcs11Session* session)\n{\n    if (token != NULL && session != NULL && token->handle != session->handle) {\n        if (token->userPin != NULL)\n            session->func->C_Logout(session->handle);\n        session->func->C_CloseSession(session->handle);\n    }\n}\n\n/**\n * Open a session on the token to be used for all operations.\n *\n * @param  token      [in]  Token object.\n * @param  readWrite  [in]  Boolean indicating to open session for Read/Write.\n * @return  BAD_FUNC_ARG when token is NULL.\n *          WC_HW_E when opening the session fails.\n *          0 on success.\n */\nint wc_Pkcs11Token_Open(Pkcs11Token* token, int readWrite)\n{\n    int ret = 0;\n    Pkcs11Session session;\n\n    if (token == NULL)\n        ret = BAD_FUNC_ARG;\n\n    if (ret == 0) {\n        ret = Pkcs11OpenSession(token, &session, readWrite);\n        token->handle = session.handle;\n    }\n\n    return ret;\n}\n\n/**\n * Close the token's session.\n * All object, like keys, will be destoyed.\n *\n * @param  token    [in]  Token object.\n */\nvoid wc_Pkcs11Token_Close(Pkcs11Token* token)\n{\n    Pkcs11Session session;\n\n    if (token != NULL) {\n        session.func = token->func;\n        session.handle = token->handle;\n        token->handle = NULL_PTR;\n        Pkcs11CloseSession(token, &session);\n    }\n}\n\n\n#if (!defined(NO_AES) && (defined(HAVE_AESGCM) || defined(HAVE_AES_CBC))) || \\\n                                                               !defined(NO_HMAC)\nstatic int Pkcs11CreateSecretKey(CK_OBJECT_HANDLE* key, Pkcs11Session* session,\n                                 CK_KEY_TYPE keyType, unsigned char* data,\n                                 int len, unsigned char* id, int idLen)\n{\n    int              ret = 0;\n    CK_RV            rv;\n    CK_ATTRIBUTE     keyTemplate[] = {\n        { CKA_CLASS,    &secretKeyClass, sizeof(secretKeyClass) },\n        { CKA_KEY_TYPE, &keyType,        sizeof(keyType)        },\n        { CKA_ENCRYPT,  &ckTrue,         sizeof(ckTrue)         },\n        { CKA_VALUE,    NULL,            0                      },\n        { CKA_ID,       id,              (CK_ULONG)idLen        }\n    };\n    int              keyTmplCnt = 4;\n\n    WOLFSSL_MSG(\"PKCS#11: Create Secret Key\");\n\n    /* Set the modulus and public exponent data. */\n    keyTemplate[3].pValue     = data;\n    keyTemplate[3].ulValueLen = (CK_ULONG)len;\n\n    if (idLen > 0)\n        keyTmplCnt++;\n\n    /* Create an object containing key data for device to use. */\n    rv = session->func->C_CreateObject(session->handle, keyTemplate, keyTmplCnt,\n                                                                           key);\n    if (rv != CKR_OK)\n        ret = WC_HW_E;\n\n    return ret;\n}\n#endif\n\n#ifndef NO_RSA\n/**\n * Create a PKCS#11 object containing the RSA private key data.\n *\n * @param  privateKey [out]  Henadle to private key object.\n * @param  session    [in]   Session object.\n * @param  rsaKey     [in]   RSA key with private key data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11CreateRsaPrivateKey(CK_OBJECT_HANDLE* privateKey,\n                                     Pkcs11Session* session,\n                                     RsaKey* rsaKey)\n{\n    int             ret = 0;\n    CK_RV           rv;\n    CK_ATTRIBUTE    keyTemplate[] = {\n        { CKA_CLASS,            &privKeyClass, sizeof(privKeyClass) },\n        { CKA_KEY_TYPE,         &rsaKeyType,   sizeof(rsaKeyType)   },\n        { CKA_DECRYPT,          &ckTrue,       sizeof(ckTrue)       },\n        { CKA_MODULUS,          NULL,          0                    },\n        { CKA_PRIVATE_EXPONENT, NULL,          0                    },\n        { CKA_PRIME_1,          NULL,          0                    },\n        { CKA_PRIME_2,          NULL,          0                    },\n        { CKA_EXPONENT_1,       NULL,          0                    },\n        { CKA_EXPONENT_2,       NULL,          0                    },\n        { CKA_COEFFICIENT,      NULL,          0                    },\n        { CKA_PUBLIC_EXPONENT,  NULL,          0                    }\n    };\n    CK_ULONG        keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate);\n\n    /* Set the modulus and private key data. */\n    keyTemplate[ 3].pValue     = rsaKey->n.raw.buf;\n    keyTemplate[ 3].ulValueLen = rsaKey->n.raw.len;\n    keyTemplate[ 4].pValue     = rsaKey->d.raw.buf;\n    keyTemplate[ 4].ulValueLen = rsaKey->d.raw.len;\n    keyTemplate[ 5].pValue     = rsaKey->p.raw.buf;\n    keyTemplate[ 5].ulValueLen = rsaKey->p.raw.len;\n    keyTemplate[ 6].pValue     = rsaKey->q.raw.buf;\n    keyTemplate[ 6].ulValueLen = rsaKey->q.raw.len;\n    keyTemplate[ 7].pValue     = rsaKey->dP.raw.buf;\n    keyTemplate[ 7].ulValueLen = rsaKey->dP.raw.len;\n    keyTemplate[ 8].pValue     = rsaKey->dQ.raw.buf;\n    keyTemplate[ 8].ulValueLen = rsaKey->dQ.raw.len;\n    keyTemplate[ 9].pValue     = rsaKey->u.raw.buf;\n    keyTemplate[ 9].ulValueLen = rsaKey->u.raw.len;\n    keyTemplate[10].pValue     = rsaKey->e.raw.buf;\n    keyTemplate[10].ulValueLen = rsaKey->e.raw.len;\n\n    rv = session->func->C_CreateObject(session->handle, keyTemplate, keyTmplCnt,\n                                                                    privateKey);\n    if (rv != CKR_OK)\n        ret = WC_HW_E;\n\n    return ret;\n}\n#endif\n\n#ifdef HAVE_ECC\n/**\n * Set the ECC parameters into the template.\n *\n * @param  key   [in]  ECC key.\n * @param  tmpl  [in]  PKCS#11 template.\n * @param  idx   [in]  Index of template to put parameters into.\n * @return NOT_COMPILE_IN when the EC parameters are not known.\n *         0 on success.\n */\nstatic int Pkcs11EccSetParams(ecc_key* key, CK_ATTRIBUTE* tmpl, int idx)\n{\n    int ret = 0;\n\n    if (key->dp != NULL && key->dp->oid != NULL) {\n        unsigned char* derParams = tmpl[idx].pValue;\n        /* ASN.1 encoding: OBJ + ecc parameters OID */\n        tmpl[idx].ulValueLen = key->dp->oidSz + 2;\n        derParams[0] = ASN_OBJECT_ID;\n        derParams[1] = key->dp->oidSz;\n        XMEMCPY(derParams + 2, key->dp->oid, key->dp->oidSz);\n    }\n    else\n        ret = NOT_COMPILED_IN;\n\n    return ret;\n}\n\n/**\n * Create a PKCS#11 object containing the ECC private key data.\n *\n * @param  privateKey   [out]  Henadle to private key object.\n * @param  session      [in]   Session object.\n * @param  private_key  [in]   ECC private key.\n * @param  operation    [in]   Cryptographic operation key is to be used for.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11CreateEccPrivateKey(CK_OBJECT_HANDLE* privateKey,\n                                     Pkcs11Session* session,\n                                     ecc_key* private_key,\n                                     CK_ATTRIBUTE_TYPE operation)\n{\n    int             ret = 0;\n    CK_RV           rv;\n    CK_UTF8CHAR     params[MAX_EC_PARAM_LEN];\n    CK_ATTRIBUTE    keyTemplate[] = {\n        { CKA_CLASS,     &privKeyClass, sizeof(privKeyClass) },\n        { CKA_KEY_TYPE,  &ecKeyType,    sizeof(ecKeyType)    },\n        { operation,     &ckTrue,       sizeof(ckTrue)       },\n        { CKA_EC_PARAMS, params,        0                    },\n        { CKA_VALUE,     NULL,          0                    }\n    };\n    CK_ULONG        keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate);\n\n    ret = Pkcs11EccSetParams(private_key, keyTemplate, 3);\n    if (ret == 0) {\n        keyTemplate[4].pValue     = private_key->k.raw.buf;\n        keyTemplate[4].ulValueLen = private_key->k.raw.len;\n\n        rv = session->func->C_CreateObject(session->handle, keyTemplate,\n                                                        keyTmplCnt, privateKey);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    return ret;\n}\n#endif\n\n#if !defined(NO_RSA) || defined(HAVE_ECC) || (!defined(NO_AES) && \\\n           (defined(HAVE_AESGCM) || defined(HAVE_AES_CBC))) || !defined(NO_HMAC)\n/**\n * Check if mechanism is available in session on token.\n *\n * @param  session  [in]  Session object.\n * @param  mech     [in]  Mechanism to look for.\n * @return  NOT_COMPILED_IN when mechanism not avaialble.\n *          0 when mechanism is available.\n */\nstatic int Pkcs11MechAvail(Pkcs11Session* session, CK_MECHANISM_TYPE mech)\n{\n    int               ret = 0;\n    CK_RV             rv;\n    CK_MECHANISM_INFO mechInfo;\n\n    rv = session->func->C_GetMechanismInfo(session->slotId, mech, &mechInfo);\n    if (rv != CKR_OK)\n        ret = NOT_COMPILED_IN;\n\n    return ret;\n}\n#endif\n\n#ifndef NO_HMAC\n/**\n * Return the mechanism type and key type for the digest type when using HMAC.\n *\n * @param  macType   [in]  Digest type - e.g. WC_SHA256.\n * @param  mechType  [in]  Mechanism type - e.g. CKM_SHA256_HMAC.\n * @param  keyType   [in]  Key type - e.g. CKK_SHA256_HMAC.\n * @return  NOT_COMPILED_IN if the digest algorithm isn't recognised.\n *          0 otherwise.\n */\nstatic int Pkcs11HmacTypes(int macType, int* mechType, int* keyType)\n{\n    int ret = 0;\n\n    switch (macType)\n    {\n    #ifndef NO_MD5\n        case WC_MD5:\n            *mechType = CKM_MD5_HMAC;\n            *keyType = CKK_MD5_HMAC;\n            break;\n    #endif\n    #ifndef NO_SHA\n        case WC_SHA:\n            *mechType = CKM_SHA_1_HMAC;\n            *keyType = CKK_SHA_1_HMAC;\n            break;\n    #endif\n    #ifdef WOLFSSL_SHA224\n        case WC_SHA224:\n            *mechType = CKM_SHA224_HMAC;\n            *keyType = CKK_SHA224_HMAC;\n            break;\n    #endif\n    #ifndef NO_SHA256\n        case WC_SHA256:\n            *mechType = CKM_SHA256_HMAC;\n            *keyType = CKK_SHA256_HMAC;\n            break;\n    #endif\n    #ifdef WOLFSSL_SHA384\n        case WC_SHA384:\n            *mechType = CKM_SHA384_HMAC;\n            *keyType = CKK_SHA384_HMAC;\n            break;\n    #endif\n    #ifdef WOLFSSL_SHA512\n        case WC_SHA512:\n            *mechType = CKM_SHA512_HMAC;\n            *keyType = CKK_SHA512_HMAC;\n            break;\n    #endif\n        default:\n            ret = NOT_COMPILED_IN;\n            break;\n    }\n\n    return ret;\n}\n#endif\n\n/**\n * Store the private key on the token in the session.\n *\n * @param  token  [in]  Token to store private key on.\n * @param  type   [in]  Key type.\n * @param  clear  [in]  Clear out the private data from software key.\n * @param  key    [in]  Key type specific object.\n * @return  NOT_COMPILED_IN when mechanism not available.\n *          0 on success.\n */\nint wc_Pkcs11StoreKey(Pkcs11Token* token, int type, int clear, void* key)\n{\n    int               ret = 0;\n    Pkcs11Session     session;\n    CK_OBJECT_HANDLE  privKey = NULL_PTR;\n\n    ret = Pkcs11OpenSession(token, &session, 1);\n    if (ret == 0) {\n        switch (type) {\n    #if !defined(NO_AES) && defined(HAVE_AESGCM)\n            case PKCS11_KEY_TYPE_AES_GCM: {\n                Aes* aes = (Aes*)key;\n\n                ret = Pkcs11MechAvail(&session, CKM_AES_GCM);\n                if (ret == 0) {\n                    ret = Pkcs11CreateSecretKey(&privKey, &session, CKK_AES,\n                                                (unsigned char*)aes->devKey,\n                                                aes->keylen,\n                                                (unsigned char*)aes->id,\n                                                aes->idLen);\n                }\n                if (ret == 0 && clear)\n                    ForceZero(aes->devKey, aes->keylen);\n                break;\n            }\n    #endif\n    #if !defined(NO_AES) && defined(HAVE_AES_CBC)\n            case PKCS11_KEY_TYPE_AES_CBC: {\n                Aes* aes = (Aes*)key;\n\n                ret = Pkcs11MechAvail(&session, CKM_AES_CBC);\n                if (ret == 0) {\n                    ret = Pkcs11CreateSecretKey(&privKey, &session, CKK_AES,\n                                                (unsigned char*)aes->devKey,\n                                                aes->keylen,\n                                                (unsigned char*)aes->id,\n                                                aes->idLen);\n                }\n                if (ret == 0 && clear)\n                    ForceZero(aes->devKey, aes->keylen);\n                break;\n            }\n    #endif\n    #ifndef NO_HMAC\n            case PKCS11_KEY_TYPE_HMAC: {\n                Hmac* hmac = (Hmac*)key;\n                int mechType;\n                int keyType;\n\n                ret = Pkcs11HmacTypes(hmac->macType, &mechType, &keyType);\n                if (ret == NOT_COMPILED_IN)\n                    break;\n\n                if (ret == 0)\n                    ret = Pkcs11MechAvail(&session, mechType);\n                if (ret == 0) {\n                    ret = Pkcs11CreateSecretKey(&privKey, &session, keyType,\n                                                (unsigned char*)hmac->keyRaw,\n                                                hmac->keyLen,\n                                                (unsigned char*)hmac->id,\n                                                hmac->idLen);\n                    if (ret == WC_HW_E) {\n                        ret = Pkcs11CreateSecretKey(&privKey, &session,\n                                                   CKK_GENERIC_SECRET,\n                                                   (unsigned char*)hmac->keyRaw,\n                                                   hmac->keyLen,\n                                                   (unsigned char*)hmac->id,\n                                                   hmac->idLen);\n                    }\n                }\n                break;\n            }\n    #endif\n    #ifndef NO_RSA\n            case PKCS11_KEY_TYPE_RSA: {\n                RsaKey* rsaKey = (RsaKey*)key;\n\n                ret = Pkcs11MechAvail(&session, CKM_RSA_X_509);\n                if (ret == 0)\n                    ret = Pkcs11CreateRsaPrivateKey(&privKey, &session, rsaKey);\n                if (ret == 0 && clear) {\n                    mp_forcezero(&rsaKey->u);\n                    mp_forcezero(&rsaKey->dQ);\n                    mp_forcezero(&rsaKey->dP);\n                    mp_forcezero(&rsaKey->q);\n                    mp_forcezero(&rsaKey->p);\n                    mp_forcezero(&rsaKey->d);\n                }\n                break;\n            }\n    #endif\n    #ifdef HAVE_ECC\n            case PKCS11_KEY_TYPE_EC: {\n                ecc_key* eccKey = (ecc_key*)key;\n                int      ret2 = NOT_COMPILED_IN;\n\n        #ifndef NO_PKCS11_ECDH\n                /* Try ECDH mechanism first. */\n                ret = Pkcs11MechAvail(&session, CKM_ECDH1_DERIVE);\n                if (ret == 0) {\n                    ret = Pkcs11CreateEccPrivateKey(&privKey, &session, eccKey,\n                                                                    CKA_DERIVE);\n                }\n         #endif\n                if (ret == 0 || ret == NOT_COMPILED_IN) {\n                    /* Try ECDSA mechanism next. */\n                    ret2 = Pkcs11MechAvail(&session, CKM_ECDSA);\n                    if (ret2 == 0) {\n                        ret2 = Pkcs11CreateEccPrivateKey(&privKey, &session,\n                                                              eccKey, CKA_SIGN);\n                    }\n                    /* OK for this to fail if set for ECDH. */\n                    if (ret == NOT_COMPILED_IN)\n                        ret = ret2;\n                }\n                if (ret == 0 && clear)\n                    mp_forcezero(&eccKey->k);\n                break;\n            }\n    #endif\n            default:\n                ret = NOT_COMPILED_IN;\n                break;\n        }\n\n        Pkcs11CloseSession(token, &session);\n    }\n\n    (void)privKey;\n    (void)clear;\n    (void)key;\n\n    return ret;\n}\n\n#if !defined(NO_RSA) || defined(HAVE_ECC) || (!defined(NO_AES) && \\\n           (defined(HAVE_AESGCM) || defined(HAVE_AES_CBC))) || !defined(NO_HMAC)\n/**\n * Find the PKCS#11 object containing the RSA public or private key data with\n * the modulus specified.\n *\n * @param  key       [out]  Henadle to key object.\n * @param  keyClass  [in]   Public or private key class.\n * @param  keyType   [in]   Type of key.\n * @param  session   [in]   Session object.\n * @param  id        [in]   Identifier set against a key.\n * @param  idLen     [in]   Length of identifier.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11FindKeyById(CK_OBJECT_HANDLE* key, CK_OBJECT_CLASS keyClass,\n                             CK_KEY_TYPE keyType, Pkcs11Session* session,\n                             byte* id, int idLen)\n{\n    int             ret = 0;\n    CK_RV           rv;\n    CK_ULONG        count;\n    CK_ATTRIBUTE    keyTemplate[] = {\n        { CKA_CLASS,           &keyClass, sizeof(keyClass) },\n        { CKA_KEY_TYPE,        &keyType,  sizeof(keyType)  },\n        { CKA_ID,              id,        (CK_ULONG)idLen  }\n    };\n    CK_ULONG        keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate);\n\n    WOLFSSL_MSG(\"PKCS#11: Find Key By Id\");\n\n    rv = session->func->C_FindObjectsInit(session->handle, keyTemplate,\n                                                                    keyTmplCnt);\n    if (rv != CKR_OK)\n        ret = WC_HW_E;\n    if (ret == 0) {\n        rv = session->func->C_FindObjects(session->handle, key, 1, &count);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n        rv = session->func->C_FindObjectsFinal(session->handle);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0 && count == 0)\n        ret = WC_HW_E;\n\n    return ret;\n}\n#endif\n\n#ifndef NO_RSA\n/**\n * Find the PKCS#11 object containing the RSA public or private key data with\n * the modulus specified.\n *\n * @param  key       [out]  Henadle to key object.\n * @param  keyClass  [in]   Public or private key class.\n * @param  session   [in]   Session object.\n * @param  rsaKey    [in]   RSA key with modulus to search on.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11FindRsaKey(CK_OBJECT_HANDLE* key, CK_OBJECT_CLASS keyClass,\n                            Pkcs11Session* session, RsaKey* rsaKey)\n{\n    int             ret = 0;\n    CK_RV           rv;\n    CK_ULONG        count;\n    CK_ATTRIBUTE    keyTemplate[] = {\n        { CKA_CLASS,           &keyClass,   sizeof(keyClass)   },\n        { CKA_KEY_TYPE,        &rsaKeyType, sizeof(rsaKeyType) },\n        { CKA_MODULUS,         NULL,        0                  },\n    };\n    CK_ULONG        keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate);\n\n    /* Set the modulus. */\n    keyTemplate[2].pValue     = rsaKey->n.raw.buf;\n    keyTemplate[2].ulValueLen = rsaKey->n.raw.len;\n\n    rv = session->func->C_FindObjectsInit(session->handle, keyTemplate,\n                                                                    keyTmplCnt);\n    if (rv != CKR_OK)\n        ret = WC_HW_E;\n    if (ret == 0) {\n        rv = session->func->C_FindObjects(session->handle, key, 1, &count);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n        rv = session->func->C_FindObjectsFinal(session->handle);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    return ret;\n}\n\n/**\n * Exponentiate the input with the public part of the RSA key.\n * Used in public encrypt and decrypt.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11RsaPublic(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int              ret = 0;\n    CK_RV            rv;\n    CK_MECHANISM     mech;\n    CK_ULONG         outLen;\n    CK_OBJECT_HANDLE publicKey = NULL_PTR;\n    int              sessionKey = 0;\n    CK_ATTRIBUTE     keyTemplate[] = {\n        { CKA_CLASS,           &pubKeyClass, sizeof(pubKeyClass) },\n        { CKA_KEY_TYPE,        &rsaKeyType,  sizeof(rsaKeyType)  },\n        { CKA_ENCRYPT,         &ckTrue,      sizeof(ckTrue)      },\n        { CKA_MODULUS,         NULL,         0                   },\n        { CKA_PUBLIC_EXPONENT, NULL,         0                   }\n    };\n    CK_ULONG        keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate);\n\n    WOLFSSL_MSG(\"PKCS#11: RSA Public Key Operation\");\n\n    if (ret == 0 && info->pk.rsa.outLen == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n\n    if (ret == 0) {\n        if ((sessionKey = !mp_iszero(&info->pk.rsa.key->e))) {\n            /* Set the modulus and public exponent data. */\n            keyTemplate[3].pValue     = info->pk.rsa.key->n.raw.buf;\n            keyTemplate[3].ulValueLen = info->pk.rsa.key->n.raw.len;\n            keyTemplate[4].pValue     = info->pk.rsa.key->e.raw.buf;\n            keyTemplate[4].ulValueLen = info->pk.rsa.key->e.raw.len;\n\n            /* Create an object containing public key data for device to use. */\n            rv = session->func->C_CreateObject(session->handle, keyTemplate,\n                                                        keyTmplCnt, &publicKey);\n            if (rv != CKR_OK)\n                ret = WC_HW_E;\n        }\n        else {\n            ret = Pkcs11FindKeyById(&publicKey, CKO_PUBLIC_KEY, CKK_RSA,\n                                    session, info->pk.rsa.key->id,\n                                    info->pk.rsa.key->idLen);\n        }\n    }\n\n    if (ret == 0) {\n        /* Raw RSA encrypt/decrypt operation. */\n        mech.mechanism      = CKM_RSA_X_509;\n        mech.ulParameterLen = 0;\n        mech.pParameter     = NULL;\n\n        rv = session->func->C_EncryptInit(session->handle, &mech, publicKey);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0) {\n        outLen = (CK_ULONG)*info->pk.rsa.outLen;\n        rv = session->func->C_Encrypt(session->handle,\n                (CK_BYTE_PTR)info->pk.rsa.in, info->pk.rsa.inLen,\n                info->pk.rsa.out, &outLen);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0)\n        *info->pk.rsa.outLen = (word32)outLen;\n\n    if (sessionKey)\n        session->func->C_DestroyObject(session->handle, publicKey);\n\n    return ret;\n}\n\n/**\n * Exponentiate the input with the private part of the RSA key.\n * Used in private encrypt and decrypt.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11RsaPrivate(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int              ret = 0;\n    CK_RV            rv;\n    CK_MECHANISM     mech;\n    CK_ULONG         outLen;\n    CK_OBJECT_HANDLE privateKey = NULL_PTR;\n    int              sessionKey = 0;\n\n    WOLFSSL_MSG(\"PKCS#11: RSA Private Key Operation\");\n\n    if (ret == 0 && info->pk.rsa.outLen == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n\n    if (ret == 0) {\n        if ((sessionKey = !mp_iszero(&info->pk.rsa.key->d))) {\n            ret = Pkcs11CreateRsaPrivateKey(&privateKey, session,\n                                                              info->pk.rsa.key);\n        }\n        else if (info->pk.rsa.key->idLen > 0) {\n            ret = Pkcs11FindKeyById(&privateKey, CKO_PRIVATE_KEY, CKK_RSA,\n                                    session, info->pk.rsa.key->id,\n                                    info->pk.rsa.key->idLen);\n        }\n        else {\n            ret = Pkcs11FindRsaKey(&privateKey, CKO_PRIVATE_KEY, session,\n                                                              info->pk.rsa.key);\n        }\n    }\n\n    if (ret == 0) {\n        /* Raw RSA encrypt/decrypt operation. */\n        mech.mechanism      = CKM_RSA_X_509;\n        mech.ulParameterLen = 0;\n        mech.pParameter     = NULL;\n\n        rv = session->func->C_DecryptInit(session->handle, &mech, privateKey);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0) {\n        outLen = (CK_ULONG)*info->pk.rsa.outLen;\n        rv = session->func->C_Decrypt(session->handle,\n                (CK_BYTE_PTR)info->pk.rsa.in, info->pk.rsa.inLen,\n                info->pk.rsa.out, &outLen);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0)\n        *info->pk.rsa.outLen = (word32)outLen;\n\n    if (sessionKey)\n        session->func->C_DestroyObject(session->handle, privateKey);\n\n    return ret;\n}\n\n/**\n * Perform an RSA operation.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11Rsa(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int               ret = 0;\n    CK_RV             rv;\n    CK_MECHANISM_INFO mechInfo;\n\n    /* Check operation is supported. */\n    rv = session->func->C_GetMechanismInfo(session->slotId, CKM_RSA_X_509,\n                                                                     &mechInfo);\n    if (rv != CKR_OK)\n        ret = NOT_COMPILED_IN;\n\n    if (ret == 0) {\n        if (info->pk.rsa.type == RSA_PUBLIC_ENCRYPT ||\n                                      info->pk.rsa.type == RSA_PUBLIC_DECRYPT) {\n            if ((mechInfo.flags & CKF_ENCRYPT) == 0)\n                ret = NOT_COMPILED_IN;\n            else\n                ret = Pkcs11RsaPublic(session, info);\n        }\n        else if (info->pk.rsa.type == RSA_PRIVATE_ENCRYPT ||\n                                     info->pk.rsa.type == RSA_PRIVATE_DECRYPT) {\n            if ((mechInfo.flags & CKF_DECRYPT) == 0)\n                ret = NOT_COMPILED_IN;\n            else\n                ret = Pkcs11RsaPrivate(session, info);\n        }\n        else\n            ret = NOT_COMPILED_IN;\n    }\n\n    return ret;\n}\n\n#ifdef WOLFSSL_KEY_GEN\n/**\n * Get the RSA public key data from the PKCS#11 object.\n *\n * @param  key      [in]  RSA key to put the data into.\n * @param  session  [in]  Session object.\n * @param  pubkey   [in]  Public key object.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          MEMORY_E when a memory allocation fails.\n *          0 on success.\n */\nstatic int Pkcs11GetRsaPublicKey(RsaKey* key, Pkcs11Session* session,\n                                 CK_OBJECT_HANDLE pubKey)\n{\n    int            ret = 0;\n    unsigned char* mod = NULL;\n    unsigned char* exp = NULL;\n    int            modSz, expSz;\n    CK_ATTRIBUTE   tmpl[] = {\n        { CKA_MODULUS,         NULL_PTR, 0 },\n        { CKA_PUBLIC_EXPONENT, NULL_PTR, 0 }\n    };\n    CK_ULONG       tmplCnt = sizeof(tmpl) / sizeof(*tmpl);\n    CK_RV rv;\n\n    rv = session->func->C_GetAttributeValue(session->handle, pubKey, tmpl,\n                                                                       tmplCnt);\n    if (rv != CKR_OK)\n        ret = WC_HW_E;\n\n    if (ret == 0) {\n        modSz = tmpl[0].ulValueLen;\n        expSz = tmpl[1].ulValueLen;\n        mod = (unsigned char*)XMALLOC(modSz, key->heap,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n        if (mod == NULL)\n            ret = MEMORY_E;\n    }\n    if (ret == 0) {\n        exp = (unsigned char*)XMALLOC(expSz, key->heap,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n        if (exp == NULL)\n            ret = MEMORY_E;\n    }\n    if (ret == 0) {\n        tmpl[0].pValue = mod;\n        tmpl[1].pValue = exp;\n\n        rv = session->func->C_GetAttributeValue(session->handle, pubKey,\n                                                                 tmpl, tmplCnt);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0)\n        ret = wc_RsaPublicKeyDecodeRaw(mod, modSz, exp, expSz, key);\n\n    if (exp != NULL)\n        XFREE(exp, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n    if (mod != NULL)\n        XFREE(mod, key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    return ret;\n}\n\n/**\n * Perform an RSA key generation operation.\n * The private key data stays on the device.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11RsaKeyGen(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int               ret = 0;\n    RsaKey*           key = info->pk.rsakg.key;\n    CK_RV             rv;\n    CK_ULONG          bits = info->pk.rsakg.size;\n    CK_OBJECT_HANDLE  pubKey = NULL_PTR, privKey = NULL_PTR;\n    CK_MECHANISM      mech;\n    static CK_BYTE    pub_exp[] = { 0x01, 0x00, 0x01, 0x00 };\n    CK_ATTRIBUTE      pubKeyTmpl[] = {\n        { CKA_MODULUS_BITS,    &bits,    sizeof(bits)    },\n        { CKA_ENCRYPT,         &ckTrue,  sizeof(ckTrue)  },\n        { CKA_VERIFY,          &ckTrue,  sizeof(ckTrue)  },\n        { CKA_PUBLIC_EXPONENT, &pub_exp, sizeof(pub_exp) }\n    };\n    CK_ULONG          pubTmplCnt = sizeof(pubKeyTmpl)/sizeof(*pubKeyTmpl);\n    CK_ATTRIBUTE      privKeyTmpl[] = {\n        {CKA_DECRYPT,  &ckTrue, sizeof(ckTrue) },\n        {CKA_SIGN,     &ckTrue, sizeof(ckTrue) },\n        {CKA_ID,       NULL,    0              }\n    };\n    int               privTmplCnt = 2;\n    int               i;\n\n    ret = Pkcs11MechAvail(session, CKM_RSA_PKCS_KEY_PAIR_GEN);\n    if (ret == 0) {\n        WOLFSSL_MSG(\"PKCS#11: RSA Key Generation Operation\");\n\n        /* Most commonly used public exponent value (array initialized). */\n        if (info->pk.rsakg.e != WC_RSA_EXPONENT) {\n            for (i = 0; i < (int)sizeof(pub_exp); i++)\n                pub_exp[i] = (info->pk.rsakg.e >> (8 * i)) & 0xff;\n        }\n        for (i = (int)sizeof(pub_exp) - 1; pub_exp[i] == 0; i--) {\n        }\n        pubKeyTmpl[3].ulValueLen = i + 1;\n\n        if (key->idLen != 0) {\n            privKeyTmpl[privTmplCnt].pValue     = key->id;\n            privKeyTmpl[privTmplCnt].ulValueLen = key->idLen;\n            privTmplCnt++;\n        }\n\n        mech.mechanism      = CKM_RSA_PKCS_KEY_PAIR_GEN;\n        mech.ulParameterLen = 0;\n        mech.pParameter     = NULL;\n\n        rv = session->func->C_GenerateKeyPair(session->handle, &mech,\n                                                       pubKeyTmpl, pubTmplCnt,\n                                                       privKeyTmpl, privTmplCnt,\n                                                       &pubKey, &privKey);\n        if (rv != CKR_OK)\n            ret = -1;\n    }\n\n    if (ret == 0)\n        ret = Pkcs11GetRsaPublicKey(key, session, pubKey);\n\n    if (pubKey != NULL_PTR)\n        ret = session->func->C_DestroyObject(session->handle, pubKey);\n    if (ret != 0 && privKey != NULL_PTR)\n        ret = session->func->C_DestroyObject(session->handle, privKey);\n\n    return ret;\n}\n#endif /* WOLFSSL_KEY_GEN */\n#endif /* !NO_RSA */\n\n#ifdef HAVE_ECC\n/**\n * Find the PKCS#11 object containing the ECC public or private key data with\n * the modulus specified.\n *\n * @param  key       [out]  Henadle to key object.\n * @param  keyClass  [in]   Public or private key class.\n * @param  session   [in]   Session object.\n * @param  eccKey    [in]   ECC key with parameters.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          MEMORY_E when a memory allocation fails.\n *          0 on success.\n */\nstatic int Pkcs11FindEccKey(CK_OBJECT_HANDLE* key, CK_OBJECT_CLASS keyClass,\n                            Pkcs11Session* session, ecc_key* eccKey)\n{\n    int             ret = 0;\n    int             i;\n    unsigned char*  ecPoint = NULL;\n    word32          len = 0;\n    CK_RV           rv;\n    CK_ULONG        count;\n    CK_UTF8CHAR     params[MAX_EC_PARAM_LEN];\n    CK_ATTRIBUTE    keyTemplate[] = {\n        { CKA_CLASS,           &keyClass,  sizeof(keyClass)  },\n        { CKA_KEY_TYPE,        &ecKeyType, sizeof(ecKeyType) },\n        { CKA_EC_PARAMS,       params,     0                 },\n        { CKA_EC_POINT,        NULL,       0                 },\n    };\n    CK_ULONG        attrCnt = 3;\n\n    ret = Pkcs11EccSetParams(eccKey, keyTemplate, 2);\n    if (ret == 0 && keyClass == CKO_PUBLIC_KEY) {\n        /* ASN1 encoded: OCT + uncompressed point */\n        len = 3 + 1 + 2 * eccKey->dp->size;\n        ecPoint = (unsigned char*)XMALLOC(len, eccKey->heap, DYNAMIC_TYPE_ECC);\n        if (ecPoint == NULL)\n            ret = MEMORY_E;\n    }\n    if (ret == 0 && keyClass == CKO_PUBLIC_KEY) {\n        len -= 3;\n        i = 0;\n        ecPoint[i++] = ASN_OCTET_STRING;\n        if (len >= ASN_LONG_LENGTH)\n            ecPoint[i++] = (ASN_LONG_LENGTH | 1);\n        ecPoint[i++] = len;\n        ret = wc_ecc_export_x963(eccKey, ecPoint + i, &len);\n    }\n    if (ret == 0 && keyClass == CKO_PUBLIC_KEY) {\n        keyTemplate[3].pValue     = ecPoint;\n        keyTemplate[3].ulValueLen = len + i;\n        attrCnt++;\n    }\n    if (ret == 0) {\n        rv = session->func->C_FindObjectsInit(session->handle, keyTemplate,\n                                                                       attrCnt);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0) {\n        rv = session->func->C_FindObjects(session->handle, key, 1, &count);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n        rv = session->func->C_FindObjectsFinal(session->handle);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    if (ecPoint != NULL)\n        XFREE(ecPoint, eccKey->heap, DYNAMIC_TYPE_ECC);\n\n    return ret;\n}\n\n/**\n * Create a PKCS#11 object containing the ECC public key data.\n * Encode the public key as an OCTET_STRING of the encoded point.\n *\n * @param  publicKey    [out]  Henadle to public key object.\n * @param  session      [in]   Session object.\n * @param  public_key   [in]   ECC public key.\n * @param  operation    [in]   Cryptographic operation key is to be used for.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          MEMORY_E when a memory allocation fails.\n *          0 on success.\n */\nstatic int Pkcs11CreateEccPublicKey(CK_OBJECT_HANDLE* publicKey,\n                                    Pkcs11Session* session,\n                                    ecc_key* public_key,\n                                    CK_ATTRIBUTE_TYPE operation)\n{\n    int             ret = 0;\n    int             i;\n    unsigned char*  ecPoint = NULL;\n    word32          len;\n    CK_RV           rv;\n    CK_UTF8CHAR     params[MAX_EC_PARAM_LEN];\n    CK_ATTRIBUTE    keyTemplate[] = {\n        { CKA_CLASS,     &pubKeyClass, sizeof(pubKeyClass) },\n        { CKA_KEY_TYPE,  &ecKeyType,   sizeof(ecKeyType)   },\n        { operation,     &ckTrue,      sizeof(ckTrue)      },\n        { CKA_EC_PARAMS, params,       0                   },\n        { CKA_EC_POINT,  NULL,         0                   }\n    };\n    CK_ULONG        keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate);\n\n    ret = Pkcs11EccSetParams(public_key, keyTemplate, 3);\n    if (ret == 0) {\n        /* ASN1 encoded: OCT + uncompressed point */\n        len = 3 + 1 + 2 * public_key->dp->size;\n        ecPoint = (unsigned char*)XMALLOC(len, public_key->heap,\n                                                              DYNAMIC_TYPE_ECC);\n        if (ecPoint == NULL)\n            ret = MEMORY_E;\n    }\n    if (ret == 0) {\n        len -= 3;\n        i = 0;\n        ecPoint[i++] = ASN_OCTET_STRING;\n        if (len >= ASN_LONG_LENGTH)\n            ecPoint[i++] = ASN_LONG_LENGTH | 1;\n        ecPoint[i++] = len;\n        ret = wc_ecc_export_x963(public_key, ecPoint + i, &len);\n    }\n    if (ret == 0) {\n        keyTemplate[4].pValue     = ecPoint;\n        keyTemplate[4].ulValueLen = len + i;\n\n        rv = session->func->C_CreateObject(session->handle, keyTemplate,\n                                                         keyTmplCnt, publicKey);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    if (ecPoint != NULL)\n        XFREE(ecPoint, public_key->heap, DYNAMIC_TYPE_ECC);\n\n    return ret;\n}\n\n#ifndef NO_PKCS11_EC_KEYGEN\n/**\n * Gets the public key data from the PKCS#11 object and puts into the ECC key.\n *\n * @param  key      [in]  ECC public key.\n * @param  session  [in]  Session object.\n * @param  pubKey   [in]  ECC public key PKCS#11 object.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          MEMORY_E when a memory allocation fails.\n *          0 on success.\n */\nstatic int Pkcs11GetEccPublicKey(ecc_key* key, Pkcs11Session* session,\n                                 CK_OBJECT_HANDLE pubKey)\n{\n    int            ret = 0;\n    word32         i = 0;\n    int            curveIdx;\n    unsigned char* point = NULL;\n    int            pointSz;\n    byte           tag;\n    CK_RV          rv;\n    CK_ATTRIBUTE   tmpl[] = {\n        { CKA_EC_POINT,  NULL_PTR, 0 },\n    };\n    CK_ULONG       tmplCnt = sizeof(tmpl) / sizeof(*tmpl);\n\n    rv = session->func->C_GetAttributeValue(session->handle, pubKey, tmpl,\n                                                                       tmplCnt);\n    if (rv != CKR_OK)\n        ret = WC_HW_E;\n\n    if (ret == 0) {\n        pointSz = (int)tmpl[0].ulValueLen;\n        point = (unsigned char*)XMALLOC(pointSz, key->heap, DYNAMIC_TYPE_ECC);\n        if (point == NULL)\n            ret = MEMORY_E;\n    }\n    if (ret == 0) {\n        tmpl[0].pValue = point;\n\n        rv = session->func->C_GetAttributeValue(session->handle, pubKey,\n                                                                 tmpl, tmplCnt);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    /* Make sure the data is big enough for ASN.1: OCT + uncompressed point */\n    if (ret == 0 && pointSz < key->dp->size * 2 + 1 + 2)\n        ret = ASN_PARSE_E;\n    /* Step over the OCTET_STRING wrapper. */\n    if (ret == 0 && GetASNTag(point, &i, &tag, pointSz) != 0)\n        ret = ASN_PARSE_E;\n    if (ret == 0 && tag != ASN_OCTET_STRING)\n        ret = ASN_PARSE_E;\n    if (ret == 0 && point[i] >= ASN_LONG_LENGTH) {\n        if (point[i++] != (ASN_LONG_LENGTH | 1))\n            ret = ASN_PARSE_E;\n        else if (pointSz < key->dp->size * 2 + 1 + 3)\n            ret = ASN_PARSE_E;\n    }\n    if (ret == 0 && point[i++] != key->dp->size * 2 + 1)\n        ret = ASN_PARSE_E;\n\n    if (ret == 0) {\n        curveIdx = wc_ecc_get_curve_idx(key->dp->id);\n        ret = wc_ecc_import_point_der(point + i, pointSz - i, curveIdx,\n                                                                  &key->pubkey);\n    }\n\n    if (point != NULL)\n        XFREE(point, key->heap, DYNAMIC_TYPE_ECC);\n\n    return ret;\n}\n\n/**\n * Perform an ECC key generation operation.\n * The private key data stays on the device.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11EcKeyGen(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int               ret = 0;\n    ecc_key*          key = info->pk.eckg.key;\n    CK_RV             rv;\n    CK_OBJECT_HANDLE  pubKey = NULL_PTR, privKey = NULL_PTR;\n    CK_MECHANISM      mech;\n    CK_UTF8CHAR       params[MAX_EC_PARAM_LEN];\n    CK_ATTRIBUTE      pubKeyTmpl[] = {\n        { CKA_EC_PARAMS,       params,   0               },\n        { CKA_ENCRYPT,         &ckTrue,  sizeof(ckTrue)  },\n        { CKA_VERIFY,          &ckTrue,  sizeof(ckTrue)  },\n    };\n    int               pubTmplCnt = sizeof(pubKeyTmpl)/sizeof(*pubKeyTmpl);\n    CK_ATTRIBUTE      privKeyTmpl[] = {\n        { CKA_DECRYPT,  &ckTrue, sizeof(ckTrue) },\n        { CKA_SIGN,     &ckTrue, sizeof(ckTrue) },\n        { CKA_DERIVE,   &ckTrue, sizeof(ckTrue) },\n        { CKA_ID,       NULL,    0              },\n    };\n    int               privTmplCnt = 3;\n\n    ret = Pkcs11MechAvail(session, CKM_EC_KEY_PAIR_GEN);\n    if (ret == 0) {\n        WOLFSSL_MSG(\"PKCS#11: EC Key Generation Operation\");\n\n        ret = Pkcs11EccSetParams(key, pubKeyTmpl, 0);\n    }\n    if (ret == 0) {\n        if (key->idLen != 0) {\n            privKeyTmpl[privTmplCnt].pValue     = key->id;\n            privKeyTmpl[privTmplCnt].ulValueLen = key->idLen;\n            privTmplCnt++;\n        }\n\n        mech.mechanism      = CKM_EC_KEY_PAIR_GEN;\n        mech.ulParameterLen = 0;\n        mech.pParameter     = NULL;\n\n        rv = session->func->C_GenerateKeyPair(session->handle, &mech,\n                                                       pubKeyTmpl, pubTmplCnt,\n                                                       privKeyTmpl, privTmplCnt,\n                                                       &pubKey, &privKey);\n        if (rv != CKR_OK)\n            ret = -1;\n    }\n\n    if (ret == 0)\n        ret = Pkcs11GetEccPublicKey(key, session, pubKey);\n\n    if (pubKey != NULL_PTR)\n        session->func->C_DestroyObject(session->handle, pubKey);\n    if (ret != 0 && privKey != NULL_PTR)\n        session->func->C_DestroyObject(session->handle, privKey);\n\n    return ret;\n}\n#endif\n\n#ifndef NO_PKCS11_ECDH\n/**\n * Extracts the secret key data from the PKCS#11 object.\n *\n * @param  session  [in]      Session object.\n * @param  secret   [in]      PKCS#11 object with the secret key data.\n * @param  out      [in]      Buffer to hold secret data.\n * @param  outLen   [in,out]  On in, length of buffer.\n *                            On out, the length of data in buffer.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11ExtractSecret(Pkcs11Session* session, CK_OBJECT_HANDLE secret,\n    byte* out, word32* outLen)\n{\n    int ret = 0;\n    CK_ATTRIBUTE tmpl[] = {\n      {CKA_VALUE, NULL_PTR, 0}\n    };\n    CK_ULONG     tmplCnt = sizeof(tmpl) / sizeof(*tmpl);\n    CK_RV rv;\n\n    rv = session->func->C_GetAttributeValue(session->handle, secret, tmpl,\n                                                                       tmplCnt);\n    if (rv != CKR_OK)\n        ret = WC_HW_E;\n    if (ret == 0) {\n        if (tmpl[0].ulValueLen > *outLen)\n            ret = BUFFER_E;\n    }\n    if (ret == 0) {\n        tmpl[0].pValue = out;\n        rv = session->func->C_GetAttributeValue(session->handle, secret,\n                                                                 tmpl, tmplCnt);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n        *outLen = (word32)tmpl[0].ulValueLen;\n    }\n\n    return ret;\n}\n\n/**\n * Performs the ECDH secret generation operation.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11ECDH(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int                    ret = 0;\n    int                    sessionKey = 0;\n    unsigned char*         point = NULL;\n    word32                 pointLen;\n    CK_RV                  rv;\n    CK_KEY_TYPE            keyType = CKK_GENERIC_SECRET;\n    CK_MECHANISM           mech;\n    CK_ECDH1_DERIVE_PARAMS params;\n    CK_OBJECT_HANDLE       privateKey = NULL_PTR;\n    CK_OBJECT_HANDLE       secret = CK_INVALID_HANDLE;\n    CK_ULONG               secSz;\n    CK_ATTRIBUTE           tmpl[] = {\n        { CKA_CLASS,       &secretKeyClass, sizeof(secretKeyClass) },\n        { CKA_KEY_TYPE,    &keyType,        sizeof(keyType)        },\n        { CKA_PRIVATE,     &ckFalse,        sizeof(ckFalse)        },\n        { CKA_SENSITIVE,   &ckFalse,        sizeof(ckFalse)        },\n        { CKA_EXTRACTABLE, &ckTrue,         sizeof(ckTrue)         },\n        { CKA_VALUE_LEN,   &secSz,          sizeof(secSz)          }\n    };\n    CK_ULONG               tmplCnt = sizeof(tmpl) / sizeof(*tmpl);\n\n    ret = Pkcs11MechAvail(session, CKM_ECDH1_DERIVE);\n    if (ret == 0 && info->pk.ecdh.outlen == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n    if (ret == 0) {\n        WOLFSSL_MSG(\"PKCS#11: EC Key Derivation Operation\");\n\n\n        if ((sessionKey = !mp_iszero(&info->pk.ecdh.private_key->k)))\n            ret = Pkcs11CreateEccPrivateKey(&privateKey, session,\n                                         info->pk.ecdh.private_key, CKA_DERIVE);\n        else if (info->pk.ecdh.private_key->idLen > 0) {\n            ret = Pkcs11FindKeyById(&privateKey, CKO_PRIVATE_KEY, CKK_EC,\n                                    session, info->pk.ecdh.private_key->id,\n                                    info->pk.ecdh.private_key->idLen);\n        }\n        else {\n            ret = Pkcs11FindEccKey(&privateKey, CKO_PRIVATE_KEY, session,\n                                                      info->pk.ecdh.public_key);\n        }\n    }\n    if (ret == 0) {\n        ret = wc_ecc_export_x963(info->pk.ecdh.public_key, NULL, &pointLen);\n        if (ret == LENGTH_ONLY_E) {\n            point = (unsigned char*)XMALLOC(pointLen,\n                                                 info->pk.ecdh.public_key->heap,\n                                                       DYNAMIC_TYPE_ECC_BUFFER);\n            ret = wc_ecc_export_x963(info->pk.ecdh.public_key, point,\n                                                                     &pointLen);\n        }\n    }\n\n    if (ret == 0) {\n        secSz = *info->pk.ecdh.outlen;\n        if (secSz > (CK_ULONG)info->pk.ecdh.private_key->dp->size)\n            secSz = info->pk.ecdh.private_key->dp->size;\n\n        params.kdf             = CKD_NULL;\n        params.pSharedData     = NULL;\n        params.ulSharedDataLen = 0;\n        params.pPublicData     = point;\n        params.ulPublicDataLen = pointLen;\n\n        mech.mechanism      = CKM_ECDH1_DERIVE;\n        mech.ulParameterLen = sizeof(params);\n        mech.pParameter     = &params;\n\n        rv = session->func->C_DeriveKey(session->handle, &mech, privateKey,\n                                                        tmpl, tmplCnt, &secret);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    if (ret == 0) {\n        ret = Pkcs11ExtractSecret(session, secret, info->pk.ecdh.out,\n                                                          info->pk.ecdh.outlen);\n    }\n\n    if (sessionKey)\n        session->func->C_DestroyObject(session->handle, privateKey);\n\n    if (point != NULL)\n        XFREE(point, info->pk.ecdh.public_key->heap, DYNAMIC_TYPE_ECC_BUFFER);\n\n    return ret;\n}\n#endif\n\n/**\n * Encode, in place, the ECDSA signature.\n * Two fixed width values into ASN.1 DER encoded SEQ { INT, INT }\n *\n * @param  sig  [in,out]  Signature data.\n * @param  sz   [in]      Size of original signature data.\n * @return  Length of the ASN.1 DER enencoded signature.\n */\nstatic word32 Pkcs11ECDSASig_Encode(byte* sig, word32 sz)\n{\n    word32 rHigh, sHigh, seqLen;\n    word32 rStart = 0, sStart = 0;\n    word32 sigSz, rSz, rLen, sSz, sLen;\n    word32 i;\n\n    /* Find first byte of data in r and s. */\n    while (sig[rStart] == 0x00 && rStart < sz - 1)\n        rStart++;\n    while (sig[sz + sStart] == 0x00 && sStart < sz - 1)\n        sStart++;\n    /* Check if 0 needs to be prepended to make integer a positive number. */\n    rHigh = sig[rStart] >> 7;\n    sHigh = sig[sz + sStart] >> 7;\n    /* Calculate length of integer to put into ASN.1 encoding. */\n    rLen = sz - rStart;\n    sLen = sz - sStart;\n    /* r and s: INT (2 bytes) + [ 0x00 ] + integer */\n    rSz = 2 + rHigh + rLen;\n    sSz = 2 + sHigh + sLen;\n    /* Calculate the complete ASN.1 DER encoded size. */\n    sigSz = rSz + sSz;\n    if (sigSz >= ASN_LONG_LENGTH)\n        seqLen = 3;\n    else\n        seqLen = 2;\n\n    /* Move s and then r integers into their final places. */\n    XMEMMOVE(sig + seqLen + rSz + (sSz - sLen), sig + sz + sStart, sLen);\n    XMEMMOVE(sig + seqLen       + (rSz - rLen), sig      + rStart, rLen);\n\n    /* Put the ASN.1 DER encoding around data. */\n    i = 0;\n    sig[i++] = ASN_CONSTRUCTED | ASN_SEQUENCE;\n    if (seqLen == 3)\n        sig[i++] = ASN_LONG_LENGTH | 0x01;\n    sig[i++] = sigSz;\n    sig[i++] = ASN_INTEGER;\n    sig[i++] = rHigh + (sz - rStart);\n    if (rHigh)\n        sig[i++] = 0x00;\n    i += sz - rStart;\n    sig[i++] = ASN_INTEGER;\n    sig[i++] = sHigh + (sz - sStart);\n    if (sHigh)\n        sig[i] = 0x00;\n\n    return seqLen + sigSz;\n}\n\n/**\n * Decode the ECDSA signature.\n * ASN.1 DER encode SEQ { INT, INT } converted to two fixed with values.\n *\n * @param  in    [in]  ASN.1 DER encoded signature.\n * @param  inSz  [in]  Size of ASN.1 signature.\n * @param  sig   [in]  Output buffer.\n * @param  sz    [in]  Size of output buffer.\n * @return  ASN_PARSE_E when the ASN.1 encoding is invalid.\n *          0 on success.\n */\nstatic int Pkcs11ECDSASig_Decode(const byte* in, word32 inSz, byte* sig,\n                                 word32 sz)\n{\n    int ret = 0;\n    word32 i = 0;\n    byte   tag;\n    int len, seqLen = 2;\n\n    /* Make sure zeros in place when decoding short integers. */\n    XMEMSET(sig, 0, sz * 2);\n\n    /* Check min data for: SEQ + INT. */\n    if (inSz < 5)\n        ret = ASN_PARSE_E;\n    /* Check SEQ */\n    if (ret == 0 && in[i++] != (ASN_CONSTRUCTED | ASN_SEQUENCE))\n        ret = ASN_PARSE_E;\n    if (ret == 0 && in[i] >= ASN_LONG_LENGTH) {\n        if (in[i] != (ASN_LONG_LENGTH | 0x01))\n            ret = ASN_PARSE_E;\n        else {\n            i++;\n            seqLen++;\n        }\n    }\n    if (ret == 0 && in[i++] != inSz - seqLen)\n        ret = ASN_PARSE_E;\n\n    /* Check INT */\n    if (ret == 0 && GetASNTag(in, &i, &tag, inSz) != 0)\n        ret = ASN_PARSE_E;\n    if (ret == 0 && tag != ASN_INTEGER)\n        ret = ASN_PARSE_E;\n    if (ret == 0 && (len = in[i++]) > sz + 1)\n        ret = ASN_PARSE_E;\n    /* Check there is space for INT data */\n    if (ret == 0 && i + len > inSz)\n        ret = ASN_PARSE_E;\n    if (ret == 0) {\n        /* Skip leading zero */\n        if (in[i] == 0x00) {\n            i++;\n            len--;\n        }\n        /* Copy r into sig. */\n        XMEMCPY(sig + sz - len, in + i, len);\n        i += len;\n    }\n\n    /* Check min data for: INT. */\n    if (ret == 0 && i + 2 > inSz)\n        ret = ASN_PARSE_E;\n    /* Check INT */\n    if (ret == 0 && GetASNTag(in, &i, &tag, inSz) != 0)\n        ret = ASN_PARSE_E;\n    if (ret == 0 && tag != ASN_INTEGER)\n        ret = ASN_PARSE_E;\n    if (ret == 0 && (len = in[i++]) > sz + 1)\n        ret = ASN_PARSE_E;\n    /* Check there is space for INT data */\n    if (ret == 0 && i + len > inSz)\n        ret = ASN_PARSE_E;\n    if (ret == 0) {\n        /* Skip leading zero */\n        if (in[i] == 0x00) {\n            i++;\n            len--;\n        }\n        /* Copy s into sig. */\n        XMEMCPY(sig + sz + sz - len, in + i, len);\n    }\n\n    return ret;\n}\n\n/**\n * Get the parameters from the private key on the device.\n *\n * @param  session  [in]  Session object.\n * @param  privKey  [in]  PKCS #11 object handle of private key..\n * @param  key      [in]  Ecc key to set parameters against.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11GetEccParams(Pkcs11Session* session, CK_OBJECT_HANDLE privKey,\n                              ecc_key* key)\n{\n    int          ret = 0;\n    int          curveId;\n    CK_RV        rv;\n    byte         oid[16];\n    CK_ATTRIBUTE template[] = {\n        { CKA_EC_PARAMS, (CK_VOID_PTR)oid, sizeof(oid) }\n    };\n\n    rv = session->func->C_GetAttributeValue(session->handle, privKey, template,\n                                                                             1);\n    if (rv != CKR_OK)\n        ret = WC_HW_E;\n    if (ret == 0) {\n        /* PKCS #11 wraps the OID in ASN.1 */\n        curveId = wc_ecc_get_curve_id_from_oid(oid + 2,\n                                            (word32)template[0].ulValueLen - 2);\n        if (curveId == ECC_CURVE_INVALID)\n            ret = WC_HW_E;\n    }\n    if (ret == 0)\n        ret = wc_ecc_set_curve(key, 0, curveId);\n\n    return ret;\n}\n\n/**\n * Performs the ECDSA signing operation.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11ECDSA_Sign(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int                    ret = 0;\n    int                    sessionKey = 0;\n    word32                 sz;\n    CK_RV                  rv;\n    CK_ULONG               outLen;\n    CK_MECHANISM           mech;\n    CK_MECHANISM_INFO      mechInfo;\n    CK_OBJECT_HANDLE       privateKey = NULL_PTR;\n\n    /* Check operation is supported. */\n    rv = session->func->C_GetMechanismInfo(session->slotId, CKM_ECDSA,\n                                                                     &mechInfo);\n    if (rv != CKR_OK || (mechInfo.flags & CKF_SIGN) == 0)\n        ret = NOT_COMPILED_IN;\n\n    if (ret == 0 && info->pk.eccsign.outlen == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n    if (ret == 0) {\n        WOLFSSL_MSG(\"PKCS#11: EC Signing Operation\");\n\n        if ((sessionKey = !mp_iszero(&info->pk.eccsign.key->k)))\n            ret = Pkcs11CreateEccPrivateKey(&privateKey, session,\n                                                info->pk.eccsign.key, CKA_SIGN);\n        else if (info->pk.eccsign.key->idLen > 0) {\n            ret = Pkcs11FindKeyById(&privateKey, CKO_PRIVATE_KEY, CKK_EC,\n                                    session, info->pk.eccsign.key->id,\n                                    info->pk.eccsign.key->idLen);\n            if (ret == 0 && info->pk.eccsign.key->dp == NULL) {\n                ret = Pkcs11GetEccParams(session, privateKey,\n                                                          info->pk.eccsign.key);\n            }\n        }\n        else {\n            ret = Pkcs11FindEccKey(&privateKey, CKO_PRIVATE_KEY, session,\n                                                          info->pk.eccsign.key);\n        }\n    }\n\n    if (ret == 0) {\n        sz = info->pk.eccsign.key->dp->size;\n        /* Maximum encoded size is two ordinates + 8 bytes of ASN.1. */\n        if (*info->pk.eccsign.outlen < (word32)wc_ecc_sig_size_calc(sz))\n            ret = BUFFER_E;\n    }\n\n    if (ret == 0) {\n        mech.mechanism      = CKM_ECDSA;\n        mech.ulParameterLen = 0;\n        mech.pParameter     = NULL;\n\n        rv = session->func->C_SignInit(session->handle, &mech, privateKey);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    if (ret == 0) {\n        outLen = *info->pk.eccsign.outlen;\n        rv = session->func->C_Sign(session->handle,\n                                   (CK_BYTE_PTR)info->pk.eccsign.in,\n                                   info->pk.eccsign.inlen, info->pk.eccsign.out,\n                                   &outLen);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    if (ret == 0) {\n        *info->pk.eccsign.outlen = Pkcs11ECDSASig_Encode(info->pk.eccsign.out,\n                                                         sz);\n    }\n\n    if (sessionKey)\n        session->func->C_DestroyObject(session->handle, privateKey);\n\n    return ret;\n}\n\n/**\n * Performs the ECDSA verification operation.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          MEMORY_E when a memory allocation fails.\n *          0 on success.\n */\nstatic int Pkcs11ECDSA_Verify(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int                    ret = 0;\n    CK_RV                  rv;\n    CK_MECHANISM           mech;\n    CK_MECHANISM_INFO      mechInfo;\n    CK_OBJECT_HANDLE       publicKey = NULL_PTR;\n    unsigned char*         sig = NULL;\n    word32                 sz = info->pk.eccverify.key->dp->size;\n\n    /* Check operation is supported. */\n    rv = session->func->C_GetMechanismInfo(session->slotId, CKM_ECDSA,\n                                                                     &mechInfo);\n    if (rv != CKR_OK || (mechInfo.flags & CKF_VERIFY) == 0)\n        ret = NOT_COMPILED_IN;\n\n    if (ret == 0 && info->pk.eccverify.res == NULL) {\n        ret = BAD_FUNC_ARG;\n    }\n\n    if (ret == 0) {\n        WOLFSSL_MSG(\"PKCS#11: EC Verification Operation\");\n\n        ret = Pkcs11CreateEccPublicKey(&publicKey, session,\n                                            info->pk.eccverify.key, CKA_VERIFY);\n    }\n\n    if (ret == 0) {\n        sig = XMALLOC(sz * 2, info->pk.eccverify.key->heap,\n                                                       DYNAMIC_TYPE_TMP_BUFFER);\n        if (sig == NULL)\n            ret = MEMORY_E;\n    }\n\n    if (ret == 0) {\n        ret = Pkcs11ECDSASig_Decode(info->pk.eccverify.sig,\n                                    info->pk.eccverify.siglen, sig, sz);\n    }\n    if (ret == 0) {\n        mech.mechanism      = CKM_ECDSA;\n        mech.ulParameterLen = 0;\n        mech.pParameter     = NULL;\n\n        rv = session->func->C_VerifyInit(session->handle, &mech, publicKey);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    if (ret == 0) {\n        *info->pk.eccverify.res = 0;\n        rv = session->func->C_Verify(session->handle,\n                                     (CK_BYTE_PTR)info->pk.eccverify.hash,\n                                     info->pk.eccverify.hashlen,\n                                     (CK_BYTE_PTR)sig, sz * 2);\n        if (rv == CKR_SIGNATURE_INVALID) {\n        }\n        else if (rv != CKR_OK)\n            ret = WC_HW_E;\n        else\n            *info->pk.eccverify.res = 1;\n    }\n\n    if (publicKey != NULL_PTR)\n        session->func->C_DestroyObject(session->handle, publicKey);\n\n    if (sig != NULL)\n        XFREE(sig, info->pk.eccverify.key->heap, DYNAMIC_TYPE_TMP_BUFFER);\n\n    return ret;\n}\n#endif\n\n#if !defined(NO_AES) && defined(HAVE_AESGCM)\n/**\n * Performs the AES-GCM encryption operation.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          MEMORY_E when a memory allocation fails.\n *          0 on success.\n */\nstatic int Pkcs11AesGcmEncrypt(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int                ret = 0;\n    CK_RV              rv;\n    Aes*               aes = info->cipher.aesgcm_enc.aes;\n    CK_GCM_PARAMS      params;\n    CK_MECHANISM_INFO  mechInfo;\n    CK_OBJECT_HANDLE   key = NULL_PTR;\n    CK_MECHANISM       mech;\n    CK_ULONG           outLen;\n\n    /* Check operation is supported. */\n    rv = session->func->C_GetMechanismInfo(session->slotId, CKM_AES_GCM,\n                                                                     &mechInfo);\n    if (rv != CKR_OK || (mechInfo.flags & CKF_ENCRYPT) == 0)\n        ret = NOT_COMPILED_IN;\n\n    if (ret == 0) {\n        WOLFSSL_MSG(\"PKCS#11: AES-GCM Encryption Operation\");\n    }\n\n    /* Create a private key object or find by id. */\n    if (ret == 0 && aes->idLen == 0) {\n        ret = Pkcs11CreateSecretKey(&key, session, CKK_AES,\n                                    (unsigned char*)aes->devKey, aes->keylen,\n                                    NULL, 0);\n\n    }\n    else if (ret == 0) {\n        ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session, aes->id,\n                                                                    aes->idLen);\n    }\n\n    if (ret == 0) {\n        params.pIv       = (CK_BYTE_PTR)info->cipher.aesgcm_enc.iv;\n        params.ulIvLen   = info->cipher.aesgcm_enc.ivSz;\n        params.pAAD      = (CK_BYTE_PTR)info->cipher.aesgcm_enc.authIn;\n        params.ulAADLen  = info->cipher.aesgcm_enc.authInSz;\n        params.ulTagBits = info->cipher.aesgcm_enc.authTagSz * 8;\n\n        mech.mechanism      = CKM_AES_GCM;\n        mech.ulParameterLen = sizeof(params);\n        mech.pParameter     = &params;\n\n        rv = session->func->C_EncryptInit(session->handle, &mech, key);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0) {\n        outLen = info->cipher.aesgcm_enc.sz;\n        rv = session->func->C_EncryptUpdate(session->handle,\n                                        (CK_BYTE_PTR)info->cipher.aesgcm_enc.in,\n                                        info->cipher.aesgcm_enc.sz,\n                                        info->cipher.aesgcm_enc.out,\n                                        &outLen);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0) {\n        /* Authentication tag comes out in final block. */\n        outLen = info->cipher.aesgcm_enc.authTagSz;\n        rv = session->func->C_EncryptFinal(session->handle,\n                                           info->cipher.aesgcm_enc.authTag,\n                                           &outLen);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    if (aes->idLen == 0 && key != NULL_PTR)\n        session->func->C_DestroyObject(session->handle, key);\n\n    return ret;\n}\n\n/**\n * Performs the AES-GCM decryption operation.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          MEMORY_E when a memory allocation fails.\n *          0 on success.\n */\nstatic int Pkcs11AesGcmDecrypt(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int                ret = 0;\n    CK_RV              rv;\n    Aes*               aes = info->cipher.aesgcm_enc.aes;\n    CK_GCM_PARAMS      params;\n    CK_MECHANISM_INFO  mechInfo;\n    CK_OBJECT_HANDLE   key = NULL_PTR;\n    CK_MECHANISM       mech;\n    CK_ULONG           outLen;\n    word32             len;\n\n    /* Check operation is supported. */\n    rv = session->func->C_GetMechanismInfo(session->slotId, CKM_AES_GCM,\n                                                                     &mechInfo);\n    if (rv != CKR_OK || (mechInfo.flags & CKF_DECRYPT) == 0)\n        ret = NOT_COMPILED_IN;\n\n    if (ret == 0) {\n        WOLFSSL_MSG(\"PKCS#11: AES-GCM Decryption Operation\");\n    }\n\n    /* Create a private key object or find by id. */\n    if (ret == 0 && aes->idLen == 0) {\n        ret = Pkcs11CreateSecretKey(&key, session, CKK_AES,\n                                    (unsigned char*)aes->devKey, aes->keylen,\n                                    NULL, 0);\n    }\n    else if (ret == 0) {\n        ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session, aes->id,\n                                                                    aes->idLen);\n    }\n\n    if (ret == 0) {\n        params.pIv       = (CK_BYTE_PTR)info->cipher.aesgcm_dec.iv;\n        params.ulIvLen   = info->cipher.aesgcm_dec.ivSz;\n        params.pAAD      = (CK_BYTE_PTR)info->cipher.aesgcm_dec.authIn;\n        params.ulAADLen  = info->cipher.aesgcm_dec.authInSz;\n        params.ulTagBits = info->cipher.aesgcm_dec.authTagSz * 8;\n\n        mech.mechanism      = CKM_AES_GCM;\n        mech.ulParameterLen = sizeof(params);\n        mech.pParameter     = &params;\n\n        rv = session->func->C_DecryptInit(session->handle, &mech, key);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0) {\n        outLen = len = info->cipher.aesgcm_dec.sz;\n        rv = session->func->C_DecryptUpdate(session->handle,\n                                        (CK_BYTE_PTR)info->cipher.aesgcm_dec.in,\n                                        info->cipher.aesgcm_dec.sz,\n                                        info->cipher.aesgcm_dec.out,\n                                        &outLen);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0) {\n        /* Put authentication tag in as encrypted data. */\n        outLen = len = (len + info->cipher.aesgcm_dec.authTagSz -\n                                                                (word32)outLen);\n        rv = session->func->C_DecryptUpdate(session->handle,\n                                   (CK_BYTE_PTR)info->cipher.aesgcm_dec.authTag,\n                                   info->cipher.aesgcm_dec.authTagSz,\n                                   info->cipher.aesgcm_dec.out,\n                                   &outLen);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0) {\n        outLen = len = (len - (word32)outLen);\n        /* Decrypted data comes out now. */\n        rv = session->func->C_DecryptFinal(session->handle,\n                                           info->cipher.aesgcm_dec.out,\n                                           &outLen);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    if (aes->idLen == 0 && key != NULL_PTR)\n        session->func->C_DestroyObject(session->handle, key);\n\n    return ret;\n}\n#endif\n\n#if !defined(NO_AES) && defined(HAVE_AES_CBC)\n/**\n * Performs the AES-CBC encryption operation.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          MEMORY_E when a memory allocation fails.\n *          0 on success.\n */\nstatic int Pkcs11AesCbcEncrypt(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int                ret = 0;\n    CK_RV              rv;\n    Aes*               aes = info->cipher.aescbc.aes;\n    CK_MECHANISM_INFO  mechInfo;\n    CK_OBJECT_HANDLE   key = NULL_PTR;\n    CK_MECHANISM       mech;\n    CK_ULONG           outLen;\n\n    /* Check operation is supported. */\n    rv = session->func->C_GetMechanismInfo(session->slotId, CKM_AES_CBC,\n                                                                     &mechInfo);\n    if (rv != CKR_OK || (mechInfo.flags & CKF_ENCRYPT) == 0)\n        ret = NOT_COMPILED_IN;\n\n    if (ret == 0) {\n        WOLFSSL_MSG(\"PKCS#11: AES-CBC Encryption Operation\");\n    }\n\n    /* Create a private key object or find by id. */\n    if (ret == 0 && aes->idLen == 0) {\n        ret = Pkcs11CreateSecretKey(&key, session, CKK_AES,\n                                    (unsigned char*)aes->devKey, aes->keylen,\n                                    NULL, 0);\n\n    }\n    else if (ret == 0) {\n        ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session, aes->id,\n                                                                    aes->idLen);\n    }\n\n    if (ret == 0) {\n        mech.mechanism      = CKM_AES_CBC;\n        mech.ulParameterLen = AES_BLOCK_SIZE;\n        mech.pParameter     = (CK_BYTE_PTR)info->cipher.aescbc.aes->reg;\n\n        rv = session->func->C_EncryptInit(session->handle, &mech, key);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0) {\n        outLen = info->cipher.aescbc.sz;\n        rv = session->func->C_Encrypt(session->handle,\n                                      (CK_BYTE_PTR)info->cipher.aescbc.in,\n                                      info->cipher.aescbc.sz,\n                                      info->cipher.aescbc.out,\n                                      &outLen);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    if (aes->idLen == 0 && key != NULL_PTR)\n        session->func->C_DestroyObject(session->handle, key);\n\n    return ret;\n}\n\n/**\n * Performs the AES-CBC decryption operation.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          MEMORY_E when a memory allocation fails.\n *          0 on success.\n */\nstatic int Pkcs11AesCbcDecrypt(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int                ret = 0;\n    CK_RV              rv;\n    Aes*               aes = info->cipher.aescbc.aes;\n    CK_MECHANISM_INFO  mechInfo;\n    CK_OBJECT_HANDLE   key = NULL_PTR;\n    CK_MECHANISM       mech;\n    CK_ULONG           outLen;\n\n    /* Check operation is supported. */\n    rv = session->func->C_GetMechanismInfo(session->slotId, CKM_AES_CBC,\n                                                                     &mechInfo);\n    if (rv != CKR_OK || (mechInfo.flags & CKF_DECRYPT) == 0)\n        ret = NOT_COMPILED_IN;\n\n    if (ret == 0) {\n        WOLFSSL_MSG(\"PKCS#11: AES-CBC Decryption Operation\");\n    }\n\n    /* Create a private key object or find by id. */\n    if (ret == 0 && aes->idLen == 0) {\n        ret = Pkcs11CreateSecretKey(&key, session, CKK_AES,\n                                    (unsigned char*)aes->devKey, aes->keylen,\n                                    NULL, 0);\n    }\n    else if (ret == 0) {\n        ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session, aes->id,\n                                                                    aes->idLen);\n    }\n\n    if (ret == 0) {\n        mech.mechanism      = CKM_AES_CBC;\n        mech.ulParameterLen = AES_BLOCK_SIZE;\n        mech.pParameter     = (CK_BYTE_PTR)info->cipher.aescbc.aes->reg;\n\n        rv = session->func->C_DecryptInit(session->handle, &mech, key);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    if (ret == 0) {\n        outLen = info->cipher.aescbc.sz;\n        rv = session->func->C_DecryptUpdate(session->handle,\n                                        (CK_BYTE_PTR)info->cipher.aescbc.in,\n                                        info->cipher.aescbc.sz,\n                                        info->cipher.aescbc.out,\n                                        &outLen);\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n\n    if (aes->idLen == 0 && key != NULL_PTR)\n        session->func->C_DestroyObject(session->handle, key);\n\n    return ret;\n}\n#endif\n\n#ifndef NO_HMAC\n/**\n * Updates or calculates the HMAC of the data.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11Hmac(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int                ret = 0;\n    CK_RV              rv;\n    Hmac*              hmac = info->hmac.hmac;\n    CK_MECHANISM_INFO  mechInfo;\n    CK_OBJECT_HANDLE   key = NULL_PTR;\n    CK_MECHANISM       mech;\n    CK_ULONG           outLen;\n    int                mechType;\n    int                keyType;\n\n    if (hmac->innerHashKeyed == WC_HMAC_INNER_HASH_KEYED_SW)\n        ret = NOT_COMPILED_IN;\n\n    if (ret == 0)\n        ret = Pkcs11HmacTypes(info->hmac.macType, &mechType, &keyType);\n    if (ret == 0) {\n        /* Check operation is supported. */\n        rv = session->func->C_GetMechanismInfo(session->slotId, mechType,\n                                                                     &mechInfo);\n        if (rv != CKR_OK || (mechInfo.flags & CKF_SIGN) == 0)\n            ret = NOT_COMPILED_IN;\n    }\n\n    /* Check whether key been used to initialized. */\n    if (ret == 0 && !hmac->innerHashKeyed) {\n        WOLFSSL_MSG(\"PKCS#11: HMAC Init\");\n\n        /* Check device supports key length. */\n        if (mechInfo.ulMaxKeySize > 0 &&\n                                       (hmac->keyLen < mechInfo.ulMinKeySize ||\n                                        hmac->keyLen > mechInfo.ulMaxKeySize)) {\n            WOLFSSL_MSG(\"PKCS#11: Key Length not supported\");\n            ret = NOT_COMPILED_IN;\n        }\n\n        /* Create a private key object or find by id. */\n        if (ret == 0 && hmac->idLen == 0) {\n            ret = Pkcs11CreateSecretKey(&key, session, keyType,\n                                    (unsigned char*)hmac->keyRaw, hmac->keyLen,\n                                    NULL, 0);\n            if (ret == WC_HW_E) {\n                ret = Pkcs11CreateSecretKey(&key, session, CKK_GENERIC_SECRET,\n                                    (unsigned char*)hmac->keyRaw, hmac->keyLen,\n                                    NULL, 0);\n            }\n\n        }\n        else if (ret == 0) {\n            ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, keyType, session,\n                                                         hmac->id, hmac->idLen);\n            if (ret == WC_HW_E) {\n                ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY,\n                                          CKK_GENERIC_SECRET, session, hmac->id,\n                                          hmac->idLen);\n            }\n        }\n\n        /* Initialize HMAC operation */\n        if (ret == 0) {\n            mech.mechanism      = mechType;\n            mech.ulParameterLen = 0;\n            mech.pParameter     = NULL;\n\n            rv = session->func->C_SignInit(session->handle, &mech, key);\n            if (rv != CKR_OK)\n                ret = WC_HW_E;\n        }\n\n        /* Don't imitialize HMAC again if this succeeded */\n        if (ret == 0)\n            hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_DEV;\n    }\n    /* Update the HMAC if input data passed in. */\n    if (ret == 0 && info->hmac.inSz > 0) {\n        WOLFSSL_MSG(\"PKCS#11: HMAC Update\");\n\n        rv = session->func->C_SignUpdate(session->handle,\n                                         (CK_BYTE_PTR)info->hmac.in,\n                                         info->hmac.inSz);\n        /* Some algorithm implementations only support C_Sign. */\n        if (rv == CKR_MECHANISM_INVALID) {\n            WOLFSSL_MSG(\"PKCS#11: HMAC Update/Final not supported\");\n            ret = NOT_COMPILED_IN;\n            /* Allow software implementation to set key. */\n            hmac->innerHashKeyed = 0;\n        }\n        else if (rv != CKR_OK)\n            ret = WC_HW_E;\n    }\n    /* Calculate the HMAC result if output buffer specified. */\n    if (ret == 0 && info->hmac.digest != NULL) {\n        WOLFSSL_MSG(\"PKCS#11: HMAC Final\");\n\n        outLen = WC_MAX_DIGEST_SIZE;\n        rv = session->func->C_SignFinal(session->handle,\n                                        (CK_BYTE_PTR)info->hmac.digest,\n                                        &outLen);\n        /* Some algorithm implementations only support C_Sign. */\n        if (rv != CKR_OK)\n            ret = WC_HW_E;\n        else\n            hmac->innerHashKeyed = 0;\n    }\n\n    if (hmac->idLen == 0 && key != NULL_PTR)\n        session->func->C_DestroyObject(session->handle, key);\n\n    return ret;\n}\n#endif\n\n#ifndef WC_NO_RNG\n#ifndef HAVE_HASHDRBG\n/**\n * Performs random number generation.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11RandomBlock(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int                ret = 0;\n    CK_RV              rv;\n\n    rv = session->func->C_GenerateRandom(session->handle, info->rng.out,\n                                                                  info->rng.sz);\n    if (rv != CKR_OK)\n        ret = WC_HW_E;\n    return ret;\n}\n#endif\n\n/**\n * Generates entropy (seed) data.\n *\n * @param  session  [in]  Session object.\n * @param  info     [in]  Cryptographic operation data.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nstatic int Pkcs11RandomSeed(Pkcs11Session* session, wc_CryptoInfo* info)\n{\n    int                ret = 0;\n    CK_RV              rv;\n\n    rv = session->func->C_GenerateRandom(session->handle, info->seed.seed,\n                                                                 info->seed.sz);\n    if (rv != CKR_OK)\n        ret = WC_HW_E;\n    return ret;\n}\n#endif\n\n/**\n * Perform a cryptographic operation using PKCS#11 device.\n *\n * @param  devId  [in]  Device identifier.\n * @param  info   [in]  Cryptographic operation data.\n * @param  ctx    [in]  Context data for device - the token object.\n * @return  WC_HW_E when a PKCS#11 library call fails.\n *          0 on success.\n */\nint wc_Pkcs11_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)\n{\n    int ret = 0;\n    Pkcs11Token* token = (Pkcs11Token*)ctx;\n    Pkcs11Session session;\n    int readWrite = 0;\n\n    if (devId <= INVALID_DEVID || info == NULL || ctx == NULL)\n        ret = BAD_FUNC_ARG;\n\n    if (ret == 0) {\n        ret = Pkcs11OpenSession(token, &session, readWrite);\n        if (ret == 0) {\n            if (info->algo_type == WC_ALGO_TYPE_PK) {\n#if !defined(NO_RSA) || defined(HAVE_ECC)\n                switch (info->pk.type) {\n    #ifndef NO_RSA\n                    case WC_PK_TYPE_RSA:\n                        ret = Pkcs11Rsa(&session, info);\n                        break;\n        #ifdef WOLFSSL_KEY_GEN\n                    case WC_PK_TYPE_RSA_KEYGEN:\n                        ret = Pkcs11RsaKeyGen(&session, info);\n                        break;\n        #endif\n    #endif\n    #ifdef HAVE_ECC\n        #ifndef NO_PKCS11_EC_KEYGEN\n                    case WC_PK_TYPE_EC_KEYGEN:\n                        ret = Pkcs11EcKeyGen(&session, info);\n                        break;\n        #endif\n        #ifndef NO_PKCS11_ECDH\n                    case WC_PK_TYPE_ECDH:\n                        ret = Pkcs11ECDH(&session, info);\n                        break;\n        #endif\n                    case WC_PK_TYPE_ECDSA_SIGN:\n                        ret = Pkcs11ECDSA_Sign(&session, info);\n                        break;\n                    case WC_PK_TYPE_ECDSA_VERIFY:\n                        ret = Pkcs11ECDSA_Verify(&session, info);\n                        break;\n    #endif\n                    default:\n                        ret = NOT_COMPILED_IN;\n                        break;\n                }\n#else\n                ret = NOT_COMPILED_IN;\n#endif /* !NO_RSA || HAVE_ECC */\n            }\n            else if (info->algo_type == WC_ALGO_TYPE_CIPHER) {\n    #ifndef NO_AES\n                switch (info->cipher.type) {\n        #ifdef HAVE_AESGCM\n                    case WC_CIPHER_AES_GCM:\n                        if (info->cipher.enc)\n                            ret = Pkcs11AesGcmEncrypt(&session, info);\n                        else\n                            ret = Pkcs11AesGcmDecrypt(&session, info);\n                        break;\n        #endif\n        #ifdef HAVE_AES_CBC\n                    case WC_CIPHER_AES_CBC:\n                        if (info->cipher.enc)\n                            ret = Pkcs11AesCbcEncrypt(&session, info);\n                        else\n                            ret = Pkcs11AesCbcDecrypt(&session, info);\n                        break;\n        #endif\n                }\n    #else\n                ret = NOT_COMPILED_IN;\n    #endif\n            }\n            else if (info->algo_type == WC_ALGO_TYPE_HMAC) {\n    #ifndef NO_HMAC\n                ret = Pkcs11Hmac(&session, info);\n    #else\n                ret = NOT_COMPILED_IN;\n    #endif\n            }\n            else if (info->algo_type == WC_ALGO_TYPE_RNG) {\n    #if !defined(WC_NO_RNG) && !defined(HAVE_HASHDRBG)\n                ret = Pkcs11RandomBlock(&session, info);\n    #else\n                ret = NOT_COMPILED_IN;\n    #endif\n            }\n            else if (info->algo_type == WC_ALGO_TYPE_SEED) {\n    #ifndef WC_NO_RNG\n                ret = Pkcs11RandomSeed(&session, info);\n    #else\n                ret = NOT_COMPILED_IN;\n    #endif\n            }\n            else\n                ret = NOT_COMPILED_IN;\n\n            Pkcs11CloseSession(token, &session);\n        }\n    }\n\n    return ret;\n}\n\n#endif /* HAVE_PKCS11 */\n\n"
  },
  {
    "path": "src/wolfcrypt/src/wc_port.c",
    "content": "/* port.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/types.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n#include <wolfssl/wolfcrypt/wc_port.h>\n#ifdef HAVE_ECC\n    #include <wolfssl/wolfcrypt/ecc.h>\n#endif\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n\n/* IPP header files for library initialization */\n#ifdef HAVE_FAST_RSA\n    #include <ipp.h>\n    #include <ippcp.h>\n#endif\n\n#ifdef FREESCALE_LTC_TFM\n    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>\n#endif\n\n#if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A)\n    #include <wolfssl/wolfcrypt/port/atmel/atmel.h>\n#endif\n#if defined(WOLFSSL_RENESAS_TSIP)\n    #include <wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h>\n#endif\n#if defined(WOLFSSL_STSAFEA100)\n    #include <wolfssl/wolfcrypt/port/st/stsafe.h>\n#endif\n\n#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)\n    #include <wolfssl/openssl/evp.h>\n#endif\n\n#if defined(USE_WOLFSSL_MEMORY) && defined(WOLFSSL_TRACK_MEMORY)\n    #include <wolfssl/wolfcrypt/memory.h>\n    #include <wolfssl/wolfcrypt/mem_track.h>\n#endif\n\n#if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \\\n    defined(WOLFSSL_IMX6_CAAM_BLOB)\n    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>\n#endif\n\n#ifdef WOLF_CRYPTO_CB\n    #include <wolfssl/wolfcrypt/cryptocb.h>\n#endif\n\n#ifdef HAVE_INTEL_QA_SYNC\n    #include <wolfssl/wolfcrypt/port/intel/quickassist_sync.h>\n#endif\n\n#ifdef HAVE_CAVIUM_OCTEON_SYNC\n    #include <wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h>\n#endif\n\n#ifdef _MSC_VER\n    /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */\n    #pragma warning(disable: 4996)\n#endif\n\n/* prevent multiple mutex initializations */\nstatic volatile int initRefCount = 0;\n\n/* Used to initialize state for wolfcrypt\n   return 0 on success\n */\nint wolfCrypt_Init(void)\n{\n    int ret = 0;\n\n    if (initRefCount == 0) {\n        WOLFSSL_ENTER(\"wolfCrypt_Init\");\n\n    #ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST\n        {\n            word32 rngMallocFail;\n            time_t seed = time(NULL);\n            srand((word32)seed);\n            rngMallocFail = rand() % 2000; /* max 2000 */\n            printf(\"\\n--- RNG MALLOC FAIL AT %d---\\n\", rngMallocFail);\n            wolfSSL_SetMemFailCount(rngMallocFail);\n        }\n    #endif\n\n    #ifdef WOLF_CRYPTO_CB\n        wc_CryptoCb_Init();\n    #endif\n\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        ret = wolfAsync_HardwareStart();\n        if (ret != 0) {\n            WOLFSSL_MSG(\"Async hardware start failed\");\n            /* don't return failure, allow operation to continue */\n        }\n    #endif\n\n    #if defined(WOLFSSL_RENESAS_TSIP_CRYPT)\n        ret = tsip_Open( );\n        if( ret != TSIP_SUCCESS ) {\n            WOLFSSL_MSG(\"RENESAS TSIP Open failed\");\n            /* not return 1 since WOLFSSL_SUCCESS=1*/\n            ret = -1;/* FATAL ERROR */\n            return ret;\n        }\n    #endif\n\n    #if defined(WOLFSSL_TRACK_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)\n        ret = InitMemoryTracker();\n        if (ret != 0) {\n            WOLFSSL_MSG(\"InitMemoryTracker failed\");\n            return ret;\n        }\n    #endif\n\n    #if WOLFSSL_CRYPT_HW_MUTEX\n        /* If crypto hardware mutex protection is enabled, then initialize it */\n        ret = wolfSSL_CryptHwMutexInit();\n        if (ret != 0) {\n            WOLFSSL_MSG(\"Hw crypt mutex init failed\");\n            return ret;\n        }\n    #endif\n\n    /* if defined have fast RSA then initialize Intel IPP */\n    #ifdef HAVE_FAST_RSA\n        WOLFSSL_MSG(\"Attempting to use optimized IPP Library\");\n        if ((ret = ippInit()) != ippStsNoErr) {\n            /* possible to get a CPU feature support status on optimized IPP\n              library but still use default library and see competitive speeds */\n            WOLFSSL_MSG(\"Warning when trying to set up optimization\");\n            WOLFSSL_MSG(ippGetStatusString(ret));\n            WOLFSSL_MSG(\"Using default fast IPP library\");\n            ret = 0;\n            (void)ret; /* suppress not read warning */\n        }\n    #endif\n\n    #if defined(FREESCALE_LTC_TFM) || defined(FREESCALE_LTC_ECC)\n        ret = ksdk_port_init();\n        if (ret != 0) {\n            WOLFSSL_MSG(\"KSDK port init failed\");\n            return ret;\n        }\n    #endif\n\n    #if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A)\n        ret = atmel_init();\n        if (ret != 0) {\n            WOLFSSL_MSG(\"CryptoAuthLib init failed\");\n            return ret;\n        }\n    #endif\n    #if defined(WOLFSSL_CRYPTOCELL)\n        /* enable and initialize the ARM CryptoCell 3xx runtime library */\n        ret = cc310_Init();\n        if (ret != 0) {\n            WOLFSSL_MSG(\"CRYPTOCELL init failed\");\n            return ret;\n        }\n    #endif\n    #if defined(WOLFSSL_STSAFEA100)\n        stsafe_interface_init();\n    #endif\n\n    #ifdef WOLFSSL_ARMASM\n        WOLFSSL_MSG(\"Using ARM hardware acceleration\");\n    #endif\n\n    #ifdef WOLFSSL_AFALG\n\tWOLFSSL_MSG(\"Using AF_ALG for crypto acceleration\");\n    #endif\n\n    #if !defined(WOLFCRYPT_ONLY) && \\\n        ( defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) )\n        wolfSSL_EVP_init();\n    #endif\n\n    #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)\n        if ((ret = wc_LoggingInit()) != 0) {\n            WOLFSSL_MSG(\"Error creating logging mutex\");\n            return ret;\n        }\n    #endif\n\n#ifdef HAVE_ECC\n    #ifdef ECC_CACHE_CURVE\n        if ((ret = wc_ecc_curve_cache_init()) != 0) {\n            WOLFSSL_MSG(\"Error creating curve cache\");\n            return ret;\n        }\n    #endif\n#endif\n\n#if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \\\n    defined(WOLFSSL_IMX6_CAAM_BLOB)\n        if ((ret = wc_caamInit()) != 0) {\n            return ret;\n        }\n#endif\n    }\n    initRefCount++;\n\n    return ret;\n}\n\n\n/* return success value is the same as wolfCrypt_Init */\nint wolfCrypt_Cleanup(void)\n{\n    int ret = 0;\n\n    initRefCount--;\n    if (initRefCount < 0)\n        initRefCount = 0;\n\n    if (initRefCount == 0) {\n        WOLFSSL_ENTER(\"wolfCrypt_Cleanup\");\n\n#ifdef HAVE_ECC\n    #ifdef FP_ECC\n        wc_ecc_fp_free();\n    #endif\n    #ifdef ECC_CACHE_CURVE\n        wc_ecc_curve_cache_free();\n    #endif\n#endif /* HAVE_ECC */\n\n    #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)\n        ret = wc_LoggingCleanup();\n    #endif\n\n    #if defined(WOLFSSL_TRACK_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)\n        ShowMemoryTracker();\n    #endif\n\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        wolfAsync_HardwareStop();\n    #endif\n\n    #if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \\\n        defined(WOLFSSL_IMX6_CAAM_BLOB)\n        wc_caamFree();\n    #endif\n    #if defined(WOLFSSL_CRYPTOCELL)\n        cc310_Free();\n    #endif\n    #if defined(WOLFSSL_RENESAS_TSIP_CRYPT)\n        tsip_Close();\n    #endif\n    }\n\n    return ret;\n}\n\n#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) && \\\n\t!defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2)\n\n/* File Handling Helpers */\n/* returns 0 if file found, WC_READDIR_NOFILE if no files or negative error */\nint wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name)\n{\n    int ret = WC_READDIR_NOFILE; /* default to no files found */\n    int pathLen = 0;\n    int dnameLen = 0;\n\n    if (name)\n        *name = NULL;\n\n    if (ctx == NULL || path == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    XMEMSET(ctx->name, 0, MAX_FILENAME_SZ);\n    pathLen = (int)XSTRLEN(path);\n\n#ifdef USE_WINDOWS_API\n    if (pathLen > MAX_FILENAME_SZ - 3)\n        return BAD_PATH_ERROR;\n\n    XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ - 3);\n    XSTRNCPY(ctx->name + pathLen, \"\\\\*\", MAX_FILENAME_SZ - pathLen);\n\n    ctx->hFind = FindFirstFileA(ctx->name, &ctx->FindFileData);\n    if (ctx->hFind == INVALID_HANDLE_VALUE) {\n        WOLFSSL_MSG(\"FindFirstFile for path verify locations failed\");\n        return BAD_PATH_ERROR;\n    }\n\n    do {\n        if (!(ctx->FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {\n            dnameLen = (int)XSTRLEN(ctx->FindFileData.cFileName);\n\n            if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {\n                return BAD_PATH_ERROR;\n            }\n            XSTRNCPY(ctx->name, path, pathLen + 1);\n            ctx->name[pathLen] = '\\\\';\n            XSTRNCPY(ctx->name + pathLen + 1,\n                     ctx->FindFileData.cFileName,\n                     MAX_FILENAME_SZ - pathLen - 1);\n            if (name)\n                *name = ctx->name;\n            return 0;\n        }\n    } while (FindNextFileA(ctx->hFind, &ctx->FindFileData));\n#elif defined(WOLFSSL_ZEPHYR)\n    if (fs_opendir(&ctx->dir, path) != 0) {\n        WOLFSSL_MSG(\"opendir path verify locations failed\");\n        return BAD_PATH_ERROR;\n    }\n    ctx->dirp = &ctx->dir;\n\n    while ((fs_readdir(&ctx->dir, &ctx->entry)) != 0) {\n        dnameLen = (int)XSTRLEN(ctx->entry.name);\n\n        if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {\n            ret = BAD_PATH_ERROR;\n            break;\n        }\n        XSTRNCPY(ctx->name, path, pathLen + 1);\n        ctx->name[pathLen] = '/';\n\n        /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because\n         * of earlier check it is known that dnameLen is less than\n         * MAX_FILENAME_SZ - (pathLen + 2)  so dnameLen +1 will fit */\n        XSTRNCPY(ctx->name + pathLen + 1, ctx->entry.name, dnameLen + 1);\n        if (fs_stat(ctx->name, &ctx->s) != 0) {\n            WOLFSSL_MSG(\"stat on name failed\");\n            ret = BAD_PATH_ERROR;\n            break;\n        } else if (ctx->s.type == FS_DIR_ENTRY_FILE) {\n            if (name)\n                *name = ctx->name;\n            return 0;\n        }\n    }\n#elif defined(WOLFSSL_TELIT_M2MB)\n    ctx->dir = m2mb_fs_opendir((const CHAR*)path);\n    if (ctx->dir == NULL) {\n        WOLFSSL_MSG(\"opendir path verify locations failed\");\n        return BAD_PATH_ERROR;\n    }\n\n    while ((ctx->entry = m2mb_fs_readdir(ctx->dir)) != NULL) {\n        dnameLen = (int)XSTRLEN(ctx->entry->d_name);\n\n        if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {\n            ret = BAD_PATH_ERROR;\n            break;\n        }\n        XSTRNCPY(ctx->name, path, pathLen + 1);\n        ctx->name[pathLen] = '/';\n\n        /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because\n         * of earlier check it is known that dnameLen is less than\n         * MAX_FILENAME_SZ - (pathLen + 2)  so dnameLen +1 will fit */\n        XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1);\n\n        if (m2mb_fs_stat(ctx->name, &ctx->s) != 0) {\n            WOLFSSL_MSG(\"stat on name failed\");\n            ret = BAD_PATH_ERROR;\n            break;\n        }\n        else if (ctx->s.st_mode & M2MB_S_IFREG) {\n            if (name)\n                *name = ctx->name;\n            return 0;\n        }\n    }\n#else\n    ctx->dir = opendir(path);\n    if (ctx->dir == NULL) {\n        WOLFSSL_MSG(\"opendir path verify locations failed\");\n        return BAD_PATH_ERROR;\n    }\n\n    while ((ctx->entry = readdir(ctx->dir)) != NULL) {\n        dnameLen = (int)XSTRLEN(ctx->entry->d_name);\n\n        if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {\n            ret = BAD_PATH_ERROR;\n            break;\n        }\n        XSTRNCPY(ctx->name, path, pathLen + 1);\n        ctx->name[pathLen] = '/';\n\n        /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because\n         * of earlier check it is known that dnameLen is less than\n         * MAX_FILENAME_SZ - (pathLen + 2)  so dnameLen +1 will fit */\n        XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1);\n        if (stat(ctx->name, &ctx->s) != 0) {\n            WOLFSSL_MSG(\"stat on name failed\");\n            ret = BAD_PATH_ERROR;\n            break;\n        } else if (S_ISREG(ctx->s.st_mode)) {\n            if (name)\n                *name = ctx->name;\n            return 0;\n        }\n    }\n#endif\n    wc_ReadDirClose(ctx);\n\n    return ret;\n}\n\n/* returns 0 if file found, WC_READDIR_NOFILE if no more files */\nint wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name)\n{\n    int ret = WC_READDIR_NOFILE; /* default to no file found */\n    int pathLen = 0;\n    int dnameLen = 0;\n\n    if (name)\n        *name = NULL;\n\n    if (ctx == NULL || path == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    XMEMSET(ctx->name, 0, MAX_FILENAME_SZ);\n    pathLen = (int)XSTRLEN(path);\n\n#ifdef USE_WINDOWS_API\n    while (FindNextFileA(ctx->hFind, &ctx->FindFileData)) {\n        if (!(ctx->FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {\n            dnameLen = (int)XSTRLEN(ctx->FindFileData.cFileName);\n\n            if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) {\n                return BAD_PATH_ERROR;\n            }\n            XSTRNCPY(ctx->name, path, pathLen + 1);\n            ctx->name[pathLen] = '\\\\';\n            XSTRNCPY(ctx->name + pathLen + 1,\n                     ctx->FindFileData.cFileName,\n                     MAX_FILENAME_SZ - pathLen - 1);\n            if (name)\n                *name = ctx->name;\n            return 0;\n        }\n    }\n#elif defined(WOLFSSL_ZEPHYR)\n    while ((fs_readdir(&ctx->dir, &ctx->entry)) != 0) {\n        dnameLen = (int)XSTRLEN(ctx->entry.name);\n\n        if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {\n            ret = BAD_PATH_ERROR;\n            break;\n        }\n        XSTRNCPY(ctx->name, path, pathLen + 1);\n        ctx->name[pathLen] = '/';\n        /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because\n         * of earlier check it is known that dnameLen is less than\n         * MAX_FILENAME_SZ - (pathLen + 2) so that dnameLen +1 will fit */\n        XSTRNCPY(ctx->name + pathLen + 1, ctx->entry.name, dnameLen + 1);\n\n        if (fs_stat(ctx->name, &ctx->s) != 0) {\n            WOLFSSL_MSG(\"stat on name failed\");\n            ret = BAD_PATH_ERROR;\n            break;\n        } else if (ctx->s.type == FS_DIR_ENTRY_FILE) {\n            if (name)\n                *name = ctx->name;\n            return 0;\n        }\n    }\n#elif defined(WOLFSSL_TELIT_M2MB)\n    while ((ctx->entry = m2mb_fs_readdir(ctx->dir)) != NULL) {\n        dnameLen = (int)XSTRLEN(ctx->entry->d_name);\n\n        if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {\n            ret = BAD_PATH_ERROR;\n            break;\n        }\n        XSTRNCPY(ctx->name, path, pathLen + 1);\n        ctx->name[pathLen] = '/';\n\n        /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because\n         * of earlier check it is known that dnameLen is less than\n         * MAX_FILENAME_SZ - (pathLen + 2)  so dnameLen +1 will fit */\n        XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1);\n\n        if (m2mb_fs_stat(ctx->name, &ctx->s) != 0) {\n            WOLFSSL_MSG(\"stat on name failed\");\n            ret = BAD_PATH_ERROR;\n            break;\n        }\n        else if (ctx->s.st_mode & M2MB_S_IFREG) {\n            if (name)\n                *name = ctx->name;\n            return 0;\n        }\n    }\n#else\n    while ((ctx->entry = readdir(ctx->dir)) != NULL) {\n        dnameLen = (int)XSTRLEN(ctx->entry->d_name);\n\n        if (pathLen + dnameLen + 2 >= MAX_FILENAME_SZ) {\n            ret = BAD_PATH_ERROR;\n            break;\n        }\n        XSTRNCPY(ctx->name, path, pathLen + 1);\n        ctx->name[pathLen] = '/';\n        /* Use dnameLen + 1 for GCC 8 warnings of truncating d_name. Because\n         * of earlier check it is known that dnameLen is less than\n         * MAX_FILENAME_SZ - (pathLen + 2) so that dnameLen +1 will fit */\n        XSTRNCPY(ctx->name + pathLen + 1, ctx->entry->d_name, dnameLen + 1);\n\n        if (stat(ctx->name, &ctx->s) != 0) {\n            WOLFSSL_MSG(\"stat on name failed\");\n            ret = BAD_PATH_ERROR;\n            break;\n        } else if (S_ISREG(ctx->s.st_mode)) {\n            if (name)\n                *name = ctx->name;\n            return 0;\n        }\n    }\n#endif\n\n    wc_ReadDirClose(ctx);\n\n    return ret;\n}\n\nvoid wc_ReadDirClose(ReadDirCtx* ctx)\n{\n    if (ctx == NULL) {\n        return;\n    }\n\n#ifdef USE_WINDOWS_API\n    if (ctx->hFind != INVALID_HANDLE_VALUE) {\n        FindClose(ctx->hFind);\n        ctx->hFind = INVALID_HANDLE_VALUE;\n    }\n#elif defined(WOLFSSL_ZEPHYR)\n    if (ctx->dirp) {\n        fs_closedir(ctx->dirp);\n        ctx->dirp = NULL;\n    }\n#elif defined(WOLFSSL_TELIT_M2MB)\n    if (ctx->dir) {\n        m2mb_fs_closedir(ctx->dir);\n        ctx->dir = NULL;\n    }\n#else\n    if (ctx->dir) {\n        closedir(ctx->dir);\n        ctx->dir = NULL;\n    }\n#endif\n}\n\n#endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */\n\n#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_ZEPHYR)\nXFILE z_fs_open(const char* filename, const char* perm)\n{\n    XFILE file;\n\n    file = XMALLOC(sizeof(*file), NULL, DYNAMIC_TYPE_FILE);\n    if (file != NULL) {\n        if (fs_open(file, filename) != 0) {\n            XFREE(file, NULL, DYNAMIC_TYPE_FILE);\n            file = NULL;\n        }\n    }\n\n    return file;\n}\n\nint z_fs_close(XFILE file)\n{\n    int ret;\n\n    if (file == NULL)\n        return -1;\n    ret = (fs_close(file) == 0) ? 0 : -1;\n\n    XFREE(file, NULL, DYNAMIC_TYPE_FILE);\n\n    return ret;\n}\n\n#endif /* !NO_FILESYSTEM && !WOLFSSL_ZEPHYR */\n\n\nwolfSSL_Mutex* wc_InitAndAllocMutex(void)\n{\n    wolfSSL_Mutex* m = (wolfSSL_Mutex*) XMALLOC(sizeof(wolfSSL_Mutex), NULL,\n            DYNAMIC_TYPE_MUTEX);\n    if (m != NULL) {\n        if (wc_InitMutex(m) != 0) {\n            WOLFSSL_MSG(\"Init Mutex failed\");\n            XFREE(m, NULL, DYNAMIC_TYPE_MUTEX);\n            m = NULL;\n        }\n    }\n    else {\n        WOLFSSL_MSG(\"Memory error with Mutex allocation\");\n    }\n\n    return m;\n}\n\n#ifdef USE_WOLF_STRTOK\n/* String token (delim) search. If str is null use nextp. */\nchar* wc_strtok(char *str, const char *delim, char **nextp)\n{\n    char* ret;\n    int i, j;\n\n    /* Use next if str is NULL */\n    if (str == NULL && nextp)\n        str = *nextp;\n\n    /* verify str input */\n    if (str == NULL || *str == '\\0')\n        return NULL;\n\n    /* match on entire delim */\n    for (i = 0; str[i]; i++) {\n        for (j = 0; delim[j]; j++) {\n            if (delim[j] == str[i])\n                break;\n        }\n        if (!delim[j])\n            break;\n    }\n    str += i;\n    /* if end of string, not found so return NULL */\n    if (*str == '\\0')\n        return NULL;\n\n    ret = str;\n\n    /* match on first delim */\n    for (i = 0; str[i]; i++) {\n        for (j = 0; delim[j]; j++) {\n            if (delim[j] == str[i])\n                break;\n        }\n        if (delim[j] == str[i])\n            break;\n    }\n    str += i;\n\n    /* null terminate found string */\n    if (*str)\n        *str++ = '\\0';\n\n    /* return pointer to next */\n    if (nextp)\n        *nextp = str;\n\n    return ret;\n}\n#endif /* USE_WOLF_STRTOK */\n\n#ifdef USE_WOLF_STRSEP\nchar* wc_strsep(char **stringp, const char *delim)\n{\n    char *s, *tok;\n    const char *spanp;\n\n    /* null check */\n    if (stringp == NULL || *stringp == NULL)\n        return NULL;\n\n    s = *stringp;\n    for (tok = s; *tok; ++tok) {\n        for (spanp = delim; *spanp; ++spanp) {\n            /* found delimiter */\n            if (*tok == *spanp) {\n                *tok = '\\0'; /* replace delim with null term */\n                *stringp = tok + 1; /* return past delim */\n                return s;\n            }\n        }\n    }\n\n    *stringp = NULL;\n    return s;\n}\n#endif /* USE_WOLF_STRSEP */\n\n#if WOLFSSL_CRYPT_HW_MUTEX\n/* Mutex for protection of cryptography hardware */\nstatic wolfSSL_Mutex wcCryptHwMutex;\nstatic int wcCryptHwMutexInit = 0;\n\nint wolfSSL_CryptHwMutexInit(void) {\n    int ret = 0;\n    if(wcCryptHwMutexInit == 0) {\n        ret = wc_InitMutex(&wcCryptHwMutex);\n        if(ret == 0) {\n            wcCryptHwMutexInit = 1;\n        }\n    }\n    return ret;\n}\n\nint wolfSSL_CryptHwMutexLock(void) {\n    int ret = BAD_MUTEX_E;\n\n    /* Make sure HW Mutex has been initialized */\n    wolfSSL_CryptHwMutexInit();\n\n    if(wcCryptHwMutexInit) {\n        ret = wc_LockMutex(&wcCryptHwMutex);\n    }\n    return ret;\n}\n\nint wolfSSL_CryptHwMutexUnLock(void) {\n    int ret = BAD_MUTEX_E;\n\n    if(wcCryptHwMutexInit) {\n        ret = wc_UnLockMutex(&wcCryptHwMutex);\n    }\n    return ret;\n}\n#endif /* WOLFSSL_CRYPT_HW_MUTEX */\n\n\n/* ---------------------------------------------------------------------------*/\n/* Mutex Ports */\n/* ---------------------------------------------------------------------------*/\n#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)\n    static mutex_cb*     compat_mutex_cb = NULL;\n\n    /* Function that locks or unlocks a mutex based on the flag passed in.\n     *\n     * flag lock or unlock i.e. CRYPTO_LOCK\n     * type the type of lock to unlock or lock\n     * file name of the file calling\n     * line the line number from file calling\n     */\n    int wc_LockMutex_ex(int flag, int type, const char* file, int line)\n    {\n        if (compat_mutex_cb != NULL) {\n            compat_mutex_cb(flag, type, file, line);\n            return 0;\n        }\n        else {\n            WOLFSSL_MSG(\"Mutex call back function not set. Call wc_SetMutexCb\");\n            return BAD_STATE_E;\n        }\n    }\n\n\n    /* Set the callback function to use for locking/unlocking mutex\n     *\n     * cb callback function to use\n     */\n    int wc_SetMutexCb(mutex_cb* cb)\n    {\n        compat_mutex_cb = cb;\n        return 0;\n    }\n#endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) */\n#ifdef SINGLE_THREADED\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        (void)m;\n        return 0;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex *m)\n    {\n        (void)m;\n        return 0;\n    }\n\n\n    int wc_LockMutex(wolfSSL_Mutex *m)\n    {\n        (void)m;\n        return 0;\n    }\n\n\n    int wc_UnLockMutex(wolfSSL_Mutex *m)\n    {\n        (void)m;\n        return 0;\n    }\n\n#elif defined(FREERTOS) || defined(FREERTOS_TCP) || \\\n  defined(FREESCALE_FREE_RTOS)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        int iReturn;\n\n        *m = ( wolfSSL_Mutex ) xSemaphoreCreateMutex();\n        if( *m != NULL )\n            iReturn = 0;\n        else\n            iReturn = BAD_MUTEX_E;\n\n        return iReturn;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        vSemaphoreDelete( *m );\n        return 0;\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        /* Assume an infinite block, or should there be zero block? */\n        xSemaphoreTake( *m, portMAX_DELAY );\n        return 0;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        xSemaphoreGive( *m );\n        return 0;\n    }\n\n#elif defined(WOLFSSL_SAFERTOS)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        vSemaphoreCreateBinary(m->mutexBuffer, m->mutex);\n        if (m->mutex == NULL)\n            return BAD_MUTEX_E;\n\n        return 0;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        (void)m;\n        return 0;\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        /* Assume an infinite block */\n        xSemaphoreTake(m->mutex, portMAX_DELAY);\n        return 0;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        xSemaphoreGive(m->mutex);\n        return 0;\n    }\n\n#elif defined(USE_WINDOWS_API)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        InitializeCriticalSection(m);\n        return 0;\n    }\n\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        DeleteCriticalSection(m);\n        return 0;\n    }\n\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        EnterCriticalSection(m);\n        return 0;\n    }\n\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        LeaveCriticalSection(m);\n        return 0;\n    }\n\n#elif defined(WOLFSSL_PTHREADS)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        if (pthread_mutex_init(m, 0) == 0)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        if (pthread_mutex_destroy(m) == 0)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        if (pthread_mutex_lock(m) == 0)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        if (pthread_mutex_unlock(m) == 0)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n#elif defined(WOLFSSL_VXWORKS)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        if (m) {\n            if ((*m = semMCreate(0)) != SEM_ID_NULL)\n                return 0;\n        }\n        return BAD_MUTEX_E;\n    }\n\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        if (m) {\n            if (semDelete(*m) == OK)\n                return 0;\n        }\n        return BAD_MUTEX_E;\n    }\n\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        if (m) {\n            if (semTake(*m, WAIT_FOREVER) == OK)\n                return 0;\n        }\n        return BAD_MUTEX_E;\n    }\n\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        if (m) {\n            if (semGive(*m) == OK)\n                return 0;\n        }\n        return BAD_MUTEX_E;\n    }\n\n#elif defined(THREADX)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        if (tx_mutex_create(m, \"wolfSSL Mutex\", TX_NO_INHERIT) == 0)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        if (tx_mutex_delete(m) == 0)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        if (tx_mutex_get(m, TX_WAIT_FOREVER) == 0)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        if (tx_mutex_put(m) == 0)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n#elif defined(WOLFSSL_DEOS)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        mutexStatus mutStat;\n        /*\n        The empty string \"\" denotes an anonymous mutex, so objects do not cause name collisions.\n        `protectWolfSSLTemp` in an XML configuration element template describing a mutex.\n        */\n        if (m) {\n            mutStat = createMutex(\"\", \"protectWolfSSLTemp\", m);\n            if (mutStat == mutexSuccess)\n                return 0;\n            else{\n                WOLFSSL_MSG(\"wc_InitMutex failed\");\n                return mutStat;\n            }\n        }\n        return BAD_MUTEX_E;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        mutexStatus mutStat;\n        if (m) {\n            mutStat = deleteMutex(*m);\n            if (mutStat == mutexSuccess)\n                return 0;\n            else{\n                WOLFSSL_MSG(\"wc_FreeMutex failed\");\n                return mutStat;\n            }\n        }\n        return BAD_MUTEX_E;\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        mutexStatus mutStat;\n        if (m) {\n            mutStat = lockMutex(*m);\n            if (mutStat == mutexSuccess)\n                return 0;\n            else{\n                WOLFSSL_MSG(\"wc_LockMutex failed\");\n                return mutStat;\n            }\n        }\n        return BAD_MUTEX_E;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        mutexStatus mutStat;\n        if (m) {\n            mutStat = unlockMutex(*m);\n            if (mutStat== mutexSuccess)\n                return 0;\n            else{\n                WOLFSSL_MSG(\"wc_UnLockMutex failed\");\n                return mutStat;\n            }\n        }\n        return BAD_MUTEX_E;\n    }\n\n#elif defined(MICRIUM)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        OS_ERR err;\n\n        OSMutexCreate(m, \"wolfSSL Mutex\", &err);\n\n        if (err == OS_ERR_NONE)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        #if (OS_CFG_MUTEX_DEL_EN == DEF_ENABLED)\n            OS_ERR err;\n\n            OSMutexDel(m, OS_OPT_DEL_ALWAYS, &err);\n\n            if (err == OS_ERR_NONE)\n                return 0;\n            else\n                return BAD_MUTEX_E;\n        #else\n            return 0;\n        #endif\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        OS_ERR err;\n\n        OSMutexPend(m, 0, OS_OPT_PEND_BLOCKING, NULL, &err);\n\n        if (err == OS_ERR_NONE)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        OS_ERR err;\n\n        OSMutexPost(m, OS_OPT_POST_NONE, &err);\n\n        if (err == OS_ERR_NONE)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n#elif defined(EBSNET)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        if (rtp_sig_mutex_alloc(m, \"wolfSSL Mutex\") == -1)\n            return BAD_MUTEX_E;\n        else\n            return 0;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        rtp_sig_mutex_free(*m);\n        return 0;\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        if (rtp_sig_mutex_claim_timed(*m, RTIP_INF) == 0)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        rtp_sig_mutex_release(*m);\n        return 0;\n    }\n\n    int ebsnet_fseek(int a, long b, int c)\n    {\n        int retval;\n\n        retval = vf_lseek(a, b, c);\n        if (retval > 0)\n            retval = 0;\n        else\n            retval =  -1;\n\n        return(retval);\n    }\n\n#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        if (_mutex_init(m, NULL) == MQX_EOK)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        if (_mutex_destroy(m) == MQX_EOK)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        if (_mutex_lock(m) == MQX_EOK)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        if (_mutex_unlock(m) == MQX_EOK)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n#elif defined(WOLFSSL_TIRTOS)\n    #include <xdc/runtime/Error.h>\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        Semaphore_Params params;\n        Error_Block eb;\n\n        Error_init(&eb);\n        Semaphore_Params_init(&params);\n        params.mode = Semaphore_Mode_BINARY;\n\n        *m = Semaphore_create(1, &params, &eb);\n        if (Error_check(&eb)) {\n            Error_raise(&eb, Error_E_generic, \"Failed to Create the semaphore.\",\n                NULL);\n            return BAD_MUTEX_E;\n        }\n        else\n            return 0;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        Semaphore_delete(m);\n\n        return 0;\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        Semaphore_pend(*m, BIOS_WAIT_FOREVER);\n\n        return 0;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        Semaphore_post(*m);\n\n        return 0;\n    }\n\n#elif defined(WOLFSSL_uITRON4)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        int iReturn;\n        m->sem.sematr  = TA_TFIFO;\n        m->sem.isemcnt = 1;\n        m->sem.maxsem  = 1;\n        m->sem.name    = NULL;\n\n        m->id = acre_sem(&m->sem);\n        if( m->id != E_OK )\n            iReturn = 0;\n        else\n            iReturn = BAD_MUTEX_E;\n\n        return iReturn;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        del_sem( m->id );\n        return 0;\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        wai_sem(m->id);\n        return 0;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        sig_sem(m->id);\n        return 0;\n    }\n\n    /****  uITRON malloc/free ***/\n    static ID ID_wolfssl_MPOOL = 0;\n    static T_CMPL wolfssl_MPOOL = {TA_TFIFO, 0, NULL, \"wolfSSL_MPOOL\"};\n\n    int uITRON4_minit(size_t poolsz) {\n        ER ercd;\n        wolfssl_MPOOL.mplsz = poolsz;\n        ercd = acre_mpl(&wolfssl_MPOOL);\n        if (ercd > 0) {\n            ID_wolfssl_MPOOL = ercd;\n            return 0;\n        } else {\n            return -1;\n        }\n    }\n\n    void *uITRON4_malloc(size_t sz) {\n        ER ercd;\n        void *p;\n        ercd = get_mpl(ID_wolfssl_MPOOL, sz, (VP)&p);\n        if (ercd == E_OK) {\n            return p;\n        } else {\n            return 0;\n        }\n    }\n\n    void *uITRON4_realloc(void *p, size_t sz) {\n      ER ercd;\n      void *newp;\n      if(p) {\n          ercd = get_mpl(ID_wolfssl_MPOOL, sz, (VP)&newp);\n          if (ercd == E_OK) {\n              XMEMCPY(newp, p, sz);\n              ercd = rel_mpl(ID_wolfssl_MPOOL, (VP)p);\n              if (ercd == E_OK) {\n                  return newp;\n              }\n          }\n      }\n      return 0;\n    }\n\n    void uITRON4_free(void *p) {\n        ER ercd;\n        ercd = rel_mpl(ID_wolfssl_MPOOL, (VP)p);\n        if (ercd == E_OK) {\n            return;\n        } else {\n            return;\n        }\n    }\n\n#elif defined(WOLFSSL_uTKERNEL2)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        int iReturn;\n        m->sem.sematr  = TA_TFIFO;\n        m->sem.isemcnt = 1;\n        m->sem.maxsem  = 1;\n\n        m->id = tk_cre_sem(&m->sem);\n        if( m->id != NULL )\n            iReturn = 0;\n        else\n            iReturn = BAD_MUTEX_E;\n\n        return iReturn;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        tk_del_sem(m->id);\n        return 0;\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        tk_wai_sem(m->id, 1, TMO_FEVR);\n        return 0;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        tk_sig_sem(m->id, 1);\n        return 0;\n    }\n\n    /****  uT-Kernel malloc/free ***/\n    static ID ID_wolfssl_MPOOL = 0;\n    static T_CMPL wolfssl_MPOOL = {\n        NULL,       /* Extended information */\n        TA_TFIFO,   /* Memory pool attribute */\n        0,          /* Size of whole memory pool (byte) */\n        \"wolfSSL\"   /* Object name (max 8-char) */\n    };\n\n    int uTKernel_init_mpool(unsigned int sz) {\n        ER ercd;\n        wolfssl_MPOOL.mplsz = sz;\n        ercd = tk_cre_mpl(&wolfssl_MPOOL);\n        if (ercd > 0) {\n            ID_wolfssl_MPOOL = ercd;\n            return 0;\n        } else {\n            return (int)ercd;\n        }\n    }\n\n    void *uTKernel_malloc(unsigned int sz) {\n        ER ercd;\n        void *p;\n        ercd = tk_get_mpl(ID_wolfssl_MPOOL, sz, (VP)&p, TMO_FEVR);\n        if (ercd == E_OK) {\n            return p;\n        } else {\n            return 0;\n        }\n    }\n\n    void *uTKernel_realloc(void *p, unsigned int sz) {\n      ER ercd;\n      void *newp;\n      if (p) {\n          ercd = tk_get_mpl(ID_wolfssl_MPOOL, sz, (VP)&newp, TMO_FEVR);\n          if (ercd == E_OK) {\n              XMEMCPY(newp, p, sz);\n              ercd = tk_rel_mpl(ID_wolfssl_MPOOL, (VP)p);\n              if (ercd == E_OK) {\n                  return newp;\n              }\n          }\n      }\n      return 0;\n    }\n\n    void uTKernel_free(void *p) {\n        ER ercd;\n        ercd = tk_rel_mpl(ID_wolfssl_MPOOL, (VP)p);\n        if (ercd == E_OK) {\n            return;\n        } else {\n            return;\n        }\n    }\n\n#elif defined (WOLFSSL_FROSTED)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        *m = mutex_init();\n        if (*m)\n            return 0;\n        else\n            return -1;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        mutex_destroy(*m);\n        return(0);\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        mutex_lock(*m);\n        return 0;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        mutex_unlock(*m);\n        return 0;\n    }\n\n#elif defined(WOLFSSL_CMSIS_RTOS)\n\n    #define CMSIS_NMUTEX 10\n    osMutexDef(wolfSSL_mt0);  osMutexDef(wolfSSL_mt1);  osMutexDef(wolfSSL_mt2);\n    osMutexDef(wolfSSL_mt3);  osMutexDef(wolfSSL_mt4);  osMutexDef(wolfSSL_mt5);\n    osMutexDef(wolfSSL_mt6);  osMutexDef(wolfSSL_mt7);  osMutexDef(wolfSSL_mt8);\n    osMutexDef(wolfSSL_mt9);\n\n    static const osMutexDef_t *CMSIS_mutex[] = { osMutex(wolfSSL_mt0),\n        osMutex(wolfSSL_mt1),    osMutex(wolfSSL_mt2),   osMutex(wolfSSL_mt3),\n        osMutex(wolfSSL_mt4),    osMutex(wolfSSL_mt5),   osMutex(wolfSSL_mt6),\n        osMutex(wolfSSL_mt7),    osMutex(wolfSSL_mt8),   osMutex(wolfSSL_mt9) };\n\n    static osMutexId CMSIS_mutexID[CMSIS_NMUTEX] = {0};\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        int i;\n        for (i=0; i<CMSIS_NMUTEX; i++) {\n            if(CMSIS_mutexID[i] == 0) {\n                CMSIS_mutexID[i] = osMutexCreate(CMSIS_mutex[i]);\n                (*m) = CMSIS_mutexID[i];\n            return 0;\n            }\n        }\n        return -1;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        int i;\n        osMutexDelete   (*m);\n        for (i=0; i<CMSIS_NMUTEX; i++) {\n            if(CMSIS_mutexID[i] == (*m)) {\n                CMSIS_mutexID[i] = 0;\n                return(0);\n            }\n        }\n        return(-1);\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        osMutexWait(*m, osWaitForever);\n        return(0);\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        osMutexRelease (*m);\n        return 0;\n    }\n\n#elif defined(WOLFSSL_CMSIS_RTOSv2)\n    int wc_InitMutex(wolfSSL_Mutex *m)\n    {\n        static const osMutexAttr_t attr = {\n            \"wolfSSL_mutex\", osMutexRecursive, NULL, 0};\n\n        if ((*m = osMutexNew(&attr)) != NULL)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex *m)\n    {\n        if (osMutexDelete(*m) == osOK)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n\n    int wc_LockMutex(wolfSSL_Mutex *m)\n    {\n        if (osMutexAcquire(*m, osWaitForever) == osOK)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex *m)\n    {\n        if (osMutexRelease(*m) == osOK)\n            return 0;\n        else\n            return BAD_MUTEX_E;\n    }\n\n#elif defined(WOLFSSL_MDK_ARM)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        os_mut_init (m);\n        return 0;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        return(0);\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        os_mut_wait (m, 0xffff);\n        return(0);\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        os_mut_release (m);\n        return 0;\n    }\n\n#elif defined(INTIME_RTOS)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        int ret = 0;\n\n        if (m == NULL)\n            return BAD_FUNC_ARG;\n\n        *m = CreateRtSemaphore(\n            1,                      /* initial unit count */\n            1,                      /* maximum unit count */\n            PRIORITY_QUEUING        /* creation flags: FIFO_QUEUING or PRIORITY_QUEUING */\n        );\n        if (*m == BAD_RTHANDLE) {\n            ret = GetLastRtError();\n            if (ret != E_OK)\n                ret = BAD_MUTEX_E;\n        }\n        return ret;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        int ret = 0;\n        BOOLEAN del;\n\n        if (m == NULL)\n            return BAD_FUNC_ARG;\n\n        del = DeleteRtSemaphore(\n            *m                      /* handle for RT semaphore */\n        );\n    \tif (del != TRUE)\n    \t\tret = BAD_MUTEX_E;\n\n        return ret;\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        int ret = 0;\n        DWORD lck;\n\n        if (m == NULL)\n            return BAD_FUNC_ARG;\n\n        lck = WaitForRtSemaphore(\n            *m,                     /* handle for RT semaphore */\n            1,                      /* number of units to wait for */\n            WAIT_FOREVER            /* number of milliseconds to wait for units */\n        );\n        if (lck == WAIT_FAILED) {\n            ret = GetLastRtError();\n            if (ret != E_OK)\n                ret = BAD_MUTEX_E;\n        }\n        return ret;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        int ret = 0;\n        BOOLEAN rel;\n\n        if (m == NULL)\n            return BAD_FUNC_ARG;\n\n        rel = ReleaseRtSemaphore(\n            *m,                     /* handle for RT semaphore */\n            1                       /* number of units to release to semaphore */\n        );\n    \tif (rel != TRUE)\n    \t\tret = BAD_MUTEX_E;\n\n        return ret;\n    }\n\n#elif defined(WOLFSSL_NUCLEUS_1_2)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        /* Call the Nucleus function to create the semaphore */\n        if (NU_Create_Semaphore(m, \"WOLFSSL_MTX\", 1,\n                                NU_PRIORITY) == NU_SUCCESS) {\n            return 0;\n        }\n\n        return BAD_MUTEX_E;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        if (NU_Delete_Semaphore(m) == NU_SUCCESS)\n            return 0;\n\n        return BAD_MUTEX_E;\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        /* passing suspend task option */\n        if (NU_Obtain_Semaphore(m, NU_SUSPEND) == NU_SUCCESS)\n            return 0;\n\n        return BAD_MUTEX_E;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        if (NU_Release_Semaphore(m) == NU_SUCCESS)\n            return 0;\n\n        return BAD_MUTEX_E;\n    }\n\n#elif defined(WOLFSSL_ZEPHYR)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        k_mutex_init(m);\n\n        return 0;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        return 0;\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        int ret = 0;\n\n        if (k_mutex_lock(m, K_FOREVER) != 0)\n            ret = BAD_MUTEX_E;\n\n        return ret;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        k_mutex_unlock(m);\n\n        return 0;\n    }\n\n#elif defined(WOLFSSL_TELIT_M2MB)\n\n    int wc_InitMutex(wolfSSL_Mutex* m)\n    {\n        M2MB_OS_RESULT_E        osRes;\n        M2MB_OS_MTX_ATTR_HANDLE mtxAttrHandle;\n        UINT32                  inheritVal = 1;\n\n        osRes = m2mb_os_mtx_setAttrItem(&mtxAttrHandle,\n                                    CMDS_ARGS(\n                                      M2MB_OS_MTX_SEL_CMD_CREATE_ATTR, NULL,\n                                      M2MB_OS_MTX_SEL_CMD_NAME, \"wolfMtx\",\n                                      M2MB_OS_MTX_SEL_CMD_INHERIT, inheritVal\n                                    )\n                                );\n        if (osRes != M2MB_OS_SUCCESS) {\n            return BAD_MUTEX_E;\n        }\n\n        osRes = m2mb_os_mtx_init(m, &mtxAttrHandle);\n        if (osRes != M2MB_OS_SUCCESS) {\n            return BAD_MUTEX_E;\n        }\n\n        return 0;\n    }\n\n    int wc_FreeMutex(wolfSSL_Mutex* m)\n    {\n        M2MB_OS_RESULT_E osRes;\n\n        if (m == NULL)\n            return BAD_MUTEX_E;\n\n        osRes = m2mb_os_mtx_deinit(*m);\n        if (osRes != M2MB_OS_SUCCESS) {\n            return BAD_MUTEX_E;\n        }\n\n        return 0;\n    }\n\n    int wc_LockMutex(wolfSSL_Mutex* m)\n    {\n        M2MB_OS_RESULT_E osRes;\n\n        if (m == NULL)\n            return BAD_MUTEX_E;\n\n        osRes = m2mb_os_mtx_get(*m, M2MB_OS_WAIT_FOREVER);\n        if (osRes != M2MB_OS_SUCCESS) {\n            return BAD_MUTEX_E;\n        }\n\n        return 0;\n    }\n\n    int wc_UnLockMutex(wolfSSL_Mutex* m)\n    {\n        M2MB_OS_RESULT_E osRes;\n\n        if (m == NULL)\n            return BAD_MUTEX_E;\n\n        osRes = m2mb_os_mtx_put(*m);\n        if (osRes != M2MB_OS_SUCCESS) {\n            return BAD_MUTEX_E;\n        }\n\n        return 0;\n    }\n\n#else\n    #warning No mutex handling defined\n\n#endif\n\n#ifndef NO_ASN_TIME\n#if defined(_WIN32_WCE)\ntime_t windows_time(time_t* timer)\n{\n    SYSTEMTIME     sysTime;\n    FILETIME       fTime;\n    ULARGE_INTEGER intTime;\n    time_t         localTime;\n\n    if (timer == NULL)\n        timer = &localTime;\n\n    GetSystemTime(&sysTime);\n    SystemTimeToFileTime(&sysTime, &fTime);\n\n    XMEMCPY(&intTime, &fTime, sizeof(FILETIME));\n    /* subtract EPOCH */\n    intTime.QuadPart -= 0x19db1ded53e8000;\n    /* to secs */\n    intTime.QuadPart /= 10000000;\n    *timer = (time_t)intTime.QuadPart;\n\n    return *timer;\n}\n#endif /*  _WIN32_WCE */\n\n#if defined(WOLFSSL_APACHE_MYNEWT)\n#include \"os/os_time.h\"\n\ntime_t mynewt_time(time_t* timer)\n{\n    time_t now;\n    struct os_timeval tv;\n    os_gettimeofday(&tv, NULL);\n    now = (time_t)tv.tv_sec;\n    if(timer != NULL) {\n        *timer = now;\n    }\n    return now;\n}\n#endif /* WOLFSSL_APACHE_MYNEWT */\n\n#if defined(WOLFSSL_GMTIME)\nstruct tm* gmtime(const time_t* timer)\n{\n    #define YEAR0          1900\n    #define EPOCH_YEAR     1970\n    #define SECS_DAY       (24L * 60L * 60L)\n    #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400)))\n    #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)\n\n    static const int _ytab[2][12] =\n    {\n        {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},\n        {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}\n    };\n\n    static struct tm st_time;\n    struct tm* ret = &st_time;\n    time_t secs = *timer;\n    unsigned long dayclock, dayno;\n    int year = EPOCH_YEAR;\n\n    dayclock = (unsigned long)secs % SECS_DAY;\n    dayno    = (unsigned long)secs / SECS_DAY;\n\n    ret->tm_sec  = (int) dayclock % 60;\n    ret->tm_min  = (int)(dayclock % 3600) / 60;\n    ret->tm_hour = (int) dayclock / 3600;\n    ret->tm_wday = (int) (dayno + 4) % 7;        /* day 0 a Thursday */\n\n    while(dayno >= (unsigned long)YEARSIZE(year)) {\n        dayno -= YEARSIZE(year);\n        year++;\n    }\n\n    ret->tm_year = year - YEAR0;\n    ret->tm_yday = (int)dayno;\n    ret->tm_mon  = 0;\n\n    while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) {\n        dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon];\n        ret->tm_mon++;\n    }\n\n    ret->tm_mday  = (int)++dayno;\n    ret->tm_isdst = 0;\n\n    return ret;\n}\n#endif /* WOLFSSL_GMTIME */\n\n\n#if defined(HAVE_RTP_SYS)\n#define YEAR0          1900\n\nstruct tm* rtpsys_gmtime(const time_t* timer)       /* has a gmtime() but hangs */\n{\n    static struct tm st_time;\n    struct tm* ret = &st_time;\n\n    DC_RTC_CALENDAR cal;\n    dc_rtc_time_get(&cal, TRUE);\n\n    ret->tm_year  = cal.year - YEAR0;       /* gm starts at 1900 */\n    ret->tm_mon   = cal.month - 1;          /* gm starts at 0 */\n    ret->tm_mday  = cal.day;\n    ret->tm_hour  = cal.hour;\n    ret->tm_min   = cal.minute;\n    ret->tm_sec   = cal.second;\n\n    return ret;\n}\n\n#endif /* HAVE_RTP_SYS */\n\n\n#if defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)\n\n/*\n * time() is just a stub in Microchip libraries. We need our own\n * implementation. Use SNTP client to get seconds since epoch.\n */\ntime_t pic32_time(time_t* timer)\n{\n#ifdef MICROCHIP_TCPIP_V5\n    DWORD sec = 0;\n#else\n    uint32_t sec = 0;\n#endif\n    time_t localTime;\n\n    if (timer == NULL)\n        timer = &localTime;\n\n#ifdef MICROCHIP_MPLAB_HARMONY\n    sec = TCPIP_SNTP_UTCSecondsGet();\n#else\n    sec = SNTPGetUTCSeconds();\n#endif\n    *timer = (time_t) sec;\n\n    return *timer;\n}\n\n#endif /* MICROCHIP_TCPIP || MICROCHIP_TCPIP_V5 */\n\n#if defined(WOLFSSL_DEOS)\n\ntime_t deos_time(time_t* timer)\n{\n    const uint32_t systemTickTimeInHz = 1000000 / systemTickInMicroseconds();\n    uint32_t *systemTickPtr = systemTickPointer();\n\n    if (timer != NULL)\n        *timer = *systemTickPtr/systemTickTimeInHz;\n\n    #if defined(CURRENT_UNIX_TIMESTAMP)\n        /* CURRENT_UNIX_TIMESTAMP is seconds since Jan 01 1970. (UTC) */\n        return (time_t) *systemTickPtr/systemTickTimeInHz + CURRENT_UNIX_TIMESTAMP;\n    #else\n        return (time_t) *systemTickPtr/systemTickTimeInHz;\n    #endif\n}\n#endif /* WOLFSSL_DEOS */\n\n#if defined(MICRIUM)\n\ntime_t micrium_time(time_t* timer)\n{\n    CLK_TS_SEC sec;\n\n    Clk_GetTS_Unix(&sec);\n\n    if (timer != NULL)\n        *timer = sec;\n\n    return (time_t) sec;\n}\n\n#endif /* MICRIUM */\n\n#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)\n\ntime_t mqx_time(time_t* timer)\n{\n    time_t localTime;\n    TIME_STRUCT time_s;\n\n    if (timer == NULL)\n        timer = &localTime;\n\n    _time_get(&time_s);\n    *timer = (time_t) time_s.SECONDS;\n\n    return *timer;\n}\n\n#endif /* FREESCALE_MQX || FREESCALE_KSDK_MQX */\n\n\n#if defined(WOLFSSL_TIRTOS) && defined(USER_TIME)\n\ntime_t XTIME(time_t * timer)\n{\n    time_t sec = 0;\n\n    sec = (time_t) Seconds_get();\n\n    if (timer != NULL)\n        *timer = sec;\n\n    return sec;\n}\n\n#endif /* WOLFSSL_TIRTOS */\n\n#if defined(WOLFSSL_XILINX)\n#include \"xrtcpsu.h\"\n\ntime_t XTIME(time_t * timer)\n{\n    time_t sec = 0;\n    XRtcPsu_Config* con;\n    XRtcPsu         rtc;\n\n    con = XRtcPsu_LookupConfig(XPAR_XRTCPSU_0_DEVICE_ID);\n    if (con != NULL) {\n        if (XRtcPsu_CfgInitialize(&rtc, con, con->BaseAddr) == XST_SUCCESS) {\n            sec = (time_t)XRtcPsu_GetCurrentTime(&rtc);\n        }\n        else {\n            WOLFSSL_MSG(\"Unable to initialize RTC\");\n        }\n    }\n\n    if (timer != NULL)\n        *timer = sec;\n\n    return sec;\n}\n\n#endif /* WOLFSSL_XILINX */\n\n#if defined(WOLFSSL_ZEPHYR)\n\ntime_t z_time(time_t * timer)\n{\n    struct timespec ts;\n\n    if (clock_gettime(CLOCK_REALTIME, &ts) == 0)\n        if (timer != NULL)\n            *timer = ts.tv_sec;\n\n    return ts.tv_sec;\n}\n\n#endif /* WOLFSSL_ZEPHYR */\n\n\n#if defined(WOLFSSL_WICED)\n    #ifndef WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME\n        #error Please define WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME at build time.\n    #endif /* WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME */\n\ntime_t wiced_pseudo_unix_epoch_time(time_t * timer)\n{\n    time_t epoch_time;\n    /* The time() function return uptime on WICED platform. */\n    epoch_time = time(NULL) + WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME;\n\n    if (timer != NULL) {\n        *timer = epoch_time;\n    }\n    return epoch_time;\n}\n#endif /* WOLFSSL_WICED */\n\n#ifdef WOLFSSL_TELIT_M2MB\n    time_t m2mb_xtime(time_t * timer)\n    {\n        time_t myTime = 0;\n        INT32 fd = m2mb_rtc_open(\"/dev/rtc0\", 0);\n        if (fd >= 0) {\n            M2MB_RTC_TIMEVAL_T timeval;\n\n            m2mb_rtc_ioctl(fd, M2MB_RTC_IOCTL_GET_TIMEVAL, &timeval);\n\n            myTime = timeval.sec;\n\n            m2mb_rtc_close(fd);\n        }\n        return myTime;\n    }\n    #ifdef WOLFSSL_TLS13\n    time_t m2mb_xtime_ms(time_t * timer)\n    {\n        time_t myTime = 0;\n        INT32 fd = m2mb_rtc_open(\"/dev/rtc0\", 0);\n        if (fd >= 0) {\n            M2MB_RTC_TIMEVAL_T timeval;\n\n            m2mb_rtc_ioctl(fd, M2MB_RTC_IOCTL_GET_TIMEVAL, &timeval);\n\n            myTime = timeval.sec + timeval.msec;\n\n            m2mb_rtc_close(fd);\n        }\n        return myTime;\n    }\n    #endif /* WOLFSSL_TLS13 */\n    #ifndef NO_CRYPT_BENCHMARK\n    double m2mb_xtime_bench(int reset)\n    {\n        double myTime = 0;\n        INT32 fd = m2mb_rtc_open(\"/dev/rtc0\", 0);\n        if (fd >= 0) {\n            M2MB_RTC_TIMEVAL_T timeval;\n\n            m2mb_rtc_ioctl(fd, M2MB_RTC_IOCTL_GET_TIMEVAL, &timeval);\n\n            myTime = (double)timeval.sec + ((double)timeval.msec / 1000);\n\n            m2mb_rtc_close(fd);\n        }\n        return myTime;\n    }\n    #endif /* !NO_CRYPT_BENCHMARK */\n#endif /* WOLFSSL_TELIT_M2MB */\n\n#endif /* !NO_ASN_TIME */\n\n#ifndef WOLFSSL_LEANPSK\nchar* mystrnstr(const char* s1, const char* s2, unsigned int n)\n{\n    unsigned int s2_len = (unsigned int)XSTRLEN(s2);\n\n    if (s2_len == 0)\n        return (char*)s1;\n\n    while (n >= s2_len && s1[0]) {\n        if (s1[0] == s2[0])\n            if (XMEMCMP(s1, s2, s2_len) == 0)\n                return (char*)s1;\n        s1++;\n        n--;\n    }\n\n    return NULL;\n}\n#endif\n\n/* custom memory wrappers */\n#ifdef WOLFSSL_NUCLEUS_1_2\n\n    /* system memory pool */\n    extern NU_MEMORY_POOL System_Memory;\n\n    void* nucleus_malloc(unsigned long size, void* heap, int type)\n    {\n        STATUS status;\n        void*  stack_ptr;\n\n        status = NU_Allocate_Memory(&System_Memory, &stack_ptr, size,\n                                    NU_NO_SUSPEND);\n        if (status == NU_SUCCESS) {\n            return 0;\n        } else {\n            return stack_ptr;\n        }\n    }\n\n    void* nucleus_realloc(void* ptr, unsigned long size, void* heap, int type)\n    {\n        STATUS     status;\n        DM_HEADER* old_header;\n        word32     old_size, copy_size;\n        void*      new_mem;\n\n        /* if ptr is NULL, behave like malloc */\n        new_mem = nucleus_malloc(size, NULL, 0);\n        if (new_mem == 0 || ptr == 0) {\n            return new_mem;\n        }\n\n        /* calculate old memory block size */\n        /* mem pointers stored in block headers (ref dm_defs.h) */\n        old_header = (DM_HEADER*) ((byte*)ptr - DM_OVERHEAD);\n        old_size   = (byte*)old_header->dm_next_memory - (byte*)ptr;\n\n        /* copy old to new */\n        if (old_size < size) {\n            copy_size = old_size;\n        } else {\n            copy_size = size;\n        }\n        XMEMCPY(new_mem, ptr, copy_size);\n\n        /* free old */\n        nucleus_free(ptr, NULL, 0);\n\n        return new_mem;\n    }\n\n    void nucleus_free(void* ptr, void* heap, int type)\n    {\n        if (ptr != NULL)\n            NU_Deallocate_Memory(ptr);\n    }\n\n#endif /* WOLFSSL_NUCLEUS_1_2 */\n\n#if defined(WOLFSSL_TI_CRYPT) || defined(WOLFSSL_TI_HASH)\n    #include <wolfcrypt/src/port/ti/ti-ccm.c>  /* initialize and Mutex for TI Crypt Engine */\n    #include <wolfcrypt/src/port/ti/ti-hash.c> /* md5, sha1, sha224, sha256 */\n#endif\n\n#if defined(WOLFSSL_CRYPTOCELL)\n    #define WOLFSSL_CRYPTOCELL_C\n    #include <wolfcrypt/src/port/arm/cryptoCell.c> /* CC310, RTC and RNG */\n    #if !defined(NO_SHA256)\n        #define WOLFSSL_CRYPTOCELL_HASH_C\n        #include <wolfcrypt/src/port/arm/cryptoCellHash.c> /* sha256 */\n    #endif\n#endif\n"
  },
  {
    "path": "src/wolfcrypt/src/wolfevent.c",
    "content": "/* wolfevent.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n\n#ifdef HAVE_WOLF_EVENT\n\n#include <wolfssl/internal.h>\n#include <wolfssl/error-ssl.h>\n#include <wolfssl/wolfcrypt/error-crypt.h>\n\n#include <wolfssl/wolfcrypt/wolfevent.h>\n\n\nint wolfEvent_Init(WOLF_EVENT* event, WOLF_EVENT_TYPE type, void* context)\n{\n    if (event == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (event->state == WOLF_EVENT_STATE_PENDING) {\n        WOLFSSL_MSG(\"Event already pending!\");\n        return BAD_COND_E;\n    }\n\n    XMEMSET(event, 0, sizeof(WOLF_EVENT));\n    event->type = type;\n    event->context = context;\n\n    return 0;\n}\n\nint wolfEvent_Poll(WOLF_EVENT* event, WOLF_EVENT_FLAG flags)\n{\n    int ret = BAD_COND_E;\n\n    /* Check hardware */\n#ifdef WOLFSSL_ASYNC_CRYPT\n    if (event->type >= WOLF_EVENT_TYPE_ASYNC_FIRST &&\n        event->type <= WOLF_EVENT_TYPE_ASYNC_LAST)\n    {\n        ret = wolfAsync_EventPoll(event, flags);\n    }\n#endif /* WOLFSSL_ASYNC_CRYPT */\n\n    return ret;\n}\n\nint wolfEventQueue_Init(WOLF_EVENT_QUEUE* queue)\n{\n    int ret = 0;\n\n    if (queue == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    XMEMSET(queue, 0, sizeof(WOLF_EVENT_QUEUE));\n#ifndef SINGLE_THREADED\n    ret = wc_InitMutex(&queue->lock);\n#endif\n    return ret;\n}\n\n\nint wolfEventQueue_Push(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event)\n{\n    int ret;\n\n    if (queue == NULL || event == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifndef SINGLE_THREADED\n    if ((ret = wc_LockMutex(&queue->lock)) != 0) {\n        return ret;\n    }\n#endif\n\n    ret = wolfEventQueue_Add(queue, event);\n\n#ifndef SINGLE_THREADED\n    wc_UnLockMutex(&queue->lock);\n#endif\n\n    return ret;\n}\n\nint wolfEventQueue_Pop(WOLF_EVENT_QUEUE* queue, WOLF_EVENT** event)\n{\n    int ret = 0;\n\n    if (queue == NULL || event == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifndef SINGLE_THREADED\n    /* In single threaded mode \"event_queue.lock\" doesn't exist */\n    if ((ret = wc_LockMutex(&queue->lock)) != 0) {\n        return ret;\n    }\n#endif\n\n    /* Pop first item off queue */\n    *event = queue->head;\n    ret = wolfEventQueue_Remove(queue, *event);\n\n#ifndef SINGLE_THREADED\n    wc_UnLockMutex(&queue->lock);\n#endif\n\n    return ret;\n}\n\n/* assumes queue is locked by caller */\nint wolfEventQueue_Add(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event)\n{\n    if (queue == NULL || event == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    event->next = NULL; /* added to end */\n    event->prev = NULL;\n    if (queue->tail == NULL)  {\n        queue->head = event;\n    }\n    else {\n        queue->tail->next = event;\n        event->prev = queue->tail;\n    }\n    queue->tail = event;      /* add to the end either way */\n    queue->count++;\n\n    return 0;\n}\n\n/* assumes queue is locked by caller */\nint wolfEventQueue_Remove(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event)\n{\n    int ret = 0;\n\n    if (queue == NULL || event == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n    if (event == queue->head && event == queue->tail) {\n        queue->head = NULL;\n        queue->tail = NULL;\n    }\n    else if (event == queue->head) {\n        queue->head = event->next;\n        queue->head->prev = NULL;\n    }\n    else if (event == queue->tail) {\n        queue->tail = event->prev;\n        queue->tail->next = NULL;\n    }\n    else {\n        WOLF_EVENT* next = event->next;\n        WOLF_EVENT* prev = event->prev;\n        next->prev = prev;\n        prev->next = next;\n    }\n    queue->count--;\n\n    return ret;\n}\n\nint wolfEventQueue_Poll(WOLF_EVENT_QUEUE* queue, void* context_filter,\n    WOLF_EVENT** events, int maxEvents, WOLF_EVENT_FLAG flags, int* eventCount)\n{\n    WOLF_EVENT* event;\n    int ret = 0, count = 0;\n\n    if (queue == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifndef SINGLE_THREADED\n    /* In single threaded mode \"event_queue.lock\" doesn't exist */\n    if ((ret = wc_LockMutex(&queue->lock)) != 0) {\n        return ret;\n    }\n#endif\n\n    /* itterate event queue */\n    for (event = queue->head; event != NULL; event = event->next)\n    {\n        /* optional filter based on context */\n        if (context_filter == NULL || event->context == context_filter) {\n\n            /* poll event */\n            ret = wolfEvent_Poll(event, flags);\n            if (ret < 0) break; /* exit for */\n\n            /* If event is done then process */\n            if (event->state == WOLF_EVENT_STATE_DONE) {\n                /* remove from queue */\n                ret = wolfEventQueue_Remove(queue, event);\n                if (ret < 0) break; /* exit for */\n\n                /* return pointer in 'events' arg */\n                if (events) {\n                    events[count] = event; /* return pointer */\n                }\n                count++;\n\n                /* check to make sure our event list isn't full */\n                if (events && count >= maxEvents) {\n                    break; /* exit for */\n                }\n            }\n        }\n    }\n\n#ifndef SINGLE_THREADED\n    wc_UnLockMutex(&queue->lock);\n#endif\n\n    /* return number of properly populated events */\n    if (eventCount) {\n        *eventCount = count;\n    }\n\n    return ret;\n}\n\nint wolfEventQueue_Count(WOLF_EVENT_QUEUE* queue)\n{\n    int ret;\n\n    if (queue == NULL) {\n        return BAD_FUNC_ARG;\n    }\n\n#ifndef SINGLE_THREADED\n    /* In single threaded mode \"event_queue.lock\" doesn't exist */\n    if ((ret = wc_LockMutex(&queue->lock)) != 0) {\n        return ret;\n    }\n#endif\n\n    ret = queue->count;\n\n#ifndef SINGLE_THREADED\n    wc_UnLockMutex(&queue->lock);\n#endif\n\n    return ret;\n}\n\nvoid wolfEventQueue_Free(WOLF_EVENT_QUEUE* queue)\n{\n    if (queue) {\n    #ifndef SINGLE_THREADED\n        wc_FreeMutex(&queue->lock);\n    #endif\n    }\n}\n\n#endif /* HAVE_WOLF_EVENT */\n"
  },
  {
    "path": "src/wolfcrypt/src/wolfmath.c",
    "content": "/* wolfmath.c\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n/* common functions for either math library */\n\n#ifdef HAVE_CONFIG_H\n    #include <config.h>\n#endif\n\n/* in case user set USE_FAST_MATH there */\n#include <wolfssl/wolfcrypt/settings.h>\n\n#include <wolfssl/wolfcrypt/integer.h>\n\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#include <wolfssl/wolfcrypt/logging.h>\n\n#if defined(USE_FAST_MATH) || !defined(NO_BIG_INT)\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n\n#ifdef NO_INLINE\n    #include <wolfssl/wolfcrypt/misc.h>\n#else\n    #define WOLFSSL_MISC_INCLUDED\n    #include <wolfcrypt/src/misc.c>\n#endif\n\n\n#if !defined(WC_NO_CACHE_RESISTANT) && \\\n    ((defined(HAVE_ECC) && defined(ECC_TIMING_RESISTANT)) || \\\n     (defined(USE_FAST_MATH) && defined(TFM_TIMING_RESISTANT)))\n\n    /* all off / all on pointer addresses for constant calculations */\n    /* ecc.c uses same table */\n    const wolfssl_word wc_off_on_addr[2] =\n    {\n    #if defined(WC_64BIT_CPU)\n        W64LIT(0x0000000000000000),\n        W64LIT(0xffffffffffffffff)\n    #elif defined(WC_16BIT_CPU)\n        0x0000U,\n        0xffffU\n    #else\n        /* 32 bit */\n        0x00000000U,\n        0xffffffffU\n    #endif\n    };\n#endif\n\n\n#if !defined(WOLFSSL_SP_MATH)\nint get_digit_count(mp_int* a)\n{\n    if (a == NULL)\n        return 0;\n\n    return a->used;\n}\n#endif\n\nmp_digit get_digit(mp_int* a, int n)\n{\n    if (a == NULL)\n        return 0;\n\n    return (n >= a->used || n < 0) ? 0 : a->dp[n];\n}\n\n#ifndef WC_NO_RNG\nint get_rand_digit(WC_RNG* rng, mp_digit* d)\n{\n    return wc_RNG_GenerateBlock(rng, (byte*)d, sizeof(mp_digit));\n}\n\n#ifdef WC_RSA_BLINDING\nint mp_rand(mp_int* a, int digits, WC_RNG* rng)\n{\n    int ret = 0;\n    mp_digit d;\n\n    if (rng == NULL) {\n        ret = MISSING_RNG_E; goto exit;\n    }\n\n    if (a == NULL) {\n        ret = BAD_FUNC_ARG; goto exit;\n    }\n\n    mp_zero(a);\n    if (digits <= 0) {\n        ret = MP_OKAY; goto exit;\n    }\n\n    /* first place a random non-zero digit */\n    do {\n        ret = get_rand_digit(rng, &d);\n        if (ret != 0) {\n            goto exit;\n        }\n    } while (d == 0);\n\n    if ((ret = mp_add_d(a, d, a)) != MP_OKAY) {\n        goto exit;\n    }\n\n    while (--digits > 0) {\n        if ((ret = mp_lshd(a, 1)) != MP_OKAY) {\n            goto exit;\n        }\n        if ((ret = get_rand_digit(rng, &d)) != 0) {\n            goto exit;\n        }\n        if ((ret = mp_add_d(a, d, a)) != MP_OKAY) {\n            goto exit;\n        }\n    }\n\nexit:\n    return ret;\n}\n#endif /* WC_RSA_BLINDING */\n#endif\n\n/* export an mp_int as unsigned char or hex string\n * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR\n * return MP_OKAY on success */\nint wc_export_int(mp_int* mp, byte* buf, word32* len, word32 keySz,\n    int encType)\n{\n    int err;\n\n    if (mp == NULL)\n        return BAD_FUNC_ARG;\n\n    /* check buffer size */\n    if (*len < keySz) {\n        *len = keySz;\n        return BUFFER_E;\n    }\n\n    *len = keySz;\n    XMEMSET(buf, 0, *len);\n\n    if (encType == WC_TYPE_HEX_STR) {\n    #ifdef WC_MP_TO_RADIX\n        err = mp_tohex(mp, (char*)buf);\n    #else\n        err = NOT_COMPILED_IN;\n    #endif\n    }\n    else {\n        err = mp_to_unsigned_bin(mp, buf + (keySz - mp_unsigned_bin_size(mp)));\n    }\n\n    return err;\n}\n\n\n#ifdef HAVE_WOLF_BIGINT\nvoid wc_bigint_init(WC_BIGINT* a)\n{\n    if (a != NULL) {\n        a->buf = NULL;\n        a->len = 0;\n        a->heap = NULL;\n    }\n}\n\nint wc_bigint_alloc(WC_BIGINT* a, word32 sz)\n{\n    int err = MP_OKAY;\n\n    if (a == NULL)\n        return BAD_FUNC_ARG;\n\n    if (sz > 0) {\n        if (a->buf && sz > a->len) {\n            wc_bigint_free(a);\n        }\n        if (a->buf == NULL) {\n            a->buf = (byte*)XMALLOC(sz, a->heap, DYNAMIC_TYPE_WOLF_BIGINT);\n        }\n        if (a->buf == NULL) {\n            err = MP_MEM;\n        }\n        else {\n            XMEMSET(a->buf, 0, sz);\n        }\n    }\n    a->len = sz;\n\n    return err;\n}\n\n/* assumes input is big endian format */\nint wc_bigint_from_unsigned_bin(WC_BIGINT* a, const byte* in, word32 inlen)\n{\n    int err;\n\n    if (a == NULL || in == NULL || inlen == 0)\n        return BAD_FUNC_ARG;\n\n    err = wc_bigint_alloc(a, inlen);\n    if (err == 0) {\n        XMEMCPY(a->buf, in, inlen);\n    }\n\n    return err;\n}\n\nint wc_bigint_to_unsigned_bin(WC_BIGINT* a, byte* out, word32* outlen)\n{\n    word32 sz;\n\n    if (a == NULL || out == NULL || outlen == NULL || *outlen == 0)\n        return BAD_FUNC_ARG;\n\n    /* trim to fit into output buffer */\n    sz = a->len;\n    if (a->len > *outlen) {\n        WOLFSSL_MSG(\"wc_bigint_export: Truncating output\");\n        sz = *outlen;\n    }\n\n    if (a->buf) {\n        XMEMCPY(out, a->buf, sz);\n    }\n\n    *outlen = sz;\n\n    return MP_OKAY;\n}\n\nvoid wc_bigint_zero(WC_BIGINT* a)\n{\n    if (a && a->buf) {\n        ForceZero(a->buf, a->len);\n    }\n}\n\nvoid wc_bigint_free(WC_BIGINT* a)\n{\n    if (a) {\n        if (a->buf) {\n          XFREE(a->buf, a->heap, DYNAMIC_TYPE_WOLF_BIGINT);\n        }\n        a->buf = NULL;\n        a->len = 0;\n    }\n}\n\n/* sz: make sure the buffer is at least that size and zero padded.\n *     A `sz == 0` will use the size of `src`.\n *     The calulcates sz is stored into dst->len in `wc_bigint_alloc`.\n */\nint wc_mp_to_bigint_sz(mp_int* src, WC_BIGINT* dst, word32 sz)\n{\n    int err;\n    word32 x, y;\n\n    if (src == NULL || dst == NULL)\n        return BAD_FUNC_ARG;\n\n    /* get size of source */\n    x = mp_unsigned_bin_size(src);\n    if (sz < x)\n        sz = x;\n\n    /* make sure destination is allocated and large enough */\n    err = wc_bigint_alloc(dst, sz);\n    if (err == MP_OKAY) {\n\n        /* leading zero pad */\n        y = sz - x;\n        XMEMSET(dst->buf, 0, y);\n\n        /* export src as unsigned bin to destination buf */\n        err = mp_to_unsigned_bin(src, dst->buf + y);\n    }\n\n    return err;\n}\n\nint wc_mp_to_bigint(mp_int* src, WC_BIGINT* dst)\n{\n    if (src == NULL || dst == NULL)\n        return BAD_FUNC_ARG;\n\n    return wc_mp_to_bigint_sz(src, dst, 0);\n}\n\nint wc_bigint_to_mp(WC_BIGINT* src, mp_int* dst)\n{\n    int err;\n\n    if (src == NULL || dst == NULL)\n        return BAD_FUNC_ARG;\n\n    if (src->buf == NULL)\n        return BAD_FUNC_ARG;\n\n    err = mp_read_unsigned_bin(dst, src->buf, src->len);\n    wc_bigint_free(src);\n\n    return err;\n}\n\n#endif /* HAVE_WOLF_BIGINT */\n\n#endif /* USE_FAST_MATH || !NO_BIG_INT */\n"
  },
  {
    "path": "src/wolfssl/version.h",
    "content": "/* wolfssl_version.h.in\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifndef WOLFSSL_VERSION_H\n#define WOLFSSL_VERSION_H\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define LIBWOLFSSL_VERSION_STRING \"4.3.0\"\n#define LIBWOLFSSL_VERSION_HEX 0x04003000\n\n#ifdef __cplusplus\n}\n#endif\n\n\n#endif /* WOLFSSL_VERSION_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/aes.h",
    "content": "/* aes.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/aes.h\n*/\n\n\n#ifndef WOLF_CRYPT_AES_H\n#define WOLF_CRYPT_AES_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_AES\n\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n    #include <wolfssl/wolfcrypt/fips.h>\n#endif /* HAVE_FIPS_VERSION >= 2 */\n\n/* included for fips @wc_fips */\n#if defined(HAVE_FIPS) && \\\n    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n#include <cyassl/ctaocrypt/aes.h>\n#if defined(CYASSL_AES_COUNTER) && !defined(WOLFSSL_AES_COUNTER)\n    #define WOLFSSL_AES_COUNTER\n#endif\n#if !defined(WOLFSSL_AES_DIRECT) && defined(CYASSL_AES_DIRECT)\n    #define WOLFSSL_AES_DIRECT\n#endif\n#endif\n\n#ifndef WC_NO_RNG\n    #include <wolfssl/wolfcrypt/random.h>\n#endif\n#ifdef STM32_CRYPTO\n    #include <wolfssl/wolfcrypt/port/st/stm32.h>\n#endif\n\n#ifdef WOLFSSL_AESNI\n\n#include <wmmintrin.h>\n#include <emmintrin.h>\n#include <smmintrin.h>\n\n#endif /* WOLFSSL_AESNI */\n\n\n#ifdef WOLFSSL_XILINX_CRYPT\n#include \"xsecure_aes.h\"\n#endif\n\n#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)\n/* included for struct msghdr */\n#include <wolfssl/wolfcrypt/port/af_alg/wc_afalg.h>\n#endif\n\n#if defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)\n#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>\n#endif\n\n#if defined(HAVE_AESGCM) && !defined(WC_NO_RNG)\n    #include <wolfssl/wolfcrypt/random.h>\n#endif\n\n#if defined(WOLFSSL_CRYPTOCELL)\n    #include <wolfssl/wolfcrypt/port/arm/cryptoCell.h>\n#endif\n\n#if defined(WOLFSSL_RENESAS_TSIP_TLS) && \\\n    defined(WOLFSSL_RENESAS_TSIP_TLS_AES_CRYPT)\n    #include <wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h>\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* these are required for FIPS and non-FIPS */\nenum {\n    AES_128_KEY_SIZE    = 16,  /* for 128 bit             */\n    AES_192_KEY_SIZE    = 24,  /* for 192 bit             */\n    AES_256_KEY_SIZE    = 32,  /* for 256 bit             */\n\n    AES_IV_SIZE         = 16,  /* always block size       */\n};\n\n\n/* avoid redefinition of structs */\n#if !defined(HAVE_FIPS) || \\\n    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n\nenum {\n    AES_ENC_TYPE   = WC_CIPHER_AES,   /* cipher unique type */\n    AES_ENCRYPTION = 0,\n    AES_DECRYPTION = 1,\n\n    AES_BLOCK_SIZE      = 16,\n\n    KEYWRAP_BLOCK_SIZE  = 8,\n\n    GCM_NONCE_MAX_SZ = 16, /* wolfCrypt's maximum nonce size allowed. */\n    GCM_NONCE_MID_SZ = 12, /* The usual default nonce size for AES-GCM. */\n    GCM_NONCE_MIN_SZ = 8,  /* wolfCrypt's minimum nonce size allowed. */\n    CCM_NONCE_MIN_SZ = 7,\n    CCM_NONCE_MAX_SZ = 13,\n    CTR_SZ   = 4,\n    AES_IV_FIXED_SZ = 4,\n\n#ifdef HAVE_PKCS11\n    AES_MAX_ID_LEN   = 32,\n#endif\n};\n\n\nstruct Aes {\n    /* AESNI needs key first, rounds 2nd, not sure why yet */\n    ALIGN16 word32 key[60];\n    word32  rounds;\n    int     keylen;\n\n    ALIGN16 word32 reg[AES_BLOCK_SIZE / sizeof(word32)];      /* for CBC mode */\n    ALIGN16 word32 tmp[AES_BLOCK_SIZE / sizeof(word32)];      /* same         */\n\n#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)\n    word32 invokeCtr[2];\n    word32 nonceSz;\n#endif\n#ifdef HAVE_AESGCM\n    ALIGN16 byte H[AES_BLOCK_SIZE];\n#ifdef OPENSSL_EXTRA\n    word32 aadH[4]; /* additional authenticated data GHASH */\n    word32 aadLen;  /* additional authenticated data len */\n#endif\n\n#ifdef GCM_TABLE\n    /* key-based fast multiplication table. */\n    ALIGN16 byte M0[256][AES_BLOCK_SIZE];\n#endif /* GCM_TABLE */\n#ifdef HAVE_CAVIUM_OCTEON_SYNC\n    word32 y0;\n#endif\n#endif /* HAVE_AESGCM */\n#ifdef WOLFSSL_AESNI\n    byte use_aesni;\n#endif /* WOLFSSL_AESNI */\n#ifdef WOLF_CRYPTO_CB\n    int    devId;\n    void*  devCtx;\n#endif\n#ifdef HAVE_PKCS11\n    byte id[AES_MAX_ID_LEN];\n    int  idLen;\n#endif\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV asyncDev;\n#endif /* WOLFSSL_ASYNC_CRYPT */\n#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB)\n    word32  left;            /* unused bytes left from last call */\n#endif\n#ifdef WOLFSSL_XILINX_CRYPT\n    XSecure_Aes xilAes;\n    XCsuDma     dma;\n    word32      key_init[8];\n    word32      kup;\n#endif\n#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)\n    int alFd; /* server socket to bind to */\n    int rdFd; /* socket to read from */\n    struct msghdr msg;\n    int dir;  /* flag for encrpyt or decrypt */\n#ifdef WOLFSSL_AFALG_XILINX_AES\n    word32 msgBuf[CMSG_SPACE(4) + CMSG_SPACE(sizeof(struct af_alg_iv) +\n                  GCM_NONCE_MID_SZ)];\n#endif\n#endif\n#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \\\n    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \\\n    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))\n    word32 devKey[AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE/sizeof(word32)]; /* raw key */\n#ifdef HAVE_CAVIUM_OCTEON_SYNC\n    int    keySet;\n#endif\n#endif\n#if defined(WOLFSSL_DEVCRYPTO) && \\\n    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))\n    WC_CRYPTODEV ctx;\n#endif\n#if defined(WOLFSSL_CRYPTOCELL)\n    aes_context_t ctx;\n#endif\n#if defined(WOLFSSL_RENESAS_TSIP_TLS) && \\\n    defined(WOLFSSL_RENESAS_TSIP_TLS_AES_CRYPT)\n    TSIP_AES_CTX ctx;\n#endif\n    void*  heap; /* memory hint to use */\n};\n\n#ifndef WC_AES_TYPE_DEFINED\n    typedef struct Aes Aes;\n    #define WC_AES_TYPE_DEFINED\n#endif\n\n#ifdef WOLFSSL_AES_XTS\ntypedef struct XtsAes {\n    Aes aes;\n    Aes tweak;\n} XtsAes;\n#endif\n\n#ifdef HAVE_AESGCM\ntypedef struct Gmac {\n    Aes aes;\n} Gmac;\n#endif /* HAVE_AESGCM */\n#endif /* HAVE_FIPS */\n\n\n/* Authenticate cipher function prototypes */\ntypedef int (*wc_AesAuthEncryptFunc)(Aes* aes, byte* out,\n                                   const byte* in, word32 sz,\n                                   const byte* iv, word32 ivSz,\n                                   byte* authTag, word32 authTagSz,\n                                   const byte* authIn, word32 authInSz);\ntypedef int (*wc_AesAuthDecryptFunc)(Aes* aes, byte* out,\n                                   const byte* in, word32 sz,\n                                   const byte* iv, word32 ivSz,\n                                   const byte* authTag, word32 authTagSz,\n                                   const byte* authIn, word32 authInSz);\n\n/* AES-CBC */\nWOLFSSL_API int  wc_AesSetKey(Aes* aes, const byte* key, word32 len,\n                              const byte* iv, int dir);\nWOLFSSL_API int  wc_AesSetIV(Aes* aes, const byte* iv);\n\n#ifdef HAVE_AES_CBC\nWOLFSSL_API int  wc_AesCbcEncrypt(Aes* aes, byte* out,\n                                  const byte* in, word32 sz);\nWOLFSSL_API int  wc_AesCbcDecrypt(Aes* aes, byte* out,\n                                  const byte* in, word32 sz);\n#endif\n\n#ifdef WOLFSSL_AES_CFB\nWOLFSSL_API int wc_AesCfbEncrypt(Aes* aes, byte* out,\n                                    const byte* in, word32 sz);\n#ifdef HAVE_AES_DECRYPT\nWOLFSSL_API int wc_AesCfbDecrypt(Aes* aes, byte* out,\n                                    const byte* in, word32 sz);\n#endif /* HAVE_AES_DECRYPT */\n#endif /* WOLFSSL_AES_CFB */\n\n#ifdef HAVE_AES_ECB\nWOLFSSL_API int wc_AesEcbEncrypt(Aes* aes, byte* out,\n                                  const byte* in, word32 sz);\nWOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out,\n                                  const byte* in, word32 sz);\n#endif\n\n/* AES-CTR */\n#ifdef WOLFSSL_AES_COUNTER\n WOLFSSL_API int wc_AesCtrEncrypt(Aes* aes, byte* out,\n                                   const byte* in, word32 sz);\n#endif\n/* AES-DIRECT */\n#if defined(WOLFSSL_AES_DIRECT)\n WOLFSSL_API void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in);\n WOLFSSL_API void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in);\n WOLFSSL_API int  wc_AesSetKeyDirect(Aes* aes, const byte* key, word32 len,\n                                const byte* iv, int dir);\n#endif\n\n#ifdef HAVE_AESGCM\n#ifdef WOLFSSL_XILINX_CRYPT\n WOLFSSL_API int  wc_AesGcmSetKey_ex(Aes* aes, const byte* key, word32 len,\n         word32 kup);\n#elif defined(WOLFSSL_AFALG_XILINX_AES)\n WOLFSSL_LOCAL int  wc_AesGcmSetKey_ex(Aes* aes, const byte* key, word32 len,\n         word32 kup);\n#endif\n WOLFSSL_API int  wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len);\n WOLFSSL_API int  wc_AesGcmEncrypt(Aes* aes, byte* out,\n                                   const byte* in, word32 sz,\n                                   const byte* iv, word32 ivSz,\n                                   byte* authTag, word32 authTagSz,\n                                   const byte* authIn, word32 authInSz);\n WOLFSSL_API int  wc_AesGcmDecrypt(Aes* aes, byte* out,\n                                   const byte* in, word32 sz,\n                                   const byte* iv, word32 ivSz,\n                                   const byte* authTag, word32 authTagSz,\n                                   const byte* authIn, word32 authInSz);\n\n#ifndef WC_NO_RNG\n WOLFSSL_API int  wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz);\n WOLFSSL_API int  wc_AesGcmSetIV(Aes* aes, word32 ivSz,\n                                   const byte* ivFixed, word32 ivFixedSz,\n                                   WC_RNG* rng);\n WOLFSSL_API int  wc_AesGcmEncrypt_ex(Aes* aes, byte* out,\n                                   const byte* in, word32 sz,\n                                   byte* ivOut, word32 ivOutSz,\n                                   byte* authTag, word32 authTagSz,\n                                   const byte* authIn, word32 authInSz);\n#endif /* WC_NO_RNG */\n\n WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len);\n WOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,\n                               const byte* authIn, word32 authInSz,\n                               byte* authTag, word32 authTagSz);\n#ifndef WC_NO_RNG\n WOLFSSL_API int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,\n                               const byte* authIn, word32 authInSz,\n                               byte* authTag, word32 authTagSz, WC_RNG* rng);\n WOLFSSL_API int wc_GmacVerify(const byte* key, word32 keySz,\n                               const byte* iv, word32 ivSz,\n                               const byte* authIn, word32 authInSz,\n                               const byte* authTag, word32 authTagSz);\n#endif /* WC_NO_RNG */\n WOLFSSL_LOCAL void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,\n                               word32 cSz, byte* s, word32 sSz);\n#endif /* HAVE_AESGCM */\n#ifdef HAVE_AESCCM\n WOLFSSL_API int  wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz);\n WOLFSSL_API int  wc_AesCcmEncrypt(Aes* aes, byte* out,\n                                   const byte* in, word32 inSz,\n                                   const byte* nonce, word32 nonceSz,\n                                   byte* authTag, word32 authTagSz,\n                                   const byte* authIn, word32 authInSz);\n WOLFSSL_API int  wc_AesCcmDecrypt(Aes* aes, byte* out,\n                                   const byte* in, word32 inSz,\n                                   const byte* nonce, word32 nonceSz,\n                                   const byte* authTag, word32 authTagSz,\n                                   const byte* authIn, word32 authInSz);\n WOLFSSL_API int  wc_AesCcmSetNonce(Aes* aes,\n                                   const byte* nonce, word32 nonceSz);\n WOLFSSL_API int  wc_AesCcmEncrypt_ex(Aes* aes, byte* out,\n                                   const byte* in, word32 sz,\n                                   byte* ivOut, word32 ivOutSz,\n                                   byte* authTag, word32 authTagSz,\n                                   const byte* authIn, word32 authInSz);\n#endif /* HAVE_AESCCM */\n#ifdef HAVE_AES_KEYWRAP\n WOLFSSL_API int  wc_AesKeyWrap(const byte* key, word32 keySz,\n                                const byte* in, word32 inSz,\n                                byte* out, word32 outSz,\n                                const byte* iv);\n WOLFSSL_API int  wc_AesKeyUnWrap(const byte* key, word32 keySz,\n                                const byte* in, word32 inSz,\n                                byte* out, word32 outSz,\n                                const byte* iv);\n#endif /* HAVE_AES_KEYWRAP */\n\n#ifdef WOLFSSL_AES_XTS\n\nWOLFSSL_API int wc_AesXtsSetKey(XtsAes* aes, const byte* key,\n         word32 len, int dir, void* heap, int devId);\n\nWOLFSSL_API int wc_AesXtsEncryptSector(XtsAes* aes, byte* out,\n         const byte* in, word32 sz, word64 sector);\n\nWOLFSSL_API int wc_AesXtsDecryptSector(XtsAes* aes, byte* out,\n         const byte* in, word32 sz, word64 sector);\n\nWOLFSSL_API int wc_AesXtsEncrypt(XtsAes* aes, byte* out,\n         const byte* in, word32 sz, const byte* i, word32 iSz);\n\nWOLFSSL_API int wc_AesXtsDecrypt(XtsAes* aes, byte* out,\n        const byte* in, word32 sz, const byte* i, word32 iSz);\n\nWOLFSSL_API int wc_AesXtsFree(XtsAes* aes);\n#endif\n\nWOLFSSL_API int wc_AesGetKeySize(Aes* aes, word32* keySize);\n\nWOLFSSL_API int  wc_AesInit(Aes* aes, void* heap, int devId);\n#ifdef HAVE_PKCS11\nWOLFSSL_API int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap,\n        int devId);\n#endif\nWOLFSSL_API void wc_AesFree(Aes* aes);\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n\n#endif /* NO_AES */\n#endif /* WOLF_CRYPT_AES_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/arc4.h",
    "content": "/* arc4.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/arc4.h\n*/\n\n#ifndef WOLF_CRYPT_ARC4_H\n#define WOLF_CRYPT_ARC4_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n\nenum {\n\tARC4_ENC_TYPE   = 4,    /* cipher unique type */\n    ARC4_STATE_SIZE = 256,\n    RC4_KEY_SIZE    = 16,   /* always 128bit           */\n};\n\n/* ARC4 encryption and decryption */\ntypedef struct Arc4 {\n    byte x;\n    byte y;\n    byte state[ARC4_STATE_SIZE];\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV asyncDev;\n#endif\n    void* heap;\n} Arc4;\n\nWOLFSSL_API int wc_Arc4Process(Arc4*, byte*, const byte*, word32);\nWOLFSSL_API int wc_Arc4SetKey(Arc4*, const byte*, word32);\n\nWOLFSSL_API int  wc_Arc4Init(Arc4*, void*, int);\nWOLFSSL_API void wc_Arc4Free(Arc4*);\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n\n#endif /* WOLF_CRYPT_ARC4_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/asn.h",
    "content": "/* asn.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/asn.h\n*/\n\n#ifndef WOLF_CRYPT_ASN_H\n#define WOLF_CRYPT_ASN_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_ASN\n\n\n#if !defined(NO_ASN_TIME) && defined(NO_TIME_H)\n    #define NO_ASN_TIME /* backwards compatibility with NO_TIME_H */\n#endif\n\n#include <wolfssl/wolfcrypt/integer.h>\n\n/* fips declare of RsaPrivateKeyDecode @wc_fips */\n#if defined(HAVE_FIPS) && !defined(NO_RSA) && \\\n\t(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n    #include <cyassl/ctaocrypt/rsa.h>\n#endif\n\n#ifndef NO_DH\n    #include <wolfssl/wolfcrypt/dh.h>\n#endif\n#ifndef NO_DSA\n    #include <wolfssl/wolfcrypt/dsa.h>\n#endif\n#ifndef NO_SHA\n    #include <wolfssl/wolfcrypt/sha.h>\n#endif\n#ifndef NO_MD5\n    #include <wolfssl/wolfcrypt/md5.h>\n#endif\n#include <wolfssl/wolfcrypt/sha256.h>\n#include <wolfssl/wolfcrypt/asn_public.h>   /* public interface */\n\n#if defined(NO_SHA) && defined(NO_SHA256)\n    #define WC_SHA256_DIGEST_SIZE 32\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifndef EXTERNAL_SERIAL_SIZE\n    #define EXTERNAL_SERIAL_SIZE 32\n#endif\n\nenum {\n    ISSUER  = 0,\n    SUBJECT = 1,\n\n    BEFORE  = 0,\n    AFTER   = 1\n};\n\n/* ASN Tags   */\nenum ASN_Tags {\n    ASN_EOC               = 0x00,\n    ASN_BOOLEAN           = 0x01,\n    ASN_INTEGER           = 0x02,\n    ASN_BIT_STRING        = 0x03,\n    ASN_OCTET_STRING      = 0x04,\n    ASN_TAG_NULL          = 0x05,\n    ASN_OBJECT_ID         = 0x06,\n    ASN_ENUMERATED        = 0x0a,\n    ASN_UTF8STRING        = 0x0c,\n    ASN_SEQUENCE          = 0x10,\n    ASN_SET               = 0x11,\n    ASN_PRINTABLE_STRING  = 0x13,\n    ASN_UTC_TIME          = 0x17,\n    ASN_OTHER_TYPE        = 0x00,\n    ASN_RFC822_TYPE       = 0x01,\n    ASN_DNS_TYPE          = 0x02,\n    ASN_DIR_TYPE          = 0x04,\n    ASN_URI_TYPE          = 0x06, /* the value 6 is from GeneralName OID */\n    ASN_GENERALIZED_TIME  = 0x18,\n    CRL_EXTENSIONS        = 0xa0,\n    ASN_EXTENSIONS        = 0xa3,\n    ASN_LONG_LENGTH       = 0x80,\n    ASN_INDEF_LENGTH      = 0x80,\n\n    /* ASN_Flags - Bitmask */\n    ASN_CONSTRUCTED       = 0x20,\n    ASN_APPLICATION       = 0x40,\n    ASN_CONTEXT_SPECIFIC  = 0x80,\n};\n\n#define ASN_UTC_TIME_SIZE 14\n#define ASN_GENERALIZED_TIME_SIZE 16\n#define ASN_GENERALIZED_TIME_MAX 68\n\nenum DN_Tags {\n    ASN_DN_NULL       = 0x00,\n    ASN_COMMON_NAME   = 0x03,   /* CN */\n    ASN_SUR_NAME      = 0x04,   /* SN */\n    ASN_SERIAL_NUMBER = 0x05,   /* serialNumber */\n    ASN_COUNTRY_NAME  = 0x06,   /* C  */\n    ASN_LOCALITY_NAME = 0x07,   /* L  */\n    ASN_STATE_NAME    = 0x08,   /* ST */\n    ASN_ORG_NAME      = 0x0a,   /* O  */\n    ASN_ORGUNIT_NAME  = 0x0b,   /* OU */\n    ASN_BUS_CAT       = 0x0f,   /* businessCategory */\n    ASN_EMAIL_NAME    = 0x98,   /* not oid number there is 97 in 2.5.4.0-97 */\n\n    /* pilot attribute types\n     * OID values of 0.9.2342.19200300.100.1.* */\n    ASN_USER_ID          = 0x01, /* UID */\n    ASN_DOMAIN_COMPONENT = 0x19  /* DC */\n};\n\n/* DN Tag Strings */\n#define WOLFSSL_COMMON_NAME      \"/CN=\"\n#define WOLFSSL_SUR_NAME         \"/SN=\"\n#define WOLFSSL_SERIAL_NUMBER    \"/serialNumber=\"\n#define WOLFSSL_COUNTRY_NAME     \"/C=\"\n#define WOLFSSL_LOCALITY_NAME    \"/L=\"\n#define WOLFSSL_STATE_NAME       \"/ST=\"\n#define WOLFSSL_ORG_NAME         \"/O=\"\n#define WOLFSSL_ORGUNIT_NAME     \"/OU=\"\n#define WOLFSSL_DOMAIN_COMPONENT \"/DC=\"\n#define WOLFSSL_BUS_CAT          \"/businessCategory=\"\n#define WOLFSSL_JOI_C            \"/jurisdictionC=\"\n#define WOLFSSL_JOI_ST           \"/jurisdictionST=\"\n#define WOLFSSL_EMAIL_ADDR       \"/emailAddress=\"\n\n#define WOLFSSL_USER_ID          \"/UID=\"\n#define WOLFSSL_DOMAIN_COMPONENT \"/DC=\"\n\n#if defined(WOLFSSL_APACHE_HTTPD)\n    /* otherName strings */\n    #define WOLFSSL_SN_MS_UPN       \"msUPN\"\n    #define WOLFSSL_LN_MS_UPN       \"Microsoft Universal Principal Name\"\n    #define WOLFSSL_MS_UPN_SUM 265\n    #define WOLFSSL_SN_DNS_SRV      \"id-on-dnsSRV\"\n    #define WOLFSSL_LN_DNS_SRV      \"SRVName otherName form\"\n    /* TLS features extension strings */\n    #define WOLFSSL_SN_TLS_FEATURE  \"tlsfeature\"\n    #define WOLFSSL_LN_TLS_FEATURE  \"TLS Feature\"\n    #define WOLFSSL_TLS_FEATURE_SUM 92\n#endif\n\n/* NIDs */\nenum\n{\n    NID_undef = 0,\n    NID_netscape_cert_type = NID_undef,\n    NID_des = 66,\n    NID_des3 = 67,\n    NID_sha256 = 672,\n    NID_sha384 = 673,\n    NID_sha512 = 674,\n    NID_hw_name_oid = 73,\n    NID_id_pkix_OCSP_basic = 74,\n    NID_any_policy = 75,\n    NID_anyExtendedKeyUsage = 76,\n    NID_givenName = 99,\n    NID_initials = 101,\n    NID_title = 106,\n    NID_description = 107,\n    NID_basic_constraints = 133,\n    NID_key_usage = 129,     /* 2.5.29.15 */\n    NID_ext_key_usage = 151, /* 2.5.29.37 */\n    NID_subject_key_identifier = 128,\n    NID_authority_key_identifier = 149,\n    NID_private_key_usage_period = 130, /* 2.5.29.16 */\n    NID_subject_alt_name = 131,\n    NID_issuer_alt_name = 132,\n    NID_info_access = 69,\n    NID_sinfo_access = 79,      /* id-pe 11 */\n    NID_name_constraints = 144, /* 2.5.29.30 */\n    NID_crl_distribution_points = 145, /* 2.5.29.31 */\n    NID_certificate_policies = 146,\n    NID_policy_mappings = 147,\n    NID_policy_constraints = 150,\n    NID_inhibit_any_policy = 168,      /* 2.5.29.54 */\n    NID_tlsfeature = 1020,             /* id-pe 24 */\n    NID_commonName = 0x03,             /* matchs ASN_COMMON_NAME in asn.h */\n\n\n    NID_surname = 0x04,                /* SN */\n    NID_serialNumber = 0x05,           /* serialNumber */\n    NID_countryName = 0x06,            /* C  */\n    NID_localityName = 0x07,           /* L  */\n    NID_stateOrProvinceName = 0x08,    /* ST */\n    NID_organizationName = 0x0a,       /* O  */\n    NID_organizationalUnitName = 0x0b, /* OU */\n    NID_domainComponent = 0x19,        /* matchs ASN_DOMAIN_COMPONENT in asn.h */\n    NID_emailAddress = 0x30,           /* emailAddress */\n    NID_id_on_dnsSRV = 82,             /* 1.3.6.1.5.5.7.8.7 */\n    NID_ms_upn = 265                   /* 1.3.6.1.4.1.311.20.2.3 */\n};\n\nenum ECC_TYPES\n{\n    ECC_PREFIX_0 = 160,\n    ECC_PREFIX_1 = 161\n};\n\n#ifdef WOLFSSL_CERT_PIV\n    enum PIV_Tags {\n        ASN_PIV_CERT          = 0x0A,\n        ASN_PIV_NONCE         = 0x0B,\n        ASN_PIV_SIGNED_NONCE  = 0x0C,\n\n        ASN_PIV_TAG_CERT      = 0x70,\n        ASN_PIV_TAG_CERT_INFO = 0x71,\n        ASN_PIV_TAG_MSCUID    = 0x72,\n        ASN_PIV_TAG_ERR_DET   = 0xFE,\n\n        /* certificate info masks */\n        ASN_PIV_CERT_INFO_COMPRESSED = 0x03,\n        ASN_PIV_CERT_INFO_ISX509     = 0x04,\n    };\n#endif /* WOLFSSL_CERT_PIV */\n\n\n#define ASN_JOI_PREFIX_SZ       10\n#define ASN_JOI_PREFIX          \"\\x2b\\x06\\x01\\x04\\x01\\x82\\x37\\x3c\\x02\\x01\"\n#define ASN_JOI_C               0x3\n#define ASN_JOI_ST              0x2\n\n#ifndef WC_ASN_NAME_MAX\n    #ifdef OPENSSL_EXTRA\n        #define WC_ASN_NAME_MAX 300\n    #else\n        #define WC_ASN_NAME_MAX 256\n    #endif\n#endif\n#define ASN_NAME_MAX WC_ASN_NAME_MAX\n\nenum Misc_ASN {\n    MAX_SALT_SIZE       =  64,     /* MAX PKCS Salt length */\n    MAX_IV_SIZE         =  64,     /* MAX PKCS Iv length */\n    ASN_BOOL_SIZE       =   2,     /* including type */\n    ASN_ECC_HEADER_SZ   =   2,     /* String type + 1 byte len */\n    ASN_ECC_CONTEXT_SZ  =   2,     /* Content specific type + 1 byte len */\n#ifdef NO_SHA\n    KEYID_SIZE          = WC_SHA256_DIGEST_SIZE,\n#else\n    KEYID_SIZE          = WC_SHA_DIGEST_SIZE,\n#endif\n    RSA_INTS            =   8,     /* RSA ints in private key */\n    DSA_INTS            =   5,     /* DSA ints in private key */\n    MIN_DATE_SIZE       =  13,\n    MAX_DATE_SIZE       =  32,\n    ASN_GEN_TIME_SZ     =  15,     /* 7 numbers * 2 + Zulu tag */\n#ifndef NO_RSA\n    MAX_ENCODED_SIG_SZ  = 512,\n#elif defined(HAVE_ECC)\n    MAX_ENCODED_SIG_SZ  = 140,\n#else\n    MAX_ENCODED_SIG_SZ  =  64,\n#endif\n    MAX_SIG_SZ          = 256,\n    MAX_ALGO_SZ         =  20,\n    MAX_SHORT_SZ        =   6,     /* asn int + byte len + 4 byte length */\n    MAX_SEQ_SZ          =   5,     /* enum(seq | con) + length(4) */\n    MAX_SET_SZ          =   5,     /* enum(set | con) + length(4) */\n    MAX_OCTET_STR_SZ    =   5,     /* enum(set | con) + length(4) */\n    MAX_EXP_SZ          =   5,     /* enum(contextspec|con|exp) + length(4) */\n    MAX_PRSTR_SZ        =   5,     /* enum(prstr) + length(4) */\n    MAX_VERSION_SZ      =   5,     /* enum + id + version(byte) + (header(2))*/\n    MAX_ENCODED_DIG_ASN_SZ= 9,     /* enum(bit or octet) + length(4) */\n    MAX_ENCODED_DIG_SZ  =  64 + MAX_ENCODED_DIG_ASN_SZ, /* asn header + sha512 */\n    MAX_RSA_INT_SZ      = 517,     /* RSA raw sz 4096 for bits + tag + len(4) */\n    MAX_NTRU_KEY_SZ     = 610,     /* NTRU 112 bit public key */\n    MAX_NTRU_ENC_SZ     = 628,     /* NTRU 112 bit DER public encoding */\n    MAX_LENGTH_SZ       =   4,     /* Max length size for DER encoding */\n    MAX_RSA_E_SZ        =  16,     /* Max RSA public e size */\n    MAX_CA_SZ           =  32,     /* Max encoded CA basic constraint length */\n    MAX_SN_SZ           =  35,     /* Max encoded serial number (INT) length */\n    MAX_DER_DIGEST_SZ     = MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ,\n                            /* Maximum DER digest size */\n    MAX_DER_DIGEST_ASN_SZ = MAX_ENCODED_DIG_ASN_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ,\n                            /* Maximum DER digest ASN header size */\n#ifdef WOLFSSL_CERT_GEN\n    #ifdef WOLFSSL_CERT_REQ\n                          /* Max encoded cert req attributes length */\n        MAX_ATTRIB_SZ   = MAX_SEQ_SZ * 3 + (11 + MAX_SEQ_SZ) * 2 +\n                          MAX_PRSTR_SZ + CTC_NAME_SIZE, /* 11 is the OID size */\n    #endif\n    #if defined(WOLFSSL_ALT_NAMES) || defined(WOLFSSL_CERT_EXT)\n        MAX_EXTENSIONS_SZ   = 1 + MAX_LENGTH_SZ + CTC_MAX_ALT_SIZE,\n    #else\n        MAX_EXTENSIONS_SZ   = 1 + MAX_LENGTH_SZ + MAX_CA_SZ,\n    #endif\n                                   /* Max total extensions, id + len + others */\n#endif\n#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || defined(HAVE_PKCS7)\n    MAX_OID_SZ          = 32,      /* Max DER length of OID*/\n    MAX_OID_STRING_SZ   = 64,      /* Max string length representation of OID*/\n#endif\n#ifdef WOLFSSL_CERT_EXT\n    MAX_KID_SZ\t\t\t= 45,\t   /* Max encoded KID length (SHA-256 case) */\n    MAX_KEYUSAGE_SZ     = 18,      /* Max encoded Key Usage length */\n    MAX_EXTKEYUSAGE_SZ  = 12 + (6 * (8 + 2)) +\n                          CTC_MAX_EKU_OID_SZ, /* Max encoded ExtKeyUsage\n                          (SEQ/LEN + OBJID + OCTSTR/LEN + SEQ +\n                          (6 * (SEQ + OID))) */\n    MAX_CERTPOL_NB      = CTC_MAX_CERTPOL_NB,/* Max number of Cert Policy */\n    MAX_CERTPOL_SZ      = CTC_MAX_CERTPOL_SZ,\n#endif\n    MAX_NAME_ENTRIES    = 5,       /* extra entries added to x509 name struct */\n    OCSP_NONCE_EXT_SZ   = 35,      /* OCSP Nonce Extension size */\n    MAX_OCSP_EXT_SZ     = 58,      /* Max OCSP Extension length */\n    MAX_OCSP_NONCE_SZ   = 16,      /* OCSP Nonce size           */\n    EIGHTK_BUF          = 8192,    /* Tmp buffer size           */\n    MAX_PUBLIC_KEY_SZ   = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2,\n                                   /* use bigger NTRU size */\n#ifdef WOLFSSL_ENCRYPTED_KEYS\n    HEADER_ENCRYPTED_KEY_SIZE = 88,/* Extra header size for encrypted key */\n#else\n    HEADER_ENCRYPTED_KEY_SIZE = 0,\n#endif\n    TRAILING_ZERO       = 1,       /* Used for size of zero pad */\n    ASN_TAG_SZ          = 1,       /* single byte ASN.1 tag */\n    MIN_VERSION_SZ      = 3,       /* Min bytes needed for GetMyVersion */\n#if defined(OPENSSL_ALL)  || defined(WOLFSSL_MYSQL_COMPATIBLE) || \\\n    defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \\\n    defined(OPENSSL_EXTRA) || defined(HAVE_PKCS7)\n    MAX_TIME_STRING_SZ  = 25,      /* Max length of formatted time string */\n#endif\n\n    PKCS5_SALT_SZ       = 8,\n\n    PEM_LINE_LEN       = 80,       /* PEM line max + fudge */\n};\n\n\nenum Oid_Types {\n    oidHashType         = 0,\n    oidSigType          = 1,\n    oidKeyType          = 2,\n    oidCurveType        = 3,\n    oidBlkType          = 4,\n    oidOcspType         = 5,\n    oidCertExtType      = 6,\n    oidCertAuthInfoType = 7,\n    oidCertPolicyType   = 8,\n    oidCertAltNameType  = 9,\n    oidCertKeyUseType   = 10,\n    oidKdfType          = 11,\n    oidKeyWrapType      = 12,\n    oidCmsKeyAgreeType  = 13,\n    oidPBEType          = 14,\n    oidHmacType         = 15,\n    oidCompressType     = 16,\n    oidCertNameType     = 17,\n    oidTlsExtType       = 18,\n    oidCrlExtType       = 19,\n    oidIgnoreType\n};\n\n\nenum Hash_Sum  {\n    MD2h      = 646,\n    MD5h      = 649,\n    SHAh      =  88,\n    SHA224h   = 417,\n    SHA256h   = 414,\n    SHA384h   = 415,\n    SHA512h   = 416,\n    SHA3_224h = 420,\n    SHA3_256h = 421,\n    SHA3_384h = 422,\n    SHA3_512h = 423\n};\n\n\n#if !defined(NO_DES3) || !defined(NO_AES)\nenum Block_Sum {\n#ifdef WOLFSSL_AES_128\n    AES128CBCb = 414,\n    AES128GCMb = 418,\n    AES128CCMb = 419,\n#endif\n#ifdef WOLFSSL_AES_192\n    AES192CBCb = 434,\n    AES192GCMb = 438,\n    AES192CCMb = 439,\n#endif\n#ifdef WOLFSSL_AES_256\n    AES256CBCb = 454,\n    AES256GCMb = 458,\n    AES256CCMb = 459,\n#endif\n#ifndef NO_DES3\n    DESb       = 69,\n    DES3b      = 652\n#endif\n};\n#endif /* !NO_DES3 || !NO_AES */\n\n\nenum Key_Sum {\n    DSAk     = 515,\n    RSAk     = 645,\n    NTRUk    = 274,\n    ECDSAk   = 518,\n    ED25519k = 256\n};\n\n\n#if !defined(NO_AES) || defined(HAVE_PKCS7)\nenum KeyWrap_Sum {\n#ifdef WOLFSSL_AES_128\n    AES128_WRAP  = 417,\n#endif\n#ifdef WOLFSSL_AES_192\n    AES192_WRAP  = 437,\n#endif\n#ifdef WOLFSSL_AES_256\n    AES256_WRAP  = 457,\n#endif\n#ifdef HAVE_PKCS7\n    PWRI_KEK_WRAP = 680  /*id-alg-PWRI-KEK, 1.2.840.113549.1.9.16.3.9 */\n#endif\n};\n#endif /* !NO_AES || PKCS7 */\n\nenum Key_Agree {\n    dhSinglePass_stdDH_sha1kdf_scheme   = 464,\n    dhSinglePass_stdDH_sha224kdf_scheme = 188,\n    dhSinglePass_stdDH_sha256kdf_scheme = 189,\n    dhSinglePass_stdDH_sha384kdf_scheme = 190,\n    dhSinglePass_stdDH_sha512kdf_scheme = 191,\n};\n\n\n\nenum KDF_Sum {\n    PBKDF2_OID = 660\n};\n\n\nenum HMAC_Sum {\n    HMAC_SHA224_OID   = 652,\n    HMAC_SHA256_OID   = 653,\n    HMAC_SHA384_OID   = 654,\n    HMAC_SHA512_OID   = 655,\n    HMAC_SHA3_224_OID = 426,\n    HMAC_SHA3_256_OID = 427,\n    HMAC_SHA3_384_OID = 428,\n    HMAC_SHA3_512_OID = 429\n};\n\n\nenum Extensions_Sum {\n    BASIC_CA_OID    = 133,\n    ALT_NAMES_OID   = 131,\n    CRL_DIST_OID    = 145,\n    AUTH_INFO_OID   = 69, /* id-pe 1 */\n    AUTH_KEY_OID    = 149,\n    SUBJ_KEY_OID    = 128,\n    CERT_POLICY_OID = 146,\n    KEY_USAGE_OID   = 129,  /* 2.5.29.15 */\n    INHIBIT_ANY_OID = 168,  /* 2.5.29.54 */\n    EXT_KEY_USAGE_OID         = 151, /* 2.5.29.37 */\n    NAME_CONS_OID             = 144, /* 2.5.29.30 */\n    PRIV_KEY_USAGE_PERIOD_OID = 130, /* 2.5.29.16 */\n    SUBJECT_INFO_ACCESS       = 79,  /* id-pe 11 */\n    POLICY_MAP_OID            = 147,\n    POLICY_CONST_OID          = 150,\n    ISSUE_ALT_NAMES_OID       = 132,\n    TLS_FEATURE_OID           = 92   /* id-pe 24 */\n};\n\nenum CertificatePolicy_Sum {\n    CP_ANY_OID      = 146  /* id-ce 32 0 */\n};\n\nenum SepHardwareName_Sum {\n    HW_NAME_OID     = 79   /* 1.3.6.1.5.5.7.8.4 from RFC 4108*/\n};\n\nenum AuthInfo_Sum {\n    AIA_OCSP_OID      = 116, /* 1.3.6.1.5.5.7.48.1 */\n    AIA_CA_ISSUER_OID = 117  /* 1.3.6.1.5.5.7.48.2 */\n};\n\nenum ExtKeyUsage_Sum { /* From RFC 5280 */\n    EKU_ANY_OID         = 151, /* 2.5.29.37.0, anyExtendedKeyUsage         */\n    EKU_SERVER_AUTH_OID = 71,  /* 1.3.6.1.5.5.7.3.1, id-kp-serverAuth      */\n    EKU_CLIENT_AUTH_OID = 72,  /* 1.3.6.1.5.5.7.3.2, id-kp-clientAuth      */\n    EKU_CODESIGNING_OID = 73,  /* 1.3.6.1.5.5.7.3.3, id-kp-codeSigning     */\n    EKU_EMAILPROTECT_OID = 74, /* 1.3.6.1.5.5.7.3.4, id-kp-emailProtection */\n    EKU_TIMESTAMP_OID   = 78,  /* 1.3.6.1.5.5.7.3.8, id-kp-timeStamping    */\n    EKU_OCSP_SIGN_OID   = 79   /* 1.3.6.1.5.5.7.3.9, id-kp-OCSPSigning     */\n};\n\n#ifdef HAVE_LIBZ\nenum CompressAlg_Sum {\n    ZLIBc = 679  /* 1.2.840.113549.1.9.16.3.8, id-alg-zlibCompress */\n};\n#endif\n\nenum VerifyType {\n    NO_VERIFY   = 0,\n    VERIFY      = 1,\n    VERIFY_CRL  = 2,\n    VERIFY_OCSP = 3,\n    VERIFY_NAME = 4,\n    VERIFY_SKIP_DATE = 5\n};\n\n#ifdef WOLFSSL_CERT_EXT\nenum KeyIdType {\n    SKID_TYPE = 0,\n    AKID_TYPE = 1\n};\n#endif\n\n/* Key usage extension bits (based on RFC 5280) */\n#define KEYUSE_DIGITAL_SIG    0x0080\n#define KEYUSE_CONTENT_COMMIT 0x0040\n#define KEYUSE_KEY_ENCIPHER   0x0020\n#define KEYUSE_DATA_ENCIPHER  0x0010\n#define KEYUSE_KEY_AGREE      0x0008\n#define KEYUSE_KEY_CERT_SIGN  0x0004\n#define KEYUSE_CRL_SIGN       0x0002\n#define KEYUSE_ENCIPHER_ONLY  0x0001\n#define KEYUSE_DECIPHER_ONLY  0x8000\n\n/* Extended Key Usage bits (internal mapping only) */\n#define EXTKEYUSE_USER        0x80\n#define EXTKEYUSE_OCSP_SIGN   0x40\n#define EXTKEYUSE_TIMESTAMP   0x20\n#define EXTKEYUSE_EMAILPROT   0x10\n#define EXTKEYUSE_CODESIGN    0x08\n#define EXTKEYUSE_CLIENT_AUTH 0x04\n#define EXTKEYUSE_SERVER_AUTH 0x02\n#define EXTKEYUSE_ANY         0x01\n\ntypedef struct DNS_entry   DNS_entry;\n\nstruct DNS_entry {\n    DNS_entry* next;   /* next on DNS list */\n    int        type;   /* i.e. ASN_DNS_TYPE */\n    int        len;    /* actual DNS len */\n    char*      name;   /* actual DNS name */\n};\n\n\ntypedef struct Base_entry  Base_entry;\n\nstruct Base_entry {\n    Base_entry* next;   /* next on name base list */\n    char*       name;   /* actual name base */\n    int         nameSz; /* name length */\n    byte        type;   /* Name base type (DNS or RFC822) */\n};\n\n#define DOMAIN_COMPONENT_MAX 10\n#define DN_NAMES_MAX 9\n\nstruct DecodedName {\n    char*   fullName;\n    int     fullNameLen;\n    int     entryCount;\n    int     cnIdx;\n    int     cnLen;\n    int     cnNid;\n    int     snIdx;\n    int     snLen;\n    int     snNid;\n    int     cIdx;\n    int     cLen;\n    int     cNid;\n    int     lIdx;\n    int     lLen;\n    int     lNid;\n    int     stIdx;\n    int     stLen;\n    int     stNid;\n    int     oIdx;\n    int     oLen;\n    int     oNid;\n    int     ouIdx;\n    int     ouLen;\n#ifdef WOLFSSL_CERT_EXT\n    int     bcIdx;\n    int     bcLen;\n    int     jcIdx;\n    int     jcLen;\n    int     jsIdx;\n    int     jsLen;\n#endif\n    int     ouNid;\n    int     emailIdx;\n    int     emailLen;\n    int     emailNid;\n    int     uidIdx;\n    int     uidLen;\n    int     uidNid;\n    int     serialIdx;\n    int     serialLen;\n    int     serialNid;\n    int     dcIdx[DOMAIN_COMPONENT_MAX];\n    int     dcLen[DOMAIN_COMPONENT_MAX];\n    int     dcNum;\n    int     dcMode;\n#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n    /* hold the location / order with which each of the DN tags was found\n     *\n     * example of ASN_DOMAIN_COMPONENT at index 0 if first found and so on.\n     */\n    int     loc[DOMAIN_COMPONENT_MAX + DN_NAMES_MAX];\n    int     locSz;\n#endif\n};\n\nenum SignatureState {\n    SIG_STATE_BEGIN,\n    SIG_STATE_HASH,\n    SIG_STATE_KEY,\n    SIG_STATE_DO,\n    SIG_STATE_CHECK,\n};\n\n\n#ifdef HAVE_PK_CALLBACKS\n#ifdef HAVE_ECC\n    typedef int (*wc_CallbackEccVerify)(\n           const unsigned char* sig, unsigned int sigSz,\n           const unsigned char* hash, unsigned int hashSz,\n           const unsigned char* keyDer, unsigned int keySz,\n           int* result, void* ctx);\n#endif\n#ifndef NO_RSA\n    typedef int (*wc_CallbackRsaVerify)(\n           unsigned char* sig, unsigned int sigSz,\n           unsigned char** out,\n           const unsigned char* keyDer, unsigned int keySz,\n           void* ctx);\n#endif\n#endif /* HAVE_PK_CALLBACKS */\n\nstruct SignatureCtx {\n    void* heap;\n    byte* digest;\n#ifndef NO_RSA\n    byte* out;\n    byte* plain;\n#endif\n#if defined(HAVE_ECC) || defined(HAVE_ED25519)\n    int verify;\n#endif\n    union {\n    #ifndef NO_RSA\n        struct RsaKey*      rsa;\n    #endif\n    #ifdef HAVE_ECC\n        struct ecc_key*     ecc;\n    #endif\n    #ifdef HAVE_ED25519\n        struct ed25519_key* ed25519;\n    #endif\n        void* ptr;\n    } key;\n    int devId;\n    int state;\n    int typeH;\n    int digestSz;\n    word32 keyOID;\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV* asyncDev;\n    void* asyncCtx;\n#endif\n\n#ifdef HAVE_PK_CALLBACKS\n#ifdef HAVE_ECC\n    wc_CallbackEccVerify pkCbEcc;\n    void* pkCtxEcc;\n#endif\n#ifndef NO_RSA\n    wc_CallbackRsaVerify pkCbRsa;\n    void* pkCtxRsa;\n#endif\n#endif /* HAVE_PK_CALLBACKS */\n#ifndef NO_RSA\n#ifdef WOLFSSL_RENESAS_TSIP_TLS\n    byte verifyByTSIP;\n    word32 certBegin;\n    word32 pubkey_n_start;\n    word32 pubkey_n_len;\n    word32 pubkey_e_start;\n    word32 pubkey_e_len;\n#endif\n#endif\n};\n\nenum CertSignState {\n    CERTSIGN_STATE_BEGIN,\n    CERTSIGN_STATE_DIGEST,\n    CERTSIGN_STATE_ENCODE,\n    CERTSIGN_STATE_DO,\n};\n\nstruct CertSignCtx {\n    byte* sig;\n    byte* digest;\n    #ifndef NO_RSA\n        byte* encSig;\n        int encSigSz;\n    #endif\n    int state; /* enum CertSignState */\n};\n\n#ifndef WOLFSSL_MAX_PATH_LEN\n    /* RFC 5280 Section 6.1.2. \"Initialization\" - item (k) defines\n     *     (k)  max_path_length:  this integer is initialized to \"n\", is\n     *     decremented for each non-self-issued certificate in the path,\n     *     and may be reduced to the value in the path length constraint\n     *     field within the basic constraints extension of a CA\n     *     certificate.\n     *\n     * wolfSSL has arbitrarily selected the value 127 for \"n\" in the above\n     * description. Users can modify the maximum path length by setting\n     * WOLFSSL_MAX_PATH_LEN to a preferred value at build time\n     */\n    #define WOLFSSL_MAX_PATH_LEN 127\n#endif\n\ntypedef struct DecodedCert DecodedCert;\ntypedef struct DecodedName DecodedName;\ntypedef struct Signer      Signer;\n#ifdef WOLFSSL_TRUST_PEER_CERT\ntypedef struct TrustedPeerCert TrustedPeerCert;\n#endif /* WOLFSSL_TRUST_PEER_CERT */\ntypedef struct SignatureCtx SignatureCtx;\ntypedef struct CertSignCtx  CertSignCtx;\n\n\nstruct DecodedCert {\n    const byte* publicKey;\n    word32  pubKeySize;\n    int     pubKeyStored;\n    word32  certBegin;               /* offset to start of cert          */\n    word32  sigIndex;                /* offset to start of signature     */\n    word32  sigLength;               /* length of signature              */\n    word32  signatureOID;            /* sum of algorithm object id       */\n    word32  keyOID;                  /* sum of key algo  object id       */\n    int     version;                 /* cert version, 1 or 3             */\n    DNS_entry* altNames;             /* alt names list of dns entries    */\n#ifndef IGNORE_NAME_CONSTRAINTS\n    DNS_entry* altEmailNames;        /* alt names list of RFC822 entries */\n    Base_entry* permittedNames;      /* Permitted name bases             */\n    Base_entry* excludedNames;       /* Excluded name bases              */\n#endif /* IGNORE_NAME_CONSTRAINTS */\n    byte    subjectHash[KEYID_SIZE]; /* hash of all Names                */\n    byte    issuerHash[KEYID_SIZE];  /* hash of all Names                */\n#ifdef HAVE_OCSP\n    byte    subjectKeyHash[KEYID_SIZE]; /* hash of the public Key         */\n    byte    issuerKeyHash[KEYID_SIZE]; /* hash of the public Key         */\n#endif /* HAVE_OCSP */\n    const byte* signature;           /* not owned, points into raw cert  */\n    char*   subjectCN;               /* CommonName                       */\n    int     subjectCNLen;            /* CommonName Length                */\n    char    subjectCNEnc;            /* CommonName Encoding              */\n    char    issuer[ASN_NAME_MAX];    /* full name including common name  */\n    char    subject[ASN_NAME_MAX];   /* full name including common name  */\n    int     verify;                  /* Default to yes, but could be off */\n    const byte* source;              /* byte buffer holder cert, NOT owner */\n    word32  srcIdx;                  /* current offset into buffer       */\n    word32  maxIdx;                  /* max offset based on init size    */\n    void*   heap;                    /* for user memory overrides        */\n    byte    serial[EXTERNAL_SERIAL_SIZE];  /* raw serial number          */\n    int     serialSz;                /* raw serial bytes stored */\n    const byte* extensions;          /* not owned, points into raw cert  */\n    int     extensionsSz;            /* length of cert extensions */\n    word32  extensionsIdx;           /* if want to go back and parse later */\n    const byte* extAuthInfo;         /* Authority Information Access URI */\n    int     extAuthInfoSz;           /* length of the URI                */\n    const byte* extCrlInfo;          /* CRL Distribution Points          */\n    int     extCrlInfoSz;            /* length of the URI                */\n    byte    extSubjKeyId[KEYID_SIZE]; /* Subject Key ID                  */\n    byte    extAuthKeyId[KEYID_SIZE]; /* Authority Key ID                */\n    byte    pathLength;              /* CA basic constraint path length  */\n    byte    maxPathLen;              /* max_path_len see RFC 5280 section\n                                      * 6.1.2 \"Initialization\" - (k) for\n                                      * description of max_path_len */\n    word16  extKeyUsage;             /* Key usage bitfield               */\n    byte    extExtKeyUsage;          /* Extended Key usage bitfield      */\n\n#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n    const byte* extExtKeyUsageSrc;\n    word32  extExtKeyUsageSz;\n    word32  extExtKeyUsageCount;\n    const byte* extAuthKeyIdSrc;\n    word32  extAuthKeyIdSz;\n    const byte* extSubjKeyIdSrc;\n    word32  extSubjKeyIdSz;\n#endif\n\n#if defined(HAVE_ECC) || defined(HAVE_ED25519)\n    word32  pkCurveOID;           /* Public Key's curve OID */\n#endif /* HAVE_ECC */\n    const byte* beforeDate;\n    int     beforeDateLen;\n    const byte* afterDate;\n    int     afterDateLen;\n#if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)\n    const byte* issuerRaw;           /* pointer to issuer inside source */\n    int     issuerRawLen;\n#endif\n#if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)\n    const byte* subjectRaw;          /* pointer to subject inside source */\n    int     subjectRawLen;\n#endif\n#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)\n    /* easy access to subject info for other sign */\n    char*   subjectSN;\n    int     subjectSNLen;\n    char    subjectSNEnc;\n    char*   subjectC;\n    int     subjectCLen;\n    char    subjectCEnc;\n    char*   subjectL;\n    int     subjectLLen;\n    char    subjectLEnc;\n    char*   subjectST;\n    int     subjectSTLen;\n    char    subjectSTEnc;\n    char*   subjectO;\n    int     subjectOLen;\n    char    subjectOEnc;\n    char*   subjectOU;\n    int     subjectOULen;\n    char    subjectOUEnc;\n    char*   subjectSND;\n    int     subjectSNDLen;\n    char    subjectSNDEnc;\n#ifdef WOLFSSL_CERT_EXT\n    char*   subjectBC;\n    int     subjectBCLen;\n    char    subjectBCEnc;\n    char*   subjectJC;\n    int     subjectJCLen;\n    char    subjectJCEnc;\n    char*   subjectJS;\n    int     subjectJSLen;\n    char    subjectJSEnc;\n#endif\n    char*   subjectEmail;\n    int     subjectEmailLen;\n#endif /* WOLFSSL_CERT_GEN */\n#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n    DecodedName issuerName;\n    DecodedName subjectName;\n#endif /* OPENSSL_EXTRA */\n#ifdef WOLFSSL_SEP\n    int     deviceTypeSz;\n    byte*   deviceType;\n    int     hwTypeSz;\n    byte*   hwType;\n    int     hwSerialNumSz;\n    byte*   hwSerialNum;\n#endif /* WOLFSSL_SEP */\n#ifdef WOLFSSL_CERT_EXT\n    char    extCertPolicies[MAX_CERTPOL_NB][MAX_CERTPOL_SZ];\n    int     extCertPoliciesNb;\n#endif /* defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) */\n\n    Signer* ca;\n#ifndef NO_CERTS\n    SignatureCtx sigCtx;\n#endif\n#ifdef WOLFSSL_RENESAS_TSIP\n    byte*  tsip_encRsaKeyIdx;\n#endif\n\n    int badDate;\n    int criticalExt;\n\n    /* Option Bits */\n    byte subjectCNStored : 1;      /* have we saved a copy we own */\n    byte extSubjKeyIdSet : 1;      /* Set when the SKID was read from cert */\n    byte extAuthKeyIdSet : 1;      /* Set when the AKID was read from cert */\n#ifndef IGNORE_NAME_CONSTRAINTS\n    byte extNameConstraintSet : 1;\n#endif\n    byte isCA : 1;                 /* CA basic constraint true */\n    byte pathLengthSet : 1;        /* CA basic const path length set */\n    byte weOwnAltNames : 1;        /* altNames haven't been given to copy */\n    byte extKeyUsageSet : 1;\n    byte extExtKeyUsageSet : 1;    /* Extended Key Usage set */\n    byte extCRLdistSet : 1;\n    byte extAuthInfoSet : 1;\n    byte extBasicConstSet : 1;\n    byte extSubjAltNameSet : 1;\n    byte inhibitAnyOidSet : 1;\n    byte selfSigned : 1;           /* Indicates subject and issuer are same */\n#ifdef WOLFSSL_SEP\n    byte extCertPolicySet : 1;\n#endif\n#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)\n    byte extCRLdistCrit : 1;\n    byte extAuthInfoCrit : 1;\n    byte extBasicConstCrit : 1;\n    byte extSubjAltNameCrit : 1;\n    byte extAuthKeyIdCrit : 1;\n    #ifndef IGNORE_NAME_CONSTRAINTS\n        byte extNameConstraintCrit : 1;\n    #endif\n    byte extSubjKeyIdCrit : 1;\n    byte extKeyUsageCrit : 1;\n    byte extExtKeyUsageCrit : 1;\n#endif /* OPENSSL_EXTRA */\n#ifdef WOLFSSL_SEP\n    byte extCertPolicyCrit : 1;\n#endif\n\n};\n\n\n#ifdef NO_SHA\n    #define SIGNER_DIGEST_SIZE WC_SHA256_DIGEST_SIZE\n#else\n    #define SIGNER_DIGEST_SIZE WC_SHA_DIGEST_SIZE\n#endif\n\n/* CA Signers */\n/* if change layout change PERSIST_CERT_CACHE functions too */\nstruct Signer {\n    word32  pubKeySize;\n    word32  keyOID;                  /* key type */\n    word16  keyUsage;\n    byte    maxPathLen;\n    byte    pathLength;\n    byte    pathLengthSet : 1;\n    byte    selfSigned : 1;\n    const byte* publicKey;\n    int     nameLen;\n    char*   name;                    /* common name */\n#ifndef IGNORE_NAME_CONSTRAINTS\n        Base_entry* permittedNames;\n        Base_entry* excludedNames;\n#endif /* IGNORE_NAME_CONSTRAINTS */\n    byte    subjectNameHash[SIGNER_DIGEST_SIZE];\n                                     /* sha hash of names in certificate */\n    #ifndef NO_SKID\n        byte    subjectKeyIdHash[SIGNER_DIGEST_SIZE];\n                                     /* sha hash of names in certificate */\n    #endif\n    #ifdef HAVE_OCSP\n        byte subjectKeyHash[KEYID_SIZE];\n    #endif\n#ifdef WOLFSSL_SIGNER_DER_CERT\n    DerBuffer* derCert;\n#endif\n#ifdef WOLFSSL_RENESAS_TSIP_TLS\n    word32 cm_idx;\n#endif\n    Signer* next;\n};\n\n\n#ifdef WOLFSSL_TRUST_PEER_CERT\n/* used for having trusted peer certs rather then CA */\nstruct TrustedPeerCert {\n    int     nameLen;\n    char*   name;                    /* common name */\n    #ifndef IGNORE_NAME_CONSTRAINTS\n        Base_entry* permittedNames;\n        Base_entry* excludedNames;\n    #endif /* IGNORE_NAME_CONSTRAINTS */\n    byte    subjectNameHash[SIGNER_DIGEST_SIZE];\n                                     /* sha hash of names in certificate */\n    #ifndef NO_SKID\n        byte    subjectKeyIdHash[SIGNER_DIGEST_SIZE];\n                                     /* sha hash of names in certificate */\n    #endif\n    word32 sigLen;\n    byte*  sig;\n    struct TrustedPeerCert* next;\n};\n#endif /* WOLFSSL_TRUST_PEER_CERT */\n\n\n/* for testing or custom openssl wrappers */\n#if defined(WOLFSSL_TEST_CERT) || defined(OPENSSL_EXTRA) || \\\n    defined(OPENSSL_EXTRA_X509_SMALL)\n    #define WOLFSSL_ASN_API WOLFSSL_API\n#else\n    #define WOLFSSL_ASN_API WOLFSSL_LOCAL\n#endif\n\nWOLFSSL_LOCAL int CalcHashId(const byte* data, word32 len, byte* hash);\n\nWOLFSSL_ASN_API int wc_BerToDer(const byte* ber, word32 berSz, byte* der,\n                                word32* derSz);\n\nWOLFSSL_ASN_API void FreeAltNames(DNS_entry*, void*);\n#ifndef IGNORE_NAME_CONSTRAINTS\n    WOLFSSL_ASN_API void FreeNameSubtrees(Base_entry*, void*);\n#endif /* IGNORE_NAME_CONSTRAINTS */\nWOLFSSL_ASN_API void InitDecodedCert(DecodedCert*, const byte*, word32, void*);\nWOLFSSL_ASN_API void FreeDecodedCert(DecodedCert*);\nWOLFSSL_ASN_API int  ParseCert(DecodedCert*, int type, int verify, void* cm);\n\nWOLFSSL_LOCAL int DecodePolicyOID(char *o, word32 oSz,\n                                  const byte *in, word32 inSz);\nWOLFSSL_LOCAL int EncodePolicyOID(byte *out, word32 *outSz,\n                                  const char *in, void* heap);\nWOLFSSL_API int CheckCertSignature(const byte*,word32,void*,void* cm);\nWOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz,\n        void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID);\nWOLFSSL_LOCAL int ParseCertRelative(DecodedCert*,int type,int verify,void* cm);\nWOLFSSL_LOCAL int DecodeToKey(DecodedCert*, int verify);\nWOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate);\n\nWOLFSSL_LOCAL const byte* OidFromId(word32 id, word32 type, word32* oidSz);\nWOLFSSL_LOCAL Signer* MakeSigner(void*);\nWOLFSSL_LOCAL void    FreeSigner(Signer*, void*);\nWOLFSSL_LOCAL void    FreeSignerTable(Signer**, int, void*);\n#ifdef WOLFSSL_TRUST_PEER_CERT\nWOLFSSL_LOCAL void    FreeTrustedPeer(TrustedPeerCert*, void*);\nWOLFSSL_LOCAL void    FreeTrustedPeerTable(TrustedPeerCert**, int, void*);\n#endif /* WOLFSSL_TRUST_PEER_CERT */\n\nWOLFSSL_ASN_API int ToTraditional(byte* buffer, word32 length);\nWOLFSSL_ASN_API int ToTraditional_ex(byte* buffer, word32 length,\n                                     word32* algId);\nWOLFSSL_LOCAL int ToTraditionalInline(const byte* input, word32* inOutIdx,\n                                      word32 length);\nWOLFSSL_LOCAL int ToTraditionalInline_ex(const byte* input, word32* inOutIdx,\n                                         word32 length, word32* algId);\nWOLFSSL_LOCAL int ToTraditionalEnc(byte* buffer, word32 length,const char*,int,\n                                   word32* algId);\nWOLFSSL_ASN_API int UnTraditionalEnc(byte* key, word32 keySz, byte* out,\n        word32* outSz, const char* password, int passwordSz, int vPKCS,\n        int vAlgo, byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap);\nWOLFSSL_ASN_API int TraditionalEnc(byte* key, word32 keySz, byte* out,\n        word32* outSz, const char* password, int passwordSz, int vPKCS,\n        int vAlgo, int encAlgId, byte* salt, word32 saltSz, int itt,\n        WC_RNG* rng, void* heap);\nWOLFSSL_LOCAL int DecryptContent(byte* input, word32 sz,const char* psw,int pswSz);\nWOLFSSL_LOCAL int EncryptContent(byte* input, word32 sz, byte* out, word32* outSz,\n        const char* password,int passwordSz, int vPKCS, int vAlgo,\n        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap);\nWOLFSSL_LOCAL int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID,\n        word32* oidSz, int* algoID, void* heap);\n\ntypedef struct tm wolfssl_tm;\n#if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA) || \\\n    defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)\nWOLFSSL_LOCAL int GetTimeString(byte* date, int format, char* buf, int len);\n#endif\n#if !defined(NO_ASN_TIME) && defined(HAVE_PKCS7)\nWOLFSSL_LOCAL int GetAsnTimeString(void* currTime, byte* buf, word32 len);\n#endif\nWOLFSSL_LOCAL int ExtractDate(const unsigned char* date, unsigned char format,\n                                                 wolfssl_tm* certTime, int* idx);\nWOLFSSL_LOCAL int DateGreaterThan(const struct tm* a, const struct tm* b);\nWOLFSSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType);\nWOLFSSL_LOCAL int wc_OBJ_sn2nid(const char *sn);\n\n/* ASN.1 helper functions */\n#ifdef WOLFSSL_CERT_GEN\nWOLFSSL_ASN_API int SetName(byte* output, word32 outputSz, CertName* name);\n#endif\nWOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number,\n                              word32 maxIdx);\nWOLFSSL_LOCAL int SetShortInt(byte* input, word32* inOutIdx, word32 number,\n                              word32 maxIdx);\n\nWOLFSSL_LOCAL char* GetSigName(int oid);\nWOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,\n                           word32 maxIdx);\nWOLFSSL_LOCAL int GetLength_ex(const byte* input, word32* inOutIdx, int* len,\n                           word32 maxIdx, int check);\nWOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,\n                             word32 maxIdx);\nWOLFSSL_LOCAL int GetSequence_ex(const byte* input, word32* inOutIdx, int* len,\n                           word32 maxIdx, int check);\nWOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,\n                        word32 maxIdx);\nWOLFSSL_LOCAL int GetSet_ex(const byte* input, word32* inOutIdx, int* len,\n                        word32 maxIdx, int check);\nWOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,\n                              int* version, word32 maxIdx);\nWOLFSSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx,\n                        word32 maxIdx);\n#ifdef HAVE_OID_ENCODING\n    WOLFSSL_LOCAL int EncodeObjectId(const word16* in, word32 inSz,\n        byte* out, word32* outSz);\n#endif\n#ifdef HAVE_OID_DECODING\n    WOLFSSL_LOCAL int DecodeObjectId(const byte* in, word32 inSz,\n        word16* out, word32* outSz);\n#endif\nWOLFSSL_LOCAL int GetASNObjectId(const byte* input, word32* inOutIdx, int* len,\n                                 word32 maxIdx);\nWOLFSSL_LOCAL int SetObjectId(int len, byte* output);\nWOLFSSL_LOCAL int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,\n                              word32 oidType, word32 maxIdx);\nWOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,\n                           word32 oidType, word32 maxIdx);\nWOLFSSL_LOCAL int GetASNTag(const byte* input, word32* idx, byte* tag,\n                            word32 inputSz);\nWOLFSSL_LOCAL word32 SetLength(word32 length, byte* output);\nWOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output);\nWOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output);\nWOLFSSL_LOCAL word32 SetImplicit(byte tag,byte number,word32 len,byte* output);\nWOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output);\nWOLFSSL_LOCAL word32 SetSet(word32 len, byte* output);\nWOLFSSL_LOCAL word32 SetAlgoID(int algoOID,byte* output,int type,int curveSz);\nWOLFSSL_LOCAL int SetMyVersion(word32 version, byte* output, int header);\nWOLFSSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output,\n    word32 outputSz, int maxSnSz);\nWOLFSSL_LOCAL int GetSerialNumber(const byte* input, word32* inOutIdx,\n    byte* serial, int* serialSz, word32 maxIdx);\nWOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,\n                             int maxIdx);\nWOLFSSL_LOCAL int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der);\n\n#ifdef HAVE_ECC\n    /* ASN sig helpers */\n    WOLFSSL_LOCAL int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r,\n                                      mp_int* s);\n    WOLFSSL_LOCAL int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen,\n                                       mp_int* r, mp_int* s);\n#endif\n\nWOLFSSL_LOCAL void InitSignatureCtx(SignatureCtx* sigCtx, void* heap, int devId);\nWOLFSSL_LOCAL void FreeSignatureCtx(SignatureCtx* sigCtx);\n\n#ifndef NO_CERTS\n\nWOLFSSL_LOCAL int wc_EncryptedInfoParse(EncryptedInfo* info, char** pBuffer,\n                                        size_t bufSz);\n\nWOLFSSL_LOCAL int PemToDer(const unsigned char* buff, long sz, int type,\n                          DerBuffer** pDer, void* heap, EncryptedInfo* info,\n                          int* eccKey);\nWOLFSSL_LOCAL int AllocDer(DerBuffer** der, word32 length, int type, void* heap);\nWOLFSSL_LOCAL void FreeDer(DerBuffer** der);\n\n#endif /* !NO_CERTS */\n\n#ifdef WOLFSSL_CERT_GEN\n\nenum cert_enums {\n#ifdef WOLFSSL_CERT_EXT\n    NAME_ENTRIES    =  10,\n#else\n    NAME_ENTRIES    =  9,\n#endif\n    JOINT_LEN       =  2,\n    EMAIL_JOINT_LEN =  9,\n    PILOT_JOINT_LEN =  10,\n    RSA_KEY         = 10,\n    NTRU_KEY        = 11,\n    ECC_KEY         = 12,\n    ED25519_KEY     = 13\n};\n\n#endif /* WOLFSSL_CERT_GEN */\n\n\n\n/* for pointer use */\ntypedef struct CertStatus CertStatus;\n\n#ifdef HAVE_OCSP\n\nenum Ocsp_Response_Status {\n    OCSP_SUCCESSFUL        = 0, /* Response has valid confirmations */\n    OCSP_MALFORMED_REQUEST = 1, /* Illegal confirmation request */\n    OCSP_INTERNAL_ERROR    = 2, /* Internal error in issuer */\n    OCSP_TRY_LATER         = 3, /* Try again later */\n    OCSP_SIG_REQUIRED      = 5, /* Must sign the request (4 is skipped) */\n    OCSP_UNAUTHROIZED      = 6  /* Request unauthorized */\n};\n\n\nenum Ocsp_Cert_Status {\n    CERT_GOOD    = 0,\n    CERT_REVOKED = 1,\n    CERT_UNKNOWN = 2\n};\n\n\nenum Ocsp_Sums {\n    OCSP_BASIC_OID = 117,\n    OCSP_NONCE_OID = 118\n};\n\n#ifdef OPENSSL_EXTRA\nenum Ocsp_Verify_Error {\n    OCSP_VERIFY_ERROR_NONE = 0,\n    OCSP_BAD_ISSUER = 1\n};\n#endif\n\n\ntypedef struct OcspRequest  OcspRequest;\ntypedef struct OcspResponse OcspResponse;\n\n\nstruct CertStatus {\n    CertStatus* next;\n\n    byte serial[EXTERNAL_SERIAL_SIZE];\n    int serialSz;\n\n    int status;\n\n    byte thisDate[MAX_DATE_SIZE];\n    byte nextDate[MAX_DATE_SIZE];\n    byte thisDateFormat;\n    byte nextDateFormat;\n#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)\n    WOLFSSL_ASN1_TIME thisDateParsed;\n    WOLFSSL_ASN1_TIME nextDateParsed;\n    byte* thisDateAsn;\n    byte* nextDateAsn;\n#endif\n\n    byte*  rawOcspResponse;\n    word32 rawOcspResponseSz;\n};\n\n\nstruct OcspResponse {\n    int     responseStatus;  /* return code from Responder */\n\n    byte*   response;        /* Pointer to beginning of OCSP Response */\n    word32  responseSz;      /* length of the OCSP Response */\n\n    byte    producedDate[MAX_DATE_SIZE];\n                             /* Date at which this response was signed */\n    byte    producedDateFormat; /* format of the producedDate */\n    byte*   issuerHash;\n    byte*   issuerKeyHash;\n\n    byte*   cert;\n    word32  certSz;\n\n    byte*   sig;             /* Pointer to sig in source */\n    word32  sigSz;           /* Length in octets for the sig */\n    word32  sigOID;          /* OID for hash used for sig */\n\n    CertStatus* status;      /* certificate status to fill out */\n\n    byte*   nonce;           /* pointer to nonce inside ASN.1 response */\n    int     nonceSz;         /* length of the nonce string */\n\n    byte*   source;          /* pointer to source buffer, not owned */\n    word32  maxIdx;          /* max offset based on init size */\n\n#ifdef OPENSSL_EXTRA\n    int     verifyError;\n#endif\n};\n\n\nstruct OcspRequest {\n    byte   issuerHash[KEYID_SIZE];\n    byte   issuerKeyHash[KEYID_SIZE];\n    byte*  serial;   /* copy of the serial number in source cert */\n    int    serialSz;\n#ifdef OPENSSL_EXTRA\n    WOLFSSL_ASN1_INTEGER* serialInt;\n#endif\n    byte*  url;      /* copy of the extAuthInfo in source cert */\n    int    urlSz;\n\n    byte   nonce[MAX_OCSP_NONCE_SZ];\n    int    nonceSz;\n    void*  heap;\n    void*  ssl;\n};\n\ntypedef struct OcspEntry OcspEntry;\n\n#ifdef NO_SHA\n#define OCSP_DIGEST_SIZE WC_SHA256_DIGEST_SIZE\n#else\n#define OCSP_DIGEST_SIZE WC_SHA_DIGEST_SIZE\n#endif\n\nstruct OcspEntry\n{\n    OcspEntry *next;                      /* next entry             */\n    byte issuerHash[OCSP_DIGEST_SIZE];    /* issuer hash            */\n    byte issuerKeyHash[OCSP_DIGEST_SIZE]; /* issuer public key hash */\n    CertStatus *status;                   /* OCSP response list     */\n    int totalStatus;                      /* number on list         */\n};\n\nWOLFSSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32);\nWOLFSSL_LOCAL int  OcspResponseDecode(OcspResponse*, void*, void* heap, int);\n\nWOLFSSL_LOCAL int    InitOcspRequest(OcspRequest*, DecodedCert*, byte, void*);\nWOLFSSL_LOCAL void   FreeOcspRequest(OcspRequest*);\nWOLFSSL_LOCAL int    EncodeOcspRequest(OcspRequest*, byte*, word32);\nWOLFSSL_LOCAL word32 EncodeOcspRequestExtensions(OcspRequest*, byte*, word32);\n\n\nWOLFSSL_LOCAL int  CompareOcspReqResp(OcspRequest*, OcspResponse*);\n\n\n#endif /* HAVE_OCSP */\n\n\n/* for pointer use */\ntypedef struct RevokedCert RevokedCert;\n\n#ifdef HAVE_CRL\n\nstruct RevokedCert {\n    byte         serialNumber[EXTERNAL_SERIAL_SIZE];\n    int          serialSz;\n    RevokedCert* next;\n};\n\ntypedef struct DecodedCRL DecodedCRL;\n\nstruct DecodedCRL {\n    word32  certBegin;               /* offset to start of cert          */\n    word32  sigIndex;                /* offset to start of signature     */\n    word32  sigLength;               /* length of signature              */\n    word32  signatureOID;            /* sum of algorithm object id       */\n    byte*   signature;               /* pointer into raw source, not owned */\n    byte    issuerHash[SIGNER_DIGEST_SIZE]; /* issuer name hash          */\n    byte    crlHash[SIGNER_DIGEST_SIZE]; /* raw crl data hash            */\n    byte    lastDate[MAX_DATE_SIZE]; /* last date updated  */\n    byte    nextDate[MAX_DATE_SIZE]; /* next update date   */\n    byte    lastDateFormat;          /* format of last date */\n    byte    nextDateFormat;          /* format of next date */\n    RevokedCert* certs;              /* revoked cert list  */\n    int          totalCerts;         /* number on list     */\n    void*   heap;\n#ifndef NO_SKID\n    byte    extAuthKeyIdSet;\n    byte    extAuthKeyId[SIGNER_DIGEST_SIZE]; /* Authority Key ID        */\n#endif\n};\n\nWOLFSSL_LOCAL void InitDecodedCRL(DecodedCRL*, void* heap);\nWOLFSSL_LOCAL int VerifyCRL_Signature(SignatureCtx* sigCtx,\n                                      const byte* toBeSigned, word32 tbsSz,\n                                      const byte* signature, word32 sigSz,\n                                      word32 signatureOID, Signer *ca,\n                                      void* heap);\nWOLFSSL_LOCAL int  ParseCRL(DecodedCRL*, const byte* buff, word32 sz, void* cm);\nWOLFSSL_LOCAL void FreeDecodedCRL(DecodedCRL*);\n\n\n#endif /* HAVE_CRL */\n\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* !NO_ASN */\n\n\n#if !defined(NO_ASN) || !defined(NO_PWDBASED)\n\n#ifndef MAX_KEY_SIZE\n    #define MAX_KEY_SIZE    64  /* MAX PKCS Key length */\n#endif\n#ifndef MAX_UNICODE_SZ\n    #define MAX_UNICODE_SZ  256\n#endif\n\nenum PBESTypes {\n    PBE_MD5_DES      = 0,\n    PBE_SHA1_RC4_128 = 1,\n    PBE_SHA1_DES     = 2,\n    PBE_SHA1_DES3    = 3,\n    PBE_AES256_CBC   = 4,\n\n    PBE_SHA1_RC4_128_SUM = 657,\n    PBE_SHA1_DES3_SUM    = 659,\n    PBES2            = 13       /* algo ID */\n};\n\nenum PKCSTypes {\n    PKCS5v2             =   6,     /* PKCS #5 v2.0 */\n    PKCS12v1            =  12,     /* PKCS #12 */\n    PKCS5               =   5,     /* PKCS oid tag */\n    PKCS8v0             =   0,     /* default PKCS#8 version */\n};\n\n#endif /* !NO_ASN || !NO_PWDBASED */\n\n#endif /* WOLF_CRYPT_ASN_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/asn_public.h",
    "content": "/* asn_public.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/asn_public.h\n*/\n\n#ifndef WOLF_CRYPT_ASN_PUBLIC_H\n#define WOLF_CRYPT_ASN_PUBLIC_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* guard on redeclaration */\n#ifndef WC_ECCKEY_TYPE_DEFINED\n    typedef struct ecc_key ecc_key;\n    #define WC_ECCKEY_TYPE_DEFINED\n#endif\n#ifndef WC_ED25519KEY_TYPE_DEFINED\n    typedef struct ed25519_key ed25519_key;\n    #define WC_ED25519KEY_TYPE_DEFINED\n#endif\n#ifndef WC_RSAKEY_TYPE_DEFINED\n    typedef struct RsaKey RsaKey;\n    #define WC_RSAKEY_TYPE_DEFINED\n#endif\n#ifndef WC_RNG_TYPE_DEFINED\n    typedef struct WC_RNG WC_RNG;\n    #define WC_RNG_TYPE_DEFINED\n#endif\n\nenum Ecc_Sum {\n    ECC_SECP112R1_OID = 182,\n    ECC_SECP112R2_OID = 183,\n    ECC_SECP128R1_OID = 204,\n    ECC_SECP128R2_OID = 205,\n    ECC_SECP160R1_OID = 184,\n    ECC_SECP160R2_OID = 206,\n    ECC_SECP160K1_OID = 185,\n    ECC_BRAINPOOLP160R1_OID = 98,\n    ECC_SECP192R1_OID = 520,\n    ECC_PRIME192V2_OID = 521,\n    ECC_PRIME192V3_OID = 522,\n    ECC_SECP192K1_OID = 207,\n    ECC_BRAINPOOLP192R1_OID = 100,\n    ECC_SECP224R1_OID = 209,\n    ECC_SECP224K1_OID = 208,\n    ECC_BRAINPOOLP224R1_OID = 102,\n    ECC_PRIME239V1_OID = 523,\n    ECC_PRIME239V2_OID = 524,\n    ECC_PRIME239V3_OID = 525,\n    ECC_SECP256R1_OID = 526,\n    ECC_SECP256K1_OID = 186,\n    ECC_BRAINPOOLP256R1_OID = 104,\n    ECC_X25519_OID = 365,\n    ECC_ED25519_OID = 256,\n    ECC_BRAINPOOLP320R1_OID = 106,\n    ECC_SECP384R1_OID = 210,\n    ECC_BRAINPOOLP384R1_OID = 108,\n    ECC_BRAINPOOLP512R1_OID = 110,\n    ECC_SECP521R1_OID = 211,\n};\n\n\n/* Certificate file Type */\nenum CertType {\n    CERT_TYPE       = 0,\n    PRIVATEKEY_TYPE,\n    DH_PARAM_TYPE,\n    DSA_PARAM_TYPE,\n    CRL_TYPE,\n    CA_TYPE,\n    ECC_PRIVATEKEY_TYPE,\n    DSA_PRIVATEKEY_TYPE,\n    CERTREQ_TYPE,\n    DSA_TYPE,\n    ECC_TYPE,\n    RSA_TYPE,\n    PUBLICKEY_TYPE,\n    RSA_PUBLICKEY_TYPE,\n    ECC_PUBLICKEY_TYPE,\n    TRUSTED_PEER_TYPE,\n    EDDSA_PRIVATEKEY_TYPE,\n    ED25519_TYPE,\n    PKCS12_TYPE,\n    PKCS8_PRIVATEKEY_TYPE,\n    PKCS8_ENC_PRIVATEKEY_TYPE,\n    DETECT_CERT_TYPE,\n    DH_PRIVATEKEY_TYPE,\n};\n\n\n/* Signature type, by OID sum */\nenum Ctc_SigType {\n    CTC_SHAwDSA      = 517,\n    CTC_MD2wRSA      = 646,\n    CTC_MD5wRSA      = 648,\n    CTC_SHAwRSA      = 649,\n    CTC_SHAwECDSA    = 520,\n    CTC_SHA224wRSA   = 658,\n    CTC_SHA224wECDSA = 523,\n    CTC_SHA256wRSA   = 655,\n    CTC_SHA256wECDSA = 524,\n    CTC_SHA384wRSA   = 656,\n    CTC_SHA384wECDSA = 525,\n    CTC_SHA512wRSA   = 657,\n    CTC_SHA512wECDSA = 526,\n    CTC_ED25519      = 256\n};\n\nenum Ctc_Encoding {\n    CTC_UTF8       = 0x0c, /* utf8      */\n    CTC_PRINTABLE  = 0x13  /* printable */\n};\n\n#ifndef WC_CTC_NAME_SIZE\n    #define WC_CTC_NAME_SIZE 64\n#endif\n#ifndef WC_CTC_MAX_ALT_SIZE\n    #define WC_CTC_MAX_ALT_SIZE 16384\n#endif\n\nenum Ctc_Misc {\n    CTC_COUNTRY_SIZE  =     2,\n    CTC_NAME_SIZE     = WC_CTC_NAME_SIZE,\n    CTC_DATE_SIZE     =    32,\n    CTC_MAX_ALT_SIZE  = WC_CTC_MAX_ALT_SIZE, /* may be huge, default: 16384 */\n    CTC_SERIAL_SIZE   =    20,\n    CTC_GEN_SERIAL_SZ =    16,\n#ifdef WOLFSSL_CERT_EXT\n    /* AKID could contains: hash + (Option) AuthCertIssuer,AuthCertSerialNum\n     * We support only hash */\n    CTC_MAX_SKID_SIZE = 32, /* SHA256_DIGEST_SIZE */\n    CTC_MAX_AKID_SIZE = 32, /* SHA256_DIGEST_SIZE */\n    CTC_MAX_CERTPOL_SZ = 64,\n    CTC_MAX_CERTPOL_NB = 2 /* Max number of Certificate Policy */\n#endif /* WOLFSSL_CERT_EXT */\n};\n\n/* DER buffer */\ntypedef struct DerBuffer {\n    byte*  buffer;\n    void*  heap;\n    word32 length;\n    int    type;    /* enum CertType */\n    int    dynType; /* DYNAMIC_TYPE_* */\n} DerBuffer;\n\ntypedef struct WOLFSSL_ASN1_TIME {\n    unsigned char data[CTC_DATE_SIZE]; /* date bytes */\n    int length;\n    int type;\n} WOLFSSL_ASN1_TIME;\n\nenum {\n    IV_SZ   = 32,                   /* max iv sz */\n    NAME_SZ = 80,                   /* max one line */\n\n    PEM_PASS_READ  = 0,\n    PEM_PASS_WRITE = 1,\n};\n\n\ntypedef int (pem_password_cb)(char* passwd, int sz, int rw, void* userdata);\n\ntypedef struct EncryptedInfo {\n    pem_password_cb* passwd_cb;\n    void*            passwd_userdata;\n\n    long     consumed;         /* tracks PEM bytes consumed */\n\n    int      cipherType;\n    word32   keySz;\n    word32   ivSz;             /* salt or encrypted IV size */\n\n    char     name[NAME_SZ];    /* cipher name, such as \"DES-CBC\" */\n    byte     iv[IV_SZ];        /* salt or encrypted IV */\n\n    word16   set:1;            /* if encryption set */\n} EncryptedInfo;\n\n\n#define WOLFSSL_ASN1_INTEGER_MAX 20\ntypedef struct WOLFSSL_ASN1_INTEGER {\n    /* size can be increased set at 20 for tag, length then to hold at least 16\n     * byte type */\n    unsigned char  intData[WOLFSSL_ASN1_INTEGER_MAX];\n    /* ASN_INTEGER | LENGTH | hex of number */\n    unsigned char  negative;   /* negative number flag */\n\n    unsigned char* data;\n    unsigned int   dataMax;   /* max size of data buffer */\n    unsigned int   isDynamic:1; /* flag for if data pointer dynamic (1 is yes 0 is no) */\n\n    int length;\n    int type;\n} WOLFSSL_ASN1_INTEGER;\n\n\n#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)\n#ifdef WOLFSSL_EKU_OID\n    #ifndef CTC_MAX_EKU_NB\n        #define CTC_MAX_EKU_NB 1\n    #endif\n    #ifndef CTC_MAX_EKU_OID_SZ\n        #define CTC_MAX_EKU_OID_SZ 30\n    #endif\n#else\n    #undef CTC_MAX_EKU_OID_SZ\n    #define CTC_MAX_EKU_OID_SZ 0\n#endif\n#endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */\n\n#ifdef WOLFSSL_CERT_GEN\n\n#ifdef WOLFSSL_MULTI_ATTRIB\n#ifndef CTC_MAX_ATTRIB\n    #define CTC_MAX_ATTRIB 4\n#endif\n\n/* ASN Encoded Name field */\ntypedef struct NameAttrib {\n    int  sz;                     /* actual string value length */\n    int  id;                     /* id of name */\n    int  type;                   /* enc of name */\n    char value[CTC_NAME_SIZE];   /* name */\n} NameAttrib;\n#endif /* WOLFSSL_MULTI_ATTRIB */\n\n\ntypedef struct CertName {\n    char country[CTC_NAME_SIZE];\n    char countryEnc;\n    char state[CTC_NAME_SIZE];\n    char stateEnc;\n    char locality[CTC_NAME_SIZE];\n    char localityEnc;\n    char sur[CTC_NAME_SIZE];\n    char surEnc;\n    char org[CTC_NAME_SIZE];\n    char orgEnc;\n    char unit[CTC_NAME_SIZE];\n    char unitEnc;\n    char commonName[CTC_NAME_SIZE];\n    char commonNameEnc;\n    char serialDev[CTC_NAME_SIZE];\n    char serialDevEnc;\n#ifdef WOLFSSL_CERT_EXT\n    char busCat[CTC_NAME_SIZE];\n    char busCatEnc;\n    char joiC[CTC_NAME_SIZE];\n    char joiCEnc;\n    char joiSt[CTC_NAME_SIZE];\n    char joiStEnc;\n#endif\n    char email[CTC_NAME_SIZE];  /* !!!! email has to be last !!!! */\n#ifdef WOLFSSL_MULTI_ATTRIB\n    NameAttrib name[CTC_MAX_ATTRIB];\n#endif\n} CertName;\n\n\n/* for user to fill for certificate generation */\ntypedef struct Cert {\n    int      version;                   /* x509 version  */\n    byte     serial[CTC_SERIAL_SIZE];   /* serial number */\n    int      serialSz;                  /* serial size */\n    int      sigType;                   /* signature algo type */\n    CertName issuer;                    /* issuer info */\n    int      daysValid;                 /* validity days */\n    int      selfSigned;                /* self signed flag */\n    CertName subject;                   /* subject info */\n    int      isCA;                      /* is this going to be a CA */\n    /* internal use only */\n    int      bodySz;                    /* pre sign total size */\n    int      keyType;                   /* public key type of subject */\n#ifdef WOLFSSL_ALT_NAMES\n    byte     altNames[CTC_MAX_ALT_SIZE]; /* altNames copy */\n    int      altNamesSz;                 /* altNames size in bytes */\n    byte     beforeDate[CTC_DATE_SIZE];  /* before date copy */\n    int      beforeDateSz;               /* size of copy */\n    byte     afterDate[CTC_DATE_SIZE];   /* after date copy */\n    int      afterDateSz;                /* size of copy */\n#endif\n#ifdef WOLFSSL_CERT_EXT\n    byte    skid[CTC_MAX_SKID_SIZE];     /* Subject Key Identifier */\n    int     skidSz;                      /* SKID size in bytes */\n    byte    akid[CTC_MAX_AKID_SIZE];     /* Authority Key Identifier */\n    int     akidSz;                      /* AKID size in bytes */\n    word16  keyUsage;                    /* Key Usage */\n    byte    extKeyUsage;                 /* Extended Key Usage */\n#ifdef WOLFSSL_EKU_OID\n    /* Extended Key Usage OIDs */\n    byte    extKeyUsageOID[CTC_MAX_EKU_NB][CTC_MAX_EKU_OID_SZ];\n    byte    extKeyUsageOIDSz[CTC_MAX_EKU_NB];\n#endif\n    char    certPolicies[CTC_MAX_CERTPOL_NB][CTC_MAX_CERTPOL_SZ];\n    word16  certPoliciesNb;              /* Number of Cert Policy */\n    byte     issRaw[sizeof(CertName)];   /* raw issuer info */\n    byte     sbjRaw[sizeof(CertName)];   /* raw subject info */\n#endif\n#ifdef WOLFSSL_CERT_REQ\n    char     challengePw[CTC_NAME_SIZE];\n    int      challengePwPrintableString; /* encode as PrintableString */\n#endif\n    void*   decodedCert;    /* internal DecodedCert allocated from heap */\n    byte*   der;            /* Pointer to buffer of current DecodedCert cache */\n    void*   heap;           /* heap hint */\n} Cert;\n\n\n/* Initialize and Set Certificate defaults:\n   version    = 3 (0x2)\n   serial     = 0 (Will be randomly generated)\n   sigType    = SHA_WITH_RSA\n   issuer     = blank\n   daysValid  = 500\n   selfSigned = 1 (true) use subject as issuer\n   subject    = blank\n   isCA       = 0 (false)\n   keyType    = RSA_KEY (default)\n*/\nWOLFSSL_API int wc_InitCert(Cert*);\nWOLFSSL_API int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz,\n                                int keyType, void* key, WC_RNG* rng);\nWOLFSSL_API int wc_MakeCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*,\n                             ecc_key*, WC_RNG*);\n#ifdef WOLFSSL_CERT_REQ\n    WOLFSSL_API int wc_MakeCertReq_ex(Cert*, byte* derBuffer, word32 derSz,\n                                       int, void*);\n    WOLFSSL_API int wc_MakeCertReq(Cert*, byte* derBuffer, word32 derSz,\n                                    RsaKey*, ecc_key*);\n#endif\nWOLFSSL_API int wc_SignCert_ex(int requestSz, int sType, byte* buffer,\n                                word32 buffSz, int keyType, void* key,\n                                WC_RNG* rng);\nWOLFSSL_API int wc_SignCert(int requestSz, int sigType, byte* derBuffer,\n                             word32 derSz, RsaKey*, ecc_key*, WC_RNG*);\nWOLFSSL_API int wc_MakeSelfCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*,\n                             WC_RNG*);\nWOLFSSL_API int wc_SetIssuer(Cert*, const char*);\nWOLFSSL_API int wc_SetSubject(Cert*, const char*);\n#ifdef WOLFSSL_ALT_NAMES\n    WOLFSSL_API int wc_SetAltNames(Cert*, const char*);\n#endif\n\n#ifdef WOLFSSL_CERT_GEN_CACHE\nWOLFSSL_API void wc_SetCert_Free(Cert* cert);\n#endif\n\nWOLFSSL_API int wc_SetIssuerBuffer(Cert*, const byte*, int);\nWOLFSSL_API int wc_SetSubjectBuffer(Cert*, const byte*, int);\nWOLFSSL_API int wc_SetAltNamesBuffer(Cert*, const byte*, int);\nWOLFSSL_API int wc_SetDatesBuffer(Cert*, const byte*, int);\n\n#ifndef NO_ASN_TIME\nWOLFSSL_API int wc_GetCertDates(Cert* cert, struct tm* before,\n    struct tm* after);\n#endif\n\n#ifdef WOLFSSL_CERT_EXT\nWOLFSSL_API int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType,\n                                                void* key);\nWOLFSSL_API int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey,\n                                             ecc_key *eckey);\nWOLFSSL_API int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz);\nWOLFSSL_API int wc_SetAuthKeyId(Cert *cert, const char* file);\nWOLFSSL_API int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType,\n                                                   void* key);\nWOLFSSL_API int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey,\n                                                ecc_key *eckey);\nWOLFSSL_API int wc_SetSubjectKeyId(Cert *cert, const char* file);\nWOLFSSL_API int wc_GetSubjectRaw(byte **subjectRaw, Cert *cert);\nWOLFSSL_API int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz);\nWOLFSSL_API int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz);\n\n#ifdef HAVE_NTRU\nWOLFSSL_API int wc_SetSubjectKeyIdFromNtruPublicKey(Cert *cert, byte *ntruKey,\n                                                    word16 ntruKeySz);\n#endif\n\n/* Set the KeyUsage.\n * Value is a string separated tokens with ','. Accepted tokens are :\n * digitalSignature,nonRepudiation,contentCommitment,keyCertSign,cRLSign,\n * dataEncipherment,keyAgreement,keyEncipherment,encipherOnly and decipherOnly.\n *\n * nonRepudiation and contentCommitment are for the same usage.\n */\nWOLFSSL_API int wc_SetKeyUsage(Cert *cert, const char *value);\n\n/* Set ExtendedKeyUsage\n * Value is a string separated tokens with ','. Accepted tokens are :\n * any,serverAuth,clientAuth,codeSigning,emailProtection,timeStamping,OCSPSigning\n */\nWOLFSSL_API int wc_SetExtKeyUsage(Cert *cert, const char *value);\n\n\n#ifdef WOLFSSL_EKU_OID\n/* Set ExtendedKeyUsage with unique OID\n * oid is expected to be in byte representation\n */\nWOLFSSL_API int wc_SetExtKeyUsageOID(Cert *cert, const char *oid, word32 sz,\n                                     byte idx, void* heap);\n#endif /* WOLFSSL_EKU_OID */\n#endif /* WOLFSSL_CERT_EXT */\n\n    #ifdef HAVE_NTRU\n        WOLFSSL_API int wc_MakeNtruCert(Cert*, byte* derBuffer, word32 derSz,\n                                     const byte* ntruKey, word16 keySz,\n                                     WC_RNG*);\n    #endif\n\n#endif /* WOLFSSL_CERT_GEN */\n\nWOLFSSL_API int wc_GetDateInfo(const byte* certDate, int certDateSz,\n    const byte** date, byte* format, int* length);\n#ifndef NO_ASN_TIME\nWOLFSSL_API int wc_GetDateAsCalendarTime(const byte* date, int length,\n    byte format, struct tm* time);\n#endif\n\n#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)\n\n    WOLFSSL_API int wc_PemGetHeaderFooter(int type, const char** header,\n        const char** footer);\n\n#endif\n\nWOLFSSL_API  int wc_AllocDer(DerBuffer** pDer, word32 length, int type, void* heap);\nWOLFSSL_API void wc_FreeDer(DerBuffer** pDer);\n\n#ifdef WOLFSSL_PEM_TO_DER\n    WOLFSSL_API int wc_PemToDer(const unsigned char* buff, long longSz, int type,\n              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey);\n\n    WOLFSSL_API int wc_KeyPemToDer(const unsigned char*, int,\n                                   unsigned char*, int, const char*);\n    WOLFSSL_API int wc_CertPemToDer(const unsigned char*, int,\n                                    unsigned char*, int, int);\n#endif /* WOLFSSL_PEM_TO_DER */\n\n#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)\n    #ifndef NO_FILESYSTEM\n        WOLFSSL_API int wc_PemPubKeyToDer(const char* fileName,\n                                          unsigned char* derBuf, int derSz);\n    #endif\n\n    WOLFSSL_API int wc_PubKeyPemToDer(const unsigned char*, int,\n                                      unsigned char*, int);\n#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */\n\n#ifdef WOLFSSL_CERT_GEN\n    #ifndef NO_FILESYSTEM\n        WOLFSSL_API int wc_PemCertToDer(const char* fileName,\n                                        unsigned char* derBuf, int derSz);\n    #endif\n#endif /* WOLFSSL_CERT_GEN */\n\n#ifdef WOLFSSL_DER_TO_PEM\n    WOLFSSL_API int wc_DerToPem(const byte* der, word32 derSz, byte* output,\n                                word32 outputSz, int type);\n    WOLFSSL_API int wc_DerToPemEx(const byte* der, word32 derSz, byte* output,\n                                word32 outputSz, byte *cipherIno, int type);\n#endif\n\n#ifndef NO_RSA\n    #if !defined(HAVE_USER_RSA)\n    WOLFSSL_API int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx,\n        word32 inSz, const byte** n, word32* nSz, const byte** e, word32* eSz);\n    #endif\n    WOLFSSL_API int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header);\n#endif\n\n#ifdef HAVE_ECC\n    /* private key helpers */\n    WOLFSSL_API int wc_EccPrivateKeyDecode(const byte*, word32*,\n                                           ecc_key*, word32);\n    WOLFSSL_API int wc_EccKeyToDer(ecc_key*, byte* output, word32 inLen);\n    WOLFSSL_API int wc_EccPrivateKeyToDer(ecc_key* key, byte* output,\n                                          word32 inLen);\n    WOLFSSL_API int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output,\n                                            word32* outLen);\n\n    /* public key helper */\n    WOLFSSL_API int wc_EccPublicKeyDecode(const byte*, word32*,\n                                              ecc_key*, word32);\n    WOLFSSL_API int wc_EccPublicKeyToDer(ecc_key*, byte* output,\n                                         word32 inLen, int with_AlgCurve);\n    WOLFSSL_API int wc_EccPublicKeyDerSize(ecc_key*, int with_AlgCurve);\n#endif\n\n#ifdef HAVE_ED25519\n    /* private key helpers */\n    WOLFSSL_API int wc_Ed25519PrivateKeyDecode(const byte*, word32*,\n                                               ed25519_key*, word32);\n    WOLFSSL_API int wc_Ed25519KeyToDer(ed25519_key* key, byte* output,\n                                       word32 inLen);\n    WOLFSSL_API int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output,\n                                              word32 inLen);\n\n    /* public key helper */\n    WOLFSSL_API int wc_Ed25519PublicKeyDecode(const byte*, word32*,\n                                              ed25519_key*, word32);\n    #if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))\n        WOLFSSL_API int wc_Ed25519PublicKeyToDer(ed25519_key*, byte* output,\n                                               word32 inLen, int with_AlgCurve);\n    #endif\n#endif\n\n/* DER encode signature */\nWOLFSSL_API word32 wc_EncodeSignature(byte* out, const byte* digest,\n                                      word32 digSz, int hashOID);\nWOLFSSL_API int wc_GetCTC_HashOID(int type);\n\nWOLFSSL_API int wc_GetPkcs8TraditionalOffset(byte* input,\n                                             word32* inOutIdx, word32 sz);\nWOLFSSL_API int wc_CreatePKCS8Key(byte* out, word32* outSz,\n       byte* key, word32 keySz, int algoID, const byte* curveOID, word32 oidSz);\n\n#ifndef NO_ASN_TIME\n/* Time */\n/* Returns seconds (Epoch/UTC)\n * timePtr: is \"time_t\", which is typically \"long\"\n * Example:\n    long lTime;\n    rc = wc_GetTime(&lTime, (word32)sizeof(lTime));\n*/\nWOLFSSL_API int wc_GetTime(void* timePtr, word32 timeSize);\n#endif\n\n#ifdef WOLFSSL_ENCRYPTED_KEYS\n    WOLFSSL_API int wc_EncryptedInfoGet(EncryptedInfo* info,\n        const char* cipherInfo);\n#endif\n\n\n#ifdef WOLFSSL_CERT_PIV\n\ntypedef struct _wc_CertPIV {\n    const byte*  cert;\n    word32       certSz;\n    const byte*  certErrDet;\n    word32       certErrDetSz;\n    const byte*  nonce;         /* Identiv Only */\n    word32       nonceSz;       /* Identiv Only */\n    const byte*  signedNonce;   /* Identiv Only */\n    word32       signedNonceSz; /* Identiv Only */\n\n    /* flags */\n    word16       compression:2;\n    word16       isX509:1;\n    word16       isIdentiv:1;\n} wc_CertPIV;\n\nWOLFSSL_API int wc_ParseCertPIV(wc_CertPIV* cert, const byte* buf, word32 totalSz);\n#endif /* WOLFSSL_CERT_PIV */\n\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLF_CRYPT_ASN_PUBLIC_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/blake2-impl.h",
    "content": "/*\n   BLAKE2 reference source code package - reference C implementations\n\n   Written in 2012 by Samuel Neves <sneves@dei.uc.pt>\n\n   To the extent possible under law, the author(s) have dedicated all copyright\n   and related and neighboring rights to this software to the public domain\n   worldwide. This software is distributed without any warranty.\n\n   You should have received a copy of the CC0 Public Domain Dedication along with\n   this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.\n*/\n/* blake2-impl.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#ifndef WOLFCRYPT_BLAKE2_IMPL_H\n#define WOLFCRYPT_BLAKE2_IMPL_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\nstatic WC_INLINE word32 load32( const void *src )\n{\n#if defined(LITTLE_ENDIAN_ORDER)\n  return *( word32 * )( src );\n#else\n  const byte *p = ( byte * )src;\n  word32 w = *p++;\n  w |= ( word32 )( *p++ ) <<  8;\n  w |= ( word32 )( *p++ ) << 16;\n  w |= ( word32 )( *p++ ) << 24;\n  return w;\n#endif\n}\n\nstatic WC_INLINE word64 load64( const void *src )\n{\n#if defined(LITTLE_ENDIAN_ORDER)\n  return *( word64 * )( src );\n#else\n  const byte *p = ( byte * )src;\n  word64 w = *p++;\n  w |= ( word64 )( *p++ ) <<  8;\n  w |= ( word64 )( *p++ ) << 16;\n  w |= ( word64 )( *p++ ) << 24;\n  w |= ( word64 )( *p++ ) << 32;\n  w |= ( word64 )( *p++ ) << 40;\n  w |= ( word64 )( *p++ ) << 48;\n  w |= ( word64 )( *p++ ) << 56;\n  return w;\n#endif\n}\n\nstatic WC_INLINE void store32( void *dst, word32 w )\n{\n#if defined(LITTLE_ENDIAN_ORDER)\n  *( word32 * )( dst ) = w;\n#else\n  byte *p = ( byte * )dst;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w;\n#endif\n}\n\nstatic WC_INLINE void store64( void *dst, word64 w )\n{\n#if defined(LITTLE_ENDIAN_ORDER)\n  *( word64 * )( dst ) = w;\n#else\n  byte *p = ( byte * )dst;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w;\n#endif\n}\n\nstatic WC_INLINE word64 load48( const void *src )\n{\n  const byte *p = ( const byte * )src;\n  word64 w = *p++;\n  w |= ( word64 )( *p++ ) <<  8;\n  w |= ( word64 )( *p++ ) << 16;\n  w |= ( word64 )( *p++ ) << 24;\n  w |= ( word64 )( *p++ ) << 32;\n  w |= ( word64 )( *p++ ) << 40;\n  return w;\n}\n\nstatic WC_INLINE void store48( void *dst, word64 w )\n{\n  byte *p = ( byte * )dst;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w; w >>= 8;\n  *p++ = ( byte )w;\n}\n\nstatic WC_INLINE word32 rotl32( const word32 w, const unsigned c )\n{\n  return ( w << c ) | ( w >> ( 32 - c ) );\n}\n\nstatic WC_INLINE word64 rotl64( const word64 w, const unsigned c )\n{\n  return ( w << c ) | ( w >> ( 64 - c ) );\n}\n\nstatic WC_INLINE word32 rotr32( const word32 w, const unsigned c )\n{\n  return ( w >> c ) | ( w << ( 32 - c ) );\n}\n\nstatic WC_INLINE word64 rotr64( const word64 w, const unsigned c )\n{\n  return ( w >> c ) | ( w << ( 64 - c ) );\n}\n\n/* prevents compiler optimizing out memset() */\nstatic WC_INLINE void secure_zero_memory( void *v, word64 n )\n{\n  volatile byte *p = ( volatile byte * )v;\n\n  while( n-- ) *p++ = 0;\n}\n\n#endif  /* WOLFCRYPT_BLAKE2_IMPL_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/blake2-int.h",
    "content": "/*\n   BLAKE2 reference source code package - reference C implementations\n\n   Written in 2012 by Samuel Neves <sneves@dei.uc.pt>\n\n   To the extent possible under law, the author(s) have dedicated all copyright\n   and related and neighboring rights to this software to the public domain\n   worldwide. This software is distributed without any warranty.\n\n   You should have received a copy of the CC0 Public Domain Dedication along with\n   this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.\n*/\n/* blake2-int.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n\n#ifndef WOLFCRYPT_BLAKE2_INT_H\n#define WOLFCRYPT_BLAKE2_INT_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n\n#if defined(_MSC_VER)\n    #define ALIGN(x) __declspec(align(x))\n#elif defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__)\n    #define ALIGN(x) __attribute__((aligned(x)))\n#else\n    #define ALIGN(x)\n#endif\n\n\n#if defined(__cplusplus)\n    extern \"C\" {\n#endif\n\n  enum blake2s_constant\n  {\n    BLAKE2S_BLOCKBYTES = 64,\n    BLAKE2S_OUTBYTES   = 32,\n    BLAKE2S_KEYBYTES   = 32,\n    BLAKE2S_SALTBYTES  = 8,\n    BLAKE2S_PERSONALBYTES = 8\n  };\n\n  enum blake2b_constant\n  {\n    BLAKE2B_BLOCKBYTES = 128,\n    BLAKE2B_OUTBYTES   = 64,\n    BLAKE2B_KEYBYTES   = 64,\n    BLAKE2B_SALTBYTES  = 16,\n    BLAKE2B_PERSONALBYTES = 16\n  };\n\n#pragma pack(push, 1)\n  typedef struct __blake2s_param\n  {\n    byte  digest_length; /* 1 */\n    byte  key_length;    /* 2 */\n    byte  fanout;        /* 3 */\n    byte  depth;         /* 4 */\n    word32 leaf_length;   /* 8 */\n    byte  node_offset[6];/* 14 */\n    byte  node_depth;    /* 15 */\n    byte  inner_length;  /* 16 */\n    /* byte  reserved[0]; */\n    byte  salt[BLAKE2B_SALTBYTES]; /* 24 */\n    byte  personal[BLAKE2S_PERSONALBYTES];  /* 32 */\n  } blake2s_param;\n\n  ALIGN( 32 ) typedef struct __blake2s_state\n  {\n    word32 h[8];\n    word32 t[2];\n    word32 f[2];\n    byte  buf[2 * BLAKE2S_BLOCKBYTES];\n    word32 buflen;\n    byte  last_node;\n  } blake2s_state ;\n\n  typedef struct __blake2b_param\n  {\n    byte  digest_length; /* 1 */\n    byte  key_length;    /* 2 */\n    byte  fanout;        /* 3 */\n    byte  depth;         /* 4 */\n    word32 leaf_length;   /* 8 */\n    word64 node_offset;   /* 16 */\n    byte  node_depth;    /* 17 */\n    byte  inner_length;  /* 18 */\n    byte  reserved[14];  /* 32 */\n    byte  salt[BLAKE2B_SALTBYTES]; /* 48 */\n    byte  personal[BLAKE2B_PERSONALBYTES];  /* 64 */\n  } blake2b_param;\n\n  ALIGN( 64 ) typedef struct __blake2b_state\n  {\n    word64 h[8];\n    word64 t[2];\n    word64 f[2];\n    byte  buf[2 * BLAKE2B_BLOCKBYTES];\n    word64 buflen;\n    byte  last_node;\n  } blake2b_state;\n\n  typedef struct __blake2sp_state\n  {\n    blake2s_state S[8][1];\n    blake2s_state R[1];\n    byte buf[8 * BLAKE2S_BLOCKBYTES];\n    word32 buflen;\n  } blake2sp_state;\n\n  typedef struct __blake2bp_state\n  {\n    blake2b_state S[4][1];\n    blake2b_state R[1];\n    byte buf[4 * BLAKE2B_BLOCKBYTES];\n    word64 buflen;\n  } blake2bp_state;\n#pragma pack(pop)\n\n  /* Streaming API */\n  int blake2s_init( blake2s_state *S, const byte outlen );\n  int blake2s_init_key( blake2s_state *S, const byte outlen, const void *key, const byte keylen );\n  int blake2s_init_param( blake2s_state *S, const blake2s_param *P );\n  int blake2s_update( blake2s_state *S, const byte *in, word32 inlen );\n  int blake2s_final( blake2s_state *S, byte *out, byte outlen );\n\n  int blake2b_init( blake2b_state *S, const byte outlen );\n  int blake2b_init_key( blake2b_state *S, const byte outlen, const void *key, const byte keylen );\n  int blake2b_init_param( blake2b_state *S, const blake2b_param *P );\n  int blake2b_update( blake2b_state *S, const byte *in, word64 inlen );\n  int blake2b_final( blake2b_state *S, byte *out, byte outlen );\n\n  int blake2sp_init( blake2sp_state *S, const byte outlen );\n  int blake2sp_init_key( blake2sp_state *S, const byte outlen, const void *key, const byte keylen );\n  int blake2sp_update( blake2sp_state *S, const byte *in, word32 inlen );\n  int blake2sp_final( blake2sp_state *S, byte *out, byte outlen );\n\n  int blake2bp_init( blake2bp_state *S, const byte outlen );\n  int blake2bp_init_key( blake2bp_state *S, const byte outlen, const void *key, const byte keylen );\n  int blake2bp_update( blake2bp_state *S, const byte *in, word64 inlen );\n  int blake2bp_final( blake2bp_state *S, byte *out, byte outlen );\n\n  /* Simple API */\n  int blake2s( byte *out, const void *in, const void *key, const byte outlen, const word32 inlen, byte keylen );\n  int blake2b( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen );\n\n  int blake2sp( byte *out, const void *in, const void *key, const byte outlen, const word32 inlen, byte keylen );\n  int blake2bp( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen );\n\n  static WC_INLINE int blake2( byte *out, const void *in, const void *key, const byte outlen, const word64 inlen, byte keylen )\n  {\n    return blake2b( out, in, key, outlen, inlen, keylen );\n  }\n\n\n\n#if defined(__cplusplus)\n    }\n#endif\n\n#endif  /* WOLFCRYPT_BLAKE2_INT_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/blake2.h",
    "content": "/* blake2.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/blake2.h\n*/\n\n#ifndef WOLF_CRYPT_BLAKE2_H\n#define WOLF_CRYPT_BLAKE2_H\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S)\n\n#include <wolfssl/wolfcrypt/blake2-int.h>\n\n/* call old functions if using fips for the sake of hmac @wc_fips */\n#ifdef HAVE_FIPS\n    /* Since hmac can call blake functions provide original calls */\n    #define wc_InitBlake2b   InitBlake2b\n    #define wc_Blake2bUpdate Blake2bUpdate\n    #define wc_Blake2bFinal  Blake2bFinal\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* in bytes, variable digest size up to 512 bits (64 bytes) */\nenum {\n#ifdef HAVE_BLAKE2B\n    BLAKE2B_ID  = WC_HASH_TYPE_BLAKE2B,\n    BLAKE2B_256 = 32,  /* 256 bit type, SSL default */\n#endif\n#ifdef HAVE_BLAKE2S\n    BLAKE2S_ID  = WC_HASH_TYPE_BLAKE2S,\n    BLAKE2S_256 = 32   /* 256 bit type */\n#endif\n};\n\n\n#ifdef HAVE_BLAKE2B\n/* BLAKE2b digest */\ntypedef struct Blake2b {\n    blake2b_state S[1];         /* our state */\n    word32        digestSz;     /* digest size used on init */\n} Blake2b;\n#endif\n\n#ifdef HAVE_BLAKE2S\n/* BLAKE2s digest */\ntypedef struct Blake2s {\n    blake2s_state S[1];         /* our state */\n    word32        digestSz;     /* digest size used on init */\n} Blake2s;\n#endif\n\n\n#ifdef HAVE_BLAKE2B\nWOLFSSL_API int wc_InitBlake2b(Blake2b*, word32);\nWOLFSSL_API int wc_Blake2bUpdate(Blake2b*, const byte*, word32);\nWOLFSSL_API int wc_Blake2bFinal(Blake2b*, byte*, word32);\n#endif\n\n#ifdef HAVE_BLAKE2S\nWOLFSSL_API int wc_InitBlake2s(Blake2s*, word32);\nWOLFSSL_API int wc_Blake2sUpdate(Blake2s*, const byte*, word32);\nWOLFSSL_API int wc_Blake2sFinal(Blake2s*, byte*, word32);\n#endif\n\n\n#ifdef __cplusplus\n    }\n#endif\n\n#endif  /* HAVE_BLAKE2 || HAVE_BLAKE2S */\n#endif  /* WOLF_CRYPT_BLAKE2_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/camellia.h",
    "content": "/* camellia.h ver 1.2.0\n *\n * Copyright (c) 2006,2007\n * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer as\n *   the first lines of this file unmodified.\n * 2. Redistributions in binary form must reproduce the above copyright\n *   notice, this list of conditions and the following disclaimer in the\n *   documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/* camellia.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/camellia.h\n*/\n\n\n#ifndef WOLF_CRYPT_CAMELLIA_H\n#define WOLF_CRYPT_CAMELLIA_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef HAVE_CAMELLIA\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\nenum {\n    CAMELLIA_BLOCK_SIZE = 16\n};\n\n#define CAMELLIA_TABLE_BYTE_LEN 272\n#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / sizeof(word32))\n\ntypedef word32 KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];\n\ntypedef struct Camellia {\n    word32 keySz;\n    KEY_TABLE_TYPE key;\n    word32 reg[CAMELLIA_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */\n    word32 tmp[CAMELLIA_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */\n} Camellia;\n\n\nWOLFSSL_API int  wc_CamelliaSetKey(Camellia* cam,\n                                   const byte* key, word32 len, const byte* iv);\nWOLFSSL_API int  wc_CamelliaSetIV(Camellia* cam, const byte* iv);\nWOLFSSL_API int  wc_CamelliaEncryptDirect(Camellia* cam, byte* out,\n                                                                const byte* in);\nWOLFSSL_API int  wc_CamelliaDecryptDirect(Camellia* cam, byte* out,\n                                                                const byte* in);\nWOLFSSL_API int wc_CamelliaCbcEncrypt(Camellia* cam,\n                                          byte* out, const byte* in, word32 sz);\nWOLFSSL_API int wc_CamelliaCbcDecrypt(Camellia* cam,\n                                          byte* out, const byte* in, word32 sz);\n\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* HAVE_CAMELLIA */\n#endif /* WOLF_CRYPT_CAMELLIA_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/chacha.h",
    "content": "/* chacha.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/chacha.h\n*/\n\n\n#ifndef WOLF_CRYPT_CHACHA_H\n#define WOLF_CRYPT_CHACHA_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef HAVE_CHACHA\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* Size of the IV */\n#define CHACHA_IV_WORDS    3\n#define CHACHA_IV_BYTES    (CHACHA_IV_WORDS * sizeof(word32))\n\n/* Size of ChaCha chunks */\n#define CHACHA_CHUNK_WORDS 16\n#define CHACHA_CHUNK_BYTES (CHACHA_CHUNK_WORDS * sizeof(word32))\n\n#ifdef WOLFSSL_X86_64_BUILD\n#if defined(USE_INTEL_SPEEDUP) && !defined(NO_CHACHA_ASM)\n    #define USE_INTEL_CHACHA_SPEEDUP\n    #define HAVE_INTEL_AVX1\n#endif\n#endif\n\nenum {\n\tCHACHA_ENC_TYPE = WC_CIPHER_CHACHA,    /* cipher unique type */\n    CHACHA_MAX_KEY_SZ = 32,\n};\n\ntypedef struct ChaCha {\n    word32 X[CHACHA_CHUNK_WORDS];           /* state of cipher */\n#ifdef HAVE_INTEL_AVX1\n    /* vpshufd reads 16 bytes but we only use bottom 4. */\n    byte extra[12];\n#endif\n} ChaCha;\n\n/**\n  * IV(nonce) changes with each record\n  * counter is for what value the block counter should start ... usually 0\n  */\nWOLFSSL_API int wc_Chacha_SetIV(ChaCha* ctx, const byte* inIv, word32 counter);\n\nWOLFSSL_API int wc_Chacha_Process(ChaCha* ctx, byte* cipher, const byte* plain,\n                              word32 msglen);\nWOLFSSL_API int wc_Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz);\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* HAVE_CHACHA */\n#endif /* WOLF_CRYPT_CHACHA_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/chacha20_poly1305.h",
    "content": "/* chacha20_poly1305.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n/* This implementation of the ChaCha20-Poly1305 AEAD is based on \"ChaCha20\n * and Poly1305 for IETF protocols\" (draft-irtf-cfrg-chacha20-poly1305-10):\n * https://tools.ietf.org/html/draft-irtf-cfrg-chacha20-poly1305-10\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/chacha20_poly1305.h\n*/\n\n#ifndef WOLF_CRYPT_CHACHA20_POLY1305_H\n#define WOLF_CRYPT_CHACHA20_POLY1305_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#define CHACHA20_POLY1305_AEAD_KEYSIZE      32\n#define CHACHA20_POLY1305_AEAD_IV_SIZE      12\n#define CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE 16\n\nenum {\n    CHACHA20_POLY_1305_ENC_TYPE = 8    /* cipher unique type */\n};\n\n    /*\n     * The IV for this implementation is 96 bits to give the most flexibility.\n     *\n     * Some protocols may have unique per-invocation inputs that are not\n     * 96-bit in length. For example, IPsec may specify a 64-bit nonce. In\n     * such a case, it is up to the protocol document to define how to\n     * transform the protocol nonce into a 96-bit nonce, for example by\n     * concatenating a constant value.\n     */\n\nWOLFSSL_API\nint wc_ChaCha20Poly1305_Encrypt(\n                const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE],\n                const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE],\n                const byte* inAAD, const word32 inAADLen,\n                const byte* inPlaintext, const word32 inPlaintextLen,\n                byte* outCiphertext,\n                byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]);\n\nWOLFSSL_API\nint wc_ChaCha20Poly1305_Decrypt(\n                const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE],\n                const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE],\n                const byte* inAAD, const word32 inAADLen,\n                const byte* inCiphertext, const word32 inCiphertextLen,\n                const byte inAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE],\n                byte* outPlaintext);\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* HAVE_CHACHA && HAVE_POLY1305 */\n#endif /* WOLF_CRYPT_CHACHA20_POLY1305_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/cmac.h",
    "content": "/* cmac.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifndef WOLF_CRYPT_CMAC_H\n#define WOLF_CRYPT_CMAC_H\n\n#include <wolfssl/wolfcrypt/types.h>\n#include <wolfssl/wolfcrypt/aes.h>\n\n#if !defined(NO_AES) && defined(WOLFSSL_CMAC)\n\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n    #include <wolfssl/wolfcrypt/fips.h>\n#endif /* HAVE_FIPS_VERSION >= 2 */\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* avoid redefinition of structs */\n#if !defined(HAVE_FIPS) || \\\n    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))\n\n#ifndef WC_CMAC_TYPE_DEFINED\n    typedef struct Cmac Cmac;\n    #define WC_CMAC_TYPE_DEFINED\n#endif\nstruct Cmac {\n    Aes aes;\n    byte buffer[AES_BLOCK_SIZE]; /* partially stored block */\n    byte digest[AES_BLOCK_SIZE]; /* running digest */\n    byte k1[AES_BLOCK_SIZE];\n    byte k2[AES_BLOCK_SIZE];\n    word32 bufferSz;\n    word32 totalSz;\n};\n\n\n\ntypedef enum CmacType {\n    WC_CMAC_AES = 1\n} CmacType;\n\n#define WC_CMAC_TAG_MAX_SZ AES_BLOCK_SIZE\n#define WC_CMAC_TAG_MIN_SZ (AES_BLOCK_SIZE/4)\n\n#endif /* HAVE_FIPS */\n\nWOLFSSL_API\nint wc_InitCmac(Cmac* cmac,\n                const byte* key, word32 keySz,\n                int type, void* unused);\nWOLFSSL_API\nint wc_CmacUpdate(Cmac* cmac,\n                  const byte* in, word32 inSz);\nWOLFSSL_API\nint wc_CmacFinal(Cmac* cmac,\n                 byte* out, word32* outSz);\n\nWOLFSSL_API\nint wc_AesCmacGenerate(byte* out, word32* outSz,\n                       const byte* in, word32 inSz,\n                       const byte* key, word32 keySz);\n\nWOLFSSL_API\nint wc_AesCmacVerify(const byte* check, word32 checkSz,\n                     const byte* in, word32 inSz,\n                     const byte* key, word32 keySz);\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n\n#endif /* NO_AES && WOLFSSL_CMAC */\n#endif /* WOLF_CRYPT_CMAC_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/coding.h",
    "content": "/* coding.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/coding.h\n*/\n\n#ifndef WOLF_CRYPT_CODING_H\n#define WOLF_CRYPT_CODING_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n\nWOLFSSL_API int Base64_Decode(const byte* in, word32 inLen, byte* out,\n                               word32* outLen);\n\n#if defined(OPENSSL_EXTRA) || defined(SESSION_CERTS) || defined(WOLFSSL_KEY_GEN) \\\n   || defined(WOLFSSL_CERT_GEN) || defined(HAVE_WEBSERVER) || !defined(NO_DSA)\n    #ifndef WOLFSSL_BASE64_ENCODE\n        #define WOLFSSL_BASE64_ENCODE\n    #endif\n#endif\n\n\n#ifdef WOLFSSL_BASE64_ENCODE\n    enum Escaped {\n        WC_STD_ENC = 0,       /* normal \\n line ending encoding */\n        WC_ESC_NL_ENC,        /* use escape sequence encoding   */\n        WC_NO_NL_ENC          /* no encoding at all             */\n    }; /* Encoding types */\n\n    /* encode isn't */\n    WOLFSSL_API\n    int Base64_Encode(const byte* in, word32 inLen, byte* out,\n                                  word32* outLen);\n    WOLFSSL_API\n    int Base64_EncodeEsc(const byte* in, word32 inLen, byte* out,\n                                  word32* outLen);\n    WOLFSSL_API\n    int Base64_Encode_NoNl(const byte* in, word32 inLen, byte* out,\n                                  word32* outLen);\n#endif\n\n#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \\\n    defined(HAVE_WEBSERVER) || defined(HAVE_FIPS) || \\\n    defined(HAVE_ECC_CDH) || defined(HAVE_SELFTEST) || \\\n    defined(WOLFSSL_ENCRYPTED_KEYS)\n    #ifndef WOLFSSL_BASE16\n        #define WOLFSSL_BASE16\n    #endif\n#endif\n\n#ifdef WOLFSSL_BASE16\n    WOLFSSL_API\n    int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen);\n    WOLFSSL_API\n    int Base16_Encode(const byte* in, word32 inLen, byte* out, word32* outLen);\n#endif\n\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLF_CRYPT_CODING_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/compress.h",
    "content": "/* compress.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/compress.h\n*/\n\n\n#ifndef WOLF_CRYPT_COMPRESS_H\n#define WOLF_CRYPT_COMPRESS_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef HAVE_LIBZ\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n\n#define COMPRESS_FIXED 1\n\n#define LIBZ_WINBITS_GZIP 16\n\n\nWOLFSSL_API int wc_Compress(byte*, word32, const byte*, word32, word32);\nWOLFSSL_API int wc_Compress_ex(byte* out, word32 outSz, const byte* in,\n    word32 inSz, word32 flags, word32 windowBits);\nWOLFSSL_API int wc_DeCompress(byte*, word32, const byte*, word32);\nWOLFSSL_API int wc_DeCompress_ex(byte* out, word32 outSz, const byte* in,\n    word32 inSz, int windowBits);\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n\n#endif /* HAVE_LIBZ */\n#endif /* WOLF_CRYPT_COMPRESS_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/cpuid.h",
    "content": "/* cpuid.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#ifndef WOLF_CRYPT_CPUID_H\n#define WOLF_CRYPT_CPUID_H\n\n\n#include <wolfssl/wolfcrypt/types.h>\n\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#if defined(WOLFSSL_X86_64_BUILD) || defined(USE_INTEL_SPEEDUP) || \\\n    defined(WOLFSSL_AESNI)\n    #define CPUID_AVX1   0x0001\n    #define CPUID_AVX2   0x0002\n    #define CPUID_RDRAND 0x0004\n    #define CPUID_RDSEED 0x0008\n    #define CPUID_BMI2   0x0010   /* MULX, RORX */\n    #define CPUID_AESNI  0x0020\n    #define CPUID_ADX    0x0040   /* ADCX, ADOX */\n\n    #define IS_INTEL_AVX1(f)    ((f) & CPUID_AVX1)\n    #define IS_INTEL_AVX2(f)    ((f) & CPUID_AVX2)\n    #define IS_INTEL_RDRAND(f)  ((f) & CPUID_RDRAND)\n    #define IS_INTEL_RDSEED(f)  ((f) & CPUID_RDSEED)\n    #define IS_INTEL_BMI2(f)    ((f) & CPUID_BMI2)\n    #define IS_INTEL_AESNI(f)   ((f) & CPUID_AESNI)\n    #define IS_INTEL_ADX(f)     ((f) & CPUID_ADX)\n\n    void cpuid_set_flags(void);\n    word32 cpuid_get_flags(void);\n#endif\n\n#ifdef __cplusplus\n    }   /* extern \"C\" */\n#endif\n\n\n#endif /* WOLF_CRYPT_CPUID_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/cryptocb.h",
    "content": "/* cryptocb.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef _WOLF_CRYPTO_CB_H_\n#define _WOLF_CRYPTO_CB_H_\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* Defines the Crypto Callback interface version, for compatibility */\n/* Increment this when Crypto Callback interface changes are made */\n#define CRYPTO_CB_VER   2\n\n\n#ifdef WOLF_CRYPTO_CB\n\n#ifndef NO_RSA\n    #include <wolfssl/wolfcrypt/rsa.h>\n#endif\n#ifdef HAVE_ECC\n    #include <wolfssl/wolfcrypt/ecc.h>\n#endif\n#ifndef NO_AES\n    #include <wolfssl/wolfcrypt/aes.h>\n#endif\n#ifndef NO_SHA\n    #include <wolfssl/wolfcrypt/sha.h>\n#endif\n#ifndef NO_SHA256\n    #include <wolfssl/wolfcrypt/sha256.h>\n#endif\n#ifndef NO_HMAC\n    #include <wolfssl/wolfcrypt/hmac.h>\n#endif\n#ifndef WC_NO_RNG\n    #include <wolfssl/wolfcrypt/random.h>\n#endif\n#ifndef NO_DES3\n    #include <wolfssl/wolfcrypt/des3.h>\n#endif\n\n\n/* Crypto Information Structure for callbacks */\ntypedef struct wc_CryptoInfo {\n    int algo_type; /* enum wc_AlgoType */\n#if !defined(NO_RSA) || defined(HAVE_ECC)\n    struct {\n        int type; /* enum wc_PkType */\n        union {\n        #ifndef NO_RSA\n            struct {\n                const byte* in;\n                word32      inLen;\n                byte*       out;\n                word32*     outLen;\n                int         type;\n                RsaKey*     key;\n                WC_RNG*     rng;\n            } rsa;\n        #ifdef WOLFSSL_KEY_GEN\n            struct {\n                RsaKey* key;\n                int     size;\n                long    e;\n                WC_RNG* rng;\n            } rsakg;\n        #endif\n        #endif\n        #ifdef HAVE_ECC\n            struct {\n                WC_RNG*  rng;\n                int      size;\n                ecc_key* key;\n                int      curveId;\n            } eckg;\n            struct {\n                ecc_key* private_key;\n                ecc_key* public_key;\n                byte*    out;\n                word32*  outlen;\n            } ecdh;\n            struct {\n                const byte* in;\n                word32      inlen;\n                byte*       out;\n                word32*     outlen;\n                WC_RNG*     rng;\n                ecc_key*    key;\n            } eccsign;\n            struct {\n                const byte* sig;\n                word32      siglen;\n                const byte* hash;\n                word32      hashlen;\n                int*        res;\n                ecc_key*    key;\n            } eccverify;\n        #endif\n        };\n    } pk;\n#endif /* !NO_RSA || HAVE_ECC */\n#if !defined(NO_AES) || !defined(NO_DES3)\n    struct {\n        int type; /* enum wc_CipherType */\n        int enc;\n        union {\n        #ifdef HAVE_AESGCM\n            struct {\n                Aes*        aes;\n                byte*       out;\n                const byte* in;\n                word32      sz;\n                const byte* iv;\n                word32      ivSz;\n                byte*       authTag;\n                word32      authTagSz;\n                const byte* authIn;\n                word32      authInSz;\n            } aesgcm_enc;\n            struct {\n                Aes*        aes;\n                byte*       out;\n                const byte* in;\n                word32      sz;\n                const byte* iv;\n                word32      ivSz;\n                const byte* authTag;\n                word32      authTagSz;\n                const byte* authIn;\n                word32      authInSz;\n            } aesgcm_dec;\n        #endif /* HAVE_AESGCM */\n        #ifdef HAVE_AES_CBC\n            struct {\n                Aes*        aes;\n                byte*       out;\n                const byte* in;\n                word32      sz;\n            } aescbc;\n        #endif /* HAVE_AES_CBC */\n        #ifndef NO_DES3\n            struct {\n                Des3*       des;\n                byte*       out;\n                const byte* in;\n                word32      sz;\n            } des3;\n        #endif\n        };\n    } cipher;\n#endif /* !NO_AES || !NO_DES3 */\n#if !defined(NO_SHA) || !defined(NO_SHA256)\n    struct {\n        int type; /* enum wc_HashType */\n        const byte* in;\n        word32 inSz;\n        byte* digest;\n        union {\n        #ifndef NO_SHA\n            wc_Sha* sha1;\n        #endif\n        #ifndef NO_SHA256\n            wc_Sha256* sha256;\n        #endif\n        };\n    } hash;\n#endif /* !NO_SHA || !NO_SHA256 */\n#ifndef NO_HMAC\n    struct {\n        int macType; /* enum wc_HashType */\n        const byte* in;\n        word32 inSz;\n        byte* digest;\n        Hmac* hmac;\n    } hmac;\n#endif\n#ifndef WC_NO_RNG\n    struct {\n        WC_RNG* rng;\n        byte* out;\n        word32 sz;\n    } rng;\n    struct {\n        OS_Seed* os;\n        byte* seed;\n        word32 sz;\n    } seed;\n#endif\n} wc_CryptoInfo;\n\n\ntypedef int (*CryptoDevCallbackFunc)(int devId, wc_CryptoInfo* info, void* ctx);\n\nWOLFSSL_LOCAL void wc_CryptoCb_Init(void);\n\nWOLFSSL_API int  wc_CryptoCb_RegisterDevice(int devId, CryptoDevCallbackFunc cb, void* ctx);\nWOLFSSL_API void wc_CryptoCb_UnRegisterDevice(int devId);\n\n/* old function names */\n#define wc_CryptoDev_RegisterDevice   wc_CryptoCb_RegisterDevice\n#define wc_CryptoDev_UnRegisterDevice wc_CryptoCb_UnRegisterDevice\n\n\n#ifndef NO_RSA\nWOLFSSL_LOCAL int wc_CryptoCb_Rsa(const byte* in, word32 inLen, byte* out,\n    word32* outLen, int type, RsaKey* key, WC_RNG* rng);\n\n#ifdef WOLFSSL_KEY_GEN\nWOLFSSL_LOCAL int wc_CryptoCb_MakeRsaKey(RsaKey* key, int size, long e,\n    WC_RNG* rng);\n#endif /* WOLFSSL_KEY_GEN */\n#endif /* !NO_RSA */\n\n#ifdef HAVE_ECC\nWOLFSSL_LOCAL int wc_CryptoCb_MakeEccKey(WC_RNG* rng, int keySize,\n    ecc_key* key, int curveId);\n\nWOLFSSL_LOCAL int wc_CryptoCb_Ecdh(ecc_key* private_key, ecc_key* public_key,\n    byte* out, word32* outlen);\n\nWOLFSSL_LOCAL int wc_CryptoCb_EccSign(const byte* in, word32 inlen, byte* out,\n    word32 *outlen, WC_RNG* rng, ecc_key* key);\n\nWOLFSSL_LOCAL int wc_CryptoCb_EccVerify(const byte* sig, word32 siglen,\n    const byte* hash, word32 hashlen, int* res, ecc_key* key);\n#endif /* HAVE_ECC */\n\n#ifndef NO_AES\n#ifdef HAVE_AESGCM\nWOLFSSL_LOCAL int wc_CryptoCb_AesGcmEncrypt(Aes* aes, byte* out,\n     const byte* in, word32 sz, const byte* iv, word32 ivSz,\n     byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz);\n\nWOLFSSL_LOCAL int wc_CryptoCb_AesGcmDecrypt(Aes* aes, byte* out,\n     const byte* in, word32 sz, const byte* iv, word32 ivSz,\n     const byte* authTag, word32 authTagSz,\n     const byte* authIn, word32 authInSz);\n#endif /* HAVE_AESGCM */\n#ifdef HAVE_AES_CBC\nWOLFSSL_LOCAL int wc_CryptoCb_AesCbcEncrypt(Aes* aes, byte* out,\n                               const byte* in, word32 sz);\nWOLFSSL_LOCAL int wc_CryptoCb_AesCbcDecrypt(Aes* aes, byte* out,\n                               const byte* in, word32 sz);\n#endif /* HAVE_AES_CBC */\n#endif /* !NO_AES */\n\n#ifndef NO_DES3\nWOLFSSL_LOCAL int wc_CryptoCb_Des3Encrypt(Des3* des3, byte* out,\n                               const byte* in, word32 sz);\nWOLFSSL_LOCAL int wc_CryptoCb_Des3Decrypt(Des3* des3, byte* out,\n                               const byte* in, word32 sz);\n#endif /* !NO_DES3 */\n\n#ifndef NO_SHA\nWOLFSSL_LOCAL int wc_CryptoCb_ShaHash(wc_Sha* sha, const byte* in,\n    word32 inSz, byte* digest);\n#endif /* !NO_SHA */\n\n#ifndef NO_SHA256\nWOLFSSL_LOCAL int wc_CryptoCb_Sha256Hash(wc_Sha256* sha256, const byte* in,\n    word32 inSz, byte* digest);\n#endif /* !NO_SHA256 */\n#ifndef NO_HMAC\nWOLFSSL_LOCAL int wc_CryptoCb_Hmac(Hmac* hmac, int macType, const byte* in,\n    word32 inSz, byte* digest);\n#endif /* !NO_HMAC */\n\n#ifndef WC_NO_RNG\nWOLFSSL_LOCAL int wc_CryptoCb_RandomBlock(WC_RNG* rng, byte* out, word32 sz);\nWOLFSSL_LOCAL int wc_CryptoCb_RandomSeed(OS_Seed* os, byte* seed, word32 sz);\n#endif\n\n#endif /* WOLF_CRYPTO_CB */\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* _WOLF_CRYPTO_CB_H_ */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/curve25519.h",
    "content": "/* curve25519.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/curve25519.h\n*/\n\n\n#ifndef WOLF_CRYPT_CURVE25519_H\n#define WOLF_CRYPT_CURVE25519_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef HAVE_CURVE25519\n\n#include <wolfssl/wolfcrypt/fe_operations.h>\n#include <wolfssl/wolfcrypt/random.h>\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#define CURVE25519_KEYSIZE 32\n\n/* curve25519 set type */\ntypedef struct {\n    int size;       /* The size of the curve in octets */\n    const char* name;     /* name of this curve */\n} curve25519_set_type;\n\n\n/* ECC point, the internal structure is Little endian\n * the mathematical functions used the endianess */\ntypedef struct {\n    byte point[CURVE25519_KEYSIZE];\n    #ifdef FREESCALE_LTC_ECC\n        byte pointY[CURVE25519_KEYSIZE];\n    #endif\n} ECPoint;\n\n/* A CURVE25519 Key */\ntypedef struct curve25519_key {\n    int idx;            /* Index into the ecc_sets[] for the parameters of\n                           this curve if -1, this key is using user supplied\n                           curve in dp */\n    const curve25519_set_type* dp;   /* domain parameters, either points to\n                                   curves (idx >= 0) or user supplied */\n    ECPoint   p;        /* public key  */\n    ECPoint   k;        /* private key */\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV asyncDev;\n#endif\n} curve25519_key;\n\nenum {\n    EC25519_LITTLE_ENDIAN=0,\n    EC25519_BIG_ENDIAN=1\n};\n\nWOLFSSL_API\nint wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key);\n\nWOLFSSL_API\nint wc_curve25519_shared_secret(curve25519_key* private_key,\n                                curve25519_key* public_key,\n                                byte* out, word32* outlen);\n\nWOLFSSL_API\nint wc_curve25519_shared_secret_ex(curve25519_key* private_key,\n                                   curve25519_key* public_key,\n                                   byte* out, word32* outlen, int endian);\n\nWOLFSSL_API\nint wc_curve25519_init(curve25519_key* key);\n\nWOLFSSL_API\nvoid wc_curve25519_free(curve25519_key* key);\n\n\n/* raw key helpers */\nWOLFSSL_API\nint wc_curve25519_import_private(const byte* priv, word32 privSz,\n                                 curve25519_key* key);\nWOLFSSL_API\nint wc_curve25519_import_private_ex(const byte* priv, word32 privSz,\n                                    curve25519_key* key, int endian);\n\nWOLFSSL_API\nint wc_curve25519_import_private_raw(const byte* priv, word32 privSz,\n                            const byte* pub, word32 pubSz, curve25519_key* key);\nWOLFSSL_API\nint wc_curve25519_import_private_raw_ex(const byte* priv, word32 privSz,\n                                        const byte* pub, word32 pubSz,\n                                        curve25519_key* key, int endian);\nWOLFSSL_API\nint wc_curve25519_export_private_raw(curve25519_key* key, byte* out,\n                                     word32* outLen);\nWOLFSSL_API\nint wc_curve25519_export_private_raw_ex(curve25519_key* key, byte* out,\n                                        word32* outLen, int endian);\n\nWOLFSSL_API\nint wc_curve25519_import_public(const byte* in, word32 inLen,\n                                curve25519_key* key);\nWOLFSSL_API\nint wc_curve25519_import_public_ex(const byte* in, word32 inLen,\n                                   curve25519_key* key, int endian);\nWOLFSSL_API\nint wc_curve25519_check_public(const byte* pub, word32 pubSz, int endian);\n\nWOLFSSL_API\nint wc_curve25519_export_public(curve25519_key* key, byte* out, word32* outLen);\nWOLFSSL_API\nint wc_curve25519_export_public_ex(curve25519_key* key, byte* out,\n                                   word32* outLen, int endian);\n\nWOLFSSL_API\nint wc_curve25519_export_key_raw(curve25519_key* key,\n                                 byte* priv, word32 *privSz,\n                                 byte* pub, word32 *pubSz);\nWOLFSSL_API\nint wc_curve25519_export_key_raw_ex(curve25519_key* key,\n                                    byte* priv, word32 *privSz,\n                                    byte* pub, word32 *pubSz,\n                                    int endian);\n/* size helper */\nWOLFSSL_API\nint wc_curve25519_size(curve25519_key* key);\n\n#ifdef __cplusplus\n    }    /* extern \"C\" */\n#endif\n\n#endif /* HAVE_CURVE25519 */\n#endif /* WOLF_CRYPT_CURVE25519_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/des3.h",
    "content": "/* des3.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/des3.h\n*/\n\n#ifndef WOLF_CRYPT_DES3_H\n#define WOLF_CRYPT_DES3_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_DES3\n\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n    #include <wolfssl/wolfcrypt/fips.h>\n#endif /* HAVE_FIPS_VERSION >= 2 */\n\n#if defined(HAVE_FIPS) && \\\n\t(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n/* included for fips @wc_fips */\n#include <cyassl/ctaocrypt/des3.h>\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* these are required for FIPS and non-FIPS */\nenum {\n    DES_KEY_SIZE        =  8,  /* des                     */\n    DES3_KEY_SIZE       = 24,  /* 3 des ede               */\n    DES_IV_SIZE         =  8,  /* should be the same as DES_BLOCK_SIZE */\n};\n\n\n/* avoid redefinition of structs */\n#if !defined(HAVE_FIPS) || \\\n    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n\nenum {\n    DES_ENC_TYPE    = WC_CIPHER_DES,     /* cipher unique type */\n    DES3_ENC_TYPE   = WC_CIPHER_DES3,    /* cipher unique type */\n\n    DES_BLOCK_SIZE  = 8,\n    DES_KS_SIZE     = 32,    /* internal DES key buffer size */\n\n    DES_ENCRYPTION  = 0,\n    DES_DECRYPTION  = 1\n};\n\n#define DES_IVLEN 8\n#define DES_KEYLEN 8\n#define DES3_IVLEN 8\n#define DES3_KEYLEN 24\n\n\n#if defined(STM32_CRYPTO)\nenum {\n    DES_CBC = 0,\n    DES_ECB = 1\n};\n#endif\n\n\n/* DES encryption and decryption */\ntypedef struct Des {\n    word32 reg[DES_BLOCK_SIZE / sizeof(word32)];      /* for CBC mode */\n    word32 tmp[DES_BLOCK_SIZE / sizeof(word32)];      /* same         */\n    word32 key[DES_KS_SIZE];\n} Des;\n\n\n/* DES3 encryption and decryption */\nstruct Des3 {\n    word32 key[3][DES_KS_SIZE];\n    word32 reg[DES_BLOCK_SIZE / sizeof(word32)];      /* for CBC mode */\n    word32 tmp[DES_BLOCK_SIZE / sizeof(word32)];      /* same         */\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV asyncDev;\n#endif\n#if defined(WOLF_CRYPTO_CB) || \\\n    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES))\n    word32 devKey[DES3_KEYLEN/sizeof(word32)]; /* raw key */\n#endif\n#ifdef WOLF_CRYPTO_CB\n    int    devId;\n    void*  devCtx;\n#endif\n    void* heap;\n};\n\n#ifndef WC_DES3_TYPE_DEFINED\n    typedef struct Des3 Des3;\n    #define WC_DES3_TYPE_DEFINED\n#endif\n#endif /* HAVE_FIPS */\n\n\nWOLFSSL_API int  wc_Des_SetKey(Des* des, const byte* key,\n                               const byte* iv, int dir);\nWOLFSSL_API void wc_Des_SetIV(Des* des, const byte* iv);\nWOLFSSL_API int  wc_Des_CbcEncrypt(Des* des, byte* out,\n                                   const byte* in, word32 sz);\nWOLFSSL_API int  wc_Des_CbcDecrypt(Des* des, byte* out,\n                                   const byte* in, word32 sz);\nWOLFSSL_API int  wc_Des_EcbEncrypt(Des* des, byte* out,\n                                   const byte* in, word32 sz);\nWOLFSSL_API int wc_Des3_EcbEncrypt(Des3* des, byte* out,\n                                   const byte* in, word32 sz);\n\n/* ECB decrypt same process as encrypt but with decrypt key */\n#define wc_Des_EcbDecrypt  wc_Des_EcbEncrypt\n#define wc_Des3_EcbDecrypt wc_Des3_EcbEncrypt\n\nWOLFSSL_API int  wc_Des3_SetKey(Des3* des, const byte* key,\n                                const byte* iv,int dir);\nWOLFSSL_API int  wc_Des3_SetIV(Des3* des, const byte* iv);\nWOLFSSL_API int  wc_Des3_CbcEncrypt(Des3* des, byte* out,\n                                    const byte* in,word32 sz);\nWOLFSSL_API int  wc_Des3_CbcDecrypt(Des3* des, byte* out,\n                                    const byte* in,word32 sz);\n\n/* These are only required when using either:\n  static memory (WOLFSSL_STATIC_MEMORY) or asynchronous (WOLFSSL_ASYNC_CRYPT) */\nWOLFSSL_API int  wc_Des3Init(Des3*, void*, int);\nWOLFSSL_API void wc_Des3Free(Des3*);\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* NO_DES3 */\n#endif /* WOLF_CRYPT_DES3_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/dh.h",
    "content": "/* dh.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/dh.h\n*/\n\n#ifndef WOLF_CRYPT_DH_H\n#define WOLF_CRYPT_DH_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_DH\n\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n    #include <wolfssl/wolfcrypt/fips.h>\n#endif /* HAVE_FIPS_VERSION >= 2 */\n\n#include <wolfssl/wolfcrypt/integer.h>\n#include <wolfssl/wolfcrypt/random.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\ntypedef struct DhParams {\n    #ifdef HAVE_FFDHE_Q\n    const byte* q;\n    word32      q_len;\n    #endif /* HAVE_FFDHE_Q */\n    const byte* p;\n    word32      p_len;\n    const byte* g;\n    word32      g_len;\n} DhParams;\n\n/* Diffie-Hellman Key */\nstruct DhKey {\n    mp_int p, g, q;                         /* group parameters  */\n    void* heap;\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV asyncDev;\n#endif\n};\n\n#ifndef WC_DH_TYPE_DEFINED\n    typedef struct DhKey DhKey;\n    #define WC_DH_TYPE_DEFINED\n#endif\n\n#ifdef HAVE_FFDHE_2048\nWOLFSSL_API const DhParams* wc_Dh_ffdhe2048_Get(void);\n#endif\n#ifdef HAVE_FFDHE_3072\nWOLFSSL_API const DhParams* wc_Dh_ffdhe3072_Get(void);\n#endif\n#ifdef HAVE_FFDHE_4096\nWOLFSSL_API const DhParams* wc_Dh_ffdhe4096_Get(void);\n#endif\n#ifdef HAVE_FFDHE_6144\nWOLFSSL_API const DhParams* wc_Dh_ffdhe6144_Get(void);\n#endif\n#ifdef HAVE_FFDHE_8192\nWOLFSSL_API const DhParams* wc_Dh_ffdhe8192_Get(void);\n#endif\n\nWOLFSSL_API int wc_InitDhKey(DhKey* key);\nWOLFSSL_API int wc_InitDhKey_ex(DhKey* key, void* heap, int devId);\nWOLFSSL_API int wc_FreeDhKey(DhKey* key);\n\nWOLFSSL_API int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng, byte* priv,\n                                 word32* privSz, byte* pub, word32* pubSz);\nWOLFSSL_API int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz,\n                       const byte* priv, word32 privSz, const byte* otherPub,\n                       word32 pubSz);\n\nWOLFSSL_API int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key,\n                           word32);\nWOLFSSL_API int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,\n                        word32 gSz);\nWOLFSSL_API int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz,\n                        const byte* g, word32 gSz, const byte* q, word32 qSz);\nWOLFSSL_API int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz,\n                        const byte* g, word32 gSz, const byte* q, word32 qSz,\n                        int trusted, WC_RNG* rng);\nWOLFSSL_API int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p,\n                            word32* pInOutSz, byte* g, word32* gInOutSz);\nWOLFSSL_API int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz);\nWOLFSSL_API int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,\n                            const byte* prime, word32 primeSz);\nWOLFSSL_API int wc_DhCheckPubValue(const byte* prime, word32 primeSz,\n                                   const byte* pub, word32 pubSz);\nWOLFSSL_API int wc_DhCheckPrivKey(DhKey* key, const byte* priv, word32 pubSz);\nWOLFSSL_API int wc_DhCheckPrivKey_ex(DhKey* key, const byte* priv, word32 pubSz,\n                            const byte* prime, word32 primeSz);\nWOLFSSL_API int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz,\n                        const byte* priv, word32 privSz);\nWOLFSSL_API int wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh);\nWOLFSSL_API int wc_DhExportParamsRaw(DhKey* dh, byte* p, word32* pSz,\n                       byte* q, word32* qSz, byte* g, word32* gSz);\n\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* NO_DH */\n#endif /* WOLF_CRYPT_DH_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/dsa.h",
    "content": "/* dsa.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/dsa.h\n*/\n\n#ifndef WOLF_CRYPT_DSA_H\n#define WOLF_CRYPT_DSA_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_DSA\n\n#include <wolfssl/wolfcrypt/integer.h>\n#include <wolfssl/wolfcrypt/random.h>\n\n/* for DSA reverse compatibility */\n#define InitDsaKey wc_InitDsaKey\n#define FreeDsaKey wc_FreeDsaKey\n#define DsaSign wc_DsaSign\n#define DsaVerify wc_DsaVerify\n#define DsaPublicKeyDecode wc_DsaPublicKeyDecode\n#define DsaPrivateKeyDecode wc_DsaPrivateKeyDecode\n#define DsaKeyToDer wc_DsaKeyToDer\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n\nenum {\n    DSA_PUBLIC   = 0,\n    DSA_PRIVATE  = 1\n};\n\n/* DSA */\ntypedef struct DsaKey {\n    mp_int p, q, g, y, x;\n    int   type;                               /* public or private */\n    void* heap;                               /* memory hint */\n} DsaKey;\n\nWOLFSSL_API int wc_InitDsaKey(DsaKey* key);\nWOLFSSL_API int wc_InitDsaKey_h(DsaKey* key, void* h);\nWOLFSSL_API void wc_FreeDsaKey(DsaKey* key);\nWOLFSSL_API int wc_DsaSign(const byte* digest, byte* out,\n                           DsaKey* key, WC_RNG* rng);\nWOLFSSL_API int wc_DsaVerify(const byte* digest, const byte* sig,\n                             DsaKey* key, int* answer);\nWOLFSSL_API int wc_DsaPublicKeyDecode(const byte* input, word32* inOutIdx,\n                                      DsaKey*, word32);\nWOLFSSL_API int wc_DsaPrivateKeyDecode(const byte* input, word32* inOutIdx,\n                                       DsaKey*, word32);\nWOLFSSL_API int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen);\n\n#ifdef WOLFSSL_KEY_GEN\nWOLFSSL_API int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa);\nWOLFSSL_API int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa);\n#endif\n\n/* raw export functions */\nWOLFSSL_API int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p,\n                                      const char* q, const char* g);\nWOLFSSL_API int wc_DsaImportParamsRawCheck(DsaKey* dsa, const char* p,\n                                      const char* q, const char* g,\n                                      int trusted, WC_RNG* rng);\nWOLFSSL_API int wc_DsaExportParamsRaw(DsaKey* dsa, byte* p, word32* pSz,\n                                      byte* q, word32* qSz, byte* g,\n                                      word32* gSz);\nWOLFSSL_API int wc_DsaExportKeyRaw(DsaKey* dsa, byte* x, word32* xSz, byte* y,\n                                   word32* ySz);\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* NO_DSA */\n#endif /* WOLF_CRYPT_DSA_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/ecc.h",
    "content": "/* ecc.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/ecc.h\n*/\n\n\n#ifndef WOLF_CRYPT_ECC_H\n#define WOLF_CRYPT_ECC_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef HAVE_ECC\n\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n    #include <wolfssl/wolfcrypt/fips.h>\n#endif /* HAVE_FIPS_VERSION >= 2 */\n\n#include <wolfssl/wolfcrypt/integer.h>\n#include <wolfssl/wolfcrypt/random.h>\n\n#ifdef HAVE_X963_KDF\n    #include <wolfssl/wolfcrypt/hash.h>\n#endif\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n    #ifdef WOLFSSL_CERT_GEN\n        #include <wolfssl/wolfcrypt/asn.h>\n    #endif\n#endif\n\n#ifdef WOLFSSL_ATECC508A\n    #include <wolfssl/wolfcrypt/port/atmel/atmel.h>\n#endif /* WOLFSSL_ATECC508A */\n\n#if defined(WOLFSSL_CRYPTOCELL)\n    #include <wolfssl/wolfcrypt/port/arm/cryptoCell.h>\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n\n/* Enable curve B parameter if needed */\n#if defined(HAVE_COMP_KEY) || defined(ECC_CACHE_CURVE)\n    #ifndef USE_ECC_B_PARAM /* Allow someone to force enable */\n        #define USE_ECC_B_PARAM\n    #endif\n#endif\n\n\n/* Use this as the key->idx if a custom ecc_set is used for key->dp */\n#define ECC_CUSTOM_IDX    (-1)\n\n\n/* Determine max ECC bits based on enabled curves */\n#if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)\n    #define MAX_ECC_BITS    521\n#elif defined(HAVE_ECC512)\n    #define MAX_ECC_BITS    512\n#elif defined(HAVE_ECC384)\n    #define MAX_ECC_BITS    384\n#elif defined(HAVE_ECC320)\n    #define MAX_ECC_BITS    320\n#elif !defined(NO_ECC256)\n    #define MAX_ECC_BITS    256\n#elif defined(HAVE_ECC239)\n    #define MAX_ECC_BITS    239\n#elif defined(HAVE_ECC224)\n    #define MAX_ECC_BITS    224\n#elif defined(HAVE_ECC192)\n    #define MAX_ECC_BITS    192\n#elif defined(HAVE_ECC160)\n    #define MAX_ECC_BITS    160\n#elif defined(HAVE_ECC128)\n    #define MAX_ECC_BITS    128\n#elif defined(HAVE_ECC112)\n    #define MAX_ECC_BITS    112\n#endif\n\n/* calculate max ECC bytes */\n#if ((MAX_ECC_BITS * 2) % 8) == 0\n    #define MAX_ECC_BYTES     (MAX_ECC_BITS / 8)\n#else\n    /* add byte if not aligned */\n    #define MAX_ECC_BYTES     ((MAX_ECC_BITS / 8) + 1)\n#endif\n\n#ifndef ECC_MAX_PAD_SZ\n    /* ECC maximum padding size (when MSB is set extra byte required for R and S) */\n    #define ECC_MAX_PAD_SZ 2\n#endif\n\nenum {\n    ECC_PUBLICKEY       = 1,\n    ECC_PRIVATEKEY      = 2,\n    ECC_PRIVATEKEY_ONLY = 3,\n    ECC_MAXNAME     = 16,   /* MAX CURVE NAME LENGTH */\n    SIG_HEADER_SZ   =  7,   /* ECC signature header size (30 81 87 02 42 [R] 02 42 [S]) */\n    ECC_BUFSIZE     = 256,  /* for exported keys temp buffer */\n    ECC_MINSIZE     = 20,   /* MIN Private Key size */\n    ECC_MAXSIZE     = 66,   /* MAX Private Key size */\n    ECC_MAXSIZE_GEN = 74,   /* MAX Buffer size required when generating ECC keys*/\n    ECC_MAX_OID_LEN = 16,\n    ECC_MAX_SIG_SIZE= ((MAX_ECC_BYTES * 2) + ECC_MAX_PAD_SZ + SIG_HEADER_SZ),\n\n    /* max crypto hardware size */\n#ifdef WOLFSSL_ATECC508A\n    ECC_MAX_CRYPTO_HW_SIZE = ATECC_KEY_SIZE, /* from port/atmel/atmel.h */\n    ECC_MAX_CRYPTO_HW_PUBKEY_SIZE = (ATECC_KEY_SIZE*2),\n#elif defined(PLUTON_CRYPTO_ECC)\n    ECC_MAX_CRYPTO_HW_SIZE = 32,\n#elif defined(WOLFSSL_CRYPTOCELL)\n    #ifndef CRYPTOCELL_KEY_SIZE\n        CRYPTOCELL_KEY_SIZE = ECC_MAXSIZE,\n    #endif\n    ECC_MAX_CRYPTO_HW_SIZE = CRYPTOCELL_KEY_SIZE,\n#endif\n\n    /* point compression type */\n    ECC_POINT_COMP_EVEN = 0x02,\n    ECC_POINT_COMP_ODD = 0x03,\n    ECC_POINT_UNCOMP = 0x04,\n\n    /* Shamir's dual add constants */\n    SHAMIR_PRECOMP_SZ = 16,\n\n#ifdef HAVE_PKCS11\n    ECC_MAX_ID_LEN    = 32,\n#endif\n};\n\n/* Curve Types */\ntypedef enum ecc_curve_id {\n    ECC_CURVE_INVALID = -1,\n    ECC_CURVE_DEF = 0, /* NIST or SECP */\n\n    /* NIST Prime Curves */\n    ECC_SECP192R1,\n    ECC_PRIME192V2,\n    ECC_PRIME192V3,\n    ECC_PRIME239V1,\n    ECC_PRIME239V2,\n    ECC_PRIME239V3,\n    ECC_SECP256R1,\n\n    /* SECP Curves */\n    ECC_SECP112R1,\n    ECC_SECP112R2,\n    ECC_SECP128R1,\n    ECC_SECP128R2,\n    ECC_SECP160R1,\n    ECC_SECP160R2,\n    ECC_SECP224R1,\n    ECC_SECP384R1,\n    ECC_SECP521R1,\n\n    /* Koblitz */\n    ECC_SECP160K1,\n    ECC_SECP192K1,\n    ECC_SECP224K1,\n    ECC_SECP256K1,\n\n    /* Brainpool Curves */\n    ECC_BRAINPOOLP160R1,\n    ECC_BRAINPOOLP192R1,\n    ECC_BRAINPOOLP224R1,\n    ECC_BRAINPOOLP256R1,\n    ECC_BRAINPOOLP320R1,\n    ECC_BRAINPOOLP384R1,\n    ECC_BRAINPOOLP512R1,\n\n    /* Twisted Edwards Curves */\n#ifdef HAVE_CURVE25519\n    ECC_X25519,\n#endif\n#ifdef HAVE_X448\n    ECC_X448,\n#endif\n\n#ifdef WOLFSSL_CUSTOM_CURVES\n    ECC_CURVE_CUSTOM,\n#endif\n} ecc_curve_id;\n\n#ifdef HAVE_OID_ENCODING\ntypedef word16 ecc_oid_t;\n#else\ntypedef byte   ecc_oid_t;\n    /* OID encoded with ASN scheme:\n        first element = (oid[0] * 40) + oid[1]\n        if any element > 127 then MSB 0x80 indicates additional byte */\n#endif\n\n/* ECC set type defined a GF(p) curve */\n#ifndef USE_WINDOWS_API\ntypedef struct ecc_set_type {\n    int size;             /* The size of the curve in octets */\n    int id;               /* id of this curve */\n    const char* name;     /* name of this curve */\n    const char* prime;    /* prime that defines the field, curve is in (hex) */\n    const char* Af;       /* fields A param (hex) */\n    const char* Bf;       /* fields B param (hex) */\n    const char* order;    /* order of the curve (hex) */\n    const char* Gx;       /* x coordinate of the base point on curve (hex) */\n    const char* Gy;       /* y coordinate of the base point on curve (hex) */\n    const ecc_oid_t* oid;\n    word32      oidSz;\n    word32      oidSum;    /* sum of encoded OID bytes */\n    int         cofactor;\n} ecc_set_type;\n#else\n/* MSC does something different with the pointers to the arrays than GCC,\n * and it causes the FIPS checksum to fail. In the case of windows builds,\n * store everything as arrays instead of pointers to strings. */\n\n#define MAX_ECC_NAME 16\n#define MAX_ECC_STRING ((MAX_ECC_BYTES * 2) + 1)\n    /* The values are stored as text strings. */\n\ntypedef struct ecc_set_type {\n    int size;             /* The size of the curve in octets */\n    int id;               /* id of this curve */\n    const char name[MAX_ECC_NAME];     /* name of this curve */\n    const char prime[MAX_ECC_STRING];    /* prime that defines the field, curve is in (hex) */\n    const char Af[MAX_ECC_STRING];       /* fields A param (hex) */\n    const char Bf[MAX_ECC_STRING];       /* fields B param (hex) */\n    const char order[MAX_ECC_STRING];    /* order of the curve (hex) */\n    const char Gx[MAX_ECC_STRING];       /* x coordinate of the base point on curve (hex) */\n    const char Gy[MAX_ECC_STRING];       /* y coordinate of the base point on curve (hex) */\n    const ecc_oid_t oid[10];\n    word32      oidSz;\n    word32      oidSum;    /* sum of encoded OID bytes */\n    int         cofactor;\n} ecc_set_type;\n#endif\n\n\n#ifdef ALT_ECC_SIZE\n\n/* Note on ALT_ECC_SIZE:\n * The fast math code uses an array of a fixed size to store the big integers.\n * By default, the array is big enough for RSA keys. There is a size,\n * FP_MAX_BITS which can be used to make the array smaller when one wants ECC\n * but not RSA. Some people want fast math sized for both RSA and ECC, where\n * ECC won't use as much as RSA. The flag ALT_ECC_SIZE switches in an alternate\n * ecc_point structure that uses an alternate fp_int that has a shorter array\n * of fp_digits.\n *\n * Now, without ALT_ECC_SIZE, the ecc_point has three single item arrays of\n * mp_ints for the components of the point. With ALT_ECC_SIZE, the components\n * of the point are pointers that are set to each of a three item array of\n * alt_fp_ints. While an mp_int will have 4096 bits of digit inside the\n * structure, the alt_fp_int will only have 528 bits. A size value was added\n * in the ALT case, as well, and is set by mp_init() and alt_fp_init(). The\n * functions fp_zero() and fp_copy() use the size parameter. An int needs to\n * be initialized before using it instead of just fp_zeroing it, the init will\n * call zero. FP_MAX_BITS_ECC defaults to 528, but can be set to change the\n * number of bits used in the alternate FP_INT.\n *\n * Do not enable ALT_ECC_SIZE and disable fast math in the configuration.\n */\n\n#ifndef USE_FAST_MATH\n    #error USE_FAST_MATH must be defined to use ALT_ECC_SIZE\n#endif\n\n/* determine max bits required for ECC math */\n#ifndef FP_MAX_BITS_ECC\n    /* check alignment */\n    #if ((MAX_ECC_BITS * 2) % DIGIT_BIT) == 0\n        /* max bits is double */\n        #define FP_MAX_BITS_ECC     (MAX_ECC_BITS * 2)\n    #else\n        /* max bits is doubled, plus one digit of fudge */\n        #define FP_MAX_BITS_ECC     ((MAX_ECC_BITS * 2) + DIGIT_BIT)\n    #endif\n#else\n    /* verify alignment */\n    #if FP_MAX_BITS_ECC % CHAR_BIT\n       #error FP_MAX_BITS_ECC must be a multiple of CHAR_BIT\n    #endif\n#endif\n\n/* determine buffer size */\n#define FP_SIZE_ECC    (FP_MAX_BITS_ECC/DIGIT_BIT)\n\n\n/* This needs to match the size of the fp_int struct, except the\n * fp_digit array will be shorter. */\ntypedef struct alt_fp_int {\n    int used, sign, size;\n    mp_digit dp[FP_SIZE_ECC];\n} alt_fp_int;\n#endif /* ALT_ECC_SIZE */\n\n#ifndef WC_ECCKEY_TYPE_DEFINED\n    typedef struct ecc_key ecc_key;\n    #define WC_ECCKEY_TYPE_DEFINED\n#endif\n\n\n/* A point on an ECC curve, stored in Jacbobian format such that (x,y,z) =>\n   (x/z^2, y/z^3, 1) when interpreted as affine */\ntypedef struct {\n#ifndef ALT_ECC_SIZE\n    mp_int x[1];        /* The x coordinate */\n    mp_int y[1];        /* The y coordinate */\n    mp_int z[1];        /* The z coordinate */\n#else\n    mp_int* x;        /* The x coordinate */\n    mp_int* y;        /* The y coordinate */\n    mp_int* z;        /* The z coordinate */\n    alt_fp_int xyz[3];\n#endif\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    ecc_key* key;\n#endif\n} ecc_point;\n\n/* ECC Flags */\nenum {\n    WC_ECC_FLAG_NONE = 0x00,\n#ifdef HAVE_ECC_CDH\n    WC_ECC_FLAG_COFACTOR = 0x01,\n#endif\n};\n\n/* An ECC Key */\nstruct ecc_key {\n    int type;           /* Public or Private */\n    int idx;            /* Index into the ecc_sets[] for the parameters of\n                           this curve if -1, this key is using user supplied\n                           curve in dp */\n    int    state;\n    word32 flags;\n    const ecc_set_type* dp;     /* domain parameters, either points to NIST\n                                   curves (idx >= 0) or user supplied */\n#ifdef WOLFSSL_CUSTOM_CURVES\n    int deallocSet;\n#endif\n    void* heap;         /* heap hint */\n    ecc_point pubkey;   /* public key */\n    mp_int    k;        /* private key */\n#ifdef WOLFSSL_ATECC508A\n    int  slot;        /* Key Slot Number (-1 unknown) */\n    byte pubkey_raw[ECC_MAX_CRYPTO_HW_PUBKEY_SIZE];\n#endif\n#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)\n    int devId;\n#endif\n#ifdef WOLFSSL_ASYNC_CRYPT\n    mp_int* r;          /* sign/verify temps */\n    mp_int* s;\n    WC_ASYNC_DEV asyncDev;\n    #ifdef HAVE_CAVIUM_V\n        mp_int* e;      /* Sign, Verify and Shared Secret */\n        mp_int* signK;\n    #endif\n    #ifdef WOLFSSL_CERT_GEN\n        CertSignCtx certSignCtx; /* context info for cert sign (MakeSignature) */\n    #endif\n#endif /* WOLFSSL_ASYNC_CRYPT */\n#ifdef HAVE_PKCS11\n    byte id[ECC_MAX_ID_LEN];\n    int  idLen;\n#endif\n#if defined(WOLFSSL_CRYPTOCELL)\n    ecc_context_t ctx;\n#endif\n\n#ifdef WOLFSSL_ECDSA_SET_K\n    mp_int *sign_k;\n#endif\n\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    mp_int* t1;\n    mp_int* t2;\n#ifdef ALT_ECC_SIZE\n    mp_int* x;\n    mp_int* y;\n    mp_int* z;\n#endif\n#endif\n};\n\n\nWOLFSSL_ABI WOLFSSL_API ecc_key* wc_ecc_key_new(void*);\nWOLFSSL_ABI WOLFSSL_API void wc_ecc_key_free(ecc_key*);\n\n\n/* ECC predefined curve sets  */\nextern const ecc_set_type ecc_sets[];\n\nWOLFSSL_API\nconst char* wc_ecc_get_name(int curve_id);\n\n#ifndef WOLFSSL_ATECC508A\n\n#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL\n    #define ECC_API    WOLFSSL_API\n#else\n    #define ECC_API    WOLFSSL_LOCAL\n#endif\n\nECC_API int ecc_mul2add(ecc_point* A, mp_int* kA,\n                ecc_point* B, mp_int* kB,\n                ecc_point* C, mp_int* a, mp_int* modulus, void* heap);\n\nECC_API int ecc_map(ecc_point*, mp_int*, mp_digit);\nECC_API int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,\n                                     mp_int* a, mp_int* modulus, mp_digit mp);\nECC_API int ecc_projective_dbl_point(ecc_point* P, ecc_point* R, mp_int* a,\n                                     mp_int* modulus, mp_digit mp);\n\n#endif\n\nWOLFSSL_API\nint wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key);\nWOLFSSL_ABI WOLFSSL_API\nint wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id);\nWOLFSSL_API\nint wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut);\nWOLFSSL_API\nint wc_ecc_check_key(ecc_key* key);\nWOLFSSL_API\nint wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime);\n\n#ifdef HAVE_ECC_DHE\nWOLFSSL_API\nint wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,\n                      word32* outlen);\nWOLFSSL_LOCAL\nint wc_ecc_shared_secret_gen(ecc_key* private_key, ecc_point* point,\n                             byte* out, word32 *outlen);\nWOLFSSL_API\nint wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,\n                             byte* out, word32 *outlen);\n\n#if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL)\n#define wc_ecc_shared_secret_ssh wc_ecc_shared_secret\n#else\n#define wc_ecc_shared_secret_ssh wc_ecc_shared_secret_ex /* For backwards compat */\n#endif\n\n#endif /* HAVE_ECC_DHE */\n\n#ifdef HAVE_ECC_SIGN\nWOLFSSL_ABI WOLFSSL_API\nint wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,\n                     WC_RNG* rng, ecc_key* key);\nWOLFSSL_API\nint wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,\n                        ecc_key* key, mp_int *r, mp_int *s);\n#ifdef WOLFSSL_ECDSA_SET_K\nWOLFSSL_API\nint wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key);\n#endif\n#endif /* HAVE_ECC_SIGN */\n\n#ifdef HAVE_ECC_VERIFY\nWOLFSSL_API\nint wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,\n                    word32 hashlen, int* stat, ecc_key* key);\nWOLFSSL_API\nint wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,\n                          word32 hashlen, int* stat, ecc_key* key);\n#endif /* HAVE_ECC_VERIFY */\n\nWOLFSSL_API\nint wc_ecc_init(ecc_key* key);\nWOLFSSL_ABI WOLFSSL_API\nint wc_ecc_init_ex(ecc_key* key, void* heap, int devId);\n#ifdef HAVE_PKCS11\nWOLFSSL_API\nint wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,\n                   int devId);\n#endif\n#ifdef WOLFSSL_CUSTOM_CURVES\nWOLFSSL_LOCAL\nvoid wc_ecc_free_curve(const ecc_set_type* curve, void* heap);\n#endif\nWOLFSSL_ABI WOLFSSL_API\nint wc_ecc_free(ecc_key* key);\nWOLFSSL_API\nint wc_ecc_set_flags(ecc_key* key, word32 flags);\nWOLFSSL_API\nvoid wc_ecc_fp_free(void);\n\nWOLFSSL_API\nint wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id);\n\nWOLFSSL_API\nint wc_ecc_is_valid_idx(int n);\nWOLFSSL_API\nint wc_ecc_get_curve_idx(int curve_id);\nWOLFSSL_API\nint wc_ecc_get_curve_id(int curve_idx);\n#define wc_ecc_get_curve_name_from_id wc_ecc_get_name\nWOLFSSL_API\nint wc_ecc_get_curve_size_from_id(int curve_id);\n\nWOLFSSL_API\nint wc_ecc_get_curve_idx_from_name(const char* curveName);\nWOLFSSL_API\nint wc_ecc_get_curve_size_from_name(const char* curveName);\nWOLFSSL_API\nint wc_ecc_get_curve_id_from_name(const char* curveName);\nWOLFSSL_API\nint wc_ecc_get_curve_id_from_params(int fieldSize,\n        const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,\n        const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,\n        const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor);\nWOLFSSL_API\nint wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp);\n\nWOLFSSL_API\nint wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len);\n\nWOLFSSL_API const ecc_set_type* wc_ecc_get_curve_params(int curve_idx);\n\nWOLFSSL_API\necc_point* wc_ecc_new_point(void);\nWOLFSSL_API\necc_point* wc_ecc_new_point_h(void* h);\nWOLFSSL_API\nvoid wc_ecc_del_point(ecc_point* p);\nWOLFSSL_API\nvoid wc_ecc_del_point_h(ecc_point* p, void* h);\nWOLFSSL_API\nint wc_ecc_copy_point(ecc_point* p, ecc_point *r);\nWOLFSSL_API\nint wc_ecc_cmp_point(ecc_point* a, ecc_point *b);\nWOLFSSL_API\nint wc_ecc_point_is_at_infinity(ecc_point *p);\n\n#ifndef WOLFSSL_ATECC508A\nWOLFSSL_API\nint wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R,\n                  mp_int* a, mp_int* modulus, int map);\nWOLFSSL_LOCAL\nint wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,\n                  mp_int* a, mp_int* modulus, int map, void* heap);\n#endif /* !WOLFSSL_ATECC508A */\n\n\n#ifdef HAVE_ECC_KEY_EXPORT\n/* ASN key helpers */\nWOLFSSL_API\nint wc_ecc_export_x963(ecc_key*, byte* out, word32* outLen);\nWOLFSSL_API\nint wc_ecc_export_x963_ex(ecc_key*, byte* out, word32* outLen, int compressed);\n    /* extended functionality with compressed option */\n#endif /* HAVE_ECC_KEY_EXPORT */\n\n#ifdef HAVE_ECC_KEY_IMPORT\nWOLFSSL_API\nint wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key);\nWOLFSSL_API\nint wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,\n                          int curve_id);\nWOLFSSL_API\nint wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,\n                           word32 pubSz, ecc_key* key);\nWOLFSSL_API\nint wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,\n                const byte* pub, word32 pubSz, ecc_key* key, int curve_id);\nWOLFSSL_API\nint wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen);\nWOLFSSL_API\nint wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,\n    byte* out, word32* outlen);\nWOLFSSL_API\nint wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,\n                   byte* s, word32* sLen);\nWOLFSSL_API\nint wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,\n                   const char* d, const char* curveName);\nWOLFSSL_API\nint wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,\n                   const char* d, int curve_id);\nWOLFSSL_API\nint wc_ecc_import_unsigned(ecc_key* key, byte* qx, byte* qy,\n                   byte* d, int curve_id);\n#endif /* HAVE_ECC_KEY_IMPORT */\n\n#ifdef HAVE_ECC_KEY_EXPORT\nWOLFSSL_API\nint wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,\n                     byte* qy, word32* qyLen, byte* d, word32* dLen,\n                     int encType);\nWOLFSSL_API\nint wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen);\nWOLFSSL_API\nint wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,\n                             byte* qy, word32* qyLen);\nWOLFSSL_API\nint wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,\n                              byte* qy, word32* qyLen, byte* d, word32* dLen);\n#endif /* HAVE_ECC_KEY_EXPORT */\n\n#ifdef HAVE_ECC_KEY_EXPORT\n\nWOLFSSL_API\nint wc_ecc_export_point_der(const int curve_idx, ecc_point* point,\n                            byte* out, word32* outLen);\n#endif /* HAVE_ECC_KEY_EXPORT */\n\n\n#ifdef HAVE_ECC_KEY_IMPORT\nWOLFSSL_API\nint wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,\n                            ecc_point* point);\n#endif /* HAVE_ECC_KEY_IMPORT */\n\n/* size helper */\nWOLFSSL_API\nint wc_ecc_size(ecc_key* key);\nWOLFSSL_API\nint wc_ecc_sig_size_calc(int sz);\nWOLFSSL_API\nint wc_ecc_sig_size(ecc_key* key);\n\nWOLFSSL_API\nint wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz);\n\n#ifdef WOLFSSL_CUSTOM_CURVES\n    WOLFSSL_API\n    int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp);\n#endif\n\n#ifdef HAVE_ECC_ENCRYPT\n/* ecc encrypt */\n\nenum ecEncAlgo {\n    ecAES_128_CBC = 1,  /* default */\n    ecAES_256_CBC = 2\n};\n\nenum ecKdfAlgo {\n    ecHKDF_SHA256 = 1,  /* default */\n    ecHKDF_SHA1   = 2\n};\n\nenum ecMacAlgo {\n    ecHMAC_SHA256 = 1,  /* default */\n    ecHMAC_SHA1   = 2\n};\n\nenum {\n    KEY_SIZE_128     = 16,\n    KEY_SIZE_256     = 32,\n    IV_SIZE_64       =  8,\n    IV_SIZE_128      = 16,\n    EXCHANGE_SALT_SZ = 16,\n    EXCHANGE_INFO_SZ = 23\n};\n\nenum ecFlags {\n    REQ_RESP_CLIENT = 1,\n    REQ_RESP_SERVER = 2\n};\n\n\ntypedef struct ecEncCtx ecEncCtx;\n\nWOLFSSL_API\necEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng);\nWOLFSSL_API\necEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap);\nWOLFSSL_API\nvoid wc_ecc_ctx_free(ecEncCtx*);\nWOLFSSL_API\nint wc_ecc_ctx_reset(ecEncCtx*, WC_RNG*);  /* reset for use again w/o alloc/free */\n\nWOLFSSL_API\nconst byte* wc_ecc_ctx_get_own_salt(ecEncCtx*);\nWOLFSSL_API\nint wc_ecc_ctx_set_peer_salt(ecEncCtx*, const byte* salt);\nWOLFSSL_API\nint wc_ecc_ctx_set_info(ecEncCtx*, const byte* info, int sz);\n\nWOLFSSL_API\nint wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,\n                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx);\nWOLFSSL_API\nint wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,\n                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx);\n\n#endif /* HAVE_ECC_ENCRYPT */\n\n#ifdef HAVE_X963_KDF\nWOLFSSL_API int wc_X963_KDF(enum wc_HashType type, const byte* secret,\n                word32 secretSz, const byte* sinfo, word32 sinfoSz,\n                byte* out, word32 outSz);\n#endif\n\n#ifdef ECC_CACHE_CURVE\nWOLFSSL_API int wc_ecc_curve_cache_init(void);\nWOLFSSL_API void wc_ecc_curve_cache_free(void);\n#endif\n\nWOLFSSL_API\nint wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order);\n\n#ifdef __cplusplus\n    }    /* extern \"C\" */\n#endif\n\n#endif /* HAVE_ECC */\n#endif /* WOLF_CRYPT_ECC_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/ed25519.h",
    "content": "/* ed25519.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/ed25519.h\n*/\n\n\n#ifndef WOLF_CRYPT_ED25519_H\n#define WOLF_CRYPT_ED25519_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef HAVE_ED25519\n\n#include <wolfssl/wolfcrypt/fe_operations.h>\n#include <wolfssl/wolfcrypt/ge_operations.h>\n#include <wolfssl/wolfcrypt/random.h>\n#include <wolfssl/wolfcrypt/sha512.h>\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n\n/* info about EdDSA curve specifically ed25519, defined as an elliptic curve\n   over GF(p) */\n/*\n    32,                key size\n    \"ED25519\",         curve name\n    \"2^255-19\",        prime number\n    \"SHA512\",          hash function\n    \"-121665/121666\",  value of d\n*/\n\n#define ED25519_KEY_SIZE     32 /* private key only */\n#define ED25519_SIG_SIZE     64\n\n#define ED25519_PUB_KEY_SIZE 32 /* compressed */\n/* both private and public key */\n#define ED25519_PRV_KEY_SIZE (ED25519_PUB_KEY_SIZE+ED25519_KEY_SIZE)\n\n\nenum {\n    Ed25519    = -1,\n    Ed25519ctx = 0,\n    Ed25519ph  = 1,\n};\n\n#ifndef WC_ED25519KEY_TYPE_DEFINED\n    typedef struct ed25519_key ed25519_key;\n    #define WC_ED25519KEY_TYPE_DEFINED\n#endif\n\n/* An ED25519 Key */\nstruct ed25519_key {\n    byte    p[ED25519_PUB_KEY_SIZE]; /* compressed public key */\n    byte    k[ED25519_PRV_KEY_SIZE]; /* private key : 32 secret -- 32 public */\n#ifdef FREESCALE_LTC_ECC\n    /* uncompressed point coordinates */\n    byte pointX[ED25519_KEY_SIZE]; /* recovered X coordinate */\n    byte pointY[ED25519_KEY_SIZE]; /* Y coordinate is the public key with The most significant bit of the final octet always zero. */\n#endif\n    word16 pubKeySet:1;\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV asyncDev;\n#endif\n};\n\n\nWOLFSSL_API\nint wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey,\n                           word32 pubKeySz);\nWOLFSSL_API\nint wc_ed25519_make_key(WC_RNG* rng, int keysize, ed25519_key* key);\nWOLFSSL_API\nint wc_ed25519_sign_msg(const byte* in, word32 inLen, byte* out,\n                        word32 *outLen, ed25519_key* key);\nWOLFSSL_API\nint wc_ed25519ctx_sign_msg(const byte* in, word32 inLen, byte* out,\n                           word32 *outLen, ed25519_key* key,\n                           const byte* context, byte contextLen);\nWOLFSSL_API\nint wc_ed25519ph_sign_hash(const byte* hash, word32 hashLen, byte* out,\n                           word32 *outLen, ed25519_key* key,\n                           const byte* context, byte contextLen);\nWOLFSSL_API\nint wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out,\n                          word32 *outLen, ed25519_key* key, const byte* context,\n                          byte contextLen);\nWOLFSSL_API\nint wc_ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg,\n                          word32 msgLen, int* stat, ed25519_key* key);\nWOLFSSL_API\nint wc_ed25519ctx_verify_msg(const byte* sig, word32 sigLen, const byte* msg,\n                             word32 msgLen, int* stat, ed25519_key* key,\n                             const byte* context, byte contextLen);\nWOLFSSL_API\nint wc_ed25519ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash,\n                             word32 hashLen, int* stat, ed25519_key* key,\n                             const byte* context, byte contextLen);\nWOLFSSL_API\nint wc_ed25519ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,\n                            word32 msgLen, int* stat, ed25519_key* key,\n                            const byte* context, byte contextLen);\nWOLFSSL_API\nint wc_ed25519_init(ed25519_key* key);\nWOLFSSL_API\nvoid wc_ed25519_free(ed25519_key* key);\nWOLFSSL_API\nint wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key);\nWOLFSSL_API\nint wc_ed25519_import_private_only(const byte* priv, word32 privSz,\n                                                              ed25519_key* key);\nWOLFSSL_API\nint wc_ed25519_import_private_key(const byte* priv, word32 privSz,\n                               const byte* pub, word32 pubSz, ed25519_key* key);\nWOLFSSL_API\nint wc_ed25519_export_public(ed25519_key*, byte* out, word32* outLen);\nWOLFSSL_API\nint wc_ed25519_export_private_only(ed25519_key* key, byte* out, word32* outLen);\nWOLFSSL_API\nint wc_ed25519_export_private(ed25519_key* key, byte* out, word32* outLen);\nWOLFSSL_API\nint wc_ed25519_export_key(ed25519_key* key,\n                          byte* priv, word32 *privSz,\n                          byte* pub, word32 *pubSz);\n\nWOLFSSL_API\nint wc_ed25519_check_key(ed25519_key* key);\n\n/* size helper */\nWOLFSSL_API\nint wc_ed25519_size(ed25519_key* key);\nWOLFSSL_API\nint wc_ed25519_priv_size(ed25519_key* key);\nWOLFSSL_API\nint wc_ed25519_pub_size(ed25519_key* key);\nWOLFSSL_API\nint wc_ed25519_sig_size(ed25519_key* key);\n\n#ifdef __cplusplus\n    }    /* extern \"C\" */\n#endif\n\n#endif /* HAVE_ED25519 */\n#endif /* WOLF_CRYPT_ED25519_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/error-crypt.h",
    "content": "/* error-crypt.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/error-crypt.h\n*/\n\n#ifndef WOLF_CRYPT_ERROR_H\n#define WOLF_CRYPT_ERROR_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#if defined(HAVE_FIPS) && \\\n    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n\t#include <cyassl/ctaocrypt/error-crypt.h>\n#endif /* HAVE_FIPS V1 */\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n\n/* error codes, add string for new errors !!! */\nenum {\n    MAX_CODE_E         = -100,  /* errors -101 - -299 */\n    OPEN_RAN_E         = -101,  /* opening random device error */\n    READ_RAN_E         = -102,  /* reading random device error */\n    WINCRYPT_E         = -103,  /* windows crypt init error */\n    CRYPTGEN_E         = -104,  /* windows crypt generation error */\n    RAN_BLOCK_E        = -105,  /* reading random device would block */\n    BAD_MUTEX_E        = -106,  /* Bad mutex operation */\n    WC_TIMEOUT_E       = -107,  /* timeout error */\n    WC_PENDING_E       = -108,  /* wolfCrypt operation pending (would block) */\n    WC_NOT_PENDING_E   = -109,  /* wolfCrypt operation not pending */\n\n    MP_INIT_E          = -110,  /* mp_init error state */\n    MP_READ_E          = -111,  /* mp_read error state */\n    MP_EXPTMOD_E       = -112,  /* mp_exptmod error state */\n    MP_TO_E            = -113,  /* mp_to_xxx error state, can't convert */\n    MP_SUB_E           = -114,  /* mp_sub error state, can't subtract */\n    MP_ADD_E           = -115,  /* mp_add error state, can't add */\n    MP_MUL_E           = -116,  /* mp_mul error state, can't multiply */\n    MP_MULMOD_E        = -117,  /* mp_mulmod error state, can't multiply mod */\n    MP_MOD_E           = -118,  /* mp_mod error state, can't mod */\n    MP_INVMOD_E        = -119,  /* mp_invmod error state, can't inv mod */\n    MP_CMP_E           = -120,  /* mp_cmp error state */\n    MP_ZERO_E          = -121,  /* got a mp zero result, not expected */\n\n    MEMORY_E           = -125,  /* out of memory error */\n    VAR_STATE_CHANGE_E = -126,  /* var state modified by different thread */\n\n    RSA_WRONG_TYPE_E   = -130,  /* RSA wrong block type for RSA function */\n    RSA_BUFFER_E       = -131,  /* RSA buffer error, output too small or\n                                   input too large */\n    BUFFER_E           = -132,  /* output buffer too small or input too large */\n    ALGO_ID_E          = -133,  /* setting algo id error */\n    PUBLIC_KEY_E       = -134,  /* setting public key error */\n    DATE_E             = -135,  /* setting date validity error */\n    SUBJECT_E          = -136,  /* setting subject name error */\n    ISSUER_E           = -137,  /* setting issuer  name error */\n    CA_TRUE_E          = -138,  /* setting CA basic constraint true error */\n    EXTENSIONS_E       = -139,  /* setting extensions error */\n\n    ASN_PARSE_E        = -140,  /* ASN parsing error, invalid input */\n    ASN_VERSION_E      = -141,  /* ASN version error, invalid number */\n    ASN_GETINT_E       = -142,  /* ASN get big int error, invalid data */\n    ASN_RSA_KEY_E      = -143,  /* ASN key init error, invalid input */\n    ASN_OBJECT_ID_E    = -144,  /* ASN object id error, invalid id */\n    ASN_TAG_NULL_E     = -145,  /* ASN tag error, not null */\n    ASN_EXPECT_0_E     = -146,  /* ASN expect error, not zero */\n    ASN_BITSTR_E       = -147,  /* ASN bit string error, wrong id */\n    ASN_UNKNOWN_OID_E  = -148,  /* ASN oid error, unknown sum id */\n    ASN_DATE_SZ_E      = -149,  /* ASN date error, bad size */\n    ASN_BEFORE_DATE_E  = -150,  /* ASN date error, current date before */\n    ASN_AFTER_DATE_E   = -151,  /* ASN date error, current date after */\n    ASN_SIG_OID_E      = -152,  /* ASN signature error, mismatched oid */\n    ASN_TIME_E         = -153,  /* ASN time error, unknown time type */\n    ASN_INPUT_E        = -154,  /* ASN input error, not enough data */\n    ASN_SIG_CONFIRM_E  = -155,  /* ASN sig error, confirm failure */\n    ASN_SIG_HASH_E     = -156,  /* ASN sig error, unsupported hash type */\n    ASN_SIG_KEY_E      = -157,  /* ASN sig error, unsupported key type */\n    ASN_DH_KEY_E       = -158,  /* ASN key init error, invalid input */\n    ASN_NTRU_KEY_E     = -159,  /* ASN ntru key decode error, invalid input */\n    ASN_CRIT_EXT_E     = -160,  /* ASN unsupported critical extension */\n    ASN_ALT_NAME_E     = -161,  /* ASN alternate name error */\n    ASN_NO_PEM_HEADER  = -162,  /* ASN no PEM header found */\n\n    ECC_BAD_ARG_E      = -170,  /* ECC input argument of wrong type */\n    ASN_ECC_KEY_E      = -171,  /* ASN ECC bad input */\n    ECC_CURVE_OID_E    = -172,  /* Unsupported ECC OID curve type */\n    BAD_FUNC_ARG       = -173,  /* Bad function argument provided */\n    NOT_COMPILED_IN    = -174,  /* Feature not compiled in */\n    UNICODE_SIZE_E     = -175,  /* Unicode password too big */\n    NO_PASSWORD        = -176,  /* no password provided by user */\n    ALT_NAME_E         = -177,  /* alt name size problem, too big */\n    BAD_OCSP_RESPONDER = -178,  /* missing key usage extensions */\n\n    AES_GCM_AUTH_E     = -180,  /* AES-GCM Authentication check failure */\n    AES_CCM_AUTH_E     = -181,  /* AES-CCM Authentication check failure */\n\n    ASYNC_INIT_E       = -182,  /* Async Init type error */\n\n    COMPRESS_INIT_E    = -183,  /* Compress init error */\n    COMPRESS_E         = -184,  /* Compress error */\n    DECOMPRESS_INIT_E  = -185,  /* DeCompress init error */\n    DECOMPRESS_E       = -186,  /* DeCompress error */\n\n    BAD_ALIGN_E         = -187,  /* Bad alignment for operation, no alloc */\n    ASN_NO_SIGNER_E     = -188,  /* ASN no signer to confirm failure */\n    ASN_CRL_CONFIRM_E   = -189,  /* ASN CRL signature confirm failure */\n    ASN_CRL_NO_SIGNER_E = -190,  /* ASN CRL no signer to confirm failure */\n    ASN_OCSP_CONFIRM_E  = -191,  /* ASN OCSP signature confirm failure */\n\n    BAD_STATE_E         = -192,  /* Bad state operation */\n    BAD_PADDING_E       = -193,  /* Bad padding, msg not correct length  */\n\n    REQ_ATTRIBUTE_E     = -194,  /* setting cert request attributes error */\n\n    PKCS7_OID_E         = -195,  /* PKCS#7, mismatched OID error */\n    PKCS7_RECIP_E       = -196,  /* PKCS#7, recipient error */\n    FIPS_NOT_ALLOWED_E  = -197,  /* FIPS not allowed error */\n    ASN_NAME_INVALID_E  = -198,  /* ASN name constraint error */\n\n    RNG_FAILURE_E       = -199,  /* RNG Failed, Reinitialize */\n    HMAC_MIN_KEYLEN_E   = -200,  /* FIPS Mode HMAC Minimum Key Length error */\n    RSA_PAD_E           = -201,  /* RSA Padding Error */\n    LENGTH_ONLY_E       = -202,  /* Returning output length only */\n\n    IN_CORE_FIPS_E      = -203,  /* In Core Integrity check failure */\n    AES_KAT_FIPS_E      = -204,  /* AES KAT failure */\n    DES3_KAT_FIPS_E     = -205,  /* DES3 KAT failure */\n    HMAC_KAT_FIPS_E     = -206,  /* HMAC KAT failure */\n    RSA_KAT_FIPS_E      = -207,  /* RSA KAT failure */\n    DRBG_KAT_FIPS_E     = -208,  /* HASH DRBG KAT failure */\n    DRBG_CONT_FIPS_E    = -209,  /* HASH DRBG Continuous test failure */\n    AESGCM_KAT_FIPS_E   = -210,  /* AESGCM KAT failure */\n    THREAD_STORE_KEY_E  = -211,  /* Thread local storage key create failure */\n    THREAD_STORE_SET_E  = -212,  /* Thread local storage key set failure */\n\n    MAC_CMP_FAILED_E    = -213,  /* MAC comparison failed */\n    IS_POINT_E          = -214,  /* ECC is point on curve failed */\n    ECC_INF_E           = -215,  /* ECC point infinity error */\n    ECC_PRIV_KEY_E      = -216,  /* ECC private key not valid error */\n    ECC_OUT_OF_RANGE_E  = -217,  /* ECC key component out of range */\n\n    SRP_CALL_ORDER_E    = -218,  /* SRP function called in the wrong order. */\n    SRP_VERIFY_E        = -219,  /* SRP proof verification failed. */\n    SRP_BAD_KEY_E       = -220,  /* SRP bad ephemeral values. */\n\n    ASN_NO_SKID         = -221,  /* ASN no Subject Key Identifier found */\n    ASN_NO_AKID         = -222,  /* ASN no Authority Key Identifier found */\n    ASN_NO_KEYUSAGE     = -223,  /* ASN no Key Usage found */\n    SKID_E              = -224,  /* setting Subject Key Identifier error */\n    AKID_E              = -225,  /* setting Authority Key Identifier error */\n    KEYUSAGE_E          = -226,  /* Bad Key Usage value */\n    CERTPOLICIES_E      = -227,  /* setting Certificate Policies error */\n\n    WC_INIT_E           = -228,  /* wolfcrypt failed to initialize */\n    SIG_VERIFY_E        = -229,  /* wolfcrypt signature verify error */\n    BAD_COND_E          = -230,  /* Bad condition variable operation */\n    SIG_TYPE_E          = -231,  /* Signature Type not enabled/available */\n    HASH_TYPE_E         = -232,  /* Hash Type not enabled/available */\n\n    WC_KEY_SIZE_E       = -234,  /* Key size error, either too small or large */\n    ASN_COUNTRY_SIZE_E  = -235,  /* ASN Cert Gen, invalid country code size */\n    MISSING_RNG_E       = -236,  /* RNG required but not provided */\n    ASN_PATHLEN_SIZE_E  = -237,  /* ASN CA path length too large error */\n    ASN_PATHLEN_INV_E   = -238,  /* ASN CA path length inversion error */\n\n    BAD_KEYWRAP_ALG_E   = -239,\n    BAD_KEYWRAP_IV_E    = -240,  /* Decrypted AES key wrap IV incorrect */\n    WC_CLEANUP_E        = -241,  /* wolfcrypt cleanup failed */\n    ECC_CDH_KAT_FIPS_E  = -242,  /* ECC CDH Known Answer Test failure */\n    DH_CHECK_PUB_E      = -243,  /* DH Check Pub Key error */\n    BAD_PATH_ERROR      = -244,  /* Bad path for opendir */\n\n    ASYNC_OP_E          = -245,  /* Async operation error */\n\n    ECC_PRIVATEONLY_E   = -246,  /* Invalid use of private only ECC key*/\n    EXTKEYUSAGE_E       = -247,  /* Bad Extended Key Usage value */\n    WC_HW_E             = -248,  /* Error with hardware crypto use */\n    WC_HW_WAIT_E        = -249,  /* Hardware waiting on resource */\n\n    PSS_SALTLEN_E       = -250,  /* PSS length of salt is too long for hash */\n    PRIME_GEN_E         = -251,  /* Failure finding a prime. */\n    BER_INDEF_E         = -252,  /* Cannot decode indefinite length BER. */\n    RSA_OUT_OF_RANGE_E  = -253,  /* Ciphertext to decrypt out of range. */\n    RSAPSS_PAT_FIPS_E   = -254,  /* RSA-PSS PAT failure */\n    ECDSA_PAT_FIPS_E    = -255,  /* ECDSA PAT failure */\n    DH_KAT_FIPS_E       = -256,  /* DH KAT failure */\n    AESCCM_KAT_FIPS_E   = -257,  /* AESCCM KAT failure */\n    SHA3_KAT_FIPS_E     = -258,  /* SHA-3 KAT failure */\n    ECDHE_KAT_FIPS_E    = -259,  /* ECDHE KAT failure */\n    AES_GCM_OVERFLOW_E  = -260,  /* AES-GCM invocation counter overflow. */\n    AES_CCM_OVERFLOW_E  = -261,  /* AES-CCM invocation counter overflow. */\n    RSA_KEY_PAIR_E      = -262,  /* RSA Key Pair-Wise Consistency check fail. */\n    DH_CHECK_PRIV_E     = -263,  /* DH Check Priv Key error */\n\n    WC_AFALG_SOCK_E     = -264,  /* AF_ALG socket error */\n    WC_DEVCRYPTO_E      = -265,  /* /dev/crypto error */\n\n    ZLIB_INIT_ERROR     = -266,   /* zlib init error  */\n    ZLIB_COMPRESS_ERROR = -267,   /* zlib compression error  */\n    ZLIB_DECOMPRESS_ERROR = -268,  /* zlib decompression error  */\n\n    PKCS7_NO_SIGNER_E   = -269,  /* No signer in PKCS#7 signed data msg */\n    WC_PKCS7_WANT_READ_E= -270,  /* PKCS7 operations wants more input */\n\n    CRYPTOCB_UNAVAILABLE= -271,  /* Crypto callback unavailable */\n    PKCS7_SIGNEEDS_CHECK= -272,  /* signature needs verified by caller */\n    PSS_SALTLEN_RECOVER_E=-273,  /* PSS slat length not recoverable */\n\n    WC_LAST_E           = -273,  /* Update this to indicate last error */\n    MIN_CODE_E          = -300   /* errors -101 - -299 */\n\n    /* add new companion error id strings for any new error codes\n       wolfcrypt/src/error.c !!! */\n};\n\n\n#ifdef NO_ERROR_STRINGS\n    #define wc_GetErrorString(error) \"no support for error strings built in\"\n    #define wc_ErrorString(err, buf) \\\n        (void)err; XSTRNCPY((buf), wc_GetErrorString((err)), \\\n        WOLFSSL_MAX_ERROR_SZ);\n\n#else\nWOLFSSL_API void wc_ErrorString(int err, char* buff);\nWOLFSSL_API const char* wc_GetErrorString(int error);\n#endif\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n#endif /* WOLF_CRYPT_ERROR_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/fe_operations.h",
    "content": "/* fe_operations.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifndef WOLF_CRYPT_FE_OPERATIONS_H\n#define WOLF_CRYPT_FE_OPERATIONS_H\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#if defined(HAVE_CURVE25519) || defined(HAVE_ED25519)\n\n#if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL)\n    #include <stdint.h>\n#endif\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#if defined(USE_INTEL_SPEEDUP) && !defined(NO_CURVED25519_X64)\n    #define CURVED25519_X64\n#elif defined(HAVE___UINT128_T) && !defined(NO_CURVED25519_128BIT)\n    #define CURVED25519_128BIT\n#endif\n\n#if defined(CURVED25519_X64)\n    #define CURVED25519_ASM_64BIT\n    #define CURVED25519_ASM\n#endif\n#if defined(WOLFSSL_ARMASM)\n    #ifdef __aarch64__\n        #define CURVED25519_ASM_64BIT\n    #else\n        #define CURVED25519_ASM_32BIT\n    #endif\n    #define CURVED25519_ASM\n#endif\n\n/*\nfe means field element.\nHere the field is \\Z/(2^255-19).\nAn element t, entries t[0]...t[9], represents the integer\nt[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].\nBounds on each t[i] vary depending on context.\n*/\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#if defined(CURVE25519_SMALL) || defined(ED25519_SMALL)\n    #define F25519_SIZE 32\n\n    WOLFSSL_LOCAL void lm_copy(byte*, const byte*);\n    WOLFSSL_LOCAL void lm_add(byte*, const byte*, const byte*);\n    WOLFSSL_LOCAL void lm_sub(byte*, const byte*, const byte*);\n    WOLFSSL_LOCAL void lm_neg(byte*,const byte*);\n    WOLFSSL_LOCAL void lm_invert(byte*, const byte*);\n    WOLFSSL_LOCAL void lm_mul(byte*,const byte*,const byte*);\n#endif\n\n\n#if !defined(FREESCALE_LTC_ECC)\nWOLFSSL_LOCAL void fe_init(void);\n\nWOLFSSL_LOCAL int  curve25519(byte * q, byte * n, byte * p);\n#endif\n\n/* default to be faster but take more memory */\n#if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL)\n\n#ifdef CURVED25519_ASM_64BIT\n    typedef int64_t  fe[4];\n#elif defined(CURVED25519_ASM_32BIT)\n    typedef int32_t  fe[8];\n#elif defined(CURVED25519_128BIT)\n    typedef int64_t  fe[5];\n#else\n    typedef int32_t  fe[10];\n#endif\n\nWOLFSSL_LOCAL void fe_copy(fe, const fe);\nWOLFSSL_LOCAL void fe_add(fe, const fe, const fe);\nWOLFSSL_LOCAL void fe_neg(fe,const fe);\nWOLFSSL_LOCAL void fe_sub(fe, const fe, const fe);\nWOLFSSL_LOCAL void fe_invert(fe, const fe);\nWOLFSSL_LOCAL void fe_mul(fe,const fe,const fe);\n\n\n/* Based On Daniel J Bernstein's curve25519 and ed25519 Public Domain ref10\n   work. */\n\nWOLFSSL_LOCAL void fe_0(fe);\nWOLFSSL_LOCAL void fe_1(fe);\nWOLFSSL_LOCAL int  fe_isnonzero(const fe);\nWOLFSSL_LOCAL int  fe_isnegative(const fe);\nWOLFSSL_LOCAL void fe_tobytes(unsigned char *, const fe);\nWOLFSSL_LOCAL void fe_sq(fe, const fe);\nWOLFSSL_LOCAL void fe_sq2(fe,const fe);\nWOLFSSL_LOCAL void fe_frombytes(fe,const unsigned char *);\nWOLFSSL_LOCAL void fe_cswap(fe, fe, int);\nWOLFSSL_LOCAL void fe_mul121666(fe,fe);\nWOLFSSL_LOCAL void fe_cmov(fe,const fe, int);\nWOLFSSL_LOCAL void fe_pow22523(fe,const fe);\n\n/* 64 type needed for SHA512 */\nWOLFSSL_LOCAL uint64_t load_3(const unsigned char *in);\nWOLFSSL_LOCAL uint64_t load_4(const unsigned char *in);\n\n#ifdef CURVED25519_ASM\nWOLFSSL_LOCAL void fe_ge_to_p2(fe rx, fe ry, fe rz, const fe px, const fe py,\n                               const fe pz, const fe pt);\nWOLFSSL_LOCAL void fe_ge_to_p3(fe rx, fe ry, fe rz, fe rt, const fe px,\n                               const fe py, const fe pz, const fe pt);\nWOLFSSL_LOCAL void fe_ge_dbl(fe rx, fe ry, fe rz, fe rt, const fe px,\n                             const fe py, const fe pz);\nWOLFSSL_LOCAL void fe_ge_madd(fe rx, fe ry, fe rz, fe rt, const fe px,\n                              const fe py, const fe pz, const fe pt,\n                              const fe qxy2d, const fe qyplusx,\n                              const fe qyminusx);\nWOLFSSL_LOCAL void fe_ge_msub(fe rx, fe ry, fe rz, fe rt, const fe px,\n                              const fe py, const fe pz, const fe pt,\n                              const fe qxy2d, const fe qyplusx,\n                              const fe qyminusx);\nWOLFSSL_LOCAL void fe_ge_add(fe rx, fe ry, fe rz, fe rt, const fe px,\n                             const fe py, const fe pz, const fe pt, const fe qz,\n                             const fe qt2d, const fe qyplusx,\n                             const fe qyminusx);\nWOLFSSL_LOCAL void fe_ge_sub(fe rx, fe ry, fe rz, fe rt, const fe px,\n                             const fe py, const fe pz, const fe pt, const fe qz,\n                             const fe qt2d, const fe qyplusx,\n                             const fe qyminusx);\nWOLFSSL_LOCAL void fe_cmov_table(fe* r, fe* base, signed char b);\n#endif /* CURVED25519_ASM */\n#endif /* !CURVE25519_SMALL || !ED25519_SMALL */\n\n/* Use less memory and only 32bit types or less, but is slower\n   Based on Daniel Beer's public domain work. */\n#if defined(CURVE25519_SMALL) || defined(ED25519_SMALL)\nstatic const byte c25519_base_x[F25519_SIZE] = {9};\nstatic const byte f25519_zero[F25519_SIZE]   = {0};\nstatic const byte f25519_one[F25519_SIZE]    = {1};\nstatic const byte fprime_zero[F25519_SIZE]   = {0};\nstatic const byte fprime_one[F25519_SIZE]    = {1};\n\nWOLFSSL_LOCAL void fe_load(byte *x, word32 c);\nWOLFSSL_LOCAL void fe_normalize(byte *x);\nWOLFSSL_LOCAL void fe_inv__distinct(byte *r, const byte *x);\n\n/* Conditional copy. If condition == 0, then zero is copied to dst. If\n * condition == 1, then one is copied to dst. Any other value results in\n * undefined behavior.\n */\nWOLFSSL_LOCAL void fe_select(byte *dst, const byte *zero, const byte *one,\n\t\t   byte condition);\n\n/* Multiply a point by a small constant. The two pointers are not\n * required to be distinct.\n *\n * The constant must be less than 2^24.\n */\nWOLFSSL_LOCAL void fe_mul_c(byte *r, const byte *a, word32 b);\nWOLFSSL_LOCAL void fe_mul__distinct(byte *r, const byte *a, const byte *b);\n\n/* Compute one of the square roots of the field element, if the element\n * is square. The other square is -r.\n *\n * If the input is not square, the returned value is a valid field\n * element, but not the correct answer. If you don't already know that\n * your element is square, you should square the return value and test.\n */\nWOLFSSL_LOCAL void fe_sqrt(byte *r, const byte *x);\n\n/* Conditional copy. If condition == 0, then zero is copied to dst. If\n * condition == 1, then one is copied to dst. Any other value results in\n * undefined behavior.\n */\nWOLFSSL_LOCAL void fprime_select(byte *dst, const byte *zero, const byte *one,\n\t\t                         byte condition);\nWOLFSSL_LOCAL void fprime_add(byte *r, const byte *a, const byte *modulus);\nWOLFSSL_LOCAL void fprime_sub(byte *r, const byte *a, const byte *modulus);\nWOLFSSL_LOCAL void fprime_mul(byte *r, const byte *a, const byte *b,\n\t\t                      const byte *modulus);\nWOLFSSL_LOCAL void fprime_copy(byte *x, const byte *a);\n\n#endif /* CURVE25519_SMALL || ED25519_SMALL */\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* HAVE_CURVE25519 || HAVE_ED25519 */\n\n#endif /* WOLF_CRYPT_FE_OPERATIONS_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/fips_test.h",
    "content": "/* fips_test.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#ifndef WOLF_CRYPT_FIPS_TEST_H\n#define WOLF_CRYPT_FIPS_TEST_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* Known Answer Test string inputs are hex, internal */\nWOLFSSL_LOCAL int DoKnownAnswerTests(char*, int);\n\n\n/* FIPS failure callback */\ntypedef void(*wolfCrypt_fips_cb)(int ok, int err, const char* hash);\n\n/* Public set function */\nWOLFSSL_API int wolfCrypt_SetCb_fips(wolfCrypt_fips_cb cbf);\n\n/* Public get status functions */\nWOLFSSL_API int wolfCrypt_GetStatus_fips(void);\nWOLFSSL_API const char* wolfCrypt_GetCoreHash_fips(void);\n\n#ifdef HAVE_FORCE_FIPS_FAILURE\n    /* Public function to force failure mode for operational testing */\n    WOLFSSL_API int wolfCrypt_SetStatus_fips(int);\n#endif\n\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLF_CRYPT_FIPS_TEST_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/ge_operations.h",
    "content": "/* ge_operations.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n /* Based On Daniel J Bernstein's ed25519 Public Domain ref10 work. */\n\n#ifndef WOLF_CRYPT_GE_OPERATIONS_H\n#define WOLF_CRYPT_GE_OPERATIONS_H\n\n#include <wolfssl/wolfcrypt/settings.h>\n\n#ifdef HAVE_ED25519\n\n#include <wolfssl/wolfcrypt/fe_operations.h>\n\n/*\nge means group element.\n\nHere the group is the set of pairs (x,y) of field elements (see fe.h)\nsatisfying -x^2 + y^2 = 1 + d x^2y^2\nwhere d = -121665/121666.\n\nRepresentations:\n  ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z\n  ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT\n  ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T\n  ge_precomp (Duif): (y+x,y-x,2dxy)\n*/\n\n#ifdef ED25519_SMALL\n  typedef byte     ge[F25519_SIZE];\n#elif defined(CURVED25519_ASM_64BIT)\n  typedef int64_t  ge[4];\n#elif defined(CURVED25519_ASM_32BIT)\n  typedef int32_t  ge[8];\n#elif defined(CURVED25519_128BIT)\n  typedef int64_t  ge[5];\n#else\n  typedef int32_t  ge[10];\n#endif\n\ntypedef struct {\n  ge X;\n  ge Y;\n  ge Z;\n} ge_p2;\n\ntypedef struct {\n  ge X;\n  ge Y;\n  ge Z;\n  ge T;\n} ge_p3;\n\n\nWOLFSSL_LOCAL int  ge_compress_key(byte* out, const byte* xIn, const byte* yIn,\n                                                                word32 keySz);\nWOLFSSL_LOCAL int  ge_frombytes_negate_vartime(ge_p3 *,const unsigned char *);\n\nWOLFSSL_LOCAL int  ge_double_scalarmult_vartime(ge_p2 *,const unsigned char *,\n                                         const ge_p3 *,const unsigned char *);\nWOLFSSL_LOCAL void ge_scalarmult_base(ge_p3 *,const unsigned char *);\nWOLFSSL_LOCAL void sc_reduce(byte* s);\nWOLFSSL_LOCAL void sc_muladd(byte* s, const byte* a, const byte* b,\n                             const byte* c);\nWOLFSSL_LOCAL void ge_tobytes(unsigned char *,const ge_p2 *);\nWOLFSSL_LOCAL void ge_p3_tobytes(unsigned char *,const ge_p3 *);\n\n\n#ifndef ED25519_SMALL\ntypedef struct {\n  ge X;\n  ge Y;\n  ge Z;\n  ge T;\n} ge_p1p1;\n\ntypedef struct {\n  ge yplusx;\n  ge yminusx;\n  ge xy2d;\n} ge_precomp;\n\ntypedef struct {\n  ge YplusX;\n  ge YminusX;\n  ge Z;\n  ge T2d;\n} ge_cached;\n\n#endif /* !ED25519_SMALL */\n\n#endif /* HAVE_ED25519 */\n\n#endif /* WOLF_CRYPT_GE_OPERATIONS_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/hash.h",
    "content": "/* hash.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/hash.h\n*/\n\n#ifndef WOLF_CRYPT_HASH_H\n#define WOLF_CRYPT_HASH_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_MD5\n    #include <wolfssl/wolfcrypt/md5.h>\n#endif\n#ifndef NO_SHA\n    #include <wolfssl/wolfcrypt/sha.h>\n#endif\n#if defined(WOLFSSL_SHA224) || !defined(NO_SHA256)\n    #include <wolfssl/wolfcrypt/sha256.h>\n#endif\n#if defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)\n    #include <wolfssl/wolfcrypt/sha512.h>\n#endif\n#ifdef HAVE_BLAKE2\n    #include <wolfssl/wolfcrypt/blake2.h>\n#endif\n#ifdef WOLFSSL_SHA3\n    #include <wolfssl/wolfcrypt/sha3.h>\n#endif\n#ifndef NO_MD4\n    #include <wolfssl/wolfcrypt/md4.h>\n#endif\n#ifdef WOLFSSL_MD2\n    #include <wolfssl/wolfcrypt/md2.h>\n#endif\n#if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S)\n    #include <wolfssl/wolfcrypt/blake2.h>\n#endif\n\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#if !defined(HAVE_FIPS) && !defined(NO_OLD_WC_NAMES)\n    #define MAX_DIGEST_SIZE WC_MAX_DIGEST_SIZE\n#endif\n\n\n/* Supported Message Authentication Codes from page 43 */\nenum wc_MACAlgorithm {\n    no_mac,\n    md5_mac,\n    sha_mac,\n    sha224_mac,\n    sha256_mac,     /* needs to match external KDF_MacAlgorithm */\n    sha384_mac,\n    sha512_mac,\n    rmd_mac,\n    blake2b_mac\n};\n\nenum wc_HashFlags {\n    WC_HASH_FLAG_NONE =     0x00000000,\n    WC_HASH_FLAG_WILLCOPY = 0x00000001, /* flag to indicate hash will be copied */\n    WC_HASH_FLAG_ISCOPY =   0x00000002, /* hash is copy */\n#ifdef WOLFSSL_SHA3\n    WC_HASH_SHA3_KECCAK256 =0x00010000, /* Older KECCAK256 */\n#endif\n};\n\n\ntypedef union {\n    #ifndef NO_MD5\n        wc_Md5 md5;\n    #endif\n    #ifndef NO_SHA\n        wc_Sha sha;\n    #endif\n    #ifdef WOLFSSL_SHA224\n        wc_Sha224 sha224;\n    #endif\n    #ifndef NO_SHA256\n        wc_Sha256 sha256;\n    #endif\n    #ifdef WOLFSSL_SHA384\n        wc_Sha384 sha384;\n    #endif\n    #ifdef WOLFSSL_SHA512\n        wc_Sha512 sha512;\n    #endif\n    #ifdef WOLFSSL_SHA3\n        wc_Sha3 sha3;\n    #endif\n} wc_HashAlg;\n\n/* Find largest possible digest size\n   Note if this gets up to the size of 80 or over check smallstack build */\n#if defined(WOLFSSL_SHA3)\n    #define WC_MAX_DIGEST_SIZE WC_SHA3_512_DIGEST_SIZE\n    #define WC_MAX_BLOCK_SIZE  WC_SHA3_224_BLOCK_SIZE /* 224 is the largest block size */\n#elif defined(WOLFSSL_SHA512)\n    #define WC_MAX_DIGEST_SIZE WC_SHA512_DIGEST_SIZE\n    #define WC_MAX_BLOCK_SIZE  WC_SHA512_BLOCK_SIZE\n#elif defined(HAVE_BLAKE2)\n    #define WC_MAX_DIGEST_SIZE BLAKE2B_OUTBYTES\n    #define WC_MAX_BLOCK_SIZE  BLAKE2B_BLOCKBYTES\n#elif defined(WOLFSSL_SHA384)\n    #define WC_MAX_DIGEST_SIZE WC_SHA384_DIGEST_SIZE\n    #define WC_MAX_BLOCK_SIZE  WC_SHA384_BLOCK_SIZE\n#elif !defined(NO_SHA256)\n    #define WC_MAX_DIGEST_SIZE WC_SHA256_DIGEST_SIZE\n    #define WC_MAX_BLOCK_SIZE  WC_SHA256_BLOCK_SIZE\n#elif defined(WOLFSSL_SHA224)\n    #define WC_MAX_DIGEST_SIZE WC_SHA224_DIGEST_SIZE\n    #define WC_MAX_BLOCK_SIZE  WC_SHA224_BLOCK_SIZE\n#elif !defined(NO_SHA)\n    #define WC_MAX_DIGEST_SIZE WC_SHA_DIGEST_SIZE\n    #define WC_MAX_BLOCK_SIZE  WC_SHA_BLOCK_SIZE\n#elif !defined(NO_MD5)\n    #define WC_MAX_DIGEST_SIZE WC_MD5_DIGEST_SIZE\n    #define WC_MAX_BLOCK_SIZE  WC_MD5_BLOCK_SIZE\n#else\n    #define WC_MAX_DIGEST_SIZE 64 /* default to max size of 64 */\n    #define WC_MAX_BLOCK_SIZE  128\n#endif\n\n#if !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC)\nWOLFSSL_API int wc_HashGetOID(enum wc_HashType hash_type);\nWOLFSSL_API enum wc_HashType wc_OidGetHash(int oid);\n#endif\n\nWOLFSSL_API enum wc_HashType wc_HashTypeConvert(int hashType);\n\nWOLFSSL_API int wc_HashGetDigestSize(enum wc_HashType hash_type);\nWOLFSSL_API int wc_HashGetBlockSize(enum wc_HashType hash_type);\nWOLFSSL_API int wc_Hash(enum wc_HashType hash_type,\n    const byte* data, word32 data_len,\n    byte* hash, word32 hash_len);\n\n/* generic hash operation wrappers */\nWOLFSSL_API int wc_HashInit_ex(wc_HashAlg* hash, enum wc_HashType type,\n    void* heap, int devId);\nWOLFSSL_API int wc_HashInit(wc_HashAlg* hash, enum wc_HashType type);\nWOLFSSL_API int wc_HashUpdate(wc_HashAlg* hash, enum wc_HashType type,\n    const byte* data, word32 dataSz);\nWOLFSSL_API int wc_HashFinal(wc_HashAlg* hash, enum wc_HashType type,\n    byte* out);\nWOLFSSL_API int wc_HashFree(wc_HashAlg* hash, enum wc_HashType type);\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    WOLFSSL_API int wc_HashSetFlags(wc_HashAlg* hash, enum wc_HashType type,\n        word32 flags);\n    WOLFSSL_API int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type,\n        word32* flags);\n#endif\n\n#ifndef NO_MD5\n#include <wolfssl/wolfcrypt/md5.h>\nWOLFSSL_API int wc_Md5Hash(const byte* data, word32 len, byte* hash);\n#endif\n\n#ifndef NO_SHA\n#include <wolfssl/wolfcrypt/sha.h>\nWOLFSSL_API int wc_ShaHash(const byte*, word32, byte*);\n#endif\n\n#ifdef WOLFSSL_SHA224\n#include <wolfssl/wolfcrypt/sha256.h>\nWOLFSSL_API int wc_Sha224Hash(const byte*, word32, byte*);\n#endif /* defined(WOLFSSL_SHA224) */\n\n#ifndef NO_SHA256\n#include <wolfssl/wolfcrypt/sha256.h>\nWOLFSSL_API int wc_Sha256Hash(const byte*, word32, byte*);\n#endif\n\n#ifdef WOLFSSL_SHA384\n#include <wolfssl/wolfcrypt/sha512.h>\nWOLFSSL_API int wc_Sha384Hash(const byte*, word32, byte*);\n#endif /* defined(WOLFSSL_SHA384) */\n\n#ifdef WOLFSSL_SHA512\n#include <wolfssl/wolfcrypt/sha512.h>\nWOLFSSL_API int wc_Sha512Hash(const byte*, word32, byte*);\n#endif /* WOLFSSL_SHA512 */\n\n#ifdef WOLFSSL_SHA3\n#include <wolfssl/wolfcrypt/sha3.h>\nWOLFSSL_API int wc_Sha3_224Hash(const byte*, word32, byte*);\nWOLFSSL_API int wc_Sha3_256Hash(const byte*, word32, byte*);\nWOLFSSL_API int wc_Sha3_384Hash(const byte*, word32, byte*);\nWOLFSSL_API int wc_Sha3_512Hash(const byte*, word32, byte*);\n#endif /* WOLFSSL_SHA3 */\n\nenum max_prf {\n#ifdef HAVE_FFDHE_8192\n    MAX_PRF_HALF        = 516, /* Maximum half secret len */\n#elif defined(HAVE_FFDHE_6144)\n    MAX_PRF_HALF        = 388, /* Maximum half secret len */\n#else\n    MAX_PRF_HALF        = 260, /* Maximum half secret len */\n#endif\n    MAX_PRF_LABSEED     = 128, /* Maximum label + seed len */\n    MAX_PRF_DIG         = 224  /* Maximum digest len      */\n};\n\n#ifdef WOLFSSL_HAVE_PRF\nWOLFSSL_API int wc_PRF(byte* result, word32 resLen, const byte* secret,\n                    word32 secLen, const byte* seed, word32 seedLen, int hash,\n                    void* heap, int devId);\nWOLFSSL_API int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret,\n                    word32 secLen, const byte* label, word32 labLen,\n                    const byte* seed, word32 seedLen, void* heap, int devId);\nWOLFSSL_API int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret,\n                    word32 secLen, const byte* label, word32 labLen,\n                    const byte* seed, word32 seedLen, int useAtLeastSha256,\n                    int hash_type, void* heap, int devId);\n#endif /* WOLFSSL_HAVE_PRF */\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLF_CRYPT_HASH_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/hc128.h",
    "content": "/* hc128.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/hc128.h\n*/\n\n\n#ifndef WOLF_CRYPT_HC128_H\n#define WOLF_CRYPT_HC128_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_HC128\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\nenum {\n\tHC128_ENC_TYPE =  WC_CIPHER_HC128,     /* cipher unique type */\n};\n\n/* HC-128 stream cipher */\ntypedef struct HC128 {\n    word32 T[1024];             /* P[i] = T[i];  Q[i] = T[1024 + i ]; */\n    word32 X[16];\n    word32 Y[16];\n    word32 counter1024;         /* counter1024 = i mod 1024 at the ith step */\n    word32 key[8];\n    word32 iv[8];\n#ifdef XSTREAM_ALIGN\n    void*  heap;  /* heap hint, currently XMALLOC only used with aligning */\n#endif\n} HC128;\n\n\nWOLFSSL_API int wc_Hc128_Process(HC128*, byte*, const byte*, word32);\nWOLFSSL_API int wc_Hc128_SetKey(HC128*, const byte* key, const byte* iv);\n\nWOLFSSL_LOCAL int wc_Hc128_SetHeap(HC128* ctx, void* heap);\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* HAVE_HC128 */\n#endif /* WOLF_CRYPT_HC128_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/hmac.h",
    "content": "/* hmac.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/hmac.h\n*/\n\n#ifndef NO_HMAC\n\n#ifndef WOLF_CRYPT_HMAC_H\n#define WOLF_CRYPT_HMAC_H\n\n#include <wolfssl/wolfcrypt/hash.h>\n\n#if defined(HAVE_FIPS) && \\\n\t(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n/* for fips @wc_fips */\n    #include <cyassl/ctaocrypt/hmac.h>\n    #define WC_HMAC_BLOCK_SIZE HMAC_BLOCK_SIZE\n#endif\n\n\n#if defined(HAVE_FIPS) && \\\n\tdefined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n\t#include <wolfssl/wolfcrypt/fips.h>\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* avoid redefinition of structs */\n#if !defined(HAVE_FIPS) || \\\n    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n\n#ifndef NO_OLD_WC_NAMES\n    #define HMAC_BLOCK_SIZE WC_HMAC_BLOCK_SIZE\n#endif\n\n#define WC_HMAC_INNER_HASH_KEYED_SW     1\n#define WC_HMAC_INNER_HASH_KEYED_DEV    2\n\nenum {\n    HMAC_FIPS_MIN_KEY = 14,   /* 112 bit key length minimum */\n\n    IPAD    = 0x36,\n    OPAD    = 0x5C,\n\n/* If any hash is not enabled, add the ID here. */\n#ifdef NO_MD5\n    WC_MD5     = WC_HASH_TYPE_MD5,\n#endif\n#ifdef NO_SHA\n    WC_SHA     = WC_HASH_TYPE_SHA,\n#endif\n#ifdef NO_SHA256\n    WC_SHA256  = WC_HASH_TYPE_SHA256,\n#endif\n#ifndef WOLFSSL_SHA512\n    WC_SHA512  = WC_HASH_TYPE_SHA512,\n#endif\n#ifndef WOLFSSL_SHA384\n    WC_SHA384  = WC_HASH_TYPE_SHA384,\n#endif\n#ifndef WOLFSSL_SHA224\n    WC_SHA224  = WC_HASH_TYPE_SHA224,\n#endif\n#ifndef WOLFSSL_SHA3\n    WC_SHA3_224 = WC_HASH_TYPE_SHA3_224,\n    WC_SHA3_256 = WC_HASH_TYPE_SHA3_256,\n    WC_SHA3_384 = WC_HASH_TYPE_SHA3_384,\n    WC_SHA3_512 = WC_HASH_TYPE_SHA3_512,\n#endif\n#ifdef HAVE_PKCS11\n    HMAC_MAX_ID_LEN = 32,\n#endif\n};\n\n/* Select the largest available hash for the buffer size. */\n#define WC_HMAC_BLOCK_SIZE WC_MAX_BLOCK_SIZE\n\n#if !defined(WOLFSSL_SHA3) && !defined(WOLFSSL_SHA512) && \\\n    !defined(WOLFSSL_SHA384) && defined(NO_SHA256) && \\\n    defined(WOLFSSL_SHA224) && defined(NO_SHA) && defined(NO_MD5)\n    #error \"You have to have some kind of hash if you want to use HMAC.\"\n#endif\n\n\n/* hash union */\ntypedef union {\n#ifndef NO_MD5\n    wc_Md5 md5;\n#endif\n#ifndef NO_SHA\n    wc_Sha sha;\n#endif\n#ifdef WOLFSSL_SHA224\n    wc_Sha224 sha224;\n#endif\n#ifndef NO_SHA256\n    wc_Sha256 sha256;\n#endif\n#ifdef WOLFSSL_SHA384\n    wc_Sha384 sha384;\n#endif\n#ifdef WOLFSSL_SHA512\n    wc_Sha512 sha512;\n#endif\n#ifdef WOLFSSL_SHA3\n    wc_Sha3 sha3;\n#endif\n} Hash;\n\n/* Hmac digest */\nstruct Hmac {\n    Hash    hash;\n    word32  ipad[WC_HMAC_BLOCK_SIZE  / sizeof(word32)];  /* same block size all*/\n    word32  opad[WC_HMAC_BLOCK_SIZE  / sizeof(word32)];\n    word32  innerHash[WC_MAX_DIGEST_SIZE / sizeof(word32)];\n    void*   heap;                 /* heap hint */\n    byte    macType;              /* md5 sha or sha256 */\n    byte    innerHashKeyed;       /* keyed flag */\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV asyncDev;\n#endif /* WOLFSSL_ASYNC_CRYPT */\n#ifdef WOLF_CRYPTO_CB\n    int     devId;\n    void*   devCtx;\n    const byte* keyRaw;\n#endif\n#ifdef HAVE_PKCS11\n    byte    id[HMAC_MAX_ID_LEN];\n    int     idLen;\n#endif\n#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)\n    word16  keyLen;          /* hmac key length (key in ipad) */\n#endif\n};\n\n#ifndef WC_HMAC_TYPE_DEFINED\n    typedef struct Hmac Hmac;\n    #define WC_HMAC_TYPE_DEFINED\n#endif\n\n\n#endif /* HAVE_FIPS */\n\n/* does init */\nWOLFSSL_API int wc_HmacSetKey(Hmac*, int type, const byte* key, word32 keySz);\nWOLFSSL_API int wc_HmacUpdate(Hmac*, const byte*, word32);\nWOLFSSL_API int wc_HmacFinal(Hmac*, byte*);\nWOLFSSL_API int wc_HmacSizeByType(int type);\n\nWOLFSSL_API int wc_HmacInit(Hmac* hmac, void* heap, int devId);\nWOLFSSL_API int wc_HmacInit_Id(Hmac* hmac, byte* id, int len, void* heap,\n                               int devId);\nWOLFSSL_API void wc_HmacFree(Hmac*);\n\nWOLFSSL_API int wolfSSL_GetHmacMaxSize(void);\n\nWOLFSSL_LOCAL int _InitHmac(Hmac* hmac, int type, void* heap);\n\n#ifdef HAVE_HKDF\n\nWOLFSSL_API int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz,\n                                const byte* inKey, word32 inKeySz, byte* out);\nWOLFSSL_API int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz,\n                               const byte* info, word32 infoSz,\n                               byte* out,        word32 outSz);\n\nWOLFSSL_API int wc_HKDF(int type, const byte* inKey, word32 inKeySz,\n                    const byte* salt, word32 saltSz,\n                    const byte* info, word32 infoSz,\n                    byte* out, word32 outSz);\n\n#endif /* HAVE_HKDF */\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLF_CRYPT_HMAC_H */\n\n#endif /* NO_HMAC */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/idea.h",
    "content": "/* idea.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/idea.h\n*/\n\n#ifndef WOLF_CRYPT_IDEA_H\n#define WOLF_CRYPT_IDEA_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef HAVE_IDEA\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\nenum {\n    IDEA_MODULO     = 0x10001,             /* 2^16+1 */\n    IDEA_2EXP16     = 0x10000,             /* 2^16 */\n    IDEA_MASK       = 0xFFFF,              /* 16 bits set to one */\n    IDEA_ROUNDS     = 8,                   /* number of rounds for IDEA */\n    IDEA_SK_NUM     = (6*IDEA_ROUNDS + 4), /* number of subkeys */\n    IDEA_KEY_SIZE   = 16,                  /* size of key in bytes */\n    IDEA_BLOCK_SIZE = 8,                   /* size of IDEA blocks in bytes */\n    IDEA_IV_SIZE    = 8,                   /* size of IDEA IV in bytes */\n    IDEA_ENCRYPTION = 0,\n    IDEA_DECRYPTION = 1\n};\n\n/* IDEA encryption and decryption */\ntypedef struct Idea {\n    word32  reg[IDEA_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */\n    word32  tmp[IDEA_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */\n    word16  skey[IDEA_SK_NUM]; /* 832 bits expanded key */\n} Idea;\n\nWOLFSSL_API int wc_IdeaSetKey(Idea *idea, const byte* key, word16 keySz,\n                              const byte *iv, int dir);\nWOLFSSL_API int wc_IdeaSetIV(Idea *idea, const byte* iv);\nWOLFSSL_API int wc_IdeaCipher(Idea *idea, byte* out, const byte* in);\nWOLFSSL_API int wc_IdeaCbcEncrypt(Idea *idea, byte* out,\n                                  const byte* in, word32 len);\nWOLFSSL_API int wc_IdeaCbcDecrypt(Idea *idea, byte* out,\n                                  const byte* in, word32 len);\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* HAVE_IDEA */\n#endif /* WOLF_CRYPT_IDEA_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/integer.h",
    "content": "/* integer.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n/*\n * Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca,\n * http://math.libtomcrypt.com\n */\n\n\n#ifndef WOLF_CRYPT_INTEGER_H\n#define WOLF_CRYPT_INTEGER_H\n\n/* may optionally use fast math instead, not yet supported on all platforms and\n   may not be faster on all\n*/\n#include <wolfssl/wolfcrypt/types.h>       /* will set MP_xxBIT if not default */\n#ifdef WOLFSSL_SP_MATH\n    #include <wolfssl/wolfcrypt/sp_int.h>\n#elif defined(USE_FAST_MATH)\n    #include <wolfssl/wolfcrypt/tfm.h>\n#else\n\n#include <wolfssl/wolfcrypt/random.h>\n\n#ifndef CHAR_BIT\n    #include <limits.h>\n#endif\n\n#include <wolfssl/wolfcrypt/mpi_class.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n\n/* C++ compilers don't like assigning void * to mp_digit * */\n#define  OPT_CAST(x)  (x *)\n\n#elif defined(_SH3)\n\n/* SuperH SH3 compiler doesn't like assigning voi* to mp_digit* */\n#define  OPT_CAST(x)  (x *)\n\n#else\n\n/* C on the other hand doesn't care */\n#define  OPT_CAST(x)\n\n#endif /* __cplusplus */\n\n\n/* detect 64-bit mode if possible */\n#if defined(__x86_64__) && !(defined (_MSC_VER) && defined(__clang__))\n   #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT))\n      #define MP_64BIT\n   #endif\n#endif\n/* if intel compiler doesn't provide 128 bit type don't turn on 64bit */\n#if defined(MP_64BIT) && defined(__INTEL_COMPILER) && !defined(HAVE___UINT128_T)\n    #undef MP_64BIT\n#endif\n\n\n/* allow user to define on mp_digit, mp_word, DIGIT_BIT types */\n#ifndef WOLFSSL_BIGINT_TYPES\n\n/* some default configurations.\n *\n * A \"mp_digit\" must be able to hold DIGIT_BIT + 1 bits\n * A \"mp_word\" must be able to hold 2*DIGIT_BIT + 1 bits\n *\n * At the very least a mp_digit must be able to hold 7 bits\n * [any size beyond that is ok provided it doesn't overflow the data type]\n */\n#ifdef MP_8BIT\n   /* 8-bit */\n   typedef unsigned char      mp_digit;\n   typedef unsigned short     mp_word;\n   /* don't define DIGIT_BIT, so its calculated below */\n#elif defined(MP_16BIT)\n   /* 16-bit */\n   typedef unsigned int       mp_digit;\n   typedef unsigned long      mp_word;\n   /* don't define DIGIT_BIT, so its calculated below */\n#elif defined(NO_64BIT)\n   /* 32-bit forced to 16-bit */\n   typedef unsigned short     mp_digit;\n   typedef unsigned int       mp_word;\n   #define DIGIT_BIT          12\n#elif defined(MP_64BIT)\n   /* 64-bit */\n   /* for GCC only on supported platforms */\n   typedef unsigned long long mp_digit;  /* 64 bit type, 128 uses mode(TI) */\n   typedef unsigned long      mp_word __attribute__ ((mode(TI)));\n   #define DIGIT_BIT          60\n#else\n   /* 32-bit default case */\n\n   #if defined(_MSC_VER) || defined(__BORLANDC__)\n      typedef unsigned __int64   ulong64;\n   #else\n      typedef unsigned long long ulong64;\n   #endif\n\n   typedef unsigned int       mp_digit;  /* long could be 64 now, changed TAO */\n   typedef ulong64            mp_word;\n\n   #ifdef MP_31BIT\n      /* this is an extension that uses 31-bit digits */\n      #define DIGIT_BIT          31\n   #else\n      /* default case is 28-bit digits, defines MP_28BIT as a handy test macro */\n      #define DIGIT_BIT          28\n      #define MP_28BIT\n   #endif\n#endif\n\n#endif /* WOLFSSL_BIGINT_TYPES */\n\n/* otherwise the bits per digit is calculated automatically from the size of\n   a mp_digit */\n#ifndef DIGIT_BIT\n   #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1)))\n      /* bits per digit */\n#endif\n\n#define MP_DIGIT_BIT     DIGIT_BIT\n#define MP_MASK          ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))\n#define MP_DIGIT_MAX     MP_MASK\n\n/* equalities */\n#define MP_LT        -1   /* less than */\n#define MP_EQ         0   /* equal to */\n#define MP_GT         1   /* greater than */\n\n#define MP_ZPOS       0   /* positive integer */\n#define MP_NEG        1   /* negative */\n\n#define MP_OKAY       0   /* ok result */\n#define MP_MEM        -2  /* out of mem */\n#define MP_VAL        -3  /* invalid input */\n#define MP_NOT_INF\t  -4  /* point not at infinity */\n#define MP_RANGE      MP_NOT_INF\n\n#define MP_YES        1   /* yes response */\n#define MP_NO         0   /* no response */\n\n/* Primality generation flags */\n#define LTM_PRIME_BBS      0x0001 /* BBS style prime */\n#define LTM_PRIME_SAFE     0x0002 /* Safe prime (p-1)/2 == prime */\n#define LTM_PRIME_2MSB_ON  0x0008 /* force 2nd MSB to 1 */\n\ntypedef int           mp_err;\n\n/* define this to use lower memory usage routines (exptmods mostly) */\n#define MP_LOW_MEM\n\n/* default precision */\n#ifndef MP_PREC\n   #ifndef MP_LOW_MEM\n      #define MP_PREC                 32     /* default digits of precision */\n   #else\n      #define MP_PREC                 1      /* default digits of precision */\n   #endif\n#endif\n\n/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD -\n   BITS_PER_DIGIT*2) */\n#define MP_WARRAY  ((mp_word)1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))\n\n#ifdef HAVE_WOLF_BIGINT\n    /* raw big integer */\n    typedef struct WC_BIGINT {\n        byte*   buf;\n        word32  len;\n        void*   heap;\n    } WC_BIGINT;\n    #define WOLF_BIGINT_DEFINED\n#endif\n\n/* the mp_int structure */\ntypedef struct mp_int {\n    int used, alloc, sign;\n    mp_digit *dp;\n\n#ifdef HAVE_WOLF_BIGINT\n    struct WC_BIGINT raw; /* unsigned binary (big endian) */\n#endif\n} mp_int;\n\n/* wolf big int and common functions */\n#include <wolfssl/wolfcrypt/wolfmath.h>\n\n\n/* callback for mp_prime_random, should fill dst with random bytes and return\n   how many read [up to len] */\ntypedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);\n\n\n#define USED(m)    ((m)->used)\n#define DIGIT(m,k) ((m)->dp[(k)])\n#define SIGN(m)    ((m)->sign)\n\n\n/* ---> Basic Manipulations <--- */\n#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)\n#define mp_isone(a) \\\n    (((((a)->used == 1)) && ((a)->dp[0] == 1u)) ? MP_YES : MP_NO)\n#define mp_iseven(a) \\\n    (((a)->used > 0 && (((a)->dp[0] & 1u) == 0u)) ? MP_YES : MP_NO)\n#define mp_isodd(a) \\\n    (((a)->used > 0 && (((a)->dp[0] & 1u) == 1u)) ? MP_YES : MP_NO)\n#define mp_isneg(a)  (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO)\n\n/* number of primes */\n#ifdef MP_8BIT\n   #define PRIME_SIZE      31\n#else\n   #define PRIME_SIZE      256\n#endif\n\n#ifndef MAX_INVMOD_SZ\n    #if defined(WOLFSSL_MYSQL_COMPATIBLE)\n        #define MAX_INVMOD_SZ 8192\n    #else\n        #define MAX_INVMOD_SZ 4096\n    #endif\n#endif\n\n#define mp_prime_random(a, t, size, bbs, cb, dat) \\\n   mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat)\n\n#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))\n#define mp_raw_size(mp)           mp_signed_bin_size(mp)\n#define mp_toraw(mp, str)         mp_to_signed_bin((mp), (str))\n#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))\n#define mp_mag_size(mp)           mp_unsigned_bin_size(mp)\n#define mp_tomag(mp, str)         mp_to_unsigned_bin((mp), (str))\n\n#define MP_RADIX_BIN  2\n#define MP_RADIX_OCT  8\n#define MP_RADIX_DEC  10\n#define MP_RADIX_HEX  16\n#define MP_RADIX_MAX  64\n\n#define mp_tobinary(M, S)  mp_toradix((M), (S), MP_RADIX_BIN)\n#define mp_tooctal(M, S)   mp_toradix((M), (S), MP_RADIX_OCT)\n#define mp_todecimal(M, S) mp_toradix((M), (S), MP_RADIX_DEC)\n#define mp_tohex(M, S)     mp_toradix((M), (S), MP_RADIX_HEX)\n\n#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)\n\n#if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \\\n    defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL)\nextern const char *mp_s_rmap;\n#endif\n\n/* 6 functions needed by Rsa */\nMP_API int  mp_init (mp_int * a);\nMP_API void mp_clear (mp_int * a);\nMP_API void mp_free (mp_int * a);\nMP_API void mp_forcezero(mp_int * a);\nMP_API int  mp_unsigned_bin_size(mp_int * a);\nMP_API int  mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c);\nMP_API int  mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b);\nMP_API int  mp_to_unsigned_bin (mp_int * a, unsigned char *b);\nMP_API int  mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c);\nMP_API int  mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y);\nMP_API int  mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P,\n                           mp_int * Y);\n/* end functions needed by Rsa */\n\n/* functions added to support above needed, removed TOOM and KARATSUBA */\nMP_API int  mp_count_bits (mp_int * a);\nMP_API int  mp_leading_bit (mp_int * a);\nMP_API int  mp_init_copy (mp_int * a, mp_int * b);\nMP_API int  mp_copy (mp_int * a, mp_int * b);\nMP_API int  mp_grow (mp_int * a, int size);\nMP_API int  mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d);\nMP_API void mp_zero (mp_int * a);\nMP_API void mp_clamp (mp_int * a);\nMP_API void mp_exch (mp_int * a, mp_int * b);\nMP_API void mp_rshd (mp_int * a, int b);\nMP_API void mp_rshb (mp_int * a, int b);\nMP_API int  mp_mod_2d (mp_int * a, int b, mp_int * c);\nMP_API int  mp_mul_2d (mp_int * a, int b, mp_int * c);\nMP_API int  mp_lshd (mp_int * a, int b);\nMP_API int  mp_abs (mp_int * a, mp_int * b);\nMP_API int  mp_invmod (mp_int * a, mp_int * b, mp_int * c);\nint  fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c);\nMP_API int  mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);\nMP_API int  mp_cmp_mag (mp_int * a, mp_int * b);\nMP_API int  mp_cmp (mp_int * a, mp_int * b);\nMP_API int  mp_cmp_d(mp_int * a, mp_digit b);\nMP_API int  mp_set (mp_int * a, mp_digit b);\nMP_API int  mp_is_bit_set (mp_int * a, mp_digit b);\nMP_API int  mp_mod (mp_int * a, mp_int * b, mp_int * c);\nMP_API int  mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d);\nMP_API int  mp_div_2(mp_int * a, mp_int * b);\nMP_API int  mp_add (mp_int * a, mp_int * b, mp_int * c);\nint  s_mp_add (mp_int * a, mp_int * b, mp_int * c);\nint  s_mp_sub (mp_int * a, mp_int * b, mp_int * c);\nMP_API int  mp_sub (mp_int * a, mp_int * b, mp_int * c);\nMP_API int  mp_reduce_is_2k_l(mp_int *a);\nMP_API int  mp_reduce_is_2k(mp_int *a);\nMP_API int  mp_dr_is_modulus(mp_int *a);\nMP_API int  mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,\n                             int);\nMP_API int  mp_exptmod_base_2 (mp_int * X, mp_int * P, mp_int * Y);\nMP_API int  mp_montgomery_setup (mp_int * n, mp_digit * rho);\nint  fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho);\nMP_API int  mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho);\nMP_API void mp_dr_setup(mp_int *a, mp_digit *d);\nMP_API int  mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k);\nMP_API int  mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);\nint  fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs);\nint  s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs);\nMP_API int  mp_reduce_2k_setup_l(mp_int *a, mp_int *d);\nMP_API int  mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);\nMP_API int  mp_reduce (mp_int * x, mp_int * m, mp_int * mu);\nMP_API int  mp_reduce_setup (mp_int * a, mp_int * b);\nint  s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode);\nMP_API int  mp_montgomery_calc_normalization (mp_int * a, mp_int * b);\nint  s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs);\nint  s_mp_sqr (mp_int * a, mp_int * b);\nint  fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs);\nint  fast_s_mp_sqr (mp_int * a, mp_int * b);\nMP_API int  mp_init_size (mp_int * a, int size);\nMP_API int  mp_div_3 (mp_int * a, mp_int *c, mp_digit * d);\nMP_API int  mp_mul_2(mp_int * a, mp_int * b);\nMP_API int  mp_mul (mp_int * a, mp_int * b, mp_int * c);\nMP_API int  mp_sqr (mp_int * a, mp_int * b);\nMP_API int  mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d);\nMP_API int  mp_submod (mp_int* a, mp_int* b, mp_int* c, mp_int* d);\nMP_API int  mp_addmod (mp_int* a, mp_int* b, mp_int* c, mp_int* d);\nMP_API int  mp_mul_d (mp_int * a, mp_digit b, mp_int * c);\nMP_API int  mp_2expt (mp_int * a, int b);\nMP_API int  mp_set_bit (mp_int * a, int b);\nMP_API int  mp_reduce_2k_setup(mp_int *a, mp_digit *d);\nMP_API int  mp_add_d (mp_int* a, mp_digit b, mp_int* c);\nMP_API int  mp_set_int (mp_int * a, unsigned long b);\nMP_API int  mp_sub_d (mp_int * a, mp_digit b, mp_int * c);\n/* end support added functions */\n\n/* added */\nMP_API int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,\n                         mp_int* f);\nMP_API int mp_toradix (mp_int *a, char *str, int radix);\nMP_API int mp_radix_size (mp_int * a, int radix, int *size);\n\n#ifdef WOLFSSL_DEBUG_MATH\n    MP_API void mp_dump(const char* desc, mp_int* a, byte verbose);\n#else\n    #define mp_dump(desc, a, verbose)\n#endif\n\n#if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || !defined(NO_RSA) || \\\n    !defined(NO_DSA) || !defined(NO_DH)\n    MP_API int mp_sqrmod(mp_int* a, mp_int* b, mp_int* c);\n#endif\n#if !defined(NO_DSA) || defined(HAVE_ECC)\n    MP_API int mp_read_radix(mp_int* a, const char* str, int radix);\n#endif\n\n#if defined(WOLFSSL_KEY_GEN) || !defined(NO_RSA) || !defined(NO_DSA) || !defined(NO_DH)\n    MP_API int mp_prime_is_prime (mp_int * a, int t, int *result);\n    MP_API int mp_prime_is_prime_ex (mp_int * a, int t, int *result, WC_RNG*);\n#endif /* WOLFSSL_KEY_GEN NO_RSA NO_DSA NO_DH */\n#ifdef WOLFSSL_KEY_GEN\n    MP_API int mp_gcd (mp_int * a, mp_int * b, mp_int * c);\n    MP_API int mp_lcm (mp_int * a, mp_int * b, mp_int * c);\n    MP_API int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap);\n#endif\n\nMP_API int mp_cnt_lsb(mp_int *a);\nMP_API int mp_mod_d(mp_int* a, mp_digit b, mp_digit* c);\n\n\n#ifdef __cplusplus\n   }\n#endif\n\n\n#endif /* USE_FAST_MATH */\n\n#endif  /* WOLF_CRYPT_INTEGER_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/logging.h",
    "content": "/* logging.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/logging.h\n*/\n\n\n/* submitted by eof */\n\n\n#ifndef WOLFSSL_LOGGING_H\n#define WOLFSSL_LOGGING_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n\nenum wc_LogLevels {\n    ERROR_LOG = 0,\n    INFO_LOG,\n    ENTER_LOG,\n    LEAVE_LOG,\n    OTHER_LOG\n};\n\n#ifdef WOLFSSL_FUNC_TIME\n/* WARNING: This code is only to be used for debugging performance.\n *          The code is not thread-safe.\n *          Do not use WOLFSSL_FUNC_TIME in production code.\n */\nenum wc_FuncNum {\n    WC_FUNC_HELLO_REQUEST_SEND = 0,\n    WC_FUNC_HELLO_REQUEST_DO,\n    WC_FUNC_CLIENT_HELLO_SEND,\n    WC_FUNC_CLIENT_HELLO_DO,\n    WC_FUNC_SERVER_HELLO_SEND,\n    WC_FUNC_SERVER_HELLO_DO,\n    WC_FUNC_ENCRYPTED_EXTENSIONS_SEND,\n    WC_FUNC_ENCRYPTED_EXTENSIONS_DO,\n    WC_FUNC_CERTIFICATE_REQUEST_SEND,\n    WC_FUNC_CERTIFICATE_REQUEST_DO,\n    WC_FUNC_CERTIFICATE_SEND,\n    WC_FUNC_CERTIFICATE_DO,\n    WC_FUNC_CERTIFICATE_VERIFY_SEND,\n    WC_FUNC_CERTIFICATE_VERIFY_DO,\n    WC_FUNC_FINISHED_SEND,\n    WC_FUNC_FINISHED_DO,\n    WC_FUNC_KEY_UPDATE_SEND,\n    WC_FUNC_KEY_UPDATE_DO,\n    WC_FUNC_EARLY_DATA_SEND,\n    WC_FUNC_EARLY_DATA_DO,\n    WC_FUNC_NEW_SESSION_TICKET_SEND,\n    WC_FUNC_NEW_SESSION_TICKET_DO,\n    WC_FUNC_SERVER_HELLO_DONE_SEND,\n    WC_FUNC_SERVER_HELLO_DONE_DO,\n    WC_FUNC_TICKET_SEND,\n    WC_FUNC_TICKET_DO,\n    WC_FUNC_CLIENT_KEY_EXCHANGE_SEND,\n    WC_FUNC_CLIENT_KEY_EXCHANGE_DO,\n    WC_FUNC_CERTIFICATE_STATUS_SEND,\n    WC_FUNC_CERTIFICATE_STATUS_DO,\n    WC_FUNC_SERVER_KEY_EXCHANGE_SEND,\n    WC_FUNC_SERVER_KEY_EXCHANGE_DO,\n    WC_FUNC_END_OF_EARLY_DATA_SEND,\n    WC_FUNC_END_OF_EARLY_DATA_DO,\n    WC_FUNC_COUNT\n};\n#endif\n\ntypedef void (*wolfSSL_Logging_cb)(const int logLevel,\n                                   const char *const logMessage);\n\nWOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function);\n\n/* turn logging on, only if compiled in */\nWOLFSSL_API int  wolfSSL_Debugging_ON(void);\n/* turn logging off */\nWOLFSSL_API void wolfSSL_Debugging_OFF(void);\n\n\n#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)\n    WOLFSSL_LOCAL int wc_LoggingInit(void);\n    WOLFSSL_LOCAL int wc_LoggingCleanup(void);\n    WOLFSSL_LOCAL int wc_AddErrorNode(int error, int line, char* buf,\n            char* file);\n    WOLFSSL_LOCAL int wc_PeekErrorNode(int index, const char **file,\n            const char **reason, int *line);\n    WOLFSSL_LOCAL void wc_RemoveErrorNode(int index);\n    WOLFSSL_LOCAL void wc_ClearErrorNodes(void);\n    WOLFSSL_LOCAL int wc_PullErrorNode(const char **file, const char **reason,\n                            int *line);\n    WOLFSSL_API   int wc_SetLoggingHeap(void* h);\n    WOLFSSL_API   int wc_ERR_remove_state(void);\n    #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)\n        WOLFSSL_API   void wc_ERR_print_errors_fp(XFILE fp);\n    #endif\n#endif /* OPENSSL_EXTRA || DEBUG_WOLFSSL_VERBOSE */\n\n#ifdef WOLFSSL_FUNC_TIME\n    /* WARNING: This code is only to be used for debugging performance.\n     *          The code is not thread-safe.\n     *          Do not use WOLFSSL_FUNC_TIME in production code.\n     */\n    WOLFSSL_API void WOLFSSL_START(int funcNum);\n    WOLFSSL_API void WOLFSSL_END(int funcNum);\n    WOLFSSL_API void WOLFSSL_TIME(int count);\n#else\n    #define WOLFSSL_START(n)\n    #define WOLFSSL_END(n)\n    #define WOLFSSL_TIME(n)\n#endif\n\n#if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_DEBUG_ERRORS_ONLY)\n    #if defined(_WIN32)\n        #if defined(INTIME_RTOS)\n            #define __func__ NULL\n        #else\n            #define __func__ __FUNCTION__\n        #endif\n    #endif\n\n    /* a is prepended to m and b is appended, creating a log msg a + m + b */\n    #define WOLFSSL_LOG_CAT(a, m, b) #a \" \" m \" \"  #b\n\n    WOLFSSL_API void WOLFSSL_ENTER(const char* msg);\n    WOLFSSL_API void WOLFSSL_LEAVE(const char* msg, int ret);\n    #define WOLFSSL_STUB(m) \\\n        WOLFSSL_MSG(WOLFSSL_LOG_CAT(wolfSSL Stub, m, not implemented))\n\n    WOLFSSL_API void WOLFSSL_MSG(const char* msg);\n    WOLFSSL_API void WOLFSSL_BUFFER(const byte* buffer, word32 length);\n\n#else\n\n    #define WOLFSSL_ENTER(m)\n    #define WOLFSSL_LEAVE(m, r)\n    #define WOLFSSL_STUB(m)\n\n    #define WOLFSSL_MSG(m)\n    #define WOLFSSL_BUFFER(b, l)\n\n#endif /* DEBUG_WOLFSSL && !WOLFSSL_DEBUG_ERRORS_ONLY */\n\n#if defined(DEBUG_WOLFSSL) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) ||\\\n    defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)\n\n    #if (!defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && !defined(_WIN32))\\\n        || defined(DEBUG_WOLFSSL_VERBOSE)\n        WOLFSSL_API void WOLFSSL_ERROR_LINE(int err, const char* func, unsigned int line,\n            const char* file, void* ctx);\n        #define WOLFSSL_ERROR(x) \\\n            WOLFSSL_ERROR_LINE((x), __func__, __LINE__, __FILE__, NULL)\n    #else\n        WOLFSSL_API void WOLFSSL_ERROR(int err);\n    #endif\n    WOLFSSL_API void WOLFSSL_ERROR_MSG(const char* msg);\n\n#else\n    #define WOLFSSL_ERROR(e)\n    #define WOLFSSL_ERROR_MSG(m)\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif /* WOLFSSL_LOGGING_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/md2.h",
    "content": "/* md2.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/md2.h\n*/\n\n\n#ifndef WOLF_CRYPT_MD2_H\n#define WOLF_CRYPT_MD2_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef WOLFSSL_MD2\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* in bytes */\nenum {\n    MD2             =  WC_HASH_TYPE_MD2,\n    MD2_BLOCK_SIZE  = 16,\n    MD2_DIGEST_SIZE = 16,\n    MD2_PAD_SIZE    = 16,\n    MD2_X_SIZE      = 48\n};\n\n\n/* Md2 digest */\ntypedef struct Md2 {\n    word32  count;   /* bytes % PAD_SIZE  */\n    byte    X[MD2_X_SIZE];\n    byte    C[MD2_BLOCK_SIZE];\n    byte    buffer[MD2_BLOCK_SIZE];\n} Md2;\n\n\nWOLFSSL_API void wc_InitMd2(Md2*);\nWOLFSSL_API void wc_Md2Update(Md2*, const byte*, word32);\nWOLFSSL_API void wc_Md2Final(Md2*, byte*);\nWOLFSSL_API int  wc_Md2Hash(const byte*, word32, byte*);\n\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLFSSL_MD2 */\n#endif /* WOLF_CRYPT_MD2_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/md4.h",
    "content": "/* md4.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/md4.h\n*/\n\n#ifndef WOLF_CRYPT_MD4_H\n#define WOLF_CRYPT_MD4_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_MD4\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* in bytes */\nenum {\n    MD4             =  WC_HASH_TYPE_MD4,\n    MD4_BLOCK_SIZE  = 64,\n    MD4_DIGEST_SIZE = 16,\n    MD4_PAD_SIZE    = 56\n};\n\n\n/* MD4 digest */\ntypedef struct Md4 {\n    word32  buffLen;   /* in bytes          */\n    word32  loLen;     /* length in bytes   */\n    word32  hiLen;     /* length in bytes   */\n    word32  digest[MD4_DIGEST_SIZE / sizeof(word32)];\n    word32  buffer[MD4_BLOCK_SIZE  / sizeof(word32)];\n} Md4;\n\n\nWOLFSSL_API void wc_InitMd4(Md4*);\nWOLFSSL_API void wc_Md4Update(Md4*, const byte*, word32);\nWOLFSSL_API void wc_Md4Final(Md4*, byte*);\n\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* NO_MD4 */\n#endif /* WOLF_CRYPT_MD4_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/md5.h",
    "content": "/* md5.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/md5.h\n*/\n\n\n#ifndef WOLF_CRYPT_MD5_H\n#define WOLF_CRYPT_MD5_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_MD5\n\n#ifdef HAVE_FIPS\n    #define wc_InitMd5   InitMd5\n    #define wc_Md5Update Md5Update\n    #define wc_Md5Final  Md5Final\n    #define wc_Md5Hash   Md5Hash\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifndef NO_OLD_WC_NAMES\n    #define Md5             wc_Md5\n    #define MD5             WC_MD5\n    #define MD5_BLOCK_SIZE  WC_MD5_BLOCK_SIZE\n    #define MD5_DIGEST_SIZE WC_MD5_DIGEST_SIZE\n    #define WC_MD5_PAD_SIZE WC_MD5_PAD_SIZE\n#endif\n\n/* in bytes */\nenum {\n    WC_MD5             =  WC_HASH_TYPE_MD5,\n    WC_MD5_BLOCK_SIZE  = 64,\n    WC_MD5_DIGEST_SIZE = 16,\n    WC_MD5_PAD_SIZE    = 56\n};\n\n\n#ifdef WOLFSSL_MICROCHIP_PIC32MZ\n    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>\n#endif\n#ifdef STM32_HASH\n    #include <wolfssl/wolfcrypt/port/st/stm32.h>\n#endif\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n\n#ifdef WOLFSSL_TI_HASH\n    #include \"wolfssl/wolfcrypt/port/ti/ti-hash.h\"\n#elif defined(WOLFSSL_IMX6_CAAM)\n    #include \"wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h\"\n#else\n\n/* MD5 digest */\ntypedef struct wc_Md5 {\n#ifdef STM32_HASH\n    STM32_HASH_Context stmCtx;\n#else\n    word32  buffLen;   /* in bytes          */\n    word32  loLen;     /* length in bytes   */\n    word32  hiLen;     /* length in bytes   */\n    word32  buffer[WC_MD5_BLOCK_SIZE  / sizeof(word32)];\n#ifdef WOLFSSL_PIC32MZ_HASH\n    word32  digest[PIC32_DIGEST_SIZE / sizeof(word32)];\n#else\n    word32  digest[WC_MD5_DIGEST_SIZE / sizeof(word32)];\n#endif\n    void*   heap;\n#ifdef WOLFSSL_PIC32MZ_HASH\n    hashUpdCache cache; /* cache for updates */\n#endif\n#endif /* STM32_HASH */\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV asyncDev;\n#endif /* WOLFSSL_ASYNC_CRYPT */\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    word32 flags; /* enum wc_HashFlags in hash.h */\n#endif\n} wc_Md5;\n\n#endif /* WOLFSSL_TI_HASH */\n\nWOLFSSL_API int wc_InitMd5(wc_Md5*);\nWOLFSSL_API int wc_InitMd5_ex(wc_Md5*, void*, int);\nWOLFSSL_API int wc_Md5Update(wc_Md5*, const byte*, word32);\nWOLFSSL_API int wc_Md5Final(wc_Md5*, byte*);\nWOLFSSL_API void wc_Md5Free(wc_Md5*);\n\nWOLFSSL_API int  wc_Md5GetHash(wc_Md5*, byte*);\nWOLFSSL_API int  wc_Md5Copy(wc_Md5*, wc_Md5*);\n\n#ifdef WOLFSSL_PIC32MZ_HASH\nWOLFSSL_API void wc_Md5SizeSet(wc_Md5* md5, word32 len);\n#endif\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    WOLFSSL_API int wc_Md5SetFlags(wc_Md5* md5, word32 flags);\n    WOLFSSL_API int wc_Md5GetFlags(wc_Md5* md5, word32* flags);\n#endif\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* NO_MD5 */\n#endif /* WOLF_CRYPT_MD5_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/mem_track.h",
    "content": "/* mem_track.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n/* The memory tracker overrides the wolfSSL memory callback system and uses a\n * static to track the total, peak and currently allocated bytes.\n *\n * If you are already using the memory callbacks then enabling this will\n * override the memory callbacks and prevent your memory callbacks from\n * working. This assumes malloc() and free() are available. Feel free to\n * customize this for your needs.\n\n * The enable this feature define the following:\n * #define USE_WOLFSSL_MEMORY\n * #define WOLFSSL_TRACK_MEMORY\n *\n * On startup call:\n * InitMemoryTracker();\n *\n * When ready to dump the memory report call:\n * ShowMemoryTracker();\n *\n * Report example:\n * total   Allocs =       228\n * total   Bytes  =     93442\n * peak    Bytes  =      8840\n * current Bytes  =         0\n *\n *\n * You can also:\n * #define WOLFSSL_DEBUG_MEMORY\n *\n * To print every alloc/free along with the function and line number.\n * Example output:\n * Alloc: 0x7fa14a500010 -> 120 at wc_InitRng:496\n * Free: 0x7fa14a500010 -> 120 at wc_FreeRng:606\n */\n\n\n#ifndef WOLFSSL_MEM_TRACK_H\n#define WOLFSSL_MEM_TRACK_H\n\n#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)\n\n    #include \"wolfssl/wolfcrypt/logging.h\"\n\n    #if defined(WOLFSSL_TRACK_MEMORY)\n        #define DO_MEM_STATS\n        #if defined(__linux__) || defined(__MACH__)\n            #define DO_MEM_LIST\n        #endif\n    #endif\n\n\n    typedef struct memoryStats {\n        long totalAllocs;     /* number of allocations */\n        long totalDeallocs;   /* number of deallocations */\n        long totalBytes;      /* total number of bytes allocated */\n        long peakBytes;       /* concurrent max bytes */\n        long currentBytes;    /* total current bytes in use */\n    } memoryStats;\n\n    typedef struct memHint {\n        size_t thisSize;      /* size of this memory */\n\n    #ifdef DO_MEM_LIST\n        struct memHint* next;\n        struct memHint* prev;\n        #ifdef WOLFSSL_DEBUG_MEMORY\n            const char* func;\n            unsigned int line;\n        #endif\n    #endif\n        void*  thisMemory;    /* actual memory for user */\n    } memHint;\n\n    typedef struct memoryTrack {\n        union {\n            memHint hint;\n            byte    alignit[sizeof(memHint) + ((16-1) & ~(16-1))]; /* make sure we have strong alignment */\n        } u;\n    } memoryTrack;\n\n#ifdef DO_MEM_LIST\n    /* track allocations and report at end */\n    typedef struct memoryList {\n        memHint* head;\n        memHint* tail;\n        word32   count;\n    } memoryList;\n#endif\n\n#if defined(WOLFSSL_TRACK_MEMORY)\n    static memoryStats ourMemStats;\n\n    #ifdef DO_MEM_LIST\n        #include <pthread.h>\n        static memoryList ourMemList;\n        static pthread_mutex_t memLock = PTHREAD_MUTEX_INITIALIZER;\n    #endif\n#endif\n\n\n    /* if defined to not using inline then declare function prototypes */\n    #ifdef NO_INLINE\n        #define WC_STATIC\n\t\t#ifdef WOLFSSL_DEBUG_MEMORY\n\t\t\tWOLFSSL_LOCAL void* TrackMalloc(size_t sz, const char* func, unsigned int line);\n\t\t\tWOLFSSL_LOCAL void TrackFree(void* ptr, const char* func, unsigned int line);\n\t\t\tWOLFSSL_LOCAL void* TrackRealloc(void* ptr, size_t sz, const char* func, unsigned int line);\n\t\t#else\n\t\t\tWOLFSSL_LOCAL void* TrackMalloc(size_t sz);\n\t\t\tWOLFSSL_LOCAL void TrackFree(void* ptr);\n\t\t\tWOLFSSL_LOCAL void* TrackRealloc(void* ptr, size_t sz);\n\t\t#endif\n        WOLFSSL_LOCAL int InitMemoryTracker(void);\n        WOLFSSL_LOCAL void ShowMemoryTracker(void);\n    #else\n        #define WC_STATIC static\n    #endif\n\n#ifdef WOLFSSL_DEBUG_MEMORY\n    WC_STATIC WC_INLINE void* TrackMalloc(size_t sz, const char* func, unsigned int line)\n#else\n    WC_STATIC WC_INLINE void* TrackMalloc(size_t sz)\n#endif\n    {\n        memoryTrack* mt;\n        memHint* header;\n\n        if (sz == 0)\n            return NULL;\n\n        mt = (memoryTrack*)malloc(sizeof(memoryTrack) + sz);\n        if (mt == NULL)\n            return NULL;\n\n        header = &mt->u.hint;\n        header->thisSize   = sz;\n        header->thisMemory = (byte*)mt + sizeof(memoryTrack);\n\n    #ifdef WOLFSSL_DEBUG_MEMORY\n    #ifdef WOLFSSL_DEBUG_MEMORY_PRINT\n        printf(\"Alloc: %p -> %u at %s:%d\\n\", header->thisMemory, (word32)sz, func, line);\n    #else\n        (void)func;\n        (void)line;\n    #endif\n    #endif\n\n    #ifdef DO_MEM_STATS\n        ourMemStats.totalAllocs++;\n        ourMemStats.totalBytes   += sz;\n        ourMemStats.currentBytes += sz;\n        if (ourMemStats.currentBytes > ourMemStats.peakBytes)\n            ourMemStats.peakBytes = ourMemStats.currentBytes;\n    #endif\n    #ifdef DO_MEM_LIST\n        if (pthread_mutex_lock(&memLock) == 0) {\n        #ifdef WOLFSSL_DEBUG_MEMORY\n            header->func = func;\n            header->line = line;\n        #endif\n\n            /* Setup event */\n            header->next = NULL;\n            if (ourMemList.tail == NULL)  {\n                ourMemList.head = header;\n                header->prev = NULL;\n            }\n            else {\n                ourMemList.tail->next = header;\n                header->prev = ourMemList.tail;\n            }\n            ourMemList.tail = header;      /* add to the end either way */\n            ourMemList.count++;\n\n            pthread_mutex_unlock(&memLock);\n        }\n    #endif\n\n        return header->thisMemory;\n    }\n\n\n#ifdef WOLFSSL_DEBUG_MEMORY\n    WC_STATIC WC_INLINE void TrackFree(void* ptr, const char* func, unsigned int line)\n#else\n    WC_STATIC WC_INLINE void TrackFree(void* ptr)\n#endif\n    {\n        memoryTrack* mt;\n        memHint* header;\n        size_t sz;\n\n        if (ptr == NULL) {\n            return;\n        }\n\n        mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack));\n        header = &mt->u.hint;\n        sz = header->thisSize;\n\n    #ifdef DO_MEM_LIST\n        if (pthread_mutex_lock(&memLock) == 0) \n        {\n    #endif\n\n    #ifdef DO_MEM_STATS\n            ourMemStats.currentBytes -= header->thisSize;\n            ourMemStats.totalDeallocs++;\n    #endif\n\n    #ifdef DO_MEM_LIST\n            if (header == ourMemList.head && header == ourMemList.tail) {\n                ourMemList.head = NULL;\n                ourMemList.tail = NULL;\n            }\n            else if (header == ourMemList.head) {\n                ourMemList.head = header->next;\n                ourMemList.head->prev = NULL;\n            }\n            else if (header == ourMemList.tail) {\n                ourMemList.tail = header->prev;\n                ourMemList.tail->next = NULL;\n            }\n            else {\n                memHint* next = header->next;\n                memHint* prev = header->prev;\n                if (next)\n                    next->prev = prev;\n                if (prev)\n                    prev->next = next;\n            }\n            ourMemList.count--;\n\n            pthread_mutex_unlock(&memLock);\n        }\n    #endif\n\n#ifdef WOLFSSL_DEBUG_MEMORY\n#ifdef WOLFSSL_DEBUG_MEMORY_PRINT\n        printf(\"Free: %p -> %u at %s:%d\\n\", ptr, (word32)sz, func, line);\n#else\n        (void)func;\n        (void)line;\n#endif\n#endif\n        (void)sz;\n\n        free(mt);\n    }\n\n\n#ifdef WOLFSSL_DEBUG_MEMORY\n    WC_STATIC WC_INLINE void* TrackRealloc(void* ptr, size_t sz, const char* func, unsigned int line)\n#else\n    WC_STATIC WC_INLINE void* TrackRealloc(void* ptr, size_t sz)\n#endif\n    {\n    #ifdef WOLFSSL_DEBUG_MEMORY\n        void* ret = TrackMalloc(sz, func, line);\n    #else\n        void* ret = TrackMalloc(sz);\n    #endif\n\n        if (ptr) {\n            /* if realloc is bigger, don't overread old ptr */\n            memoryTrack* mt;\n            memHint* header;\n\n            mt = (memoryTrack*)((byte*)ptr - sizeof(memoryTrack));\n            header = &mt->u.hint;\n\n            if (header->thisSize < sz)\n                sz = header->thisSize;\n        }\n\n        if (ret && ptr)\n            XMEMCPY(ret, ptr, sz);\n\n        if (ret) {\n        #ifdef WOLFSSL_DEBUG_MEMORY\n            TrackFree(ptr, func, line);\n        #else\n            TrackFree(ptr);\n        #endif\n        }\n\n        return ret;\n    }\n\n#ifdef WOLFSSL_TRACK_MEMORY\n    static wolfSSL_Malloc_cb mfDefault = NULL;\n    static wolfSSL_Free_cb ffDefault = NULL;\n    static wolfSSL_Realloc_cb rfDefault = NULL;\n\n    WC_STATIC WC_INLINE int InitMemoryTracker(void)\n    {\n        int ret;\n\n        ret = wolfSSL_GetAllocators(&mfDefault, &ffDefault, &rfDefault);\n        if (ret < 0) {\n            printf(\"wolfSSL GetAllocators failed to get the defaults\\n\");\n        }\n        ret = wolfSSL_SetAllocators(TrackMalloc, TrackFree, TrackRealloc);\n        if (ret < 0) {\n            printf(\"wolfSSL SetAllocators failed for track memory\\n\");\n            return ret;\n        }\n\n    #ifdef DO_MEM_LIST\n        if (pthread_mutex_lock(&memLock) == 0)\n        {\n    #endif\n\n    #ifdef DO_MEM_STATS\n        ourMemStats.totalAllocs  = 0;\n        ourMemStats.totalDeallocs = 0;\n        ourMemStats.totalBytes   = 0;\n        ourMemStats.peakBytes    = 0;\n        ourMemStats.currentBytes = 0;\n    #endif\n    \n    #ifdef DO_MEM_LIST\n        XMEMSET(&ourMemList, 0, sizeof(ourMemList));\n\n        pthread_mutex_unlock(&memLock);\n        }\n    #endif\n\n        return ret;\n    }\n\n    WC_STATIC WC_INLINE void ShowMemoryTracker(void)\n    {\n    #ifdef DO_MEM_LIST\n        if (pthread_mutex_lock(&memLock) == 0)\n        {\n    #endif\n\n    #ifdef DO_MEM_STATS\n        printf(\"total   Allocs   = %9ld\\n\", ourMemStats.totalAllocs);\n        printf(\"total   Deallocs = %9ld\\n\", ourMemStats.totalDeallocs);\n        printf(\"total   Bytes    = %9ld\\n\", ourMemStats.totalBytes);\n        printf(\"peak    Bytes    = %9ld\\n\", ourMemStats.peakBytes);\n        printf(\"current Bytes    = %9ld\\n\", ourMemStats.currentBytes);\n    #endif\n\n    #ifdef DO_MEM_LIST\n        if (ourMemList.count > 0) {\n            /* print list of allocations */\n            memHint* header;\n            for (header = ourMemList.head; header != NULL; header = header->next) {\n                printf(\"Leak: Ptr %p, Size %u\"\n                #ifdef WOLFSSL_DEBUG_MEMORY\n                    \", Func %s, Line %d\"\n                #endif\n                    \"\\n\",\n                    (byte*)header + sizeof(memHint), (unsigned int)header->thisSize\n                #ifdef WOLFSSL_DEBUG_MEMORY\n                    , header->func, header->line\n                #endif\n                );\n            }\n        }\n\n        pthread_mutex_unlock(&memLock);\n        }\n    #endif\n    }\n\n    WC_STATIC WC_INLINE int CleanupMemoryTracker(void)\n    {\n        /* restore default allocators */\n        return wolfSSL_SetAllocators(mfDefault, ffDefault, rfDefault);\n    }\n#endif\n\n#endif /* USE_WOLFSSL_MEMORY */\n\n#endif /* WOLFSSL_MEM_TRACK_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/memory.h",
    "content": "/* memory.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n/* submitted by eof */\n\n/*!\n    \\file wolfssl/wolfcrypt/memory.h\n*/\n\n#ifndef WOLFSSL_MEMORY_H\n#define WOLFSSL_MEMORY_H\n\n#ifndef STRING_USER\n#include <stdlib.h>\n#endif\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST\n    WOLFSSL_API void wolfSSL_SetMemFailCount(int memFailCount);\n#endif\n\n#ifdef WOLFSSL_STATIC_MEMORY\n    #ifdef WOLFSSL_DEBUG_MEMORY\n        typedef void *(*wolfSSL_Malloc_cb)(size_t size, void* heap, int type, const char* func, unsigned int line);\n        typedef void (*wolfSSL_Free_cb)(void *ptr, void* heap, int type, const char* func, unsigned int line);\n        typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line);\n        WOLFSSL_API void* wolfSSL_Malloc(size_t size, void* heap, int type, const char* func, unsigned int line);\n        WOLFSSL_API void  wolfSSL_Free(void *ptr, void* heap, int type, const char* func, unsigned int line);\n        WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line);\n    #else\n        typedef void *(*wolfSSL_Malloc_cb)(size_t size, void* heap, int type);\n        typedef void (*wolfSSL_Free_cb)(void *ptr, void* heap, int type);\n        typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, void* heap, int type);\n        WOLFSSL_API void* wolfSSL_Malloc(size_t size, void* heap, int type);\n        WOLFSSL_API void  wolfSSL_Free(void *ptr, void* heap, int type);\n        WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type);\n    #endif /* WOLFSSL_DEBUG_MEMORY */\n#else\n    #ifdef WOLFSSL_DEBUG_MEMORY\n        typedef void *(*wolfSSL_Malloc_cb)(size_t size, const char* func, unsigned int line);\n        typedef void (*wolfSSL_Free_cb)(void *ptr, const char* func, unsigned int line);\n        typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, const char* func, unsigned int line);\n\n        /* Public in case user app wants to use XMALLOC/XFREE */\n        WOLFSSL_API void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line);\n        WOLFSSL_API void  wolfSSL_Free(void *ptr, const char* func, unsigned int line);\n        WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line);\n    #else\n        typedef void *(*wolfSSL_Malloc_cb)(size_t size);\n        typedef void (*wolfSSL_Free_cb)(void *ptr);\n        typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size);\n        /* Public in case user app wants to use XMALLOC/XFREE */\n        WOLFSSL_API void* wolfSSL_Malloc(size_t size);\n        WOLFSSL_API void  wolfSSL_Free(void *ptr);\n        WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size);\n    #endif /* WOLFSSL_DEBUG_MEMORY */\n#endif /* WOLFSSL_STATIC_MEMORY */\n\n/* Public get/set functions */\nWOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb,\n                                      wolfSSL_Free_cb,\n                                      wolfSSL_Realloc_cb);\nWOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb*,\n                                      wolfSSL_Free_cb*,\n                                      wolfSSL_Realloc_cb*);\n\n#ifdef WOLFSSL_STATIC_MEMORY\n    #define WOLFSSL_STATIC_TIMEOUT 1\n    #ifndef WOLFSSL_STATIC_ALIGN\n        #define WOLFSSL_STATIC_ALIGN 16\n    #endif\n    #ifndef WOLFMEM_MAX_BUCKETS\n        #define WOLFMEM_MAX_BUCKETS  9\n    #endif\n    #define WOLFMEM_DEF_BUCKETS  9     /* number of default memory blocks */\n    #ifndef WOLFMEM_IO_SZ\n        #define WOLFMEM_IO_SZ        16992 /* 16 byte aligned */\n    #endif\n    #ifndef WOLFMEM_BUCKETS\n        #ifndef SESSION_CERTS\n            /* default size of chunks of memory to separate into */\n            #ifndef LARGEST_MEM_BUCKET\n                #define LARGEST_MEM_BUCKET 16128\n            #endif\n            #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,\\\n                                    LARGEST_MEM_BUCKET\n        #elif defined (OPENSSL_EXTRA)\n            /* extra storage in structs for multiple attributes and order */\n            #ifndef LARGEST_MEM_BUCKET\n                #define LARGEST_MEM_BUCKET 25536\n            #endif\n            #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3360,4480,\\\n                                    LARGEST_MEM_BUCKET\n        #elif defined (WOLFSSL_CERT_EXT)\n            /* certificate extensions requires 24k for the SSL struct */\n            #ifndef LARGEST_MEM_BUCKET\n                #define LARGEST_MEM_BUCKET 24576\n            #endif\n            #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,\\\n                                    LARGEST_MEM_BUCKET\n        #else\n            /* increase 23k for object member of WOLFSSL_X509_NAME_ENTRY */\n            #ifndef LARGEST_MEM_BUCKET\n                #define LARGEST_MEM_BUCKET 23440\n            #endif\n            #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,\\\n                                    LARGEST_MEM_BUCKET\n        #endif\n    #endif\n    #ifndef WOLFMEM_DIST\n        #ifndef WOLFSSL_STATIC_MEMORY_SMALL\n            #define WOLFMEM_DIST    49,10,6,14,5,6,9,1,1\n        #else\n            /* Low resource and not RSA */\n            #define WOLFMEM_DIST    29, 7,6, 9,4,4,0,0,0\n        #endif\n    #endif\n\n    /* flags for loading static memory (one hot bit) */\n    #define WOLFMEM_GENERAL       0x01\n    #define WOLFMEM_IO_POOL       0x02\n    #define WOLFMEM_IO_POOL_FIXED 0x04\n    #define WOLFMEM_TRACK_STATS   0x08\n\n    #ifndef WOLFSSL_MEM_GUARD\n    #define WOLFSSL_MEM_GUARD\n        typedef struct WOLFSSL_MEM_STATS      WOLFSSL_MEM_STATS;\n        typedef struct WOLFSSL_MEM_CONN_STATS WOLFSSL_MEM_CONN_STATS;\n    #endif\n\n    struct WOLFSSL_MEM_CONN_STATS {\n        word32 peakMem;   /* peak memory usage    */\n        word32 curMem;    /* current memory usage */\n        word32 peakAlloc; /* peak memory allocations */\n        word32 curAlloc;  /* current memory allocations */\n        word32 totalAlloc;/* total memory allocations for lifetime */\n        word32 totalFr;   /* total frees for lifetime */\n    };\n\n    struct WOLFSSL_MEM_STATS {\n        word32 curAlloc;  /* current memory allocations */\n        word32 totalAlloc;/* total memory allocations for lifetime */\n        word32 totalFr;   /* total frees for lifetime */\n        word32 totalUse;  /* total amount of memory used in blocks */\n        word32 avaIO;     /* available IO specific pools */\n        word32 maxHa;     /* max number of concurent handshakes allowed */\n        word32 maxIO;     /* max number of concurent IO connections allowed */\n        word32 blockSz[WOLFMEM_MAX_BUCKETS]; /* block sizes in stacks */\n        word32 avaBlock[WOLFMEM_MAX_BUCKETS];/* ava block sizes */\n        word32 usedBlock[WOLFMEM_MAX_BUCKETS];\n        int    flag; /* flag used */\n    };\n\n    typedef struct wc_Memory wc_Memory; /* internal structure for mem bucket */\n    typedef struct WOLFSSL_HEAP {\n        wc_Memory* ava[WOLFMEM_MAX_BUCKETS];\n        wc_Memory* io;                  /* list of buffers to use for IO */\n        word32     maxHa;               /* max concurent handshakes */\n        word32     curHa;\n        word32     maxIO;               /* max concurrent IO connections */\n        word32     curIO;\n        word32     sizeList[WOLFMEM_MAX_BUCKETS];/* memory sizes in ava list */\n        word32     distList[WOLFMEM_MAX_BUCKETS];/* general distribution */\n        word32     inUse; /* amount of memory currently in use */\n        word32     ioUse;\n        word32     alloc; /* total number of allocs */\n        word32     frAlc; /* total number of frees  */\n        int        flag;\n        wolfSSL_Mutex memory_mutex;\n    } WOLFSSL_HEAP;\n\n    /* structure passed into XMALLOC as heap hint\n     * having this abstraction allows tracking statistics of individual ssl's\n     */\n    typedef struct WOLFSSL_HEAP_HINT {\n        WOLFSSL_HEAP*           memory;\n        WOLFSSL_MEM_CONN_STATS* stats;  /* hold individual connection stats */\n        wc_Memory*  outBuf; /* set if using fixed io buffers */\n        wc_Memory*  inBuf;\n        byte        haFlag; /* flag used for checking handshake count */\n    } WOLFSSL_HEAP_HINT;\n\n    WOLFSSL_API int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint,\n            unsigned char* buf, unsigned int sz, int flag, int max);\n\n    WOLFSSL_LOCAL int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap);\n    WOLFSSL_LOCAL int wolfSSL_load_static_memory(byte* buffer, word32 sz,\n                                                  int flag, WOLFSSL_HEAP* heap);\n    WOLFSSL_LOCAL int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap,\n                                                      WOLFSSL_MEM_STATS* stats);\n    WOLFSSL_LOCAL int SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io);\n    WOLFSSL_LOCAL int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io);\n\n    WOLFSSL_API int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag);\n    WOLFSSL_API int wolfSSL_MemoryPaddingSz(void);\n#endif /* WOLFSSL_STATIC_MEMORY */\n\n#ifdef WOLFSSL_STACK_LOG\n    WOLFSSL_API void __attribute__((no_instrument_function))\n            __cyg_profile_func_enter(void *func,  void *caller);\n    WOLFSSL_API void __attribute__((no_instrument_function))\n            __cyg_profile_func_exit(void *func, void *caller);\n#endif /* WOLFSSL_STACK_LOG */\n\n#ifdef __cplusplus\n    }  /* extern \"C\" */\n#endif\n\n#endif /* WOLFSSL_MEMORY_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/misc.h",
    "content": "/* misc.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#ifndef WOLF_CRYPT_MISC_H\n#define WOLF_CRYPT_MISC_H\n\n\n#include <wolfssl/wolfcrypt/types.h>\n\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n\n#ifdef NO_INLINE\nWOLFSSL_LOCAL\nword32 rotlFixed(word32, word32);\nWOLFSSL_LOCAL\nword32 rotrFixed(word32, word32);\n\nWOLFSSL_LOCAL\nword32 ByteReverseWord32(word32);\nWOLFSSL_LOCAL\nvoid   ByteReverseWords(word32*, const word32*, word32);\n\nWOLFSSL_LOCAL\nvoid XorWords(wolfssl_word*, const wolfssl_word*, word32);\nWOLFSSL_LOCAL\nvoid xorbuf(void*, const void*, word32);\n\nWOLFSSL_LOCAL\nvoid ForceZero(const void*, word32);\n\nWOLFSSL_LOCAL\nint ConstantCompare(const byte*, const byte*, int);\n\n#ifdef WORD64_AVAILABLE\nWOLFSSL_LOCAL\nword64 rotlFixed64(word64, word64);\nWOLFSSL_LOCAL\nword64 rotrFixed64(word64, word64);\n\nWOLFSSL_LOCAL\nword64 ByteReverseWord64(word64);\nWOLFSSL_LOCAL\nvoid   ByteReverseWords64(word64*, const word64*, word32);\n#endif /* WORD64_AVAILABLE */\n\n#ifndef WOLFSSL_HAVE_MIN\n    #if defined(HAVE_FIPS) && !defined(min) /* so ifdef check passes */\n        #define min min\n    #endif\n    WOLFSSL_LOCAL word32 min(word32 a, word32 b);\n#endif\n\n#ifndef WOLFSSL_HAVE_MAX\n    #if defined(HAVE_FIPS) && !defined(max) /* so ifdef check passes */\n        #define max max\n    #endif\n    WOLFSSL_LOCAL word32 max(word32 a, word32 b);\n#endif /* WOLFSSL_HAVE_MAX */\n\n\nvoid c32to24(word32 in, word24 out);\nvoid c16toa(word16 u16, byte* c);\nvoid c32toa(word32 u32, byte* c);\nvoid c24to32(const word24 u24, word32* u32);\nvoid ato16(const byte* c, word16* u16);\nvoid ato24(const byte* c, word32* u24);\nvoid ato32(const byte* c, word32* u32);\nword32 btoi(byte b);\n\n\nWOLFSSL_LOCAL byte ctMaskGT(int a, int b);\nWOLFSSL_LOCAL byte ctMaskGTE(int a, int b);\nWOLFSSL_LOCAL int  ctMaskIntGTE(int a, int b);\nWOLFSSL_LOCAL byte ctMaskLT(int a, int b);\nWOLFSSL_LOCAL byte ctMaskLTE(int a, int b);\nWOLFSSL_LOCAL byte ctMaskEq(int a, int b);\nWOLFSSL_LOCAL word16 ctMask16Eq(int a, int b);\nWOLFSSL_LOCAL byte ctMaskNotEq(int a, int b);\nWOLFSSL_LOCAL byte ctMaskSel(byte m, byte a, byte b);\nWOLFSSL_LOCAL int  ctMaskSelInt(byte m, int a, int b);\nWOLFSSL_LOCAL byte ctSetLTE(int a, int b);\n\n#endif /* NO_INLINE */\n\n\n#ifdef __cplusplus\n    }   /* extern \"C\" */\n#endif\n\n\n#endif /* WOLF_CRYPT_MISC_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/mpi_class.h",
    "content": "/* mpi_class.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))\n#if defined(LTM2)\n#define LTM3\n#endif\n#if defined(LTM1)\n#define LTM2\n#endif\n#define LTM1\n\n#if defined(LTM_ALL)\n#define BN_ERROR_C\n#define BN_FAST_MP_INVMOD_C\n#define BN_FAST_MP_MONTGOMERY_REDUCE_C\n#define BN_FAST_S_MP_MUL_DIGS_C\n#define BN_FAST_S_MP_MUL_HIGH_DIGS_C\n#define BN_FAST_S_MP_SQR_C\n#define BN_MP_2EXPT_C\n#define BN_MP_ABS_C\n#define BN_MP_ADD_C\n#define BN_MP_ADD_D_C\n#define BN_MP_ADDMOD_C\n#define BN_MP_AND_C\n#define BN_MP_CLAMP_C\n#define BN_MP_CLEAR_C\n#define BN_MP_CLEAR_MULTI_C\n#define BN_MP_CMP_C\n#define BN_MP_CMP_D_C\n#define BN_MP_CMP_MAG_C\n#define BN_MP_CNT_LSB_C\n#define BN_MP_COPY_C\n#define BN_MP_COUNT_BITS_C\n#define BN_MP_DIV_C\n#define BN_MP_DIV_2_C\n#define BN_MP_DIV_2D_C\n#define BN_MP_DIV_3_C\n#define BN_MP_DIV_D_C\n#define BN_MP_DR_IS_MODULUS_C\n#define BN_MP_DR_REDUCE_C\n#define BN_MP_DR_SETUP_C\n#define BN_MP_EXCH_C\n#define BN_MP_EXPT_D_C\n#define BN_MP_EXPTMOD_BASE_2\n#define BN_MP_EXPTMOD_C\n#define BN_MP_EXPTMOD_FAST_C\n#define BN_MP_EXTEUCLID_C\n#define BN_MP_FREAD_C\n#define BN_MP_FWRITE_C\n#define BN_MP_GCD_C\n#define BN_MP_GET_INT_C\n#define BN_MP_GROW_C\n#define BN_MP_INIT_C\n#define BN_MP_INIT_COPY_C\n#define BN_MP_INIT_MULTI_C\n#define BN_MP_INIT_SET_C\n#define BN_MP_INIT_SET_INT_C\n#define BN_MP_INIT_SIZE_C\n#define BN_MP_INVMOD_C\n#define BN_MP_INVMOD_SLOW_C\n#define BN_MP_IS_SQUARE_C\n#define BN_MP_JACOBI_C\n#define BN_MP_KARATSUBA_MUL_C\n#define BN_MP_KARATSUBA_SQR_C\n#define BN_MP_LCM_C\n#define BN_MP_LSHD_C\n#define BN_MP_MOD_C\n#define BN_MP_MOD_2D_C\n#define BN_MP_MOD_D_C\n#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C\n#define BN_MP_MONTGOMERY_REDUCE_C\n#define BN_MP_MONTGOMERY_SETUP_C\n#define BN_MP_MUL_C\n#define BN_MP_MUL_2_C\n#define BN_MP_MUL_2D_C\n#define BN_MP_MUL_D_C\n#define BN_MP_MULMOD_C\n#define BN_MP_N_ROOT_C\n#define BN_MP_NEG_C\n#define BN_MP_OR_C\n#define BN_MP_PRIME_FERMAT_C\n#define BN_MP_PRIME_IS_DIVISIBLE_C\n#define BN_MP_PRIME_IS_PRIME_C\n#define BN_MP_PRIME_MILLER_RABIN_C\n#define BN_MP_PRIME_NEXT_PRIME_C\n#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C\n#define BN_MP_PRIME_RANDOM_EX_C\n#define BN_MP_RADIX_SIZE_C\n#define BN_MP_RADIX_SMAP_C\n#define BN_MP_RAND_C\n#define BN_MP_READ_RADIX_C\n#define BN_MP_READ_SIGNED_BIN_C\n#define BN_MP_READ_UNSIGNED_BIN_C\n#define BN_MP_REDUCE_C\n#define BN_MP_REDUCE_2K_C\n#define BN_MP_REDUCE_2K_L_C\n#define BN_MP_REDUCE_2K_SETUP_C\n#define BN_MP_REDUCE_2K_SETUP_L_C\n#define BN_MP_REDUCE_IS_2K_C\n#define BN_MP_REDUCE_IS_2K_L_C\n#define BN_MP_REDUCE_SETUP_C\n#define BN_MP_RSHD_C\n#define BN_MP_SET_C\n#define BN_MP_SET_INT_C\n#define BN_MP_SHRINK_C\n#define BN_MP_SIGNED_BIN_SIZE_C\n#define BN_MP_SQR_C\n#define BN_MP_SQRMOD_C\n#define BN_MP_SQRT_C\n#define BN_MP_SUB_C\n#define BN_MP_SUB_D_C\n#define BN_MP_SUBMOD_C\n#define BN_MP_TO_SIGNED_BIN_C\n#define BN_MP_TO_SIGNED_BIN_N_C\n#define BN_MP_TO_UNSIGNED_BIN_C\n#define BN_MP_TO_UNSIGNED_BIN_N_C\n#define BN_MP_TOOM_MUL_C\n#define BN_MP_TOOM_SQR_C\n#define BN_MP_TORADIX_C\n#define BN_MP_TORADIX_N_C\n#define BN_MP_UNSIGNED_BIN_SIZE_C\n#define BN_MP_XOR_C\n#define BN_MP_ZERO_C\n#define BN_PRIME_TAB_C\n#define BN_REVERSE_C\n#define BN_S_MP_ADD_C\n#define BN_S_MP_EXPTMOD_C\n#define BN_S_MP_MUL_DIGS_C\n#define BN_S_MP_MUL_HIGH_DIGS_C\n#define BN_S_MP_SQR_C\n#define BN_S_MP_SUB_C\n#define BNCORE_C\n#endif\n\n#if defined(BN_ERROR_C)\n   #define BN_MP_ERROR_TO_STRING_C\n#endif\n\n#if defined(BN_FAST_MP_INVMOD_C)\n   #define BN_MP_ISEVEN_C\n   #define BN_MP_INIT_MULTI_C\n   #define BN_MP_COPY_C\n   #define BN_MP_MOD_C\n   #define BN_MP_SET_C\n   #define BN_MP_DIV_2_C\n   #define BN_MP_ISODD_C\n   #define BN_MP_SUB_C\n   #define BN_MP_CMP_C\n   #define BN_MP_ISZERO_C\n   #define BN_MP_CMP_D_C\n   #define BN_MP_ADD_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_MULTI_C\n#endif\n\n#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C)\n   #define BN_MP_GROW_C\n   #define BN_MP_RSHD_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_S_MP_SUB_C\n#endif\n\n#if defined(BN_FAST_S_MP_MUL_DIGS_C)\n   #define BN_MP_GROW_C\n   #define BN_MP_CLAMP_C\n#endif\n\n#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)\n   #define BN_MP_GROW_C\n   #define BN_MP_CLAMP_C\n#endif\n\n#if defined(BN_FAST_S_MP_SQR_C)\n   #define BN_MP_GROW_C\n   #define BN_MP_CLAMP_C\n#endif\n\n#if defined(BN_MP_2EXPT_C)\n   #define BN_MP_ZERO_C\n   #define BN_MP_GROW_C\n#endif\n\n#if defined(BN_MP_ABS_C)\n   #define BN_MP_COPY_C\n#endif\n\n#if defined(BN_MP_ADD_C)\n   #define BN_S_MP_ADD_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_S_MP_SUB_C\n#endif\n\n#if defined(BN_MP_ADD_D_C)\n   #define BN_MP_GROW_C\n   #define BN_MP_SUB_D_C\n   #define BN_MP_CLAMP_C\n#endif\n\n#if defined(BN_MP_ADDMOD_C)\n   #define BN_MP_INIT_C\n   #define BN_MP_ADD_C\n   #define BN_MP_CLEAR_C\n   #define BN_MP_MOD_C\n#endif\n\n#if defined(BN_MP_AND_C)\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_CLAMP_C)\n#endif\n\n#if defined(BN_MP_CLEAR_C)\n#endif\n\n#if defined(BN_MP_CLEAR_MULTI_C)\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_CMP_C)\n   #define BN_MP_CMP_MAG_C\n#endif\n\n#if defined(BN_MP_CMP_D_C)\n#endif\n\n#if defined(BN_MP_CMP_MAG_C)\n#endif\n\n#if defined(BN_MP_CNT_LSB_C)\n   #define BN_MP_ISZERO_C\n#endif\n\n#if defined(BN_MP_COPY_C)\n   #define BN_MP_GROW_C\n#endif\n\n#if defined(BN_MP_COUNT_BITS_C)\n#endif\n\n#if defined(BN_MP_DIV_C)\n   #define BN_MP_ISZERO_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_MP_COPY_C\n   #define BN_MP_ZERO_C\n   #define BN_MP_INIT_MULTI_C\n   #define BN_MP_SET_C\n   #define BN_MP_COUNT_BITS_C\n   #define BN_MP_ABS_C\n   #define BN_MP_MUL_2D_C\n   #define BN_MP_CMP_C\n   #define BN_MP_SUB_C\n   #define BN_MP_ADD_C\n   #define BN_MP_DIV_2D_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_MULTI_C\n   #define BN_MP_INIT_SIZE_C\n   #define BN_MP_INIT_C\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_LSHD_C\n   #define BN_MP_RSHD_C\n   #define BN_MP_MUL_D_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_DIV_2_C)\n   #define BN_MP_GROW_C\n   #define BN_MP_CLAMP_C\n#endif\n\n#if defined(BN_MP_DIV_2D_C)\n   #define BN_MP_COPY_C\n   #define BN_MP_ZERO_C\n   #define BN_MP_INIT_C\n   #define BN_MP_MOD_2D_C\n   #define BN_MP_CLEAR_C\n   #define BN_MP_RSHD_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_EXCH_C\n#endif\n\n#if defined(BN_MP_DIV_3_C)\n   #define BN_MP_INIT_SIZE_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_DIV_D_C)\n   #define BN_MP_ISZERO_C\n   #define BN_MP_COPY_C\n   #define BN_MP_DIV_2D_C\n   #define BN_MP_DIV_3_C\n   #define BN_MP_INIT_SIZE_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_DR_IS_MODULUS_C)\n#endif\n\n#if defined(BN_MP_DR_REDUCE_C)\n   #define BN_MP_GROW_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_S_MP_SUB_C\n#endif\n\n#if defined(BN_MP_DR_SETUP_C)\n#endif\n\n#if defined(BN_MP_EXCH_C)\n#endif\n\n#if defined(BN_MP_EXPT_D_C)\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_SET_C\n   #define BN_MP_SQR_C\n   #define BN_MP_CLEAR_C\n   #define BN_MP_MUL_C\n#endif\n\n#if defined(BN_MP_EXPTMOD_C)\n   #define BN_MP_INIT_C\n   #define BN_MP_INVMOD_C\n   #define BN_MP_CLEAR_C\n   #define BN_MP_ABS_C\n   #define BN_MP_CLEAR_MULTI_C\n   #define BN_MP_REDUCE_IS_2K_L_C\n   #define BN_S_MP_EXPTMOD_C\n   #define BN_MP_DR_IS_MODULUS_C\n   #define BN_MP_REDUCE_IS_2K_C\n   #define BN_MP_ISODD_C\n   #define BN_MP_EXPTMOD_FAST_C\n   #define BN_MP_EXPTMOD_BASE_2\n#endif\n\n#if defined(BN_MP_EXPTMOD_FAST_C)\n   #define BN_MP_COUNT_BITS_C\n   #define BN_MP_INIT_C\n   #define BN_MP_CLEAR_C\n   #define BN_MP_MONTGOMERY_SETUP_C\n   #define BN_FAST_MP_MONTGOMERY_REDUCE_C\n   #define BN_MP_MONTGOMERY_REDUCE_C\n   #define BN_MP_DR_SETUP_C\n   #define BN_MP_DR_REDUCE_C\n   #define BN_MP_REDUCE_2K_SETUP_C\n   #define BN_MP_REDUCE_2K_C\n   #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C\n   #define BN_MP_MULMOD_C\n   #define BN_MP_SET_C\n   #define BN_MP_MOD_C\n   #define BN_MP_COPY_C\n   #define BN_MP_SQR_C\n   #define BN_MP_MUL_C\n   #define BN_MP_EXCH_C\n#endif\n\n#if defined(BN_MP_EXTEUCLID_C)\n   #define BN_MP_INIT_MULTI_C\n   #define BN_MP_SET_C\n   #define BN_MP_COPY_C\n   #define BN_MP_ISZERO_C\n   #define BN_MP_DIV_C\n   #define BN_MP_MUL_C\n   #define BN_MP_SUB_C\n   #define BN_MP_NEG_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_MULTI_C\n#endif\n\n#if defined(BN_MP_FREAD_C)\n   #define BN_MP_ZERO_C\n   #define BN_MP_S_RMAP_C\n   #define BN_MP_MUL_D_C\n   #define BN_MP_ADD_D_C\n   #define BN_MP_CMP_D_C\n#endif\n\n#if defined(BN_MP_FWRITE_C)\n   #define BN_MP_RADIX_SIZE_C\n   #define BN_MP_TORADIX_C\n#endif\n\n#if defined(BN_MP_GCD_C)\n   #define BN_MP_ISZERO_C\n   #define BN_MP_ABS_C\n   #define BN_MP_ZERO_C\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_CNT_LSB_C\n   #define BN_MP_DIV_2D_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_MP_EXCH_C\n   #define BN_S_MP_SUB_C\n   #define BN_MP_MUL_2D_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_GET_INT_C)\n#endif\n\n#if defined(BN_MP_GROW_C)\n#endif\n\n#if defined(BN_MP_INIT_C)\n#endif\n\n#if defined(BN_MP_INIT_COPY_C)\n   #define BN_MP_COPY_C\n#endif\n\n#if defined(BN_MP_INIT_MULTI_C)\n   #define BN_MP_ERR_C\n   #define BN_MP_INIT_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_INIT_SET_C)\n   #define BN_MP_INIT_C\n   #define BN_MP_SET_C\n#endif\n\n#if defined(BN_MP_INIT_SET_INT_C)\n   #define BN_MP_INIT_C\n   #define BN_MP_SET_INT_C\n#endif\n\n#if defined(BN_MP_INIT_SIZE_C)\n   #define BN_MP_INIT_C\n#endif\n\n#if defined(BN_MP_INVMOD_C)\n   #define BN_MP_ISZERO_C\n   #define BN_MP_ISODD_C\n   #define BN_FAST_MP_INVMOD_C\n   #define BN_MP_INVMOD_SLOW_C\n#endif\n\n#if defined(BN_MP_INVMOD_SLOW_C)\n   #define BN_MP_ISZERO_C\n   #define BN_MP_INIT_MULTI_C\n   #define BN_MP_MOD_C\n   #define BN_MP_COPY_C\n   #define BN_MP_ISEVEN_C\n   #define BN_MP_SET_C\n   #define BN_MP_DIV_2_C\n   #define BN_MP_ISODD_C\n   #define BN_MP_ADD_C\n   #define BN_MP_SUB_C\n   #define BN_MP_CMP_C\n   #define BN_MP_CMP_D_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_MULTI_C\n#endif\n\n#if defined(BN_MP_IS_SQUARE_C)\n   #define BN_MP_MOD_D_C\n   #define BN_MP_INIT_SET_INT_C\n   #define BN_MP_MOD_C\n   #define BN_MP_GET_INT_C\n   #define BN_MP_SQRT_C\n   #define BN_MP_SQR_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_JACOBI_C)\n   #define BN_MP_CMP_D_C\n   #define BN_MP_ISZERO_C\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_CNT_LSB_C\n   #define BN_MP_DIV_2D_C\n   #define BN_MP_MOD_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_KARATSUBA_MUL_C)\n   #define BN_MP_MUL_C\n   #define BN_MP_INIT_SIZE_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_SUB_C\n   #define BN_MP_ADD_C\n   #define BN_MP_LSHD_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_KARATSUBA_SQR_C)\n   #define BN_MP_INIT_SIZE_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_SQR_C\n   #define BN_MP_SUB_C\n   #define BN_S_MP_ADD_C\n   #define BN_MP_LSHD_C\n   #define BN_MP_ADD_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_LCM_C)\n   #define BN_MP_INIT_MULTI_C\n   #define BN_MP_GCD_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_MP_DIV_C\n   #define BN_MP_MUL_C\n   #define BN_MP_CLEAR_MULTI_C\n#endif\n\n#if defined(BN_MP_LSHD_C)\n   #define BN_MP_GROW_C\n   #define BN_MP_RSHD_C\n#endif\n\n#if defined(BN_MP_MOD_C)\n   #define BN_MP_INIT_C\n   #define BN_MP_DIV_C\n   #define BN_MP_CLEAR_C\n   #define BN_MP_ADD_C\n   #define BN_MP_EXCH_C\n#endif\n\n#if defined(BN_MP_MOD_2D_C)\n   #define BN_MP_ZERO_C\n   #define BN_MP_COPY_C\n   #define BN_MP_CLAMP_C\n#endif\n\n#if defined(BN_MP_MOD_D_C)\n   #define BN_MP_DIV_D_C\n#endif\n\n#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C)\n   #define BN_MP_COUNT_BITS_C\n   #define BN_MP_2EXPT_C\n   #define BN_MP_SET_C\n   #define BN_MP_MUL_2_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_S_MP_SUB_C\n#endif\n\n#if defined(BN_MP_MONTGOMERY_REDUCE_C)\n   #define BN_FAST_MP_MONTGOMERY_REDUCE_C\n   #define BN_MP_GROW_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_RSHD_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_S_MP_SUB_C\n#endif\n\n#if defined(BN_MP_MONTGOMERY_SETUP_C)\n#endif\n\n#if defined(BN_MP_MUL_C)\n   #define BN_MP_TOOM_MUL_C\n   #define BN_MP_KARATSUBA_MUL_C\n   #define BN_FAST_S_MP_MUL_DIGS_C\n   #define BN_S_MP_MUL_C\n   #define BN_S_MP_MUL_DIGS_C\n#endif\n\n#if defined(BN_MP_MUL_2_C)\n   #define BN_MP_GROW_C\n#endif\n\n#if defined(BN_MP_MUL_2D_C)\n   #define BN_MP_COPY_C\n   #define BN_MP_GROW_C\n   #define BN_MP_LSHD_C\n   #define BN_MP_CLAMP_C\n#endif\n\n#if defined(BN_MP_MUL_D_C)\n   #define BN_MP_GROW_C\n   #define BN_MP_CLAMP_C\n#endif\n\n#if defined(BN_MP_MULMOD_C)\n   #define BN_MP_INIT_C\n   #define BN_MP_MUL_C\n   #define BN_MP_CLEAR_C\n   #define BN_MP_MOD_C\n#endif\n\n#if defined(BN_MP_N_ROOT_C)\n   #define BN_MP_INIT_C\n   #define BN_MP_SET_C\n   #define BN_MP_COPY_C\n   #define BN_MP_EXPT_D_C\n   #define BN_MP_MUL_C\n   #define BN_MP_SUB_C\n   #define BN_MP_MUL_D_C\n   #define BN_MP_DIV_C\n   #define BN_MP_CMP_C\n   #define BN_MP_SUB_D_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_NEG_C)\n   #define BN_MP_COPY_C\n   #define BN_MP_ISZERO_C\n#endif\n\n#if defined(BN_MP_OR_C)\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_PRIME_FERMAT_C)\n   #define BN_MP_CMP_D_C\n   #define BN_MP_INIT_C\n   #define BN_MP_EXPTMOD_C\n   #define BN_MP_CMP_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_PRIME_IS_DIVISIBLE_C)\n   #define BN_MP_MOD_D_C\n#endif\n\n#if defined(BN_MP_PRIME_IS_PRIME_C)\n   #define BN_MP_CMP_D_C\n   #define BN_MP_PRIME_IS_DIVISIBLE_C\n   #define BN_MP_INIT_C\n   #define BN_MP_SET_C\n   #define BN_MP_PRIME_MILLER_RABIN_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_PRIME_MILLER_RABIN_C)\n   #define BN_MP_CMP_D_C\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_SUB_D_C\n   #define BN_MP_CNT_LSB_C\n   #define BN_MP_DIV_2D_C\n   #define BN_MP_EXPTMOD_C\n   #define BN_MP_CMP_C\n   #define BN_MP_SQRMOD_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_PRIME_NEXT_PRIME_C)\n   #define BN_MP_CMP_D_C\n   #define BN_MP_SET_C\n   #define BN_MP_SUB_D_C\n   #define BN_MP_ISEVEN_C\n   #define BN_MP_MOD_D_C\n   #define BN_MP_INIT_C\n   #define BN_MP_ADD_D_C\n   #define BN_MP_PRIME_MILLER_RABIN_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C)\n#endif\n\n#if defined(BN_MP_PRIME_RANDOM_EX_C)\n   #define BN_MP_READ_UNSIGNED_BIN_C\n   #define BN_MP_PRIME_IS_PRIME_C\n   #define BN_MP_SUB_D_C\n   #define BN_MP_DIV_2_C\n   #define BN_MP_MUL_2_C\n   #define BN_MP_ADD_D_C\n#endif\n\n#if defined(BN_MP_RADIX_SIZE_C)\n   #define BN_MP_COUNT_BITS_C\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_ISZERO_C\n   #define BN_MP_DIV_D_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_RADIX_SMAP_C)\n   #define BN_MP_S_RMAP_C\n#endif\n\n#if defined(BN_MP_RAND_C)\n   #define BN_MP_ZERO_C\n   #define BN_MP_ADD_D_C\n   #define BN_MP_LSHD_C\n#endif\n\n#if defined(BN_MP_READ_RADIX_C)\n   #define BN_MP_ZERO_C\n   #define BN_MP_S_RMAP_C\n   #define BN_MP_RADIX_SMAP_C\n   #define BN_MP_MUL_D_C\n   #define BN_MP_ADD_D_C\n   #define BN_MP_ISZERO_C\n#endif\n\n#if defined(BN_MP_READ_SIGNED_BIN_C)\n   #define BN_MP_READ_UNSIGNED_BIN_C\n#endif\n\n#if defined(BN_MP_READ_UNSIGNED_BIN_C)\n   #define BN_MP_GROW_C\n   #define BN_MP_ZERO_C\n   #define BN_MP_MUL_2D_C\n   #define BN_MP_CLAMP_C\n#endif\n\n#if defined(BN_MP_REDUCE_C)\n   #define BN_MP_REDUCE_SETUP_C\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_RSHD_C\n   #define BN_MP_MUL_C\n   #define BN_S_MP_MUL_HIGH_DIGS_C\n   #define BN_FAST_S_MP_MUL_HIGH_DIGS_C\n   #define BN_MP_MOD_2D_C\n   #define BN_S_MP_MUL_DIGS_C\n   #define BN_MP_SUB_C\n   #define BN_MP_CMP_D_C\n   #define BN_MP_SET_C\n   #define BN_MP_LSHD_C\n   #define BN_MP_ADD_C\n   #define BN_MP_CMP_C\n   #define BN_S_MP_SUB_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_REDUCE_2K_C)\n   #define BN_MP_INIT_C\n   #define BN_MP_COUNT_BITS_C\n   #define BN_MP_DIV_2D_C\n   #define BN_MP_MUL_D_C\n   #define BN_S_MP_ADD_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_S_MP_SUB_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_REDUCE_2K_L_C)\n   #define BN_MP_INIT_C\n   #define BN_MP_COUNT_BITS_C\n   #define BN_MP_DIV_2D_C\n   #define BN_MP_MUL_C\n   #define BN_S_MP_ADD_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_S_MP_SUB_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_REDUCE_2K_SETUP_C)\n   #define BN_MP_INIT_C\n   #define BN_MP_COUNT_BITS_C\n   #define BN_MP_2EXPT_C\n   #define BN_MP_CLEAR_C\n   #define BN_S_MP_SUB_C\n#endif\n\n#if defined(BN_MP_REDUCE_2K_SETUP_L_C)\n   #define BN_MP_INIT_C\n   #define BN_MP_2EXPT_C\n   #define BN_MP_COUNT_BITS_C\n   #define BN_S_MP_SUB_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_REDUCE_IS_2K_C)\n   #define BN_MP_REDUCE_2K_C\n   #define BN_MP_COUNT_BITS_C\n#endif\n\n#if defined(BN_MP_REDUCE_IS_2K_L_C)\n#endif\n\n#if defined(BN_MP_REDUCE_SETUP_C)\n   #define BN_MP_2EXPT_C\n   #define BN_MP_DIV_C\n#endif\n\n#if defined(BN_MP_RSHD_C)\n   #define BN_MP_ZERO_C\n#endif\n\n#if defined(BN_MP_SET_C)\n   #define BN_MP_ZERO_C\n#endif\n\n#if defined(BN_MP_SET_INT_C)\n   #define BN_MP_ZERO_C\n   #define BN_MP_MUL_2D_C\n   #define BN_MP_CLAMP_C\n#endif\n\n#if defined(BN_MP_SHRINK_C)\n#endif\n\n#if defined(BN_MP_SIGNED_BIN_SIZE_C)\n   #define BN_MP_UNSIGNED_BIN_SIZE_C\n#endif\n\n#if defined(BN_MP_SQR_C)\n   #define BN_MP_TOOM_SQR_C\n   #define BN_MP_KARATSUBA_SQR_C\n   #define BN_FAST_S_MP_SQR_C\n   #define BN_S_MP_SQR_C\n#endif\n\n#if defined(BN_MP_SQRMOD_C)\n   #define BN_MP_INIT_C\n   #define BN_MP_SQR_C\n   #define BN_MP_CLEAR_C\n   #define BN_MP_MOD_C\n#endif\n\n#if defined(BN_MP_SQRT_C)\n   #define BN_MP_N_ROOT_C\n   #define BN_MP_ISZERO_C\n   #define BN_MP_ZERO_C\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_RSHD_C\n   #define BN_MP_DIV_C\n   #define BN_MP_ADD_C\n   #define BN_MP_DIV_2_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_SUB_C)\n   #define BN_S_MP_ADD_C\n   #define BN_MP_CMP_MAG_C\n   #define BN_S_MP_SUB_C\n#endif\n\n#if defined(BN_MP_SUB_D_C)\n   #define BN_MP_GROW_C\n   #define BN_MP_ADD_D_C\n   #define BN_MP_CLAMP_C\n#endif\n\n#if defined(BN_MP_SUBMOD_C)\n   #define BN_MP_INIT_C\n   #define BN_MP_SUB_C\n   #define BN_MP_CLEAR_C\n   #define BN_MP_MOD_C\n#endif\n\n#if defined(BN_MP_TO_SIGNED_BIN_C)\n   #define BN_MP_TO_UNSIGNED_BIN_C\n#endif\n\n#if defined(BN_MP_TO_SIGNED_BIN_N_C)\n   #define BN_MP_SIGNED_BIN_SIZE_C\n   #define BN_MP_TO_SIGNED_BIN_C\n#endif\n\n#if defined(BN_MP_TO_UNSIGNED_BIN_C)\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_ISZERO_C\n   #define BN_MP_DIV_2D_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_TO_UNSIGNED_BIN_N_C)\n   #define BN_MP_UNSIGNED_BIN_SIZE_C\n   #define BN_MP_TO_UNSIGNED_BIN_C\n#endif\n\n#if defined(BN_MP_TOOM_MUL_C)\n   #define BN_MP_INIT_MULTI_C\n   #define BN_MP_MOD_2D_C\n   #define BN_MP_COPY_C\n   #define BN_MP_RSHD_C\n   #define BN_MP_MUL_C\n   #define BN_MP_MUL_2_C\n   #define BN_MP_ADD_C\n   #define BN_MP_SUB_C\n   #define BN_MP_DIV_2_C\n   #define BN_MP_MUL_2D_C\n   #define BN_MP_MUL_D_C\n   #define BN_MP_DIV_3_C\n   #define BN_MP_LSHD_C\n   #define BN_MP_CLEAR_MULTI_C\n#endif\n\n#if defined(BN_MP_TOOM_SQR_C)\n   #define BN_MP_INIT_MULTI_C\n   #define BN_MP_MOD_2D_C\n   #define BN_MP_COPY_C\n   #define BN_MP_RSHD_C\n   #define BN_MP_SQR_C\n   #define BN_MP_MUL_2_C\n   #define BN_MP_ADD_C\n   #define BN_MP_SUB_C\n   #define BN_MP_DIV_2_C\n   #define BN_MP_MUL_2D_C\n   #define BN_MP_MUL_D_C\n   #define BN_MP_DIV_3_C\n   #define BN_MP_LSHD_C\n   #define BN_MP_CLEAR_MULTI_C\n#endif\n\n#if defined(BN_MP_TORADIX_C)\n   #define BN_MP_ISZERO_C\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_DIV_D_C\n   #define BN_MP_CLEAR_C\n   #define BN_MP_S_RMAP_C\n#endif\n\n#if defined(BN_MP_TORADIX_N_C)\n   #define BN_MP_ISZERO_C\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_DIV_D_C\n   #define BN_MP_CLEAR_C\n   #define BN_MP_S_RMAP_C\n#endif\n\n#if defined(BN_MP_UNSIGNED_BIN_SIZE_C)\n   #define BN_MP_COUNT_BITS_C\n#endif\n\n#if defined(BN_MP_XOR_C)\n   #define BN_MP_INIT_COPY_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_MP_ZERO_C)\n#endif\n\n#if defined(BN_PRIME_TAB_C)\n#endif\n\n#if defined(BN_REVERSE_C)\n#endif\n\n#if defined(BN_S_MP_ADD_C)\n   #define BN_MP_GROW_C\n   #define BN_MP_CLAMP_C\n#endif\n\n#if defined(BN_S_MP_EXPTMOD_C)\n   #define BN_MP_COUNT_BITS_C\n   #define BN_MP_INIT_C\n   #define BN_MP_CLEAR_C\n   #define BN_MP_REDUCE_SETUP_C\n   #define BN_MP_REDUCE_C\n   #define BN_MP_REDUCE_2K_SETUP_L_C\n   #define BN_MP_REDUCE_2K_L_C\n   #define BN_MP_MOD_C\n   #define BN_MP_COPY_C\n   #define BN_MP_SQR_C\n   #define BN_MP_MUL_C\n   #define BN_MP_SET_C\n   #define BN_MP_EXCH_C\n#endif\n\n#if defined(BN_S_MP_MUL_DIGS_C)\n   #define BN_FAST_S_MP_MUL_DIGS_C\n   #define BN_MP_INIT_SIZE_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_S_MP_MUL_HIGH_DIGS_C)\n   #define BN_FAST_S_MP_MUL_HIGH_DIGS_C\n   #define BN_MP_INIT_SIZE_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_S_MP_SQR_C)\n   #define BN_MP_INIT_SIZE_C\n   #define BN_MP_CLAMP_C\n   #define BN_MP_EXCH_C\n   #define BN_MP_CLEAR_C\n#endif\n\n#if defined(BN_S_MP_SUB_C)\n   #define BN_MP_GROW_C\n   #define BN_MP_CLAMP_C\n#endif\n\n#if defined(BNCORE_C)\n#endif\n\n#ifdef LTM3\n#define LTM_LAST\n#endif\n#include \"mpi_superclass.h\"\n#include \"mpi_class.h\"\n#else\n#define LTM_LAST\n#endif\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/mpi_superclass.h",
    "content": "/* mpi_superclass.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n/* super class file for PK algos */\n\n/* default ... include all MPI */\n#define LTM_ALL\n\n/* RSA only (does not support DH/DSA/ECC) */\n/* #define SC_RSA_1 */\n\n/* For reference.... On an Athlon64 optimizing for speed...\n\n   LTM's mpi.o with all functions [striped] is 142KiB in size.\n\n*/\n\n/* Works for RSA only, mpi.o is 68KiB */\n#ifdef SC_RSA_1\n   #define BN_MP_SHRINK_C\n   #define BN_MP_LCM_C\n   #define BN_MP_PRIME_RANDOM_EX_C\n   #define BN_MP_INVMOD_C\n   #define BN_MP_GCD_C\n   #define BN_MP_MOD_C\n   #define BN_MP_MULMOD_C\n   #define BN_MP_ADDMOD_C\n   #define BN_MP_EXPTMOD_C\n   #define BN_MP_SET_INT_C\n   #define BN_MP_INIT_MULTI_C\n   #define BN_MP_CLEAR_MULTI_C\n   #define BN_MP_UNSIGNED_BIN_SIZE_C\n   #define BN_MP_TO_UNSIGNED_BIN_C\n   #define BN_MP_MOD_D_C\n   #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C\n   #define BN_REVERSE_C\n   #define BN_PRIME_TAB_C\n\n   /* other modifiers */\n   #define BN_MP_DIV_SMALL                    /* Slower division, not critical */\n\n   /* here we are on the last pass so we turn things off.  The functions classes are still there\n    * but we remove them specifically from the build.  This also invokes tweaks in functions\n    * like removing support for even moduli, etc...\n    */\n#ifdef LTM_LAST\n   #undef  BN_MP_TOOM_MUL_C\n   #undef  BN_MP_TOOM_SQR_C\n   #undef  BN_MP_KARATSUBA_MUL_C\n   #undef  BN_MP_KARATSUBA_SQR_C\n   #undef  BN_MP_REDUCE_C\n   #undef  BN_MP_REDUCE_SETUP_C\n   #undef  BN_MP_DR_IS_MODULUS_C\n   #undef  BN_MP_DR_SETUP_C\n   #undef  BN_MP_DR_REDUCE_C\n   #undef  BN_MP_REDUCE_IS_2K_C\n   #undef  BN_MP_REDUCE_2K_SETUP_C\n   #undef  BN_MP_REDUCE_2K_C\n   #undef  BN_S_MP_EXPTMOD_C\n   #undef  BN_MP_DIV_3_C\n   #undef  BN_S_MP_MUL_HIGH_DIGS_C\n   #undef  BN_FAST_S_MP_MUL_HIGH_DIGS_C\n   #undef  BN_FAST_MP_INVMOD_C\n\n   /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold\n    * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines]\n    * which means roughly speaking you can handle up to 2536-bit RSA keys with these defined without\n    * trouble.\n    */\n   #undef  BN_S_MP_MUL_DIGS_C\n   #undef  BN_S_MP_SQR_C\n   #undef  BN_MP_MONTGOMERY_REDUCE_C\n#endif\n\n#endif\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/pkcs11.h",
    "content": "/* pkcs11.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n#ifndef _PKCS11_H_\n#define _PKCS11_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifndef NULL_PTR\n#define NULL_PTR        0\n#endif\n#define CK_TRUE         1\n#define CK_FALSE        0\n\n\n#define CK_INVALID_HANDLE                     0UL\n\n#define CKN_SURRENDER                         0UL\n\n#define CKF_TOKEN_PRESENT                     0x00000001UL\n#define CKF_REMOVABLE_DEVICE                  0x00000002UL\n#define CKF_HW_SLOT                           0x00000004UL\n\n#define CKF_HW                                0x00000001UL\n#define CKF_ENCRYPT                           0x00000100UL\n#define CKF_DECRYPT                           0x00000200UL\n#define CKF_DIGEST                            0x00000400UL\n#define CKF_SIGN                              0x00000800UL\n#define CKF_SIGN_RECOVER                      0x00001000UL\n#define CKF_VERIFY                            0x00002000UL\n#define CKF_VERIFY_RECOVER                    0x00004000UL\n#define CKF_GENERATE                          0x00008000UL\n#define CKF_GENERATE_KEY_PAIR                 0x00010000UL\n#define CKF_WRAP                              0x00020000UL\n#define CKF_UNWRAP                            0x00040000UL\n#define CKF_DERIVE                            0x00080000UL\n#define CKF_EC_F_P                            0x00100000UL\n#define CKF_EC_F_2M                           0x00200000UL\n#define CKF_EC_ECPARAMETERS                   0x00400000UL\n#define CKF_EC_NAMEDCURVE                     0x00800000UL\n#define CKF_EC_UNCOMPRESS                     0x01000000UL\n#define CKF_EC_COMPRESS                       0x02000000UL\n\n#define CKF_LIBRARY_CANT_CREATE_OS_THREADS    0x00000001UL\n#define CKF_OS_LOCKING_OK                     0x00000002UL\n\n#define CKU_SO                                0UL\n#define CKU_USER                              1UL\n#define CKU_CONTEXT_SPECIFIC                  2UL\n\n#define CKF_RW_SESSION                        0x00000002UL\n#define CKF_SERIAL_SESSION                    0x00000004UL\n\n#define CKO_PUBLIC_KEY                        0x00000002UL\n#define CKO_PRIVATE_KEY                       0x00000003UL\n#define CKO_SECRET_KEY                        0x00000004UL\n\n#define CKK_RSA                               0x00000000UL\n#define CKK_DH                                0x00000002UL\n#define CKK_EC                                0x00000003UL\n#define CKK_GENERIC_SECRET                    0x00000010UL\n#define CKK_AES                               0x0000001FUL\n#define CKK_MD5_HMAC                          0x00000027UL\n#define CKK_SHA_1_HMAC                        0x00000028UL\n#define CKK_SHA256_HMAC                       0x0000002bUL\n#define CKK_SHA384_HMAC                       0x0000002cUL\n#define CKK_SHA512_HMAC                       0x0000002dUL\n#define CKK_SHA224_HMAC                       0x0000002eUL\n\n#define CKA_CLASS                             0x00000000UL\n#define CKA_TOKEN                             0x00000001UL\n#define CKA_PRIVATE                           0x00000002UL\n#define CKA_LABEL                             0x00000003UL\n#define CKA_VALUE                             0x00000011UL\n#define CKA_OBJECT_ID                         0x00000012UL\n#define CKA_OWNER                             0x00000084UL\n#define CKA_TRUSTED                           0x00000086UL\n#define CKA_KEY_TYPE                          0x00000100UL\n#define CKA_ID                                0x00000102UL\n#define CKA_SENSITIVE                         0x00000103UL\n#define CKA_ENCRYPT                           0x00000104UL\n#define CKA_DECRYPT                           0x00000105UL\n#define CKA_WRAP                              0x00000106UL\n#define CKA_UNWRAP                            0x00000107UL\n#define CKA_SIGN                              0x00000108UL\n#define CKA_SIGN_RECOVER                      0x00000109UL\n#define CKA_VERIFY                            0x0000010AUL\n#define CKA_VERIFY_RECOVER                    0x0000010BUL\n#define CKA_DERIVE                            0x0000010CUL\n#define CKA_MODULUS                           0x00000120UL\n#define CKA_MODULUS_BITS                      0x00000121UL\n#define CKA_PUBLIC_EXPONENT                   0x00000122UL\n#define CKA_PRIVATE_EXPONENT                  0x00000123UL\n#define CKA_PRIME_1                           0x00000124UL\n#define CKA_PRIME_2                           0x00000125UL\n#define CKA_EXPONENT_1                        0x00000126UL\n#define CKA_EXPONENT_2                        0x00000127UL\n#define CKA_COEFFICIENT                       0x00000128UL\n#define CKA_PUBLIC_KEY_INFO                   0x00000129UL\n#define CKA_PRIME                             0x00000130UL\n#define CKA_BASE                              0x00000132UL\n#define CKA_PRIME_BITS                        0x00000133UL\n#define CKA_VALUE_BITS                        0x00000160UL\n#define CKA_VALUE_LEN                         0x00000161UL\n#define CKA_EXTRACTABLE                       0x00000162UL\n#define CKA_LOCAL                             0x00000163UL\n#define CKA_NEVER_EXTRACTABLE                 0x00000164UL\n#define CKA_ALWAYS_SENSITIVE                  0x00000165UL\n#define CKA_KEY_GEN_MECHANISM                 0x00000166UL\n#define CKA_MODIFIABLE                        0x00000170UL\n#define CKA_COPYABLE                          0x00000171UL\n#define CKA_DESTROYABLE                       0x00000172UL\n#define CKA_EC_PARAMS                         0x00000180UL\n#define CKA_EC_POINT                          0x00000181UL\n#define CKA_ALWAYS_AUTHENTICATE               0x00000202UL\n#define CKA_HW_FEATURE_TYPE                   0x00000300UL\n#define CKA_RESET_ON_INIT                     0x00000301UL\n#define CKA_HAS_RESET                         0x00000302UL\n\n#define CKM_RSA_PKCS_KEY_PAIR_GEN             0x00000000UL\n#define CKM_RSA_X_509                         0x00000003UL\n#define CKM_DH_PKCS_KEY_PAIR_GEN              0x00000020UL\n#define CKM_DH_PKCS_DERIVE                    0x00000021UL\n#define CKM_MD5_HMAC                          0x00000211UL\n#define CKM_SHA_1_HMAC                        0x00000221UL\n#define CKM_SHA256_HMAC                       0x00000251UL\n#define CKM_SHA224_HMAC                       0x00000256UL\n#define CKM_SHA384_HMAC                       0x00000261UL\n#define CKM_SHA512_HMAC                       0x00000271UL\n#define CKM_GENERIC_SECRET_KEY_GEN            0x00000350UL\n#define CKM_EC_KEY_PAIR_GEN                   0x00001040UL\n#define CKM_ECDSA                             0x00001041UL\n#define CKM_ECDH1_DERIVE                      0x00001050UL\n#define CKM_ECDH1_COFACTOR_DERIVE             0x00001051UL\n#define CKM_AES_KEY_GEN                       0x00001080UL\n#define CKM_AES_CBC                           0x00001082UL\n#define CKM_AES_GCM                           0x00001087UL\n\n#define CKR_OK                                0x00000000UL\n#define CKR_MECHANISM_INVALID                 0x00000070UL\n#define CKR_SIGNATURE_INVALID                 0x000000C0UL\n\n#define CKD_NULL                              0x00000001UL\n\n\ntypedef unsigned char     CK_BYTE;\ntypedef CK_BYTE           CK_CHAR;\ntypedef CK_BYTE           CK_UTF8CHAR;\ntypedef CK_BYTE           CK_BBOOL;\ntypedef unsigned long int CK_ULONG;\ntypedef long int          CK_LONG;\ntypedef CK_ULONG          CK_FLAGS;\ntypedef CK_BYTE*          CK_BYTE_PTR;\ntypedef CK_CHAR*          CK_CHAR_PTR;\ntypedef CK_UTF8CHAR*      CK_UTF8CHAR_PTR;\ntypedef CK_ULONG*         CK_ULONG_PTR;\ntypedef void*             CK_VOID_PTR;\ntypedef CK_VOID_PTR*      CK_VOID_PTR_PTR;\n\n\ntypedef CK_ULONG          CK_RV;\n\n\ntypedef struct CK_VERSION {\n    CK_BYTE major;\n    CK_BYTE minor;\n} CK_VERSION;\ntypedef CK_VERSION* CK_VERSION_PTR;\n\n\n/* Info Types */\ntypedef struct CK_INFO {\n    CK_VERSION  cryptokiVersion;\n    CK_UTF8CHAR manufacturerID[32];\n    CK_FLAGS    flags;\n    CK_UTF8CHAR libraryDescription[32];\n    CK_VERSION  libraryVersion;\n} CK_INFO;\ntypedef CK_INFO* CK_INFO_PTR;\n\n\n/* Slot Types */\ntypedef CK_ULONG    CK_SLOT_ID;\ntypedef CK_SLOT_ID* CK_SLOT_ID_PTR;\n\ntypedef struct CK_SLOT_INFO {\n    CK_UTF8CHAR   slotDescription[64];\n    CK_UTF8CHAR   manufacturerID[32];\n    CK_FLAGS      flags;\n\n    CK_VERSION    hardwareVersion;\n    CK_VERSION    firmwareVersion;\n} CK_SLOT_INFO;\ntypedef CK_SLOT_INFO* CK_SLOT_INFO_PTR;\n\n\n/* Token Types */\ntypedef struct CK_TOKEN_INFO {\n    CK_UTF8CHAR   label[32];\n    CK_UTF8CHAR   manufacturerID[32];\n    CK_UTF8CHAR   model[16];\n    CK_CHAR       serialNumber[16];\n    CK_FLAGS      flags;\n    CK_ULONG      ulMaxSessionCount;\n    CK_ULONG      ulSessionCount;\n    CK_ULONG      ulMaxRwSessionCount;\n    CK_ULONG      ulRwSessionCount;\n    CK_ULONG      ulMaxPinLen;\n    CK_ULONG      ulMinPinLen;\n    CK_ULONG      ulTotalPublicMemory;\n    CK_ULONG      ulFreePublicMemory;\n    CK_ULONG      ulTotalPrivateMemory;\n    CK_ULONG      ulFreePrivateMemory;\n    CK_VERSION    hardwareVersion;\n    CK_VERSION    firmwareVersion;\n    CK_CHAR       utcTime[16];\n} CK_TOKEN_INFO;\ntypedef CK_TOKEN_INFO* CK_TOKEN_INFO_PTR;\n\n\n/* Session Types */\ntypedef CK_ULONG           CK_SESSION_HANDLE;\ntypedef CK_SESSION_HANDLE* CK_SESSION_HANDLE_PTR;\n\ntypedef CK_ULONG          CK_USER_TYPE;\n\ntypedef CK_ULONG          CK_STATE;\n\ntypedef struct CK_SESSION_INFO {\n    CK_SLOT_ID    slotID;\n    CK_STATE      state;\n    CK_FLAGS      flags;\n    CK_ULONG      ulDeviceError;\n} CK_SESSION_INFO;\ntypedef CK_SESSION_INFO* CK_SESSION_INFO_PTR;\n\n\n/* Object Types */\ntypedef CK_ULONG          CK_OBJECT_HANDLE;\ntypedef CK_OBJECT_HANDLE* CK_OBJECT_HANDLE_PTR;\n\ntypedef CK_ULONG         CK_OBJECT_CLASS;\ntypedef CK_OBJECT_CLASS* CK_OBJECT_CLASS_PTR;\n\ntypedef CK_ULONG          CK_KEY_TYPE;\n\ntypedef CK_ULONG          CK_ATTRIBUTE_TYPE;\n\ntypedef struct CK_ATTRIBUTE {\n    CK_ATTRIBUTE_TYPE type;\n    CK_VOID_PTR       pValue;\n    CK_ULONG          ulValueLen;\n} CK_ATTRIBUTE;\ntypedef CK_ATTRIBUTE* CK_ATTRIBUTE_PTR;\n\n\n/* Mechanism Types */\ntypedef CK_ULONG           CK_MECHANISM_TYPE;\ntypedef CK_MECHANISM_TYPE* CK_MECHANISM_TYPE_PTR;\n\ntypedef struct CK_MECHANISM {\n    CK_MECHANISM_TYPE mechanism;\n    CK_VOID_PTR       pParameter;\n    CK_ULONG          ulParameterLen;\n} CK_MECHANISM;\ntypedef CK_MECHANISM* CK_MECHANISM_PTR;\n\ntypedef struct CK_MECHANISM_INFO {\n    CK_ULONG ulMinKeySize;\n    CK_ULONG ulMaxKeySize;\n    CK_FLAGS flags;\n} CK_MECHANISM_INFO;\ntypedef CK_MECHANISM_INFO * CK_MECHANISM_INFO_PTR;\n\n\ntypedef CK_ULONG CK_NOTIFICATION;\n\ntypedef CK_RV (*CK_NOTIFY)(CK_SESSION_HANDLE hSession, CK_NOTIFICATION event,\n                           CK_VOID_PTR pApplication);\n\n\n/* Threading types. */\ntypedef CK_RV (*CK_CREATEMUTEX)(CK_VOID_PTR_PTR ppMutex);\ntypedef CK_RV (*CK_DESTROYMUTEX)(CK_VOID_PTR pMutex);\ntypedef CK_RV (*CK_LOCKMUTEX)(CK_VOID_PTR pMutex);\ntypedef CK_RV (*CK_UNLOCKMUTEX)(CK_VOID_PTR pMutex);\n\ntypedef struct CK_C_INITIALIZE_ARGS {\n    CK_CREATEMUTEX CreateMutex;\n    CK_DESTROYMUTEX DestroyMutex;\n    CK_LOCKMUTEX LockMutex;\n    CK_UNLOCKMUTEX UnlockMutex;\n    CK_FLAGS flags;\n    CK_VOID_PTR pReserved;\n} CK_C_INITIALIZE_ARGS;\ntypedef CK_C_INITIALIZE_ARGS* CK_C_INITIALIZE_ARGS_PTR;\n\n\n/* Cryptographic algorithm types. */\ntypedef CK_ULONG CK_EC_KDF_TYPE;\n\ntypedef struct CK_ECDH1_DERIVE_PARAMS {\n    CK_EC_KDF_TYPE kdf;\n    CK_ULONG ulSharedDataLen;\n    CK_BYTE_PTR pSharedData;\n    CK_ULONG ulPublicDataLen;\n    CK_BYTE_PTR pPublicData;\n} CK_ECDH1_DERIVE_PARAMS;\ntypedef CK_ECDH1_DERIVE_PARAMS* CK_ECDH1_DERIVE_PARAMS_PTR;\n\n\ntypedef struct CK_GCM_PARAMS {\n    CK_BYTE_PTR       pIv;\n    CK_ULONG          ulIvLen;\n    CK_ULONG          ulIvBits;\n    CK_BYTE_PTR       pAAD;\n    CK_ULONG          ulAADLen;\n    CK_ULONG          ulTagBits;\n} CK_GCM_PARAMS;\ntypedef CK_GCM_PARAMS* CK_GCM_PARAMS_PTR;\n\n/* Function list types. */\ntypedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;\ntypedef CK_FUNCTION_LIST* CK_FUNCTION_LIST_PTR;\ntypedef CK_FUNCTION_LIST_PTR* CK_FUNCTION_LIST_PTR_PTR;\n\ntypedef CK_RV (*CK_C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR ppFunctionList);\n\nstruct CK_FUNCTION_LIST {\n    CK_VERSION version;\n\n    CK_RV (*C_Initialize)(CK_VOID_PTR pInitArgs);\n    CK_RV (*C_Finalize)(CK_VOID_PTR pReserved);\n    CK_RV (*C_GetInfo)(CK_INFO_PTR pInfo);\n    CK_RV (*C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR ppFunctionList);\n    CK_RV (*C_GetSlotList)(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList,\n                           CK_ULONG_PTR pulCount);\n    CK_RV (*C_GetSlotInfo)(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo);\n    CK_RV (*C_GetTokenInfo)(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo);\n    CK_RV (*C_GetMechanismList)(CK_SLOT_ID slotID,\n                                CK_MECHANISM_TYPE_PTR pMechanismList,\n                                CK_ULONG_PTR pulCount);\n    CK_RV (*C_GetMechanismInfo)(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,\n                                CK_MECHANISM_INFO_PTR pInfo);\n    CK_RV (*C_InitToken)(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin,\n                         CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pLabel);\n    CK_RV (*C_InitPIN)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, \n                       CK_ULONG ulPinLen);\n    CK_RV (*C_SetPIN)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,\n                      CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin,\n                      CK_ULONG ulNewLen);\n    CK_RV (*C_OpenSession)(CK_SLOT_ID slotID, CK_FLAGS flags,\n                           CK_VOID_PTR pApplication, CK_NOTIFY Notify,\n                           CK_SESSION_HANDLE_PTR phSession);\n    CK_RV (*C_CloseSession)(CK_SESSION_HANDLE hSession);\n    CK_RV (*C_CloseAllSessions)(CK_SLOT_ID slotID);\n    CK_RV (*C_GetSessionInfo)(CK_SESSION_HANDLE hSession,\n                              CK_SESSION_INFO_PTR pInfo);\n    CK_RV (*C_GetOperationState)(CK_SESSION_HANDLE hSession,\n                                 CK_BYTE_PTR pOperationState,\n                                 CK_ULONG_PTR pulOperationStateLen);\n    CK_RV (*C_SetOperationState)(CK_SESSION_HANDLE hSession,\n                                 CK_BYTE_PTR pOperationState,\n                                 CK_ULONG ulOperationStateLen,\n                                 CK_OBJECT_HANDLE hEncryptionKey,\n                                 CK_OBJECT_HANDLE hAuthenticationKey);\n    CK_RV (*C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,\n                     CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen);\n    CK_RV (*C_Logout)(CK_SESSION_HANDLE hSession);\n    CK_RV (*C_CreateObject)(CK_SESSION_HANDLE hSession,\n                            CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,\n                            CK_OBJECT_HANDLE_PTR phObject);\n    CK_RV (*C_CopyObject)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,\n                          CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,\n                          CK_OBJECT_HANDLE_PTR phNewObject);\n    CK_RV (*C_DestroyObject)(CK_SESSION_HANDLE hSession,\n                             CK_OBJECT_HANDLE hObject);\n    CK_RV (*C_GetObjectSize)(CK_SESSION_HANDLE hSession,\n                             CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize);\n    CK_RV (*C_GetAttributeValue)(CK_SESSION_HANDLE hSession,\n                                 CK_OBJECT_HANDLE hObject,\n                                 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount);\n    CK_RV (*C_SetAttributeValue)(CK_SESSION_HANDLE hSession,\n                                 CK_OBJECT_HANDLE hObject,\n                                 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount);\n    CK_RV (*C_FindObjectsInit)(CK_SESSION_HANDLE hSession,\n                               CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount);\n    CK_RV (*C_FindObjects)(CK_SESSION_HANDLE hSession,\n                           CK_OBJECT_HANDLE_PTR phObject,\n                           CK_ULONG ulMaxObjectCount,\n                           CK_ULONG_PTR pulObjectCount);\n    CK_RV (*C_FindObjectsFinal)(CK_SESSION_HANDLE hSession);\n    CK_RV (*C_EncryptInit)(CK_SESSION_HANDLE hSession,\n                           CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey);\n    CK_RV (*C_Encrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,\n                       CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData,\n                       CK_ULONG_PTR pulEncryptedDataLen);\n    CK_RV (*C_EncryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,\n                             CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,\n                             CK_ULONG_PTR pulEncryptedPartLen);\n    CK_RV (*C_EncryptFinal)(CK_SESSION_HANDLE hSession,\n                            CK_BYTE_PTR pLastEncryptedPart,\n                            CK_ULONG_PTR pulLastEncryptedPartLen);\n    CK_RV (*C_DecryptInit)(CK_SESSION_HANDLE hSession,\n                           CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey);\n    CK_RV (*C_Decrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData,\n                       CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData,\n                       CK_ULONG_PTR pulDataLen);\n    CK_RV (*C_DecryptUpdate)(CK_SESSION_HANDLE hSession,\n                             CK_BYTE_PTR pEncryptedPart,\n                             CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,\n                             CK_ULONG_PTR pulPartLen);\n    CK_RV (*C_DecryptFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart,\n                            CK_ULONG_PTR pulLastPartLen);\n    CK_RV (*C_DigestInit)(CK_SESSION_HANDLE hSession,\n                          CK_MECHANISM_PTR pMechanism);\n    CK_RV (*C_Digest)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,\n                      CK_ULONG ulDataLen, CK_BYTE_PTR pDigest,\n                      CK_ULONG_PTR pulDigestLen);\n    CK_RV (*C_DigestUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,\n                            CK_ULONG ulPartLen);\n    CK_RV (*C_DigestKey)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey);\n    CK_RV (*C_DigestFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest,\n                           CK_ULONG_PTR pulDigestLen);\n    CK_RV (*C_SignInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,\n                        CK_OBJECT_HANDLE hKey);\n    CK_RV (*C_Sign)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,\n                    CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,\n                    CK_ULONG_PTR pulSignatureLen);\n    CK_RV (*C_SignUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,\n                          CK_ULONG ulPartLen);\n    CK_RV (*C_SignFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,\n                         CK_ULONG_PTR pulSignatureLen);\n    CK_RV (*C_SignRecoverInit)(CK_SESSION_HANDLE hSession,\n                               CK_MECHANISM_PTR pMechanism,\n                               CK_OBJECT_HANDLE hKey);\n    CK_RV (*C_SignRecover)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,\n                           CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,\n                           CK_ULONG_PTR pulSignatureLen);\n    CK_RV (*C_VerifyInit)(CK_SESSION_HANDLE hSession,\n                          CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey);\n    CK_RV (*C_Verify)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,\n                      CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,\n                      CK_ULONG ulSignatureLen);\n    CK_RV (*C_VerifyUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,\n                            CK_ULONG ulPartLen);\n    CK_RV (*C_VerifyFinal)(CK_SESSION_HANDLE hSession,\n                           CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen);\n    CK_RV (*C_VerifyRecoverInit)(CK_SESSION_HANDLE hSession,\n                                 CK_MECHANISM_PTR pMechanism,\n                                 CK_OBJECT_HANDLE hKey);\n    CK_RV (*C_VerifyRecover)(CK_SESSION_HANDLE hSession,\n                             CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen,\n                             CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen);\n    CK_RV (*C_DigestEncryptUpdate)(CK_SESSION_HANDLE hSession,\n                                   CK_BYTE_PTR pPart, CK_ULONG ulPartLen,\n                                   CK_BYTE_PTR pEncryptedPart,\n                                   CK_ULONG_PTR pulEncryptedPartLen);\n    CK_RV (*C_DecryptDigestUpdate)(CK_SESSION_HANDLE hSession,\n                                   CK_BYTE_PTR pEncryptedPart,\n                                   CK_ULONG ulEncryptedPartLen,\n                                   CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen);\n    CK_RV (*C_SignEncryptUpdate)(CK_SESSION_HANDLE hSession,\n                                 CK_BYTE_PTR pPart, CK_ULONG ulPartLen,\n                                 CK_BYTE_PTR pEncryptedPart,\n                                 CK_ULONG_PTR pulEncryptedPartLen);\n    CK_RV (*C_DecryptVerifyUpdate)(CK_SESSION_HANDLE hSession,\n                                   CK_BYTE_PTR pEncryptedPart,\n                                   CK_ULONG ulEncryptedPartLen,\n                                   CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen);\n    CK_RV (*C_GenerateKey)(CK_SESSION_HANDLE hSession,\n                           CK_MECHANISM_PTR pMechanism,\n                           CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,\n                           CK_OBJECT_HANDLE_PTR phKey);\n    CK_RV (*C_GenerateKeyPair)(CK_SESSION_HANDLE hSession,\n                               CK_MECHANISM_PTR pMechanism,\n                               CK_ATTRIBUTE_PTR pPublicKeyTemplate,\n                               CK_ULONG ulPublicKeyAttributeCount,\n                               CK_ATTRIBUTE_PTR pPrivateKeyTemplate,\n                               CK_ULONG ulPrivateKeyAttributeCount,\n                               CK_OBJECT_HANDLE_PTR phPublicKey,\n                               CK_OBJECT_HANDLE_PTR phPrivateKey);\n    CK_RV (*C_WrapKey)(CK_SESSION_HANDLE hSession,\n                       CK_MECHANISM_PTR pMechanism,\n                       CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey,\n                       CK_BYTE_PTR pWrappedKey,\n                       CK_ULONG_PTR pulWrappedKeyLen);\n    CK_RV (*C_UnwrapKey)(CK_SESSION_HANDLE hSession,\n                         CK_MECHANISM_PTR pMechanism,\n                         CK_OBJECT_HANDLE hUnwrappingKey,\n                         CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,\n                         CK_ATTRIBUTE_PTR pTemplate,\n                         CK_ULONG ulAttributeCount,\n                         CK_OBJECT_HANDLE_PTR phKey);\n    CK_RV (*C_DeriveKey)(CK_SESSION_HANDLE hSession,\n                         CK_MECHANISM_PTR pMechanism,\n                         CK_OBJECT_HANDLE hBaseKey,\n                         CK_ATTRIBUTE_PTR pTemplate,\n                         CK_ULONG ulAttributeCount,\n                         CK_OBJECT_HANDLE_PTR phKey);\n    CK_RV (*C_SeedRandom)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,\n                          CK_ULONG ulSeedLen);\n    CK_RV (*C_GenerateRandom)(CK_SESSION_HANDLE hSession,\n                              CK_BYTE_PTR RandomData, CK_ULONG ulRandomLen);\n    CK_RV (*C_GetFunctionStatus)(CK_SESSION_HANDLE hSession);\n    CK_RV (*C_CancelFunction)(CK_SESSION_HANDLE hSession);\n    CK_RV (*C_WaitForSlotEvent)(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,\n                                CK_VOID_PTR pRserved);\n\n};\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _PKCS11_H_ */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/pkcs12.h",
    "content": "/* pkcs12.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifndef WOLF_CRYPT_PKCS12_H\n#define WOLF_CRYPT_PKCS12_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifndef WOLFSSL_TYPES_DEFINED /* do not redeclare from ssl.h */\n    typedef struct WC_PKCS12 WC_PKCS12;\n#endif\n\ntypedef struct WC_DerCertList { /* dereferenced in ssl.c */\n    byte* buffer;\n    word32 bufferSz;\n    struct WC_DerCertList* next;\n} WC_DerCertList;\n\n/* default values for creating PKCS12 */\nenum {\n    WC_PKCS12_ITT_DEFAULT = 2048,\n    WC_PKCS12_VERSION_DEFAULT = 3,\n    WC_PKCS12_MAC_DEFAULT = 1,\n};\n\nWOLFSSL_API WC_PKCS12* wc_PKCS12_new(void);\nWOLFSSL_API void wc_PKCS12_free(WC_PKCS12* pkcs12);\nWOLFSSL_API int wc_d2i_PKCS12(const byte* der, word32 derSz, WC_PKCS12* pkcs12);\nWOLFSSL_API int wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der, int* derSz);\nWOLFSSL_API int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,\n        byte** pkey, word32* pkeySz, byte** cert, word32* certSz,\n        WC_DerCertList** ca);\nWOLFSSL_API WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz,\n        char* name, byte* key, word32 keySz, byte* cert, word32 certSz,\n        WC_DerCertList* ca, int nidKey, int nidCert, int iter, int macIter,\n        int keyType, void* heap);\n\n\nWOLFSSL_LOCAL int wc_PKCS12_SetHeap(WC_PKCS12* pkcs12, void* heap);\nWOLFSSL_LOCAL void* wc_PKCS12_GetHeap(WC_PKCS12* pkcs12);\n\nWOLFSSL_LOCAL void wc_FreeCertList(WC_DerCertList* list, void* heap);\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLF_CRYPT_PKCS12_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/pkcs7.h",
    "content": "/* pkcs7.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/pkcs7.h\n*/\n\n#ifndef WOLF_CRYPT_PKCS7_H\n#define WOLF_CRYPT_PKCS7_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef HAVE_PKCS7\n\n#ifndef NO_ASN\n    #include <wolfssl/wolfcrypt/asn.h>\n#endif\n#include <wolfssl/wolfcrypt/asn_public.h>\n#include <wolfssl/wolfcrypt/random.h>\n#ifndef NO_AES\n    #include <wolfssl/wolfcrypt/aes.h>\n#endif\n#ifndef NO_DES3\n    #include <wolfssl/wolfcrypt/des3.h>\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* Max number of certificates that PKCS7 structure can parse */\n#ifndef MAX_PKCS7_CERTS\n    #define MAX_PKCS7_CERTS 4\n#endif\n\n#ifndef MAX_ORI_TYPE_SZ\n    #define MAX_ORI_TYPE_SZ  MAX_OID_SZ\n#endif\n#ifndef MAX_ORI_VALUE_SZ\n    #define MAX_ORI_VALUE_SZ 512\n#endif\n\n#ifndef MAX_SIGNED_ATTRIBS_SZ\n    #define MAX_SIGNED_ATTRIBS_SZ 7\n#endif\n\n#ifndef MAX_AUTH_ATTRIBS_SZ\n    #define MAX_AUTH_ATTRIBS_SZ 7\n#endif\n\n#ifndef MAX_UNAUTH_ATTRIBS_SZ\n    #define MAX_UNAUTH_ATTRIBS_SZ 7\n#endif\n\n/* PKCS#7 content types, ref RFC 2315 (Section 14) */\nenum PKCS7_TYPES {\n    PKCS7_MSG                 = 650,  /* 1.2.840.113549.1.7   */\n    DATA                      = 651,  /* 1.2.840.113549.1.7.1 */\n    SIGNED_DATA               = 652,  /* 1.2.840.113549.1.7.2 */\n    ENVELOPED_DATA            = 653,  /* 1.2.840.113549.1.7.3 */\n    SIGNED_AND_ENVELOPED_DATA = 654,  /* 1.2.840.113549.1.7.4 */\n    DIGESTED_DATA             = 655,  /* 1.2.840.113549.1.7.5 */\n    ENCRYPTED_DATA            = 656,  /* 1.2.840.113549.1.7.6 */\n#if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)\n    COMPRESSED_DATA           = 678,  /* 1.2.840.113549.1.9.16.1.9,  RFC 3274 */\n#endif\n    FIRMWARE_PKG_DATA         = 685,  /* 1.2.840.113549.1.9.16.1.16, RFC 4108 */\n    AUTH_ENVELOPED_DATA       = 692   /* 1.2.840.113549.1.9.16.1.23, RFC 5083 */\n};\n\nenum PKCS7_STATE {\n    WC_PKCS7_START = 0,\n\n    /* decode encrypted */\n    WC_PKCS7_STAGE2,\n    WC_PKCS7_STAGE3,\n    WC_PKCS7_STAGE4,\n    WC_PKCS7_STAGE5,\n    WC_PKCS7_STAGE6,\n\n    WC_PKCS7_VERIFY_STAGE2,\n    WC_PKCS7_VERIFY_STAGE3,\n    WC_PKCS7_VERIFY_STAGE4,\n    WC_PKCS7_VERIFY_STAGE5,\n    WC_PKCS7_VERIFY_STAGE6,\n\n    /* parse info set */\n    WC_PKCS7_INFOSET_START,\n    WC_PKCS7_INFOSET_BER,\n    WC_PKCS7_INFOSET_STAGE1,\n    WC_PKCS7_INFOSET_STAGE2,\n    WC_PKCS7_INFOSET_END,\n\n    /* decode enveloped data */\n    WC_PKCS7_ENV_2,\n    WC_PKCS7_ENV_3,\n    WC_PKCS7_ENV_4,\n    WC_PKCS7_ENV_5,\n\n    /* decode auth enveloped */\n    WC_PKCS7_AUTHENV_2,\n    WC_PKCS7_AUTHENV_3,\n    WC_PKCS7_AUTHENV_4,\n    WC_PKCS7_AUTHENV_5,\n    WC_PKCS7_AUTHENV_6,\n    WC_PKCS7_AUTHENV_ATRB,\n    WC_PKCS7_AUTHENV_ATRBEND,\n    WC_PKCS7_AUTHENV_7,\n\n    /* decryption state types */\n    WC_PKCS7_DECRYPT_KTRI,\n    WC_PKCS7_DECRYPT_KTRI_2,\n    WC_PKCS7_DECRYPT_KTRI_3,\n\n\n    WC_PKCS7_DECRYPT_KARI,\n    WC_PKCS7_DECRYPT_KEKRI,\n    WC_PKCS7_DECRYPT_PWRI,\n    WC_PKCS7_DECRYPT_ORI,\n\n    WC_PKCS7_DECRYPT_DONE,\n\n};\n\nenum Pkcs7_Misc {\n    PKCS7_NONCE_SZ        = 16,\n    MAX_ENCRYPTED_KEY_SZ  = 512,    /* max enc. key size, RSA <= 4096 */\n    MAX_CONTENT_KEY_LEN   = 32,     /* highest current cipher is AES-256-CBC */\n    MAX_CONTENT_IV_SIZE   = 16,     /* highest current is AES128 */\n#ifndef NO_AES\n    MAX_CONTENT_BLOCK_LEN = AES_BLOCK_SIZE,\n#else\n    MAX_CONTENT_BLOCK_LEN = DES_BLOCK_SIZE,\n#endif\n    MAX_RECIP_SZ          = MAX_VERSION_SZ +\n                            MAX_SEQ_SZ + ASN_NAME_MAX + MAX_SN_SZ +\n                            MAX_SEQ_SZ + MAX_ALGO_SZ + 1 + MAX_ENCRYPTED_KEY_SZ,\n#if (defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \\\n     (HAVE_FIPS_VERSION >= 2)) || defined(HAVE_SELFTEST)\n    /* In the event of fips cert 3389 or CAVP selftest build, these enums are\n     * not in aes.h for use with pkcs7 so enumerate it here outside the fips\n     * boundary */\n    GCM_NONCE_MID_SZ = 12, /* The usual default nonce size for AES-GCM. */\n    CCM_NONCE_MIN_SZ = 7,\n#endif\n};\n\nenum Cms_Options {\n    CMS_SKID = 1,\n    CMS_ISSUER_AND_SERIAL_NUMBER = 2,\n};\n#define DEGENERATE_SID 3\n\n/* CMS/PKCS#7 RecipientInfo types, RFC 5652, Section 6.2 */\nenum Pkcs7_RecipientInfo_Types {\n    PKCS7_KTRI  = 0,\n    PKCS7_KARI  = 1,\n    PKCS7_KEKRI = 2,\n    PKCS7_PWRI  = 3,\n    PKCS7_ORI   = 4\n};\n\ntypedef struct PKCS7Attrib {\n    const byte* oid;\n    word32 oidSz;\n    const byte* value;\n    word32 valueSz;\n} PKCS7Attrib;\n\n\ntypedef struct PKCS7DecodedAttrib {\n    struct PKCS7DecodedAttrib* next;\n    byte* oid;\n    word32 oidSz;\n    byte* value;\n    word32 valueSz;\n} PKCS7DecodedAttrib;\n\ntypedef struct PKCS7State PKCS7State;\ntypedef struct Pkcs7Cert Pkcs7Cert;\ntypedef struct Pkcs7EncodedRecip Pkcs7EncodedRecip;\ntypedef struct PKCS7 PKCS7;\ntypedef struct PKCS7 PKCS7_SIGNED;\ntypedef struct PKCS7SignerInfo PKCS7SignerInfo;\n\n/* OtherRecipientInfo decrypt callback prototype */\ntypedef int (*CallbackOriDecrypt)(PKCS7* pkcs7, byte* oriType, word32 oriTypeSz,\n                                  byte* oriValue, word32 oriValueSz,\n                                  byte* decryptedKey, word32* decryptedKeySz,\n                                  void* ctx);\ntypedef int (*CallbackOriEncrypt)(PKCS7* pkcs7, byte* cek, word32 cekSz,\n                                  byte* oriType, word32* oriTypeSz,\n                                  byte* oriValue, word32* oriValueSz,\n                                  void* ctx);\ntypedef int (*CallbackDecryptContent)(PKCS7* pkcs7, int encryptOID,\n                                   byte* iv, int ivSz, byte* aad, word32 aadSz,\n                                   byte* authTag, word32 authTagSz, byte* in,\n                                   int inSz, byte* out, void* ctx);\ntypedef int (*CallbackWrapCEK)(PKCS7* pkcs7, byte* cek, word32 cekSz,\n                                  byte* keyId, word32 keyIdSz,\n                                  byte* originKey, word32 originKeySz,\n                                  byte* out, word32 outSz,\n                                  int keyWrapAlgo, int type, int dir);\n\n#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)\n/* RSA sign raw digest callback, user builds DigestInfo */\ntypedef int (*CallbackRsaSignRawDigest)(PKCS7* pkcs7, byte* digest,\n                                   word32 digestSz, byte* out, word32 outSz,\n                                   byte* privateKey, word32 privateKeySz,\n                                   int devId, int hashOID);\n#endif\n\n/* Public Structure Warning:\n * Existing members must not be changed to maintain backwards compatibility!\n */\nstruct PKCS7 {\n    WC_RNG* rng;\n    PKCS7Attrib* signedAttribs;\n    byte*  content;               /* inner content, not owner             */\n    byte*  contentDynamic;        /* content if constructed OCTET_STRING  */\n    byte*  singleCert;            /* recipient cert, DER, not owner       */\n    const byte* issuer;           /* issuer name of singleCert            */\n    byte*  privateKey;            /* private key, DER, not owner          */\n    void*  heap;                  /* heap hint for dynamic memory         */\n#ifdef ASN_BER_TO_DER\n    byte*  der;                   /* DER encoded version of message       */\n    word32 derSz;\n#endif\n    byte*  cert[MAX_PKCS7_CERTS];\n\n    /* Encrypted-data Content Type */\n    byte*        encryptionKey;         /* block cipher encryption key */\n    PKCS7Attrib* unprotectedAttribs;    /* optional */\n    PKCS7DecodedAttrib* decodedAttrib;  /* linked list of decoded attribs */\n\n    /* Enveloped-data optional ukm, not owner */\n    byte*  ukm;\n    word32 ukmSz;\n\n    word32 encryptionKeySz;       /* size of key buffer, bytes */\n    word32 unprotectedAttribsSz;\n    word32 contentSz;             /* content size                         */\n    word32 singleCertSz;          /* size of recipient cert buffer, bytes */\n    word32 issuerSz;              /* length of issuer name                */\n    word32 issuerSnSz;            /* length of serial number              */\n\n    word32 publicKeySz;\n    word32 publicKeyOID;          /* key OID (RSAk, ECDSAk, etc) */\n    word32 privateKeySz;          /* size of private key buffer, bytes    */\n    word32 signedAttribsSz;\n    int contentOID;               /* PKCS#7 content type OID sum          */\n    int hashOID;\n    int encryptOID;               /* key encryption algorithm OID         */\n    int keyWrapOID;               /* key wrap algorithm OID               */\n    int keyAgreeOID;              /* key agreement algorithm OID          */\n    int devId;                    /* device ID for HW based private key   */\n    byte issuerHash[KEYID_SIZE];  /* hash of all alt Names                */\n    byte issuerSn[MAX_SN_SZ];     /* singleCert's serial number           */\n    byte publicKey[MAX_RSA_INT_SZ + MAX_RSA_E_SZ]; /* MAX RSA key size (m + e)*/\n    word32 certSz[MAX_PKCS7_CERTS];\n\n     /* flags - up to 16-bits */\n    word16 isDynamic:1;\n    word16 noDegenerate:1; /* allow degenerate case in verify function */\n    word16 detached:1;     /* generate detached SignedData signature bundles */\n\n    byte contentType[MAX_OID_SZ]; /* custom contentType byte array */\n    word32 contentTypeSz;         /* size of contentType, bytes */\n\n    int sidType;                  /* SignerIdentifier type to use, of type\n                                     Pkcs7_SignerIdentifier_Types, default to\n                                     SID_ISSUER_AND_SERIAL_NUMBER */\n    byte issuerSubjKeyId[KEYID_SIZE];  /* SubjectKeyIdentifier of singleCert  */\n    Pkcs7Cert* certList;          /* certificates list for SignedData set */\n    Pkcs7EncodedRecip* recipList; /* recipients list */\n    byte* cek;                    /* content encryption key, random, dynamic */\n    word32 cekSz;                 /* size of cek, bytes */\n    byte* pass;                   /* password, for PWRI decryption */\n    word32 passSz;                /* size of pass, bytes */\n    int kekEncryptOID;            /* KEK encryption algorithm OID */\n\n    CallbackOriEncrypt oriEncryptCb;  /* ORI encrypt callback */\n    CallbackOriDecrypt oriDecryptCb;  /* ORI decrypt callback */\n    void* oriEncryptCtx;              /* ORI encrypt user context ptr */\n    void* oriDecryptCtx;              /* ORI decrypt user context ptr */\n\n    PKCS7Attrib* authAttribs;     /* authenticated attribs */\n    word32 authAttribsSz;\n    PKCS7Attrib* unauthAttribs;   /* unauthenticated attribs */\n    word32 unauthAttribsSz;\n\n#ifndef NO_PKCS7_STREAM\n    PKCS7State* stream;\n#endif\n    word32 state;\n\n    word16 skipDefaultSignedAttribs:1; /* skip adding default signed attribs */\n\n    byte version; /* 1 for RFC 2315 and 3 for RFC 4108 */\n    PKCS7SignerInfo* signerInfo;\n    CallbackDecryptContent decryptionCb;\n    CallbackWrapCEK        wrapCEKCb;\n    void*            decryptionCtx;\n\n    byte* signature;\n    byte* plainDigest;\n    byte* pkcs7Digest;\n    word32 signatureSz;\n    word32 plainDigestSz;\n    word32 pkcs7DigestSz;\n\n#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)\n    CallbackRsaSignRawDigest rsaSignRawDigestCb;\n#endif\n    /* !! NEW DATA MEMBERS MUST BE ADDED AT END !! */\n};\n\nWOLFSSL_API PKCS7* wc_PKCS7_New(void* heap, int devId);\nWOLFSSL_API int  wc_PKCS7_Init(PKCS7* pkcs7, void* heap, int devId);\nWOLFSSL_API int  wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* der, word32 derSz);\nWOLFSSL_API int  wc_PKCS7_AddCertificate(PKCS7* pkcs7, byte* der, word32 derSz);\nWOLFSSL_API void wc_PKCS7_Free(PKCS7* pkcs7);\n\nWOLFSSL_API int wc_PKCS7_GetAttributeValue(PKCS7* pkcs7, const byte* oid,\n        word32 oidSz, byte* out, word32* outSz);\n\nWOLFSSL_API int wc_PKCS7_SetSignerIdentifierType(PKCS7* pkcs7, int type);\nWOLFSSL_API int wc_PKCS7_SetContentType(PKCS7* pkcs7, byte* contentType,\n                                        word32 sz);\nWOLFSSL_API int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz);\nWOLFSSL_API int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,\n                                 word32 blockSz);\n\n/* CMS/PKCS#7 Data */\nWOLFSSL_API int  wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output,\n                                       word32 outputSz);\n\n/* CMS/PKCS#7 SignedData */\nWOLFSSL_API int  wc_PKCS7_SetDetached(PKCS7* pkcs7, word16 flag);\nWOLFSSL_API int  wc_PKCS7_NoDefaultSignedAttribs(PKCS7* pkcs7);\nWOLFSSL_API int  wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,\n                                          byte* output, word32 outputSz);\nWOLFSSL_API int  wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf,\n                                          word32 hashSz, byte* outputHead,\n                                          word32* outputHeadSz,\n                                          byte* outputFoot,\n                                          word32* outputFootSz);\nWOLFSSL_API void wc_PKCS7_AllowDegenerate(PKCS7* pkcs7, word16 flag);\nWOLFSSL_API int  wc_PKCS7_VerifySignedData(PKCS7* pkcs7,\n                                          byte* pkiMsg, word32 pkiMsgSz);\nWOLFSSL_API int  wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf,\n                                          word32 hashSz, byte* pkiMsgHead,\n                                          word32 pkiMsgHeadSz, byte* pkiMsgFoot,\n                                          word32 pkiMsgFootSz);\n\nWOLFSSL_API int  wc_PKCS7_GetSignerSID(PKCS7* pkcs7, byte* out, word32* outSz);\n\n/* CMS single-shot API for Signed FirmwarePkgData */\nWOLFSSL_API int  wc_PKCS7_EncodeSignedFPD(PKCS7* pkcs7, byte* privateKey,\n                                          word32 privateKeySz, int signOID,\n                                          int hashOID, byte* content,\n                                          word32 contentSz,\n                                          PKCS7Attrib* signedAttribs,\n                                          word32 signedAttribsSz, byte* output,\n                                          word32 outputSz);\n#ifndef NO_PKCS7_ENCRYPTED_DATA\n/* CMS single-shot API for Signed Encrypted FirmwarePkgData */\nWOLFSSL_API int  wc_PKCS7_EncodeSignedEncryptedFPD(PKCS7* pkcs7,\n                                          byte* encryptKey, word32 encryptKeySz,\n                                          byte* privateKey, word32 privateKeySz,\n                                          int encryptOID, int signOID,\n                                          int hashOID, byte* content,\n                                          word32 contentSz,\n                                          PKCS7Attrib* unprotectedAttribs,\n                                          word32 unprotectedAttribsSz,\n                                          PKCS7Attrib* signedAttribs,\n                                          word32 signedAttribsSz,\n                                          byte* output, word32 outputSz);\n#endif /* NO_PKCS7_ENCRYPTED_DATA */\n#if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)\n/* CMS single-shot API for Signed Compressed FirmwarePkgData */\nWOLFSSL_API int  wc_PKCS7_EncodeSignedCompressedFPD(PKCS7* pkcs7,\n                                          byte* privateKey, word32 privateKeySz,\n                                          int signOID, int hashOID,\n                                          byte* content, word32 contentSz,\n                                          PKCS7Attrib* signedAttribs,\n                                          word32 signedAttribsSz, byte* output,\n                                          word32 outputSz);\n\n#ifndef NO_PKCS7_ENCRYPTED_DATA\n/* CMS single-shot API for Signed Encrypted Compressed FirmwarePkgData */\nWOLFSSL_API int  wc_PKCS7_EncodeSignedEncryptedCompressedFPD(PKCS7* pkcs7,\n                                          byte* encryptKey, word32 encryptKeySz,\n                                          byte* privateKey, word32 privateKeySz,\n                                          int encryptOID, int signOID,\n                                          int hashOID, byte* content,\n                                          word32 contentSz,\n                                          PKCS7Attrib* unprotectedAttribs,\n                                          word32 unprotectedAttribsSz,\n                                          PKCS7Attrib* signedAttribs,\n                                          word32 signedAttribsSz,\n                                          byte* output, word32 outputSz);\n#endif /* !NO_PKCS7_ENCRYPTED_DATA */\n#endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */\n\n/* EnvelopedData and AuthEnvelopedData RecipientInfo functions */\nWOLFSSL_API int  wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert,\n                                          word32 certSz, int options);\nWOLFSSL_API int  wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert,\n                                          word32 certSz, int keyWrapOID,\n                                          int keyAgreeOID, byte* ukm,\n                                          word32 ukmSz, int options);\n\nWOLFSSL_API int  wc_PKCS7_SetKey(PKCS7* pkcs7, byte* key, word32 keySz);\nWOLFSSL_API int  wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID,\n                                          byte* kek, word32 kekSz,\n                                          byte* keyID, word32 keyIdSz,\n                                          void* timePtr, byte* otherOID,\n                                          word32 otherOIDSz, byte* other,\n                                          word32 otherSz, int options);\n\nWOLFSSL_API int  wc_PKCS7_SetPassword(PKCS7* pkcs7, byte* passwd, word32 pLen);\nWOLFSSL_API int  wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd,\n                                          word32 pLen, byte* salt,\n                                          word32 saltSz, int kdfOID,\n                                          int prfOID, int iterations,\n                                          int kekEncryptOID, int options);\nWOLFSSL_API int  wc_PKCS7_SetOriEncryptCtx(PKCS7* pkcs7, void* ctx);\nWOLFSSL_API int  wc_PKCS7_SetOriDecryptCtx(PKCS7* pkcs7, void* ctx);\nWOLFSSL_API int  wc_PKCS7_SetOriDecryptCb(PKCS7* pkcs7, CallbackOriDecrypt cb);\nWOLFSSL_API int  wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt cb,\n                                           int options);\nWOLFSSL_API int  wc_PKCS7_SetWrapCEKCb(PKCS7* pkcs7,\n        CallbackWrapCEK wrapCEKCb);\n\n#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)\nWOLFSSL_API int  wc_PKCS7_SetRsaSignRawDigestCb(PKCS7* pkcs7,\n        CallbackRsaSignRawDigest cb);\n#endif\n\n/* CMS/PKCS#7 EnvelopedData */\nWOLFSSL_API int  wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7,\n                                          byte* output, word32 outputSz);\nWOLFSSL_API int  wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,\n                                          word32 pkiMsgSz, byte* output,\n                                          word32 outputSz);\n\n/* CMS/PKCS#7 AuthEnvelopedData */\nWOLFSSL_API int  wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7,\n                                          byte* output, word32 outputSz);\nWOLFSSL_API int  wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,\n                                          word32 pkiMsgSz, byte* output,\n                                          word32 outputSz);\n\n/* CMS/PKCS#7 EncryptedData */\n#ifndef NO_PKCS7_ENCRYPTED_DATA\nWOLFSSL_API int  wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7,\n                                          byte* output, word32 outputSz);\nWOLFSSL_API int  wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg,\n                                          word32 pkiMsgSz, byte* output,\n                                          word32 outputSz);\nWOLFSSL_API int  wc_PKCS7_SetDecodeEncryptedCb(PKCS7* pkcs7,\n        CallbackDecryptContent decryptionCb);\nWOLFSSL_API int  wc_PKCS7_SetDecodeEncryptedCtx(PKCS7* pkcs7, void* ctx);\n#endif /* NO_PKCS7_ENCRYPTED_DATA */\n\n/* CMS/PKCS#7 CompressedData */\n#if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)\nWOLFSSL_API int wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output,\n                                              word32 outputSz);\nWOLFSSL_API int wc_PKCS7_DecodeCompressedData(PKCS7* pkcs7, byte* pkiMsg,\n                                              word32 pkiMsgSz, byte* output,\n                                              word32 outputSz);\n#endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* HAVE_PKCS7 */\n#endif /* WOLF_CRYPT_PKCS7_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/poly1305.h",
    "content": "/* poly1305.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/poly1305.h\n*/\n\n#ifndef WOLF_CRYPT_POLY1305_H\n#define WOLF_CRYPT_POLY1305_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef HAVE_POLY1305\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* auto detect between 32bit / 64bit */\n#if defined(__SIZEOF_INT128__) && defined(__LP64__)\n#define WC_HAS_SIZEOF_INT128_64BIT\n#endif\n\n#if defined(_MSC_VER) && defined(_M_X64)\n#define WC_HAS_MSVC_64BIT\n#endif\n\n#if (defined(__GNUC__) && defined(__LP64__) && \\\n        ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4))))\n#define WC_HAS_GCC_4_4_64BIT\n#endif\n\n#ifdef USE_INTEL_SPEEDUP\n#elif (defined(WC_HAS_SIZEOF_INT128_64BIT) || defined(WC_HAS_MSVC_64BIT) ||  \\\n       defined(WC_HAS_GCC_4_4_64BIT))\n#define POLY130564\n#else\n#define POLY130532\n#endif\n\nenum {\n    POLY1305 = 7,\n    POLY1305_BLOCK_SIZE = 16,\n    POLY1305_DIGEST_SIZE = 16,\n};\n\n#define WC_POLY1305_PAD_SZ 16\n#define WC_POLY1305_MAC_SZ 16\n\n/* Poly1305 state */\ntypedef struct Poly1305 {\n#ifdef USE_INTEL_SPEEDUP\n    word64 r[3];\n    word64 h[3];\n    word64 pad[2];\n    word64 hh[20];\n    word32 r1[8];\n    word32 r2[8];\n    word32 r3[8];\n    word32 r4[8];\n    word64 hm[16];\n    unsigned char buffer[8*POLY1305_BLOCK_SIZE];\n    size_t leftover;\n    unsigned char finished;\n    unsigned char started;\n#else\n#if defined(WOLFSSL_ARMASM) && defined(__aarch64__)\n    ALIGN128 word32 r[5];\n    ALIGN128 word32 r_2[5]; // r^2\n    ALIGN128 word32 r_4[5]; // r^4\n    ALIGN128 word32 h[5];\n    word32 pad[4];\n    word64 leftover;\n#else\n#if defined(POLY130564)\n    word64 r[3];\n    word64 h[3];\n    word64 pad[2];\n#else\n    word32 r[5];\n    word32 h[5];\n    word32 pad[4];\n#endif\n    size_t leftover;\n#endif /* WOLFSSL_ARMASM */\n    unsigned char buffer[POLY1305_BLOCK_SIZE];\n    unsigned char finished;\n#endif\n} Poly1305;\n\n/* does init */\n\nWOLFSSL_API int wc_Poly1305SetKey(Poly1305* poly1305, const byte* key,\n                                  word32 kySz);\nWOLFSSL_API int wc_Poly1305Update(Poly1305* poly1305, const byte*, word32);\nWOLFSSL_API int wc_Poly1305Final(Poly1305* poly1305, byte* tag);\nWOLFSSL_API int wc_Poly1305_MAC(Poly1305* ctx, byte* additional, word32 addSz,\n                               byte* input, word32 sz, byte* tag, word32 tagSz);\n\nvoid poly1305_block(Poly1305* ctx, const unsigned char *m);\nvoid poly1305_blocks(Poly1305* ctx, const unsigned char *m,\n                            size_t bytes);\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* HAVE_POLY1305 */\n#endif /* WOLF_CRYPT_POLY1305_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h",
    "content": "/* esp32-crypt.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n#ifndef __ESP32_CRYPT_H__\n\n#define __ESP32_CRYPT_H__\n\n//#include \"esp_idf_version.h\"    // ===== delete this line\n#include \"esp_types.h\"\n#include \"esp_log.h\"\n\n#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG\n#undef LOG_LOCAL_LEVEL\n#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG\n#else\n#undef LOG_LOCAL_LEVEL\n#define LOG_LOCAL_LEVEL ESP_LOG_ERROR\n#endif\n\n#include \"wolfssl/wolfcrypt/types.h\"   // ===== add this line\n#include \"wolfssl/wolfcrypt/wc_port.h\" // ===== add this line\n\n#include <freertos/FreeRTOS.h>\n#include \"soc/dport_reg.h\"\n#include \"soc/hwcrypto_reg.h\"\n#include \"soc/cpu.h\"\n#include \"driver/periph_ctrl.h\"\n#if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 1\n#include <esp32/rom/ets_sys.h>\n#else\n#include <rom/ets_sys.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nint esp_CryptHwMutexInit(wolfSSL_Mutex* mutex);\nint esp_CryptHwMutexLock(wolfSSL_Mutex* mutex, TickType_t xBloxkTime);\nint esp_CryptHwMutexUnLock(wolfSSL_Mutex* mutex);\n\n#ifndef NO_AES\n\n#if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 1\n#include \"esp32/rom/aes.h\"\n#else\n#include \"rom/aes.h\"\n#endif\n\ntypedef enum tagES32_AES_PROCESS {\n    ESP32_AES_LOCKHW = 1,\n    ESP32_AES_UPDATEKEY_ENCRYPT = 2,\n    ESP32_AES_UPDATEKEY_DECRYPT = 3,\n    ESP32_AES_UNLOCKHW          = 4\n} ESP32_AESPROCESS;\n\nstruct Aes;\nint wc_esp32AesCbcEncrypt(struct Aes* aes, byte* out, const byte* in, word32 sz);\nint wc_esp32AesCbcDecrypt(struct Aes* aes, byte* out, const byte* in, word32 sz);\nint wc_esp32AesEncrypt(struct Aes *aes, const byte* in, byte* out);\nint wc_esp32AesDecrypt(struct Aes *aes, const byte* in, byte* out);\n\n#endif\n\n#ifdef WOLFSSL_ESP32WROOM32_CRYPT_DEBUG\n\nvoid wc_esp32TimerStart();\nuint64_t  wc_esp32elapsedTime();\n\n#endif /* WOLFSSL_ESP32WROOM32_CRYPT_DEBUG */\n\n#if (!defined(NO_SHA) || !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \\\n      defined(WOLFSSL_SHA512)) && \\\n    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n\n/* RAW hash function APIs are not implemented with esp32 hardware acceleration*/\n#define WOLFSSL_NO_HASH_RAW\n#if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 1\n#include \"esp32/rom/sha.h\"\n#else\n#include \"rom/sha.h\"\n#endif\n\ntypedef enum {\n    ESP32_SHA_INIT = 0,\n    ESP32_SHA_HW = 1,\n    ESP32_SHA_SW = 2,\n} ESP32_DOSHA;\n\ntypedef struct {\n    byte isfirstblock;\n    /* 0 , 1 hard, 2 soft */\n    byte mode;\n    /* sha_type */\n    enum SHA_TYPE sha_type;\n} WC_ESP32SHA;\n\nint esp_sha_try_hw_lock(WC_ESP32SHA* ctx);\nvoid esp_sha_hw_unlock( void );\n\nstruct wc_Sha;\nint esp_sha_digest_process(struct wc_Sha* sha, byte bockprocess);\nint esp_sha_process(struct wc_Sha* sha, const byte* data);\n\n#ifndef NO_SHA256\n    struct wc_Sha256;\n    int esp_sha256_digest_process(struct wc_Sha256* sha, byte bockprocess);\n    int esp_sha256_process(struct wc_Sha256* sha, const byte* data);\n#endif\n\n#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)\n    struct wc_Sha512;\n    int esp_sha512_process(struct wc_Sha512* sha);\n    int esp_sha512_digest_process(struct wc_Sha512* sha, byte blockproc);\n#endif\n\n#endif /* NO_SHA && */\n\n#if !defined(NO_RSA) || defined(HAVE_ECC)\n\n#ifndef ESP_RSA_TIMEOUT\n    #define ESP_RSA_TIMEOUT 0xFFFFF\n#endif\n\nstruct fp_int;\nint esp_mp_mul(struct fp_int* X, struct fp_int* Y, struct fp_int* Z);\nint esp_mp_exptmod(struct fp_int* G, struct fp_int* X, word32 Xbits, struct fp_int* P,\n                                     struct fp_int* Y);\nint esp_mp_mulmod(struct fp_int* X, struct fp_int* Y, struct fp_int* M,\n                                     struct fp_int* Z);\n\n#endif /* NO_RSA || HAVE_ECC*/\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif  /* __ESP32_CRYPT_H__ */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/pwdbased.h",
    "content": "/* pwdbased.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/pwdbased.h\n*/\n\n#ifndef WOLF_CRYPT_PWDBASED_H\n#define WOLF_CRYPT_PWDBASED_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_PWDBASED\n\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/*\n * hashType renamed to typeH to avoid shadowing global declaration here:\n * wolfssl/wolfcrypt/asn.h line 173 in enum Oid_Types\n */\nWOLFSSL_API int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,\n                      const byte* passwd, int passwdLen, \n                      const byte* salt, int saltLen, int iterations, \n                      int hashType, void* heap);\nWOLFSSL_API int wc_PBKDF1(byte* output, const byte* passwd, int pLen,\n                      const byte* salt, int sLen, int iterations, int kLen,\n                      int typeH);\nWOLFSSL_API int wc_PBKDF2_ex(byte* output, const byte* passwd, int pLen,\n                    const byte* salt, int sLen, int iterations, int kLen,\n                    int typeH, void* heap, int devId);\nWOLFSSL_API int wc_PBKDF2(byte* output, const byte* passwd, int pLen,\n                      const byte* salt, int sLen, int iterations, int kLen,\n                      int typeH);\nWOLFSSL_API int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int pLen,\n                            const byte* salt, int sLen, int iterations,\n                            int kLen, int typeH, int purpose);\nWOLFSSL_API int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd,int passLen,\n                       const byte* salt, int saltLen, int iterations, int kLen,\n                       int hashType, int id, void* heap);\n\n#ifdef HAVE_SCRYPT\nWOLFSSL_API int wc_scrypt(byte* output, const byte* passwd, int passLen,\n                          const byte* salt, int saltLen, int cost,\n                          int blockSize, int parallel, int dkLen);\nWOLFSSL_API int wc_scrypt_ex(byte* output, const byte* passwd, int passLen,\n                             const byte* salt, int saltLen, word32 iterations,\n                             int blockSize, int parallel, int dkLen);\n#endif\n\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* NO_PWDBASED */\n#endif /* WOLF_CRYPT_PWDBASED_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/rabbit.h",
    "content": "/* rabbit.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/rabbit.h\n*/\n\n\n#ifndef WOLF_CRYPT_RABBIT_H\n#define WOLF_CRYPT_RABBIT_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_RABBIT\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n\nenum {\n\tRABBIT_ENC_TYPE  = 5     /* cipher unique type */\n};\n\n\n/* Rabbit Context */\ntypedef struct RabbitCtx {\n    word32 x[8];\n    word32 c[8];\n    word32 carry;\n} RabbitCtx;\n\n\n/* Rabbit stream cipher */\ntypedef struct Rabbit {\n    RabbitCtx masterCtx;\n    RabbitCtx workCtx;\n#ifdef XSTREAM_ALIGN\n    void*  heap;  /* heap hint, currently XMALLOC only used with aligning */\n#endif\n} Rabbit;\n\n\nWOLFSSL_API int wc_RabbitProcess(Rabbit*, byte*, const byte*, word32);\nWOLFSSL_API int wc_RabbitSetKey(Rabbit*, const byte* key, const byte* iv);\n\nWOLFSSL_LOCAL int wc_Rabbit_SetHeap(Rabbit* ctx, void* heap);\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* NO_RABBIT */\n#endif /* WOLF_CRYPT_RABBIT_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/random.h",
    "content": "/* random.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/random.h\n*/\n\n\n\n#ifndef WOLF_CRYPT_RANDOM_H\n#define WOLF_CRYPT_RANDOM_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n    #include <wolfssl/wolfcrypt/fips.h>\n#endif /* HAVE_FIPS_VERSION >= 2 */\n\n/* included for fips @wc_fips */\n#if defined(HAVE_FIPS) && \\\n        (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n#include <cyassl/ctaocrypt/random.h>\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n /* Maximum generate block length */\n#ifndef RNG_MAX_BLOCK_LEN\n    #ifdef HAVE_INTEL_QA\n        #define RNG_MAX_BLOCK_LEN (0xFFFFl)\n    #else\n        #define RNG_MAX_BLOCK_LEN (0x10000l)\n    #endif\n#endif\n\n/* Size of the BRBG seed */\n#ifndef DRBG_SEED_LEN\n    #define DRBG_SEED_LEN (440/8)\n#endif\n\n\n#if !defined(CUSTOM_RAND_TYPE)\n    /* To maintain compatibility the default is byte */\n    #define CUSTOM_RAND_TYPE    byte\n#endif\n\n/* make sure Hash DRBG is enabled, unless WC_NO_HASHDRBG is defined\n    or CUSTOM_RAND_GENERATE_BLOCK is defined */\n#if !defined(WC_NO_HASHDRBG) && !defined(CUSTOM_RAND_GENERATE_BLOCK)\n    #undef  HAVE_HASHDRBG\n    #define HAVE_HASHDRBG\n    #ifndef WC_RESEED_INTERVAL\n        #define WC_RESEED_INTERVAL (1000000)\n    #endif\n#endif\n\n\n/* avoid redefinition of structs */\n#if !defined(HAVE_FIPS) || \\\n    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))\n\n/* RNG supports the following sources (in order):\n * 1. CUSTOM_RAND_GENERATE_BLOCK: Defines name of function as RNG source and\n *     bypasses the options below.\n * 2. HAVE_INTEL_RDRAND: Uses the Intel RDRAND if supported by CPU.\n * 3. HAVE_HASHDRBG (requires SHA256 enabled): Uses SHA256 based P-RNG\n *     seeded via wc_GenerateSeed. This is the default source.\n */\n\n /* Seed source can be overridden by defining one of these:\n      CUSTOM_RAND_GENERATE_SEED\n      CUSTOM_RAND_GENERATE_SEED_OS\n      CUSTOM_RAND_GENERATE */\n\n\n#if defined(CUSTOM_RAND_GENERATE_BLOCK)\n    /* To use define the following:\n     * #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc\n     * extern int myRngFunc(byte* output, word32 sz);\n     */\n#elif defined(HAVE_HASHDRBG)\n    #ifdef NO_SHA256\n        #error \"Hash DRBG requires SHA-256.\"\n    #endif /* NO_SHA256 */\n    #include <wolfssl/wolfcrypt/sha256.h>\n#elif defined(HAVE_WNR)\n     /* allow whitewood as direct RNG source using wc_GenerateSeed directly */\n#elif defined(HAVE_INTEL_RDRAND)\n    /* Intel RDRAND or RDSEED */\n#elif !defined(WC_NO_RNG)\n    #error No RNG source defined!\n#endif\n\n#ifdef HAVE_WNR\n    #include <wnr.h>\n#endif\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n\n\n#if defined(USE_WINDOWS_API)\n    #if defined(_WIN64)\n        typedef unsigned __int64 ProviderHandle;\n        /* type HCRYPTPROV, avoid #include <windows.h> */\n    #else\n        typedef unsigned long ProviderHandle;\n    #endif\n#endif\n\n\n/* OS specific seeder */\ntypedef struct OS_Seed {\n    #if defined(USE_WINDOWS_API)\n        ProviderHandle handle;\n    #else\n        int fd;\n    #endif\n    #if defined(WOLF_CRYPTO_CB)\n        int devId;\n    #endif\n} OS_Seed;\n\n\n#ifndef WC_RNG_TYPE_DEFINED /* guard on redeclaration */\n    typedef struct WC_RNG WC_RNG;\n    #define WC_RNG_TYPE_DEFINED\n#endif\n\n/* RNG context */\nstruct WC_RNG {\n    OS_Seed seed;\n    void* heap;\n#ifdef HAVE_HASHDRBG\n    /* Hash-based Deterministic Random Bit Generator */\n    struct DRBG* drbg;\n#if defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_STATIC_MEMORY)\n    #define DRBG_STRUCT_SZ ((sizeof(word32)*3) + (DRBG_SEED_LEN*2))\n    #ifdef WOLFSSL_SMALL_STACK_CACHE\n        #define DRBG_STRUCT_SZ_SHA256 (sizeof(wc_Sha256))\n    #else\n        #define DRBG_STRUCT_SZ_SHA256 0\n    #endif\n    #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)\n        #define DRBG_STRUCT_SZ_ASYNC (sizeof(void*) + sizeof(int))\n    #else\n        #define DRBG_STRUCT_SZ_ASYNC 0\n    #endif\n    byte drbg_data[DRBG_STRUCT_SZ + DRBG_STRUCT_SZ_SHA256 + DRBG_STRUCT_SZ_ASYNC];\n#endif\n    byte status;\n#endif\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV asyncDev;\n#endif\n#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB)\n    int devId;\n#endif\n};\n\n#endif /* NO FIPS or have FIPS v2*/\n\n/* NO_OLD_RNGNAME removes RNG struct name to prevent possible type conflicts,\n * can't be used with CTaoCrypt FIPS */\n#if !defined(NO_OLD_RNGNAME) && !defined(HAVE_FIPS)\n    #define RNG WC_RNG\n#endif\n\n\nWOLFSSL_LOCAL\nint wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz);\n\n\n#ifdef HAVE_WNR\n    /* Whitewood netRandom client library */\n    WOLFSSL_API int  wc_InitNetRandom(const char*, wnr_hmac_key, int);\n    WOLFSSL_API int  wc_FreeNetRandom(void);\n#endif /* HAVE_WNR */\n\n\nWOLFSSL_ABI WOLFSSL_API WC_RNG* wc_rng_new(byte*, word32, void*);\nWOLFSSL_ABI WOLFSSL_API void wc_rng_free(WC_RNG*);\n\n\n#ifndef WC_NO_RNG\nWOLFSSL_API int  wc_InitRng(WC_RNG*);\nWOLFSSL_API int  wc_InitRng_ex(WC_RNG* rng, void* heap, int devId);\nWOLFSSL_API int  wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz);\nWOLFSSL_API int  wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz,\n                                    void* heap, int devId);\nWOLFSSL_API int  wc_RNG_GenerateBlock(WC_RNG*, byte*, word32 sz);\nWOLFSSL_API int  wc_RNG_GenerateByte(WC_RNG*, byte*);\nWOLFSSL_API int  wc_FreeRng(WC_RNG*);\n#else\n#include <wolfssl/wolfcrypt/error-crypt.h>\n#define wc_InitRng(rng) NOT_COMPILED_IN\n#define wc_InitRng_ex(rng, h, d) NOT_COMPILED_IN\n#define wc_InitRngNonce(rng, n, s) NOT_COMPILED_IN\n#define wc_InitRngNonce_ex(rng, n, s, h, d) NOT_COMPILED_IN\n#define wc_RNG_GenerateBlock(rng, b, s) NOT_COMPILED_IN\n#define wc_RNG_GenerateByte(rng, b) NOT_COMPILED_IN\n#define wc_FreeRng(rng) (void)NOT_COMPILED_IN\n#endif\n\n\n\n#ifdef HAVE_HASHDRBG\n    WOLFSSL_LOCAL int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy,\n                                        word32 entropySz);\n    WOLFSSL_API int wc_RNG_TestSeed(const byte* seed, word32 seedSz);\n    WOLFSSL_API int wc_RNG_HealthTest(int reseed,\n                                        const byte* entropyA, word32 entropyASz,\n                                        const byte* entropyB, word32 entropyBSz,\n                                        byte* output, word32 outputSz);\n    WOLFSSL_API int wc_RNG_HealthTest_ex(int reseed,\n                                        const byte* nonce, word32 nonceSz,\n                                        const byte* entropyA, word32 entropyASz,\n                                        const byte* entropyB, word32 entropyBSz,\n                                        byte* output, word32 outputSz,\n                                        void* heap, int devId);\n#endif /* HAVE_HASHDRBG */\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLF_CRYPT_RANDOM_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/ripemd.h",
    "content": "/* ripemd.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/ripemd.h\n*/\n\n#ifndef WOLF_CRYPT_RIPEMD_H\n#define WOLF_CRYPT_RIPEMD_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef WOLFSSL_RIPEMD\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n\n/* in bytes */\nenum {\n    RIPEMD             =  3,    /* hash type unique */\n    RIPEMD_BLOCK_SIZE  = 64,\n    RIPEMD_DIGEST_SIZE = 20,\n    RIPEMD_PAD_SIZE    = 56\n};\n\n\n/* RipeMd 160 digest */\ntypedef struct RipeMd {\n    word32  buffLen;   /* in bytes          */\n    word32  loLen;     /* length in bytes   */\n    word32  hiLen;     /* length in bytes   */\n    word32  digest[RIPEMD_DIGEST_SIZE / sizeof(word32)];\n    word32  buffer[RIPEMD_BLOCK_SIZE  / sizeof(word32)];\n} RipeMd;\n\n\nWOLFSSL_API int wc_InitRipeMd(RipeMd*);\nWOLFSSL_API int wc_RipeMdUpdate(RipeMd*, const byte*, word32);\nWOLFSSL_API int wc_RipeMdFinal(RipeMd*, byte*);\n\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLFSSL_RIPEMD */\n#endif /* WOLF_CRYPT_RIPEMD_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/rsa.h",
    "content": "/* rsa.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/rsa.h\n*/\n\n\n#ifndef WOLF_CRYPT_RSA_H\n#define WOLF_CRYPT_RSA_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_RSA\n\n\n/* RSA default exponent */\n#ifndef WC_RSA_EXPONENT\n    #define WC_RSA_EXPONENT 65537L\n#endif\n\n#if defined(WC_RSA_NONBLOCK)\n    /* enable support for fast math based non-blocking exptmod */\n    /* this splits the RSA function into many smaller operations */\n    #ifndef USE_FAST_MATH\n        #error RSA non-blocking mode only supported using fast math\n    #endif\n    #ifndef TFM_TIMING_RESISTANT\n      #error RSA non-blocking mode only supported with timing resistance enabled\n    #endif\n\n    /* RSA bounds check is not supported with RSA non-blocking mode */\n    #undef  NO_RSA_BOUNDS_CHECK\n    #define NO_RSA_BOUNDS_CHECK\n#endif\n\n/* allow for user to plug in own crypto */\n#if !defined(HAVE_FIPS) && (defined(HAVE_USER_RSA) || defined(HAVE_FAST_RSA))\n    #include \"user_rsa.h\"\n#else\n\n#if defined(HAVE_FIPS) && \\\n\t(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n/* for fips @wc_fips */\n#include <cyassl/ctaocrypt/rsa.h>\n#if defined(CYASSL_KEY_GEN) && !defined(WOLFSSL_KEY_GEN)\n    #define WOLFSSL_KEY_GEN\n#endif\n#else\n    #include <wolfssl/wolfcrypt/integer.h>\n    #include <wolfssl/wolfcrypt/random.h>\n#endif /* HAVE_FIPS && HAVE_FIPS_VERION 1 */\n#if defined(HAVE_FIPS) && \\\n\tdefined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n#include <wolfssl/wolfcrypt/fips.h>\n#endif\n\n/* header file needed for OAEP padding */\n#include <wolfssl/wolfcrypt/hash.h>\n\n#ifdef WOLFSSL_XILINX_CRYPT\n#include \"xsecure_rsa.h\"\n#endif\n\n#if defined(WOLFSSL_CRYPTOCELL)\n    #include <wolfssl/wolfcrypt/port/arm/cryptoCell.h>\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\nenum {\n    RSA_MIN_SIZE = 512,\n    RSA_MAX_SIZE = 4096,\n};\n\n/* avoid redefinition of structs */\n#if !defined(HAVE_FIPS) || \\\n    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n    #ifdef WOLFSSL_CERT_GEN\n        #include <wolfssl/wolfcrypt/asn.h>\n    #endif\n#endif\n\nenum {\n    RSA_PUBLIC   = 0,\n    RSA_PRIVATE  = 1,\n\n    RSA_TYPE_UNKNOWN    = -1,\n    RSA_PUBLIC_ENCRYPT  = 0,\n    RSA_PUBLIC_DECRYPT  = 1,\n    RSA_PRIVATE_ENCRYPT = 2,\n    RSA_PRIVATE_DECRYPT = 3,\n\n    RSA_BLOCK_TYPE_1 = 1,\n    RSA_BLOCK_TYPE_2 = 2,\n\n    RSA_MIN_PAD_SZ   = 11,     /* separator + 0 + pad value + 8 pads */\n\n    RSA_PSS_PAD_SZ = 8,\n    RSA_PSS_SALT_MAX_SZ = 62,\n\n#ifdef OPENSSL_EXTRA\n    RSA_PKCS1_PADDING_SIZE = 11,\n    RSA_PKCS1_OAEP_PADDING_SIZE = 42, /* (2 * hashlen(SHA-1)) + 2 */\n#endif\n#ifdef WC_RSA_PSS\n    RSA_PSS_PAD_TERM = 0xBC,\n#endif\n\n    RSA_PSS_SALT_LEN_DEFAULT  = -1,\n#ifdef WOLFSSL_PSS_SALT_LEN_DISCOVER\n    RSA_PSS_SALT_LEN_DISCOVER = -2,\n#endif\n\n#ifdef HAVE_PKCS11\n    RSA_MAX_ID_LEN      = 32,\n#endif\n};\n\n#ifdef WC_RSA_NONBLOCK\ntypedef struct RsaNb {\n    exptModNb_t exptmod; /* non-block expt_mod */\n    mp_int tmp;\n} RsaNb;\n#endif\n\n/* RSA */\nstruct RsaKey {\n    mp_int n, e;\n#ifndef WOLFSSL_RSA_PUBLIC_ONLY\n    mp_int d, p, q;\n#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)\n    mp_int dP, dQ, u;\n#endif\n#endif\n    void* heap;                               /* for user memory overrides */\n    byte* data;                               /* temp buffer for async RSA */\n    int   type;                               /* public or private */\n    int   state;\n    word32 dataLen;\n#ifdef WC_RSA_BLINDING\n    WC_RNG* rng;                              /* for PrivateDecrypt blinding */\n#endif\n#ifdef WOLF_CRYPTO_CB\n    int   devId;\n#endif\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV asyncDev;\n    #ifdef WOLFSSL_CERT_GEN\n        CertSignCtx certSignCtx; /* context info for cert sign (MakeSignature) */\n    #endif\n#endif /* WOLFSSL_ASYNC_CRYPT */\n#ifdef WOLFSSL_XILINX_CRYPT\n    word32 pubExp; /* to keep values in scope they are here in struct */\n    byte*  mod;\n    XSecure_Rsa xRsa;\n#endif\n#ifdef HAVE_PKCS11\n    byte id[RSA_MAX_ID_LEN];\n    int  idLen;\n#endif\n#if defined(WOLFSSL_ASYNC_CRYPT) || !defined(WOLFSSL_RSA_VERIFY_INLINE)\n    byte   dataIsAlloc;\n#endif\n#ifdef WC_RSA_NONBLOCK\n    RsaNb* nb;\n#endif\n#ifdef WOLFSSL_AFALG_XILINX_RSA\n    int alFd;\n    int rdFd;\n#endif\n#if defined(WOLFSSL_CRYPTOCELL)\n    rsa_context_t ctx;\n#endif\n};\n\n#ifndef WC_RSAKEY_TYPE_DEFINED\n    typedef struct RsaKey RsaKey;\n    #define WC_RSAKEY_TYPE_DEFINED\n#endif\n\n#endif /*HAVE_FIPS */\n\nWOLFSSL_API int  wc_InitRsaKey(RsaKey* key, void* heap);\nWOLFSSL_API int  wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId);\nWOLFSSL_API int  wc_FreeRsaKey(RsaKey* key);\n#ifdef HAVE_PKCS11\nWOLFSSL_API int wc_InitRsaKey_Id(RsaKey* key, unsigned char* id, int len,\n                                 void* heap, int devId);\n#endif\nWOLFSSL_API int  wc_CheckRsaKey(RsaKey* key);\n#ifdef WOLFSSL_XILINX_CRYPT\nWOLFSSL_LOCAL int wc_InitRsaHw(RsaKey* key);\n#endif /* WOLFSSL_XILINX_CRYPT */\n\nWOLFSSL_API int  wc_RsaFunction(const byte* in, word32 inLen, byte* out,\n                           word32* outLen, int type, RsaKey* key, WC_RNG* rng);\n\nWOLFSSL_API int  wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out,\n                                 word32 outLen, RsaKey* key, WC_RNG* rng);\nWOLFSSL_API int  wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out,\n                                        RsaKey* key);\nWOLFSSL_API int  wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,\n                                  word32 outLen, RsaKey* key);\nWOLFSSL_API int  wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out,\n                            word32 outLen, RsaKey* key, WC_RNG* rng);\nWOLFSSL_API int  wc_RsaPSS_Sign(const byte* in, word32 inLen, byte* out,\n                                word32 outLen, enum wc_HashType hash, int mgf,\n                                RsaKey* key, WC_RNG* rng);\nWOLFSSL_API int  wc_RsaPSS_Sign_ex(const byte* in, word32 inLen, byte* out,\n                                   word32 outLen, enum wc_HashType hash,\n                                   int mgf, int saltLen, RsaKey* key,\n                                   WC_RNG* rng);\nWOLFSSL_API int  wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out,\n                                    RsaKey* key);\nWOLFSSL_API int  wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out,\n                              word32 outLen, RsaKey* key);\nWOLFSSL_API int  wc_RsaPSS_VerifyInline(byte* in, word32 inLen, byte** out,\n                                        enum wc_HashType hash, int mgf,\n                                        RsaKey* key);\nWOLFSSL_API int  wc_RsaPSS_VerifyInline_ex(byte* in, word32 inLen, byte** out,\n                                           enum wc_HashType hash, int mgf,\n                                           int saltLen, RsaKey* key);\nWOLFSSL_API int  wc_RsaPSS_Verify(byte* in, word32 inLen, byte* out,\n                                  word32 outLen, enum wc_HashType hash, int mgf,\n                                  RsaKey* key);\nWOLFSSL_API int  wc_RsaPSS_Verify_ex(byte* in, word32 inLen, byte* out,\n                                     word32 outLen, enum wc_HashType hash,\n                                     int mgf, int saltLen, RsaKey* key);\nWOLFSSL_API int  wc_RsaPSS_CheckPadding(const byte* in, word32 inLen, byte* sig,\n                                        word32 sigSz,\n                                        enum wc_HashType hashType);\nWOLFSSL_API int  wc_RsaPSS_CheckPadding_ex(const byte* in, word32 inLen,\n                                           byte* sig, word32 sigSz,\n                                           enum wc_HashType hashType,\n                                           int saltLen, int bits);\nWOLFSSL_API int  wc_RsaPSS_VerifyCheckInline(byte* in, word32 inLen, byte** out,\n                               const byte* digest, word32 digentLen,\n                               enum wc_HashType hash, int mgf,\n                               RsaKey* key);\nWOLFSSL_API int  wc_RsaPSS_VerifyCheck(byte* in, word32 inLen,\n                               byte* out, word32 outLen,\n                               const byte* digest, word32 digestLen,\n                               enum wc_HashType hash, int mgf,\n                               RsaKey* key);\n\nWOLFSSL_API int  wc_RsaEncryptSize(RsaKey* key);\n\n#if !defined(HAVE_FIPS) || \\\n\t(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))\n/* to avoid asn duplicate symbols @wc_fips */\nWOLFSSL_API int  wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,\n                                                               RsaKey*, word32);\nWOLFSSL_API int  wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx,\n                                                               RsaKey*, word32);\nWOLFSSL_API int  wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz,\n                                        const byte* e, word32 eSz, RsaKey* key);\n#ifdef WOLFSSL_KEY_GEN\n    WOLFSSL_API int wc_RsaKeyToDer(RsaKey*, byte* output, word32 inLen);\n#endif\n\n#ifdef WC_RSA_BLINDING\n    WOLFSSL_API int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng);\n#endif\n#ifdef WC_RSA_NONBLOCK\n    WOLFSSL_API int wc_RsaSetNonBlock(RsaKey* key, RsaNb* nb);\n    #ifdef WC_RSA_NONBLOCK_TIME\n    WOLFSSL_API int wc_RsaSetNonBlockTime(RsaKey* key, word32 maxBlockUs,\n                                          word32 cpuMHz);\n    #endif\n#endif\n\n/*\n   choice of padding added after fips, so not available when using fips RSA\n */\n\n/* Mask Generation Function Identifiers */\n#define WC_MGF1NONE   0\n#define WC_MGF1SHA1   26\n#define WC_MGF1SHA224 4\n#define WC_MGF1SHA256 1\n#define WC_MGF1SHA384 2\n#define WC_MGF1SHA512 3\n\n/* Padding types */\n#define WC_RSA_PKCSV15_PAD 0\n#define WC_RSA_OAEP_PAD    1\n#define WC_RSA_PSS_PAD     2\n#define WC_RSA_NO_PAD      3\n\nWOLFSSL_API int  wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out,\n                   word32 outLen, RsaKey* key, WC_RNG* rng, int type,\n                   enum wc_HashType hash, int mgf, byte* label, word32 lableSz);\nWOLFSSL_API int  wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen,\n                   byte* out, word32 outLen, RsaKey* key, int type,\n                   enum wc_HashType hash, int mgf, byte* label, word32 lableSz);\nWOLFSSL_API int  wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen,\n                      byte** out, RsaKey* key, int type, enum wc_HashType hash,\n                      int mgf, byte* label, word32 lableSz);\n#if defined(WC_RSA_DIRECT) || defined(WC_RSA_NO_PADDING)\nWOLFSSL_API int wc_RsaDirect(byte* in, word32 inLen, byte* out, word32* outSz,\n                   RsaKey* key, int type, WC_RNG* rng);\n#endif\n\n#endif /* HAVE_FIPS */\n\nWOLFSSL_API int  wc_RsaFlattenPublicKey(RsaKey*, byte*, word32*, byte*,\n                                                                       word32*);\nWOLFSSL_API int wc_RsaExportKey(RsaKey* key,\n                                byte* e, word32* eSz,\n                                byte* n, word32* nSz,\n                                byte* d, word32* dSz,\n                                byte* p, word32* pSz,\n                                byte* q, word32* qSz);\n\nWOLFSSL_API int wc_RsaKeyToPublicDer(RsaKey*, byte* output, word32 inLen);\n\n#ifdef WOLFSSL_KEY_GEN\n    WOLFSSL_API int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng);\n    WOLFSSL_API int wc_CheckProbablePrime_ex(const byte* p, word32 pSz,\n                                          const byte* q, word32 qSz,\n                                          const byte* e, word32 eSz,\n                                          int nlen, int* isPrime, WC_RNG* rng);\n    WOLFSSL_API int wc_CheckProbablePrime(const byte* p, word32 pSz,\n                                          const byte* q, word32 qSz,\n                                          const byte* e, word32 eSz,\n                                          int nlen, int* isPrime);\n#endif\n\n#endif /* HAVE_USER_RSA */\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* NO_RSA */\n#endif /* WOLF_CRYPT_RSA_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/selftest.h",
    "content": "/* selftest.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n#ifndef WOLFCRYPT_SELF_TEST_H\n#define WOLFCRYPT_SELF_TEST_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifdef HAVE_SELFTEST\n    /* Get wolfCrypt CAVP version */\n    WOLFSSL_API const char* wolfCrypt_GetVersion_CAVP_selftest(void);\n\n    /* wolfCrypt self test, runs CAVP KATs */\n    WOLFSSL_API int wolfCrypt_SelfTest(void);\n#endif\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLFCRYPT_SELF_TEST_H */\n\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/settings.h",
    "content": "/* settings.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n/* Place OS specific preprocessor flags, defines, includes here, will be\n   included into every file because types.h includes it */\n\n\n#ifndef WOLF_CRYPT_SETTINGS_H\n#define WOLF_CRYPT_SETTINGS_H\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* Uncomment next line if using IPHONE */\n/* #define IPHONE */\n\n/* Uncomment next line if using ThreadX */\n/* #define THREADX */\n\n/* Uncomment next line if using Micrium uC/OS-III */\n/* #define MICRIUM */\n\n/* Uncomment next line if using Deos RTOS*/\n/* #define WOLFSSL_DEOS*/\n\n/* Uncomment next line if using Mbed */\n/* #define MBED */\n\n/* Uncomment next line if using Microchip PIC32 ethernet starter kit */\n/* #define MICROCHIP_PIC32 */\n\n/* Uncomment next line if using Microchip TCP/IP stack, version 5 */\n/* #define MICROCHIP_TCPIP_V5 */\n\n/* Uncomment next line if using Microchip TCP/IP stack, version 6 or later */\n/* #define MICROCHIP_TCPIP */\n\n/* Uncomment next line if using PIC32MZ Crypto Engine */\n/* #define WOLFSSL_MICROCHIP_PIC32MZ */\n\n/* Uncomment next line if using FreeRTOS */\n/* #define FREERTOS */\n\n/* Uncomment next line if using FreeRTOS+ TCP */\n/* #define FREERTOS_TCP */\n\n/* Uncomment next line if using FreeRTOS Windows Simulator */\n/* #define FREERTOS_WINSIM */\n\n/* Uncomment next line if using RTIP */\n/* #define EBSNET */\n\n/* Uncomment next line if using lwip */\n/* #define WOLFSSL_LWIP */\n\n/* Uncomment next line if building wolfSSL for a game console */\n/* #define WOLFSSL_GAME_BUILD */\n\n/* Uncomment next line if building wolfSSL for LSR */\n/* #define WOLFSSL_LSR */\n\n/* Uncomment next line if building for Freescale Classic MQX version 5.0 */\n/* #define FREESCALE_MQX_5_0 */\n\n/* Uncomment next line if building for Freescale Classic MQX version 4.0 */\n/* #define FREESCALE_MQX_4_0 */\n\n/* Uncomment next line if building for Freescale Classic MQX/RTCS/MFS */\n/* #define FREESCALE_MQX */\n\n/* Uncomment next line if building for Freescale KSDK MQX/RTCS/MFS */\n/* #define FREESCALE_KSDK_MQX */\n\n/* Uncomment next line if building for Freescale KSDK Bare Metal */\n/* #define FREESCALE_KSDK_BM */\n\n/* Uncomment next line if building for Freescale KSDK FreeRTOS, */\n/* (old name FREESCALE_FREE_RTOS) */\n/* #define FREESCALE_KSDK_FREERTOS */\n\n/* Uncomment next line if using STM32F2 */\n/* #define WOLFSSL_STM32F2 */\n\n/* Uncomment next line if using STM32F4 */\n/* #define WOLFSSL_STM32F4 */\n\n/* Uncomment next line if using STM32FL */\n/* #define WOLFSSL_STM32FL */\n\n/* Uncomment next line if using STM32F7 */\n/* #define WOLFSSL_STM32F7 */\n\n/* Uncomment next line if using QL SEP settings */\n/* #define WOLFSSL_QL */\n\n/* Uncomment next line if building for EROAD */\n/* #define WOLFSSL_EROAD */\n\n/* Uncomment next line if building for IAR EWARM */\n/* #define WOLFSSL_IAR_ARM */\n\n/* Uncomment next line if building for Rowley CrossWorks ARM */\n/* #define WOLFSSL_ROWLEY_ARM */\n\n/* Uncomment next line if using TI-RTOS settings */\n/* #define WOLFSSL_TIRTOS */\n\n/* Uncomment next line if building with PicoTCP */\n/* #define WOLFSSL_PICOTCP */\n\n/* Uncomment next line if building for PicoTCP demo bundle */\n/* #define WOLFSSL_PICOTCP_DEMO */\n\n/* Uncomment next line if building for uITRON4  */\n/* #define WOLFSSL_uITRON4 */\n\n/* Uncomment next line if building for uT-Kernel */\n/* #define WOLFSSL_uTKERNEL2 */\n\n/* Uncomment next line if using Max Strength build */\n/* #define WOLFSSL_MAX_STRENGTH */\n\n/* Uncomment next line if building for VxWorks */\n/* #define WOLFSSL_VXWORKS */\n\n/* Uncomment next line if building for Nordic nRF5x platofrm */\n/* #define WOLFSSL_NRF5x */\n\n/* Uncomment next line to enable deprecated less secure static DH suites */\n/* #define WOLFSSL_STATIC_DH */\n\n/* Uncomment next line to enable deprecated less secure static RSA suites */\n/* #define WOLFSSL_STATIC_RSA */\n\n/* Uncomment next line if building for ARDUINO */\n/* Uncomment both lines if building for ARDUINO on INTEL_GALILEO */\n/* #define WOLFSSL_ARDUINO */\n/* #define INTEL_GALILEO */\n\n/* Uncomment next line to enable asynchronous crypto WC_PENDING_E */\n/* #define WOLFSSL_ASYNC_CRYPT */\n\n/* Uncomment next line if building for uTasker */\n/* #define WOLFSSL_UTASKER */\n\n/* Uncomment next line if building for embOS */\n/* #define WOLFSSL_EMBOS */\n\n/* Uncomment next line if building for RIOT-OS */\n/* #define WOLFSSL_RIOT_OS */\n\n/* Uncomment next line if building for using XILINX hardened crypto */\n/* #define WOLFSSL_XILINX_CRYPT */\n\n/* Uncomment next line if building for using XILINX */\n/* #define WOLFSSL_XILINX */\n\n/* Uncomment next line if building for WICED Studio. */\n/* #define WOLFSSL_WICED  */\n\n/* Uncomment next line if building for Nucleus 1.2 */\n/* #define WOLFSSL_NUCLEUS_1_2 */\n\n/* Uncomment next line if building for using Apache mynewt */\n/* #define WOLFSSL_APACHE_MYNEWT */\n\n/* Uncomment next line if building for using ESP-IDF */\n/* #define WOLFSSL_ESPIDF */\n\n/* Uncomment next line if using Espressif ESP32-WROOM-32 */\n/* #define WOLFSSL_ESPWROOM32 */\n\n/* Uncomment next line if using Espressif ESP32-WROOM-32SE */\n/* #define WOLFSSL_ESPWROOM32SE */\n\n/* Uncomment next line if using ARM CRYPTOCELL*/\n/* #define WOLFSSL_CRYPTOCELL */\n\n/* Uncomment next line if using RENESAS TSIP */\n/* #define WOLFSSL_RENESAS_TSIP */\n\n/* Uncomment next line if using RENESAS RX64N */\n/* #define WOLFSSL_RENESAS_RX65N */\n\n#include <wolfssl/wolfcrypt/visibility.h>\n\n#define WOLFSSL_USER_SETTINGS\n\n#ifdef WOLFSSL_USER_SETTINGS\n    #include \"user_settings.h\"\n#endif\n\n\n/* make sure old RNG name is used with CTaoCrypt FIPS */\n#ifdef HAVE_FIPS\n    #if !defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)\n        #define WC_RNG RNG\n    #else\n        #ifndef WOLFSSL_STM32L4\n            #define RNG WC_RNG\n        #endif\n    #endif\n    /* blinding adds API not available yet in FIPS mode */\n    #undef WC_RSA_BLINDING\n#endif\n\n\n#if defined(_WIN32) && !defined(_M_X64) && \\\n    defined(HAVE_AESGCM) && defined(WOLFSSL_AESNI)\n\n/* The _M_X64 macro is what's used in the headers for MSC to tell if it\n * has the 64-bit versions of the 128-bit integers available. If one is\n * building on 32-bit Windows with AES-NI, turn off the AES-GCMloop\n * unrolling. */\n\n    #define AES_GCM_AESNI_NO_UNROLL\n#endif\n\n#ifdef IPHONE\n    #define SIZEOF_LONG_LONG 8\n#endif\n\n#ifdef THREADX\n    #define SIZEOF_LONG_LONG 8\n#endif\n\n#ifdef HAVE_NETX\n    #ifdef NEED_THREADX_TYPES\n        #include <types.h>\n    #endif\n    #include <nx_api.h>\n#endif\n\n#if defined(WOLFSSL_ESPIDF)\n    #define FREERTOS\n    #define WOLFSSL_LWIP\n    #define NO_WRITEV\n    #define SIZEOF_LONG_LONG 8\n    #define NO_WOLFSSL_DIR\n    #define WOLFSSL_NO_CURRDIR\n\n    #define TFM_TIMING_RESISTANT\n    #define ECC_TIMING_RESISTANT\n    #define WC_RSA_BLINDING\n\n#if defined(WOLFSSL_ESPWROOM32) || defined(WOLFSSL_ESPWROOM32SE)\n   #ifndef NO_ESP32WROOM32_CRYPT\n        #define WOLFSSL_ESP32WROOM32_CRYPT\n        #if defined(ESP32_USE_RSA_PRIMITIVE) && \\\n            !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI)\n            #define WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI\n            #define USE_FAST_MATH\n            #define WOLFSSL_SMALL_STACK\n        #endif\n   #endif\n#endif\n#endif /* WOLFSSL_ESPIDF */\n\n#if defined(WOLFSSL_RENESAS_TSIP)\n    #define TSIP_TLS_HMAC_KEY_INDEX_WORDSIZE 64\n    #define TSIP_TLS_MASTERSECRET_SIZE       80   /* 20 words */\n    #define TSIP_TLS_ENCPUBKEY_SZ_BY_CERTVRFY 560 /* in byte  */\n    #if !defined(NO_RENESAS_TSIP_CRYPT) && defined(WOLFSSL_RENESAS_RX65N)\n        #define WOLFSSL_RENESAS_TSIP_CRYPT\n        #define WOLFSSL_RENESAS_TSIP_TLS\n        #define WOLFSSL_RENESAS_TSIP_TLS_AES_CRYPT\n    #endif\n#endif\n\n#if defined(HAVE_LWIP_NATIVE) /* using LwIP native TCP socket */\n    #define WOLFSSL_LWIP\n    #define NO_WRITEV\n    #define SINGLE_THREADED\n    #define WOLFSSL_USER_IO\n    #define NO_FILESYSTEM\n#endif\n\n#if defined(WOLFSSL_CONTIKI)\n    #include <contiki.h>\n    #define WOLFSSL_UIP\n    #define NO_WOLFSSL_MEMORY\n    #define NO_WRITEV\n    #define SINGLE_THREADED\n    #define WOLFSSL_USER_IO\n    #define NO_FILESYSTEM\n    #define CUSTOM_RAND_TYPE uint16_t\n    #define CUSTOM_RAND_GENERATE random_rand\n    static inline word32 LowResTimer(void)\n    {\n        return clock_seconds();\n    }\n#endif\n\n#if defined(WOLFSSL_IAR_ARM) || defined(WOLFSSL_ROWLEY_ARM)\n    #define NO_MAIN_DRIVER\n    #define SINGLE_THREADED\n    #if !defined(USE_CERT_BUFFERS_2048) && !defined(USE_CERT_BUFFERS_4096)\n        #define USE_CERT_BUFFERS_1024\n    #endif\n    #define BENCH_EMBEDDED\n    #define NO_FILESYSTEM\n    #define NO_WRITEV\n    #define WOLFSSL_USER_IO\n    #define BENCH_EMBEDDED\n#endif\n\n#ifdef MICROCHIP_PIC32\n    /* #define WOLFSSL_MICROCHIP_PIC32MZ */\n    #define SIZEOF_LONG_LONG 8\n    #define SINGLE_THREADED\n    #define WOLFSSL_USER_IO\n    #define NO_WRITEV\n    #define NO_DEV_RANDOM\n    #define NO_FILESYSTEM\n    #define USE_FAST_MATH\n    #define TFM_TIMING_RESISTANT\n    #define WOLFSSL_HAVE_MIN\n    #define WOLFSSL_HAVE_MAX\n    #define NO_BIG_INT\n#endif\n\n#ifdef WOLFSSL_MICROCHIP_PIC32MZ\n    #ifndef NO_PIC32MZ_CRYPT\n        #define WOLFSSL_PIC32MZ_CRYPT\n    #endif\n    #ifndef NO_PIC32MZ_RNG\n        #define WOLFSSL_PIC32MZ_RNG\n    #endif\n    #ifndef NO_PIC32MZ_HASH\n        #define WOLFSSL_PIC32MZ_HASH\n    #endif\n#endif\n\n#ifdef MICROCHIP_TCPIP_V5\n    /* include timer functions */\n    #include \"TCPIP Stack/TCPIP.h\"\n#endif\n\n#ifdef MICROCHIP_TCPIP\n    /* include timer, NTP functions */\n    #ifdef MICROCHIP_MPLAB_HARMONY\n        #include \"tcpip/tcpip.h\"\n    #else\n        #include \"system/system_services.h\"\n        #include \"tcpip/sntp.h\"\n    #endif\n#endif\n\n#ifdef MBED\n    #define WOLFSSL_USER_IO\n    #define NO_FILESYSTEM\n    #define NO_CERTS\n    #if !defined(USE_CERT_BUFFERS_2048) && !defined(USE_CERT_BUFFERS_4096)\n        #define USE_CERT_BUFFERS_1024\n    #endif\n    #define NO_WRITEV\n    #define NO_DEV_RANDOM\n    #define NO_SHA512\n    #define NO_DH\n    /* Allows use of DH with fixed points if uncommented and NO_DH is removed */\n    /* WOLFSSL_DH_CONST */\n    #define NO_DSA\n    #define NO_HC128\n    #define HAVE_ECC\n    #define NO_SESSION_CACHE\n    #define WOLFSSL_CMSIS_RTOS\n#endif\n\n\n#ifdef WOLFSSL_EROAD\n    #define FREESCALE_MQX\n    #define FREESCALE_MMCAU\n    #define SINGLE_THREADED\n    #define NO_STDIO_FILESYSTEM\n    #define WOLFSSL_LEANPSK\n    #define HAVE_NULL_CIPHER\n    #define NO_OLD_TLS\n    #define NO_ASN\n    #define NO_BIG_INT\n    #define NO_RSA\n    #define NO_DSA\n    #define NO_DH\n    /* Allows use of DH with fixed points if uncommented and NO_DH is removed */\n    /* WOLFSSL_DH_CONST */\n    #define NO_CERTS\n    #define NO_PWDBASED\n    #define NO_DES3\n    #define NO_MD4\n    #define NO_RC4\n    #define NO_MD5\n    #define NO_SESSION_CACHE\n    #define NO_MAIN_DRIVER\n#endif\n\n#ifdef WOLFSSL_PICOTCP\n    #ifndef errno\n        #define errno pico_err\n    #endif\n    #include \"pico_defines.h\"\n    #include \"pico_stack.h\"\n    #include \"pico_constants.h\"\n    #include \"pico_protocol.h\"\n    #define CUSTOM_RAND_GENERATE pico_rand\n#endif\n\n#ifdef WOLFSSL_PICOTCP_DEMO\n    #define WOLFSSL_STM32\n    #define USE_FAST_MATH\n    #define TFM_TIMING_RESISTANT\n    #define XMALLOC(s, h, type)  PICO_ZALLOC((s))\n    #define XFREE(p, h, type)    PICO_FREE((p))\n    #define SINGLE_THREADED\n    #define NO_WRITEV\n    #define WOLFSSL_USER_IO\n    #define NO_DEV_RANDOM\n    #define NO_FILESYSTEM\n#endif\n\n#ifdef FREERTOS_WINSIM\n    #define FREERTOS\n    #define USE_WINDOWS_API\n#endif\n\n\n#ifdef WOLFSSL_VXWORKS\n    /* VxWorks simulator incorrectly detects building for i386 */\n    #ifdef VXWORKS_SIM\n        #define TFM_NO_ASM\n    #endif\n    /* For VxWorks pthreads wrappers for mutexes uncomment the next line. */\n    /* #define WOLFSSL_PTHREADS */\n    #define WOLFSSL_HAVE_MIN\n    #define WOLFSSL_HAVE_MAX\n    #define USE_FAST_MATH\n    #define TFM_TIMING_RESISTANT\n    #define NO_MAIN_DRIVER\n    #define NO_DEV_RANDOM\n    #define NO_WRITEV\n#endif\n\n\n#ifdef WOLFSSL_ARDUINO\n    #define NO_WRITEV\n    #define NO_WOLFSSL_DIR\n    #define SINGLE_THREADED\n    #define NO_DEV_RANDOM\n    #ifndef INTEL_GALILEO /* Galileo has time.h compatibility */\n        #define TIME_OVERRIDES\n        #ifndef XTIME\n            #error \"Must define XTIME externally see porting guide\"\n            #error \"https://www.wolfssl.com/docs/porting-guide/\"\n        #endif\n        #ifndef XGMTIME\n            #error \"Must define XGMTIME externally see porting guide\"\n            #error \"https://www.wolfssl.com/docs/porting-guide/\"\n        #endif\n    #endif\n    #define WOLFSSL_USER_IO\n    #define HAVE_ECC\n    #define NO_DH\n    #define NO_SESSION_CACHE\n#endif\n\n\n#ifdef WOLFSSL_UTASKER\n    /* uTasker configuration - used for fnRandom() */\n    #include \"config.h\"\n\n    #define SINGLE_THREADED\n    #define NO_WOLFSSL_DIR\n    #define WOLFSSL_HAVE_MIN\n    #define NO_WRITEV\n\n    #define HAVE_ECC\n    #define ALT_ECC_SIZE\n    #define USE_FAST_MATH\n    #define TFM_TIMING_RESISTANT\n    #define ECC_TIMING_RESISTANT\n\n    /* used in wolfCrypt test */\n    #define NO_MAIN_DRIVER\n    #define USE_CERT_BUFFERS_2048\n\n    /* uTasker port uses RAW sockets, use I/O callbacks\n     * See wolfSSL uTasker example for sample callbacks */\n    #define WOLFSSL_USER_IO\n\n    /* uTasker filesystem not ported  */\n    #define NO_FILESYSTEM\n\n    /* uTasker RNG is abstracted, calls HW RNG when available */\n    #define CUSTOM_RAND_GENERATE    fnRandom\n    #define CUSTOM_RAND_TYPE        unsigned short\n\n    /* user needs to define XTIME to function that provides\n     * seconds since Unix epoch */\n    #ifndef XTIME\n        #error XTIME must be defined in wolfSSL settings.h\n        /* #define XTIME fnSecondsSinceEpoch */\n    #endif\n\n    /* use uTasker std library replacements where available */\n    #define STRING_USER\n    #define XMEMCPY(d,s,l)         uMemcpy((d),(s),(l))\n    #define XMEMSET(b,c,l)         uMemset((b),(c),(l))\n    #define XMEMCMP(s1,s2,n)       uMemcmp((s1),(s2),(n))\n    #define XMEMMOVE(d,s,l)        memmove((d),(s),(l))\n\n    #define XSTRLEN(s1)            uStrlen((s1))\n    #define XSTRNCPY(s1,s2,n)      strncpy((s1),(s2),(n))\n    #define XSTRSTR(s1,s2)         strstr((s1),(s2))\n    #define XSTRNSTR(s1,s2,n)      mystrnstr((s1),(s2),(n))\n    #define XSTRNCMP(s1,s2,n)      strncmp((s1),(s2),(n))\n    #define XSTRNCAT(s1,s2,n)      strncat((s1),(s2),(n))\n    #define XSTRNCASECMP(s1,s2,n)  _strnicmp((s1),(s2),(n))\n    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) \\\n            || defined(HAVE_ALPN)\n        #define XSTRTOK            strtok_r\n    #endif\n#endif\n\n#ifdef WOLFSSL_EMBOS\n    #define NO_FILESYSTEM           /* Not ported at this time */\n    #define USE_CERT_BUFFERS_2048   /* use when NO_FILESYSTEM */\n    #define NO_MAIN_DRIVER\n    #define NO_RC4\n    #define SINGLE_THREADED         /* Not ported at this time */\n#endif\n\n#ifdef WOLFSSL_RIOT_OS\n    #define NO_WRITEV\n    #define TFM_NO_ASM\n    #define NO_FILESYSTEM\n    #define USE_CERT_BUFFERS_2048\n    #if defined(WOLFSSL_GNRC) && !defined(WOLFSSL_DTLS)\n        #define WOLFSSL_DTLS\n    #endif\n#endif\n\n#ifdef WOLFSSL_CHIBIOS\n    /* ChibiOS definitions. This file is distributed with chibiOS. */\n    #include \"wolfssl_chibios.h\"\n#endif\n\n#ifdef WOLFSSL_PB\n    /* PB is using older 1.2 version of Nucleus */\n    #undef WOLFSSL_NUCLEUS\n    #define WOLFSSL_NUCLEUS_1_2\n#endif\n\n#ifdef WOLFSSL_NUCLEUS_1_2\n    #define NO_WRITEV\n    #define NO_WOLFSSL_DIR\n\n    #if !defined(NO_ASN_TIME) && !defined(USER_TIME)\n        #error User must define XTIME, see manual\n    #endif\n\n    #if !defined(XMALLOC_OVERRIDE) && !defined(XMALLOC_USER)\n        extern void* nucleus_malloc(unsigned long size, void* heap, int type);\n        extern void* nucleus_realloc(void* ptr, unsigned long size, void* heap,\n                                     int type);\n        extern void  nucleus_free(void* ptr, void* heap, int type);\n\n        #define XMALLOC(s, h, type)  nucleus_malloc((s), (h), (type))\n        #define XREALLOC(p, n, h, t) nucleus_realloc((p), (n), (h), (t))\n        #define XFREE(p, h, type)    nucleus_free((p), (h), (type))\n    #endif\n#endif\n\n#ifdef WOLFSSL_NRF5x\n        #define SIZEOF_LONG 4\n        #define SIZEOF_LONG_LONG 8\n        #define NO_ASN_TIME\n        #define NO_DEV_RANDOM\n        #define NO_FILESYSTEM\n        #define NO_MAIN_DRIVER\n        #define NO_WRITEV\n        #define SINGLE_THREADED\n        #define USE_FAST_MATH\n        #define TFM_TIMING_RESISTANT\n        #define USE_WOLFSSL_MEMORY\n        #define WOLFSSL_NRF51\n        #define WOLFSSL_USER_IO\n        #define NO_SESSION_CACHE\n#endif\n\n/* Micrium will use Visual Studio for compilation but not the Win32 API */\n#if defined(_WIN32) && !defined(MICRIUM) && !defined(FREERTOS) && \\\n    !defined(FREERTOS_TCP) && !defined(EBSNET) && !defined(WOLFSSL_EROAD) && \\\n    !defined(WOLFSSL_UTASKER) && !defined(INTIME_RTOS)\n    #define USE_WINDOWS_API\n#endif\n\n#if defined(WOLFSSL_uITRON4)\n\n#define XMALLOC_USER\n#include <stddef.h>\n#define ITRON_POOL_SIZE 1024*20\nextern int uITRON4_minit(size_t poolsz) ;\nextern void *uITRON4_malloc(size_t sz) ;\nextern void *uITRON4_realloc(void *p, size_t sz) ;\nextern void uITRON4_free(void *p) ;\n\n#define XMALLOC(sz, heap, type)     uITRON4_malloc(sz)\n#define XREALLOC(p, sz, heap, type) uITRON4_realloc(p, sz)\n#define XFREE(p, heap, type)        uITRON4_free(p)\n#endif\n\n#if defined(WOLFSSL_uTKERNEL2)\n  #ifndef NO_TKERNEL_MEM_POOL\n    #define XMALLOC_OVERRIDE\n    int   uTKernel_init_mpool(unsigned int sz); /* initializing malloc pool */\n    void* uTKernel_malloc(unsigned int sz);\n    void* uTKernel_realloc(void *p, unsigned int sz);\n    void  uTKernel_free(void *p);\n    #define XMALLOC(s, h, type)  uTKernel_malloc((s))\n    #define XREALLOC(p, n, h, t) uTKernel_realloc((p), (n))\n    #define XFREE(p, h, type)    uTKernel_free((p))\n  #endif\n\n  #ifndef NO_STDIO_FGETS_REMAP\n    #include <stdio.h>\n    #include \"tm/tmonitor.h\"\n\n    /* static char* gets(char *buff); */\n    static char* fgets(char *buff, int sz, XFILE fp) {\n        char * p = buff;\n        *p = '\\0';\n        while (1) {\n            *p = tm_getchar(-1);\n            tm_putchar(*p);\n            if (*p == '\\r') {\n                tm_putchar('\\n');\n                *p = '\\0';\n                break;\n            }\n            p++;\n        }\n        return buff;\n    }\n  #endif /* !NO_STDIO_FGETS_REMAP */\n#endif\n\n\n#if defined(WOLFSSL_LEANPSK) && !defined(XMALLOC_USER) && \\\n        !defined(NO_WOLFSSL_MEMORY)\n    #include <stdlib.h>\n    #define XMALLOC(s, h, type)  malloc((s))\n    #define XFREE(p, h, type)    free((p))\n    #define XREALLOC(p, n, h, t) realloc((p), (n))\n#endif\n\n#if defined(XMALLOC_USER) && defined(SSN_BUILDING_LIBYASSL)\n    #undef  XMALLOC\n    #define XMALLOC     yaXMALLOC\n    #undef  XFREE\n    #define XFREE       yaXFREE\n    #undef  XREALLOC\n    #define XREALLOC    yaXREALLOC\n#endif\n\n\n#ifdef FREERTOS\n    #include \"FreeRTOS.h\"\n\n    /* FreeRTOS pvPortRealloc() only in AVR32_UC3 port */\n    #if !defined(XMALLOC_USER) && !defined(NO_WOLFSSL_MEMORY) && \\\n        !defined(WOLFSSL_STATIC_MEMORY)\n        #define XMALLOC(s, h, type)  pvPortMalloc((s))\n        #define XFREE(p, h, type)    vPortFree((p))\n    #endif\n    #if defined(HAVE_ED25519) || defined(WOLFSSL_ESPIDF)\n        #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n))\n    #endif\n    #ifndef NO_WRITEV\n        #define NO_WRITEV\n    #endif\n    #ifndef HAVE_SHA512\n        #ifndef NO_SHA512\n            #define NO_SHA512\n        #endif\n    #endif\n    #ifndef HAVE_DH\n        #ifndef NO_DH\n            #define NO_DH\n        #endif\n    #endif\n    #ifndef NO_DSA\n        #define NO_DSA\n    #endif\n    #ifndef NO_HC128\n        #define NO_HC128\n    #endif\n\n    #ifndef SINGLE_THREADED\n        #include \"semphr.h\"\n    #endif\n#endif\n\n#ifdef FREERTOS_TCP\n    #if !defined(NO_WOLFSSL_MEMORY) && !defined(XMALLOC_USER) && \\\n        !defined(WOLFSSL_STATIC_MEMORY)\n        #define XMALLOC(s, h, type)  pvPortMalloc((s))\n        #define XFREE(p, h, type)    vPortFree((p))\n    #endif\n\n    #define WOLFSSL_GENSEED_FORTEST\n\n    #define NO_WOLFSSL_DIR\n    #define NO_WRITEV\n    #define USE_FAST_MATH\n    #define TFM_TIMING_RESISTANT\n    #define NO_MAIN_DRIVER\n#endif\n\n#ifdef WOLFSSL_TIRTOS\n    #define SIZEOF_LONG_LONG 8\n    #define NO_WRITEV\n    #define NO_WOLFSSL_DIR\n    #define USE_FAST_MATH\n    #define TFM_TIMING_RESISTANT\n    #define ECC_TIMING_RESISTANT\n    #define WC_RSA_BLINDING\n    #define NO_DEV_RANDOM\n    #define NO_FILESYSTEM\n    #define USE_CERT_BUFFERS_2048\n    #define NO_ERROR_STRINGS\n    /* Uncomment this setting if your toolchain does not offer time.h header */\n    /* #define USER_TIME */\n    #define HAVE_ECC\n    #define HAVE_ALPN\n    #define USE_WOLF_STRTOK /* use with HAVE_ALPN */\n    #define HAVE_TLS_EXTENSIONS\n    #define HAVE_AESGCM\n    #ifdef WOLFSSL_TI_CRYPT\n        #define NO_GCM_ENCRYPT_EXTRA\n        #define NO_PUBLIC_GCM_SET_IV\n        #define NO_PUBLIC_CCM_SET_NONCE\n    #endif\n    #define HAVE_SUPPORTED_CURVES\n    #define ALT_ECC_SIZE\n\n    #ifdef __IAR_SYSTEMS_ICC__\n        #pragma diag_suppress=Pa089\n    #elif !defined(__GNUC__)\n        /* Suppress the sslpro warning */\n        #pragma diag_suppress=11\n    #endif\n\n    #include <ti/sysbios/hal/Seconds.h>\n#endif\n\n#ifdef EBSNET\n    #include \"rtip.h\"\n\n    /* #define DEBUG_WOLFSSL */\n    #define NO_WOLFSSL_DIR  /* tbd */\n\n    #if (POLLOS)\n        #define SINGLE_THREADED\n    #endif\n\n    #if (RTPLATFORM)\n        #if (!RTP_LITTLE_ENDIAN)\n            #define BIG_ENDIAN_ORDER\n        #endif\n    #else\n        #if (!KS_LITTLE_ENDIAN)\n            #define BIG_ENDIAN_ORDER\n        #endif\n    #endif\n\n    #if (WINMSP3)\n        #undef SIZEOF_LONG\n        #define SIZEOF_LONG_LONG 8\n    #else\n        #error settings.h - please implement SIZEOF_LONG and SIZEOF_LONG_LONG\n    #endif\n\n    #define XMALLOC(s, h, type) ((void *)rtp_malloc((s), SSL_PRO_MALLOC))\n    #define XFREE(p, h, type) (rtp_free(p))\n    #define XREALLOC(p, n, h, t) (rtp_realloc((p), (n)))\n\n    #if (WINMSP3)\n        #define XSTRNCASECMP(s1,s2,n)  _strnicmp((s1),(s2),(n))\n    #else\n        #sslpro: settings.h - please implement XSTRNCASECMP - needed for HAVE_ECC\n    #endif\n\n    #define WOLFSSL_HAVE_MAX\n    #define WOLFSSL_HAVE_MIN\n\n    #define USE_FAST_MATH\n    #define TFM_TIMING_RESISTANT\n    #define WC_RSA_BLINDING\n    #define ECC_TIMING_RESISTANT\n\n    #define HAVE_ECC\n\n#endif /* EBSNET */\n\n#ifdef WOLFSSL_GAME_BUILD\n    #define SIZEOF_LONG_LONG 8\n    #if defined(__PPU) || defined(__XENON)\n        #define BIG_ENDIAN_ORDER\n    #endif\n#endif\n\n#ifdef WOLFSSL_LSR\n    #define HAVE_WEBSERVER\n    #define SIZEOF_LONG_LONG 8\n    #define WOLFSSL_LOW_MEMORY\n    #define NO_WRITEV\n    #define NO_SHA512\n    #define NO_DH\n    /* Allows use of DH with fixed points if uncommented and NO_DH is removed */\n    /* WOLFSSL_DH_CONST */\n    #define NO_DSA\n    #define NO_HC128\n    #define NO_DEV_RANDOM\n    #define NO_WOLFSSL_DIR\n    #define NO_RABBIT\n    #ifndef NO_FILESYSTEM\n        #define LSR_FS\n        #include \"inc/hw_types.h\"\n        #include \"fs.h\"\n    #endif\n    #define WOLFSSL_LWIP\n    #include <errno.h>  /* for tcp errno */\n    #define WOLFSSL_SAFERTOS\n    #if defined(__IAR_SYSTEMS_ICC__)\n        /* enum uses enum */\n        #pragma diag_suppress=Pa089\n    #endif\n#endif\n\n#ifdef WOLFSSL_SAFERTOS\n    #ifndef SINGLE_THREADED\n        #include \"SafeRTOS/semphr.h\"\n    #endif\n    #ifndef WOLFSSL_NO_MALLOC\n        #include \"SafeRTOS/heap.h\"\n    #endif\n    #if !defined(XMALLOC_USER) && !defined(NO_WOLFSSL_MEMORY) && \\\n        !defined(WOLFSSL_STATIC_MEMORY)\n        #define XMALLOC(s, h, type)  pvPortMalloc((s))\n        #define XFREE(p, h, type)    vPortFree((p))\n    #endif\n    #if !defined(USE_FAST_MATH) || defined(HAVE_ED25519)\n        #define XREALLOC(p, n, h, t) pvPortRealloc((p), (n))\n    #endif\n#endif\n\n#ifdef WOLFSSL_LOW_MEMORY\n    #undef  RSA_LOW_MEM\n    #define RSA_LOW_MEM\n    #undef  WOLFSSL_SMALL_STACK\n    #define WOLFSSL_SMALL_STACK\n    #undef  TFM_TIMING_RESISTANT\n    #define TFM_TIMING_RESISTANT\n#endif\n\n#ifdef FREESCALE_MQX_5_0\n    /* use normal Freescale MQX port, but with minor changes for 5.0 */\n    #define FREESCALE_MQX\n#endif\n\n#ifdef FREESCALE_MQX_4_0\n    /* use normal Freescale MQX port, but with minor changes for 4.0 */\n    #define FREESCALE_MQX\n#endif\n\n#ifdef FREESCALE_MQX\n    #define FREESCALE_COMMON\n    #include \"mqx.h\"\n    #ifndef NO_FILESYSTEM\n        #include \"mfs.h\"\n        #if (defined(MQX_USE_IO_OLD) && MQX_USE_IO_OLD) || \\\n            defined(FREESCALE_MQX_5_0)\n            #include \"fio.h\"\n            #define NO_STDIO_FILESYSTEM\n        #else\n            #include \"nio.h\"\n        #endif\n    #endif\n    #ifndef SINGLE_THREADED\n        #include \"mutex.h\"\n    #endif\n\n    #if !defined(XMALLOC_OVERRIDE) && !defined(XMALLOC_USER)\n        #define XMALLOC_OVERRIDE\n        #define XMALLOC(s, h, t)    (void *)_mem_alloc_system((s))\n        #define XFREE(p, h, t)      {void* xp = (p); if ((xp)) _mem_free((xp));}\n        /* Note: MQX has no realloc, using fastmath above */\n    #endif\n#endif\n\n#ifdef FREESCALE_KSDK_MQX\n    #define FREESCALE_COMMON\n    #include <mqx.h>\n    #ifndef NO_FILESYSTEM\n        #if (defined(MQX_USE_IO_OLD) && MQX_USE_IO_OLD) || \\\n            defined(FREESCALE_MQX_5_0)\n            #include <fio.h>\n        #else\n            #include <stdio.h>\n            #include <nio.h>\n        #endif\n    #endif\n    #ifndef SINGLE_THREADED\n        #include <mutex.h>\n    #endif\n\n    #define XMALLOC(s, h, t)    (void *)_mem_alloc_system((s))\n    #define XFREE(p, h, t)      {void* xp = (p); if ((xp)) _mem_free((xp));}\n    #define XREALLOC(p, n, h, t) _mem_realloc((p), (n)) /* since MQX 4.1.2 */\n\n    #define MQX_FILE_PTR FILE *\n    #define IO_SEEK_SET  SEEK_SET\n    #define IO_SEEK_END  SEEK_END\n#endif /* FREESCALE_KSDK_MQX */\n\n#if defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS)\n    #define NO_FILESYSTEM\n    #define WOLFSSL_CRYPT_HW_MUTEX 1\n\n    #if !defined(XMALLOC_USER) && !defined(NO_WOLFSSL_MEMORY)\n        #define XMALLOC(s, h, type)  pvPortMalloc((s))\n        #define XFREE(p, h, type)    vPortFree((p))\n    #endif\n\n    //#define USER_TICKS\n    /* Allows use of DH with fixed points if uncommented and NO_DH is removed */\n    /* WOLFSSL_DH_CONST */\n    #define WOLFSSL_LWIP\n    #define FREERTOS_TCP\n\n    #define FREESCALE_FREE_RTOS\n    #define FREERTOS_SOCKET_ERROR ( -1 )\n    #define FREERTOS_EWOULDBLOCK ( -2 )\n    #define FREERTOS_EINVAL ( -4 )\n    #define FREERTOS_EADDRNOTAVAIL ( -5 )\n    #define FREERTOS_EADDRINUSE ( -6 )\n    #define FREERTOS_ENOBUFS ( -7 )\n    #define FREERTOS_ENOPROTOOPT ( -8 )\n#endif /* FREESCALE_FREE_RTOS || FREESCALE_KSDK_FREERTOS */\n\n#ifdef FREESCALE_KSDK_BM\n    #define FREESCALE_COMMON\n    #define WOLFSSL_USER_IO\n    #define SINGLE_THREADED\n    #define NO_FILESYSTEM\n    #ifndef TIME_OVERRIDES\n        #define USER_TICKS\n    #endif\n#endif /* FREESCALE_KSDK_BM */\n\n#ifdef FREESCALE_COMMON\n    #define SIZEOF_LONG_LONG 8\n\n    /* disable features */\n    #undef  NO_WRITEV\n    #define NO_WRITEV\n    #undef  NO_DEV_RANDOM\n    #define NO_DEV_RANDOM\n    #undef  NO_RABBIT\n    #define NO_RABBIT\n    #undef  NO_WOLFSSL_DIR\n    #define NO_WOLFSSL_DIR\n    #undef  NO_RC4\n    #define NO_RC4\n\n    /* enable features */\n    #undef  USE_FAST_MATH\n    #define USE_FAST_MATH\n\n    #define USE_CERT_BUFFERS_2048\n    #define BENCH_EMBEDDED\n\n    #define TFM_TIMING_RESISTANT\n    #define ECC_TIMING_RESISTANT\n\n    #undef  HAVE_ECC\n    #define HAVE_ECC\n    #ifndef NO_AES\n        #undef  HAVE_AESCCM\n        #define HAVE_AESCCM\n        #undef  HAVE_AESGCM\n        #define HAVE_AESGCM\n        #undef  WOLFSSL_AES_COUNTER\n        #define WOLFSSL_AES_COUNTER\n        #undef  WOLFSSL_AES_DIRECT\n        #define WOLFSSL_AES_DIRECT\n    #endif\n\n    #ifdef FREESCALE_KSDK_1_3\n        #include \"fsl_device_registers.h\"\n    #elif !defined(FREESCALE_MQX)\n        /* Classic MQX does not have fsl_common.h */\n        #include \"fsl_common.h\"\n    #endif\n\n    /* random seed */\n    #define NO_OLD_RNGNAME\n    #if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0)\n        #define FREESCALE_KSDK_2_0_TRNG\n    #elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0)\n        #ifdef FREESCALE_KSDK_1_3\n            #include \"fsl_rnga_driver.h\"\n            #define FREESCALE_RNGA\n            #define RNGA_INSTANCE (0)\n        #else\n            #define FREESCALE_KSDK_2_0_RNGA\n        #endif\n    #elif !defined(FREESCALE_KSDK_BM) && !defined(FREESCALE_FREE_RTOS) && !defined(FREESCALE_KSDK_FREERTOS)\n        #define FREESCALE_RNGA\n        #define RNGA_INSTANCE (0)\n        /* defaulting to K70 RNGA, user should change if different */\n        /* #define FREESCALE_K53_RNGB */\n        #define FREESCALE_K70_RNGA\n    #endif\n\n    /* HW crypto */\n    /* automatic enable based on Kinetis feature */\n    /* if case manual selection is required, for example for benchmarking purposes,\n     * just define FREESCALE_USE_MMCAU or FREESCALE_USE_LTC or none of these two macros (for software only)\n     * both can be enabled simultaneously as LTC has priority over MMCAU in source code.\n     */\n    /* #define FSL_HW_CRYPTO_MANUAL_SELECTION */\n    #ifndef FSL_HW_CRYPTO_MANUAL_SELECTION\n        #if defined(FSL_FEATURE_SOC_MMCAU_COUNT) && FSL_FEATURE_SOC_MMCAU_COUNT\n            #define FREESCALE_USE_MMCAU\n        #endif\n\n        #if defined(FSL_FEATURE_SOC_LTC_COUNT) && FSL_FEATURE_SOC_LTC_COUNT\n            #define FREESCALE_USE_LTC\n        #endif\n    #else\n        /* #define FREESCALE_USE_MMCAU */\n        /* #define FREESCALE_USE_LTC */\n    #endif\n#endif /* FREESCALE_COMMON */\n\n/* Classic pre-KSDK mmCAU library */\n#ifdef FREESCALE_USE_MMCAU_CLASSIC\n    #define FREESCALE_USE_MMCAU\n    #define FREESCALE_MMCAU_CLASSIC\n    #define FREESCALE_MMCAU_CLASSIC_SHA\n#endif\n\n/* KSDK mmCAU library */\n#ifdef FREESCALE_USE_MMCAU\n    /* AES and DES */\n    #define FREESCALE_MMCAU\n    /* MD5, SHA-1 and SHA-256 */\n    #define FREESCALE_MMCAU_SHA\n#endif /* FREESCALE_USE_MMCAU */\n\n#ifdef FREESCALE_USE_LTC\n    #if defined(FSL_FEATURE_SOC_LTC_COUNT) && FSL_FEATURE_SOC_LTC_COUNT\n        #define FREESCALE_LTC\n        #define LTC_BASE LTC0\n\n        #if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES\n            #define FREESCALE_LTC_DES\n        #endif\n\n        #if defined(FSL_FEATURE_LTC_HAS_GCM) && FSL_FEATURE_LTC_HAS_GCM\n            #define FREESCALE_LTC_AES_GCM\n        #endif\n\n        #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA\n            #define FREESCALE_LTC_SHA\n        #endif\n\n        #if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA\n            #define FREESCALE_LTC_ECC\n            #define FREESCALE_LTC_TFM\n\n            /* the LTC PKHA hardware limit is 2048 bits (256 bytes) for integer arithmetic.\n               the LTC_MAX_INT_BYTES defines the size of local variables that hold big integers. */\n            #ifndef LTC_MAX_INT_BYTES\n                #define LTC_MAX_INT_BYTES (256)\n            #endif\n\n            /* This FREESCALE_LTC_TFM_RSA_4096_ENABLE macro can be defined.\n             * In such a case both software and hardware algorithm\n             * for TFM is linked in. The decision for which algorithm is used is determined at runtime\n             * from size of inputs. If inputs and result can fit into LTC (see LTC_MAX_INT_BYTES)\n             * then we call hardware algorithm, otherwise we call software algorithm.\n             *\n             * Chinese reminder theorem is used to break RSA 4096 exponentiations (both public and private key)\n             * into several computations with 2048-bit modulus and exponents.\n             */\n            /* #define FREESCALE_LTC_TFM_RSA_4096_ENABLE */\n\n            /* ECC-384, ECC-256, ECC-224 and ECC-192 have been enabled with LTC PKHA acceleration */\n            #ifdef HAVE_ECC\n                #undef  ECC_TIMING_RESISTANT\n                #define ECC_TIMING_RESISTANT\n\n                /* the LTC PKHA hardware limit is 512 bits (64 bytes) for ECC.\n                   the LTC_MAX_ECC_BITS defines the size of local variables that hold ECC parameters\n                   and point coordinates */\n                #ifndef LTC_MAX_ECC_BITS\n                    #define LTC_MAX_ECC_BITS (384)\n                #endif\n\n                /* Enable curves up to 384 bits */\n                #if !defined(ECC_USER_CURVES) && !defined(HAVE_ALL_CURVES)\n                    #define ECC_USER_CURVES\n                    #define HAVE_ECC192\n                    #define HAVE_ECC224\n                    #undef  NO_ECC256\n                    #define HAVE_ECC384\n                #endif\n            #endif\n        #endif\n    #endif\n#endif /* FREESCALE_USE_LTC */\n\n#ifdef FREESCALE_LTC_TFM_RSA_4096_ENABLE\n    #undef  USE_CERT_BUFFERS_4096\n    #define USE_CERT_BUFFERS_4096\n    #undef  FP_MAX_BITS\n    #define FP_MAX_BITS (8192)\n\n    #undef  NO_DH\n    #define NO_DH\n    #undef  NO_DSA\n    #define NO_DSA\n#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */\n\n/* if LTC has AES engine but doesn't have GCM, use software with LTC AES ECB mode */\n#if defined(FREESCALE_USE_LTC) && !defined(FREESCALE_LTC_AES_GCM)\n    #define GCM_TABLE\n#endif\n\n#if defined(WOLFSSL_STM32F2) || defined(WOLFSSL_STM32F4) || \\\n    defined(WOLFSSL_STM32F7) || defined(WOLFSSL_STM32F1) || \\\n    defined(WOLFSSL_STM32L4)\n\n    #define SIZEOF_LONG_LONG 8\n    #ifndef CHAR_BIT\n      #define CHAR_BIT 8\n    #endif\n    #define NO_DEV_RANDOM\n    #define NO_WOLFSSL_DIR\n    #undef  NO_RABBIT\n    #define NO_RABBIT\n    #ifndef NO_STM32_RNG\n        #undef  STM32_RNG\n        #define STM32_RNG\n        #ifdef WOLFSSL_STM32F427_RNG\n            #include \"stm32f427xx.h\"\n        #endif\n    #endif\n    #ifndef NO_STM32_CRYPTO\n        #undef  STM32_CRYPTO\n        #define STM32_CRYPTO\n\n        #ifdef WOLFSSL_STM32L4\n            #define NO_AES_192 /* hardware does not support 192-bit */\n        #endif\n    #endif\n    #ifndef NO_STM32_HASH\n        #undef  STM32_HASH\n        #define STM32_HASH\n    #endif\n    #if !defined(__GNUC__) && !defined(__ICCARM__)\n        #define KEIL_INTRINSICS\n    #endif\n    #define NO_OLD_RNGNAME\n    #ifdef WOLFSSL_STM32_CUBEMX\n        #if defined(WOLFSSL_STM32F2)\n            #include \"stm32f2xx_hal.h\"\n        #elif defined(WOLFSSL_STM32L4)\n            #include \"stm32l4xx_hal.h\"\n        #elif defined(WOLFSSL_STM32F4)\n            #include \"stm32f4xx_hal.h\"\n        #elif defined(WOLFSSL_STM32F7)\n            #include \"stm32f7xx_hal.h\"\n        #elif defined(WOLFSSL_STM32F1)\n            #include \"stm32f1xx_hal.h\"\n        #endif\n        #if defined(WOLFSSL_CUBEMX_USE_LL) && defined(WOLFSSL_STM32L4)\n            #include \"stm32l4xx_ll_rng.h\"\n        #endif\n\n        #ifndef STM32_HAL_TIMEOUT\n            #define STM32_HAL_TIMEOUT   0xFF\n        #endif\n    #else\n        #if defined(WOLFSSL_STM32F2)\n            #include \"stm32f2xx.h\"\n            #ifdef STM32_CRYPTO\n                #include \"stm32f2xx_cryp.h\"\n            #endif\n            #ifdef STM32_HASH\n                #include \"stm32f2xx_hash.h\"\n            #endif\n        #elif defined(WOLFSSL_STM32F4)\n            #include \"stm32f4xx.h\"\n            #ifdef STM32_CRYPTO\n                #include \"stm32f4xx_cryp.h\"\n            #endif\n            #ifdef STM32_HASH\n                #include \"stm32f4xx_hash.h\"\n            #endif\n        #elif defined(WOLFSSL_STM32L4)\n            #include \"stm32l4xx.h\"\n            #ifdef STM32_CRYPTO\n                #include \"stm32l4xx_cryp.h\"\n            #endif\n            #ifdef STM32_HASH\n                #include \"stm32l4xx_hash.h\"\n            #endif\n        #elif defined(WOLFSSL_STM32F7)\n            #include \"stm32f7xx.h\"\n        #elif defined(WOLFSSL_STM32F1)\n            #include \"stm32f1xx.h\"\n        #endif\n    #endif /* WOLFSSL_STM32_CUBEMX */\n#endif /* WOLFSSL_STM32F2 || WOLFSSL_STM32F4 || WOLFSSL_STM32L4 || WOLFSSL_STM32F7 */\n#ifdef WOLFSSL_DEOS\n    #include <deos.h>\n    #include <timeout.h>\n    #include <socketapi.h>\n    #include <lwip-socket.h>\n    #include <mem.h>\n    #include <string.h>\n    #include <stdlib.h> /* for rand_r: pseudo-random number generator */\n    #include <stdio.h>  /* for snprintf */\n\n    /* use external memory XMALLOC, XFREE and XREALLOC functions */\n    #define XMALLOC_USER\n\n    /* disable fall-back case, malloc, realloc and free are unavailable */\n    #define WOLFSSL_NO_MALLOC\n\n    /* file sytem has not been ported since it is a seperate product. */\n\n    #define NO_FILESYSTEM\n\n    #ifdef NO_FILESYSTEM\n        #define NO_WOLFSSL_DIR\n        #define NO_WRITEV\n    #endif\n\n    #define USE_FAST_MATH\n    #define TFM_TIMING_RESISTANT\n    #define ECC_TIMING_RESISTANT\n    #define WC_RSA_BLINDING\n\n    #define HAVE_ECC\n    #define ALT_ECC_SIZE\n    #define TFM_ECC192\n    #define TFM_ECC224\n    #define TFM_ECC256\n    #define TFM_ECC384\n    #define TFM_ECC521\n\n    #define HAVE_TLS_EXTENSIONS\n    #define HAVE_SUPPORTED_CURVES\n    #define HAVE_EXTENDED_MASTER\n\n    #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)\n        #define BIG_ENDIAN_ORDER\n    #else\n        #undef  BIG_ENDIAN_ORDER\n        #define LITTLE_ENDIAN_ORDER\n    #endif\n#endif /* WOLFSSL_DEOS*/\n\n#ifdef MICRIUM\n    #include <stdlib.h>\n    #include <os.h>\n    #include <net_cfg.h>\n    #include <net_sock.h>\n    #include <net_err.h>\n    #include <lib_mem.h>\n    #include <lib_math.h>\n\n    #define USE_FAST_MATH\n    #define TFM_TIMING_RESISTANT\n    #define ECC_TIMING_RESISTANT\n    #define WC_RSA_BLINDING\n    #define HAVE_HASHDRBG\n\n    #define HAVE_ECC\n    #define ALT_ECC_SIZE\n    #define TFM_ECC192\n    #define TFM_ECC224\n    #define TFM_ECC256\n    #define TFM_ECC384\n    #define TFM_ECC521\n\n    #define NO_RC4\n    #define HAVE_TLS_EXTENSIONS\n    #define HAVE_SUPPORTED_CURVES\n    #define HAVE_EXTENDED_MASTER\n\n    #define NO_WOLFSSL_DIR\n    #define NO_WRITEV\n\n    #ifndef CUSTOM_RAND_GENERATE\n        #define CUSTOM_RAND_TYPE     RAND_NBR\n        #define CUSTOM_RAND_GENERATE Math_Rand\n    #endif\n    #define STRING_USER\n    #define XSTRLEN(pstr) ((CPU_SIZE_T)Str_Len((CPU_CHAR *)(pstr)))\n    #define XSTRNCPY(pstr_dest, pstr_src, len_max) \\\n                    ((CPU_CHAR *)Str_Copy_N((CPU_CHAR *)(pstr_dest), \\\n                     (CPU_CHAR *)(pstr_src), (CPU_SIZE_T)(len_max)))\n    #define XSTRNCMP(pstr_1, pstr_2, len_max) \\\n                    ((CPU_INT16S)Str_Cmp_N((CPU_CHAR *)(pstr_1), \\\n                     (CPU_CHAR *)(pstr_2), (CPU_SIZE_T)(len_max)))\n    #define XSTRNCASECMP(pstr_1, pstr_2, len_max) \\\n                    ((CPU_INT16S)Str_CmpIgnoreCase_N((CPU_CHAR *)(pstr_1), \\\n                     (CPU_CHAR *)(pstr_2), (CPU_SIZE_T)(len_max)))\n    #define XSTRSTR(pstr, pstr_srch) \\\n                    ((CPU_CHAR *)Str_Str((CPU_CHAR *)(pstr), \\\n                     (CPU_CHAR *)(pstr_srch)))\n    #define XSTRNSTR(pstr, pstr_srch, len_max) \\\n                    ((CPU_CHAR *)Str_Str_N((CPU_CHAR *)(pstr), \\\n                     (CPU_CHAR *)(pstr_srch),(CPU_SIZE_T)(len_max)))\n    #define XSTRNCAT(pstr_dest, pstr_cat, len_max) \\\n                    ((CPU_CHAR *)Str_Cat_N((CPU_CHAR *)(pstr_dest), \\\n                     (const CPU_CHAR *)(pstr_cat),(CPU_SIZE_T)(len_max)))\n    #define XMEMSET(pmem, data_val, size) \\\n                    ((void)Mem_Set((void *)(pmem), \\\n                    (CPU_INT08U) (data_val), \\\n                    (CPU_SIZE_T)(size)))\n    #define XMEMCPY(pdest, psrc, size) ((void)Mem_Copy((void *)(pdest), \\\n                     (void *)(psrc), (CPU_SIZE_T)(size)))\n    #define XMEMCMP(pmem_1, pmem_2, size) \\\n                   (((CPU_BOOLEAN)Mem_Cmp((void *)(pmem_1), \\\n                                          (void *)(pmem_2), \\\n                     (CPU_SIZE_T)(size))) ? DEF_NO : DEF_YES)\n    #define XMEMMOVE XMEMCPY\n\n    #if (OS_CFG_MUTEX_EN == DEF_DISABLED)\n        #define SINGLE_THREADED\n    #endif\n\n    #if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG)\n        #define BIG_ENDIAN_ORDER\n    #else\n        #undef  BIG_ENDIAN_ORDER\n        #define LITTLE_ENDIAN_ORDER\n    #endif\n#endif /* MICRIUM */\n\n#ifdef WOLFSSL_MCF5441X\n    #define BIG_ENDIAN_ORDER\n    #ifndef SIZEOF_LONG\n        #define SIZEOF_LONG 4\n    #endif\n    #ifndef SIZEOF_LONG_LONG\n        #define SIZEOF_LONG_LONG 8\n    #endif\n#endif\n\n#ifdef WOLFSSL_QL\n    #ifndef WOLFSSL_SEP\n        #define WOLFSSL_SEP\n    #endif\n    #ifndef OPENSSL_EXTRA\n        #define OPENSSL_EXTRA\n    #endif\n    #ifndef SESSION_CERTS\n        #define SESSION_CERTS\n    #endif\n    #ifndef HAVE_AESCCM\n        #define HAVE_AESCCM\n    #endif\n    #ifndef ATOMIC_USER\n        #define ATOMIC_USER\n    #endif\n    #ifndef WOLFSSL_DER_LOAD\n        #define WOLFSSL_DER_LOAD\n    #endif\n    #ifndef KEEP_PEER_CERT\n        #define KEEP_PEER_CERT\n    #endif\n    #ifndef HAVE_ECC\n        #define HAVE_ECC\n    #endif\n    #ifndef SESSION_INDEX\n        #define SESSION_INDEX\n    #endif\n#endif /* WOLFSSL_QL */\n\n\n#if defined(WOLFSSL_XILINX)\n    #define NO_WOLFSSL_DIR\n    #define NO_DEV_RANDOM\n    #define HAVE_AESGCM\n#endif\n\n#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_AFALG_XILINX)\n    #if defined(WOLFSSL_ARMASM)\n        #error can not use both ARMv8 instructions and XILINX hardened crypto\n    #endif\n    #if defined(WOLFSSL_SHA3)\n        /* only SHA3-384 is supported */\n        #undef WOLFSSL_NOSHA3_224\n        #undef WOLFSSL_NOSHA3_256\n        #undef WOLFSSL_NOSHA3_512\n        #define WOLFSSL_NOSHA3_224\n        #define WOLFSSL_NOSHA3_256\n        #define WOLFSSL_NOSHA3_512\n    #endif\n    #ifdef WOLFSSL_AFALG_XILINX_AES\n        #undef  WOLFSSL_AES_DIRECT\n        #define WOLFSSL_AES_DIRECT\n    #endif\n#endif /*(WOLFSSL_XILINX_CRYPT)*/\n\n#if defined(WOLFSSL_APACHE_MYNEWT)\n    #include \"os/os_malloc.h\"\n    #if !defined(WOLFSSL_LWIP)\n        #include <mn_socket/mn_socket.h>\n    #endif\n\n    #if !defined(SIZEOF_LONG)\n        #define SIZEOF_LONG 4\n    #endif\n    #if !defined(SIZEOF_LONG_LONG)\n        #define SIZEOF_LONG_LONG 8\n    #endif\n    #if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)\n        #define BIG_ENDIAN_ORDER\n    #else\n        #undef  BIG_ENDIAN_ORDER\n        #define LITTLE_ENDIAN_ORDER\n    #endif\n    #define NO_WRITEV\n    #define WOLFSSL_USER_IO\n    #define SINGLE_THREADED\n    #define NO_DEV_RANDOM\n    #define NO_DH\n    #define NO_WOLFSSL_DIR\n    #define NO_ERROR_STRINGS\n    #define HAVE_ECC\n    #define NO_SESSION_CACHE\n    #define NO_ERROR_STRINGS\n    #define XMALLOC_USER\n    #define XMALLOC(sz, heap, type)     os_malloc(sz)\n    #define XREALLOC(p, sz, heap, type) os_realloc(p, sz)\n    #define XFREE(p, heap, type)        os_free(p)\n\n#endif /*(WOLFSSL_APACHE_MYNEWT)*/\n\n#ifdef WOLFSSL_ZEPHYR\n    #include <zephyr.h>\n    #include <misc/printk.h>\n    #include <misc/util.h>\n    #include <stdlib.h>\n\n    #define WOLFSSL_DH_CONST\n    #define WOLFSSL_HAVE_MIN\n    #define WOLFSSL_HAVE_MAX\n    #define NO_WRITEV\n\n    #define USE_FLAT_BENCHMARK_H\n    #define USE_FLAT_TEST_H\n    #define EXIT_FAILURE 1\n    #define MAIN_NO_ARGS\n\n    void *z_realloc(void *ptr, size_t size);\n    #define realloc   z_realloc\n\n    #define CONFIG_NET_SOCKETS_POSIX_NAMES\n#endif\n\n#ifdef WOLFSSL_IMX6\n    #ifndef SIZEOF_LONG_LONG\n        #define SIZEOF_LONG_LONG 8\n    #endif\n#endif\n\n/* if defined turn on all CAAM support */\n#ifdef WOLFSSL_IMX6_CAAM\n    #undef  WOLFSSL_IMX6_CAAM_RNG\n    #define WOLFSSL_IMX6_CAAM_RNG\n\n    #undef  WOLFSSL_IMX6_CAAM_BLOB\n    #define WOLFSSL_IMX6_CAAM_BLOB\n\n#if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_XTS)\n    /* large performance gain with HAVE_AES_ECB defined */\n    #undef HAVE_AES_ECB\n    #define HAVE_AES_ECB\n#endif\n#endif\n\n#if !defined(XMALLOC_USER) && !defined(MICRIUM_MALLOC) && \\\n    !defined(WOLFSSL_LEANPSK) && !defined(NO_WOLFSSL_MEMORY) && \\\n    !defined(XMALLOC_OVERRIDE)\n    #define USE_WOLFSSL_MEMORY\n#endif\n\n\n#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS)\n    #undef  KEEP_PEER_CERT\n    #define KEEP_PEER_CERT\n#endif\n\n\n/* stream ciphers except arc4 need 32bit alignment, intel ok without */\n#ifndef XSTREAM_ALIGN\n    #if defined(__x86_64__) || defined(__ia64__) || defined(__i386__)\n        #define NO_XSTREAM_ALIGN\n    #else\n        #define XSTREAM_ALIGN\n    #endif\n#endif\n\n/* write dup cannot be used with secure renegotiation because write dup\n * make write side write only and read side read only */\n#if defined(HAVE_WRITE_DUP) && defined(HAVE_SECURE_RENEGOTIATION)\n    #error \"WRITE DUP and SECURE RENEGOTIATION cannot both be on\"\n#endif\n\n#ifdef WOLFSSL_SGX\n    #ifdef _MSC_VER\n        #define NO_RC4\n        #ifndef HAVE_FIPS\n            #define WOLFCRYPT_ONLY\n            #define NO_DES3\n            #define NO_SHA\n            #define NO_MD5\n        #else\n            #define TFM_TIMING_RESISTANT\n            #define NO_WOLFSSL_DIR\n            #define NO_WRITEV\n            #define NO_MAIN_DRIVER\n            #define WOLFSSL_LOG_PRINTF\n            #define WOLFSSL_DH_CONST\n        #endif\n    #else\n        #define HAVE_ECC\n        #define NO_WRITEV\n        #define NO_MAIN_DRIVER\n        #define USER_TICKS\n        #define WOLFSSL_LOG_PRINTF\n        #define WOLFSSL_DH_CONST\n    #endif /* _MSC_VER */\n    #if !defined(HAVE_FIPS) && !defined(NO_RSA)\n        #define WC_RSA_BLINDING\n    #endif\n\n    #define NO_FILESYSTEM\n    #define ECC_TIMING_RESISTANT\n    #define TFM_TIMING_RESISTANT\n    #define SINGLE_THREADED\n    #define NO_ASN_TIME /* can not use headers such as windows.h */\n    #define HAVE_AESGCM\n    #define USE_CERT_BUFFERS_2048\n    #define USE_FAST_MATH\n#endif /* WOLFSSL_SGX */\n\n/* FreeScale MMCAU hardware crypto has 4 byte alignment.\n   However, KSDK fsl_mmcau.h gives API with no alignment\n   requirements (4 byte alignment is managed internally by fsl_mmcau.c) */\n#ifdef FREESCALE_MMCAU\n    #ifdef FREESCALE_MMCAU_CLASSIC\n        #define WOLFSSL_MMCAU_ALIGNMENT 4\n    #else\n        #define WOLFSSL_MMCAU_ALIGNMENT 0\n    #endif\n#endif\n\n/* if using hardware crypto and have alignment requirements, specify the\n   requirement here.  The record header of SSL/TLS will prevent easy alignment.\n   This hint tries to help as much as possible.  */\n#ifndef WOLFSSL_GENERAL_ALIGNMENT\n    #ifdef WOLFSSL_AESNI\n        #define WOLFSSL_GENERAL_ALIGNMENT 16\n    #elif defined(XSTREAM_ALIGN)\n        #define WOLFSSL_GENERAL_ALIGNMENT  4\n    #elif defined(FREESCALE_MMCAU) || defined(FREESCALE_MMCAU_CLASSIC)\n        #define WOLFSSL_GENERAL_ALIGNMENT  WOLFSSL_MMCAU_ALIGNMENT\n    #else\n        #define WOLFSSL_GENERAL_ALIGNMENT  0\n    #endif\n#endif\n\n#if defined(WOLFSSL_GENERAL_ALIGNMENT) && (WOLFSSL_GENERAL_ALIGNMENT > 0)\n    #if defined(_MSC_VER)\n        #define XGEN_ALIGN __declspec(align(WOLFSSL_GENERAL_ALIGNMENT))\n    #elif defined(__GNUC__)\n        #define XGEN_ALIGN __attribute__((aligned(WOLFSSL_GENERAL_ALIGNMENT)))\n    #else\n        #define XGEN_ALIGN\n    #endif\n#else\n    #define XGEN_ALIGN\n#endif\n\n\n#ifdef __INTEL_COMPILER\n    #pragma warning(disable:2259) /* explicit casts to smaller sizes, disable */\n#endif\n\n/* user can specify what curves they want with ECC_USER_CURVES otherwise\n * all curves are on by default for now */\n#ifndef ECC_USER_CURVES\n    #if !defined(WOLFSSL_SP_MATH) && !defined(HAVE_ALL_CURVES)\n        #define HAVE_ALL_CURVES\n    #endif\n#endif\n\n/* ECC Configs */\n#ifdef HAVE_ECC\n    /* By default enable Sign, Verify, DHE, Key Import and Key Export unless explicitly disabled */\n    #ifndef NO_ECC_SIGN\n        #undef HAVE_ECC_SIGN\n        #define HAVE_ECC_SIGN\n    #endif\n    #ifndef NO_ECC_VERIFY\n        #undef HAVE_ECC_VERIFY\n        #define HAVE_ECC_VERIFY\n    #endif\n    #ifndef NO_ECC_CHECK_KEY\n        #undef HAVE_ECC_CHECK_KEY\n        #define HAVE_ECC_CHECK_KEY\n    #endif\n    #ifndef NO_ECC_DHE\n        #undef HAVE_ECC_DHE\n        #define HAVE_ECC_DHE\n    #endif\n    #ifndef NO_ECC_KEY_IMPORT\n        #undef HAVE_ECC_KEY_IMPORT\n        #define HAVE_ECC_KEY_IMPORT\n    #endif\n    #ifndef NO_ECC_KEY_EXPORT\n        #undef HAVE_ECC_KEY_EXPORT\n        #define HAVE_ECC_KEY_EXPORT\n    #endif\n#endif /* HAVE_ECC */\n\n/* Curve255519 Configs */\n#ifdef HAVE_CURVE25519\n    /* By default enable shared secret, key export and import */\n    #ifndef NO_CURVE25519_SHARED_SECRET\n        #undef HAVE_CURVE25519_SHARED_SECRET\n        #define HAVE_CURVE25519_SHARED_SECRET\n    #endif\n    #ifndef NO_CURVE25519_KEY_EXPORT\n        #undef HAVE_CURVE25519_KEY_EXPORT\n        #define HAVE_CURVE25519_KEY_EXPORT\n    #endif\n    #ifndef NO_CURVE25519_KEY_IMPORT\n        #undef HAVE_CURVE25519_KEY_IMPORT\n        #define HAVE_CURVE25519_KEY_IMPORT\n    #endif\n#endif /* HAVE_CURVE25519 */\n\n/* Ed255519 Configs */\n#ifdef HAVE_ED25519\n    /* By default enable sign, verify, key export and import */\n    #ifndef NO_ED25519_SIGN\n        #undef HAVE_ED25519_SIGN\n        #define HAVE_ED25519_SIGN\n    #endif\n    #ifndef NO_ED25519_VERIFY\n        #undef HAVE_ED25519_VERIFY\n        #define HAVE_ED25519_VERIFY\n    #endif\n    #ifndef NO_ED25519_KEY_EXPORT\n        #undef HAVE_ED25519_KEY_EXPORT\n        #define HAVE_ED25519_KEY_EXPORT\n    #endif\n    #ifndef NO_ED25519_KEY_IMPORT\n        #undef HAVE_ED25519_KEY_IMPORT\n        #define HAVE_ED25519_KEY_IMPORT\n    #endif\n#endif /* HAVE_ED25519 */\n\n/* AES Config */\n#ifndef NO_AES\n    /* By default enable all AES key sizes, decryption and CBC */\n    #ifndef AES_MAX_KEY_SIZE\n        #undef  AES_MAX_KEY_SIZE\n        #define AES_MAX_KEY_SIZE    256\n    #endif\n\n    #ifndef NO_AES_128\n        #undef  WOLFSSL_AES_128\n        #define WOLFSSL_AES_128\n    #endif\n    #if !defined(NO_AES_192) && AES_MAX_KEY_SIZE >= 192\n        #undef  WOLFSSL_AES_192\n        #define WOLFSSL_AES_192\n    #endif\n    #if !defined(NO_AES_256) && AES_MAX_KEY_SIZE >= 256\n        #undef  WOLFSSL_AES_256\n        #define WOLFSSL_AES_256\n    #endif\n    #if !defined(WOLFSSL_AES_128) && defined(HAVE_ECC_ENCRYPT)\n        #warning HAVE_ECC_ENCRYPT uses AES 128 bit keys\n     #endif\n\n    #ifndef NO_AES_DECRYPT\n        #undef  HAVE_AES_DECRYPT\n        #define HAVE_AES_DECRYPT\n    #endif\n    #ifndef NO_AES_CBC\n        #undef  HAVE_AES_CBC\n        #define HAVE_AES_CBC\n    #endif\n    #ifdef WOLFSSL_AES_XTS\n        /* AES-XTS makes calls to AES direct functions */\n        #ifndef WOLFSSL_AES_DIRECT\n        #define WOLFSSL_AES_DIRECT\n        #endif\n    #endif\n    #ifdef WOLFSSL_AES_CFB\n        /* AES-CFB makes calls to AES direct functions */\n        #ifndef WOLFSSL_AES_DIRECT\n        #define WOLFSSL_AES_DIRECT\n        #endif\n    #endif\n#endif\n\n#if (defined(WOLFSSL_TLS13) && defined(WOLFSSL_NO_TLS12)) || \\\n    (!defined(HAVE_AES_CBC) && defined(NO_DES3) && defined(NO_RC4) && \\\n     !defined(HAVE_CAMELLIA) && !defined(HAVE_IDEA) && \\\n     !defined(HAVE_NULL_CIPHER) && !defined(HAVE_HC128))\n    #define WOLFSSL_AEAD_ONLY\n#endif\n\n#if !defined(NO_DH) && !defined(HAVE_FFDHE)\n    #if defined(HAVE_FFDHE_2048) || defined(HAVE_FFDHE_3072) || \\\n            defined(HAVE_FFDHE_4096) || defined(HAVE_FFDHE_6144) || \\\n            defined(HAVE_FFDHE_8192)\n        #define HAVE_FFDHE\n    #endif\n#endif\n#if defined(HAVE_FFDHE_8192)\n    #define MIN_FFDHE_FP_MAX_BITS 16384\n#elif defined(HAVE_FFDHE_6144)\n    #define MIN_FFDHE_FP_MAX_BITS 12288\n#elif defined(HAVE_FFDHE_4096)\n    #define MIN_FFDHE_FP_MAX_BITS 8192\n#elif defined(HAVE_FFDHE_3072)\n    #define MIN_FFDHE_FP_MAX_BITS 6144\n#elif defined(HAVE_FFDHE_2048)\n    #define MIN_FFDHE_FP_MAX_BITS 4096\n#else\n    #define MIN_FFDHE_FP_MAX_BITS 0\n#endif\n#if defined(HAVE_FFDHE) && defined(FP_MAX_BITS)\n    #if MIN_FFDHE_FP_MAX_BITS > FP_MAX_BITS\n        #error \"FFDHE parameters are too large for FP_MAX_BIT as set\"\n    #endif\n#endif\n\n/* if desktop type system and fastmath increase default max bits */\n#ifdef WOLFSSL_X86_64_BUILD\n    #if defined(USE_FAST_MATH) && !defined(FP_MAX_BITS)\n        #if MIN_FFDHE_FP_MAX_BITS <= 8192\n            #define FP_MAX_BITS 8192\n        #else\n            #define FP_MAX_BITS MIN_FFDHE_FP_MAX_BITS\n        #endif\n    #endif\n#endif\n\n/* If using the max strength build, ensure OLD TLS is disabled. */\n#ifdef WOLFSSL_MAX_STRENGTH\n    #undef NO_OLD_TLS\n    #define NO_OLD_TLS\n#endif\n\n\n/* Default AES minimum auth tag sz, allow user to override */\n#ifndef WOLFSSL_MIN_AUTH_TAG_SZ\n    #define WOLFSSL_MIN_AUTH_TAG_SZ 12\n#endif\n\n\n/* sniffer requires:\n * static RSA cipher suites\n * session stats and peak stats\n */\n#ifdef WOLFSSL_SNIFFER\n    #ifndef WOLFSSL_STATIC_RSA\n        #define WOLFSSL_STATIC_RSA\n    #endif\n    #ifndef WOLFSSL_STATIC_DH\n        #define WOLFSSL_STATIC_DH\n    #endif\n    /* Allow option to be disabled. */\n    #ifndef WOLFSSL_NO_SESSION_STATS\n        #ifndef WOLFSSL_SESSION_STATS\n            #define WOLFSSL_SESSION_STATS\n        #endif\n        #ifndef WOLFSSL_PEAK_SESSIONS\n            #define WOLFSSL_PEAK_SESSIONS\n        #endif\n    #endif\n#endif\n\n/* Decode Public Key extras on by default, user can turn off with\n * WOLFSSL_NO_DECODE_EXTRA */\n#ifndef WOLFSSL_NO_DECODE_EXTRA\n    #ifndef RSA_DECODE_EXTRA\n        #define RSA_DECODE_EXTRA\n    #endif\n    #ifndef ECC_DECODE_EXTRA\n        #define ECC_DECODE_EXTRA\n    #endif\n#endif\n\n/* C Sharp wrapper defines */\n#ifdef HAVE_CSHARP\n    #ifndef WOLFSSL_DTLS\n        #define WOLFSSL_DTLS\n    #endif\n    #undef NO_PSK\n    #undef NO_SHA256\n    #undef NO_DH\n#endif\n\n/* Asynchronous Crypto */\n#ifdef WOLFSSL_ASYNC_CRYPT\n    /* Make sure wolf events are enabled */\n    #undef HAVE_WOLF_EVENT\n    #define HAVE_WOLF_EVENT\n\n    #ifdef WOLFSSL_ASYNC_CRYPT_TEST\n        #define WC_ASYNC_DEV_SIZE 168\n    #else\n        #define WC_ASYNC_DEV_SIZE 336\n    #endif\n\n    #if !defined(HAVE_CAVIUM) && !defined(HAVE_INTEL_QA) && \\\n        !defined(WOLFSSL_ASYNC_CRYPT_TEST)\n        #error No async hardware defined with WOLFSSL_ASYNC_CRYPT!\n    #endif\n\n    /* Enable ECC_CACHE_CURVE for ASYNC */\n    #if !defined(ECC_CACHE_CURVE)\n        #define ECC_CACHE_CURVE\n    #endif\n#endif /* WOLFSSL_ASYNC_CRYPT */\n#ifndef WC_ASYNC_DEV_SIZE\n    #define WC_ASYNC_DEV_SIZE 0\n#endif\n\n/* leantls checks */\n#ifdef WOLFSSL_LEANTLS\n    #ifndef HAVE_ECC\n        #error leantls build needs ECC\n    #endif\n#endif /* WOLFSSL_LEANTLS*/\n\n/* restriction with static memory */\n#ifdef WOLFSSL_STATIC_MEMORY\n    #if defined(HAVE_IO_POOL) || defined(XMALLOC_USER) || defined(NO_WOLFSSL_MEMORY)\n         #error static memory cannot be used with HAVE_IO_POOL, XMALLOC_USER or NO_WOLFSSL_MEMORY\n    #endif\n    #if !defined(USE_FAST_MATH) && !defined(NO_BIG_INT)\n        #error static memory requires fast math please define USE_FAST_MATH\n    #endif\n    #ifdef WOLFSSL_SMALL_STACK\n        #error static memory does not support small stack please undefine\n    #endif\n#endif /* WOLFSSL_STATIC_MEMORY */\n\n#ifdef HAVE_AES_KEYWRAP\n    #ifndef WOLFSSL_AES_DIRECT\n        #error AES key wrap requires AES direct please define WOLFSSL_AES_DIRECT\n    #endif\n#endif\n\n#ifdef HAVE_PKCS7\n    #if defined(NO_AES) && defined(NO_DES3)\n        #error PKCS7 needs either AES or 3DES enabled, please enable one\n    #endif\n    #ifndef HAVE_AES_KEYWRAP\n        #error PKCS7 requires AES key wrap please define HAVE_AES_KEYWRAP\n    #endif\n    #if defined(HAVE_ECC) && !defined(HAVE_X963_KDF)\n        #error PKCS7 requires X963 KDF please define HAVE_X963_KDF\n    #endif\n#endif\n\n#ifndef NO_PKCS12\n    #undef  HAVE_PKCS12\n    #define HAVE_PKCS12\n#endif\n\n#ifndef NO_PKCS8\n    #undef  HAVE_PKCS8\n    #define HAVE_PKCS8\n#endif\n\n#if !defined(NO_PBKDF1) || defined(WOLFSSL_ENCRYPTED_KEYS) || defined(HAVE_PKCS8) || defined(HAVE_PKCS12)\n    #undef  HAVE_PBKDF1\n    #define HAVE_PBKDF1\n#endif\n\n#if !defined(NO_PBKDF2) || defined(HAVE_PKCS7) || defined(HAVE_SCRYPT)\n    #undef  HAVE_PBKDF2\n    #define HAVE_PBKDF2\n#endif\n\n\n#if !defined(WOLFCRYPT_ONLY) && !defined(NO_OLD_TLS) && \\\n        (defined(NO_SHA) || defined(NO_MD5))\n    #error old TLS requires MD5 and SHA\n#endif\n\n/* for backwards compatibility */\n#if defined(TEST_IPV6) && !defined(WOLFSSL_IPV6)\n    #define WOLFSSL_IPV6\n#endif\n\n\n/* Place any other flags or defines here */\n\n#if defined(WOLFSSL_MYSQL_COMPATIBLE) && defined(_WIN32) \\\n                                      && defined(HAVE_GMTIME_R)\n    #undef HAVE_GMTIME_R /* don't trust macro with windows */\n#endif /* WOLFSSL_MYSQL_COMPATIBLE */\n\n#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)\n    #define SSL_OP_NO_COMPRESSION    SSL_OP_NO_COMPRESSION\n    #define OPENSSL_NO_ENGINE\n    #define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT\n    #ifndef OPENSSL_EXTRA\n        #define OPENSSL_EXTRA\n    #endif\n    #ifndef HAVE_SESSION_TICKET\n        #define HAVE_SESSION_TICKET\n    #endif\n    #ifndef HAVE_OCSP\n        #define HAVE_OCSP\n    #endif\n    #ifndef KEEP_OUR_CERT\n        #define KEEP_OUR_CERT\n    #endif\n    #ifndef HAVE_SNI\n        #define HAVE_SNI\n    #endif\n#endif\n\n#if defined(WOLFSSL_NGINX)\n    #define SSL_CTRL_SET_TLSEXT_HOSTNAME\n#endif\n\n\n/* both CURVE and ED small math should be enabled */\n#ifdef CURVED25519_SMALL\n        #define CURVE25519_SMALL\n        #define ED25519_SMALL\n#endif\n\n\n#ifndef WOLFSSL_ALERT_COUNT_MAX\n    #define WOLFSSL_ALERT_COUNT_MAX 5\n#endif\n\n/* warning for not using harden build options (default with ./configure) */\n#ifndef WC_NO_HARDEN\n    #if (defined(USE_FAST_MATH) && !defined(TFM_TIMING_RESISTANT)) || \\\n        (defined(HAVE_ECC) && !defined(ECC_TIMING_RESISTANT)) || \\\n        (!defined(NO_RSA) && !defined(WC_RSA_BLINDING) && !defined(HAVE_FIPS) && \\\n            !defined(WC_NO_RNG))\n\n        #ifndef _MSC_VER\n            #warning \"For timing resistance / side-channel attack prevention consider using harden options\"\n        #else\n            #pragma message(\"Warning: For timing resistance / side-channel attack prevention consider using harden options\")\n        #endif\n    #endif\n#endif\n\n#if defined(NO_OLD_WC_NAMES) || defined(OPENSSL_EXTRA)\n    /* added to have compatibility with SHA256() */\n    #if !defined(NO_OLD_SHA_NAMES) && !defined(HAVE_FIPS)\n        #define NO_OLD_SHA_NAMES\n    #endif\n#endif\n\n/* switch for compatibility layer functionality. Has subparts i.e. BIO/X509\n * When opensslextra is enabled all subparts should be turned on. */\n#ifdef OPENSSL_EXTRA\n    #undef  OPENSSL_EXTRA_X509_SMALL\n    #define OPENSSL_EXTRA_X509_SMALL\n#endif /* OPENSSL_EXTRA */\n\n/* support for converting DER to PEM */\n#if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) || \\\n        defined(OPENSSL_EXTRA)\n    #undef  WOLFSSL_DER_TO_PEM\n    #define WOLFSSL_DER_TO_PEM\n#endif\n\n/* keep backwards compatibility enabling encrypted private key */\n#ifndef WOLFSSL_ENCRYPTED_KEYS\n    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \\\n        defined(HAVE_WEBSERVER)\n        #define WOLFSSL_ENCRYPTED_KEYS\n    #endif\n#endif\n\n/* support for disabling PEM to DER */\n#if !defined(WOLFSSL_NO_PEM)\n    #undef  WOLFSSL_PEM_TO_DER\n    #define WOLFSSL_PEM_TO_DER\n#endif\n\n/* Parts of the openssl compatibility layer require peer certs */\n#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)\n    #undef  KEEP_PEER_CERT\n    #define KEEP_PEER_CERT\n#endif\n\n/* RAW hash function APIs are not implemented with ARMv8 hardware acceleration*/\n#ifdef WOLFSSL_ARMASM\n    #undef  WOLFSSL_NO_HASH_RAW\n    #define WOLFSSL_NO_HASH_RAW\n#endif\n\n#if !defined(WOLFSSL_SHA384) && !defined(WOLFSSL_SHA512) && defined(NO_AES) && \\\n                                                          !defined(WOLFSSL_SHA3)\n    #undef  WOLFSSL_NO_WORD64_OPS\n    #define WOLFSSL_NO_WORD64_OPS\n#endif\n\n#if !defined(WOLFCRYPT_ONLY) && !defined(WOLFSSL_NO_TLS12)\n    #undef  WOLFSSL_HAVE_PRF\n    #define WOLFSSL_HAVE_PRF\n#endif\n\n#if defined(NO_AES) && defined(NO_DES3) && !defined(HAVE_CAMELLIA) && \\\n       !defined(WOLFSSL_HAVE_PRF) && defined(NO_PWDBASED) && !defined(HAVE_IDEA)\n    #undef  WOLFSSL_NO_XOR_OPS\n    #define WOLFSSL_NO_XOR_OPS\n#endif\n\n#if defined(NO_ASN) && defined(WOLFCRYPT_ONLY)\n    #undef  WOLFSSL_NO_INT_ENCODE\n    #define WOLFSSL_NO_INT_ENCODE\n    #undef  WOLFSSL_NO_INT_DECODE\n    #define WOLFSSL_NO_INT_DECODE\n#endif\n\n#if defined(WOLFCRYPT_ONLY) && defined(WOLFSSL_RSA_VERIFY_ONLY) && \\\n    defined(WC_NO_RSA_OAEP)\n    #undef  WOLFSSL_NO_CT_OPS\n    #define WOLFSSL_NO_CT_OPS\n#endif\n\n#if defined(WOLFCRYPT_ONLY) && defined(NO_AES) && !defined(HAVE_CURVE25519) && \\\n                                   defined(WC_NO_RNG) && defined(WC_NO_RSA_OAEP)\n    #undef  WOLFSSL_NO_CONST_CMP\n    #define WOLFSSL_NO_CONST_CMP\n#endif\n\n#if defined(WOLFCRYPT_ONLY) && defined(NO_AES) && !defined(WOLFSSL_SHA384) && \\\n    !defined(WOLFSSL_SHA512) && defined(WC_NO_RNG) && \\\n                    defined(WOLFSSL_SP_MATH) && defined(WOLFSSL_RSA_PUBLIC_ONLY)\n    #undef  WOLFSSL_NO_FORCE_ZERO\n    #define WOLFSSL_NO_FORCE_ZERO\n#endif\n\n/* Detect old cryptodev name */\n#if defined(WOLF_CRYPTO_DEV) && !defined(WOLF_CRYPTO_CB)\n    #define WOLF_CRYPTO_CB\n#endif\n\n#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_NO_SIGALG)\n    #error TLS 1.3 requires the Signature Algorithms extension to be enabled\n#endif\n\n#ifdef __cplusplus\n    }   /* extern \"C\" */\n#endif\n\n#endif\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/sha.h",
    "content": "/* sha.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/sha.h\n*/\n\n\n#ifndef WOLF_CRYPT_SHA_H\n#define WOLF_CRYPT_SHA_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_SHA\n\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n    #include <wolfssl/wolfcrypt/fips.h>\n#endif /* HAVE_FIPS_VERSION >= 2 */\n\n#if defined(HAVE_FIPS) && \\\n\t(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n#define wc_Sha             Sha\n#define WC_SHA             SHA\n#define WC_SHA_BLOCK_SIZE  SHA_BLOCK_SIZE\n#define WC_SHA_DIGEST_SIZE SHA_DIGEST_SIZE\n#define WC_SHA_PAD_SIZE    SHA_PAD_SIZE\n\n/* for fips @wc_fips */\n#include <cyassl/ctaocrypt/sha.h>\n#endif\n\n#ifdef FREESCALE_LTC_SHA\n    #include \"fsl_ltc.h\"\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* avoid redefinition of structs */\n#if !defined(HAVE_FIPS) || \\\n    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))\n\n#ifdef WOLFSSL_MICROCHIP_PIC32MZ\n    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>\n#endif\n#ifdef STM32_HASH\n    #include <wolfssl/wolfcrypt/port/st/stm32.h>\n#endif\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n#ifdef WOLFSSL_ESP32WROOM32_CRYPT\n    #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>\n#endif\n\n#if !defined(NO_OLD_SHA_NAMES)\n    #define SHA             WC_SHA\n#endif\n\n#ifndef NO_OLD_WC_NAMES\n    #define Sha             wc_Sha\n    #define SHA_BLOCK_SIZE  WC_SHA_BLOCK_SIZE\n    #define SHA_DIGEST_SIZE WC_SHA_DIGEST_SIZE\n    #define SHA_PAD_SIZE    WC_SHA_PAD_SIZE\n#endif\n\n/* in bytes */\nenum {\n    WC_SHA              =  WC_HASH_TYPE_SHA,\n    WC_SHA_BLOCK_SIZE   = 64,\n    WC_SHA_DIGEST_SIZE  = 20,\n    WC_SHA_PAD_SIZE     = 56\n};\n\n\n#if defined(WOLFSSL_TI_HASH)\n    #include \"wolfssl/wolfcrypt/port/ti/ti-hash.h\"\n\n#elif defined(WOLFSSL_IMX6_CAAM)\n    #include \"wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h\"\n#elif defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \\\n   !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)\n    #include \"wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h\"\n#else\n\n/* Sha digest */\nstruct wc_Sha {\n#ifdef FREESCALE_LTC_SHA\n        ltc_hash_ctx_t ctx;\n#elif defined(STM32_HASH)\n        STM32_HASH_Context stmCtx;\n#else\n        word32  buffLen;   /* in bytes          */\n        word32  loLen;     /* length in bytes   */\n        word32  hiLen;     /* length in bytes   */\n        word32  buffer[WC_SHA_BLOCK_SIZE  / sizeof(word32)];\n    #ifdef WOLFSSL_PIC32MZ_HASH\n        word32  digest[PIC32_DIGEST_SIZE / sizeof(word32)];\n    #else\n        word32  digest[WC_SHA_DIGEST_SIZE / sizeof(word32)];\n    #endif\n        void*   heap;\n    #ifdef WOLFSSL_PIC32MZ_HASH\n        hashUpdCache cache; /* cache for updates */\n    #endif\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        WC_ASYNC_DEV asyncDev;\n    #endif /* WOLFSSL_ASYNC_CRYPT */\n    #ifdef WOLF_CRYPTO_CB\n        int    devId;\n        void*  devCtx; /* generic crypto callback context */\n    #endif\n#endif\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n   !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    WC_ESP32SHA ctx;\n#endif\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    word32 flags; /* enum wc_HashFlags in hash.h */\n#endif\n};\n\n#ifndef WC_SHA_TYPE_DEFINED\n    typedef struct wc_Sha wc_Sha;\n    #define WC_SHA_TYPE_DEFINED\n#endif\n\n#endif /* WOLFSSL_TI_HASH */\n\n\n#endif /* HAVE_FIPS */\n\nWOLFSSL_API int wc_InitSha(wc_Sha*);\nWOLFSSL_API int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId);\nWOLFSSL_API int wc_ShaUpdate(wc_Sha*, const byte*, word32);\nWOLFSSL_API int wc_ShaFinalRaw(wc_Sha*, byte*);\nWOLFSSL_API int wc_ShaFinal(wc_Sha*, byte*);\nWOLFSSL_API void wc_ShaFree(wc_Sha*);\n\nWOLFSSL_API int wc_ShaGetHash(wc_Sha*, byte*);\nWOLFSSL_API int wc_ShaCopy(wc_Sha*, wc_Sha*);\n\n#ifdef WOLFSSL_PIC32MZ_HASH\nWOLFSSL_API void wc_ShaSizeSet(wc_Sha* sha, word32 len);\n#endif\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    WOLFSSL_API int wc_ShaSetFlags(wc_Sha* sha, word32 flags);\n    WOLFSSL_API int wc_ShaGetFlags(wc_Sha* sha, word32* flags);\n#endif\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* NO_SHA */\n#endif /* WOLF_CRYPT_SHA_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/sha256.h",
    "content": "/* sha256.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/sha256.h\n*/\n\n\n\n#ifndef WOLF_CRYPT_SHA256_H\n#define WOLF_CRYPT_SHA256_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifndef NO_SHA256\n\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n    #include <wolfssl/wolfcrypt/fips.h>\n#endif /* HAVE_FIPS_VERSION >= 2 */\n\n#if defined(HAVE_FIPS) && \\\n\t(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n    #define wc_Sha256             Sha256\n    #define WC_SHA256             SHA256\n    #define WC_SHA256_BLOCK_SIZE  SHA256_BLOCK_SIZE\n    #define WC_SHA256_DIGEST_SIZE SHA256_DIGEST_SIZE\n    #define WC_SHA256_PAD_SIZE    SHA256_PAD_SIZE\n\n    #ifdef WOLFSSL_SHA224\n        #define wc_Sha224             Sha224\n        #define WC_SHA224             SHA224\n        #define WC_SHA224_BLOCK_SIZE  SHA224_BLOCK_SIZE\n        #define WC_SHA224_DIGEST_SIZE SHA224_DIGEST_SIZE\n        #define WC_SHA224_PAD_SIZE    SHA224_PAD_SIZE\n    #endif\n\n    /* for fips @wc_fips */\n    #include <cyassl/ctaocrypt/sha256.h>\n#endif\n\n#ifdef FREESCALE_LTC_SHA\n    #include \"fsl_ltc.h\"\n#endif\n\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* avoid redefinition of structs */\n#if !defined(HAVE_FIPS) || \\\n    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))\n\n#ifdef WOLFSSL_MICROCHIP_PIC32MZ\n    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>\n#endif\n#ifdef STM32_HASH\n    #include <wolfssl/wolfcrypt/port/st/stm32.h>\n#endif\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n#if defined(WOLFSSL_DEVCRYPTO) && defined(WOLFSSL_DEVCRYPTO_HASH)\n    #include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>\n#endif\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT)\n    #include \"wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h\"\n#endif\n#if defined(WOLFSSL_CRYPTOCELL)\n    #include <wolfssl/wolfcrypt/port/arm/cryptoCell.h>\n#endif\n\n#if defined(_MSC_VER)\n    #define SHA256_NOINLINE __declspec(noinline)\n#elif defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__)\n    #define SHA256_NOINLINE __attribute__((noinline))\n#else\n    #define SHA256_NOINLINE\n#endif\n\n#if !defined(NO_OLD_SHA_NAMES)\n    #define SHA256             WC_SHA256\n#endif\n\n#ifndef NO_OLD_WC_NAMES\n    #define Sha256             wc_Sha256\n    #define SHA256_BLOCK_SIZE  WC_SHA256_BLOCK_SIZE\n    #define SHA256_DIGEST_SIZE WC_SHA256_DIGEST_SIZE\n    #define SHA256_PAD_SIZE    WC_SHA256_PAD_SIZE\n#endif\n\n/* in bytes */\nenum {\n    WC_SHA256              =  WC_HASH_TYPE_SHA256,\n    WC_SHA256_BLOCK_SIZE   = 64,\n    WC_SHA256_DIGEST_SIZE  = 32,\n    WC_SHA256_PAD_SIZE     = 56\n};\n\n\n#ifdef WOLFSSL_TI_HASH\n    #include \"wolfssl/wolfcrypt/port/ti/ti-hash.h\"\n#elif defined(WOLFSSL_IMX6_CAAM)\n    #include \"wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h\"\n#elif defined(WOLFSSL_AFALG_HASH)\n    #include \"wolfssl/wolfcrypt/port/af_alg/afalg_hash.h\"\n#elif defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \\\n   !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)\n    #include \"wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h\"\n#else\n\n/* wc_Sha256 digest */\nstruct wc_Sha256 {\n#ifdef FREESCALE_LTC_SHA\n    ltc_hash_ctx_t ctx;\n#elif defined(STM32_HASH_SHA2)\n    STM32_HASH_Context stmCtx;\n#else\n    /* alignment on digest and buffer speeds up ARMv8 crypto operations */\n    ALIGN16 word32  digest[WC_SHA256_DIGEST_SIZE / sizeof(word32)];\n    ALIGN16 word32  buffer[WC_SHA256_BLOCK_SIZE  / sizeof(word32)];\n    word32  buffLen;   /* in bytes          */\n    word32  loLen;     /* length in bytes   */\n    word32  hiLen;     /* length in bytes   */\n    void*   heap;\n#ifdef WOLFSSL_PIC32MZ_HASH\n    hashUpdCache cache; /* cache for updates */\n#endif\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV asyncDev;\n#endif /* WOLFSSL_ASYNC_CRYPT */\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    word32* W;\n#endif\n#ifdef WOLFSSL_DEVCRYPTO_HASH\n    WC_CRYPTODEV ctx;\n    byte*  msg;\n    word32 used;\n    word32 len;\n#endif\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n   !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    WC_ESP32SHA ctx;\n#endif\n#ifdef WOLFSSL_CRYPTOCELL\n    CRYS_HASHUserContext_t ctx;\n#endif\n#ifdef WOLF_CRYPTO_CB\n    int    devId;\n    void*  devCtx; /* generic crypto callback context */\n#endif\n#endif\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    word32 flags; /* enum wc_HashFlags in hash.h */\n#endif\n};\n\n#ifndef WC_SHA256_TYPE_DEFINED\n    typedef struct wc_Sha256 wc_Sha256;\n    #define WC_SHA256_TYPE_DEFINED\n#endif\n\n#endif\n\n#endif /* HAVE_FIPS */\n\nWOLFSSL_API int wc_InitSha256(wc_Sha256*);\nWOLFSSL_API int wc_InitSha256_ex(wc_Sha256*, void*, int);\nWOLFSSL_API int wc_Sha256Update(wc_Sha256*, const byte*, word32);\nWOLFSSL_API int wc_Sha256FinalRaw(wc_Sha256*, byte*);\nWOLFSSL_API int wc_Sha256Final(wc_Sha256*, byte*);\nWOLFSSL_API void wc_Sha256Free(wc_Sha256*);\n\nWOLFSSL_API int wc_Sha256GetHash(wc_Sha256*, byte*);\nWOLFSSL_API int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst);\n\n#ifdef WOLFSSL_PIC32MZ_HASH\nWOLFSSL_API void wc_Sha256SizeSet(wc_Sha256*, word32);\n#endif\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    WOLFSSL_API int wc_Sha256SetFlags(wc_Sha256* sha256, word32 flags);\n    WOLFSSL_API int wc_Sha256GetFlags(wc_Sha256* sha256, word32* flags);\n#endif\n\n#ifdef WOLFSSL_SHA224\n/* avoid redefinition of structs */\n#if !defined(HAVE_FIPS) || \\\n    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))\n\n#ifndef NO_OLD_WC_NAMES\n    #define Sha224             wc_Sha224\n    #define SHA224             WC_SHA224\n    #define SHA224_BLOCK_SIZE  WC_SHA224_BLOCK_SIZE\n    #define SHA224_DIGEST_SIZE WC_SHA224_DIGEST_SIZE\n    #define SHA224_PAD_SIZE    WC_SHA224_PAD_SIZE\n#endif\n\n/* in bytes */\nenum {\n    WC_SHA224              =   WC_HASH_TYPE_SHA224,\n    WC_SHA224_BLOCK_SIZE   =   WC_SHA256_BLOCK_SIZE,\n    WC_SHA224_DIGEST_SIZE  =   28,\n    WC_SHA224_PAD_SIZE     =   WC_SHA256_PAD_SIZE\n};\n\n\n#ifndef WC_SHA224_TYPE_DEFINED\n    typedef struct wc_Sha256 wc_Sha224;\n    #define WC_SHA224_TYPE_DEFINED\n#endif\n#endif /* HAVE_FIPS */\n\nWOLFSSL_API int wc_InitSha224(wc_Sha224*);\nWOLFSSL_API int wc_InitSha224_ex(wc_Sha224*, void*, int);\nWOLFSSL_API int wc_Sha224Update(wc_Sha224*, const byte*, word32);\nWOLFSSL_API int wc_Sha224Final(wc_Sha224*, byte*);\nWOLFSSL_API void wc_Sha224Free(wc_Sha224*);\n\nWOLFSSL_API int wc_Sha224GetHash(wc_Sha224*, byte*);\nWOLFSSL_API int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst);\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    WOLFSSL_API int wc_Sha224SetFlags(wc_Sha224* sha224, word32 flags);\n    WOLFSSL_API int wc_Sha224GetFlags(wc_Sha224* sha224, word32* flags);\n#endif\n\n#endif /* WOLFSSL_SHA224 */\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* NO_SHA256 */\n#endif /* WOLF_CRYPT_SHA256_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/sha3.h",
    "content": "/* sha3.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifndef WOLF_CRYPT_SHA3_H\n#define WOLF_CRYPT_SHA3_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef WOLFSSL_SHA3\n\n#ifdef HAVE_FIPS\n    /* for fips @wc_fips */\n    #include <wolfssl/wolfcrypt/fips.h>\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n\n/* in bytes */\nenum {\n    WC_SHA3_224              = WC_HASH_TYPE_SHA3_224,\n    WC_SHA3_224_DIGEST_SIZE  = 28,\n    WC_SHA3_224_COUNT        = 18,\n\n    WC_SHA3_256              = WC_HASH_TYPE_SHA3_256,\n    WC_SHA3_256_DIGEST_SIZE  = 32,\n    WC_SHA3_256_COUNT        = 17,\n\n    WC_SHA3_384              = WC_HASH_TYPE_SHA3_384,\n    WC_SHA3_384_DIGEST_SIZE  = 48,\n    WC_SHA3_384_COUNT        = 13,\n\n    WC_SHA3_512              = WC_HASH_TYPE_SHA3_512,\n    WC_SHA3_512_DIGEST_SIZE  = 64,\n    WC_SHA3_512_COUNT        =  9,\n\n#ifndef HAVE_SELFTEST\n    /* These values are used for HMAC, not SHA-3 directly.\n     * They come from from FIPS PUB 202. */\n    WC_SHA3_224_BLOCK_SIZE = 144,\n    WC_SHA3_256_BLOCK_SIZE = 136,\n    WC_SHA3_384_BLOCK_SIZE = 104,\n    WC_SHA3_512_BLOCK_SIZE = 72,\n#endif\n};\n\n#ifndef NO_OLD_WC_NAMES\n    #define SHA3_224             WC_SHA3_224\n    #define SHA3_224_DIGEST_SIZE WC_SHA3_224_DIGEST_SIZE\n    #define SHA3_256             WC_SHA3_256\n    #define SHA3_256_DIGEST_SIZE WC_SHA3_256_DIGEST_SIZE\n    #define SHA3_384             WC_SHA3_384\n    #define SHA3_384_DIGEST_SIZE WC_SHA3_384_DIGEST_SIZE\n    #define SHA3_512             WC_SHA3_512\n    #define SHA3_512_DIGEST_SIZE WC_SHA3_512_DIGEST_SIZE\n    #define Sha3 wc_Sha3\n#endif\n\n\n\n#ifdef WOLFSSL_XILINX_CRYPT\n    #include \"wolfssl/wolfcrypt/port/xilinx/xil-sha3.h\"\n#elif defined(WOLFSSL_AFALG_XILINX_SHA3)\n    #include <wolfssl/wolfcrypt/port/af_alg/afalg_hash.h>\n#else\n\n/* Sha3 digest */\nstruct Sha3 {\n    /* State data that is processed for each block. */\n    word64 s[25];\n    /* Unprocessed message data. */\n    byte   t[200];\n    /* Index into unprocessed data to place next message byte. */\n    byte   i;\n\n    void*  heap;\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV asyncDev;\n#endif /* WOLFSSL_ASYNC_CRYPT */\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    word32 flags; /* enum wc_HashFlags in hash.h */\n#endif\n};\n\n#ifndef WC_SHA3_TYPE_DEFINED\n    typedef struct Sha3 wc_Sha3;\n    #define WC_SHA3_TYPE_DEFINED\n#endif\n\n#endif\n\n\nWOLFSSL_API int wc_InitSha3_224(wc_Sha3*, void*, int);\nWOLFSSL_API int wc_Sha3_224_Update(wc_Sha3*, const byte*, word32);\nWOLFSSL_API int wc_Sha3_224_Final(wc_Sha3*, byte*);\nWOLFSSL_API void wc_Sha3_224_Free(wc_Sha3*);\nWOLFSSL_API int wc_Sha3_224_GetHash(wc_Sha3*, byte*);\nWOLFSSL_API int wc_Sha3_224_Copy(wc_Sha3* src, wc_Sha3* dst);\n\nWOLFSSL_API int wc_InitSha3_256(wc_Sha3*, void*, int);\nWOLFSSL_API int wc_Sha3_256_Update(wc_Sha3*, const byte*, word32);\nWOLFSSL_API int wc_Sha3_256_Final(wc_Sha3*, byte*);\nWOLFSSL_API void wc_Sha3_256_Free(wc_Sha3*);\nWOLFSSL_API int wc_Sha3_256_GetHash(wc_Sha3*, byte*);\nWOLFSSL_API int wc_Sha3_256_Copy(wc_Sha3* src, wc_Sha3* dst);\n\nWOLFSSL_API int wc_InitSha3_384(wc_Sha3*, void*, int);\nWOLFSSL_API int wc_Sha3_384_Update(wc_Sha3*, const byte*, word32);\nWOLFSSL_API int wc_Sha3_384_Final(wc_Sha3*, byte*);\nWOLFSSL_API void wc_Sha3_384_Free(wc_Sha3*);\nWOLFSSL_API int wc_Sha3_384_GetHash(wc_Sha3*, byte*);\nWOLFSSL_API int wc_Sha3_384_Copy(wc_Sha3* src, wc_Sha3* dst);\n\nWOLFSSL_API int wc_InitSha3_512(wc_Sha3*, void*, int);\nWOLFSSL_API int wc_Sha3_512_Update(wc_Sha3*, const byte*, word32);\nWOLFSSL_API int wc_Sha3_512_Final(wc_Sha3*, byte*);\nWOLFSSL_API void wc_Sha3_512_Free(wc_Sha3*);\nWOLFSSL_API int wc_Sha3_512_GetHash(wc_Sha3*, byte*);\nWOLFSSL_API int wc_Sha3_512_Copy(wc_Sha3* src, wc_Sha3* dst);\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    WOLFSSL_API int wc_Sha3_SetFlags(wc_Sha3* sha3, word32 flags);\n    WOLFSSL_API int wc_Sha3_GetFlags(wc_Sha3* sha3, word32* flags);\n#endif\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLFSSL_SHA3 */\n#endif /* WOLF_CRYPT_SHA3_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/sha512.h",
    "content": "/* sha512.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/sha512.h\n*/\n\n\n#ifndef WOLF_CRYPT_SHA512_H\n#define WOLF_CRYPT_SHA512_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)\n\n#if defined(HAVE_FIPS) && \\\n    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)\n    #include <wolfssl/wolfcrypt/fips.h>\n#endif /* HAVE_FIPS_VERSION >= 2 */\n\n#if defined(HAVE_FIPS) && \\\n\t(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n    #ifdef WOLFSSL_SHA512\n        #define wc_Sha512             Sha512\n        #define WC_SHA512             SHA512\n        #define WC_SHA512_BLOCK_SIZE  SHA512_BLOCK_SIZE\n        #define WC_SHA512_DIGEST_SIZE SHA512_DIGEST_SIZE\n        #define WC_SHA512_PAD_SIZE    SHA512_PAD_SIZE\n    #endif /* WOLFSSL_SHA512 */\n    #ifdef WOLFSSL_SHA384\n        #define wc_Sha384             Sha384\n        #define WC_SHA384             SHA384\n        #define WC_SHA384_BLOCK_SIZE  SHA384_BLOCK_SIZE\n        #define WC_SHA384_DIGEST_SIZE SHA384_DIGEST_SIZE\n        #define WC_SHA384_PAD_SIZE    SHA384_PAD_SIZE\n    #endif /* WOLFSSL_SHA384 */\n\n    #define CYASSL_SHA512\n    #if defined(WOLFSSL_SHA384)\n        #define CYASSL_SHA384\n    #endif\n\t/* for fips @wc_fips */\n    #include <cyassl/ctaocrypt/sha512.h>\n#endif\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* avoid redefinition of structs */\n#if !defined(HAVE_FIPS) || \\\n    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))\n\n#ifdef WOLFSSL_ASYNC_CRYPT\n    #include <wolfssl/wolfcrypt/async.h>\n#endif\n#ifdef WOLFSSL_ESP32WROOM32_CRYPT\n    #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>\n#endif\n#if defined(_MSC_VER)\n    #define SHA512_NOINLINE __declspec(noinline)\n#elif defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__)\n    #define SHA512_NOINLINE __attribute__((noinline))\n#else\n    #define SHA512_NOINLINE\n#endif\n\n#ifdef WOLFSSL_SHA512\n\n#if !defined(NO_OLD_SHA_NAMES)\n    #define SHA512             WC_SHA512\n#endif\n\n#if !defined(NO_OLD_WC_NAMES)\n    #define Sha512             wc_Sha512\n    #define SHA512_BLOCK_SIZE  WC_SHA512_BLOCK_SIZE\n    #define SHA512_DIGEST_SIZE WC_SHA512_DIGEST_SIZE\n    #define SHA512_PAD_SIZE    WC_SHA512_PAD_SIZE\n#endif\n\n#endif /* WOLFSSL_SHA512 */\n\n/* in bytes */\nenum {\n#ifdef WOLFSSL_SHA512\n    WC_SHA512              =   WC_HASH_TYPE_SHA512,\n#endif\n    WC_SHA512_BLOCK_SIZE   = 128,\n    WC_SHA512_DIGEST_SIZE  =  64,\n    WC_SHA512_PAD_SIZE     = 112\n};\n\n\n#ifdef WOLFSSL_IMX6_CAAM\n    #include \"wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h\"\n#else\n/* wc_Sha512 digest */\nstruct wc_Sha512 {\n    word64  digest[WC_SHA512_DIGEST_SIZE / sizeof(word64)];\n    word64  buffer[WC_SHA512_BLOCK_SIZE  / sizeof(word64)];\n    word32  buffLen;   /* in bytes          */\n    word64  loLen;     /* length in bytes   */\n    word64  hiLen;     /* length in bytes   */\n    void*   heap;\n#ifdef USE_INTEL_SPEEDUP\n    const byte* data;\n#endif\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WC_ASYNC_DEV asyncDev;\n#endif /* WOLFSSL_ASYNC_CRYPT */\n#ifdef WOLFSSL_SMALL_STACK_CACHE\n    word64* W;\n#endif\n#if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \\\n   !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)\n    WC_ESP32SHA ctx;\n#endif\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    word32 flags; /* enum wc_HashFlags in hash.h */\n#endif\n};\n\n#ifndef WC_SHA512_TYPE_DEFINED\n    typedef struct wc_Sha512 wc_Sha512;\n    #define WC_SHA512_TYPE_DEFINED\n#endif\n#endif\n\n#endif /* HAVE_FIPS */\n\n#ifdef WOLFSSL_ARMASM\nWOLFSSL_LOCAL void Transform_Sha512_Len(wc_Sha512* sha512, const byte* data,\n                                        word32 len);\n#endif\n\n#ifdef WOLFSSL_SHA512\n\nWOLFSSL_API int wc_InitSha512(wc_Sha512*);\nWOLFSSL_API int wc_InitSha512_ex(wc_Sha512*, void*, int);\nWOLFSSL_API int wc_Sha512Update(wc_Sha512*, const byte*, word32);\nWOLFSSL_API int wc_Sha512FinalRaw(wc_Sha512*, byte*);\nWOLFSSL_API int wc_Sha512Final(wc_Sha512*, byte*);\nWOLFSSL_API void wc_Sha512Free(wc_Sha512*);\n\nWOLFSSL_API int wc_Sha512GetHash(wc_Sha512*, byte*);\nWOLFSSL_API int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst);\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    WOLFSSL_API int wc_Sha512SetFlags(wc_Sha512* sha512, word32 flags);\n    WOLFSSL_API int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags);\n#endif\n\n#endif /* WOLFSSL_SHA512 */\n\n#if defined(WOLFSSL_SHA384)\n\n/* avoid redefinition of structs */\n#if !defined(HAVE_FIPS) || \\\n    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))\n\n#if !defined(NO_OLD_SHA_NAMES)\n    #define SHA384             WC_SHA384\n#endif\n\n#if !defined(NO_OLD_WC_NAMES)\n    #define Sha384             wc_Sha384\n    #define SHA384_BLOCK_SIZE  WC_SHA384_BLOCK_SIZE\n    #define SHA384_DIGEST_SIZE WC_SHA384_DIGEST_SIZE\n    #define SHA384_PAD_SIZE    WC_SHA384_PAD_SIZE\n#endif\n\n/* in bytes */\nenum {\n    WC_SHA384              =   WC_HASH_TYPE_SHA384,\n    WC_SHA384_BLOCK_SIZE   =   WC_SHA512_BLOCK_SIZE,\n    WC_SHA384_DIGEST_SIZE  =   48,\n    WC_SHA384_PAD_SIZE     =   WC_SHA512_PAD_SIZE\n};\n\n\n#ifndef WC_SHA384_TYPE_DEFINED\n    typedef struct wc_Sha512 wc_Sha384;\n    #define WC_SHA384_TYPE_DEFINED\n#endif\n#endif /* HAVE_FIPS */\n\nWOLFSSL_API int wc_InitSha384(wc_Sha384*);\nWOLFSSL_API int wc_InitSha384_ex(wc_Sha384*, void*, int);\nWOLFSSL_API int wc_Sha384Update(wc_Sha384*, const byte*, word32);\nWOLFSSL_API int wc_Sha384FinalRaw(wc_Sha384*, byte*);\nWOLFSSL_API int wc_Sha384Final(wc_Sha384*, byte*);\nWOLFSSL_API void wc_Sha384Free(wc_Sha384*);\n\nWOLFSSL_API int wc_Sha384GetHash(wc_Sha384*, byte*);\nWOLFSSL_API int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst);\n\n#if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)\n    WOLFSSL_API int wc_Sha384SetFlags(wc_Sha384* sha384, word32 flags);\n    WOLFSSL_API int wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags);\n#endif\n\n#endif /* WOLFSSL_SHA384 */\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */\n#endif /* WOLF_CRYPT_SHA512_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/signature.h",
    "content": "/* signature.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/signature.h\n*/\n\n\n#ifndef WOLF_CRYPT_SIGNATURE_H\n#define WOLF_CRYPT_SIGNATURE_H\n\n#include <wolfssl/wolfcrypt/types.h>\n#include <wolfssl/wolfcrypt/hash.h>\n#include <wolfssl/wolfcrypt/random.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\nenum wc_SignatureType {\n    WC_SIGNATURE_TYPE_NONE = 0,\n    WC_SIGNATURE_TYPE_ECC = 1,\n    WC_SIGNATURE_TYPE_RSA = 2,\n    WC_SIGNATURE_TYPE_RSA_W_ENC = 3, /* Adds DER header via wc_EncodeSignature */\n};\n\nWOLFSSL_API int wc_SignatureGetSize(enum wc_SignatureType sig_type,\n    const void* key, word32 key_len);\n\nWOLFSSL_API int wc_SignatureVerifyHash(\n    enum wc_HashType hash_type, enum wc_SignatureType sig_type,\n    const byte* hash_data, word32 hash_len,\n    const byte* sig, word32 sig_len,\n    const void* key, word32 key_len);\n\nWOLFSSL_API int wc_SignatureVerify(\n    enum wc_HashType hash_type, enum wc_SignatureType sig_type,\n    const byte* data, word32 data_len,\n    const byte* sig, word32 sig_len,\n    const void* key, word32 key_len);\n\nWOLFSSL_API int wc_SignatureGenerateHash(\n    enum wc_HashType hash_type, enum wc_SignatureType sig_type,\n    const byte* hash_data, word32 hash_len,\n    byte* sig, word32 *sig_len,\n    const void* key, word32 key_len, WC_RNG* rng);\nWOLFSSL_API int wc_SignatureGenerateHash_ex(\n    enum wc_HashType hash_type, enum wc_SignatureType sig_type,\n    const byte* hash_data, word32 hash_len,\n    byte* sig, word32 *sig_len,\n    const void* key, word32 key_len, WC_RNG* rng, int verify);\nWOLFSSL_API int wc_SignatureGenerate(\n    enum wc_HashType hash_type, enum wc_SignatureType sig_type,\n    const byte* data, word32 data_len,\n    byte* sig, word32 *sig_len,\n    const void* key, word32 key_len,\n    WC_RNG* rng);\nWOLFSSL_API int wc_SignatureGenerate_ex(\n    enum wc_HashType hash_type, enum wc_SignatureType sig_type,\n    const byte* data, word32 data_len,\n    byte* sig, word32 *sig_len,\n    const void* key, word32 key_len,\n    WC_RNG* rng, int verify);\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLF_CRYPT_SIGNATURE_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/sp.h",
    "content": "/* sp.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifndef WOLF_CRYPT_SP_H\n#define WOLF_CRYPT_SP_H\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \\\n                                    defined(WOLFSSL_HAVE_SP_ECC)\n\n#include <stdint.h>\n\n#include <wolfssl/wolfcrypt/integer.h>\n#include <wolfssl/wolfcrypt/sp_int.h>\n\n#include <wolfssl/wolfcrypt/ecc.h>\n\n#if defined(_MSC_VER)\n    #define SP_NOINLINE __declspec(noinline)\n#elif defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) || defined(__KEIL__)\n    #define SP_NOINLINE __attribute__((noinline))\n#else\n    #define SP_NOINLINE\n#endif\n\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifdef WOLFSSL_HAVE_SP_RSA\n\nWOLFSSL_LOCAL int sp_RsaPublic_2048(const byte* in, word32 inLen,\n    mp_int* em, mp_int* mm, byte* out, word32* outLen);\nWOLFSSL_LOCAL int sp_RsaPrivate_2048(const byte* in, word32 inLen,\n    mp_int* dm, mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim,\n    mp_int* mm, byte* out, word32* outLen);\n\nWOLFSSL_LOCAL int sp_RsaPublic_3072(const byte* in, word32 inLen,\n    mp_int* em, mp_int* mm, byte* out, word32* outLen);\nWOLFSSL_LOCAL int sp_RsaPrivate_3072(const byte* in, word32 inLen,\n    mp_int* dm, mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim,\n    mp_int* mm, byte* out, word32* outLen);\n\nWOLFSSL_LOCAL int sp_RsaPublic_4096(const byte* in, word32 inLen,\n    mp_int* em, mp_int* mm, byte* out, word32* outLen);\nWOLFSSL_LOCAL int sp_RsaPrivate_4096(const byte* in, word32 inLen,\n    mp_int* dm, mp_int* pm, mp_int* qm, mp_int* dpm, mp_int* dqm, mp_int* qim,\n    mp_int* mm, byte* out, word32* outLen);\n\n#endif /* WOLFSSL_HAVE_SP_RSA */\n\n#if defined(WOLFSSL_HAVE_SP_DH) || defined(WOLFSSL_HAVE_SP_RSA)\n\nWOLFSSL_LOCAL int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\nWOLFSSL_LOCAL int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod,\n    mp_int* res);\n\n#endif\n\n#ifdef WOLFSSL_HAVE_SP_DH\n\nWOLFSSL_LOCAL int sp_DhExp_2048(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen);\nWOLFSSL_LOCAL int sp_DhExp_3072(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen);\nWOLFSSL_LOCAL int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen,\n    mp_int* mod, byte* out, word32* outLen);\n\n#endif /* WOLFSSL_HAVE_SP_DH */\n\n#ifdef WOLFSSL_HAVE_SP_ECC\n\nint sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* rm, int map,\n                      void* heap);\nint sp_ecc_mulmod_base_256(mp_int* km, ecc_point* rm, int map, void* heap);\n\nint sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap);\nint sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out,\n                          word32* outlen, void* heap);\nint sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,\n                    mp_int* rm, mp_int* sm, mp_int* km, void* heap);\nint sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, mp_int* pY,\n                      mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap);\nint sp_ecc_is_point_256(mp_int* pX, mp_int* pY);\nint sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap);\nint sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* qX, mp_int* qY, mp_int* qZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ);\nint sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ,\n                              mp_int* rX, mp_int* rY, mp_int* rZ);\nint sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ);\nint sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym);\n\n#endif /*ifdef WOLFSSL_HAVE_SP_ECC */\n\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* WOLFSSL_HAVE_SP_RSA || WOLFSSL_HAVE_SP_DH || WOLFSSL_HAVE_SP_ECC */\n\n#endif /* WOLF_CRYPT_SP_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/sp_int.h",
    "content": "/* sp_int.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n#ifndef WOLF_CRYPT_SP_INT_H\n#define WOLF_CRYPT_SP_INT_H\n\n#include <stdint.h>\n#include <limits.h>\n\n/* Make sure WOLFSSL_SP_ASM build option defined when requested */\n#if !defined(WOLFSSL_SP_ASM) && ( \\\n      defined(WOLFSSL_SP_X86_64_ASM) || defined(WOLFSSL_SP_ARM32_ASM) || \\\n      defined(WOLFSSL_SP_ARM64_ASM)  || defined(WOLFSSL_SP_ARM_THUMB_ASM) || \\\n      defined(WOLFSSL_SP_ARM_CORTEX_M_ASM))\n    #define WOLFSSL_SP_ASM\n#endif\n\n\n#ifdef WOLFSSL_SP_X86_64_ASM\n    #define SP_WORD_SIZE 64\n\n    #define HAVE_INTEL_AVX1\n    #define HAVE_INTEL_AVX2\n#elif defined(WOLFSSL_SP_ARM64_ASM)\n    #define SP_WORD_SIZE 64\n#elif defined(WOLFSSL_SP_ARM32_ASM)\n    #define SP_WORD_SIZE 32\n#elif defined(WOLFSSL_SP_ARM_THUMB_ASM)\n    #define SP_WORD_SIZE 32\n#endif\n\n#ifndef SP_WORD_SIZE\n    #if defined(NO_64BIT) || !defined(HAVE___UINT128_T)\n        #define SP_WORD_SIZE 32\n    #else\n        #define SP_WORD_SIZE 64\n    #endif\n#endif\n\n#ifndef WOLFSSL_SP_ASM\n  #if SP_WORD_SIZE == 32\n    typedef int32_t sp_digit;\n    typedef uint32_t sp_int_digit;\n    typedef uint64_t sp_int_word;\n  #elif SP_WORD_SIZE == 64\n    typedef int64_t sp_digit;\n    typedef uint64_t sp_int_digit;\n    #ifdef __SIZEOF_INT128__\n      typedef __uint128_t uint128_t;\n      typedef __int128_t int128_t;\n    #else\n      typedef unsigned long uint128_t __attribute__ ((mode(TI)));\n      typedef long int128_t __attribute__ ((mode(TI)));\n    #endif\n    typedef uint128_t sp_int_word;\n  #else\n    #error Word size not defined\n  #endif\n#else\n  #if SP_WORD_SIZE == 32\n    typedef uint32_t sp_digit;\n    typedef uint32_t sp_int_digit;\n    typedef uint64_t sp_int_word;\n  #elif SP_WORD_SIZE == 64\n    typedef uint64_t sp_digit;\n    typedef uint64_t sp_int_digit;\n    #ifdef __SIZEOF_INT128__\n      typedef __uint128_t uint128_t;\n      typedef __int128_t int128_t;\n    #else\n      typedef unsigned long uint128_t __attribute__ ((mode(TI)));\n      typedef long int128_t __attribute__ ((mode(TI)));\n    #endif\n    typedef uint128_t sp_int_word;\n  #else\n    #error Word size not defined\n  #endif\n#endif\n\n#ifdef WOLFSSL_SP_MATH\n#include <wolfssl/wolfcrypt/random.h>\n\n#if !defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_HAVE_SP_DH)\n    #if !defined(NO_PWDBASED) && defined(WOLFSSL_SHA512)\n        #define SP_INT_DIGITS        ((512 + SP_WORD_SIZE) / SP_WORD_SIZE)\n    #else\n        #define SP_INT_DIGITS        ((256 + SP_WORD_SIZE) / SP_WORD_SIZE)\n    #endif\n#elif defined(WOLFSSL_SP_4096)\n    #if defined(WOLFSSL_HAVE_SP_DH)\n        #define SP_INT_DIGITS        ((8192 + SP_WORD_SIZE) / SP_WORD_SIZE)\n    #else\n        #define SP_INT_DIGITS        ((4096 + SP_WORD_SIZE) / SP_WORD_SIZE)\n    #endif\n#elif !defined(WOLFSSL_SP_NO_3072)\n    #if defined(WOLFSSL_HAVE_SP_DH)\n        #define SP_INT_DIGITS        ((6144 + SP_WORD_SIZE) / SP_WORD_SIZE)\n    #else\n        #define SP_INT_DIGITS        ((3072 + SP_WORD_SIZE) / SP_WORD_SIZE)\n    #endif\n#else\n    #if defined(WOLFSSL_HAVE_SP_DH)\n        #define SP_INT_DIGITS        ((4096 + SP_WORD_SIZE) / SP_WORD_SIZE)\n    #else\n        #define SP_INT_DIGITS        ((2048 + SP_WORD_SIZE) / SP_WORD_SIZE)\n    #endif\n#endif\n\n#define sp_isodd(a)  ((a)->used != 0 && ((a)->dp[0] & 1))\n#define sp_iseven(a) ((a)->used != 0 && ((a)->dp[0] & 1) == 0)\n#define sp_iszero(a) ((a)->used == 0)\n#define sp_isone(a)  ((a)->used == 1 && (a)->dp[0] == 1)\n#define sp_abs(a, b)  sp_copy(a, b)\n\n#ifdef HAVE_WOLF_BIGINT\n    /* raw big integer */\n    typedef struct WC_BIGINT {\n        byte*   buf;\n        word32  len;\n        void*   heap;\n    } WC_BIGINT;\n    #define WOLF_BIGINT_DEFINED\n#endif\n\ntypedef struct sp_int {\n    int used;\n    int size;\n    sp_int_digit dp[SP_INT_DIGITS];\n#ifdef HAVE_WOLF_BIGINT\n    struct WC_BIGINT raw; /* unsigned binary (big endian) */\n#endif\n} sp_int;\n\ntypedef sp_int mp_int;\ntypedef sp_digit mp_digit;\n\n#include <wolfssl/wolfcrypt/wolfmath.h>\n\n\nMP_API int sp_init(sp_int* a);\nMP_API int sp_init_multi(sp_int* a, sp_int* b, sp_int* c, sp_int* d,\n                         sp_int* e, sp_int* f);\nMP_API void sp_clear(sp_int* a);\nMP_API int sp_unsigned_bin_size(sp_int* a);\nMP_API int sp_read_unsigned_bin(sp_int* a, const byte* in, int inSz);\nMP_API int sp_read_radix(sp_int* a, const char* in, int radix);\nMP_API int sp_cmp(sp_int* a, sp_int* b);\nMP_API int sp_count_bits(sp_int* a);\nMP_API int sp_leading_bit(sp_int* a);\nMP_API int sp_to_unsigned_bin(sp_int* a, byte* out);\nMP_API int sp_to_unsigned_bin_len(sp_int* a, byte* out, int outSz);\nMP_API void sp_forcezero(sp_int* a);\nMP_API int sp_copy(sp_int* a, sp_int* r);\nMP_API int sp_set(sp_int* a, sp_int_digit d);\nMP_API void sp_clamp(sp_int* a);\nMP_API int sp_grow(sp_int* a, int l);\nMP_API int sp_sub_d(sp_int* a, sp_int_digit d, sp_int* r);\nMP_API int sp_cmp_d(sp_int* a, sp_int_digit d);\nMP_API int sp_sub(sp_int* a, sp_int* b, sp_int* r);\nMP_API int sp_mod(sp_int* a, sp_int* m, sp_int* r);\nMP_API void sp_zero(sp_int* a);\nMP_API int sp_add_d(sp_int* a, sp_int_digit d, sp_int* r);\nMP_API int sp_lshd(sp_int* a, int s);\nMP_API int sp_add(sp_int* a, sp_int* b, sp_int* r);\nMP_API int sp_set_int(sp_int* a, unsigned long b);\nMP_API int sp_tohex(sp_int* a, char* str);\nMP_API int sp_2expt(sp_int* a, int e);\nMP_API int sp_rand_prime(sp_int* r, int len, WC_RNG* rng, void* heap);\nMP_API int sp_mul(sp_int* a, sp_int* b, sp_int* r);\nMP_API int sp_mulmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r);\nMP_API int sp_gcd(sp_int* a, sp_int* b, sp_int* r);\nMP_API int sp_invmod(sp_int* a, sp_int* m, sp_int* r);\nMP_API int sp_lcm(sp_int* a, sp_int* b, sp_int* r);\nMP_API int sp_exptmod(sp_int* b, sp_int* e, sp_int* m, sp_int* r);\nMP_API int sp_prime_is_prime(mp_int* a, int t, int* result);\nMP_API int sp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng);\nMP_API int sp_exch(sp_int* a, sp_int* b);\nMP_API int sp_get_digit_count(sp_int *a);\nMP_API int sp_init_copy (sp_int * a, sp_int * b);\nMP_API void sp_rshb(sp_int* a, int n, sp_int* r);\n\n\n#define MP_OKAY    0\n#define MP_NO      0\n#define MP_YES     1\n\n#define MP_RADIX_HEX     16\n\n#define MP_GT    1\n#define MP_EQ    0\n#define MP_LT    -1\n\n#define MP_MEM   -2\n#define MP_VAL   -3\n\n#define DIGIT_BIT  SP_WORD_SIZE\n\n#define CheckFastMathSettings() 1\n\n#define mp_free(a)\n\n#define mp_isodd                    sp_isodd\n#define mp_iseven                   sp_iseven\n#define mp_iszero                   sp_iszero\n#define mp_isone                    sp_isone\n#define mp_abs                      sp_abs\n\n#define mp_init                     sp_init\n#define mp_init_multi               sp_init_multi\n#define mp_clear                    sp_clear\n#define mp_read_unsigned_bin        sp_read_unsigned_bin\n#define mp_unsigned_bin_size        sp_unsigned_bin_size\n#define mp_read_radix               sp_read_radix\n#define mp_cmp                      sp_cmp\n#define mp_count_bits               sp_count_bits\n#define mp_leading_bit              sp_leading_bit\n#define mp_to_unsigned_bin          sp_to_unsigned_bin\n#define mp_to_unsigned_bin_len      sp_to_unsigned_bin_len\n#define mp_forcezero                sp_forcezero\n#define mp_copy                     sp_copy\n#define mp_set                      sp_set\n#define mp_clamp                    sp_clamp\n#define mp_grow                     sp_grow\n#define mp_sub_d                    sp_sub_d\n#define mp_cmp_d                    sp_cmp_d\n#define mp_sub                      sp_sub\n#define mp_mod                      sp_mod\n#define mp_zero                     sp_zero\n#define mp_add_d                    sp_add_d\n#define mp_lshd                     sp_lshd\n#define mp_add                      sp_add\n#define mp_set_int                  sp_set_int\n#define mp_tohex                    sp_tohex\n#define mp_2expt                    sp_2expt\n#define mp_rand_prime               sp_rand_prime\n#define mp_mul                      sp_mul\n#define mp_mulmod                   sp_mulmod\n#define mp_gcd                      sp_gcd\n#define mp_invmod                   sp_invmod\n#define mp_lcm                      sp_lcm\n#define mp_exptmod                  sp_exptmod\n#define mp_prime_is_prime           sp_prime_is_prime\n#define mp_prime_is_prime_ex        sp_prime_is_prime_ex\n#define mp_exch                     sp_exch\n#define get_digit_count             sp_get_digit_count\n#define mp_init_copy                sp_init_copy\n#define mp_rshb(A,x)                sp_rshb(A,x,A)\n\n#endif\n\n#endif /* WOLF_CRYPT_SP_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/srp.h",
    "content": "/* srp.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/srp.h\n*/\n\n#ifdef WOLFCRYPT_HAVE_SRP\n\n#ifndef WOLFCRYPT_SRP_H\n#define WOLFCRYPT_SRP_H\n\n#include <wolfssl/wolfcrypt/types.h>\n#include <wolfssl/wolfcrypt/sha.h>\n#include <wolfssl/wolfcrypt/sha256.h>\n#include <wolfssl/wolfcrypt/sha512.h>\n#include <wolfssl/wolfcrypt/integer.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* Select the largest available hash for the buffer size. */\n#if defined(WOLFSSL_SHA512)\n    #define SRP_MAX_DIGEST_SIZE WC_SHA512_DIGEST_SIZE\n#elif defined(WOLFSSL_SHA384)\n    #define SRP_MAX_DIGEST_SIZE WC_SHA384_DIGEST_SIZE\n#elif !defined(NO_SHA256)\n    #define SRP_MAX_DIGEST_SIZE WC_SHA256_DIGEST_SIZE\n#elif !defined(NO_SHA)\n    #define SRP_MAX_DIGEST_SIZE WC_SHA_DIGEST_SIZE\n#else\n    #error \"You have to have some kind of SHA hash if you want to use SRP.\"\n#endif\n\n/* Set the minimum number of bits acceptable in an SRP modulus */\n#define SRP_MODULUS_MIN_BITS 512\n\n/* Set the minimum number of bits acceptable for private keys (RFC 5054) */\n#define SRP_PRIVATE_KEY_MIN_BITS 256\n\n/* salt size for SRP password */\n#define SRP_SALT_SIZE  16\n\n/**\n * SRP side, client or server.\n */\ntypedef enum {\n    SRP_CLIENT_SIDE  = 0,\n    SRP_SERVER_SIDE  = 1,\n} SrpSide;\n\n/**\n * SRP hash type, SHA[1|256|384|512].\n */\ntypedef enum {\n        SRP_TYPE_SHA    = 1,\n        SRP_TYPE_SHA256 = 2,\n        SRP_TYPE_SHA384 = 3,\n        SRP_TYPE_SHA512 = 4,\n} SrpType;\n\n\n/**\n * SRP hash struct.\n */\ntypedef struct {\n    byte type;\n    union {\n        #ifndef NO_SHA\n            wc_Sha sha;\n        #endif\n        #ifndef NO_SHA256\n            wc_Sha256 sha256;\n        #endif\n        #ifdef WOLFSSL_SHA384\n            wc_Sha384 sha384;\n        #endif\n        #ifdef WOLFSSL_SHA512\n            wc_Sha512 sha512;\n        #endif\n    } data;\n} SrpHash;\n\ntypedef struct Srp {\n    SrpSide side;                   /**< Client or Server, @see SrpSide.      */\n    SrpType type;                   /**< Hash type, @see SrpType.             */\n    byte*   user;                   /**< Username, login.                     */\n    word32  userSz;                 /**< Username length.                     */\n    byte*   salt;                   /**< Small salt.                          */\n    word32  saltSz;                 /**< Salt length.                         */\n    mp_int  N;                      /**< Modulus. N = 2q+1, [q, N] are primes.*/\n    mp_int  g;                      /**< Generator. A generator modulo N.     */\n    byte    k[SRP_MAX_DIGEST_SIZE]; /**< Multiplier parameter. k = H(N, g)   */\n    mp_int  auth;                   /**< Client: x = H(salt + H(user:pswd))   */\n                                    /**< Server: v = g ^ x % N                */\n    mp_int  priv;                   /**< Private ephemeral value.             */\n    SrpHash client_proof;           /**< Client proof. Sent to the Server.    */\n    SrpHash server_proof;           /**< Server proof. Sent to the Client.    */\n    byte*   key;                    /**< Session key.                         */\n    word32  keySz;                  /**< Session key length.                  */\n    int (*keyGenFunc_cb) (struct Srp* srp, byte* secret, word32 size);\n        /**< Function responsible for generating the session key.             */\n        /**< It MUST use XMALLOC with type DYNAMIC_TYPE_SRP to allocate the   */\n        /**< key buffer for this structure and set keySz to the buffer size.  */\n        /**< The default function used by this implementation is a modified   */\n        /**< version of t_mgf1 that uses the proper hash function according   */\n        /**< to srp->type.                                                    */\n    void*   heap;                   /**< heap hint pointer                    */\n} Srp;\n\n/**\n * Initializes the Srp struct for usage.\n *\n * @param[out] srp   the Srp structure to be initialized.\n * @param[in]  type  the hash type to be used.\n * @param[in]  side  the side of the communication.\n *\n * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h\n */\nWOLFSSL_API int wc_SrpInit(Srp* srp, SrpType type, SrpSide side);\n\n/**\n * Releases the Srp struct resources after usage.\n *\n * @param[in,out] srp    the Srp structure to be terminated.\n */\nWOLFSSL_API void wc_SrpTerm(Srp* srp);\n\n/**\n * Sets the username.\n *\n * This function MUST be called after wc_SrpInit.\n *\n * @param[in,out] srp       the Srp structure.\n * @param[in]     username  the buffer containing the username.\n * @param[in]     size      the username size in bytes\n *\n * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h\n */\nWOLFSSL_API int wc_SrpSetUsername(Srp* srp, const byte* username, word32 size);\n\n\n/**\n * Sets the srp parameters based on the username.\n *\n * This function MUST be called after wc_SrpSetUsername.\n *\n * @param[in,out] srp       the Srp structure.\n * @param[in]     N         the Modulus. N = 2q+1, [q, N] are primes.\n * @param[in]     nSz       the N size in bytes.\n * @param[in]     g         the Generator modulo N.\n * @param[in]     gSz       the g size in bytes\n * @param[in]     salt      a small random salt. Specific for each username.\n * @param[in]     saltSz    the salt size in bytes\n *\n * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h\n */\nWOLFSSL_API int wc_SrpSetParams(Srp* srp, const byte* N,    word32 nSz,\n                                          const byte* g,    word32 gSz,\n                                          const byte* salt, word32 saltSz);\n\n/**\n * Sets the password.\n *\n * Setting the password does not persists the clear password data in the\n * srp structure. The client calculates x = H(salt + H(user:pswd)) and stores\n * it in the auth field.\n *\n * This function MUST be called after wc_SrpSetParams and is CLIENT SIDE ONLY.\n *\n * @param[in,out] srp       the Srp structure.\n * @param[in]     password  the buffer containing the password.\n * @param[in]     size      the password size in bytes.\n *\n * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h\n */\nWOLFSSL_API int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size);\n\n/**\n * Sets the verifier.\n *\n * This function MUST be called after wc_SrpSetParams and is SERVER SIDE ONLY.\n *\n * @param[in,out] srp       the Srp structure.\n * @param[in]     verifier  the buffer containing the verifier.\n * @param[in]     size      the verifier size in bytes.\n *\n * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h\n */\nWOLFSSL_API int wc_SrpSetVerifier(Srp* srp, const byte* verifier, word32 size);\n\n/**\n * Gets the verifier.\n *\n * The client calculates the verifier with v = g ^ x % N.\n * This function MAY be called after wc_SrpSetPassword and is CLIENT SIDE ONLY.\n *\n * @param[in,out] srp       the Srp structure.\n * @param[out]    verifier  the buffer to write the verifier.\n * @param[in,out] size      the buffer size in bytes. Will be updated with the\n *                          verifier size.\n *\n * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h\n */\nWOLFSSL_API int wc_SrpGetVerifier(Srp* srp, byte* verifier, word32* size);\n\n/**\n * Sets the private ephemeral value.\n *\n * The private ephemeral value is known as:\n *   a at the client side. a = random()\n *   b at the server side. b = random()\n * This function is handy for unit test cases or if the developer wants to use\n * an external random source to set the ephemeral value.\n * This function MAY be called before wc_SrpGetPublic.\n *\n * @param[in,out] srp       the Srp structure.\n * @param[in]     priv      the ephemeral value.\n * @param[in]     size      the private size in bytes.\n *\n * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h\n */\nWOLFSSL_API int wc_SrpSetPrivate(Srp* srp, const byte* priv, word32 size);\n\n/**\n * Gets the public ephemeral value.\n *\n * The public ephemeral value is known as:\n *   A at the client side. A = g ^ a % N\n *   B at the server side. B = (k * v + (g ˆ b % N)) % N\n * This function MUST be called after wc_SrpSetPassword or wc_SrpSetVerifier.\n *\n * @param[in,out] srp       the Srp structure.\n * @param[out]    pub       the buffer to write the public ephemeral value.\n * @param[in,out] size      the the buffer size in bytes. Will be updated with\n *                          the ephemeral value size.\n *\n * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h\n */\nWOLFSSL_API int wc_SrpGetPublic(Srp* srp, byte* pub, word32* size);\n\n\n/**\n * Computes the session key.\n *\n * The key can be accessed at srp->key after success.\n *\n * @param[in,out] srp               the Srp structure.\n * @param[in]     clientPubKey      the client's public ephemeral value.\n * @param[in]     clientPubKeySz    the client's public ephemeral value size.\n * @param[in]     serverPubKey      the server's public ephemeral value.\n * @param[in]     serverPubKeySz    the server's public ephemeral value size.\n *\n * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h\n */\nWOLFSSL_API int wc_SrpComputeKey(Srp* srp,\n                                 byte* clientPubKey, word32 clientPubKeySz,\n                                 byte* serverPubKey, word32 serverPubKeySz);\n\n/**\n * Gets the proof.\n *\n * This function MUST be called after wc_SrpComputeKey.\n *\n * @param[in,out] srp   the Srp structure.\n * @param[out]    proof the buffer to write the proof.\n * @param[in,out] size  the buffer size in bytes. Will be updated with the\n *                          proof size.\n *\n * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h\n */\nWOLFSSL_API int wc_SrpGetProof(Srp* srp, byte* proof, word32* size);\n\n/**\n * Verifies the peers proof.\n *\n * This function MUST be called before wc_SrpGetSessionKey.\n *\n * @param[in,out] srp   the Srp structure.\n * @param[in]     proof the peers proof.\n * @param[in]     size  the proof size in bytes.\n *\n * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h\n */\nWOLFSSL_API int wc_SrpVerifyPeersProof(Srp* srp, byte* proof, word32 size);\n\n#ifdef __cplusplus\n   } /* extern \"C\" */\n#endif\n\n#endif /* WOLFCRYPT_SRP_H */\n#endif /* WOLFCRYPT_HAVE_SRP */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/tfm.h",
    "content": "/* tfm.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n\n/*\n * Based on public domain TomsFastMath 0.10 by Tom St Denis, tomstdenis@iahu.ca,\n * http://math.libtomcrypt.com\n */\n\n\n/**\n *  Edited by Moises Guimaraes (moises.guimaraes@phoebus.com.br)\n *  to fit CyaSSL's needs.\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/tfm.h\n*/\n\n#ifndef WOLF_CRYPT_TFM_H\n#define WOLF_CRYPT_TFM_H\n\n#include <wolfssl/wolfcrypt/types.h>\n#ifndef CHAR_BIT\n    #include <limits.h>\n#endif\n\n#include <wolfssl/wolfcrypt/random.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifdef WOLFSSL_NO_ASM\n   #undef  TFM_NO_ASM\n   #define TFM_NO_ASM\n#endif\n\n#ifdef NO_64BIT\n   #undef  NO_TFM_64BIT\n   #define NO_TFM_64BIT\n#endif\n\n#ifndef NO_TFM_64BIT\n/* autodetect x86-64 and make sure we are using 64-bit digits with x86-64 asm */\n#if defined(__x86_64__)\n   #if defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM)\n       #error x86-64 detected, x86-32/SSE2/ARM optimizations are not valid!\n   #endif\n   #if !defined(TFM_X86_64) && !defined(TFM_NO_ASM)\n      #define TFM_X86_64\n   #endif\n#endif\n#if defined(TFM_X86_64)\n    #if !defined(FP_64BIT)\n       #define FP_64BIT\n    #endif\n#endif\n/* use 64-bit digit even if not using asm on x86_64 */\n#if defined(__x86_64__) && !defined(FP_64BIT)\n    #define FP_64BIT\n#endif\n/* if intel compiler doesn't provide 128 bit type don't turn on 64bit */\n#if defined(FP_64BIT) && defined(__INTEL_COMPILER) && !defined(HAVE___UINT128_T)\n    #undef FP_64BIT\n    #undef TFM_X86_64\n#endif\n#endif /* NO_TFM_64BIT */\n\n/* try to detect x86-32 */\n#if defined(__i386__) && !defined(TFM_SSE2)\n   #if defined(TFM_X86_64) || defined(TFM_ARM)\n       #error x86-32 detected, x86-64/ARM optimizations are not valid!\n   #endif\n   #if !defined(TFM_X86) && !defined(TFM_NO_ASM)\n      #define TFM_X86\n   #endif\n#endif\n\n/* make sure we're 32-bit for x86-32/sse/arm/ppc32 */\n#if (defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM) || defined(TFM_PPC32)) && defined(FP_64BIT)\n   #warning x86-32, SSE2 and ARM, PPC32 optimizations require 32-bit digits (undefining)\n   #undef FP_64BIT\n#endif\n\n/* multi asms? */\n#ifdef TFM_X86\n   #define TFM_ASM\n#endif\n#ifdef TFM_X86_64\n   #ifdef TFM_ASM\n      #error TFM_ASM already defined!\n   #endif\n   #define TFM_ASM\n#endif\n#ifdef TFM_SSE2\n   #ifdef TFM_ASM\n      #error TFM_ASM already defined!\n   #endif\n   #define TFM_ASM\n#endif\n#ifdef TFM_ARM\n   #ifdef TFM_ASM\n      #error TFM_ASM already defined!\n   #endif\n   #define TFM_ASM\n#endif\n#ifdef TFM_PPC32\n   #ifdef TFM_ASM\n      #error TFM_ASM already defined!\n   #endif\n   #define TFM_ASM\n#endif\n#ifdef TFM_PPC64\n   #ifdef TFM_ASM\n      #error TFM_ASM already defined!\n   #endif\n   #define TFM_ASM\n#endif\n#ifdef TFM_AVR32\n   #ifdef TFM_ASM\n      #error TFM_ASM already defined!\n   #endif\n   #define TFM_ASM\n#endif\n\n/* we want no asm? */\n#ifdef TFM_NO_ASM\n   #undef TFM_X86\n   #undef TFM_X86_64\n   #undef TFM_SSE2\n   #undef TFM_ARM\n   #undef TFM_PPC32\n   #undef TFM_PPC64\n   #undef TFM_AVR32\n   #undef TFM_ASM\n#endif\n\n/* ECC helpers */\n#ifdef TFM_ECC192\n   #ifdef FP_64BIT\n       #define TFM_MUL3\n       #define TFM_SQR3\n   #else\n       #define TFM_MUL6\n       #define TFM_SQR6\n   #endif\n#endif\n\n#ifdef TFM_ECC224\n   #ifdef FP_64BIT\n       #define TFM_MUL4\n       #define TFM_SQR4\n   #else\n       #define TFM_MUL7\n       #define TFM_SQR7\n   #endif\n#endif\n\n#ifdef TFM_ECC256\n   #ifdef FP_64BIT\n       #define TFM_MUL4\n       #define TFM_SQR4\n   #else\n       #define TFM_MUL8\n       #define TFM_SQR8\n   #endif\n#endif\n\n#ifdef TFM_ECC384\n   #ifdef FP_64BIT\n       #define TFM_MUL6\n       #define TFM_SQR6\n   #else\n       #define TFM_MUL12\n       #define TFM_SQR12\n   #endif\n#endif\n\n#ifdef TFM_ECC521\n   #ifdef FP_64BIT\n       #define TFM_MUL9\n       #define TFM_SQR9\n   #else\n       #define TFM_MUL17\n       #define TFM_SQR17\n   #endif\n#endif\n\n\n/* allow user to define on fp_digit, fp_word types */\n#ifndef WOLFSSL_BIGINT_TYPES\n\n/* some default configurations.\n */\n#if defined(WC_16BIT_CPU)\n   typedef unsigned int    fp_digit;\n   #define SIZEOF_FP_DIGIT 2\n   typedef unsigned long   fp_word;\n#elif defined(FP_64BIT)\n   /* for GCC only on supported platforms */\n   typedef unsigned long long fp_digit;   /* 64bit, 128 uses mode(TI) below */\n   #define SIZEOF_FP_DIGIT 8\n   typedef unsigned long      fp_word __attribute__ ((mode(TI)));\n#else\n\n   #ifndef NO_TFM_64BIT\n      #if defined(_MSC_VER) || defined(__BORLANDC__)\n         typedef unsigned __int64   ulong64;\n      #else\n         typedef unsigned long long ulong64;\n      #endif\n      typedef unsigned int       fp_digit;\n      #define SIZEOF_FP_DIGIT 4\n      typedef ulong64            fp_word;\n      #define FP_32BIT\n   #else\n      /* some procs like coldfire prefer not to place multiply into 64bit type\n         even though it exists */\n      typedef unsigned short     fp_digit;\n      #define SIZEOF_FP_DIGIT 2\n      typedef unsigned int       fp_word;\n   #endif\n#endif\n\n#endif /* WOLFSSL_BIGINT_TYPES */\n\n\n/* # of digits this is */\n#define DIGIT_BIT   ((CHAR_BIT) * SIZEOF_FP_DIGIT)\n\n/* Max size of any number in bits.  Basically the largest size you will be\n * multiplying should be half [or smaller] of FP_MAX_SIZE-four_digit\n *\n * It defaults to 4096-bits [allowing multiplications up to 2048x2048 bits ]\n */\n\n\n#ifndef FP_MAX_BITS\n    #define FP_MAX_BITS           4096\n#endif\n#define FP_MAX_SIZE           (FP_MAX_BITS+(8*DIGIT_BIT))\n\n/* will this lib work? */\n#if (CHAR_BIT & 7)\n   #error CHAR_BIT must be a multiple of eight.\n#endif\n#if FP_MAX_BITS % CHAR_BIT\n   #error FP_MAX_BITS must be a multiple of CHAR_BIT\n#endif\n\n#define FP_MASK    (fp_digit)(-1)\n#define FP_DIGIT_MAX FP_MASK\n#define FP_SIZE    (FP_MAX_SIZE/DIGIT_BIT)\n\n#define FP_MAX_PRIME_SIZE (FP_MAX_BITS/(2*CHAR_BIT))\n/* In terms of FP_MAX_BITS, it is double the size possible for a number\n * to allow for multiplication, divide that 2 out. Also divide by CHAR_BIT\n * to convert from bits to bytes. (Note, FP_PRIME_SIZE is the number of\n * values in the canned prime number list.) */\n\n/* signs */\n#define FP_ZPOS     0\n#define FP_NEG      1\n\n/* return codes */\n#define FP_OKAY      0\n#define FP_VAL      -1\n#define FP_MEM      -2\n#define FP_NOT_INF\t-3\n#define FP_WOULDBLOCK -4\n\n/* equalities */\n#define FP_LT        -1   /* less than */\n#define FP_EQ         0   /* equal to */\n#define FP_GT         1   /* greater than */\n\n/* replies */\n#define FP_YES        1   /* yes response */\n#define FP_NO         0   /* no response */\n\n#ifdef HAVE_WOLF_BIGINT\n    /* raw big integer */\n    typedef struct WC_BIGINT {\n        byte*   buf;\n        word32  len;\n        void*   heap;\n    } WC_BIGINT;\n    #define WOLF_BIGINT_DEFINED\n#endif\n\n/* a FP type */\ntypedef struct fp_int {\n    int      used;\n    int      sign;\n#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)\n    int      size;\n#endif\n    fp_digit dp[FP_SIZE];\n\n#ifdef HAVE_WOLF_BIGINT\n    struct WC_BIGINT raw; /* unsigned binary (big endian) */\n#endif\n} fp_int;\n\n/* Types */\ntypedef fp_digit mp_digit;\ntypedef fp_word  mp_word;\ntypedef fp_int   mp_int;\n\n\n/* wolf big int and common functions */\n#include <wolfssl/wolfcrypt/wolfmath.h>\n\n\n/* externally define this symbol to ignore the default settings, useful for changing the build from the make process */\n#ifndef TFM_ALREADY_SET\n\n/* do we want the large set of small multiplications ?\n   Enable these if you are going to be doing a lot of small (<= 16 digit) multiplications say in ECC\n   Or if you're on a 64-bit machine doing RSA as a 1024-bit integer == 16 digits ;-)\n */\n/* need to refactor the function */\n/*#define TFM_SMALL_SET */\n\n/* do we want huge code\n   Enable these if you are doing 20, 24, 28, 32, 48, 64 digit multiplications (useful for RSA)\n   Less important on 64-bit machines as 32 digits == 2048 bits\n */\n#if 0\n#define TFM_MUL3\n#define TFM_MUL4\n#define TFM_MUL6\n#define TFM_MUL7\n#define TFM_MUL8\n#define TFM_MUL9\n#define TFM_MUL12\n#define TFM_MUL17\n#endif\n#ifdef TFM_HUGE_SET\n#define TFM_MUL20\n#define TFM_MUL24\n#define TFM_MUL28\n#define TFM_MUL32\n#if (FP_MAX_BITS >= 6144) && defined(FP_64BIT)\n    #define TFM_MUL48\n#endif\n#if (FP_MAX_BITS >= 8192) && defined(FP_64BIT)\n    #define TFM_MUL64\n#endif\n#endif\n\n#if 0\n#define TFM_SQR3\n#define TFM_SQR4\n#define TFM_SQR6\n#define TFM_SQR7\n#define TFM_SQR8\n#define TFM_SQR9\n#define TFM_SQR12\n#define TFM_SQR17\n#endif\n#ifdef TFM_HUGE_SET\n#define TFM_SQR20\n#define TFM_SQR24\n#define TFM_SQR28\n#define TFM_SQR32\n#define TFM_SQR48\n#define TFM_SQR64\n#endif\n\n/* Optional math checks (enable WOLFSSL_DEBUG_MATH to print info) */\n/* #define TFM_CHECK */\n\n/* Is the target a P4 Prescott\n */\n/* #define TFM_PRESCOTT */\n\n/* Do we want timing resistant fp_exptmod() ?\n * This makes it slower but also timing invariant with respect to the exponent\n */\n/* #define TFM_TIMING_RESISTANT */\n\n#endif /* TFM_ALREADY_SET */\n\n/* functions */\n\n/* returns a TFM ident string useful for debugging... */\n/*const char *fp_ident(void);*/\n\n/* initialize [or zero] an fp int */\nvoid fp_init(fp_int *a);\nMP_API void fp_zero(fp_int *a);\nMP_API void fp_clear(fp_int *a); /* uses ForceZero to clear sensitive memory */\nMP_API void fp_forcezero (fp_int * a);\nMP_API void fp_free(fp_int* a);\n\n/* zero/even/odd ? */\n#define fp_iszero(a) (((a)->used == 0) ? FP_YES : FP_NO)\n#define fp_isone(a) \\\n    ((((a)->used == 1) && ((a)->dp[0] == 1)) ? FP_YES : FP_NO)\n#define fp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? FP_YES : FP_NO)\n#define fp_isodd(a)  (((a)->used > 0  && (((a)->dp[0] & 1) == 1)) ? FP_YES : FP_NO)\n#define fp_isneg(a)  (((a)->sign != 0) ? FP_YES : FP_NO)\n\n/* set to a small digit */\nvoid fp_set(fp_int *a, fp_digit b);\nvoid fp_set_int(fp_int *a, unsigned long b);\n\n/* check if a bit is set */\nint fp_is_bit_set(fp_int *a, fp_digit b);\n/* set the b bit to 1 */\nint fp_set_bit (fp_int * a, fp_digit b);\n\n/* copy from a to b */\nvoid fp_copy(fp_int *a, fp_int *b);\nvoid fp_init_copy(fp_int *a, fp_int *b);\n\n/* clamp digits */\n#define fp_clamp(a)   { while ((a)->used && (a)->dp[(a)->used-1] == 0) --((a)->used); (a)->sign = (a)->used ? (a)->sign : FP_ZPOS; }\n#define mp_clamp(a)   fp_clamp(a)\n#define mp_grow(a,s)  MP_OKAY\n\n/* negate and absolute */\n#define fp_neg(a, b)  { fp_copy(a, b); (b)->sign ^= 1; fp_clamp(b); }\n#define fp_abs(a, b)  { fp_copy(a, b); (b)->sign  = 0; }\n\n/* right shift x digits */\nvoid fp_rshd(fp_int *a, int x);\n\n/* right shift x bits */\nvoid fp_rshb(fp_int *a, int x);\n\n/* left shift x digits */\nvoid fp_lshd(fp_int *a, int x);\n\n/* signed comparison */\nint fp_cmp(fp_int *a, fp_int *b);\n\n/* unsigned comparison */\nint fp_cmp_mag(fp_int *a, fp_int *b);\n\n/* power of 2 operations */\nvoid fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d);\nvoid fp_mod_2d(fp_int *a, int b, fp_int *c);\nvoid fp_mul_2d(fp_int *a, int b, fp_int *c);\nvoid fp_2expt (fp_int *a, int b);\nvoid fp_mul_2(fp_int *a, fp_int *c);\nvoid fp_div_2(fp_int *a, fp_int *c);\n\n/* Counts the number of lsbs which are zero before the first zero bit */\nint fp_cnt_lsb(fp_int *a);\n\n/* c = a + b */\nvoid fp_add(fp_int *a, fp_int *b, fp_int *c);\n\n/* c = a - b */\nvoid fp_sub(fp_int *a, fp_int *b, fp_int *c);\n\n/* c = a * b */\nint fp_mul(fp_int *a, fp_int *b, fp_int *c);\n\n/* b = a*a  */\nint fp_sqr(fp_int *a, fp_int *b);\n\n/* a/b => cb + d == a */\nint fp_div(fp_int *a, fp_int *b, fp_int *c, fp_int *d);\n\n/* c = a mod b, 0 <= c < b  */\nint fp_mod(fp_int *a, fp_int *b, fp_int *c);\n\n/* compare against a single digit */\nint fp_cmp_d(fp_int *a, fp_digit b);\n\n/* c = a + b */\nvoid fp_add_d(fp_int *a, fp_digit b, fp_int *c);\n\n/* c = a - b */\nint fp_sub_d(fp_int *a, fp_digit b, fp_int *c);\n\n/* c = a * b */\nvoid fp_mul_d(fp_int *a, fp_digit b, fp_int *c);\n\n/* a/b => cb + d == a */\n/*int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d);*/\n\n/* c = a mod b, 0 <= c < b  */\n/*int fp_mod_d(fp_int *a, fp_digit b, fp_digit *c);*/\n\n/* ---> number theory <--- */\n/* d = a + b (mod c) */\n/*int fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);*/\n\n/* d = a - b (mod c) */\n/*int fp_submod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);*/\n\n/* d = a * b (mod c) */\nint fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);\n\n/* d = a - b (mod c) */\nint fp_submod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);\n\n/* d = a + b (mod c) */\nint fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);\n\n/* c = a * a (mod b) */\nint fp_sqrmod(fp_int *a, fp_int *b, fp_int *c);\n\n/* c = 1/a (mod b) */\nint fp_invmod(fp_int *a, fp_int *b, fp_int *c);\n\n/* c = (a, b) */\n/*int fp_gcd(fp_int *a, fp_int *b, fp_int *c);*/\n\n/* c = [a, b] */\n/*int fp_lcm(fp_int *a, fp_int *b, fp_int *c);*/\n\n/* setups the montgomery reduction */\nint fp_montgomery_setup(fp_int *a, fp_digit *mp);\n\n/* computes a = B**n mod b without division or multiplication useful for\n * normalizing numbers in a Montgomery system.\n */\nvoid fp_montgomery_calc_normalization(fp_int *a, fp_int *b);\n\n/* computes x/R == x (mod N) via Montgomery Reduction */\nint fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp);\n\n/* d = a**b (mod c) */\nint fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);\nint fp_exptmod_ex(fp_int *a, fp_int *b, int minDigits, fp_int *c, fp_int *d);\n\n#ifdef WC_RSA_NONBLOCK\n\nenum tfmExptModNbState {\n  TFM_EXPTMOD_NB_INIT = 0,\n  TFM_EXPTMOD_NB_MONT,\n  TFM_EXPTMOD_NB_MONT_RED,\n  TFM_EXPTMOD_NB_MONT_MUL,\n  TFM_EXPTMOD_NB_MONT_MOD,\n  TFM_EXPTMOD_NB_MONT_MODCHK,\n  TFM_EXPTMOD_NB_NEXT,\n  TFM_EXPTMOD_NB_MUL,\n  TFM_EXPTMOD_NB_MUL_RED,\n  TFM_EXPTMOD_NB_SQR,\n  TFM_EXPTMOD_NB_SQR_RED,\n  TFM_EXPTMOD_NB_RED,\n  TFM_EXPTMOD_NB_COUNT /* last item for total state count only */\n};\n\ntypedef struct {\n#ifndef WC_NO_CACHE_RESISTANT\n  fp_int   R[3];\n#else\n  fp_int   R[2];\n#endif\n  fp_digit buf;\n  fp_digit mp;\n  int bitcnt;\n  int digidx;\n  int y;\n  int state; /* tfmExptModNbState */\n#ifdef WC_RSA_NONBLOCK_TIME\n  word32 maxBlockInst; /* maximum instructions to block */\n  word32 totalInst;    /* tracks total instructions */\n#endif\n} exptModNb_t;\n\n#ifdef WC_RSA_NONBLOCK_TIME\nenum {\n  TFM_EXPTMOD_NB_STOP = 0,     /* stop and return FP_WOULDBLOCK */\n  TFM_EXPTMOD_NB_CONTINUE = 1, /* keep blocking */\n};\n#endif\n\n/* non-blocking version of timing resistant fp_exptmod function */\n/* supports cache resistance */\nint fp_exptmod_nb(exptModNb_t* nb, fp_int* G, fp_int* X, fp_int* P, fp_int* Y);\n\n#endif /* WC_RSA_NONBLOCK */\n\n/* primality stuff */\n\n/* perform a Miller-Rabin test of a to the base b and store result in \"result\" */\n/*void fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result);*/\n\n#define FP_PRIME_SIZE      256\n/* 256 trial divisions + 8 Miller-Rabins, returns FP_YES if probable prime  */\n/*int fp_isprime(fp_int *a);*/\n/* extended version of fp_isprime, do 't' Miller-Rabins instead of only 8 */\n/*int fp_isprime_ex(fp_int *a, int t, int* result);*/\n\n/* Primality generation flags */\n/*#define TFM_PRIME_BBS      0x0001 */ /* BBS style prime */\n/*#define TFM_PRIME_SAFE     0x0002 */ /* Safe prime (p-1)/2 == prime */\n/*#define TFM_PRIME_2MSB_OFF 0x0004 */ /* force 2nd MSB to 0 */\n/*#define TFM_PRIME_2MSB_ON  0x0008 */ /* force 2nd MSB to 1 */\n\n/* callback for fp_prime_random, should fill dst with random bytes and return how many read [up to len] */\n/*typedef int tfm_prime_callback(unsigned char *dst, int len, void *dat);*/\n\n/*#define fp_prime_random(a, t, size, bbs, cb, dat) fp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?TFM_PRIME_BBS:0, cb, dat)*/\n\n/*int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback cb, void *dat);*/\n\n/* radix conversions */\nint fp_count_bits(fp_int *a);\nint fp_leading_bit(fp_int *a);\n\nint fp_unsigned_bin_size(fp_int *a);\nvoid fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c);\nint fp_to_unsigned_bin(fp_int *a, unsigned char *b);\nint fp_to_unsigned_bin_len(fp_int *a, unsigned char *b, int c);\nint fp_to_unsigned_bin_at_pos(int x, fp_int *t, unsigned char *b);\n\n/*int fp_signed_bin_size(fp_int *a);*/\n/*void fp_read_signed_bin(fp_int *a, const unsigned char *b, int c);*/\n/*void fp_to_signed_bin(fp_int *a, unsigned char *b);*/\n\n/*int fp_read_radix(fp_int *a, char *str, int radix);*/\n/*int fp_toradix(fp_int *a, char *str, int radix);*/\n/*int fp_toradix_n(fp_int * a, char *str, int radix, int maxlen);*/\n\n\n/* VARIOUS LOW LEVEL STUFFS */\nvoid s_fp_add(fp_int *a, fp_int *b, fp_int *c);\nvoid s_fp_sub(fp_int *a, fp_int *b, fp_int *c);\nvoid fp_reverse(unsigned char *s, int len);\n\nint  fp_mul_comba(fp_int *a, fp_int *b, fp_int *c);\n\nint  fp_mul_comba_small(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba3(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba4(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba6(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba7(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba8(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba9(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba12(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba17(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba20(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba24(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba28(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba32(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba48(fp_int *a, fp_int *b, fp_int *c);\nint  fp_mul_comba64(fp_int *a, fp_int *b, fp_int *c);\nint  fp_sqr_comba(fp_int *a, fp_int *b);\nint  fp_sqr_comba_small(fp_int *a, fp_int *b);\nint  fp_sqr_comba3(fp_int *a, fp_int *b);\nint  fp_sqr_comba4(fp_int *a, fp_int *b);\nint  fp_sqr_comba6(fp_int *a, fp_int *b);\nint  fp_sqr_comba7(fp_int *a, fp_int *b);\nint  fp_sqr_comba8(fp_int *a, fp_int *b);\nint  fp_sqr_comba9(fp_int *a, fp_int *b);\nint  fp_sqr_comba12(fp_int *a, fp_int *b);\nint  fp_sqr_comba17(fp_int *a, fp_int *b);\nint  fp_sqr_comba20(fp_int *a, fp_int *b);\nint  fp_sqr_comba24(fp_int *a, fp_int *b);\nint  fp_sqr_comba28(fp_int *a, fp_int *b);\nint  fp_sqr_comba32(fp_int *a, fp_int *b);\nint  fp_sqr_comba48(fp_int *a, fp_int *b);\nint  fp_sqr_comba64(fp_int *a, fp_int *b);\n\n\n/**\n * Used by wolfSSL\n */\n\n/* Constants */\n#define MP_LT   FP_LT   /* less than    */\n#define MP_EQ   FP_EQ   /* equal to     */\n#define MP_GT   FP_GT   /* greater than */\n#define MP_VAL  FP_VAL  /* invalid */\n#define MP_MEM  FP_MEM  /* memory error */\n#define MP_NOT_INF FP_NOT_INF /* point not at infinity */\n#define MP_OKAY FP_OKAY /* ok result    */\n#define MP_NO   FP_NO   /* yes/no result */\n#define MP_YES  FP_YES  /* yes/no result */\n#define MP_ZPOS FP_ZPOS\n#define MP_NEG  FP_NEG\n#define MP_MASK FP_MASK\n\n/* Prototypes */\n#define mp_zero(a)   fp_zero(a)\n#define mp_isone(a)  fp_isone(a)\n#define mp_iseven(a) fp_iseven(a)\n#define mp_isneg(a)  fp_isneg(a)\n\n#define MP_RADIX_BIN  2\n#define MP_RADIX_OCT  8\n#define MP_RADIX_DEC  10\n#define MP_RADIX_HEX  16\n#define MP_RADIX_MAX  64\n\n#define mp_tobinary(M, S)  mp_toradix((M), (S), MP_RADIX_BIN)\n#define mp_tooctal(M, S)   mp_toradix((M), (S), MP_RADIX_OCT)\n#define mp_todecimal(M, S) mp_toradix((M), (S), MP_RADIX_DEC)\n#define mp_tohex(M, S)     mp_toradix((M), (S), MP_RADIX_HEX)\n\nMP_API int  mp_init (mp_int * a);\nMP_API void mp_clear (mp_int * a);\nMP_API void mp_free (mp_int * a);\nMP_API void mp_forcezero (mp_int * a);\nMP_API int  mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,\n                         mp_int* f);\n\nMP_API int  mp_add (mp_int * a, mp_int * b, mp_int * c);\nMP_API int  mp_sub (mp_int * a, mp_int * b, mp_int * c);\nMP_API int  mp_add_d (mp_int * a, mp_digit b, mp_int * c);\n\nMP_API int  mp_mul (mp_int * a, mp_int * b, mp_int * c);\nMP_API int  mp_mul_d (mp_int * a, mp_digit b, mp_int * c);\nMP_API int  mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d);\nMP_API int  mp_submod (mp_int* a, mp_int* b, mp_int* c, mp_int* d);\nMP_API int  mp_addmod (mp_int* a, mp_int* b, mp_int* c, mp_int* d);\nMP_API int  mp_mod(mp_int *a, mp_int *b, mp_int *c);\nMP_API int  mp_invmod(mp_int *a, mp_int *b, mp_int *c);\nMP_API int  mp_exptmod (mp_int * g, mp_int * x, mp_int * p, mp_int * y);\nMP_API int  mp_exptmod_ex (mp_int * g, mp_int * x, int minDigits, mp_int * p,\n                           mp_int * y);\nMP_API int  mp_mul_2d(mp_int *a, int b, mp_int *c);\nMP_API int  mp_2expt(mp_int* a, int b);\n\nMP_API int  mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d);\n\nMP_API int  mp_cmp(mp_int *a, mp_int *b);\nMP_API int  mp_cmp_d(mp_int *a, mp_digit b);\n\nMP_API int  mp_unsigned_bin_size(mp_int * a);\nMP_API int  mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c);\nMP_API int  mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b);\nMP_API int  mp_to_unsigned_bin (mp_int * a, unsigned char *b);\nMP_API int  mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c);\n\nMP_API int  mp_sub_d(fp_int *a, fp_digit b, fp_int *c);\nMP_API int  mp_copy(fp_int* a, fp_int* b);\nMP_API int  mp_isodd(mp_int* a);\nMP_API int  mp_iszero(mp_int* a);\nMP_API int  mp_count_bits(mp_int *a);\nMP_API int  mp_leading_bit(mp_int *a);\nMP_API int  mp_set_int(mp_int *a, unsigned long b);\nMP_API int  mp_is_bit_set (mp_int * a, mp_digit b);\nMP_API int  mp_set_bit (mp_int * a, mp_digit b);\nMP_API void mp_rshb(mp_int *a, int x);\nMP_API void mp_rshd(mp_int *a, int x);\nMP_API int mp_toradix (mp_int *a, char *str, int radix);\nMP_API int mp_radix_size (mp_int * a, int radix, int *size);\n\n#ifdef WOLFSSL_DEBUG_MATH\n    MP_API void mp_dump(const char* desc, mp_int* a, byte verbose);\n#else\n    #define mp_dump(desc, a, verbose)\n#endif\n\n#if !defined(NO_DSA) || defined(HAVE_ECC)\n    MP_API int mp_read_radix(mp_int* a, const char* str, int radix);\n#endif\n\n#ifdef HAVE_ECC\n    MP_API int mp_sqr(fp_int *a, fp_int *b);\n    MP_API int mp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp);\n    MP_API int mp_montgomery_setup(fp_int *a, fp_digit *rho);\n    MP_API int mp_div_2(fp_int * a, fp_int * b);\n    MP_API int mp_init_copy(fp_int * a, fp_int * b);\n#endif\n\n#if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DSA) || \\\n    defined(WOLFSSL_KEY_GEN)\n    MP_API int mp_set(fp_int *a, fp_digit b);\n#endif\n\n#if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || !defined(NO_RSA) || \\\n    !defined(NO_DSA) || !defined(NO_DH)\n    MP_API int mp_sqrmod(mp_int* a, mp_int* b, mp_int* c);\n    MP_API int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);\n#endif\n\n#if !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA) || defined(WOLFSSL_KEY_GEN)\nMP_API int  mp_prime_is_prime(mp_int* a, int t, int* result);\nMP_API int  mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng);\n#endif /* !NO_DH || !NO_DSA || !NO_RSA || WOLFSSL_KEY_GEN */\n#ifdef WOLFSSL_KEY_GEN\nMP_API int  mp_gcd(fp_int *a, fp_int *b, fp_int *c);\nMP_API int  mp_lcm(fp_int *a, fp_int *b, fp_int *c);\nMP_API int  mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap);\nMP_API int  mp_exch(mp_int *a, mp_int *b);\n#endif /* WOLFSSL_KEY_GEN */\n\nMP_API int  mp_cnt_lsb(fp_int *a);\nMP_API int  mp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d);\nMP_API int  mp_mod_d(fp_int* a, fp_digit b, fp_digit* c);\nMP_API int  mp_lshd (mp_int * a, int b);\nMP_API int  mp_abs(mp_int* a, mp_int* b);\n\nWOLFSSL_API word32 CheckRunTimeFastMath(void);\n\n/* If user uses RSA, DH, DSA, or ECC math lib directly then fast math FP_SIZE\n   must match, return 1 if a match otherwise 0 */\n#define CheckFastMathSettings() (FP_SIZE == CheckRunTimeFastMath())\n\n\n#ifdef __cplusplus\n   }\n#endif\n\n#endif  /* WOLF_CRYPT_TFM_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/types.h",
    "content": "/* types.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/types.h\n*/\n\n#ifndef WOLF_CRYPT_TYPES_H\n#define WOLF_CRYPT_TYPES_H\n\n    #include <wolfssl/wolfcrypt/settings.h>\n    #include <wolfssl/wolfcrypt/wc_port.h>\n\n    #ifdef __cplusplus\n        extern \"C\" {\n    #endif\n\n\n    #define WOLFSSL_ABI\n            /* Tag for all the APIs that are a part of the fixed ABI. */\n\n\n    #if defined(WORDS_BIGENDIAN)\n        #define BIG_ENDIAN_ORDER\n    #endif\n\n    #ifndef BIG_ENDIAN_ORDER\n        #define LITTLE_ENDIAN_ORDER\n    #endif\n\n    #ifndef WOLFSSL_TYPES\n        #ifndef byte\n            typedef unsigned char  byte;\n        #endif\n        #ifdef WC_16BIT_CPU\n            typedef unsigned int   word16;\n            typedef unsigned long  word32;\n        #else\n            typedef unsigned short word16;\n            typedef unsigned int   word32;\n        #endif\n        typedef byte           word24[3];\n    #endif\n\n\n    /* try to set SIZEOF_LONG or LONG_LONG if user didn't */\n    #if !defined(_MSC_VER) && !defined(__BCPLUSPLUS__) && !defined(__EMSCRIPTEN__)\n        #if !defined(SIZEOF_LONG_LONG) && !defined(SIZEOF_LONG)\n            #if (defined(__alpha__) || defined(__ia64__) || \\\n                defined(_ARCH_PPC64) || defined(__mips64) || \\\n                defined(__x86_64__) || \\\n                ((defined(sun) || defined(__sun)) && \\\n                 (defined(LP64) || defined(_LP64))))\n                /* long should be 64bit */\n                #define SIZEOF_LONG 8\n            #elif defined(__i386__) || defined(__CORTEX_M3__)\n                /* long long should be 64bit */\n                #define SIZEOF_LONG_LONG 8\n            #endif\n         #endif\n    #endif\n\n    #if defined(_MSC_VER) || defined(__BCPLUSPLUS__)\n        #define WORD64_AVAILABLE\n        #define W64LIT(x) x##ui64\n        typedef unsigned __int64 word64;\n    #elif defined(__EMSCRIPTEN__)\n        #define WORD64_AVAILABLE\n        #define W64LIT(x) x##ull\n        typedef unsigned long long word64;\n    #elif defined(SIZEOF_LONG) && SIZEOF_LONG == 8\n        #define WORD64_AVAILABLE\n        #define W64LIT(x) x##LL\n        typedef unsigned long word64;\n    #elif defined(SIZEOF_LONG_LONG) && SIZEOF_LONG_LONG == 8\n        #define WORD64_AVAILABLE\n        #define W64LIT(x) x##LL\n        typedef unsigned long long word64;\n    #elif defined(__SIZEOF_LONG_LONG__) && __SIZEOF_LONG_LONG__ == 8\n        #define WORD64_AVAILABLE\n        #define W64LIT(x) x##LL\n        typedef unsigned long long word64;\n    #endif\n\n#if !defined(NO_64BIT) && defined(WORD64_AVAILABLE) && !defined(WC_16BIT_CPU)\n    /* These platforms have 64-bit CPU registers.  */\n    #if (defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || \\\n         defined(__mips64)  || defined(__x86_64__) || defined(_M_X64)) || \\\n         defined(__aarch64__) || defined(__sparc64__) || \\\n        (defined(__riscv_xlen) && (__riscv_xlen == 64))\n        typedef word64 wolfssl_word;\n        #define WC_64BIT_CPU\n    #elif (defined(sun) || defined(__sun)) && \\\n          (defined(LP64) || defined(_LP64))\n        /* LP64 with GNU GCC compiler is reserved for when long int is 64 bits\n         * and int uses 32 bits. When using Solaris Studio sparc and __sparc are\n         * available for 32 bit detection but __sparc64__ could be missed. This\n         * uses LP64 for checking 64 bit CPU arch. */\n        typedef word64 wolfssl_word;\n        #define WC_64BIT_CPU\n    #else\n        typedef word32 wolfssl_word;\n        #ifdef WORD64_AVAILABLE\n            #define WOLFCRYPT_SLOW_WORD64\n        #endif\n    #endif\n\n#elif defined(WC_16BIT_CPU)\n        #undef WORD64_AVAILABLE\n        typedef word16 wolfssl_word;\n        #define MP_16BIT  /* for mp_int, mp_word needs to be twice as big as\n                             mp_digit, no 64 bit type so make mp_digit 16 bit */\n\n#else\n        #undef WORD64_AVAILABLE\n        typedef word32 wolfssl_word;\n        #define MP_16BIT  /* for mp_int, mp_word needs to be twice as big as\n                             mp_digit, no 64 bit type so make mp_digit 16 bit */\n#endif\n\n    enum {\n        WOLFSSL_WORD_SIZE  = sizeof(wolfssl_word),\n        WOLFSSL_BIT_SIZE   = 8,\n        WOLFSSL_WORD_BITS  = WOLFSSL_WORD_SIZE * WOLFSSL_BIT_SIZE\n    };\n\n    #define WOLFSSL_MAX_16BIT 0xffffU\n\n    /* use inlining if compiler allows */\n    #ifndef WC_INLINE\n    #ifndef NO_INLINE\n        #ifdef _MSC_VER\n            #define WC_INLINE __inline\n        #elif defined(__GNUC__)\n               #ifdef WOLFSSL_VXWORKS\n                   #define WC_INLINE __inline__\n               #else\n                   #define WC_INLINE inline\n               #endif\n        #elif defined(__IAR_SYSTEMS_ICC__)\n            #define WC_INLINE inline\n        #elif defined(THREADX)\n            #define WC_INLINE _Inline\n        #elif defined(__ghc__)\n            #ifndef __cplusplus\n                #define WC_INLINE __inline\n            #else\n                #define WC_INLINE inline\n            #endif\n        #else\n            #define WC_INLINE\n        #endif\n    #else\n        #define WC_INLINE\n    #endif\n    #endif\n\n    #if defined(HAVE_FIPS) || defined(HAVE_SELFTEST)\n        #define INLINE WC_INLINE\n    #endif\n\n\n    /* set up rotate style */\n    #if (defined(_MSC_VER) || defined(__BCPLUSPLUS__)) && \\\n        !defined(WOLFSSL_SGX) && !defined(INTIME_RTOS)\n        #define INTEL_INTRINSICS\n        #define FAST_ROTATE\n    #elif defined(__MWERKS__) && TARGET_CPU_PPC\n        #define PPC_INTRINSICS\n        #define FAST_ROTATE\n    #elif defined(__GNUC__)  && (defined(__i386__) || defined(__x86_64__))\n        /* GCC does peephole optimizations which should result in using rotate\n           instructions  */\n        #define FAST_ROTATE\n    #endif\n\n\n    /* set up thread local storage if available */\n    #ifdef HAVE_THREAD_LS\n        #if defined(_MSC_VER)\n            #define THREAD_LS_T __declspec(thread)\n        /* Thread local storage only in FreeRTOS v8.2.1 and higher */\n        #elif defined(FREERTOS) || defined(FREERTOS_TCP) || \\\n                                                         defined(WOLFSSL_ZEPHYR)\n            #define THREAD_LS_T\n        #else\n            #define THREAD_LS_T __thread\n        #endif\n    #else\n        #define THREAD_LS_T\n    #endif\n\n    /* GCC 7 has new switch() fall-through detection */\n    /* default to FALL_THROUGH stub */\n    #ifndef FALL_THROUGH\n    #define FALL_THROUGH\n\n    #if defined(__GNUC__)\n        #if ((__GNUC__ > 7) || ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 1)))\n            #undef  FALL_THROUGH\n            #define FALL_THROUGH __attribute__ ((fallthrough));\n        #endif\n    #endif\n    #endif /* FALL_THROUGH */\n\n    /* Micrium will use Visual Studio for compilation but not the Win32 API */\n    #if defined(_WIN32) && !defined(MICRIUM) && !defined(FREERTOS) && \\\n        !defined(FREERTOS_TCP) && !defined(EBSNET) && \\\n        !defined(WOLFSSL_UTASKER) && !defined(INTIME_RTOS)\n        #define USE_WINDOWS_API\n    #endif\n\n\n    /* idea to add global alloc override by Moises Guimaraes  */\n    /* default to libc stuff */\n    /* XREALLOC is used once in normal math lib, not in fast math lib */\n    /* XFREE on some embedded systems doesn't like free(0) so test  */\n    #if defined(HAVE_IO_POOL)\n        WOLFSSL_API void* XMALLOC(size_t n, void* heap, int type);\n        WOLFSSL_API void* XREALLOC(void *p, size_t n, void* heap, int type);\n        WOLFSSL_API void XFREE(void *p, void* heap, int type);\n    #elif (defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_INTEL_QA)) || \\\n          defined(HAVE_INTEL_QA_SYNC)\n        #ifndef HAVE_INTEL_QA_SYNC\n            #include <wolfssl/wolfcrypt/port/intel/quickassist_mem.h>\n            #undef USE_WOLFSSL_MEMORY\n            #ifdef WOLFSSL_DEBUG_MEMORY\n                #define XMALLOC(s, h, t)     IntelQaMalloc((s), (h), (t), __func__, __LINE__)\n                #define XFREE(p, h, t)       IntelQaFree((p), (h), (t), __func__, __LINE__)\n                #define XREALLOC(p, n, h, t) IntelQaRealloc((p), (n), (h), (t), __func__, __LINE__)\n            #else\n                #define XMALLOC(s, h, t)     IntelQaMalloc((s), (h), (t))\n                #define XFREE(p, h, t)       IntelQaFree((p), (h), (t))\n                #define XREALLOC(p, n, h, t) IntelQaRealloc((p), (n), (h), (t))\n            #endif /* WOLFSSL_DEBUG_MEMORY */\n        #else\n            #include <wolfssl/wolfcrypt/port/intel/quickassist_sync.h>\n            #undef USE_WOLFSSL_MEMORY\n            #ifdef WOLFSSL_DEBUG_MEMORY\n                #define XMALLOC(s, h, t)     wc_CryptoCb_IntelQaMalloc((s), (h), (t), __func__, __LINE__)\n                #define XFREE(p, h, t)       wc_CryptoCb_IntelQaFree((p), (h), (t), __func__, __LINE__)\n                #define XREALLOC(p, n, h, t) wc_CryptoCb_IntelQaRealloc((p), (n), (h), (t), __func__, __LINE__)\n            #else\n                #define XMALLOC(s, h, t)     wc_CryptoCb_IntelQaMalloc((s), (h), (t))\n                #define XFREE(p, h, t)       wc_CryptoCb_IntelQaFree((p), (h), (t))\n                #define XREALLOC(p, n, h, t) wc_CryptoCb_IntelQaRealloc((p), (n), (h), (t))\n            #endif /* WOLFSSL_DEBUG_MEMORY */\n        #endif\n    #elif defined(XMALLOC_USER)\n        /* prototypes for user heap override functions */\n        #include <stddef.h>  /* for size_t */\n        extern void *XMALLOC(size_t n, void* heap, int type);\n        extern void *XREALLOC(void *p, size_t n, void* heap, int type);\n        extern void XFREE(void *p, void* heap, int type);\n    #elif defined(WOLFSSL_MEMORY_LOG)\n        #define XMALLOC(n, h, t)        xmalloc(n, h, t, __func__, __FILE__, __LINE__)\n        #define XREALLOC(p, n, h, t)    xrealloc(p, n, h, t, __func__,  __FILE__, __LINE__)\n        #define XFREE(p, h, t)          xfree(p, h, t, __func__, __FILE__, __LINE__)\n\n        /* prototypes for user heap override functions */\n        #include <stddef.h>  /* for size_t */\n        #include <stdlib.h>\n        WOLFSSL_API void *xmalloc(size_t n, void* heap, int type,\n                const char* func, const char* file, unsigned int line);\n        WOLFSSL_API void *xrealloc(void *p, size_t n, void* heap, int type,\n                const char* func, const char* file, unsigned int line);\n        WOLFSSL_API void xfree(void *p, void* heap, int type, const char* func,\n                const char* file, unsigned int line);\n    #elif defined(XMALLOC_OVERRIDE)\n        /* override the XMALLOC, XFREE and XREALLOC macros */\n    #elif defined(WOLFSSL_TELIT_M2MB)\n        /* Telit M2MB SDK requires use m2mb_os API's, not std malloc/free */\n        /* Use of malloc/free will cause CPU reboot */\n        #define XMALLOC(s, h, t)     ((void)h, (void)t, m2mb_os_malloc((s)))\n        #define XFREE(p, h, t)       {void* xp = (p); if((xp)) m2mb_os_free((xp));}\n        #define XREALLOC(p, n, h, t) m2mb_os_realloc((p), (n))\n\n    #elif defined(NO_WOLFSSL_MEMORY)\n        #ifdef WOLFSSL_NO_MALLOC\n            /* this platform does not support heap use */\n            #ifdef WOLFSSL_MALLOC_CHECK\n                #include <stdio.h>\n                static inline void* malloc_check(size_t sz) {\n                    printf(\"wolfSSL_malloc failed\");\n                    return NULL;\n                };\n                #define XMALLOC(s, h, t)     malloc_check((s))\n                #define XFREE(p, h, t)\n                #define XREALLOC(p, n, h, t) (NULL)\n            #else\n                #define XMALLOC(s, h, t)     (NULL)\n                #define XFREE(p, h, t)\n                #define XREALLOC(p, n, h, t) (NULL)\n            #endif\n        #else\n        /* just use plain C stdlib stuff if desired */\n        #include <stdlib.h>\n        #define XMALLOC(s, h, t)     malloc((s))\n        #define XFREE(p, h, t)       {void* xp = (p); if((xp)) free((xp));}\n        #define XREALLOC(p, n, h, t) realloc((p), (n))\n        #endif\n    #elif !defined(MICRIUM_MALLOC) && !defined(EBSNET) \\\n            && !defined(WOLFSSL_SAFERTOS) && !defined(FREESCALE_MQX) \\\n            && !defined(FREESCALE_KSDK_MQX) && !defined(FREESCALE_FREE_RTOS) \\\n            && !defined(WOLFSSL_LEANPSK) && !defined(WOLFSSL_uITRON4)\n        /* default C runtime, can install different routines at runtime via cbs */\n        #include <wolfssl/wolfcrypt/memory.h>\n        #ifdef WOLFSSL_STATIC_MEMORY\n            #ifdef WOLFSSL_DEBUG_MEMORY\n                #define XMALLOC(s, h, t)     wolfSSL_Malloc((s), (h), (t), __func__, __LINE__)\n                #define XFREE(p, h, t)       {void* xp = (p); if((xp)) wolfSSL_Free((xp), (h), (t), __func__, __LINE__);}\n                #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n), (h), (t), __func__, __LINE__)\n            #else\n                #define XMALLOC(s, h, t)     wolfSSL_Malloc((s), (h), (t))\n                #define XFREE(p, h, t)       {void* xp = (p); if((xp)) wolfSSL_Free((xp), (h), (t));}\n                #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n), (h), (t))\n            #endif /* WOLFSSL_DEBUG_MEMORY */\n        #elif !defined(FREERTOS) && !defined(FREERTOS_TCP)\n            #ifdef WOLFSSL_DEBUG_MEMORY\n                #define XMALLOC(s, h, t)     ((void)h, (void)t, wolfSSL_Malloc((s), __func__, __LINE__))\n                #define XFREE(p, h, t)       {void* xp = (p); if((xp)) wolfSSL_Free((xp), __func__, __LINE__);}\n                #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n), __func__, __LINE__)\n            #else\n                #define XMALLOC(s, h, t)     ((void)h, (void)t, wolfSSL_Malloc((s)))\n                #define XFREE(p, h, t)       {void* xp = (p); if((xp)) wolfSSL_Free((xp));}\n                #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n))\n            #endif /* WOLFSSL_DEBUG_MEMORY */\n        #endif /* WOLFSSL_STATIC_MEMORY */\n    #endif\n\n    /* declare/free variable handling for async */\n    #ifdef WOLFSSL_ASYNC_CRYPT\n        #define DECLARE_VAR(VAR_NAME, VAR_TYPE, VAR_SIZE, HEAP) \\\n            VAR_TYPE* VAR_NAME = (VAR_TYPE*)XMALLOC(sizeof(VAR_TYPE) * VAR_SIZE, (HEAP), DYNAMIC_TYPE_WOLF_BIGINT);\n        #define DECLARE_VAR_INIT(VAR_NAME, VAR_TYPE, VAR_SIZE, INIT_VALUE, HEAP) \\\n            VAR_TYPE* VAR_NAME = ({ \\\n                VAR_TYPE* ptr = (VAR_TYPE*)XMALLOC(sizeof(VAR_TYPE) * VAR_SIZE, (HEAP), DYNAMIC_TYPE_WOLF_BIGINT); \\\n                if (ptr && INIT_VALUE) { \\\n                    XMEMCPY(ptr, INIT_VALUE, sizeof(VAR_TYPE) * VAR_SIZE); \\\n                } \\\n                ptr; \\\n            })\n        #define DECLARE_ARRAY(VAR_NAME, VAR_TYPE, VAR_ITEMS, VAR_SIZE, HEAP) \\\n            VAR_TYPE* VAR_NAME[VAR_ITEMS]; \\\n            int idx##VAR_NAME; \\\n            for (idx##VAR_NAME=0; idx##VAR_NAME<VAR_ITEMS; idx##VAR_NAME++) { \\\n                VAR_NAME[idx##VAR_NAME] = (VAR_TYPE*)XMALLOC(VAR_SIZE, (HEAP), DYNAMIC_TYPE_WOLF_BIGINT); \\\n            }\n        #define FREE_VAR(VAR_NAME, HEAP) \\\n            XFREE(VAR_NAME, (HEAP), DYNAMIC_TYPE_WOLF_BIGINT);\n        #define FREE_ARRAY(VAR_NAME, VAR_ITEMS, HEAP) \\\n            for (idx##VAR_NAME=0; idx##VAR_NAME<VAR_ITEMS; idx##VAR_NAME++) { \\\n                XFREE(VAR_NAME[idx##VAR_NAME], (HEAP), DYNAMIC_TYPE_WOLF_BIGINT); \\\n            }\n\n        #define DECLARE_ARRAY_DYNAMIC_DEC(VAR_NAME, VAR_TYPE, VAR_ITEMS, VAR_SIZE, HEAP) \\\n            DECLARE_ARRAY(VAR_NAME, VAR_TYPE, VAR_ITEMS, VAR_SIZE, HEAP)\n        #define DECLARE_ARRAY_DYNAMIC_EXE(VAR_NAME, VAR_TYPE, VAR_ITEMS, VAR_SIZE, HEAP)\n        #define FREE_ARRAY_DYNAMIC(VAR_NAME, VAR_ITEMS, HEAP) \\\n            FREE_ARRAY(VAR_NAME, VAR_ITEMS, HEAP)\n    #else\n        #define DECLARE_VAR(VAR_NAME, VAR_TYPE, VAR_SIZE, HEAP) \\\n            VAR_TYPE VAR_NAME[VAR_SIZE]\n        #define DECLARE_VAR_INIT(VAR_NAME, VAR_TYPE, VAR_SIZE, INIT_VALUE, HEAP) \\\n            VAR_TYPE* VAR_NAME = (VAR_TYPE*)INIT_VALUE\n        #define DECLARE_ARRAY(VAR_NAME, VAR_TYPE, VAR_ITEMS, VAR_SIZE, HEAP) \\\n            VAR_TYPE VAR_NAME[VAR_ITEMS][VAR_SIZE]\n        #define FREE_VAR(VAR_NAME, HEAP) /* nothing to free, its stack */\n        #define FREE_ARRAY(VAR_NAME, VAR_ITEMS, HEAP)  /* nothing to free, its stack */\n\n        #define DECLARE_ARRAY_DYNAMIC_DEC(VAR_NAME, VAR_TYPE, VAR_ITEMS, VAR_SIZE, HEAP) \\\n            VAR_TYPE* VAR_NAME[VAR_ITEMS]; \\\n            int idx##VAR_NAME;\n        #define DECLARE_ARRAY_DYNAMIC_EXE(VAR_NAME, VAR_TYPE, VAR_ITEMS, VAR_SIZE, HEAP) \\\n            for (idx##VAR_NAME=0; idx##VAR_NAME<VAR_ITEMS; idx##VAR_NAME++) { \\\n                VAR_NAME[idx##VAR_NAME] = (VAR_TYPE*)XMALLOC(VAR_SIZE, (HEAP), DYNAMIC_TYPE_TMP_BUFFER); \\\n            }\n        #define FREE_ARRAY_DYNAMIC(VAR_NAME, VAR_ITEMS, HEAP) \\\n            for (idx##VAR_NAME=0; idx##VAR_NAME<VAR_ITEMS; idx##VAR_NAME++) { \\\n                XFREE(VAR_NAME[idx##VAR_NAME], (HEAP), DYNAMIC_TYPE_TMP_BUFFER); \\\n            }\n    #endif\n\n    #if !defined(USE_WOLF_STRTOK) && \\\n            ((defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)) || \\\n             defined(WOLFSSL_TIRTOS) || defined(WOLF_C99))\n        #define USE_WOLF_STRTOK\n    #endif\n    #if !defined(USE_WOLF_STRSEP) && (defined(WOLF_C99))\n        #define USE_WOLF_STRSEP\n    #endif\n\n    #ifndef STRING_USER\n        #include <string.h>\n        #define XMEMCPY(d,s,l)    memcpy((d),(s),(l))\n        #define XMEMSET(b,c,l)    memset((b),(c),(l))\n        #define XMEMCMP(s1,s2,n)  memcmp((s1),(s2),(n))\n        #define XMEMMOVE(d,s,l)   memmove((d),(s),(l))\n\n        #define XSTRLEN(s1)       strlen((s1))\n        #define XSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n))\n        /* strstr, strncmp, and strncat only used by wolfSSL proper,\n         * not required for wolfCrypt only */\n        #define XSTRSTR(s1,s2)    strstr((s1),(s2))\n        #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n))\n        #define XSTRNCMP(s1,s2,n) strncmp((s1),(s2),(n))\n        #define XSTRNCAT(s1,s2,n) strncat((s1),(s2),(n))\n\n        #ifdef USE_WOLF_STRSEP\n            #define XSTRSEP(s1,d) wc_strsep((s1),(d))\n        #else\n            #define XSTRSEP(s1,d) strsep((s1),(d))\n        #endif\n\n        #ifndef XSTRNCASECMP\n        #if defined(MICROCHIP_PIC32) || defined(WOLFSSL_TIRTOS) || \\\n                defined(WOLFSSL_ZEPHYR)\n            /* XC32 does not support strncasecmp, so use case sensitive one */\n            #define XSTRNCASECMP(s1,s2,n) strncmp((s1),(s2),(n))\n        #elif defined(USE_WINDOWS_API) || defined(FREERTOS_TCP_WINSIM)\n            #define XSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n))\n        #else\n            #if defined(HAVE_STRINGS_H) && defined(WOLF_C99) && \\\n                !defined(WOLFSSL_SGX)\n                #include <strings.h>\n            #endif\n            #if defined(WOLFSSL_DEOS)\n                #define XSTRNCASECMP(s1,s2,n) strnicmp((s1),(s2),(n))\n            #else\n                #define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))\n            #endif\n        #endif\n        #endif /* !XSTRNCASECMP */\n\n        /* snprintf is used in asn.c for GetTimeString, PKCS7 test, and when\n           debugging is turned on */\n        #ifndef USE_WINDOWS_API\n            #ifndef XSNPRINTF\n            #if defined(NO_FILESYSTEM) && (defined(OPENSSL_EXTRA) || \\\n                   defined(HAVE_PKCS7)) && !defined(NO_STDIO_FILESYSTEM)\n                /* case where stdio is not included else where but is needed\n                   for snprintf */\n                #include <stdio.h>\n            #endif\n            #define XSNPRINTF snprintf\n            #endif\n        #else\n            #if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__)\n                #if defined(_MSC_VER) && (_MSC_VER >= 1900)\n                    /* Beginning with the UCRT in Visual Studio 2015 and\n                       Windows 10, snprintf is no longer identical to\n                       _snprintf. The snprintf function behavior is now\n                       C99 standard compliant. */\n                    #define XSNPRINTF snprintf\n                #else\n                    /* 4996 warning to use MS extensions e.g., _sprintf_s\n                       instead of _snprintf */\n                    #pragma warning(disable: 4996)\n                    static WC_INLINE\n                    int xsnprintf(char *buffer, size_t bufsize,\n                            const char *format, ...) {\n                        va_list ap;\n                        int ret;\n\n                        if ((int)bufsize <= 0) return -1;\n                        va_start(ap, format);\n                        ret = vsnprintf(buffer, bufsize, format, ap);\n                        if (ret >= (int)bufsize)\n                            ret = -1;\n                        va_end(ap);\n                        return ret;\n                    }\n                    #define XSNPRINTF xsnprintf\n                #endif /* (_MSC_VER >= 1900) */\n            #endif /* _MSC_VER || __CYGWIN__ || __MINGW32__ */\n        #endif /* USE_WINDOWS_API */\n\n        #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) \\\n                    || defined(HAVE_ALPN)\n            /* use only Thread Safe version of strtok */\n            #if defined(USE_WOLF_STRTOK)\n                #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr))\n            #elif defined(USE_WINDOWS_API) || defined(INTIME_RTOS)\n                #define XSTRTOK(s1,d,ptr) strtok_s((s1),(d),(ptr))\n            #else\n                #define XSTRTOK(s1,d,ptr) strtok_r((s1),(d),(ptr))\n            #endif\n        #endif\n\n        #if defined(WOLFSSL_CERT_EXT) || defined(HAVE_OCSP) || \\\n            defined(HAVE_CRL_IO) || defined(HAVE_HTTP_CLIENT) || \\\n            !defined(NO_CRYPT_BENCHMARK)\n\n            #ifndef XATOI /* if custom XATOI is not already defined */\n                #include <stdlib.h>\n                #define XATOI(s)          atoi((s))\n            #endif\n        #endif\n    #endif\n\n    #ifdef USE_WOLF_STRTOK\n        WOLFSSL_API char* wc_strtok(char *str, const char *delim, char **nextp);\n    #endif\n    #ifdef USE_WOLF_STRSEP\n        WOLFSSL_API char* wc_strsep(char **stringp, const char *delim);\n    #endif\n\n    #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \\\n        !defined(NO_STDIO_FILESYSTEM)\n        #ifndef XGETENV\n            #include <stdlib.h>\n            #define XGETENV getenv\n        #endif\n    #endif /* OPENSSL_EXTRA */\n\n    #ifndef CTYPE_USER\n        #include <ctype.h>\n        #if defined(HAVE_ECC) || defined(HAVE_OCSP) || \\\n            defined(WOLFSSL_KEY_GEN) || !defined(NO_DSA)\n            #define XTOUPPER(c)     toupper((c))\n            #define XISALPHA(c)     isalpha((c))\n        #endif\n        /* needed by wolfSSL_check_domain_name() */\n        #define XTOLOWER(c)      tolower((c))\n    #endif\n\n\n    /* memory allocation types for user hints */\n    enum {\n        DYNAMIC_TYPE_CA           = 1,\n        DYNAMIC_TYPE_CERT         = 2,\n        DYNAMIC_TYPE_KEY          = 3,\n        DYNAMIC_TYPE_FILE         = 4,\n        DYNAMIC_TYPE_SUBJECT_CN   = 5,\n        DYNAMIC_TYPE_PUBLIC_KEY   = 6,\n        DYNAMIC_TYPE_SIGNER       = 7,\n        DYNAMIC_TYPE_NONE         = 8,\n        DYNAMIC_TYPE_BIGINT       = 9,\n        DYNAMIC_TYPE_RSA          = 10,\n        DYNAMIC_TYPE_METHOD       = 11,\n        DYNAMIC_TYPE_OUT_BUFFER   = 12,\n        DYNAMIC_TYPE_IN_BUFFER    = 13,\n        DYNAMIC_TYPE_INFO         = 14,\n        DYNAMIC_TYPE_DH           = 15,\n        DYNAMIC_TYPE_DOMAIN       = 16,\n        DYNAMIC_TYPE_SSL          = 17,\n        DYNAMIC_TYPE_CTX          = 18,\n        DYNAMIC_TYPE_WRITEV       = 19,\n        DYNAMIC_TYPE_OPENSSL      = 20,\n        DYNAMIC_TYPE_DSA          = 21,\n        DYNAMIC_TYPE_CRL          = 22,\n        DYNAMIC_TYPE_REVOKED      = 23,\n        DYNAMIC_TYPE_CRL_ENTRY    = 24,\n        DYNAMIC_TYPE_CERT_MANAGER = 25,\n        DYNAMIC_TYPE_CRL_MONITOR  = 26,\n        DYNAMIC_TYPE_OCSP_STATUS  = 27,\n        DYNAMIC_TYPE_OCSP_ENTRY   = 28,\n        DYNAMIC_TYPE_ALTNAME      = 29,\n        DYNAMIC_TYPE_SUITES       = 30,\n        DYNAMIC_TYPE_CIPHER       = 31,\n        DYNAMIC_TYPE_RNG          = 32,\n        DYNAMIC_TYPE_ARRAYS       = 33,\n        DYNAMIC_TYPE_DTLS_POOL    = 34,\n        DYNAMIC_TYPE_SOCKADDR     = 35,\n        DYNAMIC_TYPE_LIBZ         = 36,\n        DYNAMIC_TYPE_ECC          = 37,\n        DYNAMIC_TYPE_TMP_BUFFER   = 38,\n        DYNAMIC_TYPE_DTLS_MSG     = 39,\n        DYNAMIC_TYPE_X509         = 40,\n        DYNAMIC_TYPE_TLSX         = 41,\n        DYNAMIC_TYPE_OCSP         = 42,\n        DYNAMIC_TYPE_SIGNATURE    = 43,\n        DYNAMIC_TYPE_HASHES       = 44,\n        DYNAMIC_TYPE_SRP          = 45,\n        DYNAMIC_TYPE_COOKIE_PWD   = 46,\n        DYNAMIC_TYPE_USER_CRYPTO  = 47,\n        DYNAMIC_TYPE_OCSP_REQUEST = 48,\n        DYNAMIC_TYPE_X509_EXT     = 49,\n        DYNAMIC_TYPE_X509_STORE   = 50,\n        DYNAMIC_TYPE_X509_CTX     = 51,\n        DYNAMIC_TYPE_URL          = 52,\n        DYNAMIC_TYPE_DTLS_FRAG    = 53,\n        DYNAMIC_TYPE_DTLS_BUFFER  = 54,\n        DYNAMIC_TYPE_SESSION_TICK = 55,\n        DYNAMIC_TYPE_PKCS         = 56,\n        DYNAMIC_TYPE_MUTEX        = 57,\n        DYNAMIC_TYPE_PKCS7        = 58,\n        DYNAMIC_TYPE_AES_BUFFER   = 59,\n        DYNAMIC_TYPE_WOLF_BIGINT  = 60,\n        DYNAMIC_TYPE_ASN1         = 61,\n        DYNAMIC_TYPE_LOG          = 62,\n        DYNAMIC_TYPE_WRITEDUP     = 63,\n        DYNAMIC_TYPE_PRIVATE_KEY  = 64,\n        DYNAMIC_TYPE_HMAC         = 65,\n        DYNAMIC_TYPE_ASYNC        = 66,\n        DYNAMIC_TYPE_ASYNC_NUMA   = 67,\n        DYNAMIC_TYPE_ASYNC_NUMA64 = 68,\n        DYNAMIC_TYPE_CURVE25519   = 69,\n        DYNAMIC_TYPE_ED25519      = 70,\n        DYNAMIC_TYPE_SECRET       = 71,\n        DYNAMIC_TYPE_DIGEST       = 72,\n        DYNAMIC_TYPE_RSA_BUFFER   = 73,\n        DYNAMIC_TYPE_DCERT        = 74,\n        DYNAMIC_TYPE_STRING       = 75,\n        DYNAMIC_TYPE_PEM          = 76,\n        DYNAMIC_TYPE_DER          = 77,\n        DYNAMIC_TYPE_CERT_EXT     = 78,\n        DYNAMIC_TYPE_ALPN         = 79,\n        DYNAMIC_TYPE_ENCRYPTEDINFO= 80,\n        DYNAMIC_TYPE_DIRCTX       = 81,\n        DYNAMIC_TYPE_HASHCTX      = 82,\n        DYNAMIC_TYPE_SEED         = 83,\n        DYNAMIC_TYPE_SYMMETRIC_KEY= 84,\n        DYNAMIC_TYPE_ECC_BUFFER   = 85,\n        DYNAMIC_TYPE_QSH          = 86,\n        DYNAMIC_TYPE_SALT         = 87,\n        DYNAMIC_TYPE_HASH_TMP     = 88,\n        DYNAMIC_TYPE_BLOB         = 89,\n        DYNAMIC_TYPE_NAME_ENTRY   = 90,\n        DYNAMIC_TYPE_SNIFFER_SERVER     = 1000,\n        DYNAMIC_TYPE_SNIFFER_SESSION    = 1001,\n        DYNAMIC_TYPE_SNIFFER_PB         = 1002,\n        DYNAMIC_TYPE_SNIFFER_PB_BUFFER  = 1003,\n        DYNAMIC_TYPE_SNIFFER_TICKET_ID  = 1004,\n        DYNAMIC_TYPE_SNIFFER_NAMED_KEY  = 1005,\n    };\n\n    /* max error buffer string size */\n    #ifndef WOLFSSL_MAX_ERROR_SZ\n        #define WOLFSSL_MAX_ERROR_SZ 80\n    #endif\n\n    /* stack protection */\n    enum {\n        MIN_STACK_BUFFER = 8\n    };\n\n\n    /* Algorithm Types */\n    enum wc_AlgoType {\n        WC_ALGO_TYPE_NONE = 0,\n        WC_ALGO_TYPE_HASH = 1,\n        WC_ALGO_TYPE_CIPHER = 2,\n        WC_ALGO_TYPE_PK = 3,\n        WC_ALGO_TYPE_RNG = 4,\n        WC_ALGO_TYPE_SEED = 5,\n        WC_ALGO_TYPE_HMAC = 6,\n\n        WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_HMAC\n    };\n\n    /* hash types */\n    enum wc_HashType {\n    #if defined(HAVE_SELFTEST) || defined(HAVE_FIPS)\n        /* In selftest build, WC_* types are not mapped to WC_HASH_TYPE types.\n         * Values here are based on old selftest hmac.h enum, with additions.\n         * These values are fixed for backwards FIPS compatibility */\n        WC_HASH_TYPE_NONE = 15,\n        WC_HASH_TYPE_MD2 = 16,\n        WC_HASH_TYPE_MD4 = 17,\n        WC_HASH_TYPE_MD5 = 0,\n        WC_HASH_TYPE_SHA = 1, /* SHA-1 (not old SHA-0) */\n        WC_HASH_TYPE_SHA224 = 8,\n        WC_HASH_TYPE_SHA256 = 2,\n        WC_HASH_TYPE_SHA384 = 5,\n        WC_HASH_TYPE_SHA512 = 4,\n        WC_HASH_TYPE_MD5_SHA = 18,\n        WC_HASH_TYPE_SHA3_224 = 10,\n        WC_HASH_TYPE_SHA3_256 = 11,\n        WC_HASH_TYPE_SHA3_384 = 12,\n        WC_HASH_TYPE_SHA3_512 = 13,\n        WC_HASH_TYPE_BLAKE2B = 14,\n        WC_HASH_TYPE_BLAKE2S = 19,\n\n        WC_HASH_TYPE_MAX = WC_HASH_TYPE_BLAKE2S\n    #else\n        WC_HASH_TYPE_NONE = 0,\n        WC_HASH_TYPE_MD2 = 1,\n        WC_HASH_TYPE_MD4 = 2,\n        WC_HASH_TYPE_MD5 = 3,\n        WC_HASH_TYPE_SHA = 4, /* SHA-1 (not old SHA-0) */\n        WC_HASH_TYPE_SHA224 = 5,\n        WC_HASH_TYPE_SHA256 = 6,\n        WC_HASH_TYPE_SHA384 = 7,\n        WC_HASH_TYPE_SHA512 = 8,\n        WC_HASH_TYPE_MD5_SHA = 9,\n        WC_HASH_TYPE_SHA3_224 = 10,\n        WC_HASH_TYPE_SHA3_256 = 11,\n        WC_HASH_TYPE_SHA3_384 = 12,\n        WC_HASH_TYPE_SHA3_512 = 13,\n        WC_HASH_TYPE_BLAKE2B = 14,\n        WC_HASH_TYPE_BLAKE2S = 15,\n\n        WC_HASH_TYPE_MAX = WC_HASH_TYPE_BLAKE2S\n    #endif /* HAVE_SELFTEST */\n    };\n\n    /* cipher types */\n    enum wc_CipherType {\n        WC_CIPHER_NONE = 0,\n        WC_CIPHER_AES = 1,\n        WC_CIPHER_AES_CBC = 2,\n        WC_CIPHER_AES_GCM = 3,\n        WC_CIPHER_AES_CTR = 4,\n        WC_CIPHER_AES_XTS = 5,\n        WC_CIPHER_AES_CFB = 6,\n        WC_CIPHER_DES3 = 7,\n        WC_CIPHER_DES = 8,\n        WC_CIPHER_CHACHA = 9,\n        WC_CIPHER_HC128 = 10,\n        WC_CIPHER_IDEA = 11,\n\n        WC_CIPHER_MAX = WC_CIPHER_HC128\n    };\n\n    /* PK=public key (asymmetric) based algorithms */\n    enum wc_PkType {\n        WC_PK_TYPE_NONE = 0,\n        WC_PK_TYPE_RSA = 1,\n        WC_PK_TYPE_DH = 2,\n        WC_PK_TYPE_ECDH = 3,\n        WC_PK_TYPE_ECDSA_SIGN = 4,\n        WC_PK_TYPE_ECDSA_VERIFY = 5,\n        WC_PK_TYPE_ED25519 = 6,\n        WC_PK_TYPE_CURVE25519 = 7,\n        WC_PK_TYPE_RSA_KEYGEN = 8,\n        WC_PK_TYPE_EC_KEYGEN = 9,\n\n        WC_PK_TYPE_MAX = WC_PK_TYPE_EC_KEYGEN\n    };\n\n\n    /* settings detection for compile vs runtime math incompatibilities */\n    enum {\n    #if !defined(USE_FAST_MATH) && !defined(SIZEOF_LONG) && !defined(SIZEOF_LONG_LONG)\n        CTC_SETTINGS = 0x0\n    #elif !defined(USE_FAST_MATH) && defined(SIZEOF_LONG) && (SIZEOF_LONG == 8)\n        CTC_SETTINGS = 0x1\n    #elif !defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8)\n        CTC_SETTINGS = 0x2\n    #elif !defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 4)\n        CTC_SETTINGS = 0x4\n    #elif defined(USE_FAST_MATH) && !defined(SIZEOF_LONG) && !defined(SIZEOF_LONG_LONG)\n        CTC_SETTINGS = 0x8\n    #elif defined(USE_FAST_MATH) && defined(SIZEOF_LONG) && (SIZEOF_LONG == 8)\n        CTC_SETTINGS = 0x10\n    #elif defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8)\n        CTC_SETTINGS = 0x20\n    #elif defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 4)\n        CTC_SETTINGS = 0x40\n    #else\n        #error \"bad math long / long long settings\"\n    #endif\n    };\n\n\n    WOLFSSL_API word32 CheckRunTimeSettings(void);\n\n    /* If user uses RSA, DH, DSA, or ECC math lib directly then fast math and long\n       types need to match at compile time and run time, CheckCtcSettings will\n       return 1 if a match otherwise 0 */\n    #define CheckCtcSettings() (CTC_SETTINGS == CheckRunTimeSettings())\n\n    /* invalid device id */\n    #define INVALID_DEVID    -2\n\n\n    /* AESNI requires alignment and ARMASM gains some performance from it\n     * Xilinx RSA operations require alignment */\n    #if defined(WOLFSSL_AESNI) || defined(WOLFSSL_ARMASM) || \\\n        defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_AFALG_XILINX)\n        #if !defined(ALIGN16)\n            #if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__)\n                #define ALIGN16 __attribute__ ( (aligned (16)))\n            #elif defined(_MSC_VER)\n                /* disable align warning, we want alignment ! */\n                #pragma warning(disable: 4324)\n                #define ALIGN16 __declspec (align (16))\n            #else\n                #define ALIGN16\n            #endif\n        #endif /* !ALIGN16 */\n\n        #if !defined (ALIGN32)\n            #if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__)\n                #define ALIGN32 __attribute__ ( (aligned (32)))\n            #elif defined(_MSC_VER)\n                /* disable align warning, we want alignment ! */\n                #pragma warning(disable: 4324)\n                #define ALIGN32 __declspec (align (32))\n            #else\n                #define ALIGN32\n            #endif\n        #endif /* !ALIGN32 */\n\n        #if !defined(ALIGN64)\n            #if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__)\n                #define ALIGN64 __attribute__ ( (aligned (64)))\n            #elif defined(_MSC_VER)\n                /* disable align warning, we want alignment ! */\n                #pragma warning(disable: 4324)\n                #define ALIGN64 __declspec (align (64))\n            #else\n                #define ALIGN64\n            #endif\n        #endif /* !ALIGN64 */\n\n        #if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__)\n            #define ALIGN128 __attribute__ ( (aligned (128)))\n        #elif defined(_MSC_VER)\n            /* disable align warning, we want alignment ! */\n            #pragma warning(disable: 4324)\n            #define ALIGN128 __declspec (align (128))\n        #else\n            #define ALIGN128\n        #endif\n\n        #if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__)\n            #define ALIGN256 __attribute__ ( (aligned (256)))\n        #elif defined(_MSC_VER)\n            /* disable align warning, we want alignment ! */\n            #pragma warning(disable: 4324)\n            #define ALIGN256 __declspec (align (256))\n        #else\n            #define ALIGN256\n        #endif\n\n    #else\n        #ifndef ALIGN16\n            #define ALIGN16\n        #endif\n        #ifndef ALIGN32\n            #define ALIGN32\n        #endif\n        #ifndef ALIGN64\n            #define ALIGN64\n        #endif\n        #ifndef ALIGN128\n            #define ALIGN128\n        #endif\n        #ifndef ALIGN256\n            #define ALIGN256\n        #endif\n    #endif /* WOLFSSL_AESNI || WOLFSSL_ARMASM */\n\n\n    #ifndef TRUE\n        #define TRUE  1\n    #endif\n    #ifndef FALSE\n        #define FALSE 0\n    #endif\n\n\n    #if defined(HAVE_STACK_SIZE)\n        #define EXIT_TEST(ret) return (void*)((size_t)(ret))\n    #else\n        #define EXIT_TEST(ret) return ret\n    #endif\n\n\n    #if (defined(__IAR_SYSTEMS_ICC__) && (__IAR_SYSTEMS_ICC__ > 8)) || \\\n         defined(__GNUC__)\n        #define WOLFSSL_PACK __attribute__ ((packed))\n    #else\n        #define WOLFSSL_PACK\n    #endif\n\n    #ifndef __GNUC_PREREQ\n        #if defined(__GNUC__) && defined(__GNUC_MINOR__)\n            #define __GNUC_PREREQ(maj, min) \\\n                ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))\n        #else\n            #define __GNUC_PREREQ(maj, min) (0) /* not GNUC */\n        #endif\n    #endif\n\n    #if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__)\n        #define WC_NORETURN __attribute__((noreturn))\n    #else\n        #define WC_NORETURN\n    #endif\n\n    #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \\\n        defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) || \\\n        defined(WOLFSSL_PUBLIC_MP) || defined(OPENSSL_EXTRA) || \\\n            (defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT))\n        #undef  WC_MP_TO_RADIX\n        #define WC_MP_TO_RADIX\n    #endif\n\n    #ifdef __cplusplus\n        }   /* extern \"C\" */\n    #endif\n\n#endif /* WOLF_CRYPT_TYPES_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/visibility.h",
    "content": "/* visibility.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n\n/* Visibility control macros */\n\n#ifndef WOLF_CRYPT_VISIBILITY_H\n#define WOLF_CRYPT_VISIBILITY_H\n\n\n/* for compatibility and so that fips is using same name of macro @wc_fips */\n/* The following visibility wrappers are for old FIPS. New FIPS should use\n * the same as a non-FIPS build. */\n#if defined(HAVE_FIPS) && \\\n    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))\n    #include <cyassl/ctaocrypt/visibility.h>\n    #define WOLFSSL_API   CYASSL_API\n\t#define WOLFSSL_LOCAL CYASSL_LOCAL\n#else\n\n/* WOLFSSL_API is used for the public API symbols.\n        It either imports or exports (or does nothing for static builds)\n\n   WOLFSSL_LOCAL is used for non-API symbols (private).\n*/\n\n#if defined(BUILDING_WOLFSSL)\n    #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)\n        #if defined(WOLFSSL_DLL)\n            #define WOLFSSL_API __declspec(dllexport)\n        #else\n            #define WOLFSSL_API\n        #endif\n        #define WOLFSSL_LOCAL\n    #elif defined(HAVE_VISIBILITY) && HAVE_VISIBILITY\n        #define WOLFSSL_API   __attribute__ ((visibility(\"default\")))\n        #define WOLFSSL_LOCAL __attribute__ ((visibility(\"hidden\")))\n    #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)\n        #define WOLFSSL_API   __global\n        #define WOLFSSL_LOCAL __hidden\n    #else\n        #define WOLFSSL_API\n        #define WOLFSSL_LOCAL\n    #endif /* HAVE_VISIBILITY */\n#else /* BUILDING_WOLFSSL */\n    #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)\n        #if defined(WOLFSSL_DLL)\n            #define WOLFSSL_API __declspec(dllimport)\n        #else\n            #define WOLFSSL_API\n        #endif\n        #define WOLFSSL_LOCAL\n    #else\n        #define WOLFSSL_API\n        #define WOLFSSL_LOCAL\n    #endif\n#endif /* BUILDING_WOLFSSL */\n\n#endif /* HAVE_FIPS */\n#endif /* WOLF_CRYPT_VISIBILITY_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/wc_encrypt.h",
    "content": "/* wc_encrypt.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/wc_encrypt.h\n*/\n\n\n#ifndef WOLF_CRYPT_ENCRYPT_H\n#define WOLF_CRYPT_ENCRYPT_H\n\n#include <wolfssl/wolfcrypt/types.h>\n#include <wolfssl/wolfcrypt/aes.h>\n#include <wolfssl/wolfcrypt/chacha.h>\n#include <wolfssl/wolfcrypt/des3.h>\n#include <wolfssl/wolfcrypt/arc4.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* determine max cipher key size */\n#ifndef NO_AES\n    #define WC_MAX_SYM_KEY_SIZE     (AES_MAX_KEY_SIZE/8)\n#elif defined(HAVE_CHACHA)\n    #define WC_MAX_SYM_KEY_SIZE     CHACHA_MAX_KEY_SZ\n#elif !defined(NO_DES3)\n    #define WC_MAX_SYM_KEY_SIZE     DES3_KEY_SIZE\n#elif !defined(NO_RC4)\n    #define WC_MAX_SYM_KEY_SIZE     RC4_KEY_SIZE\n#else\n    #define WC_MAX_SYM_KEY_SIZE     32\n#endif\n\n\n#if !defined(NO_AES) && defined(HAVE_AES_CBC)\nWOLFSSL_API int wc_AesCbcEncryptWithKey(byte* out, const byte* in, word32 inSz,\n                                        const byte* key, word32 keySz,\n                                        const byte* iv);\nWOLFSSL_API int wc_AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz,\n                                        const byte* key, word32 keySz,\n                                        const byte* iv);\n#endif /* !NO_AES */\n\n\n#ifndef NO_DES3\nWOLFSSL_API int wc_Des_CbcDecryptWithKey(byte* out,\n                                         const byte* in, word32 sz,\n                                         const byte* key, const byte* iv);\nWOLFSSL_API int wc_Des_CbcEncryptWithKey(byte* out,\n                                         const byte* in, word32 sz,\n                                         const byte* key, const byte* iv);\nWOLFSSL_API int wc_Des3_CbcEncryptWithKey(byte* out,\n                                          const byte* in, word32 sz,\n                                          const byte* key, const byte* iv);\nWOLFSSL_API int wc_Des3_CbcDecryptWithKey(byte* out,\n                                          const byte* in, word32 sz,\n                                          const byte* key, const byte* iv);\n#endif /* !NO_DES3 */\n\n\n\n\n#ifdef WOLFSSL_ENCRYPTED_KEYS\n    struct EncryptedInfo;\n    WOLFSSL_API int wc_BufferKeyDecrypt(struct EncryptedInfo* info, byte* der, word32 derSz,\n        const byte* password, int passwordSz, int hashType);\n    WOLFSSL_API int wc_BufferKeyEncrypt(struct EncryptedInfo* info, byte* der, word32 derSz,\n        const byte* password, int passwordSz, int hashType);\n#endif /* WOLFSSL_ENCRYPTED_KEYS */\n\n#ifndef NO_PWDBASED\n    WOLFSSL_LOCAL int wc_CryptKey(const char* password, int passwordSz, \n        byte* salt, int saltSz, int iterations, int id, byte* input, int length,\n        int version, byte* cbcIv, int enc);\n#endif\n\n#ifdef __cplusplus\n    }  /* extern \"C\" */\n#endif\n\n#endif /* WOLF_CRYPT_ENCRYPT_H */\n\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/wc_pkcs11.h",
    "content": "/* wc_pkcs11.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 3 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n#ifndef _WOLFPKCS11_H_\n#define _WOLFPKCS11_H_\n\n#include <wolfssl/wolfcrypt/types.h>\n\n#ifdef HAVE_PKCS11\n\n#ifndef WOLF_CRYPTO_CB\n    #error PKCS11 support requires ./configure --enable-cryptocb or WOLF_CRYPTO_CB to be defined\n#endif\n\n#include <wolfssl/wolfcrypt/cryptocb.h>\n#include <wolfssl/wolfcrypt/pkcs11.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n\ntypedef struct Pkcs11Dev {\n    void*             dlHandle;         /* Handle to library  */\n    CK_FUNCTION_LIST* func;             /* Array of functions */\n    void*             heap;\n} Pkcs11Dev;\n\ntypedef struct Pkcs11Token {\n    CK_FUNCTION_LIST* func;             /* Table of PKCS#11 function from lib */\n    CK_SLOT_ID        slotId;           /* Id of slot to use                  */\n    CK_SESSION_HANDLE handle;           /* Handle to active session           */\n    CK_UTF8CHAR_PTR   userPin;          /* User's PIN to login with           */\n    CK_ULONG          userPinSz;        /* Size of user's PIN in bytes        */\n} Pkcs11Token;\n\ntypedef struct Pkcs11Session {\n    CK_FUNCTION_LIST* func;             /* Table of PKCS#11 function from lib */\n    CK_SLOT_ID        slotId;           /* Id of slot to use                  */\n    CK_SESSION_HANDLE handle;           /* Handle to active session           */\n} Pkcs11Session;\n\n/* Types of keys that can be stored. */\nenum Pkcs11KeyType {\n    PKCS11_KEY_TYPE_AES_GCM,\n    PKCS11_KEY_TYPE_AES_CBC,\n    PKCS11_KEY_TYPE_HMAC,\n    PKCS11_KEY_TYPE_RSA,\n    PKCS11_KEY_TYPE_EC,\n};\n\n\nWOLFSSL_API int wc_Pkcs11_Initialize(Pkcs11Dev* dev, const char* library,\n                                     void* heap);\nWOLFSSL_API void wc_Pkcs11_Finalize(Pkcs11Dev* dev);\n\nWOLFSSL_API int wc_Pkcs11Token_Init(Pkcs11Token* token, Pkcs11Dev* dev,\n    int slotId, const char* tokenName, const unsigned char *userPin,\n    int userPinSz);\nWOLFSSL_API void wc_Pkcs11Token_Final(Pkcs11Token* token);\nWOLFSSL_API int wc_Pkcs11Token_Open(Pkcs11Token* token, int readWrite);\nWOLFSSL_API void wc_Pkcs11Token_Close(Pkcs11Token* token);\n\nWOLFSSL_API int wc_Pkcs11StoreKey(Pkcs11Token* token, int type, int clear,\n    void* key);\n\nWOLFSSL_API int wc_Pkcs11_CryptoDevCb(int devId, wc_CryptoInfo* info,\n    void* ctx);\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* HAVE_PKCS11 */\n\n#endif /* _WOLFPKCS11_H_ */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/wc_port.h",
    "content": "/* wc_port.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n/*!\n    \\file wolfssl/wolfcrypt/wc_port.h\n*/\n\n#ifndef WOLF_CRYPT_PORT_H\n#define WOLF_CRYPT_PORT_H\n\n#include <wolfssl/wolfcrypt/settings.h>\n#include <wolfssl/wolfcrypt/visibility.h>\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n/* Detect if compiler supports C99. \"NO_WOLF_C99\" can be defined in\n * user_settings.h to disable checking for C99 support. */\n#if !defined(WOLF_C99) && defined(__STDC_VERSION__) && \\\n    !defined(WOLFSSL_ARDUINO) && !defined(NO_WOLF_C99)\n    #if __STDC_VERSION__ >= 199901L\n        #define WOLF_C99\n    #endif\n#endif\n\n\n/* GENERIC INCLUDE SECTION */\n#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)\n    #include <mqx.h>\n    #if (defined(MQX_USE_IO_OLD) && MQX_USE_IO_OLD) || \\\n        defined(FREESCALE_MQX_5_0)\n        #include <fio.h>\n    #else\n        #include <nio.h>\n    #endif\n#endif\n\n\n/* THREADING/MUTEX SECTION */\n#ifdef USE_WINDOWS_API\n    #ifdef WOLFSSL_GAME_BUILD\n        #include \"system/xtl.h\"\n    #else\n        #ifndef WIN32_LEAN_AND_MEAN\n            #define WIN32_LEAN_AND_MEAN\n        #endif\n        #ifndef WOLFSSL_SGX\n            #if defined(_WIN32_WCE) || defined(WIN32_LEAN_AND_MEAN)\n                /* On WinCE winsock2.h must be included before windows.h */\n                #include <winsock2.h>\n            #endif\n            #include <windows.h>\n        #endif /* WOLFSSL_SGX */\n    #endif\n#elif defined(THREADX)\n    #ifndef SINGLE_THREADED\n        #ifdef NEED_THREADX_TYPES\n            #include <types.h>\n        #endif\n        #include <tx_api.h>\n    #endif\n#elif defined(WOLFSSL_DEOS)\n    #include \"mutexapi.h\"\n#elif defined(MICRIUM)\n    /* do nothing, just don't pick Unix */\n#elif defined(FREERTOS) || defined(FREERTOS_TCP) || defined(WOLFSSL_SAFERTOS)\n    /* do nothing */\n#elif defined(EBSNET)\n    /* do nothing */\n#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)\n    /* do nothing */\n#elif defined(FREESCALE_FREE_RTOS)\n    #include \"fsl_os_abstraction.h\"\n#elif defined(WOLFSSL_VXWORKS)\n    #include <semLib.h>\n#elif defined(WOLFSSL_uITRON4)\n    #include \"stddef.h\"\n    #include \"kernel.h\"\n#elif  defined(WOLFSSL_uTKERNEL2)\n    #include \"tk/tkernel.h\"\n#elif defined(WOLFSSL_CMSIS_RTOS)\n    #include \"cmsis_os.h\"\n#elif defined(WOLFSSL_CMSIS_RTOSv2)\n    #include \"cmsis_os2.h\"\n#elif defined(WOLFSSL_MDK_ARM)\n    #if defined(WOLFSSL_MDK5)\n        #include \"cmsis_os.h\"\n    #else\n        #include <rtl.h>\n    #endif\n#elif defined(WOLFSSL_CMSIS_RTOS)\n    #include \"cmsis_os.h\"\n#elif defined(WOLFSSL_TIRTOS)\n    #include <ti/sysbios/BIOS.h>\n    #include <ti/sysbios/knl/Semaphore.h>\n#elif defined(WOLFSSL_FROSTED)\n    #include <semaphore.h>\n#elif defined(INTIME_RTOS)\n    #include <rt.h>\n    #include <io.h>\n#elif defined(WOLFSSL_NUCLEUS_1_2)\n    /* NU_DEBUG needed struct access in nucleus_realloc */\n    #define NU_DEBUG\n    #include \"plus/nucleus.h\"\n    #include \"nucleus.h\"\n#elif defined(WOLFSSL_APACHE_MYNEWT)\n    /* do nothing */\n#elif defined(WOLFSSL_ZEPHYR)\n    #ifndef SINGLE_THREADED\n        #include <kernel.h>\n    #endif\n#elif defined(WOLFSSL_TELIT_M2MB)\n\n    /* Telit SDK uses C++ compile option (--cpp), which causes link issue\n        to API's if wrapped in extern \"C\" */\n    #ifdef __cplusplus\n        }  /* extern \"C\" */\n    #endif\n\n    #include \"m2mb_types.h\"\n    #include \"m2mb_os_types.h\"\n    #include \"m2mb_os_api.h\"\n    #include \"m2mb_os.h\"\n    #include \"m2mb_os_mtx.h\"\n    #ifndef NO_ASN_TIME\n    #include \"m2mb_rtc.h\"\n    #endif\n    #ifndef NO_FILESYSTEM\n    #include \"m2mb_fs_posix.h\"\n    #endif\n\n    #undef kB /* eliminate conflict in asn.h */\n\n    #ifdef __cplusplus\n        extern \"C\" {\n    #endif\n\n#else\n    #ifndef SINGLE_THREADED\n        #define WOLFSSL_PTHREADS\n        #include <pthread.h>\n    #endif\n    #if (defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)) && \\\n        !defined(NO_FILESYSTEM)\n        #include <unistd.h>      /* for close of BIO */\n    #endif\n#endif\n\n/* For FIPS keep the function names the same */\n#ifdef HAVE_FIPS\n#define wc_InitMutex   InitMutex\n#define wc_FreeMutex   FreeMutex\n#define wc_LockMutex   LockMutex\n#define wc_UnLockMutex UnLockMutex\n#endif /* HAVE_FIPS */\n\n#ifdef SINGLE_THREADED\n    typedef int wolfSSL_Mutex;\n#else /* MULTI_THREADED */\n    /* FREERTOS comes first to enable use of FreeRTOS Windows simulator only */\n    #if defined(FREERTOS)\n        typedef xSemaphoreHandle wolfSSL_Mutex;\n    #elif defined(FREERTOS_TCP)\n        #include \"FreeRTOS.h\"\n        #include \"semphr.h\"\n\t\ttypedef SemaphoreHandle_t  wolfSSL_Mutex;\n    #elif defined(WOLFSSL_SAFERTOS)\n        typedef struct wolfSSL_Mutex {\n            signed char mutexBuffer[portQUEUE_OVERHEAD_BYTES];\n            xSemaphoreHandle mutex;\n        } wolfSSL_Mutex;\n    #elif defined(USE_WINDOWS_API)\n        typedef CRITICAL_SECTION wolfSSL_Mutex;\n    #elif defined(WOLFSSL_PTHREADS)\n        typedef pthread_mutex_t wolfSSL_Mutex;\n    #elif defined(THREADX)\n        typedef TX_MUTEX wolfSSL_Mutex;\n    #elif defined(WOLFSSL_DEOS)\n        typedef mutex_handle_t wolfSSL_Mutex;\n    #elif defined(MICRIUM)\n        typedef OS_MUTEX wolfSSL_Mutex;\n    #elif defined(EBSNET)\n        typedef RTP_MUTEX wolfSSL_Mutex;\n    #elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)\n        typedef MUTEX_STRUCT wolfSSL_Mutex;\n    #elif defined(FREESCALE_FREE_RTOS)\n        typedef mutex_t wolfSSL_Mutex;\n    #elif defined(WOLFSSL_VXWORKS)\n        typedef SEM_ID wolfSSL_Mutex;\n    #elif defined(WOLFSSL_uITRON4)\n        typedef struct wolfSSL_Mutex {\n            T_CSEM sem ;\n            ID     id ;\n        } wolfSSL_Mutex;\n    #elif defined(WOLFSSL_uTKERNEL2)\n        typedef struct wolfSSL_Mutex {\n            T_CSEM sem ;\n            ID     id ;\n        } wolfSSL_Mutex;\n    #elif defined(WOLFSSL_MDK_ARM)\n        #if defined(WOLFSSL_CMSIS_RTOS)\n            typedef osMutexId wolfSSL_Mutex;\n        #else\n            typedef OS_MUT wolfSSL_Mutex;\n        #endif\n    #elif defined(WOLFSSL_CMSIS_RTOS)\n        typedef osMutexId wolfSSL_Mutex;\n    #elif defined(WOLFSSL_CMSIS_RTOSv2)\n        typedef osMutexId_t wolfSSL_Mutex;\n    #elif defined(WOLFSSL_TIRTOS)\n        typedef ti_sysbios_knl_Semaphore_Handle wolfSSL_Mutex;\n    #elif defined(WOLFSSL_FROSTED)\n        typedef mutex_t * wolfSSL_Mutex;\n    #elif defined(INTIME_RTOS)\n        typedef RTHANDLE wolfSSL_Mutex;\n    #elif defined(WOLFSSL_NUCLEUS_1_2)\n        typedef NU_SEMAPHORE wolfSSL_Mutex;\n    #elif defined(WOLFSSL_ZEPHYR)\n        typedef struct k_mutex wolfSSL_Mutex;\n    #elif defined(WOLFSSL_TELIT_M2MB)\n        typedef M2MB_OS_MTX_HANDLE wolfSSL_Mutex;\n    #else\n        #error Need a mutex type in multithreaded mode\n    #endif /* USE_WINDOWS_API */\n#endif /* SINGLE_THREADED */\n\n/* Enable crypt HW mutex for Freescale MMCAU, PIC32MZ or STM32 */\n#if defined(FREESCALE_MMCAU) || defined(WOLFSSL_MICROCHIP_PIC32MZ) || \\\n    defined(STM32_CRYPTO)\n    #ifndef WOLFSSL_CRYPT_HW_MUTEX\n        #define WOLFSSL_CRYPT_HW_MUTEX  1\n    #endif\n#endif /* FREESCALE_MMCAU */\n\n#ifndef WOLFSSL_CRYPT_HW_MUTEX\n    #define WOLFSSL_CRYPT_HW_MUTEX  0\n#endif\n\n#if WOLFSSL_CRYPT_HW_MUTEX\n    /* wolfSSL_CryptHwMutexInit is called on first wolfSSL_CryptHwMutexLock,\n       however it's recommended to call this directly on Hw init to avoid possible\n       race condition where two calls to wolfSSL_CryptHwMutexLock are made at\n       the same time. */\n    int wolfSSL_CryptHwMutexInit(void);\n    int wolfSSL_CryptHwMutexLock(void);\n    int wolfSSL_CryptHwMutexUnLock(void);\n#else\n    /* Define stubs, since HW mutex is disabled */\n    #define wolfSSL_CryptHwMutexInit()      0 /* Success */\n    #define wolfSSL_CryptHwMutexLock()      0 /* Success */\n    #define wolfSSL_CryptHwMutexUnLock()    (void)0 /* Success */\n#endif /* WOLFSSL_CRYPT_HW_MUTEX */\n\n/* Mutex functions */\nWOLFSSL_API int wc_InitMutex(wolfSSL_Mutex*);\nWOLFSSL_API wolfSSL_Mutex* wc_InitAndAllocMutex(void);\nWOLFSSL_API int wc_FreeMutex(wolfSSL_Mutex*);\nWOLFSSL_API int wc_LockMutex(wolfSSL_Mutex*);\nWOLFSSL_API int wc_UnLockMutex(wolfSSL_Mutex*);\n#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)\n/* dynamically set which mutex to use. unlock / lock is controlled by flag */\ntypedef void (mutex_cb)(int flag, int type, const char* file, int line);\n\nWOLFSSL_API int wc_LockMutex_ex(int flag, int type, const char* file, int line);\nWOLFSSL_API int wc_SetMutexCb(mutex_cb* cb);\n#endif\n\n/* main crypto initialization function */\nWOLFSSL_API int wolfCrypt_Init(void);\nWOLFSSL_API int wolfCrypt_Cleanup(void);\n\n\n/* FILESYSTEM SECTION */\n/* filesystem abstraction layer, used by ssl.c */\n#ifndef NO_FILESYSTEM\n\n#if defined(EBSNET)\n    #include \"vfapi.h\"\n    #include \"vfile.h\"\n\n    int ebsnet_fseek(int a, long b, int c); /* Not prototyped in vfile.h per\n                                             * EBSnet feedback */\n\n    #define XFILE                    int\n    #define XFOPEN(NAME, MODE)       vf_open((const char *)NAME, VO_RDONLY, 0);\n    #define XFSEEK                   ebsnet_fseek\n    #define XFTELL                   vf_tell\n    #define XREWIND                  vf_rewind\n    #define XFREAD(BUF, SZ, AMT, FD) vf_read(FD, BUF, SZ*AMT)\n    #define XFWRITE(BUF, SZ, AMT, FD) vf_write(FD, BUF, SZ*AMT)\n    #define XFCLOSE                  vf_close\n    #define XSEEK_END                VSEEK_END\n    #define XBADFILE                 -1\n    #define XFGETS(b,s,f)            -2 /* Not ported yet */\n#elif defined(LSR_FS)\n    #include <fs.h>\n    #define XFILE                   struct fs_file*\n    #define XFOPEN(NAME, MODE)      fs_open((char*)NAME);\n    #define XFSEEK(F, O, W)         (void)F\n    #define XFTELL(F)               (F)->len\n    #define XREWIND(F)              (void)F\n    #define XFREAD(BUF, SZ, AMT, F) fs_read(F, (char*)BUF, SZ*AMT)\n    #define XFWRITE(BUF, SZ, AMT, F) fs_write(F, (char*)BUF, SZ*AMT)\n    #define XFCLOSE                 fs_close\n    #define XSEEK_END               0\n    #define XBADFILE                NULL\n    #define XFGETS(b,s,f)            -2 /* Not ported yet */\n#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)\n    #define XFILE                   MQX_FILE_PTR\n    #define XFOPEN                  fopen\n    #define XFSEEK                  fseek\n    #define XFTELL                  ftell\n    #define XREWIND(F)              fseek(F, 0, IO_SEEK_SET)\n    #define XFREAD                  fread\n    #define XFWRITE                 fwrite\n    #define XFCLOSE                 fclose\n    #define XSEEK_END               IO_SEEK_END\n    #define XBADFILE                NULL\n    #define XFGETS                  fgets\n#elif defined(WOLFSSL_DEOS)\n    #define NO_FILESYSTEM\n    #warning \"TODO - DDC-I Certifiable Fast File System for Deos is not integrated\"\n    //#define XFILE      bfd *\n\n#elif defined(MICRIUM)\n    #include <fs_api.h>\n    #define XFILE      FS_FILE*\n    #define XFOPEN     fs_fopen\n    #define XFSEEK     fs_fseek\n    #define XFTELL     fs_ftell\n    #define XREWIND    fs_rewind\n    #define XFREAD     fs_fread\n    #define XFWRITE    fs_fwrite\n    #define XFCLOSE    fs_fclose\n    #define XSEEK_END  FS_SEEK_END\n    #define XBADFILE   NULL\n    #define XFGETS(b,s,f) -2 /* Not ported yet */\n#elif defined(WOLFSSL_NUCLEUS_1_2)\n    #include \"fal/inc/fal.h\"\n    #define XFILE      FILE*\n    #define XFOPEN     fopen\n    #define XFSEEK     fseek\n    #define XFTELL     ftell\n    #define XREWIND    rewind\n    #define XFREAD     fread\n    #define XFWRITE    fwrite\n    #define XFCLOSE    fclose\n    #define XSEEK_END  PSEEK_END\n    #define XBADFILE   NULL\n#elif defined(WOLFSSL_APACHE_MYNEWT)\n    #include <fs/fs.h>\n    #define XFILE  struct fs_file*\n\n    #define XFOPEN     mynewt_fopen\n    #define XFSEEK     mynewt_fseek\n    #define XFTELL     mynewt_ftell\n    #define XREWIND    mynewt_rewind\n    #define XFREAD     mynewt_fread\n    #define XFWRITE    mynewt_fwrite\n    #define XFCLOSE    mynewt_fclose\n    #define XSEEK_END  2\n    #define XBADFILE   NULL\n    #define XFGETS(b,s,f) -2 /* Not ported yet */\n#elif defined(WOLFSSL_ZEPHYR)\n    #include <fs.h>\n\n    #define XFILE      struct fs_file_t*\n    #define STAT       struct fs_dirent\n\n    XFILE z_fs_open(const char* filename, const char* perm);\n    int z_fs_close(XFILE file);\n\n    #define XFOPEN              z_fs_open\n    #define XFCLOSE             z_fs_close\n    #define XFSEEK              fs_seek\n    #define XFTELL              fs_tell\n    #define XFREWIND            fs_rewind\n    #define XREWIND(F)          fs_seek(F, 0, FS_SEEK_SET)\n    #define XFREAD(P,S,N,F)     fs_read(F, P, S*N)\n    #define XFWRITE(P,S,N,F)    fs_write(F, P, S*N)\n    #define XSEEK_END           FS_SEEK_END\n    #define XBADFILE            NULL\n    #define XFGETS(b,s,f)       -2 /* Not ported yet */\n\n#elif defined(WOLFSSL_TELIT_M2MB)\n    #define XFILE                    INT32\n    #define XFOPEN(NAME, MODE)       m2mb_fs_open((NAME), 0, (MODE))\n    #define XFSEEK(F, O, W)          m2mb_fs_lseek((F), (O), (W))\n    #define XFTELL(F)                m2mb_fs_lseek((F), 0, M2MB_SEEK_END)\n    #define XREWIND(F)               (void)F\n    #define XFREAD(BUF, SZ, AMT, F)  m2mb_fs_read((F), (BUF), (SZ)*(AMT))\n    #define XFWRITE(BUF, SZ, AMT, F) m2mb_fs_write((F), (BUF), (SZ)*(AMT))\n    #define XFCLOSE                  m2mb_fs_close\n    #define XSEEK_END                M2MB_SEEK_END\n    #define XBADFILE                 -1\n    #define XFGETS(b,s,f)            -2 /* Not ported yet */\n\n#elif defined(WOLFSSL_USER_FILESYSTEM)\n    /* To be defined in user_settings.h */\n#else\n    /* stdio, default case */\n    #include <stdio.h>\n    #define XFILE      FILE*\n    #if defined(WOLFSSL_MDK_ARM)\n        extern FILE * wolfSSL_fopen(const char *name, const char *mode) ;\n        #define XFOPEN     wolfSSL_fopen\n    #else\n        #define XFOPEN     fopen\n    #endif\n    #define XFSEEK     fseek\n    #define XFTELL     ftell\n    #define XREWIND    rewind\n    #define XFREAD     fread\n    #define XFWRITE    fwrite\n    #define XFCLOSE    fclose\n    #define XSEEK_END  SEEK_END\n    #define XBADFILE   NULL\n    #define XFGETS     fgets\n\n    #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\\\n        && !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2)\n        #include <dirent.h>\n        #include <unistd.h>\n        #include <sys/stat.h>\n    #endif\n#endif\n\n    #ifndef MAX_FILENAME_SZ\n        #define MAX_FILENAME_SZ  256 /* max file name length */\n    #endif\n    #ifndef MAX_PATH\n        #define MAX_PATH 256\n    #endif\n\n#if !defined(NO_WOLFSSL_DIR) && !defined(WOLFSSL_NUCLEUS) && \\\n    !defined(WOLFSSL_NUCLEUS_1_2)\n    typedef struct ReadDirCtx {\n    #ifdef USE_WINDOWS_API\n        WIN32_FIND_DATAA FindFileData;\n        HANDLE hFind;\n    #elif defined(WOLFSSL_ZEPHYR)\n        struct fs_dirent entry;\n        struct fs_dir_t  dir;\n        struct fs_dirent s;\n        struct fs_dir_t* dirp;\n\n    #elif defined(WOLFSSL_TELIT_M2MB)\n        M2MB_DIR_T* dir;\n        struct M2MB_DIRENT* entry;\n        struct M2MB_STAT s;\n    #else\n        struct dirent* entry;\n        DIR*   dir;\n        struct stat s;\n    #endif\n        char name[MAX_FILENAME_SZ];\n    } ReadDirCtx;\n\n    #define WC_READDIR_NOFILE -1\n\n    WOLFSSL_API int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name);\n    WOLFSSL_API int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name);\n    WOLFSSL_API void wc_ReadDirClose(ReadDirCtx* ctx);\n#endif /* !NO_WOLFSSL_DIR */\n\n#endif /* !NO_FILESYSTEM */\n\n\n/* MIN/MAX MACRO SECTION */\n/* Windows API defines its own min() macro. */\n#if defined(USE_WINDOWS_API)\n    #if defined(min) || defined(WOLFSSL_MYSQL_COMPATIBLE)\n        #define WOLFSSL_HAVE_MIN\n    #endif /* min */\n    #if defined(max) || defined(WOLFSSL_MYSQL_COMPATIBLE)\n        #define WOLFSSL_HAVE_MAX\n    #endif /* max */\n#endif /* USE_WINDOWS_API */\n\n\n/* TIME SECTION */\n/* Time functions */\n#ifndef NO_ASN_TIME\n#if defined(USER_TIME)\n    /* Use our gmtime and time_t/struct tm types.\n       Only needs seconds since EPOCH using XTIME function.\n       time_t XTIME(time_t * timer) {}\n    */\n    #define WOLFSSL_GMTIME\n    #ifndef HAVE_TM_TYPE\n        #define USE_WOLF_TM\n    #endif\n    #ifndef HAVE_TIME_T_TYPE\n        #define USE_WOLF_TIME_T\n    #endif\n\n#elif defined(TIME_OVERRIDES)\n    /* Override XTIME() and XGMTIME() functionality.\n       Requires user to provide these functions:\n        time_t XTIME(time_t * timer) {}\n        struct tm* XGMTIME(const time_t* timer, struct tm* tmp) {}\n    */\n    #ifndef HAVE_TIME_T_TYPE\n        #define USE_WOLF_TIME_T\n    #endif\n    #ifndef HAVE_TM_TYPE\n        #define USE_WOLF_TM\n    #endif\n    #define NEED_TMP_TIME\n\n#elif defined(WOLFSSL_XILINX) && defined(FREERTOS)\n    #define USER_TIME\n    #include <time.h>\n\n#elif defined(HAVE_RTP_SYS)\n    #include \"os.h\"           /* dc_rtc_api needs    */\n    #include \"dc_rtc_api.h\"   /* to get current time */\n\n    /* uses parital <time.h> structures */\n    #define XTIME(tl)       (0)\n    #define XGMTIME(c, t)   rtpsys_gmtime((c))\n\n#elif defined(WOLFSSL_DEOS)\n    #define XTIME(t1)       deos_time((t1))\n    #define WOLFSSL_GMTIME\n    #define USE_WOLF_TM\n    #define USE_WOLF_TIME_T\n\n#elif defined(MICRIUM)\n    #include <clk.h>\n    #include <time.h>\n    #define XTIME(t1)       micrium_time((t1))\n    #define WOLFSSL_GMTIME\n\n#elif defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP)\n    #include <time.h>\n    #define XTIME(t1)       pic32_time((t1))\n    #define XGMTIME(c, t)   gmtime((c))\n\n#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)\n    #ifdef FREESCALE_MQX_4_0\n        #include <time.h>\n        extern time_t mqx_time(time_t* timer);\n    #else\n        #define HAVE_GMTIME_R\n    #endif\n    #define XTIME(t1)       mqx_time((t1))\n\n#elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS)\n    #include <time.h>\n    #ifndef XTIME\n        /*extern time_t ksdk_time(time_t* timer);*/\n        #define XTIME(t1)   ksdk_time((t1))\n    #endif\n    #define XGMTIME(c, t)   gmtime((c))\n\n#elif defined(WOLFSSL_ATMEL) && defined(WOLFSSL_ATMEL_TIME)\n    #define XTIME(t1)       atmel_get_curr_time_and_date((t1))\n    #define WOLFSSL_GMTIME\n    #define USE_WOLF_TM\n    #define USE_WOLF_TIME_T\n\n#elif defined(WOLFSSL_WICED)\n    #include <time.h>\n    time_t wiced_pseudo_unix_epoch_time(time_t * timer);\n    #define XTIME(t1)       wiced_pseudo_unix_epoch_time((t1))\n    #define HAVE_GMTIME_R\n\n#elif defined(IDIRECT_DEV_TIME)\n    /*Gets the timestamp from cloak software owned by VT iDirect\n    in place of time() from <time.h> */\n    #include <time.h>\n    #define XTIME(t1)       idirect_time((t1))\n    #define XGMTIME(c, t)   gmtime((c))\n\n#elif defined(_WIN32_WCE)\n    #include <windows.h>\n    #define XTIME(t1)       windows_time((t1))\n    #define WOLFSSL_GMTIME\n\n#elif defined(WOLFSSL_APACHE_MYNEWT)\n    #include \"os/os_time.h\"\n    #define XTIME(t1)       mynewt_time((t1))\n    #define WOLFSSL_GMTIME\n    #define USE_WOLF_TM\n    #define USE_WOLF_TIME_T\n\n#elif defined(WOLFSSL_ZEPHYR)\n    #ifndef _POSIX_C_SOURCE\n        #include <posix/time.h>\n    #else\n        #include <sys/time.h>\n    #endif\n\n    typedef signed int time_t;\n\n    time_t z_time(time_t *timer);\n\n    #define XTIME(tl)       z_time((tl))\n    #define XGMTIME(c, t)   gmtime((c))\n    #define WOLFSSL_GMTIME\n\n    #define USE_WOLF_TM\n\n#elif defined(WOLFSSL_TELIT_M2MB)\n    typedef long time_t;\n    extern time_t m2mb_xtime(time_t * timer);\n    #define XTIME(tl)       m2mb_xtime((tl))\n    #ifdef WOLFSSL_TLS13\n        extern time_t m2mb_xtime_ms(time_t * timer);\n        #define XTIME_MS(tl)    m2mb_xtime_ms((tl))\n    #endif\n    #ifndef NO_CRYPT_BENCHMARK\n        extern double m2mb_xtime_bench(int reset);\n        #define WOLFSSL_CURRTIME_REMAP m2mb_xtime_bench\n    #endif\n    #define XGMTIME(c, t)   gmtime((c))\n    #define WOLFSSL_GMTIME\n    #define USE_WOLF_TM\n\n#else\n    /* default */\n    /* uses complete <time.h> facility */\n    #include <time.h>\n    #if defined(HAVE_SYS_TIME_H)\n        #include <sys/time.h>\n    #endif\n\n    /* PowerPC time_t is int */\n    #ifdef __PPC__\n        #define TIME_T_NOT_64BIT\n    #endif\n#endif\n\n#ifdef SIZEOF_TIME_T\n    /* check if size of time_t from autoconf is less than 8 bytes (64bits) */\n    #if SIZEOF_TIME_T < 8\n        #undef  TIME_T_NOT_64BIT\n        #define TIME_T_NOT_64BIT\n    #endif\n#endif\n#ifdef TIME_T_NOT_LONG\n    /* one old reference to TIME_T_NOT_LONG in GCC-ARM example README\n     * this keeps support for the old macro name */\n    #undef  TIME_T_NOT_64BIT\n    #define TIME_T_NOT_64BIT\n#endif\n\n/* Map default time functions */\n#if !defined(XTIME) && !defined(TIME_OVERRIDES) && !defined(USER_TIME)\n    #ifdef TEST_BEFORE_DATE\n    #define XTIME(tl)       (946681200UL) /* Jan 1, 2000 */\n    #else\n    #define XTIME(tl)       time((tl))\n    #endif\n#endif\n#if !defined(XGMTIME) && !defined(TIME_OVERRIDES)\n    #if defined(WOLFSSL_GMTIME) || !defined(HAVE_GMTIME_R) || defined(WOLF_C99)\n        #define XGMTIME(c, t)   gmtime((c))\n    #else\n        #define XGMTIME(c, t)   gmtime_r((c), (t))\n        #define NEED_TMP_TIME\n    #endif\n#endif\n#if !defined(XVALIDATE_DATE) && !defined(HAVE_VALIDATE_DATE)\n    #define USE_WOLF_VALIDDATE\n    #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))\n#endif\n\n/* wolf struct tm and time_t */\n#if defined(USE_WOLF_TM)\n    struct tm {\n        int  tm_sec;     /* seconds after the minute [0-60] */\n        int  tm_min;     /* minutes after the hour [0-59] */\n        int  tm_hour;    /* hours since midnight [0-23] */\n        int  tm_mday;    /* day of the month [1-31] */\n        int  tm_mon;     /* months since January [0-11] */\n        int  tm_year;    /* years since 1900 */\n        int  tm_wday;    /* days since Sunday [0-6] */\n        int  tm_yday;    /* days since January 1 [0-365] */\n        int  tm_isdst;   /* Daylight Savings Time flag */\n        long tm_gmtoff;  /* offset from CUT in seconds */\n        char *tm_zone;   /* timezone abbreviation */\n    };\n#endif /* USE_WOLF_TM */\n#if defined(USE_WOLF_TIME_T)\n    typedef long time_t;\n#endif\n#if defined(USE_WOLF_SUSECONDS_T)\n    typedef long suseconds_t;\n#endif\n#if defined(USE_WOLF_TIMEVAL_T)\n    struct timeval\n    {\n        time_t tv_sec;\n        suseconds_t tv_usec;\n    };\n#endif\n\n    /* forward declarations */\n#if defined(USER_TIME)\n    struct tm* gmtime(const time_t* timer);\n    extern time_t XTIME(time_t * timer);\n\n    #ifdef STACK_TRAP\n        /* for stack trap tracking, don't call os gmtime on OS X/linux,\n           uses a lot of stack spce */\n        extern time_t time(time_t * timer);\n        #define XTIME(tl)  time((tl))\n    #endif /* STACK_TRAP */\n\n#elif defined(TIME_OVERRIDES)\n    extern time_t XTIME(time_t * timer);\n    extern struct tm* XGMTIME(const time_t* timer, struct tm* tmp);\n#elif defined(WOLFSSL_GMTIME)\n    struct tm* gmtime(const time_t* timer);\n#endif\n#endif /* NO_ASN_TIME */\n\n\n#ifndef WOLFSSL_LEANPSK\n    char* mystrnstr(const char* s1, const char* s2, unsigned int n);\n#endif\n\n#ifndef FILE_BUFFER_SIZE\n    #define FILE_BUFFER_SIZE 1024     /* default static file buffer size for input,\n                                    will use dynamic buffer if not big enough */\n#endif\n\n#ifdef HAVE_CAVIUM_OCTEON_SYNC\n    /* By default, the OCTEON's global variables are all thread local. This\n     * tag allows them to be shared between threads. */\n    #include \"cvmx-platform.h\"\n    #define WOLFSSL_GLOBAL CVMX_SHARED\n#else\n    #define WOLFSSL_GLOBAL\n#endif\n\n#ifdef __cplusplus\n    }  /* extern \"C\" */\n#endif\n\n#endif /* WOLF_CRYPT_PORT_H */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/wolfevent.h",
    "content": "/* wolfevent.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n#ifndef _WOLF_EVENT_H_\n#define _WOLF_EVENT_H_\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifndef SINGLE_THREADED\n    #include <wolfssl/wolfcrypt/wc_port.h>\n#endif\n\ntypedef struct WOLF_EVENT WOLF_EVENT;\ntypedef unsigned short WOLF_EVENT_FLAG;\n\ntypedef enum WOLF_EVENT_TYPE {\n    WOLF_EVENT_TYPE_NONE,\n#ifdef WOLFSSL_ASYNC_CRYPT\n    WOLF_EVENT_TYPE_ASYNC_WOLFSSL,    /* context is WOLFSSL* */\n    WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT,  /* context is WC_ASYNC_DEV */\n    WOLF_EVENT_TYPE_ASYNC_FIRST = WOLF_EVENT_TYPE_ASYNC_WOLFSSL,\n    WOLF_EVENT_TYPE_ASYNC_LAST = WOLF_EVENT_TYPE_ASYNC_WOLFCRYPT,\n#endif /* WOLFSSL_ASYNC_CRYPT */\n} WOLF_EVENT_TYPE;\n\ntypedef enum WOLF_EVENT_STATE {\n    WOLF_EVENT_STATE_READY,\n    WOLF_EVENT_STATE_PENDING,\n    WOLF_EVENT_STATE_DONE,\n} WOLF_EVENT_STATE;\n\nstruct WOLF_EVENT {\n    /* double linked list */\n    WOLF_EVENT*         next;\n    WOLF_EVENT*         prev;\n\n    void*               context;\n    union {\n        void* ptr;\n#ifdef WOLFSSL_ASYNC_CRYPT\n        struct WC_ASYNC_DEV* async;\n#endif\n    } dev;\n#ifdef HAVE_CAVIUM\n    word64              reqId;\n    #ifdef WOLFSSL_NITROX_DEBUG\n    word32              pendCount;\n    #endif\n#endif\n#ifndef WC_NO_ASYNC_THREADING\n    pthread_t           threadId;\n#endif\n    int                 ret;    /* Async return code */\n    unsigned int        flags;\n    WOLF_EVENT_TYPE     type;\n    WOLF_EVENT_STATE    state;\n};\n\nenum WOLF_POLL_FLAGS {\n    WOLF_POLL_FLAG_CHECK_HW = 0x01,\n};\n\ntypedef struct {\n    WOLF_EVENT*         head;     /* head of queue */\n    WOLF_EVENT*         tail;     /* tail of queue */\n#ifndef SINGLE_THREADED\n    wolfSSL_Mutex       lock;     /* queue lock */\n#endif\n    int                 count;\n} WOLF_EVENT_QUEUE;\n\n\n#ifdef HAVE_WOLF_EVENT\n\n/* Event */\nWOLFSSL_API int wolfEvent_Init(WOLF_EVENT* event, WOLF_EVENT_TYPE type, void* context);\nWOLFSSL_API int wolfEvent_Poll(WOLF_EVENT* event, WOLF_EVENT_FLAG flags);\n\n/* Event Queue */\nWOLFSSL_API int wolfEventQueue_Init(WOLF_EVENT_QUEUE* queue);\nWOLFSSL_API int wolfEventQueue_Push(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event);\nWOLFSSL_API int wolfEventQueue_Pop(WOLF_EVENT_QUEUE* queue, WOLF_EVENT** event);\nWOLFSSL_API int wolfEventQueue_Poll(WOLF_EVENT_QUEUE* queue, void* context_filter,\n    WOLF_EVENT** events, int maxEvents, WOLF_EVENT_FLAG flags, int* eventCount);\nWOLFSSL_API int wolfEventQueue_Count(WOLF_EVENT_QUEUE* queue);\nWOLFSSL_API void wolfEventQueue_Free(WOLF_EVENT_QUEUE* queue);\n\n/* the queue mutex must be locked prior to calling these */\nWOLFSSL_API int wolfEventQueue_Add(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event);\nWOLFSSL_API int wolfEventQueue_Remove(WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event);\n\n\n#endif /* HAVE_WOLF_EVENT */\n\n\n#ifdef __cplusplus\n    }   /* extern \"C\" */\n#endif\n\n#endif /* _WOLF_EVENT_H_ */\n"
  },
  {
    "path": "src/wolfssl/wolfcrypt/wolfmath.h",
    "content": "/* wolfmath.h\n *\n * Copyright (C) 2006-2019 wolfSSL Inc.\n *\n * This file is part of wolfSSL.\n *\n * wolfSSL is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * wolfSSL is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA\n */\n\n#ifndef __WOLFMATH_H__\n#define __WOLFMATH_H__\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifdef WOLFSSL_PUBLIC_MP\n    #define MP_API   WOLFSSL_API\n#else\n    #define MP_API   WOLFSSL_LOCAL\n#endif\n\n#ifndef MIN\n   #define MIN(x,y) ((x)<(y)?(x):(y))\n#endif\n\n#ifndef MAX\n   #define MAX(x,y) ((x)>(y)?(x):(y))\n#endif\n\n/* timing resistance array */\n#if !defined(WC_NO_CACHE_RESISTANT) && \\\n    ((defined(HAVE_ECC) && defined(ECC_TIMING_RESISTANT)) || \\\n     (defined(USE_FAST_MATH) && defined(TFM_TIMING_RESISTANT)))\n\n    extern const wolfssl_word wc_off_on_addr[2];\n#endif\n\n\n/* common math functions */\nMP_API int get_digit_count(mp_int* a);\nMP_API mp_digit get_digit(mp_int* a, int n);\nMP_API int get_rand_digit(WC_RNG* rng, mp_digit* d);\n\nWOLFSSL_API int mp_rand(mp_int* a, int digits, WC_RNG* rng);\n\nenum {\n    /* format type */\n    WC_TYPE_HEX_STR = 1,\n    WC_TYPE_UNSIGNED_BIN = 2,\n};\n\nWOLFSSL_API int wc_export_int(mp_int* mp, byte* buf, word32* len,\n    word32 keySz, int encType);\n\n#ifdef HAVE_WOLF_BIGINT\n    #if !defined(WOLF_BIGINT_DEFINED)\n        /* raw big integer */\n        typedef struct WC_BIGINT {\n            byte*   buf;\n            word32  len;\n            void*   heap;\n        } WC_BIGINT;\n        #define WOLF_BIGINT_DEFINED\n    #endif\n\n    WOLFSSL_LOCAL void wc_bigint_init(WC_BIGINT* a);\n    WOLFSSL_LOCAL int wc_bigint_alloc(WC_BIGINT* a, word32 sz);\n    WOLFSSL_LOCAL int wc_bigint_from_unsigned_bin(WC_BIGINT* a, const byte* in, word32 inlen);\n    WOLFSSL_LOCAL int wc_bigint_to_unsigned_bin(WC_BIGINT* a, byte* out, word32* outlen);\n    WOLFSSL_LOCAL void wc_bigint_zero(WC_BIGINT* a);\n    WOLFSSL_LOCAL void wc_bigint_free(WC_BIGINT* a);\n\n    WOLFSSL_LOCAL int wc_mp_to_bigint(mp_int* src, WC_BIGINT* dst);\n    WOLFSSL_LOCAL int wc_mp_to_bigint_sz(mp_int* src, WC_BIGINT* dst, word32 sz);\n    WOLFSSL_LOCAL int wc_bigint_to_mp(WC_BIGINT* src, mp_int* dst);\n#endif /* HAVE_WOLF_BIGINT */\n\n\n#ifdef __cplusplus\n    } /* extern \"C\" */\n#endif\n\n#endif /* __WOLFMATH_H__ */\n"
  }
]